@ricsam/quickjs-fetch 0.0.1 → 0.2.1

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.
Files changed (59) hide show
  1. package/README.md +109 -43
  2. package/dist/cjs/abort-controller.cjs +212 -0
  3. package/dist/cjs/abort-controller.cjs.map +10 -0
  4. package/dist/cjs/fetch.cjs +199 -0
  5. package/dist/cjs/fetch.cjs.map +10 -0
  6. package/dist/cjs/form-data.cjs +289 -0
  7. package/dist/cjs/form-data.cjs.map +10 -0
  8. package/dist/cjs/handle.cjs +248 -0
  9. package/dist/cjs/handle.cjs.map +10 -0
  10. package/dist/cjs/headers.cjs +196 -0
  11. package/dist/cjs/headers.cjs.map +10 -0
  12. package/dist/cjs/index.cjs +47 -0
  13. package/dist/cjs/index.cjs.map +10 -0
  14. package/dist/cjs/package.json +5 -0
  15. package/dist/cjs/request.cjs +315 -0
  16. package/dist/cjs/request.cjs.map +10 -0
  17. package/dist/cjs/response.cjs +315 -0
  18. package/dist/cjs/response.cjs.map +10 -0
  19. package/dist/cjs/serve.cjs +182 -0
  20. package/dist/cjs/serve.cjs.map +10 -0
  21. package/dist/cjs/setup.cjs +119 -0
  22. package/dist/cjs/setup.cjs.map +10 -0
  23. package/dist/cjs/types.cjs +26 -0
  24. package/dist/cjs/types.cjs.map +9 -0
  25. package/dist/mjs/abort-controller.mjs +181 -0
  26. package/dist/mjs/abort-controller.mjs.map +10 -0
  27. package/dist/mjs/fetch.mjs +168 -0
  28. package/dist/mjs/fetch.mjs.map +10 -0
  29. package/dist/mjs/form-data.mjs +258 -0
  30. package/dist/mjs/form-data.mjs.map +10 -0
  31. package/dist/mjs/handle.mjs +217 -0
  32. package/dist/mjs/handle.mjs.map +10 -0
  33. package/dist/mjs/headers.mjs +165 -0
  34. package/dist/mjs/headers.mjs.map +10 -0
  35. package/dist/mjs/index.mjs +22 -0
  36. package/dist/mjs/index.mjs.map +10 -0
  37. package/dist/mjs/package.json +5 -0
  38. package/dist/mjs/request.mjs +284 -0
  39. package/dist/mjs/request.mjs.map +10 -0
  40. package/dist/mjs/response.mjs +284 -0
  41. package/dist/mjs/response.mjs.map +10 -0
  42. package/dist/mjs/serve.mjs +151 -0
  43. package/dist/mjs/serve.mjs.map +10 -0
  44. package/dist/mjs/setup.mjs +92 -0
  45. package/dist/mjs/setup.mjs.map +10 -0
  46. package/dist/mjs/types.mjs +3 -0
  47. package/dist/mjs/types.mjs.map +9 -0
  48. package/dist/types/globals/abort-controller.d.ts +9 -0
  49. package/dist/types/globals/fetch.d.ts +5 -0
  50. package/dist/types/globals/form-data.d.ts +37 -0
  51. package/dist/types/globals/headers.d.ts +36 -0
  52. package/dist/types/globals/request.d.ts +16 -0
  53. package/dist/types/globals/response.d.ts +25 -0
  54. package/dist/types/globals/serve.d.ts +16 -0
  55. package/dist/types/handle.d.ts +6 -0
  56. package/dist/types/index.d.ts +5 -0
  57. package/dist/types/setup.d.ts +48 -0
  58. package/dist/types/types.d.ts +175 -0
  59. package/package.json +51 -6
