@kuralle-syrinx/ws 4.4.0 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +130 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +424 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +3 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +95 -0
- package/dist/node.js.map +1 -0
- package/dist/realtime-socket.d.ts +24 -0
- package/dist/realtime-socket.d.ts.map +1 -0
- package/dist/realtime-socket.js +45 -0
- package/dist/realtime-socket.js.map +1 -0
- package/dist/web-socket.d.ts +20 -0
- package/dist/web-socket.d.ts.map +1 -0
- package/dist/web-socket.js +62 -0
- package/dist/web-socket.js.map +1 -0
- package/dist/workers.d.ts +26 -0
- package/dist/workers.d.ts.map +1 -0
- package/dist/workers.js +122 -0
- package/dist/workers.js.map +1 -0
- package/package.json +32 -10
- package/src/index.test.ts +350 -0
- package/src/node.test.ts +68 -0
- package/src/replay.test.ts +162 -0
- package/src/web-socket.test.ts +132 -0
- package/src/workers.test.ts +84 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { type RetryConfig, type Scheduler } from "@kuralle-syrinx/core";
|
|
2
|
+
/** A WebSocket text or binary frame, normalized across runtimes. */
|
|
3
|
+
export type SocketData = string | Uint8Array;
|
|
4
|
+
/**
|
|
5
|
+
* The minimal socket the connection manager drives. Implemented over Node `ws`
|
|
6
|
+
* (createNodeWsSocket) or the built-in WebSocket (createWebSocketAdapter). Keeping the
|
|
7
|
+
* manager behind this seam is what makes it portable to Cloudflare Workers,
|
|
8
|
+
* where `ws` does not run and there are no ping frames.
|
|
9
|
+
*/
|
|
10
|
+
export interface ManagedSocket {
|
|
11
|
+
readonly isOpen: boolean;
|
|
12
|
+
send(data: SocketData): void;
|
|
13
|
+
/** Fire-and-forget liveness ping (Node WS ping frame). No-op where unsupported. */
|
|
14
|
+
keepAlivePing(): void;
|
|
15
|
+
/** When true, verify() sends a WS ping frame and awaits a pong (Node/Bun only). */
|
|
16
|
+
readonly supportsFramePing?: boolean;
|
|
17
|
+
/** Probe liveness: Node pings and awaits a pong; the built-in WebSocket just reports readyState. */
|
|
18
|
+
verify(timeoutMs: number): Promise<boolean>;
|
|
19
|
+
/** Remove listeners and close — used when replacing or tearing down. */
|
|
20
|
+
dispose(): void;
|
|
21
|
+
onOpen(handler: () => void): void;
|
|
22
|
+
onMessage(handler: (data: SocketData, isBinary: boolean) => void): void;
|
|
23
|
+
onClose(handler: (code: number, reason: string) => void): void;
|
|
24
|
+
onError(handler: (err: Error) => void): void;
|
|
25
|
+
}
|
|
26
|
+
export type SocketFactory = (url: string, headers: Record<string, string>) => ManagedSocket | Promise<ManagedSocket>;
|
|
27
|
+
export interface WebSocketConnectionOptions {
|
|
28
|
+
/** Build the connection URL fresh on every (re)connect. */
|
|
29
|
+
readonly url: () => string;
|
|
30
|
+
readonly headers?: Record<string, string>;
|
|
31
|
+
/** Creates the underlying socket for the host runtime (Node, Bun, Workers, browser). */
|
|
32
|
+
readonly socketFactory: SocketFactory;
|
|
33
|
+
/** Backoff schedule for reconnect attempts (reused from the plugin's retry config). */
|
|
34
|
+
readonly retry: RetryConfig;
|
|
35
|
+
/** Max reconnect attempts per disconnect burst before giving up. Defaults to retry.maxAttempts. */
|
|
36
|
+
readonly maxReconnectAttempts?: number;
|
|
37
|
+
/** Periodic KeepAlive to stop idle providers from closing the socket. 0 disables. */
|
|
38
|
+
readonly keepAliveIntervalMs?: number;
|
|
39
|
+
/** App-level KeepAlive payload (e.g. Deepgram `{"type":"KeepAlive"}`). When omitted a WS ping is used
|
|
40
|
+
* (which is a no-op on built-in WebSockets — provide a message for KeepAlive on Workers/browser). */
|
|
41
|
+
readonly keepAliveMessage?: () => SocketData;
|
|
42
|
+
/** A reconnect that re-opens then dies within this window counts as a quick failure. */
|
|
43
|
+
readonly minStableMs?: number;
|
|
44
|
+
/** Consecutive quick failures before giving up (backoff can't fix an instantly-closing socket). */
|
|
45
|
+
readonly maxQuickFailures?: number;
|
|
46
|
+
readonly connectTimeoutMs?: number;
|
|
47
|
+
/** App-level round-trip liveness check used on runtimes without WS ping frames (web/workers). */
|
|
48
|
+
readonly livenessProbe?: (socket: ManagedSocket) => Promise<boolean>;
|
|
49
|
+
/** Max wall-clock time for a reconnect burst before giving up. */
|
|
50
|
+
readonly maxReconnectDurationMs?: number;
|
|
51
|
+
readonly scheduler?: Scheduler;
|
|
52
|
+
readonly onMessage: (data: SocketData, isBinary: boolean) => void;
|
|
53
|
+
/** Called once when a live connection drops unexpectedly, with the close cause — for
|
|
54
|
+
* failing in-flight work and dropping stale provider state before reconnecting. */
|
|
55
|
+
readonly onConnectionLost?: (err: Error) => void;
|
|
56
|
+
/** Called before each reconnect attempt so the consumer can drop stale provider state. */
|
|
57
|
+
readonly onReconnecting?: () => void;
|
|
58
|
+
/** Called after the socket is open/verified and before replay frames flush. */
|
|
59
|
+
readonly onReadyBeforeReplay?: () => void;
|
|
60
|
+
readonly onReconnected?: () => void;
|
|
61
|
+
/** Called when reconnection is abandoned (quick-failure loop or attempts exhausted). */
|
|
62
|
+
readonly onUnrecoverable?: (err: Error) => void;
|
|
63
|
+
/**
|
|
64
|
+
* Max frames to buffer for replay-on-reconnect. 0 (default) disables replay — `send()` to a
|
|
65
|
+
* closed socket throws as before. When > 0, a `send()` that fails because the socket is not open
|
|
66
|
+
* (so the frame PROVABLY never reached the wire) is buffered and re-sent in order on the next
|
|
67
|
+
* reconnect. Frames that were sent on an open socket are never buffered, so a frame the provider
|
|
68
|
+
* may already have received is never replayed — no duplicate speech.
|
|
69
|
+
*/
|
|
70
|
+
readonly replayBufferSize?: number;
|
|
71
|
+
/** Observe replay activity: "deferred" (buffered), "replayed" (flushed on reconnect), "overflow" (dropped). */
|
|
72
|
+
readonly onReplay?: (event: "deferred" | "replayed" | "overflow", count: number) => void;
|
|
73
|
+
}
|
|
74
|
+
export declare class WebSocketConnection {
|
|
75
|
+
private readonly opts;
|
|
76
|
+
private socket;
|
|
77
|
+
private ready;
|
|
78
|
+
/** True only once the connection is verified and onReadyBeforeReplay has been
|
|
79
|
+
* given the chance to run — send() must not reach an open-but-unconfigured
|
|
80
|
+
* socket, or caller frames beat the provider config frame on reconnect. */
|
|
81
|
+
private established;
|
|
82
|
+
private closed;
|
|
83
|
+
private reconnecting;
|
|
84
|
+
private connResolver;
|
|
85
|
+
private connRejecter;
|
|
86
|
+
private abortOpen;
|
|
87
|
+
private readonly scheduler;
|
|
88
|
+
private readonly keepAliveKey;
|
|
89
|
+
private keepAliveScheduled;
|
|
90
|
+
private lastConnectAtMs;
|
|
91
|
+
private quickFailures;
|
|
92
|
+
private reconnectBurstStartedAtMs;
|
|
93
|
+
private reconnectBurstResetKey;
|
|
94
|
+
private pendingReplay;
|
|
95
|
+
constructor(opts: WebSocketConnectionOptions);
|
|
96
|
+
private get replayBufferSize();
|
|
97
|
+
/** Open the initial connection. Rejects if it cannot be established (so init fails loudly). */
|
|
98
|
+
connect(): Promise<void>;
|
|
99
|
+
get isReady(): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Send a frame. If the socket is not open: when replay is enabled (`replayBufferSize > 0`) the
|
|
102
|
+
* frame is buffered for replay on reconnect (it provably never reached the wire); otherwise this
|
|
103
|
+
* throws and the caller decides how to retry/report.
|
|
104
|
+
*/
|
|
105
|
+
send(payload: SocketData): void;
|
|
106
|
+
private bufferForReplay;
|
|
107
|
+
/** Re-send frames buffered during a disconnect gap, in order, on the reconnected socket. */
|
|
108
|
+
private flushReplay;
|
|
109
|
+
ensureReady(): Promise<void>;
|
|
110
|
+
close(): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Force a reconnect now — for when the provider stream is wedged but the socket
|
|
113
|
+
* still looks open (e.g. an unanswered Finalize). Safe no-op if closed or a
|
|
114
|
+
* reconnect is already running.
|
|
115
|
+
*/
|
|
116
|
+
reset(): void;
|
|
117
|
+
private get connectTimeoutMs();
|
|
118
|
+
private openSocket;
|
|
119
|
+
private verifyConnection;
|
|
120
|
+
private abortPendingOpen;
|
|
121
|
+
private tryReconnect;
|
|
122
|
+
private giveUp;
|
|
123
|
+
private startKeepAlive;
|
|
124
|
+
private stopKeepAlive;
|
|
125
|
+
private get minStableMs();
|
|
126
|
+
private get maxQuickFailures();
|
|
127
|
+
private cancelReconnectBurstReset;
|
|
128
|
+
private scheduleReconnectBurstReset;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
//
|
|
3
|
+
// Shared persistent-WebSocket connection manager for provider plugins.
|
|
4
|
+
//
|
|
5
|
+
// One long-lived socket per session that auto-reconnects with exponential
|
|
6
|
+
// backoff, verifies the link before trusting a reconnect, guards against
|
|
7
|
+
// concurrent reconnects, gives up fast when the socket keeps dying immediately
|
|
8
|
+
// after connecting (bad key / policy rejection — backoff can't fix that), and
|
|
9
|
+
// holds the connection open through idle with a KeepAlive.
|
|
10
|
+
//
|
|
11
|
+
// Runtime-agnostic: it drives a ManagedSocket adapter, not a concrete library.
|
|
12
|
+
// Inject createNodeWsSocket (Node/Bun, via `ws`) or createWebSocketAdapter
|
|
13
|
+
// (Cloudflare Workers / browser, via the built-in WebSocket). The reconnection
|
|
14
|
+
// logic is identical everywhere; only the socket primitive differs.
|
|
15
|
+
//
|
|
16
|
+
// Reconnection model ported from Pipecat's WebsocketService
|
|
17
|
+
// (services/websocket_service.py): _try_reconnect / _verify_connection /
|
|
18
|
+
// quick-failure detection / disconnecting guard. Backoff reuses our equal-jitter
|
|
19
|
+
// waitForRetryDelay.
|
|
20
|
+
import { TimerScheduler, waitForRetryDelay } from "@kuralle-syrinx/core";
|
|
21
|
+
const DEFAULT_MIN_STABLE_MS = 5000;
|
|
22
|
+
const DEFAULT_MAX_QUICK_FAILURES = 3;
|
|
23
|
+
const DEFAULT_CONNECT_TIMEOUT_MS = 10_000;
|
|
24
|
+
const VERIFY_TIMEOUT_MS = 2000;
|
|
25
|
+
let connectionSequence = 0;
|
|
26
|
+
export class WebSocketConnection {
|
|
27
|
+
opts;
|
|
28
|
+
socket = null;
|
|
29
|
+
ready = false;
|
|
30
|
+
/** True only once the connection is verified and onReadyBeforeReplay has been
|
|
31
|
+
* given the chance to run — send() must not reach an open-but-unconfigured
|
|
32
|
+
* socket, or caller frames beat the provider config frame on reconnect. */
|
|
33
|
+
established = false;
|
|
34
|
+
closed = false;
|
|
35
|
+
reconnecting = false;
|
|
36
|
+
connResolver = null;
|
|
37
|
+
connRejecter = null;
|
|
38
|
+
abortOpen = null;
|
|
39
|
+
scheduler;
|
|
40
|
+
keepAliveKey;
|
|
41
|
+
keepAliveScheduled = false;
|
|
42
|
+
lastConnectAtMs = 0;
|
|
43
|
+
quickFailures = 0;
|
|
44
|
+
reconnectBurstStartedAtMs = null;
|
|
45
|
+
reconnectBurstResetKey;
|
|
46
|
+
pendingReplay = [];
|
|
47
|
+
constructor(opts) {
|
|
48
|
+
this.opts = opts;
|
|
49
|
+
this.scheduler = opts.scheduler ?? new TimerScheduler();
|
|
50
|
+
connectionSequence += 1;
|
|
51
|
+
this.keepAliveKey = `voice-ws.keepalive:${String(connectionSequence)}`;
|
|
52
|
+
this.reconnectBurstResetKey = `voice-ws.burst-reset:${String(connectionSequence)}`;
|
|
53
|
+
}
|
|
54
|
+
get replayBufferSize() {
|
|
55
|
+
return Math.max(0, Math.floor(this.opts.replayBufferSize ?? 0));
|
|
56
|
+
}
|
|
57
|
+
/** Open the initial connection. Rejects if it cannot be established (so init fails loudly). */
|
|
58
|
+
async connect() {
|
|
59
|
+
this.closed = false;
|
|
60
|
+
await this.openSocket();
|
|
61
|
+
this.established = true;
|
|
62
|
+
this.opts.onReadyBeforeReplay?.();
|
|
63
|
+
this.flushReplay();
|
|
64
|
+
}
|
|
65
|
+
get isReady() {
|
|
66
|
+
return this.ready;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Send a frame. If the socket is not open: when replay is enabled (`replayBufferSize > 0`) the
|
|
70
|
+
* frame is buffered for replay on reconnect (it provably never reached the wire); otherwise this
|
|
71
|
+
* throws and the caller decides how to retry/report.
|
|
72
|
+
*/
|
|
73
|
+
send(payload) {
|
|
74
|
+
if (!this.socket || !this.socket.isOpen || !this.established) {
|
|
75
|
+
if (this.replayBufferSize > 0 && !this.closed) {
|
|
76
|
+
this.bufferForReplay(payload);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
throw new Error("WebSocket is not open");
|
|
80
|
+
}
|
|
81
|
+
this.socket.send(payload);
|
|
82
|
+
}
|
|
83
|
+
bufferForReplay(payload) {
|
|
84
|
+
this.pendingReplay.push(payload);
|
|
85
|
+
this.opts.onReplay?.("deferred", 1);
|
|
86
|
+
while (this.pendingReplay.length > this.replayBufferSize) {
|
|
87
|
+
this.pendingReplay.shift();
|
|
88
|
+
this.opts.onReplay?.("overflow", 1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/** Re-send frames buffered during a disconnect gap, in order, on the reconnected socket. */
|
|
92
|
+
flushReplay() {
|
|
93
|
+
if (this.pendingReplay.length === 0)
|
|
94
|
+
return;
|
|
95
|
+
const frames = this.pendingReplay;
|
|
96
|
+
this.pendingReplay = [];
|
|
97
|
+
let replayed = 0;
|
|
98
|
+
for (const frame of frames) {
|
|
99
|
+
if (this.socket?.isOpen) {
|
|
100
|
+
this.socket.send(frame);
|
|
101
|
+
replayed += 1;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (replayed > 0)
|
|
105
|
+
this.opts.onReplay?.("replayed", replayed);
|
|
106
|
+
}
|
|
107
|
+
async ensureReady() {
|
|
108
|
+
if (this.ready)
|
|
109
|
+
return;
|
|
110
|
+
await new Promise((resolve, reject) => {
|
|
111
|
+
const timeout = setTimeout(() => reject(new Error("WebSocket connect timeout")), this.connectTimeoutMs);
|
|
112
|
+
this.connResolver = () => {
|
|
113
|
+
clearTimeout(timeout);
|
|
114
|
+
resolve();
|
|
115
|
+
};
|
|
116
|
+
this.connRejecter = (err) => {
|
|
117
|
+
clearTimeout(timeout);
|
|
118
|
+
reject(err);
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
async close() {
|
|
123
|
+
this.closed = true;
|
|
124
|
+
this.pendingReplay = [];
|
|
125
|
+
this.cancelReconnectBurstReset();
|
|
126
|
+
this.reconnectBurstStartedAtMs = null;
|
|
127
|
+
this.stopKeepAlive();
|
|
128
|
+
this.abortPendingOpen(new Error("WebSocket connection closed"));
|
|
129
|
+
this.connResolver = null;
|
|
130
|
+
this.connRejecter = null;
|
|
131
|
+
this.ready = false;
|
|
132
|
+
this.established = false;
|
|
133
|
+
this.socket?.dispose();
|
|
134
|
+
this.socket = null;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Force a reconnect now — for when the provider stream is wedged but the socket
|
|
138
|
+
* still looks open (e.g. an unanswered Finalize). Safe no-op if closed or a
|
|
139
|
+
* reconnect is already running.
|
|
140
|
+
*/
|
|
141
|
+
reset() {
|
|
142
|
+
if (this.closed || this.reconnecting)
|
|
143
|
+
return;
|
|
144
|
+
this.abortPendingOpen(new Error("WebSocket connection reset"));
|
|
145
|
+
this.socket?.dispose();
|
|
146
|
+
this.socket = null;
|
|
147
|
+
this.ready = false;
|
|
148
|
+
this.established = false;
|
|
149
|
+
this.stopKeepAlive();
|
|
150
|
+
void this.tryReconnect();
|
|
151
|
+
}
|
|
152
|
+
get connectTimeoutMs() {
|
|
153
|
+
return this.opts.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
|
|
154
|
+
}
|
|
155
|
+
async openSocket() {
|
|
156
|
+
this.abortPendingOpen(new Error("WebSocket connection replaced"));
|
|
157
|
+
this.socket?.dispose();
|
|
158
|
+
this.ready = false;
|
|
159
|
+
this.established = false;
|
|
160
|
+
let socket = null;
|
|
161
|
+
let deadlineTimer;
|
|
162
|
+
let settled = false;
|
|
163
|
+
const clearDeadline = () => {
|
|
164
|
+
if (deadlineTimer !== undefined) {
|
|
165
|
+
clearTimeout(deadlineTimer);
|
|
166
|
+
deadlineTimer = undefined;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
const disposeAttempt = () => {
|
|
170
|
+
socket?.dispose();
|
|
171
|
+
if (socket === this.socket)
|
|
172
|
+
this.socket = null;
|
|
173
|
+
};
|
|
174
|
+
try {
|
|
175
|
+
await new Promise((resolve, reject) => {
|
|
176
|
+
deadlineTimer = setTimeout(() => {
|
|
177
|
+
if (settled)
|
|
178
|
+
return;
|
|
179
|
+
settled = true;
|
|
180
|
+
clearDeadline();
|
|
181
|
+
this.abortOpen = null;
|
|
182
|
+
disposeAttempt();
|
|
183
|
+
reject(new Error("WebSocket connect timeout"));
|
|
184
|
+
}, this.connectTimeoutMs);
|
|
185
|
+
const settle = (fn) => {
|
|
186
|
+
if (settled)
|
|
187
|
+
return;
|
|
188
|
+
settled = true;
|
|
189
|
+
clearDeadline();
|
|
190
|
+
this.abortOpen = null;
|
|
191
|
+
fn();
|
|
192
|
+
};
|
|
193
|
+
// settle() resolves THIS attempt's promise and is always safe to call (it
|
|
194
|
+
// is idempotent and owned by this socket). The shared connection state,
|
|
195
|
+
// however, must only be touched by the *current* socket: a socket replaced
|
|
196
|
+
// by a reconnect can emit a late close/message, and acting on it would
|
|
197
|
+
// clobber the healthy connection or trigger a spurious reconnect.
|
|
198
|
+
const bindSocket = (active) => active === this.socket;
|
|
199
|
+
this.abortOpen = () => {
|
|
200
|
+
settle(() => reject(new Error("WebSocket connection disposed")));
|
|
201
|
+
};
|
|
202
|
+
void (async () => {
|
|
203
|
+
try {
|
|
204
|
+
const created = await this.opts.socketFactory(this.opts.url(), this.opts.headers ?? {});
|
|
205
|
+
if (settled) {
|
|
206
|
+
created.dispose();
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
socket = created;
|
|
210
|
+
this.socket = created;
|
|
211
|
+
created.onOpen(() => {
|
|
212
|
+
settle(resolve);
|
|
213
|
+
if (!bindSocket(created))
|
|
214
|
+
return;
|
|
215
|
+
this.ready = true;
|
|
216
|
+
this.lastConnectAtMs = Date.now();
|
|
217
|
+
this.startKeepAlive();
|
|
218
|
+
this.connResolver?.();
|
|
219
|
+
this.connResolver = null;
|
|
220
|
+
this.connRejecter = null;
|
|
221
|
+
});
|
|
222
|
+
created.onMessage((data, isBinary) => {
|
|
223
|
+
if (!bindSocket(created))
|
|
224
|
+
return;
|
|
225
|
+
this.opts.onMessage(data, isBinary);
|
|
226
|
+
});
|
|
227
|
+
created.onError((err) => {
|
|
228
|
+
settle(() => reject(err));
|
|
229
|
+
if (!bindSocket(created))
|
|
230
|
+
return;
|
|
231
|
+
this.ready = false;
|
|
232
|
+
this.established = false;
|
|
233
|
+
this.connRejecter?.(err);
|
|
234
|
+
this.connResolver = null;
|
|
235
|
+
this.connRejecter = null;
|
|
236
|
+
});
|
|
237
|
+
created.onClose((code, reason) => {
|
|
238
|
+
const closeErr = closeError(code, reason);
|
|
239
|
+
settle(() => reject(closeErr));
|
|
240
|
+
if (!bindSocket(created))
|
|
241
|
+
return;
|
|
242
|
+
this.ready = false;
|
|
243
|
+
this.established = false;
|
|
244
|
+
this.stopKeepAlive();
|
|
245
|
+
this.connRejecter?.(closeErr);
|
|
246
|
+
this.connResolver = null;
|
|
247
|
+
this.connRejecter = null;
|
|
248
|
+
if (!this.closed && !this.reconnecting) {
|
|
249
|
+
this.opts.onConnectionLost?.(closeErr);
|
|
250
|
+
void this.tryReconnect();
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
settle(() => reject(err instanceof Error ? err : new Error(String(err))));
|
|
256
|
+
}
|
|
257
|
+
})();
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
if (!settled) {
|
|
262
|
+
settled = true;
|
|
263
|
+
clearDeadline();
|
|
264
|
+
this.abortOpen = null;
|
|
265
|
+
disposeAttempt();
|
|
266
|
+
}
|
|
267
|
+
throw err;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
async verifyConnection(timeoutMs) {
|
|
271
|
+
const socket = this.socket;
|
|
272
|
+
if (!socket)
|
|
273
|
+
return false;
|
|
274
|
+
if (socket.supportsFramePing)
|
|
275
|
+
return socket.verify(timeoutMs);
|
|
276
|
+
if (this.opts.livenessProbe) {
|
|
277
|
+
return await Promise.race([
|
|
278
|
+
this.opts.livenessProbe(socket),
|
|
279
|
+
new Promise((resolve) => setTimeout(() => resolve(false), timeoutMs)),
|
|
280
|
+
]);
|
|
281
|
+
}
|
|
282
|
+
return socket.verify(timeoutMs);
|
|
283
|
+
}
|
|
284
|
+
abortPendingOpen(err) {
|
|
285
|
+
if (!this.abortOpen)
|
|
286
|
+
return;
|
|
287
|
+
const abort = this.abortOpen;
|
|
288
|
+
this.abortOpen = null;
|
|
289
|
+
abort();
|
|
290
|
+
this.connRejecter?.(err);
|
|
291
|
+
this.connResolver = null;
|
|
292
|
+
this.connRejecter = null;
|
|
293
|
+
}
|
|
294
|
+
async tryReconnect() {
|
|
295
|
+
if (this.reconnecting || this.closed)
|
|
296
|
+
return;
|
|
297
|
+
this.reconnecting = true;
|
|
298
|
+
try {
|
|
299
|
+
const maxDurationMs = this.opts.maxReconnectDurationMs;
|
|
300
|
+
if (maxDurationMs !== undefined) {
|
|
301
|
+
if (this.reconnectBurstStartedAtMs === null) {
|
|
302
|
+
this.reconnectBurstStartedAtMs = Date.now();
|
|
303
|
+
}
|
|
304
|
+
else if (Date.now() - this.reconnectBurstStartedAtMs > maxDurationMs) {
|
|
305
|
+
this.giveUp(new Error(`WebSocket reconnect exceeded ${String(maxDurationMs)}ms`));
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// Quick-failure guard: a socket that re-opens then dies within minStableMs,
|
|
310
|
+
// repeatedly, will never be fixed by backoff (the handshake keeps
|
|
311
|
+
// succeeding — usually a bad key or policy rejection). Stop and surface it.
|
|
312
|
+
if (this.lastConnectAtMs > 0 && Date.now() - this.lastConnectAtMs < this.minStableMs) {
|
|
313
|
+
this.quickFailures += 1;
|
|
314
|
+
if (this.quickFailures >= this.maxQuickFailures) {
|
|
315
|
+
this.giveUp(new Error(`WebSocket closed within ${String(this.minStableMs)}ms of connecting ` +
|
|
316
|
+
`${String(this.quickFailures)} times — check credentials or provider policy`));
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
this.quickFailures = 0;
|
|
322
|
+
}
|
|
323
|
+
const maxAttempts = this.opts.maxReconnectAttempts ?? this.opts.retry.maxAttempts;
|
|
324
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
325
|
+
if (this.closed)
|
|
326
|
+
return;
|
|
327
|
+
if (maxDurationMs !== undefined && this.reconnectBurstStartedAtMs !== null) {
|
|
328
|
+
if (Date.now() - this.reconnectBurstStartedAtMs > maxDurationMs) {
|
|
329
|
+
this.giveUp(new Error(`WebSocket reconnect exceeded ${String(maxDurationMs)}ms`));
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
this.opts.onReconnecting?.();
|
|
334
|
+
try {
|
|
335
|
+
await this.openSocket();
|
|
336
|
+
if (this.socket && (await this.verifyConnection(VERIFY_TIMEOUT_MS))) {
|
|
337
|
+
this.scheduleReconnectBurstReset();
|
|
338
|
+
this.established = true;
|
|
339
|
+
this.opts.onReadyBeforeReplay?.();
|
|
340
|
+
this.flushReplay();
|
|
341
|
+
this.opts.onReconnected?.();
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
// openSocket rejected — fall through to backoff and retry
|
|
347
|
+
}
|
|
348
|
+
if (this.closed)
|
|
349
|
+
return;
|
|
350
|
+
await waitForRetryDelay(attempt, this.opts.retry);
|
|
351
|
+
}
|
|
352
|
+
this.giveUp(new Error(`failed to reconnect after ${String(maxAttempts)} attempts`));
|
|
353
|
+
}
|
|
354
|
+
finally {
|
|
355
|
+
this.reconnecting = false;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
giveUp(err) {
|
|
359
|
+
this.closed = true;
|
|
360
|
+
this.cancelReconnectBurstReset();
|
|
361
|
+
this.stopKeepAlive();
|
|
362
|
+
this.socket?.dispose();
|
|
363
|
+
this.socket = null;
|
|
364
|
+
this.opts.onUnrecoverable?.(err);
|
|
365
|
+
}
|
|
366
|
+
startKeepAlive() {
|
|
367
|
+
this.stopKeepAlive();
|
|
368
|
+
const intervalMs = this.opts.keepAliveIntervalMs ?? 0;
|
|
369
|
+
if (intervalMs <= 0)
|
|
370
|
+
return;
|
|
371
|
+
const tick = () => {
|
|
372
|
+
this.keepAliveScheduled = false;
|
|
373
|
+
const socket = this.socket;
|
|
374
|
+
if (this.closed || !socket || !socket.isOpen)
|
|
375
|
+
return;
|
|
376
|
+
if (this.opts.keepAliveMessage) {
|
|
377
|
+
socket.send(this.opts.keepAliveMessage());
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
socket.keepAlivePing();
|
|
381
|
+
}
|
|
382
|
+
if (!this.closed && socket.isOpen) {
|
|
383
|
+
this.keepAliveScheduled = true;
|
|
384
|
+
this.scheduler.schedule(this.keepAliveKey, intervalMs, tick);
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
this.keepAliveScheduled = true;
|
|
388
|
+
this.scheduler.schedule(this.keepAliveKey, intervalMs, tick);
|
|
389
|
+
}
|
|
390
|
+
stopKeepAlive() {
|
|
391
|
+
if (!this.keepAliveScheduled)
|
|
392
|
+
return;
|
|
393
|
+
this.scheduler.cancel(this.keepAliveKey);
|
|
394
|
+
this.keepAliveScheduled = false;
|
|
395
|
+
}
|
|
396
|
+
get minStableMs() {
|
|
397
|
+
return this.opts.minStableMs ?? DEFAULT_MIN_STABLE_MS;
|
|
398
|
+
}
|
|
399
|
+
get maxQuickFailures() {
|
|
400
|
+
return this.opts.maxQuickFailures ?? DEFAULT_MAX_QUICK_FAILURES;
|
|
401
|
+
}
|
|
402
|
+
cancelReconnectBurstReset() {
|
|
403
|
+
this.scheduler.cancel(this.reconnectBurstResetKey);
|
|
404
|
+
}
|
|
405
|
+
scheduleReconnectBurstReset() {
|
|
406
|
+
if (this.reconnectBurstStartedAtMs === null)
|
|
407
|
+
return;
|
|
408
|
+
const burstStarted = this.reconnectBurstStartedAtMs;
|
|
409
|
+
const stableMs = this.minStableMs * 2;
|
|
410
|
+
this.cancelReconnectBurstReset();
|
|
411
|
+
this.scheduler.schedule(this.reconnectBurstResetKey, stableMs, () => {
|
|
412
|
+
if (this.reconnectBurstStartedAtMs === burstStarted && this.ready && this.socket?.isOpen) {
|
|
413
|
+
this.reconnectBurstStartedAtMs = null;
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
function closeError(code, reason) {
|
|
419
|
+
const reasonText = reason.trim();
|
|
420
|
+
return new Error(reasonText
|
|
421
|
+
? `WebSocket closed unexpectedly: code=${code} reason=${reasonText}`
|
|
422
|
+
: `WebSocket closed unexpectedly: code=${code}`);
|
|
423
|
+
}
|
|
424
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA6B,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3E,eAAO,MAAM,kBAAkB,EAAE,aAgFhC,CAAC"}
|