@volter/tabnode 0.5.0 → 0.5.2

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.
@@ -27119,6 +27119,16 @@ function nodeLibPublic(name, require2, _process) {
27119
27119
  });
27120
27120
  return __table[name];
27121
27121
  }
27122
+ const stackOverrides = /* @__PURE__ */ new Map();
27123
+ const stackOverrideMap = {
27124
+ set(error, override) {
27125
+ stackOverrides.set(error, override);
27126
+ return this;
27127
+ },
27128
+ get: (error) => stackOverrides.get(error),
27129
+ has: (error) => stackOverrides.has(error),
27130
+ delete: (error) => stackOverrides.delete(error)
27131
+ };
27122
27132
  var builtPrimordials;
27123
27133
  function primordialsOf() {
27124
27134
  if (builtPrimordials === void 0) {
@@ -27396,6 +27406,11 @@ function bootstrapNodeLib(name, exports$1, process2) {
27396
27406
  };
27397
27407
  return;
27398
27408
  }
27409
+ if (name === "internal/errors") {
27410
+ const map = exports$1.overrideStackTrace;
27411
+ for (const [key, value] of Object.entries(stackOverrideMap)) Object.defineProperty(map, key, { value, configurable: true });
27412
+ return;
27413
+ }
27399
27414
  if (name === "internal/util/debuglog") {
27400
27415
  const env = process2.env;
27401
27416
  (_a3 = exports$1.initializeDebugEnv) == null ? void 0 : _a3.call(exports$1, (env == null ? void 0 : env.NODE_DEBUG) ?? "");
@@ -75817,7 +75832,17 @@ function __substrateCallSiteFileNames() {
75817
75832
  }
75818
75833
  return namer;
75819
75834
  };
75820
- const get2 = () => typeof guestPrepare === "function" ? namerFor(guestPrepare) : guestPrepare;
75835
+ const overriding = (error, sites) => {
75836
+ const override = error !== null && typeof error === "object" ? stackOverrides.get(error) : void 0;
75837
+ if (override) {
75838
+ stackOverrides.delete(error);
75839
+ return override(error, sites.map(named));
75840
+ }
75841
+ if (typeof guestPrepare === "function") return namerFor(guestPrepare)(error, sites);
75842
+ return `${Error.prototype.toString.call(error)}${sites.map((site) => `
75843
+ at ${String(site)}`).join("")}`;
75844
+ };
75845
+ const get2 = () => stackOverrides.size > 0 ? overriding : typeof guestPrepare === "function" ? namerFor(guestPrepare) : guestPrepare;
75821
75846
  get2.__substrateNamesFrames = true;
75822
75847
  defineOnHost(Error, "prepareStackTrace", {
75823
75848
  get: get2,
package/dist/index.mjs CHANGED
@@ -17762,17 +17762,10 @@ var implementation$1 = function bind2(that) {
17762
17762
  var implementation = implementation$1;
17763
17763
  var functionBind = Function.prototype.bind || implementation;
17764
17764
  var functionCall = Function.prototype.call;
17765
- var functionApply;
17766
- var hasRequiredFunctionApply;
17767
- function requireFunctionApply() {
17768
- if (hasRequiredFunctionApply) return functionApply;
17769
- hasRequiredFunctionApply = 1;
17770
- functionApply = Function.prototype.apply;
17771
- return functionApply;
17772
- }
17765
+ var functionApply = Function.prototype.apply;
17773
17766
  var reflectApply = typeof Reflect !== "undefined" && Reflect && Reflect.apply;
17774
17767
  var bind$2 = functionBind;
17775
- var $apply$1 = requireFunctionApply();
17768
+ var $apply$1 = functionApply;
17776
17769
  var $call$2 = functionCall;
17777
17770
  var $reflectApply = reflectApply;
17778
17771
  var actualApply = $reflectApply || bind$2.call($call$2, $apply$1);
@@ -17892,7 +17885,7 @@ var hasSymbols = requireHasSymbols()();
17892
17885
  var getProto = requireGetProto();
17893
17886
  var $ObjectGPO = requireObject_getPrototypeOf();
17894
17887
  var $ReflectGPO = requireReflect_getPrototypeOf();
17895
- var $apply = requireFunctionApply();
17888
+ var $apply = functionApply;
17896
17889
  var $call = functionCall;
17897
17890
  var needsEval = {};
17898
17891
  var TypedArray = typeof Uint8Array === "undefined" || !getProto ? undefined$1 : getProto(Uint8Array);
@@ -18533,7 +18526,7 @@ function requireApplyBind() {
18533
18526
  if (hasRequiredApplyBind) return applyBind;
18534
18527
  hasRequiredApplyBind = 1;
18535
18528
  var bind3 = functionBind;
18536
- var $apply2 = requireFunctionApply();
18529
+ var $apply2 = functionApply;
18537
18530
  var actualApply$1 = actualApply;
18538
18531
  applyBind = function applyBind2() {
18539
18532
  return actualApply$1(bind3, $apply2, arguments);
@@ -27293,6 +27286,16 @@ function nodeLibPublic(name, require2, _process) {
27293
27286
  });
27294
27287
  return __table[name];
27295
27288
  }
27289
+ const stackOverrides = /* @__PURE__ */ new Map();
27290
+ const stackOverrideMap = {
27291
+ set(error, override) {
27292
+ stackOverrides.set(error, override);
27293
+ return this;
27294
+ },
27295
+ get: (error) => stackOverrides.get(error),
27296
+ has: (error) => stackOverrides.has(error),
27297
+ delete: (error) => stackOverrides.delete(error)
27298
+ };
27296
27299
  var builtPrimordials;
27297
27300
  function primordialsOf() {
27298
27301
  if (builtPrimordials === void 0) {
@@ -27576,6 +27579,11 @@ function bootstrapNodeLib(name, exports$1, process2) {
27576
27579
  };
27577
27580
  return;
27578
27581
  }
27582
+ if (name === "internal/errors") {
27583
+ const map = exports$1.overrideStackTrace;
27584
+ for (const [key, value] of Object.entries(stackOverrideMap)) Object.defineProperty(map, key, { value, configurable: true });
27585
+ return;
27586
+ }
27579
27587
  if (name === "internal/util/debuglog") {
27580
27588
  const env = process2.env;
27581
27589
  (_a2 = exports$1.initializeDebugEnv) == null ? void 0 : _a2.call(exports$1, (env == null ? void 0 : env.NODE_DEBUG) ?? "");
@@ -35505,7 +35513,17 @@ function __substrateCallSiteFileNames() {
35505
35513
  }
35506
35514
  return namer;
35507
35515
  };
35508
- const get2 = () => typeof guestPrepare === "function" ? namerFor(guestPrepare) : guestPrepare;
35516
+ const overriding = (error, sites) => {
35517
+ const override = error !== null && typeof error === "object" ? stackOverrides.get(error) : void 0;
35518
+ if (override) {
35519
+ stackOverrides.delete(error);
35520
+ return override(error, sites.map(named));
35521
+ }
35522
+ if (typeof guestPrepare === "function") return namerFor(guestPrepare)(error, sites);
35523
+ return `${Error.prototype.toString.call(error)}${sites.map((site) => `
35524
+ at ${String(site)}`).join("")}`;
35525
+ };
35526
+ const get2 = () => stackOverrides.size > 0 ? overriding : typeof guestPrepare === "function" ? namerFor(guestPrepare) : guestPrepare;
35509
35527
  get2.__substrateNamesFrames = true;
35510
35528
  defineOnHost(Error, "prepareStackTrace", {
35511
35529
  get: get2,
@@ -35530,7 +35548,7 @@ class WorkerRuntime {
35530
35548
  this.worker = new Worker(
35531
35549
  new URL(
35532
35550
  /* @vite-ignore */
35533
- "/assets/runtime-worker-B9buriZs.js",
35551
+ "/assets/runtime-worker-CqG62h2U.js",
35534
35552
  import.meta.url
35535
35553
  ),
35536
35554
  { type: "module" }
@@ -38262,9 +38280,14 @@ function createContainer(options) {
38262
38280
  // socket handler of its own, so a guest's `net.connect` reaches it: the
38263
38281
  // registry a connect consults is the `net` shim's, and a server of the
38264
38282
  // shim's own class is what registers in it. The call answers a disposer.
38283
+ // The listener is the page's, not a guest's: a handle opened outside any
38284
+ // run is otherwise charged to the run launched last, which then read the
38285
+ // page's port as its own server and ended when the page stopped listening.
38286
+ // Sockets it accepts take its owner, so they hold no guest open either.
38265
38287
  listenNet: (port, onConnection) => {
38266
38288
  const server = new Server(onConnection);
38267
38289
  server.listen(port);
38290
+ __adoptHandle(server._handle, null);
38268
38291
  return () => {
38269
38292
  server.close();
38270
38293
  };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Node's `overrideStackTrace`, as the realm's stack hook reads it.
3
+ *
4
+ * Node's files format a stack their own way by putting a function for one
5
+ * error in `internal/errors`' `overrideStackTrace` and reading `error.stack`:
6
+ * `assert.ok` takes its caller's call site that way. V8 hands that function
7
+ * the call sites because Node's bootstrap registers `prepareStackTraceCallback`
8
+ * with it, and that callback reads the map first. The engine has no such
9
+ * registration; `Error.prepareStackTrace` is the door it has. Every process's
10
+ * `internal/errors` writes here, and the realm's hook reads here, so the
11
+ * override reaches V8 whichever process set it. An entry is consumed by the
12
+ * stack it formats, as Node's is.
13
+ */
14
+ export type StackOverride = (error: unknown, sites: unknown[]) => unknown;
15
+ export declare const stackOverrides: Map<object, StackOverride>;
16
+ /** A WeakMap-shaped view of the table, which is what `internal/errors` holds. */
17
+ export declare const stackOverrideMap: {
18
+ set(this: object, error: object, override: StackOverride): object;
19
+ get: (error: object) => StackOverride | undefined;
20
+ has: (error: object) => boolean;
21
+ delete: (error: object) => boolean;
22
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/tabnode",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Node's own library, in a browser tab.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/index.ts CHANGED
@@ -54,6 +54,7 @@ import { PackageManager } from './npm';
54
54
  import { ServerBridge, getServerBridge } from './server-bridge';
55
55
  import { runCommand, registerRunStreams, releaseRunStreams, sendStdin } from './shims/child_process';
56
56
  import { Server as NetServer, __releaseOwnedHandles, type Socket as NetSocket } from './node-lib/net-module';
57
+ import { __adoptHandle, type OwnedHandle } from './node-lib/binding/handles';
57
58
 
58
59
  import { __currentProcessToken, __runFor, __stopOwnedProcess, runPid, processByPid } from './process-tokens';
59
60
  export { runPid, processByPid };
@@ -229,9 +230,14 @@ export function createContainer(options?: ContainerOptions): {
229
230
  // socket handler of its own, so a guest's `net.connect` reaches it: the
230
231
  // registry a connect consults is the `net` shim's, and a server of the
231
232
  // shim's own class is what registers in it. The call answers a disposer.
233
+ // The listener is the page's, not a guest's: a handle opened outside any
234
+ // run is otherwise charged to the run launched last, which then read the
235
+ // page's port as its own server and ended when the page stopped listening.
236
+ // Sockets it accepts take its owner, so they hold no guest open either.
232
237
  listenNet: (port: number, onConnection: (socket: NetSocket) => void) => {
233
238
  const server = new NetServer(onConnection);
234
239
  server.listen(port);
240
+ __adoptHandle((server as unknown as { _handle?: OwnedHandle | null })._handle, null);
235
241
  return () => { server.close(); };
236
242
  },
237
243
  createREPL: () => runtime.createREPL(),
@@ -31,6 +31,7 @@ import { setLibRequire } from './require-hook';
31
31
  import { NODE_LTS_VERSION, nodeVersions } from './node-versions';
32
32
  import { createUtilBinding } from './binding/util';
33
33
  import { createFsBindings } from './binding/fs';
34
+ import { stackOverrideMap } from '../stack-overrides';
34
35
 
35
36
  /**
36
37
  * The realm's built-ins, captured as Node captures them: before a program can
@@ -445,6 +446,19 @@ function bootstrapNodeLib(name: string, exports: unknown, process: object): void
445
446
  };
446
447
  return;
447
448
  }
449
+ if (name === 'internal/errors') {
450
+ // Node's bootstrap registers this file's `prepareStackTraceCallback` with
451
+ // V8, which reads `overrideStackTrace` before anything else formats a
452
+ // stack. Here the realm's `Error.prepareStackTrace` hook is that reader,
453
+ // so the map is the one it reads (`src/stack-overrides.ts`). Unread, an
454
+ // `assert.ok(false)` indexed the stack's text for a call site and threw
455
+ // `TypeError: call.getFileName is not a function`.
456
+ // A primordial map's prototype is frozen, so its methods are shadowed by
457
+ // definition rather than assignment.
458
+ const map = (exports as { overrideStackTrace: object }).overrideStackTrace;
459
+ for (const [key, value] of Object.entries(stackOverrideMap)) Object.defineProperty(map, key, { value, configurable: true });
460
+ return;
461
+ }
448
462
  if (name === 'internal/util/debuglog') {
449
463
  const env = (process as { env?: Record<string, string | undefined> }).env;
450
464
  (exports as { initializeDebugEnv?: (value: string) => void }).initializeDebugEnv?.(env?.NODE_DEBUG ?? '');
package/src/runtime.ts CHANGED
@@ -24,6 +24,7 @@ import { netModule as netShim } from './node-lib/net-module';
24
24
  import { errname as __uvErrname } from './node-lib/binding/uv';
25
25
  import { createTimersModule } from './node-lib/timers';
26
26
  import { guestTimerFunctions } from './guest-timers';
27
+ import { stackOverrides } from './stack-overrides';
27
28
  export { pendingGuestTimers, stopGuestTimers } from './guest-timers';
28
29
  import eventsShim from './node-lib/events-module';
29
30
  import { streamModule as streamShim, streamPromisesModule as streamPromises } from './node-lib/stream-module';
@@ -2936,7 +2937,19 @@ function __substrateCallSiteFileNames(): void {
2936
2937
  }
2937
2938
  return namer;
2938
2939
  };
2939
- const get = () => (typeof guestPrepare === 'function' ? namerFor(guestPrepare as Prepare) : guestPrepare);
2940
+ // While one of Node's own files has an override pending for a stack it is
2941
+ // about to read, V8 is handed a function that gives that error its
2942
+ // override and every other error what it would have had: the guest's
2943
+ // function, else V8's own text, which is the error and one `at` line
2944
+ // per call site. Otherwise V8 is handed exactly what the guest set.
2945
+ const overriding: Prepare = (error, sites) => {
2946
+ const override = error !== null && typeof error === 'object' ? stackOverrides.get(error) : undefined;
2947
+ if (override) { stackOverrides.delete(error as object); return override(error, sites.map(named)); }
2948
+ if (typeof guestPrepare === 'function') return namerFor(guestPrepare as Prepare)(error, sites);
2949
+ return `${Error.prototype.toString.call(error)}${sites.map(site => `\n at ${String(site)}`).join('')}`;
2950
+ };
2951
+ const get = () => (stackOverrides.size > 0 ? overriding
2952
+ : typeof guestPrepare === 'function' ? namerFor(guestPrepare as Prepare) : guestPrepare);
2940
2953
  (get as { __substrateNamesFrames?: boolean }).__substrateNamesFrames = true;
2941
2954
  defineOnHost(Error, 'prepareStackTrace', {
2942
2955
  get,
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Node's `overrideStackTrace`, as the realm's stack hook reads it.
3
+ *
4
+ * Node's files format a stack their own way by putting a function for one
5
+ * error in `internal/errors`' `overrideStackTrace` and reading `error.stack`:
6
+ * `assert.ok` takes its caller's call site that way. V8 hands that function
7
+ * the call sites because Node's bootstrap registers `prepareStackTraceCallback`
8
+ * with it, and that callback reads the map first. The engine has no such
9
+ * registration; `Error.prepareStackTrace` is the door it has. Every process's
10
+ * `internal/errors` writes here, and the realm's hook reads here, so the
11
+ * override reaches V8 whichever process set it. An entry is consumed by the
12
+ * stack it formats, as Node's is.
13
+ */
14
+ export type StackOverride = (error: unknown, sites: unknown[]) => unknown;
15
+
16
+ export const stackOverrides = new Map<object, StackOverride>();
17
+
18
+ /** A WeakMap-shaped view of the table, which is what `internal/errors` holds. */
19
+ export const stackOverrideMap = {
20
+ set(this: object, error: object, override: StackOverride) { stackOverrides.set(error, override); return this; },
21
+ get: (error: object) => stackOverrides.get(error),
22
+ has: (error: object) => stackOverrides.has(error),
23
+ delete: (error: object) => stackOverrides.delete(error),
24
+ };