@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
@@ -1,12 +1,11 @@
|
|
1
|
-
import { bs, ensureSuperThis, PARAM, rt } from "@fireproof/core";
|
1
|
+
import { bs, ensureSuperThis, PARAM, rt, StoreType, storeType2DataMetaWal } from "@fireproof/core";
|
2
2
|
import { BuildURI, runtimeFn, toCryptoRuntime, URI } from "@adviser/cement";
|
3
3
|
import { base58btc } from "multiformats/bases/base58";
|
4
|
-
import { sha256 as hasher } from "multiformats/hashes/sha2";
|
5
|
-
import * as dagCodec from "@ipld/dag-cbor";
|
4
|
+
// import { sha256 as hasher } from "multiformats/hashes/sha2";
|
5
|
+
// import * as dagCodec from "@ipld/dag-cbor";
|
6
|
+
import * as cborg from "cborg";
|
6
7
|
import type { KeyBagProviderIndexedDB } from "@fireproof/core/indexeddb";
|
7
8
|
import { mockLoader, MockSuperThis, mockSuperThis } from "../helpers.js";
|
8
|
-
import { KeyWithFingerPrint } from "../../src/blockstore/types.js";
|
9
|
-
import { toKeyWithFingerPrint } from "../../src/runtime/key-bag.js";
|
10
9
|
|
11
10
|
describe("KeyBag", () => {
|
12
11
|
let url: URI;
|
@@ -113,10 +112,10 @@ describe("KeyBag", () => {
|
|
113
112
|
return JSON.parse(sthis.txt.decode(data)) as rt.kb.KeysItem;
|
114
113
|
});
|
115
114
|
}
|
116
|
-
expect((await toKeyWithFingerPrint(kb, Object.values(diskBag.keys)[0].key)).Ok().fingerPrint).toEqual(
|
115
|
+
expect((await rt.toKeyWithFingerPrint(kb, Object.values(diskBag.keys)[0].key)).Ok().fingerPrint).toEqual(
|
117
116
|
(await res.Ok().get())?.fingerPrint,
|
118
117
|
);
|
119
|
-
expect((await toKeyWithFingerPrint(kb, Object.values(diskBag2.keys)[0].key)).Ok().fingerPrint).toEqual(
|
118
|
+
expect((await rt.toKeyWithFingerPrint(kb, Object.values(diskBag2.keys)[0].key)).Ok().fingerPrint).toEqual(
|
120
119
|
(await created.Ok().get())?.fingerPrint,
|
121
120
|
);
|
122
121
|
const algo = {
|
@@ -129,7 +128,7 @@ describe("KeyBag", () => {
|
|
129
128
|
expect(await kb.rt.crypto.encrypt(algo, (await res.Ok().get())!.key, data))
|
130
129
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
131
130
|
.toEqual(await kb.rt.crypto.encrypt(algo, (await created.Ok().get())!.key, data));
|
132
|
-
const kf = (await created.Ok().get()) as KeyWithFingerPrint;
|
131
|
+
const kf = (await created.Ok().get()) as bs.KeyWithFingerPrint;
|
133
132
|
expect(await kb.rt.crypto.encrypt(algo, await kb.subtleKey(Object.values(diskBag.keys)[0].key), data)).toEqual(
|
134
133
|
await kb.rt.crypto.encrypt(algo, kf.key, data),
|
135
134
|
);
|
@@ -150,11 +149,11 @@ describe("KeyBag", () => {
|
|
150
149
|
}
|
151
150
|
expect(Object.keys((await kb.getNamedKey(name).then((i) => i.Ok().asKeysItem())).keys).length).toBe(1);
|
152
151
|
|
153
|
-
const myKey = (await rMyKey.Ok().get()) as KeyWithFingerPrint;
|
152
|
+
const myKey = (await rMyKey.Ok().get()) as bs.KeyWithFingerPrint;
|
154
153
|
expect(myKey.fingerPrint).toMatch(/^z/);
|
155
154
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
156
155
|
await rMyKey.Ok().upsert((await myKey.extract())!.key);
|
157
|
-
const myKey1 = (await rMyKey.Ok().get()) as KeyWithFingerPrint;
|
156
|
+
const myKey1 = (await rMyKey.Ok().get()) as bs.KeyWithFingerPrint;
|
158
157
|
expect(myKey.fingerPrint).toEqual(myKey1.fingerPrint);
|
159
158
|
|
160
159
|
expect(Object.keys((await kb.getNamedKey(name).then((i) => i.Ok().asKeysItem())).keys).length).toBe(1);
|
@@ -164,13 +163,13 @@ describe("KeyBag", () => {
|
|
164
163
|
const res1 = await rMyKey1.Ok().upsert(kb.rt.crypto.randomBytes(kb.rt.keyLength));
|
165
164
|
expect(res1.isOk()).toBeTruthy();
|
166
165
|
|
167
|
-
const myKey2 = (await rMyKey1.Ok().get()) as KeyWithFingerPrint;
|
166
|
+
const myKey2 = (await rMyKey1.Ok().get()) as bs.KeyWithFingerPrint;
|
168
167
|
expect(myKey.fingerPrint).toEqual(myKey2.fingerPrint);
|
169
168
|
expect(Object.keys((await kb.getNamedKey(name).then((i) => i.Ok().asKeysItem())).keys).length).toBe(2);
|
170
169
|
|
171
170
|
const res = await rMyKey1.Ok().upsert(kb.rt.crypto.randomBytes(kb.rt.keyLength), true);
|
172
171
|
expect(res.isOk()).toBeTruthy();
|
173
|
-
const myKey3 = (await rMyKey.Ok().get()) as KeyWithFingerPrint;
|
172
|
+
const myKey3 = (await rMyKey.Ok().get()) as bs.KeyWithFingerPrint;
|
174
173
|
expect(Object.keys((await kb.getNamedKey(name).then((i) => i.Ok().asKeysItem())).keys).length).toBe(3);
|
175
174
|
|
176
175
|
expect(myKey.fingerPrint).not.toEqual(myKey3.fingerPrint);
|
@@ -185,7 +184,7 @@ describe("KeyBag", () => {
|
|
185
184
|
});
|
186
185
|
const key = base58btc.encode(kb.rt.crypto.randomBytes(kb.rt.keyLength));
|
187
186
|
const name = "default-key" + Math.random();
|
188
|
-
const fpr = (await toKeyWithFingerPrint(kb, key)).Ok().fingerPrint;
|
187
|
+
const fpr = (await rt.toKeyWithFingerPrint(kb, key)).Ok().fingerPrint;
|
189
188
|
const rMyKey = await kb.getNamedKey(name, false, key);
|
190
189
|
expect(rMyKey.isOk()).toBeTruthy();
|
191
190
|
const myKey = rMyKey.Ok();
|
@@ -199,7 +198,7 @@ describe("KeyBag", () => {
|
|
199
198
|
const keys = [{ key, fpr }];
|
200
199
|
for (let i = 0; i < 10; ++i) {
|
201
200
|
const key = base58btc.encode(kb.rt.crypto.randomBytes(kb.rt.keyLength));
|
202
|
-
const fpr = (await toKeyWithFingerPrint(kb, key)).Ok().fingerPrint;
|
201
|
+
const fpr = (await rt.toKeyWithFingerPrint(kb, key)).Ok().fingerPrint;
|
203
202
|
keys.push({ key, fpr });
|
204
203
|
const rUpsert = await myKey.upsert(key, true);
|
205
204
|
expect(rUpsert.Ok().modified).toBeTruthy();
|
@@ -278,7 +277,9 @@ describe("KeyedCryptoStore", () => {
|
|
278
277
|
const kc = await store.keyedCrypto();
|
279
278
|
expect(kc.constructor.name).toBe("cryptoAction");
|
280
279
|
// expect(kc.isEncrypting).toBe(true);
|
281
|
-
expect(store.url().getParam(PARAM.STORE_KEY)).toBe(
|
280
|
+
expect(store.url().getParam(PARAM.STORE_KEY)).toBe(
|
281
|
+
`@test-${storeType2DataMetaWal(store.url().getParam(PARAM.STORE) as StoreType)}@`,
|
282
|
+
);
|
282
283
|
}
|
283
284
|
});
|
284
285
|
|
@@ -297,7 +298,7 @@ describe("KeyedCryptoStore", () => {
|
|
297
298
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
298
299
|
const blk = await kc._encrypt({ bytes: testData, key: (await kc.key.get())!.key, iv });
|
299
300
|
expect(blk).not.toEqual(testData);
|
300
|
-
const fpkey = (await genKey.Ok().get()) as KeyWithFingerPrint;
|
301
|
+
const fpkey = (await genKey.Ok().get()) as bs.KeyWithFingerPrint;
|
301
302
|
expect(fpkey.fingerPrint).toEqual(fpkey.fingerPrint);
|
302
303
|
const dec = new Uint8Array(await kc.crypto.decrypt(kc.algo(iv), fpkey.key, blk));
|
303
304
|
expect(dec).toEqual(testData);
|
@@ -316,7 +317,7 @@ describe("KeyedCryptoStore", () => {
|
|
316
317
|
expect(kc.constructor.name).toBe("cryptoAction");
|
317
318
|
const testData = kb.rt.crypto.randomBytes(1024);
|
318
319
|
const iv = kb.rt.crypto.randomBytes(12);
|
319
|
-
const ks = (await kc.key.get()) as KeyWithFingerPrint;
|
320
|
+
const ks = (await kc.key.get()) as bs.KeyWithFingerPrint;
|
320
321
|
const blk = await kc._encrypt({ bytes: testData, key: ks.key, iv });
|
321
322
|
expect(blk).not.toEqual(testData);
|
322
323
|
const dec = await kc._decrypt({ bytes: blk, key: ks.key, iv });
|
@@ -348,12 +349,12 @@ describe("KeyedCrypto", () => {
|
|
348
349
|
const iv = kb.rt.crypto.randomBytes(12);
|
349
350
|
const codec = kycr.codec(iv, { noIVVerify: true });
|
350
351
|
const blk = (await codec.encode(testData)) as Uint8Array;
|
351
|
-
const myDec =
|
352
|
-
expect(myDec.
|
353
|
-
const kc = (await kycr.key.get()) as KeyWithFingerPrint;
|
354
|
-
expect(base58btc.encode(myDec.
|
352
|
+
const myDec = cborg.decode(blk) as bs.IvKeyIdData;
|
353
|
+
expect(myDec.iv).toEqual(iv);
|
354
|
+
const kc = (await kycr.key.get()) as bs.KeyWithFingerPrint;
|
355
|
+
expect(base58btc.encode(myDec.keyId)).toEqual(kc.fingerPrint);
|
355
356
|
const dec = await codec.decode(blk);
|
356
|
-
expect(dec).toEqual(testData);
|
357
|
+
expect(dec.data).toEqual(testData);
|
357
358
|
});
|
358
359
|
|
359
360
|
it("codec implict iv", async () => {
|
@@ -362,7 +363,7 @@ describe("KeyedCrypto", () => {
|
|
362
363
|
const blk = await codec.encode(testData);
|
363
364
|
expect(blk.length).toBeGreaterThanOrEqual(12 + testData.length);
|
364
365
|
const dec = await codec.decode(blk);
|
365
|
-
expect(dec).toEqual(testData);
|
366
|
+
expect(dec.data).toEqual(testData);
|
366
367
|
});
|
367
368
|
|
368
369
|
it("codec implict iv same for multiple clients", async () => {
|
@@ -154,8 +154,8 @@ describe("basic Loader with two commits", function () {
|
|
154
154
|
|
155
155
|
it("should have a car log", function () {
|
156
156
|
expect(loader.carLog.length).toBe(2);
|
157
|
-
expect(loader.carLog[0].toString()).toBe(carCid.toString());
|
158
|
-
expect(loader.carLog[1].toString()).toBe(carCid0.toString());
|
157
|
+
expect(loader.carLog.asArray()[0].toString()).toBe(carCid.toString());
|
158
|
+
expect(loader.carLog.asArray()[1].toString()).toBe(carCid0.toString());
|
159
159
|
});
|
160
160
|
|
161
161
|
it("should commit", async () => {
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import { CID } from "multiformats";
|
2
2
|
import { rt, bs, NotFoundError, PARAM, ensureSuperThis } from "@fireproof/core";
|
3
3
|
import { Result } from "@adviser/cement";
|
4
|
-
import { createAttachedStores } from "../../src/blockstore/attachable-store.js";
|
5
4
|
import { mockLoader, noopUrl } from "../helpers.js";
|
6
5
|
|
7
6
|
// function runtime(sthis: SuperThis) {
|
@@ -17,8 +16,8 @@ import { mockLoader, noopUrl } from "../helpers.js";
|
|
17
16
|
// };
|
18
17
|
// }
|
19
18
|
|
20
|
-
describe("
|
21
|
-
let store: bs.
|
19
|
+
describe("CarStore", function () {
|
20
|
+
let store: bs.CarStore;
|
22
21
|
const sthis = ensureSuperThis();
|
23
22
|
const loader = mockLoader(sthis);
|
24
23
|
|
@@ -29,7 +28,7 @@ describe("DataStore", function () {
|
|
29
28
|
|
30
29
|
beforeEach(async () => {
|
31
30
|
await sthis.start();
|
32
|
-
const at = await createAttachedStores(noopUrl("test"), loader);
|
31
|
+
const at = await bs.createAttachedStores(noopUrl("test"), loader);
|
33
32
|
store = at.stores.car;
|
34
33
|
await store.start(at.stores);
|
35
34
|
});
|
@@ -49,8 +48,8 @@ describe("DataStore", function () {
|
|
49
48
|
});
|
50
49
|
});
|
51
50
|
|
52
|
-
describe("
|
53
|
-
let store: bs.
|
51
|
+
describe("CarStore with a saved car", function () {
|
52
|
+
let store: bs.CarStore;
|
54
53
|
let car: bs.AnyBlock;
|
55
54
|
|
56
55
|
const sthis = ensureSuperThis();
|
@@ -64,7 +63,7 @@ describe("DataStore with a saved car", function () {
|
|
64
63
|
beforeEach(async () => {
|
65
64
|
await sthis.start();
|
66
65
|
|
67
|
-
const at = await createAttachedStores(noopUrl("test2"), loader);
|
66
|
+
const at = await bs.createAttachedStores(noopUrl("test2"), loader);
|
68
67
|
store = at.stores.car;
|
69
68
|
await store.start(at.stores);
|
70
69
|
car = {
|
@@ -105,7 +104,7 @@ describe("MetaStore", function () {
|
|
105
104
|
|
106
105
|
beforeEach(async () => {
|
107
106
|
await sthis.start();
|
108
|
-
const at = await createAttachedStores(noopUrl("test"), loader);
|
107
|
+
const at = await bs.createAttachedStores(noopUrl("test"), loader);
|
109
108
|
store = at.stores.meta;
|
110
109
|
await store.start(at.stores);
|
111
110
|
});
|
@@ -145,7 +144,7 @@ describe("MetaStore with a saved header", function () {
|
|
145
144
|
|
146
145
|
beforeEach(async () => {
|
147
146
|
await sthis.start();
|
148
|
-
const at = await createAttachedStores(noopUrl("test3-meta"), loader);
|
147
|
+
const at = await bs.createAttachedStores(noopUrl("test3-meta"), loader);
|
149
148
|
store = at.stores.meta;
|
150
149
|
await store.start(at.stores);
|
151
150
|
cid = CID.parse("bafybeia4luuns6dgymy5kau5rm7r4qzrrzg6cglpzpogussprpy42cmcn4");
|
@@ -32,9 +32,9 @@ import { Future } from "@adviser/cement";
|
|
32
32
|
|
33
33
|
describe("noop Gateway", function () {
|
34
34
|
let db: Ledger;
|
35
|
-
let carStore: bs.
|
35
|
+
let carStore: bs.CarStore;
|
36
36
|
let metaStore: bs.MetaStore;
|
37
|
-
let fileStore: bs.
|
37
|
+
let fileStore: bs.FileStore;
|
38
38
|
let walStore: bs.WALStore;
|
39
39
|
let carGateway: bs.SerdeGateway;
|
40
40
|
let metaGateway: bs.SerdeGateway;
|
@@ -90,10 +90,10 @@ describe("noop Gateway", function () {
|
|
90
90
|
|
91
91
|
it("should have correct store types in URLs", async () => {
|
92
92
|
// Check that all stores have the correct store type in their URL
|
93
|
-
expect(carStore.url().toString()).toContain("store=
|
93
|
+
expect(carStore.url().toString()).toContain("store=car");
|
94
94
|
expect(carStore.url().toString()).toContain("suffix=.car");
|
95
95
|
expect(metaStore.url().toString()).toContain("store=meta");
|
96
|
-
expect(fileStore.url().toString()).toContain("store=
|
96
|
+
expect(fileStore.url().toString()).toContain("store=file");
|
97
97
|
expect(walStore.url().toString()).toContain("store=wal");
|
98
98
|
});
|
99
99
|
|
@@ -1,6 +1,207 @@
|
|
1
|
-
import {
|
1
|
+
import { URI } from "@adviser/cement";
|
2
|
+
import { stripper } from "@adviser/cement/utils";
|
3
|
+
import { Attachable, Database, ensureSuperThis, fireproof, GatewayUrlsParam, PARAM, rt, Attached, bs } from "@fireproof/core";
|
4
|
+
import { CarReader } from "@ipld/car/reader";
|
5
|
+
import * as dagCbor from "@ipld/dag-cbor";
|
6
|
+
import { sleep } from "../helpers.js";
|
7
|
+
import { mockLoader } from "../helpers.js";
|
8
|
+
|
9
|
+
describe("meta check", () => {
|
10
|
+
const sthis = ensureSuperThis();
|
11
|
+
it("empty Database", async () => {
|
12
|
+
const name = `remote-db-${sthis.nextId().str}`;
|
13
|
+
const db = fireproof(name, {
|
14
|
+
storeUrls: {
|
15
|
+
base: `memory://${name}`,
|
16
|
+
},
|
17
|
+
});
|
18
|
+
await db.ready();
|
19
|
+
const gws = db.ledger.crdt.blockstore.loader.attachedStores.local();
|
20
|
+
await db.close();
|
21
|
+
expect(
|
22
|
+
Array.from(((gws.active.car.realGateway as rt.gw.DefSerdeGateway).gw as rt.gw.memory.MemoryGateway).memorys.entries()).filter(
|
23
|
+
([k]) => k.startsWith(`memory://${name}`),
|
24
|
+
),
|
25
|
+
).toEqual([]);
|
26
|
+
});
|
27
|
+
|
28
|
+
it("one record Database", async () => {
|
29
|
+
const name = `remote-db-${sthis.nextId().str}`;
|
30
|
+
const db = fireproof(name, {
|
31
|
+
storeUrls: {
|
32
|
+
base: `memory://${name}`,
|
33
|
+
},
|
34
|
+
});
|
35
|
+
await db.put({ _id: `id-${0}`, value: `value-${0}` });
|
36
|
+
await db.close();
|
37
|
+
|
38
|
+
const db1 = fireproof(name, {
|
39
|
+
storeUrls: {
|
40
|
+
base: `memory://${name}`,
|
41
|
+
},
|
42
|
+
});
|
43
|
+
await db1.close();
|
44
|
+
});
|
45
|
+
|
46
|
+
it("multiple record Database", async () => {
|
47
|
+
const name = `remote-db-${sthis.nextId().str}`;
|
48
|
+
const base = `memory://${name}?storekey=insecure`;
|
49
|
+
const db = fireproof(name, {
|
50
|
+
storeUrls: {
|
51
|
+
base,
|
52
|
+
},
|
53
|
+
});
|
54
|
+
await db.ready();
|
55
|
+
await db.put({ _id: `id-${0}`, value: `value-${0}` });
|
56
|
+
const gws = db.ledger.crdt.blockstore.loader.attachedStores.local();
|
57
|
+
expect(db.ledger.crdt.blockstore.loader.carLog.asArray().map((i) => i.map((i) => i.toString()))).toEqual([
|
58
|
+
["baembeieldbalgnyxqp7rmj4cbrot75gweavqy3aw22km43zsfufrihfn7e"],
|
59
|
+
["baembeig2is4vdgz4gyiadfh5uutxxeiuqtacnesnytrnilpwcu7q5m5tmu"],
|
60
|
+
]);
|
61
|
+
await db.close();
|
62
|
+
expect(
|
63
|
+
Array.from(((gws.active.car.realGateway as rt.gw.DefSerdeGateway).gw as rt.gw.memory.MemoryGateway).memorys.entries())
|
64
|
+
.filter(([k]) => k.startsWith(`memory://${name}`))
|
65
|
+
.map(([k]) =>
|
66
|
+
stripper(
|
67
|
+
["name", "storekey", "version"],
|
68
|
+
Array.from(URI.from(k).getParams).reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {}),
|
69
|
+
),
|
70
|
+
),
|
71
|
+
).toEqual([
|
72
|
+
{
|
73
|
+
key: "baembeig2is4vdgz4gyiadfh5uutxxeiuqtacnesnytrnilpwcu7q5m5tmu",
|
74
|
+
store: "car",
|
75
|
+
suffix: ".car",
|
76
|
+
},
|
77
|
+
{
|
78
|
+
key: "main",
|
79
|
+
store: "wal",
|
80
|
+
},
|
81
|
+
{
|
82
|
+
key: "main",
|
83
|
+
store: "meta",
|
84
|
+
},
|
85
|
+
{
|
86
|
+
key: "baembeieldbalgnyxqp7rmj4cbrot75gweavqy3aw22km43zsfufrihfn7e",
|
87
|
+
store: "car",
|
88
|
+
suffix: ".car",
|
89
|
+
},
|
90
|
+
]);
|
91
|
+
|
92
|
+
const db1 = fireproof(name, {
|
93
|
+
storeUrls: {
|
94
|
+
base,
|
95
|
+
},
|
96
|
+
});
|
97
|
+
expect(db1.ledger).not.equal(db.ledger);
|
98
|
+
await db1.ready();
|
99
|
+
expect(db1.ledger.crdt.blockstore.loader.carLog.asArray().map((i) => i.map((i) => i.toString()))).toEqual([
|
100
|
+
["baembeieldbalgnyxqp7rmj4cbrot75gweavqy3aw22km43zsfufrihfn7e"],
|
101
|
+
["baembeig2is4vdgz4gyiadfh5uutxxeiuqtacnesnytrnilpwcu7q5m5tmu"],
|
102
|
+
]);
|
103
|
+
|
104
|
+
const gensis = await db1.get(PARAM.GENESIS_CID);
|
105
|
+
expect(gensis).toEqual({ _id: PARAM.GENESIS_CID });
|
106
|
+
|
107
|
+
const val = await db1.allDocs();
|
108
|
+
expect(val.rows).toEqual([
|
109
|
+
{
|
110
|
+
key: "id-0",
|
111
|
+
value: {
|
112
|
+
_id: "id-0",
|
113
|
+
value: "value-0",
|
114
|
+
},
|
115
|
+
},
|
116
|
+
]);
|
117
|
+
const car = Array.from(
|
118
|
+
((gws.active.car.realGateway as rt.gw.DefSerdeGateway).gw as rt.gw.memory.MemoryGateway).memorys.entries(),
|
119
|
+
)
|
120
|
+
.filter(([k]) => k.startsWith(`memory://${name}`))
|
121
|
+
.map(([k, v]) => [URI.from(k).getParam(PARAM.KEY), v])
|
122
|
+
.find(([k]) => k === "baembeig2is4vdgz4gyiadfh5uutxxeiuqtacnesnytrnilpwcu7q5m5tmu") as [string, Uint8Array];
|
123
|
+
const rawReader = await CarReader.fromBytes(car[1]);
|
124
|
+
const blocks = [];
|
125
|
+
for await (const block of rawReader.blocks()) {
|
126
|
+
blocks.push(block);
|
127
|
+
}
|
128
|
+
expect(dagCbor.decode(blocks[1].bytes)).toEqual({
|
129
|
+
doc: {
|
130
|
+
_id: "baembeiarootfireproofgenesisblockaaaafireproofgenesisblocka",
|
131
|
+
},
|
132
|
+
});
|
133
|
+
|
134
|
+
expect(blocks.map((i) => i.cid.toString())).toEqual([
|
135
|
+
"bafyreibxibqhi6wh5klrje7ne4htffeqyyqfd6y7x2no6wnhid4nixizau",
|
136
|
+
"bafyreidnvv4mwvweup5w52ddre2sl4syhvczm6ejqsmuekajowdl2cf2q4",
|
137
|
+
"bafyreihh6nbfbhgkf5lz7hhsscjgiquw426rxzr3fprbgonekzmyvirrhe",
|
138
|
+
"bafyreiejg3twlaxr7gfvvhtxrhvwaydytdv4guidmtvaz5dskm6gp73ryi",
|
139
|
+
"bafyreiblui55o25dopc5faol3umsnuohb5carto7tot4kicnkfc37he4h4",
|
140
|
+
]);
|
141
|
+
});
|
142
|
+
});
|
143
|
+
|
144
|
+
describe("activate store", () => {
|
145
|
+
// activate(store: DataAndMetaStore | CoerceURI): ActiveStore {
|
146
|
+
// if (isCoerceURI(store)) {
|
147
|
+
// throw this.loadable.sthis.logger.Error().Msg("store must be an object").AsError();
|
148
|
+
// }
|
149
|
+
// return new ActiveStoreImpl(store as DataAndMetaStore, this);
|
150
|
+
// }
|
151
|
+
|
152
|
+
const sthis = ensureSuperThis();
|
153
|
+
let attach: bs.AttachedStores;
|
154
|
+
let firstAttached: Attached;
|
155
|
+
let secondAttached: Attached;
|
156
|
+
beforeEach(async () => {
|
157
|
+
attach = new bs.AttachedRemotesImpl(mockLoader(sthis));
|
158
|
+
firstAttached = await attach.attach({
|
159
|
+
name: "first",
|
160
|
+
prepare: async () => ({
|
161
|
+
car: { url: "memory://first?store=car" },
|
162
|
+
meta: { url: "memory://first?store=meta" },
|
163
|
+
file: { url: "memory://first" },
|
164
|
+
wal: { url: "memory://first?store=wal" },
|
165
|
+
}),
|
166
|
+
});
|
167
|
+
|
168
|
+
secondAttached = await attach.attach({
|
169
|
+
name: "second",
|
170
|
+
prepare: async () => ({
|
171
|
+
car: { url: "memory://second?store=car" },
|
172
|
+
meta: { url: "memory://second?store=meta" },
|
173
|
+
file: { url: "memory://second?store=file" },
|
174
|
+
}),
|
175
|
+
});
|
176
|
+
});
|
177
|
+
|
178
|
+
it("activate by store", async () => {
|
179
|
+
expect(attach.activate(secondAttached.stores).active.car.url().toString()).toBe(
|
180
|
+
"memory://second?name=second&store=car&storekey=%40second-data%40&suffix=.car&version=v0.19-memory",
|
181
|
+
);
|
182
|
+
expect(attach.activate(firstAttached.stores).local().active.car.url().toString()).toBe(
|
183
|
+
"memory://first?name=first&store=car&storekey=%40first-data%40&suffix=.car&version=v0.19-memory",
|
184
|
+
);
|
185
|
+
expect(attach.activate(firstAttached.stores).active.meta.url().toString()).toBe(
|
186
|
+
"memory://first?name=first&store=meta&storekey=%40first-meta%40&version=v0.19-memory",
|
187
|
+
);
|
188
|
+
});
|
189
|
+
|
190
|
+
it("activate by store", async () => {
|
191
|
+
expect(attach.activate("memory://second").active.car.url().toString()).toBe(
|
192
|
+
"memory://second?name=second&store=car&storekey=%40second-data%40&suffix=.car&version=v0.19-memory",
|
193
|
+
);
|
194
|
+
expect(attach.activate("memory://second").remotes()[0].active.car.url().toString()).toEqual(
|
195
|
+
"memory://second?name=second&store=car&storekey=%40second-data%40&suffix=.car&version=v0.19-memory",
|
196
|
+
);
|
197
|
+
expect(attach.activate("memory://first?store=meta").active.car.url().toString()).toBe(
|
198
|
+
"memory://first?name=first&store=car&storekey=%40first-data%40&suffix=.car&version=v0.19-memory",
|
199
|
+
);
|
200
|
+
});
|
201
|
+
});
|
2
202
|
|
3
203
|
describe("join function", () => {
|
204
|
+
const sthis = ensureSuperThis();
|
4
205
|
// export const connect: ConnectFunction = (
|
5
206
|
// db: Database,
|
6
207
|
// remoteDbName = "",
|
@@ -29,9 +230,9 @@ describe("join function", () => {
|
|
29
230
|
}
|
30
231
|
prepare(): Promise<GatewayUrlsParam> {
|
31
232
|
return Promise.resolve({
|
32
|
-
car: { url:
|
33
|
-
meta: { url:
|
34
|
-
file: { url:
|
233
|
+
car: { url: `memory://car/${this.name}` },
|
234
|
+
meta: { url: `memory://meta/${this.name}` },
|
235
|
+
file: { url: `memory://file/${this.name}` },
|
35
236
|
});
|
36
237
|
}
|
37
238
|
}
|
@@ -40,43 +241,116 @@ describe("join function", () => {
|
|
40
241
|
}
|
41
242
|
|
42
243
|
let db: Database;
|
244
|
+
let joinableDBs: string[] = [];
|
43
245
|
beforeAll(async () => {
|
44
|
-
const set =
|
45
|
-
await Promise.all(
|
46
|
-
Array
|
47
|
-
const
|
246
|
+
const set = sthis.nextId().str;
|
247
|
+
joinableDBs = await Promise.all(
|
248
|
+
new Array(10).fill(1).map(async (_, i) => {
|
249
|
+
const name = `remote-db-${i}-${set}`;
|
250
|
+
const db = fireproof(name, {
|
48
251
|
storeUrls: {
|
49
|
-
base: `memory
|
252
|
+
// base: `memory://${name}`,
|
253
|
+
data: {
|
254
|
+
car: `memory://car/${name}`,
|
255
|
+
meta: `memory://meta/${name}`,
|
256
|
+
file: `memory://file/${name}`,
|
257
|
+
wal: `memory://wal/${name}`,
|
258
|
+
},
|
50
259
|
},
|
51
260
|
});
|
261
|
+
// await db.put({ _id: `genesis`, value: `genesis` });
|
262
|
+
// await db.ready();
|
52
263
|
for (let j = 0; j < 10; j++) {
|
53
|
-
await db.put({ _id: `${i}-${j}`, value: `${i}-${
|
264
|
+
await db.put({ _id: `${i}-${j}`, value: `${i}-${j}` });
|
54
265
|
}
|
266
|
+
expect(await db.get(PARAM.GENESIS_CID)).toEqual({ _id: PARAM.GENESIS_CID });
|
55
267
|
await db.close();
|
56
|
-
return
|
268
|
+
return name;
|
57
269
|
}),
|
58
270
|
);
|
271
|
+
// await new Promise((resolve) => setTimeout(resolve, 1000));
|
59
272
|
|
60
273
|
db = fireproof(`db-${set}`, {
|
61
274
|
storeUrls: {
|
62
275
|
base: `memory://db-${set}`,
|
63
276
|
},
|
64
277
|
});
|
278
|
+
// await db.put({ _id: `genesis`, value: `genesis` });
|
279
|
+
for (let j = 0; j < 10; j++) {
|
280
|
+
await db.put({ _id: `db-${j}`, value: `db-${set}` });
|
281
|
+
}
|
282
|
+
expect(await db.get(PARAM.GENESIS_CID)).toEqual({ _id: PARAM.GENESIS_CID });
|
65
283
|
});
|
66
284
|
afterAll(async () => {
|
67
285
|
await db.close();
|
68
286
|
});
|
69
287
|
|
70
|
-
it("it is joinable", async () => {
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
288
|
+
it("it is joinable detachable", async () => {
|
289
|
+
const my = fireproof("my", {
|
290
|
+
storeUrls: {
|
291
|
+
base: "memory://my",
|
292
|
+
},
|
293
|
+
});
|
294
|
+
await my.put({ _id: "genesis", value: "genesis" });
|
295
|
+
await Promise.all(
|
296
|
+
joinableDBs.map(async (name) => {
|
297
|
+
const tmp = fireproof(name, {
|
298
|
+
storeUrls: {
|
299
|
+
data: {
|
300
|
+
car: `memory://car/${name}`,
|
301
|
+
meta: `memory://meta/${name}`,
|
302
|
+
file: `memory://file/${name}`,
|
303
|
+
wal: `memory://wal/${name}`,
|
304
|
+
},
|
305
|
+
},
|
306
|
+
});
|
307
|
+
const res = await tmp.allDocs();
|
308
|
+
expect(res.rows.length).toBe(10);
|
309
|
+
await tmp.close();
|
310
|
+
const attached = await my.attach(aJoinable(name));
|
311
|
+
expect(attached).toBeDefined();
|
312
|
+
}),
|
313
|
+
);
|
314
|
+
expect(my.ledger.crdt.blockstore.loader.attachedStores.remotes().length).toBe(joinableDBs.length);
|
315
|
+
await my.close();
|
316
|
+
expect(my.ledger.crdt.blockstore.loader.attachedStores.remotes().length).toBe(0);
|
317
|
+
});
|
318
|
+
|
319
|
+
it("it is inbound syncing", async () => {
|
320
|
+
await Promise.all(
|
321
|
+
joinableDBs.map(async (name) => {
|
322
|
+
const attached = await db.attach(aJoinable(name));
|
323
|
+
expect(attached).toBeDefined();
|
324
|
+
}),
|
325
|
+
);
|
326
|
+
await sleep(100);
|
327
|
+
expect(db.ledger.crdt.blockstore.loader.attachedStores.remotes().length).toBe(joinableDBs.length);
|
328
|
+
const res = await db.allDocs();
|
329
|
+
expect(res.rows.length).toBe(10 + 10 * joinableDBs.length);
|
330
|
+
});
|
76
331
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
332
|
+
it("it empty inbound syncing", async () => {
|
333
|
+
const name = `empty-db-${sthis.nextId().str}`;
|
334
|
+
const db = fireproof(name, {
|
335
|
+
storeUrls: {
|
336
|
+
// base: `memory://${name}`,
|
337
|
+
data: {
|
338
|
+
car: `memory://car/${name}`,
|
339
|
+
meta: `memory://meta/${name}`,
|
340
|
+
file: `memory://file/${name}`,
|
341
|
+
wal: `memory://wal/${name}`,
|
342
|
+
},
|
343
|
+
},
|
344
|
+
});
|
345
|
+
await Promise.all(
|
346
|
+
joinableDBs.map(async (name) => {
|
347
|
+
const attached = await db.attach(aJoinable(name));
|
348
|
+
expect(attached).toBeDefined();
|
349
|
+
}),
|
350
|
+
);
|
351
|
+
await sleep(100);
|
352
|
+
expect(db.ledger.crdt.blockstore.loader.attachedStores.remotes().length).toBe(joinableDBs.length);
|
353
|
+
const res = await db.allDocs();
|
354
|
+
expect(res.rows.length).toBe(10 * joinableDBs.length);
|
81
355
|
});
|
82
356
|
});
|