dynamodb-reactive 0.2.2 → 0.2.4
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 +8 -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.cjs
CHANGED
|
@@ -132,6 +132,7 @@ var WebSocketManager = class {
|
|
|
132
132
|
connectionWaiters = /* @__PURE__ */ new Set();
|
|
133
133
|
socketGeneration = 0;
|
|
134
134
|
intentionalDisconnect = false;
|
|
135
|
+
lastConnectionError;
|
|
135
136
|
constructor(config) {
|
|
136
137
|
this.config = withDefaults(config);
|
|
137
138
|
}
|
|
@@ -172,7 +173,11 @@ var WebSocketManager = class {
|
|
|
172
173
|
this.connectionWaiters.add(waiter);
|
|
173
174
|
options.signal?.addEventListener("abort", abort, { once: true });
|
|
174
175
|
timeout = setTimeout(
|
|
175
|
-
() => finish(
|
|
176
|
+
() => finish(
|
|
177
|
+
new Error(`Connection timed out after ${timeoutMs}ms`, {
|
|
178
|
+
cause: this.lastConnectionError
|
|
179
|
+
})
|
|
180
|
+
),
|
|
176
181
|
timeoutMs
|
|
177
182
|
);
|
|
178
183
|
});
|
|
@@ -186,16 +191,30 @@ var WebSocketManager = class {
|
|
|
186
191
|
await this.waitForConnectionId();
|
|
187
192
|
return;
|
|
188
193
|
}
|
|
194
|
+
if (this.state !== "reconnecting") this.lastConnectionError = void 0;
|
|
189
195
|
this.intentionalDisconnect = false;
|
|
190
196
|
const generation = ++this.socketGeneration;
|
|
191
197
|
this.setState("connecting");
|
|
192
198
|
let socket;
|
|
199
|
+
let retryable = true;
|
|
193
200
|
try {
|
|
201
|
+
if (!this.config.webSocketFactory && typeof globalThis.WebSocket !== "function") {
|
|
202
|
+
retryable = false;
|
|
203
|
+
throw new Error(
|
|
204
|
+
"WebSocket is unavailable in this runtime. Enable the native WebSocket API (Node 20: --experimental-websocket), use Node 22 or newer, or configure webSocketFactory."
|
|
205
|
+
);
|
|
206
|
+
}
|
|
194
207
|
const url = await this.buildUrl();
|
|
195
208
|
if (generation !== this.socketGeneration || this.intentionalDisconnect) {
|
|
196
209
|
return;
|
|
197
210
|
}
|
|
198
|
-
|
|
211
|
+
let nextSocket;
|
|
212
|
+
try {
|
|
213
|
+
nextSocket = this.config.webSocketFactory ? this.config.webSocketFactory(url) : new globalThis.WebSocket(url);
|
|
214
|
+
} catch (cause) {
|
|
215
|
+
retryable = false;
|
|
216
|
+
throw cause;
|
|
217
|
+
}
|
|
199
218
|
socket = nextSocket;
|
|
200
219
|
this.ws = nextSocket;
|
|
201
220
|
this.startHandshakeTimer(nextSocket, generation);
|
|
@@ -209,10 +228,7 @@ var WebSocketManager = class {
|
|
|
209
228
|
this.ws = null;
|
|
210
229
|
this._connectionId = null;
|
|
211
230
|
this.setState("disconnected");
|
|
212
|
-
this.invokeLifecycleCallback(
|
|
213
|
-
"onDisconnect",
|
|
214
|
-
this.config.onDisconnect
|
|
215
|
-
);
|
|
231
|
+
this.invokeLifecycleCallback("onDisconnect", this.config.onDisconnect);
|
|
216
232
|
if (this.config.autoReconnect && !this.intentionalDisconnect) {
|
|
217
233
|
this.scheduleReconnect();
|
|
218
234
|
} else {
|
|
@@ -221,11 +237,9 @@ var WebSocketManager = class {
|
|
|
221
237
|
};
|
|
222
238
|
nextSocket.onerror = () => {
|
|
223
239
|
if (!this.isCurrent(nextSocket, generation)) return;
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
new Error("WebSocket error")
|
|
228
|
-
);
|
|
240
|
+
const failure = new Error("WebSocket error");
|
|
241
|
+
this.lastConnectionError = failure;
|
|
242
|
+
this.invokeLifecycleCallback("onError", this.config.onError, failure);
|
|
229
243
|
};
|
|
230
244
|
nextSocket.onmessage = (event) => {
|
|
231
245
|
if (!this.isCurrent(nextSocket, generation)) return;
|
|
@@ -234,13 +248,18 @@ var WebSocketManager = class {
|
|
|
234
248
|
} catch (cause) {
|
|
235
249
|
if (generation !== this.socketGeneration) return;
|
|
236
250
|
const failure = cause instanceof Error ? cause : new Error(String(cause));
|
|
251
|
+
this.lastConnectionError = failure;
|
|
237
252
|
this.clearConnectionTimers();
|
|
253
|
+
if (!retryable) {
|
|
254
|
+
this.clearTimers();
|
|
255
|
+
this.reconnectAttempts = 0;
|
|
256
|
+
}
|
|
238
257
|
if (socket && this.ws === socket) socket.close();
|
|
239
258
|
this.ws = null;
|
|
240
259
|
this._connectionId = null;
|
|
241
260
|
this.setState("disconnected");
|
|
242
261
|
this.invokeLifecycleCallback("onError", this.config.onError, failure);
|
|
243
|
-
if (this.config.autoReconnect && !this.intentionalDisconnect) {
|
|
262
|
+
if (retryable && this.config.autoReconnect && !this.intentionalDisconnect) {
|
|
244
263
|
this.scheduleReconnect();
|
|
245
264
|
await this.waitForConnectionId();
|
|
246
265
|
return;
|
|
@@ -305,6 +324,7 @@ var WebSocketManager = class {
|
|
|
305
324
|
if (message.type === "pong") {
|
|
306
325
|
if (!this._connectionId || this.state === "connected") return;
|
|
307
326
|
this.clearHandshakeTimer();
|
|
327
|
+
this.lastConnectionError = void 0;
|
|
308
328
|
this.reconnectAttempts = 0;
|
|
309
329
|
this.setState("connected");
|
|
310
330
|
this.startHeartbeat(socket, generation);
|
|
@@ -325,6 +345,7 @@ var WebSocketManager = class {
|
|
|
325
345
|
return;
|
|
326
346
|
}
|
|
327
347
|
const failure = new Error("WebSocket handshake timed out");
|
|
348
|
+
this.lastConnectionError = failure;
|
|
328
349
|
this.invokeLifecycleCallback("onError", this.config.onError, failure);
|
|
329
350
|
socket.close(4e3, "Handshake timeout");
|
|
330
351
|
}, this.config.handshakeTimeout);
|
|
@@ -332,7 +353,7 @@ var WebSocketManager = class {
|
|
|
332
353
|
startHeartbeat(socket, generation) {
|
|
333
354
|
this.clearHeartbeatTimer();
|
|
334
355
|
this.heartbeatTimer = setInterval(() => {
|
|
335
|
-
if (!this.isCurrent(socket, generation) || this.state !== "connected" || socket.readyState !==
|
|
356
|
+
if (!this.isCurrent(socket, generation) || this.state !== "connected" || socket.readyState !== socket.OPEN) {
|
|
336
357
|
return;
|
|
337
358
|
}
|
|
338
359
|
socket.send(JSON.stringify({ type: "ping" }));
|
|
@@ -349,7 +370,9 @@ var WebSocketManager = class {
|
|
|
349
370
|
scheduleReconnect() {
|
|
350
371
|
if (this.reconnectTimer || this.intentionalDisconnect) return;
|
|
351
372
|
if (this.reconnectAttempts >= this.config.maxReconnectAttempts) {
|
|
352
|
-
const failure = new Error("Max reconnection attempts reached"
|
|
373
|
+
const failure = new Error("Max reconnection attempts reached", {
|
|
374
|
+
cause: this.lastConnectionError
|
|
375
|
+
});
|
|
353
376
|
error(failure.message);
|
|
354
377
|
this.setState("disconnected");
|
|
355
378
|
this.rejectWaiters(failure);
|
|
@@ -358,10 +381,7 @@ var WebSocketManager = class {
|
|
|
358
381
|
}
|
|
359
382
|
this.setState("reconnecting");
|
|
360
383
|
this.reconnectAttempts++;
|
|
361
|
-
const delay = Math.min(
|
|
362
|
-
this.config.reconnectDelay * 2 ** (this.reconnectAttempts - 1),
|
|
363
|
-
3e4
|
|
364
|
-
) * (0.5 + Math.random() * 0.5);
|
|
384
|
+
const delay = Math.min(this.config.reconnectDelay * 2 ** (this.reconnectAttempts - 1), 3e4) * (0.5 + Math.random() * 0.5);
|
|
365
385
|
this.reconnectTimer = setTimeout(() => {
|
|
366
386
|
this.reconnectTimer = null;
|
|
367
387
|
void this.connect().catch(() => void 0);
|