@githolon/runtime 0.112.3 → 0.112.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.
@@ -11,7 +11,6 @@
11
11
  06525d62b18918913a7fe7981204fba9e1f70369cc2aa785851caae39f546de3 node_modules/@bufbuild/protobuf/dist/esm/wire/base64-encoding.js
12
12
  09a24ed660112991f8105d8c0c2c250617b6ad99f6a12afe2d39b8a9305289ec peer-office/src/runtime/session_directory.ts
13
13
  0a687d73d1754114045dd64ab0125af437945ed11b1302753b1c3c46793a014b peer-office/src/runtime/replica_follow_lane.ts
14
- 0aed53ba7b333581e2aab3f5e90444abdbaa8d3defdb11ae3d7ae475b869d36c platform-shells/browser/kernel_custody.ts
15
14
  0b2994ee1fee5c72c7f27881aea421bdb1757b0c8c4042f155c433015b0b2455 node_modules/@bufbuild/protobuf/dist/esm/codegenv2/scalar.js
16
15
  0b5eee51991554d54865ea30f65f8803c8dfe73116cd815676f927021329259a peer-office/src/runtime/credential_vault.ts
17
16
  0db0f42ba330749a7b05095ea1fd0ff63fd2b30e84cead30fe4c28359d15f194 node_modules/@bjorn3/browser_wasi_shim/dist/wasi_defs.js
@@ -27,11 +26,11 @@
27
26
  11ba369493cb754f09f8ef04f1235d64708a283cead2164bfd12679c940fcbe6 adapter/certification_seal.ts
28
27
  13418e92f08476ae029573738d8a74f8fb4d6cfd3d8f610d0512da9d44a3a20d peer-office/src/runtime/http_obligation_delivery.ts
29
28
  151e39e98e6d58e6453f6b9aab5f93af32cfe4e8e2915b71952a337145976049 peer-office/src/runtime/authoring_preflight.ts
29
+ 15a24c9133b37575f0e8d6a0db6a9e383b8ebb944d1929aab6694084eff85291 adapter/kernel_machine_desk.ts
30
30
  161a203d3e9f10a6de3ffa798f736f6aa157f0ab85a40c3f3d6a412729a105e2 peer-office/src/runtime/platform_effect_driver.ts
31
31
  168eb977a826f75ab0c39f9322f78cc58dbd5b233019ad1d6a7e940af8a7c4aa node_modules/@bjorn3/browser_wasi_shim/dist/wasi.js
32
32
  16d6522ee4ecf4a91c4d29357ebc874844c266f2ae89ef2a92ec2d391f3762e9 node_modules/is-unsafe/src/contexts/sql-strict.js
33
33
  17b0d228dd20748bd5fa03164478198c813214e4fa5d8f1650705128a954f0bd adapter/wasi_custody_filesystem.ts
34
- 1923aefdc23c6f66e5bc5b70c71b3fa66267738b3dcfa82a59ddecf7831152ef adapter/memory_custody_filesystem.ts
35
34
  1963a804a9cfe7d44a76b2c476817639b939d7e93828da865cab40fe9ba536fa adapter/custody-transport.ts
36
35
  1a5d9fd32360e2cec4adbee9e56221fb26def66bb9d122e0b5745cebc963d92e node_modules/xml-naming/src/index.js
37
36
  1b27a1f4d58d6314cd4887d0f47493d1a98fc474e3364388f321c3aeb94a8ac3 adapter/workspace_effect_outcome.ts
@@ -52,6 +51,7 @@
52
51
  25c033d29ed62a510d8c43054ec238776bcba0949808cb6054df5cbea951ddf7 adapter/proto/nomos/runtime/v2/interaction_desk_pb.js
53
52
  25d57b7e880708c04738087de674a8c98092e5bfd39d5193cdb63a2f1e33871e node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/compiler/plugin_pb.js
54
53
  27d164987aeae0cffae136eaa84ff39ca6efd9c07018dce4b63f0d352d3d855b adapter/proto/nomos/runtime/v2/maintenance_desk_pb.js
54
+ 27d996c3e9e0e5b3c45612da4588dd10cf1c7a0d3285e652c705c07e238a2b48 platform-shells/browser/custody_store.ts
55
55
  286c659a8f940c313077afe8a00c0dc128d4a138edf6d9a4519f29538b58c94f node_modules/fast-xml-parser/src/xmlparser/XMLParser.js
56
56
  2902315d1ae081647345f4e2aab7c8e60f8f8ae16de1a6c6e642ed6fd14e4959 peer-office/src/runtime/law_package_desk.ts
57
57
  29bf27cac2afa56801e728f9aeca4c6b7c281d7e602adb5a4c6d53bf0a79762b peer-office/src/runtime/correspondence_recovery.ts
@@ -72,7 +72,6 @@
72
72
  3c092b8d4185badd23ecf4552434d05aa541b0cd0d534781d687db55260d5da8 adapter/proto/nomos/runtime/v2/sealing_desk_pb.js
