@fireproof/core 0.19.9-dev-frag → 0.19.11-dev-dryrun2

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.
Files changed (48) hide show
  1. package/README.md +27 -0
  2. package/{chunk-YS4GL6OK.js → chunk-OFGPKRCM.js} +30 -6
  3. package/chunk-OFGPKRCM.js.map +1 -0
  4. package/{chunk-JO5AVWG7.js → chunk-WS3YRPIA.js} +14 -6
  5. package/chunk-WS3YRPIA.js.map +1 -0
  6. package/deno.json +20 -0
  7. package/{gateway-YSNUK2L3.js → gateway-5FCWPX5W.js} +4 -5
  8. package/{gateway-YSNUK2L3.js.map → gateway-5FCWPX5W.js.map} +1 -1
  9. package/{gateway-IZRHJWPE.js → gateway-H7UD6TNB.js} +3 -4
  10. package/gateway-H7UD6TNB.js.map +1 -0
  11. package/index.cjs +468 -338
  12. package/index.cjs.map +1 -1
  13. package/index.d.cts +80 -52
  14. package/index.d.ts +80 -52
  15. package/index.global.js +21378 -15079
  16. package/index.global.js.map +1 -1
  17. package/index.js +389 -293
  18. package/index.js.map +1 -1
  19. package/{key-bag-file-NMEBFSPM.js → key-bag-file-WADZBHYG.js} +3 -3
  20. package/{key-bag-indexdb-X5V6GNBZ.js → key-bag-indexdb-PGVAI3FJ.js} +3 -3
  21. package/key-bag-indexdb-PGVAI3FJ.js.map +1 -0
  22. package/{mem-filesystem-B6C6QOIP.js → mem-filesystem-YPPJV7Q2.js} +3 -3
  23. package/metafile-cjs.json +1 -1
  24. package/metafile-esm.json +1 -1
  25. package/metafile-iife.json +1 -1
  26. package/{node-filesystem-5JLBSHKQ.js → node-filesystem-INX4ZTHE.js} +8 -4
  27. package/node-filesystem-INX4ZTHE.js.map +1 -0
  28. package/package.json +8 -5
  29. package/tests/blockstore/keyed-crypto.test.ts +34 -4
  30. package/tests/blockstore/store.test.ts +18 -13
  31. package/tests/fireproof/all-gateway.test.ts +394 -0
  32. package/tests/fireproof/cars/bafkreidxwt2nhvbl4fnqfw3ctlt6zbrir4kqwmjo5im6rf4q5si27kgo2i.car +0 -0
  33. package/tests/fireproof/cars/bafkreidxwt2nhvbl4fnqfw3ctlt6zbrir4kqwmjo5im6rf4q5si27kgo2i.ts +316 -0
  34. package/tests/fireproof/fireproof.test.ts +18 -18
  35. package/tests/fireproof/hello.test.ts +33 -19
  36. package/tests/fireproof/utils.test.ts +19 -0
  37. package/tests/helpers.ts +7 -4
  38. package/tests/www/todo-local.html +1 -1
  39. package/tests/www/todo.html +12 -15
  40. package/{utils-IZPK4QS7.js → utils-QO2HIWGI.js} +3 -3
  41. package/chunk-JO5AVWG7.js.map +0 -1
  42. package/chunk-YS4GL6OK.js.map +0 -1
  43. package/gateway-IZRHJWPE.js.map +0 -1
  44. package/key-bag-indexdb-X5V6GNBZ.js.map +0 -1
  45. package/node-filesystem-5JLBSHKQ.js.map +0 -1
  46. /package/{key-bag-file-NMEBFSPM.js.map → key-bag-file-WADZBHYG.js.map} +0 -0
  47. /package/{mem-filesystem-B6C6QOIP.js.map → mem-filesystem-YPPJV7Q2.js.map} +0 -0
  48. /package/{utils-IZPK4QS7.js.map → utils-QO2HIWGI.js.map} +0 -0
