@ai-ecoverse/slicc-kernel 1.117.3 → 1.117.5

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;
@@ -4119,6 +4155,7 @@ var READ_ATTEMPTS = 3;
4119
4155
  var MAX_LINKS5 = 40;
4120
4156
  var CHECK_MS = 1e3;
4121
4157
  var ABSENT_MS = 2;
4158
+ var GLANCE_MS = 2;
4122
4159
  var ABSENT_NAMES = 4096;
4123
4160
  var FILE_HANDLES = 4096;
4124
4161
  var STALE = /* @__PURE__ */ new Set(["NotFoundError", "TypeMismatchError"]);
@@ -4255,7 +4292,7 @@ var OpfsFs = class {
4255
4292
  changes = 0;
4256
4293
  replacing = Promise.resolve();
4257
4294
  replacements = 0;
4258
- snapshots = /* @__PURE__ */ new WeakMap();
4295
+ glances = /* @__PURE__ */ new WeakMap();
4259
4296
  found = /* @__PURE__ */ new WeakMap();
4260
4297
  checked = /* @__PURE__ */ new WeakMap();
4261
4298
  channel;
@@ -4274,6 +4311,7 @@ var OpfsFs = class {
4274
4311
  this.lockPrefix = `slicc-excl:${channel ?? ""}:`;
4275
4312
  this.channel = channel === void 0 ? void 0 : new BroadcastChannel(channel);
4276
4313
  this.remote = channel === void 0 ? void 0 : new RemoteWatch(`${channel}:watch`);
4314
+ if (this.remote) this.remote.quiet = () => this.quiet();
4277
4315
  if (this.channel) {
4278
4316
  const remote = this.remote;
4279
4317
  meta.listen?.(
@@ -4417,8 +4455,24 @@ var OpfsFs = class {
4417
4455
  throw fsError("EROFS", path);
4418
4456
  }
4419
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
+ }
4420
4473
  async locked(physicalPath, op) {
4421
4474
  if (!this.locks) return op();
4475
+ if (this.remote && !await this.remote.peered()) return this.alone(op);
4422
4476
  const key = `${this.lockPrefix}${physicalPath}`;
4423
4477
  let result;
4424
4478
  await this.locks.request(key, async () => {
@@ -4509,7 +4563,7 @@ var OpfsFs = class {
4509
4563
  if (handle.kind !== "file") return handle;
4510
4564
  if (looked) {
4511
4565
  this.found.set(handle, performance.now());
4512
- this.snapshots.delete(handle);
4566
+ this.glances.delete(handle);
4513
4567
  }
4514
4568
  this.files.delete(path);
4515
4569
  if (this.files.size >= FILE_HANDLES)
@@ -4543,14 +4597,15 @@ var OpfsFs = class {
4543
4597
  const fresh2 = cached && performance.now() - (this.found.get(cached) ?? -CHECK_MS) < CHECK_MS;
4544
4598
  if (cached && !fresh2) this.files.delete(path);
4545
4599
  if (cached && fresh2) {
4600
+ if (this.glanced(cached)) return this.remember(path, cached);
4546
4601
  try {
4547
- this.snapshots.set(cached, await cached.getFile());
4602
+ await this.glance(cached);
4548
4603
  return this.remember(path, cached);
4549
4604
  } catch (err) {
4550
4605
  if (!STALE.has(err?.name))
4551
4606
  throw translate(err, path, "read");
4552
4607
  this.files.delete(path);
4553
- this.snapshots.delete(cached);
4608
+ this.glances.delete(cached);
4554
4609
  }
4555
4610
  }
4556
4611
  const kept = this.dirs.get(path);
@@ -4743,11 +4798,25 @@ var OpfsFs = class {
4743
4798
  if (this.dirTimes.get(path) === ms) this.dirTimes.delete(path);
4744
4799
  }
4745
4800
  }
4801
+ glanced(handle) {
4802
+ const seen = this.glances.get(handle);
4803
+ const fresh2 = seen && seen.changes === this.changes && performance.now() - seen.at < GLANCE_MS;
4804
+ return fresh2 ? seen.file : void 0;
4805
+ }
4806
+ async glance(handle) {
4807
+ const at = performance.now();
4808
+ const before = this.changes;
4809
+ const file = await handle.getFile();
4810
+ if (before === this.changes) this.glances.set(handle, { at, file, changes: before });
4811
+ else this.glances.delete(handle);
4812
+ return file;
4813
+ }
4814
+ wrote(handle) {
4815
+ this.changes++;
4816
+ this.glances.delete(handle);
4817
+ }
4746
4818
  async snapshot(handle) {
4747
- const taken = this.snapshots.get(handle);
4748
- if (!taken) return handle.getFile();
4749
- this.snapshots.delete(handle);
4750
- return taken;
4819
+ return this.glanced(handle) ?? this.glance(handle);
4751
4820
  }
4752
4821
  async statOf(path, handle, meta, touched) {
4753
4822
  const directory = handle.kind === "directory";
@@ -4882,9 +4951,11 @@ var OpfsFs = class {
4882
4951
  async pwrite(path, offset, bytes) {
4883
4952
  const [handle, , target] = await this.fileFor(path);
4884
4953
  await this.counting(target);
4954
+ this.wrote(handle);
4885
4955
  try {
4886
4956
  await this.retrying(path, () => positioned(handle, (io) => io.write(offset, bytes)), true);
4887
4957
  } finally {
4958
+ this.wrote(handle);
4888
4959
  await this.recounting(handle, target);
4889
4960
  }
4890
4961
  this.written(target);
@@ -4895,9 +4966,11 @@ var OpfsFs = class {
4895
4966
  const resolve2 = this.ranged || this.remote?.watched();
4896
4967
  const target = resolve2 || this.counted.length > 0 ? (await this.locate(path, true)).path : path;
4897
4968
  await this.counting(target);
4969
+ this.wrote(handle);
4898
4970
  try {
4899
4971
  await this.retrying(path, () => positioned(handle, (io) => io.truncate(size)), true);
4900
4972
  } finally {
4973
+ this.wrote(handle);
4901
4974
  await this.recounting(handle, target);
4902
4975
  }
4903
4976
  this.written(target);
@@ -4917,9 +4990,12 @@ var OpfsFs = class {
4917
4990
  throw translate(err, path, "write", false);
4918
4991
  }),
4919
4992
  close: async () => {
4993
+ this.wrote(handle);
4920
4994
  await writable2.close().catch((err) => {
4995
+ this.wrote(handle);
4921
4996
  throw translate(err, path, "commit", false);
4922
4997
  });
4998
+ this.wrote(handle);
4923
4999
  this.committed(target);
4924
5000
  }
4925
5001
  };
@@ -4966,6 +5042,7 @@ var OpfsFs = class {
4966
5042
  if (!existed) await this.stampNew(target, owner, false);
4967
5043
  if (!existed && content.length === 0) return;
4968
5044
  let writable2;
5045
+ this.wrote(file);
4969
5046
  try {
4970
5047
  writable2 = await file.createWritable();
4971
5048
  await writable2.write(content);
@@ -4973,6 +5050,8 @@ var OpfsFs = class {
4973
5050
  } catch (err) {
4974
5051
  await writable2?.abort().catch(() => void 0);
4975
5052
  throw translate(err, path, "commit", false);
5053
+ } finally {
5054
+ this.wrote(file);
4976
5055
  }
4977
5056
  this.committed(target);
4978
5057
  }
@@ -5226,7 +5305,7 @@ var OpfsFs = class {
5226
5305
  }
5227
5306
  async modified(path) {
5228
5307
  const handle = await this.handle(path);
5229
- return handle.kind === "file" ? (await handle.getFile()).lastModified : 0;
5308
+ return handle.kind === "file" ? (await this.snapshot(handle)).lastModified : 0;
5230
5309
  }
5231
5310
  async explicitTimes(path) {
5232
5311
  const timed2 = [];
@@ -6656,7 +6735,7 @@ function satisfies(version, range2) {
6656
6735
  }
6657
6736
 
6658
6737
  // src/version.ts
6659
- var KERNEL_VERSION = true ? "1.117.3" : "0.0.0-dev";
6738
+ var KERNEL_VERSION = true ? "1.117.5" : "0.0.0-dev";
6660
6739
  var OS_RELEASE = "6.0.0-slicc";
6661
6740
  function procVersion() {
6662
6741
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -8885,6 +8964,7 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
8885
8964
  readlink: (path) => fs.readlink(path),
8886
8965
  ...fs.realpath ? { realpath: fs.realpath.bind(fs) } : {},
8887
8966
  ...fs.chown ? { chown: fs.chown.bind(fs) } : {},
8967
+ ...fs.createExclusive ? { createExclusive: fs.createExclusive.bind(fs) } : {},
8888
8968
  ...fs.ancestry ? { ancestry: fs.ancestry.bind(fs) } : {},
8889
8969
  ...fs.hasOwner ? { hasOwner: fs.hasOwner.bind(fs) } : {},
8890
8970
  chmod: (path, mode) => fs.chmod(path, mode),
@@ -9184,6 +9264,7 @@ var FsWatchers = class {
9184
9264
  };
9185
9265
  const overrides = {
9186
9266
  writeFile: content(fs.writeFile.bind(fs)),
9267
+ ...fs.createExclusive ? { createExclusive: content(fs.createExclusive.bind(fs)) } : {},
9187
9268
  mkdir: async (path, options) => {
9188
9269
  const created3 = [];
9189
9270
  if (options?.recursive) {
@@ -10880,6 +10961,23 @@ var MountFs = class _MountFs {
10880
10961
  throw err;
10881
10962
  }
10882
10963
  }
10964
+ async createExclusive(path, owner, redirects = 0) {
10965
+ const exclusive = this.base.createExclusive?.bind(this.base);
10966
+ if (!this.at(path) && exclusive) {
10967
+ return this.based(
10968
+ [path],
10969
+ redirects,
10970
+ () => exclusive(path, owner),
10971
+ ([to], n) => this.createExclusive(to, owner, n)
10972
+ );
10973
+ }
10974
+ const there = await this.lstat(path).then(
10975
+ () => true,
10976
+ () => false
10977
+ );
10978
+ if (there) throw errnoError("EEXIST", path);
10979
+ await this.writeFile(path, new Uint8Array(0), owner);
10980
+ }
10883
10981
  async lstat(path, redirects = 0) {
10884
10982
  const found = this.at(path);
10885
10983
  if (!found) {
@@ -16958,7 +17056,10 @@ var VfsNodes = class {
16958
17056
  return this.onEntry(path, async () => {
16959
17057
  const node = this.byPath.get(path);
16960
17058
  const held = node ? await node.serial(async () => node.holds()) : false;
16961
- if (held || await present2(this.fs, path)) throw fsError("EEXIST", path);
17059
+ if (held) throw fsError("EEXIST", path);
17060
+ const exclusive = this.fs.createExclusive;
17061
+ if (exclusive) return exclusive.call(this.fs, path, owner);
17062
+ if (await present2(this.fs, path)) throw fsError("EEXIST", path);
16962
17063
  await this.fs.writeFile(path, new Uint8Array(0), owner);
16963
17064
  });
16964
17065
  }