@actuallab/rpc 12.3.6 → 12.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +86 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -6
- package/dist/index.d.ts +40 -6
- package/dist/index.js +85 -17
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -380,6 +380,19 @@ declare function createMessageChannelPair(): [
|
|
|
380
380
|
RpcMessageChannelConnection
|
|
381
381
|
];
|
|
382
382
|
|
|
383
|
+
/** Controls outbound RPC call behavior regarding connection waiting, reconnection, and resending. */
|
|
384
|
+
declare const RpcRemoteExecutionMode: {
|
|
385
|
+
/** Wait for connection if disconnected when the call is made. */
|
|
386
|
+
readonly AwaitForConnection: 1;
|
|
387
|
+
/** Resend on reconnection to the same peer. */
|
|
388
|
+
readonly AllowReconnect: 2;
|
|
389
|
+
/** Resend on reconnection to a different peer (implies AllowReconnect). */
|
|
390
|
+
readonly AllowResend: 6;
|
|
391
|
+
/** Default: wait + reconnect + resend. */
|
|
392
|
+
readonly Default: 7;
|
|
393
|
+
};
|
|
394
|
+
/** Bitfield combination of RpcRemoteExecutionMode flags. */
|
|
395
|
+
type RpcRemoteExecutionMode = number;
|
|
383
396
|
/** Describes a single method on an RPC service. */
|
|
384
397
|
interface RpcMethodDef {
|
|
385
398
|
readonly name: string;
|
|
@@ -389,6 +402,7 @@ interface RpcMethodDef {
|
|
|
389
402
|
readonly callTypeId: number;
|
|
390
403
|
readonly stream: boolean;
|
|
391
404
|
readonly noWait: boolean;
|
|
405
|
+
readonly remoteExecutionMode: RpcRemoteExecutionMode;
|
|
392
406
|
}
|
|
393
407
|
/** Describes an RPC service — its name and method definitions. */
|
|
394
408
|
interface RpcServiceDef {
|
|
@@ -401,6 +415,8 @@ interface RpcMethodDefInput {
|
|
|
401
415
|
callTypeId?: number;
|
|
402
416
|
/** Override for wireArgCount. Default: args.length + 1 (assumes a CancellationToken slot). */
|
|
403
417
|
wireArgCount?: number;
|
|
418
|
+
/** Override for remoteExecutionMode. Default: RpcRemoteExecutionMode.Default (7). NoWait methods always use 0. */
|
|
419
|
+
remoteExecutionMode?: RpcRemoteExecutionMode;
|
|
404
420
|
}
|
|
405
421
|
declare const RpcType: {
|
|
406
422
|
readonly object: symbol;
|
|
@@ -417,12 +433,14 @@ declare class RpcOutboundCall {
|
|
|
417
433
|
readonly callId: number;
|
|
418
434
|
readonly method: string;
|
|
419
435
|
readonly result: PromiseSource<unknown>;
|
|
436
|
+
/** Bitfield of RpcRemoteExecutionMode flags controlling reconnect/resend behavior. */
|
|
437
|
+
readonly remoteExecutionMode: number;
|
|
420
438
|
/** Whether to remove this call from the tracker on $sys.Ok. Default: true.
|
|
421
439
|
* Subclasses (e.g. compute calls) override to false to stay in tracker for invalidation. */
|
|
422
440
|
readonly removeOnOk: boolean;
|
|
423
441
|
/** The serialized wire data — stored for re-sending on reconnect. */
|
|
424
442
|
serializedWireData: string | Uint8Array;
|
|
425
|
-
constructor(callId: number, method: string);
|
|
443
|
+
constructor(callId: number, method: string, remoteExecutionMode?: number);
|
|
426
444
|
/** Called when the connection is lost. Subclasses can override to resolve invalidation promises. */
|
|
427
445
|
onDisconnect(): void;
|
|
428
446
|
}
|
|
@@ -483,6 +501,8 @@ declare class RpcServiceHost {
|
|
|
483
501
|
interface MethodMeta {
|
|
484
502
|
argCount: number;
|
|
485
503
|
returns?: symbol;
|
|
504
|
+
/** Bitfield of RpcRemoteExecutionMode flags. */
|
|
505
|
+
remoteExecutionMode?: number;
|
|
486
506
|
[key: symbol]: unknown;
|
|
487
507
|
}
|
|
488
508
|
interface ServiceMeta {
|
|
@@ -495,9 +515,10 @@ declare function getMethodsMeta(cls: AnyConstructor): Record<string, MethodMeta>
|
|
|
495
515
|
declare function getServiceMeta(cls: AnyConstructor): ServiceMeta | undefined;
|
|
496
516
|
/** Class decorator — stores the RPC service wire name. */
|
|
497
517
|
declare function rpcService(serviceName: string): <T extends AnyConstructor>(_target: T, context: ClassDecoratorContext<T>) => void;
|
|
498
|
-
/** Method decorator — stores RPC method metadata (argCount, returns). Does NOT wrap the method. */
|
|
518
|
+
/** Method decorator — stores RPC method metadata (argCount, returns, remoteExecutionMode). Does NOT wrap the method. */
|
|
499
519
|
declare function rpcMethod(options?: {
|
|
500
520
|
returns?: symbol;
|
|
521
|
+
remoteExecutionMode?: number;
|
|
501
522
|
}): <This, Args extends unknown[], Return>(target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>) => (this: This, ...args: Args) => Return;
|
|
502
523
|
|
|
503
524
|
/**
|
|
@@ -631,6 +652,8 @@ interface RpcCallOptions {
|
|
|
631
652
|
outboundCallFactory?: (id: number, method: string) => RpcOutboundCall;
|
|
632
653
|
/** AbortSignal for caller-initiated cancellation. */
|
|
633
654
|
signal?: AbortSignal;
|
|
655
|
+
/** Bitfield of RpcRemoteExecutionMode flags (default: 7 = Default). */
|
|
656
|
+
remoteExecutionMode?: number;
|
|
634
657
|
}
|
|
635
658
|
/** Data extracted from an inbound $sys.Handshake message. */
|
|
636
659
|
interface RemoteHandshake {
|
|
@@ -754,6 +777,13 @@ interface RpcStreamRef {
|
|
|
754
777
|
readonly allowReconnect: boolean;
|
|
755
778
|
readonly isRealTime: boolean;
|
|
756
779
|
}
|
|
780
|
+
/**
|
|
781
|
+
* A stream source is either a plain async iterable or a factory function
|
|
782
|
+
* that receives an AbortSignal and returns an async iterable.
|
|
783
|
+
* The AbortSignal is aborted when the sender is disconnected, allowing
|
|
784
|
+
* the source to release resources (e.g., camera, microphone) promptly.
|
|
785
|
+
*/
|
|
786
|
+
type RpcStreamSource<T> = AsyncIterable<T> | ((abortSignal: AbortSignal) => AsyncIterable<T>);
|
|
757
787
|
/** Configuration options for creating a local (origin-side) RpcStream. */
|
|
758
788
|
interface RpcStreamOptions<T> {
|
|
759
789
|
ackPeriod?: number;
|
|
@@ -787,7 +817,7 @@ declare class RpcStream<T> implements AsyncIterable<T>, IRpcObject {
|
|
|
787
817
|
readonly canSkipTo: (item: T) => boolean;
|
|
788
818
|
readonly ackPeriod: number;
|
|
789
819
|
readonly ackAdvance: number;
|
|
790
|
-
readonly localSource?:
|
|
820
|
+
readonly localSource?: RpcStreamSource<T>;
|
|
791
821
|
readonly peer: RpcPeer;
|
|
792
822
|
private _sender?;
|
|
793
823
|
private _toRefValue?;
|
|
@@ -801,8 +831,8 @@ declare class RpcStream<T> implements AsyncIterable<T>, IRpcObject {
|
|
|
801
831
|
private _started;
|
|
802
832
|
private _iterating;
|
|
803
833
|
private _ackSentUpTo;
|
|
804
|
-
/** Create a local (origin-side) stream wrapping an async iterable with optional configuration. */
|
|
805
|
-
constructor(source:
|
|
834
|
+
/** Create a local (origin-side) stream wrapping an async iterable or source factory with optional configuration. */
|
|
835
|
+
constructor(source: RpcStreamSource<T>, options?: RpcStreamOptions<T>);
|
|
806
836
|
/** Create a remote (target-side) stream from a parsed stream reference and peer. */
|
|
807
837
|
constructor(ref: RpcStreamRef, peer: RpcPeer);
|
|
808
838
|
/**
|
|
@@ -874,7 +904,11 @@ declare class RpcStreamSender<T> implements IRpcObject {
|
|
|
874
904
|
private _lastAckedIndex;
|
|
875
905
|
private _ackWaiting;
|
|
876
906
|
private _resetRequested;
|
|
907
|
+
private _abortController;
|
|
908
|
+
private _iterator;
|
|
877
909
|
constructor(peer: RpcPeer, ackPeriod?: number, ackAdvance?: number, allowReconnect?: boolean, isRealTime?: boolean, canSkipTo?: (item: T) => boolean);
|
|
910
|
+
/** AbortSignal that is aborted when the sender is disconnected. */
|
|
911
|
+
get abortSignal(): AbortSignal;
|
|
878
912
|
/** Returns the stream reference string for the $sys.Ok response. */
|
|
879
913
|
toRef(): string;
|
|
880
914
|
/** Called by system call handler when $sys.Ack is received from the client. */
|
|
@@ -968,4 +1002,4 @@ declare function xxh3_64str(input: string, seed?: bigint): bigint;
|
|
|
968
1002
|
*/
|
|
969
1003
|
declare function computeMethodHash(methodName: string): number;
|
|
970
1004
|
|
|
971
|
-
export { ARG_DELIMITER, ENVELOPE_DELIMITER, FRAME_DELIMITER, type IRpcObject, type MethodMeta, RPC_CLOSE_CODE_UNSUPPORTED_FORMAT, type RemoteHandshake, type RpcCallOptions, RpcCallTypeId, RpcClientPeer, RpcClientPeerReconnectDelayer, type RpcConnection, type RpcConnectionUrlResolver, type RpcDeserializedMessage, type RpcDispatchContext, RpcHub, RpcInboundCall, RpcInboundCallTracker, RpcJsonSerializationFormat, type RpcMessage, RpcMessageChannelConnection, RpcMessagePackCompactSerializationFormat, RpcMessagePackSerializationFormat, type RpcMethodDef, type RpcMethodDefInput, RpcMethodRegistry, type RpcObjectId, RpcObjectKind, RpcOutboundCall, RpcOutboundCallTracker, RpcPeer, RpcPeerConnectionKind, type RpcPeerState, RpcPeerStateKind, RpcPeerStateMonitor, type RpcReceivedMessage, RpcRemoteObjectTracker, RpcSerializationFormat, RpcSerializationFormatResolver, RpcServerPeer, type RpcServiceDef, RpcServiceHost, type RpcServiceImpl, RpcSharedObjectTracker, RpcStream, type RpcStreamOptions, type RpcStreamRef, RpcStreamSender, 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, getMethodsMeta, getServiceMeta, getStateDescription, isConnected, likelyConnected, parseStreamRef, resolveStreamRefs, rpcMethod, rpcService, serializeBinaryFrame, serializeBinaryMessage, serializeCompactBinaryMessage, serializeFrame, serializeMessage, splitBinaryFrame, splitCompactBinaryFrame, splitFrame, wireMethodName, xxh3_64, xxh3_64str };
|
|
1005
|
+
export { ARG_DELIMITER, ENVELOPE_DELIMITER, FRAME_DELIMITER, type IRpcObject, type MethodMeta, RPC_CLOSE_CODE_UNSUPPORTED_FORMAT, type RemoteHandshake, type RpcCallOptions, RpcCallTypeId, RpcClientPeer, RpcClientPeerReconnectDelayer, type RpcConnection, type RpcConnectionUrlResolver, type RpcDeserializedMessage, type RpcDispatchContext, RpcHub, RpcInboundCall, RpcInboundCallTracker, RpcJsonSerializationFormat, type RpcMessage, RpcMessageChannelConnection, RpcMessagePackCompactSerializationFormat, RpcMessagePackSerializationFormat, type RpcMethodDef, type RpcMethodDefInput, RpcMethodRegistry, type RpcObjectId, RpcObjectKind, RpcOutboundCall, RpcOutboundCallTracker, RpcPeer, RpcPeerConnectionKind, 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, getMethodsMeta, getServiceMeta, getStateDescription, isConnected, likelyConnected, parseStreamRef, resolveStreamRefs, rpcMethod, rpcService, serializeBinaryFrame, serializeBinaryMessage, serializeCompactBinaryMessage, serializeFrame, serializeMessage, splitBinaryFrame, splitCompactBinaryFrame, splitFrame, wireMethodName, xxh3_64, xxh3_64str };
|
package/dist/index.d.ts
CHANGED
|
@@ -380,6 +380,19 @@ declare function createMessageChannelPair(): [
|
|
|
380
380
|
RpcMessageChannelConnection
|
|
381
381
|
];
|
|
382
382
|
|
|
383
|
+
/** Controls outbound RPC call behavior regarding connection waiting, reconnection, and resending. */
|
|
384
|
+
declare const RpcRemoteExecutionMode: {
|
|
385
|
+
/** Wait for connection if disconnected when the call is made. */
|
|
386
|
+
readonly AwaitForConnection: 1;
|
|
387
|
+
/** Resend on reconnection to the same peer. */
|
|
388
|
+
readonly AllowReconnect: 2;
|
|
389
|
+
/** Resend on reconnection to a different peer (implies AllowReconnect). */
|
|
390
|
+
readonly AllowResend: 6;
|
|
391
|
+
/** Default: wait + reconnect + resend. */
|
|
392
|
+
readonly Default: 7;
|
|
393
|
+
};
|
|
394
|
+
/** Bitfield combination of RpcRemoteExecutionMode flags. */
|
|
395
|
+
type RpcRemoteExecutionMode = number;
|
|
383
396
|
/** Describes a single method on an RPC service. */
|
|
384
397
|
interface RpcMethodDef {
|
|
385
398
|
readonly name: string;
|
|
@@ -389,6 +402,7 @@ interface RpcMethodDef {
|
|
|
389
402
|
readonly callTypeId: number;
|
|
390
403
|
readonly stream: boolean;
|
|
391
404
|
readonly noWait: boolean;
|
|
405
|
+
readonly remoteExecutionMode: RpcRemoteExecutionMode;
|
|
392
406
|
}
|
|
393
407
|
/** Describes an RPC service — its name and method definitions. */
|
|
394
408
|
interface RpcServiceDef {
|
|
@@ -401,6 +415,8 @@ interface RpcMethodDefInput {
|
|
|
401
415
|
callTypeId?: number;
|
|
402
416
|
/** Override for wireArgCount. Default: args.length + 1 (assumes a CancellationToken slot). */
|
|
403
417
|
wireArgCount?: number;
|
|
418
|
+
/** Override for remoteExecutionMode. Default: RpcRemoteExecutionMode.Default (7). NoWait methods always use 0. */
|
|
419
|
+
remoteExecutionMode?: RpcRemoteExecutionMode;
|
|
404
420
|
}
|
|
405
421
|
declare const RpcType: {
|
|
406
422
|
readonly object: symbol;
|
|
@@ -417,12 +433,14 @@ declare class RpcOutboundCall {
|
|
|
417
433
|
readonly callId: number;
|
|
418
434
|
readonly method: string;
|
|
419
435
|
readonly result: PromiseSource<unknown>;
|
|
436
|
+
/** Bitfield of RpcRemoteExecutionMode flags controlling reconnect/resend behavior. */
|
|
437
|
+
readonly remoteExecutionMode: number;
|
|
420
438
|
/** Whether to remove this call from the tracker on $sys.Ok. Default: true.
|
|
421
439
|
* Subclasses (e.g. compute calls) override to false to stay in tracker for invalidation. */
|
|
422
440
|
readonly removeOnOk: boolean;
|
|
423
441
|
/** The serialized wire data — stored for re-sending on reconnect. */
|
|
424
442
|
serializedWireData: string | Uint8Array;
|
|
425
|
-
constructor(callId: number, method: string);
|
|
443
|
+
constructor(callId: number, method: string, remoteExecutionMode?: number);
|
|
426
444
|
/** Called when the connection is lost. Subclasses can override to resolve invalidation promises. */
|
|
427
445
|
onDisconnect(): void;
|
|
428
446
|
}
|
|
@@ -483,6 +501,8 @@ declare class RpcServiceHost {
|
|
|
483
501
|
interface MethodMeta {
|
|
484
502
|
argCount: number;
|
|
485
503
|
returns?: symbol;
|
|
504
|
+
/** Bitfield of RpcRemoteExecutionMode flags. */
|
|
505
|
+
remoteExecutionMode?: number;
|
|
486
506
|
[key: symbol]: unknown;
|
|
487
507
|
}
|
|
488
508
|
interface ServiceMeta {
|
|
@@ -495,9 +515,10 @@ declare function getMethodsMeta(cls: AnyConstructor): Record<string, MethodMeta>
|
|
|
495
515
|
declare function getServiceMeta(cls: AnyConstructor): ServiceMeta | undefined;
|
|
496
516
|
/** Class decorator — stores the RPC service wire name. */
|
|
497
517
|
declare function rpcService(serviceName: string): <T extends AnyConstructor>(_target: T, context: ClassDecoratorContext<T>) => void;
|
|
498
|
-
/** Method decorator — stores RPC method metadata (argCount, returns). Does NOT wrap the method. */
|
|
518
|
+
/** Method decorator — stores RPC method metadata (argCount, returns, remoteExecutionMode). Does NOT wrap the method. */
|
|
499
519
|
declare function rpcMethod(options?: {
|
|
500
520
|
returns?: symbol;
|
|
521
|
+
remoteExecutionMode?: number;
|
|
501
522
|
}): <This, Args extends unknown[], Return>(target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>) => (this: This, ...args: Args) => Return;
|
|
502
523
|
|
|
503
524
|
/**
|
|
@@ -631,6 +652,8 @@ interface RpcCallOptions {
|
|
|
631
652
|
outboundCallFactory?: (id: number, method: string) => RpcOutboundCall;
|
|
632
653
|
/** AbortSignal for caller-initiated cancellation. */
|
|
633
654
|
signal?: AbortSignal;
|
|
655
|
+
/** Bitfield of RpcRemoteExecutionMode flags (default: 7 = Default). */
|
|
656
|
+
remoteExecutionMode?: number;
|
|
634
657
|
}
|
|
635
658
|
/** Data extracted from an inbound $sys.Handshake message. */
|
|
636
659
|
interface RemoteHandshake {
|
|
@@ -754,6 +777,13 @@ interface RpcStreamRef {
|
|
|
754
777
|
readonly allowReconnect: boolean;
|
|
755
778
|
readonly isRealTime: boolean;
|
|
756
779
|
}
|
|
780
|
+
/**
|
|
781
|
+
* A stream source is either a plain async iterable or a factory function
|
|
782
|
+
* that receives an AbortSignal and returns an async iterable.
|
|
783
|
+
* The AbortSignal is aborted when the sender is disconnected, allowing
|
|
784
|
+
* the source to release resources (e.g., camera, microphone) promptly.
|
|
785
|
+
*/
|
|
786
|
+
type RpcStreamSource<T> = AsyncIterable<T> | ((abortSignal: AbortSignal) => AsyncIterable<T>);
|
|
757
787
|
/** Configuration options for creating a local (origin-side) RpcStream. */
|
|
758
788
|
interface RpcStreamOptions<T> {
|
|
759
789
|
ackPeriod?: number;
|
|
@@ -787,7 +817,7 @@ declare class RpcStream<T> implements AsyncIterable<T>, IRpcObject {
|
|
|
787
817
|
readonly canSkipTo: (item: T) => boolean;
|
|
788
818
|
readonly ackPeriod: number;
|
|
789
819
|
readonly ackAdvance: number;
|
|
790
|
-
readonly localSource?:
|
|
820
|
+
readonly localSource?: RpcStreamSource<T>;
|
|
791
821
|
readonly peer: RpcPeer;
|
|
792
822
|
private _sender?;
|
|
793
823
|
private _toRefValue?;
|
|
@@ -801,8 +831,8 @@ declare class RpcStream<T> implements AsyncIterable<T>, IRpcObject {
|
|
|
801
831
|
private _started;
|
|
802
832
|
private _iterating;
|
|
803
833
|
private _ackSentUpTo;
|
|
804
|
-
/** Create a local (origin-side) stream wrapping an async iterable with optional configuration. */
|
|
805
|
-
constructor(source:
|
|
834
|
+
/** Create a local (origin-side) stream wrapping an async iterable or source factory with optional configuration. */
|
|
835
|
+
constructor(source: RpcStreamSource<T>, options?: RpcStreamOptions<T>);
|
|
806
836
|
/** Create a remote (target-side) stream from a parsed stream reference and peer. */
|
|
807
837
|
constructor(ref: RpcStreamRef, peer: RpcPeer);
|
|
808
838
|
/**
|
|
@@ -874,7 +904,11 @@ declare class RpcStreamSender<T> implements IRpcObject {
|
|
|
874
904
|
private _lastAckedIndex;
|
|
875
905
|
private _ackWaiting;
|
|
876
906
|
private _resetRequested;
|
|
907
|
+
private _abortController;
|
|
908
|
+
private _iterator;
|
|
877
909
|
constructor(peer: RpcPeer, ackPeriod?: number, ackAdvance?: number, allowReconnect?: boolean, isRealTime?: boolean, canSkipTo?: (item: T) => boolean);
|
|
910
|
+
/** AbortSignal that is aborted when the sender is disconnected. */
|
|
911
|
+
get abortSignal(): AbortSignal;
|
|
878
912
|
/** Returns the stream reference string for the $sys.Ok response. */
|
|
879
913
|
toRef(): string;
|
|
880
914
|
/** Called by system call handler when $sys.Ack is received from the client. */
|
|
@@ -968,4 +1002,4 @@ declare function xxh3_64str(input: string, seed?: bigint): bigint;
|
|
|
968
1002
|
*/
|
|
969
1003
|
declare function computeMethodHash(methodName: string): number;
|
|
970
1004
|
|
|
971
|
-
export { ARG_DELIMITER, ENVELOPE_DELIMITER, FRAME_DELIMITER, type IRpcObject, type MethodMeta, RPC_CLOSE_CODE_UNSUPPORTED_FORMAT, type RemoteHandshake, type RpcCallOptions, RpcCallTypeId, RpcClientPeer, RpcClientPeerReconnectDelayer, type RpcConnection, type RpcConnectionUrlResolver, type RpcDeserializedMessage, type RpcDispatchContext, RpcHub, RpcInboundCall, RpcInboundCallTracker, RpcJsonSerializationFormat, type RpcMessage, RpcMessageChannelConnection, RpcMessagePackCompactSerializationFormat, RpcMessagePackSerializationFormat, type RpcMethodDef, type RpcMethodDefInput, RpcMethodRegistry, type RpcObjectId, RpcObjectKind, RpcOutboundCall, RpcOutboundCallTracker, RpcPeer, RpcPeerConnectionKind, type RpcPeerState, RpcPeerStateKind, RpcPeerStateMonitor, type RpcReceivedMessage, RpcRemoteObjectTracker, RpcSerializationFormat, RpcSerializationFormatResolver, RpcServerPeer, type RpcServiceDef, RpcServiceHost, type RpcServiceImpl, RpcSharedObjectTracker, RpcStream, type RpcStreamOptions, type RpcStreamRef, RpcStreamSender, 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, getMethodsMeta, getServiceMeta, getStateDescription, isConnected, likelyConnected, parseStreamRef, resolveStreamRefs, rpcMethod, rpcService, serializeBinaryFrame, serializeBinaryMessage, serializeCompactBinaryMessage, serializeFrame, serializeMessage, splitBinaryFrame, splitCompactBinaryFrame, splitFrame, wireMethodName, xxh3_64, xxh3_64str };
|
|
1005
|
+
export { ARG_DELIMITER, ENVELOPE_DELIMITER, FRAME_DELIMITER, type IRpcObject, type MethodMeta, RPC_CLOSE_CODE_UNSUPPORTED_FORMAT, type RemoteHandshake, type RpcCallOptions, RpcCallTypeId, RpcClientPeer, RpcClientPeerReconnectDelayer, type RpcConnection, type RpcConnectionUrlResolver, type RpcDeserializedMessage, type RpcDispatchContext, RpcHub, RpcInboundCall, RpcInboundCallTracker, RpcJsonSerializationFormat, type RpcMessage, RpcMessageChannelConnection, RpcMessagePackCompactSerializationFormat, RpcMessagePackSerializationFormat, type RpcMethodDef, type RpcMethodDefInput, RpcMethodRegistry, type RpcObjectId, RpcObjectKind, RpcOutboundCall, RpcOutboundCallTracker, RpcPeer, RpcPeerConnectionKind, 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, getMethodsMeta, getServiceMeta, getStateDescription, isConnected, likelyConnected, parseStreamRef, resolveStreamRefs, rpcMethod, rpcService, serializeBinaryFrame, serializeBinaryMessage, serializeCompactBinaryMessage, serializeFrame, serializeMessage, splitBinaryFrame, splitCompactBinaryFrame, splitFrame, wireMethodName, xxh3_64, xxh3_64str };
|
package/dist/index.js
CHANGED
|
@@ -515,6 +515,18 @@ function createMessageChannelPair() {
|
|
|
515
515
|
}
|
|
516
516
|
|
|
517
517
|
// src/rpc-service-def.ts
|
|
518
|
+
var RpcRemoteExecutionMode = {
|
|
519
|
+
/** Wait for connection if disconnected when the call is made. */
|
|
520
|
+
AwaitForConnection: 1,
|
|
521
|
+
/** Resend on reconnection to the same peer. */
|
|
522
|
+
AllowReconnect: 2,
|
|
523
|
+
/** Resend on reconnection to a different peer (implies AllowReconnect). */
|
|
524
|
+
AllowResend: 6,
|
|
525
|
+
// 4 | AllowReconnect
|
|
526
|
+
/** Default: wait + reconnect + resend. */
|
|
527
|
+
Default: 7
|
|
528
|
+
// AwaitForConnection | AllowResend
|
|
529
|
+
};
|
|
518
530
|
var RpcType = {
|
|
519
531
|
object: /* @__PURE__ */ Symbol("object"),
|
|
520
532
|
stream: /* @__PURE__ */ Symbol("stream"),
|
|
@@ -531,6 +543,7 @@ function defineRpcService(name, methods) {
|
|
|
531
543
|
const cleanName = colonIndex >= 0 ? key.substring(0, colonIndex) : key;
|
|
532
544
|
const wireArgCount = input.wireArgCount ?? input.args.length + 1;
|
|
533
545
|
const mapKey = `${cleanName}:${wireArgCount}`;
|
|
546
|
+
const isNoWait = input.returns === RpcType.noWait;
|
|
534
547
|
map.set(mapKey, {
|
|
535
548
|
name: cleanName,
|
|
536
549
|
serviceName: name,
|
|
@@ -538,7 +551,8 @@ function defineRpcService(name, methods) {
|
|
|
538
551
|
wireArgCount,
|
|
539
552
|
callTypeId: input.callTypeId ?? 0,
|
|
540
553
|
stream: input.returns === RpcType.stream,
|
|
541
|
-
noWait:
|
|
554
|
+
noWait: isNoWait,
|
|
555
|
+
remoteExecutionMode: isNoWait ? 0 : input.remoteExecutionMode ?? RpcRemoteExecutionMode.Default
|
|
542
556
|
});
|
|
543
557
|
}
|
|
544
558
|
return { name, methods: map };
|
|
@@ -550,14 +564,17 @@ var RpcOutboundCall = class {
|
|
|
550
564
|
callId;
|
|
551
565
|
method;
|
|
552
566
|
result = new PromiseSource2();
|
|
567
|
+
/** Bitfield of RpcRemoteExecutionMode flags controlling reconnect/resend behavior. */
|
|
568
|
+
remoteExecutionMode;
|
|
553
569
|
/** Whether to remove this call from the tracker on $sys.Ok. Default: true.
|
|
554
570
|
* Subclasses (e.g. compute calls) override to false to stay in tracker for invalidation. */
|
|
555
571
|
removeOnOk = true;
|
|
556
572
|
/** The serialized wire data — stored for re-sending on reconnect. */
|
|
557
573
|
serializedWireData = "";
|
|
558
|
-
constructor(callId, method) {
|
|
574
|
+
constructor(callId, method, remoteExecutionMode = 7) {
|
|
559
575
|
this.callId = callId;
|
|
560
576
|
this.method = method;
|
|
577
|
+
this.remoteExecutionMode = remoteExecutionMode;
|
|
561
578
|
}
|
|
562
579
|
/** Called when the connection is lost. Subclasses can override to resolve invalidation promises. */
|
|
563
580
|
onDisconnect() {
|
|
@@ -670,6 +687,8 @@ var RpcStreamSender = class _RpcStreamSender {
|
|
|
670
687
|
_lastAckedIndex = 0;
|
|
671
688
|
_ackWaiting = null;
|
|
672
689
|
_resetRequested = false;
|
|
690
|
+
_abortController = new AbortController();
|
|
691
|
+
_iterator = null;
|
|
673
692
|
constructor(peer, ackPeriod = DEFAULT_ACK_PERIOD, ackAdvance = DEFAULT_ACK_ADVANCE, allowReconnect = true, isRealTime = false, canSkipTo = () => true) {
|
|
674
693
|
const localId = peer.sharedObjects.nextId();
|
|
675
694
|
this.id = { hostId: peer.hub.hubId, localId };
|
|
@@ -680,6 +699,10 @@ var RpcStreamSender = class _RpcStreamSender {
|
|
|
680
699
|
this.ackPeriod = ackPeriod;
|
|
681
700
|
this.ackAdvance = ackAdvance;
|
|
682
701
|
}
|
|
702
|
+
/** AbortSignal that is aborted when the sender is disconnected. */
|
|
703
|
+
get abortSignal() {
|
|
704
|
+
return this._abortController.signal;
|
|
705
|
+
}
|
|
683
706
|
/** Returns the stream reference string for the $sys.Ok response. */
|
|
684
707
|
toRef() {
|
|
685
708
|
return `${this.id.hostId},${this.id.localId},${this.ackPeriod},${this.ackAdvance},${this.allowReconnect ? "1" : "0"},${this.isRealTime ? "1" : "0"}`;
|
|
@@ -706,8 +729,7 @@ var RpcStreamSender = class _RpcStreamSender {
|
|
|
706
729
|
}
|
|
707
730
|
/** Called by system call handler when $sys.AckEnd is received from the client. */
|
|
708
731
|
onAckEnd(_hostId) {
|
|
709
|
-
this.
|
|
710
|
-
this.peer.sharedObjects.unregister(this);
|
|
732
|
+
this.disconnect();
|
|
711
733
|
}
|
|
712
734
|
/** Send a single item to the client. */
|
|
713
735
|
sendItem(item) {
|
|
@@ -764,6 +786,7 @@ var RpcStreamSender = class _RpcStreamSender {
|
|
|
764
786
|
async writeFrom(source) {
|
|
765
787
|
await this._started.promise;
|
|
766
788
|
const iterator = source[Symbol.asyncIterator]();
|
|
789
|
+
this._iterator = iterator;
|
|
767
790
|
try {
|
|
768
791
|
for (; ; ) {
|
|
769
792
|
const next = await iterator.next();
|
|
@@ -828,10 +851,20 @@ var RpcStreamSender = class _RpcStreamSender {
|
|
|
828
851
|
reconnect() {
|
|
829
852
|
}
|
|
830
853
|
disconnect() {
|
|
854
|
+
if (this._ended) return;
|
|
831
855
|
this._ended = true;
|
|
856
|
+
this._abortController.abort();
|
|
832
857
|
if (!this._started.isCompleted) {
|
|
833
858
|
this._started.resolve();
|
|
834
859
|
}
|
|
860
|
+
if (this._ackWaiting) {
|
|
861
|
+
this._ackWaiting.resolve();
|
|
862
|
+
this._ackWaiting = null;
|
|
863
|
+
}
|
|
864
|
+
if (this._iterator) {
|
|
865
|
+
void this._iterator.return?.(void 0);
|
|
866
|
+
this._iterator = null;
|
|
867
|
+
}
|
|
835
868
|
this.peer.sharedObjects.unregister(this);
|
|
836
869
|
}
|
|
837
870
|
};
|
|
@@ -896,7 +929,7 @@ var RpcStream = class _RpcStream {
|
|
|
896
929
|
_iterating = false;
|
|
897
930
|
_ackSentUpTo = 0;
|
|
898
931
|
constructor(sourceOrRef, optionsOrPeer) {
|
|
899
|
-
if (
|
|
932
|
+
if (_isStreamSource(sourceOrRef)) {
|
|
900
933
|
const options = optionsOrPeer ?? {};
|
|
901
934
|
this.kind = RpcObjectKind.Local;
|
|
902
935
|
this.localSource = sourceOrRef;
|
|
@@ -957,7 +990,8 @@ var RpcStream = class _RpcStream {
|
|
|
957
990
|
);
|
|
958
991
|
peer.sharedObjects.register(sender);
|
|
959
992
|
this._sender = sender;
|
|
960
|
-
this.
|
|
993
|
+
const source = typeof this.localSource === "function" ? this.localSource(sender.abortSignal) : this.localSource;
|
|
994
|
+
this._whenSent = sender.writeFrom(source);
|
|
961
995
|
this._toRefValue = peer.format.isBinary ? {
|
|
962
996
|
SerializedId: [sender.id.hostId, sender.id.localId],
|
|
963
997
|
AckPeriod: sender.ackPeriod,
|
|
@@ -1037,7 +1071,10 @@ var RpcStream = class _RpcStream {
|
|
|
1037
1071
|
}
|
|
1038
1072
|
}
|
|
1039
1073
|
disconnect() {
|
|
1040
|
-
if (this.kind === RpcObjectKind.Local)
|
|
1074
|
+
if (this.kind === RpcObjectKind.Local) {
|
|
1075
|
+
this._sender?.disconnect();
|
|
1076
|
+
return;
|
|
1077
|
+
}
|
|
1041
1078
|
if (this._completed) return;
|
|
1042
1079
|
this._completed = true;
|
|
1043
1080
|
this._completionError = new Error("Peer disconnected.");
|
|
@@ -1046,7 +1083,8 @@ var RpcStream = class _RpcStream {
|
|
|
1046
1083
|
// -- AsyncIterable --
|
|
1047
1084
|
[Symbol.asyncIterator]() {
|
|
1048
1085
|
if (this.kind === RpcObjectKind.Local) {
|
|
1049
|
-
|
|
1086
|
+
const source = typeof this.localSource === "function" ? this.localSource(new AbortController().signal) : this.localSource;
|
|
1087
|
+
return source[Symbol.asyncIterator]();
|
|
1050
1088
|
}
|
|
1051
1089
|
if (this._iterating)
|
|
1052
1090
|
throw new Error("RpcStream can only be iterated once.");
|
|
@@ -1127,7 +1165,8 @@ var RpcStream = class _RpcStream {
|
|
|
1127
1165
|
}
|
|
1128
1166
|
}
|
|
1129
1167
|
};
|
|
1130
|
-
function
|
|
1168
|
+
function _isStreamSource(value) {
|
|
1169
|
+
if (typeof value === "function") return true;
|
|
1131
1170
|
return value !== null && typeof value === "object" && Symbol.asyncIterator in value;
|
|
1132
1171
|
}
|
|
1133
1172
|
function resolveStreamRefs(value, peer) {
|
|
@@ -1662,7 +1701,7 @@ var RpcPeer = class {
|
|
|
1662
1701
|
}
|
|
1663
1702
|
call(method, args, options) {
|
|
1664
1703
|
const callId = this.outbound.nextId();
|
|
1665
|
-
const outboundCall = options?.outboundCallFactory ? options.outboundCallFactory(callId, method) : new RpcOutboundCall(callId, method);
|
|
1704
|
+
const outboundCall = options?.outboundCallFactory ? options.outboundCallFactory(callId, method) : new RpcOutboundCall(callId, method, options?.remoteExecutionMode ?? 7);
|
|
1666
1705
|
const envelope = {
|
|
1667
1706
|
Method: method,
|
|
1668
1707
|
RelatedId: callId,
|
|
@@ -1999,7 +2038,18 @@ var RpcClientPeer = class extends RpcPeer {
|
|
|
1999
2038
|
}
|
|
2000
2039
|
const trackerCalls = [...this.outbound.values()];
|
|
2001
2040
|
for (const call of trackerCalls) {
|
|
2002
|
-
|
|
2041
|
+
const mode = call.remoteExecutionMode;
|
|
2042
|
+
if (!(mode & 2)) {
|
|
2043
|
+
if (!call.result.isCompleted)
|
|
2044
|
+
call.result.reject(new Error("Outbound call failed: disconnected and AllowReconnect is not set."));
|
|
2045
|
+
call.onDisconnect();
|
|
2046
|
+
this.outbound.remove(call.callId);
|
|
2047
|
+
} else if (_isPeerChanged && !(mode & 4)) {
|
|
2048
|
+
if (!call.result.isCompleted)
|
|
2049
|
+
call.result.reject(new Error("Outbound call failed: reconnected to a different peer and AllowResend is not set."));
|
|
2050
|
+
call.onDisconnect();
|
|
2051
|
+
this.outbound.remove(call.callId);
|
|
2052
|
+
} else if (!call.removeOnOk && call.result.isCompleted) {
|
|
2003
2053
|
call.onDisconnect();
|
|
2004
2054
|
this.outbound.remove(call.callId);
|
|
2005
2055
|
} else {
|
|
@@ -2023,6 +2073,9 @@ var RpcServerPeer = class extends RpcPeer {
|
|
|
2023
2073
|
/** Accept an incoming connection — sets up message handling and handshake response. */
|
|
2024
2074
|
accept(conn) {
|
|
2025
2075
|
this.setupConnection(conn);
|
|
2076
|
+
conn.closed.add(() => {
|
|
2077
|
+
this.sharedObjects.disconnectAll();
|
|
2078
|
+
});
|
|
2026
2079
|
}
|
|
2027
2080
|
_onHandshakeReceived(_handshake) {
|
|
2028
2081
|
if (this._connection !== void 0) {
|
|
@@ -2102,7 +2155,8 @@ function rpcMethod(options) {
|
|
|
2102
2155
|
methods[methodName] = {
|
|
2103
2156
|
...methods[methodName],
|
|
2104
2157
|
argCount: target.length,
|
|
2105
|
-
returns: options?.returns
|
|
2158
|
+
returns: options?.returns,
|
|
2159
|
+
remoteExecutionMode: options?.remoteExecutionMode
|
|
2106
2160
|
};
|
|
2107
2161
|
return target;
|
|
2108
2162
|
};
|
|
@@ -2717,7 +2771,8 @@ var RpcHub = class {
|
|
|
2717
2771
|
const methods = /* @__PURE__ */ new Map();
|
|
2718
2772
|
for (const [name, byArgCount] of overloads) {
|
|
2719
2773
|
if (byArgCount.size === 1) {
|
|
2720
|
-
|
|
2774
|
+
const [[, singleFn]] = byArgCount;
|
|
2775
|
+
methods.set(name, singleFn);
|
|
2721
2776
|
} else {
|
|
2722
2777
|
methods.set(name, (...args) => {
|
|
2723
2778
|
const fn = byArgCount.get(args.length);
|
|
@@ -2747,6 +2802,7 @@ var RpcHub = class {
|
|
|
2747
2802
|
for (const [name, meta] of Object.entries(methodsMeta)) {
|
|
2748
2803
|
const wireArgCount = meta.argCount + 1;
|
|
2749
2804
|
const mapKey = `${name}:${wireArgCount}`;
|
|
2805
|
+
const isNoWait = meta.returns === RpcType.noWait;
|
|
2750
2806
|
methods.set(mapKey, {
|
|
2751
2807
|
name,
|
|
2752
2808
|
serviceName: svcMeta.name,
|
|
@@ -2754,7 +2810,8 @@ var RpcHub = class {
|
|
|
2754
2810
|
wireArgCount,
|
|
2755
2811
|
callTypeId: 0,
|
|
2756
2812
|
stream: meta.returns === RpcType.stream,
|
|
2757
|
-
noWait:
|
|
2813
|
+
noWait: isNoWait,
|
|
2814
|
+
remoteExecutionMode: isNoWait ? 0 : meta.remoteExecutionMode ?? RpcRemoteExecutionMode.Default
|
|
2758
2815
|
});
|
|
2759
2816
|
}
|
|
2760
2817
|
return { name: svcMeta.name, methods };
|
|
@@ -2772,6 +2829,8 @@ var RpcHub = class {
|
|
|
2772
2829
|
/** Create a client method for the given methodDef. Override in FusionHub for custom call types. */
|
|
2773
2830
|
_createClientMethod(peer, methodDef) {
|
|
2774
2831
|
const wireName = wireMethodName(methodDef);
|
|
2832
|
+
const mode = methodDef.remoteExecutionMode;
|
|
2833
|
+
const mustCheckConnection = !(mode & RpcRemoteExecutionMode.AwaitForConnection);
|
|
2775
2834
|
if (methodDef.noWait) {
|
|
2776
2835
|
return (...args) => {
|
|
2777
2836
|
const callArgs = args.slice(0, methodDef.argCount);
|
|
@@ -2780,6 +2839,8 @@ var RpcHub = class {
|
|
|
2780
2839
|
}
|
|
2781
2840
|
if (methodDef.stream) {
|
|
2782
2841
|
return async (...args) => {
|
|
2842
|
+
if (mustCheckConnection && !peer.isConnected)
|
|
2843
|
+
throw new Error("Outbound call failed: not connected and AwaitForConnection is not set.");
|
|
2783
2844
|
const callArgs = args.slice(0, methodDef.argCount);
|
|
2784
2845
|
const outboundCall = peer.call(wireName, callArgs);
|
|
2785
2846
|
const result = await outboundCall.result.promise;
|
|
@@ -2793,8 +2854,10 @@ var RpcHub = class {
|
|
|
2793
2854
|
return stream;
|
|
2794
2855
|
};
|
|
2795
2856
|
}
|
|
2796
|
-
const callOptions = methodDef.callTypeId !== 0 ? { callTypeId: methodDef.callTypeId } : void 0;
|
|
2857
|
+
const callOptions = methodDef.callTypeId !== 0 || mode !== RpcRemoteExecutionMode.Default ? { callTypeId: methodDef.callTypeId, remoteExecutionMode: mode } : void 0;
|
|
2797
2858
|
return async (...args) => {
|
|
2859
|
+
if (mustCheckConnection && !peer.isConnected)
|
|
2860
|
+
throw new Error("Outbound call failed: not connected and AwaitForConnection is not set.");
|
|
2798
2861
|
const callArgs = args.slice(0, methodDef.argCount);
|
|
2799
2862
|
const outboundCall = peer.call(wireName, callArgs, callOptions);
|
|
2800
2863
|
const result = await outboundCall.result.promise;
|
|
@@ -2817,7 +2880,7 @@ function createRpcClient(peer, serviceDef) {
|
|
|
2817
2880
|
const methods = /* @__PURE__ */ new Map();
|
|
2818
2881
|
for (const [name, byArgCount] of overloads) {
|
|
2819
2882
|
if (byArgCount.size === 1) {
|
|
2820
|
-
const methodDef = byArgCount
|
|
2883
|
+
const [[, methodDef]] = byArgCount;
|
|
2821
2884
|
methods.set(name, createMethod(peer, methodDef));
|
|
2822
2885
|
} else {
|
|
2823
2886
|
const fns = /* @__PURE__ */ new Map();
|
|
@@ -2842,10 +2905,14 @@ function createRpcClient(peer, serviceDef) {
|
|
|
2842
2905
|
});
|
|
2843
2906
|
}
|
|
2844
2907
|
function createMethod(peer, methodDef) {
|
|
2908
|
+
const mode = methodDef.remoteExecutionMode;
|
|
2909
|
+
const mustCheckConnection = !(mode & RpcRemoteExecutionMode.AwaitForConnection);
|
|
2845
2910
|
return async (...args) => {
|
|
2911
|
+
if (mustCheckConnection && !peer.isConnected)
|
|
2912
|
+
throw new Error("Outbound call failed: not connected and AwaitForConnection is not set.");
|
|
2846
2913
|
const callArgs = args.slice(0, methodDef.argCount);
|
|
2847
2914
|
const wireName = wireMethodName(methodDef);
|
|
2848
|
-
const options = methodDef.callTypeId !== 0 ? { callTypeId: methodDef.callTypeId } : void 0;
|
|
2915
|
+
const options = methodDef.callTypeId !== 0 || mode !== RpcRemoteExecutionMode.Default ? { callTypeId: methodDef.callTypeId, remoteExecutionMode: mode } : void 0;
|
|
2849
2916
|
const outboundCall = peer.call(wireName, callArgs, options);
|
|
2850
2917
|
return outboundCall.result.promise;
|
|
2851
2918
|
};
|
|
@@ -3059,6 +3126,7 @@ export {
|
|
|
3059
3126
|
RpcPeerConnectionKind,
|
|
3060
3127
|
RpcPeerStateKind,
|
|
3061
3128
|
RpcPeerStateMonitor,
|
|
3129
|
+
RpcRemoteExecutionMode,
|
|
3062
3130
|
RpcRemoteObjectTracker,
|
|
3063
3131
|
RpcSerializationFormat,
|
|
3064
3132
|
RpcSerializationFormatResolver,
|