@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.
- package/deno.json +3 -2
- package/index.cjs +567 -340
- package/index.cjs.map +1 -1
- package/index.d.cts +210 -101
- package/index.d.ts +210 -101
- package/index.js +588 -360
- package/index.js.map +1 -1
- package/indexeddb/index.cjs.map +1 -1
- package/indexeddb/index.js.map +1 -1
- package/indexeddb/metafile-cjs.json +1 -1
- package/indexeddb/metafile-esm.json +1 -1
- package/metafile-cjs.json +1 -1
- package/metafile-esm.json +1 -1
- package/package.json +6 -4
- package/react/index.cjs.map +1 -1
- package/react/index.d.cts +3 -3
- package/react/index.d.ts +3 -3
- package/react/metafile-cjs.json +1 -1
- package/react/metafile-esm.json +1 -1
- package/tests/blockstore/interceptor-gateway.test.ts +11 -1
- package/tests/blockstore/keyed-crypto.test.ts +24 -23
- package/tests/blockstore/loader.test.ts +2 -2
- package/tests/blockstore/store.test.ts +8 -9
- package/tests/fireproof/all-gateway.test.ts +4 -4
- package/tests/fireproof/attachable.test.ts +295 -21
- package/tests/fireproof/crdt.test.ts +51 -12
- package/tests/fireproof/database.test.ts +66 -25
- package/tests/fireproof/fireproof.test.ts +15 -13
- package/tests/fireproof/stable-cid.test.ts +69 -0
- package/tests/fireproof/utils.test.ts +17 -7
- package/tests/gateway/file/loader-config.test.ts +8 -8
- package/tests/gateway/fp-envelope-serialize.test.ts +8 -8
- package/tests/gateway/indexeddb/loader-config.test.ts +2 -2
- package/tests/helpers.ts +8 -7
- package/tests/react/useFireproof.test.tsx +19 -13
@@ -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.
|
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("
|
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=
|
555
|
-
file: "my://bla/storage?name=test&store=
|
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=
|
561
|
-
file: "my://bla/storage?index=idx&name=test&store=
|
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=
|
572
|
-
file: "my://bla/storage?name=gogo&store=
|
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=
|
578
|
-
file: "my://bla/storage?index=idx&name=gogo&store=
|
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
|
-
|
633
|
+
car: "my://storage-data?name=yyy",
|
593
634
|
meta: "my://storage-meta",
|
594
635
|
},
|
595
636
|
idx: {
|
596
|
-
|
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=
|
605
|
-
file: "my://storage-data?name=yyy&store=
|
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=
|
611
|
-
file: "my://storage-idx-data?index=bla&name=yyy&store=
|
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=
|
623
|
-
file: "murks://fp?name=maxi&store=
|
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=
|
629
|
-
file: "murks://fp?index=idx&name=maxi&store=
|
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=
|
646
|
-
file: "my://bla/storage?name=test&store=
|
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=
|
654
|
-
file: "my://bla/storage?index=idx&name=test&store=
|
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
|
-
|
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
|
-
|
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: "
|
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.
|
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.
|
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
|
-
|
53
|
-
|
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
|
-
|
63
|
-
|
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: "
|
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: "
|
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: "
|
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: "
|
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: "
|
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: "
|
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: "
|
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: "
|
282
|
+
store: "file",
|
283
283
|
name: my_app(),
|
284
284
|
storekey: `@${my_app()}-data@`,
|
285
285
|
version: rt.FILESTORE_VERSION,
|