@volter/tabnode 0.3.1 → 0.4.1
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.
- package/dist/assets/{runtime-worker-CUO9SNFs.js → runtime-worker-LWfW6VWE.js} +180 -52
- package/dist/index.d.ts +6 -0
- package/dist/index.mjs +207 -69
- package/dist/node-lib/binding/fs.d.ts +6 -6
- package/dist/node-lib/binding/process_wrap.d.ts +1 -1
- package/dist/process-tokens.d.ts +5 -0
- package/dist/server-bridge.d.ts +1 -0
- package/dist/shims/child_process.d.ts +6 -0
- package/dist/virtual-fs.d.ts +3 -0
- package/package.json +1 -1
- package/src/index.ts +6 -1
- package/src/node-lib/binding/fs.ts +41 -35
- package/src/node-lib/binding/handles.ts +27 -1
- package/src/node-lib/binding/process_wrap.ts +23 -10
- package/src/process-tokens.ts +5 -0
- package/src/server-bridge.ts +12 -2
- package/src/shims/child_process.ts +61 -4
- package/src/virtual-fs.ts +15 -1
|
@@ -6635,6 +6635,7 @@ function pidIsLive(pid) {
|
|
|
6635
6635
|
return false;
|
|
6636
6636
|
}
|
|
6637
6637
|
const owners = /* @__PURE__ */ new Map();
|
|
6638
|
+
const allOwned = /* @__PURE__ */ new Map();
|
|
6638
6639
|
const heldBy = /* @__PURE__ */ new WeakMap();
|
|
6639
6640
|
const refHeld = /* @__PURE__ */ new WeakSet();
|
|
6640
6641
|
const activeHandles = /* @__PURE__ */ new WeakSet();
|
|
@@ -6665,6 +6666,15 @@ function ownerOf(handle) {
|
|
|
6665
6666
|
}
|
|
6666
6667
|
function registerHandle(handle) {
|
|
6667
6668
|
heldBy.set(handle, currentOwner());
|
|
6669
|
+
const token = heldBy.get(handle);
|
|
6670
|
+
if (token != null) {
|
|
6671
|
+
let owned = allOwned.get(token);
|
|
6672
|
+
if (!owned) {
|
|
6673
|
+
owned = /* @__PURE__ */ new Set();
|
|
6674
|
+
allOwned.set(token, owned);
|
|
6675
|
+
}
|
|
6676
|
+
owned.add(handle);
|
|
6677
|
+
}
|
|
6668
6678
|
refHeld.add(handle);
|
|
6669
6679
|
activeHandles.add(handle);
|
|
6670
6680
|
hold(handle);
|
|
@@ -6686,6 +6696,12 @@ function handleHasRef(handle) {
|
|
|
6686
6696
|
}
|
|
6687
6697
|
function releaseHandle(handle) {
|
|
6688
6698
|
drop(handle);
|
|
6699
|
+
const token = heldBy.get(handle);
|
|
6700
|
+
if (token != null) {
|
|
6701
|
+
const owned = allOwned.get(token);
|
|
6702
|
+
owned == null ? void 0 : owned.delete(handle);
|
|
6703
|
+
if ((owned == null ? void 0 : owned.size) === 0) allOwned.delete(token);
|
|
6704
|
+
}
|
|
6689
6705
|
heldBy.delete(handle);
|
|
6690
6706
|
refHeld.delete(handle);
|
|
6691
6707
|
activeHandles.delete(handle);
|
|
@@ -6719,8 +6735,9 @@ function __releaseOwnedServers(token, stopTimers = true, stopProcess) {
|
|
|
6719
6735
|
}
|
|
6720
6736
|
}
|
|
6721
6737
|
function __releaseOwnedHandles(token) {
|
|
6722
|
-
const held =
|
|
6738
|
+
const held = allOwned.get(token);
|
|
6723
6739
|
if (!held) return;
|
|
6740
|
+
allOwned.delete(token);
|
|
6724
6741
|
owners.delete(token);
|
|
6725
6742
|
for (const handle of [...held]) {
|
|
6726
6743
|
try {
|
|
@@ -6732,7 +6749,21 @@ function __releaseOwnedHandles(token) {
|
|
|
6732
6749
|
function __adoptHandle(handle, token) {
|
|
6733
6750
|
if (!handle) return;
|
|
6734
6751
|
drop(handle);
|
|
6752
|
+
const previous = heldBy.get(handle);
|
|
6753
|
+
if (previous != null) {
|
|
6754
|
+
const owned = allOwned.get(previous);
|
|
6755
|
+
owned == null ? void 0 : owned.delete(handle);
|
|
6756
|
+
if ((owned == null ? void 0 : owned.size) === 0) allOwned.delete(previous);
|
|
6757
|
+
}
|
|
6735
6758
|
heldBy.set(handle, token);
|
|
6759
|
+
if (token !== null) {
|
|
6760
|
+
let owned = allOwned.get(token);
|
|
6761
|
+
if (!owned) {
|
|
6762
|
+
owned = /* @__PURE__ */ new Set();
|
|
6763
|
+
allOwned.set(token, owned);
|
|
6764
|
+
}
|
|
6765
|
+
owned.add(handle);
|
|
6766
|
+
}
|
|
6736
6767
|
hold(handle);
|
|
6737
6768
|
}
|
|
6738
6769
|
function ownedBytes(view) {
|
|
@@ -7444,8 +7475,12 @@ function signalNameOf(signal) {
|
|
|
7444
7475
|
if (typeof signal === "string") return signal;
|
|
7445
7476
|
return signalNames[signal] ?? "SIGTERM";
|
|
7446
7477
|
}
|
|
7447
|
-
function
|
|
7448
|
-
|
|
7478
|
+
function parentProcess(token) {
|
|
7479
|
+
var _a3;
|
|
7480
|
+
return token !== null ? (_a3 = __runFor(token)) == null ? void 0 : _a3.process : globalThis.process;
|
|
7481
|
+
}
|
|
7482
|
+
function spawningDirectory(token) {
|
|
7483
|
+
const realm = parentProcess(token);
|
|
7449
7484
|
if (typeof (realm == null ? void 0 : realm.cwd) !== "function") return void 0;
|
|
7450
7485
|
try {
|
|
7451
7486
|
return realm.cwd();
|
|
@@ -7453,9 +7488,13 @@ function spawningDirectory() {
|
|
|
7453
7488
|
return void 0;
|
|
7454
7489
|
}
|
|
7455
7490
|
}
|
|
7456
|
-
function inheritedWriter$1(fd2) {
|
|
7491
|
+
function inheritedWriter$1(fd2, token) {
|
|
7457
7492
|
if (fd2 !== 1 && fd2 !== 2) return null;
|
|
7458
|
-
|
|
7493
|
+
if (token !== null) {
|
|
7494
|
+
const parent = __runFor(token);
|
|
7495
|
+
return (fd2 === 1 ? parent == null ? void 0 : parent.stdout : parent == null ? void 0 : parent.stderr) ?? null;
|
|
7496
|
+
}
|
|
7497
|
+
const realm = parentProcess(token);
|
|
7459
7498
|
const stream = fd2 === 1 ? realm == null ? void 0 : realm.stdout : realm == null ? void 0 : realm.stderr;
|
|
7460
7499
|
if (!stream || typeof stream.write !== "function") return null;
|
|
7461
7500
|
return (text2) => {
|
|
@@ -7507,7 +7546,7 @@ class Process {
|
|
|
7507
7546
|
const request = {
|
|
7508
7547
|
file: options.file,
|
|
7509
7548
|
args: options.args ?? [options.file],
|
|
7510
|
-
cwd: options.cwd ?? spawningDirectory(),
|
|
7549
|
+
cwd: options.cwd ?? spawningDirectory(ownerOf(this)),
|
|
7511
7550
|
env,
|
|
7512
7551
|
detached: options.detached === true,
|
|
7513
7552
|
stdout: null,
|
|
@@ -7550,7 +7589,7 @@ class Process {
|
|
|
7550
7589
|
request.stderrIsPipe = true;
|
|
7551
7590
|
}
|
|
7552
7591
|
} else if (entry.type === "inherit" || entry.type === "fd") {
|
|
7553
|
-
const inherited = inheritedWriter$1(entry.fd ?? index2);
|
|
7592
|
+
const inherited = inheritedWriter$1(entry.fd ?? index2, ownerOf(this));
|
|
7554
7593
|
if (index2 === 1) request.stdout = inherited;
|
|
7555
7594
|
else request.stderr = inherited;
|
|
7556
7595
|
}
|
|
@@ -9077,7 +9116,9 @@ function refuseLinks(syscall, path2) {
|
|
|
9077
9116
|
{ code: "EPERM", errno: -1, syscall, path: path2 }
|
|
9078
9117
|
);
|
|
9079
9118
|
}
|
|
9080
|
-
|
|
9119
|
+
function unsupportedMetadata(syscall) {
|
|
9120
|
+
throw Object.assign(new Error(`ENOTSUP: filesystem does not support ${syscall}`), { code: "ENOTSUP", syscall });
|
|
9121
|
+
}
|
|
9081
9122
|
function treeHoldsLinks() {
|
|
9082
9123
|
return vfs$1().holdsLinks === true;
|
|
9083
9124
|
}
|
|
@@ -9141,19 +9182,18 @@ function fileFor(fd2) {
|
|
|
9141
9182
|
return file;
|
|
9142
9183
|
}
|
|
9143
9184
|
function statArray(stats, bigint, path2) {
|
|
9144
|
-
var _a3, _b3;
|
|
9185
|
+
var _a3, _b3, _c3;
|
|
9145
9186
|
const mtime = stats.mtime instanceof Date ? stats.mtime.getTime() : Number(stats.mtimeMs ?? 0);
|
|
9146
9187
|
const atime = stats.atime instanceof Date ? stats.atime.getTime() : Number(stats.atimeMs ?? mtime);
|
|
9147
9188
|
const ctime = stats.ctime instanceof Date ? stats.ctime.getTime() : Number(stats.ctimeMs ?? mtime);
|
|
9148
9189
|
const birth = stats.birthtime instanceof Date ? stats.birthtime.getTime() : Number(stats.birthtimeMs ?? mtime);
|
|
9149
9190
|
const seconds = (ms2) => Math.floor(ms2 / 1e3);
|
|
9150
9191
|
const nanos = (ms2) => Math.floor(ms2 % 1e3 * 1e6);
|
|
9151
|
-
const
|
|
9152
|
-
const
|
|
9153
|
-
const type2 = ((_a3 = stats.isDirectory) == null ? void 0 : _a3.call(stats)) ? S_IFDIR : ((_b3 = stats.isSymbolicLink) == null ? void 0 : _b3.call(stats)) ? S_IFLNK : S_IFREG;
|
|
9192
|
+
const permissions = Number(stats.mode ?? (((_a3 = stats.isDirectory) == null ? void 0 : _a3.call(stats)) ? 493 : 420)) & 4095;
|
|
9193
|
+
const type2 = ((_b3 = stats.isDirectory) == null ? void 0 : _b3.call(stats)) ? S_IFDIR : ((_c3 = stats.isSymbolicLink) == null ? void 0 : _c3.call(stats)) ? S_IFLNK : S_IFREG;
|
|
9154
9194
|
const values = [
|
|
9155
9195
|
Number(stats.dev ?? 0),
|
|
9156
|
-
type2 |
|
|
9196
|
+
type2 | permissions,
|
|
9157
9197
|
Number(stats.nlink ?? 1),
|
|
9158
9198
|
Number(stats.uid ?? 0),
|
|
9159
9199
|
Number(stats.gid ?? 0),
|
|
@@ -9299,15 +9339,23 @@ class FSEvent {
|
|
|
9299
9339
|
__privateAdd(this, _watcher, null);
|
|
9300
9340
|
__publicField(this, "initialized", false);
|
|
9301
9341
|
}
|
|
9302
|
-
start(path2,
|
|
9342
|
+
start(path2, persistent, recursive, _encoding2) {
|
|
9303
9343
|
const name = asPath(path2);
|
|
9304
9344
|
const tree2 = vfs$1();
|
|
9345
|
+
const cwd = callingCwd();
|
|
9346
|
+
const owner = currentOwner();
|
|
9305
9347
|
try {
|
|
9306
9348
|
__privateSet(this, _watcher, tree2.watch(name, { recursive: Boolean(recursive) }, (event, filename) => {
|
|
9307
|
-
|
|
9308
|
-
|
|
9349
|
+
const notify = () => withFilesystem(tree2, () => withCwd(cwd, () => {
|
|
9350
|
+
var _a3;
|
|
9351
|
+
return (_a3 = this.onchange) == null ? void 0 : _a3.call(this, 0, event === "rename" ? "rename" : "change", filename ?? "");
|
|
9352
|
+
}));
|
|
9353
|
+
if (owner === null) notify();
|
|
9354
|
+
else enterRun(owner, notify);
|
|
9309
9355
|
}));
|
|
9310
9356
|
this.initialized = true;
|
|
9357
|
+
registerHandle(this);
|
|
9358
|
+
if (persistent === false) unrefHandle(this);
|
|
9311
9359
|
return 0;
|
|
9312
9360
|
} catch (error) {
|
|
9313
9361
|
const code2 = error.code;
|
|
@@ -9316,6 +9364,7 @@ class FSEvent {
|
|
|
9316
9364
|
}
|
|
9317
9365
|
close() {
|
|
9318
9366
|
var _a3;
|
|
9367
|
+
releaseHandle(this);
|
|
9319
9368
|
this.initialized = false;
|
|
9320
9369
|
try {
|
|
9321
9370
|
(_a3 = __privateGet(this, _watcher)) == null ? void 0 : _a3.close();
|
|
@@ -9324,14 +9373,16 @@ class FSEvent {
|
|
|
9324
9373
|
__privateSet(this, _watcher, null);
|
|
9325
9374
|
}
|
|
9326
9375
|
ref() {
|
|
9376
|
+
if (this.initialized) refHandle(this);
|
|
9327
9377
|
}
|
|
9328
9378
|
unref() {
|
|
9379
|
+
unrefHandle(this);
|
|
9329
9380
|
}
|
|
9330
9381
|
getAsyncId() {
|
|
9331
9382
|
return 0;
|
|
9332
9383
|
}
|
|
9333
9384
|
hasRef() {
|
|
9334
|
-
return this.initialized;
|
|
9385
|
+
return this.initialized && handleHasRef(this);
|
|
9335
9386
|
}
|
|
9336
9387
|
}
|
|
9337
9388
|
_watcher = new WeakMap();
|
|
@@ -9428,6 +9479,9 @@ const fsBinding = {
|
|
|
9428
9479
|
const tree2 = vfs$1();
|
|
9429
9480
|
const bits = flagBits();
|
|
9430
9481
|
const exists = tree2.existsSync(name);
|
|
9482
|
+
if (exists && ((flags & 3) !== 0 || (flags & (bits.create | bits.truncate | bits.append)) !== 0)) {
|
|
9483
|
+
tree2.accessSync(name, 2);
|
|
9484
|
+
}
|
|
9431
9485
|
if ((flags & bits.excl) !== 0 && (flags & bits.create) !== 0 && exists) throw createNodeError$1("EEXIST", "open", name);
|
|
9432
9486
|
if (!exists) {
|
|
9433
9487
|
if ((flags & bits.create) === 0) throw createNodeError$1("ENOENT", "open", name);
|
|
@@ -9579,10 +9633,10 @@ const fsBinding = {
|
|
|
9579
9633
|
return bigint ? BigInt64Array.from(values.map((value) => BigInt(value))) : Float64Array.from(values);
|
|
9580
9634
|
});
|
|
9581
9635
|
},
|
|
9582
|
-
access(path2,
|
|
9636
|
+
access(path2, mode, req) {
|
|
9583
9637
|
return answer(req, () => {
|
|
9584
9638
|
const name = asPath(path2);
|
|
9585
|
-
|
|
9639
|
+
vfs$1().accessSync(name, mode);
|
|
9586
9640
|
return void 0;
|
|
9587
9641
|
});
|
|
9588
9642
|
},
|
|
@@ -9687,13 +9741,10 @@ const fsBinding = {
|
|
|
9687
9741
|
if (tree2.existsSync(name)) {
|
|
9688
9742
|
const stats = tree2.statSync(name);
|
|
9689
9743
|
if (!recursive || !stats.isDirectory()) throw createNodeError$1("EEXIST", "mkdir", name);
|
|
9690
|
-
const stored = pathModes.get(name);
|
|
9691
|
-
if (stored !== void 0 && (stored & 511) !== wanted) throw createNodeError$1("EEXIST", "mkdir", name);
|
|
9692
|
-
pathModes.set(name, wanted);
|
|
9693
9744
|
return void 0;
|
|
9694
9745
|
}
|
|
9695
9746
|
tree2.mkdirSync(name, { recursive });
|
|
9696
|
-
|
|
9747
|
+
tree2.chmodSync(name, wanted);
|
|
9697
9748
|
return void 0;
|
|
9698
9749
|
});
|
|
9699
9750
|
},
|
|
@@ -9765,46 +9816,50 @@ const fsBinding = {
|
|
|
9765
9816
|
}
|
|
9766
9817
|
});
|
|
9767
9818
|
},
|
|
9768
|
-
//
|
|
9769
|
-
//
|
|
9770
|
-
// are kept here, because a program that sets a mode and stats it back must
|
|
9771
|
-
// see what it set, and a missing path is ENOENT as Node's is.
|
|
9819
|
+
// Metadata belongs to the filesystem, including a host's permission view.
|
|
9820
|
+
// Never keep a realm-global mode table or bypass that view for descriptors.
|
|
9772
9821
|
chmod(path2, mode, req) {
|
|
9773
9822
|
return answer(req, () => {
|
|
9774
9823
|
const name = asPath(path2);
|
|
9775
|
-
|
|
9776
|
-
pathModes.set(name, mode & 4095);
|
|
9824
|
+
vfs$1().chmodSync(name, mode);
|
|
9777
9825
|
return void 0;
|
|
9778
9826
|
});
|
|
9779
9827
|
},
|
|
9780
9828
|
fchmod(fd2, mode, req) {
|
|
9781
9829
|
return answer(req, () => {
|
|
9782
9830
|
const file = fileFor(fd2);
|
|
9783
|
-
|
|
9831
|
+
file.tree.chmodSync(file.path, mode);
|
|
9784
9832
|
return void 0;
|
|
9785
9833
|
});
|
|
9786
9834
|
},
|
|
9787
|
-
chown(
|
|
9788
|
-
return answer(req, () =>
|
|
9789
|
-
const name = asPath(path2);
|
|
9790
|
-
if (!vfs$1().existsSync(name)) throw createNodeError$1("ENOENT", "chown", name);
|
|
9791
|
-
return void 0;
|
|
9792
|
-
});
|
|
9835
|
+
chown(_path, _uid, _gid, req) {
|
|
9836
|
+
return answer(req, () => unsupportedMetadata("chown"));
|
|
9793
9837
|
},
|
|
9794
9838
|
fchown(_fd, _uid, _gid, req) {
|
|
9795
|
-
return answer(req, () =>
|
|
9839
|
+
return answer(req, () => unsupportedMetadata("fchown"));
|
|
9796
9840
|
},
|
|
9797
9841
|
lchown(_path, _uid, _gid, req) {
|
|
9798
|
-
return answer(req, () =>
|
|
9842
|
+
return answer(req, () => unsupportedMetadata("lchown"));
|
|
9799
9843
|
},
|
|
9800
|
-
utimes(
|
|
9801
|
-
return answer(req, () =>
|
|
9844
|
+
utimes(path2, atime, mtime, req) {
|
|
9845
|
+
return answer(req, () => {
|
|
9846
|
+
vfs$1().utimesSync(asPath(path2), new Date(atime * 1e3), new Date(mtime * 1e3));
|
|
9847
|
+
return void 0;
|
|
9848
|
+
});
|
|
9802
9849
|
},
|
|
9803
|
-
futimes(
|
|
9804
|
-
return answer(req, () =>
|
|
9850
|
+
futimes(fd2, atime, mtime, req) {
|
|
9851
|
+
return answer(req, () => {
|
|
9852
|
+
const file = fileFor(fd2);
|
|
9853
|
+
file.tree.utimesSync(file.path, new Date(atime * 1e3), new Date(mtime * 1e3));
|
|
9854
|
+
return void 0;
|
|
9855
|
+
});
|
|
9805
9856
|
},
|
|
9806
|
-
lutimes(
|
|
9807
|
-
return answer(req, () =>
|
|
9857
|
+
lutimes(path2, atime, mtime, req) {
|
|
9858
|
+
return answer(req, () => {
|
|
9859
|
+
if (treeHoldsLinks()) return unsupportedMetadata("lutimes");
|
|
9860
|
+
vfs$1().utimesSync(asPath(path2), new Date(atime * 1e3), new Date(mtime * 1e3));
|
|
9861
|
+
return void 0;
|
|
9862
|
+
});
|
|
9808
9863
|
},
|
|
9809
9864
|
fsync(_fd, req) {
|
|
9810
9865
|
return answer(req, () => void 0);
|
|
@@ -26407,6 +26462,17 @@ class VirtualFS {
|
|
|
26407
26462
|
/**
|
|
26408
26463
|
* Get stats for path
|
|
26409
26464
|
*/
|
|
26465
|
+
chmodSync(path2, mode) {
|
|
26466
|
+
const node = this.getNode(path2);
|
|
26467
|
+
if (!node) throw createNodeError("ENOENT", "chmod", path2);
|
|
26468
|
+
node.mode = mode & 4095;
|
|
26469
|
+
}
|
|
26470
|
+
utimesSync(path2, atime, mtime) {
|
|
26471
|
+
const node = this.getNode(path2);
|
|
26472
|
+
if (!node) throw createNodeError("ENOENT", "utimes", path2);
|
|
26473
|
+
node.atime = atime instanceof Date ? atime.getTime() : atime * 1e3;
|
|
26474
|
+
node.mtime = mtime instanceof Date ? mtime.getTime() : mtime * 1e3;
|
|
26475
|
+
}
|
|
26410
26476
|
statSync(path2) {
|
|
26411
26477
|
var _a3;
|
|
26412
26478
|
const node = this.getNode(path2);
|
|
@@ -26425,7 +26491,7 @@ class VirtualFS {
|
|
|
26425
26491
|
isFIFO: () => false,
|
|
26426
26492
|
isSocket: () => false,
|
|
26427
26493
|
size,
|
|
26428
|
-
mode: node.type === "directory" ? 493 : 420,
|
|
26494
|
+
mode: node.mode ?? (node.type === "directory" ? 493 : 420),
|
|
26429
26495
|
mtime: new Date(mtime),
|
|
26430
26496
|
atime: new Date(atime),
|
|
26431
26497
|
ctime: new Date(mtime),
|
|
@@ -68772,7 +68838,7 @@ function initChildProcess(vfs2) {
|
|
|
68772
68838
|
};
|
|
68773
68839
|
};
|
|
68774
68840
|
const nodeCommand = uA("node", async (args, ctx) => {
|
|
68775
|
-
var _a3, _b3;
|
|
68841
|
+
var _a3, _b3, _c3, _d3;
|
|
68776
68842
|
if (!tree2) {
|
|
68777
68843
|
return { stdout: "", stderr: "VFS not initialized\n", exitCode: 1 };
|
|
68778
68844
|
}
|
|
@@ -68859,7 +68925,7 @@ function initChildProcess(vfs2) {
|
|
|
68859
68925
|
// open, as a pipe whose writer has not closed.
|
|
68860
68926
|
stdin: typeof ctx.stdin === "string" ? ctx.stdin : "",
|
|
68861
68927
|
...(streams == null ? void 0 : streams.held) || (streams == null ? void 0 : streams.stdinOpen) ? { stdinHeld: true } : {},
|
|
68862
|
-
...(streams == null ? void 0 : streams.held) ? { tty: true } : {},
|
|
68928
|
+
...(streams == null ? void 0 : streams.held) || (streams == null ? void 0 : streams.terminal) ? { tty: true } : {},
|
|
68863
68929
|
// The numbers this run was started with, so the guest's `process.pid`
|
|
68864
68930
|
// is the one its parent's handle carries.
|
|
68865
68931
|
...runPid(runToken) ? { pid: runPid(runToken).pid, ppid: runPid(runToken).ppid } : {}
|
|
@@ -68867,6 +68933,9 @@ function initChildProcess(vfs2) {
|
|
|
68867
68933
|
const proc = runtime2.getProcess();
|
|
68868
68934
|
if (runToken !== null) setRunPid(runToken, proc.pid, proc.ppid);
|
|
68869
68935
|
const releaseRun = runToken === null ? null : __recordRun(runToken, {
|
|
68936
|
+
process: proc,
|
|
68937
|
+
stdout: appendStdout,
|
|
68938
|
+
stderr: appendStderr,
|
|
68870
68939
|
pendingTimers: () => pendingGuestTimers(proc),
|
|
68871
68940
|
stopTimers: () => stopGuestTimers(proc),
|
|
68872
68941
|
reportUncaught: (error) => __reportUncaughtException(proc, error)
|
|
@@ -68901,12 +68970,28 @@ function initChildProcess(vfs2) {
|
|
|
68901
68970
|
proc.argv0 = "node";
|
|
68902
68971
|
proc.execArgv = execArgv;
|
|
68903
68972
|
if (streams) streams.stdin = proc.stdin;
|
|
68904
|
-
if (streams == null ? void 0 : streams.held) {
|
|
68973
|
+
if ((streams == null ? void 0 : streams.held) || (streams == null ? void 0 : streams.terminal)) {
|
|
68905
68974
|
proc.stdout.isTTY = true;
|
|
68906
68975
|
proc.stderr.isTTY = true;
|
|
68907
68976
|
proc.stdin.isTTY = true;
|
|
68908
68977
|
proc.stdin.setRawMode = () => proc.stdin;
|
|
68909
68978
|
}
|
|
68979
|
+
const terminal = streams == null ? void 0 : streams.terminal;
|
|
68980
|
+
const resize = (columns, rows) => {
|
|
68981
|
+
for (const stream of [proc.stdout, proc.stderr]) {
|
|
68982
|
+
stream.columns = columns;
|
|
68983
|
+
stream.rows = rows;
|
|
68984
|
+
stream.emit("resize");
|
|
68985
|
+
}
|
|
68986
|
+
};
|
|
68987
|
+
let stopResize;
|
|
68988
|
+
let inputActive = true;
|
|
68989
|
+
let inputIterator;
|
|
68990
|
+
const readableInput = proc.stdin;
|
|
68991
|
+
const inputReading = () => {
|
|
68992
|
+
var _a4, _b4;
|
|
68993
|
+
return readableInput.readableFlowing === true || ((_a4 = readableInput._readableState) == null ? void 0 : _a4.reading) === true || ((_b4 = readableInput._readableState) == null ? void 0 : _b4.needReadable) === true || readableInput.listenerCount("data") > 0 || readableInput.listenerCount("readable") > 0;
|
|
68994
|
+
};
|
|
68910
68995
|
if (Number.isInteger(channelFd) && channelFd >= 0 && runToken !== null) {
|
|
68911
68996
|
enterRun(runToken, () => {
|
|
68912
68997
|
attachChannel(proc, channelFd, channelSerialization);
|
|
@@ -68964,6 +69049,39 @@ ${reason.stack || ""}` : String(reason);
|
|
|
68964
69049
|
};
|
|
68965
69050
|
const detachUncaught = __onUncaughtException(proc, onUncaughtException);
|
|
68966
69051
|
try {
|
|
69052
|
+
if (streams == null ? void 0 : streams.stdinStream) {
|
|
69053
|
+
inputIterator = streams.stdinStream[Symbol.asyncIterator]();
|
|
69054
|
+
const input = inputIterator;
|
|
69055
|
+
void (async () => {
|
|
69056
|
+
var _a4, _b4, _c4, _d4, _e3;
|
|
69057
|
+
const push = (chunk) => {
|
|
69058
|
+
if (runToken === null) proc.stdin.push(chunk);
|
|
69059
|
+
else enterRun(runToken, () => proc.stdin.push(chunk));
|
|
69060
|
+
};
|
|
69061
|
+
try {
|
|
69062
|
+
while (inputActive && !((_a4 = streams.signal) == null ? void 0 : _a4.aborted)) {
|
|
69063
|
+
while (inputActive && !((_b4 = streams.signal) == null ? void 0 : _b4.aborted) && (!inputReading() || readableInput.readableLength >= readableInput.readableHighWaterMark)) {
|
|
69064
|
+
await new Promise((resolve2) => (globalThis.__browserRuntimeNativeSetTimeout ?? setTimeout).call(globalThis, resolve2, 10));
|
|
69065
|
+
}
|
|
69066
|
+
if (!inputActive || ((_c4 = streams.signal) == null ? void 0 : _c4.aborted)) break;
|
|
69067
|
+
const next2 = await input.next();
|
|
69068
|
+
if (next2.done) break;
|
|
69069
|
+
if (!inputActive || ((_d4 = streams.signal) == null ? void 0 : _d4.aborted)) break;
|
|
69070
|
+
push(next2.value);
|
|
69071
|
+
}
|
|
69072
|
+
if (inputActive && !((_e3 = streams.signal) == null ? void 0 : _e3.aborted)) push(null);
|
|
69073
|
+
} catch (error) {
|
|
69074
|
+
if (inputActive) onUncaughtException(error);
|
|
69075
|
+
} finally {
|
|
69076
|
+
streams.stdinOpen = false;
|
|
69077
|
+
}
|
|
69078
|
+
})();
|
|
69079
|
+
}
|
|
69080
|
+
if (terminal) resize(terminal.columns, terminal.rows);
|
|
69081
|
+
stopResize = (_a3 = terminal == null ? void 0 : terminal.onResize) == null ? void 0 : _a3.call(terminal, (columns, rows) => {
|
|
69082
|
+
if (runToken === null) resize(columns, rows);
|
|
69083
|
+
else enterRun(runToken, () => resize(columns, rows));
|
|
69084
|
+
});
|
|
68967
69085
|
let entrySettling;
|
|
68968
69086
|
try {
|
|
68969
69087
|
const runEntry = () => runtime2.runFile(resolvedPath);
|
|
@@ -69001,7 +69119,7 @@ ${error.stack || ""}` : String(error);
|
|
|
69001
69119
|
}
|
|
69002
69120
|
}
|
|
69003
69121
|
const __ownsHandles = () => runToken !== null && (__ownedServerPorts(runToken).length > 0 || __ownedHandleCount(runToken) > 0);
|
|
69004
|
-
const __printedThenWorking = () => pendingGuestTimers(proc) > 0 || heldWork().count > 0 || __ownsHandles();
|
|
69122
|
+
const __printedThenWorking = () => (streams == null ? void 0 : streams.stdinOpen) === true && inputReading() || pendingGuestTimers(proc) > 0 || heldWork().count > 0 || __ownsHandles();
|
|
69005
69123
|
if ((stdout.length > 0 || stderr.length > 0) && !__printedThenWorking()) {
|
|
69006
69124
|
await new Promise((r10) => (globalThis.__browserRuntimeNativeSetTimeout ?? setTimeout).call(globalThis, r10, 0));
|
|
69007
69125
|
if (exitCalled) return { stdout, stderr, exitCode };
|
|
@@ -69024,16 +69142,16 @@ ${error.stack || ""}` : String(error);
|
|
|
69024
69142
|
const startTime = Date.now();
|
|
69025
69143
|
let lastOutputLen = stdout.length + stderr.length;
|
|
69026
69144
|
let idleMs = 0;
|
|
69027
|
-
const stillWorking = () => pendingGuestTimers(proc) > 0 || __ownsHandles();
|
|
69145
|
+
const stillWorking = () => (streams == null ? void 0 : streams.stdinOpen) === true && inputReading() || pendingGuestTimers(proc) > 0 || __ownsHandles();
|
|
69028
69146
|
const isLongRunning = !!(streams == null ? void 0 : streams.held);
|
|
69029
69147
|
while (!exitCalled) {
|
|
69030
|
-
if ((
|
|
69148
|
+
if ((_b3 = streams == null ? void 0 : streams.signal) == null ? void 0 : _b3.aborted) break;
|
|
69031
69149
|
const raceResult = await Promise.race([
|
|
69032
69150
|
exitPromise.then(() => "exit"),
|
|
69033
69151
|
new Promise((r10) => (globalThis.__browserRuntimeNativeSetTimeout ?? setTimeout).call(globalThis, () => r10("tick"), CHECK_MS))
|
|
69034
69152
|
]);
|
|
69035
69153
|
if (raceResult === "exit" || exitCalled) break;
|
|
69036
|
-
if ((
|
|
69154
|
+
if ((_c3 = streams == null ? void 0 : streams.signal) == null ? void 0 : _c3.aborted) break;
|
|
69037
69155
|
const currentLen = stdout.length + stderr.length;
|
|
69038
69156
|
if (currentLen > lastOutputLen) {
|
|
69039
69157
|
lastOutputLen = currentLen;
|
|
@@ -69058,6 +69176,16 @@ ${error.stack || ""}` : String(error);
|
|
|
69058
69176
|
} finally {
|
|
69059
69177
|
detachRejections();
|
|
69060
69178
|
detachUncaught();
|
|
69179
|
+
inputActive = false;
|
|
69180
|
+
try {
|
|
69181
|
+
void Promise.resolve((_d3 = inputIterator == null ? void 0 : inputIterator.return) == null ? void 0 : _d3.call(inputIterator)).catch(() => {
|
|
69182
|
+
});
|
|
69183
|
+
} catch {
|
|
69184
|
+
}
|
|
69185
|
+
try {
|
|
69186
|
+
stopResize == null ? void 0 : stopResize();
|
|
69187
|
+
} catch {
|
|
69188
|
+
}
|
|
69061
69189
|
if (runToken !== null) {
|
|
69062
69190
|
__releaseOwnedServers(runToken, false);
|
|
69063
69191
|
__releaseOwnedHandles(runToken);
|
package/dist/index.d.ts
CHANGED
|
@@ -55,6 +55,12 @@ export interface RunOptions {
|
|
|
55
55
|
env?: Record<string, string>;
|
|
56
56
|
/** What the shell reads on stdin, so a builtin reads what was piped to it. */
|
|
57
57
|
stdin?: string;
|
|
58
|
+
stdinStream?: AsyncIterable<Uint8Array>;
|
|
59
|
+
terminal?: {
|
|
60
|
+
columns: number;
|
|
61
|
+
rows: number;
|
|
62
|
+
onResize?: (listener: (columns: number, rows: number) => void) => () => void;
|
|
63
|
+
};
|
|
58
64
|
/** Callback for streaming stdout chunks as they arrive (for long-running commands like vitest watch) */
|
|
59
65
|
onStdout?: (data: string) => void;
|
|
60
66
|
/** Callback for streaming stderr chunks as they arrive */
|