@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
package/dist/index.mjs
CHANGED
|
@@ -6344,6 +6344,7 @@ function processByPid(pid) {
|
|
|
6344
6344
|
return void 0;
|
|
6345
6345
|
}
|
|
6346
6346
|
const owners = /* @__PURE__ */ new Map();
|
|
6347
|
+
const allOwned = /* @__PURE__ */ new Map();
|
|
6347
6348
|
const heldBy = /* @__PURE__ */ new WeakMap();
|
|
6348
6349
|
const refHeld = /* @__PURE__ */ new WeakSet();
|
|
6349
6350
|
const activeHandles = /* @__PURE__ */ new WeakSet();
|
|
@@ -6374,6 +6375,15 @@ function ownerOf(handle) {
|
|
|
6374
6375
|
}
|
|
6375
6376
|
function registerHandle(handle) {
|
|
6376
6377
|
heldBy.set(handle, currentOwner());
|
|
6378
|
+
const token = heldBy.get(handle);
|
|
6379
|
+
if (token != null) {
|
|
6380
|
+
let owned = allOwned.get(token);
|
|
6381
|
+
if (!owned) {
|
|
6382
|
+
owned = /* @__PURE__ */ new Set();
|
|
6383
|
+
allOwned.set(token, owned);
|
|
6384
|
+
}
|
|
6385
|
+
owned.add(handle);
|
|
6386
|
+
}
|
|
6377
6387
|
refHeld.add(handle);
|
|
6378
6388
|
activeHandles.add(handle);
|
|
6379
6389
|
hold(handle);
|
|
@@ -6395,6 +6405,12 @@ function handleHasRef(handle) {
|
|
|
6395
6405
|
}
|
|
6396
6406
|
function releaseHandle(handle) {
|
|
6397
6407
|
drop(handle);
|
|
6408
|
+
const token = heldBy.get(handle);
|
|
6409
|
+
if (token != null) {
|
|
6410
|
+
const owned = allOwned.get(token);
|
|
6411
|
+
owned == null ? void 0 : owned.delete(handle);
|
|
6412
|
+
if ((owned == null ? void 0 : owned.size) === 0) allOwned.delete(token);
|
|
6413
|
+
}
|
|
6398
6414
|
heldBy.delete(handle);
|
|
6399
6415
|
refHeld.delete(handle);
|
|
6400
6416
|
activeHandles.delete(handle);
|
|
@@ -6428,8 +6444,9 @@ function __releaseOwnedServers(token, stopTimers = true, stopProcess) {
|
|
|
6428
6444
|
}
|
|
6429
6445
|
}
|
|
6430
6446
|
function __releaseOwnedHandles(token) {
|
|
6431
|
-
const held =
|
|
6447
|
+
const held = allOwned.get(token);
|
|
6432
6448
|
if (!held) return;
|
|
6449
|
+
allOwned.delete(token);
|
|
6433
6450
|
owners.delete(token);
|
|
6434
6451
|
for (const handle of [...held]) {
|
|
6435
6452
|
try {
|
|
@@ -6441,7 +6458,21 @@ function __releaseOwnedHandles(token) {
|
|
|
6441
6458
|
function __adoptHandle(handle, token) {
|
|
6442
6459
|
if (!handle) return;
|
|
6443
6460
|
drop(handle);
|
|
6461
|
+
const previous = heldBy.get(handle);
|
|
6462
|
+
if (previous != null) {
|
|
6463
|
+
const owned = allOwned.get(previous);
|
|
6464
|
+
owned == null ? void 0 : owned.delete(handle);
|
|
6465
|
+
if ((owned == null ? void 0 : owned.size) === 0) allOwned.delete(previous);
|
|
6466
|
+
}
|
|
6444
6467
|
heldBy.set(handle, token);
|
|
6468
|
+
if (token !== null) {
|
|
6469
|
+
let owned = allOwned.get(token);
|
|
6470
|
+
if (!owned) {
|
|
6471
|
+
owned = /* @__PURE__ */ new Set();
|
|
6472
|
+
allOwned.set(token, owned);
|
|
6473
|
+
}
|
|
6474
|
+
owned.add(handle);
|
|
6475
|
+
}
|
|
6445
6476
|
hold(handle);
|
|
6446
6477
|
}
|
|
6447
6478
|
function ownedBytes$1(view) {
|
|
@@ -7157,8 +7188,12 @@ function signalNameOf(signal) {
|
|
|
7157
7188
|
if (typeof signal === "string") return signal;
|
|
7158
7189
|
return signalNames[signal] ?? "SIGTERM";
|
|
7159
7190
|
}
|
|
7160
|
-
function
|
|
7161
|
-
|
|
7191
|
+
function parentProcess(token) {
|
|
7192
|
+
var _a2;
|
|
7193
|
+
return token !== null ? (_a2 = __runFor(token)) == null ? void 0 : _a2.process : globalThis.process;
|
|
7194
|
+
}
|
|
7195
|
+
function spawningDirectory(token) {
|
|
7196
|
+
const realm = parentProcess(token);
|
|
7162
7197
|
if (typeof (realm == null ? void 0 : realm.cwd) !== "function") return void 0;
|
|
7163
7198
|
try {
|
|
7164
7199
|
return realm.cwd();
|
|
@@ -7166,9 +7201,13 @@ function spawningDirectory() {
|
|
|
7166
7201
|
return void 0;
|
|
7167
7202
|
}
|
|
7168
7203
|
}
|
|
7169
|
-
function inheritedWriter$1(fd) {
|
|
7204
|
+
function inheritedWriter$1(fd, token) {
|
|
7170
7205
|
if (fd !== 1 && fd !== 2) return null;
|
|
7171
|
-
|
|
7206
|
+
if (token !== null) {
|
|
7207
|
+
const parent = __runFor(token);
|
|
7208
|
+
return (fd === 1 ? parent == null ? void 0 : parent.stdout : parent == null ? void 0 : parent.stderr) ?? null;
|
|
7209
|
+
}
|
|
7210
|
+
const realm = parentProcess(token);
|
|
7172
7211
|
const stream = fd === 1 ? realm == null ? void 0 : realm.stdout : realm == null ? void 0 : realm.stderr;
|
|
7173
7212
|
if (!stream || typeof stream.write !== "function") return null;
|
|
7174
7213
|
return (text2) => {
|
|
@@ -7220,7 +7259,7 @@ class Process {
|
|
|
7220
7259
|
const request = {
|
|
7221
7260
|
file: options.file,
|
|
7222
7261
|
args: options.args ?? [options.file],
|
|
7223
|
-
cwd: options.cwd ?? spawningDirectory(),
|
|
7262
|
+
cwd: options.cwd ?? spawningDirectory(ownerOf(this)),
|
|
7224
7263
|
env,
|
|
7225
7264
|
detached: options.detached === true,
|
|
7226
7265
|
stdout: null,
|
|
@@ -7263,7 +7302,7 @@ class Process {
|
|
|
7263
7302
|
request.stderrIsPipe = true;
|
|
7264
7303
|
}
|
|
7265
7304
|
} else if (entry.type === "inherit" || entry.type === "fd") {
|
|
7266
|
-
const inherited = inheritedWriter$1(entry.fd ?? index2);
|
|
7305
|
+
const inherited = inheritedWriter$1(entry.fd ?? index2, ownerOf(this));
|
|
7267
7306
|
if (index2 === 1) request.stdout = inherited;
|
|
7268
7307
|
else request.stderr = inherited;
|
|
7269
7308
|
}
|
|
@@ -8790,7 +8829,9 @@ function refuseLinks(syscall, path2) {
|
|
|
8790
8829
|
{ code: "EPERM", errno: -1, syscall, path: path2 }
|
|
8791
8830
|
);
|
|
8792
8831
|
}
|
|
8793
|
-
|
|
8832
|
+
function unsupportedMetadata(syscall) {
|
|
8833
|
+
throw Object.assign(new Error(`ENOTSUP: filesystem does not support ${syscall}`), { code: "ENOTSUP", syscall });
|
|
8834
|
+
}
|
|
8794
8835
|
function treeHoldsLinks() {
|
|
8795
8836
|
return vfs().holdsLinks === true;
|
|
8796
8837
|
}
|
|
@@ -8854,19 +8895,18 @@ function fileFor(fd) {
|
|
|
8854
8895
|
return file;
|
|
8855
8896
|
}
|
|
8856
8897
|
function statArray(stats, bigint, path2) {
|
|
8857
|
-
var _a2, _b2;
|
|
8898
|
+
var _a2, _b2, _c2;
|
|
8858
8899
|
const mtime = stats.mtime instanceof Date ? stats.mtime.getTime() : Number(stats.mtimeMs ?? 0);
|
|
8859
8900
|
const atime = stats.atime instanceof Date ? stats.atime.getTime() : Number(stats.atimeMs ?? mtime);
|
|
8860
8901
|
const ctime = stats.ctime instanceof Date ? stats.ctime.getTime() : Number(stats.ctimeMs ?? mtime);
|
|
8861
8902
|
const birth = stats.birthtime instanceof Date ? stats.birthtime.getTime() : Number(stats.birthtimeMs ?? mtime);
|
|
8862
8903
|
const seconds = (ms) => Math.floor(ms / 1e3);
|
|
8863
8904
|
const nanos = (ms) => Math.floor(ms % 1e3 * 1e6);
|
|
8864
|
-
const
|
|
8865
|
-
const
|
|
8866
|
-
const type2 = ((_a2 = stats.isDirectory) == null ? void 0 : _a2.call(stats)) ? S_IFDIR : ((_b2 = stats.isSymbolicLink) == null ? void 0 : _b2.call(stats)) ? S_IFLNK : S_IFREG;
|
|
8905
|
+
const permissions = Number(stats.mode ?? (((_a2 = stats.isDirectory) == null ? void 0 : _a2.call(stats)) ? 493 : 420)) & 4095;
|
|
8906
|
+
const type2 = ((_b2 = stats.isDirectory) == null ? void 0 : _b2.call(stats)) ? S_IFDIR : ((_c2 = stats.isSymbolicLink) == null ? void 0 : _c2.call(stats)) ? S_IFLNK : S_IFREG;
|
|
8867
8907
|
const values = [
|
|
8868
8908
|
Number(stats.dev ?? 0),
|
|
8869
|
-
type2 |
|
|
8909
|
+
type2 | permissions,
|
|
8870
8910
|
Number(stats.nlink ?? 1),
|
|
8871
8911
|
Number(stats.uid ?? 0),
|
|
8872
8912
|
Number(stats.gid ?? 0),
|
|
@@ -9012,15 +9052,23 @@ class FSEvent {
|
|
|
9012
9052
|
__privateAdd(this, _watcher, null);
|
|
9013
9053
|
__publicField(this, "initialized", false);
|
|
9014
9054
|
}
|
|
9015
|
-
start(path2,
|
|
9055
|
+
start(path2, persistent, recursive, _encoding2) {
|
|
9016
9056
|
const name = asPath(path2);
|
|
9017
9057
|
const tree2 = vfs();
|
|
9058
|
+
const cwd = callingCwd();
|
|
9059
|
+
const owner = currentOwner();
|
|
9018
9060
|
try {
|
|
9019
9061
|
__privateSet(this, _watcher, tree2.watch(name, { recursive: Boolean(recursive) }, (event, filename) => {
|
|
9020
|
-
|
|
9021
|
-
|
|
9062
|
+
const notify = () => withFilesystem(tree2, () => withCwd(cwd, () => {
|
|
9063
|
+
var _a2;
|
|
9064
|
+
return (_a2 = this.onchange) == null ? void 0 : _a2.call(this, 0, event === "rename" ? "rename" : "change", filename ?? "");
|
|
9065
|
+
}));
|
|
9066
|
+
if (owner === null) notify();
|
|
9067
|
+
else enterRun(owner, notify);
|
|
9022
9068
|
}));
|
|
9023
9069
|
this.initialized = true;
|
|
9070
|
+
registerHandle(this);
|
|
9071
|
+
if (persistent === false) unrefHandle(this);
|
|
9024
9072
|
return 0;
|
|
9025
9073
|
} catch (error) {
|
|
9026
9074
|
const code2 = error.code;
|
|
@@ -9029,6 +9077,7 @@ class FSEvent {
|
|
|
9029
9077
|
}
|
|
9030
9078
|
close() {
|
|
9031
9079
|
var _a2;
|
|
9080
|
+
releaseHandle(this);
|
|
9032
9081
|
this.initialized = false;
|
|
9033
9082
|
try {
|
|
9034
9083
|
(_a2 = __privateGet(this, _watcher)) == null ? void 0 : _a2.close();
|
|
@@ -9037,14 +9086,16 @@ class FSEvent {
|
|
|
9037
9086
|
__privateSet(this, _watcher, null);
|
|
9038
9087
|
}
|
|
9039
9088
|
ref() {
|
|
9089
|
+
if (this.initialized) refHandle(this);
|
|
9040
9090
|
}
|
|
9041
9091
|
unref() {
|
|
9092
|
+
unrefHandle(this);
|
|
9042
9093
|
}
|
|
9043
9094
|
getAsyncId() {
|
|
9044
9095
|
return 0;
|
|
9045
9096
|
}
|
|
9046
9097
|
hasRef() {
|
|
9047
|
-
return this.initialized;
|
|
9098
|
+
return this.initialized && handleHasRef(this);
|
|
9048
9099
|
}
|
|
9049
9100
|
}
|
|
9050
9101
|
_watcher = new WeakMap();
|
|
@@ -9141,6 +9192,9 @@ const fsBinding = {
|
|
|
9141
9192
|
const tree2 = vfs();
|
|
9142
9193
|
const bits = flagBits();
|
|
9143
9194
|
const exists = tree2.existsSync(name);
|
|
9195
|
+
if (exists && ((flags & 3) !== 0 || (flags & (bits.create | bits.truncate | bits.append)) !== 0)) {
|
|
9196
|
+
tree2.accessSync(name, 2);
|
|
9197
|
+
}
|
|
9144
9198
|
if ((flags & bits.excl) !== 0 && (flags & bits.create) !== 0 && exists) throw createNodeError$1("EEXIST", "open", name);
|
|
9145
9199
|
if (!exists) {
|
|
9146
9200
|
if ((flags & bits.create) === 0) throw createNodeError$1("ENOENT", "open", name);
|
|
@@ -9292,10 +9346,10 @@ const fsBinding = {
|
|
|
9292
9346
|
return bigint ? BigInt64Array.from(values.map((value) => BigInt(value))) : Float64Array.from(values);
|
|
9293
9347
|
});
|
|
9294
9348
|
},
|
|
9295
|
-
access(path2,
|
|
9349
|
+
access(path2, mode, req) {
|
|
9296
9350
|
return answer(req, () => {
|
|
9297
9351
|
const name = asPath(path2);
|
|
9298
|
-
|
|
9352
|
+
vfs().accessSync(name, mode);
|
|
9299
9353
|
return void 0;
|
|
9300
9354
|
});
|
|
9301
9355
|
},
|
|
@@ -9400,13 +9454,10 @@ const fsBinding = {
|
|
|
9400
9454
|
if (tree2.existsSync(name)) {
|
|
9401
9455
|
const stats = tree2.statSync(name);
|
|
9402
9456
|
if (!recursive || !stats.isDirectory()) throw createNodeError$1("EEXIST", "mkdir", name);
|
|
9403
|
-
const stored = pathModes.get(name);
|
|
9404
|
-
if (stored !== void 0 && (stored & 511) !== wanted) throw createNodeError$1("EEXIST", "mkdir", name);
|
|
9405
|
-
pathModes.set(name, wanted);
|
|
9406
9457
|
return void 0;
|
|
9407
9458
|
}
|
|
9408
9459
|
tree2.mkdirSync(name, { recursive });
|
|
9409
|
-
|
|
9460
|
+
tree2.chmodSync(name, wanted);
|
|
9410
9461
|
return void 0;
|
|
9411
9462
|
});
|
|
9412
9463
|
},
|
|
@@ -9478,46 +9529,50 @@ const fsBinding = {
|
|
|
9478
9529
|
}
|
|
9479
9530
|
});
|
|
9480
9531
|
},
|
|
9481
|
-
//
|
|
9482
|
-
//
|
|
9483
|
-
// are kept here, because a program that sets a mode and stats it back must
|
|
9484
|
-
// see what it set, and a missing path is ENOENT as Node's is.
|
|
9532
|
+
// Metadata belongs to the filesystem, including a host's permission view.
|
|
9533
|
+
// Never keep a realm-global mode table or bypass that view for descriptors.
|
|
9485
9534
|
chmod(path2, mode, req) {
|
|
9486
9535
|
return answer(req, () => {
|
|
9487
9536
|
const name = asPath(path2);
|
|
9488
|
-
|
|
9489
|
-
pathModes.set(name, mode & 4095);
|
|
9537
|
+
vfs().chmodSync(name, mode);
|
|
9490
9538
|
return void 0;
|
|
9491
9539
|
});
|
|
9492
9540
|
},
|
|
9493
9541
|
fchmod(fd, mode, req) {
|
|
9494
9542
|
return answer(req, () => {
|
|
9495
9543
|
const file = fileFor(fd);
|
|
9496
|
-
|
|
9544
|
+
file.tree.chmodSync(file.path, mode);
|
|
9497
9545
|
return void 0;
|
|
9498
9546
|
});
|
|
9499
9547
|
},
|
|
9500
|
-
chown(
|
|
9501
|
-
return answer(req, () =>
|
|
9502
|
-
const name = asPath(path2);
|
|
9503
|
-
if (!vfs().existsSync(name)) throw createNodeError$1("ENOENT", "chown", name);
|
|
9504
|
-
return void 0;
|
|
9505
|
-
});
|
|
9548
|
+
chown(_path, _uid, _gid, req) {
|
|
9549
|
+
return answer(req, () => unsupportedMetadata("chown"));
|
|
9506
9550
|
},
|
|
9507
9551
|
fchown(_fd, _uid, _gid, req) {
|
|
9508
|
-
return answer(req, () =>
|
|
9552
|
+
return answer(req, () => unsupportedMetadata("fchown"));
|
|
9509
9553
|
},
|
|
9510
9554
|
lchown(_path, _uid, _gid, req) {
|
|
9511
|
-
return answer(req, () =>
|
|
9555
|
+
return answer(req, () => unsupportedMetadata("lchown"));
|
|
9512
9556
|
},
|
|
9513
|
-
utimes(
|
|
9514
|
-
return answer(req, () =>
|
|
9557
|
+
utimes(path2, atime, mtime, req) {
|
|
9558
|
+
return answer(req, () => {
|
|
9559
|
+
vfs().utimesSync(asPath(path2), new Date(atime * 1e3), new Date(mtime * 1e3));
|
|
9560
|
+
return void 0;
|
|
9561
|
+
});
|
|
9515
9562
|
},
|
|
9516
|
-
futimes(
|
|
9517
|
-
return answer(req, () =>
|
|
9563
|
+
futimes(fd, atime, mtime, req) {
|
|
9564
|
+
return answer(req, () => {
|
|
9565
|
+
const file = fileFor(fd);
|
|
9566
|
+
file.tree.utimesSync(file.path, new Date(atime * 1e3), new Date(mtime * 1e3));
|
|
9567
|
+
return void 0;
|
|
9568
|
+
});
|
|
9518
9569
|
},
|
|
9519
|
-
lutimes(
|
|
9520
|
-
return answer(req, () =>
|
|
9570
|
+
lutimes(path2, atime, mtime, req) {
|
|
9571
|
+
return answer(req, () => {
|
|
9572
|
+
if (treeHoldsLinks()) return unsupportedMetadata("lutimes");
|
|
9573
|
+
vfs().utimesSync(asPath(path2), new Date(atime * 1e3), new Date(mtime * 1e3));
|
|
9574
|
+
return void 0;
|
|
9575
|
+
});
|
|
9521
9576
|
},
|
|
9522
9577
|
fsync(_fd, req) {
|
|
9523
9578
|
return answer(req, () => void 0);
|
|
@@ -26140,6 +26195,17 @@ class VirtualFS {
|
|
|
26140
26195
|
/**
|
|
26141
26196
|
* Get stats for path
|
|
26142
26197
|
*/
|
|
26198
|
+
chmodSync(path2, mode) {
|
|
26199
|
+
const node = this.getNode(path2);
|
|
26200
|
+
if (!node) throw createNodeError("ENOENT", "chmod", path2);
|
|
26201
|
+
node.mode = mode & 4095;
|
|
26202
|
+
}
|
|
26203
|
+
utimesSync(path2, atime, mtime) {
|
|
26204
|
+
const node = this.getNode(path2);
|
|
26205
|
+
if (!node) throw createNodeError("ENOENT", "utimes", path2);
|
|
26206
|
+
node.atime = atime instanceof Date ? atime.getTime() : atime * 1e3;
|
|
26207
|
+
node.mtime = mtime instanceof Date ? mtime.getTime() : mtime * 1e3;
|
|
26208
|
+
}
|
|
26143
26209
|
statSync(path2) {
|
|
26144
26210
|
var _a2;
|
|
26145
26211
|
const node = this.getNode(path2);
|
|
@@ -26158,7 +26224,7 @@ class VirtualFS {
|
|
|
26158
26224
|
isFIFO: () => false,
|
|
26159
26225
|
isSocket: () => false,
|
|
26160
26226
|
size,
|
|
26161
|
-
mode: node.type === "directory" ? 493 : 420,
|
|
26227
|
+
mode: node.mode ?? (node.type === "directory" ? 493 : 420),
|
|
26162
26228
|
mtime: new Date(mtime),
|
|
26163
26229
|
atime: new Date(atime),
|
|
26164
26230
|
ctime: new Date(mtime),
|
|
@@ -27892,7 +27958,7 @@ function initChildProcess(vfs2) {
|
|
|
27892
27958
|
};
|
|
27893
27959
|
};
|
|
27894
27960
|
const nodeCommand = defineCommand("node", async (args, ctx) => {
|
|
27895
|
-
var _a2, _b2;
|
|
27961
|
+
var _a2, _b2, _c2, _d2;
|
|
27896
27962
|
if (!tree2) {
|
|
27897
27963
|
return { stdout: "", stderr: "VFS not initialized\n", exitCode: 1 };
|
|
27898
27964
|
}
|
|
@@ -27979,7 +28045,7 @@ function initChildProcess(vfs2) {
|
|
|
27979
28045
|
// open, as a pipe whose writer has not closed.
|
|
27980
28046
|
stdin: typeof ctx.stdin === "string" ? ctx.stdin : "",
|
|
27981
28047
|
...(streams == null ? void 0 : streams.held) || (streams == null ? void 0 : streams.stdinOpen) ? { stdinHeld: true } : {},
|
|
27982
|
-
...(streams == null ? void 0 : streams.held) ? { tty: true } : {},
|
|
28048
|
+
...(streams == null ? void 0 : streams.held) || (streams == null ? void 0 : streams.terminal) ? { tty: true } : {},
|
|
27983
28049
|
// The numbers this run was started with, so the guest's `process.pid`
|
|
27984
28050
|
// is the one its parent's handle carries.
|
|
27985
28051
|
...runPid(runToken) ? { pid: runPid(runToken).pid, ppid: runPid(runToken).ppid } : {}
|
|
@@ -27987,6 +28053,9 @@ function initChildProcess(vfs2) {
|
|
|
27987
28053
|
const proc = runtime.getProcess();
|
|
27988
28054
|
if (runToken !== null) setRunPid(runToken, proc.pid, proc.ppid);
|
|
27989
28055
|
const releaseRun = runToken === null ? null : __recordRun(runToken, {
|
|
28056
|
+
process: proc,
|
|
28057
|
+
stdout: appendStdout,
|
|
28058
|
+
stderr: appendStderr,
|
|
27990
28059
|
pendingTimers: () => pendingGuestTimers(proc),
|
|
27991
28060
|
stopTimers: () => stopGuestTimers(proc),
|
|
27992
28061
|
reportUncaught: (error) => __reportUncaughtException(proc, error)
|
|
@@ -28021,12 +28090,28 @@ function initChildProcess(vfs2) {
|
|
|
28021
28090
|
proc.argv0 = "node";
|
|
28022
28091
|
proc.execArgv = execArgv;
|
|
28023
28092
|
if (streams) streams.stdin = proc.stdin;
|
|
28024
|
-
if (streams == null ? void 0 : streams.held) {
|
|
28093
|
+
if ((streams == null ? void 0 : streams.held) || (streams == null ? void 0 : streams.terminal)) {
|
|
28025
28094
|
proc.stdout.isTTY = true;
|
|
28026
28095
|
proc.stderr.isTTY = true;
|
|
28027
28096
|
proc.stdin.isTTY = true;
|
|
28028
28097
|
proc.stdin.setRawMode = () => proc.stdin;
|
|
28029
28098
|
}
|
|
28099
|
+
const terminal = streams == null ? void 0 : streams.terminal;
|
|
28100
|
+
const resize = (columns, rows) => {
|
|
28101
|
+
for (const stream of [proc.stdout, proc.stderr]) {
|
|
28102
|
+
stream.columns = columns;
|
|
28103
|
+
stream.rows = rows;
|
|
28104
|
+
stream.emit("resize");
|
|
28105
|
+
}
|
|
28106
|
+
};
|
|
28107
|
+
let stopResize;
|
|
28108
|
+
let inputActive = true;
|
|
28109
|
+
let inputIterator;
|
|
28110
|
+
const readableInput = proc.stdin;
|
|
28111
|
+
const inputReading = () => {
|
|
28112
|
+
var _a3, _b3;
|
|
28113
|
+
return readableInput.readableFlowing === true || ((_a3 = readableInput._readableState) == null ? void 0 : _a3.reading) === true || ((_b3 = readableInput._readableState) == null ? void 0 : _b3.needReadable) === true || readableInput.listenerCount("data") > 0 || readableInput.listenerCount("readable") > 0;
|
|
28114
|
+
};
|
|
28030
28115
|
if (Number.isInteger(channelFd) && channelFd >= 0 && runToken !== null) {
|
|
28031
28116
|
enterRun(runToken, () => {
|
|
28032
28117
|
attachChannel(proc, channelFd, channelSerialization);
|
|
@@ -28084,6 +28169,39 @@ ${reason.stack || ""}` : String(reason);
|
|
|
28084
28169
|
};
|
|
28085
28170
|
const detachUncaught = __onUncaughtException(proc, onUncaughtException);
|
|
28086
28171
|
try {
|
|
28172
|
+
if (streams == null ? void 0 : streams.stdinStream) {
|
|
28173
|
+
inputIterator = streams.stdinStream[Symbol.asyncIterator]();
|
|
28174
|
+
const input = inputIterator;
|
|
28175
|
+
void (async () => {
|
|
28176
|
+
var _a3, _b3, _c3, _d3, _e2;
|
|
28177
|
+
const push = (chunk) => {
|
|
28178
|
+
if (runToken === null) proc.stdin.push(chunk);
|
|
28179
|
+
else enterRun(runToken, () => proc.stdin.push(chunk));
|
|
28180
|
+
};
|
|
28181
|
+
try {
|
|
28182
|
+
while (inputActive && !((_a3 = streams.signal) == null ? void 0 : _a3.aborted)) {
|
|
28183
|
+
while (inputActive && !((_b3 = streams.signal) == null ? void 0 : _b3.aborted) && (!inputReading() || readableInput.readableLength >= readableInput.readableHighWaterMark)) {
|
|
28184
|
+
await new Promise((resolve2) => (globalThis.__browserRuntimeNativeSetTimeout ?? setTimeout).call(globalThis, resolve2, 10));
|
|
28185
|
+
}
|
|
28186
|
+
if (!inputActive || ((_c3 = streams.signal) == null ? void 0 : _c3.aborted)) break;
|
|
28187
|
+
const next = await input.next();
|
|
28188
|
+
if (next.done) break;
|
|
28189
|
+
if (!inputActive || ((_d3 = streams.signal) == null ? void 0 : _d3.aborted)) break;
|
|
28190
|
+
push(next.value);
|
|
28191
|
+
}
|
|
28192
|
+
if (inputActive && !((_e2 = streams.signal) == null ? void 0 : _e2.aborted)) push(null);
|
|
28193
|
+
} catch (error) {
|
|
28194
|
+
if (inputActive) onUncaughtException(error);
|
|
28195
|
+
} finally {
|
|
28196
|
+
streams.stdinOpen = false;
|
|
28197
|
+
}
|
|
28198
|
+
})();
|
|
28199
|
+
}
|
|
28200
|
+
if (terminal) resize(terminal.columns, terminal.rows);
|
|
28201
|
+
stopResize = (_a2 = terminal == null ? void 0 : terminal.onResize) == null ? void 0 : _a2.call(terminal, (columns, rows) => {
|
|
28202
|
+
if (runToken === null) resize(columns, rows);
|
|
28203
|
+
else enterRun(runToken, () => resize(columns, rows));
|
|
28204
|
+
});
|
|
28087
28205
|
let entrySettling;
|
|
28088
28206
|
try {
|
|
28089
28207
|
const runEntry = () => runtime.runFile(resolvedPath);
|
|
@@ -28121,7 +28239,7 @@ ${error.stack || ""}` : String(error);
|
|
|
28121
28239
|
}
|
|
28122
28240
|
}
|
|
28123
28241
|
const __ownsHandles = () => runToken !== null && (__ownedServerPorts(runToken).length > 0 || __ownedHandleCount(runToken) > 0);
|
|
28124
|
-
const __printedThenWorking = () => pendingGuestTimers(proc) > 0 || heldWork().count > 0 || __ownsHandles();
|
|
28242
|
+
const __printedThenWorking = () => (streams == null ? void 0 : streams.stdinOpen) === true && inputReading() || pendingGuestTimers(proc) > 0 || heldWork().count > 0 || __ownsHandles();
|
|
28125
28243
|
if ((stdout.length > 0 || stderr.length > 0) && !__printedThenWorking()) {
|
|
28126
28244
|
await new Promise((r) => (globalThis.__browserRuntimeNativeSetTimeout ?? setTimeout).call(globalThis, r, 0));
|
|
28127
28245
|
if (exitCalled) return { stdout, stderr, exitCode };
|
|
@@ -28144,16 +28262,16 @@ ${error.stack || ""}` : String(error);
|
|
|
28144
28262
|
const startTime = Date.now();
|
|
28145
28263
|
let lastOutputLen = stdout.length + stderr.length;
|
|
28146
28264
|
let idleMs = 0;
|
|
28147
|
-
const stillWorking = () => pendingGuestTimers(proc) > 0 || __ownsHandles();
|
|
28265
|
+
const stillWorking = () => (streams == null ? void 0 : streams.stdinOpen) === true && inputReading() || pendingGuestTimers(proc) > 0 || __ownsHandles();
|
|
28148
28266
|
const isLongRunning = !!(streams == null ? void 0 : streams.held);
|
|
28149
28267
|
while (!exitCalled) {
|
|
28150
|
-
if ((
|
|
28268
|
+
if ((_b2 = streams == null ? void 0 : streams.signal) == null ? void 0 : _b2.aborted) break;
|
|
28151
28269
|
const raceResult = await Promise.race([
|
|
28152
28270
|
exitPromise.then(() => "exit"),
|
|
28153
28271
|
new Promise((r) => (globalThis.__browserRuntimeNativeSetTimeout ?? setTimeout).call(globalThis, () => r("tick"), CHECK_MS))
|
|
28154
28272
|
]);
|
|
28155
28273
|
if (raceResult === "exit" || exitCalled) break;
|
|
28156
|
-
if ((
|
|
28274
|
+
if ((_c2 = streams == null ? void 0 : streams.signal) == null ? void 0 : _c2.aborted) break;
|
|
28157
28275
|
const currentLen = stdout.length + stderr.length;
|
|
28158
28276
|
if (currentLen > lastOutputLen) {
|
|
28159
28277
|
lastOutputLen = currentLen;
|
|
@@ -28178,6 +28296,16 @@ ${error.stack || ""}` : String(error);
|
|
|
28178
28296
|
} finally {
|
|
28179
28297
|
detachRejections();
|
|
28180
28298
|
detachUncaught();
|
|
28299
|
+
inputActive = false;
|
|
28300
|
+
try {
|
|
28301
|
+
void Promise.resolve((_d2 = inputIterator == null ? void 0 : inputIterator.return) == null ? void 0 : _d2.call(inputIterator)).catch(() => {
|
|
28302
|
+
});
|
|
28303
|
+
} catch {
|
|
28304
|
+
}
|
|
28305
|
+
try {
|
|
28306
|
+
stopResize == null ? void 0 : stopResize();
|
|
28307
|
+
} catch {
|
|
28308
|
+
}
|
|
28181
28309
|
if (runToken !== null) {
|
|
28182
28310
|
__releaseOwnedServers(runToken, false);
|
|
28183
28311
|
__releaseOwnedHandles(runToken);
|
|
@@ -33810,7 +33938,7 @@ class WorkerRuntime {
|
|
|
33810
33938
|
this.worker = new Worker(
|
|
33811
33939
|
new URL(
|
|
33812
33940
|
/* @vite-ignore */
|
|
33813
|
-
"/assets/runtime-worker-
|
|
33941
|
+
"/assets/runtime-worker-LWfW6VWE.js",
|
|
33814
33942
|
import.meta.url
|
|
33815
33943
|
),
|
|
33816
33944
|
{ type: "module" }
|
|
@@ -35228,7 +35356,7 @@ function ownedBytes(view) {
|
|
|
35228
35356
|
return copy2;
|
|
35229
35357
|
}
|
|
35230
35358
|
function guestListeningServer(port, address) {
|
|
35231
|
-
const hostname2 = address
|
|
35359
|
+
const hostname2 = address;
|
|
35232
35360
|
return {
|
|
35233
35361
|
listening: true,
|
|
35234
35362
|
address: () => ({
|
|
@@ -35472,6 +35600,18 @@ const _ServerBridge = class _ServerBridge extends EventEmitter {
|
|
|
35472
35600
|
__publicField(this, "upgradeChannel", null);
|
|
35473
35601
|
__publicField(this, "serviceWorkerReady", false);
|
|
35474
35602
|
__publicField(this, "keepaliveInterval", null);
|
|
35603
|
+
/**
|
|
35604
|
+
* Give back everything this bridge opened: the upgrade channel and the
|
|
35605
|
+
* service worker keepalive. A host that is done with a container calls it
|
|
35606
|
+
* and has its process back; calling it twice is nothing.
|
|
35607
|
+
*/
|
|
35608
|
+
/**
|
|
35609
|
+
* Every port a guest starts listening on becomes a server this bridge can
|
|
35610
|
+
* answer for, and every port it stops listening on stops being one. The
|
|
35611
|
+
* news comes from the net binding, because that is where a port is taken;
|
|
35612
|
+
* the engine's `http` is Node's own file and knows nothing of a page.
|
|
35613
|
+
*/
|
|
35614
|
+
__publicField(this, "guestServers", /* @__PURE__ */ new WeakSet());
|
|
35475
35615
|
/** The server the service worker answers at the origin's root, the preview's; null for none. */
|
|
35476
35616
|
__publicField(this, "primaryPort", null);
|
|
35477
35617
|
__publicField(this, "ownDocuments");
|
|
@@ -35484,27 +35624,21 @@ const _ServerBridge = class _ServerBridge extends EventEmitter {
|
|
|
35484
35624
|
this.watchGuestPorts();
|
|
35485
35625
|
this.upgradeChannel = __substrateListenForUpgrades();
|
|
35486
35626
|
}
|
|
35487
|
-
/**
|
|
35488
|
-
* Give back everything this bridge opened: the upgrade channel and the
|
|
35489
|
-
* service worker keepalive. A host that is done with a container calls it
|
|
35490
|
-
* and has its process back; calling it twice is nothing.
|
|
35491
|
-
*/
|
|
35492
|
-
/**
|
|
35493
|
-
* Every port a guest starts listening on becomes a server this bridge can
|
|
35494
|
-
* answer for, and every port it stops listening on stops being one. The
|
|
35495
|
-
* news comes from the net binding, because that is where a port is taken;
|
|
35496
|
-
* the engine's `http` is Node's own file and knows nothing of a page.
|
|
35497
|
-
*/
|
|
35498
35627
|
watchGuestPorts() {
|
|
35499
35628
|
setPortWatchers(
|
|
35500
35629
|
(port, address) => {
|
|
35501
35630
|
if (this.servers.has(port)) return;
|
|
35502
35631
|
const hostname2 = address || "0.0.0.0";
|
|
35503
|
-
|
|
35632
|
+
const server = guestListeningServer(port, hostname2);
|
|
35633
|
+
this.guestServers.add(server);
|
|
35634
|
+
this.registerServer(server, port, hostname2);
|
|
35504
35635
|
},
|
|
35505
35636
|
(port) => {
|
|
35506
35637
|
const entry = this.servers.get(port);
|
|
35507
|
-
if (entry && entry.server === null
|
|
35638
|
+
if (entry && (entry.server === null || this.guestServers.has(entry.server))) {
|
|
35639
|
+
if (entry.server) entry.server.listening = false;
|
|
35640
|
+
this.unregisterServer(port);
|
|
35641
|
+
}
|
|
35508
35642
|
}
|
|
35509
35643
|
);
|
|
35510
35644
|
}
|
|
@@ -35955,15 +36089,19 @@ function createContainer(options) {
|
|
|
35955
36089
|
onStdout: runOptions == null ? void 0 : runOptions.onStdout,
|
|
35956
36090
|
onStderr: runOptions == null ? void 0 : runOptions.onStderr,
|
|
35957
36091
|
signal: runOptions == null ? void 0 : runOptions.signal,
|
|
35958
|
-
held: (runOptions == null ? void 0 : runOptions.held) === true
|
|
36092
|
+
held: (runOptions == null ? void 0 : runOptions.held) === true,
|
|
36093
|
+
stdinStream: runOptions == null ? void 0 : runOptions.stdinStream,
|
|
36094
|
+
stdinOpen: (runOptions == null ? void 0 : runOptions.stdinStream) !== void 0,
|
|
36095
|
+
terminal: runOptions == null ? void 0 : runOptions.terminal
|
|
35959
36096
|
});
|
|
35960
36097
|
return new Promise((resolve2) => {
|
|
35961
36098
|
runCommand(command, { cwd: runOptions == null ? void 0 : runOptions.cwd, env: runOptions == null ? void 0 : runOptions.env, stdin: typeof (runOptions == null ? void 0 : runOptions.stdin) === "string" ? runOptions.stdin : void 0, processToken, vfs: vfs2 }, (error, stdout, stderr) => {
|
|
36099
|
+
var _a3;
|
|
35962
36100
|
releaseRunStreams(processToken);
|
|
35963
36101
|
resolve2({
|
|
35964
36102
|
stdout: String(stdout),
|
|
35965
36103
|
stderr: String(stderr),
|
|
35966
|
-
exitCode: error ? error.code ?? 1 : 0
|
|
36104
|
+
exitCode: ((_a3 = runOptions == null ? void 0 : runOptions.signal) == null ? void 0 : _a3.aborted) ? 143 : error ? error.code ?? 1 : 0
|
|
35967
36105
|
});
|
|
35968
36106
|
});
|
|
35969
36107
|
});
|
|
@@ -45,7 +45,7 @@ export declare class FSEvent {
|
|
|
45
45
|
#private;
|
|
46
46
|
onchange: ((status: number, event: string, filename: string) => void) | null;
|
|
47
47
|
initialized: boolean;
|
|
48
|
-
start(path: unknown,
|
|
48
|
+
start(path: unknown, persistent?: boolean, recursive?: boolean, _encoding?: string): number;
|
|
49
49
|
close(): void;
|
|
50
50
|
ref(): void;
|
|
51
51
|
unref(): void;
|
|
@@ -109,7 +109,7 @@ export declare const fsBinding: {
|
|
|
109
109
|
* a disk: a block size, and a count no program can exhaust.
|
|
110
110
|
*/
|
|
111
111
|
statfs(_path: unknown, bigint: boolean, req?: FSReq): Float64Array | BigInt64Array | undefined;
|
|
112
|
-
access(path: unknown,
|
|
112
|
+
access(path: unknown, mode: number, req?: FSReq): undefined;
|
|
113
113
|
existsSync(path: unknown): boolean;
|
|
114
114
|
/**
|
|
115
115
|
* Node's `cpSync` asks this before it copies: a directory is not a file,
|
|
@@ -143,12 +143,12 @@ export declare const fsBinding: {
|
|
|
143
143
|
mkdtemp(prefix: unknown, encoding: string, req?: FSReq): string | Uint8Array | undefined;
|
|
144
144
|
chmod(path: unknown, mode: number, req?: FSReq): undefined;
|
|
145
145
|
fchmod(fd: number, mode: number, req?: FSReq): undefined;
|
|
146
|
-
chown(
|
|
146
|
+
chown(_path: unknown, _uid: number, _gid: number, req?: FSReq): undefined;
|
|
147
147
|
fchown(_fd: number, _uid: number, _gid: number, req?: FSReq): undefined;
|
|
148
148
|
lchown(_path: unknown, _uid: number, _gid: number, req?: FSReq): undefined;
|
|
149
|
-
utimes(
|
|
150
|
-
futimes(
|
|
151
|
-
lutimes(
|
|
149
|
+
utimes(path: unknown, atime: number, mtime: number, req?: FSReq): undefined;
|
|
150
|
+
futimes(fd: number, atime: number, mtime: number, req?: FSReq): undefined;
|
|
151
|
+
lutimes(path: unknown, atime: number, mtime: number, req?: FSReq): undefined;
|
|
152
152
|
fsync(_fd: number, req?: FSReq): undefined;
|
|
153
153
|
fdatasync(_fd: number, req?: FSReq): undefined;
|
|
154
154
|
ftruncate(fd: number, length: number, req?: FSReq): undefined;
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
import { LibuvStreamWrap } from './stream_wrap';
|
|
22
22
|
import { Pipe } from './pipe_wrap';
|
|
23
23
|
import { type OwnedHandle } from './handles';
|
|
24
|
-
import type
|
|
24
|
+
import { type ProcessToken } from '../../process-tokens';
|
|
25
25
|
/** One entry of Node's `options.stdio`, as `getValidStdio` builds it. */
|
|
26
26
|
export interface StdioEntry {
|
|
27
27
|
type: 'pipe' | 'overlapped' | 'ignore' | 'inherit' | 'fd' | 'wrap';
|
package/dist/process-tokens.d.ts
CHANGED
|
@@ -14,12 +14,17 @@
|
|
|
14
14
|
* for both. The guest never sees the variable: the environment the `node`
|
|
15
15
|
* command gives its process has it removed.
|
|
16
16
|
*/
|
|
17
|
+
import type { Process } from './shims/process';
|
|
17
18
|
/** Whatever the embedding runtime uses to name one guest process. */
|
|
18
19
|
export type ProcessToken = string;
|
|
19
20
|
/** The environment variable a run's name travels in, from `exec` to `node`. */
|
|
20
21
|
export declare const PROCESS_TOKEN_ENV = "__TABNODE_PROCESS_TOKEN";
|
|
21
22
|
/** What the engine can answer about one named run. */
|
|
22
23
|
export interface OwnedRun {
|
|
24
|
+
/** The guest whose cwd and inherited streams belong to this run. */
|
|
25
|
+
process: Process;
|
|
26
|
+
stdout(text: string): void;
|
|
27
|
+
stderr(text: string): void;
|
|
23
28
|
/** The timers the run's guest still holds, as Node's loop counts them. */
|
|
24
29
|
pendingTimers(): number;
|
|
25
30
|
/** Clear those timers, as ending the process clears them. */
|
package/dist/server-bridge.d.ts
CHANGED
|
@@ -65,6 +65,7 @@ export declare class ServerBridge extends EventEmitter {
|
|
|
65
65
|
* news comes from the net binding, because that is where a port is taken;
|
|
66
66
|
* the engine's `http` is Node's own file and knows nothing of a page.
|
|
67
67
|
*/
|
|
68
|
+
private readonly guestServers;
|
|
68
69
|
private watchGuestPorts;
|
|
69
70
|
close(): void;
|
|
70
71
|
/**
|
|
@@ -32,6 +32,12 @@ type RunStdin = {
|
|
|
32
32
|
* output went down the child's channel.
|
|
33
33
|
*/
|
|
34
34
|
export interface RunStreams {
|
|
35
|
+
stdinStream?: AsyncIterable<Uint8Array>;
|
|
36
|
+
terminal?: {
|
|
37
|
+
columns: number;
|
|
38
|
+
rows: number;
|
|
39
|
+
onResize?: (listener: (columns: number, rows: number) => void) => () => void;
|
|
40
|
+
};
|
|
35
41
|
onStdout?: (data: string) => void;
|
|
36
42
|
onStderr?: (data: string) => void;
|
|
37
43
|
signal?: AbortSignal;
|