package/index.cjs CHANGED
@@ -117,6 +117,21 @@ function ensureLogger(sthis, componentName, ctx) {
117
117
  sthis.env.onSet(
118
118
  (key, value) => {
119
119
  switch (key) {
120
+ case "FP_FORMAT": {
121
+ switch (value) {
122
+ case "jsonice":
123
+ logger.SetFormatter(new import_cement.JSONFormatter(logger.TxtEnDe(), 2));
124
+ break;
125
+ case "yaml":
126
+ logger.SetFormatter(new import_cement.YAMLFormatter(logger.TxtEnDe(), 2));
127
+ break;
128
+ case "json":
129
+ default:
130
+ logger.SetFormatter(new import_cement.JSONFormatter(logger.TxtEnDe()));
131
+ break;
132
+ }
133
+ break;
134
+ }
120
135
  case "FP_DEBUG":
121
136
  logger.SetDebug(value || []);
122
137
  break;
@@ -125,6 +140,7 @@ function ensureLogger(sthis, componentName, ctx) {
125
140
  break;
126
141
  }
127
142
  },
143
+ "FP_FORMAT",
128
144
  "FP_DEBUG",
129
145
  "FP_STACK"
130
146
  );
@@ -170,9 +186,6 @@ function getName(sthis, url) {
170
186
  }
171
187
  return result;
172
188
  }
173
- function exception2Result(fn) {
174
- return fn().then((value) => import_cement.Result.Ok(value)).catch((e) => import_cement.Result.Err(e));
175
- }
176
189
  async function exceptionWrapper(fn) {
177
190
  return fn().catch((e) => import_cement.Result.Err(e));
178
191
  }
@@ -230,6 +243,16 @@ var init_utils = __esm({
230
243
  bin
231
244
  };
232
245
  }
246
+ timeOrderedNextId(now) {
247
+ now = typeof now === "number" ? now : (/* @__PURE__ */ new Date()).getTime();
248
+ const t = (281474976710656 + now).toString(16).replace(/^1/, "");
249
+ const bin = this.crypto.randomBytes(10);
250
+ bin[1] = bin[1] & 240 | (bin[1] | 8 && 11);
251
+ const hex = Array.from(bin).map((i) => i.toString(16).padStart(2, "0")).join("");
252
+ return {
253
+ str: `${t.slice(0, 8)}-${t.slice(8)}-7${hex.slice(0, 3)}-${hex.slice(3, 7)}-${hex.slice(7, 19)}`
254
+ };
255
+ }
233
256
  start() {
234
257
  return Promise.resolve();
235
258
  }
@@ -318,11 +341,12 @@ var node_filesystem_exports = {};
318
341
  __export(node_filesystem_exports, {
319
342
  NodeFileSystem: () => NodeFileSystem
320
343
  });
321
- var NodeFileSystem;
344
+ var import_cement4, NodeFileSystem;
322
345
  var init_node_filesystem = __esm({
323
346
  "src/runtime/gateways/file/node-filesystem.ts"() {
324
347
  "use strict";
325
348
  init_utils2();
349
+ import_cement4 = require("@adviser/cement");
326
350
  NodeFileSystem = class {
327
351
  async start() {
328
352
  this.fs = await import("fs/promises");
@@ -351,6 +375,9 @@ var init_node_filesystem = __esm({
351
375
  return this.fs?.unlink(path);
352
376
  }
353
377
  async writefile(path, data) {
378
+ if ((0, import_cement4.runtimeFn)().isDeno) {
379
+ return this.fs?.writeFile(path, data);
380
+ }
354
381
  return this.fs?.writeFile(path, Buffer.from(data));
355
382
  }
356
383
  };
@@ -375,11 +402,19 @@ async function getFileSystem(url) {
375
402
  fs2 = new MemFileSystem2();
376
403
  }
377
404
  break;
378
- case "node":
379
- case "sys":
380
- default: {
405
+ // case 'deno': {
406
+ // const { DenoFileSystem } = await import("./deno-filesystem.js");
407
+ // fs = new DenoFileSystem();
408
+ // break;
409
+ // }
410
+ case "node": {
381
411
  const { NodeFileSystem: NodeFileSystem2 } = await Promise.resolve().then(() => (init_node_filesystem(), node_filesystem_exports));
382
412
  fs2 = new NodeFileSystem2();
413
+ break;
414
+ }
415
+ case "sys":
416
+ default: {
417
+ return getFileSystem(url.build().setParam("fs", "node").URI());
383
418
  }
384
419
  }
385
420
  return fs2.start();
@@ -489,16 +524,16 @@ var key_bag_indexdb_exports = {};
489
524
  __export(key_bag_indexdb_exports, {
490
525
  KeyBagProviderIndexDB: () => KeyBagProviderIndexDB
491
526
  });
492
- var import_idb, import_cement4, KeyBagProviderIndexDB;
527
+ var import_idb, import_cement5, KeyBagProviderIndexDB;
493
528
  var init_key_bag_indexdb = __esm({
494
529
  "src/runtime/key-bag-indexdb.ts"() {
495
530
  "use strict";
496
531
  import_idb = require("idb");
497
532
  init_utils2();
498
- import_cement4 = require("@adviser/cement");
533
+ import_cement5 = require("@adviser/cement");
499
534
  KeyBagProviderIndexDB = class {
500
535
  constructor(url, sthis) {
501
- this._db = new import_cement4.ResolveOnce();
536
+ this._db = new import_cement5.ResolveOnce();
502
537
  this.sthis = sthis;
503
538
  this.logger = sthis.logger;
504
539
  this.url = url;
@@ -552,15 +587,15 @@ __export(gateway_exports, {
552
587
  FileGateway: () => FileGateway,
553
588
  FileTestStore: () => FileTestStore
554
589
  });
555
- var import_cement8, versionFiles, FileGateway, FileTestStore;
590
+ var import_cement11, versionFiles, FileGateway, FileTestStore;
556
591
  var init_gateway = __esm({
557
592
  "src/runtime/gateways/file/gateway.ts"() {
558
593
  "use strict";
559
594
  init_version();
560
- import_cement8 = require("@adviser/cement");
595
+ import_cement11 = require("@adviser/cement");
561
596
  init_utils();
562
597
  init_utils2();
563
- versionFiles = new import_cement8.KeyedResolvOnce();
598
+ versionFiles = new import_cement11.KeyedResolvOnce();
564
599
  FileGateway = class {
565
600
  get fs() {
566
601
  if (!this._fs) throw this.logger.Error().Msg("fs not initialized").AsError();
@@ -590,7 +625,7 @@ var init_gateway = __esm({
590
625
  });
591
626
  }
592
627
  start(baseURL) {
593
- return exception2Result(async () => {
628
+ return (0, import_cement11.exception2Result)(async () => {
594
629
  this._fs = await getFileSystem(baseURL);
595
630
  await this.fs.start();
596
631
  const url = baseURL.build();
@@ -605,10 +640,10 @@ var init_gateway = __esm({
605
640
  });
606
641
  }
607
642
  async buildUrl(baseUrl, key) {
608
- return import_cement8.Result.Ok(baseUrl.build().setParam("key", key).URI());
643
+ return import_cement11.Result.Ok(baseUrl.build().setParam("key", key).URI());
609
644
  }
610
645
  async close() {
611
- return import_cement8.Result.Ok(void 0);
646
+ return import_cement11.Result.Ok(void 0);
612
647
  }
613
648
  // abstract buildUrl(baseUrl: URL, key: string): Promise<Result<URL>>;
614
649
  getFilePath(url) {
@@ -617,7 +652,7 @@ var init_gateway = __esm({
617
652
  return this.sthis.pathOps.join(getPath(url, this.sthis), getFileName(url, this.sthis));
618
653
  }
619
654
  async put(url, body) {
620
- return exception2Result(async () => {
655
+ return (0, import_cement11.exception2Result)(async () => {
621
656
  const file = await this.getFilePath(url);
622
657
  this.logger.Debug().Str("url", url.toString()).Str("file", file).Msg("put");
623
658
  await this.fs.writefile(file, body);
@@ -629,17 +664,17 @@ var init_gateway = __esm({
629
664
  try {
630
665
  const res = await this.fs.readfile(file);
631
666
  this.logger.Debug().Url(url.asURL()).Str("file", file).Msg("get");
632
- return import_cement8.Result.Ok(new Uint8Array(res));
667
+ return import_cement11.Result.Ok(new Uint8Array(res));
633
668
  } catch (e) {
634
669
  if (isNotFoundError(e)) {
635
- return import_cement8.Result.Err(new NotFoundError(`file not found: ${file}`));
670
+ return import_cement11.Result.Err(new NotFoundError(`file not found: ${file}`));
636
671
  }
637
- return import_cement8.Result.Err(e);
672
+ return import_cement11.Result.Err(e);
638
673
  }
639
674
  });
640
675
  }
641
676
  async delete(url) {
642
- return exception2Result(async () => {
677
+ return (0, import_cement11.exception2Result)(async () => {
643
678
  await this.fs.unlink(this.getFilePath(url));
644
679
  });
645
680
  }
@@ -665,7 +700,7 @@ var init_gateway = __esm({
665
700
  }
666
701
  }
667
702
  }
668
- return import_cement8.Result.Ok(void 0);
703
+ return import_cement11.Result.Ok(void 0);
669
704
  }
670
705
  };
671
706
  FileTestStore = class {
@@ -754,15 +789,15 @@ function getIndexDBName(iurl, sthis) {
754
789
  dbName
755
790
  };
756
791
  }
757
- var import_idb2, import_cement9, onceIndexDB, IndexDBGateway, IndexDBTestStore;
792
+ var import_idb2, import_cement12, onceIndexDB, IndexDBGateway, IndexDBTestStore;
758
793
  var init_gateway2 = __esm({
759
794
  "src/runtime/gateways/indexdb/gateway.ts"() {
760
795
  "use strict";
761
796
  import_idb2 = require("idb");
762
- import_cement9 = require("@adviser/cement");
797
+ import_cement12 = require("@adviser/cement");
763
798
  init_version2();
764
799
  init_utils();
765
- onceIndexDB = new import_cement9.KeyedResolvOnce();
800
+ onceIndexDB = new import_cement12.KeyedResolvOnce();
766
801
  IndexDBGateway = class {
767
802
  constructor(sthis) {
768
803
  this._db = {};
@@ -770,7 +805,7 @@ var init_gateway2 = __esm({
770
805
  this.sthis = sthis;
771
806
  }
772
807
  async start(baseURL) {
773
- return exception2Result(async () => {
808
+ return (0, import_cement12.exception2Result)(async () => {
774
809
  this.logger.Debug().Url(baseURL).Msg("starting");
775
810
  await this.sthis.start();
776
811
  const ic = await connectIdb(baseURL, this.sthis);
@@ -780,10 +815,10 @@ var init_gateway2 = __esm({
780
815
  });
781
816
  }
782
817
  async close() {
783
- return import_cement9.Result.Ok(void 0);
818
+ return import_cement12.Result.Ok(void 0);
784
819
  }
785
820
  async destroy(baseUrl) {
786
- return exception2Result(async () => {
821
+ return (0, import_cement12.exception2Result)(async () => {
787
822
  const type = getStore(baseUrl, this.sthis, joinDBName).name;
788
823
  const idb = this._db;
789
824
  const trans = idb.transaction(type, "readwrite");
@@ -799,7 +834,7 @@ var init_gateway2 = __esm({
799
834
  });
800
835
  }
801
836
  buildUrl(baseUrl, key) {
802
- return Promise.resolve(import_cement9.Result.Ok(baseUrl.build().setParam("key", key).URI()));
837
+ return Promise.resolve(import_cement12.Result.Ok(baseUrl.build().setParam("key", key).URI()));
803
838
  }
804
839
  async get(url) {
805
840
  return exceptionWrapper(async () => {
@@ -810,13 +845,13 @@ var init_gateway2 = __esm({
810
845
  const bytes = await tx.objectStore(store).get(sanitzeKey(key));
811
846
  await tx.done;
812
847
  if (!bytes) {
813
- return import_cement9.Result.Err(new NotFoundError(`missing ${key}`));
848
+ return import_cement12.Result.Err(new NotFoundError(`missing ${key}`));
814
849
  }
815
- return import_cement9.Result.Ok(bytes);
850
+ return import_cement12.Result.Ok(bytes);
816
851
  });
817
852
  }
818
853
  async put(url, value) {
819
- return exception2Result(async () => {
854
+ return (0, import_cement12.exception2Result)(async () => {
820
855
  const key = getKey(url, this.logger);
821
856
  const store = getStore(url, this.sthis, joinDBName).name;
822
857
  this.logger.Debug().Url(url).Str("key", key).Str("store", store).Msg("putting");
@@ -826,14 +861,14 @@ var init_gateway2 = __esm({
826
861
  });
827
862
  }
828
863
  async delete(url) {
829
- return exception2Result(async () => {
864
+ return (0, import_cement12.exception2Result)(async () => {
830
865
  const key = getKey(url, this.logger);
831
866
  const store = getStore(url, this.sthis, joinDBName).name;
832
867
  this.logger.Debug().Url(url).Str("key", key).Str("store", store).Msg("deleting");
833
868
  const tx = this._db.transaction([store], "readwrite");
834
869
  await tx.objectStore(store).delete(sanitzeKey(key));
835
870
  await tx.done;
836
- return import_cement9.Result.Ok(void 0);
871
+ return import_cement12.Result.Ok(void 0);
837
872
  });
838
873
  }
839
874
  };
@@ -873,7 +908,6 @@ __export(src_exports, {
873
908
  ensureLogger: () => ensureLogger,
874
909
  ensureSuperLog: () => ensureSuperLog,
875
910
  ensureSuperThis: () => ensureSuperThis,
876
- exception2Result: () => exception2Result,
877
911
  exceptionWrapper: () => exceptionWrapper,
878
912
  falsyToUndef: () => falsyToUndef,
879
913
  fireproof: () => fireproof,
@@ -890,7 +924,7 @@ __export(src_exports, {
890
924
  module.exports = __toCommonJS(src_exports);
891
925
 
892
926
  // src/database.ts
893
- var import_cement13 = require("@adviser/cement");
927
+ var import_cement16 = require("@adviser/cement");
894
928
 
895
929
  // src/write-queue.ts
896
930
  function writeQueue(worker, payload = Infinity, unbounded = false) {
@@ -933,7 +967,7 @@ function writeQueue(worker, payload = Infinity, unbounded = false) {
933
967
  }
934
968
 
935
969
  // src/crdt.ts
936
- var import_cement12 = require("@adviser/cement");
970
+ var import_cement15 = require("@adviser/cement");
937
971
 
938
972
  // src/runtime/wait-pr-multiformats/block.ts
939
973
  var block_exports = {};
@@ -1024,10 +1058,12 @@ __export(blockstore_exports, {
1024
1058
  EncryptedBlockstore: () => EncryptedBlockstore,
1025
1059
  FragmentGateway: () => FragmentGateway,
1026
1060
  Loader: () => Loader,
1061
+ addCryptoKeyToGatewayMetaPayload: () => addCryptoKeyToGatewayMetaPayload,
1027
1062
  ensureStart: () => ensureStart,
1028
1063
  getGatewayFromURL: () => getGatewayFromURL,
1029
1064
  parseCarFile: () => parseCarFile,
1030
1065
  registerStoreProtocol: () => registerStoreProtocol,
1066
+ setCryptoKeyFromGatewayMetaPayload: () => setCryptoKeyFromGatewayMetaPayload,
1031
1067
  testStoreFactory: () => testStoreFactory,
1032
1068
  toCIDBlock: () => toCIDBlock,
1033
1069
  toStoreRuntime: () => toStoreRuntime
@@ -1039,7 +1075,7 @@ function toCIDBlock(block) {
1039
1075
  }
1040
1076
 
1041
1077
  // src/blockstore/store-factory.ts
1042
- var import_cement10 = require("@adviser/cement");
1078
+ var import_cement13 = require("@adviser/cement");
1043
1079
 
1044
1080
  // src/runtime/files.ts
1045
1081
  var files_exports = {};
@@ -1114,8 +1150,8 @@ var UnixFSFileBuilder = class {
1114
1150
 
1115
1151
  // src/blockstore/store.ts
1116
1152
  var import_p_limit2 = __toESM(require("p-limit"), 1);
1117
- var import_dag_json = require("@ipld/dag-json");
1118
- var import_cement7 = require("@adviser/cement");
1153
+ var import_dag_json2 = require("@ipld/dag-json");
1154
+ var import_cement10 = require("@adviser/cement");
1119
1155
 
1120
1156
  // src/types.ts
1121
1157
  function isFalsy(value) {
@@ -1140,7 +1176,7 @@ init_utils();
1140
1176
  // src/blockstore/loader.ts
1141
1177
  var import_p_limit = __toESM(require("p-limit"), 1);
1142
1178
  var import_car = require("@ipld/car");
1143
- var import_cement6 = require("@adviser/cement");
1179
+ var import_cement7 = require("@adviser/cement");
1144
1180
 
1145
1181
  // src/blockstore/loader-helpers.ts
1146
1182
  var import_sha2 = require("multiformats/hashes/sha2");
@@ -1411,34 +1447,38 @@ __export(key_bag_exports, {
1411
1447
  getKeyBag: () => getKeyBag,
1412
1448
  registerKeyBagProviderFactory: () => registerKeyBagProviderFactory
1413
1449
  });
1414
- var import_cement5 = require("@adviser/cement");
1450
+ var import_cement6 = require("@adviser/cement");
1415
1451
  init_utils();
1416
1452
  var import_base582 = require("multiformats/bases/base58");
1417
1453
  var KeyBag = class {
1418
1454
  constructor(rt) {
1419
1455
  this.rt = rt;
1420
- this._seq = new import_cement5.ResolveSeq();
1421
- this.logger = ensureLogger(rt.sthis, "KeyBag", {
1422
- id: rt.id()
1423
- });
1456
+ this._warnOnce = new import_cement6.ResolveOnce();
1457
+ this._seq = new import_cement6.ResolveSeq();
1458
+ this.logger = ensureLogger(rt.sthis, "KeyBag");
1424
1459
  this.logger.Debug().Msg("KeyBag created");
1425
1460
  }
1426
1461
  async subtleKey(key) {
1462
+ const extractable = this.rt.url.getParam("extractKey") === "_deprecated_internal_api";
1463
+ if (extractable) {
1464
+ this._warnOnce.once(
1465
+ () => this.logger.Warn().Msg("extractKey is enabled via _deprecated_internal_api --- handle keys safely!!!")
1466
+ );
1467
+ }
1427
1468
  return await this.rt.crypto.importKey(
1428
1469
  "raw",
1429
1470
  // raw or jwk
1430
1471
  import_base582.base58btc.decode(key),
1431
1472
  // hexStringToUint8Array(key), // raw data
1432
1473
  "AES-GCM",
1433
- false,
1434
- // extractable
1474
+ extractable,
1435
1475
  ["encrypt", "decrypt"]
1436
1476
  );
1437
1477
  }
1438
1478
  async ensureKeyFromUrl(url, keyFactory) {
1439
1479
  const storeKey = url.getParam("storekey");
1440
1480
  if (storeKey === "insecure") {
1441
- return import_cement5.Result.Ok(url);
1481
+ return import_cement6.Result.Ok(url);
1442
1482
  }
1443
1483
  if (!storeKey) {
1444
1484
  const keyName = `@${keyFactory()}@`;
@@ -1447,7 +1487,7 @@ var KeyBag = class {
1447
1487
  return ret;
1448
1488
  }
1449
1489
  const urb = url.build().setParam("storekey", keyName);
1450
- return import_cement5.Result.Ok(urb.URI());
1490
+ return import_cement6.Result.Ok(urb.URI());
1451
1491
  }
1452
1492
  if (storeKey.startsWith("@") && storeKey.endsWith("@")) {
1453
1493
  const ret = await this.getNamedKey(storeKey);
@@ -1455,13 +1495,13 @@ var KeyBag = class {
1455
1495
  return ret;
1456
1496
  }
1457
1497
  }
1458
- return import_cement5.Result.Ok(url);
1498
+ return import_cement6.Result.Ok(url);
1459
1499
  }
1460
1500
  async toKeyWithFingerPrint(keyStr) {
1461
1501
  const material = import_base582.base58btc.decode(keyStr);
1462
1502
  const key = await this.subtleKey(keyStr);
1463
1503
  const fpr = await this.rt.crypto.digestSHA256(material);
1464
- return import_cement5.Result.Ok({
1504
+ return import_cement6.Result.Ok({
1465
1505
  key,
1466
1506
  fingerPrint: import_base582.base58btc.encode(new Uint8Array(fpr))
1467
1507
  });
@@ -1480,6 +1520,23 @@ var KeyBag = class {
1480
1520
  await bag.set(name, item);
1481
1521
  return await this.toKeyWithFingerPrint(item.key);
1482
1522
  }
1523
+ async getNamedExtractableKey(name, failIfNotFound = false) {
1524
+ const ret = await this.getNamedKey(name, failIfNotFound);
1525
+ if (ret.isErr()) {
1526
+ return ret;
1527
+ }
1528
+ const named = ret.Ok();
1529
+ return import_cement6.Result.Ok({
1530
+ ...named,
1531
+ extract: async () => {
1532
+ const ext = new Uint8Array(await this.rt.crypto.exportKey("raw", named.key));
1533
+ return {
1534
+ key: ext,
1535
+ keyStr: import_base582.base58btc.encode(ext)
1536
+ };
1537
+ }
1538
+ });
1539
+ }
1483
1540
  async getNamedKey(name, failIfNotFound = false) {
1484
1541
  const id = this.rt.sthis.nextId(4).str;
1485
1542
  return this._seq.add(async () => {
@@ -1492,7 +1549,7 @@ var KeyBag = class {
1492
1549
  }
1493
1550
  if (failIfNotFound) {
1494
1551
  this.logger.Debug().Str("id", id).Str("name", name).Msg("failIfNotFound getNamedKey");
1495
- return import_cement5.Result.Err(new Error(`Key not found: ${name}`));
1552
+ return import_cement6.Result.Err(new Error(`Key not found: ${name}`));
1496
1553
  }
1497
1554
  const ret = await this._setNamedKey(name, import_base582.base58btc.encode(this.rt.crypto.randomBytes(this.rt.keyLength)));
1498
1555
  this.logger.Debug().Str("id", id).Str("name", name).Result("fpr", ret).Msg("createKey getNamedKey-post");
@@ -1532,56 +1589,44 @@ function defaultKeyBagOpts(sthis, kbo) {
1532
1589
  const logger = ensureLogger(sthis, "KeyBag");
1533
1590
  let url;
1534
1591
  if (kbo.url) {
1535
- url = import_cement5.URI.from(kbo.url);
1592
+ url = import_cement6.URI.from(kbo.url);
1536
1593
  logger.Debug().Url(url).Msg("from opts");
1537
1594
  } else {
1538
1595
  let bagFnameOrUrl = sthis.env.get("FP_KEYBAG_URL");
1539
- if ((0, import_cement5.runtimeFn)().isBrowser) {
1540
- url = import_cement5.URI.from(bagFnameOrUrl || "indexdb://fp-keybag");
1596
+ if ((0, import_cement6.runtimeFn)().isBrowser) {
1597
+ url = import_cement6.URI.from(bagFnameOrUrl || "indexdb://fp-keybag");
1541
1598
  } else {
1542
1599
  if (!bagFnameOrUrl) {
1543
1600
  const home = sthis.env.get("HOME");
1544
1601
  bagFnameOrUrl = `${home}/.fireproof/keybag`;
1545
- url = import_cement5.URI.from(`file://${bagFnameOrUrl}`);
1602
+ url = import_cement6.URI.from(`file://${bagFnameOrUrl}`);
1546
1603
  } else {
1547
- url = import_cement5.URI.from(bagFnameOrUrl);
1604
+ url = import_cement6.URI.from(bagFnameOrUrl);
1548
1605
  }
1549
1606
  }
1550
1607
  logger.Debug().Url(url).Msg("from env");
1551
1608
  }
1552
- let keyProviderFactory;
1553
- switch (url.protocol) {
1554
- case "file:":
1555
- keyProviderFactory = async () => {
1556
- const { KeyBagProviderFile: KeyBagProviderFile2 } = await Promise.resolve().then(() => (init_key_bag_file(), key_bag_file_exports));
1557
- return new KeyBagProviderFile2(url, sthis);
1558
- };
1559
- break;
1560
- case "indexdb:":
1561
- keyProviderFactory = async () => {
1562
- const { KeyBagProviderIndexDB: KeyBagProviderIndexDB2 } = await Promise.resolve().then(() => (init_key_bag_indexdb(), key_bag_indexdb_exports));
1563
- return new KeyBagProviderIndexDB2(url, sthis);
1564
- };
1565
- break;
1566
- default:
1567
- throw logger.Error().Url(url).Msg("unsupported protocol").AsError();
1609
+ const kitem = keyBagProviderFactories.get(url.protocol);
1610
+ if (!kitem) {
1611
+ throw logger.Error().Url(url).Msg("unsupported protocol").AsError();
1568
1612
  }
1613
+ const getBag = async () => kitem.factory(url, sthis);
1569
1614
  if (url.hasParam("masterkey")) {
1570
1615
  throw logger.Error().Url(url).Msg("masterkey is not supported").AsError();
1571
1616
  }
1572
1617
  return {
1573
1618
  url,
1574
- crypto: kbo.crypto || (0, import_cement5.toCryptoRuntime)({}),
1619
+ crypto: kbo.crypto || (0, import_cement6.toCryptoRuntime)({}),
1575
1620
  sthis,
1576
1621
  logger,
1577
1622
  keyLength: kbo.keyLength || 16,
1578
- getBag: keyProviderFactory,
1623
+ getBag,
1579
1624
  id: () => {
1580
1625
  return url.toString();
1581
1626
  }
1582
1627
  };
1583
1628
  }
1584
- var _keyBags = new import_cement5.KeyedResolvOnce();
1629
+ var _keyBags = new import_cement6.KeyedResolvOnce();
1585
1630
  async function getKeyBag(sthis, kbo = {}) {
1586
1631
  await sthis.start();
1587
1632
  const rt = defaultKeyBagOpts(sthis, kbo);
@@ -1669,7 +1714,7 @@ async function commit(params, t, done, opts = { noLoader: false, compact: false
1669
1714
  }
1670
1715
  async function prepareCarFiles(encoder, threshold, rootBlock, t) {
1671
1716
  const carFiles = [];
1672
- threshold = threshold || 1e3 * 1e3;
1717
+ threshold = threshold || 128e3 * 8;
1673
1718
  let clonedt = new CarTransaction(t.parent, { add: false, noLoader: false });
1674
1719
  clonedt.putSync(rootBlock.cid, rootBlock.bytes);
1675
1720
  let newsize = CBW.blockLength(toCIDBlock(rootBlock));
@@ -1692,6 +1737,54 @@ async function prepareCarFiles(encoder, threshold, rootBlock, t) {
1692
1737
 
1693
1738
  // src/blockstore/loader.ts
1694
1739
  var import_sha23 = require("multiformats/hashes/sha2");
1740
+
1741
+ // src/blockstore/task-manager.ts
1742
+ init_utils();
1743
+ var TaskManager = class {
1744
+ constructor(sthis, callback) {
1745
+ this.eventsWeHandled = /* @__PURE__ */ new Set();
1746
+ this.queue = [];
1747
+ this.isProcessing = false;
1748
+ this.logger = ensureLogger(sthis, "TaskManager");
1749
+ this.callback = callback;
1750
+ }
1751
+ async handleEvent(cid, parents, dbMeta) {
1752
+ for (const parent of parents) {
1753
+ this.eventsWeHandled.add(parent.toString());
1754
+ }
1755
+ this.queue.push({ cid: cid.toString(), dbMeta, retries: 0 });
1756
+ this.queue = this.queue.filter(({ cid: cid2 }) => !this.eventsWeHandled.has(cid2));
1757
+ void this.processQueue();
1758
+ }
1759
+ async processQueue() {
1760
+ if (this.isProcessing) return;
1761
+ this.isProcessing = true;
1762
+ const filteredQueue = this.queue.filter(({ cid }) => !this.eventsWeHandled.has(cid));
1763
+ const first = filteredQueue[0];
1764
+ if (!first) {
1765
+ return;
1766
+ }
1767
+ try {
1768
+ await this.callback(first.dbMeta);
1769
+ this.eventsWeHandled.add(first.cid);
1770
+ this.queue = this.queue.filter(({ cid }) => !this.eventsWeHandled.has(cid));
1771
+ } catch (err) {
1772
+ if (first.retries++ > 3) {
1773
+ this.logger.Error().Str("cid", first.cid).Msg("failed to process event block after 3 retries");
1774
+ this.queue = this.queue.filter(({ cid }) => cid !== first.cid);
1775
+ }
1776
+ await new Promise((resolve) => setTimeout(resolve, 50));
1777
+ throw this.logger.Error().Err(err).Msg("failed to process event block").AsError();
1778
+ } finally {
1779
+ this.isProcessing = false;
1780
+ if (this.queue.length > 0) {
1781
+ void this.processQueue();
1782
+ }
1783
+ }
1784
+ }
1785
+ };
1786
+
1787
+ // src/blockstore/loader.ts
1695
1788
  function carLogIncludesGroup(list, cids) {
1696
1789
  return list.some((arr) => {
1697
1790
  return arr.toString() === cids.toString();
@@ -1716,7 +1809,7 @@ var Loader = class {
1716
1809
  this.getBlockCache = /* @__PURE__ */ new Map();
1717
1810
  this.seenMeta = /* @__PURE__ */ new Set();
1718
1811
  this.writeLimit = (0, import_p_limit.default)(1);
1719
- this.onceReady = new import_cement6.ResolveOnce();
1812
+ this.onceReady = new import_cement7.ResolveOnce();
1720
1813
  this.name = name;
1721
1814
  this.sthis = sthis;
1722
1815
  this.ebOpts = defaultedBlockstoreRuntime(
@@ -1728,6 +1821,9 @@ var Loader = class {
1728
1821
  "Loader"
1729
1822
  );
1730
1823
  this.logger = this.ebOpts.logger;
1824
+ this.taskManager = new TaskManager(sthis, async (dbMeta) => {
1825
+ await this.handleDbMetasFromStore([dbMeta]);
1826
+ });
1731
1827
  }
1732
1828
  // readonly id = uuidv4();
1733
1829
  async keyBag() {
@@ -1747,8 +1843,10 @@ var Loader = class {
1747
1843
  }
1748
1844
  async ready() {
1749
1845
  return this.onceReady.once(async () => {
1750
- const metas = this.ebOpts.meta ? [this.ebOpts.meta] : await (await this.metaStore()).load("main");
1751
- if (metas) {
1846
+ const metas = await (await this.metaStore()).load();
1847
+ if (this.ebOpts.meta) {
1848
+ await this.handleDbMetasFromStore([this.ebOpts.meta]);
1849
+ } else if (metas) {
1752
1850
  await this.handleDbMetasFromStore(metas);
1753
1851
  }
1754
1852
  });
@@ -1829,7 +1927,8 @@ var Loader = class {
1829
1927
  carLog: this.carLog,
1830
1928
  carStore: fstore,
1831
1929
  WALStore: await this.WALStore(),
1832
- metaStore: await this.metaStore()
1930
+ metaStore: await this.metaStore(),
1931
+ threshold: this.ebOpts.threshold
1833
1932
  };
1834
1933
  return this.commitQueue.enqueue(async () => {
1835
1934
  await this.cacheTransaction(t);
@@ -2054,7 +2153,7 @@ var generateIV = {
2054
2153
  calc: async (ko, crypto, data) => {
2055
2154
  const hash = await import_sha24.sha256.digest(data);
2056
2155
  const hashBytes = new Uint8Array(hash.bytes);
2057
- const hashArray = new Uint8Array(ko.ivLength * 8);
2156
+ const hashArray = new Uint8Array(ko.ivLength);
2058
2157
  for (let i = 0; i < hashBytes.length; i++) {
2059
2158
  hashArray[i % ko.ivLength] ^= hashBytes[i];
2060
2159
  }
@@ -2132,7 +2231,7 @@ var keyedCrypto = class {
2132
2231
  };
2133
2232
  }
2134
2233
  async _decrypt(data) {
2135
- this.logger.Debug().Len(data.bytes).Str("fp", this.key.fingerPrint).Msg("decrypting");
2234
+ this.logger.Debug().Len(data.bytes, "bytes").Len(data.iv, "iv").Str("fp", this.key.fingerPrint).Msg("decrypting");
2136
2235
  return new Uint8Array(await this.crypto.decrypt(this.algo(data.iv), this.key.key, data.bytes));
2137
2236
  }
2138
2237
  async _encrypt(data) {
@@ -2203,8 +2302,10 @@ async function keyedCryptoFactory(url, kb, sthis) {
2203
2302
  }
2204
2303
 
2205
2304
  // src/blockstore/fragment-gateway.ts
2305
+ var import_cement8 = require("@adviser/cement");
2206
2306
  var import_base584 = require("multiformats/bases/base58");
2207
2307
  var import_cborg = require("cborg");
2308
+ init_utils();
2208
2309
  function getFragSize(url) {
2209
2310
  const fragSize = url.getParam("fragSize");
2210
2311
  let ret = 0;
@@ -2225,7 +2326,7 @@ async function getFrags(url, innerGW, headerSize, logger) {
2225
2326
  }
2226
2327
  const data = res.unwrap();
2227
2328
  return [
2228
- import_cement.Result.Ok({
2329
+ import_cement8.Result.Ok({
2229
2330
  fid: new Uint8Array(0),
2230
2331
  ofs: 0,
2231
2332
  len: data.length,
@@ -2239,7 +2340,7 @@ async function getFrags(url, innerGW, headerSize, logger) {
2239
2340
  }
2240
2341
  const firstFragment = (0, import_cborg.decode)(firstRaw.unwrap());
2241
2342
  const blockSize = firstFragment.data.length;
2242
- const ops = [Promise.resolve(import_cement.Result.Ok(firstFragment))];
2343
+ const ops = [Promise.resolve(import_cement8.Result.Ok(firstFragment))];
2243
2344
  const fidStr = import_base584.base58btc.encode(firstFragment.fid);
2244
2345
  const fragUrl = url.build().setParam("fid", fidStr).setParam("len", firstFragment.len.toString()).setParam("headerSize", headerSize.toString());
2245
2346
  for (let ofs = blockSize; ofs < firstFragment.len; ofs += blockSize) {
@@ -2251,12 +2352,12 @@ async function getFrags(url, innerGW, headerSize, logger) {
2251
2352
  }
2252
2353
  const fragment = (0, import_cborg.decode)(raw2.unwrap());
2253
2354
  if (import_base584.base58btc.encode(fragment.fid) !== fidStr) {
2254
- return import_cement.Result.Err(logger.Error().Msg("Fragment fid mismatch").AsError());
2355
+ return import_cement8.Result.Err(logger.Error().Msg("Fragment fid mismatch").AsError());
2255
2356
  }
2256
2357
  if (fragment.ofs !== ofs2) {
2257
- return import_cement.Result.Err(logger.Error().Uint64("ofs", ofs2).Msg("Fragment ofs mismatch").AsError());
2358
+ return import_cement8.Result.Err(logger.Error().Uint64("ofs", ofs2).Msg("Fragment ofs mismatch").AsError());
2258
2359
  }
2259
- return import_cement.Result.Ok(fragment);
2360
+ return import_cement8.Result.Ok(fragment);
2260
2361
  })(fragUrl.setParam("ofs", ofs.toString()).URI(), ofs)
2261
2362
  );
2262
2363
  }
@@ -2318,42 +2419,156 @@ var FragmentGateway = class {
2318
2419
  }
2319
2420
  async put(url, body) {
2320
2421
  await Promise.all(this.slicer(url, body));
2321
- return import_cement.Result.Ok(void 0);
2422
+ return import_cement8.Result.Ok(void 0);
2322
2423
  }
2323
2424
  async get(url) {
2324
2425
  const rfrags = await getFrags(url, this.innerGW, this.headerSize, this.logger);
2325
2426
  let buffer = void 0;
2326
2427
  for (const rfrag of rfrags) {
2327
2428
  if (rfrag.isErr()) {
2328
- return import_cement.Result.Err(rfrag.Err());
2429
+ return import_cement8.Result.Err(rfrag.Err());
2329
2430
  }
2330
2431
  const frag = rfrag.Ok();
2331
2432
  buffer = buffer || new Uint8Array(frag.len);
2332
2433
  buffer.set(frag.data, frag.ofs);
2333
2434
  }
2334
- return import_cement.Result.Ok(buffer || new Uint8Array(0));
2435
+ return import_cement8.Result.Ok(buffer || new Uint8Array(0));
2436
+ }
2437
+ async subscribe(url, callback) {
2438
+ if (this.innerGW.subscribe) {
2439
+ return this.innerGW.subscribe(url, callback);
2440
+ } else {
2441
+ return import_cement8.Result.Err(this.logger.Error().Url(url).Msg("subscribe not supported").AsError());
2442
+ }
2335
2443
  }
2336
2444
  async delete(url) {
2337
2445
  const rfrags = await getFrags(url, this.innerGW, this.headerSize, this.logger);
2338
2446
  for (const rfrag of rfrags) {
2339
2447
  if (rfrag.isErr()) {
2340
- return import_cement.Result.Err(rfrag.Err());
2448
+ return import_cement8.Result.Err(rfrag.Err());
2341
2449
  }
2342
2450
  const frag = rfrag.Ok();
2343
2451
  const fidStr = import_base584.base58btc.encode(frag.fid);
2344
2452
  const fragUrl = url.build().setParam("fid", fidStr).setParam("len", frag.len.toString()).setParam("headerSize", this.headerSize.toString()).URI();
2345
2453
  await this.innerGW.delete(fragUrl);
2346
2454
  }
2347
- return import_cement.Result.Ok(void 0);
2455
+ return import_cement8.Result.Ok(void 0);
2348
2456
  }
2349
2457
  };
2350
2458
 
2459
+ // src/blockstore/meta-key-helper.ts
2460
+ var import_dag_json = require("@ipld/dag-json");
2461
+ var import_clock = require("@web3-storage/pail/clock");
2462
+ var import_multiformats2 = require("multiformats");
2463
+ var import_base64 = require("multiformats/bases/base64");
2464
+ var import_cement9 = require("@adviser/cement");
2465
+ async function decodeGatewayMetaBytesToDbMeta(sthis, byteHeads) {
2466
+ const crdtEntries = JSON.parse(sthis.txt.decode(byteHeads));
2467
+ if (!crdtEntries.length) {
2468
+ sthis.logger.Debug().Str("byteHeads", new TextDecoder().decode(byteHeads)).Msg("No CRDT entries found");
2469
+ return [];
2470
+ }
2471
+ if (!crdtEntries.map) {
2472
+ sthis.logger.Debug().Str("crdtEntries", JSON.stringify(crdtEntries)).Msg("No data in CRDT entries");
2473
+ return [];
2474
+ }
2475
+ return Promise.all(
2476
+ crdtEntries.map(async (crdtEntry) => {
2477
+ const eventBlock = await (0, import_clock.decodeEventBlock)(import_base64.base64pad.decode(crdtEntry.data));
2478
+ const dbMeta = (0, import_dag_json.parse)(sthis.txt.decode(eventBlock.value.data.dbMeta));
2479
+ return {
2480
+ eventCid: eventBlock.cid,
2481
+ parents: crdtEntry.parents,
2482
+ dbMeta
2483
+ };
2484
+ })
2485
+ );
2486
+ }
2487
+ async function setCryptoKeyFromGatewayMetaPayload(uri, sthis, data) {
2488
+ try {
2489
+ sthis.logger.Debug().Str("uri", uri.toString()).Msg("Setting crypto key from gateway meta payload");
2490
+ const keyInfo = await decodeGatewayMetaBytesToDbMeta(sthis, data);
2491
+ if (keyInfo.length) {
2492
+ const dbMeta = keyInfo[0].dbMeta;
2493
+ if (dbMeta.key) {
2494
+ const kb = await getKeyBag(sthis);
2495
+ const keyName = getStoreKeyName(uri);
2496
+ const res = await kb.setNamedKey(keyName, dbMeta.key);
2497
+ if (res.isErr()) {
2498
+ sthis.logger.Debug().Str("keyName", keyName).Str("dbMeta.key", dbMeta.key).Msg("Failed to set named key");
2499
+ throw res.Err();
2500
+ }
2501
+ }
2502
+ sthis.logger.Debug().Str("dbMeta.key", dbMeta.key).Str("uri", uri.toString()).Msg("Set crypto key from gateway meta payload");
2503
+ return import_cement9.Result.Ok(dbMeta);
2504
+ }
2505
+ sthis.logger.Debug().Str("data", new TextDecoder().decode(data)).Msg("No crypto in gateway meta payload");
2506
+ return import_cement9.Result.Ok(void 0);
2507
+ } catch (error) {
2508
+ sthis.logger.Debug().Err(error).Msg("Failed to set crypto key from gateway meta payload");
2509
+ return import_cement9.Result.Err(error);
2510
+ }
2511
+ }
2512
+ async function addCryptoKeyToGatewayMetaPayload(uri, sthis, body) {
2513
+ try {
2514
+ sthis.logger.Debug().Str("uri", uri.toString()).Msg("Adding crypto key to gateway meta payload");
2515
+ const keyName = getStoreKeyName(uri);
2516
+ const kb = await getKeyBag(sthis);
2517
+ const res = await kb.getNamedExtractableKey(keyName, true);
2518
+ if (res.isErr()) {
2519
+ sthis.logger.Error().Str("keyName", keyName).Msg("Failed to get named extractable key");
2520
+ throw res.Err();
2521
+ }
2522
+ const keyData = await res.Ok().extract();
2523
+ const dbMetas = await decodeGatewayMetaBytesToDbMeta(sthis, body);
2524
+ const { dbMeta, parents } = dbMetas[0];
2525
+ const parentLinks = parents.map((p) => import_multiformats2.CID.parse(p));
2526
+ dbMeta.key = keyData.keyStr;
2527
+ const events = await Promise.all([dbMeta].map((dbMeta2) => createDbMetaEventBlock(sthis, dbMeta2, parentLinks)));
2528
+ const encoded = await encodeEventsWithParents(sthis, events, parentLinks);
2529
+ sthis.logger.Debug().Str("uri", uri.toString()).Msg("Added crypto key to gateway meta payload");
2530
+ return import_cement9.Result.Ok(encoded);
2531
+ } catch (error) {
2532
+ sthis.logger.Error().Err(error).Msg("Failed to add crypto key to gateway meta payload");
2533
+ return import_cement9.Result.Err(error);
2534
+ }
2535
+ }
2536
+ function getStoreKeyName(url) {
2537
+ const storeKeyName = [url.getParam("localName") || url.getParam("name")];
2538
+ const idx = url.getParam("index");
2539
+ if (idx) {
2540
+ storeKeyName.push(idx);
2541
+ }
2542
+ storeKeyName.push("data");
2543
+ return `@${storeKeyName.join(":")}@`;
2544
+ }
2545
+ async function createDbMetaEventBlock(sthis, dbMeta, parents) {
2546
+ const event = await import_clock.EventBlock.create(
2547
+ {
2548
+ dbMeta: sthis.txt.encode((0, import_dag_json.format)(dbMeta))
2549
+ },
2550
+ parents
2551
+ );
2552
+ return event;
2553
+ }
2554
+ async function encodeEventsWithParents(sthis, events, parents) {
2555
+ const crdtEntries = events.map((event) => {
2556
+ const base64String = import_base64.base64pad.encode(event.bytes);
2557
+ return {
2558
+ cid: event.cid.toString(),
2559
+ data: base64String,
2560
+ parents: parents.map((p) => p.toString())
2561
+ };
2562
+ });
2563
+ return sthis.txt.encode(JSON.stringify(crdtEntries));
2564
+ }
2565
+
2351
2566
  // src/blockstore/store.ts
2352
2567
  function guardVersion(url) {
2353
2568
  if (!url.hasParam("version")) {
2354
- return import_cement7.Result.Err(`missing version: ${url.toString()}`);
2569
+ return import_cement10.Result.Err(`missing version: ${url.toString()}`);
2355
2570
  }
2356
- return import_cement7.Result.Ok(url);
2571
+ return import_cement10.Result.Ok(url);
2357
2572
  }
2358
2573
  var BaseStoreImpl = class {
2359
2574
  constructor(name, url, opts, sthis, logger) {
@@ -2365,6 +2580,7 @@ var BaseStoreImpl = class {
2365
2580
  this.sthis = sthis;
2366
2581
  this.logger = logger.With().Ref("url", () => this._url.toString()).Str("name", name).Logger();
2367
2582
  this.gateway = new FragmentGateway(this.sthis, opts.gateway);
2583
+ this.loader = opts.loader;
2368
2584
  }
2369
2585
  url() {
2370
2586
  return this._url;
@@ -2375,6 +2591,9 @@ var BaseStoreImpl = class {
2375
2591
  onClosed(fn) {
2376
2592
  this._onClosed.push(fn);
2377
2593
  }
2594
+ async ready() {
2595
+ return;
2596
+ }
2378
2597
  async keyedCrypto() {
2379
2598
  return keyedCryptoFactory(this._url, await this.keybag(), this.sthis);
2380
2599
  }
@@ -2409,7 +2628,7 @@ var BaseStoreImpl = class {
2409
2628
  }
2410
2629
  if (this.ready) {
2411
2630
  const fn = this.ready.bind(this);
2412
- const ready = await exception2Result(fn);
2631
+ const ready = await (0, import_cement10.exception2Result)(fn);
2413
2632
  if (ready.isErr()) {
2414
2633
  await this.close();
2415
2634
  return ready;
@@ -2421,67 +2640,44 @@ var BaseStoreImpl = class {
2421
2640
  }
2422
2641
  };
2423
2642
  var MetaStoreImpl = class extends BaseStoreImpl {
2643
+ // remote: boolean;
2424
2644
  constructor(sthis, name, url, opts) {
2425
- super(
2426
- name,
2427
- url,
2428
- {
2429
- ...opts
2430
- },
2431
- sthis,
2432
- ensureLogger(sthis, "MetaStoreImpl")
2433
- );
2645
+ super(name, url, { ...opts }, sthis, ensureLogger(sthis, "MetaStoreImpl"));
2434
2646
  this.storeType = "meta";
2435
2647
  this.subscribers = /* @__PURE__ */ new Map();
2436
- }
2437
- onLoad(branch, loadHandler) {
2438
- const subscribers = this.subscribers.get(branch) || [];
2439
- subscribers.push(loadHandler);
2440
- this.subscribers.set(branch, subscribers);
2441
- return () => {
2442
- const subscribers2 = this.subscribers.get(branch) || [];
2443
- const idx = subscribers2.indexOf(loadHandler);
2444
- if (idx > -1) subscribers2.splice(idx, 1);
2445
- };
2446
- }
2447
- makeHeader({ cars }) {
2448
- const toEncode = { cars };
2449
- return (0, import_dag_json.format)(toEncode);
2450
- }
2451
- parseHeader(headerData) {
2452
- const got = (0, import_dag_json.parse)(headerData);
2453
- return got;
2454
- }
2455
- async handleSubscribers(dbMetas, branch) {
2456
- try {
2457
- const subscribers = this.subscribers.get(branch) || [];
2458
- await Promise.all(subscribers.map((subscriber) => subscriber(dbMetas)));
2459
- } catch (e) {
2460
- this.logger.Error().Err(e).Msg("handleSubscribers").AsError();
2648
+ this.parents = [];
2649
+ if (
2650
+ /*this.remote && */
2651
+ opts.gateway.subscribe
2652
+ ) {
2653
+ this.onStarted(async () => {
2654
+ this.logger.Debug().Str("url", this.url().toString()).Msg("Subscribing to the gateway");
2655
+ opts.gateway.subscribe?.(this.url(), async (message) => {
2656
+ this.logger.Debug().Msg("Received message from gateway");
2657
+ const dbMetas = await decodeGatewayMetaBytesToDbMeta(this.sthis, message);
2658
+ await Promise.all(
2659
+ dbMetas.map((dbMeta) => this.loader?.taskManager?.handleEvent(dbMeta.eventCid, dbMeta.parents, dbMeta.dbMeta))
2660
+ );
2661
+ this.updateParentsFromDbMetas(dbMetas);
2662
+ });
2663
+ });
2461
2664
  }
2462
2665
  }
2463
- async handleByteHeads(byteHeads, branch = "main") {
2464
- let dbMetas;
2465
- try {
2466
- dbMetas = this.dbMetasForByteHeads(byteHeads);
2467
- } catch (e) {
2468
- throw this.logger.Error().Err(e).Msg("parseHeader").AsError();
2469
- }
2470
- await this.handleSubscribers(dbMetas, branch);
2471
- return dbMetas;
2666
+ updateParentsFromDbMetas(dbMetas) {
2667
+ const cids = dbMetas.map((m) => m.eventCid);
2668
+ const dbMetaParents = dbMetas.flatMap((m) => m.parents);
2669
+ const uniqueParentsMap = new Map([...this.parents, ...cids].map((p) => [p.toString(), p]));
2670
+ const dbMetaParentsSet = new Set(dbMetaParents.map((p) => p.toString()));
2671
+ this.parents = Array.from(uniqueParentsMap.values()).filter((p) => !dbMetaParentsSet.has(p.toString()));
2472
2672
  }
2473
- dbMetasForByteHeads(byteHeads) {
2474
- return byteHeads.map((bytes) => {
2475
- const txt = this.sthis.txt.decode(bytes);
2476
- return this.parseHeader(txt);
2477
- });
2673
+ async handleByteHeads(byteHeads) {
2674
+ return await decodeGatewayMetaBytesToDbMeta(this.sthis, byteHeads);
2478
2675
  }
2479
- async load(branch) {
2480
- branch = branch || "main";
2481
- this.logger.Debug().Str("branch", branch).Msg("loading");
2676
+ async load() {
2677
+ const branch = "main";
2482
2678
  const url = await this.gateway.buildUrl(this.url(), branch);
2483
2679
  if (url.isErr()) {
2484
- throw this.logger.Error().Result("buidUrl", url).Str("branch", branch).Msg("got error from gateway.buildUrl").AsError();
2680
+ throw this.logger.Error().Result("buildUrl", url).Str("branch", branch).Msg("got error from gateway.buildUrl").AsError();
2485
2681
  }
2486
2682
  const bytes = await this.gateway.get(url.Ok());
2487
2683
  if (bytes.isErr()) {
@@ -2490,27 +2686,31 @@ var MetaStoreImpl = class extends BaseStoreImpl {
2490
2686
  }
2491
2687
  throw this.logger.Error().Url(url.Ok()).Result("bytes:", bytes).Msg("gateway get").AsError();
2492
2688
  }
2493
- return this.handleByteHeads([bytes.Ok()], branch);
2689
+ const dbMetas = await this.handleByteHeads(bytes.Ok());
2690
+ await this.loader?.handleDbMetasFromStore(dbMetas.map((m) => m.dbMeta));
2691
+ this.updateParentsFromDbMetas(dbMetas);
2692
+ return dbMetas.map((m) => m.dbMeta);
2494
2693
  }
2495
2694
  async save(meta, branch) {
2496
2695
  branch = branch || "main";
2497
2696
  this.logger.Debug().Str("branch", branch).Any("meta", meta).Msg("saving meta");
2498
- const bytes = this.makeHeader(meta);
2697
+ const event = await createDbMetaEventBlock(this.sthis, meta, this.parents);
2698
+ const bytes = await encodeEventsWithParents(this.sthis, [event], this.parents);
2499
2699
  const url = await this.gateway.buildUrl(this.url(), branch);
2500
2700
  if (url.isErr()) {
2501
2701
  throw this.logger.Error().Err(url.Err()).Str("branch", branch).Msg("got error from gateway.buildUrl").AsError();
2502
2702
  }
2503
- const res = await this.gateway.put(url.Ok(), this.sthis.txt.encode(bytes));
2703
+ this.parents = [event.cid];
2704
+ const res = await this.gateway.put(url.Ok(), bytes);
2504
2705
  if (res.isErr()) {
2505
2706
  throw this.logger.Error().Err(res.Err()).Msg("got error from gateway.put").AsError();
2506
2707
  }
2507
- await this.handleSubscribers([meta], branch);
2508
2708
  return res;
2509
2709
  }
2510
2710
  async close() {
2511
2711
  await this.gateway.close(this.url());
2512
2712
  this._onClosed.forEach((fn) => fn());
2513
- return import_cement7.Result.Ok(void 0);
2713
+ return import_cement10.Result.Ok(void 0);
2514
2714
  }
2515
2715
  async destroy() {
2516
2716
  return this.gateway.destroy(this.url());
@@ -2519,15 +2719,7 @@ var MetaStoreImpl = class extends BaseStoreImpl {
2519
2719
  var DataStoreImpl = class extends BaseStoreImpl {
2520
2720
  // readonly tag: string = "car-base";
2521
2721
  constructor(sthis, name, url, opts) {
2522
- super(
2523
- name,
2524
- url,
2525
- {
2526
- ...opts
2527
- },
2528
- sthis,
2529
- ensureLogger(sthis, "DataStoreImpl")
2530
- );
2722
+ super(name, url, { ...opts }, sthis, ensureLogger(sthis, "DataStoreImpl"));
2531
2723
  this.storeType = "data";
2532
2724
  }
2533
2725
  async load(cid) {
@@ -2565,7 +2757,7 @@ var DataStoreImpl = class extends BaseStoreImpl {
2565
2757
  async close() {
2566
2758
  await this.gateway.close(this.url());
2567
2759
  this._onClosed.forEach((fn) => fn());
2568
- return import_cement7.Result.Ok(void 0);
2760
+ return import_cement10.Result.Ok(void 0);
2569
2761
  }
2570
2762
  destroy() {
2571
2763
  return this.gateway.destroy(this.url());
@@ -2573,46 +2765,43 @@ var DataStoreImpl = class extends BaseStoreImpl {
2573
2765
  };
2574
2766
  var WALStoreImpl = class extends BaseStoreImpl {
2575
2767
  constructor(loader, url, opts) {
2576
- super(
2577
- loader.name,
2578
- url,
2579
- {
2580
- ...opts
2581
- },
2582
- loader.sthis,
2583
- ensureLogger(loader.sthis, "WALStoreImpl")
2584
- );
2768
+ super(loader.name, url, { ...opts }, loader.sthis, ensureLogger(loader.sthis, "WALStoreImpl"));
2585
2769
  this.storeType = "wal";
2586
- this._ready = new import_cement7.ResolveOnce();
2770
+ this._ready = new import_cement10.ResolveOnce();
2587
2771
  this.walState = { operations: [], noLoaderOps: [], fileOperations: [] };
2588
2772
  this.processing = void 0;
2589
2773
  this.processQueue = new CommitQueue();
2590
- this.ready = async () => {
2591
- return this._ready.once(async () => {
2592
- const walState = await this.load().catch((e) => {
2593
- this.logger.Error().Any("error", e).Msg("error loading wal");
2594
- return void 0;
2595
- });
2596
- if (!walState) {
2597
- this.walState.operations = [];
2598
- this.walState.fileOperations = [];
2599
- } else {
2600
- this.walState.operations = walState.operations || [];
2601
- this.walState.fileOperations = walState.fileOperations || [];
2602
- }
2603
- });
2604
- };
2605
2774
  this.loader = loader;
2606
2775
  }
2776
+ async ready() {
2777
+ return this._ready.once(async () => {
2778
+ const walState = await this.load().catch((e) => {
2779
+ this.logger.Error().Any("error", e).Msg("error loading wal");
2780
+ return void 0;
2781
+ });
2782
+ if (!walState) {
2783
+ this.walState.operations = [];
2784
+ this.walState.fileOperations = [];
2785
+ } else {
2786
+ this.walState.operations = walState.operations || [];
2787
+ this.walState.fileOperations = walState.fileOperations || [];
2788
+ }
2789
+ });
2790
+ }
2607
2791
  async enqueue(dbMeta, opts) {
2608
2792
  await this.ready();
2609
- if (opts.noLoader) {
2793
+ if (opts.compact) {
2794
+ this.walState.operations = [];
2795
+ this.walState.noLoaderOps = [dbMeta];
2796
+ } else if (opts.noLoader) {
2610
2797
  this.walState.noLoaderOps.push(dbMeta);
2611
2798
  } else {
2612
2799
  this.walState.operations.push(dbMeta);
2613
2800
  }
2614
2801
  await this.save(this.walState);
2615
- void this.process();
2802
+ if (!opts.noLoader) {
2803
+ void this.process();
2804
+ }
2616
2805
  }
2617
2806
  async enqueueFile(fileCid, publicFile = false) {
2618
2807
  await this.ready();
@@ -2639,7 +2828,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
2639
2828
  const fileOperations = [...this.walState.fileOperations];
2640
2829
  const uploads = [];
2641
2830
  const noLoaderOps = [...this.walState.noLoaderOps];
2642
- const limit = (0, import_p_limit2.default)(5);
2831
+ const limit = (0, import_p_limit2.default)(3);
2643
2832
  if (operations.length + fileOperations.length + noLoaderOps.length === 0) return;
2644
2833
  for (const dbMeta of noLoaderOps) {
2645
2834
  const uploadP = limit(async () => {
@@ -2715,7 +2904,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
2715
2904
  throw this.logger.Error().Err(bytes.Err()).Msg("error get").AsError();
2716
2905
  }
2717
2906
  try {
2718
- return bytes && (0, import_dag_json.parse)(this.sthis.txt.decode(bytes.Ok()));
2907
+ return bytes && (0, import_dag_json2.parse)(this.sthis.txt.decode(bytes.Ok()));
2719
2908
  } catch (e) {
2720
2909
  throw this.logger.Error().Err(e).Msg("error parse").AsError();
2721
2910
  }
@@ -2727,7 +2916,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
2727
2916
  }
2728
2917
  let encoded;
2729
2918
  try {
2730
- encoded = (0, import_dag_json.format)(state);
2919
+ encoded = (0, import_dag_json2.format)(state);
2731
2920
  } catch (e) {
2732
2921
  throw this.logger.Error().Err(e).Any("state", state).Msg("error format").AsError();
2733
2922
  }
@@ -2739,7 +2928,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
2739
2928
  async close() {
2740
2929
  await this.gateway.close(this.url());
2741
2930
  this._onClosed.forEach((fn) => fn());
2742
- return import_cement7.Result.Ok(void 0);
2931
+ return import_cement10.Result.Ok(void 0);
2743
2932
  }
2744
2933
  destroy() {
2745
2934
  return this.gateway.destroy(this.url());
@@ -2766,15 +2955,15 @@ function buildURL(optURL, loader) {
2766
2955
  const obuItem = Array.from(storeFactory.values()).find((items) => items.overrideBaseURL);
2767
2956
  let obuUrl;
2768
2957
  if (obuItem && obuItem.overrideBaseURL) {
2769
- obuUrl = import_cement10.URI.from(obuItem.overrideBaseURL);
2958
+ obuUrl = import_cement13.URI.from(obuItem.overrideBaseURL);
2770
2959
  }
2771
2960
  const ret = ensureIsIndex(
2772
- import_cement10.URI.from(optURL || obuUrl || dataDir(loader.sthis, loader.name, storeOpts.stores?.base)),
2961
+ import_cement13.URI.from(optURL || obuUrl || dataDir(loader.sthis, loader.name, storeOpts.stores?.base)),
2773
2962
  storeOpts.isIndex
2774
2963
  );
2775
2964
  return ret;
2776
2965
  }
2777
- var onceGateway = new import_cement10.KeyedResolvOnce();
2966
+ var onceGateway = new import_cement13.KeyedResolvOnce();
2778
2967
  async function getGatewayFromURL(url, sthis) {
2779
2968
  return onceGateway.get(url.toString()).once(async () => {
2780
2969
  const item = storeFactory.get(url.protocol);
@@ -2816,52 +3005,61 @@ function registerStoreProtocol(item) {
2816
3005
  storeFactory.delete(protocol);
2817
3006
  };
2818
3007
  }
3008
+ var onceDataStoreFactory = new import_cement13.KeyedResolvOnce();
2819
3009
  async function dataStoreFactory(loader) {
2820
3010
  const url = ensureName(loader.name, buildURL(loader.ebOpts.store.stores?.data, loader)).build().setParam("store", "data").URI();
2821
3011
  const sthis = ensureSuperLog(loader.sthis, "dataStoreFactory", { url: url.toString() });
2822
- const gateway = await getGatewayFromURL(url, sthis);
2823
- if (!gateway) {
2824
- throw sthis.logger.Error().Url(url).Msg("gateway not found").AsError();
2825
- }
2826
- const store = new DataStoreImpl(sthis, loader.name, url, {
2827
- gateway: gateway.gateway,
2828
- keybag: () => getKeyBag(loader.sthis, {
2829
- ...loader.ebOpts.keyBag
2830
- })
3012
+ return onceDataStoreFactory.get(url.toString()).once(async () => {
3013
+ const gateway = await getGatewayFromURL(url, sthis);
3014
+ if (!gateway) {
3015
+ throw sthis.logger.Error().Url(url).Msg("gateway not found").AsError();
3016
+ }
3017
+ const store = new DataStoreImpl(sthis, loader.name, url, {
3018
+ gateway: gateway.gateway,
3019
+ keybag: () => getKeyBag(loader.sthis, {
3020
+ ...loader.ebOpts.keyBag
3021
+ })
3022
+ });
3023
+ return store;
2831
3024
  });
2832
- return store;
2833
3025
  }
3026
+ var onceMetaStoreFactory = new import_cement13.KeyedResolvOnce();
2834
3027
  async function metaStoreFactory(loader) {
2835
3028
  const url = ensureName(loader.name, buildURL(loader.ebOpts.store.stores?.meta, loader)).build().setParam("store", "meta").URI();
2836
3029
  const sthis = ensureSuperLog(loader.sthis, "metaStoreFactory", { url: () => url.toString() });
2837
- sthis.logger.Debug().Str("protocol", url.protocol).Msg("pre-protocol switch");
2838
- const gateway = await getGatewayFromURL(url, sthis);
2839
- if (!gateway) {
2840
- throw sthis.logger.Error().Url(url).Msg("gateway not found").AsError();
2841
- }
2842
- const store = new MetaStoreImpl(loader.sthis, loader.name, url, {
2843
- gateway: gateway.gateway,
2844
- keybag: () => getKeyBag(loader.sthis, {
2845
- ...loader.ebOpts.keyBag
2846
- })
3030
+ return onceMetaStoreFactory.get(url.toString()).once(async () => {
3031
+ sthis.logger.Debug().Str("protocol", url.protocol).Msg("pre-protocol switch");
3032
+ const gateway = await getGatewayFromURL(url, sthis);
3033
+ if (!gateway) {
3034
+ throw sthis.logger.Error().Url(url).Msg("gateway not found").AsError();
3035
+ }
3036
+ const store = new MetaStoreImpl(loader.sthis, loader.name, url, {
3037
+ gateway: gateway.gateway,
3038
+ keybag: () => getKeyBag(loader.sthis, {
3039
+ ...loader.ebOpts.keyBag
3040
+ })
3041
+ });
3042
+ return store;
2847
3043
  });
2848
- return store;
2849
3044
  }
3045
+ var onceRemoteWalFactory = new import_cement13.KeyedResolvOnce();
2850
3046
  async function remoteWalFactory(loader) {
2851
3047
  const url = ensureName(loader.name, buildURL(loader.ebOpts.store.stores?.wal, loader)).build().setParam("store", "wal").URI();
2852
3048
  const sthis = ensureSuperLog(loader.sthis, "remoteWalFactory", { url: url.toString() });
2853
- const gateway = await getGatewayFromURL(url, sthis);
2854
- if (!gateway) {
2855
- throw sthis.logger.Error().Url(url).Msg("gateway not found").AsError();
2856
- }
2857
- sthis.logger.Debug().Str("prepared", url.toString()).Msg("produced");
2858
- const store = new WALStoreImpl(loader, url, {
2859
- gateway: gateway.gateway,
2860
- keybag: () => getKeyBag(loader.sthis, {
2861
- ...loader.ebOpts.keyBag
2862
- })
3049
+ return onceRemoteWalFactory.get(url.toString()).once(async () => {
3050
+ const gateway = await getGatewayFromURL(url, sthis);
3051
+ if (!gateway) {
3052
+ throw sthis.logger.Error().Url(url).Msg("gateway not found").AsError();
3053
+ }
3054
+ sthis.logger.Debug().Str("prepared", url.toString()).Msg("produced");
3055
+ const store = new WALStoreImpl(loader, url, {
3056
+ gateway: gateway.gateway,
3057
+ keybag: () => getKeyBag(loader.sthis, {
3058
+ ...loader.ebOpts.keyBag
3059
+ })
3060
+ });
3061
+ return store;
2863
3062
  });
2864
- return store;
2865
3063
  }
2866
3064
  async function testStoreFactory(url, sthis) {
2867
3065
  sthis = ensureSuperLog(sthis, "testStoreFactory");
@@ -2900,79 +3098,27 @@ function toStoreRuntime(opts, sthis) {
2900
3098
  }
2901
3099
  registerStoreProtocol({
2902
3100
  protocol: "file:",
2903
- gateway: async (logger) => {
3101
+ gateway: async (sthis) => {
2904
3102
  const { FileGateway: FileGateway2 } = await Promise.resolve().then(() => (init_gateway(), gateway_exports));
2905
- return new FileGateway2(logger);
3103
+ return new FileGateway2(sthis);
2906
3104
  },
2907
- test: async (logger) => {
3105
+ test: async (sthis) => {
2908
3106
  const { FileTestStore: FileTestStore2 } = await Promise.resolve().then(() => (init_gateway(), gateway_exports));
2909
- return new FileTestStore2(logger);
3107
+ return new FileTestStore2(sthis);
2910
3108
  }
2911
3109
  });
2912
3110
  registerStoreProtocol({
2913
3111
  protocol: "indexdb:",
2914
- gateway: async (logger) => {
3112
+ gateway: async (sthis) => {
2915
3113
  const { IndexDBGateway: IndexDBGateway2 } = await Promise.resolve().then(() => (init_gateway2(), gateway_exports2));
2916
- return new IndexDBGateway2(logger);
3114
+ return new IndexDBGateway2(sthis);
2917
3115
  },
2918
- test: async (logger) => {
3116
+ test: async (sthis) => {
2919
3117
  const { IndexDBTestStore: IndexDBTestStore2 } = await Promise.resolve().then(() => (init_gateway2(), gateway_exports2));
2920
- return new IndexDBTestStore2(logger);
3118
+ return new IndexDBTestStore2(sthis);
2921
3119
  }
2922
3120
  });
2923
3121
 
2924
- // src/blockstore/connection-base.ts
2925
- var import_clock = require("@web3-storage/pail/clock");
2926
- var import_block6 = require("@web3-storage/pail/block");
2927
-
2928
- // src/blockstore/task-manager.ts
2929
- init_utils();
2930
- var TaskManager = class {
2931
- constructor(loader) {
2932
- this.eventsWeHandled = /* @__PURE__ */ new Set();
2933
- this.queue = [];
2934
- this.isProcessing = false;
2935
- this.loader = loader;
2936
- this.logger = ensureLogger(loader.sthis, "TaskManager");
2937
- }
2938
- async handleEvent(eventBlock) {
2939
- const cid = eventBlock.cid.toString();
2940
- const parents = eventBlock.value.parents.map((cid2) => cid2.toString());
2941
- for (const parent of parents) {
2942
- this.eventsWeHandled.add(parent);
2943
- }
2944
- this.queue.push({ cid, eventBlock, retries: 0 });
2945
- this.queue = this.queue.filter(({ cid: cid2 }) => !this.eventsWeHandled.has(cid2));
2946
- void this.processQueue();
2947
- }
2948
- async processQueue() {
2949
- if (this.isProcessing) return;
2950
- this.isProcessing = true;
2951
- const filteredQueue = this.queue.filter(({ cid }) => !this.eventsWeHandled.has(cid));
2952
- const first = filteredQueue[0];
2953
- if (!first) {
2954
- return;
2955
- }
2956
- try {
2957
- this.loader?.remoteMetaStore?.handleByteHeads([first.eventBlock.value.data.dbMeta]);
2958
- this.eventsWeHandled.add(first.cid);
2959
- this.queue = this.queue.filter(({ cid }) => !this.eventsWeHandled.has(cid));
2960
- } catch (err) {
2961
- if (first.retries++ > 3) {
2962
- this.logger.Error().Str("cid", first.cid).Msg("failed to process event block after 3 retries");
2963
- this.queue = this.queue.filter(({ cid }) => cid !== first.cid);
2964
- }
2965
- await new Promise((resolve) => setTimeout(resolve, 50));
2966
- throw this.logger.Error().Err(err).Msg("failed to process event block").AsError();
2967
- } finally {
2968
- this.isProcessing = false;
2969
- if (this.queue.length > 0) {
2970
- void this.processQueue();
2971
- }
2972
- }
2973
- }
2974
- };
2975
-
2976
3122
  // src/blockstore/store-remote.ts
2977
3123
  async function RemoteDataStore(sthis, name, url, opts) {
2978
3124
  const ds = new DataStoreImpl(sthis, name, url, opts);
@@ -2980,7 +3126,13 @@ async function RemoteDataStore(sthis, name, url, opts) {
2980
3126
  return ds;
2981
3127
  }
2982
3128
  async function RemoteMetaStore(sthis, name, url, opts) {
2983
- const ms = new MetaStoreImpl(sthis, name, url, opts);
3129
+ const ms = new MetaStoreImpl(
3130
+ sthis,
3131
+ name,
3132
+ url,
3133
+ opts
3134
+ /* , true*/
3135
+ );
2984
3136
  await ms.start();
2985
3137
  return ms;
2986
3138
  }
@@ -2988,16 +3140,12 @@ async function RemoteMetaStore(sthis, name, url, opts) {
2988
3140
  // src/blockstore/connection-base.ts
2989
3141
  var ConnectionBase = class {
2990
3142
  constructor(url, logger) {
2991
- // readonly ready: Promise<unknown>;
2992
- // todo move to LRU blockstore https://github.com/web3-storage/w3clock/blob/main/src/worker/block.js
2993
- this.eventBlocks = new import_block6.MemoryBlockstore();
2994
- this.parents = [];
2995
3143
  this.loaded = Promise.resolve();
2996
3144
  this.logger = logger;
2997
3145
  this.url = url;
2998
3146
  }
2999
3147
  async refresh() {
3000
- await throwFalsy(throwFalsy(this.loader).remoteMetaStore).load("main");
3148
+ await throwFalsy(throwFalsy(this.loader).remoteMetaStore).load();
3001
3149
  await (await throwFalsy(this.loader).WALStore()).process();
3002
3150
  }
3003
3151
  async connect_X({ loader }) {
@@ -3008,26 +3156,20 @@ var ConnectionBase = class {
3008
3156
  async connectMeta_X({ loader }) {
3009
3157
  if (!loader) throw this.logger.Error().Msg("connectMeta_X: loader is required").AsError();
3010
3158
  this.loader = loader;
3011
- this.taskManager = new TaskManager(loader);
3012
3159
  await this.onConnect();
3013
3160
  const metaUrl = this.url.build().defParam("store", "meta").URI();
3014
3161
  const gateway = await getGatewayFromURL(metaUrl, this.loader.sthis);
3015
3162
  if (!gateway) throw this.logger.Error().Url(metaUrl).Msg("connectMeta_X: gateway is required").AsError();
3016
- const name = metaUrl.toString();
3017
- const remote = await RemoteMetaStore(loader.sthis, name, metaUrl, {
3163
+ const dbName = metaUrl.getParam("name");
3164
+ if (!dbName) throw this.logger.Error().Url(metaUrl).Msg("connectMeta_X: name is required").AsError();
3165
+ const remote = await RemoteMetaStore(loader.sthis, dbName, metaUrl, {
3018
3166
  gateway: gateway.gateway,
3019
- keybag: () => getKeyBag(loader.sthis, loader.ebOpts.keyBag)
3020
- });
3021
- remote.onLoad("main", async (metas) => {
3022
- if (metas) {
3023
- this.logger.Debug().Any("metas", metas).Bool("loader", this.loader).Msg("connectMeta_X: handleDbMetasFromStore pre");
3024
- await throwFalsy(this.loader).handleDbMetasFromStore(metas);
3025
- this.logger.Debug().Any("metas", metas).Msg("connectMeta_X: handleDbMetasFromStore post");
3026
- }
3167
+ keybag: () => getKeyBag(loader.sthis, loader.ebOpts.keyBag),
3168
+ loader
3027
3169
  });
3028
3170
  this.loader.remoteMetaStore = remote;
3029
3171
  this.loaded = this.loader.ready().then(async () => {
3030
- remote.load("main").then(async () => {
3172
+ remote.load().then(async () => {
3031
3173
  (await throwFalsy(this.loader).WALStore()).process();
3032
3174
  });
3033
3175
  });
@@ -3038,28 +3180,14 @@ var ConnectionBase = class {
3038
3180
  const dataUrl = this.url.build().defParam("store", "data").URI();
3039
3181
  const gateway = await getGatewayFromURL(dataUrl, this.loader.sthis);
3040
3182
  if (!gateway) throw this.logger.Error().Url(dataUrl).Msg("connectStorage_X: gateway is required").AsError();
3041
- const name = dataUrl.toString();
3183
+ const name = dataUrl.getParam("name");
3184
+ if (!name) throw this.logger.Error().Url(dataUrl).Msg("connectStorage_X: name is required").AsError;
3042
3185
  loader.remoteCarStore = await RemoteDataStore(loader.sthis, name, this.url, {
3043
3186
  gateway: gateway.gateway,
3044
3187
  keybag: () => getKeyBag(loader.sthis, this.loader?.ebOpts.keyBag)
3045
3188
  });
3046
3189
  loader.remoteFileStore = loader.remoteCarStore;
3047
3190
  }
3048
- async createEventBlock(bytes) {
3049
- const data = {
3050
- dbMeta: bytes
3051
- };
3052
- const event = await import_clock.EventBlock.create(
3053
- data,
3054
- this.parents
3055
- );
3056
- await this.eventBlocks.put(event.cid, event.bytes);
3057
- return event;
3058
- }
3059
- async decodeEventBlock(bytes) {
3060
- const event = await (0, import_clock.decodeEventBlock)(bytes);
3061
- return event;
3062
- }
3063
3191
  // move this stuff to connect
3064
3192
  // async getDashboardURL(compact = true) {
3065
3193
  // const baseUrl = 'https://dashboard.fireproof.storage/'
@@ -3364,7 +3492,7 @@ var import_sha26 = require("multiformats/hashes/sha2");
3364
3492
  var codec2 = __toESM(require("@ipld/dag-cbor"), 1);
3365
3493
  var import_charwise = __toESM(require("charwise"), 1);
3366
3494
  var DbIndex = __toESM(require("prolly-trees/db-index"), 1);
3367
- var import_utils15 = require("prolly-trees/utils");
3495
+ var import_utils16 = require("prolly-trees/utils");
3368
3496
  var import_cache = require("prolly-trees/cache");
3369
3497
  var IndexTree = class {
3370
3498
  };
@@ -3372,17 +3500,17 @@ function refCompare(aRef, bRef) {
3372
3500
  if (Number.isNaN(aRef)) return -1;
3373
3501
  if (Number.isNaN(bRef)) throw new Error("ref may not be Infinity or NaN");
3374
3502
  if (aRef === Infinity) return 1;
3375
- return (0, import_utils15.simpleCompare)(aRef, bRef);
3503
+ return (0, import_utils16.simpleCompare)(aRef, bRef);
3376
3504
  }
3377
3505
  function compare(a, b) {
3378
3506
  const [aKey, aRef] = a;
3379
3507
  const [bKey, bRef] = b;
3380
- const comp = (0, import_utils15.simpleCompare)(aKey, bKey);
3508
+ const comp = (0, import_utils16.simpleCompare)(aKey, bKey);
3381
3509
  if (comp !== 0) return comp;
3382
3510
  return refCompare(aRef, bRef);
3383
3511
  }
3384
- var byKeyOpts = { cache: import_cache.nocache, chunker: (0, import_utils15.bf)(30), codec: codec2, hasher: import_sha26.sha256, compare };
3385
- var byIdOpts = { cache: import_cache.nocache, chunker: (0, import_utils15.bf)(30), codec: codec2, hasher: import_sha26.sha256, compare: import_utils15.simpleCompare };
3512
+ var byKeyOpts = { cache: import_cache.nocache, chunker: (0, import_utils16.bf)(30), codec: codec2, hasher: import_sha26.sha256, compare };
3513
+ var byIdOpts = { cache: import_cache.nocache, chunker: (0, import_utils16.bf)(30), codec: codec2, hasher: import_sha26.sha256, compare: import_utils16.simpleCompare };
3386
3514
  function indexEntriesForChanges(changes, mapFn) {
3387
3515
  const indexEntries = [];
3388
3516
  changes.forEach(({ id: key, value, del }) => {
@@ -3690,7 +3818,7 @@ var Index = class {
3690
3818
  // src/crdt-clock.ts
3691
3819
  var import_clock3 = require("@web3-storage/pail/clock");
3692
3820
  var import_crdt2 = require("@web3-storage/pail/crdt");
3693
- var import_cement11 = require("@adviser/cement");
3821
+ var import_cement14 = require("@adviser/cement");
3694
3822
 
3695
3823
  // src/apply-head-queue.ts
3696
3824
  function applyHeadQueue(worker, logger) {
@@ -3705,7 +3833,7 @@ function applyHeadQueue(worker, logger) {
3705
3833
  queue.sort((a, b) => b.updates ? 1 : -1);
3706
3834
  const task = queue.shift();
3707
3835
  if (!task) continue;
3708
- await worker(task.newHead, task.prevHead, task.updates !== null).catch((e) => {
3836
+ await worker(task.newHead, task.prevHead, task.updates !== void 0).catch((e) => {
3709
3837
  throw logger.Error().Err(e).Msg("int_applyHead worker error").AsError();
3710
3838
  });
3711
3839
  if (task.updates) {
@@ -3748,7 +3876,7 @@ var CRDTClock = class {
3748
3876
  this.zoomers = /* @__PURE__ */ new Set();
3749
3877
  this.watchers = /* @__PURE__ */ new Set();
3750
3878
  this.emptyWatchers = /* @__PURE__ */ new Set();
3751
- this._ready = new import_cement11.ResolveOnce();
3879
+ this._ready = new import_cement14.ResolveOnce();
3752
3880
  this.blockstore = blockstore;
3753
3881
  this.logger = ensureLogger(blockstore.sthis, "CRDTClock");
3754
3882
  this.applyHeadQueue = applyHeadQueue(this.int_applyHead.bind(this), this.logger);
@@ -3796,6 +3924,7 @@ var CRDTClock = class {
3796
3924
  this.zoomers.add(fn);
3797
3925
  }
3798
3926
  async int_applyHead(newHead, prevHead, localUpdates) {
3927
+ const noLoader = !localUpdates;
3799
3928
  const ogHead = sortClockHead(this.head);
3800
3929
  newHead = sortClockHead(newHead);
3801
3930
  if (compareClockHeads(ogHead, newHead)) {
@@ -3806,7 +3935,6 @@ var CRDTClock = class {
3806
3935
  this.setHead(newHead);
3807
3936
  return;
3808
3937
  }
3809
- const noLoader = !localUpdates;
3810
3938
  if (!this.blockstore) {
3811
3939
  throw this.logger.Error().Msg("missing blockstore").AsError();
3812
3940
  }
@@ -3860,7 +3988,7 @@ init_utils();
3860
3988
  var CRDT = class {
3861
3989
  constructor(sthis, name, opts = {}) {
3862
3990
  this.indexers = /* @__PURE__ */ new Map();
3863
- this.onceReady = new import_cement12.ResolveOnce();
3991
+ this.onceReady = new import_cement15.ResolveOnce();
3864
3992
  this.sthis = sthis;
3865
3993
  this.name = name;
3866
3994
  this.logger = ensureLogger(sthis, "CRDT");
@@ -3926,7 +4054,7 @@ var CRDT = class {
3926
4054
  try {
3927
4055
  await Promise.all([this.blockstore.ready(), this.indexBlockstore.ready(), this.clock.ready()]);
3928
4056
  } catch (e) {
3929
- throw this.logger.Error().Err(e).Msg("CRDT not ready").AsError();
4057
+ throw this.logger.Error().Err(e).Msg(`CRDT is not ready`).AsError();
3930
4058
  }
3931
4059
  });
3932
4060
  }
@@ -3981,7 +4109,7 @@ var Database = class {
3981
4109
  this._listening = false;
3982
4110
  this._listeners = /* @__PURE__ */ new Set();
3983
4111
  this._noupdate_listeners = /* @__PURE__ */ new Set();
3984
- this._ready = new import_cement13.ResolveOnce();
4112
+ this._ready = new import_cement16.ResolveOnce();
3985
4113
  this.name = name;
3986
4114
  this.opts = opts || this.opts;
3987
4115
  this.sthis = ensureSuperThis(this.opts);
@@ -4030,7 +4158,7 @@ var Database = class {
4030
4158
  await this.ready();
4031
4159
  this.logger.Debug().Str("id", doc._id).Msg("put");
4032
4160
  const { _id, ...value } = doc;
4033
- const docId = _id || this.sthis.nextId().str;
4161
+ const docId = _id || this.sthis.timeOrderedNextId().str;
4034
4162
  const result = await this._writeQueue.push({
4035
4163
  id: docId,
4036
4164
  value: {
@@ -4171,6 +4299,7 @@ __export(runtime_exports, {
4171
4299
  kb: () => key_bag_exports,
4172
4300
  kc: () => keyed_crypto_exports,
4173
4301
  mf: () => wait_pr_multiformats_exports,
4302
+ runtimeFn: () => import_cement17.runtimeFn,
4174
4303
  toArrayBuffer: () => toArrayBuffer
4175
4304
  });
4176
4305
  init_utils2();
@@ -4186,6 +4315,7 @@ __export(wait_pr_multiformats_exports, {
4186
4315
  var codec_interface_exports = {};
4187
4316
 
4188
4317
  // src/runtime/index.ts
4318
+ var import_cement17 = require("@adviser/cement");
4189
4319
  init_version();
4190
4320
  init_version2();
4191
4321
 
@@ -4194,6 +4324,6 @@ init_utils();
4194
4324
 
4195
4325
  // src/version.ts
4196
4326
  var PACKAGE_VERSION = Object.keys({
4197
- "0.19.9-dev-frag": "xxxx"
4327
+ "0.19.11-dev-dryrun2": "xxxx"
4198
4328
  })[0];
4199
4329
  //# sourceMappingURL=index.cjs.map