@nice-code/action 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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-B3JwSaRH.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-Dd1qJAwK.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-C4TDUY7-.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-C5XrQI1K.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-B3JwSaRH.cjs";
1
+ import { a as TDevtoolsActionStatus, i as IDevtoolsObservableDomain, n as IActionDevtoolsCoreOptions, o as TDevtoolsListener, r as IDevtoolsActionEntry, t as ActionDevtoolsCore } from "../../ActionDevtoolsCore-Dd1qJAwK.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-C4TDUY7-.mjs";
1
+ import { a as TDevtoolsActionStatus, i as IDevtoolsObservableDomain, n as IActionDevtoolsCoreOptions, o as TDevtoolsListener, r as IDevtoolsActionEntry, t as ActionDevtoolsCore } from "../../ActionDevtoolsCore-C5XrQI1K.mjs";
2
2
 
3
3
  //#region src/devtools/server/NiceActionServerDevtools.d.ts
4
4
  type TServerDevtoolsLogFn = (message: string, data?: Record<string, unknown>) => void;
package/build/index.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("./rolldown-runtime-emK7D4bc.cjs");
3
3
  const require_RunningAction_types = require("./RunningAction.types-DjCX1xp5.cjs");
4
+ const require_wsAcceptorCarrier = require("./wsAcceptorCarrier-DHRbsY1X.cjs");
4
5
  let nanoid = require("nanoid");
5
6
  let _nice_code_error = require("@nice-code/error");
6
7
  let _nice_code_common_errors = require("@nice-code/common-errors");
@@ -854,32 +855,6 @@ const err_nice_transport = err_nice_external_client.createChildDomain({
854
855
  }
855
856
  });
856
857
  //#endregion
857
- //#region src/ActionRuntime/Transport/Transport.types.ts
858
- /**
859
- * Carrier-shape class identity: the one carrier-invariant trait the selection layer reasons about —
860
- * whether a carrier can push unsolicited frames (`duplex`: WS/WebRTC/BLE/in-memory) or only answers a
861
- * request with a single correlated reply (`exchange`: HTTP). The concrete carrier kind ("ws", "webrtc",
862
- * "http", …) is a free-form {@link ITransportRouteInfo.carrierLabel} for display, not a class tag.
863
- */
864
- let ETransportShape = /* @__PURE__ */ function(ETransportShape) {
865
- ETransportShape["duplex"] = "duplex";
866
- ETransportShape["exchange"] = "exchange";
867
- return ETransportShape;
868
- }({});
869
- /**
870
- *
871
- * TRANSPORT READINESS RESPONSE
872
- *
873
- */
874
- let ETransportStatus = /* @__PURE__ */ function(ETransportStatus) {
875
- ETransportStatus["uninitialized"] = "uninitialized";
876
- ETransportStatus["unsupported"] = "unsupported";
877
- ETransportStatus["initializing"] = "initializing";
878
- ETransportStatus["ready"] = "ready";
879
- ETransportStatus["failed"] = "failed";
880
- return ETransportStatus;
881
- }({});
882
- //#endregion
883
858
  //#region src/ActionRuntime/Transport/ConnectionTransportManager.ts
