@actuallab/rpc 12.1.62 → 12.1.69

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
@@ -13,6 +13,11 @@ declare const RpcSystemCalls: {
13
13
  readonly cancel: "$sys.Cancel:0";
14
14
  readonly keepAlive: "$sys.KeepAlive:1";
15
15
  readonly reconnect: "$sys.Reconnect:3";
16
+ readonly ack: "$sys.Ack:2";
17
+ readonly ackEnd: "$sys.AckEnd:1";
18
+ readonly item: "$sys.I:2";
19
+ readonly batch: "$sys.B:2";
20
+ readonly end: "$sys.End:2";
16
21
  };
17
22
  /** Wire-format RPC message envelope. */
18
23
  interface RpcMessage {
@@ -127,20 +132,18 @@ interface RpcMethodDefInput {
127
132
  args: unknown[];
128
133
  returns?: symbol;
129
134
  callTypeId?: number;
130
- stream?: boolean;
131
- noWait?: boolean;
135
+ /** Override for wireArgCount. Default: args.length + 1 (assumes a CancellationToken slot). */
136
+ wireArgCount?: number;
132
137
  }
133
138
  declare const RpcType: {
134
139
  readonly object: symbol;
135
140
  readonly stream: symbol;
141
+ readonly noWait: symbol;
136
142
  readonly void: symbol;
137
143
  };
138
- interface RpcServiceDefOptions {
139
- ctOffset?: number;
140
- }
141
144
  /** Returns the full wire method name: "ServiceName.MethodName:wireArgCount". */
142
145
  declare function wireMethodName(def: RpcMethodDef): string;
143
- declare function defineRpcService(name: string, methods: Record<string, RpcMethodDefInput>, options?: RpcServiceDefOptions): RpcServiceDef;
146
+ declare function defineRpcService(name: string, methods: Record<string, RpcMethodDefInput>): RpcServiceDef;
144
147
 
145
148
  /** Tracks a pending outbound RPC call. */
146
149
  declare class RpcOutboundCall {
@@ -191,18 +194,6 @@ declare class RpcInboundCallTracker {
191
194
  clear(): void;
192
195
  }
193
196
 
194
- /** Handles an incoming system call message and dispatches to the appropriate tracker. */
195
- declare function handleSystemCall(message: RpcMessage, args: unknown[], outboundTracker: RpcOutboundCallTracker, inboundTracker: RpcInboundCallTracker): void;
196
-
197
- /** Sends system RPC messages — like .NET's RpcSystemCallSender. */
198
- declare class RpcSystemCallSender {
199
- handshake(conn: RpcConnection, peerId: string, hubId: string, index: number): void;
200
- ok(conn: RpcConnection, relatedId: number, result: unknown): void;
201
- error(conn: RpcConnection, relatedId: number, error: unknown): void;
202
- cancel(conn: RpcConnection, relatedId: number): void;
203
- keepAlive(conn: RpcConnection, activeCallIds: number[]): void;
204
- }
205
-
206
197
  declare class RpcClientPeerReconnectDelayer extends RetryDelayer {
207
198
  constructor();
208
199
  }
@@ -222,12 +213,29 @@ declare class RpcServiceHost {
222
213
  getMethodDef(wireMethod: string): RpcMethodDef | undefined;
223
214
  }
224
215
 
216
+ /** Sends system RPC messages — like .NET's RpcSystemCallSender. */
217
+ declare class RpcSystemCallSender {
218
+ handshake(conn: RpcConnection, peerId: string, hubId: string, index: number): void;
219
+ ok(conn: RpcConnection, relatedId: number, result: unknown): void;
220
+ error(conn: RpcConnection, relatedId: number, error: unknown): void;
221
+ cancel(conn: RpcConnection, relatedId: number): void;
222
+ keepAlive(conn: RpcConnection, activeCallIds: number[]): void;
223
+ item(conn: RpcConnection, localId: number, index: number, item: unknown): void;
224
+ batch(conn: RpcConnection, localId: number, index: number, items: unknown[]): void;
225
+ end(conn: RpcConnection, localId: number, index: number, error?: {
226
+ Message: string;
227
+ } | null): void;
228
+ ack(conn: RpcConnection, localId: number, nextIndex: number, hostId: string): void;
229
+ ackEnd(conn: RpcConnection, localId: number, hostId: string): void;
230
+ }
231
+
225
232
  /** Central RPC coordinator — manages peers, services, and configuration. */
226
233
  declare class RpcHub {
227
234
  readonly hubId: string;
228
235
  readonly peers: Map<string, RpcPeer>;
229
236
  readonly serviceHost: RpcServiceHost;
230
237
  readonly systemCallSender: RpcSystemCallSender;
238
+ systemCallHandler: RpcSystemCallHandler;
231
239
  constructor(hubId?: string);
232
240
  addPeer(peer: RpcPeer): void;
233
241
  removePeer(ref: string): void;
@@ -242,8 +250,6 @@ declare class RpcHub {
242
250
  /** Create a typed client proxy for a service on a remote peer. */
243
251
  addClient<T extends object>(peer: RpcPeer, defOrContract: RpcServiceDef | (abstract new (...args: any[]) => any)): T;
244
252
  close(): void;
245
- /** Dispatch an inbound system call. Override in FusionHub to handle compute-specific system calls. */
246
- handleSystemCall(message: RpcMessage, args: unknown[], outbound: RpcOutboundCallTracker, inbound: RpcInboundCallTracker): void;
247
253
  /** Build an RpcServiceDef from decorator metadata on a contract class. Override in FusionHub for compute support. */
248
254
  protected _buildServiceDef(cls: abstract new (...args: any[]) => any): RpcServiceDef;
249
255
  /** Resolve a service def from either a plain RpcServiceDef or a contract class. */
@@ -254,6 +260,41 @@ declare class RpcHub {
254
260
  protected _createClientMethod(peer: RpcPeer, methodDef: RpcMethodDef): (...args: unknown[]) => unknown;
255
261
  }
256
262
 
263
+ interface RpcObjectId {
264
+ readonly hostId: string;
265
+ readonly localId: number;
266
+ }
267
+ declare const RpcObjectKind: {
268
+ readonly Local: 0;
269
+ readonly Remote: 1;
270
+ };
271
+ type RpcObjectKind = (typeof RpcObjectKind)[keyof typeof RpcObjectKind];
272
+ interface IRpcObject {
273
+ readonly id: RpcObjectId;
274
+ readonly kind: RpcObjectKind;
275
+ reconnect(): void;
276
+ disconnect(): void;
277
+ }
278
+
279
+ declare class RpcRemoteObjectTracker {
280
+ private _objects;
281
+ register(obj: IRpcObject): void;
282
+ get(localId: number): IRpcObject | undefined;
283
+ unregister(obj: IRpcObject): void;
284
+ disconnectAll(): void;
285
+ reconnectAll(): void;
286
+ }
287
+
288
+ declare class RpcSharedObjectTracker {
289
+ private _nextId;
290
+ private _objects;
291
+ nextId(): number;
292
+ register(obj: IRpcObject): void;
293
+ get(localId: number): IRpcObject | undefined;
294
+ unregister(obj: IRpcObject): void;
295
+ disconnectAll(): void;
296
+ }
297
+
257
298
  /**
258
299
  * Default serialization format for RpcClientPeer connections.
259
300
  * TS uses plain JSON.stringify without polymorphic type wrapping,
@@ -290,6 +331,8 @@ declare abstract class RpcPeer {
290
331
  protected _connection: RpcConnection | undefined;
291
332
  readonly outbound: RpcOutboundCallTracker;
292
333
  readonly inbound: RpcInboundCallTracker;
334
+ readonly remoteObjects: RpcRemoteObjectTracker;
335
+ readonly sharedObjects: RpcSharedObjectTracker;
293
336
  readonly connected: EventHandlerSet<void>;
294
337
  readonly disconnected: EventHandlerSet<{
295
338
  code: number;
@@ -298,6 +341,7 @@ declare abstract class RpcPeer {
298
341
  protected _pendingSends: RpcOutboundCall[];
299
342
  private _keepAliveTimer;
300
343
  constructor(ref: string, hub: RpcHub);
344
+ get hub(): RpcHub;
301
345
  get connection(): RpcConnection | undefined;
302
346
  get isConnected(): boolean;
303
347
  protected setupConnection(conn: RpcConnection): void;
@@ -368,6 +412,116 @@ declare class RpcServerPeer extends RpcPeer {
368
412
  protected _onHandshakeReceived(_handshake: RemoteHandshake): void;
369
413
  }
370
414
 
415
+ /** Handles incoming system call messages — class-based equivalent of the former standalone function. */
416
+ declare class RpcSystemCallHandler {
417
+ handle(message: RpcMessage, args: unknown[], peer: RpcPeer): void;
418
+ }
419
+
420
+ /** Parsed stream reference from the server's result payload. */
421
+ interface RpcStreamRef {
422
+ readonly hostId: string;
423
+ readonly localId: number;
424
+ readonly ackPeriod: number;
425
+ readonly ackAdvance: number;
426
+ }
427
+ /**
428
+ * Parses a stream reference string of the form "{hostId},{localId},{ackPeriod},{ackAdvance}".
429
+ * Returns null if the value is not a valid stream reference.
430
+ */
431
+ declare function parseStreamRef(value: unknown): RpcStreamRef | null;
432
+ /**
433
+ * Client-side RPC stream — consumes items sent by the server via system calls
434
+ * ($sys.I, $sys.B, $sys.End) and implements AsyncIterable<T> for for-await-of consumption.
435
+ *
436
+ * Wire protocol:
437
+ * - Client sends Ack(0, hostId) to start the stream
438
+ * - Server sends I (single item) / B (batch) messages
439
+ * - Client acks every ackPeriod items for flow control
440
+ * - Server sends End to signal completion (with optional error)
441
+ * - Client sends AckEnd to acknowledge completion
442
+ */
443
+ declare class RpcStream<T> implements AsyncIterable<T>, IRpcObject {
444
+ readonly id: RpcObjectId;
445
+ readonly kind: 1;
446
+ readonly peer: RpcPeer;
447
+ readonly ackPeriod: number;
448
+ readonly ackAdvance: number;
449
+ private _buffer;
450
+ private _nextExpectedIndex;
451
+ private _consumerWaiting;
452
+ private _completed;
453
+ private _completionError;
454
+ private _disposed;
455
+ private _started;
456
+ private _iterating;
457
+ private _ackSentUpTo;
458
+ constructor(ref: RpcStreamRef, peer: RpcPeer);
459
+ /** Called by system call handler when a single item arrives ($sys.I). */
460
+ onItem(index: number, item: T): void;
461
+ /** Called by system call handler when a batch arrives ($sys.B). */
462
+ onBatch(index: number, items: T[]): void;
463
+ /** Called by system call handler when the stream ends ($sys.End). */
464
+ onEnd(index: number, error: Error | null): void;
465
+ reconnect(): void;
466
+ disconnect(): void;
467
+ [Symbol.asyncIterator](): AsyncIterator<T>;
468
+ dispose(): void;
469
+ private _notifyConsumer;
470
+ private _maybeSendAck;
471
+ private _sendAck;
472
+ private _sendAckEnd;
473
+ }
474
+ /**
475
+ * Recursively walks a deserialized value and replaces any stream ref strings
476
+ * with live RpcStream<unknown> instances registered on the given peer.
477
+ * This handles nested stream refs inside complex return types (e.g. Table<T>
478
+ * containing RpcStream<Row<T>> fields serialized as "{hostId},{localId},{ackPeriod},{ackAdvance}").
479
+ */
480
+ declare function resolveStreamRefs(value: unknown, peer: RpcPeer): unknown;
481
+
482
+ /**
483
+ * Server-side RPC stream producer — sends items to a remote consumer via
484
+ * $sys.I / $sys.B / $sys.End system calls.
485
+ *
486
+ * Wire protocol (server perspective):
487
+ * - Server returns the stream reference string as $sys.Ok
488
+ * - Client sends Ack(0, hostId) to start the stream
489
+ * - Server sends I (single item) / B (batch) messages
490
+ * - Client acks every ackPeriod items for flow control
491
+ * - Server sends End to signal completion (with optional error)
492
+ * - Client sends AckEnd to acknowledge completion
493
+ */
494
+ declare class RpcStreamSender<T> implements IRpcObject {
495
+ readonly id: RpcObjectId;
496
+ readonly kind: 0;
497
+ readonly peer: RpcPeer;
498
+ readonly ackPeriod: number;
499
+ readonly ackAdvance: number;
500
+ private _nextIndex;
501
+ private _ended;
502
+ private _started;
503
+ constructor(peer: RpcPeer, ackPeriod?: number, ackAdvance?: number);
504
+ /** Returns the stream reference string for the $sys.Ok response. */
505
+ toRef(): string;
506
+ /** Called by system call handler when $sys.Ack is received from the client. */
507
+ onAck(_nextIndex: number, _hostId: string): void;
508
+ /** Called by system call handler when $sys.AckEnd is received from the client. */
509
+ onAckEnd(_hostId: string): void;
510
+ /** Send a single item to the client. */
511
+ sendItem(item: T): void;
512
+ /** Send a batch of items to the client. */
513
+ sendBatch(items: T[]): void;
514
+ /** Signal stream completion to the client. */
515
+ sendEnd(error?: Error | null): void;
516
+ /**
517
+ * Consume an AsyncIterable and send all items to the client.
518
+ * Waits for the client's initial Ack before starting to pump items.
519
+ */
520
+ writeFrom(source: AsyncIterable<T>): Promise<void>;
521
+ reconnect(): void;
522
+ disconnect(): void;
523
+ }
524
+
371
525
  /** Creates a typed RPC client proxy — intercepts method calls and sends them over RPC. */
372
526
  declare function createRpcClient<T extends object>(peer: RpcPeer, serviceDef: RpcServiceDef): T;
373
527
 
@@ -379,26 +533,21 @@ interface WebSocketServer {
379
533
 
380
534
  interface MethodMeta {
381
535
  argCount: number;
382
- stream?: boolean;
383
- noWait?: boolean;
536
+ returns?: symbol;
384
537
  [key: symbol]: unknown;
385
538
  }
386
539
  interface ServiceMeta {
387
540
  name: string;
388
- ctOffset?: number;
389
541
  }
390
542
  /** Read method metadata from a decorated class. */
391
543
  declare function getMethodsMeta(cls: abstract new (...args: any[]) => any): Record<string, MethodMeta> | undefined;
392
544
  /** Read service metadata from a decorated class. */
393
545
  declare function getServiceMeta(cls: abstract new (...args: any[]) => any): ServiceMeta | undefined;
394
- /** Class decorator — stores the RPC service wire name and optional ctOffset. */
395
- declare function rpcService(serviceName: string, options?: {
396
- ctOffset?: number;
397
- }): <T extends abstract new (...args: any[]) => any>(_target: T, context: ClassDecoratorContext<T>) => void;
398
- /** Method decorator — stores RPC method metadata (argCount, stream, noWait). Does NOT wrap the method. */
546
+ /** Class decorator — stores the RPC service wire name. */
547
+ declare function rpcService(serviceName: string): <T extends abstract new (...args: any[]) => any>(_target: T, context: ClassDecoratorContext<T>) => void;
548
+ /** Method decorator — stores RPC method metadata (argCount, returns). Does NOT wrap the method. */
399
549
  declare function rpcMethod(options?: {
400
- stream?: boolean;
401
- noWait?: boolean;
550
+ returns?: symbol;
402
551
  }): <This, Args extends unknown[], Return>(target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>) => (this: This, ...args: Args) => Return;
403
552
 
404
553
  declare const enum RpcPeerStateKind {
@@ -437,4 +586,4 @@ declare class RpcPeerStateMonitor {
437
586
  private _scheduleRecompute;
438
587
  }
439
588
 
440
- export { ARG_DELIMITER, DEFAULT_SERIALIZATION_FORMAT, ENVELOPE_DELIMITER, FRAME_DELIMITER, type MethodMeta, type RemoteHandshake, type RpcCallOptions, RpcCallTypeId, RpcClientPeer, RpcClientPeerReconnectDelayer, type RpcConnection, type RpcConnectionUrlResolver, type RpcDispatchContext, RpcHub, RpcInboundCall, RpcInboundCallTracker, type RpcMessage, RpcMessageChannelConnection, type RpcMethodDef, type RpcMethodDefInput, RpcOutboundCall, RpcOutboundCallTracker, RpcPeer, RpcPeerConnectionKind, type RpcPeerState, RpcPeerStateKind, RpcPeerStateMonitor, RpcServerPeer, type RpcServiceDef, type RpcServiceDefOptions, RpcServiceHost, type RpcServiceImpl, RpcSystemCallSender, RpcSystemCalls, RpcType, RpcWebSocketConnection, type ServiceMeta, type WebSocketLike, type WebSocketServer, WebSocketState, createMessageChannelPair, createRpcClient, defaultConnectionUrlResolver, defineRpcService, deserializeMessage, getMethodsMeta, getServiceMeta, getStateDescription, handleSystemCall, isConnected, likelyConnected, rpcMethod, rpcService, serializeFrame, serializeMessage, splitFrame, wireMethodName };
589
+ export { ARG_DELIMITER, DEFAULT_SERIALIZATION_FORMAT, ENVELOPE_DELIMITER, FRAME_DELIMITER, type IRpcObject, type MethodMeta, type RemoteHandshake, type RpcCallOptions, RpcCallTypeId, RpcClientPeer, RpcClientPeerReconnectDelayer, type RpcConnection, type RpcConnectionUrlResolver, type RpcDispatchContext, RpcHub, RpcInboundCall, RpcInboundCallTracker, type RpcMessage, RpcMessageChannelConnection, type RpcMethodDef, type RpcMethodDefInput, type RpcObjectId, RpcObjectKind, RpcOutboundCall, RpcOutboundCallTracker, RpcPeer, RpcPeerConnectionKind, type RpcPeerState, RpcPeerStateKind, RpcPeerStateMonitor, RpcRemoteObjectTracker, RpcServerPeer, type RpcServiceDef, RpcServiceHost, type RpcServiceImpl, RpcSharedObjectTracker, RpcStream, type RpcStreamRef, RpcStreamSender, RpcSystemCallHandler, RpcSystemCallSender, RpcSystemCalls, RpcType, RpcWebSocketConnection, type ServiceMeta, type WebSocketLike, type WebSocketServer, WebSocketState, createMessageChannelPair, createRpcClient, defaultConnectionUrlResolver, defineRpcService, deserializeMessage, getMethodsMeta, getServiceMeta, getStateDescription, isConnected, likelyConnected, parseStreamRef, resolveStreamRefs, rpcMethod, rpcService, serializeFrame, serializeMessage, splitFrame, wireMethodName };
package/dist/index.d.ts CHANGED
@@ -13,6 +13,11 @@ declare const RpcSystemCalls: {
13
13
  readonly cancel: "$sys.Cancel:0";
14
14
  readonly keepAlive: "$sys.KeepAlive:1";
15
15
  readonly reconnect: "$sys.Reconnect:3";
16
+ readonly ack: "$sys.Ack:2";
17
+ readonly ackEnd: "$sys.AckEnd:1";
18
+ readonly item: "$sys.I:2";
19
+ readonly batch: "$sys.B:2";
20
+ readonly end: "$sys.End:2";
16
21
  };
17
22
  /** Wire-format RPC message envelope. */
18
23
  interface RpcMessage {
@@ -127,20 +132,18 @@ interface RpcMethodDefInput {
127
132
  args: unknown[];
128
133
  returns?: symbol;
129
134
  callTypeId?: number;
130
- stream?: boolean;
131
- noWait?: boolean;
135
+ /** Override for wireArgCount. Default: args.length + 1 (assumes a CancellationToken slot). */
136
+ wireArgCount?: number;
132
137
  }
133
138
  declare const RpcType: {
134
139
  readonly object: symbol;
135
140
  readonly stream: symbol;
141
+ readonly noWait: symbol;
136
142
  readonly void: symbol;
137
143
  };
138
- interface RpcServiceDefOptions {
139
- ctOffset?: number;
140
- }
141
144
  /** Returns the full wire method name: "ServiceName.MethodName:wireArgCount". */
142
145
  declare function wireMethodName(def: RpcMethodDef): string;
143
- declare function defineRpcService(name: string, methods: Record<string, RpcMethodDefInput>, options?: RpcServiceDefOptions): RpcServiceDef;
146
+ declare function defineRpcService(name: string, methods: Record<string, RpcMethodDefInput>): RpcServiceDef;
144
147
 
145
148
  /** Tracks a pending outbound RPC call. */
146
149
  declare class RpcOutboundCall {
@@ -191,18 +194,6 @@ declare class RpcInboundCallTracker {
191
194
  clear(): void;
192
195
  }
193
196
 
194
- /** Handles an incoming system call message and dispatches to the appropriate tracker. */
195
- declare function handleSystemCall(message: RpcMessage, args: unknown[], outboundTracker: RpcOutboundCallTracker, inboundTracker: RpcInboundCallTracker): void;
196
-
197
- /** Sends system RPC messages — like .NET's RpcSystemCallSender. */
198
- declare class RpcSystemCallSender {
199
- handshake(conn: RpcConnection, peerId: string, hubId: string, index: number): void;
200
- ok(conn: RpcConnection, relatedId: number, result: unknown): void;
201
- error(conn: RpcConnection, relatedId: number, error: unknown): void;
202
- cancel(conn: RpcConnection, relatedId: number): void;
203
- keepAlive(conn: RpcConnection, activeCallIds: number[]): void;
204
- }
205
-
206
197
  declare class RpcClientPeerReconnectDelayer extends RetryDelayer {
207
198
  constructor();
208
199
  }
@@ -222,12 +213,29 @@ declare class RpcServiceHost {
222
213
  getMethodDef(wireMethod: string): RpcMethodDef | undefined;
223
214
  }
224
215
 
216
+ /** Sends system RPC messages — like .NET's RpcSystemCallSender. */
217
+ declare class RpcSystemCallSender {
218
+ handshake(conn: RpcConnection, peerId: string, hubId: string, index: number): void;
219
+ ok(conn: RpcConnection, relatedId: number, result: unknown): void;
220
+ error(conn: RpcConnection, relatedId: number, error: unknown): void;
221
+ cancel(conn: RpcConnection, relatedId: number): void;
222
+ keepAlive(conn: RpcConnection, activeCallIds: number[]): void;
223
+ item(conn: RpcConnection, localId: number, index: number, item: unknown): void;
224
+ batch(conn: RpcConnection, localId: number, index: number, items: unknown[]): void;
225
+ end(conn: RpcConnection, localId: number, index: number, error?: {
226
+ Message: string;
227
+ } | null): void;
228
+ ack(conn: RpcConnection, localId: number, nextIndex: number, hostId: string): void;
229
+ ackEnd(conn: RpcConnection, localId: number, hostId: string): void;
230
+ }
231
+
225
232
  /** Central RPC coordinator — manages peers, services, and configuration. */
226
233
  declare class RpcHub {
227
234
  readonly hubId: string;
228
235
  readonly peers: Map<string, RpcPeer>;
229
236
  readonly serviceHost: RpcServiceHost;
230
237
  readonly systemCallSender: RpcSystemCallSender;
238
+ systemCallHandler: RpcSystemCallHandler;
231
239
  constructor(hubId?: string);
232
240
  addPeer(peer: RpcPeer): void;
233
241
  removePeer(ref: string): void;
@@ -242,8 +250,6 @@ declare class RpcHub {
242
250
  /** Create a typed client proxy for a service on a remote peer. */
243
251
  addClient<T extends object>(peer: RpcPeer, defOrContract: RpcServiceDef | (abstract new (...args: any[]) => any)): T;
244
252
  close(): void;
245
- /** Dispatch an inbound system call. Override in FusionHub to handle compute-specific system calls. */
246
- handleSystemCall(message: RpcMessage, args: unknown[], outbound: RpcOutboundCallTracker, inbound: RpcInboundCallTracker): void;
247
253
  /** Build an RpcServiceDef from decorator metadata on a contract class. Override in FusionHub for compute support. */
248
254
  protected _buildServiceDef(cls: abstract new (...args: any[]) => any): RpcServiceDef;
249
255
  /** Resolve a service def from either a plain RpcServiceDef or a contract class. */
@@ -254,6 +260,41 @@ declare class RpcHub {
254
260
  protected _createClientMethod(peer: RpcPeer, methodDef: RpcMethodDef): (...args: unknown[]) => unknown;
255
261
  }
256
262
 
263
+ interface RpcObjectId {
264
+ readonly hostId: string;
265
+ readonly localId: number;
266
+ }
267
+ declare const RpcObjectKind: {
268
+ readonly Local: 0;
269
+ readonly Remote: 1;
270
+ };
271
+ type RpcObjectKind = (typeof RpcObjectKind)[keyof typeof RpcObjectKind];
272
+ interface IRpcObject {
273
+ readonly id: RpcObjectId;
274
+ readonly kind: RpcObjectKind;
275
+ reconnect(): void;
276
+ disconnect(): void;
277
+ }
278
+
279
+ declare class RpcRemoteObjectTracker {
280
+ private _objects;
281
+ register(obj: IRpcObject): void;
282
+ get(localId: number): IRpcObject | undefined;
283
+ unregister(obj: IRpcObject): void;
284
+ disconnectAll(): void;
285
+ reconnectAll(): void;
286
+ }
287
+
288
+ declare class RpcSharedObjectTracker {
289
+ private _nextId;
290
+ private _objects;
291
+ nextId(): number;
292
+ register(obj: IRpcObject): void;
293
+ get(localId: number): IRpcObject | undefined;
294
+ unregister(obj: IRpcObject): void;
295
+ disconnectAll(): void;
296
+ }
297
+
257
298
  /**
258
299
  * Default serialization format for RpcClientPeer connections.
259
300
  * TS uses plain JSON.stringify without polymorphic type wrapping,
@@ -290,6 +331,8 @@ declare abstract class RpcPeer {
290
331
  protected _connection: RpcConnection | undefined;
291
332
  readonly outbound: RpcOutboundCallTracker;
292
333
  readonly inbound: RpcInboundCallTracker;
334
+ readonly remoteObjects: RpcRemoteObjectTracker;
335
+ readonly sharedObjects: RpcSharedObjectTracker;
293
336
  readonly connected: EventHandlerSet<void>;
294
337
  readonly disconnected: EventHandlerSet<{
295
338
  code: number;
@@ -298,6 +341,7 @@ declare abstract class RpcPeer {
298
341
  protected _pendingSends: RpcOutboundCall[];
299
342
  private _keepAliveTimer;
300
343
  constructor(ref: string, hub: RpcHub);
344
+ get hub(): RpcHub;
301
345
  get connection(): RpcConnection | undefined;
302
346
  get isConnected(): boolean;
303
347
  protected setupConnection(conn: RpcConnection): void;
@@ -368,6 +412,116 @@ declare class RpcServerPeer extends RpcPeer {
368
412
  protected _onHandshakeReceived(_handshake: RemoteHandshake): void;
369
413
  }
370
414
 
415
+ /** Handles incoming system call messages — class-based equivalent of the former standalone function. */
416
+ declare class RpcSystemCallHandler {
417
+ handle(message: RpcMessage, args: unknown[], peer: RpcPeer): void;
418
+ }
419
+
420
+ /** Parsed stream reference from the server's result payload. */
421
+ interface RpcStreamRef {
422
+ readonly hostId: string;
423
+ readonly localId: number;
424
+ readonly ackPeriod: number;
425
+ readonly ackAdvance: number;
426
+ }
427
+ /**
428
+ * Parses a stream reference string of the form "{hostId},{localId},{ackPeriod},{ackAdvance}".
429
+ * Returns null if the value is not a valid stream reference.
430
+ */
431
+ declare function parseStreamRef(value: unknown): RpcStreamRef | null;
432
+ /**
433
+ * Client-side RPC stream — consumes items sent by the server via system calls
434
+ * ($sys.I, $sys.B, $sys.End) and implements AsyncIterable<T> for for-await-of consumption.
435
+ *
436
+ * Wire protocol:
437
+ * - Client sends Ack(0, hostId) to start the stream
438
+ * - Server sends I (single item) / B (batch) messages
439
+ * - Client acks every ackPeriod items for flow control
440
+ * - Server sends End to signal completion (with optional error)
441
+ * - Client sends AckEnd to acknowledge completion
442
+ */
443
+ declare class RpcStream<T> implements AsyncIterable<T>, IRpcObject {
444
+ readonly id: RpcObjectId;
445
+ readonly kind: 1;
446
+ readonly peer: RpcPeer;
447
+ readonly ackPeriod: number;
448
+ readonly ackAdvance: number;
449
+ private _buffer;
450
+ private _nextExpectedIndex;
451
+ private _consumerWaiting;
452
+ private _completed;
453
+ private _completionError;
454
+ private _disposed;
455
+ private _started;
456
+ private _iterating;
457
+ private _ackSentUpTo;
458
+ constructor(ref: RpcStreamRef, peer: RpcPeer);
459
+ /** Called by system call handler when a single item arrives ($sys.I). */
460
+ onItem(index: number, item: T): void;
461
+ /** Called by system call handler when a batch arrives ($sys.B). */
462
+ onBatch(index: number, items: T[]): void;
463
+ /** Called by system call handler when the stream ends ($sys.End). */
464
+ onEnd(index: number, error: Error | null): void;
465
+ reconnect(): void;
466
+ disconnect(): void;
467
+ [Symbol.asyncIterator](): AsyncIterator<T>;
468
+ dispose(): void;
469
+ private _notifyConsumer;
470
+ private _maybeSendAck;
471
+ private _sendAck;
472
+ private _sendAckEnd;
473
+ }
474
+ /**
475
+ * Recursively walks a deserialized value and replaces any stream ref strings
476
+ * with live RpcStream<unknown> instances registered on the given peer.
477
+ * This handles nested stream refs inside complex return types (e.g. Table<T>
478
+ * containing RpcStream<Row<T>> fields serialized as "{hostId},{localId},{ackPeriod},{ackAdvance}").
479
+ */
480
+ declare function resolveStreamRefs(value: unknown, peer: RpcPeer): unknown;
481
+
482
+ /**
483
+ * Server-side RPC stream producer — sends items to a remote consumer via
484
+ * $sys.I / $sys.B / $sys.End system calls.
485
+ *
486
+ * Wire protocol (server perspective):
487
+ * - Server returns the stream reference string as $sys.Ok
488
+ * - Client sends Ack(0, hostId) to start the stream
489
+ * - Server sends I (single item) / B (batch) messages
490
+ * - Client acks every ackPeriod items for flow control
491
+ * - Server sends End to signal completion (with optional error)
492
+ * - Client sends AckEnd to acknowledge completion
493
+ */
494
+ declare class RpcStreamSender<T> implements IRpcObject {
495
+ readonly id: RpcObjectId;
496
+ readonly kind: 0;
497
+ readonly peer: RpcPeer;
498
+ readonly ackPeriod: number;
499
+ readonly ackAdvance: number;
500
+ private _nextIndex;
501
+ private _ended;
502
+ private _started;
503
+ constructor(peer: RpcPeer, ackPeriod?: number, ackAdvance?: number);
504
+ /** Returns the stream reference string for the $sys.Ok response. */
505
+ toRef(): string;
506
+ /** Called by system call handler when $sys.Ack is received from the client. */
507
+ onAck(_nextIndex: number, _hostId: string): void;
508
+ /** Called by system call handler when $sys.AckEnd is received from the client. */
509
+ onAckEnd(_hostId: string): void;
510
+ /** Send a single item to the client. */
511
+ sendItem(item: T): void;
512
+ /** Send a batch of items to the client. */
513
+ sendBatch(items: T[]): void;
514
+ /** Signal stream completion to the client. */
515
+ sendEnd(error?: Error | null): void;
516
+ /**
517
+ * Consume an AsyncIterable and send all items to the client.
518
+ * Waits for the client's initial Ack before starting to pump items.
519
+ */
520
+ writeFrom(source: AsyncIterable<T>): Promise<void>;
521
+ reconnect(): void;
522
+ disconnect(): void;
523
+ }
524
+
371
525
  /** Creates a typed RPC client proxy — intercepts method calls and sends them over RPC. */
372
526
  declare function createRpcClient<T extends object>(peer: RpcPeer, serviceDef: RpcServiceDef): T;
373
527
 
@@ -379,26 +533,21 @@ interface WebSocketServer {
379
533
 
380
534
  interface MethodMeta {
381
535
  argCount: number;
382
- stream?: boolean;
383
- noWait?: boolean;
536
+ returns?: symbol;
384
537
  [key: symbol]: unknown;
385
538
  }
386
539
  interface ServiceMeta {
387
540
  name: string;
388
- ctOffset?: number;
389
541
  }
390
542
  /** Read method metadata from a decorated class. */
391
543
  declare function getMethodsMeta(cls: abstract new (...args: any[]) => any): Record<string, MethodMeta> | undefined;
392
544
  /** Read service metadata from a decorated class. */
393
545
  declare function getServiceMeta(cls: abstract new (...args: any[]) => any): ServiceMeta | undefined;
394
- /** Class decorator — stores the RPC service wire name and optional ctOffset. */
395
- declare function rpcService(serviceName: string, options?: {
396
- ctOffset?: number;
397
- }): <T extends abstract new (...args: any[]) => any>(_target: T, context: ClassDecoratorContext<T>) => void;
398
- /** Method decorator — stores RPC method metadata (argCount, stream, noWait). Does NOT wrap the method. */
546
+ /** Class decorator — stores the RPC service wire name. */
547
+ declare function rpcService(serviceName: string): <T extends abstract new (...args: any[]) => any>(_target: T, context: ClassDecoratorContext<T>) => void;
548
+ /** Method decorator — stores RPC method metadata (argCount, returns). Does NOT wrap the method. */
399
549
  declare function rpcMethod(options?: {
400
- stream?: boolean;
401
- noWait?: boolean;
550
+ returns?: symbol;
402
551
  }): <This, Args extends unknown[], Return>(target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>) => (this: This, ...args: Args) => Return;
403
552
 
404
553
  declare const enum RpcPeerStateKind {
@@ -437,4 +586,4 @@ declare class RpcPeerStateMonitor {
437
586
  private _scheduleRecompute;
438
587
  }
439
588
 
440
- export { ARG_DELIMITER, DEFAULT_SERIALIZATION_FORMAT, ENVELOPE_DELIMITER, FRAME_DELIMITER, type MethodMeta, type RemoteHandshake, type RpcCallOptions, RpcCallTypeId, RpcClientPeer, RpcClientPeerReconnectDelayer, type RpcConnection, type RpcConnectionUrlResolver, type RpcDispatchContext, RpcHub, RpcInboundCall, RpcInboundCallTracker, type RpcMessage, RpcMessageChannelConnection, type RpcMethodDef, type RpcMethodDefInput, RpcOutboundCall, RpcOutboundCallTracker, RpcPeer, RpcPeerConnectionKind, type RpcPeerState, RpcPeerStateKind, RpcPeerStateMonitor, RpcServerPeer, type RpcServiceDef, type RpcServiceDefOptions, RpcServiceHost, type RpcServiceImpl, RpcSystemCallSender, RpcSystemCalls, RpcType, RpcWebSocketConnection, type ServiceMeta, type WebSocketLike, type WebSocketServer, WebSocketState, createMessageChannelPair, createRpcClient, defaultConnectionUrlResolver, defineRpcService, deserializeMessage, getMethodsMeta, getServiceMeta, getStateDescription, handleSystemCall, isConnected, likelyConnected, rpcMethod, rpcService, serializeFrame, serializeMessage, splitFrame, wireMethodName };
589
+ export { ARG_DELIMITER, DEFAULT_SERIALIZATION_FORMAT, ENVELOPE_DELIMITER, FRAME_DELIMITER, type IRpcObject, type MethodMeta, type RemoteHandshake, type RpcCallOptions, RpcCallTypeId, RpcClientPeer, RpcClientPeerReconnectDelayer, type RpcConnection, type RpcConnectionUrlResolver, type RpcDispatchContext, RpcHub, RpcInboundCall, RpcInboundCallTracker, type RpcMessage, RpcMessageChannelConnection, type RpcMethodDef, type RpcMethodDefInput, type RpcObjectId, RpcObjectKind, RpcOutboundCall, RpcOutboundCallTracker, RpcPeer, RpcPeerConnectionKind, type RpcPeerState, RpcPeerStateKind, RpcPeerStateMonitor, RpcRemoteObjectTracker, RpcServerPeer, type RpcServiceDef, RpcServiceHost, type RpcServiceImpl, RpcSharedObjectTracker, RpcStream, type RpcStreamRef, RpcStreamSender, RpcSystemCallHandler, RpcSystemCallSender, RpcSystemCalls, RpcType, RpcWebSocketConnection, type ServiceMeta, type WebSocketLike, type WebSocketServer, WebSocketState, createMessageChannelPair, createRpcClient, defaultConnectionUrlResolver, defineRpcService, deserializeMessage, getMethodsMeta, getServiceMeta, getStateDescription, isConnected, likelyConnected, parseStreamRef, resolveStreamRefs, rpcMethod, rpcService, serializeFrame, serializeMessage, splitFrame, wireMethodName };