@ricsam/quickjs-fetch 0.2.13 → 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
package/dist/mjs/setup.mjs.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/setup.ts"],
|
|
4
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.mjs\";\nimport { createHeadersClass } from \"./globals/headers.mjs\";\nimport { createRequestClass, addRequestFormDataMethod } from \"./globals/request.mjs\";\nimport { createResponseClass, addResponseStaticMethods } from \"./globals/response.mjs\";\nimport { setupAbortControllerAndSignal } from \"./globals/abort-controller.mjs\";\nimport { createFormDataClass, addFormDataFileMethods } from \"./globals/form-data.mjs\";\nimport { createFetchFunction } from \"./globals/fetch.mjs\";\nimport {\n createServeFunction,\n createServerClass,\n createServerWebSocketClass,\n} from \"./globals/serve.mjs\";\nimport { createFetchHandle } from \"./handle.mjs\";\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.mjs\").WebSocketCommand) => void\n >();\n const dispatchWsCommand = (cmd: import(\"./types.mjs\").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 stream helpers for upload streaming\n const streamHelpers = {\n createStream: streamFactory,\n /**\n * Create an empty ReadableStream for upload streaming.\n *\n * IMPORTANT: We store the stream on a global variable and return the key.\n * This is necessary because __hostCall__ manages and disposes returned handles\n * in its scope. If we cached the handle and returned it multiple times,\n * subsequent calls would return a dead handle.\n *\n * The getter must call getStreamByKey() each time to get a fresh handle.\n */\n createEmptyStream: (): { instanceId: number; globalKey: string } => {\n const globalKey = `__uploadStream_${Date.now()}_${Math.random().toString(36).slice(2)}__`;\n const result = context.evalCode(`\n (function() {\n const stream = new ReadableStream();\n globalThis[\"${globalKey}\"] = stream;\n return stream.__instanceId__;\n })()\n `);\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create empty ReadableStream: ${JSON.stringify(error)}`);\n }\n const instanceId = context.getNumber(result.value);\n result.value.dispose();\n\n return { instanceId, globalKey };\n },\n /**\n * Get a fresh handle to the stream stored at globalKey.\n * This must be called each time the body getter is accessed to avoid\n * returning disposed handles.\n */\n getStreamByKey: (globalKey: string): import(\"quickjs-emscripten\").QuickJSHandle | null => {\n const result = context.evalCode(`globalThis[\"${globalKey}\"]`);\n if (result.error) {\n result.error.dispose();\n return null;\n }\n if (context.typeof(result.value) === \"undefined\") {\n result.value.dispose();\n return null;\n }\n return result.value;\n },\n pumpEventLoop: () => {\n context.runtime.executePendingJobs();\n },\n };\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, streamHelpers);\n context.setProp(context.global, \"Request\", RequestClass);\n RequestClass.dispose();\n\n // Note: No body getter wrapper needed - handles are returned directly\n // through __hostCall__ because quickjs-emscripten properly duplicates\n // handles via QTS_DupValuePointer before returning to QuickJS.\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 // Add Request.formData() method that returns a proper FormData instance\n // Must be after both Request and FormData are on global\n addRequestFormDataMethod(context);\n\n // Add FormData.get()/getAll() overrides to reconstruct File instances\n // Must be after both FormData and File are on global\n addFormDataFileMethods(context);\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 // Add pure-JS data getter to ServerWebSocket prototype\n // This getter reads from __upgradeRegistry__ using __connectionId__,\n // keeping complex data (like Zod schemas) entirely within QuickJS\n // to avoid marshalling depth limit issues\n const dataGetterResult = context.evalCode(`\n Object.defineProperty(__ServerWebSocket__.prototype, 'data', {\n get: function() {\n return __upgradeRegistry__.get(this.__connectionId__);\n },\n enumerable: true,\n configurable: true\n });\n `);\n if (dataGetterResult.error) {\n dataGetterResult.error.dispose();\n } else {\n dataGetterResult.value.dispose();\n }\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 // Setup upgrade registry and helper function for WebSocket upgrades\n // The registry keeps data within QuickJS to avoid marshalling complex objects\n const registryResult = context.evalCode(`\n globalThis.__upgradeRegistry__ = new Map();\n globalThis.__upgradeIdCounter__ = 0;\n `);\n if (registryResult.error) {\n registryResult.error.dispose();\n } else {\n registryResult.value.dispose();\n }\n\n // Host function to set pendingUpgrade - only receives connectionId string\n const setPendingUpgradeFn = context.newFunction(\n \"__setPendingUpgrade__\",\n (connIdHandle) => {\n const connectionId = context.getString(connIdHandle);\n serveState.pendingUpgrade = { requested: true, connectionId };\n return context.undefined;\n }\n );\n context.setProp(context.global, \"__setPendingUpgrade__\", setPendingUpgradeFn);\n setPendingUpgradeFn.dispose();\n\n // Add upgrade method to Server prototype as pure JavaScript\n // This keeps the data within QuickJS and only passes connectionId to host\n const upgradeMethodResult = context.evalCode(`\n __Server__.prototype.upgrade = function(request, options) {\n const data = options && typeof options === 'object' ? options.data : undefined;\n const connectionId = String(++globalThis.__upgradeIdCounter__);\n globalThis.__upgradeRegistry__.set(connectionId, data);\n __setPendingUpgrade__(connectionId);\n return true;\n };\n `);\n if (upgradeMethodResult.error) {\n upgradeMethodResult.error.dispose();\n } else {\n upgradeMethodResult.value.dispose();\n }\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"
|
|
5
|
+
"import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { setupCore, createStateMap, createReadableStream } from \"@ricsam/quickjs-core\";\nimport type { SetupFetchOptions, FetchHandle, ServeState } from \"./types.mjs\";\nimport { createHeadersClass } from \"./globals/headers.mjs\";\nimport { createRequestClass, addRequestFormDataMethod, addRequestCloneMethod } from \"./globals/request.mjs\";\nimport { createResponseClass, addResponseStaticMethods, addResponseCloneMethod } from \"./globals/response.mjs\";\nimport { setupAbortControllerAndSignal } from \"./globals/abort-controller.mjs\";\nimport { createFormDataClass, addFormDataFileMethods } from \"./globals/form-data.mjs\";\nimport { createFetchFunction } from \"./globals/fetch.mjs\";\nimport {\n createServeFunction,\n createServerClass,\n createServerWebSocketClass,\n} from \"./globals/serve.mjs\";\nimport { createFetchHandle } from \"./handle.mjs\";\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.mjs\").WebSocketCommand) => void\n >();\n const dispatchWsCommand = (cmd: import(\"./types.mjs\").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 stream helpers for upload streaming\n const streamHelpers = {\n createStream: streamFactory,\n /**\n * Create an empty ReadableStream for upload streaming.\n *\n * IMPORTANT: We store the stream on a global variable and return the key.\n * This is necessary because __hostCall__ manages and disposes returned handles\n * in its scope. If we cached the handle and returned it multiple times,\n * subsequent calls would return a dead handle.\n *\n * The getter must call getStreamByKey() each time to get a fresh handle.\n */\n createEmptyStream: (): { instanceId: number; globalKey: string } => {\n const globalKey = `__uploadStream_${Date.now()}_${Math.random().toString(36).slice(2)}__`;\n const result = context.evalCode(`\n (function() {\n const stream = new ReadableStream();\n globalThis[\"${globalKey}\"] = stream;\n return stream.__instanceId__;\n })()\n `);\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create empty ReadableStream: ${JSON.stringify(error)}`);\n }\n const instanceId = context.getNumber(result.value);\n result.value.dispose();\n\n return { instanceId, globalKey };\n },\n /**\n * Get a fresh handle to the stream stored at globalKey.\n * This must be called each time the body getter is accessed to avoid\n * returning disposed handles.\n */\n getStreamByKey: (globalKey: string): import(\"quickjs-emscripten\").QuickJSHandle | null => {\n const result = context.evalCode(`globalThis[\"${globalKey}\"]`);\n if (result.error) {\n result.error.dispose();\n return null;\n }\n if (context.typeof(result.value) === \"undefined\") {\n result.value.dispose();\n return null;\n }\n return result.value;\n },\n pumpEventLoop: () => {\n context.runtime.executePendingJobs();\n },\n };\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, streamHelpers);\n context.setProp(context.global, \"Request\", RequestClass);\n RequestClass.dispose();\n\n // Note: No body getter wrapper needed - handles are returned directly\n // through __hostCall__ because quickjs-emscripten properly duplicates\n // handles via QTS_DupValuePointer before returning to QuickJS.\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 // Add Request.formData() method that returns a proper FormData instance\n // Must be after both Request and FormData are on global\n addRequestFormDataMethod(context);\n\n // Add Request.clone() method that returns a proper Request instance\n // Must be after Request and Headers are on global\n addRequestCloneMethod(context);\n\n // Add Response.clone() method that returns a proper Response instance\n // Must be after Response and Headers are on global\n addResponseCloneMethod(context);\n\n // Add FormData.get()/getAll() overrides to reconstruct File instances\n // Must be after both FormData and File are on global\n addFormDataFileMethods(context);\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 // Add pure-JS data getter to ServerWebSocket prototype\n // This getter reads from __upgradeRegistry__ using __connectionId__,\n // keeping complex data (like Zod schemas) entirely within QuickJS\n // to avoid marshalling depth limit issues\n const dataGetterResult = context.evalCode(`\n Object.defineProperty(__ServerWebSocket__.prototype, 'data', {\n get: function() {\n return __upgradeRegistry__.get(this.__connectionId__);\n },\n enumerable: true,\n configurable: true\n });\n `);\n if (dataGetterResult.error) {\n dataGetterResult.error.dispose();\n } else {\n dataGetterResult.value.dispose();\n }\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 // Setup upgrade registry and helper function for WebSocket upgrades\n // The registry keeps data within QuickJS to avoid marshalling complex objects\n const registryResult = context.evalCode(`\n globalThis.__upgradeRegistry__ = new Map();\n globalThis.__upgradeIdCounter__ = 0;\n `);\n if (registryResult.error) {\n registryResult.error.dispose();\n } else {\n registryResult.value.dispose();\n }\n\n // Host function to set pendingUpgrade - only receives connectionId string\n const setPendingUpgradeFn = context.newFunction(\n \"__setPendingUpgrade__\",\n (connIdHandle) => {\n const connectionId = context.getString(connIdHandle);\n serveState.pendingUpgrade = { requested: true, connectionId };\n return context.undefined;\n }\n );\n context.setProp(context.global, \"__setPendingUpgrade__\", setPendingUpgradeFn);\n setPendingUpgradeFn.dispose();\n\n // Add upgrade method to Server prototype as pure JavaScript\n // This keeps the data within QuickJS and only passes connectionId to host\n const upgradeMethodResult = context.evalCode(`\n __Server__.prototype.upgrade = function(request, options) {\n const data = options && typeof options === 'object' ? options.data : undefined;\n const connectionId = String(++globalThis.__upgradeIdCounter__);\n globalThis.__upgradeRegistry__.set(connectionId, data);\n __setPendingUpgrade__(connectionId);\n return true;\n };\n `);\n if (upgradeMethodResult.error) {\n upgradeMethodResult.error.dispose();\n } else {\n upgradeMethodResult.value.dispose();\n }\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
6
|
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "0B557F24B4AAB22264756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/mjs/types.mjs
CHANGED
|
@@ -1,3 +1,44 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
// packages/fetch/src/types.ts
|
|
3
|
+
function isHeadersState(obj) {
|
|
4
|
+
return obj !== null && typeof obj === "object" && "headers" in obj && obj.headers instanceof Map;
|
|
5
|
+
}
|
|
6
|
+
function isRequestState(obj) {
|
|
7
|
+
if (obj === null || typeof obj !== "object")
|
|
8
|
+
return false;
|
|
9
|
+
const state = obj;
|
|
10
|
+
return typeof state.method === "string" && typeof state.url === "string" && isHeadersState(state.headersState);
|
|
11
|
+
}
|
|
12
|
+
function isResponseState(obj) {
|
|
13
|
+
if (obj === null || typeof obj !== "object")
|
|
14
|
+
return false;
|
|
15
|
+
const state = obj;
|
|
16
|
+
return typeof state.status === "number" && "headersState" in state && isHeadersState(state.headersState) && typeof state.bodyUsed === "boolean";
|
|
17
|
+
}
|
|
18
|
+
function isAbortSignalState(obj) {
|
|
19
|
+
if (obj === null || typeof obj !== "object")
|
|
20
|
+
return false;
|
|
21
|
+
const state = obj;
|
|
22
|
+
return typeof state.aborted === "boolean" && "listeners" in state && state.listeners instanceof Set;
|
|
23
|
+
}
|
|
24
|
+
function isUnmarshalledUint8Array(obj) {
|
|
25
|
+
if (obj === null || typeof obj !== "object")
|
|
26
|
+
return false;
|
|
27
|
+
if (!("0" in obj))
|
|
28
|
+
return false;
|
|
29
|
+
const record = obj;
|
|
30
|
+
for (let i = 0;i < Math.min(3, Object.keys(record).length); i++) {
|
|
31
|
+
if (typeof record[String(i)] !== "number")
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
isUnmarshalledUint8Array,
|
|
38
|
+
isResponseState,
|
|
39
|
+
isRequestState,
|
|
40
|
+
isHeadersState,
|
|
41
|
+
isAbortSignalState
|
|
42
|
+
};
|
|
2
43
|
|
|
3
|
-
//# debugId=
|
|
44
|
+
//# debugId=C26B19AD3011C06F64756E2164756E21
|
package/dist/mjs/types.mjs.map
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": [],
|
|
3
|
+
"sources": ["../../src/types.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
+
"import type { QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap, CoreHandle } from \"@ricsam/quickjs-core\";\n\nexport type { StateMap, CoreHandle };\n\n/**\n * Options for setting up Fetch APIs\n */\nexport interface SetupFetchOptions {\n /**\n * Handler for outbound fetch() calls from QuickJS\n * If not provided, fetch() will throw an error\n */\n onFetch?: (request: Request) => Promise<Response>;\n\n /** Existing state map (creates new one if not provided) */\n stateMap?: StateMap;\n\n /** Existing core handle (sets up core if not provided) */\n coreHandle?: CoreHandle;\n}\n\n/**\n * Data associated with a WebSocket connection\n */\nexport interface WebSocketData {\n /** User-provided data from server.upgrade() */\n data: unknown;\n\n /** Connection ID assigned by the host */\n connectionId: string;\n}\n\n/**\n * Pending upgrade request info\n */\nexport interface UpgradeRequest {\n /** Whether an upgrade was requested */\n requested: true;\n\n /** Connection ID generated by server.upgrade() - used to look up user data from QuickJS registry */\n connectionId: string;\n}\n\n/**\n * Message to send to a WebSocket\n */\nexport interface WebSocketOutgoingMessage {\n type: \"message\";\n connectionId: string;\n data: string | ArrayBuffer;\n}\n\n/**\n * Close command for a WebSocket\n */\nexport interface WebSocketClose {\n type: \"close\";\n connectionId: string;\n code?: number;\n reason?: string;\n}\n\nexport type WebSocketCommand = WebSocketOutgoingMessage | WebSocketClose;\n\n/**\n * Internal state for serve() handler\n */\nexport interface ServeState {\n fetchHandler: QuickJSHandle | null;\n websocketHandlers: {\n open?: QuickJSHandle;\n message?: QuickJSHandle;\n close?: QuickJSHandle;\n error?: QuickJSHandle;\n };\n pendingUpgrade: UpgradeRequest | null;\n activeConnections: Map<string, ServerWebSocketState>;\n}\n\nexport interface ServerWebSocketState {\n // Note: 'data' is accessed via pure-JS getter that reads from __upgradeRegistry__\n // This avoids marshalling complex objects (like Zod schemas) that exceed depth limits\n readyState: number;\n connectionId: string;\n wsHandle: QuickJSHandle | null;\n}\n\n/**\n * Handle returned from setupFetch\n */\nexport interface FetchHandle {\n /** State map containing all internal states */\n readonly stateMap: StateMap;\n\n /**\n * Dispatch an HTTP request to the serve() handler\n *\n * @returns Response from the QuickJS handler\n * @throws If no serve() handler is registered\n */\n dispatchRequest(request: Request): Promise<Response>;\n\n /**\n * Check if the last request resulted in an upgrade request\n * Must be called immediately after dispatchRequest()\n */\n getUpgradeRequest(): UpgradeRequest | null;\n\n /**\n * Dispatch WebSocket open event\n *\n * @param connectionId The connectionId from getUpgradeRequest() - used to look up data from QuickJS registry\n */\n dispatchWebSocketOpen(connectionId: string): void;\n\n /**\n * Dispatch WebSocket message event\n */\n dispatchWebSocketMessage(\n connectionId: string,\n message: string | ArrayBuffer\n ): void;\n\n /**\n * Dispatch WebSocket close event\n */\n dispatchWebSocketClose(\n connectionId: string,\n code: number,\n reason: string\n ): void;\n\n /**\n * Dispatch WebSocket error event\n */\n dispatchWebSocketError(connectionId: string, error: Error): void;\n\n /**\n * Register a callback for outgoing WebSocket messages/commands\n * Called when QuickJS code calls ws.send() or ws.close()\n */\n onWebSocketCommand(callback: (command: WebSocketCommand) => void): () => void;\n\n /**\n * Check if a serve() handler is registered\n */\n hasServeHandler(): boolean;\n\n /**\n * Check if there are active WebSocket connections\n */\n hasActiveConnections(): boolean;\n\n /**\n * Dispose all handles and cleanup\n */\n dispose(): void;\n}\n\n// Internal state types for the classes\nexport interface HeadersState {\n headers: Map<string, string[]>;\n}\n\n/**\n * What we get when unmarshalling a Request instance from QuickJS.\n * Contains identity markers + enumerable debug properties.\n */\nexport interface UnmarshalledRequest {\n __instanceId__: number;\n __className__: \"Request\";\n __isDefineClassInstance__: true;\n // Debug properties (may be present from unmarshal.ts)\n method?: string;\n url?: string;\n}\n\n/**\n * What we get when unmarshalling a Response instance from QuickJS.\n * Contains identity markers + enumerable debug properties.\n */\nexport interface UnmarshalledResponse {\n __instanceId__: number;\n __className__: \"Response\";\n __isDefineClassInstance__: true;\n // Debug properties (may be present from unmarshal.ts)\n status?: number;\n ok?: boolean;\n url?: string;\n}\n\nexport interface RequestState {\n method: string;\n url: string;\n headersState: HeadersState;\n body: Uint8Array | null;\n bodyUsed: boolean;\n cache: string;\n credentials: string;\n destination: string;\n integrity: string;\n keepalive: boolean;\n mode: string;\n redirect: string;\n referrer: string;\n referrerPolicy: string;\n signal: AbortSignalState | null;\n /** Native ReadableStream for streaming request bodies (upload streaming) */\n nativeBodyStream?: ReadableStream<Uint8Array>;\n /** Instance ID of QuickJS stream created by body getter (for consumption methods) */\n _uploadStreamInstanceId?: number;\n}\n\nexport interface ResponseState {\n status: number;\n statusText: string;\n headersState: HeadersState;\n body: Uint8Array | null;\n bodyUsed: boolean;\n url: string;\n redirected: boolean;\n type: string;\n ok: boolean;\n /** Original body type - used to convert back to string for native Response */\n bodyType?: \"string\" | \"binary\" | \"stream\" | null;\n /** Instance ID of ReadableStream when bodyType is \"stream\" */\n streamInstanceId?: number;\n}\n\nexport interface AbortControllerState {\n signalState: AbortSignalState;\n}\n\nexport interface AbortSignalState {\n aborted: boolean;\n reason: unknown;\n listeners: Set<() => void>;\n}\n\nexport interface FormDataFileValue {\n __formDataFile__: true;\n data: Uint8Array;\n filename: string;\n type: string;\n}\n\nexport interface FormDataEntry {\n name: string;\n value: string | FormDataFileValue;\n}\n\nexport interface FormDataState {\n entries: FormDataEntry[];\n}\n\n/**\n * Host-side queue for upload stream bridging.\n * Native ReadableStream reader pushes chunks here.\n * QuickJS ReadableStream's synchronous pull() reads from here.\n * This avoids async callbacks with QuickJS handles.\n */\nexport interface UploadStreamQueue {\n /** Buffered chunks waiting to be read by QuickJS */\n chunks: Uint8Array[];\n /** Whether the native stream has closed */\n closed: boolean;\n /** Error from native stream if any */\n error?: Error;\n /** Whether the native reader should pause (backpressure) */\n paused: boolean;\n /** Callback to resume native reader when queue is drained */\n resumeCallback?: () => void;\n /** Callback to cancel native reader when QuickJS stream is cancelled */\n cancelCallback?: () => void;\n}\n\n// ============================================\n// Type Guards\n// ============================================\n\n/**\n * Type guard for HeadersState.\n * Validates that the object has the correct structure with a Map.\n */\nexport function isHeadersState(obj: unknown): obj is HeadersState {\n return (\n obj !== null &&\n typeof obj === \"object\" &&\n \"headers\" in obj &&\n (obj as HeadersState).headers instanceof Map\n );\n}\n\n/**\n * Type guard for RequestState.\n * Validates key properties including their types.\n */\nexport function isRequestState(obj: unknown): obj is RequestState {\n if (obj === null || typeof obj !== \"object\") return false;\n const state = obj as Partial<RequestState>;\n return (\n typeof state.method === \"string\" &&\n typeof state.url === \"string\" &&\n isHeadersState(state.headersState)\n );\n}\n\n/**\n * Type guard for ResponseState.\n * Validates key properties including their types.\n */\nexport function isResponseState(obj: unknown): obj is ResponseState {\n if (obj === null || typeof obj !== \"object\") return false;\n const state = obj as Partial<ResponseState>;\n return (\n typeof state.status === \"number\" &&\n \"headersState\" in state &&\n isHeadersState(state.headersState) &&\n typeof state.bodyUsed === \"boolean\"\n );\n}\n\n/**\n * Type guard for AbortSignalState.\n * Validates the aborted flag and listeners set.\n */\nexport function isAbortSignalState(obj: unknown): obj is AbortSignalState {\n if (obj === null || typeof obj !== \"object\") return false;\n const state = obj as Partial<AbortSignalState>;\n return (\n typeof state.aborted === \"boolean\" &&\n \"listeners\" in state &&\n state.listeners instanceof Set\n );\n}\n\n/**\n * Type guard for unmarshalled Uint8Array-like objects.\n * These are objects with numeric keys and number values, created by unmarshal.ts.\n */\nexport function isUnmarshalledUint8Array(obj: unknown): obj is Record<string, number> {\n if (obj === null || typeof obj !== \"object\") return false;\n if (!(\"0\" in obj)) return false;\n // Verify at least the first few numeric keys have number values\n // (checking all keys would be expensive for large arrays)\n const record = obj as Record<string, unknown>;\n for (let i = 0; i < Math.min(3, Object.keys(record).length); i++) {\n if (typeof record[String(i)] !== \"number\") return false;\n }\n return true;\n}\n"
|
|
5
6
|
],
|
|
6
|
-
"mappings": "",
|
|
7
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;AA6RO,SAAS,cAAc,CAAC,KAAmC;AAAA,EAChE,OACE,QAAQ,QACR,OAAO,QAAQ,YACf,aAAa,OACZ,IAAqB,mBAAmB;AAAA;AAQtC,SAAS,cAAc,CAAC,KAAmC;AAAA,EAChE,IAAI,QAAQ,QAAQ,OAAO,QAAQ;AAAA,IAAU,OAAO;AAAA,EACpD,MAAM,QAAQ;AAAA,EACd,OACE,OAAO,MAAM,WAAW,YACxB,OAAO,MAAM,QAAQ,YACrB,eAAe,MAAM,YAAY;AAAA;AAQ9B,SAAS,eAAe,CAAC,KAAoC;AAAA,EAClE,IAAI,QAAQ,QAAQ,OAAO,QAAQ;AAAA,IAAU,OAAO;AAAA,EACpD,MAAM,QAAQ;AAAA,EACd,OACE,OAAO,MAAM,WAAW,YACxB,kBAAkB,SAClB,eAAe,MAAM,YAAY,KACjC,OAAO,MAAM,aAAa;AAAA;AAQvB,SAAS,kBAAkB,CAAC,KAAuC;AAAA,EACxE,IAAI,QAAQ,QAAQ,OAAO,QAAQ;AAAA,IAAU,OAAO;AAAA,EACpD,MAAM,QAAQ;AAAA,EACd,OACE,OAAO,MAAM,YAAY,aACzB,eAAe,SACf,MAAM,qBAAqB;AAAA;AAQxB,SAAS,wBAAwB,CAAC,KAA6C;AAAA,EACpF,IAAI,QAAQ,QAAQ,OAAO,QAAQ;AAAA,IAAU,OAAO;AAAA,EACpD,IAAI,EAAE,OAAO;AAAA,IAAM,OAAO;AAAA,EAG1B,MAAM,SAAS;AAAA,EACf,SAAS,IAAI,EAAG,IAAI,KAAK,IAAI,GAAG,OAAO,KAAK,MAAM,EAAE,MAAM,GAAG,KAAK;AAAA,IAChE,IAAI,OAAO,OAAO,OAAO,CAAC,OAAO;AAAA,MAAU,OAAO;AAAA,EACpD;AAAA,EACA,OAAO;AAAA;",
|
|
8
|
+
"debugId": "C26B19AD3011C06F64756E2164756E21",
|
|
8
9
|
"names": []
|
|
9
10
|
}
|
|
@@ -32,6 +32,15 @@ export declare function createRequestClass(context: QuickJSContext, stateMap: St
|
|
|
32
32
|
* @see PATTERNS.md section 2 (Class Methods That Return Instances)
|
|
33
33
|
*/
|
|
34
34
|
export declare function addRequestFormDataMethod(context: QuickJSContext): void;
|
|
35
|
+
/**
|
|
36
|
+
* Add the clone() method to Request.prototype via evalCode.
|
|
37
|
+
*
|
|
38
|
+
* This must be called AFTER Request class is on global.
|
|
39
|
+
* The method creates a proper Request instance with cloned state.
|
|
40
|
+
*
|
|
41
|
+
* @see PATTERNS.md section 2 (Class Methods That Return Instances)
|
|
42
|
+
*/
|
|
43
|
+
export declare function addRequestCloneMethod(context: QuickJSContext): void;
|
|
35
44
|
/**
|
|
36
45
|
* Create a RequestState from a native Request object.
|
|
37
46
|
*
|
|
@@ -14,6 +14,15 @@ export declare function createResponseClass(context: QuickJSContext, stateMap: S
|
|
|
14
14
|
* This must be called after Response and Headers are available on global
|
|
15
15
|
*/
|
|
16
16
|
export declare function addResponseStaticMethods(context: QuickJSContext): void;
|
|
17
|
+
/**
|
|
18
|
+
* Add the clone() method to Response.prototype via evalCode.
|
|
19
|
+
*
|
|
20
|
+
* This must be called AFTER Response and Headers classes are on global.
|
|
21
|
+
* The method creates a proper Response instance with cloned state.
|
|
22
|
+
*
|
|
23
|
+
* @see PATTERNS.md section 2 (Class Methods That Return Instances)
|
|
24
|
+
*/
|
|
25
|
+
export declare function addResponseCloneMethod(context: QuickJSContext): void;
|
|
17
26
|
/**
|
|
18
27
|
* Convert ResponseState (or unmarshalled Response object) to native Response
|
|
19
28
|
*/
|
package/dist/types/types.d.ts
CHANGED
|
@@ -127,6 +127,29 @@ export interface FetchHandle {
|
|
|
127
127
|
export interface HeadersState {
|
|
128
128
|
headers: Map<string, string[]>;
|
|
129
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* What we get when unmarshalling a Request instance from QuickJS.
|
|
132
|
+
* Contains identity markers + enumerable debug properties.
|
|
133
|
+
*/
|
|
134
|
+
export interface UnmarshalledRequest {
|
|
135
|
+
__instanceId__: number;
|
|
136
|
+
__className__: "Request";
|
|
137
|
+
__isDefineClassInstance__: true;
|
|
138
|
+
method?: string;
|
|
139
|
+
url?: string;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* What we get when unmarshalling a Response instance from QuickJS.
|
|
143
|
+
* Contains identity markers + enumerable debug properties.
|
|
144
|
+
*/
|
|
145
|
+
export interface UnmarshalledResponse {
|
|
146
|
+
__instanceId__: number;
|
|
147
|
+
__className__: "Response";
|
|
148
|
+
__isDefineClassInstance__: true;
|
|
149
|
+
status?: number;
|
|
150
|
+
ok?: boolean;
|
|
151
|
+
url?: string;
|
|
152
|
+
}
|
|
130
153
|
export interface RequestState {
|
|
131
154
|
method: string;
|
|
132
155
|
url: string;
|
|
@@ -204,3 +227,28 @@ export interface UploadStreamQueue {
|
|
|
204
227
|
/** Callback to cancel native reader when QuickJS stream is cancelled */
|
|
205
228
|
cancelCallback?: () => void;
|
|
206
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* Type guard for HeadersState.
|
|
232
|
+
* Validates that the object has the correct structure with a Map.
|
|
233
|
+
*/
|
|
234
|
+
export declare function isHeadersState(obj: unknown): obj is HeadersState;
|
|
235
|
+
/**
|
|
236
|
+
* Type guard for RequestState.
|
|
237
|
+
* Validates key properties including their types.
|
|
238
|
+
*/
|
|
239
|
+
export declare function isRequestState(obj: unknown): obj is RequestState;
|
|
240
|
+
/**
|
|
241
|
+
* Type guard for ResponseState.
|
|
242
|
+
* Validates key properties including their types.
|
|
243
|
+
*/
|
|
244
|
+
export declare function isResponseState(obj: unknown): obj is ResponseState;
|
|
245
|
+
/**
|
|
246
|
+
* Type guard for AbortSignalState.
|
|
247
|
+
* Validates the aborted flag and listeners set.
|
|
248
|
+
*/
|
|
249
|
+
export declare function isAbortSignalState(obj: unknown): obj is AbortSignalState;
|
|
250
|
+
/**
|
|
251
|
+
* Type guard for unmarshalled Uint8Array-like objects.
|
|
252
|
+
* These are objects with numeric keys and number values, created by unmarshal.ts.
|
|
253
|
+
*/
|
|
254
|
+
export declare function isUnmarshalledUint8Array(obj: unknown): obj is Record<string, number>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ricsam/quickjs-fetch",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.15",
|
|
4
4
|
"main": "./dist/cjs/index.cjs",
|
|
5
5
|
"types": "./dist/types/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"typecheck": "tsc --noEmit"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@ricsam/quickjs-core": "^0.2.
|
|
22
|
+
"@ricsam/quickjs-core": "^0.2.14",
|
|
23
23
|
"quickjs-emscripten": "^0.31.0"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|