@@ -0,0 +1,119 @@
1
+ // @bun @bun-cjs
2
+ (function(exports, require, module, __filename, __dirname) {var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
7
+ var __toCommonJS = (from) => {
8
+ var entry = __moduleCache.get(from), desc;
9
+ if (entry)
10
+ return entry;
11
+ entry = __defProp({}, "__esModule", { value: true });
12
+ if (from && typeof from === "object" || typeof from === "function")
13
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
14
+ get: () => from[key],
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ }));
17
+ __moduleCache.set(from, entry);
18
+ return entry;
19
+ };
20
+ var __export = (target, all) => {
21
+ for (var name in all)
22
+ __defProp(target, name, {
23
+ get: all[name],
24
+ enumerable: true,
25
+ configurable: true,
26
+ set: (newValue) => all[name] = () => newValue
27
+ });
28
+ };
29
+
30
+ // packages/fetch/src/setup.ts
31
+ var exports_setup = {};
32
+ __export(exports_setup, {
33
+ setupFetch: () => setupFetch
34
+ });
35
+ module.exports = __toCommonJS(exports_setup);
36
+ var import_quickjs_core = require("@ricsam/quickjs-core");
37
+ var import_headers = require("./globals/headers.ts");
38
+ var import_request = require("./globals/request.ts");
39
+ var import_response = require("./globals/response.ts");
40
+ var import_abort_controller = require("./globals/abort-controller.ts");
41
+ var import_form_data = require("./globals/form-data.ts");
42
+ var import_fetch = require("./globals/fetch.ts");
43
+ var import_serve = require("./globals/serve.ts");
44
+ var import_handle = require("./handle.ts");
45
+ function setupFetch(context, options = {}) {
46
+ const coreHandle = options.coreHandle ?? import_quickjs_core.setupCore(context, {
47
+ stateMap: options.stateMap
48
+ });
49
+ const stateMap = options.stateMap ?? coreHandle.stateMap;
50
+ const serveState = {
51
+ fetchHandler: null,
52
+ websocketHandlers: {},
53
+ pendingUpgrade: null,
54
+ activeConnections: new Map
55
+ };
56
+ const wsCommandCallbacks = new Set;
57
+ const dispatchWsCommand = (cmd) => {
58
+ for (const cb of wsCommandCallbacks) {
59
+ cb(cmd);
60
+ }
61
+ };
62
+ const streamFactory = (source) => import_quickjs_core.createReadableStream(context, stateMap, source);
63
+ const HeadersClass = import_headers.createHeadersClass(context, stateMap);
64
+ context.setProp(context.global, "Headers", HeadersClass);
65
+ HeadersClass.dispose();
66
+ const iteratorResult = context.evalCode(`
67
+ Headers.prototype[Symbol.iterator] = function() {
68
+ return this.entries()[Symbol.iterator]();
69
+ };
70
+ `);
71
+ if (iteratorResult.error) {
72
+ iteratorResult.error.dispose();
73
+ } else {
74
+ iteratorResult.value.dispose();
75
+ }
76
+ const RequestClass = import_request.createRequestClass(context, stateMap, streamFactory);
77
+ context.setProp(context.global, "Request", RequestClass);
78
+ RequestClass.dispose();
79
+ const ResponseClass = import_response.createResponseClass(context, stateMap, streamFactory);
80
+ context.setProp(context.global, "Response", ResponseClass);
81
+ ResponseClass.dispose();
82
+ import_response.addResponseStaticMethods(context);
83
+ import_abort_controller.setupAbortControllerAndSignal(context);
84
+ const FormDataClass = import_form_data.createFormDataClass(context, stateMap);
85
+ context.setProp(context.global, "FormData", FormDataClass);
86
+ FormDataClass.dispose();
87
+ const formDataIteratorResult = context.evalCode(`
88
+ FormData.prototype[Symbol.iterator] = function() {
89
+ return this.entries()[Symbol.iterator]();
90
+ };
91
+ `);
92
+ if (formDataIteratorResult.error) {
93
+ formDataIteratorResult.error.dispose();
94
+ } else {
95
+ formDataIteratorResult.value.dispose();
96
+ }
97
+ const ServerWebSocketClass = import_serve.createServerWebSocketClass(context, stateMap, dispatchWsCommand);
98
+ context.setProp(context.global, "__ServerWebSocket__", ServerWebSocketClass);
99
+ ServerWebSocketClass.dispose();
100
+ const ServerClass = import_serve.createServerClass(context, stateMap, serveState);
101
+ context.setProp(context.global, "__Server__", ServerClass);
102
+ ServerClass.dispose();
103
+ const fetchFn = import_fetch.createFetchFunction(context, options.onFetch);
104
+ context.setProp(context.global, "fetch", fetchFn);
105
+ fetchFn.dispose();
106
+ const serveFn = import_serve.createServeFunction(context, stateMap, serveState);
107
+ context.setProp(context.global, "serve", serveFn);
108
+ serveFn.dispose();
109
+ const fetchHandle = import_handle.createFetchHandle(context, stateMap, serveState);
110
+ const originalOnWebSocketCommand = fetchHandle.onWebSocketCommand;
111
+ fetchHandle.onWebSocketCommand = (callback) => {
112
+ wsCommandCallbacks.add(callback);
113
+ return () => wsCommandCallbacks.delete(callback);
114
+ };
115
+ return fetchHandle;
116
+ }
117
+ })
118
+
119
+ //# debugId=44954C27AE5818A564756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/setup.ts"],
4
+ "sourcesContent": [
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { setupCore, createStateMap, createReadableStream } from \"@ricsam/quickjs-core\";\nimport type { SetupFetchOptions, FetchHandle, ServeState } from \"./types.ts\";\nimport { createHeadersClass } from \"./globals/headers.ts\";\nimport { createRequestClass } from \"./globals/request.ts\";\nimport { createResponseClass, addResponseStaticMethods } from \"./globals/response.ts\";\nimport { setupAbortControllerAndSignal } from \"./globals/abort-controller.ts\";\nimport { createFormDataClass } from \"./globals/form-data.ts\";\nimport { createFetchFunction } from \"./globals/fetch.ts\";\nimport {\n createServeFunction,\n createServerClass,\n createServerWebSocketClass,\n} from \"./globals/serve.ts\";\nimport { createFetchHandle } from \"./handle.ts\";\n\n/**\n * Setup Fetch API in a QuickJS context\n *\n * Injects the following globals:\n * - fetch\n * - Request\n * - Response\n * - Headers\n * - AbortController\n * - AbortSignal\n * - serve\n * - FormData\n *\n * Also sets up Core APIs (Streams, Blob, File) if not already present.\n *\n * **Private globals (internal use):**\n * - `__Server__` - Server class for serve() handler, instantiated via evalCode\n * - `__ServerWebSocket__` - WebSocket class for connection handling\n * - `__scheduleTimeout__` - Host function to schedule AbortSignal.timeout()\n * - `__checkTimeout__` - Host function to check if timeout elapsed\n *\n * These private globals follow the `__Name__` convention and are required for\n * JavaScript code in QuickJS to create class instances via evalCode.\n * See PATTERNS.md section 5 for details.\n *\n * @example\n * const handle = setupFetch(context, {\n * onFetch: async (request) => {\n * // Proxy to real fetch\n * return fetch(request);\n * }\n * });\n *\n * context.evalCode(`\n * serve({\n * fetch(request, server) {\n * return new Response(\"Hello!\");\n * }\n * });\n * `);\n *\n * const response = await handle.dispatchRequest(\n * new Request(\"http://localhost/\")\n * );\n */\nexport function setupFetch(\n context: QuickJSContext,\n options: SetupFetchOptions = {}\n): FetchHandle {\n // Setup core if not already done\n const coreHandle =\n options.coreHandle ??\n setupCore(context, {\n stateMap: options.stateMap,\n });\n\n const stateMap = options.stateMap ?? coreHandle.stateMap;\n\n // Create serve state\n const serveState: ServeState = {\n fetchHandler: null,\n websocketHandlers: {},\n pendingUpgrade: null,\n activeConnections: new Map(),\n };\n\n // WebSocket command dispatcher\n const wsCommandCallbacks = new Set<\n (cmd: import(\"./types.ts\").WebSocketCommand) => void\n >();\n const dispatchWsCommand = (cmd: import(\"./types.ts\").WebSocketCommand) => {\n for (const cb of wsCommandCallbacks) {\n cb(cmd);\n }\n };\n\n // Create stream factory for Request/Response body\n const streamFactory = (source: UnderlyingSource) =>\n createReadableStream(context, stateMap, source);\n\n // Create Headers class\n const HeadersClass = createHeadersClass(context, stateMap);\n context.setProp(context.global, \"Headers\", HeadersClass);\n HeadersClass.dispose();\n\n // Add Symbol.iterator support for Headers (for...of, Array.from, spread)\n const iteratorResult = context.evalCode(`\n Headers.prototype[Symbol.iterator] = function() {\n return this.entries()[Symbol.iterator]();\n };\n `);\n if (iteratorResult.error) {\n iteratorResult.error.dispose();\n } else {\n iteratorResult.value.dispose();\n }\n\n // Create Request class\n const RequestClass = createRequestClass(context, stateMap, streamFactory);\n context.setProp(context.global, \"Request\", RequestClass);\n RequestClass.dispose();\n\n // Create Response class\n const ResponseClass = createResponseClass(context, stateMap, streamFactory);\n context.setProp(context.global, \"Response\", ResponseClass);\n ResponseClass.dispose();\n\n // Add Response static methods (must be after Response and Headers are on global)\n addResponseStaticMethods(context);\n\n // Create AbortSignal and AbortController classes (pure QuickJS implementation)\n setupAbortControllerAndSignal(context);\n\n // Create FormData class\n const FormDataClass = createFormDataClass(context, stateMap);\n context.setProp(context.global, \"FormData\", FormDataClass);\n FormDataClass.dispose();\n\n // Add Symbol.iterator support for FormData (for...of, Array.from, spread)\n const formDataIteratorResult = context.evalCode(`\n FormData.prototype[Symbol.iterator] = function() {\n return this.entries()[Symbol.iterator]();\n };\n `);\n if (formDataIteratorResult.error) {\n formDataIteratorResult.error.dispose();\n } else {\n formDataIteratorResult.value.dispose();\n }\n\n // Create ServerWebSocket class (internal, for WebSocket handling)\n const ServerWebSocketClass = createServerWebSocketClass(\n context,\n stateMap,\n dispatchWsCommand\n );\n // Set on global with internal name so we can use evalCode to instantiate\n context.setProp(context.global, \"__ServerWebSocket__\", ServerWebSocketClass);\n ServerWebSocketClass.dispose();\n // Note: ServerWebSocketClass handle is now owned by global\n\n // Create Server class (internal, passed to fetch handler)\n const ServerClass = createServerClass(context, stateMap, serveState);\n // Set on global with internal name so we can use evalCode to instantiate\n context.setProp(context.global, \"__Server__\", ServerClass);\n ServerClass.dispose();\n // Note: ServerClass handle is now owned by global\n\n // Create fetch function\n const fetchFn = createFetchFunction(context, options.onFetch);\n context.setProp(context.global, \"fetch\", fetchFn);\n fetchFn.dispose();\n\n // Create serve function\n const serveFn = createServeFunction(context, stateMap, serveState);\n context.setProp(context.global, \"serve\", serveFn);\n serveFn.dispose();\n\n // Create and return the handle\n const fetchHandle = createFetchHandle(\n context,\n stateMap,\n serveState\n );\n\n // Wire up WebSocket command callbacks\n const originalOnWebSocketCommand = fetchHandle.onWebSocketCommand;\n fetchHandle.onWebSocketCommand = (callback) => {\n wsCommandCallbacks.add(callback);\n return () => wsCommandCallbacks.delete(callback);\n };\n\n return fetchHandle;\n}\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACgE,IAAhE;AAEmC,IAAnC;AACmC,IAAnC;AAC8D,IAA9D;AAC8C,IAA9C;AACoC,IAApC;AACoC,IAApC;AAKO,IAJP;AAKkC,IAAlC;AA+CO,SAAS,UAAU,CACxB,SACA,UAA6B,CAAC,GACjB;AAAA,EAEb,MAAM,aACJ,QAAQ,cACR,8BAAU,SAAS;AAAA,IACjB,UAAU,QAAQ;AAAA,EACpB,CAAC;AAAA,EAEH,MAAM,WAAW,QAAQ,YAAY,WAAW;AAAA,EAGhD,MAAM,aAAyB;AAAA,IAC7B,cAAc;AAAA,IACd,mBAAmB,CAAC;AAAA,IACpB,gBAAgB;AAAA,IAChB,mBAAmB,IAAI;AAAA,EACzB;AAAA,EAGA,MAAM,qBAAqB,IAAI;AAAA,EAG/B,MAAM,oBAAoB,CAAC,QAA+C;AAAA,IACxE,WAAW,MAAM,oBAAoB;AAAA,MACnC,GAAG,GAAG;AAAA,IACR;AAAA;AAAA,EAIF,MAAM,gBAAgB,CAAC,WACrB,yCAAqB,SAAS,UAAU,MAAM;AAAA,EAGhD,MAAM,eAAe,kCAAmB,SAAS,QAAQ;AAAA,EACzD,QAAQ,QAAQ,QAAQ,QAAQ,WAAW,YAAY;AAAA,EACvD,aAAa,QAAQ;AAAA,EAGrB,MAAM,iBAAiB,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,GAIvC;AAAA,EACD,IAAI,eAAe,OAAO;AAAA,IACxB,eAAe,MAAM,QAAQ;AAAA,EAC/B,EAAO;AAAA,IACL,eAAe,MAAM,QAAQ;AAAA;AAAA,EAI/B,MAAM,eAAe,kCAAmB,SAAS,UAAU,aAAa;AAAA,EACxE,QAAQ,QAAQ,QAAQ,QAAQ,WAAW,YAAY;AAAA,EACvD,aAAa,QAAQ;AAAA,EAGrB,MAAM,gBAAgB,oCAAoB,SAAS,UAAU,aAAa;AAAA,EAC1E,QAAQ,QAAQ,QAAQ,QAAQ,YAAY,aAAa;AAAA,EACzD,cAAc,QAAQ;AAAA,EAGtB,yCAAyB,OAAO;AAAA,EAGhC,sDAA8B,OAAO;AAAA,EAGrC,MAAM,gBAAgB,qCAAoB,SAAS,QAAQ;AAAA,EAC3D,QAAQ,QAAQ,QAAQ,QAAQ,YAAY,aAAa;AAAA,EACzD,cAAc,QAAQ;AAAA,EAGtB,MAAM,yBAAyB,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,GAI/C;AAAA,EACD,IAAI,uBAAuB,OAAO;AAAA,IAChC,uBAAuB,MAAM,QAAQ;AAAA,EACvC,EAAO;AAAA,IACL,uBAAuB,MAAM,QAAQ;AAAA;AAAA,EAIvC,MAAM,uBAAuB,wCAC3B,SACA,UACA,iBACF;AAAA,EAEA,QAAQ,QAAQ,QAAQ,QAAQ,uBAAuB,oBAAoB;AAAA,EAC3E,qBAAqB,QAAQ;AAAA,EAI7B,MAAM,cAAc,+BAAkB,SAAS,UAAU,UAAU;AAAA,EAEnE,QAAQ,QAAQ,QAAQ,QAAQ,cAAc,WAAW;AAAA,EACzD,YAAY,QAAQ;AAAA,EAIpB,MAAM,UAAU,iCAAoB,SAAS,QAAQ,OAAO;AAAA,EAC5D,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,OAAO;AAAA,EAChD,QAAQ,QAAQ;AAAA,EAGhB,MAAM,UAAU,iCAAoB,SAAS,UAAU,UAAU;AAAA,EACjE,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,OAAO;AAAA,EAChD,QAAQ,QAAQ;AAAA,EAGhB,MAAM,cAAc,gCAClB,SACA,UACA,UACF;AAAA,EAGA,MAAM,6BAA6B,YAAY;AAAA,EAC/C,YAAY,qBAAqB,CAAC,aAAa;AAAA,IAC7C,mBAAmB,IAAI,QAAQ;AAAA,IAC/B,OAAO,MAAM,mBAAmB,OAAO,QAAQ;AAAA;AAAA,EAGjD,OAAO;AAAA;",
8
+ "debugId": "44954C27AE5818A564756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,26 @@
1
+ // @bun @bun-cjs
2
+ (function(exports, require, module, __filename, __dirname) {var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
7
+ var __toCommonJS = (from) => {
8
+ var entry = __moduleCache.get(from), desc;
9
+ if (entry)
10
+ return entry;
11
+ entry = __defProp({}, "__esModule", { value: true });
12
+ if (from && typeof from === "object" || typeof from === "function")
13
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
14
+ get: () => from[key],
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ }));
17
+ __moduleCache.set(from, entry);
18
+ return entry;
19
+ };
20
+
21
+ // packages/fetch/src/types.ts
22
+ var exports_types = {};
23
+ module.exports = __toCommonJS(exports_types);
24
+ })
25
+
26
+ //# debugId=215C36070677FEE964756E2164756E21
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [
5
+ ],
6
+ "mappings": "",
7
+ "debugId": "215C36070677FEE964756E2164756E21",
8
+ "names": []
9
+ }
@@ -0,0 +1,181 @@
1
+ // @bun
2
+ // packages/fetch/src/globals/abort-controller.ts
3
+ function setupAbortControllerAndSignal(context) {
4
+ const pendingTimeouts = new Map;
5
+ let nextTimeoutId = 1;
6
+ const scheduleTimeoutFn = context.newFunction("__scheduleTimeout__", (msHandle) => {
7
+ const ms = context.getNumber(msHandle);
8
+ const timeoutId = nextTimeoutId++;
9
+ const hostTimeoutId = setTimeout(() => {
10
+ pendingTimeouts.delete(timeoutId);
11
+ }, ms);
12
+ pendingTimeouts.set(timeoutId, hostTimeoutId);
13
+ return context.newNumber(timeoutId);
14
+ });
15
+ const checkTimeoutFn = context.newFunction("__checkTimeout__", (timeoutIdHandle) => {
16
+ const timeoutId = context.getNumber(timeoutIdHandle);
17
+ const isElapsed = !pendingTimeouts.has(timeoutId);
18
+ return isElapsed ? context.true : context.false;
19
+ });
20
+ context.setProp(context.global, "__scheduleTimeout__", scheduleTimeoutFn);
21
+ context.setProp(context.global, "__checkTimeout__", checkTimeoutFn);
22
+ scheduleTimeoutFn.dispose();
23
+ checkTimeoutFn.dispose();
24
+ const result = context.evalCode(`
25
+ (function() {
26
+ const signalState = new WeakMap();
27
+
28
+ class AbortSignal {
29
+ constructor() {
30
+ signalState.set(this, {
31
+ aborted: false,
32
+ reason: undefined,
33
+ listeners: []
34
+ });
35
+ }
36
+
37
+ get aborted() {
38
+ return signalState.get(this).aborted;
39
+ }
40
+
41
+ get reason() {
42
+ return signalState.get(this).reason;
43
+ }
44
+
45
+ throwIfAborted() {
46
+ const state = signalState.get(this);
47
+ if (state.aborted) {
48
+ throw state.reason ?? new DOMException("signal is aborted", "AbortError");
49
+ }
50
+ }
51
+
52
+ addEventListener(type, callback) {
53
+ if (type === "abort" && typeof callback === "function") {
54
+ signalState.get(this).listeners.push(callback);
55
+ }
56
+ }
57
+
58
+ removeEventListener(type, callback) {
59
+ if (type === "abort") {
60
+ const state = signalState.get(this);
61
+ const idx = state.listeners.indexOf(callback);
62
+ if (idx >= 0) state.listeners.splice(idx, 1);
63
+ }
64
+ }
65
+
66
+ static abort(reason) {
67
+ const signal = new AbortSignal();
68
+ const state = signalState.get(signal);
69
+ state.aborted = true;
70
+ state.reason = reason ?? new DOMException("signal is aborted", "AbortError");
71
+ return signal;
72
+ }
73
+
74
+ static timeout(ms) {
75
+ const signal = new AbortSignal();
76
+ const state = signalState.get(signal);
77
+ const timeoutId = __scheduleTimeout__(Number(ms));
78
+
79
+ // Store timeout info for later checking
80
+ state.timeoutId = timeoutId;
81
+ state.timeoutReason = new DOMException("signal timed out", "TimeoutError");
82
+
83
+ return signal;
84
+ }
85
+
86
+ // Internal method to check and trigger timeout
87
+ __checkAndTriggerTimeout__() {
88
+ const state = signalState.get(this);
89
+ if (state.aborted || state.timeoutId === undefined) {
90
+ return false;
91
+ }
92
+
93
+ if (__checkTimeout__(state.timeoutId)) {
94
+ state.aborted = true;
95
+ state.reason = state.timeoutReason;
96
+ delete state.timeoutId;
97
+ delete state.timeoutReason;
98
+
99
+ for (const cb of state.listeners) {
100
+ try { cb(); } catch {}
101
+ }
102
+ return true;
103
+ }
104
+ return false;
105
+ }
106
+
107
+ static any(signals) {
108
+ const signal = new AbortSignal();
109
+ const state = signalState.get(signal);
110
+
111
+ if (!Array.isArray(signals)) return signal;
112
+
113
+ for (const s of signals) {
114
+ if (s && typeof s === "object" && "aborted" in s) {
115
+ // Check timeout signals
116
+ if (s.__checkAndTriggerTimeout__) {
117
+ s.__checkAndTriggerTimeout__();
118
+ }
119
+
120
+ if (s.aborted) {
121
+ state.aborted = true;
122
+ state.reason = s.reason;
123
+ return signal;
124
+ }
125
+ s.addEventListener("abort", () => {
126
+ if (!state.aborted) {
127
+ state.aborted = true;
128
+ state.reason = s.reason;
129
+ for (const cb of state.listeners) {
130
+ try { cb(); } catch {}
131
+ }
132
+ }
133
+ });
134
+ }
135
+ }
136
+ return signal;
137
+ }
138
+ }
139
+
140
+ const controllerState = new WeakMap();
141
+
142
+ class AbortController {
143
+ constructor() {
144
+ const signal = new AbortSignal();
145
+ controllerState.set(this, { signal });
146
+ }
147
+
148
+ get signal() {
149
+ return controllerState.get(this).signal;
150
+ }
151
+
152
+ abort(reason) {
153
+ const signal = controllerState.get(this).signal;
154
+ const state = signalState.get(signal);
155
+ if (state.aborted) return;
156
+
157
+ state.aborted = true;
158
+ state.reason = reason ?? new DOMException("signal is aborted", "AbortError");
159
+
160
+ for (const cb of state.listeners) {
161
+ try { cb(); } catch {}
162
+ }
163
+ }
164
+ }
165
+
166
+ globalThis.AbortSignal = AbortSignal;
167
+ globalThis.AbortController = AbortController;
168
+ })();
169
+ `);
170
+ if (result.error) {
171
+ const error = context.dump(result.error);
172
+ result.error.dispose();
173
+ throw new Error(`Failed to setup AbortController: ${JSON.stringify(error)}`);
174
+ }
175
+ result.value.dispose();
176
+ }
177
+ export {
178
+ setupAbortControllerAndSignal
179
+ };
180
+
181
+ //# debugId=6DD39F43A7A1BBC664756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/globals/abort-controller.ts"],
4
+ "sourcesContent": [
5
+ "import type { QuickJSContext } from \"quickjs-emscripten\";\n\n/**\n * Setup AbortController and AbortSignal classes in QuickJS.\n * Uses pure QuickJS implementation so that:\n * - controller.signal returns an actual AbortSignal instance\n * - Event listeners work correctly\n * - All prototype methods are accessible\n */\nexport function setupAbortControllerAndSignal(context: QuickJSContext): void {\n // Track signals for timeout feature - we need to call back into QuickJS after a delay\n const pendingTimeouts = new Map<number, ReturnType<typeof setTimeout>>();\n let nextTimeoutId = 1;\n\n // Create a host function that schedules a timeout and returns an ID\n const scheduleTimeoutFn = context.newFunction(\"__scheduleTimeout__\", (msHandle) => {\n const ms = context.getNumber(msHandle);\n const timeoutId = nextTimeoutId++;\n\n // Schedule the timeout - we'll call back into QuickJS using a polling mechanism\n const hostTimeoutId = setTimeout(() => {\n pendingTimeouts.delete(timeoutId);\n }, ms);\n\n pendingTimeouts.set(timeoutId, hostTimeoutId);\n return context.newNumber(timeoutId);\n });\n\n // Create a host function to check if a timeout has elapsed\n const checkTimeoutFn = context.newFunction(\"__checkTimeout__\", (timeoutIdHandle) => {\n const timeoutId = context.getNumber(timeoutIdHandle);\n // If the timeout is no longer in pendingTimeouts, it has elapsed\n const isElapsed = !pendingTimeouts.has(timeoutId);\n return isElapsed ? context.true : context.false;\n });\n\n context.setProp(context.global, \"__scheduleTimeout__\", scheduleTimeoutFn);\n context.setProp(context.global, \"__checkTimeout__\", checkTimeoutFn);\n scheduleTimeoutFn.dispose();\n checkTimeoutFn.dispose();\n\n // Use WeakMap for private state (more compatible than private fields)\n // Note: AbortSignal.timeout() uses a polling approach since we can't easily\n // call back into QuickJS from a host setTimeout callback\n const result = context.evalCode(`\n (function() {\n const signalState = new WeakMap();\n\n class AbortSignal {\n constructor() {\n signalState.set(this, {\n aborted: false,\n reason: undefined,\n listeners: []\n });\n }\n\n get aborted() {\n return signalState.get(this).aborted;\n }\n\n get reason() {\n return signalState.get(this).reason;\n }\n\n throwIfAborted() {\n const state = signalState.get(this);\n if (state.aborted) {\n throw state.reason ?? new DOMException(\"signal is aborted\", \"AbortError\");\n }\n }\n\n addEventListener(type, callback) {\n if (type === \"abort\" && typeof callback === \"function\") {\n signalState.get(this).listeners.push(callback);\n }\n }\n\n removeEventListener(type, callback) {\n if (type === \"abort\") {\n const state = signalState.get(this);\n const idx = state.listeners.indexOf(callback);\n if (idx >= 0) state.listeners.splice(idx, 1);\n }\n }\n\n static abort(reason) {\n const signal = new AbortSignal();\n const state = signalState.get(signal);\n state.aborted = true;\n state.reason = reason ?? new DOMException(\"signal is aborted\", \"AbortError\");\n return signal;\n }\n\n static timeout(ms) {\n const signal = new AbortSignal();\n const state = signalState.get(signal);\n const timeoutId = __scheduleTimeout__(Number(ms));\n\n // Store timeout info for later checking\n state.timeoutId = timeoutId;\n state.timeoutReason = new DOMException(\"signal timed out\", \"TimeoutError\");\n\n return signal;\n }\n\n // Internal method to check and trigger timeout\n __checkAndTriggerTimeout__() {\n const state = signalState.get(this);\n if (state.aborted || state.timeoutId === undefined) {\n return false;\n }\n\n if (__checkTimeout__(state.timeoutId)) {\n state.aborted = true;\n state.reason = state.timeoutReason;\n delete state.timeoutId;\n delete state.timeoutReason;\n\n for (const cb of state.listeners) {\n try { cb(); } catch {}\n }\n return true;\n }\n return false;\n }\n\n static any(signals) {\n const signal = new AbortSignal();\n const state = signalState.get(signal);\n\n if (!Array.isArray(signals)) return signal;\n\n for (const s of signals) {\n if (s && typeof s === \"object\" && \"aborted\" in s) {\n // Check timeout signals\n if (s.__checkAndTriggerTimeout__) {\n s.__checkAndTriggerTimeout__();\n }\n\n if (s.aborted) {\n state.aborted = true;\n state.reason = s.reason;\n return signal;\n }\n s.addEventListener(\"abort\", () => {\n if (!state.aborted) {\n state.aborted = true;\n state.reason = s.reason;\n for (const cb of state.listeners) {\n try { cb(); } catch {}\n }\n }\n });\n }\n }\n return signal;\n }\n }\n\n const controllerState = new WeakMap();\n\n class AbortController {\n constructor() {\n const signal = new AbortSignal();\n controllerState.set(this, { signal });\n }\n\n get signal() {\n return controllerState.get(this).signal;\n }\n\n abort(reason) {\n const signal = controllerState.get(this).signal;\n const state = signalState.get(signal);\n if (state.aborted) return;\n\n state.aborted = true;\n state.reason = reason ?? new DOMException(\"signal is aborted\", \"AbortError\");\n\n for (const cb of state.listeners) {\n try { cb(); } catch {}\n }\n }\n }\n\n globalThis.AbortSignal = AbortSignal;\n globalThis.AbortController = AbortController;\n })();\n `);\n\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to setup AbortController: ${JSON.stringify(error)}`);\n }\n result.value.dispose();\n}\n"
6
+ ],
7
+ "mappings": ";;AASO,SAAS,6BAA6B,CAAC,SAA+B;AAAA,EAE3E,MAAM,kBAAkB,IAAI;AAAA,EAC5B,IAAI,gBAAgB;AAAA,EAGpB,MAAM,oBAAoB,QAAQ,YAAY,uBAAuB,CAAC,aAAa;AAAA,IACjF,MAAM,KAAK,QAAQ,UAAU,QAAQ;AAAA,IACrC,MAAM,YAAY;AAAA,IAGlB,MAAM,gBAAgB,WAAW,MAAM;AAAA,MACrC,gBAAgB,OAAO,SAAS;AAAA,OAC/B,EAAE;AAAA,IAEL,gBAAgB,IAAI,WAAW,aAAa;AAAA,IAC5C,OAAO,QAAQ,UAAU,SAAS;AAAA,GACnC;AAAA,EAGD,MAAM,iBAAiB,QAAQ,YAAY,oBAAoB,CAAC,oBAAoB;AAAA,IAClF,MAAM,YAAY,QAAQ,UAAU,eAAe;AAAA,IAEnD,MAAM,YAAY,CAAC,gBAAgB,IAAI,SAAS;AAAA,IAChD,OAAO,YAAY,QAAQ,OAAO,QAAQ;AAAA,GAC3C;AAAA,EAED,QAAQ,QAAQ,QAAQ,QAAQ,uBAAuB,iBAAiB;AAAA,EACxE,QAAQ,QAAQ,QAAQ,QAAQ,oBAAoB,cAAc;AAAA,EAClE,kBAAkB,QAAQ;AAAA,EAC1B,eAAe,QAAQ;AAAA,EAKvB,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAiJ/B;AAAA,EAED,IAAI,OAAO,OAAO;AAAA,IAChB,MAAM,QAAQ,QAAQ,KAAK,OAAO,KAAK;AAAA,IACvC,OAAO,MAAM,QAAQ;AAAA,IACrB,MAAM,IAAI,MAAM,oCAAoC,KAAK,UAAU,KAAK,GAAG;AAAA,EAC7E;AAAA,EACA,OAAO,MAAM,QAAQ;AAAA;",
8
+ "debugId": "6DD39F43A7A1BBC664756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,168 @@
1
+ // @bun
2
+ // packages/fetch/src/globals/fetch.ts
3
+ import { unmarshal, marshal } from "@ricsam/quickjs-core";
4
+ import { headersStateToNative } from "./headers.ts";
5
+ import { createResponseStateFromNative } from "./response.ts";
6
+ function createFetchFunction(context, onFetch) {
7
+ return context.newFunction("fetch", (...argHandles) => {
8
+ const deferred = context.newPromise();
9
+ const inputHandle = argHandles[0];
10
+ const initHandle = argHandles[1];
11
+ let signalHandle = null;
12
+ if (initHandle !== undefined) {
13
+ const initType = context.typeof(initHandle);
14
+ if (initType === "object") {
15
+ const tempSignal = context.getProp(initHandle, "signal");
16
+ const signalType = context.typeof(tempSignal);
17
+ if (signalType !== "undefined" && signalType !== "null") {
18
+ signalHandle = tempSignal;
19
+ } else {
20
+ tempSignal.dispose();
21
+ }
22
+ }
23
+ }
24
+ let isPreAborted = false;
25
+ let abortReason;
26
+ if (signalHandle) {
27
+ const abortedHandle = context.getProp(signalHandle, "aborted");
28
+ isPreAborted = Boolean(context.dump(abortedHandle));
29
+ abortedHandle.dispose();
30
+ if (isPreAborted) {
31
+ const reasonHandle = context.getProp(signalHandle, "reason");
32
+ abortReason = context.dump(reasonHandle);
33
+ reasonHandle.dispose();
34
+ signalHandle.dispose();
35
+ signalHandle = null;
36
+ }
37
+ }
38
+ if (isPreAborted) {
39
+ Promise.resolve().then(() => {
40
+ const errorMessage = abortReason?.message || "signal is aborted without reason";
41
+ const safeMessage = errorMessage.replace(/"/g, "\\\"");
42
+ const errorResult = context.evalCode(`new DOMException("${safeMessage}", "AbortError")`);
43
+ if ("value" in errorResult) {
44
+ deferred.reject(errorResult.value);
45
+ errorResult.value.dispose();
46
+ } else {
47
+ const fallbackError = marshal(context, { name: "AbortError", message: errorMessage });
48
+ deferred.reject(fallbackError);
49
+ fallbackError.dispose();
50
+ errorResult.error.dispose();
51
+ }
52
+ context.runtime.executePendingJobs();
53
+ });
54
+ return deferred.handle;
55
+ }
56
+ const nativeController = new AbortController;
57
+ if (signalHandle) {
58
+ const abortCallback = context.newFunction("__fetchAbortCallback__", () => {
59
+ nativeController.abort();
60
+ return context.undefined;
61
+ });
62
+ const addEventListenerHandle = context.getProp(signalHandle, "addEventListener");
63
+ const typeHandle = context.newString("abort");
64
+ context.callFunction(addEventListenerHandle, signalHandle, typeHandle, abortCallback);
65
+ typeHandle.dispose();
66
+ addEventListenerHandle.dispose();
67
+ abortCallback.dispose();
68
+ signalHandle.dispose();
69
+ }
70
+ const input = inputHandle ? unmarshal(context, inputHandle) : undefined;
71
+ const init = initHandle ? unmarshal(context, initHandle) : undefined;
72
+ let url = "";
73
+ let method = "GET";
74
+ let headers = new Headers;
75
+ let body = null;
76
+ if (typeof input === "string") {
77
+ url = input;
78
+ } else if (input && typeof input === "object" && "url" in input) {
79
+ const reqState = input;
80
+ url = reqState.url;
81
+ method = reqState.method;
82
+ headers = headersStateToNative(reqState.headersState);
83
+ if (reqState.body) {
84
+ body = reqState.body;
85
+ }
86
+ }
87
+ if (init) {
88
+ if (init.method) {
89
+ method = init.method;
90
+ }
91
+ if (init.headers) {
92
+ if (init.headers && typeof init.headers === "object" && "headers" in init.headers) {
93
+ headers = headersStateToNative(init.headers);
94
+ } else {
95
+ headers = new Headers;
96
+ for (const [key, value] of Object.entries(init.headers)) {
97
+ headers.set(key, String(value));
98
+ }
99
+ }
100
+ }
101
+ if (init.body !== undefined) {
102
+ if (typeof init.body === "string") {
103
+ body = init.body;
104
+ } else if (init.body instanceof ArrayBuffer) {
105
+ body = init.body;
106
+ } else if (init.body instanceof Uint8Array) {
107
+ body = init.body;
108
+ } else if (init.body && typeof init.body === "object" && "parts" in init.body) {
109
+ const parts = init.body.parts;
110
+ const totalLength = parts.reduce((sum, p) => sum + p.length, 0);
111
+ const combined = new Uint8Array(totalLength);
112
+ let offset = 0;
113
+ for (const part of parts) {
114
+ combined.set(part, offset);
115
+ offset += part.length;
116
+ }
117
+ body = combined;
118
+ }
119
+ }
120
+ }
121
+ Promise.resolve().then(async () => {
122
+ try {
123
+ if (!onFetch) {
124
+ throw new Error("fetch is not configured - no onFetch handler provided to setupFetch");
125
+ }
126
+ const nativeRequest = new Request(url, {
127
+ method,
128
+ headers,
129
+ body: method !== "GET" && method !== "HEAD" ? body : undefined,
130
+ signal: nativeController.signal
131
+ });
132
+ const nativeResponse = await onFetch(nativeRequest);
133
+ const responseState = await createResponseStateFromNative(nativeResponse);
134
+ const resultHandle = marshal(context, responseState);
135
+ deferred.resolve(resultHandle);
136
+ resultHandle.dispose();
137
+ } catch (error) {
138
+ if (error instanceof DOMException && error.name === "AbortError") {
139
+ const safeMessage = error.message.replace(/"/g, "\\\"");
140
+ const errorResult = context.evalCode(`new DOMException("${safeMessage}", "AbortError")`);
141
+ if ("value" in errorResult) {
142
+ deferred.reject(errorResult.value);
143
+ errorResult.value.dispose();
144
+ } else {
145
+ const fallbackError = marshal(context, { name: "AbortError", message: error.message });
146
+ deferred.reject(fallbackError);
147
+ fallbackError.dispose();
148
+ errorResult.error.dispose();
149
+ }
150
+ } else {
151
+ const errorHandle = marshal(context, {
152
+ name: error instanceof Error ? error.name : "Error",
153
+ message: error instanceof Error ? error.message : String(error)
154
+ });
155
+ deferred.reject(errorHandle);
156
+ errorHandle.dispose();
157
+ }
158
+ }
159
+ context.runtime.executePendingJobs();
160
+ });
161
+ return deferred.handle;
162
+ });
163
+ }
164
+ export {
165
+ createFetchFunction
166
+ };
167
+
168
+ //# debugId=9A6BA5BFF80ED1FD64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/globals/fetch.ts"],
4
+ "sourcesContent": [
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { unmarshal, marshal } from \"@ricsam/quickjs-core\";\nimport type { RequestState, HeadersState } from \"../types.ts\";\nimport { headersStateToNative } from \"./headers.ts\";\nimport { createResponseStateFromNative } from \"./response.ts\";\n\n/**\n * Create the fetch function for QuickJS\n */\nexport function createFetchFunction(\n context: QuickJSContext,\n onFetch?: (request: Request) => Promise<Response>\n): QuickJSHandle {\n return context.newFunction(\"fetch\", (...argHandles) => {\n // Create promise first\n const deferred = context.newPromise();\n\n const inputHandle = argHandles[0];\n const initHandle = argHandles[1];\n\n // Extract signal BEFORE unmarshalling (keep as handle)\n let signalHandle: QuickJSHandle | null = null;\n // Check if initHandle exists and is a valid QuickJS handle (not JS undefined)\n if (initHandle !== undefined) {\n const initType = context.typeof(initHandle);\n if (initType === \"object\") {\n const tempSignal = context.getProp(initHandle, \"signal\");\n const signalType = context.typeof(tempSignal);\n if (signalType !== \"undefined\" && signalType !== \"null\") {\n signalHandle = tempSignal;\n } else {\n tempSignal.dispose();\n }\n }\n }\n\n // Check if signal is pre-aborted\n let isPreAborted = false;\n let abortReason: { message?: string } | undefined;\n if (signalHandle) {\n const abortedHandle = context.getProp(signalHandle, \"aborted\");\n isPreAborted = Boolean(context.dump(abortedHandle));\n abortedHandle.dispose();\n\n if (isPreAborted) {\n const reasonHandle = context.getProp(signalHandle, \"reason\");\n abortReason = context.dump(reasonHandle) as { message?: string } | undefined;\n reasonHandle.dispose();\n signalHandle.dispose();\n signalHandle = null;\n }\n }\n\n // If pre-aborted, reject immediately in a microtask\n if (isPreAborted) {\n Promise.resolve().then(() => {\n // Create DOMException and reject\n const errorMessage = abortReason?.message || \"signal is aborted without reason\";\n // Escape quotes in the message for safety\n const safeMessage = errorMessage.replace(/\"/g, '\\\\\"');\n const errorResult = context.evalCode(\n `new DOMException(\"${safeMessage}\", \"AbortError\")`\n );\n if (\"value\" in errorResult) {\n deferred.reject(errorResult.value);\n errorResult.value.dispose();\n } else {\n // If evalCode failed, create a plain error\n const fallbackError = marshal(context, { name: \"AbortError\", message: errorMessage });\n deferred.reject(fallbackError);\n fallbackError.dispose();\n errorResult.error.dispose();\n }\n context.runtime.executePendingJobs();\n });\n return deferred.handle;\n }\n\n // Create native AbortController\n const nativeController = new AbortController();\n\n // Wire QuickJS signal to native controller\n if (signalHandle) {\n // Create callback that aborts native controller when QuickJS signal aborts\n const abortCallback = context.newFunction(\"__fetchAbortCallback__\", () => {\n nativeController.abort();\n return context.undefined;\n });\n\n // Call addEventListener on the QuickJS signal\n const addEventListenerHandle = context.getProp(signalHandle, \"addEventListener\");\n const typeHandle = context.newString(\"abort\");\n\n context.callFunction(addEventListenerHandle, signalHandle, typeHandle, abortCallback);\n\n typeHandle.dispose();\n addEventListenerHandle.dispose();\n abortCallback.dispose();\n signalHandle.dispose();\n }\n\n // Unmarshal arguments\n const input = inputHandle ? unmarshal(context, inputHandle) : undefined;\n const init = initHandle ? unmarshal(context, initHandle) as {\n method?: string;\n headers?: object;\n body?: unknown;\n } | undefined : undefined;\n\n // Build the request\n let url = \"\";\n let method = \"GET\";\n let headers = new Headers();\n let body: BodyInit | null = null;\n\n if (typeof input === \"string\") {\n url = input;\n } else if (input && typeof input === \"object\" && \"url\" in input) {\n // Request-like object from QuickJS\n const reqState = input as RequestState;\n url = reqState.url;\n method = reqState.method;\n headers = headersStateToNative(reqState.headersState);\n if (reqState.body) {\n body = reqState.body as BodyInit;\n }\n }\n\n // Apply init overrides\n if (init) {\n if (init.method) {\n method = init.method;\n }\n if (init.headers) {\n if (\n init.headers &&\n typeof init.headers === \"object\" &&\n \"headers\" in init.headers\n ) {\n headers = headersStateToNative(init.headers as HeadersState);\n } else {\n headers = new Headers();\n for (const [key, value] of Object.entries(init.headers)) {\n headers.set(key, String(value));\n }\n }\n }\n if (init.body !== undefined) {\n if (typeof init.body === \"string\") {\n body = init.body;\n } else if (init.body instanceof ArrayBuffer) {\n body = init.body;\n } else if (init.body instanceof Uint8Array) {\n body = init.body as BodyInit;\n } else if (\n init.body &&\n typeof init.body === \"object\" &&\n \"parts\" in init.body\n ) {\n // Blob-like\n const parts = (init.body as { parts: Uint8Array[] }).parts;\n const totalLength = parts.reduce((sum, p) => sum + p.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n combined.set(part, offset);\n offset += part.length;\n }\n body = combined as BodyInit;\n }\n }\n }\n\n // Run the async fetch operation in a microtask to ensure proper promise settling\n Promise.resolve().then(async () => {\n try {\n if (!onFetch) {\n throw new Error(\n \"fetch is not configured - no onFetch handler provided to setupFetch\"\n );\n }\n\n // Create native Request with signal\n const nativeRequest = new Request(url, {\n method,\n headers,\n body: method !== \"GET\" && method !== \"HEAD\" ? body : undefined,\n signal: nativeController.signal,\n });\n\n // Call the host fetch handler\n const nativeResponse = await onFetch(nativeRequest);\n\n // Convert to ResponseState for QuickJS\n const responseState = await createResponseStateFromNative(nativeResponse);\n const resultHandle = marshal(context, responseState);\n deferred.resolve(resultHandle);\n resultHandle.dispose();\n } catch (error) {\n // Handle abort errors specially\n if (error instanceof DOMException && error.name === \"AbortError\") {\n const safeMessage = error.message.replace(/\"/g, '\\\\\"');\n const errorResult = context.evalCode(\n `new DOMException(\"${safeMessage}\", \"AbortError\")`\n );\n if (\"value\" in errorResult) {\n deferred.reject(errorResult.value);\n errorResult.value.dispose();\n } else {\n const fallbackError = marshal(context, { name: \"AbortError\", message: error.message });\n deferred.reject(fallbackError);\n fallbackError.dispose();\n errorResult.error.dispose();\n }\n } else {\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n }\n }\n context.runtime.executePendingJobs();\n });\n\n return deferred.handle;\n });\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "9A6BA5BFF80ED1FD64756E2164756E21",
9
+ "names": []
10
+ }