@ricsam/quickjs-fetch 0.2.7 → 0.2.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.
@@ -47,6 +47,7 @@ function createResponseClass(context, stateMap, createStream) {
47
47
  const init = args[1];
48
48
  let body = null;
49
49
  let bodyType = null;
50
+ let streamInstanceId = undefined;
50
51
  const status = init?.status ?? 200;
51
52
  const statusText = init?.statusText ?? "";
52
53
  let headersState = { headers: new Map };
@@ -70,6 +71,11 @@ function createResponseClass(context, stateMap, createStream) {
70
71
  offset += part.length;
71
72
  }
72
73
  bodyType = "binary";
74
+ } else if (bodyInit && typeof bodyInit === "object" && "__isDefineClassInstance__" in bodyInit && bodyInit.__className__ === "ReadableStream") {
75
+ const streamInstance = bodyInit;
76
+ body = null;
77
+ bodyType = "stream";
78
+ streamInstanceId = streamInstance.__instanceId__;
73
79
  }
74
80
  }
75
81
  if (init?.headers) {
@@ -102,12 +108,16 @@ function createResponseClass(context, stateMap, createStream) {
102
108
  redirected: false,
103
109
  type: init?._type ?? "default",
104
110
  ok: status >= 200 && status < 300,
105
- bodyType
111
+ bodyType,
112
+ streamInstanceId
106
113
  };
107
114
  },
