@fireproof/core 0.20.0-dev-preview-41 → 0.20.0-dev-preview-50

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.
@@ -240,11 +240,16 @@ describe("Compact a named CRDT with writes", function () {
240
240
  });
241
241
  beforeEach(async () => {
242
242
  await sthis.start();
243
+ // sthis.env.set(
244
+ // "FP_STORAGE_URL",
245
+ // BuildURI.from(sthis.env.get("FP_STORAGE_URL")).setParam(PARAM.STORE_KEY, "insecure").toString(),
246
+ // );
247
+ // console.log("FP_STORAGE_URL", sthis.env.get("FP_STORAGE_URL"));
243
248
  const dbOpts: LedgerOpts = {
244
249
  name: "test-crdt",
245
250
  writeQueue: defaultWriteQueueOpts({}),
246
251
  keyBag: rt.defaultKeyBagOpts(sthis),
247
- storeUrls: toStoreURIRuntime(sthis, `named-crdt-compaction`),
252
+ storeUrls: toStoreURIRuntime(sthis, `named-crdt-compaction-${sthis.nextId().str}`),
248
253
  storeEnDe: bs.ensureStoreEnDeFile({}),
249
254
  };
250
255
  crdt = new CRDTImpl(sthis, dbOpts);
@@ -255,6 +260,7 @@ describe("Compact a named CRDT with writes", function () {
255
260
  ];
256
261
  await crdt.bulk(bulk);
257
262
  }
263
+ // await sleep(1000);
258
264
  });
