@ai-ecoverse/slicc-kernel 1.66.0 → 1.66.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.
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/cdp/port.ts", "../src/client/dial-stream.ts", "../src/client/loopback-fetch.ts", "../src/kernel/net/loopback-names.ts", "../src/kernel/net/routes.ts", "../src/kernel/net/uplink.ts", "../src/body-idle.ts", "../src/kernel/net/ws-queue.ts", "../src/websocket-transport.ts", "../src/transport.ts", "../src/kernel/net/remote-transport.ts", "../src/client/protocol.ts", "../src/client/attach.ts", "../src/local-proxy-transport.ts", "../src/mount/driver.ts", "../src/mount/hostfs.ts", "../src/index.ts"],
4
- "sourcesContent": ["import type { CdpConnection, CdpHook, CdpRequest } from './types.ts';\n\nexport interface CdpPortLike {\n postMessage(message: unknown): void;\n addEventListener(type: 'message', handler: (event: MessageEvent) => void): void;\n start?(): void;\n close(): void;\n}\n\nexport type CdpWire = { open: true } | { error: string } | { m: string } | { close: string | null };\n\nexport interface CdpOpen {\n cdpOpen: CdpRequest & { registration?: number };\n port: CdpPortLike;\n}\n\nexport function serveCdpPort(\n port: CdpPortLike,\n hook: CdpHook,\n request: CdpRequest,\n onDone?: () => void\n): () => void {\n let conn: CdpConnection | undefined;\n let done = false;\n const end = () => {\n done = true;\n port.close();\n onDone?.();\n };\n const finish = (reason: string | null) => {\n if (done) return;\n port.postMessage({ close: reason });\n end();\n };\n port.addEventListener('message', ({ data }: MessageEvent<{ m?: string; close?: true }>) => {\n if (data.m !== undefined) conn?.send(data.m);\n else if (data.close && !done) {\n end();\n conn?.close();\n }\n });\n port.start?.();\n new Promise<CdpConnection>((resolve) => resolve(hook(request))).then(\n (opened) => {\n conn = opened;\n if (done) return opened.close();\n opened.onmessage = (m) => {\n if (!done) port.postMessage({ m });\n };\n opened.onclose = (reason) => finish(reason ?? null);\n port.postMessage({ open: true });\n },\n (e: unknown) => {\n if (done) return;\n port.postMessage({ error: e instanceof Error ? e.message : String(e) });\n end();\n }\n );\n return () => {\n if (done) return;\n conn?.close();\n finish('the CDP host is gone');\n };\n}\n\nexport function portCdpHook(\n ask: (request: CdpRequest, port: CdpPortLike) => void,\n gone?: Promise<unknown>\n): CdpHook {\n return (request) =>\n new Promise((resolve, reject) => {\n const { port1, port2 } = new MessageChannel();\n let closed = false;\n const conn: CdpConnection = {\n send: (m) => {\n if (!closed) port1.postMessage({ m });\n },\n onmessage: null,\n onclose: null,\n close: () => {\n if (closed) return;\n closed = true;\n port1.postMessage({ close: true });\n port1.close();\n },\n };\n port1.addEventListener('message', ({ data }: MessageEvent<CdpWire>) => {\n if ('m' in data) conn.onmessage?.(data.m);\n else if ('open' in data) resolve(conn);\n else if ('error' in data) {\n closed = true;\n port1.close();\n reject(new Error(data.error));\n } else if (!closed) {\n closed = true;\n port1.close();\n conn.onclose?.(data.close ?? undefined);\n }\n });\n port1.start();\n void gone?.then(() => {\n if (closed) return;\n closed = true;\n port1.close();\n reject(new Error('the CDP host is gone'));\n conn.onclose?.('the CDP host is gone');\n });\n ask(request, port2 as unknown as CdpPortLike);\n });\n}\n", "export interface DialledSocket {\n readable: ReadableStream<Uint8Array>;\n writable: WritableStream<Uint8Array>;\n close(): void;\n}\n\nexport interface DialOptions {\n port: number;\n host?: string;\n}\n\ninterface StreamPort {\n postMessage(message: unknown, transfer?: Transferable[]): void;\n addEventListener(type: 'message', handler: (event: MessageEvent) => void): void;\n start?(): void;\n close(): void;\n}\n\ntype DialMessage = Uint8Array | { end: true } | { ack: true } | { error: string };\n\nexport interface DialHandle extends DialledSocket {\n fail(error: Error): void;\n}\n\nexport function errorWithCode(message: string): Error & { code?: string } {\n const code = /^E[A-Z]+/.exec(message)?.[0];\n return Object.assign(new Error(message), code ? { code } : {});\n}\n\nexport function dialStream(port: StreamPort, onClose?: () => void): DialHandle {\n let closed = false;\n let reader: ReadableStreamDefaultController<Uint8Array> | undefined;\n const acks: Array<{ resolve: () => void; reject: (error: Error) => void }> = [];\n const readable = new ReadableStream<Uint8Array>({\n start(controller) {\n reader = controller;\n },\n pull() {\n if (!closed) port.postMessage({ more: true });\n },\n cancel() {\n reader = undefined;\n close();\n },\n });\n const finish = (fail?: Error) => {\n const controller = reader;\n reader = undefined;\n for (const ack of acks.splice(0)) {\n if (fail) ack.reject(fail);\n else ack.resolve();\n }\n if (!controller) return;\n if (fail) controller.error(fail);\n else controller.close();\n };\n function shut(): void {\n if (closed) return;\n closed = true;\n port.close();\n onClose?.();\n }\n function close(): void {\n if (!closed) port.postMessage({ close: true });\n shut();\n finish();\n }\n port.addEventListener('message', ({ data }: MessageEvent<DialMessage>) => {\n if (data instanceof Uint8Array) reader?.enqueue(data);\n else if ('ack' in data) acks.shift()?.resolve();\n else if ('end' in data) finish();\n else finish(errorWithCode(data.error));\n });\n port.start?.();\n const writable = new WritableStream<Uint8Array>({\n write(chunk) {\n if (closed) throw errorWithCode('EPIPE: the connection is closed');\n const copy = chunk.slice();\n const acked = new Promise<void>((resolve, reject) => acks.push({ resolve, reject }));\n port.postMessage(copy, [copy.buffer]);\n return acked;\n },\n close() {\n if (!closed) port.postMessage({ end: true });\n },\n abort() {\n close();\n },\n });\n const fail = (error: Error) => {\n shut();\n finish(error);\n };\n return { readable, writable, close, fail };\n}\n", "import { type DialledSocket, type DialOptions, errorWithCode } from './dial-stream.ts';\n\nexport interface LoopbackFetchOptions extends DialOptions {\n signal?: AbortSignal;\n}\n\nconst OWN_HEADERS = new Set(['host', 'connection', 'content-length', 'transfer-encoding']);\nconst encoder = new TextEncoder();\nconst latin1 = new TextDecoder('latin1');\n\nclass ByteSource {\n private buffered = new Uint8Array(0);\n private readonly reader: ReadableStreamDefaultReader<Uint8Array>;\n\n constructor(reader: ReadableStreamDefaultReader<Uint8Array>) {\n this.reader = reader;\n }\n\n private async more(): Promise<boolean> {\n const { done, value } = await this.reader.read();\n if (done) return false;\n const joined = new Uint8Array(this.buffered.length + value.length);\n joined.set(this.buffered);\n joined.set(value, this.buffered.length);\n this.buffered = joined;\n return true;\n }\n\n async until(marker: string): Promise<Uint8Array | undefined> {\n const needle = encoder.encode(marker);\n for (;;) {\n const at = indexOf(this.buffered, needle);\n if (at >= 0) return this.take(at + needle.length);\n if (!(await this.more())) return undefined;\n }\n }\n\n async some(max: number): Promise<Uint8Array | undefined> {\n if (this.buffered.length === 0 && !(await this.more())) return undefined;\n return this.take(Math.min(max, this.buffered.length));\n }\n\n async exactly(count: number): Promise<Uint8Array | undefined> {\n while (this.buffered.length < count) if (!(await this.more())) return undefined;\n return this.take(count);\n }\n\n private take(count: number): Uint8Array {\n const out = this.buffered.slice(0, count);\n this.buffered = this.buffered.slice(count);\n return out;\n }\n}\n\nfunction indexOf(haystack: Uint8Array, needle: Uint8Array): number {\n outer: for (let i = 0; i + needle.length <= haystack.length; i++) {\n for (let j = 0; j < needle.length; j++) if (haystack[i + j] !== needle[j]) continue outer;\n return i;\n }\n return -1;\n}\n\ninterface ResponseHead {\n status: number;\n statusText: string;\n headers: Array<[string, string]>;\n}\n\nfunction parseHead(bytes: Uint8Array): ResponseHead {\n const [statusLine = '', ...lines] = latin1.decode(bytes).split('\\r\\n');\n const match = /^HTTP\\/1\\.[01] (\\d{3})(?: (.*))?$/.exec(statusLine);\n if (!match) throw errorWithCode(`EPROTO: not an HTTP/1.x response: ${statusLine.slice(0, 80)}`);\n const headers: Array<[string, string]> = [];\n for (const line of lines) {\n const colon = line.indexOf(':');\n if (colon > 0) headers.push([line.slice(0, colon).trim(), line.slice(colon + 1).trim()]);\n }\n return { status: Number(match[1]), statusText: match[2] ?? '', headers };\n}\n\nfunction header(head: ResponseHead, name: string): string | undefined {\n return head.headers.find(([key]) => key.toLowerCase() === name)?.[1];\n}\n\nasync function* chunked(source: ByteSource): AsyncGenerator<Uint8Array> {\n for (;;) {\n const line = await source.until('\\r\\n');\n if (!line) throw errorWithCode('EPROTO: the chunked body ended early');\n const size = Number.parseInt(latin1.decode(line).trim().split(';')[0] ?? '', 16);\n if (!Number.isFinite(size)) throw errorWithCode('EPROTO: a malformed chunk size');\n if (size === 0) return;\n const data = await source.exactly(size);\n if (!data || !(await source.exactly(2))) throw errorWithCode('EPROTO: a chunk ended early');\n yield data;\n }\n}\n\nasync function* counted(source: ByteSource, length: number): AsyncGenerator<Uint8Array> {\n let left = length;\n while (left > 0) {\n const data = await source.some(left);\n if (!data) throw errorWithCode('EPROTO: the body ended early');\n left -= data.length;\n yield data;\n }\n}\n\nasync function* untilClose(source: ByteSource): AsyncGenerator<Uint8Array> {\n for (let data = await source.some(65536); data; data = await source.some(65536)) yield data;\n}\n\nfunction bodyOf(source: ByteSource, head: ResponseHead, method: string) {\n if (method === 'HEAD' || head.status === 204 || head.status === 304) return undefined;\n if (header(head, 'transfer-encoding')?.toLowerCase().includes('chunked')) return chunked(source);\n const length = header(head, 'content-length');\n if (length === undefined) return untilClose(source);\n const size = Number(length);\n if (!/^\\d+$/.test(length.trim()) || !Number.isSafeInteger(size)) {\n throw errorWithCode(`EPROTO: a malformed Content-Length: ${length}`);\n }\n return counted(source, size);\n}\n\nfunction stream(chunks: AsyncGenerator<Uint8Array>, socket: DialledSocket, signal?: AbortSignal) {\n return new ReadableStream<Uint8Array>({\n start(controller) {\n signal?.addEventListener('abort', () => controller.error(signal.reason), { once: true });\n },\n async pull(controller) {\n try {\n const next = await chunks.next();\n if (next.done) {\n controller.close();\n socket.close();\n } else controller.enqueue(next.value);\n } catch (err) {\n controller.error(err);\n socket.close();\n }\n },\n cancel() {\n socket.close();\n },\n });\n}\n\nasync function requestBytes(request: Request): Promise<Uint8Array> {\n const url = new URL(request.url);\n const body = request.body ? new Uint8Array(await request.arrayBuffer()) : undefined;\n const lines = [`${request.method} ${url.pathname}${url.search} HTTP/1.1`, `Host: ${url.host}`];\n request.headers.forEach((value, name) => {\n if (!OWN_HEADERS.has(name)) lines.push(`${name}: ${value}`);\n });\n if (body) lines.push(`Content-Length: ${body.length}`);\n lines.push('Connection: close', '', '');\n const head = encoder.encode(lines.join('\\r\\n'));\n const out = new Uint8Array(head.length + (body?.length ?? 0));\n out.set(head);\n if (body) out.set(body, head.length);\n return out;\n}\n\nexport async function loopbackFetch(\n dial: (options: DialOptions) => Promise<DialledSocket>,\n input: RequestInfo | URL,\n options: LoopbackFetchOptions\n): Promise<Response> {\n options.signal?.throwIfAborted();\n const request = input instanceof Request ? input : new Request(input);\n const bytes = await requestBytes(request);\n const socket = await dial({\n port: options.port,\n ...(options.host ? { host: options.host } : {}),\n });\n options.signal?.addEventListener('abort', () => socket.close(), { once: true });\n try {\n const writer = socket.writable.getWriter();\n await writer.write(bytes);\n writer.releaseLock();\n const source = new ByteSource(socket.readable.getReader());\n let head: ResponseHead;\n do {\n const raw = await source.until('\\r\\n\\r\\n');\n if (!raw) throw errorWithCode('ECONNRESET: the connection closed before a response');\n head = parseHead(raw);\n } while (head.status >= 100 && head.status < 200);\n const chunks = bodyOf(source, head, request.method);\n if (!chunks) socket.close();\n return new Response(chunks ? stream(chunks, socket, options.signal) : null, {\n status: head.status,\n statusText: head.statusText,\n headers: head.headers,\n });\n } catch (err) {\n socket.close();\n throw err;\n }\n}\n", "export const HOST_LOOPBACK = 'host.slicc.internal';\n\nexport const HOST_LOOPBACK_ADDRESS = [10, 0, 2, 2] as const;\n\nexport const PAGE_LOOPBACK = 'kernel.localhost';\n\nexport const PAGE_LOOPBACK_URL = `http://{port}.${PAGE_LOOPBACK}`;\n\nexport function toHostLoopback(href: string): string {\n const url = new URL(href);\n if (url.hostname.replace(/\\.$/, '').toLowerCase() !== HOST_LOOPBACK) return href;\n url.hostname = '127.0.0.1';\n return url.href;\n}\n\nexport const DEFAULT_HOSTNAME = 'slicc';\n\nexport const HOSTNAME_ADDRESS = '127.0.1.1';\n\nexport const LIBC_HOSTNAMES: readonly string[] = ['emscripten', 'wasmer.sh'];\n\nconst LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i;\n\nfunction reserved(name: string): boolean {\n const lower = name.toLowerCase();\n return (\n lower === 'localhost' ||\n lower.endsWith('.localhost') ||\n lower === HOST_LOOPBACK ||\n lower === 'wasmer.sh' ||\n /^\\d+(\\.\\d+){3}$/.test(lower)\n );\n}\n\nexport function isHostname(name: unknown): name is string {\n if (typeof name !== 'string' || name.length > 253 || reserved(name)) return false;\n return name.split('.').every((l) => LABEL.test(l));\n}\n\nexport function hostnameOf(env: Readonly<Record<string, string>>): string {\n return isHostname(env.HOSTNAME) ? env.HOSTNAME : DEFAULT_HOSTNAME;\n}\n\nexport function ownNames(hostname: string): string[] {\n return [...new Set([hostname.toLowerCase(), ...LIBC_HOSTNAMES])];\n}\n\nexport function hostsFile(hostname: string = DEFAULT_HOSTNAME): string {\n return [\n '127.0.0.1 localhost localhost.localdomain',\n '::1 localhost ip6-localhost',\n `${HOSTNAME_ADDRESS} ${ownNames(hostname).join(' ')}`,\n `${HOST_LOOPBACK_ADDRESS.join('.')} ${HOST_LOOPBACK}`,\n '',\n ].join('\\n');\n}\n", "import { HOST_LOOPBACK, HOST_LOOPBACK_ADDRESS } from './loopback-names.ts';\n\nexport interface RouteTable {\n prefixes: readonly string[];\n exit: boolean;\n}\n\nexport type Destination = 'loopback' | 'host' | 'reserved' | 'uplink' | 'unreachable';\n\ninterface Prefix {\n v6: boolean;\n bits: bigint;\n length: number;\n}\n\nconst HOST_ADDRESS = HOST_LOOPBACK_ADDRESS.join('.');\n\nexport function ipv4Bytes(text: string): number[] | undefined {\n const parts = text.split('.');\n if (parts.length !== 4 || !parts.every((p) => /^\\d{1,3}$/.test(p))) return undefined;\n const bytes = parts.map(Number);\n return bytes.every((b) => b <= 255) ? bytes : undefined;\n}\n\nexport function ipv6Groups(text: string): number[] | undefined {\n if (!text.includes(':')) return undefined;\n let canonical: string;\n try {\n canonical = new URL(`http://[${text}]/`).hostname.slice(1, -1);\n } catch {\n return undefined;\n }\n const [head, tail] = canonical.split('::');\n const part = (s: string | undefined) =>\n s ? s.split(':').map((h) => Number.parseInt(h, 16)) : [];\n const front = part(head);\n const back = part(tail);\n return tail === undefined\n ? front\n : [...front, ...new Array<number>(8 - front.length - back.length).fill(0), ...back];\n}\n\nfunction toBits(values: number[], width: number): bigint {\n return values.reduce((acc, v) => (acc << BigInt(width)) | BigInt(v), 0n);\n}\n\nfunction addressBits(host: string): { v6: boolean; bits: bigint } | undefined {\n const v4 = ipv4Bytes(host);\n if (v4) return { v6: false, bits: toBits(v4, 8) };\n const v6 = ipv6Groups(host);\n return v6 ? { v6: true, bits: toBits(v6, 16) } : undefined;\n}\n\nfunction parsePrefix(text: string): Prefix | undefined {\n const parts = text.trim().split('/');\n if (parts.length > 2) return undefined;\n const [address = '', size] = parts;\n const parsed = addressBits(address);\n if (!parsed) return undefined;\n const max = parsed.v6 ? 128 : 32;\n const length = size === undefined ? max : /^\\d{1,3}$/.test(size) ? Number(size) : -1;\n if (length < 0 || length > max) return undefined;\n return { ...parsed, length };\n}\n\nfunction within(prefix: Prefix, addr: { v6: boolean; bits: bigint }): boolean {\n if (prefix.v6 !== addr.v6) return false;\n const shift = BigInt((prefix.v6 ? 128 : 32) - prefix.length);\n return addr.bits >> shift === prefix.bits >> shift;\n}\n\nconst RESERVED = [\n '0.0.0.0/8',\n '127.0.0.0/8',\n '169.254.0.0/16',\n '224.0.0.0/4',\n '240.0.0.0/4',\n '::/96',\n '::ffff:0:0/96',\n 'fe80::/10',\n 'ff00::/8',\n].map((p) => parsePrefix(p) as Prefix);\n\nexport class Routes {\n private table: Prefix[] = [];\n private exit = false;\n readonly ipv6: boolean;\n\n constructor(ipv6 = false) {\n this.ipv6 = ipv6;\n }\n\n set(table: RouteTable): void {\n const parsed = (table.prefixes ?? []).map(parsePrefix);\n const bad = (table.prefixes ?? []).find((_, i) => !parsed[i]);\n if (bad !== undefined) throw new Error(`not an address prefix: ${bad}`);\n this.table = parsed as Prefix[];\n this.exit = table.exit === true;\n }\n\n classify(host: string): Destination {\n const name = host.toLowerCase().replace(/\\.$/, '');\n if (name === 'localhost' || name.endsWith('.localhost') || name === '0.0.0.0') {\n return 'loopback';\n }\n if (name === HOST_LOOPBACK || name === HOST_ADDRESS) return 'host';\n const addr = addressBits(name);\n if (!addr) return 'unreachable';\n if (addr.v6 && addr.bits === 1n) return 'loopback';\n if (!addr.v6 && addr.bits >> 24n === 127n) return 'loopback';\n if (RESERVED.some((p) => within(p, addr))) return 'reserved';\n if (addr.v6 && !this.ipv6) return 'unreachable';\n if (this.exit || this.table.some((p) => within(p, addr))) return 'uplink';\n return 'unreachable';\n }\n}\n", "import { Routes, type RouteTable } from './routes.ts';\n\nexport interface UplinkTraits {\n tcp: true;\n udp: false;\n ipv6: boolean;\n}\n\nexport type ResolveFamily = 0 | 4 | 6;\n\nexport interface ResolveAnswer {\n addresses: string[];\n ttl?: number;\n}\n\nexport interface UplinkConn {\n readonly localAddr: string;\n readonly remoteAddr: string;\n read(): Promise<Uint8Array | null>;\n write(bytes: Uint8Array): Promise<number>;\n closeWrite(): void;\n close(): void;\n}\n\nexport interface UplinkDial {\n network: 'tcp';\n host: string;\n port: number;\n signal: AbortSignal;\n}\n\nexport interface NetworkUplink {\n readonly traits: UplinkTraits;\n readonly routes?: RouteTable;\n resolve(\n name: string,\n family: ResolveFamily,\n signal?: AbortSignal\n ): Promise<string[] | ResolveAnswer>;\n dial(req: UplinkDial): Promise<UplinkConn>;\n}\n\nexport type UplinkCall =\n | { uplink: 'resolve'; uid: number; name: string; family: ResolveFamily }\n | { uplink: 'dial'; uid: number; host: string; port: number }\n | { uplink: 'cancel'; uid: number }\n | { uplink: 'read'; uid: number; cid: number }\n | { uplink: 'write'; uid: number; cid: number; bytes: Uint8Array }\n | { uplink: 'close-write'; cid: number }\n | { uplink: 'close'; cid: number };\n\nexport type UplinkReply =\n | { uplink: 'resolved'; uid: number; addresses: string[]; ttl?: number }\n | { uplink: 'dialled'; uid: number; cid: number; localAddr: string; remoteAddr: string }\n | { uplink: 'data'; uid: number; bytes: Uint8Array | null }\n | { uplink: 'written'; uid: number; n: number }\n | { uplink: 'error'; uid: number; message: string; code?: string };\n\nexport interface UplinkPeer {\n postMessage(message: UplinkReply, transfer?: Transferable[]): void;\n}\n\nexport interface UplinkPort {\n postMessage(message: UplinkCall, transfer?: Transferable[]): void;\n}\n\nexport interface UplinkServer {\n answer(call: UplinkCall): void;\n close(): void;\n}\n\nexport function answerOf(result: string[] | ResolveAnswer): ResolveAnswer {\n const answer = Array.isArray(result) ? { addresses: result } : result;\n const addresses = Array.isArray(answer?.addresses)\n ? answer.addresses.filter((a): a is string => typeof a === 'string')\n : [];\n return {\n addresses,\n ...(typeof answer?.ttl === 'number' && answer.ttl >= 0 ? { ttl: answer.ttl } : {}),\n };\n}\n\nfunction failure(uid: number, e: unknown): UplinkReply {\n const code = (e as { code?: unknown } | null)?.code;\n return {\n uplink: 'error',\n uid,\n message: e instanceof Error ? e.message : String(e),\n ...(typeof code === 'string' ? { code } : {}),\n };\n}\n\nconst NEVER = new Routes(true);\n\nexport function serveUplink(peer: UplinkPeer, uplink: NetworkUplink): UplinkServer {\n const conns = new Map<number, UplinkConn>();\n const pending = new Map<number, AbortController>();\n let nextCid = 0;\n let closed = false;\n const run = (uid: number, work: (signal: AbortSignal) => Promise<UplinkReply | undefined>) => {\n const abort = new AbortController();\n pending.set(uid, abort);\n void work(abort.signal)\n .then(\n (reply) => reply && peer.postMessage(reply, transferOf(reply)),\n (e: unknown) => peer.postMessage(failure(uid, e))\n )\n .finally(() => pending.delete(uid));\n };\n const conn = (cid: number): UplinkConn => {\n const found = conns.get(cid);\n if (!found) throw Object.assign(new Error('no such uplink connection'), { code: 'EBADF' });\n return found;\n };\n const dial = async (call: Extract<UplinkCall, { uplink: 'dial' }>, signal: AbortSignal) => {\n const kind = NEVER.classify(call.host);\n if (kind === 'loopback' || kind === 'host' || kind === 'reserved') {\n throw Object.assign(new Error(`the uplink does not carry ${call.host}`), {\n code: 'ENETUNREACH',\n });\n }\n const { host, port } = call;\n const opened = await uplink.dial({ network: 'tcp', host, port, signal });\n if (signal.aborted || closed) {\n opened.close();\n return undefined;\n }\n const cid = ++nextCid;\n conns.set(cid, opened);\n const { localAddr, remoteAddr } = opened;\n return { uplink: 'dialled' as const, uid: call.uid, cid, localAddr, remoteAddr };\n };\n const drop = (cid: number) => {\n const found = conns.get(cid);\n conns.delete(cid);\n found?.close();\n };\n return {\n answer(call) {\n switch (call.uplink) {\n case 'resolve':\n return run(call.uid, async (signal) => ({\n uplink: 'resolved',\n uid: call.uid,\n ...answerOf(await uplink.resolve(call.name, call.family, signal)),\n }));\n case 'dial':\n return run(call.uid, (signal) => dial(call, signal));\n case 'cancel':\n return pending.get(call.uid)?.abort();\n case 'read':\n return run(call.uid, async () => ({\n uplink: 'data',\n uid: call.uid,\n bytes: (await conn(call.cid).read())?.slice() ?? null,\n }));\n case 'write':\n return run(call.uid, async () => ({\n uplink: 'written',\n uid: call.uid,\n n: await conn(call.cid).write(call.bytes),\n }));\n case 'close-write':\n return conns.get(call.cid)?.closeWrite();\n default:\n return drop(call.cid);\n }\n },\n close() {\n closed = true;\n for (const abort of pending.values()) abort.abort();\n for (const cid of [...conns.keys()]) drop(cid);\n },\n };\n}\n\nfunction transferOf(reply: UplinkReply): Transferable[] | undefined {\n if (reply.uplink !== 'data' || !reply.bytes) return undefined;\n return [reply.bytes.buffer as ArrayBuffer];\n}\n\ntype Answer = Exclude<UplinkReply, { uplink: 'error' }>;\n\nexport class RemoteUplink implements NetworkUplink {\n readonly traits: UplinkTraits;\n readonly routes: RouteTable | undefined;\n private readonly port: UplinkPort;\n private readonly waiting = new Map<number, PromiseWithResolvers<Answer>>();\n private nextId = 0;\n\n constructor(port: UplinkPort, traits: UplinkTraits, routes?: RouteTable) {\n this.port = port;\n this.traits = traits;\n this.routes = routes;\n }\n\n receive(reply: UplinkReply): void {\n const waiter = this.waiting.get(reply.uid);\n if (!waiter) return;\n this.waiting.delete(reply.uid);\n if (reply.uplink === 'error') {\n waiter.reject(Object.assign(new Error(reply.message), { code: reply.code }));\n } else waiter.resolve(reply);\n }\n\n private ask<T extends Answer>(\n call: Extract<UplinkCall, { uid: number }>,\n signal?: AbortSignal,\n transfer?: Transferable[]\n ): Promise<T> {\n const waiter = Promise.withResolvers<Answer>();\n this.waiting.set(call.uid, waiter);\n const abort = () => {\n this.waiting.delete(call.uid);\n this.port.postMessage({ uplink: 'cancel', uid: call.uid });\n waiter.reject(signal?.reason);\n };\n signal?.addEventListener('abort', abort, { once: true });\n const settled = () => signal?.removeEventListener('abort', abort);\n waiter.promise.then(settled, settled);\n this.port.postMessage(call, transfer);\n return waiter.promise as Promise<T>;\n }\n\n async resolve(name: string, family: ResolveFamily, signal?: AbortSignal) {\n const reply = await this.ask<Extract<Answer, { uplink: 'resolved' }>>(\n { uplink: 'resolve', uid: ++this.nextId, name, family },\n signal\n );\n return answerOf(reply);\n }\n\n async dial(req: UplinkDial): Promise<UplinkConn> {\n req.signal.throwIfAborted();\n const { host, port } = req;\n const opened = await this.ask<Extract<Answer, { uplink: 'dialled' }>>(\n { uplink: 'dial', uid: ++this.nextId, host, port },\n req.signal\n );\n const { cid, localAddr, remoteAddr } = opened;\n return {\n localAddr,\n remoteAddr,\n read: async () => {\n const got = await this.ask<Extract<Answer, { uplink: 'data' }>>({\n uplink: 'read',\n uid: ++this.nextId,\n cid,\n });\n return got.bytes;\n },\n write: async (bytes) => {\n const copy = bytes.slice();\n const call = { uplink: 'write' as const, uid: ++this.nextId, cid, bytes: copy };\n const done = await this.ask<Extract<Answer, { uplink: 'written' }>>(call, undefined, [\n copy.buffer,\n ]);\n return done.n;\n },\n closeWrite: () => this.port.postMessage({ uplink: 'close-write', cid }),\n close: () => this.port.postMessage({ uplink: 'close', cid }),\n };\n }\n}\n", "export const BODY_IDLE_MS = 5 * 60 * 1000;\n\nexport function idleFailure(ms: number): Error {\n return Object.assign(new Error(`the response body sent no data for ${ms} ms`), {\n code: 'ETIMEDOUT',\n });\n}\n\nexport async function readWithin<T>(\n reader: ReadableStreamDefaultReader<T>,\n ms: number\n): Promise<ReadableStreamReadResult<T>> {\n if (!(ms > 0 && ms < Number.POSITIVE_INFINITY)) return reader.read();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const idle = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(idleFailure(ms)), ms);\n });\n try {\n return await Promise.race([reader.read(), idle]);\n } finally {\n clearTimeout(timer);\n }\n}\n", "import type { RealmWebSocketClose, RealmWebSocketMessage } from './transport.ts';\n\nexport const INBOUND_LIMIT = 16 * 1024 * 1024;\nexport const MESSAGE_LIMIT = 64 * 1024 * 1024;\nexport const TOO_BIG = 1009;\n\nexport function payloadSize(message: RealmWebSocketMessage): number {\n return typeof message === 'string' ? new TextEncoder().encode(message).length : message.length;\n}\n\nexport class MessageQueue implements AsyncIterable<RealmWebSocketMessage> {\n private readonly items: RealmWebSocketMessage[] = [];\n private readonly limit: number;\n private waiter: (() => void) | undefined;\n private size = 0;\n private ended = false;\n private readonly overflow: () => void;\n private readonly taken: ((n: number) => void) | undefined;\n readonly closed: Promise<RealmWebSocketClose>;\n private settle!: (close: RealmWebSocketClose) => void;\n\n constructor(overflow: () => void, limit = INBOUND_LIMIT, taken?: (n: number) => void) {\n this.overflow = overflow;\n this.limit = limit;\n this.taken = taken;\n this.closed = new Promise((resolve) => {\n this.settle = resolve;\n });\n }\n\n push(message: RealmWebSocketMessage): void {\n if (this.ended) return;\n const size = payloadSize(message);\n const huge = size > MESSAGE_LIMIT;\n if (huge || (this.items.length > 0 && this.size + size > this.limit)) {\n const reason = huge\n ? `a message is over ${MESSAGE_LIMIT} bytes`\n : `over ${this.limit} bytes of messages are waiting`;\n this.end({ code: TOO_BIG, reason });\n this.overflow();\n return;\n }\n this.size += size;\n this.items.push(message);\n this.wake();\n }\n\n end(close: RealmWebSocketClose): void {\n if (this.ended) return;\n this.ended = true;\n this.settle(close);\n this.wake();\n }\n\n private wake(): void {\n const waiter = this.waiter;\n this.waiter = undefined;\n waiter?.();\n }\n\n async *[Symbol.asyncIterator](): AsyncIterator<RealmWebSocketMessage> {\n for (;;) {\n const next = this.items.shift();\n if (next !== undefined) {\n const n = payloadSize(next);\n this.size -= n;\n this.taken?.(n);\n yield next;\n continue;\n }\n if (this.ended) return;\n await new Promise<void>((resolve) => {\n this.waiter = resolve;\n });\n }\n }\n}\n", "import type {\n HeaderList,\n RealmWebSocket,\n RealmWebSocketMessage,\n RealmWebSocketRequest,\n} from './kernel/net/transport.ts';\nimport { MessageQueue } from './kernel/net/ws-queue.ts';\n\nexport interface WebSocketLike {\n binaryType: string;\n readonly protocol: string;\n readonly bufferedAmount: number;\n send(data: string | ArrayBufferView): void;\n close(code?: number, reason?: string): void;\n addEventListener(type: string, listener: (event: never) => void): void;\n}\n\nexport type WebSocketConstructor = new (url: string, init?: unknown) => WebSocketLike;\n\nconst SENT_HEADERS_DROP = new Set([\n 'host',\n 'connection',\n 'upgrade',\n 'sec-websocket-key',\n 'sec-websocket-version',\n 'sec-websocket-extensions',\n 'sec-websocket-protocol',\n]);\n\nfunction headerRecord(headers: HeaderList): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [name, value] of headers) {\n if (!SENT_HEADERS_DROP.has(name.toLowerCase())) out[name] = value;\n }\n return out;\n}\n\nexport function sendableClose(code?: number): number {\n return code === 1000 || (code !== undefined && code >= 3000 && code <= 4999) ? code : 1000;\n}\n\nfunction blockedReason(url: string, e: unknown): string {\n const name = (e as { name?: unknown } | null)?.name;\n if (name === 'SecurityError' && url.startsWith('ws:')) {\n return `${url}: ws:// is blocked from an https page; use wss:// or slicc-node`;\n }\n return `${url}: ${e instanceof Error ? e.message : String(e)}`;\n}\n\nfunction unopened(url: string, code: number): Error {\n return Object.assign(new Error(`${url}: the WebSocket closed (${code}) before it opened`), {\n status: 502,\n });\n}\n\nexport function openWebSocket(\n Socket: WebSocketConstructor,\n request: RealmWebSocketRequest,\n withHeaders: boolean\n): Promise<RealmWebSocket> {\n const { url, protocols, signal } = request;\n signal.throwIfAborted();\n let socket: WebSocketLike;\n try {\n socket = withHeaders\n ? new Socket(url, { protocols, headers: headerRecord(request.headers) })\n : new Socket(url, protocols);\n } catch (e) {\n return Promise.reject(Object.assign(new Error(blockedReason(url, e)), { status: 502 }));\n }\n socket.binaryType = 'arraybuffer';\n const queue = new MessageQueue(() => socket.close(1000, 'too many waiting messages'));\n return new Promise((resolve, reject) => {\n let open = false;\n let settled = false;\n const fail = (error: unknown) => {\n if (settled) return;\n settled = true;\n signal.removeEventListener('abort', abort);\n reject(error);\n };\n const abort = () => {\n fail(signal.reason);\n socket.close(1000, 'aborted');\n };\n signal.addEventListener('abort', abort, { once: true });\n socket.addEventListener('open', () => {\n if (settled) return;\n open = true;\n settled = true;\n signal.removeEventListener('abort', abort);\n resolve({\n protocol: socket.protocol,\n get buffered() {\n return socket.bufferedAmount;\n },\n send: (data: RealmWebSocketMessage) => socket.send(data),\n messages: queue,\n close: (code?: number, reason?: string) => socket.close(sendableClose(code), reason),\n closed: queue.closed,\n });\n });\n socket.addEventListener('message', (event: { data: string | ArrayBuffer }) => {\n queue.push(typeof event.data === 'string' ? event.data : new Uint8Array(event.data));\n });\n socket.addEventListener('error', () => {\n if (open || settled) return;\n fail(unopened(url, 1006));\n queue.end({ code: 1006, reason: '' });\n try {\n socket.close();\n } catch {}\n });\n socket.addEventListener('close', (event: { code: number; reason: string }) => {\n queue.end({ code: event.code, reason: event.reason });\n if (open) return;\n fail(unopened(url, event.code));\n });\n });\n}\n", "import { BODY_IDLE_MS, readWithin } from './body-idle.ts';\nimport type { TransportCall, TransportReply } from './kernel/net/remote-transport.ts';\nimport type {\n HeaderList,\n RealmRedirectHop,\n RealmTransport,\n RealmTransportRequest,\n RealmTransportResponse,\n RealmTransportTraits,\n RealmWebSocket,\n RealmWebSocketRequest,\n} from './kernel/net/transport.ts';\nimport { INBOUND_LIMIT, MESSAGE_LIMIT, payloadSize } from './kernel/net/ws-queue.ts';\nimport { openWebSocket, type WebSocketConstructor } from './websocket-transport.ts';\n\nexport type {\n HeaderList,\n RealmRedirectHop as NetworkRedirectHop,\n RealmTransport as NetworkTransport,\n RealmTransportRequest as NetworkRequest,\n RealmTransportResponse as NetworkResponse,\n RealmTransportTraits as NetworkTraits,\n RealmWebSocket as NetworkWebSocket,\n RealmWebSocketRequest as NetworkWebSocketRequest,\n};\n\nexport interface FetchTransportOptions {\n fetch?: typeof globalThis.fetch;\n maxRequestBody?: number;\n hint?: string;\n bodyIdleMs?: number;\n webSocket?: boolean | WebSocketConstructor;\n webSocketHeaders?: boolean;\n redirect?: 'follow' | 'manual';\n}\n\nexport const SEND_BUFFER = 1024 * 1024;\nconst CLOSE_WAIT_MS = 5000;\n\nconst NO_WEBSOCKET =\n 'WebSocket not supported by this transport (fetchTransport needs { webSocket: true })';\n\nconst MAX_REQUEST_BODY = 64 * 1024 * 1024;\n\nfunction joinHeaders(headers: HeaderList): Headers {\n const out = new Headers();\n for (const [name, value] of headers) {\n try {\n out.append(name, value);\n } catch {}\n }\n return out;\n}\n\nasync function* chunks(\n body: ReadableStream<Uint8Array> | null,\n idleMs: number\n): AsyncGenerator<Uint8Array> {\n if (!body) return;\n const reader = body.getReader();\n try {\n for (\n let next = await readWithin(reader, idleMs);\n !next.done;\n next = await readWithin(reader, idleMs)\n ) {\n if (next.value.byteLength > 0) yield next.value;\n }\n } finally {\n await reader.cancel().catch(() => undefined);\n }\n}\n\nexport function fetchTransport(options: FetchTransportOptions = {}): RealmTransport {\n const send = options.fetch ?? globalThis.fetch.bind(globalThis);\n const Socket =\n options.webSocket === true\n ? (globalThis as { WebSocket?: WebSocketConstructor }).WebSocket\n : options.webSocket || undefined;\n const headers = options.webSocketHeaders === true;\n const redirect = options.redirect ?? 'follow';\n return {\n traits: {\n manualRedirects: redirect === 'manual',\n encodedBodies: false,\n maxRequestBody: options.maxRequestBody ?? MAX_REQUEST_BODY,\n crossOrigin: 'cors',\n ...(Socket ? { websocket: true as const } : {}),\n },\n ...(Socket ? { websocket: (request) => openWebSocket(Socket, request, headers) } : {}),\n async fetch(request: RealmTransportRequest): Promise<RealmTransportResponse> {\n let response: Response;\n try {\n response = await send(request.url, {\n method: request.method,\n headers: joinHeaders(request.headers),\n ...(request.body ? { body: request.body as BodyInit } : {}),\n signal: request.signal,\n redirect,\n credentials: 'omit',\n mode: 'cors',\n });\n } catch (e) {\n if (request.signal.aborted) throw e;\n throw Object.assign(\n new Error(\n `fetch ${request.url} failed (unreachable, or not allowed by CORS)${options.hint ? `: ${options.hint}` : ''}`\n ),\n { status: 502 }\n );\n }\n const headers: Array<[string, string]> = [];\n response.headers.forEach((value, name) => {\n headers.push([name, value]);\n });\n const body = chunks(response.body, options.bodyIdleMs ?? BODY_IDLE_MS);\n return {\n ...(response.redirected ? { url: response.url, redirected: true } : {}),\n status: response.status,\n statusText: response.statusText,\n headers,\n body,\n cancel: async () => {\n await body.return(undefined);\n await response.body?.cancel().catch(() => undefined);\n },\n };\n },\n };\n}\n\nexport interface TransportPeer {\n postMessage(message: TransportReply, transfer?: Transferable[]): void;\n}\n\nexport interface TransportServer {\n answer(call: TransportCall): void;\n close(): void;\n}\n\ninterface Flow {\n inflight: number;\n closing: boolean;\n deadline(): void;\n wake?: () => void;\n}\n\nexport function serveTransport(\n peer: TransportPeer,\n transport: RealmTransport,\n { closeWaitMs = CLOSE_WAIT_MS }: { closeWaitMs?: number } = {}\n): TransportServer {\n const open = new Map<\n number,\n { abort: AbortController; body?: AsyncIterator<Uint8Array>; response?: RealmTransportResponse }\n >();\n const fail = (nid: number, e: unknown) => {\n open.delete(nid);\n const { status, code } = e as { status?: unknown; code?: unknown };\n peer.postMessage({\n net: 'error',\n nid,\n message: e instanceof Error ? e.message : String(e),\n ...(typeof status === 'number' ? { status } : {}),\n ...(typeof code === 'string' ? { code } : {}),\n });\n };\n const start = async (call: Extract<TransportCall, { net: 'fetch' }>) => {\n const abort = new AbortController();\n const entry: { abort: AbortController; body?: AsyncIterator<Uint8Array> } = { abort };\n open.set(call.nid, entry);\n try {\n const response = await transport.fetch({\n url: call.url,\n method: call.method,\n headers: call.headers,\n ...(call.body ? { body: call.body } : {}),\n signal: abort.signal,\n });\n if (!open.has(call.nid)) {\n await response.cancel();\n return;\n }\n open.set(call.nid, { abort, body: response.body[Symbol.asyncIterator](), response });\n peer.postMessage({\n net: 'head',\n nid: call.nid,\n ...(response.redirected ? { url: response.url, redirected: true } : {}),\n ...(response.redirects ? { redirects: response.redirects } : {}),\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n } catch (e) {\n fail(call.nid, e);\n }\n };\n const sockets = new Map<number, RealmWebSocket>();\n const credit = new Map<number, Flow>();\n const refill = (nid: number, n: number, closing = false) => {\n const flow = credit.get(nid);\n if (!flow) return;\n flow.inflight -= n;\n if (closing && !flow.closing) {\n flow.closing = true;\n flow.deadline();\n }\n flow.wake?.();\n };\n const openSocket = async (call: Extract<TransportCall, { net: 'ws-open' }>) => {\n const abort = new AbortController();\n open.set(call.nid, { abort });\n try {\n if (!transport.websocket) throw new Error(NO_WEBSOCKET);\n const socket = await transport.websocket({\n url: call.url,\n protocols: call.protocols,\n headers: call.headers,\n signal: abort.signal,\n });\n if (!open.delete(call.nid)) {\n socket.close(1000, 'cancelled');\n return;\n }\n sockets.set(call.nid, socket);\n peer.postMessage({ net: 'ws-opened', nid: call.nid, protocol: socket.protocol });\n void relay(call.nid, socket);\n } catch (e) {\n fail(call.nid, e);\n }\n };\n const relay = async (nid: number, socket: RealmWebSocket) => {\n let ending: { code: number; reason: string };\n let late!: () => void;\n const unanswered = new Promise<'late'>((resolve) => {\n late = () => resolve('late');\n });\n const flow: Flow = {\n inflight: 0,\n closing: false,\n deadline: () =>\n AbortSignal.timeout(closeWaitMs).addEventListener('abort', late, { once: true }),\n };\n credit.set(nid, flow);\n const timedOut = { code: 1006, reason: 'the far end did not answer the close' };\n let oversize = false;\n try {\n const messages = socket.messages[Symbol.asyncIterator]();\n for (;;) {\n const next = await Promise.race([messages.next(), unanswered]);\n if (next === 'late' || next.done) break;\n const data = next.value;\n if (flow.closing) continue;\n if (payloadSize(data) > MESSAGE_LIMIT) {\n oversize = true;\n break;\n }\n if (typeof data === 'string') peer.postMessage({ net: 'ws-message', nid, data });\n else {\n const bytes = data.slice();\n peer.postMessage({ net: 'ws-message', nid, data: bytes }, [bytes.buffer]);\n }\n flow.inflight += payloadSize(data);\n while (flow.inflight > INBOUND_LIMIT && !flow.closing) {\n await new Promise<void>((resolve) => {\n flow.wake = resolve;\n });\n }\n }\n if (oversize) socket.close(1000, 'a message is too big');\n ending = oversize\n ? { code: 1009, reason: `a message is over ${MESSAGE_LIMIT} bytes` }\n : await Promise.race([socket.closed, unanswered.then(() => timedOut)]);\n } catch (e) {\n socket.close(1000, 'the relay failed');\n ending = { code: 1011, reason: e instanceof Error ? e.message : String(e) };\n }\n sockets.delete(nid);\n credit.delete(nid);\n peer.postMessage({ net: 'ws-closed', nid, ...ending });\n };\n const sendOn = async (call: Extract<TransportCall, { net: 'ws-send' }>) => {\n const socket = sockets.get(call.nid);\n if (!socket) return;\n socket.send(call.data);\n while (socket.buffered > SEND_BUFFER && sockets.has(call.nid)) {\n await new Promise((resolve) => setTimeout(resolve, 10));\n }\n peer.postMessage({ net: 'ws-acked', nid: call.nid, n: payloadSize(call.data) });\n };\n const read = async (nid: number) => {\n const body = open.get(nid)?.body;\n if (!body) return;\n try {\n const next = await body.next();\n if (next.done) {\n open.delete(nid);\n peer.postMessage({ net: 'end', nid });\n } else {\n const bytes = next.value.slice();\n peer.postMessage({ net: 'chunk', nid, bytes }, [bytes.buffer]);\n }\n } catch (e) {\n fail(nid, e);\n }\n };\n const drop = (nid: number) => {\n sockets.get(nid)?.close(1000, 'cancelled');\n refill(nid, 0, true);\n const entry = open.get(nid);\n open.delete(nid);\n entry?.abort.abort();\n void entry?.response?.cancel().catch(() => undefined);\n };\n return {\n answer(call) {\n if (call.net === 'fetch') void start(call);\n else if (call.net === 'read') void read(call.nid);\n else if (call.net === 'ws-open') void openSocket(call);\n else if (call.net === 'ws-send') void sendOn(call);\n else if (call.net === 'ws-close') {\n sockets.get(call.nid)?.close(call.code, call.reason);\n refill(call.nid, 0, true);\n } else if (call.net === 'ws-consumed') refill(call.nid, call.n);\n else drop(call.nid);\n },\n close() {\n for (const nid of [...open.keys(), ...sockets.keys()]) drop(nid);\n },\n };\n}\n", "import type {\n HeaderList,\n RealmRedirectHop,\n RealmTransport,\n RealmTransportRequest,\n RealmTransportResponse,\n RealmTransportTraits,\n RealmWebSocket,\n RealmWebSocketMessage,\n RealmWebSocketRequest,\n} from './transport.ts';\nimport { MessageQueue, payloadSize } from './ws-queue.ts';\n\nexport type TransportCall =\n | {\n net: 'fetch';\n nid: number;\n url: string;\n method: string;\n headers: HeaderList;\n body?: Uint8Array;\n }\n | { net: 'read'; nid: number }\n | { net: 'cancel'; nid: number }\n | { net: 'ws-open'; nid: number; url: string; protocols: string[]; headers: HeaderList }\n | { net: 'ws-send'; nid: number; data: RealmWebSocketMessage }\n | { net: 'ws-close'; nid: number; code?: number; reason?: string }\n | { net: 'ws-consumed'; nid: number; n: number };\n\nexport type TransportReply =\n | {\n net: 'head';\n nid: number;\n status: number;\n statusText: string;\n headers: HeaderList;\n url?: string;\n redirected?: boolean;\n redirects?: readonly RealmRedirectHop[];\n }\n | { net: 'chunk'; nid: number; bytes: Uint8Array }\n | { net: 'end'; nid: number }\n | { net: 'error'; nid: number; message: string; status?: number; code?: string }\n | { net: 'ws-opened'; nid: number; protocol: string }\n | { net: 'ws-message'; nid: number; data: RealmWebSocketMessage }\n | { net: 'ws-acked'; nid: number; n: number }\n | { net: 'ws-closed'; nid: number; code: number; reason: string };\n\nexport interface TransportPort {\n postMessage(message: TransportCall): void;\n}\n\nexport class TransportError extends Error {\n readonly status: number | undefined;\n readonly code: string | undefined;\n\n constructor(message: string, status?: number, code?: string) {\n super(message);\n this.status = status;\n this.code = code;\n }\n}\n\ninterface Waiter {\n resolve(reply: TransportReply): void;\n reject(error: Error): void;\n}\n\nexport class RemoteTransport implements RealmTransport {\n readonly traits: RealmTransportTraits;\n\n private readonly port: TransportPort;\n\n private readonly waiting = new Map<number, Waiter>();\n\n private nextId = 0;\n\n private readonly sockets = new Map<number, { queue: MessageQueue; acked(n: number): void }>();\n\n private failure: Error | undefined;\n\n constructor(port: TransportPort, traits: RealmTransportTraits) {\n this.port = port;\n this.traits = traits;\n }\n\n receive(reply: TransportReply): void {\n const socket = this.sockets.get(reply.nid);\n if (socket && this.toSocket(reply, socket)) return;\n const waiter = this.waiting.get(reply.nid);\n if (!waiter) return;\n this.waiting.delete(reply.nid);\n if (reply.net === 'error') {\n waiter.reject(new TransportError(reply.message, reply.status, reply.code));\n } else waiter.resolve(reply);\n }\n\n private toSocket(\n reply: TransportReply,\n socket: { queue: MessageQueue; acked(n: number): void }\n ): boolean {\n if (reply.net === 'ws-message') socket.queue.push(reply.data);\n else if (reply.net === 'ws-acked') socket.acked(reply.n);\n else if (reply.net === 'ws-closed') {\n this.sockets.delete(reply.nid);\n socket.queue.end({ code: reply.code, reason: reply.reason });\n } else return false;\n return true;\n }\n\n fail(error: Error): void {\n this.failure = error;\n for (const waiter of this.waiting.values()) waiter.reject(error);\n this.waiting.clear();\n for (const socket of this.sockets.values())\n socket.queue.end({ code: 1011, reason: error.message });\n this.sockets.clear();\n }\n\n private ask(call: TransportCall): Promise<TransportReply> {\n if (this.failure) return Promise.reject(this.failure);\n return new Promise((resolve, reject) => {\n this.waiting.set(call.nid, { resolve, reject });\n this.port.postMessage(call);\n });\n }\n\n private cancel(nid: number): void {\n const waiter = this.waiting.get(nid);\n this.waiting.delete(nid);\n waiter?.reject(new TransportError('the request was cancelled'));\n this.port.postMessage({ net: 'cancel', nid });\n }\n\n async fetch(request: RealmTransportRequest): Promise<RealmTransportResponse> {\n const nid = ++this.nextId;\n const { signal } = request;\n signal.throwIfAborted();\n let finished = false;\n const abort = () => {\n finished = true;\n this.cancel(nid);\n };\n signal.addEventListener('abort', abort, { once: true });\n const finish = () => {\n if (finished) return;\n finished = true;\n signal.removeEventListener('abort', abort);\n };\n let head: TransportReply;\n try {\n head = await this.ask({\n net: 'fetch',\n nid,\n url: request.url,\n method: request.method,\n headers: request.headers,\n ...(request.body ? { body: request.body } : {}),\n });\n } catch (e) {\n finish();\n throw e;\n }\n const { status, statusText, headers, url, redirected, redirects } = head as Extract<\n TransportReply,\n { net: 'head' }\n >;\n const read = async (): Promise<Uint8Array | undefined> => {\n if (finished) return undefined;\n const reply = await this.ask({ net: 'read', nid }).catch((e: unknown) => {\n finish();\n throw e;\n });\n if (reply.net === 'chunk') return reply.bytes;\n finish();\n return undefined;\n };\n const cancel = async () => {\n if (finished) return;\n finish();\n this.cancel(nid);\n };\n return {\n ...(redirected ? { url, redirected } : {}),\n ...(redirects ? { redirects } : {}),\n status,\n statusText,\n headers,\n cancel,\n body: {\n [Symbol.asyncIterator]: () => ({\n next: async () => {\n const bytes = await read();\n return bytes ? { value: bytes, done: false } : { value: undefined, done: true };\n },\n return: async () => {\n await cancel();\n return { value: undefined, done: true };\n },\n }),\n },\n };\n }\n\n async websocket(request: RealmWebSocketRequest): Promise<RealmWebSocket> {\n const nid = ++this.nextId;\n const { signal } = request;\n signal.throwIfAborted();\n const abort = () => this.cancel(nid);\n signal.addEventListener('abort', abort, { once: true });\n let opened: TransportReply;\n try {\n opened = await this.ask({\n net: 'ws-open',\n nid,\n url: request.url,\n protocols: request.protocols,\n headers: request.headers,\n });\n } finally {\n signal.removeEventListener('abort', abort);\n }\n const close = (code?: number, reason?: string) =>\n this.port.postMessage({ net: 'ws-close', nid, code, reason });\n const queue = new MessageQueue(\n () => close(1000, 'a message is too big'),\n Number.POSITIVE_INFINITY,\n (n) => this.port.postMessage({ net: 'ws-consumed', nid, n })\n );\n let unacked = 0;\n this.sockets.set(nid, { queue, acked: (n) => void (unacked -= n) });\n return {\n protocol: (opened as Extract<TransportReply, { net: 'ws-opened' }>).protocol,\n get buffered() {\n return unacked;\n },\n send: (data) => {\n unacked += payloadSize(data);\n this.port.postMessage({ net: 'ws-send', nid, data });\n },\n messages: queue,\n close,\n closed: queue.closed,\n };\n }\n}\n", "import type { UsersMode } from '../fs/types.ts';\nimport type { WatchChange } from '../fs/watch.ts';\nimport type { TransportCall, TransportReply } from '../kernel/net/remote-transport.ts';\nimport type { RealmTransportTraits } from '../kernel/net/transport.ts';\nimport type { MountSpec } from '../mount/mount-fs.ts';\n\nexport const PROTOCOL: readonly [number, number] = [1, 9];\n\nexport interface ClientHello {\n protocol: readonly [number, number];\n lock?: string;\n}\n\nexport interface KernelHello {\n protocol: readonly [number, number];\n lock?: string;\n traits?: RealmTransportTraits;\n users?: UsersMode;\n error?: string;\n}\n\nexport interface SpawnRequestOptions {\n cwd?: string;\n user?: string | number;\n env?: Record<string, string>;\n stdin?: Uint8Array;\n pgid?: number;\n}\n\nexport interface TerminalRequestOptions {\n cwd?: string;\n user?: string | number;\n env?: Record<string, string>;\n cols?: number;\n rows?: number;\n}\n\nexport type TerminalAction =\n | { action: 'write'; bytes: Uint8Array }\n | { action: 'resize'; cols: number; rows: number }\n | { action: 'signal'; signal: string }\n | { action: 'close' };\n\nexport const FS_METHODS = [\n 'readFile',\n 'writeFile',\n 'stat',\n 'lstat',\n 'readdir',\n 'mkdir',\n 'rm',\n 'rename',\n 'realpath',\n 'symlink',\n 'readlink',\n 'exists',\n] as const;\n\nexport type FsMethod = (typeof FS_METHODS)[number];\n\nexport type ClientCall =\n | { op: 'spawn'; argv: string[]; options: SpawnRequestOptions }\n | { op: 'open-terminal'; argv: string[]; options: TerminalRequestOptions }\n | ({ op: 'terminal'; terminal: number } & TerminalAction)\n | { op: 'kill'; pid: number; signal: string }\n | { op: 'ps' }\n | { op: 'fs'; method: FsMethod; args: unknown[] }\n | { op: 'watch'; paths: string[]; recursive: boolean }\n | { op: 'unwatch'; watch: number }\n | { op: 'mount'; spec: MountSpec }\n | { op: 'umount'; target: string }\n | { op: 'mounts' }\n | { op: 'dial'; port: number; host?: string }\n | { op: 'serve-cdp'; runtime?: string }\n | { op: 'unserve-cdp'; registration: number }\n | { op: 'detach'; kill?: boolean };\n\nexport type ClientRequest = ClientCall & { id: number };\n\nexport interface ClientReply {\n id: number;\n result?: unknown;\n error?: string;\n code?: string;\n fd?: 1 | 2;\n bytes?: Uint8Array;\n started?: number;\n}\n\nexport type ClientMessage = { hello: ClientHello } | ClientRequest | TransportCall;\n\nexport interface WatchEvent {\n watch: number;\n change: WatchChange;\n}\n\nexport type KernelMessage = { hello: KernelHello } | ClientReply | WatchEvent | TransportReply;\n\nexport interface ProcessEntry {\n pid: number;\n ppid: number;\n pgid: number;\n sid: number;\n argv: string[];\n tty: string | null;\n started: number;\n state: 'S' | 'Z';\n memory: number;\n rss?: number;\n uid?: number;\n gid?: number;\n}\n\nexport interface MessagePortLike {\n postMessage(message: unknown, transfer?: Transferable[]): void;\n addEventListener(type: 'message' | 'close', handler: (event: MessageEvent) => void): void;\n start?(): void;\n close?(): void;\n}\n\nexport interface LockManagerLike {\n request(name: string, callback: () => Promise<unknown> | unknown): Promise<unknown>;\n}\n\nexport function locksOf(scope: object = globalThis): LockManagerLike | undefined {\n const locks = (scope as { navigator?: { locks?: LockManagerLike } }).navigator?.locks;\n return typeof locks?.request === 'function' ? locks : undefined;\n}\n\nexport function versionError(theirs: unknown): string | undefined {\n const major = Array.isArray(theirs) ? theirs[0] : undefined;\n if (major === PROTOCOL[0]) return undefined;\n const named = typeof major === 'number' ? `${major}.x` : 'without a version';\n return `slicc-kernel client protocol ${named} is not supported: this side speaks ${PROTOCOL.join('.')}`;\n}\n", "import { type CdpOpen, serveCdpPort } from '../cdp/port.ts';\nimport type { CdpHook } from '../cdp/types.ts';\nimport type { FsStat, UsersMode } from '../fs/types.ts';\nimport type { WatchChange } from '../fs/watch.ts';\nimport { RemoteTransport, type TransportReply } from '../kernel/net/remote-transport.ts';\nimport type {\n RealmTransport,\n RealmTransportRequest,\n RealmTransportResponse,\n} from '../kernel/net/transport.ts';\nimport type { MountEntry, MountSpec } from '../mount/mount-fs.ts';\nimport { type DialledSocket, type DialOptions, dialStream } from './dial-stream.ts';\nimport { type LoopbackFetchOptions, loopbackFetch } from './loopback-fetch.ts';\nimport {\n type ClientCall,\n type ClientReply,\n type FsMethod,\n type KernelHello,\n type LockManagerLike,\n locksOf,\n type MessagePortLike,\n PROTOCOL,\n type ProcessEntry,\n type TerminalAction,\n versionError,\n} from './protocol.ts';\n\nexport type { WatchChange } from '../fs/watch.ts';\nexport type { ProcessEntry } from './protocol.ts';\n\nexport class KernelGoneError extends Error {\n constructor(message = 'the slicc-kernel this client was attached to is gone') {\n super(message);\n this.name = 'KernelGoneError';\n }\n}\n\nexport class KernelCallError extends Error {\n readonly code: string | undefined;\n\n constructor(message: string, code?: string) {\n super(message);\n this.name = 'KernelCallError';\n this.code = code;\n }\n}\n\nexport interface AttachOptions {\n timeoutMs?: number;\n locks?: LockManagerLike | null;\n}\n\nexport interface SpawnOptions {\n cwd?: string;\n user?: string | number;\n env?: Record<string, string>;\n stdin?: string | Uint8Array;\n group?: 'new';\n pgid?: number;\n onStdout?: (bytes: Uint8Array) => void;\n onStderr?: (bytes: Uint8Array) => void;\n}\n\nexport interface SpawnedProcess {\n readonly pid: number;\n readonly pgid: number;\n readonly exited: Promise<number>;\n signal(name?: string): Promise<void>;\n}\n\nexport interface ClientRunOptions {\n cwd?: string;\n user?: string | number;\n env?: Record<string, string>;\n stdin?: string | Uint8Array;\n onStdout?: (text: string) => void;\n onStderr?: (text: string) => void;\n}\n\nexport interface ClientRunResult {\n pid: number;\n status: number;\n stdout: string;\n stderr: string;\n}\n\nexport interface ClientTerminalOptions {\n cwd?: string;\n user?: string | number;\n env?: Record<string, string>;\n cols?: number;\n rows?: number;\n onData?: (bytes: Uint8Array) => void;\n}\n\nexport interface ClientTerminal {\n readonly pid: number;\n readonly exited: Promise<number>;\n onData: ((bytes: Uint8Array) => void) | null;\n write(data: string | Uint8Array): void;\n resize(cols: number, rows: number): void;\n signal(name: string): void;\n close(): void;\n}\n\nexport interface ClientFs {\n readFile(path: string): Promise<Uint8Array>;\n readText(path: string): Promise<string>;\n writeFile(path: string, data: string | Uint8Array): Promise<void>;\n stat(path: string): Promise<FsStat>;\n lstat(path: string): Promise<FsStat>;\n readdir(path: string): Promise<string[]>;\n mkdir(path: string): Promise<void>;\n rm(path: string, options?: { force?: boolean }): Promise<void>;\n rename(from: string, to: string): Promise<void>;\n realpath(path: string): Promise<string>;\n symlink(target: string, path: string): Promise<void>;\n readlink(path: string): Promise<string>;\n exists(path: string): Promise<boolean>;\n watch(\n paths: string[],\n options: { recursive?: boolean },\n onChange: (change: WatchChange) => void\n ): Promise<{ close(): void }>;\n}\n\nexport type ClientFetchRequest = Omit<RealmTransportRequest, 'signal'> & { signal?: AbortSignal };\n\nexport interface KernelClient {\n readonly protocol: readonly [number, number];\n readonly transport: RealmTransport;\n readonly users: UsersMode;\n readonly closed: Promise<Error>;\n spawn(argv: string[], options?: SpawnOptions): Promise<SpawnedProcess>;\n run(argv: string[], options?: ClientRunOptions): Promise<ClientRunResult>;\n openTerminal(argv: string[], options?: ClientTerminalOptions): Promise<ClientTerminal>;\n ps(): Promise<ProcessEntry[]>;\n mount(spec: MountSpec): Promise<MountEntry>;\n umount(target: string): Promise<void>;\n mounts(): Promise<MountEntry[]>;\n kill(pid: number, signal?: string): Promise<void>;\n fetch(request: ClientFetchRequest): Promise<RealmTransportResponse>;\n dial(options: DialOptions): Promise<DialledSocket>;\n loopbackFetch(input: RequestInfo | URL, options: LoopbackFetchOptions): Promise<Response>;\n readonly fs: ClientFs;\n serveCdp(hook: CdpHook, options?: { runtime?: string }): Promise<{ close(): void }>;\n close(options?: { kill?: boolean }): Promise<void>;\n}\n\ninterface Pending {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n output?: (fd: 1 | 2, bytes: Uint8Array) => void;\n started?: (pid: number) => void;\n}\n\ntype Handlers = Omit<Pending, 'resolve' | 'reject'>;\n\nconst encoder = new TextEncoder();\nconst bytesOf = (data: string | Uint8Array) =>\n typeof data === 'string' ? encoder.encode(data) : data;\n\nconst UNAVAILABLE = {\n manualRedirects: false,\n encodedBodies: false,\n maxRequestBody: 0,\n unavailable: true,\n} as const;\n\nasync function holdLock(\n locks: LockManagerLike | undefined\n): Promise<{ name?: string; release(): void }> {\n if (!locks) return { release() {} };\n const name = `slicc-kernel-client:${crypto.randomUUID()}`;\n const granted = Promise.withResolvers<void>();\n const held = Promise.withResolvers<void>();\n void locks.request(name, () => {\n granted.resolve();\n return held.promise;\n });\n await granted.promise;\n return { name, release: () => held.resolve() };\n}\n\nfunction concat(chunks: Uint8Array[]): Uint8Array {\n const out = new Uint8Array(chunks.reduce((n, c) => n + c.length, 0));\n let at = 0;\n for (const chunk of chunks) {\n out.set(chunk, at);\n at += chunk.length;\n }\n return out;\n}\n\nclass Channel {\n readonly greeted = Promise.withResolvers<KernelHello>();\n readonly ended = Promise.withResolvers<Error>();\n remote: RemoteTransport | undefined;\n failure: Error | undefined;\n private readonly pending = new Map<number, Pending>();\n readonly watching = new Map<number, (change: WatchChange) => void>();\n readonly cdpHooks = new Map<number, CdpHook>();\n private readonly cdpOpen = new Set<() => void>();\n protocol: readonly [number, number] = PROTOCOL;\n private nextId = 0;\n private readonly port: MessagePortLike;\n private readonly release: () => void;\n\n constructor(port: MessagePortLike, release: () => void) {\n this.port = port;\n this.release = release;\n this.greeted.promise.catch(() => undefined);\n port.addEventListener('message', (event) => this.receive(event.data));\n port.addEventListener('close', () => this.end(new KernelGoneError()));\n port.start?.();\n }\n\n post(message: object): void {\n if (!this.failure) this.port.postMessage(message);\n }\n\n end(error: Error): void {\n if (this.failure) return;\n this.failure = error;\n this.greeted.reject(error);\n this.remote?.fail(error);\n for (const close of [...this.cdpOpen]) close();\n this.cdpOpen.clear();\n for (const call of this.pending.values()) call.reject(error);\n this.pending.clear();\n this.release();\n this.port.close?.();\n this.ended.resolve(error);\n }\n\n request(call: ClientCall, handlers: Handlers = {}): { id: number; done: Promise<unknown> } {\n const id = ++this.nextId;\n const { failure } = this;\n if (failure) return { id, done: Promise.reject(failure) };\n const done = new Promise((resolve, reject) => {\n this.pending.set(id, { resolve, reject, ...handlers });\n this.port.postMessage({ ...call, id });\n });\n return { id, done };\n }\n\n call(call: ClientCall): Promise<unknown> {\n return this.request(call).done;\n }\n\n private receive(data: {\n hello?: KernelHello;\n net?: unknown;\n bye?: string;\n watch?: number;\n change?: WatchChange;\n cdpOpen?: CdpOpen['cdpOpen'];\n port?: CdpOpen['port'];\n }): void {\n if (data.cdpOpen && data.port) {\n this.openCdp(data as CdpOpen);\n return;\n }\n if (data.watch !== undefined) {\n this.watching.get(data.watch)?.(data.change as WatchChange);\n return;\n }\n if (data.bye !== undefined) {\n this.end(new KernelGoneError(data.bye));\n return;\n }\n if (data.hello) {\n this.greeted.resolve(data.hello);\n return;\n }\n if (data.net !== undefined) {\n this.remote?.receive(data as TransportReply);\n return;\n }\n const reply = data as ClientReply;\n const call = this.pending.get(reply.id);\n if (!call) return;\n if (reply.fd !== undefined) {\n call.output?.(reply.fd, reply.bytes as Uint8Array);\n return;\n }\n if (reply.started !== undefined) {\n call.started?.(reply.started);\n return;\n }\n this.pending.delete(reply.id);\n if (reply.error !== undefined) call.reject(new KernelCallError(reply.error, reply.code));\n else call.resolve(reply.result);\n }\n\n private openCdp({ cdpOpen: { registration, ...request }, port }: CdpOpen): void {\n const hook = registration === undefined ? undefined : this.cdpHooks.get(registration);\n if (!hook || this.failure) {\n port.postMessage({ error: 'this client no longer serves CDP' });\n port.close();\n return;\n }\n const close = serveCdpPort(port, hook, request, () => this.cdpOpen.delete(close));\n this.cdpOpen.add(close);\n }\n}\n\nasync function serveCdpOn(\n channel: Channel,\n hook: CdpHook,\n options: { runtime?: string }\n): Promise<{ close(): void }> {\n await since(channel, 5, 'CDP serving', async () => {});\n const req = {\n op: 'serve-cdp' as const,\n ...(options.runtime ? { runtime: options.runtime } : {}),\n };\n const { id, done } = channel.request(req);\n channel.cdpHooks.set(id, hook);\n try {\n await done;\n } catch (error) {\n channel.cdpHooks.delete(id);\n throw error;\n }\n return {\n close: () => {\n if (!channel.cdpHooks.delete(id)) return;\n void channel.call({ op: 'unserve-cdp', registration: id }).catch(() => undefined);\n },\n };\n}\n\nasync function dialOn(channel: Channel, { port, host }: DialOptions): Promise<DialledSocket> {\n const req = { op: 'dial' as const, port, ...(host ? { host } : {}) };\n return dialStream((await since(channel, 4, 'dial', () => channel.call(req))) as MessagePort);\n}\n\nasync function spawnOn(\n channel: Channel,\n argv: string[],\n opts: SpawnOptions\n): Promise<SpawnedProcess> {\n const { onStdout, onStderr, stdin, group: _, ...rest } = opts;\n if (opts.pgid !== undefined)\n await since(channel, 3, 'spawn into a process group', async () => {});\n if (opts.user !== undefined) await since(channel, 8, 'spawn as a user', async () => {});\n const started = Promise.withResolvers<number>();\n const options = { ...rest, ...(stdin !== undefined ? { stdin: bytesOf(stdin) } : {}) };\n const { done } = channel.request(\n { op: 'spawn', argv, options },\n {\n output: (fd, bytes) => (fd === 1 ? onStdout : onStderr)?.(bytes),\n started: started.resolve,\n }\n );\n done.catch(started.reject);\n const pid = await started.promise;\n const pgid = opts.pgid ?? pid;\n return {\n pid,\n pgid,\n exited: done as Promise<number>,\n signal: async (name = 'SIGTERM') =>\n void (await channel.call({ op: 'kill', pid: -pgid, signal: name })),\n };\n}\n\nasync function runOn(\n channel: Channel,\n argv: string[],\n opts: ClientRunOptions\n): Promise<ClientRunResult> {\n const { onStdout, onStderr, ...rest } = opts;\n const chunks: Record<1 | 2, Uint8Array[]> = { 1: [], 2: [] };\n const live = { 1: new TextDecoder(), 2: new TextDecoder() };\n const tee = (fd: 1 | 2, on?: (text: string) => void) => (bytes: Uint8Array) => {\n chunks[fd].push(bytes);\n on?.(live[fd].decode(bytes, { stream: true }));\n };\n const child = await spawnOn(channel, argv, {\n ...rest,\n onStdout: tee(1, onStdout),\n onStderr: tee(2, onStderr),\n });\n const status = await child.exited;\n const text = (fd: 1 | 2) => new TextDecoder().decode(concat(chunks[fd]));\n return { pid: child.pid, status, stdout: text(1), stderr: text(2) };\n}\n\nasync function terminalOn(\n channel: Channel,\n argv: string[],\n opts: ClientTerminalOptions\n): Promise<ClientTerminal> {\n const { onData, ...options } = opts;\n if (opts.user !== undefined) await since(channel, 8, 'a terminal as a user', async () => {});\n let listener = onData ?? null;\n const backlog: Uint8Array[] = [];\n const started = Promise.withResolvers<number>();\n const { id, done } = channel.request(\n { op: 'open-terminal', argv, options },\n {\n output: (_fd, bytes) => (listener ? listener(bytes) : backlog.push(bytes)),\n started: started.resolve,\n }\n );\n done.catch(started.reject);\n const pid = await started.promise;\n const send = (action: TerminalAction) =>\n void channel.call({ op: 'terminal', terminal: id, ...action }).catch(() => undefined);\n return {\n pid,\n exited: done as Promise<number>,\n get onData() {\n return listener;\n },\n set onData(next) {\n listener = next;\n if (next) for (const bytes of backlog.splice(0)) next(bytes);\n },\n write: (data) => send({ action: 'write', bytes: bytesOf(data) }),\n resize: (cols, rows) => send({ action: 'resize', cols, rows }),\n signal: (name) => send({ action: 'signal', signal: name }),\n close: () => send({ action: 'close' }),\n };\n}\n\nfunction fsOn(channel: Channel): ClientFs {\n const fs = (method: FsMethod, ...args: unknown[]) => channel.call({ op: 'fs', method, args });\n const done = async (method: FsMethod, ...args: unknown[]) => void (await fs(method, ...args));\n return {\n readFile: (path) => fs('readFile', path) as Promise<Uint8Array>,\n readText: async (path) => new TextDecoder().decode((await fs('readFile', path)) as Uint8Array),\n writeFile: (path, data) => done('writeFile', path, data),\n stat: (path) => fs('stat', path) as Promise<FsStat>,\n lstat: (path) => fs('lstat', path) as Promise<FsStat>,\n readdir: (path) => fs('readdir', path) as Promise<string[]>,\n mkdir: (path) => done('mkdir', path),\n rm: (path, o = {}) => done('rm', path, o.force === true),\n rename: (from, to) => done('rename', from, to),\n realpath: (path) => fs('realpath', path) as Promise<string>,\n symlink: (target, path) => done('symlink', target, path),\n readlink: (path) => fs('readlink', path) as Promise<string>,\n exists: (path) => fs('exists', path) as Promise<boolean>,\n async watch(paths, options, onChange) {\n if (channel.protocol[1] < 1) {\n throw new KernelCallError(\n `this kernel speaks protocol ${channel.protocol.join('.')}, which has no watch`,\n 'ENOSYS'\n );\n }\n const { id, done } = channel.request({\n op: 'watch',\n paths,\n recursive: options.recursive === true,\n });\n channel.watching.set(id, onChange);\n try {\n await done;\n } catch (error) {\n channel.watching.delete(id);\n throw error;\n }\n return {\n close: () => {\n if (!channel.watching.delete(id)) return;\n void channel.call({ op: 'unwatch', watch: id }).catch(() => undefined);\n },\n };\n },\n };\n}\n\nfunction since(channel: Channel, minor: number, what: string, run: () => Promise<unknown>) {\n if (channel.protocol[1] < minor) {\n return Promise.reject(\n new KernelCallError(\n `this kernel speaks protocol ${channel.protocol.join('.')}, which has no ${what}`,\n 'ENOSYS'\n )\n );\n }\n return run();\n}\n\nasync function greet(\n channel: Channel,\n lock: string | undefined,\n timeoutMs: number\n): Promise<KernelHello> {\n channel.post({ hello: { protocol: PROTOCOL, ...(lock ? { lock } : {}) } });\n const timer = setTimeout(\n () =>\n channel.end(\n new KernelGoneError(`no slicc-kernel answered on this port within ${timeoutMs} ms`)\n ),\n timeoutMs\n );\n let hello: KernelHello;\n try {\n hello = await channel.greeted.promise;\n } finally {\n clearTimeout(timer);\n }\n const refused = hello.error ?? versionError(hello.protocol);\n if (refused) {\n const error = new Error(refused);\n channel.end(error);\n throw error;\n }\n return hello;\n}\n\nexport async function attachKernel(\n port: MessagePortLike,\n options: AttachOptions = {}\n): Promise<KernelClient> {\n const locks = options.locks === null ? undefined : (options.locks ?? locksOf());\n const own = await holdLock(locks);\n const channel = new Channel(port, own.release);\n const hello = await greet(channel, own.name, options.timeoutMs ?? 10_000);\n channel.protocol = hello.protocol;\n if (hello.lock && locks) void locks.request(hello.lock, () => channel.end(new KernelGoneError()));\n const transport = new RemoteTransport(\n { postMessage: (call) => channel.post(call) },\n hello.traits ?? UNAVAILABLE\n );\n channel.remote = transport;\n return {\n protocol: hello.protocol,\n transport,\n users: hello.users ?? 'off',\n closed: channel.ended.promise,\n spawn: (argv, opts = {}) => spawnOn(channel, argv, opts),\n run: (argv, opts = {}) => runOn(channel, argv, opts),\n openTerminal: (argv, opts = {}) => terminalOn(channel, argv, opts),\n ps: () => channel.call({ op: 'ps' }) as Promise<ProcessEntry[]>,\n mount: (spec) =>\n since(channel, 2, 'mount', () => channel.call({ op: 'mount', spec })) as Promise<MountEntry>,\n umount: async (target) =>\n void (await since(channel, 2, 'umount', () => channel.call({ op: 'umount', target }))),\n mounts: () =>\n since(channel, 2, 'mounts', () => channel.call({ op: 'mounts' })) as Promise<MountEntry[]>,\n kill: async (pid, signal = 'SIGTERM') => void (await channel.call({ op: 'kill', pid, signal })),\n fetch: (req) => {\n const { signal, ...rest } = req;\n return transport.fetch({ ...rest, signal: signal ?? new AbortController().signal });\n },\n dial: (options) => dialOn(channel, options),\n loopbackFetch: (input, options) => loopbackFetch((o) => dialOn(channel, o), input, options),\n fs: fsOn(channel),\n serveCdp: (hook, options = {}) => serveCdpOn(channel, hook, options),\n async close(o = {}) {\n if (channel.failure) return;\n await channel\n .call({ op: 'detach', ...(o.kill ? { kill: true } : {}) })\n .catch(() => undefined);\n channel.end(new KernelGoneError('this client is closed'));\n },\n };\n}\n", "import { BODY_IDLE_MS, readWithin } from './body-idle.ts';\nimport type {\n HeaderList,\n RealmTransport,\n RealmTransportRequest,\n RealmTransportResponse,\n} from './kernel/net/transport.ts';\n\nexport interface LocalProxyOptions {\n url: string;\n key: string;\n fetch?: typeof globalThis.fetch;\n}\n\nexport interface LocalProxyCheckOptions extends LocalProxyOptions {\n permissions?: Pick<Permissions, 'query'>;\n}\n\nexport interface LocalProxyTransportOptions extends LocalProxyOptions {\n maxRequestBody?: number;\n bodyIdleMs?: number;\n}\n\nexport interface LocalProxyProbe {\n rawFetch: number;\n requestBodyStreaming: boolean;\n maxRequestBodyBytes: number;\n kernelTunnel?: number;\n kernelPort?: number;\n cdp?: number;\n}\n\nexport type LocalProxyStatus =\n | { state: 'ready'; probe: LocalProxyProbe }\n | { state: 'blocked' }\n | { state: 'unreachable'; permission: 'granted' | 'prompt' | 'unknown' }\n | { state: 'refused'; status: number; error: string }\n | { state: 'incompatible' };\n\nconst PATH = '/api/fetch-proxy';\nconst RAW_CONTENT_TYPE = 'application/vnd.slicc.raw-fetch';\nconst MAX_HEAD = 1024 * 1024;\nconst MAX_REQUEST_BODY = 64 * 1024 * 1024;\nconst PERMISSIONS = ['loopback-network', 'local-network-access'];\nconst LOOPBACK_PAGE = /^(127\\.\\d+\\.\\d+\\.\\d+|localhost|\\[::1\\])$/;\n\ninterface ResponseHead {\n status: number;\n statusText: string;\n headers: Array<[string, string]>;\n}\n\nconst failure = (message: string, status = 502) =>\n Object.assign(new Error(`local proxy: ${message}`), { status });\n\nfunction encodeHead(url: string, method: string, headers: HeaderList): string {\n return JSON.stringify({ url, method, headers }).replace(\n /[\\u007f-\uFFFF]/g,\n (c) => `\\\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}`\n );\n}\n\nfunction hopHeaders(options: LocalProxyOptions, extra: Record<string, string>): Headers {\n return new Headers({ 'X-Bridge-Token': options.key, ...extra });\n}\n\nfunction send(options: LocalProxyOptions) {\n return options.fetch ?? globalThis.fetch.bind(globalThis);\n}\n\nasync function refusalMessage(response: Response): Promise<string> {\n const text = await response.text().catch(() => '');\n try {\n const parsed = JSON.parse(text) as { error?: unknown };\n if (typeof parsed.error === 'string') return parsed.error;\n } catch {}\n return text || response.statusText || `answered ${response.status}`;\n}\n\nasync function refusal(response: Response): Promise<Error> {\n return failure(await refusalMessage(response), response.ok ? 502 : response.status);\n}\n\nasync function permission(permissions: Pick<Permissions, 'query'> | undefined): Promise<string> {\n if (!permissions) return 'unknown';\n for (const name of PERMISSIONS) {\n try {\n return (await permissions.query({ name } as PermissionDescriptor)).state;\n } catch {}\n }\n return 'unknown';\n}\n\nfunction isHead(value: unknown): value is ResponseHead {\n const head = value as Partial<ResponseHead> | null;\n return (\n !!head &&\n typeof head.status === 'number' &&\n typeof head.statusText === 'string' &&\n Array.isArray(head.headers) &&\n head.headers.every(\n (pair) =>\n Array.isArray(pair) &&\n pair.length === 2 &&\n typeof pair[0] === 'string' &&\n typeof pair[1] === 'string'\n )\n );\n}\n\nfunction concat(a: Uint8Array, b: Uint8Array): Uint8Array {\n const out = new Uint8Array(a.byteLength + b.byteLength);\n out.set(a);\n out.set(b, a.byteLength);\n return out;\n}\n\nasync function readHead(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n idleMs: number\n): Promise<{ head: ResponseHead; rest: Uint8Array }> {\n let buffer: Uint8Array = new Uint8Array(0);\n for (;;) {\n if (buffer.byteLength >= 4) {\n const length = new DataView(buffer.buffer, buffer.byteOffset, 4).getUint32(0);\n if (length > MAX_HEAD) throw failure(`response head of ${length} bytes`);\n if (buffer.byteLength >= 4 + length) {\n let head: unknown;\n try {\n head = JSON.parse(new TextDecoder().decode(buffer.subarray(4, 4 + length)));\n } catch {}\n if (!isHead(head)) throw failure('malformed response head');\n return { head, rest: buffer.subarray(4 + length) };\n }\n }\n const next = await readWithin(reader, idleMs);\n if (next.done) throw failure('closed before the response head');\n buffer = concat(buffer, next.value);\n }\n}\n\nasync function* chunks(\n rest: Uint8Array,\n reader: ReadableStreamDefaultReader<Uint8Array>,\n idleMs: number\n): AsyncGenerator<Uint8Array> {\n try {\n if (rest.byteLength > 0) yield rest;\n for (\n let next = await readWithin(reader, idleMs);\n !next.done;\n next = await readWithin(reader, idleMs)\n ) {\n if (next.value.byteLength > 0) yield next.value;\n }\n } finally {\n await reader.cancel().catch(() => undefined);\n }\n}\n\nexport async function checkLocalProxy(options: LocalProxyCheckOptions): Promise<LocalProxyStatus> {\n const onLoopback = LOOPBACK_PAGE.test(globalThis.location?.hostname ?? '');\n const permissions = onLoopback\n ? undefined\n : (options.permissions ?? globalThis.navigator?.permissions);\n if ((await permission(permissions)) === 'denied') return { state: 'blocked' };\n let response: Response;\n try {\n response = await send(options)(new URL(PATH, options.url), {\n method: 'POST',\n headers: hopHeaders(options, { 'X-Slicc-Raw-Probe': '1' }),\n credentials: 'omit',\n mode: 'cors',\n });\n } catch {\n const now = await permission(permissions);\n if (now === 'denied') return { state: 'blocked' };\n return {\n state: 'unreachable',\n permission: now === 'granted' || now === 'prompt' ? now : 'unknown',\n };\n }\n if (!response.ok) {\n return { state: 'refused', status: response.status, error: await refusalMessage(response) };\n }\n const reply = (await response.json().catch(() => null)) as Partial<LocalProxyProbe> | null;\n if (\n !reply ||\n typeof reply.rawFetch !== 'number' ||\n reply.rawFetch < 1 ||\n typeof reply.requestBodyStreaming !== 'boolean' ||\n typeof reply.maxRequestBodyBytes !== 'number'\n ) {\n return { state: 'incompatible' };\n }\n return {\n state: 'ready',\n probe: {\n rawFetch: reply.rawFetch,\n requestBodyStreaming: reply.requestBodyStreaming,\n maxRequestBodyBytes: reply.maxRequestBodyBytes,\n ...(typeof reply.kernelTunnel === 'number' ? { kernelTunnel: reply.kernelTunnel } : {}),\n ...(typeof reply.kernelPort === 'number' ? { kernelPort: reply.kernelPort } : {}),\n ...(typeof reply.cdp === 'number' ? { cdp: reply.cdp } : {}),\n },\n };\n}\n\nexport async function probeLocalProxy(\n options: LocalProxyCheckOptions\n): Promise<LocalProxyProbe | null> {\n const status = await checkLocalProxy(options);\n return status.state === 'ready' ? status.probe : null;\n}\n\nexport function localProxyTransport(options: LocalProxyTransportOptions): RealmTransport {\n const endpoint = new URL(PATH, options.url);\n return {\n traits: {\n manualRedirects: true,\n encodedBodies: false,\n maxRequestBody: options.maxRequestBody ?? MAX_REQUEST_BODY,\n },\n async fetch(request: RealmTransportRequest): Promise<RealmTransportResponse> {\n let response: Response;\n try {\n response = await send(options)(endpoint, {\n method: 'POST',\n headers: hopHeaders(options, {\n 'X-Slicc-Raw-Request': encodeHead(request.url, request.method, request.headers),\n }),\n ...(request.body ? { body: request.body as BodyInit } : {}),\n signal: request.signal,\n credentials: 'omit',\n mode: 'cors',\n });\n } catch (e) {\n if (request.signal.aborted) throw e;\n throw failure(`${endpoint.origin} is unreachable or refuses this origin`);\n }\n const type = response.headers.get('content-type') ?? '';\n if (response.status !== 200 || !type.startsWith(RAW_CONTENT_TYPE) || !response.body) {\n throw await refusal(response);\n }\n const reader = response.body.getReader();\n const idleMs = options.bodyIdleMs ?? BODY_IDLE_MS;\n let framed: { head: ResponseHead; rest: Uint8Array };\n try {\n framed = await readHead(reader, idleMs);\n } catch (e) {\n await reader.cancel().catch(() => undefined);\n throw e;\n }\n const body = chunks(framed.rest, reader, idleMs);\n return {\n status: framed.head.status,\n statusText: framed.head.statusText,\n headers: framed.head.headers,\n body,\n cancel: async () => {\n await body.return(undefined);\n await reader.cancel().catch(() => undefined);\n },\n };\n },\n };\n}\n", "import {\n DRIVER_PROTOCOL,\n type DriverAttr,\n type DriverCapabilities,\n type DriverEntry,\n type DriverOwner,\n type DriverRequest,\n type DriverStatfs,\n driverVersionError,\n type KernelDriverHello,\n type MountRequestInfo,\n} from './protocol.ts';\n\nexport type {\n DriverAttr,\n DriverCapabilities,\n DriverEntry,\n DriverOwner,\n DriverStatfs,\n MountRequestInfo,\n} from './protocol.ts';\n\nexport interface OpenFlags {\n write: boolean;\n create: boolean;\n truncate: boolean;\n exclusive: boolean;\n ifMatch?: string;\n owner?: DriverOwner;\n}\n\nexport interface FilesystemHandlers {\n mount?(\n info: MountRequestInfo\n ): Promise<DriverCapabilities | undefined> | DriverCapabilities | undefined;\n getattr(path: string): Promise<DriverAttr>;\n readdir(path: string): Promise<DriverEntry[]>;\n open(path: string, flags: OpenFlags): Promise<number>;\n read(fh: number, offset: number, size: number): Promise<Uint8Array>;\n write(fh: number, offset: number, bytes: Uint8Array): Promise<void>;\n release(fh: number): Promise<void>;\n mkdir(path: string, owner?: DriverOwner): Promise<void>;\n rmdir(path: string): Promise<void>;\n unlink(path: string): Promise<void>;\n rename(from: string, to: string): Promise<void>;\n link?(from: string, to: string): Promise<void>;\n symlink?(target: string, path: string, owner?: DriverOwner): Promise<void>;\n readlink?(path: string): Promise<string>;\n setattr?(path: string, attr: DriverSetAttr): Promise<void>;\n statfs?(): Promise<DriverStatfs>;\n}\n\nexport interface DriverSetAttr {\n mode?: number;\n mtime?: number;\n size?: number;\n uid?: number;\n gid?: number;\n}\n\nfunction ownerOf(req: DriverOwner): DriverOwner | undefined {\n const owner = {\n ...(req.uid !== undefined ? { uid: req.uid } : {}),\n ...(req.gid !== undefined ? { gid: req.gid } : {}),\n ...(req.mode !== undefined ? { mode: req.mode } : {}),\n };\n return Object.keys(owner).length > 0 ? owner : undefined;\n}\n\nfunction withOwner<T extends object>(base: T, owner: DriverOwner | undefined): T {\n return owner ? { ...base, owner } : base;\n}\n\nexport interface DriverPort {\n postMessage(message: unknown, transfer?: Transferable[]): void;\n addEventListener(type: 'message', handler: (event: MessageEvent) => void): void;\n start?(): void;\n}\n\nexport interface ServedFilesystem {\n invalidate(paths: string[] | true): void;\n}\n\nexport function fsError(code: string, message = code): Error & { code: string } {\n return Object.assign(new Error(message), { code });\n}\n\nasync function dispatch(h: FilesystemHandlers, req: DriverRequest): Promise<unknown> {\n switch (req.op) {\n case 'getattr':\n return h.getattr(req.path);\n case 'readdir':\n return h.readdir(req.path);\n case 'open':\n return h.open(\n req.path,\n withOwner(\n {\n write: req.write,\n create: req.create,\n truncate: req.truncate,\n exclusive: req.exclusive,\n ...(req.ifMatch !== undefined ? { ifMatch: req.ifMatch } : {}),\n },\n ownerOf(req)\n )\n );\n case 'read':\n return h.read(req.fh, req.offset, req.size);\n case 'write':\n return h.write(req.fh, req.offset, req.bytes);\n case 'release':\n return h.release(req.fh);\n case 'mkdir':\n return ownerOf(req) ? h.mkdir(req.path, ownerOf(req)) : h.mkdir(req.path);\n case 'rmdir':\n return h.rmdir(req.path);\n case 'unlink':\n return h.unlink(req.path);\n case 'rename':\n return h.rename(req.from, req.to);\n case 'link':\n if (!h.link) throw fsError('EPERM', 'this file system has no hard links');\n return h.link(req.from, req.to);\n case 'symlink':\n if (!h.symlink) throw fsError('EPERM', 'this file system has no symlinks');\n return ownerOf(req)\n ? h.symlink(req.target, req.path, ownerOf(req))\n : h.symlink(req.target, req.path);\n case 'readlink':\n if (!h.readlink) throw fsError('EINVAL', `${req.path} is not a symlink`);\n return h.readlink(req.path);\n case 'setattr':\n return h.setattr?.(req.path, {\n ...(req.mode !== undefined ? { mode: req.mode } : {}),\n ...(req.mtime !== undefined ? { mtime: req.mtime } : {}),\n ...(req.size !== undefined ? { size: req.size } : {}),\n ...(req.uid !== undefined ? { uid: req.uid } : {}),\n ...(req.gid !== undefined ? { gid: req.gid } : {}),\n });\n case 'statfs':\n return h.statfs?.() ?? null;\n default:\n throw fsError('ENOSYS', `unknown driver op ${(req as { op: string }).op}`);\n }\n}\n\nexport function serveFilesystem(\n port: DriverPort,\n handlers: FilesystemHandlers,\n capabilities: DriverCapabilities = {},\n options: { owned?: boolean } = {}\n): ServedFilesystem {\n let open = false;\n const reply = (message: object, transfer: Transferable[] = []) =>\n port.postMessage(message, transfer);\n async function hello(message: KernelDriverHello): Promise<void> {\n const refused = driverVersionError(message.protocol);\n if (refused) {\n reply({ hello: { protocol: DRIVER_PROTOCOL, error: refused, errno: 'EPROTO' } });\n return;\n }\n try {\n const refined = await handlers.mount?.(message.mount);\n open = true;\n reply({\n hello: { protocol: DRIVER_PROTOCOL, capabilities: { ...capabilities, ...refined } },\n });\n } catch (err) {\n const code = (err as { code?: unknown })?.code;\n reply({\n hello: {\n protocol: DRIVER_PROTOCOL,\n error: err instanceof Error ? err.message : String(err),\n errno: typeof code === 'string' ? code : 'EIO',\n },\n });\n }\n }\n port.addEventListener('message', (event) => {\n const data = event.data as { hello?: KernelDriverHello } & DriverRequest;\n if (data.hello) {\n void hello(data.hello);\n return;\n }\n if (!open) return;\n dispatch(handlers, data).then(\n (result) => {\n if (result instanceof Uint8Array) {\n const whole = result.byteOffset === 0 && result.byteLength === result.buffer.byteLength;\n const bytes = options.owned && whole ? result : result.slice();\n reply({ id: data.id, result: bytes }, [bytes.buffer]);\n } else reply({ id: data.id, result: result ?? null });\n },\n (err: unknown) => {\n const code = (err as { code?: unknown })?.code;\n reply({\n id: data.id,\n errno: typeof code === 'string' ? code : 'EIO',\n message: err instanceof Error ? err.message : String(err),\n });\n }\n );\n });\n port.start?.();\n return { invalidate: (paths) => reply({ invalidate: paths }) };\n}\n", "import { type FilesystemHandlers, fsError, type OpenFlags, serveFilesystem } from './driver.ts';\nimport { type MediumHandlers, mediumSlot } from './medium.ts';\nimport type { MountSpec, OpenedDriver } from './mount-fs.ts';\nimport type { DriverAttr, DriverCapabilities, DriverEntry, DriverStatfs } from './protocol.ts';\n\nexport interface HostfsGrant {\n url: string;\n token: string;\n readonly?: boolean;\n capabilities?: DriverCapabilities;\n}\n\nexport interface HostfsPortGrant {\n port: MessagePort;\n token?: string;\n capabilities?: DriverCapabilities;\n}\n\nexport type HostfsGrantHook = (\n source: string,\n options: { readonly: boolean }\n) => Promise<HostfsGrant | HostfsPortGrant>;\n\nexport type FetchLike = (url: string, init: RequestInit) => Promise<Response>;\n\nexport interface HostfsEvent {\n paths?: string[];\n all?: boolean;\n ping?: number;\n}\n\nexport interface HostfsTransport {\n readonly capabilities: DriverCapabilities;\n readonly token: string;\n readonly maxIo: number;\n readonly gone?: boolean;\n retire?(why: string): void;\n cleanup?(op: string, body: Record<string, unknown>): Promise<unknown>;\n call<T>(op: string, body?: Record<string, unknown>, handle?: boolean): Promise<T>;\n read(fh: number, offset: number, size: number, ifMatch?: string): Promise<Uint8Array>;\n write(fh: number, offset: number, bytes: Uint8Array): Promise<void>;\n watch(\n signal: AbortSignal,\n onEvent: (event: HostfsEvent) => void,\n onOpen?: () => void\n ): Promise<void>;\n}\n\nexport type HostfsConnect = (\n source: string,\n options: { readonly: boolean }\n) => Promise<HostfsTransport>;\n\nexport const HOSTFS_IO = 16 * 1024 * 1024;\n\nconst codeOf = (err: unknown) => (err as { code?: unknown } | null)?.code;\n\nexport const unreachable = (err: unknown) => codeOf(err) === 'ENOTCONN';\n\nfunction rel(path: string): string {\n return path.replace(/^\\/+/, '');\n}\n\nexport class HostfsClient implements HostfsTransport {\n private grant: HostfsGrant;\n private readonly regrant: () => Promise<HostfsGrant>;\n private readonly fetch: FetchLike;\n\n constructor(grant: HostfsGrant, regrant: () => Promise<HostfsGrant>, fetch: FetchLike) {\n this.grant = grant;\n this.regrant = regrant;\n this.fetch = fetch;\n }\n\n get capabilities(): DriverCapabilities {\n return this.grant.capabilities ?? {};\n }\n\n get token(): string {\n return this.grant.token;\n }\n\n get maxIo(): number {\n return this.capabilities.maxIo ?? HOSTFS_IO;\n }\n\n private retired: string | undefined;\n private readonly stop = new AbortController();\n\n get gone(): boolean {\n return this.retired !== undefined;\n }\n\n retire(why: string): void {\n this.retired ??= why;\n this.stop.abort();\n }\n\n private async send(\n path: string,\n init: RequestInit,\n handle = false,\n retried = false,\n cleanup = false\n ): Promise<Response> {\n if (this.retired && !cleanup) throw fsError('ENOTCONN', this.retired);\n const stop = cleanup ? undefined : this.stop.signal;\n const signal =\n init.signal && stop ? AbortSignal.any([init.signal, stop]) : (init.signal ?? stop);\n let response: Response;\n try {\n response = await this.fetch(`${this.grant.url}${path}`, {\n ...init,\n ...(signal ? { signal } : {}),\n credentials: 'omit',\n headers: {\n ...(init.headers as Record<string, string>),\n 'X-Hostfs-Token': this.grant.token,\n },\n });\n } catch (err) {\n throw fsError('ENOTCONN', `the host proxy is unreachable: ${(err as Error).message}`);\n }\n if (response.ok) return response;\n if (response.headers.get('X-Proxy-Error')) {\n await response.body?.cancel();\n if (retried || response.status !== 403) {\n throw fsError('EACCES', `the host proxy refused this folder (${response.status})`);\n }\n this.grant = await this.regrant();\n if (handle)\n throw fsError('ESTALE', 'the folder was granted again, so its open files are gone');\n return this.send(path, init, false, true);\n }\n const errno = response.headers.get('X-Hostfs-Errno') ?? 'EIO';\n const body = (await response.json().catch(() => ({}))) as { message?: unknown };\n throw fsError(errno, typeof body.message === 'string' ? body.message : errno);\n }\n\n async call<T>(op: string, body: Record<string, unknown> = {}, handle = false): Promise<T> {\n const response = await this.send(\n '/api/hostfs',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ op, ...body }),\n },\n handle\n );\n return (await response.json()) as T;\n }\n\n async cleanup(op: string, body: Record<string, unknown>): Promise<unknown> {\n const response = await this.send(\n '/api/hostfs',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ op, ...body }),\n },\n true,\n false,\n true\n );\n return response.json().catch(() => null);\n }\n\n async read(fh: number, offset: number, size: number, ifMatch?: string): Promise<Uint8Array> {\n const response = await this.send(\n '/api/hostfs',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ op: 'read', fh, offset, size, ...(ifMatch ? { ifMatch } : {}) }),\n },\n true\n );\n return new Uint8Array(await response.arrayBuffer());\n }\n\n async write(fh: number, offset: number, bytes: Uint8Array): Promise<void> {\n const response = await this.send(\n '/api/hostfs/write',\n {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/octet-stream',\n 'X-Hostfs-Request': JSON.stringify({ fh, offset }),\n },\n body: bytes as BodyInit,\n },\n true\n );\n await response.body?.cancel();\n }\n\n async watch(\n signal: AbortSignal,\n onEvent: (event: HostfsEvent) => void,\n onOpen: () => void = () => undefined\n ): Promise<void> {\n const response = await this.send('/api/hostfs/watch', { method: 'POST', signal });\n onOpen();\n const reader = (response.body as ReadableStream<Uint8Array>).getReader();\n const decoder = new TextDecoder();\n let buffered = '';\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) return;\n buffered += decoder.decode(value, { stream: true });\n let end = buffered.indexOf('\\n');\n while (end >= 0) {\n const line = buffered.slice(0, end).trim();\n buffered = buffered.slice(end + 1);\n if (line) onEvent(JSON.parse(line) as HostfsEvent);\n end = buffered.indexOf('\\n');\n }\n }\n } catch (err) {\n if (signal.aborted) return;\n throw fsError('ENOTCONN', `the host proxy's watch broke: ${(err as Error).message}`);\n } finally {\n reader.releaseLock();\n }\n }\n}\n\ninterface Remote {\n client: HostfsTransport;\n token: string;\n fh: number;\n etag: string | undefined;\n restore: Restore | undefined;\n}\n\ntype Restore = { path: string; mode: number; was: DriverAttr };\n\nexport const RESTORE_AGAIN_MS = 30_000;\n\nexport function hostfsHandlers(\n current: () => HostfsTransport,\n againMs = RESTORE_AGAIN_MS\n): MediumHandlers {\n const handles = new Map<number, Remote>();\n let nextFh = 0;\n const fresh = (remote: Remote): Remote => {\n if (remote.client.token === remote.token && !remote.client.gone) return remote;\n throw fsError('ESTALE', 'the folder was granted again, so this open file is gone');\n };\n const live = (fh: number): Remote => {\n const remote = handles.get(fh);\n if (!remote) throw fsError('EBADF', `handle ${fh}`);\n return fresh(remote);\n };\n const call = <T>(op: string, body: Record<string, unknown> = {}) => current().call<T>(op, body);\n const same = (was: DriverAttr, mode: number, seen: DriverAttr | null) =>\n seen?.mode === (mode | 0o200) &&\n (was.ino !== undefined && seen.ino !== undefined\n ? seen.ino === was.ino\n : seen.size === was.size && seen.mtime === was.mtime);\n const settle = (client: HostfsTransport, { was, ...restore }: Restore) =>\n client.call('setattr', restore).catch((err: unknown) => {\n if (!client.gone || !client.cleanup) throw err;\n void client.cleanup('setattr', restore).catch(() => {});\n const timer = setTimeout(async () => {\n const seen = (await client\n .cleanup?.('stat', { path: restore.path })\n .catch(() => null)) as DriverAttr | null;\n if (same(was, restore.mode, seen))\n void client.cleanup?.('setattr', restore).catch(() => {});\n }, againMs) as { unref?: () => void };\n timer.unref?.();\n });\n async function writable(client: HostfsTransport, path: string, flags: OpenFlags) {\n const { ifMatch: _, ...asked } = flags;\n const opening = () =>\n client.call<{ fh: number; attr?: DriverAttr }>('open', { path: rel(path), ...asked });\n try {\n return { opened: await opening(), restore: undefined };\n } catch (err) {\n if (!flags.write || codeOf(err) !== 'EACCES') throw err;\n const was = await client.call<DriverAttr>('stat', { path: rel(path) });\n const mode = was.mode ?? 0;\n if (mode & 0o200) throw err;\n const restore = { path: rel(path), mode, was };\n const opened = await client\n .call('setattr', { path: rel(path), mode: mode | 0o200 })\n .then(opening)\n .catch(async (again: unknown) => {\n await settle(client, restore).catch(() => {});\n throw again;\n });\n return { opened, restore };\n }\n }\n const handlers: MediumHandlers = {\n getattr: async (path) => await call<DriverAttr>('stat', { path: rel(path) }),\n async readdir(path) {\n const { entries } = await call<{ entries: Array<{ name: string; attr: DriverAttr }> }>(\n 'list',\n { path: rel(path) }\n );\n return entries.map(({ name, attr }): DriverEntry => ({ name, kind: attr.kind, attr }));\n },\n async open(path: string, flags: OpenFlags) {\n const client = current();\n const token = client.token;\n const { opened, restore } = await writable(client, path, flags);\n if (flags.ifMatch !== undefined && opened.attr?.etag !== flags.ifMatch) {\n await client.call('release', { fh: opened.fh }, true);\n throw fsError('ESTALE', `${path} changed on the host while it was being read`);\n }\n handles.set(++nextFh, {\n client,\n token,\n fh: opened.fh,\n etag: flags.write ? undefined : opened.attr?.etag,\n restore,\n });\n return nextFh;\n },\n async read(fh, offset, size) {\n const remote = live(fh);\n return remote.client.read(\n remote.fh,\n offset,\n Math.min(size, remote.client.maxIo),\n remote.etag\n );\n },\n async write(fh, offset, bytes) {\n const remote = live(fh);\n const most = remote.client.maxIo;\n for (let at = 0; at < bytes.length; at += most) {\n await remote.client.write(remote.fh, offset + at, bytes.subarray(at, at + most));\n }\n },\n async release(fh) {\n const remote = handles.get(fh);\n if (!remote) throw fsError('EBADF', `handle ${fh}`);\n handles.delete(fh);\n try {\n await fresh(remote).client.call('release', { fh: remote.fh }, true);\n } finally {\n if (remote.restore) await settle(current(), remote.restore);\n }\n },\n mkdir: async (path) => void (await call('mkdir', { path: rel(path) })),\n rmdir: async (path) => void (await call('rmdir', { path: rel(path) })),\n unlink: async (path) => void (await call('unlink', { path: rel(path) })),\n rename: async (from, to) => void (await call('rename', { from: rel(from), to: rel(to) })),\n symlink: async (target, path) => void (await call('symlink', { target, path: rel(path) })),\n readlink: async (path) =>\n (await call<{ target: string }>('readlink', { path: rel(path) })).target,\n async setattr(path, { size, ...change }) {\n if (size !== undefined && !current().capabilities.ranges) await resize(handlers, path, size);\n else if (size !== undefined) change = { ...change, size } as typeof change;\n if (Object.keys(change).length > 0) await call('setattr', { path: rel(path), ...change });\n },\n statfs: () => call<DriverStatfs>('statfs'),\n };\n return handlers;\n}\n\nconst KEEP: OpenFlags = { write: false, create: false, truncate: false, exclusive: false };\n\nasync function resize(h: FilesystemHandlers, path: string, size: number): Promise<void> {\n const was = (await h.getattr(path)).size;\n if (size === was) return;\n const kept: Uint8Array[] = [];\n if (size < was && size > 0) {\n const fh = await h.open(path, KEEP);\n try {\n for (let at = 0; at < size; ) {\n const bytes = await h.read(fh, at, size - at);\n if (bytes.length === 0) break;\n kept.push(bytes);\n at += bytes.length;\n }\n } finally {\n await h.release(fh);\n }\n }\n const fh = await h.open(path, { ...KEEP, write: true, truncate: size < was });\n try {\n if (size > was) await h.write(fh, size - 1, new Uint8Array(1));\n let at = 0;\n for (const bytes of kept) {\n await h.write(fh, at, bytes);\n at += bytes.length;\n }\n } finally {\n await h.release(fh);\n }\n}\n\nexport interface WatchLoop {\n connect(): Promise<HostfsTransport>;\n up(client: HostfsTransport): void;\n event(event: HostfsEvent): void;\n down(): void;\n silenceMs?: number;\n backoffMs?: [number, number];\n connectMs?: number;\n}\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n const done = () => {\n clearTimeout(timer);\n signal.removeEventListener('abort', done);\n resolve();\n };\n const timer = setTimeout(done, ms);\n signal.addEventListener('abort', done);\n });\n}\n\nexport interface Watching {\n ready: Promise<void>;\n kick(): void;\n}\n\nexport function keepWatching(loop: WatchLoop, signal: AbortSignal): Watching {\n const silenceMs = loop.silenceMs ?? 45_000;\n const [first, most] = loop.backoffMs ?? [1000, 30_000];\n const ready = Promise.withResolvers<void>();\n const capped = setTimeout(ready.resolve, loop.connectMs ?? 15_000);\n const uncap = () => clearTimeout(capped);\n void ready.promise.then(uncap);\n signal.addEventListener('abort', uncap, { once: true });\n let wait = first;\n let up = false;\n let current: AbortController | undefined;\n async function session(): Promise<boolean> {\n const session = new AbortController();\n current = session;\n const stop = () => session.abort();\n signal.addEventListener('abort', stop);\n let timer: ReturnType<typeof setTimeout> | undefined;\n const quiet = () => {\n clearTimeout(timer);\n timer = setTimeout(stop, silenceMs);\n };\n let opened = false;\n try {\n const client = await loop.connect();\n quiet();\n await client.watch(\n session.signal,\n (event) => {\n quiet();\n if (!event.ping) loop.event(event);\n },\n () => {\n quiet();\n opened = true;\n up = true;\n loop.up(client);\n ready.resolve();\n }\n );\n return opened;\n } catch {\n return opened;\n } finally {\n clearTimeout(timer);\n signal.removeEventListener('abort', stop);\n }\n }\n void (async () => {\n while (!signal.aborted) {\n const began = Date.now();\n const opened = await session();\n if (signal.aborted) return;\n if (opened && Date.now() - began >= first) {\n wait = first;\n continue;\n }\n if (!opened && up) {\n up = false;\n loop.down();\n }\n ready.resolve();\n await sleep(wait, signal);\n wait = Math.min(wait * 2, most);\n }\n })();\n return { ready: ready.promise, kick: () => current?.abort() };\n}\n\nexport function invalidation(event: HostfsEvent): string[] | true {\n return event.paths ?? true;\n}\n\nexport interface HostfsTiming {\n silenceMs?: number;\n backoffMs?: [number, number];\n connectMs?: number;\n requestMs?: number;\n callMs?: number;\n beatMs?: number;\n deadMs?: number;\n}\n\nexport const PORT_REQUEST_MS = 60_000;\nexport const HOSTFS_CALL_MS = 20_000;\nexport const PORT_BEAT_MS = 1000;\nexport const PORT_DEAD_MS = 10_000;\nexport const PORT_LINGER_MS = 1000;\n\nexport interface PortLiveness {\n requestMs?: number;\n beatMs?: number;\n deadMs?: number;\n lingerMs?: number;\n}\n\nexport function timed(transport: HostfsTransport, ms: number): HostfsTransport {\n const inflight = new Set<Promise<unknown>>();\n const guard = <T>(\n name: string,\n run: () => Promise<T>,\n late?: (value: T) => void,\n expire?: (running: Promise<T>) => void\n ) =>\n new Promise<T>((resolve, reject) => {\n let expired = false;\n const running = run();\n inflight.add(running);\n const done = () => inflight.delete(running);\n running.then(done, done);\n const timer = setTimeout(() => {\n expired = true;\n const why = `the host folder did not answer ${name} within ${ms} ms`;\n transport.retire?.(why);\n expire?.(running);\n reject(fsError('ENOTCONN', why));\n }, ms);\n running.then(\n (value) => {\n clearTimeout(timer);\n if (expired) late?.(value);\n resolve(value);\n },\n (err) => {\n clearTimeout(timer);\n reject(err);\n }\n );\n });\n const cleanup = async (op: string, body: Record<string, unknown>, skip?: Promise<unknown>) => {\n await Promise.allSettled([...inflight].filter((work) => work !== skip));\n return await transport.cleanup?.(op, body);\n };\n const release = (opened: unknown) => {\n const fh = (opened as { fh?: unknown } | null)?.fh;\n if (typeof fh === 'number') void cleanup('release', { fh }).catch(() => {});\n };\n return {\n get capabilities() {\n return transport.capabilities;\n },\n get token() {\n return transport.token;\n },\n get maxIo() {\n return transport.maxIo;\n },\n get gone() {\n return transport.gone;\n },\n retire: (why) => transport.retire?.(why),\n ...(transport.cleanup ? { cleanup } : {}),\n call: (op, body, handle) =>\n guard(\n op,\n () => transport.call(op, body, handle),\n op === 'open' ? release : undefined,\n op === 'release'\n ? (running) => void cleanup('release', body ?? {}, running).catch(() => {})\n : undefined\n ),\n read: (fh, offset, size, ifMatch) =>\n guard('read', () => transport.read(fh, offset, size, ifMatch)),\n write: (fh, offset, bytes) => guard('write', () => transport.write(fh, offset, bytes)),\n watch: (signal, onEvent, onOpen) => transport.watch(signal, onEvent, onOpen),\n };\n}\nconst PORT_MS_PER_MIB = 1000;\n\nlet nextPortToken = 0;\n\ntype PortReply = {\n id: number;\n pong?: boolean;\n result?: unknown;\n bytes?: Uint8Array;\n event?: HostfsEvent;\n open?: boolean;\n end?: boolean;\n error?: { code?: string; message?: string };\n};\n\nexport class PortTransport implements HostfsTransport {\n readonly capabilities: DriverCapabilities;\n readonly token: string;\n private readonly port: MessagePort;\n private readonly requestMs: number;\n private readonly waiting = new Map<number, (reply: PortReply) => void>();\n private next = 0;\n private dead: string | undefined;\n private readonly beatMs: number;\n private readonly deadMs: number;\n private readonly lingerMs: number;\n private beat: ReturnType<typeof setInterval> | undefined;\n private answers = false;\n private pinged: number | undefined;\n\n constructor(grant: HostfsPortGrant, liveness: PortLiveness = {}) {\n this.port = grant.port;\n this.requestMs = liveness.requestMs ?? PORT_REQUEST_MS;\n this.beatMs = liveness.beatMs ?? PORT_BEAT_MS;\n this.deadMs = liveness.deadMs ?? PORT_DEAD_MS;\n this.lingerMs = liveness.lingerMs ?? PORT_LINGER_MS;\n this.capabilities = grant.capabilities ?? {};\n this.token = grant.token ?? `port-${++nextPortToken}`;\n this.port.addEventListener('message', (event: MessageEvent<PortReply>) => {\n if (event.data?.pong) {\n this.answers = true;\n this.pinged = undefined;\n } else this.waiting.get(event.data?.id)?.(event.data);\n });\n this.port.addEventListener('close', () => this.fail(\"the folder's port closed\"));\n this.port.start();\n }\n\n get maxIo(): number {\n return this.capabilities.maxIo ?? HOSTFS_IO;\n }\n\n get gone(): boolean {\n return this.dead !== undefined;\n }\n\n retire(why: string): void {\n this.fail(why);\n }\n\n private ping(): void {\n if (this.pinged !== undefined) return;\n this.pinged = Date.now();\n try {\n this.port.postMessage({ id: 0, op: 'ping' });\n } catch {}\n }\n\n private watchBeat(): void {\n if (this.beat || this.dead) return;\n this.ping();\n this.beat = setInterval(() => {\n if (this.waiting.size === 0) {\n clearInterval(this.beat);\n this.beat = undefined;\n return;\n }\n if (this.answers && this.pinged !== undefined && Date.now() - this.pinged > this.deadMs) {\n this.fail(\"the folder's port stopped answering\");\n return;\n }\n this.ping();\n }, this.beatMs);\n }\n\n async cleanup(op: string, body: Record<string, unknown>): Promise<void> {\n if (this.closed) throw fsError('ENOTCONN', \"the folder's port is closed\");\n this.port.postMessage({ id: 0, op: 'cleanup', name: op, body });\n }\n\n private closed = false;\n\n fail(why: string): void {\n if (this.dead === undefined) {\n setTimeout(() => {\n try {\n this.port.postMessage({ id: 0, op: 'bye' });\n } catch {}\n this.closed = true;\n this.port.close();\n }, this.lingerMs);\n }\n clearInterval(this.beat);\n this.beat = undefined;\n this.dead ??= why;\n for (const settle of [...this.waiting.values()])\n settle({ id: 0, error: { code: 'ENOTCONN', message: why } });\n }\n\n private ask(\n message: Record<string, unknown>,\n bytes = 0,\n transfer: Transferable[] = []\n ): Promise<PortReply> {\n const id = ++this.next;\n if (this.dead) return Promise.reject(fsError('ENOTCONN', this.dead));\n return new Promise((resolve, reject) => {\n const timer = setTimeout(\n () => {\n this.waiting.delete(id);\n reject(fsError('ETIMEDOUT', \"the folder's port did not answer\"));\n this.fail(\"the folder's port stopped answering\");\n },\n this.requestMs + Math.ceil(bytes / 1_048_576) * PORT_MS_PER_MIB\n );\n this.watchBeat();\n this.waiting.set(id, (reply) => {\n clearTimeout(timer);\n this.waiting.delete(id);\n if (reply.error) reject(fsError(reply.error.code ?? 'EIO', reply.error.message ?? ''));\n else resolve(reply);\n });\n try {\n this.port.postMessage({ id, ...message }, transfer);\n } catch (err) {\n this.fail(`the folder's port is closed: ${(err as Error).message}`);\n }\n });\n }\n\n async call<T>(op: string, body: Record<string, unknown> = {}): Promise<T> {\n return (await this.ask({ op: 'call', name: op, body })).result as T;\n }\n\n async read(fh: number, offset: number, size: number, ifMatch?: string): Promise<Uint8Array> {\n const reply = await this.ask(\n { op: 'read', fh, offset, size, ...(ifMatch ? { ifMatch } : {}) },\n size\n );\n return reply.bytes ?? new Uint8Array(0);\n }\n\n async write(fh: number, offset: number, bytes: Uint8Array): Promise<void> {\n await this.ask({ op: 'write', fh, offset, bytes }, bytes.length);\n }\n\n watch(\n signal: AbortSignal,\n onEvent: (event: HostfsEvent) => void,\n onOpen: () => void = () => undefined\n ): Promise<void> {\n const id = ++this.next;\n if (this.dead) return Promise.reject(fsError('ENOTCONN', this.dead));\n if (signal.aborted) {\n this.fail(\"the folder's watch ended\");\n return Promise.resolve();\n }\n return new Promise<void>((resolve, reject) => {\n const finish = () => {\n this.waiting.delete(id);\n signal.removeEventListener('abort', stop);\n };\n const stop = () => {\n finish();\n try {\n this.port.postMessage({ id, op: 'unwatch' });\n } catch {}\n resolve();\n };\n this.watchBeat();\n this.waiting.set(id, (reply) => {\n if (reply.open) return onOpen();\n if (reply.event) return onEvent(reply.event);\n finish();\n if (reply.error) reject(fsError(reply.error.code ?? 'ENOTCONN', reply.error.message ?? ''));\n else resolve();\n });\n signal.addEventListener('abort', stop, { once: true });\n try {\n this.port.postMessage({ id, op: 'watch' });\n } catch (err) {\n finish();\n reject(fsError('ENOTCONN', `the folder's port is closed: ${(err as Error).message}`));\n }\n }).finally(() => this.fail(\"the folder's watch ended\"));\n }\n}\n\nconst errorOf = (err: unknown) => ({\n code: typeof codeOf(err) === 'string' ? (codeOf(err) as string) : 'EIO',\n message: (err as Error | null)?.message ?? String(err),\n});\n\nexport function serveHostfsPort(port: MessagePort, transport: HostfsTransport): () => void {\n const watches = new Map<number, AbortController>();\n const handles = new Set<number>();\n let stopped = false;\n const closeHandles = () => {\n for (const fh of handles) void transport.call('release', { fh }, true).catch(() => {});\n handles.clear();\n };\n const send = (reply: PortReply, transfer: Transferable[] = []) =>\n port.postMessage(reply, transfer);\n const pending = new Set<Promise<unknown>>();\n const track = <T>(work: Promise<T>) => {\n pending.add(work);\n const done = () => pending.delete(work);\n work.then(done, done);\n return work;\n };\n const answer = async (name: string, body: Record<string, unknown>) => {\n const result = await track(transport.call(name, body));\n const opened = (result as { fh?: unknown } | null)?.fh;\n if (name === 'open' && typeof opened === 'number') handles.add(opened);\n if (name === 'release') handles.delete(body?.fh as number);\n if (stopped) closeHandles();\n return result;\n };\n const listener = async ({\n data,\n }: MessageEvent<Record<string, unknown> & { id: number; op: string }>) => {\n const { id, op } = data;\n if (op === 'ping') return send({ id, pong: true });\n if (op === 'bye') return stop();\n if (op === 'cleanup')\n return void Promise.allSettled([...pending])\n .then(() => answer(data.name as string, data.body as Record<string, unknown>))\n .catch(() => {});\n if (op === 'unwatch') return watches.get(id)?.abort();\n if (op === 'watch') {\n const stop = new AbortController();\n watches.set(id, stop);\n try {\n await transport.watch(\n stop.signal,\n (event) => send({ id, event }),\n () => send({ id, open: true })\n );\n send({ id, end: true });\n } catch (err) {\n send({ id, error: errorOf(err) });\n } finally {\n watches.delete(id);\n }\n return;\n }\n try {\n if (op === 'read') {\n const read = await track(\n transport.read(\n data.fh as number,\n data.offset as number,\n data.size as number,\n data.ifMatch as string | undefined\n )\n );\n const bytes = read.slice();\n return send({ id, bytes }, [bytes.buffer as ArrayBuffer]);\n }\n if (op === 'write') {\n await track(\n transport.write(data.fh as number, data.offset as number, data.bytes as Uint8Array)\n );\n return send({ id });\n }\n if (op !== 'call') throw fsError('EINVAL', `unknown hostfs port op ${op}`);\n send({ id, result: await answer(data.name as string, data.body as Record<string, unknown>) });\n } catch (err) {\n send({ id, error: errorOf(err) });\n }\n };\n const stop = () => {\n stopped = true;\n port.removeEventListener('message', listener as (event: MessageEvent) => void);\n port.removeEventListener('close', stop);\n for (const watch of watches.values()) watch.abort();\n closeHandles();\n port.close();\n };\n port.addEventListener('message', listener as (event: MessageEvent) => void);\n port.addEventListener('close', stop);\n port.start();\n return stop;\n}\n\nexport function grantConnect(\n hook: HostfsGrantHook,\n fetch: FetchLike,\n liveness: PortLiveness = {}\n): HostfsConnect {\n return async (source, options) => {\n const first = await hook(source, options);\n if ('port' in first) return new PortTransport(first, liveness);\n const grant = async () => {\n const again = await hook(source, options);\n if ('port' in again)\n throw fsError('ESTALE', 'the folder moved to a port, so its open files are gone');\n return again;\n };\n return new HostfsClient(first, grant, fetch);\n };\n}\n\nexport async function openHostfs(\n spec: MountSpec,\n connect: HostfsConnect,\n timing: HostfsTiming = {}\n): Promise<OpenedDriver> {\n const readonly = spec.options?.ro !== undefined;\n const { port1, port2 } = new MessageChannel();\n const slot = mediumSlot<HostfsTransport>(\n async (err) => unreachable(err),\n () => watching.kick()\n );\n const stop = new AbortController();\n let active: HostfsTransport | undefined;\n const handlers = hostfsHandlers(() => active as HostfsTransport);\n const ranged = () => ({\n ...(active?.capabilities.ranges === true ? { ranges: true } : {}),\n ...(active ? { maxIo: Math.min(active.maxIo, HOSTFS_IO) } : {}),\n });\n const served = serveFilesystem(\n port2,\n { ...slot.handlers, mount: ranged },\n {\n symlinks: true,\n chmod: true,\n listingStats: true,\n maxIo: HOSTFS_IO,\n ...(readonly ? { readonly: true } : {}),\n }\n );\n const watching = keepWatching(\n {\n connect: () => connect(spec.source, { readonly }),\n up(client) {\n active = timed(client, timing.callMs ?? HOSTFS_CALL_MS);\n slot.insert(client, handlers);\n served.invalidate(true);\n },\n event: (event) => served.invalidate(invalidation(event)),\n down() {\n slot.eject();\n served.invalidate(true);\n },\n ...timing,\n },\n stop.signal\n );\n await watching.ready;\n return {\n port: port1,\n present: slot.present,\n dispose() {\n stop.abort();\n port1.close();\n port2.close();\n },\n };\n}\n", "import { type CdpOpen, serveCdpPort } from './cdp/port.ts';\nimport type { CdpHook } from './cdp/types.ts';\nimport {\n type DialHandle,\n type DialledSocket,\n type DialOptions,\n dialStream,\n errorWithCode,\n} from './client/dial-stream.ts';\nimport { type LoopbackFetchOptions, loopbackFetch } from './client/loopback-fetch.ts';\nimport type { Denial, DenialHook } from './fs/dac.ts';\nimport type { UsersMode } from './fs/types.ts';\nimport { isHostname } from './kernel/net/loopback-names.ts';\nimport type { TransportCall } from './kernel/net/remote-transport.ts';\nimport type { RouteTable } from './kernel/net/routes.ts';\nimport { type NetworkUplink, serveUplink, type UplinkCall } from './kernel/net/uplink.ts';\nimport type { PendingMedium } from './launcher.ts';\nimport type { MediumHandle } from './mount/fsa.ts';\nimport type { HostfsGrantHook } from './mount/hostfs.ts';\nimport type { MountEntry, MountSpec } from './mount/mount-fs.ts';\nimport type { ProcessMountPolicy, ProcessMountRequest } from './mount/syscall.ts';\nimport type { InitRequest, KernelCall, TerminalAction } from './serve.ts';\nimport type { ApproveHook, SudoRequest } from './sudo.ts';\nimport { type NetworkTransport, serveTransport } from './transport.ts';\nimport type { Account, AddUser, Group, RemoveUser } from './users.ts';\n\nexport type { CdpConnection, CdpHook, CdpRequest } from './cdp/types.ts';\nexport {\n type AttachOptions,\n attachKernel,\n type ClientFetchRequest,\n type ClientFs,\n type ClientRunOptions,\n type ClientRunResult,\n type ClientTerminal,\n type ClientTerminalOptions,\n KernelCallError,\n type KernelClient,\n KernelGoneError,\n type ProcessEntry,\n type SpawnedProcess,\n type SpawnOptions,\n type WatchChange,\n} from './client/attach.ts';\nexport type { DialledSocket, DialOptions } from './client/dial-stream.ts';\nexport type { LoopbackFetchOptions } from './client/loopback-fetch.ts';\nexport type { Denial, DenialHook } from './fs/dac.ts';\nexport type { RouteTable } from './kernel/net/routes.ts';\nexport type {\n NetworkUplink,\n ResolveAnswer,\n ResolveFamily,\n UplinkTraits,\n} from './kernel/net/uplink.ts';\nexport {\n checkLocalProxy,\n type LocalProxyCheckOptions,\n type LocalProxyOptions,\n type LocalProxyProbe,\n type LocalProxyStatus,\n type LocalProxyTransportOptions,\n localProxyTransport,\n probeLocalProxy,\n} from './local-proxy-transport.ts';\nexport type {\n HostfsEvent,\n HostfsGrant,\n HostfsGrantHook,\n HostfsPortGrant,\n HostfsTransport,\n} from './mount/hostfs.ts';\nexport { serveHostfsPort } from './mount/hostfs.ts';\nexport type { MountEntry, MountSpec } from './mount/mount-fs.ts';\nexport type { ProcessMountPolicy, ProcessMountRequest } from './mount/syscall.ts';\nexport type { JsChild, JsExited, JsSpawnOptions, JsStdio } from './process/js/js-children.ts';\nexport type {\n JsFdStatus,\n JsFdType,\n JsFile,\n JsOpenOptions,\n JsProgramContext,\n JsSignal,\n JsSudoAnswer,\n} from './process/js/js-context.ts';\nexport type {\n JsAddress,\n JsConnection,\n JsConnectOptions,\n JsListener,\n JsListenOptions,\n JsNet,\n} from './process/js/js-net.ts';\nexport type { JsRunOptions, JsRunResult, JsRunStdio } from './process/js/js-run.ts';\nexport type { JsSyncContext, JsSyncFile } from './process/js/js-sync.ts';\nexport type { JsTermios, JsTty, JsTtySize } from './process/js/js-tty.ts';\nexport type {\n JsWebSocket,\n JsWebSocketClose,\n JsWebSocketMessage,\n JsWebSocketOptions,\n} from './process/js/js-websocket.ts';\nexport type { ApproveHook, SudoAnswer, SudoRequest } from './sudo.ts';\nexport {\n type FetchTransportOptions,\n fetchTransport,\n type HeaderList,\n type NetworkRequest,\n type NetworkResponse,\n type NetworkTraits,\n type NetworkTransport,\n type NetworkWebSocket,\n type NetworkWebSocketRequest,\n} from './transport.ts';\nexport type { Account, AddUser, Group, RemoveUser } from './users.ts';\n\nexport interface NetworkOptions {\n transport?: NetworkTransport;\n uplink?: NetworkUplink;\n}\n\nexport interface KernelOptions {\n root?: FileSystemDirectoryHandle;\n modules?: string;\n env?: Record<string, string>;\n metadata?: string | false;\n media?: string | false;\n ca?: string | false;\n worker?: string | URL;\n network?: NetworkOptions;\n requestDirectory?: () => Promise<FileSystemDirectoryHandle>;\n onMountPending?: (pending: MountPending) => void;\n hostfs?: HostfsGrantHook;\n processMounts?: ProcessMountPolicy;\n cdp?: CdpHook;\n hostname?: string;\n users?: UsersMode;\n onDenial?: DenialHook;\n approve?: ApproveHook;\n}\n\ninterface HostfsRequest {\n id: number;\n source: string;\n readonly: boolean;\n}\n\nexport interface MountPending {\n target: string;\n source: string;\n insert(): Promise<void>;\n}\n\nexport interface RunOptions {\n cwd?: string;\n user?: string | number;\n tag?: string;\n env?: Record<string, string>;\n stdin?: string | Uint8Array;\n onStdout?: (text: string) => void;\n onStderr?: (text: string) => void;\n}\n\nexport interface RunResult {\n status: number;\n stdout: string;\n stderr: string;\n}\n\nexport interface ConnectOptions {\n user?: string | number;\n tag?: string;\n}\n\nexport interface KernelGroups {\n list(): Promise<Group[]>;\n addMember(group: string, user: string): Promise<Group>;\n removeMember(group: string, user: string): Promise<Group>;\n}\n\nexport interface KernelUsers {\n readonly mode: UsersMode;\n add(user: AddUser): Promise<Account>;\n remove(name: string, options?: RemoveUser): Promise<boolean>;\n list(): Promise<Account[]>;\n}\n\nexport interface Kernel {\n run(argv: string[], options?: RunOptions): Promise<RunResult>;\n openTerminal(argv: string[], options?: TerminalOptions): Promise<Terminal>;\n connect(options?: ConnectOptions): Promise<MessagePort>;\n readonly users: KernelUsers;\n readonly groups: KernelGroups;\n setRoutes(routes: RouteTable): Promise<void>;\n dial(options: DialOptions): Promise<DialledSocket>;\n loopbackFetch(input: RequestInfo | URL, options: LoopbackFetchOptions): Promise<Response>;\n mount(spec: MountSpec): Promise<MountEntry>;\n umount(target: string): Promise<void>;\n mounts(): Promise<MountEntry[]>;\n insert(target: string, handle: FileSystemDirectoryHandle): Promise<void>;\n terminate(): void;\n}\n\nexport interface TerminalOptions {\n cwd?: string;\n user?: string | number;\n tag?: string;\n env?: Record<string, string>;\n cols?: number;\n rows?: number;\n onData?: (bytes: Uint8Array) => void;\n}\n\nexport type TerminalSignal =\n | 'SIGINT'\n | 'SIGTSTP'\n | 'SIGQUIT'\n | 'SIGHUP'\n | 'SIGTERM'\n | 'SIGKILL'\n | 'SIGCONT';\n\nexport interface Terminal {\n readonly pid: number;\n readonly exited: Promise<number>;\n onData: ((bytes: Uint8Array) => void) | null;\n write(data: string | Uint8Array): void;\n resize(cols: number, rows: number): void;\n signal(name: TerminalSignal): void;\n close(): void;\n}\n\ninterface Reply {\n id: number;\n result?: unknown;\n error?: string;\n code?: string;\n fd?: 1 | 2;\n bytes?: Uint8Array;\n started?: number;\n}\n\ninterface Pending {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n output?: (fd: 1 | 2, bytes: Uint8Array) => void;\n started?: (pid: number) => void;\n}\n\ninterface Handlers {\n output?: Pending['output'];\n started?: Pending['started'];\n}\n\nconst ISOLATION =\n 'slicc-kernel needs a cross-origin isolated page (Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp or credentialless)';\n\nfunction streamer(callback: ((text: string) => void) | undefined) {\n const decoder = new TextDecoder();\n return (bytes: Uint8Array) => callback?.(decoder.decode(bytes, { stream: true }));\n}\n\nfunction dialer(call: (req: KernelCall) => Promise<unknown>) {\n const open = new Set<DialHandle>();\n const dial = async ({ port, host }: DialOptions): Promise<DialledSocket> => {\n let reply: unknown;\n try {\n reply = await call({ op: 'dial', port, ...(host ? { host } : {}) });\n } catch (err) {\n throw errorWithCode((err as Error).message);\n }\n const handle = dialStream(reply as MessagePort, () => open.delete(handle));\n open.add(handle);\n return handle;\n };\n const reset = () => {\n for (const handle of [...open]) handle.fail(errorWithCode('ECONNRESET: the kernel is gone'));\n };\n return { dial, reset };\n}\n\nfunction uplinkInit(uplink: NetworkUplink | undefined): Pick<InitRequest, 'uplink'> {\n if (!uplink) return {};\n const traits = { tcp: true, udp: false, ipv6: uplink.traits.ipv6 === true } as const;\n return { uplink: { traits, ...(uplink.routes ? { routes: uplink.routes } : {}) } };\n}\n\nfunction initCall(options: KernelOptions, transport: NetworkTransport | undefined): KernelCall {\n return {\n op: 'init',\n ...(options.root ? { root: options.root } : {}),\n ...(options.modules ? { modules: options.modules } : {}),\n ...(options.env ? { env: options.env } : {}),\n ...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n ...(options.media !== undefined ? { media: options.media } : {}),\n ...(options.ca !== undefined ? { ca: options.ca } : {}),\n ...(transport ? { transport: transport.traits } : {}),\n ...uplinkInit(options.network?.uplink),\n ...(options.hostfs ? { hostfs: true } : {}),\n ...(options.cdp ? { cdp: true } : {}),\n ...(options.hostname !== undefined ? { hostname: options.hostname } : {}),\n ...(options.users !== undefined ? { users: options.users } : {}),\n ...(options.onDenial ? { denials: true } : {}),\n ...(options.approve ? { approve: true } : {}),\n ...(options.processMounts !== undefined\n ? {\n processMounts:\n typeof options.processMounts === 'function' ? 'ask' : options.processMounts,\n }\n : {}),\n };\n}\n\nfunction cdpBridge(hook: CdpHook | undefined) {\n const open = new Set<() => void>();\n let closed = false;\n return {\n open({ cdpOpen, port }: CdpOpen): void {\n if (!hook || closed) {\n port.close();\n return;\n }\n const close = serveCdpPort(port, hook, cdpOpen, () => open.delete(close));\n open.add(close);\n },\n close(): void {\n closed = true;\n for (const close of [...open]) close();\n },\n };\n}\n\nfunction failed(message: string, code: string | undefined): Error {\n return Object.assign(new Error(message), code === undefined ? {} : { code });\n}\n\nfunction kernelGroups(call: (req: KernelCall) => Promise<unknown>): KernelGroups {\n const member =\n (op: 'groups-add-member' | 'groups-remove-member') => async (group: string, user: string) =>\n (await call({ op, group, user })) as Group;\n return {\n list: async () => (await call({ op: 'groups-list' })) as Group[],\n addMember: member('groups-add-member'),\n removeMember: member('groups-remove-member'),\n };\n}\n\nfunction accounts(\n call: (req: KernelCall) => Promise<unknown>,\n mode: UsersMode | undefined\n): { users: KernelUsers; groups: KernelGroups } {\n return { users: kernelUsers(call, mode), groups: kernelGroups(call) };\n}\n\nfunction kernelUsers(\n call: (req: KernelCall) => Promise<unknown>,\n mode: UsersMode = 'off'\n): KernelUsers {\n return {\n mode,\n add: async (user) => (await call({ op: 'users-add', user })) as Account,\n remove: async (name, options) =>\n (await call({ op: 'users-remove', name, ...(options ? { options } : {}) })) as boolean,\n list: async () => (await call({ op: 'users-list' })) as Account[],\n };\n}\n\nasync function mountPolicy(\n options: KernelOptions,\n worker: Worker,\n { id, req }: { id: number; req: ProcessMountRequest }\n): Promise<void> {\n const decide = options.processMounts;\n let allowed = false;\n try {\n allowed = typeof decide === 'function' ? await decide(req) : decide !== false;\n } catch {}\n worker.postMessage({ mountAllowed: { id, allowed } });\n}\n\ntype SudoMessage = { sudoAsk: SudoRequest } | { sudoAbort: { id: string; reason: string } };\n\ntype WorkerMessage =\n | Reply\n | TransportCall\n | UplinkCall\n | { medium: PendingMedium }\n | { hostfs: HostfsRequest }\n | { mountPolicy: { id: number; req: ProcessMountRequest } }\n | CdpOpen\n | { denial: Denial }\n | SudoMessage;\n\nfunction approver(approve: ApproveHook | undefined, worker: Worker) {\n const asked = new Map<string, AbortController>();\n const handlers = {\n handle(data: WorkerMessage): data is SudoMessage {\n if ('sudoAsk' in data) void handlers.ask(data.sudoAsk);\n else if ('sudoAbort' in data) handlers.abort(data.sudoAbort);\n else return false;\n return true;\n },\n async ask(req: SudoRequest): Promise<void> {\n const control = new AbortController();\n asked.set(req.id, control);\n let answer: unknown = 'deny';\n try {\n answer = await approve?.(req, { signal: control.signal });\n } catch {}\n asked.delete(req.id);\n if (control.signal.aborted) return;\n worker.postMessage({ sudoAnswer: { id: req.id, answer } });\n },\n abort({ id, reason }: { id: string; reason: string }): void {\n asked.get(id)?.abort(reason);\n asked.delete(id);\n },\n close(): void {\n for (const control of asked.values()) control.abort('withdrawn');\n asked.clear();\n },\n };\n return handlers;\n}\n\nexport async function createKernel(options: KernelOptions = {}): Promise<Kernel> {\n if (!globalThis.crossOriginIsolated) throw new Error(ISOLATION);\n if (options.hostname !== undefined && !isHostname(options.hostname)) {\n throw new Error(`not a host name: ${String(options.hostname)}`);\n }\n const url = options.worker ?? new URL('./kernel-worker.js', import.meta.url);\n const worker = new Worker(url, { type: 'module', name: 'slicc-kernel' });\n const pending = new Map<number, Pending>();\n let nextId = 0;\n let failure: Error | undefined;\n\n const dials = dialer((req) => call(req));\n const cdp = cdpBridge(options.cdp);\n const approvals = approver(options.approve, worker);\n const fail = (error: Error) => {\n dials.reset();\n cdp.close();\n approvals.close();\n failure = error;\n bridge?.close();\n uplinks?.close();\n for (const call of pending.values()) call.reject(error);\n pending.clear();\n };\n const transport = options.network?.transport;\n const bridge = transport ? serveTransport(worker, transport) : undefined;\n const uplink = options.network?.uplink;\n const uplinks = uplink ? serveUplink(worker, uplink) : undefined;\n async function chosen(handle: MediumHandle | undefined): Promise<FileSystemDirectoryHandle> {\n if (handle) {\n const state = await handle.requestPermission?.({ mode: 'readwrite' });\n if (state === undefined || state === 'granted') return handle;\n throw new Error('permission for the folder was not granted');\n }\n if (!options.requestDirectory) throw new Error('this page cannot ask for a folder');\n return options.requestDirectory();\n }\n async function grantHostfs({ id, source, readonly }: HostfsRequest): Promise<void> {\n try {\n if (!options.hostfs) throw new Error('this page gives no host folders');\n const grant = await options.hostfs(source, { readonly });\n worker.postMessage({ hostfsGrant: { id, grant } }, 'port' in grant ? [grant.port] : []);\n } catch (err) {\n worker.postMessage({ hostfsGrant: { id, error: (err as Error).message ?? String(err) } });\n }\n }\n const policy = (asked: { id: number; req: ProcessMountRequest }) =>\n mountPolicy(options, worker, asked);\n const pendingMedium = ({ target, source, handle }: PendingMedium) =>\n options.onMountPending?.({\n target,\n source,\n insert: async () =>\n void (await call({ op: 'insert', target, source, handle: await chosen(handle) })),\n });\n worker.addEventListener('message', ({ data }: MessageEvent<WorkerMessage>) => {\n if ('denial' in data) return void options.onDenial?.(data.denial);\n if (approvals.handle(data)) return;\n if ('net' in data) return bridge?.answer(data);\n if ('uplink' in data) return uplinks?.answer(data);\n if ('cdpOpen' in data) return cdp.open(data);\n if ('mountPolicy' in data) return void policy(data.mountPolicy);\n if ('medium' in data) return pendingMedium(data.medium);\n if ('hostfs' in data) return void grantHostfs(data.hostfs);\n const call = pending.get(data.id);\n if (!call) return;\n if (data.fd !== undefined) return call.output?.(data.fd, data.bytes as Uint8Array);\n if (data.started !== undefined) return call.started?.(data.started);\n pending.delete(data.id);\n if (data.error !== undefined) call.reject(failed(data.error, data.code));\n else call.resolve(data.result);\n });\n worker.addEventListener('error', (event) => {\n event.preventDefault();\n fail(new Error(`slicc-kernel worker failed: ${event.message}`));\n });\n\n function request(\n req: KernelCall,\n handlers: Handlers = {}\n ): { id: number; done: Promise<unknown> } {\n const id = ++nextId;\n if (failure) return { id, done: Promise.reject(failure) };\n const done = new Promise((resolve, reject) => {\n pending.set(id, { resolve, reject, ...handlers });\n worker.postMessage({ ...req, id });\n });\n return { id, done };\n }\n\n const call = (req: KernelCall, handlers?: Handlers) => request(req, handlers).done;\n\n async function openTerminal(argv: string[], opts: TerminalOptions = {}): Promise<Terminal> {\n const { onData, ...options } = opts;\n let listener = onData ?? null;\n const backlog: Uint8Array[] = [];\n const started = Promise.withResolvers<number>();\n const { id, done } = request(\n { op: 'open-terminal', argv, options },\n {\n output: (_fd, bytes) => (listener ? listener(bytes) : backlog.push(bytes)),\n started: started.resolve,\n }\n );\n done.catch(started.reject);\n const pid = await started.promise;\n const send = (action: TerminalAction) =>\n void call({ op: 'terminal', terminal: id, ...action }).catch(() => undefined);\n return {\n pid,\n exited: done as Promise<number>,\n get onData() {\n return listener;\n },\n set onData(next) {\n listener = next;\n if (next) for (const bytes of backlog.splice(0)) next(bytes);\n },\n write: (data) =>\n send({\n action: 'write',\n bytes: typeof data === 'string' ? new TextEncoder().encode(data) : data,\n }),\n resize: (cols, rows) => send({ action: 'resize', cols, rows }),\n signal: (name) => send({ action: 'signal', signal: name }),\n close: () => send({ action: 'close' }),\n };\n }\n\n const { dial } = dials;\n\n await call(initCall(options, transport));\n\n return {\n async run(argv, runOptions = {}) {\n const { onStdout, onStderr, stdin, ...rest } = runOptions;\n const streams = { 1: streamer(onStdout), 2: streamer(onStderr) };\n const input = typeof stdin === 'string' ? new TextEncoder().encode(stdin) : stdin;\n const result = (await call(\n { op: 'run', argv, options: { ...rest, ...(input ? { stdin: input } : {}) } },\n { output: (fd, bytes) => streams[fd](bytes) }\n )) as { status: number; stdout: Uint8Array; stderr: Uint8Array };\n const decoder = new TextDecoder();\n return {\n status: result.status,\n stdout: decoder.decode(result.stdout),\n stderr: decoder.decode(result.stderr),\n };\n },\n openTerminal,\n connect: async (connectOptions = {}) =>\n (await call({ op: 'connect', ...connectOptions })) as MessagePort,\n ...accounts(call, options.users),\n setRoutes: async (routes) => void (await call({ op: 'routes', routes })),\n dial,\n loopbackFetch: (input, fetchOptions) => loopbackFetch(dial, input, fetchOptions),\n mount: async (spec) => (await call({ op: 'mount', spec })) as MountEntry,\n umount: async (target) => void (await call({ op: 'umount', target })),\n mounts: async () => (await call({ op: 'mounts' })) as MountEntry[],\n insert: async (target, handle) => void (await call({ op: 'insert', target, handle })),\n terminate() {\n fail(new Error('slicc-kernel terminated'));\n worker.terminate();\n },\n };\n}\n"],
5
- "mappings": "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",
3
+ "sources": ["../src/cdp/port.ts", "../src/bytes.ts", "../src/client/dial-stream.ts", "../src/client/loopback-fetch.ts", "../src/kernel/net/loopback-names.ts", "../src/kernel/net/routes.ts", "../src/kernel/net/uplink.ts", "../src/body-idle.ts", "../src/kernel/net/ws-queue.ts", "../src/websocket-transport.ts", "../src/transport.ts", "../src/kernel/net/remote-transport.ts", "../src/client/protocol.ts", "../src/client/attach.ts", "../src/local-proxy-transport.ts", "../src/mount/driver.ts", "../src/mount/hostfs.ts", "../src/index.ts"],
4
+ "sourcesContent": ["import type { CdpConnection, CdpHook, CdpRequest } from './types.ts';\n\nexport interface CdpPortLike {\n postMessage(message: unknown): void;\n addEventListener(type: 'message', handler: (event: MessageEvent) => void): void;\n start?(): void;\n close(): void;\n}\n\nexport type CdpWire = { open: true } | { error: string } | { m: string } | { close: string | null };\n\nexport interface CdpOpen {\n cdpOpen: CdpRequest & { registration?: number };\n port: CdpPortLike;\n}\n\nexport function serveCdpPort(\n port: CdpPortLike,\n hook: CdpHook,\n request: CdpRequest,\n onDone?: () => void\n): () => void {\n let conn: CdpConnection | undefined;\n let done = false;\n const end = () => {\n done = true;\n port.close();\n onDone?.();\n };\n const finish = (reason: string | null) => {\n if (done) return;\n port.postMessage({ close: reason });\n end();\n };\n port.addEventListener('message', ({ data }: MessageEvent<{ m?: string; close?: true }>) => {\n if (data.m !== undefined) conn?.send(data.m);\n else if (data.close && !done) {\n end();\n conn?.close();\n }\n });\n port.start?.();\n new Promise<CdpConnection>((resolve) => resolve(hook(request))).then(\n (opened) => {\n conn = opened;\n if (done) return opened.close();\n opened.onmessage = (m) => {\n if (!done) port.postMessage({ m });\n };\n opened.onclose = (reason) => finish(reason ?? null);\n port.postMessage({ open: true });\n },\n (e: unknown) => {\n if (done) return;\n port.postMessage({ error: e instanceof Error ? e.message : String(e) });\n end();\n }\n );\n return () => {\n if (done) return;\n conn?.close();\n finish('the CDP host is gone');\n };\n}\n\nexport function portCdpHook(\n ask: (request: CdpRequest, port: CdpPortLike) => void,\n gone?: Promise<unknown>\n): CdpHook {\n return (request) =>\n new Promise((resolve, reject) => {\n const { port1, port2 } = new MessageChannel();\n let closed = false;\n const conn: CdpConnection = {\n send: (m) => {\n if (!closed) port1.postMessage({ m });\n },\n onmessage: null,\n onclose: null,\n close: () => {\n if (closed) return;\n closed = true;\n port1.postMessage({ close: true });\n port1.close();\n },\n };\n port1.addEventListener('message', ({ data }: MessageEvent<CdpWire>) => {\n if ('m' in data) conn.onmessage?.(data.m);\n else if ('open' in data) resolve(conn);\n else if ('error' in data) {\n closed = true;\n port1.close();\n reject(new Error(data.error));\n } else if (!closed) {\n closed = true;\n port1.close();\n conn.onclose?.(data.close ?? undefined);\n }\n });\n port1.start();\n void gone?.then(() => {\n if (closed) return;\n closed = true;\n port1.close();\n reject(new Error('the CDP host is gone'));\n conn.onclose?.('the CDP host is gone');\n });\n ask(request, port2 as unknown as CdpPortLike);\n });\n}\n", "export function fresh(bytes: Uint8Array, start = 0, end = bytes.length): Uint8Array {\n return new Uint8Array(bytes.subarray(start, end));\n}\n", "import { fresh } from '../bytes.ts';\n\nexport interface DialledSocket {\n readable: ReadableStream<Uint8Array>;\n writable: WritableStream<Uint8Array>;\n close(): void;\n}\n\nexport interface DialOptions {\n port: number;\n host?: string;\n}\n\ninterface StreamPort {\n postMessage(message: unknown, transfer?: Transferable[]): void;\n addEventListener(type: 'message', handler: (event: MessageEvent) => void): void;\n start?(): void;\n close(): void;\n}\n\ntype DialMessage = Uint8Array | { end: true } | { ack: true } | { error: string };\n\nexport interface DialHandle extends DialledSocket {\n fail(error: Error): void;\n}\n\nexport function errorWithCode(message: string): Error & { code?: string } {\n const code = /^E[A-Z]+/.exec(message)?.[0];\n return Object.assign(new Error(message), code ? { code } : {});\n}\n\nexport function dialStream(port: StreamPort, onClose?: () => void): DialHandle {\n let closed = false;\n let reader: ReadableStreamDefaultController<Uint8Array> | undefined;\n const acks: Array<{ resolve: () => void; reject: (error: Error) => void }> = [];\n const readable = new ReadableStream<Uint8Array>({\n start(controller) {\n reader = controller;\n },\n pull() {\n if (!closed) port.postMessage({ more: true });\n },\n cancel() {\n reader = undefined;\n close();\n },\n });\n const finish = (fail?: Error) => {\n const controller = reader;\n reader = undefined;\n for (const ack of acks.splice(0)) {\n if (fail) ack.reject(fail);\n else ack.resolve();\n }\n if (!controller) return;\n if (fail) controller.error(fail);\n else controller.close();\n };\n function shut(): void {\n if (closed) return;\n closed = true;\n port.close();\n onClose?.();\n }\n function close(): void {\n if (!closed) port.postMessage({ close: true });\n shut();\n finish();\n }\n port.addEventListener('message', ({ data }: MessageEvent<DialMessage>) => {\n if (data instanceof Uint8Array) reader?.enqueue(data);\n else if ('ack' in data) acks.shift()?.resolve();\n else if ('end' in data) finish();\n else finish(errorWithCode(data.error));\n });\n port.start?.();\n const writable = new WritableStream<Uint8Array>({\n write(chunk) {\n if (closed) throw errorWithCode('EPIPE: the connection is closed');\n const copy = fresh(chunk);\n const acked = new Promise<void>((resolve, reject) => acks.push({ resolve, reject }));\n port.postMessage(copy, [copy.buffer]);\n return acked;\n },\n close() {\n if (!closed) port.postMessage({ end: true });\n },\n abort() {\n close();\n },\n });\n const fail = (error: Error) => {\n shut();\n finish(error);\n };\n return { readable, writable, close, fail };\n}\n", "import { type DialledSocket, type DialOptions, errorWithCode } from './dial-stream.ts';\n\nexport interface LoopbackFetchOptions extends DialOptions {\n signal?: AbortSignal;\n}\n\nconst OWN_HEADERS = new Set(['host', 'connection', 'content-length', 'transfer-encoding']);\nconst encoder = new TextEncoder();\nconst latin1 = new TextDecoder('latin1');\n\nclass ByteSource {\n private buffered = new Uint8Array(0);\n private readonly reader: ReadableStreamDefaultReader<Uint8Array>;\n\n constructor(reader: ReadableStreamDefaultReader<Uint8Array>) {\n this.reader = reader;\n }\n\n private async more(): Promise<boolean> {\n const { done, value } = await this.reader.read();\n if (done) return false;\n const joined = new Uint8Array(this.buffered.length + value.length);\n joined.set(this.buffered);\n joined.set(value, this.buffered.length);\n this.buffered = joined;\n return true;\n }\n\n async until(marker: string): Promise<Uint8Array | undefined> {\n const needle = encoder.encode(marker);\n for (;;) {\n const at = indexOf(this.buffered, needle);\n if (at >= 0) return this.take(at + needle.length);\n if (!(await this.more())) return undefined;\n }\n }\n\n async some(max: number): Promise<Uint8Array | undefined> {\n if (this.buffered.length === 0 && !(await this.more())) return undefined;\n return this.take(Math.min(max, this.buffered.length));\n }\n\n async exactly(count: number): Promise<Uint8Array | undefined> {\n while (this.buffered.length < count) if (!(await this.more())) return undefined;\n return this.take(count);\n }\n\n private take(count: number): Uint8Array {\n const out = this.buffered.slice(0, count);\n this.buffered = this.buffered.slice(count);\n return out;\n }\n}\n\nfunction indexOf(haystack: Uint8Array, needle: Uint8Array): number {\n outer: for (let i = 0; i + needle.length <= haystack.length; i++) {\n for (let j = 0; j < needle.length; j++) if (haystack[i + j] !== needle[j]) continue outer;\n return i;\n }\n return -1;\n}\n\ninterface ResponseHead {\n status: number;\n statusText: string;\n headers: Array<[string, string]>;\n}\n\nfunction parseHead(bytes: Uint8Array): ResponseHead {\n const [statusLine = '', ...lines] = latin1.decode(bytes).split('\\r\\n');\n const match = /^HTTP\\/1\\.[01] (\\d{3})(?: (.*))?$/.exec(statusLine);\n if (!match) throw errorWithCode(`EPROTO: not an HTTP/1.x response: ${statusLine.slice(0, 80)}`);\n const headers: Array<[string, string]> = [];\n for (const line of lines) {\n const colon = line.indexOf(':');\n if (colon > 0) headers.push([line.slice(0, colon).trim(), line.slice(colon + 1).trim()]);\n }\n return { status: Number(match[1]), statusText: match[2] ?? '', headers };\n}\n\nfunction header(head: ResponseHead, name: string): string | undefined {\n return head.headers.find(([key]) => key.toLowerCase() === name)?.[1];\n}\n\nasync function* chunked(source: ByteSource): AsyncGenerator<Uint8Array> {\n for (;;) {\n const line = await source.until('\\r\\n');\n if (!line) throw errorWithCode('EPROTO: the chunked body ended early');\n const size = Number.parseInt(latin1.decode(line).trim().split(';')[0] ?? '', 16);\n if (!Number.isFinite(size)) throw errorWithCode('EPROTO: a malformed chunk size');\n if (size === 0) return;\n const data = await source.exactly(size);\n if (!data || !(await source.exactly(2))) throw errorWithCode('EPROTO: a chunk ended early');\n yield data;\n }\n}\n\nasync function* counted(source: ByteSource, length: number): AsyncGenerator<Uint8Array> {\n let left = length;\n while (left > 0) {\n const data = await source.some(left);\n if (!data) throw errorWithCode('EPROTO: the body ended early');\n left -= data.length;\n yield data;\n }\n}\n\nasync function* untilClose(source: ByteSource): AsyncGenerator<Uint8Array> {\n for (let data = await source.some(65536); data; data = await source.some(65536)) yield data;\n}\n\nfunction bodyOf(source: ByteSource, head: ResponseHead, method: string) {\n if (method === 'HEAD' || head.status === 204 || head.status === 304) return undefined;\n if (header(head, 'transfer-encoding')?.toLowerCase().includes('chunked')) return chunked(source);\n const length = header(head, 'content-length');\n if (length === undefined) return untilClose(source);\n const size = Number(length);\n if (!/^\\d+$/.test(length.trim()) || !Number.isSafeInteger(size)) {\n throw errorWithCode(`EPROTO: a malformed Content-Length: ${length}`);\n }\n return counted(source, size);\n}\n\nfunction stream(chunks: AsyncGenerator<Uint8Array>, socket: DialledSocket, signal?: AbortSignal) {\n return new ReadableStream<Uint8Array>({\n start(controller) {\n signal?.addEventListener('abort', () => controller.error(signal.reason), { once: true });\n },\n async pull(controller) {\n try {\n const next = await chunks.next();\n if (next.done) {\n controller.close();\n socket.close();\n } else controller.enqueue(next.value);\n } catch (err) {\n controller.error(err);\n socket.close();\n }\n },\n cancel() {\n socket.close();\n },\n });\n}\n\nasync function requestBytes(request: Request): Promise<Uint8Array> {\n const url = new URL(request.url);\n const body = request.body ? new Uint8Array(await request.arrayBuffer()) : undefined;\n const lines = [`${request.method} ${url.pathname}${url.search} HTTP/1.1`, `Host: ${url.host}`];\n request.headers.forEach((value, name) => {\n if (!OWN_HEADERS.has(name)) lines.push(`${name}: ${value}`);\n });\n if (body) lines.push(`Content-Length: ${body.length}`);\n lines.push('Connection: close', '', '');\n const head = encoder.encode(lines.join('\\r\\n'));\n const out = new Uint8Array(head.length + (body?.length ?? 0));\n out.set(head);\n if (body) out.set(body, head.length);\n return out;\n}\n\nexport async function loopbackFetch(\n dial: (options: DialOptions) => Promise<DialledSocket>,\n input: RequestInfo | URL,\n options: LoopbackFetchOptions\n): Promise<Response> {\n options.signal?.throwIfAborted();\n const request = input instanceof Request ? input : new Request(input);\n const bytes = await requestBytes(request);\n const socket = await dial({\n port: options.port,\n ...(options.host ? { host: options.host } : {}),\n });\n options.signal?.addEventListener('abort', () => socket.close(), { once: true });\n try {\n const writer = socket.writable.getWriter();\n await writer.write(bytes);\n writer.releaseLock();\n const source = new ByteSource(socket.readable.getReader());\n let head: ResponseHead;\n do {\n const raw = await source.until('\\r\\n\\r\\n');\n if (!raw) throw errorWithCode('ECONNRESET: the connection closed before a response');\n head = parseHead(raw);\n } while (head.status >= 100 && head.status < 200);\n const chunks = bodyOf(source, head, request.method);\n if (!chunks) socket.close();\n return new Response(chunks ? stream(chunks, socket, options.signal) : null, {\n status: head.status,\n statusText: head.statusText,\n headers: head.headers,\n });\n } catch (err) {\n socket.close();\n throw err;\n }\n}\n", "export const HOST_LOOPBACK = 'host.slicc.internal';\n\nexport const HOST_LOOPBACK_ADDRESS = [10, 0, 2, 2] as const;\n\nexport const PAGE_LOOPBACK = 'kernel.localhost';\n\nexport const PAGE_LOOPBACK_URL = `http://{port}.${PAGE_LOOPBACK}`;\n\nexport function toHostLoopback(href: string): string {\n const url = new URL(href);\n if (url.hostname.replace(/\\.$/, '').toLowerCase() !== HOST_LOOPBACK) return href;\n url.hostname = '127.0.0.1';\n return url.href;\n}\n\nexport const DEFAULT_HOSTNAME = 'slicc';\n\nexport const HOSTNAME_ADDRESS = '127.0.1.1';\n\nexport const LIBC_HOSTNAMES: readonly string[] = ['emscripten', 'wasmer.sh'];\n\nconst LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i;\n\nfunction reserved(name: string): boolean {\n const lower = name.toLowerCase();\n return (\n lower === 'localhost' ||\n lower.endsWith('.localhost') ||\n lower === HOST_LOOPBACK ||\n lower === 'wasmer.sh' ||\n /^\\d+(\\.\\d+){3}$/.test(lower)\n );\n}\n\nexport function isHostname(name: unknown): name is string {\n if (typeof name !== 'string' || name.length > 253 || reserved(name)) return false;\n return name.split('.').every((l) => LABEL.test(l));\n}\n\nexport function hostnameOf(env: Readonly<Record<string, string>>): string {\n return isHostname(env.HOSTNAME) ? env.HOSTNAME : DEFAULT_HOSTNAME;\n}\n\nexport function ownNames(hostname: string): string[] {\n return [...new Set([hostname.toLowerCase(), ...LIBC_HOSTNAMES])];\n}\n\nexport function hostsFile(hostname: string = DEFAULT_HOSTNAME): string {\n return [\n '127.0.0.1 localhost localhost.localdomain',\n '::1 localhost ip6-localhost',\n `${HOSTNAME_ADDRESS} ${ownNames(hostname).join(' ')}`,\n `${HOST_LOOPBACK_ADDRESS.join('.')} ${HOST_LOOPBACK}`,\n '',\n ].join('\\n');\n}\n", "import { HOST_LOOPBACK, HOST_LOOPBACK_ADDRESS } from './loopback-names.ts';\n\nexport interface RouteTable {\n prefixes: readonly string[];\n exit: boolean;\n}\n\nexport type Destination = 'loopback' | 'host' | 'reserved' | 'uplink' | 'unreachable';\n\ninterface Prefix {\n v6: boolean;\n bits: bigint;\n length: number;\n}\n\nconst HOST_ADDRESS = HOST_LOOPBACK_ADDRESS.join('.');\n\nexport function ipv4Bytes(text: string): number[] | undefined {\n const parts = text.split('.');\n if (parts.length !== 4 || !parts.every((p) => /^\\d{1,3}$/.test(p))) return undefined;\n const bytes = parts.map(Number);\n return bytes.every((b) => b <= 255) ? bytes : undefined;\n}\n\nexport function ipv6Groups(text: string): number[] | undefined {\n if (!text.includes(':')) return undefined;\n let canonical: string;\n try {\n canonical = new URL(`http://[${text}]/`).hostname.slice(1, -1);\n } catch {\n return undefined;\n }\n const [head, tail] = canonical.split('::');\n const part = (s: string | undefined) =>\n s ? s.split(':').map((h) => Number.parseInt(h, 16)) : [];\n const front = part(head);\n const back = part(tail);\n return tail === undefined\n ? front\n : [...front, ...new Array<number>(8 - front.length - back.length).fill(0), ...back];\n}\n\nfunction toBits(values: number[], width: number): bigint {\n return values.reduce((acc, v) => (acc << BigInt(width)) | BigInt(v), 0n);\n}\n\nfunction addressBits(host: string): { v6: boolean; bits: bigint } | undefined {\n const v4 = ipv4Bytes(host);\n if (v4) return { v6: false, bits: toBits(v4, 8) };\n const v6 = ipv6Groups(host);\n return v6 ? { v6: true, bits: toBits(v6, 16) } : undefined;\n}\n\nfunction parsePrefix(text: string): Prefix | undefined {\n const parts = text.trim().split('/');\n if (parts.length > 2) return undefined;\n const [address = '', size] = parts;\n const parsed = addressBits(address);\n if (!parsed) return undefined;\n const max = parsed.v6 ? 128 : 32;\n const length = size === undefined ? max : /^\\d{1,3}$/.test(size) ? Number(size) : -1;\n if (length < 0 || length > max) return undefined;\n return { ...parsed, length };\n}\n\nfunction within(prefix: Prefix, addr: { v6: boolean; bits: bigint }): boolean {\n if (prefix.v6 !== addr.v6) return false;\n const shift = BigInt((prefix.v6 ? 128 : 32) - prefix.length);\n return addr.bits >> shift === prefix.bits >> shift;\n}\n\nconst RESERVED = [\n '0.0.0.0/8',\n '127.0.0.0/8',\n '169.254.0.0/16',\n '224.0.0.0/4',\n '240.0.0.0/4',\n '::/96',\n '::ffff:0:0/96',\n 'fe80::/10',\n 'ff00::/8',\n].map((p) => parsePrefix(p) as Prefix);\n\nexport class Routes {\n private table: Prefix[] = [];\n private exit = false;\n readonly ipv6: boolean;\n\n constructor(ipv6 = false) {\n this.ipv6 = ipv6;\n }\n\n set(table: RouteTable): void {\n const parsed = (table.prefixes ?? []).map(parsePrefix);\n const bad = (table.prefixes ?? []).find((_, i) => !parsed[i]);\n if (bad !== undefined) throw new Error(`not an address prefix: ${bad}`);\n this.table = parsed as Prefix[];\n this.exit = table.exit === true;\n }\n\n classify(host: string): Destination {\n const name = host.toLowerCase().replace(/\\.$/, '');\n if (name === 'localhost' || name.endsWith('.localhost') || name === '0.0.0.0') {\n return 'loopback';\n }\n if (name === HOST_LOOPBACK || name === HOST_ADDRESS) return 'host';\n const addr = addressBits(name);\n if (!addr) return 'unreachable';\n if (addr.v6 && addr.bits === 1n) return 'loopback';\n if (!addr.v6 && addr.bits >> 24n === 127n) return 'loopback';\n if (RESERVED.some((p) => within(p, addr))) return 'reserved';\n if (addr.v6 && !this.ipv6) return 'unreachable';\n if (this.exit || this.table.some((p) => within(p, addr))) return 'uplink';\n return 'unreachable';\n }\n}\n", "import { Routes, type RouteTable } from './routes.ts';\n\nexport interface UplinkTraits {\n tcp: true;\n udp: false;\n ipv6: boolean;\n}\n\nexport type ResolveFamily = 0 | 4 | 6;\n\nexport interface ResolveAnswer {\n addresses: string[];\n ttl?: number;\n}\n\nexport interface UplinkConn {\n readonly localAddr: string;\n readonly remoteAddr: string;\n read(): Promise<Uint8Array | null>;\n write(bytes: Uint8Array): Promise<number>;\n closeWrite(): void;\n close(): void;\n}\n\nexport interface UplinkDial {\n network: 'tcp';\n host: string;\n port: number;\n signal: AbortSignal;\n}\n\nexport interface NetworkUplink {\n readonly traits: UplinkTraits;\n readonly routes?: RouteTable;\n resolve(\n name: string,\n family: ResolveFamily,\n signal?: AbortSignal\n ): Promise<string[] | ResolveAnswer>;\n dial(req: UplinkDial): Promise<UplinkConn>;\n}\n\nexport type UplinkCall =\n | { uplink: 'resolve'; uid: number; name: string; family: ResolveFamily }\n | { uplink: 'dial'; uid: number; host: string; port: number }\n | { uplink: 'cancel'; uid: number }\n | { uplink: 'read'; uid: number; cid: number }\n | { uplink: 'write'; uid: number; cid: number; bytes: Uint8Array }\n | { uplink: 'close-write'; cid: number }\n | { uplink: 'close'; cid: number };\n\nexport type UplinkReply =\n | { uplink: 'resolved'; uid: number; addresses: string[]; ttl?: number }\n | { uplink: 'dialled'; uid: number; cid: number; localAddr: string; remoteAddr: string }\n | { uplink: 'data'; uid: number; bytes: Uint8Array | null }\n | { uplink: 'written'; uid: number; n: number }\n | { uplink: 'error'; uid: number; message: string; code?: string };\n\nexport interface UplinkPeer {\n postMessage(message: UplinkReply, transfer?: Transferable[]): void;\n}\n\nexport interface UplinkPort {\n postMessage(message: UplinkCall, transfer?: Transferable[]): void;\n}\n\nexport interface UplinkServer {\n answer(call: UplinkCall): void;\n close(): void;\n}\n\nexport function answerOf(result: string[] | ResolveAnswer): ResolveAnswer {\n const answer = Array.isArray(result) ? { addresses: result } : result;\n const addresses = Array.isArray(answer?.addresses)\n ? answer.addresses.filter((a): a is string => typeof a === 'string')\n : [];\n return {\n addresses,\n ...(typeof answer?.ttl === 'number' && answer.ttl >= 0 ? { ttl: answer.ttl } : {}),\n };\n}\n\nfunction failure(uid: number, e: unknown): UplinkReply {\n const code = (e as { code?: unknown } | null)?.code;\n return {\n uplink: 'error',\n uid,\n message: e instanceof Error ? e.message : String(e),\n ...(typeof code === 'string' ? { code } : {}),\n };\n}\n\nconst NEVER = new Routes(true);\n\nexport function serveUplink(peer: UplinkPeer, uplink: NetworkUplink): UplinkServer {\n const conns = new Map<number, UplinkConn>();\n const pending = new Map<number, AbortController>();\n let nextCid = 0;\n let closed = false;\n const run = (uid: number, work: (signal: AbortSignal) => Promise<UplinkReply | undefined>) => {\n const abort = new AbortController();\n pending.set(uid, abort);\n void work(abort.signal)\n .then(\n (reply) => reply && peer.postMessage(reply, transferOf(reply)),\n (e: unknown) => peer.postMessage(failure(uid, e))\n )\n .finally(() => pending.delete(uid));\n };\n const conn = (cid: number): UplinkConn => {\n const found = conns.get(cid);\n if (!found) throw Object.assign(new Error('no such uplink connection'), { code: 'EBADF' });\n return found;\n };\n const dial = async (call: Extract<UplinkCall, { uplink: 'dial' }>, signal: AbortSignal) => {\n const kind = NEVER.classify(call.host);\n if (kind === 'loopback' || kind === 'host' || kind === 'reserved') {\n throw Object.assign(new Error(`the uplink does not carry ${call.host}`), {\n code: 'ENETUNREACH',\n });\n }\n const { host, port } = call;\n const opened = await uplink.dial({ network: 'tcp', host, port, signal });\n if (signal.aborted || closed) {\n opened.close();\n return undefined;\n }\n const cid = ++nextCid;\n conns.set(cid, opened);\n const { localAddr, remoteAddr } = opened;\n return { uplink: 'dialled' as const, uid: call.uid, cid, localAddr, remoteAddr };\n };\n const drop = (cid: number) => {\n const found = conns.get(cid);\n conns.delete(cid);\n found?.close();\n };\n return {\n answer(call) {\n switch (call.uplink) {\n case 'resolve':\n return run(call.uid, async (signal) => ({\n uplink: 'resolved',\n uid: call.uid,\n ...answerOf(await uplink.resolve(call.name, call.family, signal)),\n }));\n case 'dial':\n return run(call.uid, (signal) => dial(call, signal));\n case 'cancel':\n return pending.get(call.uid)?.abort();\n case 'read':\n return run(call.uid, async () => ({\n uplink: 'data',\n uid: call.uid,\n bytes: (await conn(call.cid).read())?.slice() ?? null,\n }));\n case 'write':\n return run(call.uid, async () => ({\n uplink: 'written',\n uid: call.uid,\n n: await conn(call.cid).write(call.bytes),\n }));\n case 'close-write':\n return conns.get(call.cid)?.closeWrite();\n default:\n return drop(call.cid);\n }\n },\n close() {\n closed = true;\n for (const abort of pending.values()) abort.abort();\n for (const cid of [...conns.keys()]) drop(cid);\n },\n };\n}\n\nfunction transferOf(reply: UplinkReply): Transferable[] | undefined {\n if (reply.uplink !== 'data' || !reply.bytes) return undefined;\n return [reply.bytes.buffer as ArrayBuffer];\n}\n\ntype Answer = Exclude<UplinkReply, { uplink: 'error' }>;\n\nexport class RemoteUplink implements NetworkUplink {\n readonly traits: UplinkTraits;\n readonly routes: RouteTable | undefined;\n private readonly port: UplinkPort;\n private readonly waiting = new Map<number, PromiseWithResolvers<Answer>>();\n private nextId = 0;\n\n constructor(port: UplinkPort, traits: UplinkTraits, routes?: RouteTable) {\n this.port = port;\n this.traits = traits;\n this.routes = routes;\n }\n\n receive(reply: UplinkReply): void {\n const waiter = this.waiting.get(reply.uid);\n if (!waiter) return;\n this.waiting.delete(reply.uid);\n if (reply.uplink === 'error') {\n waiter.reject(Object.assign(new Error(reply.message), { code: reply.code }));\n } else waiter.resolve(reply);\n }\n\n private ask<T extends Answer>(\n call: Extract<UplinkCall, { uid: number }>,\n signal?: AbortSignal,\n transfer?: Transferable[]\n ): Promise<T> {\n const waiter = Promise.withResolvers<Answer>();\n this.waiting.set(call.uid, waiter);\n const abort = () => {\n this.waiting.delete(call.uid);\n this.port.postMessage({ uplink: 'cancel', uid: call.uid });\n waiter.reject(signal?.reason);\n };\n signal?.addEventListener('abort', abort, { once: true });\n const settled = () => signal?.removeEventListener('abort', abort);\n waiter.promise.then(settled, settled);\n this.port.postMessage(call, transfer);\n return waiter.promise as Promise<T>;\n }\n\n async resolve(name: string, family: ResolveFamily, signal?: AbortSignal) {\n const reply = await this.ask<Extract<Answer, { uplink: 'resolved' }>>(\n { uplink: 'resolve', uid: ++this.nextId, name, family },\n signal\n );\n return answerOf(reply);\n }\n\n async dial(req: UplinkDial): Promise<UplinkConn> {\n req.signal.throwIfAborted();\n const { host, port } = req;\n const opened = await this.ask<Extract<Answer, { uplink: 'dialled' }>>(\n { uplink: 'dial', uid: ++this.nextId, host, port },\n req.signal\n );\n const { cid, localAddr, remoteAddr } = opened;\n return {\n localAddr,\n remoteAddr,\n read: async () => {\n const got = await this.ask<Extract<Answer, { uplink: 'data' }>>({\n uplink: 'read',\n uid: ++this.nextId,\n cid,\n });\n return got.bytes;\n },\n write: async (bytes) => {\n const copy = bytes.slice();\n const call = { uplink: 'write' as const, uid: ++this.nextId, cid, bytes: copy };\n const done = await this.ask<Extract<Answer, { uplink: 'written' }>>(call, undefined, [\n copy.buffer,\n ]);\n return done.n;\n },\n closeWrite: () => this.port.postMessage({ uplink: 'close-write', cid }),\n close: () => this.port.postMessage({ uplink: 'close', cid }),\n };\n }\n}\n", "export const BODY_IDLE_MS = 5 * 60 * 1000;\n\nexport function idleFailure(ms: number): Error {\n return Object.assign(new Error(`the response body sent no data for ${ms} ms`), {\n code: 'ETIMEDOUT',\n });\n}\n\nexport async function readWithin<T>(\n reader: ReadableStreamDefaultReader<T>,\n ms: number\n): Promise<ReadableStreamReadResult<T>> {\n if (!(ms > 0 && ms < Number.POSITIVE_INFINITY)) return reader.read();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const idle = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(idleFailure(ms)), ms);\n });\n try {\n return await Promise.race([reader.read(), idle]);\n } finally {\n clearTimeout(timer);\n }\n}\n", "import type { RealmWebSocketClose, RealmWebSocketMessage } from './transport.ts';\n\nexport const INBOUND_LIMIT = 16 * 1024 * 1024;\nexport const MESSAGE_LIMIT = 64 * 1024 * 1024;\nexport const TOO_BIG = 1009;\n\nexport function payloadSize(message: RealmWebSocketMessage): number {\n return typeof message === 'string' ? new TextEncoder().encode(message).length : message.length;\n}\n\nexport class MessageQueue implements AsyncIterable<RealmWebSocketMessage> {\n private readonly items: RealmWebSocketMessage[] = [];\n private readonly limit: number;\n private waiter: (() => void) | undefined;\n private size = 0;\n private ended = false;\n private readonly overflow: () => void;\n private readonly taken: ((n: number) => void) | undefined;\n readonly closed: Promise<RealmWebSocketClose>;\n private settle!: (close: RealmWebSocketClose) => void;\n\n constructor(overflow: () => void, limit = INBOUND_LIMIT, taken?: (n: number) => void) {\n this.overflow = overflow;\n this.limit = limit;\n this.taken = taken;\n this.closed = new Promise((resolve) => {\n this.settle = resolve;\n });\n }\n\n push(message: RealmWebSocketMessage): void {\n if (this.ended) return;\n const size = payloadSize(message);\n const huge = size > MESSAGE_LIMIT;\n if (huge || (this.items.length > 0 && this.size + size > this.limit)) {\n const reason = huge\n ? `a message is over ${MESSAGE_LIMIT} bytes`\n : `over ${this.limit} bytes of messages are waiting`;\n this.end({ code: TOO_BIG, reason });\n this.overflow();\n return;\n }\n this.size += size;\n this.items.push(message);\n this.wake();\n }\n\n end(close: RealmWebSocketClose): void {\n if (this.ended) return;\n this.ended = true;\n this.settle(close);\n this.wake();\n }\n\n private wake(): void {\n const waiter = this.waiter;\n this.waiter = undefined;\n waiter?.();\n }\n\n async *[Symbol.asyncIterator](): AsyncIterator<RealmWebSocketMessage> {\n for (;;) {\n const next = this.items.shift();\n if (next !== undefined) {\n const n = payloadSize(next);\n this.size -= n;\n this.taken?.(n);\n yield next;\n continue;\n }\n if (this.ended) return;\n await new Promise<void>((resolve) => {\n this.waiter = resolve;\n });\n }\n }\n}\n", "import type {\n HeaderList,\n RealmWebSocket,\n RealmWebSocketMessage,\n RealmWebSocketRequest,\n} from './kernel/net/transport.ts';\nimport { MessageQueue } from './kernel/net/ws-queue.ts';\n\nexport interface WebSocketLike {\n binaryType: string;\n readonly protocol: string;\n readonly bufferedAmount: number;\n send(data: string | ArrayBufferView): void;\n close(code?: number, reason?: string): void;\n addEventListener(type: string, listener: (event: never) => void): void;\n}\n\nexport type WebSocketConstructor = new (url: string, init?: unknown) => WebSocketLike;\n\nconst SENT_HEADERS_DROP = new Set([\n 'host',\n 'connection',\n 'upgrade',\n 'sec-websocket-key',\n 'sec-websocket-version',\n 'sec-websocket-extensions',\n 'sec-websocket-protocol',\n]);\n\nfunction headerRecord(headers: HeaderList): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [name, value] of headers) {\n if (!SENT_HEADERS_DROP.has(name.toLowerCase())) out[name] = value;\n }\n return out;\n}\n\nexport function sendableClose(code?: number): number {\n return code === 1000 || (code !== undefined && code >= 3000 && code <= 4999) ? code : 1000;\n}\n\nfunction blockedReason(url: string, e: unknown): string {\n const name = (e as { name?: unknown } | null)?.name;\n if (name === 'SecurityError' && url.startsWith('ws:')) {\n return `${url}: ws:// is blocked from an https page; use wss:// or slicc-node`;\n }\n return `${url}: ${e instanceof Error ? e.message : String(e)}`;\n}\n\nfunction unopened(url: string, code: number): Error {\n return Object.assign(new Error(`${url}: the WebSocket closed (${code}) before it opened`), {\n status: 502,\n });\n}\n\nexport function openWebSocket(\n Socket: WebSocketConstructor,\n request: RealmWebSocketRequest,\n withHeaders: boolean\n): Promise<RealmWebSocket> {\n const { url, protocols, signal } = request;\n signal.throwIfAborted();\n let socket: WebSocketLike;\n try {\n socket = withHeaders\n ? new Socket(url, { protocols, headers: headerRecord(request.headers) })\n : new Socket(url, protocols);\n } catch (e) {\n return Promise.reject(Object.assign(new Error(blockedReason(url, e)), { status: 502 }));\n }\n socket.binaryType = 'arraybuffer';\n const queue = new MessageQueue(() => socket.close(1000, 'too many waiting messages'));\n return new Promise((resolve, reject) => {\n let open = false;\n let settled = false;\n const fail = (error: unknown) => {\n if (settled) return;\n settled = true;\n signal.removeEventListener('abort', abort);\n reject(error);\n };\n const abort = () => {\n fail(signal.reason);\n socket.close(1000, 'aborted');\n };\n signal.addEventListener('abort', abort, { once: true });\n socket.addEventListener('open', () => {\n if (settled) return;\n open = true;\n settled = true;\n signal.removeEventListener('abort', abort);\n resolve({\n protocol: socket.protocol,\n get buffered() {\n return socket.bufferedAmount;\n },\n send: (data: RealmWebSocketMessage) => socket.send(data),\n messages: queue,\n close: (code?: number, reason?: string) => socket.close(sendableClose(code), reason),\n closed: queue.closed,\n });\n });\n socket.addEventListener('message', (event: { data: string | ArrayBuffer }) => {\n queue.push(typeof event.data === 'string' ? event.data : new Uint8Array(event.data));\n });\n socket.addEventListener('error', () => {\n if (open || settled) return;\n fail(unopened(url, 1006));\n queue.end({ code: 1006, reason: '' });\n try {\n socket.close();\n } catch {}\n });\n socket.addEventListener('close', (event: { code: number; reason: string }) => {\n queue.end({ code: event.code, reason: event.reason });\n if (open) return;\n fail(unopened(url, event.code));\n });\n });\n}\n", "import { BODY_IDLE_MS, readWithin } from './body-idle.ts';\nimport { fresh } from './bytes.ts';\nimport type { TransportCall, TransportReply } from './kernel/net/remote-transport.ts';\nimport type {\n HeaderList,\n RealmRedirectHop,\n RealmTransport,\n RealmTransportRequest,\n RealmTransportResponse,\n RealmTransportTraits,\n RealmWebSocket,\n RealmWebSocketRequest,\n} from './kernel/net/transport.ts';\nimport { INBOUND_LIMIT, MESSAGE_LIMIT, payloadSize } from './kernel/net/ws-queue.ts';\nimport { openWebSocket, type WebSocketConstructor } from './websocket-transport.ts';\n\nexport type {\n HeaderList,\n RealmRedirectHop as NetworkRedirectHop,\n RealmTransport as NetworkTransport,\n RealmTransportRequest as NetworkRequest,\n RealmTransportResponse as NetworkResponse,\n RealmTransportTraits as NetworkTraits,\n RealmWebSocket as NetworkWebSocket,\n RealmWebSocketRequest as NetworkWebSocketRequest,\n};\n\nexport interface FetchTransportOptions {\n fetch?: typeof globalThis.fetch;\n maxRequestBody?: number;\n hint?: string;\n bodyIdleMs?: number;\n webSocket?: boolean | WebSocketConstructor;\n webSocketHeaders?: boolean;\n redirect?: 'follow' | 'manual';\n}\n\nexport const SEND_BUFFER = 1024 * 1024;\nconst CLOSE_WAIT_MS = 5000;\n\nconst NO_WEBSOCKET =\n 'WebSocket not supported by this transport (fetchTransport needs { webSocket: true })';\n\nconst MAX_REQUEST_BODY = 64 * 1024 * 1024;\n\nfunction joinHeaders(headers: HeaderList): Headers {\n const out = new Headers();\n for (const [name, value] of headers) {\n try {\n out.append(name, value);\n } catch {}\n }\n return out;\n}\n\nasync function* chunks(\n body: ReadableStream<Uint8Array> | null,\n idleMs: number\n): AsyncGenerator<Uint8Array> {\n if (!body) return;\n const reader = body.getReader();\n try {\n for (\n let next = await readWithin(reader, idleMs);\n !next.done;\n next = await readWithin(reader, idleMs)\n ) {\n if (next.value.byteLength > 0) yield next.value;\n }\n } finally {\n await reader.cancel().catch(() => undefined);\n }\n}\n\nexport function fetchTransport(options: FetchTransportOptions = {}): RealmTransport {\n const send = options.fetch ?? globalThis.fetch.bind(globalThis);\n const Socket =\n options.webSocket === true\n ? (globalThis as { WebSocket?: WebSocketConstructor }).WebSocket\n : options.webSocket || undefined;\n const headers = options.webSocketHeaders === true;\n const redirect = options.redirect ?? 'follow';\n return {\n traits: {\n manualRedirects: redirect === 'manual',\n encodedBodies: false,\n maxRequestBody: options.maxRequestBody ?? MAX_REQUEST_BODY,\n crossOrigin: 'cors',\n ...(Socket ? { websocket: true as const } : {}),\n },\n ...(Socket ? { websocket: (request) => openWebSocket(Socket, request, headers) } : {}),\n async fetch(request: RealmTransportRequest): Promise<RealmTransportResponse> {\n let response: Response;\n try {\n response = await send(request.url, {\n method: request.method,\n headers: joinHeaders(request.headers),\n ...(request.body ? { body: request.body as BodyInit } : {}),\n signal: request.signal,\n redirect,\n credentials: 'omit',\n mode: 'cors',\n });\n } catch (e) {\n if (request.signal.aborted) throw e;\n throw Object.assign(\n new Error(\n `fetch ${request.url} failed (unreachable, or not allowed by CORS)${options.hint ? `: ${options.hint}` : ''}`\n ),\n { status: 502 }\n );\n }\n const headers: Array<[string, string]> = [];\n response.headers.forEach((value, name) => {\n headers.push([name, value]);\n });\n const body = chunks(response.body, options.bodyIdleMs ?? BODY_IDLE_MS);\n return {\n ...(response.redirected ? { url: response.url, redirected: true } : {}),\n status: response.status,\n statusText: response.statusText,\n headers,\n body,\n cancel: async () => {\n await body.return(undefined);\n await response.body?.cancel().catch(() => undefined);\n },\n };\n },\n };\n}\n\nexport interface TransportPeer {\n postMessage(message: TransportReply, transfer?: Transferable[]): void;\n}\n\nexport interface TransportServer {\n answer(call: TransportCall): void;\n close(): void;\n}\n\ninterface Flow {\n inflight: number;\n closing: boolean;\n deadline(): void;\n wake?: () => void;\n}\n\nexport function serveTransport(\n peer: TransportPeer,\n transport: RealmTransport,\n { closeWaitMs = CLOSE_WAIT_MS }: { closeWaitMs?: number } = {}\n): TransportServer {\n const open = new Map<\n number,\n { abort: AbortController; body?: AsyncIterator<Uint8Array>; response?: RealmTransportResponse }\n >();\n const fail = (nid: number, e: unknown) => {\n open.delete(nid);\n const { status, code } = e as { status?: unknown; code?: unknown };\n peer.postMessage({\n net: 'error',\n nid,\n message: e instanceof Error ? e.message : String(e),\n ...(typeof status === 'number' ? { status } : {}),\n ...(typeof code === 'string' ? { code } : {}),\n });\n };\n const start = async (call: Extract<TransportCall, { net: 'fetch' }>) => {\n const abort = new AbortController();\n const entry: { abort: AbortController; body?: AsyncIterator<Uint8Array> } = { abort };\n open.set(call.nid, entry);\n try {\n const response = await transport.fetch({\n url: call.url,\n method: call.method,\n headers: call.headers,\n ...(call.body ? { body: call.body } : {}),\n signal: abort.signal,\n });\n if (!open.has(call.nid)) {\n await response.cancel();\n return;\n }\n open.set(call.nid, { abort, body: response.body[Symbol.asyncIterator](), response });\n peer.postMessage({\n net: 'head',\n nid: call.nid,\n ...(response.redirected ? { url: response.url, redirected: true } : {}),\n ...(response.redirects ? { redirects: response.redirects } : {}),\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n } catch (e) {\n fail(call.nid, e);\n }\n };\n const sockets = new Map<number, RealmWebSocket>();\n const credit = new Map<number, Flow>();\n const refill = (nid: number, n: number, closing = false) => {\n const flow = credit.get(nid);\n if (!flow) return;\n flow.inflight -= n;\n if (closing && !flow.closing) {\n flow.closing = true;\n flow.deadline();\n }\n flow.wake?.();\n };\n const openSocket = async (call: Extract<TransportCall, { net: 'ws-open' }>) => {\n const abort = new AbortController();\n open.set(call.nid, { abort });\n try {\n if (!transport.websocket) throw new Error(NO_WEBSOCKET);\n const socket = await transport.websocket({\n url: call.url,\n protocols: call.protocols,\n headers: call.headers,\n signal: abort.signal,\n });\n if (!open.delete(call.nid)) {\n socket.close(1000, 'cancelled');\n return;\n }\n sockets.set(call.nid, socket);\n peer.postMessage({ net: 'ws-opened', nid: call.nid, protocol: socket.protocol });\n void relay(call.nid, socket);\n } catch (e) {\n fail(call.nid, e);\n }\n };\n const relay = async (nid: number, socket: RealmWebSocket) => {\n let ending: { code: number; reason: string };\n let late!: () => void;\n const unanswered = new Promise<'late'>((resolve) => {\n late = () => resolve('late');\n });\n const flow: Flow = {\n inflight: 0,\n closing: false,\n deadline: () =>\n AbortSignal.timeout(closeWaitMs).addEventListener('abort', late, { once: true }),\n };\n credit.set(nid, flow);\n const timedOut = { code: 1006, reason: 'the far end did not answer the close' };\n let oversize = false;\n try {\n const messages = socket.messages[Symbol.asyncIterator]();\n for (;;) {\n const next = await Promise.race([messages.next(), unanswered]);\n if (next === 'late' || next.done) break;\n const data = next.value;\n if (flow.closing) continue;\n if (payloadSize(data) > MESSAGE_LIMIT) {\n oversize = true;\n break;\n }\n if (typeof data === 'string') peer.postMessage({ net: 'ws-message', nid, data });\n else {\n const bytes = fresh(data);\n peer.postMessage({ net: 'ws-message', nid, data: bytes }, [bytes.buffer]);\n }\n flow.inflight += payloadSize(data);\n while (flow.inflight > INBOUND_LIMIT && !flow.closing) {\n await new Promise<void>((resolve) => {\n flow.wake = resolve;\n });\n }\n }\n if (oversize) socket.close(1000, 'a message is too big');\n ending = oversize\n ? { code: 1009, reason: `a message is over ${MESSAGE_LIMIT} bytes` }\n : await Promise.race([socket.closed, unanswered.then(() => timedOut)]);\n } catch (e) {\n socket.close(1000, 'the relay failed');\n ending = { code: 1011, reason: e instanceof Error ? e.message : String(e) };\n }\n sockets.delete(nid);\n credit.delete(nid);\n peer.postMessage({ net: 'ws-closed', nid, ...ending });\n };\n const sendOn = async (call: Extract<TransportCall, { net: 'ws-send' }>) => {\n const socket = sockets.get(call.nid);\n if (!socket) return;\n socket.send(call.data);\n while (socket.buffered > SEND_BUFFER && sockets.has(call.nid)) {\n await new Promise((resolve) => setTimeout(resolve, 10));\n }\n peer.postMessage({ net: 'ws-acked', nid: call.nid, n: payloadSize(call.data) });\n };\n const read = async (nid: number) => {\n const body = open.get(nid)?.body;\n if (!body) return;\n try {\n const next = await body.next();\n if (next.done) {\n open.delete(nid);\n peer.postMessage({ net: 'end', nid });\n } else {\n const bytes = fresh(next.value);\n peer.postMessage({ net: 'chunk', nid, bytes }, [bytes.buffer]);\n }\n } catch (e) {\n fail(nid, e);\n }\n };\n const drop = (nid: number) => {\n sockets.get(nid)?.close(1000, 'cancelled');\n refill(nid, 0, true);\n const entry = open.get(nid);\n open.delete(nid);\n entry?.abort.abort();\n void entry?.response?.cancel().catch(() => undefined);\n };\n return {\n answer(call) {\n if (call.net === 'fetch') void start(call);\n else if (call.net === 'read') void read(call.nid);\n else if (call.net === 'ws-open') void openSocket(call);\n else if (call.net === 'ws-send') void sendOn(call);\n else if (call.net === 'ws-close') {\n sockets.get(call.nid)?.close(call.code, call.reason);\n refill(call.nid, 0, true);\n } else if (call.net === 'ws-consumed') refill(call.nid, call.n);\n else drop(call.nid);\n },\n close() {\n for (const nid of [...open.keys(), ...sockets.keys()]) drop(nid);\n },\n };\n}\n", "import type {\n HeaderList,\n RealmRedirectHop,\n RealmTransport,\n RealmTransportRequest,\n RealmTransportResponse,\n RealmTransportTraits,\n RealmWebSocket,\n RealmWebSocketMessage,\n RealmWebSocketRequest,\n} from './transport.ts';\nimport { MessageQueue, payloadSize } from './ws-queue.ts';\n\nexport type TransportCall =\n | {\n net: 'fetch';\n nid: number;\n url: string;\n method: string;\n headers: HeaderList;\n body?: Uint8Array;\n }\n | { net: 'read'; nid: number }\n | { net: 'cancel'; nid: number }\n | { net: 'ws-open'; nid: number; url: string; protocols: string[]; headers: HeaderList }\n | { net: 'ws-send'; nid: number; data: RealmWebSocketMessage }\n | { net: 'ws-close'; nid: number; code?: number; reason?: string }\n | { net: 'ws-consumed'; nid: number; n: number };\n\nexport type TransportReply =\n | {\n net: 'head';\n nid: number;\n status: number;\n statusText: string;\n headers: HeaderList;\n url?: string;\n redirected?: boolean;\n redirects?: readonly RealmRedirectHop[];\n }\n | { net: 'chunk'; nid: number; bytes: Uint8Array }\n | { net: 'end'; nid: number }\n | { net: 'error'; nid: number; message: string; status?: number; code?: string }\n | { net: 'ws-opened'; nid: number; protocol: string }\n | { net: 'ws-message'; nid: number; data: RealmWebSocketMessage }\n | { net: 'ws-acked'; nid: number; n: number }\n | { net: 'ws-closed'; nid: number; code: number; reason: string };\n\nexport interface TransportPort {\n postMessage(message: TransportCall): void;\n}\n\nexport class TransportError extends Error {\n readonly status: number | undefined;\n readonly code: string | undefined;\n\n constructor(message: string, status?: number, code?: string) {\n super(message);\n this.status = status;\n this.code = code;\n }\n}\n\ninterface Waiter {\n resolve(reply: TransportReply): void;\n reject(error: Error): void;\n}\n\nexport class RemoteTransport implements RealmTransport {\n readonly traits: RealmTransportTraits;\n\n private readonly port: TransportPort;\n\n private readonly waiting = new Map<number, Waiter>();\n\n private nextId = 0;\n\n private readonly sockets = new Map<number, { queue: MessageQueue; acked(n: number): void }>();\n\n private failure: Error | undefined;\n\n constructor(port: TransportPort, traits: RealmTransportTraits) {\n this.port = port;\n this.traits = traits;\n }\n\n receive(reply: TransportReply): void {\n const socket = this.sockets.get(reply.nid);\n if (socket && this.toSocket(reply, socket)) return;\n const waiter = this.waiting.get(reply.nid);\n if (!waiter) return;\n this.waiting.delete(reply.nid);\n if (reply.net === 'error') {\n waiter.reject(new TransportError(reply.message, reply.status, reply.code));\n } else waiter.resolve(reply);\n }\n\n private toSocket(\n reply: TransportReply,\n socket: { queue: MessageQueue; acked(n: number): void }\n ): boolean {\n if (reply.net === 'ws-message') socket.queue.push(reply.data);\n else if (reply.net === 'ws-acked') socket.acked(reply.n);\n else if (reply.net === 'ws-closed') {\n this.sockets.delete(reply.nid);\n socket.queue.end({ code: reply.code, reason: reply.reason });\n } else return false;\n return true;\n }\n\n fail(error: Error): void {\n this.failure = error;\n for (const waiter of this.waiting.values()) waiter.reject(error);\n this.waiting.clear();\n for (const socket of this.sockets.values())\n socket.queue.end({ code: 1011, reason: error.message });\n this.sockets.clear();\n }\n\n private ask(call: TransportCall): Promise<TransportReply> {\n if (this.failure) return Promise.reject(this.failure);\n return new Promise((resolve, reject) => {\n this.waiting.set(call.nid, { resolve, reject });\n this.port.postMessage(call);\n });\n }\n\n private cancel(nid: number): void {\n const waiter = this.waiting.get(nid);\n this.waiting.delete(nid);\n waiter?.reject(new TransportError('the request was cancelled'));\n this.port.postMessage({ net: 'cancel', nid });\n }\n\n async fetch(request: RealmTransportRequest): Promise<RealmTransportResponse> {\n const nid = ++this.nextId;\n const { signal } = request;\n signal.throwIfAborted();\n let finished = false;\n const abort = () => {\n finished = true;\n this.cancel(nid);\n };\n signal.addEventListener('abort', abort, { once: true });\n const finish = () => {\n if (finished) return;\n finished = true;\n signal.removeEventListener('abort', abort);\n };\n let head: TransportReply;\n try {\n head = await this.ask({\n net: 'fetch',\n nid,\n url: request.url,\n method: request.method,\n headers: request.headers,\n ...(request.body ? { body: request.body } : {}),\n });\n } catch (e) {\n finish();\n throw e;\n }\n const { status, statusText, headers, url, redirected, redirects } = head as Extract<\n TransportReply,\n { net: 'head' }\n >;\n const read = async (): Promise<Uint8Array | undefined> => {\n if (finished) return undefined;\n const reply = await this.ask({ net: 'read', nid }).catch((e: unknown) => {\n finish();\n throw e;\n });\n if (reply.net === 'chunk') return reply.bytes;\n finish();\n return undefined;\n };\n const cancel = async () => {\n if (finished) return;\n finish();\n this.cancel(nid);\n };\n return {\n ...(redirected ? { url, redirected } : {}),\n ...(redirects ? { redirects } : {}),\n status,\n statusText,\n headers,\n cancel,\n body: {\n [Symbol.asyncIterator]: () => ({\n next: async () => {\n const bytes = await read();\n return bytes ? { value: bytes, done: false } : { value: undefined, done: true };\n },\n return: async () => {\n await cancel();\n return { value: undefined, done: true };\n },\n }),\n },\n };\n }\n\n async websocket(request: RealmWebSocketRequest): Promise<RealmWebSocket> {\n const nid = ++this.nextId;\n const { signal } = request;\n signal.throwIfAborted();\n const abort = () => this.cancel(nid);\n signal.addEventListener('abort', abort, { once: true });\n let opened: TransportReply;\n try {\n opened = await this.ask({\n net: 'ws-open',\n nid,\n url: request.url,\n protocols: request.protocols,\n headers: request.headers,\n });\n } finally {\n signal.removeEventListener('abort', abort);\n }\n const close = (code?: number, reason?: string) =>\n this.port.postMessage({ net: 'ws-close', nid, code, reason });\n const queue = new MessageQueue(\n () => close(1000, 'a message is too big'),\n Number.POSITIVE_INFINITY,\n (n) => this.port.postMessage({ net: 'ws-consumed', nid, n })\n );\n let unacked = 0;\n this.sockets.set(nid, { queue, acked: (n) => void (unacked -= n) });\n return {\n protocol: (opened as Extract<TransportReply, { net: 'ws-opened' }>).protocol,\n get buffered() {\n return unacked;\n },\n send: (data) => {\n unacked += payloadSize(data);\n this.port.postMessage({ net: 'ws-send', nid, data });\n },\n messages: queue,\n close,\n closed: queue.closed,\n };\n }\n}\n", "import type { UsersMode } from '../fs/types.ts';\nimport type { WatchChange } from '../fs/watch.ts';\nimport type { TransportCall, TransportReply } from '../kernel/net/remote-transport.ts';\nimport type { RealmTransportTraits } from '../kernel/net/transport.ts';\nimport type { MountSpec } from '../mount/mount-fs.ts';\n\nexport const PROTOCOL: readonly [number, number] = [1, 9];\n\nexport interface ClientHello {\n protocol: readonly [number, number];\n lock?: string;\n}\n\nexport interface KernelHello {\n protocol: readonly [number, number];\n lock?: string;\n traits?: RealmTransportTraits;\n users?: UsersMode;\n error?: string;\n}\n\nexport interface SpawnRequestOptions {\n cwd?: string;\n user?: string | number;\n env?: Record<string, string>;\n stdin?: Uint8Array;\n pgid?: number;\n}\n\nexport interface TerminalRequestOptions {\n cwd?: string;\n user?: string | number;\n env?: Record<string, string>;\n cols?: number;\n rows?: number;\n}\n\nexport type TerminalAction =\n | { action: 'write'; bytes: Uint8Array }\n | { action: 'resize'; cols: number; rows: number }\n | { action: 'signal'; signal: string }\n | { action: 'close' };\n\nexport const FS_METHODS = [\n 'readFile',\n 'writeFile',\n 'stat',\n 'lstat',\n 'readdir',\n 'mkdir',\n 'rm',\n 'rename',\n 'realpath',\n 'symlink',\n 'readlink',\n 'exists',\n] as const;\n\nexport type FsMethod = (typeof FS_METHODS)[number];\n\nexport type ClientCall =\n | { op: 'spawn'; argv: string[]; options: SpawnRequestOptions }\n | { op: 'open-terminal'; argv: string[]; options: TerminalRequestOptions }\n | ({ op: 'terminal'; terminal: number } & TerminalAction)\n | { op: 'kill'; pid: number; signal: string }\n | { op: 'ps' }\n | { op: 'fs'; method: FsMethod; args: unknown[] }\n | { op: 'watch'; paths: string[]; recursive: boolean }\n | { op: 'unwatch'; watch: number }\n | { op: 'mount'; spec: MountSpec }\n | { op: 'umount'; target: string }\n | { op: 'mounts' }\n | { op: 'dial'; port: number; host?: string }\n | { op: 'serve-cdp'; runtime?: string }\n | { op: 'unserve-cdp'; registration: number }\n | { op: 'detach'; kill?: boolean };\n\nexport type ClientRequest = ClientCall & { id: number };\n\nexport interface ClientReply {\n id: number;\n result?: unknown;\n error?: string;\n code?: string;\n fd?: 1 | 2;\n bytes?: Uint8Array;\n started?: number;\n}\n\nexport type ClientMessage = { hello: ClientHello } | ClientRequest | TransportCall;\n\nexport interface WatchEvent {\n watch: number;\n change: WatchChange;\n}\n\nexport type KernelMessage = { hello: KernelHello } | ClientReply | WatchEvent | TransportReply;\n\nexport interface ProcessEntry {\n pid: number;\n ppid: number;\n pgid: number;\n sid: number;\n argv: string[];\n tty: string | null;\n started: number;\n state: 'S' | 'Z';\n memory: number;\n rss?: number;\n uid?: number;\n gid?: number;\n}\n\nexport interface MessagePortLike {\n postMessage(message: unknown, transfer?: Transferable[]): void;\n addEventListener(type: 'message' | 'close', handler: (event: MessageEvent) => void): void;\n start?(): void;\n close?(): void;\n}\n\nexport interface LockManagerLike {\n request(name: string, callback: () => Promise<unknown> | unknown): Promise<unknown>;\n}\n\nexport function locksOf(scope: object = globalThis): LockManagerLike | undefined {\n const locks = (scope as { navigator?: { locks?: LockManagerLike } }).navigator?.locks;\n return typeof locks?.request === 'function' ? locks : undefined;\n}\n\nexport function versionError(theirs: unknown): string | undefined {\n const major = Array.isArray(theirs) ? theirs[0] : undefined;\n if (major === PROTOCOL[0]) return undefined;\n const named = typeof major === 'number' ? `${major}.x` : 'without a version';\n return `slicc-kernel client protocol ${named} is not supported: this side speaks ${PROTOCOL.join('.')}`;\n}\n", "import { type CdpOpen, serveCdpPort } from '../cdp/port.ts';\nimport type { CdpHook } from '../cdp/types.ts';\nimport type { FsStat, UsersMode } from '../fs/types.ts';\nimport type { WatchChange } from '../fs/watch.ts';\nimport { RemoteTransport, type TransportReply } from '../kernel/net/remote-transport.ts';\nimport type {\n RealmTransport,\n RealmTransportRequest,\n RealmTransportResponse,\n} from '../kernel/net/transport.ts';\nimport type { MountEntry, MountSpec } from '../mount/mount-fs.ts';\nimport { type DialledSocket, type DialOptions, dialStream } from './dial-stream.ts';\nimport { type LoopbackFetchOptions, loopbackFetch } from './loopback-fetch.ts';\nimport {\n type ClientCall,\n type ClientReply,\n type FsMethod,\n type KernelHello,\n type LockManagerLike,\n locksOf,\n type MessagePortLike,\n PROTOCOL,\n type ProcessEntry,\n type TerminalAction,\n versionError,\n} from './protocol.ts';\n\nexport type { WatchChange } from '../fs/watch.ts';\nexport type { ProcessEntry } from './protocol.ts';\n\nexport class KernelGoneError extends Error {\n constructor(message = 'the slicc-kernel this client was attached to is gone') {\n super(message);\n this.name = 'KernelGoneError';\n }\n}\n\nexport class KernelCallError extends Error {\n readonly code: string | undefined;\n\n constructor(message: string, code?: string) {\n super(message);\n this.name = 'KernelCallError';\n this.code = code;\n }\n}\n\nexport interface AttachOptions {\n timeoutMs?: number;\n locks?: LockManagerLike | null;\n}\n\nexport interface SpawnOptions {\n cwd?: string;\n user?: string | number;\n env?: Record<string, string>;\n stdin?: string | Uint8Array;\n group?: 'new';\n pgid?: number;\n onStdout?: (bytes: Uint8Array) => void;\n onStderr?: (bytes: Uint8Array) => void;\n}\n\nexport interface SpawnedProcess {\n readonly pid: number;\n readonly pgid: number;\n readonly exited: Promise<number>;\n signal(name?: string): Promise<void>;\n}\n\nexport interface ClientRunOptions {\n cwd?: string;\n user?: string | number;\n env?: Record<string, string>;\n stdin?: string | Uint8Array;\n onStdout?: (text: string) => void;\n onStderr?: (text: string) => void;\n}\n\nexport interface ClientRunResult {\n pid: number;\n status: number;\n stdout: string;\n stderr: string;\n}\n\nexport interface ClientTerminalOptions {\n cwd?: string;\n user?: string | number;\n env?: Record<string, string>;\n cols?: number;\n rows?: number;\n onData?: (bytes: Uint8Array) => void;\n}\n\nexport interface ClientTerminal {\n readonly pid: number;\n readonly exited: Promise<number>;\n onData: ((bytes: Uint8Array) => void) | null;\n write(data: string | Uint8Array): void;\n resize(cols: number, rows: number): void;\n signal(name: string): void;\n close(): void;\n}\n\nexport interface ClientFs {\n readFile(path: string): Promise<Uint8Array>;\n readText(path: string): Promise<string>;\n writeFile(path: string, data: string | Uint8Array): Promise<void>;\n stat(path: string): Promise<FsStat>;\n lstat(path: string): Promise<FsStat>;\n readdir(path: string): Promise<string[]>;\n mkdir(path: string): Promise<void>;\n rm(path: string, options?: { force?: boolean }): Promise<void>;\n rename(from: string, to: string): Promise<void>;\n realpath(path: string): Promise<string>;\n symlink(target: string, path: string): Promise<void>;\n readlink(path: string): Promise<string>;\n exists(path: string): Promise<boolean>;\n watch(\n paths: string[],\n options: { recursive?: boolean },\n onChange: (change: WatchChange) => void\n ): Promise<{ close(): void }>;\n}\n\nexport type ClientFetchRequest = Omit<RealmTransportRequest, 'signal'> & { signal?: AbortSignal };\n\nexport interface KernelClient {\n readonly protocol: readonly [number, number];\n readonly transport: RealmTransport;\n readonly users: UsersMode;\n readonly closed: Promise<Error>;\n spawn(argv: string[], options?: SpawnOptions): Promise<SpawnedProcess>;\n run(argv: string[], options?: ClientRunOptions): Promise<ClientRunResult>;\n openTerminal(argv: string[], options?: ClientTerminalOptions): Promise<ClientTerminal>;\n ps(): Promise<ProcessEntry[]>;\n mount(spec: MountSpec): Promise<MountEntry>;\n umount(target: string): Promise<void>;\n mounts(): Promise<MountEntry[]>;\n kill(pid: number, signal?: string): Promise<void>;\n fetch(request: ClientFetchRequest): Promise<RealmTransportResponse>;\n dial(options: DialOptions): Promise<DialledSocket>;\n loopbackFetch(input: RequestInfo | URL, options: LoopbackFetchOptions): Promise<Response>;\n readonly fs: ClientFs;\n serveCdp(hook: CdpHook, options?: { runtime?: string }): Promise<{ close(): void }>;\n close(options?: { kill?: boolean }): Promise<void>;\n}\n\ninterface Pending {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n output?: (fd: 1 | 2, bytes: Uint8Array) => void;\n started?: (pid: number) => void;\n}\n\ntype Handlers = Omit<Pending, 'resolve' | 'reject'>;\n\nconst encoder = new TextEncoder();\nconst bytesOf = (data: string | Uint8Array) =>\n typeof data === 'string' ? encoder.encode(data) : data;\n\nconst UNAVAILABLE = {\n manualRedirects: false,\n encodedBodies: false,\n maxRequestBody: 0,\n unavailable: true,\n} as const;\n\nasync function holdLock(\n locks: LockManagerLike | undefined\n): Promise<{ name?: string; release(): void }> {\n if (!locks) return { release() {} };\n const name = `slicc-kernel-client:${crypto.randomUUID()}`;\n const granted = Promise.withResolvers<void>();\n const held = Promise.withResolvers<void>();\n void locks.request(name, () => {\n granted.resolve();\n return held.promise;\n });\n await granted.promise;\n return { name, release: () => held.resolve() };\n}\n\nfunction concat(chunks: Uint8Array[]): Uint8Array {\n const out = new Uint8Array(chunks.reduce((n, c) => n + c.length, 0));\n let at = 0;\n for (const chunk of chunks) {\n out.set(chunk, at);\n at += chunk.length;\n }\n return out;\n}\n\nclass Channel {\n readonly greeted = Promise.withResolvers<KernelHello>();\n readonly ended = Promise.withResolvers<Error>();\n remote: RemoteTransport | undefined;\n failure: Error | undefined;\n private readonly pending = new Map<number, Pending>();\n readonly watching = new Map<number, (change: WatchChange) => void>();\n readonly cdpHooks = new Map<number, CdpHook>();\n private readonly cdpOpen = new Set<() => void>();\n protocol: readonly [number, number] = PROTOCOL;\n private nextId = 0;\n private readonly port: MessagePortLike;\n private readonly release: () => void;\n\n constructor(port: MessagePortLike, release: () => void) {\n this.port = port;\n this.release = release;\n this.greeted.promise.catch(() => undefined);\n port.addEventListener('message', (event) => this.receive(event.data));\n port.addEventListener('close', () => this.end(new KernelGoneError()));\n port.start?.();\n }\n\n post(message: object): void {\n if (!this.failure) this.port.postMessage(message);\n }\n\n end(error: Error): void {\n if (this.failure) return;\n this.failure = error;\n this.greeted.reject(error);\n this.remote?.fail(error);\n for (const close of [...this.cdpOpen]) close();\n this.cdpOpen.clear();\n for (const call of this.pending.values()) call.reject(error);\n this.pending.clear();\n this.release();\n this.port.close?.();\n this.ended.resolve(error);\n }\n\n request(call: ClientCall, handlers: Handlers = {}): { id: number; done: Promise<unknown> } {\n const id = ++this.nextId;\n const { failure } = this;\n if (failure) return { id, done: Promise.reject(failure) };\n const done = new Promise((resolve, reject) => {\n this.pending.set(id, { resolve, reject, ...handlers });\n this.port.postMessage({ ...call, id });\n });\n return { id, done };\n }\n\n call(call: ClientCall): Promise<unknown> {\n return this.request(call).done;\n }\n\n private receive(data: {\n hello?: KernelHello;\n net?: unknown;\n bye?: string;\n watch?: number;\n change?: WatchChange;\n cdpOpen?: CdpOpen['cdpOpen'];\n port?: CdpOpen['port'];\n }): void {\n if (data.cdpOpen && data.port) {\n this.openCdp(data as CdpOpen);\n return;\n }\n if (data.watch !== undefined) {\n this.watching.get(data.watch)?.(data.change as WatchChange);\n return;\n }\n if (data.bye !== undefined) {\n this.end(new KernelGoneError(data.bye));\n return;\n }\n if (data.hello) {\n this.greeted.resolve(data.hello);\n return;\n }\n if (data.net !== undefined) {\n this.remote?.receive(data as TransportReply);\n return;\n }\n const reply = data as ClientReply;\n const call = this.pending.get(reply.id);\n if (!call) return;\n if (reply.fd !== undefined) {\n call.output?.(reply.fd, reply.bytes as Uint8Array);\n return;\n }\n if (reply.started !== undefined) {\n call.started?.(reply.started);\n return;\n }\n this.pending.delete(reply.id);\n if (reply.error !== undefined) call.reject(new KernelCallError(reply.error, reply.code));\n else call.resolve(reply.result);\n }\n\n private openCdp({ cdpOpen: { registration, ...request }, port }: CdpOpen): void {\n const hook = registration === undefined ? undefined : this.cdpHooks.get(registration);\n if (!hook || this.failure) {\n port.postMessage({ error: 'this client no longer serves CDP' });\n port.close();\n return;\n }\n const close = serveCdpPort(port, hook, request, () => this.cdpOpen.delete(close));\n this.cdpOpen.add(close);\n }\n}\n\nasync function serveCdpOn(\n channel: Channel,\n hook: CdpHook,\n options: { runtime?: string }\n): Promise<{ close(): void }> {\n await since(channel, 5, 'CDP serving', async () => {});\n const req = {\n op: 'serve-cdp' as const,\n ...(options.runtime ? { runtime: options.runtime } : {}),\n };\n const { id, done } = channel.request(req);\n channel.cdpHooks.set(id, hook);\n try {\n await done;\n } catch (error) {\n channel.cdpHooks.delete(id);\n throw error;\n }\n return {\n close: () => {\n if (!channel.cdpHooks.delete(id)) return;\n void channel.call({ op: 'unserve-cdp', registration: id }).catch(() => undefined);\n },\n };\n}\n\nasync function dialOn(channel: Channel, { port, host }: DialOptions): Promise<DialledSocket> {\n const req = { op: 'dial' as const, port, ...(host ? { host } : {}) };\n return dialStream((await since(channel, 4, 'dial', () => channel.call(req))) as MessagePort);\n}\n\nasync function spawnOn(\n channel: Channel,\n argv: string[],\n opts: SpawnOptions\n): Promise<SpawnedProcess> {\n const { onStdout, onStderr, stdin, group: _, ...rest } = opts;\n if (opts.pgid !== undefined)\n await since(channel, 3, 'spawn into a process group', async () => {});\n if (opts.user !== undefined) await since(channel, 8, 'spawn as a user', async () => {});\n const started = Promise.withResolvers<number>();\n const options = { ...rest, ...(stdin !== undefined ? { stdin: bytesOf(stdin) } : {}) };\n const { done } = channel.request(\n { op: 'spawn', argv, options },\n {\n output: (fd, bytes) => (fd === 1 ? onStdout : onStderr)?.(bytes),\n started: started.resolve,\n }\n );\n done.catch(started.reject);\n const pid = await started.promise;\n const pgid = opts.pgid ?? pid;\n return {\n pid,\n pgid,\n exited: done as Promise<number>,\n signal: async (name = 'SIGTERM') =>\n void (await channel.call({ op: 'kill', pid: -pgid, signal: name })),\n };\n}\n\nasync function runOn(\n channel: Channel,\n argv: string[],\n opts: ClientRunOptions\n): Promise<ClientRunResult> {\n const { onStdout, onStderr, ...rest } = opts;\n const chunks: Record<1 | 2, Uint8Array[]> = { 1: [], 2: [] };\n const live = { 1: new TextDecoder(), 2: new TextDecoder() };\n const tee = (fd: 1 | 2, on?: (text: string) => void) => (bytes: Uint8Array) => {\n chunks[fd].push(bytes);\n on?.(live[fd].decode(bytes, { stream: true }));\n };\n const child = await spawnOn(channel, argv, {\n ...rest,\n onStdout: tee(1, onStdout),\n onStderr: tee(2, onStderr),\n });\n const status = await child.exited;\n const text = (fd: 1 | 2) => new TextDecoder().decode(concat(chunks[fd]));\n return { pid: child.pid, status, stdout: text(1), stderr: text(2) };\n}\n\nasync function terminalOn(\n channel: Channel,\n argv: string[],\n opts: ClientTerminalOptions\n): Promise<ClientTerminal> {\n const { onData, ...options } = opts;\n if (opts.user !== undefined) await since(channel, 8, 'a terminal as a user', async () => {});\n let listener = onData ?? null;\n const backlog: Uint8Array[] = [];\n const started = Promise.withResolvers<number>();\n const { id, done } = channel.request(\n { op: 'open-terminal', argv, options },\n {\n output: (_fd, bytes) => (listener ? listener(bytes) : backlog.push(bytes)),\n started: started.resolve,\n }\n );\n done.catch(started.reject);\n const pid = await started.promise;\n const send = (action: TerminalAction) =>\n void channel.call({ op: 'terminal', terminal: id, ...action }).catch(() => undefined);\n return {\n pid,\n exited: done as Promise<number>,\n get onData() {\n return listener;\n },\n set onData(next) {\n listener = next;\n if (next) for (const bytes of backlog.splice(0)) next(bytes);\n },\n write: (data) => send({ action: 'write', bytes: bytesOf(data) }),\n resize: (cols, rows) => send({ action: 'resize', cols, rows }),\n signal: (name) => send({ action: 'signal', signal: name }),\n close: () => send({ action: 'close' }),\n };\n}\n\nfunction fsOn(channel: Channel): ClientFs {\n const fs = (method: FsMethod, ...args: unknown[]) => channel.call({ op: 'fs', method, args });\n const done = async (method: FsMethod, ...args: unknown[]) => void (await fs(method, ...args));\n return {\n readFile: (path) => fs('readFile', path) as Promise<Uint8Array>,\n readText: async (path) => new TextDecoder().decode((await fs('readFile', path)) as Uint8Array),\n writeFile: (path, data) => done('writeFile', path, data),\n stat: (path) => fs('stat', path) as Promise<FsStat>,\n lstat: (path) => fs('lstat', path) as Promise<FsStat>,\n readdir: (path) => fs('readdir', path) as Promise<string[]>,\n mkdir: (path) => done('mkdir', path),\n rm: (path, o = {}) => done('rm', path, o.force === true),\n rename: (from, to) => done('rename', from, to),\n realpath: (path) => fs('realpath', path) as Promise<string>,\n symlink: (target, path) => done('symlink', target, path),\n readlink: (path) => fs('readlink', path) as Promise<string>,\n exists: (path) => fs('exists', path) as Promise<boolean>,\n async watch(paths, options, onChange) {\n if (channel.protocol[1] < 1) {\n throw new KernelCallError(\n `this kernel speaks protocol ${channel.protocol.join('.')}, which has no watch`,\n 'ENOSYS'\n );\n }\n const { id, done } = channel.request({\n op: 'watch',\n paths,\n recursive: options.recursive === true,\n });\n channel.watching.set(id, onChange);\n try {\n await done;\n } catch (error) {\n channel.watching.delete(id);\n throw error;\n }\n return {\n close: () => {\n if (!channel.watching.delete(id)) return;\n void channel.call({ op: 'unwatch', watch: id }).catch(() => undefined);\n },\n };\n },\n };\n}\n\nfunction since(channel: Channel, minor: number, what: string, run: () => Promise<unknown>) {\n if (channel.protocol[1] < minor) {\n return Promise.reject(\n new KernelCallError(\n `this kernel speaks protocol ${channel.protocol.join('.')}, which has no ${what}`,\n 'ENOSYS'\n )\n );\n }\n return run();\n}\n\nasync function greet(\n channel: Channel,\n lock: string | undefined,\n timeoutMs: number\n): Promise<KernelHello> {\n channel.post({ hello: { protocol: PROTOCOL, ...(lock ? { lock } : {}) } });\n const timer = setTimeout(\n () =>\n channel.end(\n new KernelGoneError(`no slicc-kernel answered on this port within ${timeoutMs} ms`)\n ),\n timeoutMs\n );\n let hello: KernelHello;\n try {\n hello = await channel.greeted.promise;\n } finally {\n clearTimeout(timer);\n }\n const refused = hello.error ?? versionError(hello.protocol);\n if (refused) {\n const error = new Error(refused);\n channel.end(error);\n throw error;\n }\n return hello;\n}\n\nexport async function attachKernel(\n port: MessagePortLike,\n options: AttachOptions = {}\n): Promise<KernelClient> {\n const locks = options.locks === null ? undefined : (options.locks ?? locksOf());\n const own = await holdLock(locks);\n const channel = new Channel(port, own.release);\n const hello = await greet(channel, own.name, options.timeoutMs ?? 10_000);\n channel.protocol = hello.protocol;\n if (hello.lock && locks) void locks.request(hello.lock, () => channel.end(new KernelGoneError()));\n const transport = new RemoteTransport(\n { postMessage: (call) => channel.post(call) },\n hello.traits ?? UNAVAILABLE\n );\n channel.remote = transport;\n return {\n protocol: hello.protocol,\n transport,\n users: hello.users ?? 'off',\n closed: channel.ended.promise,\n spawn: (argv, opts = {}) => spawnOn(channel, argv, opts),\n run: (argv, opts = {}) => runOn(channel, argv, opts),\n openTerminal: (argv, opts = {}) => terminalOn(channel, argv, opts),\n ps: () => channel.call({ op: 'ps' }) as Promise<ProcessEntry[]>,\n mount: (spec) =>\n since(channel, 2, 'mount', () => channel.call({ op: 'mount', spec })) as Promise<MountEntry>,\n umount: async (target) =>\n void (await since(channel, 2, 'umount', () => channel.call({ op: 'umount', target }))),\n mounts: () =>\n since(channel, 2, 'mounts', () => channel.call({ op: 'mounts' })) as Promise<MountEntry[]>,\n kill: async (pid, signal = 'SIGTERM') => void (await channel.call({ op: 'kill', pid, signal })),\n fetch: (req) => {\n const { signal, ...rest } = req;\n return transport.fetch({ ...rest, signal: signal ?? new AbortController().signal });\n },\n dial: (options) => dialOn(channel, options),\n loopbackFetch: (input, options) => loopbackFetch((o) => dialOn(channel, o), input, options),\n fs: fsOn(channel),\n serveCdp: (hook, options = {}) => serveCdpOn(channel, hook, options),\n async close(o = {}) {\n if (channel.failure) return;\n await channel\n .call({ op: 'detach', ...(o.kill ? { kill: true } : {}) })\n .catch(() => undefined);\n channel.end(new KernelGoneError('this client is closed'));\n },\n };\n}\n", "import { BODY_IDLE_MS, readWithin } from './body-idle.ts';\nimport type {\n HeaderList,\n RealmTransport,\n RealmTransportRequest,\n RealmTransportResponse,\n} from './kernel/net/transport.ts';\n\nexport interface LocalProxyOptions {\n url: string;\n key: string;\n fetch?: typeof globalThis.fetch;\n}\n\nexport interface LocalProxyCheckOptions extends LocalProxyOptions {\n permissions?: Pick<Permissions, 'query'>;\n}\n\nexport interface LocalProxyTransportOptions extends LocalProxyOptions {\n maxRequestBody?: number;\n bodyIdleMs?: number;\n}\n\nexport interface LocalProxyProbe {\n rawFetch: number;\n requestBodyStreaming: boolean;\n maxRequestBodyBytes: number;\n kernelTunnel?: number;\n kernelPort?: number;\n cdp?: number;\n}\n\nexport type LocalProxyStatus =\n | { state: 'ready'; probe: LocalProxyProbe }\n | { state: 'blocked' }\n | { state: 'unreachable'; permission: 'granted' | 'prompt' | 'unknown' }\n | { state: 'refused'; status: number; error: string }\n | { state: 'incompatible' };\n\nconst PATH = '/api/fetch-proxy';\nconst RAW_CONTENT_TYPE = 'application/vnd.slicc.raw-fetch';\nconst MAX_HEAD = 1024 * 1024;\nconst MAX_REQUEST_BODY = 64 * 1024 * 1024;\nconst PERMISSIONS = ['loopback-network', 'local-network-access'];\nconst LOOPBACK_PAGE = /^(127\\.\\d+\\.\\d+\\.\\d+|localhost|\\[::1\\])$/;\n\ninterface ResponseHead {\n status: number;\n statusText: string;\n headers: Array<[string, string]>;\n}\n\nconst failure = (message: string, status = 502) =>\n Object.assign(new Error(`local proxy: ${message}`), { status });\n\nfunction encodeHead(url: string, method: string, headers: HeaderList): string {\n return JSON.stringify({ url, method, headers }).replace(\n /[\\u007f-\uFFFF]/g,\n (c) => `\\\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}`\n );\n}\n\nfunction hopHeaders(options: LocalProxyOptions, extra: Record<string, string>): Headers {\n return new Headers({ 'X-Bridge-Token': options.key, ...extra });\n}\n\nfunction send(options: LocalProxyOptions) {\n return options.fetch ?? globalThis.fetch.bind(globalThis);\n}\n\nasync function refusalMessage(response: Response): Promise<string> {\n const text = await response.text().catch(() => '');\n try {\n const parsed = JSON.parse(text) as { error?: unknown };\n if (typeof parsed.error === 'string') return parsed.error;\n } catch {}\n return text || response.statusText || `answered ${response.status}`;\n}\n\nasync function refusal(response: Response): Promise<Error> {\n return failure(await refusalMessage(response), response.ok ? 502 : response.status);\n}\n\nasync function permission(permissions: Pick<Permissions, 'query'> | undefined): Promise<string> {\n if (!permissions) return 'unknown';\n for (const name of PERMISSIONS) {\n try {\n return (await permissions.query({ name } as PermissionDescriptor)).state;\n } catch {}\n }\n return 'unknown';\n}\n\nfunction isHead(value: unknown): value is ResponseHead {\n const head = value as Partial<ResponseHead> | null;\n return (\n !!head &&\n typeof head.status === 'number' &&\n typeof head.statusText === 'string' &&\n Array.isArray(head.headers) &&\n head.headers.every(\n (pair) =>\n Array.isArray(pair) &&\n pair.length === 2 &&\n typeof pair[0] === 'string' &&\n typeof pair[1] === 'string'\n )\n );\n}\n\nfunction concat(a: Uint8Array, b: Uint8Array): Uint8Array {\n const out = new Uint8Array(a.byteLength + b.byteLength);\n out.set(a);\n out.set(b, a.byteLength);\n return out;\n}\n\nasync function readHead(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n idleMs: number\n): Promise<{ head: ResponseHead; rest: Uint8Array }> {\n let buffer: Uint8Array = new Uint8Array(0);\n for (;;) {\n if (buffer.byteLength >= 4) {\n const length = new DataView(buffer.buffer, buffer.byteOffset, 4).getUint32(0);\n if (length > MAX_HEAD) throw failure(`response head of ${length} bytes`);\n if (buffer.byteLength >= 4 + length) {\n let head: unknown;\n try {\n head = JSON.parse(new TextDecoder().decode(buffer.subarray(4, 4 + length)));\n } catch {}\n if (!isHead(head)) throw failure('malformed response head');\n return { head, rest: buffer.subarray(4 + length) };\n }\n }\n const next = await readWithin(reader, idleMs);\n if (next.done) throw failure('closed before the response head');\n buffer = concat(buffer, next.value);\n }\n}\n\nasync function* chunks(\n rest: Uint8Array,\n reader: ReadableStreamDefaultReader<Uint8Array>,\n idleMs: number\n): AsyncGenerator<Uint8Array> {\n try {\n if (rest.byteLength > 0) yield rest;\n for (\n let next = await readWithin(reader, idleMs);\n !next.done;\n next = await readWithin(reader, idleMs)\n ) {\n if (next.value.byteLength > 0) yield next.value;\n }\n } finally {\n await reader.cancel().catch(() => undefined);\n }\n}\n\nexport async function checkLocalProxy(options: LocalProxyCheckOptions): Promise<LocalProxyStatus> {\n const onLoopback = LOOPBACK_PAGE.test(globalThis.location?.hostname ?? '');\n const permissions = onLoopback\n ? undefined\n : (options.permissions ?? globalThis.navigator?.permissions);\n if ((await permission(permissions)) === 'denied') return { state: 'blocked' };\n let response: Response;\n try {\n response = await send(options)(new URL(PATH, options.url), {\n method: 'POST',\n headers: hopHeaders(options, { 'X-Slicc-Raw-Probe': '1' }),\n credentials: 'omit',\n mode: 'cors',\n });\n } catch {\n const now = await permission(permissions);\n if (now === 'denied') return { state: 'blocked' };\n return {\n state: 'unreachable',\n permission: now === 'granted' || now === 'prompt' ? now : 'unknown',\n };\n }\n if (!response.ok) {\n return { state: 'refused', status: response.status, error: await refusalMessage(response) };\n }\n const reply = (await response.json().catch(() => null)) as Partial<LocalProxyProbe> | null;\n if (\n !reply ||\n typeof reply.rawFetch !== 'number' ||\n reply.rawFetch < 1 ||\n typeof reply.requestBodyStreaming !== 'boolean' ||\n typeof reply.maxRequestBodyBytes !== 'number'\n ) {\n return { state: 'incompatible' };\n }\n return {\n state: 'ready',\n probe: {\n rawFetch: reply.rawFetch,\n requestBodyStreaming: reply.requestBodyStreaming,\n maxRequestBodyBytes: reply.maxRequestBodyBytes,\n ...(typeof reply.kernelTunnel === 'number' ? { kernelTunnel: reply.kernelTunnel } : {}),\n ...(typeof reply.kernelPort === 'number' ? { kernelPort: reply.kernelPort } : {}),\n ...(typeof reply.cdp === 'number' ? { cdp: reply.cdp } : {}),\n },\n };\n}\n\nexport async function probeLocalProxy(\n options: LocalProxyCheckOptions\n): Promise<LocalProxyProbe | null> {\n const status = await checkLocalProxy(options);\n return status.state === 'ready' ? status.probe : null;\n}\n\nexport function localProxyTransport(options: LocalProxyTransportOptions): RealmTransport {\n const endpoint = new URL(PATH, options.url);\n return {\n traits: {\n manualRedirects: true,\n encodedBodies: false,\n maxRequestBody: options.maxRequestBody ?? MAX_REQUEST_BODY,\n },\n async fetch(request: RealmTransportRequest): Promise<RealmTransportResponse> {\n let response: Response;\n try {\n response = await send(options)(endpoint, {\n method: 'POST',\n headers: hopHeaders(options, {\n 'X-Slicc-Raw-Request': encodeHead(request.url, request.method, request.headers),\n }),\n ...(request.body ? { body: request.body as BodyInit } : {}),\n signal: request.signal,\n credentials: 'omit',\n mode: 'cors',\n });\n } catch (e) {\n if (request.signal.aborted) throw e;\n throw failure(`${endpoint.origin} is unreachable or refuses this origin`);\n }\n const type = response.headers.get('content-type') ?? '';\n if (response.status !== 200 || !type.startsWith(RAW_CONTENT_TYPE) || !response.body) {\n throw await refusal(response);\n }\n const reader = response.body.getReader();\n const idleMs = options.bodyIdleMs ?? BODY_IDLE_MS;\n let framed: { head: ResponseHead; rest: Uint8Array };\n try {\n framed = await readHead(reader, idleMs);\n } catch (e) {\n await reader.cancel().catch(() => undefined);\n throw e;\n }\n const body = chunks(framed.rest, reader, idleMs);\n return {\n status: framed.head.status,\n statusText: framed.head.statusText,\n headers: framed.head.headers,\n body,\n cancel: async () => {\n await body.return(undefined);\n await reader.cancel().catch(() => undefined);\n },\n };\n },\n };\n}\n", "import {\n DRIVER_PROTOCOL,\n type DriverAttr,\n type DriverCapabilities,\n type DriverEntry,\n type DriverOwner,\n type DriverRequest,\n type DriverStatfs,\n driverVersionError,\n type KernelDriverHello,\n type MountRequestInfo,\n} from './protocol.ts';\n\nexport type {\n DriverAttr,\n DriverCapabilities,\n DriverEntry,\n DriverOwner,\n DriverStatfs,\n MountRequestInfo,\n} from './protocol.ts';\n\nimport { fresh } from '../bytes.ts';\n\nexport interface OpenFlags {\n write: boolean;\n create: boolean;\n truncate: boolean;\n exclusive: boolean;\n ifMatch?: string;\n owner?: DriverOwner;\n}\n\nexport interface FilesystemHandlers {\n mount?(\n info: MountRequestInfo\n ): Promise<DriverCapabilities | undefined> | DriverCapabilities | undefined;\n getattr(path: string): Promise<DriverAttr>;\n readdir(path: string): Promise<DriverEntry[]>;\n open(path: string, flags: OpenFlags): Promise<number>;\n read(fh: number, offset: number, size: number): Promise<Uint8Array>;\n write(fh: number, offset: number, bytes: Uint8Array): Promise<void>;\n release(fh: number): Promise<void>;\n mkdir(path: string, owner?: DriverOwner): Promise<void>;\n rmdir(path: string): Promise<void>;\n unlink(path: string): Promise<void>;\n rename(from: string, to: string): Promise<void>;\n link?(from: string, to: string): Promise<void>;\n symlink?(target: string, path: string, owner?: DriverOwner): Promise<void>;\n readlink?(path: string): Promise<string>;\n setattr?(path: string, attr: DriverSetAttr): Promise<void>;\n statfs?(): Promise<DriverStatfs>;\n}\n\nexport interface DriverSetAttr {\n mode?: number;\n mtime?: number;\n size?: number;\n uid?: number;\n gid?: number;\n}\n\nfunction ownerOf(req: DriverOwner): DriverOwner | undefined {\n const owner = {\n ...(req.uid !== undefined ? { uid: req.uid } : {}),\n ...(req.gid !== undefined ? { gid: req.gid } : {}),\n ...(req.mode !== undefined ? { mode: req.mode } : {}),\n };\n return Object.keys(owner).length > 0 ? owner : undefined;\n}\n\nfunction withOwner<T extends object>(base: T, owner: DriverOwner | undefined): T {\n return owner ? { ...base, owner } : base;\n}\n\nexport interface DriverPort {\n postMessage(message: unknown, transfer?: Transferable[]): void;\n addEventListener(type: 'message', handler: (event: MessageEvent) => void): void;\n start?(): void;\n}\n\nexport interface ServedFilesystem {\n invalidate(paths: string[] | true): void;\n}\n\nexport function fsError(code: string, message = code): Error & { code: string } {\n return Object.assign(new Error(message), { code });\n}\n\nasync function dispatch(h: FilesystemHandlers, req: DriverRequest): Promise<unknown> {\n switch (req.op) {\n case 'getattr':\n return h.getattr(req.path);\n case 'readdir':\n return h.readdir(req.path);\n case 'open':\n return h.open(\n req.path,\n withOwner(\n {\n write: req.write,\n create: req.create,\n truncate: req.truncate,\n exclusive: req.exclusive,\n ...(req.ifMatch !== undefined ? { ifMatch: req.ifMatch } : {}),\n },\n ownerOf(req)\n )\n );\n case 'read':\n return h.read(req.fh, req.offset, req.size);\n case 'write':\n return h.write(req.fh, req.offset, req.bytes);\n case 'release':\n return h.release(req.fh);\n case 'mkdir':\n return ownerOf(req) ? h.mkdir(req.path, ownerOf(req)) : h.mkdir(req.path);\n case 'rmdir':\n return h.rmdir(req.path);\n case 'unlink':\n return h.unlink(req.path);\n case 'rename':\n return h.rename(req.from, req.to);\n case 'link':\n if (!h.link) throw fsError('EPERM', 'this file system has no hard links');\n return h.link(req.from, req.to);\n case 'symlink':\n if (!h.symlink) throw fsError('EPERM', 'this file system has no symlinks');\n return ownerOf(req)\n ? h.symlink(req.target, req.path, ownerOf(req))\n : h.symlink(req.target, req.path);\n case 'readlink':\n if (!h.readlink) throw fsError('EINVAL', `${req.path} is not a symlink`);\n return h.readlink(req.path);\n case 'setattr':\n return h.setattr?.(req.path, {\n ...(req.mode !== undefined ? { mode: req.mode } : {}),\n ...(req.mtime !== undefined ? { mtime: req.mtime } : {}),\n ...(req.size !== undefined ? { size: req.size } : {}),\n ...(req.uid !== undefined ? { uid: req.uid } : {}),\n ...(req.gid !== undefined ? { gid: req.gid } : {}),\n });\n case 'statfs':\n return h.statfs?.() ?? null;\n default:\n throw fsError('ENOSYS', `unknown driver op ${(req as { op: string }).op}`);\n }\n}\n\nexport function serveFilesystem(\n port: DriverPort,\n handlers: FilesystemHandlers,\n capabilities: DriverCapabilities = {},\n options: { owned?: boolean } = {}\n): ServedFilesystem {\n let open = false;\n const reply = (message: object, transfer: Transferable[] = []) =>\n port.postMessage(message, transfer);\n async function hello(message: KernelDriverHello): Promise<void> {\n const refused = driverVersionError(message.protocol);\n if (refused) {\n reply({ hello: { protocol: DRIVER_PROTOCOL, error: refused, errno: 'EPROTO' } });\n return;\n }\n try {\n const refined = await handlers.mount?.(message.mount);\n open = true;\n reply({\n hello: { protocol: DRIVER_PROTOCOL, capabilities: { ...capabilities, ...refined } },\n });\n } catch (err) {\n const code = (err as { code?: unknown })?.code;\n reply({\n hello: {\n protocol: DRIVER_PROTOCOL,\n error: err instanceof Error ? err.message : String(err),\n errno: typeof code === 'string' ? code : 'EIO',\n },\n });\n }\n }\n port.addEventListener('message', (event) => {\n const data = event.data as { hello?: KernelDriverHello } & DriverRequest;\n if (data.hello) {\n void hello(data.hello);\n return;\n }\n if (!open) return;\n dispatch(handlers, data).then(\n (result) => {\n if (result instanceof Uint8Array) {\n const whole = result.byteOffset === 0 && result.byteLength === result.buffer.byteLength;\n const bytes = options.owned && whole ? result : fresh(result);\n reply({ id: data.id, result: bytes }, [bytes.buffer]);\n } else reply({ id: data.id, result: result ?? null });\n },\n (err: unknown) => {\n const code = (err as { code?: unknown })?.code;\n reply({\n id: data.id,\n errno: typeof code === 'string' ? code : 'EIO',\n message: err instanceof Error ? err.message : String(err),\n });\n }\n );\n });\n port.start?.();\n return { invalidate: (paths) => reply({ invalidate: paths }) };\n}\n", "import { type FilesystemHandlers, fsError, type OpenFlags, serveFilesystem } from './driver.ts';\nimport { type MediumHandlers, mediumSlot } from './medium.ts';\nimport type { MountSpec, OpenedDriver } from './mount-fs.ts';\nimport type { DriverAttr, DriverCapabilities, DriverEntry, DriverStatfs } from './protocol.ts';\n\nexport interface HostfsGrant {\n url: string;\n token: string;\n readonly?: boolean;\n capabilities?: DriverCapabilities;\n}\n\nexport interface HostfsPortGrant {\n port: MessagePort;\n token?: string;\n capabilities?: DriverCapabilities;\n}\n\nexport type HostfsGrantHook = (\n source: string,\n options: { readonly: boolean }\n) => Promise<HostfsGrant | HostfsPortGrant>;\n\nexport type FetchLike = (url: string, init: RequestInit) => Promise<Response>;\n\nexport interface HostfsEvent {\n paths?: string[];\n all?: boolean;\n ping?: number;\n}\n\nexport interface HostfsTransport {\n readonly capabilities: DriverCapabilities;\n readonly token: string;\n readonly maxIo: number;\n readonly gone?: boolean;\n retire?(why: string): void;\n cleanup?(op: string, body: Record<string, unknown>): Promise<unknown>;\n call<T>(op: string, body?: Record<string, unknown>, handle?: boolean): Promise<T>;\n read(fh: number, offset: number, size: number, ifMatch?: string): Promise<Uint8Array>;\n write(fh: number, offset: number, bytes: Uint8Array): Promise<void>;\n watch(\n signal: AbortSignal,\n onEvent: (event: HostfsEvent) => void,\n onOpen?: () => void\n ): Promise<void>;\n}\n\nexport type HostfsConnect = (\n source: string,\n options: { readonly: boolean }\n) => Promise<HostfsTransport>;\n\nexport const HOSTFS_IO = 16 * 1024 * 1024;\n\nconst codeOf = (err: unknown) => (err as { code?: unknown } | null)?.code;\n\nexport const unreachable = (err: unknown) => codeOf(err) === 'ENOTCONN';\n\nfunction rel(path: string): string {\n return path.replace(/^\\/+/, '');\n}\n\nexport class HostfsClient implements HostfsTransport {\n private grant: HostfsGrant;\n private readonly regrant: () => Promise<HostfsGrant>;\n private readonly fetch: FetchLike;\n\n constructor(grant: HostfsGrant, regrant: () => Promise<HostfsGrant>, fetch: FetchLike) {\n this.grant = grant;\n this.regrant = regrant;\n this.fetch = fetch;\n }\n\n get capabilities(): DriverCapabilities {\n return this.grant.capabilities ?? {};\n }\n\n get token(): string {\n return this.grant.token;\n }\n\n get maxIo(): number {\n return this.capabilities.maxIo ?? HOSTFS_IO;\n }\n\n private retired: string | undefined;\n private readonly stop = new AbortController();\n\n get gone(): boolean {\n return this.retired !== undefined;\n }\n\n retire(why: string): void {\n this.retired ??= why;\n this.stop.abort();\n }\n\n private async send(\n path: string,\n init: RequestInit,\n handle = false,\n retried = false,\n cleanup = false\n ): Promise<Response> {\n if (this.retired && !cleanup) throw fsError('ENOTCONN', this.retired);\n const stop = cleanup ? undefined : this.stop.signal;\n const signal =\n init.signal && stop ? AbortSignal.any([init.signal, stop]) : (init.signal ?? stop);\n let response: Response;\n try {\n response = await this.fetch(`${this.grant.url}${path}`, {\n ...init,\n ...(signal ? { signal } : {}),\n credentials: 'omit',\n headers: {\n ...(init.headers as Record<string, string>),\n 'X-Hostfs-Token': this.grant.token,\n },\n });\n } catch (err) {\n throw fsError('ENOTCONN', `the host proxy is unreachable: ${(err as Error).message}`);\n }\n if (response.ok) return response;\n if (response.headers.get('X-Proxy-Error')) {\n await response.body?.cancel();\n if (retried || response.status !== 403) {\n throw fsError('EACCES', `the host proxy refused this folder (${response.status})`);\n }\n this.grant = await this.regrant();\n if (handle)\n throw fsError('ESTALE', 'the folder was granted again, so its open files are gone');\n return this.send(path, init, false, true);\n }\n const errno = response.headers.get('X-Hostfs-Errno') ?? 'EIO';\n const body = (await response.json().catch(() => ({}))) as { message?: unknown };\n throw fsError(errno, typeof body.message === 'string' ? body.message : errno);\n }\n\n async call<T>(op: string, body: Record<string, unknown> = {}, handle = false): Promise<T> {\n const response = await this.send(\n '/api/hostfs',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ op, ...body }),\n },\n handle\n );\n return (await response.json()) as T;\n }\n\n async cleanup(op: string, body: Record<string, unknown>): Promise<unknown> {\n const response = await this.send(\n '/api/hostfs',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ op, ...body }),\n },\n true,\n false,\n true\n );\n return response.json().catch(() => null);\n }\n\n async read(fh: number, offset: number, size: number, ifMatch?: string): Promise<Uint8Array> {\n const response = await this.send(\n '/api/hostfs',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ op: 'read', fh, offset, size, ...(ifMatch ? { ifMatch } : {}) }),\n },\n true\n );\n return new Uint8Array(await response.arrayBuffer());\n }\n\n async write(fh: number, offset: number, bytes: Uint8Array): Promise<void> {\n const response = await this.send(\n '/api/hostfs/write',\n {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/octet-stream',\n 'X-Hostfs-Request': JSON.stringify({ fh, offset }),\n },\n body: bytes as BodyInit,\n },\n true\n );\n await response.body?.cancel();\n }\n\n async watch(\n signal: AbortSignal,\n onEvent: (event: HostfsEvent) => void,\n onOpen: () => void = () => undefined\n ): Promise<void> {\n const response = await this.send('/api/hostfs/watch', { method: 'POST', signal });\n onOpen();\n const reader = (response.body as ReadableStream<Uint8Array>).getReader();\n const decoder = new TextDecoder();\n let buffered = '';\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) return;\n buffered += decoder.decode(value, { stream: true });\n let end = buffered.indexOf('\\n');\n while (end >= 0) {\n const line = buffered.slice(0, end).trim();\n buffered = buffered.slice(end + 1);\n if (line) onEvent(JSON.parse(line) as HostfsEvent);\n end = buffered.indexOf('\\n');\n }\n }\n } catch (err) {\n if (signal.aborted) return;\n throw fsError('ENOTCONN', `the host proxy's watch broke: ${(err as Error).message}`);\n } finally {\n reader.releaseLock();\n }\n }\n}\n\ninterface Remote {\n client: HostfsTransport;\n token: string;\n fh: number;\n etag: string | undefined;\n restore: Restore | undefined;\n}\n\ntype Restore = { path: string; mode: number; was: DriverAttr };\n\nexport const RESTORE_AGAIN_MS = 30_000;\n\nexport function hostfsHandlers(\n current: () => HostfsTransport,\n againMs = RESTORE_AGAIN_MS\n): MediumHandlers {\n const handles = new Map<number, Remote>();\n let nextFh = 0;\n const fresh = (remote: Remote): Remote => {\n if (remote.client.token === remote.token && !remote.client.gone) return remote;\n throw fsError('ESTALE', 'the folder was granted again, so this open file is gone');\n };\n const live = (fh: number): Remote => {\n const remote = handles.get(fh);\n if (!remote) throw fsError('EBADF', `handle ${fh}`);\n return fresh(remote);\n };\n const call = <T>(op: string, body: Record<string, unknown> = {}) => current().call<T>(op, body);\n const same = (was: DriverAttr, mode: number, seen: DriverAttr | null) =>\n seen?.mode === (mode | 0o200) &&\n (was.ino !== undefined && seen.ino !== undefined\n ? seen.ino === was.ino\n : seen.size === was.size && seen.mtime === was.mtime);\n const settle = (client: HostfsTransport, { was, ...restore }: Restore) =>\n client.call('setattr', restore).catch((err: unknown) => {\n if (!client.gone || !client.cleanup) throw err;\n void client.cleanup('setattr', restore).catch(() => {});\n const timer = setTimeout(async () => {\n const seen = (await client\n .cleanup?.('stat', { path: restore.path })\n .catch(() => null)) as DriverAttr | null;\n if (same(was, restore.mode, seen))\n void client.cleanup?.('setattr', restore).catch(() => {});\n }, againMs) as { unref?: () => void };\n timer.unref?.();\n });\n async function writable(client: HostfsTransport, path: string, flags: OpenFlags) {\n const { ifMatch: _, ...asked } = flags;\n const opening = () =>\n client.call<{ fh: number; attr?: DriverAttr }>('open', { path: rel(path), ...asked });\n try {\n return { opened: await opening(), restore: undefined };\n } catch (err) {\n if (!flags.write || codeOf(err) !== 'EACCES') throw err;\n const was = await client.call<DriverAttr>('stat', { path: rel(path) });\n const mode = was.mode ?? 0;\n if (mode & 0o200) throw err;\n const restore = { path: rel(path), mode, was };\n const opened = await client\n .call('setattr', { path: rel(path), mode: mode | 0o200 })\n .then(opening)\n .catch(async (again: unknown) => {\n await settle(client, restore).catch(() => {});\n throw again;\n });\n return { opened, restore };\n }\n }\n const handlers: MediumHandlers = {\n getattr: async (path) => await call<DriverAttr>('stat', { path: rel(path) }),\n async readdir(path) {\n const { entries } = await call<{ entries: Array<{ name: string; attr: DriverAttr }> }>(\n 'list',\n { path: rel(path) }\n );\n return entries.map(({ name, attr }): DriverEntry => ({ name, kind: attr.kind, attr }));\n },\n async open(path: string, flags: OpenFlags) {\n const client = current();\n const token = client.token;\n const { opened, restore } = await writable(client, path, flags);\n if (flags.ifMatch !== undefined && opened.attr?.etag !== flags.ifMatch) {\n await client.call('release', { fh: opened.fh }, true);\n throw fsError('ESTALE', `${path} changed on the host while it was being read`);\n }\n handles.set(++nextFh, {\n client,\n token,\n fh: opened.fh,\n etag: flags.write ? undefined : opened.attr?.etag,\n restore,\n });\n return nextFh;\n },\n async read(fh, offset, size) {\n const remote = live(fh);\n return remote.client.read(\n remote.fh,\n offset,\n Math.min(size, remote.client.maxIo),\n remote.etag\n );\n },\n async write(fh, offset, bytes) {\n const remote = live(fh);\n const most = remote.client.maxIo;\n for (let at = 0; at < bytes.length; at += most) {\n await remote.client.write(remote.fh, offset + at, bytes.subarray(at, at + most));\n }\n },\n async release(fh) {\n const remote = handles.get(fh);\n if (!remote) throw fsError('EBADF', `handle ${fh}`);\n handles.delete(fh);\n try {\n await fresh(remote).client.call('release', { fh: remote.fh }, true);\n } finally {\n if (remote.restore) await settle(current(), remote.restore);\n }\n },\n mkdir: async (path) => void (await call('mkdir', { path: rel(path) })),\n rmdir: async (path) => void (await call('rmdir', { path: rel(path) })),\n unlink: async (path) => void (await call('unlink', { path: rel(path) })),\n rename: async (from, to) => void (await call('rename', { from: rel(from), to: rel(to) })),\n symlink: async (target, path) => void (await call('symlink', { target, path: rel(path) })),\n readlink: async (path) =>\n (await call<{ target: string }>('readlink', { path: rel(path) })).target,\n async setattr(path, { size, ...change }) {\n if (size !== undefined && !current().capabilities.ranges) await resize(handlers, path, size);\n else if (size !== undefined) change = { ...change, size } as typeof change;\n if (Object.keys(change).length > 0) await call('setattr', { path: rel(path), ...change });\n },\n statfs: () => call<DriverStatfs>('statfs'),\n };\n return handlers;\n}\n\nconst KEEP: OpenFlags = { write: false, create: false, truncate: false, exclusive: false };\n\nasync function resize(h: FilesystemHandlers, path: string, size: number): Promise<void> {\n const was = (await h.getattr(path)).size;\n if (size === was) return;\n const kept: Uint8Array[] = [];\n if (size < was && size > 0) {\n const fh = await h.open(path, KEEP);\n try {\n for (let at = 0; at < size; ) {\n const bytes = await h.read(fh, at, size - at);\n if (bytes.length === 0) break;\n kept.push(bytes);\n at += bytes.length;\n }\n } finally {\n await h.release(fh);\n }\n }\n const fh = await h.open(path, { ...KEEP, write: true, truncate: size < was });\n try {\n if (size > was) await h.write(fh, size - 1, new Uint8Array(1));\n let at = 0;\n for (const bytes of kept) {\n await h.write(fh, at, bytes);\n at += bytes.length;\n }\n } finally {\n await h.release(fh);\n }\n}\n\nexport interface WatchLoop {\n connect(): Promise<HostfsTransport>;\n up(client: HostfsTransport): void;\n event(event: HostfsEvent): void;\n down(): void;\n silenceMs?: number;\n backoffMs?: [number, number];\n connectMs?: number;\n}\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n const done = () => {\n clearTimeout(timer);\n signal.removeEventListener('abort', done);\n resolve();\n };\n const timer = setTimeout(done, ms);\n signal.addEventListener('abort', done);\n });\n}\n\nexport interface Watching {\n ready: Promise<void>;\n kick(): void;\n}\n\nexport function keepWatching(loop: WatchLoop, signal: AbortSignal): Watching {\n const silenceMs = loop.silenceMs ?? 45_000;\n const [first, most] = loop.backoffMs ?? [1000, 30_000];\n const ready = Promise.withResolvers<void>();\n const capped = setTimeout(ready.resolve, loop.connectMs ?? 15_000);\n const uncap = () => clearTimeout(capped);\n void ready.promise.then(uncap);\n signal.addEventListener('abort', uncap, { once: true });\n let wait = first;\n let up = false;\n let current: AbortController | undefined;\n async function session(): Promise<boolean> {\n const session = new AbortController();\n current = session;\n const stop = () => session.abort();\n signal.addEventListener('abort', stop);\n let timer: ReturnType<typeof setTimeout> | undefined;\n const quiet = () => {\n clearTimeout(timer);\n timer = setTimeout(stop, silenceMs);\n };\n let opened = false;\n try {\n const client = await loop.connect();\n quiet();\n await client.watch(\n session.signal,\n (event) => {\n quiet();\n if (!event.ping) loop.event(event);\n },\n () => {\n quiet();\n opened = true;\n up = true;\n loop.up(client);\n ready.resolve();\n }\n );\n return opened;\n } catch {\n return opened;\n } finally {\n clearTimeout(timer);\n signal.removeEventListener('abort', stop);\n }\n }\n void (async () => {\n while (!signal.aborted) {\n const began = Date.now();\n const opened = await session();\n if (signal.aborted) return;\n if (opened && Date.now() - began >= first) {\n wait = first;\n continue;\n }\n if (!opened && up) {\n up = false;\n loop.down();\n }\n ready.resolve();\n await sleep(wait, signal);\n wait = Math.min(wait * 2, most);\n }\n })();\n return { ready: ready.promise, kick: () => current?.abort() };\n}\n\nexport function invalidation(event: HostfsEvent): string[] | true {\n return event.paths ?? true;\n}\n\nexport interface HostfsTiming {\n silenceMs?: number;\n backoffMs?: [number, number];\n connectMs?: number;\n requestMs?: number;\n callMs?: number;\n beatMs?: number;\n deadMs?: number;\n}\n\nexport const PORT_REQUEST_MS = 60_000;\nexport const HOSTFS_CALL_MS = 20_000;\nexport const PORT_BEAT_MS = 1000;\nexport const PORT_DEAD_MS = 10_000;\nexport const PORT_LINGER_MS = 1000;\n\nexport interface PortLiveness {\n requestMs?: number;\n beatMs?: number;\n deadMs?: number;\n lingerMs?: number;\n}\n\nexport function timed(transport: HostfsTransport, ms: number): HostfsTransport {\n const inflight = new Set<Promise<unknown>>();\n const guard = <T>(\n name: string,\n run: () => Promise<T>,\n late?: (value: T) => void,\n expire?: (running: Promise<T>) => void\n ) =>\n new Promise<T>((resolve, reject) => {\n let expired = false;\n const running = run();\n inflight.add(running);\n const done = () => inflight.delete(running);\n running.then(done, done);\n const timer = setTimeout(() => {\n expired = true;\n const why = `the host folder did not answer ${name} within ${ms} ms`;\n transport.retire?.(why);\n expire?.(running);\n reject(fsError('ENOTCONN', why));\n }, ms);\n running.then(\n (value) => {\n clearTimeout(timer);\n if (expired) late?.(value);\n resolve(value);\n },\n (err) => {\n clearTimeout(timer);\n reject(err);\n }\n );\n });\n const cleanup = async (op: string, body: Record<string, unknown>, skip?: Promise<unknown>) => {\n await Promise.allSettled([...inflight].filter((work) => work !== skip));\n return await transport.cleanup?.(op, body);\n };\n const release = (opened: unknown) => {\n const fh = (opened as { fh?: unknown } | null)?.fh;\n if (typeof fh === 'number') void cleanup('release', { fh }).catch(() => {});\n };\n return {\n get capabilities() {\n return transport.capabilities;\n },\n get token() {\n return transport.token;\n },\n get maxIo() {\n return transport.maxIo;\n },\n get gone() {\n return transport.gone;\n },\n retire: (why) => transport.retire?.(why),\n ...(transport.cleanup ? { cleanup } : {}),\n call: (op, body, handle) =>\n guard(\n op,\n () => transport.call(op, body, handle),\n op === 'open' ? release : undefined,\n op === 'release'\n ? (running) => void cleanup('release', body ?? {}, running).catch(() => {})\n : undefined\n ),\n read: (fh, offset, size, ifMatch) =>\n guard('read', () => transport.read(fh, offset, size, ifMatch)),\n write: (fh, offset, bytes) => guard('write', () => transport.write(fh, offset, bytes)),\n watch: (signal, onEvent, onOpen) => transport.watch(signal, onEvent, onOpen),\n };\n}\nconst PORT_MS_PER_MIB = 1000;\n\nlet nextPortToken = 0;\n\ntype PortReply = {\n id: number;\n pong?: boolean;\n result?: unknown;\n bytes?: Uint8Array;\n event?: HostfsEvent;\n open?: boolean;\n end?: boolean;\n error?: { code?: string; message?: string };\n};\n\nexport class PortTransport implements HostfsTransport {\n readonly capabilities: DriverCapabilities;\n readonly token: string;\n private readonly port: MessagePort;\n private readonly requestMs: number;\n private readonly waiting = new Map<number, (reply: PortReply) => void>();\n private next = 0;\n private dead: string | undefined;\n private readonly beatMs: number;\n private readonly deadMs: number;\n private readonly lingerMs: number;\n private beat: ReturnType<typeof setInterval> | undefined;\n private answers = false;\n private pinged: number | undefined;\n\n constructor(grant: HostfsPortGrant, liveness: PortLiveness = {}) {\n this.port = grant.port;\n this.requestMs = liveness.requestMs ?? PORT_REQUEST_MS;\n this.beatMs = liveness.beatMs ?? PORT_BEAT_MS;\n this.deadMs = liveness.deadMs ?? PORT_DEAD_MS;\n this.lingerMs = liveness.lingerMs ?? PORT_LINGER_MS;\n this.capabilities = grant.capabilities ?? {};\n this.token = grant.token ?? `port-${++nextPortToken}`;\n this.port.addEventListener('message', (event: MessageEvent<PortReply>) => {\n if (event.data?.pong) {\n this.answers = true;\n this.pinged = undefined;\n } else this.waiting.get(event.data?.id)?.(event.data);\n });\n this.port.addEventListener('close', () => this.fail(\"the folder's port closed\"));\n this.port.start();\n }\n\n get maxIo(): number {\n return this.capabilities.maxIo ?? HOSTFS_IO;\n }\n\n get gone(): boolean {\n return this.dead !== undefined;\n }\n\n retire(why: string): void {\n this.fail(why);\n }\n\n private ping(): void {\n if (this.pinged !== undefined) return;\n this.pinged = Date.now();\n try {\n this.port.postMessage({ id: 0, op: 'ping' });\n } catch {}\n }\n\n private watchBeat(): void {\n if (this.beat || this.dead) return;\n this.ping();\n this.beat = setInterval(() => {\n if (this.waiting.size === 0) {\n clearInterval(this.beat);\n this.beat = undefined;\n return;\n }\n if (this.answers && this.pinged !== undefined && Date.now() - this.pinged > this.deadMs) {\n this.fail(\"the folder's port stopped answering\");\n return;\n }\n this.ping();\n }, this.beatMs);\n }\n\n async cleanup(op: string, body: Record<string, unknown>): Promise<void> {\n if (this.closed) throw fsError('ENOTCONN', \"the folder's port is closed\");\n this.port.postMessage({ id: 0, op: 'cleanup', name: op, body });\n }\n\n private closed = false;\n\n fail(why: string): void {\n if (this.dead === undefined) {\n setTimeout(() => {\n try {\n this.port.postMessage({ id: 0, op: 'bye' });\n } catch {}\n this.closed = true;\n this.port.close();\n }, this.lingerMs);\n }\n clearInterval(this.beat);\n this.beat = undefined;\n this.dead ??= why;\n for (const settle of [...this.waiting.values()])\n settle({ id: 0, error: { code: 'ENOTCONN', message: why } });\n }\n\n private ask(\n message: Record<string, unknown>,\n bytes = 0,\n transfer: Transferable[] = []\n ): Promise<PortReply> {\n const id = ++this.next;\n if (this.dead) return Promise.reject(fsError('ENOTCONN', this.dead));\n return new Promise((resolve, reject) => {\n const timer = setTimeout(\n () => {\n this.waiting.delete(id);\n reject(fsError('ETIMEDOUT', \"the folder's port did not answer\"));\n this.fail(\"the folder's port stopped answering\");\n },\n this.requestMs + Math.ceil(bytes / 1_048_576) * PORT_MS_PER_MIB\n );\n this.watchBeat();\n this.waiting.set(id, (reply) => {\n clearTimeout(timer);\n this.waiting.delete(id);\n if (reply.error) reject(fsError(reply.error.code ?? 'EIO', reply.error.message ?? ''));\n else resolve(reply);\n });\n try {\n this.port.postMessage({ id, ...message }, transfer);\n } catch (err) {\n this.fail(`the folder's port is closed: ${(err as Error).message}`);\n }\n });\n }\n\n async call<T>(op: string, body: Record<string, unknown> = {}): Promise<T> {\n return (await this.ask({ op: 'call', name: op, body })).result as T;\n }\n\n async read(fh: number, offset: number, size: number, ifMatch?: string): Promise<Uint8Array> {\n const reply = await this.ask(\n { op: 'read', fh, offset, size, ...(ifMatch ? { ifMatch } : {}) },\n size\n );\n return reply.bytes ?? new Uint8Array(0);\n }\n\n async write(fh: number, offset: number, bytes: Uint8Array): Promise<void> {\n await this.ask({ op: 'write', fh, offset, bytes }, bytes.length);\n }\n\n watch(\n signal: AbortSignal,\n onEvent: (event: HostfsEvent) => void,\n onOpen: () => void = () => undefined\n ): Promise<void> {\n const id = ++this.next;\n if (this.dead) return Promise.reject(fsError('ENOTCONN', this.dead));\n if (signal.aborted) {\n this.fail(\"the folder's watch ended\");\n return Promise.resolve();\n }\n return new Promise<void>((resolve, reject) => {\n const finish = () => {\n this.waiting.delete(id);\n signal.removeEventListener('abort', stop);\n };\n const stop = () => {\n finish();\n try {\n this.port.postMessage({ id, op: 'unwatch' });\n } catch {}\n resolve();\n };\n this.watchBeat();\n this.waiting.set(id, (reply) => {\n if (reply.open) return onOpen();\n if (reply.event) return onEvent(reply.event);\n finish();\n if (reply.error) reject(fsError(reply.error.code ?? 'ENOTCONN', reply.error.message ?? ''));\n else resolve();\n });\n signal.addEventListener('abort', stop, { once: true });\n try {\n this.port.postMessage({ id, op: 'watch' });\n } catch (err) {\n finish();\n reject(fsError('ENOTCONN', `the folder's port is closed: ${(err as Error).message}`));\n }\n }).finally(() => this.fail(\"the folder's watch ended\"));\n }\n}\n\nconst errorOf = (err: unknown) => ({\n code: typeof codeOf(err) === 'string' ? (codeOf(err) as string) : 'EIO',\n message: (err as Error | null)?.message ?? String(err),\n});\n\nexport function serveHostfsPort(port: MessagePort, transport: HostfsTransport): () => void {\n const watches = new Map<number, AbortController>();\n const handles = new Set<number>();\n let stopped = false;\n const closeHandles = () => {\n for (const fh of handles) void transport.call('release', { fh }, true).catch(() => {});\n handles.clear();\n };\n const send = (reply: PortReply, transfer: Transferable[] = []) =>\n port.postMessage(reply, transfer);\n const pending = new Set<Promise<unknown>>();\n const track = <T>(work: Promise<T>) => {\n pending.add(work);\n const done = () => pending.delete(work);\n work.then(done, done);\n return work;\n };\n const answer = async (name: string, body: Record<string, unknown>) => {\n const result = await track(transport.call(name, body));\n const opened = (result as { fh?: unknown } | null)?.fh;\n if (name === 'open' && typeof opened === 'number') handles.add(opened);\n if (name === 'release') handles.delete(body?.fh as number);\n if (stopped) closeHandles();\n return result;\n };\n const listener = async ({\n data,\n }: MessageEvent<Record<string, unknown> & { id: number; op: string }>) => {\n const { id, op } = data;\n if (op === 'ping') return send({ id, pong: true });\n if (op === 'bye') return stop();\n if (op === 'cleanup')\n return void Promise.allSettled([...pending])\n .then(() => answer(data.name as string, data.body as Record<string, unknown>))\n .catch(() => {});\n if (op === 'unwatch') return watches.get(id)?.abort();\n if (op === 'watch') {\n const stop = new AbortController();\n watches.set(id, stop);\n try {\n await transport.watch(\n stop.signal,\n (event) => send({ id, event }),\n () => send({ id, open: true })\n );\n send({ id, end: true });\n } catch (err) {\n send({ id, error: errorOf(err) });\n } finally {\n watches.delete(id);\n }\n return;\n }\n try {\n if (op === 'read') {\n const read = await track(\n transport.read(\n data.fh as number,\n data.offset as number,\n data.size as number,\n data.ifMatch as string | undefined\n )\n );\n const bytes = read.slice();\n return send({ id, bytes }, [bytes.buffer as ArrayBuffer]);\n }\n if (op === 'write') {\n await track(\n transport.write(data.fh as number, data.offset as number, data.bytes as Uint8Array)\n );\n return send({ id });\n }\n if (op !== 'call') throw fsError('EINVAL', `unknown hostfs port op ${op}`);\n send({ id, result: await answer(data.name as string, data.body as Record<string, unknown>) });\n } catch (err) {\n send({ id, error: errorOf(err) });\n }\n };\n const stop = () => {\n stopped = true;\n port.removeEventListener('message', listener as (event: MessageEvent) => void);\n port.removeEventListener('close', stop);\n for (const watch of watches.values()) watch.abort();\n closeHandles();\n port.close();\n };\n port.addEventListener('message', listener as (event: MessageEvent) => void);\n port.addEventListener('close', stop);\n port.start();\n return stop;\n}\n\nexport function grantConnect(\n hook: HostfsGrantHook,\n fetch: FetchLike,\n liveness: PortLiveness = {}\n): HostfsConnect {\n return async (source, options) => {\n const first = await hook(source, options);\n if ('port' in first) return new PortTransport(first, liveness);\n const grant = async () => {\n const again = await hook(source, options);\n if ('port' in again)\n throw fsError('ESTALE', 'the folder moved to a port, so its open files are gone');\n return again;\n };\n return new HostfsClient(first, grant, fetch);\n };\n}\n\nexport async function openHostfs(\n spec: MountSpec,\n connect: HostfsConnect,\n timing: HostfsTiming = {}\n): Promise<OpenedDriver> {\n const readonly = spec.options?.ro !== undefined;\n const { port1, port2 } = new MessageChannel();\n const slot = mediumSlot<HostfsTransport>(\n async (err) => unreachable(err),\n () => watching.kick()\n );\n const stop = new AbortController();\n let active: HostfsTransport | undefined;\n const handlers = hostfsHandlers(() => active as HostfsTransport);\n const ranged = () => ({\n ...(active?.capabilities.ranges === true ? { ranges: true } : {}),\n ...(active ? { maxIo: Math.min(active.maxIo, HOSTFS_IO) } : {}),\n });\n const served = serveFilesystem(\n port2,\n { ...slot.handlers, mount: ranged },\n {\n symlinks: true,\n chmod: true,\n listingStats: true,\n maxIo: HOSTFS_IO,\n ...(readonly ? { readonly: true } : {}),\n }\n );\n const watching = keepWatching(\n {\n connect: () => connect(spec.source, { readonly }),\n up(client) {\n active = timed(client, timing.callMs ?? HOSTFS_CALL_MS);\n slot.insert(client, handlers);\n served.invalidate(true);\n },\n event: (event) => served.invalidate(invalidation(event)),\n down() {\n slot.eject();\n served.invalidate(true);\n },\n ...timing,\n },\n stop.signal\n );\n await watching.ready;\n return {\n port: port1,\n present: slot.present,\n dispose() {\n stop.abort();\n port1.close();\n port2.close();\n },\n };\n}\n", "import { type CdpOpen, serveCdpPort } from './cdp/port.ts';\nimport type { CdpHook } from './cdp/types.ts';\nimport {\n type DialHandle,\n type DialledSocket,\n type DialOptions,\n dialStream,\n errorWithCode,\n} from './client/dial-stream.ts';\nimport { type LoopbackFetchOptions, loopbackFetch } from './client/loopback-fetch.ts';\nimport type { Denial, DenialHook } from './fs/dac.ts';\nimport type { UsersMode } from './fs/types.ts';\nimport { isHostname } from './kernel/net/loopback-names.ts';\nimport type { TransportCall } from './kernel/net/remote-transport.ts';\nimport type { RouteTable } from './kernel/net/routes.ts';\nimport { type NetworkUplink, serveUplink, type UplinkCall } from './kernel/net/uplink.ts';\nimport type { PendingMedium } from './launcher.ts';\nimport type { MediumHandle } from './mount/fsa.ts';\nimport type { HostfsGrantHook } from './mount/hostfs.ts';\nimport type { MountEntry, MountSpec } from './mount/mount-fs.ts';\nimport type { ProcessMountPolicy, ProcessMountRequest } from './mount/syscall.ts';\nimport type { InitRequest, KernelCall, TerminalAction } from './serve.ts';\nimport type { ApproveHook, SudoRequest } from './sudo.ts';\nimport { type NetworkTransport, serveTransport } from './transport.ts';\nimport type { Account, AddUser, Group, RemoveUser } from './users.ts';\n\nexport type { CdpConnection, CdpHook, CdpRequest } from './cdp/types.ts';\nexport {\n type AttachOptions,\n attachKernel,\n type ClientFetchRequest,\n type ClientFs,\n type ClientRunOptions,\n type ClientRunResult,\n type ClientTerminal,\n type ClientTerminalOptions,\n KernelCallError,\n type KernelClient,\n KernelGoneError,\n type ProcessEntry,\n type SpawnedProcess,\n type SpawnOptions,\n type WatchChange,\n} from './client/attach.ts';\nexport type { DialledSocket, DialOptions } from './client/dial-stream.ts';\nexport type { LoopbackFetchOptions } from './client/loopback-fetch.ts';\nexport type { Denial, DenialHook } from './fs/dac.ts';\nexport type { RouteTable } from './kernel/net/routes.ts';\nexport type {\n NetworkUplink,\n ResolveAnswer,\n ResolveFamily,\n UplinkTraits,\n} from './kernel/net/uplink.ts';\nexport {\n checkLocalProxy,\n type LocalProxyCheckOptions,\n type LocalProxyOptions,\n type LocalProxyProbe,\n type LocalProxyStatus,\n type LocalProxyTransportOptions,\n localProxyTransport,\n probeLocalProxy,\n} from './local-proxy-transport.ts';\nexport type {\n HostfsEvent,\n HostfsGrant,\n HostfsGrantHook,\n HostfsPortGrant,\n HostfsTransport,\n} from './mount/hostfs.ts';\nexport { serveHostfsPort } from './mount/hostfs.ts';\nexport type { MountEntry, MountSpec } from './mount/mount-fs.ts';\nexport type { ProcessMountPolicy, ProcessMountRequest } from './mount/syscall.ts';\nexport type { JsChild, JsExited, JsSpawnOptions, JsStdio } from './process/js/js-children.ts';\nexport type {\n JsFdStatus,\n JsFdType,\n JsFile,\n JsOpenOptions,\n JsProgramContext,\n JsSignal,\n JsSudoAnswer,\n} from './process/js/js-context.ts';\nexport type {\n JsAddress,\n JsConnection,\n JsConnectOptions,\n JsListener,\n JsListenOptions,\n JsNet,\n} from './process/js/js-net.ts';\nexport type { JsRunOptions, JsRunResult, JsRunStdio } from './process/js/js-run.ts';\nexport type { JsSyncContext, JsSyncFile } from './process/js/js-sync.ts';\nexport type { JsTermios, JsTty, JsTtySize } from './process/js/js-tty.ts';\nexport type {\n JsWebSocket,\n JsWebSocketClose,\n JsWebSocketMessage,\n JsWebSocketOptions,\n} from './process/js/js-websocket.ts';\nexport type { ApproveHook, SudoAnswer, SudoRequest } from './sudo.ts';\nexport {\n type FetchTransportOptions,\n fetchTransport,\n type HeaderList,\n type NetworkRequest,\n type NetworkResponse,\n type NetworkTraits,\n type NetworkTransport,\n type NetworkWebSocket,\n type NetworkWebSocketRequest,\n} from './transport.ts';\nexport type { Account, AddUser, Group, RemoveUser } from './users.ts';\n\nexport interface NetworkOptions {\n transport?: NetworkTransport;\n uplink?: NetworkUplink;\n}\n\nexport interface KernelOptions {\n root?: FileSystemDirectoryHandle;\n modules?: string;\n env?: Record<string, string>;\n metadata?: string | false;\n media?: string | false;\n ca?: string | false;\n worker?: string | URL;\n network?: NetworkOptions;\n requestDirectory?: () => Promise<FileSystemDirectoryHandle>;\n onMountPending?: (pending: MountPending) => void;\n hostfs?: HostfsGrantHook;\n processMounts?: ProcessMountPolicy;\n cdp?: CdpHook;\n hostname?: string;\n users?: UsersMode;\n onDenial?: DenialHook;\n approve?: ApproveHook;\n}\n\ninterface HostfsRequest {\n id: number;\n source: string;\n readonly: boolean;\n}\n\nexport interface MountPending {\n target: string;\n source: string;\n insert(): Promise<void>;\n}\n\nexport interface RunOptions {\n cwd?: string;\n user?: string | number;\n tag?: string;\n env?: Record<string, string>;\n stdin?: string | Uint8Array;\n onStdout?: (text: string) => void;\n onStderr?: (text: string) => void;\n}\n\nexport interface RunResult {\n status: number;\n stdout: string;\n stderr: string;\n}\n\nexport interface ConnectOptions {\n user?: string | number;\n tag?: string;\n}\n\nexport interface KernelGroups {\n list(): Promise<Group[]>;\n addMember(group: string, user: string): Promise<Group>;\n removeMember(group: string, user: string): Promise<Group>;\n}\n\nexport interface KernelUsers {\n readonly mode: UsersMode;\n add(user: AddUser): Promise<Account>;\n remove(name: string, options?: RemoveUser): Promise<boolean>;\n list(): Promise<Account[]>;\n}\n\nexport interface Kernel {\n run(argv: string[], options?: RunOptions): Promise<RunResult>;\n openTerminal(argv: string[], options?: TerminalOptions): Promise<Terminal>;\n connect(options?: ConnectOptions): Promise<MessagePort>;\n readonly users: KernelUsers;\n readonly groups: KernelGroups;\n setRoutes(routes: RouteTable): Promise<void>;\n dial(options: DialOptions): Promise<DialledSocket>;\n loopbackFetch(input: RequestInfo | URL, options: LoopbackFetchOptions): Promise<Response>;\n mount(spec: MountSpec): Promise<MountEntry>;\n umount(target: string): Promise<void>;\n mounts(): Promise<MountEntry[]>;\n insert(target: string, handle: FileSystemDirectoryHandle): Promise<void>;\n terminate(): void;\n}\n\nexport interface TerminalOptions {\n cwd?: string;\n user?: string | number;\n tag?: string;\n env?: Record<string, string>;\n cols?: number;\n rows?: number;\n onData?: (bytes: Uint8Array) => void;\n}\n\nexport type TerminalSignal =\n | 'SIGINT'\n | 'SIGTSTP'\n | 'SIGQUIT'\n | 'SIGHUP'\n | 'SIGTERM'\n | 'SIGKILL'\n | 'SIGCONT';\n\nexport interface Terminal {\n readonly pid: number;\n readonly exited: Promise<number>;\n onData: ((bytes: Uint8Array) => void) | null;\n write(data: string | Uint8Array): void;\n resize(cols: number, rows: number): void;\n signal(name: TerminalSignal): void;\n close(): void;\n}\n\ninterface Reply {\n id: number;\n result?: unknown;\n error?: string;\n code?: string;\n fd?: 1 | 2;\n bytes?: Uint8Array;\n started?: number;\n}\n\ninterface Pending {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n output?: (fd: 1 | 2, bytes: Uint8Array) => void;\n started?: (pid: number) => void;\n}\n\ninterface Handlers {\n output?: Pending['output'];\n started?: Pending['started'];\n}\n\nconst ISOLATION =\n 'slicc-kernel needs a cross-origin isolated page (Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp or credentialless)';\n\nfunction streamer(callback: ((text: string) => void) | undefined) {\n const decoder = new TextDecoder();\n return (bytes: Uint8Array) => callback?.(decoder.decode(bytes, { stream: true }));\n}\n\nfunction dialer(call: (req: KernelCall) => Promise<unknown>) {\n const open = new Set<DialHandle>();\n const dial = async ({ port, host }: DialOptions): Promise<DialledSocket> => {\n let reply: unknown;\n try {\n reply = await call({ op: 'dial', port, ...(host ? { host } : {}) });\n } catch (err) {\n throw errorWithCode((err as Error).message);\n }\n const handle = dialStream(reply as MessagePort, () => open.delete(handle));\n open.add(handle);\n return handle;\n };\n const reset = () => {\n for (const handle of [...open]) handle.fail(errorWithCode('ECONNRESET: the kernel is gone'));\n };\n return { dial, reset };\n}\n\nfunction uplinkInit(uplink: NetworkUplink | undefined): Pick<InitRequest, 'uplink'> {\n if (!uplink) return {};\n const traits = { tcp: true, udp: false, ipv6: uplink.traits.ipv6 === true } as const;\n return { uplink: { traits, ...(uplink.routes ? { routes: uplink.routes } : {}) } };\n}\n\nfunction initCall(options: KernelOptions, transport: NetworkTransport | undefined): KernelCall {\n return {\n op: 'init',\n ...(options.root ? { root: options.root } : {}),\n ...(options.modules ? { modules: options.modules } : {}),\n ...(options.env ? { env: options.env } : {}),\n ...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n ...(options.media !== undefined ? { media: options.media } : {}),\n ...(options.ca !== undefined ? { ca: options.ca } : {}),\n ...(transport ? { transport: transport.traits } : {}),\n ...uplinkInit(options.network?.uplink),\n ...(options.hostfs ? { hostfs: true } : {}),\n ...(options.cdp ? { cdp: true } : {}),\n ...(options.hostname !== undefined ? { hostname: options.hostname } : {}),\n ...(options.users !== undefined ? { users: options.users } : {}),\n ...(options.onDenial ? { denials: true } : {}),\n ...(options.approve ? { approve: true } : {}),\n ...(options.processMounts !== undefined\n ? {\n processMounts:\n typeof options.processMounts === 'function' ? 'ask' : options.processMounts,\n }\n : {}),\n };\n}\n\nfunction cdpBridge(hook: CdpHook | undefined) {\n const open = new Set<() => void>();\n let closed = false;\n return {\n open({ cdpOpen, port }: CdpOpen): void {\n if (!hook || closed) {\n port.close();\n return;\n }\n const close = serveCdpPort(port, hook, cdpOpen, () => open.delete(close));\n open.add(close);\n },\n close(): void {\n closed = true;\n for (const close of [...open]) close();\n },\n };\n}\n\nfunction failed(message: string, code: string | undefined): Error {\n return Object.assign(new Error(message), code === undefined ? {} : { code });\n}\n\nfunction kernelGroups(call: (req: KernelCall) => Promise<unknown>): KernelGroups {\n const member =\n (op: 'groups-add-member' | 'groups-remove-member') => async (group: string, user: string) =>\n (await call({ op, group, user })) as Group;\n return {\n list: async () => (await call({ op: 'groups-list' })) as Group[],\n addMember: member('groups-add-member'),\n removeMember: member('groups-remove-member'),\n };\n}\n\nfunction accounts(\n call: (req: KernelCall) => Promise<unknown>,\n mode: UsersMode | undefined\n): { users: KernelUsers; groups: KernelGroups } {\n return { users: kernelUsers(call, mode), groups: kernelGroups(call) };\n}\n\nfunction kernelUsers(\n call: (req: KernelCall) => Promise<unknown>,\n mode: UsersMode = 'off'\n): KernelUsers {\n return {\n mode,\n add: async (user) => (await call({ op: 'users-add', user })) as Account,\n remove: async (name, options) =>\n (await call({ op: 'users-remove', name, ...(options ? { options } : {}) })) as boolean,\n list: async () => (await call({ op: 'users-list' })) as Account[],\n };\n}\n\nasync function mountPolicy(\n options: KernelOptions,\n worker: Worker,\n { id, req }: { id: number; req: ProcessMountRequest }\n): Promise<void> {\n const decide = options.processMounts;\n let allowed = false;\n try {\n allowed = typeof decide === 'function' ? await decide(req) : decide !== false;\n } catch {}\n worker.postMessage({ mountAllowed: { id, allowed } });\n}\n\ntype SudoMessage = { sudoAsk: SudoRequest } | { sudoAbort: { id: string; reason: string } };\n\ntype WorkerMessage =\n | Reply\n | TransportCall\n | UplinkCall\n | { medium: PendingMedium }\n | { hostfs: HostfsRequest }\n | { mountPolicy: { id: number; req: ProcessMountRequest } }\n | CdpOpen\n | { denial: Denial }\n | SudoMessage;\n\nfunction approver(approve: ApproveHook | undefined, worker: Worker) {\n const asked = new Map<string, AbortController>();\n const handlers = {\n handle(data: WorkerMessage): data is SudoMessage {\n if ('sudoAsk' in data) void handlers.ask(data.sudoAsk);\n else if ('sudoAbort' in data) handlers.abort(data.sudoAbort);\n else return false;\n return true;\n },\n async ask(req: SudoRequest): Promise<void> {\n const control = new AbortController();\n asked.set(req.id, control);\n let answer: unknown = 'deny';\n try {\n answer = await approve?.(req, { signal: control.signal });\n } catch {}\n asked.delete(req.id);\n if (control.signal.aborted) return;\n worker.postMessage({ sudoAnswer: { id: req.id, answer } });\n },\n abort({ id, reason }: { id: string; reason: string }): void {\n asked.get(id)?.abort(reason);\n asked.delete(id);\n },\n close(): void {\n for (const control of asked.values()) control.abort('withdrawn');\n asked.clear();\n },\n };\n return handlers;\n}\n\nexport async function createKernel(options: KernelOptions = {}): Promise<Kernel> {\n if (!globalThis.crossOriginIsolated) throw new Error(ISOLATION);\n if (options.hostname !== undefined && !isHostname(options.hostname)) {\n throw new Error(`not a host name: ${String(options.hostname)}`);\n }\n const url = options.worker ?? new URL('./kernel-worker.js', import.meta.url);\n const worker = new Worker(url, { type: 'module', name: 'slicc-kernel' });\n const pending = new Map<number, Pending>();\n let nextId = 0;\n let failure: Error | undefined;\n\n const dials = dialer((req) => call(req));\n const cdp = cdpBridge(options.cdp);\n const approvals = approver(options.approve, worker);\n const fail = (error: Error) => {\n dials.reset();\n cdp.close();\n approvals.close();\n failure = error;\n bridge?.close();\n uplinks?.close();\n for (const call of pending.values()) call.reject(error);\n pending.clear();\n };\n const transport = options.network?.transport;\n const bridge = transport ? serveTransport(worker, transport) : undefined;\n const uplink = options.network?.uplink;\n const uplinks = uplink ? serveUplink(worker, uplink) : undefined;\n async function chosen(handle: MediumHandle | undefined): Promise<FileSystemDirectoryHandle> {\n if (handle) {\n const state = await handle.requestPermission?.({ mode: 'readwrite' });\n if (state === undefined || state === 'granted') return handle;\n throw new Error('permission for the folder was not granted');\n }\n if (!options.requestDirectory) throw new Error('this page cannot ask for a folder');\n return options.requestDirectory();\n }\n async function grantHostfs({ id, source, readonly }: HostfsRequest): Promise<void> {\n try {\n if (!options.hostfs) throw new Error('this page gives no host folders');\n const grant = await options.hostfs(source, { readonly });\n worker.postMessage({ hostfsGrant: { id, grant } }, 'port' in grant ? [grant.port] : []);\n } catch (err) {\n worker.postMessage({ hostfsGrant: { id, error: (err as Error).message ?? String(err) } });\n }\n }\n const policy = (asked: { id: number; req: ProcessMountRequest }) =>\n mountPolicy(options, worker, asked);\n const pendingMedium = ({ target, source, handle }: PendingMedium) =>\n options.onMountPending?.({\n target,\n source,\n insert: async () =>\n void (await call({ op: 'insert', target, source, handle: await chosen(handle) })),\n });\n worker.addEventListener('message', ({ data }: MessageEvent<WorkerMessage>) => {\n if ('denial' in data) return void options.onDenial?.(data.denial);\n if (approvals.handle(data)) return;\n if ('net' in data) return bridge?.answer(data);\n if ('uplink' in data) return uplinks?.answer(data);\n if ('cdpOpen' in data) return cdp.open(data);\n if ('mountPolicy' in data) return void policy(data.mountPolicy);\n if ('medium' in data) return pendingMedium(data.medium);\n if ('hostfs' in data) return void grantHostfs(data.hostfs);\n const call = pending.get(data.id);\n if (!call) return;\n if (data.fd !== undefined) return call.output?.(data.fd, data.bytes as Uint8Array);\n if (data.started !== undefined) return call.started?.(data.started);\n pending.delete(data.id);\n if (data.error !== undefined) call.reject(failed(data.error, data.code));\n else call.resolve(data.result);\n });\n worker.addEventListener('error', (event) => {\n event.preventDefault();\n fail(new Error(`slicc-kernel worker failed: ${event.message}`));\n });\n\n function request(\n req: KernelCall,\n handlers: Handlers = {}\n ): { id: number; done: Promise<unknown> } {\n const id = ++nextId;\n if (failure) return { id, done: Promise.reject(failure) };\n const done = new Promise((resolve, reject) => {\n pending.set(id, { resolve, reject, ...handlers });\n worker.postMessage({ ...req, id });\n });\n return { id, done };\n }\n\n const call = (req: KernelCall, handlers?: Handlers) => request(req, handlers).done;\n\n async function openTerminal(argv: string[], opts: TerminalOptions = {}): Promise<Terminal> {\n const { onData, ...options } = opts;\n let listener = onData ?? null;\n const backlog: Uint8Array[] = [];\n const started = Promise.withResolvers<number>();\n const { id, done } = request(\n { op: 'open-terminal', argv, options },\n {\n output: (_fd, bytes) => (listener ? listener(bytes) : backlog.push(bytes)),\n started: started.resolve,\n }\n );\n done.catch(started.reject);\n const pid = await started.promise;\n const send = (action: TerminalAction) =>\n void call({ op: 'terminal', terminal: id, ...action }).catch(() => undefined);\n return {\n pid,\n exited: done as Promise<number>,\n get onData() {\n return listener;\n },\n set onData(next) {\n listener = next;\n if (next) for (const bytes of backlog.splice(0)) next(bytes);\n },\n write: (data) =>\n send({\n action: 'write',\n bytes: typeof data === 'string' ? new TextEncoder().encode(data) : data,\n }),\n resize: (cols, rows) => send({ action: 'resize', cols, rows }),\n signal: (name) => send({ action: 'signal', signal: name }),\n close: () => send({ action: 'close' }),\n };\n }\n\n const { dial } = dials;\n\n await call(initCall(options, transport));\n\n return {\n async run(argv, runOptions = {}) {\n const { onStdout, onStderr, stdin, ...rest } = runOptions;\n const streams = { 1: streamer(onStdout), 2: streamer(onStderr) };\n const input = typeof stdin === 'string' ? new TextEncoder().encode(stdin) : stdin;\n const result = (await call(\n { op: 'run', argv, options: { ...rest, ...(input ? { stdin: input } : {}) } },\n { output: (fd, bytes) => streams[fd](bytes) }\n )) as { status: number; stdout: Uint8Array; stderr: Uint8Array };\n const decoder = new TextDecoder();\n return {\n status: result.status,\n stdout: decoder.decode(result.stdout),\n stderr: decoder.decode(result.stderr),\n };\n },\n openTerminal,\n connect: async (connectOptions = {}) =>\n (await call({ op: 'connect', ...connectOptions })) as MessagePort,\n ...accounts(call, options.users),\n setRoutes: async (routes) => void (await call({ op: 'routes', routes })),\n dial,\n loopbackFetch: (input, fetchOptions) => loopbackFetch(dial, input, fetchOptions),\n mount: async (spec) => (await call({ op: 'mount', spec })) as MountEntry,\n umount: async (target) => void (await call({ op: 'umount', target })),\n mounts: async () => (await call({ op: 'mounts' })) as MountEntry[],\n insert: async (target, handle) => void (await call({ op: 'insert', target, handle })),\n terminate() {\n fail(new Error('slicc-kernel terminated'));\n worker.terminate();\n },\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["fail", "chunks", "send", "headers", "encoder", "chunks", "failure", "send", "done", "options", "MAX_REQUEST_BODY", "failure", "concat", "chunks", "send", "stop", "failure", "call", "options", "send"]
7
7
  }