108
115
  properties: {
109
116
  body: {
110
117
  get() {
118
+ if (this.bodyType === "stream") {
119
+ return null;
120
+ }
111
121
  if (!this.body)
112
122
  return null;
113
123
  if (!createStream) {
@@ -197,6 +207,9 @@ function createResponseClass(context, stateMap, createStream) {
197
207
  if (this.bodyUsed) {
198
208
  throw new TypeError("Body has already been consumed");
199
209
  }
210
+ if (this.bodyType === "stream") {
211
+ throw new TypeError("Cannot clone Response with streaming body");
212
+ }
200
213
  return {
201
214
  ...this,
202
215
  headersState: {
@@ -242,6 +255,12 @@ function createResponseClass(context, stateMap, createStream) {
242
255
  return import_form_data.parseUrlEncodedFormData(this.body);
243
256
  }
244
257
  throw new TypeError("Could not parse content as FormData");
258
+ },
259
+ __isStreamBody__() {
260
+ return this.bodyType === "stream";
261
+ },
262
+ __getStreamInstanceId__() {
263
+ return this.streamInstanceId;
245
264
  }
246
265
  }
247
266
  });
@@ -282,8 +301,11 @@ function addResponseStaticMethods(context) {
282
301
  }
283
302
  }
284
303
  function responseStateToNative(state) {
285
- const bodyBytes = state.body ?? state.body;
286
304
  const bodyType = state.bodyType;
305
+ if (bodyType === "stream") {
306
+ throw new Error("Stream bodies must be handled at dispatch level - use dispatchRequest");
307
+ }
308
+ const bodyBytes = state.body ?? state.body;
287
309
  const status = state.status ?? 200;
288
310
  const statusText = state.statusText ?? "";
289
311
  let headersState;
@@ -346,4 +368,4 @@ async function createResponseStateFromNative(response) {
346
368
  }
347
369
  })
348
370
 
349
- //# debugId=253BFDBC49B0C92064756E2164756E21
371
+ //# debugId=61E18893615E580364756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/globals/response.ts"],
4
4
  "sourcesContent": [
5
- "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass, getInstanceStateById } from \"@ricsam/quickjs-core\";\nimport type { ResponseState, HeadersState, FormDataState } from \"../types.cjs\";\nimport { headersStateToNative, createHeadersLike } from \"./headers.cjs\";\nimport { parseMultipartFormData, parseUrlEncodedFormData } from \"./form-data.cjs\";\n\n/**\n * Type for the stream factory function\n */\ntype StreamFactory = (source: UnderlyingSource) => QuickJSHandle;\n\n/**\n * Create the Response class for QuickJS\n */\nexport function createResponseClass(\n context: QuickJSContext,\n stateMap: StateMap,\n createStream?: StreamFactory\n): QuickJSHandle {\n const classHandle = defineClass<ResponseState>(context, stateMap, {\n name: \"Response\",\n construct: (args) => {\n const bodyInit = args[0];\n const init = args[1] as {\n status?: number;\n statusText?: string;\n headers?: object;\n _type?: string; // Internal: for Response.error() to set type\n } | undefined;\n\n let body: Uint8Array | null = null;\n let bodyType: \"string\" | \"binary\" | null = null;\n const status = init?.status ?? 200;\n const statusText = init?.statusText ?? \"\";\n let headersState: HeadersState = { headers: new Map() };\n\n // Parse body\n if (bodyInit !== null && bodyInit !== undefined) {\n if (typeof bodyInit === \"string\") {\n body = new TextEncoder().encode(bodyInit);\n bodyType = \"string\";\n } else if (bodyInit instanceof ArrayBuffer) {\n body = new Uint8Array(bodyInit);\n bodyType = \"binary\";\n } else if (bodyInit instanceof Uint8Array) {\n body = bodyInit;\n bodyType = \"binary\";\n } else if (\n bodyInit &&\n typeof bodyInit === \"object\" &&\n \"parts\" in bodyInit\n ) {\n // Blob-like\n const parts = (bodyInit as { parts: Uint8Array[] }).parts;\n const totalLength = parts.reduce((sum, p) => sum + p.length, 0);\n 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 bodyType = \"binary\";\n }\n }\n\n // Parse headers\n if (init?.headers) {\n if (\n init.headers &&\n typeof init.headers === \"object\" &&\n \"headers\" in init.headers &&\n init.headers.headers instanceof Map\n ) {\n headersState = {\n headers: new Map((init.headers as HeadersState).headers),\n };\n } else if (\n init.headers &&\n typeof init.headers === \"object\" &&\n \"__isDefineClassInstance__\" in init.headers &&\n (init.headers as { __isDefineClassInstance__?: boolean }).__isDefineClassInstance__ === true &&\n \"__instanceId__\" in init.headers\n ) {\n // Unmarshalled Headers instance from defineClass\n const instanceId = (init.headers as { __instanceId__: number }).__instanceId__;\n const state = getInstanceStateById<HeadersState>(instanceId);\n if (state && state.headers instanceof Map) {\n headersState = {\n headers: new Map(state.headers),\n };\n }\n } else {\n headersState = { headers: new Map() };\n for (const [key, value] of Object.entries(init.headers)) {\n headersState.headers.set(key.toLowerCase(), [String(value)]);\n }\n }\n }\n\n return {\n status,\n statusText,\n headersState,\n body,\n bodyUsed: false,\n url: \"\",\n redirected: false,\n type: init?._type ?? \"default\",\n ok: status >= 200 && status < 300,\n bodyType,\n };\n },\n properties: {\n body: {\n get(this: ResponseState) {\n if (!this.body) return null;\n if (!createStream) {\n // Fallback: return raw body if no stream factory\n return this.body;\n }\n // Create a ReadableStream from the body data\n const bodyData = this.body;\n let offset = 0;\n const chunkSize = 65536; // 64KB chunks\n return createStream({\n pull(controller) {\n if (offset >= bodyData.length) {\n controller.close();\n return;\n }\n const chunk = bodyData.slice(offset, Math.min(offset + chunkSize, bodyData.length));\n offset += chunk.length;\n controller.enqueue(chunk);\n },\n });\n },\n },\n bodyUsed: {\n get(this: ResponseState) {\n return this.bodyUsed;\n },\n },\n headers: {\n get(this: ResponseState) {\n return createHeadersLike(this.headersState);\n },\n },\n ok: {\n get(this: ResponseState) {\n return this.ok;\n },\n },\n redirected: {\n get(this: ResponseState) {\n return this.redirected;\n },\n },\n status: {\n get(this: ResponseState) {\n return this.status;\n },\n },\n statusText: {\n get(this: ResponseState) {\n return this.statusText;\n },\n },\n type: {\n get(this: ResponseState) {\n return this.type;\n },\n },\n url: {\n get(this: ResponseState) {\n return this.url;\n },\n },\n },\n methods: {\n async arrayBuffer(this: ResponseState): Promise<ArrayBuffer> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return new ArrayBuffer(0);\n }\n return this.body.buffer.slice(\n this.body.byteOffset,\n this.body.byteOffset + this.body.byteLength\n ) as ArrayBuffer;\n },\n async blob(this: ResponseState): Promise<object> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n const contentType =\n this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n return {\n parts: this.body ? [this.body] : [],\n type: contentType,\n size: this.body?.length || 0,\n };\n },\n clone(this: ResponseState): ResponseState {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n return {\n ...this,\n headersState: {\n headers: new Map(this.headersState.headers),\n },\n body: this.body ? new Uint8Array(this.body) : null,\n bodyUsed: false,\n };\n },\n async json(this: ResponseState): Promise<unknown> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return JSON.parse(\"\");\n }\n const text = new TextDecoder().decode(this.body);\n return JSON.parse(text);\n },\n async text(this: ResponseState): Promise<string> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return \"\";\n }\n return new TextDecoder().decode(this.body);\n },\n async formData(this: ResponseState): Promise<FormDataState> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return { entries: [] };\n }\n\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n\n if (contentType.includes(\"multipart/form-data\")) {\n return parseMultipartFormData(this.body, contentType);\n } else if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n return parseUrlEncodedFormData(this.body);\n }\n\n throw new TypeError(\"Could not parse content as FormData\");\n },\n },\n });\n\n return classHandle;\n}\n\n/**\n * Add static methods to Response class after it's been set on global\n * This must be called after Response and Headers are available on global\n */\nexport function addResponseStaticMethods(context: QuickJSContext): void {\n const staticMethodsCode = `\n Response.error = function() {\n return new Response(null, { status: 0, _type: \"error\" });\n };\n\n Response.json = function(data, init = {}) {\n const body = JSON.stringify(data);\n // Merge content-type with any provided headers\n const headers = Object.assign(\n { \"content-type\": \"application/json\" },\n init.headers || {}\n );\n return new Response(body, {\n status: init.status ?? 200,\n statusText: init.statusText ?? \"\",\n headers: headers\n });\n };\n\n Response.redirect = function(url, status = 302) {\n return new Response(null, {\n status: status,\n headers: { \"location\": String(url) }\n });\n };\n `;\n const result = context.evalCode(staticMethodsCode);\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n}\n\n/**\n * Convert ResponseState (or unmarshalled Response object) to native Response\n */\nexport function responseStateToNative(state: ResponseState | Record<string, unknown>): Response {\n const bodyBytes = (state as ResponseState).body ?? (state as Record<string, unknown>).body;\n const bodyType = (state as ResponseState).bodyType;\n const status = (state as ResponseState).status ?? 200;\n const statusText = (state as ResponseState).statusText ?? \"\";\n\n // Handle both headersState (internal) and headers (from getter)\n let headersState: HeadersState;\n if ((state as ResponseState).headersState) {\n headersState = (state as ResponseState).headersState;\n } else if ((state as Record<string, unknown>).headers) {\n // When unmarshalled, headers is the HeadersLike object from getter\n const headers = (state as Record<string, unknown>).headers as { headers?: Map<string, string[]> };\n if (headers.headers instanceof Map) {\n headersState = { headers: headers.headers };\n } else {\n headersState = { headers: new Map() };\n }\n } else {\n headersState = { headers: new Map() };\n }\n\n // Convert body back to string if it was originally a string\n // This ensures Bun.serve doesn't add application/octet-stream content-type\n let body: BodyInit | null = null;\n if (bodyBytes) {\n if (bodyType === \"string\") {\n body = new TextDecoder().decode(bodyBytes as Uint8Array);\n } else {\n // Cast to ArrayBuffer which is a valid BodyInit type\n const uint8 = bodyBytes as Uint8Array;\n body = uint8.buffer.slice(uint8.byteOffset, uint8.byteOffset + uint8.byteLength) as ArrayBuffer;\n }\n }\n\n return new Response(body, {\n status,\n statusText,\n headers: headersStateToNative(headersState),\n });\n}\n\n/**\n * Create a ResponseState from a native Response\n */\nexport async function createResponseStateFromNative(\n response: Response\n): Promise<ResponseState> {\n const body = response.body\n ? new Uint8Array(await response.arrayBuffer())\n : null;\n\n const headersState: HeadersState = { headers: new Map() };\n response.headers.forEach((value, key) => {\n const existing = headersState.headers.get(key.toLowerCase()) || [];\n existing.push(value);\n headersState.headers.set(key.toLowerCase(), existing);\n });\n\n // Detect body type from content-type header\n const contentType = response.headers.get(\"content-type\");\n let bodyType: \"string\" | \"binary\" | null = null;\n if (body) {\n if (contentType && (contentType.startsWith(\"text/\") || contentType.includes(\"json\") || contentType.includes(\"xml\"))) {\n bodyType = \"string\";\n } else {\n bodyType = \"binary\";\n }\n }\n\n return {\n status: response.status,\n statusText: response.statusText,\n headersState,\n body,\n bodyUsed: false,\n url: response.url,\n redirected: response.redirected,\n type: response.type,\n ok: response.ok,\n bodyType,\n };\n}\n"
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass, getInstanceStateById } from \"@ricsam/quickjs-core\";\nimport type { ResponseState, HeadersState, FormDataState } from \"../types.cjs\";\nimport { headersStateToNative, createHeadersLike } from \"./headers.cjs\";\nimport { parseMultipartFormData, parseUrlEncodedFormData } from \"./form-data.cjs\";\n\n/**\n * Type for the stream factory function\n */\ntype StreamFactory = (source: UnderlyingSource) => QuickJSHandle;\n\n/**\n * Create the Response class for QuickJS\n */\nexport function createResponseClass(\n context: QuickJSContext,\n stateMap: StateMap,\n createStream?: StreamFactory\n): QuickJSHandle {\n const classHandle = defineClass<ResponseState>(context, stateMap, {\n name: \"Response\",\n construct: (args) => {\n const bodyInit = args[0];\n const init = args[1] as {\n status?: number;\n statusText?: string;\n headers?: object;\n _type?: string; // Internal: for Response.error() to set type\n } | undefined;\n\n let body: Uint8Array | null = null;\n let bodyType: \"string\" | \"binary\" | \"stream\" | null = null;\n let streamInstanceId: number | undefined = undefined;\n const status = init?.status ?? 200;\n const statusText = init?.statusText ?? \"\";\n let headersState: HeadersState = { headers: new Map() };\n\n // Parse body\n if (bodyInit !== null && bodyInit !== undefined) {\n if (typeof bodyInit === \"string\") {\n body = new TextEncoder().encode(bodyInit);\n bodyType = \"string\";\n } else if (bodyInit instanceof ArrayBuffer) {\n body = new Uint8Array(bodyInit);\n bodyType = \"binary\";\n } else if (bodyInit instanceof Uint8Array) {\n body = bodyInit;\n bodyType = \"binary\";\n } else if (\n bodyInit &&\n typeof bodyInit === \"object\" &&\n \"parts\" in bodyInit\n ) {\n // Blob-like\n const parts = (bodyInit as { parts: Uint8Array[] }).parts;\n const totalLength = parts.reduce((sum, p) => sum + p.length, 0);\n 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 bodyType = \"binary\";\n } else if (\n bodyInit &&\n typeof bodyInit === \"object\" &&\n \"__isDefineClassInstance__\" in bodyInit &&\n (bodyInit as { __className__?: string }).__className__ === \"ReadableStream\"\n ) {\n // ReadableStream body - don't buffer, store instance ID for later consumption\n const streamInstance = bodyInit as {\n __instanceId__: number;\n __className__: string;\n __isDefineClassInstance__: true;\n };\n body = null;\n bodyType = \"stream\";\n streamInstanceId = streamInstance.__instanceId__;\n }\n }\n\n // Parse headers\n if (init?.headers) {\n if (\n init.headers &&\n typeof init.headers === \"object\" &&\n \"headers\" in init.headers &&\n init.headers.headers instanceof Map\n ) {\n headersState = {\n headers: new Map((init.headers as HeadersState).headers),\n };\n } else if (\n init.headers &&\n typeof init.headers === \"object\" &&\n \"__isDefineClassInstance__\" in init.headers &&\n (init.headers as { __isDefineClassInstance__?: boolean }).__isDefineClassInstance__ === true &&\n \"__instanceId__\" in init.headers\n ) {\n // Unmarshalled Headers instance from defineClass\n const instanceId = (init.headers as { __instanceId__: number }).__instanceId__;\n const state = getInstanceStateById<HeadersState>(instanceId);\n if (state && state.headers instanceof Map) {\n headersState = {\n headers: new Map(state.headers),\n };\n }\n } else {\n headersState = { headers: new Map() };\n for (const [key, value] of Object.entries(init.headers)) {\n headersState.headers.set(key.toLowerCase(), [String(value)]);\n }\n }\n }\n\n return {\n status,\n statusText,\n headersState,\n body,\n bodyUsed: false,\n url: \"\",\n redirected: false,\n type: init?._type ?? \"default\",\n ok: status >= 200 && status < 300,\n bodyType,\n streamInstanceId,\n };\n },\n properties: {\n body: {\n get(this: ResponseState) {\n // Stream body - return null (stream is stored by instanceId)\n // dispatchRequest will handle stream extraction\n if (this.bodyType === \"stream\") {\n return null;\n }\n\n if (!this.body) return null;\n if (!createStream) {\n // Fallback: return raw body if no stream factory\n return this.body;\n }\n // Create a ReadableStream from the body data\n const bodyData = this.body;\n let offset = 0;\n const chunkSize = 65536; // 64KB chunks\n return createStream({\n pull(controller) {\n if (offset >= bodyData.length) {\n controller.close();\n return;\n }\n const chunk = bodyData.slice(offset, Math.min(offset + chunkSize, bodyData.length));\n offset += chunk.length;\n controller.enqueue(chunk);\n },\n });\n },\n },\n bodyUsed: {\n get(this: ResponseState) {\n return this.bodyUsed;\n },\n },\n headers: {\n get(this: ResponseState) {\n return createHeadersLike(this.headersState);\n },\n },\n ok: {\n get(this: ResponseState) {\n return this.ok;\n },\n },\n redirected: {\n get(this: ResponseState) {\n return this.redirected;\n },\n },\n status: {\n get(this: ResponseState) {\n return this.status;\n },\n },\n statusText: {\n get(this: ResponseState) {\n return this.statusText;\n },\n },\n type: {\n get(this: ResponseState) {\n return this.type;\n },\n },\n url: {\n get(this: ResponseState) {\n return this.url;\n },\n },\n },\n methods: {\n async arrayBuffer(this: ResponseState): Promise<ArrayBuffer> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return new ArrayBuffer(0);\n }\n return this.body.buffer.slice(\n this.body.byteOffset,\n this.body.byteOffset + this.body.byteLength\n ) as ArrayBuffer;\n },\n async blob(this: ResponseState): Promise<object> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n const contentType =\n this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n return {\n parts: this.body ? [this.body] : [],\n type: contentType,\n size: this.body?.length || 0,\n };\n },\n clone(this: ResponseState): ResponseState {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n if (this.bodyType === \"stream\") {\n throw new TypeError(\"Cannot clone Response with streaming body\");\n }\n return {\n ...this,\n headersState: {\n headers: new Map(this.headersState.headers),\n },\n body: this.body ? new Uint8Array(this.body) : null,\n bodyUsed: false,\n };\n },\n async json(this: ResponseState): Promise<unknown> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return JSON.parse(\"\");\n }\n const text = new TextDecoder().decode(this.body);\n return JSON.parse(text);\n },\n async text(this: ResponseState): Promise<string> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return \"\";\n }\n return new TextDecoder().decode(this.body);\n },\n async formData(this: ResponseState): Promise<FormDataState> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return { entries: [] };\n }\n\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n\n if (contentType.includes(\"multipart/form-data\")) {\n return parseMultipartFormData(this.body, contentType);\n } else if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n return parseUrlEncodedFormData(this.body);\n }\n\n throw new TypeError(\"Could not parse content as FormData\");\n },\n __isStreamBody__(this: ResponseState): boolean {\n return this.bodyType === \"stream\";\n },\n __getStreamInstanceId__(this: ResponseState): number | undefined {\n return this.streamInstanceId;\n },\n },\n });\n\n return classHandle;\n}\n\n/**\n * Add static methods to Response class after it's been set on global\n * This must be called after Response and Headers are available on global\n */\nexport function addResponseStaticMethods(context: QuickJSContext): void {\n const staticMethodsCode = `\n Response.error = function() {\n return new Response(null, { status: 0, _type: \"error\" });\n };\n\n Response.json = function(data, init = {}) {\n const body = JSON.stringify(data);\n // Merge content-type with any provided headers\n const headers = Object.assign(\n { \"content-type\": \"application/json\" },\n init.headers || {}\n );\n return new Response(body, {\n status: init.status ?? 200,\n statusText: init.statusText ?? \"\",\n headers: headers\n });\n };\n\n Response.redirect = function(url, status = 302) {\n return new Response(null, {\n status: status,\n headers: { \"location\": String(url) }\n });\n };\n `;\n const result = context.evalCode(staticMethodsCode);\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n}\n\n/**\n * Convert ResponseState (or unmarshalled Response object) to native Response\n */\nexport function responseStateToNative(state: ResponseState | Record<string, unknown>): Response {\n const bodyType = (state as ResponseState).bodyType;\n\n // Stream bodies are handled by dispatchRequest directly\n if (bodyType === \"stream\") {\n throw new Error(\"Stream bodies must be handled at dispatch level - use dispatchRequest\");\n }\n\n const bodyBytes = (state as ResponseState).body ?? (state as Record<string, unknown>).body;\n const status = (state as ResponseState).status ?? 200;\n const statusText = (state as ResponseState).statusText ?? \"\";\n\n // Handle both headersState (internal) and headers (from getter)\n let headersState: HeadersState;\n if ((state as ResponseState).headersState) {\n headersState = (state as ResponseState).headersState;\n } else if ((state as Record<string, unknown>).headers) {\n // When unmarshalled, headers is the HeadersLike object from getter\n const headers = (state as Record<string, unknown>).headers as { headers?: Map<string, string[]> };\n if (headers.headers instanceof Map) {\n headersState = { headers: headers.headers };\n } else {\n headersState = { headers: new Map() };\n }\n } else {\n headersState = { headers: new Map() };\n }\n\n // Convert body back to string if it was originally a string\n // This ensures Bun.serve doesn't add application/octet-stream content-type\n let body: BodyInit | null = null;\n if (bodyBytes) {\n if (bodyType === \"string\") {\n body = new TextDecoder().decode(bodyBytes as Uint8Array);\n } else {\n // Cast to ArrayBuffer which is a valid BodyInit type\n const uint8 = bodyBytes as Uint8Array;\n body = uint8.buffer.slice(uint8.byteOffset, uint8.byteOffset + uint8.byteLength) as ArrayBuffer;\n }\n }\n\n return new Response(body, {\n status,\n statusText,\n headers: headersStateToNative(headersState),\n });\n}\n\n/**\n * Create a ResponseState from a native Response\n */\nexport async function createResponseStateFromNative(\n response: Response\n): Promise<ResponseState> {\n const body = response.body\n ? new Uint8Array(await response.arrayBuffer())\n : null;\n\n const headersState: HeadersState = { headers: new Map() };\n response.headers.forEach((value, key) => {\n const existing = headersState.headers.get(key.toLowerCase()) || [];\n existing.push(value);\n headersState.headers.set(key.toLowerCase(), existing);\n });\n\n // Detect body type from content-type header\n const contentType = response.headers.get(\"content-type\");\n let bodyType: \"string\" | \"binary\" | null = null;\n if (body) {\n if (contentType && (contentType.startsWith(\"text/\") || contentType.includes(\"json\") || contentType.includes(\"xml\"))) {\n bodyType = \"string\";\n } else {\n bodyType = \"binary\";\n }\n }\n\n return {\n status: response.status,\n statusText: response.statusText,\n headersState,\n body,\n bodyUsed: false,\n url: response.url,\n redirected: response.redirected,\n type: response.type,\n ok: response.ok,\n bodyType,\n };\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "253BFDBC49B0C92064756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "61E18893615E580364756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -36,6 +36,55 @@ module.exports = __toCommonJS(exports_handle);
36
36
  var import_quickjs_core = require("@ricsam/quickjs-core");
37
37
  var import_request = require("./globals/request.cjs");
38
38
  var import_response = require("./globals/response.cjs");
39
+ var import_headers = require("./globals/headers.cjs");
40
+ function createNativeStreamFromState(context, streamInstanceId) {
41
+ let done = false;
42
+ return new ReadableStream({
43
+ async pull(controller) {
44
+ while (!done) {
45
+ context.runtime.executePendingJobs();
46
+ const state = import_quickjs_core.getInstanceStateById(streamInstanceId);
47
+ if (!state) {
48
+ controller.close();
49
+ done = true;
50
+ return;
51
+ }
52
+ if (state.errored) {
53
+ controller.error(state.errorValue);
54
+ done = true;
55
+ return;
56
+ }
57
+ if (state.queue && state.queue.length > 0) {
58
+ const chunk = state.queue.shift();
59
+ let bytes;
60
+ if (chunk instanceof Uint8Array) {
61
+ bytes = chunk;
62
+ } else if (typeof chunk === "string") {
63
+ bytes = new TextEncoder().encode(chunk);
64
+ } else if (chunk && typeof chunk === "object" && "0" in chunk) {
65
+ const obj = chunk;
66
+ const keys = Object.keys(obj).filter((k) => !isNaN(parseInt(k))).sort((a, b) => parseInt(a) - parseInt(b));
67
+ const values = keys.map((k) => obj[k]);
68
+ bytes = new Uint8Array(values);
69
+ } else {
70
+ continue;
71
+ }
72
+ controller.enqueue(bytes);
73
+ return;
74
+ }
75
+ if (state.closeRequested || state.closed) {
76
+ controller.close();
77
+ done = true;
78
+ return;
79
+ }
80
+ await new Promise((r) => setTimeout(r, 0));
81
+ }
82
+ },
83
+ cancel() {
84
+ done = true;
85
+ }
86
+ });
87
+ }
39
88
  function createRequestInstance(context, stateMap, requestState) {
40
89
  const urlHandle = context.newString(requestState.url);
41
90
  context.setProp(context.global, "__requestUrl__", urlHandle);
@@ -110,6 +159,14 @@ function createFetchHandle(context, stateMap, serveState) {
110
159
  if (!responseState) {
111
160
  throw new Error("Failed to get Response state");
112
161
  }
162
+ if (responseState.bodyType === "stream" && responseState.streamInstanceId !== undefined) {
163
+ const nativeStream = createNativeStreamFromState(context, responseState.streamInstanceId);
164
+ return new Response(nativeStream, {
165
+ status: responseState.status,
166
+ statusText: responseState.statusText,
167
+ headers: import_headers.headersStateToNative(responseState.headersState)
168
+ });
169
+ }
113
170
  return import_response.responseStateToNative(responseState);
114
171
  } finally {
115
172
  requestHandle.dispose();
@@ -255,4 +312,4 @@ function createFetchHandle(context, stateMap, serveState) {
255
312
  }
256
313
  })
257
314
 
258
- //# debugId=CF7F460488EA084964756E2164756E21
315
+ //# debugId=113B81210C0C3D3264756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/handle.ts"],
4
4
  "sourcesContent": [
5
- "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { marshal, getInstanceState, setInstanceState } from \"@ricsam/quickjs-core\";\nimport type {\n StateMap,\n FetchHandle,\n ServeState,\n UpgradeRequest,\n WebSocketCommand,\n ServerWebSocketState,\n RequestState,\n ResponseState,\n} from \"./types.cjs\";\nimport { createRequestStateFromNative } from \"./globals/request.cjs\";\nimport { responseStateToNative } from \"./globals/response.cjs\";\n\n/**\n * Create a proper Request instance in QuickJS with the given state\n */\nfunction createRequestInstance(\n context: QuickJSContext,\n stateMap: StateMap,\n requestState: RequestState\n): QuickJSHandle {\n // Create the Request instance using evalCode (classes must be called with 'new')\n // Pass the URL as the constructor argument - minimal construction\n const urlHandle = context.newString(requestState.url);\n context.setProp(context.global, \"__requestUrl__\", urlHandle);\n urlHandle.dispose();\n\n const requestResult = context.evalCode(`new Request(__requestUrl__)`);\n\n // Clean up temporary global\n context.setProp(context.global, \"__requestUrl__\", context.undefined);\n\n if (requestResult.error) {\n const error = context.dump(requestResult.error);\n requestResult.error.dispose();\n throw new Error(`Failed to create Request: ${JSON.stringify(error)}`);\n }\n\n const requestHandle = requestResult.value;\n\n // Overwrite the internal state with our full RequestState\n setInstanceState(context, requestHandle, requestState);\n\n return requestHandle;\n}\n\n/**\n * Create the FetchHandle implementation\n */\nexport function createFetchHandle(\n context: QuickJSContext,\n stateMap: StateMap,\n serveState: ServeState\n): FetchHandle {\n const wsCommandCallbacks = new Set<(cmd: WebSocketCommand) => void>();\n\n return {\n stateMap,\n\n async dispatchRequest(request: Request): Promise<Response> {\n if (!serveState.fetchHandler) {\n throw new Error(\"No serve() handler registered\");\n }\n\n // Clear any previous upgrade request\n serveState.pendingUpgrade = null;\n\n // Convert native Request to RequestState\n const requestState = await createRequestStateFromNative(request);\n\n // Create proper QuickJS Request instance with internal state\n const requestHandle = createRequestInstance(context, stateMap, requestState);\n\n // Create Server instance using evalCode (classes must be called with 'new')\n const serverResult = context.evalCode(`new __Server__()`);\n if (serverResult.error) {\n requestHandle.dispose();\n const error = context.dump(serverResult.error);\n serverResult.error.dispose();\n throw new Error(`Failed to create Server: ${error}`);\n }\n const serverHandle = serverResult.value;\n\n try {\n // Call the fetch handler\n const result = context.callFunction(\n serveState.fetchHandler,\n context.undefined,\n requestHandle,\n serverHandle\n );\n\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Fetch handler error: ${JSON.stringify(error)}`);\n }\n\n let responseHandle = result.value;\n\n // Check if result is a Promise\n const typeofResult = context.typeof(responseHandle);\n if (typeofResult === \"object\") {\n // Check for .then method (Promise-like)\n const thenHandle = context.getProp(responseHandle, \"then\");\n const hasThen = context.typeof(thenHandle) === \"function\";\n thenHandle.dispose();\n\n if (hasThen) {\n // Execute pending jobs BEFORE resolvePromise to allow\n // JavaScript-native async functions to schedule their resolution.\n // This is critical for async functions that don't use host-side awaits.\n context.runtime.executePendingJobs();\n\n // For pure JS async functions (without host-side awaits), we need to\n // wrap resolvePromise in a race with repeated executePendingJobs calls.\n // The sync variant of QuickJS needs this to process microtasks.\n const resolved = await Promise.race([\n context.resolvePromise(responseHandle),\n (async () => {\n // Keep executing pending jobs until the promise resolves\n // This handles pure JS async functions that don't trigger host callbacks\n for (let i = 0; i < 1000; i++) {\n await new Promise((r) => setTimeout(r, 0));\n context.runtime.executePendingJobs();\n }\n // If we get here, something is very wrong\n throw new Error(\"Promise resolution timeout\");\n })(),\n ]);\n responseHandle.dispose();\n context.runtime.executePendingJobs();\n\n if (resolved.error) {\n const error = context.dump(resolved.error);\n resolved.error.dispose();\n throw new Error(`Fetch handler promise rejected: ${JSON.stringify(error)}`);\n }\n responseHandle = resolved.value;\n }\n }\n\n // Get the ResponseState directly from the instance\n const responseState = getInstanceState<ResponseState>(context, responseHandle);\n responseHandle.dispose();\n\n if (!responseState) {\n throw new Error(\"Failed to get Response state\");\n }\n\n // Convert to native Response\n return responseStateToNative(responseState);\n } finally {\n requestHandle.dispose();\n serverHandle.dispose();\n }\n },\n\n getUpgradeRequest(): UpgradeRequest | null {\n return serveState.pendingUpgrade;\n },\n\n /**\n * Dispatch WebSocket open event to the QuickJS handler.\n *\n * **IMPORTANT:** An `open` handler MUST be defined in the serve() websocket\n * options for the connection to be tracked. Without an open handler, the\n * connection is not stored and subsequent message/close/error events will\n * be silently ignored.\n *\n * @param connectionId - Unique identifier for this WebSocket connection (host-assigned)\n * @param data - Optional user data from server.upgrade() to associate with the connection\n */\n dispatchWebSocketOpen(connectionId: string, data?: unknown): void {\n if (!serveState.websocketHandlers.open) {\n return;\n }\n\n // Create ServerWebSocket instance using evalCode (classes must be called with 'new')\n // Pass arguments through temporary globals\n const connectionIdHandle = context.newString(connectionId);\n const dataHandle = marshal(context, data);\n context.setProp(context.global, \"__wsConnectionId__\", connectionIdHandle);\n context.setProp(context.global, \"__wsData__\", dataHandle);\n connectionIdHandle.dispose();\n dataHandle.dispose();\n\n const wsResult = context.evalCode(`new __ServerWebSocket__(__wsConnectionId__, __wsData__)`);\n\n // Clean up temporary globals\n context.setProp(context.global, \"__wsConnectionId__\", context.undefined);\n context.setProp(context.global, \"__wsData__\", context.undefined);\n\n if (wsResult.error) {\n wsResult.error.dispose();\n return;\n }\n\n const wsHandle = wsResult.value;\n\n // Store the connection\n serveState.activeConnections.set(connectionId, {\n data,\n readyState: 1,\n connectionId,\n wsHandle,\n });\n\n // Call the open handler\n const result = context.callFunction(\n serveState.websocketHandlers.open,\n context.undefined,\n wsHandle\n );\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Dispatch WebSocket message event to the QuickJS handler.\n *\n * Requires the connection to have been tracked via dispatchWebSocketOpen().\n * If no message handler is defined, or the connection is not tracked, this is a no-op.\n *\n * @param connectionId - The connection ID from dispatchWebSocketOpen()\n * @param message - The message content (string or binary data)\n */\n dispatchWebSocketMessage(\n connectionId: string,\n message: string | ArrayBuffer\n ): void {\n if (!serveState.websocketHandlers.message) {\n return;\n }\n\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n return;\n }\n\n const messageHandle =\n typeof message === \"string\"\n ? context.newString(message)\n : context.newArrayBuffer(message);\n\n const result = context.callFunction(\n serveState.websocketHandlers.message,\n context.undefined,\n connection.wsHandle,\n messageHandle\n );\n\n messageHandle.dispose();\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Dispatch WebSocket close event to the QuickJS handler and clean up the connection.\n *\n * Updates the connection ready state to CLOSED (3), calls the close handler if defined,\n * disposes the WebSocket handle, and removes the connection from tracking.\n *\n * @param connectionId - The connection ID from dispatchWebSocketOpen()\n * @param code - The WebSocket close code (e.g., 1000 for normal closure)\n * @param reason - The close reason string\n */\n dispatchWebSocketClose(\n connectionId: string,\n code: number,\n reason: string\n ): void {\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n serveState.activeConnections.delete(connectionId);\n return;\n }\n\n if (!serveState.websocketHandlers.close) {\n // No close handler, but still need to cleanup the connection\n connection.wsHandle.dispose();\n serveState.activeConnections.delete(connectionId);\n return;\n }\n\n // Update ready state\n connection.readyState = 3; // CLOSED\n\n const codeHandle = context.newNumber(code);\n const reasonHandle = context.newString(reason);\n\n const result = context.callFunction(\n serveState.websocketHandlers.close,\n context.undefined,\n connection.wsHandle,\n codeHandle,\n reasonHandle\n );\n\n codeHandle.dispose();\n reasonHandle.dispose();\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n // Cleanup\n connection.wsHandle.dispose();\n serveState.activeConnections.delete(connectionId);\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Dispatch WebSocket error event to the QuickJS handler.\n *\n * Requires the connection to have been tracked via dispatchWebSocketOpen().\n * If no error handler is defined, or the connection is not tracked, this is a no-op.\n *\n * @param connectionId - The connection ID from dispatchWebSocketOpen()\n * @param error - The error that occurred\n */\n dispatchWebSocketError(connectionId: string, error: Error): void {\n if (!serveState.websocketHandlers.error) {\n return;\n }\n\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n return;\n }\n\n const errorHandle = marshal(context, {\n name: error.name,\n message: error.message,\n });\n\n const result = context.callFunction(\n serveState.websocketHandlers.error,\n context.undefined,\n connection.wsHandle,\n errorHandle\n );\n\n errorHandle.dispose();\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Register a callback for outgoing WebSocket commands from QuickJS.\n *\n * Called when QuickJS code calls ws.send() or ws.close() on a ServerWebSocket.\n * The callback receives command objects that should be forwarded to the actual WebSocket.\n *\n * @param callback - Function to handle outgoing WebSocket commands\n * @returns Unsubscribe function to remove the callback\n */\n onWebSocketCommand(\n callback: (command: WebSocketCommand) => void\n ): () => void {\n wsCommandCallbacks.add(callback);\n return () => wsCommandCallbacks.delete(callback);\n },\n\n hasServeHandler(): boolean {\n return serveState.fetchHandler !== null;\n },\n\n dispose(): void {\n // Dispose WebSocket handler handles\n if (serveState.websocketHandlers.open) {\n serveState.websocketHandlers.open.dispose();\n serveState.websocketHandlers.open = undefined;\n }\n if (serveState.websocketHandlers.message) {\n serveState.websocketHandlers.message.dispose();\n serveState.websocketHandlers.message = undefined;\n }\n if (serveState.websocketHandlers.close) {\n serveState.websocketHandlers.close.dispose();\n serveState.websocketHandlers.close = undefined;\n }\n if (serveState.websocketHandlers.error) {\n serveState.websocketHandlers.error.dispose();\n serveState.websocketHandlers.error = undefined;\n }\n\n // Dispose fetch handler handle\n if (serveState.fetchHandler) {\n serveState.fetchHandler.dispose();\n serveState.fetchHandler = null;\n }\n\n // Dispose active WebSocket connection handles\n for (const connection of serveState.activeConnections.values()) {\n if (connection.wsHandle) {\n connection.wsHandle.dispose();\n }\n }\n serveState.activeConnections.clear();\n\n // Note: __Server__ and __ServerWebSocket__ are on global and will be cleaned up by context.dispose()\n },\n };\n}\n"
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { marshal, getInstanceState, setInstanceState, getInstanceStateById } from \"@ricsam/quickjs-core\";\nimport type {\n StateMap,\n FetchHandle,\n ServeState,\n UpgradeRequest,\n WebSocketCommand,\n ServerWebSocketState,\n RequestState,\n ResponseState,\n} from \"./types.cjs\";\nimport { createRequestStateFromNative } from \"./globals/request.cjs\";\nimport { responseStateToNative } from \"./globals/response.cjs\";\nimport { headersStateToNative } from \"./globals/headers.cjs\";\n\n/**\n * Internal state of a QuickJS ReadableStream\n * Used to directly access stream queue for bridging to native streams\n */\ninterface ReadableStreamInternalState {\n queue: unknown[];\n closeRequested: boolean;\n closed: boolean;\n errored: boolean;\n errorValue: unknown;\n}\n\n/**\n * Create a native ReadableStream that reads from a QuickJS stream's internal state\n * This avoids needing a QuickJS handle by directly accessing the stream's queue\n */\nfunction createNativeStreamFromState(\n context: QuickJSContext,\n streamInstanceId: number\n): ReadableStream<Uint8Array> {\n let done = false;\n\n return new ReadableStream<Uint8Array>({\n async pull(controller) {\n while (!done) {\n // Pump QuickJS event loop to process async writes\n context.runtime.executePendingJobs();\n\n const state = getInstanceStateById<ReadableStreamInternalState>(streamInstanceId);\n\n if (!state) {\n controller.close();\n done = true;\n return;\n }\n\n // Check for error\n if (state.errored) {\n controller.error(state.errorValue);\n done = true;\n return;\n }\n\n // Check for data in queue\n if (state.queue && state.queue.length > 0) {\n const chunk = state.queue.shift();\n\n // Convert chunk to Uint8Array\n let bytes: Uint8Array;\n if (chunk instanceof Uint8Array) {\n bytes = chunk;\n } else if (typeof chunk === \"string\") {\n bytes = new TextEncoder().encode(chunk);\n } else if (chunk && typeof chunk === \"object\" && \"0\" in chunk) {\n // Handle unmarshalled Uint8Array (object with numeric keys)\n const obj = chunk as Record<string, number>;\n const keys = Object.keys(obj).filter(k => !isNaN(parseInt(k))).sort((a, b) => parseInt(a) - parseInt(b));\n const values = keys.map(k => obj[k]) as number[];\n bytes = new Uint8Array(values);\n } else {\n // Skip unknown chunk types\n continue;\n }\n\n controller.enqueue(bytes);\n return;\n }\n\n // Check if closed\n if (state.closeRequested || state.closed) {\n controller.close();\n done = true;\n return;\n }\n\n // Yield to event loop, then poll again\n await new Promise(r => setTimeout(r, 0));\n }\n },\n\n cancel() {\n done = true;\n }\n });\n}\n\n/**\n * Create a proper Request instance in QuickJS with the given state\n */\nfunction createRequestInstance(\n context: QuickJSContext,\n stateMap: StateMap,\n requestState: RequestState\n): QuickJSHandle {\n // Create the Request instance using evalCode (classes must be called with 'new')\n // Pass the URL as the constructor argument - minimal construction\n const urlHandle = context.newString(requestState.url);\n context.setProp(context.global, \"__requestUrl__\", urlHandle);\n urlHandle.dispose();\n\n const requestResult = context.evalCode(`new Request(__requestUrl__)`);\n\n // Clean up temporary global\n context.setProp(context.global, \"__requestUrl__\", context.undefined);\n\n if (requestResult.error) {\n const error = context.dump(requestResult.error);\n requestResult.error.dispose();\n throw new Error(`Failed to create Request: ${JSON.stringify(error)}`);\n }\n\n const requestHandle = requestResult.value;\n\n // Overwrite the internal state with our full RequestState\n setInstanceState(context, requestHandle, requestState);\n\n return requestHandle;\n}\n\n/**\n * Create the FetchHandle implementation\n */\nexport function createFetchHandle(\n context: QuickJSContext,\n stateMap: StateMap,\n serveState: ServeState\n): FetchHandle {\n const wsCommandCallbacks = new Set<(cmd: WebSocketCommand) => void>();\n\n return {\n stateMap,\n\n async dispatchRequest(request: Request): Promise<Response> {\n if (!serveState.fetchHandler) {\n throw new Error(\"No serve() handler registered\");\n }\n\n // Clear any previous upgrade request\n serveState.pendingUpgrade = null;\n\n // Convert native Request to RequestState\n const requestState = await createRequestStateFromNative(request);\n\n // Create proper QuickJS Request instance with internal state\n const requestHandle = createRequestInstance(context, stateMap, requestState);\n\n // Create Server instance using evalCode (classes must be called with 'new')\n const serverResult = context.evalCode(`new __Server__()`);\n if (serverResult.error) {\n requestHandle.dispose();\n const error = context.dump(serverResult.error);\n serverResult.error.dispose();\n throw new Error(`Failed to create Server: ${error}`);\n }\n const serverHandle = serverResult.value;\n\n try {\n // Call the fetch handler\n const result = context.callFunction(\n serveState.fetchHandler,\n context.undefined,\n requestHandle,\n serverHandle\n );\n\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Fetch handler error: ${JSON.stringify(error)}`);\n }\n\n let responseHandle = result.value;\n\n // Check if result is a Promise\n const typeofResult = context.typeof(responseHandle);\n if (typeofResult === \"object\") {\n // Check for .then method (Promise-like)\n const thenHandle = context.getProp(responseHandle, \"then\");\n const hasThen = context.typeof(thenHandle) === \"function\";\n thenHandle.dispose();\n\n if (hasThen) {\n // Execute pending jobs BEFORE resolvePromise to allow\n // JavaScript-native async functions to schedule their resolution.\n // This is critical for async functions that don't use host-side awaits.\n context.runtime.executePendingJobs();\n\n // For pure JS async functions (without host-side awaits), we need to\n // wrap resolvePromise in a race with repeated executePendingJobs calls.\n // The sync variant of QuickJS needs this to process microtasks.\n const resolved = await Promise.race([\n context.resolvePromise(responseHandle),\n (async () => {\n // Keep executing pending jobs until the promise resolves\n // This handles pure JS async functions that don't trigger host callbacks\n for (let i = 0; i < 1000; i++) {\n await new Promise((r) => setTimeout(r, 0));\n context.runtime.executePendingJobs();\n }\n // If we get here, something is very wrong\n throw new Error(\"Promise resolution timeout\");\n })(),\n ]);\n responseHandle.dispose();\n context.runtime.executePendingJobs();\n\n if (resolved.error) {\n const error = context.dump(resolved.error);\n resolved.error.dispose();\n throw new Error(`Fetch handler promise rejected: ${JSON.stringify(error)}`);\n }\n responseHandle = resolved.value;\n }\n }\n\n // Get the ResponseState directly from the instance\n const responseState = getInstanceState<ResponseState>(context, responseHandle);\n responseHandle.dispose();\n\n if (!responseState) {\n throw new Error(\"Failed to get Response state\");\n }\n\n // Check if streaming response\n if (responseState.bodyType === \"stream\" && responseState.streamInstanceId !== undefined) {\n const nativeStream = createNativeStreamFromState(\n context,\n responseState.streamInstanceId\n );\n\n return new Response(nativeStream, {\n status: responseState.status,\n statusText: responseState.statusText,\n headers: headersStateToNative(responseState.headersState),\n });\n }\n\n // Convert to native Response (non-streaming)\n return responseStateToNative(responseState);\n } finally {\n requestHandle.dispose();\n serverHandle.dispose();\n }\n },\n\n getUpgradeRequest(): UpgradeRequest | null {\n return serveState.pendingUpgrade;\n },\n\n /**\n * Dispatch WebSocket open event to the QuickJS handler.\n *\n * **IMPORTANT:** An `open` handler MUST be defined in the serve() websocket\n * options for the connection to be tracked. Without an open handler, the\n * connection is not stored and subsequent message/close/error events will\n * be silently ignored.\n *\n * @param connectionId - Unique identifier for this WebSocket connection (host-assigned)\n * @param data - Optional user data from server.upgrade() to associate with the connection\n */\n dispatchWebSocketOpen(connectionId: string, data?: unknown): void {\n if (!serveState.websocketHandlers.open) {\n return;\n }\n\n // Create ServerWebSocket instance using evalCode (classes must be called with 'new')\n // Pass arguments through temporary globals\n const connectionIdHandle = context.newString(connectionId);\n const dataHandle = marshal(context, data);\n context.setProp(context.global, \"__wsConnectionId__\", connectionIdHandle);\n context.setProp(context.global, \"__wsData__\", dataHandle);\n connectionIdHandle.dispose();\n dataHandle.dispose();\n\n const wsResult = context.evalCode(`new __ServerWebSocket__(__wsConnectionId__, __wsData__)`);\n\n // Clean up temporary globals\n context.setProp(context.global, \"__wsConnectionId__\", context.undefined);\n context.setProp(context.global, \"__wsData__\", context.undefined);\n\n if (wsResult.error) {\n wsResult.error.dispose();\n return;\n }\n\n const wsHandle = wsResult.value;\n\n // Store the connection\n serveState.activeConnections.set(connectionId, {\n data,\n readyState: 1,\n connectionId,\n wsHandle,\n });\n\n // Call the open handler\n const result = context.callFunction(\n serveState.websocketHandlers.open,\n context.undefined,\n wsHandle\n );\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Dispatch WebSocket message event to the QuickJS handler.\n *\n * Requires the connection to have been tracked via dispatchWebSocketOpen().\n * If no message handler is defined, or the connection is not tracked, this is a no-op.\n *\n * @param connectionId - The connection ID from dispatchWebSocketOpen()\n * @param message - The message content (string or binary data)\n */\n dispatchWebSocketMessage(\n connectionId: string,\n message: string | ArrayBuffer\n ): void {\n if (!serveState.websocketHandlers.message) {\n return;\n }\n\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n return;\n }\n\n const messageHandle =\n typeof message === \"string\"\n ? context.newString(message)\n : context.newArrayBuffer(message);\n\n const result = context.callFunction(\n serveState.websocketHandlers.message,\n context.undefined,\n connection.wsHandle,\n messageHandle\n );\n\n messageHandle.dispose();\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Dispatch WebSocket close event to the QuickJS handler and clean up the connection.\n *\n * Updates the connection ready state to CLOSED (3), calls the close handler if defined,\n * disposes the WebSocket handle, and removes the connection from tracking.\n *\n * @param connectionId - The connection ID from dispatchWebSocketOpen()\n * @param code - The WebSocket close code (e.g., 1000 for normal closure)\n * @param reason - The close reason string\n */\n dispatchWebSocketClose(\n connectionId: string,\n code: number,\n reason: string\n ): void {\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n serveState.activeConnections.delete(connectionId);\n return;\n }\n\n if (!serveState.websocketHandlers.close) {\n // No close handler, but still need to cleanup the connection\n connection.wsHandle.dispose();\n serveState.activeConnections.delete(connectionId);\n return;\n }\n\n // Update ready state\n connection.readyState = 3; // CLOSED\n\n const codeHandle = context.newNumber(code);\n const reasonHandle = context.newString(reason);\n\n const result = context.callFunction(\n serveState.websocketHandlers.close,\n context.undefined,\n connection.wsHandle,\n codeHandle,\n reasonHandle\n );\n\n codeHandle.dispose();\n reasonHandle.dispose();\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n // Cleanup\n connection.wsHandle.dispose();\n serveState.activeConnections.delete(connectionId);\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Dispatch WebSocket error event to the QuickJS handler.\n *\n * Requires the connection to have been tracked via dispatchWebSocketOpen().\n * If no error handler is defined, or the connection is not tracked, this is a no-op.\n *\n * @param connectionId - The connection ID from dispatchWebSocketOpen()\n * @param error - The error that occurred\n */\n dispatchWebSocketError(connectionId: string, error: Error): void {\n if (!serveState.websocketHandlers.error) {\n return;\n }\n\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n return;\n }\n\n const errorHandle = marshal(context, {\n name: error.name,\n message: error.message,\n });\n\n const result = context.callFunction(\n serveState.websocketHandlers.error,\n context.undefined,\n connection.wsHandle,\n errorHandle\n );\n\n errorHandle.dispose();\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Register a callback for outgoing WebSocket commands from QuickJS.\n *\n * Called when QuickJS code calls ws.send() or ws.close() on a ServerWebSocket.\n * The callback receives command objects that should be forwarded to the actual WebSocket.\n *\n * @param callback - Function to handle outgoing WebSocket commands\n * @returns Unsubscribe function to remove the callback\n */\n onWebSocketCommand(\n callback: (command: WebSocketCommand) => void\n ): () => void {\n wsCommandCallbacks.add(callback);\n return () => wsCommandCallbacks.delete(callback);\n },\n\n hasServeHandler(): boolean {\n return serveState.fetchHandler !== null;\n },\n\n dispose(): void {\n // Dispose WebSocket handler handles\n if (serveState.websocketHandlers.open) {\n serveState.websocketHandlers.open.dispose();\n serveState.websocketHandlers.open = undefined;\n }\n if (serveState.websocketHandlers.message) {\n serveState.websocketHandlers.message.dispose();\n serveState.websocketHandlers.message = undefined;\n }\n if (serveState.websocketHandlers.close) {\n serveState.websocketHandlers.close.dispose();\n serveState.websocketHandlers.close = undefined;\n }\n if (serveState.websocketHandlers.error) {\n serveState.websocketHandlers.error.dispose();\n serveState.websocketHandlers.error = undefined;\n }\n\n // Dispose fetch handler handle\n if (serveState.fetchHandler) {\n serveState.fetchHandler.dispose();\n serveState.fetchHandler = null;\n }\n\n // Dispose active WebSocket connection handles\n for (const connection of serveState.activeConnections.values()) {\n if (connection.wsHandle) {\n connection.wsHandle.dispose();\n }\n }\n serveState.activeConnections.clear();\n\n // Note: __Server__ and __ServerWebSocket__ are on global and will be cleaned up by context.dispose()\n },\n };\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "CF7F460488EA084964756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "113B81210C0C3D3264756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/quickjs-fetch",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "type": "commonjs"
5
5
  }
@@ -11,6 +11,7 @@ function createResponseClass(context, stateMap, createStream) {
11
11
  const init = args[1];
12
12
  let body = null;
13
13
  let bodyType = null;
14
+ let streamInstanceId = undefined;
14
15
  const status = init?.status ?? 200;
15
16
  const statusText = init?.statusText ?? "";
16
17
  let headersState = { headers: new Map };
@@ -34,6 +35,11 @@ function createResponseClass(context, stateMap, createStream) {
34
35
  offset += part.length;
35
36
  }
36
37
  bodyType = "binary";
38
+ } else if (bodyInit && typeof bodyInit === "object" && "__isDefineClassInstance__" in bodyInit && bodyInit.__className__ === "ReadableStream") {
39
+ const streamInstance = bodyInit;
40
+ body = null;
41
+ bodyType = "stream";
42
+ streamInstanceId = streamInstance.__instanceId__;
37
43
  }
38
44
  }
