@ricsam/isolate-fetch 0.1.16 → 0.1.18
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/consistency/origins.cjs +19 -9
- package/dist/cjs/consistency/origins.cjs.map +2 -2
- package/dist/cjs/index.cjs +93 -15
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/stream-state.cjs +19 -9
- package/dist/cjs/stream-state.cjs.map +2 -2
- package/dist/mjs/index.mjs +63 -6
- package/dist/mjs/index.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/index.d.ts +2 -0
- package/package.json +2 -3
package/dist/cjs/package.json
CHANGED
|
@@ -2,27 +2,37 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
|
|
5
|
+
function __accessProp(key) {
|
|
6
|
+
return this[key];
|
|
7
|
+
}
|
|
6
8
|
var __toCommonJS = (from) => {
|
|
7
|
-
var entry = __moduleCache.get(from), desc;
|
|
9
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
8
10
|
if (entry)
|
|
9
11
|
return entry;
|
|
10
12
|
entry = __defProp({}, "__esModule", { value: true });
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (var key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(entry, key))
|
|
16
|
+
__defProp(entry, key, {
|
|
17
|
+
get: __accessProp.bind(from, key),
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
+
});
|
|
20
|
+
}
|
|
16
21
|
__moduleCache.set(from, entry);
|
|
17
22
|
return entry;
|
|
18
23
|
};
|
|
24
|
+
var __moduleCache;
|
|
25
|
+
var __returnValue = (v) => v;
|
|
26
|
+
function __exportSetter(name, newValue) {
|
|
27
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
28
|
+
}
|
|
19
29
|
var __export = (target, all) => {
|
|
20
30
|
for (var name in all)
|
|
21
31
|
__defProp(target, name, {
|
|
22
32
|
get: all[name],
|
|
23
33
|
enumerable: true,
|
|
24
34
|
configurable: true,
|
|
25
|
-
set: (
|
|
35
|
+
set: __exportSetter.bind(all, name)
|
|
26
36
|
});
|
|
27
37
|
};
|
|
28
38
|
|
|
@@ -238,4 +248,4 @@ function startNativeStreamReader(nativeStream, streamId, registry) {
|
|
|
238
248
|
};
|
|
239
249
|
}
|
|
240
250
|
|
|
241
|
-
//# debugId=
|
|
251
|
+
//# debugId=991A034BA431A4D364756E2164756E21
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import ivm from \"isolated-vm\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface StreamState {\n /** Buffered chunks waiting to be read */\n queue: Uint8Array[];\n\n /** Total bytes in queue (for backpressure) */\n queueSize: number;\n\n /** Stream has been closed (no more data) */\n closed: boolean;\n\n /** Stream encountered an error */\n errored: boolean;\n\n /** The error value if errored */\n errorValue: unknown;\n\n /** A pull is waiting for data */\n pullWaiting: boolean;\n\n /** Resolve function for waiting pull */\n pullResolve: ((chunk: Uint8Array | null) => void) | null;\n\n /** Reject function for waiting pull */\n pullReject: ((error: unknown) => void) | null;\n}\n\nexport interface StreamStateRegistry {\n /** Create a new stream and return its ID */\n create(): number;\n\n /** Get stream state by ID */\n get(streamId: number): StreamState | undefined;\n\n /** Push a chunk to the stream's queue */\n push(streamId: number, chunk: Uint8Array): boolean;\n\n /** Pull a chunk from the stream (returns Promise that resolves when data available) */\n pull(\n streamId: number\n ): Promise<{ value: Uint8Array; done: false } | { done: true }>;\n\n /** Close the stream (no more data) */\n close(streamId: number): void;\n\n /** Error the stream */\n error(streamId: number, errorValue: unknown): void;\n\n /** Check if stream queue is above high-water mark */\n isQueueFull(streamId: number): boolean;\n\n /** Delete stream state (cleanup) */\n delete(streamId: number): void;\n\n /** Clear all streams (context cleanup) */\n clear(): void;\n\n /** Cancel a stream and call its cleanup function */\n cancel(streamId: number): void;\n\n /** Register a cleanup function for a stream */\n setCleanup(streamId: number, cleanup: () => Promise<void>): void;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Maximum bytes to buffer before backpressure kicks in */\nexport const HIGH_WATER_MARK = 64 * 1024; // 64KB\n\n/** Maximum number of chunks in queue */\nexport const MAX_QUEUE_CHUNKS = 16;\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\nexport function createStreamStateRegistry(): StreamStateRegistry {\n const streams = new Map<number, StreamState>();\n const cleanups = new Map<number, () => Promise<void>>();\n let nextStreamId = 1;\n\n return {\n create(): number {\n const streamId = nextStreamId++;\n streams.set(streamId, {\n queue: [],\n queueSize: 0,\n closed: false,\n errored: false,\n errorValue: undefined,\n pullWaiting: false,\n pullResolve: null,\n pullReject: null,\n });\n return streamId;\n },\n\n get(streamId: number): StreamState | undefined {\n return streams.get(streamId);\n },\n\n push(streamId: number, chunk: Uint8Array): boolean {\n const state = streams.get(streamId);\n if (!state) return false;\n if (state.closed || state.errored) return false;\n\n // If a pull is waiting, deliver directly\n if (state.pullWaiting && state.pullResolve) {\n state.pullWaiting = false;\n const resolve = state.pullResolve;\n state.pullResolve = null;\n state.pullReject = null;\n resolve(chunk);\n return true;\n }\n\n // Otherwise queue the chunk\n state.queue.push(chunk);\n state.queueSize += chunk.length;\n return true;\n },\n\n async pull(\n streamId: number\n ): Promise<{ value: Uint8Array; done: false } | { done: true }> {\n const state = streams.get(streamId);\n if (!state) {\n return { done: true };\n }\n\n // If queue has data, return it first (even if stream is errored)\n if (state.queue.length > 0) {\n const chunk = state.queue.shift()!;\n state.queueSize -= chunk.length;\n return { value: chunk, done: false };\n }\n\n // If errored (and queue is empty), throw\n if (state.errored) {\n throw state.errorValue;\n }\n\n // If closed and queue empty, we're done\n if (state.closed) {\n return { done: true };\n }\n\n // Wait for data\n return new Promise((resolve, reject) => {\n state.pullWaiting = true;\n state.pullResolve = (chunk) => {\n if (chunk === null) {\n resolve({ done: true });\n } else {\n resolve({ value: chunk, done: false });\n }\n };\n state.pullReject = reject;\n });\n },\n\n close(streamId: number): void {\n const state = streams.get(streamId);\n if (!state) return;\n\n state.closed = true;\n\n // If a pull is waiting, resolve with done\n if (state.pullWaiting && state.pullResolve) {\n state.pullWaiting = false;\n const resolve = state.pullResolve;\n state.pullResolve = null;\n state.pullReject = null;\n resolve(null);\n }\n },\n\n error(streamId: number, errorValue: unknown): void {\n const state = streams.get(streamId);\n if (!state) return;\n\n state.errored = true;\n state.errorValue = errorValue;\n\n // If a pull is waiting, reject it\n if (state.pullWaiting && state.pullReject) {\n state.pullWaiting = false;\n const reject = state.pullReject;\n state.pullResolve = null;\n state.pullReject = null;\n reject(errorValue);\n }\n },\n\n isQueueFull(streamId: number): boolean {\n const state = streams.get(streamId);\n if (!state) return true;\n return (\n state.queueSize >= HIGH_WATER_MARK ||\n state.queue.length >= MAX_QUEUE_CHUNKS\n );\n },\n\n delete(streamId: number): void {\n const state = streams.get(streamId);\n if (state && state.pullWaiting && state.pullReject) {\n state.pullReject(new Error(\"Stream deleted\"));\n }\n streams.delete(streamId);\n cleanups.delete(streamId);\n },\n\n clear(): void {\n for (const [streamId] of streams) {\n this.delete(streamId);\n }\n },\n\n cancel(streamId: number): void {\n this.close(streamId);\n const cleanup = cleanups.get(streamId);\n if (cleanup) {\n cleanup().catch(() => {});\n cleanups.delete(streamId);\n }\n },\n\n setCleanup(streamId: number, cleanup: () => Promise<void>): void {\n cleanups.set(streamId, cleanup);\n },\n };\n}\n\n// ============================================================================\n// Context-Scoped Registry\n// ============================================================================\n\nconst contextRegistries = new WeakMap<ivm.Context, StreamStateRegistry>();\n\nexport function getStreamRegistryForContext(\n context: ivm.Context\n): StreamStateRegistry {\n let registry = contextRegistries.get(context);\n if (!registry) {\n registry = createStreamStateRegistry();\n contextRegistries.set(context, registry);\n }\n return registry;\n}\n\nexport function clearStreamRegistryForContext(context: ivm.Context): void {\n const registry = contextRegistries.get(context);\n if (registry) {\n registry.clear();\n contextRegistries.delete(context);\n }\n}\n\n// ============================================================================\n// Native Stream Reader\n// ============================================================================\n\n/**\n * Start reading from a native ReadableStream and push to host queue.\n * Respects backpressure by pausing when queue is full.\n *\n * @param nativeStream The native ReadableStream to read from\n * @param streamId The stream ID in the registry\n * @param registry The stream state registry\n * @returns Async cleanup function to cancel the reader\n */\nexport function startNativeStreamReader(\n nativeStream: ReadableStream<Uint8Array>,\n streamId: number,\n registry: StreamStateRegistry\n): () => Promise<void> {\n let cancelled = false;\n let reader: ReadableStreamDefaultReader<Uint8Array> | null = null;\n let readLoopPromise: Promise<void> | null = null;\n\n const CHUNK_SIZE = 64 * 1024; // 64KB max chunk size\n\n async function readLoop() {\n try {\n reader = nativeStream.getReader();\n\n while (!cancelled) {\n // Respect backpressure - wait if queue is full\n while (registry.isQueueFull(streamId) && !cancelled) {\n await new Promise((resolve) => setTimeout(resolve, 1));\n }\n if (cancelled) break;\n\n const { done, value } = await reader.read();\n\n if (done) {\n registry.close(streamId);\n break;\n }\n\n if (value) {\n // Split large chunks to maintain granularity\n if (value.length > CHUNK_SIZE) {\n for (let offset = 0; offset < value.length; offset += CHUNK_SIZE) {\n const chunk = value.slice(\n offset,\n Math.min(offset + CHUNK_SIZE, value.length)\n );\n registry.push(streamId, chunk);\n }\n } else {\n registry.push(streamId, value);\n }\n }\n }\n } catch (error) {\n registry.error(streamId, error);\n } finally {\n if (reader) {\n try {\n reader.releaseLock();\n } catch {\n // Ignore release errors\n }\n }\n }\n }\n\n // Start the read loop and save the promise\n readLoopPromise = readLoop();\n\n // Return async cleanup function\n return async () => {\n cancelled = true;\n if (reader) {\n try {\n await reader.cancel();\n } catch {\n // Ignore cancel errors\n }\n }\n // Wait for read loop to finish\n if (readLoopPromise) {\n try {\n await readLoopPromise;\n } catch {\n // Ignore read loop errors during cleanup\n }\n }\n };\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "991A034BA431A4D364756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/mjs/index.mjs
CHANGED
|
@@ -1019,6 +1019,7 @@ function setupRequest(context, stateMap) {
|
|
|
1019
1019
|
body,
|
|
1020
1020
|
bodyUsed: false,
|
|
1021
1021
|
streamId: null,
|
|
1022
|
+
signalAborted: false,
|
|
1022
1023
|
mode,
|
|
1023
1024
|
credentials,
|
|
1024
1025
|
cache,
|
|
@@ -1115,6 +1116,10 @@ function setupRequest(context, stateMap) {
|
|
|
1115
1116
|
const state = stateMap.get(instanceId);
|
|
1116
1117
|
return state?.streamId ?? null;
|
|
1117
1118
|
}));
|
|
1119
|
+
global.setSync("__Request_get_signalAborted", new ivm.Callback((instanceId) => {
|
|
1120
|
+
const state = stateMap.get(instanceId);
|
|
1121
|
+
return state?.signalAborted ?? false;
|
|
1122
|
+
}));
|
|
1118
1123
|
const requestCode = `
|
|
1119
1124
|
(function() {
|
|
1120
1125
|
function __decodeError(err) {
|
|
@@ -1178,6 +1183,8 @@ function setupRequest(context, stateMap) {
|
|
|
1178
1183
|
return result;
|
|
1179
1184
|
}
|
|
1180
1185
|
|
|
1186
|
+
const __requestSignalControllers = new Map();
|
|
1187
|
+
|
|
1181
1188
|
class Request {
|
|
1182
1189
|
#instanceId;
|
|
1183
1190
|
#headers;
|
|
@@ -1188,9 +1195,15 @@ function setupRequest(context, stateMap) {
|
|
|
1188
1195
|
constructor(input, init = {}) {
|
|
1189
1196
|
// Handle internal construction from instance ID
|
|
1190
1197
|
if (typeof input === 'number' && init === null) {
|
|
1198
|
+
const controller = new AbortController();
|
|
1199
|
+
if (__Request_get_signalAborted(input)) {
|
|
1200
|
+
controller.abort();
|
|
1201
|
+
}
|
|
1202
|
+
__requestSignalControllers.set(input, controller);
|
|
1203
|
+
|
|
1191
1204
|
this.#instanceId = input;
|
|
1192
1205
|
this.#headers = new Headers(__Request_get_headers(input));
|
|
1193
|
-
this.#signal =
|
|
1206
|
+
this.#signal = controller.signal;
|
|
1194
1207
|
this.#streamId = __Request_getStreamId(input);
|
|
1195
1208
|
return;
|
|
1196
1209
|
}
|
|
@@ -1199,7 +1212,7 @@ function setupRequest(context, stateMap) {
|
|
|
1199
1212
|
let method = 'GET';
|
|
1200
1213
|
let headers;
|
|
1201
1214
|
let body = null;
|
|
1202
|
-
let signal =
|
|
1215
|
+
let signal = new AbortController().signal;
|
|
1203
1216
|
let mode = 'cors';
|
|
1204
1217
|
let credentials = 'same-origin';
|
|
1205
1218
|
let cache = 'default';
|
|
@@ -1236,6 +1249,11 @@ function setupRequest(context, stateMap) {
|
|
|
1236
1249
|
if (init.referrer !== undefined) referrer = init.referrer;
|
|
1237
1250
|
if (init.integrity !== undefined) integrity = init.integrity;
|
|
1238
1251
|
|
|
1252
|
+
// Ensure signal is always a valid AbortSignal
|
|
1253
|
+
if (signal == null) {
|
|
1254
|
+
signal = new AbortController().signal;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1239
1257
|
// Validate: body with GET/HEAD
|
|
1240
1258
|
if (body !== null && (method === 'GET' || method === 'HEAD')) {
|
|
1241
1259
|
throw new TypeError('Request with GET/HEAD method cannot have body');
|
|
@@ -1429,10 +1447,18 @@ function setupRequest(context, stateMap) {
|
|
|
1429
1447
|
}
|
|
1430
1448
|
}
|
|
1431
1449
|
|
|
1450
|
+
globalThis.__Request_abortSignalByInstanceId = function(instanceId) {
|
|
1451
|
+
const controller = __requestSignalControllers.get(instanceId);
|
|
1452
|
+
if (controller && !controller.signal.aborted) {
|
|
1453
|
+
controller.abort();
|
|
1454
|
+
}
|
|
1455
|
+
};
|
|
1456
|
+
|
|
1432
1457
|
globalThis.Request = Request;
|
|
1433
1458
|
})();
|
|
1434
1459
|
`;
|
|
1435
1460
|
context.evalSync(requestCode);
|
|
1461
|
+
return context.evalSync("globalThis.__Request_abortSignalByInstanceId", { reference: true });
|
|
1436
1462
|
}
|
|
1437
1463
|
var FETCH_STREAM_THRESHOLD = 64 * 1024;
|
|
1438
1464
|
function setupFetchFunction(context, stateMap, streamRegistry, options) {
|
|
@@ -2090,7 +2116,7 @@ async function setupFetch(context, options) {
|
|
|
2090
2116
|
setupStreamCallbacks(context, streamRegistry);
|
|
2091
2117
|
context.evalSync(hostBackedStreamCode);
|
|
2092
2118
|
setupResponse(context, stateMap, streamRegistry);
|
|
2093
|
-
setupRequest(context, stateMap);
|
|
2119
|
+
const requestAbortSignalRef = setupRequest(context, stateMap);
|
|
2094
2120
|
setupFetchFunction(context, stateMap, streamRegistry, options);
|
|
2095
2121
|
const serveState = {
|
|
2096
2122
|
pendingUpgrade: null,
|
|
@@ -2143,8 +2169,11 @@ async function setupFetch(context, options) {
|
|
|
2143
2169
|
context.evalSync(`globalThis.__upgradeRegistry__.clear()`);
|
|
2144
2170
|
serveState.activeConnections.clear();
|
|
2145
2171
|
serveState.pendingUpgrade = null;
|
|
2172
|
+
try {
|
|
2173
|
+
requestAbortSignalRef.release();
|
|
2174
|
+
} catch {}
|
|
2146
2175
|
},
|
|
2147
|
-
async dispatchRequest(request,
|
|
2176
|
+
async dispatchRequest(request, dispatchOptions) {
|
|
2148
2177
|
if (serveState.pendingUpgrade) {
|
|
2149
2178
|
const oldConnectionId = serveState.pendingUpgrade.connectionId;
|
|
2150
2179
|
context.evalSync(`globalThis.__upgradeRegistry__.delete("${oldConnectionId}")`);
|
|
@@ -2154,8 +2183,12 @@ async function setupFetch(context, options) {
|
|
|
2154
2183
|
if (!hasHandler) {
|
|
2155
2184
|
throw new Error("No serve() handler registered");
|
|
2156
2185
|
}
|
|
2186
|
+
const forwardedSignal = dispatchOptions?.signal ?? request.signal;
|
|
2187
|
+
const forwardedSignalInitiallyAborted = forwardedSignal?.aborted ?? false;
|
|
2157
2188
|
let requestStreamId = null;
|
|
2189
|
+
let requestInstanceId = null;
|
|
2158
2190
|
let streamCleanup = null;
|
|
2191
|
+
let onForwardedSignalAbort;
|
|
2159
2192
|
const canHaveBody = !["GET", "HEAD"].includes(request.method.toUpperCase());
|
|
2160
2193
|
if (canHaveBody && request.body) {
|
|
2161
2194
|
requestStreamId = streamRegistry.create();
|
|
@@ -2163,7 +2196,7 @@ async function setupFetch(context, options) {
|
|
|
2163
2196
|
}
|
|
2164
2197
|
try {
|
|
2165
2198
|
const headersArray = Array.from(request.headers.entries());
|
|
2166
|
-
|
|
2199
|
+
requestInstanceId = nextInstanceId++;
|
|
2167
2200
|
const requestState = {
|
|
2168
2201
|
url: request.url,
|
|
2169
2202
|
method: request.method,
|
|
@@ -2171,6 +2204,7 @@ async function setupFetch(context, options) {
|
|
|
2171
2204
|
body: null,
|
|
2172
2205
|
bodyUsed: false,
|
|
2173
2206
|
streamId: requestStreamId,
|
|
2207
|
+
signalAborted: forwardedSignalInitiallyAborted,
|
|
2174
2208
|
mode: request.mode,
|
|
2175
2209
|
credentials: request.credentials,
|
|
2176
2210
|
cache: request.cache,
|
|
@@ -2179,6 +2213,26 @@ async function setupFetch(context, options) {
|
|
|
2179
2213
|
integrity: request.integrity
|
|
2180
2214
|
};
|
|
2181
2215
|
stateMap.set(requestInstanceId, requestState);
|
|
2216
|
+
if (forwardedSignal && !forwardedSignalInitiallyAborted) {
|
|
2217
|
+
onForwardedSignalAbort = () => {
|
|
2218
|
+
if (requestInstanceId == null)
|
|
2219
|
+
return;
|
|
2220
|
+
const currentState = stateMap.get(requestInstanceId);
|
|
2221
|
+
if (!currentState || currentState.signalAborted) {
|
|
2222
|
+
return;
|
|
2223
|
+
}
|
|
2224
|
+
currentState.signalAborted = true;
|
|
2225
|
+
try {
|
|
2226
|
+
requestAbortSignalRef.applyIgnored(undefined, [requestInstanceId], {
|
|
2227
|
+
arguments: { copy: true }
|
|
2228
|
+
});
|
|
2229
|
+
} catch {}
|
|
2230
|
+
};
|
|
2231
|
+
forwardedSignal.addEventListener("abort", onForwardedSignalAbort, { once: true });
|
|
2232
|
+
if (forwardedSignal.aborted) {
|
|
2233
|
+
onForwardedSignalAbort();
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2182
2236
|
const responseInstanceId = await context.eval(`
|
|
2183
2237
|
(async function() {
|
|
2184
2238
|
const request = Request._fromInstanceId(${requestInstanceId});
|
|
@@ -2273,6 +2327,9 @@ async function setupFetch(context, options) {
|
|
|
2273
2327
|
response._originalStatus = responseState.status;
|
|
2274
2328
|
return response;
|
|
2275
2329
|
} finally {
|
|
2330
|
+
if (forwardedSignal && onForwardedSignalAbort) {
|
|
2331
|
+
forwardedSignal.removeEventListener("abort", onForwardedSignalAbort);
|
|
2332
|
+
}
|
|
2276
2333
|
if (requestStreamId !== null) {
|
|
2277
2334
|
const startTime = Date.now();
|
|
2278
2335
|
let streamState = streamRegistry.get(requestStreamId);
|
|
@@ -2459,4 +2516,4 @@ export {
|
|
|
2459
2516
|
clearAllInstanceState
|
|
2460
2517
|
};
|
|
2461
2518
|
|
|
2462
|
-
//# debugId=
|
|
2519
|
+
//# debugId=83B79F4E8D9D4D3864756E2164756E21
|