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