@korajs/sync 0.1.2 → 0.1.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/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
@@ -102,7 +112,8 @@ function isErrorMessage(value) {
102
112
 
103
113
  // src/protocol/serializer.ts
104
114
  var import_core = require("@korajs/core");
105
- var import_minimal = require("protobufjs/minimal");
115
+ var import_minimal = __toESM(require("protobufjs/minimal"), 1);
116
+ var { Reader, Writer } = import_minimal.default;
106
117
  function versionVectorToWire(vector) {
107
118
  const wire = {};
108
119
  for (const [nodeId, seq] of vector) {
@@ -385,7 +396,7 @@ function toBytes(data) {
385
396
  throw new import_core.SyncError("Unsupported sync payload type", { receivedType: typeof data });
386
397
  }
387
398
  function encodeEnvelope(envelope) {
388
- const writer = import_minimal.Writer.create();
399
+ const writer = Writer.create();
389
400
  if (envelope.type.length > 0) writer.uint32(10).string(envelope.type);
390
401
  if (envelope.messageId.length > 0) writer.uint32(18).string(envelope.messageId);
391
402
  if (envelope.nodeId && envelope.nodeId.length > 0) writer.uint32(26).string(envelope.nodeId);
@@ -424,7 +435,7 @@ function encodeEnvelope(envelope) {
424
435
  return writer.finish();
425
436
  }
426
437
  function decodeEnvelope(bytes) {
427
- const reader = import_minimal.Reader.create(bytes);
438
+ const reader = Reader.create(bytes);
428
439
  const envelope = { type: "error", messageId: "" };
429
440
  while (reader.pos < reader.len) {
430
441
  const tag = reader.uint32();
@@ -631,8 +642,10 @@ var WebSocketTransport = class {
631
642
  errorHandler = null;
632
643
  serializer;
633
644
  WebSocketImpl;
645
+ connectTimeout;
634
646
  constructor(options) {
635
647
  this.serializer = options?.serializer ?? new JsonMessageSerializer();
648
+ this.connectTimeout = options?.connectTimeout ?? 1e4;
636
649
  if (options?.WebSocketImpl) {
637
650
  this.WebSocketImpl = options.WebSocketImpl;
638
651
  } else if (typeof globalThis.WebSocket !== "undefined") {
@@ -648,12 +661,38 @@ var WebSocketTransport = class {
648
661
  });
649
662
  }
650
663
  return new Promise((resolve, reject) => {
664
+ let settled = false;
665
+ const settle = (fn) => {
666
+ if (settled) return;
667
+ settled = true;
668
+ clearTimeout(timer);
669
+ fn();
670
+ };
671
+ const timer = setTimeout(() => {
672
+ settle(() => {
673
+ const err = new import_core2.SyncError("WebSocket connection timed out", {
674
+ url,
675
+ timeout: this.connectTimeout
676
+ });
677
+ if (this.ws) {
678
+ try {
679
+ this.ws.onclose = null;
680
+ this.ws.onerror = null;
681
+ this.ws.close();
682
+ } catch {
683
+ }
684
+ this.ws = null;
685
+ }
686
+ this.errorHandler?.(err);
687
+ reject(err);
688
+ });
689
+ }, this.connectTimeout);
651
690
  try {
652
691
  const connectUrl = options?.authToken ? `${url}${url.includes("?") ? "&" : "?"}token=${encodeURIComponent(options.authToken)}` : url;
653
692
  const ws = new this.WebSocketImpl(connectUrl);
654
693
  this.ws = ws;
655
694
  ws.onopen = () => {
656
- resolve();
695
+ settle(() => resolve());
657
696
  };
658
697
  ws.onmessage = (event) => {
659
698
  try {
@@ -677,15 +716,17 @@ var WebSocketTransport = class {
677
716
  this.errorHandler?.(err);
678
717
  if (!this.isConnected()) {
679
718
  this.ws = null;
680
- reject(err);
719
+ settle(() => reject(err));
681
720
  }
682
721
  };
683
722
  } catch (err) {
684
- reject(
685
- err instanceof import_core2.SyncError ? err : new import_core2.SyncError("Failed to create WebSocket", {
686
- url,
687
- error: String(err)
688
- })
723
+ settle(
724
+ () => reject(
725
+ err instanceof import_core2.SyncError ? err : new import_core2.SyncError("Failed to create WebSocket", {
726
+ url,
727
+ error: String(err)
728
+ })
729
+ )
689
730
  );
690
731
  }
691
732
  });
@@ -1246,8 +1287,7 @@ var SyncEngine = class {
1246
1287
  };
1247
1288
  this.transport.send(handshake);
1248
1289
  } catch (err) {
1249
- this.transitionTo("error");
1250
- this.transitionTo("disconnected");
1290
+ this.ensureDisconnected();
1251
1291
  throw err;
1252
1292
  }
1253
1293
  }
@@ -1609,6 +1649,7 @@ var ReconnectionManager = class {
1609
1649
  attempt = 0;
1610
1650
  timer = null;
1611
1651
  stopped = false;
1652
+ running = false;
1612
1653
  waitResolve = null;
1613
1654
  constructor(config) {
1614
1655
  this.initialDelay = config?.initialDelay ?? 1e3;
@@ -1626,25 +1667,30 @@ var ReconnectionManager = class {
1626
1667
  */
1627
1668
  async start(onReconnect) {
1628
1669
  this.stopped = false;
1670
+ this.running = true;
1629
1671
  this.attempt = 0;
1630
- while (!this.stopped) {
1631
- if (this.maxAttempts > 0 && this.attempt >= this.maxAttempts) {
1632
- return false;
1633
- }
1634
- const delay = this.getNextDelay();
1635
- this.attempt++;
1636
- await this.wait(delay);
1637
- if (this.stopped) return false;
1638
- try {
1639
- const success = await onReconnect();
1640
- if (success) {
1641
- this.reset();
1642
- return true;
1672
+ try {
1673
+ while (!this.stopped) {
1674
+ if (this.maxAttempts > 0 && this.attempt >= this.maxAttempts) {
1675
+ return false;
1676
+ }
1677
+ const delay = this.getNextDelay();
1678
+ this.attempt++;
1679
+ await this.wait(delay);
1680
+ if (this.stopped) return false;
1681
+ try {
1682
+ const success = await onReconnect();
1683
+ if (success) {
1684
+ this.reset();
1685
+ return true;
1686
+ }
1687
+ } catch {
1643
1688
  }
1644
- } catch {
1645
1689
  }
1690
+ return false;
1691
+ } finally {
1692
+ this.running = false;
1646
1693
  }
1647
- return false;
1648
1694
  }
1649
1695
  /**
1650
1696
  * Stop any pending reconnection attempt.
@@ -1677,6 +1723,12 @@ var ReconnectionManager = class {
1677
1723
  const jitterOffset = (this.random() - 0.5) * 2 * jitterRange;
1678
1724
  return Math.max(0, Math.round(baseDelay + jitterOffset));
1679
1725
  }
1726
+ /**
1727
+ * Whether the reconnection loop is currently running.
1728
+ */
1729
+ isRunning() {
1730
+ return this.running;
1731
+ }
1680
1732
  /**
1681
1733
  * Current attempt number (for testing).
1682
1734
  */