@fireproof/core 0.19.5-dev → 0.19.8-dev-alldocs

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. package/{chunk-QHSXUST7.js → chunk-5UFCF36O.js} +3 -3
  2. package/{chunk-HCXR2M5B.js → chunk-DG6XSV44.js} +175 -7
  3. package/chunk-DG6XSV44.js.map +1 -0
  4. package/{chunk-H3A2HMMM.js → chunk-OWQAHX2V.js} +2 -2
  5. package/chunk-OWQAHX2V.js.map +1 -0
  6. package/{chunk-7OGPZSGT.js → chunk-PRQHQG4I.js} +2 -2
  7. package/index.cjs +248 -191
  8. package/index.cjs.map +1 -1
  9. package/index.d.cts +174 -68
  10. package/index.d.ts +174 -68
  11. package/index.global.js +24688 -0
  12. package/index.global.js.map +1 -0
  13. package/index.js +60 -127
  14. package/index.js.map +1 -1
  15. package/metafile-cjs.json +1 -1
  16. package/metafile-esm.json +1 -1
  17. package/metafile-iife.json +1 -0
  18. package/{node-sys-container-E7LADX2Z.js → node-sys-container-TTGEC66A.js} +2 -2
  19. package/package.json +1 -1
  20. package/{sqlite-data-store-YS4U7AQ4.js → sqlite-data-store-MA55LVQE.js} +4 -4
  21. package/{sqlite-meta-store-FJZSZG4R.js → sqlite-meta-store-UNQKVYRM.js} +4 -4
  22. package/{sqlite-wal-store-6JZ4URNS.js → sqlite-wal-store-KVUOC4PO.js} +4 -4
  23. package/{store-file-HMHPQTUV.js → store-file-WD746RSY.js} +3 -3
  24. package/{store-indexdb-MRVZG4OG.js → store-indexdb-NG45BU3Q.js} +4 -4
  25. package/{store-sql-5XMJ5OWJ.js → store-sql-QVFNIGND.js} +7 -69
  26. package/store-sql-QVFNIGND.js.map +1 -0
  27. package/tests/blockstore/loader.test.ts +265 -0
  28. package/tests/blockstore/store.test.ts +164 -0
  29. package/tests/blockstore/transaction.test.ts +121 -0
  30. package/tests/fireproof/config.test.ts +212 -0
  31. package/tests/fireproof/crdt.test.ts +434 -0
  32. package/tests/fireproof/database.test.ts +466 -0
  33. package/tests/fireproof/fireproof.test.ts +602 -0
  34. package/tests/fireproof/hello.test.ts +54 -0
  35. package/tests/fireproof/indexer.test.ts +389 -0
  36. package/tests/helpers.ts +81 -0
  37. package/tests/react/useFireproof.test.tsx +19 -0
  38. package/tests/www/gallery.html +132 -0
  39. package/tests/www/iife.html +42 -0
  40. package/tests/www/todo-aws.html +232 -0
  41. package/tests/www/todo-ipfs.html +213 -0
  42. package/tests/www/todo-local.html +214 -0
  43. package/tests/www/todo-netlify.html +227 -0
  44. package/tests/www/todo.html +236 -0
  45. package/chunk-H3A2HMMM.js.map +0 -1
  46. package/chunk-HCXR2M5B.js.map +0 -1
  47. package/store-sql-5XMJ5OWJ.js.map +0 -1
  48. /package/{chunk-QHSXUST7.js.map → chunk-5UFCF36O.js.map} +0 -0
  49. /package/{chunk-7OGPZSGT.js.map → chunk-PRQHQG4I.js.map} +0 -0
  50. /package/{node-sys-container-E7LADX2Z.js.map → node-sys-container-TTGEC66A.js.map} +0 -0
  51. /package/{sqlite-data-store-YS4U7AQ4.js.map → sqlite-data-store-MA55LVQE.js.map} +0 -0
  52. /package/{sqlite-meta-store-FJZSZG4R.js.map → sqlite-meta-store-UNQKVYRM.js.map} +0 -0
  53. /package/{sqlite-wal-store-6JZ4URNS.js.map → sqlite-wal-store-KVUOC4PO.js.map} +0 -0
  54. /package/{store-file-HMHPQTUV.js.map → store-file-WD746RSY.js.map} +0 -0
  55. /package/{store-indexdb-MRVZG4OG.js.map → store-indexdb-NG45BU3Q.js.map} +0 -0
