parent
1aa9c4dd30
commit
ed888e9f2d
@ -0,0 +1,78 @@
|
||||
import {
|
||||
CONNECTION_CLOSE_REASON_AUTH_FAILED,
|
||||
CONNECTION_CONNECT_REASON_AUTH_FAILED,
|
||||
CONNECTION_CONNECT_REASON_TRANSPORT_ERROR,
|
||||
CONNECTION_DIAGNOSTIC_EVENTS,
|
||||
CONNECTION_STATE_CONNECTING,
|
||||
CONNECTION_STATE_FAILED,
|
||||
CONNECTION_STATE_RECONNECTING,
|
||||
TIMER_KEY_RECONNECT
|
||||
} from './consts.ts';
|
||||
import { emitConnectionDiagnostic, type ConnectionDiagnostics } from './diagnostics.ts';
|
||||
import type { ConnectionRequestRuntime } from './connection-requests.ts';
|
||||
import type { ConnectionStateTracker } from './connection-state.ts';
|
||||
import type { ConnectionTimerControls } from './connection-timers.ts';
|
||||
import type { ConnectionSender } from './sender.ts';
|
||||
import type { ConnectionConnectResult, ConnectionTransport } from './types.ts';
|
||||
|
||||
export interface RunConnectionConnectInput {
|
||||
readonly reconnect: boolean;
|
||||
readonly timers: ConnectionTimerControls;
|
||||
resolveTransport(): ConnectionTransport;
|
||||
setTransport(transport: ConnectionTransport): void;
|
||||
attachTransport(transport: ConnectionTransport): void;
|
||||
detachTransport(): void;
|
||||
markOpen(): void;
|
||||
markClosedFailed(error: unknown): void;
|
||||
joinConfiguredChannels(reconnect: boolean): Promise<void>;
|
||||
readonly state: ConnectionStateTracker;
|
||||
readonly requests: ConnectionRequestRuntime;
|
||||
readonly sender: ConnectionSender;
|
||||
readonly diagnostics: ConnectionDiagnostics;
|
||||
}
|
||||
|
||||
export async function runConnectionConnect(
|
||||
input: RunConnectionConnectInput
|
||||
): Promise<ConnectionConnectResult> {
|
||||
input.timers.cancel(TIMER_KEY_RECONNECT);
|
||||
const nextTransport = input.resolveTransport();
|
||||
input.setTransport(nextTransport);
|
||||
input.attachTransport(nextTransport);
|
||||
input.state.transition(input.reconnect ? CONNECTION_STATE_RECONNECTING : CONNECTION_STATE_CONNECTING);
|
||||
try {
|
||||
await nextTransport.open();
|
||||
input.markOpen();
|
||||
if (input.requests.hasAuthProvider()) {
|
||||
const auth = await input.requests.runAuth();
|
||||
if (!auth.ok) {
|
||||
const authError = auth.error ?? auth.reason;
|
||||
input.state.setError(authError);
|
||||
emitConnectionDiagnostic(input.diagnostics, CONNECTION_DIAGNOSTIC_EVENTS.AUTH_FAILED, auth);
|
||||
input.detachTransport();
|
||||
nextTransport.close(undefined, CONNECTION_CLOSE_REASON_AUTH_FAILED);
|
||||
input.markClosedFailed(authError);
|
||||
return {
|
||||
ok: false,
|
||||
state: input.state.state,
|
||||
reason: CONNECTION_CONNECT_REASON_AUTH_FAILED,
|
||||
error: authError
|
||||
};
|
||||
}
|
||||
}
|
||||
await input.sender.flushBuffer();
|
||||
await input.joinConfiguredChannels(input.reconnect);
|
||||
return { ok: true, state: input.state.state };
|
||||
} catch (err) {
|
||||
input.state.setError(err);
|
||||
emitConnectionDiagnostic(input.diagnostics, CONNECTION_DIAGNOSTIC_EVENTS.CONNECT_FAILED, {
|
||||
error: err
|
||||
});
|
||||
input.state.transition(CONNECTION_STATE_FAILED, err);
|
||||
return {
|
||||
ok: false,
|
||||
state: input.state.state,
|
||||
reason: CONNECTION_CONNECT_REASON_TRANSPORT_ERROR,
|
||||
error: err
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue