@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/headers.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass } from \"@ricsam/quickjs-core\";\nimport type { HeadersState } from \"../types.mjs\";\n\n/**\n * Create the Headers class for QuickJS\n */\nexport function createHeadersClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<HeadersState>(context, stateMap, {\n name: \"Headers\",\n construct: (args) => {\n const init = args[0];\n
|
|
5
|
+
"import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass, coerceHeaders } from \"@ricsam/quickjs-core\";\nimport type { HeadersState } from \"../types.mjs\";\n\n/**\n * Create the Headers class for QuickJS\n */\nexport function createHeadersClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<HeadersState>(context, stateMap, {\n name: \"Headers\",\n construct: (args) => {\n const init = args[0];\n // Use coercion to handle all input types consistently\n const coerced = coerceHeaders.safeParse(init);\n if (coerced.success) {\n return coerced.value;\n }\n // Fallback to empty headers if coercion fails\n return { headers: new Map<string, string[]>() };\n },\n methods: {\n append(this: HeadersState, name: unknown, value: unknown) {\n const key = String(name).toLowerCase();\n const existing = this.headers.get(key) || [];\n existing.push(String(value));\n this.headers.set(key, existing);\n },\n delete(this: HeadersState, name: unknown) {\n this.headers.delete(String(name).toLowerCase());\n },\n get(this: HeadersState, name: unknown): string | null {\n const values = this.headers.get(String(name).toLowerCase());\n return values ? values.join(\", \") : null;\n },\n has(this: HeadersState, name: unknown): boolean {\n return this.headers.has(String(name).toLowerCase());\n },\n set(this: HeadersState, name: unknown, value: unknown) {\n this.headers.set(String(name).toLowerCase(), [String(value)]);\n },\n entries(this: HeadersState): Array<[string, string]> {\n const result: Array<[string, string]> = [];\n for (const [key, values] of this.headers) {\n result.push([key, values.join(\", \")]);\n }\n return result;\n },\n keys(this: HeadersState): string[] {\n return Array.from(this.headers.keys());\n },\n values(this: HeadersState): string[] {\n const result: string[] = [];\n for (const values of this.headers.values()) {\n result.push(values.join(\", \"));\n }\n return result;\n },\n forEach(this: HeadersState, callback: unknown) {\n if (typeof callback !== \"function\") {\n throw new TypeError(\"callback must be a function\");\n }\n for (const [key, values] of this.headers) {\n (callback as (value: string, key: string, parent: HeadersState) => void)(\n values.join(\", \"),\n key,\n this\n );\n }\n },\n getSetCookie(this: HeadersState): string[] {\n return this.headers.get(\"set-cookie\") || [];\n },\n },\n });\n}\n\n/**\n * Create a HeadersState from a native Headers object\n */\nexport function createHeadersStateFromNative(headers: Headers): HeadersState {\n const map = new Map<string, string[]>();\n headers.forEach((value, key) => {\n const existing = map.get(key.toLowerCase()) || [];\n existing.push(value);\n map.set(key.toLowerCase(), existing);\n });\n return { headers: map };\n}\n\n/**\n * Convert HeadersState to native Headers\n */\nexport function headersStateToNative(state: HeadersState): Headers {\n const headers = new Headers();\n for (const [key, values] of state.headers) {\n for (const value of values) {\n headers.append(key, value);\n }\n }\n return headers;\n}\n\n/**\n * Interface for a Headers-like object that can be returned from getters\n */\nexport interface HeadersLike {\n headers: Map<string, string[]>;\n append(name: string, value: string): void;\n delete(name: string): void;\n get(name: string): string | null;\n has(name: string): boolean;\n set(name: string, value: string): void;\n entries(): Array<[string, string]>;\n keys(): string[];\n values(): string[];\n forEach(callback: (value: string, key: string) => void): void;\n getSetCookie(): string[];\n}\n\n/**\n * Create a Headers-like object from HeadersState that has all the Headers methods\n * This is used for getters that need to return an object with Headers API\n */\nexport function createHeadersLike(state: HeadersState): HeadersLike {\n return {\n headers: state.headers,\n append(name: string, value: string) {\n const key = name.toLowerCase();\n const existing = state.headers.get(key) || [];\n existing.push(value);\n state.headers.set(key, existing);\n },\n delete(name: string) {\n state.headers.delete(name.toLowerCase());\n },\n get(name: string): string | null {\n const values = state.headers.get(name.toLowerCase());\n return values ? values.join(\", \") : null;\n },\n has(name: string): boolean {\n return state.headers.has(name.toLowerCase());\n },\n set(name: string, value: string) {\n state.headers.set(name.toLowerCase(), [value]);\n },\n entries(): Array<[string, string]> {\n const result: Array<[string, string]> = [];\n for (const [key, values] of state.headers) {\n result.push([key, values.join(\", \")]);\n }\n return result;\n },\n keys(): string[] {\n return Array.from(state.headers.keys());\n },\n values(): string[] {\n const result: string[] = [];\n for (const values of state.headers.values()) {\n result.push(values.join(\", \"));\n }\n return result;\n },\n forEach(callback: (value: string, key: string) => void) {\n for (const [key, values] of state.headers) {\n callback(values.join(\", \"), key);\n }\n },\n getSetCookie(): string[] {\n return state.headers.get(\"set-cookie\") || [];\n },\n };\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;AAEA;AAMO,SAAS,kBAAkB,CAChC,SACA,UACe;AAAA,EACf,OAAO,YAA0B,SAAS,UAAU;AAAA,IAClD,MAAM;AAAA,IACN,WAAW,CAAC,SAAS;AAAA,MACnB,MAAM,OAAO,KAAK;AAAA,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "18F0F0F61ED7D24064756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/fetch/src/globals/request.ts
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
defineClass,
|
|
5
|
+
getInstanceStateById,
|
|
6
|
+
isInstanceOf,
|
|
7
|
+
getClassInstanceState,
|
|
8
|
+
coerceHeaders,
|
|
9
|
+
coerceBody
|
|
10
|
+
} from "@ricsam/quickjs-core";
|
|
11
|
+
import { isHeadersState, isAbortSignalState } from "../types.mjs";
|
|
4
12
|
import { createHeadersStateFromNative, createHeadersLike } from "./headers.mjs";
|
|
5
13
|
import { parseMultipartFormData, parseUrlEncodedFormData } from "./form-data.mjs";
|
|
6
14
|
import { startNativeStreamReader } from "../upload-stream-queue.mjs";
|
|
@@ -90,70 +98,120 @@ function createRequestClass(context, stateMap, streamHelpers) {
|
|
|
90
98
|
const input = args[0];
|
|
91
99
|
const init = args[1];
|
|
92
100
|
let url = "";
|
|
93
|
-
let method = "GET";
|
|
94
|
-
let headersState = { headers: new Map };
|
|
95
|
-
let body = null;
|
|
96
|
-
let signal = null;
|
|
97
101
|
if (typeof input === "string") {
|
|
98
102
|
url = input;
|
|
99
103
|
} else if (input && typeof input === "object") {
|
|
100
|
-
if ("
|
|
104
|
+
if (isInstanceOf(input, "URL")) {
|
|
105
|
+
const urlState = getClassInstanceState(input);
|
|
106
|
+
if (urlState && urlState.href) {
|
|
107
|
+
url = urlState.href;
|
|
108
|
+
}
|
|
109
|
+
} else if (isInstanceOf(input, "Request")) {
|
|
110
|
+
const requestState = getClassInstanceState(input);
|
|
111
|
+
if (requestState) {
|
|
112
|
+
url = requestState.url;
|
|
113
|
+
}
|
|
114
|
+
} else if ("href" in input && typeof input.href === "string") {
|
|
115
|
+
url = input.href;
|
|
116
|
+
} else if ("url" in input) {
|
|
101
117
|
url = String(input.url);
|
|
102
118
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
119
|
+
}
|
|
120
|
+
let method = "GET";
|
|
121
|
+
let headersState = { headers: new Map };
|
|
122
|
+
let body = null;
|
|
123
|
+
let signal = null;
|
|
124
|
+
let cache = "default";
|
|
125
|
+
let credentials = "same-origin";
|
|
126
|
+
let integrity = "";
|
|
127
|
+
let keepalive = false;
|
|
128
|
+
let mode = "cors";
|
|
129
|
+
let redirect = "follow";
|
|
130
|
+
let referrer = "about:client";
|
|
131
|
+
let referrerPolicy = "";
|
|
132
|
+
if (input && typeof input === "object") {
|
|
133
|
+
if (isInstanceOf(input, "Request")) {
|
|
134
|
+
const requestState = getClassInstanceState(input);
|
|
135
|
+
if (requestState) {
|
|
136
|
+
method = requestState.method;
|
|
137
|
+
headersState = { headers: new Map(requestState.headersState.headers) };
|
|
138
|
+
body = requestState.body;
|
|
139
|
+
signal = requestState.signal;
|
|
140
|
+
cache = requestState.cache;
|
|
141
|
+
credentials = requestState.credentials;
|
|
142
|
+
integrity = requestState.integrity;
|
|
143
|
+
keepalive = requestState.keepalive;
|
|
144
|
+
mode = requestState.mode;
|
|
145
|
+
redirect = requestState.redirect;
|
|
146
|
+
referrer = requestState.referrer;
|
|
147
|
+
referrerPolicy = requestState.referrerPolicy;
|
|
148
|
+
}
|
|
149
|
+
} else if (!isInstanceOf(input, "URL")) {
|
|
150
|
+
const inputObj = input;
|
|
151
|
+
if ("method" in inputObj && typeof inputObj.method === "string") {
|
|
152
|
+
method = inputObj.method;
|
|
153
|
+
}
|
|
154
|
+
if ("headersState" in inputObj && isHeadersState(inputObj.headersState)) {
|
|
155
|
+
headersState = { headers: new Map(inputObj.headersState.headers) };
|
|
156
|
+
}
|
|
157
|
+
if ("body" in inputObj && inputObj.body) {
|
|
158
|
+
body = coerceBody(inputObj.body);
|
|
159
|
+
}
|
|
160
|
+
if ("signal" in inputObj && isAbortSignalState(inputObj.signal)) {
|
|
161
|
+
signal = inputObj.signal;
|
|
162
|
+
}
|
|
117
163
|
}
|
|
118
164
|
}
|
|
119
|
-
if (init) {
|
|
165
|
+
if (init && isInstanceOf(init, "Request")) {
|
|
166
|
+
const initRequestState = getClassInstanceState(init);
|
|
167
|
+
if (initRequestState) {
|
|
168
|
+
if (!isInstanceOf(input, "Request")) {
|
|
169
|
+
method = initRequestState.method;
|
|
170
|
+
headersState = { headers: new Map(initRequestState.headersState.headers) };
|
|
171
|
+
body = initRequestState.body;
|
|
172
|
+
signal = initRequestState.signal;
|
|
173
|
+
cache = initRequestState.cache;
|
|
174
|
+
credentials = initRequestState.credentials;
|
|
175
|
+
integrity = initRequestState.integrity;
|
|
176
|
+
keepalive = initRequestState.keepalive;
|
|
177
|
+
mode = initRequestState.mode;
|
|
178
|
+
redirect = initRequestState.redirect;
|
|
179
|
+
referrer = initRequestState.referrer;
|
|
180
|
+
referrerPolicy = initRequestState.referrerPolicy;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
} else if (init) {
|
|
120
184
|
if (init.method) {
|
|
121
185
|
method = init.method.toUpperCase();
|
|
122
186
|
}
|
|
123
|
-
if (init.headers) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
headers: new Map(init.headers.headers)
|
|
128
|
-
};
|
|
129
|
-
} else if ("__isDefineClassInstance__" in init.headers && init.headers.__isDefineClassInstance__ === true && "__instanceId__" in init.headers) {
|
|
130
|
-
const instanceId = init.headers.__instanceId__;
|
|
131
|
-
const state = getInstanceStateById(instanceId);
|
|
132
|
-
if (state && state.headers instanceof Map) {
|
|
133
|
-
headersState = {
|
|
134
|
-
headers: new Map(state.headers)
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
} else {
|
|
138
|
-
headersState = { headers: new Map };
|
|
139
|
-
for (const [key, value] of Object.entries(init.headers)) {
|
|
140
|
-
headersState.headers.set(key.toLowerCase(), [String(value)]);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
187
|
+
if (init.headers !== undefined) {
|
|
188
|
+
const coerced = coerceHeaders.safeParse(init.headers);
|
|
189
|
+
if (coerced.success) {
|
|
190
|
+
headersState = coerced.value;
|
|
143
191
|
}
|
|
144
192
|
}
|
|
145
|
-
if (init.body !== undefined
|
|
146
|
-
|
|
147
|
-
body = new TextEncoder().encode(init.body);
|
|
148
|
-
} else if (init.body instanceof ArrayBuffer) {
|
|
149
|
-
body = new Uint8Array(init.body);
|
|
150
|
-
} else if (init.body instanceof Uint8Array) {
|
|
151
|
-
body = init.body;
|
|
152
|
-
}
|
|
193
|
+
if (init.body !== undefined) {
|
|
194
|
+
body = coerceBody(init.body);
|
|
153
195
|
}
|
|
154
196
|
if (init.signal) {
|
|
155
197
|
signal = init.signal;
|
|
156
198
|
}
|
|
199
|
+
if (init.cache !== undefined)
|
|
200
|
+
cache = init.cache;
|
|
201
|
+
if (init.credentials !== undefined)
|
|
202
|
+
credentials = init.credentials;
|
|
203
|
+
if (init.integrity !== undefined)
|
|
204
|
+
integrity = init.integrity;
|
|
205
|
+
if (init.keepalive !== undefined)
|
|
206
|
+
keepalive = init.keepalive;
|
|
207
|
+
if (init.mode !== undefined)
|
|
208
|
+
mode = init.mode;
|
|
209
|
+
if (init.redirect !== undefined)
|
|
210
|
+
redirect = init.redirect;
|
|
211
|
+
if (init.referrer !== undefined)
|
|
212
|
+
referrer = init.referrer;
|
|
213
|
+
if (init.referrerPolicy !== undefined)
|
|
214
|
+
referrerPolicy = init.referrerPolicy;
|
|
157
215
|
}
|
|
158
216
|
return {
|
|
159
217
|
method,
|
|
@@ -161,15 +219,15 @@ function createRequestClass(context, stateMap, streamHelpers) {
|
|
|
161
219
|
headersState,
|
|
162
220
|
body,
|
|
163
221
|
bodyUsed: false,
|
|
164
|
-
cache
|
|
165
|
-
credentials
|
|
222
|
+
cache,
|
|
223
|
+
credentials,
|
|
166
224
|
destination: "",
|
|
167
|
-
integrity
|
|
168
|
-
keepalive
|
|
169
|
-
mode
|
|
170
|
-
redirect
|
|
171
|
-
referrer
|
|
172
|
-
referrerPolicy
|
|
225
|
+
integrity,
|
|
226
|
+
keepalive,
|
|
227
|
+
mode,
|
|
228
|
+
redirect,
|
|
229
|
+
referrer,
|
|
230
|
+
referrerPolicy,
|
|
173
231
|
signal
|
|
174
232
|
};
|
|
175
233
|
},
|
|
@@ -337,7 +395,7 @@ function createRequestClass(context, stateMap, streamHelpers) {
|
|
|
337
395
|
size: this.body?.length || 0
|
|
338
396
|
};
|
|
339
397
|
},
|
|
340
|
-
|
|
398
|
+
__getClonedState__() {
|
|
341
399
|
if (this.bodyUsed) {
|
|
342
400
|
throw new TypeError("Body has already been consumed");
|
|
343
401
|
}
|
|
@@ -347,13 +405,23 @@ function createRequestClass(context, stateMap, streamHelpers) {
|
|
|
347
405
|
if (this._uploadStreamInstanceId !== undefined) {
|
|
348
406
|
throw new TypeError("Cannot clone Request with streaming body");
|
|
349
407
|
}
|
|
408
|
+
const headersArray = [];
|
|
409
|
+
for (const [key, values] of this.headersState.headers) {
|
|
410
|
+
headersArray.push([key, values.join(", ")]);
|
|
411
|
+
}
|
|
350
412
|
return {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
413
|
+
method: this.method,
|
|
414
|
+
url: this.url,
|
|
415
|
+
headers: headersArray,
|
|
416
|
+
body: this.body ? Array.from(this.body) : null,
|
|
417
|
+
cache: this.cache,
|
|
418
|
+
credentials: this.credentials,
|
|
419
|
+
integrity: this.integrity,
|
|
420
|
+
keepalive: this.keepalive,
|
|
421
|
+
mode: this.mode,
|
|
422
|
+
redirect: this.redirect,
|
|
423
|
+
referrer: this.referrer,
|
|
424
|
+
referrerPolicy: this.referrerPolicy
|
|
357
425
|
};
|
|
358
426
|
},
|
|
359
427
|
async json() {
|
|
@@ -466,6 +534,46 @@ function addRequestFormDataMethod(context) {
|
|
|
466
534
|
result.value.dispose();
|
|
467
535
|
}
|
|
468
536
|
}
|
|
537
|
+
function addRequestCloneMethod(context) {
|
|
538
|
+
const result = context.evalCode(`
|
|
539
|
+
Request.prototype.clone = function() {
|
|
540
|
+
// Get cloned state from private method
|
|
541
|
+
const state = this.__getClonedState__();
|
|
542
|
+
|
|
543
|
+
// Create headers from the array of pairs
|
|
544
|
+
const headers = new Headers();
|
|
545
|
+
for (const [key, value] of state.headers) {
|
|
546
|
+
headers.set(key, value);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Convert body from number array back to Uint8Array if present
|
|
550
|
+
let body = null;
|
|
551
|
+
if (state.body) {
|
|
552
|
+
body = new Uint8Array(state.body);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// Create a proper Request instance
|
|
556
|
+
return new Request(state.url, {
|
|
557
|
+
method: state.method,
|
|
558
|
+
headers: headers,
|
|
559
|
+
body: body,
|
|
560
|
+
cache: state.cache,
|
|
561
|
+
credentials: state.credentials,
|
|
562
|
+
integrity: state.integrity,
|
|
563
|
+
keepalive: state.keepalive,
|
|
564
|
+
mode: state.mode,
|
|
565
|
+
redirect: state.redirect,
|
|
566
|
+
referrer: state.referrer,
|
|
567
|
+
referrerPolicy: state.referrerPolicy,
|
|
568
|
+
});
|
|
569
|
+
};
|
|
570
|
+
`);
|
|
571
|
+
if (result.error) {
|
|
572
|
+
result.error.dispose();
|
|
573
|
+
} else {
|
|
574
|
+
result.value.dispose();
|
|
575
|
+
}
|
|
576
|
+
}
|
|
469
577
|
function createRequestStateFromNative(request) {
|
|
470
578
|
return {
|
|
471
579
|
method: request.method,
|
|
@@ -489,7 +597,8 @@ function createRequestStateFromNative(request) {
|
|
|
489
597
|
export {
|
|
490
598
|
createRequestStateFromNative,
|
|
491
599
|
createRequestClass,
|
|
492
|
-
addRequestFormDataMethod
|
|
600
|
+
addRequestFormDataMethod,
|
|
601
|
+
addRequestCloneMethod
|
|
493
602
|
};
|
|
494
603
|
|
|
495
|
-
//# debugId=
|
|
604
|
+
//# debugId=E5A0F80A9B7BEC1464756E2164756E21
|
|
@@ -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.mjs\";\nimport { createHeadersStateFromNative, createHeadersLike } from \"./headers.mjs\";\nimport { parseMultipartFormData, parseUrlEncodedFormData } from \"./form-data.mjs\";\nimport { startNativeStreamReader } from \"../upload-stream-queue.mjs\";\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.mjs\";\nimport { isHeadersState, isAbortSignalState } from \"../types.mjs\";\nimport { createHeadersStateFromNative, createHeadersLike } from \"./headers.mjs\";\nimport { parseMultipartFormData, parseUrlEncodedFormData } from \"./form-data.mjs\";\nimport { startNativeStreamReader } from \"../upload-stream-queue.mjs\";\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": "E5A0F80A9B7BEC1464756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|