@volter/tabnode 0.5.1 → 0.5.3

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.
@@ -27126,6 +27126,16 @@ function nodeLibPublic(name, require2, _process) {
27126
27126
  });
27127
27127
  return __table[name];
27128
27128
  }
27129
+ const stackOverrides = /* @__PURE__ */ new Map();
27130
+ const stackOverrideMap = {
27131
+ set(error, override) {
27132
+ stackOverrides.set(error, override);
27133
+ return this;
27134
+ },
27135
+ get: (error) => stackOverrides.get(error),
27136
+ has: (error) => stackOverrides.has(error),
27137
+ delete: (error) => stackOverrides.delete(error)
27138
+ };
27129
27139
  var builtPrimordials;
27130
27140
  function primordialsOf() {
27131
27141
  if (builtPrimordials === void 0) {
@@ -27403,6 +27413,11 @@ function bootstrapNodeLib(name, exports$1, process2) {
27403
27413
  };
27404
27414
  return;
27405
27415
  }
27416
+ if (name === "internal/errors") {
27417
+ const map = exports$1.overrideStackTrace;
27418
+ for (const [key, value] of Object.entries(stackOverrideMap)) Object.defineProperty(map, key, { value, configurable: true });
27419
+ return;
27420
+ }
27406
27421
  if (name === "internal/util/debuglog") {
27407
27422
  const env = process2.env;
27408
27423
  (_a3 = exports$1.initializeDebugEnv) == null ? void 0 : _a3.call(exports$1, (env == null ? void 0 : env.NODE_DEBUG) ?? "");
@@ -75824,7 +75839,17 @@ function __substrateCallSiteFileNames() {
75824
75839
  }
75825
75840
  return namer;
75826
75841
  };
75827
- const get2 = () => typeof guestPrepare === "function" ? namerFor(guestPrepare) : guestPrepare;
75842
+ const overriding = (error, sites) => {
75843
+ const override = error !== null && typeof error === "object" ? stackOverrides.get(error) : void 0;
75844
+ if (override) {
75845
+ stackOverrides.delete(error);
75846
+ return override(error, sites.map(named));
75847
+ }
75848
+ if (typeof guestPrepare === "function") return namerFor(guestPrepare)(error, sites);
75849
+ return `${Error.prototype.toString.call(error)}${sites.map((site) => `
75850
+ at ${String(site)}`).join("")}`;
75851
+ };
75852
+ const get2 = () => stackOverrides.size > 0 ? overriding : typeof guestPrepare === "function" ? namerFor(guestPrepare) : guestPrepare;
75828
75853
  get2.__substrateNamesFrames = true;
75829
75854
  defineOnHost(Error, "prepareStackTrace", {
75830
75855
  get: get2,
package/dist/index.mjs CHANGED
@@ -17762,10 +17762,17 @@ 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 = Function.prototype.apply;
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
+ }
17766
17773
  var reflectApply = typeof Reflect !== "undefined" && Reflect && Reflect.apply;
17767
17774
  var bind$2 = functionBind;
17768
- var $apply$1 = functionApply;
17775
+ var $apply$1 = requireFunctionApply();
17769
17776
  var $call$2 = functionCall;
17770
17777
  var $reflectApply = reflectApply;
17771
17778
  var actualApply = $reflectApply || bind$2.call($call$2, $apply$1);
@@ -17885,7 +17892,7 @@ var hasSymbols = requireHasSymbols()();
17885
17892
  var getProto = requireGetProto();
17886
17893
  var $ObjectGPO = requireObject_getPrototypeOf();
17887
17894
  var $ReflectGPO = requireReflect_getPrototypeOf();
17888
- var $apply = functionApply;
17895
+ var $apply = requireFunctionApply();
17889
17896
  var $call = functionCall;
17890
17897
  var needsEval = {};
17891
17898
  var TypedArray = typeof Uint8Array === "undefined" || !getProto ? undefined$1 : getProto(Uint8Array);
@@ -18526,7 +18533,7 @@ function requireApplyBind() {
18526
18533
  if (hasRequiredApplyBind) return applyBind;
18527
18534
  hasRequiredApplyBind = 1;
18528
18535
  var bind3 = functionBind;
18529
- var $apply2 = functionApply;
18536
+ var $apply2 = requireFunctionApply();
18530
18537
  var actualApply$1 = actualApply;
18531
18538
  applyBind = function applyBind2() {
18532
18539
  return actualApply$1(bind3, $apply2, arguments);
@@ -27286,6 +27293,16 @@ function nodeLibPublic(name, require2, _process) {
27286
27293
  });
27287
27294
  return __table[name];
27288
27295
  }
27296
+ const stackOverrides = /* @__PURE__ */ new Map();
27297
+ const stackOverrideMap = {
27298
+ set(error, override) {
27299
+ stackOverrides.set(error, override);
27300
+ return this;
27301
+ },
27302
+ get: (error) => stackOverrides.get(error),
27303
+ has: (error) => stackOverrides.has(error),
27304
+ delete: (error) => stackOverrides.delete(error)
27305
+ };
27289
27306
  var builtPrimordials;
27290
27307
  function primordialsOf() {
27291
27308
  if (builtPrimordials === void 0) {
@@ -27569,6 +27586,11 @@ function bootstrapNodeLib(name, exports$1, process2) {
27569
27586
  };
27570
27587
  return;
27571
27588
  }
27589
+ if (name === "internal/errors") {
27590
+ const map = exports$1.overrideStackTrace;
27591
+ for (const [key, value] of Object.entries(stackOverrideMap)) Object.defineProperty(map, key, { value, configurable: true });
27592
+ return;
27593
+ }
27572
27594
  if (name === "internal/util/debuglog") {
27573
27595
  const env = process2.env;
27574
27596
  (_a2 = exports$1.initializeDebugEnv) == null ? void 0 : _a2.call(exports$1, (env == null ? void 0 : env.NODE_DEBUG) ?? "");
@@ -35498,7 +35520,17 @@ function __substrateCallSiteFileNames() {
35498
35520
  }
35499
35521
  return namer;
35500
35522
  };
35501
- const get2 = () => typeof guestPrepare === "function" ? namerFor(guestPrepare) : guestPrepare;
35523
+ const overriding = (error, sites) => {
35524
+ const override = error !== null && typeof error === "object" ? stackOverrides.get(error) : void 0;
35525
+ if (override) {
35526
+ stackOverrides.delete(error);
35527
+ return override(error, sites.map(named));
35528
+ }
35529
+ if (typeof guestPrepare === "function") return namerFor(guestPrepare)(error, sites);
35530
+ return `${Error.prototype.toString.call(error)}${sites.map((site) => `
35531
+ at ${String(site)}`).join("")}`;
35532
+ };
35533
+ const get2 = () => stackOverrides.size > 0 ? overriding : typeof guestPrepare === "function" ? namerFor(guestPrepare) : guestPrepare;
35502
35534
  get2.__substrateNamesFrames = true;
35503
35535
  defineOnHost(Error, "prepareStackTrace", {
35504
35536
  get: get2,
@@ -35523,7 +35555,7 @@ class WorkerRuntime {
35523
35555
  this.worker = new Worker(
35524
35556
  new URL(
35525
35557
  /* @vite-ignore */
35526
- "/assets/runtime-worker-DBZ2flHK.js",
35558
+ "/assets/runtime-worker-CfmZOVKz.js",
35527
35559
  import.meta.url
35528
35560
  ),
35529
35561
  { type: "module" }
@@ -37383,11 +37415,15 @@ function __substrateListenForUpgrades(bridge) {
37383
37415
  const key = uint8ToBase64(crypto.getRandomValues(new Uint8Array(16)));
37384
37416
  const protocols = Array.isArray(data2.protocols) ? data2.protocols : [];
37385
37417
  void __upgradeOverLoopback(port, "GET", url2.pathname + url2.search, {
37386
- Host: url2.host,
37418
+ // Host is the authority the client addressed, as an HTTP request's is
37419
+ Host: typeof data2.host === "string" && /^(?:\[[0-9a-f:.]+\]|[a-z0-9.-]+)(?::[0-9]{1,5})?$/iu.test(data2.host) ? data2.host : url2.host,
37387
37420
  Upgrade: "websocket",
37388
37421
  "Sec-WebSocket-Version": "13",
37389
37422
  "Sec-WebSocket-Key": key,
37390
- ...protocols.length ? { "Sec-WebSocket-Protocol": protocols.join(", ") } : {}
37423
+ ...protocols.length ? { "Sec-WebSocket-Protocol": protocols.join(", ") } : {},
37424
+ // A browser sends Origin on every WebSocket handshake, and a server's
37425
+ // check of it is how it refuses sockets from pages it did not serve.
37426
+ ...typeof data2.origin === "string" && /^https?:\/\/[^/]+$/u.test(data2.origin) ? { Origin: data2.origin } : {}
37391
37427
  }).then((result) => {
37392
37428
  if (result.statusCode !== 101 || !result.socket) {
37393
37429
  channel.postMessage({ type: "close", targetClient: data2.clientId, code: 1006, reason: "upgrade refused" });
@@ -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.1",
3
+ "version": "0.5.3",
4
4
  "description": "Node's own library, in a browser tab.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -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,
@@ -123,6 +123,10 @@ interface UpgradeSignal {
123
123
  protocols?: string[];
124
124
  /** `"none"` asks for a byte pipe; anything else, or nothing, is a WebSocket. */
125
125
  framing?: "websocket" | "none";
126
+ /** The origin of the page that opened the socket, which a browser sends on every handshake. */
127
+ origin?: string;
128
+ /** The authority the client addressed, its handshake's Host; the engine's own URL names the port. */
129
+ host?: string;
126
130
  payload?: string | ArrayBuffer;
127
131
  code?: number;
128
132
  reason?: string;
@@ -348,11 +352,15 @@ function __substrateListenForUpgrades(bridge: ServerBridge): BroadcastChannel |
348
352
  // with the socket, which is what the real `ws` takes over. What comes
349
353
  // back here is the client's end of that same connection.
350
354
  void __upgradeOverLoopback(port, "GET", url2.pathname + url2.search, {
351
- Host: url2.host,
355
+ // Host is the authority the client addressed, as an HTTP request's is
356
+ Host: typeof data2.host === "string" && /^(?:\[[0-9a-f:.]+\]|[a-z0-9.-]+)(?::[0-9]{1,5})?$/iu.test(data2.host) ? data2.host : url2.host,
352
357
  Upgrade: "websocket",
353
358
  "Sec-WebSocket-Version": "13",
354
359
  "Sec-WebSocket-Key": key,
355
360
  ...(protocols.length ? { "Sec-WebSocket-Protocol": protocols.join(", ") } : {}),
361
+ // A browser sends Origin on every WebSocket handshake, and a server's
362
+ // check of it is how it refuses sockets from pages it did not serve.
363
+ ...(typeof data2.origin === "string" && /^https?:\/\/[^/]+$/u.test(data2.origin) ? { Origin: data2.origin } : {}),
356
364
  }).then((result) => {
357
365
  if (result.statusCode !== 101 || !result.socket) {
358
366
  channel.postMessage({ type: "close", targetClient: data2.clientId, code: 1006, reason: "upgrade refused" });
@@ -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
+ };