884
859
  var ConnectionTransportManager = class {
885
860
  _cache;
@@ -1199,6 +1174,16 @@ var PeerLinkHandler = class extends ActionHandler {
1199
1174
  _emitIncoming(json) {
1200
1175
  for (const listener of this._incomingActionDataListeners) listener(json);
1201
1176
  }
1177
+ /**
1178
+ * Whether this handler currently holds a *live* connection bound to `origin`. The runtime's return-path
1179
+ * dispatch ({@link ActionRuntime.getReturnHandlerForOrigin}) prefers a handler that owns the origin's
1180
+ * connection over a mere coordinate match, so with several duplex acceptors a result/push routes back
1181
+ * over the carrier the client connected on. Defaults to `false`; an acceptor overrides it from its
1182
+ * connection registry.
1183
+ */
1184
+ ownsLiveConnectionFor(_origin) {
1185
+ return false;
1186
+ }
1202
1187
  /** Release any long-lived connections this handler owns (a teardown). No-op by default. */
1203
1188
  clearTransportCache() {}
1204
1189
  };
@@ -1509,11 +1494,19 @@ var ActionRuntime = class {
1509
1494
  * Find the best registered external handler that can reach `originClient` directly.
1510
1495
  * Used to locate the return-path channel for dispatching results back to the action origin.
1511
1496
  * Returns `undefined` if no handler matches (score > 0 required, i.e. at least id must match).
1497
+ *
1498
+ * A handler that currently holds the origin's *live* connection always wins over a mere coordinate
1499
+ * match — so with several duplex acceptors (e.g. WS + WebRTC) a result/push routes back over the carrier
1500
+ * the client actually connected on, never a same-coordinate sibling that lacks the socket. Only when no
1501
+ * handler owns a live connection do we fall back to the plain best-coordinate-score pick (the
1502
+ * single-acceptor and connector-only cases, unchanged).
1512
1503
  */
1513
1504
  getReturnHandlerForOrigin(originClient) {
1514
1505
  if (originClient.envId === "_unset_") return void 0;
1515
1506
  let bestScore = -1;
1516
1507
  let bestHandler;
1508
+ let bestOwnedScore = -1;
1509
+ let bestOwnedHandler;
1517
1510
  for (const handler of this._registeredPeerHandlers) {
1518
1511
  if (!handler.canPush) continue;
1519
1512
  const score = originClient.similarityLevel(handler.peerClient);
@@ -1521,7 +1514,12 @@ var ActionRuntime = class {
1521
1514
  bestScore = score;
1522
1515
  bestHandler = handler;
1523
1516
  }
1517
+ if (score > bestOwnedScore && handler.ownsLiveConnectionFor(originClient)) {
1518
+ bestOwnedScore = score;
1519
+ bestOwnedHandler = handler;
1520
+ }
1524
1521
  }
1522
+ if (bestOwnedHandler != null && bestOwnedScore > 0) return bestOwnedHandler;
1525
1523
  return bestScore > 0 ? bestHandler : void 0;
1526
1524
  }
1527
1525
  resetRuntime() {
@@ -2781,6 +2779,14 @@ var AcceptorHandler = class extends PeerLinkHandler {
2781
2779
  getConnectionForClient(client) {
2782
2780
  return this._connByClient.get(client.stringId);
2783
2781
  }
2782
+ /** This acceptor owns the origin's return path when it currently holds a live connection bound to it. */
2783
+ ownsLiveConnectionFor(origin) {
2784
+ return this._connByClient.has(origin.stringId);
2785
+ }
2786
+ /** Whether this acceptor currently tracks `connection` — used to pick the owning handler among several. */
2787
+ hasConnection(connection) {
2788
+ return this._clientByConn.has(connection);
2789
+ }
2784
2790
  /**
2785
2791
  * Send (and optionally await) a server-initiated action to a specific connected client. Pass the
2786
2792
  * connection token directly (e.g. the `ws`) or a client `RuntimeCoordinate` to look one up.
@@ -2928,7 +2934,7 @@ const createAcceptorHandler = (options) => {
2928
2934
  //#endregion
2929
2935
  //#region src/ActionRuntime/Handler/PeerLink/Acceptor/createSecureActionServer.ts
2930
2936
  /** Default accepted set: negotiate per connection to whatever the client picks. */
2931
- const DEFAULT_SERVER_SECURITY_LEVELS = [
2937
+ const DEFAULT_SERVER_SECURITY_LEVELS$1 = [
2932
2938
  "none",
2933
2939
  "authenticated",
2934
2940
  "encrypted"
@@ -2943,7 +2949,7 @@ const DEFAULT_SERVER_SECURITY_LEVELS = [
2943
2949
  * {@link createHibernatableWsServerAdapter} to wire persistence + replay.
2944
2950
  */
2945
2951
  function createSecureAcceptorHandler(options) {
2946
- const link = new _nice_code_util.ClientCryptoKeyLink({ storageAdapter: options.storageAdapter });
2952
+ const link = options.link ?? new _nice_code_util.ClientCryptoKeyLink({ storageAdapter: options.storageAdapter });
2947
2953
  return new AcceptorHandler({
2948
2954
  clientEnv: options.clientEnv,
2949
2955
  createFormatMessage: options.channel.createCodec,
@@ -2951,7 +2957,7 @@ function createSecureAcceptorHandler(options) {
2951
2957
  runtime: options.runtime,
2952
2958
  defaultTimeout: options.defaultTimeout,
2953
2959
  security: {
2954
- securityLevel: options.securityLevel ?? DEFAULT_SERVER_SECURITY_LEVELS,
2960
+ securityLevel: options.securityLevel ?? DEFAULT_SERVER_SECURITY_LEVELS$1,
2955
2961
  link,
2956
2962
  localCoordinate: options.runtime.coordinate.toJsonObject(),
2957
2963
  dictionaryVersion: options.channel.dictionaryVersion,
@@ -3023,6 +3029,7 @@ function acceptChannel(runtime, channel, options) {
3023
3029
  runtime,
3024
3030
  clientEnv: options.clientEnv,
3025
3031
  storageAdapter: options.storageAdapter,
3032
+ link: options.link,
3026
3033
  send: options.send,
3027
3034
  securityLevel: options.securityLevel,
3028
3035
  verifyKeyResolver: options.verifyKeyResolver,
@@ -3511,7 +3518,8 @@ function createActionFetchHandler(runtime, options = {}) {
3511
3518
  return async (request) => {
3512
3519
  if (request.method === "OPTIONS") return withCors(new Response(null, { status: 204 }));
3513
3520
  const url = new URL(request.url);
3514
- if (options.onWebSocketUpgrade != null && request.headers.get("Upgrade") === "websocket" && isWebSocketPath(url)) return options.onWebSocketUpgrade(request, url);
3521
+ const isWebSocketUpgrade = options.isWebSocketUpgrade ?? ((req, u) => req.headers.get("Upgrade") === "websocket" && isWebSocketPath(u));
3522
+ if (options.onWebSocketUpgrade != null && isWebSocketUpgrade(request, url)) return options.onWebSocketUpgrade(request, url);
3515
3523
  if (request.method === "POST" && isActionPath(url)) {
3516
3524
  if (exchangeAcceptor != null) {
3517
3525
  const reply = await exchangeAcceptor.handlePost(await request.text());
@@ -3526,6 +3534,151 @@ function createActionFetchHandler(runtime, options = {}) {
3526
3534
  };
3527
3535
  }
3528
3536
  //#endregion
3537
+ //#region src/ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/createHibernatableWsServerAdapter.ts
3538
+ /**
3539
+ * Wire the hibernation lifecycle for an acceptor handler on a transport whose connections outlive process
3540
+ * eviction (e.g. a Durable Object's hibernatable WebSockets). It owns persistence end to end:
3541
+ * registers `setAttachment` as the handler's connection-bound callback and immediately replays every
3542
+ * live connection's stored binding via `getAttachment`, so results/pushes still route after a wake.
3543
+ *
3544
+ * Layered on top of the generic {@link AcceptorHandler} — it touches only the handler's neutral
3545
+ * `setOnConnectionBound` / `rehydrateConnection` / `receive` / `dropConnection` surface, so no
3546
+ * hibernation concern leaks into the handler itself.
3547
+ *
3548
+ * Construct it once when the handler is built, then forward connection events:
3549
+ * ```ts
3550
+ * const duplex = createHibernatableWsServerAdapter({ handler, getConnections, getAttachment, setAttachment });
3551
+ * // webSocketMessage(ws, msg) => duplex.receive(ws, msg);
3552
+ * // webSocketClose/Error(ws) => duplex.drop(ws);
3553
+ * ```
3554
+ */
3555
+ function createHibernatableWsServerAdapter(options) {
3556
+ const { handler, getConnections, getAttachment, setAttachment } = options;
3557
+ handler.setOnConnectionBound(setAttachment);
3558
+ for (const connection of getConnections()) {
3559
+ const binding = getAttachment(connection);
3560
+ if (binding != null) handler.rehydrateConnection(connection, binding);
3561
+ }
3562
+ return {
3563
+ receive: (connection, frame) => handler.receive(connection, frame),
3564
+ drop: (connection) => handler.dropConnection(connection)
3565
+ };
3566
+ }
3567
+ //#endregion
3568
+ //#region src/ActionRuntime/Channel/serveChannel.ts
3569
+ /** Default accepted set, shared by every carrier: negotiate per connection to whatever the client picks. */
3570
+ const DEFAULT_SERVER_SECURITY_LEVELS = [
3571
+ "none",
3572
+ "authenticated",
3573
+ "encrypted"
3574
+ ];
3575
+ /**
3576
+ * Serve a secure channel over one or more carriers from a single call — the accept-in dual of
3577
+ * `connectChannel`. It builds the crypto identity (a {@link ClientCryptoKeyLink} + a storage-backed TOFU
3578
+ * resolver) and the security block (coordinate, dictionary version, accepted levels) *once* from
3579
+ * `(runtime, channel)` and fans them across every carrier, so the WebSocket and the secure-HTTP endpoint
3580
+ * can never drift apart. It registers your handlers (plus the duplex acceptor it builds) on the runtime,
3581
+ * wires hibernation when the duplex carrier declares it, and returns a single {@link IChannelServer} whose
3582
+ * `fetch` / `duplex` / `pushToClient` you forward straight to the host:
3583
+ * ```ts
3584
+ * const server = serveChannel(runtime, channel, {
3585
+ * clientEnv, storage,
3586
+ * carriers: [wsAcceptorCarrier({ send, upgrade, hibernation }), httpAcceptorCarrier()],
3587
+ * handlers: [localHandler],
3588
+ * });
3589
+ * // fetch(req) => server.fetch(req)
3590
+ * // webSocketMessage(conn, m) => server.duplex?.receive(conn, m)
3591
+ * // webSocketClose/Error(conn) => server.duplex?.drop(conn)
3592
+ * ```
3593
+ *
3594
+ * `TConn` (the live-connection token a duplex carrier hands back through `send`/`receive`/`drop`) is
3595
+ * inferred from the carriers — `WebSocket` for `wsAcceptorCarrier`, the data-channel type for a WebRTC
3596
+ * carrier, and so on — so it stays carrier-agnostic.
3597
+ */
3598
+ function serveChannel(runtime, channel, options) {
3599
+ const duplexCarriers = options.carriers.filter((carrier) => !require_wsAcceptorCarrier.isExchangeAcceptorCarrier(carrier));
3600
+ const exchangeCarriers = options.carriers.filter(require_wsAcceptorCarrier.isExchangeAcceptorCarrier);
3601
+ if (exchangeCarriers.length > 1) throw new Error("serveChannel: at most one exchange carrier is supported");
3602
+ const exchangeCarrier = exchangeCarriers[0];
3603
+ const exchangeSecure = exchangeCarrier != null && (exchangeCarrier.secure ?? true);
3604
+ const anyDuplexSecure = duplexCarriers.some((carrier) => carrier.secure ?? true);
3605
+ const securityLevel = options.securityLevel ?? DEFAULT_SERVER_SECURITY_LEVELS;
3606
+ let secure;
3607
+ if (anyDuplexSecure || exchangeSecure) {
3608
+ const storage = options.storage;
3609
+ if (storage == null) throw new Error("serveChannel: a secure carrier requires `storage`. Pass it, or set `secure: false` on the carrier for a plain endpoint.");
3610
+ secure = {
3611
+ storage,
3612
+ link: options.link ?? new _nice_code_util.ClientCryptoKeyLink({ storageAdapter: storage }),
3613
+ verifyKeyResolver: options.verifyKeyResolver ?? createStorageTofuVerifyKeyResolver(storage)
3614
+ };
3615
+ }
3616
+ const handlers = [];
3617
+ for (const carrier of duplexCarriers) {
3618
+ const handler = (carrier.secure ?? true) && secure != null ? acceptChannel(runtime, channel, {
3619
+ clientEnv: options.clientEnv,
3620
+ storageAdapter: secure.storage,
3621
+ link: secure.link,
3622
+ verifyKeyResolver: secure.verifyKeyResolver,
3623
+ securityLevel,
3624
+ send: carrier.send,
3625
+ defaultTimeout: options.defaultTimeout
3626
+ }) : createAcceptorHandler({
3627
+ clientEnv: options.clientEnv,
3628
+ createFormatMessage: channel.createCodec,
3629
+ send: carrier.send,
3630
+ runtime,
3631
+ defaultTimeout: options.defaultTimeout
3632
+ });
3633
+ const router = carrier.hibernation != null ? createHibernatableWsServerAdapter({
3634
+ handler,
3635
+ ...carrier.hibernation
3636
+ }) : {
3637
+ receive: (connection, frame) => handler.receive(connection, frame),
3638
+ drop: (connection) => handler.dropConnection(connection)
3639
+ };
3640
+ carrier._activate(router);
3641
+ handlers.push(handler);
3642
+ }
3643
+ runtime.addHandlers([...options.handlers ?? [], ...handlers]);
3644
+ const exchangeSecurity = exchangeSecure && secure != null ? {
3645
+ link: secure.link,
3646
+ verifyKeyResolver: secure.verifyKeyResolver,
3647
+ localCoordinate: runtime.coordinate.toJsonObject(),
3648
+ dictionaryVersion: channel.dictionaryVersion,
3649
+ securityLevel
3650
+ } : void 0;
3651
+ const defaultIsUpgrade = (request) => request.headers.get("Upgrade") === "websocket";
3652
+ const upgraders = [];
3653
+ for (const carrier of duplexCarriers) {
3654
+ if (carrier.upgrade == null) continue;
3655
+ upgraders.push({
3656
+ isUpgrade: carrier.isUpgrade ?? defaultIsUpgrade,
3657
+ upgrade: carrier.upgrade
3658
+ });
3659
+ }
3660
+ const fetch = createActionFetchHandler(runtime, {
3661
+ cors: exchangeCarrier?.cors,
3662
+ onWebSocketUpgrade: upgraders.length === 0 ? void 0 : (request, url) => (upgraders.find((u) => u.isUpgrade(request, url)) ?? upgraders[0]).upgrade(request, url),
3663
+ isWebSocketUpgrade: upgraders.length === 0 ? void 0 : (request, url) => upgraders.some((u) => u.isUpgrade(request, url)),
3664
+ isActionPath: exchangeCarrier != null ? exchangeCarrier.isActionPath ?? (() => true) : () => false,
3665
+ security: exchangeSecurity,
3666
+ useErrorStatus: exchangeCarrier?.useErrorStatus
3667
+ });
3668
+ const duplex = duplexCarriers.length === 1 ? duplexCarriers[0] : void 0;
3669
+ const pushToClient = (target, request, pushOptions) => {
3670
+ const owner = target instanceof RuntimeCoordinate ? handlers.find((handler) => handler.ownsLiveConnectionFor(target)) : handlers.find((handler) => handler.hasConnection(target));
3671
+ if (owner == null) throw new Error("serveChannel: no duplex carrier holds a connection for the push target");
3672
+ return owner.pushToClient(runtime, target, request, pushOptions);
3673
+ };
3674
+ return {
3675
+ handlers,
3676
+ fetch,
3677
+ duplex,
3678
+ pushToClient
3679
+ };
3680
+ }
3681
+ //#endregion
3529
3682
  //#region src/ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/ConnectionStateStore.ts
3530
3683
  /**
3531
3684
  * A typed per-connection state store that co-owns the app state and the acceptor handler's routing
@@ -3633,37 +3786,6 @@ function createConnectionStateStore(handler, options) {
3633
3786
  return store;
3634
3787
  }
3635
3788
  //#endregion
3636
- //#region src/ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/createHibernatableWsServerAdapter.ts
3637
- /**
3638
- * Wire the hibernation lifecycle for an acceptor handler on a transport whose sockets outlive process
3639
- * eviction (e.g. a Durable Object's hibernatable WebSockets). It owns persistence end to end:
3640
- * registers `setAttachment` as the handler's connection-bound callback and immediately replays every
3641
- * live connection's stored binding via `getAttachment`, so results/pushes still route after a wake.
3642
- *
3643
- * Layered on top of the generic {@link AcceptorHandler} — it touches only the handler's neutral
3644
- * `setOnConnectionBound` / `rehydrateConnection` / `receive` / `dropConnection` surface, so no
3645
- * hibernation concern leaks into the handler itself.
3646
- *
3647
- * Construct it once when the handler is built, then forward socket events:
3648
- * ```ts
3649
- * const wsServer = createHibernatableWsServerAdapter({ handler, getWebSockets, getAttachment, setAttachment });
3650
- * // webSocketMessage(ws, msg) => wsServer.receive(ws, msg);
3651
- * // webSocketClose/Error(ws) => wsServer.drop(ws);
3652
- * ```
3653
- */
3654
- function createHibernatableWsServerAdapter(options) {
3655
- const { handler, getWebSockets, getAttachment, setAttachment } = options;
3656
- handler.setOnConnectionBound(setAttachment);
3657
- for (const connection of getWebSockets()) {
3658
- const binding = getAttachment(connection);
3659
- if (binding != null) handler.rehydrateConnection(connection, binding);
3660
- }
3661
- return {
3662
- receive: (connection, frame) => handler.receive(connection, frame),
3663
- drop: (connection) => handler.dropConnection(connection)
3664
- };
3665
- }
3666
- //#endregion
3667
3789
  //#region src/ActionRuntime/Transport/Carrier/duplex/inMemory/createInMemoryChannel.ts
3668
3790
  /**
3669
3791
  * Two cross-wired in-process byte channels — a loopback carrier with no socket. The client end is a
@@ -3821,6 +3943,22 @@ function rtcCarrier(dataChannel, options = {}) {
3821
3943
  };
3822
3944
  }
3823
3945
  //#endregion
3946
+ //#region src/ActionRuntime/Transport/Carrier/duplex/ws/err_nice_transport_ws.ts
3947
+ let EErrId_NiceTransport_WebSocket = /* @__PURE__ */ function(EErrId_NiceTransport_WebSocket) {
3948
+ EErrId_NiceTransport_WebSocket["ws_disconnected"] = "ws_disconnected";
3949
+ EErrId_NiceTransport_WebSocket["ws_create_failed"] = "ws_create_failed";
3950
+ EErrId_NiceTransport_WebSocket["ws_error"] = "ws_error";
3951
+ return EErrId_NiceTransport_WebSocket;
3952
+ }({});
3953
+ const err_nice_transport_ws = err_nice_transport.createChildDomain({
3954
+ domain: "ws_transport",
3955
+ schema: {
3956
+ ["ws_disconnected"]: (0, _nice_code_error.err)({ message: () => `WebSocket transport disconnected.` }),
3957
+ ["ws_create_failed"]: (0, _nice_code_error.err)({ message: ({ originalError }) => `Failed to create WebSocket transport.${originalError ? ` Original error: ${originalError.message}` : ""}` }),
3958
+ ["ws_error"]: (0, _nice_code_error.err)({ message: ({ originalError }) => `WebSocket transport error.${originalError ? ` Original error: ${originalError.message}` : ""}` })
3959
+ }
3960
+ });
3961
+ //#endregion
3824
3962
  //#region src/ActionRuntime/Transport/Carrier/duplex/ws/ws_util.ts
3825
3963
  /**
3826
3964
  * Send a text or binary frame over a socket. A binary formatter may hand back a `Uint8Array` whose
@@ -3933,6 +4071,25 @@ function defaultWebSocket(url) {
3933
4071
  return ws;
3934
4072
  }
3935
4073
  //#endregion
4074
+ //#region src/ActionRuntime/Transport/Carrier/exchange/http/httpAcceptorCarrier.ts
4075
+ /**
4076
+ * An HTTP {@link IExchangeAcceptorCarrier}: the accept-in dual of {@link httpCarrier}. It serves the
4077
+ * secure exchange protocol (handshake → token session → encrypted frames) over web-standard
4078
+ * `Request`/`Response`. The crypto identity, runtime coordinate, dictionary version, and accepted security
4079
+ * levels are all supplied centrally by `serveChannel`, so this only needs to say which requests carry an
4080
+ * action envelope and how to answer CORS.
4081
+ */
4082
+ function httpAcceptorCarrier(options = {}) {
4083
+ return {
4084
+ shape: "exchange",
4085
+ carrierLabel: options.carrierLabel ?? "http",
4086
+ secure: options.secure,
4087
+ isActionPath: options.isActionPath,
4088
+ cors: options.cors,
4089
+ useErrorStatus: options.useErrorStatus
4090
+ };
4091
+ }
4092
+ //#endregion
3936
4093
  //#region src/ActionRuntime/Transport/Carrier/exchange/http/httpCarrier.ts
3937
4094
  function shortPath(url) {
3938
4095
  try {
@@ -4398,22 +4555,6 @@ var ExchangeTransport = class ExchangeTransport extends Transport {
4398
4555
  }
4399
4556
  };
4400
4557
  //#endregion
4401
- //#region src/ActionRuntime/Transport/Carrier/duplex/ws/err_nice_transport_ws.ts
4402
- let EErrId_NiceTransport_WebSocket = /* @__PURE__ */ function(EErrId_NiceTransport_WebSocket) {
4403
- EErrId_NiceTransport_WebSocket["ws_disconnected"] = "ws_disconnected";
4404
- EErrId_NiceTransport_WebSocket["ws_create_failed"] = "ws_create_failed";
4405
- EErrId_NiceTransport_WebSocket["ws_error"] = "ws_error";
4406
- return EErrId_NiceTransport_WebSocket;
4407
- }({});
4408
- const err_nice_transport_ws = err_nice_transport.createChildDomain({
4409
- domain: "ws_transport",
4410
- schema: {
4411
- ["ws_disconnected"]: (0, _nice_code_error.err)({ message: () => `WebSocket transport disconnected.` }),
4412
- ["ws_create_failed"]: (0, _nice_code_error.err)({ message: ({ originalError }) => `Failed to create WebSocket transport.${originalError ? ` Original error: ${originalError.message}` : ""}` }),
4413
- ["ws_error"]: (0, _nice_code_error.err)({ message: ({ originalError }) => `WebSocket transport error.${originalError ? ` Original error: ${originalError.message}` : ""}` })
4414
- }
4415
- });
4416
- //#endregion
4417
4558
  //#region src/ActionRuntime/Transport/helpers/createUnsetTransportResolvers.ts
4418
4559
  const createUnsetTransportResolvers = (transportLabel) => ({ onIncomingActionDataJson: (json) => {
4419
4560
  console.warn(`Received incoming action JSON [${json.domain}:${json.id}] on Transport [${transportLabel}] but no incoming data listener has been set.`);
@@ -4741,8 +4882,8 @@ exports.ERunningActionFinishedType = require_RunningAction_types.ERunningActionF
4741
4882
  exports.ERunningActionState = require_RunningAction_types.ERunningActionState;
4742
4883
  exports.ERunningActionUpdateType = require_RunningAction_types.ERunningActionUpdateType;
4743
4884
  exports.ESecurityLevel = ESecurityLevel;
4744
- exports.ETransportShape = ETransportShape;
4745
- exports.ETransportStatus = ETransportStatus;
4885
+ exports.ETransportShape = require_wsAcceptorCarrier.ETransportShape;
4886
+ exports.ETransportStatus = require_wsAcceptorCarrier.ETransportStatus;
4746
4887
  exports.ExchangeAcceptor = ExchangeAcceptor;
4747
4888
  exports.ExchangeTransport = ExchangeTransport;
4748
4889
  exports.LinkTransport = LinkTransport;
@@ -4779,16 +4920,20 @@ exports.err_nice_action = err_nice_action;
4779
4920
  exports.err_nice_external_client = err_nice_external_client;
4780
4921
  exports.err_nice_transport = err_nice_transport;
4781
4922
  exports.err_nice_transport_ws = err_nice_transport_ws;
4923
+ exports.httpAcceptorCarrier = httpAcceptorCarrier;
4782
4924
  exports.httpCarrier = httpCarrier;
4783
4925
  exports.inMemoryCarrier = inMemoryCarrier;
4784
4926
  exports.isActionPayload_Any_JsonObject = isActionPayload_Any_JsonObject;
4785
4927
  exports.isActionPayload_Request_JsonObject = isActionPayload_Request_JsonObject;
4786
4928
  exports.isActionPayload_Result_JsonObject = isActionPayload_Result_JsonObject;
4929
+ exports.isExchangeAcceptorCarrier = require_wsAcceptorCarrier.isExchangeAcceptorCarrier;
4787
4930
  exports.plainTransport = plainTransport;
4788
4931
  exports.rtcCarrier = rtcCarrier;
4789
4932
  exports.rtcDataChannelByteChannel = rtcDataChannelByteChannel;
4790
4933
  exports.runtimeLinkId = runtimeLinkId;
4791
4934
  exports.secureTransport = secureTransport;
4935
+ exports.serveChannel = serveChannel;
4936
+ exports.wsAcceptorCarrier = require_wsAcceptorCarrier.wsAcceptorCarrier;
4792
4937
  exports.wsCarrier = wsCarrier;
4793
4938
 
4794
4939
  //# sourceMappingURL=index.cjs.map