73
73
  3c98fa838c05abcfd8dfda1128f2d1fca9b196a371fe9751abbd8f4c3b9d04ec node_modules/@bufbuild/protobuf/dist/esm/wkt/timestamp.js
74
74
  3d05089a8c1008f20e06da9907eec7f8824f871edfc95e907c15dc8e2bdf43e7 node_modules/@bufbuild/protobuf/dist/esm/extensions.js
75
- 3e4d4f410f38ade5689895263df29265e13bb49c0760b82c565618082baed0a6 adapter/kernel_machine_desk.ts
76
75
  3eef60b7d08402d6a0b9427fde0308878929398918f09747833fd9a06ea3fa7d workspace-discovery/src/http.ts
77
76
  3fa38ca64538032d871cd44da41bf6a6ad2eb133b6b8ebc2d8b4d33615b00dcf peer-office/src/reception/application_session_pipe.ts
78
77
  3fade4f9262d10e39f346b57a7f08d03641e0ebd75556d087f6319f6c6003a24 peer-office/src/runtime/sha256.ts
@@ -84,7 +83,6 @@
84
83
  42242740dd3c09c2530972c6bc477e6aa2be2f91f6cdf112585eb1f1929721a7 peer-office/src/runtime/subscription_manager.ts
85
84
  437d1f7906925689d0329ee2f729786117903a5f9191a5a47faec67081ab6f6a peer-office/src/runtime/interaction_desk.ts
86
85
  44d54aa1500d8b179b56c47003530ade9220c0daec31caeeeb1a59760eca6d88 node_modules/fast-xml-builder/src/fxb.js
87
- 45f49fcf3773351a4983772c470e14e40baa392d148c991f92674c9fba1246b4 platform-shells/browser/custody_store.ts
88
86
  463a7041ce45ddd801fc0e0981bb11658b76bb44caad19d2971d73d7700d739b node_modules/@bufbuild/protobuf/dist/esm/wire/text-encoding.js
89
87
  46ce19f00a64198852937f4a982c59a5d237aeab590255873e131f2f0468e98e peer-office/src/runtime/workspace_opening.ts
90
88
  475e62094c73367833cec6253c5834a887cae9bcfa43a691a9fe3b7495c19106 node_modules/@bufbuild/protobuf/dist/esm/unknown-enum.js
@@ -107,6 +105,7 @@
107
105
  589afd70975c49b5d8856a85ffb597b1412f04b35b6234c324564d8640fcae15 node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/type_pb.js
108
106
  59ceb09d3fd2402e81ed7e5992245f2b398c7ceeb80141138f4eab5da0244586 node_modules/is-unsafe/src/contexts/redos.js
109
107
  59dd7fdcd3eac52054ff1edd4667fbadb66c851a66f60ec528f9db6421a0eed9 node_modules/@bufbuild/protobuf/dist/esm/codegenv2/restore-json-names.js
108
+ 5ac35f182ca8cdf2e187276f9c961a20799d7a2d64f3de3f5217d12ed3420890 peer-office/package/package.json
110
109
  5c47d871d691707bfa347b2c9199b433e277332ba4c523a4eb802d8c5cded105 peer-office/src/runtime/office_seat.ts
111
110
  5ce7673a392e7c11100428b040d6c9a08242021e33f859b2ad670edef31d80de node_modules/@bufbuild/protobuf/dist/esm/from-binary.js
112
111
  5cf55a0f51490590bf56e1ff2d6dd11002f8a8b43b0bc661d2cc15a6c6e0e981 adapter/git-fs.ts
@@ -163,10 +162,10 @@
163
162
  8ce60aff8226986c6ec652887c97a9515a2f10dd046596d76797cbdd0bb46e1d peer-office/src/runtime/remote_runtime_paper.ts
164
163
  8e033b086d23caeba4a8b2e69284b6448787884bb0978eddf67729569d268367 peer-office/src/runtime/credential_recovery_desk.ts
165
164
  8e73c652d2c41232e1a3217524dcdbbe7f26834d59cfe80e4432ec59a801dc42 peer-office/src/runtime/authentication_readiness_desk.ts
165
+ 8ee050cca65954e7962806818145a4cf0e9a7532362b96da0363c1d918c66e5d platform-shells/browser/kernel_custody.ts
166
166
  9109542ce7615df736d0b89b9562a0f8e989099aff65de707217d6a170591812 peer-office/src/runtime/read_maintenance_desk.ts
167
167
  92884553e5d2d46ea273441deb32dc07187dc8ded3524356fa68536d1f2fc435 node_modules/@bufbuild/protobuf/dist/esm/descriptors.js
168
168
  92aa7e4df3bf7dfc02235174f297dcbff6bd02f7eb6325876cbb24ada6d51414 node_modules/@bufbuild/protobuf/dist/esm/wire/text-format.js
169
- 9330a6cd8db9a2a6aee8d6511ec0f4e1b1dee8a6d2eac3bec39712c27127f8b6 platform-shells/browser/peer.ts
170
169
  939bd8b89505a4e9be6b8d60fed0479086c441d7ae50930986cf9657123e0524 peer-office/src/runtime_v2_codec.ts
