@fireproof/core 0.19.0-dev-publish → 0.19.0-dev-global
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.global.js +24688 -0
- package/index.global.js.map +1 -0
- package/index.js +41 -122
- package/index.js.map +1 -1
- package/metafile-cjs.json +1 -1
- package/metafile-esm.json +1 -1
- package/metafile-iife.json +1 -0
- 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
@@ -0,0 +1,602 @@
|
|
1
|
+
import { sleep, itSkip } from "../helpers.js";
|
2
|
+
|
3
|
+
import { CID } from "multiformats/cid";
|
4
|
+
|
5
|
+
import { bs, rt, fireproof, Database, index, DbResponse, IndexRows, DocWithId, Index, MapFn } from "@fireproof/core";
|
6
|
+
|
7
|
+
export function carLogIncludesGroup(list: bs.AnyLink[], cid: CID) {
|
8
|
+
return list.some((c) => c.equals(cid));
|
9
|
+
}
|
10
|
+
|
11
|
+
interface FooType {
|
12
|
+
readonly foo: string;
|
13
|
+
}
|
14
|
+
|
15
|
+
interface FireType {
|
16
|
+
readonly fire: string;
|
17
|
+
}
|
18
|
+
|
19
|
+
describe("dreamcode", function () {
|
20
|
+
interface Doc {
|
21
|
+
text: string;
|
22
|
+
dream: boolean;
|
23
|
+
}
|
24
|
+
let ok: DbResponse;
|
25
|
+
let doc: DocWithId<Doc>;
|
26
|
+
let result: IndexRows<string, Doc>;
|
27
|
+
let db: Database;
|
28
|
+
afterEach(async function () {
|
29
|
+
await db.close();
|
30
|
+
await db.destroy();
|
31
|
+
});
|
32
|
+
beforeEach(async function () {
|
33
|
+
await rt.SysContainer.start();
|
34
|
+
db = fireproof("test-db");
|
35
|
+
ok = await db.put({ _id: "test-1", text: "fireproof", dream: true });
|
36
|
+
doc = await db.get(ok.id);
|
37
|
+
result = await db.query("text", { range: ["a", "z"] });
|
38
|
+
});
|
39
|
+
it("should put", function () {
|
40
|
+
expect(ok).toBeTruthy();
|
41
|
+
expect(ok.id).toBe("test-1");
|
42
|
+
});
|
43
|
+
it("should get", function () {
|
44
|
+
expect(doc.text).toBe("fireproof");
|
45
|
+
});
|
46
|
+
it("should query", function () {
|
47
|
+
expect(result).toBeTruthy();
|
48
|
+
expect(result.rows).toBeTruthy();
|
49
|
+
expect(result.rows.length).toBe(1);
|
50
|
+
expect(result.rows[0].key).toBe("fireproof");
|
51
|
+
});
|
52
|
+
it("should query with function", async function () {
|
53
|
+
const result = await db.query<boolean, Doc>((doc) => doc.dream);
|
54
|
+
expect(result).toBeTruthy();
|
55
|
+
expect(result.rows).toBeTruthy();
|
56
|
+
expect(result.rows.length).toBe(1);
|
57
|
+
expect(result.rows[0].key).toBe(true);
|
58
|
+
});
|
59
|
+
});
|
60
|
+
|
61
|
+
describe("public API", function () {
|
62
|
+
interface Doc {
|
63
|
+
foo: string;
|
64
|
+
}
|
65
|
+
let db: Database;
|
66
|
+
let ok: DbResponse;
|
67
|
+
let doc: DocWithId<Doc>;
|
68
|
+
let query: IndexRows<string, Doc>;
|
69
|
+
|
70
|
+
afterEach(async function () {
|
71
|
+
await db.close();
|
72
|
+
await db.destroy();
|
73
|
+
});
|
74
|
+
|
75
|
+
beforeEach(async function () {
|
76
|
+
await rt.SysContainer.start();
|
77
|
+
db = fireproof("test-api");
|
78
|
+
// index = index(db, 'test-index', (doc) => doc.foo)
|
79
|
+
ok = await db.put({ _id: "test", foo: "bar" });
|
80
|
+
doc = await db.get("test");
|
81
|
+
query = await db.query<string, Doc>((doc) => doc.foo);
|
82
|
+
});
|
83
|
+
it("should be a database instance", function () {
|
84
|
+
expect(db).toBeTruthy();
|
85
|
+
expect(db instanceof Database).toBeTruthy();
|
86
|
+
});
|
87
|
+
it("should put", function () {
|
88
|
+
expect(ok).toBeTruthy();
|
89
|
+
expect(ok.id).toBe("test");
|
90
|
+
});
|
91
|
+
it("should get", function () {
|
92
|
+
expect(doc.foo).toBe("bar");
|
93
|
+
});
|
94
|
+
it("should query", function () {
|
95
|
+
expect(query).toBeTruthy();
|
96
|
+
expect(query.rows).toBeTruthy();
|
97
|
+
expect(query.rows.length).toBe(1);
|
98
|
+
expect(query.rows[0].key).toBe("bar");
|
99
|
+
});
|
100
|
+
});
|
101
|
+
|
102
|
+
describe("basic database", function () {
|
103
|
+
interface Doc {
|
104
|
+
foo: string;
|
105
|
+
}
|
106
|
+
let db: Database<Doc>;
|
107
|
+
afterEach(async function () {
|
108
|
+
await db.close();
|
109
|
+
await db.destroy();
|
110
|
+
});
|
111
|
+
beforeEach(async function () {
|
112
|
+
await rt.SysContainer.start();
|
113
|
+
db = new Database("test-basic");
|
114
|
+
});
|
115
|
+
it("can put with id", async function () {
|
116
|
+
const ok = await db.put({ _id: "test", foo: "bar" });
|
117
|
+
expect(ok).toBeTruthy();
|
118
|
+
expect(ok.id).toBe("test");
|
119
|
+
});
|
120
|
+
it("can put without id", async function () {
|
121
|
+
const ok = await db.put({ foo: "bam" });
|
122
|
+
expect(ok).toBeTruthy();
|
123
|
+
const got = await db.get<Doc>(ok.id);
|
124
|
+
expect(got.foo).toBe("bam");
|
125
|
+
});
|
126
|
+
it("can define an index", async function () {
|
127
|
+
const ok = await db.put({ _id: "test", foo: "bar" });
|
128
|
+
expect(ok).toBeTruthy();
|
129
|
+
const idx = index<string, { foo: string }>(db, "test-index", (doc) => doc.foo);
|
130
|
+
const result = await idx.query();
|
131
|
+
expect(result).toBeTruthy();
|
132
|
+
expect(result.rows).toBeTruthy();
|
133
|
+
expect(result.rows.length).toBe(1);
|
134
|
+
expect(result.rows[0].key).toBe("bar");
|
135
|
+
});
|
136
|
+
it("can define an index with a default function", async function () {
|
137
|
+
const ok = await db.put({ _id: "test", foo: "bar" });
|
138
|
+
expect(ok).toBeTruthy();
|
139
|
+
const idx = index(db, "foo");
|
140
|
+
const result = await idx.query();
|
141
|
+
expect(result).toBeTruthy();
|
142
|
+
expect(result.rows).toBeTruthy();
|
143
|
+
expect(result.rows.length).toBe(1);
|
144
|
+
expect(result.rows[0].key).toBe("bar");
|
145
|
+
});
|
146
|
+
});
|
147
|
+
|
148
|
+
describe("benchmarking with compaction", function () {
|
149
|
+
let db: Database;
|
150
|
+
afterEach(async function () {
|
151
|
+
await db.close();
|
152
|
+
await db.destroy();
|
153
|
+
});
|
154
|
+
beforeEach(async function () {
|
155
|
+
// erase the existing test data
|
156
|
+
await rt.SysContainer.start();
|
157
|
+
db = new Database("test-benchmark-compaction", { autoCompact: 3, public: true });
|
158
|
+
});
|
159
|
+
itSkip(
|
160
|
+
"passing: insert during compaction",
|
161
|
+
async function () {
|
162
|
+
const ok = await db.put({ _id: "test", foo: "fast" });
|
163
|
+
expect(ok).toBeTruthy();
|
164
|
+
expect(ok.id).toBe("test");
|
165
|
+
expect(db._crdt.clock.head).toBeTruthy();
|
166
|
+
expect(db._crdt.clock.head.length).toBe(1);
|
167
|
+
|
168
|
+
const numDocs = 20000;
|
169
|
+
const batchSize = 500;
|
170
|
+
console.time(`insert and read ${numDocs} records`);
|
171
|
+
|
172
|
+
const doing = null;
|
173
|
+
for (let i = 0; i < numDocs; i += batchSize) {
|
174
|
+
const ops: Promise<DbResponse>[] = [];
|
175
|
+
db.put({ foo: "fast" });
|
176
|
+
// await doing
|
177
|
+
// doing = db.compact()
|
178
|
+
db.put({ foo: "fast" });
|
179
|
+
for (let j = 0; j < batchSize && i + j < numDocs; j++) {
|
180
|
+
ops.push(
|
181
|
+
db.put({
|
182
|
+
data: Math.random(),
|
183
|
+
fire: Math.random()
|
184
|
+
.toString()
|
185
|
+
.repeat(25 * 1024),
|
186
|
+
}),
|
187
|
+
);
|
188
|
+
}
|
189
|
+
const blocks = db._crdt.blockstore as bs.EncryptedBlockstore;
|
190
|
+
const loader = blocks.loader;
|
191
|
+
expect(loader).toBeTruthy();
|
192
|
+
const label = `write ${i} log ${loader.carLog.length}`;
|
193
|
+
console.time(label);
|
194
|
+
db.put({
|
195
|
+
data: Math.random(),
|
196
|
+
fire: Math.random()
|
197
|
+
.toString()
|
198
|
+
.repeat(25 * 1024),
|
199
|
+
});
|
200
|
+
|
201
|
+
await Promise.all(ops);
|
202
|
+
console.timeEnd(label);
|
203
|
+
}
|
204
|
+
await doing;
|
205
|
+
console.timeEnd(`insert and read ${numDocs} records`);
|
206
|
+
},
|
207
|
+
20000000,
|
208
|
+
);
|
209
|
+
});
|
210
|
+
|
211
|
+
describe("benchmarking a database", function () {
|
212
|
+
/** @type {Database} */
|
213
|
+
let db: Database;
|
214
|
+
afterEach(async function () {
|
215
|
+
await db.close();
|
216
|
+
await db.destroy();
|
217
|
+
});
|
218
|
+
beforeEach(async function () {
|
219
|
+
await rt.SysContainer.start();
|
220
|
+
// erase the existing test data
|
221
|
+
db = new Database("test-benchmark", { autoCompact: 100000, public: true });
|
222
|
+
// db = new Database(null, {autoCompact: 100000})
|
223
|
+
});
|
224
|
+
|
225
|
+
// run benchmarking tests
|
226
|
+
// remove skip below
|
227
|
+
// run:
|
228
|
+
// npm test -- --grep 'insert and read many records'
|
229
|
+
//
|
230
|
+
itSkip(
|
231
|
+
"passing: insert and read many records",
|
232
|
+
async () => {
|
233
|
+
const ok = await db.put({ _id: "test", foo: "fast" });
|
234
|
+
expect(ok).toBeTruthy();
|
235
|
+
expect(ok.id).toBe("test");
|
236
|
+
|
237
|
+
expect(db._crdt.clock.head).toBeTruthy();
|
238
|
+
expect(db._crdt.clock.head.length).toBe(1);
|
239
|
+
|
240
|
+
const numDocs = 2500;
|
241
|
+
const batchSize = 500;
|
242
|
+
console.time(`insert and read ${numDocs} records`);
|
243
|
+
|
244
|
+
for (let i = 0; i < numDocs; i += batchSize) {
|
245
|
+
const ops: Promise<DbResponse>[] = [];
|
246
|
+
for (let j = 0; j < batchSize && i + j < numDocs; j++) {
|
247
|
+
ops.push(
|
248
|
+
db
|
249
|
+
.put({
|
250
|
+
_id: `test${i + j}`,
|
251
|
+
fire: Math.random()
|
252
|
+
.toString()
|
253
|
+
.repeat(25 * 1024),
|
254
|
+
})
|
255
|
+
.then((ok) => {
|
256
|
+
db.get<{ fire: string }>(`test${i + j}`).then((doc) => {
|
257
|
+
expect(doc.fire).toBeTruthy();
|
258
|
+
});
|
259
|
+
return ok;
|
260
|
+
}),
|
261
|
+
);
|
262
|
+
}
|
263
|
+
await Promise.all(ops);
|
264
|
+
}
|
265
|
+
|
266
|
+
console.timeEnd(`insert and read ${numDocs} records`);
|
267
|
+
|
268
|
+
// console.time('allDocs')
|
269
|
+
// const allDocsResult2 = await db.allDocs()
|
270
|
+
// console.timeEnd('allDocs')
|
271
|
+
// equals(allDocsResult2.rows.length, numDocs+1)
|
272
|
+
|
273
|
+
console.time("open new DB");
|
274
|
+
const newDb = new Database("test-benchmark", { autoCompact: 100000, public: true });
|
275
|
+
const doc = await newDb.get<{ foo: string }>("test");
|
276
|
+
expect(doc.foo).toBe("fast");
|
277
|
+
console.timeEnd("open new DB");
|
278
|
+
|
279
|
+
console.time("changes");
|
280
|
+
const result = await db.changes(); // takes 1.5 seconds (doesn't have to load blocks from cars)
|
281
|
+
console.timeEnd("changes");
|
282
|
+
expect(result.rows.length).toBe(numDocs + 1);
|
283
|
+
|
284
|
+
// this takes 1 minute w 1000 docs
|
285
|
+
console.time("changes new DB");
|
286
|
+
const result2 = await newDb.changes();
|
287
|
+
console.timeEnd("changes new DB");
|
288
|
+
expect(result2.rows.length).toBe(numDocs + 1);
|
289
|
+
|
290
|
+
await sleep(1000);
|
291
|
+
|
292
|
+
console.log("begin compact");
|
293
|
+
|
294
|
+
await sleep(100);
|
295
|
+
|
296
|
+
console.time("COMPACT");
|
297
|
+
await db.compact();
|
298
|
+
console.timeEnd("COMPACT");
|
299
|
+
|
300
|
+
// todo compaction should not need this write to show in the new db
|
301
|
+
await db.put({ _id: "compacted-test", foo: "bar" });
|
302
|
+
|
303
|
+
// console.log('car log length', db._crdt.blockstore.loader.carLog.length)
|
304
|
+
const blocks = db._crdt.blockstore as bs.EncryptedBlockstore;
|
305
|
+
const loader = blocks.loader;
|
306
|
+
expect(loader).toBeTruthy();
|
307
|
+
expect(loader.carLog.length).toBe(2);
|
308
|
+
|
309
|
+
// console.time('allDocs new DB') // takes forever on 5k
|
310
|
+
// const allDocsResult = await newDb.allDocs()
|
311
|
+
// console.timeEnd('allDocs new DB')
|
312
|
+
// equals(allDocsResult.rows.length, numDocs+1)
|
313
|
+
await sleep(100);
|
314
|
+
|
315
|
+
console.time("compacted reopen again");
|
316
|
+
const newDb2 = new Database("test-benchmark", { autoCompact: 100000, public: true });
|
317
|
+
const doc21 = await newDb2.get<FooType>("test");
|
318
|
+
expect(doc21.foo).toBe("fast");
|
319
|
+
const blocks2 = newDb2._crdt.blockstore as bs.EncryptedBlockstore;
|
320
|
+
const loader2 = blocks2.loader;
|
321
|
+
expect(loader2).toBeTruthy();
|
322
|
+
|
323
|
+
expect(loader2.carLog.length).toBe(2);
|
324
|
+
|
325
|
+
const doc2 = await newDb2.get<FooType>("compacted-test");
|
326
|
+
|
327
|
+
expect(doc2.foo).toBe("bar");
|
328
|
+
|
329
|
+
expect(doc2.foo).toBe("bar");
|
330
|
+
console.timeEnd("compacted reopen again");
|
331
|
+
|
332
|
+
await sleep(100);
|
333
|
+
|
334
|
+
console.time("compacted changes new DB2");
|
335
|
+
const result3 = await newDb2.changes();
|
336
|
+
console.timeEnd("compacted changes new DB2");
|
337
|
+
expect(result3.rows.length).toBe(numDocs + 2);
|
338
|
+
|
339
|
+
console.time("compacted newDb2 insert and read 100 records");
|
340
|
+
const ops2: Promise<void>[] = [];
|
341
|
+
for (let i = 0; i < 100; i++) {
|
342
|
+
const ok = newDb2
|
343
|
+
.put({
|
344
|
+
_id: `test${i}`,
|
345
|
+
fire: Math.random()
|
346
|
+
.toString()
|
347
|
+
.repeat(25 * 1024),
|
348
|
+
})
|
349
|
+
.then(() => {
|
350
|
+
newDb2.get<{ fire: number }>(`test${i}`).then((doc) => {
|
351
|
+
expect(doc.fire).toBeTruthy();
|
352
|
+
});
|
353
|
+
});
|
354
|
+
ops2.push(ok);
|
355
|
+
}
|
356
|
+
await Promise.all(ops2);
|
357
|
+
console.timeEnd("compacted newDb2 insert and read 100 records");
|
358
|
+
|
359
|
+
// triggers OOM on my machine
|
360
|
+
// await sleep(100)
|
361
|
+
// console.time('compacted allDocs new DB2')
|
362
|
+
// const allDocsResult3 = await newDb2.allDocs()
|
363
|
+
// console.timeEnd('compacted allDocs new DB2')
|
364
|
+
// equals(allDocsResult3.rows.length, numDocs+2)
|
365
|
+
},
|
366
|
+
20000000,
|
367
|
+
);
|
368
|
+
});
|
369
|
+
|
370
|
+
describe("Reopening a database", function () {
|
371
|
+
interface Doc {
|
372
|
+
foo: string;
|
373
|
+
}
|
374
|
+
let db: Database;
|
375
|
+
afterEach(async function () {
|
376
|
+
await db.close();
|
377
|
+
await db.destroy();
|
378
|
+
});
|
379
|
+
beforeEach(async function () {
|
380
|
+
// erase the existing test data
|
381
|
+
await rt.SysContainer.start();
|
382
|
+
|
383
|
+
db = new Database("test-reopen", { autoCompact: 100000 });
|
384
|
+
const ok = await db.put({ _id: "test", foo: "bar" });
|
385
|
+
expect(ok).toBeTruthy();
|
386
|
+
expect(ok.id).toBe("test");
|
387
|
+
|
388
|
+
expect(db._crdt.clock.head).toBeDefined();
|
389
|
+
expect(db._crdt.clock.head.length).toBe(1);
|
390
|
+
});
|
391
|
+
|
392
|
+
it("should persist data", async function () {
|
393
|
+
const doc = await db.get<Doc>("test");
|
394
|
+
expect(doc.foo).toBe("bar");
|
395
|
+
});
|
396
|
+
|
397
|
+
it("should have the same data on reopen", async function () {
|
398
|
+
const db2 = new Database("test-reopen");
|
399
|
+
const doc = await db2.get<FooType>("test");
|
400
|
+
expect(doc.foo).toBe("bar");
|
401
|
+
expect(db2._crdt.clock.head).toBeDefined();
|
402
|
+
expect(db2._crdt.clock.head.length).toBe(1);
|
403
|
+
expect(db2._crdt.clock.head).toEqual(db._crdt.clock.head);
|
404
|
+
await db2.close();
|
405
|
+
});
|
406
|
+
|
407
|
+
it("should have a car in the car log", async function () {
|
408
|
+
await db._crdt.ready();
|
409
|
+
const blocks = db._crdt.blockstore as bs.EncryptedBlockstore;
|
410
|
+
const loader = blocks.loader;
|
411
|
+
expect(loader).toBeDefined();
|
412
|
+
expect(loader.carLog).toBeDefined();
|
413
|
+
expect(loader.carLog.length).toBe(1);
|
414
|
+
});
|
415
|
+
|
416
|
+
it("should have carlog after reopen", async function () {
|
417
|
+
const db2 = new Database("test-reopen");
|
418
|
+
await db2._crdt.ready();
|
419
|
+
const blocks = db2._crdt.blockstore as bs.EncryptedBlockstore;
|
420
|
+
const loader = blocks.loader;
|
421
|
+
expect(loader).toBeDefined();
|
422
|
+
expect(loader.carLog).toBeDefined();
|
423
|
+
expect(loader.carLog.length).toBe(1);
|
424
|
+
await db2.close();
|
425
|
+
});
|
426
|
+
|
427
|
+
it("faster, should have the same data on reopen after reopen and update", async function () {
|
428
|
+
for (let i = 0; i < 4; i++) {
|
429
|
+
// console.log('iteration', i)
|
430
|
+
const db = new Database("test-reopen");
|
431
|
+
// assert(db._crdt.xready());
|
432
|
+
await db._crdt.ready();
|
433
|
+
const blocks = db._crdt.blockstore as bs.EncryptedBlockstore;
|
434
|
+
const loader = blocks.loader;
|
435
|
+
expect(loader.carLog.length).toBe(i + 1);
|
436
|
+
const ok = await db.put({ _id: `test${i}`, fire: "proof".repeat(50 * 1024) });
|
437
|
+
expect(ok).toBeTruthy();
|
438
|
+
expect(loader.carLog.length).toBe(i + 2);
|
439
|
+
const doc = await db.get<FireType>(`test${i}`);
|
440
|
+
expect(doc.fire).toBe("proof".repeat(50 * 1024));
|
441
|
+
await db.close();
|
442
|
+
}
|
443
|
+
}, 20000);
|
444
|
+
|
445
|
+
itSkip(
|
446
|
+
"passing slow, should have the same data on reopen after reopen and update",
|
447
|
+
async function () {
|
448
|
+
for (let i = 0; i < 200; i++) {
|
449
|
+
// console.log("iteration", i);
|
450
|
+
// console.time("db open");
|
451
|
+
const db = new Database("test-reopen", { autoCompact: 1000 }); // try with 10
|
452
|
+
// assert(db._crdt.ready);
|
453
|
+
await db._crdt.ready();
|
454
|
+
// console.timeEnd("db open");
|
455
|
+
const blocks = db._crdt.blockstore as bs.EncryptedBlockstore;
|
456
|
+
const loader = blocks.loader;
|
457
|
+
expect(loader).toBeDefined();
|
458
|
+
expect(loader.carLog.length).toBe(i + 1);
|
459
|
+
// console.log('car log length', loader.carLog.length)
|
460
|
+
// console.time("db put");
|
461
|
+
const ok = await db.put({ _id: `test${i}`, fire: "proof".repeat(50 * 1024) });
|
462
|
+
// console.timeEnd("db put");
|
463
|
+
expect(ok).toBeTruthy();
|
464
|
+
expect(loader.carLog.length).toBe(i + 2);
|
465
|
+
// console.time("db get");
|
466
|
+
const doc = await db.get<FireType>(`test${i}`);
|
467
|
+
// console.timeEnd("db get");
|
468
|
+
expect(doc.fire).toBe("proof".repeat(50 * 1024));
|
469
|
+
}
|
470
|
+
},
|
471
|
+
200000,
|
472
|
+
);
|
473
|
+
});
|
474
|
+
|
475
|
+
describe("Reopening a database with indexes", function () {
|
476
|
+
interface Doc {
|
477
|
+
foo: string;
|
478
|
+
}
|
479
|
+
let db: Database;
|
480
|
+
let idx: Index<string, Doc>;
|
481
|
+
let didMap: boolean;
|
482
|
+
let mapFn: MapFn<Doc>;
|
483
|
+
afterEach(async function () {
|
484
|
+
await db.close();
|
485
|
+
await db.destroy();
|
486
|
+
});
|
487
|
+
beforeEach(async function () {
|
488
|
+
await rt.SysContainer.start();
|
489
|
+
db = fireproof("test-reopen-idx");
|
490
|
+
const ok = await db.put({ _id: "test", foo: "bar" });
|
491
|
+
expect(ok.id).toBe("test");
|
492
|
+
|
493
|
+
didMap = false;
|
494
|
+
|
495
|
+
const mapFn = (doc: Doc) => {
|
496
|
+
didMap = true;
|
497
|
+
return doc.foo;
|
498
|
+
};
|
499
|
+
idx = index<string, Doc>(db, "foo", mapFn);
|
500
|
+
});
|
501
|
+
|
502
|
+
it("should persist data", async function () {
|
503
|
+
const doc = await db.get<Doc>("test");
|
504
|
+
expect(doc.foo).toBe("bar");
|
505
|
+
const idx2 = index<string, Doc>(db, "foo");
|
506
|
+
expect(idx2).toBe(idx);
|
507
|
+
const result = await idx2.query();
|
508
|
+
expect(result).toBeTruthy();
|
509
|
+
expect(result.rows).toBeTruthy();
|
510
|
+
expect(result.rows.length).toBe(1);
|
511
|
+
expect(result.rows[0].key).toBe("bar");
|
512
|
+
expect(didMap).toBeTruthy();
|
513
|
+
});
|
514
|
+
|
515
|
+
it("should reuse the index", async function () {
|
516
|
+
const idx2 = index(db, "foo", mapFn);
|
517
|
+
expect(idx2).toBe(idx);
|
518
|
+
const result = await idx2.query();
|
519
|
+
expect(result).toBeTruthy();
|
520
|
+
expect(result.rows).toBeTruthy();
|
521
|
+
expect(result.rows.length).toBe(1);
|
522
|
+
expect(result.rows[0].key).toBe("bar");
|
523
|
+
expect(didMap).toBeTruthy();
|
524
|
+
didMap = false;
|
525
|
+
const r2 = await idx2.query();
|
526
|
+
expect(r2).toBeTruthy();
|
527
|
+
expect(r2.rows).toBeTruthy();
|
528
|
+
expect(r2.rows.length).toBe(1);
|
529
|
+
expect(r2.rows[0].key).toBe("bar");
|
530
|
+
expect(didMap).toBeFalsy();
|
531
|
+
});
|
532
|
+
|
533
|
+
it("should have the same data on reopen", async function () {
|
534
|
+
const db2 = fireproof("test-reopen-idx");
|
535
|
+
const doc = await db2.get<FooType>("test");
|
536
|
+
expect(doc.foo).toBe("bar");
|
537
|
+
expect(db2._crdt.clock.head).toBeTruthy();
|
538
|
+
expect(db2._crdt.clock.head.length).toBe(1);
|
539
|
+
expect(db2._crdt.clock.head).toEqual(db._crdt.clock.head);
|
540
|
+
});
|
541
|
+
|
542
|
+
it("should have the same data on reopen after a query", async function () {
|
543
|
+
const r0 = await idx.query();
|
544
|
+
expect(r0).toBeTruthy();
|
545
|
+
expect(r0.rows).toBeTruthy();
|
546
|
+
expect(r0.rows.length).toBe(1);
|
547
|
+
expect(r0.rows[0].key).toBe("bar");
|
548
|
+
|
549
|
+
const db2 = fireproof("test-reopen-idx");
|
550
|
+
const doc = await db2.get<FooType>("test");
|
551
|
+
expect(doc.foo).toBe("bar");
|
552
|
+
expect(db2._crdt.clock.head).toBeTruthy();
|
553
|
+
expect(db2._crdt.clock.head.length).toBe(1);
|
554
|
+
expect(db2._crdt.clock.head).toEqual(db._crdt.clock.head);
|
555
|
+
});
|
556
|
+
|
557
|
+
// it('should query the same data on reopen', async function () {
|
558
|
+
// const r0 = await idx.query()
|
559
|
+
// assert(r0)
|
560
|
+
// assert(r0.rows)
|
561
|
+
// equals(r0.rows.length, 1)
|
562
|
+
// equals(r0.rows[0].key, 'bar')
|
563
|
+
|
564
|
+
// const db2 = fireproof('test-reopen-idx')
|
565
|
+
// const d2 = await db2.get('test')
|
566
|
+
// equals(d2.foo, 'bar')
|
567
|
+
// didMap = false
|
568
|
+
// const idx3 = db2.index('foo', mapFn)
|
569
|
+
// const result = await idx3.query()
|
570
|
+
// assert(result)
|
571
|
+
// assert(result.rows)
|
572
|
+
// equals(result.rows.length, 1)
|
573
|
+
// equals(result.rows[0].key, 'bar')
|
574
|
+
// assert(!didMap)
|
575
|
+
// })
|
576
|
+
});
|
577
|
+
|
578
|
+
describe("basic js verify", function () {
|
579
|
+
beforeAll(async function () {
|
580
|
+
await rt.SysContainer.start();
|
581
|
+
});
|
582
|
+
it("should include cids in arrays", async function () {
|
583
|
+
const db = fireproof("test-verify");
|
584
|
+
const ok = await db.put({ _id: "test", foo: ["bar", "bam"] });
|
585
|
+
expect(ok.id).toBe("test");
|
586
|
+
const ok2 = await db.put({ _id: "test2", foo: ["bar", "bam"] });
|
587
|
+
expect(ok2.id).toBe("test2");
|
588
|
+
const blocks = db._crdt.blockstore as bs.EncryptedBlockstore;
|
589
|
+
const loader = blocks.loader;
|
590
|
+
expect(loader).toBeTruthy();
|
591
|
+
const cid = loader.carLog[0][0];
|
592
|
+
const cid2 = db._crdt.clock.head[0];
|
593
|
+
expect(cid).not.toBe(cid2);
|
594
|
+
expect(cid).not.toBe(cid2);
|
595
|
+
const cidList = [cid, cid2];
|
596
|
+
const cid3 = CID.parse(cid.toString());
|
597
|
+
expect(cidList.includes(cid3)).toBeFalsy(); // sad trombone
|
598
|
+
expect(carLogIncludesGroup(cidList, cid3)).toBeTruthy();
|
599
|
+
await db.close();
|
600
|
+
await db.destroy();
|
601
|
+
});
|
602
|
+
});
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import { rt, fireproof as database, Database, DbResponse, DocWithId, index, Index, IndexRows } from "@fireproof/core";
|
2
|
+
|
3
|
+
describe("Hello World Test", function () {
|
4
|
+
it("should pass the hello world test", function () {
|
5
|
+
const result = database("hello"); // call to your library function
|
6
|
+
expect(result.name).toBe("hello");
|
7
|
+
});
|
8
|
+
});
|
9
|
+
|
10
|
+
describe("public API", function () {
|
11
|
+
interface TestDoc {
|
12
|
+
foo: string;
|
13
|
+
}
|
14
|
+
let db: Database;
|
15
|
+
let idx: Index<string, TestDoc>;
|
16
|
+
let ok: DbResponse;
|
17
|
+
let doc: DocWithId<TestDoc>;
|
18
|
+
let query: IndexRows<string, TestDoc>;
|
19
|
+
afterEach(async function () {
|
20
|
+
await db.close();
|
21
|
+
await db.destroy();
|
22
|
+
await idx.close();
|
23
|
+
await idx.destroy();
|
24
|
+
});
|
25
|
+
beforeEach(async function () {
|
26
|
+
await rt.SysContainer.start();
|
27
|
+
db = database("test-public-api");
|
28
|
+
idx = index<string, TestDoc>(db, "test-index", (doc) => doc.foo);
|
29
|
+
ok = await db.put({ _id: "test", foo: "bar" });
|
30
|
+
doc = await db.get("test");
|
31
|
+
query = await idx.query();
|
32
|
+
});
|
33
|
+
it("should have a database", function () {
|
34
|
+
expect(db).toBeTruthy();
|
35
|
+
expect(db instanceof Database).toBeTruthy();
|
36
|
+
});
|
37
|
+
it("should have an index", function () {
|
38
|
+
expect(idx).toBeTruthy();
|
39
|
+
expect(idx instanceof Index).toBeTruthy();
|
40
|
+
});
|
41
|
+
it("should put", function () {
|
42
|
+
expect(ok).toBeTruthy();
|
43
|
+
expect(ok.id).toBe("test");
|
44
|
+
});
|
45
|
+
it("should get", function () {
|
46
|
+
expect(doc.foo).toBe("bar");
|
47
|
+
});
|
48
|
+
it("should query", function () {
|
49
|
+
expect(query).toBeTruthy();
|
50
|
+
expect(query.rows).toBeTruthy();
|
51
|
+
expect(query.rows.length).toBe(1);
|
52
|
+
expect(query.rows[0].key).toBe("bar");
|
53
|
+
});
|
54
|
+
});
|