@fireproof/core 0.19.0-dev-publish → 0.19.0-dev-use-fix
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/{chunk-EVSZA26U.js → chunk-AZVWSRER.js} +2 -2
- package/{chunk-UCMXU3DH.js → chunk-NZNG6TQT.js} +103 -1
- package/chunk-NZNG6TQT.js.map +1 -0
- package/{chunk-5X6APJDY.js → chunk-ZHO4NMWL.js} +2 -2
- package/index.cjs +122 -92
- package/index.cjs.map +1 -1
- package/index.d.cts +21 -1
- package/index.d.ts +21 -1
- package/index.js +41 -122
- package/index.js.map +1 -1
- package/metafile-cjs.json +1 -1
- package/metafile-esm.json +1 -1
- package/package.json +1 -1
- package/{sqlite-data-store-RIH56645.js → sqlite-data-store-3ST7XOLX.js} +3 -3
- package/{sqlite-meta-store-6347MWOR.js → sqlite-meta-store-QOIMCSJ7.js} +3 -3
- package/{sqlite-wal-store-G5YGK77N.js → sqlite-wal-store-JFBQPOYT.js} +3 -3
- package/{store-file-D472VFCS.js → store-file-CSS5THFH.js} +2 -2
- package/{store-indexdb-FRX5PTKR.js → store-indexdb-DR4HELVP.js} +3 -3
- package/{store-sql-MDSU23Y7.js → store-sql-BG6SMGQJ.js} +5 -5
- package/tests/blockstore/loader.test.ts +265 -0
- package/tests/blockstore/store.test.ts +164 -0
- package/tests/blockstore/transaction.test.ts +121 -0
- package/tests/fireproof/config.test.ts +212 -0
- package/tests/fireproof/crdt.test.ts +434 -0
- package/tests/fireproof/database.test.ts +466 -0
- package/tests/fireproof/fireproof.test.ts +602 -0
- package/tests/fireproof/hello.test.ts +54 -0
- package/tests/fireproof/indexer.test.ts +389 -0
- package/tests/helpers.ts +81 -0
- package/tests/react/useFireproof.test.tsx +19 -0
- package/tests/www/gallery.html +132 -0
- package/tests/www/iife.html +42 -0
- package/tests/www/todo-aws.html +232 -0
- package/tests/www/todo-ipfs.html +213 -0
- package/tests/www/todo-local.html +214 -0
- package/tests/www/todo-netlify.html +227 -0
- package/tests/www/todo.html +236 -0
- package/chunk-UCMXU3DH.js.map +0 -1
- /package/{chunk-EVSZA26U.js.map → chunk-AZVWSRER.js.map} +0 -0
- /package/{chunk-5X6APJDY.js.map → chunk-ZHO4NMWL.js.map} +0 -0
- /package/{sqlite-data-store-RIH56645.js.map → sqlite-data-store-3ST7XOLX.js.map} +0 -0
- /package/{sqlite-meta-store-6347MWOR.js.map → sqlite-meta-store-QOIMCSJ7.js.map} +0 -0
- /package/{sqlite-wal-store-G5YGK77N.js.map → sqlite-wal-store-JFBQPOYT.js.map} +0 -0
- /package/{store-file-D472VFCS.js.map → store-file-CSS5THFH.js.map} +0 -0
- /package/{store-indexdb-FRX5PTKR.js.map → store-indexdb-DR4HELVP.js.map} +0 -0
- /package/{store-sql-MDSU23Y7.js.map → store-sql-BG6SMGQJ.js.map} +0 -0
package/package.json
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
import {
|
2
2
|
ensureSQLiteVersion
|
3
|
-
} from "./chunk-
|
3
|
+
} from "./chunk-ZHO4NMWL.js";
|
4
4
|
import {
|
5
5
|
ensureLogger,
|
6
6
|
exception2Result,
|
7
7
|
getStore
|
8
|
-
} from "./chunk-
|
8
|
+
} from "./chunk-NZNG6TQT.js";
|
9
9
|
import "./chunk-H3A2HMMM.js";
|
10
10
|
|
11
11
|
// src/runtime/store-sql/v0.19-sqlite/sqlite-data-store.ts
|
@@ -117,4 +117,4 @@ export {
|
|
117
117
|
DataSQLRecordBuilder,
|
118
118
|
V0_18_0SQLiteDataStore
|
119
119
|
};
|
120
|
-
//# sourceMappingURL=sqlite-data-store-
|
120
|
+
//# sourceMappingURL=sqlite-data-store-3ST7XOLX.js.map
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import {
|
2
2
|
ensureSQLiteVersion
|
3
|
-
} from "./chunk-
|
3
|
+
} from "./chunk-ZHO4NMWL.js";
|
4
4
|
import {
|
5
5
|
ensureLogger,
|
6
6
|
exception2Result,
|
7
7
|
getStore
|
8
|
-
} from "./chunk-
|
8
|
+
} from "./chunk-NZNG6TQT.js";
|
9
9
|
import "./chunk-H3A2HMMM.js";
|
10
10
|
|
11
11
|
// src/runtime/store-sql/v0.19-sqlite/sqlite-meta-store.ts
|
@@ -134,4 +134,4 @@ export {
|
|
134
134
|
MetaSQLRecordBuilder,
|
135
135
|
V0_18_0SQLiteMetaStore
|
136
136
|
};
|
137
|
-
//# sourceMappingURL=sqlite-meta-store-
|
137
|
+
//# sourceMappingURL=sqlite-meta-store-QOIMCSJ7.js.map
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import {
|
2
2
|
ensureSQLiteVersion
|
3
|
-
} from "./chunk-
|
3
|
+
} from "./chunk-ZHO4NMWL.js";
|
4
4
|
import {
|
5
5
|
ensureLogger,
|
6
6
|
exception2Result,
|
7
7
|
getStore
|
8
|
-
} from "./chunk-
|
8
|
+
} from "./chunk-NZNG6TQT.js";
|
9
9
|
import "./chunk-H3A2HMMM.js";
|
10
10
|
|
11
11
|
// src/runtime/store-sql/v0.19-sqlite/sqlite-wal-store.ts
|
@@ -120,4 +120,4 @@ export {
|
|
120
120
|
V0_18_0SQLiteWalStore,
|
121
121
|
WalSQLRecordBuilder
|
122
122
|
};
|
123
|
-
//# sourceMappingURL=sqlite-wal-store-
|
123
|
+
//# sourceMappingURL=sqlite-wal-store-JFBQPOYT.js.map
|
@@ -11,7 +11,7 @@ import {
|
|
11
11
|
getFileName,
|
12
12
|
getPath,
|
13
13
|
getStore
|
14
|
-
} from "./chunk-
|
14
|
+
} from "./chunk-NZNG6TQT.js";
|
15
15
|
import {
|
16
16
|
SysContainer
|
17
17
|
} from "./chunk-H3A2HMMM.js";
|
@@ -190,4 +190,4 @@ export {
|
|
190
190
|
FileTestStore,
|
191
191
|
FileWALGateway
|
192
192
|
};
|
193
|
-
//# sourceMappingURL=store-file-
|
193
|
+
//# sourceMappingURL=store-file-CSS5THFH.js.map
|
@@ -5,9 +5,9 @@ import {
|
|
5
5
|
IndexDBWalGateway,
|
6
6
|
getIndexDBName,
|
7
7
|
guardVersion
|
8
|
-
} from "./chunk-
|
8
|
+
} from "./chunk-AZVWSRER.js";
|
9
9
|
import "./chunk-VZGT7ZYP.js";
|
10
|
-
import "./chunk-
|
10
|
+
import "./chunk-NZNG6TQT.js";
|
11
11
|
import "./chunk-H3A2HMMM.js";
|
12
12
|
export {
|
13
13
|
IndexDBDataGateway,
|
@@ -17,4 +17,4 @@ export {
|
|
17
17
|
getIndexDBName,
|
18
18
|
guardVersion
|
19
19
|
};
|
20
|
-
//# sourceMappingURL=store-indexdb-
|
20
|
+
//# sourceMappingURL=store-indexdb-DR4HELVP.js.map
|
@@ -8,7 +8,7 @@ import {
|
|
8
8
|
exceptionWrapper,
|
9
9
|
getKey,
|
10
10
|
getName
|
11
|
-
} from "./chunk-
|
11
|
+
} from "./chunk-NZNG6TQT.js";
|
12
12
|
import {
|
13
13
|
SysContainer
|
14
14
|
} from "./chunk-H3A2HMMM.js";
|
@@ -88,7 +88,7 @@ function SQLConnectionFactory(databaseURL, opts = {}) {
|
|
88
88
|
async function WalStoreFactory(db) {
|
89
89
|
switch (db.opts.sqlFlavor) {
|
90
90
|
case "sqlite": {
|
91
|
-
const { V0_18_0SQLiteWalStore } = await import("./sqlite-wal-store-
|
91
|
+
const { V0_18_0SQLiteWalStore } = await import("./sqlite-wal-store-JFBQPOYT.js");
|
92
92
|
const store = new V0_18_0SQLiteWalStore(db);
|
93
93
|
return store;
|
94
94
|
}
|
@@ -99,7 +99,7 @@ async function WalStoreFactory(db) {
|
|
99
99
|
async function DataStoreFactory(db) {
|
100
100
|
switch (db.opts.sqlFlavor) {
|
101
101
|
case "sqlite": {
|
102
|
-
const { V0_18_0SQLiteDataStore } = await import("./sqlite-data-store-
|
102
|
+
const { V0_18_0SQLiteDataStore } = await import("./sqlite-data-store-3ST7XOLX.js");
|
103
103
|
const store = new V0_18_0SQLiteDataStore(db);
|
104
104
|
return store;
|
105
105
|
}
|
@@ -110,7 +110,7 @@ async function DataStoreFactory(db) {
|
|
110
110
|
async function MetaStoreFactory(db) {
|
111
111
|
switch (db.opts.sqlFlavor) {
|
112
112
|
case "sqlite": {
|
113
|
-
const { V0_18_0SQLiteMetaStore } = await import("./sqlite-meta-store-
|
113
|
+
const { V0_18_0SQLiteMetaStore } = await import("./sqlite-meta-store-QOIMCSJ7.js");
|
114
114
|
const store = new V0_18_0SQLiteMetaStore(db);
|
115
115
|
return store;
|
116
116
|
}
|
@@ -341,4 +341,4 @@ export {
|
|
341
341
|
SQLTestStore,
|
342
342
|
SQLWalGateway
|
343
343
|
};
|
344
|
-
//# sourceMappingURL=store-sql-
|
344
|
+
//# sourceMappingURL=store-sql-BG6SMGQJ.js.map
|
@@ -0,0 +1,265 @@
|
|
1
|
+
import * as codec from "@ipld/dag-cbor";
|
2
|
+
import { sha256 as hasher } from "multiformats/hashes/sha2";
|
3
|
+
import { BlockView } from "multiformats";
|
4
|
+
import { encode } from "multiformats/block";
|
5
|
+
import { CID } from "multiformats/cid";
|
6
|
+
import { MemoryBlockstore } from "@web3-storage/pail/block";
|
7
|
+
import { CRDTMeta, IndexTransactionMeta, bs, rt } from "@fireproof/core";
|
8
|
+
|
9
|
+
class MyMemoryBlockStore extends bs.EncryptedBlockstore {
|
10
|
+
readonly memblock = new MemoryBlockstore();
|
11
|
+
constructor() {
|
12
|
+
const ebOpts = {
|
13
|
+
name: "MyMemoryBlockStore",
|
14
|
+
};
|
15
|
+
super(ebOpts);
|
16
|
+
}
|
17
|
+
ready(): Promise<void> {
|
18
|
+
return Promise.resolve();
|
19
|
+
}
|
20
|
+
close(): Promise<void> {
|
21
|
+
return this.loader.close();
|
22
|
+
}
|
23
|
+
loader = new bs.Loader("MyMemoryBlockStore", {});
|
24
|
+
readonly transactions = new Set<bs.CarTransaction>();
|
25
|
+
// readonly lastTxMeta?: TransactionMeta;
|
26
|
+
readonly compacting: boolean = false;
|
27
|
+
|
28
|
+
override async put(cid: bs.AnyAnyLink, block: Uint8Array): Promise<void> {
|
29
|
+
return this.memblock.put(cid, block);
|
30
|
+
}
|
31
|
+
|
32
|
+
// transaction<M ext(fn: (t: CarTransaction) => Promise<MetaType>, opts?: { noLoader: boolean }): Promise<MetaType> {
|
33
|
+
// throw new Error("Method not implemented.");
|
34
|
+
// }
|
35
|
+
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
37
|
+
getFile(car: bs.AnyLink, cid: bs.AnyLink, isPublic?: boolean): Promise<Uint8Array> {
|
38
|
+
throw new Error("Method not implemented.");
|
39
|
+
}
|
40
|
+
compact(): Promise<void> {
|
41
|
+
throw new Error("Method not implemented.");
|
42
|
+
}
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
44
|
+
defaultCompact(blocks: bs.CompactionFetcher): Promise<bs.TransactionMeta> {
|
45
|
+
throw new Error("Method not implemented.");
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
describe("basic Loader simple", function () {
|
50
|
+
let loader: bs.Loader;
|
51
|
+
let block: BlockView;
|
52
|
+
let t: bs.CarTransaction;
|
53
|
+
|
54
|
+
afterEach(async function () {
|
55
|
+
await loader.close();
|
56
|
+
await loader.destroy();
|
57
|
+
});
|
58
|
+
|
59
|
+
beforeEach(async function () {
|
60
|
+
const testDbName = "test-loader-commit";
|
61
|
+
await rt.SysContainer.start();
|
62
|
+
const mockM = new MyMemoryBlockStore();
|
63
|
+
t = new bs.CarTransaction(mockM as bs.EncryptedBlockstore);
|
64
|
+
loader = new bs.Loader(testDbName, { public: true });
|
65
|
+
await loader.ready();
|
66
|
+
block = await encode({
|
67
|
+
value: { hello: "world" },
|
68
|
+
hasher,
|
69
|
+
codec,
|
70
|
+
});
|
71
|
+
await t.put(block.cid, block.bytes);
|
72
|
+
await mockM.put(block.cid, block.bytes);
|
73
|
+
});
|
74
|
+
it("should have an empty car log", function () {
|
75
|
+
expect(loader.carLog.length).toBe(0);
|
76
|
+
});
|
77
|
+
it("should commit", async function () {
|
78
|
+
const carGroup = await loader.commit(t, { head: [block.cid] });
|
79
|
+
expect(loader.carLog.length).toBe(1);
|
80
|
+
const reader = await loader.loadCar(carGroup[0]);
|
81
|
+
expect(reader).toBeTruthy();
|
82
|
+
const parsed = await bs.parseCarFile<CRDTMeta>(reader, loader.logger);
|
83
|
+
expect(parsed.cars).toBeTruthy();
|
84
|
+
expect(parsed.cars.length).toBe(0);
|
85
|
+
expect(parsed.meta).toBeTruthy();
|
86
|
+
expect(parsed.meta.head).toBeTruthy();
|
87
|
+
});
|
88
|
+
});
|
89
|
+
|
90
|
+
describe("basic Loader with two commits", function () {
|
91
|
+
let loader: bs.Loader;
|
92
|
+
let block: BlockView;
|
93
|
+
let block2: BlockView;
|
94
|
+
let block3: BlockView;
|
95
|
+
let block4: BlockView;
|
96
|
+
let t: bs.CarTransaction;
|
97
|
+
let carCid: bs.CarGroup;
|
98
|
+
let carCid0: bs.CarGroup;
|
99
|
+
|
100
|
+
afterEach(async function () {
|
101
|
+
await loader.close();
|
102
|
+
await loader.destroy();
|
103
|
+
});
|
104
|
+
|
105
|
+
beforeEach(async function () {
|
106
|
+
await rt.SysContainer.start();
|
107
|
+
const mockM = new MyMemoryBlockStore();
|
108
|
+
t = new bs.CarTransaction(mockM);
|
109
|
+
loader = new bs.Loader("test-loader-two-commit", { public: true });
|
110
|
+
block = await encode({
|
111
|
+
value: { hello: "world" },
|
112
|
+
hasher,
|
113
|
+
codec,
|
114
|
+
});
|
115
|
+
await t.put(block.cid, block.bytes);
|
116
|
+
carCid0 = await loader.commit(t, { head: [block.cid] });
|
117
|
+
|
118
|
+
block2 = await encode({
|
119
|
+
value: { hello: "universe" },
|
120
|
+
hasher,
|
121
|
+
codec,
|
122
|
+
});
|
123
|
+
await t.put(block2.cid, block2.bytes);
|
124
|
+
carCid = await loader.commit(t, { head: [block2.cid] });
|
125
|
+
|
126
|
+
block3 = await encode({
|
127
|
+
value: { hello: "multiverse" },
|
128
|
+
hasher,
|
129
|
+
codec,
|
130
|
+
});
|
131
|
+
await t.put(block3.cid, block3.bytes);
|
132
|
+
|
133
|
+
block4 = await encode({
|
134
|
+
value: { hello: "megaverse" },
|
135
|
+
hasher,
|
136
|
+
codec,
|
137
|
+
});
|
138
|
+
|
139
|
+
await t.put(block4.cid, block4.bytes);
|
140
|
+
});
|
141
|
+
|
142
|
+
it("should have a car log", function () {
|
143
|
+
expect(loader.carLog.length).toBe(2);
|
144
|
+
expect(loader.carLog[0].toString()).toBe(carCid.toString());
|
145
|
+
expect(loader.carLog[1].toString()).toBe(carCid0.toString());
|
146
|
+
});
|
147
|
+
|
148
|
+
it("should commit", async function () {
|
149
|
+
const reader = await loader.loadCar(carCid[0]);
|
150
|
+
expect(reader).toBeTruthy();
|
151
|
+
const parsed = await bs.parseCarFile<CRDTMeta>(reader, loader.logger);
|
152
|
+
expect(parsed.cars).toBeTruthy();
|
153
|
+
expect(parsed.compact.length).toBe(0);
|
154
|
+
expect(parsed.cars.length).toBe(1);
|
155
|
+
expect(parsed.meta).toBeTruthy();
|
156
|
+
expect(parsed.meta.head).toBeTruthy();
|
157
|
+
});
|
158
|
+
|
159
|
+
it("should compact", async function () {
|
160
|
+
const compactCid = await loader.commit(t, { head: [block2.cid] }, { compact: true });
|
161
|
+
expect(loader.carLog.length).toBe(1);
|
162
|
+
|
163
|
+
const reader = await loader.loadCar(compactCid[0]);
|
164
|
+
expect(reader).toBeTruthy();
|
165
|
+
const parsed = await bs.parseCarFile<CRDTMeta>(reader, loader.logger);
|
166
|
+
expect(parsed.cars).toBeTruthy();
|
167
|
+
expect(parsed.compact.length).toBe(2);
|
168
|
+
expect(parsed.cars.length).toBe(0);
|
169
|
+
expect(parsed.meta).toBeTruthy();
|
170
|
+
expect(parsed.meta.head).toBeTruthy();
|
171
|
+
});
|
172
|
+
|
173
|
+
it("compact should erase old files", async function () {
|
174
|
+
const cs = await loader.carStore();
|
175
|
+
await loader.commit(t, { head: [block2.cid] }, { compact: true });
|
176
|
+
expect(loader.carLog.length).toBe(1);
|
177
|
+
await loader.commit(t, { head: [block3.cid] }, { compact: false });
|
178
|
+
expect(loader.carLog.length).toBe(2);
|
179
|
+
expect(await cs.load(carCid[0])).toBeTruthy();
|
180
|
+
await loader.commit(t, { head: [block3.cid] }, { compact: true });
|
181
|
+
expect(loader.carLog.length).toBe(1);
|
182
|
+
const e0 = await cs.load(carCid[0]).catch((e) => e);
|
183
|
+
expect(e0 instanceof Error).toBeTruthy();
|
184
|
+
await loader.commit(t, { head: [block4.cid] }, { compact: false });
|
185
|
+
expect(loader.carLog.length).toBe(2);
|
186
|
+
|
187
|
+
const e = await loader.loadCar(carCid[0]).catch((e) => e);
|
188
|
+
expect(e).toBeTruthy();
|
189
|
+
expect(e instanceof Error).toBeTruthy();
|
190
|
+
expect(e.message).toMatch("missing car file");
|
191
|
+
}, 10000);
|
192
|
+
});
|
193
|
+
|
194
|
+
describe("basic Loader with index commits", function () {
|
195
|
+
let block: BlockView;
|
196
|
+
let ib: bs.EncryptedBlockstore;
|
197
|
+
let indexerResult: IndexTransactionMeta;
|
198
|
+
let cid: CID;
|
199
|
+
// let indexMap: Map<string, CID>;
|
200
|
+
|
201
|
+
afterEach(async function () {
|
202
|
+
await ib.close();
|
203
|
+
await ib.destroy();
|
204
|
+
});
|
205
|
+
|
206
|
+
beforeEach(async function () {
|
207
|
+
const name = "test-loader-index" + Math.random();
|
208
|
+
await rt.SysContainer.start();
|
209
|
+
// t = new CarTransaction()
|
210
|
+
ib = new bs.EncryptedBlockstore({ name });
|
211
|
+
block = await encode({
|
212
|
+
value: { hello: "world" },
|
213
|
+
hasher,
|
214
|
+
codec,
|
215
|
+
});
|
216
|
+
// console.log('block', block.cid)
|
217
|
+
|
218
|
+
cid = CID.parse("bafybeia4luuns6dgymy5kau5rm7r4qzrrzg6cglpzpogussprpy42cmcn4");
|
219
|
+
indexerResult = {
|
220
|
+
indexes: {
|
221
|
+
hello: {
|
222
|
+
byId: cid,
|
223
|
+
byKey: cid,
|
224
|
+
head: [cid as CID<unknown, number, number, 1>],
|
225
|
+
name: "hello",
|
226
|
+
map: "(doc) => doc.hello",
|
227
|
+
},
|
228
|
+
},
|
229
|
+
};
|
230
|
+
// indexMap = new Map();
|
231
|
+
});
|
232
|
+
|
233
|
+
it("should start with an empty car log", function () {
|
234
|
+
expect(ib.loader).toBeTruthy();
|
235
|
+
expect(ib.loader.carLog.length).toBe(0);
|
236
|
+
});
|
237
|
+
|
238
|
+
it("should commit the index metadata", async function () {
|
239
|
+
const { cars: carCid } = await ib.transaction<IndexTransactionMeta>(
|
240
|
+
async (t) => {
|
241
|
+
await t.put(block.cid, block.bytes);
|
242
|
+
return indexerResult;
|
243
|
+
} /* , indexMap */,
|
244
|
+
);
|
245
|
+
|
246
|
+
expect(carCid).toBeTruthy();
|
247
|
+
expect(ib.loader).toBeTruthy();
|
248
|
+
const carLog = ib.loader.carLog;
|
249
|
+
|
250
|
+
expect(carLog.length).toBe(1);
|
251
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
252
|
+
const reader = await ib.loader.loadCar(carCid![0]);
|
253
|
+
expect(reader).toBeTruthy();
|
254
|
+
const parsed = await bs.parseCarFile<IndexTransactionMeta>(reader, ib.loader.logger);
|
255
|
+
expect(parsed.cars).toBeTruthy();
|
256
|
+
expect(parsed.cars.length).toBe(0);
|
257
|
+
expect(parsed.meta).toBeTruthy();
|
258
|
+
expect(parsed.meta.indexes).toBeTruthy();
|
259
|
+
const indexes = parsed.meta.indexes;
|
260
|
+
expect(indexes).toBeTruthy();
|
261
|
+
expect(indexes.hello).toBeTruthy();
|
262
|
+
expect(indexes.hello.map).toBe("(doc) => doc.hello");
|
263
|
+
expect(indexes.hello.name).toBe("hello");
|
264
|
+
});
|
265
|
+
});
|
@@ -0,0 +1,164 @@
|
|
1
|
+
import { CID } from "multiformats";
|
2
|
+
import { rt, bs } from "@fireproof/core";
|
3
|
+
import { MockLogger } from "@adviser/cement";
|
4
|
+
import { NotFoundError } from "../../src/blockstore/gateway";
|
5
|
+
|
6
|
+
const decoder = new TextDecoder("utf-8");
|
7
|
+
|
8
|
+
function runtime() {
|
9
|
+
return bs.toStoreRuntime({}, MockLogger().logger);
|
10
|
+
}
|
11
|
+
|
12
|
+
function mockLoader(name: string): bs.Loadable {
|
13
|
+
return {
|
14
|
+
name,
|
15
|
+
ebOpts: {
|
16
|
+
store: {},
|
17
|
+
},
|
18
|
+
} as bs.Loadable;
|
19
|
+
}
|
20
|
+
|
21
|
+
describe("DataStore", function () {
|
22
|
+
let store: bs.DataStore;
|
23
|
+
let raw: bs.TestStore;
|
24
|
+
|
25
|
+
afterEach(async () => {
|
26
|
+
await store.close();
|
27
|
+
await store.destroy();
|
28
|
+
});
|
29
|
+
|
30
|
+
beforeEach(async () => {
|
31
|
+
await rt.SysContainer.start();
|
32
|
+
store = await runtime().makeDataStore(mockLoader("test"));
|
33
|
+
await store.start();
|
34
|
+
raw = await bs.testStoreFactory(store.url);
|
35
|
+
});
|
36
|
+
|
37
|
+
it("should have a name", function () {
|
38
|
+
expect(store.name).toEqual("test");
|
39
|
+
});
|
40
|
+
|
41
|
+
it("should save a car", async function () {
|
42
|
+
const car: bs.AnyBlock = {
|
43
|
+
cid: "cidKey" as unknown as CID,
|
44
|
+
bytes: new Uint8Array([55, 56, 57]),
|
45
|
+
};
|
46
|
+
await store.save(car);
|
47
|
+
const data = await raw.get(store.url, car.cid.toString());
|
48
|
+
expect(decoder.decode(data)).toEqual(decoder.decode(car.bytes));
|
49
|
+
});
|
50
|
+
});
|
51
|
+
|
52
|
+
describe("DataStore with a saved car", function () {
|
53
|
+
let store: bs.DataStore;
|
54
|
+
let raw: bs.TestStore;
|
55
|
+
let car: bs.AnyBlock;
|
56
|
+
|
57
|
+
afterEach(async () => {
|
58
|
+
await store.close();
|
59
|
+
await store.destroy();
|
60
|
+
});
|
61
|
+
|
62
|
+
beforeEach(async function () {
|
63
|
+
await rt.SysContainer.start();
|
64
|
+
store = await runtime().makeDataStore(mockLoader("test2"));
|
65
|
+
await store.start();
|
66
|
+
raw = await bs.testStoreFactory(store.url);
|
67
|
+
car = {
|
68
|
+
cid: "cid" as unknown as CID,
|
69
|
+
bytes: new Uint8Array([55, 56, 57, 80]),
|
70
|
+
};
|
71
|
+
await store.save(car);
|
72
|
+
});
|
73
|
+
|
74
|
+
it("should have a car", async function () {
|
75
|
+
const data = await raw.get(store.url, car.cid.toString());
|
76
|
+
expect(decoder.decode(data)).toEqual(decoder.decode(car.bytes));
|
77
|
+
});
|
78
|
+
|
79
|
+
it("should load a car", async function () {
|
80
|
+
const loaded = await store.load(car.cid);
|
81
|
+
expect(loaded.cid).toEqual(car.cid);
|
82
|
+
expect(loaded.bytes.constructor.name).toEqual("Uint8Array");
|
83
|
+
expect(loaded.bytes.toString()).toEqual(car.bytes.toString());
|
84
|
+
});
|
85
|
+
|
86
|
+
it("should remove a car", async function () {
|
87
|
+
await store.remove(car.cid);
|
88
|
+
const error = (await store.load(car.cid).catch((e: Error) => e)) as NotFoundError;
|
89
|
+
expect(error.code).toMatch("ENOENT");
|
90
|
+
// matches(error.message, "ENOENT");
|
91
|
+
});
|
92
|
+
});
|
93
|
+
|
94
|
+
describe("MetaStore", function () {
|
95
|
+
let store: bs.MetaStore;
|
96
|
+
let raw: bs.TestStore;
|
97
|
+
|
98
|
+
afterEach(async () => {
|
99
|
+
await store.close();
|
100
|
+
await store.destroy();
|
101
|
+
});
|
102
|
+
|
103
|
+
beforeEach(async function () {
|
104
|
+
await rt.SysContainer.start();
|
105
|
+
store = await runtime().makeMetaStore(mockLoader("test"));
|
106
|
+
await store.start();
|
107
|
+
raw = await bs.testStoreFactory(store.url);
|
108
|
+
});
|
109
|
+
|
110
|
+
it("should have a name", function () {
|
111
|
+
expect(store.name).toEqual("test");
|
112
|
+
});
|
113
|
+
|
114
|
+
it("should save a header", async function () {
|
115
|
+
const cid = CID.parse("bafybeia4luuns6dgymy5kau5rm7r4qzrrzg6cglpzpogussprpy42cmcn4");
|
116
|
+
const h: bs.DbMeta = {
|
117
|
+
cars: [cid],
|
118
|
+
key: undefined,
|
119
|
+
};
|
120
|
+
await store.save(h);
|
121
|
+
const file = await raw.get(store.url, "main");
|
122
|
+
const header = JSON.parse(decoder.decode(file));
|
123
|
+
expect(header).toBeTruthy();
|
124
|
+
expect(header.cars).toBeTruthy();
|
125
|
+
expect(header.cars[0]["/"]).toEqual(cid.toString());
|
126
|
+
});
|
127
|
+
});
|
128
|
+
|
129
|
+
describe("MetaStore with a saved header", function () {
|
130
|
+
let store: bs.MetaStore;
|
131
|
+
let raw: bs.TestStore;
|
132
|
+
let cid: CID;
|
133
|
+
|
134
|
+
afterEach(async () => {
|
135
|
+
await store.close();
|
136
|
+
await store.destroy();
|
137
|
+
});
|
138
|
+
|
139
|
+
beforeEach(async function () {
|
140
|
+
await rt.SysContainer.start();
|
141
|
+
store = await runtime().makeMetaStore(mockLoader("test-saved-header"));
|
142
|
+
await store.start();
|
143
|
+
raw = await bs.testStoreFactory(store.url);
|
144
|
+
cid = CID.parse("bafybeia4luuns6dgymy5kau5rm7r4qzrrzg6cglpzpogussprpy42cmcn4");
|
145
|
+
await store.save({ cars: [cid], key: undefined });
|
146
|
+
});
|
147
|
+
|
148
|
+
it("should have a header", async function () {
|
149
|
+
const data = decoder.decode(await raw.get(store.url, "main"));
|
150
|
+
expect(data).toMatch(/car/);
|
151
|
+
const header = JSON.parse(data);
|
152
|
+
expect(header).toBeTruthy();
|
153
|
+
expect(header.cars).toBeTruthy();
|
154
|
+
expect(header.cars[0]["/"]).toEqual(cid.toString());
|
155
|
+
});
|
156
|
+
|
157
|
+
it("should load a header", async function () {
|
158
|
+
const loadeds = (await store.load()) as bs.DbMeta[];
|
159
|
+
const loaded = loadeds[0];
|
160
|
+
expect(loaded).toBeTruthy();
|
161
|
+
expect(loaded.cars).toBeTruthy();
|
162
|
+
expect(loaded.cars.toString()).toEqual(cid.toString());
|
163
|
+
});
|
164
|
+
});
|
@@ -0,0 +1,121 @@
|
|
1
|
+
import { CID } from "multiformats";
|
2
|
+
// import { matches, equalsJSON } from "../helpers.js";
|
3
|
+
import { bs } from "@fireproof/core";
|
4
|
+
|
5
|
+
describe("Fresh TransactionBlockstore", function () {
|
6
|
+
let blocks: bs.BaseBlockstore;
|
7
|
+
beforeEach(function () {
|
8
|
+
blocks = new bs.BaseBlockstore();
|
9
|
+
});
|
10
|
+
it("should not have a name", function () {
|
11
|
+
expect(blocks.name).toBeFalsy();
|
12
|
+
});
|
13
|
+
it("should not have a loader", function () {
|
14
|
+
expect(blocks.loader).toBeFalsy();
|
15
|
+
});
|
16
|
+
it("should not put", async function () {
|
17
|
+
const value = new TextEncoder().encode("value");
|
18
|
+
const e = await blocks.put("key" as unknown as bs.AnyLink, value).catch((e) => e);
|
19
|
+
expect(e.message).toMatch(/transaction/g);
|
20
|
+
});
|
21
|
+
it("should yield a transaction", async function () {
|
22
|
+
const txR = await blocks.transaction(async (tblocks) => {
|
23
|
+
expect(tblocks).toBeTruthy();
|
24
|
+
expect(tblocks instanceof bs.CarTransaction).toBeTruthy();
|
25
|
+
return { head: [] };
|
26
|
+
});
|
27
|
+
expect(txR).toBeTruthy();
|
28
|
+
expect(txR.t).toBeTruthy();
|
29
|
+
expect(txR.meta).toEqual({ head: [] });
|
30
|
+
});
|
31
|
+
});
|
32
|
+
|
33
|
+
describe("TransactionBlockstore with name", function () {
|
34
|
+
let blocks: bs.EncryptedBlockstore;
|
35
|
+
beforeEach(function () {
|
36
|
+
blocks = new bs.EncryptedBlockstore({ name: "test" });
|
37
|
+
});
|
38
|
+
it("should have a name", function () {
|
39
|
+
expect(blocks.name).toEqual("test");
|
40
|
+
});
|
41
|
+
it("should have a loader", function () {
|
42
|
+
expect(blocks.loader).toBeTruthy();
|
43
|
+
});
|
44
|
+
it("should get from loader", async function () {
|
45
|
+
const bytes = new TextEncoder().encode("bytes");
|
46
|
+
expect(blocks.loader).toBeTruthy();
|
47
|
+
blocks.loader.getBlock = async (cid) => {
|
48
|
+
return { cid, bytes };
|
49
|
+
};
|
50
|
+
const value = await blocks.get("key" as unknown as bs.AnyAnyLink);
|
51
|
+
expect(value).toEqual({ cid: "key" as unknown as bs.AnyAnyLink, bytes });
|
52
|
+
});
|
53
|
+
});
|
54
|
+
|
55
|
+
describe("A transaction", function () {
|
56
|
+
let tblocks: bs.CarTransaction;
|
57
|
+
let blocks: bs.EncryptedBlockstore;
|
58
|
+
beforeEach(async function () {
|
59
|
+
blocks = new bs.EncryptedBlockstore({ name: "test" });
|
60
|
+
tblocks = new bs.CarTransaction(blocks);
|
61
|
+
blocks.transactions.add(tblocks);
|
62
|
+
});
|
63
|
+
it("should put and get", async function () {
|
64
|
+
const cid = CID.parse("bafybeia4luuns6dgymy5kau5rm7r4qzrrzg6cglpzpogussprpy42cmcn4");
|
65
|
+
const bytes = new TextEncoder().encode("bytes");
|
66
|
+
await tblocks.put(cid, bytes);
|
67
|
+
expect(blocks.transactions.has(tblocks)).toBeTruthy();
|
68
|
+
const got = await tblocks.get(cid);
|
69
|
+
expect(got).toBeTruthy();
|
70
|
+
expect(got?.cid).toEqual(cid);
|
71
|
+
expect(got?.bytes).toEqual(bytes);
|
72
|
+
});
|
73
|
+
});
|
74
|
+
|
75
|
+
function asUInt8Array(str: string) {
|
76
|
+
return new TextEncoder().encode(str);
|
77
|
+
}
|
78
|
+
|
79
|
+
describe("TransactionBlockstore with a completed transaction", function () {
|
80
|
+
let blocks: bs.BaseBlockstore;
|
81
|
+
let cid: CID;
|
82
|
+
let cid2: CID;
|
83
|
+
|
84
|
+
beforeEach(async function () {
|
85
|
+
cid = CID.parse("bafybeia4luuns6dgymy5kau5rm7r4qzrrzg6cglpzpogussprpy42cmcn4");
|
86
|
+
cid2 = CID.parse("bafybeibgouhn5ktecpjuovt52zamzvm4dlve5ak7x6d5smms3itkhplnhm");
|
87
|
+
|
88
|
+
blocks = new bs.BaseBlockstore();
|
89
|
+
await blocks.transaction(async (tblocks) => {
|
90
|
+
await tblocks.put(cid, asUInt8Array("value"));
|
91
|
+
await tblocks.put(cid2, asUInt8Array("value2"));
|
92
|
+
return { head: [] };
|
93
|
+
});
|
94
|
+
await blocks.transaction(async (tblocks) => {
|
95
|
+
await tblocks.put(cid, asUInt8Array("value"));
|
96
|
+
await tblocks.put(cid2, asUInt8Array("value2"));
|
97
|
+
return { head: [] };
|
98
|
+
});
|
99
|
+
});
|
100
|
+
it("should have transactions", async function () {
|
101
|
+
const ts = blocks.transactions;
|
102
|
+
expect(ts.size).toEqual(2);
|
103
|
+
});
|
104
|
+
it("should get", async function () {
|
105
|
+
const value = (await blocks.get(cid)) as bs.AnyBlock;
|
106
|
+
expect(value.cid).toEqual(cid);
|
107
|
+
expect(value.bytes.toString()).toEqual(asUInt8Array("value").toString());
|
108
|
+
|
109
|
+
const value2 = (await blocks.get(cid2)) as bs.AnyBlock;
|
110
|
+
expect(value2.bytes.toString()).toEqual(asUInt8Array("value2").toString());
|
111
|
+
});
|
112
|
+
it("should yield entries", async function () {
|
113
|
+
const blz = [];
|
114
|
+
for await (const blk of blocks.entries()) {
|
115
|
+
blz.push(blk);
|
116
|
+
}
|
117
|
+
expect(blz.length).toEqual(2);
|
118
|
+
});
|
119
|
+
});
|
120
|
+
|
121
|
+
// test compact
|