171
170
  9471d4fa81aa8caafdf7fca7cff9563b047a5b1803883f5dd9b7df5241350fff peer-office/src/runtime/replica_follow_desk.ts
172
171
  94a3cef0f355a9a177661748d24faae32206a5cc382c8601a34dcf005340107b node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js
@@ -238,6 +237,7 @@ c41faf95c6c33b80349ff96f8127153672a6e6bf8bb9593f7aa67d2e2e642684 peer-office/sr
238
237
  c649d39c53ebe6817c71407de8105b6d8cbc2326867f90d59f49ab02d9271b44 node_modules/anynum/digitTable.js
239
238
  c6c85d892e445a8f84e9f628f2ac1ac6766103e90bb502ee9c101774831c4f0c peer-office/src/runtime/command_preparation_desk.ts
240
239
  c87f55e284241bdf08e06a54b09567c329e8cc24519dbd08f064d0230a19f8fd peer-office/src/runtime/correspondence_work_registry.ts
240
+ c884aa80ac787299da2ec4ebd930c78372d82e227363980cc6a3baf08daf1889 platform-shells/browser/peer.ts
241
241
  caa925cb881f7586e9e01f09325f09ebdecf742debbfff21eb7c4c49ea09ef02 node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/java_features_pb.js
242
242
  cb095614d5f901cd00d46b930a23c64ebd909a77831aa666768fca47f3e7745f node_modules/@bufbuild/protobuf/dist/esm/reflect/scalar.js
243
243
  cce0e8a8876bd1d3305a666e70cd556fd1ae57560fbca9f4ff0577d91178a0b1 node_modules/fast-xml-parser/src/xmlparser/node2json.js
@@ -268,7 +268,6 @@ e34016b82b6f6e4c4a1cc2dd44ccd14a348e8156a1f6c5aeeb2c7fc36a15b8f9 adapter/proto/
268
268
  e34016b82b6f6e4c4a1cc2dd44ccd14a348e8156a1f6c5aeeb2c7fc36a15b8f9 peer-office/package/src/protocol/nomos/kernel/v1/kernel_pb.js
269
269
  e394b7a580a2853949ec937d742b54fd8169029a5d10a3e4e521b984c60adb6d peer-office/src/runtime/identity_desk.ts
270
270
  e411cf95c1c0c7063b863a08ad568d61044069f9338028eace56e362029ad3a7 peer-office/src/runtime/residency_desk.ts
271
- e4406907e251677b130006208fa24b1537e8e8c0d54505685a90ce88bd109d81 peer-office/package/package.json
272
271
  e45a879696cd2e7b692aa282677abf216297c1d129135e914b8a76fd0cbe15bd peer-office/src/reception/generated_offer_counter.ts
273
272
  e8ef38f512bfa38f0a40c8edc32540040162576cccc229197a8fbd0c0097bb73 peer-office/src/runtime/history_acquisition_desk.ts
274
273
  eb9e106e81226ab9547882079e7fd6a9d885d2c71ba78784f7edaa7db61bb941 node_modules/is-unsafe/src/contexts/svg.js
@@ -277,6 +276,7 @@ ece435d3784d928d02bff4d015b7cb686f8c06de8536ff9f8ebc38a8f403a3be node_modules/@
277
276
  eda289d9ef0e979fe77a578ffbbf8012cadcfec4629b66cd98c27d6229a9f020 node_modules/@bufbuild/protobuf/dist/esm/is-message.js
278
277
  efce20f9f127263ca66d855115e01b37af0afb8b8baafeba7dcc2e0834e99e4f node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/struct_pb.js
279
278
  f23513db2fea432df6121956d9bab4761dabf8034b6eba8988452104dba1783e adapter/proto/nomos/runtime/v2/records_desk_pb.js
279
+ f3b65d81bf72f0cf4f8c6c36af75915e9146db35d590f1e51ffcececd4233147 adapter/memory_custody_filesystem.ts
280
280
  f3b9324922e08cffcc4c7ae3c6e08454f62e187a37404df31a00160cddf34d77 node_modules/@bufbuild/protobuf/dist/esm/reflect/guard.js
281
281
  f4eb625c1c0ebee8e5863b6958706af4635ca58d1d2544ae2b465e75060ba12c peer-office/src/runtime/placement_desk.ts
282
282
  f50218256bfd061c59b454fbaf8ca304f1799b1d0d09b0f7851ba2420e1129ca adapter/kernel_failure.ts
@@ -7847,10 +7847,10 @@
7847
7847
  // ../../platform-shells/browser/kernel_custody.ts
7848
7848
  init_define_NOMOS_KERNEL_RELEASE();
7849
7849
  init_shims();
