@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.
Files changed (46) hide show
  1. package/{chunk-EVSZA26U.js → chunk-AZVWSRER.js} +2 -2
  2. package/{chunk-UCMXU3DH.js → chunk-NZNG6TQT.js} +103 -1
  3. package/chunk-NZNG6TQT.js.map +1 -0
  4. package/{chunk-5X6APJDY.js → chunk-ZHO4NMWL.js} +2 -2
  5. package/index.cjs +122 -92
  6. package/index.cjs.map +1 -1
  7. package/index.d.cts +21 -1
  8. package/index.d.ts +21 -1
  9. package/index.js +41 -122
  10. package/index.js.map +1 -1
  11. package/metafile-cjs.json +1 -1
  12. package/metafile-esm.json +1 -1
  13. package/package.json +1 -1
  14. package/{sqlite-data-store-RIH56645.js → sqlite-data-store-3ST7XOLX.js} +3 -3
  15. package/{sqlite-meta-store-6347MWOR.js → sqlite-meta-store-QOIMCSJ7.js} +3 -3
  16. package/{sqlite-wal-store-G5YGK77N.js → sqlite-wal-store-JFBQPOYT.js} +3 -3
  17. package/{store-file-D472VFCS.js → store-file-CSS5THFH.js} +2 -2
  18. package/{store-indexdb-FRX5PTKR.js → store-indexdb-DR4HELVP.js} +3 -3
  19. package/{store-sql-MDSU23Y7.js → store-sql-BG6SMGQJ.js} +5 -5
  20. package/tests/blockstore/loader.test.ts +265 -0
  21. package/tests/blockstore/store.test.ts +164 -0
  22. package/tests/blockstore/transaction.test.ts +121 -0
  23. package/tests/fireproof/config.test.ts +212 -0
  24. package/tests/fireproof/crdt.test.ts +434 -0
  25. package/tests/fireproof/database.test.ts +466 -0
  26. package/tests/fireproof/fireproof.test.ts +602 -0
  27. package/tests/fireproof/hello.test.ts +54 -0
  28. package/tests/fireproof/indexer.test.ts +389 -0
  29. package/tests/helpers.ts +81 -0
  30. package/tests/react/useFireproof.test.tsx +19 -0
  31. package/tests/www/gallery.html +132 -0
  32. package/tests/www/iife.html +42 -0
  33. package/tests/www/todo-aws.html +232 -0
  34. package/tests/www/todo-ipfs.html +213 -0
  35. package/tests/www/todo-local.html +214 -0
  36. package/tests/www/todo-netlify.html +227 -0
  37. package/tests/www/todo.html +236 -0
  38. package/chunk-UCMXU3DH.js.map +0 -1
  39. /package/{chunk-EVSZA26U.js.map → chunk-AZVWSRER.js.map} +0 -0
  40. /package/{chunk-5X6APJDY.js.map → chunk-ZHO4NMWL.js.map} +0 -0
  41. /package/{sqlite-data-store-RIH56645.js.map → sqlite-data-store-3ST7XOLX.js.map} +0 -0
  42. /package/{sqlite-meta-store-6347MWOR.js.map → sqlite-meta-store-QOIMCSJ7.js.map} +0 -0
  43. /package/{sqlite-wal-store-G5YGK77N.js.map → sqlite-wal-store-JFBQPOYT.js.map} +0 -0
  44. /package/{store-file-D472VFCS.js.map → store-file-CSS5THFH.js.map} +0 -0
  45. /package/{store-indexdb-FRX5PTKR.js.map → store-indexdb-DR4HELVP.js.map} +0 -0
  46. /package/{store-sql-MDSU23Y7.js.map → store-sql-BG6SMGQJ.js.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fireproof/core",
3
- "version": "0.19.0-dev-publish",
3
+ "version": "0.19.0-dev-use-fix",
4
4
  "description": "Live database for the web.",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  ensureSQLiteVersion
3
- } from "./chunk-5X6APJDY.js";
3
+ } from "./chunk-ZHO4NMWL.js";
4
4
  import {
5
5
  ensureLogger,
6
6
  exception2Result,
7
7
  getStore
8
- } from "./chunk-UCMXU3DH.js";
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-RIH56645.js.map
120
+ //# sourceMappingURL=sqlite-data-store-3ST7XOLX.js.map
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  ensureSQLiteVersion
3
- } from "./chunk-5X6APJDY.js";
3
+ } from "./chunk-ZHO4NMWL.js";
4
4
  import {
5
5
  ensureLogger,
6
6
  exception2Result,
7
7
  getStore
8
- } from "./chunk-UCMXU3DH.js";
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-6347MWOR.js.map
137
+ //# sourceMappingURL=sqlite-meta-store-QOIMCSJ7.js.map
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  ensureSQLiteVersion
3
- } from "./chunk-5X6APJDY.js";
3
+ } from "./chunk-ZHO4NMWL.js";
4
4
  import {
5
5
  ensureLogger,
6
6
  exception2Result,
7
7
  getStore
8
- } from "./chunk-UCMXU3DH.js";
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-G5YGK77N.js.map
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-UCMXU3DH.js";
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-D472VFCS.js.map
193
+ //# sourceMappingURL=store-file-CSS5THFH.js.map
@@ -5,9 +5,9 @@ import {
5
5
  IndexDBWalGateway,
6
6
  getIndexDBName,
7
7
  guardVersion
8
- } from "./chunk-EVSZA26U.js";
8
+ } from "./chunk-AZVWSRER.js";
9
9
  import "./chunk-VZGT7ZYP.js";
10
- import "./chunk-UCMXU3DH.js";
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-FRX5PTKR.js.map
20
+ //# sourceMappingURL=store-indexdb-DR4HELVP.js.map
@@ -8,7 +8,7 @@ import {
8
8
  exceptionWrapper,
9
9
  getKey,
10
10
  getName
11
- } from "./chunk-UCMXU3DH.js";
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-G5YGK77N.js");
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-RIH56645.js");
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-6347MWOR.js");
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-MDSU23Y7.js.map
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