@ricsam/isolate-daemon 0.1.16 → 0.1.17

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.
@@ -89,14 +89,10 @@ Shutting down...`);
89
89
  };
90
90
  process.on("SIGINT", shutdown);
91
91
  process.on("SIGTERM", shutdown);
92
- setInterval(() => {
93
- const stats = daemon.getStats();
94
- console.log(`[stats] connections: ${stats.activeConnections}, isolates: ${stats.activeIsolates}, total requests: ${stats.totalRequestsProcessed}`);
95
- }, 60000);
96
92
  }
97
93
  main().catch((err) => {
98
94
  console.error("Failed to start daemon:", err);
99
95
  process.exit(1);
100
96
  });
101
97
 
102
- //# debugId=F6A9BD16395E94A264756E2164756E21
98
+ //# debugId=D96ECFE02F2246F464756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/daemon.ts"],
4
4
  "sourcesContent": [
5
- "#!/usr/bin/env node\n\n// Suppress the ExperimentalWarning for stripTypeScriptTypes\nprocess.removeAllListeners(\"warning\");\nprocess.on(\"warning\", (warning) => {\n if (\n warning.name === \"ExperimentalWarning\" &&\n warning.message.includes(\"stripTypeScriptTypes\")\n ) {\n return; // Suppress this specific warning\n }\n console.warn(warning);\n});\n\n/**\n * CLI entry point for the isolate daemon.\n *\n * Usage:\n * isolate-daemon [options]\n *\n * Options:\n * --socket <path> Unix socket path (default: /tmp/isolate-daemon.sock)\n * --host <host> TCP host (default: 127.0.0.1)\n * --port <port> TCP port (default: 47891)\n * --max-isolates <n> Maximum isolates (default: 100)\n * --memory-limit <mb> Default memory limit (default: 128)\n */\n\nimport { startDaemon, type DaemonOptions } from \"./index.cjs\";\n\nfunction parseArgs(args: string[]): Partial<DaemonOptions> {\n const options: Partial<DaemonOptions> = {};\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n switch (arg) {\n case \"--socket\":\n i++;\n if (args[i]) {\n options.socketPath = args[i];\n }\n break;\n case \"--host\":\n i++;\n if (args[i]) {\n options.host = args[i];\n options.socketPath = undefined; // Use TCP instead\n }\n break;\n case \"--port\": {\n i++;\n const value = args[i];\n if (value !== undefined) {\n options.port = parseInt(value, 10);\n options.socketPath = undefined; // Use TCP instead\n }\n break;\n }\n case \"--max-isolates\": {\n i++;\n const value = args[i];\n if (value !== undefined) {\n options.maxIsolates = parseInt(value, 10);\n }\n break;\n }\n case \"--memory-limit\": {\n i++;\n const value = args[i];\n if (value !== undefined) {\n options.defaultMemoryLimitMB = parseInt(value, 10);\n }\n break;\n }\n case \"--help\":\n case \"-h\":\n console.log(`\nIsolate Daemon - Run isolated-vm runtimes accessible via IPC\n\nUsage:\n isolate-daemon [options]\n\nOptions:\n --socket <path> Unix socket path (default: /tmp/isolate-daemon.sock)\n --host <host> TCP host (default: 127.0.0.1, disables Unix socket)\n --port <port> TCP port (default: 47891, disables Unix socket)\n --max-isolates <n> Maximum isolates (default: 100)\n --memory-limit <mb> Default memory limit in MB (default: 128)\n --help, -h Show this help message\n`);\n process.exit(0);\n default:\n if (arg !== undefined && arg.startsWith(\"-\")) {\n console.error(`Unknown option: ${arg}`);\n process.exit(1);\n }\n }\n }\n\n return options;\n}\n\nasync function main() {\n const options = parseArgs(process.argv.slice(2));\n\n const daemon = await startDaemon(options);\n\n // Handle shutdown signals\n const shutdown = async () => {\n console.log(\"\\nShutting down...\");\n await daemon.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n // Log stats periodically\n setInterval(() => {\n const stats = daemon.getStats();\n console.log(\n `[stats] connections: ${stats.activeConnections}, isolates: ${stats.activeIsolates}, total requests: ${stats.totalRequestsProcessed}`\n );\n }, 60000);\n}\n\nmain().catch((err) => {\n console.error(\"Failed to start daemon:\", err);\n process.exit(1);\n});\n"
5
+ "#!/usr/bin/env node\n\n// Suppress the ExperimentalWarning for stripTypeScriptTypes\nprocess.removeAllListeners(\"warning\");\nprocess.on(\"warning\", (warning) => {\n if (\n warning.name === \"ExperimentalWarning\" &&\n warning.message.includes(\"stripTypeScriptTypes\")\n ) {\n return; // Suppress this specific warning\n }\n console.warn(warning);\n});\n\n/**\n * CLI entry point for the isolate daemon.\n *\n * Usage:\n * isolate-daemon [options]\n *\n * Options:\n * --socket <path> Unix socket path (default: /tmp/isolate-daemon.sock)\n * --host <host> TCP host (default: 127.0.0.1)\n * --port <port> TCP port (default: 47891)\n * --max-isolates <n> Maximum isolates (default: 100)\n * --memory-limit <mb> Default memory limit (default: 128)\n */\n\nimport { startDaemon, type DaemonOptions } from \"./index.cjs\";\n\nfunction parseArgs(args: string[]): Partial<DaemonOptions> {\n const options: Partial<DaemonOptions> = {};\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n switch (arg) {\n case \"--socket\":\n i++;\n if (args[i]) {\n options.socketPath = args[i];\n }\n break;\n case \"--host\":\n i++;\n if (args[i]) {\n options.host = args[i];\n options.socketPath = undefined; // Use TCP instead\n }\n break;\n case \"--port\": {\n i++;\n const value = args[i];\n if (value !== undefined) {\n options.port = parseInt(value, 10);\n options.socketPath = undefined; // Use TCP instead\n }\n break;\n }\n case \"--max-isolates\": {\n i++;\n const value = args[i];\n if (value !== undefined) {\n options.maxIsolates = parseInt(value, 10);\n }\n break;\n }\n case \"--memory-limit\": {\n i++;\n const value = args[i];\n if (value !== undefined) {\n options.defaultMemoryLimitMB = parseInt(value, 10);\n }\n break;\n }\n case \"--help\":\n case \"-h\":\n console.log(`\nIsolate Daemon - Run isolated-vm runtimes accessible via IPC\n\nUsage:\n isolate-daemon [options]\n\nOptions:\n --socket <path> Unix socket path (default: /tmp/isolate-daemon.sock)\n --host <host> TCP host (default: 127.0.0.1, disables Unix socket)\n --port <port> TCP port (default: 47891, disables Unix socket)\n --max-isolates <n> Maximum isolates (default: 100)\n --memory-limit <mb> Default memory limit in MB (default: 128)\n --help, -h Show this help message\n`);\n process.exit(0);\n default:\n if (arg !== undefined && arg.startsWith(\"-\")) {\n console.error(`Unknown option: ${arg}`);\n process.exit(1);\n }\n }\n }\n\n return options;\n}\n\nasync function main() {\n const options = parseArgs(process.argv.slice(2));\n\n const daemon = await startDaemon(options);\n\n // Handle shutdown signals\n const shutdown = async () => {\n console.log(\"\\nShutting down...\");\n await daemon.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n}\n\nmain().catch((err) => {\n console.error(\"Failed to start daemon:\", err);\n process.exit(1);\n});\n"
6
6
  ],
7
- "mappings": ";;;AA4BgD,IAAhD;AAzBA,QAAQ,mBAAmB,SAAS;AACpC,QAAQ,GAAG,WAAW,CAAC,YAAY;AAAA,EACjC,IACE,QAAQ,SAAS,yBACjB,QAAQ,QAAQ,SAAS,sBAAsB,GAC/C;AAAA,IACA;AAAA,EACF;AAAA,EACA,QAAQ,KAAK,OAAO;AAAA,CACrB;AAkBD,SAAS,SAAS,CAAC,MAAwC;AAAA,EACzD,MAAM,UAAkC,CAAC;AAAA,EAEzC,SAAS,IAAI,EAAG,IAAI,KAAK,QAAQ,KAAK;AAAA,IACpC,MAAM,MAAM,KAAK;AAAA,IAEjB,QAAQ;AAAA,WACD;AAAA,QACH;AAAA,QACA,IAAI,KAAK,IAAI;AAAA,UACX,QAAQ,aAAa,KAAK;AAAA,QAC5B;AAAA,QACA;AAAA,WACG;AAAA,QACH;AAAA,QACA,IAAI,KAAK,IAAI;AAAA,UACX,QAAQ,OAAO,KAAK;AAAA,UACpB,QAAQ,aAAa;AAAA,QACvB;AAAA,QACA;AAAA,WACG,UAAU;AAAA,QACb;AAAA,QACA,MAAM,QAAQ,KAAK;AAAA,QACnB,IAAI,UAAU,WAAW;AAAA,UACvB,QAAQ,OAAO,SAAS,OAAO,EAAE;AAAA,UACjC,QAAQ,aAAa;AAAA,QACvB;AAAA,QACA;AAAA,MACF;AAAA,WACK,kBAAkB;AAAA,QACrB;AAAA,QACA,MAAM,QAAQ,KAAK;AAAA,QACnB,IAAI,UAAU,WAAW;AAAA,UACvB,QAAQ,cAAc,SAAS,OAAO,EAAE;AAAA,QAC1C;AAAA,QACA;AAAA,MACF;AAAA,WACK,kBAAkB;AAAA,QACrB;AAAA,QACA,MAAM,QAAQ,KAAK;AAAA,QACnB,IAAI,UAAU,WAAW;AAAA,UACvB,QAAQ,uBAAuB,SAAS,OAAO,EAAE;AAAA,QACnD;AAAA,QACA;AAAA,MACF;AAAA,WACK;AAAA,WACA;AAAA,QACH,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAanB;AAAA,QACO,QAAQ,KAAK,CAAC;AAAA;AAAA,QAEd,IAAI,QAAQ,aAAa,IAAI,WAAW,GAAG,GAAG;AAAA,UAC5C,QAAQ,MAAM,mBAAmB,KAAK;AAAA,UACtC,QAAQ,KAAK,CAAC;AAAA,QAChB;AAAA;AAAA,EAEN;AAAA,EAEA,OAAO;AAAA;AAGT,eAAe,IAAI,GAAG;AAAA,EACpB,MAAM,UAAU,UAAU,QAAQ,KAAK,MAAM,CAAC,CAAC;AAAA,EAE/C,MAAM,SAAS,MAAM,qBAAY,OAAO;AAAA,EAGxC,MAAM,WAAW,YAAY;AAAA,IAC3B,QAAQ,IAAI;AAAA,iBAAoB;AAAA,IAChC,MAAM,OAAO,MAAM;AAAA,IACnB,QAAQ,KAAK,CAAC;AAAA;AAAA,EAGhB,QAAQ,GAAG,UAAU,QAAQ;AAAA,EAC7B,QAAQ,GAAG,WAAW,QAAQ;AAAA,EAG9B,YAAY,MAAM;AAAA,IAChB,MAAM,QAAQ,OAAO,SAAS;AAAA,IAC9B,QAAQ,IACN,wBAAwB,MAAM,gCAAgC,MAAM,mCAAmC,MAAM,wBAC/G;AAAA,KACC,KAAK;AAAA;AAGV,KAAK,EAAE,MAAM,CAAC,QAAQ;AAAA,EACpB,QAAQ,MAAM,2BAA2B,GAAG;AAAA,EAC5C,QAAQ,KAAK,CAAC;AAAA,CACf;",
8
- "debugId": "F6A9BD16395E94A264756E2164756E21",
7
+ "mappings": ";;;AA4BgD,IAAhD;AAzBA,QAAQ,mBAAmB,SAAS;AACpC,QAAQ,GAAG,WAAW,CAAC,YAAY;AAAA,EACjC,IACE,QAAQ,SAAS,yBACjB,QAAQ,QAAQ,SAAS,sBAAsB,GAC/C;AAAA,IACA;AAAA,EACF;AAAA,EACA,QAAQ,KAAK,OAAO;AAAA,CACrB;AAkBD,SAAS,SAAS,CAAC,MAAwC;AAAA,EACzD,MAAM,UAAkC,CAAC;AAAA,EAEzC,SAAS,IAAI,EAAG,IAAI,KAAK,QAAQ,KAAK;AAAA,IACpC,MAAM,MAAM,KAAK;AAAA,IAEjB,QAAQ;AAAA,WACD;AAAA,QACH;AAAA,QACA,IAAI,KAAK,IAAI;AAAA,UACX,QAAQ,aAAa,KAAK;AAAA,QAC5B;AAAA,QACA;AAAA,WACG;AAAA,QACH;AAAA,QACA,IAAI,KAAK,IAAI;AAAA,UACX,QAAQ,OAAO,KAAK;AAAA,UACpB,QAAQ,aAAa;AAAA,QACvB;AAAA,QACA;AAAA,WACG,UAAU;AAAA,QACb;AAAA,QACA,MAAM,QAAQ,KAAK;AAAA,QACnB,IAAI,UAAU,WAAW;AAAA,UACvB,QAAQ,OAAO,SAAS,OAAO,EAAE;AAAA,UACjC,QAAQ,aAAa;AAAA,QACvB;AAAA,QACA;AAAA,MACF;AAAA,WACK,kBAAkB;AAAA,QACrB;AAAA,QACA,MAAM,QAAQ,KAAK;AAAA,QACnB,IAAI,UAAU,WAAW;AAAA,UACvB,QAAQ,cAAc,SAAS,OAAO,EAAE;AAAA,QAC1C;AAAA,QACA;AAAA,MACF;AAAA,WACK,kBAAkB;AAAA,QACrB;AAAA,QACA,MAAM,QAAQ,KAAK;AAAA,QACnB,IAAI,UAAU,WAAW;AAAA,UACvB,QAAQ,uBAAuB,SAAS,OAAO,EAAE;AAAA,QACnD;AAAA,QACA;AAAA,MACF;AAAA,WACK;AAAA,WACA;AAAA,QACH,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAanB;AAAA,QACO,QAAQ,KAAK,CAAC;AAAA;AAAA,QAEd,IAAI,QAAQ,aAAa,IAAI,WAAW,GAAG,GAAG;AAAA,UAC5C,QAAQ,MAAM,mBAAmB,KAAK;AAAA,UACtC,QAAQ,KAAK,CAAC;AAAA,QAChB;AAAA;AAAA,EAEN;AAAA,EAEA,OAAO;AAAA;AAGT,eAAe,IAAI,GAAG;AAAA,EACpB,MAAM,UAAU,UAAU,QAAQ,KAAK,MAAM,CAAC,CAAC;AAAA,EAE/C,MAAM,SAAS,MAAM,qBAAY,OAAO;AAAA,EAGxC,MAAM,WAAW,YAAY;AAAA,IAC3B,QAAQ,IAAI;AAAA,iBAAoB;AAAA,IAChC,MAAM,OAAO,MAAM;AAAA,IACnB,QAAQ,KAAK,CAAC;AAAA;AAAA,EAGhB,QAAQ,GAAG,UAAU,QAAQ;AAAA,EAC7B,QAAQ,GAAG,WAAW,QAAQ;AAAA;AAGhC,KAAK,EAAE,MAAM,CAAC,QAAQ;AAAA,EACpB,QAAQ,MAAM,2BAA2B,GAAG;AAAA,EAC5C,QAAQ,KAAK,CAAC;AAAA,CACf;",
8
+ "debugId": "D96ECFE02F2246F464756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/isolate-daemon",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "type": "commonjs"
5
5
  }
@@ -51,7 +51,9 @@ function handleConnection(socket, state) {
51
51
  nextStreamId: 1,
52
52
  activeStreams: new Map,
53
53
  streamReceivers: new Map,
54
- callbackStreamReceivers: new Map
54
+ callbackStreamReceivers: new Map,
55
+ dispatchAbortControllers: new Map,
56
+ earlyAbortedDispatches: new Set
55
57
  };
56
58
  state.connections.set(socket, connection);
57
59
  const parser = createFrameParser();
@@ -68,6 +70,11 @@ function handleConnection(socket, state) {
68
70
  }
69
71
  });
70
72
  socket.on("close", () => {
73
+ for (const [, controller] of connection.dispatchAbortControllers) {
74
+ controller.abort();
75
+ }
76
+ connection.dispatchAbortControllers.clear();
77
+ connection.earlyAbortedDispatches.clear();
71
78
  for (const isolateId of connection.isolates) {
72
79
  const instance = state.isolates.get(isolateId);
73
80
  if (instance) {
@@ -129,6 +136,9 @@ async function handleMessage(message, connection, state) {
129
136
  case MessageType.DISPATCH_REQUEST:
130
137
  await handleDispatchRequest(message, connection, state);
131
138
  break;
139
+ case MessageType.DISPATCH_REQUEST_ABORT:
140
+ handleDispatchRequestAbort(message, connection);
141
+ break;
132
142
  case MessageType.CALLBACK_RESPONSE:
133
143
  handleCallbackResponse(message, connection);
134
144
  break;
@@ -738,7 +748,8 @@ async function handleCreateRuntime(message, connection, state) {
738
748
  url,
739
749
  method: init.method,
740
750
  headers: init.headers,
741
- body: init.rawBody
751
+ body: init.rawBody,
752
+ signalAborted: init.signal.aborted
742
753
  };
743
754
  const result = await invokeCallbackWithReconnect(callbackContext, () => callbackContext.fetch, [serialized], "Fetch", invokeClientCallback);
744
755
  if (result && typeof result === "object" && result.__streamingResponse) {
@@ -978,6 +989,12 @@ async function handleDispatchRequest(message, connection, state) {
978
989
  return;
979
990
  }
980
991
  instance.lastActivity = Date.now();
992
+ const dispatchAbortController = new AbortController;
993
+ connection.dispatchAbortControllers.set(message.requestId, dispatchAbortController);
994
+ if (connection.earlyAbortedDispatches.has(message.requestId) || message.request.signalAborted) {
995
+ dispatchAbortController.abort();
996
+ connection.earlyAbortedDispatches.delete(message.requestId);
997
+ }
981
998
  try {
982
999
  let requestBody = null;
983
1000
  if (message.request.bodyStreamId !== undefined) {
@@ -988,9 +1005,12 @@ async function handleDispatchRequest(message, connection, state) {
988
1005
  const request = new Request(message.request.url, {
989
1006
  method: message.request.method,
990
1007
  headers: message.request.headers,
991
- body: requestBody
1008
+ body: requestBody,
1009
+ signal: dispatchAbortController.signal
1010
+ });
1011
+ const response = await instance.runtime.fetch.dispatchRequest(request, {
1012
+ signal: dispatchAbortController.signal
992
1013
  });
993
- const response = await instance.runtime.fetch.dispatchRequest(request);
994
1014
  if (response.body) {
995
1015
  await sendStreamedResponse(connection, message.requestId, response);
996
1016
  } else {
@@ -1010,7 +1030,18 @@ async function handleDispatchRequest(message, connection, state) {
1010
1030
  } catch (err) {
1011
1031
  const error = err;
1012
1032
  sendError(connection.socket, message.requestId, ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
1033
+ } finally {
1034
+ connection.dispatchAbortControllers.delete(message.requestId);
1035
+ connection.earlyAbortedDispatches.delete(message.requestId);
1036
+ }
1037
+ }
1038
+ function handleDispatchRequestAbort(message, connection) {
1039
+ const controller = connection.dispatchAbortControllers.get(message.targetRequestId);
1040
+ if (controller) {
1041
+ controller.abort();
1042
+ return;
1013
1043
  }
1044
+ connection.earlyAbortedDispatches.add(message.targetRequestId);
1014
1045
  }
1015
1046
  function receiveStreamedBody(connection, streamId) {
1016
1047
  return new Promise((resolve, reject) => {
@@ -1646,4 +1677,4 @@ export {
1646
1677
  handleConnection
1647
1678
  };
1648
1679
 
1649
- //# debugId=DCB2345D02FBF03C64756E2164756E21
1680
+ //# debugId=23FC39B31009F9AA64756E2164756E21