@actuallab/rpc 13.0.25 → 13.0.167

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.ts CHANGED
@@ -76,6 +76,22 @@ declare const defaultBinaryDecoder: Decoder<undefined>;
76
76
  * with the same initial buffer size without needing to reach into
77
77
  * this module's private constants. */
78
78
  declare function createBinaryEncoder(): Encoder;
79
+ /**
80
+ * Parses a polymorphism marker (as written by .NET `ByteTypeSerializer`) at
81
+ * `offset`. The msgpack6 format prefixes every *polymorphic* argument/result
82
+ * with a 2-byte little-endian length:
83
+ * - 0 → expected (non-polymorphic) type — the `\0\0` fast path
84
+ * - 1 → NullValue (the value itself is absent)
85
+ * - >= 2 → a derived type (2-byte length + 2-byte hash + UTF-8 name)
86
+ *
87
+ * Returns how many bytes the marker occupies and whether the value is a
88
+ * NullValue. Derived-type markers are unsupported by the TS client and throw a
89
+ * clear error instead of letting the marker bytes corrupt the msgpack frame.
90
+ */
91
+ declare function readPolymorphismMarker(data: Uint8Array, offset: number): {
92
+ bytesRead: number;
93
+ isNull: boolean;
94
+ };
79
95
  /**
80
96
  * Serializes an RpcMessage + args into V5 binary format (msgpack6np).
81
97
  *
@@ -202,9 +218,7 @@ declare abstract class RpcSerializationFormat {
202
218
  static NewtonsoftJsonV5: RpcSerializationFormat;
203
219
  static NewtonsoftJsonV5NP: RpcSerializationFormat;
204
220
  static MessagePackV6: RpcSerializationFormat;
205
- static MemoryPackV6: RpcSerializationFormat;
206
221
  static MessagePackV6C: RpcSerializationFormat;
207
- static MemoryPackV6C: RpcSerializationFormat;
208
222
  static All: readonly RpcSerializationFormat[];
209
223
  /** Convenience shortcut for RpcSerializationFormatResolver.Default.get(key). */
210
224
  static get(key: string): RpcSerializationFormat;
@@ -225,7 +239,7 @@ declare class RpcJsonSerializationFormat extends RpcSerializationFormat {
225
239
  serializeBinaryFrame(): Uint8Array;
226
240
  }
227
241
  /**
228
- * MessagePack binary format — "msgpack6" / "mempack6" (V5 wire format).
242
+ * MessagePack binary format — "msgpack6" (V5 wire format).
229
243
  */