39
45
  if (init?.headers) {
@@ -66,12 +72,16 @@ function createResponseClass(context, stateMap, createStream) {
66
72
  redirected: false,
67
73
  type: init?._type ?? "default",
68
74
  ok: status >= 200 && status < 300,
69
- bodyType
75
+ bodyType,
76
+ streamInstanceId
70
77
  };
71
78
  },
72
79
  properties: {
73
80
  body: {
74
81
  get() {
82
+ if (this.bodyType === "stream") {
83
+ return null;
84
+ }
75
85
  if (!this.body)
76
86
  return null;
77
87
  if (!createStream) {
@@ -161,6 +171,9 @@ function createResponseClass(context, stateMap, createStream) {
161
171
  if (this.bodyUsed) {
162
172
  throw new TypeError("Body has already been consumed");
163
173
  }
174
+ if (this.bodyType === "stream") {
175
+ throw new TypeError("Cannot clone Response with streaming body");
176
+ }
164
177
  return {
165
178
  ...this,
166
179
  headersState: {
@@ -206,6 +219,12 @@ function createResponseClass(context, stateMap, createStream) {
206
219
  return parseUrlEncodedFormData(this.body);
207
220
  }
208
221
  throw new TypeError("Could not parse content as FormData");
222
+ },
223
+ __isStreamBody__() {
224
+ return this.bodyType === "stream";
225
+ },
226
+ __getStreamInstanceId__() {
227
+ return this.streamInstanceId;
209
228
  }
210
229
  }
211
230
  });
@@ -246,8 +265,11 @@ function addResponseStaticMethods(context) {
246
265
  }
247
266
  }
248
267
  function responseStateToNative(state) {
249
- const bodyBytes = state.body ?? state.body;
250
268
  const bodyType = state.bodyType;
269
+ if (bodyType === "stream") {
270
+ throw new Error("Stream bodies must be handled at dispatch level - use dispatchRequest");
271
+ }
272
+ const bodyBytes = state.body ?? state.body;
251
273
  const status = state.status ?? 200;
252
274
  const statusText = state.statusText ?? "";
253
275
  let headersState;
@@ -315,4 +337,4 @@ export {
315
337
  addResponseStaticMethods
316
338
  };
317
339
 
318
- //# debugId=77C0707215771B4364756E2164756E21
340
+ //# debugId=F2F293354229811364756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/globals/response.ts"],
4
4
  "sourcesContent": [
5
- "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass, getInstanceStateById } from \"@ricsam/quickjs-core\";\nimport type { ResponseState, HeadersState, FormDataState } from \"../types.mjs\";\nimport { headersStateToNative, createHeadersLike } from \"./headers.mjs\";\nimport { parseMultipartFormData, parseUrlEncodedFormData } from \"./form-data.mjs\";\n\n/**\n * Type for the stream factory function\n */\ntype StreamFactory = (source: UnderlyingSource) => QuickJSHandle;\n\n/**\n * Create the Response class for QuickJS\n */\nexport function createResponseClass(\n context: QuickJSContext,\n stateMap: StateMap,\n createStream?: StreamFactory\n): QuickJSHandle {\n const classHandle = defineClass<ResponseState>(context, stateMap, {\n name: \"Response\",\n construct: (args) => {\n const bodyInit = args[0];\n const init = args[1] as {\n status?: number;\n statusText?: string;\n headers?: object;\n _type?: string; // Internal: for Response.error() to set type\n } | undefined;\n\n let body: Uint8Array | null = null;\n let bodyType: \"string\" | \"binary\" | null = null;\n const status = init?.status ?? 200;\n const statusText = init?.statusText ?? \"\";\n let headersState: HeadersState = { headers: new Map() };\n\n // Parse body\n if (bodyInit !== null && bodyInit !== undefined) {\n if (typeof bodyInit === \"string\") {\n body = new TextEncoder().encode(bodyInit);\n bodyType = \"string\";\n } else if (bodyInit instanceof ArrayBuffer) {\n body = new Uint8Array(bodyInit);\n bodyType = \"binary\";\n } else if (bodyInit instanceof Uint8Array) {\n body = bodyInit;\n bodyType = \"binary\";\n } else if (\n bodyInit &&\n typeof bodyInit === \"object\" &&\n \"parts\" in bodyInit\n ) {\n // Blob-like\n const parts = (bodyInit as { parts: Uint8Array[] }).parts;\n const totalLength = parts.reduce((sum, p) => sum + p.length, 0);\n 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 bodyType = \"binary\";\n }\n }\n\n // Parse headers\n if (init?.headers) {\n if (\n init.headers &&\n typeof init.headers === \"object\" &&\n \"headers\" in init.headers &&\n init.headers.headers instanceof Map\n ) {\n headersState = {\n headers: new Map((init.headers as HeadersState).headers),\n };\n } else if (\n init.headers &&\n typeof init.headers === \"object\" &&\n \"__isDefineClassInstance__\" in init.headers &&\n (init.headers as { __isDefineClassInstance__?: boolean }).__isDefineClassInstance__ === true &&\n \"__instanceId__\" in init.headers\n ) {\n // Unmarshalled Headers instance from defineClass\n const instanceId = (init.headers as { __instanceId__: number }).__instanceId__;\n const state = getInstanceStateById<HeadersState>(instanceId);\n if (state && state.headers instanceof Map) {\n headersState = {\n headers: new Map(state.headers),\n };\n }\n } else {\n headersState = { headers: new Map() };\n for (const [key, value] of Object.entries(init.headers)) {\n headersState.headers.set(key.toLowerCase(), [String(value)]);\n }\n }\n }\n\n return {\n status,\n statusText,\n headersState,\n body,\n bodyUsed: false,\n url: \"\",\n redirected: false,\n type: init?._type ?? \"default\",\n ok: status >= 200 && status < 300,\n bodyType,\n };\n },\n properties: {\n body: {\n get(this: ResponseState) {\n if (!this.body) return null;\n if (!createStream) {\n // Fallback: return raw body if no stream factory\n return this.body;\n }\n // Create a ReadableStream from the body data\n const bodyData = this.body;\n let offset = 0;\n const chunkSize = 65536; // 64KB chunks\n return createStream({\n pull(controller) {\n if (offset >= bodyData.length) {\n controller.close();\n return;\n }\n const chunk = bodyData.slice(offset, Math.min(offset + chunkSize, bodyData.length));\n offset += chunk.length;\n controller.enqueue(chunk);\n },\n });\n },\n },\n bodyUsed: {\n get(this: ResponseState) {\n return this.bodyUsed;\n },\n },\n headers: {\n get(this: ResponseState) {\n return createHeadersLike(this.headersState);\n },\n },\n ok: {\n get(this: ResponseState) {\n return this.ok;\n },\n },\n redirected: {\n get(this: ResponseState) {\n return this.redirected;\n },\n },\n status: {\n get(this: ResponseState) {\n return this.status;\n },\n },\n statusText: {\n get(this: ResponseState) {\n return this.statusText;\n },\n },\n type: {\n get(this: ResponseState) {\n return this.type;\n },\n },\n url: {\n get(this: ResponseState) {\n return this.url;\n },\n },\n },\n methods: {\n async arrayBuffer(this: ResponseState): Promise<ArrayBuffer> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return new ArrayBuffer(0);\n }\n return this.body.buffer.slice(\n this.body.byteOffset,\n this.body.byteOffset + this.body.byteLength\n ) as ArrayBuffer;\n },\n async blob(this: ResponseState): Promise<object> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n const contentType =\n this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n return {\n parts: this.body ? [this.body] : [],\n type: contentType,\n size: this.body?.length || 0,\n };\n },\n clone(this: ResponseState): ResponseState {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n return {\n ...this,\n headersState: {\n headers: new Map(this.headersState.headers),\n },\n body: this.body ? new Uint8Array(this.body) : null,\n bodyUsed: false,\n };\n },\n async json(this: ResponseState): Promise<unknown> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return JSON.parse(\"\");\n }\n const text = new TextDecoder().decode(this.body);\n return JSON.parse(text);\n },\n async text(this: ResponseState): Promise<string> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return \"\";\n }\n return new TextDecoder().decode(this.body);\n },\n async formData(this: ResponseState): Promise<FormDataState> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return { entries: [] };\n }\n\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n\n if (contentType.includes(\"multipart/form-data\")) {\n return parseMultipartFormData(this.body, contentType);\n } else if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n return parseUrlEncodedFormData(this.body);\n }\n\n throw new TypeError(\"Could not parse content as FormData\");\n },\n },\n });\n\n return classHandle;\n}\n\n/**\n * Add static methods to Response class after it's been set on global\n * This must be called after Response and Headers are available on global\n */\nexport function addResponseStaticMethods(context: QuickJSContext): void {\n const staticMethodsCode = `\n Response.error = function() {\n return new Response(null, { status: 0, _type: \"error\" });\n };\n\n Response.json = function(data, init = {}) {\n const body = JSON.stringify(data);\n // Merge content-type with any provided headers\n const headers = Object.assign(\n { \"content-type\": \"application/json\" },\n init.headers || {}\n );\n return new Response(body, {\n status: init.status ?? 200,\n statusText: init.statusText ?? \"\",\n headers: headers\n });\n };\n\n Response.redirect = function(url, status = 302) {\n return new Response(null, {\n status: status,\n headers: { \"location\": String(url) }\n });\n };\n `;\n const result = context.evalCode(staticMethodsCode);\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n}\n\n/**\n * Convert ResponseState (or unmarshalled Response object) to native Response\n */\nexport function responseStateToNative(state: ResponseState | Record<string, unknown>): Response {\n const bodyBytes = (state as ResponseState).body ?? (state as Record<string, unknown>).body;\n const bodyType = (state as ResponseState).bodyType;\n const status = (state as ResponseState).status ?? 200;\n const statusText = (state as ResponseState).statusText ?? \"\";\n\n // Handle both headersState (internal) and headers (from getter)\n let headersState: HeadersState;\n if ((state as ResponseState).headersState) {\n headersState = (state as ResponseState).headersState;\n } else if ((state as Record<string, unknown>).headers) {\n // When unmarshalled, headers is the HeadersLike object from getter\n const headers = (state as Record<string, unknown>).headers as { headers?: Map<string, string[]> };\n if (headers.headers instanceof Map) {\n headersState = { headers: headers.headers };\n } else {\n headersState = { headers: new Map() };\n }\n } else {\n headersState = { headers: new Map() };\n }\n\n // Convert body back to string if it was originally a string\n // This ensures Bun.serve doesn't add application/octet-stream content-type\n let body: BodyInit | null = null;\n if (bodyBytes) {\n if (bodyType === \"string\") {\n body = new TextDecoder().decode(bodyBytes as Uint8Array);\n } else {\n // Cast to ArrayBuffer which is a valid BodyInit type\n const uint8 = bodyBytes as Uint8Array;\n body = uint8.buffer.slice(uint8.byteOffset, uint8.byteOffset + uint8.byteLength) as ArrayBuffer;\n }\n }\n\n return new Response(body, {\n status,\n statusText,\n headers: headersStateToNative(headersState),\n });\n}\n\n/**\n * Create a ResponseState from a native Response\n */\nexport async function createResponseStateFromNative(\n response: Response\n): Promise<ResponseState> {\n const body = response.body\n ? new Uint8Array(await response.arrayBuffer())\n : null;\n\n const headersState: HeadersState = { headers: new Map() };\n response.headers.forEach((value, key) => {\n const existing = headersState.headers.get(key.toLowerCase()) || [];\n existing.push(value);\n headersState.headers.set(key.toLowerCase(), existing);\n });\n\n // Detect body type from content-type header\n const contentType = response.headers.get(\"content-type\");\n let bodyType: \"string\" | \"binary\" | null = null;\n if (body) {\n if (contentType && (contentType.startsWith(\"text/\") || contentType.includes(\"json\") || contentType.includes(\"xml\"))) {\n bodyType = \"string\";\n } else {\n bodyType = \"binary\";\n }\n }\n\n return {\n status: response.status,\n statusText: response.statusText,\n headersState,\n body,\n bodyUsed: false,\n url: response.url,\n redirected: response.redirected,\n type: response.type,\n ok: response.ok,\n bodyType,\n };\n}\n"
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass, getInstanceStateById } from \"@ricsam/quickjs-core\";\nimport type { ResponseState, HeadersState, FormDataState } from \"../types.mjs\";\nimport { headersStateToNative, createHeadersLike } from \"./headers.mjs\";\nimport { parseMultipartFormData, parseUrlEncodedFormData } from \"./form-data.mjs\";\n\n/**\n * Type for the stream factory function\n */\ntype StreamFactory = (source: UnderlyingSource) => QuickJSHandle;\n\n/**\n * Create the Response class for QuickJS\n */\nexport function createResponseClass(\n context: QuickJSContext,\n stateMap: StateMap,\n createStream?: StreamFactory\n): QuickJSHandle {\n const classHandle = defineClass<ResponseState>(context, stateMap, {\n name: \"Response\",\n construct: (args) => {\n const bodyInit = args[0];\n const init = args[1] as {\n status?: number;\n statusText?: string;\n headers?: object;\n _type?: string; // Internal: for Response.error() to set type\n } | undefined;\n\n let body: Uint8Array | null = null;\n let bodyType: \"string\" | \"binary\" | \"stream\" | null = null;\n let streamInstanceId: number | undefined = undefined;\n const status = init?.status ?? 200;\n const statusText = init?.statusText ?? \"\";\n let headersState: HeadersState = { headers: new Map() };\n\n // Parse body\n if (bodyInit !== null && bodyInit !== undefined) {\n if (typeof bodyInit === \"string\") {\n body = new TextEncoder().encode(bodyInit);\n bodyType = \"string\";\n } else if (bodyInit instanceof ArrayBuffer) {\n body = new Uint8Array(bodyInit);\n bodyType = \"binary\";\n } else if (bodyInit instanceof Uint8Array) {\n body = bodyInit;\n bodyType = \"binary\";\n } else if (\n bodyInit &&\n typeof bodyInit === \"object\" &&\n \"parts\" in bodyInit\n ) {\n // Blob-like\n const parts = (bodyInit as { parts: Uint8Array[] }).parts;\n const totalLength = parts.reduce((sum, p) => sum + p.length, 0);\n 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 bodyType = \"binary\";\n } else if (\n bodyInit &&\n typeof bodyInit === \"object\" &&\n \"__isDefineClassInstance__\" in bodyInit &&\n (bodyInit as { __className__?: string }).__className__ === \"ReadableStream\"\n ) {\n // ReadableStream body - don't buffer, store instance ID for later consumption\n const streamInstance = bodyInit as {\n __instanceId__: number;\n __className__: string;\n __isDefineClassInstance__: true;\n };\n body = null;\n bodyType = \"stream\";\n streamInstanceId = streamInstance.__instanceId__;\n }\n }\n\n // Parse headers\n if (init?.headers) {\n if (\n init.headers &&\n typeof init.headers === \"object\" &&\n \"headers\" in init.headers &&\n init.headers.headers instanceof Map\n ) {\n headersState = {\n headers: new Map((init.headers as HeadersState).headers),\n };\n } else if (\n init.headers &&\n typeof init.headers === \"object\" &&\n \"__isDefineClassInstance__\" in init.headers &&\n (init.headers as { __isDefineClassInstance__?: boolean }).__isDefineClassInstance__ === true &&\n \"__instanceId__\" in init.headers\n ) {\n // Unmarshalled Headers instance from defineClass\n const instanceId = (init.headers as { __instanceId__: number }).__instanceId__;\n const state = getInstanceStateById<HeadersState>(instanceId);\n if (state && state.headers instanceof Map) {\n headersState = {\n headers: new Map(state.headers),\n };\n }\n } else {\n headersState = { headers: new Map() };\n for (const [key, value] of Object.entries(init.headers)) {\n headersState.headers.set(key.toLowerCase(), [String(value)]);\n }\n }\n }\n\n return {\n status,\n statusText,\n headersState,\n body,\n bodyUsed: false,\n url: \"\",\n redirected: false,\n type: init?._type ?? \"default\",\n ok: status >= 200 && status < 300,\n bodyType,\n streamInstanceId,\n };\n },\n properties: {\n body: {\n get(this: ResponseState) {\n // Stream body - return null (stream is stored by instanceId)\n // dispatchRequest will handle stream extraction\n if (this.bodyType === \"stream\") {\n return null;\n }\n\n if (!this.body) return null;\n if (!createStream) {\n // Fallback: return raw body if no stream factory\n return this.body;\n }\n // Create a ReadableStream from the body data\n const bodyData = this.body;\n let offset = 0;\n const chunkSize = 65536; // 64KB chunks\n return createStream({\n pull(controller) {\n if (offset >= bodyData.length) {\n controller.close();\n return;\n }\n const chunk = bodyData.slice(offset, Math.min(offset + chunkSize, bodyData.length));\n offset += chunk.length;\n controller.enqueue(chunk);\n },\n });\n },\n },\n bodyUsed: {\n get(this: ResponseState) {\n return this.bodyUsed;\n },\n },\n headers: {\n get(this: ResponseState) {\n return createHeadersLike(this.headersState);\n },\n },\n ok: {\n get(this: ResponseState) {\n return this.ok;\n },\n },\n redirected: {\n get(this: ResponseState) {\n return this.redirected;\n },\n },\n status: {\n get(this: ResponseState) {\n return this.status;\n },\n },\n statusText: {\n get(this: ResponseState) {\n return this.statusText;\n },\n },\n type: {\n get(this: ResponseState) {\n return this.type;\n },\n },\n url: {\n get(this: ResponseState) {\n return this.url;\n },\n },\n },\n methods: {\n async arrayBuffer(this: ResponseState): Promise<ArrayBuffer> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return new ArrayBuffer(0);\n }\n return this.body.buffer.slice(\n this.body.byteOffset,\n this.body.byteOffset + this.body.byteLength\n ) as ArrayBuffer;\n },\n async blob(this: ResponseState): Promise<object> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n const contentType =\n this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n return {\n parts: this.body ? [this.body] : [],\n type: contentType,\n size: this.body?.length || 0,\n };\n },\n clone(this: ResponseState): ResponseState {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n if (this.bodyType === \"stream\") {\n throw new TypeError(\"Cannot clone Response with streaming body\");\n }\n return {\n ...this,\n headersState: {\n headers: new Map(this.headersState.headers),\n },\n body: this.body ? new Uint8Array(this.body) : null,\n bodyUsed: false,\n };\n },\n async json(this: ResponseState): Promise<unknown> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return JSON.parse(\"\");\n }\n const text = new TextDecoder().decode(this.body);\n return JSON.parse(text);\n },\n async text(this: ResponseState): Promise<string> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return \"\";\n }\n return new TextDecoder().decode(this.body);\n },\n async formData(this: ResponseState): Promise<FormDataState> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return { entries: [] };\n }\n\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n\n if (contentType.includes(\"multipart/form-data\")) {\n return parseMultipartFormData(this.body, contentType);\n } else if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n return parseUrlEncodedFormData(this.body);\n }\n\n throw new TypeError(\"Could not parse content as FormData\");\n },\n __isStreamBody__(this: ResponseState): boolean {\n return this.bodyType === \"stream\";\n },\n __getStreamInstanceId__(this: ResponseState): number | undefined {\n return this.streamInstanceId;\n },\n },\n });\n\n return classHandle;\n}\n\n/**\n * Add static methods to Response class after it's been set on global\n * This must be called after Response and Headers are available on global\n */\nexport function addResponseStaticMethods(context: QuickJSContext): void {\n const staticMethodsCode = `\n Response.error = function() {\n return new Response(null, { status: 0, _type: \"error\" });\n };\n\n Response.json = function(data, init = {}) {\n const body = JSON.stringify(data);\n // Merge content-type with any provided headers\n const headers = Object.assign(\n { \"content-type\": \"application/json\" },\n init.headers || {}\n );\n return new Response(body, {\n status: init.status ?? 200,\n statusText: init.statusText ?? \"\",\n headers: headers\n });\n };\n\n Response.redirect = function(url, status = 302) {\n return new Response(null, {\n status: status,\n headers: { \"location\": String(url) }\n });\n };\n `;\n const result = context.evalCode(staticMethodsCode);\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n}\n\n/**\n * Convert ResponseState (or unmarshalled Response object) to native Response\n */\nexport function responseStateToNative(state: ResponseState | Record<string, unknown>): Response {\n const bodyType = (state as ResponseState).bodyType;\n\n // Stream bodies are handled by dispatchRequest directly\n if (bodyType === \"stream\") {\n throw new Error(\"Stream bodies must be handled at dispatch level - use dispatchRequest\");\n }\n\n const bodyBytes = (state as ResponseState).body ?? (state as Record<string, unknown>).body;\n const status = (state as ResponseState).status ?? 200;\n const statusText = (state as ResponseState).statusText ?? \"\";\n\n // Handle both headersState (internal) and headers (from getter)\n let headersState: HeadersState;\n if ((state as ResponseState).headersState) {\n headersState = (state as ResponseState).headersState;\n } else if ((state as Record<string, unknown>).headers) {\n // When unmarshalled, headers is the HeadersLike object from getter\n const headers = (state as Record<string, unknown>).headers as { headers?: Map<string, string[]> };\n if (headers.headers instanceof Map) {\n headersState = { headers: headers.headers };\n } else {\n headersState = { headers: new Map() };\n }\n } else {\n headersState = { headers: new Map() };\n }\n\n // Convert body back to string if it was originally a string\n // This ensures Bun.serve doesn't add application/octet-stream content-type\n let body: BodyInit | null = null;\n if (bodyBytes) {\n if (bodyType === \"string\") {\n body = new TextDecoder().decode(bodyBytes as Uint8Array);\n } else {\n // Cast to ArrayBuffer which is a valid BodyInit type\n const uint8 = bodyBytes as Uint8Array;\n body = uint8.buffer.slice(uint8.byteOffset, uint8.byteOffset + uint8.byteLength) as ArrayBuffer;\n }\n }\n\n return new Response(body, {\n status,\n statusText,\n headers: headersStateToNative(headersState),\n });\n}\n\n/**\n * Create a ResponseState from a native Response\n */\nexport async function createResponseStateFromNative(\n response: Response\n): Promise<ResponseState> {\n const body = response.body\n ? new Uint8Array(await response.arrayBuffer())\n : null;\n\n const headersState: HeadersState = { headers: new Map() };\n response.headers.forEach((value, key) => {\n const existing = headersState.headers.get(key.toLowerCase()) || [];\n existing.push(value);\n headersState.headers.set(key.toLowerCase(), existing);\n });\n\n // Detect body type from content-type header\n const contentType = response.headers.get(\"content-type\");\n let bodyType: \"string\" | \"binary\" | null = null;\n if (body) {\n if (contentType && (contentType.startsWith(\"text/\") || contentType.includes(\"json\") || contentType.includes(\"xml\"))) {\n bodyType = \"string\";\n } else {\n bodyType = \"binary\";\n }\n }\n\n return {\n status: response.status,\n statusText: response.statusText,\n headersState,\n body,\n bodyUsed: false,\n url: response.url,\n redirected: response.redirected,\n type: response.type,\n ok: response.ok,\n bodyType,\n };\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "77C0707215771B4364756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "F2F293354229811364756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,8 +1,57 @@
1
1
  // @bun
2
2
  // packages/fetch/src/handle.ts
3
- import { marshal, getInstanceState, setInstanceState } from "@ricsam/quickjs-core";
3
+ import { marshal, getInstanceState, setInstanceState, getInstanceStateById } from "@ricsam/quickjs-core";
4
4
  import { createRequestStateFromNative } from "./globals/request.mjs";
5
5
  import { responseStateToNative } from "./globals/response.mjs";
6
+ import { headersStateToNative } from "./globals/headers.mjs";
7
+ function createNativeStreamFromState(context, streamInstanceId) {
8
+ let done = false;
9
+ return new ReadableStream({
10
+ async pull(controller) {
11
+ while (!done) {
12
+ context.runtime.executePendingJobs();
13
+ const state = getInstanceStateById(streamInstanceId);
14
+ if (!state) {
15
+ controller.close();
16
+ done = true;
17
+ return;
18
+ }
19
+ if (state.errored) {
20
+ controller.error(state.errorValue);
21
+ done = true;
22
+ return;
23
+ }
24
+ if (state.queue && state.queue.length > 0) {
25
+ const chunk = state.queue.shift();
26
+ let bytes;
27
+ if (chunk instanceof Uint8Array) {
28
+ bytes = chunk;
29
+ } else if (typeof chunk === "string") {
30
+ bytes = new TextEncoder().encode(chunk);
31
+ } else if (chunk && typeof chunk === "object" && "0" in chunk) {
32
+ const obj = chunk;
33
+ const keys = Object.keys(obj).filter((k) => !isNaN(parseInt(k))).sort((a, b) => parseInt(a) - parseInt(b));
34
+ const values = keys.map((k) => obj[k]);
35
+ bytes = new Uint8Array(values);
36
+ } else {
37
+ continue;
38
+ }
39
+ controller.enqueue(bytes);
40
+ return;
41
+ }
42
+ if (state.closeRequested || state.closed) {
43
+ controller.close();
44
+ done = true;
45
+ return;
46
+ }
47
+ await new Promise((r) => setTimeout(r, 0));
48
+ }
49
+ },
50
+ cancel() {
51
+ done = true;
52
+ }
53
+ });
54
+ }
6
55
  function createRequestInstance(context, stateMap, requestState) {
7
56
  const urlHandle = context.newString(requestState.url);
8
57
  context.setProp(context.global, "__requestUrl__", urlHandle);
@@ -77,6 +126,14 @@ function createFetchHandle(context, stateMap, serveState) {
77
126
  if (!responseState) {
78
127
  throw new Error("Failed to get Response state");
79
128
  }
129
+ if (responseState.bodyType === "stream" && responseState.streamInstanceId !== undefined) {
130
+ const nativeStream = createNativeStreamFromState(context, responseState.streamInstanceId);
131
+ return new Response(nativeStream, {
132
+ status: responseState.status,
133
+ statusText: responseState.statusText,
134
+ headers: headersStateToNative(responseState.headersState)
135
+ });
136
+ }
80
137
  return responseStateToNative(responseState);
81
138
  } finally {
82
139
  requestHandle.dispose();
@@ -224,4 +281,4 @@ export {
224
281
  createFetchHandle
225
282
  };
226
283
 
227
- //# debugId=C4B0D934788B3BC064756E2164756E21
284
+ //# debugId=ED91E5C4CED38FC864756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/handle.ts"],
4
4
  "sourcesContent": [
5
- "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { marshal, getInstanceState, setInstanceState } from \"@ricsam/quickjs-core\";\nimport type {\n StateMap,\n FetchHandle,\n ServeState,\n UpgradeRequest,\n WebSocketCommand,\n ServerWebSocketState,\n RequestState,\n ResponseState,\n} from \"./types.mjs\";\nimport { createRequestStateFromNative } from \"./globals/request.mjs\";\nimport { responseStateToNative } from \"./globals/response.mjs\";\n\n/**\n * Create a proper Request instance in QuickJS with the given state\n */\nfunction createRequestInstance(\n context: QuickJSContext,\n stateMap: StateMap,\n requestState: RequestState\n): QuickJSHandle {\n // Create the Request instance using evalCode (classes must be called with 'new')\n // Pass the URL as the constructor argument - minimal construction\n const urlHandle = context.newString(requestState.url);\n context.setProp(context.global, \"__requestUrl__\", urlHandle);\n urlHandle.dispose();\n\n const requestResult = context.evalCode(`new Request(__requestUrl__)`);\n\n // Clean up temporary global\n context.setProp(context.global, \"__requestUrl__\", context.undefined);\n\n if (requestResult.error) {\n const error = context.dump(requestResult.error);\n requestResult.error.dispose();\n throw new Error(`Failed to create Request: ${JSON.stringify(error)}`);\n }\n\n const requestHandle = requestResult.value;\n\n // Overwrite the internal state with our full RequestState\n setInstanceState(context, requestHandle, requestState);\n\n return requestHandle;\n}\n\n/**\n * Create the FetchHandle implementation\n */\nexport function createFetchHandle(\n context: QuickJSContext,\n stateMap: StateMap,\n serveState: ServeState\n): FetchHandle {\n const wsCommandCallbacks = new Set<(cmd: WebSocketCommand) => void>();\n\n return {\n stateMap,\n\n async dispatchRequest(request: Request): Promise<Response> {\n if (!serveState.fetchHandler) {\n throw new Error(\"No serve() handler registered\");\n }\n\n // Clear any previous upgrade request\n serveState.pendingUpgrade = null;\n\n // Convert native Request to RequestState\n const requestState = await createRequestStateFromNative(request);\n\n // Create proper QuickJS Request instance with internal state\n const requestHandle = createRequestInstance(context, stateMap, requestState);\n\n // Create Server instance using evalCode (classes must be called with 'new')\n const serverResult = context.evalCode(`new __Server__()`);\n if (serverResult.error) {\n requestHandle.dispose();\n const error = context.dump(serverResult.error);\n serverResult.error.dispose();\n throw new Error(`Failed to create Server: ${error}`);\n }\n const serverHandle = serverResult.value;\n\n try {\n // Call the fetch handler\n const result = context.callFunction(\n serveState.fetchHandler,\n context.undefined,\n requestHandle,\n serverHandle\n );\n\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Fetch handler error: ${JSON.stringify(error)}`);\n }\n\n let responseHandle = result.value;\n\n // Check if result is a Promise\n const typeofResult = context.typeof(responseHandle);\n if (typeofResult === \"object\") {\n // Check for .then method (Promise-like)\n const thenHandle = context.getProp(responseHandle, \"then\");\n const hasThen = context.typeof(thenHandle) === \"function\";\n thenHandle.dispose();\n\n if (hasThen) {\n // Execute pending jobs BEFORE resolvePromise to allow\n // JavaScript-native async functions to schedule their resolution.\n // This is critical for async functions that don't use host-side awaits.\n context.runtime.executePendingJobs();\n\n // For pure JS async functions (without host-side awaits), we need to\n // wrap resolvePromise in a race with repeated executePendingJobs calls.\n // The sync variant of QuickJS needs this to process microtasks.\n const resolved = await Promise.race([\n context.resolvePromise(responseHandle),\n (async () => {\n // Keep executing pending jobs until the promise resolves\n // This handles pure JS async functions that don't trigger host callbacks\n for (let i = 0; i < 1000; i++) {\n await new Promise((r) => setTimeout(r, 0));\n context.runtime.executePendingJobs();\n }\n // If we get here, something is very wrong\n throw new Error(\"Promise resolution timeout\");\n })(),\n ]);\n responseHandle.dispose();\n context.runtime.executePendingJobs();\n\n if (resolved.error) {\n const error = context.dump(resolved.error);\n resolved.error.dispose();\n throw new Error(`Fetch handler promise rejected: ${JSON.stringify(error)}`);\n }\n responseHandle = resolved.value;\n }\n }\n\n // Get the ResponseState directly from the instance\n const responseState = getInstanceState<ResponseState>(context, responseHandle);\n responseHandle.dispose();\n\n if (!responseState) {\n throw new Error(\"Failed to get Response state\");\n }\n\n // Convert to native Response\n return responseStateToNative(responseState);\n } finally {\n requestHandle.dispose();\n serverHandle.dispose();\n }\n },\n\n getUpgradeRequest(): UpgradeRequest | null {\n return serveState.pendingUpgrade;\n },\n\n /**\n * Dispatch WebSocket open event to the QuickJS handler.\n *\n * **IMPORTANT:** An `open` handler MUST be defined in the serve() websocket\n * options for the connection to be tracked. Without an open handler, the\n * connection is not stored and subsequent message/close/error events will\n * be silently ignored.\n *\n * @param connectionId - Unique identifier for this WebSocket connection (host-assigned)\n * @param data - Optional user data from server.upgrade() to associate with the connection\n */\n dispatchWebSocketOpen(connectionId: string, data?: unknown): void {\n if (!serveState.websocketHandlers.open) {\n return;\n }\n\n // Create ServerWebSocket instance using evalCode (classes must be called with 'new')\n // Pass arguments through temporary globals\n const connectionIdHandle = context.newString(connectionId);\n const dataHandle = marshal(context, data);\n context.setProp(context.global, \"__wsConnectionId__\", connectionIdHandle);\n context.setProp(context.global, \"__wsData__\", dataHandle);\n connectionIdHandle.dispose();\n dataHandle.dispose();\n\n const wsResult = context.evalCode(`new __ServerWebSocket__(__wsConnectionId__, __wsData__)`);\n\n // Clean up temporary globals\n context.setProp(context.global, \"__wsConnectionId__\", context.undefined);\n context.setProp(context.global, \"__wsData__\", context.undefined);\n\n if (wsResult.error) {\n wsResult.error.dispose();\n return;\n }\n\n const wsHandle = wsResult.value;\n\n // Store the connection\n serveState.activeConnections.set(connectionId, {\n data,\n readyState: 1,\n connectionId,\n wsHandle,\n });\n\n // Call the open handler\n const result = context.callFunction(\n serveState.websocketHandlers.open,\n context.undefined,\n wsHandle\n );\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Dispatch WebSocket message event to the QuickJS handler.\n *\n * Requires the connection to have been tracked via dispatchWebSocketOpen().\n * If no message handler is defined, or the connection is not tracked, this is a no-op.\n *\n * @param connectionId - The connection ID from dispatchWebSocketOpen()\n * @param message - The message content (string or binary data)\n */\n dispatchWebSocketMessage(\n connectionId: string,\n message: string | ArrayBuffer\n ): void {\n if (!serveState.websocketHandlers.message) {\n return;\n }\n\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n return;\n }\n\n const messageHandle =\n typeof message === \"string\"\n ? context.newString(message)\n : context.newArrayBuffer(message);\n\n const result = context.callFunction(\n serveState.websocketHandlers.message,\n context.undefined,\n connection.wsHandle,\n messageHandle\n );\n\n messageHandle.dispose();\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Dispatch WebSocket close event to the QuickJS handler and clean up the connection.\n *\n * Updates the connection ready state to CLOSED (3), calls the close handler if defined,\n * disposes the WebSocket handle, and removes the connection from tracking.\n *\n * @param connectionId - The connection ID from dispatchWebSocketOpen()\n * @param code - The WebSocket close code (e.g., 1000 for normal closure)\n * @param reason - The close reason string\n */\n dispatchWebSocketClose(\n connectionId: string,\n code: number,\n reason: string\n ): void {\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n serveState.activeConnections.delete(connectionId);\n return;\n }\n\n if (!serveState.websocketHandlers.close) {\n // No close handler, but still need to cleanup the connection\n connection.wsHandle.dispose();\n serveState.activeConnections.delete(connectionId);\n return;\n }\n\n // Update ready state\n connection.readyState = 3; // CLOSED\n\n const codeHandle = context.newNumber(code);\n const reasonHandle = context.newString(reason);\n\n const result = context.callFunction(\n serveState.websocketHandlers.close,\n context.undefined,\n connection.wsHandle,\n codeHandle,\n reasonHandle\n );\n\n codeHandle.dispose();\n reasonHandle.dispose();\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n // Cleanup\n connection.wsHandle.dispose();\n serveState.activeConnections.delete(connectionId);\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Dispatch WebSocket error event to the QuickJS handler.\n *\n * Requires the connection to have been tracked via dispatchWebSocketOpen().\n * If no error handler is defined, or the connection is not tracked, this is a no-op.\n *\n * @param connectionId - The connection ID from dispatchWebSocketOpen()\n * @param error - The error that occurred\n */\n dispatchWebSocketError(connectionId: string, error: Error): void {\n if (!serveState.websocketHandlers.error) {\n return;\n }\n\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n return;\n }\n\n const errorHandle = marshal(context, {\n name: error.name,\n message: error.message,\n });\n\n const result = context.callFunction(\n serveState.websocketHandlers.error,\n context.undefined,\n connection.wsHandle,\n errorHandle\n );\n\n errorHandle.dispose();\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Register a callback for outgoing WebSocket commands from QuickJS.\n *\n * Called when QuickJS code calls ws.send() or ws.close() on a ServerWebSocket.\n * The callback receives command objects that should be forwarded to the actual WebSocket.\n *\n * @param callback - Function to handle outgoing WebSocket commands\n * @returns Unsubscribe function to remove the callback\n */\n onWebSocketCommand(\n callback: (command: WebSocketCommand) => void\n ): () => void {\n wsCommandCallbacks.add(callback);\n return () => wsCommandCallbacks.delete(callback);\n },\n\n hasServeHandler(): boolean {\n return serveState.fetchHandler !== null;\n },\n\n dispose(): void {\n // Dispose WebSocket handler handles\n if (serveState.websocketHandlers.open) {\n serveState.websocketHandlers.open.dispose();\n serveState.websocketHandlers.open = undefined;\n }\n if (serveState.websocketHandlers.message) {\n serveState.websocketHandlers.message.dispose();\n serveState.websocketHandlers.message = undefined;\n }\n if (serveState.websocketHandlers.close) {\n serveState.websocketHandlers.close.dispose();\n serveState.websocketHandlers.close = undefined;\n }\n if (serveState.websocketHandlers.error) {\n serveState.websocketHandlers.error.dispose();\n serveState.websocketHandlers.error = undefined;\n }\n\n // Dispose fetch handler handle\n if (serveState.fetchHandler) {\n serveState.fetchHandler.dispose();\n serveState.fetchHandler = null;\n }\n\n // Dispose active WebSocket connection handles\n for (const connection of serveState.activeConnections.values()) {\n if (connection.wsHandle) {\n connection.wsHandle.dispose();\n }\n }\n serveState.activeConnections.clear();\n\n // Note: __Server__ and __ServerWebSocket__ are on global and will be cleaned up by context.dispose()\n },\n };\n}\n"
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { marshal, getInstanceState, setInstanceState, getInstanceStateById } from \"@ricsam/quickjs-core\";\nimport type {\n StateMap,\n FetchHandle,\n ServeState,\n UpgradeRequest,\n WebSocketCommand,\n ServerWebSocketState,\n RequestState,\n ResponseState,\n} from \"./types.mjs\";\nimport { createRequestStateFromNative } from \"./globals/request.mjs\";\nimport { responseStateToNative } from \"./globals/response.mjs\";\nimport { headersStateToNative } from \"./globals/headers.mjs\";\n\n/**\n * Internal state of a QuickJS ReadableStream\n * Used to directly access stream queue for bridging to native streams\n */\ninterface ReadableStreamInternalState {\n queue: unknown[];\n closeRequested: boolean;\n closed: boolean;\n errored: boolean;\n errorValue: unknown;\n}\n\n/**\n * Create a native ReadableStream that reads from a QuickJS stream's internal state\n * This avoids needing a QuickJS handle by directly accessing the stream's queue\n */\nfunction createNativeStreamFromState(\n context: QuickJSContext,\n streamInstanceId: number\n): ReadableStream<Uint8Array> {\n let done = false;\n\n return new ReadableStream<Uint8Array>({\n async pull(controller) {\n while (!done) {\n // Pump QuickJS event loop to process async writes\n context.runtime.executePendingJobs();\n\n const state = getInstanceStateById<ReadableStreamInternalState>(streamInstanceId);\n\n if (!state) {\n controller.close();\n done = true;\n return;\n }\n\n // Check for error\n if (state.errored) {\n controller.error(state.errorValue);\n done = true;\n return;\n }\n\n // Check for data in queue\n if (state.queue && state.queue.length > 0) {\n const chunk = state.queue.shift();\n\n // Convert chunk to Uint8Array\n let bytes: Uint8Array;\n if (chunk instanceof Uint8Array) {\n bytes = chunk;\n } else if (typeof chunk === \"string\") {\n bytes = new TextEncoder().encode(chunk);\n } else if (chunk && typeof chunk === \"object\" && \"0\" in chunk) {\n // Handle unmarshalled Uint8Array (object with numeric keys)\n const obj = chunk as Record<string, number>;\n const keys = Object.keys(obj).filter(k => !isNaN(parseInt(k))).sort((a, b) => parseInt(a) - parseInt(b));\n const values = keys.map(k => obj[k]) as number[];\n bytes = new Uint8Array(values);\n } else {\n // Skip unknown chunk types\n continue;\n }\n\n controller.enqueue(bytes);\n return;\n }\n\n // Check if closed\n if (state.closeRequested || state.closed) {\n controller.close();\n done = true;\n return;\n }\n\n // Yield to event loop, then poll again\n await new Promise(r => setTimeout(r, 0));\n }\n },\n\n cancel() {\n done = true;\n }\n });\n}\n\n/**\n * Create a proper Request instance in QuickJS with the given state\n */\nfunction createRequestInstance(\n context: QuickJSContext,\n stateMap: StateMap,\n requestState: RequestState\n): QuickJSHandle {\n // Create the Request instance using evalCode (classes must be called with 'new')\n // Pass the URL as the constructor argument - minimal construction\n const urlHandle = context.newString(requestState.url);\n context.setProp(context.global, \"__requestUrl__\", urlHandle);\n urlHandle.dispose();\n\n const requestResult = context.evalCode(`new Request(__requestUrl__)`);\n\n // Clean up temporary global\n context.setProp(context.global, \"__requestUrl__\", context.undefined);\n\n if (requestResult.error) {\n const error = context.dump(requestResult.error);\n requestResult.error.dispose();\n throw new Error(`Failed to create Request: ${JSON.stringify(error)}`);\n }\n\n const requestHandle = requestResult.value;\n\n // Overwrite the internal state with our full RequestState\n setInstanceState(context, requestHandle, requestState);\n\n return requestHandle;\n}\n\n/**\n * Create the FetchHandle implementation\n */\nexport function createFetchHandle(\n context: QuickJSContext,\n stateMap: StateMap,\n serveState: ServeState\n): FetchHandle {\n const wsCommandCallbacks = new Set<(cmd: WebSocketCommand) => void>();\n\n return {\n stateMap,\n\n async dispatchRequest(request: Request): Promise<Response> {\n if (!serveState.fetchHandler) {\n throw new Error(\"No serve() handler registered\");\n }\n\n // Clear any previous upgrade request\n serveState.pendingUpgrade = null;\n\n // Convert native Request to RequestState\n const requestState = await createRequestStateFromNative(request);\n\n // Create proper QuickJS Request instance with internal state\n const requestHandle = createRequestInstance(context, stateMap, requestState);\n\n // Create Server instance using evalCode (classes must be called with 'new')\n const serverResult = context.evalCode(`new __Server__()`);\n if (serverResult.error) {\n requestHandle.dispose();\n const error = context.dump(serverResult.error);\n serverResult.error.dispose();\n throw new Error(`Failed to create Server: ${error}`);\n }\n const serverHandle = serverResult.value;\n\n try {\n // Call the fetch handler\n const result = context.callFunction(\n serveState.fetchHandler,\n context.undefined,\n requestHandle,\n serverHandle\n );\n\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Fetch handler error: ${JSON.stringify(error)}`);\n }\n\n let responseHandle = result.value;\n\n // Check if result is a Promise\n const typeofResult = context.typeof(responseHandle);\n if (typeofResult === \"object\") {\n // Check for .then method (Promise-like)\n const thenHandle = context.getProp(responseHandle, \"then\");\n const hasThen = context.typeof(thenHandle) === \"function\";\n thenHandle.dispose();\n\n if (hasThen) {\n // Execute pending jobs BEFORE resolvePromise to allow\n // JavaScript-native async functions to schedule their resolution.\n // This is critical for async functions that don't use host-side awaits.\n context.runtime.executePendingJobs();\n\n // For pure JS async functions (without host-side awaits), we need to\n // wrap resolvePromise in a race with repeated executePendingJobs calls.\n // The sync variant of QuickJS needs this to process microtasks.\n const resolved = await Promise.race([\n context.resolvePromise(responseHandle),\n (async () => {\n // Keep executing pending jobs until the promise resolves\n // This handles pure JS async functions that don't trigger host callbacks\n for (let i = 0; i < 1000; i++) {\n await new Promise((r) => setTimeout(r, 0));\n context.runtime.executePendingJobs();\n }\n // If we get here, something is very wrong\n throw new Error(\"Promise resolution timeout\");\n })(),\n ]);\n responseHandle.dispose();\n context.runtime.executePendingJobs();\n\n if (resolved.error) {\n const error = context.dump(resolved.error);\n resolved.error.dispose();\n throw new Error(`Fetch handler promise rejected: ${JSON.stringify(error)}`);\n }\n responseHandle = resolved.value;\n }\n }\n\n // Get the ResponseState directly from the instance\n const responseState = getInstanceState<ResponseState>(context, responseHandle);\n responseHandle.dispose();\n\n if (!responseState) {\n throw new Error(\"Failed to get Response state\");\n }\n\n // Check if streaming response\n if (responseState.bodyType === \"stream\" && responseState.streamInstanceId !== undefined) {\n const nativeStream = createNativeStreamFromState(\n context,\n responseState.streamInstanceId\n );\n\n return new Response(nativeStream, {\n status: responseState.status,\n statusText: responseState.statusText,\n headers: headersStateToNative(responseState.headersState),\n });\n }\n\n // Convert to native Response (non-streaming)\n return responseStateToNative(responseState);\n } finally {\n requestHandle.dispose();\n serverHandle.dispose();\n }\n },\n\n getUpgradeRequest(): UpgradeRequest | null {\n return serveState.pendingUpgrade;\n },\n\n /**\n * Dispatch WebSocket open event to the QuickJS handler.\n *\n * **IMPORTANT:** An `open` handler MUST be defined in the serve() websocket\n * options for the connection to be tracked. Without an open handler, the\n * connection is not stored and subsequent message/close/error events will\n * be silently ignored.\n *\n * @param connectionId - Unique identifier for this WebSocket connection (host-assigned)\n * @param data - Optional user data from server.upgrade() to associate with the connection\n */\n dispatchWebSocketOpen(connectionId: string, data?: unknown): void {\n if (!serveState.websocketHandlers.open) {\n return;\n }\n\n // Create ServerWebSocket instance using evalCode (classes must be called with 'new')\n // Pass arguments through temporary globals\n const connectionIdHandle = context.newString(connectionId);\n const dataHandle = marshal(context, data);\n context.setProp(context.global, \"__wsConnectionId__\", connectionIdHandle);\n context.setProp(context.global, \"__wsData__\", dataHandle);\n connectionIdHandle.dispose();\n dataHandle.dispose();\n\n const wsResult = context.evalCode(`new __ServerWebSocket__(__wsConnectionId__, __wsData__)`);\n\n // Clean up temporary globals\n context.setProp(context.global, \"__wsConnectionId__\", context.undefined);\n context.setProp(context.global, \"__wsData__\", context.undefined);\n\n if (wsResult.error) {\n wsResult.error.dispose();\n return;\n }\n\n const wsHandle = wsResult.value;\n\n // Store the connection\n serveState.activeConnections.set(connectionId, {\n data,\n readyState: 1,\n connectionId,\n wsHandle,\n });\n\n // Call the open handler\n const result = context.callFunction(\n serveState.websocketHandlers.open,\n context.undefined,\n wsHandle\n );\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Dispatch WebSocket message event to the QuickJS handler.\n *\n * Requires the connection to have been tracked via dispatchWebSocketOpen().\n * If no message handler is defined, or the connection is not tracked, this is a no-op.\n *\n * @param connectionId - The connection ID from dispatchWebSocketOpen()\n * @param message - The message content (string or binary data)\n */\n dispatchWebSocketMessage(\n connectionId: string,\n message: string | ArrayBuffer\n ): void {\n if (!serveState.websocketHandlers.message) {\n return;\n }\n\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n return;\n }\n\n const messageHandle =\n typeof message === \"string\"\n ? context.newString(message)\n : context.newArrayBuffer(message);\n\n const result = context.callFunction(\n serveState.websocketHandlers.message,\n context.undefined,\n connection.wsHandle,\n messageHandle\n );\n\n messageHandle.dispose();\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Dispatch WebSocket close event to the QuickJS handler and clean up the connection.\n *\n * Updates the connection ready state to CLOSED (3), calls the close handler if defined,\n * disposes the WebSocket handle, and removes the connection from tracking.\n *\n * @param connectionId - The connection ID from dispatchWebSocketOpen()\n * @param code - The WebSocket close code (e.g., 1000 for normal closure)\n * @param reason - The close reason string\n */\n dispatchWebSocketClose(\n connectionId: string,\n code: number,\n reason: string\n ): void {\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n serveState.activeConnections.delete(connectionId);\n return;\n }\n\n if (!serveState.websocketHandlers.close) {\n // No close handler, but still need to cleanup the connection\n connection.wsHandle.dispose();\n serveState.activeConnections.delete(connectionId);\n return;\n }\n\n // Update ready state\n connection.readyState = 3; // CLOSED\n\n const codeHandle = context.newNumber(code);\n const reasonHandle = context.newString(reason);\n\n const result = context.callFunction(\n serveState.websocketHandlers.close,\n context.undefined,\n connection.wsHandle,\n codeHandle,\n reasonHandle\n );\n\n codeHandle.dispose();\n reasonHandle.dispose();\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n // Cleanup\n connection.wsHandle.dispose();\n serveState.activeConnections.delete(connectionId);\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Dispatch WebSocket error event to the QuickJS handler.\n *\n * Requires the connection to have been tracked via dispatchWebSocketOpen().\n * If no error handler is defined, or the connection is not tracked, this is a no-op.\n *\n * @param connectionId - The connection ID from dispatchWebSocketOpen()\n * @param error - The error that occurred\n */\n dispatchWebSocketError(connectionId: string, error: Error): void {\n if (!serveState.websocketHandlers.error) {\n return;\n }\n\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n return;\n }\n\n const errorHandle = marshal(context, {\n name: error.name,\n message: error.message,\n });\n\n const result = context.callFunction(\n serveState.websocketHandlers.error,\n context.undefined,\n connection.wsHandle,\n errorHandle\n );\n\n errorHandle.dispose();\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n\n context.runtime.executePendingJobs();\n },\n\n /**\n * Register a callback for outgoing WebSocket commands from QuickJS.\n *\n * Called when QuickJS code calls ws.send() or ws.close() on a ServerWebSocket.\n * The callback receives command objects that should be forwarded to the actual WebSocket.\n *\n * @param callback - Function to handle outgoing WebSocket commands\n * @returns Unsubscribe function to remove the callback\n */\n onWebSocketCommand(\n callback: (command: WebSocketCommand) => void\n ): () => void {\n wsCommandCallbacks.add(callback);\n return () => wsCommandCallbacks.delete(callback);\n },\n\n hasServeHandler(): boolean {\n return serveState.fetchHandler !== null;\n },\n\n dispose(): void {\n // Dispose WebSocket handler handles\n if (serveState.websocketHandlers.open) {\n serveState.websocketHandlers.open.dispose();\n serveState.websocketHandlers.open = undefined;\n }\n if (serveState.websocketHandlers.message) {\n serveState.websocketHandlers.message.dispose();\n serveState.websocketHandlers.message = undefined;\n }\n if (serveState.websocketHandlers.close) {\n serveState.websocketHandlers.close.dispose();\n serveState.websocketHandlers.close = undefined;\n }\n if (serveState.websocketHandlers.error) {\n serveState.websocketHandlers.error.dispose();\n serveState.websocketHandlers.error = undefined;\n }\n\n // Dispose fetch handler handle\n if (serveState.fetchHandler) {\n serveState.fetchHandler.dispose();\n serveState.fetchHandler = null;\n }\n\n // Dispose active WebSocket connection handles\n for (const connection of serveState.activeConnections.values()) {\n if (connection.wsHandle) {\n connection.wsHandle.dispose();\n }\n }\n serveState.activeConnections.clear();\n\n // Note: __Server__ and __ServerWebSocket__ are on global and will be cleaned up by context.dispose()\n },\n };\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "C4B0D934788B3BC064756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "ED91E5C4CED38FC864756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/quickjs-fetch",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "type": "module"
5
5
  }
@@ -153,7 +153,9 @@ export interface ResponseState {
153
153
  type: string;
154
154
  ok: boolean;
155
155
  /** Original body type - used to convert back to string for native Response */
156
- bodyType?: "string" | "binary" | null;
156
+ bodyType?: "string" | "binary" | "stream" | null;
157
+ /** Instance ID of ReadableStream when bodyType is "stream" */
158
+ streamInstanceId?: number;
157
159
  }
158
160
  export interface AbortControllerState {
159
161
  signalState: AbortSignalState;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ricsam/quickjs-fetch",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "main": "./dist/cjs/index.cjs",
5
5
  "types": "./dist/types/index.d.ts",
6
6
  "exports": {
@@ -16,7 +16,7 @@
16
16
  "typecheck": "tsc --noEmit"
17
17
  },
18
18
  "dependencies": {
19
- "@ricsam/quickjs-core": "^0.2.6",
19
+ "@ricsam/quickjs-core": "^0.2.7",
20
20
  "quickjs-emscripten": "^0.31.0"
21
21
  },
22
22
  "peerDependencies": {