import { CONNECTION_CONNECT_REASON_DISPOSED, CONNECTION_STATE_OPEN } from './consts.ts'; import type { ConnectionConnectResult, ConnectionState } from './types.ts'; export interface ConnectionConnectController { connect(reconnect: boolean): Promise; } export interface ConnectionConnectControllerOptions { getState(): ConnectionState; isDisposed(): boolean; isConnected(): boolean; beforeAttempt(): void; runConnect(reconnect: boolean): Promise; } export function createConnectionConnectController( options: ConnectionConnectControllerOptions ): ConnectionConnectController { let connectPromise: Promise | null = null; function connect(reconnect: boolean): Promise { const state = options.getState(); if (options.isDisposed()) { return Promise.resolve({ ok: false, state, reason: CONNECTION_CONNECT_REASON_DISPOSED }); } if (state === CONNECTION_STATE_OPEN && options.isConnected()) { return Promise.resolve({ ok: true, state, reused: true }); } if (connectPromise !== null) return connectPromise; connectPromise = (async () => { options.beforeAttempt(); try { return await options.runConnect(reconnect); } finally { connectPromise = null; } })(); return connectPromise; } return { connect }; }