@nice-code/action 0.15.0 → 0.16.0
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/README.md +582 -582
- package/build/{ActionDevtoolsCore-CCRLYASa.d.cts → ActionDevtoolsCore-B3JwSaRH.d.cts} +3 -3
- package/build/{ActionDevtoolsCore-9PsnscvK.mjs → ActionDevtoolsCore-BcItqP-C.mjs} +7 -7
- package/build/ActionDevtoolsCore-BcItqP-C.mjs.map +1 -0
- package/build/{ActionDevtoolsCore-CYGD2o6C.d.mts → ActionDevtoolsCore-C4TDUY7-.d.mts} +3 -3
- package/build/{ActionDevtoolsCore-DtgXwPBZ.cjs → ActionDevtoolsCore-Cb_QR44N.cjs} +7 -7
- package/build/ActionDevtoolsCore-Cb_QR44N.cjs.map +1 -0
- package/build/{ActionPayload.types-BN-rXFBK.d.cts → ActionPayload.types-CO_hXlBc.d.cts} +1452 -941
- package/build/{ActionPayload.types-D28ELKXC.d.mts → ActionPayload.types-fieMKAgt.d.mts} +1452 -941
- package/build/devtools/browser/index.cjs +5 -5
- package/build/devtools/browser/index.cjs.map +1 -1
- package/build/devtools/browser/index.d.cts +1 -1
- package/build/devtools/browser/index.d.mts +1 -1
- package/build/devtools/browser/index.mjs +5 -5
- package/build/devtools/browser/index.mjs.map +1 -1
- package/build/devtools/server/index.cjs +1 -1
- package/build/devtools/server/index.cjs.map +1 -1
- package/build/devtools/server/index.d.cts +1 -1
- package/build/devtools/server/index.d.mts +1 -1
- package/build/devtools/server/index.mjs +1 -1
- package/build/devtools/server/index.mjs.map +1 -1
- package/build/index.cjs +2733 -1963
- package/build/index.cjs.map +1 -1
- package/build/index.d.cts +2 -2
- package/build/index.d.mts +2 -2
- package/build/index.mjs +2706 -1950
- package/build/index.mjs.map +1 -1
- package/build/react-query/index.cjs.map +1 -1
- package/build/react-query/index.d.cts +1 -1
- package/build/react-query/index.d.mts +1 -1
- package/build/react-query/index.mjs.map +1 -1
- package/package.json +4 -4
- package/build/ActionDevtoolsCore-9PsnscvK.mjs.map +0 -1
- package/build/ActionDevtoolsCore-DtgXwPBZ.cjs.map +0 -1
|
@@ -35,12 +35,45 @@ type TInferErrorFromDeclaration<D> = D extends IActionErrorDeclaration<infer DEF
|
|
|
35
35
|
type TInferDeclaredErrors<DECLS extends readonly IActionErrorDeclaration[]> = TInferErrorFromDeclaration<DECLS[number]>;
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region src/ActionDefinition/Schema/ActionSchema.d.ts
|
|
38
|
+
/**
|
|
39
|
+
* What a sender should expect back from an action — declared on its schema so both ends agree without
|
|
40
|
+
* any wire flag (each derives the mode from the shared `domain:id`).
|
|
41
|
+
*
|
|
42
|
+
* - `payload` — a typed output (the action has `.output(...)`); the sender awaits it.
|
|
43
|
+
* - `ack` — an empty success confirming receipt (no output); the sender may await it to know the
|
|
44
|
+
* receiver handled it (or to surface an error). This is the default for an action with no output.
|
|
45
|
+
* - `none` — fire-and-forget: the receiver sends no reply and the sender doesn't wait. The sender's
|
|
46
|
+
* running action completes as soon as the frame is on the wire (no pending reply, no timeout).
|
|
47
|
+
*/
|
|
48
|
+
declare enum EActionResponseMode {
|
|
49
|
+
payload = "payload",
|
|
50
|
+
ack = "ack",
|
|
51
|
+
none = "none"
|
|
52
|
+
}
|
|
38
53
|
declare class ActionSchema<INPUT extends TTransportedValue<any, any> = never, OUTPUT extends TTransportedValue<any, any> = never, ERRORS extends readonly IActionErrorDeclaration<any, any>[] = readonly []> {
|
|
39
54
|
private _errorDeclarations;
|
|
40
55
|
private inputOptions;
|
|
41
56
|
private outputOptions;
|
|
57
|
+
private _responseMode;
|
|
42
58
|
get inputSchema(): StandardSchemaV1 | undefined;
|
|
43
59
|
get outputSchema(): StandardSchemaV1 | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* The response contract for this action. Defaults are inferred — `payload` when an output schema is
|
|
62
|
+
* declared, otherwise `ack` — and made explicit by {@link ack} / {@link fireAndForget}.
|
|
63
|
+
*/
|
|
64
|
+
get responseMode(): EActionResponseMode;
|
|
65
|
+
/**
|
|
66
|
+
* Mark this action as expecting only an acknowledgment (an empty success). Mostly for clarity — an
|
|
67
|
+
* output-less action already acks by default — but it documents intent and reads as the deliberate
|
|
68
|
+
* counterpart to {@link fireAndForget}.
|
|
69
|
+
*/
|
|
70
|
+
ack(): this;
|
|
71
|
+
/**
|
|
72
|
+
* Mark this action as fire-and-forget: the receiver sends no reply, and the sender's running action
|
|
73
|
+
* completes the moment the frame is sent (no awaited reply, no timeout). Ideal for high-frequency
|
|
74
|
+
* server→client pushes (presence, ticks) where an ack would only add wire chatter.
|
|
75
|
+
*/
|
|
76
|
+
fireAndForget(): this;
|
|
44
77
|
/**
|
|
45
78
|
* Declare the input schema (JSON-native or with explicit SERDE type param).
|
|
46
79
|
* For non-JSON-native inputs, prefer the 3-argument form below to avoid
|
|
@@ -501,20 +534,20 @@ declare class ActionRouter<DATA> {
|
|
|
501
534
|
//#endregion
|
|
502
535
|
//#region src/ActionRuntime/Handler/ActionHandler.types.d.ts
|
|
503
536
|
declare enum EActionHandlerType {
|
|
504
|
-
|
|
537
|
+
peer = "peer",
|
|
505
538
|
local = "local"
|
|
506
539
|
}
|
|
507
540
|
interface IActionHandler_Json<T extends EActionHandlerType> {
|
|
508
541
|
type: T;
|
|
509
542
|
}
|
|
510
|
-
interface
|
|
543
|
+
interface IActionHandler_Peer_Json extends IActionHandler_Json<EActionHandlerType.peer> {
|
|
511
544
|
client: IRuntimeCoordinate;
|
|
512
545
|
}
|
|
513
546
|
interface IActionHandler_Local_Json extends IActionHandler_Json<EActionHandlerType.local> {}
|
|
514
|
-
type TActionHandler_Json = IActionHandler_Local_Json |
|
|
547
|
+
type TActionHandler_Json = IActionHandler_Local_Json | IActionHandler_Peer_Json;
|
|
515
548
|
interface IHandleActionOptions {
|
|
516
549
|
timeout?: number;
|
|
517
|
-
|
|
550
|
+
targetPeer?: RuntimeCoordinate;
|
|
518
551
|
targetLocalRuntime?: ActionRuntime;
|
|
519
552
|
}
|
|
520
553
|
interface IExecuteActionOptions<DOM extends IActionDomain = IActionDomain, ID extends keyof DOM["actionSchema"] & string = keyof DOM["actionSchema"] & string> extends IHandleActionOptions {
|
|
@@ -536,13 +569,13 @@ interface IActionHandler_Local extends IActionHandler_Base<EActionHandlerType.lo
|
|
|
536
569
|
}
|
|
537
570
|
/**
|
|
538
571
|
*
|
|
539
|
-
*
|
|
572
|
+
* PEER-LINK ACTION HANDLER
|
|
540
573
|
*
|
|
541
574
|
*/
|
|
542
|
-
interface
|
|
543
|
-
interface
|
|
544
|
-
|
|
545
|
-
handleActionRequest: <DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string>(action: ActionPayload_Request<DOM, ID>, config?:
|
|
575
|
+
interface IHandleActionOptions_Peer extends IHandleActionOptions {}
|
|
576
|
+
interface IActionHandler_Peer extends IActionHandler_Base<EActionHandlerType.peer> {
|
|
577
|
+
peerClient: RuntimeCoordinate;
|
|
578
|
+
handleActionRequest: <DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string>(action: ActionPayload_Request<DOM, ID>, config?: IHandleActionOptions_Peer) => Promise<RunningAction<DOM, ID>>;
|
|
546
579
|
_setIncomingActionDataListener(listener: (json: TActionPayload_Any_JsonObject<any>) => void): void;
|
|
547
580
|
}
|
|
548
581
|
/**
|
|
@@ -550,7 +583,7 @@ interface IActionHandler_ExternalClient extends IActionHandler_Base<EActionHandl
|
|
|
550
583
|
* COMBINED
|
|
551
584
|
*
|
|
552
585
|
*/
|
|
553
|
-
type TActionHandler = IActionHandler_Local |
|
|
586
|
+
type TActionHandler = IActionHandler_Local | IActionHandler_Peer;
|
|
554
587
|
//#endregion
|
|
555
588
|
//#region src/ActionDefinition/Action/Payload/ActionPayload_Request.d.ts
|
|
556
589
|
declare class ActionPayload_Request<DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string = keyof DOM["actionSchema"] & string> extends ActionPayload<EActionPayloadType.request, DOM, ID> {
|
|
@@ -624,229 +657,6 @@ declare abstract class ActionHandler<T extends EActionHandlerType> implements IA
|
|
|
624
657
|
abstract toHandlerRouteItem(...args: any[]): IActionRouteItemHandler;
|
|
625
658
|
}
|
|
626
659
|
//#endregion
|
|
627
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/TransportConnection.d.ts
|
|
628
|
-
/**
|
|
629
|
-
* Live, per-handler transport runtime built from a reusable {@link Transport} definition. Holds the
|
|
630
|
-
* connection-scoped state (ordinal, initialized config, sockets / abort sets) that must not be shared
|
|
631
|
-
* across handlers. Construct these via `definition._createConnection(...)`, never directly.
|
|
632
|
-
*/
|
|
633
|
-
declare abstract class TransportConnection<T extends ETransportType = ETransportType, RP extends ITransportRouteActionParams = ITransportRouteActionParams, RD extends IActionTransportReadyData_Base = IActionTransportReadyData_Base, I extends IActionTransportInitialized<RP, RD> = IActionTransportInitialized<RP, RD>, DEF extends IActionTransportDef<T, I> = IActionTransportDef<T, I>> {
|
|
634
|
-
readonly def: DEF;
|
|
635
|
-
readonly transOrd: number;
|
|
636
|
-
readonly type: T;
|
|
637
|
-
readonly initialized: I;
|
|
638
|
-
/** Backref to the public definition that created this connection (used for devtools route info). */
|
|
639
|
-
definition?: Transport<T>;
|
|
640
|
-
constructor(def: DEF);
|
|
641
|
-
/**
|
|
642
|
-
* Devtools route info for an action routed through this live connection. Defaults to the stateless
|
|
643
|
-
* {@link definition}'s info; connections override to enrich it from live state (e.g. the actual
|
|
644
|
-
* resolved socket URL) when the definition couldn't resolve it on its own.
|
|
645
|
-
*/
|
|
646
|
-
getRouteInfo(input: RP): ITransportRouteInfo | undefined;
|
|
647
|
-
protected abstract _finalizeTransportMethods(inputs: RD): IActionTransportReadyData_Methods;
|
|
648
|
-
protected _getCacheKey(input: RP): string | null;
|
|
649
|
-
getCacheKey(input: RP): string | null;
|
|
650
|
-
getTransport(input: RP): TTransportStatusInfo<IActionTransportReadyData_Methods>;
|
|
651
|
-
protected _processTransportStatus(input: RP): TTransportStatusInfo<IActionTransportReadyData_Methods>;
|
|
652
|
-
}
|
|
653
|
-
//#endregion
|
|
654
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/Transport.types.d.ts
|
|
655
|
-
declare enum ETransportType {
|
|
656
|
-
ws = "ws",
|
|
657
|
-
http = "http",
|
|
658
|
-
custom = "custom"
|
|
659
|
-
}
|
|
660
|
-
/**
|
|
661
|
-
* Serializable, display-only description of how an action was routed through a transport. Stored on
|
|
662
|
-
* the action's route items and shown in the devtools external-handler chips. Keep this free of
|
|
663
|
-
* sensitive data (e.g. auth headers) — route items travel over the wire.
|
|
664
|
-
*/
|
|
665
|
-
interface ITransportRouteInfo {
|
|
666
|
-
type: ETransportType;
|
|
667
|
-
/** Short label for chips, e.g. "POST /resolve_action" or "ws host/resolve_action/ws". */
|
|
668
|
-
summary?: string;
|
|
669
|
-
url?: string;
|
|
670
|
-
method?: string;
|
|
671
|
-
detail?: Record<string, string | number | boolean>;
|
|
672
|
-
}
|
|
673
|
-
interface IUpdateActionRunConfig_Output {
|
|
674
|
-
timeout?: number;
|
|
675
|
-
}
|
|
676
|
-
type TUpdateActionRunConfig = (input: ITransportRouteActionParams & {
|
|
677
|
-
timeout: number;
|
|
678
|
-
}) => IUpdateActionRunConfig_Output;
|
|
679
|
-
interface IActionTransportReadyData_Base {
|
|
680
|
-
updateRunConfig?: TUpdateActionRunConfig;
|
|
681
|
-
}
|
|
682
|
-
/**
|
|
683
|
-
*
|
|
684
|
-
* TRANSPORT READINESS RESPONSE
|
|
685
|
-
*
|
|
686
|
-
*/
|
|
687
|
-
declare enum ETransportStatus {
|
|
688
|
-
uninitialized = "uninitialized",
|
|
689
|
-
unsupported = "unsupported",
|
|
690
|
-
initializing = "initializing",
|
|
691
|
-
ready = "ready",
|
|
692
|
-
failed = "failed"
|
|
693
|
-
}
|
|
694
|
-
interface ITransportStatusInfo_Base<S extends ETransportStatus> {
|
|
695
|
-
status: S;
|
|
696
|
-
}
|
|
697
|
-
interface ITransportStatusInfo_Failed extends ITransportStatusInfo_Base<ETransportStatus.failed> {
|
|
698
|
-
error: NiceError;
|
|
699
|
-
timeFailed: number;
|
|
700
|
-
}
|
|
701
|
-
interface ITransportStatusInfo_Unsupported extends ITransportStatusInfo_Base<ETransportStatus.unsupported> {}
|
|
702
|
-
interface ITransportStatusInfo_Ready<READY extends IActionTransportReadyData_Base> extends ITransportStatusInfo_Base<ETransportStatus.ready> {
|
|
703
|
-
readyData: READY;
|
|
704
|
-
}
|
|
705
|
-
type TTransportInitializationFinishedInfo<READY extends IActionTransportReadyData_Base> = ITransportStatusInfo_Ready<READY> | ITransportStatusInfo_Failed | ITransportStatusInfo_Unsupported;
|
|
706
|
-
interface ITransportStatusInfo_Initializing<READY extends IActionTransportReadyData_Base> extends ITransportStatusInfo_Base<ETransportStatus.initializing> {
|
|
707
|
-
timeStarted: number;
|
|
708
|
-
initializationPromise: Promise<TTransportInitializationFinishedInfo<READY>>;
|
|
709
|
-
}
|
|
710
|
-
type TTransportStatusInfo<READY extends IActionTransportReadyData_Base> = ITransportStatusInfo_Base<ETransportStatus.uninitialized> | ITransportStatusInfo_Unsupported | ITransportStatusInfo_Initializing<READY> | ITransportStatusInfo_Ready<READY> | ITransportStatusInfo_Failed;
|
|
711
|
-
type TTransportStatusInfo_GetTransport_Output<READY extends IActionTransportReadyData_Base> = ITransportStatusInfo_Base<ETransportStatus.uninitialized> | ITransportStatusInfo_Unsupported | Omit<ITransportStatusInfo_Initializing<READY>, "timeStarted"> | ITransportStatusInfo_Ready<READY> | Omit<ITransportStatusInfo_Failed, "timeFailed">;
|
|
712
|
-
/**
|
|
713
|
-
*
|
|
714
|
-
* TRANSPORT ROUTING
|
|
715
|
-
*
|
|
716
|
-
*/
|
|
717
|
-
interface ITransportRouteClientParams {
|
|
718
|
-
localClient: RuntimeCoordinate;
|
|
719
|
-
externalClient: RuntimeCoordinate;
|
|
720
|
-
}
|
|
721
|
-
interface ITransportRouteActionParams extends ITransportRouteClientParams {
|
|
722
|
-
action: TActionPayload_Any_Instance<any, any>;
|
|
723
|
-
}
|
|
724
|
-
interface ITransportMethod_SendActionData_Input extends ITransportRouteActionParams {
|
|
725
|
-
runningAction: RunningAction<any, any>;
|
|
726
|
-
timeout: number;
|
|
727
|
-
}
|
|
728
|
-
interface ITransportDispatchAction<P> extends ITransportMethod_SendActionData_Input {
|
|
729
|
-
params: P;
|
|
730
|
-
}
|
|
731
|
-
type TSendActionDataMethod = (input: ITransportMethod_SendActionData_Input) => void;
|
|
732
|
-
type TSendReturnDataMethod = (payload: TActionPayload_Any_Instance<any, any>,
|
|
733
|
-
/**
|
|
734
|
-
* The local/external client pair this payload is being returned over. Bidirectional transports use
|
|
735
|
-
* it to build the full route params their outgoing formatter expects (e.g. binary packing). Optional
|
|
736
|
-
* so existing return-data implementations keep type-checking.
|
|
737
|
-
*/
|
|
738
|
-
|
|
739
|
-
clients?: ITransportRouteClientParams) => void;
|
|
740
|
-
interface IActionTransportReadyData_Methods extends IActionTransportReadyData_Base {
|
|
741
|
-
sendActionData: TSendActionDataMethod;
|
|
742
|
-
/**
|
|
743
|
-
* Optional — implement on bidirectional transports (WebSocket, Custom) to enable return-path
|
|
744
|
-
* routing. When present, the runtime uses this to dispatch results and progress payloads directly
|
|
745
|
-
* back to `originClient` without going through the original request transport.
|
|
746
|
-
*/
|
|
747
|
-
sendReturnData?: TSendReturnDataMethod;
|
|
748
|
-
addOnDisconnectListener?: (callback: () => void) => void;
|
|
749
|
-
/**
|
|
750
|
-
* Optional — implement on transports holding a long-lived connection (WebSocket, Custom) to close it
|
|
751
|
-
* deliberately. Called by `ActionExternalClientHandler.clearTransportCache()` so a teardown actually
|
|
752
|
-
* releases the underlying socket instead of leaving it open until GC.
|
|
753
|
-
*/
|
|
754
|
-
disconnect?: () => void;
|
|
755
|
-
}
|
|
756
|
-
interface IActionTransportReady {
|
|
757
|
-
methods: IActionTransportReadyData_Methods;
|
|
758
|
-
transport: TransportConnection;
|
|
759
|
-
}
|
|
760
|
-
type TTransportCache = Map<string, IActionTransportReady | Promise<IActionTransportReady>>;
|
|
761
|
-
type TOnResolveIncomingRequest = (request: ActionPayload_Request<any>) => void;
|
|
762
|
-
type TOnResolveIncomingRequestJson = (request: IActionPayload_Request_JsonObject<any>) => void;
|
|
763
|
-
type TOnResolveIncomingResponse = (response: ActionPayload_Result<any>) => void;
|
|
764
|
-
type TOnResolveIncomingResponseJson = (response: IActionPayload_Result_JsonObject<any>) => void;
|
|
765
|
-
type TOnResolveAnyIncomingActionData = (actionData: ActionPayload_Request<any> | ActionPayload_Result<any>) => void;
|
|
766
|
-
type TOnResolveAnyIncomingActionData_Json = (actionData: TActionPayload_Any_JsonObject<any>) => void;
|
|
767
|
-
interface IActionTransportResolvers {
|
|
768
|
-
onIncomingActionDataJson: TOnResolveAnyIncomingActionData_Json;
|
|
769
|
-
}
|
|
770
|
-
type TGetTransportFn<IN extends ITransportRouteActionParams, READY extends IActionTransportReadyData_Base> = (input: IN) => TTransportStatusInfo_GetTransport_Output<READY>;
|
|
771
|
-
interface IActionTransportInitialized<IN extends ITransportRouteActionParams, READY extends IActionTransportReadyData_Base> {
|
|
772
|
-
getTransportCacheKey?: (input: IN) => string[];
|
|
773
|
-
getTransport: TGetTransportFn<IN, READY>;
|
|
774
|
-
}
|
|
775
|
-
interface IActionTransportDef<TYPE extends ETransportType, INIT extends IActionTransportInitialized<any, any>> {
|
|
776
|
-
type: TYPE;
|
|
777
|
-
initialize: () => INIT;
|
|
778
|
-
}
|
|
779
|
-
//#endregion
|
|
780
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/Transport.d.ts
|
|
781
|
-
/**
|
|
782
|
-
* Context handed to a {@link Transport} definition when a handler builds a live connection from it.
|
|
783
|
-
* Only bidirectional transports (WebSocket / Custom) make use of `resolvers`.
|
|
784
|
-
*/
|
|
785
|
-
interface ITransportConnectionContext {
|
|
786
|
-
resolvers?: IActionTransportResolvers;
|
|
787
|
-
}
|
|
788
|
-
/**
|
|
789
|
-
* Reusable transport definition. Devs construct these (`HttpTransport.create({ createRequest })`,
|
|
790
|
-
* `WebSocketTransport.create({ createWebSocket })`, …) and pass them to an
|
|
791
|
-
* `ActionExternalClientHandler`. A single
|
|
792
|
-
* definition can be shared across multiple handlers — each handler builds its own live
|
|
793
|
-
* {@link TransportConnection} via {@link TransportConnection._createConnection}.
|
|
794
|
-
*/
|
|
795
|
-
declare abstract class Transport<T extends ETransportType = ETransportType> {
|
|
796
|
-
abstract readonly type: T;
|
|
797
|
-
/** Internal: build a fresh, per-handler live connection from this definition. */
|
|
798
|
-
abstract _createConnection(ctx: ITransportConnectionContext): TransportConnection<T>;
|
|
799
|
-
/**
|
|
800
|
-
* Resolve human-readable info about how a specific action would be routed through this transport
|
|
801
|
-
* (e.g. the request URL/method, or the WebSocket endpoint). Surfaced in the action devtools.
|
|
802
|
-
*/
|
|
803
|
-
abstract getRouteInfo(input: ITransportRouteActionParams): ITransportRouteInfo;
|
|
804
|
-
}
|
|
805
|
-
//#endregion
|
|
806
|
-
//#region src/ActionRuntime/Handler/ExternalClient/ActionExternalClientHandler.types.d.ts
|
|
807
|
-
interface IActionExternalClientRequestHandlerConfig {
|
|
808
|
-
defaultTimeout?: number;
|
|
809
|
-
runtimeCoordinate: RuntimeCoordinate;
|
|
810
|
-
transports: Transport[];
|
|
811
|
-
}
|
|
812
|
-
//#endregion
|
|
813
|
-
//#region src/ActionRuntime/Handler/ExternalClient/ActionExternalClientHandler.d.ts
|
|
814
|
-
declare class ActionExternalClientHandler extends ActionHandler<EActionHandlerType.external> implements IActionHandler_ExternalClient {
|
|
815
|
-
readonly externalClient: RuntimeCoordinate;
|
|
816
|
-
readonly handlerType = EActionHandlerType.external;
|
|
817
|
-
readonly cuid: string;
|
|
818
|
-
private _defaultTimeout;
|
|
819
|
-
private _transportCache;
|
|
820
|
-
private transportManager;
|
|
821
|
-
private _incomingActionDataListeners;
|
|
822
|
-
readonly actionRouter: ActionRouter<true>;
|
|
823
|
-
constructor({
|
|
824
|
-
runtimeCoordinate: externalClientSpecifier,
|
|
825
|
-
transports,
|
|
826
|
-
defaultTimeout
|
|
827
|
-
}: IActionExternalClientRequestHandlerConfig);
|
|
828
|
-
forDomain<FOR_DOM extends IActionDomain>(domain: ActionDomain<FOR_DOM>): this;
|
|
829
|
-
forAction<ACT_DOM extends IActionDomain, ID extends keyof ACT_DOM["actionSchema"] & string>(action: ActionCore<ACT_DOM, ID>): this;
|
|
830
|
-
forActionIds<ACT_DOM extends IActionDomain, IDS extends ReadonlyArray<keyof ACT_DOM["actionSchema"] & string>>(domain: ActionDomain<ACT_DOM>, ids: IDS): this;
|
|
831
|
-
_setIncomingActionDataListener(listener: (json: TActionPayload_Any_JsonObject<any, any>) => void): void;
|
|
832
|
-
handleActionRequest<DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string>(action: ActionPayload_Request<DOM, ID>, config?: IHandleActionOptions): Promise<RunningAction<DOM, ID>>;
|
|
833
|
-
private _dispatchWhenTransportReady;
|
|
834
|
-
/**
|
|
835
|
-
* Dispatch a result or progress payload directly back to the external client via the best
|
|
836
|
-
* available bidirectional transport (WebSocket / Custom). Used for return-path routing when the
|
|
837
|
-
* local runtime recognises that it has a direct channel to the action's originClient.
|
|
838
|
-
*
|
|
839
|
-
* Returns `true` if the payload was sent, `false` if no suitable transport was available.
|
|
840
|
-
*/
|
|
841
|
-
sendReturnPayload(payload: TActionPayload_Any_Instance<any, any>, config: {
|
|
842
|
-
targetLocalRuntime: ActionRuntime;
|
|
843
|
-
}): Promise<boolean>;
|
|
844
|
-
toJsonObject(): IActionHandler_ExternalClient_Json;
|
|
845
|
-
toHandlerRouteItem(transport: TransportConnection, input: ITransportRouteActionParams): IActionRouteItemHandler;
|
|
846
|
-
clearTransportCache(): void;
|
|
847
|
-
}
|
|
848
|
-
declare const createExternalClientHandler: (config: IActionExternalClientRequestHandlerConfig) => ActionExternalClientHandler;
|
|
849
|
-
//#endregion
|
|
850
660
|
//#region src/utils/typescript/MaybePromise.d.ts
|
|
851
661
|
type MaybePromise<T> = T | Promise<T>;
|
|
852
662
|
//#endregion
|
|
@@ -898,6 +708,54 @@ declare class ActionLocalHandler extends ActionHandler<EActionHandlerType.local>
|
|
|
898
708
|
}
|
|
899
709
|
declare const createLocalHandler: () => ActionLocalHandler;
|
|
900
710
|
//#endregion
|
|
711
|
+
//#region src/ActionRuntime/Handler/PeerLink/PeerLinkHandler.d.ts
|
|
712
|
+
/**
|
|
713
|
+
* Shared base for every handler that routes a domain set to/from *another runtime* (a "peer") — the
|
|
714
|
+
* unified peer-link concept. Both specializations extend this as siblings, differing only in *who
|
|
715
|
+
* establishes the connection*, which is a transport trait, not a routing one:
|
|
716
|
+
*
|
|
717
|
+
* - {@link ConnectorHandler} — **dial-out**: this runtime opens connection(s) to one peer
|
|
718
|
+
* over a transport stack (with caching + fallback). The classic "client → backend" link.
|
|
719
|
+
* - {@link AcceptorHandler} — **accept-in**: connections are accepted from many peers and fed in
|
|
720
|
+
* via `receive()`; it keeps a per-connection registry and can push to any of them.
|
|
721
|
+
*
|
|
722
|
+
* To the runtime there is no "client" vs "server" — both are peer-link handlers (`handlerType =
|
|
723
|
+
* external`) keyed to a peer coordinate, chosen by the return-path dispatch via {@link sendReturnPayload}.
|
|
724
|
+
*/
|
|
725
|
+
declare abstract class PeerLinkHandler extends ActionHandler<EActionHandlerType.peer> implements IActionHandler_Peer {
|
|
726
|
+
/** The peer runtime this handler links to (an env-only coordinate for an accept-in handler). */
|
|
727
|
+
readonly peerClient: RuntimeCoordinate;
|
|
728
|
+
readonly handlerType = EActionHandlerType.peer;
|
|
729
|
+
/**
|
|
730
|
+
* Whether this link can deliver an *unsolicited* frame to the peer (a result/progress pushed back on
|
|
731
|
+
* the return path, or a `broadcast`). A duplex carrier (WebSocket/WebRTC/…) can; an exchange-only
|
|
732
|
+
* carrier (HTTP) cannot — its reply must ride the response to its own request. The runtime's
|
|
733
|
+
* return-path dispatch ({@link ActionRuntime.getReturnHandlerForOrigin}) skips handlers that can't
|
|
734
|
+
* push, so an exchange-only handler is never asked to deliver one.
|
|
735
|
+
*/
|
|
736
|
+
abstract readonly canPush: boolean;
|
|
737
|
+
readonly actionRouter: ActionRouter<true>;
|
|
738
|
+
/** Listeners installed by the runtime (`resolveIncomingActionPayload`) for inbound peer frames. */
|
|
739
|
+
private readonly _incomingActionDataListeners;
|
|
740
|
+
constructor(peerCoordinate: RuntimeCoordinate);
|
|
741
|
+
forDomain<FOR_DOM extends IActionDomain>(domain: ActionDomain<FOR_DOM>): this;
|
|
742
|
+
forAction<ACT_DOM extends IActionDomain, ID extends keyof ACT_DOM["actionSchema"] & string>(action: ActionCore<ACT_DOM, ID>): this;
|
|
743
|
+
forActionIds<ACT_DOM extends IActionDomain, IDS extends ReadonlyArray<keyof ACT_DOM["actionSchema"] & string>>(domain: ActionDomain<ACT_DOM>, ids: IDS): this;
|
|
744
|
+
_setIncomingActionDataListener(listener: (json: TActionPayload_Any_JsonObject<any, any>) => void): void;
|
|
745
|
+
/** Hand a decoded inbound frame to the runtime (called by each specialization's receive path). */
|
|
746
|
+
protected _emitIncoming(json: TActionPayload_Any_JsonObject<any, any>): void;
|
|
747
|
+
/**
|
|
748
|
+
* Dispatch a result/progress payload back to the action's origin peer over this link. The runtime's
|
|
749
|
+
* return-path dispatch calls it on whichever peer-link handler best reaches `originClient`. Returns
|
|
750
|
+
* `true` if it was sent, `false` if no channel was available.
|
|
751
|
+
*/
|
|
752
|
+
abstract sendReturnPayload(payload: TActionPayload_Any_Instance<any, any>, config: {
|
|
753
|
+
targetLocalRuntime: ActionRuntime;
|
|
754
|
+
}): Promise<boolean>;
|
|
755
|
+
/** Release any long-lived connections this handler owns (a teardown). No-op by default. */
|
|
756
|
+
clearTransportCache(): void;
|
|
757
|
+
}
|
|
758
|
+
//#endregion
|
|
901
759
|
//#region src/ActionRuntime/ActionRuntime.types.d.ts
|
|
902
760
|
interface IRuntimeMeta {
|
|
903
761
|
assumed: boolean;
|
|
@@ -906,378 +764,9 @@ interface IRuntimeMeta {
|
|
|
906
764
|
interface IActionRuntimeManagerContext {
|
|
907
765
|
domain?: string;
|
|
908
766
|
}
|
|
909
|
-
type TActionRuntimeHandler = ActionLocalHandler |
|
|
767
|
+
type TActionRuntimeHandler = ActionLocalHandler | PeerLinkHandler;
|
|
910
768
|
//#endregion
|
|
911
|
-
//#region src/ActionRuntime/
|
|
912
|
-
declare class ActionRuntime {
|
|
913
|
-
private _coordinate;
|
|
914
|
-
readonly timeCreated: number;
|
|
915
|
-
readonly runtimeInfo: IRuntimeMeta;
|
|
916
|
-
private readonly actionRouter;
|
|
917
|
-
private readonly _pendingRunningActions;
|
|
918
|
-
private readonly _registeredExternalHandlers;
|
|
919
|
-
private _applied;
|
|
920
|
-
static getDefault(): ActionRuntime;
|
|
921
|
-
constructor(coordinate: RuntimeCoordinate);
|
|
922
|
-
get coordinate(): RuntimeCoordinate;
|
|
923
|
-
specifyRuntimeCoordinate(specifics: IRuntimeCoordinateSpecifics & {
|
|
924
|
-
envId?: string;
|
|
925
|
-
}): void;
|
|
926
|
-
registerRunningAction(ra: RunningAction<any, any>): void;
|
|
927
|
-
resolveIncomingActionPayload(json: TActionPayload_Any_JsonObject<any, any>): void;
|
|
928
|
-
/**
|
|
929
|
-
* Handle an incoming action wire (e.g. from a transport layer), route it to
|
|
930
|
-
* the correct handler, and return the response. The most specific handler
|
|
931
|
-
* match is chosen (action-ID-specific beats domain-wildcard).
|
|
932
|
-
*/
|
|
933
|
-
handleActionPayloadWire<D extends IActionDomain, ID extends keyof D["actionSchema"] & string>(wire: TActionPayload_Any_JsonObject<D, ID>): Promise<RunningAction<D, ID>>;
|
|
934
|
-
handleActionPayloadWire(wire: unknown): Promise<RunningAction<any, any>>;
|
|
935
|
-
handleActionPayload<DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string>(action: TActionPayload_Any_Instance<DOM, ID>, options?: Omit<IHandleActionOptions, "targetLocalRuntime">): Promise<RunningAction<DOM, ID>>;
|
|
936
|
-
/**
|
|
937
|
-
* @internal
|
|
938
|
-
*
|
|
939
|
-
* Return the first handler registered for the given action, or `undefined`
|
|
940
|
-
* if none has been registered (action-ID-specific beats domain-wildcard).
|
|
941
|
-
*/
|
|
942
|
-
_getHandlerForAction<ACT extends TActionPayload_Any_Instance<any, any>>(action: ACT, options?: Omit<IHandleActionOptions, "targetLocalRuntime">): TActionHandler | undefined;
|
|
943
|
-
getHandlerForActionOrThrow<ACT extends TActionPayload_Any_Instance<any, any>>(action: ACT, options?: Omit<IHandleActionOptions, "localRuntime">): TActionHandler;
|
|
944
|
-
/**
|
|
945
|
-
* Register one or more handlers. Each handler's own `actionRouter` defines
|
|
946
|
-
* which domains/actions it handles — those routing keys are mirrored into
|
|
947
|
-
* this runtime's router so the same action can be served by multiple handlers.
|
|
948
|
-
* Duplicate registrations (same handler cuid for the same key) are skipped.
|
|
949
|
-
*/
|
|
950
|
-
addHandlers(handlers: TActionRuntimeHandler[]): this;
|
|
951
|
-
/**
|
|
952
|
-
* Declare an external "backend client" in one call: build an
|
|
953
|
-
* {@link ActionExternalClientHandler} for `externalCoordinate` carrying the given
|
|
954
|
-
* `transports`, route the listed `domains`/`actions` to it, register it (plus any
|
|
955
|
-
* `localHandlers` — e.g. server→client push handlers that share the same channel)
|
|
956
|
-
* on this runtime, and `apply()`. Returns the external handler so the caller can
|
|
957
|
-
* later `clearTransportCache()` it.
|
|
958
|
-
*
|
|
959
|
-
* Sugar over `new ActionExternalClientHandler(...).forDomain(...)` + `addHandlers([...])`,
|
|
960
|
-
* so a single runtime can host one handler per backend target with its transports
|
|
961
|
-
* declared once and reused across every action routed to that backend.
|
|
962
|
-
*/
|
|
963
|
-
connectTo(externalCoordinate: RuntimeCoordinate, options: {
|
|
964
|
-
transports: Transport[];
|
|
965
|
-
domains?: ActionDomain<any>[];
|
|
966
|
-
actions?: ActionCore<any, any>[];
|
|
967
|
-
localHandlers?: TActionRuntimeHandler[];
|
|
968
|
-
defaultTimeout?: number;
|
|
969
|
-
}): ActionExternalClientHandler;
|
|
970
|
-
private applyRuntimeForDomain;
|
|
971
|
-
/**
|
|
972
|
-
* Register this runtime with all root domains covered by its currently-added handlers,
|
|
973
|
-
* making it eligible to execute actions dispatched from those domains.
|
|
974
|
-
* After apply() is called, any subsequent addHandlers() calls also auto-register.
|
|
975
|
-
*/
|
|
976
|
-
apply(): this;
|
|
977
|
-
/**
|
|
978
|
-
* Find the best registered external handler that can reach `originClient` directly.
|
|
979
|
-
* Used to locate the return-path channel for dispatching results back to the action origin.
|
|
980
|
-
* Returns `undefined` if no handler matches (score > 0 required, i.e. at least id must match).
|
|
981
|
-
*/
|
|
982
|
-
getReturnHandlerForOrigin(originClient: RuntimeCoordinate): ActionExternalClientHandler | undefined;
|
|
983
|
-
resetRuntime(): void;
|
|
984
|
-
private _trySetupReturnDispatch;
|
|
985
|
-
}
|
|
986
|
-
//#endregion
|
|
987
|
-
//#region src/ActionDefinition/Domain/ActionDomainBase.d.ts
|
|
988
|
-
declare abstract class ActionDomainBase<ACT_DOM extends IActionDomain = IActionDomain> implements IActionDomain<ACT_DOM["allDomains"], ACT_DOM["actionSchema"]> {
|
|
989
|
-
readonly domain: ACT_DOM["domain"];
|
|
990
|
-
readonly allDomains: ACT_DOM["allDomains"];
|
|
991
|
-
readonly actionSchema: ACT_DOM["actionSchema"];
|
|
992
|
-
protected _listeners: TRunningActionUpdateListener<any, any>[];
|
|
993
|
-
constructor(definition: ACT_DOM);
|
|
994
|
-
/**
|
|
995
|
-
* Add an observer that is called after every action dispatched through this domain.
|
|
996
|
-
* Returns an unsubscribe function — call it to remove the listener.
|
|
997
|
-
*/
|
|
998
|
-
addActionListener(listener: TDistributeRunningActionUpdateListener<ACT_DOM, keyof ACT_DOM["actionSchema"] & string>): () => void;
|
|
999
|
-
/**
|
|
1000
|
-
* @internal
|
|
1001
|
-
* Observers registered directly on this domain via {@link addActionListener}.
|
|
1002
|
-
* Used to wire observers (e.g. devtools) onto RunningActions that aren't created
|
|
1003
|
-
* through the local-dispatch path — notably inbound actions pushed from a backend
|
|
1004
|
-
* or another client over a bidirectional transport.
|
|
1005
|
-
*/
|
|
1006
|
-
_getActionObservers(): TRunningActionUpdateListener<any, any>[];
|
|
1007
|
-
}
|
|
1008
|
-
//#endregion
|
|
1009
|
-
//#region src/ActionDefinition/Domain/ActionRootDomain.d.ts
|
|
1010
|
-
declare class ActionRootDomain<ROOT_DOM extends IActionRootDomain = IActionRootDomain> extends ActionDomainBase<ROOT_DOM> {
|
|
1011
|
-
readonly domainDefinition: {
|
|
1012
|
-
domain: ROOT_DOM["domain"];
|
|
1013
|
-
};
|
|
1014
|
-
private _actionRuntimeManager;
|
|
1015
|
-
constructor(domainDefinition: {
|
|
1016
|
-
domain: ROOT_DOM["domain"];
|
|
1017
|
-
});
|
|
1018
|
-
createChildDomain<SUB_DOM extends IActionDomainChildOptions>(subDomainDef: SUB_DOM & { [K in Exclude<keyof SUB_DOM, keyof IActionDomainChildOptions>]: never }): ActionDomain<TActionDomainChildDef<ROOT_DOM, SUB_DOM>>;
|
|
1019
|
-
_registerRuntime(runtime: ActionRuntime): void;
|
|
1020
|
-
_hasRuntime(runtime: ActionRuntime): boolean;
|
|
1021
|
-
getRuntime(clientSpecifier: IRuntimeCoordinate): ActionRuntime | undefined;
|
|
1022
|
-
_runAction<DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string = keyof DOM["actionSchema"] & string, ACT extends ActionPayload_Request<DOM, ID> = ActionPayload_Request<DOM, ID>>(actionPayload: ACT, options?: IExecuteActionOptions<DOM, ID>): Promise<RunningAction<DOM, ID>>;
|
|
1023
|
-
}
|
|
1024
|
-
//#endregion
|
|
1025
|
-
//#region src/ActionDefinition/Domain/ActionDomain.d.ts
|
|
1026
|
-
type TActionMap<ACT_DOM extends IActionDomain> = { [K in keyof ACT_DOM["actionSchema"] & string]: ActionCore<ACT_DOM, K> };
|
|
1027
|
-
declare class ActionDomain<ACT_DOM extends IActionDomain = IActionDomain> extends ActionDomainBase<ACT_DOM> {
|
|
1028
|
-
private _rootDomain;
|
|
1029
|
-
private readonly _actionMap;
|
|
1030
|
-
constructor(definition: ACT_DOM, {
|
|
1031
|
-
rootDomain
|
|
1032
|
-
}: {
|
|
1033
|
-
rootDomain: ActionRootDomain<any>;
|
|
1034
|
-
});
|
|
1035
|
-
get rootDomain(): ActionRootDomain<any>;
|
|
1036
|
-
/**
|
|
1037
|
-
* @internal
|
|
1038
|
-
* All action observers that should see actions on this domain: the root domain's
|
|
1039
|
-
* observers plus this subdomain's own. Mirrors the listener set the local-dispatch
|
|
1040
|
-
* path assembles in `runAction`/`_runAction`, so inbound actions (pushed from a
|
|
1041
|
-
* backend or another client) can be wired up identically and surface in devtools.
|
|
1042
|
-
*/
|
|
1043
|
-
_collectActionObservers(): TRunningActionUpdateListener<any, any>[];
|
|
1044
|
-
_registerRuntime(runtime: ActionRuntime): void;
|
|
1045
|
-
createChildDomain<SUB_DOM extends IActionDomainChildOptions>(subDomainDef: SUB_DOM & { [K in Exclude<keyof SUB_DOM, keyof IActionDomainChildOptions>]: never }): ActionDomain<TActionDomainChildDef<ACT_DOM, SUB_DOM>>;
|
|
1046
|
-
get action(): TActionMap<ACT_DOM>;
|
|
1047
|
-
actionsMap(): TActionMap<ACT_DOM>;
|
|
1048
|
-
actionForId<ID extends keyof ACT_DOM["actionSchema"] & string>(id: ID): ActionCore<ACT_DOM, ID>;
|
|
1049
|
-
wrapAsPartialLocalHandler(wrappedActionExecutor: Partial<TWrappableDomainActionHandler<ACT_DOM>>): ActionLocalHandler;
|
|
1050
|
-
wrapAsLocalHandler(wrappedActionExecutor: TWrappableDomainActionHandler<ACT_DOM>): ActionLocalHandler;
|
|
1051
|
-
hydrateContext<ID extends keyof ACT_DOM["actionSchema"] & string>(id: ID, contextData: IActionContext_Data_JsonObject): ActionContext<ACT_DOM, ID>;
|
|
1052
|
-
isDomainAction<ACT extends IActionBase<any, ACT_DOM, any>>(action: ACT | unknown | null | undefined): action is TDistributedDomainActions<ACT_DOM, ACT>;
|
|
1053
|
-
hydrateRequestPayload<ID extends keyof ACT_DOM["actionSchema"] & string, P extends IActionPayload_Request_JsonObject<ACT_DOM, ID>>(serialized: P): TDistributeActionPayload_Request<ACT_DOM, ID>;
|
|
1054
|
-
hydrateResultPayload<ID extends keyof ACT_DOM["actionSchema"] & string, R extends IActionPayload_Result_JsonObject<ACT_DOM, ID>>(serialized: R): TDistributeActionPayload_Result<ACT_DOM, ID>;
|
|
1055
|
-
hydrateAnyAction<ID extends keyof ACT_DOM["actionSchema"] & string, AJ extends TAction_Any_JsonObject<ACT_DOM, ID>>(actionJson: AJ): TNarrowActionJsonTypeToActionInstanceType<ACT_DOM, AJ, ID>;
|
|
1056
|
-
runAction<ID extends keyof ACT_DOM["actionSchema"] & string, ACT extends ActionPayload_Request<ACT_DOM, ID>>(request: ACT, options?: IExecuteActionOptions<ACT_DOM, ID>): Promise<RunningAction<ACT_DOM, ID>>;
|
|
1057
|
-
private createActionMap;
|
|
1058
|
-
}
|
|
1059
|
-
//#endregion
|
|
1060
|
-
//#region src/ActionDefinition/Action/Core/ActionCore.d.ts
|
|
1061
|
-
declare class ActionCore<DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string = keyof DOM["actionSchema"] & string> extends ActionBase<EActionForm.core, DOM, ID> implements IActionCore<DOM, ID> {
|
|
1062
|
-
readonly _domain: ActionDomain<DOM>;
|
|
1063
|
-
readonly form = EActionForm.core;
|
|
1064
|
-
constructor(_domain: ActionDomain<DOM>, id: ID);
|
|
1065
|
-
is<ACT extends IActionBase<any, any, any>>(action: ACT | unknown | null | undefined): action is TNarrowActionType<DOM, ACT, ID>;
|
|
1066
|
-
toJsonObject(): IActionBase_JsonObject<EActionForm.core, DOM, ID>;
|
|
1067
|
-
request(...args: [TInferInputFromSchema<DOM["actionSchema"][ID]>["Input"]] extends [never] ? [input?: never] : [input: TInferInputFromSchema<DOM["actionSchema"][ID]>["Input"]]): ActionPayload_Request<DOM, ID>;
|
|
1068
|
-
deserializeInput(serialized: TInferInputFromSchema<DOM["actionSchema"][ID]>["SerdeInput"]): TInferInputFromSchema<DOM["actionSchema"][ID]>["Input"];
|
|
1069
|
-
serializeInput(raw: TInferInputFromSchema<DOM["actionSchema"][ID]>["Input"]): TInferInputFromSchema<DOM["actionSchema"][ID]>["SerdeInput"];
|
|
1070
|
-
validateInput(input: unknown): TInferInputFromSchema<DOM["actionSchema"][ID]>["Input"];
|
|
1071
|
-
validateOutput(output: unknown): TInferOutputFromSchema<DOM["actionSchema"][ID]>["Output"];
|
|
1072
|
-
}
|
|
1073
|
-
//#endregion
|
|
1074
|
-
//#region src/ActionDefinition/Domain/helpers/createRootActionDomain.d.ts
|
|
1075
|
-
declare const createActionRootDomain: <ID extends string>(definition: {
|
|
1076
|
-
domain: ID;
|
|
1077
|
-
}) => ActionRootDomain<IActionRootDomain<ID>>;
|
|
1078
|
-
//#endregion
|
|
1079
|
-
//#region src/ActionRuntime/Handler/ExternalClient/err_nice_external_client.d.ts
|
|
1080
|
-
declare const err_nice_external_client: import("@nice-code/error").NiceErrorDomain<{
|
|
1081
|
-
domain: string;
|
|
1082
|
-
allDomains: [string, string, "err_nice"];
|
|
1083
|
-
schema: {};
|
|
1084
|
-
}>;
|
|
1085
|
-
//#endregion
|
|
1086
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/Custom/TransportCustom.types.d.ts
|
|
1087
|
-
interface IActionTransportReadyData_Custom extends IActionTransportReadyData_Base {
|
|
1088
|
-
sendActionData: (input: ITransportMethod_SendActionData_Input) => void;
|
|
1089
|
-
sendReturnData?: TSendReturnDataMethod;
|
|
1090
|
-
closeTransport: (input?: ITransportRouteActionParams) => void;
|
|
1091
|
-
}
|
|
1092
|
-
interface IActionTransportInitialized_Custom extends IActionTransportInitialized<ITransportRouteActionParams, IActionTransportReadyData_Custom> {}
|
|
1093
|
-
interface IActionTransportDef_Custom extends IActionTransportDef<ETransportType.custom, IActionTransportInitialized_Custom> {}
|
|
1094
|
-
type TActionTransportDef_Custom_NoType = Omit<IActionTransportDef_Custom, "type">;
|
|
1095
|
-
//#endregion
|
|
1096
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/Custom/CustomConnection.d.ts
|
|
1097
|
-
declare class CustomConnection extends TransportConnection<ETransportType.custom, ITransportRouteActionParams, IActionTransportReadyData_Custom, IActionTransportInitialized_Custom, IActionTransportDef_Custom> {
|
|
1098
|
-
constructor(def: TActionTransportDef_Custom_NoType);
|
|
1099
|
-
protected _finalizeTransportMethods(inputs: IActionTransportReadyData_Custom): IActionTransportReadyData_Methods;
|
|
1100
|
-
}
|
|
1101
|
-
//#endregion
|
|
1102
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/Custom/CustomTransport.d.ts
|
|
1103
|
-
interface ICustomTransportSharedOptions {
|
|
1104
|
-
updateRunConfig?: TUpdateActionRunConfig;
|
|
1105
|
-
getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
1106
|
-
/** Short label shown in the devtools chip (defaults to "custom"). */
|
|
1107
|
-
label?: string;
|
|
1108
|
-
/** Override the devtools route info for a specific action. */
|
|
1109
|
-
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
1110
|
-
}
|
|
1111
|
-
interface ICustomTransportSendOptions extends ICustomTransportSharedOptions {
|
|
1112
|
-
/** Send a request/progress payload to the external client. */
|
|
1113
|
-
sendActionData: (input: ITransportMethod_SendActionData_Input) => void;
|
|
1114
|
-
/** Optional return-path dispatch for bidirectional channels. */
|
|
1115
|
-
sendReturnData?: TSendReturnDataMethod;
|
|
1116
|
-
closeTransport?: (input?: ITransportRouteActionParams) => void;
|
|
1117
|
-
}
|
|
1118
|
-
interface ICustomTransportAdvancedOptions extends ICustomTransportSharedOptions {
|
|
1119
|
-
/** Full control over readiness/initialization for the custom channel. */
|
|
1120
|
-
getTransport: IActionTransportInitialized_Custom["getTransport"];
|
|
1121
|
-
}
|
|
1122
|
-
type TCustomTransportOptions = (ICustomTransportSendOptions & {
|
|
1123
|
-
mode: "send";
|
|
1124
|
-
}) | (ICustomTransportAdvancedOptions & {
|
|
1125
|
-
mode: "advanced";
|
|
1126
|
-
});
|
|
1127
|
-
/**
|
|
1128
|
-
* Reusable custom transport definition for channels nice-action doesn't model natively. Create one
|
|
1129
|
-
* with `CustomTransport.create({ sendActionData })` for the simple case, or
|
|
1130
|
-
* `CustomTransport.createAdvanced({ getTransport })` for full control over the lifecycle.
|
|
1131
|
-
*/
|
|
1132
|
-
declare class CustomTransport extends Transport<ETransportType.custom> {
|
|
1133
|
-
private readonly options;
|
|
1134
|
-
readonly type = ETransportType.custom;
|
|
1135
|
-
constructor(options: TCustomTransportOptions);
|
|
1136
|
-
static create(options: ICustomTransportSendOptions): CustomTransport;
|
|
1137
|
-
static createAdvanced(options: ICustomTransportAdvancedOptions): CustomTransport;
|
|
1138
|
-
_createConnection(_ctx: ITransportConnectionContext): CustomConnection;
|
|
1139
|
-
getRouteInfo(input: ITransportRouteActionParams): ITransportRouteInfo;
|
|
1140
|
-
}
|
|
1141
|
-
//#endregion
|
|
1142
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/err_nice_transport.d.ts
|
|
1143
|
-
declare enum EErrId_NiceTransport {
|
|
1144
|
-
timeout = "timeout",
|
|
1145
|
-
not_found = "not_found",
|
|
1146
|
-
unsupported = "unsupported",
|
|
1147
|
-
initialization_failed = "initialization_failed",
|
|
1148
|
-
send_failed = "send_failed",
|
|
1149
|
-
invalid_action_response = "invalid_action_response"
|
|
1150
|
-
}
|
|
1151
|
-
declare const err_nice_transport: import("@nice-code/error").NiceErrorDomain<{
|
|
1152
|
-
domain: string;
|
|
1153
|
-
allDomains: [string, string, string, "err_nice"];
|
|
1154
|
-
schema: {
|
|
1155
|
-
timeout: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
1156
|
-
timeout: number;
|
|
1157
|
-
}, import("@nice-code/error").JSONSerializableValue>;
|
|
1158
|
-
not_found: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
1159
|
-
actionId: string;
|
|
1160
|
-
}, import("@nice-code/error").JSONSerializableValue>;
|
|
1161
|
-
unsupported: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
1162
|
-
transportTypes: ETransportType[];
|
|
1163
|
-
}, import("@nice-code/error").JSONSerializableValue>;
|
|
1164
|
-
initialization_failed: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
1165
|
-
actionId: string;
|
|
1166
|
-
}, import("@nice-code/error").JSONSerializableValue>;
|
|
1167
|
-
send_failed: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
1168
|
-
actionState: string;
|
|
1169
|
-
actionId: string;
|
|
1170
|
-
httpStatusCode?: number;
|
|
1171
|
-
message?: string;
|
|
1172
|
-
}, import("@nice-code/error").JSONSerializableValue>;
|
|
1173
|
-
invalid_action_response: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
1174
|
-
actionId: string;
|
|
1175
|
-
}, import("@nice-code/error").JSONSerializableValue>;
|
|
1176
|
-
};
|
|
1177
|
-
}>;
|
|
1178
|
-
//#endregion
|
|
1179
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/err_nice_transport_ws.d.ts
|
|
1180
|
-
declare enum EErrId_NiceTransport_WebSocket {
|
|
1181
|
-
ws_disconnected = "ws_disconnected",
|
|
1182
|
-
ws_create_failed = "ws_create_failed",
|
|
1183
|
-
ws_error = "ws_error"
|
|
1184
|
-
}
|
|
1185
|
-
declare const err_nice_transport_ws: import("@nice-code/error").NiceErrorDomain<{
|
|
1186
|
-
domain: string;
|
|
1187
|
-
allDomains: [string, string, string, string, "err_nice"];
|
|
1188
|
-
schema: {
|
|
1189
|
-
ws_disconnected: import("@nice-code/error").INiceErrorIdMetadata<Record<string, never>, import("@nice-code/error").JSONSerializableValue>;
|
|
1190
|
-
ws_create_failed: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
1191
|
-
originalError?: Error;
|
|
1192
|
-
}, import("@nice-code/error").JSONSerializableValue>;
|
|
1193
|
-
ws_error: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
1194
|
-
originalError?: Error;
|
|
1195
|
-
}, import("@nice-code/error").JSONSerializableValue>;
|
|
1196
|
-
};
|
|
1197
|
-
}>;
|
|
1198
|
-
//#endregion
|
|
1199
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/Http/TransportHttp.types.d.ts
|
|
1200
|
-
interface IHttpRequestParams {
|
|
1201
|
-
url: string;
|
|
1202
|
-
headers?: Record<string, string>;
|
|
1203
|
-
body?: string;
|
|
1204
|
-
}
|
|
1205
|
-
interface IActionTransportReadyParams_Http {
|
|
1206
|
-
request: IHttpRequestParams;
|
|
1207
|
-
}
|
|
1208
|
-
interface IActionTransportReadyData_Http extends IActionTransportReadyData_Base {
|
|
1209
|
-
createRequest: (input: ITransportRouteActionParams) => IHttpRequestParams;
|
|
1210
|
-
}
|
|
1211
|
-
interface IActionTransportInitialized_Http extends IActionTransportInitialized<ITransportRouteActionParams, IActionTransportReadyData_Http> {}
|
|
1212
|
-
interface IActionTransportDef_Http extends IActionTransportDef<ETransportType.http, IActionTransportInitialized_Http> {}
|
|
1213
|
-
//#endregion
|
|
1214
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/Http/HttpConnection.d.ts
|
|
1215
|
-
declare class HttpConnection extends TransportConnection<ETransportType.http, ITransportRouteActionParams, IActionTransportReadyData_Http, IActionTransportInitialized_Http, IActionTransportDef_Http> {
|
|
1216
|
-
constructor(def: Omit<IActionTransportDef_Http, "type">);
|
|
1217
|
-
_finalizeTransportMethods(methods: IActionTransportReadyData_Http): IActionTransportReadyData_Methods;
|
|
1218
|
-
protected send(input: ITransportDispatchAction<IActionTransportReadyParams_Http>): Promise<void>;
|
|
1219
|
-
}
|
|
1220
|
-
//#endregion
|
|
1221
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/Http/HttpTransport.d.ts
|
|
1222
|
-
interface IHttpTransportOptions {
|
|
1223
|
-
/**
|
|
1224
|
-
* Build the HTTP request for an action. Return a static request for the simple case, or derive the
|
|
1225
|
-
* url / headers / body from the action params for full control.
|
|
1226
|
-
*/
|
|
1227
|
-
createRequest: (input: ITransportRouteActionParams) => IHttpRequestParams;
|
|
1228
|
-
updateRunConfig?: TUpdateActionRunConfig;
|
|
1229
|
-
getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
1230
|
-
}
|
|
1231
|
-
/**
|
|
1232
|
-
* Reusable HTTP transport definition. Create one with `HttpTransport.create({ createRequest })` — the
|
|
1233
|
-
* single `createRequest` function lets you keep it simple (`() => ({ url })`) or derive the request
|
|
1234
|
-
* per action.
|
|
1235
|
-
*/
|
|
1236
|
-
declare class HttpTransport extends Transport<ETransportType.http> {
|
|
1237
|
-
private readonly options;
|
|
1238
|
-
readonly type = ETransportType.http;
|
|
1239
|
-
constructor(options: IHttpTransportOptions);
|
|
1240
|
-
static create(options: IHttpTransportOptions): HttpTransport;
|
|
1241
|
-
_createConnection(_ctx: ITransportConnectionContext): HttpConnection;
|
|
1242
|
-
getRouteInfo(input: ITransportRouteActionParams): ITransportRouteInfo;
|
|
1243
|
-
}
|
|
1244
|
-
//#endregion
|
|
1245
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/actionFrameCrypto.d.ts
|
|
1246
|
-
/**
|
|
1247
|
-
* Async AES-GCM transform for the `encrypted` security level. It wraps the opaque binary frame a
|
|
1248
|
-
* session codec produces (it does NOT look inside it), encrypting on the way out and decrypting on the
|
|
1249
|
-
* way in with the shared key established by the handshake.
|
|
1250
|
-
*
|
|
1251
|
-
* It is deliberately separate from the (synchronous) session `formatMessage`: WebCrypto is always
|
|
1252
|
-
* Promise-based, so encryption has to happen at the transport's async I/O boundary — the connection
|
|
1253
|
-
* encrypts after `session.outgoing()` and decrypts before `session.incoming()`. The `authenticated`
|
|
1254
|
-
* and `none` levels use no crypto transform at all (frames go out as the session produced them).
|
|
1255
|
-
*
|
|
1256
|
-
* Wire shape of an encrypted frame: `pack([nonceBytes, ciphertextBytes])` — msgpack carries the two
|
|
1257
|
-
* binary fields with a couple of bytes of overhead, no base64 inflation.
|
|
1258
|
-
*/
|
|
1259
|
-
interface IActionFrameCrypto {
|
|
1260
|
-
/** Encrypt one session frame for sending. */
|
|
1261
|
-
encryptFrame(frame: Uint8Array): Promise<Uint8Array>;
|
|
1262
|
-
/** Decrypt one received frame back to the session frame. Throws on a non-binary / malformed /
|
|
1263
|
-
* tampered frame — the caller (transport) decides how to react (drop / close). */
|
|
1264
|
-
decryptFrame(frame: string | ArrayBuffer | Uint8Array): Promise<Uint8Array>;
|
|
1265
|
-
}
|
|
1266
|
-
interface IActionFrameCryptoConfig {
|
|
1267
|
-
link: ClientCryptoKeyLink;
|
|
1268
|
-
/** The handshake-established link id for the remote (key + connection-registry id). */
|
|
1269
|
-
linkedClientId: TTypeAndId;
|
|
1270
|
-
}
|
|
1271
|
-
/**
|
|
1272
|
-
* Build the encrypt/decrypt transform for a connection whose handshake settled on the `encrypted`
|
|
1273
|
-
* level. Keyed by the link + `linkedClientId`, so it reuses the cached shared AES-GCM key.
|
|
1274
|
-
*/
|
|
1275
|
-
declare function createActionFrameCrypto({
|
|
1276
|
-
link,
|
|
1277
|
-
linkedClientId
|
|
1278
|
-
}: IActionFrameCryptoConfig): IActionFrameCrypto;
|
|
1279
|
-
//#endregion
|
|
1280
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/actionWsHandshake.d.ts
|
|
769
|
+
//#region src/ActionRuntime/Transport/crypto/actionHandshake.d.ts
|
|
1281
770
|
/** How much the channel protects after the handshake — chosen by the consumer (perf vs security). */
|
|
1282
771
|
declare enum ESecurityLevel {
|
|
1283
772
|
/** No handshake; identity is self-asserted (fastest, dev / trusted networks). */
|
|
@@ -1455,313 +944,480 @@ interface IServerHandshakeConfig {
|
|
|
1455
944
|
/** Trust decision for a client's verify key. Defaults to in-memory TOFU. */
|
|
1456
945
|
verifyKeyResolver?: IClientVerifyKeyResolver;
|
|
1457
946
|
}
|
|
1458
|
-
declare function createServerHandshake(config: IServerHandshakeConfig): {
|
|
1459
|
-
onHello(hello: THsHello): Promise<THsWelcome | THsReject>;
|
|
1460
|
-
onProve(prove: THsProve): Promise<THsAccept | THsReject>; /** The completed handshake result once `onProve` has accepted, else `undefined`. */
|
|
1461
|
-
getResult(): IHandshakeResult | undefined;
|
|
1462
|
-
};
|
|
1463
|
-
//#endregion
|
|
1464
|
-
//#region src/ActionRuntime/
|
|
947
|
+
declare function createServerHandshake(config: IServerHandshakeConfig): {
|
|
948
|
+
onHello(hello: THsHello): Promise<THsWelcome | THsReject>;
|
|
949
|
+
onProve(prove: THsProve): Promise<THsAccept | THsReject>; /** The completed handshake result once `onProve` has accepted, else `undefined`. */
|
|
950
|
+
getResult(): IHandshakeResult | undefined;
|
|
951
|
+
};
|
|
952
|
+
//#endregion
|
|
953
|
+
//#region src/ActionRuntime/Transport/Transport.d.ts
|
|
954
|
+
/**
|
|
955
|
+
* Context handed to a {@link Transport} definition when a handler builds a live connection from it.
|
|
956
|
+
* Only bidirectional transports (WebSocket / Custom) make use of `resolvers`.
|
|
957
|
+
*/
|
|
958
|
+
interface ITransportConnectionContext {
|
|
959
|
+
resolvers?: IActionTransportResolvers;
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Reusable transport definition. Devs construct these (`secureTransport({ carrier: wsCarrier(url) })`,
|
|
963
|
+
* `plainTransport({ carrier: httpCarrier(...) })`, …) and pass them to a
|
|
964
|
+
* `ConnectorHandler`. A single
|
|
965
|
+
* definition can be shared across multiple handlers — each handler builds its own live
|
|
966
|
+
* {@link TransportConnection} via {@link TransportConnection._createConnection}.
|
|
967
|
+
*/
|
|
968
|
+
declare abstract class Transport<T extends ETransportShape = ETransportShape> {
|
|
969
|
+
abstract readonly type: T;
|
|
970
|
+
/** Internal: build a fresh, per-handler live connection from this definition. */
|
|
971
|
+
abstract _createConnection(ctx: ITransportConnectionContext): TransportConnection<T>;
|
|
972
|
+
/**
|
|
973
|
+
* Resolve human-readable info about how a specific action would be routed through this transport
|
|
974
|
+
* (e.g. the request URL/method, or the WebSocket endpoint). Surfaced in the action devtools.
|
|
975
|
+
*/
|
|
976
|
+
abstract getRouteInfo(input: ITransportRouteActionParams): ITransportRouteInfo;
|
|
977
|
+
}
|
|
978
|
+
//#endregion
|
|
979
|
+
//#region src/ActionRuntime/Transport/TransportConnection.d.ts
|
|
980
|
+
/**
|
|
981
|
+
* Live, per-handler transport runtime built from a reusable {@link Transport} definition. Holds the
|
|
982
|
+
* connection-scoped state (ordinal, initialized config, sockets / abort sets) that must not be shared
|
|
983
|
+
* across handlers. Construct these via `definition._createConnection(...)`, never directly.
|
|
984
|
+
*/
|
|
985
|
+
declare abstract class TransportConnection<T extends ETransportShape = ETransportShape, RP extends ITransportRouteActionParams = ITransportRouteActionParams, RD extends IActionTransportReadyData_Base = IActionTransportReadyData_Base, I extends IActionTransportInitialized<RP, RD> = IActionTransportInitialized<RP, RD>, DEF extends IActionTransportDef<T, I> = IActionTransportDef<T, I>> {
|
|
986
|
+
readonly def: DEF;
|
|
987
|
+
readonly transOrd: number;
|
|
988
|
+
readonly type: T;
|
|
989
|
+
readonly initialized: I;
|
|
990
|
+
/** Backref to the public definition that created this connection (used for devtools route info). */
|
|
991
|
+
definition?: Transport<T>;
|
|
992
|
+
constructor(def: DEF);
|
|
993
|
+
/**
|
|
994
|
+
* Devtools route info for an action routed through this live connection. Defaults to the stateless
|
|
995
|
+
* {@link definition}'s info; connections override to enrich it from live state (e.g. the actual
|
|
996
|
+
* resolved socket URL) when the definition couldn't resolve it on its own.
|
|
997
|
+
*/
|
|
998
|
+
getRouteInfo(input: RP): ITransportRouteInfo | undefined;
|
|
999
|
+
/**
|
|
1000
|
+
* Build the live send/receive methods from a `ready` readyData, synchronously. This is the plain
|
|
1001
|
+
* (no-handshake) path and the only required per-transport hook. Stream carriers that must await the
|
|
1002
|
+
* carrier opening and/or run a handshake additionally override {@link _needsAsyncBringUp},
|
|
1003
|
+
* {@link _awaitCarrierReady}, and {@link _finalizeReady}.
|
|
1004
|
+
*/
|
|
1005
|
+
protected abstract _finalizeTransportMethods(inputs: RD): IActionTransportReadyData_Methods;
|
|
1006
|
+
/**
|
|
1007
|
+
* Whether a `ready`-status transport still needs asynchronous bring-up before its methods exist —
|
|
1008
|
+
* awaiting the carrier to open and/or running a handshake. Default `false`: a stateless transport
|
|
1009
|
+
* (HTTP) is usable the instant `getTransport` reports `ready`, so it stays a terminal *synchronous*
|
|
1010
|
+
* fallback in {@link ConnectionTransportManager}. Stream carriers (Link/WS) override to `true`.
|
|
1011
|
+
*/
|
|
1012
|
+
protected _needsAsyncBringUp(_readyData: RD): boolean;
|
|
1013
|
+
/** Await the carrier becoming ready to send (e.g. a socket `open`). Default: nothing to await. */
|
|
1014
|
+
protected _awaitCarrierReady(_readyData: RD): Promise<void>;
|
|
1015
|
+
/**
|
|
1016
|
+
* Finalize during async bring-up — may run a handshake, so it can be async. Defaults to the
|
|
1017
|
+
* synchronous {@link _finalizeTransportMethods}; secure stream carriers override to branch plain/secure.
|
|
1018
|
+
*/
|
|
1019
|
+
protected _finalizeReady(readyData: RD): IActionTransportReadyData_Methods | Promise<IActionTransportReadyData_Methods>;
|
|
1020
|
+
protected _getCacheKey(input: RP): string | null;
|
|
1021
|
+
getCacheKey(input: RP): string | null;
|
|
1022
|
+
getTransport(input: RP): TTransportStatusInfo<IActionTransportReadyData_Methods>;
|
|
1023
|
+
protected _processTransportStatus(input: RP): TTransportStatusInfo<IActionTransportReadyData_Methods>;
|
|
1024
|
+
/** Await carrier readiness, then finalize (possibly running a handshake) into the live methods. */
|
|
1025
|
+
private _bringUp;
|
|
1026
|
+
}
|
|
1027
|
+
//#endregion
|
|
1028
|
+
//#region src/ActionRuntime/Transport/Transport.types.d.ts
|
|
1029
|
+
/**
|
|
1030
|
+
* Carrier-shape class identity: the one carrier-invariant trait the selection layer reasons about —
|
|
1031
|
+
* whether a carrier can push unsolicited frames (`duplex`: WS/WebRTC/BLE/in-memory) or only answers a
|
|
1032
|
+
* request with a single correlated reply (`exchange`: HTTP). The concrete carrier kind ("ws", "webrtc",
|
|
1033
|
+
* "http", …) is a free-form {@link ITransportRouteInfo.carrierLabel} for display, not a class tag.
|
|
1034
|
+
*/
|
|
1035
|
+
declare enum ETransportShape {
|
|
1036
|
+
duplex = "duplex",
|
|
1037
|
+
exchange = "exchange"
|
|
1038
|
+
}
|
|
1039
|
+
/**
|
|
1040
|
+
* Serializable, display-only description of how an action was routed through a transport. Stored on
|
|
1041
|
+
* the action's route items and shown in the devtools external-handler chips. Keep this free of
|
|
1042
|
+
* sensitive data (e.g. auth headers) — route items travel over the wire.
|
|
1043
|
+
*/
|
|
1044
|
+
interface ITransportRouteInfo {
|
|
1045
|
+
/** Free-form carrier kind for the devtools chip — e.g. "ws", "webrtc", "http". */
|
|
1046
|
+
carrierLabel: string;
|
|
1047
|
+
/** Short label for chips, e.g. "POST /resolve_action" or "ws host/resolve_action/ws". */
|
|
1048
|
+
summary?: string;
|
|
1049
|
+
url?: string;
|
|
1050
|
+
method?: string;
|
|
1051
|
+
detail?: Record<string, string | number | boolean>;
|
|
1052
|
+
}
|
|
1053
|
+
interface IUpdateActionRunConfig_Output {
|
|
1054
|
+
timeout?: number;
|
|
1055
|
+
}
|
|
1056
|
+
type TUpdateActionRunConfig = (input: ITransportRouteActionParams & {
|
|
1057
|
+
timeout: number;
|
|
1058
|
+
}) => IUpdateActionRunConfig_Output;
|
|
1059
|
+
interface IActionTransportReadyData_Base {
|
|
1060
|
+
updateRunConfig?: TUpdateActionRunConfig;
|
|
1061
|
+
}
|
|
1062
|
+
/**
|
|
1063
|
+
* Client-side secure-channel config for a connector link — carrier-neutral (the secure session never
|
|
1064
|
+
* cared about the carrier). When present (and `securityLevel !== none`), the connection runs the
|
|
1065
|
+
* handshake during initialization and, at the `encrypted` level, encrypts every frame. The acceptor
|
|
1066
|
+
* side adds a negotiable level set + verify-key resolver on top of this (see Phase 3's `ISecureConfig`).
|
|
1067
|
+
*/
|
|
1068
|
+
interface ISecureClientConfig {
|
|
1069
|
+
/** The level this client requests; the peer must allow it. */
|
|
1070
|
+
securityLevel: ESecurityLevel;
|
|
1071
|
+
/** This client's crypto identity (verify + exchange key pairs, optionally persisted). */
|
|
1072
|
+
link: ClientCryptoKeyLink;
|
|
1073
|
+
/** This client's runtime coordinate — its authenticated identity to the peer. */
|
|
1074
|
+
localCoordinate: IRuntimeCoordinate;
|
|
1075
|
+
/** Wire dictionary version; the peer rejects the handshake on a mismatch. */
|
|
1076
|
+
dictionaryVersion: string;
|
|
1077
|
+
}
|
|
1078
|
+
/**
|
|
1079
|
+
*
|
|
1080
|
+
* TRANSPORT READINESS RESPONSE
|
|
1081
|
+
*
|
|
1082
|
+
*/
|
|
1083
|
+
declare enum ETransportStatus {
|
|
1084
|
+
uninitialized = "uninitialized",
|
|
1085
|
+
unsupported = "unsupported",
|
|
1086
|
+
initializing = "initializing",
|
|
1087
|
+
ready = "ready",
|
|
1088
|
+
failed = "failed"
|
|
1089
|
+
}
|
|
1090
|
+
interface ITransportStatusInfo_Base<S extends ETransportStatus> {
|
|
1091
|
+
status: S;
|
|
1092
|
+
}
|
|
1093
|
+
interface ITransportStatusInfo_Failed extends ITransportStatusInfo_Base<ETransportStatus.failed> {
|
|
1094
|
+
error: NiceError;
|
|
1095
|
+
timeFailed: number;
|
|
1096
|
+
}
|
|
1097
|
+
interface ITransportStatusInfo_Unsupported extends ITransportStatusInfo_Base<ETransportStatus.unsupported> {}
|
|
1098
|
+
interface ITransportStatusInfo_Ready<READY extends IActionTransportReadyData_Base> extends ITransportStatusInfo_Base<ETransportStatus.ready> {
|
|
1099
|
+
readyData: READY;
|
|
1100
|
+
}
|
|
1101
|
+
type TTransportInitializationFinishedInfo<READY extends IActionTransportReadyData_Base> = ITransportStatusInfo_Ready<READY> | ITransportStatusInfo_Failed | ITransportStatusInfo_Unsupported;
|
|
1102
|
+
interface ITransportStatusInfo_Initializing<READY extends IActionTransportReadyData_Base> extends ITransportStatusInfo_Base<ETransportStatus.initializing> {
|
|
1103
|
+
timeStarted: number;
|
|
1104
|
+
initializationPromise: Promise<TTransportInitializationFinishedInfo<READY>>;
|
|
1105
|
+
}
|
|
1106
|
+
type TTransportStatusInfo<READY extends IActionTransportReadyData_Base> = ITransportStatusInfo_Base<ETransportStatus.uninitialized> | ITransportStatusInfo_Unsupported | ITransportStatusInfo_Initializing<READY> | ITransportStatusInfo_Ready<READY> | ITransportStatusInfo_Failed;
|
|
1107
|
+
type TTransportStatusInfo_GetTransport_Output<READY extends IActionTransportReadyData_Base> = ITransportStatusInfo_Base<ETransportStatus.uninitialized> | ITransportStatusInfo_Unsupported | Omit<ITransportStatusInfo_Initializing<READY>, "timeStarted"> | ITransportStatusInfo_Ready<READY> | Omit<ITransportStatusInfo_Failed, "timeFailed">;
|
|
1108
|
+
/**
|
|
1109
|
+
*
|
|
1110
|
+
* TRANSPORT ROUTING
|
|
1111
|
+
*
|
|
1112
|
+
*/
|
|
1113
|
+
interface ITransportRouteClientParams {
|
|
1114
|
+
localClient: RuntimeCoordinate;
|
|
1115
|
+
externalClient: RuntimeCoordinate;
|
|
1116
|
+
}
|
|
1117
|
+
interface ITransportRouteActionParams extends ITransportRouteClientParams {
|
|
1118
|
+
action: TActionPayload_Any_Instance<any, any>;
|
|
1119
|
+
}
|
|
1120
|
+
interface ITransportMethod_SendActionData_Input extends ITransportRouteActionParams {
|
|
1121
|
+
runningAction: RunningAction<any, any>;
|
|
1122
|
+
timeout: number;
|
|
1123
|
+
}
|
|
1124
|
+
interface ITransportDispatchAction<P> extends ITransportMethod_SendActionData_Input {
|
|
1125
|
+
params: P;
|
|
1126
|
+
}
|
|
1127
|
+
type TSendActionDataMethod = (input: ITransportMethod_SendActionData_Input) => void;
|
|
1128
|
+
type TSendReturnDataMethod = (payload: TActionPayload_Any_Instance<any, any>,
|
|
1465
1129
|
/**
|
|
1466
|
-
*
|
|
1467
|
-
*
|
|
1468
|
-
*
|
|
1130
|
+
* The local/external client pair this payload is being returned over. Bidirectional transports use
|
|
1131
|
+
* it to build the full route params their outgoing formatter expects (e.g. binary packing). Optional
|
|
1132
|
+
* so existing return-data implementations keep type-checking.
|
|
1469
1133
|
*/
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
/**
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1134
|
+
|
|
1135
|
+
clients?: ITransportRouteClientParams) => void;
|
|
1136
|
+
interface IActionTransportReadyData_Methods extends IActionTransportReadyData_Base {
|
|
1137
|
+
sendActionData: TSendActionDataMethod;
|
|
1138
|
+
/**
|
|
1139
|
+
* Optional — implement on bidirectional transports (WebSocket, Custom) to enable return-path
|
|
1140
|
+
* routing. When present, the runtime uses this to dispatch results and progress payloads directly
|
|
1141
|
+
* back to `originClient` without going through the original request transport.
|
|
1142
|
+
*/
|
|
1143
|
+
sendReturnData?: TSendReturnDataMethod;
|
|
1144
|
+
addOnDisconnectListener?: (callback: () => void) => void;
|
|
1145
|
+
/**
|
|
1146
|
+
* Optional — implement on transports holding a long-lived connection (WebSocket, Custom) to close it
|
|
1147
|
+
* deliberately. Called by `ConnectorHandler.clearTransportCache()` so a teardown actually
|
|
1148
|
+
* releases the underlying socket instead of leaving it open until GC.
|
|
1149
|
+
*/
|
|
1150
|
+
disconnect?: () => void;
|
|
1478
1151
|
}
|
|
1479
|
-
interface
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1152
|
+
interface IActionTransportReady {
|
|
1153
|
+
methods: IActionTransportReadyData_Methods;
|
|
1154
|
+
transport: TransportConnection;
|
|
1155
|
+
}
|
|
1156
|
+
type TTransportCache = Map<string, IActionTransportReady | Promise<IActionTransportReady>>;
|
|
1157
|
+
type TOnResolveIncomingRequest = (request: ActionPayload_Request<any>) => void;
|
|
1158
|
+
type TOnResolveIncomingRequestJson = (request: IActionPayload_Request_JsonObject<any>) => void;
|
|
1159
|
+
type TOnResolveIncomingResponse = (response: ActionPayload_Result<any>) => void;
|
|
1160
|
+
type TOnResolveIncomingResponseJson = (response: IActionPayload_Result_JsonObject<any>) => void;
|
|
1161
|
+
type TOnResolveAnyIncomingActionData = (actionData: ActionPayload_Request<any> | ActionPayload_Result<any>) => void;
|
|
1162
|
+
type TOnResolveAnyIncomingActionData_Json = (actionData: TActionPayload_Any_JsonObject<any>) => void;
|
|
1163
|
+
interface IActionTransportResolvers {
|
|
1164
|
+
onIncomingActionDataJson: TOnResolveAnyIncomingActionData_Json;
|
|
1165
|
+
}
|
|
1166
|
+
type TGetTransportFn<IN extends ITransportRouteActionParams, READY extends IActionTransportReadyData_Base> = (input: IN) => TTransportStatusInfo_GetTransport_Output<READY>;
|
|
1167
|
+
interface IActionTransportInitialized<IN extends ITransportRouteActionParams, READY extends IActionTransportReadyData_Base> {
|
|
1168
|
+
getTransportCacheKey?: (input: IN) => string[];
|
|
1169
|
+
getTransport: TGetTransportFn<IN, READY>;
|
|
1170
|
+
}
|
|
1171
|
+
interface IActionTransportDef<TYPE extends ETransportShape, INIT extends IActionTransportInitialized<any, any>> {
|
|
1172
|
+
type: TYPE;
|
|
1173
|
+
initialize: () => INIT;
|
|
1174
|
+
}
|
|
1175
|
+
//#endregion
|
|
1176
|
+
//#region src/ActionRuntime/Handler/PeerLink/Connector/ConnectorHandler.types.d.ts
|
|
1177
|
+
interface IConnectorHandlerConfig {
|
|
1178
|
+
defaultTimeout?: number;
|
|
1179
|
+
runtimeCoordinate: RuntimeCoordinate;
|
|
1180
|
+
transports: Transport[];
|
|
1496
1181
|
}
|
|
1497
|
-
interface IActionTransportInitialized_Ws extends IActionTransportInitialized<ITransportRouteActionParams, IActionTransportReadyData_Ws> {}
|
|
1498
|
-
interface IActionTransportDef_Ws extends IActionTransportDef<ETransportType.ws, IActionTransportInitialized_Ws> {}
|
|
1499
1182
|
//#endregion
|
|
1500
|
-
//#region src/ActionRuntime/Handler/
|
|
1183
|
+
//#region src/ActionRuntime/Handler/PeerLink/Connector/ConnectorHandler.d.ts
|
|
1501
1184
|
/**
|
|
1502
|
-
*
|
|
1503
|
-
*
|
|
1504
|
-
*
|
|
1505
|
-
* `inputHash`/`outputHash`, and the per-frame `context.routing`/`context.timeCreated` are all dropped
|
|
1506
|
-
* (see {@link ENVELOPE}).
|
|
1507
|
-
*
|
|
1508
|
-
* No validation runs here: `incoming` blindly reconstructs the wire JSON shape and hands it back to
|
|
1509
|
-
* the connection, which flows into `ActionRuntime` → `domain.hydrateAnyAction()` where the Valibot
|
|
1510
|
-
* schemas validate it exactly as they would for a JSON frame.
|
|
1511
|
-
*
|
|
1512
|
-
* Both ends of the socket MUST construct the adapter with the same domains in the same order — the
|
|
1513
|
-
* integer dictionary is positional. Mismatched dictionaries will route to the wrong action.
|
|
1514
|
-
*
|
|
1515
|
-
* Because `incoming` returns `undefined` for text frames, a binary server can still serve plain-JSON
|
|
1516
|
-
* clients on the same runtime (the connection falls back to its built-in JSON parser).
|
|
1185
|
+
* Dial-out peer link: this runtime opens connection(s) to one peer over a transport stack (cached, with
|
|
1186
|
+
* preference-ordered fallback). The classic "client → backend" handler — but to the runtime it's just a
|
|
1187
|
+
* {@link PeerLinkHandler} like the accept-in server one.
|
|
1517
1188
|
*/
|
|
1518
|
-
declare
|
|
1189
|
+
declare class ConnectorHandler extends PeerLinkHandler {
|
|
1190
|
+
/**
|
|
1191
|
+
* Dial-out can receive (and so return) an unsolicited push only over a duplex transport. With every
|
|
1192
|
+
* transport exchange-only (HTTP), the peer can never push to us — so this link can't deliver one back.
|
|
1193
|
+
*/
|
|
1194
|
+
readonly canPush: boolean;
|
|
1195
|
+
private _defaultTimeout;
|
|
1196
|
+
private _transportCache;
|
|
1197
|
+
private transportManager;
|
|
1198
|
+
constructor({
|
|
1199
|
+
runtimeCoordinate: peerSpecifier,
|
|
1200
|
+
transports,
|
|
1201
|
+
defaultTimeout
|
|
1202
|
+
}: IConnectorHandlerConfig);
|
|
1203
|
+
handleActionRequest<DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string>(action: ActionPayload_Request<DOM, ID>, config?: IHandleActionOptions): Promise<RunningAction<DOM, ID>>;
|
|
1204
|
+
private _dispatchWhenTransportReady;
|
|
1205
|
+
/**
|
|
1206
|
+
* Dispatch a result or progress payload directly back to the external client via the best
|
|
1207
|
+
* available bidirectional transport (WebSocket / Custom). Used for return-path routing when the
|
|
1208
|
+
* local runtime recognises that it has a direct channel to the action's originClient.
|
|
1209
|
+
*
|
|
1210
|
+
* Returns `true` if the payload was sent, `false` if no suitable transport was available.
|
|
1211
|
+
*/
|
|
1212
|
+
sendReturnPayload(payload: TActionPayload_Any_Instance<any, any>, config: {
|
|
1213
|
+
targetLocalRuntime: ActionRuntime;
|
|
1214
|
+
}): Promise<boolean>;
|
|
1215
|
+
toJsonObject(): IActionHandler_Peer_Json;
|
|
1216
|
+
toHandlerRouteItem(transport: TransportConnection, input: ITransportRouteActionParams): IActionRouteItemHandler;
|
|
1217
|
+
clearTransportCache(): void;
|
|
1218
|
+
}
|
|
1219
|
+
declare const createConnectorHandler: (config: IConnectorHandlerConfig) => ConnectorHandler;
|
|
1519
1220
|
//#endregion
|
|
1520
|
-
//#region src/ActionRuntime/
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1221
|
+
//#region src/ActionRuntime/ActionRuntime.d.ts
|
|
1222
|
+
declare class ActionRuntime {
|
|
1223
|
+
private _coordinate;
|
|
1224
|
+
readonly timeCreated: number;
|
|
1225
|
+
readonly runtimeInfo: IRuntimeMeta;
|
|
1226
|
+
private readonly actionRouter;
|
|
1227
|
+
private readonly _pendingRunningActions;
|
|
1228
|
+
private readonly _registeredPeerHandlers;
|
|
1229
|
+
private _applied;
|
|
1230
|
+
static getDefault(): ActionRuntime;
|
|
1231
|
+
constructor(coordinate: RuntimeCoordinate);
|
|
1232
|
+
get coordinate(): RuntimeCoordinate;
|
|
1233
|
+
specifyRuntimeCoordinate(specifics: IRuntimeCoordinateSpecifics & {
|
|
1234
|
+
envId?: string;
|
|
1235
|
+
}): void;
|
|
1236
|
+
registerRunningAction(ra: RunningAction<any, any>): void;
|
|
1237
|
+
resolveIncomingActionPayload(json: TActionPayload_Any_JsonObject<any, any>): void;
|
|
1238
|
+
/**
|
|
1239
|
+
* Handle an incoming action wire (e.g. from a transport layer), route it to
|
|
1240
|
+
* the correct handler, and return the response. The most specific handler
|
|
1241
|
+
* match is chosen (action-ID-specific beats domain-wildcard).
|
|
1242
|
+
*/
|
|
1243
|
+
handleActionPayloadWire<D extends IActionDomain, ID extends keyof D["actionSchema"] & string>(wire: TActionPayload_Any_JsonObject<D, ID>): Promise<RunningAction<D, ID>>;
|
|
1244
|
+
handleActionPayloadWire(wire: unknown): Promise<RunningAction<any, any>>;
|
|
1245
|
+
handleActionPayload<DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string>(action: TActionPayload_Any_Instance<DOM, ID>, options?: Omit<IHandleActionOptions, "targetLocalRuntime">): Promise<RunningAction<DOM, ID>>;
|
|
1246
|
+
/**
|
|
1247
|
+
* @internal
|
|
1248
|
+
*
|
|
1249
|
+
* Return the first handler registered for the given action, or `undefined`
|
|
1250
|
+
* if none has been registered (action-ID-specific beats domain-wildcard).
|
|
1251
|
+
*/
|
|
1252
|
+
_getHandlerForAction<ACT extends TActionPayload_Any_Instance<any, any>>(action: ACT, options?: Omit<IHandleActionOptions, "targetLocalRuntime">): TActionHandler | undefined;
|
|
1253
|
+
getHandlerForActionOrThrow<ACT extends TActionPayload_Any_Instance<any, any>>(action: ACT, options?: Omit<IHandleActionOptions, "localRuntime">): TActionHandler;
|
|
1254
|
+
/**
|
|
1255
|
+
* Register one or more handlers. Each handler's own `actionRouter` defines
|
|
1256
|
+
* which domains/actions it handles — those routing keys are mirrored into
|
|
1257
|
+
* this runtime's router so the same action can be served by multiple handlers.
|
|
1258
|
+
* Duplicate registrations (same handler cuid for the same key) are skipped.
|
|
1259
|
+
*/
|
|
1260
|
+
addHandlers(handlers: TActionRuntimeHandler[]): this;
|
|
1261
|
+
/**
|
|
1262
|
+
* Declare an external "backend client" in one call: build an
|
|
1263
|
+
* {@link ConnectorHandler} for `externalCoordinate` carrying the given
|
|
1264
|
+
* `transports`, route the listed `domains`/`actions` to it, register it (plus any
|
|
1265
|
+
* `localHandlers` — e.g. server→client push handlers that share the same channel)
|
|
1266
|
+
* on this runtime, and `apply()`. Returns the external handler so the caller can
|
|
1267
|
+
* later `clearTransportCache()` it.
|
|
1268
|
+
*
|
|
1269
|
+
* Sugar over `new ConnectorHandler(...).forDomain(...)` + `addHandlers([...])`,
|
|
1270
|
+
* so a single runtime can host one handler per backend target with its transports
|
|
1271
|
+
* declared once and reused across every action routed to that backend.
|
|
1272
|
+
*/
|
|
1273
|
+
connectTo(externalCoordinate: RuntimeCoordinate, options: {
|
|
1274
|
+
transports: Transport[];
|
|
1275
|
+
domains?: ActionDomain<any>[];
|
|
1276
|
+
actions?: ActionCore<any, any>[];
|
|
1277
|
+
localHandlers?: TActionRuntimeHandler[];
|
|
1278
|
+
defaultTimeout?: number;
|
|
1279
|
+
}): ConnectorHandler;
|
|
1280
|
+
private applyRuntimeForDomain;
|
|
1281
|
+
/**
|
|
1282
|
+
* Register this runtime with all root domains covered by its currently-added handlers,
|
|
1283
|
+
* making it eligible to execute actions dispatched from those domains.
|
|
1284
|
+
* After apply() is called, any subsequent addHandlers() calls also auto-register.
|
|
1285
|
+
*/
|
|
1286
|
+
apply(): this;
|
|
1287
|
+
/**
|
|
1288
|
+
* Find the best registered external handler that can reach `originClient` directly.
|
|
1289
|
+
* Used to locate the return-path channel for dispatching results back to the action origin.
|
|
1290
|
+
* Returns `undefined` if no handler matches (score > 0 required, i.e. at least id must match).
|
|
1291
|
+
*/
|
|
1292
|
+
getReturnHandlerForOrigin(originClient: RuntimeCoordinate): PeerLinkHandler | undefined;
|
|
1293
|
+
resetRuntime(): void;
|
|
1294
|
+
private _trySetupReturnDispatch;
|
|
1525
1295
|
}
|
|
1526
|
-
/**
|
|
1527
|
-
* Builds a factory of *stateful, per-connection* codecs for {@link WebSocketTransport} /
|
|
1528
|
-
* `ActionServerHandler` — the maximally compact binary wire. Call the returned factory once per live
|
|
1529
|
-
* connection (each socket on the client, each accepted connection on the server) so every channel
|
|
1530
|
-
* gets its own correlation + identity state.
|
|
1531
|
-
*
|
|
1532
|
-
* On top of everything {@link createBinaryWsAdapter} drops, a session also drops:
|
|
1533
|
-
* - **`cuid`** — replaced by a per-connection integer correlation id. The initiator maps it to its
|
|
1534
|
-
* real cuid; the responder echoes it; each side reconstructs the cuid from its own map. Correlation
|
|
1535
|
-
* only needs to be unique per socket, so a counter suffices.
|
|
1536
|
-
* - **`originClient` after the first request** — the first request each side sends carries its
|
|
1537
|
-
* identity; the peer remembers it and injects it into later frames. Replies omit it entirely (a
|
|
1538
|
-
* reply carries the initiator's own origin, which the initiator already knows).
|
|
1539
|
-
*
|
|
1540
|
-
* Both ends MUST build the factory from the same domains in the same order (positional dictionary).
|
|
1541
|
-
* Text frames still return `undefined` from `incoming`, so JSON clients remain interoperable.
|
|
1542
|
-
*
|
|
1543
|
-
* Hibernation note: after a server connection is evicted its session resets, so a still-connected
|
|
1544
|
-
* client (whose session persists) will keep omitting `originClient`. The server must therefore restore
|
|
1545
|
-
* the connection→client binding from its own store (see `ActionServerHandler.rehydrateConnection`) and
|
|
1546
|
-
* inject `originClient` from there — the session alone can't recover it.
|
|
1547
|
-
*/
|
|
1548
|
-
declare function createBinaryWsSessionFactory(domains: ActionDomain<any>[], options?: IBinaryWsSessionOptions): () => TFormatMessage;
|
|
1549
1296
|
//#endregion
|
|
1550
|
-
//#region src/
|
|
1551
|
-
declare class
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
constructor(def: Omit<IActionTransportDef_Ws, "type">, resolvers?: IActionTransportResolvers);
|
|
1558
|
-
protected _getCacheKey(_input: ITransportRouteActionParams): string;
|
|
1559
|
-
protected _processTransportStatus(input: ITransportRouteActionParams): TTransportStatusInfo<IActionTransportReadyData_Methods>;
|
|
1560
|
-
getRouteInfo(input: ITransportRouteActionParams): ITransportRouteInfo | undefined;
|
|
1561
|
-
private _isSecure;
|
|
1562
|
-
private _awaitOpen;
|
|
1563
|
-
/** Non-secure connections finalize synchronously; secure ones run the handshake first. */
|
|
1564
|
-
private _finalize;
|
|
1565
|
-
_finalizeTransportMethods(wsData: IActionTransportReadyData_Ws): IActionTransportReadyData_Methods;
|
|
1566
|
-
/**
|
|
1567
|
-
* Secure path: a single message listener feeds the handshake until it completes, then routes action
|
|
1568
|
-
* frames (decrypting for the `encrypted` level). Frames that arrive in the gap between accept and
|
|
1569
|
-
* activation are buffered and flushed, so nothing is lost.
|
|
1570
|
-
*/
|
|
1571
|
-
private _finalizeSecureMethods;
|
|
1572
|
-
private _runClientHandshake;
|
|
1573
|
-
private _buildSendMethods;
|
|
1574
|
-
/** Decode (and, when encrypted, decrypt) one inbound action frame and hand it to the runtime. */
|
|
1575
|
-
private _handleIncomingActionFrame;
|
|
1576
|
-
/** Accept text + binary frames (ArrayBuffer / Uint8Array / Blob); Blobs are converted to a buffer. */
|
|
1577
|
-
private _normalizeFrame;
|
|
1578
|
-
private _captureSocketUrl;
|
|
1579
|
-
private _attachLifecycle;
|
|
1580
|
-
private _abortAll;
|
|
1581
|
-
}
|
|
1582
|
-
//#endregion
|
|
1583
|
-
//#region src/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/WebSocketTransport.d.ts
|
|
1584
|
-
interface IWebSocketTransportSharedOptions {
|
|
1585
|
-
/** Custom (de)serialization of action payloads on the wire (shared across all sockets). */
|
|
1586
|
-
formatMessage?: IActionTransportReadyData_Ws["formatMessage"];
|
|
1587
|
-
/**
|
|
1588
|
-
* Per-socket codec factory — called once for each socket so stateful codecs (e.g. the
|
|
1589
|
-
* `createBinaryWsSessionFactory` session, which holds per-connection correlation + identity state)
|
|
1590
|
-
* get their own instance and reset cleanly on reconnect. Takes precedence over `formatMessage`.
|
|
1591
|
-
*/
|
|
1592
|
-
createFormatMessage?: () => IActionTransportReadyData_Ws["formatMessage"];
|
|
1593
|
-
updateRunConfig?: TUpdateActionRunConfig;
|
|
1297
|
+
//#region src/ActionDefinition/Domain/ActionDomainBase.d.ts
|
|
1298
|
+
declare abstract class ActionDomainBase<ACT_DOM extends IActionDomain = IActionDomain> implements IActionDomain<ACT_DOM["allDomains"], ACT_DOM["actionSchema"]> {
|
|
1299
|
+
readonly domain: ACT_DOM["domain"];
|
|
1300
|
+
readonly allDomains: ACT_DOM["allDomains"];
|
|
1301
|
+
readonly actionSchema: ACT_DOM["actionSchema"];
|
|
1302
|
+
protected _listeners: TRunningActionUpdateListener<any, any>[];
|
|
1303
|
+
constructor(definition: ACT_DOM);
|
|
1594
1304
|
/**
|
|
1595
|
-
*
|
|
1596
|
-
*
|
|
1305
|
+
* Add an observer that is called after every action dispatched through this domain.
|
|
1306
|
+
* Returns an unsubscribe function — call it to remove the listener.
|
|
1597
1307
|
*/
|
|
1598
|
-
|
|
1599
|
-
/** Override the devtools route info for a specific action. */
|
|
1600
|
-
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
1308
|
+
addActionListener(listener: TDistributeRunningActionUpdateListener<ACT_DOM, keyof ACT_DOM["actionSchema"] & string>): () => void;
|
|
1601
1309
|
/**
|
|
1602
|
-
*
|
|
1603
|
-
*
|
|
1310
|
+
* @internal
|
|
1311
|
+
* Observers registered directly on this domain via {@link addActionListener}.
|
|
1312
|
+
* Used to wire observers (e.g. devtools) onto RunningActions that aren't created
|
|
1313
|
+
* through the local-dispatch path — notably inbound actions pushed from a backend
|
|
1314
|
+
* or another client over a bidirectional transport.
|
|
1604
1315
|
*/
|
|
1605
|
-
|
|
1316
|
+
_getActionObservers(): TRunningActionUpdateListener<any, any>[];
|
|
1606
1317
|
}
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1318
|
+
//#endregion
|
|
1319
|
+
//#region src/ActionDefinition/Domain/ActionRootDomain.d.ts
|
|
1320
|
+
declare class ActionRootDomain<ROOT_DOM extends IActionRootDomain = IActionRootDomain> extends ActionDomainBase<ROOT_DOM> {
|
|
1321
|
+
readonly domainDefinition: {
|
|
1322
|
+
domain: ROOT_DOM["domain"];
|
|
1323
|
+
};
|
|
1324
|
+
private _actionRuntimeManager;
|
|
1325
|
+
constructor(domainDefinition: {
|
|
1326
|
+
domain: ROOT_DOM["domain"];
|
|
1327
|
+
});
|
|
1328
|
+
createChildDomain<SUB_DOM extends IActionDomainChildOptions>(subDomainDef: SUB_DOM & { [K in Exclude<keyof SUB_DOM, keyof IActionDomainChildOptions>]: never }): ActionDomain<TActionDomainChildDef<ROOT_DOM, SUB_DOM>>;
|
|
1329
|
+
_registerRuntime(runtime: ActionRuntime): void;
|
|
1330
|
+
_hasRuntime(runtime: ActionRuntime): boolean;
|
|
1331
|
+
getRuntime(clientSpecifier: IRuntimeCoordinate): ActionRuntime | undefined;
|
|
1332
|
+
_runAction<DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string = keyof DOM["actionSchema"] & string, ACT extends ActionPayload_Request<DOM, ID> = ActionPayload_Request<DOM, ID>>(actionPayload: ACT, options?: IExecuteActionOptions<DOM, ID>): Promise<RunningAction<DOM, ID>>;
|
|
1610
1333
|
}
|
|
1611
|
-
|
|
1334
|
+
//#endregion
|
|
1335
|
+
//#region src/ActionDefinition/Domain/ActionDomain.d.ts
|
|
1336
|
+
type TActionMap<ACT_DOM extends IActionDomain> = { [K in keyof ACT_DOM["actionSchema"] & string]: ActionCore<ACT_DOM, K> };
|
|
1337
|
+
declare class ActionDomain<ACT_DOM extends IActionDomain = IActionDomain> extends ActionDomainBase<ACT_DOM> {
|
|
1338
|
+
private _rootDomain;
|
|
1339
|
+
private readonly _actionMap;
|
|
1340
|
+
constructor(definition: ACT_DOM, {
|
|
1341
|
+
rootDomain
|
|
1342
|
+
}: {
|
|
1343
|
+
rootDomain: ActionRootDomain<any>;
|
|
1344
|
+
});
|
|
1345
|
+
get rootDomain(): ActionRootDomain<any>;
|
|
1612
1346
|
/**
|
|
1613
|
-
*
|
|
1614
|
-
*
|
|
1615
|
-
*
|
|
1616
|
-
*
|
|
1347
|
+
* @internal
|
|
1348
|
+
* All action observers that should see actions on this domain: the root domain's
|
|
1349
|
+
* observers plus this subdomain's own. Mirrors the listener set the local-dispatch
|
|
1350
|
+
* path assembles in `runAction`/`_runAction`, so inbound actions (pushed from a
|
|
1351
|
+
* backend or another client) can be wired up identically and surface in devtools.
|
|
1617
1352
|
*/
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
constructor(options: TWebSocketTransportOptions);
|
|
1634
|
-
static create(options: IWebSocketTransportSocketOptions): WebSocketTransport;
|
|
1635
|
-
static createAdvanced(options: IWebSocketTransportAdvancedOptions): WebSocketTransport;
|
|
1636
|
-
_createConnection(ctx: ITransportConnectionContext): WebSocketConnection;
|
|
1637
|
-
getRouteInfo(input: ITransportRouteActionParams): ITransportRouteInfo;
|
|
1353
|
+
_collectActionObservers(): TRunningActionUpdateListener<any, any>[];
|
|
1354
|
+
_registerRuntime(runtime: ActionRuntime): void;
|
|
1355
|
+
createChildDomain<SUB_DOM extends IActionDomainChildOptions>(subDomainDef: SUB_DOM & { [K in Exclude<keyof SUB_DOM, keyof IActionDomainChildOptions>]: never }): ActionDomain<TActionDomainChildDef<ACT_DOM, SUB_DOM>>;
|
|
1356
|
+
get action(): TActionMap<ACT_DOM>;
|
|
1357
|
+
actionsMap(): TActionMap<ACT_DOM>;
|
|
1358
|
+
actionForId<ID extends keyof ACT_DOM["actionSchema"] & string>(id: ID): ActionCore<ACT_DOM, ID>;
|
|
1359
|
+
wrapAsPartialLocalHandler(wrappedActionExecutor: Partial<TWrappableDomainActionHandler<ACT_DOM>>): ActionLocalHandler;
|
|
1360
|
+
wrapAsLocalHandler(wrappedActionExecutor: TWrappableDomainActionHandler<ACT_DOM>): ActionLocalHandler;
|
|
1361
|
+
hydrateContext<ID extends keyof ACT_DOM["actionSchema"] & string>(id: ID, contextData: IActionContext_Data_JsonObject): ActionContext<ACT_DOM, ID>;
|
|
1362
|
+
isDomainAction<ACT extends IActionBase<any, ACT_DOM, any>>(action: ACT | unknown | null | undefined): action is TDistributedDomainActions<ACT_DOM, ACT>;
|
|
1363
|
+
hydrateRequestPayload<ID extends keyof ACT_DOM["actionSchema"] & string, P extends IActionPayload_Request_JsonObject<ACT_DOM, ID>>(serialized: P): TDistributeActionPayload_Request<ACT_DOM, ID>;
|
|
1364
|
+
hydrateResultPayload<ID extends keyof ACT_DOM["actionSchema"] & string, R extends IActionPayload_Result_JsonObject<ACT_DOM, ID>>(serialized: R): TDistributeActionPayload_Result<ACT_DOM, ID>;
|
|
1365
|
+
hydrateAnyAction<ID extends keyof ACT_DOM["actionSchema"] & string, AJ extends TAction_Any_JsonObject<ACT_DOM, ID>>(actionJson: AJ): TNarrowActionJsonTypeToActionInstanceType<ACT_DOM, AJ, ID>;
|
|
1366
|
+
runAction<ID extends keyof ACT_DOM["actionSchema"] & string, ACT extends ActionPayload_Request<ACT_DOM, ID>>(request: ACT, options?: IExecuteActionOptions<ACT_DOM, ID>): Promise<RunningAction<ACT_DOM, ID>>;
|
|
1367
|
+
private createActionMap;
|
|
1638
1368
|
}
|
|
1639
1369
|
//#endregion
|
|
1640
|
-
//#region src/
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
dictionaryVersion: string;
|
|
1653
|
-
/** Per-connection session codec factory (call once per live connection). */
|
|
1654
|
-
createCodec: () => TChannelCodec;
|
|
1655
|
-
}
|
|
1656
|
-
/**
|
|
1657
|
-
* Bundle a secure channel's shared identity from its transported domains. Both ends MUST call this
|
|
1658
|
-
* with the same domains in the same order (the binary wire dictionary is positional). The
|
|
1659
|
-
* `dictionaryVersion` is derived from those domains unless you pin an explicit one.
|
|
1660
|
-
*/
|
|
1661
|
-
declare function defineSecureWsChannel(options: {
|
|
1662
|
-
/** Domains transported over this channel, in a stable order. Add new ones to the *end*. */domains: ActionDomain<any>[]; /** Pin a human-readable version instead of the derived hash (must match on both ends). */
|
|
1663
|
-
dictionaryVersion?: string; /** Tuning for the per-connection binary session (e.g. correlation TTL). */
|
|
1664
|
-
sessionOptions?: IBinaryWsSessionOptions;
|
|
1665
|
-
}): ISecureWsChannel;
|
|
1666
|
-
interface ISecureWebSocketTransportOptions {
|
|
1667
|
-
/** The shared channel identity (codec + dictionary version). */
|
|
1668
|
-
channel: ISecureWsChannel;
|
|
1669
|
-
/** This client's runtime — its coordinate is the authenticated identity sent in the handshake. */
|
|
1670
|
-
runtime: ActionRuntime;
|
|
1671
|
-
/** Backing store for this client's crypto identity (a stable verify key across reloads). */
|
|
1672
|
-
storageAdapter: StorageAdapter;
|
|
1673
|
-
/** The level this client requests; the server must allow it. */
|
|
1674
|
-
securityLevel: ESecurityLevel;
|
|
1675
|
-
/** Endpoint URL — drives both the socket and the per-endpoint cache key. */
|
|
1676
|
-
url: string;
|
|
1677
|
-
/** Override socket creation (defaults to a `new WebSocket(url)` with `binaryType = "arraybuffer"`). */
|
|
1678
|
-
createWebSocket?: (input: ITransportRouteActionParams) => WebSocket;
|
|
1679
|
-
/** Override the reuse key (defaults to `[url]`, so one socket is shared per endpoint). */
|
|
1680
|
-
getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
1681
|
-
updateRunConfig?: TUpdateActionRunConfig;
|
|
1682
|
-
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
1370
|
+
//#region src/ActionDefinition/Action/Core/ActionCore.d.ts
|
|
1371
|
+
declare class ActionCore<DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string = keyof DOM["actionSchema"] & string> extends ActionBase<EActionForm.core, DOM, ID> implements IActionCore<DOM, ID> {
|
|
1372
|
+
readonly _domain: ActionDomain<DOM>;
|
|
1373
|
+
readonly form = EActionForm.core;
|
|
1374
|
+
constructor(_domain: ActionDomain<DOM>, id: ID);
|
|
1375
|
+
is<ACT extends IActionBase<any, any, any>>(action: ACT | unknown | null | undefined): action is TNarrowActionType<DOM, ACT, ID>;
|
|
1376
|
+
toJsonObject(): IActionBase_JsonObject<EActionForm.core, DOM, ID>;
|
|
1377
|
+
request(...args: [TInferInputFromSchema<DOM["actionSchema"][ID]>["Input"]] extends [never] ? [input?: never] : [input: TInferInputFromSchema<DOM["actionSchema"][ID]>["Input"]]): ActionPayload_Request<DOM, ID>;
|
|
1378
|
+
deserializeInput(serialized: TInferInputFromSchema<DOM["actionSchema"][ID]>["SerdeInput"]): TInferInputFromSchema<DOM["actionSchema"][ID]>["Input"];
|
|
1379
|
+
serializeInput(raw: TInferInputFromSchema<DOM["actionSchema"][ID]>["Input"]): TInferInputFromSchema<DOM["actionSchema"][ID]>["SerdeInput"];
|
|
1380
|
+
validateInput(input: unknown): TInferInputFromSchema<DOM["actionSchema"][ID]>["Input"];
|
|
1381
|
+
validateOutput(output: unknown): TInferOutputFromSchema<DOM["actionSchema"][ID]>["Output"];
|
|
1683
1382
|
}
|
|
1383
|
+
//#endregion
|
|
1384
|
+
//#region src/ActionDefinition/Domain/helpers/createRootActionDomain.d.ts
|
|
1385
|
+
declare const createActionRootDomain: <ID extends string>(definition: {
|
|
1386
|
+
domain: ID;
|
|
1387
|
+
}) => ActionRootDomain<IActionRootDomain<ID>>;
|
|
1388
|
+
//#endregion
|
|
1389
|
+
//#region src/ActionRuntime/Transport/codec/actionWireCodec.d.ts
|
|
1684
1390
|
/**
|
|
1685
|
-
*
|
|
1686
|
-
*
|
|
1687
|
-
*
|
|
1688
|
-
*
|
|
1689
|
-
* `getTransportCacheKey` to take over those bits when you need to.
|
|
1391
|
+
* Shared building blocks for the binary action codecs (the stateless {@link createBinaryWireAdapter} and
|
|
1392
|
+
* the per-connection `createBinaryWireSessionFactory`). Both map a `domain:id` route to a tiny integer
|
|
1393
|
+
* and reduce the verbose JSON wire to a positional tuple — they only differ in how much context they
|
|
1394
|
+
* carry per frame, so the dictionary + payload (de)assembly live here.
|
|
1690
1395
|
*/
|
|
1691
|
-
declare function createSecureWebSocketTransport(options: ISecureWebSocketTransportOptions): WebSocketTransport;
|
|
1692
|
-
//#endregion
|
|
1693
|
-
//#region src/ActionRuntime/Handler/Server/WsConnectionStateStore.d.ts
|
|
1694
1396
|
/**
|
|
1695
|
-
* The
|
|
1696
|
-
*
|
|
1697
|
-
* sockets outlive process eviction (e.g. a Durable Object's hibernatable WebSocket) recovers both the
|
|
1698
|
-
* application identity *and* the action routing from a single attachment after a wake — no storage reads.
|
|
1397
|
+
* The carrier-neutral codec a Link connection uses to (de)serialize action payloads on the wire — the
|
|
1398
|
+
* same shape every duplex carrier (WS/WebRTC/in-memory) shares.
|
|
1699
1399
|
*/
|
|
1700
|
-
interface
|
|
1701
|
-
app?: TApp;
|
|
1702
|
-
binding?: IActionServerConnectionBinding;
|
|
1703
|
-
}
|
|
1704
|
-
interface IWsConnectionStateStoreOptions<TConn, TApp> {
|
|
1705
|
-
/** Read a connection's raw attachment (e.g. `(ws) => ws.deserializeAttachment()`). */
|
|
1706
|
-
read: (connection: TConn) => unknown;
|
|
1707
|
-
/** Persist a connection's attachment (e.g. `(ws, value) => ws.serializeAttachment(value)`). */
|
|
1708
|
-
write: (connection: TConn, value: IConnectionAttachment<TApp>) => void;
|
|
1400
|
+
interface IActionWireFormat {
|
|
1709
1401
|
/**
|
|
1710
|
-
*
|
|
1711
|
-
*
|
|
1712
|
-
* {@link WsConnectionStateStore.entries}.
|
|
1402
|
+
* Pack an outgoing action payload. Return a `string` for text frames (JSON) or a binary
|
|
1403
|
+
* `Uint8Array`/`ArrayBuffer` for optimized binary frames (e.g. msgpackr).
|
|
1713
1404
|
*/
|
|
1714
|
-
|
|
1405
|
+
outgoing: (input: ITransportRouteActionParams) => string | Uint8Array | ArrayBuffer;
|
|
1715
1406
|
/**
|
|
1716
|
-
*
|
|
1717
|
-
*
|
|
1718
|
-
*
|
|
1407
|
+
* Unpack an incoming frame back into the wire JSON object the runtime hydrates + validates. Return
|
|
1408
|
+
* `undefined` to defer to the connection's built-in JSON parser — this is how binary adapters stay
|
|
1409
|
+
* backward compatible with plain-JSON clients on the same socket.
|
|
1719
1410
|
*/
|
|
1720
|
-
|
|
1721
|
-
}
|
|
1722
|
-
/**
|
|
1723
|
-
* A typed per-connection state store that co-owns the app state and the server handler's routing
|
|
1724
|
-
* binding in one attachment, so neither the consumer nor the handler has to hand-merge the two. Create
|
|
1725
|
-
* it through {@link ActionServerHandler.createConnectionState} (which also wires binding persistence and
|
|
1726
|
-
* replays surviving connections after a wake), then `get`/`set`/`clearApp` the app state directly.
|
|
1727
|
-
*
|
|
1728
|
-
* ```ts
|
|
1729
|
-
* const players = serverHandler.createConnectionState({
|
|
1730
|
-
* schema: vs_player,
|
|
1731
|
-
* read: (ws) => ws.deserializeAttachment(),
|
|
1732
|
-
* write: (ws, v) => ws.serializeAttachment(v),
|
|
1733
|
-
* getConnections: () => ctx.getWebSockets(),
|
|
1734
|
-
* });
|
|
1735
|
-
* players.set(ws, player); // binding is preserved automatically
|
|
1736
|
-
* const player = players.get(ws);
|
|
1737
|
-
* ```
|
|
1738
|
-
*/
|
|
1739
|
-
declare class WsConnectionStateStore<TConn, TApp> {
|
|
1740
|
-
private readonly options;
|
|
1741
|
-
constructor(options: IWsConnectionStateStoreOptions<TConn, TApp>);
|
|
1742
|
-
/** The validated app state for a connection, or `null` if unset / invalid. */
|
|
1743
|
-
get(connection: TConn): TApp | null;
|
|
1744
|
-
/** Set the app state, preserving the runtime binding already pinned to the connection. */
|
|
1745
|
-
set(connection: TConn, app: TApp): void;
|
|
1746
|
-
/** Clear the app state but keep the binding (e.g. a spectator that stopped watching). */
|
|
1747
|
-
clearApp(connection: TConn): void;
|
|
1748
|
-
/** Every live connection paired with its (validated) app state — for rebuilding in-memory state after a wake. */
|
|
1749
|
-
entries(): [TConn, TApp | null][];
|
|
1750
|
-
/** @internal Persist a freshly-bound connection's binding, preserving any app state already stored. */
|
|
1751
|
-
_persistBinding(connection: TConn, binding: IActionServerConnectionBinding): void;
|
|
1752
|
-
/** @internal The persisted binding for a connection, if any (used to replay routing after a wake). */
|
|
1753
|
-
_readBinding(connection: TConn): IActionServerConnectionBinding | undefined;
|
|
1754
|
-
private _readAttachment;
|
|
1755
|
-
private _validateApp;
|
|
1411
|
+
incoming?: (input: string | ArrayBuffer | Uint8Array | Blob) => TActionPayload_Any_JsonObject<any, any> | undefined;
|
|
1756
1412
|
}
|
|
1757
1413
|
//#endregion
|
|
1758
|
-
//#region src/ActionRuntime/Handler/
|
|
1759
|
-
/** The codec shape `
|
|
1760
|
-
type TActionChannelFormatMessage =
|
|
1414
|
+
//#region src/ActionRuntime/Handler/PeerLink/Acceptor/AcceptorHandler.d.ts
|
|
1415
|
+
/** The codec shape `AcceptorHandler` uses to pack/unpack frames — same as the Link transport's. */
|
|
1416
|
+
type TActionChannelFormatMessage = IActionWireFormat;
|
|
1761
1417
|
/** How a connection encodes its frames, remembered so we answer each client in its own dialect. */
|
|
1762
1418
|
type TActionConnectionEncoding = "json" | "binary";
|
|
1763
1419
|
/** A connection's restorable identity — what to persist so a binding survives transport eviction. */
|
|
1764
|
-
interface
|
|
1420
|
+
interface IAcceptorConnectionBinding {
|
|
1765
1421
|
/** Full client coordinate, so `originClient` can be re-injected into frames that omit it. */
|
|
1766
1422
|
client: IRuntimeCoordinate;
|
|
1767
1423
|
encoding: TActionConnectionEncoding;
|
|
@@ -1783,7 +1439,7 @@ interface IActionServerConnectionBinding {
|
|
|
1783
1439
|
* when `none` is in the allowed set) is accepted as-is with a self-asserted identity. For the
|
|
1784
1440
|
* `encrypted` level the codec source should be a session factory (`createFormatMessage`).
|
|
1785
1441
|
*/
|
|
1786
|
-
interface
|
|
1442
|
+
interface IAcceptorSecurity {
|
|
1787
1443
|
/**
|
|
1788
1444
|
* Accepted level(s). A single level is strict; an array is a negotiable allowed set — the server
|
|
1789
1445
|
* adopts whichever level each client requests (e.g. `[none, authenticated, encrypted]` serves all
|
|
@@ -1799,7 +1455,7 @@ interface IActionServerSecurity {
|
|
|
1799
1455
|
/** Trust decision for a client's verify key (defaults to in-memory TOFU inside the handshake). */
|
|
1800
1456
|
verifyKeyResolver?: IClientVerifyKeyResolver;
|
|
1801
1457
|
}
|
|
1802
|
-
interface
|
|
1458
|
+
interface IAcceptorHandlerBaseOptions<TConn> {
|
|
1803
1459
|
/**
|
|
1804
1460
|
* Coordinate of the *connecting clients* (typically env-only, e.g. `RuntimeCoordinate.env("web_app")`).
|
|
1805
1461
|
* The runtime's return-path dispatch scores incoming actions' `originClient` against this to pick
|
|
@@ -1809,7 +1465,7 @@ interface IActionServerHandlerBaseOptions<TConn> {
|
|
|
1809
1465
|
/** Write an encoded frame to a specific live connection (e.g. `(ws, frame) => ws.send(frame)`). */
|
|
1810
1466
|
send: (connection: TConn, frame: string | Uint8Array | ArrayBuffer) => void;
|
|
1811
1467
|
/**
|
|
1812
|
-
* The runtime this handler belongs to. When set, {@link
|
|
1468
|
+
* The runtime this handler belongs to. When set, {@link AcceptorHandler.broadcast} can be called
|
|
1813
1469
|
* without threading a runtime through each call. Optional — `pushToClient` still takes one explicitly.
|
|
1814
1470
|
*/
|
|
1815
1471
|
runtime?: ActionRuntime;
|
|
@@ -1818,24 +1474,24 @@ interface IActionServerHandlerBaseOptions<TConn> {
|
|
|
1818
1474
|
/**
|
|
1819
1475
|
* Called once when a connection is first bound to a client identity. Use it to persist the binding
|
|
1820
1476
|
* for transports that can resume after eviction — e.g. a Durable Object's hibernatable WebSocket:
|
|
1821
|
-
* `(ws, binding) => ws.serializeAttachment(binding)` — then replay it via {@link
|
|
1477
|
+
* `(ws, binding) => ws.serializeAttachment(binding)` — then replay it via {@link AcceptorHandler.rehydrateConnection}
|
|
1822
1478
|
* when the channel comes back.
|
|
1823
1479
|
*/
|
|
1824
|
-
onConnectionBound?: (connection: TConn, binding:
|
|
1480
|
+
onConnectionBound?: (connection: TConn, binding: IAcceptorConnectionBinding) => void;
|
|
1825
1481
|
/**
|
|
1826
1482
|
* Enable the authenticated (optionally encrypted) handshake. When omitted, connections are trusted
|
|
1827
1483
|
* as-is (identity self-asserted) — fine for dev / trusted networks.
|
|
1828
1484
|
*/
|
|
1829
|
-
security?:
|
|
1485
|
+
security?: IAcceptorSecurity;
|
|
1830
1486
|
}
|
|
1831
1487
|
/**
|
|
1832
1488
|
* Provide exactly one codec source:
|
|
1833
|
-
* - `formatMessage` — a single shared codec for every connection (stateless, e.g. `
|
|
1489
|
+
* - `formatMessage` — a single shared codec for every connection (stateless, e.g. `createBinaryWireAdapter`).
|
|
1834
1490
|
* - `createFormatMessage` — a per-connection factory for stateful codecs (e.g.
|
|
1835
|
-
* `
|
|
1491
|
+
* `createBinaryWireSessionFactory`, whose sessions hold correlation + identity state). Required for the
|
|
1836
1492
|
* leanest binary wire; the handler creates and caches one codec per connection.
|
|
1837
1493
|
*/
|
|
1838
|
-
type
|
|
1494
|
+
type IAcceptorHandlerOptions<TConn> = IAcceptorHandlerBaseOptions<TConn> & ({
|
|
1839
1495
|
formatMessage: TActionChannelFormatMessage;
|
|
1840
1496
|
createFormatMessage?: never;
|
|
1841
1497
|
} | {
|
|
@@ -1843,12 +1499,12 @@ type IActionServerHandlerOptions<TConn> = IActionServerHandlerBaseOptions<TConn>
|
|
|
1843
1499
|
formatMessage?: never;
|
|
1844
1500
|
});
|
|
1845
1501
|
/**
|
|
1846
|
-
* A connection-aware execution case (see {@link
|
|
1502
|
+
* A connection-aware execution case (see {@link AcceptorHandler.forConnectionDomainCases}). It
|
|
1847
1503
|
* receives the primed request plus the originating client's live connection (already resolved from the
|
|
1848
1504
|
* request's `originClient`, `undefined` if the socket is gone), and may return the action's raw output,
|
|
1849
1505
|
* a result payload, or nothing (auto-wrapped as an empty success) — exactly like a local handler case.
|
|
1850
1506
|
*/
|
|
1851
|
-
type
|
|
1507
|
+
type TAcceptorConnectionCaseFn<DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string, TConn> = (action: TDistributeActionPayload_Request<DOM, ID>, connection: TConn | undefined) => ReturnType<THandleActionExecutionFn<DOM, ID>> | void;
|
|
1852
1508
|
/**
|
|
1853
1509
|
* Server-side handler for backends that accept many client connections over a single open channel
|
|
1854
1510
|
* (WebSockets, Durable Objects, …). It is transport-agnostic: you feed it inbound frames with
|
|
@@ -1856,7 +1512,7 @@ type TServerConnectionCaseFn<DOM extends IActionDomain, ID extends keyof DOM["ac
|
|
|
1856
1512
|
*
|
|
1857
1513
|
* Add it alongside your local execution handler:
|
|
1858
1514
|
* ```ts
|
|
1859
|
-
* const serverHandler =
|
|
1515
|
+
* const serverHandler = createAcceptorHandler({ clientEnv, formatMessage, send: (ws, f) => ws.send(f) });
|
|
1860
1516
|
* runtime.addHandlers([localHandler, serverHandler]);
|
|
1861
1517
|
* // per inbound message (e.g. a Durable Object's webSocketMessage):
|
|
1862
1518
|
* serverHandler.receive(ws, message);
|
|
@@ -1870,15 +1526,15 @@ type TServerConnectionCaseFn<DOM extends IActionDomain, ID extends keyof DOM["ac
|
|
|
1870
1526
|
* It registers an empty action router, so it is never chosen to *execute* an inbound request — only
|
|
1871
1527
|
* to ferry results/pushes back out.
|
|
1872
1528
|
*/
|
|
1873
|
-
declare class
|
|
1529
|
+
declare class AcceptorHandler<TConn = unknown> extends PeerLinkHandler {
|
|
1530
|
+
/** Accept-in over a live (duplex) connection registry — it pushes results/broadcasts to bound sockets. */
|
|
1531
|
+
readonly canPush = true;
|
|
1874
1532
|
private readonly _formatMessage?;
|
|
1875
1533
|
private readonly _createFormatMessage?;
|
|
1876
1534
|
private readonly _send;
|
|
1877
1535
|
private readonly _runtime?;
|
|
1878
1536
|
private readonly _serverTimeout;
|
|
1879
1537
|
private _onConnectionBound?;
|
|
1880
|
-
/** Incoming-data listeners installed by the runtime (`resolveIncomingActionPayload`). */
|
|
1881
|
-
private readonly _incomingListeners;
|
|
1882
1538
|
private readonly _security?;
|
|
1883
1539
|
/** Normalized accepted levels; whether `none` (plain) is allowed; whether any level needs a handshake. */
|
|
1884
1540
|
private readonly _allowedLevels;
|
|
@@ -1888,37 +1544,19 @@ declare class ActionServerHandler<TConn = unknown> extends ActionExternalClientH
|
|
|
1888
1544
|
private readonly _clientByConn;
|
|
1889
1545
|
private readonly _connEncoding;
|
|
1890
1546
|
private readonly _codecByConn;
|
|
1891
|
-
private readonly
|
|
1892
|
-
|
|
1893
|
-
private readonly _authedConns;
|
|
1894
|
-
private readonly _plainConns;
|
|
1895
|
-
private readonly _inboundChainByConn;
|
|
1896
|
-
private readonly _outboundChainByConn;
|
|
1897
|
-
constructor(options: IActionServerHandlerOptions<TConn>);
|
|
1547
|
+
private readonly _sessionByConn;
|
|
1548
|
+
constructor(options: IAcceptorHandlerOptions<TConn>);
|
|
1898
1549
|
/**
|
|
1899
1550
|
* The codec for a connection: a per-connection session (cached) when a factory was provided, else
|
|
1900
1551
|
* the single shared `formatMessage`.
|
|
1901
1552
|
*/
|
|
1902
1553
|
private _codecFor;
|
|
1903
|
-
_setIncomingActionDataListener(listener: (json: TActionPayload_Any_JsonObject<any>) => void): void;
|
|
1904
1554
|
/**
|
|
1905
1555
|
* Register (or replace) the connection-bound persistence callback after construction. Used by
|
|
1906
1556
|
* lifecycle helpers like {@link createHibernatableWsServerAdapter} so persistence and replay are
|
|
1907
1557
|
* owned by one place instead of being split across the constructor options.
|
|
1908
1558
|
*/
|
|
1909
|
-
setOnConnectionBound(onConnectionBound: (connection: TConn, binding:
|
|
1910
|
-
/**
|
|
1911
|
-
* Create a typed per-connection state store that co-owns the consumer's app state and this handler's
|
|
1912
|
-
* routing binding in one attachment. It registers itself as the connection-bound persistence callback
|
|
1913
|
-
* (so bindings are written without overwriting app state) and immediately replays every live
|
|
1914
|
-
* connection's stored binding via {@link rehydrateConnection} — so on a transport that resumes after
|
|
1915
|
-
* eviction (e.g. a Durable Object waking from hibernation) both the app identity and the action
|
|
1916
|
-
* routing come back from a single attachment, with no storage reads and no hand-rolled merge.
|
|
1917
|
-
*
|
|
1918
|
-
* This supersedes {@link createHibernatableWsServerAdapter} for app code that also pins its own state
|
|
1919
|
-
* to the connection. Construct it once when the handler is built, then `get`/`set` app state directly.
|
|
1920
|
-
*/
|
|
1921
|
-
createConnectionState<TApp>(options: IWsConnectionStateStoreOptions<TConn, TApp>): WsConnectionStateStore<TConn, TApp>;
|
|
1559
|
+
setOnConnectionBound(onConnectionBound: (connection: TConn, binding: IAcceptorConnectionBinding) => void): void;
|
|
1922
1560
|
/**
|
|
1923
1561
|
* Feed one inbound frame from a connection into the runtime. Decodes text or binary, binds the
|
|
1924
1562
|
* connection to the requesting client's identity, then routes it (requests execute locally;
|
|
@@ -1926,8 +1564,16 @@ declare class ActionServerHandler<TConn = unknown> extends ActionExternalClientH
|
|
|
1926
1564
|
*/
|
|
1927
1565
|
receive(connection: TConn, frame: string | ArrayBuffer | Uint8Array): void;
|
|
1928
1566
|
private _receivePlain;
|
|
1929
|
-
|
|
1930
|
-
|
|
1567
|
+
/**
|
|
1568
|
+
* The secure session for a connection (built lazily on its first secure-mode frame), with the
|
|
1569
|
+
* handler-owned effects — raw send, identity binding + persistence, and inbound routing — wired in as
|
|
1570
|
+
* callbacks. The session owns all crypto/handshake/chain state; the handler keeps only the registry.
|
|
1571
|
+
*/
|
|
1572
|
+
private _sessionFor;
|
|
1573
|
+
/** Bind + persist a connection's authenticated identity once its handshake completes. */
|
|
1574
|
+
private _onConnectionAuthenticated;
|
|
1575
|
+
/** Decode a decrypted authenticated frame, inject the *authenticated* identity, and route it. */
|
|
1576
|
+
private _routeAuthedActionBytes;
|
|
1931
1577
|
/**
|
|
1932
1578
|
* Ensure an inbound request carries the client's identity and that this connection is bound to it,
|
|
1933
1579
|
* so its result can be routed back. A session codec omits `originClient` after the first request, so
|
|
@@ -1937,11 +1583,12 @@ declare class ActionServerHandler<TConn = unknown> extends ActionExternalClientH
|
|
|
1937
1583
|
private _resolveRequestIdentity;
|
|
1938
1584
|
/**
|
|
1939
1585
|
* Restore a connection→client binding without an inbound frame — for transports that resume after
|
|
1940
|
-
* eviction. Pair it with the {@link
|
|
1586
|
+
* eviction. Pair it with the {@link IAcceptorHandlerOptions.onConnectionBound} hook: persist
|
|
1941
1587
|
* the binding there, then replay each live connection here when the channel comes back (e.g. a
|
|
1942
1588
|
* Durable Object iterating `ctx.getWebSockets()` as it wakes from hibernation).
|
|
1943
1589
|
*/
|
|
1944
|
-
rehydrateConnection(connection: TConn, binding:
|
|
1590
|
+
rehydrateConnection(connection: TConn, binding: IAcceptorConnectionBinding): void;
|
|
1591
|
+
toJsonObject(): IActionHandler_Peer_Json;
|
|
1945
1592
|
toHandlerRouteItem(): IActionRouteItemHandler;
|
|
1946
1593
|
/** Forget a connection (call on socket close) so stale entries don't misroute later results. */
|
|
1947
1594
|
dropConnection(connection: TConn): void;
|
|
@@ -1964,7 +1611,14 @@ declare class ActionServerHandler<TConn = unknown> extends ActionExternalClientH
|
|
|
1964
1611
|
* runtime.addHandlers([serverHandler.forConnectionDomainCases(domain, { … }), serverHandler]);
|
|
1965
1612
|
* ```
|
|
1966
1613
|
*/
|
|
1967
|
-
forConnectionDomainCases<FOR_DOM extends IActionDomain>(domain: ActionDomain<FOR_DOM>, cases: { [ID in keyof FOR_DOM["actionSchema"] & string]?:
|
|
1614
|
+
forConnectionDomainCases<FOR_DOM extends IActionDomain>(domain: ActionDomain<FOR_DOM>, cases: { [ID in keyof FOR_DOM["actionSchema"] & string]?: TAcceptorConnectionCaseFn<FOR_DOM, ID, TConn> }): ActionLocalHandler;
|
|
1615
|
+
/**
|
|
1616
|
+
* Like {@link forConnectionDomainCases} but spanning several domains with one merged case map — used
|
|
1617
|
+
* by channel-derived wiring (`acceptChannelConnections`) where the channel's `toAcceptor` domains are
|
|
1618
|
+
* served together. Each domain takes only the cases whose ids it owns, so a single map can cover
|
|
1619
|
+
* several domains and unrelated ids are ignored.
|
|
1620
|
+
*/
|
|
1621
|
+
forConnectionDomainCasesMulti(domains: readonly ActionDomain<any>[], cases: Record<string, TAcceptorConnectionCaseFn<any, any, TConn> | undefined>): ActionLocalHandler;
|
|
1968
1622
|
/**
|
|
1969
1623
|
* Fan a server-initiated request out to every currently-bound connection. A fresh request is built
|
|
1970
1624
|
* per connection (each push mutates its own action context) and dispatched fire-and-forget. Pass
|
|
@@ -1989,9 +1643,248 @@ declare class ActionServerHandler<TConn = unknown> extends ActionExternalClientH
|
|
|
1989
1643
|
private _resolveConnection;
|
|
1990
1644
|
private _resolveSingleConnection;
|
|
1991
1645
|
}
|
|
1992
|
-
declare const
|
|
1646
|
+
declare const createAcceptorHandler: <TConn = unknown>(options: IAcceptorHandlerOptions<TConn>) => AcceptorHandler<TConn>;
|
|
1647
|
+
//#endregion
|
|
1648
|
+
//#region src/ActionRuntime/Transport/codec/createBinaryWireSessionFactory.d.ts
|
|
1649
|
+
type TFormatMessage = IActionWireFormat;
|
|
1650
|
+
interface IBinaryWireSessionOptions {
|
|
1651
|
+
/** Override how long an unresolved correlation is retained before being swept (ms). */
|
|
1652
|
+
correlationTtlMs?: number;
|
|
1653
|
+
}
|
|
1654
|
+
/**
|
|
1655
|
+
* Builds a factory of *stateful, per-connection* codecs for {@link LinkTransport} /
|
|
1656
|
+
* `AcceptorHandler` — the maximally compact binary wire. Call the returned factory once per live
|
|
1657
|
+
* connection (each socket on the client, each accepted connection on the server) so every channel
|
|
1658
|
+
* gets its own correlation + identity state.
|
|
1659
|
+
*
|
|
1660
|
+
* On top of everything {@link createBinaryWireAdapter} drops, a session also drops:
|
|
1661
|
+
* - **`cuid`** — replaced by a per-connection integer correlation id. The initiator maps it to its
|
|
1662
|
+
* real cuid; the responder echoes it; each side reconstructs the cuid from its own map. Correlation
|
|
1663
|
+
* only needs to be unique per socket, so a counter suffices.
|
|
1664
|
+
* - **`originClient` after the first request** — the first request each side sends carries its
|
|
1665
|
+
* identity; the peer remembers it and injects it into later frames. Replies omit it entirely (a
|
|
1666
|
+
* reply carries the initiator's own origin, which the initiator already knows).
|
|
1667
|
+
*
|
|
1668
|
+
* Both ends MUST build the factory from the same domains in the same order (positional dictionary).
|
|
1669
|
+
* Text frames still return `undefined` from `incoming`, so JSON clients remain interoperable.
|
|
1670
|
+
*
|
|
1671
|
+
* Hibernation note: after a server connection is evicted its session resets, so a still-connected
|
|
1672
|
+
* client (whose session persists) will keep omitting `originClient`. The server must therefore restore
|
|
1673
|
+
* the connection→client binding from its own store (see `AcceptorHandler.rehydrateConnection`) and
|
|
1674
|
+
* inject `originClient` from there — the session alone can't recover it.
|
|
1675
|
+
*/
|
|
1676
|
+
declare function createBinaryWireSessionFactory(domains: ActionDomain<any>[], options?: IBinaryWireSessionOptions): () => TFormatMessage;
|
|
1677
|
+
//#endregion
|
|
1678
|
+
//#region src/ActionRuntime/Channel/secureChannel.d.ts
|
|
1679
|
+
/** The per-connection binary session codec — built once per socket from the channel's domains. */
|
|
1680
|
+
type TChannelCodec = IActionWireFormat;
|
|
1681
|
+
/**
|
|
1682
|
+
* The shared identity of a secure channel (carrier-agnostic — WS, WebRTC, HTTP, …): the wire
|
|
1683
|
+
* dictionary version both ends check during the handshake, plus the per-connection codec factory both
|
|
1684
|
+
* ends build from the *same* domain list. Define it once (typically in code shared by both peers) and
|
|
1685
|
+
* hand it to `secureTransport` on the connector and `acceptChannel` / `createSecureAcceptorHandler` on
|
|
1686
|
+
* the acceptor, so the codec and version can never drift apart.
|
|
1687
|
+
*/
|
|
1688
|
+
interface ISecureChannel<TO_ACCEPTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[]> extends IActionChannel<TO_ACCEPTOR, TO_CONNECTOR> {
|
|
1689
|
+
/** Wire dictionary version — derived from the domains by default; the handshake rejects a mismatch. */
|
|
1690
|
+
dictionaryVersion: string;
|
|
1691
|
+
/** Per-connection session codec factory (call once per live connection). */
|
|
1692
|
+
createCodec: () => TChannelCodec;
|
|
1693
|
+
}
|
|
1694
|
+
/**
|
|
1695
|
+
* Bundle a secure channel's shared identity from its transported domains. Both ends MUST call this
|
|
1696
|
+
* with the same domains in the same order (the binary wire dictionary is positional). The
|
|
1697
|
+
* `dictionaryVersion` is derived from those domains unless you pin an explicit one.
|
|
1698
|
+
*
|
|
1699
|
+
* Declare the domains *by role* — `toAcceptor` (connector→acceptor requests) and `toConnector`
|
|
1700
|
+
* (acceptor→connector pushes) — so the routing for both ends is derived from the channel (see
|
|
1701
|
+
* {@link connectChannel} and `acceptChannelConnections`) instead of being restated at each end. The
|
|
1702
|
+
* wire dictionary spans `[...toAcceptor, ...toConnector]` in that order; add new domains to the end of
|
|
1703
|
+
* their list to keep older peers compatible. (`domains` is still accepted as a legacy alias for
|
|
1704
|
+
* `toAcceptor`.)
|
|
1705
|
+
*/
|
|
1706
|
+
declare function defineSecureChannel<const TO_ACCEPTOR extends readonly ActionDomain<any>[] = [], const TO_CONNECTOR extends readonly ActionDomain<any>[] = []>(options: {
|
|
1707
|
+
/** Domains the connector sends to the acceptor (connector→acceptor requests), in a stable order. */toAcceptor: TO_ACCEPTOR; /** Domains the acceptor pushes to the connector (acceptor→connector), in a stable order. */
|
|
1708
|
+
toConnector: TO_CONNECTOR; /** Pin a human-readable version instead of the derived hash (must match on both ends). */
|
|
1709
|
+
dictionaryVersion?: string; /** Tuning for the per-connection binary session (e.g. correlation TTL). */
|
|
1710
|
+
sessionOptions?: IBinaryWireSessionOptions;
|
|
1711
|
+
}): ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>;
|
|
1712
|
+
//#endregion
|
|
1713
|
+
//#region src/ActionRuntime/Channel/ActionChannel.d.ts
|
|
1714
|
+
/**
|
|
1715
|
+
* A transport-agnostic routing contract between two runtimes, declared *by role* rather than by
|
|
1716
|
+
* "client"/"server". The two ends are named for the only asymmetry that survives every carrier (WS,
|
|
1717
|
+
* WebRTC, BLE, raw TCP): which side dials and which side accepts.
|
|
1718
|
+
*
|
|
1719
|
+
* - The **connector** dials out and opens the link ({@link connectChannel}).
|
|
1720
|
+
* - The **acceptor** accepts incoming links and can push back ({@link acceptChannelConnections}).
|
|
1721
|
+
*
|
|
1722
|
+
* `toAcceptor` domains flow connector→acceptor (the classic "request"); `toConnector` domains flow
|
|
1723
|
+
* acceptor→connector (the classic "push"). Both ends derive their routing from the same channel instead
|
|
1724
|
+
* of restating domain lists — and because the contract is independent of how bytes move, the very same
|
|
1725
|
+
* channel can be carried over HTTP, secure WebSockets, or a mix (WS preferred, HTTP fallback).
|
|
1726
|
+
*
|
|
1727
|
+
* Build a plain one with {@link defineChannel}; layer wire-specific identity on top with
|
|
1728
|
+
* `defineSecureChannel` (which returns an `ISecureChannel` — still an `IActionChannel`, so it works
|
|
1729
|
+
* everywhere a channel is expected).
|
|
1730
|
+
*/
|
|
1731
|
+
interface IActionChannel<TO_ACCEPTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[]> {
|
|
1732
|
+
/**
|
|
1733
|
+
* Domains the connector *sends to the acceptor* (connector→acceptor requests). The connector forwards
|
|
1734
|
+
* them over its transport(s); the acceptor executes them.
|
|
1735
|
+
*/
|
|
1736
|
+
toAcceptorDomains: TO_ACCEPTOR;
|
|
1737
|
+
/**
|
|
1738
|
+
* Domains the acceptor *pushes to the connector* (acceptor→connector). The connector registers local
|
|
1739
|
+
* handlers for them ({@link connectChannel}'s `onPush`); the acceptor broadcasts them. Pushes need a
|
|
1740
|
+
* bidirectional transport (e.g. a WebSocket) — over a request-only transport like HTTP they simply
|
|
1741
|
+
* never flow.
|
|
1742
|
+
*/
|
|
1743
|
+
toConnectorDomains: TO_CONNECTOR;
|
|
1744
|
+
}
|
|
1745
|
+
/**
|
|
1746
|
+
* Declare a transport-agnostic channel by role. Use it for HTTP, custom transports, or as the routing
|
|
1747
|
+
* half of a richer channel. The order of each list is part of the contract for wire formats that pack
|
|
1748
|
+
* positionally (see `defineSecureChannel`) — add new domains to the end of their list. (`domains` is
|
|
1749
|
+
* accepted as a legacy alias for `toAcceptor`.)
|
|
1750
|
+
*/
|
|
1751
|
+
declare function defineChannel<const TO_ACCEPTOR extends readonly ActionDomain<any>[] = [], const TO_CONNECTOR extends readonly ActionDomain<any>[] = []>(options: {
|
|
1752
|
+
toAcceptor: TO_ACCEPTOR;
|
|
1753
|
+
toConnector: TO_CONNECTOR;
|
|
1754
|
+
}): IActionChannel<TO_ACCEPTOR, TO_CONNECTOR>;
|
|
1755
|
+
type TUnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
1756
|
+
type TDomainPushHandlers<D> = D extends ActionDomain<infer DEF> ? Partial<TWrappableDomainActionHandler<DEF>> : never;
|
|
1757
|
+
/**
|
|
1758
|
+
* The `onPush` map for a channel: the merged set of every acceptor→connector (`toConnector`) action
|
|
1759
|
+
* handler, each receiving the pushed action's input. Derived from the channel's `toConnectorDomains`, so
|
|
1760
|
+
* the keys and input types follow the channel definition.
|
|
1761
|
+
*/
|
|
1762
|
+
type TChannelPushHandlers<TO_CONNECTOR extends readonly ActionDomain<any>[]> = TUnionToIntersection<TDomainPushHandlers<TO_CONNECTOR[number]>>;
|
|
1763
|
+
interface IConnectChannelOptions<TO_ACCEPTOR extends readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[]> {
|
|
1764
|
+
/** The shared channel — its `toAcceptorDomains`/`toConnectorDomains` drive all routing. */
|
|
1765
|
+
channel: IActionChannel<TO_ACCEPTOR, TO_CONNECTOR>;
|
|
1766
|
+
/**
|
|
1767
|
+
* Transports to the acceptor, in preference order (e.g. `[wsTransport, httpFallback]`). They all carry
|
|
1768
|
+
* the same `toAcceptor` domains; the manager prefers the first that's ready and falls through on
|
|
1769
|
+
* failure — so connector→acceptor works over whatever transport is available, WS or HTTP.
|
|
1770
|
+
*/
|
|
1771
|
+
transports: Transport[];
|
|
1772
|
+
/** Handlers for the channel's acceptor→connector pushes. Optional — omit for a send-only connection. */
|
|
1773
|
+
onPush?: TChannelPushHandlers<TO_CONNECTOR>;
|
|
1774
|
+
/** Default per-action timeout for this connection. */
|
|
1775
|
+
defaultTimeout?: number;
|
|
1776
|
+
}
|
|
1777
|
+
/**
|
|
1778
|
+
* Wire a connection to the acceptor straight from a channel: route the channel's `toAcceptor` domains to
|
|
1779
|
+
* the acceptor over `transports`, and register local handlers for its `toConnector` pushes from
|
|
1780
|
+
* `onPush`. The channel is the single source of truth for *what* is routed in each direction — the
|
|
1781
|
+
* caller only supplies the transport(s) and the push handlers, never restated domain lists. Pass several
|
|
1782
|
+
* transports to make the connector→acceptor path transport-agnostic (e.g. secure WS preferred, HTTP
|
|
1783
|
+
* fallback).
|
|
1784
|
+
*
|
|
1785
|
+
* Sugar over {@link ActionRuntime.connectTo}. Returns the acceptor handler so the caller can later
|
|
1786
|
+
* `clearTransportCache()` it.
|
|
1787
|
+
*/
|
|
1788
|
+
declare function connectChannel<TO_ACCEPTOR extends readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[]>(runtime: ActionRuntime, acceptorCoordinate: RuntimeCoordinate, options: IConnectChannelOptions<TO_ACCEPTOR, TO_CONNECTOR>): ConnectorHandler;
|
|
1789
|
+
type TDomainAcceptorCases<D, TConn> = D extends ActionDomain<infer DEF> ? { [ID in keyof DEF["actionSchema"] & string]?: TAcceptorConnectionCaseFn<DEF, ID, TConn> } : never;
|
|
1790
|
+
/**
|
|
1791
|
+
* The connection-aware case map for a channel's acceptor side: the merged set of every
|
|
1792
|
+
* connector→acceptor (`toAcceptor`) action handler, each receiving the primed request plus the
|
|
1793
|
+
* originating connection. Derived from the channel's `toAcceptorDomains`, so the keys and input/output
|
|
1794
|
+
* types follow the channel.
|
|
1795
|
+
*/
|
|
1796
|
+
type TChannelAcceptorCases<TO_ACCEPTOR extends readonly ActionDomain<any>[], TConn> = TUnionToIntersection<TDomainAcceptorCases<TO_ACCEPTOR[number], TConn>>;
|
|
1797
|
+
/**
|
|
1798
|
+
* Register an acceptor handler's execution for a channel straight from its definition: the channel's
|
|
1799
|
+
* `toAcceptor` domains are served together with one merged, connection-aware case map (each case gets
|
|
1800
|
+
* the primed request + the originating connection, as with
|
|
1801
|
+
* {@link AcceptorHandler.forConnectionDomainCases}). The domain list is taken from the channel,
|
|
1802
|
+
* never restated. Add the returned handler to the runtime alongside the acceptor handler:
|
|
1803
|
+
* ```ts
|
|
1804
|
+
* runtime.addHandlers([acceptChannelConnections(serverHandler, channel, { … }), serverHandler]);
|
|
1805
|
+
* ```
|
|
1806
|
+
*/
|
|
1807
|
+
declare function acceptChannelConnections<TO_ACCEPTOR extends readonly ActionDomain<any>[], TConn>(serverHandler: AcceptorHandler<TConn>, channel: IActionChannel<TO_ACCEPTOR, any>, cases: TChannelAcceptorCases<TO_ACCEPTOR, TConn>): ActionLocalHandler;
|
|
1808
|
+
interface IAcceptChannelOptions<TConn> {
|
|
1809
|
+
/**
|
|
1810
|
+
* Coordinate of the *connecting clients* (typically env-only, e.g. `RuntimeCoordinate.env("web_app")`),
|
|
1811
|
+
* used to score return-path dispatch back to the right connection.
|
|
1812
|
+
*/
|
|
1813
|
+
clientEnv: RuntimeCoordinate;
|
|
1814
|
+
/**
|
|
1815
|
+
* One backing store for the acceptor's crypto identity *and* its trust-on-first-use verify-key pins
|
|
1816
|
+
* (their keys don't collide). Back it with persistent storage so identity + pins survive eviction.
|
|
1817
|
+
*/
|
|
1818
|
+
storageAdapter: StorageAdapter;
|
|
1819
|
+
/** Write an encoded frame to a specific live connection (e.g. `(ws, frame) => ws.send(frame)`). */
|
|
1820
|
+
send: (connection: TConn, frame: string | Uint8Array | ArrayBuffer) => void;
|
|
1821
|
+
/** Accepted level(s); defaults to negotiating any of none/authenticated/encrypted. */
|
|
1822
|
+
securityLevel?: ESecurityLevel | readonly ESecurityLevel[];
|
|
1823
|
+
/** Trust decision for a client's verify key; defaults to storage-backed TOFU over `storageAdapter`. */
|
|
1824
|
+
verifyKeyResolver?: IClientVerifyKeyResolver;
|
|
1825
|
+
/** Timeout (ms) applied to acceptor-initiated actions awaiting a client response. */
|
|
1826
|
+
defaultTimeout?: number;
|
|
1827
|
+
}
|
|
1828
|
+
/**
|
|
1829
|
+
* Build the secure {@link AcceptorHandler} for a channel — the accept-in counterpart to
|
|
1830
|
+
* {@link connectChannel}. It folds in the same boilerplate as {@link createSecureAcceptorHandler} (the
|
|
1831
|
+
* `ClientCryptoKeyLink` + storage-backed TOFU resolver from one `storageAdapter`, the channel's codec +
|
|
1832
|
+
* dictionary version, the `security` block from the runtime coordinate) but takes the `(runtime, channel,
|
|
1833
|
+
* options)` shape of the channel family. Pair it with {@link acceptChannelConnections} for execution:
|
|
1834
|
+
* ```ts
|
|
1835
|
+
* const acceptor = acceptChannel(runtime, gameChannel, { clientEnv, storageAdapter, send });
|
|
1836
|
+
* runtime.addHandlers([acceptChannelConnections(acceptor, gameChannel, { … }), acceptor]);
|
|
1837
|
+
* ```
|
|
1838
|
+
*/
|
|
1839
|
+
declare function acceptChannel<TO_ACCEPTOR extends readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[], TConn = unknown>(runtime: ActionRuntime, channel: ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>, options: IAcceptChannelOptions<TConn>): AcceptorHandler<TConn>;
|
|
1840
|
+
//#endregion
|
|
1841
|
+
//#region src/ActionRuntime/Transport/SecureSession/exchangeAcceptor.d.ts
|
|
1842
|
+
/** Acceptor secure config for the exchange (HTTP) endpoint — same identity an `AcceptorHandler` uses. */
|
|
1843
|
+
interface IExchangeAcceptorSecurity {
|
|
1844
|
+
/** This acceptor's crypto identity (verify + exchange key pairs, optionally persisted). */
|
|
1845
|
+
link: ClientCryptoKeyLink;
|
|
1846
|
+
/** This acceptor's coordinate — its identity to clients during the handshake. */
|
|
1847
|
+
localCoordinate: IRuntimeCoordinate;
|
|
1848
|
+
/** Wire dictionary version; the handshake rejects a client on a mismatch. */
|
|
1849
|
+
dictionaryVersion: string;
|
|
1850
|
+
/** Accepted level(s) — a single level is strict, an array is a negotiable allowed set. */
|
|
1851
|
+
securityLevel: ESecurityLevel | readonly ESecurityLevel[];
|
|
1852
|
+
/** Trust decision for a client's verify key (defaults to in-memory TOFU inside the handshake). */
|
|
1853
|
+
verifyKeyResolver?: IClientVerifyKeyResolver;
|
|
1854
|
+
}
|
|
1855
|
+
interface IExchangeAcceptorConfig {
|
|
1856
|
+
security: IExchangeAcceptorSecurity;
|
|
1857
|
+
/** The runtime that executes an inbound action wire and produces its result. */
|
|
1858
|
+
runtime: ActionRuntime;
|
|
1859
|
+
}
|
|
1860
|
+
/**
|
|
1861
|
+
* Acceptor (accept-in) side of the secure exchange protocol — the HTTP counterpart to
|
|
1862
|
+
* {@link AcceptorSecureSession}. Each POST body is one {@link decodeExchangeRequest} envelope; the
|
|
1863
|
+
* acceptor drives the server handshake over the two `hs` POSTs (correlated by `hsid`, since stateless
|
|
1864
|
+
* requests can't rely on channel ordering), mints a session **token** on accept, and on every later `act`
|
|
1865
|
+
* POST resolves the session by token, decrypts the body (at `encrypted`), routes it through the runtime,
|
|
1866
|
+
* and returns the (encrypted) result inline as the reply.
|
|
1867
|
+
*
|
|
1868
|
+
* Sessions and in-flight handshakes are held in memory — fine for a single-instance server. (Surviving a
|
|
1869
|
+
* Durable-Object eviction would persist each token's `keyMaterial` and re-derive the key on a miss, the
|
|
1870
|
+
* same primitive `AcceptorSecureSession.rehydrate` uses; left as a follow-up.)
|
|
1871
|
+
*/
|
|
1872
|
+
declare class ExchangeAcceptor {
|
|
1873
|
+
private readonly _security;
|
|
1874
|
+
private readonly _runtime;
|
|
1875
|
+
private readonly _allowedLevels;
|
|
1876
|
+
private readonly _noneAllowed;
|
|
1877
|
+
private readonly _pendingHandshakes;
|
|
1878
|
+
private readonly _sessions;
|
|
1879
|
+
constructor(config: IExchangeAcceptorConfig);
|
|
1880
|
+
/** Process one POST body (an exchange envelope), returning the reply body to send back. */
|
|
1881
|
+
handlePost(body: string): Promise<string>;
|
|
1882
|
+
private _handleHandshake;
|
|
1883
|
+
private _handleAction;
|
|
1884
|
+
private _err;
|
|
1885
|
+
}
|
|
1993
1886
|
//#endregion
|
|
1994
|
-
//#region src/ActionRuntime/Handler/
|
|
1887
|
+
//#region src/ActionRuntime/Handler/PeerLink/Acceptor/createActionFetchHandler.d.ts
|
|
1995
1888
|
interface IActionFetchHandlerOptions {
|
|
1996
1889
|
/**
|
|
1997
1890
|
* CORS headers merged onto every response (a preflight `OPTIONS` is answered `204` with them).
|
|
@@ -2010,6 +1903,13 @@ interface IActionFetchHandlerOptions {
|
|
|
2010
1903
|
onWebSocketUpgrade?: (request: Request, url: URL) => Response | Promise<Response>;
|
|
2011
1904
|
/** Forwarded to `ActionPayload_Result.toHttpResponse` — use the error's HTTP status (default true). */
|
|
2012
1905
|
useErrorStatus?: boolean;
|
|
1906
|
+
/**
|
|
1907
|
+
* Enable the secure exchange protocol (handshake + token sessions + body encryption) on the `/action`
|
|
1908
|
+
* endpoint, mirroring an `AcceptorHandler`'s `security`. The matching connector is
|
|
1909
|
+
* `secureTransport({ carrier: httpCarrier(...), securityLevel })`. When omitted, the endpoint speaks
|
|
1910
|
+
* today's plain protocol (the raw action wire is POSTed and the result is the response body).
|
|
1911
|
+
*/
|
|
1912
|
+
security?: IExchangeAcceptorSecurity;
|
|
2013
1913
|
}
|
|
2014
1914
|
/**
|
|
2015
1915
|
* Build the `fetch` handler a server/Durable-Object exposes for action traffic, folding in the
|
|
@@ -2032,10 +1932,10 @@ interface IActionFetchHandlerOptions {
|
|
|
2032
1932
|
*/
|
|
2033
1933
|
declare function createActionFetchHandler(runtime: ActionRuntime, options?: IActionFetchHandlerOptions): (request: Request) => Promise<Response>;
|
|
2034
1934
|
//#endregion
|
|
2035
|
-
//#region src/ActionRuntime/Handler/
|
|
2036
|
-
interface
|
|
1935
|
+
//#region src/ActionRuntime/Handler/PeerLink/Acceptor/createSecureActionServer.d.ts
|
|
1936
|
+
interface ISecureAcceptorHandlerOptions<TConn> {
|
|
2037
1937
|
/** The shared channel identity (codec + dictionary version) — same one the clients use. */
|
|
2038
|
-
channel:
|
|
1938
|
+
channel: ISecureChannel;
|
|
2039
1939
|
/**
|
|
2040
1940
|
* Coordinate of the *connecting clients* (typically env-only, e.g. `RuntimeCoordinate.env("web_app")`),
|
|
2041
1941
|
* used to route results/pushes back over this handler.
|
|
@@ -2059,24 +1959,108 @@ interface ISecureActionServerHandlerOptions<TConn> {
|
|
|
2059
1959
|
defaultTimeout?: number;
|
|
2060
1960
|
}
|
|
2061
1961
|
/**
|
|
2062
|
-
* Build an {@link
|
|
2063
|
-
* it creates the {@link ClientCryptoKeyLink} and the storage-backed TOFU resolver from a single
|
|
2064
|
-
* `storageAdapter`, installs the channel's per-connection codec, and assembles the `security` block
|
|
2065
|
-
* from the runtime coordinate + channel version (accepting all three levels by default).
|
|
1962
|
+
* Build an {@link AcceptorHandler} for the secure binary channel with the boilerplate folded in:
|
|
1963
|
+
* it creates the {@link ClientCryptoKeyLink} and the storage-backed TOFU resolver from a single
|
|
1964
|
+
* `storageAdapter`, installs the channel's per-connection codec, and assembles the `security` block
|
|
1965
|
+
* from the runtime coordinate + channel version (accepting all three levels by default).
|
|
1966
|
+
*
|
|
1967
|
+
* For a hibernatable transport (e.g. a Durable Object), pair it with
|
|
1968
|
+
* {@link createHibernatableWsServerAdapter} to wire persistence + replay.
|
|
1969
|
+
*/
|
|
1970
|
+
declare function createSecureAcceptorHandler<TConn = unknown>(options: ISecureAcceptorHandlerOptions<TConn>): AcceptorHandler<TConn>;
|
|
1971
|
+
//#endregion
|
|
1972
|
+
//#region src/ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/ConnectionStateStore.d.ts
|
|
1973
|
+
/**
|
|
1974
|
+
* The composite value persisted to a connection's attachment: the consumer's own app state plus the
|
|
1975
|
+
* {@link AcceptorHandler} routing binding. Co-storing them in one slot means a transport whose
|
|
1976
|
+
* sockets outlive process eviction (e.g. a Durable Object's hibernatable WebSocket) recovers both the
|
|
1977
|
+
* application identity *and* the action routing from a single attachment after a wake — no storage reads.
|
|
1978
|
+
*/
|
|
1979
|
+
interface IConnectionAttachment<TApp> {
|
|
1980
|
+
app?: TApp;
|
|
1981
|
+
binding?: IAcceptorConnectionBinding;
|
|
1982
|
+
}
|
|
1983
|
+
interface IConnectionStateStoreOptions<TConn, TApp> {
|
|
1984
|
+
/** Read a connection's raw attachment (e.g. `(ws) => ws.deserializeAttachment()`). */
|
|
1985
|
+
read: (connection: TConn) => unknown;
|
|
1986
|
+
/** Persist a connection's attachment (e.g. `(ws, value) => ws.serializeAttachment(value)`). */
|
|
1987
|
+
write: (connection: TConn, value: IConnectionAttachment<TApp>) => void;
|
|
1988
|
+
/**
|
|
1989
|
+
* All currently-live connections (e.g. `() => ctx.getWebSockets()`). Used to replay routing bindings
|
|
1990
|
+
* after a wake (via {@link createConnectionStateStore}) and to enumerate app state in
|
|
1991
|
+
* {@link ConnectionStateStore.entries}.
|
|
1992
|
+
*/
|
|
1993
|
+
getConnections: () => TConn[];
|
|
1994
|
+
/**
|
|
1995
|
+
* Optional Standard Schema (valibot, zod, …) validating the *app* portion on read. A value that
|
|
1996
|
+
* fails validation reads back as `null` — the same lenient behavior as a hand-written safeParse
|
|
1997
|
+
* helper. The binding is the library's own shape and is never validated.
|
|
1998
|
+
*/
|
|
1999
|
+
schema?: StandardSchemaV1<unknown, TApp>;
|
|
2000
|
+
}
|
|
2001
|
+
/**
|
|
2002
|
+
* A typed per-connection state store that co-owns the app state and the acceptor handler's routing
|
|
2003
|
+
* binding in one attachment, so neither the consumer nor the handler has to hand-merge the two. Create
|
|
2004
|
+
* it through {@link createConnectionStateStore} (which also wires binding persistence and replays
|
|
2005
|
+
* surviving connections after a wake), then `get`/`set`/`clearApp` the app state directly.
|
|
2006
|
+
*
|
|
2007
|
+
* The mechanism is carrier-neutral — it only needs read/write/enumerate callbacks for the connection's
|
|
2008
|
+
* attachment — but it pays off on transports whose connections outlive process eviction (e.g. a
|
|
2009
|
+
* Durable Object's hibernatable WebSockets), which is why it lives beside the hibernation adapter.
|
|
2010
|
+
*
|
|
2011
|
+
* ```ts
|
|
2012
|
+
* const players = createConnectionStateStore(serverHandler, {
|
|
2013
|
+
* schema: vs_player,
|
|
2014
|
+
* read: (ws) => ws.deserializeAttachment(),
|
|
2015
|
+
* write: (ws, v) => ws.serializeAttachment(v),
|
|
2016
|
+
* getConnections: () => ctx.getWebSockets(),
|
|
2017
|
+
* });
|
|
2018
|
+
* players.set(ws, player); // binding is preserved automatically
|
|
2019
|
+
* const player = players.get(ws);
|
|
2020
|
+
* ```
|
|
2021
|
+
*/
|
|
2022
|
+
declare class ConnectionStateStore<TConn, TApp> {
|
|
2023
|
+
private readonly options;
|
|
2024
|
+
constructor(options: IConnectionStateStoreOptions<TConn, TApp>);
|
|
2025
|
+
/** The validated app state for a connection, or `null` if unset / invalid. */
|
|
2026
|
+
get(connection: TConn): TApp | null;
|
|
2027
|
+
/** Set the app state, preserving the runtime binding already pinned to the connection. */
|
|
2028
|
+
set(connection: TConn, app: TApp): void;
|
|
2029
|
+
/** Clear the app state but keep the binding (e.g. a spectator that stopped watching). */
|
|
2030
|
+
clearApp(connection: TConn): void;
|
|
2031
|
+
/** Every live connection paired with its (validated) app state — for rebuilding in-memory state after a wake. */
|
|
2032
|
+
entries(): [TConn, TApp | null][];
|
|
2033
|
+
/** @internal Persist a freshly-bound connection's binding, preserving any app state already stored. */
|
|
2034
|
+
_persistBinding(connection: TConn, binding: IAcceptorConnectionBinding): void;
|
|
2035
|
+
/** @internal The persisted binding for a connection, if any (used to replay routing after a wake). */
|
|
2036
|
+
_readBinding(connection: TConn): IAcceptorConnectionBinding | undefined;
|
|
2037
|
+
private _readAttachment;
|
|
2038
|
+
private _validateApp;
|
|
2039
|
+
}
|
|
2040
|
+
/**
|
|
2041
|
+
* Build a per-connection {@link ConnectionStateStore} bound to an {@link AcceptorHandler}: it registers
|
|
2042
|
+
* itself as the handler's connection-bound persistence callback (so bindings are written without
|
|
2043
|
+
* overwriting app state) and immediately replays every live connection's stored binding via
|
|
2044
|
+
* {@link AcceptorHandler.rehydrateConnection} — so on a transport that resumes after eviction (e.g. a
|
|
2045
|
+
* Durable Object waking from hibernation) both the app identity and the action routing come back from a
|
|
2046
|
+
* single attachment, with no storage reads and no hand-rolled merge.
|
|
2066
2047
|
*
|
|
2067
|
-
*
|
|
2068
|
-
*
|
|
2048
|
+
* Lives outside the handler so the generic {@link AcceptorHandler} stays free of any attachment/
|
|
2049
|
+
* hibernation concern — it exposes only the neutral `setOnConnectionBound` + `rehydrateConnection`
|
|
2050
|
+
* hooks this builder drives.
|
|
2069
2051
|
*/
|
|
2070
|
-
declare function
|
|
2052
|
+
declare function createConnectionStateStore<TConn, TApp>(handler: AcceptorHandler<TConn>, options: IConnectionStateStoreOptions<TConn, TApp>): ConnectionStateStore<TConn, TApp>;
|
|
2053
|
+
//#endregion
|
|
2054
|
+
//#region src/ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/createHibernatableWsServerAdapter.d.ts
|
|
2071
2055
|
interface IHibernatableWsServerAdapterOptions<TConn> {
|
|
2072
|
-
/** The handler to drive (from
|
|
2073
|
-
handler:
|
|
2056
|
+
/** The handler to drive (from `createSecureAcceptorHandler` or `createAcceptorHandler`). */
|
|
2057
|
+
handler: AcceptorHandler<TConn>;
|
|
2074
2058
|
/** All currently-live connections — replayed on construction to rebuild bindings after a wake. */
|
|
2075
2059
|
getWebSockets: () => TConn[];
|
|
2076
2060
|
/** Read a connection's persisted binding (e.g. `(ws) => ws.deserializeAttachment()`). */
|
|
2077
|
-
getAttachment: (connection: TConn) =>
|
|
2061
|
+
getAttachment: (connection: TConn) => IAcceptorConnectionBinding | undefined;
|
|
2078
2062
|
/** Persist a connection's binding when it is bound (e.g. `(ws, b) => ws.serializeAttachment(b)`). */
|
|
2079
|
-
setAttachment: (connection: TConn, binding:
|
|
2063
|
+
setAttachment: (connection: TConn, binding: IAcceptorConnectionBinding) => void;
|
|
2080
2064
|
}
|
|
2081
2065
|
interface IHibernatableWsServerAdapter<TConn> {
|
|
2082
2066
|
/** Feed one inbound frame from a connection into the handler. */
|
|
@@ -2085,11 +2069,15 @@ interface IHibernatableWsServerAdapter<TConn> {
|
|
|
2085
2069
|
drop: (connection: TConn) => void;
|
|
2086
2070
|
}
|
|
2087
2071
|
/**
|
|
2088
|
-
* Wire the hibernation lifecycle for
|
|
2072
|
+
* Wire the hibernation lifecycle for an acceptor handler on a transport whose sockets outlive process
|
|
2089
2073
|
* eviction (e.g. a Durable Object's hibernatable WebSockets). It owns persistence end to end:
|
|
2090
2074
|
* registers `setAttachment` as the handler's connection-bound callback and immediately replays every
|
|
2091
2075
|
* live connection's stored binding via `getAttachment`, so results/pushes still route after a wake.
|
|
2092
2076
|
*
|
|
2077
|
+
* Layered on top of the generic {@link AcceptorHandler} — it touches only the handler's neutral
|
|
2078
|
+
* `setOnConnectionBound` / `rehydrateConnection` / `receive` / `dropConnection` surface, so no
|
|
2079
|
+
* hibernation concern leaks into the handler itself.
|
|
2080
|
+
*
|
|
2093
2081
|
* Construct it once when the handler is built, then forward socket events:
|
|
2094
2082
|
* ```ts
|
|
2095
2083
|
* const wsServer = createHibernatableWsServerAdapter({ handler, getWebSockets, getAttachment, setAttachment });
|
|
@@ -2099,6 +2087,529 @@ interface IHibernatableWsServerAdapter<TConn> {
|
|
|
2099
2087
|
*/
|
|
2100
2088
|
declare function createHibernatableWsServerAdapter<TConn>(options: IHibernatableWsServerAdapterOptions<TConn>): IHibernatableWsServerAdapter<TConn>;
|
|
2101
2089
|
//#endregion
|
|
2090
|
+
//#region src/ActionRuntime/Handler/PeerLink/Connector/err_nice_external_client.d.ts
|
|
2091
|
+
declare const err_nice_external_client: import("@nice-code/error").NiceErrorDomain<{
|
|
2092
|
+
domain: string;
|
|
2093
|
+
allDomains: [string, string, "err_nice"];
|
|
2094
|
+
schema: {};
|
|
2095
|
+
}>;
|
|
2096
|
+
//#endregion
|
|
2097
|
+
//#region src/ActionRuntime/Transport/Carrier/Carrier.types.d.ts
|
|
2098
|
+
/**
|
|
2099
|
+
* Carrier shapes — the only transport-specific surface a new protocol must implement. The secure
|
|
2100
|
+
* session (handshake + frame crypto + codec) and the action routing on top of it are carrier-agnostic;
|
|
2101
|
+
* a carrier just moves frames. Two shapes capture every carrier:
|
|
2102
|
+
*
|
|
2103
|
+
* - {@link IDuplexCarrier} — a persistent, push-capable byte stream (WebSocket, WebRTC `RTCDataChannel`,
|
|
2104
|
+
* Bluetooth GATT, an in-memory pipe). Either side can send at any time, so it supports server→client
|
|
2105
|
+
* pushes (the return path + broadcast).
|
|
2106
|
+
* - {@link IExchangeCarrier} — a request → single-correlated-reply carrier with no unsolicited push
|
|
2107
|
+
* (HTTP, and anything request/response-shaped). The reply rides the response to its own request.
|
|
2108
|
+
*
|
|
2109
|
+
* Frames are `string` (text — handshake control messages and JSON action frames) or binary
|
|
2110
|
+
* (`Uint8Array`/`ArrayBuffer` — the optimized binary wire / encrypted frames).
|
|
2111
|
+
*/
|
|
2112
|
+
type TFrame$1 = string | Uint8Array | ArrayBuffer;
|
|
2113
|
+
/**
|
|
2114
|
+
* A bidirectional, push-capable byte stream. Reduces every duplex carrier to "open, send bytes, receive
|
|
2115
|
+
* bytes, close" — a WebSocket, a WebRTC data channel, a Bluetooth characteristic, or an in-memory pipe
|
|
2116
|
+
* all satisfy this, so the identical secure session runs over each.
|
|
2117
|
+
*/
|
|
2118
|
+
interface IDuplexCarrier {
|
|
2119
|
+
/** Resolves once the carrier is open and ready to send; rejects if it closes/errors before opening. */
|
|
2120
|
+
readonly ready: Promise<void>;
|
|
2121
|
+
/** Whether the carrier is currently open (a synchronous guard before `send`). */
|
|
2122
|
+
isOpen(): boolean;
|
|
2123
|
+
/** Write one frame to the peer. */
|
|
2124
|
+
send(frame: TFrame$1): void;
|
|
2125
|
+
/**
|
|
2126
|
+
* Register the carrier's handlers. Called exactly once by the session after `ready`. `onMessage`
|
|
2127
|
+
* receives every inbound frame; `onClose` fires when the carrier goes away.
|
|
2128
|
+
*/
|
|
2129
|
+
attach(handlers: {
|
|
2130
|
+
onMessage: (frame: TFrame$1) => void;
|
|
2131
|
+
onClose: () => void;
|
|
2132
|
+
onError?: (error: unknown) => void;
|
|
2133
|
+
}): void;
|
|
2134
|
+
/** Close the carrier deliberately (a teardown). */
|
|
2135
|
+
close(): void;
|
|
2136
|
+
/** Optional human-readable endpoint for the devtools route chip. */
|
|
2137
|
+
readonly label?: string;
|
|
2138
|
+
}
|
|
2139
|
+
/**
|
|
2140
|
+
* A request → single-correlated-reply carrier with no unsolicited push (HTTP). One `exchange` sends a
|
|
2141
|
+
* frame and resolves with exactly the one reply frame for it; the carrier itself correlates them (the
|
|
2142
|
+
* HTTP transaction), so no correlation id is needed on the wire.
|
|
2143
|
+
*/
|
|
2144
|
+
interface IExchangeCarrier {
|
|
2145
|
+
/** Send one frame, await the single correlated reply frame. */
|
|
2146
|
+
exchange(frame: TFrame$1, opts?: {
|
|
2147
|
+
signal?: AbortSignal;
|
|
2148
|
+
}): Promise<TFrame$1>;
|
|
2149
|
+
/** Optional human-readable endpoint for the devtools route chip. */
|
|
2150
|
+
readonly label?: string;
|
|
2151
|
+
}
|
|
2152
|
+
type TCarrier = IDuplexCarrier | IExchangeCarrier;
|
|
2153
|
+
/**
|
|
2154
|
+
* A reusable opener for a {@link IDuplexCarrier} plus the per-action metadata a duplex transport needs.
|
|
2155
|
+
* Built by the small carrier factories (`wsCarrier`, `rtcCarrier`, `inMemoryCarrier`) and handed to
|
|
2156
|
+
* {@link secureTransport} / `LinkTransport` — so adding a new carrier is "write one of these", nothing
|
|
2157
|
+
* else.
|
|
2158
|
+
*/
|
|
2159
|
+
interface IDuplexCarrierSource {
|
|
2160
|
+
/** Open (or reuse) the carrier for an action. */
|
|
2161
|
+
open: (input: ITransportRouteActionParams) => IDuplexCarrier;
|
|
2162
|
+
/** Keys identifying a reusable carrier, so one carrier is shared across actions to the same peer. */
|
|
2163
|
+
getCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
2164
|
+
/** Devtools route info for an action routed over this carrier. */
|
|
2165
|
+
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
2166
|
+
/** Short carrier-kind label for the devtools chip (e.g. `"ws"`, `"webrtc"`, `"memory"`). */
|
|
2167
|
+
readonly carrierLabel: string;
|
|
2168
|
+
}
|
|
2169
|
+
/**
|
|
2170
|
+
* The exchange-shape counterpart to {@link IDuplexCarrierSource}: a reusable opener for an
|
|
2171
|
+
* {@link IExchangeCarrier} plus the per-action metadata an exchange transport needs. Built by
|
|
2172
|
+
* `httpCarrier` and handed to {@link secureTransport} — adding a new request/reply protocol is "write
|
|
2173
|
+
* one of these". The `shape` tag lets {@link secureTransport} pick the duplex vs exchange transport.
|
|
2174
|
+
*/
|
|
2175
|
+
interface IExchangeCarrierSource {
|
|
2176
|
+
/** Discriminant so a generic factory can tell an exchange source from a duplex one. */
|
|
2177
|
+
readonly shape: "exchange";
|
|
2178
|
+
/** Open (or reuse) the carrier for an action. */
|
|
2179
|
+
open: (input: ITransportRouteActionParams) => IExchangeCarrier;
|
|
2180
|
+
/** Keys identifying a reusable carrier, so one carrier is shared across actions to the same peer. */
|
|
2181
|
+
getCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
2182
|
+
/** Devtools route info for an action routed over this carrier. */
|
|
2183
|
+
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
2184
|
+
/** Short carrier-kind label for the devtools chip (e.g. `"http"`). */
|
|
2185
|
+
readonly carrierLabel: string;
|
|
2186
|
+
}
|
|
2187
|
+
//#endregion
|
|
2188
|
+
//#region src/ActionRuntime/Transport/Carrier/duplex/inMemory/createInMemoryChannel.d.ts
|
|
2189
|
+
type TFrame = string | ArrayBuffer | Uint8Array;
|
|
2190
|
+
/** The peer (server) end of an in-memory pair — what you feed into an `AcceptorHandler`. */
|
|
2191
|
+
interface IInMemoryServerEndpoint {
|
|
2192
|
+
/** Write a frame back to the client end. */
|
|
2193
|
+
send(frame: TFrame): void;
|
|
2194
|
+
/** Register the inbound handler (frames the client sent). */
|
|
2195
|
+
onMessage(handler: (frame: TFrame) => void): void;
|
|
2196
|
+
/** Close the pair from this end. */
|
|
2197
|
+
close(): void;
|
|
2198
|
+
/** Notified when the pair closes (from either end). */
|
|
2199
|
+
onClose(handler: () => void): void;
|
|
2200
|
+
}
|
|
2201
|
+
interface IInMemoryChannelPair {
|
|
2202
|
+
/** The client end — pass as a {@link IDuplexCarrier} to a `LinkTransport`. */
|
|
2203
|
+
clientChannel: IDuplexCarrier;
|
|
2204
|
+
/** The server end — wire into an `AcceptorHandler` (`send` + `receive`). */
|
|
2205
|
+
serverEndpoint: IInMemoryServerEndpoint;
|
|
2206
|
+
}
|
|
2207
|
+
/**
|
|
2208
|
+
* Two cross-wired in-process byte channels — a loopback carrier with no socket. The client end is a
|
|
2209
|
+
* {@link IDuplexCarrier} you hand to a {@link LinkTransport}; the server end plugs into an
|
|
2210
|
+
* `AcceptorHandler` (`send: (_, f) => serverEndpoint.send(f)`, and `serverEndpoint.onMessage(f =>
|
|
2211
|
+
* handler.receive(conn, f))`). Frames are delivered on a microtask, so each side observes the other
|
|
2212
|
+
* asynchronously — exactly like a real transport — which makes this ideal for tests and for running
|
|
2213
|
+
* two runtimes in one process (or proving a non-WS carrier end to end).
|
|
2214
|
+
*/
|
|
2215
|
+
declare function createInMemoryChannelPair(): IInMemoryChannelPair;
|
|
2216
|
+
//#endregion
|
|
2217
|
+
//#region src/ActionRuntime/Transport/Carrier/duplex/inMemory/inMemoryCarrier.d.ts
|
|
2218
|
+
interface IInMemoryCarrier {
|
|
2219
|
+
/** The connector end — pass as the `carrier` to {@link secureTransport} / `LinkTransport`. */
|
|
2220
|
+
carrier: IDuplexCarrierSource;
|
|
2221
|
+
/** The acceptor end — wire into an `AcceptorHandler` (`send` + `receive`). */
|
|
2222
|
+
serverEndpoint: IInMemoryServerEndpoint;
|
|
2223
|
+
}
|
|
2224
|
+
/**
|
|
2225
|
+
* A loopback duplex carrier with no socket — two cross-wired in-process ends. The connector end is an
|
|
2226
|
+
* {@link IDuplexCarrierSource} for {@link secureTransport}; the acceptor end plugs into an
|
|
2227
|
+
* `AcceptorHandler`. Ideal for tests and for running two runtimes in one process, or proving a
|
|
2228
|
+
* non-WS carrier end to end.
|
|
2229
|
+
*/
|
|
2230
|
+
declare function inMemoryCarrier(): IInMemoryCarrier;
|
|
2231
|
+
//#endregion
|
|
2232
|
+
//#region src/ActionRuntime/Transport/Carrier/duplex/rtc/rtcDataChannelByteChannel.d.ts
|
|
2233
|
+
/**
|
|
2234
|
+
* The slice of the `RTCDataChannel` surface this adapter uses — declared structurally so it accepts the
|
|
2235
|
+
* browser `RTCDataChannel`, React-Native (`react-native-webrtc`), or any node-webrtc shim without a hard
|
|
2236
|
+
* dependency on a specific DOM/RN type. A real `RTCDataChannel` satisfies it as-is.
|
|
2237
|
+
*/
|
|
2238
|
+
interface IRtcDataChannelLike {
|
|
2239
|
+
readyState: string;
|
|
2240
|
+
binaryType: string;
|
|
2241
|
+
label?: string;
|
|
2242
|
+
send(data: string | ArrayBuffer | ArrayBufferView): void;
|
|
2243
|
+
close(): void;
|
|
2244
|
+
addEventListener(type: string, listener: (event: any) => void, options?: unknown): void;
|
|
2245
|
+
}
|
|
2246
|
+
/**
|
|
2247
|
+
* Adapt a WebRTC `RTCDataChannel` to the carrier-agnostic {@link IDuplexCarrier}, so two browsers
|
|
2248
|
+
* (or two mobile apps) linked peer-to-peer — no server in the middle — run the *same* secure session as
|
|
2249
|
+
* a WebSocket. Hand it to `createSecureLinkTransport({ openChannel: () => rtcDataChannelByteChannel(dc) })`.
|
|
2250
|
+
*
|
|
2251
|
+
* The data channel must already be created (its negotiation/signaling is the app's concern); this only
|
|
2252
|
+
* drives bytes over it. Binary frames are requested as `ArrayBuffer` so the binary session codec unpacks
|
|
2253
|
+
* them synchronously; a `Blob` (if the channel hands one back) is normalized to a buffer.
|
|
2254
|
+
*/
|
|
2255
|
+
declare function rtcDataChannelByteChannel(dc: IRtcDataChannelLike): IDuplexCarrier;
|
|
2256
|
+
//#endregion
|
|
2257
|
+
//#region src/ActionRuntime/Transport/Carrier/duplex/rtc/rtcCarrier.d.ts
|
|
2258
|
+
interface IRtcCarrierOptions {
|
|
2259
|
+
getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
2260
|
+
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
2261
|
+
}
|
|
2262
|
+
/**
|
|
2263
|
+
* A WebRTC {@link IDuplexCarrierSource} over an already-negotiated `RTCDataChannel` (signaling is the
|
|
2264
|
+
* app's concern). Hand it to {@link secureTransport} so two browsers/apps linked peer-to-peer run the
|
|
2265
|
+
* identical secure session as a WebSocket.
|
|
2266
|
+
*/
|
|
2267
|
+
declare function rtcCarrier(dataChannel: IRtcDataChannelLike, options?: IRtcCarrierOptions): IDuplexCarrierSource;
|
|
2268
|
+
//#endregion
|
|
2269
|
+
//#region src/ActionRuntime/Transport/Carrier/duplex/ws/wsCarrier.d.ts
|
|
2270
|
+
interface IWsCarrierOptions {
|
|
2271
|
+
/** Override socket creation (defaults to a `new WebSocket(url)` with `binaryType = "arraybuffer"`). */
|
|
2272
|
+
createWebSocket?: (input: ITransportRouteActionParams) => WebSocket;
|
|
2273
|
+
/** Override the reuse key (defaults to `[url]`, so one socket is shared per endpoint). */
|
|
2274
|
+
getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
2275
|
+
/** Override the devtools route info for a specific action. */
|
|
2276
|
+
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
2277
|
+
}
|
|
2278
|
+
/**
|
|
2279
|
+
* A WebSocket {@link IDuplexCarrierSource}: opens an `arraybuffer` socket to `url` (cached per endpoint)
|
|
2280
|
+
* and adapts it to a carrier. Hand it to {@link secureTransport} (or `LinkTransport`) — the WebSocket is
|
|
2281
|
+
* now "just another carrier" under the shared secure session, with no WS-specific transport class.
|
|
2282
|
+
*/
|
|
2283
|
+
declare function wsCarrier(url: string, options?: IWsCarrierOptions): IDuplexCarrierSource;
|
|
2284
|
+
//#endregion
|
|
2285
|
+
//#region src/ActionRuntime/Transport/Carrier/exchange/http/httpCarrier.d.ts
|
|
2286
|
+
/** The HTTP request an action is sent over (the body is supplied by the secure exchange session). */
|
|
2287
|
+
interface IHttpCarrierRequest {
|
|
2288
|
+
url: string;
|
|
2289
|
+
headers?: Record<string, string>;
|
|
2290
|
+
}
|
|
2291
|
+
/** The slice of `fetch` the carrier uses — a structural type so callers (and tests) needn't match the
|
|
2292
|
+
* full platform `fetch` (Bun's adds `preconnect`, etc.). The global `fetch` satisfies it. */
|
|
2293
|
+
type TCarrierFetch = (input: string, init?: RequestInit) => Promise<Response>;
|
|
2294
|
+
interface IHttpCarrierOptions {
|
|
2295
|
+
/** Override the reuse key (defaults to `[url]`, so one session is shared per endpoint). */
|
|
2296
|
+
getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
2297
|
+
/** Override the devtools route info for a specific action. */
|
|
2298
|
+
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
2299
|
+
/** Override `fetch` (e.g. to route to an in-memory handler in tests). Defaults to global `fetch`. */
|
|
2300
|
+
fetch?: TCarrierFetch;
|
|
2301
|
+
}
|
|
2302
|
+
/**
|
|
2303
|
+
* An HTTP {@link IExchangeCarrierSource}: each `exchange` POSTs one frame body to the action endpoint and
|
|
2304
|
+
* resolves with the response body as the single correlated reply. Hand it to {@link secureTransport} —
|
|
2305
|
+
* HTTP then runs the *same* secure session as a duplex carrier (handshake → token → encrypted frames),
|
|
2306
|
+
* the request/reply correlation provided for free by the HTTP transaction.
|
|
2307
|
+
*
|
|
2308
|
+
* `createRequest` derives the URL/headers per action (keep it simple with `() => ({ url })`). The body is
|
|
2309
|
+
* the session's responsibility, so it is never built here.
|
|
2310
|
+
*/
|
|
2311
|
+
declare function httpCarrier(createRequest: (input: ITransportRouteActionParams) => IHttpCarrierRequest, options?: IHttpCarrierOptions): IExchangeCarrierSource;
|
|
2312
|
+
//#endregion
|
|
2313
|
+
//#region src/ActionRuntime/Transport/codec/createBinaryWireAdapter.d.ts
|
|
2314
|
+
/**
|
|
2315
|
+
* Builds a *stateless* `formatMessage` pipeline for {@link LinkTransport}, packing action
|
|
2316
|
+
* payloads into a compact msgpackr binary frame instead of JSON. The `domain`/`id` route collapses to
|
|
2317
|
+
* a single integer drawn from a shared dictionary; `form`/`type`, the recomputable
|
|
2318
|
+
* `inputHash`/`outputHash`, and the per-frame `context.routing`/`context.timeCreated` are all dropped
|
|
2319
|
+
* (see {@link ENVELOPE}).
|
|
2320
|
+
*
|
|
2321
|
+
* No validation runs here: `incoming` blindly reconstructs the wire JSON shape and hands it back to
|
|
2322
|
+
* the connection, which flows into `ActionRuntime` → `domain.hydrateAnyAction()` where the Valibot
|
|
2323
|
+
* schemas validate it exactly as they would for a JSON frame.
|
|
2324
|
+
*
|
|
2325
|
+
* Both ends of the socket MUST construct the adapter with the same domains in the same order — the
|
|
2326
|
+
* integer dictionary is positional. Mismatched dictionaries will route to the wrong action.
|
|
2327
|
+
*
|
|
2328
|
+
* Because `incoming` returns `undefined` for text frames, a binary server can still serve plain-JSON
|
|
2329
|
+
* clients on the same runtime (the connection falls back to its built-in JSON parser).
|
|
2330
|
+
*/
|
|
2331
|
+
declare function createBinaryWireAdapter(domains: ActionDomain<any>[]): IActionWireFormat;
|
|
2332
|
+
//#endregion
|
|
2333
|
+
//#region src/ActionRuntime/Transport/crypto/actionFrameCrypto.d.ts
|
|
2334
|
+
/**
|
|
2335
|
+
* Async AES-GCM transform for the `encrypted` security level. It wraps the opaque binary frame a
|
|
2336
|
+
* session codec produces (it does NOT look inside it), encrypting on the way out and decrypting on the
|
|
2337
|
+
* way in with the shared key established by the handshake.
|
|
2338
|
+
*
|
|
2339
|
+
* It is deliberately separate from the (synchronous) session `formatMessage`: WebCrypto is always
|
|
2340
|
+
* Promise-based, so encryption has to happen at the transport's async I/O boundary — the connection
|
|
2341
|
+
* encrypts after `session.outgoing()` and decrypts before `session.incoming()`. The `authenticated`
|
|
2342
|
+
* and `none` levels use no crypto transform at all (frames go out as the session produced them).
|
|
2343
|
+
*
|
|
2344
|
+
* Wire shape of an encrypted frame: `pack([nonceBytes, ciphertextBytes])` — msgpack carries the two
|
|
2345
|
+
* binary fields with a couple of bytes of overhead, no base64 inflation.
|
|
2346
|
+
*/
|
|
2347
|
+
interface IActionFrameCrypto {
|
|
2348
|
+
/** Encrypt one session frame for sending. */
|
|
2349
|
+
encryptFrame(frame: Uint8Array): Promise<Uint8Array>;
|
|
2350
|
+
/** Decrypt one received frame back to the session frame. Throws on a non-binary / malformed /
|
|
2351
|
+
* tampered frame — the caller (transport) decides how to react (drop / close). */
|
|
2352
|
+
decryptFrame(frame: string | ArrayBuffer | Uint8Array): Promise<Uint8Array>;
|
|
2353
|
+
}
|
|
2354
|
+
interface IActionFrameCryptoConfig {
|
|
2355
|
+
link: ClientCryptoKeyLink;
|
|
2356
|
+
/** The handshake-established link id for the remote (key + connection-registry id). */
|
|
2357
|
+
linkedClientId: TTypeAndId;
|
|
2358
|
+
}
|
|
2359
|
+
/**
|
|
2360
|
+
* Build the encrypt/decrypt transform for a connection whose handshake settled on the `encrypted`
|
|
2361
|
+
* level. Keyed by the link + `linkedClientId`, so it reuses the cached shared AES-GCM key.
|
|
2362
|
+
*/
|
|
2363
|
+
declare function createActionFrameCrypto({
|
|
2364
|
+
link,
|
|
2365
|
+
linkedClientId
|
|
2366
|
+
}: IActionFrameCryptoConfig): IActionFrameCrypto;
|
|
2367
|
+
//#endregion
|
|
2368
|
+
//#region src/ActionRuntime/Transport/Exchange/TransportExchange.types.d.ts
|
|
2369
|
+
interface IActionTransportReadyData_Exchange extends IActionTransportReadyData_Base {
|
|
2370
|
+
/** The live request/reply carrier this connection drives its session over. */
|
|
2371
|
+
carrier: IExchangeCarrier;
|
|
2372
|
+
/** Optional authenticated/encrypted config; the handshake runs once at bring-up when set. */
|
|
2373
|
+
secureChannel?: ISecureClientConfig;
|
|
2374
|
+
}
|
|
2375
|
+
interface IActionTransportInitialized_Exchange extends IActionTransportInitialized<ITransportRouteActionParams, IActionTransportReadyData_Exchange> {}
|
|
2376
|
+
interface IActionTransportDef_Exchange extends IActionTransportDef<ETransportShape.exchange, IActionTransportInitialized_Exchange> {}
|
|
2377
|
+
//#endregion
|
|
2378
|
+
//#region src/ActionRuntime/Transport/Exchange/ExchangeConnection.d.ts
|
|
2379
|
+
/**
|
|
2380
|
+
* Carrier-agnostic live connection for the exchange (request → single reply) shape — the HTTP
|
|
2381
|
+
* counterpart to {@link LinkConnection}. It owns only the bring-up (run the secure handshake on first
|
|
2382
|
+
* use); the request/reply lifecycle + crypto live in the shared `establishExchangeSession`.
|
|
2383
|
+
*/
|
|
2384
|
+
declare class ExchangeConnection extends TransportConnection<ETransportShape.exchange, ITransportRouteActionParams, IActionTransportReadyData_Exchange, IActionTransportInitialized_Exchange, IActionTransportDef_Exchange> {
|
|
2385
|
+
constructor(def: Omit<IActionTransportDef_Exchange, "type">);
|
|
2386
|
+
protected _getCacheKey(input: ITransportRouteActionParams): string;
|
|
2387
|
+
protected _needsAsyncBringUp(data: IActionTransportReadyData_Exchange): boolean;
|
|
2388
|
+
protected _finalizeReady(data: IActionTransportReadyData_Exchange): IActionTransportReadyData_Methods | Promise<IActionTransportReadyData_Methods>;
|
|
2389
|
+
_finalizeTransportMethods(data: IActionTransportReadyData_Exchange): IActionTransportReadyData_Methods;
|
|
2390
|
+
private _sessionContext;
|
|
2391
|
+
}
|
|
2392
|
+
//#endregion
|
|
2393
|
+
//#region src/ActionRuntime/Transport/Exchange/ExchangeTransport.d.ts
|
|
2394
|
+
interface IExchangeTransportOptions {
|
|
2395
|
+
/** Open (or reuse) the exchange carrier for an action — e.g. `httpCarrier(...).open`. */
|
|
2396
|
+
openCarrier: (input: ITransportRouteActionParams) => IExchangeCarrier;
|
|
2397
|
+
/** Secure config; when set (and `securityLevel !== none`) the handshake runs once at bring-up. */
|
|
2398
|
+
security?: ISecureClientConfig;
|
|
2399
|
+
updateRunConfig?: TUpdateActionRunConfig;
|
|
2400
|
+
/** Keys identifying a reusable session, so one carrier is shared across actions to the same peer. */
|
|
2401
|
+
getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
2402
|
+
/** Short label for the devtools chip (defaults to "exchange"). */
|
|
2403
|
+
label?: string;
|
|
2404
|
+
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
2405
|
+
}
|
|
2406
|
+
/**
|
|
2407
|
+
* A carrier-agnostic exchange (request → single reply) transport: it drives nice-action's secure session
|
|
2408
|
+
* over any {@link IExchangeCarrier} (HTTP being the one built-in). The duplex counterpart is
|
|
2409
|
+
* {@link LinkTransport}; this is the no-push half — its reply rides the response to its own request, so it
|
|
2410
|
+
* can't deliver an unsolicited frame (the runtime never picks it for the return path).
|
|
2411
|
+
*/
|
|
2412
|
+
declare class ExchangeTransport extends Transport<ETransportShape.exchange> {
|
|
2413
|
+
private readonly options;
|
|
2414
|
+
readonly type = ETransportShape.exchange;
|
|
2415
|
+
constructor(options: IExchangeTransportOptions);
|
|
2416
|
+
static create(options: IExchangeTransportOptions): ExchangeTransport;
|
|
2417
|
+
_createConnection(_ctx: ITransportConnectionContext): ExchangeConnection;
|
|
2418
|
+
getRouteInfo(input: ITransportRouteActionParams): ITransportRouteInfo;
|
|
2419
|
+
}
|
|
2420
|
+
//#endregion
|
|
2421
|
+
//#region src/ActionRuntime/Transport/err_nice_transport.d.ts
|
|
2422
|
+
declare enum EErrId_NiceTransport {
|
|
2423
|
+
timeout = "timeout",
|
|
2424
|
+
not_found = "not_found",
|
|
2425
|
+
unsupported = "unsupported",
|
|
2426
|
+
initialization_failed = "initialization_failed",
|
|
2427
|
+
send_failed = "send_failed",
|
|
2428
|
+
invalid_action_response = "invalid_action_response"
|
|
2429
|
+
}
|
|
2430
|
+
declare const err_nice_transport: import("@nice-code/error").NiceErrorDomain<{
|
|
2431
|
+
domain: string;
|
|
2432
|
+
allDomains: [string, string, string, "err_nice"];
|
|
2433
|
+
schema: {
|
|
2434
|
+
timeout: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
2435
|
+
timeout: number;
|
|
2436
|
+
}, import("@nice-code/error").JSONSerializableValue>;
|
|
2437
|
+
not_found: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
2438
|
+
actionId: string;
|
|
2439
|
+
}, import("@nice-code/error").JSONSerializableValue>;
|
|
2440
|
+
unsupported: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
2441
|
+
transportShapes: ETransportShape[];
|
|
2442
|
+
}, import("@nice-code/error").JSONSerializableValue>;
|
|
2443
|
+
initialization_failed: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
2444
|
+
actionId: string;
|
|
2445
|
+
}, import("@nice-code/error").JSONSerializableValue>;
|
|
2446
|
+
send_failed: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
2447
|
+
actionState: string;
|
|
2448
|
+
actionId: string;
|
|
2449
|
+
httpStatusCode?: number;
|
|
2450
|
+
message?: string;
|
|
2451
|
+
}, import("@nice-code/error").JSONSerializableValue>;
|
|
2452
|
+
invalid_action_response: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
2453
|
+
actionId: string;
|
|
2454
|
+
}, import("@nice-code/error").JSONSerializableValue>;
|
|
2455
|
+
};
|
|
2456
|
+
}>;
|
|
2457
|
+
//#endregion
|
|
2458
|
+
//#region src/ActionRuntime/Transport/Carrier/duplex/ws/err_nice_transport_ws.d.ts
|
|
2459
|
+
declare enum EErrId_NiceTransport_WebSocket {
|
|
2460
|
+
ws_disconnected = "ws_disconnected",
|
|
2461
|
+
ws_create_failed = "ws_create_failed",
|
|
2462
|
+
ws_error = "ws_error"
|
|
2463
|
+
}
|
|
2464
|
+
declare const err_nice_transport_ws: import("@nice-code/error").NiceErrorDomain<{
|
|
2465
|
+
domain: string;
|
|
2466
|
+
allDomains: [string, string, string, string, "err_nice"];
|
|
2467
|
+
schema: {
|
|
2468
|
+
ws_disconnected: import("@nice-code/error").INiceErrorIdMetadata<Record<string, never>, import("@nice-code/error").JSONSerializableValue>;
|
|
2469
|
+
ws_create_failed: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
2470
|
+
originalError?: Error;
|
|
2471
|
+
}, import("@nice-code/error").JSONSerializableValue>;
|
|
2472
|
+
ws_error: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
2473
|
+
originalError?: Error;
|
|
2474
|
+
}, import("@nice-code/error").JSONSerializableValue>;
|
|
2475
|
+
};
|
|
2476
|
+
}>;
|
|
2477
|
+
//#endregion
|
|
2478
|
+
//#region src/ActionRuntime/Transport/Link/TransportLink.types.d.ts
|
|
2479
|
+
/** The per-connection codec (positional binary wire / JSON fallback) the carrier's session uses. */
|
|
2480
|
+
type TLinkFormatMessage = IActionWireFormat;
|
|
2481
|
+
interface IActionTransportReadyData_Link extends IActionTransportReadyData_Base {
|
|
2482
|
+
/** The live carrier this connection drives its session over. */
|
|
2483
|
+
channel: IDuplexCarrier;
|
|
2484
|
+
formatMessage?: TLinkFormatMessage;
|
|
2485
|
+
/** Optional authenticated/encrypted channel; the connection runs the handshake during init. */
|
|
2486
|
+
secureChannel?: ISecureClientConfig;
|
|
2487
|
+
}
|
|
2488
|
+
interface IActionTransportInitialized_Link extends IActionTransportInitialized<ITransportRouteActionParams, IActionTransportReadyData_Link> {}
|
|
2489
|
+
interface IActionTransportDef_Link extends IActionTransportDef<ETransportShape.duplex, IActionTransportInitialized_Link> {}
|
|
2490
|
+
//#endregion
|
|
2491
|
+
//#region src/ActionRuntime/Transport/Link/LinkConnection.d.ts
|
|
2492
|
+
/**
|
|
2493
|
+
* Carrier-agnostic live connection. It owns only the *bring-up* (open the carrier, then run the secure
|
|
2494
|
+
* session); the session itself — handshake, frame crypto, codec, send/receive — lives in the shared
|
|
2495
|
+
* {@link finalizeSecureLinkMethods}/{@link finalizePlainLinkMethods}, so a WebSocket, a WebRTC data
|
|
2496
|
+
* channel, a Bluetooth characteristic, and an in-memory pipe all run the identical secure layer.
|
|
2497
|
+
*/
|
|
2498
|
+
declare class LinkConnection extends TransportConnection<ETransportShape.duplex, ITransportRouteActionParams, IActionTransportReadyData_Link, IActionTransportInitialized_Link, IActionTransportDef_Link> {
|
|
2499
|
+
private resolvers;
|
|
2500
|
+
constructor(def: Omit<IActionTransportDef_Link, "type">, resolvers?: IActionTransportResolvers);
|
|
2501
|
+
protected _getCacheKey(input: ITransportRouteActionParams): string;
|
|
2502
|
+
protected _needsAsyncBringUp(): boolean;
|
|
2503
|
+
protected _awaitCarrierReady(data: IActionTransportReadyData_Link): Promise<void>;
|
|
2504
|
+
protected _finalizeReady(data: IActionTransportReadyData_Link): IActionTransportReadyData_Methods | Promise<IActionTransportReadyData_Methods>;
|
|
2505
|
+
private _sessionContext;
|
|
2506
|
+
_finalizeTransportMethods(data: IActionTransportReadyData_Link): IActionTransportReadyData_Methods;
|
|
2507
|
+
}
|
|
2508
|
+
//#endregion
|
|
2509
|
+
//#region src/ActionRuntime/Transport/Link/LinkTransport.d.ts
|
|
2510
|
+
interface ILinkTransportOptions {
|
|
2511
|
+
/**
|
|
2512
|
+
* Open (or reuse) the carrier for an action — a WebSocket adapter, a WebRTC data channel, a Bluetooth
|
|
2513
|
+
* characteristic, an in-memory pipe, anything that satisfies {@link IDuplexCarrier}.
|
|
2514
|
+
*/
|
|
2515
|
+
openChannel: (input: ITransportRouteActionParams) => IDuplexCarrier;
|
|
2516
|
+
/** Shared codec for every channel (stateless). */
|
|
2517
|
+
formatMessage?: TLinkFormatMessage;
|
|
2518
|
+
/**
|
|
2519
|
+
* Per-channel codec factory — called once per opened channel so stateful codecs (e.g. the binary
|
|
2520
|
+
* session) get their own instance. Takes precedence over `formatMessage`.
|
|
2521
|
+
*/
|
|
2522
|
+
createFormatMessage?: () => TLinkFormatMessage;
|
|
2523
|
+
/** Secure-channel config; when set (and `securityLevel !== none`) the handshake runs on init. */
|
|
2524
|
+
security?: ISecureClientConfig;
|
|
2525
|
+
updateRunConfig?: TUpdateActionRunConfig;
|
|
2526
|
+
/** Keys identifying a reusable channel, so one carrier is shared across actions to the same peer. */
|
|
2527
|
+
getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
2528
|
+
/** Short label for the devtools chip (defaults to "link"). */
|
|
2529
|
+
label?: string;
|
|
2530
|
+
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
2531
|
+
}
|
|
2532
|
+
/**
|
|
2533
|
+
* A carrier-agnostic transport: it drives nice-action's secure session + action routing over any
|
|
2534
|
+
* {@link IDuplexCarrier}. The WebSocket transport is the special case that opens a `WebSocket`;
|
|
2535
|
+
* this opens whatever `openChannel` returns, so the identical secure layer works over WebRTC, Bluetooth,
|
|
2536
|
+
* or an in-memory pipe. Reported with an overridable carrier label in the devtools (defaults to "link").
|
|
2537
|
+
*/
|
|
2538
|
+
declare class LinkTransport extends Transport<ETransportShape.duplex> {
|
|
2539
|
+
private readonly options;
|
|
2540
|
+
readonly type = ETransportShape.duplex;
|
|
2541
|
+
constructor(options: ILinkTransportOptions);
|
|
2542
|
+
static create(options: ILinkTransportOptions): LinkTransport;
|
|
2543
|
+
_createConnection(ctx: ITransportConnectionContext): LinkConnection;
|
|
2544
|
+
getRouteInfo(input: ITransportRouteActionParams): ITransportRouteInfo;
|
|
2545
|
+
}
|
|
2546
|
+
//#endregion
|
|
2547
|
+
//#region src/ActionRuntime/Transport/plainTransport.d.ts
|
|
2548
|
+
interface IPlainTransportOptions {
|
|
2549
|
+
/**
|
|
2550
|
+
* How to reach the peer with no security layer. A duplex carrier (`wsCarrier(url)`,
|
|
2551
|
+
* `rtcCarrier(dc)`, `inMemoryCarrier().carrier`) builds a push-capable {@link LinkTransport}; an
|
|
2552
|
+
* exchange carrier (`httpCarrier(...)`) builds a request/reply {@link ExchangeTransport}.
|
|
2553
|
+
*/
|
|
2554
|
+
carrier: IDuplexCarrierSource | IExchangeCarrierSource;
|
|
2555
|
+
/**
|
|
2556
|
+
* Codec for a *duplex* carrier (a duplex link frames the action wire itself). Required for duplex;
|
|
2557
|
+
* ignored for an exchange carrier, which JSON-encodes the action wire in its envelope.
|
|
2558
|
+
*/
|
|
2559
|
+
formatMessage?: TLinkFormatMessage;
|
|
2560
|
+
/** Per-channel codec factory for stateful duplex codecs (e.g. the binary session). */
|
|
2561
|
+
createFormatMessage?: () => TLinkFormatMessage;
|
|
2562
|
+
updateRunConfig?: TUpdateActionRunConfig;
|
|
2563
|
+
/** Override the devtools chip label (defaults to the carrier's `carrierLabel`). */
|
|
2564
|
+
label?: string;
|
|
2565
|
+
}
|
|
2566
|
+
/**
|
|
2567
|
+
* The plain (no-handshake, no-crypto) sibling of {@link secureTransport}: swap the carrier to change
|
|
2568
|
+
* protocol, with no security layer. Over an {@link IExchangeCarrierSource} it builds an
|
|
2569
|
+
* {@link ExchangeTransport} that POSTs the bare action wire and completes inline (HTTP is just
|
|
2570
|
+
* `carrier: httpCarrier(...)`); over an {@link IDuplexCarrierSource} it builds a push-capable
|
|
2571
|
+
* {@link LinkTransport} with the given codec. HTTP is therefore no longer a bespoke transport class —
|
|
2572
|
+
* it is "just another carrier", exactly like a WebSocket under {@link secureTransport}.
|
|
2573
|
+
*/
|
|
2574
|
+
declare function plainTransport(options: IPlainTransportOptions & {
|
|
2575
|
+
carrier: IExchangeCarrierSource;
|
|
2576
|
+
}): ExchangeTransport;
|
|
2577
|
+
declare function plainTransport(options: IPlainTransportOptions & {
|
|
2578
|
+
carrier: IDuplexCarrierSource;
|
|
2579
|
+
}): LinkTransport;
|
|
2580
|
+
//#endregion
|
|
2581
|
+
//#region src/ActionRuntime/Transport/secureTransport.d.ts
|
|
2582
|
+
interface ISecureTransportOptions {
|
|
2583
|
+
/** The shared channel identity (per-connection codec + dictionary version) — same one both ends use. */
|
|
2584
|
+
channel: ISecureChannel;
|
|
2585
|
+
/** This client's runtime — its coordinate is the authenticated identity sent in the handshake. */
|
|
2586
|
+
runtime: ActionRuntime;
|
|
2587
|
+
/** Backing store for this client's crypto identity (a stable verify key across reloads). */
|
|
2588
|
+
storageAdapter: StorageAdapter;
|
|
2589
|
+
/** The level this client requests; the peer must allow it. */
|
|
2590
|
+
securityLevel: ESecurityLevel;
|
|
2591
|
+
/**
|
|
2592
|
+
* How to reach the peer. A duplex carrier (`wsCarrier(url)`, `rtcCarrier(dc)`,
|
|
2593
|
+
* `inMemoryCarrier().carrier`) runs the push-capable session; an exchange carrier (`httpCarrier(...)`)
|
|
2594
|
+
* runs the request/reply session over the same handshake + crypto.
|
|
2595
|
+
*/
|
|
2596
|
+
carrier: IDuplexCarrierSource | IExchangeCarrierSource;
|
|
2597
|
+
}
|
|
2598
|
+
/**
|
|
2599
|
+
* The one secure-transport factory — swap the carrier to change protocol. Folds in the boilerplate (the
|
|
2600
|
+
* {@link ClientCryptoKeyLink} from `storageAdapter`, the `security` block from the runtime coordinate +
|
|
2601
|
+
* channel version) and drives it over whatever carrier you pass: a {@link IDuplexCarrierSource} builds a
|
|
2602
|
+
* push-capable {@link LinkTransport} (WS is just `carrier: wsCarrier(url)`), an
|
|
2603
|
+
* {@link IExchangeCarrierSource} builds a request/reply {@link ExchangeTransport} (HTTP, with the same
|
|
2604
|
+
* authentication/encryption). Replaces the old `createSecureWebSocketTransport` / `createSecureLinkTransport`.
|
|
2605
|
+
*/
|
|
2606
|
+
declare function secureTransport(options: ISecureTransportOptions & {
|
|
2607
|
+
carrier: IDuplexCarrierSource;
|
|
2608
|
+
}): LinkTransport;
|
|
2609
|
+
declare function secureTransport(options: ISecureTransportOptions & {
|
|
2610
|
+
carrier: IExchangeCarrierSource;
|
|
2611
|
+
}): ExchangeTransport;
|
|
2612
|
+
//#endregion
|
|
2102
2613
|
//#region src/errors/err_nice_action.d.ts
|
|
2103
2614
|
declare enum EErrId_NiceAction {
|
|
2104
2615
|
not_implemented = "not_implemented",
|
|
@@ -2198,7 +2709,7 @@ declare const err_nice_action: import("@nice-code/error").NiceErrorDomain<{
|
|
|
2198
2709
|
//#region src/utils/decodeActionFrame.d.ts
|
|
2199
2710
|
/**
|
|
2200
2711
|
* Minimal codec shape needed to turn an incoming channel frame back into action wire JSON. Matches
|
|
2201
|
-
* the `formatMessage` object the WebSocket transport (and `
|
|
2712
|
+
* the `formatMessage` object the WebSocket transport (and `createBinaryWireAdapter`) provide.
|
|
2202
2713
|
*/
|
|
2203
2714
|
interface IActionFrameDecoder {
|
|
2204
2715
|
incoming?: (frame: string | ArrayBuffer | Uint8Array | Blob) => TActionPayload_Any_JsonObject<any, any> | undefined;
|
|
@@ -2207,7 +2718,7 @@ interface IActionFrameDecoder {
|
|
|
2207
2718
|
* Decode a single inbound channel frame (text or binary) into validated action wire JSON, or
|
|
2208
2719
|
* `undefined` if it isn't a recognisable action payload.
|
|
2209
2720
|
*
|
|
2210
|
-
* Shared by the WebSocket transport's message listener and the server-side `
|
|
2721
|
+
* Shared by the WebSocket transport's message listener and the server-side `AcceptorHandler` so
|
|
2211
2722
|
* both decode identically: a binary `decoder.incoming` (e.g. msgpackr) takes precedence, and plain
|
|
2212
2723
|
* text frames fall back to JSON — keeping binary and JSON clients interoperable on one channel.
|
|
2213
2724
|
*/
|
|
@@ -2237,8 +2748,8 @@ interface IActionPayload_Base<DT extends EActionPayloadType, DOM extends IAction
|
|
|
2237
2748
|
readonly type: DT;
|
|
2238
2749
|
readonly context: ActionContext<DOM, ID>;
|
|
2239
2750
|
}
|
|
2240
|
-
type IActionRouteItemHandler = IActionHandler_Local_Json | (
|
|
2241
|
-
|
|
2751
|
+
type IActionRouteItemHandler = IActionHandler_Local_Json | (IActionHandler_Peer_Json & {
|
|
2752
|
+
transShape: ETransportShape;
|
|
2242
2753
|
transOrd: number;
|
|
2243
2754
|
transInfo?: ITransportRouteInfo;
|
|
2244
2755
|
});
|
|
@@ -2324,5 +2835,5 @@ interface IActionPayload_Result_JsonObject<DOM extends IActionDomain = IActionDo
|
|
|
2324
2835
|
type TActionPayload_Any_Instance<DOM extends IActionDomain = IActionDomain, ID extends keyof DOM["actionSchema"] & string = keyof DOM["actionSchema"] & string> = ActionPayload_Request<DOM, ID> | ActionPayload_Result<DOM, ID> | ActionPayload_Progress<DOM, ID>;
|
|
2325
2836
|
type TActionPayload_Any_JsonObject<DOM extends IActionDomain = IActionDomain, ID extends keyof DOM["actionSchema"] & string = keyof DOM["actionSchema"] & string> = IActionPayload_Request_JsonObject<DOM, ID> | IActionPayload_Progress_JsonObject<DOM, ID> | IActionPayload_Result_JsonObject<DOM, ID>;
|
|
2326
2837
|
//#endregion
|
|
2327
|
-
export {
|
|
2328
|
-
//# sourceMappingURL=ActionPayload.types-
|
|
2838
|
+
export { IRtcDataChannelLike as $, PeerLinkHandler as $n, ConnectorHandler as $t, ILinkTransportOptions as A, TTransportCache as An, TDomainActionId as Ar, TChannelAcceptorCases as At, IActionTransportReadyData_Exchange as B, IClientVerifyKeyResolveInput as Bn, TActionSerializationDefinition as Br, AcceptorHandler as Bt, decodeActionFrame as C, TOnResolveAnyIncomingActionData_Json as Cn, TRuntimeCoordinateEnvId as Cr, createActionFetchHandler as Ct, secureTransport as D, TOnResolveIncomingResponseJson as Dn, IActionRootDomain as Dr, IAcceptChannelOptions as Dt, ISecureTransportOptions as E, TOnResolveIncomingResponse as En, IActionDomainChildOptions as Er, IExchangeAcceptorSecurity as Et, err_nice_transport_ws as F, ITransportConnectionContext as Fn, ActionSchema as Fr, defineChannel as Ft, IHttpCarrierOptions as G, THandshakeMessage as Gn, TActionConnectionEncoding as Gt, IActionFrameCryptoConfig as H, IHandshakeEncryptionKeyMaterial as Hn, IAcceptorHandlerOptions as Ht, EErrId_NiceTransport as I, Transport as In, EActionResponseMode as Ir, ISecureChannel as It, httpCarrier as J, createServerHandshake as Jn, createActionRootDomain as Jt, IHttpCarrierRequest as K, createClientHandshake as Kn, createAcceptorHandler as Kt, err_nice_transport as L, EHandshakeMessageType as Ln, TInferActionError as Lr, defineSecureChannel as Lt, IActionTransportReadyData_Link as M, TTransportStatusInfo as Mn, TInferOutputFromSchema as Mr, acceptChannel as Mt, TLinkFormatMessage as N, TTransportStatusInfo_GetTransport_Output as Nn, TPossibleDomainId as Nr, acceptChannelConnections as Nt, IPlainTransportOptions as O, TSendActionDataMethod as On, TActionDomainChildDef as Or, IActionChannel as Ot, EErrId_NiceTransport_WebSocket as P, TUpdateActionRunConfig as Pn, TPossibleDomainIdList as Pr, connectChannel as Pt, rtcCarrier as Q, runtimeLinkId as Qn, ActionRuntime as Qt, ExchangeTransport as R, ESecurityLevel as Rn, actionSchema as Rr, IBinaryWireSessionOptions as Rt, IActionFrameDecoder as S, TOnResolveAnyIncomingActionData as Sn, RuntimeCoordinate as Sr, IActionFetchHandlerOptions as St, err_nice_action as T, TOnResolveIncomingRequestJson as Tn, IActionDomain as Tr, IExchangeAcceptorConfig as Tt, createActionFrameCrypto as U, IHandshakeResult as Un, TAcceptorConnectionCaseFn as Ut, IActionFrameCrypto as V, IClientVerifyKeyResolver as Vn, TTransportedValue as Vr, IAcceptorConnectionBinding as Vt, createBinaryWireAdapter as W, IServerHandshakeConfig as Wn, TActionChannelFormatMessage as Wt, wsCarrier as X, decodeHandshakeMessage as Xn, ActionDomain as Xt, IWsCarrierOptions as Y, createStorageTofuVerifyKeyResolver as Yn, ActionCore as Yt, IRtcCarrierOptions as Z, encodeHandshakeMessage as Zn, ActionRootDomain as Zt, TActionProgress as _, ITransportStatusInfo_Initializing as _n, TRunningActionUpdateListener as _r, IConnectionAttachment as _t, IActionPayload_Data_Base as a, IActionTransportReady as an, ActionPayload_Request as ar, createInMemoryChannelPair as at, isActionPayload_Request_JsonObject as b, IUpdateActionRunConfig_Output as bn, IRuntimeCoordinateSpecifics as br, ISecureAcceptorHandlerOptions as bt, IActionPayload_Request_JsonObject as c, IActionTransportResolvers as cn, ERunningActionFinishedType as cr, IExchangeCarrier as ct, IActionProgress_Custom as d, ITransportMethod_SendActionData_Input as dn, IRunningActionUpdate_Abort as dr, TFrame$1 as dt, createConnectorHandler as en, ActionLocalHandler as er, rtcDataChannelByteChannel as et, IActionProgress_None as f, ITransportRouteActionParams as fn, IRunningActionUpdate_Progress as fr, err_nice_external_client as ft, TActionPayload_Any_JsonObject as g, ITransportStatusInfo_Failed as gn, TRunningActionUpdateFinished as gr, ConnectionStateStore as gt, TActionPayload_Any_Instance as h, ITransportStatusInfo_Base as hn, TRunningActionUpdate as hr, createHibernatableWsServerAdapter as ht, IActionPayload_Base_JsonObject as i, IActionTransportInitialized as in, ActionPayload_Progress as ir, IInMemoryServerEndpoint as it, LinkTransport as j, TTransportInitializationFinishedInfo as jn, TInferInputFromSchema as jr, TChannelPushHandlers as jt, plainTransport as k, TSendReturnDataMethod as kn, TActionDomainSchema as kr, IConnectChannelOptions as kt, IActionPayload_Result as l, ISecureClientConfig as ln, ERunningActionState as lr, IExchangeCarrierSource as lt, IActionRouteItemHandler as m, ITransportRouteInfo as mn, IRunningActionUpdate_Success as mr, IHibernatableWsServerAdapterOptions as mt, EActionProgressType as n, ETransportStatus as nn, MaybePromise as nr, inMemoryCarrier as nt, IActionPayload_Progress as o, IActionTransportReadyData_Base as on, IActionCore as or, IDuplexCarrier as ot, IActionProgress_Percentage as p, ITransportRouteClientParams as pn, IRunningActionUpdate_Started as pr, IHibernatableWsServerAdapter as pt, TCarrierFetch as q, createInMemoryTofuVerifyKeyResolver as qn, IActionWireFormat as qt, IActionPayload_Base as r, IActionTransportDef as rn, RunningAction as rr, IInMemoryChannelPair as rt, IActionPayload_Progress_JsonObject as s, IActionTransportReadyData_Methods as sn, IActionCore_JsonObject as sr, IDuplexCarrierSource as st, EActionPayloadType as t, ETransportShape as tn, createLocalHandler as tr, IInMemoryCarrier as tt, IActionPayload_Result_JsonObject as u, ITransportDispatchAction as un, ERunningActionUpdateType as ur, TCarrier as ut, TActionResultOutcome as v, ITransportStatusInfo_Ready as vn, ActionPayload_Result as vr, IConnectionStateStoreOptions as vt, EErrId_NiceAction as w, TOnResolveIncomingRequest as wn, TRuntimeCoordinateStringId as wr, ExchangeAcceptor as wt, isActionPayload_Any_JsonObject as x, TGetTransportFn as xn, IRuntimeFullCoordinates as xr, createSecureAcceptorHandler as xt, isActionPayload_Result_JsonObject as y, ITransportStatusInfo_Unsupported as yn, IRuntimeCoordinate as yr, createConnectionStateStore as yt, IExchangeTransportOptions as z, IClientHandshakeConfig as zn, TActionSchemaOptions as zr, createBinaryWireSessionFactory as zt };
|
|
2839
|
+
//# sourceMappingURL=ActionPayload.types-CO_hXlBc.d.cts.map
|