@nice-code/action 0.22.0 → 0.24.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 (40) hide show
  1. package/README.md +22 -25
  2. package/build/{ActionPayload.types-Dx1JPyfs.d.mts → AcceptorHandler-11-QMdx2.d.mts} +977 -1351
  3. package/build/{ActionPayload.types-L9k0LyBd.d.cts → AcceptorHandler-CxD0c1BE.d.cts} +977 -1351
  4. package/build/{ActionDevtoolsCore-CQ0vrvPD.d.cts → ActionDevtoolsCore-37JP4bOG.d.cts} +2 -2
  5. package/build/{ActionDevtoolsCore-CiLBYC3K.d.mts → ActionDevtoolsCore-Cgq-go1R.d.mts} +2 -2
  6. package/build/advanced/index.cjs +115 -0
  7. package/build/advanced/index.cjs.map +1 -0
  8. package/build/advanced/index.d.cts +344 -0
  9. package/build/advanced/index.d.mts +344 -0
  10. package/build/advanced/index.mjs +88 -0
  11. package/build/advanced/index.mjs.map +1 -0
  12. package/build/{httpAcceptorCarrier-OnJxzsAD.cjs → createHibernatableWsServerAdapter-BNi4k9j3.cjs} +258 -470
  13. package/build/createHibernatableWsServerAdapter-BNi4k9j3.cjs.map +1 -0
  14. package/build/{httpAcceptorCarrier-DL8lf0xB.mjs → createHibernatableWsServerAdapter-C07RfUTH.mjs} +233 -421
  15. package/build/createHibernatableWsServerAdapter-C07RfUTH.mjs.map +1 -0
  16. package/build/devtools/browser/index.d.cts +1 -1
  17. package/build/devtools/browser/index.d.mts +1 -1
  18. package/build/devtools/server/index.d.cts +1 -1
  19. package/build/devtools/server/index.d.mts +1 -1
  20. package/build/httpAcceptorCarrier-C3S_bDkL.cjs +454 -0
  21. package/build/httpAcceptorCarrier-C3S_bDkL.cjs.map +1 -0
  22. package/build/httpAcceptorCarrier-DPBEuewS.mjs +401 -0
  23. package/build/httpAcceptorCarrier-DPBEuewS.mjs.map +1 -0
  24. package/build/index.cjs +84 -458
  25. package/build/index.cjs.map +1 -1
  26. package/build/index.d.cts +2 -2
  27. package/build/index.d.mts +2 -2
  28. package/build/index.mjs +28 -374
  29. package/build/index.mjs.map +1 -1
  30. package/build/platform/cloudflare/index.cjs +1 -1
  31. package/build/platform/cloudflare/index.cjs.map +1 -1
  32. package/build/platform/cloudflare/index.d.cts +3 -3
  33. package/build/platform/cloudflare/index.d.mts +3 -3
  34. package/build/platform/cloudflare/index.mjs +1 -1
  35. package/build/platform/cloudflare/index.mjs.map +1 -1
  36. package/build/react-query/index.d.cts +1 -1
  37. package/build/react-query/index.d.mts +1 -1
  38. package/package.json +15 -4
  39. package/build/httpAcceptorCarrier-DL8lf0xB.mjs.map +0 -1
  40. package/build/httpAcceptorCarrier-OnJxzsAD.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["ENVELOPE","ENVELOPE_LENGTH","normalizeFrame"],"sources":["../src/ActionDefinition/Action/Context/ActionContext.ts","../src/ActionDefinition/Action/Core/ActionCore.ts","../src/utils/isAction_Context_JsonObject.ts","../src/utils/isAction_Core_JsonObject.ts","../src/utils/isAction_Any_JsonObject.ts","../src/utils/assertIsActionJson.ts","../src/utils/isAction_Any_Instance.ts","../src/ActionDefinition/Domain/ActionDomainBase.ts","../src/ActionRuntime/ActionRuntimeManager.ts","../src/ActionDefinition/Domain/ActionRootDomain.ts","../src/ActionDefinition/Domain/ActionDomain.ts","../src/ActionDefinition/Domain/helpers/createRootActionDomain.ts","../src/ActionRuntime/Transport/codec/actionWireCodec.ts","../src/ActionRuntime/Transport/codec/createBinaryWireSessionFactory.ts","../src/ActionRuntime/Channel/secureChannel.ts","../src/ActionRuntime/Transport/Carrier/duplex/inMemory/createInMemoryChannel.ts","../src/ActionRuntime/Transport/Carrier/duplex/inMemory/inMemoryCarrier.ts","../src/ActionRuntime/Transport/Carrier/duplex/rtc/rtcDataChannelByteChannel.ts","../src/ActionRuntime/Transport/Carrier/duplex/rtc/rtcCarrier.ts","../src/ActionRuntime/Transport/Carrier/duplex/ws/err_nice_transport_ws.ts","../src/ActionRuntime/Transport/Carrier/duplex/ws/ws_util.ts","../src/ActionRuntime/Transport/Carrier/duplex/ws/webSocketByteChannel.ts","../src/ActionRuntime/Transport/Carrier/duplex/ws/wsCarrier.ts","../src/ActionRuntime/Transport/Carrier/exchange/http/httpCarrier.ts","../src/ActionRuntime/Transport/codec/createBinaryWireAdapter.ts"],"sourcesContent":["import { RuntimeCoordinate } from \"../../../ActionRuntime/RuntimeCoordinate\";\nimport type { ActionDomain } from \"../../Domain/ActionDomain\";\nimport type {\n IActionDomain,\n TInferInputFromSchema,\n TInferOutputFromSchema,\n} from \"../../Domain/ActionDomain.types\";\nimport { ActionBase } from \"../ActionBase\";\nimport { EActionForm } from \"../ActionBase.types\";\nimport type {\n IActionContext,\n IActionContext_Data,\n IActionContext_Data_JsonObject,\n IActionContext_JsonObject,\n IActionRouteItem,\n} from \"./ActionContext.types\";\n\nexport class ActionContext<\n DOM extends IActionDomain,\n ID extends keyof DOM[\"actionSchema\"] & string = keyof DOM[\"actionSchema\"] & string,\n >\n extends ActionBase<EActionForm.context, DOM, ID>\n implements IActionContext<DOM, ID>\n{\n readonly form = EActionForm.context;\n readonly _routing: IActionRouteItem[];\n readonly timeCreated: number;\n readonly cuid: string;\n originClient: RuntimeCoordinate;\n\n constructor(\n readonly _domain: ActionDomain<DOM>,\n id: ID,\n hydrationData: IActionContext_Data,\n ) {\n super(EActionForm.context, _domain, id);\n this.timeCreated = hydrationData.timeCreated;\n this.cuid = hydrationData.cuid;\n this._routing = hydrationData.routing;\n this.originClient = hydrationData.originClient;\n }\n\n _setOriginClient(client: RuntimeCoordinate): void {\n this.originClient = client;\n }\n\n toJsonString(): string {\n return JSON.stringify(this.toJsonObject());\n }\n\n toContextDataJsonObject(): IActionContext_Data_JsonObject {\n return {\n timeCreated: this.timeCreated,\n cuid: this.cuid,\n routing: this.routing.map((item) => ({\n runtime: item.runtime.toJsonObject(),\n handler: item.handler,\n time: item.time,\n })),\n originClient: this.originClient.toJsonObject(),\n };\n }\n\n toJsonObject(): IActionContext_JsonObject<DOM, ID> {\n return {\n ...super.toJsonObject(),\n ...this.toContextDataJsonObject(),\n };\n }\n\n get routing(): IActionRouteItem[] {\n return this._routing;\n }\n\n addRouteItem(item: IActionRouteItem): void {\n this._routing.push(item);\n }\n\n deserializeInput(\n serialized: TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"SerdeInput\"],\n ): TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"] {\n return this.schema.deserializeInput(serialized);\n }\n\n serializeInput(\n raw: TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"],\n ): TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"SerdeInput\"] {\n return this.schema.serializeInput(raw);\n }\n\n validateInput(input: unknown): TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"] {\n return this.schema.validateInput(input, {\n domain: this.domain,\n actionId: this.id,\n });\n }\n\n validateOutput(output: unknown): TInferOutputFromSchema<DOM[\"actionSchema\"][ID]>[\"Output\"] {\n return this.schema.validateOutput(output, {\n domain: this.domain,\n actionId: this.id,\n });\n }\n}\n","import { nanoid } from \"nanoid\";\nimport { RuntimeCoordinate } from \"../../../ActionRuntime/RuntimeCoordinate\";\nimport type { ActionDomain } from \"../../Domain/ActionDomain\";\nimport type {\n IActionDomain,\n TInferInputFromSchema,\n TInferOutputFromSchema,\n} from \"../../Domain/ActionDomain.types\";\nimport type { TNarrowActionType } from \"../Action.combined.types\";\nimport { ActionBase } from \"../ActionBase\";\nimport { EActionForm, type IActionBase, type IActionBase_JsonObject } from \"../ActionBase.types\";\nimport { ActionContext } from \"../Context/ActionContext\";\nimport { ActionPayload } from \"../Payload/ActionPayload\";\nimport { ActionPayload_Request } from \"../Payload/ActionPayload_Request\";\nimport type { IActionCore } from \"./ActionCore.types\";\n\nexport class ActionCore<\n DOM extends IActionDomain,\n ID extends keyof DOM[\"actionSchema\"] & string = keyof DOM[\"actionSchema\"] & string,\n >\n extends ActionBase<EActionForm.core, DOM, ID>\n implements IActionCore<DOM, ID>\n{\n readonly form = EActionForm.core;\n\n constructor(\n readonly _domain: ActionDomain<DOM>,\n id: ID,\n ) {\n super(EActionForm.core, _domain, id);\n }\n\n is<ACT extends IActionBase<any, any, any>>(\n action: ACT | unknown | null | undefined,\n ): action is TNarrowActionType<DOM, ACT, ID> {\n return (\n action instanceof ActionPayload && action.domain === this.domain && action.id === this.id\n );\n }\n\n toJsonObject(): IActionBase_JsonObject<EActionForm.core, DOM, ID> {\n return {\n id: this.id,\n form: this.form,\n domain: this.domain,\n allDomains: this.allDomains,\n };\n }\n\n request(\n ...args: [TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"]] extends [never]\n ? [input?: never]\n : [input: TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"]]\n ): ActionPayload_Request<DOM, ID> {\n const input: unknown = args[0];\n const validatedInput = this.schema.validateInput(input, {\n actionId: this.id,\n domain: this.domain,\n });\n\n const context = new ActionContext(this._domain, this.id, {\n cuid: nanoid(),\n timeCreated: Date.now(),\n routing: [],\n originClient: RuntimeCoordinate.unknown,\n });\n\n return new ActionPayload_Request({ context }, validatedInput, {\n time: Date.now(),\n });\n }\n\n // async run(\n // input: TInferInputFromSchema<DOM[\"actions\"][ID]>[\"Input\"],\n // options?: IExecuteActionOptions<DOM, ID>,\n // ): Promise<RunningAction<DOM, ID>> {\n // return this.request(input).run(options);\n // }\n\n // async runToOutput(\n // input: TInferInputFromSchema<DOM[\"actions\"][ID]>[\"Input\"],\n // options?: IExecuteActionOptions<DOM, ID>,\n // ): Promise<TInferOutputFromSchema<DOM[\"actions\"][ID]>[\"Output\"]> {\n // return this.request(input).runToOutput(options);\n // }\n\n // async runToOutputSafe(\n // input: TInferInputFromSchema<DOM[\"actions\"][ID]>[\"Input\"],\n // options?: IExecuteActionOptions<DOM, ID>,\n // ): Promise<\n // TActionResult<\n // TInferOutputFromSchema<DOM[\"actions\"][ID]>[\"Output\"],\n // TInferActionError<DOM[\"actions\"][ID]>\n // >\n // > {\n // return this.request(input).runToOutputSafe(options);\n // }\n\n deserializeInput(\n serialized: TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"SerdeInput\"],\n ): TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"] {\n return this.schema.deserializeInput(serialized);\n }\n\n serializeInput(\n raw: TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"],\n ): TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"SerdeInput\"] {\n return this.schema.serializeInput(raw);\n }\n\n validateInput(input: unknown): TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"] {\n return this.schema.validateInput(input, {\n domain: this.domain,\n actionId: this.id,\n });\n }\n\n validateOutput(output: unknown): TInferOutputFromSchema<DOM[\"actionSchema\"][ID]>[\"Output\"] {\n return this.schema.validateOutput(output, {\n domain: this.domain,\n actionId: this.id,\n });\n }\n}\n","import { EActionForm } from \"../ActionDefinition/Action/ActionBase.types\";\nimport type { IActionContext_JsonObject } from \"../ActionDefinition/Action/Context/ActionContext.types\";\nimport { isAction_Base_JsonObject } from \"./isAction_Base_JsonObject\";\n\nexport const isAction_Context_JsonObject = (obj: unknown): obj is IActionContext_JsonObject => {\n return isAction_Base_JsonObject(obj) && obj.form === EActionForm.context;\n};\n","import { EActionForm } from \"../ActionDefinition/Action/ActionBase.types\";\nimport type { IActionCore_JsonObject } from \"../ActionDefinition/Action/Core/ActionCore.types\";\nimport { isAction_Base_JsonObject } from \"./isAction_Base_JsonObject\";\n\nexport const isAction_Core_JsonObject = (obj: unknown): obj is IActionCore_JsonObject => {\n return isAction_Base_JsonObject(obj) && obj.form === EActionForm.core;\n};\n","import type { TAction_Any_JsonObject } from \"../ActionDefinition/Action/Action.combined.types\";\nimport { isAction_Context_JsonObject } from \"./isAction_Context_JsonObject\";\nimport { isAction_Core_JsonObject } from \"./isAction_Core_JsonObject\";\nimport { isActionPayload_Any_JsonObject } from \"./isActionPayload_Any_JsonObject\";\n\nexport function isAction_Any_JsonObject(obj: unknown): obj is TAction_Any_JsonObject {\n return (\n isActionPayload_Any_JsonObject(obj) ||\n isAction_Context_JsonObject(obj) ||\n isAction_Core_JsonObject(obj)\n );\n}\n","import type { IActionBase_JsonObject } from \"../ActionDefinition/Action/ActionBase.types\";\nimport { EErrId_NiceAction, err_nice_action } from \"../errors/err_nice_action\";\nimport { isAction_Any_JsonObject } from \"./isAction_Any_JsonObject\";\n\nexport function assertIsActionJson(obj: unknown): asserts obj is IActionBase_JsonObject {\n if (!isAction_Any_JsonObject(obj)) {\n throw err_nice_action.fromId(EErrId_NiceAction.wire_not_action_data);\n }\n}\n","import type { TAction_Any_Instance } from \"../ActionDefinition/Action/Action.combined.types\";\nimport type { IActionBase } from \"../ActionDefinition/Action/ActionBase.types\";\nimport { ActionContext } from \"../ActionDefinition/Action/Context/ActionContext\";\nimport { ActionCore } from \"../ActionDefinition/Action/Core/ActionCore\";\nimport { ActionPayload } from \"../ActionDefinition/Action/Payload/ActionPayload\";\n\nexport function isAction_Any_Instance<ACT extends IActionBase<any, any>>(\n value: unknown | ACT,\n): value is TAction_Any_Instance<any, any> {\n return (\n value instanceof ActionCore || value instanceof ActionPayload || value instanceof ActionContext\n );\n}\n","import type {\n TDistributeRunningActionUpdateListener,\n TRunningActionUpdateListener,\n} from \"../Action/RunningAction.types\";\nimport type { IActionDomain } from \"./ActionDomain.types\";\n\nexport abstract class ActionDomainBase<ACT_DOM extends IActionDomain = IActionDomain>\n implements IActionDomain<ACT_DOM[\"allDomains\"], ACT_DOM[\"actionSchema\"]>\n{\n readonly domain: ACT_DOM[\"domain\"];\n readonly allDomains: ACT_DOM[\"allDomains\"];\n readonly actionSchema: ACT_DOM[\"actionSchema\"];\n\n protected _listeners: TRunningActionUpdateListener<any, any>[] = [];\n\n constructor(definition: ACT_DOM) {\n this.domain = definition.domain;\n this.allDomains = definition.allDomains;\n this.actionSchema = definition.actionSchema;\n }\n\n /**\n * Add an observer that is called after every action dispatched through this domain.\n * Returns an unsubscribe function — call it to remove the listener.\n */\n addActionListener(\n listener: TDistributeRunningActionUpdateListener<\n ACT_DOM,\n keyof ACT_DOM[\"actionSchema\"] & string\n >,\n ): () => void {\n this._listeners.push(listener as TRunningActionUpdateListener<any, any>);\n return () => {\n this._listeners = this._listeners.filter((l) => l !== listener);\n };\n }\n\n /**\n * @internal\n * Observers registered directly on this domain via {@link addActionListener}.\n * Used to wire observers (e.g. devtools) onto RunningActions that aren't created\n * through the local-dispatch path — notably inbound actions pushed from a backend\n * or another client over a bidirectional transport.\n */\n _getActionObservers(): TRunningActionUpdateListener<any, any>[] {\n return this._listeners;\n }\n}\n","import type { TActionPayload_Any_Instance } from \"../ActionDefinition/Action/Payload/ActionPayload.types\";\nimport { EErrId_NiceAction, err_nice_action } from \"../errors/err_nice_action\";\nimport type { ActionRuntime } from \"./ActionRuntime\";\nimport type { IActionHandlerAndRuntime, IActionRuntimeManagerContext } from \"./ActionRuntime.types\";\nimport type { IHandleActionOptions } from \"./Handler/ActionHandler.types\";\nimport {\n type IRuntimeCoordinate,\n RuntimeCoordinate,\n type TRuntimeCoordinateStringId,\n} from \"./RuntimeCoordinate\";\nimport { runtimeCoordinateToStringIds } from \"./utils/runtimeCoordinateToStringIds\";\n\nexport class ActionRuntimeManager {\n private _runtimes: Map<TRuntimeCoordinateStringId, ActionRuntime> = new Map();\n private _preferredRuntimeClientId: TRuntimeCoordinateStringId | null = null;\n private _context: IActionRuntimeManagerContext;\n\n constructor(context?: IActionRuntimeManagerContext) {\n this._context = context ?? {};\n }\n\n registerRuntime(runtime: ActionRuntime): void {\n const runtimeId = runtime.coordinate.stringId;\n if (this._runtimes.has(runtimeId)) {\n throw err_nice_action.fromId(EErrId_NiceAction.client_runtime_already_registered, {\n context: this._context,\n client: runtime.coordinate,\n });\n }\n\n for (const id of runtime.coordinate.toStringIds()) {\n if (this._runtimes.has(id)) {\n continue;\n }\n\n this._runtimes.set(id, runtime);\n }\n }\n\n getRuntimeAndHandlerForAction(\n action: TActionPayload_Any_Instance<any, any>,\n options?: IHandleActionOptions,\n throwOnIssue?: boolean,\n ): IActionHandlerAndRuntime | undefined {\n const localRuntime = options?.targetLocalRuntime;\n\n if (localRuntime != null) {\n const runtime = throwOnIssue\n ? this.getBestRuntimeOrThrow(options?.targetLocalRuntime?.coordinate)\n : this.getBestRuntime(options?.targetLocalRuntime?.coordinate);\n\n if (runtime == null) {\n return;\n }\n\n const handler = runtime._getHandlerForAction(action, options);\n\n if (handler != null) {\n return { handler, runtime };\n }\n\n if (throwOnIssue) {\n throw err_nice_action.fromId(EErrId_NiceAction.no_action_execution_handler, {\n domain: action.domain,\n actionId: action.id,\n specifiedClient: localRuntime.coordinate,\n });\n }\n }\n\n // If no client specified, try to find a runtime that can handle the action\n for (const runtime of this._runtimes.values()) {\n const handler = runtime._getHandlerForAction(action);\n if (handler) {\n return { handler, runtime };\n }\n }\n\n if (throwOnIssue) {\n throw err_nice_action.fromId(EErrId_NiceAction.no_action_execution_handler, {\n domain: action.domain,\n actionId: action.id,\n specifiedClient: options?.targetLocalRuntime?.coordinate,\n });\n }\n }\n\n getRuntimeAndHandlerForActionOrThrow(\n action: TActionPayload_Any_Instance<any, any>,\n options?: IHandleActionOptions,\n ): IActionHandlerAndRuntime {\n return this.getRuntimeAndHandlerForAction(action, options, true)!;\n }\n\n setPreferredRuntime(runtime: ActionRuntime): void {\n const runtimeId = runtime.coordinate.stringId;\n this._preferredRuntimeClientId = runtimeId;\n }\n\n getPreferredRuntime(): ActionRuntime | undefined {\n if (this._preferredRuntimeClientId) {\n const runtime = this._runtimes.get(this._preferredRuntimeClientId);\n if (runtime) {\n return runtime;\n }\n }\n return this._runtimes.values().next().value;\n }\n\n getBestRuntimeForSpecifier(clientSpecifier: IRuntimeCoordinate): ActionRuntime | undefined {\n const actionClient = new RuntimeCoordinate(clientSpecifier);\n const ids = actionClient.toStringIds();\n\n for (const id of ids) {\n const runtime = this._runtimes.get(id);\n if (runtime) {\n return runtime;\n }\n }\n }\n\n getBestRuntime(clientSpecifier?: IRuntimeCoordinate): ActionRuntime | undefined {\n return clientSpecifier != null\n ? this.getBestRuntimeForSpecifier(clientSpecifier)\n : this.getPreferredRuntime();\n }\n\n hasRuntime(runtime: ActionRuntime): boolean {\n return this._runtimes.has(runtime.coordinate.stringId);\n }\n\n getBestRuntimeOrThrow(specifier?: IRuntimeCoordinate): ActionRuntime {\n const runtime = this.getBestRuntime(specifier);\n\n if (!runtime) {\n if (specifier == null) {\n throw err_nice_action.fromId(EErrId_NiceAction.no_client_runtimes_registered, {\n context: this._context,\n });\n }\n\n throw err_nice_action.fromId(EErrId_NiceAction.client_runtime_not_registered, {\n context: this._context,\n clientStringId: runtimeCoordinateToStringIds(specifier)[0],\n });\n }\n\n return runtime;\n }\n}\n","import type { ActionRuntime } from \"../../ActionRuntime/ActionRuntime\";\nimport type { IActionHandlerAndRuntime } from \"../../ActionRuntime/ActionRuntime.types\";\nimport { ActionRuntimeManager } from \"../../ActionRuntime/ActionRuntimeManager\";\nimport type { IExecuteActionOptions } from \"../../ActionRuntime/Handler/ActionHandler.types\";\nimport type { IRuntimeCoordinate } from \"../../ActionRuntime/RuntimeCoordinate\";\nimport { EErrId_NiceAction, err_nice_action } from \"../../errors/err_nice_action\";\nimport type { ActionPayload_Request } from \"../Action/Payload/ActionPayload_Request\";\nimport { RunningAction } from \"../Action/RunningAction\";\nimport { ActionDomain } from \"./ActionDomain\";\nimport type {\n IActionDomain,\n IActionDomainChildOptions,\n IActionRootDomain,\n TActionDomainChildDef,\n} from \"./ActionDomain.types\";\nimport { ActionDomainBase } from \"./ActionDomainBase\";\n\nexport class ActionRootDomain<\n ROOT_DOM extends IActionRootDomain = IActionRootDomain,\n> extends ActionDomainBase<ROOT_DOM> {\n private _actionRuntimeManager: ActionRuntimeManager;\n\n constructor(\n readonly domainDefinition: {\n domain: ROOT_DOM[\"domain\"];\n },\n ) {\n const domainId = domainDefinition.domain;\n\n super({\n domain: domainId,\n allDomains: [domainId],\n actionSchema: {},\n } as ROOT_DOM);\n\n this._actionRuntimeManager = new ActionRuntimeManager({ domain: domainId });\n }\n\n createChildDomain<SUB_DOM extends IActionDomainChildOptions>(\n subDomainDef: SUB_DOM & {\n [K in Exclude<keyof SUB_DOM, keyof IActionDomainChildOptions>]: never;\n },\n ): ActionDomain<TActionDomainChildDef<ROOT_DOM, SUB_DOM>> {\n if (this.allDomains.includes(subDomainDef.domain)) {\n throw err_nice_action.fromId(EErrId_NiceAction.domain_already_exists_in_hierarchy, {\n domain: subDomainDef.domain,\n allParentDomains: this.allDomains,\n parentDomain: this.domain,\n });\n }\n\n return new ActionDomain<TActionDomainChildDef<ROOT_DOM, SUB_DOM>>(\n {\n allDomains: [...this.allDomains, subDomainDef.domain],\n domain: subDomainDef.domain,\n actionSchema: subDomainDef.actions,\n },\n { rootDomain: this },\n );\n }\n\n _registerRuntime(runtime: ActionRuntime): void {\n this._actionRuntimeManager.registerRuntime(runtime);\n }\n\n _hasRuntime(runtime: ActionRuntime): boolean {\n return this._actionRuntimeManager.hasRuntime(runtime);\n }\n\n getRuntime(clientSpecifier: IRuntimeCoordinate): ActionRuntime | undefined {\n return this._actionRuntimeManager.getBestRuntimeForSpecifier(clientSpecifier);\n }\n\n async _runAction<\n DOM extends IActionDomain,\n ID extends keyof DOM[\"actionSchema\"] & string = keyof DOM[\"actionSchema\"] & string,\n ACT extends ActionPayload_Request<DOM, ID> = ActionPayload_Request<DOM, ID>,\n >(actionPayload: ACT, options?: IExecuteActionOptions<DOM, ID>): Promise<RunningAction<DOM, ID>> {\n const allListeners = [...this._listeners, ...(options?.listeners ?? [])];\n\n let handlerAndRuntime: IActionHandlerAndRuntime;\n try {\n handlerAndRuntime = this._actionRuntimeManager.getRuntimeAndHandlerForActionOrThrow(\n actionPayload,\n options,\n );\n } catch (err) {\n const runningAction = new RunningAction<DOM, ID>({\n context: actionPayload.context,\n request: actionPayload,\n callSite: actionPayload._callSite,\n });\n runningAction.addUpdateListeners(allListeners);\n runningAction._failWithError(err);\n throw err;\n }\n\n const { handler, runtime } = handlerAndRuntime;\n\n actionPayload.context._setOriginClient(runtime.coordinate);\n\n const runningAction = await handler.handleActionRequest(actionPayload, {\n targetLocalRuntime: runtime,\n });\n\n runningAction.addUpdateListeners(allListeners);\n\n return runningAction;\n }\n}\n","import type { ActionRuntime } from \"../../ActionRuntime/ActionRuntime\";\nimport type { IExecuteActionOptions } from \"../../ActionRuntime/Handler/ActionHandler.types\";\nimport { ActionLocalHandler } from \"../../ActionRuntime/Handler/Local/ActionLocalHandler\";\nimport { RuntimeCoordinate } from \"../../ActionRuntime/RuntimeCoordinate\";\nimport { EErrId_NiceAction, err_nice_action } from \"../../errors/err_nice_action\";\nimport { assertIsActionJson } from \"../../utils/assertIsActionJson\";\nimport { isAction_Any_Instance } from \"../../utils/isAction_Any_Instance\";\nimport type {\n TAction_Any_JsonObject,\n TDistributeActionPayload_Request,\n TDistributeActionPayload_Result,\n TDistributedDomainActions,\n TNarrowActionJsonTypeToActionInstanceType,\n} from \"../Action/Action.combined.types\";\nimport { EActionForm, type IActionBase } from \"../Action/ActionBase.types\";\nimport { ActionContext } from \"../Action/Context/ActionContext\";\nimport type { IActionContext_Data_JsonObject } from \"../Action/Context/ActionContext.types\";\nimport { ActionCore } from \"../Action/Core/ActionCore\";\nimport {\n EActionPayloadType,\n type IActionPayload_Request_JsonObject,\n type IActionPayload_Result_JsonObject,\n} from \"../Action/Payload/ActionPayload.types\";\nimport { ActionPayload_Request } from \"../Action/Payload/ActionPayload_Request\";\nimport { ActionPayload_Result } from \"../Action/Payload/ActionPayload_Result\";\nimport type { RunningAction } from \"../Action/RunningAction\";\nimport type { TRunningActionUpdateListener } from \"../Action/RunningAction.types\";\nimport type {\n IActionDomain,\n IActionDomainChildOptions,\n TActionDomainChildDef,\n TWrappableDomainActionHandler,\n} from \"./ActionDomain.types\";\nimport { ActionDomainBase } from \"./ActionDomainBase\";\nimport { type ActionRootDomain } from \"./ActionRootDomain\";\n\ntype TActionMap<ACT_DOM extends IActionDomain> = {\n [K in keyof ACT_DOM[\"actionSchema\"] & string]: ActionCore<ACT_DOM, K>;\n};\n\nexport class ActionDomain<\n ACT_DOM extends IActionDomain = IActionDomain,\n> extends ActionDomainBase<ACT_DOM> {\n private _rootDomain: ActionRootDomain<any>;\n private readonly _actionMap: TActionMap<ACT_DOM>;\n\n constructor(\n definition: ACT_DOM,\n {\n rootDomain,\n }: {\n rootDomain: ActionRootDomain<any>;\n },\n ) {\n super(definition);\n this._rootDomain = rootDomain;\n this._actionMap = this.createActionMap();\n }\n\n get rootDomain() {\n return this._rootDomain;\n }\n\n /**\n * @internal\n * All action observers that should see actions on this domain: the root domain's\n * observers plus this subdomain's own. Mirrors the listener set the local-dispatch\n * path assembles in `runAction`/`_runAction`, so inbound actions (pushed from a\n * backend or another client) can be wired up identically and surface in devtools.\n */\n _collectActionObservers(): TRunningActionUpdateListener<any, any>[] {\n return [...this._rootDomain._getActionObservers(), ...this._getActionObservers()];\n }\n\n _registerRuntime(runtime: ActionRuntime): void {\n this._rootDomain._registerRuntime(runtime);\n }\n\n createChildDomain<SUB_DOM extends IActionDomainChildOptions>(\n subDomainDef: SUB_DOM & {\n [K in Exclude<keyof SUB_DOM, keyof IActionDomainChildOptions>]: never;\n },\n ): ActionDomain<TActionDomainChildDef<ACT_DOM, SUB_DOM>> {\n if (this.allDomains.includes(subDomainDef.domain)) {\n throw err_nice_action.fromId(EErrId_NiceAction.domain_already_exists_in_hierarchy, {\n domain: subDomainDef.domain,\n allParentDomains: this.allDomains,\n parentDomain: this.domain,\n });\n }\n\n return new ActionDomain<TActionDomainChildDef<ACT_DOM, SUB_DOM>>(\n {\n allDomains: [...this.allDomains, subDomainDef.domain],\n domain: subDomainDef.domain,\n actionSchema: subDomainDef.actions,\n },\n { rootDomain: this._rootDomain },\n );\n }\n\n get action(): TActionMap<ACT_DOM> {\n return this._actionMap;\n }\n\n actionsMap(): TActionMap<ACT_DOM> {\n return this._actionMap;\n }\n\n actionForId<ID extends keyof ACT_DOM[\"actionSchema\"] & string>(id: ID): ActionCore<ACT_DOM, ID> {\n const actionSchema = this.actionSchema[id];\n if (!actionSchema) {\n throw err_nice_action.fromId(EErrId_NiceAction.action_id_not_in_domain, {\n domain: this.domain,\n actionId: id as string,\n });\n }\n\n return new ActionCore<ACT_DOM, ID>(this, id);\n }\n\n wrapAsPartialLocalHandler(\n wrappedActionExecutor: Partial<TWrappableDomainActionHandler<ACT_DOM>>,\n ): ActionLocalHandler {\n const _handler = new ActionLocalHandler();\n const executor = wrappedActionExecutor as unknown as Record<string, (input: any) => any>;\n\n for (const actionKey in wrappedActionExecutor) {\n if (!this.actionSchema[actionKey]) {\n continue;\n }\n\n _handler.forAction(this.actionForId(actionKey), (request) =>\n executor[request.id](request.input),\n );\n }\n\n return _handler;\n }\n\n wrapAsLocalHandler(\n wrappedActionExecutor: TWrappableDomainActionHandler<ACT_DOM>,\n ): ActionLocalHandler {\n const _handler = new ActionLocalHandler();\n const executor = wrappedActionExecutor as unknown as Record<string, (input: any) => any>;\n return _handler.forDomain(this, (request) => executor[request.id](request.input));\n }\n\n hydrateContext<ID extends keyof ACT_DOM[\"actionSchema\"] & string>(\n id: ID,\n contextData: IActionContext_Data_JsonObject,\n ): ActionContext<ACT_DOM, ID> {\n return new ActionContext(this, id, {\n timeCreated: contextData.timeCreated,\n cuid: contextData.cuid,\n routing: contextData.routing.map((item) => {\n return {\n runtime: new RuntimeCoordinate(item.runtime),\n handler: item.handler,\n time: item.time,\n };\n }),\n originClient: contextData.originClient\n ? new RuntimeCoordinate(contextData.originClient)\n : RuntimeCoordinate.unknown,\n });\n }\n\n isDomainAction<ACT extends IActionBase<any, ACT_DOM, any>>(\n action: ACT | unknown | null | undefined,\n ): action is TDistributedDomainActions<ACT_DOM, ACT> {\n return isAction_Any_Instance(action) && action.domain === this.domain;\n }\n\n hydrateRequestPayload<\n ID extends keyof ACT_DOM[\"actionSchema\"] & string,\n P extends IActionPayload_Request_JsonObject<ACT_DOM, ID>,\n >(serialized: P): TDistributeActionPayload_Request<ACT_DOM, ID> {\n if (serialized.type !== EActionPayloadType.request) {\n throw err_nice_action.fromId(EErrId_NiceAction.hydration_action_state_mismatch, {\n expected: EActionPayloadType.request,\n received: serialized.type,\n });\n }\n\n if (serialized.domain !== this.domain) {\n throw err_nice_action.fromId(EErrId_NiceAction.hydration_domain_mismatch, {\n expected: this.domain,\n received: serialized.domain,\n });\n }\n\n const id = serialized.id;\n if (!this.actionSchema[id]) {\n throw err_nice_action.fromId(EErrId_NiceAction.hydration_action_id_not_found, {\n domain: this.domain,\n actionId: serialized.id,\n });\n }\n\n const contextAction = this.hydrateContext(id, serialized.context);\n\n return new ActionPayload_Request(\n { context: contextAction },\n contextAction.deserializeInput(serialized.input),\n {\n time: serialized.time,\n },\n ) as TDistributeActionPayload_Request<ACT_DOM, ID>;\n }\n\n hydrateResultPayload<\n ID extends keyof ACT_DOM[\"actionSchema\"] & string,\n R extends IActionPayload_Result_JsonObject<ACT_DOM, ID>,\n >(serialized: R): TDistributeActionPayload_Result<ACT_DOM, ID> {\n if (serialized.type !== EActionPayloadType.result) {\n throw err_nice_action.fromId(EErrId_NiceAction.hydration_action_state_mismatch, {\n expected: EActionPayloadType.result,\n received: serialized.type,\n });\n }\n\n if (serialized.domain !== this.domain) {\n throw err_nice_action.fromId(EErrId_NiceAction.hydration_domain_mismatch, {\n expected: this.domain,\n received: serialized.domain,\n });\n }\n\n const id = serialized.id;\n\n if (!this.actionSchema[id]) {\n throw err_nice_action.fromId(EErrId_NiceAction.hydration_action_id_not_found, {\n domain: this.domain,\n actionId: serialized.id,\n });\n }\n\n const contextAction = this.hydrateContext(id, serialized.context);\n\n const result = serialized.result.ok\n ? {\n ok: true as const,\n output: contextAction.schema.deserializeOutput(serialized.result.output),\n }\n : serialized.result;\n\n return new ActionPayload_Result({ context: contextAction }, result, {\n time: serialized.time,\n }) as TDistributeActionPayload_Result<ACT_DOM, ID>;\n }\n\n hydrateAnyAction<\n ID extends keyof ACT_DOM[\"actionSchema\"] & string,\n AJ extends TAction_Any_JsonObject<ACT_DOM, ID>,\n >(actionJson: AJ): TNarrowActionJsonTypeToActionInstanceType<ACT_DOM, AJ, ID> {\n assertIsActionJson(actionJson);\n\n if (actionJson.form === EActionForm.data) {\n if (actionJson.type === EActionPayloadType.request) {\n return this.hydrateRequestPayload(\n actionJson,\n ) as unknown as TNarrowActionJsonTypeToActionInstanceType<ACT_DOM, AJ, ID>;\n }\n\n if (actionJson.type === EActionPayloadType.result) {\n return this.hydrateResultPayload(\n actionJson,\n ) as unknown as TNarrowActionJsonTypeToActionInstanceType<ACT_DOM, AJ, ID>;\n }\n }\n\n return this.actionForId(actionJson.id) as TNarrowActionJsonTypeToActionInstanceType<\n ACT_DOM,\n AJ,\n ID\n >;\n }\n\n async runAction<\n ID extends keyof ACT_DOM[\"actionSchema\"] & string,\n ACT extends ActionPayload_Request<ACT_DOM, ID>,\n >(\n request: ACT,\n options?: IExecuteActionOptions<ACT_DOM, ID>,\n ): Promise<RunningAction<ACT_DOM, ID>> {\n const allListeners: TRunningActionUpdateListener<any, any>[] = [\n ...(options?.listeners ?? []),\n ...this._listeners,\n ];\n\n return this._rootDomain._runAction(request, {\n ...options,\n listeners: allListeners,\n });\n }\n\n private createActionMap(): {\n [K in keyof ACT_DOM[\"actionSchema\"] & string]: ActionCore<ACT_DOM, K>;\n } {\n const map = {} as {\n [K in keyof ACT_DOM[\"actionSchema\"] & string]: ActionCore<ACT_DOM, K>;\n };\n\n for (const id in this.actionSchema) {\n map[id] = new ActionCore(this, id);\n }\n\n return map;\n }\n}\n","import type { IActionRootDomain } from \"../ActionDomain.types\";\nimport { ActionRootDomain } from \"../ActionRootDomain\";\n\nexport const createActionRootDomain = <ID extends string>(definition: {\n domain: ID;\n}): ActionRootDomain<IActionRootDomain<ID>> => {\n return new ActionRootDomain<IActionRootDomain<ID>>(definition);\n};\n","import { EActionForm } from \"../../../ActionDefinition/Action/ActionBase.types\";\r\nimport type { IActionContext_Data_JsonObject } from \"../../../ActionDefinition/Action/Context/ActionContext.types\";\r\nimport {\r\n EActionPayloadType,\r\n type IActionPayload_Base_JsonObject,\r\n type TActionPayload_Any_JsonObject,\r\n} from \"../../../ActionDefinition/Action/Payload/ActionPayload.types\";\r\nimport type { ActionDomain } from \"../../../ActionDefinition/Domain/ActionDomain\";\r\nimport type { TPossibleDomainIdList } from \"../../../ActionDefinition/Domain/ActionDomain.types\";\r\nimport type { ITransportRouteActionParams } from \"../Transport.types\";\r\n\r\n/**\r\n * Shared building blocks for the binary action codecs (the stateless {@link createBinaryWireAdapter} and\r\n * the per-connection `createBinaryWireSessionFactory`). Both map a `domain:id` route to a tiny integer\r\n * and reduce the verbose JSON wire to a positional tuple — they only differ in how much context they\r\n * carry per frame, so the dictionary + payload (de)assembly live here.\r\n */\r\n\r\n/**\r\n * The carrier-neutral codec a Link connection uses to (de)serialize action payloads on the wire — the\r\n * same shape every duplex carrier (WS/WebRTC/in-memory) shares.\r\n */\r\nexport interface IActionWireFormat {\r\n /**\r\n * Pack an outgoing action payload. Return a `string` for text frames (JSON) or a binary\r\n * `Uint8Array`/`ArrayBuffer` for optimized binary frames (e.g. msgpackr).\r\n */\r\n outgoing: (input: ITransportRouteActionParams) => string | Uint8Array | ArrayBuffer;\r\n /**\r\n * Unpack an incoming frame back into the wire JSON object the runtime hydrates + validates. Return\r\n * `undefined` to defer to the connection's built-in JSON parser — this is how binary adapters stay\r\n * backward compatible with plain-JSON clients on the same socket.\r\n */\r\n incoming?: (\r\n input: string | ArrayBuffer | Uint8Array | Blob,\r\n ) => TActionPayload_Any_JsonObject<any, any> | undefined;\r\n}\r\n\r\n/**\r\n * Tiny integer codes for the payload type, so the verbose `\"request\"`/`\"result\"`/`\"progress\"`\r\n * strings never hit the wire. The index in {@link ReversePayloadType} must line up with the value.\r\n */\r\nexport const PayloadTypeToInt: Record<\r\n EActionPayloadType.request | EActionPayloadType.result | EActionPayloadType.progress,\r\n number\r\n> = {\r\n [EActionPayloadType.request]: 0,\r\n [EActionPayloadType.result]: 1,\r\n [EActionPayloadType.progress]: 2,\r\n};\r\nexport const ReversePayloadType = [\r\n EActionPayloadType.request,\r\n EActionPayloadType.result,\r\n EActionPayloadType.progress,\r\n] as const;\r\n\r\nexport interface IActionRouteMeta {\r\n domain: string;\r\n id: string;\r\n allDomains: TPossibleDomainIdList;\r\n}\r\n\r\nexport interface IActionRouteDictionary {\r\n /** `domain:id` → wire integer. */\r\n routeToInt: Map<string, number>;\r\n /** wire integer → route metadata for reconstruction. */\r\n intToRoute: IActionRouteMeta[];\r\n}\r\n\r\n/**\r\n * Build the positional `domain:id` ↔ integer dictionary. Both ends of a channel MUST build it from\r\n * the same domains in the same order — the mapping is positional, so a mismatch routes to the wrong\r\n * action. Add new transported domains to the end of the list.\r\n */\r\nexport function buildActionRouteDictionary(domains: ActionDomain<any>[]): IActionRouteDictionary {\r\n const routeToInt = new Map<string, number>();\r\n const intToRoute: IActionRouteMeta[] = [];\r\n\r\n for (const dom of domains) {\r\n for (const actionId of Object.keys(dom.actionSchema)) {\r\n const routeKey = `${dom.domain}:${actionId}`;\r\n if (routeToInt.has(routeKey)) continue;\r\n routeToInt.set(routeKey, intToRoute.length);\r\n intToRoute.push({ domain: dom.domain, id: actionId, allDomains: dom.allDomains });\r\n }\r\n }\r\n\r\n return { routeToInt, intToRoute };\r\n}\r\n\r\n/** Pull the type-specific payload (`input` / `result` / `progress`) out of a wire JSON object. */\r\nexport function extractWirePayload(json: TActionPayload_Any_JsonObject<any, any>): unknown {\r\n if (json.type === EActionPayloadType.request) return json.input;\r\n if (json.type === EActionPayloadType.result) return json.result;\r\n if (json.type === EActionPayloadType.progress) return json.progress;\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Reassemble a full wire JSON object from its decoded parts. `inputHash`/`outputHash` are emitted\r\n * empty — the hydration constructors recompute them — and the result still satisfies\r\n * `isActionPayload_Any_JsonObject` so it flows through validation like a JSON frame.\r\n */\r\nexport function assembleWireJson(\r\n routeMeta: IActionRouteMeta,\r\n payloadType: (typeof ReversePayloadType)[number],\r\n time: number,\r\n context: IActionContext_Data_JsonObject,\r\n // Runtime-dynamic payload straight off the wire (msgpack/JSON) — Valibot validates it on hydrate.\r\n payloadData: any,\r\n): TActionPayload_Any_JsonObject<any, any> {\r\n const base: Omit<IActionPayload_Base_JsonObject<EActionPayloadType>, \"type\"> = {\r\n form: EActionForm.data,\r\n domain: routeMeta.domain,\r\n id: routeMeta.id,\r\n allDomains: routeMeta.allDomains,\r\n time,\r\n context,\r\n };\r\n\r\n if (payloadType === EActionPayloadType.request) {\r\n return { ...base, type: EActionPayloadType.request, input: payloadData, inputHash: \"\" };\r\n }\r\n if (payloadType === EActionPayloadType.result) {\r\n return { ...base, type: EActionPayloadType.result, result: payloadData, outputHash: \"\" };\r\n }\r\n return { ...base, type: EActionPayloadType.progress, progress: payloadData };\r\n}\r\n","import { pack, unpack } from \"msgpackr\";\r\nimport { nanoid } from \"nanoid\";\r\nimport { EActionPayloadType } from \"../../../ActionDefinition/Action/Payload/ActionPayload.types\";\r\nimport type { ActionDomain } from \"../../../ActionDefinition/Domain/ActionDomain\";\r\nimport { UNSET_RUNTIME_ENV_ID } from \"../../../nice_action.static\";\r\nimport { type IRuntimeCoordinate, RuntimeCoordinate } from \"../../RuntimeCoordinate\";\r\nimport type { ITransportRouteActionParams } from \"../Transport.types\";\r\nimport {\r\n assembleWireJson,\r\n buildActionRouteDictionary,\r\n extractWirePayload,\r\n type IActionWireFormat,\r\n PayloadTypeToInt,\r\n ReversePayloadType,\r\n} from \"./actionWireCodec\";\r\n\r\n/**\r\n * Positional layout of the *session* binary envelope — the leanest frame. Compared to the stateless\r\n * adapter it replaces the 21-char `cuid` with a small per-connection integer and only carries\r\n * `originClient` on the very first request of each direction (the peer remembers it afterwards).\r\n *\r\n * [ routeInt, typeInt, corrId, time, originClient?, payloadData ]\r\n */\r\nconst ENVELOPE = {\r\n route: 0,\r\n type: 1,\r\n corr: 2,\r\n time: 3,\r\n originClient: 4,\r\n payload: 5,\r\n} as const;\r\nconst ENVELOPE_LENGTH = 6;\r\n\r\n/**\r\n * How long a pending correlation entry is kept before it's swept. A correlation only matters until its\r\n * action resolves or times out, so anything older than the longest realistic action timeout can be\r\n * dropped — this bounds memory when requests time out or a connection dies mid-flight (their replies\r\n * would never arrive, leaving the entry orphaned). Generous default so live correlations are never\r\n * pruned (the default transport timeout is 10s).\r\n */\r\nconst DEFAULT_CORRELATION_TTL_MS = 5 * 60_000;\r\n\r\ntype TFormatMessage = IActionWireFormat;\r\n\r\ninterface IPendingCorrelation<V> {\r\n value: V;\r\n /** Insertion time (ms), used to expire orphaned entries. */\r\n time: number;\r\n}\r\n\r\nexport interface IBinaryWireSessionOptions {\r\n /** Override how long an unresolved correlation is retained before being swept (ms). */\r\n correlationTtlMs?: number;\r\n}\r\n\r\nfunction isKnownIdentity(\r\n coordinate: IRuntimeCoordinate | null | undefined,\r\n): coordinate is IRuntimeCoordinate {\r\n return coordinate != null && coordinate.envId !== UNSET_RUNTIME_ENV_ID;\r\n}\r\n\r\n/**\r\n * Drop entries older than `ttlMs`. Maps keep insertion order and entries are inserted in time order,\r\n * so the oldest are first — stop sweeping at the first live entry.\r\n */\r\nfunction pruneExpired<K, V>(map: Map<K, IPendingCorrelation<V>>, now: number, ttlMs: number): void {\r\n for (const [key, entry] of map) {\r\n if (now - entry.time <= ttlMs) break;\r\n map.delete(key);\r\n }\r\n}\r\n\r\n/**\r\n * Builds a factory of *stateful, per-connection* codecs for {@link LinkTransport} /\r\n * `AcceptorHandler` — the maximally compact binary wire. Call the returned factory once per live\r\n * connection (each socket on the client, each accepted connection on the server) so every channel\r\n * gets its own correlation + identity state.\r\n *\r\n * On top of everything {@link createBinaryWireAdapter} drops, a session also drops:\r\n * - **`cuid`** — replaced by a per-connection integer correlation id. The initiator maps it to its\r\n * real cuid; the responder echoes it; each side reconstructs the cuid from its own map. Correlation\r\n * only needs to be unique per socket, so a counter suffices.\r\n * - **`originClient` after the first request** — the first request each side sends carries its\r\n * identity; the peer remembers it and injects it into later frames. Replies omit it entirely (a\r\n * reply carries the initiator's own origin, which the initiator already knows).\r\n *\r\n * Both ends MUST build the factory from the same domains in the same order (positional dictionary).\r\n * Text frames still return `undefined` from `incoming`, so JSON clients remain interoperable.\r\n *\r\n * Hibernation note: after a server connection is evicted its session resets, so a still-connected\r\n * client (whose session persists) will keep omitting `originClient`. The server must therefore restore\r\n * the connection→client binding from its own store (see `AcceptorHandler.rehydrateConnection`) and\r\n * inject `originClient` from there — the session alone can't recover it.\r\n */\r\nexport function createBinaryWireSessionFactory(\r\n domains: ActionDomain<any>[],\r\n options?: IBinaryWireSessionOptions,\r\n): () => TFormatMessage {\r\n const { routeToInt, intToRoute } = buildActionRouteDictionary(domains);\r\n const unknownIdentity = RuntimeCoordinate.unknown.toJsonObject();\r\n const ttlMs = options?.correlationTtlMs ?? DEFAULT_CORRELATION_TTL_MS;\r\n\r\n return (): TFormatMessage => {\r\n let outCounter = 0;\r\n // Requests this side initiated: correlation id → our cuid (to resolve the eventual reply).\r\n const corrToCuid = new Map<number, IPendingCorrelation<string>>();\r\n // Requests this side is responding to: our (synthesized) cuid → the correlation id to echo back.\r\n const cuidToCorr = new Map<string, IPendingCorrelation<number>>();\r\n let selfIdentity: IRuntimeCoordinate | undefined;\r\n let peerIdentity: IRuntimeCoordinate | undefined;\r\n\r\n return {\r\n outgoing: (input: ITransportRouteActionParams): Uint8Array => {\r\n const json = input.action.toJsonObject();\r\n const routeKey = `${json.domain}:${json.id}`;\r\n const routeInt = routeToInt.get(routeKey);\r\n if (routeInt == null) {\r\n throw new Error(`[binary-wire] Cannot pack unregistered action route: ${routeKey}`);\r\n }\r\n\r\n const now = Date.now();\r\n pruneExpired(corrToCuid, now, ttlMs);\r\n pruneExpired(cuidToCorr, now, ttlMs);\r\n\r\n let corr: number;\r\n let wireIdentity: IRuntimeCoordinate | undefined;\r\n\r\n if (json.type === EActionPayloadType.request) {\r\n // Initiator: assign a fresh per-connection correlation id, remember our cuid for the reply.\r\n corr = outCounter++;\r\n corrToCuid.set(corr, { value: json.context.cuid, time: now });\r\n\r\n // Send our identity only on the first request — the peer remembers it from then on.\r\n if (selfIdentity == null && isKnownIdentity(json.context.originClient)) {\r\n selfIdentity = json.context.originClient;\r\n wireIdentity = json.context.originClient;\r\n }\r\n } else {\r\n // Responder: echo the correlation id the request arrived with.\r\n corr = cuidToCorr.get(json.context.cuid)?.value ?? -1;\r\n if (json.type === EActionPayloadType.result) cuidToCorr.delete(json.context.cuid);\r\n }\r\n\r\n const envelope = new Array(ENVELOPE_LENGTH);\r\n envelope[ENVELOPE.route] = routeInt;\r\n envelope[ENVELOPE.type] = PayloadTypeToInt[json.type];\r\n envelope[ENVELOPE.corr] = corr;\r\n envelope[ENVELOPE.time] = json.time;\r\n envelope[ENVELOPE.originClient] = wireIdentity; // undefined except the first request\r\n envelope[ENVELOPE.payload] = extractWirePayload(json);\r\n\r\n return pack(envelope);\r\n },\r\n\r\n incoming: (frame: string | ArrayBuffer | Uint8Array | Blob) => {\r\n let buffer: Uint8Array;\r\n if (frame instanceof ArrayBuffer) {\r\n buffer = new Uint8Array(frame);\r\n } else if (frame instanceof Uint8Array) {\r\n buffer = frame;\r\n } else {\r\n return undefined;\r\n }\r\n\r\n try {\r\n const envelope = unpack(buffer);\r\n if (!Array.isArray(envelope) || envelope.length !== ENVELOPE_LENGTH) return undefined;\r\n\r\n const routeMeta = intToRoute[envelope[ENVELOPE.route]];\r\n const payloadType = ReversePayloadType[envelope[ENVELOPE.type]];\r\n if (routeMeta == null || payloadType == null) return undefined;\r\n\r\n const now = Date.now();\r\n pruneExpired(corrToCuid, now, ttlMs);\r\n pruneExpired(cuidToCorr, now, ttlMs);\r\n\r\n const corr: number = envelope[ENVELOPE.corr];\r\n const time: number = envelope[ENVELOPE.time];\r\n const wireIdentity: IRuntimeCoordinate | undefined = envelope[ENVELOPE.originClient];\r\n\r\n let cuid: string;\r\n let originClient: IRuntimeCoordinate;\r\n\r\n if (payloadType === EActionPayloadType.request) {\r\n // Incoming request: synthesize a local cuid, remember the correlation for our reply.\r\n cuid = nanoid();\r\n cuidToCorr.set(cuid, { value: corr, time: now });\r\n\r\n if (isKnownIdentity(wireIdentity)) peerIdentity = wireIdentity;\r\n originClient = peerIdentity ?? unknownIdentity;\r\n } else {\r\n // Incoming reply: map the correlation id back to the cuid of the request we initiated.\r\n cuid = corrToCuid.get(corr)?.value ?? nanoid();\r\n if (payloadType === EActionPayloadType.result) corrToCuid.delete(corr);\r\n // A reply carries our own origin (the request originated on this side).\r\n originClient = selfIdentity ?? unknownIdentity;\r\n }\r\n\r\n const context = { cuid, timeCreated: time, routing: [], originClient };\r\n return assembleWireJson(\r\n routeMeta,\r\n payloadType,\r\n time,\r\n context,\r\n envelope[ENVELOPE.payload],\r\n );\r\n } catch (e) {\r\n console.error(\"[binary-wire] Failed to unpack binary action session frame\", e);\r\n return undefined;\r\n }\r\n },\r\n };\r\n };\r\n}\r\n","import type { ActionDomain } from \"../../ActionDefinition/Domain/ActionDomain\";\r\nimport {\r\n buildActionRouteDictionary,\r\n type IActionWireFormat,\r\n} from \"../Transport/codec/actionWireCodec\";\r\nimport {\r\n createBinaryWireSessionFactory,\r\n type IBinaryWireSessionOptions,\r\n} from \"../Transport/codec/createBinaryWireSessionFactory\";\r\nimport { defineChannel, type IActionChannel } from \"./ActionChannel\";\r\n\r\n/** The per-connection binary session codec — built once per socket from the channel's domains. */\r\ntype TChannelCodec = IActionWireFormat;\r\n\r\n/**\r\n * The shared identity of a secure channel (carrier-agnostic — WS, WebRTC, HTTP, …): the wire\r\n * dictionary version both ends check during the handshake, plus the per-connection codec factory both\r\n * ends build from the *same* domain list. Define it once (typically in code shared by both peers) and\r\n * hand it to `secureTransport` on the connector and `serveChannel` (or the lower-level `acceptChannel` /\r\n * `createSecureAcceptorHandler`) on the acceptor, so the codec and version can never drift apart.\r\n */\r\nexport interface ISecureChannel<\r\n TO_ACCEPTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[],\r\n TO_CONNECTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[],\r\n> extends IActionChannel<TO_ACCEPTOR, TO_CONNECTOR> {\r\n /** Wire dictionary version — derived from the domains by default; the handshake rejects a mismatch. */\r\n dictionaryVersion: string;\r\n /** Per-connection session codec factory (call once per live connection). */\r\n createCodec: () => TChannelCodec;\r\n}\r\n\r\n/**\r\n * Derive a stable wire-dictionary version from the ordered route list (FNV-1a over `domain:id,…`), so\r\n * the version moves automatically whenever the transported domains change — a stale peer is then\r\n * rejected by the handshake instead of silently misrouting a positionally-packed frame.\r\n */\r\nfunction deriveDictionaryVersion(domains: ActionDomain<any>[]): string {\r\n const { intToRoute } = buildActionRouteDictionary(domains);\r\n const signature = intToRoute.map((route) => `${route.domain}:${route.id}`).join(\",\");\r\n\r\n let hash = 0x811c9dc5;\r\n for (let i = 0; i < signature.length; i++) {\r\n hash ^= signature.charCodeAt(i);\r\n hash = Math.imul(hash, 0x01000193);\r\n }\r\n return `auto:${(hash >>> 0).toString(16).padStart(8, \"0\")}`;\r\n}\r\n\r\n/**\r\n * Bundle a secure channel's shared identity from its transported domains. Both ends MUST call this\r\n * with the same domains in the same order (the binary wire dictionary is positional). The\r\n * `dictionaryVersion` is derived from those domains unless you pin an explicit one.\r\n *\r\n * Declare the domains *by role* — `toAcceptor` (connector→acceptor requests) and `toConnector`\r\n * (acceptor→connector pushes) — so the routing for both ends is derived from the channel (see\r\n * {@link connectChannel} and `acceptChannelConnections`) instead of being restated at each end. The\r\n * wire dictionary spans `[...toAcceptor, ...toConnector]` in that order; add new domains to the end of\r\n * their list to keep older peers compatible. (`domains` is still accepted as a legacy alias for\r\n * `toAcceptor`.)\r\n */\r\nexport function defineSecureChannel<\r\n const TO_ACCEPTOR extends readonly ActionDomain<any>[] = [],\r\n const TO_CONNECTOR extends readonly ActionDomain<any>[] = [],\r\n>(options: {\r\n /** Domains the connector sends to the acceptor (connector→acceptor requests), in a stable order. */\r\n toAcceptor: TO_ACCEPTOR;\r\n /** Domains the acceptor pushes to the connector (acceptor→connector), in a stable order. */\r\n toConnector: TO_CONNECTOR;\r\n /** Pin a human-readable version instead of the derived hash (must match on both ends). */\r\n dictionaryVersion?: string;\r\n /** Tuning for the per-connection binary session (e.g. correlation TTL). */\r\n sessionOptions?: IBinaryWireSessionOptions;\r\n}): ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR> {\r\n // The routing half (role) is just a plain channel; this adds the WS binary wire identity on top.\r\n const base = defineChannel<TO_ACCEPTOR, TO_CONNECTOR>({\r\n toAcceptor: options.toAcceptor,\r\n toConnector: options.toConnector,\r\n });\r\n // Dictionary order is positional and must match on both ends: connector→acceptor routes first, then\r\n // acceptor→connector pushes. (`domains` already covers the legacy single-list case via toAcceptorDomains.)\r\n const allDomains: ActionDomain<any>[] = [...base.toAcceptorDomains, ...base.toConnectorDomains];\r\n\r\n return {\r\n ...base,\r\n dictionaryVersion: options.dictionaryVersion ?? deriveDictionaryVersion(allDomains),\r\n createCodec: createBinaryWireSessionFactory(allDomains, options.sessionOptions),\r\n };\r\n}\r\n\r\n// The secure WS transport is now built via `secureTransport({ carrier: wsCarrier(url) })` — this file\r\n// only defines the carrier-neutral channel identity (`defineSecureChannel` / `ISecureChannel`).\r\n","import type { IDuplexCarrier } from \"../../Carrier.types\";\r\n\r\ntype TFrame = string | ArrayBuffer | Uint8Array;\r\n\r\n/** The peer (server) end of an in-memory pair — what you feed into an `AcceptorHandler`. */\r\nexport interface IInMemoryServerEndpoint {\r\n /** Write a frame back to the client end. */\r\n send(frame: TFrame): void;\r\n /** Register the inbound handler (frames the client sent). */\r\n onMessage(handler: (frame: TFrame) => void): void;\r\n /** Close the pair from this end. */\r\n close(): void;\r\n /** Notified when the pair closes (from either end). */\r\n onClose(handler: () => void): void;\r\n}\r\n\r\nexport interface IInMemoryChannelPair {\r\n /** The client end — pass as a {@link IDuplexCarrier} to a `LinkTransport`. */\r\n clientChannel: IDuplexCarrier;\r\n /** The server end — wire into an `AcceptorHandler` (`send` + `receive`). */\r\n serverEndpoint: IInMemoryServerEndpoint;\r\n}\r\n\r\n/**\r\n * Two cross-wired in-process byte channels — a loopback carrier with no socket. The client end is a\r\n * {@link IDuplexCarrier} you hand to a {@link LinkTransport}; the server end plugs into an\r\n * `AcceptorHandler` (`send: (_, f) => serverEndpoint.send(f)`, and `serverEndpoint.onMessage(f =>\r\n * handler.receive(conn, f))`). Frames are delivered on a microtask, so each side observes the other\r\n * asynchronously — exactly like a real transport — which makes this ideal for tests and for running\r\n * two runtimes in one process (or proving a non-WS carrier end to end).\r\n */\r\nexport function createInMemoryChannelPair(): IInMemoryChannelPair {\r\n let clientMessage: ((frame: TFrame) => void) | undefined;\r\n let clientClose: (() => void) | undefined;\r\n let serverMessage: ((frame: TFrame) => void) | undefined;\r\n let serverClose: (() => void) | undefined;\r\n let open = true;\r\n\r\n const closeBoth = (): void => {\r\n if (!open) return;\r\n open = false;\r\n queueMicrotask(() => {\r\n clientClose?.();\r\n serverClose?.();\r\n });\r\n };\r\n\r\n const clientChannel: IDuplexCarrier = {\r\n ready: Promise.resolve(),\r\n isOpen: () => open,\r\n send: (frame) => {\r\n if (!open) return;\r\n queueMicrotask(() => serverMessage?.(frame));\r\n },\r\n attach: ({ onMessage, onClose }) => {\r\n clientMessage = onMessage;\r\n clientClose = onClose;\r\n },\r\n close: closeBoth,\r\n label: \"in-memory\",\r\n };\r\n\r\n const serverEndpoint: IInMemoryServerEndpoint = {\r\n send: (frame) => {\r\n if (!open) return;\r\n queueMicrotask(() => clientMessage?.(frame));\r\n },\r\n onMessage: (handler) => {\r\n serverMessage = handler;\r\n },\r\n onClose: (handler) => {\r\n serverClose = handler;\r\n },\r\n close: closeBoth,\r\n };\r\n\r\n return { clientChannel, serverEndpoint };\r\n}\r\n","import {\r\n createInMemoryChannelPair,\r\n type IInMemoryServerEndpoint,\r\n} from \"./createInMemoryChannel\";\r\nimport type { IDuplexCarrierSource } from \"../../Carrier.types\";\r\n\r\nexport interface IInMemoryCarrier {\r\n /** The connector end — pass as the `carrier` to {@link secureTransport} / `LinkTransport`. */\r\n carrier: IDuplexCarrierSource;\r\n /** The acceptor end — wire into an `AcceptorHandler` (`send` + `receive`). */\r\n serverEndpoint: IInMemoryServerEndpoint;\r\n}\r\n\r\n/**\r\n * A loopback duplex carrier with no socket — two cross-wired in-process ends. The connector end is an\r\n * {@link IDuplexCarrierSource} for {@link secureTransport}; the acceptor end plugs into an\r\n * `AcceptorHandler`. Ideal for tests and for running two runtimes in one process, or proving a\r\n * non-WS carrier end to end.\r\n */\r\nexport function inMemoryCarrier(): IInMemoryCarrier {\r\n const { clientChannel, serverEndpoint } = createInMemoryChannelPair();\r\n return {\r\n carrier: {\r\n carrierLabel: \"memory\",\r\n open: () => clientChannel,\r\n getCacheKey: () => [\"memory\"],\r\n },\r\n serverEndpoint,\r\n };\r\n}\r\n","import type { IDuplexCarrier } from \"../../Carrier.types\";\r\n\r\n/**\r\n * The slice of the `RTCDataChannel` surface this adapter uses — declared structurally so it accepts the\r\n * browser `RTCDataChannel`, React-Native (`react-native-webrtc`), or any node-webrtc shim without a hard\r\n * dependency on a specific DOM/RN type. A real `RTCDataChannel` satisfies it as-is.\r\n */\r\nexport interface IRtcDataChannelLike {\r\n readyState: string; // \"connecting\" | \"open\" | \"closing\" | \"closed\"\r\n binaryType: string;\r\n label?: string;\r\n send(data: string | ArrayBuffer | ArrayBufferView): void;\r\n close(): void;\r\n addEventListener(type: string, listener: (event: any) => void, options?: unknown): void;\r\n}\r\n\r\n/**\r\n * Adapt a WebRTC `RTCDataChannel` to the carrier-agnostic {@link IDuplexCarrier}, so two browsers\r\n * (or two mobile apps) linked peer-to-peer — no server in the middle — run the *same* secure session as\r\n * a WebSocket. Hand it to `createSecureLinkTransport({ openChannel: () => rtcDataChannelByteChannel(dc) })`.\r\n *\r\n * The data channel must already be created (its negotiation/signaling is the app's concern); this only\r\n * drives bytes over it. Binary frames are requested as `ArrayBuffer` so the binary session codec unpacks\r\n * them synchronously; a `Blob` (if the channel hands one back) is normalized to a buffer.\r\n */\r\nexport function rtcDataChannelByteChannel(dc: IRtcDataChannelLike): IDuplexCarrier {\r\n dc.binaryType = \"arraybuffer\";\r\n\r\n let intentional = false;\r\n let onMessage: ((frame: string | ArrayBuffer | Uint8Array) => void) | undefined;\r\n let onClose: (() => void) | undefined;\r\n const preAttach: (string | ArrayBuffer | Uint8Array)[] = [];\r\n\r\n const deliver = (frame: string | ArrayBuffer | Uint8Array): void => {\r\n if (onMessage != null) onMessage(frame);\r\n else preAttach.push(frame);\r\n };\r\n\r\n dc.addEventListener(\"message\", async (event: { data: unknown }) => {\r\n const frame = await normalizeFrame(event.data);\r\n if (frame !== undefined) deliver(frame);\r\n });\r\n dc.addEventListener(\"close\", () => {\r\n if (!intentional) console.error(\"RTCDataChannel closed\");\r\n onClose?.();\r\n });\r\n dc.addEventListener(\"error\", (event: unknown) => {\r\n console.error(\"RTCDataChannel error:\", event);\r\n onClose?.();\r\n });\r\n\r\n const ready = new Promise<void>((resolve, reject) => {\r\n if (dc.readyState === \"open\") {\r\n resolve();\r\n return;\r\n }\r\n dc.addEventListener(\"open\", () => resolve(), { once: true });\r\n dc.addEventListener(\"error\", (event: unknown) => reject(event), { once: true });\r\n dc.addEventListener(\"close\", () => reject(new Error(\"RTCDataChannel closed before open\")), {\r\n once: true,\r\n });\r\n });\r\n\r\n return {\r\n ready,\r\n isOpen: () => dc.readyState === \"open\",\r\n send: (frame) => {\r\n // A pooled `Uint8Array` may be backed by a `SharedArrayBuffer` that `send` rejects — copy into a\r\n // fresh view (mirrors the WebSocket `sendFrame` guard).\r\n if (typeof frame === \"string\" || frame instanceof ArrayBuffer) dc.send(frame);\r\n else dc.send(new Uint8Array(frame));\r\n },\r\n attach: (handlers) => {\r\n onMessage = handlers.onMessage;\r\n onClose = handlers.onClose;\r\n for (const frame of preAttach) handlers.onMessage(frame);\r\n preAttach.length = 0;\r\n },\r\n close: () => {\r\n intentional = true;\r\n try {\r\n dc.close();\r\n } catch {\r\n // already closing/closed — the close listener still runs cleanup\r\n }\r\n },\r\n get label() {\r\n return dc.label != null && dc.label !== \"\" ? dc.label : undefined;\r\n },\r\n };\r\n}\r\n\r\nasync function normalizeFrame(\r\n data: unknown,\r\n): Promise<string | ArrayBuffer | Uint8Array | undefined> {\r\n if (typeof data === \"string\" || data instanceof ArrayBuffer || data instanceof Uint8Array) {\r\n return data;\r\n }\r\n if (typeof Blob !== \"undefined\" && data instanceof Blob) {\r\n return await data.arrayBuffer();\r\n }\r\n return undefined;\r\n}\r\n","import type { ITransportRouteActionParams, ITransportRouteInfo } from \"../../../Transport.types\";\r\nimport {\r\n type IRtcDataChannelLike,\r\n rtcDataChannelByteChannel,\r\n} from \"./rtcDataChannelByteChannel\";\r\nimport type { IDuplexCarrierSource } from \"../../Carrier.types\";\r\n\r\nexport interface IRtcCarrierOptions {\r\n getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];\r\n getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;\r\n}\r\n\r\n/**\r\n * A WebRTC {@link IDuplexCarrierSource} over an already-negotiated `RTCDataChannel` (signaling is the\r\n * app's concern). Hand it to {@link secureTransport} so two browsers/apps linked peer-to-peer run the\r\n * identical secure session as a WebSocket.\r\n */\r\nexport function rtcCarrier(\r\n dataChannel: IRtcDataChannelLike,\r\n options: IRtcCarrierOptions = {},\r\n): IDuplexCarrierSource {\r\n return {\r\n carrierLabel: \"webrtc\",\r\n open: () => rtcDataChannelByteChannel(dataChannel),\r\n getCacheKey: options.getTransportCacheKey ?? (() => [\"webrtc\"]),\r\n getRouteInfo: options.getRouteInfo,\r\n };\r\n}\r\n","import { err } from \"@nice-code/error\";\r\nimport { err_nice_transport } from \"../../../err_nice_transport\";\r\n\r\nexport enum EErrId_NiceTransport_WebSocket {\r\n ws_disconnected = \"ws_disconnected\",\r\n ws_create_failed = \"ws_create_failed\",\r\n ws_error = \"ws_error\",\r\n}\r\n\r\nexport const err_nice_transport_ws = err_nice_transport.createChildDomain({\r\n domain: \"ws_transport\",\r\n schema: {\r\n [EErrId_NiceTransport_WebSocket.ws_disconnected]: err<Record<string, never>>({\r\n message: () => `WebSocket transport disconnected.`,\r\n }),\r\n [EErrId_NiceTransport_WebSocket.ws_create_failed]: err<{\r\n originalError?: Error;\r\n }>({\r\n message: ({ originalError }) =>\r\n `Failed to create WebSocket transport.${originalError ? ` Original error: ${originalError.message}` : \"\"}`,\r\n }),\r\n [EErrId_NiceTransport_WebSocket.ws_error]: err<{\r\n originalError?: Error;\r\n }>({\r\n message: ({ originalError }) =>\r\n `WebSocket transport error.${originalError ? ` Original error: ${originalError.message}` : \"\"}`,\r\n }),\r\n },\r\n});\r\n","/**\r\n * Send a text or binary frame over a socket. A binary formatter may hand back a `Uint8Array` whose\r\n * backing buffer is typed as `ArrayBufferLike` (msgpackr pools buffers / may be `SharedArrayBuffer`),\r\n * which `WebSocket.send`'s `BufferSource` parameter rejects — copy it into a fresh `ArrayBuffer`-backed\r\n * view so the type (and the bytes) are safe to send.\r\n */\r\nexport function sendFrame(ws: WebSocket, data: string | Uint8Array | ArrayBuffer): void {\r\n if (typeof data === \"string\" || data instanceof ArrayBuffer) {\r\n ws.send(data);\r\n return;\r\n }\r\n ws.send(new Uint8Array(data));\r\n}\r\n\r\n/** Compact a WebSocket URL to `host/pathname` for devtools display, falling back to the raw url. */\r\nexport function shortWs(url: string): string {\r\n try {\r\n const u = new URL(url);\r\n return `${u.host}${u.pathname}`;\r\n } catch {\r\n return url;\r\n }\r\n}\r\n","import type { IDuplexCarrier } from \"../../Carrier.types\";\r\nimport { sendFrame } from \"./ws_util\";\r\n\r\n/**\r\n * Adapt a `WebSocket` to the carrier-agnostic {@link IDuplexCarrier}, so the WebSocket becomes\r\n * \"just another carrier\" under the shared secure session. It owns every WebSocket-specific concern —\r\n * awaiting `open`, normalizing `Blob` frames to bytes, suppressing the log on a deliberate `close`, and\r\n * buffering any frame that arrives before the session attaches its handler — leaving the session itself\r\n * carrier-neutral.\r\n */\r\nexport function webSocketByteChannel(ws: WebSocket): IDuplexCarrier {\r\n let intentional = false;\r\n let onMessage: ((frame: string | ArrayBuffer | Uint8Array) => void) | undefined;\r\n let onClose: (() => void) | undefined;\r\n // Frames that land before the session calls `attach` (none expected in practice, but never lose one).\r\n const preAttach: (string | ArrayBuffer | Uint8Array)[] = [];\r\n\r\n const deliver = (frame: string | ArrayBuffer | Uint8Array): void => {\r\n if (onMessage != null) onMessage(frame);\r\n else preAttach.push(frame);\r\n };\r\n\r\n ws.addEventListener(\"message\", async (event) => {\r\n const frame = await normalizeFrame((event as MessageEvent).data);\r\n if (frame !== undefined) deliver(frame);\r\n });\r\n ws.addEventListener(\"close\", (event) => {\r\n if (!intentional) console.error(\"WebSocket closed:\", event);\r\n onClose?.();\r\n });\r\n ws.addEventListener(\"error\", (event) => {\r\n console.error(\"WebSocket error:\", event);\r\n onClose?.();\r\n });\r\n\r\n const ready = new Promise<void>((resolve, reject) => {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n resolve();\r\n return;\r\n }\r\n ws.addEventListener(\"open\", () => resolve(), { once: true });\r\n ws.addEventListener(\"error\", (event) => reject(event), { once: true });\r\n ws.addEventListener(\r\n \"close\",\r\n (event) =>\r\n reject(new Error(`WebSocket closed before open: code=${(event as CloseEvent).code}`)),\r\n { once: true },\r\n );\r\n });\r\n\r\n return {\r\n ready,\r\n isOpen: () => ws.readyState === WebSocket.OPEN,\r\n send: (frame) => sendFrame(ws, frame),\r\n attach: (handlers) => {\r\n onMessage = handlers.onMessage;\r\n onClose = handlers.onClose;\r\n for (const frame of preAttach) handlers.onMessage(frame);\r\n preAttach.length = 0;\r\n },\r\n close: () => {\r\n intentional = true;\r\n try {\r\n ws.close();\r\n } catch {\r\n // already closing/closed — the close listener still runs cleanup\r\n }\r\n },\r\n get label() {\r\n return ws.url != null && ws.url !== \"\" ? ws.url : undefined;\r\n },\r\n };\r\n}\r\n\r\n/** Accept text + binary frames (ArrayBuffer / Uint8Array / Blob); Blobs are converted to a buffer. */\r\nasync function normalizeFrame(\r\n data: unknown,\r\n): Promise<string | ArrayBuffer | Uint8Array | undefined> {\r\n if (typeof data === \"string\" || data instanceof ArrayBuffer || data instanceof Uint8Array) {\r\n return data;\r\n }\r\n if (typeof Blob !== \"undefined\" && data instanceof Blob) {\r\n return await data.arrayBuffer();\r\n }\r\n return undefined;\r\n}\r\n","import type { ITransportRouteActionParams, ITransportRouteInfo } from \"../../../Transport.types\";\r\nimport { webSocketByteChannel } from \"./webSocketByteChannel\";\r\nimport { shortWs } from \"./ws_util\";\r\nimport type { IDuplexCarrierSource } from \"../../Carrier.types\";\r\n\r\nexport interface IWsCarrierOptions {\r\n /** Override socket creation (defaults to a `new WebSocket(url)` with `binaryType = \"arraybuffer\"`). */\r\n createWebSocket?: (input: ITransportRouteActionParams) => WebSocket;\r\n /** Override the reuse key (defaults to `[url]`, so one socket is shared per endpoint). */\r\n getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];\r\n /** Override the devtools route info for a specific action. */\r\n getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;\r\n}\r\n\r\n/**\r\n * A WebSocket {@link IDuplexCarrierSource}: opens an `arraybuffer` socket to `url` (cached per endpoint)\r\n * and adapts it to a carrier. Hand it to {@link secureTransport} (or `LinkTransport`) — the WebSocket is\r\n * now \"just another carrier\" under the shared secure session, with no WS-specific transport class.\r\n */\r\nexport function wsCarrier(url: string, options: IWsCarrierOptions = {}): IDuplexCarrierSource {\r\n return {\r\n carrierLabel: \"ws\",\r\n open: (input) =>\r\n webSocketByteChannel(options.createWebSocket?.(input) ?? defaultWebSocket(url)),\r\n getCacheKey: options.getTransportCacheKey ?? (() => [url]),\r\n getRouteInfo:\r\n options.getRouteInfo ?? (() => ({ carrierLabel: \"ws\", url, summary: `ws ${shortWs(url)}` })),\r\n };\r\n}\r\n\r\nfunction defaultWebSocket(url: string): WebSocket {\r\n const ws = new WebSocket(url);\r\n // Binary responses as ArrayBuffer (not Blob) so the session unpacks them synchronously.\r\n ws.binaryType = \"arraybuffer\";\r\n return ws;\r\n}\r\n","import type { ITransportRouteActionParams, ITransportRouteInfo } from \"../../../Transport.types\";\r\nimport type { IExchangeCarrier, IExchangeCarrierSource, TFrame } from \"../../Carrier.types\";\r\n\r\n/** The HTTP request an action is sent over (the body is supplied by the secure exchange session). */\r\nexport interface IHttpCarrierRequest {\r\n url: string;\r\n headers?: Record<string, string>;\r\n}\r\n\r\n/** The slice of `fetch` the carrier uses — a structural type so callers (and tests) needn't match the\r\n * full platform `fetch` (Bun's adds `preconnect`, etc.). The global `fetch` satisfies it. */\r\nexport type TCarrierFetch = (input: string, init?: RequestInit) => Promise<Response>;\r\n\r\nexport interface IHttpCarrierOptions {\r\n /** Override the reuse key (defaults to `[url]`, so one session is shared per endpoint). */\r\n getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];\r\n /** Override the devtools route info for a specific action. */\r\n getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;\r\n /** Override `fetch` (e.g. to route to an in-memory handler in tests). Defaults to global `fetch`. */\r\n fetch?: TCarrierFetch;\r\n}\r\n\r\nfunction shortPath(url: string): string {\r\n try {\r\n return new URL(url).pathname || url;\r\n } catch {\r\n return url;\r\n }\r\n}\r\n\r\n/**\r\n * An HTTP {@link IExchangeCarrierSource}: each `exchange` POSTs one frame body to the action endpoint and\r\n * resolves with the response body as the single correlated reply. Hand it to {@link secureTransport} —\r\n * HTTP then runs the *same* secure session as a duplex carrier (handshake → token → encrypted frames),\r\n * the request/reply correlation provided for free by the HTTP transaction.\r\n *\r\n * `createRequest` derives the URL/headers per action (keep it simple with `() => ({ url })`). The body is\r\n * the session's responsibility, so it is never built here.\r\n */\r\nexport function httpCarrier(\r\n createRequest: (input: ITransportRouteActionParams) => IHttpCarrierRequest,\r\n options: IHttpCarrierOptions = {},\r\n): IExchangeCarrierSource {\r\n const doFetch = options.fetch ?? fetch;\r\n\r\n return {\r\n shape: \"exchange\",\r\n carrierLabel: \"http\",\r\n open: (input): IExchangeCarrier => {\r\n const request = createRequest(input);\r\n return {\r\n label: request.url,\r\n exchange: async (frame: TFrame, opts): Promise<TFrame> => {\r\n const res = await doFetch(request.url, {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\", ...request.headers },\r\n body: typeof frame === \"string\" ? frame : new Uint8Array(frame),\r\n signal: opts?.signal,\r\n });\r\n return await res.text();\r\n },\r\n };\r\n },\r\n getCacheKey: options.getTransportCacheKey ?? ((input) => [createRequest(input).url]),\r\n getRouteInfo:\r\n options.getRouteInfo ??\r\n ((input) => {\r\n const { url } = createRequest(input);\r\n return { carrierLabel: \"http\", method: \"POST\", url, summary: `POST ${shortPath(url)}` };\r\n }),\r\n };\r\n}\r\n","import { pack, unpack } from \"msgpackr\";\r\nimport type { ActionDomain } from \"../../../ActionDefinition/Domain/ActionDomain\";\r\nimport type { ITransportRouteActionParams } from \"../Transport.types\";\r\nimport {\r\n assembleWireJson,\r\n buildActionRouteDictionary,\r\n extractWirePayload,\r\n type IActionWireFormat,\r\n PayloadTypeToInt,\r\n ReversePayloadType,\r\n} from \"./actionWireCodec\";\r\n\r\n/**\r\n * Positional layout of the stateless binary envelope. A flat tuple (rather than an object) strips the\r\n * repeated `domain`/`id`/`form`/`type` and context key names from every frame, and we carry only the\r\n * context fields the receiver can't recompute: `cuid` (correlation) and `originClient` (return\r\n * routing).\r\n *\r\n * [ routeInt, typeInt, time, cuid, originClient, payloadData ]\r\n *\r\n * Dropped vs the JSON wire: `form`/`type` strings, `inputHash`/`outputHash` (recomputed on hydrate),\r\n * `context.timeCreated` (reconstructed from `time`) and `context.routing` (rebuilt empty — the\r\n * receiver re-stamps its own route items as it handles the action). For the leanest possible frames\r\n * (integer correlation, identity dropped after a handshake), use `createBinaryWireSessionFactory`.\r\n */\r\nconst ENVELOPE = {\r\n route: 0,\r\n type: 1,\r\n time: 2,\r\n cuid: 3,\r\n originClient: 4,\r\n payload: 5,\r\n} as const;\r\nconst ENVELOPE_LENGTH = 6;\r\n\r\n/**\r\n * Builds a *stateless* `formatMessage` pipeline for {@link LinkTransport}, packing action\r\n * payloads into a compact msgpackr binary frame instead of JSON. The `domain`/`id` route collapses to\r\n * a single integer drawn from a shared dictionary; `form`/`type`, the recomputable\r\n * `inputHash`/`outputHash`, and the per-frame `context.routing`/`context.timeCreated` are all dropped\r\n * (see {@link ENVELOPE}).\r\n *\r\n * No validation runs here: `incoming` blindly reconstructs the wire JSON shape and hands it back to\r\n * the connection, which flows into `ActionRuntime` → `domain.hydrateAnyAction()` where the Valibot\r\n * schemas validate it exactly as they would for a JSON frame.\r\n *\r\n * Both ends of the socket MUST construct the adapter with the same domains in the same order — the\r\n * integer dictionary is positional. Mismatched dictionaries will route to the wrong action.\r\n *\r\n * Because `incoming` returns `undefined` for text frames, a binary server can still serve plain-JSON\r\n * clients on the same runtime (the connection falls back to its built-in JSON parser).\r\n */\r\nexport function createBinaryWireAdapter(domains: ActionDomain<any>[]): IActionWireFormat {\r\n const { routeToInt, intToRoute } = buildActionRouteDictionary(domains);\r\n\r\n return {\r\n outgoing: (input: ITransportRouteActionParams): Uint8Array => {\r\n const json = input.action.toJsonObject();\r\n const routeKey = `${json.domain}:${json.id}`;\r\n const routeInt = routeToInt.get(routeKey);\r\n\r\n if (routeInt == null) {\r\n throw new Error(`[binary-wire] Cannot pack unregistered action route: ${routeKey}`);\r\n }\r\n\r\n const envelope = new Array(ENVELOPE_LENGTH);\r\n envelope[ENVELOPE.route] = routeInt;\r\n envelope[ENVELOPE.type] = PayloadTypeToInt[json.type];\r\n envelope[ENVELOPE.time] = json.time;\r\n envelope[ENVELOPE.cuid] = json.context.cuid;\r\n envelope[ENVELOPE.originClient] = json.context.originClient;\r\n envelope[ENVELOPE.payload] = extractWirePayload(json);\r\n\r\n return pack(envelope);\r\n },\r\n\r\n incoming: (frame: string | ArrayBuffer | Uint8Array | Blob) => {\r\n // Only binary frames are ours. Text frames fall through to the JSON parser; Blobs should have\r\n // been converted to a buffer by the connection before reaching us — if not, we can't unpack\r\n // them synchronously, so defer.\r\n let buffer: Uint8Array;\r\n if (frame instanceof ArrayBuffer) {\r\n buffer = new Uint8Array(frame);\r\n } else if (frame instanceof Uint8Array) {\r\n buffer = frame;\r\n } else {\r\n return undefined;\r\n }\r\n\r\n try {\r\n const envelope = unpack(buffer);\r\n\r\n if (!Array.isArray(envelope) || envelope.length !== ENVELOPE_LENGTH) return undefined;\r\n\r\n const routeMeta = intToRoute[envelope[ENVELOPE.route]];\r\n const payloadType = ReversePayloadType[envelope[ENVELOPE.type]];\r\n if (routeMeta == null || payloadType == null) return undefined;\r\n\r\n const time = envelope[ENVELOPE.time];\r\n // Rebuild the context: `routing` starts empty (the receiver re-stamps its own hops) and\r\n // `timeCreated` is approximated by the payload `time` — neither affects hydration/validation.\r\n const context = {\r\n cuid: envelope[ENVELOPE.cuid],\r\n timeCreated: time,\r\n routing: [],\r\n originClient: envelope[ENVELOPE.originClient],\r\n };\r\n\r\n return assembleWireJson(routeMeta, payloadType, time, context, envelope[ENVELOPE.payload]);\r\n } catch (e) {\r\n console.error(\"[binary-wire] Failed to unpack binary action frame\", e);\r\n return undefined;\r\n }\r\n },\r\n };\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["normalizeFrame"],"sources":["../src/ActionDefinition/Action/Context/ActionContext.ts","../src/ActionDefinition/Action/Core/ActionCore.ts","../src/utils/isAction_Context_JsonObject.ts","../src/utils/isAction_Core_JsonObject.ts","../src/utils/isAction_Any_JsonObject.ts","../src/utils/assertIsActionJson.ts","../src/utils/isAction_Any_Instance.ts","../src/ActionDefinition/Domain/ActionDomainBase.ts","../src/ActionRuntime/ActionRuntimeManager.ts","../src/ActionDefinition/Domain/ActionRootDomain.ts","../src/ActionDefinition/Domain/ActionDomain.ts","../src/ActionDefinition/Domain/helpers/createRootActionDomain.ts","../src/ActionRuntime/Transport/Carrier/duplex/inMemory/createInMemoryChannel.ts","../src/ActionRuntime/Transport/Carrier/duplex/inMemory/inMemoryCarrier.ts","../src/ActionRuntime/Transport/Carrier/duplex/rtc/rtcDataChannelByteChannel.ts","../src/ActionRuntime/Transport/Carrier/duplex/rtc/rtcCarrier.ts","../src/ActionRuntime/Transport/Carrier/duplex/ws/err_nice_transport_ws.ts","../src/ActionRuntime/Transport/Carrier/duplex/ws/ws_util.ts","../src/ActionRuntime/Transport/Carrier/duplex/ws/webSocketByteChannel.ts","../src/ActionRuntime/Transport/Carrier/duplex/ws/wsCarrier.ts","../src/ActionRuntime/Transport/Carrier/exchange/http/httpCarrier.ts"],"sourcesContent":["import { RuntimeCoordinate } from \"../../../ActionRuntime/RuntimeCoordinate\";\nimport type { ActionDomain } from \"../../Domain/ActionDomain\";\nimport type {\n IActionDomain,\n TInferInputFromSchema,\n TInferOutputFromSchema,\n} from \"../../Domain/ActionDomain.types\";\nimport { ActionBase } from \"../ActionBase\";\nimport { EActionForm } from \"../ActionBase.types\";\nimport type {\n IActionContext,\n IActionContext_Data,\n IActionContext_Data_JsonObject,\n IActionContext_JsonObject,\n IActionRouteItem,\n} from \"./ActionContext.types\";\n\nexport class ActionContext<\n DOM extends IActionDomain,\n ID extends keyof DOM[\"actionSchema\"] & string = keyof DOM[\"actionSchema\"] & string,\n >\n extends ActionBase<EActionForm.context, DOM, ID>\n implements IActionContext<DOM, ID>\n{\n readonly form = EActionForm.context;\n readonly _routing: IActionRouteItem[];\n readonly timeCreated: number;\n readonly cuid: string;\n originClient: RuntimeCoordinate;\n\n constructor(\n readonly _domain: ActionDomain<DOM>,\n id: ID,\n hydrationData: IActionContext_Data,\n ) {\n super(EActionForm.context, _domain, id);\n this.timeCreated = hydrationData.timeCreated;\n this.cuid = hydrationData.cuid;\n this._routing = hydrationData.routing;\n this.originClient = hydrationData.originClient;\n }\n\n _setOriginClient(client: RuntimeCoordinate): void {\n this.originClient = client;\n }\n\n toJsonString(): string {\n return JSON.stringify(this.toJsonObject());\n }\n\n toContextDataJsonObject(): IActionContext_Data_JsonObject {\n return {\n timeCreated: this.timeCreated,\n cuid: this.cuid,\n routing: this.routing.map((item) => ({\n runtime: item.runtime.toJsonObject(),\n handler: item.handler,\n time: item.time,\n })),\n originClient: this.originClient.toJsonObject(),\n };\n }\n\n toJsonObject(): IActionContext_JsonObject<DOM, ID> {\n return {\n ...super.toJsonObject(),\n ...this.toContextDataJsonObject(),\n };\n }\n\n get routing(): IActionRouteItem[] {\n return this._routing;\n }\n\n addRouteItem(item: IActionRouteItem): void {\n this._routing.push(item);\n }\n\n deserializeInput(\n serialized: TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"SerdeInput\"],\n ): TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"] {\n return this.schema.deserializeInput(serialized);\n }\n\n serializeInput(\n raw: TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"],\n ): TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"SerdeInput\"] {\n return this.schema.serializeInput(raw);\n }\n\n validateInput(input: unknown): TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"] {\n return this.schema.validateInput(input, {\n domain: this.domain,\n actionId: this.id,\n });\n }\n\n validateOutput(output: unknown): TInferOutputFromSchema<DOM[\"actionSchema\"][ID]>[\"Output\"] {\n return this.schema.validateOutput(output, {\n domain: this.domain,\n actionId: this.id,\n });\n }\n}\n","import { nanoid } from \"nanoid\";\nimport { RuntimeCoordinate } from \"../../../ActionRuntime/RuntimeCoordinate\";\nimport type { ActionDomain } from \"../../Domain/ActionDomain\";\nimport type {\n IActionDomain,\n TInferInputFromSchema,\n TInferOutputFromSchema,\n} from \"../../Domain/ActionDomain.types\";\nimport type { TNarrowActionType } from \"../Action.combined.types\";\nimport { ActionBase } from \"../ActionBase\";\nimport { EActionForm, type IActionBase, type IActionBase_JsonObject } from \"../ActionBase.types\";\nimport { ActionContext } from \"../Context/ActionContext\";\nimport { ActionPayload } from \"../Payload/ActionPayload\";\nimport { ActionPayload_Request } from \"../Payload/ActionPayload_Request\";\nimport type { IActionCore } from \"./ActionCore.types\";\n\nexport class ActionCore<\n DOM extends IActionDomain,\n ID extends keyof DOM[\"actionSchema\"] & string = keyof DOM[\"actionSchema\"] & string,\n >\n extends ActionBase<EActionForm.core, DOM, ID>\n implements IActionCore<DOM, ID>\n{\n readonly form = EActionForm.core;\n\n constructor(\n readonly _domain: ActionDomain<DOM>,\n id: ID,\n ) {\n super(EActionForm.core, _domain, id);\n }\n\n is<ACT extends IActionBase<any, any, any>>(\n action: ACT | unknown | null | undefined,\n ): action is TNarrowActionType<DOM, ACT, ID> {\n return (\n action instanceof ActionPayload && action.domain === this.domain && action.id === this.id\n );\n }\n\n toJsonObject(): IActionBase_JsonObject<EActionForm.core, DOM, ID> {\n return {\n id: this.id,\n form: this.form,\n domain: this.domain,\n allDomains: this.allDomains,\n };\n }\n\n request(\n ...args: [TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"]] extends [never]\n ? [input?: never]\n : [input: TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"]]\n ): ActionPayload_Request<DOM, ID> {\n const input: unknown = args[0];\n const validatedInput = this.schema.validateInput(input, {\n actionId: this.id,\n domain: this.domain,\n });\n\n const context = new ActionContext(this._domain, this.id, {\n cuid: nanoid(),\n timeCreated: Date.now(),\n routing: [],\n originClient: RuntimeCoordinate.unknown,\n });\n\n return new ActionPayload_Request({ context }, validatedInput, {\n time: Date.now(),\n });\n }\n\n // async run(\n // input: TInferInputFromSchema<DOM[\"actions\"][ID]>[\"Input\"],\n // options?: IExecuteActionOptions<DOM, ID>,\n // ): Promise<RunningAction<DOM, ID>> {\n // return this.request(input).run(options);\n // }\n\n // async runToOutput(\n // input: TInferInputFromSchema<DOM[\"actions\"][ID]>[\"Input\"],\n // options?: IExecuteActionOptions<DOM, ID>,\n // ): Promise<TInferOutputFromSchema<DOM[\"actions\"][ID]>[\"Output\"]> {\n // return this.request(input).runToOutput(options);\n // }\n\n // async runToOutputSafe(\n // input: TInferInputFromSchema<DOM[\"actions\"][ID]>[\"Input\"],\n // options?: IExecuteActionOptions<DOM, ID>,\n // ): Promise<\n // TActionResult<\n // TInferOutputFromSchema<DOM[\"actions\"][ID]>[\"Output\"],\n // TInferActionError<DOM[\"actions\"][ID]>\n // >\n // > {\n // return this.request(input).runToOutputSafe(options);\n // }\n\n deserializeInput(\n serialized: TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"SerdeInput\"],\n ): TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"] {\n return this.schema.deserializeInput(serialized);\n }\n\n serializeInput(\n raw: TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"],\n ): TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"SerdeInput\"] {\n return this.schema.serializeInput(raw);\n }\n\n validateInput(input: unknown): TInferInputFromSchema<DOM[\"actionSchema\"][ID]>[\"Input\"] {\n return this.schema.validateInput(input, {\n domain: this.domain,\n actionId: this.id,\n });\n }\n\n validateOutput(output: unknown): TInferOutputFromSchema<DOM[\"actionSchema\"][ID]>[\"Output\"] {\n return this.schema.validateOutput(output, {\n domain: this.domain,\n actionId: this.id,\n });\n }\n}\n","import { EActionForm } from \"../ActionDefinition/Action/ActionBase.types\";\nimport type { IActionContext_JsonObject } from \"../ActionDefinition/Action/Context/ActionContext.types\";\nimport { isAction_Base_JsonObject } from \"./isAction_Base_JsonObject\";\n\nexport const isAction_Context_JsonObject = (obj: unknown): obj is IActionContext_JsonObject => {\n return isAction_Base_JsonObject(obj) && obj.form === EActionForm.context;\n};\n","import { EActionForm } from \"../ActionDefinition/Action/ActionBase.types\";\nimport type { IActionCore_JsonObject } from \"../ActionDefinition/Action/Core/ActionCore.types\";\nimport { isAction_Base_JsonObject } from \"./isAction_Base_JsonObject\";\n\nexport const isAction_Core_JsonObject = (obj: unknown): obj is IActionCore_JsonObject => {\n return isAction_Base_JsonObject(obj) && obj.form === EActionForm.core;\n};\n","import type { TAction_Any_JsonObject } from \"../ActionDefinition/Action/Action.combined.types\";\nimport { isAction_Context_JsonObject } from \"./isAction_Context_JsonObject\";\nimport { isAction_Core_JsonObject } from \"./isAction_Core_JsonObject\";\nimport { isActionPayload_Any_JsonObject } from \"./isActionPayload_Any_JsonObject\";\n\nexport function isAction_Any_JsonObject(obj: unknown): obj is TAction_Any_JsonObject {\n return (\n isActionPayload_Any_JsonObject(obj) ||\n isAction_Context_JsonObject(obj) ||\n isAction_Core_JsonObject(obj)\n );\n}\n","import type { IActionBase_JsonObject } from \"../ActionDefinition/Action/ActionBase.types\";\nimport { EErrId_NiceAction, err_nice_action } from \"../errors/err_nice_action\";\nimport { isAction_Any_JsonObject } from \"./isAction_Any_JsonObject\";\n\nexport function assertIsActionJson(obj: unknown): asserts obj is IActionBase_JsonObject {\n if (!isAction_Any_JsonObject(obj)) {\n throw err_nice_action.fromId(EErrId_NiceAction.wire_not_action_data);\n }\n}\n","import type { TAction_Any_Instance } from \"../ActionDefinition/Action/Action.combined.types\";\nimport type { IActionBase } from \"../ActionDefinition/Action/ActionBase.types\";\nimport { ActionContext } from \"../ActionDefinition/Action/Context/ActionContext\";\nimport { ActionCore } from \"../ActionDefinition/Action/Core/ActionCore\";\nimport { ActionPayload } from \"../ActionDefinition/Action/Payload/ActionPayload\";\n\nexport function isAction_Any_Instance<ACT extends IActionBase<any, any>>(\n value: unknown | ACT,\n): value is TAction_Any_Instance<any, any> {\n return (\n value instanceof ActionCore || value instanceof ActionPayload || value instanceof ActionContext\n );\n}\n","import type {\n TDistributeRunningActionUpdateListener,\n TRunningActionUpdateListener,\n} from \"../Action/RunningAction.types\";\nimport type { IActionDomain } from \"./ActionDomain.types\";\n\nexport abstract class ActionDomainBase<ACT_DOM extends IActionDomain = IActionDomain>\n implements IActionDomain<ACT_DOM[\"allDomains\"], ACT_DOM[\"actionSchema\"]>\n{\n readonly domain: ACT_DOM[\"domain\"];\n readonly allDomains: ACT_DOM[\"allDomains\"];\n readonly actionSchema: ACT_DOM[\"actionSchema\"];\n\n protected _listeners: TRunningActionUpdateListener<any, any>[] = [];\n\n constructor(definition: ACT_DOM) {\n this.domain = definition.domain;\n this.allDomains = definition.allDomains;\n this.actionSchema = definition.actionSchema;\n }\n\n /**\n * Add an observer that is called after every action dispatched through this domain.\n * Returns an unsubscribe function — call it to remove the listener.\n */\n addActionListener(\n listener: TDistributeRunningActionUpdateListener<\n ACT_DOM,\n keyof ACT_DOM[\"actionSchema\"] & string\n >,\n ): () => void {\n this._listeners.push(listener as TRunningActionUpdateListener<any, any>);\n return () => {\n this._listeners = this._listeners.filter((l) => l !== listener);\n };\n }\n\n /**\n * @internal\n * Observers registered directly on this domain via {@link addActionListener}.\n * Used to wire observers (e.g. devtools) onto RunningActions that aren't created\n * through the local-dispatch path — notably inbound actions pushed from a backend\n * or another client over a bidirectional transport.\n */\n _getActionObservers(): TRunningActionUpdateListener<any, any>[] {\n return this._listeners;\n }\n}\n","import type { TActionPayload_Any_Instance } from \"../ActionDefinition/Action/Payload/ActionPayload.types\";\nimport { EErrId_NiceAction, err_nice_action } from \"../errors/err_nice_action\";\nimport type { ActionRuntime } from \"./ActionRuntime\";\nimport type { IActionHandlerAndRuntime, IActionRuntimeManagerContext } from \"./ActionRuntime.types\";\nimport type { IHandleActionOptions } from \"./Handler/ActionHandler.types\";\nimport {\n type IRuntimeCoordinate,\n RuntimeCoordinate,\n type TRuntimeCoordinateStringId,\n} from \"./RuntimeCoordinate\";\nimport { runtimeCoordinateToStringIds } from \"./utils/runtimeCoordinateToStringIds\";\n\nexport class ActionRuntimeManager {\n private _runtimes: Map<TRuntimeCoordinateStringId, ActionRuntime> = new Map();\n private _preferredRuntimeClientId: TRuntimeCoordinateStringId | null = null;\n private _context: IActionRuntimeManagerContext;\n\n constructor(context?: IActionRuntimeManagerContext) {\n this._context = context ?? {};\n }\n\n registerRuntime(runtime: ActionRuntime): void {\n const runtimeId = runtime.coordinate.stringId;\n if (this._runtimes.has(runtimeId)) {\n throw err_nice_action.fromId(EErrId_NiceAction.client_runtime_already_registered, {\n context: this._context,\n client: runtime.coordinate,\n });\n }\n\n for (const id of runtime.coordinate.toStringIds()) {\n if (this._runtimes.has(id)) {\n continue;\n }\n\n this._runtimes.set(id, runtime);\n }\n }\n\n getRuntimeAndHandlerForAction(\n action: TActionPayload_Any_Instance<any, any>,\n options?: IHandleActionOptions,\n throwOnIssue?: boolean,\n ): IActionHandlerAndRuntime | undefined {\n const localRuntime = options?.targetLocalRuntime;\n\n if (localRuntime != null) {\n const runtime = throwOnIssue\n ? this.getBestRuntimeOrThrow(options?.targetLocalRuntime?.coordinate)\n : this.getBestRuntime(options?.targetLocalRuntime?.coordinate);\n\n if (runtime == null) {\n return;\n }\n\n const handler = runtime._getHandlerForAction(action, options);\n\n if (handler != null) {\n return { handler, runtime };\n }\n\n if (throwOnIssue) {\n throw err_nice_action.fromId(EErrId_NiceAction.no_action_execution_handler, {\n domain: action.domain,\n actionId: action.id,\n specifiedClient: localRuntime.coordinate,\n });\n }\n }\n\n // If no client specified, try to find a runtime that can handle the action\n for (const runtime of this._runtimes.values()) {\n const handler = runtime._getHandlerForAction(action);\n if (handler) {\n return { handler, runtime };\n }\n }\n\n if (throwOnIssue) {\n throw err_nice_action.fromId(EErrId_NiceAction.no_action_execution_handler, {\n domain: action.domain,\n actionId: action.id,\n specifiedClient: options?.targetLocalRuntime?.coordinate,\n });\n }\n }\n\n getRuntimeAndHandlerForActionOrThrow(\n action: TActionPayload_Any_Instance<any, any>,\n options?: IHandleActionOptions,\n ): IActionHandlerAndRuntime {\n return this.getRuntimeAndHandlerForAction(action, options, true)!;\n }\n\n setPreferredRuntime(runtime: ActionRuntime): void {\n const runtimeId = runtime.coordinate.stringId;\n this._preferredRuntimeClientId = runtimeId;\n }\n\n getPreferredRuntime(): ActionRuntime | undefined {\n if (this._preferredRuntimeClientId) {\n const runtime = this._runtimes.get(this._preferredRuntimeClientId);\n if (runtime) {\n return runtime;\n }\n }\n return this._runtimes.values().next().value;\n }\n\n getBestRuntimeForSpecifier(clientSpecifier: IRuntimeCoordinate): ActionRuntime | undefined {\n const actionClient = new RuntimeCoordinate(clientSpecifier);\n const ids = actionClient.toStringIds();\n\n for (const id of ids) {\n const runtime = this._runtimes.get(id);\n if (runtime) {\n return runtime;\n }\n }\n }\n\n getBestRuntime(clientSpecifier?: IRuntimeCoordinate): ActionRuntime | undefined {\n return clientSpecifier != null\n ? this.getBestRuntimeForSpecifier(clientSpecifier)\n : this.getPreferredRuntime();\n }\n\n hasRuntime(runtime: ActionRuntime): boolean {\n return this._runtimes.has(runtime.coordinate.stringId);\n }\n\n getBestRuntimeOrThrow(specifier?: IRuntimeCoordinate): ActionRuntime {\n const runtime = this.getBestRuntime(specifier);\n\n if (!runtime) {\n if (specifier == null) {\n throw err_nice_action.fromId(EErrId_NiceAction.no_client_runtimes_registered, {\n context: this._context,\n });\n }\n\n throw err_nice_action.fromId(EErrId_NiceAction.client_runtime_not_registered, {\n context: this._context,\n clientStringId: runtimeCoordinateToStringIds(specifier)[0],\n });\n }\n\n return runtime;\n }\n}\n","import type { ActionRuntime } from \"../../ActionRuntime/ActionRuntime\";\nimport type { IActionHandlerAndRuntime } from \"../../ActionRuntime/ActionRuntime.types\";\nimport { ActionRuntimeManager } from \"../../ActionRuntime/ActionRuntimeManager\";\nimport type { IExecuteActionOptions } from \"../../ActionRuntime/Handler/ActionHandler.types\";\nimport type { IRuntimeCoordinate } from \"../../ActionRuntime/RuntimeCoordinate\";\nimport { EErrId_NiceAction, err_nice_action } from \"../../errors/err_nice_action\";\nimport type { ActionPayload_Request } from \"../Action/Payload/ActionPayload_Request\";\nimport { RunningAction } from \"../Action/RunningAction\";\nimport { ActionDomain } from \"./ActionDomain\";\nimport type {\n IActionDomain,\n IActionDomainChildOptions,\n IActionRootDomain,\n TActionDomainChildDef,\n} from \"./ActionDomain.types\";\nimport { ActionDomainBase } from \"./ActionDomainBase\";\n\nexport class ActionRootDomain<\n ROOT_DOM extends IActionRootDomain = IActionRootDomain,\n> extends ActionDomainBase<ROOT_DOM> {\n private _actionRuntimeManager: ActionRuntimeManager;\n\n constructor(\n readonly domainDefinition: {\n domain: ROOT_DOM[\"domain\"];\n },\n ) {\n const domainId = domainDefinition.domain;\n\n super({\n domain: domainId,\n allDomains: [domainId],\n actionSchema: {},\n } as ROOT_DOM);\n\n this._actionRuntimeManager = new ActionRuntimeManager({ domain: domainId });\n }\n\n createChildDomain<SUB_DOM extends IActionDomainChildOptions>(\n subDomainDef: SUB_DOM & {\n [K in Exclude<keyof SUB_DOM, keyof IActionDomainChildOptions>]: never;\n },\n ): ActionDomain<TActionDomainChildDef<ROOT_DOM, SUB_DOM>> {\n if (this.allDomains.includes(subDomainDef.domain)) {\n throw err_nice_action.fromId(EErrId_NiceAction.domain_already_exists_in_hierarchy, {\n domain: subDomainDef.domain,\n allParentDomains: this.allDomains,\n parentDomain: this.domain,\n });\n }\n\n return new ActionDomain<TActionDomainChildDef<ROOT_DOM, SUB_DOM>>(\n {\n allDomains: [...this.allDomains, subDomainDef.domain],\n domain: subDomainDef.domain,\n actionSchema: subDomainDef.actions,\n },\n { rootDomain: this },\n );\n }\n\n _registerRuntime(runtime: ActionRuntime): void {\n this._actionRuntimeManager.registerRuntime(runtime);\n }\n\n _hasRuntime(runtime: ActionRuntime): boolean {\n return this._actionRuntimeManager.hasRuntime(runtime);\n }\n\n getRuntime(clientSpecifier: IRuntimeCoordinate): ActionRuntime | undefined {\n return this._actionRuntimeManager.getBestRuntimeForSpecifier(clientSpecifier);\n }\n\n async _runAction<\n DOM extends IActionDomain,\n ID extends keyof DOM[\"actionSchema\"] & string = keyof DOM[\"actionSchema\"] & string,\n ACT extends ActionPayload_Request<DOM, ID> = ActionPayload_Request<DOM, ID>,\n >(actionPayload: ACT, options?: IExecuteActionOptions<DOM, ID>): Promise<RunningAction<DOM, ID>> {\n const allListeners = [...this._listeners, ...(options?.listeners ?? [])];\n\n let handlerAndRuntime: IActionHandlerAndRuntime;\n try {\n handlerAndRuntime = this._actionRuntimeManager.getRuntimeAndHandlerForActionOrThrow(\n actionPayload,\n options,\n );\n } catch (err) {\n const runningAction = new RunningAction<DOM, ID>({\n context: actionPayload.context,\n request: actionPayload,\n callSite: actionPayload._callSite,\n });\n runningAction.addUpdateListeners(allListeners);\n runningAction._failWithError(err);\n throw err;\n }\n\n const { handler, runtime } = handlerAndRuntime;\n\n actionPayload.context._setOriginClient(runtime.coordinate);\n\n const runningAction = await handler.handleActionRequest(actionPayload, {\n targetLocalRuntime: runtime,\n });\n\n runningAction.addUpdateListeners(allListeners);\n\n return runningAction;\n }\n}\n","import type { ActionRuntime } from \"../../ActionRuntime/ActionRuntime\";\nimport type { IExecuteActionOptions } from \"../../ActionRuntime/Handler/ActionHandler.types\";\nimport { ActionLocalHandler } from \"../../ActionRuntime/Handler/Local/ActionLocalHandler\";\nimport { RuntimeCoordinate } from \"../../ActionRuntime/RuntimeCoordinate\";\nimport { EErrId_NiceAction, err_nice_action } from \"../../errors/err_nice_action\";\nimport { assertIsActionJson } from \"../../utils/assertIsActionJson\";\nimport { isAction_Any_Instance } from \"../../utils/isAction_Any_Instance\";\nimport type {\n TAction_Any_JsonObject,\n TDistributeActionPayload_Request,\n TDistributeActionPayload_Result,\n TDistributedDomainActions,\n TNarrowActionJsonTypeToActionInstanceType,\n} from \"../Action/Action.combined.types\";\nimport { EActionForm, type IActionBase } from \"../Action/ActionBase.types\";\nimport { ActionContext } from \"../Action/Context/ActionContext\";\nimport type { IActionContext_Data_JsonObject } from \"../Action/Context/ActionContext.types\";\nimport { ActionCore } from \"../Action/Core/ActionCore\";\nimport {\n EActionPayloadType,\n type IActionPayload_Request_JsonObject,\n type IActionPayload_Result_JsonObject,\n} from \"../Action/Payload/ActionPayload.types\";\nimport { ActionPayload_Request } from \"../Action/Payload/ActionPayload_Request\";\nimport { ActionPayload_Result } from \"../Action/Payload/ActionPayload_Result\";\nimport type { RunningAction } from \"../Action/RunningAction\";\nimport type { TRunningActionUpdateListener } from \"../Action/RunningAction.types\";\nimport type {\n IActionDomain,\n IActionDomainChildOptions,\n TActionDomainChildDef,\n TWrappableDomainActionHandler,\n} from \"./ActionDomain.types\";\nimport { ActionDomainBase } from \"./ActionDomainBase\";\nimport { type ActionRootDomain } from \"./ActionRootDomain\";\n\ntype TActionMap<ACT_DOM extends IActionDomain> = {\n [K in keyof ACT_DOM[\"actionSchema\"] & string]: ActionCore<ACT_DOM, K>;\n};\n\nexport class ActionDomain<\n ACT_DOM extends IActionDomain = IActionDomain,\n> extends ActionDomainBase<ACT_DOM> {\n private _rootDomain: ActionRootDomain<any>;\n private readonly _actionMap: TActionMap<ACT_DOM>;\n\n constructor(\n definition: ACT_DOM,\n {\n rootDomain,\n }: {\n rootDomain: ActionRootDomain<any>;\n },\n ) {\n super(definition);\n this._rootDomain = rootDomain;\n this._actionMap = this.createActionMap();\n }\n\n get rootDomain() {\n return this._rootDomain;\n }\n\n /**\n * @internal\n * All action observers that should see actions on this domain: the root domain's\n * observers plus this subdomain's own. Mirrors the listener set the local-dispatch\n * path assembles in `runAction`/`_runAction`, so inbound actions (pushed from a\n * backend or another client) can be wired up identically and surface in devtools.\n */\n _collectActionObservers(): TRunningActionUpdateListener<any, any>[] {\n return [...this._rootDomain._getActionObservers(), ...this._getActionObservers()];\n }\n\n _registerRuntime(runtime: ActionRuntime): void {\n this._rootDomain._registerRuntime(runtime);\n }\n\n createChildDomain<SUB_DOM extends IActionDomainChildOptions>(\n subDomainDef: SUB_DOM & {\n [K in Exclude<keyof SUB_DOM, keyof IActionDomainChildOptions>]: never;\n },\n ): ActionDomain<TActionDomainChildDef<ACT_DOM, SUB_DOM>> {\n if (this.allDomains.includes(subDomainDef.domain)) {\n throw err_nice_action.fromId(EErrId_NiceAction.domain_already_exists_in_hierarchy, {\n domain: subDomainDef.domain,\n allParentDomains: this.allDomains,\n parentDomain: this.domain,\n });\n }\n\n return new ActionDomain<TActionDomainChildDef<ACT_DOM, SUB_DOM>>(\n {\n allDomains: [...this.allDomains, subDomainDef.domain],\n domain: subDomainDef.domain,\n actionSchema: subDomainDef.actions,\n },\n { rootDomain: this._rootDomain },\n );\n }\n\n get action(): TActionMap<ACT_DOM> {\n return this._actionMap;\n }\n\n actionsMap(): TActionMap<ACT_DOM> {\n return this._actionMap;\n }\n\n actionForId<ID extends keyof ACT_DOM[\"actionSchema\"] & string>(id: ID): ActionCore<ACT_DOM, ID> {\n const actionSchema = this.actionSchema[id];\n if (!actionSchema) {\n throw err_nice_action.fromId(EErrId_NiceAction.action_id_not_in_domain, {\n domain: this.domain,\n actionId: id as string,\n });\n }\n\n return new ActionCore<ACT_DOM, ID>(this, id);\n }\n\n wrapAsPartialLocalHandler(\n wrappedActionExecutor: Partial<TWrappableDomainActionHandler<ACT_DOM>>,\n ): ActionLocalHandler {\n const _handler = new ActionLocalHandler();\n const executor = wrappedActionExecutor as unknown as Record<string, (input: any) => any>;\n\n for (const actionKey in wrappedActionExecutor) {\n if (!this.actionSchema[actionKey]) {\n continue;\n }\n\n _handler.forAction(this.actionForId(actionKey), (request) =>\n executor[request.id](request.input),\n );\n }\n\n return _handler;\n }\n\n wrapAsLocalHandler(\n wrappedActionExecutor: TWrappableDomainActionHandler<ACT_DOM>,\n ): ActionLocalHandler {\n const _handler = new ActionLocalHandler();\n const executor = wrappedActionExecutor as unknown as Record<string, (input: any) => any>;\n return _handler.forDomain(this, (request) => executor[request.id](request.input));\n }\n\n hydrateContext<ID extends keyof ACT_DOM[\"actionSchema\"] & string>(\n id: ID,\n contextData: IActionContext_Data_JsonObject,\n ): ActionContext<ACT_DOM, ID> {\n return new ActionContext(this, id, {\n timeCreated: contextData.timeCreated,\n cuid: contextData.cuid,\n routing: contextData.routing.map((item) => {\n return {\n runtime: new RuntimeCoordinate(item.runtime),\n handler: item.handler,\n time: item.time,\n };\n }),\n originClient: contextData.originClient\n ? new RuntimeCoordinate(contextData.originClient)\n : RuntimeCoordinate.unknown,\n });\n }\n\n isDomainAction<ACT extends IActionBase<any, ACT_DOM, any>>(\n action: ACT | unknown | null | undefined,\n ): action is TDistributedDomainActions<ACT_DOM, ACT> {\n return isAction_Any_Instance(action) && action.domain === this.domain;\n }\n\n hydrateRequestPayload<\n ID extends keyof ACT_DOM[\"actionSchema\"] & string,\n P extends IActionPayload_Request_JsonObject<ACT_DOM, ID>,\n >(serialized: P): TDistributeActionPayload_Request<ACT_DOM, ID> {\n if (serialized.type !== EActionPayloadType.request) {\n throw err_nice_action.fromId(EErrId_NiceAction.hydration_action_state_mismatch, {\n expected: EActionPayloadType.request,\n received: serialized.type,\n });\n }\n\n if (serialized.domain !== this.domain) {\n throw err_nice_action.fromId(EErrId_NiceAction.hydration_domain_mismatch, {\n expected: this.domain,\n received: serialized.domain,\n });\n }\n\n const id = serialized.id;\n if (!this.actionSchema[id]) {\n throw err_nice_action.fromId(EErrId_NiceAction.hydration_action_id_not_found, {\n domain: this.domain,\n actionId: serialized.id,\n });\n }\n\n const contextAction = this.hydrateContext(id, serialized.context);\n\n return new ActionPayload_Request(\n { context: contextAction },\n contextAction.deserializeInput(serialized.input),\n {\n time: serialized.time,\n },\n ) as TDistributeActionPayload_Request<ACT_DOM, ID>;\n }\n\n hydrateResultPayload<\n ID extends keyof ACT_DOM[\"actionSchema\"] & string,\n R extends IActionPayload_Result_JsonObject<ACT_DOM, ID>,\n >(serialized: R): TDistributeActionPayload_Result<ACT_DOM, ID> {\n if (serialized.type !== EActionPayloadType.result) {\n throw err_nice_action.fromId(EErrId_NiceAction.hydration_action_state_mismatch, {\n expected: EActionPayloadType.result,\n received: serialized.type,\n });\n }\n\n if (serialized.domain !== this.domain) {\n throw err_nice_action.fromId(EErrId_NiceAction.hydration_domain_mismatch, {\n expected: this.domain,\n received: serialized.domain,\n });\n }\n\n const id = serialized.id;\n\n if (!this.actionSchema[id]) {\n throw err_nice_action.fromId(EErrId_NiceAction.hydration_action_id_not_found, {\n domain: this.domain,\n actionId: serialized.id,\n });\n }\n\n const contextAction = this.hydrateContext(id, serialized.context);\n\n const result = serialized.result.ok\n ? {\n ok: true as const,\n output: contextAction.schema.deserializeOutput(serialized.result.output),\n }\n : serialized.result;\n\n return new ActionPayload_Result({ context: contextAction }, result, {\n time: serialized.time,\n }) as TDistributeActionPayload_Result<ACT_DOM, ID>;\n }\n\n hydrateAnyAction<\n ID extends keyof ACT_DOM[\"actionSchema\"] & string,\n AJ extends TAction_Any_JsonObject<ACT_DOM, ID>,\n >(actionJson: AJ): TNarrowActionJsonTypeToActionInstanceType<ACT_DOM, AJ, ID> {\n assertIsActionJson(actionJson);\n\n if (actionJson.form === EActionForm.data) {\n if (actionJson.type === EActionPayloadType.request) {\n return this.hydrateRequestPayload(\n actionJson,\n ) as unknown as TNarrowActionJsonTypeToActionInstanceType<ACT_DOM, AJ, ID>;\n }\n\n if (actionJson.type === EActionPayloadType.result) {\n return this.hydrateResultPayload(\n actionJson,\n ) as unknown as TNarrowActionJsonTypeToActionInstanceType<ACT_DOM, AJ, ID>;\n }\n }\n\n return this.actionForId(actionJson.id) as TNarrowActionJsonTypeToActionInstanceType<\n ACT_DOM,\n AJ,\n ID\n >;\n }\n\n async runAction<\n ID extends keyof ACT_DOM[\"actionSchema\"] & string,\n ACT extends ActionPayload_Request<ACT_DOM, ID>,\n >(\n request: ACT,\n options?: IExecuteActionOptions<ACT_DOM, ID>,\n ): Promise<RunningAction<ACT_DOM, ID>> {\n const allListeners: TRunningActionUpdateListener<any, any>[] = [\n ...(options?.listeners ?? []),\n ...this._listeners,\n ];\n\n return this._rootDomain._runAction(request, {\n ...options,\n listeners: allListeners,\n });\n }\n\n private createActionMap(): {\n [K in keyof ACT_DOM[\"actionSchema\"] & string]: ActionCore<ACT_DOM, K>;\n } {\n const map = {} as {\n [K in keyof ACT_DOM[\"actionSchema\"] & string]: ActionCore<ACT_DOM, K>;\n };\n\n for (const id in this.actionSchema) {\n map[id] = new ActionCore(this, id);\n }\n\n return map;\n }\n}\n","import type { IActionRootDomain } from \"../ActionDomain.types\";\nimport { ActionRootDomain } from \"../ActionRootDomain\";\n\nexport const createActionRootDomain = <ID extends string>(definition: {\n domain: ID;\n}): ActionRootDomain<IActionRootDomain<ID>> => {\n return new ActionRootDomain<IActionRootDomain<ID>>(definition);\n};\n","import type { IDuplexCarrier } from \"../../Carrier.types\";\r\n\r\ntype TFrame = string | ArrayBuffer | Uint8Array;\r\n\r\n/** The peer (server) end of an in-memory pair — what you feed into an `AcceptorHandler`. */\r\nexport interface IInMemoryServerEndpoint {\r\n /** Write a frame back to the client end. */\r\n send(frame: TFrame): void;\r\n /** Register the inbound handler (frames the client sent). */\r\n onMessage(handler: (frame: TFrame) => void): void;\r\n /** Close the pair from this end. */\r\n close(): void;\r\n /** Notified when the pair closes (from either end). */\r\n onClose(handler: () => void): void;\r\n}\r\n\r\nexport interface IInMemoryChannelPair {\r\n /** The client end — pass as a {@link IDuplexCarrier} to a `LinkTransport`. */\r\n clientChannel: IDuplexCarrier;\r\n /** The server end — wire into an `AcceptorHandler` (`send` + `receive`). */\r\n serverEndpoint: IInMemoryServerEndpoint;\r\n}\r\n\r\n/**\r\n * Two cross-wired in-process byte channels — a loopback carrier with no socket. The client end is a\r\n * {@link IDuplexCarrier} you hand to a {@link LinkTransport}; the server end plugs into an\r\n * `AcceptorHandler` (`send: (_, f) => serverEndpoint.send(f)`, and `serverEndpoint.onMessage(f =>\r\n * handler.receive(conn, f))`). Frames are delivered on a microtask, so each side observes the other\r\n * asynchronously — exactly like a real transport — which makes this ideal for tests and for running\r\n * two runtimes in one process (or proving a non-WS carrier end to end).\r\n */\r\nexport function createInMemoryChannelPair(): IInMemoryChannelPair {\r\n let clientMessage: ((frame: TFrame) => void) | undefined;\r\n let clientClose: (() => void) | undefined;\r\n let serverMessage: ((frame: TFrame) => void) | undefined;\r\n let serverClose: (() => void) | undefined;\r\n let open = true;\r\n\r\n const closeBoth = (): void => {\r\n if (!open) return;\r\n open = false;\r\n queueMicrotask(() => {\r\n clientClose?.();\r\n serverClose?.();\r\n });\r\n };\r\n\r\n const clientChannel: IDuplexCarrier = {\r\n ready: Promise.resolve(),\r\n isOpen: () => open,\r\n send: (frame) => {\r\n if (!open) return;\r\n queueMicrotask(() => serverMessage?.(frame));\r\n },\r\n attach: ({ onMessage, onClose }) => {\r\n clientMessage = onMessage;\r\n clientClose = onClose;\r\n },\r\n close: closeBoth,\r\n label: \"in-memory\",\r\n };\r\n\r\n const serverEndpoint: IInMemoryServerEndpoint = {\r\n send: (frame) => {\r\n if (!open) return;\r\n queueMicrotask(() => clientMessage?.(frame));\r\n },\r\n onMessage: (handler) => {\r\n serverMessage = handler;\r\n },\r\n onClose: (handler) => {\r\n serverClose = handler;\r\n },\r\n close: closeBoth,\r\n };\r\n\r\n return { clientChannel, serverEndpoint };\r\n}\r\n","import {\r\n createInMemoryChannelPair,\r\n type IInMemoryServerEndpoint,\r\n} from \"./createInMemoryChannel\";\r\nimport type { IDuplexCarrierSource } from \"../../Carrier.types\";\r\n\r\nexport interface IInMemoryCarrier {\r\n /** The connector end — pass as the `carrier` to one of `connectChannel`'s transports. */\r\n carrier: IDuplexCarrierSource;\r\n /** The acceptor end — wire into an `AcceptorHandler` (`send` + `receive`). */\r\n serverEndpoint: IInMemoryServerEndpoint;\r\n}\r\n\r\n/**\r\n * A loopback duplex carrier with no socket — two cross-wired in-process ends. The connector end is an\r\n * {@link IDuplexCarrierSource} for `connectChannel`; the acceptor end plugs into an `AcceptorHandler`.\r\n * Ideal for tests and for running two runtimes in one process, or proving a non-WS carrier end to end.\r\n */\r\nexport function inMemoryCarrier(): IInMemoryCarrier {\r\n const { clientChannel, serverEndpoint } = createInMemoryChannelPair();\r\n return {\r\n carrier: {\r\n carrierLabel: \"memory\",\r\n open: () => clientChannel,\r\n getCacheKey: () => [\"memory\"],\r\n },\r\n serverEndpoint,\r\n };\r\n}\r\n","import type { IDuplexCarrier } from \"../../Carrier.types\";\r\n\r\n/**\r\n * The slice of the `RTCDataChannel` surface this adapter uses — declared structurally so it accepts the\r\n * browser `RTCDataChannel`, React-Native (`react-native-webrtc`), or any node-webrtc shim without a hard\r\n * dependency on a specific DOM/RN type. A real `RTCDataChannel` satisfies it as-is.\r\n */\r\nexport interface IRtcDataChannelLike {\r\n readyState: string; // \"connecting\" | \"open\" | \"closing\" | \"closed\"\r\n binaryType: string;\r\n label?: string;\r\n send(data: string | ArrayBuffer | ArrayBufferView): void;\r\n close(): void;\r\n addEventListener(type: string, listener: (event: any) => void, options?: unknown): void;\r\n}\r\n\r\n/**\r\n * Adapt a WebRTC `RTCDataChannel` to the carrier-agnostic {@link IDuplexCarrier}, so two browsers\r\n * (or two mobile apps) linked peer-to-peer — no server in the middle — run the *same* secure session as\r\n * a WebSocket. Hand it to `createSecureLinkTransport({ openChannel: () => rtcDataChannelByteChannel(dc) })`.\r\n *\r\n * The data channel must already be created (its negotiation/signaling is the app's concern); this only\r\n * drives bytes over it. Binary frames are requested as `ArrayBuffer` so the binary session codec unpacks\r\n * them synchronously; a `Blob` (if the channel hands one back) is normalized to a buffer.\r\n */\r\nexport function rtcDataChannelByteChannel(dc: IRtcDataChannelLike): IDuplexCarrier {\r\n dc.binaryType = \"arraybuffer\";\r\n\r\n let intentional = false;\r\n let onMessage: ((frame: string | ArrayBuffer | Uint8Array) => void) | undefined;\r\n let onClose: (() => void) | undefined;\r\n const preAttach: (string | ArrayBuffer | Uint8Array)[] = [];\r\n\r\n const deliver = (frame: string | ArrayBuffer | Uint8Array): void => {\r\n if (onMessage != null) onMessage(frame);\r\n else preAttach.push(frame);\r\n };\r\n\r\n dc.addEventListener(\"message\", async (event: { data: unknown }) => {\r\n const frame = await normalizeFrame(event.data);\r\n if (frame !== undefined) deliver(frame);\r\n });\r\n dc.addEventListener(\"close\", () => {\r\n if (!intentional) console.error(\"RTCDataChannel closed\");\r\n onClose?.();\r\n });\r\n dc.addEventListener(\"error\", (event: unknown) => {\r\n console.error(\"RTCDataChannel error:\", event);\r\n onClose?.();\r\n });\r\n\r\n const ready = new Promise<void>((resolve, reject) => {\r\n if (dc.readyState === \"open\") {\r\n resolve();\r\n return;\r\n }\r\n dc.addEventListener(\"open\", () => resolve(), { once: true });\r\n dc.addEventListener(\"error\", (event: unknown) => reject(event), { once: true });\r\n dc.addEventListener(\"close\", () => reject(new Error(\"RTCDataChannel closed before open\")), {\r\n once: true,\r\n });\r\n });\r\n\r\n return {\r\n ready,\r\n isOpen: () => dc.readyState === \"open\",\r\n send: (frame) => {\r\n // A pooled `Uint8Array` may be backed by a `SharedArrayBuffer` that `send` rejects — copy into a\r\n // fresh view (mirrors the WebSocket `sendFrame` guard).\r\n if (typeof frame === \"string\" || frame instanceof ArrayBuffer) dc.send(frame);\r\n else dc.send(new Uint8Array(frame));\r\n },\r\n attach: (handlers) => {\r\n onMessage = handlers.onMessage;\r\n onClose = handlers.onClose;\r\n for (const frame of preAttach) handlers.onMessage(frame);\r\n preAttach.length = 0;\r\n },\r\n close: () => {\r\n intentional = true;\r\n try {\r\n dc.close();\r\n } catch {\r\n // already closing/closed — the close listener still runs cleanup\r\n }\r\n },\r\n get label() {\r\n return dc.label != null && dc.label !== \"\" ? dc.label : undefined;\r\n },\r\n };\r\n}\r\n\r\nasync function normalizeFrame(\r\n data: unknown,\r\n): Promise<string | ArrayBuffer | Uint8Array | undefined> {\r\n if (typeof data === \"string\" || data instanceof ArrayBuffer || data instanceof Uint8Array) {\r\n return data;\r\n }\r\n if (typeof Blob !== \"undefined\" && data instanceof Blob) {\r\n return await data.arrayBuffer();\r\n }\r\n return undefined;\r\n}\r\n","import type { ITransportRouteActionParams, ITransportRouteInfo } from \"../../../Transport.types\";\r\nimport {\r\n type IRtcDataChannelLike,\r\n rtcDataChannelByteChannel,\r\n} from \"./rtcDataChannelByteChannel\";\r\nimport type { IDuplexCarrierSource } from \"../../Carrier.types\";\r\n\r\nexport interface IRtcCarrierOptions {\r\n getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];\r\n getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;\r\n}\r\n\r\n/**\r\n * A WebRTC {@link IDuplexCarrierSource} over an already-negotiated `RTCDataChannel` (signaling is the\r\n * app's concern). Pass it as a `carrier` to `connectChannel` so two browsers/apps linked peer-to-peer run\r\n * the identical secure session as a WebSocket.\r\n */\r\nexport function rtcCarrier(\r\n dataChannel: IRtcDataChannelLike,\r\n options: IRtcCarrierOptions = {},\r\n): IDuplexCarrierSource {\r\n return {\r\n carrierLabel: \"webrtc\",\r\n open: () => rtcDataChannelByteChannel(dataChannel),\r\n getCacheKey: options.getTransportCacheKey ?? (() => [\"webrtc\"]),\r\n getRouteInfo: options.getRouteInfo,\r\n };\r\n}\r\n","import { err } from \"@nice-code/error\";\r\nimport { err_nice_transport } from \"../../../err_nice_transport\";\r\n\r\nexport enum EErrId_NiceTransport_WebSocket {\r\n ws_disconnected = \"ws_disconnected\",\r\n ws_create_failed = \"ws_create_failed\",\r\n ws_error = \"ws_error\",\r\n}\r\n\r\nexport const err_nice_transport_ws = err_nice_transport.createChildDomain({\r\n domain: \"ws_transport\",\r\n schema: {\r\n [EErrId_NiceTransport_WebSocket.ws_disconnected]: err<Record<string, never>>({\r\n message: () => `WebSocket transport disconnected.`,\r\n }),\r\n [EErrId_NiceTransport_WebSocket.ws_create_failed]: err<{\r\n originalError?: Error;\r\n }>({\r\n message: ({ originalError }) =>\r\n `Failed to create WebSocket transport.${originalError ? ` Original error: ${originalError.message}` : \"\"}`,\r\n }),\r\n [EErrId_NiceTransport_WebSocket.ws_error]: err<{\r\n originalError?: Error;\r\n }>({\r\n message: ({ originalError }) =>\r\n `WebSocket transport error.${originalError ? ` Original error: ${originalError.message}` : \"\"}`,\r\n }),\r\n },\r\n});\r\n","/**\r\n * Send a text or binary frame over a socket. A binary formatter may hand back a `Uint8Array` whose\r\n * backing buffer is typed as `ArrayBufferLike` (msgpackr pools buffers / may be `SharedArrayBuffer`),\r\n * which `WebSocket.send`'s `BufferSource` parameter rejects — copy it into a fresh `ArrayBuffer`-backed\r\n * view so the type (and the bytes) are safe to send.\r\n */\r\nexport function sendFrame(ws: WebSocket, data: string | Uint8Array | ArrayBuffer): void {\r\n if (typeof data === \"string\" || data instanceof ArrayBuffer) {\r\n ws.send(data);\r\n return;\r\n }\r\n ws.send(new Uint8Array(data));\r\n}\r\n\r\n/** Compact a WebSocket URL to `host/pathname` for devtools display, falling back to the raw url. */\r\nexport function shortWs(url: string): string {\r\n try {\r\n const u = new URL(url);\r\n return `${u.host}${u.pathname}`;\r\n } catch {\r\n return url;\r\n }\r\n}\r\n","import type { IDuplexCarrier } from \"../../Carrier.types\";\r\nimport { sendFrame } from \"./ws_util\";\r\n\r\n/**\r\n * Adapt a `WebSocket` to the carrier-agnostic {@link IDuplexCarrier}, so the WebSocket becomes\r\n * \"just another carrier\" under the shared secure session. It owns every WebSocket-specific concern —\r\n * awaiting `open`, normalizing `Blob` frames to bytes, suppressing the log on a deliberate `close`, and\r\n * buffering any frame that arrives before the session attaches its handler — leaving the session itself\r\n * carrier-neutral.\r\n */\r\nexport function webSocketByteChannel(ws: WebSocket): IDuplexCarrier {\r\n let intentional = false;\r\n let onMessage: ((frame: string | ArrayBuffer | Uint8Array) => void) | undefined;\r\n let onClose: (() => void) | undefined;\r\n // Frames that land before the session calls `attach` (none expected in practice, but never lose one).\r\n const preAttach: (string | ArrayBuffer | Uint8Array)[] = [];\r\n\r\n const deliver = (frame: string | ArrayBuffer | Uint8Array): void => {\r\n if (onMessage != null) onMessage(frame);\r\n else preAttach.push(frame);\r\n };\r\n\r\n ws.addEventListener(\"message\", async (event) => {\r\n const frame = await normalizeFrame((event as MessageEvent).data);\r\n if (frame !== undefined) deliver(frame);\r\n });\r\n ws.addEventListener(\"close\", (event) => {\r\n if (!intentional) console.error(\"WebSocket closed:\", event);\r\n onClose?.();\r\n });\r\n ws.addEventListener(\"error\", (event) => {\r\n console.error(\"WebSocket error:\", event);\r\n onClose?.();\r\n });\r\n\r\n const ready = new Promise<void>((resolve, reject) => {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n resolve();\r\n return;\r\n }\r\n ws.addEventListener(\"open\", () => resolve(), { once: true });\r\n ws.addEventListener(\"error\", (event) => reject(event), { once: true });\r\n ws.addEventListener(\r\n \"close\",\r\n (event) =>\r\n reject(new Error(`WebSocket closed before open: code=${(event as CloseEvent).code}`)),\r\n { once: true },\r\n );\r\n });\r\n\r\n return {\r\n ready,\r\n isOpen: () => ws.readyState === WebSocket.OPEN,\r\n send: (frame) => sendFrame(ws, frame),\r\n attach: (handlers) => {\r\n onMessage = handlers.onMessage;\r\n onClose = handlers.onClose;\r\n for (const frame of preAttach) handlers.onMessage(frame);\r\n preAttach.length = 0;\r\n },\r\n close: () => {\r\n intentional = true;\r\n try {\r\n ws.close();\r\n } catch {\r\n // already closing/closed — the close listener still runs cleanup\r\n }\r\n },\r\n get label() {\r\n return ws.url != null && ws.url !== \"\" ? ws.url : undefined;\r\n },\r\n };\r\n}\r\n\r\n/** Accept text + binary frames (ArrayBuffer / Uint8Array / Blob); Blobs are converted to a buffer. */\r\nasync function normalizeFrame(\r\n data: unknown,\r\n): Promise<string | ArrayBuffer | Uint8Array | undefined> {\r\n if (typeof data === \"string\" || data instanceof ArrayBuffer || data instanceof Uint8Array) {\r\n return data;\r\n }\r\n if (typeof Blob !== \"undefined\" && data instanceof Blob) {\r\n return await data.arrayBuffer();\r\n }\r\n return undefined;\r\n}\r\n","import type { ITransportRouteActionParams, ITransportRouteInfo } from \"../../../Transport.types\";\nimport { webSocketByteChannel } from \"./webSocketByteChannel\";\nimport { shortWs } from \"./ws_util\";\nimport type { IDuplexCarrierSource } from \"../../Carrier.types\";\n\n/** The WebSocket an action's socket is opened against (derived per action from the route params). */\nexport interface IWsCarrierRequest {\n url: string;\n}\n\nexport interface IWsCarrierOptions {\n /** Override the reuse key (defaults to `[url]`, so one socket is shared per endpoint). */\n getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];\n /** Override the devtools route info for a specific action. */\n getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;\n}\n\n/**\n * A WebSocket {@link IDuplexCarrierSource}: opens an `arraybuffer` socket (cached per endpoint) and adapts\n * it to a carrier. Pass it as a `carrier` to `connectChannel` — the WebSocket is now \"just another\n * carrier\" under the shared secure session, with no WS-specific transport class.\n *\n * `createRequest` derives the socket URL per action (keep it simple with `() => ({ url })`), so dynamic\n * endpoints (e.g. a per-run query param) need no `createWebSocket` escape hatch.\n */\nexport function wsCarrier(\n createRequest: (input: ITransportRouteActionParams) => IWsCarrierRequest,\n options: IWsCarrierOptions = {},\n): IDuplexCarrierSource {\n return {\n carrierLabel: \"ws\",\n open: (input) => webSocketByteChannel(defaultWebSocket(createRequest(input).url)),\n getCacheKey: options.getTransportCacheKey ?? ((input) => [createRequest(input).url]),\n getRouteInfo:\n options.getRouteInfo ??\n ((input) => {\n const { url } = createRequest(input);\n return { carrierLabel: \"ws\", url, summary: `ws ${shortWs(url)}` };\n }),\n };\n}\n\nfunction defaultWebSocket(url: string): WebSocket {\n const ws = new WebSocket(url);\n // Binary responses as ArrayBuffer (not Blob) so the session unpacks them synchronously.\n ws.binaryType = \"arraybuffer\";\n return ws;\n}\n","import type { ITransportRouteActionParams, ITransportRouteInfo } from \"../../../Transport.types\";\r\nimport type { IExchangeCarrier, IExchangeCarrierSource, TFrame } from \"../../Carrier.types\";\r\n\r\n/** The HTTP request an action is sent over (the body is supplied by the secure exchange session). */\r\nexport interface IHttpCarrierRequest {\r\n url: string;\r\n headers?: Record<string, string>;\r\n}\r\n\r\n/** The slice of `fetch` the carrier uses — a structural type so callers (and tests) needn't match the\r\n * full platform `fetch` (Bun's adds `preconnect`, etc.). The global `fetch` satisfies it. */\r\nexport type TCarrierFetch = (input: string, init?: RequestInit) => Promise<Response>;\r\n\r\nexport interface IHttpCarrierOptions {\r\n /** Override the reuse key (defaults to `[url]`, so one session is shared per endpoint). */\r\n getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];\r\n /** Override the devtools route info for a specific action. */\r\n getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;\r\n /** Override `fetch` (e.g. to route to an in-memory handler in tests). Defaults to global `fetch`. */\r\n fetch?: TCarrierFetch;\r\n}\r\n\r\nfunction shortPath(url: string): string {\r\n try {\r\n return new URL(url).pathname || url;\r\n } catch {\r\n return url;\r\n }\r\n}\r\n\r\n/**\r\n * An HTTP {@link IExchangeCarrierSource}: each `exchange` POSTs one frame body to the action endpoint and\r\n * resolves with the response body as the single correlated reply. Pass it as a `carrier` to\r\n * `connectChannel` — a secure HTTP transport then runs the *same* secure session as a duplex carrier\r\n * (handshake → token → encrypted frames), the request/reply correlation provided for free by the HTTP\r\n * transaction.\r\n *\r\n * `createRequest` derives the URL/headers per action (keep it simple with `() => ({ url })`). The body is\r\n * the session's responsibility, so it is never built here.\r\n */\r\nexport function httpCarrier(\r\n createRequest: (input: ITransportRouteActionParams) => IHttpCarrierRequest,\r\n options: IHttpCarrierOptions = {},\r\n): IExchangeCarrierSource {\r\n const doFetch = options.fetch ?? fetch;\r\n\r\n return {\r\n shape: \"exchange\",\r\n carrierLabel: \"http\",\r\n open: (input): IExchangeCarrier => {\r\n const request = createRequest(input);\r\n return {\r\n label: request.url,\r\n exchange: async (frame: TFrame, opts): Promise<TFrame> => {\r\n const res = await doFetch(request.url, {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\", ...request.headers },\r\n body: typeof frame === \"string\" ? frame : new Uint8Array(frame),\r\n signal: opts?.signal,\r\n });\r\n return await res.text();\r\n },\r\n };\r\n },\r\n getCacheKey: options.getTransportCacheKey ?? ((input) => [createRequest(input).url]),\r\n getRouteInfo:\r\n options.getRouteInfo ??\r\n ((input) => {\r\n const { url } = createRequest(input);\r\n return { carrierLabel: \"http\", method: \"POST\", url, summary: `POST ${shortPath(url)}` };\r\n }),\r\n };\r\n}\r\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_httpAcceptorCarrier = require("../../httpAcceptorCarrier-OnJxzsAD.cjs");
2
+ const require_httpAcceptorCarrier = require("../../httpAcceptorCarrier-C3S_bDkL.cjs");
3
3
  let _nice_code_util = require("@nice-code/util");
4
4
  //#region src/platform/cloudflare/index.ts
5
5
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["wsAcceptorCarrier","httpAcceptorCarrier","serveHost"],"sources":["../../../src/platform/cloudflare/index.ts"],"sourcesContent":["import {\r\n createDurableObjectStorageAdapter,\r\n type StorageAdapter,\r\n type TCreateDurableObjectStorageOptions,\r\n} from \"@nice-code/util\";\r\nimport type { ActionDomain } from \"../../ActionDefinition/Domain/ActionDomain\";\r\nimport type { ActionRuntime } from \"../../ActionRuntime/ActionRuntime\";\r\nimport type { ISecureChannel } from \"../../ActionRuntime/Channel/secureChannel\";\r\nimport type {\r\n IChannelServer,\r\n IServeConnectionStateOptions,\r\n} from \"../../ActionRuntime/Channel/serveChannel\";\r\nimport {\r\n type IChannelHostAdapter,\r\n serveHost,\r\n type TServeHostOptions,\r\n} from \"../../ActionRuntime/Channel/serveHost\";\r\nimport type { ConnectionStateStore } from \"../../ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/ConnectionStateStore\";\r\nimport type {\r\n IDuplexAcceptorCarrier,\r\n TAcceptorCarrier,\r\n} from \"../../ActionRuntime/Transport/Carrier/AcceptorCarrier.types\";\r\nimport { wsAcceptorCarrier } from \"../../ActionRuntime/Transport/Carrier/duplex/ws/wsAcceptorCarrier\";\r\nimport { httpAcceptorCarrier } from \"../../ActionRuntime/Transport/Carrier/exchange/http/httpAcceptorCarrier\";\r\n\r\n/**\r\n * Cloudflare-specific helpers for `@nice-code/action`, imported from `@nice-code/action/platform/cloudflare`.\r\n * They collapse the Durable Object boilerplate (the `WebSocketPair` upgrade, hibernation attachment wiring,\r\n * and DO-storage adapter) into one-liners you hand to `serveChannel`. The core library stays\r\n * platform-agnostic — nothing here is reachable from the main entry.\r\n *\r\n * The Workers runtime surface this module needs is declared *structurally* (and the two globals it\r\n * constructs are declared module-locally below) rather than pulled from `@cloudflare/workers-types`, so the\r\n * library's own DOM-lib build never clashes with that package's global `Response`/`WebSocket` redefinitions.\r\n * A real `DurableObjectState` and its hibernatable `WebSocket`s satisfy these shapes.\r\n */\r\n\r\ntype TDurableObjectStorage = TCreateDurableObjectStorageOptions[\"durableObjectStorage\"];\r\n\r\n/** The slice of a Durable Object's hibernatable WebSocket these helpers touch. */\r\nexport interface IDurableObjectWebSocket {\r\n send(data: string | ArrayBuffer | Uint8Array): void;\r\n serializeAttachment(value: unknown): void;\r\n // Mirrors the Workers runtime's `any` return so a typed connection binding round-trips without a cast.\r\n deserializeAttachment(): any;\r\n}\r\n\r\n/** The slice of a Durable Object's `state` (its `ctx`) these helpers touch. */\r\nexport interface IDurableObjectContext {\r\n storage: TDurableObjectStorage;\r\n getWebSockets(): IDurableObjectWebSocket[];\r\n acceptWebSocket(ws: IDurableObjectWebSocket): void;\r\n /** Register a runtime-answered keepalive so pings never wake the DO. */\r\n setWebSocketAutoResponse(pair: IWebSocketRequestResponsePair): void;\r\n}\r\n\r\n/** An `IChannelServer` whose connections are a Durable Object's hibernatable WebSockets — the type to\r\n * store the result of `serveChannel(...)` in when serving over {@link durableObjectWsCarrier}. `TApp` is the\r\n * per-connection app-state type when `connectionState` is used (defaults to `unknown` otherwise). */\r\nexport type TDurableObjectChannelServer<TApp = unknown> = IChannelServer<\r\n IDurableObjectWebSocket,\r\n TApp\r\n>;\r\n\r\n// Workers runtime globals, declared module-locally (the runtime provides them at deploy time). Declaring\r\n// them here keeps them out of the package's global scope, so the DOM lib's `Response`/`WebSocket` stand\r\n// elsewhere. The `Response` constructor type still returns the DOM `Response` — only its init gains the\r\n// Workers-only `webSocket` field.\r\ndeclare const WebSocketPair: {\r\n new (): { 0: IDurableObjectWebSocket; 1: IDurableObjectWebSocket };\r\n};\r\ndeclare const Response: {\r\n new (\r\n body: BodyInit | null,\r\n init?: {\r\n status?: number;\r\n statusText?: string;\r\n headers?: HeadersInit;\r\n webSocket?: IDurableObjectWebSocket;\r\n },\r\n ): Response;\r\n};\r\n/** The keepalive pair shape — just the fields the Workers runtime's `WebSocketRequestResponsePair` exposes. */\r\ninterface IWebSocketRequestResponsePair {\r\n readonly request: string;\r\n readonly response: string;\r\n}\r\ndeclare const WebSocketRequestResponsePair: {\r\n new (request: string, response: string): IWebSocketRequestResponsePair;\r\n};\r\n\r\nexport interface IDurableObjectWsCarrierOptions {\r\n /**\r\n * Whether each socket runs the secure handshake (default `true`). Pass `false` for a plain WS endpoint —\r\n * then `serveChannel` needs no `storage` for this carrier.\r\n */\r\n secure?: boolean;\r\n}\r\n\r\n/**\r\n * Build a hibernatable-WebSocket acceptor carrier for a Durable Object in one call — the `send`, the\r\n * `WebSocketPair` upgrade, and the hibernation attachment hooks all derived from the DO's `ctx`. Hand it\r\n * straight to `serveChannel`'s `carriers`, and forward the DO's socket events to the returned handle:\r\n * ```ts\r\n * const ws = durableObjectWsCarrier(this.ctx);\r\n * const server = serveChannel(runtime, channel, {\r\n * clientEnv,\r\n * storage: durableObjectStorage(this.ctx, { keyPrefix: \"ws:\" }),\r\n * handlers: [localHandler],\r\n * carriers: [ws, httpAcceptorCarrier()],\r\n * });\r\n * // webSocketMessage(c, m) => ws.receive(c, m);\r\n * // webSocketClose/Error(c) => ws.drop(c);\r\n * ```\r\n *\r\n * The carrier exposes the DO's socket attachment to `serveChannel`, which persists the routing binding\r\n * there and replays it on wake — and, when `connectionState` is requested, co-stores per-connection app\r\n * state in the *same* attachment, so both survive eviction without the DO wiring any of it by hand.\r\n */\r\nexport function durableObjectWsCarrier(\r\n ctx: IDurableObjectContext,\r\n options: IDurableObjectWsCarrierOptions = {},\r\n): IDuplexAcceptorCarrier<IDurableObjectWebSocket> {\r\n return wsAcceptorCarrier<IDurableObjectWebSocket>({\r\n secure: options.secure,\r\n send: (ws, frame) => ws.send(frame),\r\n upgrade: () => {\r\n const pair = new WebSocketPair();\r\n const client = pair[0];\r\n const server = pair[1];\r\n // Hibernatable WebSocket — the DO can sleep between messages.\r\n ctx.acceptWebSocket(server);\r\n return new Response(null, { status: 101, webSocket: client });\r\n },\r\n // Raw access to each socket's attachment; `serveChannel` owns the composite (binding + app) layout.\r\n attachmentStore: {\r\n getConnections: () => ctx.getWebSockets(),\r\n read: (ws) => ws.deserializeAttachment(),\r\n write: (ws, value) => ws.serializeAttachment(value),\r\n },\r\n });\r\n}\r\n\r\nexport interface IDurableObjectStorageOptions {\r\n /** Namespace prefix for every key (e.g. `\"demo-ws:\"`), so several adapters can share one DO storage. */\r\n keyPrefix?: string;\r\n}\r\n\r\n/**\r\n * Wrap a Durable Object's storage as a {@link StorageAdapter} for `serveChannel`'s `storage` — sugar over\r\n * `createDurableObjectStorageAdapter({ durableObjectStorage: ctx.storage, … })` so a DO needs one import.\r\n */\r\nexport function durableObjectStorage(\r\n ctx: IDurableObjectContext,\r\n options: IDurableObjectStorageOptions = {},\r\n): StorageAdapter {\r\n return createDurableObjectStorageAdapter({\r\n durableObjectStorage: ctx.storage,\r\n keyPrefix: options.keyPrefix,\r\n });\r\n}\r\n\r\nexport interface ICloudflareDurableObjectHostOptions {\r\n /** Namespace prefix for the DO-storage crypto identity keys (e.g. `\"lobby-ws:\"`). */\r\n keyPrefix?: string;\r\n /**\r\n * The HTTP fallback that sits beside the WebSocket: `\"plain\"` (default — POSTs the raw action wire, the\r\n * usual fallback for a public client), `\"secure\"` (the full handshake-protected exchange, sharing the WS\r\n * identity), or `false` (WebSocket only).\r\n */\r\n httpFallback?: \"plain\" | \"secure\" | false;\r\n /** Whether the WebSocket runs the secure handshake (default `true`). `false` = a plain WS endpoint. */\r\n secure?: boolean;\r\n}\r\n\r\n/**\r\n * Build the {@link IChannelHostAdapter} for a Durable Object in one call — the entire repeated transport\r\n * stack a DO would otherwise assemble by hand: a hibernatable secure WebSocket carrier, an HTTP fallback,\r\n * the DO-storage-backed crypto identity, and a runtime-answered `ping`/`pong` keepalive (so pings never\r\n * wake the DO). Hand it to {@link serveHost}, or use {@link serveDurableObject} which composes both.\r\n */\r\nexport function cloudflareDurableObjectHost(\r\n ctx: IDurableObjectContext,\r\n options: ICloudflareDurableObjectHostOptions = {},\r\n): IChannelHostAdapter<IDurableObjectWebSocket> {\r\n const httpFallback = options.httpFallback ?? \"plain\";\r\n const carriers: TAcceptorCarrier<IDurableObjectWebSocket>[] = [\r\n durableObjectWsCarrier(ctx, { secure: options.secure }),\r\n ];\r\n if (httpFallback !== false) {\r\n carriers.push(httpAcceptorCarrier({ secure: httpFallback === \"secure\" }));\r\n }\r\n\r\n return {\r\n carriers,\r\n storage: durableObjectStorage(ctx, { keyPrefix: options.keyPrefix }),\r\n onServed: () => {\r\n // Keepalive answered by the runtime itself — pings never wake the DO.\r\n ctx.setWebSocketAutoResponse(new WebSocketRequestResponsePair(\"ping\", \"pong\"));\r\n },\r\n };\r\n}\r\n\r\n/** {@link serveDurableObject}'s options: the `serveHost` surface + the DO runtime + the host knobs. */\r\nexport type TServeDurableObjectOptions<\r\n TO_ACCEPTOR extends readonly ActionDomain<any>[],\r\n TApp = unknown,\r\n> = TServeHostOptions<TO_ACCEPTOR, IDurableObjectWebSocket, TApp> &\r\n ICloudflareDurableObjectHostOptions & {\r\n /** This DO's runtime (e.g. `new ActionRuntime(coord.withPersistentId(ctx.id.toString()))`). */\r\n runtime: ActionRuntime;\r\n };\r\n\r\n/**\r\n * Serve a secure channel from a Durable Object in one call — the whole transport stack\r\n * ({@link cloudflareDurableObjectHost}: hibernatable secure WebSocket + HTTP fallback + DO-storage crypto\r\n * identity + keepalive) folded in, leaving the DO to forward its four socket lifecycle methods to the\r\n * returned server's `fetch` / `receive` / `drop`:\r\n * ```ts\r\n * const server = serveDurableObject(this.ctx, lobbyChannel, {\r\n * runtime, clientEnv,\r\n * connectionState: { schema: vs_player }, // optional, survives hibernation\r\n * channelCases: { join: (action, conn) => { conn.setState(action.input); conn.broadcast(…); } },\r\n * });\r\n * // fetch(req) => server.fetch(req)\r\n * // webSocketMessage(ws, m) => server.receive(ws, m)\r\n * // webSocketClose/Error(ws)=> server.drop(ws)\r\n * ```\r\n * Passing `connectionState` narrows the return so `server.connections` is non-optional.\r\n */\r\nexport function serveDurableObject<\r\n TO_ACCEPTOR extends readonly ActionDomain<any>[],\r\n TO_CONNECTOR extends readonly ActionDomain<any>[],\r\n TApp,\r\n>(\r\n ctx: IDurableObjectContext,\r\n channel: ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>,\r\n options: TServeDurableObjectOptions<TO_ACCEPTOR, TApp> & {\r\n connectionState: IServeConnectionStateOptions<TApp>;\r\n },\r\n): TDurableObjectChannelServer<TApp> & {\r\n connections: ConnectionStateStore<IDurableObjectWebSocket, TApp>;\r\n};\r\nexport function serveDurableObject<\r\n TO_ACCEPTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[],\r\n TO_CONNECTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[],\r\n TApp = unknown,\r\n>(\r\n ctx: IDurableObjectContext,\r\n channel: ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>,\r\n options: TServeDurableObjectOptions<TO_ACCEPTOR, TApp>,\r\n): TDurableObjectChannelServer<TApp>;\r\nexport function serveDurableObject(\r\n ctx: IDurableObjectContext,\r\n channel: ISecureChannel<readonly ActionDomain<any>[], readonly ActionDomain<any>[]>,\r\n options: TServeDurableObjectOptions<readonly ActionDomain<any>[], any>,\r\n): TDurableObjectChannelServer<any> {\r\n const { runtime, keyPrefix, httpFallback, secure, ...serveOptions } = options;\r\n const host = cloudflareDurableObjectHost(ctx, { keyPrefix, httpFallback, secure });\r\n return serveHost(runtime, channel, host, serveOptions);\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAuHA,SAAgB,uBACd,KACA,UAA0C,CAAC,GACM;CACjD,OAAOA,4BAAAA,kBAA2C;EAChD,QAAQ,QAAQ;EAChB,OAAO,IAAI,UAAU,GAAG,KAAK,KAAK;EAClC,eAAe;GACb,MAAM,OAAO,IAAI,cAAc;GAC/B,MAAM,SAAS,KAAK;GACpB,MAAM,SAAS,KAAK;GAEpB,IAAI,gBAAgB,MAAM;GAC1B,OAAO,IAAI,SAAS,MAAM;IAAE,QAAQ;IAAK,WAAW;GAAO,CAAC;EAC9D;EAEA,iBAAiB;GACf,sBAAsB,IAAI,cAAc;GACxC,OAAO,OAAO,GAAG,sBAAsB;GACvC,QAAQ,IAAI,UAAU,GAAG,oBAAoB,KAAK;EACpD;CACF,CAAC;AACH;;;;;AAWA,SAAgB,qBACd,KACA,UAAwC,CAAC,GACzB;CAChB,QAAA,GAAA,gBAAA,kCAAA,CAAyC;EACvC,sBAAsB,IAAI;EAC1B,WAAW,QAAQ;CACrB,CAAC;AACH;;;;;;;AAqBA,SAAgB,4BACd,KACA,UAA+C,CAAC,GACF;CAC9C,MAAM,eAAe,QAAQ,gBAAgB;CAC7C,MAAM,WAAwD,CAC5D,uBAAuB,KAAK,EAAE,QAAQ,QAAQ,OAAO,CAAC,CACxD;CACA,IAAI,iBAAiB,OACnB,SAAS,KAAKC,4BAAAA,oBAAoB,EAAE,QAAQ,iBAAiB,SAAS,CAAC,CAAC;CAG1E,OAAO;EACL;EACA,SAAS,qBAAqB,KAAK,EAAE,WAAW,QAAQ,UAAU,CAAC;EACnE,gBAAgB;GAEd,IAAI,yBAAyB,IAAI,6BAA6B,QAAQ,MAAM,CAAC;EAC/E;CACF;AACF;AAmDA,SAAgB,mBACd,KACA,SACA,SACkC;CAClC,MAAM,EAAE,SAAS,WAAW,cAAc,QAAQ,GAAG,iBAAiB;CAEtE,OAAOC,4BAAAA,UAAU,SAAS,SADb,4BAA4B,KAAK;EAAE;EAAW;EAAc;CAAO,CAC1C,GAAG,YAAY;AACvD"}
1
+ {"version":3,"file":"index.cjs","names":["wsAcceptorCarrier","httpAcceptorCarrier","serveHost"],"sources":["../../../src/platform/cloudflare/index.ts"],"sourcesContent":["import {\r\n createDurableObjectStorageAdapter,\r\n type StorageAdapter,\r\n type TCreateDurableObjectStorageOptions,\r\n} from \"@nice-code/util\";\r\nimport type { ActionDomain } from \"../../ActionDefinition/Domain/ActionDomain\";\r\nimport type { ActionRuntime } from \"../../ActionRuntime/ActionRuntime\";\r\nimport type { IActionChannel } from \"../../ActionRuntime/Channel/ActionChannel\";\r\nimport type {\r\n IChannelServer,\r\n IServeConnectionStateOptions,\r\n} from \"../../ActionRuntime/Channel/serveChannel\";\r\nimport {\r\n type IChannelHostAdapter,\r\n serveHost,\r\n type TServeHostOptions,\r\n} from \"../../ActionRuntime/Channel/serveHost\";\r\nimport type { ConnectionStateStore } from \"../../ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/ConnectionStateStore\";\r\nimport type {\r\n IDuplexAcceptorCarrier,\r\n TAcceptorCarrier,\r\n} from \"../../ActionRuntime/Transport/Carrier/AcceptorCarrier.types\";\r\nimport { wsAcceptorCarrier } from \"../../ActionRuntime/Transport/Carrier/duplex/ws/wsAcceptorCarrier\";\r\nimport { httpAcceptorCarrier } from \"../../ActionRuntime/Transport/Carrier/exchange/http/httpAcceptorCarrier\";\r\n\r\n/**\r\n * Cloudflare-specific helpers for `@nice-code/action`, imported from `@nice-code/action/platform/cloudflare`.\r\n * They collapse the Durable Object boilerplate (the `WebSocketPair` upgrade, hibernation attachment wiring,\r\n * and DO-storage adapter) into one-liners you hand to `serveChannel`. The core library stays\r\n * platform-agnostic — nothing here is reachable from the main entry.\r\n *\r\n * The Workers runtime surface this module needs is declared *structurally* (and the two globals it\r\n * constructs are declared module-locally below) rather than pulled from `@cloudflare/workers-types`, so the\r\n * library's own DOM-lib build never clashes with that package's global `Response`/`WebSocket` redefinitions.\r\n * A real `DurableObjectState` and its hibernatable `WebSocket`s satisfy these shapes.\r\n */\r\n\r\ntype TDurableObjectStorage = TCreateDurableObjectStorageOptions[\"durableObjectStorage\"];\r\n\r\n/** The slice of a Durable Object's hibernatable WebSocket these helpers touch. */\r\nexport interface IDurableObjectWebSocket {\r\n send(data: string | ArrayBuffer | Uint8Array): void;\r\n serializeAttachment(value: unknown): void;\r\n // Mirrors the Workers runtime's `any` return so a typed connection binding round-trips without a cast.\r\n deserializeAttachment(): any;\r\n}\r\n\r\n/** The slice of a Durable Object's `state` (its `ctx`) these helpers touch. */\r\nexport interface IDurableObjectContext {\r\n storage: TDurableObjectStorage;\r\n getWebSockets(): IDurableObjectWebSocket[];\r\n acceptWebSocket(ws: IDurableObjectWebSocket): void;\r\n /** Register a runtime-answered keepalive so pings never wake the DO. */\r\n setWebSocketAutoResponse(pair: IWebSocketRequestResponsePair): void;\r\n}\r\n\r\n/** An `IChannelServer` whose connections are a Durable Object's hibernatable WebSockets — the type to\r\n * store the result of `serveChannel(...)` in when serving over {@link durableObjectWsCarrier}. `TApp` is the\r\n * per-connection app-state type when `connectionState` is used (defaults to `unknown` otherwise). */\r\nexport type TDurableObjectChannelServer<TApp = unknown> = IChannelServer<\r\n IDurableObjectWebSocket,\r\n TApp\r\n>;\r\n\r\n// Workers runtime globals, declared module-locally (the runtime provides them at deploy time). Declaring\r\n// them here keeps them out of the package's global scope, so the DOM lib's `Response`/`WebSocket` stand\r\n// elsewhere. The `Response` constructor type still returns the DOM `Response` — only its init gains the\r\n// Workers-only `webSocket` field.\r\ndeclare const WebSocketPair: {\r\n new (): { 0: IDurableObjectWebSocket; 1: IDurableObjectWebSocket };\r\n};\r\ndeclare const Response: {\r\n new (\r\n body: BodyInit | null,\r\n init?: {\r\n status?: number;\r\n statusText?: string;\r\n headers?: HeadersInit;\r\n webSocket?: IDurableObjectWebSocket;\r\n },\r\n ): Response;\r\n};\r\n/** The keepalive pair shape — just the fields the Workers runtime's `WebSocketRequestResponsePair` exposes. */\r\ninterface IWebSocketRequestResponsePair {\r\n readonly request: string;\r\n readonly response: string;\r\n}\r\ndeclare const WebSocketRequestResponsePair: {\r\n new (request: string, response: string): IWebSocketRequestResponsePair;\r\n};\r\n\r\nexport interface IDurableObjectWsCarrierOptions {\r\n /**\r\n * Whether each socket runs the secure handshake (default `true`). Pass `false` for a plain WS endpoint —\r\n * then `serveChannel` needs no `storage` for this carrier.\r\n */\r\n secure?: boolean;\r\n}\r\n\r\n/**\r\n * Build a hibernatable-WebSocket acceptor carrier for a Durable Object in one call — the `send`, the\r\n * `WebSocketPair` upgrade, and the hibernation attachment hooks all derived from the DO's `ctx`. Hand it\r\n * straight to `serveChannel`'s `carriers`, and forward the DO's socket events to the returned handle:\r\n * ```ts\r\n * const ws = durableObjectWsCarrier(this.ctx);\r\n * const server = serveChannel(runtime, channel, {\r\n * clientEnv,\r\n * storage: durableObjectStorage(this.ctx, { keyPrefix: \"ws:\" }),\r\n * handlers: [localHandler],\r\n * carriers: [ws, httpAcceptorCarrier()],\r\n * });\r\n * // webSocketMessage(c, m) => ws.receive(c, m);\r\n * // webSocketClose/Error(c) => ws.drop(c);\r\n * ```\r\n *\r\n * The carrier exposes the DO's socket attachment to `serveChannel`, which persists the routing binding\r\n * there and replays it on wake — and, when `connectionState` is requested, co-stores per-connection app\r\n * state in the *same* attachment, so both survive eviction without the DO wiring any of it by hand.\r\n */\r\nexport function durableObjectWsCarrier(\r\n ctx: IDurableObjectContext,\r\n options: IDurableObjectWsCarrierOptions = {},\r\n): IDuplexAcceptorCarrier<IDurableObjectWebSocket> {\r\n return wsAcceptorCarrier<IDurableObjectWebSocket>({\r\n secure: options.secure,\r\n send: (ws, frame) => ws.send(frame),\r\n upgrade: () => {\r\n const pair = new WebSocketPair();\r\n const client = pair[0];\r\n const server = pair[1];\r\n // Hibernatable WebSocket — the DO can sleep between messages.\r\n ctx.acceptWebSocket(server);\r\n return new Response(null, { status: 101, webSocket: client });\r\n },\r\n // Raw access to each socket's attachment; `serveChannel` owns the composite (binding + app) layout.\r\n attachmentStore: {\r\n getConnections: () => ctx.getWebSockets(),\r\n read: (ws) => ws.deserializeAttachment(),\r\n write: (ws, value) => ws.serializeAttachment(value),\r\n },\r\n });\r\n}\r\n\r\nexport interface IDurableObjectStorageOptions {\r\n /** Namespace prefix for every key (e.g. `\"demo-ws:\"`), so several adapters can share one DO storage. */\r\n keyPrefix?: string;\r\n}\r\n\r\n/**\r\n * Wrap a Durable Object's storage as a {@link StorageAdapter} for `serveChannel`'s `storage` — sugar over\r\n * `createDurableObjectStorageAdapter({ durableObjectStorage: ctx.storage, … })` so a DO needs one import.\r\n */\r\nexport function durableObjectStorage(\r\n ctx: IDurableObjectContext,\r\n options: IDurableObjectStorageOptions = {},\r\n): StorageAdapter {\r\n return createDurableObjectStorageAdapter({\r\n durableObjectStorage: ctx.storage,\r\n keyPrefix: options.keyPrefix,\r\n });\r\n}\r\n\r\nexport interface ICloudflareDurableObjectHostOptions {\r\n /** Namespace prefix for the DO-storage crypto identity keys (e.g. `\"lobby-ws:\"`). */\r\n keyPrefix?: string;\r\n /**\r\n * The HTTP fallback that sits beside the WebSocket: `\"plain\"` (default — POSTs the raw action wire, the\r\n * usual fallback for a public client), `\"secure\"` (the full handshake-protected exchange, sharing the WS\r\n * identity), or `false` (WebSocket only).\r\n */\r\n httpFallback?: \"plain\" | \"secure\" | false;\r\n /** Whether the WebSocket runs the secure handshake (default `true`). `false` = a plain WS endpoint. */\r\n secure?: boolean;\r\n}\r\n\r\n/**\r\n * Build the {@link IChannelHostAdapter} for a Durable Object in one call — the entire repeated transport\r\n * stack a DO would otherwise assemble by hand: a hibernatable secure WebSocket carrier, an HTTP fallback,\r\n * the DO-storage-backed crypto identity, and a runtime-answered `ping`/`pong` keepalive (so pings never\r\n * wake the DO). Hand it to {@link serveHost}, or use {@link serveDurableObject} which composes both.\r\n */\r\nexport function cloudflareDurableObjectHost(\r\n ctx: IDurableObjectContext,\r\n options: ICloudflareDurableObjectHostOptions = {},\r\n): IChannelHostAdapter<IDurableObjectWebSocket> {\r\n const httpFallback = options.httpFallback ?? \"plain\";\r\n const carriers: TAcceptorCarrier<IDurableObjectWebSocket>[] = [\r\n durableObjectWsCarrier(ctx, { secure: options.secure }),\r\n ];\r\n if (httpFallback !== false) {\r\n carriers.push(httpAcceptorCarrier({ secure: httpFallback === \"secure\" }));\r\n }\r\n\r\n return {\r\n carriers,\r\n storage: durableObjectStorage(ctx, { keyPrefix: options.keyPrefix }),\r\n onServed: () => {\r\n // Keepalive answered by the runtime itself — pings never wake the DO.\r\n ctx.setWebSocketAutoResponse(new WebSocketRequestResponsePair(\"ping\", \"pong\"));\r\n },\r\n };\r\n}\r\n\r\n/** {@link serveDurableObject}'s options: the `serveHost` surface + the DO runtime + the host knobs. */\r\nexport type TServeDurableObjectOptions<\r\n TO_ACCEPTOR extends readonly ActionDomain<any>[],\r\n TApp = unknown,\r\n> = TServeHostOptions<TO_ACCEPTOR, IDurableObjectWebSocket, TApp> &\r\n ICloudflareDurableObjectHostOptions & {\r\n /** This DO's runtime (e.g. `new ActionRuntime(coord.withPersistentId(ctx.id.toString()))`). */\r\n runtime: ActionRuntime;\r\n };\r\n\r\n/**\r\n * Serve a secure channel from a Durable Object in one call — the whole transport stack\r\n * ({@link cloudflareDurableObjectHost}: hibernatable secure WebSocket + HTTP fallback + DO-storage crypto\r\n * identity + keepalive) folded in, leaving the DO to forward its four socket lifecycle methods to the\r\n * returned server's `fetch` / `receive` / `drop`:\r\n * ```ts\r\n * const server = serveDurableObject(this.ctx, lobbyChannel, {\r\n * runtime, clientEnv,\r\n * connectionState: { schema: vs_player }, // optional, survives hibernation\r\n * channelCases: { join: (action, conn) => { conn.setState(action.input); conn.broadcast(…); } },\r\n * });\r\n * // fetch(req) => server.fetch(req)\r\n * // webSocketMessage(ws, m) => server.receive(ws, m)\r\n * // webSocketClose/Error(ws)=> server.drop(ws)\r\n * ```\r\n * Passing `connectionState` narrows the return so `server.connections` is non-optional.\r\n */\r\nexport function serveDurableObject<\r\n TO_ACCEPTOR extends readonly ActionDomain<any>[],\r\n TO_CONNECTOR extends readonly ActionDomain<any>[],\r\n TApp,\r\n>(\r\n ctx: IDurableObjectContext,\r\n channel: IActionChannel<TO_ACCEPTOR, TO_CONNECTOR>,\r\n options: TServeDurableObjectOptions<TO_ACCEPTOR, TApp> & {\r\n connectionState: IServeConnectionStateOptions<TApp>;\r\n },\r\n): TDurableObjectChannelServer<TApp> & {\r\n connections: ConnectionStateStore<IDurableObjectWebSocket, TApp>;\r\n};\r\nexport function serveDurableObject<\r\n TO_ACCEPTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[],\r\n TO_CONNECTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[],\r\n TApp = unknown,\r\n>(\r\n ctx: IDurableObjectContext,\r\n channel: IActionChannel<TO_ACCEPTOR, TO_CONNECTOR>,\r\n options: TServeDurableObjectOptions<TO_ACCEPTOR, TApp>,\r\n): TDurableObjectChannelServer<TApp>;\r\nexport function serveDurableObject(\r\n ctx: IDurableObjectContext,\r\n channel: IActionChannel<readonly ActionDomain<any>[], readonly ActionDomain<any>[]>,\r\n options: TServeDurableObjectOptions<readonly ActionDomain<any>[], any>,\r\n): TDurableObjectChannelServer<any> {\r\n const { runtime, keyPrefix, httpFallback, secure, ...serveOptions } = options;\r\n const host = cloudflareDurableObjectHost(ctx, { keyPrefix, httpFallback, secure });\r\n return serveHost(runtime, channel, host, serveOptions);\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAuHA,SAAgB,uBACd,KACA,UAA0C,CAAC,GACM;CACjD,OAAOA,4BAAAA,kBAA2C;EAChD,QAAQ,QAAQ;EAChB,OAAO,IAAI,UAAU,GAAG,KAAK,KAAK;EAClC,eAAe;GACb,MAAM,OAAO,IAAI,cAAc;GAC/B,MAAM,SAAS,KAAK;GACpB,MAAM,SAAS,KAAK;GAEpB,IAAI,gBAAgB,MAAM;GAC1B,OAAO,IAAI,SAAS,MAAM;IAAE,QAAQ;IAAK,WAAW;GAAO,CAAC;EAC9D;EAEA,iBAAiB;GACf,sBAAsB,IAAI,cAAc;GACxC,OAAO,OAAO,GAAG,sBAAsB;GACvC,QAAQ,IAAI,UAAU,GAAG,oBAAoB,KAAK;EACpD;CACF,CAAC;AACH;;;;;AAWA,SAAgB,qBACd,KACA,UAAwC,CAAC,GACzB;CAChB,QAAA,GAAA,gBAAA,kCAAA,CAAyC;EACvC,sBAAsB,IAAI;EAC1B,WAAW,QAAQ;CACrB,CAAC;AACH;;;;;;;AAqBA,SAAgB,4BACd,KACA,UAA+C,CAAC,GACF;CAC9C,MAAM,eAAe,QAAQ,gBAAgB;CAC7C,MAAM,WAAwD,CAC5D,uBAAuB,KAAK,EAAE,QAAQ,QAAQ,OAAO,CAAC,CACxD;CACA,IAAI,iBAAiB,OACnB,SAAS,KAAKC,4BAAAA,oBAAoB,EAAE,QAAQ,iBAAiB,SAAS,CAAC,CAAC;CAG1E,OAAO;EACL;EACA,SAAS,qBAAqB,KAAK,EAAE,WAAW,QAAQ,UAAU,CAAC;EACnE,gBAAgB;GAEd,IAAI,yBAAyB,IAAI,6BAA6B,QAAQ,MAAM,CAAC;EAC/E;CACF;AACF;AAmDA,SAAgB,mBACd,KACA,SACA,SACkC;CAClC,MAAM,EAAE,SAAS,WAAW,cAAc,QAAQ,GAAG,iBAAiB;CAEtE,OAAOC,4BAAAA,UAAU,SAAS,SADb,4BAA4B,KAAK;EAAE;EAAW;EAAc;CAAO,CAC1C,GAAG,YAAY;AACvD"}
@@ -1,4 +1,4 @@
1
- import { Ft as ConnectionStateStore, Ot as IDuplexAcceptorCarrier, St as IChannelServer, Tt as IServeConnectionStateOptions, Yt as ISecureChannel, bt as TServeHostOptions, gn as ActionDomain, vn as ActionRuntime, yt as IChannelHostAdapter } from "../../ActionPayload.types-L9k0LyBd.cjs";
1
+ import { _t as IDuplexAcceptorCarrier, ct as IChannelHostAdapter, dt as IChannelServer, kt as IActionChannel, l as ActionDomain, lt as TServeHostOptions, mt as IServeConnectionStateOptions, u as ActionRuntime, wt as ConnectionStateStore } from "../../AcceptorHandler-CxD0c1BE.cjs";
2
2
  import { StorageAdapter, TCreateDurableObjectStorageOptions } from "@nice-code/util";
3
3
 
4
4
  //#region src/platform/cloudflare/index.d.ts
@@ -114,12 +114,12 @@ type TServeDurableObjectOptions<TO_ACCEPTOR extends readonly ActionDomain<any>[]
114
114
  * ```
115
115
  * Passing `connectionState` narrows the return so `server.connections` is non-optional.
116
116
  */
117
- declare function serveDurableObject<TO_ACCEPTOR extends readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[], TApp>(ctx: IDurableObjectContext, channel: ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>, options: TServeDurableObjectOptions<TO_ACCEPTOR, TApp> & {
117
+ declare function serveDurableObject<TO_ACCEPTOR extends readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[], TApp>(ctx: IDurableObjectContext, channel: IActionChannel<TO_ACCEPTOR, TO_CONNECTOR>, options: TServeDurableObjectOptions<TO_ACCEPTOR, TApp> & {
118
118
  connectionState: IServeConnectionStateOptions<TApp>;
119
119
  }): TDurableObjectChannelServer<TApp> & {
120
120
  connections: ConnectionStateStore<IDurableObjectWebSocket, TApp>;
121
121
  };
122
- declare function serveDurableObject<TO_ACCEPTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TApp = unknown>(ctx: IDurableObjectContext, channel: ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>, options: TServeDurableObjectOptions<TO_ACCEPTOR, TApp>): TDurableObjectChannelServer<TApp>;
122
+ declare function serveDurableObject<TO_ACCEPTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TApp = unknown>(ctx: IDurableObjectContext, channel: IActionChannel<TO_ACCEPTOR, TO_CONNECTOR>, options: TServeDurableObjectOptions<TO_ACCEPTOR, TApp>): TDurableObjectChannelServer<TApp>;
123
123
  //#endregion
124
124
  export { ICloudflareDurableObjectHostOptions, IDurableObjectContext, IDurableObjectStorageOptions, IDurableObjectWebSocket, IDurableObjectWsCarrierOptions, TDurableObjectChannelServer, TServeDurableObjectOptions, cloudflareDurableObjectHost, durableObjectStorage, durableObjectWsCarrier, serveDurableObject };
125
125
  //# sourceMappingURL=index.d.cts.map
@@ -1,4 +1,4 @@
1
- import { Ft as ConnectionStateStore, Ot as IDuplexAcceptorCarrier, St as IChannelServer, Tt as IServeConnectionStateOptions, Yt as ISecureChannel, bt as TServeHostOptions, gn as ActionDomain, vn as ActionRuntime, yt as IChannelHostAdapter } from "../../ActionPayload.types-Dx1JPyfs.mjs";
1
+ import { _t as IDuplexAcceptorCarrier, ct as IChannelHostAdapter, dt as IChannelServer, kt as IActionChannel, l as ActionDomain, lt as TServeHostOptions, mt as IServeConnectionStateOptions, u as ActionRuntime, wt as ConnectionStateStore } from "../../AcceptorHandler-11-QMdx2.mjs";
2
2
  import { StorageAdapter, TCreateDurableObjectStorageOptions } from "@nice-code/util";
3
3
 
4
4
  //#region src/platform/cloudflare/index.d.ts
@@ -114,12 +114,12 @@ type TServeDurableObjectOptions<TO_ACCEPTOR extends readonly ActionDomain<any>[]
114
114
  * ```
115
115
  * Passing `connectionState` narrows the return so `server.connections` is non-optional.
116
116
  */
117
- declare function serveDurableObject<TO_ACCEPTOR extends readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[], TApp>(ctx: IDurableObjectContext, channel: ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>, options: TServeDurableObjectOptions<TO_ACCEPTOR, TApp> & {
117
+ declare function serveDurableObject<TO_ACCEPTOR extends readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[], TApp>(ctx: IDurableObjectContext, channel: IActionChannel<TO_ACCEPTOR, TO_CONNECTOR>, options: TServeDurableObjectOptions<TO_ACCEPTOR, TApp> & {
118
118
  connectionState: IServeConnectionStateOptions<TApp>;
119
119
  }): TDurableObjectChannelServer<TApp> & {
120
120
  connections: ConnectionStateStore<IDurableObjectWebSocket, TApp>;
121
121
  };
122
- declare function serveDurableObject<TO_ACCEPTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TApp = unknown>(ctx: IDurableObjectContext, channel: ISecureChannel<TO_ACCEPTOR, TO_CONNECTOR>, options: TServeDurableObjectOptions<TO_ACCEPTOR, TApp>): TDurableObjectChannelServer<TApp>;
122
+ declare function serveDurableObject<TO_ACCEPTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TO_CONNECTOR extends readonly ActionDomain<any>[] = readonly ActionDomain<any>[], TApp = unknown>(ctx: IDurableObjectContext, channel: IActionChannel<TO_ACCEPTOR, TO_CONNECTOR>, options: TServeDurableObjectOptions<TO_ACCEPTOR, TApp>): TDurableObjectChannelServer<TApp>;
123
123
  //#endregion
124
124
  export { ICloudflareDurableObjectHostOptions, IDurableObjectContext, IDurableObjectStorageOptions, IDurableObjectWebSocket, IDurableObjectWsCarrierOptions, TDurableObjectChannelServer, TServeDurableObjectOptions, cloudflareDurableObjectHost, durableObjectStorage, durableObjectWsCarrier, serveDurableObject };
125
125
  //# sourceMappingURL=index.d.mts.map
@@ -1,4 +1,4 @@
1
- import { n as wsAcceptorCarrier, r as serveHost, t as httpAcceptorCarrier } from "../../httpAcceptorCarrier-DL8lf0xB.mjs";
1
+ import { n as wsAcceptorCarrier, r as serveHost, t as httpAcceptorCarrier } from "../../httpAcceptorCarrier-DPBEuewS.mjs";
2
2
  import { createDurableObjectStorageAdapter } from "@nice-code/util";
3
3
  //#region src/platform/cloudflare/index.ts
4
4
  /**