@volter/tabnode 0.5.6 → 0.5.8

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.
@@ -7817,7 +7817,7 @@ class Pipe extends LibuvStreamWrap {
7817
7817
  if (native) return native.write(req, [bytes2], handle);
7818
7818
  if (handle === void 0 || handle === null) return super.dispatchWrite(req, bytes2);
7819
7819
  const sent = handle;
7820
- const given = sent.peer !== null ? sent.duplicate() : sent;
7820
+ const given = sent.listening === true ? sent : sent.duplicate();
7821
7821
  __adoptHandle(given, ownerOf(this.peer ?? this));
7822
7822
  const status = super.dispatchWrite(req, bytes2, given);
7823
7823
  if (status !== 0 && given !== sent) given.close();
@@ -9324,7 +9324,16 @@ const osBinding = {
9324
9324
  /** Node's `os.type()`, `release()` and `version()`, in that order. */
9325
9325
  getOSInformation: () => [type$1(), release(), version$2()],
9326
9326
  getHostname: () => hostname(),
9327
- getHomeDirectory: () => homedir(),
9327
+ /**
9328
+ * Node's `os.homedir()` is libuv's: `HOME` when the environment sets it,
9329
+ * the account's directory otherwise. `userInfo().homedir` stays the
9330
+ * account's, as it is in Node.
9331
+ */
9332
+ getHomeDirectory: () => {
9333
+ var _a3, _b3;
9334
+ const home = (_b3 = (_a3 = globalThis.process) == null ? void 0 : _a3.env) == null ? void 0 : _b3.HOME;
9335
+ return home && home.length > 0 ? home : homedir();
9336
+ },
9328
9337
  getUptime: () => uptime(),
9329
9338
  getTotalMem: () => totalmem(),
9330
9339
  getFreeMem: () => freemem(),
@@ -70769,12 +70778,27 @@ function programExists(file, cwd, env) {
70769
70778
  const name = __substrateProgramName(file);
70770
70779
  const bare = name.includes("/") ? name.slice(name.lastIndexOf("/") + 1) : name;
70771
70780
  if (shellCommandNames().has(bare)) return true;
70772
- if (name.includes("/")) return existsInTree(resolve(cwd ?? "/", name));
70781
+ if (name.includes("/")) {
70782
+ const path2 = resolve(cwd ?? "/", name);
70783
+ return existsInTree(path2) && !isRegisteredProgramStub(path2);
70784
+ }
70773
70785
  for (const dir of (env.PATH ?? "/usr/local/bin:/usr/bin:/bin:/node_modules/.bin").split(":")) {
70774
- if (dir.length > 0 && existsInTree(`${dir}/${name}`.replace(/\/+/gu, "/"))) return true;
70786
+ const path2 = `${dir}/${name}`.replace(/\/+/gu, "/");
70787
+ if (dir.length > 0 && existsInTree(path2) && !isRegisteredProgramStub(path2)) return true;
70775
70788
  }
70776
70789
  return false;
70777
70790
  }
70791
+ const REGISTERED_PROGRAM_STUB = /^#!\/bin\/sh\n# [\w.+-]+: runtime-registered program\n/u;
70792
+ function isRegisteredProgramStub(path2) {
70793
+ if (!currentVfs$1) return false;
70794
+ try {
70795
+ const stat = currentVfs$1.statSync(path2);
70796
+ if (!stat.isFile() || stat.size > 256) return false;
70797
+ return REGISTERED_PROGRAM_STUB.test(String(currentVfs$1.readFileSync(path2, "utf8")));
70798
+ } catch {
70799
+ return false;
70800
+ }
70801
+ }
70778
70802
  let __nextChildRun = 1;
70779
70803
  function startChildRun(request) {
70780
70804
  var _a3;
@@ -73911,7 +73935,10 @@ function __substrateScopeGlobalCalls(code2) {
73911
73935
  }
73912
73936
  const positions = [];
73913
73937
  walkAst(ast, (node) => {
73914
- if (node.type === "NewExpression" && node.callee.type === "Identifier") positions.push([node.callee.start, node.callee.end, "(__substrateGuestConstructor(" + code2.slice(node.callee.start, node.callee.end) + ",$process))"]);
73938
+ if (node.type === "NewExpression" && node.callee.type === "Identifier") {
73939
+ const callee = code2.slice(node.callee.start, node.callee.end);
73940
+ positions.push([node.callee.start, node.callee.end, "(typeof __substrateGuestConstructor==='function'?__substrateGuestConstructor(" + callee + ",$process):" + callee + ")"]);
73941
+ }
73915
73942
  const called = node.type === "CallExpression" ? node.callee : node.type === "TaggedTemplateExpression" ? node.tag : void 0;
73916
73943
  if ((called == null ? void 0 : called.type) === "Identifier" && (called.name === "fetch" || called.name === "Promise")) positions.push([called.start, called.end, "(0," + code2.slice(called.start, called.end) + ")"]);
73917
73944
  });
package/dist/index.mjs CHANGED
@@ -7980,7 +7980,7 @@ class Pipe extends LibuvStreamWrap {
7980
7980
  if (native) return native.write(req, [bytes2], handle);
7981
7981
  if (handle === void 0 || handle === null) return super.dispatchWrite(req, bytes2);
7982
7982
  const sent = handle;
7983
- const given = sent.peer !== null ? sent.duplicate() : sent;
7983
+ const given = sent.listening === true ? sent : sent.duplicate();
7984
7984
  __adoptHandle(given, ownerOf(this.peer ?? this));
7985
7985
  const status = super.dispatchWrite(req, bytes2, given);
7986
7986
  if (status !== 0 && given !== sent) given.close();
@@ -9487,7 +9487,16 @@ const osBinding = {
9487
9487
  /** Node's `os.type()`, `release()` and `version()`, in that order. */
9488
9488
  getOSInformation: () => [type$1(), release(), version$2()],
9489
9489
  getHostname: () => hostname(),
9490
- getHomeDirectory: () => homedir(),
9490
+ /**
9491
+ * Node's `os.homedir()` is libuv's: `HOME` when the environment sets it,
9492
+ * the account's directory otherwise. `userInfo().homedir` stays the
9493
+ * account's, as it is in Node.
9494
+ */
9495
+ getHomeDirectory: () => {
9496
+ var _a2, _b2;
9497
+ const home = (_b2 = (_a2 = globalThis.process) == null ? void 0 : _a2.env) == null ? void 0 : _b2.HOME;
9498
+ return home && home.length > 0 ? home : homedir();
9499
+ },
9491
9500
  getUptime: () => uptime(),
9492
9501
  getTotalMem: () => totalmem(),
9493
9502
  getFreeMem: () => freemem(),
@@ -30461,12 +30470,27 @@ function programExists(file, cwd, env) {
30461
30470
  const name = __substrateProgramName(file);
30462
30471
  const bare = name.includes("/") ? name.slice(name.lastIndexOf("/") + 1) : name;
30463
30472
  if (shellCommandNames().has(bare)) return true;
30464
- if (name.includes("/")) return existsInTree(resolve(cwd ?? "/", name));
30473
+ if (name.includes("/")) {
30474
+ const path2 = resolve(cwd ?? "/", name);
30475
+ return existsInTree(path2) && !isRegisteredProgramStub(path2);
30476
+ }
30465
30477
  for (const dir of (env.PATH ?? "/usr/local/bin:/usr/bin:/bin:/node_modules/.bin").split(":")) {
30466
- if (dir.length > 0 && existsInTree(`${dir}/${name}`.replace(/\/+/gu, "/"))) return true;
30478
+ const path2 = `${dir}/${name}`.replace(/\/+/gu, "/");
30479
+ if (dir.length > 0 && existsInTree(path2) && !isRegisteredProgramStub(path2)) return true;
30467
30480
  }
30468
30481
  return false;
30469
30482
  }
30483
+ const REGISTERED_PROGRAM_STUB = /^#!\/bin\/sh\n# [\w.+-]+: runtime-registered program\n/u;
30484
+ function isRegisteredProgramStub(path2) {
30485
+ if (!currentVfs$1) return false;
30486
+ try {
30487
+ const stat = currentVfs$1.statSync(path2);
30488
+ if (!stat.isFile() || stat.size > 256) return false;
30489
+ return REGISTERED_PROGRAM_STUB.test(String(currentVfs$1.readFileSync(path2, "utf8")));
30490
+ } catch {
30491
+ return false;
30492
+ }
30493
+ }
30470
30494
  let __nextChildRun = 1;
30471
30495
  function startChildRun(request) {
30472
30496
  var _a2;
@@ -33604,7 +33628,10 @@ function __substrateScopeGlobalCalls(code2) {
33604
33628
  }
33605
33629
  const positions = [];
33606
33630
  walkAst(ast, (node) => {
33607
- if (node.type === "NewExpression" && node.callee.type === "Identifier") positions.push([node.callee.start, node.callee.end, "(__substrateGuestConstructor(" + code2.slice(node.callee.start, node.callee.end) + ",$process))"]);
33631
+ if (node.type === "NewExpression" && node.callee.type === "Identifier") {
33632
+ const callee = code2.slice(node.callee.start, node.callee.end);
33633
+ positions.push([node.callee.start, node.callee.end, "(typeof __substrateGuestConstructor==='function'?__substrateGuestConstructor(" + callee + ",$process):" + callee + ")"]);
33634
+ }
33608
33635
  const called = node.type === "CallExpression" ? node.callee : node.type === "TaggedTemplateExpression" ? node.tag : void 0;
33609
33636
  if ((called == null ? void 0 : called.type) === "Identifier" && (called.name === "fetch" || called.name === "Promise")) positions.push([called.start, called.end, "(0," + code2.slice(called.start, called.end) + ")"]);
33610
33637
  });
@@ -35668,7 +35695,7 @@ class WorkerRuntime {
35668
35695
  this.worker = new Worker(
35669
35696
  new URL(
35670
35697
  /* @vite-ignore */
35671
- "/assets/runtime-worker-Bt4uLPDa.js",
35698
+ "/assets/runtime-worker-Cl9uKRen.js",
35672
35699
  import.meta.url
35673
35700
  ),
35674
35701
  { type: "module" }
@@ -38135,7 +38162,7 @@ class NativeStreamScope {
38135
38162
  const handle = entry.handle;
38136
38163
  switch (operation.operation) {
38137
38164
  case "duplicate": {
38138
- if (!handle.peer || handle.listening) return { status: UV_ENOTSUP };
38165
+ if (handle.listening) return { status: UV_ENOTSUP };
38139
38166
  if (this.entries.size >= this.limits.maxHandles) return { status: UV_EMFILE };
38140
38167
  const copy2 = handle.duplicate();
38141
38168
  const descriptor = this.claim(copy2);
@@ -38240,7 +38267,7 @@ class NativeStreamScope {
38240
38267
  if (bytes2.byteLength > this.limits.maxReadChunkBytes || this.pendingWriteBytes + bytes2.byteLength > this.limits.maxPendingWriteBytes) return Promise.resolve(UV_ENOBUFS);
38241
38268
  const sent = sentId === void 0 ? void 0 : (_b2 = this.entry(sentId)) == null ? void 0 : _b2.handle;
38242
38269
  if (sentId !== void 0 && !sent) return Promise.resolve(UV_EBADF);
38243
- if (sent && (!(handle instanceof Pipe) || !sent.peer || sent.listening || bytes2.byteLength === 0)) return Promise.resolve(UV_ENOTSUP);
38270
+ if (sent && (!(handle instanceof Pipe) || sent.listening || bytes2.byteLength === 0)) return Promise.resolve(UV_ENOTSUP);
38244
38271
  const owned = new Uint8Array(bytes2.byteLength);
38245
38272
  owned.set(bytes2);
38246
38273
  const retained = sent == null ? void 0 : sent.duplicate();
@@ -38295,7 +38322,7 @@ class NativeStreamScope {
38295
38322
  if (this.entries.size >= this.limits.maxHandles) return { status: UV_EMFILE };
38296
38323
  const handle = (_a2 = source.entry(id)) == null ? void 0 : _a2.handle;
38297
38324
  if (!handle) return { status: UV_EBADF };
38298
- if (handle.listening || !handle.peer) return { status: UV_ENOTSUP };
38325
+ if (handle.listening) return { status: UV_ENOTSUP };
38299
38326
  const copy2 = handle.duplicate();
38300
38327
  const descriptor = this.claim(copy2);
38301
38328
  if (!descriptor) {
@@ -3,6 +3,11 @@ export declare const osBinding: {
3
3
  /** Node's `os.type()`, `release()` and `version()`, in that order. */
4
4
  getOSInformation: () => string[];
5
5
  getHostname: () => string;
6
+ /**
7
+ * Node's `os.homedir()` is libuv's: `HOME` when the environment sets it,
8
+ * the account's directory otherwise. `userInfo().homedir` stays the
9
+ * account's, as it is in Node.
10
+ */
6
11
  getHomeDirectory: () => string;
7
12
  getUptime: () => number;
8
13
  getTotalMem: () => number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/tabnode",
3
- "version": "0.5.6",
3
+ "version": "0.5.8",
4
4
  "description": "Node's own library, in a browser tab.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -142,7 +142,9 @@ export class NativeStreamScope {
142
142
  const handle = entry.handle;
143
143
  switch (operation.operation) {
144
144
  case 'duplicate': {
145
- if (!handle.peer || handle.listening) return { status: UV_ENOTSUP };
145
+ // A connection is duplicated whether or not its other end is still
146
+ // there (the copy reads its EOF); a listening server is not one.
147
+ if (handle.listening) return { status: UV_ENOTSUP };
146
148
  if (this.entries.size >= this.limits.maxHandles) return { status: UV_EMFILE };
147
149
  const copy = handle.duplicate();
148
150
  const descriptor = this.claim(copy);
@@ -240,7 +242,11 @@ export class NativeStreamScope {
240
242
  || this.pendingWriteBytes + bytes.byteLength > this.limits.maxPendingWriteBytes) return Promise.resolve(UV_ENOBUFS);
241
243
  const sent = sentId === undefined ? undefined : this.entry(sentId)?.handle;
242
244
  if (sentId !== undefined && !sent) return Promise.resolve(UV_EBADF);
243
- if (sent && (!(handle instanceof Pipe) || !sent.peer || sent.listening || bytes.byteLength === 0)) return Promise.resolve(UV_ENOTSUP);
245
+ // A connection crosses whether or not its other end is still there: Node
246
+ // passes a socket whose peer has closed, and the receiver reads its EOF.
247
+ // Refusing it failed the whole channel write (`write ENOTSUP`), which ended
248
+ // VS Code's extension host when a reconnecting client had already gone.
249
+ if (sent && (!(handle instanceof Pipe) || sent.listening || bytes.byteLength === 0)) return Promise.resolve(UV_ENOTSUP);
244
250
  // Retain the descriptor while capacity is unavailable; the sender can close
245
251
  // its original after submitting the write without invalidating this copy.
246
252
  const owned = new Uint8Array(bytes.byteLength);
@@ -285,7 +291,7 @@ export class NativeStreamScope {
285
291
  if (this.entries.size >= this.limits.maxHandles) return { status: UV_EMFILE };
286
292
  const handle = source.entry(id)?.handle;
287
293
  if (!handle) return { status: UV_EBADF };
288
- if (handle.listening || !handle.peer) return { status: UV_ENOTSUP };
294
+ if (handle.listening) return { status: UV_ENOTSUP };
289
295
  const copy = handle.duplicate();
290
296
  const descriptor = this.claim(copy);
291
297
  if (!descriptor) { copy.close(); return { status: UV_EMFILE }; }
@@ -81,7 +81,15 @@ export const osBinding = {
81
81
  /** Node's `os.type()`, `release()` and `version()`, in that order. */
82
82
  getOSInformation: (): string[] => [osShim.type(), osShim.release(), osShim.version()],
83
83
  getHostname: (): string => osShim.hostname(),
84
- getHomeDirectory: (): string => osShim.homedir(),
84
+ /**
85
+ * Node's `os.homedir()` is libuv's: `HOME` when the environment sets it,
86
+ * the account's directory otherwise. `userInfo().homedir` stays the
87
+ * account's, as it is in Node.
88
+ */
89
+ getHomeDirectory: (): string => {
90
+ const home = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process?.env?.HOME;
91
+ return home && home.length > 0 ? home : osShim.homedir();
92
+ },
85
93
  getUptime: (): number => osShim.uptime(),
86
94
  getTotalMem: (): number => osShim.totalmem(),
87
95
  getFreeMem: (): number => osShim.freemem(),
@@ -165,10 +165,11 @@ export class Pipe extends LibuvStreamWrap {
165
165
  // A descriptor crosses as a duplicate, as `SCM_RIGHTS` hands one over: the
166
166
  // receiver gets its own handle on the same connection, so the sender's
167
167
  // close on `NODE_HANDLE_ACK` -- which Node's `child_process.js` does the
168
- // moment the receiver confirms -- ends nothing. A handle with no pairing,
169
- // a listening server's, has nothing to duplicate and crosses as it is.
170
- const sent = handle as LibuvStreamWrap;
171
- const given = sent.peer !== null ? sent.duplicate() : sent;
168
+ // moment the receiver confirms -- ends nothing. A connection is duplicated
169
+ // whether or not its other end is still there; a listening server has no
170
+ // connection to duplicate and crosses as it is.
171
+ const sent = handle as LibuvStreamWrap & { listening?: boolean };
172
+ const given = sent.listening === true ? sent : sent.duplicate();
172
173
  // The receiving run owns this reference; the sender retains its own until
173
174
  // Node closes it on acknowledgement, or continues using it with keepOpen.
174
175
  __adoptHandle(given, ownerOf(this.peer ?? this));
package/src/runtime.ts CHANGED
@@ -142,7 +142,13 @@ function __substrateScopeGlobalCalls(code: string): string {
142
142
  catch { return code; }
143
143
  const positions: Array<[number, number, string]> = [];
144
144
  walkAst(ast, node => {
145
- if (node.type === "NewExpression" && node.callee.type === "Identifier") positions.push([node.callee.start, node.callee.end, "(__substrateGuestConstructor(" + code.slice(node.callee.start, node.callee.end) + ",$process))"]);
145
+ // A function's source is also data: a program sends `String(fn)` to be
146
+ // run elsewhere (a browser page, a worker), where the module wrapper's
147
+ // names do not exist. The rewrite is the original `new` there.
148
+ if (node.type === "NewExpression" && node.callee.type === "Identifier") {
149
+ const callee = code.slice(node.callee.start, node.callee.end);
150
+ positions.push([node.callee.start, node.callee.end, "(typeof __substrateGuestConstructor==='function'?__substrateGuestConstructor(" + callee + ",$process):" + callee + ")"]);
151
+ }
146
152
  // The narrow with-scope below keeps global replacements dynamic.
147
153
  // Remove its object receiver for ordinary calls (including local
148
154
  // bindings, whose bare-call receiver was already undefined).
@@ -1650,13 +1650,34 @@ function programExists(file: string, cwd: string | undefined, env: Record<string
1650
1650
  // what `spawn('/usr/bin/env', …)` means and what a Dockerfile's shebang
1651
1651
  // reaches. A file in the tree is a program too, and so is one on PATH.
1652
1652
  if (shellCommandNames().has(bare)) return true;
1653
- if (name.includes('/')) return existsInTree(__resolvePath(cwd ?? '/', name));
1653
+ if (name.includes('/')) {
1654
+ const path = __resolvePath(cwd ?? '/', name);
1655
+ return existsInTree(path) && !isRegisteredProgramStub(path);
1656
+ }
1654
1657
  for (const dir of (env.PATH ?? '/usr/local/bin:/usr/bin:/bin:/node_modules/.bin').split(':')) {
1655
- if (dir.length > 0 && existsInTree(`${dir}/${name}`.replace(/\/+/gu, '/'))) return true;
1658
+ const path = `${dir}/${name}`.replace(/\/+/gu, '/');
1659
+ if (dir.length > 0 && existsInTree(path) && !isRegisteredProgramStub(path)) return true;
1656
1660
  }
1657
1661
  return false;
1658
1662
  }
1659
1663
 
1664
+ /**
1665
+ * A program the page registered is not a file, so a host places a stub where
1666
+ * a loader looks for it (`#!/bin/sh` then `# <name>: runtime-registered
1667
+ * program`), for a caller that checks the path exists or walks PATH. The stub
1668
+ * is the page's program, not a script of this engine's: it is relayed to the
1669
+ * host, whose process host maps the pathname to the program by its basename.
1670
+ */
1671
+ const REGISTERED_PROGRAM_STUB = /^#!\/bin\/sh\n# [\w.+-]+: runtime-registered program\n/u;
1672
+ function isRegisteredProgramStub(path: string): boolean {
1673
+ if (!currentVfs) return false;
1674
+ try {
1675
+ const stat = currentVfs.statSync(path);
1676
+ if (!stat.isFile() || stat.size > 256) return false;
1677
+ return REGISTERED_PROGRAM_STUB.test(String(currentVfs.readFileSync(path, 'utf8')));
1678
+ } catch { return false; }
1679
+ }
1680
+
1660
1681
  /** The runs a `Process` handle started, so a later name never lands on a live one. */
1661
1682
  let __nextChildRun = 1;
1662
1683