@ricsam/quickjs-fetch 0.2.14 → 0.2.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/globals/fetch.cjs +19 -22
- package/dist/cjs/globals/fetch.cjs.map +3 -3
- package/dist/cjs/globals/headers.cjs +5 -30
- package/dist/cjs/globals/headers.cjs.map +3 -3
- package/dist/cjs/globals/request.cjs +167 -65
- package/dist/cjs/globals/request.cjs.map +3 -3
- package/dist/cjs/globals/response.cjs +103 -53
- package/dist/cjs/globals/response.cjs.map +3 -3
- package/dist/cjs/handle.cjs +9 -6
- package/dist/cjs/handle.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/setup.cjs +3 -1
- package/dist/cjs/setup.cjs.map +3 -3
- package/dist/cjs/types.cjs +50 -1
- package/dist/cjs/types.cjs.map +4 -3
- package/dist/mjs/globals/fetch.mjs +20 -23
- package/dist/mjs/globals/fetch.mjs.map +3 -3
- package/dist/mjs/globals/headers.mjs +6 -31
- package/dist/mjs/globals/headers.mjs.map +3 -3
- package/dist/mjs/globals/request.mjs +175 -66
- package/dist/mjs/globals/request.mjs.map +3 -3
- package/dist/mjs/globals/response.mjs +108 -54
- package/dist/mjs/globals/response.mjs.map +3 -3
- package/dist/mjs/handle.mjs +9 -6
- package/dist/mjs/handle.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/setup.mjs +5 -3
- package/dist/mjs/setup.mjs.map +3 -3
- package/dist/mjs/types.mjs +42 -1
- package/dist/mjs/types.mjs.map +4 -3
- package/dist/types/globals/request.d.ts +9 -0
- package/dist/types/globals/response.d.ts +9 -0
- package/dist/types/types.d.ts +48 -0
- package/package.json +2 -2
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/globals/request.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 { RequestState, HeadersState, AbortSignalState, FormDataState } from \"../types.cjs\";\nimport { createHeadersStateFromNative, createHeadersLike } from \"./headers.cjs\";\nimport { parseMultipartFormData, parseUrlEncodedFormData } from \"./form-data.cjs\";\nimport { startNativeStreamReader } from \"../upload-stream-queue.cjs\";\n\n/**\n * Type for the stream factory function\n */\ntype StreamFactory = (source: UnderlyingSource) => QuickJSHandle;\n\n/**\n * Stream helpers passed to the body getter for upload streaming\n */\ninterface StreamHelpers {\n createStream: StreamFactory;\n /** Creates an empty ReadableStream, stores on global, returns instanceId and globalKey */\n createEmptyStream: () => { instanceId: number; globalKey: string };\n /** Gets a fresh handle to the stream stored at globalKey */\n getStreamByKey: (globalKey: string) => QuickJSHandle | null;\n pumpEventLoop: () => void;\n}\n\n/**\n * Helper to consume a native ReadableStream into a Uint8Array.\n * Used by text(), json(), arrayBuffer(), blob() methods.\n */\nasync function consumeNativeStream(\n stream: ReadableStream<Uint8Array>\n): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n const reader = stream.getReader();\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n\n // Concatenate chunks into single Uint8Array\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result;\n}\n\n/**\n * Internal state of a QuickJS ReadableStream.\n * Mirrors structure in upload-stream-queue.ts and core/streams/readable-stream.ts.\n */\ninterface ReadableStreamInternalState {\n locked: boolean;\n queue: unknown[];\n closeRequested: boolean;\n closed: boolean;\n errored: boolean;\n errorValue: unknown;\n reader: {\n readRequests: Array<{\n resolve: (result: { value: unknown; done: boolean }) => void;\n reject: (e: unknown) => void;\n }>;\n closedPromiseResolvers: {\n resolve: () => void;\n reject: (e: unknown) => void;\n };\n } | null;\n}\n\n/**\n * Helper to consume a QuickJS ReadableStream by reading from its internal state.\n * Used when body getter was accessed before consumption methods (json(), text(), etc.).\n *\n * This reads directly from the stream's queue which is being populated by\n * startNativeStreamReader in the background.\n *\n * @param streamInstanceId The instance ID of the QuickJS ReadableStream\n * @param pumpEventLoop Function to pump the QuickJS event loop\n * @returns Promise that resolves to the concatenated body as Uint8Array\n */\nasync function consumeQuickJSStreamById(\n streamInstanceId: number,\n pumpEventLoop: () => void\n): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n\n while (true) {\n // Pump event loop to allow native stream reader to push more data\n pumpEventLoop();\n\n const state = getInstanceStateById<ReadableStreamInternalState>(streamInstanceId);\n if (!state) {\n // Stream was disposed or doesn't exist\n break;\n }\n\n // Drain all available chunks from the queue\n while (state.queue.length > 0) {\n const chunk = state.queue.shift();\n if (chunk instanceof Uint8Array) {\n chunks.push(chunk);\n }\n }\n\n // Check if stream is done (closed with empty queue)\n if (state.closed || (state.closeRequested && state.queue.length === 0)) {\n break;\n }\n\n // Check for errors\n if (state.errored) {\n throw state.errorValue instanceof Error\n ? state.errorValue\n : new Error(String(state.errorValue));\n }\n\n // Wait for more data via read request mechanism\n await new Promise<void>((resolve, reject) => {\n // Re-check state in case it changed during await\n const currentState = getInstanceStateById<ReadableStreamInternalState>(streamInstanceId);\n if (!currentState) {\n resolve();\n return;\n }\n\n // If there's data now or stream is done, resolve immediately\n if (currentState.queue.length > 0 || currentState.closed || currentState.closeRequested) {\n resolve();\n return;\n }\n\n // Ensure reader structure exists for read requests\n if (!currentState.reader) {\n currentState.reader = {\n readRequests: [],\n closedPromiseResolvers: {\n resolve: () => {},\n reject: () => {},\n },\n };\n }\n\n // Add a read request that will be fulfilled when data arrives\n currentState.reader.readRequests.push({\n resolve: (result) => {\n if (!result.done && result.value instanceof Uint8Array) {\n chunks.push(result.value);\n }\n resolve();\n },\n reject: (e) => reject(e),\n });\n\n // Pump event loop to process incoming data\n pumpEventLoop();\n });\n }\n\n // Concatenate all chunks into a single Uint8Array\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result;\n}\n\n/**\n * Create the Request class for QuickJS\n */\nexport function createRequestClass(\n context: QuickJSContext,\n stateMap: StateMap,\n streamHelpers?: StreamHelpers\n): QuickJSHandle {\n const createStream = streamHelpers?.createStream;\n return defineClass<RequestState>(context, stateMap, {\n name: \"Request\",\n construct: (args) => {\n const input = args[0];\n const init = args[1] as {\n method?: string;\n headers?: object;\n body?: unknown;\n cache?: string;\n credentials?: string;\n integrity?: string;\n keepalive?: boolean;\n mode?: string;\n redirect?: string;\n referrer?: string;\n referrerPolicy?: string;\n signal?: AbortSignalState;\n } | undefined;\n\n let url = \"\";\n let method = \"GET\";\n let headersState: HeadersState = { headers: new Map() };\n let body: Uint8Array | null = null;\n let signal: AbortSignalState | null = null;\n\n // Handle input\n if (typeof input === \"string\") {\n url = input;\n } else if (input && typeof input === \"object\") {\n // Could be URL or Request-like\n if (\"url\" in input) {\n url = String((input as { url: string }).url);\n }\n if (\"method\" in input) {\n method = String((input as { method: string }).method);\n }\n if (\"headersState\" in input) {\n const inputHeaders = (input as RequestState).headersState;\n headersState = {\n headers: new Map(inputHeaders.headers),\n };\n }\n if (\"body\" in input && (input as RequestState).body) {\n body = (input as RequestState).body;\n }\n if (\"signal\" in input) {\n signal = (input as RequestState).signal;\n }\n }\n\n // Apply init options\n if (init) {\n if (init.method) {\n method = init.method.toUpperCase();\n }\n if (init.headers) {\n if (init.headers && typeof init.headers === \"object\") {\n if (\"headers\" in init.headers && init.headers.headers instanceof Map) {\n headersState = {\n headers: new Map((init.headers as HeadersState).headers),\n };\n } else if (\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 if (init.body !== undefined && init.body !== null) {\n if (typeof init.body === \"string\") {\n body = new TextEncoder().encode(init.body);\n } else if (init.body instanceof ArrayBuffer) {\n body = new Uint8Array(init.body);\n } else if (init.body instanceof Uint8Array) {\n body = init.body;\n }\n }\n if (init.signal) {\n signal = init.signal;\n }\n }\n\n return {\n method,\n url,\n headersState,\n body,\n bodyUsed: false,\n cache: init?.cache || \"default\",\n credentials: init?.credentials || \"same-origin\",\n destination: \"\",\n integrity: init?.integrity || \"\",\n keepalive: init?.keepalive || false,\n mode: init?.mode || \"cors\",\n redirect: init?.redirect || \"follow\",\n referrer: init?.referrer || \"about:client\",\n referrerPolicy: init?.referrerPolicy || \"\",\n signal,\n };\n },\n properties: {\n method: {\n get(this: RequestState) {\n return this.method;\n },\n },\n url: {\n get(this: RequestState) {\n return this.url;\n },\n },\n headers: {\n get(this: RequestState) {\n return createHeadersLike(this.headersState);\n },\n },\n body: {\n get(this: RequestState & { _uploadStreamGlobalKey?: string; _uploadStreamCleanup?: () => void; _cachedBodyStream?: object | null; _uploadStreamInstanceId?: number }) {\n if (!createStream) {\n // Fallback: return raw body if no stream factory\n return this.body;\n }\n\n // If we have an upload stream, get a fresh handle each time\n // (Can't cache handles because __hostCall__ disposes them after each call)\n if (this._uploadStreamGlobalKey) {\n return streamHelpers?.getStreamByKey(this._uploadStreamGlobalKey) || null;\n }\n\n // Return cached buffered body stream if already created\n if (this._cachedBodyStream !== undefined) {\n return this._cachedBodyStream;\n }\n\n // Streaming native body - create a QuickJS ReadableStream that bridges to the native stream\n // Uses the \"Inverted Direct State Access\" pattern: host pushes to QuickJS stream's queue\n if (this.nativeBodyStream) {\n if (!streamHelpers?.createEmptyStream || !streamHelpers?.getStreamByKey) {\n // No helpers available - fall back to null (legacy behavior)\n return null;\n }\n\n // Create a QuickJS ReadableStream with no source callbacks.\n // The stream is stored on a global because __hostCall__ disposes returned\n // handles after each call. We cache the globalKey and get a fresh handle\n // on each access via getStreamByKey().\n const { instanceId: streamInstanceId, globalKey } = streamHelpers.createEmptyStream();\n\n // Start background reader that pushes to the QuickJS stream\n // The onChunkPushed callback pumps the event loop to process pending reads\n const cleanup = startNativeStreamReader(\n this.nativeBodyStream,\n streamInstanceId,\n streamHelpers.pumpEventLoop\n );\n\n // Store cleanup function for potential cancellation\n this._uploadStreamCleanup = cleanup;\n // Cache the global key so subsequent calls can get the same stream\n this._uploadStreamGlobalKey = globalKey;\n // Store instance ID so consumption methods can read from this stream\n this._uploadStreamInstanceId = streamInstanceId;\n\n // Clear nativeBodyStream to prevent double-consumption\n // This ensures text()/json()/arrayBuffer() don't try to read from it\n this.nativeBodyStream = undefined;\n\n // Get fresh handle to return\n return streamHelpers.getStreamByKey(globalKey);\n }\n\n // Fallback: buffered body (backwards compatibility)\n if (!this.body) {\n this._cachedBodyStream = null;\n return null;\n }\n const bodyData = this.body;\n let offset = 0;\n const chunkSize = 65536; // 64KB chunks\n const stream = 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 this._cachedBodyStream = stream;\n return stream;\n },\n },\n bodyUsed: {\n get(this: RequestState) {\n return this.bodyUsed;\n },\n },\n cache: {\n get(this: RequestState) {\n return this.cache;\n },\n },\n credentials: {\n get(this: RequestState) {\n return this.credentials;\n },\n },\n destination: {\n get(this: RequestState) {\n return this.destination;\n },\n },\n integrity: {\n get(this: RequestState) {\n return this.integrity;\n },\n },\n keepalive: {\n get(this: RequestState) {\n return this.keepalive;\n },\n },\n mode: {\n get(this: RequestState) {\n return this.mode;\n },\n },\n redirect: {\n get(this: RequestState) {\n return this.redirect;\n },\n },\n referrer: {\n get(this: RequestState) {\n return this.referrer;\n },\n },\n referrerPolicy: {\n get(this: RequestState) {\n return this.referrerPolicy;\n },\n },\n signal: {\n get(this: RequestState) {\n return this.signal;\n },\n },\n },\n methods: {\n async arrayBuffer(this: RequestState & { _uploadStreamInstanceId?: number }): Promise<ArrayBuffer> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n\n // Check if QuickJS stream was created (body getter was accessed first)\n if (this._uploadStreamInstanceId !== undefined) {\n const buffer = await consumeQuickJSStreamById(\n this._uploadStreamInstanceId,\n streamHelpers?.pumpEventLoop ?? (() => {})\n );\n return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength) as ArrayBuffer;\n }\n\n // Consume native stream if present\n if (this.nativeBodyStream) {\n const buffer = await consumeNativeStream(this.nativeBodyStream);\n return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength) as ArrayBuffer;\n }\n\n // Fallback: buffered body\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: RequestState & { _uploadStreamInstanceId?: number }): Promise<object> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n\n // Check if QuickJS stream was created (body getter was accessed first)\n if (this._uploadStreamInstanceId !== undefined) {\n const buffer = await consumeQuickJSStreamById(\n this._uploadStreamInstanceId,\n streamHelpers?.pumpEventLoop ?? (() => {})\n );\n return {\n parts: [buffer],\n type: contentType,\n size: buffer.length,\n };\n }\n\n // Consume native stream if present\n if (this.nativeBodyStream) {\n const buffer = await consumeNativeStream(this.nativeBodyStream);\n return {\n parts: [buffer],\n type: contentType,\n size: buffer.length,\n };\n }\n\n // Fallback: buffered body\n return {\n parts: this.body ? [this.body] : [],\n type: contentType,\n size: this.body?.length || 0,\n };\n },\n clone(this: RequestState & { _uploadStreamInstanceId?: number }): RequestState {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n // Note: Cannot clone streaming body - would need to tee the stream\n if (this.nativeBodyStream) {\n throw new TypeError(\"Cannot clone Request with streaming body\");\n }\n // Also cannot clone if body getter created a QuickJS stream\n if (this._uploadStreamInstanceId !== undefined) {\n throw new TypeError(\"Cannot clone Request 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: RequestState & { _uploadStreamInstanceId?: number }): Promise<unknown> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n\n // Check if QuickJS stream was created (body getter was accessed first)\n if (this._uploadStreamInstanceId !== undefined) {\n const buffer = await consumeQuickJSStreamById(\n this._uploadStreamInstanceId,\n streamHelpers?.pumpEventLoop ?? (() => {})\n );\n const text = new TextDecoder().decode(buffer);\n return JSON.parse(text);\n }\n\n // Consume native stream if present\n if (this.nativeBodyStream) {\n const buffer = await consumeNativeStream(this.nativeBodyStream);\n const text = new TextDecoder().decode(buffer);\n return JSON.parse(text);\n }\n\n // Fallback: buffered body\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: RequestState & { _uploadStreamInstanceId?: number }): Promise<string> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n\n // Check if QuickJS stream was created (body getter was accessed first)\n if (this._uploadStreamInstanceId !== undefined) {\n const buffer = await consumeQuickJSStreamById(\n this._uploadStreamInstanceId,\n streamHelpers?.pumpEventLoop ?? (() => {})\n );\n return new TextDecoder().decode(buffer);\n }\n\n // Consume native stream if present\n if (this.nativeBodyStream) {\n const buffer = await consumeNativeStream(this.nativeBodyStream);\n return new TextDecoder().decode(buffer);\n }\n\n // Fallback: buffered body\n if (!this.body) {\n return \"\";\n }\n return new TextDecoder().decode(this.body);\n },\n /**\n * Private method that returns raw FormData entries.\n * Used by the formData() method added via evalCode (see addRequestFormDataMethod).\n *\n * Note: File data is converted to plain number arrays to avoid memory issues\n * when marshalling Uint8Array between host and QuickJS contexts.\n */\n async __getFormDataEntries__(this: RequestState & { _uploadStreamInstanceId?: number }): Promise<{\n entries: Array<{\n name: string;\n value: string | { __formDataFile__: true; data: number[]; filename: string; type: string };\n }>;\n }> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n\n // Get body data from QuickJS stream, native stream, or buffered body\n let bodyData: Uint8Array | null = null;\n if (this._uploadStreamInstanceId !== undefined) {\n bodyData = await consumeQuickJSStreamById(\n this._uploadStreamInstanceId,\n streamHelpers?.pumpEventLoop ?? (() => {})\n );\n } else if (this.nativeBodyStream) {\n bodyData = await consumeNativeStream(this.nativeBodyStream);\n } else {\n bodyData = this.body;\n }\n\n if (!bodyData) {\n return { entries: [] };\n }\n\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n\n let formDataState: FormDataState;\n if (contentType.includes(\"multipart/form-data\")) {\n formDataState = parseMultipartFormData(bodyData, contentType);\n } else if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n formDataState = parseUrlEncodedFormData(bodyData);\n } else {\n throw new TypeError(\"Could not parse content as FormData\");\n }\n\n // Convert Uint8Array data to plain number arrays for safe marshalling\n // Include marker so FormData.get() can reconstruct File instances\n type SerializedFileValue = { __formDataFile__: true; data: number[]; filename: string; type: string };\n type SerializedEntry = { name: string; value: string | SerializedFileValue };\n return {\n entries: formDataState.entries.map((entry): SerializedEntry => {\n if (typeof entry.value === \"string\") {\n return { name: entry.name, value: entry.value };\n }\n // Convert Uint8Array to number array and include marker\n return {\n name: entry.name,\n value: {\n __formDataFile__: true,\n data: Array.from(entry.value.data),\n filename: entry.value.filename,\n type: entry.value.type,\n },\n };\n }),\n };\n },\n },\n });\n}\n\n/**\n * Add the formData() method to Request.prototype via evalCode.\n *\n * This must be called AFTER both Request and FormData classes are on global.\n * The method creates a proper FormData instance with all entries.\n *\n * @see PATTERNS.md section 2 (Class Methods That Return Instances)\n */\nexport function addRequestFormDataMethod(context: QuickJSContext): void {\n const result = context.evalCode(`\n Request.prototype.formData = async function() {\n // Get raw entries from private method\n // Note: File data comes as plain number arrays (converted in host side)\n const rawData = await this.__getFormDataEntries__();\n\n // Create a proper FormData instance\n const formData = new FormData();\n\n // Populate with entries\n // FormData.append handles both string values and file-like objects\n // with number arrays (converted to Uint8Array on the host side)\n for (const entry of rawData.entries) {\n formData.append(entry.name, entry.value);\n }\n\n return formData;\n };\n `);\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n}\n\n/**\n * Create a RequestState from a native Request object.\n *\n * This is now synchronous - we preserve the native ReadableStream instead of\n * buffering it. The stream is consumed lazily when QuickJS code accesses\n * request.body or calls request.text()/json()/arrayBuffer().\n *\n * This enables streaming large uploads (1GB+) without buffering.\n */\nexport function createRequestStateFromNative(\n request: Request\n): RequestState {\n return {\n method: request.method,\n url: request.url,\n headersState: createHeadersStateFromNative(request.headers),\n body: null, // Not buffered upfront - use nativeBodyStream instead\n bodyUsed: false,\n cache: request.cache,\n credentials: request.credentials,\n destination: request.destination,\n integrity: request.integrity,\n keepalive: request.keepalive,\n mode: request.mode,\n redirect: request.redirect,\n referrer: request.referrer,\n referrerPolicy: request.referrerPolicy,\n signal: null, // Signal handling is complex, simplified here\n nativeBodyStream: request.body ?? undefined,\n };\n}\n"
|
|
5
|
+
"import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport {\n defineClass,\n getInstanceStateById,\n isInstanceOf,\n getClassInstanceState,\n coerceToURLString,\n coerceHeaders,\n coerceBody,\n} from \"@ricsam/quickjs-core\";\nimport type { RequestState, HeadersState, AbortSignalState, FormDataState } from \"../types.cjs\";\nimport { isHeadersState, isAbortSignalState } from \"../types.cjs\";\nimport { createHeadersStateFromNative, createHeadersLike } from \"./headers.cjs\";\nimport { parseMultipartFormData, parseUrlEncodedFormData } from \"./form-data.cjs\";\nimport { startNativeStreamReader } from \"../upload-stream-queue.cjs\";\n\n/**\n * Type for the stream factory function\n */\ntype StreamFactory = (source: UnderlyingSource) => QuickJSHandle;\n\n/**\n * Stream helpers passed to the body getter for upload streaming\n */\ninterface StreamHelpers {\n createStream: StreamFactory;\n /** Creates an empty ReadableStream, stores on global, returns instanceId and globalKey */\n createEmptyStream: () => { instanceId: number; globalKey: string };\n /** Gets a fresh handle to the stream stored at globalKey */\n getStreamByKey: (globalKey: string) => QuickJSHandle | null;\n pumpEventLoop: () => void;\n}\n\n/**\n * Helper to consume a native ReadableStream into a Uint8Array.\n * Used by text(), json(), arrayBuffer(), blob() methods.\n */\nasync function consumeNativeStream(\n stream: ReadableStream<Uint8Array>\n): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n const reader = stream.getReader();\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n\n // Concatenate chunks into single Uint8Array\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result;\n}\n\n/**\n * Internal state of a QuickJS ReadableStream.\n * Mirrors structure in upload-stream-queue.ts and core/streams/readable-stream.ts.\n */\ninterface ReadableStreamInternalState {\n locked: boolean;\n queue: unknown[];\n closeRequested: boolean;\n closed: boolean;\n errored: boolean;\n errorValue: unknown;\n reader: {\n readRequests: Array<{\n resolve: (result: { value: unknown; done: boolean }) => void;\n reject: (e: unknown) => void;\n }>;\n closedPromiseResolvers: {\n resolve: () => void;\n reject: (e: unknown) => void;\n };\n } | null;\n}\n\n/**\n * Helper to consume a QuickJS ReadableStream by reading from its internal state.\n * Used when body getter was accessed before consumption methods (json(), text(), etc.).\n *\n * This reads directly from the stream's queue which is being populated by\n * startNativeStreamReader in the background.\n *\n * @param streamInstanceId The instance ID of the QuickJS ReadableStream\n * @param pumpEventLoop Function to pump the QuickJS event loop\n * @returns Promise that resolves to the concatenated body as Uint8Array\n */\nasync function consumeQuickJSStreamById(\n streamInstanceId: number,\n pumpEventLoop: () => void\n): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n\n while (true) {\n // Pump event loop to allow native stream reader to push more data\n pumpEventLoop();\n\n const state = getInstanceStateById<ReadableStreamInternalState>(streamInstanceId);\n if (!state) {\n // Stream was disposed or doesn't exist\n break;\n }\n\n // Drain all available chunks from the queue\n while (state.queue.length > 0) {\n const chunk = state.queue.shift();\n if (chunk instanceof Uint8Array) {\n chunks.push(chunk);\n }\n }\n\n // Check if stream is done (closed with empty queue)\n if (state.closed || (state.closeRequested && state.queue.length === 0)) {\n break;\n }\n\n // Check for errors\n if (state.errored) {\n throw state.errorValue instanceof Error\n ? state.errorValue\n : new Error(String(state.errorValue));\n }\n\n // Wait for more data via read request mechanism\n await new Promise<void>((resolve, reject) => {\n // Re-check state in case it changed during await\n const currentState = getInstanceStateById<ReadableStreamInternalState>(streamInstanceId);\n if (!currentState) {\n resolve();\n return;\n }\n\n // If there's data now or stream is done, resolve immediately\n if (currentState.queue.length > 0 || currentState.closed || currentState.closeRequested) {\n resolve();\n return;\n }\n\n // Ensure reader structure exists for read requests\n if (!currentState.reader) {\n currentState.reader = {\n readRequests: [],\n closedPromiseResolvers: {\n resolve: () => {},\n reject: () => {},\n },\n };\n }\n\n // Add a read request that will be fulfilled when data arrives\n currentState.reader.readRequests.push({\n resolve: (result) => {\n if (!result.done && result.value instanceof Uint8Array) {\n chunks.push(result.value);\n }\n resolve();\n },\n reject: (e) => reject(e),\n });\n\n // Pump event loop to process incoming data\n pumpEventLoop();\n });\n }\n\n // Concatenate all chunks into a single Uint8Array\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result;\n}\n\n/**\n * Create the Request class for QuickJS\n */\nexport function createRequestClass(\n context: QuickJSContext,\n stateMap: StateMap,\n streamHelpers?: StreamHelpers\n): QuickJSHandle {\n const createStream = streamHelpers?.createStream;\n return defineClass<RequestState>(context, stateMap, {\n name: \"Request\",\n construct: (args) => {\n const input = args[0];\n const init = args[1] as {\n method?: string;\n headers?: object;\n body?: unknown;\n cache?: string;\n credentials?: string;\n integrity?: string;\n keepalive?: boolean;\n mode?: string;\n redirect?: string;\n referrer?: string;\n referrerPolicy?: string;\n signal?: AbortSignalState;\n } | undefined;\n\n // Step 1: Extract URL from first argument (highest priority)\n // Per WHATWG Fetch spec, the first argument determines the URL\n let url = \"\";\n if (typeof input === \"string\") {\n url = input;\n } else if (input && typeof input === \"object\") {\n // Check for URL instance first (takes priority over Request.url)\n if (isInstanceOf(input, \"URL\")) {\n const urlState = getClassInstanceState<{ href: string }>(input);\n if (urlState && urlState.href) {\n url = urlState.href;\n }\n } else if (isInstanceOf(input, \"Request\")) {\n // Request instance - get URL from state\n const requestState = getClassInstanceState<RequestState>(input);\n if (requestState) {\n url = requestState.url;\n }\n } else if (\"href\" in input && typeof (input as { href: string }).href === \"string\") {\n // URL-like object with href property\n url = (input as { href: string }).href;\n } else if (\"url\" in input) {\n // Request-like object with url property\n url = String((input as { url: string }).url);\n }\n }\n\n // Step 2: Extract base properties from input if it's a Request\n let method = \"GET\";\n let headersState: HeadersState = { headers: new Map() };\n let body: Uint8Array | null = null;\n let signal: AbortSignalState | null = null;\n let cache = \"default\";\n let credentials = \"same-origin\";\n let integrity = \"\";\n let keepalive = false;\n let mode = \"cors\";\n let redirect = \"follow\";\n let referrer = \"about:client\";\n let referrerPolicy = \"\";\n\n if (input && typeof input === \"object\") {\n if (isInstanceOf(input, \"Request\")) {\n // Copy properties from Request instance\n const requestState = getClassInstanceState<RequestState>(input);\n if (requestState) {\n method = requestState.method;\n headersState = { headers: new Map(requestState.headersState.headers) };\n body = requestState.body;\n signal = requestState.signal;\n cache = requestState.cache;\n credentials = requestState.credentials;\n integrity = requestState.integrity;\n keepalive = requestState.keepalive;\n mode = requestState.mode;\n redirect = requestState.redirect;\n referrer = requestState.referrer;\n referrerPolicy = requestState.referrerPolicy;\n }\n } else if (!isInstanceOf(input, \"URL\")) {\n // Plain object with Request-like properties (not a URL)\n const inputObj = input as Record<string, unknown>;\n if (\"method\" in inputObj && typeof inputObj.method === \"string\") {\n method = inputObj.method;\n }\n if (\"headersState\" in inputObj && isHeadersState(inputObj.headersState)) {\n headersState = { headers: new Map(inputObj.headersState.headers) };\n }\n if (\"body\" in inputObj && inputObj.body) {\n body = coerceBody(inputObj.body);\n }\n if (\"signal\" in inputObj && isAbortSignalState(inputObj.signal)) {\n signal = inputObj.signal;\n }\n }\n }\n\n // Step 3: Apply init options (overrides from second argument)\n // Special case: if init is a Request instance, extract properties from it\n if (init && isInstanceOf(init, \"Request\")) {\n const initRequestState = getClassInstanceState<RequestState>(init);\n if (initRequestState) {\n // Copy properties from the Request instance\n // Only override if input wasn't also a Request (in which case we already copied)\n if (!isInstanceOf(input, \"Request\")) {\n method = initRequestState.method;\n headersState = { headers: new Map(initRequestState.headersState.headers) };\n body = initRequestState.body;\n signal = initRequestState.signal;\n cache = initRequestState.cache;\n credentials = initRequestState.credentials;\n integrity = initRequestState.integrity;\n keepalive = initRequestState.keepalive;\n mode = initRequestState.mode;\n redirect = initRequestState.redirect;\n referrer = initRequestState.referrer;\n referrerPolicy = initRequestState.referrerPolicy;\n }\n }\n } else if (init) {\n // Plain object init\n if (init.method) {\n method = init.method.toUpperCase();\n }\n if (init.headers !== undefined) {\n const coerced = coerceHeaders.safeParse(init.headers);\n if (coerced.success) {\n headersState = coerced.value;\n }\n }\n if (init.body !== undefined) {\n body = coerceBody(init.body);\n }\n if (init.signal) {\n signal = init.signal;\n }\n if (init.cache !== undefined) cache = init.cache;\n if (init.credentials !== undefined) credentials = init.credentials;\n if (init.integrity !== undefined) integrity = init.integrity;\n if (init.keepalive !== undefined) keepalive = init.keepalive;\n if (init.mode !== undefined) mode = init.mode;\n if (init.redirect !== undefined) redirect = init.redirect;\n if (init.referrer !== undefined) referrer = init.referrer;\n if (init.referrerPolicy !== undefined) referrerPolicy = init.referrerPolicy;\n }\n\n return {\n method,\n url,\n headersState,\n body,\n bodyUsed: false,\n cache,\n credentials,\n destination: \"\",\n integrity,\n keepalive,\n mode,\n redirect,\n referrer,\n referrerPolicy,\n signal,\n };\n },\n properties: {\n method: {\n get(this: RequestState) {\n return this.method;\n },\n },\n url: {\n get(this: RequestState) {\n return this.url;\n },\n },\n headers: {\n get(this: RequestState) {\n return createHeadersLike(this.headersState);\n },\n },\n body: {\n get(this: RequestState & { _uploadStreamGlobalKey?: string; _uploadStreamCleanup?: () => void; _cachedBodyStream?: object | null; _uploadStreamInstanceId?: number }) {\n if (!createStream) {\n // Fallback: return raw body if no stream factory\n return this.body;\n }\n\n // If we have an upload stream, get a fresh handle each time\n // (Can't cache handles because __hostCall__ disposes them after each call)\n if (this._uploadStreamGlobalKey) {\n return streamHelpers?.getStreamByKey(this._uploadStreamGlobalKey) || null;\n }\n\n // Return cached buffered body stream if already created\n if (this._cachedBodyStream !== undefined) {\n return this._cachedBodyStream;\n }\n\n // Streaming native body - create a QuickJS ReadableStream that bridges to the native stream\n // Uses the \"Inverted Direct State Access\" pattern: host pushes to QuickJS stream's queue\n if (this.nativeBodyStream) {\n if (!streamHelpers?.createEmptyStream || !streamHelpers?.getStreamByKey) {\n // No helpers available - fall back to null (legacy behavior)\n return null;\n }\n\n // Create a QuickJS ReadableStream with no source callbacks.\n // The stream is stored on a global because __hostCall__ disposes returned\n // handles after each call. We cache the globalKey and get a fresh handle\n // on each access via getStreamByKey().\n const { instanceId: streamInstanceId, globalKey } = streamHelpers.createEmptyStream();\n\n // Start background reader that pushes to the QuickJS stream\n // The onChunkPushed callback pumps the event loop to process pending reads\n const cleanup = startNativeStreamReader(\n this.nativeBodyStream,\n streamInstanceId,\n streamHelpers.pumpEventLoop\n );\n\n // Store cleanup function for potential cancellation\n this._uploadStreamCleanup = cleanup;\n // Cache the global key so subsequent calls can get the same stream\n this._uploadStreamGlobalKey = globalKey;\n // Store instance ID so consumption methods can read from this stream\n this._uploadStreamInstanceId = streamInstanceId;\n\n // Clear nativeBodyStream to prevent double-consumption\n // This ensures text()/json()/arrayBuffer() don't try to read from it\n this.nativeBodyStream = undefined;\n\n // Get fresh handle to return\n return streamHelpers.getStreamByKey(globalKey);\n }\n\n // Fallback: buffered body (backwards compatibility)\n if (!this.body) {\n this._cachedBodyStream = null;\n return null;\n }\n const bodyData = this.body;\n let offset = 0;\n const chunkSize = 65536; // 64KB chunks\n const stream = 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 this._cachedBodyStream = stream;\n return stream;\n },\n },\n bodyUsed: {\n get(this: RequestState) {\n return this.bodyUsed;\n },\n },\n cache: {\n get(this: RequestState) {\n return this.cache;\n },\n },\n credentials: {\n get(this: RequestState) {\n return this.credentials;\n },\n },\n destination: {\n get(this: RequestState) {\n return this.destination;\n },\n },\n integrity: {\n get(this: RequestState) {\n return this.integrity;\n },\n },\n keepalive: {\n get(this: RequestState) {\n return this.keepalive;\n },\n },\n mode: {\n get(this: RequestState) {\n return this.mode;\n },\n },\n redirect: {\n get(this: RequestState) {\n return this.redirect;\n },\n },\n referrer: {\n get(this: RequestState) {\n return this.referrer;\n },\n },\n referrerPolicy: {\n get(this: RequestState) {\n return this.referrerPolicy;\n },\n },\n signal: {\n get(this: RequestState) {\n return this.signal;\n },\n },\n },\n methods: {\n async arrayBuffer(this: RequestState & { _uploadStreamInstanceId?: number }): Promise<ArrayBuffer> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n\n // Check if QuickJS stream was created (body getter was accessed first)\n if (this._uploadStreamInstanceId !== undefined) {\n const buffer = await consumeQuickJSStreamById(\n this._uploadStreamInstanceId,\n streamHelpers?.pumpEventLoop ?? (() => {})\n );\n return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength) as ArrayBuffer;\n }\n\n // Consume native stream if present\n if (this.nativeBodyStream) {\n const buffer = await consumeNativeStream(this.nativeBodyStream);\n return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength) as ArrayBuffer;\n }\n\n // Fallback: buffered body\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: RequestState & { _uploadStreamInstanceId?: number }): Promise<object> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n\n // Check if QuickJS stream was created (body getter was accessed first)\n if (this._uploadStreamInstanceId !== undefined) {\n const buffer = await consumeQuickJSStreamById(\n this._uploadStreamInstanceId,\n streamHelpers?.pumpEventLoop ?? (() => {})\n );\n return {\n parts: [buffer],\n type: contentType,\n size: buffer.length,\n };\n }\n\n // Consume native stream if present\n if (this.nativeBodyStream) {\n const buffer = await consumeNativeStream(this.nativeBodyStream);\n return {\n parts: [buffer],\n type: contentType,\n size: buffer.length,\n };\n }\n\n // Fallback: buffered body\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 addRequestCloneMethod).\n */\n __getClonedState__(this: RequestState & { _uploadStreamInstanceId?: number }): {\n method: string;\n url: string;\n headers: Array<[string, string]>;\n body: number[] | null;\n cache: string;\n credentials: string;\n integrity: string;\n keepalive: boolean;\n mode: string;\n redirect: string;\n referrer: string;\n referrerPolicy: string;\n } {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n // Note: Cannot clone streaming body - would need to tee the stream\n if (this.nativeBodyStream) {\n throw new TypeError(\"Cannot clone Request with streaming body\");\n }\n // Also cannot clone if body getter created a QuickJS stream\n if (this._uploadStreamInstanceId !== undefined) {\n throw new TypeError(\"Cannot clone Request 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 method: this.method,\n url: this.url,\n headers: headersArray,\n body: this.body ? Array.from(this.body) : null,\n cache: this.cache,\n credentials: this.credentials,\n integrity: this.integrity,\n keepalive: this.keepalive,\n mode: this.mode,\n redirect: this.redirect,\n referrer: this.referrer,\n referrerPolicy: this.referrerPolicy,\n };\n },\n async json(this: RequestState & { _uploadStreamInstanceId?: number }): Promise<unknown> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n\n // Check if QuickJS stream was created (body getter was accessed first)\n if (this._uploadStreamInstanceId !== undefined) {\n const buffer = await consumeQuickJSStreamById(\n this._uploadStreamInstanceId,\n streamHelpers?.pumpEventLoop ?? (() => {})\n );\n const text = new TextDecoder().decode(buffer);\n return JSON.parse(text);\n }\n\n // Consume native stream if present\n if (this.nativeBodyStream) {\n const buffer = await consumeNativeStream(this.nativeBodyStream);\n const text = new TextDecoder().decode(buffer);\n return JSON.parse(text);\n }\n\n // Fallback: buffered body\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: RequestState & { _uploadStreamInstanceId?: number }): Promise<string> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n\n // Check if QuickJS stream was created (body getter was accessed first)\n if (this._uploadStreamInstanceId !== undefined) {\n const buffer = await consumeQuickJSStreamById(\n this._uploadStreamInstanceId,\n streamHelpers?.pumpEventLoop ?? (() => {})\n );\n return new TextDecoder().decode(buffer);\n }\n\n // Consume native stream if present\n if (this.nativeBodyStream) {\n const buffer = await consumeNativeStream(this.nativeBodyStream);\n return new TextDecoder().decode(buffer);\n }\n\n // Fallback: buffered body\n if (!this.body) {\n return \"\";\n }\n return new TextDecoder().decode(this.body);\n },\n /**\n * Private method that returns raw FormData entries.\n * Used by the formData() method added via evalCode (see addRequestFormDataMethod).\n *\n * Note: File data is converted to plain number arrays to avoid memory issues\n * when marshalling Uint8Array between host and QuickJS contexts.\n */\n async __getFormDataEntries__(this: RequestState & { _uploadStreamInstanceId?: number }): Promise<{\n entries: Array<{\n name: string;\n value: string | { __formDataFile__: true; data: number[]; filename: string; type: string };\n }>;\n }> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n\n // Get body data from QuickJS stream, native stream, or buffered body\n let bodyData: Uint8Array | null = null;\n if (this._uploadStreamInstanceId !== undefined) {\n bodyData = await consumeQuickJSStreamById(\n this._uploadStreamInstanceId,\n streamHelpers?.pumpEventLoop ?? (() => {})\n );\n } else if (this.nativeBodyStream) {\n bodyData = await consumeNativeStream(this.nativeBodyStream);\n } else {\n bodyData = this.body;\n }\n\n if (!bodyData) {\n return { entries: [] };\n }\n\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n\n let formDataState: FormDataState;\n if (contentType.includes(\"multipart/form-data\")) {\n formDataState = parseMultipartFormData(bodyData, contentType);\n } else if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n formDataState = parseUrlEncodedFormData(bodyData);\n } else {\n throw new TypeError(\"Could not parse content as FormData\");\n }\n\n // Convert Uint8Array data to plain number arrays for safe marshalling\n // Include marker so FormData.get() can reconstruct File instances\n type SerializedFileValue = { __formDataFile__: true; data: number[]; filename: string; type: string };\n type SerializedEntry = { name: string; value: string | SerializedFileValue };\n return {\n entries: formDataState.entries.map((entry): SerializedEntry => {\n if (typeof entry.value === \"string\") {\n return { name: entry.name, value: entry.value };\n }\n // Convert Uint8Array to number array and include marker\n return {\n name: entry.name,\n value: {\n __formDataFile__: true,\n data: Array.from(entry.value.data),\n filename: entry.value.filename,\n type: entry.value.type,\n },\n };\n }),\n };\n },\n },\n });\n}\n\n/**\n * Add the formData() method to Request.prototype via evalCode.\n *\n * This must be called AFTER both Request and FormData classes are on global.\n * The method creates a proper FormData instance with all entries.\n *\n * @see PATTERNS.md section 2 (Class Methods That Return Instances)\n */\nexport function addRequestFormDataMethod(context: QuickJSContext): void {\n const result = context.evalCode(`\n Request.prototype.formData = async function() {\n // Get raw entries from private method\n // Note: File data comes as plain number arrays (converted in host side)\n const rawData = await this.__getFormDataEntries__();\n\n // Create a proper FormData instance\n const formData = new FormData();\n\n // Populate with entries\n // FormData.append handles both string values and file-like objects\n // with number arrays (converted to Uint8Array on the host side)\n for (const entry of rawData.entries) {\n formData.append(entry.name, entry.value);\n }\n\n return formData;\n };\n `);\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n}\n\n/**\n * Add the clone() method to Request.prototype via evalCode.\n *\n * This must be called AFTER Request class is on global.\n * The method creates a proper Request instance with cloned state.\n *\n * @see PATTERNS.md section 2 (Class Methods That Return Instances)\n */\nexport function addRequestCloneMethod(context: QuickJSContext): void {\n const result = context.evalCode(`\n Request.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 Request instance\n return new Request(state.url, {\n method: state.method,\n headers: headers,\n body: body,\n cache: state.cache,\n credentials: state.credentials,\n integrity: state.integrity,\n keepalive: state.keepalive,\n mode: state.mode,\n redirect: state.redirect,\n referrer: state.referrer,\n referrerPolicy: state.referrerPolicy,\n });\n };\n `);\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n}\n\n/**\n * Create a RequestState from a native Request object.\n *\n * This is now synchronous - we preserve the native ReadableStream instead of\n * buffering it. The stream is consumed lazily when QuickJS code accesses\n * request.body or calls request.text()/json()/arrayBuffer().\n *\n * This enables streaming large uploads (1GB+) without buffering.\n */\nexport function createRequestStateFromNative(\n request: Request\n): RequestState {\n return {\n method: request.method,\n url: request.url,\n headersState: createHeadersStateFromNative(request.headers),\n body: null, // Not buffered upfront - use nativeBodyStream instead\n bodyUsed: false,\n cache: request.cache,\n credentials: request.credentials,\n destination: request.destination,\n integrity: request.integrity,\n keepalive: request.keepalive,\n mode: request.mode,\n redirect: request.redirect,\n referrer: request.referrer,\n referrerPolicy: request.referrerPolicy,\n signal: null, // Signal handling is complex, simplified here\n nativeBodyStream: request.body ?? undefined,\n };\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "C1753898494E46E164756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -33,10 +33,12 @@ __export(exports_response, {
|
|
|
33
33
|
responseStateToNative: () => responseStateToNative,
|
|
34
34
|
createResponseStateFromNative: () => createResponseStateFromNative,
|
|
35
35
|
createResponseClass: () => createResponseClass,
|
|
36
|
-
addResponseStaticMethods: () => addResponseStaticMethods
|
|
36
|
+
addResponseStaticMethods: () => addResponseStaticMethods,
|
|
37
|
+
addResponseCloneMethod: () => addResponseCloneMethod
|
|
37
38
|
});
|
|
38
39
|
module.exports = __toCommonJS(exports_response);
|
|
39
40
|
var import_quickjs_core = require("@ricsam/quickjs-core");
|
|
41
|
+
var import_types = require("../types.cjs");
|
|
40
42
|
var import_headers = require("./headers.cjs");
|
|
41
43
|
var import_form_data = require("./form-data.cjs");
|
|
42
44
|
function createResponseClass(context, stateMap, createStream) {
|
|
@@ -71,31 +73,16 @@ function createResponseClass(context, stateMap, createStream) {
|
|
|
71
73
|
offset += part.length;
|
|
72
74
|
}
|
|
73
75
|
bodyType = "binary";
|
|
74
|
-
} else if (bodyInit &&
|
|
75
|
-
const streamInstance = bodyInit;
|
|
76
|
+
} else if (import_quickjs_core.isDefineClassInstance(bodyInit) && bodyInit.__className__ === "ReadableStream") {
|
|
76
77
|
body = null;
|
|
77
78
|
bodyType = "stream";
|
|
78
|
-
streamInstanceId =
|
|
79
|
+
streamInstanceId = bodyInit.__instanceId__;
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
|
-
if (init?.headers) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
}
|
|
82
|
+
if (init?.headers !== undefined) {
|
|
83
|
+
const coerced = import_quickjs_core.coerceHeaders.safeParse(init.headers);
|
|
84
|
+
if (coerced.success) {
|
|
85
|
+
headersState = coerced.value;
|
|
99
86
|
}
|
|
100
87
|
}
|
|
101
88
|
return {
|
|
@@ -203,20 +190,27 @@ function createResponseClass(context, stateMap, createStream) {
|
|
|
203
190
|
size: this.body?.length || 0
|
|
204
191
|
};
|
|
205
192
|
},
|
|
206
|
-
|
|
193
|
+
__getClonedState__() {
|
|
207
194
|
if (this.bodyUsed) {
|
|
208
195
|
throw new TypeError("Body has already been consumed");
|
|
209
196
|
}
|
|
210
197
|
if (this.bodyType === "stream") {
|
|
211
198
|
throw new TypeError("Cannot clone Response with streaming body");
|
|
212
199
|
}
|
|
200
|
+
const headersArray = [];
|
|
201
|
+
for (const [key, values] of this.headersState.headers) {
|
|
202
|
+
headersArray.push([key, values.join(", ")]);
|
|
203
|
+
}
|
|
213
204
|
return {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
205
|
+
status: this.status,
|
|
206
|
+
statusText: this.statusText,
|
|
207
|
+
headers: headersArray,
|
|
208
|
+
body: this.body ? Array.from(this.body) : null,
|
|
209
|
+
url: this.url,
|
|
210
|
+
redirected: this.redirected,
|
|
211
|
+
type: this.type,
|
|
212
|
+
ok: this.ok,
|
|
213
|
+
bodyType: this.bodyType ?? null
|
|
220
214
|
};
|
|
221
215
|
},
|
|
222
216
|
async json() {
|
|
@@ -274,11 +268,23 @@ function addResponseStaticMethods(context) {
|
|
|
274
268
|
|
|
275
269
|
Response.json = function(data, init = {}) {
|
|
276
270
|
const body = JSON.stringify(data);
|
|
277
|
-
//
|
|
278
|
-
const headers =
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
271
|
+
// Create a new Headers instance with content-type as default
|
|
272
|
+
const headers = new Headers({ "content-type": "application/json" });
|
|
273
|
+
// If init has headers, copy them over (this handles Headers instances properly)
|
|
274
|
+
if (init.headers) {
|
|
275
|
+
// Check if it's a Headers instance by looking for entries method
|
|
276
|
+
if (typeof init.headers.entries === 'function') {
|
|
277
|
+
// Headers instance - iterate over entries
|
|
278
|
+
for (const [key, value] of init.headers.entries()) {
|
|
279
|
+
headers.set(key, value);
|
|
280
|
+
}
|
|
281
|
+
} else if (typeof init.headers === 'object') {
|
|
282
|
+
// Plain object - iterate over keys
|
|
283
|
+
for (const key of Object.keys(init.headers)) {
|
|
284
|
+
headers.set(key, init.headers[key]);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
282
288
|
return new Response(body, {
|
|
283
289
|
status: init.status ?? 200,
|
|
284
290
|
statusText: init.statusText ?? "",
|
|
@@ -300,34 +306,78 @@ function addResponseStaticMethods(context) {
|
|
|
300
306
|
result.value.dispose();
|
|
301
307
|
}
|
|
302
308
|
}
|
|
309
|
+
function addResponseCloneMethod(context) {
|
|
310
|
+
const result = context.evalCode(`
|
|
311
|
+
Response.prototype.clone = function() {
|
|
312
|
+
// Get cloned state from private method
|
|
313
|
+
const state = this.__getClonedState__();
|
|
314
|
+
|
|
315
|
+
// Create headers from the array of pairs
|
|
316
|
+
const headers = new Headers();
|
|
317
|
+
for (const [key, value] of state.headers) {
|
|
318
|
+
headers.set(key, value);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Convert body from number array back to Uint8Array if present
|
|
322
|
+
let body = null;
|
|
323
|
+
if (state.body) {
|
|
324
|
+
body = new Uint8Array(state.body);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Create a proper Response instance
|
|
328
|
+
return new Response(body, {
|
|
329
|
+
status: state.status,
|
|
330
|
+
statusText: state.statusText,
|
|
331
|
+
headers: headers,
|
|
332
|
+
});
|
|
333
|
+
};
|
|
334
|
+
`);
|
|
335
|
+
if (result.error) {
|
|
336
|
+
result.error.dispose();
|
|
337
|
+
} else {
|
|
338
|
+
result.value.dispose();
|
|
339
|
+
}
|
|
340
|
+
}
|
|
303
341
|
function responseStateToNative(state) {
|
|
304
|
-
|
|
342
|
+
if (import_types.isResponseState(state)) {
|
|
343
|
+
if (state.bodyType === "stream") {
|
|
344
|
+
throw new Error("Stream bodies must be handled at dispatch level - use dispatchRequest");
|
|
345
|
+
}
|
|
346
|
+
let body2 = null;
|
|
347
|
+
if (state.body) {
|
|
348
|
+
if (state.bodyType === "string") {
|
|
349
|
+
body2 = new TextDecoder().decode(state.body);
|
|
350
|
+
} else {
|
|
351
|
+
body2 = state.body.buffer.slice(state.body.byteOffset, state.body.byteOffset + state.body.byteLength);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return new Response(body2, {
|
|
355
|
+
status: state.status,
|
|
356
|
+
statusText: state.statusText,
|
|
357
|
+
headers: import_headers.headersStateToNative(state.headersState)
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
const stateObj = state;
|
|
361
|
+
const bodyType = stateObj.bodyType;
|
|
305
362
|
if (bodyType === "stream") {
|
|
306
363
|
throw new Error("Stream bodies must be handled at dispatch level - use dispatchRequest");
|
|
307
364
|
}
|
|
308
|
-
const
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
const headers = state.headers;
|
|
316
|
-
if (headers.headers instanceof Map) {
|
|
317
|
-
headersState = { headers: headers.headers };
|
|
318
|
-
} else {
|
|
319
|
-
headersState = { headers: new Map };
|
|
365
|
+
const status = typeof stateObj.status === "number" ? stateObj.status : 200;
|
|
366
|
+
const statusText = typeof stateObj.statusText === "string" ? stateObj.statusText : "";
|
|
367
|
+
let headersState = { headers: new Map };
|
|
368
|
+
if (stateObj.headers && typeof stateObj.headers === "object") {
|
|
369
|
+
const maybeHeadersLike = stateObj.headers;
|
|
370
|
+
if (import_types.isHeadersState(maybeHeadersLike)) {
|
|
371
|
+
headersState = { headers: new Map(maybeHeadersLike.headers) };
|
|
320
372
|
}
|
|
321
|
-
} else {
|
|
322
|
-
headersState = { headers: new Map };
|
|
323
373
|
}
|
|
324
374
|
let body = null;
|
|
325
|
-
|
|
375
|
+
const bodyBytes = stateObj.body;
|
|
376
|
+
if (bodyBytes instanceof Uint8Array) {
|
|
326
377
|
if (bodyType === "string") {
|
|
327
378
|
body = new TextDecoder().decode(bodyBytes);
|
|
328
379
|
} else {
|
|
329
|
-
|
|
330
|
-
body = uint8.buffer.slice(uint8.byteOffset, uint8.byteOffset + uint8.byteLength);
|
|
380
|
+
body = bodyBytes.buffer.slice(bodyBytes.byteOffset, bodyBytes.byteOffset + bodyBytes.byteLength);
|
|
331
381
|
}
|
|
332
382
|
}
|
|
333
383
|
return new Response(body, {
|
|
@@ -368,4 +418,4 @@ async function createResponseStateFromNative(response) {
|
|
|
368
418
|
}
|
|
369
419
|
})
|
|
370
420
|
|
|
371
|
-
//# debugId=
|
|
421
|
+
//# debugId=AD1E3EACF3B32FC464756E2164756E21
|
|
@@ -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, 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 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 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 /**\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 * 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": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQO,IANP;AAQgD,IAAhD;AACwD,IAAxD;AACgE,IAAhE;AAUO,SAAS,mBAAmB,CACjC,SACA,UACA,cACe;AAAA,EACf,MAAM,cAAc,gCAA2B,SAAS,UAAU;AAAA,IAChE,MAAM;AAAA,IACN,WAAW,CAAC,SAAS;AAAA,MACnB,MAAM,WAAW,KAAK;AAAA,MACtB,MAAM,OAAO,KAAK;AAAA,MAOlB,IAAI,OAA0B;AAAA,MAC9B,IAAI,WAAkD;AAAA,MACtD,IAAI,mBAAuC;AAAA,MAC3C,MAAM,SAAS,MAAM,UAAU;AAAA,MAC/B,MAAM,aAAa,MAAM,cAAc;AAAA,MACvC,IAAI,eAA6B,EAAE,SAAS,IAAI,IAAM;AAAA,MAGtD,IAAI,aAAa,QAAQ,aAAa,WAAW;AAAA,QAC/C,IAAI,OAAO,aAAa,UAAU;AAAA,UAChC,OAAO,IAAI,YAAY,EAAE,OAAO,QAAQ;AAAA,UACxC,WAAW;AAAA,QACb,EAAO,SAAI,oBAAoB,aAAa;AAAA,UAC1C,OAAO,IAAI,WAAW,QAAQ;AAAA,UAC9B,WAAW;AAAA,QACb,EAAO,SAAI,oBAAoB,YAAY;AAAA,UACzC,OAAO;AAAA,UACP,WAAW;AAAA,QACb,EAAO,SACL,YACA,OAAO,aAAa,YACpB,WAAW,UACX;AAAA,UAEA,MAAM,QAAS,SAAqC;AAAA,UACpD,MAAM,cAAc,MAAM,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,QAAQ,CAAC;AAAA,UAC9D,OAAO,IAAI,WAAW,WAAW;AAAA,UACjC,IAAI,SAAS;AAAA,UACb,WAAW,QAAQ,OAAO;AAAA,YACxB,KAAK,IAAI,MAAM,MAAM;AAAA,YACrB,UAAU,KAAK;AAAA,UACjB;AAAA,UACA,WAAW;AAAA,QACb,EAAO,SACL,0CAAsB,QAAQ,KAC9B,SAAS,kBAAkB,kBAC3B;AAAA,UAEA,OAAO;AAAA,UACP,WAAW;AAAA,UACX,mBAAmB,SAAS;AAAA,QAC9B;AAAA,MACF;AAAA,MAGA,IAAI,MAAM,YAAY,WAAW;AAAA,QAC/B,MAAM,UAAU,kCAAc,UAAU,KAAK,OAAO;AAAA,QACpD,IAAI,QAAQ,SAAS;AAAA,UACnB,eAAe,QAAQ;AAAA,QACzB;AAAA,MACF;AAAA,MAEA,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV,KAAK;AAAA,QACL,YAAY;AAAA,QACZ,MAAM,MAAM,SAAS;AAAA,QACrB,IAAI,UAAU,OAAO,SAAS;AAAA,QAC9B;AAAA,QACA;AAAA,MACF;AAAA;AAAA,IAEF,YAAY;AAAA,MACV,MAAM;AAAA,QACJ,GAAG,GAAsB;AAAA,UAGvB,IAAI,KAAK,aAAa,UAAU;AAAA,YAC9B,OAAO;AAAA,UACT;AAAA,UAEA,IAAI,CAAC,KAAK;AAAA,YAAM,OAAO;AAAA,UACvB,IAAI,CAAC,cAAc;AAAA,YAEjB,OAAO,KAAK;AAAA,UACd;AAAA,UAEA,MAAM,WAAW,KAAK;AAAA,UACtB,IAAI,SAAS;AAAA,UACb,MAAM,YAAY;AAAA,UAClB,OAAO,aAAa;AAAA,YAClB,IAAI,CAAC,YAAY;AAAA,cACf,IAAI,UAAU,SAAS,QAAQ;AAAA,gBAC7B,WAAW,MAAM;AAAA,gBACjB;AAAA,cACF;AAAA,cACA,MAAM,QAAQ,SAAS,MAAM,QAAQ,KAAK,IAAI,SAAS,WAAW,SAAS,MAAM,CAAC;AAAA,cAClF,UAAU,MAAM;AAAA,cAChB,WAAW,QAAQ,KAAK;AAAA;AAAA,UAE5B,CAAC;AAAA;AAAA,MAEL;AAAA,MACA,UAAU;AAAA,QACR,GAAG,GAAsB;AAAA,UACvB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,SAAS;AAAA,QACP,GAAG,GAAsB;AAAA,UACvB,OAAO,iCAAkB,KAAK,YAAY;AAAA;AAAA,MAE9C;AAAA,MACA,IAAI;AAAA,QACF,GAAG,GAAsB;AAAA,UACvB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,YAAY;AAAA,QACV,GAAG,GAAsB;AAAA,UACvB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,QAAQ;AAAA,QACN,GAAG,GAAsB;AAAA,UACvB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,YAAY;AAAA,QACV,GAAG,GAAsB;AAAA,UACvB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,MAAM;AAAA,QACJ,GAAG,GAAsB;AAAA,UACvB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,KAAK;AAAA,QACH,GAAG,GAAsB;AAAA,UACvB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,IACF;AAAA,IACA,SAAS;AAAA,WACD,YAAW,GAA4C;AAAA,QAC3D,IAAI,KAAK,UAAU;AAAA,UACjB,MAAM,IAAI,UAAU,gCAAgC;AAAA,QACtD;AAAA,QACA,KAAK,WAAW;AAAA,QAChB,IAAI,CAAC,KAAK,MAAM;AAAA,UACd,OAAO,IAAI,YAAY,CAAC;AAAA,QAC1B;AAAA,QACA,OAAO,KAAK,KAAK,OAAO,MACtB,KAAK,KAAK,YACV,KAAK,KAAK,aAAa,KAAK,KAAK,UACnC;AAAA;AAAA,WAEI,KAAI,GAAuC;AAAA,QAC/C,IAAI,KAAK,UAAU;AAAA,UACjB,MAAM,IAAI,UAAU,gCAAgC;AAAA,QACtD;AAAA,QACA,KAAK,WAAW;AAAA,QAChB,MAAM,cACJ,KAAK,aAAa,QAAQ,IAAI,cAAc,IAAI,MAAM;AAAA,QACxD,OAAO;AAAA,UACL,OAAO,KAAK,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC;AAAA,UAClC,MAAM;AAAA,UACN,MAAM,KAAK,MAAM,UAAU;AAAA,QAC7B;AAAA;AAAA,MAMF,kBAAkB,GAUhB;AAAA,QACA,IAAI,KAAK,UAAU;AAAA,UACjB,MAAM,IAAI,UAAU,gCAAgC;AAAA,QACtD;AAAA,QACA,IAAI,KAAK,aAAa,UAAU;AAAA,UAC9B,MAAM,IAAI,UAAU,2CAA2C;AAAA,QACjE;AAAA,QAGA,MAAM,eAAwC,CAAC;AAAA,QAC/C,YAAY,KAAK,WAAW,KAAK,aAAa,SAAS;AAAA,UACrD,aAAa,KAAK,CAAC,KAAK,OAAO,KAAK,IAAI,CAAC,CAAC;AAAA,QAC5C;AAAA,QAEA,OAAO;AAAA,UACL,QAAQ,KAAK;AAAA,UACb,YAAY,KAAK;AAAA,UACjB,SAAS;AAAA,UACT,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK,IAAI,IAAI;AAAA,UAC1C,KAAK,KAAK;AAAA,UACV,YAAY,KAAK;AAAA,UACjB,MAAM,KAAK;AAAA,UACX,IAAI,KAAK;AAAA,UACT,UAAU,KAAK,YAAY;AAAA,QAC7B;AAAA;AAAA,WAEI,KAAI,GAAwC;AAAA,QAChD,IAAI,KAAK,UAAU;AAAA,UACjB,MAAM,IAAI,UAAU,gCAAgC;AAAA,QACtD;AAAA,QACA,KAAK,WAAW;AAAA,QAChB,IAAI,CAAC,KAAK,MAAM;AAAA,UACd,OAAO,KAAK,MAAM,EAAE;AAAA,QACtB;AAAA,QACA,MAAM,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,IAAI;AAAA,QAC/C,OAAO,KAAK,MAAM,IAAI;AAAA;AAAA,WAElB,KAAI,GAAuC;AAAA,QAC/C,IAAI,KAAK,UAAU;AAAA,UACjB,MAAM,IAAI,UAAU,gCAAgC;AAAA,QACtD;AAAA,QACA,KAAK,WAAW;AAAA,QAChB,IAAI,CAAC,KAAK,MAAM;AAAA,UACd,OAAO;AAAA,QACT;AAAA,QACA,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,IAAI;AAAA;AAAA,WAErC,SAAQ,GAA8C;AAAA,QAC1D,IAAI,KAAK,UAAU;AAAA,UACjB,MAAM,IAAI,UAAU,gCAAgC;AAAA,QACtD;AAAA,QACA,KAAK,WAAW;AAAA,QAChB,IAAI,CAAC,KAAK,MAAM;AAAA,UACd,OAAO,EAAE,SAAS,CAAC,EAAE;AAAA,QACvB;AAAA,QAEA,MAAM,cAAc,KAAK,aAAa,QAAQ,IAAI,cAAc,IAAI,MAAM;AAAA,QAE1E,IAAI,YAAY,SAAS,qBAAqB,GAAG;AAAA,UAC/C,OAAO,wCAAuB,KAAK,MAAM,WAAW;AAAA,QACtD,EAAO,SAAI,YAAY,SAAS,mCAAmC,GAAG;AAAA,UACpE,OAAO,yCAAwB,KAAK,IAAI;AAAA,QAC1C;AAAA,QAEA,MAAM,IAAI,UAAU,qCAAqC;AAAA;AAAA,MAE3D,gBAAgB,GAA+B;AAAA,QAC7C,OAAO,KAAK,aAAa;AAAA;AAAA,MAE3B,uBAAuB,GAA0C;AAAA,QAC/D,OAAO,KAAK;AAAA;AAAA,IAEhB;AAAA,EACF,CAAC;AAAA,EAED,OAAO;AAAA;AAOF,SAAS,wBAAwB,CAAC,SAA+B;AAAA,EACtE,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsC1B,MAAM,SAAS,QAAQ,SAAS,iBAAiB;AAAA,EACjD,IAAI,OAAO,OAAO;AAAA,IAChB,OAAO,MAAM,QAAQ;AAAA,EACvB,EAAO;AAAA,IACL,OAAO,MAAM,QAAQ;AAAA;AAAA;AAYlB,SAAS,sBAAsB,CAAC,SAA+B;AAAA,EACpE,MAAM,SAAS,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAwB/B;AAAA,EAED,IAAI,OAAO,OAAO;AAAA,IAChB,OAAO,MAAM,QAAQ;AAAA,EACvB,EAAO;AAAA,IACL,OAAO,MAAM,QAAQ;AAAA;AAAA;AAOlB,SAAS,qBAAqB,CAAC,OAA0D;AAAA,EAE9F,IAAI,6BAAgB,KAAK,GAAG;AAAA,IAE1B,IAAI,MAAM,aAAa,UAAU;AAAA,MAC/B,MAAM,IAAI,MAAM,uEAAuE;AAAA,IACzF;AAAA,IAGA,IAAI,QAAwB;AAAA,IAC5B,IAAI,MAAM,MAAM;AAAA,MACd,IAAI,MAAM,aAAa,UAAU;AAAA,QAC/B,QAAO,IAAI,YAAY,EAAE,OAAO,MAAM,IAAI;AAAA,MAC5C,EAAO;AAAA,QACL,QAAO,MAAM,KAAK,OAAO,MACvB,MAAM,KAAK,YACX,MAAM,KAAK,aAAa,MAAM,KAAK,UACrC;AAAA;AAAA,IAEJ;AAAA,IAEA,OAAO,IAAI,SAAS,OAAM;AAAA,MACxB,QAAQ,MAAM;AAAA,MACd,YAAY,MAAM;AAAA,MAClB,SAAS,oCAAqB,MAAM,YAAY;AAAA,IAClD,CAAC;AAAA,EACH;AAAA,EAGA,MAAM,WAAW;AAAA,EACjB,MAAM,WAAW,SAAS;AAAA,EAE1B,IAAI,aAAa,UAAU;AAAA,IACzB,MAAM,IAAI,MAAM,uEAAuE;AAAA,EACzF;AAAA,EAEA,MAAM,SAAS,OAAO,SAAS,WAAW,WAAW,SAAS,SAAS;AAAA,EACvE,MAAM,aAAa,OAAO,SAAS,eAAe,WAAW,SAAS,aAAa;AAAA,EAGnF,IAAI,eAA6B,EAAE,SAAS,IAAI,IAAM;AAAA,EACtD,IAAI,SAAS,WAAW,OAAO,SAAS,YAAY,UAAU;AAAA,IAC5D,MAAM,mBAAmB,SAAS;AAAA,IAClC,IAAI,4BAAe,gBAAgB,GAAG;AAAA,MACpC,eAAe,EAAE,SAAS,IAAI,IAAI,iBAAiB,OAAO,EAAE;AAAA,IAC9D;AAAA,EACF;AAAA,EAGA,IAAI,OAAwB;AAAA,EAC5B,MAAM,YAAY,SAAS;AAAA,EAC3B,IAAI,qBAAqB,YAAY;AAAA,IACnC,IAAI,aAAa,UAAU;AAAA,MACzB,OAAO,IAAI,YAAY,EAAE,OAAO,SAAS;AAAA,IAC3C,EAAO;AAAA,MACL,OAAO,UAAU,OAAO,MACtB,UAAU,YACV,UAAU,aAAa,UAAU,UACnC;AAAA;AAAA,EAEJ;AAAA,EAEA,OAAO,IAAI,SAAS,MAAM;AAAA,IACxB;AAAA,IACA;AAAA,IACA,SAAS,oCAAqB,YAAY;AAAA,EAC5C,CAAC;AAAA;AAMH,eAAsB,6BAA6B,CACjD,UACwB;AAAA,EACxB,MAAM,OAAO,SAAS,OAClB,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC,IAC3C;AAAA,EAEJ,MAAM,eAA6B,EAAE,SAAS,IAAI,IAAM;AAAA,EACxD,SAAS,QAAQ,QAAQ,CAAC,OAAO,QAAQ;AAAA,IACvC,MAAM,WAAW,aAAa,QAAQ,IAAI,IAAI,YAAY,CAAC,KAAK,CAAC;AAAA,IACjE,SAAS,KAAK,KAAK;AAAA,IACnB,aAAa,QAAQ,IAAI,IAAI,YAAY,GAAG,QAAQ;AAAA,GACrD;AAAA,EAGD,MAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;AAAA,EACvD,IAAI,WAAuC;AAAA,EAC3C,IAAI,MAAM;AAAA,IACR,IAAI,gBAAgB,YAAY,WAAW,OAAO,KAAK,YAAY,SAAS,MAAM,KAAK,YAAY,SAAS,KAAK,IAAI;AAAA,MACnH,WAAW;AAAA,IACb,EAAO;AAAA,MACL,WAAW;AAAA;AAAA,EAEf;AAAA,EAEA,OAAO;AAAA,IACL,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,KAAK,SAAS;AAAA,IACd,YAAY,SAAS;AAAA,IACrB,MAAM,SAAS;AAAA,IACf,IAAI,SAAS;AAAA,IACb;AAAA,EACF;AAAA;",
|
|
8
|
+
"debugId": "AD1E3EACF3B32FC464756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/cjs/handle.cjs
CHANGED
|
@@ -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
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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=
|
|
347
|
+
//# debugId=2F54439D2001225C64756E2164756E21
|