@nice-code/action 0.19.0 → 0.20.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.
Files changed (30) hide show
  1. package/README.md +699 -666
  2. package/build/{ActionDevtoolsCore-CCZXQBAo.d.cts → ActionDevtoolsCore-D_JvgPmz.d.mts} +2 -2
  3. package/build/{ActionDevtoolsCore-bjYQ8O2_.d.mts → ActionDevtoolsCore-dV-IVPcP.d.cts} +2 -2
  4. package/build/{ActionPayload.types-Bmkzw2df.d.mts → ActionPayload.types-CnfWlkA1.d.cts} +161 -106
  5. package/build/{ActionPayload.types-CdHOGGZK.d.cts → ActionPayload.types-D0DM-g65.d.mts} +161 -106
  6. package/build/devtools/browser/index.d.cts +1 -1
  7. package/build/devtools/browser/index.d.mts +1 -1
  8. package/build/devtools/server/index.d.cts +1 -1
  9. package/build/devtools/server/index.d.mts +1 -1
  10. package/build/index.cjs +147 -138
  11. package/build/index.cjs.map +1 -1
  12. package/build/index.d.cts +2 -2
  13. package/build/index.d.mts +2 -2
  14. package/build/index.mjs +147 -138
  15. package/build/index.mjs.map +1 -1
  16. package/build/platform/cloudflare/index.cjs +8 -4
  17. package/build/platform/cloudflare/index.cjs.map +1 -1
  18. package/build/platform/cloudflare/index.d.cts +8 -3
  19. package/build/platform/cloudflare/index.d.mts +8 -3
  20. package/build/platform/cloudflare/index.mjs +8 -4
  21. package/build/platform/cloudflare/index.mjs.map +1 -1
  22. package/build/react-query/index.d.cts +1 -1
  23. package/build/react-query/index.d.mts +1 -1
  24. package/build/{wsAcceptorCarrier-DHRbsY1X.cjs → wsAcceptorCarrier-BDJRIPfu.cjs} +2 -2
  25. package/build/wsAcceptorCarrier-BDJRIPfu.cjs.map +1 -0
  26. package/build/{wsAcceptorCarrier-CXGlQU_f.mjs → wsAcceptorCarrier-CW2qX25W.mjs} +2 -2
  27. package/build/wsAcceptorCarrier-CW2qX25W.mjs.map +1 -0
  28. package/package.json +4 -4
  29. package/build/wsAcceptorCarrier-CXGlQU_f.mjs.map +0 -1
  30. package/build/wsAcceptorCarrier-DHRbsY1X.cjs.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];
