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/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(new Error(`Connection timed out after ${timeoutMs}ms`)),
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
- const nextSocket = new WebSocket(url);
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
- this.invokeLifecycleCallback(
225
- "onError",
226
- this.config.onError,
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 !== WebSocket.OPEN) {
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);