@ricsam/quickjs-fetch 0.2.14 → 0.2.16

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.
@@ -33,10 +33,13 @@ __export(exports_response, {
33
33
  responseStateToNative: () => responseStateToNative,
34
34
  createResponseStateFromNative: () => createResponseStateFromNative,
35
35
  createResponseClass: () => createResponseClass,
36
- addResponseStaticMethods: () => addResponseStaticMethods
36
+ addResponseStaticMethods: () => addResponseStaticMethods,
37
+ addResponseHeadersGetter: () => addResponseHeadersGetter,
38
+ addResponseCloneMethod: () => addResponseCloneMethod
37
39
  });
38
40
  module.exports = __toCommonJS(exports_response);
39
41
  var import_quickjs_core = require("@ricsam/quickjs-core");
42
+ var import_types = require("../types.cjs");
40
43
  var import_headers = require("./headers.cjs");
41
44
  var import_form_data = require("./form-data.cjs");
42
45
  function createResponseClass(context, stateMap, createStream) {
@@ -71,31 +74,16 @@ function createResponseClass(context, stateMap, createStream) {
71
74
  offset += part.length;
72
75
  }
73
76
  bodyType = "binary";
74
- } else if (bodyInit && typeof bodyInit === "object" && "__isDefineClassInstance__" in bodyInit && bodyInit.__className__ === "ReadableStream") {
75
- const streamInstance = bodyInit;
77
+ } else if (import_quickjs_core.isDefineClassInstance(bodyInit) && bodyInit.__className__ === "ReadableStream") {
76
78
  body = null;
77
79
  bodyType = "stream";
78
- streamInstanceId = streamInstance.__instanceId__;
80
+ streamInstanceId = bodyInit.__instanceId__;
79
81
  }
80
82
  }
