@nice-code/action 0.20.0 → 0.22.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 +140 -109
- package/build/{ActionDevtoolsCore-D_JvgPmz.d.mts → ActionDevtoolsCore-CQ0vrvPD.d.cts} +2 -2
- package/build/{ActionDevtoolsCore-dV-IVPcP.d.cts → ActionDevtoolsCore-CiLBYC3K.d.mts} +2 -2
- package/build/{ActionPayload.types-CnfWlkA1.d.cts → ActionPayload.types-Dx1JPyfs.d.mts} +292 -222
- package/build/{ActionPayload.types-D0DM-g65.d.mts → ActionPayload.types-L9k0LyBd.d.cts} +292 -222
- 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/httpAcceptorCarrier-DL8lf0xB.mjs +3906 -0
- package/build/httpAcceptorCarrier-DL8lf0xB.mjs.map +1 -0
- package/build/httpAcceptorCarrier-OnJxzsAD.cjs +4291 -0
- package/build/httpAcceptorCarrier-OnJxzsAD.cjs.map +1 -0
- package/build/index.cjs +395 -4125
- 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 +331 -4058
- package/build/index.mjs.map +1 -1
- package/build/platform/cloudflare/index.cjs +30 -2
- package/build/platform/cloudflare/index.cjs.map +1 -1
- package/build/platform/cloudflare/index.d.cts +55 -2
- package/build/platform/cloudflare/index.d.mts +55 -2
- package/build/platform/cloudflare/index.mjs +28 -2
- package/build/platform/cloudflare/index.mjs.map +1 -1
- package/build/react-query/index.d.cts +1 -1
- package/build/react-query/index.d.mts +1 -1
- package/package.json +4 -4
- package/build/wsAcceptorCarrier-BDJRIPfu.cjs +0 -103
- package/build/wsAcceptorCarrier-BDJRIPfu.cjs.map +0 -1
- package/build/wsAcceptorCarrier-CW2qX25W.mjs +0 -80
- package/build/wsAcceptorCarrier-CW2qX25W.mjs.map +0 -1
|
@@ -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";
|
|
3
2
|
import { RuntimeName } from "std-env";
|
|
4
3
|
import { ClientCryptoKeyLink, StorageAdapter, TSerializedCryptoKeyData_Ed25519_Raw, TSerializedCryptoKeyData_X25519_Raw, TTypeAndId } from "@nice-code/util";
|
|
5
4
|
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];
|
|
@@ -1283,16 +1283,16 @@ declare class ActionRuntime {
|
|
|
1283
1283
|
*/
|
|
1284
1284
|
addHandlers(handlers: TActionRuntimeHandler[]): this;
|
|
1285
1285
|
/**
|
|
1286
|
+
* @internal Low-level primitive — the public way to open a connection is `connectChannel`, which
|
|
1287
|
+
* derives routing from a channel and binds the crypto identity for you. This stays as the raw building
|
|
1288
|
+
* block it sits on (it restates domain lists by hand) and is not part of the supported surface.
|
|
1289
|
+
*
|
|
1286
1290
|
* Declare an external "backend client" in one call: build an
|
|
1287
1291
|
* {@link ConnectorHandler} for `externalCoordinate` carrying the given
|
|
1288
1292
|
* `transports`, route the listed `domains`/`actions` to it, register it (plus any
|
|
1289
1293
|
* `localHandlers` — e.g. server→client push handlers that share the same channel)
|
|
1290
1294
|
* on this runtime, and `apply()`. Returns the external handler so the caller can
|
|
1291
1295
|
* later `clearTransportCache()` it.
|
|
1292
|
-
*
|
|
1293
|
-
* Sugar over `new ConnectorHandler(...).forDomain(...)` + `addHandlers([...])`,
|
|
1294
|
-
* so a single runtime can host one handler per backend target with its transports
|
|
1295
|
-
* declared once and reused across every action routed to that backend.
|
|
1296
1296
|
*/
|
|
1297
1297
|
connectTo(externalCoordinate: RuntimeCoordinate, options: {
|
|
1298
1298
|
transports: Transport[];
|
|
@@ -1529,12 +1529,21 @@ type IAcceptorHandlerOptions<TConn> = IAcceptorHandlerBaseOptions<TConn> & ({
|
|
|
1529
1529
|
formatMessage?: never;
|
|
1530
1530
|
});
|
|
1531
1531
|
/**
|
|
1532
|
-
* A connection-aware execution case (see {@link AcceptorHandler.forConnectionDomainCases}). It
|
|
1533
|
-
*
|
|
1534
|
-
*
|
|
1535
|
-
*
|
|
1532
|
+
* A connection-aware execution case (see {@link AcceptorHandler.forConnectionDomainCases}). It receives
|
|
1533
|
+
* the primed request plus a per-invocation `context` — whatever the wiring's context mapper produces from
|
|
1534
|
+
* the originating connection. The low-level handler passes the raw connection (`TConn | undefined`); the
|
|
1535
|
+
* higher-level `serveChannel` enriches it into an `IConnectionContext` (state + broadcast + pushBack). A
|
|
1536
|
+
* case may return the action's raw output, a result payload, or nothing (auto-wrapped as an empty
|
|
1537
|
+
* success) — exactly like a local handler case.
|
|
1536
1538
|
*/
|
|
1537
|
-
type
|
|
1539
|
+
type TAcceptorCaseFn<DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string, TCtx> = (action: TDistributeActionPayload_Request<DOM, ID>, context: TCtx) => ReturnType<THandleActionExecutionFn<DOM, ID>> | void;
|
|
1540
|
+
/**
|
|
1541
|
+
* The connection-aware case the bare {@link AcceptorHandler} serves: its `context` is the originating
|
|
1542
|
+
* client's live connection (resolved from the request's `originClient`, `undefined` if the socket is
|
|
1543
|
+
* gone). It's {@link TAcceptorCaseFn} fixed to `TConn | undefined` — the un-enriched shape used by
|
|
1544
|
+
* {@link AcceptorHandler.forConnectionDomainCases} and `acceptChannelConnections`.
|
|
1545
|
+
*/
|
|
1546
|
+
type TAcceptorConnectionCaseFn<DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string, TConn> = TAcceptorCaseFn<DOM, ID, TConn | undefined>;
|
|
1538
1547
|
/**
|
|
1539
1548
|
* Server-side handler for backends that accept many client connections over a single open channel
|
|
1540
1549
|
* (WebSockets, Durable Objects, …). It is transport-agnostic: you feed it inbound frames with
|
|
@@ -1648,11 +1657,15 @@ declare class AcceptorHandler<TConn = unknown> extends PeerLinkHandler {
|
|
|
1648
1657
|
forConnectionDomainCases<FOR_DOM extends IActionDomain>(domain: ActionDomain<FOR_DOM>, cases: { [ID in keyof FOR_DOM["actionSchema"] & string]?: TAcceptorConnectionCaseFn<FOR_DOM, ID, TConn> }): ActionLocalHandler;
|
|
1649
1658
|
/**
|
|
1650
1659
|
* Like {@link forConnectionDomainCases} but spanning several domains with one merged case map — used
|
|
1651
|
-
* by channel-derived wiring (`acceptChannelConnections`) where the channel's
|
|
1652
|
-
* served together. Each domain takes only the cases whose ids it owns, so a
|
|
1653
|
-
* several domains and unrelated ids are ignored.
|
|
1660
|
+
* by channel-derived wiring (`acceptChannelConnections` / `serveChannel`) where the channel's
|
|
1661
|
+
* `toAcceptor` domains are served together. Each domain takes only the cases whose ids it owns, so a
|
|
1662
|
+
* single map can cover several domains and unrelated ids are ignored.
|
|
1663
|
+
*
|
|
1664
|
+
* `mapContext` turns the resolved connection into whatever the case's second argument should be: the
|
|
1665
|
+
* raw connection for the low-level helper, or an enriched `IConnectionContext` for `serveChannel`. It's
|
|
1666
|
+
* called once per inbound action, after the originating connection is resolved.
|
|
1654
1667
|
*/
|
|
1655
|
-
forConnectionDomainCasesMulti(domains: readonly ActionDomain<any>[], cases: Record<string,
|
|
1668
|
+
forConnectionDomainCasesMulti<TCtx>(domains: readonly ActionDomain<any>[], cases: Record<string, TAcceptorCaseFn<any, any, TCtx> | undefined>, mapContext: (connection: TConn | undefined, request: ActionPayload_Request<any, any>) => TCtx): ActionLocalHandler;
|
|
1656
1669
|
/**
|
|
1657
1670
|
* Fan a server-initiated request out to every currently-bound connection. A fresh request is built
|
|
1658
1671
|
* per connection (each push mutates its own action context) and dispatched fire-and-forget. Pass
|
|
@@ -1679,6 +1692,97 @@ declare class AcceptorHandler<TConn = unknown> extends PeerLinkHandler {
|
|
|
1679
1692
|
}
|
|
1680
1693
|
declare const createAcceptorHandler: <TConn = unknown>(options: IAcceptorHandlerOptions<TConn>) => AcceptorHandler<TConn>;
|
|
1681
1694
|
//#endregion
|
|
1695
|
+
//#region src/ActionRuntime/Transport/Carrier/Carrier.types.d.ts
|
|
1696
|
+
/**
|
|
1697
|
+
* Carrier shapes — the only transport-specific surface a new protocol must implement. The secure
|
|
1698
|
+
* session (handshake + frame crypto + codec) and the action routing on top of it are carrier-agnostic;
|
|
1699
|
+
* a carrier just moves frames. Two shapes capture every carrier:
|
|
1700
|
+
*
|
|
1701
|
+
* - {@link IDuplexCarrier} — a persistent, push-capable byte stream (WebSocket, WebRTC `RTCDataChannel`,
|
|
1702
|
+
* Bluetooth GATT, an in-memory pipe). Either side can send at any time, so it supports server→client
|
|
1703
|
+
* pushes (the return path + broadcast).
|
|
1704
|
+
* - {@link IExchangeCarrier} — a request → single-correlated-reply carrier with no unsolicited push
|
|
1705
|
+
* (HTTP, and anything request/response-shaped). The reply rides the response to its own request.
|
|
1706
|
+
*
|
|
1707
|
+
* Frames are `string` (text — handshake control messages and JSON action frames) or binary
|
|
1708
|
+
* (`Uint8Array`/`ArrayBuffer` — the optimized binary wire / encrypted frames).
|
|
1709
|
+
*/
|
|
1710
|
+
type TFrame$1 = string | Uint8Array | ArrayBuffer;
|
|
1711
|
+
/**
|
|
1712
|
+
* A bidirectional, push-capable byte stream. Reduces every duplex carrier to "open, send bytes, receive
|
|
1713
|
+
* bytes, close" — a WebSocket, a WebRTC data channel, a Bluetooth characteristic, or an in-memory pipe
|
|
1714
|
+
* all satisfy this, so the identical secure session runs over each.
|
|
1715
|
+
*/
|
|
1716
|
+
interface IDuplexCarrier {
|
|
1717
|
+
/** Resolves once the carrier is open and ready to send; rejects if it closes/errors before opening. */
|
|
1718
|
+
readonly ready: Promise<void>;
|
|
1719
|
+
/** Whether the carrier is currently open (a synchronous guard before `send`). */
|
|
1720
|
+
isOpen(): boolean;
|
|
1721
|
+
/** Write one frame to the peer. */
|
|
1722
|
+
send(frame: TFrame$1): void;
|
|
1723
|
+
/**
|
|
1724
|
+
* Register the carrier's handlers. Called exactly once by the session after `ready`. `onMessage`
|
|
1725
|
+
* receives every inbound frame; `onClose` fires when the carrier goes away.
|
|
1726
|
+
*/
|
|
1727
|
+
attach(handlers: {
|
|
1728
|
+
onMessage: (frame: TFrame$1) => void;
|
|
1729
|
+
onClose: () => void;
|
|
1730
|
+
onError?: (error: unknown) => void;
|
|
1731
|
+
}): void;
|
|
1732
|
+
/** Close the carrier deliberately (a teardown). */
|
|
1733
|
+
close(): void;
|
|
1734
|
+
/** Optional human-readable endpoint for the devtools route chip. */
|
|
1735
|
+
readonly label?: string;
|
|
1736
|
+
}
|
|
1737
|
+
/**
|
|
1738
|
+
* A request → single-correlated-reply carrier with no unsolicited push (HTTP). One `exchange` sends a
|
|
1739
|
+
* frame and resolves with exactly the one reply frame for it; the carrier itself correlates them (the
|
|
1740
|
+
* HTTP transaction), so no correlation id is needed on the wire.
|
|
1741
|
+
*/
|
|
1742
|
+
interface IExchangeCarrier {
|
|
1743
|
+
/** Send one frame, await the single correlated reply frame. */
|
|
1744
|
+
exchange(frame: TFrame$1, opts?: {
|
|
1745
|
+
signal?: AbortSignal;
|
|
1746
|
+
}): Promise<TFrame$1>;
|
|
1747
|
+
/** Optional human-readable endpoint for the devtools route chip. */
|
|
1748
|
+
readonly label?: string;
|
|
1749
|
+
}
|
|
1750
|
+
type TCarrier = IDuplexCarrier | IExchangeCarrier;
|
|
1751
|
+
/**
|
|
1752
|
+
* A reusable opener for a {@link IDuplexCarrier} plus the per-action metadata a duplex transport needs.
|
|
1753
|
+
* Built by the small carrier factories (`wsCarrier`, `rtcCarrier`, `inMemoryCarrier`) and handed to
|
|
1754
|
+
* {@link secureTransport} / `LinkTransport` — so adding a new carrier is "write one of these", nothing
|
|
1755
|
+
* else.
|
|
1756
|
+
*/
|
|
1757
|
+
interface IDuplexCarrierSource {
|
|
1758
|
+
/** Open (or reuse) the carrier for an action. */
|
|
1759
|
+
open: (input: ITransportRouteActionParams) => IDuplexCarrier;
|
|
1760
|
+
/** Keys identifying a reusable carrier, so one carrier is shared across actions to the same peer. */
|
|
1761
|
+
getCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
1762
|
+
/** Devtools route info for an action routed over this carrier. */
|
|
1763
|
+
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
1764
|
+
/** Short carrier-kind label for the devtools chip (e.g. `"ws"`, `"webrtc"`, `"memory"`). */
|
|
1765
|
+
readonly carrierLabel: string;
|
|
1766
|
+
}
|
|
1767
|
+
/**
|
|
1768
|
+
* The exchange-shape counterpart to {@link IDuplexCarrierSource}: a reusable opener for an
|
|
1769
|
+
* {@link IExchangeCarrier} plus the per-action metadata an exchange transport needs. Built by
|
|
1770
|
+
* `httpCarrier` and handed to {@link secureTransport} — adding a new request/reply protocol is "write
|
|
1771
|
+
* one of these". The `shape` tag lets {@link secureTransport} pick the duplex vs exchange transport.
|
|
1772
|
+
*/
|
|
1773
|
+
interface IExchangeCarrierSource {
|
|
1774
|
+
/** Discriminant so a generic factory can tell an exchange source from a duplex one. */
|
|
1775
|
+
readonly shape: "exchange";
|
|
1776
|
+
/** Open (or reuse) the carrier for an action. */
|
|
1777
|
+
open: (input: ITransportRouteActionParams) => IExchangeCarrier;
|
|
1778
|
+
/** Keys identifying a reusable carrier, so one carrier is shared across actions to the same peer. */
|
|
1779
|
+
getCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
1780
|
+
/** Devtools route info for an action routed over this carrier. */
|
|
1781
|
+
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
1782
|
+
/** Short carrier-kind label for the devtools chip (e.g. `"http"`). */
|
|
1783
|
+
readonly carrierLabel: string;
|
|
1784
|
+
}
|
|
1785
|
+
//#endregion
|
|
1682
1786
|
//#region src/ActionRuntime/Transport/codec/createBinaryWireSessionFactory.d.ts
|
|
1683
1787
|
type TFormatMessage = IActionWireFormat;
|
|
1684
1788
|
interface IBinaryWireSessionOptions {
|
|
@@ -1794,40 +1898,89 @@ type TDomainPushHandlers<D> = D extends ActionDomain<infer DEF> ? Partial<TWrapp
|
|
|
1794
1898
|
* the keys and input types follow the channel definition.
|
|
1795
1899
|
*/
|
|
1796
1900
|
type TChannelPushHandlers<TO_CONNECTOR extends readonly ActionDomain<any>[]> = TUnionToIntersection<TDomainPushHandlers<TO_CONNECTOR[number]>>;
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1901
|
+
/**
|
|
1902
|
+
* One transport to the peer, declared by *carrier* — the dial-out dual of `serveChannel`'s acceptor
|
|
1903
|
+
* carriers. {@link connectChannel} binds the shared facts (channel codec/version, runtime, crypto
|
|
1904
|
+
* identity) into each one, so a descriptor only carries what differs between transports: the carrier and
|
|
1905
|
+
* whether it runs the secure handshake.
|
|
1906
|
+
*
|
|
1907
|
+
* A duplex carrier (`wsCarrier(url)`, `rtcCarrier(dc)`) builds a push-capable link; an exchange carrier
|
|
1908
|
+
* (`httpCarrier(...)`) builds a request/reply transport. List them in preference order — the connection
|
|
1909
|
+
* prefers the first that's ready and falls through on failure (e.g. secure WS preferred, HTTP fallback).
|
|
1910
|
+
*/
|
|
1911
|
+
interface IConnectTransport {
|
|
1912
|
+
/** How to reach the peer — a duplex carrier (push-capable) or an exchange carrier (request/reply). */
|
|
1913
|
+
carrier: IDuplexCarrierSource | IExchangeCarrierSource;
|
|
1800
1914
|
/**
|
|
1801
|
-
*
|
|
1802
|
-
*
|
|
1803
|
-
*
|
|
1915
|
+
* Run the authenticated/encrypted handshake over this carrier. Defaults to `true`. A secure transport
|
|
1916
|
+
* draws its identity from the connection's shared `link`/`storage`; set `false` for a plain transport
|
|
1917
|
+
* (e.g. a bare HTTP fallback beside a secure WS), which then needs no `storage`.
|
|
1804
1918
|
*/
|
|
1805
|
-
|
|
1919
|
+
secure?: boolean;
|
|
1920
|
+
/** Security level for this secure transport; defaults to the connection-level `securityLevel`. */
|
|
1921
|
+
securityLevel?: ESecurityLevel;
|
|
1922
|
+
/**
|
|
1923
|
+
* Optional availability gate — when it returns `false` this transport is skipped and the connection
|
|
1924
|
+
* falls through to the next in preference order, re-evaluated per dispatch. Omit = always available.
|
|
1925
|
+
*/
|
|
1926
|
+
available?: (input: ITransportRouteActionParams) => boolean;
|
|
1927
|
+
/** Override the devtools chip label (defaults to the carrier's own label). */
|
|
1928
|
+
label?: string;
|
|
1929
|
+
}
|
|
1930
|
+
interface IConnectChannelOptions<TO_CONNECTOR extends readonly ActionDomain<any>[]> {
|
|
1931
|
+
/** The peer's runtime coordinate — the acceptor this connection dials. */
|
|
1932
|
+
peer: RuntimeCoordinate;
|
|
1933
|
+
/**
|
|
1934
|
+
* The transports to the peer, by carrier, in preference order (e.g. secure WS preferred, HTTP fallback).
|
|
1935
|
+
* They all carry the channel's `toAcceptor` domains; the connection prefers the first that's ready and
|
|
1936
|
+
* falls through on failure. {@link connectChannel} binds the channel + runtime + crypto identity into
|
|
1937
|
+
* each — the dial-out dual of `serveChannel`'s `carriers`.
|
|
1938
|
+
*/
|
|
1939
|
+
transports: readonly IConnectTransport[];
|
|
1940
|
+
/**
|
|
1941
|
+
* One backing store for this connection's crypto identity, fanned across every *secure* transport so
|
|
1942
|
+
* they present the same verify/exchange keys. Required when any transport is secure (the default); a
|
|
1943
|
+
* fully-plain connection (every transport `secure: false`) may omit it. Pass `link` instead to share an
|
|
1944
|
+
* existing identity.
|
|
1945
|
+
*/
|
|
1946
|
+
storage?: StorageAdapter;
|
|
1947
|
+
/** The connection's crypto identity. Defaults to a fresh {@link ClientCryptoKeyLink} over `storage`. */
|
|
1948
|
+
link?: ClientCryptoKeyLink;
|
|
1949
|
+
/** Default security level for secure transports; defaults to `authenticated`. */
|
|
1950
|
+
securityLevel?: ESecurityLevel;
|
|
1806
1951
|
/** Handlers for the channel's acceptor→connector pushes. Optional — omit for a send-only connection. */
|
|
1807
1952
|
onPush?: TChannelPushHandlers<TO_CONNECTOR>;
|
|
1808
1953
|
/** Default per-action timeout for this connection. */
|
|
1809
1954
|
defaultTimeout?: number;
|
|
1810
1955
|
}
|
|
1811
1956
|
/**
|
|
1812
|
-
*
|
|
1813
|
-
* the
|
|
1814
|
-
* `
|
|
1815
|
-
*
|
|
1816
|
-
*
|
|
1817
|
-
* fallback)
|
|
1818
|
-
*
|
|
1819
|
-
*
|
|
1820
|
-
*
|
|
1957
|
+
* Open a connection to a peer from a single call — the dial-out dual of `serveChannel`. The channel is
|
|
1958
|
+
* the single source of truth for *what* is routed (`toAcceptor` domains forwarded to the peer,
|
|
1959
|
+
* `toConnector` pushes handled locally from `onPush`); the call binds the shared facts — the channel's
|
|
1960
|
+
* codec/dictionary version, the runtime, and one crypto identity (a {@link ClientCryptoKeyLink} over
|
|
1961
|
+
* `storage`) — into every transport in `transports`, so none of them restate the channel or runtime.
|
|
1962
|
+
* List several transports to make the path transport-agnostic (secure WS preferred, HTTP fallback):
|
|
1963
|
+
* ```ts
|
|
1964
|
+
* const handler = connectChannel(runtime, lobbyChannel, {
|
|
1965
|
+
* peer: runtime_coordinate_lobby_do,
|
|
1966
|
+
* storage,
|
|
1967
|
+
* transports: [{ carrier: wsCarrier(url) }, { carrier: httpCarrier(...), secure: false }],
|
|
1968
|
+
* onPush: { player_joined: (p) => { … } },
|
|
1969
|
+
* });
|
|
1970
|
+
* ```
|
|
1971
|
+
* Returns the {@link ConnectorHandler} so the caller can later `clearTransportCache()` it.
|
|
1821
1972
|
*/
|
|
1822
|
-
declare function connectChannel<TO_ACCEPTOR extends readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[]>(runtime: ActionRuntime,
|
|
1823
|
-
type TDomainAcceptorCases<D,
|
|
1973
|
+
declare function connectChannel<TO_ACCEPTOR extends readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[]>(runtime: ActionRuntime, channel: ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>, options: IConnectChannelOptions<TO_CONNECTOR>): ConnectorHandler;
|
|
1974
|
+
type TDomainAcceptorCases<D, TCtx> = D extends ActionDomain<infer DEF> ? { [ID in keyof DEF["actionSchema"] & string]?: TAcceptorCaseFn<DEF, ID, TCtx> } : never;
|
|
1824
1975
|
/**
|
|
1825
1976
|
* The connection-aware case map for a channel's acceptor side: the merged set of every
|
|
1826
|
-
* connector→acceptor (`toAcceptor`) action handler, each receiving the primed request plus
|
|
1827
|
-
*
|
|
1828
|
-
*
|
|
1977
|
+
* connector→acceptor (`toAcceptor`) action handler, each receiving the primed request plus a per-action
|
|
1978
|
+
* `context`. `TCtx` is whatever the wiring supplies as that second argument — the raw connection
|
|
1979
|
+
* (`TConn | undefined`) for the low-level `acceptChannelConnections`, or an enriched `IConnectionContext`
|
|
1980
|
+
* for `serveChannel`'s `channelCases`. Derived from the channel's `toAcceptorDomains`, so the keys and
|
|
1981
|
+
* input/output types follow the channel.
|
|
1829
1982
|
*/
|
|
1830
|
-
type TChannelAcceptorCases<TO_ACCEPTOR extends readonly ActionDomain<any>[],
|
|
1983
|
+
type TChannelAcceptorCases<TO_ACCEPTOR extends readonly ActionDomain<any>[], TCtx> = TUnionToIntersection<TDomainAcceptorCases<TO_ACCEPTOR[number], TCtx>>;
|
|
1831
1984
|
/**
|
|
1832
1985
|
* Register an acceptor handler's execution for a channel straight from its definition: the channel's
|
|
1833
1986
|
* `toAcceptor` domains are served together with one merged, connection-aware case map (each case gets
|
|
@@ -1837,8 +1990,11 @@ type TChannelAcceptorCases<TO_ACCEPTOR extends readonly ActionDomain<any>[], TCo
|
|
|
1837
1990
|
* ```ts
|
|
1838
1991
|
* runtime.addHandlers([acceptChannelConnections(serverHandler, channel, { … }), serverHandler]);
|
|
1839
1992
|
* ```
|
|
1993
|
+
*
|
|
1994
|
+
* The case's second argument is the raw connection (`TConn | undefined`). For the richer state +
|
|
1995
|
+
* broadcast + pushBack context, serve the channel through `serveChannel`'s `channelCases` instead.
|
|
1840
1996
|
*/
|
|
1841
|
-
declare function acceptChannelConnections<TO_ACCEPTOR extends readonly ActionDomain<any>[], TConn>(serverHandler: AcceptorHandler<TConn>, channel: IActionChannel<TO_ACCEPTOR, any>, cases: TChannelAcceptorCases<TO_ACCEPTOR, TConn>): ActionLocalHandler;
|
|
1997
|
+
declare function acceptChannelConnections<TO_ACCEPTOR extends readonly ActionDomain<any>[], TConn>(serverHandler: AcceptorHandler<TConn>, channel: IActionChannel<TO_ACCEPTOR, any>, cases: TChannelAcceptorCases<TO_ACCEPTOR, TConn | undefined>): ActionLocalHandler;
|
|
1842
1998
|
interface IAcceptChannelOptions<TConn> {
|
|
1843
1999
|
/**
|
|
1844
2000
|
* Coordinate of the *connecting clients* (typically env-only, e.g. `RuntimeCoordinate.env("web_app")`),
|
|
@@ -2001,97 +2157,6 @@ interface IDuplexConnectionRouter<TConn> {
|
|
|
2001
2157
|
*/
|
|
2002
2158
|
declare function createHibernatableWsServerAdapter<TConn>(options: IHibernatableWsServerAdapterOptions<TConn>): IDuplexConnectionRouter<TConn>;
|
|
2003
2159
|
//#endregion
|
|
2004
|
-
//#region src/ActionRuntime/Transport/Carrier/Carrier.types.d.ts
|
|
2005
|
-
/**
|
|
2006
|
-
* Carrier shapes — the only transport-specific surface a new protocol must implement. The secure
|
|
2007
|
-
* session (handshake + frame crypto + codec) and the action routing on top of it are carrier-agnostic;
|
|
2008
|
-
* a carrier just moves frames. Two shapes capture every carrier:
|
|
2009
|
-
*
|
|
2010
|
-
* - {@link IDuplexCarrier} — a persistent, push-capable byte stream (WebSocket, WebRTC `RTCDataChannel`,
|
|
2011
|
-
* Bluetooth GATT, an in-memory pipe). Either side can send at any time, so it supports server→client
|
|
2012
|
-
* pushes (the return path + broadcast).
|
|
2013
|
-
* - {@link IExchangeCarrier} — a request → single-correlated-reply carrier with no unsolicited push
|
|
2014
|
-
* (HTTP, and anything request/response-shaped). The reply rides the response to its own request.
|
|
2015
|
-
*
|
|
2016
|
-
* Frames are `string` (text — handshake control messages and JSON action frames) or binary
|
|
2017
|
-
* (`Uint8Array`/`ArrayBuffer` — the optimized binary wire / encrypted frames).
|
|
2018
|
-
*/
|
|
2019
|
-
type TFrame$1 = string | Uint8Array | ArrayBuffer;
|
|
2020
|
-
/**
|
|
2021
|
-
* A bidirectional, push-capable byte stream. Reduces every duplex carrier to "open, send bytes, receive
|
|
2022
|
-
* bytes, close" — a WebSocket, a WebRTC data channel, a Bluetooth characteristic, or an in-memory pipe
|
|
2023
|
-
* all satisfy this, so the identical secure session runs over each.
|
|
2024
|
-
*/
|
|
2025
|
-
interface IDuplexCarrier {
|
|
2026
|
-
/** Resolves once the carrier is open and ready to send; rejects if it closes/errors before opening. */
|
|
2027
|
-
readonly ready: Promise<void>;
|
|
2028
|
-
/** Whether the carrier is currently open (a synchronous guard before `send`). */
|
|
2029
|
-
isOpen(): boolean;
|
|
2030
|
-
/** Write one frame to the peer. */
|
|
2031
|
-
send(frame: TFrame$1): void;
|
|
2032
|
-
/**
|
|
2033
|
-
* Register the carrier's handlers. Called exactly once by the session after `ready`. `onMessage`
|
|
2034
|
-
* receives every inbound frame; `onClose` fires when the carrier goes away.
|
|
2035
|
-
*/
|
|
2036
|
-
attach(handlers: {
|
|
2037
|
-
onMessage: (frame: TFrame$1) => void;
|
|
2038
|
-
onClose: () => void;
|
|
2039
|
-
onError?: (error: unknown) => void;
|
|
2040
|
-
}): void;
|
|
2041
|
-
/** Close the carrier deliberately (a teardown). */
|
|
2042
|
-
close(): void;
|
|
2043
|
-
/** Optional human-readable endpoint for the devtools route chip. */
|
|
2044
|
-
readonly label?: string;
|
|
2045
|
-
}
|
|
2046
|
-
/**
|
|
2047
|
-
* A request → single-correlated-reply carrier with no unsolicited push (HTTP). One `exchange` sends a
|
|
2048
|
-
* frame and resolves with exactly the one reply frame for it; the carrier itself correlates them (the
|
|
2049
|
-
* HTTP transaction), so no correlation id is needed on the wire.
|
|
2050
|
-
*/
|
|
2051
|
-
interface IExchangeCarrier {
|
|
2052
|
-
/** Send one frame, await the single correlated reply frame. */
|
|
2053
|
-
exchange(frame: TFrame$1, opts?: {
|
|
2054
|
-
signal?: AbortSignal;
|
|
2055
|
-
}): Promise<TFrame$1>;
|
|
2056
|
-
/** Optional human-readable endpoint for the devtools route chip. */
|
|
2057
|
-
readonly label?: string;
|
|
2058
|
-
}
|
|
2059
|
-
type TCarrier = IDuplexCarrier | IExchangeCarrier;
|
|
2060
|
-
/**
|
|
2061
|
-
* A reusable opener for a {@link IDuplexCarrier} plus the per-action metadata a duplex transport needs.
|
|
2062
|
-
* Built by the small carrier factories (`wsCarrier`, `rtcCarrier`, `inMemoryCarrier`) and handed to
|
|
2063
|
-
* {@link secureTransport} / `LinkTransport` — so adding a new carrier is "write one of these", nothing
|
|
2064
|
-
* else.
|
|
2065
|
-
*/
|
|
2066
|
-
interface IDuplexCarrierSource {
|
|
2067
|
-
/** Open (or reuse) the carrier for an action. */
|
|
2068
|
-
open: (input: ITransportRouteActionParams) => IDuplexCarrier;
|
|
2069
|
-
/** Keys identifying a reusable carrier, so one carrier is shared across actions to the same peer. */
|
|
2070
|
-
getCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
2071
|
-
/** Devtools route info for an action routed over this carrier. */
|
|
2072
|
-
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
2073
|
-
/** Short carrier-kind label for the devtools chip (e.g. `"ws"`, `"webrtc"`, `"memory"`). */
|
|
2074
|
-
readonly carrierLabel: string;
|
|
2075
|
-
}
|
|
2076
|
-
/**
|
|
2077
|
-
* The exchange-shape counterpart to {@link IDuplexCarrierSource}: a reusable opener for an
|
|
2078
|
-
* {@link IExchangeCarrier} plus the per-action metadata an exchange transport needs. Built by
|
|
2079
|
-
* `httpCarrier` and handed to {@link secureTransport} — adding a new request/reply protocol is "write
|
|
2080
|
-
* one of these". The `shape` tag lets {@link secureTransport} pick the duplex vs exchange transport.
|
|
2081
|
-
*/
|
|
2082
|
-
interface IExchangeCarrierSource {
|
|
2083
|
-
/** Discriminant so a generic factory can tell an exchange source from a duplex one. */
|
|
2084
|
-
readonly shape: "exchange";
|
|
2085
|
-
/** Open (or reuse) the carrier for an action. */
|
|
2086
|
-
open: (input: ITransportRouteActionParams) => IExchangeCarrier;
|
|
2087
|
-
/** Keys identifying a reusable carrier, so one carrier is shared across actions to the same peer. */
|
|
2088
|
-
getCacheKey?: (input: ITransportRouteActionParams) => string[];
|
|
2089
|
-
/** Devtools route info for an action routed over this carrier. */
|
|
2090
|
-
getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
|
|
2091
|
-
/** Short carrier-kind label for the devtools chip (e.g. `"http"`). */
|
|
2092
|
-
readonly carrierLabel: string;
|
|
2093
|
-
}
|
|
2094
|
-
//#endregion
|
|
2095
2160
|
//#region src/ActionRuntime/Transport/Carrier/AcceptorCarrier.types.d.ts
|
|
2096
2161
|
/**
|
|
2097
2162
|
* Acceptor-side carrier descriptors — the accept-in dual of the connector's {@link IDuplexCarrierSource}
|
|
@@ -2227,6 +2292,43 @@ interface IServeConnectionStateOptions<TApp> {
|
|
|
2227
2292
|
*/
|
|
2228
2293
|
schema?: StandardSchemaV1<unknown, TApp>;
|
|
2229
2294
|
}
|
|
2295
|
+
/**
|
|
2296
|
+
* The per-action handle a `serveChannel` `channelCases` case receives as its second argument — the
|
|
2297
|
+
* originating connection enriched with everything a case typically reaches for, so it never threads
|
|
2298
|
+
* `ws` through `this.connections` / `this.server` by hand:
|
|
2299
|
+
*
|
|
2300
|
+
* - {@link state} / {@link setState} / {@link clearState} — the connection's typed app state (when
|
|
2301
|
+
* `connectionState` is configured), co-stored with the routing binding so it survives hibernation.
|
|
2302
|
+
* - {@link broadcast} — fan a server push to every other connection (skip self with `exceptSelf`).
|
|
2303
|
+
* - {@link pushBack} — push a server-initiated action down *this* same connection.
|
|
2304
|
+
*
|
|
2305
|
+
* Over the HTTP-exchange path there is no live socket: {@link connection} is `null`, {@link state} reads
|
|
2306
|
+
* `null`, {@link setState}/{@link clearState} are no-ops, and {@link pushBack} throws (an exchange reply
|
|
2307
|
+
* rides its own request — it can't carry an unsolicited push).
|
|
2308
|
+
*/
|
|
2309
|
+
interface IConnectionContext<TConn, TApp = unknown> {
|
|
2310
|
+
/** The originating live connection, or `null` on the HTTP-exchange path (escape hatch). */
|
|
2311
|
+
connection: TConn | null;
|
|
2312
|
+
/** The originating client's coordinate (`= action.context.originClient`). */
|
|
2313
|
+
origin: RuntimeCoordinate;
|
|
2314
|
+
/** This connection's app state, or `null` if unset / no live socket. */
|
|
2315
|
+
state: TApp | null;
|
|
2316
|
+
/** Set this connection's app state (no-op without a live socket). Preserves the routing binding. */
|
|
2317
|
+
setState: (value: TApp) => void;
|
|
2318
|
+
/** Clear this connection's app state but keep the routing binding (no-op without a live socket). */
|
|
2319
|
+
clearState: () => void;
|
|
2320
|
+
/** Fan a server-initiated action out to every connection; `exceptSelf` skips this one. */
|
|
2321
|
+
broadcast: <DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string>(makeRequest: () => ActionPayload_Request<DOM, ID>, options?: {
|
|
2322
|
+
exceptSelf?: boolean;
|
|
2323
|
+
where?: (connection: TConn) => boolean;
|
|
2324
|
+
timeout?: number;
|
|
2325
|
+
onError?: (error: unknown, connection: TConn) => void;
|
|
2326
|
+
}) => void;
|
|
2327
|
+
/** Push a server-initiated action down this same connection. Throws if there is no live socket. */
|
|
2328
|
+
pushBack: <DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string>(request: ActionPayload_Request<DOM, ID>, options?: {
|
|
2329
|
+
timeout?: number;
|
|
2330
|
+
}) => RunningAction<DOM, ID>;
|
|
2331
|
+
}
|
|
2230
2332
|
interface IServeChannelOptions<TO_ACCEPTOR extends readonly ActionDomain<any>[], TConn, TApp = unknown> {
|
|
2231
2333
|
/**
|
|
2232
2334
|
* Coordinate of the *connecting clients* (typically env-only, e.g. `RuntimeCoordinate.env("web_app")`),
|
|
@@ -2273,10 +2375,11 @@ interface IServeChannelOptions<TO_ACCEPTOR extends readonly ActionDomain<any>[],
|
|
|
2273
2375
|
connectionState?: IServeConnectionStateOptions<TApp>;
|
|
2274
2376
|
/**
|
|
2275
2377
|
* Connection-aware action cases for the channel's acceptor (`toAcceptor`) domains — each case receives the
|
|
2276
|
-
* primed request *and*
|
|
2277
|
-
*
|
|
2378
|
+
* primed request *and* an {@link IConnectionContext} (the connection plus its typed `state` and
|
|
2379
|
+
* `broadcast`/`pushBack`). The connection-aware dual of `handlers`, registered on the runtime for you.
|
|
2380
|
+
* Requires exactly one duplex carrier.
|
|
2278
2381
|
*/
|
|
2279
|
-
channelCases?: TChannelAcceptorCases<TO_ACCEPTOR, TConn
|
|
2382
|
+
channelCases?: TChannelAcceptorCases<TO_ACCEPTOR, IConnectionContext<TConn, TApp>>;
|
|
2280
2383
|
}
|
|
2281
2384
|
/**
|
|
2282
2385
|
* One server serving a secure channel over several carriers — the accept-in dual of `connectChannel`,
|
|
@@ -2295,11 +2398,17 @@ interface IChannelServer<TConn, TApp = unknown> {
|
|
|
2295
2398
|
*/
|
|
2296
2399
|
fetch: (request: Request) => Promise<Response>;
|
|
2297
2400
|
/**
|
|
2298
|
-
*
|
|
2299
|
-
*
|
|
2300
|
-
*
|
|
2401
|
+
* Feed one inbound frame from a live connection into the server — forward your host's "message" event
|
|
2402
|
+
* here (a Durable Object's `webSocketMessage`, a Bun `websocket.message`, a Node `ws.on("message")`).
|
|
2403
|
+
* Routes to the sole duplex carrier; throws with a clear message when there are zero or several duplex
|
|
2404
|
+
* carriers (for the multi-carrier case feed each `handlers[i]` / carrier handle directly).
|
|
2301
2405
|
*/
|
|
2302
|
-
|
|
2406
|
+
receive: (connection: TConn, frame: string | Uint8Array | ArrayBuffer) => void;
|
|
2407
|
+
/**
|
|
2408
|
+
* Forget a connection on close/error — forward your host's "close"/"error" event here. Routes to the
|
|
2409
|
+
* sole duplex carrier; a no-op when there are none (an HTTP-only server has no sockets to drop).
|
|
2410
|
+
*/
|
|
2411
|
+
drop: (connection: TConn) => void;
|
|
2303
2412
|
/**
|
|
2304
2413
|
* Push a server-initiated action to a connected client (the runtime is bound in, so unlike
|
|
2305
2414
|
* {@link AcceptorHandler.pushToClient} you pass only the target + request). It routes through the duplex
|
|
@@ -2333,21 +2442,24 @@ interface IChannelServer<TConn, TApp = unknown> {
|
|
|
2333
2442
|
* `(runtime, channel)` and fans them across every carrier, so the WebSocket and the secure-HTTP endpoint
|
|
2334
2443
|
* can never drift apart. It registers your handlers (plus the duplex acceptor it builds) on the runtime,
|
|
2335
2444
|
* wires hibernation when the duplex carrier exposes an attachment store, and returns a single
|
|
2336
|
-
* {@link IChannelServer} whose `fetch` / `
|
|
2337
|
-
* the host:
|
|
2445
|
+
* {@link IChannelServer} whose `fetch` / `receive` / `drop` / `pushToClient` / `broadcast` you forward
|
|
2446
|
+
* straight to the host:
|
|
2338
2447
|
* ```ts
|
|
2339
2448
|
* const server = serveChannel(runtime, channel, {
|
|
2340
2449
|
* clientEnv, storage,
|
|
2341
2450
|
* carriers: [wsAcceptorCarrier({ send, upgrade, attachmentStore }), httpAcceptorCarrier()],
|
|
2342
2451
|
* connectionState: { schema: vs_player }, // optional: co-store per-connection app state (survives hibernation)
|
|
2343
|
-
* channelCases: { join: (action, conn) => { … } }, //
|
|
2452
|
+
* channelCases: { join: (action, conn) => { conn.setState(action.input); … } }, // connection-aware cases
|
|
2344
2453
|
* });
|
|
2345
2454
|
* // fetch(req) => server.fetch(req)
|
|
2346
|
-
* // webSocketMessage(conn, m) => server.
|
|
2347
|
-
* // webSocketClose/Error(conn) => server.
|
|
2455
|
+
* // webSocketMessage(conn, m) => server.receive(conn, m)
|
|
2456
|
+
* // webSocketClose/Error(conn) => server.drop(conn)
|
|
2348
2457
|
* // server.connections.get(conn) / server.broadcast(() => push.request(…), { except: conn })
|
|
2349
2458
|
* ```
|
|
2350
2459
|
*
|
|
2460
|
+
* On Cloudflare, `serveDurableObject` folds the whole DO transport stack (carriers + storage + keepalive)
|
|
2461
|
+
* into this — reach for it instead of assembling the carriers by hand.
|
|
2462
|
+
*
|
|
2351
2463
|
* `TConn` (the live-connection token a duplex carrier hands back through `send`/`receive`/`drop`) is
|
|
2352
2464
|
* inferred from the carriers — `WebSocket` for `wsAcceptorCarrier`, the data-channel type for a WebRTC
|
|
2353
2465
|
* carrier, and so on — so it stays carrier-agnostic. Passing `connectionState` narrows the return so
|
|
@@ -2360,6 +2472,44 @@ declare function serveChannel<TO_ACCEPTOR extends readonly ActionDomain<any>[],
|
|
|
2360
2472
|
};
|
|
2361
2473
|
declare function serveChannel<TO_ACCEPTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TConn = unknown, TApp = unknown>(runtime: ActionRuntime, channel: ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>, options: IServeChannelOptions<TO_ACCEPTOR, TConn, TApp>): IChannelServer<TConn, TApp>;
|
|
2362
2474
|
//#endregion
|
|
2475
|
+
//#region src/ActionRuntime/Channel/serveHost.d.ts
|
|
2476
|
+
/**
|
|
2477
|
+
* An environment-neutral description of *where* a channel is served — the accept-in dual of a connector's
|
|
2478
|
+
* transport stack, factored out so a platform adapter (a Cloudflare Durable Object, a Bun/Node WebSocket
|
|
2479
|
+
* server, …) supplies only what differs per environment while the channel + case wiring stays identical.
|
|
2480
|
+
* A host bundles:
|
|
2481
|
+
*
|
|
2482
|
+
* - the {@link carriers} the channel is served over (e.g. a WebSocket + an HTTP fallback),
|
|
2483
|
+
* - the {@link storage} backing the server's crypto identity, and
|
|
2484
|
+
* - an {@link onServed} hook run once the server exists (e.g. registering a keepalive auto-response).
|
|
2485
|
+
*
|
|
2486
|
+
* Build one with a platform helper (`cloudflareDurableObjectHost`) and hand it to {@link serveHost}.
|
|
2487
|
+
*/
|
|
2488
|
+
interface IChannelHostAdapter<TConn> {
|
|
2489
|
+
/** The carriers this channel is served over — the accept-in dual of `connectChannel`'s `transports`. */
|
|
2490
|
+
carriers: readonly TAcceptorCarrier<TConn>[];
|
|
2491
|
+
/** Backing store for the server's crypto identity + TOFU pins. Required when any carrier is secure. */
|
|
2492
|
+
storage?: StorageAdapter;
|
|
2493
|
+
/** Run once after the server is built — e.g. register a transport keepalive. */
|
|
2494
|
+
onServed?: (server: IChannelServer<TConn, unknown>) => void;
|
|
2495
|
+
}
|
|
2496
|
+
/** {@link serveChannel}'s options minus what the host adapter supplies (`carriers`, `storage`). */
|
|
2497
|
+
type TServeHostOptions<TO_ACCEPTOR extends readonly ActionDomain<any>[], TConn, TApp = unknown> = Omit<IServeChannelOptions<TO_ACCEPTOR, TConn, TApp>, "carriers" | "storage">;
|
|
2498
|
+
/**
|
|
2499
|
+
* Serve a channel over a {@link IChannelHostAdapter} — the environment-neutral core every platform helper
|
|
2500
|
+
* (e.g. `serveDurableObject`) composes. It folds the host's carriers + storage into `serveChannel`, then
|
|
2501
|
+
* runs the host's `onServed` hook. Everything else (`clientEnv`, `channelCases`, `connectionState`,
|
|
2502
|
+
* `handlers`, …) is the same `serveChannel` surface, so moving a server between environments is swapping
|
|
2503
|
+
* the host adapter and nothing else. Passing `connectionState` narrows the return so `server.connections`
|
|
2504
|
+
* is non-optional, exactly as with `serveChannel`.
|
|
2505
|
+
*/
|
|
2506
|
+
declare function serveHost<TO_ACCEPTOR extends readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[], TConn, TApp>(runtime: ActionRuntime, channel: ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>, host: IChannelHostAdapter<TConn>, options: TServeHostOptions<TO_ACCEPTOR, TConn, TApp> & {
|
|
2507
|
+
connectionState: IServeConnectionStateOptions<TApp>;
|
|
2508
|
+
}): IChannelServer<TConn, TApp> & {
|
|
2509
|
+
connections: ConnectionStateStore<TConn, TApp>;
|
|
2510
|
+
};
|
|
2511
|
+
declare function serveHost<TO_ACCEPTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TConn = unknown, TApp = unknown>(runtime: ActionRuntime, channel: ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>, host: IChannelHostAdapter<TConn>, options: TServeHostOptions<TO_ACCEPTOR, TConn, TApp>): IChannelServer<TConn, TApp>;
|
|
2512
|
+
//#endregion
|
|
2363
2513
|
//#region src/ActionRuntime/Transport/SecureSession/exchangeAcceptor.d.ts
|
|
2364
2514
|
/** Acceptor secure config for the exchange (HTTP) endpoint — same identity an `AcceptorHandler` uses. */
|
|
2365
2515
|
interface IExchangeAcceptorSecurity {
|
|
@@ -2943,47 +3093,6 @@ declare class LinkTransport extends Transport<ETransportShape.duplex> {
|
|
|
2943
3093
|
getRouteInfo(input: ITransportRouteActionParams): ITransportRouteInfo;
|
|
2944
3094
|
}
|
|
2945
3095
|
//#endregion
|
|
2946
|
-
//#region src/ActionRuntime/Transport/plainTransport.d.ts
|
|
2947
|
-
interface IPlainTransportOptions {
|
|
2948
|
-
/**
|
|
2949
|
-
* How to reach the peer with no security layer. A duplex carrier (`wsCarrier(url)`,
|
|
2950
|
-
* `rtcCarrier(dc)`, `inMemoryCarrier().carrier`) builds a push-capable {@link LinkTransport}; an
|
|
2951
|
-
* exchange carrier (`httpCarrier(...)`) builds a request/reply {@link ExchangeTransport}.
|
|
2952
|
-
*/
|
|
2953
|
-
carrier: IDuplexCarrierSource | IExchangeCarrierSource;
|
|
2954
|
-
/**
|
|
2955
|
-
* Codec for a *duplex* carrier (a duplex link frames the action wire itself). Required for duplex;
|
|
2956
|
-
* ignored for an exchange carrier, which JSON-encodes the action wire in its envelope.
|
|
2957
|
-
*/
|
|
2958
|
-
formatMessage?: TLinkFormatMessage;
|
|
2959
|
-
/** Per-channel codec factory for stateful duplex codecs (e.g. the binary session). */
|
|
2960
|
-
createFormatMessage?: () => TLinkFormatMessage;
|
|
2961
|
-
/**
|
|
2962
|
-
* Optional availability gate. When it returns `false`, this transport reports as `unsupported` for that
|
|
2963
|
-
* action and the manager falls through to the next transport in preference order — without opening the
|
|
2964
|
-
* carrier or computing its cache key. Re-evaluated per dispatch, so a transport can become available
|
|
2965
|
-
* later (e.g. once a session/connection precondition holds) with no reconnect. Omit = always available.
|
|
2966
|
-
*/
|
|
2967
|
-
available?: (input: ITransportRouteActionParams) => boolean;
|
|
2968
|
-
updateRunConfig?: TUpdateActionRunConfig;
|
|
2969
|
-
/** Override the devtools chip label (defaults to the carrier's `carrierLabel`). */
|
|
2970
|
-
label?: string;
|
|
2971
|
-
}
|
|
2972
|
-
/**
|
|
2973
|
-
* The plain (no-handshake, no-crypto) sibling of {@link secureTransport}: swap the carrier to change
|
|
2974
|
-
* protocol, with no security layer. Over an {@link IExchangeCarrierSource} it builds an
|
|
2975
|
-
* {@link ExchangeTransport} that POSTs the bare action wire and completes inline (HTTP is just
|
|
2976
|
-
* `carrier: httpCarrier(...)`); over an {@link IDuplexCarrierSource} it builds a push-capable
|
|
2977
|
-
* {@link LinkTransport} with the given codec. HTTP is therefore no longer a bespoke transport class —
|
|
2978
|
-
* it is "just another carrier", exactly like a WebSocket under {@link secureTransport}.
|
|
2979
|
-
*/
|
|
2980
|
-
declare function plainTransport(options: IPlainTransportOptions & {
|
|
2981
|
-
carrier: IExchangeCarrierSource;
|
|
2982
|
-
}): ExchangeTransport;
|
|
2983
|
-
declare function plainTransport(options: IPlainTransportOptions & {
|
|
2984
|
-
carrier: IDuplexCarrierSource;
|
|
2985
|
-
}): LinkTransport;
|
|
2986
|
-
//#endregion
|
|
2987
3096
|
//#region src/ActionRuntime/Transport/SecureSession/exchangeProtocol.d.ts
|
|
2988
3097
|
/**
|
|
2989
3098
|
* The application-level envelope for secure action traffic over an {@link IExchangeCarrier} (HTTP). An
|
|
@@ -3033,45 +3142,6 @@ declare function encodeExchange(envelope: TExchangeRequest | TExchangeReply): st
|
|
|
3033
3142
|
declare function decodeExchangeRequest(raw: string): TExchangeRequest | undefined;
|
|
3034
3143
|
declare function decodeExchangeReply(raw: string): TExchangeReply | undefined;
|
|
3035
3144
|
//#endregion
|
|
3036
|
-
//#region src/ActionRuntime/Transport/secureTransport.d.ts
|
|
3037
|
-
interface ISecureTransportOptions {
|
|
3038
|
-
/** The shared channel identity (per-connection codec + dictionary version) — same one both ends use. */
|
|
3039
|
-
channel: ISecureChannel;
|
|
3040
|
-
/** This client's runtime — its coordinate is the authenticated identity sent in the handshake. */
|
|
3041
|
-
runtime: ActionRuntime;
|
|
3042
|
-
/** Backing store for this client's crypto identity (a stable verify key across reloads). */
|
|
3043
|
-
storageAdapter: StorageAdapter;
|
|
3044
|
-
/** The level this client requests; the peer must allow it. */
|
|
3045
|
-
securityLevel: ESecurityLevel;
|
|
3046
|
-
/**
|
|
3047
|
-
* Optional availability gate. When it returns `false`, this transport reports as `unsupported` for that
|
|
3048
|
-
* action and the manager falls through to the next transport in preference order — without opening the
|
|
3049
|
-
* carrier or computing its cache key. Re-evaluated per dispatch, so a transport can become available
|
|
3050
|
-
* later (e.g. once a session/connection precondition holds) with no reconnect. Omit = always available.
|
|
3051
|
-
*/
|
|
3052
|
-
available?: (input: ITransportRouteActionParams) => boolean;
|
|
3053
|
-
/**
|
|
3054
|
-
* How to reach the peer. A duplex carrier (`wsCarrier(url)`, `rtcCarrier(dc)`,
|
|
3055
|
-
* `inMemoryCarrier().carrier`) runs the push-capable session; an exchange carrier (`httpCarrier(...)`)
|
|
3056
|
-
* runs the request/reply session over the same handshake + crypto.
|
|
3057
|
-
*/
|
|
3058
|
-
carrier: IDuplexCarrierSource | IExchangeCarrierSource;
|
|
3059
|
-
}
|
|
3060
|
-
/**
|
|
3061
|
-
* The one secure-transport factory — swap the carrier to change protocol. Folds in the boilerplate (the
|
|
3062
|
-
* {@link ClientCryptoKeyLink} from `storageAdapter`, the `security` block from the runtime coordinate +
|
|
3063
|
-
* channel version) and drives it over whatever carrier you pass: a {@link IDuplexCarrierSource} builds a
|
|
3064
|
-
* push-capable {@link LinkTransport} (WS is just `carrier: wsCarrier(url)`), an
|
|
3065
|
-
* {@link IExchangeCarrierSource} builds a request/reply {@link ExchangeTransport} (HTTP, with the same
|
|
3066
|
-
* authentication/encryption). Replaces the old `createSecureWebSocketTransport` / `createSecureLinkTransport`.
|
|
3067
|
-
*/
|
|
3068
|
-
declare function secureTransport(options: ISecureTransportOptions & {
|
|
3069
|
-
carrier: IDuplexCarrierSource;
|
|
3070
|
-
}): LinkTransport;
|
|
3071
|
-
declare function secureTransport(options: ISecureTransportOptions & {
|
|
3072
|
-
carrier: IExchangeCarrierSource;
|
|
3073
|
-
}): ExchangeTransport;
|
|
3074
|
-
//#endregion
|
|
3075
3145
|
//#region src/errors/err_nice_action.d.ts
|
|
3076
3146
|
declare enum EErrId_NiceAction {
|
|
3077
3147
|
not_implemented = "not_implemented",
|
|
@@ -3297,5 +3367,5 @@ interface IActionPayload_Result_JsonObject<DOM extends IActionDomain = IActionDo
|
|
|
3297
3367
|
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>;
|
|
3298
3368
|
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>;
|
|
3299
3369
|
//#endregion
|
|
3300
|
-
export {
|
|
3301
|
-
//# sourceMappingURL=ActionPayload.types-
|
|
3370
|
+
export { wsAcceptorCarrier as $, TTransportStatusInfo_GetTransport_Output as $n, TPossibleDomainId as $r, IDuplexCarrier as $t, encodeExchange as A, ITransportDispatchAction as An, ERunningActionUpdateType as Ar, TAcceptorCarrier as At, IActionFrameCrypto as B, IUpdateActionRunConfig_Output as Bn, IRuntimeCoordinateSpecifics as Br, IActionChannel as Bt, decodeActionFrame as C, IActionTransportDef as Cn, RunningAction as Cr, IConnectionContext as Ct, TExchangeRequest as D, IActionTransportReadyData_Methods as Dn, IActionCore_JsonObject as Dr, IAcceptorAttachmentStore as Dt, TExchangeReply as E, IActionTransportReadyData_Base as En, IActionCore as Er, serveChannel as Et, EErrId_NiceTransport as F, ITransportStatusInfo_Base as Fn, TRunningActionUpdate as Fr, ConnectionStateStore as Ft, IHttpCarrierRequest as G, TOnResolveIncomingRequestJson as Gn, IActionDomain as Gr, acceptChannel as Gt, createActionFrameCrypto as H, TOnResolveAnyIncomingActionData as Hn, RuntimeCoordinate as Hr, IConnectTransport as Ht, err_nice_transport as I, ITransportStatusInfo_Failed as In, TRunningActionUpdateFinished as Ir, IConnectionAttachment as It, IHttpAcceptorCarrierOptions as J, TSendActionDataMethod as Jn, TActionDomainChildDef as Jr, defineChannel as Jt, TCarrierFetch as K, TOnResolveIncomingResponse as Kn, IActionDomainChildOptions as Kr, acceptChannelConnections as Kt, ExchangeTransport as L, ITransportStatusInfo_Initializing as Ln, TRunningActionUpdateListener as Lr, IConnectionStateStoreOptions as Lt, LinkTransport as M, ITransportRouteActionParams as Mn, IRunningActionUpdate_Progress as Mr, IDuplexConnectionRouter as Mt, IActionTransportReadyData_Link as N, ITransportRouteClientParams as Nn, IRunningActionUpdate_Started as Nr, IHibernatableWsServerAdapterOptions as Nt, decodeExchangeReply as O, IActionTransportResolvers as On, ERunningActionFinishedType as Or, IDuplexAcceptorCarrier as Ot, TLinkFormatMessage as P, ITransportRouteInfo as Pn, IRunningActionUpdate_Success as Pr, createHibernatableWsServerAdapter as Pt, IWsAcceptorCarrierOptions as Q, TTransportStatusInfo as Qn, TInferOutputFromSchema as Qr, createBinaryWireSessionFactory as Qt, IExchangeTransportOptions as R, ITransportStatusInfo_Ready as Rn, ActionPayload_Result as Rr, createConnectionStateStore as Rt, IActionFrameDecoder as S, ETransportStatus as Sn, MaybePromise as Sr, IChannelServer as St, err_nice_action as T, IActionTransportReady as Tn, ActionPayload_Request as Tr, IServeConnectionStateOptions as Tt, createBinaryWireAdapter as U, TOnResolveAnyIncomingActionData_Json as Un, TRuntimeCoordinateEnvId as Ur, TChannelAcceptorCases as Ut, IActionFrameCryptoConfig as V, TGetTransportFn as Vn, IRuntimeFullCoordinates as Vr, IConnectChannelOptions as Vt, IHttpCarrierOptions as W, TOnResolveIncomingRequest as Wn, TRuntimeCoordinateStringId as Wr, TChannelPushHandlers as Wt, IWsCarrierOptions as X, TTransportCache as Xn, TDomainActionId as Xr, defineSecureChannel as Xt, httpAcceptorCarrier as Y, TSendReturnDataMethod as Yn, TActionDomainSchema as Yr, ISecureChannel as Yt, wsCarrier as Z, TTransportInitializationFinishedInfo as Zn, TInferInputFromSchema as Zr, IBinaryWireSessionOptions as Zt, TActionProgress as _, ActionRootDomain as _n, encodeHandshakeMessage as _r, IExchangeAcceptorConfig as _t, IActionPayload_Data_Base as a, TActionSchemaOptions as ai, AcceptorHandler as an, IClientHandshakeConfig as ar, rtcDataChannelByteChannel as at, isActionPayload_Request_JsonObject as b, createConnectorHandler as bn, ActionLocalHandler as br, TServeHostOptions as bt, IActionPayload_Request_JsonObject as c, TAcceptorCaseFn as cn, IHandshakeEncryptionKeyMaterial as cr, IInMemoryChannelPair as ct, IActionProgress_Custom as d, TActionConnectionEncoding as dn, THandshakeMessage as dr, err_nice_external_client as dt, TPossibleDomainIdList as ei, IDuplexCarrierSource as en, TUpdateActionRunConfig as er, EErrId_NiceTransport_WebSocket as et, IActionProgress_None as f, createAcceptorHandler as fn, createClientHandshake as fr, ISecureAcceptorHandlerOptions as ft, TActionPayload_Any_JsonObject as g, ActionDomain as gn, decodeHandshakeMessage as gr, ExchangeAcceptor as gt, TActionPayload_Any_Instance as h, ActionCore as hn, createStorageTofuVerifyKeyResolver as hr, createActionFetchHandler as ht, IActionPayload_Base_JsonObject as i, actionSchema as ii, TFrame$1 as in, ESecurityLevel as ir, IRtcDataChannelLike as it, ILinkTransportOptions as j, ITransportMethod_SendActionData_Input as jn, IRunningActionUpdate_Abort as jr, isExchangeAcceptorCarrier as jt, decodeExchangeRequest as k, ISecureClientConfig as kn, ERunningActionState as kr, IExchangeAcceptorCarrier as kt, IActionPayload_Result as l, TAcceptorConnectionCaseFn as ln, IHandshakeResult as lr, IInMemoryServerEndpoint as lt, IActionRouteItemHandler as m, createActionRootDomain as mn, createServerHandshake as mr, IActionFetchHandlerOptions as mt, EActionProgressType as n, EActionResponseMode as ni, IExchangeCarrierSource as nn, Transport as nr, IRtcCarrierOptions as nt, IActionPayload_Progress as o, TActionSerializationDefinition as oi, IAcceptorConnectionBinding as on, IClientVerifyKeyResolveInput as or, IInMemoryCarrier as ot, IActionProgress_Percentage as p, IActionWireFormat as pn, createInMemoryTofuVerifyKeyResolver as pr, createSecureAcceptorHandler as pt, httpCarrier as q, TOnResolveIncomingResponseJson as qn, IActionRootDomain as qr, connectChannel as qt, IActionPayload_Base as r, TInferActionError as ri, TCarrier as rn, EHandshakeMessageType as rr, rtcCarrier as rt, IActionPayload_Progress_JsonObject as s, TTransportedValue as si, IAcceptorHandlerOptions as sn, IClientVerifyKeyResolver as sr, inMemoryCarrier as st, EActionPayloadType as t, ActionSchema as ti, IExchangeCarrier as tn, ITransportConnectionContext as tr, err_nice_transport_ws as tt, IActionPayload_Result_JsonObject as u, TActionChannelFormatMessage as un, IServerHandshakeConfig as ur, createInMemoryChannelPair as ut, TActionResultOutcome as v, ActionRuntime as vn, runtimeLinkId as vr, IExchangeAcceptorSecurity as vt, EErrId_NiceAction as w, IActionTransportInitialized as wn, ActionPayload_Progress as wr, IServeChannelOptions as wt, isActionPayload_Any_JsonObject as x, ETransportShape as xn, createLocalHandler as xr, serveHost as xt, isActionPayload_Result_JsonObject as y, ConnectorHandler as yn, PeerLinkHandler as yr, IChannelHostAdapter as yt, IActionTransportReadyData_Exchange as z, ITransportStatusInfo_Unsupported as zn, IRuntimeCoordinate as zr, IAcceptChannelOptions as zt };
|
|
3371
|
+
//# sourceMappingURL=ActionPayload.types-Dx1JPyfs.d.mts.map
|