@ai-ecoverse/slicc-kernel 1.25.0 → 1.26.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/node.js CHANGED
@@ -2454,6 +2454,7 @@ Sec-WebSocket-Accept: ${accept2}\r
2454
2454
  // src/cdp/facade.ts
2455
2455
  var MAX_HEAD = 64 * 1024;
2456
2456
  var LIST_TIMEOUT = 1e4;
2457
+ var CLOSE_WAIT_MS = 1e3;
2457
2458
  function respond(status, body, type = "text/plain; charset=utf-8") {
2458
2459
  const bytes = new TextEncoder().encode(body);
2459
2460
  const head = latin1Bytes(
@@ -2599,7 +2600,11 @@ var CdpFacade = class {
2599
2600
  async upgrade(conn, incoming, req, runtime) {
2600
2601
  const accept2 = await acceptKey(req.headers);
2601
2602
  const host = await this.host(runtime);
2602
- await new Relay(conn, incoming, host, this.options.maxMessage ?? MAX_MESSAGE, this.stop.signal).start(switchingHead(accept2)).finally(() => host.close());
2603
+ const limits = {
2604
+ max: this.options.maxMessage ?? MAX_MESSAGE,
2605
+ closeWaitMs: this.options.closeWaitMs ?? CLOSE_WAIT_MS
2606
+ };
2607
+ await new Relay(conn, incoming, host, limits, this.stop.signal).start(switchingHead(accept2)).finally(() => host.close());
2603
2608
  }
2604
2609
  };
2605
2610
  var Relay = class {
@@ -2609,12 +2614,14 @@ var Relay = class {
2609
2614
  incoming;
2610
2615
  host;
2611
2616
  max;
2617
+ closeWaitMs;
2612
2618
  stop;
2613
- constructor(conn, incoming, host, max, stop) {
2619
+ constructor(conn, incoming, host, limits, stop) {
2614
2620
  this.conn = conn;
2615
2621
  this.incoming = incoming;
2616
2622
  this.host = host;
2617
- this.max = max;
2623
+ this.max = limits.max;
2624
+ this.closeWaitMs = limits.closeWaitMs;
2618
2625
  this.stop = stop;
2619
2626
  }
2620
2627
  send(bytes) {
@@ -2640,8 +2647,15 @@ var Relay = class {
2640
2647
  void this.end(CLOSE.tooBig, `a message is over ${this.max} bytes`);
2641
2648
  else void this.send(frame(OP_TEXT, bytes));
2642
2649
  };
2643
- await Promise.race([this.pump(), hostGone]);
2650
+ const pumping = this.pump();
2651
+ await Promise.race([pumping, hostGone]);
2644
2652
  await this.writes;
2653
+ let timer;
2654
+ const waited = new Promise((resolve) => {
2655
+ timer = setTimeout(resolve, this.closeWaitMs);
2656
+ });
2657
+ await Promise.race([pumping, waited]);
2658
+ clearTimeout(timer);
2645
2659
  }
2646
2660
  async pump() {
2647
2661
  const reader = new WsReader(this.incoming, this.max);
@@ -3441,7 +3455,8 @@ function statOf(attr, path, mount) {
3441
3455
  dev: mount.dev,
3442
3456
  ...readonly(mount) ? { readonly: true } : {},
3443
3457
  ...mount.maxFile > 0 ? { maxFile: mount.maxFile } : {},
3444
- ...mount.caps.ranges ? { ranged: true } : {}
3458
+ ...mount.caps.ranges ? { ranged: true } : {},
3459
+ ...attr.etag !== void 0 ? { version: attr.etag } : {}
3445
3460
  };
3446
3461
  }
3447
3462
  function concat3(chunks2, total) {
@@ -3776,7 +3791,7 @@ var MountFs = class {
3776
3791
  this.table.forget(mount, real);
3777
3792
  }
3778
3793
  }
3779
- async pread(path, offset, length2) {
3794
+ async pread(path, offset, length2, version) {
3780
3795
  const real = await this.follow(path);
3781
3796
  const found = this.at(real);
3782
3797
  if (!found && this.base.pread) return this.base.pread(real, offset, length2);
@@ -3785,7 +3800,15 @@ var MountFs = class {
3785
3800
  if ((await this.table.getattr(mount, real, rel2)).kind === "directory") {
3786
3801
  throw errnoError("EISDIR", real);
3787
3802
  }
3788
- const fh = await this.open(mount, rel2, false);
3803
+ const fh = await mount.conn.call({
3804
+ op: "open",
3805
+ path: rel2,
3806
+ write: false,
3807
+ create: false,
3808
+ truncate: false,
3809
+ exclusive: false,
3810
+ ...version !== void 0 ? { ifMatch: version } : {}
3811
+ });
3789
3812
  const chunk2 = mount.caps.maxIo ?? DEFAULT_IO;
3790
3813
  const chunks2 = [];
3791
3814
  let total = 0;
@@ -4047,7 +4070,8 @@ function statJson(s) {
4047
4070
  ...s.dev !== void 0 ? { dev: s.dev } : {},
4048
4071
  ...s.readonly ? { readonly: true } : {},
4049
4072
  ...s.maxFile ? { maxFile: s.maxFile } : {},
4050
- ...s.ranged ? { ranged: true } : {}
4073
+ ...s.ranged ? { ranged: true } : {},
4074
+ ...s.version !== void 0 ? { version: s.version } : {}
4051
4075
  };
4052
4076
  }
4053
4077
  async function readdirStat(fs, dir) {
@@ -4125,7 +4149,11 @@ async function ranged(fs, path, req) {
4125
4149
  if (!ops) throw syncError("ENOSYS", path);
4126
4150
  const offset = req.offset ?? 0;
4127
4151
  if (req.op === "pread")
4128
- return { ok: true, kind: "bytes", bytes: await ops.pread(path, offset, req.length ?? 0) };
4152
+ return {
4153
+ ok: true,
4154
+ kind: "bytes",
4155
+ bytes: await ops.pread(path, offset, req.length ?? 0, req.version)
4156
+ };
4129
4157
  if (req.op === "pwrite") await ops.pwrite(path, offset, req.body ?? new Uint8Array(0), true);
4130
4158
  else await ops.truncate(path, req.length ?? 0);
4131
4159
  return done;
@@ -6401,17 +6429,21 @@ var AsyncRangedFile = class {
6401
6429
  pages;
6402
6430
  io;
6403
6431
  pinned = false;
6432
+ version;
6404
6433
  path;
6405
- constructor(io, path, size) {
6434
+ constructor(io, path, size, version) {
6406
6435
  this.io = io;
6407
6436
  this.path = path;
6437
+ this.version = version;
6408
6438
  this.pages = new Pages(size);
6409
6439
  }
6410
6440
  size() {
6411
6441
  return this.pages.length;
6412
6442
  }
6413
6443
  async fetch(runs) {
6414
- for (const [start, n] of runs) this.pages.fill(start, await this.io.pread(this.path, start, n));
6444
+ for (const [start, n] of runs) {
6445
+ this.pages.fill(start, await this.io.pread(this.path, start, n, this.version));
6446
+ }
6415
6447
  }
6416
6448
  async read(at, length2) {
6417
6449
  await this.fetch(this.pages.missing(at, length2));
@@ -6431,6 +6463,7 @@ var AsyncRangedFile = class {
6431
6463
  if (plan.shrink !== void 0) await this.io.truncate(this.path, plan.shrink);
6432
6464
  for (const run2 of plan.runs) await this.io.pwrite(this.path, run2.offset, run2.bytes, true);
6433
6465
  if (plan.extend !== void 0) await this.io.truncate(this.path, plan.extend);
6466
+ this.version = void 0;
6434
6467
  this.pages.flushed();
6435
6468
  }
6436
6469
  async pin() {
@@ -6498,7 +6531,7 @@ var VfsNode = class {
6498
6531
  const io = rangedOps(this.fs);
6499
6532
  const st = io && !this.orphaned ? await this.fs.stat?.(this.path).catch(() => void 0) : void 0;
6500
6533
  if (io && st?.ranged) {
6501
- this.ranged = new AsyncRangedFile(io, this.path, st.size ?? 0);
6534
+ this.ranged = new AsyncRangedFile(io, this.path, st.size ?? 0, st.version);
6502
6535
  return this.ranged;
6503
6536
  }
6504
6537
  await this.load();
@@ -7792,7 +7825,8 @@ async function dispatch(h, req) {
7792
7825
  write: req.write,
7793
7826
  create: req.create,
7794
7827
  truncate: req.truncate,
7795
- exclusive: req.exclusive
7828
+ exclusive: req.exclusive,
7829
+ ...req.ifMatch !== void 0 ? { ifMatch: req.ifMatch } : {}
7796
7830
  });
7797
7831
  case "read":
7798
7832
  return h.read(req.fh, req.offset, req.size);
@@ -8333,7 +8367,8 @@ function hostfsHandlers(current) {
8333
8367
  };
8334
8368
  const call = (op, body = {}) => current().call(op, body);
8335
8369
  async function writable(client, path, flags) {
8336
- const opening = () => client.call("open", { path: rel(path), ...flags });
8370
+ const { ifMatch: _, ...asked } = flags;
8371
+ const opening = () => client.call("open", { path: rel(path), ...asked });
8337
8372
  try {
8338
8373
  return { opened: await opening(), restore: void 0 };
8339
8374
  } catch (err) {
@@ -8349,7 +8384,7 @@ function hostfsHandlers(current) {
8349
8384
  return { opened: opened2, restore };
8350
8385
  }
8351
8386
  }
8352
- return {
8387
+ const handlers = {
8353
8388
  getattr: async (path) => await call("stat", { path: rel(path) }),
8354
8389
  async readdir(path) {
8355
8390
  const { entries } = await call(
@@ -8362,6 +8397,10 @@ function hostfsHandlers(current) {
8362
8397
  const client = current();
8363
8398
  const token = client.token;
8364
8399
  const { opened: opened2, restore } = await writable(client, path, flags);
8400
+ if (flags.ifMatch !== void 0 && opened2.attr?.etag !== flags.ifMatch) {
8401
+ await client.call("release", { fh: opened2.fh }, true);
8402
+ throw fsError2("ESTALE", `${path} changed on the host while it was being read`);
8403
+ }
8365
8404
  handles.set(++nextFh, {
8366
8405
  client,
8367
8406
  token,
@@ -8403,9 +8442,44 @@ function hostfsHandlers(current) {
8403
8442
  rename: async (from, to) => void await call("rename", { from: rel(from), to: rel(to) }),
8404
8443
  symlink: async (target, path) => void await call("symlink", { target, path: rel(path) }),
8405
8444
  readlink: async (path) => (await call("readlink", { path: rel(path) })).target,
8406
- setattr: async (path, change) => void await call("setattr", { path: rel(path), ...change }),
8445
+ async setattr(path, { size, ...change }) {
8446
+ if (size !== void 0 && !current().capabilities.ranges) await resize(handlers, path, size);
8447
+ else if (size !== void 0) change = { ...change, size };
8448
+ if (Object.keys(change).length > 0) await call("setattr", { path: rel(path), ...change });
8449
+ },
8407
8450
  statfs: () => call("statfs")
8408
8451
  };
8452
+ return handlers;
8453
+ }
8454
+ var KEEP = { write: false, create: false, truncate: false, exclusive: false };
8455
+ async function resize(h, path, size) {
8456
+ const was = (await h.getattr(path)).size;
8457
+ if (size === was) return;
8458
+ const kept = [];
8459
+ if (size < was && size > 0) {
8460
+ const fh2 = await h.open(path, KEEP);
8461
+ try {
8462
+ for (let at = 0; at < size; ) {
8463
+ const bytes = await h.read(fh2, at, size - at);
8464
+ if (bytes.length === 0) break;
8465
+ kept.push(bytes);
8466
+ at += bytes.length;
8467
+ }
8468
+ } finally {
8469
+ await h.release(fh2);
8470
+ }
8471
+ }
8472
+ const fh = await h.open(path, { ...KEEP, write: true, truncate: size < was });
8473
+ try {
8474
+ if (size > was) await h.write(fh, size - 1, new Uint8Array(1));
8475
+ let at = 0;
8476
+ for (const bytes of kept) {
8477
+ await h.write(fh, at, bytes);
8478
+ at += bytes.length;
8479
+ }
8480
+ } finally {
8481
+ await h.release(fh);
8482
+ }
8409
8483
  }
8410
8484
  function sleep(ms, signal) {
8411
8485
  return new Promise((resolve) => {
@@ -8499,13 +8573,18 @@ async function openHostfs(spec, hook, fetch2, timing = {}) {
8499
8573
  const grant = () => hook(spec.source, { readonly: readonly2 });
8500
8574
  let active;
8501
8575
  const handlers = hostfsHandlers(() => active);
8502
- const served = serveFilesystem(port2, slot.handlers, {
8503
- symlinks: true,
8504
- chmod: true,
8505
- listingStats: true,
8506
- maxIo: HOSTFS_IO,
8507
- ...readonly2 ? { readonly: true } : {}
8508
- });
8576
+ const ranged2 = () => active?.capabilities.ranges === true ? { ranges: true } : {};
8577
+ const served = serveFilesystem(
8578
+ port2,
8579
+ { ...slot.handlers, mount: ranged2 },
8580
+ {
8581
+ symlinks: true,
8582
+ chmod: true,
8583
+ listingStats: true,
8584
+ maxIo: HOSTFS_IO,
8585
+ ...readonly2 ? { readonly: true } : {}
8586
+ }
8587
+ );
8509
8588
  const watching = keepWatching(
8510
8589
  {
8511
8590
  connect: async () => new HostfsClient(await grant(), grant, fetch2),