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

Sign up to get free protection for your applications and to get access to all the features.
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