osra 0.6.7 → 0.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +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/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\n/* `ReadonlyArray` throughout these unions: `expose()` infers its value with a `const` type parameter, so inline array literals arrive as readonly tuples and must stay assignable. */\nexport type Jsonable =\n | boolean\n | null\n | number\n | string\n | { [key: string]: Jsonable }\n | ReadonlyArray<Jsonable>\n\nexport type Structurable =\n | Jsonable\n // not really structureable but here for convenience.\n // A `/** */` here would be a doc comment on the union MEMBER, which makes typedoc render the\n // whole union as a 20 entry \"Union Members\" wall on the generated reference page.\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 | ReadonlyArray<Structurable>\n | Map<Structurable, Structurable>\n | Set<Structurable>\n\n/** lib.dom declares some `Transferable` members as EMPTY interfaces\n * (`MediaSourceHandle` as of TS 5.x/7.x). With no members they structurally\n * absorb every object type, which would let `WeakMap` & co. slip past the\n * `Capable` check unnoticed. Drop member-less types from the compile-time\n * union; runtime transfer of those exotic types is unaffected. */\ntype NonAbsorbing<T> = T extends unknown ? keyof T extends never ? never : T : never\n\nexport type StructurableTransferable =\n | Structurable\n | NonAbsorbing<Transferable>\n | { [key: string]: StructurableTransferable }\n | ReadonlyArray<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`/`File`/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 | ReadonlyArray<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), containers map recursively,\n * 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 Promise<infer U> ? Promise<Remote<U>>\n : T extends\n | Map<any, any> | Set<any> | Date | Error | RegExp\n | ArrayBuffer | ArrayBufferView | Blob | File | FileList\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\n/** What the local side knows about the realm on the other end of a connection.\n *\n * `origin` and `source` are only OBSERVABLE on window transports. A MessagePort message carries\n * origin \"\" and source null, so for a port the identity has to be declared by whoever created the\n * transport, which is the side that received the port over a trustworthy window message. That is why\n * `expose` takes a `context` option rather than only reporting what it can see: without it, every\n * port-based consumer would rebuild the same out-of-band handshake to learn who it is talking to. */\nexport type Context = {\n /** Tears down THIS connection and nothing else: the peer is sent a close, its revivables are torn\n * down, and it stops being tracked. `unregisterSignal` is the whole-expose equivalent; this is the\n * one a server reaches for when a single realm misbehaves or is finished with. */\n abort?: () => void\n origin?: string\n source?: MessageEventSource | null\n port?: MessagePort | WebExtPort\n sender?: WebExtSender\n}\n\nexport type MessageContext = {\n port?: MessagePort | WebExtPort // WebExtension only\n sender?: WebExtSender // WebExtension only\n receiveTransport?: ReceivePlatformTransport\n source?: MessageEventSource | null // Window, Worker, WebSocket\n origin?: string // Window only\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\n// typed structurally because lib.webworker can't be loaded next to lib.dom (conflicting `self` declarations)\nexport type WorkerSelf = {\n postMessage(...args: any[]): void\n addEventListener(type: string, listener: (event: any) => void): void\n removeEventListener(type: string, listener: (event: any) => void): void\n}\n\nexport type EmitPlatformTransport =\n | EmitJsonPlatformTransport\n | Window\n | ServiceWorker\n | Worker\n | SharedWorker\n | MessagePort\n | WorkerSelf\n\nexport type ReceivePlatformTransport =\n | ReceiveJsonPlatformTransport\n | Window\n | ServiceWorkerContainer\n | Worker\n | SharedWorker\n | MessagePort\n | WorkerSelf\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 ambient `browser`/`chrome` globals here would leak unresolvable names into the published .d.ts\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 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 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 {\n listenOnWebExtOnMessage(receiveTransport.onMessage as WebExtOnMessage)\n }\n return\n }\n\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 and ServiceWorkerContainer events carry their own unrelated origins\n const filterByOrigin = origin !== '*' && isWindow(receiveTransport)\n const messageListener = (event: MessageEvent<Message | string>) => {\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 .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\n// A WebExtension port THROWS on postMessage once it is disconnected, where a MessagePort silently no-ops\n// (measured: neither engine throws or logs for a MessagePort, in any disentanglement route). Firefox says\n// \"Attempt to postMessage on disconnected port\", Chromium \"Attempting to use a disconnected port object\".\n// Every message on a port transport funnels through here, so a revivable still talking while the other end\n// tears down - a stream topping up its credit window - throws on every message, not once.\nconst disconnectedPorts = new WeakSet<WebExtPort>()\n\nconst isDisconnectedPortError = (error: unknown): boolean =>\n String((error as { message?: unknown })?.message ?? error).includes('disconnected port')\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 // A disconnected port is ordinary teardown, not a fault; anything else here is a real bug and must stay visible\n if (disconnectedPorts.has(emitTransport)) return\n try {\n emitTransport.postMessage(message)\n } catch (error) {\n if (!isDisconnectedPortError(error)) throw error\n disconnectedPorts.add(emitTransport)\n }\n } else if (isWebExtensionRuntime(emitTransport)) {\n // Rejects while no receiver exists yet (announce retries) - swallow only that\n emitTransport.sendMessage(message)?.catch?.((error: unknown) => {\n if (!String((error as { message?: unknown })?.message).includes('Receiving end does not exist')) throw error\n })\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 {\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 that haven't shipped Float16Array yet (Node ≤ 23, Chrome ≤ 134, Firefox ≤ 132)\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) resolve to the nearest TypedArray ancestor\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\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// Some entries are also clonable (ArrayBuffer, ImageBitmap, …) - outside a `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 // prevents a SecurityError when `value` is a cross-origin window - the property probes below would throw; no test covers this guard (the cross-origin tests only cover isJsonOnlyTransport and normalizeTransport), so it reads as dead code\n if (isWindow(value)) return false\n if (!('name' in value) || !('disconnect' in value) || !('postMessage' in value)) return false\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\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 distinguish onConnect from onMessage, which share the exact same shape\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 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' && !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 || 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 (an EventEmitter) has an inherited `emit` and would otherwise be misclassified\nconst isPlainObjectShape = (value: unknown): value is Record<string, unknown> => {\n if (!value || typeof value !== 'object') return false\n // a cross-origin window's [[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: the whole backing buffer loses byteOffset/length on revive\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. */\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\n/** Whether a scope's teardown has already run. Callers use this to REFUSE work rather than start it:\n * `onTeardown` against a dead scope runs the callback immediately, which is a footgun inside an\n * initializer, and anything registered afterwards is state no teardown will ever visit again. */\nexport const isTornDown = (scope: WeakKey): boolean => tornDown.has(scope)\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 { }\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 // Request/Response are not platform Transferables, but wrapping them puts their\n // body stream inside the transfer extent so its chunks inherit move semantics\n globalThis.Request,\n globalThis.Response,\n globalThis.ImageBitmap,\n globalThis.OffscreenCanvas,\n (globalThis as { VideoFrame?: abstract new (...args: any[]) => unknown }).VideoFrame,\n (globalThis as { AudioData?: abstract new (...args: any[]) => unknown }).AudioData,\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\n// Boxing is fully synchronous (same invariant boxPath in index.ts relies on), so a\n// balanced enter/exit counter is enough to tell \"currently inside a transfer() wrapper\".\nlet transferDepth = 0\n\n/** Whether boxing is happening inside a transfer() wrapper's extent. Streams read\n * this at box time so transfer(stream) propagates move semantics to their chunks. */\nexport const isInTransfer = () => transferDepth > 0\n\n/** Internal chunk marker: unlike the public transfer(), wraps containers too, so\n * transferables nested anywhere inside a chunk move. Not part of the public API. */\nexport const forceTransfer = <T>(value: T): T =>\n (isObject(value) && !isTransferWrapper(value)\n ? { [TRANSFER_MARKER]: true, value }\n : value\n ) as T\n\n/** Runs fn with the ambient transfer extent suspended. Boxing at independent walk\n * entry points (protocol ports, revived-function calls) can fire synchronously\n * inside someone else's transfer() extent - an EventPort.start() flush during\n * boxing, or user code (a getter) calling a revived function mid-walk. Those\n * values are not part of the wrapper's graph, so their move semantics must come\n * from a wrapper in their own data, never from the ambient counter. */\nexport const outsideTransfer = <T>(fn: () => T): T => {\n const saved = transferDepth\n transferDepth = 0\n try {\n return fn()\n } finally {\n transferDepth = saved\n }\n}\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 transferDepth++\n try {\n // `degraded` tells the send-time walker in getTransferableObjects to skip the transfer-list entry\n return {\n ...BoxBase,\n type,\n inner: recursiveBox(wrapper.value, context),\n degraded: isJsonOnlyTransport(context.transport),\n } as unknown as BoxedTransfer<T>\n } finally {\n transferDepth--\n }\n}\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// Structured clone can't copy these, so they must go on the transfer list - opt-in or not.\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// `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 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, so never descend into them. Typed\n // arrays are boxed (their raw buffer rides the box and is collected above); a raw\n // DataView rides the clonable fallback, so inside a transfer box its buffer is the\n // thing to move - the serialized view then arrives over the moved buffer.\n if (ArrayBuffer.isView(value)) {\n if (inTransferBox && value instanceof DataView && !isSharedArrayBuffer(value.buffer) && !seen.has(value.buffer)) {\n seen.add(value.buffer)\n transferables.push(value.buffer as ArrayBuffer)\n }\n return\n }\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\n// NOT `extends EventTarget`: Firefox privileged sandboxes don't support subclassing platform interfaces\ntype EventPortListener = EventListenerOrEventListenerObject\n\nexport class EventPort<T> {\n // per (type, listener): value = once, and duplicate adds are ignored, matching EventTarget\n private _listeners = new Map<string, Map<EventPortListener, boolean>>()\n\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 if (!listener) return\n let listeners = this._listeners.get(type)\n if (!listeners) { listeners = new Map(); this._listeners.set(type, listeners) }\n if (!listeners.has(listener)) {\n listeners.set(listener, typeof options === 'object' && !!options?.once)\n }\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 if (!listener) return\n this._listeners.get(type)?.delete(listener)\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 const listeners = this._listeners.get(event.type)\n if (listeners) {\n for (const [listener, once] of [...listeners]) {\n if (once) listeners.delete(listener)\n if (typeof listener === 'function') listener.call(this, event)\n else listener.handleEvent(event)\n }\n }\n return true\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 // 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\n// Contract: `cleanup` MUST NOT (transitively) reference `target`, or the engine never sees target as collectable.\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 { outsideTransfer } from './transfer.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, seq?: number }\n | { type: 'message-port-close', remoteUuid: Uuid, portId: Uuid, seq?: number }\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 back `AnyPort<A | B>`, not `AnyPort<A> | AnyPort<B>`\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\n// wire contract: each side stamps its outgoing port messages with a monotonic `seq`, and the receiver buffers by seq and delivers strictly in send-order once a handler exists\n// the credit-window readable-stream protocol relies on that in-order delivery; port messages can also arrive BEFORE the message that revives the port and registers its handler, which is why handler-less routing entries exist at all\ntype PortRouting = {\n handler?: (message: Messages) => void\n /** Next incoming seq to deliver. */\n nextSeq: number\n /** Out-of-order / early incoming messages, keyed by their seq. */\n buffer: Map<number, Messages>\n /** Next outgoing seq to stamp on this side's messages for the port. */\n outSeq: number\n}\n\n// caps the per-port reorder buffer so a peer that never sends the awaited seq can't grow it without bound - overflow fails the port closed instead of wedging it silently\nconst REORDER_LIMIT = 2048\n// remembers closed portIds so late in-flight messages can't resurrect routing state\nconst TOMBSTONE_LIMIT = 128\n// caps routing entries allocated by messages arriving before their port's handler registers\nconst PENDING_PORT_LIMIT = 1024\n\ntype ConnectionMessagePortState = {\n /** O(1) per-portId routing - avoids the O(N) addEventListener scan that was the\n * bottleneck for tight-loop RPC traffic. */\n ports: Map<string, PortRouting>\n /** Recently closed portIds, insertion-ordered for bounded eviction. */\n tombstones: Set<string>\n /** Count of handler-less entries in `ports`. */\n pendingPorts: number\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\nconst getPort = (state: ConnectionMessagePortState, portId: string): PortRouting => {\n let port = state.ports.get(portId)\n if (!port) {\n port = { nextSeq: 0, buffer: new Map(), outSeq: 0 }\n state.ports.set(portId, port)\n state.pendingPorts++\n }\n return port\n}\n\nconst tombstonePort = (state: ConnectionMessagePortState, portId: string): void => {\n const port = state.ports.get(portId)\n if (port && !port.handler) state.pendingPorts--\n state.ports.delete(portId)\n if (state.tombstones.size >= TOMBSTONE_LIMIT) {\n const oldest = state.tombstones.values().next().value\n if (oldest !== undefined) state.tombstones.delete(oldest)\n }\n state.tombstones.add(portId)\n}\n\nconst drainPort = (port: PortRouting): void => {\n if (!port.handler) return\n for (let next = port.buffer.get(port.nextSeq); next !== undefined; next = port.buffer.get(port.nextSeq)) {\n port.buffer.delete(port.nextSeq)\n port.nextSeq++\n port.handler(next)\n }\n}\n\nconst nextOutSeq = (context: RevivableContext, portId: Uuid): number => getPort(getState(context), portId).outSeq++\n\nconst registerPortHandler = (\n context: RevivableContext,\n portId: Uuid,\n handler: (message: Messages) => void,\n): void => {\n const state = getState(context)\n if (state.tombstones.has(portId)) {\n // macrotask, not microtask: revived ports reach their consumer through microtask chains, which must win so close listeners attach first\n setTimeout(() => handler({ type: 'message-port-close', remoteUuid: context.remoteUuid, portId }))\n return\n }\n const port = getPort(state, portId)\n if (!port.handler) state.pendingPorts--\n port.handler = handler\n drainPort(port)\n}\n\nexport const init = (context: RevivableContext): void => {\n const state: ConnectionMessagePortState = { ports: new Map(), tombstones: new Set(), pendingPorts: 0 }\n connectionStateMap.set(context, state)\n\n context.eventTarget.addEventListener('message', ({ detail }) => {\n if (detail.type !== 'message' && detail.type !== 'message-port-close') return\n if (state.tombstones.has(detail.portId)) return\n let port = state.ports.get(detail.portId)\n // a legacy peer (osra <= 0.5.6) does not stamp seq, so deliver in arrival order\n if (detail.seq === undefined) { port?.handler?.(detail); return }\n if (!port) {\n if (state.pendingPorts >= PENDING_PORT_LIMIT) return\n port = getPort(state, detail.portId)\n }\n if (detail.seq < port.nextSeq) return\n if (port.buffer.size >= REORDER_LIMIT && !(detail.seq === port.nextSeq && port.handler)) {\n port.buffer.clear()\n tombstonePort(state, detail.portId)\n port.handler?.({ type: 'message-port-close', remoteUuid: context.remoteUuid, portId: detail.portId })\n return\n }\n port.buffer.set(detail.seq, detail)\n drainPort(port)\n })\n\n onTeardown(context, () => {\n for (const [portId, port] of [...state.ports]) {\n port.handler?.({ type: 'message-port-close', remoteUuid: context.remoteUuid, portId: portId as Uuid })\n }\n state.ports.clear()\n state.tombstones.clear()\n state.pendingPorts = 0\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 // the close MUST carry the next seq so it stays ordered after this side's data messages, which it would otherwise drop\n // a missing routing entry means the port is already torn down, so `seq: port ? port.outSeq++ : 0` reads it without resurrecting routing state (do not switch to getPort here)\n const port = getState(context).ports.get(portId)\n context.sendMessage({ type: 'message-port-close', remoteUuid: context.remoteUuid, portId, seq: port ? port.outSeq++ : 0 })\n } catch {}\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\n// MUST stay in its own scope: sharing box()'s environment record would let the FR-held closure pin context/liveRef/handlers, breaking the gc-tracker contract\nconst makeBoxGcNet = (\n contextWeak: WeakRef<RevivableContext>,\n stateWeak: WeakRef<ConnectionMessagePortState>,\n portId: Uuid,\n) => () => {\n const ctx = contextWeak.deref()\n if (ctx) sendClose(ctx, portId)\n const state = stateWeak.deref()\n if (state) tombstonePort(state, portId)\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 are not structured-clonable, so even a clone transport routes 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 state = getState(context)\n const liveRef: AnyPort<T> = value\n const portId: Uuid = globalThis.crypto.randomUUID()\n\n const liveRefWeak = new WeakRef(liveRef)\n const contextWeak = new WeakRef(context)\n const stateWeak = new WeakRef(state)\n\n let cleanedUp = false\n const performCleanup = () => {\n if (cleanedUp) return\n cleanedUp = true\n const st = stateWeak.deref()\n if (st) tombstonePort(st, 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 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 // outsideTransfer: liveRef.start() below can flush queued messages synchronously\n // while a transfer() extent is on the stack - queued values are not part of it\n data: outsideTransfer(() => recursiveBox(data, context)),\n portId,\n seq: nextOutSeq(context, portId),\n })\n }\n\n const unregisterGc = trackGc(liveRef, makeBoxGcNet(contextWeak, stateWeak, portId))\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 registerPortHandler(context, 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 // A message the platform cannot deserialize (e.g. Gecko dropping a transferred VideoFrame)\n // is silently discarded by the port; forward it so consumers can error instead of losing data.\n const onMessageError = (): void => {\n target.dispatchEvent(new Event('messageerror'))\n }\n const onClose = (): void => {\n target.dispatchEvent(new Event('close'))\n }\n port.addEventListener('message', onMessage)\n port.addEventListener('messageerror', onMessageError as EventListener)\n port.addEventListener('close', onClose as EventListener)\n target.postMessage = (data: T, opt?: Transferable[] | StructuredSerializeOptions) => {\n // outsideTransfer: a fresh walk - move semantics come from wrappers in `data` (e.g.\n // forceTransfer-marked chunks), never from an extent that happens to be on the stack\n const boxed = outsideTransfer(() => 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('messageerror', onMessageError as EventListener)\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 state = 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, so holding 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 tombstonePort(state, 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 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: outsideTransfer(() => recursiveBox(data, context)),\n portId,\n seq: nextOutSeq(context, 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 registerPortHandler(context, 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 { isTornDown, 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 excess-property check flags the failure, not a user key\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 until settle: the port↔listener cycle has no other anchor\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 // transferred MessagePorts keep working past protocol 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 let removeTeardown: (() => void) | undefined\n const settle = () => {\n port.close()\n inFlightPromisePorts.delete(port)\n removeTeardown?.()\n }\n // Same refuse-before-registering rule as function.revive: onTeardown runs its callback immediately on a\n // dead scope, which would otherwise reach `removeTeardown` from inside its own initializer\n if (wireRouted && isTornDown(context)) {\n reject(new Error('osra: connection closed'))\n settle()\n return\n }\n removeTeardown = !wireRouted ? undefined : 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 { outsideTransfer } from './transfer.js'\nimport { recursiveBox } from './index.js'\nimport { getTransferableObjects } from '../utils/transferable.js'\nimport { EventChannel, type EventPort } from '../utils/event-channel.js'\nimport { isTornDown, 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 - the cycle has no other anchor.\nconst inFlightReturnPorts = new Set<EventPort<Capable>>()\n\n/** Releases a result the peer can never receive. Top level and best effort ON PURPOSE: walking into the\n * value is what boxing does, and boxing into a dead context is the thing the caller is avoiding. */\nconst disposeUndelivered = (value: unknown): void => {\n if (value instanceof ReadableStream) {\n if (!value.locked) value.cancel(new Error('osra: connection closed')).catch(() => {})\n } else if (typeof WritableStream !== 'undefined' && value instanceof WritableStream) {\n if (!value.locked) value.abort(new Error('osra: connection closed')).catch(() => {})\n }\n}\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 in args aren't structured-clonable.\n const { port1: localPort, port2: remotePort } = new EventChannel<CallContext, CallContext>()\n\n localPort.addEventListener('message', ({ data }) => {\n // Don't recursiveRevive - 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 // The handler runs detached, so the connection can die while it is still awaiting. Boxing after that\n // builds routing state in a context whose teardown has already run and can never run again: measured,\n // a returned ReadableStream came back LOCKED by box()'s own getReader() and was never cancelled, so\n // whatever fed it was stranded. Nothing can reach the peer now, so release instead of boxing.\n if (isTornDown(context)) {\n if (message.type === 'return') disposeUndelivered(message.value)\n try { returnPort.close() } catch { /* may already be closed */ }\n return\n }\n const boxedResult = (() => {\n try {\n return recursiveBox(message as Capable, context)\n } catch (error) {\n return recursiveBox({ type: 'throw', error: error as Capable } as Capable, context)\n }\n })()\n returnPort.postMessage(boxedResult, getTransferableObjects(boxedResult))\n // Defer close so the result reaches the peer before tear-down; without the close 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 // Refuse BEFORE allocating anything. A dead connection can never answer, and the boxing below would\n // strand these args in routing state no teardown will visit again, locking any stream among them.\n // This also keeps `onTeardown`'s immediate-run branch unreachable from inside `settle`'s initializer.\n if (isTornDown(context)) {\n reject(new Error('osra: connection closed'))\n return\n }\n\n const { port1: returnLocal, port2: returnRemote } = new EventChannel<Capable, Capable>()\n inFlightReturnPorts.add(returnLocal)\n\n let removeTeardown: (() => void) | undefined\n const settle = () => {\n returnLocal.close()\n inFlightReturnPorts.delete(returnLocal)\n removeTeardown?.()\n }\n // Connection death must reject calls - GC-drop of the proxy intentionally does not (see funcDropDoesNotRejectPending).\n 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 // outsideTransfer: user code can call a revived function synchronously from inside a\n // transfer() extent (e.g. a getter evaluated while boxing a transferred chunk); these\n // args are not part of that wrapper's graph\n const callContext = outsideTransfer(() => 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 { isInTransfer, forceTransfer } from './transfer.js'\nimport {\n createRevivableChannel,\n revive as reviveMessagePort,\n BoxedMessagePort,\n AnyPort\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 | { type: 'credit', n: number }\n\ntype ChunkMessage<T = unknown> = Promise<ReadableStreamReadResult<T>>\n\ntype PushMessage =\n | { type: 'chunk', value: Capable }\n | { type: 'end' }\n | { type: 'error', error: Capable }\n\ntype Msg = PullContext | PushMessage | ChunkMessage\n\nexport type BoxedReadableStream<T extends ReadableStream = ReadableStream> =\n & BoxBaseType<typeof type>\n & { port: BoxedMessagePort<Msg>, credit?: true }\n & { [UnderlyingType]: T }\n\nexport const isType = (value: unknown): value is ReadableStream =>\n value instanceof ReadableStream\n\nexport const MAX_CREDIT_WINDOW = 64\nconst MIN_CREDIT_WINDOW = 2\nconst INITIAL_CREDIT_WINDOW = 8\nconst CREDIT_BYTE_BUDGET = 4 * 1024 * 1024\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 // Captured at box time: transfer(stream) marks each chunk so transferables inside it\n // move instead of copy. Chunks that themselves carry streams re-enter the extent when\n // they are boxed, which is what makes the marker propagate through nested streams.\n const transferChunks = isInTransfer()\n\n let credit = 0\n let pumping = false\n let finished = false\n\n const finish = (message: PushMessage) => {\n finished = true\n // The terminal itself can fail to box - still close so the peer's close arm errors the consumer instead of hanging it\n try { localPort.postMessage(message) } catch {}\n localPort.close()\n }\n\n const pump = async () => {\n if (pumping || finished) return\n pumping = true\n while (credit > 0) {\n let result: ReadableStreamReadResult<unknown>\n try { result = await reader.read() }\n catch (error) {\n if (!finished) finish({ type: 'error', error: error as Capable })\n return\n }\n if (finished) return\n if (result.done) {\n finish({ type: 'end' })\n return\n }\n credit--\n const chunk = transferChunks ? forceTransfer(result.value as Capable) : result.value as Capable\n try { localPort.postMessage({ type: 'chunk', value: chunk }) }\n catch (error) {\n finish({ type: 'error', error: error as Capable })\n reader.cancel(error).catch(() => {})\n return\n }\n }\n pumping = false\n }\n\n localPort.addEventListener('message', ({ data }) => {\n if (data instanceof Promise || !('type' in data)) return\n if (data.type === 'pull') {\n // Legacy peer (osra <= 0.5.5): one boxed-Promise round trip per chunk.\n localPort.postMessage(reader.read())\n } else if (data.type === 'credit') {\n credit += data.n\n pump()\n } else if (data.type === 'cancel') {\n finished = true\n reader.cancel(data.reason).catch(() => {})\n localPort.close()\n }\n })\n localPort.addEventListener('close', () => {\n if (finished) return\n finished = true\n reader.cancel(new Error('osra: connection closed')).catch(() => {})\n }, { once: true })\n localPort.start()\n\n return { ...BoxBase, type, credit: true, port: boxedRemote } as BoxedReadableStream<T>\n}\n\nconst byteLength = (value: unknown): number | undefined =>\n ArrayBuffer.isView(value) ? value.byteLength\n : value instanceof ArrayBuffer ? value.byteLength\n : typeof value === 'string' ? value.length * 2\n : typeof Blob !== 'undefined' && value instanceof Blob ? value.size\n : undefined\n\nconst reviveCredit = (port: AnyPort<Msg>): ReadableStream => {\n let done = false\n let outstanding = 0\n let averageChunkBytes: number | undefined\n // Pipelined chunks wait here, not in the controller queue - controller.error discards queued chunks, and an early error must not eat delivered data\n const buffered: unknown[] = []\n let ended = false\n let errored = false\n let pendingError: unknown\n let waiter: {\n controller: ReadableStreamDefaultController<unknown>\n resolve: () => void\n reject: (error: unknown) => void\n } | undefined\n\n // Unmeasurable chunk types (plain objects, Maps, ...) stay at the initial window - jumping to MAX with zero byte accounting is how memory blows up\n const targetWindow = () =>\n averageChunkBytes !== undefined\n ? Math.max(MIN_CREDIT_WINDOW, Math.min(MAX_CREDIT_WINDOW, Math.floor(CREDIT_BYTE_BUDGET / averageChunkBytes)))\n : INITIAL_CREDIT_WINDOW\n\n // Half-window hysteresis: ~one credit message per target/2 chunks.\n const topUp = () => {\n const target = targetWindow()\n const ahead = outstanding + buffered.length\n if (ahead > target / 2) return\n const n = target - ahead\n outstanding += n\n port.postMessage({ type: 'credit', n })\n }\n\n const finishClose = () => {\n done = true\n queueMicrotask(() => port.close())\n }\n\n const fail = (error: unknown) => {\n errored = true\n pendingError = error\n if (!waiter || buffered.length) return\n const w = waiter\n waiter = undefined\n finishClose()\n w.reject(error)\n }\n\n return new ReadableStream({\n start: () => {\n port.addEventListener('message', ({ data }) => {\n if (data instanceof Promise || !('type' in data)) return\n if (data.type === 'chunk') {\n if (done) return\n if (outstanding <= 0) {\n buffered.length = 0\n fail(new Error('osra: stream exceeded its credit window'))\n queueMicrotask(() => port.close())\n return\n }\n outstanding--\n const size = byteLength(data.value)\n if (size !== undefined) {\n averageChunkBytes = averageChunkBytes === undefined ? size : averageChunkBytes * 0.875 + size * 0.125\n }\n if (waiter) {\n const w = waiter\n waiter = undefined\n w.controller.enqueue(data.value)\n w.resolve()\n } else buffered.push(data.value)\n } else if (data.type === 'end') {\n if (done) return\n ended = true\n if (!waiter || buffered.length) return\n const w = waiter\n waiter = undefined\n finishClose()\n w.controller.close()\n w.resolve()\n } else if (data.type === 'error') {\n if (done) return\n fail(data.error)\n }\n })\n port.addEventListener('messageerror', () => {\n if (done) return\n fail(new Error('osra: a chunk failed to deserialize on this platform'))\n })\n port.addEventListener('close', () => {\n if (done || ended || errored) return\n fail(new Error('osra: connection closed'))\n }, { once: true })\n },\n pull: (controller) => {\n if (done) return\n if (buffered.length) {\n controller.enqueue(buffered.shift())\n if (!ended && !errored) topUp()\n return\n }\n // errored before ended: a messageerror-dropped chunk followed by a clean 'end' must\n // surface as an error, never as a silently truncated stream\n if (errored) {\n finishClose()\n return Promise.reject(pendingError)\n }\n if (ended) {\n finishClose()\n controller.close()\n return\n }\n topUp()\n return new Promise<void>((resolve, reject) => { waiter = { controller, resolve, reject } })\n },\n cancel: (reason) => {\n done = true\n buffered.length = 0\n const w = waiter\n waiter = undefined\n w?.resolve()\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 })\n}\n\nconst revivePull = (port: AnyPort<Msg>): ReadableStream => {\n let done = false\n return new ReadableStream({\n start: (controller) => {\n port.addEventListener('messageerror', () => {\n if (done) return\n done = true\n try { controller.error(new Error('osra: a chunk failed to deserialize on this platform')) } catch {}\n queueMicrotask(() => port.close())\n })\n port.addEventListener('close', () => {\n if (done) return\n done = true\n try { controller.error(new Error('osra: connection closed')) } catch {}\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 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 queueMicrotask(() => port.close())\n },\n })\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 // A box that doesn't advertise credit (osra <= 0.5.5) cancels on any unknown message, so it must only ever be spoken to in pull\n return (value.credit ? reviveCredit(port) : revivePull(port)) 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 { isInTransfer, forceTransfer } from './transfer.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 per call\nexport type WriteContext =\n | { type: 'write', chunk: Capable }\n | { type: 'close' }\n | { type: 'abort', reason: Capable }\n\n// reply box -> revive after a write completes, which is what lets writer.write() await\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 // transferChunks rides the wire because chunks originate on the revive side; old peers ignore it\n & { port: BoxedMessagePort<Msg>, transferChunks?: true }\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 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 // A write the platform failed to deserialize would otherwise never be acked, hanging the writer.\n localPort.addEventListener('messageerror', () => {\n localPort.postMessage({ type: 'err', error: 'osra: a chunk failed to deserialize on this platform' })\n })\n // Abnormal channel death: abort the 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 {\n ...BoxBase,\n type,\n port: boxedRemote,\n ...(isInTransfer() ? { transferChunks: true as const } : {}),\n } 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 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 // The port is shared, so we serialize via a chain - concurrent writes would 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 const transferChunks = value.transferChunks === true\n return new WritableStream({\n write: (chunk) => request({ type: 'write', chunk: (transferChunks ? forceTransfer(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 while the revived signal is reachable - 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 // Must box the reason here - 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 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 // 101/204/205/304 forbid a body, so cancel the boxed stream to stop the sender pushing into a dead port\n const stream = value.body ? reviveReadableStream(value.body, context) : null\n const isNullBodyStatus =\n value.status === 101 || value.status === 204 || value.status === 205 || value.status === 304\n if (stream && isNullBodyStatus) stream.cancel().catch(() => {})\n const body = isNullBodyStatus ? null : stream\n\n const response = new Response(body, {\n status: value.status,\n statusText: value.statusText,\n headers\n })\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 turns `body: null` into a `.body` getter returning `undefined`, so only pass `body` when there's a stream\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 { boxClaimedValue, recursiveRevive } from './index.js'\nimport { isTornDown, 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\n/** Phantom shape. A tracked value carries no marker of its own, the mark lives in a WeakMap, so\n * this is what `isType` declares instead: matching it at the type level would widen `Capable` to\n * every object, and nothing a user writes structurally matches this. */\ntype IdentityMarked = { readonly [IDENTITY_MARKER]: true }\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\n/** Reference to id, for the whole realm rather than one connection. The id is minted once, wherever\n * the reference first became an identity - `identity()` here, or reviving one from a peer - and\n * from then on it travels with the value onto every connection it is sent over. That is what makes\n * a value keep its identity down a chain of contexts: each hop hands the same id to the next, so\n * the value coming back resolves to what that hop handed out, all the way to the origin. */\nconst valueToId = new WeakMap<WeakKey, string>()\n\nconst idFor = (value: WeakKey): string => {\n const existing = valueToId.get(value)\n if (existing !== undefined) return existing\n const id = globalThis.crypto.randomUUID()\n valueToId.set(value, id)\n return id\n}\n\n/** Mark a value so osra preserves its reference identity across the boundary. The peer's revived\n * value stands for this one, and handing it back - to you, or onward to a further context and back\n * again - resolves to this very reference. The mark sticks to the value, so only the side that\n * owns it has to opt in. Idempotent, and primitives pass through unchanged. */\nexport const identity = <T>(value: T): T => {\n if (isObjectOrFunction(value)) idFor(value)\n return value\n}\n\ntype IdentityState = {\n /** Every id that has crossed this connection, either way, mapped to what it denotes on this side.\n * `has` doubles as \"the peer can resolve this id\", which is what lets a resend skip the payload.\n * Weak, because an entry outliving its value would resolve to nothing anyway. */\n readonly idToLocal: Map<string, WeakRef<WeakKey>>\n /** Values revived from this peer, held until the peer says its own reference is gone: it can send\n * the bare id at any time and expects this exact value back. */\n readonly pins: Map<string, unknown>\n readonly disposeRegistry: FinalizationRegistry<string>\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 idToLocal = new Map<string, WeakRef<WeakKey>>()\n const pins = new Map<string, unknown>()\n const disposeRegistry = new FinalizationRegistry<string>((id) => {\n idToLocal.delete(id)\n if (isTornDown(context)) return\n try {\n context.sendMessage({ type: 'identity-dispose', remoteUuid: context.remoteUuid, id })\n } catch { /* connection already closed */ }\n })\n const state: IdentityState = { idToLocal, pins, disposeRegistry }\n connectionStates.set(context, state)\n context.eventTarget.addEventListener('message', ({ detail }) => {\n if (detail?.type !== 'identity-dispose') return\n state.pins.delete(detail.id)\n // Dropped too, not just unpinned: the peer's reference is gone, so a later send of our own value\n // has to carry the payload again instead of a bare id nothing over there could resolve.\n state.idToLocal.delete(detail.id)\n })\n onTeardown(context, () => {\n state.pins.clear()\n state.idToLocal.clear()\n })\n return state\n}\n\nexport const isType = (value: unknown): value is IdentityMarked =>\n isObjectOrFunction(value) && valueToId.has(value)\n\n/** The shared tail of both box paths: hand the peer the id alone when it can already resolve it,\n * and otherwise the id plus the payload, remembering that this peer now knows it. */\nconst boxTracked = (\n value: WeakKey,\n buildInner: () => Capable,\n state: IdentityState,\n): BoxedIdentity => {\n const id = idFor(value)\n if (state.idToLocal.has(id)) return { ...BoxBase, type, id } as BoxedIdentity\n // Before recording the id, so a value containing itself still hits the cycle guard rather than\n // shipping a self-reference the peer could never revive.\n const inner = buildInner()\n state.idToLocal.set(id, new WeakRef(value))\n // The peer holds its revived value until we tell it this one is gone.\n state.disposeRegistry.register(value, id)\n return { ...BoxBase, type, id, inner } as BoxedIdentity\n}\n\nexport const box = <T extends Capable, TContext extends RevivableContext>(\n value: T,\n context: TContext,\n): BoxedIdentity<T> => {\n const state = getOrCreateState(context)\n const buildInner = () => boxClaimedValue(value, context, type) as Capable\n if (!isWeakKeyable(value)) {\n return { ...BoxBase, type, id: globalThis.crypto.randomUUID(), inner: buildInner() } as BoxedIdentity<T>\n }\n return boxTracked(value, buildInner, state) as BoxedIdentity<T>\n}\n\n/** Identity-box a referenceable value with a caller-supplied inner box, bypassing the walker. Used\n * by revivables (symbol with 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 boxTracked(value, () => innerBox, getOrCreateState(context))\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 if (state.pins.has(value.id)) return state.pins.get(value.id) as T[UnderlyingType]\n const known = state.idToLocal.get(value.id)?.deref()\n if (known !== undefined) return known 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 nothing local to resolve it to`)\n }\n const revived = recursiveRevive(value.inner, context)\n state.pins.set(value.id, revived)\n if (isWeakKeyable(revived)) {\n // Carries the id onward: sending this value to a further context sends it under the same id, so\n // whatever comes back through the chain lands on this very value again.\n if (!valueToId.has(revived)) valueToId.set(revived, value.id)\n state.idToLocal.set(value.id, new WeakRef(revived))\n }\n return revived as T[UnderlyingType]\n}\n\nconst typeCheck = () => {\n const fn = () => 42\n const boxed = box(fn, {} 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 value (WeakMap not assignable)\n box(new WeakMap<object, string>(), {} as RevivableContext)\n const marked: typeof fn = identity(fn)\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 Capable ↔ defaultRevivableModules ↔ this module type cycle\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\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 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 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; the source-side EventTarget owns all semantics.\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 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 - the FR strong-holds it.\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 } 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 const registryKey = Symbol.keyFor(value)\n if (registryKey !== undefined) return { ...BoxBase, type, registryKey }\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 revivable\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, isJsonOnlyTransport } from '../utils/type-guards.js'\n\ntype AnyCtor = abstract new (...args: any[]) => unknown\n\n// clonable is a pass-through fast path that short-circuits findBoxModule so unclonable's structuredClone probe never fires on a known-safe value\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 Capable union on JSON transports\n// it is a marker flag because TS can't narrow `isType<Ctx>` through generic inference\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 // `revive` is 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// getTransferableObjects pulls these out of the envelope at send time\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// Must sit after clonable so File keeps riding it\nexport type BoxedBlob = BoxBaseType<'blob'>\n\nconst isBlob = (value: unknown): value is Blob =>\n typeof Blob !== 'undefined' && value instanceof Blob\n\nexport const blob = {\n type: 'blob',\n capableOnly: true,\n isType: isBlob,\n box: (value: Blob, context: RevivableContext<any>): Blob => {\n if (isJsonOnlyTransport(context.transport)) {\n throw new TypeError('osra: Blob is only supported on structured-clone transports, send an ArrayBuffer or Uint8Array instead')\n }\n return value\n },\n revive: (value: BoxedBlob, _context: RevivableContext<any>): Blob => value as unknown as Blob,\n} as const\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\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, undefined vanishes\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 symbol from './symbol.js'\nimport * as asyncIterator from './async-iterator.js'\nimport { blob, 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: the bivariance escape hatch that 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 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, before the fallbacks so generators don't coerce to {}.\n asyncIterator,\n nonFiniteNumber,\n undefinedValue,\n // clonable/transferable before eventTarget: OffscreenCanvas & co. also extend EventTarget.\n clonable,\n transferable,\n // After clonable (File rides it): bare Blobs would otherwise silently coerce to `{}` on JSON.\n blob,\n // eventTarget MUST be last among instanceof-EventTarget revivables - the specific ones need first dibs.\n eventTarget,\n unclonable,\n] as const\n\nexport type DefaultRevivableModules = typeof defaultRevivableModules\nexport type DefaultRevivableModule = DefaultRevivableModules[number]\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// Box/revive are fully synchronous, so a module-global set with balanced enter/exit is safe; tracking the *path* (not all visited values) keeps sibling aliasing working.\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\nconst boxDispatch = <\n T extends Capable,\n TModules extends readonly RevivableModule[]\n>(\n value: T,\n context: RevivableContext<TModules>,\n skipType?: string,\n): DeepReplaceWithBox<T, TModules[number]> => {\n type ReturnCastType = DeepReplaceWithBox<T, TModules[number]>\n const handledByModule = context.revivableModules.find(\n module => module.type !== skipType && module.isType(value)\n )\n if (handledByModule) {\n return handledByModule.box(value, context) as ReturnCastType\n }\n return descend<ReturnCastType>(value, v => recursiveBox(v, context))\n}\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 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 return boxDispatch(value, context)\n } finally {\n if (track) boxPath.delete(value)\n }\n}\n\n/** Box a value your own module claimed in place: every other module gets its turn and children are\n * walked as usual, but `claimedBy` is skipped, and the cycle guard the caller's `recursiveBox`\n * frame already holds for this value is not re-entered.\n * A module needs this when its `isType` matches a bare value rather than a wrapper around one, the\n * way `identity()` marks a reference in place: `recursiveBox` on that same value would come\n * straight back to the module, and the guard would report it as a cycle. */\nexport const boxClaimedValue = <\n T extends Capable,\n TModules extends readonly RevivableModule[]\n>(\n value: T,\n context: RevivableContext<TModules>,\n claimedBy: string,\n): DeepReplaceWithBox<T, TModules[number]> =>\n boxDispatch(value, context, claimedBy)\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 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 { Context, 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, peer } }) => {\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 back after our reply), not a collision\n if (ctx.connectionContexts.has(message.uuid)) return\n ctx.sendMessage({ type: 'announce', remoteUuid: message.uuid })\n const eventTarget = ctx.createConnectionEventTarget()\n const connectionContextValues = { ...peer(), abort: () => ctx.abortConnection(message.uuid) }\n let connection: ReturnType<typeof startBidirectionalConnection<TModules>>\n try {\n // Built BEFORE the connection starts, because starting it sends our value: a factory that calls ctx.abort() has to be observable before the value goes out\n const built = ctx.valueFor(connectionContextValues)\n if (ctx.claimPendingAbort(message.uuid)) {\n ctx.sendMessage({ type: 'close', remoteUuid: message.uuid })\n return\n }\n connection = startBidirectionalConnection<TModules>({\n transport: ctx.transport,\n value: built,\n remoteUuid: message.uuid,\n eventTarget,\n send: (m) => ctx.sendMessage(m as MessageVariant),\n revivableModules: ctx.revivableModules\n })\n } catch (error) {\n // Surface it locally instead of swallowing it inside EventTarget dispatch, AND tell the peer, or its own expose() waits on a handshake that will never come\n ctx.sendMessage({ type: 'close', remoteUuid: message.uuid })\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.addConnection(connectionContextValues, 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 must not leave the caller pending forever\n ctx.rejectRemoteValue(new Error('osra: peer closed the connection'))\n return\n }\n if (message.remoteUuid !== ctx.getUuid()) return\n const connection = ctx.connectionContexts.get(message.uuid)\n if (!connection) return\n connection.eventTarget.dispatchEvent(\n new CustomEvent('message', { detail: message })\n )\n })\n\n if (ctx.presetRemoteUuid !== undefined) {\n const presetRemoteUuid = ctx.presetRemoteUuid\n const eventTarget = ctx.createConnectionEventTarget()\n let connection: ReturnType<typeof startBidirectionalConnection<TModules>>\n let presetContextValues: Context\n try {\n presetContextValues = { abort: () => ctx.abortConnection(presetRemoteUuid) }\n const built = ctx.valueFor(presetContextValues)\n if (ctx.claimPendingAbort(presetRemoteUuid)) {\n ctx.sendMessage({ type: 'close', remoteUuid: presetRemoteUuid })\n return\n }\n connection = startBidirectionalConnection<TModules>({\n transport: ctx.transport,\n value: built,\n remoteUuid: ctx.presetRemoteUuid,\n eventTarget,\n send: (m) => ctx.sendMessage(m as MessageVariant),\n revivableModules: ctx.revivableModules\n })\n } catch (error) {\n ctx.sendMessage({ type: 'close', remoteUuid: presetRemoteUuid })\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.addConnection(presetContextValues, remoteValue),\n (error) => ctx.rejectRemoteValue(error),\n )\n return\n }\n\n // Posted with '*' instead of the configured origin: until a cross-origin iframe commits, its window still holds the initial about:blank document, so a strict targetOrigin fails the browser's delivery check\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 try { ctx.sendMessage({ type: 'announce' }, '*') } catch {}\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 { Context, 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 { emit: webSocket } is JSON-only even though the wrapper is not\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 // `peer` MUST stay a thunk: eager building runs the caller's context builder on every RPC frame and stream chunk instead of once per connection\n message: CustomEvent<{ message: Message<TModules>, peer: () => Context }>\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 /** The exposed value for ONE peer. A factory rather than a value so a server can answer each realm\n * differently (scoped resolvers per origin) instead of sharing one object across every connection. */\n valueFor: (peer: Context) => Capable<TModules>\n revivableModules: TModules\n connectionContexts: Map<string, ConnectionContext<TModules>>\n getUuid: () => Uuid\n presetRemoteUuid?: Uuid\n /** targetOrigin overrides the configured origin for this one send - only\n * the unsolicited announce beacon broadcasts with '*'. */\n sendMessage: (message: MessageVariant, targetOrigin?: string) => void\n protocolEventTarget: ProtocolEventTarget<TModules>\n rejectRemoteValue: (error: unknown) => void\n /** reports an established connection: settles the first-connection promise and feeds iteration, so\n * a caller sees every realm rather than only the one that happened to connect first */\n addConnection: (ctx: Context, value: Capable<TModules>) => void\n /** tears down one connection: close to the peer, teardown locally, drop it from tracking */\n abortConnection: (remoteUuid: Uuid) => void\n /** true when this uuid was aborted before it was registered, which means refuse the registration */\n claimPendingAbort: (remoteUuid: Uuid) => boolean\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 /** Decides what one connection resolves to, for the await and for iteration alike. Omit it and that\n * is the peer's value, which is what `expose` has always given back:\n *\n * ```ts\n * const remote = await expose(api, { transport })\n *\n * const { value, context } = await expose(api, {\n * transport,\n * connection: ({ value, context }) => ({ value, context }),\n * })\n *\n * for await (const origin of expose(api, {\n * transport,\n * connection: ({ context }) => context.origin,\n * })) { }\n * ```\n *\n * It runs per connection, on this side, after the handshake. It cannot change what is sent, and\n * nothing it returns crosses the wire. */\n connection?: (connected: Connected<unknown>) => unknown\n}\n\n/** An established connection: the value that realm exposed, and what this side knows about the realm\n * it came from. `context` is whatever the transport observed, plus an `abort` that drops this one\n * peer. Anything derived from it is the caller's to compute, in the value factory or in\n * `connection:`, rather than something to declare up front. */\nexport type Connected<TValue> = {\n value: TValue\n context: Context\n}\n\n/** The result of `expose`. Awaiting it gives the first peer, iterating it gives every peer as it\n * connects, and both hand back the same thing: one shape, read once or read repeatedly.\n *\n * What that shape IS comes from the `connection:` option. Without one it is the peer's value, which\n * is what `expose` has always resolved to. With one it is whatever that function returns. */\nexport type Exposed<TResult> = Promise<TResult> & AsyncIterable<TResult>\n\nexport type ConnectionQueue<TRemote> = {\n push: (connection: Connected<TRemote>) => void\n close: () => void\n iterate: () => AsyncIterableIterator<Connected<TRemote>>\n}\n\n// bounds what a consumer that never iterates retains: each buffered connection pins a Remote proxy and a window or MessagePort\n/** Multicast: every iterator sees every peer, rather than several loops sharing one cursor and each\n * taking a slice. Two loops watching one server both mean \"tell me about every peer\", and a shared\n * cursor makes whichever one happens to be waiting eat the peer the other was waiting for. */\n/** Until someone asks to iterate, a connection is buffered only up to this many. Every consumer that\n * just awaits the first connection would otherwise retain every later one for the transport's life,\n * each pinning a Remote proxy and a window or MessagePort. Buffering a few keeps the ordinary\n * \"expose now, iterate on the next tick\" case lossless; a consumer that never iterates cannot leak. */\nconst PRE_ITERATION_BUFFER = 32\n\n/** @internal protocol plumbing, not part of the public api */\nexport const createConnectionQueue = <TRemote>(): ConnectionQueue<TRemote> => {\n type Result = IteratorResult<Connected<TRemote>>\n type Subscriber = { buffered: Connected<TRemote>[], wake?: (result: Result) => void }\n // copied into each new iterator, never drained: draining would let whichever loop iterated first decide what the others never see\n const early: Connected<TRemote>[] = []\n const subscribers = new Set<Subscriber>()\n let closed = false\n const done = () => ({ value: undefined as never, done: true as const })\n return {\n push: (connection) => {\n if (closed) return\n if (subscribers.size === 0) {\n early.push(connection)\n if (early.length > PRE_ITERATION_BUFFER) early.shift()\n return\n }\n for (const subscriber of subscribers) {\n const wake = subscriber.wake\n if (wake) { subscriber.wake = undefined; wake({ value: connection, done: false }); continue }\n subscriber.buffered.push(connection)\n }\n },\n close: () => {\n closed = true\n for (const subscriber of subscribers) {\n const wake = subscriber.wake\n subscriber.wake = undefined\n wake?.(done())\n }\n },\n iterate: () => {\n // per iterator, not shared: a waiter left behind by an abandoned iterator would swallow the next connection\n const subscriber: Subscriber = { buffered: [...early] }\n subscribers.add(subscriber)\n let finished = false\n return {\n [Symbol.asyncIterator]() { return this },\n next: () => {\n if (finished) return Promise.resolve(done())\n const next = subscriber.buffered.shift()\n if (next) return Promise.resolve({ value: next, done: false as const })\n if (closed) return Promise.resolve(done())\n return new Promise<Result>((resolve) => { subscriber.wake = resolve })\n },\n return: () => {\n finished = true\n subscribers.delete(subscriber)\n const wake = subscriber.wake\n subscriber.wake = undefined\n wake?.(done())\n return Promise.resolve(done())\n },\n }\n },\n }\n}\n\n/** The awaited-and-iterable result, with every connection passed through `select` first. The promise\n * is DERIVED from the first-connection promise, so it needs its own no-op catch: a fire-and-forget\n * `expose(...)` handles the original, and an unhandled derived rejection would still reach the\n * console. */\n/** @internal not part of the public api */\nexport const asExposed = <T, TResult>(\n first: Promise<Connected<T>>,\n queue: ConnectionQueue<T>,\n select: (connected: Connected<T>) => TResult,\n): Exposed<TResult> => {\n const result = first.then(select)\n // `result` is derived, so it needs its own no-op catch even when the caller handles the original\n result.catch(() => {})\n // do not replace with an async generator: one suspended at `await` defers `return()` until that await settles, so abandonment would hang\n const iterate = (): AsyncIterableIterator<TResult> => {\n const inner = queue.iterate()\n return {\n [Symbol.asyncIterator]() { return this },\n next: () =>\n inner.next().then(step =>\n step.done\n ? { value: undefined as never, done: true as const }\n : { value: select(step.value), done: false as const }),\n return: () =>\n inner.return?.() as Promise<IteratorResult<TResult>>\n ?? Promise.resolve({ value: undefined as never, done: true as const }),\n }\n }\n return Object.assign(result, { [Symbol.asyncIterator]: iterate }) as Exposed<TResult>\n}\n\n/** An exposed value can itself be a function - osra exposes functions as endpoints - so a bare\n * `typeof value === 'function'` cannot tell a per-peer factory from a plain function value. The\n * marker makes the intent explicit and unambiguous. */\n/** @internal */\nexport const CONTEXT = Symbol.for('osra.context')\n\nexport type Contextual<TValue> = {\n [CONTEXT]: (ctx: Context) => TValue\n}\n\n/** Build the exposed value once per connection, from that connection's context, rather than sharing\n * one value across every realm that connects. It runs BEFORE the value is boxed and sent, which is\n * what lets one server answer each realm differently:\n *\n * ```ts\n * expose(context(({ origin }) => resolvers(idFor(origin))), { transport })\n * ```\n *\n * A wrapper rather than \"pass a function\", because osra exposes functions as endpoints, so a bare\n * `typeof value === 'function'` cannot tell a per-peer factory from a plain function value.\n *\n * What the read side needs is not declared here: `connection:` sees the same context and derives its\n * own. */\nexport const context = <TValue,>(make: (ctx: Context) => TValue): Contextual<TValue> =>\n ({ [CONTEXT]: make })\n\n/** @internal */\nexport const isContextual = <TValue,>(value: unknown): value is Contextual<TValue> =>\n typeof value === 'object' && value !== null && CONTEXT in value\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, Context } from '../utils/transport.js'\nimport type { Connected, Contextual, Exposed } from './utils.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 { asExposed, createConnectionQueue, isContextual, mergeRevivableModules, normalizeTransport, CONTEXT } 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> for the same bivariance reason as RevivableModule.box\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 TResult = T\n>(\n value: Capable<TModules> | Contextual<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 // type-level counterpart is `TResult`'s default in src/index.ts: those two state the same fact separately and have to move together\n connection: selectConnection = ({ value }) => value,\n }: StartConnectionsOptions<TModules>\n): Exposed<TResult> => {\n const select = selectConnection as (connected: Connected<T>) => TResult\n const transport = normalizeTransport(_transport)\n if (!(isEmitTransport(transport) && isReceiveTransport(transport))) {\n const queue = createConnectionQueue<T>()\n queue.close()\n const rejected = Promise.reject(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 rejected.catch(() => {})\n return asExposed<T, TResult>(rejected, queue, select)\n }\n const mergedRevivableModules = mergeRevivableModules<TModules>(configureRevivableModules)\n type MergedModules = typeof mergedRevivableModules\n const connectionContexts = new Map<string, ConnectionContext<MergedModules>>()\n\n const pendingAborts = new Set<string>()\n\n const connectionQueue = createConnectionQueue<T>()\n\n const { promise: firstConnection, resolve: resolveFirstConnection, reject: rejectRemoteValue } =\n Promise.withResolvers<Connected<T>>()\n // Keeps a fire-and-forget `expose(value, …)` from surfacing an unhandled rejection on abort/close\n firstConnection.catch(() => {})\n\n const uuid: Uuid = _uuid ?? globalThis.crypto.randomUUID()\n\n const sendEnvelope = (message: MessageVariant, targetOrigin: string = origin) => {\n const envelope = { [OSRA_KEY]: key, name, uuid, ...message }\n sendOsraMessage(transport, envelope, targetOrigin, getTransferableObjects(envelope))\n }\n\n const sendMessage = (message: MessageVariant, targetOrigin?: string) => {\n if (unregisterSignal?.aborted) return\n sendEnvelope(message, targetOrigin)\n }\n\n const protocolEventTarget = createTypedEventTarget<{ message: CustomEvent<{ message: Message<MergedModules>, peer: () => Context }> }>()\n\n const ctx: ProtocolContext<MergedModules> = {\n transport,\n valueFor: (peer: Context) =>\n (isContextual<Capable<MergedModules>>(value)\n ? value[CONTEXT](peer)\n : value) as Capable<MergedModules>,\n revivableModules: mergedRevivableModules,\n connectionContexts,\n getUuid: () => uuid,\n presetRemoteUuid,\n sendMessage,\n protocolEventTarget,\n rejectRemoteValue,\n abortConnection: (remoteUuid: Uuid) => {\n const connectionContext = connectionContexts.get(remoteUuid)\n // Raised from inside the value factory, which runs BEFORE the connection is registered\n if (!connectionContext) { pendingAborts.add(remoteUuid); return }\n connectionContexts.delete(remoteUuid)\n sendEnvelope({ type: 'close', remoteUuid })\n runTeardown(connectionContext.connection.revivableContext)\n rejectRemoteValue(new Error('osra: connection aborted'))\n },\n claimPendingAbort: (remoteUuid) => pendingAborts.delete(remoteUuid),\n addConnection: (ctx, value) => {\n const connection = { value: value as T, context: ctx }\n resolveFirstConnection(connection)\n connectionQueue.push(connection)\n },\n createConnectionEventTarget: createTypedEventTarget,\n unregisterSignal,\n }\n\n const listener = (message: Message, messageContext: MessageContext) => {\n if (message.uuid === uuid) return\n // Built from LOCAL knowledge only: nothing from the peer's payload participates, and none of it is ever sent back\n const peer = (): Context => ({\n ...(messageContext.origin ? { origin: messageContext.origin } : {}),\n ...(messageContext.source ? { source: messageContext.source } : {}),\n ...(messageContext.port ? { port: messageContext.port } : {}),\n ...(messageContext.sender ? { sender: messageContext.sender } : {}),\n })\n protocolEventTarget.dispatchEvent(\n new CustomEvent('message', { detail: { message: message as Message<MergedModules>, peer } }),\n )\n }\n\n registerOsraMessageListener({\n listener,\n transport,\n remoteName,\n key,\n origin,\n unregisterSignal\n })\n\n // an already-aborted signal's 'abort' event has fired and will never fire again, so the listener below would leave the promise pending forever\n if (unregisterSignal?.aborted) {\n rejectRemoteValue(unregisterSignal.reason)\n connectionQueue.close()\n return asExposed<T, TResult>(firstConnection, connectionQueue, select)\n }\n\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 // the other two exit paths close the queue; without this a `for await` over connections never terminates\n connectionQueue.close()\n rejectRemoteValue(unregisterSignal.reason)\n }, { once: true })\n\n for (const connectionModule of connections) {\n connectionModule.init(ctx)\n }\n\n return asExposed<T, TResult>(firstConnection, connectionQueue, select)\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 { Connected, Contextual, Exposed, StartConnectionsOptions } from './connections/utils.js'\nimport type { Context, Transport } from './utils/transport.js'\nimport type { IsJsonOnlyTransport } from './utils/type-guards.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// named for the revivable context specifically: `ContextOf` is the PUBLIC helper for a connection\n// context builder, re-exported from connections/utils, and two of them in one module is a trap\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.\n * Named for the revivable context specifically: `ContextOf` is the PUBLIC helper for a connection\n * context builder, re-exported from connections/utils, and two of them in one module is a trap. */\ntype RevivableContextOf<TTransport extends Transport> = RevivableContext & { transport: TTransport }\n\n// picks between two error texts: when the value fails ONLY because the transport is JSON (it would\n// pass under the broad `RevivableContext`, whose transport union resolves to structured-clone\n// semantics), blame the transport instead of the value\n/** Error text for a failed check. When the value only fails because the\n * transport is JSON (it would pass under the broad `RevivableContext`,\n * whose transport union resolves to structured-clone semantics), blame\n * the transport instead of the value. */\ntype CapableCheckMessage<\n T,\n TModules extends readonly RevivableModule[],\n Ctx extends RevivableContext,\n> =\n IsJsonOnlyTransport<Ctx['transport']> extends true\n ? [T] extends [Capable<TModules, RevivableContext>]\n ? 'Value type is only supported on structured-clone transports, not on JSON transports'\n : 'Value type must resolve to a Capable'\n : 'Value type must resolve to a Capable'\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]: CapableCheckMessage<T, TModules, Ctx>\n [BadValue]: BadFieldValue<T, Capable<TModules, Ctx>>\n [Path]: BadFieldPath<T, Capable<TModules, Ctx>>\n [ParentObject]: BadFieldParent<T, Capable<TModules, Ctx>>\n }\n\n/**\n * Expose a value to whoever connects, and get back what they exposed.\n *\n * Wrap `value` in `context` to build it once per connection, which is what lets one server answer\n * each realm differently (scoped resolvers per app) instead of sharing one object across all of them.\n * A bare function stays a plain exposed endpoint, so the wrapper is what disambiguates the two.\n *\n * The result is both awaitable and async-iterable: awaiting gives the first peer, iterating gives\n * every peer as it connects. Both hand back the same shape.\n *\n * ```ts\n * const remote = await expose(resolvers, { transport }) // the first peer's value\n * for await (const remote of expose(resolvers, { transport })) { } // every peer's value\n * ```\n *\n * `connection` decides what that shape is. Omit it and it is the peer's value, which is what expose\n * has always resolved to. Return whatever a connection should mean instead:\n *\n * ```ts\n * const { value, context } = await expose(resolvers, {\n * transport,\n * connection: ({ value, context }) => ({ value, context }),\n * })\n *\n * for await (const peer of expose(resolvers, {\n * transport,\n * connection: ({ value, context }) => ({ value, context }),\n * })) {\n * if (!allowed(peer.context.origin)) peer.context.abort?.()\n * }\n * ```\n *\n * A peer's identity is whatever the transport can observe merged over whatever the caller declared\n * in `context`. Only a window message carries a browser-set origin and source; a MessagePort message\n * carries neither, so a port-based server declares what it learned when it received the port.\n * Observed fields win over declared ones, so a declaration can never spoof a real origin.\n */\nexport const expose = <\n T = unknown,\n const TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n const TTransport extends Transport = Transport,\n // after TValue, not before it: these are positional, so slotting a new one into the middle\n // silently reassigns every explicit type argument a consumer already wrote\n const TValue = Capable<TModules, RevivableContextOf<TTransport>>,\n TResult = Remote<T>\n>(\n value:\n | CapableCheck<TValue, TModules, RevivableContextOf<TTransport>>\n | Contextual<CapableCheck<TValue, TModules, RevivableContextOf<TTransport>>>,\n // intersecting instead of omitting gives `connection` two signatures at once, and its parameter\n // degrades to a union of both\n options: Omit<StartConnectionsOptions<TModules>, 'connection'> & {\n transport: TTransport\n connection?: (connected: Connected<Remote<T>>) => TResult\n }\n): Exposed<TResult> =>\n startConnections<Remote<T>, TModules, TResult>(\n value as Capable<TModules> | Contextual<Capable<TModules>>,\n options as StartConnectionsOptions<TModules>\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/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\n/* `ReadonlyArray` throughout these unions: `expose()` infers its value with a `const` type parameter, so inline array literals arrive as readonly tuples and must stay assignable. */\nexport type Jsonable =\n | boolean\n | null\n | number\n | string\n | { [key: string]: Jsonable }\n | ReadonlyArray<Jsonable>\n\nexport type Structurable =\n | Jsonable\n // not really structureable but here for convenience.\n // A `/** */` here would be a doc comment on the union MEMBER, which makes typedoc render the\n // whole union as a 20 entry \"Union Members\" wall on the generated reference page.\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 | ReadonlyArray<Structurable>\n | Map<Structurable, Structurable>\n | Set<Structurable>\n\n/** lib.dom declares some `Transferable` members as EMPTY interfaces\n * (`MediaSourceHandle` as of TS 5.x/7.x). With no members they structurally\n * absorb every object type, which would let `WeakMap` & co. slip past the\n * `Capable` check unnoticed. Drop member-less types from the compile-time\n * union; runtime transfer of those exotic types is unaffected. */\ntype NonAbsorbing<T> = T extends unknown ? keyof T extends never ? never : T : never\n\nexport type StructurableTransferable =\n | Structurable\n | NonAbsorbing<Transferable>\n | { [key: string]: StructurableTransferable }\n | ReadonlyArray<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`/`File`/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 | ReadonlyArray<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), containers map recursively,\n * 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 Promise<infer U> ? Promise<Remote<U>>\n // these three carry values that are boxed and revived like any other, so what you read out of them\n // on this side is the REMOTE shape: a Map of functions hands you promise-returning ones. A\n // WritableStream is the other way round, you write local values into it, so it passes through\n : T extends Map<infer K, infer V> ? Map<Remote<K>, Remote<V>>\n : T extends Set<infer V> ? Set<Remote<V>>\n : T extends ReadableStream<infer C> ? ReadableStream<Remote<C>>\n : T extends\n | Date | Error | RegExp\n | ArrayBuffer | ArrayBufferView | Blob | File | FileList\n | 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 { Message} from '../types.js'\nimport type {\n WebExtGlobal, WebExtOnConnect, WebExtOnMessage,\n WebExtPort, WebExtRuntime, WebExtSender\n} from './webext-types.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\n/** What the local side knows about the realm on the other end of a connection.\n *\n * `origin` and `source` are only OBSERVABLE on window transports. A MessagePort message carries\n * origin \"\" and source null, so for a port the identity has to be declared by whoever created the\n * transport, which is the side that received the port over a trustworthy window message. That is why\n * `expose` takes a `context` option rather than only reporting what it can see: without it, every\n * port-based consumer would rebuild the same out-of-band handshake to learn who it is talking to. */\nexport type Context = {\n /** Tears down THIS connection and nothing else: the peer is sent a close, its revivables are torn\n * down, and it stops being tracked. `unregisterSignal` is the whole-expose equivalent; this is the\n * one a server reaches for when a single realm misbehaves or is finished with. */\n abort?: () => void\n origin?: string\n source?: MessageEventSource | null\n port?: MessagePort | WebExtPort\n sender?: WebExtSender\n}\n\nexport type MessageContext = {\n port?: MessagePort | WebExtPort // WebExtension only\n sender?: WebExtSender // WebExtension only\n receiveTransport?: ReceivePlatformTransport\n source?: MessageEventSource | null // Window, Worker, WebSocket\n origin?: string // Window only\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\n// typed structurally because lib.webworker can't be loaded next to lib.dom (conflicting `self` declarations)\nexport type WorkerSelf = {\n postMessage(...args: any[]): void\n addEventListener(type: string, listener: (event: any) => void): void\n removeEventListener(type: string, listener: (event: any) => void): void\n}\n\nexport type EmitPlatformTransport =\n | EmitJsonPlatformTransport\n | Window\n | ServiceWorker\n | Worker\n | SharedWorker\n | MessagePort\n | WorkerSelf\n\nexport type ReceivePlatformTransport =\n | ReceiveJsonPlatformTransport\n | Window\n | ServiceWorkerContainer\n | Worker\n | SharedWorker\n | MessagePort\n | WorkerSelf\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// Structural shapes from ./webext-types, never the polyfill's own module types: an import of those\n// would land in the published .d.ts, where the consumer may have nothing to resolve it to. Naming the\n// ambient `browser`/`chrome` globals here would leak unresolvable names the same way.\ntype WebExtGlobals = { browser?: WebExtGlobal, chrome?: WebExtGlobal }\nexport const getWebExtensionGlobal = (): WebExtGlobal | 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 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 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 {\n listenOnWebExtOnMessage(receiveTransport.onMessage as WebExtOnMessage)\n }\n return\n }\n\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 and ServiceWorkerContainer events carry their own unrelated origins\n const filterByOrigin = origin !== '*' && isWindow(receiveTransport)\n const messageListener = (event: MessageEvent<Message | string>) => {\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 .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\n// A WebExtension port THROWS on postMessage once it is disconnected, where a MessagePort silently no-ops\n// (measured: neither engine throws or logs for a MessagePort, in any disentanglement route). Firefox says\n// \"Attempt to postMessage on disconnected port\", Chromium \"Attempting to use a disconnected port object\".\n// Every message on a port transport funnels through here, so a revivable still talking while the other end\n// tears down - a stream topping up its credit window - throws on every message, not once.\nconst disconnectedPorts = new WeakSet<WebExtPort>()\n\nconst isDisconnectedPortError = (error: unknown): boolean =>\n String((error as { message?: unknown })?.message ?? error).includes('disconnected port')\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 // A disconnected port is ordinary teardown, not a fault; anything else here is a real bug and must stay visible\n if (disconnectedPorts.has(emitTransport)) return\n try {\n emitTransport.postMessage(message)\n } catch (error) {\n if (!isDisconnectedPortError(error)) throw error\n disconnectedPorts.add(emitTransport)\n }\n } else if (isWebExtensionRuntime(emitTransport)) {\n // Rejects while no receiver exists yet (announce retries) - swallow only that\n emitTransport.sendMessage(message)?.catch?.((error: unknown) => {\n if (!String((error as { message?: unknown })?.message).includes('Receiving end does not exist')) throw error\n })\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 {\n emitTransport.postMessage(message, transferables)\n }\n}\n","import 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'\nimport type {\n WebExtOnConnect, WebExtOnMessage, WebExtPort, WebExtRuntime, WebExtSender\n} from './webext-types.js'\n\nimport { OSRA_KEY } from '../types.js'\nimport { getWebExtensionRuntime } from './transport.js'\n\n// Pulled from globalThis so module evaluation does not crash on platforms that have not shipped Float16Array yet (Node <= 23, Chrome <= 134, Firefox <= 128)\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) resolve to the nearest TypedArray ancestor\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 instanceOfAny(value, typedArrayConstructors)\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\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 // `instanceof` is false for every primitive by definition, and this runs on every leaf of every\n // boxed value, several times over, so the walk should not pay for a dozen prototype lookups to\n // learn that a string is not an ImageBitmap.\n if (value === null || (typeof value !== 'object' && typeof value !== 'function')) return false\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// Some entries are also clonable (ArrayBuffer, ImageBitmap, …) - outside a `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, WebExtPort, WebExtSender, WebExtOnConnect, WebExtOnMessage, WebExtEvent, WebExtGlobal } from './webext-types.js'\n\nexport const isWebExtensionRuntime = (value: unknown): value is WebExtRuntime => {\n const runtime = getWebExtensionRuntime()\n if (!runtime) return false\n return value === runtime\n}\n\nexport const isWebExtensionPort = (value: unknown, connectPort: boolean = false): value is WebExtPort => {\n if (!value || typeof value !== 'object') return false\n // prevents a SecurityError when `value` is a cross-origin window - the property probes below would throw; no test covers this guard (the cross-origin tests only cover isJsonOnlyTransport and normalizeTransport), so it reads as dead code\n if (isWindow(value)) return false\n if (!('name' in value) || !('disconnect' in value) || !('postMessage' in value)) return false\n if (!connectPort) return true\n return 'sender' in value && 'onMessage' in value && 'onDisconnect' in value\n}\n\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 distinguish onConnect from onMessage, which share the exact same shape\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 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 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' && !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 || 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 (an EventEmitter) has an inherited `emit` and would otherwise be misclassified\nconst isPlainObjectShape = (value: unknown): value is Record<string, unknown> => {\n if (!value || typeof value !== 'object') return false\n // a cross-origin window's [[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: the whole backing buffer loses byteOffset/length on revive\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. */\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\n/** Whether a scope's teardown has already run. Callers use this to REFUSE work rather than start it:\n * `onTeardown` against a dead scope runs the callback immediately, which is a footgun inside an\n * initializer, and anything registered afterwards is state no teardown will ever visit again. */\nexport const isTornDown = (scope: WeakKey): boolean => tornDown.has(scope)\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 { }\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 // Request/Response are not platform Transferables, but wrapping them puts their\n // body stream inside the transfer extent so its chunks inherit move semantics\n globalThis.Request,\n globalThis.Response,\n globalThis.ImageBitmap,\n globalThis.OffscreenCanvas,\n (globalThis as { VideoFrame?: abstract new (...args: any[]) => unknown }).VideoFrame,\n (globalThis as { AudioData?: abstract new (...args: any[]) => unknown }).AudioData,\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\n// Boxing is fully synchronous (same invariant boxPath in index.ts relies on), so a\n// balanced enter/exit counter is enough to tell \"currently inside a transfer() wrapper\".\nlet transferDepth = 0\n\n/** Whether boxing is happening inside a transfer() wrapper's extent. Streams read\n * this at box time so transfer(stream) propagates move semantics to their chunks. */\nexport const isInTransfer = () => transferDepth > 0\n\n/** Internal chunk marker: unlike the public transfer(), wraps containers too, so\n * transferables nested anywhere inside a chunk move. Not part of the public API. */\nexport const forceTransfer = <T>(value: T): T =>\n (isObject(value) && !isTransferWrapper(value)\n ? { [TRANSFER_MARKER]: true, value }\n : value\n ) as T\n\n/** Runs fn with the ambient transfer extent suspended. Boxing at independent walk\n * entry points (protocol ports, revived-function calls) can fire synchronously\n * inside someone else's transfer() extent - an EventPort.start() flush during\n * boxing, or user code (a getter) calling a revived function mid-walk. Those\n * values are not part of the wrapper's graph, so their move semantics must come\n * from a wrapper in their own data, never from the ambient counter. */\nexport const outsideTransfer = <T>(fn: () => T): T => {\n const saved = transferDepth\n transferDepth = 0\n try {\n return fn()\n } finally {\n transferDepth = saved\n }\n}\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 transferDepth++\n try {\n // `degraded` tells the send-time walker in getTransferableObjects to skip the transfer-list entry\n return {\n ...BoxBase,\n type,\n inner: recursiveBox(wrapper.value, context),\n degraded: isJsonOnlyTransport(context.transport),\n } as unknown as BoxedTransfer<T>\n } finally {\n transferDepth--\n }\n}\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// Structured clone can't copy these, so they must go on the transfer list - opt-in or not.\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// `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 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, so never descend into them. Typed\n // arrays are boxed (their raw buffer rides the box and is collected above); a raw\n // DataView rides the clonable fallback, so inside a transfer box its buffer is the\n // thing to move - the serialized view then arrives over the moved buffer.\n if (ArrayBuffer.isView(value)) {\n if (inTransferBox && value instanceof DataView && !isSharedArrayBuffer(value.buffer) && !seen.has(value.buffer)) {\n seen.add(value.buffer)\n transferables.push(value.buffer as ArrayBuffer)\n }\n return\n }\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\n// NOT `extends EventTarget`: Firefox privileged sandboxes don't support subclassing platform interfaces\ntype EventPortListener = EventListenerOrEventListenerObject\n\nexport class EventPort<T> {\n // per (type, listener): value = once, and duplicate adds are ignored, matching EventTarget\n private _listeners = new Map<string, Map<EventPortListener, boolean>>()\n\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 if (!listener) return\n let listeners = this._listeners.get(type)\n if (!listeners) { listeners = new Map(); this._listeners.set(type, listeners) }\n if (!listeners.has(listener)) {\n listeners.set(listener, typeof options === 'object' && !!options?.once)\n }\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 if (!listener) return\n this._listeners.get(type)?.delete(listener)\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 const listeners = this._listeners.get(event.type)\n if (listeners) {\n for (const [listener, once] of [...listeners]) {\n if (once) listeners.delete(listener)\n if (typeof listener === 'function') listener.call(this, event)\n else listener.handleEvent(event)\n }\n }\n return true\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 // 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\n// Contract: `cleanup` MUST NOT (transitively) reference `target`, or the engine never sees target as collectable.\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 { outsideTransfer } from './transfer.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, seq?: number }\n | { type: 'message-port-close', remoteUuid: Uuid, portId: Uuid, seq?: number }\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 back `AnyPort<A | B>`, not `AnyPort<A> | AnyPort<B>`\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\n// wire contract: each side stamps its outgoing port messages with a monotonic `seq`, and the receiver buffers by seq and delivers strictly in send-order once a handler exists\n// the credit-window readable-stream protocol relies on that in-order delivery; port messages can also arrive BEFORE the message that revives the port and registers its handler, which is why handler-less routing entries exist at all\ntype PortRouting = {\n handler?: (message: Messages) => void\n /** Next incoming seq to deliver. */\n nextSeq: number\n /** Out-of-order / early incoming messages, keyed by their seq. */\n buffer: Map<number, Messages>\n /** Next outgoing seq to stamp on this side's messages for the port. */\n outSeq: number\n}\n\n// caps the per-port reorder buffer so a peer that never sends the awaited seq can't grow it without bound - overflow fails the port closed instead of wedging it silently\nconst REORDER_LIMIT = 2048\n// remembers closed portIds so late in-flight messages can't resurrect routing state\nconst TOMBSTONE_LIMIT = 128\n// caps routing entries allocated by messages arriving before their port's handler registers\nconst PENDING_PORT_LIMIT = 1024\n\ntype ConnectionMessagePortState = {\n /** O(1) per-portId routing - avoids the O(N) addEventListener scan that was the\n * bottleneck for tight-loop RPC traffic. */\n ports: Map<string, PortRouting>\n /** Recently closed portIds, insertion-ordered for bounded eviction. */\n tombstones: Set<string>\n /** Count of handler-less entries in `ports`. */\n pendingPorts: number\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\nconst getPort = (state: ConnectionMessagePortState, portId: string): PortRouting => {\n let port = state.ports.get(portId)\n if (!port) {\n port = { nextSeq: 0, buffer: new Map(), outSeq: 0 }\n state.ports.set(portId, port)\n state.pendingPorts++\n }\n return port\n}\n\nconst tombstonePort = (state: ConnectionMessagePortState, portId: string): void => {\n const port = state.ports.get(portId)\n if (port && !port.handler) state.pendingPorts--\n state.ports.delete(portId)\n if (state.tombstones.size >= TOMBSTONE_LIMIT) {\n const oldest = state.tombstones.values().next().value\n if (oldest !== undefined) state.tombstones.delete(oldest)\n }\n state.tombstones.add(portId)\n}\n\nconst drainPort = (port: PortRouting): void => {\n if (!port.handler) return\n for (let next = port.buffer.get(port.nextSeq); next !== undefined; next = port.buffer.get(port.nextSeq)) {\n port.buffer.delete(port.nextSeq)\n port.nextSeq++\n port.handler(next)\n }\n}\n\nconst nextOutSeq = (context: RevivableContext, portId: Uuid): number => getPort(getState(context), portId).outSeq++\n\nconst registerPortHandler = (\n context: RevivableContext,\n portId: Uuid,\n handler: (message: Messages) => void,\n): void => {\n const state = getState(context)\n if (state.tombstones.has(portId)) {\n // macrotask, not microtask: revived ports reach their consumer through microtask chains, which must win so close listeners attach first\n setTimeout(() => handler({ type: 'message-port-close', remoteUuid: context.remoteUuid, portId }))\n return\n }\n const port = getPort(state, portId)\n if (!port.handler) state.pendingPorts--\n port.handler = handler\n drainPort(port)\n}\n\nexport const init = (context: RevivableContext): void => {\n const state: ConnectionMessagePortState = { ports: new Map(), tombstones: new Set(), pendingPorts: 0 }\n connectionStateMap.set(context, state)\n\n context.eventTarget.addEventListener('message', ({ detail }) => {\n if (detail.type !== 'message' && detail.type !== 'message-port-close') return\n if (state.tombstones.has(detail.portId)) return\n let port = state.ports.get(detail.portId)\n // a legacy peer (osra <= 0.5.6) does not stamp seq, so deliver in arrival order\n if (detail.seq === undefined) { port?.handler?.(detail); return }\n if (!port) {\n if (state.pendingPorts >= PENDING_PORT_LIMIT) return\n port = getPort(state, detail.portId)\n }\n if (detail.seq < port.nextSeq) return\n if (port.buffer.size >= REORDER_LIMIT && !(detail.seq === port.nextSeq && port.handler)) {\n port.buffer.clear()\n tombstonePort(state, detail.portId)\n port.handler?.({ type: 'message-port-close', remoteUuid: context.remoteUuid, portId: detail.portId })\n return\n }\n port.buffer.set(detail.seq, detail)\n drainPort(port)\n })\n\n onTeardown(context, () => {\n for (const [portId, port] of [...state.ports]) {\n port.handler?.({ type: 'message-port-close', remoteUuid: context.remoteUuid, portId: portId as Uuid })\n }\n state.ports.clear()\n state.tombstones.clear()\n state.pendingPorts = 0\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 // the close MUST carry the next seq so it stays ordered after this side's data messages, which it would otherwise drop\n // a missing routing entry means the port is already torn down, so `seq: port ? port.outSeq++ : 0` reads it without resurrecting routing state (do not switch to getPort here)\n const port = getState(context).ports.get(portId)\n context.sendMessage({ type: 'message-port-close', remoteUuid: context.remoteUuid, portId, seq: port ? port.outSeq++ : 0 })\n } catch {}\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\n// MUST stay in its own scope: sharing box()'s environment record would let the FR-held closure pin context/liveRef/handlers, breaking the gc-tracker contract\nconst makeBoxGcNet = (\n contextWeak: WeakRef<RevivableContext>,\n stateWeak: WeakRef<ConnectionMessagePortState>,\n portId: Uuid,\n) => () => {\n const ctx = contextWeak.deref()\n if (ctx) sendClose(ctx, portId)\n const state = stateWeak.deref()\n if (state) tombstonePort(state, portId)\n}\n\n/** Payloads that are already boxed, so the port listener forwards them as they are.\n *\n * `function` has to box eagerly (the args must be snapshotted in the caller's synchronous frame,\n * before user code can mutate them), and the port would otherwise walk the very same value again:\n * boxes short-circuit, but every plain container in between is rebuilt and every leaf re-dispatched\n * through the whole module list, in both directions. `EventPort.postMessage` hands the peer the same\n * object reference, which is what makes the mark findable on the other side. */\nconst preBoxedPayloads = new WeakSet<object>()\n\nconst isMarkable = (value: unknown): value is object =>\n value !== null && (typeof value === 'object' || typeof value === 'function')\n\n/** Post a payload that is already boxed. Anything else must go through `postMessage` as usual. */\nexport const postPreBoxed = (\n port: MessagePort,\n boxed: Capable,\n transferables?: Transferable[],\n): void => {\n if (isMarkable(boxed)) preBoxedPayloads.add(boxed)\n port.postMessage(boxed, transferables ?? [])\n}\n\n/** Consumes the mark: a value posted twice is boxed the second time, as it must be. */\nconst boxUnlessPreBoxed = <TContext extends RevivableContext>(data: Capable, context: TContext): Capable =>\n isMarkable(data) && preBoxedPayloads.delete(data)\n ? data\n // outsideTransfer: liveRef.start() can flush queued messages synchronously while a transfer()\n // extent is on the stack - queued values are not part of it\n : outsideTransfer(() => recursiveBox(data, context)) as Capable\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 are not structured-clonable, so even a clone transport routes 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 state = getState(context)\n const liveRef: AnyPort<T> = value\n const portId: Uuid = globalThis.crypto.randomUUID()\n\n const liveRefWeak = new WeakRef(liveRef)\n const contextWeak = new WeakRef(context)\n const stateWeak = new WeakRef(state)\n\n let cleanedUp = false\n const performCleanup = () => {\n if (cleanedUp) return\n cleanedUp = true\n const st = stateWeak.deref()\n if (st) tombstonePort(st, 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 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: boxUnlessPreBoxed(data, context),\n portId,\n seq: nextOutSeq(context, portId),\n })\n }\n\n const unregisterGc = trackGc(liveRef, makeBoxGcNet(contextWeak, stateWeak, portId))\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 registerPortHandler(context, 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 // A message the platform cannot deserialize (e.g. Gecko dropping a transferred VideoFrame)\n // is silently discarded by the port; forward it so consumers can error instead of losing data.\n const onMessageError = (): void => {\n target.dispatchEvent(new Event('messageerror'))\n }\n const onClose = (): void => {\n target.dispatchEvent(new Event('close'))\n }\n port.addEventListener('message', onMessage)\n port.addEventListener('messageerror', onMessageError as EventListener)\n port.addEventListener('close', onClose as EventListener)\n target.postMessage = (data: T, opt?: Transferable[] | StructuredSerializeOptions) => {\n // outsideTransfer: a fresh walk - move semantics come from wrappers in `data` (e.g.\n // forceTransfer-marked chunks), never from an extent that happens to be on the stack\n const boxed = outsideTransfer(() => 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('messageerror', onMessageError as EventListener)\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 state = 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, so holding 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 tombstonePort(state, 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 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: boxUnlessPreBoxed(data as Capable, context),\n portId,\n seq: nextOutSeq(context, 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 registerPortHandler(context, 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 { isTornDown, 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 excess-property check flags the failure, not a user key\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 until settle: the port↔listener cycle has no other anchor\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 // transferred MessagePorts keep working past protocol 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 let removeTeardown: (() => void) | undefined\n const settle = () => {\n port.close()\n inFlightPromisePorts.delete(port)\n removeTeardown?.()\n }\n // Same refuse-before-registering rule as function.revive: onTeardown runs its callback immediately on a\n // dead scope, which would otherwise reach `removeTeardown` from inside its own initializer\n if (wireRouted && isTornDown(context)) {\n reject(new Error('osra: connection closed'))\n settle()\n return\n }\n removeTeardown = !wireRouted ? undefined : 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 { outsideTransfer } from './transfer.js'\nimport { recursiveBox } from './index.js'\nimport { EventChannel, type EventPort } from '../utils/event-channel.js'\nimport { isTornDown, onTeardown } from '../utils/teardown.js'\nimport { box as boxMessagePort, postPreBoxed, 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 - the cycle has no other anchor.\nconst inFlightReturnPorts = new Set<EventPort<Capable>>()\n\n/** Releases a result the peer can never receive. Top level and best effort ON PURPOSE: walking into the\n * value is what boxing does, and boxing into a dead context is the thing the caller is avoiding. */\nconst disposeUndelivered = (value: unknown): void => {\n if (value instanceof ReadableStream) {\n if (!value.locked) value.cancel(new Error('osra: connection closed')).catch(() => {})\n } else if (typeof WritableStream !== 'undefined' && value instanceof WritableStream) {\n if (!value.locked) value.abort(new Error('osra: connection closed')).catch(() => {})\n }\n}\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 in args aren't structured-clonable.\n const { port1: localPort, port2: remotePort } = new EventChannel<CallContext, CallContext>()\n\n localPort.addEventListener('message', ({ data }) => {\n // Don't recursiveRevive - 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 // The handler runs detached, so the connection can die while it is still awaiting. Boxing after that\n // builds routing state in a context whose teardown has already run and can never run again: measured,\n // a returned ReadableStream came back LOCKED by box()'s own getReader() and was never cancelled, so\n // whatever fed it was stranded. Nothing can reach the peer now, so release instead of boxing.\n if (isTornDown(context)) {\n if (message.type === 'return') disposeUndelivered(message.value)\n try { returnPort.close() } catch { /* may already be closed */ }\n return\n }\n const boxedResult = (() => {\n try {\n return recursiveBox(message as Capable, context)\n } catch (error) {\n return recursiveBox({ type: 'throw', error: error as Capable } as Capable, context)\n }\n })()\n // No transfer list: the port on this side is always an EventPort (function boxes its channel with\n // EventChannel, so the peer revives a synthetic port), which ignores one. The list that matters is\n // computed on the envelope at the transport boundary, in connections/index.ts.\n postPreBoxed(returnPort, boxedResult as Capable)\n // Defer close so the result reaches the peer before tear-down; without the close 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 // Refuse BEFORE allocating anything. A dead connection can never answer, and the boxing below would\n // strand these args in routing state no teardown will visit again, locking any stream among them.\n // This also keeps `onTeardown`'s immediate-run branch unreachable from inside `settle`'s initializer.\n if (isTornDown(context)) {\n reject(new Error('osra: connection closed'))\n return\n }\n\n const { port1: returnLocal, port2: returnRemote } = new EventChannel<Capable, Capable>()\n inFlightReturnPorts.add(returnLocal)\n\n let removeTeardown: (() => void) | undefined\n const settle = () => {\n returnLocal.close()\n inFlightReturnPorts.delete(returnLocal)\n removeTeardown?.()\n }\n // Connection death must reject calls - GC-drop of the proxy intentionally does not (see funcDropDoesNotRejectPending).\n 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 // outsideTransfer: user code can call a revived function synchronously from inside a\n // transfer() extent (e.g. a getter evaluated while boxing a transferred chunk); these\n // args are not part of that wrapper's graph\n const callContext = outsideTransfer(() => recursiveBox([returnRemote, args] as unknown as Capable, context))\n postPreBoxed(port, callContext as Capable)\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 { isInTransfer, forceTransfer } from './transfer.js'\nimport {\n createRevivableChannel,\n revive as reviveMessagePort,\n BoxedMessagePort,\n AnyPort\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 | { type: 'credit', n: number }\n\ntype ChunkMessage<T = unknown> = Promise<ReadableStreamReadResult<T>>\n\ntype PushMessage =\n | { type: 'chunk', value: Capable }\n | { type: 'end' }\n | { type: 'error', error: Capable }\n\ntype Msg = PullContext | PushMessage | ChunkMessage\n\nexport type BoxedReadableStream<T extends ReadableStream = ReadableStream> =\n & BoxBaseType<typeof type>\n & { port: BoxedMessagePort<Msg>, credit?: true }\n & { [UnderlyingType]: T }\n\nexport const isType = (value: unknown): value is ReadableStream =>\n value instanceof ReadableStream\n\nexport const MAX_CREDIT_WINDOW = 64\nconst MIN_CREDIT_WINDOW = 2\nconst INITIAL_CREDIT_WINDOW = 8\nconst CREDIT_BYTE_BUDGET = 4 * 1024 * 1024\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 // Captured at box time: transfer(stream) marks each chunk so transferables inside it\n // move instead of copy. Chunks that themselves carry streams re-enter the extent when\n // they are boxed, which is what makes the marker propagate through nested streams.\n const transferChunks = isInTransfer()\n\n let credit = 0\n let pumping = false\n let finished = false\n\n const finish = (message: PushMessage) => {\n finished = true\n // The terminal itself can fail to box - still close so the peer's close arm errors the consumer instead of hanging it\n try { localPort.postMessage(message) } catch {}\n localPort.close()\n }\n\n const pump = async () => {\n if (pumping || finished) return\n pumping = true\n while (credit > 0) {\n let result: ReadableStreamReadResult<unknown>\n try { result = await reader.read() }\n catch (error) {\n if (!finished) finish({ type: 'error', error: error as Capable })\n return\n }\n if (finished) return\n if (result.done) {\n finish({ type: 'end' })\n return\n }\n credit--\n const chunk = transferChunks ? forceTransfer(result.value as Capable) : result.value as Capable\n try { localPort.postMessage({ type: 'chunk', value: chunk }) }\n catch (error) {\n finish({ type: 'error', error: error as Capable })\n reader.cancel(error).catch(() => {})\n return\n }\n }\n pumping = false\n }\n\n localPort.addEventListener('message', ({ data }) => {\n if (data instanceof Promise || !('type' in data)) return\n if (data.type === 'pull') {\n // Legacy peer (osra <= 0.5.5): one boxed-Promise round trip per chunk.\n localPort.postMessage(reader.read())\n } else if (data.type === 'credit') {\n credit += data.n\n pump()\n } else if (data.type === 'cancel') {\n finished = true\n reader.cancel(data.reason).catch(() => {})\n localPort.close()\n }\n })\n localPort.addEventListener('close', () => {\n if (finished) return\n finished = true\n reader.cancel(new Error('osra: connection closed')).catch(() => {})\n }, { once: true })\n localPort.start()\n\n return { ...BoxBase, type, credit: true, port: boxedRemote } as BoxedReadableStream<T>\n}\n\nconst byteLength = (value: unknown): number | undefined =>\n ArrayBuffer.isView(value) ? value.byteLength\n : value instanceof ArrayBuffer ? value.byteLength\n : typeof value === 'string' ? value.length * 2\n : typeof Blob !== 'undefined' && value instanceof Blob ? value.size\n : undefined\n\nconst reviveCredit = (port: AnyPort<Msg>): ReadableStream => {\n let done = false\n let outstanding = 0\n let averageChunkBytes: number | undefined\n // Pipelined chunks wait here, not in the controller queue - controller.error discards queued chunks, and an early error must not eat delivered data\n const buffered: unknown[] = []\n let ended = false\n let errored = false\n let pendingError: unknown\n let waiter: {\n controller: ReadableStreamDefaultController<unknown>\n resolve: () => void\n reject: (error: unknown) => void\n } | undefined\n\n // Unmeasurable chunk types (plain objects, Maps, ...) stay at the initial window - jumping to MAX with zero byte accounting is how memory blows up\n const targetWindow = () =>\n averageChunkBytes !== undefined\n ? Math.max(MIN_CREDIT_WINDOW, Math.min(MAX_CREDIT_WINDOW, Math.floor(CREDIT_BYTE_BUDGET / averageChunkBytes)))\n : INITIAL_CREDIT_WINDOW\n\n // Half-window hysteresis: ~one credit message per target/2 chunks.\n const topUp = () => {\n const target = targetWindow()\n const ahead = outstanding + buffered.length\n if (ahead > target / 2) return\n const n = target - ahead\n outstanding += n\n port.postMessage({ type: 'credit', n })\n }\n\n const finishClose = () => {\n done = true\n queueMicrotask(() => port.close())\n }\n\n const fail = (error: unknown) => {\n errored = true\n pendingError = error\n if (!waiter || buffered.length) return\n const w = waiter\n waiter = undefined\n finishClose()\n w.reject(error)\n }\n\n return new ReadableStream({\n start: () => {\n port.addEventListener('message', ({ data }) => {\n if (data instanceof Promise || !('type' in data)) return\n if (data.type === 'chunk') {\n if (done) return\n if (outstanding <= 0) {\n buffered.length = 0\n fail(new Error('osra: stream exceeded its credit window'))\n queueMicrotask(() => port.close())\n return\n }\n outstanding--\n const size = byteLength(data.value)\n if (size !== undefined) {\n averageChunkBytes = averageChunkBytes === undefined ? size : averageChunkBytes * 0.875 + size * 0.125\n }\n if (waiter) {\n const w = waiter\n waiter = undefined\n w.controller.enqueue(data.value)\n w.resolve()\n } else buffered.push(data.value)\n } else if (data.type === 'end') {\n if (done) return\n ended = true\n if (!waiter || buffered.length) return\n const w = waiter\n waiter = undefined\n finishClose()\n w.controller.close()\n w.resolve()\n } else if (data.type === 'error') {\n if (done) return\n fail(data.error)\n }\n })\n port.addEventListener('messageerror', () => {\n if (done) return\n fail(new Error('osra: a chunk failed to deserialize on this platform'))\n })\n port.addEventListener('close', () => {\n if (done || ended || errored) return\n fail(new Error('osra: connection closed'))\n }, { once: true })\n },\n pull: (controller) => {\n if (done) return\n if (buffered.length) {\n controller.enqueue(buffered.shift())\n if (!ended && !errored) topUp()\n return\n }\n // errored before ended: a messageerror-dropped chunk followed by a clean 'end' must\n // surface as an error, never as a silently truncated stream\n if (errored) {\n finishClose()\n return Promise.reject(pendingError)\n }\n if (ended) {\n finishClose()\n controller.close()\n return\n }\n topUp()\n return new Promise<void>((resolve, reject) => { waiter = { controller, resolve, reject } })\n },\n cancel: (reason) => {\n done = true\n buffered.length = 0\n const w = waiter\n waiter = undefined\n w?.resolve()\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 })\n}\n\nconst revivePull = (port: AnyPort<Msg>): ReadableStream => {\n let done = false\n return new ReadableStream({\n start: (controller) => {\n port.addEventListener('messageerror', () => {\n if (done) return\n done = true\n try { controller.error(new Error('osra: a chunk failed to deserialize on this platform')) } catch {}\n queueMicrotask(() => port.close())\n })\n port.addEventListener('close', () => {\n if (done) return\n done = true\n try { controller.error(new Error('osra: connection closed')) } catch {}\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 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 queueMicrotask(() => port.close())\n },\n })\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 // A box that doesn't advertise credit (osra <= 0.5.5) cancels on any unknown message, so it must only ever be spoken to in pull\n return (value.credit ? reviveCredit(port) : revivePull(port)) 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 { isInTransfer, forceTransfer } from './transfer.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 per call\nexport type WriteContext =\n | { type: 'write', chunk: Capable }\n | { type: 'close' }\n | { type: 'abort', reason: Capable }\n\n// reply box -> revive after a write completes, which is what lets writer.write() await\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 // transferChunks rides the wire because chunks originate on the revive side; old peers ignore it\n & { port: BoxedMessagePort<Msg>, transferChunks?: true }\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 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 // A write the platform failed to deserialize would otherwise never be acked, hanging the writer.\n localPort.addEventListener('messageerror', () => {\n localPort.postMessage({ type: 'err', error: 'osra: a chunk failed to deserialize on this platform' })\n })\n // Abnormal channel death: abort the 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 {\n ...BoxBase,\n type,\n port: boxedRemote,\n ...(isInTransfer() ? { transferChunks: true as const } : {}),\n } 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 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 // The port is shared, so we serialize via a chain - concurrent writes would 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 const transferChunks = value.transferChunks === true\n return new WritableStream({\n write: (chunk) => request({ type: 'write', chunk: (transferChunks ? forceTransfer(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 while the revived signal is reachable - 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 // Must box the reason here - 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 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 // 101/204/205/304 forbid a body, so cancel the boxed stream to stop the sender pushing into a dead port\n const stream = value.body ? reviveReadableStream(value.body, context) : null\n const isNullBodyStatus =\n value.status === 101 || value.status === 204 || value.status === 205 || value.status === 304\n if (stream && isNullBodyStatus) stream.cancel().catch(() => {})\n const body = isNullBodyStatus ? null : stream\n\n const response = new Response(body, {\n status: value.status,\n statusText: value.statusText,\n headers\n })\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 turns `body: null` into a `.body` getter returning `undefined`, so only pass `body` when there's a stream\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 { boxClaimedValue, onBoxWalkSettled, recursiveRevive } from './index.js'\nimport { isTornDown, 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\n/** Phantom shape. A tracked value carries no marker of its own, the mark lives in a WeakMap, so\n * this is what `isType` declares instead: matching it at the type level would widen `Capable` to\n * every object, and nothing a user writes structurally matches this. */\ntype IdentityMarked = { readonly [IDENTITY_MARKER]: true }\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\n/** Reference to id, for the whole realm rather than one connection. The id is minted once, wherever\n * the reference first became an identity - `identity()` here, or reviving one from a peer - and\n * from then on it travels with the value onto every connection it is sent over. That is what makes\n * a value keep its identity down a chain of contexts: each hop hands the same id to the next, so\n * the value coming back resolves to what that hop handed out, all the way to the origin. */\nconst valueToId = new WeakMap<WeakKey, string>()\n\nconst idFor = (value: WeakKey): string => {\n const existing = valueToId.get(value)\n if (existing !== undefined) return existing\n const id = globalThis.crypto.randomUUID()\n valueToId.set(value, id)\n return id\n}\n\n/** Mark a value so osra preserves its reference identity across the boundary. The peer's revived\n * value stands for this one, and handing it back - to you, or onward to a further context and back\n * again - resolves to this very reference. The mark sticks to the value, so only the side that\n * owns it has to opt in. Idempotent, and primitives pass through unchanged. */\nexport const identity = <T>(value: T): T => {\n if (isObjectOrFunction(value)) idFor(value)\n return value\n}\n\ntype IdentityState = {\n /** Every id that has crossed this connection, either way, mapped to what it denotes on this side.\n * `has` doubles as \"the peer can resolve this id\", which is what lets a resend skip the payload.\n * Weak, because an entry outliving its value would resolve to nothing anyway. */\n readonly idToLocal: Map<string, WeakRef<WeakKey>>\n /** Values revived from this peer, held until the peer says its own reference is gone: it can send\n * the bare id at any time and expects this exact value back. */\n readonly pins: Map<string, unknown>\n /** The id to use for a value whose realm id is already spoken for on THIS connection by a different\n * local value. See `idOnConnection`. */\n readonly aliasIds: WeakMap<WeakKey, string>\n readonly disposeRegistry: FinalizationRegistry<string>\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 idToLocal = new Map<string, WeakRef<WeakKey>>()\n const pins = new Map<string, unknown>()\n const aliasIds = new WeakMap<WeakKey, string>()\n const disposeRegistry = new FinalizationRegistry<string>((id) => {\n idToLocal.delete(id)\n if (isTornDown(context)) return\n try {\n context.sendMessage({ type: 'identity-dispose', remoteUuid: context.remoteUuid, id })\n } catch { /* connection already closed */ }\n })\n const state: IdentityState = { idToLocal, pins, aliasIds, disposeRegistry }\n connectionStates.set(context, state)\n context.eventTarget.addEventListener('message', ({ detail }) => {\n if (detail?.type !== 'identity-dispose') return\n state.pins.delete(detail.id)\n // Dropped too, not just unpinned: the peer's reference is gone, so a later send of our own value\n // has to carry the payload again instead of a bare id nothing over there could resolve.\n state.idToLocal.delete(detail.id)\n })\n onTeardown(context, () => {\n state.pins.clear()\n state.idToLocal.clear()\n })\n return state\n}\n\nexport const isType = (value: unknown): value is IdentityMarked =>\n isObjectOrFunction(value) && valueToId.has(value)\n\n/** The id this value travels under ON THIS CONNECTION.\n *\n * Normally that is its realm id, and the whole chain mechanism rests on the two being the same. They\n * can only differ when one origin identity was revived twice in this realm, once per connection it\n * arrived on: both revived values then carry the same realm id, and forwarding both onto a third\n * connection would send the second as a bare id the peer resolves to the FIRST one, silently handing\n * it one object where two were sent. Re-minting the realm id instead would be worse: it is the value's\n * identity on every OTHER connection too, including the one it came from, so re-minting breaks the\n * round trip home. The substitute is therefore per connection, and the loser of the race is the one\n * that gets it. */\nconst idOnConnection = (value: WeakKey, state: IdentityState): string => {\n const alias = state.aliasIds.get(value)\n if (alias !== undefined) return alias\n const id = idFor(value)\n const record = state.idToLocal.get(id)\n if (record === undefined || record.deref() === value) return id\n // Taken here by another local value (or by one already collected, whose pin the peer still holds).\n const substitute = globalThis.crypto.randomUUID()\n state.aliasIds.set(value, substitute)\n return substitute\n}\n\n/** The shared tail of both box paths: hand the peer the id alone when it can already resolve it,\n * and otherwise the id plus the payload, remembering that this peer now knows it. */\nconst boxTracked = (\n value: WeakKey,\n buildInner: () => Capable,\n state: IdentityState,\n): BoxedIdentity => {\n const id = idOnConnection(value, state)\n if (state.idToLocal.has(id)) return { ...BoxBase, type, id } as BoxedIdentity\n // Before recording the id, so a value containing itself still hits the cycle guard rather than\n // shipping a self-reference the peer could never revive.\n const inner = buildInner()\n // Recorded now so a second occurrence in the SAME message rides the id, and rolled back if the walk\n // never finishes: the record is a claim about what the peer received, and a message that was never\n // built was never received.\n state.idToLocal.set(id, new WeakRef(value))\n state.disposeRegistry.register(value, id, value)\n onBoxWalkSettled(\n () => {},\n () => {\n state.idToLocal.delete(id)\n state.disposeRegistry.unregister(value)\n },\n )\n return { ...BoxBase, type, id, inner } as BoxedIdentity\n}\n\nexport const box = <T extends Capable, TContext extends RevivableContext>(\n value: T,\n context: TContext,\n): BoxedIdentity<T> => {\n const state = getOrCreateState(context)\n const buildInner = () => boxClaimedValue(value, context, type) as Capable\n if (!isWeakKeyable(value)) {\n return { ...BoxBase, type, id: globalThis.crypto.randomUUID(), inner: buildInner() } as BoxedIdentity<T>\n }\n return boxTracked(value, buildInner, state) as BoxedIdentity<T>\n}\n\n/** Identity-box a referenceable value with a caller-supplied inner box, bypassing the walker. Used\n * by revivables (symbol with 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 boxTracked(value, () => innerBox, getOrCreateState(context))\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 if (state.pins.has(value.id)) return state.pins.get(value.id) as T[UnderlyingType]\n const known = state.idToLocal.get(value.id)?.deref()\n if (known !== undefined) return known as T[UnderlyingType]\n if (!('inner' in value) || value.inner === undefined) {\n // The peer believes we know this id, so something between its record and here lost the payload.\n // Tell it to forget the record, which is exactly what dispose does on that side, so its next send\n // of that value carries the payload again instead of repeating this.\n try {\n context.sendMessage({ type: 'identity-dispose', remoteUuid: context.remoteUuid, id: value.id })\n } catch { /* connection already closed */ }\n throw new Error(`osra identity: received id=${value.id} with no inner payload and nothing local to resolve it to`)\n }\n const revived = recursiveRevive(value.inner, context)\n state.pins.set(value.id, revived)\n if (isWeakKeyable(revived)) {\n // Carries the id onward: sending this value to a further context sends it under the same id, so\n // whatever comes back through the chain lands on this very value again.\n if (!valueToId.has(revived)) valueToId.set(revived, value.id)\n state.idToLocal.set(value.id, new WeakRef(revived))\n }\n return revived as T[UnderlyingType]\n}\n\nconst typeCheck = () => {\n const fn = () => 42\n const boxed = box(fn, {} 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 value (WeakMap not assignable)\n box(new WeakMap<object, string>(), {} as RevivableContext)\n const marked: typeof fn = identity(fn)\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 Capable ↔ defaultRevivableModules ↔ this module type cycle\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\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 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 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; the source-side EventTarget owns all semantics.\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 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 - the FR strong-holds it.\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 } 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 const registryKey = Symbol.keyFor(value)\n if (registryKey !== undefined) return { ...BoxBase, type, registryKey }\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 revivable\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, isJsonOnlyTransport } from '../utils/type-guards.js'\n\ntype AnyCtor = abstract new (...args: any[]) => unknown\n\n// clonable is a pass-through fast path that short-circuits findBoxModule so unclonable's structuredClone probe never fires on a known-safe value\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 Capable union on JSON transports\n// it is a marker flag because TS can't narrow `isType<Ctx>` through generic inference\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 // `revive` is 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// getTransferableObjects pulls these out of the envelope at send time\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// Must sit after clonable so File keeps riding it\nexport type BoxedBlob = BoxBaseType<'blob'>\n\nconst isBlob = (value: unknown): value is Blob =>\n typeof Blob !== 'undefined' && value instanceof Blob\n\nexport const blob = {\n type: 'blob',\n capableOnly: true,\n isType: isBlob,\n box: (value: Blob, context: RevivableContext<any>): Blob => {\n if (isJsonOnlyTransport(context.transport)) {\n throw new TypeError('osra: Blob is only supported on structured-clone transports, send an ArrayBuffer or Uint8Array instead')\n }\n return value\n },\n revive: (value: BoxedBlob, _context: RevivableContext<any>): Blob => value as unknown as Blob,\n} as const\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\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, undefined vanishes\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 symbol from './symbol.js'\nimport * as asyncIterator from './async-iterator.js'\nimport { blob, 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: the bivariance escape hatch that 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 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, before the fallbacks so generators don't coerce to {}.\n asyncIterator,\n nonFiniteNumber,\n undefinedValue,\n // clonable/transferable before eventTarget: OffscreenCanvas & co. also extend EventTarget.\n clonable,\n transferable,\n // After clonable (File rides it): bare Blobs would otherwise silently coerce to `{}` on JSON.\n blob,\n // eventTarget MUST be last among instanceof-EventTarget revivables - the specific ones need first dibs.\n eventTarget,\n unclonable,\n] as const\n\nexport type DefaultRevivableModules = typeof defaultRevivableModules\nexport type DefaultRevivableModule = DefaultRevivableModules[number]\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// Box/revive are fully synchronous, so a module-global set with balanced enter/exit is safe; tracking the *path* (not all visited values) keeps sibling aliasing working.\nconst boxPath = new WeakSet<object>()\nconst revivePath = new WeakSet<object>()\n\n// Depth of the current top-level box walk, and the side effects waiting on it to finish. Same\n// synchronous-walk invariant as boxPath.\nlet boxDepth = 0\nlet pendingWalkEffects: Array<{ commit: () => void, rollback: () => void }> = []\n\n/** Hold a side effect until the whole box walk this value belongs to has finished, and undo it if the\n * walk throws. A module that records state the PEER will be told about (\"it knows this id now\") must\n * not keep that record when a later sibling breaks the message it was recorded for: nothing ships,\n * and every later send would then reference something the peer never received. Outside a walk the\n * effect is already settled, so `commit` runs immediately. */\nexport const onBoxWalkSettled = (commit: () => void, rollback: () => void): void => {\n if (boxDepth === 0) {\n commit()\n return\n }\n pendingWalkEffects.push({ commit, rollback })\n}\n\nconst settleBoxWalk = (failed: boolean) => {\n const effects = pendingWalkEffects\n pendingWalkEffects = []\n for (const effect of effects) {\n try {\n if (failed) effect.rollback()\n else effect.commit()\n } catch { /* one module's bookkeeping must not break another's */ }\n }\n}\n\nconst isTrackable = (value: unknown): value is object =>\n value !== null && (typeof value === 'object' || typeof value === 'function')\n\nconst boxDispatch = <\n T extends Capable,\n TModules extends readonly RevivableModule[]\n>(\n value: T,\n context: RevivableContext<TModules>,\n skipType?: string,\n): DeepReplaceWithBox<T, TModules[number]> => {\n type ReturnCastType = DeepReplaceWithBox<T, TModules[number]>\n const handledByModule = context.revivableModules.find(\n module => module.type !== skipType && module.isType(value)\n )\n if (handledByModule) {\n return handledByModule.box(value, context) as ReturnCastType\n }\n return descend<ReturnCastType>(value, v => recursiveBox(v, context))\n}\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 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 boxDepth++\n let failed = true\n try {\n const boxed = boxDispatch(value, context)\n failed = false\n return boxed\n } finally {\n if (track) boxPath.delete(value)\n boxDepth--\n if (boxDepth === 0) settleBoxWalk(failed)\n }\n}\n\n/** Box a value your own module claimed in place: every other module gets its turn and children are\n * walked as usual, but `claimedBy` is skipped, and the cycle guard the caller's `recursiveBox`\n * frame already holds for this value is not re-entered.\n * A module needs this when its `isType` matches a bare value rather than a wrapper around one, the\n * way `identity()` marks a reference in place: `recursiveBox` on that same value would come\n * straight back to the module, and the guard would report it as a cycle. */\nexport const boxClaimedValue = <\n T extends Capable,\n TModules extends readonly RevivableModule[]\n>(\n value: T,\n context: RevivableContext<TModules>,\n claimedBy: string,\n): DeepReplaceWithBox<T, TModules[number]> =>\n boxDispatch(value, context, claimedBy)\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 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 { Context, 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, peer } }) => {\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 back after our reply), not a collision\n if (ctx.connectionContexts.has(message.uuid)) return\n ctx.sendMessage({ type: 'announce', remoteUuid: message.uuid })\n const eventTarget = ctx.createConnectionEventTarget()\n const connectionContextValues = { ...peer(), abort: () => ctx.abortConnection(message.uuid) }\n let connection: ReturnType<typeof startBidirectionalConnection<TModules>>\n try {\n // Built BEFORE the connection starts, because starting it sends our value: a factory that calls ctx.abort() has to be observable before the value goes out\n const built = ctx.valueFor(connectionContextValues)\n if (ctx.claimPendingAbort(message.uuid)) {\n ctx.sendMessage({ type: 'close', remoteUuid: message.uuid })\n return\n }\n connection = startBidirectionalConnection<TModules>({\n transport: ctx.transport,\n value: built,\n remoteUuid: message.uuid,\n eventTarget,\n send: (m) => ctx.sendMessage(m as MessageVariant),\n revivableModules: ctx.revivableModules\n })\n } catch (error) {\n // Surface it locally instead of swallowing it inside EventTarget dispatch, AND tell the peer, or its own expose() waits on a handshake that will never come\n ctx.sendMessage({ type: 'close', remoteUuid: message.uuid })\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.addConnection(connectionContextValues, 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 must not leave the caller pending forever\n ctx.rejectRemoteValue(new Error('osra: peer closed the connection'))\n return\n }\n if (message.remoteUuid !== ctx.getUuid()) return\n const connection = ctx.connectionContexts.get(message.uuid)\n if (!connection) return\n connection.eventTarget.dispatchEvent(\n new CustomEvent('message', { detail: message })\n )\n })\n\n if (ctx.presetRemoteUuid !== undefined) {\n const presetRemoteUuid = ctx.presetRemoteUuid\n const eventTarget = ctx.createConnectionEventTarget()\n let connection: ReturnType<typeof startBidirectionalConnection<TModules>>\n let presetContextValues: Context\n try {\n presetContextValues = { abort: () => ctx.abortConnection(presetRemoteUuid) }\n const built = ctx.valueFor(presetContextValues)\n if (ctx.claimPendingAbort(presetRemoteUuid)) {\n ctx.sendMessage({ type: 'close', remoteUuid: presetRemoteUuid })\n return\n }\n connection = startBidirectionalConnection<TModules>({\n transport: ctx.transport,\n value: built,\n remoteUuid: ctx.presetRemoteUuid,\n eventTarget,\n send: (m) => ctx.sendMessage(m as MessageVariant),\n revivableModules: ctx.revivableModules\n })\n } catch (error) {\n ctx.sendMessage({ type: 'close', remoteUuid: presetRemoteUuid })\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.addConnection(presetContextValues, remoteValue),\n (error) => ctx.rejectRemoteValue(error),\n )\n return\n }\n\n // Posted with '*' instead of the configured origin: until a cross-origin iframe commits, its window still holds the initial about:blank document, so a strict targetOrigin fails the browser's delivery check\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 try { ctx.sendMessage({ type: 'announce' }, '*') } catch {}\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 { Context, 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 { emit: webSocket } is JSON-only even though the wrapper is not\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 // `peer` MUST stay a thunk: eager building runs the caller's context builder on every RPC frame and stream chunk instead of once per connection\n message: CustomEvent<{ message: Message<TModules>, peer: () => Context }>\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 /** The exposed value for ONE peer. A factory rather than a value so a server can answer each realm\n * differently (scoped resolvers per origin) instead of sharing one object across every connection. */\n valueFor: (peer: Context) => Capable<TModules>\n revivableModules: TModules\n connectionContexts: Map<string, ConnectionContext<TModules>>\n getUuid: () => Uuid\n presetRemoteUuid?: Uuid\n /** targetOrigin overrides the configured origin for this one send - only\n * the unsolicited announce beacon broadcasts with '*'. */\n sendMessage: (message: MessageVariant, targetOrigin?: string) => void\n protocolEventTarget: ProtocolEventTarget<TModules>\n rejectRemoteValue: (error: unknown) => void\n /** reports an established connection: settles the first-connection promise and feeds iteration, so\n * a caller sees every realm rather than only the one that happened to connect first */\n addConnection: (ctx: Context, value: Capable<TModules>) => void\n /** tears down one connection: close to the peer, teardown locally, drop it from tracking */\n abortConnection: (remoteUuid: Uuid) => void\n /** true when this uuid was aborted before it was registered, which means refuse the registration */\n claimPendingAbort: (remoteUuid: Uuid) => boolean\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 /** Decides what one connection resolves to, for the await and for iteration alike. Omit it and that\n * is the peer's value, which is what `expose` has always given back:\n *\n * ```ts\n * const remote = await expose(api, { transport })\n *\n * const { value, context } = await expose(api, {\n * transport,\n * connection: ({ value, context }) => ({ value, context }),\n * })\n *\n * for await (const origin of expose(api, {\n * transport,\n * connection: ({ context }) => context.origin,\n * })) { }\n * ```\n *\n * It runs per connection, on this side, after the handshake. It cannot change what is sent, and\n * nothing it returns crosses the wire. */\n connection?: (connected: Connected<unknown>) => unknown\n}\n\n/** An established connection: the value that realm exposed, and what this side knows about the realm\n * it came from. `context` is whatever the transport observed, plus an `abort` that drops this one\n * peer. Anything derived from it is the caller's to compute, in the value factory or in\n * `connection:`, rather than something to declare up front. */\nexport type Connected<TValue> = {\n value: TValue\n context: Context\n}\n\n/** The result of `expose`. Awaiting it gives the first peer, iterating it gives every peer as it\n * connects, and both hand back the same thing: one shape, read once or read repeatedly.\n *\n * What that shape IS comes from the `connection:` option. Without one it is the peer's value, which\n * is what `expose` has always resolved to. With one it is whatever that function returns. */\nexport type Exposed<TResult> = Promise<TResult> & AsyncIterable<TResult>\n\nexport type ConnectionQueue<TRemote> = {\n push: (connection: Connected<TRemote>) => void\n close: () => void\n iterate: () => AsyncIterableIterator<Connected<TRemote>>\n}\n\n// bounds what a consumer that never iterates retains: each buffered connection pins a Remote proxy and a window or MessagePort\n/** Multicast: every iterator sees every peer, rather than several loops sharing one cursor and each\n * taking a slice. Two loops watching one server both mean \"tell me about every peer\", and a shared\n * cursor makes whichever one happens to be waiting eat the peer the other was waiting for. */\n/** Until someone asks to iterate, a connection is buffered only up to this many. Every consumer that\n * just awaits the first connection would otherwise retain every later one for the transport's life,\n * each pinning a Remote proxy and a window or MessagePort. Buffering a few keeps the ordinary\n * \"expose now, iterate on the next tick\" case lossless; a consumer that never iterates cannot leak. */\nconst PRE_ITERATION_BUFFER = 32\n\n/** @internal protocol plumbing, not part of the public api */\nexport const createConnectionQueue = <TRemote>(): ConnectionQueue<TRemote> => {\n type Result = IteratorResult<Connected<TRemote>>\n type Subscriber = { buffered: Connected<TRemote>[], wake?: (result: Result) => void }\n // copied into each new iterator, never drained: draining would let whichever loop iterated first decide what the others never see\n const early: Connected<TRemote>[] = []\n const subscribers = new Set<Subscriber>()\n let closed = false\n const done = () => ({ value: undefined as never, done: true as const })\n return {\n push: (connection) => {\n if (closed) return\n if (subscribers.size === 0) {\n early.push(connection)\n if (early.length > PRE_ITERATION_BUFFER) early.shift()\n return\n }\n for (const subscriber of subscribers) {\n const wake = subscriber.wake\n if (wake) { subscriber.wake = undefined; wake({ value: connection, done: false }); continue }\n subscriber.buffered.push(connection)\n }\n },\n close: () => {\n closed = true\n for (const subscriber of subscribers) {\n const wake = subscriber.wake\n subscriber.wake = undefined\n wake?.(done())\n }\n },\n iterate: () => {\n // per iterator, not shared: a waiter left behind by an abandoned iterator would swallow the next connection\n const subscriber: Subscriber = { buffered: [...early] }\n subscribers.add(subscriber)\n let finished = false\n return {\n [Symbol.asyncIterator]() { return this },\n next: () => {\n if (finished) return Promise.resolve(done())\n const next = subscriber.buffered.shift()\n if (next) return Promise.resolve({ value: next, done: false as const })\n if (closed) return Promise.resolve(done())\n return new Promise<Result>((resolve) => { subscriber.wake = resolve })\n },\n return: () => {\n finished = true\n subscribers.delete(subscriber)\n const wake = subscriber.wake\n subscriber.wake = undefined\n wake?.(done())\n return Promise.resolve(done())\n },\n }\n },\n }\n}\n\n/** The awaited-and-iterable result, with every connection passed through `select` first. The promise\n * is DERIVED from the first-connection promise, so it needs its own no-op catch: a fire-and-forget\n * `expose(...)` handles the original, and an unhandled derived rejection would still reach the\n * console. */\n/** @internal not part of the public api */\nexport const asExposed = <T, TResult>(\n first: Promise<Connected<T>>,\n queue: ConnectionQueue<T>,\n select: (connected: Connected<T>) => TResult,\n): Exposed<TResult> => {\n const result = first.then(select)\n // `result` is derived, so it needs its own no-op catch even when the caller handles the original\n result.catch(() => {})\n // do not replace with an async generator: one suspended at `await` defers `return()` until that await settles, so abandonment would hang\n const iterate = (): AsyncIterableIterator<TResult> => {\n const inner = queue.iterate()\n return {\n [Symbol.asyncIterator]() { return this },\n next: () =>\n inner.next().then(step =>\n step.done\n ? { value: undefined as never, done: true as const }\n : { value: select(step.value), done: false as const }),\n return: () =>\n inner.return?.() as Promise<IteratorResult<TResult>>\n ?? Promise.resolve({ value: undefined as never, done: true as const }),\n }\n }\n return Object.assign(result, { [Symbol.asyncIterator]: iterate }) as Exposed<TResult>\n}\n\n/** An exposed value can itself be a function - osra exposes functions as endpoints - so a bare\n * `typeof value === 'function'` cannot tell a per-peer factory from a plain function value. The\n * marker makes the intent explicit and unambiguous. */\n/** @internal */\nexport const CONTEXT = Symbol.for('osra.context')\n\nexport type Contextual<TValue> = {\n [CONTEXT]: (ctx: Context) => TValue\n}\n\n/** Build the exposed value once per connection, from that connection's context, rather than sharing\n * one value across every realm that connects. It runs BEFORE the value is boxed and sent, which is\n * what lets one server answer each realm differently:\n *\n * ```ts\n * expose(context(({ origin }) => resolvers(idFor(origin))), { transport })\n * ```\n *\n * A wrapper rather than \"pass a function\", because osra exposes functions as endpoints, so a bare\n * `typeof value === 'function'` cannot tell a per-peer factory from a plain function value.\n *\n * What the read side needs is not declared here: `connection:` sees the same context and derives its\n * own. */\nexport const context = <TValue,>(make: (ctx: Context) => TValue): Contextual<TValue> =>\n ({ [CONTEXT]: make })\n\n/** @internal */\nexport const isContextual = <TValue,>(value: unknown): value is Contextual<TValue> =>\n typeof value === 'object' && value !== null && CONTEXT in value\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, Context } from '../utils/transport.js'\nimport type { Connected, Contextual, Exposed } from './utils.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 { asExposed, createConnectionQueue, isContextual, mergeRevivableModules, normalizeTransport, CONTEXT } 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> for the same bivariance reason as RevivableModule.box\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 TResult = T\n>(\n value: Capable<TModules> | Contextual<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 // type-level counterpart is `TResult`'s default in src/index.ts: those two state the same fact separately and have to move together\n connection: selectConnection = ({ value }) => value,\n }: StartConnectionsOptions<TModules>\n): Exposed<TResult> => {\n const select = selectConnection as (connected: Connected<T>) => TResult\n const transport = normalizeTransport(_transport)\n if (!(isEmitTransport(transport) && isReceiveTransport(transport))) {\n const queue = createConnectionQueue<T>()\n queue.close()\n const rejected = Promise.reject(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 rejected.catch(() => {})\n return asExposed<T, TResult>(rejected, queue, select)\n }\n const mergedRevivableModules = mergeRevivableModules<TModules>(configureRevivableModules)\n type MergedModules = typeof mergedRevivableModules\n const connectionContexts = new Map<string, ConnectionContext<MergedModules>>()\n\n const pendingAborts = new Set<string>()\n\n const connectionQueue = createConnectionQueue<T>()\n\n const { promise: firstConnection, resolve: resolveFirstConnection, reject: rejectRemoteValue } =\n Promise.withResolvers<Connected<T>>()\n // Keeps a fire-and-forget `expose(value, …)` from surfacing an unhandled rejection on abort/close\n firstConnection.catch(() => {})\n\n const uuid: Uuid = _uuid ?? globalThis.crypto.randomUUID()\n\n const sendEnvelope = (message: MessageVariant, targetOrigin: string = origin) => {\n const envelope = { [OSRA_KEY]: key, name, uuid, ...message }\n sendOsraMessage(transport, envelope, targetOrigin, getTransferableObjects(envelope))\n }\n\n const sendMessage = (message: MessageVariant, targetOrigin?: string) => {\n if (unregisterSignal?.aborted) return\n sendEnvelope(message, targetOrigin)\n }\n\n const protocolEventTarget = createTypedEventTarget<{ message: CustomEvent<{ message: Message<MergedModules>, peer: () => Context }> }>()\n\n const ctx: ProtocolContext<MergedModules> = {\n transport,\n valueFor: (peer: Context) =>\n (isContextual<Capable<MergedModules>>(value)\n ? value[CONTEXT](peer)\n : value) as Capable<MergedModules>,\n revivableModules: mergedRevivableModules,\n connectionContexts,\n getUuid: () => uuid,\n presetRemoteUuid,\n sendMessage,\n protocolEventTarget,\n rejectRemoteValue,\n abortConnection: (remoteUuid: Uuid) => {\n const connectionContext = connectionContexts.get(remoteUuid)\n // Raised from inside the value factory, which runs BEFORE the connection is registered\n if (!connectionContext) { pendingAborts.add(remoteUuid); return }\n connectionContexts.delete(remoteUuid)\n sendEnvelope({ type: 'close', remoteUuid })\n runTeardown(connectionContext.connection.revivableContext)\n rejectRemoteValue(new Error('osra: connection aborted'))\n },\n claimPendingAbort: (remoteUuid) => pendingAborts.delete(remoteUuid),\n addConnection: (ctx, value) => {\n const connection = { value: value as T, context: ctx }\n resolveFirstConnection(connection)\n connectionQueue.push(connection)\n },\n createConnectionEventTarget: createTypedEventTarget,\n unregisterSignal,\n }\n\n const listener = (message: Message, messageContext: MessageContext) => {\n if (message.uuid === uuid) return\n // Built from LOCAL knowledge only: nothing from the peer's payload participates, and none of it is ever sent back\n const peer = (): Context => ({\n ...(messageContext.origin ? { origin: messageContext.origin } : {}),\n ...(messageContext.source ? { source: messageContext.source } : {}),\n ...(messageContext.port ? { port: messageContext.port } : {}),\n ...(messageContext.sender ? { sender: messageContext.sender } : {}),\n })\n protocolEventTarget.dispatchEvent(\n new CustomEvent('message', { detail: { message: message as Message<MergedModules>, peer } }),\n )\n }\n\n registerOsraMessageListener({\n listener,\n transport,\n remoteName,\n key,\n origin,\n unregisterSignal\n })\n\n // an already-aborted signal's 'abort' event has fired and will never fire again, so the listener below would leave the promise pending forever\n if (unregisterSignal?.aborted) {\n rejectRemoteValue(unregisterSignal.reason)\n connectionQueue.close()\n return asExposed<T, TResult>(firstConnection, connectionQueue, select)\n }\n\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 // the other two exit paths close the queue; without this a `for await` over connections never terminates\n connectionQueue.close()\n rejectRemoteValue(unregisterSignal.reason)\n }, { once: true })\n\n for (const connectionModule of connections) {\n connectionModule.init(ctx)\n }\n\n return asExposed<T, TResult>(firstConnection, connectionQueue, select)\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 { Connected, Contextual, Exposed, StartConnectionsOptions } from './connections/utils.js'\nimport type { Context, Transport } from './utils/transport.js'\nimport type { IsJsonOnlyTransport } from './utils/type-guards.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// named for the revivable context specifically: `ContextOf` is the PUBLIC helper for a connection\n// context builder, re-exported from connections/utils, and two of them in one module is a trap\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.\n * Named for the revivable context specifically: `ContextOf` is the PUBLIC helper for a connection\n * context builder, re-exported from connections/utils, and two of them in one module is a trap. */\ntype RevivableContextOf<TTransport extends Transport> = RevivableContext & { transport: TTransport }\n\n// picks between two error texts: when the value fails ONLY because the transport is JSON (it would\n// pass under the broad `RevivableContext`, whose transport union resolves to structured-clone\n// semantics), blame the transport instead of the value\n/** Error text for a failed check. When the value only fails because the\n * transport is JSON (it would pass under the broad `RevivableContext`,\n * whose transport union resolves to structured-clone semantics), blame\n * the transport instead of the value. */\ntype CapableCheckMessage<\n T,\n TModules extends readonly RevivableModule[],\n Ctx extends RevivableContext,\n> =\n IsJsonOnlyTransport<Ctx['transport']> extends true\n ? [T] extends [Capable<TModules, RevivableContext>]\n ? 'Value type is only supported on structured-clone transports, not on JSON transports'\n : 'Value type must resolve to a Capable'\n : 'Value type must resolve to a Capable'\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]: CapableCheckMessage<T, TModules, Ctx>\n [BadValue]: BadFieldValue<T, Capable<TModules, Ctx>>\n [Path]: BadFieldPath<T, Capable<TModules, Ctx>>\n [ParentObject]: BadFieldParent<T, Capable<TModules, Ctx>>\n }\n\n/**\n * Expose a value to whoever connects, and get back what they exposed.\n *\n * Wrap `value` in `context` to build it once per connection, which is what lets one server answer\n * each realm differently (scoped resolvers per app) instead of sharing one object across all of them.\n * A bare function stays a plain exposed endpoint, so the wrapper is what disambiguates the two.\n *\n * The result is both awaitable and async-iterable: awaiting gives the first peer, iterating gives\n * every peer as it connects. Both hand back the same shape.\n *\n * ```ts\n * const remote = await expose(resolvers, { transport }) // the first peer's value\n * for await (const remote of expose(resolvers, { transport })) { } // every peer's value\n * ```\n *\n * `connection` decides what that shape is. Omit it and it is the peer's value, which is what expose\n * has always resolved to. Return whatever a connection should mean instead:\n *\n * ```ts\n * const { value, context } = await expose(resolvers, {\n * transport,\n * connection: ({ value, context }) => ({ value, context }),\n * })\n *\n * for await (const peer of expose(resolvers, {\n * transport,\n * connection: ({ value, context }) => ({ value, context }),\n * })) {\n * if (!allowed(peer.context.origin)) peer.context.abort?.()\n * }\n * ```\n *\n * A peer's identity is whatever the transport can observe merged over whatever the caller declared\n * in `context`. Only a window message carries a browser-set origin and source; a MessagePort message\n * carries neither, so a port-based server declares what it learned when it received the port.\n * Observed fields win over declared ones, so a declaration can never spoof a real origin.\n */\nexport const expose = <\n T = unknown,\n const TModules extends readonly RevivableModule[] = DefaultRevivableModules,\n const TTransport extends Transport = Transport,\n // after TValue, not before it: these are positional, so slotting a new one into the middle\n // silently reassigns every explicit type argument a consumer already wrote\n const TValue = Capable<TModules, RevivableContextOf<TTransport>>,\n TResult = Remote<T>\n>(\n value:\n | CapableCheck<TValue, TModules, RevivableContextOf<TTransport>>\n | Contextual<CapableCheck<TValue, TModules, RevivableContextOf<TTransport>>>,\n // intersecting instead of omitting gives `connection` two signatures at once, and its parameter\n // degrades to a union of both\n options: Omit<StartConnectionsOptions<TModules>, 'connection'> & {\n transport: TTransport\n connection?: (connected: Connected<Remote<T>>) => TResult\n }\n): Exposed<TResult> =>\n startConnections<Remote<T>, TModules, TResult>(\n value as Capable<TModules> | Contextual<Capable<TModules>>,\n options as StartConnectionsOptions<TModules>\n )\n"],"mappings":"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"}