@actuallab/rpc 12.1.69 → 12.1.115

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
@@ -24,6 +24,7 @@ __export(index_exports, {
24
24
  DEFAULT_SERIALIZATION_FORMAT: () => DEFAULT_SERIALIZATION_FORMAT,
25
25
  ENVELOPE_DELIMITER: () => ENVELOPE_DELIMITER,
26
26
  FRAME_DELIMITER: () => FRAME_DELIMITER,
27
+ RPC_CLOSE_CODE_UNSUPPORTED_FORMAT: () => RPC_CLOSE_CODE_UNSUPPORTED_FORMAT,
27
28
  RpcCallTypeId: () => RpcCallTypeId,
28
29
  RpcClientPeer: () => RpcClientPeer,
29
30
  RpcClientPeerReconnectDelayer: () => RpcClientPeerReconnectDelayer,
@@ -383,17 +384,19 @@ var RpcObjectKind = { Local: 0, Remote: 1 };
383
384
  function parseStreamRef(value) {
384
385
  if (typeof value !== "string") return null;
385
386
  const parts = value.split(",");
386
- if (parts.length !== 4) return null;
387
+ if (parts.length < 4 || parts.length > 5) return null;
387
388
  const hostId = parts[0];
388
389
  const localId = parseInt(parts[1], 10);
389
390
  const ackPeriod = parseInt(parts[2], 10);
390
391
  const ackAdvance = parseInt(parts[3], 10);
391
392
  if (isNaN(localId) || isNaN(ackPeriod) || isNaN(ackAdvance)) return null;
392
- return { hostId, localId, ackPeriod, ackAdvance };
393
+ const allowReconnect = parts.length < 5 || parts[4] !== "0";
394
+ return { hostId, localId, ackPeriod, ackAdvance, allowReconnect };
393
395
  }
394
396
  var RpcStream = class {
395
397
  id;
396
398
  kind = RpcObjectKind.Remote;
399
+ allowReconnect;
397
400
  peer;
398
401
  ackPeriod;
399
402
  ackAdvance;
@@ -408,6 +411,7 @@ var RpcStream = class {
408
411
  _ackSentUpTo = 0;
409
412
  constructor(ref, peer) {
410
413
  this.id = { hostId: ref.hostId, localId: ref.localId };
414
+ this.allowReconnect = ref.allowReconnect;
411
415
  this.peer = peer;
412
416
  this.ackPeriod = ref.ackPeriod;
413
417
  this.ackAdvance = ref.ackAdvance;
@@ -453,7 +457,11 @@ var RpcStream = class {
453
457
  }
454
458
  // -- IRpcObject --
455
459
  reconnect() {
456
- this._sendAck(this._nextExpectedIndex, true);
460
+ if (this.allowReconnect) {
461
+ this._sendAck(this._nextExpectedIndex, true);
462
+ } else {
463
+ this.disconnect();
464
+ }
457
465
  }
458
466
  disconnect() {
459
467
  if (this._completed) return;
@@ -706,22 +714,24 @@ var DEFAULT_ACK_ADVANCE = 128;
706
714
  var RpcStreamSender = class {
707
715
  id;
708
716
  kind = RpcObjectKind.Local;
717
+ allowReconnect;
709
718
  peer;
710
719
  ackPeriod;
711
720
  ackAdvance;
712
721
  _nextIndex = 0;
713
722
  _ended = false;
714
723
  _started = new import_core5.PromiseSource();
715
- constructor(peer, ackPeriod = DEFAULT_ACK_PERIOD, ackAdvance = DEFAULT_ACK_ADVANCE) {
724
+ constructor(peer, ackPeriod = DEFAULT_ACK_PERIOD, ackAdvance = DEFAULT_ACK_ADVANCE, allowReconnect = true) {
716
725
  const localId = peer.sharedObjects.nextId();
717
726
  this.id = { hostId: peer.hub.hubId, localId };
727
+ this.allowReconnect = allowReconnect;
718
728
  this.peer = peer;
719
729
  this.ackPeriod = ackPeriod;
720
730
  this.ackAdvance = ackAdvance;
721
731
  }
722
732
  /** Returns the stream reference string for the $sys.Ok response. */
723
733
  toRef() {
724
- return `${this.id.hostId},${this.id.localId},${this.ackPeriod},${this.ackAdvance}`;
734
+ return `${this.id.hostId},${this.id.localId},${this.ackPeriod},${this.ackAdvance},${this.allowReconnect ? "1" : "0"}`;
725
735
  }
726
736
  /** Called by system call handler when $sys.Ack is received from the client. */
727
737
  onAck(_nextIndex, _hostId) {
@@ -811,7 +821,10 @@ var RpcRemoteObjectTracker = class {
811
821
  }
812
822
  reconnectAll() {
813
823
  for (const obj of this._objects.values()) {
814
- obj.reconnect();
824
+ if (obj.allowReconnect)
825
+ obj.reconnect();
826
+ else
827
+ obj.disconnect();
815
828
  }
816
829
  }
817
830
  };
@@ -854,6 +867,7 @@ var RpcClientPeerReconnectDelayer = class extends import_core6.RetryDelayer {
854
867
 
855
868
  // src/rpc-peer.ts
856
869
  var DEFAULT_SERIALIZATION_FORMAT = "json5np";
870
+ var RPC_CLOSE_CODE_UNSUPPORTED_FORMAT = 4001;
857
871
  var defaultConnectionUrlResolver = (peer) => {
858
872
  const sep = peer.ref.includes("?") ? "&" : "?";
859
873
  return peer.ref + sep + `clientId=${peer.clientId}&f=${peer.serializationFormat}`;
@@ -1059,6 +1073,8 @@ var RpcClientPeer = class extends RpcPeer {
1059
1073
  /** Builds the WebSocket URL for this peer. Replace to customize URL construction. */
1060
1074
  connectionUrlResolver = defaultConnectionUrlResolver;
1061
1075
  peerChanged = new import_core7.EventHandlerSet();
1076
+ /** Fired when the server rejects the connection due to an unsupported serialization format (close code 4010). */
1077
+ unsupportedFormat = new import_core7.EventHandlerSet();
1062
1078
  reconnectDelayer = new RpcClientPeerReconnectDelayer();
1063
1079
  reconnectsAtChanged = new import_core7.EventHandlerSet();
1064
1080
  get reconnectsAt() {
@@ -1086,10 +1102,16 @@ var RpcClientPeer = class extends RpcPeer {
1086
1102
  async run(wsFactory) {
1087
1103
  const connUrl = this.connectionUrlResolver(this);
1088
1104
  while (!this._disposed) {
1105
+ let lastCloseCode = 0;
1106
+ let lastCloseReason = "";
1089
1107
  try {
1090
1108
  const ws = wsFactory?.(connUrl) ?? new WebSocket(connUrl);
1091
1109
  const conn = new RpcWebSocketConnection(ws);
1092
1110
  this._connectionKind = 1 /* Connecting */;
1111
+ conn.closed.add((ev) => {
1112
+ lastCloseCode = ev.code;
1113
+ lastCloseReason = ev.reason;
1114
+ });
1093
1115
  this._pendingHandshake = new import_core7.PromiseSource();
1094
1116
  this.setupConnection(conn);
1095
1117
  this._connection = void 0;
@@ -1122,6 +1144,11 @@ var RpcClientPeer = class extends RpcPeer {
1122
1144
  }
1123
1145
  this._connectionKind = 0 /* Disconnected */;
1124
1146
  if (this._disposed) break;
1147
+ if (lastCloseCode === RPC_CLOSE_CODE_UNSUPPORTED_FORMAT) {
1148
+ this.unsupportedFormat.trigger({ reason: lastCloseReason });
1149
+ this._disposed = true;
1150
+ break;
1151
+ }
1125
1152
  this._tryIndex++;
1126
1153
  const delay = this.reconnectDelayer.getDelay(this._tryIndex);
1127
1154
  if (delay.isLimitExceeded) {
@@ -1593,6 +1620,7 @@ var RpcPeerStateMonitor = class {
1593
1620
  DEFAULT_SERIALIZATION_FORMAT,
1594
1621
  ENVELOPE_DELIMITER,
1595
1622
  FRAME_DELIMITER,
1623
+ RPC_CLOSE_CODE_UNSUPPORTED_FORMAT,
1596
1624
  RpcCallTypeId,
1597
1625
  RpcClientPeer,
1598
1626
  RpcClientPeerReconnectDelayer,