@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.
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