export-runtime 0.0.20 → 0.0.21

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 (2) hide show
  1. package/handler.js +42 -26
  2. package/package.json +1 -1
package/handler.js CHANGED
@@ -323,6 +323,7 @@ export const createHandler = (moduleMap, generatedTypes, minifiedCore, coreId, m
323
323
  // Track session state and connection state for this WebSocket connection
324
324
  const wsSession = { token: null };
325
325
  let isClosed = false;
326
+ const pendingOps = new Set();
326
327
 
327
328
  // Safe send that ignores errors when connection is closed
328
329
  const safeSend = (data) => {
@@ -334,37 +335,51 @@ export const createHandler = (moduleMap, generatedTypes, minifiedCore, coreId, m
334
335
  }
335
336
  };
336
337
 
337
- server.addEventListener("message", async (event) => {
338
- if (isClosed) return;
339
- let id;
338
+ // Wrap async operations to track them
339
+ const trackOp = async (op) => {
340
+ const promise = op();
341
+ pendingOps.add(promise);
340
342
  try {
341
- const msg = parse(event.data);
342
- id = msg.id;
343
-
344
- // Handle auth token updates (on reconnect or explicit setToken)
345
- if (msg.type === "auth" && msg.token && !msg.method) {
346
- // Direct token send on reconnect - just update session
347
- wsSession.token = msg.token;
348
- safeSend(stringify({ type: "auth-result", id, success: true }));
349
- return;
350
- }
343
+ return await promise;
344
+ } finally {
345
+ pendingOps.delete(promise);
346
+ }
347
+ };
351
348
 
352
- const result = await dispatchMessage(dispatcher, msg, env, wsSession);
349
+ server.addEventListener("message", (event) => {
350
+ if (isClosed) return;
353
351
 
354
- // Don't send if connection closed during dispatch
355
- if (isClosed) return;
352
+ // Handle message asynchronously but don't await it
353
+ trackOp(async () => {
354
+ let id;
355
+ try {
356
+ if (isClosed) return;
357
+ const msg = parse(event.data);
358
+ id = msg.id;
359
+
360
+ // Handle auth token updates (on reconnect or explicit setToken)
361
+ if (msg.type === "auth" && msg.token && !msg.method) {
362
+ wsSession.token = msg.token;
363
+ safeSend(stringify({ type: "auth-result", id, success: true }));
364
+ return;
365
+ }
356
366
 
357
- // Extract token from auth responses
358
- if (result?.value?.token && msg.type === "auth") {
359
- wsSession.token = result.value.token;
360
- }
367
+ if (isClosed) return;
368
+ const result = await dispatchMessage(dispatcher, msg, env, wsSession);
361
369
 
362
- if (result) safeSend(stringify({ ...result, id }));
363
- } catch (err) {
364
- // Don't send errors if connection is closed or error is about closed connection
365
- if (isClosed || String(err).includes("Connection closed")) return;
366
- if (id !== undefined) safeSend(stringify({ type: "error", id, error: String(err) }));
367
- }
370
+ if (isClosed) return;
371
+
372
+ // Extract token from auth responses
373
+ if (result?.value?.token && msg.type === "auth") {
374
+ wsSession.token = result.value.token;
375
+ }
376
+
377
+ if (result) safeSend(stringify({ ...result, id }));
378
+ } catch (err) {
379
+ if (isClosed || String(err).includes("Connection closed")) return;
380
+ if (id !== undefined) safeSend(stringify({ type: "error", id, error: String(err) }));
381
+ }
382
+ });
368
383
  });
369
384
 
370
385
  server.addEventListener("close", () => {
@@ -374,6 +389,7 @@ export const createHandler = (moduleMap, generatedTypes, minifiedCore, coreId, m
374
389
 
375
390
  server.addEventListener("error", () => {
376
391
  isClosed = true;
392
+ if (onClose) onClose();
377
393
  });
378
394
  };
379
395
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "export-runtime",
3
- "version": "0.0.20",
3
+ "version": "0.0.21",
4
4
  "description": "Cloudflare Workers ESM Export Framework Runtime",
5
5
  "keywords": [
6
6
  "cloudflare",