@actuallab/rpc 12.3.29 → 12.3.33

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
@@ -80,6 +80,7 @@ __export(index_exports, {
80
80
  deserializeBinaryMessage: () => deserializeBinaryMessage,
81
81
  deserializeCompactBinaryMessage: () => deserializeCompactBinaryMessage,
82
82
  deserializeMessage: () => deserializeMessage,
83
+ getLogs: () => getLogs,
83
84
  getMethodsMeta: () => getMethodsMeta,
84
85
  getServiceMeta: () => getServiceMeta,
85
86
  getStateDescription: () => getStateDescription,
@@ -103,6 +104,33 @@ __export(index_exports, {
103
104
  });
104
105
  module.exports = __toCommonJS(index_exports);
105
106
 
107
+ // src/logging.ts
108
+ var import_core = require("@actuallab/core");
109
+ var scopeDefaults = {
110
+ RpcCallTracker: import_core.LogLevel.Warn,
111
+ RpcClient: import_core.LogLevel.Warn,
112
+ RpcClientPeerReconnectDelayer: import_core.LogLevel.Warn,
113
+ RpcConnection: import_core.LogLevel.Warn,
114
+ RpcHub: import_core.LogLevel.Warn,
115
+ RpcInterceptor: import_core.LogLevel.Warn,
116
+ RpcMessageChannelConnection: import_core.LogLevel.Warn,
117
+ RpcMethodRegistry: import_core.LogLevel.Warn,
118
+ RpcOutboundCall: import_core.LogLevel.Warn,
119
+ RpcPeer: import_core.LogLevel.Info,
120
+ RpcPeerStateMonitor: import_core.LogLevel.Warn,
121
+ RpcRemoteObjectTracker: import_core.LogLevel.Warn,
122
+ RpcSerialization: import_core.LogLevel.Warn,
123
+ RpcServiceHost: import_core.LogLevel.Warn,
124
+ RpcSharedObjectTracker: import_core.LogLevel.Warn,
125
+ RpcSharedStream: import_core.LogLevel.Warn,
126
+ RpcStream: import_core.LogLevel.Warn,
127
+ RpcStreamSender: import_core.LogLevel.Warn,
128
+ RpcSystemCallHandler: import_core.LogLevel.Warn,
129
+ RpcSystemCallSender: import_core.LogLevel.Warn,
130
+ RpcWebSocketClient: import_core.LogLevel.Warn
131
+ };
132
+ var getLogs = (0, import_core.createLogProvider)("rpc.", scopeDefaults);
133
+
106
134
  // src/rpc-message.ts
107
135
  var RpcCallTypeId = /* @__PURE__ */ ((RpcCallTypeId2) => {
108
136
  RpcCallTypeId2[RpcCallTypeId2["Regular"] = 0] = "Regular";
@@ -164,6 +192,7 @@ function patchMsgpackEncoderForMaps() {
164
192
  patchMsgpackEncoderForMaps();
165
193
 
166
194
  // src/rpc-serialization.ts
195
+ var { warnLog } = getLogs("RpcSerialization");
167
196
  function serializeMessage(message, args) {
168
197
  const envelope = JSON.stringify(message);
169
198
  if (args === void 0 || args.length === 0) {
@@ -193,9 +222,7 @@ function deserializeMessage(raw) {
193
222
  try {
194
223
  return JSON.parse(s);
195
224
  } catch {
196
- console.warn(
197
- `[RpcSerialization] failed to parse arg as JSON: ${s.substring(0, 100)}`
198
- );
225
+ warnLog?.log(`failed to parse arg as JSON: ${s.substring(0, 100)}`);
199
226
  return s;
200
227
  }
201
228
  });
@@ -450,7 +477,8 @@ function splitCompactBinaryFrame(frame, registry, decoder = defaultBinaryDecoder
450
477
 
451
478
  // src/rpc-connection.ts
452
479
  var import_msgpack3 = require("@msgpack/msgpack");
453
- var import_core = require("@actuallab/core");
480
+ var import_core2 = require("@actuallab/core");
481
+ var { warnLog: warnLog2 } = getLogs("RpcConnection");
454
482
  var WebSocketState = {
455
483
  CONNECTING: 0,
456
484
  OPEN: 1,
@@ -460,7 +488,7 @@ var WebSocketState = {
460
488
  var RpcWebSocketConnection = class {
461
489
  _ws;
462
490
  _sendBuffer = [];
463
- _connected = new import_core.PromiseSource();
491
+ _connected = new import_core2.PromiseSource();
464
492
  /** Per-connection msgpack encoder — reused across outbound messages to
465
493
  * amortise construction cost and to keep the internal write buffer at
466
494
  * its largest observed size (avoids repeated `resizeBuffer` growth on
@@ -481,9 +509,9 @@ var RpcWebSocketConnection = class {
481
509
  _format;
482
510
  _methodRegistry;
483
511
  binaryMode;
484
- messageReceived = new import_core.EventHandlerSet();
485
- closed = new import_core.EventHandlerSet();
486
- error = new import_core.EventHandlerSet();
512
+ messageReceived = new import_core2.EventHandlerSet();
513
+ closed = new import_core2.EventHandlerSet();
514
+ error = new import_core2.EventHandlerSet();
487
515
  constructor(ws, binaryMode = false, format, methodRegistry) {
488
516
  this._ws = ws;
489
517
  this.binaryMode = binaryMode;
@@ -512,6 +540,7 @@ var RpcWebSocketConnection = class {
512
540
  });
513
541
  }
514
542
  } catch (e) {
543
+ warnLog2?.log("Failed to split binary frame:", e);
515
544
  this.error.trigger(e);
516
545
  }
517
546
  } else if (typeof Blob !== "undefined" && ev.data instanceof Blob && this.binaryMode) {
@@ -527,6 +556,7 @@ var RpcWebSocketConnection = class {
527
556
  });
528
557
  }
529
558
  } catch (e) {
559
+ warnLog2?.log("Failed to split binary blob frame:", e);
530
560
  this.error.trigger(e);
531
561
  }
532
562
  });
@@ -602,13 +632,13 @@ var RpcWebSocketConnection = class {
602
632
  };
603
633
 
604
634
  // src/rpc-message-channel-connection.ts
605
- var import_core2 = require("@actuallab/core");
635
+ var import_core3 = require("@actuallab/core");
606
636
  var RpcMessageChannelConnection = class {
607
637
  _port;
608
638
  _open = true;
609
639
  binaryMode = false;
610
- messageReceived = new import_core2.EventHandlerSet();
611
- closed = new import_core2.EventHandlerSet();
640
+ messageReceived = new import_core3.EventHandlerSet();
641
+ closed = new import_core3.EventHandlerSet();
612
642
  whenConnected = Promise.resolve();
613
643
  // immediately connected
614
644
  constructor(port) {
@@ -697,7 +727,7 @@ function defineRpcService(name, methods) {
697
727
  }
698
728
 
699
729
  // src/rpc-call-tracker.ts
700
- var import_core3 = require("@actuallab/core");
730
+ var import_core4 = require("@actuallab/core");
701
731
 
702
732
  // src/rpc-call-stage.ts
703
733
  var RpcCallStage = {
@@ -716,7 +746,7 @@ var RpcCallStage = {
716
746
  var RpcOutboundCall = class {
717
747
  callId;
718
748
  method;
719
- result = new import_core3.PromiseSource();
749
+ result = new import_core4.PromiseSource();
720
750
  /** Bitfield of RpcRemoteExecutionMode flags controlling reconnect/resend behavior. */
721
751
  remoteExecutionMode;
722
752
  /** Whether to remove this call from the tracker on $sys.Ok. Default: true.
@@ -933,13 +963,14 @@ function _readVarUint(data, offset) {
933
963
 
934
964
  // src/rpc-stream.ts
935
965
  var import_denque = __toESM(require("denque"), 1);
936
- var import_core5 = require("@actuallab/core");
966
+ var import_core6 = require("@actuallab/core");
937
967
 
938
968
  // src/rpc-object.ts
939
969
  var RpcObjectKind = { Local: 0, Remote: 1 };
940
970
 
941
971
  // src/rpc-stream-sender.ts
942
- var import_core4 = require("@actuallab/core");
972
+ var import_core5 = require("@actuallab/core");
973
+ var { warnLog: warnLog3 } = getLogs("RpcSharedStream");
943
974
  var DEFAULT_ACK_PERIOD = 256;
944
975
  var DEFAULT_ACK_ADVANCE = 128;
945
976
  var RpcStreamSender = class _RpcStreamSender {
@@ -966,7 +997,7 @@ var RpcStreamSender = class _RpcStreamSender {
966
997
  /** Next stream index that will be sent (matches .NET's `index`). */
967
998
  _nextIndex = 0;
968
999
  _ended = false;
969
- _started = new import_core4.PromiseSource();
1000
+ _started = new import_core5.PromiseSource();
970
1001
  /** Highest `nextIndex` observed in an ACK so far (matches .NET's `lastAckNextIndex` idiom). */
971
1002
  _lastAckedIndex = 0;
972
1003
  _abortController = new AbortController();
@@ -1098,7 +1129,7 @@ var RpcStreamSender = class _RpcStreamSender {
1098
1129
  */
1099
1130
  /* eslint-disable @typescript-eslint/no-unnecessary-condition -- _ended changes across awaits */
1100
1131
  async _runNonRealTime(iterator, state) {
1101
- const buffer = new import_core4.RingBuffer(this.ackAdvance + 1);
1132
+ const buffer = new import_core5.RingBuffer(this.ackAdvance + 1);
1102
1133
  let bufferStart = 0;
1103
1134
  let isFullyBuffered = false;
1104
1135
  while (true) {
@@ -1108,6 +1139,7 @@ var RpcStreamSender = class _RpcStreamSender {
1108
1139
  if (this._ended) return;
1109
1140
  ack = this._tryProcessAcks();
1110
1141
  if (!ack) {
1142
+ warnLog3?.log("Something is off: couldn't read an acknowledgement");
1111
1143
  return;
1112
1144
  }
1113
1145
  }
@@ -1171,7 +1203,7 @@ var RpcStreamSender = class _RpcStreamSender {
1171
1203
  * src/ActualLab.Rpc/Infrastructure/RpcSharedStream.cs:219-420.
1172
1204
  */
1173
1205
  async _runRealTime(iterator, state) {
1174
- const buffer = new import_core4.RingBuffer(this.ackAdvance + 1);
1206
+ const buffer = new import_core5.RingBuffer(this.ackAdvance + 1);
1175
1207
  let bufferStart = 0;
1176
1208
  let isFullyBuffered = false;
1177
1209
  while (true) {
@@ -1180,7 +1212,10 @@ var RpcStreamSender = class _RpcStreamSender {
1180
1212
  await this._waitAckReady();
1181
1213
  if (this._ended) return;
1182
1214
  ack = this._tryProcessAcks();
1183
- if (!ack) return;
1215
+ if (!ack) {
1216
+ warnLog3?.log("Something is off: couldn't read an acknowledgement");
1217
+ return;
1218
+ }
1184
1219
  }
1185
1220
  this._lastAckedIndex = ack.nextIndex;
1186
1221
  if (ack.mustReset && !isFullyBuffered) {
@@ -1328,7 +1363,7 @@ var RpcStreamSender = class _RpcStreamSender {
1328
1363
  /** Wait for the ACK queue to have at least one entry (or `_ended`). */
1329
1364
  async _waitAckReady() {
1330
1365
  if (this._acks.length > 0 || this._ended) return;
1331
- this._whenAckReady = new import_core4.PromiseSource();
1366
+ this._whenAckReady = new import_core5.PromiseSource();
1332
1367
  await this._whenAckReady.promise;
1333
1368
  this._whenAckReady = null;
1334
1369
  }
@@ -1376,6 +1411,7 @@ function _clamp(value, min, max) {
1376
1411
  }
1377
1412
 
1378
1413
  // src/rpc-stream.ts
1414
+ var { warnLog: warnLog4 } = getLogs("RpcStream");
1379
1415
  var DEFAULT_ACK_PERIOD2 = 30;
1380
1416
  var DEFAULT_ACK_ADVANCE2 = 61;
1381
1417
  function parseStreamRef(value) {
@@ -1521,9 +1557,7 @@ var RpcStream = class _RpcStream {
1521
1557
  onItem(index, item) {
1522
1558
  if (this._disposed || this._completed) return;
1523
1559
  if (index > this._nextExpectedIndex) {
1524
- console.warn(
1525
- `[RpcStream] item index gap: localId=${this.id.localId}, expected=${this._nextExpectedIndex}, received=${index}`
1526
- );
1560
+ warnLog4?.log(`item index gap: localId=${this.id.localId}, expected=${this._nextExpectedIndex}, received=${index}`);
1527
1561
  if (!this.allowReconnect) {
1528
1562
  this._completed = true;
1529
1563
  this._completionError = new Error(
@@ -1548,9 +1582,7 @@ var RpcStream = class _RpcStream {
1548
1582
  onBatch(index, items) {
1549
1583
  if (this._disposed || this._completed) return;
1550
1584
  if (index > this._nextExpectedIndex) {
1551
- console.warn(
1552
- `[RpcStream] batch index gap: localId=${this.id.localId}, expected=${this._nextExpectedIndex}, received=${index}`
1553
- );
1585
+ warnLog4?.log(`batch index gap: localId=${this.id.localId}, expected=${this._nextExpectedIndex}, received=${index}`);
1554
1586
  if (!this.allowReconnect) {
1555
1587
  this._completed = true;
1556
1588
  this._completionError = new Error(
@@ -1621,7 +1653,7 @@ var RpcStream = class _RpcStream {
1621
1653
  if (this._completionError) throw this._completionError;
1622
1654
  return { value: void 0, done: true };
1623
1655
  }
1624
- this._consumerWaiting = new import_core5.PromiseSource();
1656
+ this._consumerWaiting = new import_core6.PromiseSource();
1625
1657
  await this._consumerWaiting.promise;
1626
1658
  }
1627
1659
  },
@@ -1737,10 +1769,12 @@ function base64Decode(encoded) {
1737
1769
  }
1738
1770
 
1739
1771
  // src/rpc-system-call-handler.ts
1772
+ var { debugLog, warnLog: warnLog5 } = getLogs("RpcSystemCallHandler");
1740
1773
  var RpcSystemCallHandler = class {
1741
1774
  handle(message, args, peer) {
1742
1775
  const method = message.Method;
1743
1776
  const relatedId = message.RelatedId ?? 0;
1777
+ debugLog?.log(`'${peer.ref}': handle ${method}#${relatedId}`);
1744
1778
  switch (method) {
1745
1779
  case RpcSystemCalls.ok: {
1746
1780
  const call = peer.outbound.get(relatedId);
@@ -1762,6 +1796,12 @@ var RpcSystemCallHandler = class {
1762
1796
  if (call !== void 0) {
1763
1797
  const errorInfo = args[0];
1764
1798
  const msg = errorInfo?.Message ?? errorInfo?.message ?? "RPC error";
1799
+ const errorType = errorInfo?.TypeRef ?? errorInfo?.typeRef;
1800
+ if (errorType !== null && typeof errorType === "object") {
1801
+ const t = errorType;
1802
+ if (t.TypeName === "RpcRerouteException" || t.typeName === "RpcRerouteException")
1803
+ warnLog5?.log("Got RpcRerouteException from remote peer:", msg);
1804
+ }
1765
1805
  call.result.reject(new Error(msg));
1766
1806
  }
1767
1807
  break;
@@ -1775,25 +1815,20 @@ var RpcSystemCallHandler = class {
1775
1815
  }
1776
1816
  case RpcSystemCalls.item: {
1777
1817
  const stream = peer.remoteObjects.get(relatedId);
1778
- if (!stream) {
1779
- console.warn(
1780
- `[RpcSysHandler] $sys.I: no stream for relatedId=${relatedId}`
1781
- );
1782
- } else {
1818
+ if (!stream)
1819
+ debugLog?.log(`$sys.I: no stream for relatedId=${relatedId}`);
1820
+ else
1783
1821
  stream.onItem(
1784
1822
  args[0],
1785
1823
  resolveStreamRefs(args[1], peer)
1786
1824
  );
1787
- }
1788
1825
  break;
1789
1826
  }
1790
1827
  case RpcSystemCalls.batch: {
1791
1828
  const stream = peer.remoteObjects.get(relatedId);
1792
- if (!stream) {
1793
- console.warn(
1794
- `[RpcSysHandler] $sys.B: no stream for relatedId=${relatedId}`
1795
- );
1796
- } else if (Array.isArray(args[1])) {
1829
+ if (!stream)
1830
+ debugLog?.log(`$sys.B: no stream for relatedId=${relatedId}`);
1831
+ else if (Array.isArray(args[1])) {
1797
1832
  const items = args[1];
1798
1833
  for (let i = 0; i < items.length; i++)
1799
1834
  items[i] = resolveStreamRefs(items[i], peer);
@@ -1804,9 +1839,7 @@ var RpcSystemCallHandler = class {
1804
1839
  case RpcSystemCalls.end: {
1805
1840
  const stream = peer.remoteObjects.get(relatedId);
1806
1841
  if (!stream) {
1807
- console.warn(
1808
- `[RpcSysHandler] $sys.End: no stream for relatedId=${relatedId}`
1809
- );
1842
+ debugLog?.log(`$sys.End: no stream for relatedId=${relatedId}`);
1810
1843
  } else {
1811
1844
  const errorInfo = args[1];
1812
1845
  const msg = errorInfo?.Message ?? errorInfo?.message;
@@ -1895,6 +1928,7 @@ function _toBytes(value) {
1895
1928
  }
1896
1929
 
1897
1930
  // src/rpc-system-call-sender.ts
1931
+ var { errorLog } = getLogs("RpcSystemCallSender");
1898
1932
  var RpcSystemCallSender = class _RpcSystemCallSender {
1899
1933
  // Reusable envelopes — one per hot-path method.
1900
1934
  _itemEnv = {
@@ -1951,12 +1985,17 @@ var RpcSystemCallSender = class _RpcSystemCallSender {
1951
1985
  ]);
1952
1986
  }
1953
1987
  ok(conn, format, relatedId, result) {
1954
- this._send(
1955
- conn,
1956
- format,
1957
- { Method: RpcSystemCalls.ok, RelatedId: relatedId },
1958
- [result]
1959
- );
1988
+ try {
1989
+ this._send(
1990
+ conn,
1991
+ format,
1992
+ { Method: RpcSystemCalls.ok, RelatedId: relatedId },
1993
+ [result]
1994
+ );
1995
+ } catch (e) {
1996
+ errorLog?.log(`Failed to send Ok response for call #${relatedId}`, e);
1997
+ this.error(conn, format, relatedId, e);
1998
+ }
1960
1999
  }
1961
2000
  error(conn, format, relatedId, error) {
1962
2001
  const message = error instanceof Error ? error.message : String(error);
@@ -2068,14 +2107,14 @@ var RpcSharedObjectTracker = class {
2068
2107
  };
2069
2108
 
2070
2109
  // src/rpc-peer.ts
2071
- var import_core7 = require("@actuallab/core");
2110
+ var import_core8 = require("@actuallab/core");
2072
2111
 
2073
2112
  // src/rpc-client-peer-reconnect-delayer.ts
2074
- var import_core6 = require("@actuallab/core");
2075
- var RpcClientPeerReconnectDelayer = class extends import_core6.RetryDelayer {
2113
+ var import_core7 = require("@actuallab/core");
2114
+ var RpcClientPeerReconnectDelayer = class extends import_core7.RetryDelayer {
2076
2115
  constructor() {
2077
2116
  super();
2078
- this.delays = import_core6.RetryDelaySeq.exp(1e3, 6e4);
2117
+ this.delays = import_core7.RetryDelaySeq.exp(1e3, 6e4);
2079
2118
  }
2080
2119
  };
2081
2120
 
@@ -2238,6 +2277,7 @@ var RpcSerializationFormatResolver = class _RpcSerializationFormatResolver {
2238
2277
 
2239
2278
  // src/rpc-peer.ts
2240
2279
  var RPC_CLOSE_CODE_UNSUPPORTED_FORMAT = 4001;
2280
+ var { debugLog: debugLog2, infoLog, warnLog: warnLog6, errorLog: errorLog2 } = getLogs("RpcPeer");
2241
2281
  var defaultConnectionUrlResolver = (peer) => {
2242
2282
  const sep = peer.ref.includes("?") ? "&" : "?";
2243
2283
  return peer.ref + sep + `clientId=${peer.clientId}&f=${peer.serializationFormat}`;
@@ -2253,8 +2293,8 @@ var RpcPeer = class {
2253
2293
  inbound = new RpcInboundCallTracker();
2254
2294
  remoteObjects = new RpcRemoteObjectTracker();
2255
2295
  sharedObjects = new RpcSharedObjectTracker();
2256
- connected = new import_core7.EventHandlerSet();
2257
- disconnected = new import_core7.EventHandlerSet();
2296
+ connected = new import_core8.EventHandlerSet();
2297
+ disconnected = new import_core8.EventHandlerSet();
2258
2298
  _pendingSends = [];
2259
2299
  _keepAliveTimer;
2260
2300
  constructor(ref, hub) {
@@ -2276,9 +2316,14 @@ var RpcPeer = class {
2276
2316
  conn.closed.add((ev) => {
2277
2317
  this._connection = void 0;
2278
2318
  this._stopKeepAlive();
2319
+ if (ev.reason)
2320
+ infoLog?.log(`'${this.ref}': Disconnected: ${ev.reason} (code=${ev.code})`);
2321
+ else
2322
+ infoLog?.log(`'${this.ref}': Disconnected`);
2279
2323
  this.disconnected.trigger(ev);
2280
2324
  });
2281
2325
  void conn.whenConnected.then(() => {
2326
+ infoLog?.log(`'${this.ref}': Connected`);
2282
2327
  this.connected.trigger();
2283
2328
  this._startKeepAlive();
2284
2329
  });
@@ -2353,6 +2398,7 @@ var RpcPeer = class {
2353
2398
  this._sendWireData(wireData);
2354
2399
  }
2355
2400
  close() {
2401
+ infoLog?.log(`'${this.ref}': Stopping`);
2356
2402
  this._stopKeepAlive();
2357
2403
  this.remoteObjects.disconnectAll();
2358
2404
  this.sharedObjects.disconnectAll();
@@ -2366,6 +2412,7 @@ var RpcPeer = class {
2366
2412
  this.outbound.invalidateAll();
2367
2413
  this._connection?.close();
2368
2414
  this._hub.peers.delete(this.ref);
2415
+ infoLog?.log(`'${this.ref}': Stopped`);
2369
2416
  }
2370
2417
  /** Send any messages buffered while disconnected. Call after connection + handshake are ready. */
2371
2418
  _flushPendingSends() {
@@ -2392,15 +2439,21 @@ var RpcPeer = class {
2392
2439
  _handleMessage(received) {
2393
2440
  let message;
2394
2441
  let args;
2395
- if (received.kind === "binary") {
2396
- message = received.message;
2397
- args = received.args;
2398
- } else {
2399
- const parsed = deserializeMessage(received.raw);
2400
- message = parsed.message;
2401
- args = parsed.args;
2442
+ try {
2443
+ if (received.kind === "binary") {
2444
+ message = received.message;
2445
+ args = received.args;
2446
+ } else {
2447
+ const parsed = deserializeMessage(received.raw);
2448
+ message = parsed.message;
2449
+ args = parsed.args;
2450
+ }
2451
+ } catch (e) {
2452
+ errorLog2?.log(`'${this.ref}': Failed to process inbound message:`, received, e);
2453
+ return;
2402
2454
  }
2403
2455
  const method = message.Method ?? "";
2456
+ debugLog2?.log(`'${this.ref}': <- ${method}#${message.RelatedId ?? 0}`);
2404
2457
  if (method === RpcSystemCalls.handshake) {
2405
2458
  const raw = args[0];
2406
2459
  if (raw !== void 0) {
@@ -2467,6 +2520,7 @@ var RpcPeer = class {
2467
2520
  e
2468
2521
  );
2469
2522
  }
2523
+ debugLog2?.log(`'${this.ref}': Inbound call failed: ${method}#${relatedId}`, e);
2470
2524
  } finally {
2471
2525
  if (!isNoWait) {
2472
2526
  this.inbound.remove(relatedId);
@@ -2520,11 +2574,11 @@ var RpcClientPeer = class extends RpcPeer {
2520
2574
  serializationFormat;
2521
2575
  /** Builds the WebSocket URL for this peer. Replace to customize URL construction. */
2522
2576
  connectionUrlResolver = defaultConnectionUrlResolver;
2523
- peerChanged = new import_core7.EventHandlerSet();
2577
+ peerChanged = new import_core8.EventHandlerSet();
2524
2578
  /** Fired when the server rejects the connection due to an unsupported serialization format (close code 4010). */
2525
- unsupportedFormat = new import_core7.EventHandlerSet();
2579
+ unsupportedFormat = new import_core8.EventHandlerSet();
2526
2580
  reconnectDelayer = new RpcClientPeerReconnectDelayer();
2527
- reconnectsAtChanged = new import_core7.EventHandlerSet();
2581
+ reconnectsAtChanged = new import_core8.EventHandlerSet();
2528
2582
  get reconnectsAt() {
2529
2583
  return this._reconnectsAt;
2530
2584
  }
@@ -2555,10 +2609,12 @@ var RpcClientPeer = class extends RpcPeer {
2555
2609
  /** Start the reconnection loop — runs until disposed. */
2556
2610
  async run(wsFactory) {
2557
2611
  const connUrl = this.connectionUrlResolver(this);
2612
+ infoLog?.log(`'${this.ref}': Started (Client)`);
2558
2613
  while (!this._disposed) {
2559
2614
  let lastCloseCode = 0;
2560
2615
  let lastCloseReason = "";
2561
2616
  try {
2617
+ infoLog?.log(`'${this.ref}': Connecting to ${connUrl}`);
2562
2618
  const ws = wsFactory?.(connUrl) ?? new WebSocket(connUrl);
2563
2619
  const conn = new RpcWebSocketConnection(
2564
2620
  ws,
@@ -2571,7 +2627,7 @@ var RpcClientPeer = class extends RpcPeer {
2571
2627
  lastCloseCode = ev.code;
2572
2628
  lastCloseReason = ev.reason;
2573
2629
  });
2574
- this._pendingHandshake = new import_core7.PromiseSource();
2630
+ this._pendingHandshake = new import_core8.PromiseSource();
2575
2631
  this.setupConnection(conn);
2576
2632
  this._connection = void 0;
2577
2633
  const closedRejection = new Promise(
@@ -2582,13 +2638,18 @@ var RpcClientPeer = class extends RpcPeer {
2582
2638
  closedRejection.catch(() => {
2583
2639
  });
2584
2640
  await Promise.race([conn.whenConnected, closedRejection]);
2585
- this._hub.systemCallSender.handshake(
2586
- conn,
2587
- this.format,
2588
- this.id,
2589
- this._hub.hubId,
2590
- ++this._handshakeIndex
2591
- );
2641
+ try {
2642
+ this._hub.systemCallSender.handshake(
2643
+ conn,
2644
+ this.format,
2645
+ this.id,
2646
+ this._hub.hubId,
2647
+ ++this._handshakeIndex
2648
+ );
2649
+ } catch (e) {
2650
+ warnLog6?.log(`'${this.ref}': Failed to send handshake`, e);
2651
+ throw e;
2652
+ }
2592
2653
  const remoteHandshake = await Promise.race([
2593
2654
  this._pendingHandshake.promise,
2594
2655
  closedRejection
@@ -2601,20 +2662,24 @@ var RpcClientPeer = class extends RpcPeer {
2601
2662
  isPeerChanged = this._lastRemoteHubId !== void 0 && this._lastRemoteHubId !== remoteHubId;
2602
2663
  if (isPeerChanged) {
2603
2664
  this.inbound.clear();
2665
+ infoLog?.log(`'${this.ref}': Peer changed`);
2604
2666
  this.peerChanged.trigger();
2605
2667
  }
2606
2668
  this._lastRemoteHubId = remoteHubId;
2607
2669
  }
2670
+ infoLog?.log(`'${this.ref}': Handshake succeeded, peerChanged=${isPeerChanged}`);
2608
2671
  this._connection = conn;
2609
2672
  this._connectionKind = 2 /* Connected */;
2610
2673
  this._tryIndex = 0;
2611
2674
  await this._reconnect(isPeerChanged);
2612
2675
  await new Promise((r) => conn.closed.add(() => r()));
2613
- } catch {
2676
+ } catch (e) {
2677
+ debugLog2?.log(`'${this.ref}': run() iteration failed:`, e);
2614
2678
  }
2615
2679
  this._connectionKind = 0 /* Disconnected */;
2616
2680
  if (this._disposed) break;
2617
2681
  if (lastCloseCode === RPC_CLOSE_CODE_UNSUPPORTED_FORMAT) {
2682
+ warnLog6?.log(`'${this.ref}': Unsupported serialization format - shutting down`);
2618
2683
  this.unsupportedFormat.trigger({ reason: lastCloseReason });
2619
2684
  this._disposed = true;
2620
2685
  break;
@@ -2622,6 +2687,7 @@ var RpcClientPeer = class extends RpcPeer {
2622
2687
  this._tryIndex++;
2623
2688
  const delay = this.reconnectDelayer.getDelay(this._tryIndex);
2624
2689
  if (delay.isLimitExceeded) {
2690
+ warnLog6?.log(`'${this.ref}': Reconnect limit exceeded - shutting down`);
2625
2691
  this._disposed = true;
2626
2692
  break;
2627
2693
  }
@@ -2816,6 +2882,7 @@ function _toBytes2(value) {
2816
2882
  }
2817
2883
 
2818
2884
  // src/rpc-service-host.ts
2885
+ var { warnLog: warnLog7 } = getLogs("RpcServiceHost");
2819
2886
  var RpcServiceHost = class {
2820
2887
  _methods = /* @__PURE__ */ new Map();
2821
2888
  register(def, impl) {
@@ -2830,8 +2897,10 @@ var RpcServiceHost = class {
2830
2897
  }
2831
2898
  async dispatch(wireMethod, args, context) {
2832
2899
  const entry = this._methods.get(wireMethod);
2833
- if (entry === void 0)
2900
+ if (entry === void 0) {
2901
+ warnLog7?.log(`Method not found: ${wireMethod}`);
2834
2902
  throw new Error(`Method not found: ${wireMethod}`);
2903
+ }
2835
2904
  if (context !== void 0 && entry.def.callTypeId !== 0) {
2836
2905
  return await entry.fn(...args, context);
2837
2906
  }
@@ -3361,6 +3430,7 @@ function computeMethodHash(methodName) {
3361
3430
  }
3362
3431
 
3363
3432
  // src/rpc-method-registry.ts
3433
+ var { warnLog: warnLog8 } = getLogs("RpcMethodRegistry");
3364
3434
  var RpcMethodRegistry = class {
3365
3435
  _nameToHash = /* @__PURE__ */ new Map();
3366
3436
  _hashToName = /* @__PURE__ */ new Map();
@@ -3370,9 +3440,7 @@ var RpcMethodRegistry = class {
3370
3440
  const hash = computeMethodHash(methodName);
3371
3441
  const existing = this._hashToName.get(hash);
3372
3442
  if (existing !== void 0 && existing !== methodName) {
3373
- console.warn(
3374
- `[RpcMethodRegistry] hash collision: "${methodName}" and "${existing}" both hash to ${hash}`
3375
- );
3443
+ warnLog8?.log(`hash collision: "${methodName}" and "${existing}" both hash to ${hash}`);
3376
3444
  return;
3377
3445
  }
3378
3446
  this._nameToHash.set(methodName, hash);
@@ -3405,6 +3473,7 @@ var RpcMethodRegistry = class {
3405
3473
  };
3406
3474
 
3407
3475
  // src/rpc-hub.ts
3476
+ var { warnLog: warnLog9 } = getLogs("RpcHub");
3408
3477
  var RpcHub = class {
3409
3478
  hubId;
3410
3479
  peers = /* @__PURE__ */ new Map();
@@ -3430,6 +3499,7 @@ var RpcHub = class {
3430
3499
  if (peer !== void 0) {
3431
3500
  peer.close();
3432
3501
  this.peers.delete(ref);
3502
+ warnLog9?.log(`'${ref}': peer is removed from RpcHub`);
3433
3503
  }
3434
3504
  }
3435
3505
  /** Get or create a peer by ref. Server peers have "server://" prefix, everything else is a client peer. */
@@ -3661,13 +3731,14 @@ function getStateDescription(state, useLastError = false) {
3661
3731
  }
3662
3732
 
3663
3733
  // src/rpc-peer-state-monitor.ts
3664
- var import_core8 = require("@actuallab/core");
3734
+ var import_core9 = require("@actuallab/core");
3735
+ var { infoLog: infoLog2 } = getLogs("RpcPeerStateMonitor");
3665
3736
  var JustConnectedPeriodMs = 1500;
3666
3737
  var JustDisconnectedPeriodMs = 3e3;
3667
3738
  var MinReconnectsInMs = 1e3;
3668
3739
  var RpcPeerStateMonitor = class {
3669
3740
  peer;
3670
- stateChanged = new import_core8.EventHandlerSet();
3741
+ stateChanged = new import_core9.EventHandlerSet();
3671
3742
  _rawConnected;
3672
3743
  _connectedAt = 0;
3673
3744
  _disconnectedAt = 0;
@@ -3723,6 +3794,7 @@ var RpcPeerStateMonitor = class {
3723
3794
  this._scheduleRecompute(
3724
3795
  this._rawConnected ? JustConnectedPeriodMs : JustDisconnectedPeriodMs
3725
3796
  );
3797
+ infoLog2?.log(`'${peer.ref}': monitor started`);
3726
3798
  }
3727
3799
  get state() {
3728
3800
  return this._state;
@@ -3738,6 +3810,7 @@ var RpcPeerStateMonitor = class {
3738
3810
  this.peer.reconnectDelayer.cancelDelaysChanged.remove(
3739
3811
  this._onCancelDelaysChanged
3740
3812
  );
3813
+ infoLog2?.log(`'${this.peer.ref}': monitor stopped`);
3741
3814
  }
3742
3815
  _recompute() {
3743
3816
  if (this._timer !== void 0) {
@@ -3864,6 +3937,7 @@ var RpcPeerStateMonitor = class {
3864
3937
  deserializeBinaryMessage,
3865
3938
  deserializeCompactBinaryMessage,
3866
3939
  deserializeMessage,
3940
+ getLogs,
3867
3941
  getMethodsMeta,
3868
3942
  getServiceMeta,
3869
3943
  getStateDescription,