UNPKG

@microsoft/teams.apps

Version:

<p> <a href="https://www.npmjs.com/package/@microsoft/teams.apps" target="_blank"> <img src="https://img.shields.io/npm/v/@microsoft/teams.apps/latest" /> </a> <a href="https://www.npmjs.com/package/@microsoft/teams.apps?activeTab=code

77 lines (76 loc) • 3.43 kB
import { ILogger } from '@microsoft/teams.common'; import { ISocketConnection, ReplyFrame, SocketActivityEnvelope, SocketConnectionHandlers, SocketModeStatus, SocketReadyFrame } from './types'; /** Internal callbacks and settings required by one geo supervisor. */ export type GeoSocketDeps = { readonly isAccepting: () => boolean; readonly getAbortSignal: () => AbortSignal | undefined; readonly createConnection: (negotiateUrl: string, handlers: SocketConnectionHandlers, /** Live predecessor ID lookup for planned refreshes only. */ getConnectionIdToReplace?: () => string | undefined) => ISocketConnection; readonly dispatch: (envelope: SocketActivityEnvelope) => Promise<ReplyFrame | undefined>; readonly retryAfterOf: (error: unknown) => number | undefined; /** `true` for errors (negotiate 401/403) that retrying cannot fix. */ readonly isNonRetryable: (error: unknown) => boolean; readonly backoffDelay: (attempt: number) => number; readonly sleep: (ms: number) => Promise<boolean>; readonly onReady: (frame: SocketReadyFrame) => void; readonly onDisconnected: (error: Error | undefined, terminal: boolean) => void; readonly onReconnected: () => void; readonly startupTimeoutMs: number; readonly tokenRefreshMarginMs: number; }; /** * Supervises one Socket Mode connection for a single geo, including readiness, * reconnection, and proactive token refresh. */ export declare class GeoSocket { private readonly deps; readonly geo: string; private readonly negotiateUrl; private readonly log; /** Monotonic connection generation. */ private generation; /** The ready generation receiving new backend traffic. */ private active?; /** Prior generations serving cached deliveries and draining SDK replies. */ private readonly retiring; private supervisorLoop?; private refreshTimer?; private _status; /** Settles when the current connection terminates and drives the supervisor. */ private closed; constructor(deps: GeoSocketDeps, geo: string, negotiateUrl: string, log: ILogger); get status(): SocketModeStatus; /** Accept frames from the active socket and its draining predecessors. */ canDispatch(gen: number): boolean; /** * Establish the initial connection within the configured startup budget. */ startInitial(): Promise<void>; superviseInBackground(): void; /** Stop token refresh, every owned connection, and the reconnect supervisor. */ stop(): Promise<void>; private connectCycle; private supervise; private whenAborted; private reconnect; /** * Stop reconnecting after a 401/403: close every connection this geo owns * (including a predecessor still serving during a planned rotation and any * sockets in their handoff window), then report the outage with the auth * error so listeners can see why delivery stopped. */ private stopAfterNonRetryable; /** * Mark this geo disconnected and emit the event. A non-retryable error means * the geo has stopped for good; it skips the "paused" warning because * {@link stopAfterNonRetryable} already logged the permanent stop. */ private reportDisconnected; private retire; private scheduleDrain; private clearDrain; private releaseConnections; private scheduleTokenRefresh; private clearRefreshTimer; }