@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.
- package/deno.json +3 -2
- package/index.cjs +576 -342
- package/index.cjs.map +1 -1
- package/index.d.cts +210 -101
- package/index.d.ts +210 -101
- package/index.js +597 -362
- 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 +52 -13
- package/tests/fireproof/database.test.ts +79 -25
- package/tests/fireproof/fireproof.test.ts +24 -19
- 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);
|
@@ -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("
|
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=
|
555
|
-
file: "my://bla/storage?name=test&store=
|
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=
|
561
|
-
file: "my://bla/storage?index=idx&name=test&store=
|
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=
|
572
|
-
file: "my://bla/storage?name=gogo&store=
|
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=
|
578
|
-
file: "my://bla/storage?index=idx&name=gogo&store=
|
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
|
-
|
646
|
+
car: "my://storage-data?name=yyy",
|
593
647
|
meta: "my://storage-meta",
|
594
648
|
},
|
595
649
|
idx: {
|
596
|
-
|
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=
|
605
|
-
file: "my://storage-data?name=yyy&store=
|
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=
|
611
|
-
file: "my://storage-idx-data?index=bla&name=yyy&store=
|
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=
|
623
|
-
file: "murks://fp?name=maxi&store=
|
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=
|
629
|
-
file: "murks://fp?index=idx&name=maxi&store=
|
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=
|
646
|
-
file: "my://bla/storage?name=test&store=
|
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=
|
654
|
-
file: "my://bla/storage?index=idx&name=test&store=
|
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
|
-
|
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().
|
134
|
-
|
135
|
-
wal: base.build().
|
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().
|
139
|
-
|
140
|
-
wal: base.build().
|
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: "
|
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
|
});
|