You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.3 KiB
52 lines
1.3 KiB
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<ConnectionConnectResult>;
|
|
}
|
|
|
|
export interface ConnectionConnectControllerOptions {
|
|
getState(): ConnectionState;
|
|
isDisposed(): boolean;
|
|
isConnected(): boolean;
|
|
beforeAttempt(): void;
|
|
runConnect(reconnect: boolean): Promise<ConnectionConnectResult>;
|
|
}
|
|
|
|
export function createConnectionConnectController(
|
|
options: ConnectionConnectControllerOptions
|
|
): ConnectionConnectController {
|
|
let connectPromise: Promise<ConnectionConnectResult> | null = null;
|
|
|
|
function connect(reconnect: boolean): Promise<ConnectionConnectResult> {
|
|
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 };
|
|
}
|