230
244
  declare class RpcMessagePackSerializationFormat extends RpcSerializationFormat {
231
245
  readonly key: string;
@@ -240,7 +254,7 @@ declare class RpcMessagePackSerializationFormat extends RpcSerializationFormat {
240
254
  createDecoder(): Decoder;
241
255
  }
242
256
  /**
243
- * MessagePack compact binary format — "msgpack6c" / "mempack6c" (V5Compact).
257
+ * MessagePack compact binary format — "msgpack6c" (V5Compact).
244
258
  * Uses 4-byte method hash instead of full method name.
245
259
  * Registry is passed via parameters — format instance is immutable.
246
260
  */
@@ -385,6 +399,22 @@ declare function createMessageChannelPair(): [
385
399
  RpcMessageChannelConnection
386
400
  ];
387
401
 
402
+ /**
403
+ * Connect/run timeouts for an outbound RPC call, enforced by the peer's
404
+ * maintenance loop. `Infinity` means "no timeout".
405
+ */
406
+ declare class RpcCallTimeouts {
407
+ /** Both timeouts unbounded — the query default (.NET `RpcCallTimeouts.None`). */
408
+ static readonly None: RpcCallTimeouts;
409
+ /** Command default: 1.5 s connect / 10 s run (.NET `RpcCallTimeouts.Default.Command`). */
410
+ static readonly Command: RpcCallTimeouts;
411
+ /** Max time a call may wait for the connection before it is sent. */
412
+ readonly connectTimeoutMs: number;
413
+ /** Max time a sent call may stay unanswered before it is failed. */
414
+ readonly runTimeoutMs: number;
415
+ constructor(connectTimeoutMs?: number, runTimeoutMs?: number);
416
+ }
417
+
388
418
  /** Controls outbound RPC call behavior regarding connection waiting, reconnection, and resending. */
389
419
  declare const RpcRemoteExecutionMode: {
390
420
  /** Wait for connection if disconnected when the call is made. */
@@ -408,6 +438,8 @@ interface RpcMethodDef {
408
438
  readonly stream: boolean;
409
439
  readonly noWait: boolean;
410
440
  readonly remoteExecutionMode: RpcRemoteExecutionMode;
441
+ /** Per-method connect/run timeouts (R12). `undefined` means unbounded. */
442
+ readonly timeouts?: RpcCallTimeouts;
411
443
  }
412
444
  /** Describes an RPC service — its name and method definitions. */
413
445
  interface RpcServiceDef {
@@ -422,6 +454,8 @@ interface RpcMethodDefInput {
422
454
  wireArgCount?: number;
423
455
  /** Override for remoteExecutionMode. Default: RpcRemoteExecutionMode.Default (7). NoWait methods always use 0. */
424
456
  remoteExecutionMode?: RpcRemoteExecutionMode;
457
+ /** Per-method connect/run timeouts (R12). Default: unbounded. */
458
+ timeouts?: RpcCallTimeouts;
425
459
  }
426
460
  declare const RpcType: {
427
461
  readonly object: symbol;
@@ -445,6 +479,14 @@ declare class RpcOutboundCall {
445
479
  readonly removeOnOk: boolean;
446
480
  /** The serialized wire data — stored for re-sending on reconnect. */
447
481
  serializedWireData: string | Uint8Array;
482
+ /** Per-call connect/run timeouts enforced by the peer's maintenance loop
483
+ * (R12). `undefined` means unbounded (the query default). */
484
+ timeouts: RpcCallTimeouts | undefined;
485
+ /** `Date.now()` when this call was created (used for the connect timeout). */
486
+ readonly startedAt: number;
487
+ /** `Date.now()` when this call was last put on the wire, or 0 if it hasn't
488
+ * been sent yet (used for the run timeout). */
489
+ sentAt: number;
448
490
  /**
449
491
  * Bitfield of {@link RpcCallStage} flags indicating how far this call
450
492
  * has progressed. Used by the `$sys.Reconnect` protocol to tell the
@@ -491,13 +533,31 @@ declare class RpcInboundCall {
491
533
  readonly callId: number;
492
534
  readonly method: string;
493
535
  readonly args: unknown[];
536
+ /** 0 = still processing, 1 = result computed and sent at least once. */
537
+ completedStage: number;
538
+ private _resend;
539
+ private readonly _abortController;
494
540
  constructor(callId: number, method: string, args: unknown[]);
541
+ /** Aborted when the remote peer cancels this call via `$sys.Cancel` (R17).
542
+ * Threaded into the service handler so it can abort in-flight work. */
543
+ get signal(): AbortSignal;
544
+ /** True once the remote peer cancelled this call — the response is then
545
+ * suppressed even though the call may still be registered (R9 dedup). */
546
+ get isCancelled(): boolean;
547
+ cancel(): void;
548
+ setResult(resend: () => void): void;
549
+ resendResult(): void;
495
550
  }
496
551
  /** Manages inbound calls by their RelatedId. */
497
552
  declare class RpcInboundCallTracker {
498
553
  private _calls;
554
+ private _completedIds;
555
+ /** Cap on retained completed calls — see `RpcLimits.completedInboundCallsLimit`. */
556
+ completedCallsLimit: number;
499
557
  get size(): number;
500
558
  register(call: RpcInboundCall): void;
559
+ getOrRegister(call: RpcInboundCall): RpcInboundCall;
560
+ markCompleted(call: RpcInboundCall): void;
501
561
  get(callId: number): RpcInboundCall | undefined;
502
562
  remove(callId: number): RpcInboundCall | undefined;
503
563
  clear(): void;
@@ -529,6 +589,12 @@ declare class RpcError extends Error {
529
589
  readonly typeName?: string;
530
590
  constructor(message: string, typeName?: string);
531
591
  }
592
+ declare const REMOTE_EXCEPTION_TYPE_REF = "ActualLab.Serialization.RemoteException, ActualLab.Core";
593
+ /** Wire shape of .NET `ExceptionInfo` for a JS error sent to a .NET peer. */
594
+ declare function toExceptionInfo(error: unknown): {
595
+ TypeRef: string;
596
+ Message: string;
597
+ };
532
598
 
533
599
  /**
534
600
  * Compresses and decompresses monotonically increasing sequences of
@@ -581,6 +647,12 @@ declare class RpcLimits {
581
647
  /** Process-wide default. Hubs read from this when they're constructed
582
648
  * unless caller assigns a custom instance to `hub.limits`. */
583
649
  static Default: RpcLimits;
650
+ /** Dev preset with a relaxed keep-alive timeout (5 min), matching .NET's
651
+ * debugger-attached `KeepAlivePeriod` (RpcLimits.cs:46-54). Activate
652
+ * explicitly — e.g. `RpcLimits.Default = RpcLimits.Debug` or per-hub
653
+ * `hub.limits = RpcLimits.Debug`. Never switched on automatically: the
654
+ * TS side can't detect a debugger on the server (decision D4). */
655
+ static readonly Debug: RpcLimits;
584
656
  /** Max time to wait for the WebSocket to enter the OPEN state. On a
585
657
  * hung connect (mobile after network change, half-open after sleep)
586
658
  * the browser can take ~2 min to emit `onerror`/`onclose`; without
@@ -588,6 +660,22 @@ declare class RpcLimits {
588
660
  connectTimeoutMs: number;
589
661
  /** Max time to wait for the server's handshake response after WS opens. */
590
662
  handshakeTimeoutMs: number;
663
+ /** If a connection lived less than this before dropping, a graceful close
664
+ * still counts as a failed attempt — the client keeps its growing
665
+ * `_tryIndex` instead of resetting it, so a crash-looping server sees
666
+ * increasing reconnect delays via `RetryDelaySeq`. Mirrors .NET
667
+ * `RpcLimits.PrematureDisconnectTimeout` (RpcLimits.cs:18). */
668
+ prematureDisconnectTimeoutMs: number;
669
+ /** Max completed inbound calls retained for duplicate-frame dedup
670
+ * (a resent call id re-sends the computed result instead of
671
+ * re-executing the handler). Deviation from .NET, which unregisters a
672
+ * call once its result is sent: TS clients blind-resend on reconnect,
673
+ * so completed calls are retained — bounded by this limit (oldest
674
+ * evicted first) to cap memory on long-lived connections. */
675
+ completedInboundCallsLimit: number;
676
+ /** How often each peer's maintenance loop scans outbound calls for
677
+ * timeouts (R12). Mirrors .NET `RpcLimits.CallTimeoutCheckPeriod`. */
678
+ callTimeoutCheckPeriodMs: number;
591
679
  /** Outbound `$sys.KeepAlive` send period. */
592
680
  keepAlivePeriodMs: number;
593
681
  /** Reaper threshold — connection is force-closed (and the reconnect
@@ -597,6 +685,13 @@ declare class RpcLimits {
597
685
  * `keepAlivePeriodMs + stall_duration`, so with these defaults the
598
686
  * tolerated stall is ~15 s. */
599
687
  keepAliveTimeoutMs: number;
688
+ /** How long a server peer stays in `hub.peers` after its connection closes
689
+ * before it's stopped and removed. A same-peer reconnect (`accept()`)
690
+ * within this window cancels the pending removal, so brief drops don't
691
+ * discard the peer's trackers. Mirrors .NET's server-peer shutdown timeout
692
+ * (`RpcPeerOptions.ServerPeerShutdownTimeoutProvider`, 3-15 min); the TS
693
+ * port uses a fixed floor-matching default. */
694
+ serverPeerCloseTimeoutMs: number;
600
695
  constructor(overrides?: Partial<RpcLimits>);
601
696
  }
602
697
 
@@ -605,16 +700,21 @@ declare class RpcClientPeerReconnectDelayer extends RetryDelayer {
605
700
  }
606
701
 
607
702
  type RpcServiceImpl = Record<string, ((...args: unknown[]) => unknown) | undefined>;
608
- /** Context passed to service dispatch — carries callId and connection for compute tracking. */
703
+ /** Context passed to service dispatch — carries callId, the inbound CallType,
704
+ * the connection, and the peer for compute-call invalidation tracking. */
609
705
  interface RpcDispatchContext {
610
706
  __rpcDispatch: true;
611
707
  callId: number;
708
+ callType: number;
612
709
  connection: RpcConnection;
710
+ /** Aborted when the inbound call is cancelled via `$sys.Cancel` (R17). */
711
+ signal?: AbortSignal;
712
+ peer: RpcPeer;
613
713
  }
614
714
  /** Dispatches inbound RPC calls to registered service implementations. */
615
715
  declare class RpcServiceHost {
616
716
  private _methods;
617
- register(def: RpcServiceDef, impl: RpcServiceImpl): void;
717
+ register(def: RpcServiceDef, impl: RpcServiceImpl, receiver?: object): void;
618
718
  dispatch(wireMethod: string, args: unknown[], context?: RpcDispatchContext): Promise<unknown>;
619
719
  getMethodDef(wireMethod: string): RpcMethodDef | undefined;
620
720
  }
@@ -640,6 +740,7 @@ declare function rpcService(serviceName: string): <T extends AnyConstructor>(_ta
640
740
  declare function rpcMethod(options?: {
641
741
  returns?: symbol;
642
742
  remoteExecutionMode?: number;
743
+ argCount?: number;
643
744
  }): <This, Args extends unknown[], Return>(target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>) => (this: This, ...args: Args) => Return;
644
745
 
645
746
  /**
@@ -671,12 +772,13 @@ declare class RpcSystemCallSender {
671
772
  private readonly _ackEndArgs;
672
773
  private static readonly NO_ERROR;
673
774
  registry?: RpcMethodRegistry;
674
- private _send;
775
+ protected _send(conn: RpcConnection, format: RpcSerializationFormat, envelope: RpcMessage, args?: unknown[]): void;
675
776
  handshake(conn: RpcConnection, format: RpcSerializationFormat, peerId: string, hubId: string, index: number): void;
676
777
  ok(conn: RpcConnection, format: RpcSerializationFormat, relatedId: number, result: unknown): void;
677
778
  error(conn: RpcConnection, format: RpcSerializationFormat, relatedId: number, error: unknown): void;
678
779
  cancel(conn: RpcConnection, format: RpcSerializationFormat, relatedId: number): void;
679
780
  keepAlive(conn: RpcConnection, format: RpcSerializationFormat, activeCallIds: number[]): void;
781
+ disconnect(conn: RpcConnection, format: RpcSerializationFormat, localIds: number[]): void;
680
782
  item(conn: RpcConnection, format: RpcSerializationFormat, localId: number, index: number, item: unknown): void;
681
783
  batch(conn: RpcConnection, format: RpcSerializationFormat, localId: number, index: number, items: unknown[]): void;
682
784
  end(conn: RpcConnection, format: RpcSerializationFormat, localId: number, index: number, error?: {
@@ -705,6 +807,14 @@ declare class RpcHub {
705
807
  /** Shared reconnect delayer used by every client peer in this hub. Swap in
706
808
  * a custom subclass (e.g. app-level signal-gated) before peers start. */
707
809
  reconnectDelayer: RpcClientPeerReconnectDelayer;
810
+ /** Cache of client proxies keyed by peer, then by service name — so
811
+ * repeated {@link addClient} calls for the same service+peer return one
812
+ * proxy. All consumers then share a single computed/call/invalidation
813
+ * stream per logical value, matching .NET's singleton client proxies (F8).
814
+ * A later def registered under the same name extends the existing proxy
815
+ * with its extra methods (superset), so no consumer ever receives a proxy
816
+ * missing methods the def declares. */
817
+ private readonly _clientProxies;
708
818
  /** Connection-lifecycle timing limits. Peers constructed against this hub
709
819
  * read their initial `*Ms` field values from this instance; later
710
820
  * mutations affect only peers built afterward (existing peers can be
@@ -742,9 +852,14 @@ declare class RpcHub {
742
852
  getServerPeer(ref: string, factory?: RpcPeerFactory): RpcServerPeer;
743
853
  /** Register a service with optional server method wrapping for custom call types. */
744
854
  addService(defOrContract: RpcServiceDef | (AnyConstructor), impl: RpcServiceImpl): void;
745
- /** Create a typed client proxy for a service on a remote peer. */
855
+ /** Create a typed client proxy for a service on a remote peer. Repeated calls
856
+ * for the same (peer, service name) return one shared proxy; a def carrying
857
+ * extra methods extends it (F8). */
746
858
  addClient<T extends object>(peer: RpcPeer, defOrContract: RpcServiceDef | (AnyConstructor)): T;
747
859
  close(): void;
860
+ /** Create the hub's system-call sender. Override in FusionHub to add
861
+ * Fusion-specific system calls (e.g. $sys-c.Invalidate). */
862
+ protected _createSystemCallSender(): RpcSystemCallSender;
748
863
  /** Build an RpcServiceDef from decorator metadata on a contract class. Override in FusionHub for compute support. */
749
864
  protected _buildServiceDef(cls: AnyConstructor): RpcServiceDef;
750
865
  /** Resolve a service def from either a plain RpcServiceDef or a contract class. */
@@ -753,6 +868,8 @@ declare class RpcHub {
753
868
  protected _wrapServerMethod(_methodDef: RpcMethodDef, fn: (...args: unknown[]) => unknown, _impl: object): (...args: unknown[]) => unknown;
754
869
  /** Create a client method for the given methodDef. Override in FusionHub for custom call types. */
755
870
  protected _createClientMethod(peer: RpcPeer, methodDef: RpcMethodDef): (...args: unknown[]) => unknown;
871
+ private _createClientProxy;
872
+ private _extendClientProxy;
756
873
  }
757
874
 
758
875
  interface RpcObjectId {
@@ -811,6 +928,8 @@ interface RpcCallOptions {
811
928
  signal?: AbortSignal;
812
929
  /** Bitfield of RpcRemoteExecutionMode flags (default: 7 = Default). */
813
930
  remoteExecutionMode?: number;
931
+ /** Per-call connect/run timeouts (R12). Default: unbounded. */
932
+ timeouts?: RpcCallTimeouts;
814
933
  }
815
934
  /** Data extracted from an inbound $sys.Handshake message. */
816
935
  interface RemoteHandshake {
@@ -835,6 +954,10 @@ declare abstract class RpcPeer {
835
954
  * attempt (the reconnect delay is part of this phase); `Connected` is
836
955
  * entered only after the handshake has succeeded. */
837
956
  readonly connectionStateChanged: EventHandlerSet<RpcConnectionState>;
957
+ /** Index of the handshake THIS peer most recently sent. Used to reject a
958
+ * stale `$sys.Reconnect` that references an older connection generation
959
+ * (C# `RpcSystemCalls.Reconnect`'s `ownHandshake.Index` check). */
960
+ protected _ownHandshakeIndex: number;
838
961
  protected _connection: RpcConnection | undefined;
839
962
  /** Mirror of `_connectionState === Connected`. True only after the
840
963
  * handshake round-trip completes; outbound `call()` checks this to
@@ -846,6 +969,7 @@ declare abstract class RpcPeer {
846
969
  protected _connectionState: RpcConnectionState;
847
970
  private _keepAliveTimer;
848
971
  private _keepAliveWatchdog;
972
+ private _maintainTimer;
849
973
  /** Wall-clock time of the last inbound `$sys.KeepAlive`, or 0 if none yet
850
974
  * for the current connection. Useful for diagnostics. */
851
975
  private _lastKeepAliveAt;
@@ -856,9 +980,16 @@ declare abstract class RpcPeer {
856
980
  * at construction; set directly to override on a single peer. */
857
981
  keepAliveTimeoutMs: number;
858
982
  protected constructor(hub: RpcHub, ref: string);
983
+ /** Fail outbound calls whose per-call {@link RpcCallTimeouts} elapsed —
984
+ * the connect timeout while a call still awaits the wire, the run timeout
985
+ * once it has been sent. Mirrors .NET `RpcOutboundCallTracker.Maintain`
986
+ * (RpcCallTrackers.cs:108-207). Calls without timeouts (queries) never
987
+ * time out here. */
988
+ private _maintainOutboundCalls;
859
989
  get connection(): RpcConnection | undefined;
860
990
  get connectionState(): RpcConnectionState;
861
991
  get isConnected(): boolean;
992
+ get ownHandshakeIndex(): number;
862
993
  protected _setConnectionState(value: RpcConnectionState): void;
863
994
  /** Resolves on the next transition into `Connected` — or immediately if
864
995
  * already in that state. */
@@ -914,15 +1045,17 @@ declare const enum RpcConnectionState {
914
1045
  /** Client-side RPC peer — initiates WebSocket connection. ref = URL. */
915
1046
  declare class RpcClientPeer extends RpcPeer {
916
1047
  private _disposed;
1048
+ /** Aborted when the peer is stopped/disposed — threaded into the reconnect
1049
+ * delay so a pending delay rejects promptly instead of parking. */
1050
+ private readonly _stopController;
917
1051
  private _tryIndex;
918
- private _handshakeIndex;
919
1052
  /** Index from the MOST RECENTLY RECEIVED server handshake — sent back
920
1053
  * to the server in `$sys.Reconnect:3` so the server can verify we're
921
1054
  * talking about the current connection. Mirrors .NET's
922
1055
  * `connectionState.Handshake.Index` path in
923
1056
  * `RpcOutboundCallTracker.TryReconnect`. */
924
1057
  private _remoteHandshakeIndex;
925
- private _lastRemoteHubId;
1058
+ private _lastRemotePeerId;
926
1059
  private _pendingHandshake;
927
1060
  private _reconnectsAt;
928
1061
  /** Base64url-encoded peer ID — matches .NET's RpcClientPeer.ClientId (Guid.ToBase64Url). */
@@ -943,6 +1076,10 @@ declare class RpcClientPeer extends RpcPeer {
943
1076
  * the connection attempt. Initialized from `hub.limits` at construction;
944
1077
  * set directly to override on a single peer. */
945
1078
  handshakeTimeoutMs: number;
1079
+ /** A connection that lived less than this before dropping does NOT reset
1080
+ * `_tryIndex`, so a crash-looping server sees growing reconnect delays.
1081
+ * Initialized from `hub.limits` at construction; override per peer. */
1082
+ prematureDisconnectTimeoutMs: number;
946
1083
  readonly peerChanged: EventHandlerSet<void>;
947
1084
  /** Fired when the server rejects the connection due to an unsupported serialization format (close code 4010). */
948
1085
  readonly unsupportedFormat: EventHandlerSet<{
@@ -1018,14 +1155,30 @@ declare class RpcClientPeer extends RpcPeer {
1018
1155
  * default for `Dictionary<int, byte[]>`.
1019
1156
  */
1020
1157
  private _reconcileReconnect;
1158
+ /** Detects a server-peer identity change by comparing the incoming
1159
+ * handshake's `RemotePeerId` with the last one — C#
1160
+ * `RpcHandshake.GetPeerChangeKind` keys off `RemotePeerId`, not
1161
+ * `RemoteHubId` (an idle server peer can be replaced while keeping the
1162
+ * same hub id). On a change it clears the inbound tracker and fires
1163
+ * `peerChanged`; the very first handshake is never a change. */
1164
+ private _detectPeerChange;
1021
1165
  protected _onHandshakeReceived(handshake: RemoteHandshake): void;
1022
1166
  close(): void;
1023
1167
  }
1024
1168
  /** Server-side RPC peer — wraps an accepted connection. ref = "server://{uuid}". */
1025
1169
  declare class RpcServerPeer extends RpcPeer {
1170
+ /** Grace period before an idle (disconnected) server peer is stopped and
1171
+ * removed from `hub.peers`; a re-`accept()` within it cancels removal.
1172
+ * Snapshotted from `hub.limits` at construction (F11). */
1173
+ serverPeerCloseTimeoutMs: number;
1174
+ private _closeTimer;
1175
+ private _isClosed;
1026
1176
  constructor(hub: RpcHub, ref: string);
1027
1177
  /** Accept an incoming connection — sets up message handling and handshake response. */
1028
1178
  accept(conn: RpcConnection): void;
1179
+ close(): void;
1180
+ private _armCloseTimer;
1181
+ private _clearCloseTimer;
1029
1182
  protected _onHandshakeReceived(_handshake: RemoteHandshake): void;
1030
1183
  }
1031
1184
 
@@ -1113,6 +1266,8 @@ declare class RpcStreamSender<T> implements IRpcObject {
1113
1266
  private _lastAckedIndex;
1114
1267
  private _abortController;
1115
1268
  private _iterator;
1269
+ private _pendingSendTimes;
1270
+ private _rttSamples;
1116
1271
  /** Total items skipped via real-time `canSkipTo` compaction. */
1117
1272
  private _skipCount;
1118
1273
  /** Fires after a $sys.Ack has been processed (post-compaction). The
@@ -1130,6 +1285,7 @@ declare class RpcStreamSender<T> implements IRpcObject {
1130
1285
  get nextIndex(): number;
1131
1286
  get lastAckIndex(): number;
1132
1287
  get skipCount(): number;
1288
+ get minRttMs(): number;
1133
1289
  private _acks;
1134
1290
  private _whenAckReady;
1135
1291
  constructor(peer: RpcPeer, ackPeriod?: number, ackAdvance?: number, allowReconnect?: boolean, isRealTime?: boolean, canSkipTo?: (item: T) => boolean, sourceUsesAbortSignal?: boolean, bufferSize?: number);
@@ -1144,6 +1300,7 @@ declare class RpcStreamSender<T> implements IRpcObject {
1144
1300
  * src/ActualLab.Rpc/Infrastructure/RpcSharedStream.cs:68-101.
1145
1301
  */
1146
1302
  onAck(nextIndex: number, hostId: string): void;
1303
+ private _sendDisconnect;
1147
1304
  /** Called by system call handler when $sys.AckEnd is received from the client. */
1148
1305
  onAckEnd(_hostId: string): void;
1149
1306
  /**
@@ -1179,6 +1336,7 @@ declare class RpcStreamSender<T> implements IRpcObject {
1179
1336
  private _tryProcessAcks;
1180
1337
  /** Wait for the ACK queue to have at least one entry (or `_ended`). */
1181
1338
  private _waitAckReady;
1339
+ private _sampleRtt;
1182
1340
  reconnect(): void;
1183
1341
  disconnect(): void;
1184
1342
  private _forceCloseIterator;
@@ -1307,6 +1465,8 @@ declare class RpcStream<T> implements AsyncIterable<T>, IRpcObject {
1307
1465
  disconnect(): void;
1308
1466
  [Symbol.asyncIterator](): AsyncIterator<T>;
1309
1467
  dispose(): void;
1468
+ private _complete;
1469
+ private _gapError;
1310
1470
  private _notifyConsumer;
1311
1471
  private _maybeSendAck;
1312
1472
  private static readonly _emptyGuid;
@@ -1396,4 +1556,4 @@ declare function xxh3_64str(input: string, seed?: bigint): bigint;
1396
1556
  */
1397
1557
  declare function computeMethodHash(methodName: string): number;
1398
1558
 
1399
- export { ARG_DELIMITER, ENVELOPE_DELIMITER, FRAME_DELIMITER, type IRpcObject, IncreasingSeqCompressor, type MethodMeta, RPC_CLOSE_CODE_UNSUPPORTED_FORMAT, type RemoteHandshake, type RpcCallOptions, RpcCallStage, RpcCallTypeId, RpcClientPeer, RpcClientPeerReconnectDelayer, type RpcConnection, RpcConnectionState, type RpcConnectionUrlResolver, type RpcDeserializedMessage, type RpcDispatchContext, RpcError, 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, RpcPeerRefBuilder, type RpcPeerState, RpcPeerStateKind, RpcPeerStateMonitor, type RpcReceivedMessage, 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, createBinaryEncoder, createMessageChannelPair, createRpcClient, defaultBinaryDecoder, defaultBinaryEncoder, defaultConnectionUrlResolver, defineRpcService, deserializeBinaryMessage, deserializeCompactBinaryMessage, deserializeMessage, getLogs, getMethodsMeta, getServiceMeta, getStateDescription, isConnected, likelyConnected, parseStreamRef, resolveStreamRefs, rpcMethod, rpcService, serializeBinaryFrame, serializeBinaryMessage, serializeCompactBinaryMessage, serializeFrame, serializeMessage, splitBinaryFrame, splitCompactBinaryFrame, splitFrame, wireMethodName, xxh3_64, xxh3_64str };
1559
+ 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, 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, RpcPeerRefBuilder, type RpcPeerState, RpcPeerStateKind, RpcPeerStateMonitor, type RpcReceivedMessage, 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, createBinaryEncoder, createMessageChannelPair, createRpcClient, defaultBinaryDecoder, defaultBinaryEncoder, defaultConnectionUrlResolver, defineRpcService, deserializeBinaryMessage, deserializeCompactBinaryMessage, deserializeMessage, getLogs, getMethodsMeta, getServiceMeta, getStateDescription, isConnected, likelyConnected, parseStreamRef, readPolymorphismMarker, resolveStreamRefs, rpcMethod, rpcService, serializeBinaryFrame, serializeBinaryMessage, serializeCompactBinaryMessage, serializeFrame, serializeMessage, splitBinaryFrame, splitCompactBinaryFrame, splitFrame, toExceptionInfo, wireMethodName, xxh3_64, xxh3_64str };