81
- if (init?.headers) {
82
- if (init.headers && typeof init.headers === "object" && "headers" in init.headers && init.headers.headers instanceof Map) {
83
- headersState = {
84
- headers: new Map(init.headers.headers)
85
- };
86
- } else if (init.headers && typeof init.headers === "object" && "__isDefineClassInstance__" in init.headers && init.headers.__isDefineClassInstance__ === true && "__instanceId__" in init.headers) {
87
- const instanceId = init.headers.__instanceId__;
88
- const state = import_quickjs_core.getInstanceStateById(instanceId);
89
- if (state && state.headers instanceof Map) {
90
- headersState = {
91
- headers: new Map(state.headers)
92
- };
93
- }
94
- } else {
95
- headersState = { headers: new Map };
96
- for (const [key, value] of Object.entries(init.headers)) {
97
- headersState.headers.set(key.toLowerCase(), [String(value)]);
98
- }
83
+ if (init?.headers !== undefined) {
84
+ const coerced = import_quickjs_core.coerceHeaders.safeParse(init.headers);
85
+ if (coerced.success) {
86
+ headersState = coerced.value;
99
87
  }
100
88
  }
101
89
  return {
@@ -144,11 +132,6 @@ function createResponseClass(context, stateMap, createStream) {
144
132
  return this.bodyUsed;
145
133
  }
146
134
  },
147
- headers: {
148
- get() {
149
- return import_headers.createHeadersLike(this.headersState);
150
- }
151
- },
152
135
  ok: {
153
136
  get() {
154
137
  return this.ok;
@@ -203,20 +186,27 @@ function createResponseClass(context, stateMap, createStream) {
203
186
  size: this.body?.length || 0
204
187
  };
205
188
  },
206
- clone() {
189
+ __getClonedState__() {
207
190
  if (this.bodyUsed) {
208
191
  throw new TypeError("Body has already been consumed");
209
192
  }
210
193
  if (this.bodyType === "stream") {
211
194
  throw new TypeError("Cannot clone Response with streaming body");
212
195
  }
196
+ const headersArray = [];
197
+ for (const [key, values] of this.headersState.headers) {
198
+ headersArray.push([key, values.join(", ")]);
199
+ }
213
200
  return {
214
- ...this,
215
- headersState: {
216
- headers: new Map(this.headersState.headers)
217
- },
218
- body: this.body ? new Uint8Array(this.body) : null,
219
- bodyUsed: false
201
+ status: this.status,
202
+ statusText: this.statusText,
203
+ headers: headersArray,
204
+ body: this.body ? Array.from(this.body) : null,
205
+ url: this.url,
206
+ redirected: this.redirected,
207
+ type: this.type,
208
+ ok: this.ok,
209
+ bodyType: this.bodyType ?? null
220
210
  };
221
211
  },
222
212
  async json() {
@@ -274,11 +264,23 @@ function addResponseStaticMethods(context) {
274
264
 
275
265
  Response.json = function(data, init = {}) {
276
266
  const body = JSON.stringify(data);
277
- // Merge content-type with any provided headers
278
- const headers = Object.assign(
279
- { "content-type": "application/json" },
280
- init.headers || {}
281
- );
267
+ // Create a new Headers instance with content-type as default
268
+ const headers = new Headers({ "content-type": "application/json" });
269
+ // If init has headers, copy them over (this handles Headers instances properly)
270
+ if (init.headers) {
271
+ // Check if it's a Headers instance by looking for entries method
272
+ if (typeof init.headers.entries === 'function') {
273
+ // Headers instance - iterate over entries
274
+ for (const [key, value] of init.headers.entries()) {
275
+ headers.set(key, value);
276
+ }
277
+ } else if (typeof init.headers === 'object') {
278
+ // Plain object - iterate over keys
279
+ for (const key of Object.keys(init.headers)) {
280
+ headers.set(key, init.headers[key]);
281
+ }
282
+ }
283
+ }
282
284
  return new Response(body, {
283
285
  status: init.status ?? 200,
284
286
  statusText: init.statusText ?? "",
@@ -300,34 +302,104 @@ function addResponseStaticMethods(context) {
300
302
  result.value.dispose();
301
303
  }
302
304
  }
305
+ function addResponseCloneMethod(context) {
306
+ const result = context.evalCode(`
307
+ Response.prototype.clone = function() {
308
+ // Get cloned state from private method
309
+ const state = this.__getClonedState__();
310
+
311
+ // Create headers from the array of pairs
312
+ const headers = new Headers();
313
+ for (const [key, value] of state.headers) {
314
+ headers.set(key, value);
315
+ }
316
+
317
+ // Convert body from number array back to Uint8Array if present
318
+ let body = null;
319
+ if (state.body) {
320
+ body = new Uint8Array(state.body);
321
+ }
322
+
323
+ // Create a proper Response instance
324
+ return new Response(body, {
325
+ status: state.status,
326
+ statusText: state.statusText,
327
+ headers: headers,
328
+ });
329
+ };
330
+ `);
331
+ if (result.error) {
332
+ result.error.dispose();
333
+ } else {
334
+ result.value.dispose();
335
+ }
336
+ }
337
+ function addResponseHeadersGetter(context) {
338
+ const result = context.evalCode(`
339
+ (function() {
340
+ const headersCache = new Map();
341
+
342
+ Object.defineProperty(Response.prototype, 'headers', {
343
+ get: function() {
344
+ const instanceId = this.__instanceId__;
345
+ if (!headersCache.has(instanceId)) {
346
+ const headers = new Headers();
347
+ headers.__linkToParent__(instanceId);
348
+ headersCache.set(instanceId, headers);
349
+ }
350
+ return headersCache.get(instanceId);
351
+ },
352
+ enumerable: true,
353
+ configurable: true
354
+ });
355
+ })();
356
+ `);
357
+ if (result.error) {
358
+ result.error.dispose();
359
+ } else {
360
+ result.value.dispose();
361
+ }
362
+ }
303
363
  function responseStateToNative(state) {
304
- const bodyType = state.bodyType;
364
+ if (import_types.isResponseState(state)) {
365
+ if (state.bodyType === "stream") {
366
+ throw new Error("Stream bodies must be handled at dispatch level - use dispatchRequest");
367
+ }
368
+ let body2 = null;
369
+ if (state.body) {
370
+ if (state.bodyType === "string") {
371
+ body2 = new TextDecoder().decode(state.body);
372
+ } else {
373
+ body2 = state.body.buffer.slice(state.body.byteOffset, state.body.byteOffset + state.body.byteLength);
374
+ }
375
+ }
376
+ return new Response(body2, {
377
+ status: state.status,
378
+ statusText: state.statusText,
379
+ headers: import_headers.headersStateToNative(state.headersState)
380
+ });
381
+ }
382
+ const stateObj = state;
383
+ const bodyType = stateObj.bodyType;
305
384
  if (bodyType === "stream") {
306
385
  throw new Error("Stream bodies must be handled at dispatch level - use dispatchRequest");
307
386
  }
308
- const bodyBytes = state.body ?? state.body;
309
- const status = state.status ?? 200;
310
- const statusText = state.statusText ?? "";
311
- let headersState;
312
- if (state.headersState) {
313
- headersState = state.headersState;
314
- } else if (state.headers) {
315
- const headers = state.headers;
316
- if (headers.headers instanceof Map) {
317
- headersState = { headers: headers.headers };
318
- } else {
319
- headersState = { headers: new Map };
387
+ const status = typeof stateObj.status === "number" ? stateObj.status : 200;
388
+ const statusText = typeof stateObj.statusText === "string" ? stateObj.statusText : "";
389
+ let headersState = { headers: new Map };
390
+ if (stateObj.headers && typeof stateObj.headers === "object") {
391
+ const maybeHeadersLike = stateObj.headers;
392
+ if (import_types.isHeadersState(maybeHeadersLike)) {
393
+ headersState = { headers: new Map(maybeHeadersLike.headers) };
320
394
  }
321
- } else {
322
- headersState = { headers: new Map };
323
395
  }
324
396
  let body = null;
325
- if (bodyBytes) {
397
+ const bodyBytes = stateObj.body;
398
+ if (bodyBytes instanceof Uint8Array) {
326
399
  if (bodyType === "string") {
327
400
  body = new TextDecoder().decode(bodyBytes);
328
401
  } else {
329
- const uint8 = bodyBytes;
330
- body = uint8.buffer.slice(uint8.byteOffset, uint8.byteOffset + uint8.byteLength);
402
+ body = bodyBytes.buffer.slice(bodyBytes.byteOffset, bodyBytes.byteOffset + bodyBytes.byteLength);
331
403
  }
332
404
  }
333
405
  return new Response(body, {
@@ -368,4 +440,4 @@ async function createResponseStateFromNative(response) {
368
440
  }
369
441
  })
370
442
 
371
- //# debugId=61E18893615E580364756E2164756E21
443
+ //# debugId=16A8FB178C927BA664756E2164756E21
@@ -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\" | \"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"
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport {\n defineClass,\n isInstanceOf,\n isDefineClassInstance,\n coerceHeaders,\n coerceBody,\n} from \"@ricsam/quickjs-core\";\nimport type { ResponseState, HeadersState, FormDataState } from \"../types.cjs\";\nimport { isResponseState, isHeadersState } from \"../types.cjs\";\nimport { headersStateToNative } 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 isDefineClassInstance(bodyInit) &&\n bodyInit.__className__ === \"ReadableStream\"\n ) {\n // ReadableStream body - don't buffer, store instance ID for later consumption\n body = null;\n bodyType = \"stream\";\n streamInstanceId = bodyInit.__instanceId__;\n }\n }\n\n // Parse headers using coercion\n if (init?.headers !== undefined) {\n const coerced = coerceHeaders.safeParse(init.headers);\n if (coerced.success) {\n headersState = coerced.value;\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 // Note: headers getter is added via addResponseHeadersGetter() in setup.ts\n // to return a proper Headers instance instead of a plain object\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 /**\n * Private method that returns the cloned state as a serializable object.\n * Used by the clone() method added via evalCode (see addResponseCloneMethod).\n */\n __getClonedState__(this: ResponseState): {\n status: number;\n statusText: string;\n headers: Array<[string, string]>;\n body: number[] | null;\n url: string;\n redirected: boolean;\n type: string;\n ok: boolean;\n bodyType: \"string\" | \"binary\" | \"stream\" | null;\n } {\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\n // Convert headers to array of pairs for safe marshalling\n const headersArray: Array<[string, string]> = [];\n for (const [key, values] of this.headersState.headers) {\n headersArray.push([key, values.join(\", \")]);\n }\n\n return {\n status: this.status,\n statusText: this.statusText,\n headers: headersArray,\n body: this.body ? Array.from(this.body) : null,\n url: this.url,\n redirected: this.redirected,\n type: this.type,\n ok: this.ok,\n bodyType: this.bodyType ?? null,\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 // Create a new Headers instance with content-type as default\n const headers = new Headers({ \"content-type\": \"application/json\" });\n // If init has headers, copy them over (this handles Headers instances properly)\n if (init.headers) {\n // Check if it's a Headers instance by looking for entries method\n if (typeof init.headers.entries === 'function') {\n // Headers instance - iterate over entries\n for (const [key, value] of init.headers.entries()) {\n headers.set(key, value);\n }\n } else if (typeof init.headers === 'object') {\n // Plain object - iterate over keys\n for (const key of Object.keys(init.headers)) {\n headers.set(key, init.headers[key]);\n }\n }\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 * Add the clone() method to Response.prototype via evalCode.\n *\n * This must be called AFTER Response and Headers classes are on global.\n * The method creates a proper Response instance with cloned state.\n *\n * @see PATTERNS.md section 2 (Class Methods That Return Instances)\n */\nexport function addResponseCloneMethod(context: QuickJSContext): void {\n const result = context.evalCode(`\n Response.prototype.clone = function() {\n // Get cloned state from private method\n const state = this.__getClonedState__();\n\n // Create headers from the array of pairs\n const headers = new Headers();\n for (const [key, value] of state.headers) {\n headers.set(key, value);\n }\n\n // Convert body from number array back to Uint8Array if present\n let body = null;\n if (state.body) {\n body = new Uint8Array(state.body);\n }\n\n // Create a proper Response instance\n return new Response(body, {\n status: state.status,\n statusText: state.statusText,\n headers: headers,\n });\n };\n `);\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n}\n\n/**\n * Add the headers getter to Response.prototype via evalCode.\n *\n * This must be called AFTER both Response and Headers classes are on global.\n * Returns a cached Headers instance that shares state with the Response.\n *\n * @see PATTERNS.md section 9 (Instance-Cached Properties)\n */\nexport function addResponseHeadersGetter(context: QuickJSContext): void {\n const result = context.evalCode(`\n (function() {\n const headersCache = new Map();\n\n Object.defineProperty(Response.prototype, 'headers', {\n get: function() {\n const instanceId = this.__instanceId__;\n if (!headersCache.has(instanceId)) {\n const headers = new Headers();\n headers.__linkToParent__(instanceId);\n headersCache.set(instanceId, headers);\n }\n return headersCache.get(instanceId);\n },\n enumerable: true,\n configurable: true\n });\n })();\n `);\n\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 // Use type guard to safely extract properties\n if (isResponseState(state)) {\n // Direct ResponseState object\n if (state.bodyType === \"stream\") {\n throw new Error(\"Stream bodies must be handled at dispatch level - use dispatchRequest\");\n }\n\n // Convert body back to string if it was originally a string\n let body: BodyInit | null = null;\n if (state.body) {\n if (state.bodyType === \"string\") {\n body = new TextDecoder().decode(state.body);\n } else {\n body = state.body.buffer.slice(\n state.body.byteOffset,\n state.body.byteOffset + state.body.byteLength\n ) as ArrayBuffer;\n }\n }\n\n return new Response(body, {\n status: state.status,\n statusText: state.statusText,\n headers: headersStateToNative(state.headersState),\n });\n }\n\n // Unmarshalled object - extract properties safely\n const stateObj = state as Record<string, unknown>;\n const bodyType = stateObj.bodyType as string | undefined;\n\n if (bodyType === \"stream\") {\n throw new Error(\"Stream bodies must be handled at dispatch level - use dispatchRequest\");\n }\n\n const status = typeof stateObj.status === \"number\" ? stateObj.status : 200;\n const statusText = typeof stateObj.statusText === \"string\" ? stateObj.statusText : \"\";\n\n // Handle headers from getter (HeadersLike object)\n let headersState: HeadersState = { headers: new Map() };\n if (stateObj.headers && typeof stateObj.headers === \"object\") {\n const maybeHeadersLike = stateObj.headers;\n if (isHeadersState(maybeHeadersLike)) {\n headersState = { headers: new Map(maybeHeadersLike.headers) };\n }\n }\n\n // Convert body\n let body: BodyInit | null = null;\n const bodyBytes = stateObj.body;\n if (bodyBytes instanceof Uint8Array) {\n if (bodyType === \"string\") {\n body = new TextDecoder().decode(bodyBytes);\n } else {\n body = bodyBytes.buffer.slice(\n bodyBytes.byteOffset,\n bodyBytes.byteOffset + bodyBytes.byteLength\n ) 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": "61E18893615E580364756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "16A8FB178C927BA664756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -34,6 +34,7 @@ __export(exports_handle, {
34
34
  });
35
35
  module.exports = __toCommonJS(exports_handle);
36
36
  var import_quickjs_core = require("@ricsam/quickjs-core");
37
+ var import_types = require("./types.cjs");
37
38
  var import_request = require("./globals/request.cjs");
38
39
  var import_response = require("./globals/response.cjs");
39
40
  var import_headers = require("./globals/headers.cjs");
@@ -61,11 +62,13 @@ function createNativeStreamFromState(context, streamInstanceId) {
61
62
  bytes = chunk;
62
63
  } else if (typeof chunk === "string") {
63
64
  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);
65
+ } else if (import_types.isUnmarshalledUint8Array(chunk)) {
66
+ const keys = Object.keys(chunk).filter((k) => !isNaN(parseInt(k, 10))).sort((a, b) => parseInt(a, 10) - parseInt(b, 10));
67
+ bytes = new Uint8Array(keys.length);
68
+ for (let i = 0;i < keys.length; i++) {
69
+ const key = keys[i];
70
+ bytes[i] = chunk[key] ?? 0;
71
+ }
69
72
  } else {
70
73
  continue;
71
74
  }
@@ -341,4 +344,4 @@ function createFetchHandle(context, stateMap, serveState) {
341
344
  }
342
345
  })
343
346
 
344
- //# debugId=B000FB0DDA931AAB64756E2164756E21
347
+ //# debugId=2F54439D2001225C64756E2164756E21
@@ -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, 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 // Clean up previous pending upgrade entry if it was never consumed\n // This handles the case where host called getUpgradeRequest() but never called dispatchWebSocketOpen()\n // Only delete from registry if the connection was NOT opened (not in activeConnections)\n if (serveState.pendingUpgrade?.connectionId) {\n const connId = serveState.pendingUpgrade.connectionId;\n // Only clean up if this upgrade was never consumed (connection never opened)\n if (!serveState.activeConnections.has(connId)) {\n const deleteResult = context.evalCode(`__upgradeRegistry__.delete(\"${connId}\")`);\n if (deleteResult.error) {\n deleteResult.error.dispose();\n } else {\n deleteResult.value.dispose();\n }\n }\n }\n serveState.pendingUpgrade = null;\n\n // Convert native Request to RequestState\n const requestState = 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 * The user data is looked up from the QuickJS-side __upgradeRegistry__ using\n * the connectionId. This avoids marshalling complex objects across the boundary.\n *\n * @param connectionId - The connectionId from getUpgradeRequest()\n */\n dispatchWebSocketOpen(connectionId: string): void {\n // Note: Data stays in __upgradeRegistry__ and is accessed via pure-JS getter\n // This avoids marshalling complex objects (like Zod schemas) that exceed depth limits\n // Registry cleanup happens in dispatchWebSocketClose()\n\n if (!serveState.websocketHandlers.open) {\n return;\n }\n\n // Create ServerWebSocket instance using evalCode (classes must be called with 'new')\n // Only pass connectionId to constructor to avoid unmarshalling complex data objects\n const connectionIdHandle = context.newString(connectionId);\n context.setProp(context.global, \"__wsConnectionId__\", connectionIdHandle);\n connectionIdHandle.dispose();\n\n const wsResult = context.evalCode(`new __ServerWebSocket__(__wsConnectionId__)`);\n\n // Clean up temporary global\n context.setProp(context.global, \"__wsConnectionId__\", context.undefined);\n\n if (wsResult.error) {\n wsResult.error.dispose();\n return;\n }\n\n const wsHandle = wsResult.value;\n\n // Set __connectionId__ on the instance for the pure-JS data getter to use\n const connIdForGetter = context.newString(connectionId);\n context.setProp(wsHandle, \"__connectionId__\", connIdForGetter);\n connIdForGetter.dispose();\n\n // Store the connection\n serveState.activeConnections.set(connectionId, {\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 // Helper to clean up registry entry\n const cleanupRegistry = () => {\n const deleteResult = context.evalCode(`__upgradeRegistry__.delete(\"${connectionId}\")`);\n if (deleteResult.error) {\n deleteResult.error.dispose();\n } else {\n deleteResult.value.dispose();\n }\n };\n\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n serveState.activeConnections.delete(connectionId);\n cleanupRegistry();\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 cleanupRegistry();\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 cleanupRegistry();\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 hasActiveConnections(): boolean {\n return serveState.activeConnections.size > 0;\n },\n\n dispose(): void {\n // Clear upgrade registry to prevent memory leaks\n const clearResult = context.evalCode(`__upgradeRegistry__.clear()`);\n if (clearResult.error) {\n clearResult.error.dispose();\n } else {\n clearResult.value.dispose();\n }\n\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 { isUnmarshalledUint8Array } 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 (isUnmarshalledUint8Array(chunk)) {\n // Handle unmarshalled Uint8Array (object with numeric keys)\n const keys = Object.keys(chunk).filter(k => !isNaN(parseInt(k, 10))).sort((a, b) => parseInt(a, 10) - parseInt(b, 10));\n bytes = new Uint8Array(keys.length);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]!;\n bytes[i] = chunk[key] ?? 0;\n }\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 // Clean up previous pending upgrade entry if it was never consumed\n // This handles the case where host called getUpgradeRequest() but never called dispatchWebSocketOpen()\n // Only delete from registry if the connection was NOT opened (not in activeConnections)\n if (serveState.pendingUpgrade?.connectionId) {\n const connId = serveState.pendingUpgrade.connectionId;\n // Only clean up if this upgrade was never consumed (connection never opened)\n if (!serveState.activeConnections.has(connId)) {\n const deleteResult = context.evalCode(`__upgradeRegistry__.delete(\"${connId}\")`);\n if (deleteResult.error) {\n deleteResult.error.dispose();\n } else {\n deleteResult.value.dispose();\n }\n }\n }\n serveState.pendingUpgrade = null;\n\n // Convert native Request to RequestState\n const requestState = 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 * The user data is looked up from the QuickJS-side __upgradeRegistry__ using\n * the connectionId. This avoids marshalling complex objects across the boundary.\n *\n * @param connectionId - The connectionId from getUpgradeRequest()\n */\n dispatchWebSocketOpen(connectionId: string): void {\n // Note: Data stays in __upgradeRegistry__ and is accessed via pure-JS getter\n // This avoids marshalling complex objects (like Zod schemas) that exceed depth limits\n // Registry cleanup happens in dispatchWebSocketClose()\n\n if (!serveState.websocketHandlers.open) {\n return;\n }\n\n // Create ServerWebSocket instance using evalCode (classes must be called with 'new')\n // Only pass connectionId to constructor to avoid unmarshalling complex data objects\n const connectionIdHandle = context.newString(connectionId);\n context.setProp(context.global, \"__wsConnectionId__\", connectionIdHandle);\n connectionIdHandle.dispose();\n\n const wsResult = context.evalCode(`new __ServerWebSocket__(__wsConnectionId__)`);\n\n // Clean up temporary global\n context.setProp(context.global, \"__wsConnectionId__\", context.undefined);\n\n if (wsResult.error) {\n wsResult.error.dispose();\n return;\n }\n\n const wsHandle = wsResult.value;\n\n // Set __connectionId__ on the instance for the pure-JS data getter to use\n const connIdForGetter = context.newString(connectionId);\n context.setProp(wsHandle, \"__connectionId__\", connIdForGetter);\n connIdForGetter.dispose();\n\n // Store the connection\n serveState.activeConnections.set(connectionId, {\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 // Helper to clean up registry entry\n const cleanupRegistry = () => {\n const deleteResult = context.evalCode(`__upgradeRegistry__.delete(\"${connectionId}\")`);\n if (deleteResult.error) {\n deleteResult.error.dispose();\n } else {\n deleteResult.value.dispose();\n }\n };\n\n const connection = serveState.activeConnections.get(connectionId);\n if (!connection || !connection.wsHandle) {\n serveState.activeConnections.delete(connectionId);\n cleanupRegistry();\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 cleanupRegistry();\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 cleanupRegistry();\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 hasActiveConnections(): boolean {\n return serveState.activeConnections.size > 0;\n },\n\n dispose(): void {\n // Clear upgrade registry to prevent memory leaks\n const clearResult = context.evalCode(`__upgradeRegistry__.clear()`);\n if (clearResult.error) {\n clearResult.error.dispose();\n } else {\n clearResult.value.dispose();\n }\n\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": "B000FB0DDA931AAB64756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "2F54439D2001225C64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/quickjs-fetch",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "type": "commonjs"
5
5
  }
@@ -131,6 +131,10 @@ function setupFetch(context, options = {}) {
131
131
  formDataIteratorResult.value.dispose();
132
132
  }
133
133
  import_request.addRequestFormDataMethod(context);
134
+ import_request.addRequestCloneMethod(context);
135
+ import_response.addResponseCloneMethod(context);
136
+ import_request.addRequestHeadersGetter(context);
137
+ import_response.addResponseHeadersGetter(context);
134
138
  import_form_data.addFormDataFileMethods(context);
135
139
  const ServerWebSocketClass = import_serve.createServerWebSocketClass(context, stateMap, dispatchWsCommand);
136
140
  context.setProp(context.global, "__ServerWebSocket__", ServerWebSocketClass);
@@ -198,4 +202,4 @@ function setupFetch(context, options = {}) {
198
202
  }
199
203
  })
200
204
 
201
- //# debugId=2354E39DCBC5283664756E2164756E21
205
+ //# debugId=69084328C5578CAD64756E2164756E21