@@ -0,0 +1,434 @@
1
+ import { itSkip } from "../helpers.js";
2
+
3
+ import { uuidv4 } from "uuidv7";
4
+
5
+ import { CRDT } from "@fireproof/core";
6
+ import { bs, rt } from "@fireproof/core";
7
+ import { CRDTMeta, DocValue } from "@fireproof/core";
8
+ import { Index, index } from "@fireproof/core";
9
+
10
+ describe("Fresh crdt", function () {
11
+ let crdt: CRDT<{ hello: string } | { points: number }>;
12
+ afterEach(async function () {
13
+ await crdt.close();
14
+ await crdt.destroy();
15
+ });
16
+ beforeEach(async function () {
17
+ await rt.SysContainer.start();
18
+ crdt = new CRDT();
19
+ });
20
+ it("should have an empty head", async function () {
21
+ const head = crdt.clock.head;
22
+ expect(head.length).toBe(0);
23
+ });
24
+ it("should accept put and return results", async function () {
25
+ const didPut = await crdt.bulk([{ id: "hello", value: { hello: "world" } }]);
26
+ const head = didPut.head;
27
+ expect(head.length).toBe(1);
28
+ });
29
+ it("should accept multi-put and return results", async function () {
30
+ const didPut = await crdt.bulk([
31
+ { id: "ace", value: { points: 11 } },
32
+ { id: "king", value: { points: 10 } },
33
+ ]);
34
+ const head = didPut.head;
35
+ expect(head.length).toBe(1);
36
+ });
37
+ });
38
+
39
+ describe("CRDT with one record", function () {
40
+ interface CRDTTestType {
41
+ readonly hello: string;
42
+ readonly nice: string;
43
+ }
44
+ let crdt: CRDT<Partial<CRDTTestType>>;
45
+ let firstPut: CRDTMeta;
46
+
47
+ afterEach(async function () {
48
+ await crdt.close();
49
+ await crdt.destroy();
50
+ });
51
+
52
+ beforeEach(async function () {
53
+ await rt.SysContainer.start();
54
+ crdt = new CRDT(`test@${uuidv4()}`);
55
+ firstPut = await crdt.bulk([{ id: "hello", value: { hello: "world" } }]);
56
+ });
57
+ it("should have a one-element head", async function () {
58
+ const head = crdt.clock.head;
59
+ expect(head.length).toBe(1);
60
+ });
61
+ it("should return the head", async function () {
62
+ expect(firstPut.head.length).toBe(1);
63
+ });
64
+ it("return the record on get", async function () {
65
+ const got = (await crdt.get("hello")) as DocValue<CRDTTestType>;
66
+ expect(got).toBeTruthy();
67
+ expect(got.doc.hello).toBe("world");
68
+ });
69
+ it("should accept another put and return results", async function () {
70
+ const didPut = await crdt.bulk([{ id: "nice", value: { nice: "data" } }]);
71
+ const head = didPut.head;
72
+ expect(head.length).toBe(1);
73
+ const { doc } = (await crdt.get("nice")) as DocValue<CRDTTestType>;
74
+ expect(doc.nice).toBe("data");
75
+ });
76
+ it("should allow for a delete", async function () {
77
+ const didDel = await crdt.bulk([{ id: "hello", del: true }]);
78
+ expect(didDel.head).toBeTruthy();
79
+ const got = await crdt.get("hello");
80
+ expect(got).toBeFalsy();
81
+ });
82
+ it("should offer changes", async function () {
83
+ const { result } = await crdt.changes([]);
84
+ expect(result.length).toBe(1);
85
+ expect(result[0].id).toBe("hello");
86
+ expect(result[0].value?.hello).toBe("world");
87
+ });
88
+ });
89
+
90
+ describe("CRDT with a multi-write", function () {
91
+ interface CRDTTestType {
92
+ readonly points: number;
93
+ }
94
+ let crdt: CRDT<CRDTTestType>;
95
+ let firstPut: CRDTMeta;
96
+
97
+ afterEach(async function () {
98
+ await crdt.close();
99
+ await crdt.destroy();
100
+ });
101
+ beforeEach(async function () {
102
+ await rt.SysContainer.start();
103
+ crdt = new CRDT();
104
+ firstPut = await crdt.bulk([
105
+ { id: "ace", value: { points: 11 } },
106
+ { id: "king", value: { points: 10 } },
107
+ ]);
108
+ });
109
+ it("should have a one-element head", async function () {
110
+ const head = crdt.clock.head;
111
+ expect(head.length).toBe(1);
112
+ expect(firstPut.head.length).toBe(1);
113
+ });
114
+ it("return the records on get", async function () {
115
+ const { doc } = (await crdt.get("ace")) as DocValue<CRDTTestType>;
116
+ expect(doc.points).toBe(11);
117
+
118
+ const got2 = (await crdt.get("king")) as DocValue<CRDTTestType>;
119
+ expect(got2).toBeTruthy();
120
+ expect(got2.doc.points).toBe(10);
121
+ });
122
+ it("should accept another put and return results", async function () {
123
+ const didPut = await crdt.bulk([{ id: "queen", value: { points: 10 } }]);
124
+ const head = didPut.head;
125
+ expect(head.length).toBe(1);
126
+ const got = (await crdt.get("queen")) as DocValue<CRDTTestType>;
127
+ expect(got).toBeTruthy();
128
+ expect(got.doc.points).toBe(10);
129
+ });
130
+ it("should offer changes", async function () {
131
+ const { result } = await crdt.changes([]);
132
+ expect(result.length).toBe(2);
133
+ expect(result[0].id).toBe("ace");
134
+ expect(result[0].value?.points).toBe(11);
135
+ expect(result[1].id).toBe("king");
136
+ });
137
+ it("should offer changes since", async function () {
138
+ /** @type {CRDTMeta} */
139
+ const secondPut = await crdt.bulk([
140
+ { id: "queen", value: { points: 10 } },
141
+ { id: "jack", value: { points: 10 } },
142
+ ]);
143
+ expect(secondPut.head).toBeTruthy();
144
+ const { result: r2, head: h2 } = await crdt.changes();
145
+ expect(r2.length).toBe(4);
146
+ const { result: r3 } = await crdt.changes(firstPut.head);
147
+ expect(r3.length).toBe(2);
148
+ const { result: r4 } = await crdt.changes(h2);
149
+ expect(r4.length).toBe(0);
150
+ });
151
+ });
152
+
153
+ interface CRDTTestType {
154
+ readonly points: number;
155
+ }
156
+ describe("CRDT with two multi-writes", function () {
157
+ /** @type {CRDT} */
158
+ let crdt: CRDT<CRDTTestType>;
159
+ let firstPut: CRDTMeta;
160
+ let secondPut: CRDTMeta;
161
+ afterEach(async function () {
162
+ await crdt.close();
163
+ await crdt.destroy();
164
+ });
165
+ beforeEach(async () => {
166
+ await rt.SysContainer.start();
167
+ crdt = new CRDT();
168
+ firstPut = await crdt.bulk([
169
+ { id: "ace", value: { points: 11 } },
170
+ { id: "king", value: { points: 10 } },
171
+ ]);
172
+ secondPut = await crdt.bulk([
173
+ { id: "queen", value: { points: 10 } },
174
+ { id: "jack", value: { points: 10 } },
175
+ ]);
176
+ });
177
+ it("should have a one-element head", async function () {
178
+ const head = crdt.clock.head;
179
+ expect(head.length).toBe(1);
180
+ expect(firstPut.head.length).toBe(1);
181
+ expect(secondPut.head.length).toBe(1);
182
+ expect(firstPut.head[0]).not.toBe(secondPut.head[0]);
183
+ });
184
+ it("return the records on get", async function () {
185
+ const ret = await crdt.get("ace");
186
+ expect(ret).not.toBeNull();
187
+ const { doc } = ret as DocValue<CRDTTestType>;
188
+ expect(doc.points).toBe(11);
189
+
190
+ for (const key of ["king", "queen", "jack"]) {
191
+ const { doc } = (await crdt.get(key)) as DocValue<CRDTTestType>;
192
+ expect(doc.points).toBe(10);
193
+ }
194
+ });
195
+ it("should offer changes", async function () {
196
+ const { result } = await crdt.changes();
197
+ expect(result.length).toBe(4);
198
+ expect(result[0].id).toBe("ace");
199
+ expect(result[0].value?.points).toBe(11);
200
+ expect(result[1].id).toBe("king");
201
+ expect(result[2].id).toBe("queen");
202
+ expect(result[3].id).toBe("jack");
203
+ });
204
+ });
205
+
206
+ describe("Compact a named CRDT with writes", function () {
207
+ let crdt: CRDT<CRDTTestType>;
208
+ afterEach(async function () {
209
+ await crdt.close();
210
+ await crdt.destroy();
211
+ });
212
+ beforeEach(async function () {
213
+ await rt.SysContainer.start();
214
+ crdt = new CRDT("named-crdt-compaction");
215
+ for (let i = 0; i < 10; i++) {
216
+ const bulk = [
217
+ { id: "ace", value: { points: 11 } },
218
+ { id: "king", value: { points: 10 } },
219
+ ];
220
+ await crdt.bulk(bulk);
221
+ }
222
+ });
223
+ it("has data", async function () {
224
+ const got = (await crdt.get("ace")) as DocValue<CRDTTestType>;
225
+ expect(got.doc).toBeTruthy();
226
+ expect(got.doc.points).toBe(11);
227
+ });
228
+ it("should start with blocks", async function () {
229
+ const blz: bs.AnyBlock[] = [];
230
+ for await (const blk of crdt.blockstore.entries()) {
231
+ blz.push(blk);
232
+ }
233
+ expect(blz.length).toBe(13);
234
+ });
235
+ it("should start with changes", async function () {
236
+ const { result } = await crdt.changes();
237
+ expect(result.length).toBe(2);
238
+ expect(result[0].id).toBe("ace");
239
+ });
240
+ itSkip("should have fewer blocks after compact", async function () {
241
+ await crdt.compact();
242
+ const blz: bs.AnyBlock[] = [];
243
+ for await (const blk of crdt.blockstore.entries()) {
244
+ blz.push(blk);
245
+ }
246
+ expect(blz.length).toBe(23);
247
+ });
248
+ it("should have data after compact", async function () {
249
+ await crdt.compact();
250
+ const got = (await crdt.get("ace")) as DocValue<CRDTTestType>;
251
+ expect(got.doc).toBeTruthy();
252
+ expect(got.doc.points).toBe(11);
253
+ });
254
+ it("should have changes after compact", async function () {
255
+ const chs = await crdt.changes();
256
+ expect(chs.result[0].id).toBe("ace");
257
+ });
258
+ });
259
+
260
+ describe("CRDT with an index", function () {
261
+ let crdt: CRDT<CRDTTestType>;
262
+ let idx: Index<number, CRDTTestType>;
263
+ afterEach(async function () {
264
+ await crdt.close();
265
+ await crdt.destroy();
266
+ });
267
+ beforeEach(async function () {
268
+ await rt.SysContainer.start();
269
+ crdt = new CRDT<CRDTTestType>();
270
+ await crdt.bulk([
271
+ { id: "ace", value: { points: 11 } },
272
+ { id: "king", value: { points: 10 } },
273
+ ]);
274
+ idx = await index<number, CRDTTestType>({ _crdt: crdt }, "points");
275
+ });
276
+ it("should query the data", async function () {
277
+ const got = await idx.query({ range: [9, 12] });
278
+ expect(got.rows.length).toBe(2);
279
+ expect(got.rows[0].id).toBe("king");
280
+ expect(got.rows[0].key).toBe(10);
281
+ });
282
+ it("should register the index", async function () {
283
+ const rIdx = await index<number, CRDTTestType>({ _crdt: crdt }, "points");
284
+ expect(rIdx).toBeTruthy();
285
+ expect(rIdx.name).toBe("points");
286
+ const got = await rIdx.query({ range: [9, 12] });
287
+ expect(got.rows.length).toBe(2);
288
+ expect(got.rows[0].id).toBe("king");
289
+ expect(got.rows[0].key).toBe(10);
290
+ });
291
+ it("creating a different index with same name should not work", async function () {
292
+ const e = await index({ _crdt: crdt }, "points", (doc) => doc._id)
293
+ .query()
294
+ .catch((err) => err);
295
+ expect(e.message).toMatch(/cannot apply/);
296
+ });
297
+ });
298
+
299
+ describe("Loader with a committed transaction", function () {
300
+ interface CRDTTestType {
301
+ readonly foo: string;
302
+ }
303
+ let loader: bs.Loader;
304
+ let blockstore: bs.EncryptedBlockstore;
305
+ let crdt: CRDT<CRDTTestType>;
306
+ let done: CRDTMeta;
307
+ const dbname = "test-loader";
308
+ afterEach(async function () {
309
+ await crdt.close();
310
+ await crdt.destroy();
311
+ });
312
+ beforeEach(async function () {
313
+ await rt.SysContainer.start();
314
+ crdt = new CRDT(dbname);
315
+ blockstore = crdt.blockstore as bs.EncryptedBlockstore;
316
+ expect(blockstore.loader).toBeTruthy();
317
+ loader = blockstore.loader;
318
+ done = await crdt.bulk([{ id: "foo", value: { foo: "bar" } }]);
319
+ });
320
+ it("should have a name", function () {
321
+ expect(loader.name).toBe(dbname);
322
+ });
323
+ it("should commit a transaction", function () {
324
+ expect(done.head).toBeTruthy();
325
+ // expect(done.cars).toBeTruthy();
326
+ expect(loader.carLog.length).toBe(1);
327
+ });
328
+ it("can load the car", async function () {
329
+ const blk = loader.carLog[0][0];
330
+ expect(blk).toBeTruthy();
331
+ const reader = await loader.loadCar(blk);
332
+ expect(reader).toBeTruthy();
333
+ const parsed = await bs.parseCarFile<CRDTMeta>(reader, loader.logger);
334
+ expect(parsed.cars).toBeTruthy();
335
+ expect(parsed.cars.length).toBe(0);
336
+ expect(parsed.meta).toBeTruthy();
337
+ expect(parsed.meta.head).toBeTruthy();
338
+ });
339
+ });
340
+
341
+ describe("Loader with two committed transactions", function () {
342
+ interface CRDTTestType {
343
+ readonly foo: string;
344
+ }
345
+ let loader: bs.Loader;
346
+ let crdt: CRDT<CRDTTestType>;
347
+ let blockstore: bs.EncryptedBlockstore;
348
+ let done1: CRDTMeta;
349
+ let done2: CRDTMeta;
350
+ afterEach(async function () {
351
+ await crdt.close();
352
+ await crdt.destroy();
353
+ });
354
+ beforeEach(async function () {
355
+ await rt.SysContainer.start();
356
+ crdt = new CRDT("test-loader");
357
+ blockstore = crdt.blockstore as bs.EncryptedBlockstore;
358
+ expect(blockstore.loader).toBeTruthy();
359
+ loader = blockstore.loader;
360
+ done1 = await crdt.bulk([{ id: "apple", value: { foo: "bar" } }]);
361
+ done2 = await crdt.bulk([{ id: "orange", value: { foo: "bar" } }]);
362
+ });
363
+ it("should commit two transactions", function () {
364
+ expect(done1.head).toBeTruthy();
365
+ // expect(done1.cars).toBeTruthy();
366
+ expect(done2.head).toBeTruthy();
367
+ // expect(done2.cars).toBeTruthy();
368
+ expect(done1.head).not.toBe(done2.head);
369
+ // expect(done1.cars).not.toBe(done2.cars);
370
+ // expect(blockstore.transactions.size).toBe(2);
371
+ expect(loader.carLog.length).toBe(2);
372
+ // expect(loader.carLog.indexOf(done1.cars)).toBe(1);
373
+ // expect(loader.carLog.map((cs) => cs.toString()).indexOf(done1.cars.toString())).toBe(1);
374
+ // expect(loader.carLog.indexOf(done2.cars)).toBe(0);
375
+ // expect(loader.carLog.map((cs) => cs.toString()).indexOf(done2.cars.toString())).toBe(0);
376
+ });
377
+ it("can load the car", async function () {
378
+ const blk = loader.carLog[0][0];
379
+ expect(blk).toBeTruthy();
380
+ const reader = await loader.loadCar(blk);
381
+ expect(reader).toBeTruthy();
382
+ const parsed = await bs.parseCarFile<CRDTMeta>(reader, loader.logger);
383
+ expect(parsed.cars).toBeTruthy();
384
+ expect(parsed.cars.length).toBe(1);
385
+ expect(parsed.meta).toBeTruthy();
386
+ expect(parsed.meta.head).toBeTruthy();
387
+ });
388
+ });
389
+
390
+ describe("Loader with many committed transactions", function () {
391
+ interface Doc {
392
+ foo: string;
393
+ }
394
+ let loader: bs.Loader;
395
+ let blockstore: bs.EncryptedBlockstore;
396
+ let crdt: CRDT<Doc>;
397
+ let dones: CRDTMeta[];
398
+ const count = 10;
399
+ afterEach(async function () {
400
+ await crdt.close();
401
+ await crdt.destroy();
402
+ });
403
+ beforeEach(async function () {
404
+ await rt.SysContainer.start();
405
+ crdt = new CRDT("test-loader-many");
406
+ blockstore = crdt.blockstore as bs.EncryptedBlockstore;
407
+ expect(blockstore.loader).toBeTruthy();
408
+ loader = blockstore.loader;
409
+ dones = [];
410
+ for (let i = 0; i < count; i++) {
411
+ const did = await crdt.bulk([{ id: `apple${i}`, value: { foo: "bar" } }]);
412
+ dones.push(did);
413
+ }
414
+ });
415
+ it("should commit many transactions", function () {
416
+ for (const done of dones) {
417
+ expect(done.head).toBeTruthy();
418
+ // expect(done.cars).toBeTruthy();
419
+ }
420
+ expect(blockstore.transactions.size).toBe(0); // cleaned up on commit
421
+ expect(loader.carLog.length).toBe(count);
422
+ });
423
+ it("can load the car", async function () {
424
+ const blk = loader.carLog[2][0];
425
+ // expect(dones[5].cars).toBeTruthy();
426
+ const reader = await loader.loadCar(blk);
427
+ expect(reader).toBeTruthy();
428
+ const parsed = await bs.parseCarFile<CRDTMeta>(reader, loader.logger);
429
+ expect(parsed.cars).toBeTruthy();
430
+ expect(parsed.cars.length).toBe(7);
431
+ expect(parsed.meta).toBeTruthy();
432
+ expect(parsed.meta.head).toBeTruthy();
433
+ });
434
+ });