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

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,466 @@
1
+ import { buildBlobFiles, FileWithCid } from "../helpers.js";
2
+ import { rt, bs, Database, DbResponse, DocFileMeta, DocWithId, DocFiles } from "@fireproof/core";
3
+
4
+ describe("basic Database", () => {
5
+ let db: Database;
6
+ afterEach(async () => {
7
+ await db.close();
8
+ await db.destroy();
9
+ });
10
+ beforeEach(async () => {
11
+ await rt.SysContainer.start();
12
+ db = new Database();
13
+ });
14
+ it("should put", async () => {
15
+ /** @type {Doc} */
16
+ const doc = { _id: "hello", value: "world" };
17
+ const ok = await db.put(doc);
18
+ expect(ok.id).toBe("hello");
19
+ });
20
+ it("get missing should throw", async () => {
21
+ const e = await db.get("missing").catch((e) => e);
22
+ expect(e.message).toMatch(/Not found/);
23
+ });
24
+ it("del missing should result in deleted state", async () => {
25
+ await db.del("missing");
26
+
27
+ const e = await db.get("missing").catch((e) => e);
28
+ expect(e.message).toMatch(/Not found/);
29
+ });
30
+ it("has no changes", async () => {
31
+ const { rows } = await db.changes([]);
32
+ expect(rows.length).toBe(0);
33
+ });
34
+ });
35
+
36
+ describe("basic Database with record", function () {
37
+ interface Doc {
38
+ readonly value: string;
39
+ }
40
+ let db: Database;
41
+ afterEach(async () => {
42
+ await db.close();
43
+ await db.destroy();
44
+ });
45
+ beforeEach(async function () {
46
+ await rt.SysContainer.start();
47
+ db = new Database();
48
+ const ok = await db.put<Doc>({ _id: "hello", value: "world" });
49
+ expect(ok.id).toBe("hello");
50
+ });
51
+ it("should get", async function () {
52
+ const doc = await db.get<Doc>("hello");
53
+ expect(doc).toBeTruthy();
54
+ expect(doc._id).toBe("hello");
55
+ expect(doc.value).toBe("world");
56
+ });
57
+ it("should update", async function () {
58
+ const ok = await db.put({ _id: "hello", value: "universe" });
59
+ expect(ok.id).toBe("hello");
60
+ const doc = await db.get<Doc>("hello");
61
+ expect(doc).toBeTruthy();
62
+ expect(doc._id).toBe("hello");
63
+ expect(doc.value).toBe("universe");
64
+ });
65
+ it("should del last record", async function () {
66
+ const ok = await db.del("hello");
67
+ expect(ok.id).toBe("hello");
68
+
69
+ const e = await db.get("hello").catch((e) => e);
70
+ expect(e.message).toMatch(/Not found/);
71
+ });
72
+ it("has changes", async function () {
73
+ const { rows } = await db.changes([]);
74
+ expect(rows.length).toBe(1);
75
+ expect(rows[0].key).toBe("hello");
76
+ expect(rows[0].value._id).toBe("hello");
77
+ });
78
+ it("is not persisted", async function () {
79
+ const db2 = new Database();
80
+ const { rows } = await db2.changes([]);
81
+ expect(rows.length).toBe(0);
82
+ const doc = await db2.get("hello").catch((e) => e);
83
+ expect(doc.message).toBeTruthy();
84
+ await db2.close();
85
+ await db2.destroy();
86
+ });
87
+ });
88
+
89
+ describe("named Database with record", function () {
90
+ interface Doc {
91
+ readonly value: string;
92
+ }
93
+ let db: Database;
94
+ afterEach(async () => {
95
+ await db.close();
96
+ await db.destroy();
97
+ });
98
+ beforeEach(async function () {
99
+ await rt.SysContainer.start();
100
+ db = new Database("test-db-name");
101
+ /** @type {Doc} */
102
+ const doc = { _id: "hello", value: "world" };
103
+ const ok = await db.put(doc);
104
+ expect(ok.id).toBe("hello");
105
+ });
106
+ it("should get", async function () {
107
+ const doc = await db.get<Doc>("hello");
108
+ expect(doc).toBeTruthy();
109
+ expect(doc._id).toBe("hello");
110
+ expect(doc.value).toBe("world");
111
+ });
112
+ it("should update", async function () {
113
+ const ok = await db.put({ _id: "hello", value: "universe" });
114
+ expect(ok.id).toBe("hello");
115
+ const doc = await db.get<Doc>("hello");
116
+ expect(doc).toBeTruthy();
117
+ expect(doc._id).toBe("hello");
118
+ expect(doc.value).toBe("universe");
119
+ });
120
+ it("should del last record", async function () {
121
+ const ok = await db.del("hello");
122
+ expect(ok.id).toBe("hello");
123
+
124
+ const e = await db.get("hello").catch((e) => e);
125
+ expect(e.message).toMatch(/Not found/);
126
+ });
127
+ it("has changes", async function () {
128
+ const { rows } = await db.changes([]);
129
+ expect(rows.length).toBe(1);
130
+ expect(rows[0].key).toBe("hello");
131
+ expect(rows[0].value._id).toBe("hello");
132
+ });
133
+ it("should have a key", async function () {
134
+ const { rows } = await db.changes([]);
135
+ expect(rows.length).toBe(1);
136
+ const blocks = db._crdt.blockstore as bs.EncryptedBlockstore;
137
+ const loader = blocks.loader;
138
+ expect(loader).toBeTruthy();
139
+ await loader.ready();
140
+ expect(loader.key?.length).toBe(64);
141
+ expect(loader.keyId?.length).toBe(64);
142
+ expect(loader.key).not.toBe(loader.keyId);
143
+ });
144
+ it("should work right with a sequence of changes", async function () {
145
+ const numDocs = 10;
146
+ for (let i = 0; i < numDocs; i++) {
147
+ const doc = { _id: `id-${i}`, hello: "world" };
148
+ const ok = await db.put(doc);
149
+ expect(ok.id).toBe(`id-${i}`);
150
+ }
151
+ const { rows } = await db.changes([]);
152
+ expect(rows.length).toBe(numDocs + 1);
153
+
154
+ const ok6 = await db.put({ _id: `id-${6}`, hello: "block" });
155
+ expect(ok6.id).toBe(`id-${6}`);
156
+
157
+ for (let i = 0; i < numDocs; i++) {
158
+ const id = `id-${i}`;
159
+ const doc = await db.get<{ hello: string }>(id);
160
+ expect(doc).toBeTruthy();
161
+ expect(doc._id).toBe(id);
162
+ expect(doc.hello.length).toBe(5);
163
+ }
164
+
165
+ const { rows: rows2 } = await db.changes([]);
166
+ expect(rows2.length).toBe(numDocs + 1);
167
+
168
+ const ok7 = await db.del(`id-${7}`);
169
+ expect(ok7.id).toBe(`id-${7}`);
170
+
171
+ const { rows: rows3 } = await db.changes([]);
172
+ expect(rows3.length).toBe(numDocs + 1);
173
+ expect(rows3[numDocs].key).toBe(`id-${7}`);
174
+ expect(rows3[numDocs].value._deleted).toBe(true);
175
+
176
+ // test limit
177
+ const { rows: rows4 } = await db.changes([], { limit: 5 });
178
+ expect(rows4.length).toBe(5);
179
+ });
180
+
181
+ it("should work right after compaction", async function () {
182
+ const numDocs = 10;
183
+ for (let i = 0; i < numDocs; i++) {
184
+ const doc = { _id: `id-${i}`, hello: "world" };
185
+ const ok = await db.put(doc);
186
+ expect(ok.id).toBe(`id-${i}`);
187
+ }
188
+ const { rows } = await db.changes([]);
189
+ expect(rows.length).toBe(numDocs + 1);
190
+
191
+ await db.compact();
192
+
193
+ const { rows: rows3 } = await db.changes([], { dirty: true });
194
+ expect(rows3.length).toBe(numDocs + 1);
195
+
196
+ const { rows: rows4 } = await db.changes([], { dirty: false });
197
+ expect(rows4.length).toBe(numDocs + 1);
198
+ });
199
+ });
200
+
201
+ // describe('basic Database parallel writes / public', function () {
202
+ // /** @type {Database} */
203
+ // let db
204
+ // const writes = []
205
+ // beforeEach(async function () {
206
+ // await resetDirectory(dataDir, 'test-parallel-writes')
207
+ // db = new Database('test-parallel-writes', { public: true })
208
+ // /** @type {Doc} */
209
+ // for (let i = 0; i < 10; i++) {
210
+ // const doc = { _id: `id-${i}`, hello: 'world' }
211
+ // writes.push(db.put(doc))
212
+ // }
213
+ // await Promise.all(writes)
214
+ // })
215
+
216
+ describe("basic Database parallel writes / public", function () {
217
+ let db: Database;
218
+ const writes: Promise<DbResponse>[] = [];
219
+ afterEach(async () => {
220
+ await db.close();
221
+ await db.destroy();
222
+ });
223
+ beforeEach(async function () {
224
+ await rt.SysContainer.start();
225
+ db = new Database("test-parallel-writes", { public: true });
226
+ for (let i = 0; i < 10; i++) {
227
+ const doc = { _id: `id-${i}`, hello: "world" };
228
+ writes.push(db.put(doc));
229
+ }
230
+ await Promise.all(writes);
231
+ });
232
+ it("should have one head", function () {
233
+ const crdt = db._crdt;
234
+ expect(crdt.clock.head.length).toBe(1);
235
+ });
236
+ it("should write all", async function () {
237
+ for (let i = 0; i < 10; i++) {
238
+ const id = `id-${i}`;
239
+ const doc = await db.get<{ hello: string }>(id);
240
+ expect(doc).toBeTruthy();
241
+ expect(doc._id).toBe(id);
242
+ expect(doc.hello).toBe("world");
243
+ }
244
+ });
245
+ it("should del all", async function () {
246
+ for (let i = 0; i < 10; i++) {
247
+ const id = `id-${i}`;
248
+ const ok = await db.del(id);
249
+ expect(ok.id).toBe(id);
250
+
251
+ const e = await db.get(id).catch((e) => e);
252
+ expect(e.message).toMatch(/Not found/);
253
+ }
254
+ });
255
+ it("should delete all in parallel", async function () {
256
+ const deletes: Promise<DbResponse>[] = [];
257
+ for (let i = 0; i < 10; i++) {
258
+ const id = `id-${i}`;
259
+ deletes.push(db.del(id));
260
+ }
261
+ await Promise.all(deletes);
262
+ for (let i = 0; i < 10; i++) {
263
+ const id = `id-${i}`;
264
+ const e = await db.get(id).catch((e) => e);
265
+ expect(e.message).toMatch(/Not found/);
266
+ }
267
+ });
268
+ it("has changes", async function () {
269
+ const { rows, clock } = await db.changes([]);
270
+ expect(clock[0]).toBe(db._crdt.clock.head[0]);
271
+ expect(rows.length).toBe(10);
272
+ // rows.sort((a, b) => a.key.localeCompare(b.key));
273
+ for (let i = 0; i < 10; i++) {
274
+ expect(rows[i].key).toBe("id-" + i);
275
+ expect(rows[i].clock).toBeTruthy();
276
+ }
277
+ });
278
+ it("should not have a key", async function () {
279
+ const { rows } = await db.changes([]);
280
+ expect(rows.length).toBe(10);
281
+ expect(db.opts.public).toBeTruthy();
282
+ expect(db._crdt.opts.public).toBeTruthy();
283
+ const blocks = db._crdt.blockstore as bs.EncryptedBlockstore;
284
+ const loader = blocks.loader;
285
+ expect(loader).toBeTruthy();
286
+ await loader.ready();
287
+ expect(loader.key).toBeUndefined();
288
+ expect(loader.keyId).toBeUndefined();
289
+ });
290
+ });
291
+
292
+ describe("basic Database with subscription", function () {
293
+ let db: Database;
294
+ let didRun: number;
295
+ let unsubscribe: () => void;
296
+ let lastDoc: DocWithId<NonNullable<unknown>>;
297
+ let waitForSub: Promise<void>;
298
+ afterEach(async () => {
299
+ await db.close();
300
+ await db.destroy();
301
+ });
302
+ beforeEach(async function () {
303
+ await rt.SysContainer.start();
304
+ db = new Database();
305
+ didRun = 0;
306
+ waitForSub = new Promise((resolve) => {
307
+ unsubscribe = db.subscribe((docs) => {
308
+ lastDoc = docs[0];
309
+ // lastDoc = {_id: "ok"};
310
+ didRun++;
311
+ resolve();
312
+ }, true);
313
+ });
314
+ });
315
+ it("should run on put", async function () {
316
+ const all = await db.allDocs();
317
+ expect(all.rows.length).toBe(0);
318
+ const doc = { _id: "hello", message: "world" };
319
+ expect(didRun).toBe(0);
320
+ const ok = await db.put(doc);
321
+ await waitForSub;
322
+ expect(didRun).toBeTruthy();
323
+ expect(lastDoc).toBeTruthy();
324
+ expect(lastDoc._id).toBe("hello");
325
+ expect(ok.id).toBe("hello");
326
+ expect(didRun).toBe(1);
327
+ });
328
+ it("should unsubscribe", async function () {
329
+ unsubscribe();
330
+ const doc = { _id: "hello", message: "again" };
331
+ const ok = await db.put(doc);
332
+ expect(ok.id).toBe("hello");
333
+ expect(didRun).toBe(0);
334
+ });
335
+ });
336
+
337
+ describe("basic Database with no update subscription", function () {
338
+ let db: Database;
339
+ let didRun: number;
340
+ let unsubscribe: () => void;
341
+ afterEach(async () => {
342
+ await db.close();
343
+ await db.destroy();
344
+ });
345
+ beforeEach(async function () {
346
+ await rt.SysContainer.start();
347
+ db = new Database();
348
+ didRun = 0;
349
+
350
+ unsubscribe = db.subscribe(() => {
351
+ didRun++;
352
+ });
353
+ });
354
+ it("should run on put", async function () {
355
+ const all = await db.allDocs();
356
+ expect(all.rows.length).toBe(0);
357
+ /** @type {Doc} */
358
+ const doc = { _id: "hello", message: "world" };
359
+ expect(didRun).toBe(0);
360
+ const ok = await db.put(doc);
361
+ expect(ok.id).toBe("hello");
362
+ expect(didRun).toBe(1);
363
+ });
364
+ it("should unsubscribe", async function () {
365
+ unsubscribe();
366
+ const doc = { _id: "hello", message: "again" };
367
+ const ok = await db.put(doc);
368
+ expect(ok.id).toBe("hello");
369
+ expect(didRun).toBe(0);
370
+ });
371
+ });
372
+
373
+ describe("database with files input", () => {
374
+ let db: Database;
375
+ let imagefiles: FileWithCid[] = [];
376
+ let result: DbResponse;
377
+
378
+ afterEach(async () => {
379
+ await db.close();
380
+ await db.destroy();
381
+ });
382
+ beforeEach(async function () {
383
+ await rt.SysContainer.start();
384
+ imagefiles = await buildBlobFiles();
385
+ db = new Database("fireproof-with-images");
386
+ const doc = {
387
+ _id: "images-main",
388
+ type: "files",
389
+ _files: {
390
+ one: imagefiles[0].file,
391
+ two: imagefiles[1].file,
392
+ },
393
+ };
394
+ result = await db.put(doc);
395
+ });
396
+
397
+ it("Should upload images", async function () {
398
+ expect(result.id).toBe("images-main");
399
+ });
400
+
401
+ it("Should fetch the images", async function () {
402
+ const doc = await db.get(result.id);
403
+ const files = doc._files as DocFiles;
404
+ expect(files).toBeTruthy();
405
+ const keys = Object.keys(files);
406
+ let fileMeta = files[keys[0]] as DocFileMeta;
407
+ expect(fileMeta).toBeTruthy();
408
+ expect(imagefiles[0].file.type).toBeTruthy();
409
+ expect(fileMeta.type).toBeTruthy();
410
+ expect(fileMeta.type).toBe(imagefiles[0].file.type);
411
+ expect(fileMeta.size).toBe(imagefiles[0].file.size);
412
+ expect(fileMeta.cid.toString()).toBe(imagefiles[0].cid);
413
+ expect(typeof fileMeta.file).toBe("function");
414
+ let file = (await fileMeta.file?.()) as File;
415
+
416
+ expect(file.type).toBe(imagefiles[0].file.type);
417
+ expect(file.size).toBe(imagefiles[0].file.size);
418
+ // expect(file.name).toBe('image.jpg') // see https://github.com/fireproof-storage/fireproof/issues/70
419
+
420
+ fileMeta = files[keys[1]] as DocFileMeta;
421
+ expect(fileMeta.type).toBe(imagefiles[1].file.type);
422
+ expect(fileMeta.size).toBe(imagefiles[1].file.size);
423
+ expect(fileMeta.cid.toString()).toBe(imagefiles[1].cid);
424
+ expect(typeof fileMeta.file).toBe("function");
425
+ file = (await fileMeta.file?.()) as File;
426
+
427
+ expect(file.type).toBe(imagefiles[1].file.type);
428
+ expect(file.size).toBe(imagefiles[1].file.size);
429
+ // expect(file.name).toBe('fireproof.png') // see https://github.com/fireproof-storage/fireproof/issues/70
430
+ });
431
+
432
+ it("should update the file document data without changing the files", async function () {
433
+ interface Doc {
434
+ type: string;
435
+ }
436
+ const doc = await db.get<Doc>(result.id);
437
+ let files = doc._files || {};
438
+ let keys = Object.keys(files);
439
+ let fileMeta = files[keys[0]] as DocFileMeta;
440
+ expect(fileMeta.type).toBe(imagefiles[0].file.type);
441
+ expect(fileMeta.size).toBe(imagefiles[0].file.size);
442
+ expect(fileMeta.cid.toString()).toBe(imagefiles[0].cid);
443
+ expect(typeof fileMeta.file).toBe("function");
444
+ let file = (await fileMeta.file?.()) as File;
445
+
446
+ expect(file.type).toBe(imagefiles[0].file.type);
447
+ expect(file.size).toBe(imagefiles[0].file.size);
448
+
449
+ doc.type = "images";
450
+ const r2 = await db.put(doc);
451
+ expect(r2.id).toBe("images-main");
452
+ const readDoc = await db.get<Doc>(r2.id);
453
+ expect(readDoc.type).toBe("images");
454
+ files = readDoc._files || {};
455
+ keys = Object.keys(files);
456
+ fileMeta = files[keys[0]] as DocFileMeta;
457
+ expect(fileMeta.type).toBe(imagefiles[0].file.type);
458
+ expect(fileMeta.size).toBe(imagefiles[0].file.size);
459
+ expect(fileMeta.cid.toString()).toBe(imagefiles[0].cid);
460
+ expect(typeof fileMeta.file).toBe("function");
461
+ file = (await fileMeta.file?.()) as File;
462
+
463
+ expect(file.type).toBe(imagefiles[0].file.type);
464
+ expect(file.size).toBe(imagefiles[0].file.size);
465
+ });
466
+ });