export-runtime 0.0.21 → 0.0.22

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 (3) hide show
  1. package/handler.js +15 -2
  2. package/package.json +1 -1
  3. package/rpc.js +11 -16
package/handler.js CHANGED
@@ -387,14 +387,15 @@ export const createHandler = (moduleMap, generatedTypes, minifiedCore, coreId, m
387
387
  if (onClose) onClose();
388
388
  });
389
389
 
390
- server.addEventListener("error", () => {
390
+ server.addEventListener("error", (err) => {
391
391
  isClosed = true;
392
392
  if (onClose) onClose();
393
+ try { server.close(); } catch {}
393
394
  });
394
395
  };
395
396
 
396
397
  return {
397
- async fetch(request, env) {
398
+ async fetch(request, env, ctx) {
398
399
  const url = new URL(request.url);
399
400
  const isShared = url.searchParams.has("shared");
400
401
  const origin = request.headers.get("Origin");
@@ -417,6 +418,13 @@ export const createHandler = (moduleMap, generatedTypes, minifiedCore, coreId, m
417
418
 
418
419
  const pair = new WebSocketPair();
419
420
  const [client, server] = Object.values(pair);
421
+
422
+ // Create a promise that resolves when the WebSocket closes
423
+ const wsLifetime = new Promise((resolve) => {
424
+ server.addEventListener("close", resolve, { once: true });
425
+ server.addEventListener("error", resolve, { once: true });
426
+ });
427
+
420
428
  server.accept();
421
429
 
422
430
  if (isShared && env?.SHARED_EXPORT) {
@@ -429,6 +437,11 @@ export const createHandler = (moduleMap, generatedTypes, minifiedCore, coreId, m
429
437
  wireWebSocket(server, dispatcher, env, () => dispatcher.clearAll());
430
438
  }
431
439
 
440
+ // Keep worker alive for the WebSocket lifetime
441
+ if (ctx?.waitUntil) {
442
+ ctx.waitUntil(wsLifetime);
443
+ }
444
+
432
445
  return new Response(null, { status: 101, webSocket: client });
433
446
  }
434
447
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "export-runtime",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "description": "Cloudflare Workers ESM Export Framework Runtime",
5
5
  "keywords": [
6
6
  "cloudflare",
package/rpc.js CHANGED
@@ -155,25 +155,20 @@ export function createRpcDispatcher(moduleMap) {
155
155
 
156
156
  clearAll() {
157
157
  closed = true;
158
- // Cancel all active iterators
159
- for (const iter of iterators.values()) {
160
- try {
161
- if (iter?.return) iter.return(undefined);
162
- } catch {}
163
- }
164
- // Cancel all active streams
165
- for (const entry of streams.values()) {
166
- try {
167
- if (entry.reader) {
168
- entry.reader.cancel();
169
- } else if (entry.stream) {
170
- entry.stream.cancel();
171
- }
172
- } catch {}
173
- }
158
+ // Synchronously clear all maps to prevent further access
159
+ const iters = [...iterators.values()];
160
+ const strms = [...streams.values()];
174
161
  instances.clear();
175
162
  iterators.clear();
176
163
  streams.clear();
164
+
165
+ // Cancel iterators and streams without awaiting (fire and forget)
166
+ for (const iter of iters) {
167
+ try { iter?.return?.(); } catch {}
168
+ }
169
+ for (const entry of strms) {
170
+ try { (entry.reader || entry.stream)?.cancel?.(); } catch {}
171
+ }
177
172
  },
178
173
  };
179
174
  }