@ai-ecoverse/slicc-kernel 1.117.4 → 1.118.0

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
@@ -3994,22 +3994,54 @@ var RemoteWatch = class {
3994
3994
  mine = [];
3995
3995
  seq = 0;
3996
3996
  pruned = 0;
3997
+ joined;
3998
+ met;
3999
+ quiet;
3997
4000
  constructor(name2, options = {}) {
3998
4001
  this.name = name2;
3999
4002
  this.locks = options.locks === void 0 ? lockManager() : options.locks ?? void 0;
4000
4003
  this.channel = new BroadcastChannel(name2);
4001
4004
  this.channel.onmessage = ({ data }) => this.receive(data);
4002
4005
  this.channel.unref?.();
4003
- void this.locks?.request(this.lockOf(this.tab), () => new Promise(() => {
4004
- }));
4006
+ const granted2 = new Promise((resolve2) => {
4007
+ void this.locks?.request(this.lockOf(this.tab), () => {
4008
+ resolve2();
4009
+ return new Promise(() => {
4010
+ });
4011
+ });
4012
+ if (!this.locks) resolve2();
4013
+ });
4014
+ this.joined = granted2.then(() => this.join());
4005
4015
  this.channel.postMessage({ hello: this.tab });
4006
4016
  }
4017
+ async join() {
4018
+ if (!this.locks) return;
4019
+ const prefix = `${this.name}:`;
4020
+ const mine = this.lockOf(this.tab);
4021
+ const held = ((await this.locks.query()).held ?? []).map((lock) => lock.name ?? "");
4022
+ if (!held.some((name2) => name2.startsWith(prefix) && name2 !== mine) || this.peers.size > 0)
4023
+ return;
4024
+ await new Promise((resolve2) => {
4025
+ const timer = setTimeout(resolve2, ANNOUNCE_WAIT_MS);
4026
+ this.met = () => {
4027
+ clearTimeout(timer);
4028
+ resolve2();
4029
+ };
4030
+ });
4031
+ }
4032
+ async peered() {
4033
+ await this.joined;
4034
+ return this.peers.size > 0;
4035
+ }
4007
4036
  lockOf(tab) {
4008
4037
  return `${this.name}:${tab}`;
4009
4038
  }
4010
4039
  receive(data) {
4011
4040
  if (data.hello !== void 0) this.greeted(data.hello);
4012
- if (data.here !== void 0 && data.to === this.tab) this.peers.add(data.here);
4041
+ if (data.here !== void 0 && data.to === this.tab) {
4042
+ this.peers.add(data.here);
4043
+ this.met?.();
4044
+ }
4013
4045
  if (data.tab !== void 0 && data.paths !== void 0) this.announced(data);
4014
4046
  if (data.ack !== void 0 && data.to === this.tab && data.from !== void 0) {
4015
4047
  this.acked(data.ack, data.from);
@@ -4018,8 +4050,12 @@ var RemoteWatch = class {
4018
4050
  }
4019
4051
  greeted(peer) {
4020
4052
  this.peers.add(peer);
4021
- this.channel.postMessage({ here: this.tab, to: peer });
4022
- if (this.mine.length > 0) void this.announce(this.mine);
4053
+ const answer = () => {
4054
+ this.channel.postMessage({ here: this.tab, to: peer });
4055
+ if (this.mine.length > 0) void this.announce(this.mine);
4056
+ };
4057
+ if (this.quiet) void this.quiet().then(answer, answer);
4058
+ else answer();
4023
4059
  }
4024
4060
  announced({ tab, paths, seq: seq2 }) {
4025
4061
  const from = tab;
@@ -4275,6 +4311,7 @@ var OpfsFs = class {
4275
4311
  this.lockPrefix = `slicc-excl:${channel ?? ""}:`;
4276
4312
  this.channel = channel === void 0 ? void 0 : new BroadcastChannel(channel);
4277
4313
  this.remote = channel === void 0 ? void 0 : new RemoteWatch(`${channel}:watch`);
4314
+ if (this.remote) this.remote.quiet = () => this.quiet();
4278
4315
  if (this.channel) {
4279
4316
  const remote = this.remote;
4280
4317
  meta.listen?.(
@@ -4418,8 +4455,24 @@ var OpfsFs = class {
4418
4455
  throw fsError("EROFS", path);
4419
4456
  }
4420
4457
  }
4458
+ unlocked = 0;
4459
+ idle = [];
4460
+ async alone(op) {
4461
+ this.unlocked++;
4462
+ try {
4463
+ return await op();
4464
+ } finally {
4465
+ this.unlocked--;
4466
+ if (this.unlocked === 0) for (const done4 of this.idle.splice(0)) done4();
4467
+ }
4468
+ }
4469
+ quiet() {
4470
+ if (this.unlocked === 0) return Promise.resolve();
4471
+ return new Promise((resolve2) => this.idle.push(resolve2));
4472
+ }
4421
4473
  async locked(physicalPath, op) {
4422
4474
  if (!this.locks) return op();
4475
+ if (this.remote && !await this.remote.peered()) return this.alone(op);
4423
4476
  const key = `${this.lockPrefix}${physicalPath}`;
4424
4477
  let result;
4425
4478
  await this.locks.request(key, async () => {
@@ -6682,7 +6735,7 @@ function satisfies(version, range2) {
6682
6735
  }
6683
6736
 
6684
6737
  // src/version.ts
6685
- var KERNEL_VERSION = true ? "1.117.4" : "0.0.0-dev";
6738
+ var KERNEL_VERSION = true ? "1.118.0" : "0.0.0-dev";
6686
6739
  var OS_RELEASE = "6.0.0-slicc";
6687
6740
  function procVersion() {
6688
6741
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -8911,6 +8964,7 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
8911
8964
  readlink: (path) => fs.readlink(path),
8912
8965
  ...fs.realpath ? { realpath: fs.realpath.bind(fs) } : {},
8913
8966
  ...fs.chown ? { chown: fs.chown.bind(fs) } : {},
8967
+ ...fs.createExclusive ? { createExclusive: fs.createExclusive.bind(fs) } : {},
8914
8968
  ...fs.ancestry ? { ancestry: fs.ancestry.bind(fs) } : {},
8915
8969
  ...fs.hasOwner ? { hasOwner: fs.hasOwner.bind(fs) } : {},
8916
8970
  chmod: (path, mode) => fs.chmod(path, mode),
@@ -9210,6 +9264,7 @@ var FsWatchers = class {
9210
9264
  };
9211
9265
  const overrides = {
9212
9266
  writeFile: content(fs.writeFile.bind(fs)),
9267
+ ...fs.createExclusive ? { createExclusive: content(fs.createExclusive.bind(fs)) } : {},
9213
9268
  mkdir: async (path, options) => {
9214
9269
  const created3 = [];
9215
9270
  if (options?.recursive) {
@@ -9861,7 +9916,7 @@ var FifoTable = class {
9861
9916
  };
9862
9917
 
9863
9918
  // src/mount/protocol.ts
9864
- var DRIVER_PROTOCOL = [1, 2];
9919
+ var DRIVER_PROTOCOL = [1, 3];
9865
9920
  function driverVersionError(theirs) {
9866
9921
  const major = Array.isArray(theirs) ? theirs[0] : void 0;
9867
9922
  if (major === DRIVER_PROTOCOL[0]) return void 0;
@@ -10173,11 +10228,12 @@ function inodeless(mount, attr2) {
10173
10228
  }
10174
10229
  function statOf(attr2, path, mount) {
10175
10230
  const mtime = new Date(attr2.mtime);
10176
- const fallback = attr2.kind === "directory" ? 16877 : attr2.kind === "symlink" ? 41471 : 33188;
10231
+ const fallback = attr2.kind === "directory" ? 16877 : attr2.kind === "symlink" ? 41471 : attr2.kind === "fifo" ? 4516 : 33188;
10177
10232
  return {
10178
10233
  isFile: attr2.kind === "file",
10179
10234
  isDirectory: attr2.kind === "directory",
10180
10235
  isSymbolicLink: attr2.kind === "symlink",
10236
+ ...attr2.kind === "fifo" ? { isFifo: true } : {},
10181
10237
  size: attr2.size,
10182
10238
  mode: attr2.mode ?? fallback,
10183
10239
  mtime,
@@ -10720,7 +10776,7 @@ var MountFs = class _MountFs {
10720
10776
  }
10721
10777
  const { mount, rel: rel2 } = found;
10722
10778
  this.writable(mount, real);
10723
- if (owner?.fifo) throw errnoError("EPERM", `${real}: this mount has no FIFOs`);
10779
+ if (owner?.fifo) return this.mkfifo(found, real, owner);
10724
10780
  const bytes = typeof content === "string" ? new TextEncoder().encode(content) : content;
10725
10781
  if (mount.maxFile > 0 && bytes.length > mount.maxFile) {
10726
10782
  throw errnoError(
@@ -10737,6 +10793,18 @@ var MountFs = class _MountFs {
10737
10793
  }
10738
10794
  }
10739
10795
  }
10796
+ async mkfifo(found, real, owner) {
10797
+ const { mount, rel: rel2 } = found;
10798
+ if (!mount.caps.fifos) throw errnoError("EPERM", `${real}: this mount has no FIFOs`);
10799
+ const made2 = await this.driverOwner(found, real, owner, false);
10800
+ await this.table.commit(real);
10801
+ this.table.forget(mount, real);
10802
+ try {
10803
+ await mount.conn.call({ op: "mkfifo", path: rel2, ...made2 });
10804
+ } finally {
10805
+ this.table.forget(mount, real);
10806
+ }
10807
+ }
10740
10808
  async writeWhole(mount, real, rel2, bytes, owner) {
10741
10809
  await this.table.commit(real);
10742
10810
  this.table.forget(mount, real);
@@ -10906,6 +10974,23 @@ var MountFs = class _MountFs {
10906
10974
  throw err;
10907
10975
  }
10908
10976
  }
10977
+ async createExclusive(path, owner, redirects = 0) {
10978
+ const exclusive = this.base.createExclusive?.bind(this.base);
10979
+ if (!this.at(path) && exclusive) {
10980
+ return this.based(
10981
+ [path],
10982
+ redirects,
10983
+ () => exclusive(path, owner),
10984
+ ([to], n) => this.createExclusive(to, owner, n)
10985
+ );
10986
+ }
10987
+ const there = await this.lstat(path).then(
10988
+ () => true,
10989
+ () => false
10990
+ );
10991
+ if (there) throw errnoError("EEXIST", path);
10992
+ await this.writeFile(path, new Uint8Array(0), owner);
10993
+ }
10909
10994
  async lstat(path, redirects = 0) {
10910
10995
  const found = this.at(path);
10911
10996
  if (!found) {
@@ -16984,7 +17069,10 @@ var VfsNodes = class {
16984
17069
  return this.onEntry(path, async () => {
16985
17070
  const node = this.byPath.get(path);
16986
17071
  const held = node ? await node.serial(async () => node.holds()) : false;
16987
- if (held || await present2(this.fs, path)) throw fsError("EEXIST", path);
17072
+ if (held) throw fsError("EEXIST", path);
17073
+ const exclusive = this.fs.createExclusive;
17074
+ if (exclusive) return exclusive.call(this.fs, path, owner);
17075
+ if (await present2(this.fs, path)) throw fsError("EEXIST", path);
16988
17076
  await this.fs.writeFile(path, new Uint8Array(0), owner);
16989
17077
  });
16990
17078
  }
@@ -20746,6 +20834,9 @@ async function dispatch(h, req) {
20746
20834
  case "link":
20747
20835
  if (!h.link) throw fsError2("EPERM", "this file system has no hard links");
20748
20836
  return h.link(req.from, req.to);
20837
+ case "mkfifo":
20838
+ if (!h.mkfifo) throw fsError2("EPERM", "this file system has no FIFOs");
20839
+ return ownerOf2(req) ? h.mkfifo(req.path, ownerOf2(req)) : h.mkfifo(req.path);
20749
20840
  case "symlink":
20750
20841
  if (!h.symlink) throw fsError2("EPERM", "this file system has no symlinks");
20751
20842
  return ownerOf2(req) ? h.symlink(req.target, req.path, ownerOf2(req)) : h.symlink(req.target, req.path);
@@ -21987,7 +22078,7 @@ function owned3(node, change) {
21987
22078
  function attr(node) {
21988
22079
  return {
21989
22080
  kind: node.kind,
21990
- size: node.kind === "file" ? node.data.size : node.kind === "symlink" ? node.target.length : 4096,
22081
+ size: node.kind === "file" ? node.data.size : node.kind === "symlink" ? node.target.length : node.kind === "fifo" ? 0 : 4096,
21991
22082
  mtime: node.mtime,
21992
22083
  atime: node.atime,
21993
22084
  mode: node.mode,
@@ -22036,6 +22127,7 @@ function tmpfs() {
22036
22127
  const existing = dir.children.get(name2);
22037
22128
  if (existing && flags2.exclusive) throw fsError2("EEXIST", path);
22038
22129
  if (existing?.kind === "directory" && flags2.write) throw fsError2("EISDIR", path);
22130
+ if (existing?.kind === "fifo") throw fsError2("ENXIO", path);
22039
22131
  if (existing) return existing;
22040
22132
  if (!flags2.create) throw fsError2("ENOENT", path);
22041
22133
  const node = make("file", 33188, dir, flags2.owner);
@@ -22080,6 +22172,11 @@ function tmpfs() {
22080
22172
  handle(fh);
22081
22173
  handles.delete(fh);
22082
22174
  },
22175
+ async mkfifo(path, owner) {
22176
+ const { dir, name: name2 } = parent(path);
22177
+ if (dir.children.has(name2)) throw fsError2("EEXIST", path);
22178
+ place(dir, name2, make("fifo", 4516, dir, owner));
22179
+ },
22083
22180
  async mkdir(path, owner) {
22084
22181
  const { dir, name: name2 } = parent(path);
22085
22182
  if (dir.children.has(name2)) throw fsError2("EEXIST", path);
@@ -24457,6 +24554,7 @@ var Launcher = class {
24457
24554
  {
24458
24555
  symlinks: true,
24459
24556
  links: true,
24557
+ fifos: true,
24460
24558
  chmod: true,
24461
24559
  owners: true,
24462
24560
  linkTimes: true,