@nice-code/action 0.16.0 → 0.17.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 +2 -2
- package/build/{ActionDevtoolsCore-B3JwSaRH.d.cts → ActionDevtoolsCore-C5XrQI1K.d.mts} +2 -2
- package/build/{ActionDevtoolsCore-C4TDUY7-.d.mts → ActionDevtoolsCore-Dd1qJAwK.d.cts} +2 -2
- package/build/{ActionPayload.types-CO_hXlBc.d.cts → ActionPayload.types-BchJrBIX.d.mts} +468 -152
- package/build/{ActionPayload.types-fieMKAgt.d.mts → ActionPayload.types-snDlSIF-.d.cts} +468 -152
- package/build/devtools/browser/index.d.cts +1 -1
- package/build/devtools/browser/index.d.mts +1 -1
- package/build/devtools/server/index.d.cts +1 -1
- package/build/devtools/server/index.d.mts +1 -1
- package/build/index.cjs +224 -79
- 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 +219 -78
- package/build/index.mjs.map +1 -1
- package/build/platform/cloudflare/index.cjs +56 -0
- package/build/platform/cloudflare/index.cjs.map +1 -0
- package/build/platform/cloudflare/index.d.cts +67 -0
- package/build/platform/cloudflare/index.d.mts +67 -0
- package/build/platform/cloudflare/index.mjs +54 -0
- package/build/platform/cloudflare/index.mjs.map +1 -0
- package/build/react-query/index.d.cts +1 -1
- package/build/react-query/index.d.mts +1 -1
- package/build/wsAcceptorCarrier-CXGlQU_f.mjs +80 -0
- package/build/wsAcceptorCarrier-CXGlQU_f.mjs.map +1 -0
- package/build/wsAcceptorCarrier-DHRbsY1X.cjs +103 -0
- package/build/wsAcceptorCarrier-DHRbsY1X.cjs.map +1 -0
- package/package.json +15 -4
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { INiceErrorDomainProps, InferNiceError, NiceError, NiceErrorDomain, err_cast_not_nice } from "@nice-code/error";
|
|
2
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
3
|
import { RuntimeName } from "std-env";
|
|
3
4
|
import { ClientCryptoKeyLink, StorageAdapter, TSerializedCryptoKeyData_Ed25519_Raw, TSerializedCryptoKeyData_X25519_Raw, TTypeAndId } from "@nice-code/util";
|
|
4
5
|
import * as v from "valibot";
|
|
5
|
-
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
6
6
|
|
|
7
7
|
//#region src/ActionDefinition/Schema/ActionSchema.types.d.ts
|
|
8
8
|
type TTransportedValue<RAW_VAL, SERDE_VAL> = [RAW_VAL] | [RAW_VAL, SERDE_VAL];
|
|
@@ -752,6 +752,14 @@ declare abstract class PeerLinkHandler extends ActionHandler<EActionHandlerType.
|
|
|
752
752
|
abstract sendReturnPayload(payload: TActionPayload_Any_Instance<any, any>, config: {
|
|
753
753
|
targetLocalRuntime: ActionRuntime;
|
|
754
754
|
}): Promise<boolean>;
|
|
755
|
+
/**
|
|
756
|
+
* Whether this handler currently holds a *live* connection bound to `origin`. The runtime's return-path
|
|
757
|
+
* dispatch ({@link ActionRuntime.getReturnHandlerForOrigin}) prefers a handler that owns the origin's
|
|
758
|
+
* connection over a mere coordinate match, so with several duplex acceptors a result/push routes back
|
|
759
|
+
* over the carrier the client connected on. Defaults to `false`; an acceptor overrides it from its
|
|
760
|
+
* connection registry.
|
|
761
|
+
*/
|
|
762
|
+
ownsLiveConnectionFor(_origin: RuntimeCoordinate): boolean;
|
|
755
763
|
/** Release any long-lived connections this handler owns (a teardown). No-op by default. */
|
|
756
764
|
clearTransportCache(): void;
|
|
757
765
|
}
|
|
@@ -1288,6 +1296,12 @@ declare class ActionRuntime {
|
|
|
1288
1296
|
* Find the best registered external handler that can reach `originClient` directly.
|
|
1289
1297
|
* Used to locate the return-path channel for dispatching results back to the action origin.
|
|
1290
1298
|
* Returns `undefined` if no handler matches (score > 0 required, i.e. at least id must match).
|
|
1299
|
+
*
|
|
1300
|
+
* A handler that currently holds the origin's *live* connection always wins over a mere coordinate
|
|
1301
|
+
* match — so with several duplex acceptors (e.g. WS + WebRTC) a result/push routes back over the carrier
|
|
1302
|
+
* the client actually connected on, never a same-coordinate sibling that lacks the socket. Only when no
|
|
1303
|
+
* handler owns a live connection do we fall back to the plain best-coordinate-score pick (the
|
|
1304
|
+
* single-acceptor and connector-only cases, unchanged).
|
|
1291
1305
|
*/
|
|
1292
1306
|
getReturnHandlerForOrigin(originClient: RuntimeCoordinate): PeerLinkHandler | undefined;
|
|
1293
1307
|
resetRuntime(): void;
|
|
@@ -1594,6 +1608,10 @@ declare class AcceptorHandler<TConn = unknown> extends PeerLinkHandler {
|
|
|
1594
1608
|
dropConnection(connection: TConn): void;
|
|
1595
1609
|
/** Live connection for a client coordinate, if currently registered. */
|
|
1596
1610
|
getConnectionForClient(client: RuntimeCoordinate): TConn | undefined;
|
|
1611
|
+
/** This acceptor owns the origin's return path when it currently holds a live connection bound to it. */
|
|
1612
|
+
ownsLiveConnectionFor(origin: RuntimeCoordinate): boolean;
|
|
1613
|
+
/** Whether this acceptor currently tracks `connection` — used to pick the owning handler among several. */
|
|
1614
|
+
hasConnection(connection: TConn): boolean;
|
|
1597
1615
|
/**
|
|
1598
1616
|
* Send (and optionally await) a server-initiated action to a specific connected client. Pass the
|
|
1599
1617
|
* connection token directly (e.g. the `ws`) or a client `RuntimeCoordinate` to look one up.
|
|
@@ -1682,8 +1700,8 @@ type TChannelCodec = IActionWireFormat;
|
|
|
1682
1700
|
* The shared identity of a secure channel (carrier-agnostic — WS, WebRTC, HTTP, …): the wire
|
|
1683
1701
|
* dictionary version both ends check during the handshake, plus the per-connection codec factory both
|
|
1684
1702
|
* 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 `
|
|
1686
|
-
* the acceptor, so the codec and version can never drift apart.
|
|
1703
|
+
* hand it to `secureTransport` on the connector and `serveChannel` (or the lower-level `acceptChannel` /
|
|
1704
|
+
* `createSecureAcceptorHandler`) on the acceptor, so the codec and version can never drift apart.
|
|
1687
1705
|
*/
|
|
1688
1706
|
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
1707
|
/** Wire dictionary version — derived from the domains by default; the handshake rejects a mismatch. */
|
|
@@ -1818,6 +1836,12 @@ interface IAcceptChannelOptions<TConn> {
|
|
|
1818
1836
|
storageAdapter: StorageAdapter;
|
|
1819
1837
|
/** Write an encoded frame to a specific live connection (e.g. `(ws, frame) => ws.send(frame)`). */
|
|
1820
1838
|
send: (connection: TConn, frame: string | Uint8Array | ArrayBuffer) => void;
|
|
1839
|
+
/**
|
|
1840
|
+
* The acceptor's crypto identity. Defaults to a fresh `ClientCryptoKeyLink` over `storageAdapter`.
|
|
1841
|
+
* Pass an existing link to share one identity across several acceptors on the same server (e.g. this
|
|
1842
|
+
* WebSocket acceptor and a secure-HTTP `createActionFetchHandler`), so they present the same keys.
|
|
1843
|
+
*/
|
|
1844
|
+
link?: ClientCryptoKeyLink;
|
|
1821
1845
|
/** Accepted level(s); defaults to negotiating any of none/authenticated/encrypted. */
|
|
1822
1846
|
securityLevel?: ESecurityLevel | readonly ESecurityLevel[];
|
|
1823
1847
|
/** Trust decision for a client's verify key; defaults to storage-backed TOFU over `storageAdapter`. */
|
|
@@ -1838,6 +1862,351 @@ interface IAcceptChannelOptions<TConn> {
|
|
|
1838
1862
|
*/
|
|
1839
1863
|
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
1864
|
//#endregion
|
|
1865
|
+
//#region src/ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/createHibernatableWsServerAdapter.d.ts
|
|
1866
|
+
interface IHibernatableWsServerAdapterOptions<TConn> {
|
|
1867
|
+
/** The handler to drive (from `createSecureAcceptorHandler` or `createAcceptorHandler`). */
|
|
1868
|
+
handler: AcceptorHandler<TConn>;
|
|
1869
|
+
/** All currently-live connections — replayed on construction to rebuild bindings after a wake. */
|
|
1870
|
+
getConnections: () => TConn[];
|
|
1871
|
+
/** Read a connection's persisted binding (e.g. `(ws) => ws.deserializeAttachment()`). */
|
|
1872
|
+
getAttachment: (connection: TConn) => IAcceptorConnectionBinding | undefined;
|
|
1873
|
+
/** Persist a connection's binding when it is bound (e.g. `(ws, b) => ws.serializeAttachment(b)`). */
|
|
1874
|
+
setAttachment: (connection: TConn, binding: IAcceptorConnectionBinding) => void;
|
|
1875
|
+
}
|
|
1876
|
+
/**
|
|
1877
|
+
* The neutral lifecycle surface for a duplex (push-capable) acceptor: feed it each inbound frame and tell
|
|
1878
|
+
* it when a connection goes away. Carrier-agnostic — a WebSocket, a WebRTC data channel, or any other
|
|
1879
|
+
* duplex connection drives the same two methods.
|
|
1880
|
+
*/
|
|
1881
|
+
interface IDuplexConnectionRouter<TConn> {
|
|
1882
|
+
/** Feed one inbound frame from a connection into the handler. */
|
|
1883
|
+
receive: (connection: TConn, frame: string | ArrayBuffer | Uint8Array) => void;
|
|
1884
|
+
/** Forget a connection (call on socket close/error). */
|
|
1885
|
+
drop: (connection: TConn) => void;
|
|
1886
|
+
}
|
|
1887
|
+
/**
|
|
1888
|
+
* Wire the hibernation lifecycle for an acceptor handler on a transport whose connections outlive process
|
|
1889
|
+
* eviction (e.g. a Durable Object's hibernatable WebSockets). It owns persistence end to end:
|
|
1890
|
+
* registers `setAttachment` as the handler's connection-bound callback and immediately replays every
|
|
1891
|
+
* live connection's stored binding via `getAttachment`, so results/pushes still route after a wake.
|
|
1892
|
+
*
|
|
1893
|
+
* Layered on top of the generic {@link AcceptorHandler} — it touches only the handler's neutral
|
|
1894
|
+
* `setOnConnectionBound` / `rehydrateConnection` / `receive` / `dropConnection` surface, so no
|
|
1895
|
+
* hibernation concern leaks into the handler itself.
|
|
1896
|
+
*
|
|
1897
|
+
* Construct it once when the handler is built, then forward connection events:
|
|
1898
|
+
* ```ts
|
|
1899
|
+
* const duplex = createHibernatableWsServerAdapter({ handler, getConnections, getAttachment, setAttachment });
|
|
1900
|
+
* // webSocketMessage(ws, msg) => duplex.receive(ws, msg);
|
|
1901
|
+
* // webSocketClose/Error(ws) => duplex.drop(ws);
|
|
1902
|
+
* ```
|
|
1903
|
+
*/
|
|
1904
|
+
declare function createHibernatableWsServerAdapter<TConn>(options: IHibernatableWsServerAdapterOptions<TConn>): IDuplexConnectionRouter<TConn>;
|
|
1905
|
+
//#endregion
|
|
1906
|
+
//#region src/ActionRuntime/Transport/Carrier/Carrier.types.d.ts
|
|
1907
|
+
/**
|
|
1908
|
+
* Carrier shapes — the only transport-specific surface a new protocol must implement. The secure
|
|
1909
|
+
* session (handshake + frame crypto + codec) and the action routing on top of it are carrier-agnostic;
|
|
1910
|
+
* a carrier just moves frames. Two shapes capture every carrier:
|
|
1911
|
+
*
|
|
1912
|
+
* - {@link IDuplexCarrier} — a persistent, push-capable byte stream (WebSocket, WebRTC `RTCDataChannel`,
|
|
1913
|
+
* Bluetooth GATT, an in-memory pipe). Either side can send at any time, so it supports server→client
|
|
1914
|
+
* pushes (the return path + broadcast).
|
|
1915
|
+
* - {@link IExchangeCarrier} — a request → single-correlated-reply carrier with no unsolicited push
|
|
1916
|
+
* (HTTP, and anything request/response-shaped). The reply rides the response to its own request.
|
|
1917
|
+
*
|
|
1918
|
+
* Frames are `string` (text — handshake control messages and JSON action frames) or binary
|
|
1919
|
+
* (`Uint8Array`/`ArrayBuffer` — the optimized binary wire / encrypted frames).
|
|
1920
|
+
*/
|
|
1921
|
+
type TFrame$1 = string | Uint8Array | ArrayBuffer;
|
|
1922
|
+
/**
|
|
1923
|
+
* A bidirectional, push-capable byte stream. Reduces every duplex carrier to "open, send bytes, receive
|
|
1924
|
+
* bytes, close" — a WebSocket, a WebRTC data channel, a Bluetooth characteristic, or an in-memory pipe
|
|
1925
|
+
* all satisfy this, so the identical secure session runs over each.
|
|
1926
|
+
*/
|
|
1927
|
+
interface IDuplexCarrier {
|
|
1928
|
+
/** Resolves once the carrier is open and ready to send; rejects if it closes/errors before opening. */
|
|
1929
|
+
readonly ready: Promise<void>;
|
|
1930
|
+
/** Whether the carrier is currently open (a synchronous guard before `send`). */
|
|
1931
|
+
isOpen(): boolean;
|
|
1932
|
+
/** Write one frame to the peer. */
|
|
1933
|
+
send(frame: TFrame$1): void;
|
|
1934
|
+
/**
|
|
1935
|
+
* Register the carrier's handlers. Called exactly once by the session after `ready`. `onMessage`
|
|
1936
|
+
* receives every inbound frame; `onClose` fires when the carrier goes away.
|
|
1937
|
+
*/
|
|
1938
|
+
attach(handlers: {
|
|
1939
|
+
onMessage: (frame: TFrame$1) => void;
|
|
1940
|
+
onClose: () => void;
|
|
1941
|
+
onError?: (error: unknown) => void;
|
|
1942
|
+
}): void;
|
|
1943
|
+
/** Close the carrier deliberately (a teardown). */
|
|
1944
|
+
close(): void;
|
|
1945
|
+
/** Optional human-readable endpoint for the devtools route chip. */
|
|
1946
|
+
readonly label?: string;
|
|
1947
|
+
}
|
|
1948
|
+
/**
|
|
1949
|
+
* A request → single-correlated-reply carrier with no unsolicited push (HTTP). One `exchange` sends a
|
|
1950
|
+
* frame and resolves with exactly the one reply frame for it; the carrier itself correlates them (the
|
|
1951
|
+
* HTTP transaction), so no correlation id is needed on the wire.
|
|
1952
|
+
*/
|
|
1953
|
+
interface IExchangeCarrier {
|
|
1954
|
+
/** Send one frame, await the single correlated reply frame. */
|
|
1955
|
+
exchange(frame: TFrame$1, opts?: {
|
|
1956
|
+
signal?: AbortSignal;
|
|
1957
|
+
}): Promise<TFrame$1>;
|
|
1958
|
+
/** Optional human-readable endpoint for the devtools route chip. */
|
|
1959
|
+
readonly label?: string;
|
|
1960
|
+
}
|
|
1961
|
+
type TCarrier = IDuplexCarrier | IExchangeCarrier;
|
|
1962
|
+
/**
|
|
1963
|
+
* A reusable opener for a {@link IDuplexCarrier} plus the per-action metadata a duplex transport needs.
|
|
1964
|
+
* Built by the small carrier factories (`wsCarrier`, `rtcCarrier`, `inMemoryCarrier`) and handed to
|
|
1965
|
+
* {@link secureTransport} / `LinkTransport` — so adding a new carrier is "write one of these", nothing
|
|
1966
|
+
* else.
|
|
1967
|
+
*/
|
|
1968
|
+
interface IDuplexCarrierSource {
|
|
1969
|
+
/** Open (or reuse) the carrier for an action. */
|
|
1970
|
+
open: (input: ITransportRouteActionParams) => IDuplexCarrier;
|
|
1971
|
+
/** Keys identifying a reusable carrier, so one carrier is shared across actions to the same peer. */
|
|
1972
|
+
getCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
1973
|
+
/** Devtools route info for an action routed over this carrier. */
|
|
1974
|
+
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
1975
|
+
/** Short carrier-kind label for the devtools chip (e.g. `"ws"`, `"webrtc"`, `"memory"`). */
|
|
1976
|
+
readonly carrierLabel: string;
|
|
1977
|
+
}
|
|
1978
|
+
/**
|
|
1979
|
+
* The exchange-shape counterpart to {@link IDuplexCarrierSource}: a reusable opener for an
|
|
1980
|
+
* {@link IExchangeCarrier} plus the per-action metadata an exchange transport needs. Built by
|
|
1981
|
+
* `httpCarrier` and handed to {@link secureTransport} — adding a new request/reply protocol is "write
|
|
1982
|
+
* one of these". The `shape` tag lets {@link secureTransport} pick the duplex vs exchange transport.
|
|
1983
|
+
*/
|
|
1984
|
+
interface IExchangeCarrierSource {
|
|
1985
|
+
/** Discriminant so a generic factory can tell an exchange source from a duplex one. */
|
|
1986
|
+
readonly shape: "exchange";
|
|
1987
|
+
/** Open (or reuse) the carrier for an action. */
|
|
1988
|
+
open: (input: ITransportRouteActionParams) => IExchangeCarrier;
|
|
1989
|
+
/** Keys identifying a reusable carrier, so one carrier is shared across actions to the same peer. */
|
|
1990
|
+
getCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
1991
|
+
/** Devtools route info for an action routed over this carrier. */
|
|
1992
|
+
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
1993
|
+
/** Short carrier-kind label for the devtools chip (e.g. `"http"`). */
|
|
1994
|
+
readonly carrierLabel: string;
|
|
1995
|
+
}
|
|
1996
|
+
//#endregion
|
|
1997
|
+
//#region src/ActionRuntime/Transport/Carrier/AcceptorCarrier.types.d.ts
|
|
1998
|
+
/**
|
|
1999
|
+
* Acceptor-side carrier descriptors — the accept-in dual of the connector's {@link IDuplexCarrierSource}
|
|
2000
|
+
* / {@link IExchangeCarrierSource}. Where a connector source knows how to *open* a carrier to a peer, an
|
|
2001
|
+
* acceptor carrier knows how to *serve* one peer's traffic on this server. Both shapes are carrier-neutral
|
|
2002
|
+
* about security: `serveChannel` builds the crypto identity (link + TOFU resolver) and the security block
|
|
2003
|
+
* once from `(runtime, channel)` and fans it across every carrier, so a carrier descriptor never restates
|
|
2004
|
+
* it.
|
|
2005
|
+
*
|
|
2006
|
+
* Two shapes mirror the connector side:
|
|
2007
|
+
*
|
|
2008
|
+
* - {@link IDuplexAcceptorCarrier} — a persistent, push-capable byte stream (WebSocket, WebRTC, …). It can
|
|
2009
|
+
* push acceptor→connector, so it carries the return path and broadcasts, and it may need an upgrade step
|
|
2010
|
+
* (e.g. a Durable Object's `WebSocketPair`) and optional hibernation persistence.
|
|
2011
|
+
* - {@link IExchangeAcceptorCarrier} — a request → single-correlated-reply carrier with no unsolicited push
|
|
2012
|
+
* (HTTP). The reply rides the response to its own request; there is nothing to push and nothing to
|
|
2013
|
+
* upgrade.
|
|
2014
|
+
*/
|
|
2015
|
+
/**
|
|
2016
|
+
* Persistence + replay hooks for a duplex carrier whose connections outlive process eviction (e.g. a
|
|
2017
|
+
* Durable Object's hibernatable WebSockets). Optional — omit for a transport that never hibernates. The
|
|
2018
|
+
* same surface {@link createHibernatableWsServerAdapter} consumes, minus the handler it's bound to.
|
|
2019
|
+
*/
|
|
2020
|
+
interface IAcceptorHibernation<TConn> {
|
|
2021
|
+
/** All currently-live connections — replayed on build to rebuild bindings after a wake. */
|
|
2022
|
+
getConnections: () => TConn[];
|
|
2023
|
+
/** Read a connection's persisted binding (e.g. `(ws) => ws.deserializeAttachment()`). */
|
|
2024
|
+
getAttachment: (connection: TConn) => IAcceptorConnectionBinding | undefined;
|
|
2025
|
+
/** Persist a connection's binding when it is bound (e.g. `(ws, b) => ws.serializeAttachment(b)`). */
|
|
2026
|
+
setAttachment: (connection: TConn, binding: IAcceptorConnectionBinding) => void;
|
|
2027
|
+
}
|
|
2028
|
+
/**
|
|
2029
|
+
* A duplex carrier is also its own lifecycle handle: once it has been passed to `serveChannel`, feed each
|
|
2030
|
+
* inbound frame to {@link receive} and forget a connection on close/error with {@link drop}. This is how a
|
|
2031
|
+
* server with *several* duplex carriers routes each connection's traffic to the right one — you hold the
|
|
2032
|
+
* carrier you created and feed it directly, so no per-carrier router lookup is needed. The methods throw if
|
|
2033
|
+
* called before the carrier is served. (`serveChannel` binds the live router via {@link _activate}.)
|
|
2034
|
+
*/
|
|
2035
|
+
interface IDuplexCarrierLifecycle<TConn> {
|
|
2036
|
+
/** Feed one inbound frame from a live connection into the server. Throws until the carrier is served. */
|
|
2037
|
+
receive(connection: TConn, frame: TFrame$1): void;
|
|
2038
|
+
/** Forget a connection on close/error. No-op until the carrier is served. */
|
|
2039
|
+
drop(connection: TConn): void;
|
|
2040
|
+
/** @internal `serveChannel` binds this carrier's live connection router here. */
|
|
2041
|
+
_activate(router: IDuplexConnectionRouter<TConn>): void;
|
|
2042
|
+
}
|
|
2043
|
+
/**
|
|
2044
|
+
* A duplex (push-capable) carrier on the acceptor side. Describes how to write a frame back to a live
|
|
2045
|
+
* connection, how to perform the transport-specific upgrade that admits one, which requests are such
|
|
2046
|
+
* upgrades, and (optionally) how to persist bindings across hibernation. Built by `wsAcceptorCarrier` and
|
|
2047
|
+
* handed to `serveChannel`'s `carriers` list — the returned carrier is also its own lifecycle handle (see
|
|
2048
|
+
* {@link IDuplexCarrierLifecycle}).
|
|
2049
|
+
*/
|
|
2050
|
+
interface IDuplexAcceptorCarrier<TConn = unknown> extends IDuplexCarrierLifecycle<TConn> {
|
|
2051
|
+
/** Discriminant so `serveChannel` can tell a duplex carrier from an exchange one. */
|
|
2052
|
+
readonly shape: ETransportShape.duplex;
|
|
2053
|
+
/**
|
|
2054
|
+
* Whether each connection runs the secure handshake (default `true`). `false` makes it a plain duplex
|
|
2055
|
+
* carrier: connections speak the channel's wire codec directly with a self-asserted identity — no
|
|
2056
|
+
* handshake, pins, or encryption (the duplex dual of `httpAcceptorCarrier({ secure: false })`). A plain
|
|
2057
|
+
* carrier ignores the central crypto identity, so it needs no `storage` on `serveChannel`.
|
|
2058
|
+
*/
|
|
2059
|
+
secure?: boolean;
|
|
2060
|
+
/** Write an encoded frame to a specific live connection (e.g. `(ws, frame) => ws.send(frame)`). */
|
|
2061
|
+
send: (connection: TConn, frame: TFrame$1) => void;
|
|
2062
|
+
/**
|
|
2063
|
+
* Perform the transport-specific upgrade for an inbound request, returning its raw response (e.g. a
|
|
2064
|
+
* Durable Object's `new WebSocketPair()` + `ctx.acceptWebSocket()` → a `101`). Omit for a carrier that
|
|
2065
|
+
* is fed connections out of band (the server then only routes frames via {@link receive}/{@link drop}).
|
|
2066
|
+
*/
|
|
2067
|
+
upgrade?: (request: Request, url: URL) => Response | Promise<Response>;
|
|
2068
|
+
/**
|
|
2069
|
+
* Whether an inbound request is an upgrade for this carrier. Defaults to an `Upgrade: websocket` header.
|
|
2070
|
+
* Only consulted when {@link upgrade} is present.
|
|
2071
|
+
*/
|
|
2072
|
+
isUpgrade?: (request: Request, url: URL) => boolean;
|
|
2073
|
+
/** Optional persistence + replay for connections that survive eviction (Durable Object hibernation). */
|
|
2074
|
+
hibernation?: IAcceptorHibernation<TConn>;
|
|
2075
|
+
/** Short carrier-kind label for the devtools chip (e.g. `"ws"`, `"webrtc"`). */
|
|
2076
|
+
readonly carrierLabel: string;
|
|
2077
|
+
}
|
|
2078
|
+
/**
|
|
2079
|
+
* An exchange (request/reply) carrier on the acceptor side, over web-standard `Request`/`Response`. By
|
|
2080
|
+
* default it speaks the *secure* exchange protocol (handshake → token session → encrypted frames), whose
|
|
2081
|
+
* identity is supplied centrally by `serveChannel`. Set {@link secure} to `false` for a plain endpoint
|
|
2082
|
+
* that POSTs the raw action wire and returns the result inline — the request/reply dual of the connector's
|
|
2083
|
+
* `plainTransport({ carrier: httpCarrier(...) })`. So a server can pair a secure duplex (WebSocket) with a
|
|
2084
|
+
* plain HTTP fallback on the same runtime. Built by `httpAcceptorCarrier`.
|
|
2085
|
+
*/
|
|
2086
|
+
interface IExchangeAcceptorCarrier {
|
|
2087
|
+
/** Discriminant so `serveChannel` can tell an exchange carrier from a duplex one. */
|
|
2088
|
+
readonly shape: ETransportShape.exchange;
|
|
2089
|
+
/**
|
|
2090
|
+
* Whether this endpoint runs the secure exchange protocol (default `true`). `false` makes it a plain
|
|
2091
|
+
* endpoint: the body is the raw action wire and the result is the response body — no handshake, token,
|
|
2092
|
+
* or encryption. A plain endpoint ignores the central crypto identity entirely.
|
|
2093
|
+
*/
|
|
2094
|
+
secure?: boolean;
|
|
2095
|
+
/** Which requests carry an action exchange envelope on `POST`. Defaults to `serveChannel`'s path match. */
|
|
2096
|
+
isActionPath?: (url: URL) => boolean;
|
|
2097
|
+
/**
|
|
2098
|
+
* CORS headers merged onto every response (a preflight `OPTIONS` is answered `204`). Defaults to the
|
|
2099
|
+
* permissive `*` set; pass `false` to attach no CORS headers at all.
|
|
2100
|
+
*/
|
|
2101
|
+
cors?: Record<string, string> | false;
|
|
2102
|
+
/** Plain mode only: use the error's HTTP status for failures (default `true`). Ignored when secure. */
|
|
2103
|
+
useErrorStatus?: boolean;
|
|
2104
|
+
/** Short carrier-kind label for the devtools chip (e.g. `"http"`). */
|
|
2105
|
+
readonly carrierLabel: string;
|
|
2106
|
+
}
|
|
2107
|
+
type TAcceptorCarrier<TConn = unknown> = IDuplexAcceptorCarrier<TConn> | IExchangeAcceptorCarrier;
|
|
2108
|
+
/**
|
|
2109
|
+
* Narrow an acceptor carrier to the exchange shape via its `shape` discriminant — the one branch
|
|
2110
|
+
* `serveChannel` uses to pick the duplex (push-capable) vs exchange (request/reply) wiring. A duplex
|
|
2111
|
+
* carrier carries `shape: ETransportShape.duplex`, so the `else` branch is the duplex one.
|
|
2112
|
+
*/
|
|
2113
|
+
declare function isExchangeAcceptorCarrier<TConn>(carrier: TAcceptorCarrier<TConn>): carrier is IExchangeAcceptorCarrier;
|
|
2114
|
+
//#endregion
|
|
2115
|
+
//#region src/ActionRuntime/Channel/serveChannel.d.ts
|
|
2116
|
+
interface IServeChannelOptions<TConn> {
|
|
2117
|
+
/**
|
|
2118
|
+
* Coordinate of the *connecting clients* (typically env-only, e.g. `RuntimeCoordinate.env("web_app")`),
|
|
2119
|
+
* used to score return-path dispatch back to the right connection.
|
|
2120
|
+
*/
|
|
2121
|
+
clientEnv: RuntimeCoordinate;
|
|
2122
|
+
/**
|
|
2123
|
+
* One backing store for the server's crypto identity *and* its trust-on-first-use verify-key pins
|
|
2124
|
+
* (their keys don't collide). It is built once and shared across every carrier, so the WebSocket and the
|
|
2125
|
+
* secure-HTTP endpoint present the exact same verify/exchange keys and trust the same pinned clients.
|
|
2126
|
+
* Back it with persistent storage (e.g. a Durable Object's storage) so identity + pins survive eviction.
|
|
2127
|
+
*
|
|
2128
|
+
* Required only when at least one carrier is secure (the default). A fully-plain server (every carrier
|
|
2129
|
+
* `secure: false`) needs no storage and may omit it.
|
|
2130
|
+
*/
|
|
2131
|
+
storage?: StorageAdapter;
|
|
2132
|
+
/**
|
|
2133
|
+
* The carriers this channel is served over — the accept-in dual of `connectChannel`'s `transports`.
|
|
2134
|
+
* Build them with `wsAcceptorCarrier` / `httpAcceptorCarrier`. Any number of duplex (push-capable)
|
|
2135
|
+
* carriers are supported (e.g. WebSocket + WebRTC), plus at most one exchange (request/reply) carrier;
|
|
2136
|
+
* all share one crypto identity and one runtime, and each result/push routes back over the carrier its
|
|
2137
|
+
* client connected on.
|
|
2138
|
+
*/
|
|
2139
|
+
carriers: readonly TAcceptorCarrier<TConn>[];
|
|
2140
|
+
/** Your execution handlers (e.g. the local handler holding the action cases). Registered for you. */
|
|
2141
|
+
handlers?: TActionRuntimeHandler[];
|
|
2142
|
+
/**
|
|
2143
|
+
* The server's crypto identity. Defaults to a fresh {@link ClientCryptoKeyLink} over `storage`. Pass an
|
|
2144
|
+
* existing link only to share identity with acceptors built outside this call.
|
|
2145
|
+
*/
|
|
2146
|
+
link?: ClientCryptoKeyLink;
|
|
2147
|
+
/** Accepted level(s) for every carrier; defaults to negotiating any of none/authenticated/encrypted. */
|
|
2148
|
+
securityLevel?: ESecurityLevel | readonly ESecurityLevel[];
|
|
2149
|
+
/** Trust decision for a client's verify key; defaults to storage-backed TOFU over `storage`. */
|
|
2150
|
+
verifyKeyResolver?: IClientVerifyKeyResolver;
|
|
2151
|
+
/** Timeout (ms) applied to server-initiated actions awaiting a client response. */
|
|
2152
|
+
defaultTimeout?: number;
|
|
2153
|
+
}
|
|
2154
|
+
/**
|
|
2155
|
+
* One server serving a secure channel over several carriers — the accept-in dual of `connectChannel`,
|
|
2156
|
+
* returned by {@link serveChannel}. Wire its surface straight to the host's request/socket events.
|
|
2157
|
+
*/
|
|
2158
|
+
interface IChannelServer<TConn> {
|
|
2159
|
+
/**
|
|
2160
|
+
* The duplex acceptor handlers — one per duplex carrier, in carrier order (empty if none). For pushing,
|
|
2161
|
+
* prefer {@link pushToClient} (it resolves the owning handler); reach for these for cross-carrier work
|
|
2162
|
+
* like a per-handler `broadcast`.
|
|
2163
|
+
*/
|
|
2164
|
+
handlers: AcceptorHandler<TConn>[];
|
|
2165
|
+
/**
|
|
2166
|
+
* Unified request handler: answers the CORS preflight, performs the duplex upgrade for an upgrade
|
|
2167
|
+
* request, serves a secure-exchange action `POST`, else `404`. Forward the host's `fetch` straight to it.
|
|
2168
|
+
*/
|
|
2169
|
+
fetch: (request: Request) => Promise<Response>;
|
|
2170
|
+
/**
|
|
2171
|
+
* Convenience lifecycle for the *sole* duplex carrier — `receive` inbound frames, `drop` on close. Set
|
|
2172
|
+
* only when exactly one duplex carrier was provided; with several, feed each carrier handle directly
|
|
2173
|
+
* (every duplex carrier is its own lifecycle handle). `undefined` when there are zero or multiple.
|
|
2174
|
+
*/
|
|
2175
|
+
duplex?: IDuplexConnectionRouter<TConn>;
|
|
2176
|
+
/**
|
|
2177
|
+
* Push a server-initiated action to a connected client (the runtime is bound in, so unlike
|
|
2178
|
+
* {@link AcceptorHandler.pushToClient} you pass only the target + request). It routes through the duplex
|
|
2179
|
+
* carrier the target connected on. Throws if no duplex carrier currently holds the target.
|
|
2180
|
+
*/
|
|
2181
|
+
pushToClient: <DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string>(target: TConn | RuntimeCoordinate, request: ActionPayload_Request<DOM, ID>, options?: {
|
|
2182
|
+
timeout?: number;
|
|
2183
|
+
}) => RunningAction<DOM, ID>;
|
|
2184
|
+
}
|
|
2185
|
+
/**
|
|
2186
|
+
* Serve a secure channel over one or more carriers from a single call — the accept-in dual of
|
|
2187
|
+
* `connectChannel`. It builds the crypto identity (a {@link ClientCryptoKeyLink} + a storage-backed TOFU
|
|
2188
|
+
* resolver) and the security block (coordinate, dictionary version, accepted levels) *once* from
|
|
2189
|
+
* `(runtime, channel)` and fans them across every carrier, so the WebSocket and the secure-HTTP endpoint
|
|
2190
|
+
* can never drift apart. It registers your handlers (plus the duplex acceptor it builds) on the runtime,
|
|
2191
|
+
* wires hibernation when the duplex carrier declares it, and returns a single {@link IChannelServer} whose
|
|
2192
|
+
* `fetch` / `duplex` / `pushToClient` you forward straight to the host:
|
|
2193
|
+
* ```ts
|
|
2194
|
+
* const server = serveChannel(runtime, channel, {
|
|
2195
|
+
* clientEnv, storage,
|
|
2196
|
+
* carriers: [wsAcceptorCarrier({ send, upgrade, hibernation }), httpAcceptorCarrier()],
|
|
2197
|
+
* handlers: [localHandler],
|
|
2198
|
+
* });
|
|
2199
|
+
* // fetch(req) => server.fetch(req)
|
|
2200
|
+
* // webSocketMessage(conn, m) => server.duplex?.receive(conn, m)
|
|
2201
|
+
* // webSocketClose/Error(conn) => server.duplex?.drop(conn)
|
|
2202
|
+
* ```
|
|
2203
|
+
*
|
|
2204
|
+
* `TConn` (the live-connection token a duplex carrier hands back through `send`/`receive`/`drop`) is
|
|
2205
|
+
* inferred from the carriers — `WebSocket` for `wsAcceptorCarrier`, the data-channel type for a WebRTC
|
|
2206
|
+
* carrier, and so on — so it stays carrier-agnostic.
|
|
2207
|
+
*/
|
|
2208
|
+
declare function serveChannel<TO_ACCEPTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TConn = unknown>(runtime: ActionRuntime, channel: ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>, options: IServeChannelOptions<TConn>): IChannelServer<TConn>;
|
|
2209
|
+
//#endregion
|
|
1841
2210
|
//#region src/ActionRuntime/Transport/SecureSession/exchangeAcceptor.d.ts
|
|
1842
2211
|
/** Acceptor secure config for the exchange (HTTP) endpoint — same identity an `AcceptorHandler` uses. */
|
|
1843
2212
|
interface IExchangeAcceptorSecurity {
|
|
@@ -1895,6 +2264,13 @@ interface IActionFetchHandlerOptions {
|
|
|
1895
2264
|
isActionPath?: (url: URL) => boolean;
|
|
1896
2265
|
/** Which requests are WebSocket upgrades. Default: pathname ends with `/ws`. */
|
|
1897
2266
|
isWebSocketPath?: (url: URL) => boolean;
|
|
2267
|
+
/**
|
|
2268
|
+
* Whether a request is a WebSocket upgrade for this endpoint, given the whole request (not just the
|
|
2269
|
+
* URL). When set it *replaces* the default gate (an `Upgrade: websocket` header on an
|
|
2270
|
+
* {@link isWebSocketPath} match) — use it when the discriminant needs a header or method, not only the
|
|
2271
|
+
* path. Only consulted when {@link onWebSocketUpgrade} is present.
|
|
2272
|
+
*/
|
|
2273
|
+
isWebSocketUpgrade?: (request: Request, url: URL) => boolean;
|
|
1898
2274
|
/**
|
|
1899
2275
|
* Perform the transport-specific WebSocket upgrade (e.g. a Durable Object's
|
|
1900
2276
|
* `new WebSocketPair()` + `ctx.acceptWebSocket()` returning a `101`). Omit for HTTP-only endpoints.
|
|
@@ -1951,6 +2327,13 @@ interface ISecureAcceptorHandlerOptions<TConn> {
|
|
|
1951
2327
|
storageAdapter: StorageAdapter;
|
|
1952
2328
|
/** Write an encoded frame to a specific live connection (e.g. `(ws, frame) => ws.send(frame)`). */
|
|
1953
2329
|
send: (connection: TConn, frame: string | Uint8Array | ArrayBuffer) => void;
|
|
2330
|
+
/**
|
|
2331
|
+
* The server's crypto identity. Defaults to a fresh {@link ClientCryptoKeyLink} over `storageAdapter`.
|
|
2332
|
+
* Pass an existing link to share one identity across several acceptors on the same server (e.g. a
|
|
2333
|
+
* WebSocket acceptor and a secure-HTTP {@link createActionFetchHandler}), so they present the same
|
|
2334
|
+
* verify/exchange keys — avoiding a divergent-key race when two fresh links initialize concurrently.
|
|
2335
|
+
*/
|
|
2336
|
+
link?: ClientCryptoKeyLink;
|
|
1954
2337
|
/** Accepted level(s); defaults to negotiating any of none/authenticated/encrypted. */
|
|
1955
2338
|
securityLevel?: ESecurityLevel | readonly ESecurityLevel[];
|
|
1956
2339
|
/** Trust decision for a client's verify key; defaults to storage-backed TOFU over `storageAdapter`. */
|
|
@@ -2051,42 +2434,6 @@ declare class ConnectionStateStore<TConn, TApp> {
|
|
|
2051
2434
|
*/
|
|
2052
2435
|
declare function createConnectionStateStore<TConn, TApp>(handler: AcceptorHandler<TConn>, options: IConnectionStateStoreOptions<TConn, TApp>): ConnectionStateStore<TConn, TApp>;
|
|
2053
2436
|
//#endregion
|
|
2054
|
-
//#region src/ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/createHibernatableWsServerAdapter.d.ts
|
|
2055
|
-
interface IHibernatableWsServerAdapterOptions<TConn> {
|
|
2056
|
-
/** The handler to drive (from `createSecureAcceptorHandler` or `createAcceptorHandler`). */
|
|
2057
|
-
handler: AcceptorHandler<TConn>;
|
|
2058
|
-
/** All currently-live connections — replayed on construction to rebuild bindings after a wake. */
|
|
2059
|
-
getWebSockets: () => TConn[];
|
|
2060
|
-
/** Read a connection's persisted binding (e.g. `(ws) => ws.deserializeAttachment()`). */
|
|
2061
|
-
getAttachment: (connection: TConn) => IAcceptorConnectionBinding | undefined;
|
|
2062
|
-
/** Persist a connection's binding when it is bound (e.g. `(ws, b) => ws.serializeAttachment(b)`). */
|
|
2063
|
-
setAttachment: (connection: TConn, binding: IAcceptorConnectionBinding) => void;
|
|
2064
|
-
}
|
|
2065
|
-
interface IHibernatableWsServerAdapter<TConn> {
|
|
2066
|
-
/** Feed one inbound frame from a connection into the handler. */
|
|
2067
|
-
receive: (connection: TConn, frame: string | ArrayBuffer | Uint8Array) => void;
|
|
2068
|
-
/** Forget a connection (call on socket close/error). */
|
|
2069
|
-
drop: (connection: TConn) => void;
|
|
2070
|
-
}
|
|
2071
|
-
/**
|
|
2072
|
-
* Wire the hibernation lifecycle for an acceptor handler on a transport whose sockets outlive process
|
|
2073
|
-
* eviction (e.g. a Durable Object's hibernatable WebSockets). It owns persistence end to end:
|
|
2074
|
-
* registers `setAttachment` as the handler's connection-bound callback and immediately replays every
|
|
2075
|
-
* live connection's stored binding via `getAttachment`, so results/pushes still route after a wake.
|
|
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
|
-
*
|
|
2081
|
-
* Construct it once when the handler is built, then forward socket events:
|
|
2082
|
-
* ```ts
|
|
2083
|
-
* const wsServer = createHibernatableWsServerAdapter({ handler, getWebSockets, getAttachment, setAttachment });
|
|
2084
|
-
* // webSocketMessage(ws, msg) => wsServer.receive(ws, msg);
|
|
2085
|
-
* // webSocketClose/Error(ws) => wsServer.drop(ws);
|
|
2086
|
-
* ```
|
|
2087
|
-
*/
|
|
2088
|
-
declare function createHibernatableWsServerAdapter<TConn>(options: IHibernatableWsServerAdapterOptions<TConn>): IHibernatableWsServerAdapter<TConn>;
|
|
2089
|
-
//#endregion
|
|
2090
2437
|
//#region src/ActionRuntime/Handler/PeerLink/Connector/err_nice_external_client.d.ts
|
|
2091
2438
|
declare const err_nice_external_client: import("@nice-code/error").NiceErrorDomain<{
|
|
2092
2439
|
domain: string;
|
|
@@ -2094,97 +2441,6 @@ declare const err_nice_external_client: import("@nice-code/error").NiceErrorDoma
|
|
|
2094
2441
|
schema: {};
|
|
2095
2442
|
}>;
|
|
2096
2443
|
//#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
2444
|
//#region src/ActionRuntime/Transport/Carrier/duplex/inMemory/createInMemoryChannel.d.ts
|
|
2189
2445
|
type TFrame = string | ArrayBuffer | Uint8Array;
|
|
2190
2446
|
/** The peer (server) end of an in-memory pair — what you feed into an `AcceptorHandler`. */
|
|
@@ -2266,6 +2522,56 @@ interface IRtcCarrierOptions {
|
|
|
2266
2522
|
*/
|
|
2267
2523
|
declare function rtcCarrier(dataChannel: IRtcDataChannelLike, options?: IRtcCarrierOptions): IDuplexCarrierSource;
|
|
2268
2524
|
//#endregion
|
|
2525
|
+
//#region src/ActionRuntime/Transport/Carrier/duplex/ws/err_nice_transport_ws.d.ts
|
|
2526
|
+
declare enum EErrId_NiceTransport_WebSocket {
|
|
2527
|
+
ws_disconnected = "ws_disconnected",
|
|
2528
|
+
ws_create_failed = "ws_create_failed",
|
|
2529
|
+
ws_error = "ws_error"
|
|
2530
|
+
}
|
|
2531
|
+
declare const err_nice_transport_ws: import("@nice-code/error").NiceErrorDomain<{
|
|
2532
|
+
domain: string;
|
|
2533
|
+
allDomains: [string, string, string, string, "err_nice"];
|
|
2534
|
+
schema: {
|
|
2535
|
+
ws_disconnected: import("@nice-code/error").INiceErrorIdMetadata<Record<string, never>, import("@nice-code/error").JSONSerializableValue>;
|
|
2536
|
+
ws_create_failed: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
2537
|
+
originalError?: Error;
|
|
2538
|
+
}, import("@nice-code/error").JSONSerializableValue>;
|
|
2539
|
+
ws_error: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
2540
|
+
originalError?: Error;
|
|
2541
|
+
}, import("@nice-code/error").JSONSerializableValue>;
|
|
2542
|
+
};
|
|
2543
|
+
}>;
|
|
2544
|
+
//#endregion
|
|
2545
|
+
//#region src/ActionRuntime/Transport/Carrier/duplex/ws/wsAcceptorCarrier.d.ts
|
|
2546
|
+
interface IWsAcceptorCarrierOptions<TConn> {
|
|
2547
|
+
/**
|
|
2548
|
+
* Whether each socket runs the secure handshake (default `true`). Pass `false` for a plain WS endpoint
|
|
2549
|
+
* — connections speak the channel's wire codec with a self-asserted identity, no handshake/pins/encryption
|
|
2550
|
+
* (and `serveChannel` then needs no `storage` for this carrier).
|
|
2551
|
+
*/
|
|
2552
|
+
secure?: boolean;
|
|
2553
|
+
/** Write an encoded frame to a specific live connection (e.g. `(ws, frame) => ws.send(frame)`). */
|
|
2554
|
+
send: (connection: TConn, frame: TFrame$1) => void;
|
|
2555
|
+
/**
|
|
2556
|
+
* Perform the transport-specific WebSocket upgrade, returning its raw response (e.g. a Durable Object's
|
|
2557
|
+
* `new WebSocketPair()` + `ctx.acceptWebSocket()` → a `101`). Omit if sockets are fed in out of band.
|
|
2558
|
+
*/
|
|
2559
|
+
upgrade?: (request: Request, url: URL) => Response | Promise<Response>;
|
|
2560
|
+
/** Whether an inbound request is a WS upgrade. Defaults to an `Upgrade: websocket` header. */
|
|
2561
|
+
isUpgrade?: (request: Request, url: URL) => boolean;
|
|
2562
|
+
/** Persistence + replay hooks for hibernatable sockets (e.g. a Durable Object). */
|
|
2563
|
+
hibernation?: IAcceptorHibernation<TConn>;
|
|
2564
|
+
/** Override the devtools carrier-kind label (defaults to `"ws"`). */
|
|
2565
|
+
carrierLabel?: string;
|
|
2566
|
+
}
|
|
2567
|
+
/**
|
|
2568
|
+
* A WebSocket {@link IDuplexAcceptorCarrier}: the accept-in dual of {@link wsCarrier}. It describes how to
|
|
2569
|
+
* write frames back to a live socket, how to upgrade an inbound request into one, and (optionally) how to
|
|
2570
|
+
* persist bindings across hibernation. Hand it to `serveChannel`'s `carriers` list — the secure session,
|
|
2571
|
+
* codec, and crypto identity are supplied centrally there, so this only carries the WS-specific surface.
|
|
2572
|
+
*/
|
|
2573
|
+
declare function wsAcceptorCarrier<TConn = WebSocket>(options: IWsAcceptorCarrierOptions<TConn>): IDuplexAcceptorCarrier<TConn>;
|
|
2574
|
+
//#endregion
|
|
2269
2575
|
//#region src/ActionRuntime/Transport/Carrier/duplex/ws/wsCarrier.d.ts
|
|
2270
2576
|
interface IWsCarrierOptions {
|
|
2271
2577
|
/** Override socket creation (defaults to a `new WebSocket(url)` with `binaryType = "arraybuffer"`). */
|
|
@@ -2282,6 +2588,36 @@ interface IWsCarrierOptions {
|
|
|
2282
2588
|
*/
|
|
2283
2589
|
declare function wsCarrier(url: string, options?: IWsCarrierOptions): IDuplexCarrierSource;
|
|
2284
2590
|
//#endregion
|
|
2591
|
+
//#region src/ActionRuntime/Transport/Carrier/exchange/http/httpAcceptorCarrier.d.ts
|
|
2592
|
+
interface IHttpAcceptorCarrierOptions {
|
|
2593
|
+
/**
|
|
2594
|
+
* Whether this endpoint runs the secure exchange protocol (default `true`). Pass `false` for a plain
|
|
2595
|
+
* endpoint — the body is the raw action wire and the result is the response body, the request/reply dual
|
|
2596
|
+
* of `plainTransport({ carrier: httpCarrier(...) })`. A plain endpoint ignores the crypto identity, so it
|
|
2597
|
+
* can sit alongside a secure WebSocket on the same server (e.g. a secure WS preferred, plain HTTP fallback).
|
|
2598
|
+
*/
|
|
2599
|
+
secure?: boolean;
|
|
2600
|
+
/** Which requests carry an action exchange envelope on `POST`. Defaults to `serveChannel`'s path match. */
|
|
2601
|
+
isActionPath?: (url: URL) => boolean;
|
|
2602
|
+
/**
|
|
2603
|
+
* CORS headers merged onto every response (a preflight `OPTIONS` is answered `204`). Defaults to the
|
|
2604
|
+
* permissive `*` set; pass `false` to attach no CORS headers at all.
|
|
2605
|
+
*/
|
|
2606
|
+
cors?: Record<string, string> | false;
|
|
2607
|
+
/** Plain mode only: use the error's HTTP status for failures (default `true`). Ignored when secure. */
|
|
2608
|
+
useErrorStatus?: boolean;
|
|
2609
|
+
/** Override the devtools carrier-kind label (defaults to `"http"`). */
|
|
2610
|
+
carrierLabel?: string;
|
|
2611
|
+
}
|
|
2612
|
+
/**
|
|
2613
|
+
* An HTTP {@link IExchangeAcceptorCarrier}: the accept-in dual of {@link httpCarrier}. It serves the
|
|
2614
|
+
* secure exchange protocol (handshake → token session → encrypted frames) over web-standard
|
|
2615
|
+
* `Request`/`Response`. The crypto identity, runtime coordinate, dictionary version, and accepted security
|
|
2616
|
+
* levels are all supplied centrally by `serveChannel`, so this only needs to say which requests carry an
|
|
2617
|
+
* action envelope and how to answer CORS.
|
|
2618
|
+
*/
|
|
2619
|
+
declare function httpAcceptorCarrier(options?: IHttpAcceptorCarrierOptions): IExchangeAcceptorCarrier;
|
|
2620
|
+
//#endregion
|
|
2285
2621
|
//#region src/ActionRuntime/Transport/Carrier/exchange/http/httpCarrier.d.ts
|
|
2286
2622
|
/** The HTTP request an action is sent over (the body is supplied by the secure exchange session). */
|
|
2287
2623
|
interface IHttpCarrierRequest {
|
|
@@ -2455,26 +2791,6 @@ declare const err_nice_transport: import("@nice-code/error").NiceErrorDomain<{
|
|
|
2455
2791
|
};
|
|
2456
2792
|
}>;
|
|
2457
2793
|
//#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
2794
|
//#region src/ActionRuntime/Transport/Link/TransportLink.types.d.ts
|
|
2479
2795
|
/** The per-connection codec (positional binary wire / JSON fallback) the carrier's session uses. */
|
|
2480
2796
|
type TLinkFormatMessage = IActionWireFormat;
|
|
@@ -2835,5 +3151,5 @@ interface IActionPayload_Result_JsonObject<DOM extends IActionDomain = IActionDo
|
|
|
2835
3151
|
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>;
|
|
2836
3152
|
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>;
|
|
2837
3153
|
//#endregion
|
|
2838
|
-
export {
|
|
2839
|
-
//# sourceMappingURL=ActionPayload.types-
|
|
3154
|
+
export { EErrId_NiceTransport_WebSocket as $, IClientVerifyKeyResolver as $n, TTransportedValue as $r, IAcceptorConnectionBinding as $t, ILinkTransportOptions as A, ITransportStatusInfo_Ready as An, ActionPayload_Result as Ar, IDuplexCarrier as At, IActionFrameCryptoConfig as B, TSendActionDataMethod as Bn, TActionDomainChildDef as Br, IActionChannel as Bt, decodeActionFrame as C, ITransportMethod_SendActionData_Input as Cn, IRunningActionUpdate_Abort as Cr, IServeChannelOptions as Ct, secureTransport as D, ITransportStatusInfo_Base as Dn, TRunningActionUpdate as Dr, IExchangeAcceptorCarrier as Dt, ISecureTransportOptions as E, ITransportRouteInfo as En, IRunningActionUpdate_Success as Er, IDuplexAcceptorCarrier as Et, err_nice_transport as F, TOnResolveAnyIncomingActionData_Json as Fn, TRuntimeCoordinateEnvId as Fr, TFrame$1 as Ft, TCarrierFetch as G, TTransportStatusInfo_GetTransport_Output as Gn, TPossibleDomainId as Gr, acceptChannelConnections as Gt, createBinaryWireAdapter as H, TTransportCache as Hn, TDomainActionId as Hr, TChannelAcceptorCases as Ht, ExchangeTransport as I, TOnResolveIncomingRequest as In, TRuntimeCoordinateStringId as Ir, IDuplexConnectionRouter as It, httpAcceptorCarrier as J, Transport as Jn, EActionResponseMode as Jr, ISecureChannel as Jt, httpCarrier as K, TUpdateActionRunConfig as Kn, TPossibleDomainIdList as Kr, connectChannel as Kt, IExchangeTransportOptions as L, TOnResolveIncomingRequestJson as Ln, IActionDomain as Lr, IHibernatableWsServerAdapterOptions as Lt, IActionTransportReadyData_Link as M, IUpdateActionRunConfig_Output as Mn, IRuntimeCoordinateSpecifics as Mr, IExchangeCarrier as Mt, TLinkFormatMessage as N, TGetTransportFn as Nn, IRuntimeFullCoordinates as Nr, IExchangeCarrierSource as Nt, IPlainTransportOptions as O, ITransportStatusInfo_Failed as On, TRunningActionUpdateFinished as Or, TAcceptorCarrier as Ot, EErrId_NiceTransport as P, TOnResolveAnyIncomingActionData as Pn, RuntimeCoordinate as Pr, TCarrier as Pt, wsAcceptorCarrier as Q, IClientVerifyKeyResolveInput as Qn, TActionSerializationDefinition as Qr, AcceptorHandler as Qt, IActionTransportReadyData_Exchange as R, TOnResolveIncomingResponse as Rn, IActionDomainChildOptions as Rr, createHibernatableWsServerAdapter as Rt, IActionFrameDecoder as S, ITransportDispatchAction as Sn, ERunningActionUpdateType as Sr, IChannelServer as St, err_nice_action as T, ITransportRouteClientParams as Tn, IRunningActionUpdate_Started as Tr, IAcceptorHibernation as Tt, IHttpCarrierOptions as U, TTransportInitializationFinishedInfo as Un, TInferInputFromSchema as Ur, TChannelPushHandlers as Ut, createActionFrameCrypto as V, TSendReturnDataMethod as Vn, TActionDomainSchema as Vr, IConnectChannelOptions as Vt, IHttpCarrierRequest as W, TTransportStatusInfo as Wn, TInferOutputFromSchema as Wr, acceptChannel as Wt, wsCarrier as X, ESecurityLevel as Xn, actionSchema as Xr, IBinaryWireSessionOptions as Xt, IWsCarrierOptions as Y, EHandshakeMessageType as Yn, TInferActionError as Yr, defineSecureChannel as Yt, IWsAcceptorCarrierOptions as Z, IClientHandshakeConfig as Zn, TActionSchemaOptions as Zr, createBinaryWireSessionFactory as Zt, TActionProgress as _, IActionTransportReady as _n, ActionPayload_Request as _r, IActionFetchHandlerOptions as _t, IActionPayload_Data_Base as a, IActionWireFormat as an, createInMemoryTofuVerifyKeyResolver as ar, IInMemoryCarrier as at, isActionPayload_Request_JsonObject as b, IActionTransportResolvers as bn, ERunningActionFinishedType as br, IExchangeAcceptorConfig as bt, IActionPayload_Request_JsonObject as c, ActionDomain as cn, decodeHandshakeMessage as cr, IInMemoryServerEndpoint as ct, IActionProgress_Custom as d, ConnectorHandler as dn, PeerLinkHandler as dr, ConnectionStateStore as dt, IAcceptorHandlerOptions as en, IHandshakeEncryptionKeyMaterial as er, err_nice_transport_ws as et, IActionProgress_None as f, createConnectorHandler as fn, ActionLocalHandler as fr, IConnectionAttachment as ft, TActionPayload_Any_JsonObject as g, IActionTransportInitialized as gn, ActionPayload_Progress as gr, createSecureAcceptorHandler as gt, TActionPayload_Any_Instance as h, IActionTransportDef as hn, RunningAction as hr, ISecureAcceptorHandlerOptions as ht, IActionPayload_Base_JsonObject as i, createAcceptorHandler as in, createClientHandshake as ir, rtcDataChannelByteChannel as it, LinkTransport as j, ITransportStatusInfo_Unsupported as jn, IRuntimeCoordinate as jr, IDuplexCarrierSource as jt, plainTransport as k, ITransportStatusInfo_Initializing as kn, TRunningActionUpdateListener as kr, isExchangeAcceptorCarrier as kt, IActionPayload_Result as l, ActionRootDomain as ln, encodeHandshakeMessage as lr, createInMemoryChannelPair as lt, IActionRouteItemHandler as m, ETransportStatus as mn, MaybePromise as mr, createConnectionStateStore as mt, EActionProgressType as n, TActionChannelFormatMessage as nn, IServerHandshakeConfig as nr, rtcCarrier as nt, IActionPayload_Progress as o, createActionRootDomain as on, createServerHandshake as or, inMemoryCarrier as ot, IActionProgress_Percentage as p, ETransportShape as pn, createLocalHandler as pr, IConnectionStateStoreOptions as pt, IHttpAcceptorCarrierOptions as q, ITransportConnectionContext as qn, ActionSchema as qr, defineChannel as qt, IActionPayload_Base as r, TActionConnectionEncoding as rn, THandshakeMessage as rr, IRtcDataChannelLike as rt, IActionPayload_Progress_JsonObject as s, ActionCore as sn, createStorageTofuVerifyKeyResolver as sr, IInMemoryChannelPair as st, EActionPayloadType as t, TAcceptorConnectionCaseFn as tn, IHandshakeResult as tr, IRtcCarrierOptions as tt, IActionPayload_Result_JsonObject as u, ActionRuntime as un, runtimeLinkId as ur, err_nice_external_client as ut, TActionResultOutcome as v, IActionTransportReadyData_Base as vn, IActionCore as vr, createActionFetchHandler as vt, EErrId_NiceAction as w, ITransportRouteActionParams as wn, IRunningActionUpdate_Progress as wr, serveChannel as wt, isActionPayload_Any_JsonObject as x, ISecureClientConfig as xn, ERunningActionState as xr, IExchangeAcceptorSecurity as xt, isActionPayload_Result_JsonObject as y, IActionTransportReadyData_Methods as yn, IActionCore_JsonObject as yr, ExchangeAcceptor as yt, IActionFrameCrypto as z, TOnResolveIncomingResponseJson as zn, IActionRootDomain as zr, IAcceptChannelOptions as zt };
|
|
3155
|
+
//# sourceMappingURL=ActionPayload.types-snDlSIF-.d.cts.map
|