dynamodb-reactive 0.2.1 → 0.2.3
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/README.md +52 -0
- package/dist/{client-r_tnzwqi.d.ts → client-Zb67giI5.d.ts} +5 -0
- package/dist/client.cjs +38 -18
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +38 -18
- package/dist/client.js.map +1 -1
- package/dist/react.cjs +38 -18
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +38 -18
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -126,6 +126,7 @@ var WebSocketManager = class {
|
|
|
126
126
|
connectionWaiters = /* @__PURE__ */ new Set();
|
|
127
127
|
socketGeneration = 0;
|
|
128
128
|
intentionalDisconnect = false;
|
|
129
|
+
lastConnectionError;
|
|
129
130
|
constructor(config) {
|
|
130
131
|
this.config = withDefaults(config);
|
|
131
132
|
}
|
|
@@ -166,7 +167,11 @@ var WebSocketManager = class {
|
|
|
166
167
|
this.connectionWaiters.add(waiter);
|
|
167
168
|
options.signal?.addEventListener("abort", abort, { once: true });
|
|
168
169
|
timeout = setTimeout(
|
|
169
|
-
() => finish(
|
|
170
|
+
() => finish(
|
|
171
|
+
new Error(`Connection timed out after ${timeoutMs}ms`, {
|
|
172
|
+
cause: this.lastConnectionError
|
|
173
|
+
})
|
|
174
|
+
),
|
|
170
175
|
timeoutMs
|
|
171
176
|
);
|
|
172
177
|
});
|
|
@@ -180,16 +185,30 @@ var WebSocketManager = class {
|
|
|
180
185
|
await this.waitForConnectionId();
|
|
181
186
|
return;
|
|
182
187
|
}
|
|
188
|
+
if (this.state !== "reconnecting") this.lastConnectionError = void 0;
|
|
183
189
|
this.intentionalDisconnect = false;
|
|
184
190
|
const generation = ++this.socketGeneration;
|
|
185
191
|
this.setState("connecting");
|
|
186
192
|
let socket;
|
|
193
|
+
let retryable = true;
|
|
187
194
|
try {
|
|
195
|
+
if (!this.config.webSocketFactory && typeof globalThis.WebSocket !== "function") {
|
|
196
|
+
retryable = false;
|
|
197
|
+
throw new Error(
|
|
198
|
+
"WebSocket is unavailable in this runtime. Enable the native WebSocket API (Node 20: --experimental-websocket), use Node 22 or newer, or configure webSocketFactory."
|
|
199
|
+
);
|
|
200
|
+
}
|
|
188
201
|
const url = await this.buildUrl();
|
|
189
202
|
if (generation !== this.socketGeneration || this.intentionalDisconnect) {
|
|
190
203
|
return;
|
|
191
204
|
}
|
|
192
|
-
|
|
205
|
+
let nextSocket;
|
|
206
|
+
try {
|
|
207
|
+
nextSocket = this.config.webSocketFactory ? this.config.webSocketFactory(url) : new globalThis.WebSocket(url);
|
|
208
|
+
} catch (cause) {
|
|
209
|
+
retryable = false;
|
|
210
|
+
throw cause;
|
|
211
|
+
}
|
|
193
212
|
socket = nextSocket;
|
|
194
213
|
this.ws = nextSocket;
|
|
195
214
|
this.startHandshakeTimer(nextSocket, generation);
|
|
@@ -203,10 +222,7 @@ var WebSocketManager = class {
|
|
|
203
222
|
this.ws = null;
|
|
204
223
|
this._connectionId = null;
|
|
205
224
|
this.setState("disconnected");
|
|
206
|
-
this.invokeLifecycleCallback(
|
|
207
|
-
"onDisconnect",
|
|
208
|
-
this.config.onDisconnect
|
|
209
|
-
);
|
|
225
|
+
this.invokeLifecycleCallback("onDisconnect", this.config.onDisconnect);
|
|
210
226
|
if (this.config.autoReconnect && !this.intentionalDisconnect) {
|
|
211
227
|
this.scheduleReconnect();
|
|
212
228
|
} else {
|
|
@@ -215,11 +231,9 @@ var WebSocketManager = class {
|
|
|
215
231
|
};
|
|
216
232
|
nextSocket.onerror = () => {
|
|
217
233
|
if (!this.isCurrent(nextSocket, generation)) return;
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
new Error("WebSocket error")
|
|
222
|
-
);
|
|
234
|
+
const failure = new Error("WebSocket error");
|
|
235
|
+
this.lastConnectionError = failure;
|
|
236
|
+
this.invokeLifecycleCallback("onError", this.config.onError, failure);
|
|
223
237
|
};
|
|
224
238
|
nextSocket.onmessage = (event) => {
|
|
225
239
|
if (!this.isCurrent(nextSocket, generation)) return;
|
|
@@ -228,13 +242,18 @@ var WebSocketManager = class {
|
|
|
228
242
|
} catch (cause) {
|
|
229
243
|
if (generation !== this.socketGeneration) return;
|
|
230
244
|
const failure = cause instanceof Error ? cause : new Error(String(cause));
|
|
245
|
+
this.lastConnectionError = failure;
|
|
231
246
|
this.clearConnectionTimers();
|
|
247
|
+
if (!retryable) {
|
|
248
|
+
this.clearTimers();
|
|
249
|
+
this.reconnectAttempts = 0;
|
|
250
|
+
}
|
|
232
251
|
if (socket && this.ws === socket) socket.close();
|
|
233
252
|
this.ws = null;
|
|
234
253
|
this._connectionId = null;
|
|
235
254
|
this.setState("disconnected");
|
|
236
255
|
this.invokeLifecycleCallback("onError", this.config.onError, failure);
|
|
237
|
-
if (this.config.autoReconnect && !this.intentionalDisconnect) {
|
|
256
|
+
if (retryable && this.config.autoReconnect && !this.intentionalDisconnect) {
|
|
238
257
|
this.scheduleReconnect();
|
|
239
258
|
await this.waitForConnectionId();
|
|
240
259
|
return;
|
|
@@ -299,6 +318,7 @@ var WebSocketManager = class {
|
|
|
299
318
|
if (message.type === "pong") {
|
|
300
319
|
if (!this._connectionId || this.state === "connected") return;
|
|
301
320
|
this.clearHandshakeTimer();
|
|
321
|
+
this.lastConnectionError = void 0;
|
|
302
322
|
this.reconnectAttempts = 0;
|
|
303
323
|
this.setState("connected");
|
|
304
324
|
this.startHeartbeat(socket, generation);
|
|
@@ -319,6 +339,7 @@ var WebSocketManager = class {
|
|
|
319
339
|
return;
|
|
320
340
|
}
|
|
321
341
|
const failure = new Error("WebSocket handshake timed out");
|
|
342
|
+
this.lastConnectionError = failure;
|
|
322
343
|
this.invokeLifecycleCallback("onError", this.config.onError, failure);
|
|
323
344
|
socket.close(4e3, "Handshake timeout");
|
|
324
345
|
}, this.config.handshakeTimeout);
|
|
@@ -326,7 +347,7 @@ var WebSocketManager = class {
|
|
|
326
347
|
startHeartbeat(socket, generation) {
|
|
327
348
|
this.clearHeartbeatTimer();
|
|
328
349
|
this.heartbeatTimer = setInterval(() => {
|
|
329
|
-
if (!this.isCurrent(socket, generation) || this.state !== "connected" || socket.readyState !==
|
|
350
|
+
if (!this.isCurrent(socket, generation) || this.state !== "connected" || socket.readyState !== socket.OPEN) {
|
|
330
351
|
return;
|
|
331
352
|
}
|
|
332
353
|
socket.send(JSON.stringify({ type: "ping" }));
|
|
@@ -343,7 +364,9 @@ var WebSocketManager = class {
|
|
|
343
364
|
scheduleReconnect() {
|
|
344
365
|
if (this.reconnectTimer || this.intentionalDisconnect) return;
|
|
345
366
|
if (this.reconnectAttempts >= this.config.maxReconnectAttempts) {
|
|
346
|
-
const failure = new Error("Max reconnection attempts reached"
|
|
367
|
+
const failure = new Error("Max reconnection attempts reached", {
|
|
368
|
+
cause: this.lastConnectionError
|
|
369
|
+
});
|
|
347
370
|
error(failure.message);
|
|
348
371
|
this.setState("disconnected");
|
|
349
372
|
this.rejectWaiters(failure);
|
|
@@ -352,10 +375,7 @@ var WebSocketManager = class {
|
|
|
352
375
|
}
|
|
353
376
|
this.setState("reconnecting");
|
|
354
377
|
this.reconnectAttempts++;
|
|
355
|
-
const delay = Math.min(
|
|
356
|
-
this.config.reconnectDelay * 2 ** (this.reconnectAttempts - 1),
|
|
357
|
-
3e4
|
|
358
|
-
) * (0.5 + Math.random() * 0.5);
|
|
378
|
+
const delay = Math.min(this.config.reconnectDelay * 2 ** (this.reconnectAttempts - 1), 3e4) * (0.5 + Math.random() * 0.5);
|
|
359
379
|
this.reconnectTimer = setTimeout(() => {
|
|
360
380
|
this.reconnectTimer = null;
|
|
361
381
|
void this.connect().catch(() => void 0);
|