@actuallab/rpc 14.3.34 → 14.4.11

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
@@ -409,7 +409,8 @@ declare class RpcCallTimeouts {
409
409
  static readonly None: RpcCallTimeouts;
410
410
  /** Command default: 1.5 s connect / 10 s run (.NET `RpcCallTimeouts.Default.Command`). */
411
411
  static readonly Command: RpcCallTimeouts;
412
- /** Max time a call may wait for the connection before it is sent. */
412
+ /** Max time a call may wait for a connection - before it is sent, and again for the
413
+ * duration of any outage it is still pending through. */
413
414
  readonly connectTimeoutMs: number;
414
415
  /** Max time a sent call may stay unanswered before it is failed. */
415
416
  readonly runTimeoutMs: number;
@@ -1003,6 +1004,8 @@ declare abstract class RpcPeer {
1003
1004
  /** Wall-clock time of the last inbound `$sys.KeepAlive`, or 0 if none yet
1004
1005
  * for the current connection. Useful for diagnostics. */
1005
1006
  private _lastKeepAliveAt;
1007
+ /** When the current outage began; 0 until the peer has been connected at least once. */
1008
+ private _disconnectedAt;
1006
1009
  /** Outbound keep-alive send period. Initialized from `hub.limits` at
1007
1010
  * construction; set directly to override on a single peer. */
1008
1011
  keepAlivePeriodMs: number;
@@ -1012,11 +1015,13 @@ declare abstract class RpcPeer {
1012
1015
  protected constructor(hub: RpcHub, ref: string);
1013
1016
  /** Fail outbound calls whose per-call {@link RpcCallTimeouts} elapsed —
1014
1017
  * the connect timeout while a call still awaits the wire, the run timeout
1015
- * once it has been sent. Mirrors .NET `RpcOutboundCallTracker.Maintain`
1016
- * (RpcCallTrackers.cs:108-207). Calls without timeouts (queries) never
1017
- * time out here. */
1018
+ * once it has been sent, and the connect timeout again for any pending call while the
1019
+ * peer is away. Mirrors .NET `RpcOutboundCallTracker.HandleDisconnect` (ConnectTimeout,
1020
+ * per outage) plus `Maintain` (RunTimeout, per connection). Calls without timeouts
1021
+ * (queries) never time out here. */
1018
1022
  private _maintainOutboundCalls;
1019
1023
  get connection(): RpcConnection | undefined;
1024
+ get wireConnection(): RpcConnection | undefined;
1020
1025
  get connectionState(): RpcConnectionState;
1021
1026
  get isConnected(): boolean;
1022
1027
  get ownHandshakeIndex(): number;
@@ -1043,7 +1048,9 @@ declare abstract class RpcPeer {
1043
1048
  * stays in the hub and all client proxies bound to it remain valid. */
1044
1049
  disconnect(): void;
1045
1050
  close(): void;
1046
- /** Send pre-serialized wire data through the current connection. */
1051
+ /** Send pre-serialized wire data through the current connection. Callers are
1052
+ * already gated on `_isConnected`; the check is repeated here so the next one
1053
+ * cannot reintroduce a pre-handshake write. $sys.Handshake does not use this. */
1047
1054
  protected _sendWireData(data: string | Uint8Array): void;
1048
1055
  /** Override in subclasses to handle the remote peer's handshake response. */
1049
1056
  protected _onHandshakeReceived(_handshake: RemoteHandshake): void;
@@ -1322,7 +1329,11 @@ declare class RpcStreamSender<T> implements IRpcObject {
1322
1329
  readonly sourceUsesAbortSignal: boolean;
1323
1330
  /** Next stream index that will be sent (matches .NET's `index`). */
1324
1331
  private _nextIndex;
1325
- private _ended;
1332
+ /** Torn down — `disconnect()` ran. .NET's counterpart is disposal; note it
1333
+ * does NOT mean "an End was sent", which .NET does not track at all. */
1334
+ private _isDisposed;
1335
+ /** The pump has returned. .NET's `WhenRunning.IsCompleted`. */
1336
+ private _isCompleted;
1326
1337
  private _started;
1327
1338
  /** Highest `nextIndex` observed in an ACK so far (matches .NET's `lastAckNextIndex` idiom). */
1328
1339
  private _lastAckedIndex;
@@ -1375,14 +1386,17 @@ declare class RpcStreamSender<T> implements IRpcObject {
1375
1386
  *
1376
1387
  * Advances `_nextIndex` unconditionally — even if the peer is disconnected
1377
1388
  * the item is considered "sent" from the pump's perspective so the replay
1378
- * buffer indexing stays consistent. If a connection is absent, the wire
1389
+ * buffer indexing stays consistent. If the peer isn't connected, the wire
1379
1390
  * message is dropped; the item will be resent from the replay buffer
1380
1391
  * after a reconnect (client sends `Ack(N, mustReset=true)`).
1381
1392
  */
1382
1393
  sendItem(item: T): void;
1383
1394
  /** Send a batch of items to the client. See {@link sendItem} for disconnect semantics. */
1384
1395
  sendBatch(items: T[]): void;
1385
- /** Signal stream completion to the client. */
1396
+ /** Signal stream completion to the client. Re-sendable on purpose: if the
1397
+ * peer was not connected the frame is dropped, and the End stays in the
1398
+ * replay buffer for the next reset ack — .NET has no "already ended" latch
1399
+ * (the End is an ordinary buffer entry, RpcSharedStream.cs:185/239). */
1386
1400
  sendEnd(error?: Error | null): void;
1387
1401
  /**
1388
1402
  * Consume an AsyncIterable and send all items to the client.
@@ -1405,7 +1419,7 @@ declare class RpcStreamSender<T> implements IRpcObject {
1405
1419
  * ACKs the client sends right after it, so `mustReset` accumulates across
1406
1420
  * the whole batch — the newest ACK alone can't represent it. */
1407
1421
  private _tryProcessAcks;
1408
- /** Wait until an ACK is pending (or `_ended`). */
1422
+ /** Wait until an ACK is pending (or the sender is torn down). */
1409
1423
  private _waitAckReady;
1410
1424
  private _sampleRtt;
1411
1425
  reconnect(): void;
@@ -1507,8 +1521,11 @@ declare class RpcStream<T> implements AsyncIterable<T>, IRpcObject {
1507
1521
  /** Create a remote (target-side) stream from a parsed stream reference and peer. */
1508
1522
  constructor(ref: RpcStreamRef, peer: RpcPeer);
1509
1523
  /**
1510
- * For local streams: resolves when the sender finishes pumping (after `toRef()` was called).
1511
- * Rejects if the source throws. Throws if `toRef()` hasn't been called yet.
1524
+ * For local streams: resolves once the consumer acknowledges the end
1525
+ * ($sys.AckEnd) or the sender is disconnected — NOT when the source drains,
1526
+ * since the sender keeps serving acks after End so a reconnect can replay it.
1527
+ * A source error reaches the consumer as $sys.End(error) instead of rejecting
1528
+ * this. Throws if `toRef()` hasn't been called yet.
1512
1529
  */
1513
1530
  get whenSent(): Promise<void>;
1514
1531
  /** Local sender backing this stream after `toRef()` has been called.
package/dist/index.d.ts CHANGED
@@ -409,7 +409,8 @@ declare class RpcCallTimeouts {
409
409
  static readonly None: RpcCallTimeouts;
410
410
  /** Command default: 1.5 s connect / 10 s run (.NET `RpcCallTimeouts.Default.Command`). */
411
411
  static readonly Command: RpcCallTimeouts;
412
- /** Max time a call may wait for the connection before it is sent. */
412
+ /** Max time a call may wait for a connection - before it is sent, and again for the
413
+ * duration of any outage it is still pending through. */
413
414
  readonly connectTimeoutMs: number;
414
415
  /** Max time a sent call may stay unanswered before it is failed. */
415
416
  readonly runTimeoutMs: number;
@@ -1003,6 +1004,8 @@ declare abstract class RpcPeer {
1003
1004
  /** Wall-clock time of the last inbound `$sys.KeepAlive`, or 0 if none yet
1004
1005
  * for the current connection. Useful for diagnostics. */
1005
1006
  private _lastKeepAliveAt;
1007
+ /** When the current outage began; 0 until the peer has been connected at least once. */
1008
+ private _disconnectedAt;
1006
1009
  /** Outbound keep-alive send period. Initialized from `hub.limits` at
1007
1010
  * construction; set directly to override on a single peer. */
1008
1011
  keepAlivePeriodMs: number;
@@ -1012,11 +1015,13 @@ declare abstract class RpcPeer {
1012
1015
  protected constructor(hub: RpcHub, ref: string);
1013
1016
  /** Fail outbound calls whose per-call {@link RpcCallTimeouts} elapsed —
1014
1017
  * the connect timeout while a call still awaits the wire, the run timeout
1015
- * once it has been sent. Mirrors .NET `RpcOutboundCallTracker.Maintain`
1016
- * (RpcCallTrackers.cs:108-207). Calls without timeouts (queries) never
1017
- * time out here. */
1018
+ * once it has been sent, and the connect timeout again for any pending call while the
1019
+ * peer is away. Mirrors .NET `RpcOutboundCallTracker.HandleDisconnect` (ConnectTimeout,
1020
+ * per outage) plus `Maintain` (RunTimeout, per connection). Calls without timeouts
1021
+ * (queries) never time out here. */
1018
1022
  private _maintainOutboundCalls;
1019
1023
  get connection(): RpcConnection | undefined;
1024
+ get wireConnection(): RpcConnection | undefined;
1020
1025
  get connectionState(): RpcConnectionState;
1021
1026
  get isConnected(): boolean;
1022
1027
  get ownHandshakeIndex(): number;
@@ -1043,7 +1048,9 @@ declare abstract class RpcPeer {
1043
1048
  * stays in the hub and all client proxies bound to it remain valid. */
1044
1049
  disconnect(): void;
1045
1050
  close(): void;
1046
- /** Send pre-serialized wire data through the current connection. */
1051
+ /** Send pre-serialized wire data through the current connection. Callers are
1052
+ * already gated on `_isConnected`; the check is repeated here so the next one
1053
+ * cannot reintroduce a pre-handshake write. $sys.Handshake does not use this. */
1047
1054
  protected _sendWireData(data: string | Uint8Array): void;
1048
1055
  /** Override in subclasses to handle the remote peer's handshake response. */
1049
1056
  protected _onHandshakeReceived(_handshake: RemoteHandshake): void;
@@ -1322,7 +1329,11 @@ declare class RpcStreamSender<T> implements IRpcObject {
1322
1329
  readonly sourceUsesAbortSignal: boolean;
1323
1330
  /** Next stream index that will be sent (matches .NET's `index`). */
1324
1331
  private _nextIndex;
1325
- private _ended;
1332
+ /** Torn down — `disconnect()` ran. .NET's counterpart is disposal; note it
1333
+ * does NOT mean "an End was sent", which .NET does not track at all. */
1334
+ private _isDisposed;
1335
+ /** The pump has returned. .NET's `WhenRunning.IsCompleted`. */
1336
+ private _isCompleted;
1326
1337
  private _started;
1327
1338
  /** Highest `nextIndex` observed in an ACK so far (matches .NET's `lastAckNextIndex` idiom). */
1328
1339
  private _lastAckedIndex;
@@ -1375,14 +1386,17 @@ declare class RpcStreamSender<T> implements IRpcObject {
1375
1386
  *
1376
1387
  * Advances `_nextIndex` unconditionally — even if the peer is disconnected
1377
1388
  * the item is considered "sent" from the pump's perspective so the replay
1378
- * buffer indexing stays consistent. If a connection is absent, the wire
1389
+ * buffer indexing stays consistent. If the peer isn't connected, the wire
1379
1390
  * message is dropped; the item will be resent from the replay buffer
1380
1391
  * after a reconnect (client sends `Ack(N, mustReset=true)`).
1381
1392
  */
1382
1393
  sendItem(item: T): void;
1383
1394
  /** Send a batch of items to the client. See {@link sendItem} for disconnect semantics. */
1384
1395
  sendBatch(items: T[]): void;
1385
- /** Signal stream completion to the client. */
1396
+ /** Signal stream completion to the client. Re-sendable on purpose: if the
1397
+ * peer was not connected the frame is dropped, and the End stays in the
1398
+ * replay buffer for the next reset ack — .NET has no "already ended" latch
1399
+ * (the End is an ordinary buffer entry, RpcSharedStream.cs:185/239). */
1386
1400
  sendEnd(error?: Error | null): void;
1387
1401
  /**
1388
1402
  * Consume an AsyncIterable and send all items to the client.
@@ -1405,7 +1419,7 @@ declare class RpcStreamSender<T> implements IRpcObject {
1405
1419
  * ACKs the client sends right after it, so `mustReset` accumulates across
1406
1420
  * the whole batch — the newest ACK alone can't represent it. */
1407
1421
  private _tryProcessAcks;
1408
- /** Wait until an ACK is pending (or `_ended`). */
1422
+ /** Wait until an ACK is pending (or the sender is torn down). */
1409
1423
  private _waitAckReady;
1410
1424
  private _sampleRtt;
1411
1425
  reconnect(): void;
@@ -1507,8 +1521,11 @@ declare class RpcStream<T> implements AsyncIterable<T>, IRpcObject {
1507
1521
  /** Create a remote (target-side) stream from a parsed stream reference and peer. */
1508
1522
  constructor(ref: RpcStreamRef, peer: RpcPeer);
1509
1523
  /**
1510
- * For local streams: resolves when the sender finishes pumping (after `toRef()` was called).
1511
- * Rejects if the source throws. Throws if `toRef()` hasn't been called yet.
1524
+ * For local streams: resolves once the consumer acknowledges the end
1525
+ * ($sys.AckEnd) or the sender is disconnected — NOT when the source drains,
1526
+ * since the sender keeps serving acks after End so a reconnect can replay it.
1527
+ * A source error reaches the consumer as $sys.End(error) instead of rejecting
1528
+ * this. Throws if `toRef()` hasn't been called yet.
1512
1529
  */
1513
1530
  get whenSent(): Promise<void>;
1514
1531
  /** Local sender backing this stream after `toRef()` has been called.