posipaki 0.45.0 → 0.45.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket-CAyMntP1.js","names":[],"sources":["../src/remote/process-ref.ts","../src/remote/channel.ts","../src/remote/protocols/json1.ts","../src/remote/remote-process.ts","../src/remote/process-streams.ts","../src/remote/sender.ts","../src/remote/call-side.ts","../src/remote/stream.ts","../src/remote/server.ts","../src/remote/reactor.ts","../src/remote/output.ts","../src/remote/client.ts","../src/remote/lines.ts","../src/remote/transports/websocket.ts"],"sourcesContent":["// ── Process references on the wire ─────────────────────────────────────────\n//\n// A process is not JSON: it holds state, children and methods. So a reflection\n// method that returns one cannot answer with the process itself — it answers\n// with a reference, and the caller is handed what it can read: a name, and an id\n// this connection uses for that process.\n//\n// The id belongs to the connection and to the side that holds the process: that\n// side allocates it, and both sides then know the process by it. Allocated once\n// per process — handed over twice, it is the same reference both times — and\n// never reused, so an id whose process is gone resolves to nothing rather than to\n// whatever came after it.\n//\n// The two sides allocate from one space, split by parity: the client takes the\n// odd ids, the server the even ones. Every connection also has a root, and a root is\n// numbered like anything else — the first id of the parity of the side that holds it:\n// 0 on the even side (the server), 1 on the odd one (the client). So an id says on\n// its own which side holds the process it names, the two roots included, and a frame's\n// address means the same thing whoever reads it.\n//\n// A side's own root is the process the connection is, and the far side's root is a\n// handle here like any of theirs. Neither end has to be told which number belongs to\n// whom: each root is the first id of its own parity.\n\nimport { isProcess } from \"../process.async.js\";\nimport type { RemoteProcess } from \"./remote-process.js\";\nimport { isPlainObject, isStreamLike } from \"./channel.js\";\n\n/** The key that marks a process reference inside an otherwise JSON value. */\nexport const PROCESS_REF = \"$p\";\n\n/**\n * The id a side gives its own root: the first id of its parity. The two ends of a\n * connection therefore number their roots differently, and an id says whose root it is\n * as it says who holds every other process. A side hands out its next id from two\n * steps further on, the one in between belonging to the root of the side it talks to.\n */\nexport function rootIdFor(parity: IdParity): number {\n return parity === \"odd\" ? 1 : 0;\n}\n\n/** What a served root is called when the client states no name for it. A client that\n * states one — and the library's own does, in `$init` — is served under that name instead:\n * the process across the seam is the one its proxy was forked as, and it should be called\n * the same on both sides. This is the name for a connection that says nothing. */\nexport const SERVED_ROOT_NAME = \"remote\";\n\n/** What crosses the wire in place of a process. */\nexport interface ProcessRef {\n id: number;\n pname: string;\n}\n\n/** The little a table needs of what it holds to name it: what it is called, and\n * the symbol that identifies it in this build. */\nexport interface ProcessHandle {\n readonly pname: string;\n readonly id: symbol;\n}\n\n/** Which ids a side hands out: the client takes the odd ones, the server the\n * even ones, so one number can never name a process on both sides at once. */\nexport type IdParity = \"odd\" | \"even\";\n/** The end of the low band: ids 0 and 1 are the two roots, 2 through 8 belong to a party that speaks\n * on a connection it otherwise only relays — the first stage's own streams — and nothing allocates\n * inside it, so a band id can never collide with one either end mints. */\nexport const LOW_BAND_END = 8;\n\n/**\n * The ids one side of a connection hands out: its own parity, from the far side of the low band.\n *\n * Everything numbered on the connection draws from one space — a process reference and a stream alike —\n * so a number names one thing, and the parity says which side made it. Each side builds its own and\n * hands the same one to whatever allocates.\n */\nexport class IdSpace {\n private pvtNext: number;\n /** True for a space inside the low band, which refuses to leave it. */\n private readonly pvtBand: boolean;\n\n constructor(\n readonly parity: IdParity,\n first: number = parity === \"odd\" ? LOW_BAND_END + 1 : LOW_BAND_END + 2,\n ) {\n this.pvtNext = first;\n this.pvtBand = first <= LOW_BAND_END;\n }\n\n /** This side's own end of the connection: the first id of its parity, never handed out. */\n root(): number {\n return rootIdFor(this.parity);\n }\n\n /** The next id of this side's parity, and never the same one twice. */\n next(): number {\n if (this.pvtBand && this.pvtNext > LOW_BAND_END) throw new Error(\"IdSpace: the low band is spent\");\n const id = this.pvtNext;\n this.pvtNext += 2;\n return id;\n }\n}\n\n/**\n * A space inside the low band, for a party that speaks on a connection it otherwise relays: its ids\n * come from a range no end allocates in, so announcing something of its own cannot take a number\n * either end might mint.\n */\nexport function lowBand(parity: IdParity): IdSpace {\n return new IdSpace(parity, parity === \"odd\" ? 3 : 2);\n}\n\n/**\n * The processes one connection knows, by the ids that name them. One table per\n * connection, because an id means nothing on any other one, and it lives exactly\n * as long as the connection that owns it.\n *\n * It holds two sets, told apart by parity rather than kept apart by a rule: the\n * processes this side holds — the root, and anything it hands over — and the ones\n * the far side holds, which this side knows as handles. A frame's address is\n * looked up in both, and exactly one can answer.\n */\nexport class ProcessTable<P extends ProcessHandle = ProcessHandle> {\n /** This side's own processes, by the ids it gave them. */\n private pvtMine = new Map<number, P>();\n private pvtMineIds = new Map<P, number>();\n /** The far side's processes, by the ids they came with. */\n private pvtTheirs = new Map<number, P>();\n /** The id of this side's own root: the first of its parity. */\n private pvtRootId: number;\n /** The id the far side gave its root: the first of its parity, and the number this\n * side's own numbering skips. */\n private pvtFarRootId: number;\n /** Told the first time a process is numbered — the moment it is about to\n * cross the connection. */\n private pvtOnCrossed: ((proc: P, id: number) => void) | undefined;\n /** Where the ids come from: one space per side, shared with whatever else numbers something. */\n private readonly ids: IdSpace;\n\n constructor(parity: IdParity, onCrossed?: (proc: P, id: number) => void, ids: IdSpace = new IdSpace(parity)) {\n this.ids = ids;\n this.pvtRootId = ids.root();\n this.pvtFarRootId = rootIdFor(parity === \"odd\" ? \"even\" : \"odd\");\n this.pvtOnCrossed = onCrossed;\n }\n\n /** The id of this side's own end of the connection. */\n rootId(): number {\n return this.pvtRootId;\n }\n\n /** The id the far side knows its own end by: the root this side reaches as a handle,\n * and the one it never hands out for anything of its own. */\n farRootId(): number {\n return this.pvtFarRootId;\n }\n\n /** Bind this side's own end of the connection — the root — to its id. */\n bindRoot(proc: P): void {\n const bound = this.pvtMine.get(this.pvtRootId);\n if (bound !== undefined && bound !== proc) {\n throw new Error(\"ProcessTable: the root is already bound\");\n }\n this.pvtMine.set(this.pvtRootId, proc);\n this.pvtMineIds.set(proc, this.pvtRootId);\n }\n\n /** The id this side gives a process it holds, allocating one the first time. */\n handleFor(proc: P): number {\n const known = this.pvtMineIds.get(proc);\n if (known !== undefined) return known;\n const id = this.ids.next();\n this.pvtMine.set(id, proc);\n this.pvtMineIds.set(proc, id);\n this.pvtOnCrossed?.(proc, id);\n return id;\n }\n\n /** A process this side holds, by the id it gave it. */\n processFor(id: number): P | undefined {\n return this.pvtMine.get(id);\n }\n\n /**\n * Register a process the far side holds — a handle — under the id it arrived\n * with. A root is one of these as much as anything else: both ends hold one at 0,\n * so the far side's root is a handle here, and the one this side has of itself\n * stays what it was.\n */\n bindFar(id: number, proc: P): void {\n this.pvtTheirs.set(id, proc);\n }\n\n /** A process the far side holds, by the id it gave it. */\n farHandleFor(id: number): P | undefined {\n return this.pvtTheirs.get(id);\n }\n\n /**\n * Whatever this connection knows `id` to mean: a process this side holds, or a\n * handle on one the far side holds. Only one of the two can answer, because\n * the two sides take their ids from different halves of the space — so what\n * comes back does not depend on which way the frame was going.\n */\n resolve(id: number): P | undefined {\n return this.pvtMine.get(id) ?? this.pvtTheirs.get(id);\n }\n\n /**\n * Let go of an id: the process behind it is not this connection's business any\n * more, so it is no longer known by it. Both sides' ids go the same way — the\n * side that lets a handle go names the far side's id, the side that is asked to\n * forget names its own — and an id let go is never handed out again, so nothing\n * that still names it can come to mean another process.\n *\n * Neither root is let go of: one is this side's own end of the connection, and the\n * other is what this side is talking to.\n */\n release(id: number): P | undefined {\n if (id === this.pvtRootId || id === this.pvtFarRootId) return undefined;\n const mine = this.pvtMine.get(id);\n if (mine !== undefined) {\n this.pvtMine.delete(id);\n this.pvtMineIds.delete(mine);\n return mine;\n }\n const theirs = this.pvtTheirs.get(id);\n if (theirs !== undefined) this.pvtTheirs.delete(id);\n return theirs;\n }\n\n /** Every handle this side holds on a process of the far side. */\n handles(): P[] {\n return [...this.pvtTheirs.values()];\n }\n}\n\n/** Whether `value` is the wire form of a reference. */\nexport function asProcessRef(value: unknown): ProcessRef | null {\n if (typeof value !== \"object\" || value === null) return null;\n const ref = (value as Record<string, unknown>)[PROCESS_REF];\n if (typeof ref !== \"object\" || ref === null) return null;\n const { id, pname } = ref as Record<string, unknown>;\n if (typeof id !== \"number\" || typeof pname !== \"string\") return null;\n return { id, pname };\n}\n\n/** Whether `value` has the shape of a handle on a far-side process. Judged by\n * what it holds rather than by `instanceof`, for the reason a process is: one\n * build can hold two copies of the class. */\nexport function isRemoteProcess(value: unknown): value is RemoteProcess {\n if (typeof value !== \"object\" || value === null) return false;\n const candidate = value as { pname?: unknown; id?: unknown; ref?: unknown; send?: unknown };\n return (\n typeof candidate.pname === \"string\" &&\n typeof candidate.id === \"symbol\" &&\n typeof candidate.send === \"function\" &&\n asProcessRef({ [PROCESS_REF]: candidate.ref }) !== null\n );\n}\n\n/**\n * Replace every process in `value` with the reference this connection uses for\n * it, so what is left is JSON that says which processes the answer is about.\n *\n * A handle goes back as the reference it came with, id and all: that id is the\n * far side's own, the one it will be read by.\n *\n * Containers are copied rather than rewritten: the objects belong to the actor\n * that returned them, and a state it is still running on is not ours to edit. A\n * node already seen is left where it is — a cycle is the encoder's to report, not\n * something to walk forever.\n */\nexport function encodeProcessRefs(\n value: unknown,\n table: ProcessTable,\n seen: Set<unknown> = new Set(),\n): unknown {\n // A stream is carried by reference too, and its behaviour lives on a symbol-keyed property a\n // copy would drop. It is the stream layer's value to offer, so it is left as it is here.\n if (isStreamLike(value)) return value;\n if (isRemoteProcess(value)) {\n return { [PROCESS_REF]: { id: value.ref.id, pname: value.ref.pname } };\n }\n if (isProcess(value)) {\n return { [PROCESS_REF]: { id: table.handleFor(value), pname: value.pname } };\n }\n if (Array.isArray(value)) {\n if (seen.has(value)) return value;\n seen.add(value);\n return value.map((item) => encodeProcessRefs(item, table, seen));\n }\n if (isPlainObject(value)) {\n if (seen.has(value)) return value;\n seen.add(value);\n const copy: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) {\n copy[key] = encodeProcessRefs(item, table, seen);\n }\n return copy;\n }\n return value;\n}\n\n/** How a side turns a reference into something it can hold: a handle. */\nexport type RefResolver = (ref: ProcessRef) => unknown;\n\n/** Replace every reference in `value` with what `resolve` makes of it. */\nexport function decodeProcessRefs(\n value: unknown,\n resolve: RefResolver,\n seen: Set<unknown> = new Set(),\n): unknown {\n // A stream is carried by reference too, and its behaviour lives on a symbol-keyed property a\n // copy would drop. It is the stream layer's value to offer, so it is left as it is here.\n if (isStreamLike(value)) return value;\n const ref = asProcessRef(value);\n if (ref) return resolve(ref);\n if (Array.isArray(value)) {\n if (seen.has(value)) return value;\n seen.add(value);\n return value.map((item) => decodeProcessRefs(item, resolve, seen));\n }\n if (isPlainObject(value)) {\n if (seen.has(value)) return value;\n seen.add(value);\n const copy: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) {\n copy[key] = decodeProcessRefs(item, resolve, seen);\n }\n return copy;\n }\n return value;\n}\n","// ── Frame channel ──────────────────────────────────────────────────────────\n//\n// The seam's shared vocabulary. A StringTransport moves encoded frames\n// (strings); a Channel moves decoded frame objects. The frame guards narrow a\n// decoded frame to one of the `$`-key shapes. server.ts / client.ts speak only\n// in Channels and these guards — they never see a specific protocol or\n// transport.\n\nimport type { FrameChannel, Message } from \"../types.js\";\nimport {\n decodeProcessRefs,\n encodeProcessRefs,\n type ProcessTable,\n type RefResolver,\n} from \"./process-ref.js\";\n\nexport interface StringTransport {\n send(frame: string): void | Promise<void>;\n /**\n * A line arrived. Answer with the number of raw octets that follow it, if any: a frame\n * may announce a run of bytes (a chunk of a stream), and the transport then hands those\n * octets over instead of reading them as more lines.\n */\n onMessage(handler: (frame: string) => number | void): void;\n /** The octets a line announced, whole, in the order they were sent. */\n onBytes(handler: (bytes: Uint8Array) => void): void;\n removeHandler(): void;\n /** Raw octets, written after whatever went before them. */\n sendBytes(bytes: Uint8Array): void | Promise<void>;\n /** Fires when the peer disconnects (transport closes from the other side). */\n onClose(handler: () => void): void;\n close(): Promise<void>;\n}\n\n/**\n * What the frame layer needs of a connection's values: two walks, and no knowledge of how the\n * bytes travel. The frame vocabulary lives in this file and the machinery in\n * `stream.ts`, so a store comes in as this shape rather than as an import from here.\n */\nexport interface ValueCodec {\n /** Replace every value that must cross by reference with one this connection serves. */\n encode(value: unknown): unknown;\n /** Replace every reference in a value with something the reader can hold. */\n decode(value: unknown): unknown;\n}\n\n/**\n * Several codecs over one connection, each value through all of them, in the order given.\n *\n * A connection carries more than one kind of thing by reference — a blob, a stream — and each\n * store knows only its own. Walking a value through every store in turn is what keeps them\n * from having to know about each other.\n */\nexport function combineCodecs(...codecs: ValueCodec[]): ValueCodec {\n return {\n encode: (value) => codecs.reduce((current, codec) => codec.encode(current), value),\n decode: (value) => codecs.reduce((current, codec) => codec.decode(current), value),\n };\n}\n\n/** The frames of one connection, as the remote layer speaks them: the process's own `FrameChannel`,\n * where a reader has the unsubscribe `onMessage` returned rather than a handler to take back. */\nexport type Channel = FrameChannel;\n\n/** Is this something JSON would carry as an object, rather than an instance with behaviour? */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const prototype = Object.getPrototypeOf(value) as object | null;\n return prototype === Object.prototype || prototype === null;\n}\n\n/**\n * Is this a stream — a value whose bytes come later, carried by reference?\n *\n * The question every walk that copies containers has to ask: copying a stream keeps the object and\n * loses the behaviour, because its iterator is a symbol-keyed property and `Object.entries` does not\n * see those. What such a value is belongs to `stream.ts`; that it must be left alone belongs to\n * every layer that walks a message.\n */\nexport function isStreamLike(value: unknown): value is AsyncIterable<Uint8Array> {\n if (typeof value !== \"object\" || value === null) return false;\n return typeof (value as Partial<AsyncIterable<Uint8Array>>)[Symbol.asyncIterator] === \"function\";\n}\n\n/**\n * One handler on the wire, however many readers on it. A transport holds one handler — and reports a\n * second one as a mistake — so the layer above keeps the readers and installs a single handler; the\n * subscribe this returns is what a reader calls to leave. The handler goes on with the first reader and\n * stays for the life of the connection: taking it off between readers would drop whatever arrives in\n * between, and a connection is not paused by nobody reading it.\n */\nexport function frameReaders(\n install: (deliver: (frame: Record<string, unknown>) => void) => void,\n): (handler: (frame: Record<string, unknown>) => void) => () => void {\n const readers = new Set<(frame: Record<string, unknown>) => void>();\n let installed = false;\n return (handler) => {\n if (!installed) {\n installed = true;\n install((frame) => {\n // Over a copy: a reader that leaves as it is handed a frame must not cut the rest short.\n for (const reader of [...readers]) reader(frame);\n });\n }\n readers.add(handler);\n return () => {\n readers.delete(handler);\n };\n };\n}\n\n/**\n * A channel that is `base`, with every incoming frame offered to `onFrame` first — and not handed\n * on when it is claimed.\n *\n * Every wrapper above a protocol wants this one thing, and none of them may lose the octets: a\n * connection that carries segments keeps carrying them through whatever wraps it, or a stream\n * dies one layer above the wire it was written for.\n */\nexport function channelThrough(base: Channel, onFrame: (frame: Record<string, unknown>) => boolean): Channel {\n const wrapped: Channel = {\n send: (frame) => base.send(frame),\n onMessage: (handler) =>\n base.onMessage((frame) => {\n if (onFrame(frame)) return;\n handler(frame);\n }),\n onClose: (handler) => base.onClose(handler),\n close: () => base.close(),\n };\n if (base.sendSegment) {\n wrapped.sendSegment = (frame, bytes) => base.sendSegment?.(frame, bytes);\n }\n if (base.onSegment) {\n wrapped.onSegment = (handler) => base.onSegment?.(handler) ?? (() => {});\n }\n return wrapped;\n}\n\n// ── the address on a frame ─────────────────────────────────────────────────\n//\n// A frame that is about a process carries that process's id as `to`, at the top level\n// of the frame rather than inside its body: the frame is the envelope, and the address\n// says who it is for whatever kind it turns out to be. Every frame that is about a\n// process names it, the root of the connection included, since both ends number their\n// own root and neither has to be guessed at.\n\n/** The id a frame addresses, or null when it names no process. */\nexport function frameTo(frame: Record<string, unknown>): number | null {\n const to = frame.to;\n return typeof to === \"number\" ? to : null;\n}\n\n/**\n * A frame on its way out: every process in it becomes the reference this\n * connection uses for that process, and the process the frame addresses is\n * written down as `to`.\n */\nexport function encodeFrame(\n frame: Record<string, unknown>,\n table: ProcessTable,\n to: number,\n codecs?: ValueCodec,\n): Record<string, unknown> {\n const withProcesses = encodeProcessRefs(frame, table) as Record<string, unknown>;\n const encoded = codecs === undefined ? withProcesses : (codecs.encode(withProcesses) as Record<string, unknown>);\n return { ...encoded, to };\n}\n\n/**\n * A frame just read: every reference in it becomes a handle on that process — or\n * the handle this side already made for it, since the same process handed over\n * twice is one process.\n */\nexport function decodeFrame(\n frame: Record<string, unknown>,\n resolve: RefResolver,\n codecs?: ValueCodec,\n): Record<string, unknown> {\n const resolved = decodeProcessRefs(frame, resolve) as Record<string, unknown>;\n return codecs === undefined ? resolved : (codecs.decode(resolved) as Record<string, unknown>);\n}\n\n// ── frame guards ──────────────────────────────────────────────────────────\n//\n// Each guard narrows a decoded frame to the frame it is, and each of those types is\n// named, so the whole set can be written down once (see `Frame`, at the foot of this\n// file). A guard asks only whether the key is there: the body under it belongs to\n// whoever wrote it.\n\nexport type ProtoFrame = {\n $proto: string;\n};\nexport type InitFrame = {\n $init: Record<string, unknown>;\n};\nexport type StateFrame = {\n $state: Record<string, unknown>;\n};\nexport type MsgFrame = {\n $msg: { fromName: string; body: Message };\n};\nexport type ExitFrame = {\n $exit: { code: number; state: unknown };\n};\n\nexport function isProto(msg: Record<string, unknown>): msg is ProtoFrame {\n return \"$proto\" in msg;\n}\nexport function isInit(msg: Record<string, unknown>): msg is InitFrame {\n return \"$init\" in msg;\n}\nexport function isState(msg: Record<string, unknown>): msg is StateFrame {\n return \"$state\" in msg;\n}\nexport function isMsg(msg: Record<string, unknown>): msg is MsgFrame {\n return \"$msg\" in msg;\n}\nexport function isExit(msg: Record<string, unknown>): msg is ExitFrame {\n return \"$exit\" in msg;\n}\n\n// ── a wire that could not be read ─────────────────────────────────────────\n//\n// Two frames are about the wire itself and not about a process: what a codec could\n// not read, and what a side says when the wire is over. Neither is addressed to\n// anything, and both are decided before a frame is looked up as news or as an ask —\n// a frame about the wire is about the ground the other frames stand on.\n//\n// {\"$bad\": {\"reason\": \"…\", \"raw\": \"…\"}} this side could not read that frame\n// {\"$error\": \"…\"} the wire cannot be spoken over, and why\n//\n// They are frames rather than raised errors on purpose. A frame is read inside the\n// transport's own callback — a socket's `message` event, a stream's line reader —\n// where a throw belongs to nobody: it arrives at the host as an uncaught exception,\n// and one unreadable frame from one peer takes the process down, every other\n// connection in it included. An unreadable frame is the connection's business, not\n// the process's, so it is carried as a frame the connection can answer: `$bad` is how\n// a reader says it inward, and `$error` is how a side says it outward before ending\n// that connection.\n//\n// `$error` is not a refused call — a call that is refused says so about itself, in\n// `$r.result.<name>` (see below). This one is about the wire the calls travel on.\n\nconst BAD_KEY = \"$bad\";\n\n/** How much of an unreadable line is carried: enough to see what it was, never enough to be it.\n * A line that failed to parse is the one line nobody vouched for, so quoting it whole would move\n * whatever it holds — a credential in a paste accident is how that happens — into every log,\n * transcript and context window that later reads the frame. Why, how long, and a short head of\n * it. (`reason` carries a little of the line on its own: a JSON parser says where it gave up and\n * quotes what it was looking at. That is the parser's business, not a promise this file makes.) */\nexport const BAD_PREFIX_LIMIT = 32;\n\nexport type BadFrame = {\n $bad: { reason: string };\n};\n\nexport function isBad(msg: Record<string, unknown>): msg is BadFrame {\n return BAD_KEY in msg;\n}\n\n/** The frame that says a frame could not be read: why, how long it was, and the head of it. */\nexport function badFrame(reason: string, raw: string): Record<string, unknown> {\n const prefix = raw.length > BAD_PREFIX_LIMIT ? `${raw.slice(0, BAD_PREFIX_LIMIT)}…` : raw;\n return { [BAD_KEY]: { reason, length: raw.length, prefix } };\n}\n\n/** Why a frame could not be read, or null when it is not a frame that says so. */\nexport function badReason(msg: Record<string, unknown>): string | null {\n const body = msg[BAD_KEY];\n if (typeof body !== \"object\" || body === null) return null;\n const reason = (body as { reason?: unknown }).reason;\n return typeof reason === \"string\" ? reason : null;\n}\n\nconst ERROR_KEY = \"$error\";\n\nexport type ErrorFrame = {\n $error: string;\n};\n\nexport function isError(msg: Record<string, unknown>): msg is ErrorFrame {\n return ERROR_KEY in msg;\n}\n\n/** The frame that says the wire is over: the reason, and the connection ends with it. */\nexport function errorFrame(reason: string): Record<string, unknown> {\n return { [ERROR_KEY]: reason };\n}\n\n/** The reason a wire error carries, or null when it is not one. */\nexport function errorReason(msg: Record<string, unknown>): string | null {\n const reason = msg[ERROR_KEY];\n return typeof reason === \"string\" ? reason : null;\n}\n\n// A process that crossed can be asked for less than everything, or for nothing at\n// all: what crosses about it is three categories, and only the ones asked for are\n// sent. Silence is the empty list, so a handle that asks for nothing hears\n// nothing — not its state, not its messages, and not that it is gone.\n//\n// {\"$tune\": {\"streams\": [\"state\"]}, \"to\": 3} this much about it, and no more\n\nexport type StreamKind = \"message\" | \"state\" | \"exit\";\n\n/** The three, in the one order they are ever named in — the order a tune frame\n * carries them in, so two ways of asking for the same thing look the same. */\nexport const STREAM_KINDS: StreamKind[] = [\"message\", \"state\", \"exit\"];\n\nexport function isStreamKind(value: unknown): value is StreamKind {\n return typeof value === \"string\" && (STREAM_KINDS as string[]).includes(value);\n}\n\n// ── control frames ─────────────────────────────────────────────────────────\n//\n// What the holder of a handle can ask of a process on the far side, beside\n// sending it a message. Each is a frame of its own rather than a message, so\n// nothing an actor reads is ever a control signal by accident:\n//\n// {\"$stop\": {}, \"to\": 3} stop it; it ends, and its `$exit` crosses back\n// {\"$pause\": {}, \"to\": 3} stop feeding it messages\n// {\"$resume\": {}, \"to\": 3} feed it again\n// {\"$release\": {}, \"to\": 3} let it go: forget this id, and stop telling me\n// about the process behind it\n// {\"$tune\": {\"streams\": [...]}, \"to\": 3}\n// say this much about it and no more: a subset of\n// message, state and exit, or the empty list for\n// silence\n//\n// They address the process they are about, so they are answered by whoever holds\n// that process — the side that can act on it. Stopping the *root* of a connection\n// is not one of these: that stays the STOP message it always was, since the root\n// is not a handle but the process this side is talking through.\n\nexport type StopFrame = {\n $stop: Record<string, unknown>;\n};\nexport type PauseFrame = {\n $pause: Record<string, unknown>;\n};\nexport type ResumeFrame = {\n $resume: Record<string, unknown>;\n};\nexport type ReleaseFrame = {\n $release: Record<string, unknown>;\n};\nexport type TuneFrame = {\n $tune: Record<string, unknown>;\n};\n\nexport function isStop(msg: Record<string, unknown>): msg is StopFrame {\n return \"$stop\" in msg;\n}\nexport function isPause(msg: Record<string, unknown>): msg is PauseFrame {\n return \"$pause\" in msg;\n}\nexport function isResume(msg: Record<string, unknown>): msg is ResumeFrame {\n return \"$resume\" in msg;\n}\nexport function isRelease(msg: Record<string, unknown>): msg is ReleaseFrame {\n return \"$release\" in msg;\n}\nexport function isTune(msg: Record<string, unknown>): msg is TuneFrame {\n return \"$tune\" in msg;\n}\n\n/**\n * The categories a tune frame asks for, in the order they are named in — or null\n * when the frame says something this vocabulary has no word for, which is a frame\n * to ignore rather than to guess at.\n */\nexport function tuneFrame(frame: { $tune: unknown }): StreamKind[] | null {\n const body = frame.$tune;\n if (typeof body !== \"object\" || body === null) return null;\n const streams = (body as { streams?: unknown }).streams;\n if (!Array.isArray(streams)) return null;\n if (!streams.every(isStreamKind)) return null;\n return STREAM_KINDS.filter((kind) => (streams as StreamKind[]).includes(kind));\n}\n\n// ── reflection frames ──────────────────────────────────────────────────────\n//\n// A reflection call crosses the seam as one frame and its answer as another, and\n// both go both ways: whoever holds a process is the one that answers for it.\n//\n// {\"$r.methods\": [\"inspect.getTree\", …]} what a process can answer, once, when\n// it crosses (and, for the root, once\n// when the connection opens)\n// {\"$r.call.<name>\": {seq, args}} asking, addressed to the process\n// {\"$r.result.<name>\": {seq, value}} answered\n// {\"$r.result.<name>\": {seq, error}} refused\n//\n// The method name is in the frame key, so a frame says what it is without a\n// table, and `seq` — one connection's, never reused — tells two calls to the\n// same method apart while both are in flight. An answer is about the call and not\n// about a process, so it carries no address: it names the seq it settles.\n\nexport const REFLECT_METHODS = \"$r.methods\";\nexport const REFLECT_CALL = \"$r.call.\";\nexport const REFLECT_RESULT = \"$r.result.\";\n\nexport interface ReflectionCall {\n name: string;\n seq: number;\n args: unknown[];\n}\n\nexport interface ReflectionResult {\n name: string;\n seq: number;\n value?: unknown;\n error?: string;\n}\n\nexport type ReflectionMethodsFrame = {\n \"$r.methods\": string[];\n};\n\n/** A call frame: the method in the key, the call in the body (`$r.call.<name>`). */\nexport type ReflectionCallFrame = {\n [key: `$r.call.${string}`]: { seq: number; args?: unknown[] };\n};\n\n/** An answer frame: `value` or `error`, naming the seq it settles. */\nexport type ReflectionResultFrame = {\n [key: `$r.result.${string}`]: { seq: number; value?: unknown; error?: string };\n};\n\nexport function isReflectionMethods(msg: Record<string, unknown>): msg is ReflectionMethodsFrame {\n const names = msg[REFLECT_METHODS];\n return Array.isArray(names) && names.every((name) => typeof name === \"string\");\n}\n\nfunction reflectionBody(\n frame: Record<string, unknown>,\n prefix: string,\n): { name: string; body: Record<string, unknown> } | null {\n for (const key of Object.keys(frame)) {\n if (!key.startsWith(prefix) || key.length === prefix.length) continue;\n const body = frame[key];\n if (typeof body !== \"object\" || body === null) return null;\n return { name: key.slice(prefix.length), body: body as Record<string, unknown> };\n }\n return null;\n}\n\n/** A call frame, or null — a malformed one is not worth an answer. */\nexport function asReflectionCall(frame: Record<string, unknown>): ReflectionCall | null {\n const parsed = reflectionBody(frame, REFLECT_CALL);\n if (!parsed || typeof parsed.body.seq !== \"number\") return null;\n const args = parsed.body.args;\n return {\n name: parsed.name,\n seq: parsed.body.seq,\n args: Array.isArray(args) ? args : [],\n };\n}\n\n/** An answer frame, or null. `error` present means the call was refused. */\nexport function asReflectionResult(frame: Record<string, unknown>): ReflectionResult | null {\n const parsed = reflectionBody(frame, REFLECT_RESULT);\n if (!parsed || typeof parsed.body.seq !== \"number\") return null;\n const { seq, value, error } = parsed.body;\n return typeof error === \"string\"\n ? { name: parsed.name, seq, error }\n : { name: parsed.name, seq, value };\n}\n\n/**\n * Why a value cannot cross a frame, or null when it can. Only JSON data\n * crosses: a function, a symbol or a bigint cannot be written down at all, and\n * a value with a cycle or a bigint inside it makes the encoder throw. What\n * JSON itself would quietly drop — a function stored inside an object — is the\n * caller's business, not something to invent a policy for here.\n */\nexport function jsonProblem(value: unknown): string | null {\n const kind = typeof value;\n if (kind === \"function\" || kind === \"symbol\" || kind === \"bigint\") return `a ${kind}`;\n if (kind !== \"object\" || value === null) return null;\n try {\n JSON.stringify(value);\n } catch (err) {\n return err instanceof Error ? err.message : String(err);\n }\n return null;\n}\n\n// ── the frames, as one type ────────────────────────────────────────────────\n//\n// The guards above say what a frame is one at a time; this is the same set as one type.\n// Neither direction nor protocol is in it — who may send which is the two ends' business,\n// and the handshake names the protocol that writes them. The address a frame carries\n// (`to`, `frameTo`) is the envelope the connection writes around it, not the frame.\n\nexport type Frame =\n | ProtoFrame\n | InitFrame\n | StateFrame\n | MsgFrame\n | ExitFrame\n | BadFrame\n | ErrorFrame\n | StopFrame\n | PauseFrame\n | ResumeFrame\n | ReleaseFrame\n | TuneFrame\n | ReflectionMethodsFrame\n | ReflectionCallFrame\n | ReflectionResultFrame;\n","// ── json1 wire protocol ────────────────────────────────────────────────────\n//\n// One JSON object per frame: `{\"$key\": value}`. encode/decode turn a decoded\n// frame object into a string and back. json1Channel wraps a StringTransport so\n// it moves frame objects instead of strings.\n//\n// This is the boundary where the wire's bytes become a frame, and it is the one\n// place a bad peer can throw into a callback that belongs to nobody but the host:\n// the handler runs where the transport called it — a socket's `message` event, a\n// line reader — so a `SyntaxError` here is an uncaught exception and takes the\n// process down. So a line that will not parse is not thrown at the caller: it\n// becomes the frame that says so (`$bad`, channel.ts) and travels inward like any\n// other, where the connection it came from can answer for it.\n//\n// One frame is one JSON *object*: a line that parses to a number, a string, an\n// array or `null` is not a frame either, and reading one as a frame (`\"$init\" in 7`)\n// throws just as surely as a line that never parsed.\n\nimport { badFrame, type Channel, type StringTransport } from \"../channel.js\";\n\nexport const VERSION = \"json.v1\";\n\n/** The frames this protocol carries. The shapes and the union are in channel.ts; a protocol\n * owns that the connection speaks them, and how they are written down. */\nexport type { Frame } from \"../channel.js\";\n\nexport function encode(frame: Record<string, unknown>): string {\n return JSON.stringify(frame);\n}\n\n/** The frame a line carries, throwing on a line that is not JSON. `readFrame` is how the\n * seam reads a line; this is the primitive underneath it. */\nexport function decode(str: string): Record<string, unknown> {\n return JSON.parse(str);\n}\n\n/** A line read as a frame: the frame itself, or the frame that says this one could not be\n * read. Never throws — see the note at the top of this file. */\nexport function readFrame(str: string): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = decode(str);\n } catch (err) {\n return badFrame(err instanceof Error ? err.message : String(err), str);\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return badFrame(`a frame is one JSON object, and this was ${kindOf(parsed)}`, str);\n }\n return parsed as Record<string, unknown>;\n}\n\nfunction kindOf(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"an array\";\n return `a ${typeof value}`;\n}\n\n/**\n * The octets a frame announces after it, or null when it announces none.\n *\n * One shape only: a chunk head carries the number of raw octets that follow, and that number\n * is what keeps the reader's framing. A head without one is not a segment — it goes on as a\n * frame, and whoever reads it refuses it by name.\n */\nexport function announcedOctets(frame: Record<string, unknown>): number | null {\n const head = frame.$chunk;\n if (typeof head !== \"object\" || head === null) return null;\n const bytes = (head as { bytes?: unknown }).bytes;\n return typeof bytes === \"number\" && Number.isInteger(bytes) && bytes >= 0 ? bytes : null;\n}\n\nexport function json1Channel(transport: StringTransport): Channel {\n const frameReaders = new Set<(frame: Record<string, unknown>) => void>();\n const segmentReaders = new Set<(frame: Record<string, unknown>, bytes: Uint8Array) => void>();\n /** The head whose octets are on their way: set between the line and the run it announced. */\n let expecting: Record<string, unknown> | null = null;\n\n const deliver = (frame: Record<string, unknown>): void => {\n // Over a copy: a reader that leaves as it is handed a frame must not cut the rest short.\n for (const reader of [...frameReaders]) reader(frame);\n };\n\n // Both handlers go on at once: the octets have to be read even when nobody is listening for\n // them, or the next line starts in the wrong place and the connection is lost.\n transport.onMessage((str) => {\n const frame = readFrame(str);\n const octets = announcedOctets(frame);\n if (octets === null) {\n deliver(frame);\n return;\n }\n expecting = frame;\n return octets;\n });\n transport.onBytes((bytes) => {\n const frame = expecting;\n expecting = null;\n // Octets nobody announced are a peer talking past the protocol: they are said out loud\n // rather than attached to whatever frame happened to arrive last.\n if (frame === null) {\n deliver(badFrame(`${bytes.length} octets arrived that no frame announced`, \"\"));\n return;\n }\n for (const reader of [...segmentReaders]) reader(frame, bytes);\n });\n\n return {\n send(frame) {\n return transport.send(encode(frame));\n },\n onMessage(handler) {\n frameReaders.add(handler);\n return () => {\n frameReaders.delete(handler);\n };\n },\n async sendSegment(frame, bytes) {\n // The line first, then its octets, each written before the next is asked for: a chunk\n // that was queued behind a megabyte of earlier chunks is a chunk the writer ran ahead of\n // its reader with.\n await transport.send(encode(frame));\n await transport.sendBytes(bytes);\n },\n onSegment(handler) {\n segmentReaders.add(handler);\n return () => {\n segmentReaders.delete(handler);\n };\n },\n onClose(handler) {\n transport.onClose(handler);\n },\n close() {\n return transport.close();\n },\n };\n}\n","// ── A process on the far side, as this side can use it ─────────────────────\n//\n// A handle. It knows the name the far side calls the process and the id this\n// connection knows it by, and one thing more than a bare reference has: a way to\n// put a frame on the wire with that id. Everything else it offers is what comes\n// back because of it — the state that streams for it, the messages it emits, the\n// methods it announced.\n//\n// A handle is not a process of this side's tree. Nothing has to make it one:\n// the far side's tree is already reachable through reflection, so asking the\n// proxy for it walks that side and gives that tree. A handle is how something\n// on the far side is talked to, not where it sits here.\n\nimport type { Message } from \"../types.js\";\nimport { makeWaiter, type Waiter } from \"../util.js\";\nimport { PROCESS_REF, isRemoteProcess } from \"./process-ref.js\";\nimport { STREAM_KINDS, type StreamKind } from \"./channel.js\";\nimport type { ProcessRef } from \"./process-ref.js\";\n\n/**\n * What a reference with nothing keeping it amounts to. It names a process this side can\n * hear nothing from and ask nothing of, so it is not a process in any sense that matters\n * here, and it is written as what it is wherever it turns up: a state somebody is reading,\n * a log line, anything at all that stringifies.\n */\nexport const UNSTABLE_REFERENCE = \"UnstableReference\";\n\n/** What a process left behind when it ended. */\n/**\n * The references inside a value that crossed. A handle is the one thing in a frame that is\n * not JSON, so wherever one sits, it came here on somebody else's frame and whoever is\n * holding that value is holding it. Plain objects and arrays only: a value of another kind\n * is not a shape this walks, and its references are not found.\n */\nfunction refsInside(value: unknown): RemoteProcess[] {\n const found: RemoteProcess[] = [];\n const seen = new Set<unknown>();\n const walk = (node: unknown): void => {\n if (isRemoteProcess(node)) {\n found.push(node);\n return;\n }\n if (typeof node !== \"object\" || node === null) return;\n if (seen.has(node)) return;\n seen.add(node);\n if (Array.isArray(node)) {\n for (const item of node) walk(item);\n return;\n }\n const proto = Object.getPrototypeOf(node) as object | null;\n if (proto !== Object.prototype && proto !== null) return;\n for (const item of Object.values(node as Record<string, unknown>)) walk(item);\n };\n walk(value);\n return found;\n}\n\nexport interface RemoteExit {\n code: number;\n state: unknown;\n}\n\n/** How a handle gets a frame onto the connection it belongs to, addressed to a\n * process the far side holds. The answer is handed back when a caller has to know\n * the frame is out — the root's end is said that way, just before the wire closes. */\nexport type FrameSink = (frame: Record<string, unknown>, to: number) => void | Promise<void>;\n\n/** What a side does when it lets go of a handle: stop knowing the id, so nothing\n * arriving for it can land here again. */\nexport type ReleaseHook = (id: number) => void;\n\n/** An out-message of the far process, and the name it came with. */\nexport type RemoteMessage<OutMsg extends Message = Message> = (msg: OutMsg, fromName: string) => void;\n\nexport class RemoteProcess<InMsg extends Message = Message, OutMsg extends Message = Message> {\n /** The name the far side knows it by. */\n readonly pname: string;\n /** The id this connection knows it by — the far side's own, since it is the\n * side that holds the process. */\n readonly ref: ProcessRef;\n /** A symbol of this side's own, so a handle can be told apart from any other\n * the way a process is: by holding one. */\n readonly id: symbol;\n /** What the far side has said about its state so far. */\n state: Record<string, unknown> | null = null;\n /** The methods the far side announced it can answer. */\n readonly $reflection: Record<string, (...args: unknown[]) => Promise<unknown>> = {};\n\n private pvtSend: FrameSink;\n private pvtFromName: string;\n private pvtConnected = true;\n /** This side let it go: nothing more is asked of it, and nothing arriving for it\n * is news any more. Not the same as ending, and not the same as the connection\n * going: in all three the handle is dead, and only the reason differs. */\n private pvtReleased = false;\n private pvtLetGo: ReleaseHook | undefined;\n /** What the far side said when it ended, or null while it is running. */\n private pvtExit: RemoteExit | null = null;\n private pvtExitWaiter: Waiter<RemoteExit> | null = null;\n private pvtMessageSubs: Array<RemoteMessage<OutMsg>> = [];\n private pvtStateSubs: Array<() => void> = [];\n /** Whoever is waiting to hear what it holds, settled by the first word of it. */\n private pvtReadyWaiters: Array<() => void> = [];\n /** How many times this reference has been kept. Nothing is heard about a process\n * nothing here keeps, so the count is what makes a handle usable rather than a name. */\n private pvtRefCount = 0;\n /** The handles this one keeps because they sit in what it holds. Counted, and given\n * back when this one is let go of: the thing holding them is here. */\n private pvtOwnedRefs: RemoteProcess[] = [];\n /** The handles that arrived here on their way somewhere else, in a message or an answer.\n * Not counted — nobody here asked for them, and whoever receives them is the one to deal\n * with them — but remembered, so that one nobody ever keeps is let go of after all. */\n private pvtTransientRefs: RemoteProcess[] = [];\n /** What this side has asked to be told about it. A process that crosses is\n * silent, so a handle starts out having asked for nothing and hears nothing\n * until something here wants it — which is the same rule the far side holds,\n * written from the other end. */\n private pvtWanted: Set<StreamKind> = new Set();\n\n constructor(ref: ProcessRef, send: FrameSink, fromName: string, letGo?: ReleaseHook) {\n this.ref = ref;\n this.pname = ref.pname;\n this.id = Symbol(ref.pname);\n this.pvtSend = send;\n this.pvtFromName = fromName;\n this.pvtLetGo = letGo;\n }\n\n /**\n * Whether the process this handle names can still be reached: the wire is there, and\n * this side has not let the handle go.\n *\n * Reaching it is not the same as it being alive. A process that has ended is still\n * one this side has a handle on — it is what the handle points at, and what it left\n * behind is here — so an end does not put it out of reach; `hasEnded()` is that\n * answer, and the two are asked separately. From the two ways out there is no coming\n * back: no reconnect, and no way to un-release.\n */\n isConnected(): boolean {\n return this.pvtConnected && !this.pvtReleased;\n }\n\n /**\n * The connection is gone. Every handle this side holds goes out of reach with it,\n * and says so: there is no reconnect to wait for, so a send fails here and now\n * rather than disappearing into nothing.\n */\n disconnect(): void {\n if (!this.pvtConnected) return;\n this.pvtConnected = false;\n this.pvtStateSubs.forEach((fn) => fn());\n this.pvtSettleReady();\n // Whoever is waiting for it to end is waiting for news that can no longer come.\n this.pvtExitWaiter?.reject(new Error(`${this.pname} cannot be reached: the connection is closed`));\n }\n\n /** Whether the process it names has ended, as far as this side has been told. */\n hasEnded(): boolean {\n return this.pvtExit !== null;\n }\n\n /** Why nothing can be asked *of the process* — let go, ended, or out of reach — or\n * nothing when something can. Those are not one thing said three ways: an ended\n * process is still reached, it simply has nothing left to receive. */\n private pvtWhyNotAskable(): string | null {\n if (this.pvtReleased) return `${this.pname} was released`;\n if (this.pvtExit !== null) return `${this.pname} has ended`;\n if (!this.pvtConnected) return `${this.pname} cannot be reached: the connection is closed`;\n return null;\n }\n\n private pvtRequireAskable(): void {\n const why = this.pvtWhyNotAskable();\n if (why !== null) throw new Error(why);\n }\n\n /**\n * Keep this reference: from here it is counted, which is what lets anything be asked of\n * it. It returns the handle, so what is kept is written in one line —\n * `this.pvtRemoteRefsHeld.push(ref.holdRef())` — and a table of them reads as what it is.\n */\n holdRef(): this {\n this.pvtRefCount += 1;\n return this;\n }\n\n /**\n * Give the count back. Whoever gives the last one back lets the reference go, which is\n * what tells the far side that nothing here wants to hear about the process again. A\n * reference nobody ever kept is let go of by this too, which is how whoever receives one\n * they do not want is rid of it.\n */\n releaseRef(): void {\n if (this.pvtRefCount > 0) this.pvtRefCount -= 1;\n if (this.pvtRefCount > 0) return;\n // The last count going means this reference is nobody's here. One that can still be\n // asked is let go of, which is what tells the far side to stop saying anything about it.\n // One that has ended, or whose connection went, has nothing left to be told: what there\n // is to drop is the binding here, and there is nobody to ask about it.\n if (this.pvtWhyNotAskable() === null) {\n this.release();\n return;\n }\n this.pvtDropBinding();\n }\n\n /** Let go of the binding here without asking the far side for anything: what the process\n * was is over, or the wire that carried it is. */\n private pvtDropBinding(): void {\n if (this.pvtReleased) return;\n this.pvtReleased = true;\n this.pvtLetGo?.(this.ref.id);\n this.pvtSettleReady();\n }\n\n /** How many times this reference has been kept. */\n refCount(): number {\n return this.pvtRefCount;\n }\n\n /**\n * What this is, as text: a handle nothing here keeps is an unstable reference and says\n * so, and one that is kept says which process it names and by which id.\n */\n [Symbol.for(\"nodejs.util.inspect.custom\")](): string {\n return this.pvtRefCount === 0 ? UNSTABLE_REFERENCE : `RemoteProcess(${this.ref.id}: ${this.pname})`;\n }\n\n /**\n * What this is, in JSON: the same reference the wire would carry, or the unstable thing\n * it is when nothing keeps it. Written so that an unheld reference cannot be mistaken\n * for a process that merely looks odd in a state, and so that one that is kept reads as\n * the reference it is rather than as whatever fields it happens to have.\n */\n toJSON(): unknown {\n if (this.pvtRefCount === 0) return UNSTABLE_REFERENCE;\n return { [PROCESS_REF]: { id: this.ref.id, pname: this.pname } };\n }\n\n /**\n * Remember the references inside a value that arrived here to be passed on. They are not\n * counted — the receiver is the one to deal with them — and this is what keeps one from\n * being nobody's for ever: when this handle is let go of, they are dropped with it.\n */\n markTransient(value: unknown): void {\n for (const ref of refsInside(value)) {\n if (ref.id === this.id || ref.pvtReleased) continue;\n this.pvtDropTransient(ref);\n if (this.pvtOwnedRefs.includes(ref) || this.pvtTransientRefs.includes(ref)) continue;\n this.pvtTransientRefs.push(ref);\n }\n }\n\n /** Stop treating a reference as one that was only passing through. */\n private pvtDropTransient(ref: RemoteProcess): void {\n const at = this.pvtTransientRefs.indexOf(ref);\n if (at >= 0) this.pvtTransientRefs.splice(at, 1);\n }\n\n /**\n * Keep the references sitting in what this process holds. What it holds is here, so the\n * thing keeping those references alive is this handle, and it holds them until it is let\n * go of itself.\n */\n private pvtHoldOwned(value: unknown): void {\n for (const ref of refsInside(value)) {\n if (ref.id === this.id || ref.pvtReleased) continue;\n if (this.pvtOwnedRefs.includes(ref)) continue;\n this.pvtDropTransient(ref);\n this.pvtOwnedRefs.push(ref.holdRef());\n }\n }\n\n /** Nothing is heard about a process nothing here keeps. A subscription, a tuning and a\n * wait for the state are all ways of hearing, so they are where a reference has to have\n * been kept first — and where the mistake says what to do about it. */\n private pvtRequireHeld(what: string): void {\n if (this.pvtRefCount > 0) return;\n throw new Error(\n `${this.pname} is not held by anyone here: call holdRef() to keep this reference, ` +\n `or releaseRef() to let it go, before ${what}`,\n );\n }\n\n /**\n * Wait until what it holds is here.\n *\n * A handle starts out knowing nothing about the process: the far side says what a\n * process holds when something over here asks to hear it, so the asking and the waiting\n * are one act, and this is both. It settles with whatever has arrived when nothing more\n * can: a process that has ended has said its last, and a connection that has gone has\n * nothing left to say. Asking twice is asking about what is already here.\n */\n ready(): Promise<void> {\n if (this.state !== null || this.pvtWhyNotAskable() !== null) return Promise.resolve();\n this.pvtRequireHeld(\"waiting for what it holds\");\n this.pvtWant(\"state\");\n return new Promise<void>((resolve) => this.pvtReadyWaiters.push(resolve));\n }\n\n /** Everyone waiting for what it holds has heard it, or never will. */\n private pvtSettleReady(): void {\n const waiting = this.pvtReadyWaiters;\n this.pvtReadyWaiters = [];\n for (const resolve of waiting) resolve();\n }\n\n /**\n * Wait for the process to end. Its exit crosses back like everything else it\n * does, and what it left behind is the answer.\n *\n * A handle whose connection is gone rejects instead: what is left to wait for\n * after that is nothing, and a process that keeps running is not something this\n * side can tell from one that died with the wire.\n */\n wait(): Promise<RemoteExit> {\n if (this.pvtExit !== null) return Promise.resolve(this.pvtExit);\n const why = this.pvtWhyNotAskable();\n if (why !== null) return Promise.reject(new Error(why));\n // Waiting for it to end is a subscription to its end: nothing here hears an\n // exit that was never asked for, so asking to wait asks for it.\n this.pvtWant(\"exit\");\n this.pvtExitWaiter ??= makeWaiter<RemoteExit>();\n return this.pvtExitWaiter.promise;\n }\n\n /**\n * Ask the far side to stop it. Stops the way it always does there, and this\n * resolves when its exit has crossed back — which is all this side can know.\n * There is no deadline, so a process that refuses to stop leaves this pending.\n */\n stop(): Promise<void> {\n this.pvtRequireAskable();\n // Ask for the end before asking it to stop: whether an exit is sent is decided\n // by what the far side has been asked for when it comes, so a stop ordered ahead\n // of the asking could leave nothing to wait for.\n this.pvtWant(\"exit\");\n this.pvtSend({ $stop: {} }, this.ref.id);\n return this.wait().then(() => undefined);\n }\n\n /**\n * Let it go: the far side forgets this id and stops telling this side anything\n * about the process behind it. The process itself is untouched — it runs on, it\n * is simply nobody's here any more — and this handle is done: nothing reaches it,\n * nothing is waited for, and what arrives for it later is not news.\n */\n release(): void {\n this.pvtRequireAskable();\n this.pvtReleased = true;\n const owned = this.pvtOwnedRefs;\n this.pvtOwnedRefs = [];\n for (const ref of owned) {\n if (!ref.pvtReleased) ref.releaseRef();\n }\n const transient = this.pvtTransientRefs;\n this.pvtTransientRefs = [];\n for (const ref of transient) {\n // One that was kept by whoever received it is theirs, and one that was never kept is\n // nobody's: there is nothing else that would ever let go of it.\n if (!ref.pvtReleased && ref.pvtRefCount === 0) ref.release();\n }\n this.pvtLetGo?.(this.ref.id);\n this.pvtSend({ $release: {} }, this.ref.id);\n this.pvtSettleReady();\n }\n\n /** Stop feeding it messages. It is still there: `send` still reaches it. */\n pause(): void {\n this.pvtRequireAskable();\n this.pvtSend({ $pause: {} }, this.ref.id);\n }\n\n /** Feed it messages again. */\n resume(): void {\n this.pvtRequireAskable();\n this.pvtSend({ $resume: {} }, this.ref.id);\n }\n\n /**\n * What to be told about it from now on: any of `message`, `state` and `exit`,\n * or `\"silent\"` for none of it.\n *\n * A process that crossed is silent to begin with, so this is how a handle asks\n * to hear anything at all — and what is heard is only ever what was asked for.\n * An exit nobody asked for is not sent: silence is silence, which makes this the\n * one way to leave a handle that will not answer a `wait()`, and the far side's\n * books the one place an end can go unrecorded.\n */\n tune(kinds: StreamKind[] | \"silent\"): void {\n this.pvtRequireAskable();\n this.pvtRequireHeld(\"tuning what is heard about it\");\n this.pvtTune(kinds === \"silent\" ? [] : kinds);\n }\n\n /** Ask the far side to say exactly this much, and nothing when it is already\n * saying it. The list goes in the order the three are named in, so asking for\n * the same thing twice sends the same frame twice. */\n private pvtTune(wanted: StreamKind[]): void {\n const kinds = STREAM_KINDS.filter((kind) => wanted.includes(kind));\n if (kinds.length === this.pvtWanted.size && kinds.every((kind) => this.pvtWanted.has(kind))) {\n return;\n }\n this.pvtWanted = new Set(kinds);\n this.pvtSend({ $tune: { streams: kinds } }, this.ref.id);\n }\n\n /** Ask for one more category, because something here now wants it. A handle\n * that is gone asks nothing: there is no far side left to hear it, and nothing\n * was asked for, so what was wanted stays what it was. */\n private pvtWant(kind: StreamKind): void {\n if (this.pvtWanted.has(kind)) return;\n if (!this.pvtConnected || this.pvtReleased) return;\n this.pvtTune([...this.pvtWanted, kind]);\n }\n\n /** Hand the far process a message. */\n send(msg: InMsg): void {\n this.pvtRequireAskable();\n this.pvtSend({ $msg: { fromName: this.pvtFromName, body: msg } }, this.ref.id);\n }\n\n /** Subscribe to what it says, or to what it holds. Asking here is asking the far\n * side: a subscription is the first thing that wants the category, so it is what\n * turns it on, and unsubscribing leaves it on — the far side is not told to stop\n * saying something that another subscriber may still want. */\n subscribe(channel: \"message\", cb: RemoteMessage<OutMsg>): () => void;\n subscribe(channel: \"state\", cb: () => void): () => void;\n subscribe(channel: \"message\" | \"state\", cb: RemoteMessage<OutMsg> | (() => void)): () => void {\n this.pvtRequireHeld(`subscribing to what it ${channel === \"message\" ? \"says\" : \"holds\"}`);\n if (channel === \"message\") {\n const fn = cb as RemoteMessage<OutMsg>;\n this.pvtMessageSubs.push(fn);\n this.pvtWant(\"message\");\n return () => this.pvtUnsubscribe(this.pvtMessageSubs, fn);\n }\n const fn = cb as () => void;\n this.pvtStateSubs.push(fn);\n this.pvtWant(\"state\");\n return () => this.pvtUnsubscribe(this.pvtStateSubs, fn);\n }\n\n private pvtUnsubscribe<T>(list: Array<T>, fn: T): void {\n const idx = list.indexOf(fn);\n if (idx >= 0) list.splice(idx, 1);\n }\n\n // ── what the connection delivers ─────────────────────────────────────────\n // The handle does not read frames; the side that owns the connection hands it\n // what a frame about this process said.\n\n /** Its state, as the far side just published it. */\n receiveState(state: Record<string, unknown>): void {\n if (this.pvtReleased) return;\n this.state = Object.assign(this.state ?? {}, state);\n this.pvtHoldOwned(state);\n this.pvtStateSubs.forEach((fn) => fn());\n this.pvtSettleReady();\n }\n\n /** A message it emitted. */\n receiveMessage(msg: OutMsg, fromName: string): void {\n if (this.pvtReleased) return;\n // Anything that came along in the message came here on its way somewhere else.\n this.markTransient(msg);\n this.pvtMessageSubs.forEach((fn) => fn(msg, fromName));\n }\n\n /** It has ended, and this is what it left behind. The last thing said about a\n * process: nothing crosses about it after its exit, though the handle still\n * reaches it for what it left. */\n receiveExit(exit: RemoteExit): void {\n if (this.pvtExit !== null || this.pvtReleased) return;\n this.pvtExit = exit;\n this.pvtExitWaiter?.resolve(exit);\n // Nobody is waiting for state from a process that has ended: what it left is all\n // there is, and nothing more is coming.\n this.pvtSettleReady();\n }\n\n /** The methods it can answer, as functions that ask it for an answer. `call`\n * is the connection's own: a handle knows what to ask for, not how a call is\n * made or paired with its answer. */\n receiveMethods(names: string[], call: (name: string, args: unknown[]) => Promise<unknown>): void {\n for (const name of names) {\n this.$reflection[name] = async (...args: unknown[]) => {\n const value = await call(name, args);\n // A reference in an answer was handed to whoever asked, which makes it theirs to\n // deal with; this handle only remembers it, so that it is dropped with this one.\n this.markTransient(value);\n return value;\n };\n }\n }\n}\n","// ── What a process says once it has crossed ─────────────────────────────────\n//\n// A process that crosses the connection is numbered, and from that moment the\n// other side can be told about it: what it can answer, what it holds, and what it\n// emits. Both ends say exactly this about the processes they hold — the side that\n// hands one over, and the side that serves one — so it is written once here\n// rather than once per side.\n\nimport { isProcess, type AnyProcess } from \"../process.async.js\";\nimport { REFLECT_METHODS, STREAM_KINDS, type StreamKind } from \"./channel.js\";\n\nimport type { FrameSink } from \"./remote-process.js\";\n\n/** What a process can be asked over the wire: the functions on its reflection\n * surface, read once. On the side that serves it the list *is* the dispatch\n * table, so a name that was never on it can never be reached. */\nconst pvtReflectionNames = new WeakMap<object, string[]>();\n\nexport function reflectionNames(target: { $reflection?: unknown }): string[] {\n const known = pvtReflectionNames.get(target);\n if (known) return known;\n const surface = (target.$reflection ?? {}) as Record<string, unknown>;\n const names = Object.keys(surface).filter((name) => typeof surface[name] === \"function\");\n pvtReflectionNames.set(target, names);\n return names;\n}\n\n/**\n * The processes of one side that have crossed, and what the far side is told\n * about them.\n *\n * A stream starts once the frame that carried the reference is out: frames about\n * a process the reader cannot name yet have nowhere to land. The table numbers a\n * process while that frame is being written, so the numbering is queued here and\n * let out by `flush` right after the frame goes — which is the only thing a\n * caller has to remember.\n *\n * What a stream says is what the far side asked for. A process that crosses is silent\n * until something over there asks to hear it, and `tune` is that asking: only the\n * categories it names cross. The root of the connection is no exception. It is\n * registered here the moment the connection opens, and a side that wants to hear it\n * asks, which is what a visitor's proxy does for the state and messages it stands in\n * for.\n */\n\n/** One process that crossed, and what is said about it now. */\ninterface StreamRecord {\n target: AnyProcess;\n /** The categories that cross, out of the three. */\n kinds: Set<StreamKind>;\n /** How to stop hearing one that is armed. `exit` is not among them: a stream\n * has to hear the end to know it is over, and what it does with the news is\n * the question `kinds` answers. */\n stops: Map<StreamKind, () => void>;\n}\n\nexport class ProcessStreams {\n private pvtSink: FrameSink;\n /** The id of the connection's own end. Its end is the connection's end, so the side\n * that owns the wire says it, awaited there, instead of this watching for it as it\n * watches any other process's. */\n private pvtRootId: number;\n private pvtPending: Array<[AnyProcess, number]> = [];\n private pvtRecords = new Map<number, StreamRecord>();\n private pvtFlushing = false;\n\n constructor(sink: FrameSink, rootId: number) {\n this.pvtSink = sink;\n this.pvtRootId = rootId;\n }\n\n /** A process was numbered: it is about to cross. Anything that is not a\n * process — a handle travelling back to the side that holds it — crosses as\n * the reference it came with and is nobody's to stream. */\n crossed(proc: unknown, id: number): void {\n if (!isProcess(proc)) return;\n this.pvtPending.push([proc, id]);\n }\n\n /** Say what there is to say about whatever crossed while a frame was written. */\n flush(): void {\n if (this.pvtFlushing) return;\n this.pvtFlushing = true;\n try {\n while (this.pvtPending.length > 0) {\n const next = this.pvtPending.shift();\n if (next) this.pvtStream(next[0], next[1]);\n }\n } finally {\n this.pvtFlushing = false;\n }\n }\n\n /**\n * What to say about it from now on: the categories named, and none of the\n * others. Asking for its state says it there and then — a handle that has just\n * asked what it holds should not have to wait for it to change.\n *\n * An id with no stream here is not this side's to tune, and the frame is\n * dropped: both sides tune only what they hold, so an id names a stream on the\n * side that numbered it.\n */\n tune(id: number, kinds: StreamKind[]): void {\n const record = this.pvtRecords.get(id);\n if (!record) return;\n const wanted = new Set(kinds);\n for (const kind of STREAM_KINDS) {\n const isOn = record.kinds.has(kind);\n const want = wanted.has(kind);\n if (want === isOn) continue;\n if (want) {\n record.kinds.add(kind);\n this.pvtArm(record, id, kind);\n } else {\n record.kinds.delete(kind);\n this.pvtDisarm(record, kind);\n }\n }\n }\n\n /**\n * Say nothing more about this one. It is not that the process ended — the far\n * side asked to be left out of it, so its exit is nobody's news over here, and\n * dropping the subscription is what keeps it from being sent.\n */\n stop(id: number): void {\n const record = this.pvtRecords.get(id);\n if (!record) return;\n for (const stop of record.stops.values()) stop();\n this.pvtRecords.delete(id);\n }\n\n /** Nothing more is said about any of them: the connection is done. */\n stopAll(): void {\n for (const id of [...this.pvtRecords.keys()]) this.stop(id);\n this.pvtPending.length = 0;\n }\n\n private pvtStream(target: AnyProcess, id: number): void {\n // Nothing to begin with: what is said about a process is what the far side asks\n // for, and the root is asked for like anything else.\n const record: StreamRecord = {\n target,\n kinds: new Set(),\n stops: new Map(),\n };\n this.pvtRecords.set(id, record);\n // What it can answer comes first: a handle that hears from a process it cannot\n // name yet has nowhere to put the news. It is not one of the three categories\n // — a handle with no methods can do nothing with the process however much it\n // is told about it — so it crosses even in silence.\n this.pvtSink({ [REFLECT_METHODS]: reflectionNames(target) }, id);\n for (const kind of record.kinds) this.pvtArm(record, id, kind);\n // Its end is the last thing ever said about it, and the one thing a stream has\n // to hear to know it is over, whether or not the far side is told. A process\n // that fails to run takes the same road as one that finishes.\n //\n // Not for the root. Its end is the connection's end, and the side that owns the\n // wire says it while taking the wire down, awaiting it there because that frame has\n // to be out before the close. Both of them end up in `sayEnded`.\n if (id !== this.pvtRootId) {\n void target.wait().then(\n () => void this.sayEnded(id, 0),\n () => void this.sayEnded(id, 1),\n );\n }\n }\n\n /** Start saying this much about it, and say what there is to say now. */\n private pvtArm(record: StreamRecord, id: number, kind: StreamKind): void {\n if (kind === \"message\") {\n record.stops.set(\n \"message\",\n record.target.subscribe(\"message\", (msg, sender) => {\n this.pvtSink({ $msg: { fromName: sender.fromName, body: msg } }, id);\n }),\n );\n return;\n }\n if (kind === \"state\") {\n record.stops.set(\n \"state\",\n record.target.subscribe(\"state\", () => {\n this.pvtSink({ $state: record.target.state as Record<string, unknown> }, id);\n }),\n );\n // Asked for, so said now: in silence the far side has heard nothing about\n // its state, and this is the first word rather than a repeat.\n this.pvtSink({ $state: record.target.state as Record<string, unknown> }, id);\n }\n // `exit` needs no subscription: the end is watched from the moment the process\n // crosses, since a stream has to know when it is over. Whether it is sent is\n // read from `kinds` when it comes.\n }\n\n private pvtDisarm(record: StreamRecord, kind: StreamKind): void {\n const stop = record.stops.get(kind);\n if (!stop) return;\n stop();\n record.stops.delete(kind);\n }\n\n /**\n * It has ended: say so once, if that is among the categories asked for, and say\n * nothing more about it either way. Awaited by whoever has to have the frame out\n * before the wire closes, which is the root's end and nobody else's — no other\n * process can end after this side has stopped saying anything about it.\n */\n async sayEnded(id: number, code: number): Promise<void> {\n const record = this.pvtRecords.get(id);\n if (!record) return;\n const told = record.kinds.has(\"exit\");\n const state = record.target.state;\n this.stop(id);\n if (told) await this.pvtSink({ $exit: { code, state } }, id);\n }\n}\n","// ── Who a message that crossed the wire came from ──────────────────────────\n//\n// A frame carries its sender as a name, because a symbol cannot be written down.\n// On the other side the name is turned back into an identity a process can be\n// handed: whoever the frame names, and — when that name is the one a process was\n// told is its parent — the parent's own stable id, so a child on either side of\n// the seam recognises the same sender.\n\nimport type { SenderInfo } from \"../types.js\";\n\nexport function makeSender(\n fromName: string,\n parentName: string | null,\n parentId: symbol | null,\n): SenderInfo {\n if (parentId && fromName === parentName) {\n return { fromName, fromId: parentId };\n }\n return { fromName, fromId: Symbol() };\n}\n","// ── The call side of a connection ───────────────────────────────────────────\n//\n// Both ends of a seam make calls and answer them, and the machinery is the same\n// once the wire is: a `seq` the connection counts, the calls waiting under it, the\n// surface a handle reads to make one, and the answer that names which call it\n// settles. Only where a frame leaves differs between the two ends, which is why\n// that is the one thing handed in and the rest is written once.\n\nimport { isProcess } from \"../process.async.js\";\nimport {\n REFLECT_CALL,\n REFLECT_RESULT,\n asReflectionResult,\n encodeFrame,\n jsonProblem,\n type ReflectionCall,\n type ValueCodec,\n} from \"./channel.js\";\nimport {\n encodeProcessRefs,\n isRemoteProcess,\n type ProcessHandle,\n type ProcessTable,\n} from \"./process-ref.js\";\nimport { reflectionNames } from \"./process-streams.js\";\n\n/** A frame on its way out: encoded, addressed, and written to this end's wire. */\nexport type WireSink = (frame: Record<string, unknown>) => Promise<void>;\n\nexport class CallSide {\n /**\n * `seq` belongs to this connection and is never reused, so two calls to the same\n * method in flight at once stay apart; the answer names the one it belongs to,\n * whichever process it was asked of.\n */\n private pvtCalls = 0;\n private pvtWaiting = new Map<\n number,\n { name: string; resolve: (value: unknown) => void; reject: (error: Error) => void }\n >();\n private pvtWrite: WireSink;\n private pvtTable: ProcessTable<ProcessHandle>;\n private pvtCodec: ValueCodec | undefined;\n\n constructor(write: WireSink, table: ProcessTable<ProcessHandle>, codec?: ValueCodec) {\n this.pvtWrite = write;\n this.pvtTable = table;\n this.pvtCodec = codec;\n }\n\n /**\n * Ask a process on the far side for one of its methods. Processes among the\n * arguments become references first — this side's own, with ids from its table, or\n * the far side's coming back — and what is left has to be JSON, or nothing is sent\n * at all.\n */\n call(method: string, callArgs: unknown[], to: number): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const seq = ++this.pvtCalls;\n const frame = encodeFrame(\n { [`${REFLECT_CALL}${method}`]: { seq, args: callArgs } },\n this.pvtTable,\n to,\n this.pvtCodec,\n );\n const problem = jsonProblem(frame);\n if (problem !== null) {\n reject(new Error(`cannot send ${problem} to ${method}`));\n return;\n }\n this.pvtWaiting.set(seq, { name: method, resolve, reject });\n void this.pvtWrite(frame).catch((error: unknown) => {\n this.pvtWaiting.delete(seq);\n reject(error instanceof Error ? error : new Error(String(error)));\n });\n });\n }\n\n /**\n * One function per announced name, on the surface whoever calls reads.\n *\n * An answer that carries a reference hands it to whoever asked, which makes it theirs to\n * deal with: the handle that was asked is told about it, so that one nobody keeps is let\n * go of with that handle rather than being nobody's for ever.\n */\n install(surface: Record<string, unknown>, methods: string[], to: number): void {\n for (const method of methods) {\n surface[method] = async (...callArgs: unknown[]) => {\n const value = await this.call(method, callArgs, to);\n const owner = this.pvtTable.farHandleFor(to);\n if (isRemoteProcess(owner)) owner.markTransient(value);\n return value;\n };\n }\n }\n\n /**\n * An answer to a call this side made: the call waiting under that `seq` is settled\n * by it, and the frame says whether it was one at all. An answer is about the call\n * and not about a process, so a dispatcher reads it before it looks anything up.\n */\n settle(frame: Record<string, unknown>): boolean {\n const result = asReflectionResult(frame);\n if (!result) return false;\n const waiting = this.pvtWaiting.get(result.seq);\n if (waiting) {\n this.pvtWaiting.delete(result.seq);\n if (result.error === undefined) waiting.resolve(result.value);\n else waiting.reject(new Error(`${waiting.name}: ${result.error}`));\n }\n return true;\n }\n\n /** A call that was in flight when the wire went has no answer coming; it fails\n * here rather than hanging for ever. */\n rejectAll(): void {\n for (const waiting of this.pvtWaiting.values()) {\n waiting.reject(new Error(`connection closed before ${waiting.name} answered`));\n }\n this.pvtWaiting.clear();\n }\n}\n\n/**\n * Answer one call with what the process said, or why it could not. A method may be\n * written for a call that answers later; the wire has no opinion about that, it just\n * waits for the frame.\n */\nexport async function answerCall(\n call: ReflectionCall,\n target: ProcessHandle | undefined,\n write: WireSink,\n table: ProcessTable<ProcessHandle>,\n codec?: ValueCodec,\n): Promise<void> {\n // An answer goes back to the far side's own end of the connection: a result is about\n // the call and not about a process, and the one waiting for it is out there.\n const reply = (body: Record<string, unknown>) =>\n write(encodeFrame({ [`${REFLECT_RESULT}${call.name}`]: body }, table, table.farRootId(), codec));\n // Only a process this side holds can be asked: the id a call names is the holder's\n // own, and this side is the holder of what it holds.\n if (!isProcess(target)) {\n await reply({ seq: call.seq, error: \"no process with that id on this connection\" });\n return;\n }\n const names = reflectionNames(target);\n const surface = target.$reflection as unknown as Record<string, Function>;\n const method = names.includes(call.name) ? surface[call.name] : undefined;\n if (typeof method !== \"function\") {\n await reply({ seq: call.seq, error: `no reflection method named ${call.name}` });\n return;\n }\n try {\n // References in the arguments arrived as handles on processes of this side's own, and\n // processes in the answer become references. Bytes become references too, and that\n // walk runs before the check below: what has to be JSON is the frame, and a megabyte of\n // bytes is JSON only once it is a reference to them (stringifying the array itself is\n // a million keys — measured at 4.6 s for one megabyte, which is how this was found).\n const answer = encodeProcessRefs(await method(...call.args), table);\n const value = codec === undefined ? answer : codec.encode(answer);\n const problem = jsonProblem(value);\n if (problem !== null) {\n await reply({\n seq: call.seq,\n error: `${call.name} returned ${problem}, which cannot cross a frame`,\n });\n return;\n }\n await reply({ seq: call.seq, value });\n } catch (err) {\n await reply({ seq: call.seq, error: err instanceof Error ? err.message : String(err) });\n }\n}\n","// ── streams on the wire ────────────────────────────────────────────────────\n//\n// A stream is bytes arriving over time. A blob has to be whole before anybody can look at it,\n// so the reader waits for all of it, the writer has nothing to slow it down, and a file bigger\n// than memory cannot cross at all. A stream is what a file already is on a connection: asked\n// for at the rate the reader can take it.\n//\n// What the octets mean is not the announcement's business. The value that references them says\n// what they are and carries the facts about them: a stream has none, a typed array has its\n// length, a blob has its size, type and name.\n//\n// {\"$stream\": {\"id\": 7}} announced first: octets are coming\n// {\"$msg\": {\"fromName\": \"a\", \"body\": {\"feed\": {\"$s\": {\"id\": 7}}}}} a stream\n// {\"$msg\": {\"fromName\": \"a\", \"body\": {\"data\": {\"$bytes\": {\"id\": 7, \"size\": 4}}}}} a typed array\n// {\"$msg\": {\"fromName\": \"a\", \"body\": {\"shot\": {\"$blob\": {\"id\": 7, \"size\": 4, \"type\": \"image/png\", \"name\": \"a.png\"}}}}}\n// {\"$streamAsk\": {\"id\": 7, \"credit\": 262144}} the reader's demand, in bytes\n// {\"$chunk\": {\"id\": 7, \"seq\": 1, \"bytes\": 65536}} a chunk: its head…\n// <65536 raw octets> …its bytes…\n// {\"$chunkEnd\": {\"id\": 7, \"seq\": 1, \"crc32\": 2663770700}} …and the checksum, after them\n// {\"$streamDone\": {\"id\": 7}} or {\"$streamFail\": {…, \"reason\": …}}\n// {\"$streamCancel\": {\"id\": 7}} a reader that stops early\n//\n// The announcement goes out before the frame that references it, so a reader never receives a\n// reference to something it has not been told about. The head's `bytes` is what keeps the\n// framing: a reader that does not know the stream still skips exactly that many octets, and a\n// head whose length is a lie is the one thing that costs the connection rather than the stream.\n//\n// Credit is the flow control, counted in bytes: the reader grants a window and the writer sends\n// whole chunks until it is spent. Nothing is written ahead of demand, so a slow consumer slows\n// the writer instead of filling a buffer somewhere. The one eager case is a typed array: the\n// reference arriving is the demand, so the reader asks at once and puts the array back together\n// as the chunks land.\n\nimport { isPlainObject, isStreamLike, type Channel, type ValueCodec } from \"./channel.js\";\n\nexport { isStreamLike };\nimport { IdSpace, type IdParity } from \"./process-ref.js\";\n\n/** The chunk size, which bounds one segment. */\nexport const DEFAULT_CHUNK_BYTES = 64 * 1024;\n\n/** How far ahead of the consumer a writer may run: the credit window, in bytes. */\nexport const DEFAULT_WINDOW_BYTES = 4 * DEFAULT_CHUNK_BYTES;\n\n/** The largest stream this side will take: a reader that will not read a 5 GB file should say so\n * before the first chunk, not after the last. */\nexport const DEFAULT_MAX_BYTES = 64 * 1024 * 1024;\n\n/** What a blob knows about itself: the facts ride the reference, not the stream behind it. */\nexport interface BlobFacts {\n /** Bytes in total. A blob is whole by definition, so this is always known. */\n readonly size: number;\n /** The media type, when the sender knows it. */\n readonly type?: string;\n /** A name for a file, when one had it. */\n readonly name?: string;\n}\n\n/** What the far side made of an announcement: the stream itself, a blob over it, or an array. */\ntype ValueForm = \"stream\" | \"blob\" | \"bytes\";\n\n/** A stream of octets: what the library takes at one end of a connection and gives at the other.\n * It says nothing about what the octets are — that belongs to the value that references it. */\nexport type Stream = AsyncIterable<Uint8Array>;\n\n/** What a message carries in place of a stream: an id, or the name the far side announced it under. */\nexport interface StreamRef {\n $s: { id: number } | { name: string };\n}\n\nexport function isStreamRef(value: unknown): value is StreamRef {\n const body = (value as { $s?: { id?: unknown; name?: unknown } } | null)?.$s;\n return typeof body?.id === \"number\" || typeof body?.name === \"string\";\n}\n\n/** What a message carries in place of a typed array: its octets, and the length they add up to. */\nexport interface BytesRef {\n $bytes: { id: number; size: number };\n}\n\nexport function isBytesRef(value: unknown): value is BytesRef {\n const body = (value as { $bytes?: { id?: unknown; size?: unknown } } | null)?.$bytes;\n return typeof body?.id === \"number\" && typeof body?.size === \"number\";\n}\n\n/** What a message carries in place of a blob: its octets and the facts about them. */\nexport interface BlobRef {\n $blob: { id: number } & BlobFacts;\n}\n\nexport function isBlobRef(value: unknown): value is BlobRef {\n const body = (value as { $blob?: { id?: unknown; size?: unknown } } | null)?.$blob;\n return typeof body?.id === \"number\" && typeof body?.size === \"number\";\n}\n\n/** What may be offered in place of a whole file: sized, and read on demand. A platform `Blob` or\n * `File` is one as it stands, and so is a `RemoteBlob` that arrived from a connection — which is how\n * a file that was received can be passed on without being read here. */\nexport interface BlobSource {\n readonly size: number;\n readonly type?: string;\n readonly name?: string;\n /** A window of the bytes, when the value can give one without reading the rest. */\n readonly slice?: (start?: number, end?: number) => BlobSource;\n readonly arrayBuffer: () => Promise<ArrayBuffer>;\n /** The bytes over time, for a value that cannot be sliced. */\n readonly stream?: () => AsyncIterable<Uint8Array>;\n}\n\nexport function isBlob(value: unknown): value is BlobSource {\n if (typeof value !== \"object\" || value === null) return false;\n const candidate = value as { size?: unknown; arrayBuffer?: unknown; slice?: unknown; stream?: unknown };\n if (typeof candidate.size !== \"number\") return false;\n if (typeof candidate.arrayBuffer !== \"function\") return false;\n return typeof candidate.slice === \"function\" || typeof candidate.stream === \"function\";\n}\n\n/** What a message carries in place of a blob: the same value, read off the connection. */\nexport interface Blob {\n readonly size?: number;\n readonly type?: string;\n readonly name?: string;\n /** Read it once: the bytes are on the wire, not here. */\n stream(): Stream;\n arrayBuffer(): Promise<ArrayBuffer>;\n}\n\n/** Every octet of a stream, in one array. */\nexport async function bytesOf(stream: AsyncIterable<Uint8Array>): Promise<Uint8Array> {\n const parts: Uint8Array[] = [];\n let total = 0;\n for await (const part of stream) {\n parts.push(part);\n total += part.length;\n }\n const all = new Uint8Array(total);\n let at = 0;\n for (const part of parts) {\n all.set(part, at);\n at += part.length;\n }\n return all;\n}\n\n\n// ── the checksum ───────────────────────────────────────────────────────────\n//\n// CRC-32, because it is the one the runtime already has: `Bun.hash.crc32` costs 0.1 ms for a\n// 64 KiB chunk here and a table written in TypeScript costs 65 ms on a box without a JIT. The\n// numbers are in docs/proposals/streams.md; the polynomial is the same everywhere, so either\n// side verifies the other's.\n\ntype Crc = (bytes: Uint8Array) => number;\n\nlet pvtCrc: Crc | null = null;\n\nfunction crcOf(): Crc {\n if (pvtCrc !== null) return pvtCrc;\n const bun = (globalThis as { Bun?: { hash?: { crc32?: (data: Uint8Array) => number } } }).Bun;\n if (typeof bun?.hash?.crc32 === \"function\") {\n const native = bun.hash.crc32;\n pvtCrc = (bytes) => native(bytes) >>> 0;\n return pvtCrc;\n }\n // Node 22 has it on `zlib`, reachable without importing anything the browser cannot parse.\n const builtin = (globalThis as { process?: { getBuiltinModule?: (name: string) => unknown } }).process\n ?.getBuiltinModule?.(\"node:zlib\") as { crc32?: (data: Uint8Array) => number } | undefined;\n if (typeof builtin?.crc32 === \"function\") {\n const native = builtin.crc32;\n pvtCrc = (bytes) => native(bytes) >>> 0;\n return pvtCrc;\n }\n pvtCrc = tableCrc;\n return pvtCrc;\n}\n\n/** CRC-32 by hand, for a runtime that has none. Correct, and slow where nothing is a JIT. */\nfunction tableCrc(bytes: Uint8Array): number {\n let crc = 0xffff_ffff;\n for (const byte of bytes) {\n crc = (crc >>> 8) ^ pvtTable[(crc ^ byte) & 0xff]!;\n }\n return (crc ^ 0xffff_ffff) >>> 0;\n}\n\nconst pvtTable: number[] = (() => {\n const table: number[] = [];\n for (let i = 0; i < 256; i += 1) {\n let value = i;\n for (let bit = 0; bit < 8; bit += 1) value = value & 1 ? 0xed_b8_83_20 ^ (value >>> 1) : value >>> 1;\n table.push(value >>> 0);\n }\n return table;\n})();\n\n/** The checksum a chunk's tail carries. */\nexport function crc32(bytes: Uint8Array): number {\n return crcOf()(bytes);\n}\n\n// ── the reader's side ──────────────────────────────────────────────────────\n\n/** What a stream on this side costs and asks for, without knowing the connection. */\ninterface ReaderHooks {\n /** Octets taken by the consumer: credit spent, and the writer may be asked for more. */\n consumed(bytes: number): void;\n /** The consumer will take no more. */\n cancelled(reason: string): void;\n /** The consumer is waiting for octets: what the far side may now be asked for. */\n wanted(): void;\n}\n\n/**\n * Bytes the far side offers, read at the consumer's pace.\n *\n * An async iterable of octets, and nothing more: turning it into an array, a `Blob` or a digest\n * is the platform's job — `new Response(stream).arrayBuffer()` where there is a `Response`,\n * `for await` where there is not.\n */\nexport class RemoteStream implements Stream {\n private readonly queue: Uint8Array[] = [];\n private readonly waiting: Array<{ resolve: (r: IteratorResult<Uint8Array>) => void; reject: (e: Error) => void }> =\n [];\n private ended = false;\n private failure: Error | null = null;\n private stopped = false;\n private platform: ReadableStream<Uint8Array> | null = null;\n\n constructor(private readonly hooks: ReaderHooks) {}\n\n /** The far side sent more of it. */\n push(bytes: Uint8Array): void {\n if (this.ended || this.failure || this.stopped) return;\n const waiting = this.waiting.shift();\n if (!waiting) {\n this.queue.push(bytes);\n return;\n }\n this.hooks.consumed(bytes.length);\n waiting.resolve({ value: bytes, done: false });\n }\n\n /** The far side has sent all of it. */\n end(): void {\n if (this.ended || this.failure) return;\n this.ended = true;\n for (const waiting of this.waiting.splice(0)) waiting.resolve({ value: undefined, done: true });\n }\n\n /** The far side gave up on it, or it arrived corrupt. */\n fail(reason: string): void {\n if (this.ended || this.failure) return;\n this.failure = new Error(reason);\n for (const waiting of this.waiting.splice(0)) waiting.reject(this.failure);\n }\n\n /** Take no more of it. Said to the far side, so it stops reading its source. */\n cancel(reason = \"the reader stopped\"): void {\n if (this.stopped || this.ended) return;\n this.stopped = true;\n this.queue.length = 0;\n for (const waiting of this.waiting.splice(0)) waiting.resolve({ value: undefined, done: true });\n this.hooks.cancelled(reason);\n }\n\n async next(): Promise<IteratorResult<Uint8Array>> {\n const queued = this.queue.shift();\n if (queued) {\n this.hooks.consumed(queued.length);\n return { value: queued, done: false };\n }\n if (this.failure) throw this.failure;\n if (this.ended || this.stopped) return { value: undefined, done: true };\n // Nothing flows until somebody waits for it: a blob nobody opens is not read at all.\n this.hooks.wanted();\n return new Promise<IteratorResult<Uint8Array>>((resolve, reject) => {\n this.waiting.push({ resolve, reject });\n });\n }\n\n async return(): Promise<IteratorResult<Uint8Array>> {\n this.cancel();\n return { value: undefined, done: true };\n }\n\n /**\n * The runtime's own stream, built over this one the first time something asks for it. What a\n * sender usually hands over is a `ReadableStream`, so what arrives offers the same interface —\n * `getReader()`, `pipeTo()`, `tee()` — rather than a narrower shape of its own. A runtime\n * without `ReadableStream` keeps the iterable, which is the library's own interface.\n */\n asReadableStream(): ReadableStream<Uint8Array> {\n const ctor = globalThis.ReadableStream;\n if (typeof ctor !== \"function\") throw new Error(\"this runtime has no ReadableStream: read the stream with `for await`\");\n this.platform ??= new ctor({\n pull: async (controller) => {\n const next = await this.next();\n if (next.done) controller.close();\n else controller.enqueue(next.value);\n },\n cancel: (reason: unknown) => {\n this.cancel(typeof reason === \"string\" ? reason : \"the reader stopped\");\n },\n });\n return this.platform;\n }\n\n getReader(): ReadableStreamDefaultReader<Uint8Array> {\n return this.asReadableStream().getReader();\n }\n\n pipeTo(destination: WritableStream<Uint8Array>, options?: StreamPipeOptions): Promise<void> {\n return this.asReadableStream().pipeTo(destination, options);\n }\n\n tee(): [ReadableStream<Uint8Array>, ReadableStream<Uint8Array>] {\n return this.asReadableStream().tee();\n }\n\n /** One consumer, whichever door it comes through: where the runtime has a platform stream this\n * path goes through it, so the lock and the queue are the platform's and not two of ours. */\n async *[Symbol.asyncIterator](): AsyncIterator<Uint8Array> {\n if (typeof globalThis.ReadableStream !== \"function\") {\n for (;;) {\n const next = await this.next();\n if (next.done) return;\n yield next.value;\n }\n }\n const reader = this.asReadableStream().getReader();\n let finished = false;\n try {\n for (;;) {\n const next = await reader.read();\n if (next.done) {\n finished = true;\n return;\n }\n yield next.value;\n }\n } finally {\n reader.releaseLock();\n // A reader that walks away is a reader that takes no more: the far side is told to stop.\n if (!finished) this.cancel();\n }\n }\n}\n\n/**\n * A blob that came over a connection: the same value the far side offered, with its bytes still\n * over there. Reading it is what asks for them — and only at the pace the reader takes them, so a\n * file nobody opens costs nothing on the wire.\n */\nexport class RemoteBlob implements Blob {\n private readonly body: RemoteStream;\n\n constructor(\n body: RemoteStream,\n readonly facts: BlobFacts,\n ) {\n this.body = body;\n }\n\n get size(): number {\n return this.facts.size;\n }\n\n get type(): string | undefined {\n return this.facts.type;\n }\n\n get name(): string | undefined {\n return this.facts.name;\n }\n\n stream(): Stream {\n return this.body;\n }\n\n async arrayBuffer(): Promise<ArrayBuffer> {\n const all = await bytesOf(this.body);\n return all.buffer as ArrayBuffer;\n }\n}\n\n/**\n * Bytes that crossed a connection: the sender's array, taken apart into a stream and put back\n * together here as the chunks arrive. Not lazy — the sender was asked the moment the reference\n * arrived — so awaiting this is waiting for the last chunk, not for a read to start.\n */\nexport class RemoteBytes implements PromiseLike<Uint8Array> {\n /** The length the sender stated, which the octets must add up to. */\n readonly size: number;\n private readonly body: RemoteStream;\n private filling: Promise<Uint8Array> | null = null;\n\n constructor(body: RemoteStream, size: number) {\n this.body = body;\n this.size = size;\n }\n\n /** Start re-assembling. Called by the store once its record for this stream is in place. */\n start(): void {\n void this.bytes().catch(() => {});\n }\n\n /** The octets, once they are all here. */\n bytes(): Promise<Uint8Array> {\n this.filling ??= this.pvtFill();\n return this.filling;\n }\n\n /** The same octets as an array's buffer, for a caller that wants the platform's shape. */\n async arrayBuffer(): Promise<ArrayBuffer> {\n return (await this.bytes()).buffer as ArrayBuffer;\n }\n\n then<TResult1 = Uint8Array, TResult2 = never>(\n onfulfilled?: ((value: Uint8Array) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): Promise<TResult1 | TResult2> {\n return this.bytes().then(onfulfilled, onrejected);\n }\n\n private async pvtFill(): Promise<Uint8Array> {\n const all = new Uint8Array(this.size);\n let at = 0;\n for await (const chunk of this.body) {\n if (at + chunk.length > all.length) throw new Error(`the array is longer than the ${this.size} bytes it stated`);\n all.set(chunk, at);\n at += chunk.length;\n }\n if (at !== all.length) throw new Error(`the array is short: ${at} of ${this.size} octets arrived`);\n return all;\n }\n}\n\n// ── the store ──────────────────────────────────────────────────────────────\n\n/** What this side is sending: the source, the credit it has been given, and what is left of a chunk. */\ninterface Offered {\n id: number;\n source: AsyncIterator<Uint8Array>;\n /** The rest of a piece the source gave us, not yet cut into chunks. */\n pending: Uint8Array | null;\n /** Octets the reader has asked for and not been sent. */\n credit: number;\n seq: number;\n pumping: boolean;\n dropped: boolean;\n}\n\n/** What this side is reading. */\ninterface Incoming {\n id: number;\n reader: RemoteStream;\n /** What the far side made of it: a stream until a reference says otherwise. */\n form: ValueForm;\n /** The value a reference asked for, built once: a stream, a blob over it, or bytes. */\n value?: RemoteStream | RemoteBlob | RemoteBytes;\n /** Octets asked for, and octets the consumer has taken: what may still be in flight. */\n asked: number;\n consumed: number;\n /** Octets that have arrived, for a value whose size this side was never told. */\n received: number;\n /** The chunk whose head and bytes have arrived, waiting for its tail. */\n chunk: { seq: number; bytes: Uint8Array } | null;\n done: boolean;\n}\n\nexport interface StreamStoreOptions {\n chunkBytes?: number;\n windowBytes?: number;\n maxBytes?: number;\n /** Where stream ids come from. One space per side, shared with the process table so a number\n * names one thing on the connection whatever it names. */\n ids?: IdSpace;\n /** Whether the store reads the connection itself. A party that carries a connection it does not\n * speak — a first stage — sets this false and hands frames in with `handle()`, so the far side's\n * frames are never mistaken for its own. */\n attach?: boolean;\n}\n\n/**\n * One connection's streams, as this side sees them.\n *\n * Both directions are in one table, because both are the same numbering: what this side offers\n * (and answers asks for) and what it may read from the far side. Ids follow the process table's\n * parity, so an id names one stream on one connection and nothing anywhere else.\n */\nexport class StreamStore implements ValueCodec {\n private readonly channel: Channel;\n private readonly chunkBytes: number;\n private readonly windowBytes: number;\n readonly maxBytes: number;\n private readonly pvtOffers = new Map<number, Offered>();\n private readonly pvtIncoming = new Map<number, Incoming>();\n private readonly ids: IdSpace;\n /** Why streams that are over failed, for a reference that arrives after the fact. */\n private readonly pvtRefused = new Map<number, { reason: string; form: ValueForm }>();\n /** What this side announced under a name, and what the far side did. A name is taken while it is\n * in either map, so the two directions never answer to one name at once. */\n private readonly pvtNamesOut = new Map<string, number>();\n private readonly pvtNamesIn = new Map<string, number>();\n /** Told about every named stream the far side announces: the live ones replay, then each arrival. */\n private readonly pvtNamedListeners = new Set<(name: string, stream: RemoteStream) => void>();\n private readonly pvtOff: () => void;\n private readonly pvtSegmentOff: (() => void) | null = null;\n private pvtClosed = false;\n\n constructor(channel: Channel, parity: IdParity, options: StreamStoreOptions = {}) {\n this.channel = channel;\n this.chunkBytes = options.chunkBytes ?? DEFAULT_CHUNK_BYTES;\n this.windowBytes = options.windowBytes ?? DEFAULT_WINDOW_BYTES;\n this.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n this.ids = options.ids ?? new IdSpace(parity);\n const attached = options.attach !== false;\n this.pvtOff = attached\n ? channel.onMessage((frame) => {\n this.onFrame(frame);\n })\n : () => {};\n this.pvtSegmentOff = attached ? (channel.onSegment?.((head, bytes) => this.onSegment(head, bytes)) ?? null) : null;\n }\n\n /** Whether this connection can carry a stream at all: it must carry octets beside its lines. */\n get canCarryStreams(): boolean {\n return this.pvtSegmentOff !== null && this.channel.sendSegment !== undefined;\n }\n\n /**\n * Offer a stream to the connection: the announcement goes out now, and the bytes when the far\n * side asks for them. What comes back is what a message carries in their place.\n *\n * A `name` makes the stream findable: the far side can reference it by that name instead of the\n * id, and ask for it with `named()` without waiting for a message to carry a reference.\n */\n offer(stream: Stream, name?: string): StreamRef {\n return { $s: { id: this.pvtAnnounce(stream[Symbol.asyncIterator](), name) } };\n }\n\n /**\n * Offer a blob — a whole file, read on demand. It crosses as a stream over its bytes and arrives\n * on the far side as a `RemoteBlob`, so nothing of it is read until somebody wants the bytes.\n */\n offerBlob(blob: BlobSource): BlobRef {\n const { size, type, name } = blob;\n const id = this.pvtAnnounce(this.pvtBlobChunks(blob));\n return { $blob: { id, size, ...(type === undefined ? {} : { type }), ...(name === undefined ? {} : { name }) } };\n }\n\n /**\n * Offer bytes this side already holds. The reference states the length, so the far side can\n * check it against its bound and size the array before the first chunk arrives — a typed array\n * is one piece, so the wire carries it as a stream of one.\n */\n offerBytes(bytes: Uint8Array): BytesRef {\n return { $bytes: { id: this.pvtAnnounce(this.pvtOnePiece(bytes)), size: bytes.length } };\n }\n\n private pvtAnnounce(source: AsyncIterator<Uint8Array>, name?: string): number {\n const id = this.ids.next();\n this.pvtOffers.set(id, { id, source, pending: null, credit: 0, seq: 0, pumping: false, dropped: false });\n if (name !== undefined) this.pvtNamesOut.set(name, id);\n void this.channel.send(name === undefined ? { $stream: { id } } : { $stream: { id, name } });\n return id;\n }\n\n private async *pvtOnePiece(bytes: Uint8Array): AsyncGenerator<Uint8Array> {\n if (bytes.length > 0) yield bytes;\n }\n\n /** A blob's octets, a window at a time: sliced where the value can, streamed where it cannot. */\n private async *pvtBlobChunks(blob: BlobSource): AsyncGenerator<Uint8Array> {\n const slice = blob.slice;\n if (slice) {\n for (let at = 0; at < blob.size; at += this.chunkBytes) {\n const end = Math.min(at + this.chunkBytes, blob.size);\n yield new Uint8Array(await slice.call(blob, at, end).arrayBuffer());\n }\n return;\n }\n const stream = blob.stream;\n if (!stream) throw new TypeError(\"a blob must offer a slice or a stream\");\n yield* stream.call(blob);\n }\n\n /** A value on its way out: every stream in it becomes an announcement and a reference. */\n encode(value: unknown): unknown {\n return this.pvtEncode(value, new Set());\n }\n\n /** A value just read: every reference in it becomes something this side can read. */\n decode(value: unknown): unknown {\n return this.pvtDecode(value, new Set());\n }\n\n /** Drop every stream of this connection, in both directions. Called when it ends. */\n close(): void {\n if (this.pvtClosed) return;\n this.pvtClosed = true;\n this.pvtOff();\n this.pvtSegmentOff?.();\n for (const offered of this.pvtOffers.values()) {\n offered.dropped = true;\n // A reader still waiting is told the stream is over rather than left on a connection that is\n // about to end: the frames may still go out, and a send that cannot is nobody's to hear.\n void Promise.resolve(this.channel.send({ $streamDone: { id: offered.id } })).catch(() => {});\n void offered.source.return?.();\n }\n this.pvtOffers.clear();\n for (const incoming of this.pvtIncoming.values()) incoming.reader.fail(\"the connection ended\");\n this.pvtIncoming.clear();\n }\n\n /** The ids this side is holding, in the order they were offered. */\n held(): number[] {\n return [...this.pvtOffers.keys()];\n }\n\n /**\n * Take a frame if it is one this store answers for, and say whether it did. A party that carries a\n * connection it does not speak — a first stage, relaying a client to a payload — has to know which\n * inbound frames are its own and which belong to the far side, and this is the question it asks.\n * Only frames about a stream this side offered are claimed, so a stream the far side offers passes\n * through untouched.\n */\n handle(frame: Record<string, unknown>): boolean {\n if (this.pvtClosed) return false;\n const id = frameId(frame);\n if (id === null || !this.pvtOffers.has(id)) return false;\n this.onFrame(frame);\n return true;\n }\n\n /**\n * The stream the far side announced under `name`, if it is still live — the way a caller finds a\n * stream nobody sent it a reference to. A name that was never announced answers `undefined`, and a\n * name whose stream is over does too: the sentence lives on the value the reference would give.\n */\n named(name: string): RemoteStream | undefined {\n const id = this.pvtNamesIn.get(name);\n if (id === undefined) return undefined;\n return this.pvtValueFor(id, \"stream\") as RemoteStream;\n }\n\n /**\n * Every named stream the far side announces, now and later. The listener is called for the names\n * already live when it is installed and for each new one as it arrives, so a caller that wires a\n * sink to `stdout` does not have to know whether the far side has printed yet.\n */\n onNamed(listener: (name: string, stream: RemoteStream) => void): () => void {\n this.pvtNamedListeners.add(listener);\n for (const [name, id] of this.pvtNamesIn) {\n if (this.pvtIncoming.has(id)) listener(name, this.pvtValueFor(id, \"stream\") as RemoteStream);\n }\n return () => {\n this.pvtNamedListeners.delete(listener);\n };\n }\n\n // ── writing ────────────────────────────────────────────────────────────\n\n private pvtSend(frame: Record<string, unknown>): Promise<void> {\n return Promise.resolve(this.channel.send(frame));\n }\n\n private pvtEncode(value: unknown, seen: Set<unknown>): unknown {\n if (typeof value !== \"object\" || value === null) return value;\n // Offering reads the source's own facts (`size`, `type`, `name`), so it is asked before the\n // walk decides the value is a plain object to copy.\n // A blob is offered before a stream is looked for: it is a value with bytes behind it, not the\n // iterator itself, and the far side is given a blob back.\n if (isBlob(value)) return this.offerBlob(value);\n if (isStreamLike(value)) return this.offer(value);\n if (seen.has(value)) return value;\n seen.add(value);\n if (Array.isArray(value)) return value.map((item) => this.pvtEncode(item, seen));\n if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return this.offerBytes(asOctets(value));\n // Only a plain object is walked into: a handle, a logger, anything with its own prototype is\n // the application's and is left as it is. Copying one would take its methods away.\n if (!isPlainObject(value)) return value;\n const copy: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) copy[key] = this.pvtEncode(item, seen);\n return copy;\n }\n\n private pvtTake(offered: Offered): Uint8Array | null {\n if (offered.pending === null) return null;\n const size = Math.min(offered.pending.length, this.chunkBytes, offered.credit);\n const piece = offered.pending.subarray(0, size);\n offered.pending = size === offered.pending.length ? null : offered.pending.subarray(size);\n return piece;\n }\n\n private async pvtPull(offered: Offered): Promise<boolean> {\n const next = await offered.source.next();\n if (next.done) return false;\n const value: unknown = next.value;\n const bytes =\n value instanceof Uint8Array\n ? value\n : ArrayBuffer.isView(value)\n ? new Uint8Array(value.buffer, value.byteOffset, value.byteLength)\n : value instanceof ArrayBuffer\n ? new Uint8Array(value)\n : null;\n if (bytes === null) throw new TypeError(\"a stream may only yield octets\");\n if (bytes.length === 0) return true;\n offered.pending = bytes;\n return true;\n }\n\n private async pvtPump(offered: Offered): Promise<void> {\n if (offered.pumping || offered.dropped || this.pvtClosed) return;\n offered.pumping = true;\n try {\n while (!offered.dropped && offered.credit > 0) {\n if (offered.pending === null && !(await this.pvtPull(offered))) {\n await this.channel.send({ $streamDone: { id: offered.id } });\n this.pvtDrop(offered);\n return;\n }\n const piece = this.pvtTake(offered);\n if (piece === null) continue;\n const seq = offered.seq;\n offered.seq += 1;\n offered.credit -= piece.length;\n await this.channel.sendSegment?.({ $chunk: { id: offered.id, seq, bytes: piece.length } }, piece);\n await this.channel.send({ $chunkEnd: { id: offered.id, seq, crc32: crc32(piece) } });\n }\n } catch (error) {\n await this.pvtSend({ $streamFail: { id: offered.id, reason: reasonOf(error) } }).catch(() => {});\n this.pvtDrop(offered);\n } finally {\n offered.pumping = false;\n }\n }\n\n private pvtDrop(offered: Offered): void {\n if (offered.dropped) return;\n offered.dropped = true;\n this.pvtOffers.delete(offered.id);\n this.pvtRelease(offered.id);\n }\n\n /**\n * Take a stream out of the live table and remember why it ended, for a reference that arrives\n * after the fact: \"no stream was announced\" is the wrong sentence for a stream that was refused.\n */\n private pvtRetire(id: number, reason: string, form: ValueForm = \"stream\"): void {\n this.pvtIncoming.delete(id);\n this.pvtRelease(id);\n this.pvtRefused.set(id, { reason, form });\n // A connection lives a long time and a refusal is rare; past a bound the oldest reason goes.\n if (this.pvtRefused.size > 64) {\n const oldest = this.pvtRefused.keys().next();\n if (!oldest.done) this.pvtRefused.delete(oldest.value);\n }\n }\n\n /** A stream that is over gives its name back, so the next announcement of it is not a duplicate. */\n private pvtRelease(id: number): void {\n for (const [name, bound] of this.pvtNamesIn) if (bound === id) this.pvtNamesIn.delete(name);\n for (const [name, bound] of this.pvtNamesOut) if (bound === id) this.pvtNamesOut.delete(name);\n }\n\n // ── reading ────────────────────────────────────────────────────────────\n\n private pvtDecode(value: unknown, seen: Set<unknown>): unknown {\n if (typeof value !== \"object\" || value === null) return value;\n if (isBytesRef(value)) return this.pvtValueFor(value.$bytes.id, \"bytes\", { size: value.$bytes.size });\n if (isBlobRef(value)) {\n const { id, size, type, name } = value.$blob;\n return this.pvtValueFor(id, \"blob\", { size, type, name });\n }\n if (isStreamRef(value)) {\n const ref = value.$s;\n return \"id\" in ref ? this.pvtValueFor(ref.id, \"stream\") : this.pvtValueForNamed(ref.name);\n }\n if (seen.has(value)) return value;\n seen.add(value);\n if (Array.isArray(value)) return value.map((item) => this.pvtDecode(item, seen));\n if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return value;\n // Whatever a store earlier in the chain already turned into a handle is not a plain object any\n // more, and copying it here would strip what makes it one.\n if (!isPlainObject(value)) return value;\n const copy: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) copy[key] = this.pvtDecode(item, seen);\n return copy;\n }\n\n private pvtValueFor(id: number, form: ValueForm, facts?: BlobFacts): RemoteStream | RemoteBlob | RemoteBytes {\n const incoming = this.pvtIncoming.get(id);\n if (!incoming) {\n // A reference to a stream that is over, or one this side was never told about. The value says\n // so when it is read rather than throwing in the middle of a decoded frame: it was the message's\n // fault, not the connection's.\n const ended = this.pvtRefused.get(id);\n const failed = new RemoteStream({ consumed() {}, cancelled() {}, wanted() {} });\n failed.fail(ended?.reason ?? `no stream was announced with id ${id}`);\n return this.pvtBuild(failed, ended?.form ?? form, facts);\n }\n if (incoming.value) return incoming.value;\n incoming.form = form;\n const value = (incoming.value = this.pvtBuild(incoming.reader, form, facts));\n // The size is on the reference now, so a value this side will not read is refused before a\n // chunk is asked for. A plain stream has no size to check: its bound is counted as it arrives.\n if (facts !== undefined && facts.size > this.maxBytes) {\n const reason = `stream ${id} is ${facts.size} bytes, over this side's bound of ${this.maxBytes}`;\n incoming.done = true;\n incoming.reader.fail(reason);\n this.pvtRetire(id, reason, form);\n void this.channel.send({ $streamFail: { id, reason: \"over the reader's bound\" } });\n }\n if (value instanceof RemoteBytes) value.start();\n return value;\n }\n\n /** The value a name the far side announced stands for — or one that says it was never announced. */\n private pvtValueForNamed(name: string): RemoteStream {\n const id = this.pvtNamesIn.get(name);\n if (id !== undefined && this.pvtIncoming.has(id)) return this.pvtValueFor(id, \"stream\") as RemoteStream;\n const failed = new RemoteStream({ consumed() {}, cancelled() {}, wanted() {} });\n failed.fail(`no stream was announced with the name ${name}`);\n return failed;\n }\n\n private pvtBuild(reader: RemoteStream, form: ValueForm, facts?: BlobFacts): RemoteStream | RemoteBlob | RemoteBytes {\n if (form === \"blob\" && facts !== undefined) return new RemoteBlob(reader, facts);\n if (form === \"bytes\" && facts !== undefined) return new RemoteBytes(reader, facts.size);\n return reader;\n }\n\n private pvtAsk(incoming: Incoming): void {\n if (incoming.done || this.pvtClosed) return;\n const outstanding = incoming.asked - incoming.consumed;\n if (outstanding >= this.windowBytes / 2) return;\n const credit = this.windowBytes - outstanding;\n incoming.asked += credit;\n void this.channel.send({ $streamAsk: { id: incoming.id, credit } });\n }\n\n private pvtAnnounced(id: number, name?: string): void {\n const existing = this.pvtIncoming.get(id);\n existing?.reader.fail(`a stream was announced twice with id ${id}`);\n if (name !== undefined) {\n const taken = this.pvtNamesIn.get(name);\n // A name already live is refused: a reference to it would otherwise resolve to whichever of the\n // two arrived last, and neither side would be able to say which.\n if (taken !== undefined) {\n const reason = `a stream named ${name} is already live (id ${taken})`;\n this.pvtRetire(id, reason, \"stream\");\n void this.channel.send({ $streamFail: { id, reason } });\n return;\n }\n this.pvtNamesIn.set(name, id);\n }\n // The reader is built before the record it lives in: its callbacks close over that record and only run\n // once a chunk or a cancel arrives, which is after the assignment below.\n let incoming: Incoming;\n const reader = new RemoteStream({\n consumed: (bytes) => {\n incoming.consumed += bytes;\n this.pvtAsk(incoming);\n },\n wanted: () => {\n this.pvtAsk(incoming);\n },\n cancelled: (reason) => {\n incoming.done = true;\n this.pvtIncoming.delete(id);\n this.pvtRelease(id);\n void this.channel.send({ $streamCancel: { id, reason } });\n },\n });\n incoming = { id, reader, form: \"stream\", asked: 0, consumed: 0, received: 0, chunk: null, done: false };\n this.pvtIncoming.set(id, incoming);\n if (name !== undefined) {\n const stream = this.pvtValueFor(id, \"stream\") as RemoteStream;\n for (const listener of this.pvtNamedListeners) listener(name, stream);\n }\n }\n\n private onSegment(head: Record<string, unknown>, bytes: Uint8Array): void {\n const chunk = head.$chunk as { id?: unknown; seq?: unknown; bytes?: unknown } | undefined;\n if (typeof chunk?.id !== \"number\" || typeof chunk.seq !== \"number\") return;\n const incoming = this.pvtIncoming.get(chunk.id);\n if (!incoming || incoming.done) {\n // A stream this side has dropped or never heard of: the octets are skipped, and that is what\n // the head's own length is for.\n return;\n }\n incoming.received += bytes.length;\n if (incoming.received > this.maxBytes) {\n const reason = `stream ${incoming.id} passed this side's bound of ${this.maxBytes} bytes`;\n incoming.done = true;\n incoming.reader.fail(reason);\n this.pvtRetire(incoming.id, reason, incoming.form);\n void this.channel.send({ $streamFail: { id: incoming.id, reason: \"over the reader's bound\" } });\n return;\n }\n incoming.chunk = { seq: chunk.seq, bytes };\n }\n\n private onFrame(frame: Record<string, unknown>): void {\n if (this.pvtClosed) return;\n if (\"$stream\" in frame) {\n const body = frame.$stream as { id?: unknown; name?: unknown } | undefined;\n if (typeof body?.id !== \"number\") return;\n this.pvtAnnounced(body.id, typeof body.name === \"string\" ? body.name : undefined);\n return;\n }\n if (\"$streamAsk\" in frame) {\n const body = frame.$streamAsk as { id?: unknown; credit?: unknown } | undefined;\n const offered = typeof body?.id === \"number\" ? this.pvtOffers.get(body.id) : undefined;\n if (!offered || typeof body?.credit !== \"number\" || body.credit <= 0) return;\n offered.credit += body.credit;\n void this.pvtPump(offered);\n return;\n }\n if (\"$chunkEnd\" in frame) {\n const body = frame.$chunkEnd as { id?: unknown; seq?: unknown; crc32?: unknown } | undefined;\n const incoming = typeof body?.id === \"number\" ? this.pvtIncoming.get(body.id) : undefined;\n if (!incoming) return;\n const chunk = incoming.chunk;\n incoming.chunk = null;\n if (chunk === null || chunk.seq !== body?.seq) {\n incoming.done = true;\n incoming.reader.fail(`stream ${incoming.id} lost its framing: a chunk ended that never began`);\n this.pvtRetire(incoming.id, `stream ${incoming.id} lost its framing: a chunk ended that never began`, incoming.form);\n void this.channel.send({ $streamFail: { id: incoming.id, reason: \"lost the framing\" } });\n return;\n }\n if (typeof body?.crc32 === \"number\" && crc32(chunk.bytes) !== body.crc32) {\n incoming.done = true;\n incoming.reader.fail(`stream ${incoming.id} arrived corrupt: chunk ${chunk.seq} failed its checksum`);\n this.pvtRetire(incoming.id, `stream ${incoming.id} arrived corrupt: chunk ${chunk.seq} failed its checksum`, incoming.form);\n void this.channel.send({ $streamFail: { id: incoming.id, reason: \"a chunk failed its checksum\" } });\n return;\n }\n incoming.reader.push(chunk.bytes);\n return;\n }\n if (\"$streamDone\" in frame) {\n const body = frame.$streamDone as { id?: unknown } | undefined;\n const incoming = typeof body?.id === \"number\" ? this.pvtIncoming.get(body.id) : undefined;\n if (!incoming) return;\n incoming.done = true;\n this.pvtIncoming.delete(incoming.id);\n this.pvtRelease(incoming.id);\n incoming.reader.end();\n return;\n }\n if (\"$streamFail\" in frame) {\n const body = frame.$streamFail as { id?: unknown; reason?: unknown } | undefined;\n const incoming = typeof body?.id === \"number\" ? this.pvtIncoming.get(body.id) : undefined;\n if (!incoming) return;\n const reason = typeof body?.reason === \"string\" ? body.reason : `stream ${incoming.id} failed`;\n incoming.done = true;\n incoming.reader.fail(reason);\n this.pvtRetire(incoming.id, reason, incoming.form);\n return;\n }\n if (\"$streamCancel\" in frame) {\n const body = frame.$streamCancel as { id?: unknown } | undefined;\n const offered = typeof body?.id === \"number\" ? this.pvtOffers.get(body.id) : undefined;\n if (!offered) return;\n this.pvtDrop(offered);\n void offered.source.return?.();\n }\n }\n}\n\n/** A typed array or an `ArrayBuffer` as the octets the wire carries. */\nfunction asOctets(value: ArrayBuffer | ArrayBufferView): Uint8Array {\n if (ArrayBuffer.isView(value)) return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n return new Uint8Array(value);\n}\n\nfunction reasonOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** The stream id a control frame names, or null when it names none of them. */\nfunction frameId(frame: Record<string, unknown>): number | null {\n for (const key of [\"$streamAsk\", \"$streamCancel\", \"$streamDone\", \"$streamFail\"]) {\n const body = frame[key] as { id?: unknown } | undefined;\n if (typeof body?.id === \"number\") return body.id;\n }\n return null;\n}\n","// ── Server side of the seam ────────────────────────────────────────────────\n//\n// serveChannel serves one process over a frame Channel that is already through the `$proto` handshake, and\n// takes a factory for the process rather than spawning one itself. It knows only the frame vocabulary\n// (channel.ts) — no protocol, no transport, no spawner. The reactor calls it once for each connection it\n// accepts, and serveRemoteActor (reactor.ts) is the same thing for a single connection.\nimport type { ActorDefinition, SpawnedFrom } from \"../actor-types.js\";\nimport { isProcess } from \"../process.async.js\";\nimport type { Channel } from \"./channel.js\";\nimport {\n IdSpace,\n ProcessTable,\n SERVED_ROOT_NAME,\n isRemoteProcess,\n type ProcessHandle,\n type ProcessRef,\n} from \"./process-ref.js\";\nimport { RemoteProcess, type FrameSink } from \"./remote-process.js\";\nimport { ProcessStreams } from \"./process-streams.js\";\nimport { makeSender } from \"./sender.js\";\nimport {\n REFLECT_METHODS,\n asReflectionCall,\n badReason,\n decodeFrame,\n encodeFrame,\n errorFrame,\n errorReason,\n frameTo,\n isExit,\n isInit,\n isMsg,\n isPause,\n isRelease,\n isResume,\n isState,\n isStop,\n isTune,\n isReflectionMethods,\n tuneFrame,\n} from \"./channel.js\";\nimport { CallSide, answerCall } from \"./call-side.js\";\nimport { StreamStore, type StreamStoreOptions } from \"./stream.js\";\n\nexport type Spawner = () => Promise<Channel>;\n\n/** The process a definition's spawn gives back: what a caller reports when it serves one. */\nexport type ServedProcess<T extends ActorDefinition<any, any, any, any, any>> = SpawnedFrom<T>;\n\n/** A process, whatever definition it came from: all the serving half needs of one. */\nexport type AnyProcess = ServedProcess<ActorDefinition<any, any, any, any, any>>;\n\n/** What the far side stated when it opened the connection: the args it asks to be spawned with, and its own\n * name for its end of the connection. */\nexport interface Init<Args = unknown> {\n readonly args: Args;\n /** The name the process answers to as a sender: the far side's word, or the default when it stated none. */\n readonly rootName: string;\n readonly parentName: string | null;\n readonly parentId: symbol | null;\n}\n\n/** What a factory answers: the process to serve, and what the serving half has to know about it. */\nexport interface Served<Meta = unknown> {\n readonly proc: AnyProcess;\n /** What the factory resolved, when it has more to say about the session than the connection did. */\n readonly meta?: Meta;\n /**\n * What ends this session: run once, when the connection closes and when the reactor stops. It defaults to\n * stopping the process, which is what a factory that spawned one wants; a factory that hands over a process\n * it did not spawn returns its own, since that process outlives every connection.\n */\n readonly cleanup?: () => void | Promise<void>;\n}\n\n/** A factory, as the serving half sees it: the connection and the meta are its caller's business. */\nexport type MakeProcess<Meta = unknown> = (init: Init) => Served<Meta> | Promise<Served<Meta>>;\n\n/** The name the served actor is spawned under, and the one it answers to as a sender when\n * it talks to a process of the far side's: what the client states in `$init`, since the\n * process being served is the one its proxy was forked as over there. The fallback is for\n * a connection that states none — an older client, or a hand-written `$init` — where the\n * far side's name for its own end is all there is to go on. */\nlet rootName: string = SERVED_ROOT_NAME;\n\nexport async function serveChannel<Meta = unknown>(\n channel: Channel,\n makeProc: MakeProcess<Meta>,\n /**\n * Called once the served process is up and wired to the connection, with what the factory answered and the\n * one function that ends this session. Nothing about the serve changes because of it.\n */\n onSpawned?: (served: Served<Meta>, ended: () => Promise<void>) => void,\n streamOptions?: StreamStoreOptions,\n): Promise<void> {\n // The table takes the even ids: the odd ones are the far side's, so the same\n // number can never name a process on both ends at once. A process that is\n // numbered here is one that is about to cross, and its stream follows the frame\n // that carried it.\n // One id space for everything this side numbers — the process table and the stream store alike.\n const ids = new IdSpace(\"even\");\n const table = new ProcessTable<ProcessHandle>(\"even\", (proc, id) => streams.crossed(proc, id), ids);\n // The connection's byte streams, on the same parity split the process table uses: the octets ride\n // as segments beside the frames, and a blob crosses the same way a stream does.\n const byteStreams = new StreamStore(channel, \"even\", { ...streamOptions, ids });\n\n /** Put an encoded frame on the wire, and then say what it numbered. A frame that\n * carried a reference has to be out before anything about that process is. */\n const write = async (frame: Record<string, unknown>): Promise<void> => {\n await channel.send(frame);\n streams.flush();\n };\n\n const sendToFrame = (frame: Record<string, unknown>, to: number): Promise<void> =>\n write(encodeFrame(frame, table, to, byteStreams));\n\n /** Set once the connection is winding down: from here a frame that cannot be delivered has\n * nowhere to go by construction, and saying so with a stack is noise (see the sink below). */\n let pvtWindDown = false;\n\n /** Every frame leaves this way. The answer is handed back, since the one frame that\n * has to be out before the wire closes is awaited by the side that owns the wire. */\n const sendTo: FrameSink = (frame, to) =>\n sendToFrame(frame, to).catch((e: unknown) => {\n // Two different things wear the same words. On a live wire a frame that did not go is a\n // loss and belongs in the log with its stack; during the wind-down the peer is gone by\n // construction and every stream still saying its last word fails the same way. Measured on\n // the voice service, 2026-09-28: half a dozen raw stacks per restart from the teardown paths\n // alone, which is how a reader — twice that evening — comes to mistake a deploy for an outage.\n if (pvtWindDown) return;\n console.error(\"Error sending out the frame\", e);\n });\n\n // Everything is in place to speak: the sink writes to the wire, and what the\n // table numbers crosses through it.\n const streams = new ProcessStreams(sendTo, table.rootId());\n\n // Both ends of a connection make calls and answer them: a process the far side\n // holds is asked the same way this side is asked.\n const calls = new CallSide(write, table, byteStreams);\n\n /** The handle for a reference that arrived: the same one every time, and the process\n * itself when the reference names a process of this side's own. The roots are\n * numbered apart, so a reference to the far side's root is a reference to a process\n * of theirs, and a handle like any of those. */\n const handleFor = (ref: ProcessRef): ProcessHandle => {\n const held = table.processFor(ref.id);\n if (held) return held;\n const known = table.farHandleFor(ref.id);\n if (isRemoteProcess(known)) return known;\n const handle = new RemoteProcess(ref, sendTo, rootName, (id) => table.release(id));\n table.bindFar(ref.id, handle);\n return handle;\n };\n\n // The first frame is the $init. A connection that goes before it will never be served, so the wait\n // settles on the close as well: pending forever is one promise and one channel left behind per peer\n // that dials and hangs up. The collecting handler stays until the actor can be dispatched to, so\n // frames that arrive while it starts wait here and are replayed rather than dropped for want of a slot.\n const waiting: Record<string, unknown>[] = [];\n let stopCollecting: () => void = () => {};\n await new Promise<void>((resolve, reject) => {\n stopCollecting = channel.onMessage((frame) => {\n waiting.push(frame);\n resolve();\n });\n channel.onClose(() => reject(new Error(\"serveRemoteActor: the connection went before $init\")));\n });\n const firstFrame = waiting.shift() as Record<string, unknown>;\n // A first frame that could not be read is a failed start like any other: the far side is told\n // what could not be read, and this connection is refused to its caller — the spawner that opened\n // it — rather than raised into the host. Nothing is served yet, so nothing is stopped here.\n const initProblem = badReason(firstFrame) ?? errorReason(firstFrame);\n if (initProblem !== null) {\n await write(errorFrame(`expected $init: ${initProblem}`)).catch(() => undefined);\n throw new Error(`serveRemoteActor: expected $init (${initProblem})`);\n }\n const initFrame = decodeFrame(firstFrame, handleFor, byteStreams);\n if (!isInit(initFrame)) {\n throw new Error(\"serveRemoteActor: expected $init\");\n }\n\n const init = initFrame.$init;\n const stated = init.rootName;\n if (typeof stated === \"string\" && stated !== \"\") rootName = stated;\n const parentName = (init.parentName as string) ?? null;\n const parentIdName = (init.parentIdName as string) ?? null;\n const parentId = parentIdName ? Symbol.for(parentIdName) : null;\n const { parentName: _pn, parentIdName: _pid, ...initArgs } = init;\n\n const opening: Init = {\n args: initArgs,\n rootName,\n parentName,\n parentId,\n };\n const served = await makeProc(opening);\n const proc = served.proc;\n\n // What ends this session, run once: the factory's cleanup when it returned one, and stopping the process\n // when it did not. A process meant to outlive the connection is handed over with a cleanup of its own,\n // since stopping it here would end it for every other connection bound to it. The call is kept, so\n // whoever asks second waits for the ending rather than returning before it.\n let pvtEnding: Promise<void> | null = null;\n const end = (): Promise<void> => {\n if (pvtEnding === null) {\n pvtEnding = (async () => {\n await (served.cleanup ?? (() => proc.stop()))();\n })();\n }\n return pvtEnding;\n };\n\n // This side's own end of the connection is the process this session serves: id 0\n // here, and on the other side the proxy that asked for it.\n table.bindRoot(proc);\n\n await proc.ready();\n\n // The root is a process that crossed this connection like any other, at the id this\n // side gave it. What it can be asked is announced, and what it holds and what it\n // says are said once the far side asks: the announced list is the whole surface, so a\n // name that was never on it can never be reached. A proxy on the other end asks for\n // the state and the messages it stands in for the moment it connects.\n streams.crossed(proc, table.rootId());\n streams.flush();\n\n // The session is over when either side is: the process ended, or the connection went. That is the same\n // moment for a process the session owns, since its cleanup stops it, and not the same at all for one that\n // outlives the connection. A close handler is one slot, so the promise the teardown waits on is settled\n // from the same place the cleanup runs.\n let pvtGone: () => void = () => {};\n const connectionGone = new Promise<void>((resolve) => {\n pvtGone = resolve;\n });\n channel.onClose(() => {\n pvtGone();\n void end();\n });\n\n // The process is up and wired: whoever asked for the handle of what is served gets it here, which is\n // the only moment it exists and the connection is still open.\n onSpawned?.(served, end);\n\n /**\n * A frame that was not a frame is the connection's problem and not the process's: the far side is\n * told what could not be read, and then this connection ends — the actor it was serving ends with\n * it, that being what it was spawned for. The host everything else runs in is never the cost of\n * one peer that is not speaking the protocol.\n *\n * The write is awaited only so the reason is out before the wire closes. A wire that has already\n * gone ends nothing twice, and the ending is the part that matters.\n */\n const endUnreadable = async (reason: string): Promise<void> => {\n console.warn(`a frame from the far side could not be read: ${reason}`);\n try {\n await write(errorFrame(reason));\n } catch {\n // The wire went before the reason could; the ending below is the same either way.\n }\n await end();\n };\n\n // bridge channel input → actor\n function dispatch(raw: Record<string, unknown>): void {\n // A frame about the wire is settled before anything else is looked up: what a codec could not\n // read, and a far side saying the connection is over, are one piece of news here — this\n // connection cannot be spoken over any more, and nothing said after it could be trusted. The\n // connection ends; the process does not.\n const wireProblem = badReason(raw) ?? errorReason(raw);\n if (wireProblem !== null) {\n void endUnreadable(wireProblem);\n return;\n }\n const frame = decodeFrame(raw, handleFor, byteStreams);\n // An answer is about the call waiting for it and not about a process: it names\n // the seq, and is settled before anything is looked up.\n if (calls.settle(frame)) return;\n const to = frameTo(frame);\n if (to === null) return;\n // A frame answers one of two questions. News about a process the far side holds\n // lands on the handle for it: what it holds, that it is over, what it can answer.\n // An ask of a process this side holds goes to wherever that process lives: a\n // message, control, a call, a tune.\n const news = table.farHandleFor(to);\n const mine = table.processFor(to);\n if (isRelease(frame)) {\n // A process of this side's own, let go of over there: nothing more is said about\n // it, and the id the far side knew it by is no longer this connection's. The\n // process itself runs on, and a later crossing numbers it afresh. Neither root is\n // let go of, so the table refuses both.\n if (mine !== undefined) {\n streams.stop(to);\n table.release(to);\n }\n return;\n }\n if (isTune(frame)) {\n // How much the far side is told about a process of this side's own is that\n // side's to ask, and this is where the asking lands: what it names is what\n // crosses from now on. An id this side does not hold has nothing to tune.\n if (mine !== undefined) {\n const kinds = tuneFrame(frame);\n if (kinds !== null) streams.tune(to, kinds);\n }\n return;\n }\n if (isReflectionMethods(frame)) {\n // What a process the far side holds can answer, said the moment it crossed:\n // the handle here reads it as its own surface, so a name asked on it is asked\n // there. What a process of this side's own can answer is this side's to\n // announce, not the far side's to tell it.\n if (isRemoteProcess(news)) {\n news.receiveMethods(frame[REFLECT_METHODS], (method, args) => calls.call(method, args, to));\n }\n return;\n }\n if (isState(frame)) {\n // A process the far side holds, saying what it holds: that is news for the\n // handle on it, and lands where a subscription can see it. A state frame about\n // a process of this side's own is this side's to publish, not the far side's to\n // tell it.\n if (isRemoteProcess(news)) news.receiveState(frame.$state);\n return;\n }\n if (isExit(frame)) {\n // A process the far side holds, gone. Nothing more will be said about it, so\n // this is the last thing a handle can be told.\n if (isRemoteProcess(news)) news.receiveExit(frame.$exit);\n return;\n }\n if (isStop(frame) || isPause(frame) || isResume(frame)) {\n // Control, addressed to the process it is about: acted on by whoever holds that\n // process, which is this side. The root is one of those — stopping it stops\n // what the connection is for — and a handle has nothing here to act on.\n if (isProcess(mine)) {\n const sender = makeSender(rootName, parentName, parentId);\n if (isStop(frame)) void mine.stop({ from: sender });\n else if (isPause(frame)) mine.pause();\n else mine.resume();\n }\n return;\n }\n if (isMsg(frame)) {\n const { fromName, body } = frame.$msg;\n // A message for a process this side holds goes into it, the root included. One\n // about a process the far side holds — a handle here — is that process talking,\n // and goes to whoever subscribed to the handle.\n if (isProcess(mine)) mine.send(body, makeSender(fromName, parentName, parentId));\n else if (isRemoteProcess(news)) news.receiveMessage(body, fromName);\n return;\n }\n const call = asReflectionCall(frame);\n if (call) void answerCall(call, mine, write, table, byteStreams);\n }\n\n // The collecting reader stops here, and the dispatch is what hears the frames from now on: the two are\n // not the same reader, and leaving the first one on would buffer every frame for nobody.\n stopCollecting();\n channel.onMessage(dispatch);\n for (const frame of waiting.splice(0)) dispatch(frame);\n\n // The session is awaited here: the process's end, or the connection going, whichever is first.\n let code = 0;\n const procEnded = proc.wait().then(\n () => undefined,\n (err: unknown) => {\n console.error(\"server actor error:\", err);\n code = 1;\n },\n );\n await Promise.race([procEnded, connectionGone]);\n // Whichever it was, the session's cleanup runs here: the process stops, unless the factory answered with\n // something else to do.\n await end();\n // The root is over, which is the last thing said about it. It is said and awaited\n // here, because the wire closes right after it. From this line on, the wire is going: what\n // cannot be delivered is expected, and the sink stops reporting it.\n pvtWindDown = true;\n await streams.sayEnded(table.rootId(), code);\n // And nothing more about anything else of this side's: there is no one left to say\n // it to.\n streams.stopAll();\n // A call this side made and the far side has not answered is not going to be\n // answered now; it fails here rather than hanging.\n calls.rejectAll();\n // A stream read still in flight has no answer coming either.\n byteStreams.close();\n await channel.close();\n}\n","// ── the server reactor ─────────────────────────────────────────────────────\n//\n// One loop for every medium: accept a connection, serve one actor for it, report what is being served,\n// and stop when asked. What a medium is lives in a Listener, so nothing here knows a transport.\n// serveRemoteActor is the same loop for a listener that carries exactly one connection.\n\nimport type { ActorDefinition, ReflectionOptions } from \"../actor-types.js\";\nimport type { Message } from \"../types.js\";\nimport { channelThrough, type Channel, type StringTransport } from \"./channel.js\";\nimport { json1Channel, VERSION } from \"./protocols/json1.js\";\nimport { serveChannel, type AnyProcess, type Init, type Served, type ServedProcess, type Spawner } from \"./server.js\";\nimport type { StreamStoreOptions } from \"./stream.js\";\n\n/** Any actor definition: the reactor serves it, and does not care which one it is. */\nexport type AnyActorDefinition = ActorDefinition<any, any, any, any, any>;\n\n/**\n * A way in, as a listener hands it over: a transport the reactor runs the protocol step on, or a channel\n * that has already been through one (a spawner's, where the handshake is not the reactor's to do).\n */\nexport type Incoming =\n | { readonly transport: StringTransport; readonly channel?: undefined }\n | { readonly channel: Channel; readonly transport?: undefined };\n\n/** An admitted connection: the way in, and whatever the listener knows about it. */\nexport type Connection<Meta = unknown> = Incoming & {\n /** The transport's own facts: what the listener resolved, the URL, the peer. */\n readonly meta: Meta;\n};\n\n/** A connection as a session is built on it: what it was admitted by, what the listener resolved,\n * and the channel above the protocol step. Past admission the way in *is* that channel: the\n * reactor owns the protocol step, so a listener never has to carry one for it. */\nexport type ServedConnection<Meta = unknown> = {\n /** The transport it was admitted on, when the listener handed one over rather than a channel.\n * What the connection came in on, kept as that; the session speaks over `channel`. */\n readonly transport?: StringTransport;\n /** What the listener resolved about the connection. */\n readonly meta: Meta;\n /** The frames of this connection: the channel above the protocol step. This is what the\n * session's process is given as `ctx.connection`, and what a serving half answers with. */\n readonly channel: Channel;\n};\n\n/** Where connections come from. A listener owns its medium and its own admission. */\nexport interface Listener<Meta = unknown> {\n /** The next admitted connection. Rejects once the listener is closed. */\n accept(signal?: AbortSignal): Promise<Connection<Meta>>;\n /** Stop accepting, and release what the listener owns. */\n close(): Promise<void>;\n}\n\n/** One served connection, as the reactor reports it. */\nexport interface Session<Meta = unknown> {\n /** The served process. It is a root process: the seam spawned it for this connection. */\n readonly proc: ServedProcess<AnyActorDefinition>;\n /** What the listener resolved, plus whatever the factory added. */\n readonly meta: Meta;\n /** The frames of this connection: the one the factory was given, so a starter reads and prints on\n * exactly the channel the process is served over. */\n readonly channel: Channel;\n /** Settles when the connection closes and the serve is over. */\n readonly done: Promise<void>;\n}\n\n/** What a connection becomes: the process to serve. It is called once the `$init` has been read, so the\n * args the far side asked for are in hand. A bare actor definition is the shortcut for a factory that\n * spawns one with them. */\nexport type SessionFactory<Meta = unknown> = (\n connection: ServedConnection<Meta>,\n init: Init,\n) => Served<Meta> | AnyProcess | Promise<Served<Meta> | AnyProcess>;\n\n/** The shortcut, as a factory: spawn the definition with what the far side asked for, and hand\n * it the connection as `ctx.connection` so the process speaks for itself from `setup` on. */\nexport function spawnFactory<Meta = unknown>(definition: AnyActorDefinition): SessionFactory<Meta> {\n return async (connection, init) => ({\n proc: await definition.spawn(init.args, {\n name: init.rootName,\n parentName: init.parentName,\n parentId: init.parentId,\n connection: connection.channel,\n }),\n });\n}\n\nexport interface ReactorOptions<Meta = unknown> {\n /** A connection was admitted and its process is up. What it returns is called when the session is\n * over: the place a starter uninstalls what it put on this connection. */\n onSession?(session: Session<Meta>): void | (() => void | Promise<void>);\n /** Its connection closed, and the serve is over. */\n onClosed?(session: Session<Meta>): void;\n /** A connection could not be served: a handshake that never came, a wire that went early. */\n onError?(error: unknown, connection: Connection<Meta>): void;\n /**\n * Every decoded frame, before the serve handles it. Returning true swallows the frame, which is\n * where a subprocess's own output frames (`$fd`) are captured instead of passed on.\n */\n onIncomingFrame?(frame: Record<string, unknown>): boolean | void;\n /** The served side's streams: its own bound on what it will read, and how it chunks what it\n * sends. A connection's reader decides how much it is willing to hold, so the bound is\n * the server's to set — the default refuses anything over 64 MiB. */\n streams?: StreamStoreOptions;\n}\n\nexport interface Reactor {\n /** Stop accepting and stop every live session. */\n stop(): Promise<void>;\n /** How many sessions are being served right now. */\n readonly live: number;\n}\n\nexport function reactor<Meta = unknown>(\n listener: Listener<Meta>,\n serve: AnyActorDefinition | SessionFactory<Meta>,\n options: ReactorOptions<Meta> = {},\n): Reactor {\n const factory: SessionFactory<Meta> = typeof serve === \"function\" ? serve : spawnFactory(serve);\n const stopping = new AbortController();\n // What is being served: the one function that ends each session, and the promise that says it is over.\n const live = new Map<() => Promise<void>, Promise<void>>();\n\n const serveOne = async (connection: Connection<Meta>): Promise<void> => {\n // Held in an object: the session is built inside the seam's callback, and a local `let` assigned\n // only there is narrowed to null by the compiler by the time the teardown reads it.\n const held: {\n session: Session<Meta> | null;\n end: (() => Promise<void>) | null;\n release: (() => void | Promise<void>) | null;\n } = { session: null, end: null, release: null };\n let settle: () => void = () => {};\n const done = new Promise<void>((resolve) => {\n settle = resolve;\n });\n\n try {\n // The way in: a transport this side runs the protocol step on, or a channel somebody else already\n // handshaked. Either way the frame hook goes on before the serve sees a frame.\n const channel = connection.channel\n ? withFrameHook(connection.channel, options.onIncomingFrame)\n : await protocolStep(connection.transport, options);\n\n // What the session is served over: the channel above the protocol step. It goes to the factory,\n // which hands it to the process it spawns (`ctx.connection`), and it is the whole way out — the\n // far end's own output included, as a frame of its own (`outputFrame`, channel.ts).\n const served: ServedConnection<Meta> = {\n transport: connection.transport,\n meta: connection.meta,\n channel,\n };\n\n await serveChannel(\n channel,\n // The factory is asked where the args are: the serve reads the `$init` and hands it over.\n async (init) => {\n const answer = await factory(served, init);\n return \"proc\" in answer ? answer : { proc: answer };\n },\n (spawned, ended) => {\n live.set(ended, done);\n held.end = ended;\n const session: Session<Meta> = {\n proc: spawned.proc,\n meta: spawned.meta ?? connection.meta,\n channel,\n done,\n };\n held.session = session;\n held.release = options.onSession?.(session) ?? null;\n },\n options.streams,\n );\n } catch (error) {\n options.onError?.(error, connection);\n } finally {\n const session = held.session;\n if (held.end) live.delete(held.end);\n // What the starter installed goes away before the session is reported over, and a cleanup that\n // throws is a report: `done` settles either way, so a `stop()` waiting on it cannot hang.\n if (held.release) {\n try {\n await held.release();\n } catch (error) {\n options.onError?.(error, connection);\n }\n }\n if (session) options.onClosed?.(session);\n settle();\n }\n };\n\n // The loop: one accept at a time, and a session's life never holds the next connection back.\n const accepting = (async (): Promise<void> => {\n for (;;) {\n let connection: Connection<Meta>;\n try {\n connection = await listener.accept(stopping.signal);\n } catch {\n // Nothing more is coming: the listener was closed, or its medium is over.\n return;\n }\n if (stopping.signal.aborted) {\n // A connection admitted as the reactor stops is ended rather than served: it asked for a server\n // that is no longer taking any.\n await (connection.channel ?? connection.transport).close();\n return;\n }\n void serveOne(connection);\n }\n })();\n\n return {\n get live(): number {\n return live.size;\n },\n async stop(): Promise<void> {\n stopping.abort();\n await listener.close();\n // Every live session is ended, and the stop waits for them to be over: something that asks whether a\n // reactor is still serving gets its answer from here rather than from a race.\n const ending = [...live.keys()].map((end) => end());\n const over = [...live.values()];\n await Promise.all(ending);\n await Promise.all(over);\n await accepting;\n },\n };\n}\n\n/**\n * A listener with exactly one connection: what a caller serves on when the medium is already open for it,\n * as a spawner that hands back a channel is. The connection is taken once, a second `accept()` is a\n * mistake worth naming, and `close()` releases an accept that is still waiting for one.\n */\nexport function oneConnection<Meta = unknown>(\n spawner: Spawner,\n meta: Meta = undefined as Meta,\n): Listener<Meta> {\n let taken = false;\n let closed = false;\n let release: (() => void) | null = null;\n\n return {\n async accept(signal?: AbortSignal): Promise<Connection<Meta>> {\n if (taken) throw new Error(\"oneConnection: the connection has already been taken\");\n if (closed) throw new Error(\"oneConnection: closed\");\n taken = true;\n const channel = await Promise.race([\n spawner(),\n new Promise<never>((_resolve, reject) => {\n release = () => reject(new Error(\"oneConnection: closed before a connection arrived\"));\n signal?.addEventListener(\"abort\", release, { once: true });\n }),\n ]);\n return { channel, meta };\n },\n async close(): Promise<void> {\n closed = true;\n release?.();\n },\n };\n}\n\n/** The protocol step: the frame channel over a transport, and the `$proto` frame that opens it. */\nasync function protocolStep(\n transport: StringTransport,\n options: ReactorOptions<unknown>,\n): Promise<Channel> {\n const channel = json1Channel(transport);\n await channel.send({ $proto: VERSION });\n return withFrameHook(channel, options.onIncomingFrame);\n}\n\n/**\n * The frame hook, as the channel the serve gets: every decoded frame is offered to it, and one it claims\n * with `true` goes no further.\n */\nfunction withFrameHook(\n channel: Channel,\n hook: ReactorOptions<unknown>[\"onIncomingFrame\"],\n): Channel {\n if (!hook) return channel;\n return channelThrough(channel, (frame) => hook(frame) === true);\n}\n\n/**\n * One actor over one connection: the reactor with a listener that carries exactly one. A caller that\n * has a spawner and no loop of its own gets the same serving, the same reports and the same teardown a\n * listener gets. The promise settles when the serve is over, and rejects when the connection could not\n * be served at all — the two outcomes the seam has always had.\n */\nexport async function serveRemoteActor<\n Args,\n State,\n InMsg extends Message,\n OutMsg extends Message,\n R extends ReflectionOptions,\n>(\n actor: ActorDefinition<Args, State, InMsg, OutMsg, R>,\n spawner: Spawner,\n onSpawned?: (proc: ServedProcess<ActorDefinition<Args, State, InMsg, OutMsg, R>>) => void,\n streams?: StreamStoreOptions,\n): Promise<void> {\n // A medium that cannot be reached fails the caller's await rather than the loop's: the loop reads an\n // accept that ends as nothing more coming.\n const channel = await spawner();\n await new Promise<void>((resolve, reject) => {\n reactor(oneConnection(async () => channel), actor, {\n onSession: ({ proc }) => onSpawned?.(proc),\n onClosed: () => resolve(),\n onError: (error) => reject(error),\n streams,\n });\n });\n}\n","// ── the far end's own output ───────────────────────────────────────────────\n//\n// A program that prints says so in a stream it announces under a name — `stdout`, `stderr` — on the\n// connection it speaks on, and the reader takes it like any other stream. This is the layer between\n// such a stream and a sink: decode the octets and hand them on, or write them tagged to our own\n// stderr.\n//\n// Nothing here is a frame. A stream is the wire's own carrier for bytes, so the reader that wants\n// the output of something it spawned asks for the name and reads; there is nothing to strip off the\n// frame stream, and no second way for a program's words to reach this side.\n\nimport type { Stream } from \"./stream.js\";\n\n/** Where the far end's own output goes: the stream it came on, and the text it carried. */\nexport type OutputSink = (name: string, data: string) => void;\n\n/** Write the far end's output to our stderr, tagged with the name of the process that printed. */\nexport function stderrSink(pname = \"\"): OutputSink {\n const tag = pname ? `[${pname}] ` : \"\";\n return (name, data) => {\n const lead = name === \"stderr\" ? `${tag}err: ` : tag;\n for (const line of data.split(\"\\n\")) {\n if (line.length > 0) process.stderr.write(`${lead}${line}\\n`);\n }\n };\n}\n\n/**\n * Read a named stream into a sink, decoding the octets as text as they arrive.\n *\n * A stream that fails ends the pump quietly: the far end going away is the end of its output, not an\n * error to raise on this side.\n */\nexport function pumpOutput(stream: Stream, name: string, sink: OutputSink): void {\n const decoder = new TextDecoder();\n void (async () => {\n try {\n for await (const chunk of stream) sink(name, decoder.decode(chunk, { stream: true }));\n const tail = decoder.decode();\n if (tail.length > 0) sink(name, tail);\n } catch {\n /* the far end went: what it said is what arrived */\n }\n })();\n}\n","// ── Client side of the seam ────────────────────────────────────────────────\n//\n// remoteClient builds a posipaki actor that talks to a remote server through a\n// frame Channel produced by a spawner. It knows only the frame vocabulary\n// (channel.ts) — no protocol, no transport, no spawner. The spawner has\n// already done the $proto handshake.\n\nimport { defineActor } from \"../define-actor.js\";\nimport { isProcess } from \"../process.async.js\";\nimport { stopPropagation } from \"../hooks.js\";\nimport type { HookResult } from \"../hooks.js\";\nimport type { ActorDefinition, HandlerOptions, MethodOptions, ReflectionOptions } from \"../actor-types.js\";\nimport type { Message } from \"../types.js\";\nimport type { Channel } from \"./channel.js\";\nimport { pumpOutput, stderrSink, type OutputSink } from \"./output.js\";\nimport {\n IdSpace,\n ProcessTable,\n isRemoteProcess,\n type ProcessHandle,\n type ProcessRef,\n} from \"./process-ref.js\";\nimport { ProcessStreams } from \"./process-streams.js\";\nimport { RemoteProcess, type FrameSink } from \"./remote-process.js\";\nimport { makeSender } from \"./sender.js\";\nimport {\n REFLECT_METHODS,\n asReflectionCall,\n badReason,\n decodeFrame,\n encodeFrame,\n errorReason,\n frameTo,\n isExit,\n isMsg,\n isPause,\n isRelease,\n isResume,\n isStop,\n isReflectionMethods,\n isState,\n isTune,\n tuneFrame,\n} from \"./channel.js\";\nimport { CallSide, answerCall } from \"./call-side.js\";\nimport { StreamStore } from \"./stream.js\";\n\nexport type ClientSpawner<Args> = (args: Args) => Promise<Channel>;\n\n/** What the proxy knows about itself when its connection is handed over: enough to name itself. */\nexport interface ClientContext {\n /** The full name of the proxy process, which is the name the far side serves it under. */\n readonly pname: string;\n}\n\n/**\n * What a caller may install on the connection a proxy opens. `onChannel` is called once the channel\n * is up and before the first frame is sent or read, so a reader put there misses nothing; what it\n * returns is called when the proxy is over, before the channel is closed.\n */\nexport interface RemoteClientOptions {\n onChannel?(channel: Channel, ctx: ClientContext): void | (() => void | Promise<void>);\n /**\n * Where what the far end prints goes. A process that prints announces its `stdout` and `stderr`\n * as streams on the connection; this is the sink they are read into, and the first two names are\n * the only ones taken. Defaults to our own stderr, tagged with the process's name.\n */\n onOutput?: OutputSink;\n}\n\n\n/**\n * Why a proxy ends when the wire under it goes.\n *\n * The far side is *unreachable*, which is not the same as ended: the handles that came across are\n * still here and still readable, and what the far process left behind is still what it left behind.\n * But nothing it says can arrive and nothing here can reach it, and that is news of its own — so the\n * proxy ends with this reason rather than sitting there silent. Whoever forked the proxy hears it\n * where it hears everything else about a child, in `onChildExit`.\n */\nexport const CHANNEL_LOST = \"channel-lost\";\n\nexport function remoteClient<\n Args,\n State,\n InMsg extends Message,\n OutMsg extends Message,\n Methods extends MethodOptions = MethodOptions,\n Handlers extends HandlerOptions<InMsg> = HandlerOptions<InMsg>,\n R extends ReflectionOptions = ReflectionOptions,\n>(\n name: string,\n spawner: ClientSpawner<Args>,\n options: RemoteClientOptions = {},\n): ActorDefinition<Args, State, InMsg, OutMsg, R> {\n const proxyDef = defineActor<\n Args,\n {\n public: State;\n private: {\n channel: Channel;\n farRoot: RemoteProcess<InMsg, OutMsg>;\n exitPromise: Promise<{ code: number | null; state: State }>;\n release: (() => void | Promise<void>) | null;\n };\n },\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n R\n >({\n name,\n handlers: {} as unknown as Handlers,\n async setup(args: Args) {\n // This side's own end of the connection is the root, and id 0 is how both\n // sides name it: the far actor on one end, this proxy on the other. The\n // table takes the odd ids for the processes this side holds — the far side\n // takes the even ones — so an id says on its own which side holds it.\n // A process this side hands over is numbered by the table, and from then on\n // the far side is told what it says: the stream follows the frame that\n // carried the reference.\n // One id space for everything this side numbers — the process table and the stream store\n // alike — so a number on the connection names one thing and the parity says which side made it.\n const ids = new IdSpace(\"odd\");\n const table = new ProcessTable(\"odd\", (proc, id) => streams.crossed(proc, id), ids);\n const root = this.ctx;\n table.bindRoot(root);\n const channel = await spawner(args);\n // Its byte streams, on the same parity split: a stream crosses as itself, and a blob as a stream\n // over the same octets with its size and name said first.\n const byteStreams = new StreamStore(channel, \"odd\", { ids });\n // The connection this proxy holds is the process's own fact, so whatever the process\n // does with the frames asks the same place the remote layer does.\n this.ctx.connection = channel;\n // Whoever wants the connection gets it here, before the first frame is sent or read: a reader\n // installed later would have missed whatever the far side said first. What it answers with is\n // this side's to clean up when the proxy is over, not the library's to guess at.\n const release = options.onChannel?.(channel, { pname: this.ctx.pname }) ?? null;\n // What this side calls the process it serves: the full name, not the short one the\n // definition was written with. A process is called here what it is called on the side\n // that forked it, and the far side spells its own subtree off whatever it is told, so a\n // short name would be a second spelling of one process — and the tree would show both.\n const fromName = this.ctx.pname;\n\n // What the far end prints arrives as streams it announced under a name; the two output names\n // are read into the caller's sink, and any other name is the application's to ask for.\n const output = options.onOutput ?? stderrSink(fromName);\n byteStreams.onNamed((name, stream) => {\n if (name === \"stdout\" || name === \"stderr\") pumpOutput(stream, name, output);\n });\n // And the process above it, which is who a message to the served root comes from: the\n // far side is told the same thing a child here is told about its parent.\n const parentName = this.ctx.parentName ?? this.ctx.pname;\n // Everything is in place to speak: the sink writes to the wire, and what the\n // table numbers crosses through it. The sink is reached by a call rather\n // than handed over, because what it does is flush these streams.\n const streams = new ProcessStreams((frame, to) => sendTo(frame, to), table.rootId());\n\n /** Put an encoded frame on the wire, and then say what it numbered. A frame that\n * carried a reference has to be out first, or the far side hears about a process\n * it cannot name yet. */\n const write = (frame: Record<string, unknown>): Promise<void> =>\n Promise.resolve(channel.send(frame)).then(() => streams.flush());\n\n /** Set once the wire is going: after that, a frame that cannot be delivered has nowhere to\n * go by construction, and a stack for it is noise rather than news (see the sink below). */\n let pvtWindDown = false;\n\n /** Every frame leaves this way: the processes in it become references, and\n * what the frame is addressed to becomes the id the far side knows. */\n const sendTo: FrameSink = (frame, to) => {\n void write(encodeFrame(frame, table, to, byteStreams)).catch((error: unknown) => {\n // A live wire reports a lost frame loudly; a wire that is ending reports nothing, because\n // its last words are exactly what cannot be delivered any more (see server.ts).\n if (pvtWindDown) return;\n console.error(\"Error sending out the frame\", error);\n });\n };\n sendTo(\n {\n $init: {\n ...(args as unknown as Record<string, unknown>),\n // Under what name the far side serves is this side's to state: it is serving the\n // process this proxy stands in for, which is the one named here.\n rootName: fromName,\n parentName,\n parentIdName: parentName,\n },\n },\n table.farRootId(),\n );\n\n let currentState: Record<string, unknown> = {};\n\n // ── the call side ──────────────────────────────────────────────────\n // This side both makes calls and answers them, and so does the other end of\n // every connection: what a call is, and how an answer finds the one waiting\n // for it, is written once in call-side.ts.\n const calls = new CallSide(write, table, byteStreams);\n\n /**\n * The handle for a reference that arrived. A process handed over twice is one\n * process, so a reference that names one this side already knows gives back the\n * handle it gave last time, and one that names a process of this side's own —\n * handed back to its owner — gives back that process.\n *\n * The roots are numbered apart, so the numbers say what belongs to whom: 1 is this\n * side's own end, and 0 is the far side's root, which is a handle like any of the\n * processes they hold.\n */\n const handleFor = (ref: ProcessRef): ProcessHandle => {\n const held = table.processFor(ref.id);\n if (held) return held;\n const known = table.farHandleFor(ref.id);\n if (isRemoteProcess(known)) return known;\n const handle = new RemoteProcess(ref, sendTo, fromName, (id) => table.release(id));\n table.bindFar(ref.id, handle);\n return handle;\n };\n\n /**\n * The far side's root, which is what this proxy stands in for. It is bound here\n * like any other reference the far side sends: what it holds, what it says, when\n * it is over and what it can answer reach it as they reach any handle.\n */\n const farRoot = new RemoteProcess<InMsg, OutMsg>(\n { id: table.farRootId(), pname: fromName },\n sendTo,\n fromName,\n (id) => table.release(id),\n );\n table.bindFar(table.farRootId(), farRoot);\n // The proxy is this side's stand-in for that process, so it is the one thing here\n // that keeps it: the state it mirrors and the messages it passes on are heard because\n // this handle is held, and it is let go of when the connection is.\n farRoot.holdRef();\n\n // Setup is done when the far side has said what it holds; until then the\n // one handler below is what takes everything that arrives, so nothing\n // falls between two of them.\n let started: (() => void) | null = null;\n const start = new Promise<void>((resolve) => {\n started = resolve;\n });\n\n // All three in one asking, since this proxy stands in for the far root: what it\n // holds is this proxy's state, what it says is what this proxy says, and its end\n // is the end of the connection. A process says nothing until something asks, and\n // the root is no exception.\n farRoot.tune([\"message\", \"state\", \"exit\"]);\n farRoot.subscribe(\"state\", () => {\n // One object, updated the way the far side publishes it: the proxy's state is\n // the far root's, and a caller here reads it as `proc.state`.\n Object.assign(currentState, farRoot.state ?? {});\n root.notify();\n started?.();\n started = null;\n });\n farRoot.subscribe(\"message\", (msg) => {\n void this.emit(msg as OutMsg);\n });\n const exitPromise: Promise<{ code: number | null; state: State }> = farRoot.wait().then(\n (exit) => ({ code: exit.code, state: exit.state as State }),\n // The wire went before the far root did: what is known here is that it is over,\n // and the state last heard is the last word there is.\n () => ({ code: null, state: currentState as State }),\n );\n\n /**\n * The wire is over, whoever ended it: the far side stopped talking, or stopped making sense.\n * What was in flight fails, handles disconnect, nothing more is said about the processes of\n * this side's own, and the proxy ends with CHANNEL_LOST — a proxy that stayed up would be one\n * whose parent still believes the far side is listening, which is exactly the belief a display\n * panel that went dark punishes.\n *\n * Said once: a wire can go in more than one way at once, and it only goes once.\n */\n let wireEnded = false;\n const wireGone = (): void => {\n if (wireEnded) return;\n wireEnded = true;\n // A call that was in flight when the wire went away has no answer coming; it fails\n // here rather than hanging forever.\n calls.rejectAll();\n // A stream read still in flight has no answer coming either.\n byteStreams.close();\n // Handles live on this connection: with it gone there is nothing to reach, and\n // nothing to wait for either.\n for (const held of table.handles()) {\n if (isRemoteProcess(held)) held.disconnect();\n }\n // And nothing more is said about the processes of this side's own that were handed\n // over: there is no one left to say it to.\n streams.stopAll();\n pvtWindDown = true;\n this.exit(CHANNEL_LOST);\n };\n\n channel.onMessage((raw) => {\n // A frame about the wire ends the wire: what the far side says it could not read, and what\n // it says when the connection is over, are the same news here. A frame that could not be\n // *read* leaves nothing after it trustworthy — a wire that has lost its framing can still\n // deliver something, and what it delivers is not the far side's meaning — so this is where\n // the connection ends. A frame that reads fine and is not understood is not this, and is\n // answered about itself rather than by breaking the connection.\n const wireProblem = badReason(raw) ?? errorReason(raw);\n if (wireProblem !== null) {\n void channel.close();\n wireGone();\n return;\n }\n const frame = decodeFrame(raw, handleFor, byteStreams);\n // An answer is about the call waiting for it and not about a process: it names\n // the seq, and is settled before anything is looked up.\n if (calls.settle(frame)) return;\n const to = frameTo(frame);\n if (to === null) return;\n // A frame answers one of two questions. News about a process the far side holds\n // lands on the handle for it: what it holds, what it says, that it is over, what\n // it can answer. An ask of a process this side holds goes to wherever that\n // process lives: a message, control, a call, a tune.\n const news = table.farHandleFor(to);\n const mine = table.processFor(to);\n if (isRelease(frame)) {\n // A process of this side's own, let go of over there: nothing more is said\n // about it, and the id is no longer this connection's. The process itself\n // runs on. Neither root is let go of, so the table refuses both.\n if (mine !== undefined) {\n streams.stop(to);\n table.release(to);\n }\n return;\n }\n if (isReflectionMethods(frame)) {\n // What the far side holds can answer, and how this side asks it: what was\n // announced is the whole surface, so a name never announced is never called\n // here either. The far root's names go on this proxy's own surface as well,\n // since the proxy is the process a caller here holds.\n if (isRemoteProcess(news)) {\n news.receiveMethods(frame[REFLECT_METHODS], (method, callArgs) =>\n calls.call(method, callArgs, to),\n );\n if (to === table.farRootId()) {\n calls.install(\n this.reflection as unknown as Record<string, unknown>,\n frame[REFLECT_METHODS],\n table.farRootId(),\n );\n }\n }\n return;\n }\n if (isState(frame)) {\n // A process the far side holds, saying what it holds: news for whoever\n // subscribed to the handle.\n if (isRemoteProcess(news)) news.receiveState(frame.$state);\n return;\n }\n if (isExit(frame)) {\n // A process the far side holds, gone: nothing more will be said about it.\n if (isRemoteProcess(news)) news.receiveExit(frame.$exit);\n return;\n }\n if (isMsg(frame)) {\n // A message naming a process this side holds goes into it, the proxy's own\n // root included, and the wire says who sent it by name alone. One about a\n // process the far side holds is that process talking, and goes to whoever\n // subscribed to the handle.\n if (isProcess(mine)) {\n mine.send(frame.$msg.body as InMsg, makeSender(frame.$msg.fromName, null, null));\n } else if (isRemoteProcess(news)) {\n news.receiveMessage(frame.$msg.body as OutMsg, frame.$msg.fromName);\n }\n return;\n }\n if (isTune(frame)) {\n // How much the far side hears about a process of this side's own is its to\n // ask, and this is where the asking lands.\n if (mine !== undefined) {\n const kinds = tuneFrame(frame);\n if (kinds !== null) streams.tune(to, kinds);\n }\n return;\n }\n if (isStop(frame) || isPause(frame) || isResume(frame)) {\n // Control, addressed to the process it is about, and acted on by whoever holds\n // it, which is this side. Its own root is one of those. A handle has nothing\n // here to act on.\n if (isProcess(mine)) {\n if (isStop(frame)) void mine.stop({ from: makeSender(fromName, null, null) });\n else if (isPause(frame)) mine.pause();\n else mine.resume();\n }\n return;\n }\n // A call into a process of this side's own, made from over there: the method is\n // this side's to run, and the answer goes back by name and seq.\n const call = asReflectionCall(frame);\n if (call) void answerCall(call, mine, write, table, byteStreams);\n });\n // A wire that goes before the far root does leaves nothing to wait for: the handles are gone,\n // and the far root's end is the connection's end, which is what `wait()` on it rejects about.\n channel.onClose(() => wireGone());\n\n await start;\n\n return {\n public: currentState as State,\n private: { channel, farRoot, exitPromise, release },\n };\n\n },\n async onMessage(msg: InMsg): Promise<HookResult> {\n const { farRoot } = this.state.private;\n // A message this side sends is for the root: that is the process the proxy stands\n // for, and it is sent the way any handle sends to a process of the far side's.\n if (farRoot.isConnected()) farRoot.send(msg);\n return stopPropagation();\n },\n async onStopRequested() {\n const { channel, farRoot, exitPromise } = this.state.private;\n if (channel) {\n // Asking the far root to stop is asking a process, not sending it a message:\n // the control frame its holder acts on, the one every other handle uses. Worth\n // asking only while there is something to ask of it — an end that has come, or\n // a wire that has gone, leaves nothing to ask and nothing to wait for.\n if (farRoot.isConnected() && !farRoot.hasEnded()) {\n void farRoot.stop().catch(() => undefined);\n }\n await exitPromise;\n }\n this.agreeToStop();\n },\n async afterEnd() {\n const { channel, release } = this.state.private;\n if (release) {\n // The wire closes whatever a cleanup does: one that throws is reported, not a reason to\n // leave a connection open behind a proxy that is over.\n try {\n await release();\n } catch (error) {\n console.error(\"Error releasing the connection\", error);\n }\n }\n if (channel) {\n await channel.close();\n }\n },\n });\n\n return proxyDef as unknown as ActorDefinition<Args, State, InMsg, OutMsg, R>;\n}\n","// ── bytes on a stream, and the lines they carry ─────────────────────────────\n//\n// A line transport's reader, and the number that made it a file of its own: 13.3 MB of\n// 87 KB frames read through `node:readline` costs 4.0 s on this box, and through a buffer\n// and an `indexOf` it costs 76 ms. The difference is not the parsing — it is that a\n// frame the size of a file chunk is the normal case here and readline is built for the\n// other one.\n//\n// Splitting on the byte 0x0a is safe for UTF-8: a continuation byte is never 0x0a, so a\n// line boundary cannot fall inside a character, and a chunk boundary inside one is\n// carried by the accumulator until the rest of it arrives.\n//\n// CRLF is read as a line ending rather than as part of the frame, which is what the line\n// reader it replaces did; the frames this library writes end in \"\\n\" alone.\n//\n// ── a line may carry octets after it ───────────────────────────────────────\n//\n// Not every frame on the wire is text: a chunk of a stream is a JSON head, the raw\n// octets it announces, and a JSON tail. So a line is also a question — how many octets\n// follow — and the answer says where the next line starts. `PartReader` is that state\n// machine, over bytes as they arrive however the carrier splits them; a carrier that\n// moves whole messages (a websocket) feeds it one message at a time and the machine\n// cannot tell the difference.\n\nimport type { Readable } from \"node:stream\";\n\n/** A reader, and the one way to stop it. */\nexport interface LineReader {\n /** Stop reading and drop what is buffered. Idempotent. */\n stop(): void;\n}\n\nconst NL = 0x0a;\nconst CR = 0x0d;\n\nfunction withoutCr(line: Buffer<ArrayBufferLike>): Buffer<ArrayBufferLike> {\n return line.length > 0 && line[line.length - 1] === CR ? line.subarray(0, line.length - 1) : line;\n}\n\n/**\n * The wire as a sequence of lines, where a line may announce raw octets to follow it.\n *\n * `onLine` gets a line and answers how many octets come next — none, for every frame but\n * one that carries them. Those octets reach `onBytes` whole, however many reads they\n * arrived in, and the reader goes back to looking for a newline.\n */\nexport class PartReader {\n private acc: Buffer<ArrayBufferLike> = Buffer.alloc(0);\n /** How many octets the octet run still needs, or 0 while looking for a line. */\n private want = 0;\n private done = false;\n\n constructor(\n private readonly onLine: (line: string) => number | void,\n private readonly onBytes: (bytes: Uint8Array) => void,\n ) {}\n\n feed(chunk: Uint8Array): void {\n if (this.done) return;\n this.acc = this.acc.length === 0 ? Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength) : Buffer.concat([this.acc, chunk]);\n this.pump();\n }\n\n /** The stream is over: whatever is left of a line is still a line, as `readline` said. */\n end(): void {\n if (this.done) return;\n const rest = this.acc;\n this.acc = Buffer.alloc(0);\n this.done = true;\n if (rest.length > 0 && this.want === 0) this.onLine(withoutCr(rest).toString(\"utf8\"));\n }\n\n private pump(): void {\n for (;;) {\n if (this.want > 0) {\n if (this.acc.length < this.want) return;\n const bytes = this.acc.subarray(0, this.want);\n this.acc = this.acc.subarray(this.want);\n this.want = 0;\n this.onBytes(bytes);\n continue;\n }\n const at = this.acc.indexOf(NL);\n if (at < 0) return;\n const line = this.acc.subarray(0, at);\n this.acc = this.acc.subarray(at + 1);\n const asked = this.onLine(withoutCr(line).toString(\"utf8\"));\n if (typeof asked === \"number\") {\n // A run of no octets is still a run: the line said what follows, and it follows as nothing.\n if (asked > 0) this.want = asked;\n else this.onBytes(new Uint8Array(0));\n }\n }\n }\n}\n\n/**\n * Read `stream` as lines, with the octets a line announces.\n *\n * `onEnd` is called once when the stream is over, after the last line: a stream that\n * ends without its final newline still gives up its last line, because that is what the\n * peer meant to say.\n */\nexport function readParts(\n stream: Readable,\n onLine: (line: string) => number | void,\n onBytes: (bytes: Uint8Array) => void,\n onEnd?: () => void,\n): LineReader {\n const reader = new PartReader(onLine, onBytes);\n return readChunks(\n stream,\n (chunk) => reader.feed(chunk),\n () => {\n reader.end();\n onEnd?.();\n },\n );\n}\n\n/** Read `stream` a line at a time, with no octets: the plain line carrier. */\nexport function readLines(stream: Readable, onLine: (line: string) => void, onEnd?: () => void): LineReader {\n return readParts(\n stream,\n (line) => {\n onLine(line);\n },\n () => {\n // A carrier that never announces octets never delivers any; a peer that sends them\n // anyway is talking past the protocol, and the bytes are dropped rather than guessed at.\n },\n onEnd,\n );\n}\n\n/** The bytes a stream carries, before anything is made of them. */\nexport function readChunks(stream: Readable, onChunk: (chunk: Uint8Array) => void, onEnd?: () => void): LineReader {\n let stopped = false;\n\n const onData = (chunk: Buffer | string): void => {\n if (stopped) return;\n onChunk(typeof chunk === \"string\" ? Buffer.from(chunk, \"utf8\") : chunk);\n };\n\n const finish = (): void => {\n if (stopped) return;\n stopped = true;\n stream.off(\"data\", onData);\n onEnd?.();\n };\n\n stream.on(\"data\", onData);\n // A pipe finishes in more than one way. `end` is a peer that closes politely; one that vanishes —\n // a socket destroyed, a write that fails, a process killed — reports `close` or `error` and never\n // an end at all, and a reader that waits for the end alone hangs on a connection that is gone.\n stream.once(\"end\", finish);\n stream.once(\"close\", finish);\n stream.once(\"error\", finish);\n\n return {\n stop(): void {\n stopped = true;\n stream.off(\"data\", onData);\n stream.off(\"end\", finish);\n stream.off(\"close\", finish);\n stream.off(\"error\", finish);\n },\n };\n}\n","/* eslint-disable unicorn/prefer-add-event-listener */\n// ── WebSocket transport ─────────────────────────────────────────────────────────\n//\n// Message-boundary transport over a WebSocket. The socket's native framing means\n// one `send` is one message — there is no delimiter to add or strip — so a line\n// travels as a text message and the octets a line announces travel as a binary one.\n// Both ends feed what they receive through the same reader a stream carrier uses,\n// which is why a websocket and a fifo are the same wire above this point.\n\nimport { PartReader } from \"../lines.js\";\nimport type { StringTransport } from \"../channel.js\";\n\n/**\n * The subset of a WebSocket the transport needs. The WHATWG client WebSocket\n * (Node, Bun, browsers) satisfies this directly; a Bun server socket is adapted\n * by the consumer (see spawners/ws-server.ts).\n */\nexport interface WebSocketLike {\n send(data: string | Uint8Array): void;\n close(code?: number, reason?: string): void;\n readonly readyState: number;\n onmessage: ((event: { data: unknown }) => void) | null;\n onclose: (() => void) | null;\n}\n\n/** WHATWG WebSocket readyState: OPEN. */\nexport const WS_OPEN = 1;\n\nconst encoder = new TextEncoder();\n\n/** The octets a message carried, whatever the socket hands over. */\nfunction octetsOf(data: unknown): Uint8Array | null {\n if (typeof data === \"string\") return encoder.encode(data);\n if (data instanceof Uint8Array) return data;\n if (data instanceof ArrayBuffer) return new Uint8Array(data);\n if (ArrayBuffer.isView(data)) return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n return null;\n}\n\nexport class WebSocketTransport implements StringTransport {\n private ws: WebSocketLike;\n private pvtOnMessage: ((frame: string) => number | void) | null = null;\n private pvtOnBytes: ((bytes: Uint8Array) => void) | null = null;\n private pvtOnClose: (() => void) | null = null;\n private closed = false;\n private readonly reader: PartReader;\n\n constructor(ws: WebSocketLike) {\n this.ws = ws;\n this.reader = new PartReader(\n (line) => (this.closed ? undefined : this.pvtOnMessage?.(line)),\n (bytes) => {\n if (!this.closed) this.pvtOnBytes?.(bytes);\n },\n );\n ws.onmessage = (event) => {\n if (this.closed) return;\n // A text message is a line, and the reader wants it ended the way a line ends on a\n // stream; a binary message is the octets a line announced.\n if (typeof event.data === \"string\") this.reader.feed(encoder.encode(`${event.data}\\n`));\n else {\n const bytes = octetsOf(event.data);\n if (bytes) this.reader.feed(bytes);\n }\n };\n ws.onclose = () => {\n this.closed = true;\n this.reader.end();\n this.pvtOnClose?.();\n };\n }\n\n get canSend(): boolean {\n return !this.closed && this.ws.readyState === WS_OPEN;\n }\n\n onMessage(handler: (frame: string) => number | void): void {\n if (this.closed) throw new Error(\"WebSocketTransport: closed\");\n if (this.pvtOnMessage !== null) {\n throw new Error(\"WebSocketTransport: handler already set — call removeHandler() first\");\n }\n this.pvtOnMessage = handler;\n }\n\n onBytes(handler: (bytes: Uint8Array) => void): void {\n if (this.closed) throw new Error(\"WebSocketTransport: closed\");\n this.pvtOnBytes = handler;\n }\n\n removeHandler(): ((frame: string) => number | void) | null {\n const prev = this.pvtOnMessage;\n this.pvtOnMessage = null;\n return prev;\n }\n\n onClose(handler: () => void): void {\n this.pvtOnClose = handler;\n }\n\n get hasHandler(): boolean {\n return this.pvtOnMessage !== null;\n }\n\n async send(frame: string): Promise<void> {\n if (this.closed) throw new Error(\"WebSocketTransport: closed\");\n if (this.ws.readyState !== WS_OPEN) throw new Error(\"WebSocketTransport: not open\");\n this.ws.send(frame);\n }\n\n async sendBytes(bytes: Uint8Array): Promise<void> {\n if (this.closed) throw new Error(\"WebSocketTransport: closed\");\n if (this.ws.readyState !== WS_OPEN) throw new Error(\"WebSocketTransport: not open\");\n this.ws.send(bytes);\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n try {\n this.ws.close();\n } catch {\n // already closing / closed — ignore\n }\n }\n}\n"],"mappings":"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"}