@ricsam/isolate-fetch 0.1.6 → 0.1.8
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/cjs/index.cjs +29 -6
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/index.mjs +29 -6
- package/dist/mjs/index.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -467,6 +467,19 @@ var hostBackedStreamCode = `
|
|
|
467
467
|
return false;
|
|
468
468
|
}
|
|
469
469
|
|
|
470
|
+
async *[Symbol.asyncIterator]() {
|
|
471
|
+
const reader = this.getReader();
|
|
472
|
+
try {
|
|
473
|
+
while (true) {
|
|
474
|
+
const { value, done } = await reader.read();
|
|
475
|
+
if (done) return;
|
|
476
|
+
yield value;
|
|
477
|
+
}
|
|
478
|
+
} finally {
|
|
479
|
+
reader.releaseLock();
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
470
483
|
// Static method to create from existing stream ID
|
|
471
484
|
static _fromStreamId(streamId) {
|
|
472
485
|
return new HostBackedReadableStream(streamId);
|
|
@@ -1253,6 +1266,12 @@ function setupRequest(context, stateMap) {
|
|
|
1253
1266
|
}
|
|
1254
1267
|
|
|
1255
1268
|
get body() {
|
|
1269
|
+
// Per WHATWG Fetch spec: GET/HEAD requests cannot have a body
|
|
1270
|
+
const method = __Request_get_method(this.#instanceId);
|
|
1271
|
+
if (method === 'GET' || method === 'HEAD') {
|
|
1272
|
+
return null;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1256
1275
|
// Return cached body if available
|
|
1257
1276
|
if (this.#cachedBody !== null) {
|
|
1258
1277
|
return this.#cachedBody;
|
|
@@ -1264,12 +1283,15 @@ function setupRequest(context, stateMap) {
|
|
|
1264
1283
|
return this.#cachedBody;
|
|
1265
1284
|
}
|
|
1266
1285
|
|
|
1267
|
-
//
|
|
1268
|
-
const newStreamId = __Stream_create();
|
|
1286
|
+
// Check if there's any buffered body data
|
|
1269
1287
|
const buffer = __Request_arrayBuffer(this.#instanceId);
|
|
1270
|
-
if (buffer.byteLength
|
|
1271
|
-
|
|
1288
|
+
if (buffer.byteLength === 0) {
|
|
1289
|
+
return null; // Return null per WHATWG Fetch spec for empty body
|
|
1272
1290
|
}
|
|
1291
|
+
|
|
1292
|
+
// Create stream from non-empty buffered body
|
|
1293
|
+
const newStreamId = __Stream_create();
|
|
1294
|
+
__Stream_push(newStreamId, Array.from(new Uint8Array(buffer)));
|
|
1273
1295
|
__Stream_close(newStreamId);
|
|
1274
1296
|
|
|
1275
1297
|
this.#cachedBody = HostBackedReadableStream._fromStreamId(newStreamId);
|
|
@@ -1580,7 +1602,8 @@ async function setupFetch(context, options) {
|
|
|
1580
1602
|
}
|
|
1581
1603
|
let requestStreamId = null;
|
|
1582
1604
|
let streamCleanup = null;
|
|
1583
|
-
|
|
1605
|
+
const canHaveBody = !["GET", "HEAD"].includes(request.method.toUpperCase());
|
|
1606
|
+
if (canHaveBody && request.body) {
|
|
1584
1607
|
requestStreamId = streamRegistry.create();
|
|
1585
1608
|
streamCleanup = import_stream_state.startNativeStreamReader(request.body, requestStreamId, streamRegistry);
|
|
1586
1609
|
}
|
|
@@ -1796,4 +1819,4 @@ async function setupFetch(context, options) {
|
|
|
1796
1819
|
}
|
|
1797
1820
|
})
|
|
1798
1821
|
|
|
1799
|
-
//# debugId=
|
|
1822
|
+
//# debugId=654ECA7C6F1E87A964756E2164756E21
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import ivm from \"isolated-vm\";\nimport { setupCore, clearAllInstanceState } from \"@ricsam/isolate-core\";\nimport {\n getStreamRegistryForContext,\n startNativeStreamReader,\n} from \"./stream-state.cjs\";\nimport type { StreamStateRegistry } from \"./stream-state.cjs\";\n\nexport { clearAllInstanceState };\n\nexport interface FetchOptions {\n /** Handler for fetch requests from the isolate */\n onFetch?: (request: Request) => Promise<Response>;\n}\n\n// ============================================================================\n// Serve Types\n// ============================================================================\n\nexport interface UpgradeRequest {\n requested: true;\n connectionId: string;\n}\n\nexport interface WebSocketCommand {\n type: \"message\" | \"close\";\n connectionId: string;\n data?: string | ArrayBuffer;\n code?: number;\n reason?: string;\n}\n\ninterface ServeState {\n pendingUpgrade: UpgradeRequest | null;\n activeConnections: Map<string, { connectionId: string }>;\n}\n\nexport interface DispatchRequestOptions {\n // Reserved for future options\n}\n\nexport interface FetchHandle {\n dispose(): void;\n /** Dispatch an HTTP request to the isolate's serve() handler */\n dispatchRequest(request: Request, options?: DispatchRequestOptions): Promise<Response>;\n /** Check if isolate requested WebSocket upgrade */\n getUpgradeRequest(): UpgradeRequest | null;\n /** Dispatch WebSocket open event to isolate */\n dispatchWebSocketOpen(connectionId: string): void;\n /** Dispatch WebSocket message event to isolate */\n dispatchWebSocketMessage(connectionId: string, message: string | ArrayBuffer): void;\n /** Dispatch WebSocket close event to isolate */\n dispatchWebSocketClose(connectionId: string, code: number, reason: string): void;\n /** Dispatch WebSocket error event to isolate */\n dispatchWebSocketError(connectionId: string, error: Error): void;\n /** Register callback for WebSocket commands from isolate */\n onWebSocketCommand(callback: (cmd: WebSocketCommand) => void): () => void;\n /** Check if serve() has been called */\n hasServeHandler(): boolean;\n /** Check if there are active WebSocket connections */\n hasActiveConnections(): boolean;\n}\n\n// ============================================================================\n// Instance State Management\n// ============================================================================\n\nconst instanceStateMap = new WeakMap<ivm.Context, Map<number, unknown>>();\nlet nextInstanceId = 1;\n\nfunction getInstanceStateMapForContext(\n context: ivm.Context\n): Map<number, unknown> {\n let map = instanceStateMap.get(context);\n if (!map) {\n map = new Map();\n instanceStateMap.set(context, map);\n }\n return map;\n}\n\n// ============================================================================\n// State Types\n// ============================================================================\n\ninterface ResponseState {\n status: number;\n statusText: string;\n headers: [string, string][];\n body: Uint8Array | null;\n bodyUsed: boolean;\n type: string;\n url: string;\n redirected: boolean;\n streamId: number | null;\n}\n\ninterface RequestState {\n method: string;\n url: string;\n headers: [string, string][];\n body: Uint8Array | null;\n bodyUsed: boolean;\n streamId: number | null;\n mode: string;\n credentials: string;\n cache: string;\n redirect: string;\n referrer: string;\n integrity: string;\n}\n\n// ============================================================================\n// Headers Implementation (Pure JS)\n// ============================================================================\n\nconst headersCode = `\n(function() {\n class Headers {\n #headers = new Map(); // lowercase key -> [originalCase, values[]]\n\n constructor(init) {\n if (init instanceof Headers) {\n init.forEach((value, key) => this.append(key, value));\n } else if (Array.isArray(init)) {\n for (const pair of init) {\n if (Array.isArray(pair) && pair.length >= 2) {\n this.append(pair[0], pair[1]);\n }\n }\n } else if (init && typeof init === 'object') {\n for (const [key, value] of Object.entries(init)) {\n this.append(key, value);\n }\n }\n }\n\n append(name, value) {\n const key = String(name).toLowerCase();\n const valueStr = String(value);\n const existing = this.#headers.get(key);\n if (existing) {\n existing[1].push(valueStr);\n } else {\n this.#headers.set(key, [String(name), [valueStr]]);\n }\n }\n\n delete(name) {\n this.#headers.delete(String(name).toLowerCase());\n }\n\n get(name) {\n const entry = this.#headers.get(String(name).toLowerCase());\n return entry ? entry[1].join(', ') : null;\n }\n\n getSetCookie() {\n const entry = this.#headers.get('set-cookie');\n return entry ? [...entry[1]] : [];\n }\n\n has(name) {\n return this.#headers.has(String(name).toLowerCase());\n }\n\n set(name, value) {\n const key = String(name).toLowerCase();\n this.#headers.set(key, [String(name), [String(value)]]);\n }\n\n forEach(callback, thisArg) {\n for (const [key, [originalName, values]] of this.#headers) {\n callback.call(thisArg, values.join(', '), originalName, this);\n }\n }\n\n *entries() {\n for (const [key, [name, values]] of this.#headers) {\n yield [name, values.join(', ')];\n }\n }\n\n *keys() {\n for (const [key, [name]] of this.#headers) {\n yield name;\n }\n }\n\n *values() {\n for (const [key, [name, values]] of this.#headers) {\n yield values.join(', ');\n }\n }\n\n [Symbol.iterator]() {\n return this.entries();\n }\n }\n\n globalThis.Headers = Headers;\n})();\n`;\n\n// ============================================================================\n// FormData Implementation (Pure JS)\n// ============================================================================\n\nconst formDataCode = `\n(function() {\n class FormData {\n #entries = []; // Array of [name, value]\n\n append(name, value, filename) {\n let finalValue = value;\n if (value instanceof Blob && !(value instanceof File)) {\n if (filename !== undefined) {\n finalValue = new File([value], String(filename), { type: value.type });\n }\n } else if (value instanceof File && filename !== undefined) {\n finalValue = new File([value], String(filename), {\n type: value.type,\n lastModified: value.lastModified\n });\n }\n this.#entries.push([String(name), finalValue]);\n }\n\n delete(name) {\n const nameStr = String(name);\n this.#entries = this.#entries.filter(([n]) => n !== nameStr);\n }\n\n get(name) {\n const nameStr = String(name);\n const entry = this.#entries.find(([n]) => n === nameStr);\n return entry ? entry[1] : null;\n }\n\n getAll(name) {\n const nameStr = String(name);\n return this.#entries.filter(([n]) => n === nameStr).map(([, v]) => v);\n }\n\n has(name) {\n return this.#entries.some(([n]) => n === String(name));\n }\n\n set(name, value, filename) {\n const nameStr = String(name);\n this.delete(nameStr);\n this.append(nameStr, value, filename);\n }\n\n *entries() {\n for (const [name, value] of this.#entries) {\n yield [name, value];\n }\n }\n\n *keys() {\n for (const [name] of this.#entries) {\n yield name;\n }\n }\n\n *values() {\n for (const [, value] of this.#entries) {\n yield value;\n }\n }\n\n forEach(callback, thisArg) {\n for (const [name, value] of this.#entries) {\n callback.call(thisArg, value, name, this);\n }\n }\n\n [Symbol.iterator]() {\n return this.entries();\n }\n }\n\n globalThis.FormData = FormData;\n})();\n`;\n\n// ============================================================================\n// Multipart FormData Parsing/Serialization (Pure JS)\n// ============================================================================\n\nconst multipartCode = `\n(function() {\n // Find byte sequence in Uint8Array\n function findSequence(haystack, needle, start = 0) {\n outer: for (let i = start; i <= haystack.length - needle.length; i++) {\n for (let j = 0; j < needle.length; j++) {\n if (haystack[i + j] !== needle[j]) continue outer;\n }\n return i;\n }\n return -1;\n }\n\n // Parse header lines into object\n function parseHeaders(text) {\n const headers = {};\n for (const line of text.split(/\\\\r?\\\\n/)) {\n const colonIdx = line.indexOf(':');\n if (colonIdx > 0) {\n const name = line.slice(0, colonIdx).trim().toLowerCase();\n const value = line.slice(colonIdx + 1).trim();\n headers[name] = value;\n }\n }\n return headers;\n }\n\n // Parse multipart/form-data body into FormData\n globalThis.__parseMultipartFormData = function(bodyBytes, contentType) {\n const formData = new FormData();\n\n // Extract boundary from Content-Type\n const boundaryMatch = contentType.match(/boundary=([^;]+)/i);\n if (!boundaryMatch) return formData;\n\n const boundary = boundaryMatch[1].replace(/^[\"']|[\"']$/g, '');\n const encoder = new TextEncoder();\n const decoder = new TextDecoder();\n const boundaryBytes = encoder.encode('--' + boundary);\n\n // Find first boundary\n let pos = findSequence(bodyBytes, boundaryBytes, 0);\n if (pos === -1) return formData;\n pos += boundaryBytes.length;\n\n while (pos < bodyBytes.length) {\n // Skip CRLF after boundary\n if (bodyBytes[pos] === 0x0d && bodyBytes[pos + 1] === 0x0a) pos += 2;\n else if (bodyBytes[pos] === 0x0a) pos += 1;\n\n // Check for closing boundary (--)\n if (bodyBytes[pos] === 0x2d && bodyBytes[pos + 1] === 0x2d) break;\n\n // Find header/body separator (CRLFCRLF)\n const crlfcrlf = encoder.encode('\\\\r\\\\n\\\\r\\\\n');\n const headersEnd = findSequence(bodyBytes, crlfcrlf, pos);\n if (headersEnd === -1) break;\n\n // Parse headers\n const headersText = decoder.decode(bodyBytes.slice(pos, headersEnd));\n const headers = parseHeaders(headersText);\n pos = headersEnd + 4;\n\n // Find next boundary\n const nextBoundary = findSequence(bodyBytes, boundaryBytes, pos);\n if (nextBoundary === -1) break;\n\n // Extract content (minus trailing CRLF)\n let contentEnd = nextBoundary;\n if (contentEnd > 0 && bodyBytes[contentEnd - 1] === 0x0a) contentEnd--;\n if (contentEnd > 0 && bodyBytes[contentEnd - 1] === 0x0d) contentEnd--;\n const content = bodyBytes.slice(pos, contentEnd);\n\n // Parse Content-Disposition\n const disposition = headers['content-disposition'] || '';\n const nameMatch = disposition.match(/name=\"([^\"]+)\"/);\n const filenameMatch = disposition.match(/filename=\"([^\"]+)\"/);\n\n if (nameMatch) {\n const name = nameMatch[1];\n if (filenameMatch) {\n const filename = filenameMatch[1];\n const mimeType = headers['content-type'] || 'application/octet-stream';\n const file = new File([content], filename, { type: mimeType });\n formData.append(name, file);\n } else {\n formData.append(name, decoder.decode(content));\n }\n }\n\n pos = nextBoundary + boundaryBytes.length;\n }\n\n return formData;\n };\n\n // Serialize FormData to multipart/form-data format\n globalThis.__serializeFormData = function(formData) {\n const boundary = '----FormDataBoundary' + Math.random().toString(36).slice(2) +\n Math.random().toString(36).slice(2);\n const encoder = new TextEncoder();\n const parts = [];\n\n for (const [name, value] of formData.entries()) {\n if (value instanceof File) {\n const header = [\n '--' + boundary,\n 'Content-Disposition: form-data; name=\"' + name + '\"; filename=\"' + value.name + '\"',\n 'Content-Type: ' + (value.type || 'application/octet-stream'),\n '',\n ''\n ].join('\\\\r\\\\n');\n parts.push(encoder.encode(header));\n // Use existing __Blob_bytes callback (File extends Blob)\n parts.push(__Blob_bytes(value._getInstanceId()));\n parts.push(encoder.encode('\\\\r\\\\n'));\n } else if (value instanceof Blob) {\n const header = [\n '--' + boundary,\n 'Content-Disposition: form-data; name=\"' + name + '\"; filename=\"blob\"',\n 'Content-Type: ' + (value.type || 'application/octet-stream'),\n '',\n ''\n ].join('\\\\r\\\\n');\n parts.push(encoder.encode(header));\n parts.push(__Blob_bytes(value._getInstanceId()));\n parts.push(encoder.encode('\\\\r\\\\n'));\n } else {\n const header = [\n '--' + boundary,\n 'Content-Disposition: form-data; name=\"' + name + '\"',\n '',\n ''\n ].join('\\\\r\\\\n');\n parts.push(encoder.encode(header));\n parts.push(encoder.encode(String(value)));\n parts.push(encoder.encode('\\\\r\\\\n'));\n }\n }\n\n // Closing boundary\n parts.push(encoder.encode('--' + boundary + '--\\\\r\\\\n'));\n\n // Concatenate all parts\n const totalLength = parts.reduce((sum, p) => sum + p.length, 0);\n const body = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n body.set(part, offset);\n offset += part.length;\n }\n\n return {\n body: body,\n contentType: 'multipart/form-data; boundary=' + boundary\n };\n };\n})();\n`;\n\n// ============================================================================\n// Stream Callbacks (Host State)\n// ============================================================================\n\nfunction setupStreamCallbacks(\n context: ivm.Context,\n streamRegistry: StreamStateRegistry\n): void {\n const global = context.global;\n\n // Create stream (returns ID)\n global.setSync(\n \"__Stream_create\",\n new ivm.Callback(() => {\n return streamRegistry.create();\n })\n );\n\n // Push chunk (sync) - receives number[] from isolate\n global.setSync(\n \"__Stream_push\",\n new ivm.Callback((streamId: number, chunkArray: number[]) => {\n const chunk = new Uint8Array(chunkArray);\n return streamRegistry.push(streamId, chunk);\n })\n );\n\n // Close stream (sync)\n global.setSync(\n \"__Stream_close\",\n new ivm.Callback((streamId: number) => {\n streamRegistry.close(streamId);\n })\n );\n\n // Error stream (sync)\n global.setSync(\n \"__Stream_error\",\n new ivm.Callback((streamId: number, message: string) => {\n streamRegistry.error(streamId, new Error(message));\n })\n );\n\n // Check backpressure (sync)\n global.setSync(\n \"__Stream_isQueueFull\",\n new ivm.Callback((streamId: number) => {\n return streamRegistry.isQueueFull(streamId);\n })\n );\n\n // Pull chunk (async with applySyncPromise)\n const pullRef = new ivm.Reference(async (streamId: number) => {\n const result = await streamRegistry.pull(streamId);\n if (result.done) {\n return JSON.stringify({ done: true });\n }\n return JSON.stringify({ done: false, value: Array.from(result.value) });\n });\n global.setSync(\"__Stream_pull_ref\", pullRef);\n}\n\n// ============================================================================\n// Host-Backed ReadableStream (Isolate Code)\n// ============================================================================\n\nconst hostBackedStreamCode = `\n(function() {\n const _streamIds = new WeakMap();\n\n class HostBackedReadableStream {\n constructor(streamId) {\n if (streamId === undefined) {\n streamId = __Stream_create();\n }\n _streamIds.set(this, streamId);\n }\n\n _getStreamId() {\n return _streamIds.get(this);\n }\n\n getReader() {\n const streamId = this._getStreamId();\n let released = false;\n\n return {\n read: async () => {\n if (released) {\n throw new TypeError(\"Reader has been released\");\n }\n const resultJson = __Stream_pull_ref.applySyncPromise(undefined, [streamId]);\n const result = JSON.parse(resultJson);\n\n if (result.done) {\n return { done: true, value: undefined };\n }\n return { done: false, value: new Uint8Array(result.value) };\n },\n\n releaseLock: () => {\n released = true;\n },\n\n get closed() {\n return new Promise(() => {});\n },\n\n cancel: async (reason) => {\n __Stream_error(streamId, String(reason || \"cancelled\"));\n }\n };\n }\n\n async cancel(reason) {\n __Stream_error(this._getStreamId(), String(reason || \"cancelled\"));\n }\n\n get locked() {\n return false;\n }\n\n // Static method to create from existing stream ID\n static _fromStreamId(streamId) {\n return new HostBackedReadableStream(streamId);\n }\n }\n\n globalThis.HostBackedReadableStream = HostBackedReadableStream;\n})();\n`;\n\n// ============================================================================\n// Response Implementation (Host State + Isolate Class)\n// ============================================================================\n\nfunction setupResponse(\n context: ivm.Context,\n stateMap: Map<number, unknown>\n): void {\n const global = context.global;\n\n // Register host callbacks\n global.setSync(\n \"__Response_construct\",\n new ivm.Callback(\n (\n bodyBytes: number[] | null,\n status: number,\n statusText: string,\n headers: [string, string][]\n ) => {\n const instanceId = nextInstanceId++;\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const state: ResponseState = {\n status,\n statusText,\n headers,\n body,\n bodyUsed: false,\n type: \"default\",\n url: \"\",\n redirected: false,\n streamId: null,\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n // Streaming Response constructor - creates Response with stream ID but no buffered body\n global.setSync(\n \"__Response_constructStreaming\",\n new ivm.Callback(\n (\n streamId: number,\n status: number,\n statusText: string,\n headers: [string, string][]\n ) => {\n const instanceId = nextInstanceId++;\n const state: ResponseState = {\n status,\n statusText,\n headers,\n body: null, // No buffered body - using stream\n bodyUsed: false,\n type: \"default\",\n url: \"\",\n redirected: false,\n streamId, // Stream ID for body\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n global.setSync(\n \"__Response_constructFromFetch\",\n new ivm.Callback(\n (\n bodyBytes: number[] | null,\n status: number,\n statusText: string,\n headers: [string, string][],\n url: string,\n redirected: boolean\n ) => {\n const instanceId = nextInstanceId++;\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const state: ResponseState = {\n status,\n statusText,\n headers,\n body,\n bodyUsed: false,\n type: \"default\",\n url,\n redirected,\n streamId: null,\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n global.setSync(\n \"__Response_get_status\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.status ?? 200;\n })\n );\n\n global.setSync(\n \"__Response_get_statusText\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.statusText ?? \"\";\n })\n );\n\n global.setSync(\n \"__Response_get_headers\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.headers ?? [];\n })\n );\n\n global.setSync(\n \"__Response_get_bodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.bodyUsed ?? false;\n })\n );\n\n global.setSync(\n \"__Response_get_url\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.url ?? \"\";\n })\n );\n\n global.setSync(\n \"__Response_get_redirected\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.redirected ?? false;\n })\n );\n\n global.setSync(\n \"__Response_get_type\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.type ?? \"default\";\n })\n );\n\n global.setSync(\n \"__Response_setType\",\n new ivm.Callback((instanceId: number, type: string) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (state) {\n state.type = type;\n }\n })\n );\n\n global.setSync(\n \"__Response_markBodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (state) {\n if (state.bodyUsed) {\n throw new Error(\"[TypeError]Body has already been consumed\");\n }\n state.bodyUsed = true;\n }\n })\n );\n\n global.setSync(\n \"__Response_text\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (!state || !state.body) return \"\";\n return new TextDecoder().decode(state.body);\n })\n );\n\n global.setSync(\n \"__Response_arrayBuffer\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (!state || !state.body) {\n return new ivm.ExternalCopy(new ArrayBuffer(0)).copyInto();\n }\n return new ivm.ExternalCopy(state.body.buffer.slice(\n state.body.byteOffset,\n state.body.byteOffset + state.body.byteLength\n )).copyInto();\n })\n );\n\n global.setSync(\n \"__Response_clone\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (!state) {\n throw new Error(\"[TypeError]Cannot clone invalid Response\");\n }\n const newId = nextInstanceId++;\n const newState: ResponseState = {\n ...state,\n body: state.body ? new Uint8Array(state.body) : null,\n bodyUsed: false,\n };\n stateMap.set(newId, newState);\n return newId;\n })\n );\n\n global.setSync(\n \"__Response_getStreamId\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.streamId ?? null;\n })\n );\n\n // Inject Response class\n const responseCode = `\n(function() {\n const _responseInstanceIds = new WeakMap();\n\n function __decodeError(err) {\n if (!(err instanceof Error)) return err;\n const match = err.message.match(/^\\\\[(TypeError|RangeError|SyntaxError|ReferenceError|URIError|EvalError|Error)\\\\](.*)$/);\n if (match) {\n const ErrorType = globalThis[match[1]] || Error;\n return new ErrorType(match[2]);\n }\n return err;\n }\n\n function __prepareBody(body) {\n if (body === null || body === undefined) return null;\n if (typeof body === 'string') {\n const encoder = new TextEncoder();\n return Array.from(encoder.encode(body));\n }\n if (body instanceof ArrayBuffer) {\n return Array.from(new Uint8Array(body));\n }\n if (body instanceof Uint8Array) {\n return Array.from(body);\n }\n if (ArrayBuffer.isView(body)) {\n return Array.from(new Uint8Array(body.buffer, body.byteOffset, body.byteLength));\n }\n if (body instanceof Blob) {\n // Mark as needing async Blob handling - will be read in constructor\n return { __isBlob: true, blob: body };\n }\n // Handle ReadableStream (both native and host-backed)\n if (body instanceof ReadableStream || body instanceof HostBackedReadableStream) {\n return { __isStream: true, stream: body };\n }\n // Try to convert to string\n return Array.from(new TextEncoder().encode(String(body)));\n }\n\n class Response {\n #instanceId;\n #headers;\n #streamId = null;\n #blobInitPromise = null; // For async Blob body initialization\n\n constructor(body, init = {}) {\n // Handle internal construction from instance ID\n if (typeof body === 'number' && init === null) {\n this.#instanceId = body;\n this.#headers = new Headers(__Response_get_headers(body));\n this.#streamId = __Response_getStreamId(body);\n return;\n }\n\n const preparedBody = __prepareBody(body);\n\n // Handle Blob body - create streaming response and push blob data\n if (preparedBody && preparedBody.__isBlob) {\n this.#streamId = __Stream_create();\n const status = init.status ?? 200;\n const statusText = init.statusText ?? '';\n const headers = new Headers(init.headers);\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Response_constructStreaming(\n this.#streamId,\n status,\n statusText,\n headersArray\n );\n this.#headers = headers;\n\n // Start async blob initialization and stream pumping\n const streamId = this.#streamId;\n const blob = preparedBody.blob;\n this.#blobInitPromise = (async () => {\n try {\n const buffer = await blob.arrayBuffer();\n __Stream_push(streamId, Array.from(new Uint8Array(buffer)));\n __Stream_close(streamId);\n } catch (error) {\n __Stream_error(streamId, String(error));\n }\n })();\n return;\n }\n\n // Handle streaming body\n if (preparedBody && preparedBody.__isStream) {\n this.#streamId = __Stream_create();\n const status = init.status ?? 200;\n const statusText = init.statusText ?? '';\n const headers = new Headers(init.headers);\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Response_constructStreaming(\n this.#streamId,\n status,\n statusText,\n headersArray\n );\n this.#headers = headers;\n\n // Start pumping the source stream to host queue (fire-and-forget)\n this._startStreamPump(preparedBody.stream);\n return;\n }\n\n // Existing buffered body handling\n const bodyBytes = preparedBody;\n const status = init.status ?? 200;\n const statusText = init.statusText ?? '';\n const headersInit = init.headers;\n const headers = new Headers(headersInit);\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Response_construct(bodyBytes, status, statusText, headersArray);\n this.#headers = headers;\n }\n\n async _startStreamPump(sourceStream) {\n const streamId = this.#streamId;\n try {\n const reader = sourceStream.getReader();\n while (true) {\n // Check backpressure - wait if queue is full\n while (__Stream_isQueueFull(streamId)) {\n await new Promise(r => setTimeout(r, 1));\n }\n\n const { done, value } = await reader.read();\n if (done) {\n __Stream_close(streamId);\n break;\n }\n if (value) {\n __Stream_push(streamId, Array.from(value));\n }\n }\n } catch (error) {\n __Stream_error(streamId, String(error));\n }\n }\n\n _getInstanceId() {\n return this.#instanceId;\n }\n\n static _fromInstanceId(instanceId) {\n return new Response(instanceId, null);\n }\n\n get status() {\n return __Response_get_status(this.#instanceId);\n }\n\n get statusText() {\n return __Response_get_statusText(this.#instanceId);\n }\n\n get ok() {\n const status = this.status;\n return status >= 200 && status < 300;\n }\n\n get headers() {\n return this.#headers;\n }\n\n get bodyUsed() {\n return __Response_get_bodyUsed(this.#instanceId);\n }\n\n get url() {\n return __Response_get_url(this.#instanceId);\n }\n\n get redirected() {\n return __Response_get_redirected(this.#instanceId);\n }\n\n get type() {\n return __Response_get_type(this.#instanceId);\n }\n\n get body() {\n const streamId = __Response_getStreamId(this.#instanceId);\n if (streamId !== null) {\n return HostBackedReadableStream._fromStreamId(streamId);\n }\n\n // Fallback: create host-backed stream from buffered body\n const instanceId = this.#instanceId;\n const newStreamId = __Stream_create();\n const buffer = __Response_arrayBuffer(instanceId);\n\n if (buffer.byteLength > 0) {\n __Stream_push(newStreamId, Array.from(new Uint8Array(buffer)));\n }\n __Stream_close(newStreamId);\n\n return HostBackedReadableStream._fromStreamId(newStreamId);\n }\n\n async text() {\n try {\n __Response_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n return __Response_text(this.#instanceId);\n }\n\n async json() {\n const text = await this.text();\n return JSON.parse(text);\n }\n\n async arrayBuffer() {\n try {\n __Response_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n\n // For streaming responses (including Blob bodies), consume the stream\n if (this.#streamId !== null) {\n // Wait for blob init to complete if needed\n if (this.#blobInitPromise) {\n await this.#blobInitPromise;\n this.#blobInitPromise = null;\n }\n\n const reader = this.body.getReader();\n const chunks = [];\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value) chunks.push(value);\n }\n // Concatenate all chunks\n const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n return result.buffer;\n }\n\n return __Response_arrayBuffer(this.#instanceId);\n }\n\n async blob() {\n const buffer = await this.arrayBuffer();\n const contentType = this.headers.get('content-type') || '';\n return new Blob([buffer], { type: contentType });\n }\n\n async formData() {\n const contentType = this.headers.get('content-type') || '';\n\n // Parse multipart/form-data\n if (contentType.includes('multipart/form-data')) {\n const buffer = await this.arrayBuffer();\n return __parseMultipartFormData(new Uint8Array(buffer), contentType);\n }\n\n // Parse application/x-www-form-urlencoded\n if (contentType.includes('application/x-www-form-urlencoded')) {\n const text = await this.text();\n const formData = new FormData();\n const params = new URLSearchParams(text);\n for (const [key, value] of params) {\n formData.append(key, value);\n }\n return formData;\n }\n\n throw new TypeError('Unsupported content type for formData()');\n }\n\n clone() {\n if (this.bodyUsed) {\n throw new TypeError('Cannot clone a Response that has already been used');\n }\n const newId = __Response_clone(this.#instanceId);\n const cloned = Response._fromInstanceId(newId);\n return cloned;\n }\n\n static json(data, init = {}) {\n const body = JSON.stringify(data);\n const headers = new Headers(init.headers);\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/json');\n }\n return new Response(body, { ...init, headers });\n }\n\n static redirect(url, status = 302) {\n if (![301, 302, 303, 307, 308].includes(status)) {\n throw new RangeError('Invalid redirect status code');\n }\n const headers = new Headers({ Location: String(url) });\n return new Response(null, { status, headers });\n }\n\n static error() {\n const response = new Response(null, { status: 0, statusText: '' });\n __Response_setType(response._getInstanceId(), 'error');\n return response;\n }\n }\n\n globalThis.Response = Response;\n})();\n`;\n\n context.evalSync(responseCode);\n}\n\n// ============================================================================\n// Request Implementation (Host State + Isolate Class)\n// ============================================================================\n\nfunction setupRequest(\n context: ivm.Context,\n stateMap: Map<number, unknown>\n): void {\n const global = context.global;\n\n // Register host callbacks\n global.setSync(\n \"__Request_construct\",\n new ivm.Callback(\n (\n url: string,\n method: string,\n headers: [string, string][],\n bodyBytes: number[] | null,\n mode: string,\n credentials: string,\n cache: string,\n redirect: string,\n referrer: string,\n integrity: string\n ) => {\n const instanceId = nextInstanceId++;\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const state: RequestState = {\n url,\n method,\n headers,\n body,\n bodyUsed: false,\n streamId: null,\n mode,\n credentials,\n cache,\n redirect,\n referrer,\n integrity,\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n global.setSync(\n \"__Request_get_method\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.method ?? \"GET\";\n })\n );\n\n global.setSync(\n \"__Request_get_url\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.url ?? \"\";\n })\n );\n\n global.setSync(\n \"__Request_get_headers\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.headers ?? [];\n })\n );\n\n global.setSync(\n \"__Request_get_bodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.bodyUsed ?? false;\n })\n );\n\n global.setSync(\n \"__Request_get_mode\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.mode ?? \"cors\";\n })\n );\n\n global.setSync(\n \"__Request_get_credentials\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.credentials ?? \"same-origin\";\n })\n );\n\n global.setSync(\n \"__Request_get_cache\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.cache ?? \"default\";\n })\n );\n\n global.setSync(\n \"__Request_get_redirect\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.redirect ?? \"follow\";\n })\n );\n\n global.setSync(\n \"__Request_get_referrer\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.referrer ?? \"about:client\";\n })\n );\n\n global.setSync(\n \"__Request_get_integrity\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.integrity ?? \"\";\n })\n );\n\n global.setSync(\n \"__Request_markBodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (state) {\n if (state.bodyUsed) {\n throw new Error(\"[TypeError]Body has already been consumed\");\n }\n state.bodyUsed = true;\n }\n })\n );\n\n global.setSync(\n \"__Request_text\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state || !state.body) return \"\";\n return new TextDecoder().decode(state.body);\n })\n );\n\n global.setSync(\n \"__Request_arrayBuffer\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state || !state.body) {\n return new ivm.ExternalCopy(new ArrayBuffer(0)).copyInto();\n }\n return new ivm.ExternalCopy(state.body.buffer.slice(\n state.body.byteOffset,\n state.body.byteOffset + state.body.byteLength\n )).copyInto();\n })\n );\n\n global.setSync(\n \"__Request_getBodyBytes\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state || !state.body) return null;\n return Array.from(state.body);\n })\n );\n\n global.setSync(\n \"__Request_clone\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state) {\n throw new Error(\"[TypeError]Cannot clone invalid Request\");\n }\n const newId = nextInstanceId++;\n const newState: RequestState = {\n ...state,\n body: state.body ? new Uint8Array(state.body) : null,\n bodyUsed: false,\n };\n stateMap.set(newId, newState);\n return newId;\n })\n );\n\n global.setSync(\n \"__Request_getStreamId\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.streamId ?? null;\n })\n );\n\n // Inject Request class\n const requestCode = `\n(function() {\n function __decodeError(err) {\n if (!(err instanceof Error)) return err;\n const match = err.message.match(/^\\\\[(TypeError|RangeError|SyntaxError|ReferenceError|URIError|EvalError|Error)\\\\](.*)$/);\n if (match) {\n const ErrorType = globalThis[match[1]] || Error;\n return new ErrorType(match[2]);\n }\n return err;\n }\n\n function __prepareBody(body) {\n if (body === null || body === undefined) return null;\n if (typeof body === 'string') {\n const encoder = new TextEncoder();\n return Array.from(encoder.encode(body));\n }\n if (body instanceof ArrayBuffer) {\n return Array.from(new Uint8Array(body));\n }\n if (body instanceof Uint8Array) {\n return Array.from(body);\n }\n if (ArrayBuffer.isView(body)) {\n return Array.from(new Uint8Array(body.buffer, body.byteOffset, body.byteLength));\n }\n if (body instanceof URLSearchParams) {\n return Array.from(new TextEncoder().encode(body.toString()));\n }\n if (body instanceof FormData) {\n // Check if FormData has any File/Blob entries\n let hasFiles = false;\n for (const [, value] of body.entries()) {\n if (value instanceof File || value instanceof Blob) {\n hasFiles = true;\n break;\n }\n }\n\n if (hasFiles) {\n // Serialize as multipart/form-data\n const { body: bytes, contentType } = __serializeFormData(body);\n globalThis.__pendingFormDataContentType = contentType;\n return Array.from(bytes);\n }\n\n // URL-encoded for string-only FormData\n const parts = [];\n body.forEach((value, key) => {\n if (typeof value === 'string') {\n parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));\n }\n });\n return Array.from(new TextEncoder().encode(parts.join('&')));\n }\n // Try to convert to string\n return Array.from(new TextEncoder().encode(String(body)));\n }\n\n // Helper to consume a HostBackedReadableStream and concatenate all chunks\n async function __consumeStream(stream) {\n const reader = stream.getReader();\n const chunks = [];\n let totalLength = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n totalLength += value.length;\n }\n\n // Concatenate all chunks\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n return result;\n }\n\n class Request {\n #instanceId;\n #headers;\n #signal;\n #streamId;\n #cachedBody = null;\n\n constructor(input, init = {}) {\n // Handle internal construction from instance ID\n if (typeof input === 'number' && init === null) {\n this.#instanceId = input;\n this.#headers = new Headers(__Request_get_headers(input));\n this.#signal = null;\n this.#streamId = __Request_getStreamId(input);\n return;\n }\n\n let url;\n let method = 'GET';\n let headers;\n let body = null;\n let signal = null;\n let mode = 'cors';\n let credentials = 'same-origin';\n let cache = 'default';\n let redirect = 'follow';\n let referrer = 'about:client';\n let integrity = '';\n\n if (input instanceof Request) {\n url = input.url;\n method = input.method;\n headers = new Headers(input.headers);\n signal = input.signal;\n mode = input.mode;\n credentials = input.credentials;\n cache = input.cache;\n redirect = input.redirect;\n referrer = input.referrer;\n integrity = input.integrity;\n // Note: We don't copy the body from the input Request\n } else {\n url = String(input);\n headers = new Headers();\n }\n\n // Apply init overrides\n if (init.method !== undefined) method = String(init.method).toUpperCase();\n if (init.headers !== undefined) headers = new Headers(init.headers);\n if (init.body !== undefined) body = init.body;\n if (init.signal !== undefined) signal = init.signal;\n if (init.mode !== undefined) mode = init.mode;\n if (init.credentials !== undefined) credentials = init.credentials;\n if (init.cache !== undefined) cache = init.cache;\n if (init.redirect !== undefined) redirect = init.redirect;\n if (init.referrer !== undefined) referrer = init.referrer;\n if (init.integrity !== undefined) integrity = init.integrity;\n\n // Validate: body with GET/HEAD\n if (body !== null && (method === 'GET' || method === 'HEAD')) {\n throw new TypeError('Request with GET/HEAD method cannot have body');\n }\n\n const bodyBytes = __prepareBody(body);\n\n // Handle Content-Type for FormData\n if (globalThis.__pendingFormDataContentType) {\n headers.set('content-type', globalThis.__pendingFormDataContentType);\n delete globalThis.__pendingFormDataContentType;\n } else if (body instanceof FormData && !headers.has('content-type')) {\n headers.set('content-type', 'application/x-www-form-urlencoded');\n }\n\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Request_construct(\n url, method, headersArray, bodyBytes,\n mode, credentials, cache, redirect, referrer, integrity\n );\n this.#headers = headers;\n this.#signal = signal;\n this.#streamId = null;\n }\n\n _getInstanceId() {\n return this.#instanceId;\n }\n\n static _fromInstanceId(instanceId) {\n return new Request(instanceId, null);\n }\n\n get method() {\n return __Request_get_method(this.#instanceId);\n }\n\n get url() {\n return __Request_get_url(this.#instanceId);\n }\n\n get headers() {\n return this.#headers;\n }\n\n get bodyUsed() {\n return __Request_get_bodyUsed(this.#instanceId);\n }\n\n get signal() {\n return this.#signal;\n }\n\n get mode() {\n return __Request_get_mode(this.#instanceId);\n }\n\n get credentials() {\n return __Request_get_credentials(this.#instanceId);\n }\n\n get cache() {\n return __Request_get_cache(this.#instanceId);\n }\n\n get redirect() {\n return __Request_get_redirect(this.#instanceId);\n }\n\n get referrer() {\n return __Request_get_referrer(this.#instanceId);\n }\n\n get integrity() {\n return __Request_get_integrity(this.#instanceId);\n }\n\n get body() {\n // Return cached body if available\n if (this.#cachedBody !== null) {\n return this.#cachedBody;\n }\n\n // If we have a stream ID, create and cache the stream\n if (this.#streamId !== null) {\n this.#cachedBody = HostBackedReadableStream._fromStreamId(this.#streamId);\n return this.#cachedBody;\n }\n\n // Create stream from buffered body\n const newStreamId = __Stream_create();\n const buffer = __Request_arrayBuffer(this.#instanceId);\n if (buffer.byteLength > 0) {\n __Stream_push(newStreamId, Array.from(new Uint8Array(buffer)));\n }\n __Stream_close(newStreamId);\n\n this.#cachedBody = HostBackedReadableStream._fromStreamId(newStreamId);\n return this.#cachedBody;\n }\n\n async text() {\n try {\n __Request_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n\n // If streaming, consume the stream\n if (this.#streamId !== null) {\n const bytes = await __consumeStream(this.body);\n return new TextDecoder().decode(bytes);\n }\n\n // Fallback to host callback for buffered body\n return __Request_text(this.#instanceId);\n }\n\n async json() {\n const text = await this.text();\n return JSON.parse(text);\n }\n\n async arrayBuffer() {\n try {\n __Request_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n\n // If streaming, consume the stream\n if (this.#streamId !== null) {\n const bytes = await __consumeStream(this.body);\n return bytes.buffer;\n }\n\n return __Request_arrayBuffer(this.#instanceId);\n }\n\n async blob() {\n const buffer = await this.arrayBuffer();\n const contentType = this.headers.get('content-type') || '';\n return new Blob([buffer], { type: contentType });\n }\n\n async formData() {\n const contentType = this.headers.get('content-type') || '';\n\n // Parse multipart/form-data\n if (contentType.includes('multipart/form-data')) {\n const buffer = await this.arrayBuffer();\n return __parseMultipartFormData(new Uint8Array(buffer), contentType);\n }\n\n // Parse application/x-www-form-urlencoded\n if (contentType.includes('application/x-www-form-urlencoded')) {\n const text = await this.text();\n const formData = new FormData();\n const params = new URLSearchParams(text);\n for (const [key, value] of params) {\n formData.append(key, value);\n }\n return formData;\n }\n\n throw new TypeError('Unsupported content type for formData()');\n }\n\n clone() {\n if (this.bodyUsed) {\n throw new TypeError('Cannot clone a Request that has already been used');\n }\n const newId = __Request_clone(this.#instanceId);\n const cloned = Request._fromInstanceId(newId);\n cloned.#signal = this.#signal;\n return cloned;\n }\n\n _getBodyBytes() {\n return __Request_getBodyBytes(this.#instanceId);\n }\n }\n\n globalThis.Request = Request;\n})();\n`;\n\n context.evalSync(requestCode);\n}\n\n// ============================================================================\n// fetch Implementation\n// ============================================================================\n\nfunction setupFetchFunction(\n context: ivm.Context,\n stateMap: Map<number, unknown>,\n options?: FetchOptions\n): void {\n const global = context.global;\n\n // Create async fetch reference\n // We use JSON serialization for complex data to avoid transfer issues\n const fetchRef = new ivm.Reference(\n async (\n url: string,\n method: string,\n headersJson: string,\n bodyJson: string | null,\n signalAborted: boolean\n ) => {\n // Check if already aborted\n if (signalAborted) {\n throw new Error(\"[AbortError]The operation was aborted.\");\n }\n\n // Parse headers and body from JSON\n const headers = JSON.parse(headersJson) as [string, string][];\n const bodyBytes = bodyJson ? JSON.parse(bodyJson) as number[] : null;\n\n // Construct native Request\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const nativeRequest = new Request(url, {\n method,\n headers,\n body,\n });\n\n // Call user's onFetch handler or default fetch\n const onFetch = options?.onFetch ?? fetch;\n const nativeResponse = await onFetch(nativeRequest);\n\n // Read response body\n const responseBody = await nativeResponse.arrayBuffer();\n const responseBodyArray = Array.from(new Uint8Array(responseBody));\n\n // Store the response in the state map and return just the ID + metadata\n const instanceId = nextInstanceId++;\n const state: ResponseState = {\n status: nativeResponse.status,\n statusText: nativeResponse.statusText,\n headers: Array.from(nativeResponse.headers.entries()),\n body: new Uint8Array(responseBodyArray),\n bodyUsed: false,\n type: \"default\",\n url: nativeResponse.url,\n redirected: nativeResponse.redirected,\n streamId: null,\n };\n stateMap.set(instanceId, state);\n\n // Return only the instance ID - avoid complex object transfer\n return instanceId;\n }\n );\n\n global.setSync(\"__fetch_ref\", fetchRef);\n\n // Inject fetch function\n const fetchCode = `\n(function() {\n function __decodeError(err) {\n if (!(err instanceof Error)) return err;\n const match = err.message.match(/^\\\\[(TypeError|RangeError|AbortError|Error)\\\\](.*)$/);\n if (match) {\n if (match[1] === 'AbortError') {\n return new DOMException(match[2], 'AbortError');\n }\n const ErrorType = globalThis[match[1]] || Error;\n return new ErrorType(match[2]);\n }\n return err;\n }\n\n globalThis.fetch = function(input, init = {}) {\n // Create Request from input\n const request = input instanceof Request ? input : new Request(input, init);\n\n // Get signal info\n const signal = init.signal ?? request.signal;\n const signalAborted = signal?.aborted ?? false;\n\n // Serialize headers and body to JSON for transfer\n const headersJson = JSON.stringify(Array.from(request.headers.entries()));\n const bodyBytes = request._getBodyBytes();\n const bodyJson = bodyBytes ? JSON.stringify(bodyBytes) : null;\n\n // Call host - returns just the response instance ID\n try {\n const instanceId = __fetch_ref.applySyncPromise(undefined, [\n request.url,\n request.method,\n headersJson,\n bodyJson,\n signalAborted\n ]);\n\n // Construct Response from the instance ID\n return Response._fromInstanceId(instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n };\n})();\n`;\n\n context.evalSync(fetchCode);\n}\n\n// ============================================================================\n// Server Implementation (for serve())\n// ============================================================================\n\nfunction setupServer(\n context: ivm.Context,\n serveState: ServeState\n): void {\n const global = context.global;\n\n // Setup upgrade registry in isolate (data stays in isolate, never marshalled to host)\n context.evalSync(`\n globalThis.__upgradeRegistry__ = new Map();\n globalThis.__upgradeIdCounter__ = 0;\n `);\n\n // Host callback to notify about pending upgrade\n global.setSync(\n \"__setPendingUpgrade__\",\n new ivm.Callback((connectionId: string) => {\n serveState.pendingUpgrade = { requested: true, connectionId };\n })\n );\n\n // Pure JS Server class with upgrade method\n context.evalSync(`\n(function() {\n class Server {\n upgrade(request, options) {\n const data = options?.data;\n const connectionId = String(++globalThis.__upgradeIdCounter__);\n globalThis.__upgradeRegistry__.set(connectionId, data);\n __setPendingUpgrade__(connectionId);\n return true;\n }\n }\n globalThis.__Server__ = Server;\n})();\n `);\n}\n\n// ============================================================================\n// ServerWebSocket Implementation (for serve())\n// ============================================================================\n\nfunction setupServerWebSocket(\n context: ivm.Context,\n wsCommandCallbacks: Set<(cmd: WebSocketCommand) => void>\n): void {\n const global = context.global;\n\n // Host callback for ws.send()\n global.setSync(\n \"__ServerWebSocket_send\",\n new ivm.Callback((connectionId: string, data: string) => {\n const cmd: WebSocketCommand = { type: \"message\", connectionId, data };\n for (const cb of wsCommandCallbacks) cb(cmd);\n })\n );\n\n // Host callback for ws.close()\n global.setSync(\n \"__ServerWebSocket_close\",\n new ivm.Callback((connectionId: string, code?: number, reason?: string) => {\n const cmd: WebSocketCommand = { type: \"close\", connectionId, code, reason };\n for (const cb of wsCommandCallbacks) cb(cmd);\n })\n );\n\n // Pure JS ServerWebSocket class\n context.evalSync(`\n(function() {\n const _wsInstanceData = new WeakMap();\n\n class ServerWebSocket {\n constructor(connectionId) {\n _wsInstanceData.set(this, { connectionId, readyState: 1 });\n }\n\n get data() {\n const state = _wsInstanceData.get(this);\n return globalThis.__upgradeRegistry__.get(state.connectionId);\n }\n\n get readyState() {\n return _wsInstanceData.get(this).readyState;\n }\n\n send(message) {\n const state = _wsInstanceData.get(this);\n if (state.readyState !== 1) throw new Error(\"WebSocket is not open\");\n // Convert ArrayBuffer/Uint8Array to string for transfer\n let data = message;\n if (message instanceof ArrayBuffer) {\n data = new TextDecoder().decode(message);\n } else if (message instanceof Uint8Array) {\n data = new TextDecoder().decode(message);\n }\n __ServerWebSocket_send(state.connectionId, data);\n }\n\n close(code, reason) {\n const state = _wsInstanceData.get(this);\n if (state.readyState === 3) return;\n state.readyState = 2; // CLOSING\n __ServerWebSocket_close(state.connectionId, code, reason);\n }\n\n _setReadyState(readyState) {\n _wsInstanceData.get(this).readyState = readyState;\n }\n }\n\n globalThis.__ServerWebSocket__ = ServerWebSocket;\n})();\n `);\n}\n\n// ============================================================================\n// serve() Function Implementation\n// ============================================================================\n\nfunction setupServe(context: ivm.Context): void {\n // Pure JS serve() that stores options on __serveOptions__ global\n context.evalSync(`\n(function() {\n globalThis.__serveOptions__ = null;\n\n function serve(options) {\n globalThis.__serveOptions__ = options;\n }\n\n globalThis.serve = serve;\n})();\n `);\n}\n\n// ============================================================================\n// Main Setup Function\n// ============================================================================\n\n/**\n * Setup Fetch API in an isolated-vm context\n *\n * Injects fetch, Request, Response, Headers, FormData\n * Also sets up core APIs (Blob, File, AbortController, etc.) if not already present\n *\n * @example\n * const handle = await setupFetch(context, {\n * onFetch: async (request) => {\n * // Proxy fetch requests to the host\n * return fetch(request);\n * }\n * });\n *\n * await context.eval(`\n * const response = await fetch(\"https://example.com\");\n * const text = await response.text();\n * `);\n */\nexport async function setupFetch(\n context: ivm.Context,\n options?: FetchOptions\n): Promise<FetchHandle> {\n // Setup core APIs first (Blob, File, AbortController, Streams, etc.)\n await setupCore(context);\n\n const stateMap = getInstanceStateMapForContext(context);\n const streamRegistry = getStreamRegistryForContext(context);\n\n // Inject Headers (pure JS)\n context.evalSync(headersCode);\n\n // Inject FormData (pure JS)\n context.evalSync(formDataCode);\n\n // Inject multipart parsing/serialization (pure JS)\n context.evalSync(multipartCode);\n\n // Setup stream callbacks and inject HostBackedReadableStream\n setupStreamCallbacks(context, streamRegistry);\n context.evalSync(hostBackedStreamCode);\n\n // Setup Response (host state + isolate class)\n setupResponse(context, stateMap);\n\n // Setup Request (host state + isolate class)\n setupRequest(context, stateMap);\n\n // Setup fetch function\n setupFetchFunction(context, stateMap, options);\n\n // Setup serve state\n const serveState: ServeState = {\n pendingUpgrade: null,\n activeConnections: new Map(),\n };\n\n // Setup WebSocket command callbacks\n const wsCommandCallbacks = new Set<(cmd: WebSocketCommand) => void>();\n\n // Setup Server class\n setupServer(context, serveState);\n\n // Setup ServerWebSocket class\n setupServerWebSocket(context, wsCommandCallbacks);\n\n // Setup serve function\n setupServe(context);\n\n return {\n dispose() {\n // Clear state for this context\n stateMap.clear();\n // Clear upgrade registry\n context.evalSync(`globalThis.__upgradeRegistry__.clear()`);\n // Clear serve state\n serveState.activeConnections.clear();\n serveState.pendingUpgrade = null;\n },\n\n async dispatchRequest(\n request: Request,\n _dispatchOptions?: DispatchRequestOptions\n ): Promise<Response> {\n // Clean up previous pending upgrade if not consumed\n if (serveState.pendingUpgrade) {\n const oldConnectionId = serveState.pendingUpgrade.connectionId;\n context.evalSync(`globalThis.__upgradeRegistry__.delete(\"${oldConnectionId}\")`);\n serveState.pendingUpgrade = null;\n }\n\n // Check if serve handler exists\n const hasHandler = context.evalSync(`!!globalThis.__serveOptions__?.fetch`);\n if (!hasHandler) {\n throw new Error(\"No serve() handler registered\");\n }\n\n // Setup streaming for request body\n let requestStreamId: number | null = null;\n let streamCleanup: (() => Promise<void>) | null = null;\n\n if (request.body) {\n // Create a stream in the registry for the request body\n requestStreamId = streamRegistry.create();\n\n // Start background reader that pushes from native stream to host queue\n streamCleanup = startNativeStreamReader(\n request.body,\n requestStreamId,\n streamRegistry\n );\n }\n\n try {\n const headersArray = Array.from(request.headers.entries());\n\n // Create Request instance in isolate\n const requestInstanceId = nextInstanceId++;\n const requestState: RequestState = {\n url: request.url,\n method: request.method,\n headers: headersArray,\n body: null, // No buffered body - using stream\n bodyUsed: false,\n streamId: requestStreamId,\n mode: request.mode,\n credentials: request.credentials,\n cache: request.cache,\n redirect: request.redirect,\n referrer: request.referrer,\n integrity: request.integrity,\n };\n stateMap.set(requestInstanceId, requestState);\n\n // Call the fetch handler and get response\n // We use eval with promise: true to handle async handlers\n const responseInstanceId = await context.eval(`\n (async function() {\n const request = Request._fromInstanceId(${requestInstanceId});\n const server = new __Server__();\n const response = await Promise.resolve(__serveOptions__.fetch(request, server));\n return response._getInstanceId();\n })()\n `, { promise: true });\n\n // Get ResponseState from the instance\n const responseState = stateMap.get(responseInstanceId) as ResponseState | undefined;\n if (!responseState) {\n throw new Error(\"Response state not found\");\n }\n\n // Check if response has streaming body\n if (responseState.streamId !== null) {\n const responseStreamId = responseState.streamId;\n let streamDone = false;\n\n // Create native stream that waits for data from isolate\n const pumpedStream = new ReadableStream<Uint8Array>({\n async pull(controller) {\n if (streamDone) return;\n\n // Wait for data to be available\n while (!streamDone) {\n // Check if data is available\n const state = streamRegistry.get(responseStreamId);\n if (!state) {\n controller.close();\n streamDone = true;\n return;\n }\n\n // If queue has data or stream is done, break and pull\n if (state.queue.length > 0 || state.closed || state.errored) {\n break;\n }\n\n // Small delay to avoid busy-waiting\n await new Promise((r) => setTimeout(r, 1));\n }\n\n try {\n const result = await streamRegistry.pull(responseStreamId);\n if (result.done) {\n controller.close();\n streamDone = true;\n streamRegistry.delete(responseStreamId);\n return;\n }\n controller.enqueue(result.value);\n } catch (error) {\n controller.error(error);\n streamDone = true;\n streamRegistry.delete(responseStreamId);\n }\n },\n cancel() {\n streamDone = true;\n streamRegistry.error(\n responseStreamId,\n new Error(\"Stream cancelled\")\n );\n streamRegistry.delete(responseStreamId);\n },\n });\n\n const responseHeaders = new Headers(responseState.headers);\n const status =\n responseState.status === 101 ? 200 : responseState.status;\n const response = new Response(pumpedStream, {\n status,\n statusText: responseState.statusText,\n headers: responseHeaders,\n });\n\n // @ts-expect-error - adding custom property\n response._originalStatus = responseState.status;\n\n return response;\n }\n\n // Convert to native Response (non-streaming)\n const responseHeaders = new Headers(responseState.headers);\n const responseBody = responseState.body;\n\n // Note: Status 101 (Switching Protocols) is not valid for Response constructor\n // We use 200 as the status but preserve the actual status in a custom header\n // The caller should check getUpgradeRequest() for WebSocket upgrades\n const status = responseState.status === 101 ? 200 : responseState.status;\n const response = new Response(responseBody as ConstructorParameters<typeof Response>[0], {\n status,\n statusText: responseState.statusText,\n headers: responseHeaders,\n });\n\n // Expose the original status via a property for callers to check\n // @ts-expect-error - adding custom property\n response._originalStatus = responseState.status;\n\n return response;\n } finally {\n // Cleanup: cancel stream reader if still running\n if (streamCleanup) {\n await streamCleanup();\n }\n // Delete stream from registry\n if (requestStreamId !== null) {\n streamRegistry.delete(requestStreamId);\n }\n }\n },\n\n getUpgradeRequest(): UpgradeRequest | null {\n const result = serveState.pendingUpgrade;\n // Don't clear yet - it will be cleared on next dispatchRequest or consumed by dispatchWebSocketOpen\n return result;\n },\n\n dispatchWebSocketOpen(connectionId: string): void {\n // Store connection (data stays in isolate registry)\n serveState.activeConnections.set(connectionId, { connectionId });\n\n // Check if websocket.open handler exists\n const hasOpenHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.open`);\n\n // Create ServerWebSocket instance (always needed for message/close handlers)\n context.evalSync(`\n (function() {\n const ws = new __ServerWebSocket__(\"${connectionId}\");\n globalThis.__activeWs_${connectionId}__ = ws;\n })()\n `);\n\n // Call open handler if it exists\n if (hasOpenHandler) {\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n __serveOptions__.websocket.open(ws);\n })()\n `);\n }\n\n // Clear pending upgrade after successful open\n if (serveState.pendingUpgrade?.connectionId === connectionId) {\n serveState.pendingUpgrade = null;\n }\n },\n\n dispatchWebSocketMessage(connectionId: string, message: string | ArrayBuffer): void {\n // Check if connection is tracked\n if (!serveState.activeConnections.has(connectionId)) {\n return; // Silently ignore for unknown connections\n }\n\n // Check if message handler exists\n const hasMessageHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.message`);\n if (!hasMessageHandler) {\n return;\n }\n\n // Marshal message and call handler\n if (typeof message === \"string\") {\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) __serveOptions__.websocket.message(ws, \"${message.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\")}\");\n })()\n `);\n } else {\n // ArrayBuffer - convert to base64 or pass as array\n const bytes = Array.from(new Uint8Array(message));\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) {\n const bytes = new Uint8Array([${bytes.join(\",\")}]);\n __serveOptions__.websocket.message(ws, bytes.buffer);\n }\n })()\n `);\n }\n },\n\n dispatchWebSocketClose(connectionId: string, code: number, reason: string): void {\n // Check if connection is tracked\n if (!serveState.activeConnections.has(connectionId)) {\n return;\n }\n\n // Update readyState to CLOSED\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) ws._setReadyState(3);\n })()\n `);\n\n // Check if close handler exists\n const hasCloseHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.close`);\n if (hasCloseHandler) {\n const safeReason = reason.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) __serveOptions__.websocket.close(ws, ${code}, \"${safeReason}\");\n })()\n `);\n }\n\n // Cleanup\n context.evalSync(`\n delete globalThis.__activeWs_${connectionId}__;\n globalThis.__upgradeRegistry__.delete(\"${connectionId}\");\n `);\n serveState.activeConnections.delete(connectionId);\n },\n\n dispatchWebSocketError(connectionId: string, error: Error): void {\n // Check if connection is tracked\n if (!serveState.activeConnections.has(connectionId)) {\n return;\n }\n\n // Check if error handler exists\n const hasErrorHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.error`);\n if (!hasErrorHandler) {\n return;\n }\n\n const safeName = error.name.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n const safeMessage = error.message.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) {\n const error = { name: \"${safeName}\", message: \"${safeMessage}\" };\n __serveOptions__.websocket.error(ws, error);\n }\n })()\n `);\n },\n\n onWebSocketCommand(callback: (cmd: WebSocketCommand) => void): () => void {\n wsCommandCallbacks.add(callback);\n return () => wsCommandCallbacks.delete(callback);\n },\n\n hasServeHandler(): boolean {\n return context.evalSync(`!!globalThis.__serveOptions__?.fetch`) as boolean;\n },\n\n hasActiveConnections(): boolean {\n return serveState.activeConnections.size > 0;\n },\n };\n}\n"
|
|
5
|
+
"import ivm from \"isolated-vm\";\nimport { setupCore, clearAllInstanceState } from \"@ricsam/isolate-core\";\nimport {\n getStreamRegistryForContext,\n startNativeStreamReader,\n} from \"./stream-state.cjs\";\nimport type { StreamStateRegistry } from \"./stream-state.cjs\";\n\nexport { clearAllInstanceState };\n\nexport interface FetchOptions {\n /** Handler for fetch requests from the isolate */\n onFetch?: (request: Request) => Promise<Response>;\n}\n\n// ============================================================================\n// Serve Types\n// ============================================================================\n\nexport interface UpgradeRequest {\n requested: true;\n connectionId: string;\n}\n\nexport interface WebSocketCommand {\n type: \"message\" | \"close\";\n connectionId: string;\n data?: string | ArrayBuffer;\n code?: number;\n reason?: string;\n}\n\ninterface ServeState {\n pendingUpgrade: UpgradeRequest | null;\n activeConnections: Map<string, { connectionId: string }>;\n}\n\nexport interface DispatchRequestOptions {\n // Reserved for future options\n}\n\nexport interface FetchHandle {\n dispose(): void;\n /** Dispatch an HTTP request to the isolate's serve() handler */\n dispatchRequest(request: Request, options?: DispatchRequestOptions): Promise<Response>;\n /** Check if isolate requested WebSocket upgrade */\n getUpgradeRequest(): UpgradeRequest | null;\n /** Dispatch WebSocket open event to isolate */\n dispatchWebSocketOpen(connectionId: string): void;\n /** Dispatch WebSocket message event to isolate */\n dispatchWebSocketMessage(connectionId: string, message: string | ArrayBuffer): void;\n /** Dispatch WebSocket close event to isolate */\n dispatchWebSocketClose(connectionId: string, code: number, reason: string): void;\n /** Dispatch WebSocket error event to isolate */\n dispatchWebSocketError(connectionId: string, error: Error): void;\n /** Register callback for WebSocket commands from isolate */\n onWebSocketCommand(callback: (cmd: WebSocketCommand) => void): () => void;\n /** Check if serve() has been called */\n hasServeHandler(): boolean;\n /** Check if there are active WebSocket connections */\n hasActiveConnections(): boolean;\n}\n\n// ============================================================================\n// Instance State Management\n// ============================================================================\n\nconst instanceStateMap = new WeakMap<ivm.Context, Map<number, unknown>>();\nlet nextInstanceId = 1;\n\nfunction getInstanceStateMapForContext(\n context: ivm.Context\n): Map<number, unknown> {\n let map = instanceStateMap.get(context);\n if (!map) {\n map = new Map();\n instanceStateMap.set(context, map);\n }\n return map;\n}\n\n// ============================================================================\n// State Types\n// ============================================================================\n\ninterface ResponseState {\n status: number;\n statusText: string;\n headers: [string, string][];\n body: Uint8Array | null;\n bodyUsed: boolean;\n type: string;\n url: string;\n redirected: boolean;\n streamId: number | null;\n}\n\ninterface RequestState {\n method: string;\n url: string;\n headers: [string, string][];\n body: Uint8Array | null;\n bodyUsed: boolean;\n streamId: number | null;\n mode: string;\n credentials: string;\n cache: string;\n redirect: string;\n referrer: string;\n integrity: string;\n}\n\n// ============================================================================\n// Headers Implementation (Pure JS)\n// ============================================================================\n\nconst headersCode = `\n(function() {\n class Headers {\n #headers = new Map(); // lowercase key -> [originalCase, values[]]\n\n constructor(init) {\n if (init instanceof Headers) {\n init.forEach((value, key) => this.append(key, value));\n } else if (Array.isArray(init)) {\n for (const pair of init) {\n if (Array.isArray(pair) && pair.length >= 2) {\n this.append(pair[0], pair[1]);\n }\n }\n } else if (init && typeof init === 'object') {\n for (const [key, value] of Object.entries(init)) {\n this.append(key, value);\n }\n }\n }\n\n append(name, value) {\n const key = String(name).toLowerCase();\n const valueStr = String(value);\n const existing = this.#headers.get(key);\n if (existing) {\n existing[1].push(valueStr);\n } else {\n this.#headers.set(key, [String(name), [valueStr]]);\n }\n }\n\n delete(name) {\n this.#headers.delete(String(name).toLowerCase());\n }\n\n get(name) {\n const entry = this.#headers.get(String(name).toLowerCase());\n return entry ? entry[1].join(', ') : null;\n }\n\n getSetCookie() {\n const entry = this.#headers.get('set-cookie');\n return entry ? [...entry[1]] : [];\n }\n\n has(name) {\n return this.#headers.has(String(name).toLowerCase());\n }\n\n set(name, value) {\n const key = String(name).toLowerCase();\n this.#headers.set(key, [String(name), [String(value)]]);\n }\n\n forEach(callback, thisArg) {\n for (const [key, [originalName, values]] of this.#headers) {\n callback.call(thisArg, values.join(', '), originalName, this);\n }\n }\n\n *entries() {\n for (const [key, [name, values]] of this.#headers) {\n yield [name, values.join(', ')];\n }\n }\n\n *keys() {\n for (const [key, [name]] of this.#headers) {\n yield name;\n }\n }\n\n *values() {\n for (const [key, [name, values]] of this.#headers) {\n yield values.join(', ');\n }\n }\n\n [Symbol.iterator]() {\n return this.entries();\n }\n }\n\n globalThis.Headers = Headers;\n})();\n`;\n\n// ============================================================================\n// FormData Implementation (Pure JS)\n// ============================================================================\n\nconst formDataCode = `\n(function() {\n class FormData {\n #entries = []; // Array of [name, value]\n\n append(name, value, filename) {\n let finalValue = value;\n if (value instanceof Blob && !(value instanceof File)) {\n if (filename !== undefined) {\n finalValue = new File([value], String(filename), { type: value.type });\n }\n } else if (value instanceof File && filename !== undefined) {\n finalValue = new File([value], String(filename), {\n type: value.type,\n lastModified: value.lastModified\n });\n }\n this.#entries.push([String(name), finalValue]);\n }\n\n delete(name) {\n const nameStr = String(name);\n this.#entries = this.#entries.filter(([n]) => n !== nameStr);\n }\n\n get(name) {\n const nameStr = String(name);\n const entry = this.#entries.find(([n]) => n === nameStr);\n return entry ? entry[1] : null;\n }\n\n getAll(name) {\n const nameStr = String(name);\n return this.#entries.filter(([n]) => n === nameStr).map(([, v]) => v);\n }\n\n has(name) {\n return this.#entries.some(([n]) => n === String(name));\n }\n\n set(name, value, filename) {\n const nameStr = String(name);\n this.delete(nameStr);\n this.append(nameStr, value, filename);\n }\n\n *entries() {\n for (const [name, value] of this.#entries) {\n yield [name, value];\n }\n }\n\n *keys() {\n for (const [name] of this.#entries) {\n yield name;\n }\n }\n\n *values() {\n for (const [, value] of this.#entries) {\n yield value;\n }\n }\n\n forEach(callback, thisArg) {\n for (const [name, value] of this.#entries) {\n callback.call(thisArg, value, name, this);\n }\n }\n\n [Symbol.iterator]() {\n return this.entries();\n }\n }\n\n globalThis.FormData = FormData;\n})();\n`;\n\n// ============================================================================\n// Multipart FormData Parsing/Serialization (Pure JS)\n// ============================================================================\n\nconst multipartCode = `\n(function() {\n // Find byte sequence in Uint8Array\n function findSequence(haystack, needle, start = 0) {\n outer: for (let i = start; i <= haystack.length - needle.length; i++) {\n for (let j = 0; j < needle.length; j++) {\n if (haystack[i + j] !== needle[j]) continue outer;\n }\n return i;\n }\n return -1;\n }\n\n // Parse header lines into object\n function parseHeaders(text) {\n const headers = {};\n for (const line of text.split(/\\\\r?\\\\n/)) {\n const colonIdx = line.indexOf(':');\n if (colonIdx > 0) {\n const name = line.slice(0, colonIdx).trim().toLowerCase();\n const value = line.slice(colonIdx + 1).trim();\n headers[name] = value;\n }\n }\n return headers;\n }\n\n // Parse multipart/form-data body into FormData\n globalThis.__parseMultipartFormData = function(bodyBytes, contentType) {\n const formData = new FormData();\n\n // Extract boundary from Content-Type\n const boundaryMatch = contentType.match(/boundary=([^;]+)/i);\n if (!boundaryMatch) return formData;\n\n const boundary = boundaryMatch[1].replace(/^[\"']|[\"']$/g, '');\n const encoder = new TextEncoder();\n const decoder = new TextDecoder();\n const boundaryBytes = encoder.encode('--' + boundary);\n\n // Find first boundary\n let pos = findSequence(bodyBytes, boundaryBytes, 0);\n if (pos === -1) return formData;\n pos += boundaryBytes.length;\n\n while (pos < bodyBytes.length) {\n // Skip CRLF after boundary\n if (bodyBytes[pos] === 0x0d && bodyBytes[pos + 1] === 0x0a) pos += 2;\n else if (bodyBytes[pos] === 0x0a) pos += 1;\n\n // Check for closing boundary (--)\n if (bodyBytes[pos] === 0x2d && bodyBytes[pos + 1] === 0x2d) break;\n\n // Find header/body separator (CRLFCRLF)\n const crlfcrlf = encoder.encode('\\\\r\\\\n\\\\r\\\\n');\n const headersEnd = findSequence(bodyBytes, crlfcrlf, pos);\n if (headersEnd === -1) break;\n\n // Parse headers\n const headersText = decoder.decode(bodyBytes.slice(pos, headersEnd));\n const headers = parseHeaders(headersText);\n pos = headersEnd + 4;\n\n // Find next boundary\n const nextBoundary = findSequence(bodyBytes, boundaryBytes, pos);\n if (nextBoundary === -1) break;\n\n // Extract content (minus trailing CRLF)\n let contentEnd = nextBoundary;\n if (contentEnd > 0 && bodyBytes[contentEnd - 1] === 0x0a) contentEnd--;\n if (contentEnd > 0 && bodyBytes[contentEnd - 1] === 0x0d) contentEnd--;\n const content = bodyBytes.slice(pos, contentEnd);\n\n // Parse Content-Disposition\n const disposition = headers['content-disposition'] || '';\n const nameMatch = disposition.match(/name=\"([^\"]+)\"/);\n const filenameMatch = disposition.match(/filename=\"([^\"]+)\"/);\n\n if (nameMatch) {\n const name = nameMatch[1];\n if (filenameMatch) {\n const filename = filenameMatch[1];\n const mimeType = headers['content-type'] || 'application/octet-stream';\n const file = new File([content], filename, { type: mimeType });\n formData.append(name, file);\n } else {\n formData.append(name, decoder.decode(content));\n }\n }\n\n pos = nextBoundary + boundaryBytes.length;\n }\n\n return formData;\n };\n\n // Serialize FormData to multipart/form-data format\n globalThis.__serializeFormData = function(formData) {\n const boundary = '----FormDataBoundary' + Math.random().toString(36).slice(2) +\n Math.random().toString(36).slice(2);\n const encoder = new TextEncoder();\n const parts = [];\n\n for (const [name, value] of formData.entries()) {\n if (value instanceof File) {\n const header = [\n '--' + boundary,\n 'Content-Disposition: form-data; name=\"' + name + '\"; filename=\"' + value.name + '\"',\n 'Content-Type: ' + (value.type || 'application/octet-stream'),\n '',\n ''\n ].join('\\\\r\\\\n');\n parts.push(encoder.encode(header));\n // Use existing __Blob_bytes callback (File extends Blob)\n parts.push(__Blob_bytes(value._getInstanceId()));\n parts.push(encoder.encode('\\\\r\\\\n'));\n } else if (value instanceof Blob) {\n const header = [\n '--' + boundary,\n 'Content-Disposition: form-data; name=\"' + name + '\"; filename=\"blob\"',\n 'Content-Type: ' + (value.type || 'application/octet-stream'),\n '',\n ''\n ].join('\\\\r\\\\n');\n parts.push(encoder.encode(header));\n parts.push(__Blob_bytes(value._getInstanceId()));\n parts.push(encoder.encode('\\\\r\\\\n'));\n } else {\n const header = [\n '--' + boundary,\n 'Content-Disposition: form-data; name=\"' + name + '\"',\n '',\n ''\n ].join('\\\\r\\\\n');\n parts.push(encoder.encode(header));\n parts.push(encoder.encode(String(value)));\n parts.push(encoder.encode('\\\\r\\\\n'));\n }\n }\n\n // Closing boundary\n parts.push(encoder.encode('--' + boundary + '--\\\\r\\\\n'));\n\n // Concatenate all parts\n const totalLength = parts.reduce((sum, p) => sum + p.length, 0);\n const body = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n body.set(part, offset);\n offset += part.length;\n }\n\n return {\n body: body,\n contentType: 'multipart/form-data; boundary=' + boundary\n };\n };\n})();\n`;\n\n// ============================================================================\n// Stream Callbacks (Host State)\n// ============================================================================\n\nfunction setupStreamCallbacks(\n context: ivm.Context,\n streamRegistry: StreamStateRegistry\n): void {\n const global = context.global;\n\n // Create stream (returns ID)\n global.setSync(\n \"__Stream_create\",\n new ivm.Callback(() => {\n return streamRegistry.create();\n })\n );\n\n // Push chunk (sync) - receives number[] from isolate\n global.setSync(\n \"__Stream_push\",\n new ivm.Callback((streamId: number, chunkArray: number[]) => {\n const chunk = new Uint8Array(chunkArray);\n return streamRegistry.push(streamId, chunk);\n })\n );\n\n // Close stream (sync)\n global.setSync(\n \"__Stream_close\",\n new ivm.Callback((streamId: number) => {\n streamRegistry.close(streamId);\n })\n );\n\n // Error stream (sync)\n global.setSync(\n \"__Stream_error\",\n new ivm.Callback((streamId: number, message: string) => {\n streamRegistry.error(streamId, new Error(message));\n })\n );\n\n // Check backpressure (sync)\n global.setSync(\n \"__Stream_isQueueFull\",\n new ivm.Callback((streamId: number) => {\n return streamRegistry.isQueueFull(streamId);\n })\n );\n\n // Pull chunk (async with applySyncPromise)\n const pullRef = new ivm.Reference(async (streamId: number) => {\n const result = await streamRegistry.pull(streamId);\n if (result.done) {\n return JSON.stringify({ done: true });\n }\n return JSON.stringify({ done: false, value: Array.from(result.value) });\n });\n global.setSync(\"__Stream_pull_ref\", pullRef);\n}\n\n// ============================================================================\n// Host-Backed ReadableStream (Isolate Code)\n// ============================================================================\n\nconst hostBackedStreamCode = `\n(function() {\n const _streamIds = new WeakMap();\n\n class HostBackedReadableStream {\n constructor(streamId) {\n if (streamId === undefined) {\n streamId = __Stream_create();\n }\n _streamIds.set(this, streamId);\n }\n\n _getStreamId() {\n return _streamIds.get(this);\n }\n\n getReader() {\n const streamId = this._getStreamId();\n let released = false;\n\n return {\n read: async () => {\n if (released) {\n throw new TypeError(\"Reader has been released\");\n }\n const resultJson = __Stream_pull_ref.applySyncPromise(undefined, [streamId]);\n const result = JSON.parse(resultJson);\n\n if (result.done) {\n return { done: true, value: undefined };\n }\n return { done: false, value: new Uint8Array(result.value) };\n },\n\n releaseLock: () => {\n released = true;\n },\n\n get closed() {\n return new Promise(() => {});\n },\n\n cancel: async (reason) => {\n __Stream_error(streamId, String(reason || \"cancelled\"));\n }\n };\n }\n\n async cancel(reason) {\n __Stream_error(this._getStreamId(), String(reason || \"cancelled\"));\n }\n\n get locked() {\n return false;\n }\n\n async *[Symbol.asyncIterator]() {\n const reader = this.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) return;\n yield value;\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n // Static method to create from existing stream ID\n static _fromStreamId(streamId) {\n return new HostBackedReadableStream(streamId);\n }\n }\n\n globalThis.HostBackedReadableStream = HostBackedReadableStream;\n})();\n`;\n\n// ============================================================================\n// Response Implementation (Host State + Isolate Class)\n// ============================================================================\n\nfunction setupResponse(\n context: ivm.Context,\n stateMap: Map<number, unknown>\n): void {\n const global = context.global;\n\n // Register host callbacks\n global.setSync(\n \"__Response_construct\",\n new ivm.Callback(\n (\n bodyBytes: number[] | null,\n status: number,\n statusText: string,\n headers: [string, string][]\n ) => {\n const instanceId = nextInstanceId++;\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const state: ResponseState = {\n status,\n statusText,\n headers,\n body,\n bodyUsed: false,\n type: \"default\",\n url: \"\",\n redirected: false,\n streamId: null,\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n // Streaming Response constructor - creates Response with stream ID but no buffered body\n global.setSync(\n \"__Response_constructStreaming\",\n new ivm.Callback(\n (\n streamId: number,\n status: number,\n statusText: string,\n headers: [string, string][]\n ) => {\n const instanceId = nextInstanceId++;\n const state: ResponseState = {\n status,\n statusText,\n headers,\n body: null, // No buffered body - using stream\n bodyUsed: false,\n type: \"default\",\n url: \"\",\n redirected: false,\n streamId, // Stream ID for body\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n global.setSync(\n \"__Response_constructFromFetch\",\n new ivm.Callback(\n (\n bodyBytes: number[] | null,\n status: number,\n statusText: string,\n headers: [string, string][],\n url: string,\n redirected: boolean\n ) => {\n const instanceId = nextInstanceId++;\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const state: ResponseState = {\n status,\n statusText,\n headers,\n body,\n bodyUsed: false,\n type: \"default\",\n url,\n redirected,\n streamId: null,\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n global.setSync(\n \"__Response_get_status\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.status ?? 200;\n })\n );\n\n global.setSync(\n \"__Response_get_statusText\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.statusText ?? \"\";\n })\n );\n\n global.setSync(\n \"__Response_get_headers\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.headers ?? [];\n })\n );\n\n global.setSync(\n \"__Response_get_bodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.bodyUsed ?? false;\n })\n );\n\n global.setSync(\n \"__Response_get_url\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.url ?? \"\";\n })\n );\n\n global.setSync(\n \"__Response_get_redirected\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.redirected ?? false;\n })\n );\n\n global.setSync(\n \"__Response_get_type\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.type ?? \"default\";\n })\n );\n\n global.setSync(\n \"__Response_setType\",\n new ivm.Callback((instanceId: number, type: string) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (state) {\n state.type = type;\n }\n })\n );\n\n global.setSync(\n \"__Response_markBodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (state) {\n if (state.bodyUsed) {\n throw new Error(\"[TypeError]Body has already been consumed\");\n }\n state.bodyUsed = true;\n }\n })\n );\n\n global.setSync(\n \"__Response_text\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (!state || !state.body) return \"\";\n return new TextDecoder().decode(state.body);\n })\n );\n\n global.setSync(\n \"__Response_arrayBuffer\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (!state || !state.body) {\n return new ivm.ExternalCopy(new ArrayBuffer(0)).copyInto();\n }\n return new ivm.ExternalCopy(state.body.buffer.slice(\n state.body.byteOffset,\n state.body.byteOffset + state.body.byteLength\n )).copyInto();\n })\n );\n\n global.setSync(\n \"__Response_clone\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (!state) {\n throw new Error(\"[TypeError]Cannot clone invalid Response\");\n }\n const newId = nextInstanceId++;\n const newState: ResponseState = {\n ...state,\n body: state.body ? new Uint8Array(state.body) : null,\n bodyUsed: false,\n };\n stateMap.set(newId, newState);\n return newId;\n })\n );\n\n global.setSync(\n \"__Response_getStreamId\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.streamId ?? null;\n })\n );\n\n // Inject Response class\n const responseCode = `\n(function() {\n const _responseInstanceIds = new WeakMap();\n\n function __decodeError(err) {\n if (!(err instanceof Error)) return err;\n const match = err.message.match(/^\\\\[(TypeError|RangeError|SyntaxError|ReferenceError|URIError|EvalError|Error)\\\\](.*)$/);\n if (match) {\n const ErrorType = globalThis[match[1]] || Error;\n return new ErrorType(match[2]);\n }\n return err;\n }\n\n function __prepareBody(body) {\n if (body === null || body === undefined) return null;\n if (typeof body === 'string') {\n const encoder = new TextEncoder();\n return Array.from(encoder.encode(body));\n }\n if (body instanceof ArrayBuffer) {\n return Array.from(new Uint8Array(body));\n }\n if (body instanceof Uint8Array) {\n return Array.from(body);\n }\n if (ArrayBuffer.isView(body)) {\n return Array.from(new Uint8Array(body.buffer, body.byteOffset, body.byteLength));\n }\n if (body instanceof Blob) {\n // Mark as needing async Blob handling - will be read in constructor\n return { __isBlob: true, blob: body };\n }\n // Handle ReadableStream (both native and host-backed)\n if (body instanceof ReadableStream || body instanceof HostBackedReadableStream) {\n return { __isStream: true, stream: body };\n }\n // Try to convert to string\n return Array.from(new TextEncoder().encode(String(body)));\n }\n\n class Response {\n #instanceId;\n #headers;\n #streamId = null;\n #blobInitPromise = null; // For async Blob body initialization\n\n constructor(body, init = {}) {\n // Handle internal construction from instance ID\n if (typeof body === 'number' && init === null) {\n this.#instanceId = body;\n this.#headers = new Headers(__Response_get_headers(body));\n this.#streamId = __Response_getStreamId(body);\n return;\n }\n\n const preparedBody = __prepareBody(body);\n\n // Handle Blob body - create streaming response and push blob data\n if (preparedBody && preparedBody.__isBlob) {\n this.#streamId = __Stream_create();\n const status = init.status ?? 200;\n const statusText = init.statusText ?? '';\n const headers = new Headers(init.headers);\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Response_constructStreaming(\n this.#streamId,\n status,\n statusText,\n headersArray\n );\n this.#headers = headers;\n\n // Start async blob initialization and stream pumping\n const streamId = this.#streamId;\n const blob = preparedBody.blob;\n this.#blobInitPromise = (async () => {\n try {\n const buffer = await blob.arrayBuffer();\n __Stream_push(streamId, Array.from(new Uint8Array(buffer)));\n __Stream_close(streamId);\n } catch (error) {\n __Stream_error(streamId, String(error));\n }\n })();\n return;\n }\n\n // Handle streaming body\n if (preparedBody && preparedBody.__isStream) {\n this.#streamId = __Stream_create();\n const status = init.status ?? 200;\n const statusText = init.statusText ?? '';\n const headers = new Headers(init.headers);\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Response_constructStreaming(\n this.#streamId,\n status,\n statusText,\n headersArray\n );\n this.#headers = headers;\n\n // Start pumping the source stream to host queue (fire-and-forget)\n this._startStreamPump(preparedBody.stream);\n return;\n }\n\n // Existing buffered body handling\n const bodyBytes = preparedBody;\n const status = init.status ?? 200;\n const statusText = init.statusText ?? '';\n const headersInit = init.headers;\n const headers = new Headers(headersInit);\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Response_construct(bodyBytes, status, statusText, headersArray);\n this.#headers = headers;\n }\n\n async _startStreamPump(sourceStream) {\n const streamId = this.#streamId;\n try {\n const reader = sourceStream.getReader();\n while (true) {\n // Check backpressure - wait if queue is full\n while (__Stream_isQueueFull(streamId)) {\n await new Promise(r => setTimeout(r, 1));\n }\n\n const { done, value } = await reader.read();\n if (done) {\n __Stream_close(streamId);\n break;\n }\n if (value) {\n __Stream_push(streamId, Array.from(value));\n }\n }\n } catch (error) {\n __Stream_error(streamId, String(error));\n }\n }\n\n _getInstanceId() {\n return this.#instanceId;\n }\n\n static _fromInstanceId(instanceId) {\n return new Response(instanceId, null);\n }\n\n get status() {\n return __Response_get_status(this.#instanceId);\n }\n\n get statusText() {\n return __Response_get_statusText(this.#instanceId);\n }\n\n get ok() {\n const status = this.status;\n return status >= 200 && status < 300;\n }\n\n get headers() {\n return this.#headers;\n }\n\n get bodyUsed() {\n return __Response_get_bodyUsed(this.#instanceId);\n }\n\n get url() {\n return __Response_get_url(this.#instanceId);\n }\n\n get redirected() {\n return __Response_get_redirected(this.#instanceId);\n }\n\n get type() {\n return __Response_get_type(this.#instanceId);\n }\n\n get body() {\n const streamId = __Response_getStreamId(this.#instanceId);\n if (streamId !== null) {\n return HostBackedReadableStream._fromStreamId(streamId);\n }\n\n // Fallback: create host-backed stream from buffered body\n const instanceId = this.#instanceId;\n const newStreamId = __Stream_create();\n const buffer = __Response_arrayBuffer(instanceId);\n\n if (buffer.byteLength > 0) {\n __Stream_push(newStreamId, Array.from(new Uint8Array(buffer)));\n }\n __Stream_close(newStreamId);\n\n return HostBackedReadableStream._fromStreamId(newStreamId);\n }\n\n async text() {\n try {\n __Response_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n return __Response_text(this.#instanceId);\n }\n\n async json() {\n const text = await this.text();\n return JSON.parse(text);\n }\n\n async arrayBuffer() {\n try {\n __Response_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n\n // For streaming responses (including Blob bodies), consume the stream\n if (this.#streamId !== null) {\n // Wait for blob init to complete if needed\n if (this.#blobInitPromise) {\n await this.#blobInitPromise;\n this.#blobInitPromise = null;\n }\n\n const reader = this.body.getReader();\n const chunks = [];\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value) chunks.push(value);\n }\n // Concatenate all chunks\n const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n return result.buffer;\n }\n\n return __Response_arrayBuffer(this.#instanceId);\n }\n\n async blob() {\n const buffer = await this.arrayBuffer();\n const contentType = this.headers.get('content-type') || '';\n return new Blob([buffer], { type: contentType });\n }\n\n async formData() {\n const contentType = this.headers.get('content-type') || '';\n\n // Parse multipart/form-data\n if (contentType.includes('multipart/form-data')) {\n const buffer = await this.arrayBuffer();\n return __parseMultipartFormData(new Uint8Array(buffer), contentType);\n }\n\n // Parse application/x-www-form-urlencoded\n if (contentType.includes('application/x-www-form-urlencoded')) {\n const text = await this.text();\n const formData = new FormData();\n const params = new URLSearchParams(text);\n for (const [key, value] of params) {\n formData.append(key, value);\n }\n return formData;\n }\n\n throw new TypeError('Unsupported content type for formData()');\n }\n\n clone() {\n if (this.bodyUsed) {\n throw new TypeError('Cannot clone a Response that has already been used');\n }\n const newId = __Response_clone(this.#instanceId);\n const cloned = Response._fromInstanceId(newId);\n return cloned;\n }\n\n static json(data, init = {}) {\n const body = JSON.stringify(data);\n const headers = new Headers(init.headers);\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/json');\n }\n return new Response(body, { ...init, headers });\n }\n\n static redirect(url, status = 302) {\n if (![301, 302, 303, 307, 308].includes(status)) {\n throw new RangeError('Invalid redirect status code');\n }\n const headers = new Headers({ Location: String(url) });\n return new Response(null, { status, headers });\n }\n\n static error() {\n const response = new Response(null, { status: 0, statusText: '' });\n __Response_setType(response._getInstanceId(), 'error');\n return response;\n }\n }\n\n globalThis.Response = Response;\n})();\n`;\n\n context.evalSync(responseCode);\n}\n\n// ============================================================================\n// Request Implementation (Host State + Isolate Class)\n// ============================================================================\n\nfunction setupRequest(\n context: ivm.Context,\n stateMap: Map<number, unknown>\n): void {\n const global = context.global;\n\n // Register host callbacks\n global.setSync(\n \"__Request_construct\",\n new ivm.Callback(\n (\n url: string,\n method: string,\n headers: [string, string][],\n bodyBytes: number[] | null,\n mode: string,\n credentials: string,\n cache: string,\n redirect: string,\n referrer: string,\n integrity: string\n ) => {\n const instanceId = nextInstanceId++;\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const state: RequestState = {\n url,\n method,\n headers,\n body,\n bodyUsed: false,\n streamId: null,\n mode,\n credentials,\n cache,\n redirect,\n referrer,\n integrity,\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n global.setSync(\n \"__Request_get_method\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.method ?? \"GET\";\n })\n );\n\n global.setSync(\n \"__Request_get_url\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.url ?? \"\";\n })\n );\n\n global.setSync(\n \"__Request_get_headers\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.headers ?? [];\n })\n );\n\n global.setSync(\n \"__Request_get_bodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.bodyUsed ?? false;\n })\n );\n\n global.setSync(\n \"__Request_get_mode\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.mode ?? \"cors\";\n })\n );\n\n global.setSync(\n \"__Request_get_credentials\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.credentials ?? \"same-origin\";\n })\n );\n\n global.setSync(\n \"__Request_get_cache\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.cache ?? \"default\";\n })\n );\n\n global.setSync(\n \"__Request_get_redirect\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.redirect ?? \"follow\";\n })\n );\n\n global.setSync(\n \"__Request_get_referrer\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.referrer ?? \"about:client\";\n })\n );\n\n global.setSync(\n \"__Request_get_integrity\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.integrity ?? \"\";\n })\n );\n\n global.setSync(\n \"__Request_markBodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (state) {\n if (state.bodyUsed) {\n throw new Error(\"[TypeError]Body has already been consumed\");\n }\n state.bodyUsed = true;\n }\n })\n );\n\n global.setSync(\n \"__Request_text\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state || !state.body) return \"\";\n return new TextDecoder().decode(state.body);\n })\n );\n\n global.setSync(\n \"__Request_arrayBuffer\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state || !state.body) {\n return new ivm.ExternalCopy(new ArrayBuffer(0)).copyInto();\n }\n return new ivm.ExternalCopy(state.body.buffer.slice(\n state.body.byteOffset,\n state.body.byteOffset + state.body.byteLength\n )).copyInto();\n })\n );\n\n global.setSync(\n \"__Request_getBodyBytes\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state || !state.body) return null;\n return Array.from(state.body);\n })\n );\n\n global.setSync(\n \"__Request_clone\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state) {\n throw new Error(\"[TypeError]Cannot clone invalid Request\");\n }\n const newId = nextInstanceId++;\n const newState: RequestState = {\n ...state,\n body: state.body ? new Uint8Array(state.body) : null,\n bodyUsed: false,\n };\n stateMap.set(newId, newState);\n return newId;\n })\n );\n\n global.setSync(\n \"__Request_getStreamId\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.streamId ?? null;\n })\n );\n\n // Inject Request class\n const requestCode = `\n(function() {\n function __decodeError(err) {\n if (!(err instanceof Error)) return err;\n const match = err.message.match(/^\\\\[(TypeError|RangeError|SyntaxError|ReferenceError|URIError|EvalError|Error)\\\\](.*)$/);\n if (match) {\n const ErrorType = globalThis[match[1]] || Error;\n return new ErrorType(match[2]);\n }\n return err;\n }\n\n function __prepareBody(body) {\n if (body === null || body === undefined) return null;\n if (typeof body === 'string') {\n const encoder = new TextEncoder();\n return Array.from(encoder.encode(body));\n }\n if (body instanceof ArrayBuffer) {\n return Array.from(new Uint8Array(body));\n }\n if (body instanceof Uint8Array) {\n return Array.from(body);\n }\n if (ArrayBuffer.isView(body)) {\n return Array.from(new Uint8Array(body.buffer, body.byteOffset, body.byteLength));\n }\n if (body instanceof URLSearchParams) {\n return Array.from(new TextEncoder().encode(body.toString()));\n }\n if (body instanceof FormData) {\n // Check if FormData has any File/Blob entries\n let hasFiles = false;\n for (const [, value] of body.entries()) {\n if (value instanceof File || value instanceof Blob) {\n hasFiles = true;\n break;\n }\n }\n\n if (hasFiles) {\n // Serialize as multipart/form-data\n const { body: bytes, contentType } = __serializeFormData(body);\n globalThis.__pendingFormDataContentType = contentType;\n return Array.from(bytes);\n }\n\n // URL-encoded for string-only FormData\n const parts = [];\n body.forEach((value, key) => {\n if (typeof value === 'string') {\n parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));\n }\n });\n return Array.from(new TextEncoder().encode(parts.join('&')));\n }\n // Try to convert to string\n return Array.from(new TextEncoder().encode(String(body)));\n }\n\n // Helper to consume a HostBackedReadableStream and concatenate all chunks\n async function __consumeStream(stream) {\n const reader = stream.getReader();\n const chunks = [];\n let totalLength = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n totalLength += value.length;\n }\n\n // Concatenate all chunks\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n return result;\n }\n\n class Request {\n #instanceId;\n #headers;\n #signal;\n #streamId;\n #cachedBody = null;\n\n constructor(input, init = {}) {\n // Handle internal construction from instance ID\n if (typeof input === 'number' && init === null) {\n this.#instanceId = input;\n this.#headers = new Headers(__Request_get_headers(input));\n this.#signal = null;\n this.#streamId = __Request_getStreamId(input);\n return;\n }\n\n let url;\n let method = 'GET';\n let headers;\n let body = null;\n let signal = null;\n let mode = 'cors';\n let credentials = 'same-origin';\n let cache = 'default';\n let redirect = 'follow';\n let referrer = 'about:client';\n let integrity = '';\n\n if (input instanceof Request) {\n url = input.url;\n method = input.method;\n headers = new Headers(input.headers);\n signal = input.signal;\n mode = input.mode;\n credentials = input.credentials;\n cache = input.cache;\n redirect = input.redirect;\n referrer = input.referrer;\n integrity = input.integrity;\n // Note: We don't copy the body from the input Request\n } else {\n url = String(input);\n headers = new Headers();\n }\n\n // Apply init overrides\n if (init.method !== undefined) method = String(init.method).toUpperCase();\n if (init.headers !== undefined) headers = new Headers(init.headers);\n if (init.body !== undefined) body = init.body;\n if (init.signal !== undefined) signal = init.signal;\n if (init.mode !== undefined) mode = init.mode;\n if (init.credentials !== undefined) credentials = init.credentials;\n if (init.cache !== undefined) cache = init.cache;\n if (init.redirect !== undefined) redirect = init.redirect;\n if (init.referrer !== undefined) referrer = init.referrer;\n if (init.integrity !== undefined) integrity = init.integrity;\n\n // Validate: body with GET/HEAD\n if (body !== null && (method === 'GET' || method === 'HEAD')) {\n throw new TypeError('Request with GET/HEAD method cannot have body');\n }\n\n const bodyBytes = __prepareBody(body);\n\n // Handle Content-Type for FormData\n if (globalThis.__pendingFormDataContentType) {\n headers.set('content-type', globalThis.__pendingFormDataContentType);\n delete globalThis.__pendingFormDataContentType;\n } else if (body instanceof FormData && !headers.has('content-type')) {\n headers.set('content-type', 'application/x-www-form-urlencoded');\n }\n\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Request_construct(\n url, method, headersArray, bodyBytes,\n mode, credentials, cache, redirect, referrer, integrity\n );\n this.#headers = headers;\n this.#signal = signal;\n this.#streamId = null;\n }\n\n _getInstanceId() {\n return this.#instanceId;\n }\n\n static _fromInstanceId(instanceId) {\n return new Request(instanceId, null);\n }\n\n get method() {\n return __Request_get_method(this.#instanceId);\n }\n\n get url() {\n return __Request_get_url(this.#instanceId);\n }\n\n get headers() {\n return this.#headers;\n }\n\n get bodyUsed() {\n return __Request_get_bodyUsed(this.#instanceId);\n }\n\n get signal() {\n return this.#signal;\n }\n\n get mode() {\n return __Request_get_mode(this.#instanceId);\n }\n\n get credentials() {\n return __Request_get_credentials(this.#instanceId);\n }\n\n get cache() {\n return __Request_get_cache(this.#instanceId);\n }\n\n get redirect() {\n return __Request_get_redirect(this.#instanceId);\n }\n\n get referrer() {\n return __Request_get_referrer(this.#instanceId);\n }\n\n get integrity() {\n return __Request_get_integrity(this.#instanceId);\n }\n\n get body() {\n // Per WHATWG Fetch spec: GET/HEAD requests cannot have a body\n const method = __Request_get_method(this.#instanceId);\n if (method === 'GET' || method === 'HEAD') {\n return null;\n }\n\n // Return cached body if available\n if (this.#cachedBody !== null) {\n return this.#cachedBody;\n }\n\n // If we have a stream ID, create and cache the stream\n if (this.#streamId !== null) {\n this.#cachedBody = HostBackedReadableStream._fromStreamId(this.#streamId);\n return this.#cachedBody;\n }\n\n // Check if there's any buffered body data\n const buffer = __Request_arrayBuffer(this.#instanceId);\n if (buffer.byteLength === 0) {\n return null; // Return null per WHATWG Fetch spec for empty body\n }\n\n // Create stream from non-empty buffered body\n const newStreamId = __Stream_create();\n __Stream_push(newStreamId, Array.from(new Uint8Array(buffer)));\n __Stream_close(newStreamId);\n\n this.#cachedBody = HostBackedReadableStream._fromStreamId(newStreamId);\n return this.#cachedBody;\n }\n\n async text() {\n try {\n __Request_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n\n // If streaming, consume the stream\n if (this.#streamId !== null) {\n const bytes = await __consumeStream(this.body);\n return new TextDecoder().decode(bytes);\n }\n\n // Fallback to host callback for buffered body\n return __Request_text(this.#instanceId);\n }\n\n async json() {\n const text = await this.text();\n return JSON.parse(text);\n }\n\n async arrayBuffer() {\n try {\n __Request_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n\n // If streaming, consume the stream\n if (this.#streamId !== null) {\n const bytes = await __consumeStream(this.body);\n return bytes.buffer;\n }\n\n return __Request_arrayBuffer(this.#instanceId);\n }\n\n async blob() {\n const buffer = await this.arrayBuffer();\n const contentType = this.headers.get('content-type') || '';\n return new Blob([buffer], { type: contentType });\n }\n\n async formData() {\n const contentType = this.headers.get('content-type') || '';\n\n // Parse multipart/form-data\n if (contentType.includes('multipart/form-data')) {\n const buffer = await this.arrayBuffer();\n return __parseMultipartFormData(new Uint8Array(buffer), contentType);\n }\n\n // Parse application/x-www-form-urlencoded\n if (contentType.includes('application/x-www-form-urlencoded')) {\n const text = await this.text();\n const formData = new FormData();\n const params = new URLSearchParams(text);\n for (const [key, value] of params) {\n formData.append(key, value);\n }\n return formData;\n }\n\n throw new TypeError('Unsupported content type for formData()');\n }\n\n clone() {\n if (this.bodyUsed) {\n throw new TypeError('Cannot clone a Request that has already been used');\n }\n const newId = __Request_clone(this.#instanceId);\n const cloned = Request._fromInstanceId(newId);\n cloned.#signal = this.#signal;\n return cloned;\n }\n\n _getBodyBytes() {\n return __Request_getBodyBytes(this.#instanceId);\n }\n }\n\n globalThis.Request = Request;\n})();\n`;\n\n context.evalSync(requestCode);\n}\n\n// ============================================================================\n// fetch Implementation\n// ============================================================================\n\nfunction setupFetchFunction(\n context: ivm.Context,\n stateMap: Map<number, unknown>,\n options?: FetchOptions\n): void {\n const global = context.global;\n\n // Create async fetch reference\n // We use JSON serialization for complex data to avoid transfer issues\n const fetchRef = new ivm.Reference(\n async (\n url: string,\n method: string,\n headersJson: string,\n bodyJson: string | null,\n signalAborted: boolean\n ) => {\n // Check if already aborted\n if (signalAborted) {\n throw new Error(\"[AbortError]The operation was aborted.\");\n }\n\n // Parse headers and body from JSON\n const headers = JSON.parse(headersJson) as [string, string][];\n const bodyBytes = bodyJson ? JSON.parse(bodyJson) as number[] : null;\n\n // Construct native Request\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const nativeRequest = new Request(url, {\n method,\n headers,\n body,\n });\n\n // Call user's onFetch handler or default fetch\n const onFetch = options?.onFetch ?? fetch;\n const nativeResponse = await onFetch(nativeRequest);\n\n // Read response body\n const responseBody = await nativeResponse.arrayBuffer();\n const responseBodyArray = Array.from(new Uint8Array(responseBody));\n\n // Store the response in the state map and return just the ID + metadata\n const instanceId = nextInstanceId++;\n const state: ResponseState = {\n status: nativeResponse.status,\n statusText: nativeResponse.statusText,\n headers: Array.from(nativeResponse.headers.entries()),\n body: new Uint8Array(responseBodyArray),\n bodyUsed: false,\n type: \"default\",\n url: nativeResponse.url,\n redirected: nativeResponse.redirected,\n streamId: null,\n };\n stateMap.set(instanceId, state);\n\n // Return only the instance ID - avoid complex object transfer\n return instanceId;\n }\n );\n\n global.setSync(\"__fetch_ref\", fetchRef);\n\n // Inject fetch function\n const fetchCode = `\n(function() {\n function __decodeError(err) {\n if (!(err instanceof Error)) return err;\n const match = err.message.match(/^\\\\[(TypeError|RangeError|AbortError|Error)\\\\](.*)$/);\n if (match) {\n if (match[1] === 'AbortError') {\n return new DOMException(match[2], 'AbortError');\n }\n const ErrorType = globalThis[match[1]] || Error;\n return new ErrorType(match[2]);\n }\n return err;\n }\n\n globalThis.fetch = function(input, init = {}) {\n // Create Request from input\n const request = input instanceof Request ? input : new Request(input, init);\n\n // Get signal info\n const signal = init.signal ?? request.signal;\n const signalAborted = signal?.aborted ?? false;\n\n // Serialize headers and body to JSON for transfer\n const headersJson = JSON.stringify(Array.from(request.headers.entries()));\n const bodyBytes = request._getBodyBytes();\n const bodyJson = bodyBytes ? JSON.stringify(bodyBytes) : null;\n\n // Call host - returns just the response instance ID\n try {\n const instanceId = __fetch_ref.applySyncPromise(undefined, [\n request.url,\n request.method,\n headersJson,\n bodyJson,\n signalAborted\n ]);\n\n // Construct Response from the instance ID\n return Response._fromInstanceId(instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n };\n})();\n`;\n\n context.evalSync(fetchCode);\n}\n\n// ============================================================================\n// Server Implementation (for serve())\n// ============================================================================\n\nfunction setupServer(\n context: ivm.Context,\n serveState: ServeState\n): void {\n const global = context.global;\n\n // Setup upgrade registry in isolate (data stays in isolate, never marshalled to host)\n context.evalSync(`\n globalThis.__upgradeRegistry__ = new Map();\n globalThis.__upgradeIdCounter__ = 0;\n `);\n\n // Host callback to notify about pending upgrade\n global.setSync(\n \"__setPendingUpgrade__\",\n new ivm.Callback((connectionId: string) => {\n serveState.pendingUpgrade = { requested: true, connectionId };\n })\n );\n\n // Pure JS Server class with upgrade method\n context.evalSync(`\n(function() {\n class Server {\n upgrade(request, options) {\n const data = options?.data;\n const connectionId = String(++globalThis.__upgradeIdCounter__);\n globalThis.__upgradeRegistry__.set(connectionId, data);\n __setPendingUpgrade__(connectionId);\n return true;\n }\n }\n globalThis.__Server__ = Server;\n})();\n `);\n}\n\n// ============================================================================\n// ServerWebSocket Implementation (for serve())\n// ============================================================================\n\nfunction setupServerWebSocket(\n context: ivm.Context,\n wsCommandCallbacks: Set<(cmd: WebSocketCommand) => void>\n): void {\n const global = context.global;\n\n // Host callback for ws.send()\n global.setSync(\n \"__ServerWebSocket_send\",\n new ivm.Callback((connectionId: string, data: string) => {\n const cmd: WebSocketCommand = { type: \"message\", connectionId, data };\n for (const cb of wsCommandCallbacks) cb(cmd);\n })\n );\n\n // Host callback for ws.close()\n global.setSync(\n \"__ServerWebSocket_close\",\n new ivm.Callback((connectionId: string, code?: number, reason?: string) => {\n const cmd: WebSocketCommand = { type: \"close\", connectionId, code, reason };\n for (const cb of wsCommandCallbacks) cb(cmd);\n })\n );\n\n // Pure JS ServerWebSocket class\n context.evalSync(`\n(function() {\n const _wsInstanceData = new WeakMap();\n\n class ServerWebSocket {\n constructor(connectionId) {\n _wsInstanceData.set(this, { connectionId, readyState: 1 });\n }\n\n get data() {\n const state = _wsInstanceData.get(this);\n return globalThis.__upgradeRegistry__.get(state.connectionId);\n }\n\n get readyState() {\n return _wsInstanceData.get(this).readyState;\n }\n\n send(message) {\n const state = _wsInstanceData.get(this);\n if (state.readyState !== 1) throw new Error(\"WebSocket is not open\");\n // Convert ArrayBuffer/Uint8Array to string for transfer\n let data = message;\n if (message instanceof ArrayBuffer) {\n data = new TextDecoder().decode(message);\n } else if (message instanceof Uint8Array) {\n data = new TextDecoder().decode(message);\n }\n __ServerWebSocket_send(state.connectionId, data);\n }\n\n close(code, reason) {\n const state = _wsInstanceData.get(this);\n if (state.readyState === 3) return;\n state.readyState = 2; // CLOSING\n __ServerWebSocket_close(state.connectionId, code, reason);\n }\n\n _setReadyState(readyState) {\n _wsInstanceData.get(this).readyState = readyState;\n }\n }\n\n globalThis.__ServerWebSocket__ = ServerWebSocket;\n})();\n `);\n}\n\n// ============================================================================\n// serve() Function Implementation\n// ============================================================================\n\nfunction setupServe(context: ivm.Context): void {\n // Pure JS serve() that stores options on __serveOptions__ global\n context.evalSync(`\n(function() {\n globalThis.__serveOptions__ = null;\n\n function serve(options) {\n globalThis.__serveOptions__ = options;\n }\n\n globalThis.serve = serve;\n})();\n `);\n}\n\n// ============================================================================\n// Main Setup Function\n// ============================================================================\n\n/**\n * Setup Fetch API in an isolated-vm context\n *\n * Injects fetch, Request, Response, Headers, FormData\n * Also sets up core APIs (Blob, File, AbortController, etc.) if not already present\n *\n * @example\n * const handle = await setupFetch(context, {\n * onFetch: async (request) => {\n * // Proxy fetch requests to the host\n * return fetch(request);\n * }\n * });\n *\n * await context.eval(`\n * const response = await fetch(\"https://example.com\");\n * const text = await response.text();\n * `);\n */\nexport async function setupFetch(\n context: ivm.Context,\n options?: FetchOptions\n): Promise<FetchHandle> {\n // Setup core APIs first (Blob, File, AbortController, Streams, etc.)\n await setupCore(context);\n\n const stateMap = getInstanceStateMapForContext(context);\n const streamRegistry = getStreamRegistryForContext(context);\n\n // Inject Headers (pure JS)\n context.evalSync(headersCode);\n\n // Inject FormData (pure JS)\n context.evalSync(formDataCode);\n\n // Inject multipart parsing/serialization (pure JS)\n context.evalSync(multipartCode);\n\n // Setup stream callbacks and inject HostBackedReadableStream\n setupStreamCallbacks(context, streamRegistry);\n context.evalSync(hostBackedStreamCode);\n\n // Setup Response (host state + isolate class)\n setupResponse(context, stateMap);\n\n // Setup Request (host state + isolate class)\n setupRequest(context, stateMap);\n\n // Setup fetch function\n setupFetchFunction(context, stateMap, options);\n\n // Setup serve state\n const serveState: ServeState = {\n pendingUpgrade: null,\n activeConnections: new Map(),\n };\n\n // Setup WebSocket command callbacks\n const wsCommandCallbacks = new Set<(cmd: WebSocketCommand) => void>();\n\n // Setup Server class\n setupServer(context, serveState);\n\n // Setup ServerWebSocket class\n setupServerWebSocket(context, wsCommandCallbacks);\n\n // Setup serve function\n setupServe(context);\n\n return {\n dispose() {\n // Clear state for this context\n stateMap.clear();\n // Clear upgrade registry\n context.evalSync(`globalThis.__upgradeRegistry__.clear()`);\n // Clear serve state\n serveState.activeConnections.clear();\n serveState.pendingUpgrade = null;\n },\n\n async dispatchRequest(\n request: Request,\n _dispatchOptions?: DispatchRequestOptions\n ): Promise<Response> {\n // Clean up previous pending upgrade if not consumed\n if (serveState.pendingUpgrade) {\n const oldConnectionId = serveState.pendingUpgrade.connectionId;\n context.evalSync(`globalThis.__upgradeRegistry__.delete(\"${oldConnectionId}\")`);\n serveState.pendingUpgrade = null;\n }\n\n // Check if serve handler exists\n const hasHandler = context.evalSync(`!!globalThis.__serveOptions__?.fetch`);\n if (!hasHandler) {\n throw new Error(\"No serve() handler registered\");\n }\n\n // Setup streaming for request body\n // Per WHATWG Fetch spec, GET/HEAD requests cannot have bodies\n let requestStreamId: number | null = null;\n let streamCleanup: (() => Promise<void>) | null = null;\n const canHaveBody = !['GET', 'HEAD'].includes(request.method.toUpperCase());\n\n if (canHaveBody && request.body) {\n // Create a stream in the registry for the request body\n requestStreamId = streamRegistry.create();\n\n // Start background reader that pushes from native stream to host queue\n streamCleanup = startNativeStreamReader(\n request.body,\n requestStreamId,\n streamRegistry\n );\n }\n\n try {\n const headersArray = Array.from(request.headers.entries());\n\n // Create Request instance in isolate\n const requestInstanceId = nextInstanceId++;\n const requestState: RequestState = {\n url: request.url,\n method: request.method,\n headers: headersArray,\n body: null, // No buffered body - using stream\n bodyUsed: false,\n streamId: requestStreamId,\n mode: request.mode,\n credentials: request.credentials,\n cache: request.cache,\n redirect: request.redirect,\n referrer: request.referrer,\n integrity: request.integrity,\n };\n stateMap.set(requestInstanceId, requestState);\n\n // Call the fetch handler and get response\n // We use eval with promise: true to handle async handlers\n const responseInstanceId = await context.eval(`\n (async function() {\n const request = Request._fromInstanceId(${requestInstanceId});\n const server = new __Server__();\n const response = await Promise.resolve(__serveOptions__.fetch(request, server));\n return response._getInstanceId();\n })()\n `, { promise: true });\n\n // Get ResponseState from the instance\n const responseState = stateMap.get(responseInstanceId) as ResponseState | undefined;\n if (!responseState) {\n throw new Error(\"Response state not found\");\n }\n\n // Check if response has streaming body\n if (responseState.streamId !== null) {\n const responseStreamId = responseState.streamId;\n let streamDone = false;\n\n // Create native stream that waits for data from isolate\n const pumpedStream = new ReadableStream<Uint8Array>({\n async pull(controller) {\n if (streamDone) return;\n\n // Wait for data to be available\n while (!streamDone) {\n // Check if data is available\n const state = streamRegistry.get(responseStreamId);\n if (!state) {\n controller.close();\n streamDone = true;\n return;\n }\n\n // If queue has data or stream is done, break and pull\n if (state.queue.length > 0 || state.closed || state.errored) {\n break;\n }\n\n // Small delay to avoid busy-waiting\n await new Promise((r) => setTimeout(r, 1));\n }\n\n try {\n const result = await streamRegistry.pull(responseStreamId);\n if (result.done) {\n controller.close();\n streamDone = true;\n streamRegistry.delete(responseStreamId);\n return;\n }\n controller.enqueue(result.value);\n } catch (error) {\n controller.error(error);\n streamDone = true;\n streamRegistry.delete(responseStreamId);\n }\n },\n cancel() {\n streamDone = true;\n streamRegistry.error(\n responseStreamId,\n new Error(\"Stream cancelled\")\n );\n streamRegistry.delete(responseStreamId);\n },\n });\n\n const responseHeaders = new Headers(responseState.headers);\n const status =\n responseState.status === 101 ? 200 : responseState.status;\n const response = new Response(pumpedStream, {\n status,\n statusText: responseState.statusText,\n headers: responseHeaders,\n });\n\n // @ts-expect-error - adding custom property\n response._originalStatus = responseState.status;\n\n return response;\n }\n\n // Convert to native Response (non-streaming)\n const responseHeaders = new Headers(responseState.headers);\n const responseBody = responseState.body;\n\n // Note: Status 101 (Switching Protocols) is not valid for Response constructor\n // We use 200 as the status but preserve the actual status in a custom header\n // The caller should check getUpgradeRequest() for WebSocket upgrades\n const status = responseState.status === 101 ? 200 : responseState.status;\n const response = new Response(responseBody as ConstructorParameters<typeof Response>[0], {\n status,\n statusText: responseState.statusText,\n headers: responseHeaders,\n });\n\n // Expose the original status via a property for callers to check\n // @ts-expect-error - adding custom property\n response._originalStatus = responseState.status;\n\n return response;\n } finally {\n // Cleanup: cancel stream reader if still running\n if (streamCleanup) {\n await streamCleanup();\n }\n // Delete stream from registry\n if (requestStreamId !== null) {\n streamRegistry.delete(requestStreamId);\n }\n }\n },\n\n getUpgradeRequest(): UpgradeRequest | null {\n const result = serveState.pendingUpgrade;\n // Don't clear yet - it will be cleared on next dispatchRequest or consumed by dispatchWebSocketOpen\n return result;\n },\n\n dispatchWebSocketOpen(connectionId: string): void {\n // Store connection (data stays in isolate registry)\n serveState.activeConnections.set(connectionId, { connectionId });\n\n // Check if websocket.open handler exists\n const hasOpenHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.open`);\n\n // Create ServerWebSocket instance (always needed for message/close handlers)\n context.evalSync(`\n (function() {\n const ws = new __ServerWebSocket__(\"${connectionId}\");\n globalThis.__activeWs_${connectionId}__ = ws;\n })()\n `);\n\n // Call open handler if it exists\n if (hasOpenHandler) {\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n __serveOptions__.websocket.open(ws);\n })()\n `);\n }\n\n // Clear pending upgrade after successful open\n if (serveState.pendingUpgrade?.connectionId === connectionId) {\n serveState.pendingUpgrade = null;\n }\n },\n\n dispatchWebSocketMessage(connectionId: string, message: string | ArrayBuffer): void {\n // Check if connection is tracked\n if (!serveState.activeConnections.has(connectionId)) {\n return; // Silently ignore for unknown connections\n }\n\n // Check if message handler exists\n const hasMessageHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.message`);\n if (!hasMessageHandler) {\n return;\n }\n\n // Marshal message and call handler\n if (typeof message === \"string\") {\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) __serveOptions__.websocket.message(ws, \"${message.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\")}\");\n })()\n `);\n } else {\n // ArrayBuffer - convert to base64 or pass as array\n const bytes = Array.from(new Uint8Array(message));\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) {\n const bytes = new Uint8Array([${bytes.join(\",\")}]);\n __serveOptions__.websocket.message(ws, bytes.buffer);\n }\n })()\n `);\n }\n },\n\n dispatchWebSocketClose(connectionId: string, code: number, reason: string): void {\n // Check if connection is tracked\n if (!serveState.activeConnections.has(connectionId)) {\n return;\n }\n\n // Update readyState to CLOSED\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) ws._setReadyState(3);\n })()\n `);\n\n // Check if close handler exists\n const hasCloseHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.close`);\n if (hasCloseHandler) {\n const safeReason = reason.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) __serveOptions__.websocket.close(ws, ${code}, \"${safeReason}\");\n })()\n `);\n }\n\n // Cleanup\n context.evalSync(`\n delete globalThis.__activeWs_${connectionId}__;\n globalThis.__upgradeRegistry__.delete(\"${connectionId}\");\n `);\n serveState.activeConnections.delete(connectionId);\n },\n\n dispatchWebSocketError(connectionId: string, error: Error): void {\n // Check if connection is tracked\n if (!serveState.activeConnections.has(connectionId)) {\n return;\n }\n\n // Check if error handler exists\n const hasErrorHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.error`);\n if (!hasErrorHandler) {\n return;\n }\n\n const safeName = error.name.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n const safeMessage = error.message.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) {\n const error = { name: \"${safeName}\", message: \"${safeMessage}\" };\n __serveOptions__.websocket.error(ws, error);\n }\n })()\n `);\n },\n\n onWebSocketCommand(callback: (cmd: WebSocketCommand) => void): () => void {\n wsCommandCallbacks.add(callback);\n return () => wsCommandCallbacks.delete(callback);\n },\n\n hasServeHandler(): boolean {\n return context.evalSync(`!!globalThis.__serveOptions__?.fetch`) as boolean;\n },\n\n hasActiveConnections(): boolean {\n return serveState.activeConnections.size > 0;\n },\n };\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkVpB,QAAQ,SAAS,WAAW;AAAA;AA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",
|
|
8
|
+
"debugId": "654ECA7C6F1E87A964756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/cjs/package.json
CHANGED
package/dist/mjs/index.mjs
CHANGED
|
@@ -423,6 +423,19 @@ var hostBackedStreamCode = `
|
|
|
423
423
|
return false;
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
+
async *[Symbol.asyncIterator]() {
|
|
427
|
+
const reader = this.getReader();
|
|
428
|
+
try {
|
|
429
|
+
while (true) {
|
|
430
|
+
const { value, done } = await reader.read();
|
|
431
|
+
if (done) return;
|
|
432
|
+
yield value;
|
|
433
|
+
}
|
|
434
|
+
} finally {
|
|
435
|
+
reader.releaseLock();
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
426
439
|
// Static method to create from existing stream ID
|
|
427
440
|
static _fromStreamId(streamId) {
|
|
428
441
|
return new HostBackedReadableStream(streamId);
|
|
@@ -1209,6 +1222,12 @@ function setupRequest(context, stateMap) {
|
|
|
1209
1222
|
}
|
|
1210
1223
|
|
|
1211
1224
|
get body() {
|
|
1225
|
+
// Per WHATWG Fetch spec: GET/HEAD requests cannot have a body
|
|
1226
|
+
const method = __Request_get_method(this.#instanceId);
|
|
1227
|
+
if (method === 'GET' || method === 'HEAD') {
|
|
1228
|
+
return null;
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1212
1231
|
// Return cached body if available
|
|
1213
1232
|
if (this.#cachedBody !== null) {
|
|
1214
1233
|
return this.#cachedBody;
|
|
@@ -1220,12 +1239,15 @@ function setupRequest(context, stateMap) {
|
|
|
1220
1239
|
return this.#cachedBody;
|
|
1221
1240
|
}
|
|
1222
1241
|
|
|
1223
|
-
//
|
|
1224
|
-
const newStreamId = __Stream_create();
|
|
1242
|
+
// Check if there's any buffered body data
|
|
1225
1243
|
const buffer = __Request_arrayBuffer(this.#instanceId);
|
|
1226
|
-
if (buffer.byteLength
|
|
1227
|
-
|
|
1244
|
+
if (buffer.byteLength === 0) {
|
|
1245
|
+
return null; // Return null per WHATWG Fetch spec for empty body
|
|
1228
1246
|
}
|
|
1247
|
+
|
|
1248
|
+
// Create stream from non-empty buffered body
|
|
1249
|
+
const newStreamId = __Stream_create();
|
|
1250
|
+
__Stream_push(newStreamId, Array.from(new Uint8Array(buffer)));
|
|
1229
1251
|
__Stream_close(newStreamId);
|
|
1230
1252
|
|
|
1231
1253
|
this.#cachedBody = HostBackedReadableStream._fromStreamId(newStreamId);
|
|
@@ -1536,7 +1558,8 @@ async function setupFetch(context, options) {
|
|
|
1536
1558
|
}
|
|
1537
1559
|
let requestStreamId = null;
|
|
1538
1560
|
let streamCleanup = null;
|
|
1539
|
-
|
|
1561
|
+
const canHaveBody = !["GET", "HEAD"].includes(request.method.toUpperCase());
|
|
1562
|
+
if (canHaveBody && request.body) {
|
|
1540
1563
|
requestStreamId = streamRegistry.create();
|
|
1541
1564
|
streamCleanup = startNativeStreamReader(request.body, requestStreamId, streamRegistry);
|
|
1542
1565
|
}
|
|
@@ -1755,4 +1778,4 @@ export {
|
|
|
1755
1778
|
clearAllInstanceState
|
|
1756
1779
|
};
|
|
1757
1780
|
|
|
1758
|
-
//# debugId=
|
|
1781
|
+
//# debugId=AECB616396B74DA864756E2164756E21
|
package/dist/mjs/index.mjs.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import ivm from \"isolated-vm\";\nimport { setupCore, clearAllInstanceState } from \"@ricsam/isolate-core\";\nimport {\n getStreamRegistryForContext,\n startNativeStreamReader,\n} from \"./stream-state.mjs\";\nimport type { StreamStateRegistry } from \"./stream-state.mjs\";\n\nexport { clearAllInstanceState };\n\nexport interface FetchOptions {\n /** Handler for fetch requests from the isolate */\n onFetch?: (request: Request) => Promise<Response>;\n}\n\n// ============================================================================\n// Serve Types\n// ============================================================================\n\nexport interface UpgradeRequest {\n requested: true;\n connectionId: string;\n}\n\nexport interface WebSocketCommand {\n type: \"message\" | \"close\";\n connectionId: string;\n data?: string | ArrayBuffer;\n code?: number;\n reason?: string;\n}\n\ninterface ServeState {\n pendingUpgrade: UpgradeRequest | null;\n activeConnections: Map<string, { connectionId: string }>;\n}\n\nexport interface DispatchRequestOptions {\n // Reserved for future options\n}\n\nexport interface FetchHandle {\n dispose(): void;\n /** Dispatch an HTTP request to the isolate's serve() handler */\n dispatchRequest(request: Request, options?: DispatchRequestOptions): Promise<Response>;\n /** Check if isolate requested WebSocket upgrade */\n getUpgradeRequest(): UpgradeRequest | null;\n /** Dispatch WebSocket open event to isolate */\n dispatchWebSocketOpen(connectionId: string): void;\n /** Dispatch WebSocket message event to isolate */\n dispatchWebSocketMessage(connectionId: string, message: string | ArrayBuffer): void;\n /** Dispatch WebSocket close event to isolate */\n dispatchWebSocketClose(connectionId: string, code: number, reason: string): void;\n /** Dispatch WebSocket error event to isolate */\n dispatchWebSocketError(connectionId: string, error: Error): void;\n /** Register callback for WebSocket commands from isolate */\n onWebSocketCommand(callback: (cmd: WebSocketCommand) => void): () => void;\n /** Check if serve() has been called */\n hasServeHandler(): boolean;\n /** Check if there are active WebSocket connections */\n hasActiveConnections(): boolean;\n}\n\n// ============================================================================\n// Instance State Management\n// ============================================================================\n\nconst instanceStateMap = new WeakMap<ivm.Context, Map<number, unknown>>();\nlet nextInstanceId = 1;\n\nfunction getInstanceStateMapForContext(\n context: ivm.Context\n): Map<number, unknown> {\n let map = instanceStateMap.get(context);\n if (!map) {\n map = new Map();\n instanceStateMap.set(context, map);\n }\n return map;\n}\n\n// ============================================================================\n// State Types\n// ============================================================================\n\ninterface ResponseState {\n status: number;\n statusText: string;\n headers: [string, string][];\n body: Uint8Array | null;\n bodyUsed: boolean;\n type: string;\n url: string;\n redirected: boolean;\n streamId: number | null;\n}\n\ninterface RequestState {\n method: string;\n url: string;\n headers: [string, string][];\n body: Uint8Array | null;\n bodyUsed: boolean;\n streamId: number | null;\n mode: string;\n credentials: string;\n cache: string;\n redirect: string;\n referrer: string;\n integrity: string;\n}\n\n// ============================================================================\n// Headers Implementation (Pure JS)\n// ============================================================================\n\nconst headersCode = `\n(function() {\n class Headers {\n #headers = new Map(); // lowercase key -> [originalCase, values[]]\n\n constructor(init) {\n if (init instanceof Headers) {\n init.forEach((value, key) => this.append(key, value));\n } else if (Array.isArray(init)) {\n for (const pair of init) {\n if (Array.isArray(pair) && pair.length >= 2) {\n this.append(pair[0], pair[1]);\n }\n }\n } else if (init && typeof init === 'object') {\n for (const [key, value] of Object.entries(init)) {\n this.append(key, value);\n }\n }\n }\n\n append(name, value) {\n const key = String(name).toLowerCase();\n const valueStr = String(value);\n const existing = this.#headers.get(key);\n if (existing) {\n existing[1].push(valueStr);\n } else {\n this.#headers.set(key, [String(name), [valueStr]]);\n }\n }\n\n delete(name) {\n this.#headers.delete(String(name).toLowerCase());\n }\n\n get(name) {\n const entry = this.#headers.get(String(name).toLowerCase());\n return entry ? entry[1].join(', ') : null;\n }\n\n getSetCookie() {\n const entry = this.#headers.get('set-cookie');\n return entry ? [...entry[1]] : [];\n }\n\n has(name) {\n return this.#headers.has(String(name).toLowerCase());\n }\n\n set(name, value) {\n const key = String(name).toLowerCase();\n this.#headers.set(key, [String(name), [String(value)]]);\n }\n\n forEach(callback, thisArg) {\n for (const [key, [originalName, values]] of this.#headers) {\n callback.call(thisArg, values.join(', '), originalName, this);\n }\n }\n\n *entries() {\n for (const [key, [name, values]] of this.#headers) {\n yield [name, values.join(', ')];\n }\n }\n\n *keys() {\n for (const [key, [name]] of this.#headers) {\n yield name;\n }\n }\n\n *values() {\n for (const [key, [name, values]] of this.#headers) {\n yield values.join(', ');\n }\n }\n\n [Symbol.iterator]() {\n return this.entries();\n }\n }\n\n globalThis.Headers = Headers;\n})();\n`;\n\n// ============================================================================\n// FormData Implementation (Pure JS)\n// ============================================================================\n\nconst formDataCode = `\n(function() {\n class FormData {\n #entries = []; // Array of [name, value]\n\n append(name, value, filename) {\n let finalValue = value;\n if (value instanceof Blob && !(value instanceof File)) {\n if (filename !== undefined) {\n finalValue = new File([value], String(filename), { type: value.type });\n }\n } else if (value instanceof File && filename !== undefined) {\n finalValue = new File([value], String(filename), {\n type: value.type,\n lastModified: value.lastModified\n });\n }\n this.#entries.push([String(name), finalValue]);\n }\n\n delete(name) {\n const nameStr = String(name);\n this.#entries = this.#entries.filter(([n]) => n !== nameStr);\n }\n\n get(name) {\n const nameStr = String(name);\n const entry = this.#entries.find(([n]) => n === nameStr);\n return entry ? entry[1] : null;\n }\n\n getAll(name) {\n const nameStr = String(name);\n return this.#entries.filter(([n]) => n === nameStr).map(([, v]) => v);\n }\n\n has(name) {\n return this.#entries.some(([n]) => n === String(name));\n }\n\n set(name, value, filename) {\n const nameStr = String(name);\n this.delete(nameStr);\n this.append(nameStr, value, filename);\n }\n\n *entries() {\n for (const [name, value] of this.#entries) {\n yield [name, value];\n }\n }\n\n *keys() {\n for (const [name] of this.#entries) {\n yield name;\n }\n }\n\n *values() {\n for (const [, value] of this.#entries) {\n yield value;\n }\n }\n\n forEach(callback, thisArg) {\n for (const [name, value] of this.#entries) {\n callback.call(thisArg, value, name, this);\n }\n }\n\n [Symbol.iterator]() {\n return this.entries();\n }\n }\n\n globalThis.FormData = FormData;\n})();\n`;\n\n// ============================================================================\n// Multipart FormData Parsing/Serialization (Pure JS)\n// ============================================================================\n\nconst multipartCode = `\n(function() {\n // Find byte sequence in Uint8Array\n function findSequence(haystack, needle, start = 0) {\n outer: for (let i = start; i <= haystack.length - needle.length; i++) {\n for (let j = 0; j < needle.length; j++) {\n if (haystack[i + j] !== needle[j]) continue outer;\n }\n return i;\n }\n return -1;\n }\n\n // Parse header lines into object\n function parseHeaders(text) {\n const headers = {};\n for (const line of text.split(/\\\\r?\\\\n/)) {\n const colonIdx = line.indexOf(':');\n if (colonIdx > 0) {\n const name = line.slice(0, colonIdx).trim().toLowerCase();\n const value = line.slice(colonIdx + 1).trim();\n headers[name] = value;\n }\n }\n return headers;\n }\n\n // Parse multipart/form-data body into FormData\n globalThis.__parseMultipartFormData = function(bodyBytes, contentType) {\n const formData = new FormData();\n\n // Extract boundary from Content-Type\n const boundaryMatch = contentType.match(/boundary=([^;]+)/i);\n if (!boundaryMatch) return formData;\n\n const boundary = boundaryMatch[1].replace(/^[\"']|[\"']$/g, '');\n const encoder = new TextEncoder();\n const decoder = new TextDecoder();\n const boundaryBytes = encoder.encode('--' + boundary);\n\n // Find first boundary\n let pos = findSequence(bodyBytes, boundaryBytes, 0);\n if (pos === -1) return formData;\n pos += boundaryBytes.length;\n\n while (pos < bodyBytes.length) {\n // Skip CRLF after boundary\n if (bodyBytes[pos] === 0x0d && bodyBytes[pos + 1] === 0x0a) pos += 2;\n else if (bodyBytes[pos] === 0x0a) pos += 1;\n\n // Check for closing boundary (--)\n if (bodyBytes[pos] === 0x2d && bodyBytes[pos + 1] === 0x2d) break;\n\n // Find header/body separator (CRLFCRLF)\n const crlfcrlf = encoder.encode('\\\\r\\\\n\\\\r\\\\n');\n const headersEnd = findSequence(bodyBytes, crlfcrlf, pos);\n if (headersEnd === -1) break;\n\n // Parse headers\n const headersText = decoder.decode(bodyBytes.slice(pos, headersEnd));\n const headers = parseHeaders(headersText);\n pos = headersEnd + 4;\n\n // Find next boundary\n const nextBoundary = findSequence(bodyBytes, boundaryBytes, pos);\n if (nextBoundary === -1) break;\n\n // Extract content (minus trailing CRLF)\n let contentEnd = nextBoundary;\n if (contentEnd > 0 && bodyBytes[contentEnd - 1] === 0x0a) contentEnd--;\n if (contentEnd > 0 && bodyBytes[contentEnd - 1] === 0x0d) contentEnd--;\n const content = bodyBytes.slice(pos, contentEnd);\n\n // Parse Content-Disposition\n const disposition = headers['content-disposition'] || '';\n const nameMatch = disposition.match(/name=\"([^\"]+)\"/);\n const filenameMatch = disposition.match(/filename=\"([^\"]+)\"/);\n\n if (nameMatch) {\n const name = nameMatch[1];\n if (filenameMatch) {\n const filename = filenameMatch[1];\n const mimeType = headers['content-type'] || 'application/octet-stream';\n const file = new File([content], filename, { type: mimeType });\n formData.append(name, file);\n } else {\n formData.append(name, decoder.decode(content));\n }\n }\n\n pos = nextBoundary + boundaryBytes.length;\n }\n\n return formData;\n };\n\n // Serialize FormData to multipart/form-data format\n globalThis.__serializeFormData = function(formData) {\n const boundary = '----FormDataBoundary' + Math.random().toString(36).slice(2) +\n Math.random().toString(36).slice(2);\n const encoder = new TextEncoder();\n const parts = [];\n\n for (const [name, value] of formData.entries()) {\n if (value instanceof File) {\n const header = [\n '--' + boundary,\n 'Content-Disposition: form-data; name=\"' + name + '\"; filename=\"' + value.name + '\"',\n 'Content-Type: ' + (value.type || 'application/octet-stream'),\n '',\n ''\n ].join('\\\\r\\\\n');\n parts.push(encoder.encode(header));\n // Use existing __Blob_bytes callback (File extends Blob)\n parts.push(__Blob_bytes(value._getInstanceId()));\n parts.push(encoder.encode('\\\\r\\\\n'));\n } else if (value instanceof Blob) {\n const header = [\n '--' + boundary,\n 'Content-Disposition: form-data; name=\"' + name + '\"; filename=\"blob\"',\n 'Content-Type: ' + (value.type || 'application/octet-stream'),\n '',\n ''\n ].join('\\\\r\\\\n');\n parts.push(encoder.encode(header));\n parts.push(__Blob_bytes(value._getInstanceId()));\n parts.push(encoder.encode('\\\\r\\\\n'));\n } else {\n const header = [\n '--' + boundary,\n 'Content-Disposition: form-data; name=\"' + name + '\"',\n '',\n ''\n ].join('\\\\r\\\\n');\n parts.push(encoder.encode(header));\n parts.push(encoder.encode(String(value)));\n parts.push(encoder.encode('\\\\r\\\\n'));\n }\n }\n\n // Closing boundary\n parts.push(encoder.encode('--' + boundary + '--\\\\r\\\\n'));\n\n // Concatenate all parts\n const totalLength = parts.reduce((sum, p) => sum + p.length, 0);\n const body = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n body.set(part, offset);\n offset += part.length;\n }\n\n return {\n body: body,\n contentType: 'multipart/form-data; boundary=' + boundary\n };\n };\n})();\n`;\n\n// ============================================================================\n// Stream Callbacks (Host State)\n// ============================================================================\n\nfunction setupStreamCallbacks(\n context: ivm.Context,\n streamRegistry: StreamStateRegistry\n): void {\n const global = context.global;\n\n // Create stream (returns ID)\n global.setSync(\n \"__Stream_create\",\n new ivm.Callback(() => {\n return streamRegistry.create();\n })\n );\n\n // Push chunk (sync) - receives number[] from isolate\n global.setSync(\n \"__Stream_push\",\n new ivm.Callback((streamId: number, chunkArray: number[]) => {\n const chunk = new Uint8Array(chunkArray);\n return streamRegistry.push(streamId, chunk);\n })\n );\n\n // Close stream (sync)\n global.setSync(\n \"__Stream_close\",\n new ivm.Callback((streamId: number) => {\n streamRegistry.close(streamId);\n })\n );\n\n // Error stream (sync)\n global.setSync(\n \"__Stream_error\",\n new ivm.Callback((streamId: number, message: string) => {\n streamRegistry.error(streamId, new Error(message));\n })\n );\n\n // Check backpressure (sync)\n global.setSync(\n \"__Stream_isQueueFull\",\n new ivm.Callback((streamId: number) => {\n return streamRegistry.isQueueFull(streamId);\n })\n );\n\n // Pull chunk (async with applySyncPromise)\n const pullRef = new ivm.Reference(async (streamId: number) => {\n const result = await streamRegistry.pull(streamId);\n if (result.done) {\n return JSON.stringify({ done: true });\n }\n return JSON.stringify({ done: false, value: Array.from(result.value) });\n });\n global.setSync(\"__Stream_pull_ref\", pullRef);\n}\n\n// ============================================================================\n// Host-Backed ReadableStream (Isolate Code)\n// ============================================================================\n\nconst hostBackedStreamCode = `\n(function() {\n const _streamIds = new WeakMap();\n\n class HostBackedReadableStream {\n constructor(streamId) {\n if (streamId === undefined) {\n streamId = __Stream_create();\n }\n _streamIds.set(this, streamId);\n }\n\n _getStreamId() {\n return _streamIds.get(this);\n }\n\n getReader() {\n const streamId = this._getStreamId();\n let released = false;\n\n return {\n read: async () => {\n if (released) {\n throw new TypeError(\"Reader has been released\");\n }\n const resultJson = __Stream_pull_ref.applySyncPromise(undefined, [streamId]);\n const result = JSON.parse(resultJson);\n\n if (result.done) {\n return { done: true, value: undefined };\n }\n return { done: false, value: new Uint8Array(result.value) };\n },\n\n releaseLock: () => {\n released = true;\n },\n\n get closed() {\n return new Promise(() => {});\n },\n\n cancel: async (reason) => {\n __Stream_error(streamId, String(reason || \"cancelled\"));\n }\n };\n }\n\n async cancel(reason) {\n __Stream_error(this._getStreamId(), String(reason || \"cancelled\"));\n }\n\n get locked() {\n return false;\n }\n\n // Static method to create from existing stream ID\n static _fromStreamId(streamId) {\n return new HostBackedReadableStream(streamId);\n }\n }\n\n globalThis.HostBackedReadableStream = HostBackedReadableStream;\n})();\n`;\n\n// ============================================================================\n// Response Implementation (Host State + Isolate Class)\n// ============================================================================\n\nfunction setupResponse(\n context: ivm.Context,\n stateMap: Map<number, unknown>\n): void {\n const global = context.global;\n\n // Register host callbacks\n global.setSync(\n \"__Response_construct\",\n new ivm.Callback(\n (\n bodyBytes: number[] | null,\n status: number,\n statusText: string,\n headers: [string, string][]\n ) => {\n const instanceId = nextInstanceId++;\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const state: ResponseState = {\n status,\n statusText,\n headers,\n body,\n bodyUsed: false,\n type: \"default\",\n url: \"\",\n redirected: false,\n streamId: null,\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n // Streaming Response constructor - creates Response with stream ID but no buffered body\n global.setSync(\n \"__Response_constructStreaming\",\n new ivm.Callback(\n (\n streamId: number,\n status: number,\n statusText: string,\n headers: [string, string][]\n ) => {\n const instanceId = nextInstanceId++;\n const state: ResponseState = {\n status,\n statusText,\n headers,\n body: null, // No buffered body - using stream\n bodyUsed: false,\n type: \"default\",\n url: \"\",\n redirected: false,\n streamId, // Stream ID for body\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n global.setSync(\n \"__Response_constructFromFetch\",\n new ivm.Callback(\n (\n bodyBytes: number[] | null,\n status: number,\n statusText: string,\n headers: [string, string][],\n url: string,\n redirected: boolean\n ) => {\n const instanceId = nextInstanceId++;\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const state: ResponseState = {\n status,\n statusText,\n headers,\n body,\n bodyUsed: false,\n type: \"default\",\n url,\n redirected,\n streamId: null,\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n global.setSync(\n \"__Response_get_status\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.status ?? 200;\n })\n );\n\n global.setSync(\n \"__Response_get_statusText\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.statusText ?? \"\";\n })\n );\n\n global.setSync(\n \"__Response_get_headers\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.headers ?? [];\n })\n );\n\n global.setSync(\n \"__Response_get_bodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.bodyUsed ?? false;\n })\n );\n\n global.setSync(\n \"__Response_get_url\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.url ?? \"\";\n })\n );\n\n global.setSync(\n \"__Response_get_redirected\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.redirected ?? false;\n })\n );\n\n global.setSync(\n \"__Response_get_type\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.type ?? \"default\";\n })\n );\n\n global.setSync(\n \"__Response_setType\",\n new ivm.Callback((instanceId: number, type: string) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (state) {\n state.type = type;\n }\n })\n );\n\n global.setSync(\n \"__Response_markBodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (state) {\n if (state.bodyUsed) {\n throw new Error(\"[TypeError]Body has already been consumed\");\n }\n state.bodyUsed = true;\n }\n })\n );\n\n global.setSync(\n \"__Response_text\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (!state || !state.body) return \"\";\n return new TextDecoder().decode(state.body);\n })\n );\n\n global.setSync(\n \"__Response_arrayBuffer\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (!state || !state.body) {\n return new ivm.ExternalCopy(new ArrayBuffer(0)).copyInto();\n }\n return new ivm.ExternalCopy(state.body.buffer.slice(\n state.body.byteOffset,\n state.body.byteOffset + state.body.byteLength\n )).copyInto();\n })\n );\n\n global.setSync(\n \"__Response_clone\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (!state) {\n throw new Error(\"[TypeError]Cannot clone invalid Response\");\n }\n const newId = nextInstanceId++;\n const newState: ResponseState = {\n ...state,\n body: state.body ? new Uint8Array(state.body) : null,\n bodyUsed: false,\n };\n stateMap.set(newId, newState);\n return newId;\n })\n );\n\n global.setSync(\n \"__Response_getStreamId\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.streamId ?? null;\n })\n );\n\n // Inject Response class\n const responseCode = `\n(function() {\n const _responseInstanceIds = new WeakMap();\n\n function __decodeError(err) {\n if (!(err instanceof Error)) return err;\n const match = err.message.match(/^\\\\[(TypeError|RangeError|SyntaxError|ReferenceError|URIError|EvalError|Error)\\\\](.*)$/);\n if (match) {\n const ErrorType = globalThis[match[1]] || Error;\n return new ErrorType(match[2]);\n }\n return err;\n }\n\n function __prepareBody(body) {\n if (body === null || body === undefined) return null;\n if (typeof body === 'string') {\n const encoder = new TextEncoder();\n return Array.from(encoder.encode(body));\n }\n if (body instanceof ArrayBuffer) {\n return Array.from(new Uint8Array(body));\n }\n if (body instanceof Uint8Array) {\n return Array.from(body);\n }\n if (ArrayBuffer.isView(body)) {\n return Array.from(new Uint8Array(body.buffer, body.byteOffset, body.byteLength));\n }\n if (body instanceof Blob) {\n // Mark as needing async Blob handling - will be read in constructor\n return { __isBlob: true, blob: body };\n }\n // Handle ReadableStream (both native and host-backed)\n if (body instanceof ReadableStream || body instanceof HostBackedReadableStream) {\n return { __isStream: true, stream: body };\n }\n // Try to convert to string\n return Array.from(new TextEncoder().encode(String(body)));\n }\n\n class Response {\n #instanceId;\n #headers;\n #streamId = null;\n #blobInitPromise = null; // For async Blob body initialization\n\n constructor(body, init = {}) {\n // Handle internal construction from instance ID\n if (typeof body === 'number' && init === null) {\n this.#instanceId = body;\n this.#headers = new Headers(__Response_get_headers(body));\n this.#streamId = __Response_getStreamId(body);\n return;\n }\n\n const preparedBody = __prepareBody(body);\n\n // Handle Blob body - create streaming response and push blob data\n if (preparedBody && preparedBody.__isBlob) {\n this.#streamId = __Stream_create();\n const status = init.status ?? 200;\n const statusText = init.statusText ?? '';\n const headers = new Headers(init.headers);\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Response_constructStreaming(\n this.#streamId,\n status,\n statusText,\n headersArray\n );\n this.#headers = headers;\n\n // Start async blob initialization and stream pumping\n const streamId = this.#streamId;\n const blob = preparedBody.blob;\n this.#blobInitPromise = (async () => {\n try {\n const buffer = await blob.arrayBuffer();\n __Stream_push(streamId, Array.from(new Uint8Array(buffer)));\n __Stream_close(streamId);\n } catch (error) {\n __Stream_error(streamId, String(error));\n }\n })();\n return;\n }\n\n // Handle streaming body\n if (preparedBody && preparedBody.__isStream) {\n this.#streamId = __Stream_create();\n const status = init.status ?? 200;\n const statusText = init.statusText ?? '';\n const headers = new Headers(init.headers);\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Response_constructStreaming(\n this.#streamId,\n status,\n statusText,\n headersArray\n );\n this.#headers = headers;\n\n // Start pumping the source stream to host queue (fire-and-forget)\n this._startStreamPump(preparedBody.stream);\n return;\n }\n\n // Existing buffered body handling\n const bodyBytes = preparedBody;\n const status = init.status ?? 200;\n const statusText = init.statusText ?? '';\n const headersInit = init.headers;\n const headers = new Headers(headersInit);\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Response_construct(bodyBytes, status, statusText, headersArray);\n this.#headers = headers;\n }\n\n async _startStreamPump(sourceStream) {\n const streamId = this.#streamId;\n try {\n const reader = sourceStream.getReader();\n while (true) {\n // Check backpressure - wait if queue is full\n while (__Stream_isQueueFull(streamId)) {\n await new Promise(r => setTimeout(r, 1));\n }\n\n const { done, value } = await reader.read();\n if (done) {\n __Stream_close(streamId);\n break;\n }\n if (value) {\n __Stream_push(streamId, Array.from(value));\n }\n }\n } catch (error) {\n __Stream_error(streamId, String(error));\n }\n }\n\n _getInstanceId() {\n return this.#instanceId;\n }\n\n static _fromInstanceId(instanceId) {\n return new Response(instanceId, null);\n }\n\n get status() {\n return __Response_get_status(this.#instanceId);\n }\n\n get statusText() {\n return __Response_get_statusText(this.#instanceId);\n }\n\n get ok() {\n const status = this.status;\n return status >= 200 && status < 300;\n }\n\n get headers() {\n return this.#headers;\n }\n\n get bodyUsed() {\n return __Response_get_bodyUsed(this.#instanceId);\n }\n\n get url() {\n return __Response_get_url(this.#instanceId);\n }\n\n get redirected() {\n return __Response_get_redirected(this.#instanceId);\n }\n\n get type() {\n return __Response_get_type(this.#instanceId);\n }\n\n get body() {\n const streamId = __Response_getStreamId(this.#instanceId);\n if (streamId !== null) {\n return HostBackedReadableStream._fromStreamId(streamId);\n }\n\n // Fallback: create host-backed stream from buffered body\n const instanceId = this.#instanceId;\n const newStreamId = __Stream_create();\n const buffer = __Response_arrayBuffer(instanceId);\n\n if (buffer.byteLength > 0) {\n __Stream_push(newStreamId, Array.from(new Uint8Array(buffer)));\n }\n __Stream_close(newStreamId);\n\n return HostBackedReadableStream._fromStreamId(newStreamId);\n }\n\n async text() {\n try {\n __Response_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n return __Response_text(this.#instanceId);\n }\n\n async json() {\n const text = await this.text();\n return JSON.parse(text);\n }\n\n async arrayBuffer() {\n try {\n __Response_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n\n // For streaming responses (including Blob bodies), consume the stream\n if (this.#streamId !== null) {\n // Wait for blob init to complete if needed\n if (this.#blobInitPromise) {\n await this.#blobInitPromise;\n this.#blobInitPromise = null;\n }\n\n const reader = this.body.getReader();\n const chunks = [];\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value) chunks.push(value);\n }\n // Concatenate all chunks\n const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n return result.buffer;\n }\n\n return __Response_arrayBuffer(this.#instanceId);\n }\n\n async blob() {\n const buffer = await this.arrayBuffer();\n const contentType = this.headers.get('content-type') || '';\n return new Blob([buffer], { type: contentType });\n }\n\n async formData() {\n const contentType = this.headers.get('content-type') || '';\n\n // Parse multipart/form-data\n if (contentType.includes('multipart/form-data')) {\n const buffer = await this.arrayBuffer();\n return __parseMultipartFormData(new Uint8Array(buffer), contentType);\n }\n\n // Parse application/x-www-form-urlencoded\n if (contentType.includes('application/x-www-form-urlencoded')) {\n const text = await this.text();\n const formData = new FormData();\n const params = new URLSearchParams(text);\n for (const [key, value] of params) {\n formData.append(key, value);\n }\n return formData;\n }\n\n throw new TypeError('Unsupported content type for formData()');\n }\n\n clone() {\n if (this.bodyUsed) {\n throw new TypeError('Cannot clone a Response that has already been used');\n }\n const newId = __Response_clone(this.#instanceId);\n const cloned = Response._fromInstanceId(newId);\n return cloned;\n }\n\n static json(data, init = {}) {\n const body = JSON.stringify(data);\n const headers = new Headers(init.headers);\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/json');\n }\n return new Response(body, { ...init, headers });\n }\n\n static redirect(url, status = 302) {\n if (![301, 302, 303, 307, 308].includes(status)) {\n throw new RangeError('Invalid redirect status code');\n }\n const headers = new Headers({ Location: String(url) });\n return new Response(null, { status, headers });\n }\n\n static error() {\n const response = new Response(null, { status: 0, statusText: '' });\n __Response_setType(response._getInstanceId(), 'error');\n return response;\n }\n }\n\n globalThis.Response = Response;\n})();\n`;\n\n context.evalSync(responseCode);\n}\n\n// ============================================================================\n// Request Implementation (Host State + Isolate Class)\n// ============================================================================\n\nfunction setupRequest(\n context: ivm.Context,\n stateMap: Map<number, unknown>\n): void {\n const global = context.global;\n\n // Register host callbacks\n global.setSync(\n \"__Request_construct\",\n new ivm.Callback(\n (\n url: string,\n method: string,\n headers: [string, string][],\n bodyBytes: number[] | null,\n mode: string,\n credentials: string,\n cache: string,\n redirect: string,\n referrer: string,\n integrity: string\n ) => {\n const instanceId = nextInstanceId++;\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const state: RequestState = {\n url,\n method,\n headers,\n body,\n bodyUsed: false,\n streamId: null,\n mode,\n credentials,\n cache,\n redirect,\n referrer,\n integrity,\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n global.setSync(\n \"__Request_get_method\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.method ?? \"GET\";\n })\n );\n\n global.setSync(\n \"__Request_get_url\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.url ?? \"\";\n })\n );\n\n global.setSync(\n \"__Request_get_headers\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.headers ?? [];\n })\n );\n\n global.setSync(\n \"__Request_get_bodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.bodyUsed ?? false;\n })\n );\n\n global.setSync(\n \"__Request_get_mode\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.mode ?? \"cors\";\n })\n );\n\n global.setSync(\n \"__Request_get_credentials\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.credentials ?? \"same-origin\";\n })\n );\n\n global.setSync(\n \"__Request_get_cache\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.cache ?? \"default\";\n })\n );\n\n global.setSync(\n \"__Request_get_redirect\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.redirect ?? \"follow\";\n })\n );\n\n global.setSync(\n \"__Request_get_referrer\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.referrer ?? \"about:client\";\n })\n );\n\n global.setSync(\n \"__Request_get_integrity\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.integrity ?? \"\";\n })\n );\n\n global.setSync(\n \"__Request_markBodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (state) {\n if (state.bodyUsed) {\n throw new Error(\"[TypeError]Body has already been consumed\");\n }\n state.bodyUsed = true;\n }\n })\n );\n\n global.setSync(\n \"__Request_text\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state || !state.body) return \"\";\n return new TextDecoder().decode(state.body);\n })\n );\n\n global.setSync(\n \"__Request_arrayBuffer\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state || !state.body) {\n return new ivm.ExternalCopy(new ArrayBuffer(0)).copyInto();\n }\n return new ivm.ExternalCopy(state.body.buffer.slice(\n state.body.byteOffset,\n state.body.byteOffset + state.body.byteLength\n )).copyInto();\n })\n );\n\n global.setSync(\n \"__Request_getBodyBytes\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state || !state.body) return null;\n return Array.from(state.body);\n })\n );\n\n global.setSync(\n \"__Request_clone\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state) {\n throw new Error(\"[TypeError]Cannot clone invalid Request\");\n }\n const newId = nextInstanceId++;\n const newState: RequestState = {\n ...state,\n body: state.body ? new Uint8Array(state.body) : null,\n bodyUsed: false,\n };\n stateMap.set(newId, newState);\n return newId;\n })\n );\n\n global.setSync(\n \"__Request_getStreamId\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.streamId ?? null;\n })\n );\n\n // Inject Request class\n const requestCode = `\n(function() {\n function __decodeError(err) {\n if (!(err instanceof Error)) return err;\n const match = err.message.match(/^\\\\[(TypeError|RangeError|SyntaxError|ReferenceError|URIError|EvalError|Error)\\\\](.*)$/);\n if (match) {\n const ErrorType = globalThis[match[1]] || Error;\n return new ErrorType(match[2]);\n }\n return err;\n }\n\n function __prepareBody(body) {\n if (body === null || body === undefined) return null;\n if (typeof body === 'string') {\n const encoder = new TextEncoder();\n return Array.from(encoder.encode(body));\n }\n if (body instanceof ArrayBuffer) {\n return Array.from(new Uint8Array(body));\n }\n if (body instanceof Uint8Array) {\n return Array.from(body);\n }\n if (ArrayBuffer.isView(body)) {\n return Array.from(new Uint8Array(body.buffer, body.byteOffset, body.byteLength));\n }\n if (body instanceof URLSearchParams) {\n return Array.from(new TextEncoder().encode(body.toString()));\n }\n if (body instanceof FormData) {\n // Check if FormData has any File/Blob entries\n let hasFiles = false;\n for (const [, value] of body.entries()) {\n if (value instanceof File || value instanceof Blob) {\n hasFiles = true;\n break;\n }\n }\n\n if (hasFiles) {\n // Serialize as multipart/form-data\n const { body: bytes, contentType } = __serializeFormData(body);\n globalThis.__pendingFormDataContentType = contentType;\n return Array.from(bytes);\n }\n\n // URL-encoded for string-only FormData\n const parts = [];\n body.forEach((value, key) => {\n if (typeof value === 'string') {\n parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));\n }\n });\n return Array.from(new TextEncoder().encode(parts.join('&')));\n }\n // Try to convert to string\n return Array.from(new TextEncoder().encode(String(body)));\n }\n\n // Helper to consume a HostBackedReadableStream and concatenate all chunks\n async function __consumeStream(stream) {\n const reader = stream.getReader();\n const chunks = [];\n let totalLength = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n totalLength += value.length;\n }\n\n // Concatenate all chunks\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n return result;\n }\n\n class Request {\n #instanceId;\n #headers;\n #signal;\n #streamId;\n #cachedBody = null;\n\n constructor(input, init = {}) {\n // Handle internal construction from instance ID\n if (typeof input === 'number' && init === null) {\n this.#instanceId = input;\n this.#headers = new Headers(__Request_get_headers(input));\n this.#signal = null;\n this.#streamId = __Request_getStreamId(input);\n return;\n }\n\n let url;\n let method = 'GET';\n let headers;\n let body = null;\n let signal = null;\n let mode = 'cors';\n let credentials = 'same-origin';\n let cache = 'default';\n let redirect = 'follow';\n let referrer = 'about:client';\n let integrity = '';\n\n if (input instanceof Request) {\n url = input.url;\n method = input.method;\n headers = new Headers(input.headers);\n signal = input.signal;\n mode = input.mode;\n credentials = input.credentials;\n cache = input.cache;\n redirect = input.redirect;\n referrer = input.referrer;\n integrity = input.integrity;\n // Note: We don't copy the body from the input Request\n } else {\n url = String(input);\n headers = new Headers();\n }\n\n // Apply init overrides\n if (init.method !== undefined) method = String(init.method).toUpperCase();\n if (init.headers !== undefined) headers = new Headers(init.headers);\n if (init.body !== undefined) body = init.body;\n if (init.signal !== undefined) signal = init.signal;\n if (init.mode !== undefined) mode = init.mode;\n if (init.credentials !== undefined) credentials = init.credentials;\n if (init.cache !== undefined) cache = init.cache;\n if (init.redirect !== undefined) redirect = init.redirect;\n if (init.referrer !== undefined) referrer = init.referrer;\n if (init.integrity !== undefined) integrity = init.integrity;\n\n // Validate: body with GET/HEAD\n if (body !== null && (method === 'GET' || method === 'HEAD')) {\n throw new TypeError('Request with GET/HEAD method cannot have body');\n }\n\n const bodyBytes = __prepareBody(body);\n\n // Handle Content-Type for FormData\n if (globalThis.__pendingFormDataContentType) {\n headers.set('content-type', globalThis.__pendingFormDataContentType);\n delete globalThis.__pendingFormDataContentType;\n } else if (body instanceof FormData && !headers.has('content-type')) {\n headers.set('content-type', 'application/x-www-form-urlencoded');\n }\n\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Request_construct(\n url, method, headersArray, bodyBytes,\n mode, credentials, cache, redirect, referrer, integrity\n );\n this.#headers = headers;\n this.#signal = signal;\n this.#streamId = null;\n }\n\n _getInstanceId() {\n return this.#instanceId;\n }\n\n static _fromInstanceId(instanceId) {\n return new Request(instanceId, null);\n }\n\n get method() {\n return __Request_get_method(this.#instanceId);\n }\n\n get url() {\n return __Request_get_url(this.#instanceId);\n }\n\n get headers() {\n return this.#headers;\n }\n\n get bodyUsed() {\n return __Request_get_bodyUsed(this.#instanceId);\n }\n\n get signal() {\n return this.#signal;\n }\n\n get mode() {\n return __Request_get_mode(this.#instanceId);\n }\n\n get credentials() {\n return __Request_get_credentials(this.#instanceId);\n }\n\n get cache() {\n return __Request_get_cache(this.#instanceId);\n }\n\n get redirect() {\n return __Request_get_redirect(this.#instanceId);\n }\n\n get referrer() {\n return __Request_get_referrer(this.#instanceId);\n }\n\n get integrity() {\n return __Request_get_integrity(this.#instanceId);\n }\n\n get body() {\n // Return cached body if available\n if (this.#cachedBody !== null) {\n return this.#cachedBody;\n }\n\n // If we have a stream ID, create and cache the stream\n if (this.#streamId !== null) {\n this.#cachedBody = HostBackedReadableStream._fromStreamId(this.#streamId);\n return this.#cachedBody;\n }\n\n // Create stream from buffered body\n const newStreamId = __Stream_create();\n const buffer = __Request_arrayBuffer(this.#instanceId);\n if (buffer.byteLength > 0) {\n __Stream_push(newStreamId, Array.from(new Uint8Array(buffer)));\n }\n __Stream_close(newStreamId);\n\n this.#cachedBody = HostBackedReadableStream._fromStreamId(newStreamId);\n return this.#cachedBody;\n }\n\n async text() {\n try {\n __Request_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n\n // If streaming, consume the stream\n if (this.#streamId !== null) {\n const bytes = await __consumeStream(this.body);\n return new TextDecoder().decode(bytes);\n }\n\n // Fallback to host callback for buffered body\n return __Request_text(this.#instanceId);\n }\n\n async json() {\n const text = await this.text();\n return JSON.parse(text);\n }\n\n async arrayBuffer() {\n try {\n __Request_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n\n // If streaming, consume the stream\n if (this.#streamId !== null) {\n const bytes = await __consumeStream(this.body);\n return bytes.buffer;\n }\n\n return __Request_arrayBuffer(this.#instanceId);\n }\n\n async blob() {\n const buffer = await this.arrayBuffer();\n const contentType = this.headers.get('content-type') || '';\n return new Blob([buffer], { type: contentType });\n }\n\n async formData() {\n const contentType = this.headers.get('content-type') || '';\n\n // Parse multipart/form-data\n if (contentType.includes('multipart/form-data')) {\n const buffer = await this.arrayBuffer();\n return __parseMultipartFormData(new Uint8Array(buffer), contentType);\n }\n\n // Parse application/x-www-form-urlencoded\n if (contentType.includes('application/x-www-form-urlencoded')) {\n const text = await this.text();\n const formData = new FormData();\n const params = new URLSearchParams(text);\n for (const [key, value] of params) {\n formData.append(key, value);\n }\n return formData;\n }\n\n throw new TypeError('Unsupported content type for formData()');\n }\n\n clone() {\n if (this.bodyUsed) {\n throw new TypeError('Cannot clone a Request that has already been used');\n }\n const newId = __Request_clone(this.#instanceId);\n const cloned = Request._fromInstanceId(newId);\n cloned.#signal = this.#signal;\n return cloned;\n }\n\n _getBodyBytes() {\n return __Request_getBodyBytes(this.#instanceId);\n }\n }\n\n globalThis.Request = Request;\n})();\n`;\n\n context.evalSync(requestCode);\n}\n\n// ============================================================================\n// fetch Implementation\n// ============================================================================\n\nfunction setupFetchFunction(\n context: ivm.Context,\n stateMap: Map<number, unknown>,\n options?: FetchOptions\n): void {\n const global = context.global;\n\n // Create async fetch reference\n // We use JSON serialization for complex data to avoid transfer issues\n const fetchRef = new ivm.Reference(\n async (\n url: string,\n method: string,\n headersJson: string,\n bodyJson: string | null,\n signalAborted: boolean\n ) => {\n // Check if already aborted\n if (signalAborted) {\n throw new Error(\"[AbortError]The operation was aborted.\");\n }\n\n // Parse headers and body from JSON\n const headers = JSON.parse(headersJson) as [string, string][];\n const bodyBytes = bodyJson ? JSON.parse(bodyJson) as number[] : null;\n\n // Construct native Request\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const nativeRequest = new Request(url, {\n method,\n headers,\n body,\n });\n\n // Call user's onFetch handler or default fetch\n const onFetch = options?.onFetch ?? fetch;\n const nativeResponse = await onFetch(nativeRequest);\n\n // Read response body\n const responseBody = await nativeResponse.arrayBuffer();\n const responseBodyArray = Array.from(new Uint8Array(responseBody));\n\n // Store the response in the state map and return just the ID + metadata\n const instanceId = nextInstanceId++;\n const state: ResponseState = {\n status: nativeResponse.status,\n statusText: nativeResponse.statusText,\n headers: Array.from(nativeResponse.headers.entries()),\n body: new Uint8Array(responseBodyArray),\n bodyUsed: false,\n type: \"default\",\n url: nativeResponse.url,\n redirected: nativeResponse.redirected,\n streamId: null,\n };\n stateMap.set(instanceId, state);\n\n // Return only the instance ID - avoid complex object transfer\n return instanceId;\n }\n );\n\n global.setSync(\"__fetch_ref\", fetchRef);\n\n // Inject fetch function\n const fetchCode = `\n(function() {\n function __decodeError(err) {\n if (!(err instanceof Error)) return err;\n const match = err.message.match(/^\\\\[(TypeError|RangeError|AbortError|Error)\\\\](.*)$/);\n if (match) {\n if (match[1] === 'AbortError') {\n return new DOMException(match[2], 'AbortError');\n }\n const ErrorType = globalThis[match[1]] || Error;\n return new ErrorType(match[2]);\n }\n return err;\n }\n\n globalThis.fetch = function(input, init = {}) {\n // Create Request from input\n const request = input instanceof Request ? input : new Request(input, init);\n\n // Get signal info\n const signal = init.signal ?? request.signal;\n const signalAborted = signal?.aborted ?? false;\n\n // Serialize headers and body to JSON for transfer\n const headersJson = JSON.stringify(Array.from(request.headers.entries()));\n const bodyBytes = request._getBodyBytes();\n const bodyJson = bodyBytes ? JSON.stringify(bodyBytes) : null;\n\n // Call host - returns just the response instance ID\n try {\n const instanceId = __fetch_ref.applySyncPromise(undefined, [\n request.url,\n request.method,\n headersJson,\n bodyJson,\n signalAborted\n ]);\n\n // Construct Response from the instance ID\n return Response._fromInstanceId(instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n };\n})();\n`;\n\n context.evalSync(fetchCode);\n}\n\n// ============================================================================\n// Server Implementation (for serve())\n// ============================================================================\n\nfunction setupServer(\n context: ivm.Context,\n serveState: ServeState\n): void {\n const global = context.global;\n\n // Setup upgrade registry in isolate (data stays in isolate, never marshalled to host)\n context.evalSync(`\n globalThis.__upgradeRegistry__ = new Map();\n globalThis.__upgradeIdCounter__ = 0;\n `);\n\n // Host callback to notify about pending upgrade\n global.setSync(\n \"__setPendingUpgrade__\",\n new ivm.Callback((connectionId: string) => {\n serveState.pendingUpgrade = { requested: true, connectionId };\n })\n );\n\n // Pure JS Server class with upgrade method\n context.evalSync(`\n(function() {\n class Server {\n upgrade(request, options) {\n const data = options?.data;\n const connectionId = String(++globalThis.__upgradeIdCounter__);\n globalThis.__upgradeRegistry__.set(connectionId, data);\n __setPendingUpgrade__(connectionId);\n return true;\n }\n }\n globalThis.__Server__ = Server;\n})();\n `);\n}\n\n// ============================================================================\n// ServerWebSocket Implementation (for serve())\n// ============================================================================\n\nfunction setupServerWebSocket(\n context: ivm.Context,\n wsCommandCallbacks: Set<(cmd: WebSocketCommand) => void>\n): void {\n const global = context.global;\n\n // Host callback for ws.send()\n global.setSync(\n \"__ServerWebSocket_send\",\n new ivm.Callback((connectionId: string, data: string) => {\n const cmd: WebSocketCommand = { type: \"message\", connectionId, data };\n for (const cb of wsCommandCallbacks) cb(cmd);\n })\n );\n\n // Host callback for ws.close()\n global.setSync(\n \"__ServerWebSocket_close\",\n new ivm.Callback((connectionId: string, code?: number, reason?: string) => {\n const cmd: WebSocketCommand = { type: \"close\", connectionId, code, reason };\n for (const cb of wsCommandCallbacks) cb(cmd);\n })\n );\n\n // Pure JS ServerWebSocket class\n context.evalSync(`\n(function() {\n const _wsInstanceData = new WeakMap();\n\n class ServerWebSocket {\n constructor(connectionId) {\n _wsInstanceData.set(this, { connectionId, readyState: 1 });\n }\n\n get data() {\n const state = _wsInstanceData.get(this);\n return globalThis.__upgradeRegistry__.get(state.connectionId);\n }\n\n get readyState() {\n return _wsInstanceData.get(this).readyState;\n }\n\n send(message) {\n const state = _wsInstanceData.get(this);\n if (state.readyState !== 1) throw new Error(\"WebSocket is not open\");\n // Convert ArrayBuffer/Uint8Array to string for transfer\n let data = message;\n if (message instanceof ArrayBuffer) {\n data = new TextDecoder().decode(message);\n } else if (message instanceof Uint8Array) {\n data = new TextDecoder().decode(message);\n }\n __ServerWebSocket_send(state.connectionId, data);\n }\n\n close(code, reason) {\n const state = _wsInstanceData.get(this);\n if (state.readyState === 3) return;\n state.readyState = 2; // CLOSING\n __ServerWebSocket_close(state.connectionId, code, reason);\n }\n\n _setReadyState(readyState) {\n _wsInstanceData.get(this).readyState = readyState;\n }\n }\n\n globalThis.__ServerWebSocket__ = ServerWebSocket;\n})();\n `);\n}\n\n// ============================================================================\n// serve() Function Implementation\n// ============================================================================\n\nfunction setupServe(context: ivm.Context): void {\n // Pure JS serve() that stores options on __serveOptions__ global\n context.evalSync(`\n(function() {\n globalThis.__serveOptions__ = null;\n\n function serve(options) {\n globalThis.__serveOptions__ = options;\n }\n\n globalThis.serve = serve;\n})();\n `);\n}\n\n// ============================================================================\n// Main Setup Function\n// ============================================================================\n\n/**\n * Setup Fetch API in an isolated-vm context\n *\n * Injects fetch, Request, Response, Headers, FormData\n * Also sets up core APIs (Blob, File, AbortController, etc.) if not already present\n *\n * @example\n * const handle = await setupFetch(context, {\n * onFetch: async (request) => {\n * // Proxy fetch requests to the host\n * return fetch(request);\n * }\n * });\n *\n * await context.eval(`\n * const response = await fetch(\"https://example.com\");\n * const text = await response.text();\n * `);\n */\nexport async function setupFetch(\n context: ivm.Context,\n options?: FetchOptions\n): Promise<FetchHandle> {\n // Setup core APIs first (Blob, File, AbortController, Streams, etc.)\n await setupCore(context);\n\n const stateMap = getInstanceStateMapForContext(context);\n const streamRegistry = getStreamRegistryForContext(context);\n\n // Inject Headers (pure JS)\n context.evalSync(headersCode);\n\n // Inject FormData (pure JS)\n context.evalSync(formDataCode);\n\n // Inject multipart parsing/serialization (pure JS)\n context.evalSync(multipartCode);\n\n // Setup stream callbacks and inject HostBackedReadableStream\n setupStreamCallbacks(context, streamRegistry);\n context.evalSync(hostBackedStreamCode);\n\n // Setup Response (host state + isolate class)\n setupResponse(context, stateMap);\n\n // Setup Request (host state + isolate class)\n setupRequest(context, stateMap);\n\n // Setup fetch function\n setupFetchFunction(context, stateMap, options);\n\n // Setup serve state\n const serveState: ServeState = {\n pendingUpgrade: null,\n activeConnections: new Map(),\n };\n\n // Setup WebSocket command callbacks\n const wsCommandCallbacks = new Set<(cmd: WebSocketCommand) => void>();\n\n // Setup Server class\n setupServer(context, serveState);\n\n // Setup ServerWebSocket class\n setupServerWebSocket(context, wsCommandCallbacks);\n\n // Setup serve function\n setupServe(context);\n\n return {\n dispose() {\n // Clear state for this context\n stateMap.clear();\n // Clear upgrade registry\n context.evalSync(`globalThis.__upgradeRegistry__.clear()`);\n // Clear serve state\n serveState.activeConnections.clear();\n serveState.pendingUpgrade = null;\n },\n\n async dispatchRequest(\n request: Request,\n _dispatchOptions?: DispatchRequestOptions\n ): Promise<Response> {\n // Clean up previous pending upgrade if not consumed\n if (serveState.pendingUpgrade) {\n const oldConnectionId = serveState.pendingUpgrade.connectionId;\n context.evalSync(`globalThis.__upgradeRegistry__.delete(\"${oldConnectionId}\")`);\n serveState.pendingUpgrade = null;\n }\n\n // Check if serve handler exists\n const hasHandler = context.evalSync(`!!globalThis.__serveOptions__?.fetch`);\n if (!hasHandler) {\n throw new Error(\"No serve() handler registered\");\n }\n\n // Setup streaming for request body\n let requestStreamId: number | null = null;\n let streamCleanup: (() => Promise<void>) | null = null;\n\n if (request.body) {\n // Create a stream in the registry for the request body\n requestStreamId = streamRegistry.create();\n\n // Start background reader that pushes from native stream to host queue\n streamCleanup = startNativeStreamReader(\n request.body,\n requestStreamId,\n streamRegistry\n );\n }\n\n try {\n const headersArray = Array.from(request.headers.entries());\n\n // Create Request instance in isolate\n const requestInstanceId = nextInstanceId++;\n const requestState: RequestState = {\n url: request.url,\n method: request.method,\n headers: headersArray,\n body: null, // No buffered body - using stream\n bodyUsed: false,\n streamId: requestStreamId,\n mode: request.mode,\n credentials: request.credentials,\n cache: request.cache,\n redirect: request.redirect,\n referrer: request.referrer,\n integrity: request.integrity,\n };\n stateMap.set(requestInstanceId, requestState);\n\n // Call the fetch handler and get response\n // We use eval with promise: true to handle async handlers\n const responseInstanceId = await context.eval(`\n (async function() {\n const request = Request._fromInstanceId(${requestInstanceId});\n const server = new __Server__();\n const response = await Promise.resolve(__serveOptions__.fetch(request, server));\n return response._getInstanceId();\n })()\n `, { promise: true });\n\n // Get ResponseState from the instance\n const responseState = stateMap.get(responseInstanceId) as ResponseState | undefined;\n if (!responseState) {\n throw new Error(\"Response state not found\");\n }\n\n // Check if response has streaming body\n if (responseState.streamId !== null) {\n const responseStreamId = responseState.streamId;\n let streamDone = false;\n\n // Create native stream that waits for data from isolate\n const pumpedStream = new ReadableStream<Uint8Array>({\n async pull(controller) {\n if (streamDone) return;\n\n // Wait for data to be available\n while (!streamDone) {\n // Check if data is available\n const state = streamRegistry.get(responseStreamId);\n if (!state) {\n controller.close();\n streamDone = true;\n return;\n }\n\n // If queue has data or stream is done, break and pull\n if (state.queue.length > 0 || state.closed || state.errored) {\n break;\n }\n\n // Small delay to avoid busy-waiting\n await new Promise((r) => setTimeout(r, 1));\n }\n\n try {\n const result = await streamRegistry.pull(responseStreamId);\n if (result.done) {\n controller.close();\n streamDone = true;\n streamRegistry.delete(responseStreamId);\n return;\n }\n controller.enqueue(result.value);\n } catch (error) {\n controller.error(error);\n streamDone = true;\n streamRegistry.delete(responseStreamId);\n }\n },\n cancel() {\n streamDone = true;\n streamRegistry.error(\n responseStreamId,\n new Error(\"Stream cancelled\")\n );\n streamRegistry.delete(responseStreamId);\n },\n });\n\n const responseHeaders = new Headers(responseState.headers);\n const status =\n responseState.status === 101 ? 200 : responseState.status;\n const response = new Response(pumpedStream, {\n status,\n statusText: responseState.statusText,\n headers: responseHeaders,\n });\n\n // @ts-expect-error - adding custom property\n response._originalStatus = responseState.status;\n\n return response;\n }\n\n // Convert to native Response (non-streaming)\n const responseHeaders = new Headers(responseState.headers);\n const responseBody = responseState.body;\n\n // Note: Status 101 (Switching Protocols) is not valid for Response constructor\n // We use 200 as the status but preserve the actual status in a custom header\n // The caller should check getUpgradeRequest() for WebSocket upgrades\n const status = responseState.status === 101 ? 200 : responseState.status;\n const response = new Response(responseBody as ConstructorParameters<typeof Response>[0], {\n status,\n statusText: responseState.statusText,\n headers: responseHeaders,\n });\n\n // Expose the original status via a property for callers to check\n // @ts-expect-error - adding custom property\n response._originalStatus = responseState.status;\n\n return response;\n } finally {\n // Cleanup: cancel stream reader if still running\n if (streamCleanup) {\n await streamCleanup();\n }\n // Delete stream from registry\n if (requestStreamId !== null) {\n streamRegistry.delete(requestStreamId);\n }\n }\n },\n\n getUpgradeRequest(): UpgradeRequest | null {\n const result = serveState.pendingUpgrade;\n // Don't clear yet - it will be cleared on next dispatchRequest or consumed by dispatchWebSocketOpen\n return result;\n },\n\n dispatchWebSocketOpen(connectionId: string): void {\n // Store connection (data stays in isolate registry)\n serveState.activeConnections.set(connectionId, { connectionId });\n\n // Check if websocket.open handler exists\n const hasOpenHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.open`);\n\n // Create ServerWebSocket instance (always needed for message/close handlers)\n context.evalSync(`\n (function() {\n const ws = new __ServerWebSocket__(\"${connectionId}\");\n globalThis.__activeWs_${connectionId}__ = ws;\n })()\n `);\n\n // Call open handler if it exists\n if (hasOpenHandler) {\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n __serveOptions__.websocket.open(ws);\n })()\n `);\n }\n\n // Clear pending upgrade after successful open\n if (serveState.pendingUpgrade?.connectionId === connectionId) {\n serveState.pendingUpgrade = null;\n }\n },\n\n dispatchWebSocketMessage(connectionId: string, message: string | ArrayBuffer): void {\n // Check if connection is tracked\n if (!serveState.activeConnections.has(connectionId)) {\n return; // Silently ignore for unknown connections\n }\n\n // Check if message handler exists\n const hasMessageHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.message`);\n if (!hasMessageHandler) {\n return;\n }\n\n // Marshal message and call handler\n if (typeof message === \"string\") {\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) __serveOptions__.websocket.message(ws, \"${message.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\")}\");\n })()\n `);\n } else {\n // ArrayBuffer - convert to base64 or pass as array\n const bytes = Array.from(new Uint8Array(message));\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) {\n const bytes = new Uint8Array([${bytes.join(\",\")}]);\n __serveOptions__.websocket.message(ws, bytes.buffer);\n }\n })()\n `);\n }\n },\n\n dispatchWebSocketClose(connectionId: string, code: number, reason: string): void {\n // Check if connection is tracked\n if (!serveState.activeConnections.has(connectionId)) {\n return;\n }\n\n // Update readyState to CLOSED\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) ws._setReadyState(3);\n })()\n `);\n\n // Check if close handler exists\n const hasCloseHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.close`);\n if (hasCloseHandler) {\n const safeReason = reason.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) __serveOptions__.websocket.close(ws, ${code}, \"${safeReason}\");\n })()\n `);\n }\n\n // Cleanup\n context.evalSync(`\n delete globalThis.__activeWs_${connectionId}__;\n globalThis.__upgradeRegistry__.delete(\"${connectionId}\");\n `);\n serveState.activeConnections.delete(connectionId);\n },\n\n dispatchWebSocketError(connectionId: string, error: Error): void {\n // Check if connection is tracked\n if (!serveState.activeConnections.has(connectionId)) {\n return;\n }\n\n // Check if error handler exists\n const hasErrorHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.error`);\n if (!hasErrorHandler) {\n return;\n }\n\n const safeName = error.name.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n const safeMessage = error.message.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) {\n const error = { name: \"${safeName}\", message: \"${safeMessage}\" };\n __serveOptions__.websocket.error(ws, error);\n }\n })()\n `);\n },\n\n onWebSocketCommand(callback: (cmd: WebSocketCommand) => void): () => void {\n wsCommandCallbacks.add(callback);\n return () => wsCommandCallbacks.delete(callback);\n },\n\n hasServeHandler(): boolean {\n return context.evalSync(`!!globalThis.__serveOptions__?.fetch`) as boolean;\n },\n\n hasActiveConnections(): boolean {\n return serveState.activeConnections.size > 0;\n },\n };\n}\n"
|
|
5
|
+
"import ivm from \"isolated-vm\";\nimport { setupCore, clearAllInstanceState } from \"@ricsam/isolate-core\";\nimport {\n getStreamRegistryForContext,\n startNativeStreamReader,\n} from \"./stream-state.mjs\";\nimport type { StreamStateRegistry } from \"./stream-state.mjs\";\n\nexport { clearAllInstanceState };\n\nexport interface FetchOptions {\n /** Handler for fetch requests from the isolate */\n onFetch?: (request: Request) => Promise<Response>;\n}\n\n// ============================================================================\n// Serve Types\n// ============================================================================\n\nexport interface UpgradeRequest {\n requested: true;\n connectionId: string;\n}\n\nexport interface WebSocketCommand {\n type: \"message\" | \"close\";\n connectionId: string;\n data?: string | ArrayBuffer;\n code?: number;\n reason?: string;\n}\n\ninterface ServeState {\n pendingUpgrade: UpgradeRequest | null;\n activeConnections: Map<string, { connectionId: string }>;\n}\n\nexport interface DispatchRequestOptions {\n // Reserved for future options\n}\n\nexport interface FetchHandle {\n dispose(): void;\n /** Dispatch an HTTP request to the isolate's serve() handler */\n dispatchRequest(request: Request, options?: DispatchRequestOptions): Promise<Response>;\n /** Check if isolate requested WebSocket upgrade */\n getUpgradeRequest(): UpgradeRequest | null;\n /** Dispatch WebSocket open event to isolate */\n dispatchWebSocketOpen(connectionId: string): void;\n /** Dispatch WebSocket message event to isolate */\n dispatchWebSocketMessage(connectionId: string, message: string | ArrayBuffer): void;\n /** Dispatch WebSocket close event to isolate */\n dispatchWebSocketClose(connectionId: string, code: number, reason: string): void;\n /** Dispatch WebSocket error event to isolate */\n dispatchWebSocketError(connectionId: string, error: Error): void;\n /** Register callback for WebSocket commands from isolate */\n onWebSocketCommand(callback: (cmd: WebSocketCommand) => void): () => void;\n /** Check if serve() has been called */\n hasServeHandler(): boolean;\n /** Check if there are active WebSocket connections */\n hasActiveConnections(): boolean;\n}\n\n// ============================================================================\n// Instance State Management\n// ============================================================================\n\nconst instanceStateMap = new WeakMap<ivm.Context, Map<number, unknown>>();\nlet nextInstanceId = 1;\n\nfunction getInstanceStateMapForContext(\n context: ivm.Context\n): Map<number, unknown> {\n let map = instanceStateMap.get(context);\n if (!map) {\n map = new Map();\n instanceStateMap.set(context, map);\n }\n return map;\n}\n\n// ============================================================================\n// State Types\n// ============================================================================\n\ninterface ResponseState {\n status: number;\n statusText: string;\n headers: [string, string][];\n body: Uint8Array | null;\n bodyUsed: boolean;\n type: string;\n url: string;\n redirected: boolean;\n streamId: number | null;\n}\n\ninterface RequestState {\n method: string;\n url: string;\n headers: [string, string][];\n body: Uint8Array | null;\n bodyUsed: boolean;\n streamId: number | null;\n mode: string;\n credentials: string;\n cache: string;\n redirect: string;\n referrer: string;\n integrity: string;\n}\n\n// ============================================================================\n// Headers Implementation (Pure JS)\n// ============================================================================\n\nconst headersCode = `\n(function() {\n class Headers {\n #headers = new Map(); // lowercase key -> [originalCase, values[]]\n\n constructor(init) {\n if (init instanceof Headers) {\n init.forEach((value, key) => this.append(key, value));\n } else if (Array.isArray(init)) {\n for (const pair of init) {\n if (Array.isArray(pair) && pair.length >= 2) {\n this.append(pair[0], pair[1]);\n }\n }\n } else if (init && typeof init === 'object') {\n for (const [key, value] of Object.entries(init)) {\n this.append(key, value);\n }\n }\n }\n\n append(name, value) {\n const key = String(name).toLowerCase();\n const valueStr = String(value);\n const existing = this.#headers.get(key);\n if (existing) {\n existing[1].push(valueStr);\n } else {\n this.#headers.set(key, [String(name), [valueStr]]);\n }\n }\n\n delete(name) {\n this.#headers.delete(String(name).toLowerCase());\n }\n\n get(name) {\n const entry = this.#headers.get(String(name).toLowerCase());\n return entry ? entry[1].join(', ') : null;\n }\n\n getSetCookie() {\n const entry = this.#headers.get('set-cookie');\n return entry ? [...entry[1]] : [];\n }\n\n has(name) {\n return this.#headers.has(String(name).toLowerCase());\n }\n\n set(name, value) {\n const key = String(name).toLowerCase();\n this.#headers.set(key, [String(name), [String(value)]]);\n }\n\n forEach(callback, thisArg) {\n for (const [key, [originalName, values]] of this.#headers) {\n callback.call(thisArg, values.join(', '), originalName, this);\n }\n }\n\n *entries() {\n for (const [key, [name, values]] of this.#headers) {\n yield [name, values.join(', ')];\n }\n }\n\n *keys() {\n for (const [key, [name]] of this.#headers) {\n yield name;\n }\n }\n\n *values() {\n for (const [key, [name, values]] of this.#headers) {\n yield values.join(', ');\n }\n }\n\n [Symbol.iterator]() {\n return this.entries();\n }\n }\n\n globalThis.Headers = Headers;\n})();\n`;\n\n// ============================================================================\n// FormData Implementation (Pure JS)\n// ============================================================================\n\nconst formDataCode = `\n(function() {\n class FormData {\n #entries = []; // Array of [name, value]\n\n append(name, value, filename) {\n let finalValue = value;\n if (value instanceof Blob && !(value instanceof File)) {\n if (filename !== undefined) {\n finalValue = new File([value], String(filename), { type: value.type });\n }\n } else if (value instanceof File && filename !== undefined) {\n finalValue = new File([value], String(filename), {\n type: value.type,\n lastModified: value.lastModified\n });\n }\n this.#entries.push([String(name), finalValue]);\n }\n\n delete(name) {\n const nameStr = String(name);\n this.#entries = this.#entries.filter(([n]) => n !== nameStr);\n }\n\n get(name) {\n const nameStr = String(name);\n const entry = this.#entries.find(([n]) => n === nameStr);\n return entry ? entry[1] : null;\n }\n\n getAll(name) {\n const nameStr = String(name);\n return this.#entries.filter(([n]) => n === nameStr).map(([, v]) => v);\n }\n\n has(name) {\n return this.#entries.some(([n]) => n === String(name));\n }\n\n set(name, value, filename) {\n const nameStr = String(name);\n this.delete(nameStr);\n this.append(nameStr, value, filename);\n }\n\n *entries() {\n for (const [name, value] of this.#entries) {\n yield [name, value];\n }\n }\n\n *keys() {\n for (const [name] of this.#entries) {\n yield name;\n }\n }\n\n *values() {\n for (const [, value] of this.#entries) {\n yield value;\n }\n }\n\n forEach(callback, thisArg) {\n for (const [name, value] of this.#entries) {\n callback.call(thisArg, value, name, this);\n }\n }\n\n [Symbol.iterator]() {\n return this.entries();\n }\n }\n\n globalThis.FormData = FormData;\n})();\n`;\n\n// ============================================================================\n// Multipart FormData Parsing/Serialization (Pure JS)\n// ============================================================================\n\nconst multipartCode = `\n(function() {\n // Find byte sequence in Uint8Array\n function findSequence(haystack, needle, start = 0) {\n outer: for (let i = start; i <= haystack.length - needle.length; i++) {\n for (let j = 0; j < needle.length; j++) {\n if (haystack[i + j] !== needle[j]) continue outer;\n }\n return i;\n }\n return -1;\n }\n\n // Parse header lines into object\n function parseHeaders(text) {\n const headers = {};\n for (const line of text.split(/\\\\r?\\\\n/)) {\n const colonIdx = line.indexOf(':');\n if (colonIdx > 0) {\n const name = line.slice(0, colonIdx).trim().toLowerCase();\n const value = line.slice(colonIdx + 1).trim();\n headers[name] = value;\n }\n }\n return headers;\n }\n\n // Parse multipart/form-data body into FormData\n globalThis.__parseMultipartFormData = function(bodyBytes, contentType) {\n const formData = new FormData();\n\n // Extract boundary from Content-Type\n const boundaryMatch = contentType.match(/boundary=([^;]+)/i);\n if (!boundaryMatch) return formData;\n\n const boundary = boundaryMatch[1].replace(/^[\"']|[\"']$/g, '');\n const encoder = new TextEncoder();\n const decoder = new TextDecoder();\n const boundaryBytes = encoder.encode('--' + boundary);\n\n // Find first boundary\n let pos = findSequence(bodyBytes, boundaryBytes, 0);\n if (pos === -1) return formData;\n pos += boundaryBytes.length;\n\n while (pos < bodyBytes.length) {\n // Skip CRLF after boundary\n if (bodyBytes[pos] === 0x0d && bodyBytes[pos + 1] === 0x0a) pos += 2;\n else if (bodyBytes[pos] === 0x0a) pos += 1;\n\n // Check for closing boundary (--)\n if (bodyBytes[pos] === 0x2d && bodyBytes[pos + 1] === 0x2d) break;\n\n // Find header/body separator (CRLFCRLF)\n const crlfcrlf = encoder.encode('\\\\r\\\\n\\\\r\\\\n');\n const headersEnd = findSequence(bodyBytes, crlfcrlf, pos);\n if (headersEnd === -1) break;\n\n // Parse headers\n const headersText = decoder.decode(bodyBytes.slice(pos, headersEnd));\n const headers = parseHeaders(headersText);\n pos = headersEnd + 4;\n\n // Find next boundary\n const nextBoundary = findSequence(bodyBytes, boundaryBytes, pos);\n if (nextBoundary === -1) break;\n\n // Extract content (minus trailing CRLF)\n let contentEnd = nextBoundary;\n if (contentEnd > 0 && bodyBytes[contentEnd - 1] === 0x0a) contentEnd--;\n if (contentEnd > 0 && bodyBytes[contentEnd - 1] === 0x0d) contentEnd--;\n const content = bodyBytes.slice(pos, contentEnd);\n\n // Parse Content-Disposition\n const disposition = headers['content-disposition'] || '';\n const nameMatch = disposition.match(/name=\"([^\"]+)\"/);\n const filenameMatch = disposition.match(/filename=\"([^\"]+)\"/);\n\n if (nameMatch) {\n const name = nameMatch[1];\n if (filenameMatch) {\n const filename = filenameMatch[1];\n const mimeType = headers['content-type'] || 'application/octet-stream';\n const file = new File([content], filename, { type: mimeType });\n formData.append(name, file);\n } else {\n formData.append(name, decoder.decode(content));\n }\n }\n\n pos = nextBoundary + boundaryBytes.length;\n }\n\n return formData;\n };\n\n // Serialize FormData to multipart/form-data format\n globalThis.__serializeFormData = function(formData) {\n const boundary = '----FormDataBoundary' + Math.random().toString(36).slice(2) +\n Math.random().toString(36).slice(2);\n const encoder = new TextEncoder();\n const parts = [];\n\n for (const [name, value] of formData.entries()) {\n if (value instanceof File) {\n const header = [\n '--' + boundary,\n 'Content-Disposition: form-data; name=\"' + name + '\"; filename=\"' + value.name + '\"',\n 'Content-Type: ' + (value.type || 'application/octet-stream'),\n '',\n ''\n ].join('\\\\r\\\\n');\n parts.push(encoder.encode(header));\n // Use existing __Blob_bytes callback (File extends Blob)\n parts.push(__Blob_bytes(value._getInstanceId()));\n parts.push(encoder.encode('\\\\r\\\\n'));\n } else if (value instanceof Blob) {\n const header = [\n '--' + boundary,\n 'Content-Disposition: form-data; name=\"' + name + '\"; filename=\"blob\"',\n 'Content-Type: ' + (value.type || 'application/octet-stream'),\n '',\n ''\n ].join('\\\\r\\\\n');\n parts.push(encoder.encode(header));\n parts.push(__Blob_bytes(value._getInstanceId()));\n parts.push(encoder.encode('\\\\r\\\\n'));\n } else {\n const header = [\n '--' + boundary,\n 'Content-Disposition: form-data; name=\"' + name + '\"',\n '',\n ''\n ].join('\\\\r\\\\n');\n parts.push(encoder.encode(header));\n parts.push(encoder.encode(String(value)));\n parts.push(encoder.encode('\\\\r\\\\n'));\n }\n }\n\n // Closing boundary\n parts.push(encoder.encode('--' + boundary + '--\\\\r\\\\n'));\n\n // Concatenate all parts\n const totalLength = parts.reduce((sum, p) => sum + p.length, 0);\n const body = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n body.set(part, offset);\n offset += part.length;\n }\n\n return {\n body: body,\n contentType: 'multipart/form-data; boundary=' + boundary\n };\n };\n})();\n`;\n\n// ============================================================================\n// Stream Callbacks (Host State)\n// ============================================================================\n\nfunction setupStreamCallbacks(\n context: ivm.Context,\n streamRegistry: StreamStateRegistry\n): void {\n const global = context.global;\n\n // Create stream (returns ID)\n global.setSync(\n \"__Stream_create\",\n new ivm.Callback(() => {\n return streamRegistry.create();\n })\n );\n\n // Push chunk (sync) - receives number[] from isolate\n global.setSync(\n \"__Stream_push\",\n new ivm.Callback((streamId: number, chunkArray: number[]) => {\n const chunk = new Uint8Array(chunkArray);\n return streamRegistry.push(streamId, chunk);\n })\n );\n\n // Close stream (sync)\n global.setSync(\n \"__Stream_close\",\n new ivm.Callback((streamId: number) => {\n streamRegistry.close(streamId);\n })\n );\n\n // Error stream (sync)\n global.setSync(\n \"__Stream_error\",\n new ivm.Callback((streamId: number, message: string) => {\n streamRegistry.error(streamId, new Error(message));\n })\n );\n\n // Check backpressure (sync)\n global.setSync(\n \"__Stream_isQueueFull\",\n new ivm.Callback((streamId: number) => {\n return streamRegistry.isQueueFull(streamId);\n })\n );\n\n // Pull chunk (async with applySyncPromise)\n const pullRef = new ivm.Reference(async (streamId: number) => {\n const result = await streamRegistry.pull(streamId);\n if (result.done) {\n return JSON.stringify({ done: true });\n }\n return JSON.stringify({ done: false, value: Array.from(result.value) });\n });\n global.setSync(\"__Stream_pull_ref\", pullRef);\n}\n\n// ============================================================================\n// Host-Backed ReadableStream (Isolate Code)\n// ============================================================================\n\nconst hostBackedStreamCode = `\n(function() {\n const _streamIds = new WeakMap();\n\n class HostBackedReadableStream {\n constructor(streamId) {\n if (streamId === undefined) {\n streamId = __Stream_create();\n }\n _streamIds.set(this, streamId);\n }\n\n _getStreamId() {\n return _streamIds.get(this);\n }\n\n getReader() {\n const streamId = this._getStreamId();\n let released = false;\n\n return {\n read: async () => {\n if (released) {\n throw new TypeError(\"Reader has been released\");\n }\n const resultJson = __Stream_pull_ref.applySyncPromise(undefined, [streamId]);\n const result = JSON.parse(resultJson);\n\n if (result.done) {\n return { done: true, value: undefined };\n }\n return { done: false, value: new Uint8Array(result.value) };\n },\n\n releaseLock: () => {\n released = true;\n },\n\n get closed() {\n return new Promise(() => {});\n },\n\n cancel: async (reason) => {\n __Stream_error(streamId, String(reason || \"cancelled\"));\n }\n };\n }\n\n async cancel(reason) {\n __Stream_error(this._getStreamId(), String(reason || \"cancelled\"));\n }\n\n get locked() {\n return false;\n }\n\n async *[Symbol.asyncIterator]() {\n const reader = this.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) return;\n yield value;\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n // Static method to create from existing stream ID\n static _fromStreamId(streamId) {\n return new HostBackedReadableStream(streamId);\n }\n }\n\n globalThis.HostBackedReadableStream = HostBackedReadableStream;\n})();\n`;\n\n// ============================================================================\n// Response Implementation (Host State + Isolate Class)\n// ============================================================================\n\nfunction setupResponse(\n context: ivm.Context,\n stateMap: Map<number, unknown>\n): void {\n const global = context.global;\n\n // Register host callbacks\n global.setSync(\n \"__Response_construct\",\n new ivm.Callback(\n (\n bodyBytes: number[] | null,\n status: number,\n statusText: string,\n headers: [string, string][]\n ) => {\n const instanceId = nextInstanceId++;\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const state: ResponseState = {\n status,\n statusText,\n headers,\n body,\n bodyUsed: false,\n type: \"default\",\n url: \"\",\n redirected: false,\n streamId: null,\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n // Streaming Response constructor - creates Response with stream ID but no buffered body\n global.setSync(\n \"__Response_constructStreaming\",\n new ivm.Callback(\n (\n streamId: number,\n status: number,\n statusText: string,\n headers: [string, string][]\n ) => {\n const instanceId = nextInstanceId++;\n const state: ResponseState = {\n status,\n statusText,\n headers,\n body: null, // No buffered body - using stream\n bodyUsed: false,\n type: \"default\",\n url: \"\",\n redirected: false,\n streamId, // Stream ID for body\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n global.setSync(\n \"__Response_constructFromFetch\",\n new ivm.Callback(\n (\n bodyBytes: number[] | null,\n status: number,\n statusText: string,\n headers: [string, string][],\n url: string,\n redirected: boolean\n ) => {\n const instanceId = nextInstanceId++;\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const state: ResponseState = {\n status,\n statusText,\n headers,\n body,\n bodyUsed: false,\n type: \"default\",\n url,\n redirected,\n streamId: null,\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n global.setSync(\n \"__Response_get_status\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.status ?? 200;\n })\n );\n\n global.setSync(\n \"__Response_get_statusText\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.statusText ?? \"\";\n })\n );\n\n global.setSync(\n \"__Response_get_headers\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.headers ?? [];\n })\n );\n\n global.setSync(\n \"__Response_get_bodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.bodyUsed ?? false;\n })\n );\n\n global.setSync(\n \"__Response_get_url\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.url ?? \"\";\n })\n );\n\n global.setSync(\n \"__Response_get_redirected\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.redirected ?? false;\n })\n );\n\n global.setSync(\n \"__Response_get_type\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.type ?? \"default\";\n })\n );\n\n global.setSync(\n \"__Response_setType\",\n new ivm.Callback((instanceId: number, type: string) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (state) {\n state.type = type;\n }\n })\n );\n\n global.setSync(\n \"__Response_markBodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (state) {\n if (state.bodyUsed) {\n throw new Error(\"[TypeError]Body has already been consumed\");\n }\n state.bodyUsed = true;\n }\n })\n );\n\n global.setSync(\n \"__Response_text\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (!state || !state.body) return \"\";\n return new TextDecoder().decode(state.body);\n })\n );\n\n global.setSync(\n \"__Response_arrayBuffer\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (!state || !state.body) {\n return new ivm.ExternalCopy(new ArrayBuffer(0)).copyInto();\n }\n return new ivm.ExternalCopy(state.body.buffer.slice(\n state.body.byteOffset,\n state.body.byteOffset + state.body.byteLength\n )).copyInto();\n })\n );\n\n global.setSync(\n \"__Response_clone\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n if (!state) {\n throw new Error(\"[TypeError]Cannot clone invalid Response\");\n }\n const newId = nextInstanceId++;\n const newState: ResponseState = {\n ...state,\n body: state.body ? new Uint8Array(state.body) : null,\n bodyUsed: false,\n };\n stateMap.set(newId, newState);\n return newId;\n })\n );\n\n global.setSync(\n \"__Response_getStreamId\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as ResponseState | undefined;\n return state?.streamId ?? null;\n })\n );\n\n // Inject Response class\n const responseCode = `\n(function() {\n const _responseInstanceIds = new WeakMap();\n\n function __decodeError(err) {\n if (!(err instanceof Error)) return err;\n const match = err.message.match(/^\\\\[(TypeError|RangeError|SyntaxError|ReferenceError|URIError|EvalError|Error)\\\\](.*)$/);\n if (match) {\n const ErrorType = globalThis[match[1]] || Error;\n return new ErrorType(match[2]);\n }\n return err;\n }\n\n function __prepareBody(body) {\n if (body === null || body === undefined) return null;\n if (typeof body === 'string') {\n const encoder = new TextEncoder();\n return Array.from(encoder.encode(body));\n }\n if (body instanceof ArrayBuffer) {\n return Array.from(new Uint8Array(body));\n }\n if (body instanceof Uint8Array) {\n return Array.from(body);\n }\n if (ArrayBuffer.isView(body)) {\n return Array.from(new Uint8Array(body.buffer, body.byteOffset, body.byteLength));\n }\n if (body instanceof Blob) {\n // Mark as needing async Blob handling - will be read in constructor\n return { __isBlob: true, blob: body };\n }\n // Handle ReadableStream (both native and host-backed)\n if (body instanceof ReadableStream || body instanceof HostBackedReadableStream) {\n return { __isStream: true, stream: body };\n }\n // Try to convert to string\n return Array.from(new TextEncoder().encode(String(body)));\n }\n\n class Response {\n #instanceId;\n #headers;\n #streamId = null;\n #blobInitPromise = null; // For async Blob body initialization\n\n constructor(body, init = {}) {\n // Handle internal construction from instance ID\n if (typeof body === 'number' && init === null) {\n this.#instanceId = body;\n this.#headers = new Headers(__Response_get_headers(body));\n this.#streamId = __Response_getStreamId(body);\n return;\n }\n\n const preparedBody = __prepareBody(body);\n\n // Handle Blob body - create streaming response and push blob data\n if (preparedBody && preparedBody.__isBlob) {\n this.#streamId = __Stream_create();\n const status = init.status ?? 200;\n const statusText = init.statusText ?? '';\n const headers = new Headers(init.headers);\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Response_constructStreaming(\n this.#streamId,\n status,\n statusText,\n headersArray\n );\n this.#headers = headers;\n\n // Start async blob initialization and stream pumping\n const streamId = this.#streamId;\n const blob = preparedBody.blob;\n this.#blobInitPromise = (async () => {\n try {\n const buffer = await blob.arrayBuffer();\n __Stream_push(streamId, Array.from(new Uint8Array(buffer)));\n __Stream_close(streamId);\n } catch (error) {\n __Stream_error(streamId, String(error));\n }\n })();\n return;\n }\n\n // Handle streaming body\n if (preparedBody && preparedBody.__isStream) {\n this.#streamId = __Stream_create();\n const status = init.status ?? 200;\n const statusText = init.statusText ?? '';\n const headers = new Headers(init.headers);\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Response_constructStreaming(\n this.#streamId,\n status,\n statusText,\n headersArray\n );\n this.#headers = headers;\n\n // Start pumping the source stream to host queue (fire-and-forget)\n this._startStreamPump(preparedBody.stream);\n return;\n }\n\n // Existing buffered body handling\n const bodyBytes = preparedBody;\n const status = init.status ?? 200;\n const statusText = init.statusText ?? '';\n const headersInit = init.headers;\n const headers = new Headers(headersInit);\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Response_construct(bodyBytes, status, statusText, headersArray);\n this.#headers = headers;\n }\n\n async _startStreamPump(sourceStream) {\n const streamId = this.#streamId;\n try {\n const reader = sourceStream.getReader();\n while (true) {\n // Check backpressure - wait if queue is full\n while (__Stream_isQueueFull(streamId)) {\n await new Promise(r => setTimeout(r, 1));\n }\n\n const { done, value } = await reader.read();\n if (done) {\n __Stream_close(streamId);\n break;\n }\n if (value) {\n __Stream_push(streamId, Array.from(value));\n }\n }\n } catch (error) {\n __Stream_error(streamId, String(error));\n }\n }\n\n _getInstanceId() {\n return this.#instanceId;\n }\n\n static _fromInstanceId(instanceId) {\n return new Response(instanceId, null);\n }\n\n get status() {\n return __Response_get_status(this.#instanceId);\n }\n\n get statusText() {\n return __Response_get_statusText(this.#instanceId);\n }\n\n get ok() {\n const status = this.status;\n return status >= 200 && status < 300;\n }\n\n get headers() {\n return this.#headers;\n }\n\n get bodyUsed() {\n return __Response_get_bodyUsed(this.#instanceId);\n }\n\n get url() {\n return __Response_get_url(this.#instanceId);\n }\n\n get redirected() {\n return __Response_get_redirected(this.#instanceId);\n }\n\n get type() {\n return __Response_get_type(this.#instanceId);\n }\n\n get body() {\n const streamId = __Response_getStreamId(this.#instanceId);\n if (streamId !== null) {\n return HostBackedReadableStream._fromStreamId(streamId);\n }\n\n // Fallback: create host-backed stream from buffered body\n const instanceId = this.#instanceId;\n const newStreamId = __Stream_create();\n const buffer = __Response_arrayBuffer(instanceId);\n\n if (buffer.byteLength > 0) {\n __Stream_push(newStreamId, Array.from(new Uint8Array(buffer)));\n }\n __Stream_close(newStreamId);\n\n return HostBackedReadableStream._fromStreamId(newStreamId);\n }\n\n async text() {\n try {\n __Response_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n return __Response_text(this.#instanceId);\n }\n\n async json() {\n const text = await this.text();\n return JSON.parse(text);\n }\n\n async arrayBuffer() {\n try {\n __Response_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n\n // For streaming responses (including Blob bodies), consume the stream\n if (this.#streamId !== null) {\n // Wait for blob init to complete if needed\n if (this.#blobInitPromise) {\n await this.#blobInitPromise;\n this.#blobInitPromise = null;\n }\n\n const reader = this.body.getReader();\n const chunks = [];\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value) chunks.push(value);\n }\n // Concatenate all chunks\n const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n return result.buffer;\n }\n\n return __Response_arrayBuffer(this.#instanceId);\n }\n\n async blob() {\n const buffer = await this.arrayBuffer();\n const contentType = this.headers.get('content-type') || '';\n return new Blob([buffer], { type: contentType });\n }\n\n async formData() {\n const contentType = this.headers.get('content-type') || '';\n\n // Parse multipart/form-data\n if (contentType.includes('multipart/form-data')) {\n const buffer = await this.arrayBuffer();\n return __parseMultipartFormData(new Uint8Array(buffer), contentType);\n }\n\n // Parse application/x-www-form-urlencoded\n if (contentType.includes('application/x-www-form-urlencoded')) {\n const text = await this.text();\n const formData = new FormData();\n const params = new URLSearchParams(text);\n for (const [key, value] of params) {\n formData.append(key, value);\n }\n return formData;\n }\n\n throw new TypeError('Unsupported content type for formData()');\n }\n\n clone() {\n if (this.bodyUsed) {\n throw new TypeError('Cannot clone a Response that has already been used');\n }\n const newId = __Response_clone(this.#instanceId);\n const cloned = Response._fromInstanceId(newId);\n return cloned;\n }\n\n static json(data, init = {}) {\n const body = JSON.stringify(data);\n const headers = new Headers(init.headers);\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/json');\n }\n return new Response(body, { ...init, headers });\n }\n\n static redirect(url, status = 302) {\n if (![301, 302, 303, 307, 308].includes(status)) {\n throw new RangeError('Invalid redirect status code');\n }\n const headers = new Headers({ Location: String(url) });\n return new Response(null, { status, headers });\n }\n\n static error() {\n const response = new Response(null, { status: 0, statusText: '' });\n __Response_setType(response._getInstanceId(), 'error');\n return response;\n }\n }\n\n globalThis.Response = Response;\n})();\n`;\n\n context.evalSync(responseCode);\n}\n\n// ============================================================================\n// Request Implementation (Host State + Isolate Class)\n// ============================================================================\n\nfunction setupRequest(\n context: ivm.Context,\n stateMap: Map<number, unknown>\n): void {\n const global = context.global;\n\n // Register host callbacks\n global.setSync(\n \"__Request_construct\",\n new ivm.Callback(\n (\n url: string,\n method: string,\n headers: [string, string][],\n bodyBytes: number[] | null,\n mode: string,\n credentials: string,\n cache: string,\n redirect: string,\n referrer: string,\n integrity: string\n ) => {\n const instanceId = nextInstanceId++;\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const state: RequestState = {\n url,\n method,\n headers,\n body,\n bodyUsed: false,\n streamId: null,\n mode,\n credentials,\n cache,\n redirect,\n referrer,\n integrity,\n };\n stateMap.set(instanceId, state);\n return instanceId;\n }\n )\n );\n\n global.setSync(\n \"__Request_get_method\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.method ?? \"GET\";\n })\n );\n\n global.setSync(\n \"__Request_get_url\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.url ?? \"\";\n })\n );\n\n global.setSync(\n \"__Request_get_headers\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.headers ?? [];\n })\n );\n\n global.setSync(\n \"__Request_get_bodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.bodyUsed ?? false;\n })\n );\n\n global.setSync(\n \"__Request_get_mode\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.mode ?? \"cors\";\n })\n );\n\n global.setSync(\n \"__Request_get_credentials\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.credentials ?? \"same-origin\";\n })\n );\n\n global.setSync(\n \"__Request_get_cache\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.cache ?? \"default\";\n })\n );\n\n global.setSync(\n \"__Request_get_redirect\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.redirect ?? \"follow\";\n })\n );\n\n global.setSync(\n \"__Request_get_referrer\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.referrer ?? \"about:client\";\n })\n );\n\n global.setSync(\n \"__Request_get_integrity\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.integrity ?? \"\";\n })\n );\n\n global.setSync(\n \"__Request_markBodyUsed\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (state) {\n if (state.bodyUsed) {\n throw new Error(\"[TypeError]Body has already been consumed\");\n }\n state.bodyUsed = true;\n }\n })\n );\n\n global.setSync(\n \"__Request_text\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state || !state.body) return \"\";\n return new TextDecoder().decode(state.body);\n })\n );\n\n global.setSync(\n \"__Request_arrayBuffer\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state || !state.body) {\n return new ivm.ExternalCopy(new ArrayBuffer(0)).copyInto();\n }\n return new ivm.ExternalCopy(state.body.buffer.slice(\n state.body.byteOffset,\n state.body.byteOffset + state.body.byteLength\n )).copyInto();\n })\n );\n\n global.setSync(\n \"__Request_getBodyBytes\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state || !state.body) return null;\n return Array.from(state.body);\n })\n );\n\n global.setSync(\n \"__Request_clone\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n if (!state) {\n throw new Error(\"[TypeError]Cannot clone invalid Request\");\n }\n const newId = nextInstanceId++;\n const newState: RequestState = {\n ...state,\n body: state.body ? new Uint8Array(state.body) : null,\n bodyUsed: false,\n };\n stateMap.set(newId, newState);\n return newId;\n })\n );\n\n global.setSync(\n \"__Request_getStreamId\",\n new ivm.Callback((instanceId: number) => {\n const state = stateMap.get(instanceId) as RequestState | undefined;\n return state?.streamId ?? null;\n })\n );\n\n // Inject Request class\n const requestCode = `\n(function() {\n function __decodeError(err) {\n if (!(err instanceof Error)) return err;\n const match = err.message.match(/^\\\\[(TypeError|RangeError|SyntaxError|ReferenceError|URIError|EvalError|Error)\\\\](.*)$/);\n if (match) {\n const ErrorType = globalThis[match[1]] || Error;\n return new ErrorType(match[2]);\n }\n return err;\n }\n\n function __prepareBody(body) {\n if (body === null || body === undefined) return null;\n if (typeof body === 'string') {\n const encoder = new TextEncoder();\n return Array.from(encoder.encode(body));\n }\n if (body instanceof ArrayBuffer) {\n return Array.from(new Uint8Array(body));\n }\n if (body instanceof Uint8Array) {\n return Array.from(body);\n }\n if (ArrayBuffer.isView(body)) {\n return Array.from(new Uint8Array(body.buffer, body.byteOffset, body.byteLength));\n }\n if (body instanceof URLSearchParams) {\n return Array.from(new TextEncoder().encode(body.toString()));\n }\n if (body instanceof FormData) {\n // Check if FormData has any File/Blob entries\n let hasFiles = false;\n for (const [, value] of body.entries()) {\n if (value instanceof File || value instanceof Blob) {\n hasFiles = true;\n break;\n }\n }\n\n if (hasFiles) {\n // Serialize as multipart/form-data\n const { body: bytes, contentType } = __serializeFormData(body);\n globalThis.__pendingFormDataContentType = contentType;\n return Array.from(bytes);\n }\n\n // URL-encoded for string-only FormData\n const parts = [];\n body.forEach((value, key) => {\n if (typeof value === 'string') {\n parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));\n }\n });\n return Array.from(new TextEncoder().encode(parts.join('&')));\n }\n // Try to convert to string\n return Array.from(new TextEncoder().encode(String(body)));\n }\n\n // Helper to consume a HostBackedReadableStream and concatenate all chunks\n async function __consumeStream(stream) {\n const reader = stream.getReader();\n const chunks = [];\n let totalLength = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n totalLength += value.length;\n }\n\n // Concatenate all chunks\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n return result;\n }\n\n class Request {\n #instanceId;\n #headers;\n #signal;\n #streamId;\n #cachedBody = null;\n\n constructor(input, init = {}) {\n // Handle internal construction from instance ID\n if (typeof input === 'number' && init === null) {\n this.#instanceId = input;\n this.#headers = new Headers(__Request_get_headers(input));\n this.#signal = null;\n this.#streamId = __Request_getStreamId(input);\n return;\n }\n\n let url;\n let method = 'GET';\n let headers;\n let body = null;\n let signal = null;\n let mode = 'cors';\n let credentials = 'same-origin';\n let cache = 'default';\n let redirect = 'follow';\n let referrer = 'about:client';\n let integrity = '';\n\n if (input instanceof Request) {\n url = input.url;\n method = input.method;\n headers = new Headers(input.headers);\n signal = input.signal;\n mode = input.mode;\n credentials = input.credentials;\n cache = input.cache;\n redirect = input.redirect;\n referrer = input.referrer;\n integrity = input.integrity;\n // Note: We don't copy the body from the input Request\n } else {\n url = String(input);\n headers = new Headers();\n }\n\n // Apply init overrides\n if (init.method !== undefined) method = String(init.method).toUpperCase();\n if (init.headers !== undefined) headers = new Headers(init.headers);\n if (init.body !== undefined) body = init.body;\n if (init.signal !== undefined) signal = init.signal;\n if (init.mode !== undefined) mode = init.mode;\n if (init.credentials !== undefined) credentials = init.credentials;\n if (init.cache !== undefined) cache = init.cache;\n if (init.redirect !== undefined) redirect = init.redirect;\n if (init.referrer !== undefined) referrer = init.referrer;\n if (init.integrity !== undefined) integrity = init.integrity;\n\n // Validate: body with GET/HEAD\n if (body !== null && (method === 'GET' || method === 'HEAD')) {\n throw new TypeError('Request with GET/HEAD method cannot have body');\n }\n\n const bodyBytes = __prepareBody(body);\n\n // Handle Content-Type for FormData\n if (globalThis.__pendingFormDataContentType) {\n headers.set('content-type', globalThis.__pendingFormDataContentType);\n delete globalThis.__pendingFormDataContentType;\n } else if (body instanceof FormData && !headers.has('content-type')) {\n headers.set('content-type', 'application/x-www-form-urlencoded');\n }\n\n const headersArray = Array.from(headers.entries());\n\n this.#instanceId = __Request_construct(\n url, method, headersArray, bodyBytes,\n mode, credentials, cache, redirect, referrer, integrity\n );\n this.#headers = headers;\n this.#signal = signal;\n this.#streamId = null;\n }\n\n _getInstanceId() {\n return this.#instanceId;\n }\n\n static _fromInstanceId(instanceId) {\n return new Request(instanceId, null);\n }\n\n get method() {\n return __Request_get_method(this.#instanceId);\n }\n\n get url() {\n return __Request_get_url(this.#instanceId);\n }\n\n get headers() {\n return this.#headers;\n }\n\n get bodyUsed() {\n return __Request_get_bodyUsed(this.#instanceId);\n }\n\n get signal() {\n return this.#signal;\n }\n\n get mode() {\n return __Request_get_mode(this.#instanceId);\n }\n\n get credentials() {\n return __Request_get_credentials(this.#instanceId);\n }\n\n get cache() {\n return __Request_get_cache(this.#instanceId);\n }\n\n get redirect() {\n return __Request_get_redirect(this.#instanceId);\n }\n\n get referrer() {\n return __Request_get_referrer(this.#instanceId);\n }\n\n get integrity() {\n return __Request_get_integrity(this.#instanceId);\n }\n\n get body() {\n // Per WHATWG Fetch spec: GET/HEAD requests cannot have a body\n const method = __Request_get_method(this.#instanceId);\n if (method === 'GET' || method === 'HEAD') {\n return null;\n }\n\n // Return cached body if available\n if (this.#cachedBody !== null) {\n return this.#cachedBody;\n }\n\n // If we have a stream ID, create and cache the stream\n if (this.#streamId !== null) {\n this.#cachedBody = HostBackedReadableStream._fromStreamId(this.#streamId);\n return this.#cachedBody;\n }\n\n // Check if there's any buffered body data\n const buffer = __Request_arrayBuffer(this.#instanceId);\n if (buffer.byteLength === 0) {\n return null; // Return null per WHATWG Fetch spec for empty body\n }\n\n // Create stream from non-empty buffered body\n const newStreamId = __Stream_create();\n __Stream_push(newStreamId, Array.from(new Uint8Array(buffer)));\n __Stream_close(newStreamId);\n\n this.#cachedBody = HostBackedReadableStream._fromStreamId(newStreamId);\n return this.#cachedBody;\n }\n\n async text() {\n try {\n __Request_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n\n // If streaming, consume the stream\n if (this.#streamId !== null) {\n const bytes = await __consumeStream(this.body);\n return new TextDecoder().decode(bytes);\n }\n\n // Fallback to host callback for buffered body\n return __Request_text(this.#instanceId);\n }\n\n async json() {\n const text = await this.text();\n return JSON.parse(text);\n }\n\n async arrayBuffer() {\n try {\n __Request_markBodyUsed(this.#instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n\n // If streaming, consume the stream\n if (this.#streamId !== null) {\n const bytes = await __consumeStream(this.body);\n return bytes.buffer;\n }\n\n return __Request_arrayBuffer(this.#instanceId);\n }\n\n async blob() {\n const buffer = await this.arrayBuffer();\n const contentType = this.headers.get('content-type') || '';\n return new Blob([buffer], { type: contentType });\n }\n\n async formData() {\n const contentType = this.headers.get('content-type') || '';\n\n // Parse multipart/form-data\n if (contentType.includes('multipart/form-data')) {\n const buffer = await this.arrayBuffer();\n return __parseMultipartFormData(new Uint8Array(buffer), contentType);\n }\n\n // Parse application/x-www-form-urlencoded\n if (contentType.includes('application/x-www-form-urlencoded')) {\n const text = await this.text();\n const formData = new FormData();\n const params = new URLSearchParams(text);\n for (const [key, value] of params) {\n formData.append(key, value);\n }\n return formData;\n }\n\n throw new TypeError('Unsupported content type for formData()');\n }\n\n clone() {\n if (this.bodyUsed) {\n throw new TypeError('Cannot clone a Request that has already been used');\n }\n const newId = __Request_clone(this.#instanceId);\n const cloned = Request._fromInstanceId(newId);\n cloned.#signal = this.#signal;\n return cloned;\n }\n\n _getBodyBytes() {\n return __Request_getBodyBytes(this.#instanceId);\n }\n }\n\n globalThis.Request = Request;\n})();\n`;\n\n context.evalSync(requestCode);\n}\n\n// ============================================================================\n// fetch Implementation\n// ============================================================================\n\nfunction setupFetchFunction(\n context: ivm.Context,\n stateMap: Map<number, unknown>,\n options?: FetchOptions\n): void {\n const global = context.global;\n\n // Create async fetch reference\n // We use JSON serialization for complex data to avoid transfer issues\n const fetchRef = new ivm.Reference(\n async (\n url: string,\n method: string,\n headersJson: string,\n bodyJson: string | null,\n signalAborted: boolean\n ) => {\n // Check if already aborted\n if (signalAborted) {\n throw new Error(\"[AbortError]The operation was aborted.\");\n }\n\n // Parse headers and body from JSON\n const headers = JSON.parse(headersJson) as [string, string][];\n const bodyBytes = bodyJson ? JSON.parse(bodyJson) as number[] : null;\n\n // Construct native Request\n const body = bodyBytes ? new Uint8Array(bodyBytes) : null;\n const nativeRequest = new Request(url, {\n method,\n headers,\n body,\n });\n\n // Call user's onFetch handler or default fetch\n const onFetch = options?.onFetch ?? fetch;\n const nativeResponse = await onFetch(nativeRequest);\n\n // Read response body\n const responseBody = await nativeResponse.arrayBuffer();\n const responseBodyArray = Array.from(new Uint8Array(responseBody));\n\n // Store the response in the state map and return just the ID + metadata\n const instanceId = nextInstanceId++;\n const state: ResponseState = {\n status: nativeResponse.status,\n statusText: nativeResponse.statusText,\n headers: Array.from(nativeResponse.headers.entries()),\n body: new Uint8Array(responseBodyArray),\n bodyUsed: false,\n type: \"default\",\n url: nativeResponse.url,\n redirected: nativeResponse.redirected,\n streamId: null,\n };\n stateMap.set(instanceId, state);\n\n // Return only the instance ID - avoid complex object transfer\n return instanceId;\n }\n );\n\n global.setSync(\"__fetch_ref\", fetchRef);\n\n // Inject fetch function\n const fetchCode = `\n(function() {\n function __decodeError(err) {\n if (!(err instanceof Error)) return err;\n const match = err.message.match(/^\\\\[(TypeError|RangeError|AbortError|Error)\\\\](.*)$/);\n if (match) {\n if (match[1] === 'AbortError') {\n return new DOMException(match[2], 'AbortError');\n }\n const ErrorType = globalThis[match[1]] || Error;\n return new ErrorType(match[2]);\n }\n return err;\n }\n\n globalThis.fetch = function(input, init = {}) {\n // Create Request from input\n const request = input instanceof Request ? input : new Request(input, init);\n\n // Get signal info\n const signal = init.signal ?? request.signal;\n const signalAborted = signal?.aborted ?? false;\n\n // Serialize headers and body to JSON for transfer\n const headersJson = JSON.stringify(Array.from(request.headers.entries()));\n const bodyBytes = request._getBodyBytes();\n const bodyJson = bodyBytes ? JSON.stringify(bodyBytes) : null;\n\n // Call host - returns just the response instance ID\n try {\n const instanceId = __fetch_ref.applySyncPromise(undefined, [\n request.url,\n request.method,\n headersJson,\n bodyJson,\n signalAborted\n ]);\n\n // Construct Response from the instance ID\n return Response._fromInstanceId(instanceId);\n } catch (err) {\n throw __decodeError(err);\n }\n };\n})();\n`;\n\n context.evalSync(fetchCode);\n}\n\n// ============================================================================\n// Server Implementation (for serve())\n// ============================================================================\n\nfunction setupServer(\n context: ivm.Context,\n serveState: ServeState\n): void {\n const global = context.global;\n\n // Setup upgrade registry in isolate (data stays in isolate, never marshalled to host)\n context.evalSync(`\n globalThis.__upgradeRegistry__ = new Map();\n globalThis.__upgradeIdCounter__ = 0;\n `);\n\n // Host callback to notify about pending upgrade\n global.setSync(\n \"__setPendingUpgrade__\",\n new ivm.Callback((connectionId: string) => {\n serveState.pendingUpgrade = { requested: true, connectionId };\n })\n );\n\n // Pure JS Server class with upgrade method\n context.evalSync(`\n(function() {\n class Server {\n upgrade(request, options) {\n const data = options?.data;\n const connectionId = String(++globalThis.__upgradeIdCounter__);\n globalThis.__upgradeRegistry__.set(connectionId, data);\n __setPendingUpgrade__(connectionId);\n return true;\n }\n }\n globalThis.__Server__ = Server;\n})();\n `);\n}\n\n// ============================================================================\n// ServerWebSocket Implementation (for serve())\n// ============================================================================\n\nfunction setupServerWebSocket(\n context: ivm.Context,\n wsCommandCallbacks: Set<(cmd: WebSocketCommand) => void>\n): void {\n const global = context.global;\n\n // Host callback for ws.send()\n global.setSync(\n \"__ServerWebSocket_send\",\n new ivm.Callback((connectionId: string, data: string) => {\n const cmd: WebSocketCommand = { type: \"message\", connectionId, data };\n for (const cb of wsCommandCallbacks) cb(cmd);\n })\n );\n\n // Host callback for ws.close()\n global.setSync(\n \"__ServerWebSocket_close\",\n new ivm.Callback((connectionId: string, code?: number, reason?: string) => {\n const cmd: WebSocketCommand = { type: \"close\", connectionId, code, reason };\n for (const cb of wsCommandCallbacks) cb(cmd);\n })\n );\n\n // Pure JS ServerWebSocket class\n context.evalSync(`\n(function() {\n const _wsInstanceData = new WeakMap();\n\n class ServerWebSocket {\n constructor(connectionId) {\n _wsInstanceData.set(this, { connectionId, readyState: 1 });\n }\n\n get data() {\n const state = _wsInstanceData.get(this);\n return globalThis.__upgradeRegistry__.get(state.connectionId);\n }\n\n get readyState() {\n return _wsInstanceData.get(this).readyState;\n }\n\n send(message) {\n const state = _wsInstanceData.get(this);\n if (state.readyState !== 1) throw new Error(\"WebSocket is not open\");\n // Convert ArrayBuffer/Uint8Array to string for transfer\n let data = message;\n if (message instanceof ArrayBuffer) {\n data = new TextDecoder().decode(message);\n } else if (message instanceof Uint8Array) {\n data = new TextDecoder().decode(message);\n }\n __ServerWebSocket_send(state.connectionId, data);\n }\n\n close(code, reason) {\n const state = _wsInstanceData.get(this);\n if (state.readyState === 3) return;\n state.readyState = 2; // CLOSING\n __ServerWebSocket_close(state.connectionId, code, reason);\n }\n\n _setReadyState(readyState) {\n _wsInstanceData.get(this).readyState = readyState;\n }\n }\n\n globalThis.__ServerWebSocket__ = ServerWebSocket;\n})();\n `);\n}\n\n// ============================================================================\n// serve() Function Implementation\n// ============================================================================\n\nfunction setupServe(context: ivm.Context): void {\n // Pure JS serve() that stores options on __serveOptions__ global\n context.evalSync(`\n(function() {\n globalThis.__serveOptions__ = null;\n\n function serve(options) {\n globalThis.__serveOptions__ = options;\n }\n\n globalThis.serve = serve;\n})();\n `);\n}\n\n// ============================================================================\n// Main Setup Function\n// ============================================================================\n\n/**\n * Setup Fetch API in an isolated-vm context\n *\n * Injects fetch, Request, Response, Headers, FormData\n * Also sets up core APIs (Blob, File, AbortController, etc.) if not already present\n *\n * @example\n * const handle = await setupFetch(context, {\n * onFetch: async (request) => {\n * // Proxy fetch requests to the host\n * return fetch(request);\n * }\n * });\n *\n * await context.eval(`\n * const response = await fetch(\"https://example.com\");\n * const text = await response.text();\n * `);\n */\nexport async function setupFetch(\n context: ivm.Context,\n options?: FetchOptions\n): Promise<FetchHandle> {\n // Setup core APIs first (Blob, File, AbortController, Streams, etc.)\n await setupCore(context);\n\n const stateMap = getInstanceStateMapForContext(context);\n const streamRegistry = getStreamRegistryForContext(context);\n\n // Inject Headers (pure JS)\n context.evalSync(headersCode);\n\n // Inject FormData (pure JS)\n context.evalSync(formDataCode);\n\n // Inject multipart parsing/serialization (pure JS)\n context.evalSync(multipartCode);\n\n // Setup stream callbacks and inject HostBackedReadableStream\n setupStreamCallbacks(context, streamRegistry);\n context.evalSync(hostBackedStreamCode);\n\n // Setup Response (host state + isolate class)\n setupResponse(context, stateMap);\n\n // Setup Request (host state + isolate class)\n setupRequest(context, stateMap);\n\n // Setup fetch function\n setupFetchFunction(context, stateMap, options);\n\n // Setup serve state\n const serveState: ServeState = {\n pendingUpgrade: null,\n activeConnections: new Map(),\n };\n\n // Setup WebSocket command callbacks\n const wsCommandCallbacks = new Set<(cmd: WebSocketCommand) => void>();\n\n // Setup Server class\n setupServer(context, serveState);\n\n // Setup ServerWebSocket class\n setupServerWebSocket(context, wsCommandCallbacks);\n\n // Setup serve function\n setupServe(context);\n\n return {\n dispose() {\n // Clear state for this context\n stateMap.clear();\n // Clear upgrade registry\n context.evalSync(`globalThis.__upgradeRegistry__.clear()`);\n // Clear serve state\n serveState.activeConnections.clear();\n serveState.pendingUpgrade = null;\n },\n\n async dispatchRequest(\n request: Request,\n _dispatchOptions?: DispatchRequestOptions\n ): Promise<Response> {\n // Clean up previous pending upgrade if not consumed\n if (serveState.pendingUpgrade) {\n const oldConnectionId = serveState.pendingUpgrade.connectionId;\n context.evalSync(`globalThis.__upgradeRegistry__.delete(\"${oldConnectionId}\")`);\n serveState.pendingUpgrade = null;\n }\n\n // Check if serve handler exists\n const hasHandler = context.evalSync(`!!globalThis.__serveOptions__?.fetch`);\n if (!hasHandler) {\n throw new Error(\"No serve() handler registered\");\n }\n\n // Setup streaming for request body\n // Per WHATWG Fetch spec, GET/HEAD requests cannot have bodies\n let requestStreamId: number | null = null;\n let streamCleanup: (() => Promise<void>) | null = null;\n const canHaveBody = !['GET', 'HEAD'].includes(request.method.toUpperCase());\n\n if (canHaveBody && request.body) {\n // Create a stream in the registry for the request body\n requestStreamId = streamRegistry.create();\n\n // Start background reader that pushes from native stream to host queue\n streamCleanup = startNativeStreamReader(\n request.body,\n requestStreamId,\n streamRegistry\n );\n }\n\n try {\n const headersArray = Array.from(request.headers.entries());\n\n // Create Request instance in isolate\n const requestInstanceId = nextInstanceId++;\n const requestState: RequestState = {\n url: request.url,\n method: request.method,\n headers: headersArray,\n body: null, // No buffered body - using stream\n bodyUsed: false,\n streamId: requestStreamId,\n mode: request.mode,\n credentials: request.credentials,\n cache: request.cache,\n redirect: request.redirect,\n referrer: request.referrer,\n integrity: request.integrity,\n };\n stateMap.set(requestInstanceId, requestState);\n\n // Call the fetch handler and get response\n // We use eval with promise: true to handle async handlers\n const responseInstanceId = await context.eval(`\n (async function() {\n const request = Request._fromInstanceId(${requestInstanceId});\n const server = new __Server__();\n const response = await Promise.resolve(__serveOptions__.fetch(request, server));\n return response._getInstanceId();\n })()\n `, { promise: true });\n\n // Get ResponseState from the instance\n const responseState = stateMap.get(responseInstanceId) as ResponseState | undefined;\n if (!responseState) {\n throw new Error(\"Response state not found\");\n }\n\n // Check if response has streaming body\n if (responseState.streamId !== null) {\n const responseStreamId = responseState.streamId;\n let streamDone = false;\n\n // Create native stream that waits for data from isolate\n const pumpedStream = new ReadableStream<Uint8Array>({\n async pull(controller) {\n if (streamDone) return;\n\n // Wait for data to be available\n while (!streamDone) {\n // Check if data is available\n const state = streamRegistry.get(responseStreamId);\n if (!state) {\n controller.close();\n streamDone = true;\n return;\n }\n\n // If queue has data or stream is done, break and pull\n if (state.queue.length > 0 || state.closed || state.errored) {\n break;\n }\n\n // Small delay to avoid busy-waiting\n await new Promise((r) => setTimeout(r, 1));\n }\n\n try {\n const result = await streamRegistry.pull(responseStreamId);\n if (result.done) {\n controller.close();\n streamDone = true;\n streamRegistry.delete(responseStreamId);\n return;\n }\n controller.enqueue(result.value);\n } catch (error) {\n controller.error(error);\n streamDone = true;\n streamRegistry.delete(responseStreamId);\n }\n },\n cancel() {\n streamDone = true;\n streamRegistry.error(\n responseStreamId,\n new Error(\"Stream cancelled\")\n );\n streamRegistry.delete(responseStreamId);\n },\n });\n\n const responseHeaders = new Headers(responseState.headers);\n const status =\n responseState.status === 101 ? 200 : responseState.status;\n const response = new Response(pumpedStream, {\n status,\n statusText: responseState.statusText,\n headers: responseHeaders,\n });\n\n // @ts-expect-error - adding custom property\n response._originalStatus = responseState.status;\n\n return response;\n }\n\n // Convert to native Response (non-streaming)\n const responseHeaders = new Headers(responseState.headers);\n const responseBody = responseState.body;\n\n // Note: Status 101 (Switching Protocols) is not valid for Response constructor\n // We use 200 as the status but preserve the actual status in a custom header\n // The caller should check getUpgradeRequest() for WebSocket upgrades\n const status = responseState.status === 101 ? 200 : responseState.status;\n const response = new Response(responseBody as ConstructorParameters<typeof Response>[0], {\n status,\n statusText: responseState.statusText,\n headers: responseHeaders,\n });\n\n // Expose the original status via a property for callers to check\n // @ts-expect-error - adding custom property\n response._originalStatus = responseState.status;\n\n return response;\n } finally {\n // Cleanup: cancel stream reader if still running\n if (streamCleanup) {\n await streamCleanup();\n }\n // Delete stream from registry\n if (requestStreamId !== null) {\n streamRegistry.delete(requestStreamId);\n }\n }\n },\n\n getUpgradeRequest(): UpgradeRequest | null {\n const result = serveState.pendingUpgrade;\n // Don't clear yet - it will be cleared on next dispatchRequest or consumed by dispatchWebSocketOpen\n return result;\n },\n\n dispatchWebSocketOpen(connectionId: string): void {\n // Store connection (data stays in isolate registry)\n serveState.activeConnections.set(connectionId, { connectionId });\n\n // Check if websocket.open handler exists\n const hasOpenHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.open`);\n\n // Create ServerWebSocket instance (always needed for message/close handlers)\n context.evalSync(`\n (function() {\n const ws = new __ServerWebSocket__(\"${connectionId}\");\n globalThis.__activeWs_${connectionId}__ = ws;\n })()\n `);\n\n // Call open handler if it exists\n if (hasOpenHandler) {\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n __serveOptions__.websocket.open(ws);\n })()\n `);\n }\n\n // Clear pending upgrade after successful open\n if (serveState.pendingUpgrade?.connectionId === connectionId) {\n serveState.pendingUpgrade = null;\n }\n },\n\n dispatchWebSocketMessage(connectionId: string, message: string | ArrayBuffer): void {\n // Check if connection is tracked\n if (!serveState.activeConnections.has(connectionId)) {\n return; // Silently ignore for unknown connections\n }\n\n // Check if message handler exists\n const hasMessageHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.message`);\n if (!hasMessageHandler) {\n return;\n }\n\n // Marshal message and call handler\n if (typeof message === \"string\") {\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) __serveOptions__.websocket.message(ws, \"${message.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\")}\");\n })()\n `);\n } else {\n // ArrayBuffer - convert to base64 or pass as array\n const bytes = Array.from(new Uint8Array(message));\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) {\n const bytes = new Uint8Array([${bytes.join(\",\")}]);\n __serveOptions__.websocket.message(ws, bytes.buffer);\n }\n })()\n `);\n }\n },\n\n dispatchWebSocketClose(connectionId: string, code: number, reason: string): void {\n // Check if connection is tracked\n if (!serveState.activeConnections.has(connectionId)) {\n return;\n }\n\n // Update readyState to CLOSED\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) ws._setReadyState(3);\n })()\n `);\n\n // Check if close handler exists\n const hasCloseHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.close`);\n if (hasCloseHandler) {\n const safeReason = reason.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) __serveOptions__.websocket.close(ws, ${code}, \"${safeReason}\");\n })()\n `);\n }\n\n // Cleanup\n context.evalSync(`\n delete globalThis.__activeWs_${connectionId}__;\n globalThis.__upgradeRegistry__.delete(\"${connectionId}\");\n `);\n serveState.activeConnections.delete(connectionId);\n },\n\n dispatchWebSocketError(connectionId: string, error: Error): void {\n // Check if connection is tracked\n if (!serveState.activeConnections.has(connectionId)) {\n return;\n }\n\n // Check if error handler exists\n const hasErrorHandler = context.evalSync(`!!globalThis.__serveOptions__?.websocket?.error`);\n if (!hasErrorHandler) {\n return;\n }\n\n const safeName = error.name.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n const safeMessage = error.message.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n context.evalSync(`\n (function() {\n const ws = globalThis.__activeWs_${connectionId}__;\n if (ws) {\n const error = { name: \"${safeName}\", message: \"${safeMessage}\" };\n __serveOptions__.websocket.error(ws, error);\n }\n })()\n `);\n },\n\n onWebSocketCommand(callback: (cmd: WebSocketCommand) => void): () => void {\n wsCommandCallbacks.add(callback);\n return () => wsCommandCallbacks.delete(callback);\n },\n\n hasServeHandler(): boolean {\n return context.evalSync(`!!globalThis.__serveOptions__?.fetch`) as boolean;\n },\n\n hasActiveConnections(): boolean {\n return serveState.activeConnections.size > 0;\n },\n };\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "AECB616396B74DA864756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/mjs/package.json
CHANGED