osra 0.5.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -126,7 +126,7 @@ var e = Object.defineProperty, t = (t, n) => {
126
126
  return !1;
127
127
  }
128
128
  }
129
- }, oe = (e) => _(e) || T(e) || w(e), se = (e) => _(e) || T(e) || E(e) || D(e) || w(e), k = (e) => !!e && typeof e == "object" && "isJson" in e && e.isJson === !0 || oe(e) || se(e), A = (e) => O(e) || oe(e) || v(e) || y(e) || b(e) || x(e) || S(e) || de(e);
129
+ }, oe = (e) => _(e) || T(e) || w(e), se = (e) => _(e) || T(e) || E(e) || D(e) || w(e), k = (e) => !!e && typeof e == "object" && !O(e) && "isJson" in e && e.isJson === !0 || oe(e) || se(e), A = (e) => O(e) || oe(e) || v(e) || y(e) || b(e) || x(e) || S(e) || de(e);
130
130
  function ce(e) {
131
131
  if (!A(e)) throw Error("Transport is not emitable");
132
132
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/types.ts","../src/utils/transport.ts","../src/utils/type-guards.ts","../src/revivables/utils.ts","../src/revivables/array-buffer.ts","../src/revivables/date.ts","../src/revivables/headers.ts","../src/revivables/error.ts","../src/revivables/typed-array.ts","../src/utils/teardown.ts","../src/revivables/transfer.ts","../src/utils/transferable.ts","../src/utils/event-channel.ts","../src/utils/gc-tracker.ts","../src/revivables/message-port.ts","../src/revivables/promise.ts","../src/revivables/function.ts","../src/revivables/readable-stream.ts","../src/revivables/writable-stream.ts","../src/revivables/abort-signal.ts","../src/revivables/response.ts","../src/revivables/request.ts","../src/revivables/identity.ts","../src/revivables/map.ts","../src/revivables/set.ts","../src/revivables/bigint.ts","../src/revivables/event.ts","../src/revivables/event-target.ts","../src/revivables/blob.ts","../src/revivables/symbol.ts","../src/revivables/async-iterator.ts","../src/revivables/fallbacks.ts","../src/revivables/json-primitives.ts","../src/revivables/index.ts","../src/connections/bidirectional.ts","../src/utils/typed-event-target.ts","../src/connections/utils.ts","../src/connections/relay.ts","../src/connections/index.ts","../src/index.ts"],"sourcesContent":["import type { ConnectionMessage } from './connections/index.js'\nimport type { TypedEventTarget } from './utils/typed-event-target.js'\nimport type { IsJsonOnlyTransport } from './utils/type-guards.js'\nimport type {\n DefaultRevivableModules, RevivableModule,\n InferMessages, InferRevivables, RevivableContext\n} from './revivables/index.js'\n\nexport const OSRA_KEY = '__OSRA_KEY__' as const\nexport const OSRA_DEFAULT_KEY = '__OSRA_DEFAULT_KEY__' as const\nexport const OSRA_BOX = '__OSRA_BOX__' as const\n\nexport type Uuid = `${string}-${string}-${string}-${string}-${string}`\n\nexport type Jsonable =\n | boolean\n | null\n | number\n | string\n | { [key: string]: Jsonable }\n | Array<Jsonable>\n\nexport type Structurable =\n | Jsonable\n /** not really structureable but here for convenience */\n | void\n | undefined\n | bigint\n | Date\n | RegExp\n | Blob\n | File\n | FileList\n | ArrayBuffer\n | ArrayBufferView\n | ImageBitmap\n | ImageData\n | { [key: string]: Structurable }\n | Array<Structurable>\n | Map<Structurable, Structurable>\n | Set<Structurable>\n\nexport type StructurableTransferable =\n | Structurable\n | Transferable\n | { [key: string]: StructurableTransferable }\n | Array<StructurableTransferable>\n | Map<StructurableTransferable, StructurableTransferable>\n | Set<StructurableTransferable>\n\n/** \"Free\" types in `Capable` — narrows to `Jsonable` on JSON transports so\n * user code can't type a `Date`/`Blob`/etc. that JSON would silently coerce.\n * Modules that DO support JSON (date, map, set, bigint, …) put their type\n * back via `InferRevivables`. */\ntype CapableBase<Ctx extends RevivableContext> =\n IsJsonOnlyTransport<Ctx['transport']> extends true\n ? Jsonable | undefined | void\n : StructurableTransferable\n\nexport type Capable<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n Ctx extends RevivableContext = RevivableContext,\n> =\n | CapableBase<Ctx>\n | InferRevivables<TModules, Ctx>\n | { [key: string]: Capable<TModules, Ctx> }\n | Array<Capable<TModules, Ctx>>\n | Map<Capable<TModules, Ctx>, Capable<TModules, Ctx>>\n | Set<Capable<TModules, Ctx>>\n\n/** What a value looks like from the far side of the connection: functions\n * become async (calls cross the wire), Blobs arrive as Promise<Blob>,\n * containers map recursively, everything else revives as itself. */\nexport type Remote<T> =\n T extends (...args: infer P) => infer R ? (...args: P) => Promise<Remote<Awaited<R>>>\n : T extends Blob ? Promise<T>\n : T extends Promise<infer U> ? Promise<Remote<U>>\n : T extends\n | Map<any, any> | Set<any> | Date | Error | RegExp\n | ArrayBuffer | ArrayBufferView\n | ReadableStream | WritableStream | MessagePort | EventTarget\n | Request | Response | Headers\n ? T\n : T extends AsyncIterable<infer U> ? AsyncIterableIterator<Remote<U>>\n : T extends ReadonlyArray<unknown> ? { [K in keyof T]: Remote<T[K]> }\n : T extends object ? { [K in keyof T]: Remote<T[K]> }\n : T\n\nexport type MessageFields = {\n type: string\n remoteUuid: Uuid\n}\n\nexport type MessageBase = {\n [OSRA_KEY]: string\n /** UUID of the client that sent the message */\n uuid: Uuid\n name?: string\n}\n\nexport type ProtocolMessage =\n | { type: 'announce', remoteUuid?: Uuid }\n | { type: 'close', remoteUuid: Uuid }\n\nexport type MessageVariant<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> =\n | ProtocolMessage\n | ConnectionMessage<TModules>\n | InferMessages<TModules>\n\nexport type Message<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> =\n & MessageBase\n & MessageVariant<TModules>\n\nexport type MessageEventMap<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n message: CustomEvent<Message<TModules>>\n}\n\nexport type MessageEventTarget<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n > = TypedEventTarget<MessageEventMap<TModules>>\n","import type { Browser } from 'webextension-polyfill'\nimport type { Message} from '../types.js'\nimport type {\n WebExtOnConnect, WebExtOnMessage,\n WebExtPort, WebExtRuntime, WebExtSender\n} from './type-guards.js'\n\nimport { OSRA_DEFAULT_KEY, OSRA_KEY } from '../types.js'\nimport {\n isOsraMessage, isCustomTransport,\n isWebExtensionOnConnect, isWebExtensionOnMessage,\n isWebExtensionPort, isWebExtensionRuntime, isWebSocket, isWindow, isSharedWorker\n} from './type-guards.js'\n\nexport type MessageContext = {\n port?: MessagePort | WebExtPort // WebExtension\n sender?: WebExtSender // WebExtension\n receiveTransport?: ReceivePlatformTransport\n source?: MessageEventSource | null // Window, Worker, WebSocket, ect...\n origin?: string // Window\n}\n\nexport type ReceiveHandler = (listener: (event: Message, messageContext: MessageContext) => void) => void | (() => void)\nexport type EmitHandler = (message: Message, transferables?: Transferable[]) => void\n\ntype CustomReceive = ReceivePlatformTransport | ReceiveHandler\ntype CustomEmit = EmitPlatformTransport | EmitHandler\n\nexport type CustomTransport =\n { isJson?: boolean }\n & (\n | { receive: CustomReceive, emit: CustomEmit }\n | { receive: CustomReceive }\n | { emit: CustomEmit }\n )\n\nexport type CustomEmitTransport = Extract<CustomTransport, { emit: any }>\nexport type CustomReceiveTransport = Extract<CustomTransport, { receive: any }>\n\nexport type EmitJsonPlatformTransport =\n | WebSocket\n | WebExtPort\n | WebExtRuntime\n\nexport type ReceiveJsonPlatformTransport =\n | WebSocket\n | WebExtPort\n | WebExtOnConnect\n | WebExtOnMessage\n | WebExtRuntime\n\nexport type JsonPlatformTransport =\n | { isJson: true }\n | EmitJsonPlatformTransport\n | ReceiveJsonPlatformTransport\n\nexport type EmitPlatformTransport =\n | EmitJsonPlatformTransport\n | Window\n | ServiceWorker\n | Worker\n | SharedWorker\n | MessagePort\n\nexport type ReceivePlatformTransport =\n | ReceiveJsonPlatformTransport\n | Window\n | ServiceWorkerContainer\n | Worker\n | SharedWorker\n | MessagePort\n\nexport type PlatformTransport =\n | EmitPlatformTransport\n | ReceivePlatformTransport\n\nexport type EmitTransport = EmitPlatformTransport | CustomEmitTransport\nexport type ReceiveTransport = ReceivePlatformTransport | CustomReceiveTransport\n\nexport type Transport =\n | PlatformTransport\n | CustomTransport\n\n// Typed via the shipped webextension-polyfill module types — referencing the\n// ambient `browser`/`chrome` globals here would leak unresolvable names into\n// the published .d.ts (those @types are devDependencies only).\ntype WebExtGlobals = { browser?: Browser, chrome?: Browser }\nexport const getWebExtensionGlobal = (): Browser | undefined =>\n (globalThis as unknown as WebExtGlobals).browser ?? (globalThis as unknown as WebExtGlobals).chrome\nexport const getWebExtensionRuntime = () => getWebExtensionGlobal()?.runtime\n\nexport const checkOsraMessageKey = (message: any, key: string): message is Message =>\n isOsraMessage(message)\n && message[OSRA_KEY] === key\n\nconst onAbort = (signal: AbortSignal | undefined, fn: () => void) => {\n if (!signal) return\n if (signal.aborted) {\n fn()\n return\n }\n signal.addEventListener('abort', fn, { once: true })\n}\n\nexport const registerOsraMessageListener = (\n { listener, transport, remoteName, key = OSRA_DEFAULT_KEY, origin = '*', unregisterSignal }:\n {\n listener: (message: Message, messageContext: MessageContext) => void\n transport: ReceiveTransport\n remoteName?: string\n key?: string\n origin?: string\n unregisterSignal?: AbortSignal\n }\n) => {\n if (unregisterSignal?.aborted) return\n\n const receiveTransport: Extract<CustomTransport, { receive: any }>['receive'] =\n isCustomTransport(transport) ? transport.receive : transport\n\n // Custom function handler\n if (typeof receiveTransport === 'function') {\n const unregister = receiveTransport((message, ctx) => {\n if (unregisterSignal?.aborted) return\n if (!checkOsraMessageKey(message, key)) return\n if (remoteName && message.name !== remoteName) return\n listener(message, ctx)\n })\n if (typeof unregister === 'function') onAbort(unregisterSignal, unregister)\n return\n }\n\n // WebExtension family — subscribe to an `onMessage`-style listener.\n if (\n isWebExtensionRuntime(receiveTransport)\n || isWebExtensionPort(receiveTransport)\n || isWebExtensionOnConnect(receiveTransport)\n || isWebExtensionOnMessage(receiveTransport)\n ) {\n const listenOnWebExtOnMessage = (onMessage: WebExtOnMessage, port?: WebExtPort) => {\n const _listener = (message: unknown, sender?: WebExtSender) => {\n if (!checkOsraMessageKey(message, key)) return\n if (remoteName && message.name !== remoteName) return\n listener(message, { port, sender })\n }\n onMessage.addListener(_listener)\n onAbort(unregisterSignal, () => onMessage.removeListener(_listener))\n }\n\n if (isWebExtensionRuntime(receiveTransport)) {\n listenOnWebExtOnMessage(receiveTransport.onMessage)\n } else if (isWebExtensionOnConnect(receiveTransport)) {\n const _listener = (port: WebExtPort) =>\n listenOnWebExtOnMessage(port.onMessage as WebExtOnMessage, port)\n receiveTransport.addListener(_listener)\n onAbort(unregisterSignal, () => receiveTransport.removeListener(_listener))\n } else if (isWebExtensionOnMessage(receiveTransport)) {\n listenOnWebExtOnMessage(receiveTransport)\n } else { // WebExtPort\n listenOnWebExtOnMessage(receiveTransport.onMessage as WebExtOnMessage)\n }\n return\n }\n\n // Window, Worker, WebSocket, ServiceWorkerContainer, MessagePort, SharedWorker, …\n // SharedWorker dispatches messages on its .port, not on the worker object.\n const target = isSharedWorker(receiveTransport) ? receiveTransport.port : receiveTransport\n // Inbound origin filtering is a cross-origin *window* concern — WebSocket\n // and ServiceWorkerContainer events carry their own unrelated origins and\n // a page-origin value would silently drop all their traffic.\n const filterByOrigin = origin !== '*' && isWindow(receiveTransport)\n const messageListener = (event: MessageEvent<Message | string>) => {\n // JSON transports (WebSocket) deliver strings — parse before the key check.\n let data = event.data\n if (typeof data === 'string') {\n try { data = JSON.parse(data) as Message } catch { return }\n }\n if (!checkOsraMessageKey(data, key)) return\n if (remoteName && data.name !== remoteName) return\n if (filterByOrigin && event.origin && event.origin !== origin) return\n listener(data, { receiveTransport, source: event.source, origin: event.origin })\n }\n target.addEventListener('message', messageListener as EventListener)\n // addEventListener alone never enables a MessagePort's queue — only\n // .start() or assigning onmessage does.\n if (target instanceof MessagePort) target.start()\n onAbort(unregisterSignal, () =>\n target.removeEventListener('message', messageListener as EventListener),\n )\n}\n\nexport const sendOsraMessage = (\n transport: EmitTransport,\n message: Message,\n origin = '*',\n transferables: Transferable[] = []\n) => {\n const emitTransport: Extract<EmitTransport, { emit: any }>['emit'] =\n isCustomTransport(transport) ? transport.emit : transport\n\n if (typeof emitTransport === 'function') {\n emitTransport(message, transferables)\n } else if (isWindow(emitTransport)) {\n // Must check first — cross-origin windows throw on other property access.\n emitTransport.postMessage(message, origin, transferables)\n } else if (isWebExtensionPort(emitTransport)) {\n emitTransport.postMessage(message)\n } else if (isWebExtensionRuntime(emitTransport)) {\n emitTransport.sendMessage(message)\n } else if (isWebSocket(emitTransport)) {\n const payload = JSON.stringify(message)\n if (emitTransport.readyState === WebSocket.CONNECTING) {\n emitTransport.addEventListener('open', () => emitTransport.send(payload), { once: true })\n } else {\n emitTransport.send(payload)\n }\n } else if (isSharedWorker(emitTransport)) {\n emitTransport.port.postMessage(message, transferables)\n } else { // MessagePort | ServiceWorker | Worker\n emitTransport.postMessage(message, transferables)\n }\n}\n","import type { Runtime } from 'webextension-polyfill'\nimport type { Message } from '../types.js'\nimport type {\n CustomEmitTransport, CustomReceiveTransport,\n CustomTransport, EmitJsonPlatformTransport,\n EmitTransport, JsonPlatformTransport,\n ReceiveJsonPlatformTransport,\n ReceiveTransport, Transport\n} from './transport.js'\n\nimport { OSRA_KEY } from '../types.js'\nimport { getWebExtensionRuntime } from './transport.js'\n\n// Pulled from globalThis so module evaluation doesn't crash on platforms\n// that haven't shipped Float16Array yet (Node ≤ 23, Chrome ≤ 134, Firefox\n// ≤ 132). Platforms without it just don't round-trip Float16 values.\nconst Float16ArrayCtor = (globalThis as { Float16Array?: typeof Float16Array }).Float16Array\n\nconst typedArrayConstructorsByName = {\n Int8Array,\n Uint8Array,\n Uint8ClampedArray,\n Int16Array,\n Uint16Array,\n Int32Array,\n Uint32Array,\n Float16Array: Float16ArrayCtor,\n Float32Array,\n Float64Array,\n BigInt64Array,\n BigUint64Array,\n} as const\n\nexport type TypedArrayType = keyof typeof typedArrayConstructorsByName\nexport type TypedArrayConstructor = NonNullable<(typeof typedArrayConstructorsByName)[TypedArrayType]>\nexport type TypedArray = InstanceType<TypedArrayConstructor>\n\nconst typedArrayConstructors = Object.values(typedArrayConstructorsByName)\n\nexport const typedArrayToType = (value: TypedArray): TypedArrayType => {\n const name = value.constructor.name as TypedArrayType\n if (name in typedArrayConstructorsByName) return name\n // Subclasses (e.g. Node's Buffer extends Uint8Array). Find the nearest\n // TypedArray ancestor by walking the prototype chain.\n for (const [ancestorName, ctor] of Object.entries(typedArrayConstructorsByName)) {\n if (ctor && value instanceof ctor) return ancestorName as TypedArrayType\n }\n throw new Error('Unknown typed array type')\n}\n\nexport const typedArrayTypeToTypedArrayConstructor = (value: TypedArrayType): TypedArrayConstructor => {\n const ctor = typedArrayConstructorsByName[value]\n if (!ctor) throw new Error('Unknown typed array type')\n return ctor\n}\n\nexport const isTypedArray = (value: unknown): value is TypedArray =>\n typedArrayConstructors.some(ctor => !!ctor && value instanceof ctor)\nexport const isWebSocket = (value: unknown): value is WebSocket => value instanceof WebSocket\nexport const isServiceWorkerContainer = (value: unknown): value is ServiceWorkerContainer => !!globalThis.ServiceWorkerContainer && value instanceof ServiceWorkerContainer\nexport const isServiceWorker = (value: unknown): value is ServiceWorker => !!globalThis.ServiceWorker && value instanceof ServiceWorker\nexport const isWorker = (value: unknown): value is Worker => !!globalThis.Worker && value instanceof Worker\n// Structural stand-in: the real DedicatedWorkerGlobalScope type lives in\n// lib.webworker, which consumers of the published .d.ts may not load.\nexport type DedicatedWorkerGlobalScopeLike = typeof globalThis & {\n postMessage: (message: unknown, transfer?: Transferable[]) => void\n name: string\n}\nexport const isDedicatedWorker = (value: unknown): value is DedicatedWorkerGlobalScopeLike => {\n const scope = (globalThis as { DedicatedWorkerGlobalScope?: abstract new (...args: never[]) => unknown }).DedicatedWorkerGlobalScope\n return !!scope && value instanceof scope\n}\nexport const isSharedWorker = (value: unknown): value is SharedWorker => !!globalThis.SharedWorker && value instanceof SharedWorker\nconst isMessagePort = (value: unknown): value is MessagePort => value instanceof MessagePort\n\nexport const isOsraMessage = (value: unknown): value is Message =>\n !!value\n && typeof value === 'object'\n && OSRA_KEY in value\n && !!value[OSRA_KEY]\n\ntype AnyConstructor = abstract new (...args: any[]) => unknown\n\n/** True if `value` is an instance of any of the given constructors.\n * Tolerates undefined entries (constructors missing on this platform). */\nexport const instanceOfAny = (value: unknown, ctors: readonly (AnyConstructor | undefined)[]): boolean => {\n for (const ctor of ctors) if (ctor && value instanceof ctor) return true\n return false\n}\n\nexport const isSharedArrayBuffer = (value: unknown): boolean =>\n instanceOfAny(value, [globalThis.SharedArrayBuffer])\n/** @deprecated Renamed — this only ever checked SharedArrayBuffer, unlike\n * the unrelated clonable fallback module. Use isSharedArrayBuffer. */\nexport const isClonable = isSharedArrayBuffer\n\n// Types eligible for transfer when the user opts in via `transfer()`. Some\n// entries are also clonable (ArrayBuffer, ImageBitmap, …) — outside a\n// `transfer` box they fall back to clone.\nexport const isTransferable = (value: unknown): value is Transferable =>\n instanceOfAny(value, [\n globalThis.ArrayBuffer,\n globalThis.MessagePort,\n globalThis.ReadableStream,\n globalThis.WritableStream,\n globalThis.TransformStream,\n globalThis.ImageBitmap,\n globalThis.OffscreenCanvas,\n (globalThis as { AudioData?: abstract new (...args: any[]) => unknown }).AudioData,\n (globalThis as { VideoFrame?: abstract new (...args: any[]) => unknown }).VideoFrame,\n (globalThis as { MediaSourceHandle?: abstract new (...args: any[]) => unknown }).MediaSourceHandle,\n (globalThis as { MediaStreamTrack?: abstract new (...args: any[]) => unknown }).MediaStreamTrack,\n (globalThis as { MIDIAccess?: abstract new (...args: any[]) => unknown }).MIDIAccess,\n (globalThis as { RTCDataChannel?: abstract new (...args: any[]) => unknown }).RTCDataChannel,\n (globalThis as { WebTransportReceiveStream?: abstract new (...args: any[]) => unknown }).WebTransportReceiveStream,\n (globalThis as { WebTransportSendStream?: abstract new (...args: any[]) => unknown }).WebTransportSendStream,\n ])\n\nexport type WebExtRuntime = Runtime.Static\nexport const isWebExtensionRuntime = (value: unknown): value is WebExtRuntime => {\n const runtime = getWebExtensionRuntime()\n if (!runtime) return false\n return value === runtime\n}\n\nexport type WebExtPort = ReturnType<WebExtRuntime['connect']> | Runtime.Port\nexport const isWebExtensionPort = (value: unknown, connectPort: boolean = false): value is WebExtPort => {\n if (!value || typeof value !== 'object') return false\n // Prevent SecurityError when `value` is a cross-origin window.\n if (isWindow(value)) return false\n if (!('name' in value) || !('disconnect' in value) || !('postMessage' in value)) return false\n // these properties are only present on WebExtPorts created through runtime.connect()\n if (!connectPort) return true\n return 'sender' in value && 'onMessage' in value && 'onDisconnect' in value\n}\n\nexport type WebExtSender = NonNullable<WebExtPort['sender']>\n\n// Structural guard. Can't distinguish onConnect from onMessage on its own —\n// they share this exact shape.\nconst hasListenerApi = (value: unknown): boolean =>\n !!value\n && typeof value === 'object'\n && !isWindow(value)\n && 'addListener' in value\n && 'hasListener' in value\n && 'removeListener' in value\n\n// Identity-compare against runtime.onConnect — structural checks can't\n// distinguish onConnect from onMessage, and misclassifying causes us to\n// treat each incoming message as a port and crash.\nexport type WebExtOnConnect = WebExtRuntime['onConnect']\nexport const isWebExtensionOnConnect = (value: unknown): value is WebExtOnConnect => {\n const runtime = getWebExtensionRuntime()\n if (!runtime) return false\n return value === runtime.onConnect || value === runtime.onConnectExternal\n}\n\nexport type WebExtOnMessage = WebExtRuntime['onMessage']\nexport const isWebExtensionOnMessage = (value: unknown): value is WebExtOnMessage =>\n hasListenerApi(value)\n\nexport const isWindow = (value: unknown): value is Window => {\n if (!value || typeof value !== 'object') return false\n try {\n return 'window' in value && value.window === value\n } catch {\n // Cross-origin Window access can throw SecurityError — fall back to a\n // shape probe over properties that don't trigger the security check.\n try {\n return 'closed' in value\n && typeof value.closed === 'boolean'\n && 'close' in value\n && typeof value.close === 'function'\n } catch {\n return false\n }\n }\n}\n\nexport const isEmitJsonOnlyTransport = (value: unknown): value is EmitJsonPlatformTransport =>\n isWebSocket(value)\n || isWebExtensionPort(value)\n || isWebExtensionRuntime(value)\n\nexport const isReceiveJsonOnlyTransport = (value: unknown): value is ReceiveJsonPlatformTransport =>\n isWebSocket(value)\n || isWebExtensionPort(value)\n || isWebExtensionOnConnect(value)\n || isWebExtensionOnMessage(value)\n || isWebExtensionRuntime(value)\n\nexport type IsJsonOnlyTransport<T extends Transport> = T extends JsonPlatformTransport ? true : false\nexport const isJsonOnlyTransport = (value: unknown): value is Extract<Transport, JsonPlatformTransport> =>\n (!!value && typeof value === 'object' && 'isJson' in value && value.isJson === true)\n || isEmitJsonOnlyTransport(value)\n || isReceiveJsonOnlyTransport(value)\n\nexport const isEmitTransport = (value: unknown): value is EmitTransport =>\n isWindow(value)\n || isEmitJsonOnlyTransport(value)\n // ServiceWorker instances can postMessage; the container cannot — it only receives.\n || isServiceWorker(value)\n || isWorker(value)\n || isDedicatedWorker(value)\n || isSharedWorker(value)\n || isMessagePort(value)\n || isCustomEmitTransport(value)\n\nexport function assertEmitTransport(transport: Transport): asserts transport is EmitTransport {\n if (!isEmitTransport(transport)) throw new Error('Transport is not emitable')\n}\n\nexport const isReceiveTransport = (value: unknown): value is ReceiveTransport =>\n isWindow(value)\n || isReceiveJsonOnlyTransport(value)\n || isServiceWorkerContainer(value)\n || isWorker(value)\n || isDedicatedWorker(value)\n || isSharedWorker(value)\n || isMessagePort(value)\n || isCustomReceiveTransport(value)\n\nexport function assertReceiveTransport(transport: Transport): asserts transport is ReceiveTransport {\n if (!isReceiveTransport(transport)) throw new Error('Transport is not receiveable')\n}\n\n// Custom transports must be plain objects: Node's worker_threads MessagePort\n// (an EventEmitter) has an inherited `emit` and would otherwise be\n// misclassified, then gutted by normalizeTransport's object spread.\nconst isPlainObjectShape = (value: unknown): value is Record<string, unknown> => {\n if (!value || typeof value !== 'object') return false\n // Prevent SecurityError when `value` is a cross-origin window — its\n // [[GetPrototypeOf]] returns null, which would pass the proto check.\n if (isWindow(value)) return false\n const proto = Object.getPrototypeOf(value)\n return proto === Object.prototype || proto === null\n}\n\nexport const isCustomEmitTransport = (value: unknown): value is CustomEmitTransport => {\n if (!isPlainObjectShape(value)) return false\n if (!('emit' in value)) return false\n return isEmitTransport(value.emit) || typeof value.emit === 'function'\n}\n\nexport const isCustomReceiveTransport = (value: unknown): value is CustomReceiveTransport => {\n if (!isPlainObjectShape(value)) return false\n if (!('receive' in value)) return false\n return isReceiveTransport(value.receive) || typeof value.receive === 'function'\n}\n\nexport const isCustomTransport = (value: unknown): value is CustomTransport =>\n isCustomEmitTransport(value)\n || isCustomReceiveTransport(value)\n\nexport const isTransport = (value: unknown): value is Transport =>\n isEmitTransport(value)\n || isReceiveTransport(value)\n || isCustomTransport(value)\n || isJsonOnlyTransport(value)\n","import type { DefaultRevivableModules, RevivableModule } from './index.js'\nimport type {\n MessageEventTarget,\n MessageFields,\n Uuid,\n} from '../types.js'\nimport type { Transport } from '../utils/transport.js'\nimport type { IsJsonOnlyTransport } from '../utils/type-guards.js'\n\nimport { OSRA_BOX } from '../types.js'\nimport { isJsonOnlyTransport } from '../utils/type-guards.js'\n\nexport type { UnderlyingType } from '../utils/type.js'\n\nexport const BoxBase = {\n [OSRA_BOX]: 'revivable',\n} as const\n\nexport type BoxBase<T extends string = string> =\n & typeof BoxBase\n & { type: T }\n\nexport type RevivableContext<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n transport: Transport\n remoteUuid: Uuid\n /** Typed as a broad dispatcher so revivables can post their own message\n * variants without triggering contravariant function-parameter mismatches\n * across modules. The shape is enforced structurally via `MessageFields`. */\n sendMessage: (message: MessageFields & Record<string, unknown>) => void\n revivableModules: TModules\n eventTarget: MessageEventTarget<TModules>\n}\n\n/** Extract the type a module's `isType` narrows to. Modules marked\n * `capableOnly: true` (clonable, transferable) contribute `never` on JSON\n * transports so users can't type values JSON would silently drop. */\nexport type ExtractType<T, Ctx extends RevivableContext = RevivableContext> =\n T extends { capableOnly: true }\n ? IsJsonOnlyTransport<Ctx['transport']> extends true\n ? never\n : T extends { isType: (value: unknown) => value is infer S } ? S : never\n : T extends { isType: (value: unknown) => value is infer S } ? S : never\n\nexport type ExtractMessages<T> =\n T extends { Messages?: infer B }\n ? B extends { type: string }\n ? string extends B['type'] ? never : B\n : never\n : never\n\nexport type InferMessages<TModules extends readonly unknown[]> =\n ExtractMessages<TModules[number]>\n\nexport type InferRevivables<\n TModules extends readonly unknown[],\n Ctx extends RevivableContext = RevivableContext,\n> =\n ExtractType<TModules[number], Ctx>\n\nexport const isRevivableBox = (value: unknown): value is BoxBase =>\n !!value\n && typeof value === 'object'\n && OSRA_BOX in value\n && value[OSRA_BOX] === 'revivable'\n\n/** Wire shape for an ArrayBuffer: base64 on JSON, raw on clone. */\nexport type BoxedBuffer<TCtx extends RevivableContext = RevivableContext> =\n IsJsonOnlyTransport<TCtx['transport']> extends true ? { base64Buffer: string }\n : IsJsonOnlyTransport<TCtx['transport']> extends false ? { arrayBuffer: ArrayBuffer }\n : { base64Buffer: string } | { arrayBuffer: ArrayBuffer }\n\nexport const boxBuffer = <TCtx extends RevivableContext>(\n buffer: ArrayBuffer,\n context: TCtx,\n): BoxedBuffer<TCtx> =>\n (isJsonOnlyTransport(context.transport)\n ? { base64Buffer: new Uint8Array(buffer).toBase64() }\n : { arrayBuffer: buffer }\n ) as BoxedBuffer<TCtx>\n\nexport const reviveBuffer = (boxed: { arrayBuffer: ArrayBuffer } | { base64Buffer: string }): ArrayBuffer =>\n 'arrayBuffer' in boxed\n ? boxed.arrayBuffer\n : Uint8Array.fromBase64(boxed.base64Buffer).buffer\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase, boxBuffer, reviveBuffer } from './utils.js'\n\nexport const type = 'arrayBuffer' as const\n\nexport const isType = (value: unknown): value is ArrayBuffer =>\n value instanceof ArrayBuffer\n\nexport const box = <T extends ArrayBuffer, T2 extends RevivableContext>(\n value: T,\n context: T2,\n) => ({\n ...BoxBase,\n type,\n ...boxBuffer(value, context),\n})\n\nexport const revive = <T extends ReturnType<typeof box>>(\n value: T,\n _context: RevivableContext,\n) => reviveBuffer(value)\n\nconst typeCheck = () => {\n const boxed = box(new ArrayBuffer(10), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: ArrayBuffer = revived\n // @ts-expect-error - not an ArrayBuffer\n const notArrayBuffer: string = revived\n // @ts-expect-error - cannot box non-ArrayBuffer\n box('not an array buffer', {} as RevivableContext)\n}\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\n\nexport const type = 'date' as const\n\nexport const isType = (value: unknown): value is Date =>\n value instanceof Date\n\nexport const box = <T extends Date, T2 extends RevivableContext>(\n value: T,\n _context: T2\n) => ({\n ...BoxBase,\n type,\n ISOString: value.toISOString()\n})\n\nexport const revive = <T extends ReturnType<typeof box>, T2 extends RevivableContext>(\n value: T,\n _context: T2\n) => new Date(value.ISOString)\n\nconst typeCheck = () => {\n const boxed = box(new Date(), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Date = revived\n // @ts-expect-error - not a Date\n const notDate: string = revived\n // @ts-expect-error - cannot box non-Date\n box('not a date', {} as RevivableContext)\n}\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\n\nexport const type = 'headers' as const\n\nexport const isType = (value: unknown): value is Headers =>\n value instanceof Headers\n\nexport const box = <T extends Headers, T2 extends RevivableContext>(\n value: T,\n _context: T2\n) => ({\n ...BoxBase,\n type,\n entries: [...value.entries()]\n})\n\nexport const revive = <T extends ReturnType<typeof box>, T2 extends RevivableContext>(\n value: T,\n _context: T2\n): Headers => {\n return new Headers(value.entries)\n}\n\nconst typeCheck = () => {\n const boxed = box(new Headers(), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Headers = revived\n // @ts-expect-error - not a Headers\n const notHeaders: string = revived\n // @ts-expect-error - cannot box non-Headers\n box('not a header', {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\n\nexport const type = 'error' as const\n\nexport type BoxedError =\n & BoxBaseType<typeof type>\n & {\n name: string\n message: string\n stack: string\n cause?: Capable\n /** AggregateError only */\n errors?: Capable\n isDOMException?: boolean\n }\n\nconst ERROR_CONSTRUCTORS: Record<string, ErrorConstructor> = {\n Error,\n TypeError: TypeError as ErrorConstructor,\n RangeError: RangeError as ErrorConstructor,\n SyntaxError: SyntaxError as ErrorConstructor,\n ReferenceError: ReferenceError as ErrorConstructor,\n EvalError: EvalError as ErrorConstructor,\n URIError: URIError as ErrorConstructor,\n}\n\nexport const isType = (value: unknown): value is Error =>\n value instanceof Error\n\nexport const box = <T extends Error, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedError => {\n const hasCause = 'cause' in value && value.cause !== undefined\n const isAggregate = typeof AggregateError !== 'undefined' && value instanceof AggregateError\n const isDomException = typeof DOMException !== 'undefined' && value instanceof DOMException\n return {\n ...BoxBase,\n type,\n name: value.name,\n message: value.message,\n stack: value.stack || value.toString(),\n ...(hasCause ? { cause: recursiveBox(value.cause as Capable, context) as Capable } : {}),\n ...(isAggregate ? { errors: recursiveBox(value.errors as Capable, context) as Capable } : {}),\n ...(isDomException ? { isDOMException: true } : {}),\n }\n}\n\nexport const revive = <T extends BoxedError, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): Error => {\n const cause = value.cause !== undefined\n ? recursiveRevive(value.cause, context)\n : undefined\n const options = cause !== undefined ? { cause } : undefined\n\n if (value.isDOMException && typeof DOMException !== 'undefined') {\n const err = new DOMException(value.message, value.name)\n if (value.stack) {\n try { Object.defineProperty(err, 'stack', { value: value.stack, configurable: true }) } catch { /* immutable on some engines */ }\n }\n return err\n }\n\n let err: Error\n if (value.errors !== undefined && typeof AggregateError !== 'undefined') {\n err = new AggregateError(recursiveRevive(value.errors, context) as unknown as unknown[], value.message, options)\n } else {\n const Constructor = ERROR_CONSTRUCTORS[value.name] ?? Error\n err = options !== undefined\n ? new Constructor(value.message, options)\n : new Constructor(value.message)\n }\n if (value.name && err.name !== value.name) err.name = value.name\n if (value.stack) err.stack = value.stack\n return err\n}\n\nconst typeCheck = () => {\n const boxed = box(new Error('test'), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Error = revived\n // @ts-expect-error - not an Error\n const notError: string = revived\n // @ts-expect-error - cannot box non-Error\n box('not an error', {} as RevivableContext)\n}\n","import type { RevivableContext, UnderlyingType, BoxedBuffer } from './utils.js'\nimport type { TypedArray, TypedArrayType } from '../utils/type-guards.js'\n\nimport { BoxBase, boxBuffer, reviveBuffer } from './utils.js'\nimport {\n isTypedArray,\n typedArrayToType,\n typedArrayTypeToTypedArrayConstructor,\n} from '../utils/type-guards.js'\n\nexport const type = 'typedArray' as const\n\ntype BoxedTypedArray<T extends TypedArray, T2 extends RevivableContext> =\n & typeof BoxBase\n & { type: typeof type }\n & { typedArrayType: TypedArrayType }\n & BoxedBuffer<T2>\n & { [UnderlyingType]: T }\n\nexport const isType = isTypedArray\n\nexport const box = <T extends TypedArray, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedTypedArray<T, T2> => {\n // Ship exactly the view's window — shipping the whole backing buffer\n // loses byteOffset/length on revive (silent corruption for subarrays,\n // RangeError for multi-byte views over odd-sized buffers).\n const aligned = value.byteOffset === 0 && value.byteLength === value.buffer.byteLength\n const buffer = aligned\n ? value.buffer as ArrayBuffer\n : (value.buffer as ArrayBuffer).slice(value.byteOffset, value.byteOffset + value.byteLength)\n return {\n ...BoxBase,\n type,\n typedArrayType: typedArrayToType(value),\n ...boxBuffer(buffer, context),\n } as unknown as BoxedTypedArray<T, T2>\n}\n\nexport const revive = <T extends BoxedTypedArray<TypedArray, RevivableContext>>(\n value: T,\n _context: RevivableContext,\n): T[UnderlyingType] =>\n new (typedArrayTypeToTypedArrayConstructor(value.typedArrayType))(reviveBuffer(value)) as T[UnderlyingType]\n\nconst typeCheck = () => {\n const uint8Boxed = box(new Uint8Array(10), {} as RevivableContext)\n const uint8Revived = revive(uint8Boxed, {} as RevivableContext)\n const expectedUint8: Uint8Array = uint8Revived\n // @ts-expect-error - wrong typed array type\n const wrongType: Int32Array = uint8Revived\n\n const float32Boxed = box(new Float32Array(10), {} as RevivableContext)\n const float32Revived = revive(float32Boxed, {} as RevivableContext)\n const expectedFloat32: Float32Array = float32Revived\n // @ts-expect-error - wrong typed array type\n const wrongFloat: Uint8Array = float32Revived\n\n // @ts-expect-error - cannot box non-TypedArray\n box('not a typed array', {} as RevivableContext)\n}\n","/** Per-connection teardown registry. Revivables register cleanup for state\n * tied to a connection (pending RPC settlements, port routing, caches);\n * the connection layer runs it on protocol close or unregisterSignal abort.\n * Registering against an already-torn-down scope runs the callback\n * immediately so late registrations fail fast instead of leaking. */\n\nconst registries = new WeakMap<WeakKey, Set<() => void>>()\nconst tornDown = new WeakSet<WeakKey>()\n\nexport const onTeardown = (scope: WeakKey, fn: () => void): (() => void) => {\n if (tornDown.has(scope)) {\n fn()\n return () => {}\n }\n let set = registries.get(scope)\n if (!set) registries.set(scope, set = new Set())\n set.add(fn)\n return () => set.delete(fn)\n}\n\nexport const runTeardown = (scope: WeakKey): void => {\n if (tornDown.has(scope)) return\n tornDown.add(scope)\n const set = registries.get(scope)\n if (!set) return\n registries.delete(scope)\n for (const fn of set) {\n try { fn() } catch { /* teardown is best-effort */ }\n }\n}\n","import type { Capable } from '../types.js'\nimport type { BoxBase as BoxBaseType, RevivableContext, UnderlyingType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { instanceOfAny, isJsonOnlyTransport } from '../utils/type-guards.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\n\nexport const type = 'transfer' as const\n\nconst TRANSFER_MARKER: unique symbol = Symbol.for('osra.transfer')\n\ntype TransferWrapper<T = unknown> = {\n readonly [TRANSFER_MARKER]: true\n readonly value: T\n}\n\nexport type BoxedTransfer<T extends Capable = Capable> = BoxBaseType<typeof type> & {\n inner: Capable\n degraded: boolean\n [UnderlyingType]: T\n}\n\nconst isObject = (value: unknown): value is object =>\n value !== null && typeof value === 'object'\n\nconst isTransferWrapper = (value: unknown): value is TransferWrapper =>\n isObject(value) && TRANSFER_MARKER in value && value[TRANSFER_MARKER] === true\n\nconst isWrappableTransferable = (value: unknown): boolean => {\n if (!isObject(value)) return false\n if (ArrayBuffer.isView(value)) return true\n return instanceOfAny(value, [\n globalThis.ArrayBuffer,\n globalThis.MessagePort,\n globalThis.ReadableStream,\n globalThis.WritableStream,\n globalThis.TransformStream,\n globalThis.ImageBitmap,\n globalThis.OffscreenCanvas,\n ])\n}\n\n/** Opt into transfer (move) semantics for a transferable value. Idempotent;\n * non-transferable inputs pass through unchanged. Silently degrades to a\n * copy when the platform/transport can't transfer the given type. Lies at\n * the type level — runtime value is a TransferWrapper<T> typed as T. */\nexport const transfer = <T>(value: T): T =>\n (isWrappableTransferable(value)\n ? { [TRANSFER_MARKER]: true, value }\n : value\n ) as T\n\nexport const isType = (value: unknown): value is TransferWrapper =>\n isTransferWrapper(value)\n\nexport const box = <T extends Capable, TContext extends RevivableContext>(\n wrapper: TransferWrapper<T>,\n context: TContext,\n): BoxedTransfer<T> =>\n // `degraded` tells the send-time walker in getTransferableObjects to treat\n // this box as a regular value (no transfer-list entry). JSON transports\n // can't move ownership, so transfer semantics don't apply.\n ({\n ...BoxBase,\n type,\n inner: recursiveBox(wrapper.value, context),\n degraded: isJsonOnlyTransport(context.transport),\n }) as unknown as BoxedTransfer<T>\n\nexport const revive = <T extends BoxedTransfer, TContext extends RevivableContext>(\n value: T,\n context: TContext,\n): T[UnderlyingType] =>\n recursiveRevive(value.inner, context) as T[UnderlyingType]\n\nconst typeCheck = () => {\n const ab = new ArrayBuffer(10)\n const wrapper = { [TRANSFER_MARKER]: true, value: ab } as TransferWrapper<ArrayBuffer>\n const boxed = box(wrapper, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: ArrayBuffer = revived\n // @ts-expect-error - revived is ArrayBuffer, not string\n const notExpected: string = revived\n // @ts-expect-error - cannot box a non-Capable wrapper (WeakMap not assignable)\n box({ [TRANSFER_MARKER]: true, value: new WeakMap() } as TransferWrapper<WeakMap<object, string>>, {} as RevivableContext)\n}\n","import { transfer } from '../revivables/transfer.js'\nimport { isRevivableBox } from '../revivables/utils.js'\nimport { instanceOfAny, isSharedArrayBuffer, isTransferable } from './type-guards.js'\n\nexport { transfer }\n\n// Must-transfer types: structured clone can't copy these, so any occurrence\n// in the outgoing message must go on the transfer list — opt-in or not.\n// (MessagePort is the canonical case: cloning would leave the peer mute.)\nconst isMustTransfer = (value: unknown): value is Transferable =>\n instanceOfAny(value, [\n globalThis.MessagePort,\n globalThis.ReadableStream,\n globalThis.WritableStream,\n globalThis.TransformStream,\n globalThis.OffscreenCanvas,\n (globalThis as { MediaSourceHandle?: abstract new (...args: any[]) => unknown }).MediaSourceHandle,\n (globalThis as { MediaStreamTrack?: abstract new (...args: any[]) => unknown }).MediaStreamTrack,\n (globalThis as { MIDIAccess?: abstract new (...args: any[]) => unknown }).MIDIAccess,\n (globalThis as { RTCDataChannel?: abstract new (...args: any[]) => unknown }).RTCDataChannel,\n (globalThis as { WebTransportReceiveStream?: abstract new (...args: any[]) => unknown }).WebTransportReceiveStream,\n (globalThis as { WebTransportSendStream?: abstract new (...args: any[]) => unknown }).WebTransportSendStream,\n ])\n\n// Structural check — keeps the walker decoupled from the module graph.\n// `degraded` (set by transfer.box) means the wrapper is a no-op here.\nconst isTransferBox = (value: unknown): value is { inner: unknown, degraded: boolean } =>\n isRevivableBox(value) && value.type === 'transfer'\n\n/** Walk a boxed message and collect Transferables to move (rather than copy)\n * on postMessage:\n * 1. Must-transfer types are always included.\n * 2. Clonable types (SharedArrayBuffer) are skipped.\n * 3. Other Transferables are included only inside a non-degraded transfer\n * box (user opted in AND the platform supports transferring). */\nexport const getTransferableObjects = (value: unknown): Transferable[] => {\n const transferables: Transferable[] = []\n const seen = new WeakSet<object>()\n\n const recurse = (value: unknown, inTransferBox: boolean): void => {\n if (!value || typeof value !== 'object') return\n if (seen.has(value)) return\n seen.add(value)\n\n if (isSharedArrayBuffer(value)) return\n\n if (isTransferBox(value)) {\n // Non-degraded box flips into transfer mode for everything below.\n recurse(value.inner, inTransferBox || !value.degraded)\n return\n }\n\n if (isMustTransfer(value)) {\n transferables.push(value)\n return\n }\n\n if (isTransferable(value)) {\n if (inTransferBox) {\n transferables.push(value)\n }\n return\n }\n\n // TypedArray / DataView expose every numeric index — iterating a 100 KB\n // buffer would walk 100 K entries for nothing. The underlying buffer is\n // the only candidate; the typed-array revivable handles that path.\n if (ArrayBuffer.isView(value)) return\n\n if (Array.isArray(value)) {\n for (const item of value) recurse(item, inTransferBox)\n return\n }\n\n for (const item of Object.values(value)) recurse(item, inTransferBox)\n }\n\n recurse(value, false)\n return transferables\n}\n","import type { TypedMessagePort, TypedMessagePortEventMap } from './typed-message-channel.js'\n\nexport class EventPort<T> extends EventTarget {\n addEventListener<K extends keyof TypedMessagePortEventMap<T> & string>(\n type: K,\n listener: ((event: TypedMessagePortEventMap<T>[K]) => void) | null,\n options?: boolean | AddEventListenerOptions\n ): void\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | AddEventListenerOptions\n ): void\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | AddEventListenerOptions\n ): void {\n super.addEventListener(type, listener, options)\n }\n\n removeEventListener<K extends keyof TypedMessagePortEventMap<T> & string>(\n type: K,\n listener: ((event: TypedMessagePortEventMap<T>[K]) => void) | null,\n options?: boolean | EventListenerOptions\n ): void\n removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | EventListenerOptions\n ): void\n removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | EventListenerOptions\n ): void {\n super.removeEventListener(type, listener, options)\n }\n\n _peer: EventPort<any> | undefined\n _queue: MessageEvent<T>[] = []\n _started = false\n _closed = false\n _onClose: (() => void) | undefined\n\n private _onmessage: ((this: MessagePort, ev: MessageEvent<T>) => unknown) | null = null\n\n get onmessage(): ((this: MessagePort, ev: MessageEvent<T>) => unknown) | null {\n return this._onmessage\n }\n set onmessage(value: ((this: MessagePort, ev: MessageEvent<T>) => unknown) | null) {\n this._onmessage = value\n if (value !== null) this.start()\n }\n\n onmessageerror: ((this: MessagePort, ev: MessageEvent) => unknown) | null = null\n\n dispatchEvent(event: Event): boolean {\n if (event.type === 'message') {\n this._onmessage?.call(this, event as MessageEvent<T>)\n } else if (event.type === 'messageerror') {\n this.onmessageerror?.call(this, event as MessageEvent)\n }\n return super.dispatchEvent(event)\n }\n\n postMessage(message: T, _options?: Transferable[] | StructuredSerializeOptions): void {\n const peer = this._peer\n if (!peer || peer._closed) return\n queueMicrotask(() => {\n if (peer._closed) return\n const event = new MessageEvent('message', { data: message })\n if (peer._started) {\n peer.dispatchEvent(event)\n } else {\n peer._queue.push(event)\n }\n })\n }\n\n start(): void {\n if (this._started) return\n this._started = true\n for (const event of this._queue.splice(0)) {\n this.dispatchEvent(event)\n }\n }\n\n close(): void {\n if (this._closed) return\n this._closed = true\n this._queue.length = 0\n this._onClose?.()\n // Mirror the platform 'close' event: closing a port notifies its peer.\n // Deferred so messages posted before the close still deliver first.\n const peer = this._peer\n if (peer && !peer._closed) {\n queueMicrotask(() => {\n if (!peer._closed) peer.dispatchEvent(new Event('close'))\n })\n }\n }\n}\n\nexport interface EventPort<T>\n extends Omit<\n TypedMessagePort<T>,\n 'addEventListener' | 'removeEventListener'\n > {}\n\nexport class EventChannel<T1 = unknown, T2 = unknown> {\n readonly port1: EventPort<T1>\n readonly port2: EventPort<T2>\n\n constructor() {\n const port1 = new EventPort<T1>()\n const port2 = new EventPort<T2>()\n port1._peer = port2\n port2._peer = port1\n this.port1 = port1\n this.port2 = port2\n }\n}\n","/**\n * Run `cleanup` after `target` is garbage-collected. Returns a handle to\n * cancel the tracking before that happens.\n *\n * Backed by a single shared FinalizationRegistry — every revivable that\n * needs FR semantics goes through this so the boilerplate (token,\n * unregister, cycle-safety contract) lives in one place.\n *\n * Contract: `cleanup` MUST NOT (transitively) reference `target`. The\n * registry strong-holds the cleanup callback, the cleanup would then\n * strong-hold target, and the engine would never see target as\n * collectable. Use a `WeakRef` if cleanup needs something that points\n * back at target.\n *\n * Errors thrown from cleanup are swallowed: the callback fires from the\n * FR thread, where there's no caller to surface them to.\n */\nexport type GcUnregister = () => void\n\nconst registry = new FinalizationRegistry<() => void>((cleanup) => {\n try { cleanup() } catch { /* no caller to surface to */ }\n})\n\nexport const trackGc = (target: WeakKey, cleanup: () => void): GcUnregister => {\n const token = {}\n registry.register(target, cleanup, token)\n return () => registry.unregister(token)\n}\n","import type { Capable, StructurableTransferable, Uuid } from '../types.js'\nimport type { TypedMessageChannel, TypedMessagePort } from '../utils/typed-message-channel.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { UnderlyingType } from '../utils/type.js'\nimport type {\n BadFieldValue, BadFieldPath, BadFieldParent,\n ErrorMessage, BadValue, Path, ParentObject\n} from '../utils/capable-check.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\nimport { getTransferableObjects } from '../utils/transferable.js'\nimport { isJsonOnlyTransport } from '../utils/type-guards.js'\nimport { EventChannel, EventPort } from '../utils/event-channel.js'\nimport { trackGc } from '../utils/gc-tracker.js'\nimport { onTeardown } from '../utils/teardown.js'\n\nexport const type = 'messagePort' as const\n\nexport type Messages =\n | { type: 'message', remoteUuid: Uuid, data: Capable, portId: Uuid }\n | { type: 'message-port-close', remoteUuid: Uuid, portId: Uuid }\n\nexport declare const Messages: Messages\n\nexport type AnyPort<T = Capable> =\n | TypedMessagePort<T>\n | EventPort<T>\n\nexport type BoxedMessagePort<T = Capable> =\n & BoxBaseType<typeof type>\n & (\n | { portId: Uuid, synthetic: true }\n | { portId: Uuid, synthetic: false }\n | { port: AnyPort<T>, autoBox?: boolean }\n )\n & { [UnderlyingType]: TypedMessagePort<T> }\n\n// `[T] extends [Capable]` disables distributive conditionals so `A | B` gives\n// back `AnyPort<A | B>`, not `AnyPort<A> | AnyPort<B>`. The error branch\n// intersects with AnyPort<T> so excess-property check targets the failure\n// rather than the user's port-shaped keys.\ntype StructurableTransferablePort<T> = [T] extends [Capable]\n ? AnyPort<T>\n : AnyPort<T> & {\n [ErrorMessage]: 'Message type must extend Capable'\n [BadValue]: BadFieldValue<T, Capable>\n [Path]: BadFieldPath<T, Capable>\n [ParentObject]: BadFieldParent<T, Capable>\n }\n\ntype ConnectionMessagePortState = {\n /** O(1) per-portId dispatch — avoids the O(N) addEventListener scan\n * that was the bottleneck for tight-loop RPC traffic. */\n portHandlers: Map<string, (message: Messages) => void>\n}\n\nconst connectionStateMap = new WeakMap<RevivableContext, ConnectionMessagePortState>()\n\nconst getState = (context: RevivableContext): ConnectionMessagePortState => {\n const state = connectionStateMap.get(context)\n if (!state) throw new Error('osra message-port: connection state missing; did init() run?')\n return state\n}\n\nexport const init = (context: RevivableContext): void => {\n const state: ConnectionMessagePortState = { portHandlers: new Map() }\n connectionStateMap.set(context, state)\n\n context.eventTarget.addEventListener('message', ({ detail }) => {\n if (detail.type !== 'message' && detail.type !== 'message-port-close') return\n state.portHandlers.get(detail.portId)?.(detail)\n })\n\n // Connection death = every routed port is dead: run each handler's close\n // arm so user-facing ports close and routing entries clear.\n onTeardown(context, () => {\n for (const [portId, handler] of [...state.portHandlers]) {\n handler({ type: 'message-port-close', remoteUuid: context.remoteUuid, portId: portId as Uuid })\n }\n state.portHandlers.clear()\n })\n}\n\nexport const isType = (value: unknown): value is MessagePort | EventPort<StructurableTransferable> =>\n value instanceof MessagePort || value instanceof EventPort\n\nconst sendClose = (context: RevivableContext, portId: Uuid) => {\n try {\n context.sendMessage({ type: 'message-port-close', remoteUuid: context.remoteUuid, portId })\n } catch { /* connection torn down */ }\n}\n\nconst postRevived = <T>(port: AnyPort<T>, data: T, synthetic: boolean) => {\n if (synthetic) port.postMessage(data)\n else port.postMessage(data, getTransferableObjects(data))\n}\n\nexport const box = <T, T2 extends RevivableContext = RevivableContext>(\n value: StructurableTransferablePort<T>,\n context: T2,\n options?: { autoBox?: boolean },\n): BoxedMessagePort<T> => {\n // Synthetic EventPorts aren't structured-clonable, so even on a clone\n // transport we route them via portId.\n const synthetic = value instanceof EventPort\n if (!synthetic && !isJsonOnlyTransport(context.transport)) {\n return {\n ...BoxBase, type, port: value,\n ...(options?.autoBox ? { autoBox: true } : {}),\n } as BoxedMessagePort<T>\n }\n\n const { portHandlers } = getState(context)\n const liveRef: AnyPort<T> = value\n const portId: Uuid = globalThis.crypto.randomUUID()\n\n // The FR-held cleanup must not (transitively) strong-hold liveRef or the\n // context — the gc-tracker contract — or the registry pins them forever\n // and the safety net can never fire.\n const liveRefWeak = new WeakRef(liveRef)\n const contextWeak = new WeakRef(context)\n const portHandlersWeak = new WeakRef(portHandlers)\n\n let cleanedUp = false\n const performCleanup = () => {\n if (cleanedUp) return\n cleanedUp = true\n portHandlersWeak.deref()?.delete(portId)\n unregisterGc?.()\n const live = liveRefWeak.deref()\n live?.removeEventListener('message', outgoingListener as EventListener)\n if (live instanceof EventPort) live._onClose = undefined\n }\n\n const handler = (message: Messages) => {\n if (message.type === 'message-port-close') {\n performCleanup()\n // Peer side closed — surface the platform 'close' event before closing.\n liveRef.dispatchEvent(new Event('close'))\n liveRef.close()\n return\n }\n postRevived(liveRef, recursiveRevive(message.data, context) as T, false)\n }\n\n function outgoingListener({ data }: MessageEvent<Capable>) {\n context.sendMessage({\n type: 'message',\n remoteUuid: context.remoteUuid,\n data: recursiveBox(data, context),\n portId,\n })\n }\n\n // Safety net only — `handler` strong-holds liveRef via portHandlers, so\n // the FR won't fire while the connection is alive. Real cleanup runs via\n // the wire `message-port-close`, EventPort `_onClose`, or teardown.\n const unregisterGc = trackGc(liveRef, () => {\n const ctx = contextWeak.deref()\n if (ctx) sendClose(ctx, portId)\n performCleanup()\n })\n\n liveRef.addEventListener('message', outgoingListener as EventListener)\n liveRef.start()\n\n if (liveRef instanceof EventPort) {\n liveRef._onClose = () => {\n if (cleanedUp) return\n sendClose(context, portId)\n performCleanup()\n }\n }\n\n portHandlers.set(portId, handler)\n\n return { ...BoxBase, type, portId, synthetic } as BoxedMessagePort<T>\n}\n\nexport const revive = <T extends Capable, T2 extends RevivableContext>(\n value: BoxedMessagePort<T>,\n context: T2,\n): TypedMessagePort<T> => {\n if ('port' in value) {\n if (value.autoBox) return createProtocolPort<T>(value.port as TypedMessagePort<Capable>, context)\n return value.port\n }\n return reviveViaPortId<T>(value.portId, context, value.synthetic)\n}\n\n/** Wraps a real MessagePort so revivables can treat it like a transparent\n * EventTarget that auto-boxes/revives — letting live values (Promises,\n * Functions, …) ride a clone-only transport. */\nconst createProtocolPort = <T>(\n port: TypedMessagePort<Capable>,\n ctx: RevivableContext,\n): TypedMessagePort<T> => {\n const target = new EventTarget() as TypedMessagePort<T>\n const onMessage = ({ data }: MessageEvent<Capable>): void => {\n target.dispatchEvent(new MessageEvent('message', { data: recursiveRevive(data, ctx) }))\n }\n // Modern browsers fire 'close' on a MessagePort when its entangled peer\n // closes or its realm dies — forward it so consumers can clean up.\n const onClose = (): void => {\n target.dispatchEvent(new Event('close'))\n }\n port.addEventListener('message', onMessage)\n port.addEventListener('close', onClose as EventListener)\n target.postMessage = (data: T, opt?: Transferable[] | StructuredSerializeOptions) => {\n const boxed = recursiveBox(data as Capable, ctx)\n const transferables = getTransferableObjects(boxed)\n const extra = Array.isArray(opt) ? opt : []\n port.postMessage(boxed, extra.length ? [...transferables, ...extra] : transferables)\n }\n target.start = () => port.start()\n target.close = () => {\n port.removeEventListener('message', onMessage)\n port.removeEventListener('close', onClose as EventListener)\n port.close()\n }\n return target\n}\n\n/** Factory for revivable-internal channels. Returns a local port that\n * auto-boxes live values regardless of transport, plus a pre-boxed remote\n * port the revivable embeds in its Boxed* structure. */\nexport const createRevivableChannel = <T extends Capable>(\n context: RevivableContext,\n): { localPort: AnyPort<T>, boxedRemote: BoxedMessagePort<T> } => {\n if (isJsonOnlyTransport(context.transport)) {\n const { port1, port2 } = new EventChannel<T, T>()\n return {\n localPort: port1,\n boxedRemote: box(port2 as StructurableTransferablePort<T>, context),\n }\n }\n const { port1, port2 } = new MessageChannel() as unknown as TypedMessageChannel<Capable, Capable>\n return {\n localPort: createProtocolPort<T>(port1, context) as unknown as AnyPort<T>,\n boxedRemote: box(port2 as unknown as StructurableTransferablePort<T>, context, { autoBox: true }),\n }\n}\n\nconst reviveViaPortId = <T extends Capable>(\n portId: Uuid,\n context: RevivableContext,\n synthetic: boolean,\n): TypedMessagePort<T> => {\n const { portHandlers } = getState(context)\n const { port1: userPort, port2: internalPort } =\n synthetic\n ? new EventChannel<T, T>()\n : new MessageChannel() as unknown as TypedMessageChannel<T, T>\n const userPortRef = new WeakRef(userPort)\n // For synthetic EventChannels, internalPort._peer === userPort — holding\n // internalPort strongly from the trackGc cleanup would re-pin userPort.\n const internalPortRef = new WeakRef(internalPort)\n\n let cleanedUp = false\n const performCleanup = () => {\n if (cleanedUp) return\n cleanedUp = true\n portHandlers.delete(portId)\n const internal = internalPortRef.deref()\n internal?.removeEventListener('message', internalPortListener as EventListener)\n internal?.close()\n unregisterGc?.()\n }\n\n const handler = (message: Messages) => {\n if (message.type === 'message-port-close') {\n performCleanup()\n const user = userPortRef.deref()\n // Peer side closed — surface the platform 'close' event before closing.\n user?.dispatchEvent(new Event('close'))\n user?.close()\n return\n }\n if (!userPortRef.deref()) {\n performCleanup()\n return\n }\n const internal = internalPortRef.deref()\n if (!internal) return\n postRevived(internal, recursiveRevive(message.data, context) as T, synthetic)\n }\n\n const internalPortListener = ({ data }: MessageEvent<T>) => {\n context.sendMessage({\n type: 'message',\n remoteUuid: context.remoteUuid,\n data: recursiveBox(data, context),\n portId,\n })\n }\n\n const unregisterGc = trackGc(userPort, () => {\n sendClose(context, portId)\n performCleanup()\n })\n\n if (userPort instanceof EventPort) {\n userPort._onClose = () => {\n if (cleanedUp) return\n sendClose(context, portId)\n performCleanup()\n }\n }\n\n internalPort.addEventListener('message', internalPortListener as EventListener)\n internalPort.start()\n\n portHandlers.set(portId, handler)\n\n return userPort\n}\n\nconst typeCheck = () => {\n const port = {} as TypedMessagePort<{ foo: string }>\n const boxed = box(port, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: AnyPort<{ foo: string }> = revived\n // @ts-expect-error - wrong message type\n const wrongType: AnyPort<{ bar: number }> = revived\n box({} as TypedMessagePort<Promise<string>>, {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { UnderlyingType } from './index.js'\nimport type {\n BadFieldValue, BadFieldPath, BadFieldParent,\n ErrorMessage, BadValue, Path, ParentObject\n} from '../utils/capable-check.js'\n\nimport { BoxBase } from './utils.js'\nimport { onTeardown } from '../utils/teardown.js'\nimport {\n createRevivableChannel,\n revive as reviveMessagePort,\n BoxedMessagePort,\n AnyPort,\n} from './message-port.js'\n\nexport const type = 'promise' as const\n\nexport type Context =\n | { type: 'resolve', data: Capable }\n | { type: 'reject', error: Capable }\n\n// Error branches intersect with T so the user's own keys land on the target —\n// otherwise TS's excess-property check flags a user key instead of the failure.\ntype CapablePromise<T> = T extends Promise<infer U>\n ? U extends Capable\n ? T\n : T & {\n [ErrorMessage]: 'Value type must extend a Promise that resolves to a Capable'\n [BadValue]: BadFieldValue<U, Capable>\n [Path]: BadFieldPath<U, Capable>\n [ParentObject]: BadFieldParent<U, Capable>\n }\n : T & {\n [ErrorMessage]: 'Value type must extend a Promise that resolves to a Capable'\n [BadValue]: T\n [Path]: ''\n [ParentObject]: T\n }\n\ntype ExtractCapable<T> = T extends Promise<infer U>\n ? U extends Capable ? U : never\n : never\n\nconst isCapablePromise = <T, U extends Capable = ExtractCapable<T>>(value: T): value is T & Promise<U> =>\n value instanceof Promise\n\nexport type BoxedPromise<T extends Capable = Capable> =\n & BoxBaseType<typeof type>\n & { port: BoxedMessagePort<Context> }\n & { [UnderlyingType]: T }\n\n// Pins the revived port between executor return and result arrival — the\n// port↔listener cycle has no other anchor (the caller only holds the\n// returned Promise). The once-listener removes its entry on settle.\nconst inFlightPromisePorts = new Set<AnyPort<Context>>()\n\nexport const isType = (value: unknown): value is Promise<any> =>\n value instanceof Promise\n\nexport const box = <T, T2 extends RevivableContext>(\n value: CapablePromise<T>,\n context: T2\n): BoxedPromise<ExtractCapable<T>> => {\n if (!isCapablePromise(value)) throw new TypeError('Expected Promise')\n const { localPort, boxedRemote } = createRevivableChannel<Context>(context)\n\n const sendResult = (result: Context) => {\n localPort.postMessage(result)\n localPort.close()\n }\n\n value\n .then((data: ExtractCapable<T>) => sendResult({ type: 'resolve', data }))\n .catch((error: unknown) => sendResult({ type: 'reject', error: error as Capable }))\n\n return { ...BoxBase, type, port: boxedRemote } as BoxedPromise<ExtractCapable<T>>\n}\n\nexport const revive = <T extends BoxedPromise, T2 extends RevivableContext>(\n value: T,\n context: T2\n) => {\n const port = reviveMessagePort(value.port, context)\n inFlightPromisePorts.add(port)\n // portId boxes route over the wire and die with the connection; real\n // transferred MessagePorts (clone transports) keep working past protocol\n // teardown, so those must stay pending rather than reject.\n const wireRouted = 'portId' in value.port\n return new Promise<T[UnderlyingType]>((resolve, reject) => {\n const settle = () => {\n port.close()\n inFlightPromisePorts.delete(port)\n removeTeardown()\n }\n const removeTeardown = !wireRouted ? () => {} : onTeardown(context, () => {\n reject(new Error('osra: connection closed'))\n settle()\n })\n port.addEventListener('message', ({ data: result }) => {\n if (result.type === 'resolve') resolve(result.data as T[UnderlyingType])\n else reject(result.error)\n settle()\n }, { once: true })\n port.start()\n })\n}\n\nconst typeCheck = () => {\n const boxed = box(Promise.resolve(1 as const), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Promise<1> = revived\n // @ts-expect-error\n const notExpected: Promise<string> = revived\n // @ts-expect-error\n box(1 as const, {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { UnderlyingType, RevivableContext, BoxBase as BoxBaseType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox } from './index.js'\nimport { getTransferableObjects } from '../utils/transferable.js'\nimport { EventChannel, type EventPort } from '../utils/event-channel.js'\nimport { onTeardown } from '../utils/teardown.js'\nimport { box as boxMessagePort, revive as reviveMessagePort, BoxedMessagePort } from './message-port.js'\n\nexport const type = 'function' as const\n\ntype ResultMessage =\n | { type: 'return', value: Capable }\n | { type: 'throw', error: Capable }\n\ntype CallContext = [EventPort<Capable>, Capable[]]\n\n// Pins return-value ports between call-site return and result arrival —\n// the (port ↔ once-listener ↔ resolve/reject) cycle has no other anchor.\nconst inFlightReturnPorts = new Set<EventPort<Capable>>()\n\nexport type BoxedFunction<T extends (...args: any[]) => any = (...args: any[]) => any> =\n & BoxBaseType<typeof type>\n & { port: BoxedMessagePort<CallContext> }\n & { [UnderlyingType]: (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>> }\n\ntype CapableFunction<T> = T extends (...args: infer P) => infer R\n ? P extends Capable[]\n ? R extends Capable ? T : never\n : never\n : never\n\nexport const isType = (value: unknown): value is (...args: any[]) => any =>\n typeof value === 'function'\n\nexport const box = <T extends (...args: any[]) => any, T2 extends RevivableContext>(\n value: T & CapableFunction<T>,\n context: T2,\n): BoxedFunction<T> => {\n // EventChannel rather than MessageChannel: revived live values arriving\n // in args (functions, EventTarget façades, …) aren't structured-clonable.\n const { port1: localPort, port2: remotePort } = new EventChannel<CallContext, CallContext>()\n\n localPort.addEventListener('message', ({ data }) => {\n // Don't recursiveRevive — message-port handler already revived in place.\n // Re-walking would Object.fromEntries plain args, breaking identity.\n const [returnPort, args] = data as CallContext\n ;(async () => {\n let message: ResultMessage\n try {\n const resolved = await value(...(args as Parameters<T>))\n message = { type: 'return', value: resolved as Capable }\n } catch (error) {\n message = { type: 'throw', error: error as Capable }\n }\n const boxedResult = recursiveBox(message as Capable, context)\n returnPort.postMessage(boxedResult, getTransferableObjects(boxedResult))\n // Defer close so the result reaches the peer before tear-down. The\n // close fires _onClose, dropping per-call routing entries on both\n // sides — without it portHandlers grows one entry per call.\n queueMicrotask(() => {\n try { returnPort.close() } catch { /* may already be closed */ }\n })\n })()\n })\n localPort.start()\n\n return {\n ...BoxBase,\n type,\n port: boxMessagePort(remotePort as unknown as MessagePort, context),\n } as unknown as BoxedFunction<T>\n}\n\nexport const revive = <T extends BoxedFunction, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): T[UnderlyingType] => {\n const port = reviveMessagePort(value.port, context) as unknown as MessagePort\n\n return ((...args: Capable[]) =>\n new Promise((resolve, reject) => {\n const { port1: returnLocal, port2: returnRemote } = new EventChannel<Capable, Capable>()\n inFlightReturnPorts.add(returnLocal)\n\n const settle = () => {\n returnLocal.close()\n inFlightReturnPorts.delete(returnLocal)\n removeTeardown()\n }\n // Calls always route over the wire (EventPorts are synthetic on every\n // transport), so connection death must reject them — GC-drop of the\n // proxy intentionally does not (see funcDropDoesNotRejectPending).\n const removeTeardown = onTeardown(context, () => {\n reject(new Error('osra: connection closed'))\n settle()\n })\n\n returnLocal.addEventListener('message', ({ data }) => {\n const message = data as ResultMessage\n if (message.type === 'return') resolve(message.value)\n else reject(message.error)\n settle()\n }, { once: true })\n returnLocal.start()\n\n const callContext = recursiveBox([returnRemote, args] as unknown as Capable, context)\n port.postMessage(callContext, getTransferableObjects(callContext))\n })) as T[UnderlyingType]\n}\n\nconst typeCheck = () => {\n const boxed = box((a: number, b: string) => a + b.length, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: (a: number, b: string) => Promise<number> = revived\n // @ts-expect-error - wrong return type\n const wrongReturn: (a: number, b: string) => Promise<string> = revived\n // @ts-expect-error - wrong parameter types\n const wrongParams: (a: string, b: number) => Promise<number> = revived\n // @ts-expect-error - non-Capable parameter type (WeakMap isn't structured-clonable)\n box((a: WeakMap<object, string>) => a.toString(), {} as RevivableContext)\n // @ts-expect-error - non-Capable return type\n box(() => new WeakMap<object, string>(), {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { UnderlyingType } from './index.js'\n\nimport { BoxBase } from './utils.js'\nimport {\n createRevivableChannel,\n revive as reviveMessagePort,\n BoxedMessagePort\n} from './message-port.js'\n\nexport const type = 'readableStream' as const\n\nexport type PullContext =\n | { type: 'pull' }\n | { type: 'cancel', reason?: Capable }\n\ntype ChunkMessage<T = unknown> = Promise<ReadableStreamReadResult<T>>\n\ntype Msg = PullContext | ChunkMessage\n\nexport type BoxedReadableStream<T extends ReadableStream = ReadableStream> =\n & BoxBaseType<typeof type>\n & { port: BoxedMessagePort<Msg> }\n & { [UnderlyingType]: T }\n\nexport const isType = (value: unknown): value is ReadableStream =>\n value instanceof ReadableStream\n\nexport const box = <T extends ReadableStream, T2 extends RevivableContext>(\n value: T,\n context: T2\n): BoxedReadableStream<T> => {\n const { localPort, boxedRemote } = createRevivableChannel<Msg>(context)\n const reader = value.getReader()\n\n localPort.addEventListener('message', ({ data }) => {\n if ('type' in data && data.type === 'pull') {\n // reader.read() is a Promise — localPort boxes it for the transport.\n localPort.postMessage(reader.read())\n } else {\n reader.cancel('type' in data ? data.reason : undefined).catch(() => {})\n localPort.close()\n }\n })\n // Abnormal channel death (consumer dropped, connection closed): stop the\n // producer and release the source lock instead of leaking both forever.\n localPort.addEventListener('close', () => {\n reader.cancel(new Error('osra: connection closed')).catch(() => {})\n }, { once: true })\n localPort.start()\n\n return { ...BoxBase, type, port: boxedRemote } as BoxedReadableStream<T>\n}\n\nexport const revive = <T extends BoxedReadableStream, T2 extends RevivableContext>(\n value: T,\n context: T2\n): T[UnderlyingType] => {\n const port = reviveMessagePort(value.port, context)\n port.start()\n\n let done = false\n return new ReadableStream({\n start: (controller) => {\n // Channel death mid-stream (source dropped, connection closed): error\n // the consumer instead of hanging its pending read forever.\n port.addEventListener('close', () => {\n if (done) return\n done = true\n try { controller.error(new Error('osra: connection closed')) } catch { /* already settled */ }\n }, { once: true })\n },\n pull: (controller) => new Promise<void>((resolve, reject) => {\n port.addEventListener('message', ({ data }) => {\n if (!(data instanceof Promise)) return\n data\n .then(result => {\n if (result.done) {\n done = true\n controller.close()\n // Stream exhausted — release the channel on both sides.\n port.postMessage({ type: 'cancel' })\n queueMicrotask(() => port.close())\n }\n else controller.enqueue(result.value)\n resolve()\n })\n .catch(error => {\n done = true\n reject(error)\n })\n }, { once: true })\n port.postMessage({ type: 'pull' })\n }),\n cancel: (reason) => {\n done = true\n port.postMessage({ type: 'cancel', reason: reason as Capable })\n // Defer close so the cancel message dispatches before tear-down.\n queueMicrotask(() => port.close())\n },\n }) as T[UnderlyingType]\n}\n\nconst typeCheck = () => {\n const stream = new ReadableStream<number>()\n const boxed = box(stream, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: ReadableStream<number> = revived\n // @ts-expect-error - wrong stream type\n const wrongType: ReadableStream<string> = revived\n // @ts-expect-error - not a ReadableStream\n box('not a stream', {} as RevivableContext)\n}\n","import type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { UnderlyingType } from './index.js'\nimport type { Capable } from '../types.js'\n\nimport { BoxBase } from './utils.js'\nimport {\n createRevivableChannel,\n revive as reviveMessagePort,\n BoxedMessagePort,\n} from './message-port.js'\n\nexport const type = 'writableStream' as const\n\n// Outgoing wire shape (revive → box): one of these per call.\nexport type WriteContext =\n | { type: 'write', chunk: Capable }\n | { type: 'close' }\n | { type: 'abort', reason: Capable }\n\n// Reply from box → revive after a write completes (so writer.write() awaits).\nexport type WriteAck =\n | { type: 'ack' }\n | { type: 'err', error: string }\n\nexport type Msg = WriteContext | WriteAck\n\nexport type BoxedWritableStream<T extends WritableStream = WritableStream> =\n & BoxBaseType<typeof type>\n & { port: BoxedMessagePort<Msg> }\n & { [UnderlyingType]: T }\n\nexport const isType = (value: unknown): value is WritableStream =>\n value instanceof WritableStream\n\nexport const box = <T extends WritableStream, T2 extends RevivableContext>(\n value: T,\n context: T2\n): BoxedWritableStream<T> => {\n const { localPort, boxedRemote } = createRevivableChannel<Msg>(context)\n const writer = value.getWriter()\n\n let terminated = false\n const settle = (op: Promise<void>, terminal: boolean) =>\n op\n .then(() => localPort.postMessage({ type: 'ack' }))\n .catch((err) => localPort.postMessage({ type: 'err', error: (err as Error)?.message ?? String(err) }))\n .then(() => {\n if (!terminal) return\n terminated = true\n // Terminal op acked — release the channel on both sides.\n queueMicrotask(() => localPort.close())\n })\n\n localPort.addEventListener('message', ({ data }) => {\n if (!data || typeof data !== 'object' || !('type' in data)) return\n if (data.type === 'write') settle(writer.write((data as { chunk: Capable }).chunk as any), false)\n else if (data.type === 'close') settle(writer.close(), true)\n else if (data.type === 'abort') settle(writer.abort((data as { reason: Capable }).reason as any), true)\n })\n // Abnormal channel death (consumer dropped, connection closed): abort the\n // sink and release the writer lock instead of holding both forever.\n localPort.addEventListener('close', () => {\n if (terminated) return\n terminated = true\n writer.abort(new Error('osra: connection closed')).catch(() => {})\n }, { once: true })\n localPort.start()\n\n return { ...BoxBase, type, port: boxedRemote } as BoxedWritableStream<T>\n}\n\nexport const revive = <T extends BoxedWritableStream, T2 extends RevivableContext>(\n value: T,\n context: T2\n): T[UnderlyingType] => {\n const port = reviveMessagePort(value.port, context)\n port.start()\n\n // Channel death mid-write (sink dropped, connection closed): reject every\n // pending request instead of hanging the writer forever.\n const pending = new Set<(error: Error) => void>()\n let dead = false\n port.addEventListener('close', () => {\n dead = true\n const error = new Error('osra: connection closed')\n for (const reject of [...pending]) reject(error)\n pending.clear()\n }, { once: true })\n\n // Each `write` call posts a 'write' message and awaits an 'ack'/'err'.\n // The port is shared, so we serialize via a chain — without it, two\n // concurrent writes would race and could mis-pair their ack messages.\n let chain: Promise<void> = Promise.resolve()\n const request = (msg: WriteContext): Promise<void> => {\n const next = chain.then(() => new Promise<void>((resolve, reject) => {\n if (dead) {\n reject(new Error('osra: connection closed'))\n return\n }\n const settle = (fn: () => void) => {\n pending.delete(reject)\n fn()\n }\n pending.add(reject)\n port.addEventListener('message', ({ data }) => {\n if (!data || typeof data !== 'object' || !('type' in data)) return\n if ((data as { type: string }).type === 'ack') settle(resolve)\n else if ((data as { type: string }).type === 'err') settle(() => reject(new Error((data as { error: string }).error)))\n }, { once: true })\n port.postMessage(msg as Msg)\n }))\n chain = next.catch(() => {})\n return next\n }\n\n return new WritableStream({\n write: (chunk) => request({ type: 'write', chunk: chunk as Capable }),\n close: () => request({ type: 'close' }),\n abort: (reason) => request({ type: 'abort', reason: reason as Capable }),\n }) as T[UnderlyingType]\n}\n\nconst typeCheck = () => {\n const stream = new WritableStream<number>()\n const boxed = box(stream, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: WritableStream<number> = revived\n // @ts-expect-error - wrong stream type\n const wrongType: WritableStream<string> = revived\n // @ts-expect-error - not a WritableStream\n box('not a stream', {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { BoxedMessagePort } from './message-port.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\nimport { onTeardown } from '../utils/teardown.js'\nimport {\n createRevivableChannel,\n revive as reviveMessagePort,\n AnyPort,\n} from './message-port.js'\n\nexport const type = 'abortSignal' as const\n\ntype AbortMessage = {\n type: 'abort'\n reason?: Capable\n}\n\nexport type BoxedAbortSignal =\n & BoxBaseType<typeof type>\n & {\n aborted: boolean\n reason?: Capable\n /** Absent when the signal was already aborted at box time — the reason\n * rides the wrapper and no live channel is needed. */\n port?: BoxedMessagePort<AbortMessage>\n }\n\nexport const isType = (value: unknown): value is AbortSignal =>\n value instanceof AbortSignal\n\n// Pins the revived port for exactly as long as the revived signal is\n// reachable — the port↔listener↔controller subgraph has no other strong\n// root, and a GC of it would silently sever abort propagation.\nconst revivedPortPins = new WeakMap<AbortSignal, AnyPort<AbortMessage>>()\n\nexport const box = <T extends AbortSignal, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedAbortSignal => {\n // Eagerly-aborted reason rides the wrapper, so we must box it here —\n // recursiveBox short-circuits on OSRA_BOX without descending in.\n if (value.aborted) {\n return {\n ...BoxBase,\n type,\n aborted: true,\n reason: recursiveBox(value.reason as Capable, context) as Capable,\n }\n }\n\n const { localPort, boxedRemote } = createRevivableChannel<AbortMessage>(context)\n\n const onSourceAbort = () => {\n localPort.postMessage({ type: 'abort', reason: value.reason as Capable })\n localPort.close()\n removeTeardown()\n }\n // Long-lived signals accumulate one listener per send otherwise —\n // connection death must release them.\n const removeTeardown = onTeardown(context, () => {\n value.removeEventListener('abort', onSourceAbort)\n localPort.close()\n })\n value.addEventListener('abort', onSourceAbort, { once: true })\n\n return {\n ...BoxBase,\n type,\n aborted: false,\n reason: undefined,\n port: boxedRemote,\n }\n}\n\nexport const revive = <T extends BoxedAbortSignal, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): AbortSignal => {\n const controller = new AbortController()\n\n if (value.aborted || value.port === undefined) {\n controller.abort(recursiveRevive(value.reason as Capable, context))\n return controller.signal\n }\n\n const port = reviveMessagePort(value.port, context)\n revivedPortPins.set(controller.signal, port)\n port.start()\n\n port.addEventListener('message', ({ data: message }) => {\n if (message.type === 'abort') {\n controller.abort(recursiveRevive(message.reason as Capable, context))\n revivedPortPins.delete(controller.signal)\n port.close()\n }\n })\n\n return controller.signal\n}\n\nconst typeCheck = () => {\n const boxed = box(new AbortController().signal, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: AbortSignal = revived\n // @ts-expect-error - not an AbortSignal\n const notAbortSignal: string = revived\n // @ts-expect-error - cannot box non-AbortSignal\n box('not an abort signal', {} as RevivableContext)\n}\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { box as boxHeaders, revive as reviveHeaders } from './headers.js'\nimport { box as boxReadableStream, revive as reviveReadableStream } from './readable-stream.js'\n\nexport const type = 'response' as const\n\nexport const isType = (value: unknown): value is Response =>\n value instanceof Response\n\nexport const box = <T extends Response, T2 extends RevivableContext>(\n value: T,\n context: T2\n) => ({\n ...BoxBase,\n type,\n status: value.status,\n statusText: value.statusText,\n headers: boxHeaders(value.headers, context),\n body: value.body ? boxReadableStream(value.body, context) : null,\n url: value.url,\n redirected: value.redirected\n})\n\nexport const revive = <T extends ReturnType<typeof box>, T2 extends RevivableContext>(\n value: T,\n context: T2\n): Response => {\n // Opaque/error responses report status 0, which the constructor rejects.\n if (value.status === 0) return Response.error()\n\n const headers = reviveHeaders(value.headers, context)\n const body = value.body ? reviveReadableStream(value.body, context) : null\n\n const response = new Response(body, {\n status: value.status,\n statusText: value.statusText,\n headers\n })\n // url/redirected are read-only getters fed by internal state the\n // constructor can't set — shadow them so the round trip is faithful.\n if (value.url) Object.defineProperty(response, 'url', { value: value.url, configurable: true })\n if (value.redirected) Object.defineProperty(response, 'redirected', { value: true, configurable: true })\n return response\n}\n\nconst typeCheck = () => {\n const boxed = box(new Response('body', { status: 200 }), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Response = revived\n // @ts-expect-error - not a Response\n const notResponse: string = revived\n // @ts-expect-error - cannot box non-Response\n box('not a response', {} as RevivableContext)\n}\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { box as boxHeaders, revive as reviveHeaders } from './headers.js'\nimport { box as boxReadableStream, revive as reviveReadableStream } from './readable-stream.js'\nimport { box as boxAbortSignal, revive as reviveAbortSignal } from './abort-signal.js'\n\nexport const type = 'request' as const\n\nexport const isType = (value: unknown): value is Request =>\n value instanceof Request\n\nexport const box = <T extends Request, T2 extends RevivableContext>(\n value: T,\n context: T2\n) => ({\n ...BoxBase,\n type,\n method: value.method,\n url: value.url,\n headers: boxHeaders(value.headers, context),\n body: value.body ? boxReadableStream(value.body, context) : null,\n credentials: value.credentials,\n cache: value.cache,\n mode: value.mode,\n redirect: value.redirect,\n referrer: value.referrer,\n referrerPolicy: value.referrerPolicy,\n integrity: value.integrity,\n keepalive: value.keepalive,\n signal: boxAbortSignal(value.signal, context),\n})\n\nexport const revive = <T extends ReturnType<typeof box>, T2 extends RevivableContext>(\n value: T,\n context: T2\n): Request => {\n const headers = reviveHeaders(value.headers, context)\n\n // Firefox normalizes `body: null` in the constructor to a Request whose\n // `.body` getter returns `undefined` instead of `null`. Only pass `body`\n // when there's an actual stream so a bodyless source round-trips to a\n // bodyless Request on every browser.\n const init: RequestInit & { duplex?: 'half' } = {\n method: value.method,\n headers,\n credentials: value.credentials,\n cache: value.cache,\n redirect: value.redirect,\n referrer: value.referrer,\n referrerPolicy: value.referrerPolicy,\n integrity: value.integrity,\n keepalive: value.keepalive,\n signal: reviveAbortSignal(value.signal, context),\n }\n // 'navigate' is not constructible via RequestInit.\n if (value.mode !== 'navigate') init.mode = value.mode\n if (value.body) {\n init.body = reviveReadableStream(value.body, context)\n init.duplex = 'half'\n }\n\n return new Request(value.url, init)\n}\n\nconst typeCheck = () => {\n const boxed = box(new Request('https://example.com'), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Request = revived\n // @ts-expect-error - not a Request\n const notRequest: string = revived\n // @ts-expect-error - cannot box non-Request\n box('not a request', {} as RevivableContext)\n}\n","import type { Capable, Uuid } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { UnderlyingType } from '../utils/type.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\nimport { onTeardown } from '../utils/teardown.js'\n\nexport const type = 'identity' as const\n\nexport type Messages = {\n type: 'identity-dispose'\n remoteUuid: Uuid\n id: string\n}\n\nexport declare const Messages: Messages\n\nconst IDENTITY_MARKER: unique symbol = Symbol.for('osra.identity')\n\ntype IdentityWrapper<T = unknown> = {\n readonly [IDENTITY_MARKER]: true\n readonly value: T\n}\n\nexport type BoxedIdentity<T extends Capable = Capable> = BoxBaseType<typeof type> & {\n id: string\n inner?: Capable\n [UnderlyingType]: T\n}\n\nconst isObjectOrFunction = (value: unknown): value is object =>\n value !== null && (typeof value === 'object' || typeof value === 'function')\n\n/** Anything we can hand to WeakMap/WeakRef/FinalizationRegistry. Excludes\n * registered symbols (Symbol.for) — those throw at runtime. */\nconst isWeakKeyable = (value: unknown): value is WeakKey => {\n if (value === null) return false\n const t = typeof value\n if (t === 'object' || t === 'function') return true\n if (t === 'symbol') return Symbol.keyFor(value as symbol) === undefined\n return false\n}\n\nconst isIdentityWrapper = (value: unknown): value is IdentityWrapper =>\n isObjectOrFunction(value) && IDENTITY_MARKER in value && value[IDENTITY_MARKER] === true\n\nconst wrapperMemo = new WeakMap<object, IdentityWrapper>()\n\nconst wrap = (value: object): IdentityWrapper => {\n if (isIdentityWrapper(value)) return value\n const cached = wrapperMemo.get(value)\n if (cached) return cached\n const wrapper: IdentityWrapper = { [IDENTITY_MARKER]: true, value }\n wrapperMemo.set(value, wrapper)\n return wrapper\n}\n\n/** Wrap a value so osra preserves reference identity across the RPC\n * boundary. Idempotent; primitives pass through unchanged. Lies at the\n * type level — runtime value is an IdentityWrapper<T> typed as T. */\nexport const identity = <T>(value: T): T =>\n (isObjectOrFunction(value) ? wrap(value) : value) as T\n\ntype IdentityState = {\n readonly sendIds: WeakMap<WeakKey, string>\n /** id → ref to the value we sent, so a round-trip resolves to the\n * original reference instead of building a fresh proxy. */\n readonly idToSent: Map<string, WeakRef<WeakKey>>\n readonly sendRegistry: FinalizationRegistry<string>\n readonly receiveCache: Map<string, unknown>\n /** Revived value → id, so user code passing a revived value back to\n * its origin replays the peer's id and short-circuits to the real ref. */\n readonly revivedToId: WeakMap<WeakKey, string>\n listenerInstalled: boolean\n}\n\nconst connectionStates = new WeakMap<RevivableContext, IdentityState>()\n\nconst getOrCreateState = (context: RevivableContext): IdentityState => {\n const existing = connectionStates.get(context)\n if (existing) return existing\n const sendIds = new WeakMap<WeakKey, string>()\n const idToSent = new Map<string, WeakRef<WeakKey>>()\n const receiveCache = new Map<string, unknown>()\n const revivedToId = new WeakMap<WeakKey, string>()\n const sendRegistry = new FinalizationRegistry<string>((id) => {\n idToSent.delete(id)\n try {\n context.sendMessage({ type: 'identity-dispose', remoteUuid: context.remoteUuid, id })\n } catch { /* connection already closed */ }\n })\n const state: IdentityState = {\n sendIds, idToSent, sendRegistry, receiveCache, revivedToId,\n listenerInstalled: false,\n }\n connectionStates.set(context, state)\n installReceiveListener(context, state)\n onTeardown(context, () => {\n state.receiveCache.clear()\n state.idToSent.clear()\n })\n return state\n}\n\nconst installReceiveListener = (context: RevivableContext, state: IdentityState) => {\n if (state.listenerInstalled) return\n state.listenerInstalled = true\n context.eventTarget.addEventListener('message', ({ detail }) => {\n if (detail?.type !== 'identity-dispose') return\n const revived = state.receiveCache.get(detail.id)\n state.receiveCache.delete(detail.id)\n if (revived !== undefined && isWeakKeyable(revived)) state.revivedToId.delete(revived)\n })\n}\n\nexport const isType = (value: unknown): value is IdentityWrapper =>\n isIdentityWrapper(value)\n\n/** Look up or assign the id for a referenceable value. Returns whether\n * the id is already-known (resend or round-trip) so the caller can skip\n * shipping the inner payload. */\nconst registerForReference = (\n value: WeakKey,\n state: IdentityState,\n): { id: string, isExisting: boolean } => {\n const existingId = state.sendIds.get(value)\n if (existingId !== undefined) return { id: existingId, isExisting: true }\n const receivedId = state.revivedToId.get(value)\n if (receivedId !== undefined) return { id: receivedId, isExisting: true }\n const id = globalThis.crypto.randomUUID()\n state.sendIds.set(value, id)\n state.idToSent.set(id, new WeakRef(value))\n state.sendRegistry.register(value, id)\n return { id, isExisting: false }\n}\n\nexport const box = <T extends Capable, TContext extends RevivableContext>(\n wrapper: IdentityWrapper<T>,\n context: TContext,\n): BoxedIdentity<T> => {\n const state = getOrCreateState(context)\n const inner = wrapper.value\n const innerBox = recursiveBox(inner, context)\n if (!isWeakKeyable(inner)) {\n // Inner can't anchor a WeakMap key — emit fresh id+inner each time, no dedup.\n return { ...BoxBase, type, id: globalThis.crypto.randomUUID(), inner: innerBox } as BoxedIdentity<T>\n }\n const { id, isExisting } = registerForReference(inner, state)\n if (isExisting) return { ...BoxBase, type, id } as BoxedIdentity<T>\n return { ...BoxBase, type, id, inner: innerBox } as BoxedIdentity<T>\n}\n\n/** Identity-box a referenceable value with a caller-supplied inner box,\n * bypassing the recursive-box step. Used by revivables (symbol with\n * description=undefined) where recursing back through their own box\n * would loop into this module again. */\nexport const boxByReference = <T extends WeakKey, TContext extends RevivableContext>(\n value: T,\n innerBox: Capable,\n context: TContext,\n): BoxedIdentity => {\n const state = getOrCreateState(context)\n const { id, isExisting } = registerForReference(value, state)\n if (isExisting) return { ...BoxBase, type, id } as BoxedIdentity\n return { ...BoxBase, type, id, inner: innerBox } as BoxedIdentity\n}\n\nexport const revive = <T extends BoxedIdentity, TContext extends RevivableContext>(\n value: T,\n context: TContext,\n): T[UnderlyingType] => {\n const state = getOrCreateState(context)\n const cached = state.receiveCache.get(value.id)\n if (cached !== undefined) return cached as T[UnderlyingType]\n const originated = state.idToSent.get(value.id)?.deref()\n if (originated !== undefined) return originated as T[UnderlyingType]\n if (!('inner' in value) || value.inner === undefined) {\n throw new Error(`osra identity: received id=${value.id} with no inner payload and no cached value`)\n }\n const revived = recursiveRevive(value.inner, context)\n state.receiveCache.set(value.id, revived)\n if (isWeakKeyable(revived)) state.revivedToId.set(revived, value.id)\n return revived as T[UnderlyingType]\n}\n\nconst typeCheck = () => {\n const fn = () => 42\n const wrapper = { [IDENTITY_MARKER]: true, value: fn } as IdentityWrapper<typeof fn>\n const boxed = box(wrapper, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: typeof fn = revived\n // @ts-expect-error - revived is the original function type, not string\n const notExpected: string = revived\n // @ts-expect-error - cannot box a non-Capable wrapper (WeakMap not assignable)\n box({ [IDENTITY_MARKER]: true, value: new WeakMap() } as IdentityWrapper<WeakMap<object, string>>, {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, UnderlyingType, BoxBase as BoxBaseType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\n\nexport const type = 'map' as const\n\nexport type BoxedMap<T extends Map<Capable, Capable> = Map<Capable, Capable>> =\n & BoxBaseType<typeof type>\n & { entries: Array<[Capable, Capable]> }\n & { [UnderlyingType]: T }\n\n// `Map<unknown, unknown>` (rather than `Map<Capable, Capable>`) breaks the\n// Capable ↔ defaultRevivableModules ↔ this module type cycle. box() still\n// narrows to `Map<Capable, Capable>` so misuse is caught there.\nexport const isType = (value: unknown): value is Map<unknown, unknown> =>\n value instanceof Map\n\nexport const box = <T extends Map<Capable, Capable>, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedMap<T> => ({\n ...BoxBase,\n type,\n entries: Array.from(value, ([k, v]): [Capable, Capable] =>\n [recursiveBox(k, context) as Capable, recursiveBox(v, context) as Capable]),\n}) as BoxedMap<T>\n\nexport const revive = <T extends BoxedMap, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): T[UnderlyingType] =>\n new Map(value.entries.map(([k, v]) => [\n recursiveRevive(k, context),\n recursiveRevive(v, context),\n ])) as T[UnderlyingType]\n\nconst typeCheck = () => {\n const m = new Map<string, number>([['a', 1]])\n const boxed = box(m, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Map<string, number> = revived\n // @ts-expect-error - wrong value type\n const wrongValue: Map<string, string> = revived\n // @ts-expect-error - cannot box non-Map\n box('not a map', {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, UnderlyingType, BoxBase as BoxBaseType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\n\nexport const type = 'set' as const\n\nexport type BoxedSet<T extends Set<Capable> = Set<Capable>> =\n & BoxBaseType<typeof type>\n & { values: Array<Capable> }\n & { [UnderlyingType]: T }\n\n// `Set<unknown>` breaks the Capable ↔ defaultRevivableModules ↔ this module\n// type cycle; box() narrows to `Set<Capable>` so misuse is caught there.\nexport const isType = (value: unknown): value is Set<unknown> =>\n value instanceof Set\n\nexport const box = <T extends Set<Capable>, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedSet<T> => ({\n ...BoxBase,\n type,\n values: Array.from(value, v => recursiveBox(v, context) as Capable),\n}) as BoxedSet<T>\n\nexport const revive = <T extends BoxedSet, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): T[UnderlyingType] =>\n new Set(value.values.map(v => recursiveRevive(v, context))) as T[UnderlyingType]\n\nconst typeCheck = () => {\n const s = new Set<number>([1, 2, 3])\n const boxed = box(s, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Set<number> = revived\n // @ts-expect-error - wrong value type\n const wrongValue: Set<string> = revived\n // @ts-expect-error - cannot box non-Set\n box('not a set', {} as RevivableContext)\n}\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\n\nexport const type = 'bigint' as const\n\nexport const isType = (value: unknown): value is bigint =>\n typeof value === 'bigint'\n\nexport const box = <T extends bigint, T2 extends RevivableContext>(\n value: T,\n _context: T2,\n) => ({\n ...BoxBase,\n type,\n value: value.toString(),\n})\n\nexport const revive = <T extends ReturnType<typeof box>>(\n value: T,\n _context: RevivableContext,\n) => BigInt(value.value)\n\nconst typeCheck = () => {\n const boxed = box(123n, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: bigint = revived\n // @ts-expect-error - not a string\n const notString: string = revived\n // @ts-expect-error - cannot box non-bigint\n box('not a bigint', {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\n\nexport const type = 'event' as const\n\n/** Boxes Event/CustomEvent only. Subclass-specific fields (MessageEvent.data,\n * ErrorEvent.error, ProgressEvent.loaded, etc.) are dropped on the wire. */\nexport type BoxedEvent =\n & BoxBaseType<typeof type>\n & { eventType: string, bubbles: boolean, cancelable: boolean, composed: boolean, detail?: Capable }\n\nexport const isType = (value: unknown): value is Event =>\n value instanceof Event\n\nexport const box = <T extends Event, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedEvent => ({\n ...BoxBase,\n type,\n eventType: value.type,\n bubbles: value.bubbles,\n cancelable: value.cancelable,\n composed: value.composed,\n ...(value instanceof CustomEvent ? { detail: recursiveBox(value.detail as Capable, context) as Capable } : {}),\n})\n\nexport const revive = <T extends BoxedEvent, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): Event => {\n const init = { bubbles: value.bubbles, cancelable: value.cancelable, composed: value.composed }\n return 'detail' in value\n ? new CustomEvent(value.eventType, { ...init, detail: recursiveRevive(value.detail as Capable, context) })\n : new Event(value.eventType, init)\n}\n\nconst typeCheck = () => {\n const boxed = box(new Event('foo'), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Event = revived\n // @ts-expect-error - not an Event\n const notEvent: string = revived\n // @ts-expect-error - cannot box non-Event\n box('not an event', {} as RevivableContext)\n}\n","import { BoxBase, type RevivableContext } from './utils.js'\nimport { identity } from './identity.js'\nimport { box as boxFunction, revive as reviveFunction } from './function.js'\nimport { trackGc } from '../utils/gc-tracker.js'\n\nexport const type = 'eventTarget' as const\n\ntype ListenerOpts = boolean | { capture?: boolean, once?: boolean, passive?: boolean, signal?: AbortSignal }\n\nexport const isType = (value: unknown): value is EventTarget => value instanceof EventTarget\n\nexport const box = <T extends EventTarget, T2 extends RevivableContext>(value: T, context: T2) => {\n // Track what this box added so the façade's GC cleanup can drop everything\n // through one zero-argument RPC — holding no reference to user listeners.\n const added: { eventType: string, listener: EventListener, capture: boolean }[] = []\n const captureOf = (options?: ListenerOpts) =>\n typeof options === 'boolean' ? options : !!options?.capture\n return {\n ...BoxBase,\n type,\n addListener: boxFunction(\n (eventType: string, listener: EventListener, options?: ListenerOpts) => {\n added.push({ eventType, listener, capture: captureOf(options) })\n value.addEventListener(eventType, listener, options)\n },\n context,\n ),\n removeListener: boxFunction(\n (eventType: string, listener: EventListener, options?: ListenerOpts) => {\n const capture = captureOf(options)\n const index = added.findIndex(r =>\n r.eventType === eventType && r.listener === listener && r.capture === capture)\n if (index !== -1) added.splice(index, 1)\n value.removeEventListener(eventType, listener, options)\n },\n context,\n ),\n removeAllListeners: boxFunction(\n () => {\n for (const { eventType, listener, capture } of added.splice(0)) {\n value.removeEventListener(eventType, listener, { capture })\n }\n },\n context,\n ),\n }\n}\n\nexport type BoxedEventTarget = ReturnType<typeof box>\n\n// Stable EventListener per EventListenerObject so identity() yields the\n// same id on add and remove.\nconst objectWrappers = new WeakMap<EventListenerObject, EventListener>()\nconst toListener = (listerObject: EventListenerOrEventListenerObject): EventListener => {\n if (typeof listerObject === 'function') return listerObject\n let listener = objectWrappers.get(listerObject)\n if (!listener) objectWrappers.set(listerObject, listener = (e) => listerObject.handleEvent(e))\n return listener\n}\n\ntype Reg = { eventType: string, listener: EventListener, capture: boolean, wire: EventListener }\n\nconst findReg = (regs: Reg[], eventType: string, listener: EventListener, capture: boolean): Reg | undefined =>\n regs.find(r => r.eventType === eventType && r.listener === listener && r.capture === capture)\n\nexport const revive = <T extends BoxedEventTarget, T2 extends RevivableContext>(value: T, context: T2) => {\n const addRpc = reviveFunction(value.addListener, context)\n const removeRpc = reviveFunction(value.removeListener, context)\n const removeAllRpc = reviveFunction(value.removeAllListeners, context)\n // Façade only — events never dispatch through it. Source-side EventTarget\n // owns all semantics; we just track regs for cleanup.\n const target = new EventTarget()\n const regs: Reg[] = []\n\n const prune = (reg: Reg) => {\n const index = regs.indexOf(reg)\n if (index !== -1) regs.splice(index, 1)\n }\n\n Object.defineProperty(target, 'addEventListener', {\n value: (eventType: string, listener: EventListenerOrEventListenerObject | null, options?: ListenerOpts) => {\n if (listener === null) return\n const fn = toListener(listener)\n const capture = typeof options === 'boolean' ? options : !!options?.capture\n if (findReg(regs, eventType, fn, capture)) return\n const once = typeof options === 'object' && !!options?.once\n // The source side auto-removes once/aborted listeners — prune the\n // local reg in step so the same listener can be re-added later.\n const wire: EventListener = once\n ? (event) => {\n prune(reg)\n return fn(event)\n }\n : fn\n const reg: Reg = { eventType, listener: fn, capture, wire }\n regs.push(reg)\n const signal = typeof options === 'object' ? options?.signal : undefined\n signal?.addEventListener('abort', () => prune(reg), { once: true })\n addRpc(eventType, identity(wire), options).catch(() => {})\n },\n })\n\n Object.defineProperty(target, 'removeEventListener', {\n value: (eventType: string, listener: EventListenerOrEventListenerObject | null, options?: ListenerOpts) => {\n if (listener === null) return\n const fn = toListener(listener)\n const capture = typeof options === 'boolean' ? options : !!options?.capture\n const reg = findReg(regs, eventType, fn, capture)\n if (!reg) return\n prune(reg)\n removeRpc(eventType, identity(reg.wire), { capture }).catch(() => {})\n },\n })\n\n // Cleanup must NOT close over `target`, `regs`, or any user listener —\n // the FR strong-holds it, and a listener closing over the façade would\n // otherwise pin the whole subgraph forever. removeAllRpc only references\n // its own RPC port.\n trackGc(target, () => {\n removeAllRpc().catch(() => {})\n })\n\n return target\n}\n\nconst typeCheck = () => {\n const r = revive(box(new EventTarget(), {} as RevivableContext), {} as RevivableContext)\n const expected: EventTarget = r\n // @ts-expect-error - not a string\n const notString: string = r\n // @ts-expect-error - cannot box non-EventTarget\n box('not an event target', {} as RevivableContext)\n}\n","import type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { UnderlyingType } from '../utils/type.js'\nimport type { BoxedPromise } from './promise.js'\n\nimport { BoxBase } from './utils.js'\nimport { box as boxPromise, revive as revivePromise } from './promise.js'\n\nexport const type = 'blob' as const\n\nexport type BoxedBlob<T extends Blob = Blob> =\n & BoxBaseType<typeof type>\n & { mimeType: string }\n & { buffer: BoxedPromise<ArrayBuffer> }\n & { fileName?: string, lastModified?: number }\n & { [UnderlyingType]: Promise<T> }\n\n// File extends Blob and is handled here too — encoding `name` + `lastModified`\n// when present so the receiver reconstructs a File rather than dropping to a\n// plain Blob. Avoids a runtime/type mismatch where File would type-check as\n// Capable but silently coerce.\nexport const isType = (value: unknown): value is Blob =>\n value instanceof Blob\n\nconst isFile = (value: Blob): value is File =>\n typeof File !== 'undefined' && value instanceof File\n\nexport const box = <T extends Blob, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedBlob<T> => ({\n ...BoxBase,\n type,\n mimeType: value.type,\n buffer: boxPromise(value.arrayBuffer(), context),\n ...(isFile(value)\n ? { fileName: value.name, lastModified: value.lastModified }\n : {}),\n}) as unknown as BoxedBlob<T>\n\n// Blob bytes are fetched async (`blob.arrayBuffer()`), so revive can't\n// hand back a Blob synchronously — receivers `await` to get the Blob.\nexport const revive = <T extends BoxedBlob, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): T[UnderlyingType] =>\n revivePromise(value.buffer, context)\n .then(buffer =>\n value.fileName !== undefined && typeof File !== 'undefined'\n ? new File([buffer], value.fileName, {\n type: value.mimeType,\n lastModified: value.lastModified,\n })\n : new Blob([buffer], { type: value.mimeType })) as T[UnderlyingType]\n\nconst typeCheck = () => {\n const boxed = box(new Blob(['x'], { type: 'text/plain' }), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Promise<Blob> = revived\n // @ts-expect-error - revived is Promise<Blob>, not a sync Blob\n const notBlob: Blob = revived\n // @ts-expect-error - cannot box non-Blob\n box('not a blob', {} as RevivableContext)\n}\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { boxByReference } from './identity.js'\n\nexport const type = 'symbol' as const\n\nexport const isType = (value: unknown): value is symbol =>\n typeof value === 'symbol'\n\nexport const box = <T extends symbol, T2 extends RevivableContext>(\n value: T,\n context: T2,\n) => {\n // Registry symbols carry global identity through their key.\n const registryKey = Symbol.keyFor(value)\n if (registryKey !== undefined) return { ...BoxBase, type, registryKey }\n // Everything else routes through identity so the same symbol revives to\n // the same symbol on every send (and round-trips to the original).\n return boxByReference(value, { ...BoxBase, type, description: value.description }, context)\n}\n\nexport const revive = <\n T extends { registryKey: string } | { description: string | undefined },\n T2 extends RevivableContext,\n>(\n value: T,\n _context: T2,\n): symbol =>\n 'registryKey' in value\n ? Symbol.for(value.registryKey)\n : Symbol(value.description)\n\nconst typeCheck = () => {\n const boxed = box(Symbol('foo'), {} as RevivableContext)\n const revivedDescribed = revive({ description: 'foo' }, {} as RevivableContext)\n const expected: symbol = revivedDescribed\n const revivedRegistered = revive({ registryKey: 'foo' }, {} as RevivableContext)\n const expectedRegistered: symbol = revivedRegistered\n // @ts-expect-error - not a string\n const notString: string = revivedDescribed\n // @ts-expect-error - cannot box non-symbol\n box('not a symbol', {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { box as boxFunction, revive as reviveFunction, BoxedFunction } from './function.js'\n\nexport const type = 'asyncIterator' as const\n\ntype AnyAsyncIterable = { [Symbol.asyncIterator]: () => AsyncIterator<unknown> }\n\nexport type BoxedAsyncIterator =\n & BoxBaseType<typeof type>\n & {\n next: BoxedFunction\n return: BoxedFunction\n throw: BoxedFunction\n }\n\nexport const isType = (value: unknown): value is AnyAsyncIterable => {\n if (!value || typeof value !== 'object') return false\n // ReadableStream is async-iterable on some platforms but has its own\n // revivable — belt and braces for custom module orders.\n if (typeof ReadableStream !== 'undefined' && value instanceof ReadableStream) return false\n return typeof (value as Record<symbol, unknown>)[Symbol.asyncIterator] === 'function'\n}\n\nexport const box = <T extends AnyAsyncIterable, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedAsyncIterator => {\n const iterator = value[Symbol.asyncIterator]()\n return {\n ...BoxBase,\n type,\n next: boxFunction(((arg?: Capable) => iterator.next(arg)) as never, context) as unknown as BoxedFunction,\n return: boxFunction(((arg?: Capable) =>\n iterator.return?.(arg) ?? Promise.resolve({ done: true as const, value: arg })) as never, context) as unknown as BoxedFunction,\n throw: boxFunction(((error?: Capable) =>\n iterator.throw?.(error) ?? Promise.reject(error)) as never, context) as unknown as BoxedFunction,\n }\n}\n\nexport const revive = <T extends BoxedAsyncIterator, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): AsyncIterableIterator<Capable> => {\n const next = reviveFunction(value.next, context)\n const returnRpc = reviveFunction(value.return, context)\n const throwRpc = reviveFunction(value.throw, context)\n const iterator: AsyncIterableIterator<Capable> = {\n next: (...args: [] | [unknown]) =>\n next(...args as Capable[]) as Promise<IteratorResult<Capable>>,\n return: (arg?: unknown) =>\n returnRpc(arg as Capable) as Promise<IteratorResult<Capable>>,\n throw: (error?: unknown) =>\n throwRpc(error as Capable) as Promise<IteratorResult<Capable>>,\n [Symbol.asyncIterator]: () => iterator,\n }\n return iterator\n}\n\nconst typeCheck = () => {\n const gen = (async function* () { yield 1 })()\n const boxed = box(gen, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: AsyncIterableIterator<Capable> = revived\n // @ts-expect-error - not a string\n const notString: string = revived\n // @ts-expect-error - cannot box a non-async-iterable\n box({ next: () => {} }, {} as RevivableContext)\n}\n","import type { BoxBase as BoxBaseType, RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { instanceOfAny } from '../utils/type-guards.js'\n\ntype AnyCtor = abstract new (...args: any[]) => unknown\n\n// -------------------------------------------------------------------------\n// clonable — pass-through fast path for HTML structured-clone types not\n// owned by another revivable. Short-circuits findBoxModule so unclonable's\n// structuredClone probe never fires on a known-safe value.\n// -------------------------------------------------------------------------\n\nconst TYPED_CLONABLE_CTORS = [\n globalThis.File,\n globalThis.FileList,\n globalThis.RegExp,\n globalThis.DataView,\n globalThis.ImageData,\n globalThis.FormData,\n globalThis.DOMException,\n globalThis.DOMMatrix,\n globalThis.DOMMatrixReadOnly,\n globalThis.DOMPoint,\n globalThis.DOMPointReadOnly,\n globalThis.DOMQuad,\n globalThis.DOMRect,\n globalThis.DOMRectReadOnly,\n globalThis.CryptoKey,\n globalThis.FileSystemHandle,\n globalThis.FileSystemFileHandle,\n globalThis.FileSystemDirectoryHandle,\n globalThis.RTCCertificate,\n] as const\n\nconst EXPERIMENTAL_CLONABLE_CTORS = [\n (globalThis as { CropTarget?: AnyCtor }).CropTarget,\n (globalThis as { EncodedAudioChunk?: AnyCtor }).EncodedAudioChunk,\n (globalThis as { EncodedVideoChunk?: AnyCtor }).EncodedVideoChunk,\n (globalThis as { FencedFrameConfig?: AnyCtor }).FencedFrameConfig,\n (globalThis as { GPUCompilationInfo?: AnyCtor }).GPUCompilationInfo,\n (globalThis as { GPUCompilationMessage?: AnyCtor }).GPUCompilationMessage,\n (globalThis as { GPUPipelineError?: AnyCtor }).GPUPipelineError,\n (globalThis as { RTCEncodedAudioFrame?: AnyCtor }).RTCEncodedAudioFrame,\n (globalThis as { RTCEncodedVideoFrame?: AnyCtor }).RTCEncodedVideoFrame,\n (globalThis as { WebTransportError?: AnyCtor }).WebTransportError,\n] as const\n\nexport type Clonable = InstanceType<typeof TYPED_CLONABLE_CTORS[number]>\nexport type BoxedClonable = BoxBaseType<'clonable'>\n\n// `capableOnly: true` tells ExtractType to elide this module from the\n// Capable union on JSON transports — TS can't narrow `isType<Ctx>` via\n// generic inference, so we use a marker flag.\nconst isClonable = (value: unknown): value is Clonable =>\n instanceOfAny(value, TYPED_CLONABLE_CTORS) || instanceOfAny(value, EXPERIMENTAL_CLONABLE_CTORS)\n\nexport const clonable = {\n type: 'clonable',\n capableOnly: true,\n isType: isClonable,\n // Pass-through; structured-clone handles these on the wire. `revive` is\n // never reached — `box` returns the raw value so isRevivableBox is false.\n box: (value: Clonable, _context: RevivableContext<any>): Clonable => value,\n revive: (value: BoxedClonable, _context: RevivableContext<any>): Clonable => value as unknown as Clonable,\n} as const\n\n// -------------------------------------------------------------------------\n// transferable — pass-through fast path for transfer-only host objects.\n// getTransferableObjects pulls them out of the envelope at send time.\n// -------------------------------------------------------------------------\n\nconst TYPED_TRANSFERABLE_CTORS = [\n globalThis.ImageBitmap,\n globalThis.OffscreenCanvas,\n globalThis.WritableStream,\n globalThis.TransformStream,\n globalThis.MediaStreamTrack,\n globalThis.RTCDataChannel,\n] as const\n\nconst EXPERIMENTAL_TRANSFERABLE_CTORS = [\n (globalThis as { AudioData?: AnyCtor }).AudioData,\n (globalThis as { VideoFrame?: AnyCtor }).VideoFrame,\n (globalThis as { MediaSourceHandle?: AnyCtor }).MediaSourceHandle,\n (globalThis as { MIDIAccess?: AnyCtor }).MIDIAccess,\n (globalThis as { WebTransportReceiveStream?: AnyCtor }).WebTransportReceiveStream,\n (globalThis as { WebTransportSendStream?: AnyCtor }).WebTransportSendStream,\n] as const\n\nexport type Transferable = InstanceType<typeof TYPED_TRANSFERABLE_CTORS[number]>\nexport type BoxedTransferable = BoxBaseType<'transferable'>\n\nconst isTransferable = (value: unknown): value is Transferable =>\n instanceOfAny(value, TYPED_TRANSFERABLE_CTORS) || instanceOfAny(value, EXPERIMENTAL_TRANSFERABLE_CTORS)\n\nexport const transferable = {\n type: 'transferable',\n capableOnly: true,\n isType: isTransferable,\n box: (value: Transferable, _context: RevivableContext<any>): Transferable => value,\n revive: (value: BoxedTransferable, _context: RevivableContext<any>): Transferable => value as unknown as Transferable,\n} as const\n\n// -------------------------------------------------------------------------\n// unclonable — catch-all that probes via structuredClone and coerces\n// unclonables to `{}` so the wire never blows up on exotic host objects.\n// -------------------------------------------------------------------------\n\nconst isPlainObject = (value: unknown): boolean => {\n if (value === null || typeof value !== 'object') return false\n const proto = Object.getPrototypeOf(value)\n return proto === Object.prototype || proto === null\n}\n\nconst isUnclonable = (value: unknown): boolean => {\n if (value === null) return false\n const t = typeof value\n if (t !== 'object') return false\n if (Array.isArray(value)) return false\n if (isPlainObject(value)) return false\n try {\n structuredClone(value)\n return false\n } catch {\n return true\n }\n}\n\nexport type BoxedUnclonable = BoxBaseType<'unclonable'>\n\n// Type-level lie: `value is never` so this module doesn't widen Capable.\n// Coercion to `{}` is a runtime rescue for values we shouldn't see.\nconst isUnclonableTyped = isUnclonable as (value: unknown) => value is never\n\nexport const unclonable = {\n type: 'unclonable',\n isType: isUnclonableTyped,\n box: (_value: never, _context: RevivableContext<any>): BoxedUnclonable => ({ ...BoxBase, type: 'unclonable' }),\n revive: (_value: BoxedUnclonable, _context: RevivableContext<any>): Record<string, never> => ({}),\n} as const\n","import type { BoxBase as BoxBaseType, RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { isJsonOnlyTransport } from '../utils/type-guards.js'\n\n// JSON.stringify silently corrupts these: NaN/±Infinity become null,\n// undefined vanishes from objects and becomes null in arrays. On clone\n// transports both pass through untouched (box returns the raw value, so\n// isRevivableBox is false and revive is never reached) — the wire shape\n// only exists on JSON transports.\n\nexport type BoxedNonFiniteNumber = BoxBaseType<'nonFiniteNumber'> & { value: 'NaN' | 'Infinity' | '-Infinity' }\n\nexport const nonFiniteNumber = {\n type: 'nonFiniteNumber',\n isType: (value: unknown): value is number =>\n typeof value === 'number' && !Number.isFinite(value),\n box: (value: number, context: RevivableContext<any>): BoxedNonFiniteNumber | number =>\n isJsonOnlyTransport(context.transport)\n ? { ...BoxBase, type: 'nonFiniteNumber', value: String(value) as BoxedNonFiniteNumber['value'] }\n : value,\n revive: (value: BoxedNonFiniteNumber, _context: RevivableContext<any>): number =>\n Number(value.value),\n} as const\n\nexport type BoxedUndefined = BoxBaseType<'undefined'>\n\nexport const undefinedValue = {\n type: 'undefined',\n isType: (value: unknown): value is undefined =>\n value === undefined,\n box: (value: undefined, context: RevivableContext<any>): BoxedUndefined | undefined =>\n isJsonOnlyTransport(context.transport)\n ? { ...BoxBase, type: 'undefined' }\n : value,\n revive: (_value: BoxedUndefined, _context: RevivableContext<any>): undefined =>\n undefined,\n} as const\n","import type { BoxBase, RevivableContext } from './utils.js'\nimport type { DeepReplaceWithBox, DeepReplaceWithRevive } from '../utils/replace.js'\nimport type { MessageFields, Capable } from '../types.js'\n\nimport { isRevivableBox } from './utils.js'\nimport * as arrayBuffer from './array-buffer.js'\nimport * as date from './date.js'\nimport * as headers from './headers.js'\nimport * as error from './error.js'\nimport * as typedArray from './typed-array.js'\nimport * as promise from './promise.js'\nimport * as func from './function.js'\nimport * as messagePort from './message-port.js'\nimport * as readableStream from './readable-stream.js'\nimport * as writableStream from './writable-stream.js'\nimport * as abortSignal from './abort-signal.js'\nimport * as response from './response.js'\nimport * as request from './request.js'\nimport * as identity from './identity.js'\nimport * as transfer from './transfer.js'\nimport * as map from './map.js'\nimport * as set from './set.js'\nimport * as bigInt from './bigint.js'\nimport * as event from './event.js'\nimport * as eventTarget from './event-target.js'\nimport * as blob from './blob.js'\nimport * as symbol from './symbol.js'\nimport * as asyncIterator from './async-iterator.js'\nimport { clonable, transferable, unclonable } from './fallbacks.js'\nimport { nonFiniteNumber, undefinedValue } from './json-primitives.js'\n\nexport { identity } from './identity.js'\nexport { transfer } from './transfer.js'\n\nexport * from './utils.js'\n\n// `any` on box/revive/init: each module's concrete box has a narrower input\n// than the shared interface can express, and TS treats readonly function\n// types contravariantly. The bivariance escape hatch lets modules assign.\nexport type RevivableModule<\n T extends string = string,\n T2 = any,\n T3 extends BoxBase<T> = any,\n T4 extends MessageFields = MessageFields,\n> = {\n readonly type: T\n readonly isType: (value: unknown) => value is T2\n readonly box: ((value: T2, context: RevivableContext<any>) => T3) | ((...args: any[]) => any)\n readonly revive: (value: T3, context: RevivableContext<any>) => T2\n readonly init?: (context: RevivableContext<any>) => void\n readonly Messages?: T4\n}\n\nexport const defaultRevivableModules = [\n transfer,\n identity,\n arrayBuffer,\n date,\n headers,\n error,\n typedArray,\n // blob MUST come before clonable — clonable would otherwise pass-through\n // a Blob unboxed, which works on clone transports but loses the data on\n // JSON. Blob's isType excludes File so File still rides clonable.\n blob,\n promise,\n func,\n messagePort,\n readableStream,\n writableStream,\n abortSignal,\n response,\n request,\n map,\n set,\n bigInt,\n symbol,\n event,\n // After readableStream (some platforms make streams async-iterable),\n // before the fallbacks so generators don't coerce to {}.\n asyncIterator,\n nonFiniteNumber,\n undefinedValue,\n // clonable/transferable before eventTarget: OffscreenCanvas & co. are Transferables\n // that also extend EventTarget, which eventTarget would otherwise box as façade husks.\n clonable,\n transferable,\n // eventTarget MUST be last among instanceof-EventTarget revivables —\n // MessagePort/AbortSignal/Window/Worker all extend EventTarget; the\n // specific ones need first dibs via findBoxModule iteration order.\n eventTarget,\n // Catch-all: structuredClone-probes and coerces unclonables to `{}`,\n // matching JSON.stringify(new WeakMap()) === \"{}\".\n unclonable,\n] as const\n\nexport type DefaultRevivableModules = typeof defaultRevivableModules\nexport type DefaultRevivableModule = DefaultRevivableModules[number]\n\nconst findBoxModule = (\n value: unknown,\n modules: readonly RevivableModule[]\n): RevivableModule | undefined =>\n modules.find(module => module.isType(value))\n\nconst findReviveModule = (\n value: BoxBase,\n modules: readonly RevivableModule[],\n): RevivableModule | undefined =>\n modules.find(module => module.type === value.type)\n\nconst isPlainObject = (value: unknown): value is Record<string, Capable> =>\n !!value && typeof value === 'object' && Object.getPrototypeOf(value) === Object.prototype\n\nconst descend = <TOut>(value: unknown, transform: (v: Capable) => unknown): TOut => {\n if (Array.isArray(value)) {\n return value.map(v => transform(v)) as TOut\n }\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries<Capable>(value).map(([k, v]) => [k, transform(v)]),\n ) as TOut\n }\n return value as TOut\n}\n\n// Walk path for cycle detection. Box/revive are fully synchronous, so a\n// module-global set with balanced enter/exit is safe; tracking the *path*\n// (not all visited values) keeps sibling aliasing working — only a true\n// ancestor revisit, which would recurse forever, throws.\nconst boxPath = new WeakSet<object>()\nconst revivePath = new WeakSet<object>()\n\nconst isTrackable = (value: unknown): value is object =>\n value !== null && (typeof value === 'object' || typeof value === 'function')\n\nexport const recursiveBox = <\n T extends Capable,\n TModules extends readonly RevivableModule[]\n>(\n value: T,\n context: RevivableContext<TModules>\n): DeepReplaceWithBox<T, TModules[number]> => {\n type ReturnCastType = DeepReplaceWithBox<T, TModules[number]>\n // Already-boxed values pass through — revivables may embed a pre-built\n // BoxedX in their outgoing payload; descending would re-box raw ports.\n if (isRevivableBox(value)) return value as ReturnCastType\n const track = isTrackable(value)\n if (track) {\n if (boxPath.has(value)) {\n throw new TypeError('osra: cannot serialize a circular structure — break the cycle or send the container by reference')\n }\n boxPath.add(value)\n }\n try {\n const handledByModule = findBoxModule(value, context.revivableModules)\n if (handledByModule) {\n return handledByModule.box(value, context) as ReturnCastType\n }\n return descend<ReturnCastType>(value, v => recursiveBox(v, context))\n } finally {\n if (track) boxPath.delete(value)\n }\n}\n\nexport const recursiveRevive = <\n T extends Capable,\n TModules extends readonly RevivableModule[]\n>(\n value: T,\n context: RevivableContext<TModules>\n): DeepReplaceWithRevive<T, TModules[number]> => {\n type ReturnCastType = DeepReplaceWithRevive<T, TModules[number]>\n const track = isTrackable(value)\n if (track) {\n // Structured clone can deliver cyclic graphs a peer crafted — fail\n // with a clear error instead of blowing the stack mid-dispatch.\n if (revivePath.has(value)) {\n throw new TypeError('osra: cannot revive a circular structure')\n }\n revivePath.add(value)\n }\n try {\n if (isRevivableBox(value)) {\n const handledByModule = findReviveModule(value, context.revivableModules)\n if (handledByModule) {\n return handledByModule.revive(value, context) as ReturnCastType\n }\n }\n return descend<ReturnCastType>(value, v => recursiveRevive(v, context))\n } finally {\n if (track) revivePath.delete(value)\n }\n}","import type { Transport } from '../utils/transport.js'\nimport type { DefaultRevivableModules, RevivableModule } from '../revivables/index.js'\nimport type { DeepReplaceWithBox } from '../utils/replace.js'\nimport type { ProtocolContext } from './utils.js'\nimport type {\n Capable, MessageEventTarget, MessageFields,\n MessageVariant, Uuid,\n} from '../types.js'\n\nimport { recursiveBox, recursiveRevive } from '../revivables/index.js'\nimport { isEmitTransport, isReceiveTransport } from '../utils/type-guards.js'\nimport { runTeardown } from '../utils/teardown.js'\n\nexport const type = 'bidirectional' as const\n\nexport type InitMessage<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n T extends Capable<TModules> = Capable<TModules>\n> = {\n type: 'init'\n remoteUuid: Uuid\n data: DeepReplaceWithBox<T, TModules[number]>\n}\n\nexport declare const Messages: <\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n T extends Capable<TModules> = Capable<TModules>\n>(modules: TModules, value: T) =>\n | InitMessage<TModules, T>\n\nexport type Messages<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n T extends Capable<TModules> = Capable<TModules>\n> = ReturnType<typeof Messages<TModules, T>>\n\nexport type ConnectionContext<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n type: 'bidirectional'\n eventTarget: MessageEventTarget<TModules>\n connection: BidirectionalConnection<TModules>\n}\n\nexport type ConnectionRevivableContext<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n transport: Transport\n remoteUuid: Uuid\n sendMessage: (message: MessageFields & Record<string, unknown>) => void\n revivableModules: TModules\n eventTarget: MessageEventTarget<TModules>\n}\n\nexport const startBidirectionalConnection = <\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n>(\n { transport, value, remoteUuid, eventTarget, send, revivableModules }:\n {\n transport: Transport\n value: Capable<TModules>\n remoteUuid: Uuid\n eventTarget: MessageEventTarget<TModules>\n send: (message: MessageFields & Record<string, unknown>) => void\n revivableModules: TModules\n },\n) => {\n const revivableContext = {\n transport,\n remoteUuid,\n sendMessage: send,\n eventTarget,\n revivableModules\n } satisfies ConnectionRevivableContext<TModules>\n\n for (const module of revivableModules) {\n module.init?.(revivableContext)\n }\n\n const { promise, resolve } = Promise.withResolvers<InitMessage<TModules>['data']>()\n\n eventTarget.addEventListener('message', function listener ({ detail }) {\n if (detail.type === 'init') {\n resolve(detail.data)\n eventTarget.removeEventListener('message', listener)\n }\n })\n\n send({\n type: 'init',\n remoteUuid,\n data: recursiveBox(value, revivableContext)\n })\n\n return {\n revivableContext,\n remoteValue:\n promise\n .then(initData => recursiveRevive(initData, revivableContext) as Capable),\n }\n}\n\nexport type BidirectionalConnection<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n revivableContext: ConnectionRevivableContext<TModules>\n remoteValue: Promise<Capable>\n}\n\n/** Mounts bidirectional mode on the shared protocol context. Only active\n * when the transport can both emit and receive. */\nexport const init = <TModules extends readonly RevivableModule[]>(\n ctx: ProtocolContext<TModules>\n): void => {\n if (!(isEmitTransport(ctx.transport) && isReceiveTransport(ctx.transport))) return\n\n ctx.protocolEventTarget.addEventListener('message', ({ detail: message }) => {\n if (message.type === 'announce') {\n if (!message.remoteUuid) {\n ctx.sendMessage({ type: 'announce', remoteUuid: message.uuid })\n return\n }\n if (message.remoteUuid !== ctx.getUuid()) return\n // Already-tracked uuid is the normal handshake-echo (peer re-announcing\n // back after our reply), not a collision — drop it.\n if (ctx.connectionContexts.has(message.uuid)) return\n // Echo announce back in case the peer missed our initial one.\n ctx.sendMessage({ type: 'announce', remoteUuid: message.uuid })\n const eventTarget = ctx.createConnectionEventTarget()\n let connection: ReturnType<typeof startBidirectionalConnection<TModules>>\n try {\n connection = startBidirectionalConnection<TModules>({\n transport: ctx.transport,\n value: ctx.value,\n remoteUuid: message.uuid,\n eventTarget,\n send: (m) => ctx.sendMessage(m as MessageVariant),\n revivableModules: ctx.revivableModules\n })\n } catch (error) {\n // Boxing our own value failed (e.g. cyclic data) — surface it\n // instead of swallowing inside EventTarget dispatch.\n ctx.rejectRemoteValue(error)\n return\n }\n const connectionContext = {\n type: 'bidirectional',\n eventTarget,\n connection,\n } satisfies ConnectionContext<TModules>\n ctx.connectionContexts.set(message.uuid, connectionContext)\n connectionContext.connection.remoteValue.then(\n (remoteValue) => ctx.resolveRemoteValue(remoteValue),\n (error) => ctx.rejectRemoteValue(error),\n )\n return\n }\n if (message.type === 'close') {\n if (message.remoteUuid !== ctx.getUuid()) return\n const connectionContext = ctx.connectionContexts.get(message.uuid)\n if (!connectionContext) return\n ctx.connectionContexts.delete(message.uuid)\n runTeardown(connectionContext.connection.revivableContext)\n // No-op when the handshake already resolved; a close that beats init\n // must not leave the caller pending forever.\n ctx.rejectRemoteValue(new Error('osra: peer closed the connection'))\n return\n }\n // \"init\" | \"message\" | \"message-port-close\"\n if (message.remoteUuid !== ctx.getUuid()) return\n const connection = ctx.connectionContexts.get(message.uuid)\n // drop messages from peers we haven't tracked (pre-announce or post-close)\n if (!connection) return\n connection.eventTarget.dispatchEvent(\n new CustomEvent('message', { detail: message })\n )\n })\n\n if (ctx.presetRemoteUuid !== undefined) {\n const eventTarget = ctx.createConnectionEventTarget()\n let connection: ReturnType<typeof startBidirectionalConnection<TModules>>\n try {\n connection = startBidirectionalConnection<TModules>({\n transport: ctx.transport,\n value: ctx.value,\n remoteUuid: ctx.presetRemoteUuid,\n eventTarget,\n send: (m) => ctx.sendMessage(m as MessageVariant),\n revivableModules: ctx.revivableModules\n })\n } catch (error) {\n ctx.rejectRemoteValue(error)\n return\n }\n const connectionContext = {\n type: 'bidirectional',\n eventTarget,\n connection,\n } satisfies ConnectionContext<TModules>\n ctx.connectionContexts.set(ctx.presetRemoteUuid, connectionContext)\n connectionContext.connection.remoteValue.then(\n (remoteValue) => ctx.resolveRemoteValue(remoteValue),\n (error) => ctx.rejectRemoteValue(error),\n )\n return\n }\n\n // A lone announce is lost when the counterpart isn't listening yet (still-loading iframe,\n // relay attached after a worker exposes) — re-announce with capped backoff until a peer\n // connects. The uuid is stable across retries, so duplicates are dropped as handshake echoes.\n let announceDelay = 50\n let announceTimeout: ReturnType<typeof setTimeout> | undefined\n const announce = () => {\n if (ctx.unregisterSignal?.aborted || ctx.connectionContexts.size > 0) return\n ctx.sendMessage({ type: 'announce' })\n announceTimeout = setTimeout(announce, announceDelay)\n announceDelay = Math.min(announceDelay * 2, 1_000)\n }\n ctx.unregisterSignal?.addEventListener('abort', () => clearTimeout(announceTimeout), { once: true })\n announce()\n}\n","import type { UnderlyingType } from './type.js'\n\nexport type EventMap = Record<string, Event>\n\nexport interface TypedEventTarget<T extends EventMap> extends EventTarget {\n [UnderlyingType]?: T\n\n addEventListener<K extends keyof T & string>(\n type: K,\n listener: ((event: T[K]) => void) | null,\n options?: boolean | AddEventListenerOptions\n ): void\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | AddEventListenerOptions\n ): void\n\n removeEventListener<K extends keyof T & string>(\n type: K,\n listener: ((event: T[K]) => void) | null,\n options?: boolean | EventListenerOptions\n ): void\n removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | EventListenerOptions\n ): void\n}\n\n/**\n * Create a new `TypedEventTarget<T>` for a given event map. Centralises the\n * `EventTarget` → `TypedEventTarget<T>` cast so individual call sites don't\n * each need their own (`EventTarget` lacks the generic event map at the type\n * level, but the runtime behaviour is identical).\n */\nexport const createTypedEventTarget = <T extends EventMap>(): TypedEventTarget<T> =>\n new EventTarget() as TypedEventTarget<T>\n","import type {\n Message, MessageVariant, Uuid,\n Capable, MessageEventMap\n} from '../types.js'\nimport type { DefaultRevivableModules, RevivableModule } from '../revivables/index.js'\nimport type { Transport } from '../utils/transport.js'\nimport type { ConnectionContext } from './index.js'\nimport type { TypedEventTarget } from '../utils/typed-event-target.js'\n\nimport { defaultRevivableModules } from '../revivables/index.js'\nimport { isJsonOnlyTransport, isCustomTransport } from '../utils/type-guards.js'\n\nexport const normalizeTransport = (transport: Transport): Transport => {\n const custom = isCustomTransport(transport)\n const emit = custom ? (transport as { emit?: unknown }).emit : transport\n const receive = custom ? (transport as { receive?: unknown }).receive : transport\n // Probe the embedded platform transports, not the wrapper — a custom\n // { emit: webSocket } is JSON-only even though the wrapper itself isn't.\n const isJson =\n custom && 'isJson' in transport && transport.isJson !== undefined\n ? transport.isJson\n : (emit !== undefined && isJsonOnlyTransport(emit))\n || (receive !== undefined && isJsonOnlyTransport(receive))\n return {\n isJson,\n ...(emit !== undefined ? { emit } : {}),\n ...(receive !== undefined ? { receive } : {}),\n } as Transport\n}\n\n/** Resolves the final revivable module list. The user supplies a function\n * that takes the defaults and returns whatever ordering/composition they\n * want — add modules, drop defaults, reorder, override per-type. When\n * omitted, the defaults are used as-is. */\nexport const mergeRevivableModules = <\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n>(\n configure: ((defaults: DefaultRevivableModules) => TModules) | undefined,\n): TModules =>\n configure\n ? configure(defaultRevivableModules)\n : defaultRevivableModules as unknown as TModules\n\nexport type ProtocolEventMap<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n message: CustomEvent<Message<TModules>>\n}\n\nexport type ProtocolEventTarget<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = TypedEventTarget<ProtocolEventMap<TModules>>\n\nexport type ProtocolContext<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n transport: Transport\n value: Capable<TModules>\n revivableModules: TModules\n connectionContexts: Map<string, ConnectionContext<TModules>>\n getUuid: () => Uuid\n presetRemoteUuid?: Uuid\n sendMessage: (message: MessageVariant) => void\n protocolEventTarget: ProtocolEventTarget<TModules>\n resolveRemoteValue: (value: Capable<TModules>) => void\n rejectRemoteValue: (error: unknown) => void\n createConnectionEventTarget: () => TypedEventTarget<MessageEventMap<TModules>>\n unregisterSignal?: AbortSignal\n}\n\nexport type StartConnectionsOptions<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n transport: Transport\n name?: string\n remoteName?: string\n key?: string\n origin?: string\n unregisterSignal?: AbortSignal\n /** Configure the revivable module list. Receives the defaults and\n * returns the final ordered list — add modules, drop defaults, reorder,\n * or override per-type as needed. */\n revivableModules?: (defaults: DefaultRevivableModules) => TModules\n uuid?: Uuid\n remoteUuid?: Uuid\n}\n","import type { Transport } from '../utils/transport.js'\n\nimport { OSRA_DEFAULT_KEY } from '../types.js'\nimport { isEmitTransport, isReceiveTransport } from '../utils/type-guards.js'\nimport { getTransferableObjects } from '../utils/transferable.js'\nimport {\n registerOsraMessageListener,\n sendOsraMessage,\n} from '../utils/transport.js'\nimport { normalizeTransport } from './utils.js'\n\nexport type RelayOptions = {\n key?: string\n origin?: string\n originA?: string\n originB?: string\n nameA?: string\n nameB?: string\n unregisterSignal?: AbortSignal\n}\n\nexport const relay = (\n transportA: Transport,\n transportB: Transport,\n {\n key = OSRA_DEFAULT_KEY,\n origin = '*',\n originA = origin,\n originB = origin,\n nameA,\n nameB,\n unregisterSignal,\n }: RelayOptions = {},\n): void => {\n const a = normalizeTransport(transportA)\n const b = normalizeTransport(transportB)\n\n const forward = (\n from: Transport,\n to: Transport,\n fromOrigin: string,\n toOrigin: string,\n remoteName: string | undefined,\n ): void => {\n if (!isReceiveTransport(from) || !isEmitTransport(to)) return\n registerOsraMessageListener({\n transport: from,\n key,\n remoteName,\n origin: fromOrigin,\n unregisterSignal,\n listener: (message) => {\n sendOsraMessage(to, message, toOrigin, getTransferableObjects(message))\n },\n })\n }\n\n forward(a, b, originA, originB, nameA)\n forward(b, a, originB, originA, nameB)\n}\n","import type { DefaultRevivableModules, RevivableModule } from '../revivables/index.js'\nimport type { ConnectionContext as BidirectionalConnectionContext } from './bidirectional.js'\nimport type {\n Message, MessageVariant, Uuid,\n Capable,\n} from '../types.js'\nimport type {\n ProtocolContext,\n StartConnectionsOptions,\n} from './utils.js'\nimport type { MessageContext } from '../utils/transport.js'\n\nimport { OSRA_DEFAULT_KEY, OSRA_KEY } from '../types.js'\nimport * as bidirectional from './bidirectional.js'\nimport {\n isEmitTransport,\n isReceiveTransport,\n} from '../utils/type-guards.js'\nimport { createTypedEventTarget } from '../utils/typed-event-target.js'\nimport { getTransferableObjects } from '../utils/transferable.js'\nimport { registerOsraMessageListener, sendOsraMessage } from '../utils/transport.js'\nimport { runTeardown } from '../utils/teardown.js'\nimport { mergeRevivableModules, normalizeTransport } from './utils.js'\n\nexport * from './bidirectional.js'\nexport * from './relay.js'\nexport * from './utils.js'\n\nexport type ConnectionModule<T> = {\n readonly type: string\n // ProtocolContext<any> rather than ProtocolContext<readonly RevivableModule[]>\n // for the same bivariance reason as RevivableModule.box — concrete modules\n // declare narrower context generics than the shared interface can express.\n readonly init: (ctx: ProtocolContext<any>) => void\n readonly Messages?: T\n}\n\nexport const connections = [\n bidirectional\n] as const\n\nexport type DefaultConnectionModules = typeof connections\nexport type DefaultConnectionModule = DefaultConnectionModules[number]\n\nexport type ConnectionMessage<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n T extends Capable<TModules> = Capable<TModules>\n> =\n DefaultConnectionModule extends {\n Messages: (modules: TModules, value: T) => infer R\n }\n ? R\n : never\n\nexport type ConnectionContext<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> =\n | BidirectionalConnectionContext<TModules>\n\nexport const startConnections = <\n T = unknown,\n const TModules extends readonly RevivableModule[] = DefaultRevivableModules\n>(\n value: Capable<TModules>,\n {\n transport: _transport,\n name,\n remoteName,\n key = OSRA_DEFAULT_KEY,\n origin = '*',\n unregisterSignal,\n revivableModules: configureRevivableModules,\n uuid: _uuid,\n remoteUuid: presetRemoteUuid,\n }: StartConnectionsOptions<TModules>\n): Promise<T> => {\n const transport = normalizeTransport(_transport)\n if (!(isEmitTransport(transport) && isReceiveTransport(transport))) {\n throw new Error(\n 'osra: transport must be able to both emit and receive to establish a connection'\n + ' — pass a bidirectional platform transport or a custom { emit, receive } pair',\n )\n }\n const mergedRevivableModules = mergeRevivableModules<TModules>(configureRevivableModules)\n type MergedModules = typeof mergedRevivableModules\n const connectionContexts = new Map<string, ConnectionContext<MergedModules>>()\n\n const { promise: remoteValuePromise, resolve: resolveRemoteValue, reject: rejectRemoteValue } =\n Promise.withResolvers<Capable<MergedModules>>()\n // Keeps a fire-and-forget `expose(value, …)` (the documented server-side\n // pattern) from surfacing an unhandled rejection on abort/close; awaiting\n // callers still observe the rejection through the original promise.\n remoteValuePromise.catch(() => {})\n\n const uuid: Uuid = _uuid ?? globalThis.crypto.randomUUID()\n\n const sendEnvelope = (message: MessageVariant) => {\n const envelope = { [OSRA_KEY]: key, name, uuid, ...message }\n sendOsraMessage(transport, envelope, origin, getTransferableObjects(envelope))\n }\n\n const sendMessage = (message: MessageVariant) => {\n if (unregisterSignal?.aborted) return\n sendEnvelope(message)\n }\n\n const protocolEventTarget = createTypedEventTarget<{ message: CustomEvent<Message<MergedModules>> }>()\n\n const ctx: ProtocolContext<MergedModules> = {\n transport,\n value: value as Capable<MergedModules>,\n revivableModules: mergedRevivableModules,\n connectionContexts,\n getUuid: () => uuid,\n presetRemoteUuid,\n sendMessage,\n protocolEventTarget,\n resolveRemoteValue,\n rejectRemoteValue,\n createConnectionEventTarget: createTypedEventTarget,\n unregisterSignal,\n }\n\n const listener = (message: Message, _: MessageContext) => {\n // own message looped back on the channel\n if (message.uuid === uuid) return\n protocolEventTarget.dispatchEvent(\n new CustomEvent('message', { detail: message as Message<MergedModules> }),\n )\n }\n\n registerOsraMessageListener({\n listener,\n transport,\n remoteName,\n key,\n origin,\n unregisterSignal\n })\n\n // Abort = explicit local teardown: notify every tracked peer, dispose\n // per-connection state, and reject the (possibly still pending) handshake.\n unregisterSignal?.addEventListener('abort', () => {\n for (const [peerUuid, connectionContext] of connectionContexts) {\n sendEnvelope({ type: 'close', remoteUuid: peerUuid as Uuid })\n runTeardown(connectionContext.connection.revivableContext)\n }\n connectionContexts.clear()\n rejectRemoteValue(unregisterSignal.reason)\n }, { once: true })\n\n for (const connectionModule of connections) {\n connectionModule.init(ctx)\n }\n\n return remoteValuePromise as Promise<T>\n}\n","import type { Capable, Remote } from './types.js'\nimport type { DefaultRevivableModules, RevivableContext } from './revivables/index.js'\nimport type { RevivableModule } from './revivables/index.js'\nimport type { StartConnectionsOptions } from './connections/utils.js'\nimport type { Transport } from './utils/transport.js'\nimport type {\n BadFieldValue, BadFieldPath, BadFieldParent,\n ErrorMessage, BadValue, Path, ParentObject\n} from './utils/capable-check.js'\n\nimport { startConnections } from './connections/index.js'\n\nexport * from './types.js'\nexport * from './revivables/index.js'\nexport * from './connections/index.js'\nexport * from './utils/index.js'\n\n/** Synthetic context so `Capable` can narrow on the inferred transport\n * without an actual context object at the call site. Only `transport`\n * matters; the rest is stubbed with the broadest types. */\ntype ContextOf<TTransport extends Transport> = RevivableContext & { transport: TTransport }\n\ntype CapableCheck<\n T,\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n Ctx extends RevivableContext = RevivableContext,\n> =\n T extends Capable<TModules, Ctx>\n ? T\n : T & {\n [ErrorMessage]: 'Value type must resolve to a Capable'\n [BadValue]: BadFieldValue<T, Capable<TModules, Ctx>>\n [Path]: BadFieldPath<T, Capable<TModules, Ctx>>\n [ParentObject]: BadFieldParent<T, Capable<TModules, Ctx>>\n }\n\nexport const expose = async <\n T = unknown,\n const TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n const TTransport extends Transport = Transport,\n const TValue = Capable<TModules, ContextOf<TTransport>>\n>(\n value: CapableCheck<TValue, TModules, ContextOf<TTransport>>,\n options: StartConnectionsOptions<TModules> & { transport: TTransport }\n): Promise<Remote<T>> =>\n startConnections<Remote<T>, TModules>(\n value as Capable<TModules>,\n options\n )\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/types.ts","../src/utils/transport.ts","../src/utils/type-guards.ts","../src/revivables/utils.ts","../src/revivables/array-buffer.ts","../src/revivables/date.ts","../src/revivables/headers.ts","../src/revivables/error.ts","../src/revivables/typed-array.ts","../src/utils/teardown.ts","../src/revivables/transfer.ts","../src/utils/transferable.ts","../src/utils/event-channel.ts","../src/utils/gc-tracker.ts","../src/revivables/message-port.ts","../src/revivables/promise.ts","../src/revivables/function.ts","../src/revivables/readable-stream.ts","../src/revivables/writable-stream.ts","../src/revivables/abort-signal.ts","../src/revivables/response.ts","../src/revivables/request.ts","../src/revivables/identity.ts","../src/revivables/map.ts","../src/revivables/set.ts","../src/revivables/bigint.ts","../src/revivables/event.ts","../src/revivables/event-target.ts","../src/revivables/blob.ts","../src/revivables/symbol.ts","../src/revivables/async-iterator.ts","../src/revivables/fallbacks.ts","../src/revivables/json-primitives.ts","../src/revivables/index.ts","../src/connections/bidirectional.ts","../src/utils/typed-event-target.ts","../src/connections/utils.ts","../src/connections/relay.ts","../src/connections/index.ts","../src/index.ts"],"sourcesContent":["import type { ConnectionMessage } from './connections/index.js'\nimport type { TypedEventTarget } from './utils/typed-event-target.js'\nimport type { IsJsonOnlyTransport } from './utils/type-guards.js'\nimport type {\n DefaultRevivableModules, RevivableModule,\n InferMessages, InferRevivables, RevivableContext\n} from './revivables/index.js'\n\nexport const OSRA_KEY = '__OSRA_KEY__' as const\nexport const OSRA_DEFAULT_KEY = '__OSRA_DEFAULT_KEY__' as const\nexport const OSRA_BOX = '__OSRA_BOX__' as const\n\nexport type Uuid = `${string}-${string}-${string}-${string}-${string}`\n\nexport type Jsonable =\n | boolean\n | null\n | number\n | string\n | { [key: string]: Jsonable }\n | Array<Jsonable>\n\nexport type Structurable =\n | Jsonable\n /** not really structureable but here for convenience */\n | void\n | undefined\n | bigint\n | Date\n | RegExp\n | Blob\n | File\n | FileList\n | ArrayBuffer\n | ArrayBufferView\n | ImageBitmap\n | ImageData\n | { [key: string]: Structurable }\n | Array<Structurable>\n | Map<Structurable, Structurable>\n | Set<Structurable>\n\nexport type StructurableTransferable =\n | Structurable\n | Transferable\n | { [key: string]: StructurableTransferable }\n | Array<StructurableTransferable>\n | Map<StructurableTransferable, StructurableTransferable>\n | Set<StructurableTransferable>\n\n/** \"Free\" types in `Capable` — narrows to `Jsonable` on JSON transports so\n * user code can't type a `Date`/`Blob`/etc. that JSON would silently coerce.\n * Modules that DO support JSON (date, map, set, bigint, …) put their type\n * back via `InferRevivables`. */\ntype CapableBase<Ctx extends RevivableContext> =\n IsJsonOnlyTransport<Ctx['transport']> extends true\n ? Jsonable | undefined | void\n : StructurableTransferable\n\nexport type Capable<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n Ctx extends RevivableContext = RevivableContext,\n> =\n | CapableBase<Ctx>\n | InferRevivables<TModules, Ctx>\n | { [key: string]: Capable<TModules, Ctx> }\n | Array<Capable<TModules, Ctx>>\n | Map<Capable<TModules, Ctx>, Capable<TModules, Ctx>>\n | Set<Capable<TModules, Ctx>>\n\n/** What a value looks like from the far side of the connection: functions\n * become async (calls cross the wire), Blobs arrive as Promise<Blob>,\n * containers map recursively, everything else revives as itself. */\nexport type Remote<T> =\n T extends (...args: infer P) => infer R ? (...args: P) => Promise<Remote<Awaited<R>>>\n : T extends Blob ? Promise<T>\n : T extends Promise<infer U> ? Promise<Remote<U>>\n : T extends\n | Map<any, any> | Set<any> | Date | Error | RegExp\n | ArrayBuffer | ArrayBufferView\n | ReadableStream | WritableStream | MessagePort | EventTarget\n | Request | Response | Headers\n ? T\n : T extends AsyncIterable<infer U> ? AsyncIterableIterator<Remote<U>>\n : T extends ReadonlyArray<unknown> ? { [K in keyof T]: Remote<T[K]> }\n : T extends object ? { [K in keyof T]: Remote<T[K]> }\n : T\n\nexport type MessageFields = {\n type: string\n remoteUuid: Uuid\n}\n\nexport type MessageBase = {\n [OSRA_KEY]: string\n /** UUID of the client that sent the message */\n uuid: Uuid\n name?: string\n}\n\nexport type ProtocolMessage =\n | { type: 'announce', remoteUuid?: Uuid }\n | { type: 'close', remoteUuid: Uuid }\n\nexport type MessageVariant<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> =\n | ProtocolMessage\n | ConnectionMessage<TModules>\n | InferMessages<TModules>\n\nexport type Message<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> =\n & MessageBase\n & MessageVariant<TModules>\n\nexport type MessageEventMap<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n message: CustomEvent<Message<TModules>>\n}\n\nexport type MessageEventTarget<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n > = TypedEventTarget<MessageEventMap<TModules>>\n","import type { Browser } from 'webextension-polyfill'\nimport type { Message} from '../types.js'\nimport type {\n WebExtOnConnect, WebExtOnMessage,\n WebExtPort, WebExtRuntime, WebExtSender\n} from './type-guards.js'\n\nimport { OSRA_DEFAULT_KEY, OSRA_KEY } from '../types.js'\nimport {\n isOsraMessage, isCustomTransport,\n isWebExtensionOnConnect, isWebExtensionOnMessage,\n isWebExtensionPort, isWebExtensionRuntime, isWebSocket, isWindow, isSharedWorker\n} from './type-guards.js'\n\nexport type MessageContext = {\n port?: MessagePort | WebExtPort // WebExtension\n sender?: WebExtSender // WebExtension\n receiveTransport?: ReceivePlatformTransport\n source?: MessageEventSource | null // Window, Worker, WebSocket, ect...\n origin?: string // Window\n}\n\nexport type ReceiveHandler = (listener: (event: Message, messageContext: MessageContext) => void) => void | (() => void)\nexport type EmitHandler = (message: Message, transferables?: Transferable[]) => void\n\ntype CustomReceive = ReceivePlatformTransport | ReceiveHandler\ntype CustomEmit = EmitPlatformTransport | EmitHandler\n\nexport type CustomTransport =\n { isJson?: boolean }\n & (\n | { receive: CustomReceive, emit: CustomEmit }\n | { receive: CustomReceive }\n | { emit: CustomEmit }\n )\n\nexport type CustomEmitTransport = Extract<CustomTransport, { emit: any }>\nexport type CustomReceiveTransport = Extract<CustomTransport, { receive: any }>\n\nexport type EmitJsonPlatformTransport =\n | WebSocket\n | WebExtPort\n | WebExtRuntime\n\nexport type ReceiveJsonPlatformTransport =\n | WebSocket\n | WebExtPort\n | WebExtOnConnect\n | WebExtOnMessage\n | WebExtRuntime\n\nexport type JsonPlatformTransport =\n | { isJson: true }\n | EmitJsonPlatformTransport\n | ReceiveJsonPlatformTransport\n\nexport type EmitPlatformTransport =\n | EmitJsonPlatformTransport\n | Window\n | ServiceWorker\n | Worker\n | SharedWorker\n | MessagePort\n\nexport type ReceivePlatformTransport =\n | ReceiveJsonPlatformTransport\n | Window\n | ServiceWorkerContainer\n | Worker\n | SharedWorker\n | MessagePort\n\nexport type PlatformTransport =\n | EmitPlatformTransport\n | ReceivePlatformTransport\n\nexport type EmitTransport = EmitPlatformTransport | CustomEmitTransport\nexport type ReceiveTransport = ReceivePlatformTransport | CustomReceiveTransport\n\nexport type Transport =\n | PlatformTransport\n | CustomTransport\n\n// Typed via the shipped webextension-polyfill module types — referencing the\n// ambient `browser`/`chrome` globals here would leak unresolvable names into\n// the published .d.ts (those @types are devDependencies only).\ntype WebExtGlobals = { browser?: Browser, chrome?: Browser }\nexport const getWebExtensionGlobal = (): Browser | undefined =>\n (globalThis as unknown as WebExtGlobals).browser ?? (globalThis as unknown as WebExtGlobals).chrome\nexport const getWebExtensionRuntime = () => getWebExtensionGlobal()?.runtime\n\nexport const checkOsraMessageKey = (message: any, key: string): message is Message =>\n isOsraMessage(message)\n && message[OSRA_KEY] === key\n\nconst onAbort = (signal: AbortSignal | undefined, fn: () => void) => {\n if (!signal) return\n if (signal.aborted) {\n fn()\n return\n }\n signal.addEventListener('abort', fn, { once: true })\n}\n\nexport const registerOsraMessageListener = (\n { listener, transport, remoteName, key = OSRA_DEFAULT_KEY, origin = '*', unregisterSignal }:\n {\n listener: (message: Message, messageContext: MessageContext) => void\n transport: ReceiveTransport\n remoteName?: string\n key?: string\n origin?: string\n unregisterSignal?: AbortSignal\n }\n) => {\n if (unregisterSignal?.aborted) return\n\n const receiveTransport: Extract<CustomTransport, { receive: any }>['receive'] =\n isCustomTransport(transport) ? transport.receive : transport\n\n // Custom function handler\n if (typeof receiveTransport === 'function') {\n const unregister = receiveTransport((message, ctx) => {\n if (unregisterSignal?.aborted) return\n if (!checkOsraMessageKey(message, key)) return\n if (remoteName && message.name !== remoteName) return\n listener(message, ctx)\n })\n if (typeof unregister === 'function') onAbort(unregisterSignal, unregister)\n return\n }\n\n // WebExtension family — subscribe to an `onMessage`-style listener.\n if (\n isWebExtensionRuntime(receiveTransport)\n || isWebExtensionPort(receiveTransport)\n || isWebExtensionOnConnect(receiveTransport)\n || isWebExtensionOnMessage(receiveTransport)\n ) {\n const listenOnWebExtOnMessage = (onMessage: WebExtOnMessage, port?: WebExtPort) => {\n const _listener = (message: unknown, sender?: WebExtSender) => {\n if (!checkOsraMessageKey(message, key)) return\n if (remoteName && message.name !== remoteName) return\n listener(message, { port, sender })\n }\n onMessage.addListener(_listener)\n onAbort(unregisterSignal, () => onMessage.removeListener(_listener))\n }\n\n if (isWebExtensionRuntime(receiveTransport)) {\n listenOnWebExtOnMessage(receiveTransport.onMessage)\n } else if (isWebExtensionOnConnect(receiveTransport)) {\n const _listener = (port: WebExtPort) =>\n listenOnWebExtOnMessage(port.onMessage as WebExtOnMessage, port)\n receiveTransport.addListener(_listener)\n onAbort(unregisterSignal, () => receiveTransport.removeListener(_listener))\n } else if (isWebExtensionOnMessage(receiveTransport)) {\n listenOnWebExtOnMessage(receiveTransport)\n } else { // WebExtPort\n listenOnWebExtOnMessage(receiveTransport.onMessage as WebExtOnMessage)\n }\n return\n }\n\n // Window, Worker, WebSocket, ServiceWorkerContainer, MessagePort, SharedWorker, …\n // SharedWorker dispatches messages on its .port, not on the worker object.\n const target = isSharedWorker(receiveTransport) ? receiveTransport.port : receiveTransport\n // Inbound origin filtering is a cross-origin *window* concern — WebSocket\n // and ServiceWorkerContainer events carry their own unrelated origins and\n // a page-origin value would silently drop all their traffic.\n const filterByOrigin = origin !== '*' && isWindow(receiveTransport)\n const messageListener = (event: MessageEvent<Message | string>) => {\n // JSON transports (WebSocket) deliver strings — parse before the key check.\n let data = event.data\n if (typeof data === 'string') {\n try { data = JSON.parse(data) as Message } catch { return }\n }\n if (!checkOsraMessageKey(data, key)) return\n if (remoteName && data.name !== remoteName) return\n if (filterByOrigin && event.origin && event.origin !== origin) return\n listener(data, { receiveTransport, source: event.source, origin: event.origin })\n }\n target.addEventListener('message', messageListener as EventListener)\n // addEventListener alone never enables a MessagePort's queue — only\n // .start() or assigning onmessage does.\n if (target instanceof MessagePort) target.start()\n onAbort(unregisterSignal, () =>\n target.removeEventListener('message', messageListener as EventListener),\n )\n}\n\nexport const sendOsraMessage = (\n transport: EmitTransport,\n message: Message,\n origin = '*',\n transferables: Transferable[] = []\n) => {\n const emitTransport: Extract<EmitTransport, { emit: any }>['emit'] =\n isCustomTransport(transport) ? transport.emit : transport\n\n if (typeof emitTransport === 'function') {\n emitTransport(message, transferables)\n } else if (isWindow(emitTransport)) {\n // Must check first — cross-origin windows throw on other property access.\n emitTransport.postMessage(message, origin, transferables)\n } else if (isWebExtensionPort(emitTransport)) {\n emitTransport.postMessage(message)\n } else if (isWebExtensionRuntime(emitTransport)) {\n emitTransport.sendMessage(message)\n } else if (isWebSocket(emitTransport)) {\n const payload = JSON.stringify(message)\n if (emitTransport.readyState === WebSocket.CONNECTING) {\n emitTransport.addEventListener('open', () => emitTransport.send(payload), { once: true })\n } else {\n emitTransport.send(payload)\n }\n } else if (isSharedWorker(emitTransport)) {\n emitTransport.port.postMessage(message, transferables)\n } else { // MessagePort | ServiceWorker | Worker\n emitTransport.postMessage(message, transferables)\n }\n}\n","import type { Runtime } from 'webextension-polyfill'\nimport type { Message } from '../types.js'\nimport type {\n CustomEmitTransport, CustomReceiveTransport,\n CustomTransport, EmitJsonPlatformTransport,\n EmitTransport, JsonPlatformTransport,\n ReceiveJsonPlatformTransport,\n ReceiveTransport, Transport\n} from './transport.js'\n\nimport { OSRA_KEY } from '../types.js'\nimport { getWebExtensionRuntime } from './transport.js'\n\n// Pulled from globalThis so module evaluation doesn't crash on platforms\n// that haven't shipped Float16Array yet (Node ≤ 23, Chrome ≤ 134, Firefox\n// ≤ 132). Platforms without it just don't round-trip Float16 values.\nconst Float16ArrayCtor = (globalThis as { Float16Array?: typeof Float16Array }).Float16Array\n\nconst typedArrayConstructorsByName = {\n Int8Array,\n Uint8Array,\n Uint8ClampedArray,\n Int16Array,\n Uint16Array,\n Int32Array,\n Uint32Array,\n Float16Array: Float16ArrayCtor,\n Float32Array,\n Float64Array,\n BigInt64Array,\n BigUint64Array,\n} as const\n\nexport type TypedArrayType = keyof typeof typedArrayConstructorsByName\nexport type TypedArrayConstructor = NonNullable<(typeof typedArrayConstructorsByName)[TypedArrayType]>\nexport type TypedArray = InstanceType<TypedArrayConstructor>\n\nconst typedArrayConstructors = Object.values(typedArrayConstructorsByName)\n\nexport const typedArrayToType = (value: TypedArray): TypedArrayType => {\n const name = value.constructor.name as TypedArrayType\n if (name in typedArrayConstructorsByName) return name\n // Subclasses (e.g. Node's Buffer extends Uint8Array). Find the nearest\n // TypedArray ancestor by walking the prototype chain.\n for (const [ancestorName, ctor] of Object.entries(typedArrayConstructorsByName)) {\n if (ctor && value instanceof ctor) return ancestorName as TypedArrayType\n }\n throw new Error('Unknown typed array type')\n}\n\nexport const typedArrayTypeToTypedArrayConstructor = (value: TypedArrayType): TypedArrayConstructor => {\n const ctor = typedArrayConstructorsByName[value]\n if (!ctor) throw new Error('Unknown typed array type')\n return ctor\n}\n\nexport const isTypedArray = (value: unknown): value is TypedArray =>\n typedArrayConstructors.some(ctor => !!ctor && value instanceof ctor)\nexport const isWebSocket = (value: unknown): value is WebSocket => value instanceof WebSocket\nexport const isServiceWorkerContainer = (value: unknown): value is ServiceWorkerContainer => !!globalThis.ServiceWorkerContainer && value instanceof ServiceWorkerContainer\nexport const isServiceWorker = (value: unknown): value is ServiceWorker => !!globalThis.ServiceWorker && value instanceof ServiceWorker\nexport const isWorker = (value: unknown): value is Worker => !!globalThis.Worker && value instanceof Worker\n// Structural stand-in: the real DedicatedWorkerGlobalScope type lives in\n// lib.webworker, which consumers of the published .d.ts may not load.\nexport type DedicatedWorkerGlobalScopeLike = typeof globalThis & {\n postMessage: (message: unknown, transfer?: Transferable[]) => void\n name: string\n}\nexport const isDedicatedWorker = (value: unknown): value is DedicatedWorkerGlobalScopeLike => {\n const scope = (globalThis as { DedicatedWorkerGlobalScope?: abstract new (...args: never[]) => unknown }).DedicatedWorkerGlobalScope\n return !!scope && value instanceof scope\n}\nexport const isSharedWorker = (value: unknown): value is SharedWorker => !!globalThis.SharedWorker && value instanceof SharedWorker\nconst isMessagePort = (value: unknown): value is MessagePort => value instanceof MessagePort\n\nexport const isOsraMessage = (value: unknown): value is Message =>\n !!value\n && typeof value === 'object'\n && OSRA_KEY in value\n && !!value[OSRA_KEY]\n\ntype AnyConstructor = abstract new (...args: any[]) => unknown\n\n/** True if `value` is an instance of any of the given constructors.\n * Tolerates undefined entries (constructors missing on this platform). */\nexport const instanceOfAny = (value: unknown, ctors: readonly (AnyConstructor | undefined)[]): boolean => {\n for (const ctor of ctors) if (ctor && value instanceof ctor) return true\n return false\n}\n\nexport const isSharedArrayBuffer = (value: unknown): boolean =>\n instanceOfAny(value, [globalThis.SharedArrayBuffer])\n/** @deprecated Renamed — this only ever checked SharedArrayBuffer, unlike\n * the unrelated clonable fallback module. Use isSharedArrayBuffer. */\nexport const isClonable = isSharedArrayBuffer\n\n// Types eligible for transfer when the user opts in via `transfer()`. Some\n// entries are also clonable (ArrayBuffer, ImageBitmap, …) — outside a\n// `transfer` box they fall back to clone.\nexport const isTransferable = (value: unknown): value is Transferable =>\n instanceOfAny(value, [\n globalThis.ArrayBuffer,\n globalThis.MessagePort,\n globalThis.ReadableStream,\n globalThis.WritableStream,\n globalThis.TransformStream,\n globalThis.ImageBitmap,\n globalThis.OffscreenCanvas,\n (globalThis as { AudioData?: abstract new (...args: any[]) => unknown }).AudioData,\n (globalThis as { VideoFrame?: abstract new (...args: any[]) => unknown }).VideoFrame,\n (globalThis as { MediaSourceHandle?: abstract new (...args: any[]) => unknown }).MediaSourceHandle,\n (globalThis as { MediaStreamTrack?: abstract new (...args: any[]) => unknown }).MediaStreamTrack,\n (globalThis as { MIDIAccess?: abstract new (...args: any[]) => unknown }).MIDIAccess,\n (globalThis as { RTCDataChannel?: abstract new (...args: any[]) => unknown }).RTCDataChannel,\n (globalThis as { WebTransportReceiveStream?: abstract new (...args: any[]) => unknown }).WebTransportReceiveStream,\n (globalThis as { WebTransportSendStream?: abstract new (...args: any[]) => unknown }).WebTransportSendStream,\n ])\n\nexport type WebExtRuntime = Runtime.Static\nexport const isWebExtensionRuntime = (value: unknown): value is WebExtRuntime => {\n const runtime = getWebExtensionRuntime()\n if (!runtime) return false\n return value === runtime\n}\n\nexport type WebExtPort = ReturnType<WebExtRuntime['connect']> | Runtime.Port\nexport const isWebExtensionPort = (value: unknown, connectPort: boolean = false): value is WebExtPort => {\n if (!value || typeof value !== 'object') return false\n // Prevent SecurityError when `value` is a cross-origin window.\n if (isWindow(value)) return false\n if (!('name' in value) || !('disconnect' in value) || !('postMessage' in value)) return false\n // these properties are only present on WebExtPorts created through runtime.connect()\n if (!connectPort) return true\n return 'sender' in value && 'onMessage' in value && 'onDisconnect' in value\n}\n\nexport type WebExtSender = NonNullable<WebExtPort['sender']>\n\n// Structural guard. Can't distinguish onConnect from onMessage on its own —\n// they share this exact shape.\nconst hasListenerApi = (value: unknown): boolean =>\n !!value\n && typeof value === 'object'\n && !isWindow(value)\n && 'addListener' in value\n && 'hasListener' in value\n && 'removeListener' in value\n\n// Identity-compare against runtime.onConnect — structural checks can't\n// distinguish onConnect from onMessage, and misclassifying causes us to\n// treat each incoming message as a port and crash.\nexport type WebExtOnConnect = WebExtRuntime['onConnect']\nexport const isWebExtensionOnConnect = (value: unknown): value is WebExtOnConnect => {\n const runtime = getWebExtensionRuntime()\n if (!runtime) return false\n return value === runtime.onConnect || value === runtime.onConnectExternal\n}\n\nexport type WebExtOnMessage = WebExtRuntime['onMessage']\nexport const isWebExtensionOnMessage = (value: unknown): value is WebExtOnMessage =>\n hasListenerApi(value)\n\nexport const isWindow = (value: unknown): value is Window => {\n if (!value || typeof value !== 'object') return false\n try {\n return 'window' in value && value.window === value\n } catch {\n // Cross-origin Window access can throw SecurityError — fall back to a\n // shape probe over properties that don't trigger the security check.\n try {\n return 'closed' in value\n && typeof value.closed === 'boolean'\n && 'close' in value\n && typeof value.close === 'function'\n } catch {\n return false\n }\n }\n}\n\nexport const isEmitJsonOnlyTransport = (value: unknown): value is EmitJsonPlatformTransport =>\n isWebSocket(value)\n || isWebExtensionPort(value)\n || isWebExtensionRuntime(value)\n\nexport const isReceiveJsonOnlyTransport = (value: unknown): value is ReceiveJsonPlatformTransport =>\n isWebSocket(value)\n || isWebExtensionPort(value)\n || isWebExtensionOnConnect(value)\n || isWebExtensionOnMessage(value)\n || isWebExtensionRuntime(value)\n\nexport type IsJsonOnlyTransport<T extends Transport> = T extends JsonPlatformTransport ? true : false\nexport const isJsonOnlyTransport = (value: unknown): value is Extract<Transport, JsonPlatformTransport> =>\n // `'isJson' in value` triggers SecurityError on a cross-origin Window (the iframe-broker\n // `emit: window.parent` case) — exclude windows first; the marker only lives on normalized transports.\n (!!value && typeof value === 'object' && !isWindow(value) && 'isJson' in value && value.isJson === true)\n || isEmitJsonOnlyTransport(value)\n || isReceiveJsonOnlyTransport(value)\n\nexport const isEmitTransport = (value: unknown): value is EmitTransport =>\n isWindow(value)\n || isEmitJsonOnlyTransport(value)\n // ServiceWorker instances can postMessage; the container cannot — it only receives.\n || isServiceWorker(value)\n || isWorker(value)\n || isDedicatedWorker(value)\n || isSharedWorker(value)\n || isMessagePort(value)\n || isCustomEmitTransport(value)\n\nexport function assertEmitTransport(transport: Transport): asserts transport is EmitTransport {\n if (!isEmitTransport(transport)) throw new Error('Transport is not emitable')\n}\n\nexport const isReceiveTransport = (value: unknown): value is ReceiveTransport =>\n isWindow(value)\n || isReceiveJsonOnlyTransport(value)\n || isServiceWorkerContainer(value)\n || isWorker(value)\n || isDedicatedWorker(value)\n || isSharedWorker(value)\n || isMessagePort(value)\n || isCustomReceiveTransport(value)\n\nexport function assertReceiveTransport(transport: Transport): asserts transport is ReceiveTransport {\n if (!isReceiveTransport(transport)) throw new Error('Transport is not receiveable')\n}\n\n// Custom transports must be plain objects: Node's worker_threads MessagePort\n// (an EventEmitter) has an inherited `emit` and would otherwise be\n// misclassified, then gutted by normalizeTransport's object spread.\nconst isPlainObjectShape = (value: unknown): value is Record<string, unknown> => {\n if (!value || typeof value !== 'object') return false\n // Prevent SecurityError when `value` is a cross-origin window — its\n // [[GetPrototypeOf]] returns null, which would pass the proto check.\n if (isWindow(value)) return false\n const proto = Object.getPrototypeOf(value)\n return proto === Object.prototype || proto === null\n}\n\nexport const isCustomEmitTransport = (value: unknown): value is CustomEmitTransport => {\n if (!isPlainObjectShape(value)) return false\n if (!('emit' in value)) return false\n return isEmitTransport(value.emit) || typeof value.emit === 'function'\n}\n\nexport const isCustomReceiveTransport = (value: unknown): value is CustomReceiveTransport => {\n if (!isPlainObjectShape(value)) return false\n if (!('receive' in value)) return false\n return isReceiveTransport(value.receive) || typeof value.receive === 'function'\n}\n\nexport const isCustomTransport = (value: unknown): value is CustomTransport =>\n isCustomEmitTransport(value)\n || isCustomReceiveTransport(value)\n\nexport const isTransport = (value: unknown): value is Transport =>\n isEmitTransport(value)\n || isReceiveTransport(value)\n || isCustomTransport(value)\n || isJsonOnlyTransport(value)\n","import type { DefaultRevivableModules, RevivableModule } from './index.js'\nimport type {\n MessageEventTarget,\n MessageFields,\n Uuid,\n} from '../types.js'\nimport type { Transport } from '../utils/transport.js'\nimport type { IsJsonOnlyTransport } from '../utils/type-guards.js'\n\nimport { OSRA_BOX } from '../types.js'\nimport { isJsonOnlyTransport } from '../utils/type-guards.js'\n\nexport type { UnderlyingType } from '../utils/type.js'\n\nexport const BoxBase = {\n [OSRA_BOX]: 'revivable',\n} as const\n\nexport type BoxBase<T extends string = string> =\n & typeof BoxBase\n & { type: T }\n\nexport type RevivableContext<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n transport: Transport\n remoteUuid: Uuid\n /** Typed as a broad dispatcher so revivables can post their own message\n * variants without triggering contravariant function-parameter mismatches\n * across modules. The shape is enforced structurally via `MessageFields`. */\n sendMessage: (message: MessageFields & Record<string, unknown>) => void\n revivableModules: TModules\n eventTarget: MessageEventTarget<TModules>\n}\n\n/** Extract the type a module's `isType` narrows to. Modules marked\n * `capableOnly: true` (clonable, transferable) contribute `never` on JSON\n * transports so users can't type values JSON would silently drop. */\nexport type ExtractType<T, Ctx extends RevivableContext = RevivableContext> =\n T extends { capableOnly: true }\n ? IsJsonOnlyTransport<Ctx['transport']> extends true\n ? never\n : T extends { isType: (value: unknown) => value is infer S } ? S : never\n : T extends { isType: (value: unknown) => value is infer S } ? S : never\n\nexport type ExtractMessages<T> =\n T extends { Messages?: infer B }\n ? B extends { type: string }\n ? string extends B['type'] ? never : B\n : never\n : never\n\nexport type InferMessages<TModules extends readonly unknown[]> =\n ExtractMessages<TModules[number]>\n\nexport type InferRevivables<\n TModules extends readonly unknown[],\n Ctx extends RevivableContext = RevivableContext,\n> =\n ExtractType<TModules[number], Ctx>\n\nexport const isRevivableBox = (value: unknown): value is BoxBase =>\n !!value\n && typeof value === 'object'\n && OSRA_BOX in value\n && value[OSRA_BOX] === 'revivable'\n\n/** Wire shape for an ArrayBuffer: base64 on JSON, raw on clone. */\nexport type BoxedBuffer<TCtx extends RevivableContext = RevivableContext> =\n IsJsonOnlyTransport<TCtx['transport']> extends true ? { base64Buffer: string }\n : IsJsonOnlyTransport<TCtx['transport']> extends false ? { arrayBuffer: ArrayBuffer }\n : { base64Buffer: string } | { arrayBuffer: ArrayBuffer }\n\nexport const boxBuffer = <TCtx extends RevivableContext>(\n buffer: ArrayBuffer,\n context: TCtx,\n): BoxedBuffer<TCtx> =>\n (isJsonOnlyTransport(context.transport)\n ? { base64Buffer: new Uint8Array(buffer).toBase64() }\n : { arrayBuffer: buffer }\n ) as BoxedBuffer<TCtx>\n\nexport const reviveBuffer = (boxed: { arrayBuffer: ArrayBuffer } | { base64Buffer: string }): ArrayBuffer =>\n 'arrayBuffer' in boxed\n ? boxed.arrayBuffer\n : Uint8Array.fromBase64(boxed.base64Buffer).buffer\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase, boxBuffer, reviveBuffer } from './utils.js'\n\nexport const type = 'arrayBuffer' as const\n\nexport const isType = (value: unknown): value is ArrayBuffer =>\n value instanceof ArrayBuffer\n\nexport const box = <T extends ArrayBuffer, T2 extends RevivableContext>(\n value: T,\n context: T2,\n) => ({\n ...BoxBase,\n type,\n ...boxBuffer(value, context),\n})\n\nexport const revive = <T extends ReturnType<typeof box>>(\n value: T,\n _context: RevivableContext,\n) => reviveBuffer(value)\n\nconst typeCheck = () => {\n const boxed = box(new ArrayBuffer(10), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: ArrayBuffer = revived\n // @ts-expect-error - not an ArrayBuffer\n const notArrayBuffer: string = revived\n // @ts-expect-error - cannot box non-ArrayBuffer\n box('not an array buffer', {} as RevivableContext)\n}\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\n\nexport const type = 'date' as const\n\nexport const isType = (value: unknown): value is Date =>\n value instanceof Date\n\nexport const box = <T extends Date, T2 extends RevivableContext>(\n value: T,\n _context: T2\n) => ({\n ...BoxBase,\n type,\n ISOString: value.toISOString()\n})\n\nexport const revive = <T extends ReturnType<typeof box>, T2 extends RevivableContext>(\n value: T,\n _context: T2\n) => new Date(value.ISOString)\n\nconst typeCheck = () => {\n const boxed = box(new Date(), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Date = revived\n // @ts-expect-error - not a Date\n const notDate: string = revived\n // @ts-expect-error - cannot box non-Date\n box('not a date', {} as RevivableContext)\n}\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\n\nexport const type = 'headers' as const\n\nexport const isType = (value: unknown): value is Headers =>\n value instanceof Headers\n\nexport const box = <T extends Headers, T2 extends RevivableContext>(\n value: T,\n _context: T2\n) => ({\n ...BoxBase,\n type,\n entries: [...value.entries()]\n})\n\nexport const revive = <T extends ReturnType<typeof box>, T2 extends RevivableContext>(\n value: T,\n _context: T2\n): Headers => {\n return new Headers(value.entries)\n}\n\nconst typeCheck = () => {\n const boxed = box(new Headers(), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Headers = revived\n // @ts-expect-error - not a Headers\n const notHeaders: string = revived\n // @ts-expect-error - cannot box non-Headers\n box('not a header', {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\n\nexport const type = 'error' as const\n\nexport type BoxedError =\n & BoxBaseType<typeof type>\n & {\n name: string\n message: string\n stack: string\n cause?: Capable\n /** AggregateError only */\n errors?: Capable\n isDOMException?: boolean\n }\n\nconst ERROR_CONSTRUCTORS: Record<string, ErrorConstructor> = {\n Error,\n TypeError: TypeError as ErrorConstructor,\n RangeError: RangeError as ErrorConstructor,\n SyntaxError: SyntaxError as ErrorConstructor,\n ReferenceError: ReferenceError as ErrorConstructor,\n EvalError: EvalError as ErrorConstructor,\n URIError: URIError as ErrorConstructor,\n}\n\nexport const isType = (value: unknown): value is Error =>\n value instanceof Error\n\nexport const box = <T extends Error, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedError => {\n const hasCause = 'cause' in value && value.cause !== undefined\n const isAggregate = typeof AggregateError !== 'undefined' && value instanceof AggregateError\n const isDomException = typeof DOMException !== 'undefined' && value instanceof DOMException\n return {\n ...BoxBase,\n type,\n name: value.name,\n message: value.message,\n stack: value.stack || value.toString(),\n ...(hasCause ? { cause: recursiveBox(value.cause as Capable, context) as Capable } : {}),\n ...(isAggregate ? { errors: recursiveBox(value.errors as Capable, context) as Capable } : {}),\n ...(isDomException ? { isDOMException: true } : {}),\n }\n}\n\nexport const revive = <T extends BoxedError, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): Error => {\n const cause = value.cause !== undefined\n ? recursiveRevive(value.cause, context)\n : undefined\n const options = cause !== undefined ? { cause } : undefined\n\n if (value.isDOMException && typeof DOMException !== 'undefined') {\n const err = new DOMException(value.message, value.name)\n if (value.stack) {\n try { Object.defineProperty(err, 'stack', { value: value.stack, configurable: true }) } catch { /* immutable on some engines */ }\n }\n return err\n }\n\n let err: Error\n if (value.errors !== undefined && typeof AggregateError !== 'undefined') {\n err = new AggregateError(recursiveRevive(value.errors, context) as unknown as unknown[], value.message, options)\n } else {\n const Constructor = ERROR_CONSTRUCTORS[value.name] ?? Error\n err = options !== undefined\n ? new Constructor(value.message, options)\n : new Constructor(value.message)\n }\n if (value.name && err.name !== value.name) err.name = value.name\n if (value.stack) err.stack = value.stack\n return err\n}\n\nconst typeCheck = () => {\n const boxed = box(new Error('test'), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Error = revived\n // @ts-expect-error - not an Error\n const notError: string = revived\n // @ts-expect-error - cannot box non-Error\n box('not an error', {} as RevivableContext)\n}\n","import type { RevivableContext, UnderlyingType, BoxedBuffer } from './utils.js'\nimport type { TypedArray, TypedArrayType } from '../utils/type-guards.js'\n\nimport { BoxBase, boxBuffer, reviveBuffer } from './utils.js'\nimport {\n isTypedArray,\n typedArrayToType,\n typedArrayTypeToTypedArrayConstructor,\n} from '../utils/type-guards.js'\n\nexport const type = 'typedArray' as const\n\ntype BoxedTypedArray<T extends TypedArray, T2 extends RevivableContext> =\n & typeof BoxBase\n & { type: typeof type }\n & { typedArrayType: TypedArrayType }\n & BoxedBuffer<T2>\n & { [UnderlyingType]: T }\n\nexport const isType = isTypedArray\n\nexport const box = <T extends TypedArray, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedTypedArray<T, T2> => {\n // Ship exactly the view's window — shipping the whole backing buffer\n // loses byteOffset/length on revive (silent corruption for subarrays,\n // RangeError for multi-byte views over odd-sized buffers).\n const aligned = value.byteOffset === 0 && value.byteLength === value.buffer.byteLength\n const buffer = aligned\n ? value.buffer as ArrayBuffer\n : (value.buffer as ArrayBuffer).slice(value.byteOffset, value.byteOffset + value.byteLength)\n return {\n ...BoxBase,\n type,\n typedArrayType: typedArrayToType(value),\n ...boxBuffer(buffer, context),\n } as unknown as BoxedTypedArray<T, T2>\n}\n\nexport const revive = <T extends BoxedTypedArray<TypedArray, RevivableContext>>(\n value: T,\n _context: RevivableContext,\n): T[UnderlyingType] =>\n new (typedArrayTypeToTypedArrayConstructor(value.typedArrayType))(reviveBuffer(value)) as T[UnderlyingType]\n\nconst typeCheck = () => {\n const uint8Boxed = box(new Uint8Array(10), {} as RevivableContext)\n const uint8Revived = revive(uint8Boxed, {} as RevivableContext)\n const expectedUint8: Uint8Array = uint8Revived\n // @ts-expect-error - wrong typed array type\n const wrongType: Int32Array = uint8Revived\n\n const float32Boxed = box(new Float32Array(10), {} as RevivableContext)\n const float32Revived = revive(float32Boxed, {} as RevivableContext)\n const expectedFloat32: Float32Array = float32Revived\n // @ts-expect-error - wrong typed array type\n const wrongFloat: Uint8Array = float32Revived\n\n // @ts-expect-error - cannot box non-TypedArray\n box('not a typed array', {} as RevivableContext)\n}\n","/** Per-connection teardown registry. Revivables register cleanup for state\n * tied to a connection (pending RPC settlements, port routing, caches);\n * the connection layer runs it on protocol close or unregisterSignal abort.\n * Registering against an already-torn-down scope runs the callback\n * immediately so late registrations fail fast instead of leaking. */\n\nconst registries = new WeakMap<WeakKey, Set<() => void>>()\nconst tornDown = new WeakSet<WeakKey>()\n\nexport const onTeardown = (scope: WeakKey, fn: () => void): (() => void) => {\n if (tornDown.has(scope)) {\n fn()\n return () => {}\n }\n let set = registries.get(scope)\n if (!set) registries.set(scope, set = new Set())\n set.add(fn)\n return () => set.delete(fn)\n}\n\nexport const runTeardown = (scope: WeakKey): void => {\n if (tornDown.has(scope)) return\n tornDown.add(scope)\n const set = registries.get(scope)\n if (!set) return\n registries.delete(scope)\n for (const fn of set) {\n try { fn() } catch { /* teardown is best-effort */ }\n }\n}\n","import type { Capable } from '../types.js'\nimport type { BoxBase as BoxBaseType, RevivableContext, UnderlyingType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { instanceOfAny, isJsonOnlyTransport } from '../utils/type-guards.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\n\nexport const type = 'transfer' as const\n\nconst TRANSFER_MARKER: unique symbol = Symbol.for('osra.transfer')\n\ntype TransferWrapper<T = unknown> = {\n readonly [TRANSFER_MARKER]: true\n readonly value: T\n}\n\nexport type BoxedTransfer<T extends Capable = Capable> = BoxBaseType<typeof type> & {\n inner: Capable\n degraded: boolean\n [UnderlyingType]: T\n}\n\nconst isObject = (value: unknown): value is object =>\n value !== null && typeof value === 'object'\n\nconst isTransferWrapper = (value: unknown): value is TransferWrapper =>\n isObject(value) && TRANSFER_MARKER in value && value[TRANSFER_MARKER] === true\n\nconst isWrappableTransferable = (value: unknown): boolean => {\n if (!isObject(value)) return false\n if (ArrayBuffer.isView(value)) return true\n return instanceOfAny(value, [\n globalThis.ArrayBuffer,\n globalThis.MessagePort,\n globalThis.ReadableStream,\n globalThis.WritableStream,\n globalThis.TransformStream,\n globalThis.ImageBitmap,\n globalThis.OffscreenCanvas,\n ])\n}\n\n/** Opt into transfer (move) semantics for a transferable value. Idempotent;\n * non-transferable inputs pass through unchanged. Silently degrades to a\n * copy when the platform/transport can't transfer the given type. Lies at\n * the type level — runtime value is a TransferWrapper<T> typed as T. */\nexport const transfer = <T>(value: T): T =>\n (isWrappableTransferable(value)\n ? { [TRANSFER_MARKER]: true, value }\n : value\n ) as T\n\nexport const isType = (value: unknown): value is TransferWrapper =>\n isTransferWrapper(value)\n\nexport const box = <T extends Capable, TContext extends RevivableContext>(\n wrapper: TransferWrapper<T>,\n context: TContext,\n): BoxedTransfer<T> =>\n // `degraded` tells the send-time walker in getTransferableObjects to treat\n // this box as a regular value (no transfer-list entry). JSON transports\n // can't move ownership, so transfer semantics don't apply.\n ({\n ...BoxBase,\n type,\n inner: recursiveBox(wrapper.value, context),\n degraded: isJsonOnlyTransport(context.transport),\n }) as unknown as BoxedTransfer<T>\n\nexport const revive = <T extends BoxedTransfer, TContext extends RevivableContext>(\n value: T,\n context: TContext,\n): T[UnderlyingType] =>\n recursiveRevive(value.inner, context) as T[UnderlyingType]\n\nconst typeCheck = () => {\n const ab = new ArrayBuffer(10)\n const wrapper = { [TRANSFER_MARKER]: true, value: ab } as TransferWrapper<ArrayBuffer>\n const boxed = box(wrapper, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: ArrayBuffer = revived\n // @ts-expect-error - revived is ArrayBuffer, not string\n const notExpected: string = revived\n // @ts-expect-error - cannot box a non-Capable wrapper (WeakMap not assignable)\n box({ [TRANSFER_MARKER]: true, value: new WeakMap() } as TransferWrapper<WeakMap<object, string>>, {} as RevivableContext)\n}\n","import { transfer } from '../revivables/transfer.js'\nimport { isRevivableBox } from '../revivables/utils.js'\nimport { instanceOfAny, isSharedArrayBuffer, isTransferable } from './type-guards.js'\n\nexport { transfer }\n\n// Must-transfer types: structured clone can't copy these, so any occurrence\n// in the outgoing message must go on the transfer list — opt-in or not.\n// (MessagePort is the canonical case: cloning would leave the peer mute.)\nconst isMustTransfer = (value: unknown): value is Transferable =>\n instanceOfAny(value, [\n globalThis.MessagePort,\n globalThis.ReadableStream,\n globalThis.WritableStream,\n globalThis.TransformStream,\n globalThis.OffscreenCanvas,\n (globalThis as { MediaSourceHandle?: abstract new (...args: any[]) => unknown }).MediaSourceHandle,\n (globalThis as { MediaStreamTrack?: abstract new (...args: any[]) => unknown }).MediaStreamTrack,\n (globalThis as { MIDIAccess?: abstract new (...args: any[]) => unknown }).MIDIAccess,\n (globalThis as { RTCDataChannel?: abstract new (...args: any[]) => unknown }).RTCDataChannel,\n (globalThis as { WebTransportReceiveStream?: abstract new (...args: any[]) => unknown }).WebTransportReceiveStream,\n (globalThis as { WebTransportSendStream?: abstract new (...args: any[]) => unknown }).WebTransportSendStream,\n ])\n\n// Structural check — keeps the walker decoupled from the module graph.\n// `degraded` (set by transfer.box) means the wrapper is a no-op here.\nconst isTransferBox = (value: unknown): value is { inner: unknown, degraded: boolean } =>\n isRevivableBox(value) && value.type === 'transfer'\n\n/** Walk a boxed message and collect Transferables to move (rather than copy)\n * on postMessage:\n * 1. Must-transfer types are always included.\n * 2. Clonable types (SharedArrayBuffer) are skipped.\n * 3. Other Transferables are included only inside a non-degraded transfer\n * box (user opted in AND the platform supports transferring). */\nexport const getTransferableObjects = (value: unknown): Transferable[] => {\n const transferables: Transferable[] = []\n const seen = new WeakSet<object>()\n\n const recurse = (value: unknown, inTransferBox: boolean): void => {\n if (!value || typeof value !== 'object') return\n if (seen.has(value)) return\n seen.add(value)\n\n if (isSharedArrayBuffer(value)) return\n\n if (isTransferBox(value)) {\n // Non-degraded box flips into transfer mode for everything below.\n recurse(value.inner, inTransferBox || !value.degraded)\n return\n }\n\n if (isMustTransfer(value)) {\n transferables.push(value)\n return\n }\n\n if (isTransferable(value)) {\n if (inTransferBox) {\n transferables.push(value)\n }\n return\n }\n\n // TypedArray / DataView expose every numeric index — iterating a 100 KB\n // buffer would walk 100 K entries for nothing. The underlying buffer is\n // the only candidate; the typed-array revivable handles that path.\n if (ArrayBuffer.isView(value)) return\n\n if (Array.isArray(value)) {\n for (const item of value) recurse(item, inTransferBox)\n return\n }\n\n for (const item of Object.values(value)) recurse(item, inTransferBox)\n }\n\n recurse(value, false)\n return transferables\n}\n","import type { TypedMessagePort, TypedMessagePortEventMap } from './typed-message-channel.js'\n\nexport class EventPort<T> extends EventTarget {\n addEventListener<K extends keyof TypedMessagePortEventMap<T> & string>(\n type: K,\n listener: ((event: TypedMessagePortEventMap<T>[K]) => void) | null,\n options?: boolean | AddEventListenerOptions\n ): void\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | AddEventListenerOptions\n ): void\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | AddEventListenerOptions\n ): void {\n super.addEventListener(type, listener, options)\n }\n\n removeEventListener<K extends keyof TypedMessagePortEventMap<T> & string>(\n type: K,\n listener: ((event: TypedMessagePortEventMap<T>[K]) => void) | null,\n options?: boolean | EventListenerOptions\n ): void\n removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | EventListenerOptions\n ): void\n removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | EventListenerOptions\n ): void {\n super.removeEventListener(type, listener, options)\n }\n\n _peer: EventPort<any> | undefined\n _queue: MessageEvent<T>[] = []\n _started = false\n _closed = false\n _onClose: (() => void) | undefined\n\n private _onmessage: ((this: MessagePort, ev: MessageEvent<T>) => unknown) | null = null\n\n get onmessage(): ((this: MessagePort, ev: MessageEvent<T>) => unknown) | null {\n return this._onmessage\n }\n set onmessage(value: ((this: MessagePort, ev: MessageEvent<T>) => unknown) | null) {\n this._onmessage = value\n if (value !== null) this.start()\n }\n\n onmessageerror: ((this: MessagePort, ev: MessageEvent) => unknown) | null = null\n\n dispatchEvent(event: Event): boolean {\n if (event.type === 'message') {\n this._onmessage?.call(this, event as MessageEvent<T>)\n } else if (event.type === 'messageerror') {\n this.onmessageerror?.call(this, event as MessageEvent)\n }\n return super.dispatchEvent(event)\n }\n\n postMessage(message: T, _options?: Transferable[] | StructuredSerializeOptions): void {\n const peer = this._peer\n if (!peer || peer._closed) return\n queueMicrotask(() => {\n if (peer._closed) return\n const event = new MessageEvent('message', { data: message })\n if (peer._started) {\n peer.dispatchEvent(event)\n } else {\n peer._queue.push(event)\n }\n })\n }\n\n start(): void {\n if (this._started) return\n this._started = true\n for (const event of this._queue.splice(0)) {\n this.dispatchEvent(event)\n }\n }\n\n close(): void {\n if (this._closed) return\n this._closed = true\n this._queue.length = 0\n this._onClose?.()\n // Mirror the platform 'close' event: closing a port notifies its peer.\n // Deferred so messages posted before the close still deliver first.\n const peer = this._peer\n if (peer && !peer._closed) {\n queueMicrotask(() => {\n if (!peer._closed) peer.dispatchEvent(new Event('close'))\n })\n }\n }\n}\n\nexport interface EventPort<T>\n extends Omit<\n TypedMessagePort<T>,\n 'addEventListener' | 'removeEventListener'\n > {}\n\nexport class EventChannel<T1 = unknown, T2 = unknown> {\n readonly port1: EventPort<T1>\n readonly port2: EventPort<T2>\n\n constructor() {\n const port1 = new EventPort<T1>()\n const port2 = new EventPort<T2>()\n port1._peer = port2\n port2._peer = port1\n this.port1 = port1\n this.port2 = port2\n }\n}\n","/**\n * Run `cleanup` after `target` is garbage-collected. Returns a handle to\n * cancel the tracking before that happens.\n *\n * Backed by a single shared FinalizationRegistry — every revivable that\n * needs FR semantics goes through this so the boilerplate (token,\n * unregister, cycle-safety contract) lives in one place.\n *\n * Contract: `cleanup` MUST NOT (transitively) reference `target`. The\n * registry strong-holds the cleanup callback, the cleanup would then\n * strong-hold target, and the engine would never see target as\n * collectable. Use a `WeakRef` if cleanup needs something that points\n * back at target.\n *\n * Errors thrown from cleanup are swallowed: the callback fires from the\n * FR thread, where there's no caller to surface them to.\n */\nexport type GcUnregister = () => void\n\nconst registry = new FinalizationRegistry<() => void>((cleanup) => {\n try { cleanup() } catch { /* no caller to surface to */ }\n})\n\nexport const trackGc = (target: WeakKey, cleanup: () => void): GcUnregister => {\n const token = {}\n registry.register(target, cleanup, token)\n return () => registry.unregister(token)\n}\n","import type { Capable, StructurableTransferable, Uuid } from '../types.js'\nimport type { TypedMessageChannel, TypedMessagePort } from '../utils/typed-message-channel.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { UnderlyingType } from '../utils/type.js'\nimport type {\n BadFieldValue, BadFieldPath, BadFieldParent,\n ErrorMessage, BadValue, Path, ParentObject\n} from '../utils/capable-check.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\nimport { getTransferableObjects } from '../utils/transferable.js'\nimport { isJsonOnlyTransport } from '../utils/type-guards.js'\nimport { EventChannel, EventPort } from '../utils/event-channel.js'\nimport { trackGc } from '../utils/gc-tracker.js'\nimport { onTeardown } from '../utils/teardown.js'\n\nexport const type = 'messagePort' as const\n\nexport type Messages =\n | { type: 'message', remoteUuid: Uuid, data: Capable, portId: Uuid }\n | { type: 'message-port-close', remoteUuid: Uuid, portId: Uuid }\n\nexport declare const Messages: Messages\n\nexport type AnyPort<T = Capable> =\n | TypedMessagePort<T>\n | EventPort<T>\n\nexport type BoxedMessagePort<T = Capable> =\n & BoxBaseType<typeof type>\n & (\n | { portId: Uuid, synthetic: true }\n | { portId: Uuid, synthetic: false }\n | { port: AnyPort<T>, autoBox?: boolean }\n )\n & { [UnderlyingType]: TypedMessagePort<T> }\n\n// `[T] extends [Capable]` disables distributive conditionals so `A | B` gives\n// back `AnyPort<A | B>`, not `AnyPort<A> | AnyPort<B>`. The error branch\n// intersects with AnyPort<T> so excess-property check targets the failure\n// rather than the user's port-shaped keys.\ntype StructurableTransferablePort<T> = [T] extends [Capable]\n ? AnyPort<T>\n : AnyPort<T> & {\n [ErrorMessage]: 'Message type must extend Capable'\n [BadValue]: BadFieldValue<T, Capable>\n [Path]: BadFieldPath<T, Capable>\n [ParentObject]: BadFieldParent<T, Capable>\n }\n\ntype ConnectionMessagePortState = {\n /** O(1) per-portId dispatch — avoids the O(N) addEventListener scan\n * that was the bottleneck for tight-loop RPC traffic. */\n portHandlers: Map<string, (message: Messages) => void>\n}\n\nconst connectionStateMap = new WeakMap<RevivableContext, ConnectionMessagePortState>()\n\nconst getState = (context: RevivableContext): ConnectionMessagePortState => {\n const state = connectionStateMap.get(context)\n if (!state) throw new Error('osra message-port: connection state missing; did init() run?')\n return state\n}\n\nexport const init = (context: RevivableContext): void => {\n const state: ConnectionMessagePortState = { portHandlers: new Map() }\n connectionStateMap.set(context, state)\n\n context.eventTarget.addEventListener('message', ({ detail }) => {\n if (detail.type !== 'message' && detail.type !== 'message-port-close') return\n state.portHandlers.get(detail.portId)?.(detail)\n })\n\n // Connection death = every routed port is dead: run each handler's close\n // arm so user-facing ports close and routing entries clear.\n onTeardown(context, () => {\n for (const [portId, handler] of [...state.portHandlers]) {\n handler({ type: 'message-port-close', remoteUuid: context.remoteUuid, portId: portId as Uuid })\n }\n state.portHandlers.clear()\n })\n}\n\nexport const isType = (value: unknown): value is MessagePort | EventPort<StructurableTransferable> =>\n value instanceof MessagePort || value instanceof EventPort\n\nconst sendClose = (context: RevivableContext, portId: Uuid) => {\n try {\n context.sendMessage({ type: 'message-port-close', remoteUuid: context.remoteUuid, portId })\n } catch { /* connection torn down */ }\n}\n\nconst postRevived = <T>(port: AnyPort<T>, data: T, synthetic: boolean) => {\n if (synthetic) port.postMessage(data)\n else port.postMessage(data, getTransferableObjects(data))\n}\n\nexport const box = <T, T2 extends RevivableContext = RevivableContext>(\n value: StructurableTransferablePort<T>,\n context: T2,\n options?: { autoBox?: boolean },\n): BoxedMessagePort<T> => {\n // Synthetic EventPorts aren't structured-clonable, so even on a clone\n // transport we route them via portId.\n const synthetic = value instanceof EventPort\n if (!synthetic && !isJsonOnlyTransport(context.transport)) {\n return {\n ...BoxBase, type, port: value,\n ...(options?.autoBox ? { autoBox: true } : {}),\n } as BoxedMessagePort<T>\n }\n\n const { portHandlers } = getState(context)\n const liveRef: AnyPort<T> = value\n const portId: Uuid = globalThis.crypto.randomUUID()\n\n // The FR-held cleanup must not (transitively) strong-hold liveRef or the\n // context — the gc-tracker contract — or the registry pins them forever\n // and the safety net can never fire.\n const liveRefWeak = new WeakRef(liveRef)\n const contextWeak = new WeakRef(context)\n const portHandlersWeak = new WeakRef(portHandlers)\n\n let cleanedUp = false\n const performCleanup = () => {\n if (cleanedUp) return\n cleanedUp = true\n portHandlersWeak.deref()?.delete(portId)\n unregisterGc?.()\n const live = liveRefWeak.deref()\n live?.removeEventListener('message', outgoingListener as EventListener)\n if (live instanceof EventPort) live._onClose = undefined\n }\n\n const handler = (message: Messages) => {\n if (message.type === 'message-port-close') {\n performCleanup()\n // Peer side closed — surface the platform 'close' event before closing.\n liveRef.dispatchEvent(new Event('close'))\n liveRef.close()\n return\n }\n postRevived(liveRef, recursiveRevive(message.data, context) as T, false)\n }\n\n function outgoingListener({ data }: MessageEvent<Capable>) {\n context.sendMessage({\n type: 'message',\n remoteUuid: context.remoteUuid,\n data: recursiveBox(data, context),\n portId,\n })\n }\n\n // Safety net only — `handler` strong-holds liveRef via portHandlers, so\n // the FR won't fire while the connection is alive. Real cleanup runs via\n // the wire `message-port-close`, EventPort `_onClose`, or teardown.\n const unregisterGc = trackGc(liveRef, () => {\n const ctx = contextWeak.deref()\n if (ctx) sendClose(ctx, portId)\n performCleanup()\n })\n\n liveRef.addEventListener('message', outgoingListener as EventListener)\n liveRef.start()\n\n if (liveRef instanceof EventPort) {\n liveRef._onClose = () => {\n if (cleanedUp) return\n sendClose(context, portId)\n performCleanup()\n }\n }\n\n portHandlers.set(portId, handler)\n\n return { ...BoxBase, type, portId, synthetic } as BoxedMessagePort<T>\n}\n\nexport const revive = <T extends Capable, T2 extends RevivableContext>(\n value: BoxedMessagePort<T>,\n context: T2,\n): TypedMessagePort<T> => {\n if ('port' in value) {\n if (value.autoBox) return createProtocolPort<T>(value.port as TypedMessagePort<Capable>, context)\n return value.port\n }\n return reviveViaPortId<T>(value.portId, context, value.synthetic)\n}\n\n/** Wraps a real MessagePort so revivables can treat it like a transparent\n * EventTarget that auto-boxes/revives — letting live values (Promises,\n * Functions, …) ride a clone-only transport. */\nconst createProtocolPort = <T>(\n port: TypedMessagePort<Capable>,\n ctx: RevivableContext,\n): TypedMessagePort<T> => {\n const target = new EventTarget() as TypedMessagePort<T>\n const onMessage = ({ data }: MessageEvent<Capable>): void => {\n target.dispatchEvent(new MessageEvent('message', { data: recursiveRevive(data, ctx) }))\n }\n // Modern browsers fire 'close' on a MessagePort when its entangled peer\n // closes or its realm dies — forward it so consumers can clean up.\n const onClose = (): void => {\n target.dispatchEvent(new Event('close'))\n }\n port.addEventListener('message', onMessage)\n port.addEventListener('close', onClose as EventListener)\n target.postMessage = (data: T, opt?: Transferable[] | StructuredSerializeOptions) => {\n const boxed = recursiveBox(data as Capable, ctx)\n const transferables = getTransferableObjects(boxed)\n const extra = Array.isArray(opt) ? opt : []\n port.postMessage(boxed, extra.length ? [...transferables, ...extra] : transferables)\n }\n target.start = () => port.start()\n target.close = () => {\n port.removeEventListener('message', onMessage)\n port.removeEventListener('close', onClose as EventListener)\n port.close()\n }\n return target\n}\n\n/** Factory for revivable-internal channels. Returns a local port that\n * auto-boxes live values regardless of transport, plus a pre-boxed remote\n * port the revivable embeds in its Boxed* structure. */\nexport const createRevivableChannel = <T extends Capable>(\n context: RevivableContext,\n): { localPort: AnyPort<T>, boxedRemote: BoxedMessagePort<T> } => {\n if (isJsonOnlyTransport(context.transport)) {\n const { port1, port2 } = new EventChannel<T, T>()\n return {\n localPort: port1,\n boxedRemote: box(port2 as StructurableTransferablePort<T>, context),\n }\n }\n const { port1, port2 } = new MessageChannel() as unknown as TypedMessageChannel<Capable, Capable>\n return {\n localPort: createProtocolPort<T>(port1, context) as unknown as AnyPort<T>,\n boxedRemote: box(port2 as unknown as StructurableTransferablePort<T>, context, { autoBox: true }),\n }\n}\n\nconst reviveViaPortId = <T extends Capable>(\n portId: Uuid,\n context: RevivableContext,\n synthetic: boolean,\n): TypedMessagePort<T> => {\n const { portHandlers } = getState(context)\n const { port1: userPort, port2: internalPort } =\n synthetic\n ? new EventChannel<T, T>()\n : new MessageChannel() as unknown as TypedMessageChannel<T, T>\n const userPortRef = new WeakRef(userPort)\n // For synthetic EventChannels, internalPort._peer === userPort — holding\n // internalPort strongly from the trackGc cleanup would re-pin userPort.\n const internalPortRef = new WeakRef(internalPort)\n\n let cleanedUp = false\n const performCleanup = () => {\n if (cleanedUp) return\n cleanedUp = true\n portHandlers.delete(portId)\n const internal = internalPortRef.deref()\n internal?.removeEventListener('message', internalPortListener as EventListener)\n internal?.close()\n unregisterGc?.()\n }\n\n const handler = (message: Messages) => {\n if (message.type === 'message-port-close') {\n performCleanup()\n const user = userPortRef.deref()\n // Peer side closed — surface the platform 'close' event before closing.\n user?.dispatchEvent(new Event('close'))\n user?.close()\n return\n }\n if (!userPortRef.deref()) {\n performCleanup()\n return\n }\n const internal = internalPortRef.deref()\n if (!internal) return\n postRevived(internal, recursiveRevive(message.data, context) as T, synthetic)\n }\n\n const internalPortListener = ({ data }: MessageEvent<T>) => {\n context.sendMessage({\n type: 'message',\n remoteUuid: context.remoteUuid,\n data: recursiveBox(data, context),\n portId,\n })\n }\n\n const unregisterGc = trackGc(userPort, () => {\n sendClose(context, portId)\n performCleanup()\n })\n\n if (userPort instanceof EventPort) {\n userPort._onClose = () => {\n if (cleanedUp) return\n sendClose(context, portId)\n performCleanup()\n }\n }\n\n internalPort.addEventListener('message', internalPortListener as EventListener)\n internalPort.start()\n\n portHandlers.set(portId, handler)\n\n return userPort\n}\n\nconst typeCheck = () => {\n const port = {} as TypedMessagePort<{ foo: string }>\n const boxed = box(port, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: AnyPort<{ foo: string }> = revived\n // @ts-expect-error - wrong message type\n const wrongType: AnyPort<{ bar: number }> = revived\n box({} as TypedMessagePort<Promise<string>>, {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { UnderlyingType } from './index.js'\nimport type {\n BadFieldValue, BadFieldPath, BadFieldParent,\n ErrorMessage, BadValue, Path, ParentObject\n} from '../utils/capable-check.js'\n\nimport { BoxBase } from './utils.js'\nimport { onTeardown } from '../utils/teardown.js'\nimport {\n createRevivableChannel,\n revive as reviveMessagePort,\n BoxedMessagePort,\n AnyPort,\n} from './message-port.js'\n\nexport const type = 'promise' as const\n\nexport type Context =\n | { type: 'resolve', data: Capable }\n | { type: 'reject', error: Capable }\n\n// Error branches intersect with T so the user's own keys land on the target —\n// otherwise TS's excess-property check flags a user key instead of the failure.\ntype CapablePromise<T> = T extends Promise<infer U>\n ? U extends Capable\n ? T\n : T & {\n [ErrorMessage]: 'Value type must extend a Promise that resolves to a Capable'\n [BadValue]: BadFieldValue<U, Capable>\n [Path]: BadFieldPath<U, Capable>\n [ParentObject]: BadFieldParent<U, Capable>\n }\n : T & {\n [ErrorMessage]: 'Value type must extend a Promise that resolves to a Capable'\n [BadValue]: T\n [Path]: ''\n [ParentObject]: T\n }\n\ntype ExtractCapable<T> = T extends Promise<infer U>\n ? U extends Capable ? U : never\n : never\n\nconst isCapablePromise = <T, U extends Capable = ExtractCapable<T>>(value: T): value is T & Promise<U> =>\n value instanceof Promise\n\nexport type BoxedPromise<T extends Capable = Capable> =\n & BoxBaseType<typeof type>\n & { port: BoxedMessagePort<Context> }\n & { [UnderlyingType]: T }\n\n// Pins the revived port between executor return and result arrival — the\n// port↔listener cycle has no other anchor (the caller only holds the\n// returned Promise). The once-listener removes its entry on settle.\nconst inFlightPromisePorts = new Set<AnyPort<Context>>()\n\nexport const isType = (value: unknown): value is Promise<any> =>\n value instanceof Promise\n\nexport const box = <T, T2 extends RevivableContext>(\n value: CapablePromise<T>,\n context: T2\n): BoxedPromise<ExtractCapable<T>> => {\n if (!isCapablePromise(value)) throw new TypeError('Expected Promise')\n const { localPort, boxedRemote } = createRevivableChannel<Context>(context)\n\n const sendResult = (result: Context) => {\n localPort.postMessage(result)\n localPort.close()\n }\n\n value\n .then((data: ExtractCapable<T>) => sendResult({ type: 'resolve', data }))\n .catch((error: unknown) => sendResult({ type: 'reject', error: error as Capable }))\n\n return { ...BoxBase, type, port: boxedRemote } as BoxedPromise<ExtractCapable<T>>\n}\n\nexport const revive = <T extends BoxedPromise, T2 extends RevivableContext>(\n value: T,\n context: T2\n) => {\n const port = reviveMessagePort(value.port, context)\n inFlightPromisePorts.add(port)\n // portId boxes route over the wire and die with the connection; real\n // transferred MessagePorts (clone transports) keep working past protocol\n // teardown, so those must stay pending rather than reject.\n const wireRouted = 'portId' in value.port\n return new Promise<T[UnderlyingType]>((resolve, reject) => {\n const settle = () => {\n port.close()\n inFlightPromisePorts.delete(port)\n removeTeardown()\n }\n const removeTeardown = !wireRouted ? () => {} : onTeardown(context, () => {\n reject(new Error('osra: connection closed'))\n settle()\n })\n port.addEventListener('message', ({ data: result }) => {\n if (result.type === 'resolve') resolve(result.data as T[UnderlyingType])\n else reject(result.error)\n settle()\n }, { once: true })\n port.start()\n })\n}\n\nconst typeCheck = () => {\n const boxed = box(Promise.resolve(1 as const), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Promise<1> = revived\n // @ts-expect-error\n const notExpected: Promise<string> = revived\n // @ts-expect-error\n box(1 as const, {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { UnderlyingType, RevivableContext, BoxBase as BoxBaseType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox } from './index.js'\nimport { getTransferableObjects } from '../utils/transferable.js'\nimport { EventChannel, type EventPort } from '../utils/event-channel.js'\nimport { onTeardown } from '../utils/teardown.js'\nimport { box as boxMessagePort, revive as reviveMessagePort, BoxedMessagePort } from './message-port.js'\n\nexport const type = 'function' as const\n\ntype ResultMessage =\n | { type: 'return', value: Capable }\n | { type: 'throw', error: Capable }\n\ntype CallContext = [EventPort<Capable>, Capable[]]\n\n// Pins return-value ports between call-site return and result arrival —\n// the (port ↔ once-listener ↔ resolve/reject) cycle has no other anchor.\nconst inFlightReturnPorts = new Set<EventPort<Capable>>()\n\nexport type BoxedFunction<T extends (...args: any[]) => any = (...args: any[]) => any> =\n & BoxBaseType<typeof type>\n & { port: BoxedMessagePort<CallContext> }\n & { [UnderlyingType]: (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>> }\n\ntype CapableFunction<T> = T extends (...args: infer P) => infer R\n ? P extends Capable[]\n ? R extends Capable ? T : never\n : never\n : never\n\nexport const isType = (value: unknown): value is (...args: any[]) => any =>\n typeof value === 'function'\n\nexport const box = <T extends (...args: any[]) => any, T2 extends RevivableContext>(\n value: T & CapableFunction<T>,\n context: T2,\n): BoxedFunction<T> => {\n // EventChannel rather than MessageChannel: revived live values arriving\n // in args (functions, EventTarget façades, …) aren't structured-clonable.\n const { port1: localPort, port2: remotePort } = new EventChannel<CallContext, CallContext>()\n\n localPort.addEventListener('message', ({ data }) => {\n // Don't recursiveRevive — message-port handler already revived in place.\n // Re-walking would Object.fromEntries plain args, breaking identity.\n const [returnPort, args] = data as CallContext\n ;(async () => {\n let message: ResultMessage\n try {\n const resolved = await value(...(args as Parameters<T>))\n message = { type: 'return', value: resolved as Capable }\n } catch (error) {\n message = { type: 'throw', error: error as Capable }\n }\n const boxedResult = recursiveBox(message as Capable, context)\n returnPort.postMessage(boxedResult, getTransferableObjects(boxedResult))\n // Defer close so the result reaches the peer before tear-down. The\n // close fires _onClose, dropping per-call routing entries on both\n // sides — without it portHandlers grows one entry per call.\n queueMicrotask(() => {\n try { returnPort.close() } catch { /* may already be closed */ }\n })\n })()\n })\n localPort.start()\n\n return {\n ...BoxBase,\n type,\n port: boxMessagePort(remotePort as unknown as MessagePort, context),\n } as unknown as BoxedFunction<T>\n}\n\nexport const revive = <T extends BoxedFunction, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): T[UnderlyingType] => {\n const port = reviveMessagePort(value.port, context) as unknown as MessagePort\n\n return ((...args: Capable[]) =>\n new Promise((resolve, reject) => {\n const { port1: returnLocal, port2: returnRemote } = new EventChannel<Capable, Capable>()\n inFlightReturnPorts.add(returnLocal)\n\n const settle = () => {\n returnLocal.close()\n inFlightReturnPorts.delete(returnLocal)\n removeTeardown()\n }\n // Calls always route over the wire (EventPorts are synthetic on every\n // transport), so connection death must reject them — GC-drop of the\n // proxy intentionally does not (see funcDropDoesNotRejectPending).\n const removeTeardown = onTeardown(context, () => {\n reject(new Error('osra: connection closed'))\n settle()\n })\n\n returnLocal.addEventListener('message', ({ data }) => {\n const message = data as ResultMessage\n if (message.type === 'return') resolve(message.value)\n else reject(message.error)\n settle()\n }, { once: true })\n returnLocal.start()\n\n const callContext = recursiveBox([returnRemote, args] as unknown as Capable, context)\n port.postMessage(callContext, getTransferableObjects(callContext))\n })) as T[UnderlyingType]\n}\n\nconst typeCheck = () => {\n const boxed = box((a: number, b: string) => a + b.length, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: (a: number, b: string) => Promise<number> = revived\n // @ts-expect-error - wrong return type\n const wrongReturn: (a: number, b: string) => Promise<string> = revived\n // @ts-expect-error - wrong parameter types\n const wrongParams: (a: string, b: number) => Promise<number> = revived\n // @ts-expect-error - non-Capable parameter type (WeakMap isn't structured-clonable)\n box((a: WeakMap<object, string>) => a.toString(), {} as RevivableContext)\n // @ts-expect-error - non-Capable return type\n box(() => new WeakMap<object, string>(), {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { UnderlyingType } from './index.js'\n\nimport { BoxBase } from './utils.js'\nimport {\n createRevivableChannel,\n revive as reviveMessagePort,\n BoxedMessagePort\n} from './message-port.js'\n\nexport const type = 'readableStream' as const\n\nexport type PullContext =\n | { type: 'pull' }\n | { type: 'cancel', reason?: Capable }\n\ntype ChunkMessage<T = unknown> = Promise<ReadableStreamReadResult<T>>\n\ntype Msg = PullContext | ChunkMessage\n\nexport type BoxedReadableStream<T extends ReadableStream = ReadableStream> =\n & BoxBaseType<typeof type>\n & { port: BoxedMessagePort<Msg> }\n & { [UnderlyingType]: T }\n\nexport const isType = (value: unknown): value is ReadableStream =>\n value instanceof ReadableStream\n\nexport const box = <T extends ReadableStream, T2 extends RevivableContext>(\n value: T,\n context: T2\n): BoxedReadableStream<T> => {\n const { localPort, boxedRemote } = createRevivableChannel<Msg>(context)\n const reader = value.getReader()\n\n localPort.addEventListener('message', ({ data }) => {\n if ('type' in data && data.type === 'pull') {\n // reader.read() is a Promise — localPort boxes it for the transport.\n localPort.postMessage(reader.read())\n } else {\n reader.cancel('type' in data ? data.reason : undefined).catch(() => {})\n localPort.close()\n }\n })\n // Abnormal channel death (consumer dropped, connection closed): stop the\n // producer and release the source lock instead of leaking both forever.\n localPort.addEventListener('close', () => {\n reader.cancel(new Error('osra: connection closed')).catch(() => {})\n }, { once: true })\n localPort.start()\n\n return { ...BoxBase, type, port: boxedRemote } as BoxedReadableStream<T>\n}\n\nexport const revive = <T extends BoxedReadableStream, T2 extends RevivableContext>(\n value: T,\n context: T2\n): T[UnderlyingType] => {\n const port = reviveMessagePort(value.port, context)\n port.start()\n\n let done = false\n return new ReadableStream({\n start: (controller) => {\n // Channel death mid-stream (source dropped, connection closed): error\n // the consumer instead of hanging its pending read forever.\n port.addEventListener('close', () => {\n if (done) return\n done = true\n try { controller.error(new Error('osra: connection closed')) } catch { /* already settled */ }\n }, { once: true })\n },\n pull: (controller) => new Promise<void>((resolve, reject) => {\n port.addEventListener('message', ({ data }) => {\n if (!(data instanceof Promise)) return\n data\n .then(result => {\n if (result.done) {\n done = true\n controller.close()\n // Stream exhausted — release the channel on both sides.\n port.postMessage({ type: 'cancel' })\n queueMicrotask(() => port.close())\n }\n else controller.enqueue(result.value)\n resolve()\n })\n .catch(error => {\n done = true\n reject(error)\n })\n }, { once: true })\n port.postMessage({ type: 'pull' })\n }),\n cancel: (reason) => {\n done = true\n port.postMessage({ type: 'cancel', reason: reason as Capable })\n // Defer close so the cancel message dispatches before tear-down.\n queueMicrotask(() => port.close())\n },\n }) as T[UnderlyingType]\n}\n\nconst typeCheck = () => {\n const stream = new ReadableStream<number>()\n const boxed = box(stream, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: ReadableStream<number> = revived\n // @ts-expect-error - wrong stream type\n const wrongType: ReadableStream<string> = revived\n // @ts-expect-error - not a ReadableStream\n box('not a stream', {} as RevivableContext)\n}\n","import type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { UnderlyingType } from './index.js'\nimport type { Capable } from '../types.js'\n\nimport { BoxBase } from './utils.js'\nimport {\n createRevivableChannel,\n revive as reviveMessagePort,\n BoxedMessagePort,\n} from './message-port.js'\n\nexport const type = 'writableStream' as const\n\n// Outgoing wire shape (revive → box): one of these per call.\nexport type WriteContext =\n | { type: 'write', chunk: Capable }\n | { type: 'close' }\n | { type: 'abort', reason: Capable }\n\n// Reply from box → revive after a write completes (so writer.write() awaits).\nexport type WriteAck =\n | { type: 'ack' }\n | { type: 'err', error: string }\n\nexport type Msg = WriteContext | WriteAck\n\nexport type BoxedWritableStream<T extends WritableStream = WritableStream> =\n & BoxBaseType<typeof type>\n & { port: BoxedMessagePort<Msg> }\n & { [UnderlyingType]: T }\n\nexport const isType = (value: unknown): value is WritableStream =>\n value instanceof WritableStream\n\nexport const box = <T extends WritableStream, T2 extends RevivableContext>(\n value: T,\n context: T2\n): BoxedWritableStream<T> => {\n const { localPort, boxedRemote } = createRevivableChannel<Msg>(context)\n const writer = value.getWriter()\n\n let terminated = false\n const settle = (op: Promise<void>, terminal: boolean) =>\n op\n .then(() => localPort.postMessage({ type: 'ack' }))\n .catch((err) => localPort.postMessage({ type: 'err', error: (err as Error)?.message ?? String(err) }))\n .then(() => {\n if (!terminal) return\n terminated = true\n // Terminal op acked — release the channel on both sides.\n queueMicrotask(() => localPort.close())\n })\n\n localPort.addEventListener('message', ({ data }) => {\n if (!data || typeof data !== 'object' || !('type' in data)) return\n if (data.type === 'write') settle(writer.write((data as { chunk: Capable }).chunk as any), false)\n else if (data.type === 'close') settle(writer.close(), true)\n else if (data.type === 'abort') settle(writer.abort((data as { reason: Capable }).reason as any), true)\n })\n // Abnormal channel death (consumer dropped, connection closed): abort the\n // sink and release the writer lock instead of holding both forever.\n localPort.addEventListener('close', () => {\n if (terminated) return\n terminated = true\n writer.abort(new Error('osra: connection closed')).catch(() => {})\n }, { once: true })\n localPort.start()\n\n return { ...BoxBase, type, port: boxedRemote } as BoxedWritableStream<T>\n}\n\nexport const revive = <T extends BoxedWritableStream, T2 extends RevivableContext>(\n value: T,\n context: T2\n): T[UnderlyingType] => {\n const port = reviveMessagePort(value.port, context)\n port.start()\n\n // Channel death mid-write (sink dropped, connection closed): reject every\n // pending request instead of hanging the writer forever.\n const pending = new Set<(error: Error) => void>()\n let dead = false\n port.addEventListener('close', () => {\n dead = true\n const error = new Error('osra: connection closed')\n for (const reject of [...pending]) reject(error)\n pending.clear()\n }, { once: true })\n\n // Each `write` call posts a 'write' message and awaits an 'ack'/'err'.\n // The port is shared, so we serialize via a chain — without it, two\n // concurrent writes would race and could mis-pair their ack messages.\n let chain: Promise<void> = Promise.resolve()\n const request = (msg: WriteContext): Promise<void> => {\n const next = chain.then(() => new Promise<void>((resolve, reject) => {\n if (dead) {\n reject(new Error('osra: connection closed'))\n return\n }\n const settle = (fn: () => void) => {\n pending.delete(reject)\n fn()\n }\n pending.add(reject)\n port.addEventListener('message', ({ data }) => {\n if (!data || typeof data !== 'object' || !('type' in data)) return\n if ((data as { type: string }).type === 'ack') settle(resolve)\n else if ((data as { type: string }).type === 'err') settle(() => reject(new Error((data as { error: string }).error)))\n }, { once: true })\n port.postMessage(msg as Msg)\n }))\n chain = next.catch(() => {})\n return next\n }\n\n return new WritableStream({\n write: (chunk) => request({ type: 'write', chunk: chunk as Capable }),\n close: () => request({ type: 'close' }),\n abort: (reason) => request({ type: 'abort', reason: reason as Capable }),\n }) as T[UnderlyingType]\n}\n\nconst typeCheck = () => {\n const stream = new WritableStream<number>()\n const boxed = box(stream, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: WritableStream<number> = revived\n // @ts-expect-error - wrong stream type\n const wrongType: WritableStream<string> = revived\n // @ts-expect-error - not a WritableStream\n box('not a stream', {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { BoxedMessagePort } from './message-port.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\nimport { onTeardown } from '../utils/teardown.js'\nimport {\n createRevivableChannel,\n revive as reviveMessagePort,\n AnyPort,\n} from './message-port.js'\n\nexport const type = 'abortSignal' as const\n\ntype AbortMessage = {\n type: 'abort'\n reason?: Capable\n}\n\nexport type BoxedAbortSignal =\n & BoxBaseType<typeof type>\n & {\n aborted: boolean\n reason?: Capable\n /** Absent when the signal was already aborted at box time — the reason\n * rides the wrapper and no live channel is needed. */\n port?: BoxedMessagePort<AbortMessage>\n }\n\nexport const isType = (value: unknown): value is AbortSignal =>\n value instanceof AbortSignal\n\n// Pins the revived port for exactly as long as the revived signal is\n// reachable — the port↔listener↔controller subgraph has no other strong\n// root, and a GC of it would silently sever abort propagation.\nconst revivedPortPins = new WeakMap<AbortSignal, AnyPort<AbortMessage>>()\n\nexport const box = <T extends AbortSignal, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedAbortSignal => {\n // Eagerly-aborted reason rides the wrapper, so we must box it here —\n // recursiveBox short-circuits on OSRA_BOX without descending in.\n if (value.aborted) {\n return {\n ...BoxBase,\n type,\n aborted: true,\n reason: recursiveBox(value.reason as Capable, context) as Capable,\n }\n }\n\n const { localPort, boxedRemote } = createRevivableChannel<AbortMessage>(context)\n\n const onSourceAbort = () => {\n localPort.postMessage({ type: 'abort', reason: value.reason as Capable })\n localPort.close()\n removeTeardown()\n }\n // Long-lived signals accumulate one listener per send otherwise —\n // connection death must release them.\n const removeTeardown = onTeardown(context, () => {\n value.removeEventListener('abort', onSourceAbort)\n localPort.close()\n })\n value.addEventListener('abort', onSourceAbort, { once: true })\n\n return {\n ...BoxBase,\n type,\n aborted: false,\n reason: undefined,\n port: boxedRemote,\n }\n}\n\nexport const revive = <T extends BoxedAbortSignal, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): AbortSignal => {\n const controller = new AbortController()\n\n if (value.aborted || value.port === undefined) {\n controller.abort(recursiveRevive(value.reason as Capable, context))\n return controller.signal\n }\n\n const port = reviveMessagePort(value.port, context)\n revivedPortPins.set(controller.signal, port)\n port.start()\n\n port.addEventListener('message', ({ data: message }) => {\n if (message.type === 'abort') {\n controller.abort(recursiveRevive(message.reason as Capable, context))\n revivedPortPins.delete(controller.signal)\n port.close()\n }\n })\n\n return controller.signal\n}\n\nconst typeCheck = () => {\n const boxed = box(new AbortController().signal, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: AbortSignal = revived\n // @ts-expect-error - not an AbortSignal\n const notAbortSignal: string = revived\n // @ts-expect-error - cannot box non-AbortSignal\n box('not an abort signal', {} as RevivableContext)\n}\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { box as boxHeaders, revive as reviveHeaders } from './headers.js'\nimport { box as boxReadableStream, revive as reviveReadableStream } from './readable-stream.js'\n\nexport const type = 'response' as const\n\nexport const isType = (value: unknown): value is Response =>\n value instanceof Response\n\nexport const box = <T extends Response, T2 extends RevivableContext>(\n value: T,\n context: T2\n) => ({\n ...BoxBase,\n type,\n status: value.status,\n statusText: value.statusText,\n headers: boxHeaders(value.headers, context),\n body: value.body ? boxReadableStream(value.body, context) : null,\n url: value.url,\n redirected: value.redirected\n})\n\nexport const revive = <T extends ReturnType<typeof box>, T2 extends RevivableContext>(\n value: T,\n context: T2\n): Response => {\n // Opaque/error responses report status 0, which the constructor rejects.\n if (value.status === 0) return Response.error()\n\n const headers = reviveHeaders(value.headers, context)\n const body = value.body ? reviveReadableStream(value.body, context) : null\n\n const response = new Response(body, {\n status: value.status,\n statusText: value.statusText,\n headers\n })\n // url/redirected are read-only getters fed by internal state the\n // constructor can't set — shadow them so the round trip is faithful.\n if (value.url) Object.defineProperty(response, 'url', { value: value.url, configurable: true })\n if (value.redirected) Object.defineProperty(response, 'redirected', { value: true, configurable: true })\n return response\n}\n\nconst typeCheck = () => {\n const boxed = box(new Response('body', { status: 200 }), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Response = revived\n // @ts-expect-error - not a Response\n const notResponse: string = revived\n // @ts-expect-error - cannot box non-Response\n box('not a response', {} as RevivableContext)\n}\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { box as boxHeaders, revive as reviveHeaders } from './headers.js'\nimport { box as boxReadableStream, revive as reviveReadableStream } from './readable-stream.js'\nimport { box as boxAbortSignal, revive as reviveAbortSignal } from './abort-signal.js'\n\nexport const type = 'request' as const\n\nexport const isType = (value: unknown): value is Request =>\n value instanceof Request\n\nexport const box = <T extends Request, T2 extends RevivableContext>(\n value: T,\n context: T2\n) => ({\n ...BoxBase,\n type,\n method: value.method,\n url: value.url,\n headers: boxHeaders(value.headers, context),\n body: value.body ? boxReadableStream(value.body, context) : null,\n credentials: value.credentials,\n cache: value.cache,\n mode: value.mode,\n redirect: value.redirect,\n referrer: value.referrer,\n referrerPolicy: value.referrerPolicy,\n integrity: value.integrity,\n keepalive: value.keepalive,\n signal: boxAbortSignal(value.signal, context),\n})\n\nexport const revive = <T extends ReturnType<typeof box>, T2 extends RevivableContext>(\n value: T,\n context: T2\n): Request => {\n const headers = reviveHeaders(value.headers, context)\n\n // Firefox normalizes `body: null` in the constructor to a Request whose\n // `.body` getter returns `undefined` instead of `null`. Only pass `body`\n // when there's an actual stream so a bodyless source round-trips to a\n // bodyless Request on every browser.\n const init: RequestInit & { duplex?: 'half' } = {\n method: value.method,\n headers,\n credentials: value.credentials,\n cache: value.cache,\n redirect: value.redirect,\n referrer: value.referrer,\n referrerPolicy: value.referrerPolicy,\n integrity: value.integrity,\n keepalive: value.keepalive,\n signal: reviveAbortSignal(value.signal, context),\n }\n // 'navigate' is not constructible via RequestInit.\n if (value.mode !== 'navigate') init.mode = value.mode\n if (value.body) {\n init.body = reviveReadableStream(value.body, context)\n init.duplex = 'half'\n }\n\n return new Request(value.url, init)\n}\n\nconst typeCheck = () => {\n const boxed = box(new Request('https://example.com'), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Request = revived\n // @ts-expect-error - not a Request\n const notRequest: string = revived\n // @ts-expect-error - cannot box non-Request\n box('not a request', {} as RevivableContext)\n}\n","import type { Capable, Uuid } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { UnderlyingType } from '../utils/type.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\nimport { onTeardown } from '../utils/teardown.js'\n\nexport const type = 'identity' as const\n\nexport type Messages = {\n type: 'identity-dispose'\n remoteUuid: Uuid\n id: string\n}\n\nexport declare const Messages: Messages\n\nconst IDENTITY_MARKER: unique symbol = Symbol.for('osra.identity')\n\ntype IdentityWrapper<T = unknown> = {\n readonly [IDENTITY_MARKER]: true\n readonly value: T\n}\n\nexport type BoxedIdentity<T extends Capable = Capable> = BoxBaseType<typeof type> & {\n id: string\n inner?: Capable\n [UnderlyingType]: T\n}\n\nconst isObjectOrFunction = (value: unknown): value is object =>\n value !== null && (typeof value === 'object' || typeof value === 'function')\n\n/** Anything we can hand to WeakMap/WeakRef/FinalizationRegistry. Excludes\n * registered symbols (Symbol.for) — those throw at runtime. */\nconst isWeakKeyable = (value: unknown): value is WeakKey => {\n if (value === null) return false\n const t = typeof value\n if (t === 'object' || t === 'function') return true\n if (t === 'symbol') return Symbol.keyFor(value as symbol) === undefined\n return false\n}\n\nconst isIdentityWrapper = (value: unknown): value is IdentityWrapper =>\n isObjectOrFunction(value) && IDENTITY_MARKER in value && value[IDENTITY_MARKER] === true\n\nconst wrapperMemo = new WeakMap<object, IdentityWrapper>()\n\nconst wrap = (value: object): IdentityWrapper => {\n if (isIdentityWrapper(value)) return value\n const cached = wrapperMemo.get(value)\n if (cached) return cached\n const wrapper: IdentityWrapper = { [IDENTITY_MARKER]: true, value }\n wrapperMemo.set(value, wrapper)\n return wrapper\n}\n\n/** Wrap a value so osra preserves reference identity across the RPC\n * boundary. Idempotent; primitives pass through unchanged. Lies at the\n * type level — runtime value is an IdentityWrapper<T> typed as T. */\nexport const identity = <T>(value: T): T =>\n (isObjectOrFunction(value) ? wrap(value) : value) as T\n\ntype IdentityState = {\n readonly sendIds: WeakMap<WeakKey, string>\n /** id → ref to the value we sent, so a round-trip resolves to the\n * original reference instead of building a fresh proxy. */\n readonly idToSent: Map<string, WeakRef<WeakKey>>\n readonly sendRegistry: FinalizationRegistry<string>\n readonly receiveCache: Map<string, unknown>\n /** Revived value → id, so user code passing a revived value back to\n * its origin replays the peer's id and short-circuits to the real ref. */\n readonly revivedToId: WeakMap<WeakKey, string>\n listenerInstalled: boolean\n}\n\nconst connectionStates = new WeakMap<RevivableContext, IdentityState>()\n\nconst getOrCreateState = (context: RevivableContext): IdentityState => {\n const existing = connectionStates.get(context)\n if (existing) return existing\n const sendIds = new WeakMap<WeakKey, string>()\n const idToSent = new Map<string, WeakRef<WeakKey>>()\n const receiveCache = new Map<string, unknown>()\n const revivedToId = new WeakMap<WeakKey, string>()\n const sendRegistry = new FinalizationRegistry<string>((id) => {\n idToSent.delete(id)\n try {\n context.sendMessage({ type: 'identity-dispose', remoteUuid: context.remoteUuid, id })\n } catch { /* connection already closed */ }\n })\n const state: IdentityState = {\n sendIds, idToSent, sendRegistry, receiveCache, revivedToId,\n listenerInstalled: false,\n }\n connectionStates.set(context, state)\n installReceiveListener(context, state)\n onTeardown(context, () => {\n state.receiveCache.clear()\n state.idToSent.clear()\n })\n return state\n}\n\nconst installReceiveListener = (context: RevivableContext, state: IdentityState) => {\n if (state.listenerInstalled) return\n state.listenerInstalled = true\n context.eventTarget.addEventListener('message', ({ detail }) => {\n if (detail?.type !== 'identity-dispose') return\n const revived = state.receiveCache.get(detail.id)\n state.receiveCache.delete(detail.id)\n if (revived !== undefined && isWeakKeyable(revived)) state.revivedToId.delete(revived)\n })\n}\n\nexport const isType = (value: unknown): value is IdentityWrapper =>\n isIdentityWrapper(value)\n\n/** Look up or assign the id for a referenceable value. Returns whether\n * the id is already-known (resend or round-trip) so the caller can skip\n * shipping the inner payload. */\nconst registerForReference = (\n value: WeakKey,\n state: IdentityState,\n): { id: string, isExisting: boolean } => {\n const existingId = state.sendIds.get(value)\n if (existingId !== undefined) return { id: existingId, isExisting: true }\n const receivedId = state.revivedToId.get(value)\n if (receivedId !== undefined) return { id: receivedId, isExisting: true }\n const id = globalThis.crypto.randomUUID()\n state.sendIds.set(value, id)\n state.idToSent.set(id, new WeakRef(value))\n state.sendRegistry.register(value, id)\n return { id, isExisting: false }\n}\n\nexport const box = <T extends Capable, TContext extends RevivableContext>(\n wrapper: IdentityWrapper<T>,\n context: TContext,\n): BoxedIdentity<T> => {\n const state = getOrCreateState(context)\n const inner = wrapper.value\n const innerBox = recursiveBox(inner, context)\n if (!isWeakKeyable(inner)) {\n // Inner can't anchor a WeakMap key — emit fresh id+inner each time, no dedup.\n return { ...BoxBase, type, id: globalThis.crypto.randomUUID(), inner: innerBox } as BoxedIdentity<T>\n }\n const { id, isExisting } = registerForReference(inner, state)\n if (isExisting) return { ...BoxBase, type, id } as BoxedIdentity<T>\n return { ...BoxBase, type, id, inner: innerBox } as BoxedIdentity<T>\n}\n\n/** Identity-box a referenceable value with a caller-supplied inner box,\n * bypassing the recursive-box step. Used by revivables (symbol with\n * description=undefined) where recursing back through their own box\n * would loop into this module again. */\nexport const boxByReference = <T extends WeakKey, TContext extends RevivableContext>(\n value: T,\n innerBox: Capable,\n context: TContext,\n): BoxedIdentity => {\n const state = getOrCreateState(context)\n const { id, isExisting } = registerForReference(value, state)\n if (isExisting) return { ...BoxBase, type, id } as BoxedIdentity\n return { ...BoxBase, type, id, inner: innerBox } as BoxedIdentity\n}\n\nexport const revive = <T extends BoxedIdentity, TContext extends RevivableContext>(\n value: T,\n context: TContext,\n): T[UnderlyingType] => {\n const state = getOrCreateState(context)\n const cached = state.receiveCache.get(value.id)\n if (cached !== undefined) return cached as T[UnderlyingType]\n const originated = state.idToSent.get(value.id)?.deref()\n if (originated !== undefined) return originated as T[UnderlyingType]\n if (!('inner' in value) || value.inner === undefined) {\n throw new Error(`osra identity: received id=${value.id} with no inner payload and no cached value`)\n }\n const revived = recursiveRevive(value.inner, context)\n state.receiveCache.set(value.id, revived)\n if (isWeakKeyable(revived)) state.revivedToId.set(revived, value.id)\n return revived as T[UnderlyingType]\n}\n\nconst typeCheck = () => {\n const fn = () => 42\n const wrapper = { [IDENTITY_MARKER]: true, value: fn } as IdentityWrapper<typeof fn>\n const boxed = box(wrapper, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: typeof fn = revived\n // @ts-expect-error - revived is the original function type, not string\n const notExpected: string = revived\n // @ts-expect-error - cannot box a non-Capable wrapper (WeakMap not assignable)\n box({ [IDENTITY_MARKER]: true, value: new WeakMap() } as IdentityWrapper<WeakMap<object, string>>, {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, UnderlyingType, BoxBase as BoxBaseType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\n\nexport const type = 'map' as const\n\nexport type BoxedMap<T extends Map<Capable, Capable> = Map<Capable, Capable>> =\n & BoxBaseType<typeof type>\n & { entries: Array<[Capable, Capable]> }\n & { [UnderlyingType]: T }\n\n// `Map<unknown, unknown>` (rather than `Map<Capable, Capable>`) breaks the\n// Capable ↔ defaultRevivableModules ↔ this module type cycle. box() still\n// narrows to `Map<Capable, Capable>` so misuse is caught there.\nexport const isType = (value: unknown): value is Map<unknown, unknown> =>\n value instanceof Map\n\nexport const box = <T extends Map<Capable, Capable>, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedMap<T> => ({\n ...BoxBase,\n type,\n entries: Array.from(value, ([k, v]): [Capable, Capable] =>\n [recursiveBox(k, context) as Capable, recursiveBox(v, context) as Capable]),\n}) as BoxedMap<T>\n\nexport const revive = <T extends BoxedMap, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): T[UnderlyingType] =>\n new Map(value.entries.map(([k, v]) => [\n recursiveRevive(k, context),\n recursiveRevive(v, context),\n ])) as T[UnderlyingType]\n\nconst typeCheck = () => {\n const m = new Map<string, number>([['a', 1]])\n const boxed = box(m, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Map<string, number> = revived\n // @ts-expect-error - wrong value type\n const wrongValue: Map<string, string> = revived\n // @ts-expect-error - cannot box non-Map\n box('not a map', {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, UnderlyingType, BoxBase as BoxBaseType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\n\nexport const type = 'set' as const\n\nexport type BoxedSet<T extends Set<Capable> = Set<Capable>> =\n & BoxBaseType<typeof type>\n & { values: Array<Capable> }\n & { [UnderlyingType]: T }\n\n// `Set<unknown>` breaks the Capable ↔ defaultRevivableModules ↔ this module\n// type cycle; box() narrows to `Set<Capable>` so misuse is caught there.\nexport const isType = (value: unknown): value is Set<unknown> =>\n value instanceof Set\n\nexport const box = <T extends Set<Capable>, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedSet<T> => ({\n ...BoxBase,\n type,\n values: Array.from(value, v => recursiveBox(v, context) as Capable),\n}) as BoxedSet<T>\n\nexport const revive = <T extends BoxedSet, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): T[UnderlyingType] =>\n new Set(value.values.map(v => recursiveRevive(v, context))) as T[UnderlyingType]\n\nconst typeCheck = () => {\n const s = new Set<number>([1, 2, 3])\n const boxed = box(s, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Set<number> = revived\n // @ts-expect-error - wrong value type\n const wrongValue: Set<string> = revived\n // @ts-expect-error - cannot box non-Set\n box('not a set', {} as RevivableContext)\n}\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\n\nexport const type = 'bigint' as const\n\nexport const isType = (value: unknown): value is bigint =>\n typeof value === 'bigint'\n\nexport const box = <T extends bigint, T2 extends RevivableContext>(\n value: T,\n _context: T2,\n) => ({\n ...BoxBase,\n type,\n value: value.toString(),\n})\n\nexport const revive = <T extends ReturnType<typeof box>>(\n value: T,\n _context: RevivableContext,\n) => BigInt(value.value)\n\nconst typeCheck = () => {\n const boxed = box(123n, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: bigint = revived\n // @ts-expect-error - not a string\n const notString: string = revived\n // @ts-expect-error - cannot box non-bigint\n box('not a bigint', {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { recursiveBox, recursiveRevive } from './index.js'\n\nexport const type = 'event' as const\n\n/** Boxes Event/CustomEvent only. Subclass-specific fields (MessageEvent.data,\n * ErrorEvent.error, ProgressEvent.loaded, etc.) are dropped on the wire. */\nexport type BoxedEvent =\n & BoxBaseType<typeof type>\n & { eventType: string, bubbles: boolean, cancelable: boolean, composed: boolean, detail?: Capable }\n\nexport const isType = (value: unknown): value is Event =>\n value instanceof Event\n\nexport const box = <T extends Event, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedEvent => ({\n ...BoxBase,\n type,\n eventType: value.type,\n bubbles: value.bubbles,\n cancelable: value.cancelable,\n composed: value.composed,\n ...(value instanceof CustomEvent ? { detail: recursiveBox(value.detail as Capable, context) as Capable } : {}),\n})\n\nexport const revive = <T extends BoxedEvent, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): Event => {\n const init = { bubbles: value.bubbles, cancelable: value.cancelable, composed: value.composed }\n return 'detail' in value\n ? new CustomEvent(value.eventType, { ...init, detail: recursiveRevive(value.detail as Capable, context) })\n : new Event(value.eventType, init)\n}\n\nconst typeCheck = () => {\n const boxed = box(new Event('foo'), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Event = revived\n // @ts-expect-error - not an Event\n const notEvent: string = revived\n // @ts-expect-error - cannot box non-Event\n box('not an event', {} as RevivableContext)\n}\n","import { BoxBase, type RevivableContext } from './utils.js'\nimport { identity } from './identity.js'\nimport { box as boxFunction, revive as reviveFunction } from './function.js'\nimport { trackGc } from '../utils/gc-tracker.js'\n\nexport const type = 'eventTarget' as const\n\ntype ListenerOpts = boolean | { capture?: boolean, once?: boolean, passive?: boolean, signal?: AbortSignal }\n\nexport const isType = (value: unknown): value is EventTarget => value instanceof EventTarget\n\nexport const box = <T extends EventTarget, T2 extends RevivableContext>(value: T, context: T2) => {\n // Track what this box added so the façade's GC cleanup can drop everything\n // through one zero-argument RPC — holding no reference to user listeners.\n const added: { eventType: string, listener: EventListener, capture: boolean }[] = []\n const captureOf = (options?: ListenerOpts) =>\n typeof options === 'boolean' ? options : !!options?.capture\n return {\n ...BoxBase,\n type,\n addListener: boxFunction(\n (eventType: string, listener: EventListener, options?: ListenerOpts) => {\n added.push({ eventType, listener, capture: captureOf(options) })\n value.addEventListener(eventType, listener, options)\n },\n context,\n ),\n removeListener: boxFunction(\n (eventType: string, listener: EventListener, options?: ListenerOpts) => {\n const capture = captureOf(options)\n const index = added.findIndex(r =>\n r.eventType === eventType && r.listener === listener && r.capture === capture)\n if (index !== -1) added.splice(index, 1)\n value.removeEventListener(eventType, listener, options)\n },\n context,\n ),\n removeAllListeners: boxFunction(\n () => {\n for (const { eventType, listener, capture } of added.splice(0)) {\n value.removeEventListener(eventType, listener, { capture })\n }\n },\n context,\n ),\n }\n}\n\nexport type BoxedEventTarget = ReturnType<typeof box>\n\n// Stable EventListener per EventListenerObject so identity() yields the\n// same id on add and remove.\nconst objectWrappers = new WeakMap<EventListenerObject, EventListener>()\nconst toListener = (listerObject: EventListenerOrEventListenerObject): EventListener => {\n if (typeof listerObject === 'function') return listerObject\n let listener = objectWrappers.get(listerObject)\n if (!listener) objectWrappers.set(listerObject, listener = (e) => listerObject.handleEvent(e))\n return listener\n}\n\ntype Reg = { eventType: string, listener: EventListener, capture: boolean, wire: EventListener }\n\nconst findReg = (regs: Reg[], eventType: string, listener: EventListener, capture: boolean): Reg | undefined =>\n regs.find(r => r.eventType === eventType && r.listener === listener && r.capture === capture)\n\nexport const revive = <T extends BoxedEventTarget, T2 extends RevivableContext>(value: T, context: T2) => {\n const addRpc = reviveFunction(value.addListener, context)\n const removeRpc = reviveFunction(value.removeListener, context)\n const removeAllRpc = reviveFunction(value.removeAllListeners, context)\n // Façade only — events never dispatch through it. Source-side EventTarget\n // owns all semantics; we just track regs for cleanup.\n const target = new EventTarget()\n const regs: Reg[] = []\n\n const prune = (reg: Reg) => {\n const index = regs.indexOf(reg)\n if (index !== -1) regs.splice(index, 1)\n }\n\n Object.defineProperty(target, 'addEventListener', {\n value: (eventType: string, listener: EventListenerOrEventListenerObject | null, options?: ListenerOpts) => {\n if (listener === null) return\n const fn = toListener(listener)\n const capture = typeof options === 'boolean' ? options : !!options?.capture\n if (findReg(regs, eventType, fn, capture)) return\n const once = typeof options === 'object' && !!options?.once\n // The source side auto-removes once/aborted listeners — prune the\n // local reg in step so the same listener can be re-added later.\n const wire: EventListener = once\n ? (event) => {\n prune(reg)\n return fn(event)\n }\n : fn\n const reg: Reg = { eventType, listener: fn, capture, wire }\n regs.push(reg)\n const signal = typeof options === 'object' ? options?.signal : undefined\n signal?.addEventListener('abort', () => prune(reg), { once: true })\n addRpc(eventType, identity(wire), options).catch(() => {})\n },\n })\n\n Object.defineProperty(target, 'removeEventListener', {\n value: (eventType: string, listener: EventListenerOrEventListenerObject | null, options?: ListenerOpts) => {\n if (listener === null) return\n const fn = toListener(listener)\n const capture = typeof options === 'boolean' ? options : !!options?.capture\n const reg = findReg(regs, eventType, fn, capture)\n if (!reg) return\n prune(reg)\n removeRpc(eventType, identity(reg.wire), { capture }).catch(() => {})\n },\n })\n\n // Cleanup must NOT close over `target`, `regs`, or any user listener —\n // the FR strong-holds it, and a listener closing over the façade would\n // otherwise pin the whole subgraph forever. removeAllRpc only references\n // its own RPC port.\n trackGc(target, () => {\n removeAllRpc().catch(() => {})\n })\n\n return target\n}\n\nconst typeCheck = () => {\n const r = revive(box(new EventTarget(), {} as RevivableContext), {} as RevivableContext)\n const expected: EventTarget = r\n // @ts-expect-error - not a string\n const notString: string = r\n // @ts-expect-error - cannot box non-EventTarget\n box('not an event target', {} as RevivableContext)\n}\n","import type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\nimport type { UnderlyingType } from '../utils/type.js'\nimport type { BoxedPromise } from './promise.js'\n\nimport { BoxBase } from './utils.js'\nimport { box as boxPromise, revive as revivePromise } from './promise.js'\n\nexport const type = 'blob' as const\n\nexport type BoxedBlob<T extends Blob = Blob> =\n & BoxBaseType<typeof type>\n & { mimeType: string }\n & { buffer: BoxedPromise<ArrayBuffer> }\n & { fileName?: string, lastModified?: number }\n & { [UnderlyingType]: Promise<T> }\n\n// File extends Blob and is handled here too — encoding `name` + `lastModified`\n// when present so the receiver reconstructs a File rather than dropping to a\n// plain Blob. Avoids a runtime/type mismatch where File would type-check as\n// Capable but silently coerce.\nexport const isType = (value: unknown): value is Blob =>\n value instanceof Blob\n\nconst isFile = (value: Blob): value is File =>\n typeof File !== 'undefined' && value instanceof File\n\nexport const box = <T extends Blob, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedBlob<T> => ({\n ...BoxBase,\n type,\n mimeType: value.type,\n buffer: boxPromise(value.arrayBuffer(), context),\n ...(isFile(value)\n ? { fileName: value.name, lastModified: value.lastModified }\n : {}),\n}) as unknown as BoxedBlob<T>\n\n// Blob bytes are fetched async (`blob.arrayBuffer()`), so revive can't\n// hand back a Blob synchronously — receivers `await` to get the Blob.\nexport const revive = <T extends BoxedBlob, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): T[UnderlyingType] =>\n revivePromise(value.buffer, context)\n .then(buffer =>\n value.fileName !== undefined && typeof File !== 'undefined'\n ? new File([buffer], value.fileName, {\n type: value.mimeType,\n lastModified: value.lastModified,\n })\n : new Blob([buffer], { type: value.mimeType })) as T[UnderlyingType]\n\nconst typeCheck = () => {\n const boxed = box(new Blob(['x'], { type: 'text/plain' }), {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: Promise<Blob> = revived\n // @ts-expect-error - revived is Promise<Blob>, not a sync Blob\n const notBlob: Blob = revived\n // @ts-expect-error - cannot box non-Blob\n box('not a blob', {} as RevivableContext)\n}\n","import type { RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { boxByReference } from './identity.js'\n\nexport const type = 'symbol' as const\n\nexport const isType = (value: unknown): value is symbol =>\n typeof value === 'symbol'\n\nexport const box = <T extends symbol, T2 extends RevivableContext>(\n value: T,\n context: T2,\n) => {\n // Registry symbols carry global identity through their key.\n const registryKey = Symbol.keyFor(value)\n if (registryKey !== undefined) return { ...BoxBase, type, registryKey }\n // Everything else routes through identity so the same symbol revives to\n // the same symbol on every send (and round-trips to the original).\n return boxByReference(value, { ...BoxBase, type, description: value.description }, context)\n}\n\nexport const revive = <\n T extends { registryKey: string } | { description: string | undefined },\n T2 extends RevivableContext,\n>(\n value: T,\n _context: T2,\n): symbol =>\n 'registryKey' in value\n ? Symbol.for(value.registryKey)\n : Symbol(value.description)\n\nconst typeCheck = () => {\n const boxed = box(Symbol('foo'), {} as RevivableContext)\n const revivedDescribed = revive({ description: 'foo' }, {} as RevivableContext)\n const expected: symbol = revivedDescribed\n const revivedRegistered = revive({ registryKey: 'foo' }, {} as RevivableContext)\n const expectedRegistered: symbol = revivedRegistered\n // @ts-expect-error - not a string\n const notString: string = revivedDescribed\n // @ts-expect-error - cannot box non-symbol\n box('not a symbol', {} as RevivableContext)\n}\n","import type { Capable } from '../types.js'\nimport type { RevivableContext, BoxBase as BoxBaseType } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { box as boxFunction, revive as reviveFunction, BoxedFunction } from './function.js'\n\nexport const type = 'asyncIterator' as const\n\ntype AnyAsyncIterable = { [Symbol.asyncIterator]: () => AsyncIterator<unknown> }\n\nexport type BoxedAsyncIterator =\n & BoxBaseType<typeof type>\n & {\n next: BoxedFunction\n return: BoxedFunction\n throw: BoxedFunction\n }\n\nexport const isType = (value: unknown): value is AnyAsyncIterable => {\n if (!value || typeof value !== 'object') return false\n // ReadableStream is async-iterable on some platforms but has its own\n // revivable — belt and braces for custom module orders.\n if (typeof ReadableStream !== 'undefined' && value instanceof ReadableStream) return false\n return typeof (value as Record<symbol, unknown>)[Symbol.asyncIterator] === 'function'\n}\n\nexport const box = <T extends AnyAsyncIterable, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): BoxedAsyncIterator => {\n const iterator = value[Symbol.asyncIterator]()\n return {\n ...BoxBase,\n type,\n next: boxFunction(((arg?: Capable) => iterator.next(arg)) as never, context) as unknown as BoxedFunction,\n return: boxFunction(((arg?: Capable) =>\n iterator.return?.(arg) ?? Promise.resolve({ done: true as const, value: arg })) as never, context) as unknown as BoxedFunction,\n throw: boxFunction(((error?: Capable) =>\n iterator.throw?.(error) ?? Promise.reject(error)) as never, context) as unknown as BoxedFunction,\n }\n}\n\nexport const revive = <T extends BoxedAsyncIterator, T2 extends RevivableContext>(\n value: T,\n context: T2,\n): AsyncIterableIterator<Capable> => {\n const next = reviveFunction(value.next, context)\n const returnRpc = reviveFunction(value.return, context)\n const throwRpc = reviveFunction(value.throw, context)\n const iterator: AsyncIterableIterator<Capable> = {\n next: (...args: [] | [unknown]) =>\n next(...args as Capable[]) as Promise<IteratorResult<Capable>>,\n return: (arg?: unknown) =>\n returnRpc(arg as Capable) as Promise<IteratorResult<Capable>>,\n throw: (error?: unknown) =>\n throwRpc(error as Capable) as Promise<IteratorResult<Capable>>,\n [Symbol.asyncIterator]: () => iterator,\n }\n return iterator\n}\n\nconst typeCheck = () => {\n const gen = (async function* () { yield 1 })()\n const boxed = box(gen, {} as RevivableContext)\n const revived = revive(boxed, {} as RevivableContext)\n const expected: AsyncIterableIterator<Capable> = revived\n // @ts-expect-error - not a string\n const notString: string = revived\n // @ts-expect-error - cannot box a non-async-iterable\n box({ next: () => {} }, {} as RevivableContext)\n}\n","import type { BoxBase as BoxBaseType, RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { instanceOfAny } from '../utils/type-guards.js'\n\ntype AnyCtor = abstract new (...args: any[]) => unknown\n\n// -------------------------------------------------------------------------\n// clonable — pass-through fast path for HTML structured-clone types not\n// owned by another revivable. Short-circuits findBoxModule so unclonable's\n// structuredClone probe never fires on a known-safe value.\n// -------------------------------------------------------------------------\n\nconst TYPED_CLONABLE_CTORS = [\n globalThis.File,\n globalThis.FileList,\n globalThis.RegExp,\n globalThis.DataView,\n globalThis.ImageData,\n globalThis.FormData,\n globalThis.DOMException,\n globalThis.DOMMatrix,\n globalThis.DOMMatrixReadOnly,\n globalThis.DOMPoint,\n globalThis.DOMPointReadOnly,\n globalThis.DOMQuad,\n globalThis.DOMRect,\n globalThis.DOMRectReadOnly,\n globalThis.CryptoKey,\n globalThis.FileSystemHandle,\n globalThis.FileSystemFileHandle,\n globalThis.FileSystemDirectoryHandle,\n globalThis.RTCCertificate,\n] as const\n\nconst EXPERIMENTAL_CLONABLE_CTORS = [\n (globalThis as { CropTarget?: AnyCtor }).CropTarget,\n (globalThis as { EncodedAudioChunk?: AnyCtor }).EncodedAudioChunk,\n (globalThis as { EncodedVideoChunk?: AnyCtor }).EncodedVideoChunk,\n (globalThis as { FencedFrameConfig?: AnyCtor }).FencedFrameConfig,\n (globalThis as { GPUCompilationInfo?: AnyCtor }).GPUCompilationInfo,\n (globalThis as { GPUCompilationMessage?: AnyCtor }).GPUCompilationMessage,\n (globalThis as { GPUPipelineError?: AnyCtor }).GPUPipelineError,\n (globalThis as { RTCEncodedAudioFrame?: AnyCtor }).RTCEncodedAudioFrame,\n (globalThis as { RTCEncodedVideoFrame?: AnyCtor }).RTCEncodedVideoFrame,\n (globalThis as { WebTransportError?: AnyCtor }).WebTransportError,\n] as const\n\nexport type Clonable = InstanceType<typeof TYPED_CLONABLE_CTORS[number]>\nexport type BoxedClonable = BoxBaseType<'clonable'>\n\n// `capableOnly: true` tells ExtractType to elide this module from the\n// Capable union on JSON transports — TS can't narrow `isType<Ctx>` via\n// generic inference, so we use a marker flag.\nconst isClonable = (value: unknown): value is Clonable =>\n instanceOfAny(value, TYPED_CLONABLE_CTORS) || instanceOfAny(value, EXPERIMENTAL_CLONABLE_CTORS)\n\nexport const clonable = {\n type: 'clonable',\n capableOnly: true,\n isType: isClonable,\n // Pass-through; structured-clone handles these on the wire. `revive` is\n // never reached — `box` returns the raw value so isRevivableBox is false.\n box: (value: Clonable, _context: RevivableContext<any>): Clonable => value,\n revive: (value: BoxedClonable, _context: RevivableContext<any>): Clonable => value as unknown as Clonable,\n} as const\n\n// -------------------------------------------------------------------------\n// transferable — pass-through fast path for transfer-only host objects.\n// getTransferableObjects pulls them out of the envelope at send time.\n// -------------------------------------------------------------------------\n\nconst TYPED_TRANSFERABLE_CTORS = [\n globalThis.ImageBitmap,\n globalThis.OffscreenCanvas,\n globalThis.WritableStream,\n globalThis.TransformStream,\n globalThis.MediaStreamTrack,\n globalThis.RTCDataChannel,\n] as const\n\nconst EXPERIMENTAL_TRANSFERABLE_CTORS = [\n (globalThis as { AudioData?: AnyCtor }).AudioData,\n (globalThis as { VideoFrame?: AnyCtor }).VideoFrame,\n (globalThis as { MediaSourceHandle?: AnyCtor }).MediaSourceHandle,\n (globalThis as { MIDIAccess?: AnyCtor }).MIDIAccess,\n (globalThis as { WebTransportReceiveStream?: AnyCtor }).WebTransportReceiveStream,\n (globalThis as { WebTransportSendStream?: AnyCtor }).WebTransportSendStream,\n] as const\n\nexport type Transferable = InstanceType<typeof TYPED_TRANSFERABLE_CTORS[number]>\nexport type BoxedTransferable = BoxBaseType<'transferable'>\n\nconst isTransferable = (value: unknown): value is Transferable =>\n instanceOfAny(value, TYPED_TRANSFERABLE_CTORS) || instanceOfAny(value, EXPERIMENTAL_TRANSFERABLE_CTORS)\n\nexport const transferable = {\n type: 'transferable',\n capableOnly: true,\n isType: isTransferable,\n box: (value: Transferable, _context: RevivableContext<any>): Transferable => value,\n revive: (value: BoxedTransferable, _context: RevivableContext<any>): Transferable => value as unknown as Transferable,\n} as const\n\n// -------------------------------------------------------------------------\n// unclonable — catch-all that probes via structuredClone and coerces\n// unclonables to `{}` so the wire never blows up on exotic host objects.\n// -------------------------------------------------------------------------\n\nconst isPlainObject = (value: unknown): boolean => {\n if (value === null || typeof value !== 'object') return false\n const proto = Object.getPrototypeOf(value)\n return proto === Object.prototype || proto === null\n}\n\nconst isUnclonable = (value: unknown): boolean => {\n if (value === null) return false\n const t = typeof value\n if (t !== 'object') return false\n if (Array.isArray(value)) return false\n if (isPlainObject(value)) return false\n try {\n structuredClone(value)\n return false\n } catch {\n return true\n }\n}\n\nexport type BoxedUnclonable = BoxBaseType<'unclonable'>\n\n// Type-level lie: `value is never` so this module doesn't widen Capable.\n// Coercion to `{}` is a runtime rescue for values we shouldn't see.\nconst isUnclonableTyped = isUnclonable as (value: unknown) => value is never\n\nexport const unclonable = {\n type: 'unclonable',\n isType: isUnclonableTyped,\n box: (_value: never, _context: RevivableContext<any>): BoxedUnclonable => ({ ...BoxBase, type: 'unclonable' }),\n revive: (_value: BoxedUnclonable, _context: RevivableContext<any>): Record<string, never> => ({}),\n} as const\n","import type { BoxBase as BoxBaseType, RevivableContext } from './utils.js'\n\nimport { BoxBase } from './utils.js'\nimport { isJsonOnlyTransport } from '../utils/type-guards.js'\n\n// JSON.stringify silently corrupts these: NaN/±Infinity become null,\n// undefined vanishes from objects and becomes null in arrays. On clone\n// transports both pass through untouched (box returns the raw value, so\n// isRevivableBox is false and revive is never reached) — the wire shape\n// only exists on JSON transports.\n\nexport type BoxedNonFiniteNumber = BoxBaseType<'nonFiniteNumber'> & { value: 'NaN' | 'Infinity' | '-Infinity' }\n\nexport const nonFiniteNumber = {\n type: 'nonFiniteNumber',\n isType: (value: unknown): value is number =>\n typeof value === 'number' && !Number.isFinite(value),\n box: (value: number, context: RevivableContext<any>): BoxedNonFiniteNumber | number =>\n isJsonOnlyTransport(context.transport)\n ? { ...BoxBase, type: 'nonFiniteNumber', value: String(value) as BoxedNonFiniteNumber['value'] }\n : value,\n revive: (value: BoxedNonFiniteNumber, _context: RevivableContext<any>): number =>\n Number(value.value),\n} as const\n\nexport type BoxedUndefined = BoxBaseType<'undefined'>\n\nexport const undefinedValue = {\n type: 'undefined',\n isType: (value: unknown): value is undefined =>\n value === undefined,\n box: (value: undefined, context: RevivableContext<any>): BoxedUndefined | undefined =>\n isJsonOnlyTransport(context.transport)\n ? { ...BoxBase, type: 'undefined' }\n : value,\n revive: (_value: BoxedUndefined, _context: RevivableContext<any>): undefined =>\n undefined,\n} as const\n","import type { BoxBase, RevivableContext } from './utils.js'\nimport type { DeepReplaceWithBox, DeepReplaceWithRevive } from '../utils/replace.js'\nimport type { MessageFields, Capable } from '../types.js'\n\nimport { isRevivableBox } from './utils.js'\nimport * as arrayBuffer from './array-buffer.js'\nimport * as date from './date.js'\nimport * as headers from './headers.js'\nimport * as error from './error.js'\nimport * as typedArray from './typed-array.js'\nimport * as promise from './promise.js'\nimport * as func from './function.js'\nimport * as messagePort from './message-port.js'\nimport * as readableStream from './readable-stream.js'\nimport * as writableStream from './writable-stream.js'\nimport * as abortSignal from './abort-signal.js'\nimport * as response from './response.js'\nimport * as request from './request.js'\nimport * as identity from './identity.js'\nimport * as transfer from './transfer.js'\nimport * as map from './map.js'\nimport * as set from './set.js'\nimport * as bigInt from './bigint.js'\nimport * as event from './event.js'\nimport * as eventTarget from './event-target.js'\nimport * as blob from './blob.js'\nimport * as symbol from './symbol.js'\nimport * as asyncIterator from './async-iterator.js'\nimport { clonable, transferable, unclonable } from './fallbacks.js'\nimport { nonFiniteNumber, undefinedValue } from './json-primitives.js'\n\nexport { identity } from './identity.js'\nexport { transfer } from './transfer.js'\n\nexport * from './utils.js'\n\n// `any` on box/revive/init: each module's concrete box has a narrower input\n// than the shared interface can express, and TS treats readonly function\n// types contravariantly. The bivariance escape hatch lets modules assign.\nexport type RevivableModule<\n T extends string = string,\n T2 = any,\n T3 extends BoxBase<T> = any,\n T4 extends MessageFields = MessageFields,\n> = {\n readonly type: T\n readonly isType: (value: unknown) => value is T2\n readonly box: ((value: T2, context: RevivableContext<any>) => T3) | ((...args: any[]) => any)\n readonly revive: (value: T3, context: RevivableContext<any>) => T2\n readonly init?: (context: RevivableContext<any>) => void\n readonly Messages?: T4\n}\n\nexport const defaultRevivableModules = [\n transfer,\n identity,\n arrayBuffer,\n date,\n headers,\n error,\n typedArray,\n // blob MUST come before clonable — clonable would otherwise pass-through\n // a Blob unboxed, which works on clone transports but loses the data on\n // JSON. Blob's isType excludes File so File still rides clonable.\n blob,\n promise,\n func,\n messagePort,\n readableStream,\n writableStream,\n abortSignal,\n response,\n request,\n map,\n set,\n bigInt,\n symbol,\n event,\n // After readableStream (some platforms make streams async-iterable),\n // before the fallbacks so generators don't coerce to {}.\n asyncIterator,\n nonFiniteNumber,\n undefinedValue,\n // clonable/transferable before eventTarget: OffscreenCanvas & co. are Transferables\n // that also extend EventTarget, which eventTarget would otherwise box as façade husks.\n clonable,\n transferable,\n // eventTarget MUST be last among instanceof-EventTarget revivables —\n // MessagePort/AbortSignal/Window/Worker all extend EventTarget; the\n // specific ones need first dibs via findBoxModule iteration order.\n eventTarget,\n // Catch-all: structuredClone-probes and coerces unclonables to `{}`,\n // matching JSON.stringify(new WeakMap()) === \"{}\".\n unclonable,\n] as const\n\nexport type DefaultRevivableModules = typeof defaultRevivableModules\nexport type DefaultRevivableModule = DefaultRevivableModules[number]\n\nconst findBoxModule = (\n value: unknown,\n modules: readonly RevivableModule[]\n): RevivableModule | undefined =>\n modules.find(module => module.isType(value))\n\nconst findReviveModule = (\n value: BoxBase,\n modules: readonly RevivableModule[],\n): RevivableModule | undefined =>\n modules.find(module => module.type === value.type)\n\nconst isPlainObject = (value: unknown): value is Record<string, Capable> =>\n !!value && typeof value === 'object' && Object.getPrototypeOf(value) === Object.prototype\n\nconst descend = <TOut>(value: unknown, transform: (v: Capable) => unknown): TOut => {\n if (Array.isArray(value)) {\n return value.map(v => transform(v)) as TOut\n }\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries<Capable>(value).map(([k, v]) => [k, transform(v)]),\n ) as TOut\n }\n return value as TOut\n}\n\n// Walk path for cycle detection. Box/revive are fully synchronous, so a\n// module-global set with balanced enter/exit is safe; tracking the *path*\n// (not all visited values) keeps sibling aliasing working — only a true\n// ancestor revisit, which would recurse forever, throws.\nconst boxPath = new WeakSet<object>()\nconst revivePath = new WeakSet<object>()\n\nconst isTrackable = (value: unknown): value is object =>\n value !== null && (typeof value === 'object' || typeof value === 'function')\n\nexport const recursiveBox = <\n T extends Capable,\n TModules extends readonly RevivableModule[]\n>(\n value: T,\n context: RevivableContext<TModules>\n): DeepReplaceWithBox<T, TModules[number]> => {\n type ReturnCastType = DeepReplaceWithBox<T, TModules[number]>\n // Already-boxed values pass through — revivables may embed a pre-built\n // BoxedX in their outgoing payload; descending would re-box raw ports.\n if (isRevivableBox(value)) return value as ReturnCastType\n const track = isTrackable(value)\n if (track) {\n if (boxPath.has(value)) {\n throw new TypeError('osra: cannot serialize a circular structure — break the cycle or send the container by reference')\n }\n boxPath.add(value)\n }\n try {\n const handledByModule = findBoxModule(value, context.revivableModules)\n if (handledByModule) {\n return handledByModule.box(value, context) as ReturnCastType\n }\n return descend<ReturnCastType>(value, v => recursiveBox(v, context))\n } finally {\n if (track) boxPath.delete(value)\n }\n}\n\nexport const recursiveRevive = <\n T extends Capable,\n TModules extends readonly RevivableModule[]\n>(\n value: T,\n context: RevivableContext<TModules>\n): DeepReplaceWithRevive<T, TModules[number]> => {\n type ReturnCastType = DeepReplaceWithRevive<T, TModules[number]>\n const track = isTrackable(value)\n if (track) {\n // Structured clone can deliver cyclic graphs a peer crafted — fail\n // with a clear error instead of blowing the stack mid-dispatch.\n if (revivePath.has(value)) {\n throw new TypeError('osra: cannot revive a circular structure')\n }\n revivePath.add(value)\n }\n try {\n if (isRevivableBox(value)) {\n const handledByModule = findReviveModule(value, context.revivableModules)\n if (handledByModule) {\n return handledByModule.revive(value, context) as ReturnCastType\n }\n }\n return descend<ReturnCastType>(value, v => recursiveRevive(v, context))\n } finally {\n if (track) revivePath.delete(value)\n }\n}","import type { Transport } from '../utils/transport.js'\nimport type { DefaultRevivableModules, RevivableModule } from '../revivables/index.js'\nimport type { DeepReplaceWithBox } from '../utils/replace.js'\nimport type { ProtocolContext } from './utils.js'\nimport type {\n Capable, MessageEventTarget, MessageFields,\n MessageVariant, Uuid,\n} from '../types.js'\n\nimport { recursiveBox, recursiveRevive } from '../revivables/index.js'\nimport { isEmitTransport, isReceiveTransport } from '../utils/type-guards.js'\nimport { runTeardown } from '../utils/teardown.js'\n\nexport const type = 'bidirectional' as const\n\nexport type InitMessage<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n T extends Capable<TModules> = Capable<TModules>\n> = {\n type: 'init'\n remoteUuid: Uuid\n data: DeepReplaceWithBox<T, TModules[number]>\n}\n\nexport declare const Messages: <\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n T extends Capable<TModules> = Capable<TModules>\n>(modules: TModules, value: T) =>\n | InitMessage<TModules, T>\n\nexport type Messages<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n T extends Capable<TModules> = Capable<TModules>\n> = ReturnType<typeof Messages<TModules, T>>\n\nexport type ConnectionContext<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n type: 'bidirectional'\n eventTarget: MessageEventTarget<TModules>\n connection: BidirectionalConnection<TModules>\n}\n\nexport type ConnectionRevivableContext<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n transport: Transport\n remoteUuid: Uuid\n sendMessage: (message: MessageFields & Record<string, unknown>) => void\n revivableModules: TModules\n eventTarget: MessageEventTarget<TModules>\n}\n\nexport const startBidirectionalConnection = <\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n>(\n { transport, value, remoteUuid, eventTarget, send, revivableModules }:\n {\n transport: Transport\n value: Capable<TModules>\n remoteUuid: Uuid\n eventTarget: MessageEventTarget<TModules>\n send: (message: MessageFields & Record<string, unknown>) => void\n revivableModules: TModules\n },\n) => {\n const revivableContext = {\n transport,\n remoteUuid,\n sendMessage: send,\n eventTarget,\n revivableModules\n } satisfies ConnectionRevivableContext<TModules>\n\n for (const module of revivableModules) {\n module.init?.(revivableContext)\n }\n\n const { promise, resolve } = Promise.withResolvers<InitMessage<TModules>['data']>()\n\n eventTarget.addEventListener('message', function listener ({ detail }) {\n if (detail.type === 'init') {\n resolve(detail.data)\n eventTarget.removeEventListener('message', listener)\n }\n })\n\n send({\n type: 'init',\n remoteUuid,\n data: recursiveBox(value, revivableContext)\n })\n\n return {\n revivableContext,\n remoteValue:\n promise\n .then(initData => recursiveRevive(initData, revivableContext) as Capable),\n }\n}\n\nexport type BidirectionalConnection<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n revivableContext: ConnectionRevivableContext<TModules>\n remoteValue: Promise<Capable>\n}\n\n/** Mounts bidirectional mode on the shared protocol context. Only active\n * when the transport can both emit and receive. */\nexport const init = <TModules extends readonly RevivableModule[]>(\n ctx: ProtocolContext<TModules>\n): void => {\n if (!(isEmitTransport(ctx.transport) && isReceiveTransport(ctx.transport))) return\n\n ctx.protocolEventTarget.addEventListener('message', ({ detail: message }) => {\n if (message.type === 'announce') {\n if (!message.remoteUuid) {\n ctx.sendMessage({ type: 'announce', remoteUuid: message.uuid })\n return\n }\n if (message.remoteUuid !== ctx.getUuid()) return\n // Already-tracked uuid is the normal handshake-echo (peer re-announcing\n // back after our reply), not a collision — drop it.\n if (ctx.connectionContexts.has(message.uuid)) return\n // Echo announce back in case the peer missed our initial one.\n ctx.sendMessage({ type: 'announce', remoteUuid: message.uuid })\n const eventTarget = ctx.createConnectionEventTarget()\n let connection: ReturnType<typeof startBidirectionalConnection<TModules>>\n try {\n connection = startBidirectionalConnection<TModules>({\n transport: ctx.transport,\n value: ctx.value,\n remoteUuid: message.uuid,\n eventTarget,\n send: (m) => ctx.sendMessage(m as MessageVariant),\n revivableModules: ctx.revivableModules\n })\n } catch (error) {\n // Boxing our own value failed (e.g. cyclic data) — surface it\n // instead of swallowing inside EventTarget dispatch.\n ctx.rejectRemoteValue(error)\n return\n }\n const connectionContext = {\n type: 'bidirectional',\n eventTarget,\n connection,\n } satisfies ConnectionContext<TModules>\n ctx.connectionContexts.set(message.uuid, connectionContext)\n connectionContext.connection.remoteValue.then(\n (remoteValue) => ctx.resolveRemoteValue(remoteValue),\n (error) => ctx.rejectRemoteValue(error),\n )\n return\n }\n if (message.type === 'close') {\n if (message.remoteUuid !== ctx.getUuid()) return\n const connectionContext = ctx.connectionContexts.get(message.uuid)\n if (!connectionContext) return\n ctx.connectionContexts.delete(message.uuid)\n runTeardown(connectionContext.connection.revivableContext)\n // No-op when the handshake already resolved; a close that beats init\n // must not leave the caller pending forever.\n ctx.rejectRemoteValue(new Error('osra: peer closed the connection'))\n return\n }\n // \"init\" | \"message\" | \"message-port-close\"\n if (message.remoteUuid !== ctx.getUuid()) return\n const connection = ctx.connectionContexts.get(message.uuid)\n // drop messages from peers we haven't tracked (pre-announce or post-close)\n if (!connection) return\n connection.eventTarget.dispatchEvent(\n new CustomEvent('message', { detail: message })\n )\n })\n\n if (ctx.presetRemoteUuid !== undefined) {\n const eventTarget = ctx.createConnectionEventTarget()\n let connection: ReturnType<typeof startBidirectionalConnection<TModules>>\n try {\n connection = startBidirectionalConnection<TModules>({\n transport: ctx.transport,\n value: ctx.value,\n remoteUuid: ctx.presetRemoteUuid,\n eventTarget,\n send: (m) => ctx.sendMessage(m as MessageVariant),\n revivableModules: ctx.revivableModules\n })\n } catch (error) {\n ctx.rejectRemoteValue(error)\n return\n }\n const connectionContext = {\n type: 'bidirectional',\n eventTarget,\n connection,\n } satisfies ConnectionContext<TModules>\n ctx.connectionContexts.set(ctx.presetRemoteUuid, connectionContext)\n connectionContext.connection.remoteValue.then(\n (remoteValue) => ctx.resolveRemoteValue(remoteValue),\n (error) => ctx.rejectRemoteValue(error),\n )\n return\n }\n\n // A lone announce is lost when the counterpart isn't listening yet (still-loading iframe,\n // relay attached after a worker exposes) — re-announce with capped backoff until a peer\n // connects. The uuid is stable across retries, so duplicates are dropped as handshake echoes.\n let announceDelay = 50\n let announceTimeout: ReturnType<typeof setTimeout> | undefined\n const announce = () => {\n if (ctx.unregisterSignal?.aborted || ctx.connectionContexts.size > 0) return\n ctx.sendMessage({ type: 'announce' })\n announceTimeout = setTimeout(announce, announceDelay)\n announceDelay = Math.min(announceDelay * 2, 1_000)\n }\n ctx.unregisterSignal?.addEventListener('abort', () => clearTimeout(announceTimeout), { once: true })\n announce()\n}\n","import type { UnderlyingType } from './type.js'\n\nexport type EventMap = Record<string, Event>\n\nexport interface TypedEventTarget<T extends EventMap> extends EventTarget {\n [UnderlyingType]?: T\n\n addEventListener<K extends keyof T & string>(\n type: K,\n listener: ((event: T[K]) => void) | null,\n options?: boolean | AddEventListenerOptions\n ): void\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | AddEventListenerOptions\n ): void\n\n removeEventListener<K extends keyof T & string>(\n type: K,\n listener: ((event: T[K]) => void) | null,\n options?: boolean | EventListenerOptions\n ): void\n removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | EventListenerOptions\n ): void\n}\n\n/**\n * Create a new `TypedEventTarget<T>` for a given event map. Centralises the\n * `EventTarget` → `TypedEventTarget<T>` cast so individual call sites don't\n * each need their own (`EventTarget` lacks the generic event map at the type\n * level, but the runtime behaviour is identical).\n */\nexport const createTypedEventTarget = <T extends EventMap>(): TypedEventTarget<T> =>\n new EventTarget() as TypedEventTarget<T>\n","import type {\n Message, MessageVariant, Uuid,\n Capable, MessageEventMap\n} from '../types.js'\nimport type { DefaultRevivableModules, RevivableModule } from '../revivables/index.js'\nimport type { Transport } from '../utils/transport.js'\nimport type { ConnectionContext } from './index.js'\nimport type { TypedEventTarget } from '../utils/typed-event-target.js'\n\nimport { defaultRevivableModules } from '../revivables/index.js'\nimport { isJsonOnlyTransport, isCustomTransport } from '../utils/type-guards.js'\n\nexport const normalizeTransport = (transport: Transport): Transport => {\n const custom = isCustomTransport(transport)\n const emit = custom ? (transport as { emit?: unknown }).emit : transport\n const receive = custom ? (transport as { receive?: unknown }).receive : transport\n // Probe the embedded platform transports, not the wrapper — a custom\n // { emit: webSocket } is JSON-only even though the wrapper itself isn't.\n const isJson =\n custom && 'isJson' in transport && transport.isJson !== undefined\n ? transport.isJson\n : (emit !== undefined && isJsonOnlyTransport(emit))\n || (receive !== undefined && isJsonOnlyTransport(receive))\n return {\n isJson,\n ...(emit !== undefined ? { emit } : {}),\n ...(receive !== undefined ? { receive } : {}),\n } as Transport\n}\n\n/** Resolves the final revivable module list. The user supplies a function\n * that takes the defaults and returns whatever ordering/composition they\n * want — add modules, drop defaults, reorder, override per-type. When\n * omitted, the defaults are used as-is. */\nexport const mergeRevivableModules = <\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n>(\n configure: ((defaults: DefaultRevivableModules) => TModules) | undefined,\n): TModules =>\n configure\n ? configure(defaultRevivableModules)\n : defaultRevivableModules as unknown as TModules\n\nexport type ProtocolEventMap<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n message: CustomEvent<Message<TModules>>\n}\n\nexport type ProtocolEventTarget<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = TypedEventTarget<ProtocolEventMap<TModules>>\n\nexport type ProtocolContext<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n transport: Transport\n value: Capable<TModules>\n revivableModules: TModules\n connectionContexts: Map<string, ConnectionContext<TModules>>\n getUuid: () => Uuid\n presetRemoteUuid?: Uuid\n sendMessage: (message: MessageVariant) => void\n protocolEventTarget: ProtocolEventTarget<TModules>\n resolveRemoteValue: (value: Capable<TModules>) => void\n rejectRemoteValue: (error: unknown) => void\n createConnectionEventTarget: () => TypedEventTarget<MessageEventMap<TModules>>\n unregisterSignal?: AbortSignal\n}\n\nexport type StartConnectionsOptions<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> = {\n transport: Transport\n name?: string\n remoteName?: string\n key?: string\n origin?: string\n unregisterSignal?: AbortSignal\n /** Configure the revivable module list. Receives the defaults and\n * returns the final ordered list — add modules, drop defaults, reorder,\n * or override per-type as needed. */\n revivableModules?: (defaults: DefaultRevivableModules) => TModules\n uuid?: Uuid\n remoteUuid?: Uuid\n}\n","import type { Transport } from '../utils/transport.js'\n\nimport { OSRA_DEFAULT_KEY } from '../types.js'\nimport { isEmitTransport, isReceiveTransport } from '../utils/type-guards.js'\nimport { getTransferableObjects } from '../utils/transferable.js'\nimport {\n registerOsraMessageListener,\n sendOsraMessage,\n} from '../utils/transport.js'\nimport { normalizeTransport } from './utils.js'\n\nexport type RelayOptions = {\n key?: string\n origin?: string\n originA?: string\n originB?: string\n nameA?: string\n nameB?: string\n unregisterSignal?: AbortSignal\n}\n\nexport const relay = (\n transportA: Transport,\n transportB: Transport,\n {\n key = OSRA_DEFAULT_KEY,\n origin = '*',\n originA = origin,\n originB = origin,\n nameA,\n nameB,\n unregisterSignal,\n }: RelayOptions = {},\n): void => {\n const a = normalizeTransport(transportA)\n const b = normalizeTransport(transportB)\n\n const forward = (\n from: Transport,\n to: Transport,\n fromOrigin: string,\n toOrigin: string,\n remoteName: string | undefined,\n ): void => {\n if (!isReceiveTransport(from) || !isEmitTransport(to)) return\n registerOsraMessageListener({\n transport: from,\n key,\n remoteName,\n origin: fromOrigin,\n unregisterSignal,\n listener: (message) => {\n sendOsraMessage(to, message, toOrigin, getTransferableObjects(message))\n },\n })\n }\n\n forward(a, b, originA, originB, nameA)\n forward(b, a, originB, originA, nameB)\n}\n","import type { DefaultRevivableModules, RevivableModule } from '../revivables/index.js'\nimport type { ConnectionContext as BidirectionalConnectionContext } from './bidirectional.js'\nimport type {\n Message, MessageVariant, Uuid,\n Capable,\n} from '../types.js'\nimport type {\n ProtocolContext,\n StartConnectionsOptions,\n} from './utils.js'\nimport type { MessageContext } from '../utils/transport.js'\n\nimport { OSRA_DEFAULT_KEY, OSRA_KEY } from '../types.js'\nimport * as bidirectional from './bidirectional.js'\nimport {\n isEmitTransport,\n isReceiveTransport,\n} from '../utils/type-guards.js'\nimport { createTypedEventTarget } from '../utils/typed-event-target.js'\nimport { getTransferableObjects } from '../utils/transferable.js'\nimport { registerOsraMessageListener, sendOsraMessage } from '../utils/transport.js'\nimport { runTeardown } from '../utils/teardown.js'\nimport { mergeRevivableModules, normalizeTransport } from './utils.js'\n\nexport * from './bidirectional.js'\nexport * from './relay.js'\nexport * from './utils.js'\n\nexport type ConnectionModule<T> = {\n readonly type: string\n // ProtocolContext<any> rather than ProtocolContext<readonly RevivableModule[]>\n // for the same bivariance reason as RevivableModule.box — concrete modules\n // declare narrower context generics than the shared interface can express.\n readonly init: (ctx: ProtocolContext<any>) => void\n readonly Messages?: T\n}\n\nexport const connections = [\n bidirectional\n] as const\n\nexport type DefaultConnectionModules = typeof connections\nexport type DefaultConnectionModule = DefaultConnectionModules[number]\n\nexport type ConnectionMessage<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n T extends Capable<TModules> = Capable<TModules>\n> =\n DefaultConnectionModule extends {\n Messages: (modules: TModules, value: T) => infer R\n }\n ? R\n : never\n\nexport type ConnectionContext<\n TModules extends readonly RevivableModule[] = DefaultRevivableModules\n> =\n | BidirectionalConnectionContext<TModules>\n\nexport const startConnections = <\n T = unknown,\n const TModules extends readonly RevivableModule[] = DefaultRevivableModules\n>(\n value: Capable<TModules>,\n {\n transport: _transport,\n name,\n remoteName,\n key = OSRA_DEFAULT_KEY,\n origin = '*',\n unregisterSignal,\n revivableModules: configureRevivableModules,\n uuid: _uuid,\n remoteUuid: presetRemoteUuid,\n }: StartConnectionsOptions<TModules>\n): Promise<T> => {\n const transport = normalizeTransport(_transport)\n if (!(isEmitTransport(transport) && isReceiveTransport(transport))) {\n throw new Error(\n 'osra: transport must be able to both emit and receive to establish a connection'\n + ' — pass a bidirectional platform transport or a custom { emit, receive } pair',\n )\n }\n const mergedRevivableModules = mergeRevivableModules<TModules>(configureRevivableModules)\n type MergedModules = typeof mergedRevivableModules\n const connectionContexts = new Map<string, ConnectionContext<MergedModules>>()\n\n const { promise: remoteValuePromise, resolve: resolveRemoteValue, reject: rejectRemoteValue } =\n Promise.withResolvers<Capable<MergedModules>>()\n // Keeps a fire-and-forget `expose(value, …)` (the documented server-side\n // pattern) from surfacing an unhandled rejection on abort/close; awaiting\n // callers still observe the rejection through the original promise.\n remoteValuePromise.catch(() => {})\n\n const uuid: Uuid = _uuid ?? globalThis.crypto.randomUUID()\n\n const sendEnvelope = (message: MessageVariant) => {\n const envelope = { [OSRA_KEY]: key, name, uuid, ...message }\n sendOsraMessage(transport, envelope, origin, getTransferableObjects(envelope))\n }\n\n const sendMessage = (message: MessageVariant) => {\n if (unregisterSignal?.aborted) return\n sendEnvelope(message)\n }\n\n const protocolEventTarget = createTypedEventTarget<{ message: CustomEvent<Message<MergedModules>> }>()\n\n const ctx: ProtocolContext<MergedModules> = {\n transport,\n value: value as Capable<MergedModules>,\n revivableModules: mergedRevivableModules,\n connectionContexts,\n getUuid: () => uuid,\n presetRemoteUuid,\n sendMessage,\n protocolEventTarget,\n resolveRemoteValue,\n rejectRemoteValue,\n createConnectionEventTarget: createTypedEventTarget,\n unregisterSignal,\n }\n\n const listener = (message: Message, _: MessageContext) => {\n // own message looped back on the channel\n if (message.uuid === uuid) return\n protocolEventTarget.dispatchEvent(\n new CustomEvent('message', { detail: message as Message<MergedModules> }),\n )\n }\n\n registerOsraMessageListener({\n listener,\n transport,\n remoteName,\n key,\n origin,\n unregisterSignal\n })\n\n // Abort = explicit local teardown: notify every tracked peer, dispose\n // per-connection state, and reject the (possibly still pending) handshake.\n unregisterSignal?.addEventListener('abort', () => {\n for (const [peerUuid, connectionContext] of connectionContexts) {\n sendEnvelope({ type: 'close', remoteUuid: peerUuid as Uuid })\n runTeardown(connectionContext.connection.revivableContext)\n }\n connectionContexts.clear()\n rejectRemoteValue(unregisterSignal.reason)\n }, { once: true })\n\n for (const connectionModule of connections) {\n connectionModule.init(ctx)\n }\n\n return remoteValuePromise as Promise<T>\n}\n","import type { Capable, Remote } from './types.js'\nimport type { DefaultRevivableModules, RevivableContext } from './revivables/index.js'\nimport type { RevivableModule } from './revivables/index.js'\nimport type { StartConnectionsOptions } from './connections/utils.js'\nimport type { Transport } from './utils/transport.js'\nimport type {\n BadFieldValue, BadFieldPath, BadFieldParent,\n ErrorMessage, BadValue, Path, ParentObject\n} from './utils/capable-check.js'\n\nimport { startConnections } from './connections/index.js'\n\nexport * from './types.js'\nexport * from './revivables/index.js'\nexport * from './connections/index.js'\nexport * from './utils/index.js'\n\n/** Synthetic context so `Capable` can narrow on the inferred transport\n * without an actual context object at the call site. Only `transport`\n * matters; the rest is stubbed with the broadest types. */\ntype ContextOf<TTransport extends Transport> = RevivableContext & { transport: TTransport }\n\ntype CapableCheck<\n T,\n TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n Ctx extends RevivableContext = RevivableContext,\n> =\n T extends Capable<TModules, Ctx>\n ? T\n : T & {\n [ErrorMessage]: 'Value type must resolve to a Capable'\n [BadValue]: BadFieldValue<T, Capable<TModules, Ctx>>\n [Path]: BadFieldPath<T, Capable<TModules, Ctx>>\n [ParentObject]: BadFieldParent<T, Capable<TModules, Ctx>>\n }\n\nexport const expose = async <\n T = unknown,\n const TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n const TTransport extends Transport = Transport,\n const TValue = Capable<TModules, ContextOf<TTransport>>\n>(\n value: CapableCheck<TValue, TModules, ContextOf<TTransport>>,\n options: StartConnectionsOptions<TModules> & { transport: TTransport }\n): Promise<Remote<T>> =>\n startConnections<Remote<T>, TModules>(\n value as Capable<TModules>,\n options\n )\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "osra",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Easy communication between workers",
5
5
  "files": [
6
6
  "build"