@fireproof/core 0.19.0-dev-publish → 0.19.0-dev-use-fix
Sign up to get free protection for your applications and to get access to all the features.
- 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
|