@actuallab/rpc 14.3.32 → 14.3.34

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.d.cts CHANGED
@@ -522,6 +522,10 @@ declare class RpcOutboundCallTracker {
522
522
  remove(callId: number): RpcOutboundCall | undefined;
523
523
  values(): IterableIterator<RpcOutboundCall>;
524
524
  activeCallIds(): number[];
525
+ /** Calls handed to the transport at least once. Must be snapshotted BEFORE the
526
+ * peer enters `Connected` — that flushes every queued call, making queued and
527
+ * in-flight calls indistinguishable. Mirrors .NET's `GetSentCalls`. */
528
+ getSentCalls(): RpcOutboundCall[];
525
529
  /** Reject all pending calls with the given error.
526
530
  * Stage-3 compute calls (result resolved, awaiting invalidation) are kept in the tracker. */
527
531
  rejectAll(error: Error): void;
@@ -1071,6 +1075,14 @@ declare const enum RpcConnectionState {
1071
1075
  Handshaking = 2,
1072
1076
  Connected = 3
1073
1077
  }
1078
+ /** Outcome of comparing an incoming handshake with the previous one. Mirrors
1079
+ * .NET `RpcPeerChangeKind` — `ChangedToVeryFirst` lets the first handshake skip
1080
+ * reconnect processing, since there's no prior connection to reconcile with. */
1081
+ declare const enum RpcPeerChangeKind {
1082
+ Unchanged = 0,
1083
+ ChangedToVeryFirst = 1,
1084
+ Changed = 2
1085
+ }
1074
1086
  /** Client-side RPC peer — initiates WebSocket connection. ref = URL. */
1075
1087
  declare class RpcClientPeer extends RpcPeer {
1076
1088
  private _disposed;
@@ -1084,7 +1096,10 @@ declare class RpcClientPeer extends RpcPeer {
1084
1096
  * `connectionState.Handshake.Index` path in
1085
1097
  * `RpcOutboundCallTracker.TryReconnect`. */
1086
1098
  private _remoteHandshakeIndex;
1087
- private _lastRemotePeerId;
1099
+ /** Mirrors .NET's `lastHandshake` local in `RpcPeer.OnRun`: first-ness is keyed
1100
+ * off "was there a previous handshake", not off `RemotePeerId` — a legacy server
1101
+ * sends none, so every one of its handshakes would look like the first. */
1102
+ private _lastHandshake;
1088
1103
  private _pendingHandshake;
1089
1104
  private _reconnectsAt;
1090
1105
  /** Server-issued reconnect secret, from the most recent handshake that
@@ -1166,7 +1181,10 @@ declare class RpcClientPeer extends RpcPeer {
1166
1181
  protected run(): Promise<void>;
1167
1182
  private _runImpl;
1168
1183
  /**
1169
- * Reconcile outbound calls after reconnection, then flush pending sends.
1184
+ * Reconcile the calls that were in flight on the connection that just died
1185
+ * (`sentCalls`), then resend the survivors. Calls still waiting for a
1186
+ * connection are deliberately NOT passed in — `AllowReconnect`/`AllowResend`
1187
+ * don't apply to them, and entering `Connected` already sends them.
1170
1188
  *
1171
1189
  * On peer change (different server hubId) or with binary wire format —
1172
1190
  * we blind-resend every eligible call.
@@ -1204,7 +1222,7 @@ declare class RpcClientPeer extends RpcPeer {
1204
1222
  * `RpcHandshake.GetPeerChangeKind` keys off `RemotePeerId`, not
1205
1223
  * `RemoteHubId` (an idle server peer can be replaced while keeping the
1206
1224
  * same hub id). On a change it clears the inbound tracker and fires
1207
- * `peerChanged`; the very first handshake is never a change. */
1225
+ * `peerChanged`; the very first handshake is `ChangedToVeryFirst`. */
1208
1226
  private _detectPeerChange;
1209
1227
  protected _onHandshakeReceived(handshake: RemoteHandshake): void;
1210
1228
  close(): void;
@@ -1620,4 +1638,4 @@ declare function xxh3_64str(input: string, seed?: bigint): bigint;
1620
1638
  */
1621
1639
  declare function computeMethodHash(methodName: string): number;
1622
1640
 
1623
- export { ARG_DELIMITER, ENVELOPE_DELIMITER, FRAME_DELIMITER, type IRpcObject, IncreasingSeqCompressor, type MethodMeta, REMOTE_EXCEPTION_TYPE_REF, RPC_CLOSE_CODE_UNSUPPORTED_FORMAT, type RemoteHandshake, type RpcCallOptions, RpcCallStage, RpcCallTimeouts, RpcCallTypeId, RpcClientPeer, RpcClientPeerReconnectDelayer, type RpcConnection, RpcConnectionState, type RpcConnectionUrlResolver, type RpcDeserializedMessage, type RpcDispatchContext, RpcError, type RpcErrorFilter, type RpcExceptionInfo, RpcHub, RpcInboundCall, RpcInboundCallTracker, RpcJsonSerializationFormat, RpcLimits, type RpcLogScope, type RpcMessage, RpcMessageChannelConnection, RpcMessagePackCompactSerializationFormat, RpcMessagePackSerializationFormat, type RpcMethodDef, type RpcMethodDefInput, RpcMethodRegistry, type RpcObjectId, RpcObjectKind, RpcOutboundCall, RpcOutboundCallTracker, RpcPeer, type RpcPeerFactory, type RpcPeerState, RpcPeerStateKind, RpcPeerStateMonitor, type RpcReceivedMessage, type RpcReconnectProofParameters, RpcRefBuilder, RpcRemoteExecutionMode, RpcRemoteObjectTracker, RpcSerializationFormat, RpcSerializationFormatResolver, RpcServerPeer, type RpcServiceDef, RpcServiceHost, type RpcServiceImpl, RpcSharedObjectTracker, RpcStream, type RpcStreamOptions, type RpcStreamRef, RpcStreamSender, type RpcStreamSource, RpcSystemCallHandler, RpcSystemCallSender, RpcSystemCalls, RpcType, RpcWebSocketConnection, type RpcWireData, type ServiceMeta, type WebSocketLike, type WebSocketServer, WebSocketState, computeMethodHash, computeReconnectProof, createBinaryEncoder, createMessageChannelPair, createRpcClient, defaultBinaryDecoder, defaultBinaryEncoder, defaultConnectionUrlResolver, defineRpcService, deserializeBinaryMessage, deserializeCompactBinaryMessage, deserializeMessage, genericErrorFilter, getLogs, getMethodsMeta, getServiceMeta, getStateDescription, isConnected, isReconnectProofSupported, likelyConnected, parseStreamRef, readPolymorphismMarker, rpcMethod, rpcService, serializeBinaryFrame, serializeBinaryMessage, serializeCompactBinaryMessage, serializeFrame, serializeMessage, splitBinaryFrame, splitCompactBinaryFrame, splitFrame, toExceptionInfo, toRpcStream, wireMethodName, xxh3_64, xxh3_64str };
1641
+ export { ARG_DELIMITER, ENVELOPE_DELIMITER, FRAME_DELIMITER, type IRpcObject, IncreasingSeqCompressor, type MethodMeta, REMOTE_EXCEPTION_TYPE_REF, RPC_CLOSE_CODE_UNSUPPORTED_FORMAT, type RemoteHandshake, type RpcCallOptions, RpcCallStage, RpcCallTimeouts, RpcCallTypeId, RpcClientPeer, RpcClientPeerReconnectDelayer, type RpcConnection, RpcConnectionState, type RpcConnectionUrlResolver, type RpcDeserializedMessage, type RpcDispatchContext, RpcError, type RpcErrorFilter, type RpcExceptionInfo, RpcHub, RpcInboundCall, RpcInboundCallTracker, RpcJsonSerializationFormat, RpcLimits, type RpcLogScope, type RpcMessage, RpcMessageChannelConnection, RpcMessagePackCompactSerializationFormat, RpcMessagePackSerializationFormat, type RpcMethodDef, type RpcMethodDefInput, RpcMethodRegistry, type RpcObjectId, RpcObjectKind, RpcOutboundCall, RpcOutboundCallTracker, RpcPeer, RpcPeerChangeKind, type RpcPeerFactory, type RpcPeerState, RpcPeerStateKind, RpcPeerStateMonitor, type RpcReceivedMessage, type RpcReconnectProofParameters, RpcRefBuilder, RpcRemoteExecutionMode, RpcRemoteObjectTracker, RpcSerializationFormat, RpcSerializationFormatResolver, RpcServerPeer, type RpcServiceDef, RpcServiceHost, type RpcServiceImpl, RpcSharedObjectTracker, RpcStream, type RpcStreamOptions, type RpcStreamRef, RpcStreamSender, type RpcStreamSource, RpcSystemCallHandler, RpcSystemCallSender, RpcSystemCalls, RpcType, RpcWebSocketConnection, type RpcWireData, type ServiceMeta, type WebSocketLike, type WebSocketServer, WebSocketState, computeMethodHash, computeReconnectProof, createBinaryEncoder, createMessageChannelPair, createRpcClient, defaultBinaryDecoder, defaultBinaryEncoder, defaultConnectionUrlResolver, defineRpcService, deserializeBinaryMessage, deserializeCompactBinaryMessage, deserializeMessage, genericErrorFilter, getLogs, getMethodsMeta, getServiceMeta, getStateDescription, isConnected, isReconnectProofSupported, likelyConnected, parseStreamRef, readPolymorphismMarker, rpcMethod, rpcService, serializeBinaryFrame, serializeBinaryMessage, serializeCompactBinaryMessage, serializeFrame, serializeMessage, splitBinaryFrame, splitCompactBinaryFrame, splitFrame, toExceptionInfo, toRpcStream, wireMethodName, xxh3_64, xxh3_64str };
package/dist/index.d.ts CHANGED
@@ -522,6 +522,10 @@ declare class RpcOutboundCallTracker {
522
522
  remove(callId: number): RpcOutboundCall | undefined;
523
523
  values(): IterableIterator<RpcOutboundCall>;
524
524
  activeCallIds(): number[];
525
+ /** Calls handed to the transport at least once. Must be snapshotted BEFORE the
526
+ * peer enters `Connected` — that flushes every queued call, making queued and
527
+ * in-flight calls indistinguishable. Mirrors .NET's `GetSentCalls`. */
528
+ getSentCalls(): RpcOutboundCall[];
525
529
  /** Reject all pending calls with the given error.
526
530
  * Stage-3 compute calls (result resolved, awaiting invalidation) are kept in the tracker. */
527
531
  rejectAll(error: Error): void;
@@ -1071,6 +1075,14 @@ declare const enum RpcConnectionState {
1071
1075
  Handshaking = 2,
1072
1076
  Connected = 3
1073
1077
  }
1078
+ /** Outcome of comparing an incoming handshake with the previous one. Mirrors
1079
+ * .NET `RpcPeerChangeKind` — `ChangedToVeryFirst` lets the first handshake skip
1080
+ * reconnect processing, since there's no prior connection to reconcile with. */
1081
+ declare const enum RpcPeerChangeKind {
1082
+ Unchanged = 0,
1083
+ ChangedToVeryFirst = 1,
1084
+ Changed = 2
1085
+ }
1074
1086
  /** Client-side RPC peer — initiates WebSocket connection. ref = URL. */
1075
1087
  declare class RpcClientPeer extends RpcPeer {
1076
1088
  private _disposed;
@@ -1084,7 +1096,10 @@ declare class RpcClientPeer extends RpcPeer {
1084
1096
  * `connectionState.Handshake.Index` path in
1085
1097
  * `RpcOutboundCallTracker.TryReconnect`. */
1086
1098
  private _remoteHandshakeIndex;
1087
- private _lastRemotePeerId;
1099
+ /** Mirrors .NET's `lastHandshake` local in `RpcPeer.OnRun`: first-ness is keyed
1100
+ * off "was there a previous handshake", not off `RemotePeerId` — a legacy server
1101
+ * sends none, so every one of its handshakes would look like the first. */
1102
+ private _lastHandshake;
1088
1103
  private _pendingHandshake;
1089
1104
  private _reconnectsAt;
1090
1105
  /** Server-issued reconnect secret, from the most recent handshake that
@@ -1166,7 +1181,10 @@ declare class RpcClientPeer extends RpcPeer {
1166
1181
  protected run(): Promise<void>;
1167
1182
  private _runImpl;
1168
1183
  /**
1169
- * Reconcile outbound calls after reconnection, then flush pending sends.
1184
+ * Reconcile the calls that were in flight on the connection that just died
1185
+ * (`sentCalls`), then resend the survivors. Calls still waiting for a
1186
+ * connection are deliberately NOT passed in — `AllowReconnect`/`AllowResend`
1187
+ * don't apply to them, and entering `Connected` already sends them.
1170
1188
  *
1171
1189
  * On peer change (different server hubId) or with binary wire format —
1172
1190
  * we blind-resend every eligible call.
@@ -1204,7 +1222,7 @@ declare class RpcClientPeer extends RpcPeer {
1204
1222
  * `RpcHandshake.GetPeerChangeKind` keys off `RemotePeerId`, not
1205
1223
  * `RemoteHubId` (an idle server peer can be replaced while keeping the
1206
1224
  * same hub id). On a change it clears the inbound tracker and fires
1207
- * `peerChanged`; the very first handshake is never a change. */
1225
+ * `peerChanged`; the very first handshake is `ChangedToVeryFirst`. */
1208
1226
  private _detectPeerChange;
1209
1227
  protected _onHandshakeReceived(handshake: RemoteHandshake): void;
1210
1228
  close(): void;
@@ -1620,4 +1638,4 @@ declare function xxh3_64str(input: string, seed?: bigint): bigint;
1620
1638
  */
1621
1639
  declare function computeMethodHash(methodName: string): number;
1622
1640
 
1623
- export { ARG_DELIMITER, ENVELOPE_DELIMITER, FRAME_DELIMITER, type IRpcObject, IncreasingSeqCompressor, type MethodMeta, REMOTE_EXCEPTION_TYPE_REF, RPC_CLOSE_CODE_UNSUPPORTED_FORMAT, type RemoteHandshake, type RpcCallOptions, RpcCallStage, RpcCallTimeouts, RpcCallTypeId, RpcClientPeer, RpcClientPeerReconnectDelayer, type RpcConnection, RpcConnectionState, type RpcConnectionUrlResolver, type RpcDeserializedMessage, type RpcDispatchContext, RpcError, type RpcErrorFilter, type RpcExceptionInfo, RpcHub, RpcInboundCall, RpcInboundCallTracker, RpcJsonSerializationFormat, RpcLimits, type RpcLogScope, type RpcMessage, RpcMessageChannelConnection, RpcMessagePackCompactSerializationFormat, RpcMessagePackSerializationFormat, type RpcMethodDef, type RpcMethodDefInput, RpcMethodRegistry, type RpcObjectId, RpcObjectKind, RpcOutboundCall, RpcOutboundCallTracker, RpcPeer, type RpcPeerFactory, type RpcPeerState, RpcPeerStateKind, RpcPeerStateMonitor, type RpcReceivedMessage, type RpcReconnectProofParameters, RpcRefBuilder, RpcRemoteExecutionMode, RpcRemoteObjectTracker, RpcSerializationFormat, RpcSerializationFormatResolver, RpcServerPeer, type RpcServiceDef, RpcServiceHost, type RpcServiceImpl, RpcSharedObjectTracker, RpcStream, type RpcStreamOptions, type RpcStreamRef, RpcStreamSender, type RpcStreamSource, RpcSystemCallHandler, RpcSystemCallSender, RpcSystemCalls, RpcType, RpcWebSocketConnection, type RpcWireData, type ServiceMeta, type WebSocketLike, type WebSocketServer, WebSocketState, computeMethodHash, computeReconnectProof, createBinaryEncoder, createMessageChannelPair, createRpcClient, defaultBinaryDecoder, defaultBinaryEncoder, defaultConnectionUrlResolver, defineRpcService, deserializeBinaryMessage, deserializeCompactBinaryMessage, deserializeMessage, genericErrorFilter, getLogs, getMethodsMeta, getServiceMeta, getStateDescription, isConnected, isReconnectProofSupported, likelyConnected, parseStreamRef, readPolymorphismMarker, rpcMethod, rpcService, serializeBinaryFrame, serializeBinaryMessage, serializeCompactBinaryMessage, serializeFrame, serializeMessage, splitBinaryFrame, splitCompactBinaryFrame, splitFrame, toExceptionInfo, toRpcStream, wireMethodName, xxh3_64, xxh3_64str };
1641
+ export { ARG_DELIMITER, ENVELOPE_DELIMITER, FRAME_DELIMITER, type IRpcObject, IncreasingSeqCompressor, type MethodMeta, REMOTE_EXCEPTION_TYPE_REF, RPC_CLOSE_CODE_UNSUPPORTED_FORMAT, type RemoteHandshake, type RpcCallOptions, RpcCallStage, RpcCallTimeouts, RpcCallTypeId, RpcClientPeer, RpcClientPeerReconnectDelayer, type RpcConnection, RpcConnectionState, type RpcConnectionUrlResolver, type RpcDeserializedMessage, type RpcDispatchContext, RpcError, type RpcErrorFilter, type RpcExceptionInfo, RpcHub, RpcInboundCall, RpcInboundCallTracker, RpcJsonSerializationFormat, RpcLimits, type RpcLogScope, type RpcMessage, RpcMessageChannelConnection, RpcMessagePackCompactSerializationFormat, RpcMessagePackSerializationFormat, type RpcMethodDef, type RpcMethodDefInput, RpcMethodRegistry, type RpcObjectId, RpcObjectKind, RpcOutboundCall, RpcOutboundCallTracker, RpcPeer, RpcPeerChangeKind, type RpcPeerFactory, type RpcPeerState, RpcPeerStateKind, RpcPeerStateMonitor, type RpcReceivedMessage, type RpcReconnectProofParameters, RpcRefBuilder, RpcRemoteExecutionMode, RpcRemoteObjectTracker, RpcSerializationFormat, RpcSerializationFormatResolver, RpcServerPeer, type RpcServiceDef, RpcServiceHost, type RpcServiceImpl, RpcSharedObjectTracker, RpcStream, type RpcStreamOptions, type RpcStreamRef, RpcStreamSender, type RpcStreamSource, RpcSystemCallHandler, RpcSystemCallSender, RpcSystemCalls, RpcType, RpcWebSocketConnection, type RpcWireData, type ServiceMeta, type WebSocketLike, type WebSocketServer, WebSocketState, computeMethodHash, computeReconnectProof, createBinaryEncoder, createMessageChannelPair, createRpcClient, defaultBinaryDecoder, defaultBinaryEncoder, defaultConnectionUrlResolver, defineRpcService, deserializeBinaryMessage, deserializeCompactBinaryMessage, deserializeMessage, genericErrorFilter, getLogs, getMethodsMeta, getServiceMeta, getStateDescription, isConnected, isReconnectProofSupported, likelyConnected, parseStreamRef, readPolymorphismMarker, rpcMethod, rpcService, serializeBinaryFrame, serializeBinaryMessage, serializeCompactBinaryMessage, serializeFrame, serializeMessage, splitBinaryFrame, splitCompactBinaryFrame, splitFrame, toExceptionInfo, toRpcStream, wireMethodName, xxh3_64, xxh3_64str };
package/dist/index.js CHANGED
@@ -751,6 +751,16 @@ var RpcOutboundCallTracker = class {
751
751
  activeCallIds() {
752
752
  return [...this._calls.keys()];
753
753
  }
754
+ /** Calls handed to the transport at least once. Must be snapshotted BEFORE the
755
+ * peer enters `Connected` — that flushes every queued call, making queued and
756
+ * in-flight calls indistinguishable. Mirrors .NET's `GetSentCalls`. */
757
+ getSentCalls() {
758
+ const calls = [];
759
+ for (const call of this._calls.values())
760
+ if (call.sentAt !== 0)
761
+ calls.push(call);
762
+ return calls;
763
+ }
754
764
  /** Reject all pending calls with the given error.
755
765
  * Stage-3 compute calls (result resolved, awaiting invalidation) are kept in the tracker. */
756
766
  rejectAll(error) {
@@ -3065,6 +3075,13 @@ var RpcConnectionState = /* @__PURE__ */ ((RpcConnectionState2) => {
3065
3075
  RpcConnectionState2[RpcConnectionState2["Connected"] = 3] = "Connected";
3066
3076
  return RpcConnectionState2;
3067
3077
  })(RpcConnectionState || {});
3078
+ var RpcPeerChangeKind = /* @__PURE__ */ ((RpcPeerChangeKind2) => {
3079
+ RpcPeerChangeKind2[RpcPeerChangeKind2["Unchanged"] = 0] = "Unchanged";
3080
+ RpcPeerChangeKind2[RpcPeerChangeKind2["ChangedToVeryFirst"] = 1] = "ChangedToVeryFirst";
3081
+ RpcPeerChangeKind2[RpcPeerChangeKind2["Changed"] = 2] = "Changed";
3082
+ return RpcPeerChangeKind2;
3083
+ })(RpcPeerChangeKind || {});
3084
+ var peerChangeKindNames = ["Unchanged", "ChangedToVeryFirst", "Changed"];
3068
3085
  var RpcClientPeer = class extends RpcPeer {
3069
3086
  _disposed = false;
3070
3087
  /** Aborted when the peer is stopped/disposed — threaded into the reconnect
@@ -3077,7 +3094,10 @@ var RpcClientPeer = class extends RpcPeer {
3077
3094
  * `connectionState.Handshake.Index` path in
3078
3095
  * `RpcOutboundCallTracker.TryReconnect`. */
3079
3096
  _remoteHandshakeIndex = 0;
3080
- _lastRemotePeerId;
3097
+ /** Mirrors .NET's `lastHandshake` local in `RpcPeer.OnRun`: first-ness is keyed
3098
+ * off "was there a previous handshake", not off `RemotePeerId` — a legacy server
3099
+ * sends none, so every one of its handshakes would look like the first. */
3100
+ _lastHandshake;
3081
3101
  _pendingHandshake;
3082
3102
  _reconnectsAt = 0;
3083
3103
  /** Server-issued reconnect secret, from the most recent handshake that
@@ -3158,10 +3178,11 @@ var RpcClientPeer = class extends RpcPeer {
3158
3178
  * self-invalidate and remote/shared objects are disposed). Pass `false`
3159
3179
  * to simulate a same-peer reconnect in tests. */
3160
3180
  connectWith(conn, isPeerChanged = true) {
3181
+ const sentCalls = this.outboundCalls.getSentCalls();
3161
3182
  this.setupConnection(conn);
3162
3183
  this._isConnected = true;
3163
3184
  this.connectionStateChanged.trigger(3 /* Connected */);
3164
- void this._reconnect(isPeerChanged);
3185
+ void this._reconnect(sentCalls, isPeerChanged);
3165
3186
  }
3166
3187
  /** Kick off the reconnect loop. Idempotent — subsequent calls are
3167
3188
  * no-ops; await `peer.whenRunning` if you need the loop's completion
@@ -3292,11 +3313,19 @@ var RpcClientPeer = class extends RpcPeer {
3292
3313
  this._remoteHandshakeIndex = remoteHandshake.Index ?? 0;
3293
3314
  if (remoteHandshake.Secret)
3294
3315
  this._reconnectSecret = remoteHandshake.Secret;
3295
- const isPeerChanged = this._detectPeerChange(remoteHandshake);
3296
- infoLog?.log(`'${this.ref}': Handshake succeeded, peerChanged=${isPeerChanged}`);
3316
+ const peerChangeKind = this._detectPeerChange(remoteHandshake);
3317
+ infoLog?.log(
3318
+ `'${this.ref}': Handshake succeeded, peerChangeKind=${peerChangeKindNames[peerChangeKind]}`
3319
+ );
3320
+ const sentCalls = this.outboundCalls.getSentCalls();
3297
3321
  this._setConnectionState(3 /* Connected */);
3298
3322
  connectedAt = Date.now();
3299
- await this._reconnect(isPeerChanged, closedController.signal);
3323
+ if (peerChangeKind !== 1 /* ChangedToVeryFirst */)
3324
+ await this._reconnect(
3325
+ sentCalls,
3326
+ peerChangeKind === 2 /* Changed */,
3327
+ closedController.signal
3328
+ );
3300
3329
  await whenClosed;
3301
3330
  } catch (e) {
3302
3331
  debugLog2?.log(`'${this.ref}': run() iteration failed:`, e);
@@ -3318,7 +3347,10 @@ var RpcClientPeer = class extends RpcPeer {
3318
3347
  }
3319
3348
  }
3320
3349
  /**
3321
- * Reconcile outbound calls after reconnection, then flush pending sends.
3350
+ * Reconcile the calls that were in flight on the connection that just died
3351
+ * (`sentCalls`), then resend the survivors. Calls still waiting for a
3352
+ * connection are deliberately NOT passed in — `AllowReconnect`/`AllowResend`
3353
+ * don't apply to them, and entering `Connected` already sends them.
3322
3354
  *
3323
3355
  * On peer change (different server hubId) or with binary wire format —
3324
3356
  * we blind-resend every eligible call.
@@ -3336,7 +3368,7 @@ var RpcClientPeer = class extends RpcPeer {
3336
3368
  * are always self-invalidated — TS doesn't track compute-call stages
3337
3369
  * across reconnect, so the safest behavior is to force a fresh compute.
3338
3370
  */
3339
- async _reconnect(isPeerChanged, closedSignal) {
3371
+ async _reconnect(sentCalls, isPeerChanged, closedSignal) {
3340
3372
  if (this._connection === void 0) return;
3341
3373
  if (isPeerChanged) {
3342
3374
  this.remoteObjects.disconnectAll();
@@ -3345,7 +3377,7 @@ var RpcClientPeer = class extends RpcPeer {
3345
3377
  this.remoteObjects.reconnectAll();
3346
3378
  }
3347
3379
  const eligible = [];
3348
- for (const call of [...this.outboundCalls.values()]) {
3380
+ for (const call of sentCalls) {
3349
3381
  const mode = call.remoteExecutionMode;
3350
3382
  if (!(mode & 2)) {
3351
3383
  if (!call.result.isCompleted)
@@ -3366,8 +3398,7 @@ var RpcClientPeer = class extends RpcPeer {
3366
3398
  continue;
3367
3399
  }
3368
3400
  eligible.push(call);
3369
- if (call.sentAt !== 0)
3370
- call.sentAt = Date.now();
3401
+ call.sentAt = Date.now();
3371
3402
  }
3372
3403
  let unknownIds = null;
3373
3404
  if (!isPeerChanged && eligible.length > 0) {
@@ -3455,19 +3486,18 @@ var RpcClientPeer = class extends RpcPeer {
3455
3486
  * `RpcHandshake.GetPeerChangeKind` keys off `RemotePeerId`, not
3456
3487
  * `RemoteHubId` (an idle server peer can be replaced while keeping the
3457
3488
  * same hub id). On a change it clears the inbound tracker and fires
3458
- * `peerChanged`; the very first handshake is never a change. */
3489
+ * `peerChanged`; the very first handshake is `ChangedToVeryFirst`. */
3459
3490
  _detectPeerChange(handshake) {
3460
- const remotePeerId = handshake.RemotePeerId;
3461
- if (remotePeerId === void 0)
3462
- return false;
3463
- const isPeerChanged = this._lastRemotePeerId !== void 0 && this._lastRemotePeerId !== remotePeerId;
3464
- this._lastRemotePeerId = remotePeerId;
3465
- if (isPeerChanged) {
3466
- this.inboundCalls.clear();
3467
- infoLog?.log(`'${this.ref}': Peer changed`);
3468
- this.peerChanged.trigger();
3469
- }
3470
- return isPeerChanged;
3491
+ const lastHandshake = this._lastHandshake;
3492
+ this._lastHandshake = handshake;
3493
+ if (lastHandshake === void 0)
3494
+ return 1 /* ChangedToVeryFirst */;
3495
+ if (handshake.RemotePeerId === lastHandshake.RemotePeerId)
3496
+ return 0 /* Unchanged */;
3497
+ this.inboundCalls.clear();
3498
+ infoLog?.log(`'${this.ref}': Peer changed`);
3499
+ this.peerChanged.trigger();
3500
+ return 2 /* Changed */;
3471
3501
  }
3472
3502
  _onHandshakeReceived(handshake) {
3473
3503
  this._pendingHandshake?.resolve(handshake);
@@ -4766,6 +4796,7 @@ export {
4766
4796
  RpcOutboundCall,
4767
4797
  RpcOutboundCallTracker,
4768
4798
  RpcPeer,
4799
+ RpcPeerChangeKind,
4769
4800
  RpcPeerStateKind,
4770
4801
  RpcPeerStateMonitor,
4771
4802
  RpcRefBuilder,