7850
- function browserKernelCustody(kernel, checkpoint, isCheckpointCurrent) {
7850
+ function browserKernelCustody(kernel, checkpoint, isCheckpointCurrent, provisionedGenesisWorkspace) {
7851
7851
  return {
7852
7852
  canRetainChanges: () => true,
7853
- hasLocalCustody: (workspace) => kernel.branchHead(workspace, "main") !== void 0,
7853
+ hasLocalCustody: (workspace) => kernel.branchHead(workspace, "main") !== void 0 || workspace === provisionedGenesisWorkspace,
7854
7854
  openLocalCustody: async () => ({}),
7855
7855
  ledgerFor: () => {
7856
7856
  throw new Error("Browser Git custody is opened in place; there is no second local ledger");
@@ -9722,9 +9722,25 @@
9722
9722
  };
9723
9723
  return {
9724
9724
  preopen,
9725
- snapshot() {
9725
+ delta(previous, mutated, includePath = () => true, copyChanged = true) {
9726
+ const nodes = /* @__PURE__ */ new Map();
9727
+ const changed = [];
9728
+ const visit = (path, node) => {
9729
+ if (!includePath(path)) return;
9730
+ if (path !== "/work") {
9731
+ nodes.set(path, node);
9732
+ if (copyChanged && (previous.get(path) !== node || mutated.has(node)))
9733
+ changed.push({ path, ...node.data ? { bytes: node.data.slice() } : {} });
9734
+ }
9735
+ for (const [name, child] of node.contents ?? []) visit(`${path}/${name}`, child);
9736
+ };
9737
+ visit("/work", preopen.dir);
9738
+ return { nodes, changed, removed: [...previous.keys()].filter((path) => !nodes.has(path)) };
9739
+ },
9740
+ snapshot(includePath = () => true) {
9726
9741
  const entries = [];
9727
9742
  const visit = (path, node) => {
9743
+ if (!includePath(path)) return;
9728
9744
  if (path !== "/work") entries.push({ path, ...node.data ? { bytes: node.data.slice() } : {} });
9729
9745
  for (const [name, child] of node.contents ?? []) visit(`${path}/${name}`, child);
9730
9746
  };
@@ -9949,7 +9965,11 @@
9949
9965
  if (!original) continue;
9950
9966
  imports[name] = (...args) => {
9951
9967
  const result = original(...args);
9952
- if (result === 0 && !(name === "fd_write" && Number(args[0]) < 3) && !(name === "path_open" && (Number(args[4]) & 9) === 0)) onFilesystemMutation();
9968
+ if (result === 0 && !(name === "fd_write" && Number(args[0]) < 3) && !(name === "path_open" && (Number(args[4]) & 9) === 0)) {
9969
+ const fd = name === "path_open" ? new DataView(wasi.inst.exports.memory.buffer).getUint32(Number(args[8]) >>> 0, true) : Number(args[0]);
9970
+ const opened = wasi.fds[fd];
9971
+ onFilesystemMutation(opened instanceof OpenFile ? opened.file : void 0);
9972
+ }
9953
9973
  return result;
9954
9974
  };
9955
9975
  }
@@ -11377,8 +11397,10 @@
11377
11397
  init_define_NOMOS_KERNEL_RELEASE();
11378
11398
  init_shims();
11379
11399
  var copyRecord = (record) => ({ ...record, value: record.value.slice() });
11400
+ var currentCacheFile = (path) => path.endsWith("/nomos.git/nomos-cache/raw-frontier-v2/current.sqlite");
11401
+ var durableFile = (path) => !path.includes("/nomos.git/nomos-cache/raw-frontier-v2/addressed/") && !path.endsWith("/nomos.git/nomos-cache/raw-frontier-v2/addressed") && !currentCacheFile(path);
11380
11402
  var keyOf = (namespace, key) => JSON.stringify([namespace, key]);
11381
- var _backend, _records, _revision, _committed, _queued, _failure, _closed;
11403
+ var _backend, _records, _knownNodes, _mutatedNodes, _changedRecords, _cachePaths, _cacheDirty, _cacheDisabled, _cacheTimer, _cachePending, _revision, _committed, _queued, _failure, _closed;
11382
11404
  var _BrowserCustodyStore = class _BrowserCustodyStore {
11383
11405
  constructor(backend, snapshot) {
11384
11406
  __publicField(this, "filesystem", memoryCustodyFilesystem());
@@ -11386,26 +11408,46 @@
11386
11408
  __publicField(this, "identity");
11387
11409
  __privateAdd(this, _backend);
11388
11410
  __privateAdd(this, _records, /* @__PURE__ */ new Map());
11411
+ __privateAdd(this, _knownNodes, /* @__PURE__ */ new Map());
11412
+ __privateAdd(this, _mutatedNodes, /* @__PURE__ */ new Set());
11413
+ __privateAdd(this, _changedRecords, /* @__PURE__ */ new Map());
11414
+ __privateAdd(this, _cachePaths, /* @__PURE__ */ new Set());
11415
+ __privateAdd(this, _cacheDirty, false);
11416
+ __privateAdd(this, _cacheDisabled, false);
11417
+ __privateAdd(this, _cacheTimer);
11418
+ __privateAdd(this, _cachePending);
11389
11419
  __privateAdd(this, _revision, 0);
11390
11420
  __privateAdd(this, _committed, -1);
11391
11421
  __privateAdd(this, _queued);
11392
11422
  __privateAdd(this, _failure);
11393
11423
  __privateAdd(this, _closed, false);
11394
- __publicField(this, "changed", () => {
11424
+ __publicField(this, "changed", (inode) => {
11395
11425
  this.assertUsable();
11426
+ if (inode) __privateGet(this, _mutatedNodes).add(inode);
11396
11427
  __privateWrapper(this, _revision)._++;
11428
+ if (__privateGet(this, _backend).commitCache && !__privateGet(this, _cacheDisabled)) {
11429
+ __privateSet(this, _cacheDirty, true);
11430
+ if (!__privateGet(this, _cacheTimer)) __privateSet(this, _cacheTimer, setTimeout(() => {
11431
+ __privateSet(this, _cacheTimer, void 0);
11432
+ void this.flushCache().catch(() => {
11433
+ });
11434
+ }, 3e4));
11435
+ __privateGet(this, _cacheTimer).unref?.();
11436
+ }
11397
11437
  void this.checkpoint().catch(() => {
11398
11438
  });
11399
11439
  });
11400
11440
  __privateSet(this, _backend, backend);
11401
- if (snapshot && snapshot.format !== 1) throw new Error("Unsupported browser custody format; keep this site's data and update the application.");
11441
+ if (snapshot && snapshot.format !== 2) throw new Error("Unsupported browser custody format; keep this site's data and update the application.");
11402
11442
  this.replica = snapshot?.replica ?? globalThis.crypto.getRandomValues(new BigUint64Array(1))[0] & (1n << 63n) - 1n;
11403
11443
  this.identity = snapshot?.identity ?? `browser-${globalThis.crypto.randomUUID()}`;
11404
11444
  for (const entry of snapshot?.files ?? []) {
11405
11445
  if (entry.bytes === void 0) this.filesystem.files.mkdir(entry.path);
11406
11446
  else this.filesystem.files.writeFile(entry.path, entry.bytes);
11447
+ if (currentCacheFile(entry.path)) __privateGet(this, _cachePaths).add(entry.path);
11407
11448
  }
11408
11449
  for (const record of snapshot?.records ?? []) __privateGet(this, _records).set(keyOf(record.namespace, record.key), copyRecord(record));
11450
+ __privateSet(this, _knownNodes, new Map(this.filesystem.delta(/* @__PURE__ */ new Map(), /* @__PURE__ */ new Set(), durableFile, false).nodes));
11409
11451
  for (const name of ["mkdir", "writeFile", "unlink"]) {
11410
11452
  const original = this.filesystem.files[name].bind(this.filesystem.files);
11411
11453
  this.filesystem.files[name] = (...args) => {
@@ -11416,20 +11458,15 @@
11416
11458
  };
11417
11459
  }
11418
11460
  const promises = this.filesystem.fs.promises;
11419
- const mkdir = promises.mkdir.bind(promises);
11420
- const writeFile = promises.writeFile.bind(promises);
11421
- promises.mkdir = async (path) => {
11422
- this.assertUsable();
11423
- const result = await mkdir(path);
11424
- this.changed();
11425
- return result;
11426
- };
11427
- promises.writeFile = async (path, bytes) => {
11428
- this.assertUsable();
11429
- const result = await writeFile(path, bytes);
11430
- this.changed();
11431
- return result;
11432
- };
11461
+ for (const name of ["mkdir", "writeFile", "unlink", "rmdir"]) {
11462
+ const original = promises[name].bind(promises);
11463
+ promises[name] = async (...args) => {
11464
+ this.assertUsable();
11465
+ const result = await original(...args);
11466
+ this.changed();
11467
+ return result;
11468
+ };
11469
+ }
11433
11470
  }
11434
11471
  static async open(backend) {
11435
11472
  try {
@@ -11455,6 +11492,7 @@
11455
11492
  const next = value === void 0 ? void 0 : { namespace, key, revision: (current?.revision ?? 0n) + 1n, value: value.slice() };
11456
11493
  if (next) __privateGet(this, _records).set(id, next);
11457
11494
  else __privateGet(this, _records).delete(id);
11495
+ __privateGet(this, _changedRecords).set(id, next && copyRecord(next));
11458
11496
  this.changed();
11459
11497
  return next && copyRecord(next);
11460
11498
  }
@@ -11464,14 +11502,19 @@
11464
11502
  __privateSet(this, _queued, Promise.resolve().then(async () => {
11465
11503
  while (__privateGet(this, _committed) !== __privateGet(this, _revision)) {
11466
11504
  const revision = __privateGet(this, _revision);
11467
- const snapshot = {
11468
- format: 1,
11469
- replica: this.replica,
11470
- identity: this.identity,
11471
- files: this.filesystem.snapshot(),
11472
- records: [...__privateGet(this, _records).values()].map(copyRecord)
11473
- };
11474
- await __privateGet(this, _backend).commit(snapshot);
11505
+ const delta = this.filesystem.delta(__privateGet(this, _knownNodes), __privateGet(this, _mutatedNodes), durableFile);
11506
+ __privateGet(this, _mutatedNodes).clear();
11507
+ const records = [...__privateGet(this, _changedRecords).values()].filter((record) => record !== void 0).map(copyRecord);
11508
+ const removedRecords = [...__privateGet(this, _changedRecords).entries()].filter(([, record]) => record === void 0).map(([id]) => id);
11509
+ __privateGet(this, _changedRecords).clear();
11510
+ await __privateGet(this, _backend).commit({
11511
+ control: { format: 2, replica: this.replica, identity: this.identity },
11512
+ files: delta.changed,
11513
+ removedFiles: delta.removed,
11514
+ records,
11515
+ removedRecords
11516
+ });
11517
+ __privateSet(this, _knownNodes, new Map(delta.nodes));
11475
11518
  __privateSet(this, _committed, revision);
11476
11519
  }
11477
11520
  }).catch((error) => {
@@ -11488,14 +11531,41 @@
11488
11531
  isCheckpointCurrent() {
11489
11532
  return !__privateGet(this, _failure) && !__privateGet(this, _closed) && __privateGet(this, _committed) === __privateGet(this, _revision);
11490
11533
  }
11534
+ async flushCache() {
11535
+ if (__privateGet(this, _cachePending)) await __privateGet(this, _cachePending);
11536
+ if (!__privateGet(this, _backend).commitCache || !__privateGet(this, _cacheDirty) || __privateGet(this, _cacheDisabled)) return;
11537
+ __privateSet(this, _cacheDirty, false);
11538
+ const paths = new Set(this.filesystem.files.listFiles("/work").filter(currentCacheFile));
11539
+ const files = [...paths].map((path) => ({ path, bytes: this.filesystem.files.readFile(path) }));
11540
+ const removed = [...__privateGet(this, _cachePaths)].filter((path) => !paths.has(path));
11541
+ __privateSet(this, _cachePending, __privateGet(this, _backend).commitCache(files, removed).then(() => {
11542
+ __privateSet(this, _cachePaths, paths);
11543
+ }).catch(() => {
11544
+ __privateSet(this, _cacheDisabled, true);
11545
+ }).finally(() => {
11546
+ __privateSet(this, _cachePending, void 0);
11547
+ }));
11548
+ await __privateGet(this, _cachePending);
11549
+ }
11491
11550
  async close() {
11492
11551
  await this.checkpoint();
11552
+ if (__privateGet(this, _cacheTimer)) clearTimeout(__privateGet(this, _cacheTimer));
11553
+ __privateSet(this, _cacheTimer, void 0);
11554
+ await this.flushCache();
11493
11555
  __privateSet(this, _closed, true);
11494
11556
  __privateGet(this, _backend).close();
11495
11557
  }
11496
11558
  };
11497
11559
  _backend = new WeakMap();
11498
11560
  _records = new WeakMap();
11561
+ _knownNodes = new WeakMap();
11562
+ _mutatedNodes = new WeakMap();
11563
+ _changedRecords = new WeakMap();
11564
+ _cachePaths = new WeakMap();
11565
+ _cacheDirty = new WeakMap();
11566
+ _cacheDisabled = new WeakMap();
11567
+ _cacheTimer = new WeakMap();
11568
+ _cachePending = new WeakMap();
11499
11569
  _revision = new WeakMap();
11500
11570
  _committed = new WeakMap();
11501
11571
  _queued = new WeakMap();
@@ -11527,8 +11597,28 @@
11527
11597
  let db;
11528
11598
  try {
11529
11599
  db = await new Promise((resolve, reject) => {
11530
- const request = indexedDB.open(name, 1);
11531
- request.onupgradeneeded = () => request.result.createObjectStore("custody");
11600
+ const request = indexedDB.open(name, 3);
11601
+ request.onupgradeneeded = (event) => {
11602
+ const database = request.result;
11603
+ if (!database.objectStoreNames.contains("custody")) database.createObjectStore("custody");
11604
+ if (!database.objectStoreNames.contains("files")) database.createObjectStore("files");
11605
+ if (!database.objectStoreNames.contains("records")) database.createObjectStore("records");
11606
+ if (!database.objectStoreNames.contains("cache")) database.createObjectStore("cache");
11607
+ if (event.oldVersion === 2) {
11608
+ const files = request.transaction.objectStore("files");
11609
+ const cache = request.transaction.objectStore("cache");
11610
+ const cursor = files.openCursor();
11611
+ cursor.onsuccess = () => {
11612
+ const entry = cursor.result;
11613
+ if (!entry) return;
11614
+ if (Array.isArray(entry.key) && currentCacheFile(String(entry.key[0]))) {
11615
+ cache.put(entry.value, entry.key);
11616
+ entry.delete();
11617
+ }
11618
+ entry.continue();
11619
+ };
11620
+ }
11621
+ };
11532
11622
  request.onsuccess = () => resolve(request.result);
11533
11623
  request.onerror = () => reject(request.error);
11534
11624
  request.onblocked = () => reject(new Error("Browser custody upgrade is blocked by another tab. Close it and retry."));
@@ -11537,19 +11627,148 @@
11537
11627
  release();
11538
11628
  throw error;
11539
11629
  }
11630
+ const chunkBytes = 4 * 1024 * 1024;
11631
+ const replace = (store, id, entry) => {
11632
+ const old = store.get([id, -1]);
11633
+ old.onsuccess = () => {
11634
+ const count = Number(old.result?.chunks ?? 0);
11635
+ for (let index = 0; index < count; index++) store.delete([id, index]);
11636
+ store.delete([id, -1]);
11637
+ if (!entry) return;
11638
+ const bytes = "path" in entry ? entry.bytes : entry.value;
11639
+ const chunks = bytes === void 0 ? 0 : Math.max(1, Math.ceil(bytes.byteLength / chunkBytes));
11640
+ const meta = "path" in entry ? { path: entry.path, directory: bytes === void 0, chunks } : { namespace: entry.namespace, key: entry.key, revision: entry.revision, chunks };
11641
+ store.put(meta, [id, -1]);
11642
+ for (let index = 0; index < chunks; index++)
11643
+ store.put(bytes.slice(index * chunkBytes, (index + 1) * chunkBytes), [id, index]);
11644
+ };
11645
+ };
11646
+ const completeChunks = (chunks, count) => Number.isSafeInteger(count) && count >= 0 && chunks.length === count && Array.from({ length: count }, (_, index) => chunks[index]).every((chunk) => chunk instanceof Uint8Array);
11647
+ const readState = () => new Promise((resolve, reject) => {
11648
+ const tx = db.transaction(["custody", "files", "records", "cache"], "readonly");
11649
+ const control = tx.objectStore("custody").get("current");
11650
+ const files = tx.objectStore("files").getAll();
11651
+ const fileKeys = tx.objectStore("files").getAllKeys();
11652
+ const records = tx.objectStore("records").getAll();
11653
+ const recordKeys = tx.objectStore("records").getAllKeys();
11654
+ const caches = tx.objectStore("cache").getAll();
11655
+ const cacheKeys = tx.objectStore("cache").getAllKeys();
11656
+ tx.oncomplete = () => {
11657
+ try {
11658
+ if (!control.result) {
11659
+ resolve(void 0);
11660
+ return;
11661
+ }
11662
+ if (control.result.format !== 2) {
11663
+ reject(new Error("Unsupported browser custody format"));
11664
+ return;
11665
+ }
11666
+ const fileValues = /* @__PURE__ */ new Map();
11667
+ for (let index = 0; index < fileKeys.result.length; index++) {
11668
+ const [path, chunk] = fileKeys.result[index];
11669
+ const value = fileValues.get(path) ?? { chunks: [] };
11670
+ if (chunk === -1) value.meta = files.result[index];
11671
+ else value.chunks[chunk] = files.result[index];
11672
+ fileValues.set(path, value);
11673
+ }
11674
+ for (let index = 0; index < cacheKeys.result.length; index++) {
11675
+ const [path, chunk] = cacheKeys.result[index];
11676
+ const value = fileValues.get(path) ?? { chunks: [] };
11677
+ if (chunk === -1) value.meta = caches.result[index];
11678
+ else value.chunks[chunk] = caches.result[index];
11679
+ fileValues.set(path, value);
11680
+ }
11681
+ const image = [...fileValues].map(([path, value]) => {
11682
+ if (!value.meta) throw new Error(`Missing browser custody file metadata: ${path}`);
11683
+ if (value.meta.directory) return { path };
11684
+ if (!completeChunks(value.chunks, value.meta.chunks))
11685
+ throw new Error(`Incomplete browser custody file: ${path}`);
11686
+ const length = value.chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);
11687
+ const bytes = new Uint8Array(length);
11688
+ let offset = 0;
11689
+ for (const chunk of value.chunks) {
11690
+ bytes.set(chunk, offset);
11691
+ offset += chunk.byteLength;
11692
+ }
11693
+ return { path, bytes };
11694
+ }).sort((a, b) => a.path.split("/").length - b.path.split("/").length || a.path.localeCompare(b.path));
11695
+ const recordValues = /* @__PURE__ */ new Map();
11696
+ for (let index = 0; index < recordKeys.result.length; index++) {
11697
+ const [id, chunk] = recordKeys.result[index];
11698
+ const value = recordValues.get(id) ?? { chunks: [] };
11699
+ if (chunk === -1) value.meta = records.result[index];
11700
+ else value.chunks[chunk] = records.result[index];
11701
+ recordValues.set(id, value);
11702
+ }
11703
+ const restoredRecords = [...recordValues].map(([id, value]) => {
11704
+ if (!value.meta || !completeChunks(value.chunks, value.meta.chunks))
11705
+ throw new Error(`Incomplete browser custody record: ${id}`);
11706
+ const length = value.chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);
11707
+ const bytes = new Uint8Array(length);
11708
+ let offset = 0;
11709
+ for (const chunk of value.chunks) {
11710
+ bytes.set(chunk, offset);
11711
+ offset += chunk.byteLength;
11712
+ }
11713
+ return { namespace: value.meta.namespace, key: value.meta.key, revision: value.meta.revision, value: bytes };
11714
+ });
11715
+ resolve({ ...control.result, files: image, records: restoredRecords });
11716
+ } catch (error) {
11717
+ reject(error);
11718
+ }
11719
+ };
11720
+ tx.onabort = () => reject(tx.error ?? new Error("Browser custody read aborted"));
11721
+ });
11722
+ const migrate = async () => new Promise((resolve, reject) => {
11723
+ const tx = db.transaction(["custody", "files", "records", "cache"], "readwrite", { durability: "strict" });
11724
+ const control = tx.objectStore("custody");
11725
+ const read = control.get("current");
11726
+ read.onsuccess = () => {
11727
+ const snapshot = read.result;
11728
+ if (!snapshot || snapshot.format === 2) return;
11729
+ if (snapshot.format !== 1) {
11730
+ tx.abort();
11731
+ return;
11732
+ }
11733
+ for (const file of snapshot.files) {
11734
+ if (durableFile(file.path)) replace(tx.objectStore("files"), file.path, file);
11735
+ else if (currentCacheFile(file.path)) replace(tx.objectStore("cache"), file.path, file);
11736
+ }
11737
+ for (const record of snapshot.records) replace(tx.objectStore("records"), keyOf(record.namespace, record.key), record);
11738
+ control.put({ format: 2, replica: snapshot.replica, identity: snapshot.identity }, "current");
11739
+ };
11740
+ tx.oncomplete = () => resolve();
11741
+ tx.onabort = () => reject(tx.error ?? new Error("Browser custody migration aborted"));
11742
+ });
11743
+ try {
11744
+ await migrate();
11745
+ } catch (error) {
11746
+ db.close();
11747
+ release();
11748
+ throw error;
11749
+ }
11540
11750
  return BrowserCustodyStore.open({
11541
- load: () => new Promise((resolve, reject) => {
11542
- const tx = db.transaction("custody", "readonly");
11543
- const read = tx.objectStore("custody").get("current");
11544
- tx.oncomplete = () => resolve(read.result);
11545
- tx.onabort = () => reject(tx.error ?? new Error("Browser custody read aborted"));
11546
- }),
11547
- commit: (snapshot) => new Promise((resolve, reject) => {
11548
- const tx = db.transaction("custody", "readwrite", { durability: "strict" });
11549
- tx.objectStore("custody").put(snapshot, "current");
11751
+ load: readState,
11752
+ commit: (change) => new Promise((resolve, reject) => {
11753
+ const tx = db.transaction(["custody", "files", "records"], "readwrite", { durability: "strict" });
11754
+ const files = tx.objectStore("files");
11755
+ const records = tx.objectStore("records");
11756
+ for (const path of change.removedFiles) replace(files, path);
11757
+ for (const file of change.files) replace(files, file.path, file);
11758
+ for (const id of change.removedRecords) replace(records, id);
11759
+ for (const record of change.records) replace(records, keyOf(record.namespace, record.key), record);
11760
+ tx.objectStore("custody").put(change.control, "current");
11550
11761
  tx.oncomplete = () => resolve();
11551
11762
  tx.onabort = () => reject(tx.error ?? new Error("Browser custody transaction aborted"));
11552
11763
  }),
11764
+ commitCache: (cacheFiles, removedFiles) => new Promise((resolve, reject) => {
11765
+ const tx = db.transaction("cache", "readwrite", { durability: "relaxed" });
11766
+ const cache = tx.objectStore("cache");
11767
+ for (const path of removedFiles) replace(cache, path);
11768
+ for (const file of cacheFiles) replace(cache, file.path, file);
11769
+ tx.oncomplete = () => resolve();
11770
+ tx.onabort = () => reject(tx.error ?? new Error("Browser cache checkpoint aborted"));
11771
+ }),
11553
11772
  close: () => {
11554
11773
  db.close();
11555
11774
  release();
@@ -35031,9 +35250,10 @@
35031
35250
  replica: options.replica ?? storage.replica,
35032
35251
  trustRootPublicKey: options.trustRootPublicKey
35033
35252
  }, storage.filesystem, storage.changed);
35034
- const kernel = kernelExecutionDesk(machine);
35253
+ const physicalKernel = kernelExecutionDesk(machine);
35254
+ const kernel = options.observeKernel?.(physicalKernel) ?? physicalKernel;
35035
35255
  const custodyDesk = gitCustodyDesk(kernel, fetchImpl);
35036
- const kernelStore = browserKernelCustody(kernel, () => storage.checkpoint(), () => storage.isCheckpointCurrent());
35256
+ const kernelStore = browserKernelCustody(kernel, () => storage.checkpoint(), () => storage.isCheckpointCurrent(), options.provisionedGenesisWorkspace);
35037
35257
  const physical = withWorkspaceDiscovery(kernelStore, {
35038
35258
  providers: options.discoveryProviders ?? [options.base],
35039
35259
  fetch: (input, init) => fetchImpl(input, init)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@githolon/runtime",
3
- "version": "0.112.3",
3
+ "version": "0.112.5",
4
4
  "type": "module",
5
5
  "description": "The portable Nomos application runtime, reception contracts, and Node/browser runners.",
6
6
  "license": "SEE LICENSE IN LICENSE.md",