259
265
  it("has data", async () => {
260
266
  const got = (await crdt.get("ace")) as DocValue<CRDTTestType>;
@@ -266,8 +272,41 @@ describe("Compact a named CRDT with writes", function () {
266
272
  for await (const blk of crdt.blockstore.entries()) {
267
273
  blz.push(blk);
268
274
  }
269
- expect(blz.length).toBe(13);
270
- });
275
+ // expect(blz.map((i) => sthis.txt.decode(i.bytes) + "\n=================\n")).toEqual([
276
+ //
277
+ // ])
278
+ expect(blz.map((i) => i.cid.toString())).toEqual([
279
+ "bafyreicuomyooryb747esregkhooc4phr656tocowyo6dwcocq22h7qdhu",
280
+ "bafyreig5jhovaiocwk3vfafzdspgtwinftjygyghjzigkc554muhdmp5ba",
281
+ "bafyreiegj7yumreue7llzqroebigscedyzrkeir3zneg5q7zia77itowy4",
282
+ "bafyreihobual6tt3hgdfve4h5uzt7fey62se3dfecbuj6f4ndkkwquke4u",
283
+ "bafyreibqqcs3r6mhpr3525na6jtqnjcf6dmgskk27x4a2jb3r2qveqgexm",
284
+ "bafyreibr7udlekt4xgavn54i4zfsdlrmi4r76iq6gh3bdq4xh52px6to3e",
285
+ "bafyreidg2eyas62nvwvi6ggq44tsldj4kwmupyk2xtwmxbwf77g3noqtp4",
286
+ "bafyreigbzxzj4eh7ljfvzlc7smdextuuk7gvep5mpnb3igaj5r2qzjlfye",
287
+ "bafyreicr7takuntpofvk52xerdcoiq7wdt73ef54acoya2geig2ywkqlsi",
288
+ "bafyreihmmgm5sufvnsgjic4fbizkdbajpy2yrklyieadstbtegfr4qko2m",
289
+ "bafyreibnu44uyu3ggqwgmnlxodw6dyta3qg7e5qldsjq7bkbv452ova6oa",
290
+ "bafyreieh4nlzg7enfczmj4z7uxvgrnykh7ajw7crxjrncqfrzj47ip6t6m",
291
+ "bafyreigqqrccymfvvdfetjd2twsdzjwxbb6cn6tedqntvpgp5vboky2ol4",
292
+ "bafyreid6kkobhgdmce2cyroepyos3jwumtdrfuzi6suldlxzjsgagc3fvi",
293
+ "bafyreibo2d56wo5ldey24hygtmsfhdxsqgdpmtne5oitehxjppipru33ma",
294
+ "bafyreifjv6havcza3is7w6ii345f5akba7e34xqcxwoqozmsnihkivykum",
295
+ "bafyreig6eroqeg3y7am4bnrun3yzbvd656epzxjyivdpzwqo3j3vpuwysi",
296
+ "bafyreibpsnfsducp7refempcyqnte54j7ueh4ysdlabggihclbddfnuzxm",
297
+ "bafyreicfkkygbzz5zawr3xbfah2gy3e7w4opzysew4tini7xnksujj4gf4",
298
+ "bafyreiddjm5xkpfa5vmyhoj5opocrwo6zbdnmqyhouc5ttfxoilmaf25bm",
299
+ "bafyreibp7vlgfexaknaoxpemnnwadyfa4cfuc3euzlkslskks2n44wwspu",
300
+ "bafyreichwj7izzpxeyjkhwl26pq45m4hnhxcgzqfk5ffeqkscafleiwfzm",
301
+ "bafyreidzjjqou36q2ghqdue4buq7536w4sl5aejni6tw25mzsusl26gtwu",
302
+ "bafyreibxibqhi6wh5klrje7ne4htffeqyyqfd6y7x2no6wnhid4nixizau",
303
+ "bafyreidnvv4mwvweup5w52ddre2sl4syhvczm6ejqsmuekajowdl2cf2q4",
304
+ "bafyreihh6nbfbhgkf5lz7hhsscjgiquw426rxzr3fprbgonekzmyvirrhe",
305
+ "bafyreiejg3twlaxr7gfvvhtxrhvwaydytdv4guidmtvaz5dskm6gp73ryi",
306
+ "bafyreiblui55o25dopc5faol3umsnuohb5carto7tot4kicnkfc37he4h4",
307
+ ]);
308
+ // expect(blz.length).toBe(13);
309
+ }, 1000000);
271
310
  it("should start with changes", async () => {
272
311
  const { result } = await crdt.changes();
273
312
  expect(result.length).toBe(2);
@@ -377,16 +416,16 @@ describe("Loader with a committed transaction", function () {
377
416
  it("should commit a transaction", function () {
378
417
  expect(done.head).toBeTruthy();
379
418
  // expect(done.cars).toBeTruthy();
380
- expect(loader.carLog.length).toBe(1);
419
+ expect(loader.carLog.length).toBe(1 + 1 /* genesis */);
381
420
  });
382
421
  it("can load the car", async () => {
383
- const blk = loader.carLog[0][0];
422
+ const blk = loader.carLog.asArray()[0][0];
384
423
  expect(blk).toBeTruthy();
385
424
  const reader = await loader.loadCar(blk, loader.attachedStores.local());
386
425
  expect(reader).toBeTruthy();
387
426
  const parsed = await bs.parseCarFile<CRDTMeta>(reader, loader.logger);
388
427
  expect(parsed.cars).toBeTruthy();
389
- expect(parsed.cars.length).toBe(0);
428
+ expect(parsed.cars.length).toBe(0 + 1 /* genesis */);
390
429
  expect(parsed.meta).toBeTruthy();
391
430
  expect(parsed.meta.head).toBeTruthy();
392
431
  });
@@ -427,20 +466,20 @@ describe("Loader with two committed transactions", function () {
427
466
  expect(done1.head).not.toBe(done2.head);
428
467
  // expect(done1.cars).not.toBe(done2.cars);
429
468
  // expect(blockstore.transactions.size).toBe(2);
430
- expect(loader.carLog.length).toBe(2);
469
+ expect(loader.carLog.length).toBe(2 + 1 /* genesis */);
431
470
  // expect(loader.carLog.indexOf(done1.cars)).toBe(1);
432
471
  // expect(loader.carLog.map((cs) => cs.toString()).indexOf(done1.cars.toString())).toBe(1);
433
472
  // expect(loader.carLog.indexOf(done2.cars)).toBe(0);
434
473
  // expect(loader.carLog.map((cs) => cs.toString()).indexOf(done2.cars.toString())).toBe(0);
435
474
  });
436
475
  it("can load the car", async () => {
437
- const blk = loader.carLog[0][0];
476
+ const blk = loader.carLog.asArray()[0][0];
438
477
  expect(blk).toBeTruthy();
439
478
  const reader = await loader.loadCar(blk, loader.attachedStores.local());
440
479
  expect(reader).toBeTruthy();
441
480
  const parsed = await bs.parseCarFile<CRDTMeta>(reader, loader.logger);
442
481
  expect(parsed.cars).toBeTruthy();
443
- expect(parsed.cars.length).toBe(1);
482
+ expect(parsed.cars.length).toBe(1 + 1 /* genesis */);
444
483
  expect(parsed.meta).toBeTruthy();
445
484
  expect(parsed.meta.head).toBeTruthy();
446
485
  });
@@ -482,16 +521,16 @@ describe("Loader with many committed transactions", function () {
482
521
  // expect(done.cars).toBeTruthy();
483
522
  }
484
523
  expect(blockstore.transactions.size).toBe(0); // cleaned up on commit
485
- expect(loader.carLog.length).toBe(count);
524
+ expect(loader.carLog.length).toBe(count + 1 /* genesis */);
486
525
  });
487
526
  it("can load the car", async () => {
488
- const blk = loader.carLog[2][0];
527
+ const blk = loader.carLog.asArray()[2][0];
489
528
  // expect(dones[5].cars).toBeTruthy();
490
529
  const reader = await loader.loadCar(blk, loader.attachedStores.local());
491
530
  expect(reader).toBeTruthy();
492
531
  const parsed = await bs.parseCarFile<CRDTMeta>(reader, loader.logger);
493
532
  expect(parsed.cars).toBeTruthy();
494
- expect(parsed.cars.length).toBe(7);
533
+ expect(parsed.cars.length).toBe(7 + 1 /* genesis */);
495
534
  expect(parsed.meta).toBeTruthy();
496
535
  expect(parsed.meta.head).toBeTruthy();
497
536
  });
@@ -136,6 +136,47 @@ describe("named Ledger with record", function () {
136
136
  expect(doc._id).toBe("hello");
137
137
  expect(doc.value).toBe("universe");
138
138
  });
139
+ it("should update with null value", async function () {
140
+ const ok = await db.put({ _id: "hello", value: null });
141
+ expect(ok.id).toBe("hello");
142
+ const doc = await db.get<Doc>("hello");
143
+ expect(doc).toBeTruthy();
144
+ expect(doc._id).toBe("hello");
145
+ expect(doc.value).toBeNull();
146
+ expect(Object.keys(doc).includes("value")).toBeTruthy();
147
+ });
148
+ it("should update with undefined value", async function () {
149
+ const ok = await db.put({ _id: "hello", value: undefined });
150
+ expect(ok.id).toBe("hello");
151
+ const doc = await db.get<Doc>("hello");
152
+ expect(doc).toBeTruthy();
153
+ expect(doc._id).toBe("hello");
154
+
155
+ // expect 'value' not to be in keys
156
+ expect(Object.keys(doc).includes("value")).toBeFalsy();
157
+ });
158
+ it("should update with NaN value", async function () {
159
+ const ok = await db.put({ _id: "hello", value: NaN });
160
+ expect(ok.id).toBe("hello");
161
+ const doc = await db.get<Doc>("hello");
162
+ expect(doc).toBeTruthy();
163
+ expect(doc._id).toBe("hello");
164
+
165
+ // expect 'value' not to be in keys
166
+ expect(Object.keys(doc).includes("value")).toBeFalsy();
167
+ });
168
+ it("should not update with Infinity value", async function () {
169
+ const ok = await db.put({ _id: "hello", value: Infinity }).catch((e) => e);
170
+ expect(ok.message).toMatch(/IPLD/);
171
+ });
172
+ it("should not update with undefined array value", async function () {
173
+ const ok = await db.put({ _id: "hello", value: [undefined] }).catch((e) => e);
174
+ expect(ok.message).toMatch(/IPLD/);
175
+ });
176
+ it("should not update with NaN array value", async function () {
177
+ const ok = await db.put({ _id: "hello", value: [NaN] }).catch((e) => e);
178
+ expect(ok.message).toMatch(/IPLD/);
179
+ });
139
180
  it("should del last record", async () => {
140
181
  const ok = await db.del("hello");
141
182
  expect(ok.id).toBe("hello");
@@ -409,7 +450,7 @@ describe("basic Ledger with no update subscription", function () {
409
450
  didRun++;
410
451
  });
411
452
  });
412
- it("should run on put", async () => {
453
+ it("xshould run on put", async function () {
413
454
  const all = await db.allDocs();
414
455
  expect(all.rows.length).toBe(0);
415
456
  /** @type {Doc} */
@@ -418,7 +459,7 @@ describe("basic Ledger with no update subscription", function () {
418
459
  const ok = await db.put(doc);
419
460
  expect(ok.id).toBe("hello");
420
461
  expect(didRun).toBe(1);
421
- });
462
+ }, 10000);
422
463
  it("should unsubscribe", async () => {
423
464
  unsubscribe();
424
465
  const doc = { _id: "hello", message: "again" };
@@ -521,7 +562,7 @@ describe("ledger with files input", () => {
521
562
 
522
563
  expect(file.type).toBe(imagefiles[0].file.type);
523
564
  expect(file.size).toBe(imagefiles[0].file.size);
524
- });
565
+ }, 1000000);
525
566
  });
526
567
 
527
568
  describe("StoreURIRuntime", () => {
@@ -551,14 +592,14 @@ describe("StoreURIRuntime", () => {
551
592
  it("default toStoreURIRuntime", () => {
552
593
  expect(JSON.parse(JSON.stringify(toStoreURIRuntime(sthis, "test")))).toEqual({
553
594
  data: {
554
- car: "my://bla/storage?name=test&store=data&storekey=%40test-data%40&suffix=.car&urlGen=fromEnv",
555
- file: "my://bla/storage?name=test&store=data&storekey=%40test-data%40&urlGen=fromEnv",
595
+ car: "my://bla/storage?name=test&store=car&storekey=%40test-data%40&suffix=.car&urlGen=fromEnv",
596
+ file: "my://bla/storage?name=test&store=file&storekey=%40test-data%40&urlGen=fromEnv",
556
597
  meta: "my://bla/storage?name=test&store=meta&storekey=%40test-meta%40&urlGen=fromEnv",
557
598
  wal: "my://bla/storage?name=test&store=wal&storekey=%40test-wal%40&urlGen=fromEnv",
558
599
  },
559
600
  idx: {
560
- car: "my://bla/storage?index=idx&name=test&store=data&storekey=%40test-data-idx%40&suffix=.car&urlGen=fromEnv",
561
- file: "my://bla/storage?index=idx&name=test&store=data&storekey=%40test-data-idx%40&urlGen=fromEnv",
601
+ car: "my://bla/storage?index=idx&name=test&store=car&storekey=%40test-data-idx%40&suffix=.car&urlGen=fromEnv",
602
+ file: "my://bla/storage?index=idx&name=test&store=file&storekey=%40test-data-idx%40&urlGen=fromEnv",
562
603
  meta: "my://bla/storage?index=idx&name=test&store=meta&storekey=%40test-meta-idx%40&urlGen=fromEnv",
563
604
  wal: "my://bla/storage?index=idx&name=test&store=wal&storekey=%40test-wal-idx%40&urlGen=fromEnv",
564
605
  },
@@ -568,14 +609,14 @@ describe("StoreURIRuntime", () => {
568
609
  it("no name toStoreURIRuntime(not more)", () => {
569
610
  expect(JSON.parse(JSON.stringify(toStoreURIRuntime(sthis, "gogo")))).toEqual({
570
611
  data: {
571
- car: "my://bla/storage?name=gogo&store=data&storekey=%40gogo-data%40&suffix=.car&urlGen=fromEnv",
572
- file: "my://bla/storage?name=gogo&store=data&storekey=%40gogo-data%40&urlGen=fromEnv",
612
+ car: "my://bla/storage?name=gogo&store=car&storekey=%40gogo-data%40&suffix=.car&urlGen=fromEnv",
613
+ file: "my://bla/storage?name=gogo&store=file&storekey=%40gogo-data%40&urlGen=fromEnv",
573
614
  meta: "my://bla/storage?name=gogo&store=meta&storekey=%40gogo-meta%40&urlGen=fromEnv",
574
615
  wal: "my://bla/storage?name=gogo&store=wal&storekey=%40gogo-wal%40&urlGen=fromEnv",
575
616
  },
576
617
  idx: {
577
- car: "my://bla/storage?index=idx&name=gogo&store=data&storekey=%40gogo-data-idx%40&suffix=.car&urlGen=fromEnv",
578
- file: "my://bla/storage?index=idx&name=gogo&store=data&storekey=%40gogo-data-idx%40&urlGen=fromEnv",
618
+ car: "my://bla/storage?index=idx&name=gogo&store=car&storekey=%40gogo-data-idx%40&suffix=.car&urlGen=fromEnv",
619
+ file: "my://bla/storage?index=idx&name=gogo&store=file&storekey=%40gogo-data-idx%40&urlGen=fromEnv",
579
620
  meta: "my://bla/storage?index=idx&name=gogo&store=meta&storekey=%40gogo-meta-idx%40&urlGen=fromEnv",
580
621
  wal: "my://bla/storage?index=idx&name=gogo&store=wal&storekey=%40gogo-wal-idx%40&urlGen=fromEnv",
581
622
  },
@@ -589,11 +630,11 @@ describe("StoreURIRuntime", () => {
589
630
  toStoreURIRuntime(sthis, "xxx", {
590
631
  base: "my://storage-base",
591
632
  data: {
592
- data: "my://storage-data?name=yyy",
633
+ car: "my://storage-data?name=yyy",
593
634
  meta: "my://storage-meta",
594
635
  },
595
636
  idx: {
596
- data: "my://storage-idx-data?name=yyy&index=bla",
637
+ car: "my://storage-idx-data?name=yyy&index=bla",
597
638
  meta: "my://storage-idx-meta",
598
639
  },
599
640
  }),
@@ -601,14 +642,14 @@ describe("StoreURIRuntime", () => {
601
642
  ),
602
643
  ).toEqual({
603
644
  data: {
604
- car: "my://storage-data?name=yyy&store=data&storekey=%40yyy-data%40&suffix=.car",
605
- file: "my://storage-data?name=yyy&store=data&storekey=%40yyy-data%40",
645
+ car: "my://storage-data?name=yyy&store=car&storekey=%40yyy-data%40&suffix=.car",
646
+ file: "my://storage-data?name=yyy&store=file&storekey=%40yyy-data%40",
606
647
  meta: "my://storage-meta?name=xxx&store=meta&storekey=%40xxx-meta%40",
607
648
  wal: "my://storage-base?name=xxx&store=wal&storekey=%40xxx-wal%40",
608
649
  },
609
650
  idx: {
610
- car: "my://storage-idx-data?index=bla&name=yyy&store=data&storekey=%40yyy-data-idx%40&suffix=.car",
611
- file: "my://storage-idx-data?index=bla&name=yyy&store=data&storekey=%40yyy-data-idx%40",
651
+ car: "my://storage-idx-data?index=bla&name=yyy&store=car&storekey=%40yyy-data-idx%40&suffix=.car",
652
+ file: "my://storage-idx-data?index=bla&name=yyy&store=file&storekey=%40yyy-data-idx%40",
612
653
  meta: "my://storage-idx-meta?index=idx&name=xxx&store=meta&storekey=%40xxx-meta-idx%40",
613
654
  wal: "my://storage-base?index=idx&name=xxx&store=wal&storekey=%40xxx-wal-idx%40",
614
655
  },
@@ -619,14 +660,14 @@ describe("StoreURIRuntime", () => {
619
660
  sthis.env.delete("FP_STORAGE_URL");
620
661
  expect(JSON.parse(JSON.stringify(toStoreURIRuntime(sthis, "maxi")))).toEqual({
621
662
  data: {
622
- car: "murks://fp?name=maxi&store=data&storekey=%40maxi-data%40&suffix=.car&urlGen=default",
623
- file: "murks://fp?name=maxi&store=data&storekey=%40maxi-data%40&urlGen=default",
663
+ car: "murks://fp?name=maxi&store=car&storekey=%40maxi-data%40&suffix=.car&urlGen=default",
664
+ file: "murks://fp?name=maxi&store=file&storekey=%40maxi-data%40&urlGen=default",
624
665
  meta: "murks://fp?name=maxi&store=meta&storekey=%40maxi-meta%40&urlGen=default",
625
666
  wal: "murks://fp?name=maxi&store=wal&storekey=%40maxi-wal%40&urlGen=default",
626
667
  },
627
668
  idx: {
628
- car: "murks://fp?index=idx&name=maxi&store=data&storekey=%40maxi-data-idx%40&suffix=.car&urlGen=default",
629
- file: "murks://fp?index=idx&name=maxi&store=data&storekey=%40maxi-data-idx%40&urlGen=default",
669
+ car: "murks://fp?index=idx&name=maxi&store=car&storekey=%40maxi-data-idx%40&suffix=.car&urlGen=default",
670
+ file: "murks://fp?index=idx&name=maxi&store=file&storekey=%40maxi-data-idx%40&urlGen=default",
630
671
  meta: "murks://fp?index=idx&name=maxi&store=meta&storekey=%40maxi-meta-idx%40&urlGen=default",
631
672
  wal: "murks://fp?index=idx&name=maxi&store=wal&storekey=%40maxi-wal-idx%40&urlGen=default",
632
673
  },
@@ -642,16 +683,16 @@ describe("StoreURIRuntime", () => {
642
683
  stores: [
643
684
  {
644
685
  data: {
645
- car: "my://bla/storage?name=test&store=data&storekey=%40test-data%40&suffix=.car&urlGen=fromEnv",
646
- file: "my://bla/storage?name=test&store=data&storekey=%40test-data%40&urlGen=fromEnv",
686
+ car: "my://bla/storage?name=test&store=car&storekey=%40test-data%40&suffix=.car&urlGen=fromEnv",
687
+ file: "my://bla/storage?name=test&store=file&storekey=%40test-data%40&urlGen=fromEnv",
647
688
  meta: "my://bla/storage?name=test&store=meta&storekey=%40test-meta%40&urlGen=fromEnv",
648
689
  wal: "my://bla/storage?name=test&store=wal&storekey=%40test-wal%40&urlGen=fromEnv",
649
690
  },
650
691
  },
651
692
  {
652
693
  idx: {
653
- car: "my://bla/storage?index=idx&name=test&store=data&storekey=%40test-data-idx%40&suffix=.car&urlGen=fromEnv",
654
- file: "my://bla/storage?index=idx&name=test&store=data&storekey=%40test-data-idx%40&urlGen=fromEnv",
694
+ car: "my://bla/storage?index=idx&name=test&store=car&storekey=%40test-data-idx%40&suffix=.car&urlGen=fromEnv",
695
+ file: "my://bla/storage?index=idx&name=test&store=file&storekey=%40test-data-idx%40&urlGen=fromEnv",
655
696
  meta: "my://bla/storage?index=idx&name=test&store=meta&storekey=%40test-meta-idx%40&urlGen=fromEnv",
656
697
  wal: "my://bla/storage?index=idx&name=test&store=wal&storekey=%40test-wal-idx%40&urlGen=fromEnv",
657
698
  },
@@ -131,12 +131,12 @@ describe("database fullconfig", () => {
131
131
  // meta: `${base}/meta?taste=${taste}`,
132
132
  data: {
133
133
  meta: base.build().pathname("dist/full/meta"),
134
- data: base.build().pathname("dist/full/data"),
134
+ car: base.build().pathname("dist/full/data"),
135
135
  wal: base.build().pathname("dist/full/wal"),
136
136
  },
137
137
  idx: {
138
138
  meta: base.build().pathname("dist/full/idx-meta"),
139
- data: base.build().pathname("dist/full/idx-data"),
139
+ car: base.build().pathname("dist/full/idx-data"),
140
140
  wal: base.build().pathname("dist/full/idx-wal"),
141
141
  },
142
142
  // wal: `${base}/wal?taste=${taste}`,
@@ -487,7 +487,7 @@ describe("Reopening a ledger", function () {
487
487
  const loader = blocks.loader;
488
488
  expect(loader).toBeDefined();
489
489
  expect(loader.carLog).toBeDefined();
490
- expect(loader.carLog.length).toBe(1);
490
+ expect(loader.carLog.length).toBe(1 + 1 /* genesis */);
491
491
  });
492
492
 
493
493
  it("should have carlog after reopen", async () => {
@@ -497,7 +497,7 @@ describe("Reopening a ledger", function () {
497
497
  const loader = blocks.loader;
498
498
  expect(loader).toBeDefined();
499
499
  expect(loader.carLog).toBeDefined();
500
- expect(loader.carLog.length).toBe(1);
500
+ expect(loader.carLog.length).toBe(1 + 1 /* genesis */);
501
501
  await db2.close();
502
502
  });
503
503
 
@@ -509,10 +509,10 @@ describe("Reopening a ledger", function () {
509
509
  await db.ready();
510
510
  const blocks = db.ledger.crdt.blockstore as bs.EncryptedBlockstore;
511
511
  const loader = blocks.loader;
512
- expect(loader.carLog.length).toBe(i + 1);
512
+ expect(loader.carLog.length).toBe(i + 1 + 1 /* genesis */);
513
513
  const ok = await db.put({ _id: `test${i}`, fire: "proof".repeat(50 * 1024) });
514
514
  expect(ok).toBeTruthy();
515
- expect(loader.carLog.length).toBe(i + 2);
515
+ expect(loader.carLog.length).toBe(i + 2 + 1 /* genesis */);
516
516
  const doc = await db.get<FireType>(`test${i}`);
517
517
  expect(doc.fire).toBe("proof".repeat(50 * 1024));
518
518
  await db.close();
@@ -663,7 +663,7 @@ describe("basic js verify", function () {
663
663
  const blocks = db.ledger.crdt.blockstore as bs.EncryptedBlockstore;
664
664
  const loader = blocks.loader;
665
665
  expect(loader).toBeTruthy();
666
- const cid = loader.carLog[0][0];
666
+ const cid = loader.carLog.asArray()[0][0];
667
667
  const cid2 = db.ledger.crdt.clock.head[0];
668
668
  expect(cid).not.toBe(cid2);
669
669
  expect(cid).not.toBe(cid2);
@@ -709,6 +709,7 @@ describe("same workload twice, same CID", function () {
709
709
  await sthis.start();
710
710
  // todo this fails because the test setup doesn't properly configure both ledgers to use the same key
711
711
  dbA = fireproof("test-dual-workload-a", configA);
712
+ await dbA.destroy();
712
713
  for (const doc of docs) {
713
714
  ok = await dbA.put(doc);
714
715
  expect(ok).toBeTruthy();
@@ -718,6 +719,7 @@ describe("same workload twice, same CID", function () {
718
719
 
719
720
  // todo this fails because the test setup doesn't properly configure both ledgers to use the same key
720
721
  dbB = fireproof("test-dual-workload-b", configB);
722
+ await dbA.destroy();
721
723
  for (const doc of docs) {
722
724
  ok = await dbB.put(doc);
723
725
  expect(ok).toBeTruthy();
@@ -735,15 +737,15 @@ describe("same workload twice, same CID", function () {
735
737
  const logA = dbA.ledger.crdt.blockstore.loader?.carLog;
736
738
  expect(logA).toBeTruthy();
737
739
  assert(logA);
738
- expect(logA.length).toBe(docs.length);
740
+ expect(logA.length).toBe(docs.length + 1 /*genesis*/);
739
741
 
740
742
  const logB = dbB.ledger.crdt.blockstore.loader?.carLog;
741
743
  expect(logB).toBeTruthy();
742
744
  assert(logB);
743
- expect(logB.length).toBe(docs.length);
745
+ expect(logB.length).toBe(docs.length + 1 /*genesis*/);
744
746
 
745
- const logA2 = logA.map((c) => c.toString());
746
- const logB2 = logB.map((c) => c.toString());
747
+ const logA2 = logA.asArray().map((c) => c.toString());
748
+ const logB2 = logB.asArray().map((c) => c.toString());
747
749
 
748
750
  expect(logA2.length).toBe(logB2.length);
749
751
 
@@ -764,8 +766,8 @@ describe("same workload twice, same CID", function () {
764
766
  assert(cmpLogB);
765
767
  expect(cmpLogB.length).toBe(1);
766
768
 
767
- const cmpLogA2 = cmpLogA.map((c) => c.toString());
768
- const cmpLogB2 = cmpLogB.map((c) => c.toString());
769
+ const cmpLogA2 = cmpLogA.asArray().map((c) => c.toString());
770
+ const cmpLogB2 = cmpLogB.asArray().map((c) => c.toString());
769
771
 
770
772
  expect(cmpLogA2.length).toBe(cmpLogB2.length);
771
773
 
@@ -0,0 +1,69 @@
1
+ import { sha256 } from "multiformats/hashes/sha2";
2
+ import { ensureSuperThis, rt, bs } from "@fireproof/core";
3
+ import { base58btc } from "multiformats/bases/base58";
4
+ import { URI, toCryptoRuntime } from "@adviser/cement";
5
+ import * as cborg from "cborg";
6
+
7
+ const sthis = ensureSuperThis();
8
+ describe.each([
9
+ async () => {
10
+ const kb = await rt.kb.getKeyBag(sthis, {});
11
+ const keyStr = base58btc.encode(toCryptoRuntime().randomBytes(kb.rt.keyLength));
12
+ return await rt.kc.keyedCryptoFactory(URI.from(`test://bla?storekey=${keyStr}`), kb, sthis);
13
+ },
14
+ async () => {
15
+ const kb = await rt.kb.getKeyBag(sthis, {});
16
+ return await rt.kc.keyedCryptoFactory(URI.from(`test://bla?storekey=insecure`), kb, sthis);
17
+ },
18
+ ])("regression of stable cid encoding", (factory) => {
19
+ let kycr: bs.CryptoAction;
20
+ beforeEach(async () => {
21
+ // let url: URI;
22
+ // if (runtimeFn().isBrowser) {
23
+ // url = URI.from("indexeddb://fp-keybag");
24
+ // } else {
25
+ // url = URI.merge(`file://./dist/tests/key.bag`, sthis.env.get("FP_KEYBAG_URL"));
26
+ // }
27
+ kycr = await factory();
28
+ });
29
+
30
+ it("should encode and decode a stable cid", async () => {
31
+ const x1 = await rt.mf.block.encode({
32
+ value: cborg.encode({ hello: "world" }),
33
+ // hashBytes: {
34
+ // as: (x: Uint8Array<ArrayBufferLike>): Promise<ByteView<Uint8Array>> => Promise.resolve(x),
35
+ // },
36
+ hasher: sha256,
37
+ codec: kycr.codec(toCryptoRuntime().randomBytes(12)),
38
+ });
39
+ const x2 = await rt.mf.block.encode({
40
+ value: cborg.encode({ hello: "world" }),
41
+ // hashBytes: {
42
+ // as: (x: Uint8Array<ArrayBufferLike>): Promise<ByteView<Uint8Array>> => Promise.resolve(x),
43
+ // },
44
+ hasher: sha256,
45
+ codec: kycr.codec(toCryptoRuntime().randomBytes(12)),
46
+ });
47
+ expect(x1.cid).toEqual(x2.cid);
48
+ });
49
+ it("decode stable cid", async () => {
50
+ const x1 = await rt.mf.block.encode({
51
+ value: cborg.encode({ hello: "world" }),
52
+ // hashBytes: {
53
+ // as: (x: Uint8Array<ArrayBufferLike>): Promise<ByteView<Uint8Array>> => Promise.resolve(x),
54
+ // },
55
+ hasher: sha256,
56
+ codec: kycr.codec(),
57
+ });
58
+ const x = await rt.mf.block.decode<bs.IvKeyIdData, 24, 18>({
59
+ bytes: x1.bytes,
60
+ // hashBytes: {
61
+ // get: (x: bs.IvKeyIdData): Promise<ByteView<Uint8Array>> => Promise.resolve(x.data as ByteView<Uint8Array<ArrayBufferLike>>),
62
+ // },
63
+ codec: kycr.codec(),
64
+ hasher: sha256,
65
+ });
66
+ expect(x.cid.toString()).toEqual(x1.cid.toString());
67
+ expect(cborg.decode(x.value.data)).toEqual({ hello: "world" });
68
+ }, 1000000);
69
+ });
@@ -17,22 +17,30 @@ describe("utils", () => {
17
17
 
18
18
  const storeOpts = [
19
19
  {
20
- type: "data",
20
+ type: "car",
21
+ pathPart: "data",
21
22
  suffix: ".car",
22
23
  },
24
+ {
25
+ type: "file",
26
+ pathPart: "data",
27
+ suffix: "",
28
+ },
23
29
  {
24
30
  type: "wal",
31
+ pathPart: "wal",
25
32
  suffix: ".json",
26
33
  },
27
34
  {
28
35
  type: "meta",
36
+ pathPart: "meta",
29
37
  suffix: ".json",
30
38
  },
31
39
  ];
32
40
  it("getfilename plain", () => {
33
41
  for (const store of storeOpts) {
34
42
  const url = URI.from(`file://./x/path?store=${store.type}&name=name&key=key&version=version&suffix=${store.suffix}`);
35
- expect(rt.getFileName(url, logger)).toEqual(`${store.type}/key${store.suffix}`);
43
+ expect(rt.getFileName(url, logger)).toEqual(`${store.pathPart}/key${store.suffix}`);
36
44
  }
37
45
  });
38
46
 
@@ -41,7 +49,7 @@ describe("utils", () => {
41
49
  const url = URI.from(
42
50
  `file://./x/path?index=idx&store=${store.type}&name=name&key=key&version=version&suffix=${store.suffix}`,
43
51
  );
44
- expect(rt.getFileName(url, logger)).toEqual(`idx-${store.type}/key${store.suffix}`);
52
+ expect(rt.getFileName(url, logger)).toEqual(`idx-${store.pathPart}/key${store.suffix}`);
45
53
  }
46
54
  });
47
55
 
@@ -49,8 +57,9 @@ describe("utils", () => {
49
57
  for (const store of storeOpts) {
50
58
  const url = URI.from(`file://./x/path?store=${store.type}&name=name&key=key&version=version`);
51
59
  expect(getStore(url, logger, (...toJoin) => toJoin.join("+"))).toEqual({
52
- name: store.type,
53
- store: store.type,
60
+ fromUrl: store.type,
61
+ name: store.pathPart,
62
+ pathPart: store.pathPart,
54
63
  });
55
64
  }
56
65
  });
@@ -59,8 +68,9 @@ describe("utils", () => {
59
68
  for (const store of storeOpts) {
60
69
  const url = URI.from(`file://./x/path?index=ix&store=${store.type}&name=name&key=key&version=version`);
61
70
  expect(getStore(url, logger, (...toJoin) => toJoin.join("+"))).toEqual({
62
- name: `ix+${store.type}`,
63
- store: store.type,
71
+ fromUrl: store.type,
72
+ pathPart: store.pathPart,
73
+ name: `ix+${store.pathPart}`,
64
74
  });
65
75
  }
66
76
  });
@@ -44,7 +44,7 @@ describe("config file gateway", () => {
44
44
  searchParams: {
45
45
  // ...isMemFS,
46
46
  name: "my-app",
47
- store: "data",
47
+ store: "file",
48
48
  storekey: "@my-app-data@",
49
49
  urlGen: "fromEnv",
50
50
  version: "v0.19-file",
@@ -59,7 +59,7 @@ describe("config file gateway", () => {
59
59
  searchParams: {
60
60
  // ...isMemFS,
61
61
  name: "my-app",
62
- store: "data",
62
+ store: "car",
63
63
  suffix: ".car",
64
64
  storekey: "@my-app-data@",
65
65
  urlGen: "fromEnv",
@@ -121,7 +121,7 @@ describe("config file gateway", () => {
121
121
  searchParams: {
122
122
  // ...isMemFS,
123
123
  name: "my-app",
124
- store: "data",
124
+ store: "car",
125
125
  storekey: "@my-app-data@",
126
126
  suffix: ".car",
127
127
  version: "v0.19-file",
@@ -135,7 +135,7 @@ describe("config file gateway", () => {
135
135
  searchParams: {
136
136
  // ...isMemFS,
137
137
  name: "my-app",
138
- store: "data",
138
+ store: "file",
139
139
  storekey: "@my-app-data@",
140
140
  version: "v0.19-file",
141
141
  },
@@ -191,7 +191,7 @@ describe("config file gateway", () => {
191
191
  suffix: ".car",
192
192
  runtime: runtimeFn().isDeno ? "deno" : "node",
193
193
  urlGen: "default",
194
- store: "data",
194
+ store: "car",
195
195
  name: my_app(),
196
196
  storekey: `@${my_app()}-data@`,
197
197
  version: rt.FILESTORE_VERSION,
@@ -209,7 +209,7 @@ describe("config file gateway", () => {
209
209
  // ...isMemFS,
210
210
  runtime: runtimeFn().isDeno ? "deno" : "node",
211
211
  urlGen: "default",
212
- store: "data",
212
+ store: "file",
213
213
  name: my_app(),
214
214
  storekey: `@${my_app()}-data@`,
215
215
  version: rt.FILESTORE_VERSION,
@@ -261,7 +261,7 @@ describe("config file gateway", () => {
261
261
  searchParams: {
262
262
  // ...isMemFS,
263
263
  urlGen: "fromEnv",
264
- store: "data",
264
+ store: "car",
265
265
  // runtime: "node",
266
266
  suffix: ".car",
267
267
  name: my_app(),
@@ -279,7 +279,7 @@ describe("config file gateway", () => {
279
279
  searchParams: {
280
280
  // ...isMemFS,
281
281
  urlGen: "fromEnv",
282
- store: "data",
282
+ store: "file",
283
283
  name: my_app(),
284
284
  storekey: `@${my_app()}-data@`,
285
285
  version: rt.FILESTORE_VERSION,