@@ -1878,6 +1878,88 @@ interface IAcceptChannelOptions<TConn> {
1878
1878
  */
1879
1879
  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>;
1880
1880
  //#endregion
1881
+ //#region src/ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/ConnectionStateStore.d.ts
1882
+ /**
1883
+ * The composite value persisted to a connection's attachment: the consumer's own app state plus the
1884
+ * {@link AcceptorHandler} routing binding. Co-storing them in one slot means a transport whose
1885
+ * sockets outlive process eviction (e.g. a Durable Object's hibernatable WebSocket) recovers both the
1886
+ * application identity *and* the action routing from a single attachment after a wake — no storage reads.
1887
+ */
1888
+ interface IConnectionAttachment<TApp> {
1889
+ app?: TApp;
1890
+ binding?: IAcceptorConnectionBinding;
1891
+ }
1892
+ interface IConnectionStateStoreOptions<TConn, TApp> {
1893
+ /** Read a connection's raw attachment (e.g. `(ws) => ws.deserializeAttachment()`). */
1894
+ read: (connection: TConn) => unknown;
1895
+ /** Persist a connection's attachment (e.g. `(ws, value) => ws.serializeAttachment(value)`). */
1896
+ write: (connection: TConn, value: IConnectionAttachment<TApp>) => void;
1897
+ /**
1898
+ * All currently-live connections (e.g. `() => ctx.getWebSockets()`). Used to replay routing bindings
1899
+ * after a wake (via {@link createConnectionStateStore}) and to enumerate app state in
1900
+ * {@link ConnectionStateStore.entries}.
1901
+ */
1902
+ getConnections: () => TConn[];
1903
+ /**
1904
+ * Optional Standard Schema (valibot, zod, …) validating the *app* portion on read. A value that
1905
+ * fails validation reads back as `null` — the same lenient behavior as a hand-written safeParse
1906
+ * helper. The binding is the library's own shape and is never validated.
1907
+ */
1908
+ schema?: StandardSchemaV1<unknown, TApp>;
1909
+ }
1910
+ /**
1911
+ * A typed per-connection state store that co-owns the app state and the acceptor handler's routing
1912
+ * binding in one attachment, so neither the consumer nor the handler has to hand-merge the two. Create
1913
+ * it through {@link createConnectionStateStore} (which also wires binding persistence and replays
1914
+ * surviving connections after a wake), then `get`/`set`/`clearApp` the app state directly.
1915
+ *
1916
+ * The mechanism is carrier-neutral — it only needs read/write/enumerate callbacks for the connection's
1917
+ * attachment — but it pays off on transports whose connections outlive process eviction (e.g. a
1918
+ * Durable Object's hibernatable WebSockets), which is why it lives beside the hibernation adapter.
1919
+ *
1920
+ * ```ts
1921
+ * const players = createConnectionStateStore(serverHandler, {
1922
+ * schema: vs_player,
1923
+ * read: (ws) => ws.deserializeAttachment(),
1924
+ * write: (ws, v) => ws.serializeAttachment(v),
1925
+ * getConnections: () => ctx.getWebSockets(),
1926
+ * });
1927
+ * players.set(ws, player); // binding is preserved automatically
1928
+ * const player = players.get(ws);
1929
+ * ```
1930
+ */
1931
+ declare class ConnectionStateStore<TConn, TApp> {
1932
+ private readonly options;
1933
+ constructor(options: IConnectionStateStoreOptions<TConn, TApp>);
1934
+ /** The validated app state for a connection, or `null` if unset / invalid. */
1935
+ get(connection: TConn): TApp | null;
1936
+ /** Set the app state, preserving the runtime binding already pinned to the connection. */
1937
+ set(connection: TConn, app: TApp): void;
1938
+ /** Clear the app state but keep the binding (e.g. a spectator that stopped watching). */
1939
+ clearApp(connection: TConn): void;
1940
+ /** Every live connection paired with its (validated) app state — for rebuilding in-memory state after a wake. */
1941
+ entries(): [TConn, TApp | null][];
1942
+ /** @internal Persist a freshly-bound connection's binding, preserving any app state already stored. */
1943
+ _persistBinding(connection: TConn, binding: IAcceptorConnectionBinding): void;
1944
+ /** @internal The persisted binding for a connection, if any (used to replay routing after a wake). */
1945
+ _readBinding(connection: TConn): IAcceptorConnectionBinding | undefined;
1946
+ private _readAttachment;
1947
+ private _validateApp;
1948
+ }
1949
+ /**
1950
+ * Build a per-connection {@link ConnectionStateStore} bound to an {@link AcceptorHandler}: it registers
1951
+ * itself as the handler's connection-bound persistence callback (so bindings are written without
1952
+ * overwriting app state) and immediately replays every live connection's stored binding via
1953
+ * {@link AcceptorHandler.rehydrateConnection} — so on a transport that resumes after eviction (e.g. a
1954
+ * Durable Object waking from hibernation) both the app identity and the action routing come back from a
1955
+ * single attachment, with no storage reads and no hand-rolled merge.
1956
+ *
1957
+ * Lives outside the handler so the generic {@link AcceptorHandler} stays free of any attachment/
1958
+ * hibernation concern — it exposes only the neutral `setOnConnectionBound` + `rehydrateConnection`
1959
+ * hooks this builder drives.
1960
+ */
1961
+ declare function createConnectionStateStore<TConn, TApp>(handler: AcceptorHandler<TConn>, options: IConnectionStateStoreOptions<TConn, TApp>): ConnectionStateStore<TConn, TApp>;
1962
+ //#endregion
1881
1963
  //#region src/ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/createHibernatableWsServerAdapter.d.ts
1882
1964
  interface IHibernatableWsServerAdapterOptions<TConn> {
1883
1965
  /** The handler to drive (from `createSecureAcceptorHandler` or `createAcceptorHandler`). */
@@ -2029,17 +2111,21 @@ interface IExchangeCarrierSource {
2029
2111
  * upgrade.
2030
2112
  */
2031
2113
  /**
2032
- * Persistence + replay hooks for a duplex carrier whose connections outlive process eviction (e.g. a
2033
- * Durable Object's hibernatable WebSockets). Optional — omit for a transport that never hibernates. The
2034
- * same surface {@link createHibernatableWsServerAdapter} consumes, minus the handler it's bound to.
2114
+ * Raw read/write access to a connection's persisted attachment, for a duplex carrier whose connections
2115
+ * outlive process eviction (e.g. a Durable Object's hibernatable WebSockets). Optional — omit for a
2116
+ * transport that never hibernates (per-connection state is then in-memory only).
2117
+ *
2118
+ * `serveChannel` owns the attachment *layout*: it co-stores the routing binding and (when
2119
+ * `connectionState` is requested) per-connection app state as one composite in this single slot, so both
2120
+ * survive a wake. The carrier only has to say how to read/write the slot and enumerate live connections.
2035
2121
  */
2036
- interface IAcceptorHibernation<TConn> {
2037
- /** All currently-live connections — replayed on build to rebuild bindings after a wake. */
2122
+ interface IAcceptorAttachmentStore<TConn> {
2123
+ /** All currently-live connections — enumerated on build to replay binding + app state after a wake. */
2038
2124
  getConnections: () => TConn[];
2039
- /** Read a connection's persisted binding (e.g. `(ws) => ws.deserializeAttachment()`). */
2040
- getAttachment: (connection: TConn) => IAcceptorConnectionBinding | undefined;
2041
- /** Persist a connection's binding when it is bound (e.g. `(ws, b) => ws.serializeAttachment(b)`). */
2042
- setAttachment: (connection: TConn, binding: IAcceptorConnectionBinding) => void;
2125
+ /** Read a connection's persisted attachment (e.g. `(ws) => ws.deserializeAttachment()`). */
2126
+ read: (connection: TConn) => unknown;
2127
+ /** Persist a connection's attachment (e.g. `(ws, value) => ws.serializeAttachment(value)`). */
2128
+ write: (connection: TConn, value: unknown) => void;
2043
2129
  }
2044
2130
  /**
2045
2131
  * A duplex carrier is also its own lifecycle handle: once it has been passed to `serveChannel`, feed each
@@ -2086,8 +2172,12 @@ interface IDuplexAcceptorCarrier<TConn = unknown> extends IDuplexCarrierLifecycl
2086
2172
  * Only consulted when {@link upgrade} is present.
2087
2173
  */
2088
2174
  isUpgrade?: (request: Request, url: URL) => boolean;
2089
- /** Optional persistence + replay for connections that survive eviction (Durable Object hibernation). */
2090
- hibernation?: IAcceptorHibernation<TConn>;
2175
+ /**
2176
+ * Optional attachment read/write for connections that survive eviction (Durable Object hibernation).
2177
+ * Present → `serveChannel` persists the routing binding (and any `connectionState`) here and replays it
2178
+ * on wake. Absent → per-connection state is in-memory only.
2179
+ */
2180
+ attachmentStore?: IAcceptorAttachmentStore<TConn>;
2091
2181
  /** Short carrier-kind label for the devtools chip (e.g. `"ws"`, `"webrtc"`). */
2092
2182
  readonly carrierLabel: string;
2093
2183
  }
@@ -2129,7 +2219,15 @@ type TAcceptorCarrier<TConn = unknown> = IDuplexAcceptorCarrier<TConn> | IExchan
2129
2219
  declare function isExchangeAcceptorCarrier<TConn>(carrier: TAcceptorCarrier<TConn>): carrier is IExchangeAcceptorCarrier;
2130
2220
  //#endregion
2131
2221
  //#region src/ActionRuntime/Channel/serveChannel.d.ts
2132
- interface IServeChannelOptions<TConn> {
2222
+ /** Per-connection app-state config for {@link serveChannel}'s `connectionState`. */
2223
+ interface IServeConnectionStateOptions<TApp> {
2224
+ /**
2225
+ * Optional Standard Schema (valibot, zod, …) validating the app state on read — a value that fails
2226
+ * validation reads back as `null`. Omit to store the app state untyped.
2227
+ */
2228
+ schema?: StandardSchemaV1<unknown, TApp>;
2229
+ }
2230
+ interface IServeChannelOptions<TO_ACCEPTOR extends readonly ActionDomain<any>[], TConn, TApp = unknown> {
2133
2231
  /**
2134
2232
  * Coordinate of the *connecting clients* (typically env-only, e.g. `RuntimeCoordinate.env("web_app")`),
2135
2233
  * used to score return-path dispatch back to the right connection.
@@ -2166,12 +2264,25 @@ interface IServeChannelOptions<TConn> {
2166
2264
  verifyKeyResolver?: IClientVerifyKeyResolver;
2167
2265
  /** Timeout (ms) applied to server-initiated actions awaiting a client response. */
2168
2266
  defaultTimeout?: number;
2267
+ /**
2268
+ * Co-store per-connection app state alongside the routing binding in the sole duplex carrier's connection
2269
+ * attachment, so both survive a wake from eviction. Reach the typed store back on `server.connections`.
2270
+ * Requires the carrier to expose an attachment store (the Cloudflare `durableObjectWsCarrier` does) and
2271
+ * exactly one duplex carrier.
2272
+ */
2273
+ connectionState?: IServeConnectionStateOptions<TApp>;
2274
+ /**
2275
+ * Connection-aware action cases for the channel's acceptor (`toAcceptor`) domains — each case receives the
2276
+ * primed request *and* the originating connection (the connection-aware dual of `handlers`). Registered on
2277
+ * the runtime for you. Requires exactly one duplex carrier.
2278
+ */
2279
+ channelCases?: TChannelAcceptorCases<TO_ACCEPTOR, TConn>;
2169
2280
  }
2170
2281
  /**
2171
2282
  * One server serving a secure channel over several carriers — the accept-in dual of `connectChannel`,
2172
2283
  * returned by {@link serveChannel}. Wire its surface straight to the host's request/socket events.
2173
2284
  */
2174
- interface IChannelServer<TConn> {
2285
+ interface IChannelServer<TConn, TApp = unknown> {
2175
2286
  /**
2176
2287
  * The duplex acceptor handlers — one per duplex carrier, in carrier order (empty if none). For pushing,
2177
2288
  * prefer {@link pushToClient} (it resolves the owning handler); reach for these for cross-carrier work
@@ -2197,6 +2308,23 @@ interface IChannelServer<TConn> {
2197
2308
  pushToClient: <DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string>(target: TConn | RuntimeCoordinate, request: ActionPayload_Request<DOM, ID>, options?: {
2198
2309
  timeout?: number;
2199
2310
  }) => RunningAction<DOM, ID>;
2311
+ /**
2312
+ * Fan a server-initiated action out to every connection on the sole duplex carrier (skip the origin with
2313
+ * `except`, filter with `where`). The push-to-many counterpart of {@link pushToClient}. Throws if there
2314
+ * isn't exactly one duplex carrier (with several, broadcast over a specific `handlers[i]`).
2315
+ */
2316
+ broadcast: <DOM extends IActionDomain, ID extends keyof DOM["actionSchema"] & string>(makeRequest: () => ActionPayload_Request<DOM, ID>, options?: {
2317
+ except?: TConn | null;
2318
+ where?: (connection: TConn) => boolean;
2319
+ timeout?: number;
2320
+ onError?: (error: unknown, connection: TConn) => void;
2321
+ }) => void;
2322
+ /**
2323
+ * The per-connection app-state store co-stored with the routing binding in the connection attachment —
2324
+ * present only when `connectionState` was passed. `get`/`set`/`clearApp`/`entries` it directly; it
2325
+ * survives hibernation alongside the binding.
2326
+ */
2327
+ connections?: ConnectionStateStore<TConn, TApp>;
2200
2328
  }
2201
2329
  /**
2202
2330
  * Serve a secure channel over one or more carriers from a single call — the accept-in dual of
@@ -2204,24 +2332,33 @@ interface IChannelServer<TConn> {
2204
2332
  * resolver) and the security block (coordinate, dictionary version, accepted levels) *once* from
2205
2333
  * `(runtime, channel)` and fans them across every carrier, so the WebSocket and the secure-HTTP endpoint
2206
2334
  * can never drift apart. It registers your handlers (plus the duplex acceptor it builds) on the runtime,
2207
- * wires hibernation when the duplex carrier declares it, and returns a single {@link IChannelServer} whose
2208
- * `fetch` / `duplex` / `pushToClient` you forward straight to the host:
2335
+ * wires hibernation when the duplex carrier exposes an attachment store, and returns a single
2336
+ * {@link IChannelServer} whose `fetch` / `duplex` / `pushToClient` / `broadcast` you forward straight to
2337
+ * the host:
2209
2338
  * ```ts
2210
2339
  * const server = serveChannel(runtime, channel, {
2211
2340
  * clientEnv, storage,
2212
- * carriers: [wsAcceptorCarrier({ send, upgrade, hibernation }), httpAcceptorCarrier()],
2213
- * handlers: [localHandler],
2341
+ * carriers: [wsAcceptorCarrier({ send, upgrade, attachmentStore }), httpAcceptorCarrier()],
2342
+ * connectionState: { schema: vs_player }, // optional: co-store per-connection app state (survives hibernation)
2343
+ * channelCases: { join: (action, conn) => { … } }, // optional: connection-aware action cases
2214
2344
  * });
2215
2345
  * // fetch(req) => server.fetch(req)
2216
2346
  * // webSocketMessage(conn, m) => server.duplex?.receive(conn, m)
2217
2347
  * // webSocketClose/Error(conn) => server.duplex?.drop(conn)
2348
+ * // server.connections.get(conn) / server.broadcast(() => push.request(…), { except: conn })
2218
2349
  * ```
2219
2350
  *
2220
2351
  * `TConn` (the live-connection token a duplex carrier hands back through `send`/`receive`/`drop`) is
2221
2352
  * inferred from the carriers — `WebSocket` for `wsAcceptorCarrier`, the data-channel type for a WebRTC
2222
- * carrier, and so on — so it stays carrier-agnostic.
2353
+ * carrier, and so on — so it stays carrier-agnostic. Passing `connectionState` narrows the return so
2354
+ * `server.connections` is non-optional.
2223
2355
  */
2224
- 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>;
2356
+ declare function serveChannel<TO_ACCEPTOR extends readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[], TConn, TApp>(runtime: ActionRuntime, channel: ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>, options: IServeChannelOptions<TO_ACCEPTOR, TConn, TApp> & {
2357
+ connectionState: IServeConnectionStateOptions<TApp>;
2358
+ }): IChannelServer<TConn, TApp> & {
2359
+ connections: ConnectionStateStore<TConn, TApp>;
2360
+ };
2361
+ 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>;
2225
2362
  //#endregion
2226
2363
  //#region src/ActionRuntime/Transport/SecureSession/exchangeAcceptor.d.ts
2227
2364
  /** Acceptor secure config for the exchange (HTTP) endpoint — same identity an `AcceptorHandler` uses. */
@@ -2368,88 +2505,6 @@ interface ISecureAcceptorHandlerOptions<TConn> {
2368
2505
  */
2369
2506
  declare function createSecureAcceptorHandler<TConn = unknown>(options: ISecureAcceptorHandlerOptions<TConn>): AcceptorHandler<TConn>;
2370
2507
  //#endregion
2371
- //#region src/ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/ConnectionStateStore.d.ts
2372
- /**
2373
- * The composite value persisted to a connection's attachment: the consumer's own app state plus the
2374
- * {@link AcceptorHandler} routing binding. Co-storing them in one slot means a transport whose
2375
- * sockets outlive process eviction (e.g. a Durable Object's hibernatable WebSocket) recovers both the
2376
- * application identity *and* the action routing from a single attachment after a wake — no storage reads.
2377
- */
2378
- interface IConnectionAttachment<TApp> {
2379
- app?: TApp;
2380
- binding?: IAcceptorConnectionBinding;
2381
- }
2382
- interface IConnectionStateStoreOptions<TConn, TApp> {
2383
- /** Read a connection's raw attachment (e.g. `(ws) => ws.deserializeAttachment()`). */
2384
- read: (connection: TConn) => unknown;
2385
- /** Persist a connection's attachment (e.g. `(ws, value) => ws.serializeAttachment(value)`). */
2386
- write: (connection: TConn, value: IConnectionAttachment<TApp>) => void;
2387
- /**
2388
- * All currently-live connections (e.g. `() => ctx.getWebSockets()`). Used to replay routing bindings
2389
- * after a wake (via {@link createConnectionStateStore}) and to enumerate app state in
2390
- * {@link ConnectionStateStore.entries}.
2391
- */
2392
- getConnections: () => TConn[];
2393
- /**
2394
- * Optional Standard Schema (valibot, zod, …) validating the *app* portion on read. A value that
2395
- * fails validation reads back as `null` — the same lenient behavior as a hand-written safeParse
2396
- * helper. The binding is the library's own shape and is never validated.
2397
- */
2398
- schema?: StandardSchemaV1<unknown, TApp>;
2399
- }
2400
- /**
2401
- * A typed per-connection state store that co-owns the app state and the acceptor handler's routing
2402
- * binding in one attachment, so neither the consumer nor the handler has to hand-merge the two. Create
2403
- * it through {@link createConnectionStateStore} (which also wires binding persistence and replays
2404
- * surviving connections after a wake), then `get`/`set`/`clearApp` the app state directly.
2405
- *
2406
- * The mechanism is carrier-neutral — it only needs read/write/enumerate callbacks for the connection's
2407
- * attachment — but it pays off on transports whose connections outlive process eviction (e.g. a
2408
- * Durable Object's hibernatable WebSockets), which is why it lives beside the hibernation adapter.
2409
- *
2410
- * ```ts
2411
- * const players = createConnectionStateStore(serverHandler, {
2412
- * schema: vs_player,
2413
- * read: (ws) => ws.deserializeAttachment(),
2414
- * write: (ws, v) => ws.serializeAttachment(v),
2415
- * getConnections: () => ctx.getWebSockets(),
2416
- * });
2417
- * players.set(ws, player); // binding is preserved automatically
2418
- * const player = players.get(ws);
2419
- * ```
2420
- */
2421
- declare class ConnectionStateStore<TConn, TApp> {
2422
- private readonly options;
2423
- constructor(options: IConnectionStateStoreOptions<TConn, TApp>);
2424
- /** The validated app state for a connection, or `null` if unset / invalid. */
2425
- get(connection: TConn): TApp | null;
2426
- /** Set the app state, preserving the runtime binding already pinned to the connection. */
2427
- set(connection: TConn, app: TApp): void;
2428
- /** Clear the app state but keep the binding (e.g. a spectator that stopped watching). */
2429
- clearApp(connection: TConn): void;
2430
- /** Every live connection paired with its (validated) app state — for rebuilding in-memory state after a wake. */
2431
- entries(): [TConn, TApp | null][];
2432
- /** @internal Persist a freshly-bound connection's binding, preserving any app state already stored. */
2433
- _persistBinding(connection: TConn, binding: IAcceptorConnectionBinding): void;
2434
- /** @internal The persisted binding for a connection, if any (used to replay routing after a wake). */
2435
- _readBinding(connection: TConn): IAcceptorConnectionBinding | undefined;
2436
- private _readAttachment;
2437
- private _validateApp;
2438
- }
2439
- /**
2440
- * Build a per-connection {@link ConnectionStateStore} bound to an {@link AcceptorHandler}: it registers
2441
- * itself as the handler's connection-bound persistence callback (so bindings are written without
2442
- * overwriting app state) and immediately replays every live connection's stored binding via
2443
- * {@link AcceptorHandler.rehydrateConnection} — so on a transport that resumes after eviction (e.g. a
2444
- * Durable Object waking from hibernation) both the app identity and the action routing come back from a
2445
- * single attachment, with no storage reads and no hand-rolled merge.
2446
- *
2447
- * Lives outside the handler so the generic {@link AcceptorHandler} stays free of any attachment/
2448
- * hibernation concern — it exposes only the neutral `setOnConnectionBound` + `rehydrateConnection`
2449
- * hooks this builder drives.
2450
- */
2451
- declare function createConnectionStateStore<TConn, TApp>(handler: AcceptorHandler<TConn>, options: IConnectionStateStoreOptions<TConn, TApp>): ConnectionStateStore<TConn, TApp>;
2452
- //#endregion
2453
2508
  //#region src/ActionRuntime/Handler/PeerLink/Connector/err_nice_external_client.d.ts
2454
2509
  declare const err_nice_external_client: import("@nice-code/error").NiceErrorDomain<{
2455
2510
  domain: string;
@@ -2575,8 +2630,8 @@ interface IWsAcceptorCarrierOptions<TConn> {
2575
2630
  upgrade?: (request: Request, url: URL) => Response | Promise<Response>;
2576
2631
  /** Whether an inbound request is a WS upgrade. Defaults to an `Upgrade: websocket` header. */
2577
2632
  isUpgrade?: (request: Request, url: URL) => boolean;
2578
- /** Persistence + replay hooks for hibernatable sockets (e.g. a Durable Object). */
2579
- hibernation?: IAcceptorHibernation<TConn>;
2633
+ /** Attachment read/write for hibernatable sockets (e.g. a Durable Object); `serveChannel` persists here. */
2634
+ attachmentStore?: IAcceptorAttachmentStore<TConn>;
2580
2635
  /** Override the devtools carrier-kind label (defaults to `"ws"`). */
2581
2636
  carrierLabel?: string;
2582
2637
  }
@@ -3242,5 +3297,5 @@ interface IActionPayload_Result_JsonObject<DOM extends IActionDomain = IActionDo
3242
3297
  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>;
3243
3298
  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>;
3244
3299
  //#endregion
3245
- export { httpAcceptorCarrier as $, Transport as $n, EActionResponseMode as $r, ISecureChannel as $t, decodeExchangeReply as A, ITransportRouteClientParams as An, IRunningActionUpdate_Started as Ar, IAcceptorHibernation as At, err_nice_transport as B, TOnResolveAnyIncomingActionData_Json as Bn, TRuntimeCoordinateEnvId as Br, TFrame$1 as Bt, decodeActionFrame as C, IActionTransportReadyData_Base as Cn, IActionCore as Cr, createActionFetchHandler as Ct, secureTransport as D, ITransportDispatchAction as Dn, ERunningActionUpdateType as Dr, IChannelServer as Dt, ISecureTransportOptions as E, ISecureClientConfig as En, ERunningActionState as Er, IExchangeAcceptorSecurity as Et, ILinkTransportOptions as F, ITransportStatusInfo_Ready as Fn, ActionPayload_Result as Fr, IDuplexCarrier as Ft, IActionFrameCryptoConfig as G, TSendActionDataMethod as Gn, TActionDomainChildDef as Gr, IActionChannel as Gt, IExchangeTransportOptions as H, TOnResolveIncomingRequestJson as Hn, IActionDomain as Hr, IHibernatableWsServerAdapterOptions as Ht, LinkTransport as I, ITransportStatusInfo_Unsupported as In, IRuntimeCoordinate as Ir, IDuplexCarrierSource as It, IHttpCarrierOptions as J, TTransportInitializationFinishedInfo as Jn, TInferInputFromSchema as Jr, TChannelPushHandlers as Jt, createActionFrameCrypto as K, TSendReturnDataMethod as Kn, TActionDomainSchema as Kr, IConnectChannelOptions as Kt, IActionTransportReadyData_Link as L, IUpdateActionRunConfig_Output as Ln, IRuntimeCoordinateSpecifics as Lr, IExchangeCarrier as Lt, encodeExchange as M, ITransportStatusInfo_Base as Mn, TRunningActionUpdate as Mr, IExchangeAcceptorCarrier as Mt, IPlainTransportOptions as N, ITransportStatusInfo_Failed as Nn, TRunningActionUpdateFinished as Nr, TAcceptorCarrier as Nt, TExchangeReply as O, ITransportMethod_SendActionData_Input as On, IRunningActionUpdate_Abort as Or, IServeChannelOptions as Ot, plainTransport as P, ITransportStatusInfo_Initializing as Pn, TRunningActionUpdateListener as Pr, isExchangeAcceptorCarrier as Pt, IHttpAcceptorCarrierOptions as Q, ITransportConnectionContext as Qn, ActionSchema as Qr, defineChannel as Qt, TLinkFormatMessage as R, TGetTransportFn as Rn, IRuntimeFullCoordinates as Rr, IExchangeCarrierSource as Rt, IActionFrameDecoder as S, IActionTransportReady as Sn, ActionPayload_Request as Sr, IActionFetchHandlerOptions as St, err_nice_action as T, IActionTransportResolvers as Tn, ERunningActionFinishedType as Tr, IExchangeAcceptorConfig as Tt, IActionTransportReadyData_Exchange as U, TOnResolveIncomingResponse as Un, IActionDomainChildOptions as Ur, createHibernatableWsServerAdapter as Ut, ExchangeTransport as V, TOnResolveIncomingRequest as Vn, TRuntimeCoordinateStringId as Vr, IDuplexConnectionRouter as Vt, IActionFrameCrypto as W, TOnResolveIncomingResponseJson as Wn, IActionRootDomain as Wr, IAcceptChannelOptions as Wt, TCarrierFetch as X, TTransportStatusInfo_GetTransport_Output as Xn, TPossibleDomainId as Xr, acceptChannelConnections as Xt, IHttpCarrierRequest as Y, TTransportStatusInfo as Yn, TInferOutputFromSchema as Yr, acceptChannel as Yt, httpCarrier as Z, TUpdateActionRunConfig as Zn, TPossibleDomainIdList as Zr, connectChannel as Zt, TActionProgress as _, createConnectorHandler as _n, ActionLocalHandler as _r, IConnectionAttachment as _t, IActionPayload_Data_Base as a, IAcceptorHandlerOptions as an, IHandshakeEncryptionKeyMaterial as ar, err_nice_transport_ws as at, isActionPayload_Request_JsonObject as b, IActionTransportDef as bn, RunningAction as br, ISecureAcceptorHandlerOptions as bt, IActionPayload_Request_JsonObject as c, TActionConnectionEncoding as cn, THandshakeMessage as cr, IRtcDataChannelLike as ct, IActionProgress_Custom as d, createActionRootDomain as dn, createServerHandshake as dr, inMemoryCarrier as dt, TInferActionError as ei, defineSecureChannel as en, EHandshakeMessageType as er, IWsCarrierOptions as et, IActionProgress_None as f, ActionCore as fn, createStorageTofuVerifyKeyResolver as fr, IInMemoryChannelPair as ft, TActionPayload_Any_JsonObject as g, ConnectorHandler as gn, PeerLinkHandler as gr, ConnectionStateStore as gt, TActionPayload_Any_Instance as h, ActionRuntime as hn, runtimeLinkId as hr, err_nice_external_client as ht, IActionPayload_Base_JsonObject as i, TTransportedValue as ii, IAcceptorConnectionBinding as in, IClientVerifyKeyResolver as ir, EErrId_NiceTransport_WebSocket as it, decodeExchangeRequest as j, ITransportRouteInfo as jn, IRunningActionUpdate_Success as jr, IDuplexAcceptorCarrier as jt, TExchangeRequest as k, ITransportRouteActionParams as kn, IRunningActionUpdate_Progress as kr, serveChannel as kt, IActionPayload_Result as l, createAcceptorHandler as ln, createClientHandshake as lr, rtcDataChannelByteChannel as lt, IActionRouteItemHandler as m, ActionRootDomain as mn, encodeHandshakeMessage as mr, createInMemoryChannelPair as mt, EActionProgressType as n, TActionSchemaOptions as ni, createBinaryWireSessionFactory as nn, IClientHandshakeConfig as nr, IWsAcceptorCarrierOptions as nt, IActionPayload_Progress as o, TAcceptorConnectionCaseFn as on, IHandshakeResult as or, IRtcCarrierOptions as ot, IActionProgress_Percentage as p, ActionDomain as pn, decodeHandshakeMessage as pr, IInMemoryServerEndpoint as pt, createBinaryWireAdapter as q, TTransportCache as qn, TDomainActionId as qr, TChannelAcceptorCases as qt, IActionPayload_Base as r, TActionSerializationDefinition as ri, AcceptorHandler as rn, IClientVerifyKeyResolveInput as rr, wsAcceptorCarrier as rt, IActionPayload_Progress_JsonObject as s, TActionChannelFormatMessage as sn, IServerHandshakeConfig as sr, rtcCarrier as st, EActionPayloadType as t, actionSchema as ti, IBinaryWireSessionOptions as tn, ESecurityLevel as tr, wsCarrier as tt, IActionPayload_Result_JsonObject as u, IActionWireFormat as un, createInMemoryTofuVerifyKeyResolver as ur, IInMemoryCarrier as ut, TActionResultOutcome as v, ETransportShape as vn, createLocalHandler as vr, IConnectionStateStoreOptions as vt, EErrId_NiceAction as w, IActionTransportReadyData_Methods as wn, IActionCore_JsonObject as wr, ExchangeAcceptor as wt, isActionPayload_Any_JsonObject as x, IActionTransportInitialized as xn, ActionPayload_Progress as xr, createSecureAcceptorHandler as xt, isActionPayload_Result_JsonObject as y, ETransportStatus as yn, MaybePromise as yr, createConnectionStateStore as yt, EErrId_NiceTransport as z, TOnResolveAnyIncomingActionData as zn, RuntimeCoordinate as zr, TCarrier as zt };
3246
- //# sourceMappingURL=ActionPayload.types-CdHOGGZK.d.cts.map
3300
+ export { httpAcceptorCarrier as $, ITransportConnectionContext as $n, ActionSchema as $r, defineChannel as $t, decodeExchangeReply as A, ITransportRouteActionParams as An, IRunningActionUpdate_Progress as Ar, TAcceptorCarrier as At, err_nice_transport as B, TOnResolveAnyIncomingActionData as Bn, RuntimeCoordinate as Br, createHibernatableWsServerAdapter as Bt, decodeActionFrame as C, IActionTransportReady as Cn, ActionPayload_Request as Cr, IChannelServer as Ct, secureTransport as D, ISecureClientConfig as Dn, ERunningActionState as Dr, IAcceptorAttachmentStore as Dt, ISecureTransportOptions as E, IActionTransportResolvers as En, ERunningActionFinishedType as Er, serveChannel as Et, ILinkTransportOptions as F, ITransportStatusInfo_Initializing as Fn, TRunningActionUpdateListener as Fr, IExchangeCarrierSource as Ft, IActionFrameCryptoConfig as G, TOnResolveIncomingResponseJson as Gn, IActionRootDomain as Gr, IAcceptChannelOptions as Gt, IExchangeTransportOptions as H, TOnResolveIncomingRequest as Hn, TRuntimeCoordinateStringId as Hr, IConnectionAttachment as Ht, LinkTransport as I, ITransportStatusInfo_Ready as In, ActionPayload_Result as Ir, TCarrier as It, IHttpCarrierOptions as J, TTransportCache as Jn, TDomainActionId as Jr, TChannelAcceptorCases as Jt, createActionFrameCrypto as K, TSendActionDataMethod as Kn, TActionDomainChildDef as Kr, IActionChannel as Kt, IActionTransportReadyData_Link as L, ITransportStatusInfo_Unsupported as Ln, IRuntimeCoordinate as Lr, TFrame$1 as Lt, encodeExchange as M, ITransportRouteInfo as Mn, IRunningActionUpdate_Success as Mr, IDuplexCarrier as Mt, IPlainTransportOptions as N, ITransportStatusInfo_Base as Nn, TRunningActionUpdate as Nr, IDuplexCarrierSource as Nt, TExchangeReply as O, ITransportDispatchAction as On, ERunningActionUpdateType as Or, IDuplexAcceptorCarrier as Ot, plainTransport as P, ITransportStatusInfo_Failed as Pn, TRunningActionUpdateFinished as Pr, IExchangeCarrier as Pt, IHttpAcceptorCarrierOptions as Q, TUpdateActionRunConfig as Qn, TPossibleDomainIdList as Qr, connectChannel as Qt, TLinkFormatMessage as R, IUpdateActionRunConfig_Output as Rn, IRuntimeCoordinateSpecifics as Rr, IDuplexConnectionRouter as Rt, IActionFrameDecoder as S, IActionTransportInitialized as Sn, ActionPayload_Progress as Sr, IExchangeAcceptorSecurity as St, err_nice_action as T, IActionTransportReadyData_Methods as Tn, IActionCore_JsonObject as Tr, IServeConnectionStateOptions as Tt, IActionTransportReadyData_Exchange as U, TOnResolveIncomingRequestJson as Un, IActionDomain as Ur, IConnectionStateStoreOptions as Ut, ExchangeTransport as V, TOnResolveAnyIncomingActionData_Json as Vn, TRuntimeCoordinateEnvId as Vr, ConnectionStateStore as Vt, IActionFrameCrypto as W, TOnResolveIncomingResponse as Wn, IActionDomainChildOptions as Wr, createConnectionStateStore as Wt, TCarrierFetch as X, TTransportStatusInfo as Xn, TInferOutputFromSchema as Xr, acceptChannel as Xt, IHttpCarrierRequest as Y, TTransportInitializationFinishedInfo as Yn, TInferInputFromSchema as Yr, TChannelPushHandlers as Yt, httpCarrier as Z, TTransportStatusInfo_GetTransport_Output as Zn, TPossibleDomainId as Zr, acceptChannelConnections as Zt, TActionProgress as _, ConnectorHandler as _n, PeerLinkHandler as _r, createSecureAcceptorHandler as _t, IActionPayload_Data_Base as a, TTransportedValue as ai, IAcceptorConnectionBinding as an, IClientVerifyKeyResolver as ar, err_nice_transport_ws as at, isActionPayload_Request_JsonObject as b, ETransportStatus as bn, MaybePromise as br, ExchangeAcceptor as bt, IActionPayload_Request_JsonObject as c, TActionChannelFormatMessage as cn, IServerHandshakeConfig as cr, IRtcDataChannelLike as ct, IActionProgress_Custom as d, IActionWireFormat as dn, createInMemoryTofuVerifyKeyResolver as dr, inMemoryCarrier as dt, EActionResponseMode as ei, ISecureChannel as en, Transport as er, IWsCarrierOptions as et, IActionProgress_None as f, createActionRootDomain as fn, createServerHandshake as fr, IInMemoryChannelPair as ft, TActionPayload_Any_JsonObject as g, ActionRuntime as gn, runtimeLinkId as gr, ISecureAcceptorHandlerOptions as gt, TActionPayload_Any_Instance as h, ActionRootDomain as hn, encodeHandshakeMessage as hr, err_nice_external_client as ht, IActionPayload_Base_JsonObject as i, TActionSerializationDefinition as ii, AcceptorHandler as in, IClientVerifyKeyResolveInput as ir, EErrId_NiceTransport_WebSocket as it, decodeExchangeRequest as j, ITransportRouteClientParams as jn, IRunningActionUpdate_Started as jr, isExchangeAcceptorCarrier as jt, TExchangeRequest as k, ITransportMethod_SendActionData_Input as kn, IRunningActionUpdate_Abort as kr, IExchangeAcceptorCarrier as kt, IActionPayload_Result as l, TActionConnectionEncoding as ln, THandshakeMessage as lr, rtcDataChannelByteChannel as lt, IActionRouteItemHandler as m, ActionDomain as mn, decodeHandshakeMessage as mr, createInMemoryChannelPair as mt, EActionProgressType as n, actionSchema as ni, IBinaryWireSessionOptions as nn, ESecurityLevel as nr, IWsAcceptorCarrierOptions as nt, IActionPayload_Progress as o, IAcceptorHandlerOptions as on, IHandshakeEncryptionKeyMaterial as or, IRtcCarrierOptions as ot, IActionProgress_Percentage as p, ActionCore as pn, createStorageTofuVerifyKeyResolver as pr, IInMemoryServerEndpoint as pt, createBinaryWireAdapter as q, TSendReturnDataMethod as qn, TActionDomainSchema as qr, IConnectChannelOptions as qt, IActionPayload_Base as r, TActionSchemaOptions as ri, createBinaryWireSessionFactory as rn, IClientHandshakeConfig as rr, wsAcceptorCarrier as rt, IActionPayload_Progress_JsonObject as s, TAcceptorConnectionCaseFn as sn, IHandshakeResult as sr, rtcCarrier as st, EActionPayloadType as t, TInferActionError as ti, defineSecureChannel as tn, EHandshakeMessageType as tr, wsCarrier as tt, IActionPayload_Result_JsonObject as u, createAcceptorHandler as un, createClientHandshake as ur, IInMemoryCarrier as ut, TActionResultOutcome as v, createConnectorHandler as vn, ActionLocalHandler as vr, IActionFetchHandlerOptions as vt, EErrId_NiceAction as w, IActionTransportReadyData_Base as wn, IActionCore as wr, IServeChannelOptions as wt, isActionPayload_Any_JsonObject as x, IActionTransportDef as xn, RunningAction as xr, IExchangeAcceptorConfig as xt, isActionPayload_Result_JsonObject as y, ETransportShape as yn, createLocalHandler as yr, createActionFetchHandler as yt, EErrId_NiceTransport as z, TGetTransportFn as zn, IRuntimeFullCoordinates as zr, IHibernatableWsServerAdapterOptions as zt };
3301
+ //# sourceMappingURL=ActionPayload.types-D0DM-g65.d.mts.map
@@ -1,4 +1,4 @@
1
- import { a as TDevtoolsActionStatus, i as IDevtoolsObservableDomain, n as IActionDevtoolsCoreOptions, o as TDevtoolsListener, r as IDevtoolsActionEntry, s as TDevtoolsPosition, t as ActionDevtoolsCore } from "../../ActionDevtoolsCore-CCZXQBAo.cjs";
1
+ import { a as TDevtoolsActionStatus, i as IDevtoolsObservableDomain, n as IActionDevtoolsCoreOptions, o as TDevtoolsListener, r as IDevtoolsActionEntry, s as TDevtoolsPosition, t as ActionDevtoolsCore } from "../../ActionDevtoolsCore-dV-IVPcP.cjs";
2
2
 
3
3
  //#region src/devtools/browser/NiceActionDevtools.d.ts
4
4
  interface INiceActionDevtoolsProps {
@@ -1,4 +1,4 @@
1
- import { a as TDevtoolsActionStatus, i as IDevtoolsObservableDomain, n as IActionDevtoolsCoreOptions, o as TDevtoolsListener, r as IDevtoolsActionEntry, s as TDevtoolsPosition, t as ActionDevtoolsCore } from "../../ActionDevtoolsCore-bjYQ8O2_.mjs";
1
+ import { a as TDevtoolsActionStatus, i as IDevtoolsObservableDomain, n as IActionDevtoolsCoreOptions, o as TDevtoolsListener, r as IDevtoolsActionEntry, s as TDevtoolsPosition, t as ActionDevtoolsCore } from "../../ActionDevtoolsCore-D_JvgPmz.mjs";
2
2
 
3
3
  //#region src/devtools/browser/NiceActionDevtools.d.ts
4
4
  interface INiceActionDevtoolsProps {
@@ -1,4 +1,4 @@
1
- import { a as TDevtoolsActionStatus, i as IDevtoolsObservableDomain, n as IActionDevtoolsCoreOptions, o as TDevtoolsListener, r as IDevtoolsActionEntry, t as ActionDevtoolsCore } from "../../ActionDevtoolsCore-CCZXQBAo.cjs";
1
+ import { a as TDevtoolsActionStatus, i as IDevtoolsObservableDomain, n as IActionDevtoolsCoreOptions, o as TDevtoolsListener, r as IDevtoolsActionEntry, t as ActionDevtoolsCore } from "../../ActionDevtoolsCore-dV-IVPcP.cjs";
2
2
 
3
3
  //#region src/devtools/server/NiceActionServerDevtools.d.ts
4
4
  type TServerDevtoolsLogFn = (message: string, data?: Record<string, unknown>) => void;
@@ -1,4 +1,4 @@
1
- import { a as TDevtoolsActionStatus, i as IDevtoolsObservableDomain, n as IActionDevtoolsCoreOptions, o as TDevtoolsListener, r as IDevtoolsActionEntry, t as ActionDevtoolsCore } from "../../ActionDevtoolsCore-bjYQ8O2_.mjs";
1
+ import { a as TDevtoolsActionStatus, i as IDevtoolsObservableDomain, n as IActionDevtoolsCoreOptions, o as TDevtoolsListener, r as IDevtoolsActionEntry, t as ActionDevtoolsCore } from "../../ActionDevtoolsCore-D_JvgPmz.mjs";
2
2
 
3
3
  //#region src/devtools/server/NiceActionServerDevtools.d.ts
4
4
  type TServerDevtoolsLogFn = (message: string, data?: Record<string, unknown>) => void;