@ricsam/isolate-daemon 0.1.10 → 0.1.12

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.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/isolate-daemon",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "type": "commonjs"
5
5
  }
@@ -1,5 +1,6 @@
1
1
  // packages/isolate-daemon/src/connection.ts
2
2
  import { randomUUID } from "node:crypto";
3
+ import path from "node:path";
3
4
  import ivm from "isolated-vm";
4
5
  import {
5
6
  createFrameParser,
@@ -8,6 +9,7 @@ import {
8
9
  ErrorCode,
9
10
  STREAM_CHUNK_SIZE,
10
11
  STREAM_DEFAULT_CREDIT,
12
+ normalizeEntryFilename,
11
13
  marshalValue,
12
14
  unmarshalValue
13
15
  } from "@ricsam/isolate-protocol";
@@ -24,6 +26,12 @@ import {
24
26
  import {
25
27
  createInternalRuntime
26
28
  } from "@ricsam/isolate-runtime";
29
+ import {
30
+ transformEntryCode,
31
+ transformModuleCode,
32
+ contentHash,
33
+ mapErrorStack
34
+ } from "@ricsam/isolate-transform";
27
35
  function handleConnection(socket, state) {
28
36
  const connection = {
29
37
  socket,
@@ -406,7 +414,7 @@ async function handleCreateRuntime(message, connection, state) {
406
414
  }
407
415
  },
408
416
  fs: {
409
- getDirectory: async (path) => {
417
+ getDirectory: async (path2) => {
410
418
  const conn = callbackContext.connection;
411
419
  if (!conn) {
412
420
  throw new Error("FS callbacks not available");
@@ -415,7 +423,7 @@ async function handleCreateRuntime(message, connection, state) {
415
423
  connection: conn,
416
424
  callbackContext,
417
425
  invokeClientCallback,
418
- basePath: path
426
+ basePath: path2
419
427
  });
420
428
  }
421
429
  }
@@ -439,6 +447,7 @@ async function handleCreateRuntime(message, connection, state) {
439
447
  if (moduleLoaderCallback) {
440
448
  instance.moduleLoaderCallbackId = moduleLoaderCallback.callbackId;
441
449
  instance.moduleCache = new Map;
450
+ instance.moduleToFilename = new Map;
442
451
  }
443
452
  if (customCallbacks) {
444
453
  await setupCustomFunctions(runtime.context, customCallbacks, connection, instance);
@@ -583,10 +592,19 @@ async function handleEval(message, connection, state) {
583
592
  }
584
593
  instance.lastActivity = Date.now();
585
594
  try {
586
- const mod = await instance.runtime.isolate.compileModule(message.code, {
587
- filename: message.filename ?? "<eval>"
595
+ const filename = normalizeEntryFilename(message.filename);
596
+ const transformed = await transformEntryCode(message.code, filename);
597
+ if (transformed.sourceMap) {
598
+ if (!instance.sourceMaps) {
599
+ instance.sourceMaps = new Map;
600
+ }
601
+ instance.sourceMaps.set(filename, transformed.sourceMap);
602
+ }
603
+ const mod = await instance.runtime.isolate.compileModule(transformed.code, {
604
+ filename
588
605
  });
589
606
  if (instance.moduleLoaderCallbackId) {
607
+ instance.moduleToFilename?.set(mod, filename);
590
608
  const resolver = createModuleResolver(instance, connection);
591
609
  await mod.instantiate(instance.runtime.context, resolver);
592
610
  } else {
@@ -594,13 +612,25 @@ async function handleEval(message, connection, state) {
594
612
  throw new Error(`No module loader registered. Cannot import: ${specifier}`);
595
613
  });
596
614
  }
597
- const timeout = message.maxExecutionMs;
598
- await mod.evaluate(timeout ? { timeout } : undefined);
615
+ await mod.evaluate();
616
+ const ns = mod.namespace;
617
+ const runRef = await ns.get("default", { reference: true });
618
+ try {
619
+ await runRef.apply(undefined, [], {
620
+ result: { promise: true },
621
+ ...message.maxExecutionMs ? { timeout: message.maxExecutionMs } : {}
622
+ });
623
+ } finally {
624
+ runRef.release();
625
+ }
599
626
  await Promise.all(instance.pendingCallbacks);
600
627
  instance.pendingCallbacks.length = 0;
601
628
  sendOk(connection.socket, message.requestId, { value: undefined });
602
629
  } catch (err) {
603
630
  const error = err;
631
+ if (error.stack && instance.sourceMaps?.size) {
632
+ error.stack = mapErrorStack(error.stack, instance.sourceMaps);
633
+ }
604
634
  const isTimeoutError = error.message?.includes("Script execution timed out");
605
635
  sendError(connection.socket, message.requestId, isTimeoutError ? ErrorCode.ISOLATE_TIMEOUT : ErrorCode.SCRIPT_ERROR, error.message, { name: error.name, stack: error.stack });
606
636
  }
@@ -1354,20 +1384,38 @@ async function setupCustomFunctions(context, customCallbacks, connection, instan
1354
1384
  }
1355
1385
  }
1356
1386
  function createModuleResolver(instance, connection) {
1357
- return async (specifier, _referrer) => {
1387
+ return async (specifier, referrer) => {
1358
1388
  const cached = instance.moduleCache?.get(specifier);
1359
1389
  if (cached)
1360
1390
  return cached;
1361
1391
  if (!instance.moduleLoaderCallbackId) {
1362
1392
  throw new Error(`Module not found: ${specifier}`);
1363
1393
  }
1364
- const code = await invokeClientCallback(connection, instance.moduleLoaderCallbackId, [specifier]);
1365
- const mod = await instance.runtime.isolate.compileModule(code, {
1394
+ const importerPath = instance.moduleToFilename?.get(referrer) ?? "<unknown>";
1395
+ const importerResolveDir = path.posix.dirname(importerPath);
1396
+ const result = await invokeClientCallback(connection, instance.moduleLoaderCallbackId, [specifier, { path: importerPath, resolveDir: importerResolveDir }]);
1397
+ const { code, resolveDir } = result;
1398
+ const hash = contentHash(code);
1399
+ const cacheKey = `${specifier}:${hash}`;
1400
+ const hashCached = instance.moduleCache?.get(cacheKey);
1401
+ if (hashCached)
1402
+ return hashCached;
1403
+ const transformed = await transformModuleCode(code, specifier);
1404
+ if (transformed.sourceMap) {
1405
+ if (!instance.sourceMaps) {
1406
+ instance.sourceMaps = new Map;
1407
+ }
1408
+ instance.sourceMaps.set(specifier, transformed.sourceMap);
1409
+ }
1410
+ const mod = await instance.runtime.isolate.compileModule(transformed.code, {
1366
1411
  filename: specifier
1367
1412
  });
1413
+ const resolvedPath = path.posix.join(resolveDir, path.posix.basename(specifier));
1414
+ instance.moduleToFilename?.set(mod, resolvedPath);
1368
1415
  const resolver = createModuleResolver(instance, connection);
1369
1416
  await mod.instantiate(instance.runtime.context, resolver);
1370
1417
  instance.moduleCache?.set(specifier, mod);
1418
+ instance.moduleCache?.set(cacheKey, mod);
1371
1419
  return mod;
1372
1420
  };
1373
1421
  }
@@ -1510,6 +1558,10 @@ function handleCallbackStreamStart(message, connection) {
1510
1558
  resolver();
1511
1559
  }
1512
1560
  connection.callbackStreamReceivers.delete(message.streamId);
1561
+ sendMessage(connection.socket, {
1562
+ type: MessageType.CALLBACK_STREAM_CANCEL,
1563
+ streamId: message.streamId
1564
+ });
1513
1565
  return Promise.resolve();
1514
1566
  }
1515
1567
  });
@@ -1785,4 +1837,4 @@ export {
1785
1837
  handleConnection
1786
1838
  };
1787
1839
 
1788
- //# debugId=2A1E0650E9CDD7A964756E2164756E21
1840
+ //# debugId=514032B8427B94A564756E2164756E21