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

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);
@@ -332,7 +371,7 @@ describe("CRDT with an index", function () {
332
371
  expect(got.rows[0].id).toBe("king");
333
372
  expect(got.rows[0].key).toBe(10);
334
373
  });
335
- it("creating a different index with same name should not work", async () => {
374
+ it.skip("creating a different index with same name should not work", async () => {
336
375
  const e = await index(crdt, "points", (doc) => doc._id)
337
376
  .query()
338
377
  .catch((err) => err);
@@ -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,60 @@ 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 Date value", async function () {
140
+ const date = new Date();
141
+ const dateStr = date.toISOString();
142
+ const ok = await db.put({ _id: "hello", value: date });
143
+ expect(ok.id).toBe("hello");
144
+ const doc = await db.get<Doc>("hello");
145
+ expect(doc).toBeTruthy();
146
+ expect(doc._id).toBe("hello");
147
+ expect(doc.value).toBe(dateStr);
148
+ expect(typeof doc.value).toBe("string");
149
+ const parsed = new Date(doc.value);
150
+ expect(parsed).toStrictEqual(date);
151
+ });
152
+ it("should update with null value", async function () {
153
+ const ok = await db.put({ _id: "hello", value: null });
154
+ expect(ok.id).toBe("hello");
155
+ const doc = await db.get<Doc>("hello");
156
+ expect(doc).toBeTruthy();
157
+ expect(doc._id).toBe("hello");
158
+ expect(doc.value).toBeNull();
159
+ expect(Object.keys(doc).includes("value")).toBeTruthy();
160
+ });
161
+ it("should update with undefined value", async function () {
162
+ const ok = await db.put({ _id: "hello", value: undefined });
163
+ expect(ok.id).toBe("hello");
164
+ const doc = await db.get<Doc>("hello");
165
+ expect(doc).toBeTruthy();
166
+ expect(doc._id).toBe("hello");
167
+
168
+ // expect 'value' not to be in keys
169
+ expect(Object.keys(doc).includes("value")).toBeFalsy();
170
+ });
171
+ it("should update with NaN value", async function () {
172
+ const ok = await db.put({ _id: "hello", value: NaN });
173
+ expect(ok.id).toBe("hello");
174
+ const doc = await db.get<Doc>("hello");
175
+ expect(doc).toBeTruthy();
176
+ expect(doc._id).toBe("hello");
177
+
178
+ // expect 'value' not to be in keys
179
+ expect(Object.keys(doc).includes("value")).toBeFalsy();
180
+ });
181
+ it("should not update with Infinity value", async function () {
182
+ const ok = await db.put({ _id: "hello", value: Infinity }).catch((e) => e);
183
+ expect(ok.message).toMatch(/IPLD/);
184
+ });
185
+ it("should not update with undefined array value", async function () {
186
+ const ok = await db.put({ _id: "hello", value: [undefined] }).catch((e) => e);
187
+ expect(ok.message).toMatch(/IPLD/);
188
+ });
189
+ it("should not update with NaN array value", async function () {
190
+ const ok = await db.put({ _id: "hello", value: [NaN] }).catch((e) => e);
191
+ expect(ok.message).toMatch(/IPLD/);
192
+ });
139
193
  it("should del last record", async () => {
140
194
  const ok = await db.del("hello");
141
195
  expect(ok.id).toBe("hello");
@@ -409,7 +463,7 @@ describe("basic Ledger with no update subscription", function () {
409
463
  didRun++;
410
464
  });
411
465
  });
412
- it("should run on put", async () => {
466
+ it("xshould run on put", async function () {
413
467
  const all = await db.allDocs();
414
468
  expect(all.rows.length).toBe(0);
415
469
  /** @type {Doc} */
@@ -418,7 +472,7 @@ describe("basic Ledger with no update subscription", function () {
418
472
  const ok = await db.put(doc);
419
473
  expect(ok.id).toBe("hello");
420
474
  expect(didRun).toBe(1);
421
- });
475
+ }, 10000);
422
476
  it("should unsubscribe", async () => {
423
477
  unsubscribe();
424
478
  const doc = { _id: "hello", message: "again" };
@@ -521,7 +575,7 @@ describe("ledger with files input", () => {
521
575
 
522
576
  expect(file.type).toBe(imagefiles[0].file.type);
523
577
  expect(file.size).toBe(imagefiles[0].file.size);
524
- });
578
+ }, 1000000);
525
579
  });
526
580
 
527
581
  describe("StoreURIRuntime", () => {
@@ -551,14 +605,14 @@ describe("StoreURIRuntime", () => {
551
605
  it("default toStoreURIRuntime", () => {
552
606
  expect(JSON.parse(JSON.stringify(toStoreURIRuntime(sthis, "test")))).toEqual({
553
607
  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",
608
+ car: "my://bla/storage?name=test&store=car&storekey=%40test-data%40&suffix=.car&urlGen=fromEnv",
609
+ file: "my://bla/storage?name=test&store=file&storekey=%40test-data%40&urlGen=fromEnv",
556
610
  meta: "my://bla/storage?name=test&store=meta&storekey=%40test-meta%40&urlGen=fromEnv",
557
611
  wal: "my://bla/storage?name=test&store=wal&storekey=%40test-wal%40&urlGen=fromEnv",
558
612
  },
559
613
  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",
614
+ car: "my://bla/storage?index=idx&name=test&store=car&storekey=%40test-data-idx%40&suffix=.car&urlGen=fromEnv",
615
+ file: "my://bla/storage?index=idx&name=test&store=file&storekey=%40test-data-idx%40&urlGen=fromEnv",
562
616
  meta: "my://bla/storage?index=idx&name=test&store=meta&storekey=%40test-meta-idx%40&urlGen=fromEnv",
563
617
  wal: "my://bla/storage?index=idx&name=test&store=wal&storekey=%40test-wal-idx%40&urlGen=fromEnv",
564
618
  },
@@ -568,14 +622,14 @@ describe("StoreURIRuntime", () => {
568
622
  it("no name toStoreURIRuntime(not more)", () => {
569
623
  expect(JSON.parse(JSON.stringify(toStoreURIRuntime(sthis, "gogo")))).toEqual({
570
624
  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",
625
+ car: "my://bla/storage?name=gogo&store=car&storekey=%40gogo-data%40&suffix=.car&urlGen=fromEnv",
626
+ file: "my://bla/storage?name=gogo&store=file&storekey=%40gogo-data%40&urlGen=fromEnv",
573
627
  meta: "my://bla/storage?name=gogo&store=meta&storekey=%40gogo-meta%40&urlGen=fromEnv",
574
628
  wal: "my://bla/storage?name=gogo&store=wal&storekey=%40gogo-wal%40&urlGen=fromEnv",
575
629
  },
576
630
  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",
631
+ car: "my://bla/storage?index=idx&name=gogo&store=car&storekey=%40gogo-data-idx%40&suffix=.car&urlGen=fromEnv",
632
+ file: "my://bla/storage?index=idx&name=gogo&store=file&storekey=%40gogo-data-idx%40&urlGen=fromEnv",
579
633
  meta: "my://bla/storage?index=idx&name=gogo&store=meta&storekey=%40gogo-meta-idx%40&urlGen=fromEnv",
580
634
  wal: "my://bla/storage?index=idx&name=gogo&store=wal&storekey=%40gogo-wal-idx%40&urlGen=fromEnv",
581
635
  },
@@ -589,11 +643,11 @@ describe("StoreURIRuntime", () => {
589
643
  toStoreURIRuntime(sthis, "xxx", {
590
644
  base: "my://storage-base",
591
645
  data: {
592
- data: "my://storage-data?name=yyy",
646
+ car: "my://storage-data?name=yyy",
593
647
  meta: "my://storage-meta",
594
648
  },
595
649
  idx: {
596
- data: "my://storage-idx-data?name=yyy&index=bla",
650
+ car: "my://storage-idx-data?name=yyy&index=bla",
597
651
  meta: "my://storage-idx-meta",
598
652
  },
599
653
  }),
@@ -601,14 +655,14 @@ describe("StoreURIRuntime", () => {
601
655
  ),
602
656
  ).toEqual({
603
657
  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",
658
+ car: "my://storage-data?name=yyy&store=car&storekey=%40yyy-data%40&suffix=.car",
659
+ file: "my://storage-data?name=yyy&store=file&storekey=%40yyy-data%40",
606
660
  meta: "my://storage-meta?name=xxx&store=meta&storekey=%40xxx-meta%40",
607
661
  wal: "my://storage-base?name=xxx&store=wal&storekey=%40xxx-wal%40",
608
662
  },
609
663
  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",
664
+ car: "my://storage-idx-data?index=bla&name=yyy&store=car&storekey=%40yyy-data-idx%40&suffix=.car",
665
+ file: "my://storage-idx-data?index=bla&name=yyy&store=file&storekey=%40yyy-data-idx%40",
612
666
  meta: "my://storage-idx-meta?index=idx&name=xxx&store=meta&storekey=%40xxx-meta-idx%40",
613
667
  wal: "my://storage-base?index=idx&name=xxx&store=wal&storekey=%40xxx-wal-idx%40",
614
668
  },
@@ -619,14 +673,14 @@ describe("StoreURIRuntime", () => {
619
673
  sthis.env.delete("FP_STORAGE_URL");
620
674
  expect(JSON.parse(JSON.stringify(toStoreURIRuntime(sthis, "maxi")))).toEqual({
621
675
  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",
676
+ car: "murks://fp?name=maxi&store=car&storekey=%40maxi-data%40&suffix=.car&urlGen=default",
677
+ file: "murks://fp?name=maxi&store=file&storekey=%40maxi-data%40&urlGen=default",
624
678
  meta: "murks://fp?name=maxi&store=meta&storekey=%40maxi-meta%40&urlGen=default",
625
679
  wal: "murks://fp?name=maxi&store=wal&storekey=%40maxi-wal%40&urlGen=default",
626
680
  },
627
681
  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",
682
+ car: "murks://fp?index=idx&name=maxi&store=car&storekey=%40maxi-data-idx%40&suffix=.car&urlGen=default",
683
+ file: "murks://fp?index=idx&name=maxi&store=file&storekey=%40maxi-data-idx%40&urlGen=default",
630
684
  meta: "murks://fp?index=idx&name=maxi&store=meta&storekey=%40maxi-meta-idx%40&urlGen=default",
631
685
  wal: "murks://fp?index=idx&name=maxi&store=wal&storekey=%40maxi-wal-idx%40&urlGen=default",
632
686
  },
@@ -642,16 +696,16 @@ describe("StoreURIRuntime", () => {
642
696
  stores: [
643
697
  {
644
698
  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",
699
+ car: "my://bla/storage?name=test&store=car&storekey=%40test-data%40&suffix=.car&urlGen=fromEnv",
700
+ file: "my://bla/storage?name=test&store=file&storekey=%40test-data%40&urlGen=fromEnv",
647
701
  meta: "my://bla/storage?name=test&store=meta&storekey=%40test-meta%40&urlGen=fromEnv",
648
702
  wal: "my://bla/storage?name=test&store=wal&storekey=%40test-wal%40&urlGen=fromEnv",
649
703
  },
650
704
  },
651
705
  {
652
706
  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",
707
+ car: "my://bla/storage?index=idx&name=test&store=car&storekey=%40test-data-idx%40&suffix=.car&urlGen=fromEnv",
708
+ file: "my://bla/storage?index=idx&name=test&store=file&storekey=%40test-data-idx%40&urlGen=fromEnv",
655
709
  meta: "my://bla/storage?index=idx&name=test&store=meta&storekey=%40test-meta-idx%40&urlGen=fromEnv",
656
710
  wal: "my://bla/storage?index=idx&name=test&store=wal&storekey=%40test-wal-idx%40&urlGen=fromEnv",
657
711
  },
@@ -121,23 +121,26 @@ describe("database fullconfig", () => {
121
121
  it("have the right name", async () => {
122
122
  let protocol: string | undefined;
123
123
  const url = sthis.env.get("FP_STORAGE_URL");
124
+ let path = "";
124
125
  if (url) {
125
- protocol = URI.from(url).protocol;
126
+ const uri = URI.from(url);
127
+ protocol = uri.protocol;
128
+ path = uri.pathname;
126
129
  }
127
- const base = bs.getDefaultURI(sthis, protocol);
130
+ const base = bs.getDefaultURI(sthis, protocol).build().appendRelative(path).URI();
128
131
  const db = fireproof("my-funky-name", {
129
132
  storeUrls: {
130
133
  base: base,
131
134
  // meta: `${base}/meta?taste=${taste}`,
132
135
  data: {
133
- meta: base.build().pathname("dist/full/meta"),
134
- data: base.build().pathname("dist/full/data"),
135
- wal: base.build().pathname("dist/full/wal"),
136
+ meta: base.build().appendRelative("funky/meta"),
137
+ car: base.build().appendRelative("funky/data"),
138
+ wal: base.build().appendRelative("funky/wal"),
136
139
  },
137
140
  idx: {
138
- meta: base.build().pathname("dist/full/idx-meta"),
139
- data: base.build().pathname("dist/full/idx-data"),
140
- wal: base.build().pathname("dist/full/idx-wal"),
141
+ meta: base.build().appendRelative("funky/idx-meta"),
142
+ car: base.build().appendRelative("funky/idx-data"),
143
+ wal: base.build().appendRelative("funky/idx-wal"),
141
144
  },
142
145
  // wal: `${base}/wal?taste=${taste}`,
143
146
  },
@@ -487,7 +490,7 @@ describe("Reopening a ledger", function () {
487
490
  const loader = blocks.loader;
488
491
  expect(loader).toBeDefined();
489
492
  expect(loader.carLog).toBeDefined();
490
- expect(loader.carLog.length).toBe(1);
493
+ expect(loader.carLog.length).toBe(1 + 1 /* genesis */);
491
494
  });
492
495
 
493
496
  it("should have carlog after reopen", async () => {
@@ -497,7 +500,7 @@ describe("Reopening a ledger", function () {
497
500
  const loader = blocks.loader;
498
501
  expect(loader).toBeDefined();
499
502
  expect(loader.carLog).toBeDefined();
500
- expect(loader.carLog.length).toBe(1);
503
+ expect(loader.carLog.length).toBe(1 + 1 /* genesis */);
501
504
  await db2.close();
502
505
  });
503
506
 
@@ -509,10 +512,10 @@ describe("Reopening a ledger", function () {
509
512
  await db.ready();
510
513
  const blocks = db.ledger.crdt.blockstore as bs.EncryptedBlockstore;
511
514
  const loader = blocks.loader;
512
- expect(loader.carLog.length).toBe(i + 1);
515
+ expect(loader.carLog.length).toBe(i + 1 + 1 /* genesis */);
513
516
  const ok = await db.put({ _id: `test${i}`, fire: "proof".repeat(50 * 1024) });
514
517
  expect(ok).toBeTruthy();
515
- expect(loader.carLog.length).toBe(i + 2);
518
+ expect(loader.carLog.length).toBe(i + 2 + 1 /* genesis */);
516
519
  const doc = await db.get<FireType>(`test${i}`);
517
520
  expect(doc.fire).toBe("proof".repeat(50 * 1024));
518
521
  await db.close();
@@ -663,7 +666,7 @@ describe("basic js verify", function () {
663
666
  const blocks = db.ledger.crdt.blockstore as bs.EncryptedBlockstore;
664
667
  const loader = blocks.loader;
665
668
  expect(loader).toBeTruthy();
666
- const cid = loader.carLog[0][0];
669
+ const cid = loader.carLog.asArray()[0][0];
667
670
  const cid2 = db.ledger.crdt.clock.head[0];
668
671
  expect(cid).not.toBe(cid2);
669
672
  expect(cid).not.toBe(cid2);
@@ -709,6 +712,7 @@ describe("same workload twice, same CID", function () {
709
712
  await sthis.start();
710
713
  // todo this fails because the test setup doesn't properly configure both ledgers to use the same key
711
714
  dbA = fireproof("test-dual-workload-a", configA);
715
+ await dbA.destroy();
712
716
  for (const doc of docs) {
713
717
  ok = await dbA.put(doc);
714
718
  expect(ok).toBeTruthy();
@@ -718,6 +722,7 @@ describe("same workload twice, same CID", function () {
718
722
 
719
723
  // todo this fails because the test setup doesn't properly configure both ledgers to use the same key
720
724
  dbB = fireproof("test-dual-workload-b", configB);
725
+ await dbA.destroy();
721
726
  for (const doc of docs) {
722
727
  ok = await dbB.put(doc);
723
728
  expect(ok).toBeTruthy();
@@ -735,15 +740,15 @@ describe("same workload twice, same CID", function () {
735
740
  const logA = dbA.ledger.crdt.blockstore.loader?.carLog;
736
741
  expect(logA).toBeTruthy();
737
742
  assert(logA);
738
- expect(logA.length).toBe(docs.length);
743
+ expect(logA.length).toBe(docs.length + 1 /*genesis*/);
739
744
 
740
745
  const logB = dbB.ledger.crdt.blockstore.loader?.carLog;
741
746
  expect(logB).toBeTruthy();
742
747
  assert(logB);
743
- expect(logB.length).toBe(docs.length);
748
+ expect(logB.length).toBe(docs.length + 1 /*genesis*/);
744
749
 
745
- const logA2 = logA.map((c) => c.toString());
746
- const logB2 = logB.map((c) => c.toString());
750
+ const logA2 = logA.asArray().map((c) => c.toString());
751
+ const logB2 = logB.asArray().map((c) => c.toString());
747
752
 
748
753
  expect(logA2.length).toBe(logB2.length);
749
754
 
@@ -764,8 +769,8 @@ describe("same workload twice, same CID", function () {
764
769
  assert(cmpLogB);
765
770
  expect(cmpLogB.length).toBe(1);
766
771
 
767
- const cmpLogA2 = cmpLogA.map((c) => c.toString());
768
- const cmpLogB2 = cmpLogB.map((c) => c.toString());
772
+ const cmpLogA2 = cmpLogA.asArray().map((c) => c.toString());
773
+ const cmpLogB2 = cmpLogB.asArray().map((c) => c.toString());
769
774
 
770
775
  expect(cmpLogA2.length).toBe(cmpLogB2.length);
771
776
 
@@ -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
  });