@fireproof/core-test 0.0.0-smoke-1b31059-1752074105

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 (162) hide show
  1. package/LICENSE.md +232 -0
  2. package/blockstore/fp-envelope.test.ts-off +65 -0
  3. package/blockstore/fragment-gateway.test.ts-off +106 -0
  4. package/blockstore/interceptor-gateway.test.d.ts +19 -0
  5. package/blockstore/interceptor-gateway.test.js +217 -0
  6. package/blockstore/interceptor-gateway.test.js.map +1 -0
  7. package/blockstore/interceptor-gateway.test.ts +259 -0
  8. package/blockstore/keyed-crypto-indexeddb-file.test.d.ts +1 -0
  9. package/blockstore/keyed-crypto-indexeddb-file.test.js +114 -0
  10. package/blockstore/keyed-crypto-indexeddb-file.test.js.map +1 -0
  11. package/blockstore/keyed-crypto-indexeddb-file.test.ts +134 -0
  12. package/blockstore/keyed-crypto.test.d.ts +1 -0
  13. package/blockstore/keyed-crypto.test.js +310 -0
  14. package/blockstore/keyed-crypto.test.js.map +1 -0
  15. package/blockstore/keyed-crypto.test.ts +382 -0
  16. package/blockstore/loader.test.d.ts +1 -0
  17. package/blockstore/loader.test.js +241 -0
  18. package/blockstore/loader.test.js.map +1 -0
  19. package/blockstore/loader.test.ts +313 -0
  20. package/blockstore/standalone.test.d.ts +1 -0
  21. package/blockstore/standalone.test.js +112 -0
  22. package/blockstore/standalone.test.js.map +1 -0
  23. package/blockstore/standalone.test.ts +156 -0
  24. package/blockstore/store.test.d.ts +1 -0
  25. package/blockstore/store.test.js +152 -0
  26. package/blockstore/store.test.js.map +1 -0
  27. package/blockstore/store.test.ts +199 -0
  28. package/blockstore/transaction.test.d.ts +1 -0
  29. package/blockstore/transaction.test.js +109 -0
  30. package/blockstore/transaction.test.js.map +1 -0
  31. package/blockstore/transaction.test.ts +132 -0
  32. package/fireproof/all-gateway.test.d.ts +1 -0
  33. package/fireproof/all-gateway.test.js +333 -0
  34. package/fireproof/all-gateway.test.js.map +1 -0
  35. package/fireproof/all-gateway.test.ts +477 -0
  36. package/fireproof/attachable.test.d.ts +1 -0
  37. package/fireproof/attachable.test.js +438 -0
  38. package/fireproof/attachable.test.js.map +1 -0
  39. package/fireproof/attachable.test.ts +677 -0
  40. package/fireproof/cars/bafkreidxwt2nhvbl4fnqfw3ctlt6zbrir4kqwmjo5im6rf4q5si27kgo2i.car +0 -0
  41. package/fireproof/cars/bafkreidxwt2nhvbl4fnqfw3ctlt6zbrir4kqwmjo5im6rf4q5si27kgo2i.d.ts +4 -0
  42. package/fireproof/cars/bafkreidxwt2nhvbl4fnqfw3ctlt6zbrir4kqwmjo5im6rf4q5si27kgo2i.js +325 -0
  43. package/fireproof/cars/bafkreidxwt2nhvbl4fnqfw3ctlt6zbrir4kqwmjo5im6rf4q5si27kgo2i.js.map +1 -0
  44. package/fireproof/cars/bafkreidxwt2nhvbl4fnqfw3ctlt6zbrir4kqwmjo5im6rf4q5si27kgo2i.ts +324 -0
  45. package/fireproof/charwise-boolean.test.d.ts +1 -0
  46. package/fireproof/charwise-boolean.test.js +43 -0
  47. package/fireproof/charwise-boolean.test.js.map +1 -0
  48. package/fireproof/charwise-boolean.test.ts +68 -0
  49. package/fireproof/crdt.test.d.ts +1 -0
  50. package/fireproof/crdt.test.js +509 -0
  51. package/fireproof/crdt.test.js.map +1 -0
  52. package/fireproof/crdt.test.ts +572 -0
  53. package/fireproof/database.test.d.ts +1 -0
  54. package/fireproof/database.test.js +658 -0
  55. package/fireproof/database.test.js.map +1 -0
  56. package/fireproof/database.test.ts +772 -0
  57. package/fireproof/deleted-docs-handling.test.d.ts +1 -0
  58. package/fireproof/deleted-docs-handling.test.js +69 -0
  59. package/fireproof/deleted-docs-handling.test.js.map +1 -0
  60. package/fireproof/deleted-docs-handling.test.ts +112 -0
  61. package/fireproof/fireproof.test.d.ts +3 -0
  62. package/fireproof/fireproof.test.fixture.d.ts +15 -0
  63. package/fireproof/fireproof.test.fixture.js +134 -0
  64. package/fireproof/fireproof.test.fixture.js.map +1 -0
  65. package/fireproof/fireproof.test.fixture.ts +133 -0
  66. package/fireproof/fireproof.test.js +574 -0
  67. package/fireproof/fireproof.test.js.map +1 -0
  68. package/fireproof/fireproof.test.ts +767 -0
  69. package/fireproof/hello.test.d.ts +1 -0
  70. package/fireproof/hello.test.js +67 -0
  71. package/fireproof/hello.test.js.map +1 -0
  72. package/fireproof/hello.test.ts +75 -0
  73. package/fireproof/indexer.test.d.ts +1 -0
  74. package/fireproof/indexer.test.js +408 -0
  75. package/fireproof/indexer.test.js.map +1 -0
  76. package/fireproof/indexer.test.ts +459 -0
  77. package/fireproof/multiple-ledger.test.d.ts +1 -0
  78. package/fireproof/multiple-ledger.test.js +51 -0
  79. package/fireproof/multiple-ledger.test.js.map +1 -0
  80. package/fireproof/multiple-ledger.test.ts +67 -0
  81. package/fireproof/query-docs.test.d.ts +1 -0
  82. package/fireproof/query-docs.test.js +69 -0
  83. package/fireproof/query-docs.test.js.map +1 -0
  84. package/fireproof/query-docs.test.ts +117 -0
  85. package/fireproof/query-limit-issue.test.d.ts +1 -0
  86. package/fireproof/query-limit-issue.test.js +89 -0
  87. package/fireproof/query-limit-issue.test.js.map +1 -0
  88. package/fireproof/query-limit-issue.test.ts +147 -0
  89. package/fireproof/query-property-inconsistency.test.d.ts +1 -0
  90. package/fireproof/query-property-inconsistency.test.js +52 -0
  91. package/fireproof/query-property-inconsistency.test.js.map +1 -0
  92. package/fireproof/query-property-inconsistency.test.ts +90 -0
  93. package/fireproof/query-result-properties.test.d.ts +1 -0
  94. package/fireproof/query-result-properties.test.js +25 -0
  95. package/fireproof/query-result-properties.test.js.map +1 -0
  96. package/fireproof/query-result-properties.test.ts +43 -0
  97. package/fireproof/stable-cid.test.d.ts +1 -0
  98. package/fireproof/stable-cid.test.js +52 -0
  99. package/fireproof/stable-cid.test.js.map +1 -0
  100. package/fireproof/stable-cid.test.ts +72 -0
  101. package/fireproof/utils.test.d.ts +1 -0
  102. package/fireproof/utils.test.js +124 -0
  103. package/fireproof/utils.test.js.map +1 -0
  104. package/fireproof/utils.test.ts +137 -0
  105. package/gateway/file/loader-config.test.d.ts +1 -0
  106. package/gateway/file/loader-config.test.js +255 -0
  107. package/gateway/file/loader-config.test.js.map +1 -0
  108. package/gateway/file/loader-config.test.ts +309 -0
  109. package/gateway/indexeddb/loader-config.test.d.ts +1 -0
  110. package/gateway/indexeddb/loader-config.test.js +77 -0
  111. package/gateway/indexeddb/loader-config.test.js.map +1 -0
  112. package/gateway/indexeddb/loader-config.test.ts +80 -0
  113. package/global-setup.d.ts +2 -0
  114. package/global-setup.js +9 -0
  115. package/global-setup.js.map +1 -0
  116. package/global-setup.ts +11 -0
  117. package/helpers.d.ts +31 -0
  118. package/helpers.js +140 -0
  119. package/helpers.js.map +1 -0
  120. package/helpers.ts +177 -0
  121. package/package.json +75 -0
  122. package/protocols/cloud/msger.test.d.ts +1 -0
  123. package/protocols/cloud/msger.test.js +464 -0
  124. package/protocols/cloud/msger.test.js.map +1 -0
  125. package/protocols/cloud/msger.test.ts +559 -0
  126. package/runtime/fp-envelope-serialize.test.d.ts +1 -0
  127. package/runtime/fp-envelope-serialize.test.js +223 -0
  128. package/runtime/fp-envelope-serialize.test.js.map +1 -0
  129. package/runtime/fp-envelope-serialize.test.ts +266 -0
  130. package/runtime/meta-key-hack.test.d.ts +1 -0
  131. package/runtime/meta-key-hack.test.js +85 -0
  132. package/runtime/meta-key-hack.test.js.map +1 -0
  133. package/runtime/meta-key-hack.test.ts +103 -0
  134. package/setup.file.d.ts +1 -0
  135. package/setup.file.js +3 -0
  136. package/setup.file.js.map +1 -0
  137. package/setup.file.ts +1 -0
  138. package/setup.indexeddb.d.ts +1 -0
  139. package/setup.indexeddb.js +2 -0
  140. package/setup.indexeddb.js.map +1 -0
  141. package/setup.indexeddb.ts +0 -0
  142. package/setup.memory.d.ts +1 -0
  143. package/setup.memory.js +4 -0
  144. package/setup.memory.js.map +1 -0
  145. package/setup.memory.ts +2 -0
  146. package/tsconfig.json +18 -0
  147. package/vitest.config.d.ts +2 -0
  148. package/vitest.config.js +8 -0
  149. package/vitest.config.js.map +1 -0
  150. package/vitest.config.ts +8 -0
  151. package/vitest.file.config.d.ts +2 -0
  152. package/vitest.file.config.js +11 -0
  153. package/vitest.file.config.js.map +1 -0
  154. package/vitest.file.config.ts +11 -0
  155. package/vitest.indexeddb.config.d.ts +2 -0
  156. package/vitest.indexeddb.config.js +21 -0
  157. package/vitest.indexeddb.config.js.map +1 -0
  158. package/vitest.indexeddb.config.ts +34 -0
  159. package/vitest.memory.config.d.ts +2 -0
  160. package/vitest.memory.config.js +24 -0
  161. package/vitest.memory.config.js.map +1 -0
  162. package/vitest.memory.config.ts +24 -0
@@ -0,0 +1,459 @@
1
+ import {
2
+ Index,
3
+ index,
4
+ CRDT,
5
+ IndexRows,
6
+ toStoreURIRuntime,
7
+ defaultWriteQueueOpts,
8
+ LedgerOpts,
9
+ Database,
10
+ CRDTImpl,
11
+ fireproof,
12
+ } from "@fireproof/core";
13
+ import { tracer } from "../helpers.js";
14
+ import { AppContext } from "@adviser/cement";
15
+ import { ensureSuperThis } from "@fireproof/core-runtime";
16
+ import { describe, afterEach, beforeEach, it, expect } from "vitest";
17
+ import { ensureStoreEnDeFile } from "@fireproof/core-blockstore";
18
+ import { defaultKeyBagOpts } from "@fireproof/core-keybag";
19
+
20
+ interface TestType {
21
+ readonly title: string;
22
+ readonly score: number;
23
+ }
24
+
25
+ describe("basic Index", () => {
26
+ let db: Database;
27
+ let indexer: Index<TestType, string>;
28
+ let didMap: boolean;
29
+ const sthis = ensureSuperThis();
30
+ afterEach(async () => {
31
+ await db.close();
32
+ await db.destroy();
33
+ // await indexer.close();
34
+ // await indexer.destroy();
35
+ });
36
+ beforeEach(async () => {
37
+ await sthis.start();
38
+ db = fireproof("test-indexer");
39
+ await db.put({ title: "amazing" });
40
+ await db.put({ title: "creative" });
41
+ await db.put({ title: "bazillas" });
42
+ indexer = new Index<TestType, string>(sthis, db.ledger.crdt, "hello", (doc) => {
43
+ didMap = true;
44
+ return doc.title;
45
+ });
46
+ await indexer.ready();
47
+ });
48
+ it("should have properties", function () {
49
+ expect(indexer.crdt).toBe(db.ledger.crdt);
50
+ // expect(indexer.crdt.name).toBe("test-indexer");
51
+ expect(indexer.name).toBe("hello");
52
+ expect(indexer.mapFn).toBeTruthy();
53
+ });
54
+ it("should call the map function on first query", async () => {
55
+ didMap = false;
56
+ await indexer.query();
57
+ expect(didMap).toBeTruthy();
58
+ });
59
+ it("should not call the map function on second query", async () => {
60
+ await indexer.query();
61
+ didMap = false;
62
+ await indexer.query();
63
+ expect(didMap).toBeFalsy();
64
+ });
65
+ it("should get results", async () => {
66
+ const result = await indexer.query();
67
+ expect(result).toBeTruthy();
68
+ expect(result.rows).toBeTruthy();
69
+ expect(result.rows.length).toBe(3);
70
+ });
71
+ it("should be in order", async () => {
72
+ const { rows } = await indexer.query();
73
+ expect(rows[0].key).toBe("amazing");
74
+ });
75
+ it("should work with limit", async () => {
76
+ const { rows } = await indexer.query({ limit: 1 });
77
+ expect(rows.length).toBe(1);
78
+ });
79
+ it("should work with descending", async () => {
80
+ const { rows } = await indexer.query({ descending: true });
81
+ expect(rows[0].key).toBe("creative");
82
+ });
83
+ it("should range query all", async () => {
84
+ const { rows } = await indexer.query({ range: ["a", "z"] });
85
+ expect(rows.length).toBe(3);
86
+ expect(rows[0].key).toBe("amazing");
87
+ });
88
+ it("should range query all twice", async () => {
89
+ const { rows } = await indexer.query({ range: ["a", "z"] });
90
+ expect(rows.length).toBe(3);
91
+ expect(rows[0].key).toBe("amazing");
92
+ const { rows: rows2 } = await indexer.query({ range: ["a", "z"] });
93
+ expect(rows2.length).toBe(3);
94
+ expect(rows2[0].key).toBe("amazing");
95
+ });
96
+ it("should range query", async () => {
97
+ const { rows } = await indexer.query({ range: ["b", "d"] });
98
+ expect(rows[0].key).toBe("bazillas");
99
+ });
100
+ it("should key query", async () => {
101
+ const { rows } = await indexer.query({ key: "bazillas" });
102
+ expect(rows.length).toBe(1);
103
+ });
104
+ it("should include docs", async () => {
105
+ const { rows } = await indexer.query({ includeDocs: true });
106
+ expect(rows[0]).toBeTruthy();
107
+ expect(rows[0].id).toBeTruthy();
108
+ expect(rows[0].doc).toBeTruthy();
109
+ expect(rows[0].doc?._id).toBe(rows[0].id);
110
+ });
111
+ });
112
+
113
+ describe("Index query with compound key", function () {
114
+ let db: Database;
115
+ let indexer: Index<TestType, [string, number]>;
116
+ const sthis = ensureSuperThis();
117
+ afterEach(async () => {
118
+ await db.close();
119
+ await db.destroy();
120
+ // await indexer.close();
121
+ // await indexer.destroy();
122
+ });
123
+ beforeEach(async () => {
124
+ await sthis.start();
125
+ db = fireproof("test-indexer");
126
+ await db.put({ title: "amazing", score: 1 });
127
+ await db.put({ title: "creative", score: 2 });
128
+ await db.put({ title: "creative", score: 20 });
129
+ await db.put({ title: "bazillas", score: 3 });
130
+ indexer = new Index<TestType, [string, number]>(sthis, db.ledger.crdt, "hello", (doc) => {
131
+ return [doc.title, doc.score];
132
+ });
133
+ await indexer.ready();
134
+ });
135
+ it("should prefix query", async () => {
136
+ const { rows } = await indexer.query({ prefix: "creative" });
137
+ expect(rows.length).toBe(2);
138
+ expect(rows[0].key).toEqual(["creative", 2]);
139
+ expect(rows[1].key).toEqual(["creative", 20]);
140
+ });
141
+ });
142
+
143
+ describe("basic Index with map fun", function () {
144
+ let db: Database;
145
+ let indexer: Index<TestType, string>;
146
+ const sthis = ensureSuperThis();
147
+ afterEach(async () => {
148
+ await db.close();
149
+ await db.destroy();
150
+ // await indexer.close();
151
+ // await indexer.destroy();
152
+ });
153
+ beforeEach(async () => {
154
+ await sthis.start();
155
+ db = fireproof("test-indexer");
156
+ await db.put({ title: "amazing" });
157
+ await db.put({ title: "creative" });
158
+ await db.put({ title: "bazillas" });
159
+ indexer = new Index<TestType, string>(sthis, db.ledger.crdt, "hello", (doc, map) => {
160
+ map(doc.title);
161
+ });
162
+ await indexer.ready();
163
+ });
164
+ it("should get results", async () => {
165
+ const result = await indexer.query();
166
+ expect(result).toBeTruthy();
167
+ expect(result.rows).toBeTruthy();
168
+ expect(result.rows.length).toBe(3);
169
+ expect(result.rows[0].key).toBe("amazing");
170
+ });
171
+ });
172
+
173
+ describe("basic Index with map fun with value", function () {
174
+ let db: Database;
175
+ let indexer: Index<TestType, string, number>;
176
+ const sthis = ensureSuperThis();
177
+ afterEach(async () => {
178
+ await db.close();
179
+ await db.destroy();
180
+ });
181
+ beforeEach(async () => {
182
+ await sthis.start();
183
+ db = fireproof("test-indexer");
184
+ await db.put({ title: "amazing" });
185
+ await db.put({ title: "creative" });
186
+ await db.put({ title: "bazillas" });
187
+ indexer = new Index<TestType, string, number>(sthis, db.ledger.crdt, "hello", (doc, map) => {
188
+ map(doc.title, doc.title.length);
189
+ });
190
+ });
191
+ it("should get results", async () => {
192
+ const result = await indexer.query();
193
+ expect(result).toBeTruthy();
194
+ expect(result.rows).toBeTruthy();
195
+ expect(result.rows.length).toBe(3);
196
+ expect(result.rows[0].key).toBe("amazing");
197
+ // @jchris why is this not a object?
198
+ expect(result.rows[0].value).toBe(7);
199
+ });
200
+ it("should include docs", async () => {
201
+ const { rows } = await indexer.query({ includeDocs: true });
202
+ expect(rows[0].doc).toBeTruthy();
203
+ expect(rows[0].doc?._id).toBe(rows[0].id);
204
+ expect(rows.length).toBe(3);
205
+ expect(rows[0].key).toBe("amazing");
206
+ // @jchris why is this not a object?
207
+ expect(rows[0].value).toBe(7);
208
+ });
209
+ });
210
+
211
+ describe("Index query with map and compound key", function () {
212
+ let db: Database;
213
+ let indexer: Index<TestType, [string, number]>;
214
+ const sthis = ensureSuperThis();
215
+ afterEach(async () => {
216
+ await db.close();
217
+ await db.destroy();
218
+ // await indexer.close();
219
+ // await indexer.destroy();
220
+ });
221
+ beforeEach(async () => {
222
+ await sthis.start();
223
+ db = fireproof("test-indexer");
224
+ await db.put({ title: "amazing", score: 1 });
225
+ await db.put({ title: "creative", score: 2 });
226
+ await db.put({ title: "creative", score: 20 });
227
+ await db.put({ title: "bazillas", score: 3 });
228
+ indexer = new Index<TestType, [string, number]>(sthis, db.ledger.crdt, "hello", (doc, emit) => {
229
+ emit([doc.title, doc.score]);
230
+ });
231
+ await indexer.ready();
232
+ });
233
+ it("should prefix query", async () => {
234
+ const { rows } = await indexer.query({ prefix: "creative" });
235
+ expect(rows.length).toBe(2);
236
+ expect(rows[0].key).toEqual(["creative", 2]);
237
+ expect(rows[1].key).toEqual(["creative", 20]);
238
+ });
239
+ });
240
+
241
+ describe("basic Index with string fun", function () {
242
+ let db: Database;
243
+ let indexer: Index<TestType, string>;
244
+ const sthis = ensureSuperThis();
245
+ afterEach(async () => {
246
+ await db.close();
247
+ await db.destroy();
248
+ // await indexer.close();
249
+ // await indexer.destroy();
250
+ });
251
+ beforeEach(async () => {
252
+ await sthis.start();
253
+ db = fireproof("test-indexer");
254
+ await db.put({ title: "amazing" });
255
+ await db.put({ title: "creative" });
256
+ await db.put({ title: "bazillas" });
257
+ indexer = new Index<TestType, string>(sthis, db.ledger.crdt, "title");
258
+ await indexer.ready();
259
+ });
260
+ it("should get results", async () => {
261
+ const result = await indexer.query();
262
+ expect(result).toBeTruthy();
263
+ expect(result.rows).toBeTruthy();
264
+ expect(result.rows.length).toBe(3);
265
+ });
266
+ it("should include docs", async () => {
267
+ const { rows } = await indexer.query();
268
+ expect(rows.length).toBeTruthy();
269
+ expect(rows[0].doc).toBeTruthy();
270
+ });
271
+ });
272
+
273
+ describe("basic Index with string fun and numeric keys", function () {
274
+ let db: Database;
275
+ let indexer: Index<TestType, string>;
276
+ const sthis = ensureSuperThis();
277
+ afterEach(async () => {
278
+ await db.close();
279
+ await db.destroy();
280
+ // await indexer.close();
281
+ // await indexer.destroy();
282
+ });
283
+ beforeEach(async () => {
284
+ await sthis.start();
285
+ db = fireproof("test-indexer");
286
+ await db.put({ points: 0 });
287
+ await db.put({ points: 1 });
288
+ await db.put({ points: 2 });
289
+ await db.put({ points: 3 });
290
+ indexer = new Index<TestType, string>(sthis, db.ledger.crdt, "points");
291
+ await indexer.ready();
292
+ });
293
+ it("should get results", async () => {
294
+ const result = await indexer.query();
295
+ expect(result).toBeTruthy();
296
+ expect(result.rows).toBeTruthy();
297
+ expect(result.rows.length).toBe(4);
298
+ });
299
+ it("should include docs", async () => {
300
+ const { rows } = await indexer.query();
301
+ expect(rows.length).toBeTruthy();
302
+ expect(rows[0].doc).toBeTruthy();
303
+ });
304
+ });
305
+
306
+ describe("basic Index upon cold start", function () {
307
+ interface TestType {
308
+ title: string;
309
+ score?: number;
310
+ }
311
+ let crdt: CRDT;
312
+ let indexer: Index<TestType>;
313
+ let didMap: number;
314
+ let mapFn: (doc: TestType) => string;
315
+ let result: IndexRows<TestType>;
316
+ const sthis = ensureSuperThis();
317
+ let dbOpts: LedgerOpts;
318
+ // result, mapFn;
319
+ afterEach(async () => {
320
+ await crdt.close();
321
+ await crdt.destroy();
322
+ // await indexer.close();
323
+ // await indexer.destroy();
324
+ });
325
+ beforeEach(async () => {
326
+ await sthis.start();
327
+ const logger = sthis.logger.With().Module("IndexerTest").Logger();
328
+ logger.Debug().Msg("enter beforeEach");
329
+ dbOpts = {
330
+ name: "test-indexer-cold",
331
+ writeQueue: defaultWriteQueueOpts({}),
332
+ keyBag: defaultKeyBagOpts(sthis),
333
+ storeUrls: toStoreURIRuntime(sthis, "test-indexer-cold"),
334
+ storeEnDe: ensureStoreEnDeFile({}),
335
+ ctx: new AppContext(),
336
+ tracer,
337
+ };
338
+ crdt = new CRDTImpl(sthis, dbOpts);
339
+ await crdt.bulk([
340
+ { id: "abc1", value: { title: "amazing" } },
341
+ { id: "abc2", value: { title: "creative" } },
342
+ { id: "abc3", value: { title: "bazillas" } },
343
+ ]);
344
+ logger.Debug().Msg("post bulk beforeEach");
345
+ didMap = 0;
346
+ mapFn = (doc) => {
347
+ didMap++;
348
+ return doc.title;
349
+ };
350
+ indexer = await index<TestType>(crdt, "hello", mapFn);
351
+ logger.Debug().Msg("post index beforeEach");
352
+ await indexer.ready();
353
+ logger.Debug().Msg("post indexer.ready beforeEach");
354
+ // new Index(db._crdt.indexBlockstore, db._crdt, 'hello', mapFn)
355
+ result = await indexer.query();
356
+
357
+ logger.Debug().Msg("post indexer.query beforeEach");
358
+ expect(indexer.indexHead).toEqual(crdt.clock.head);
359
+ });
360
+ it("should call map on first query", function () {
361
+ expect(didMap).toBeTruthy();
362
+ expect(didMap).toEqual(3);
363
+ });
364
+ it("should get results on first query", function () {
365
+ expect(result).toBeTruthy();
366
+ expect(result.rows).toBeTruthy();
367
+ expect(result.rows.length).toEqual(3);
368
+ });
369
+ it("should work on cold load", async () => {
370
+ const crdt2 = new CRDTImpl(sthis, dbOpts);
371
+ await crdt2.ready();
372
+ const { result, head } = await crdt2.changes();
373
+ expect(result).toBeTruthy();
374
+ await crdt2.ready();
375
+ const indexer2 = await index<TestType>(crdt2, "hello", mapFn);
376
+ await indexer2.ready();
377
+ const result2 = await indexer2.query();
378
+ expect(indexer2.indexHead).toEqual(head);
379
+ expect(result2).toBeTruthy();
380
+ expect(result2.rows.length).toEqual(3);
381
+ expect(indexer2.indexHead).toEqual(head);
382
+ });
383
+ it.skip("should not rerun the map function on seen changes", async () => {
384
+ didMap = 0;
385
+ const crdt2 = new CRDTImpl(sthis, dbOpts);
386
+ const indexer2 = await index(crdt2, "hello", mapFn);
387
+ const { result, head } = await crdt2.changes([]);
388
+ expect(result.length).toEqual(3);
389
+ expect(head.length).toEqual(1);
390
+ const { result: ch2, head: h2 } = await crdt2.changes(head);
391
+ expect(ch2.length).toEqual(0);
392
+ expect(h2.length).toEqual(1);
393
+ expect(h2).toEqual(head);
394
+ const result2 = await indexer2.query();
395
+ expect(indexer2.indexHead).toEqual(head);
396
+ expect(result2).toBeTruthy();
397
+ expect(result2.rows.length).toEqual(3);
398
+ expect(didMap).toEqual(0);
399
+ await crdt2.bulk([{ id: "abc4", value: { title: "despicable", score: 0 } }]);
400
+
401
+ const { result: ch3, head: h3 } = await crdt2.changes(head);
402
+ expect(ch3.length).toEqual(1);
403
+ expect(h3.length).toEqual(1);
404
+ const result3 = await indexer2.query();
405
+ expect(result3).toBeTruthy();
406
+ expect(result3.rows.length).toEqual(4);
407
+ expect(didMap).toEqual(1);
408
+ });
409
+ it("should ignore meta when map function definiton changes", async () => {
410
+ const crdt2 = new CRDTImpl(sthis, dbOpts);
411
+ const result = await index<TestType>(crdt2, "hello", (doc) => doc.title.split("").reverse().join("")).query();
412
+ expect(result.rows.length).toEqual(3);
413
+ expect(result.rows[0].key).toEqual("evitaerc"); // creative
414
+ });
415
+ });
416
+
417
+ describe("basic Index with no data", function () {
418
+ let db: Database;
419
+ let indexer: Index<TestType>;
420
+ let didMap: boolean;
421
+ const sthis = ensureSuperThis();
422
+ afterEach(async () => {
423
+ await db.close();
424
+ await db.destroy();
425
+ // await indexer.close();
426
+ // await indexer.destroy();
427
+ });
428
+ beforeEach(async () => {
429
+ await sthis.start();
430
+ db = fireproof("test-indexer");
431
+ indexer = new Index<TestType>(sthis, db.ledger.crdt, "hello", (doc) => {
432
+ didMap = true;
433
+ return doc.title;
434
+ });
435
+ await indexer.ready();
436
+ });
437
+ it("should have properties", function () {
438
+ expect(indexer.crdt).toEqual(db.ledger.crdt);
439
+ expect(indexer.name).toEqual("hello");
440
+ expect(indexer.mapFn).toBeTruthy();
441
+ });
442
+ it("should not call the map function on first query", async () => {
443
+ didMap = false;
444
+ await indexer.query();
445
+ expect(didMap).toBeFalsy();
446
+ });
447
+ it("should not call the map function on second query", async () => {
448
+ await indexer.query();
449
+ didMap = false;
450
+ await indexer.query();
451
+ expect(didMap).toBeFalsy();
452
+ });
453
+ it("should get results", async () => {
454
+ const result = await indexer.query();
455
+ expect(result).toBeTruthy();
456
+ expect(result.rows).toBeTruthy();
457
+ expect(result.rows.length).toEqual(0);
458
+ });
459
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,51 @@
1
+ import { ensureSuperThis } from "@fireproof/core-runtime";
2
+ import { fireproof } from "@fireproof/core-base";
3
+ import { describe, beforeEach, afterEach, it, expect } from "vitest";
4
+ function shuffle(ina) {
5
+ const array = [...ina];
6
+ for (let i = array.length - 1; i > 0; i--) {
7
+ const j = Math.floor(Math.random() * (i + 1));
8
+ [array[i], array[j]] = [array[j], array[i]];
9
+ }
10
+ return array;
11
+ }
12
+ describe("Multiple Databases", () => {
13
+ const dbs = [];
14
+ const sthis = ensureSuperThis();
15
+ const rows = 10;
16
+ const concurrentDbs = 7;
17
+ beforeEach(async () => {
18
+ const group = sthis.nextId().str;
19
+ await Promise.all(Array(concurrentDbs)
20
+ .fill(0)
21
+ .map(async (_, i) => {
22
+ const name = `db-${group}-${i}`;
23
+ const db = fireproof(name);
24
+ dbs.push({ db, name });
25
+ for (let i = 0; i < rows; i++) {
26
+ await db.put({ _id: `${name}-${i}`, hello: "world" });
27
+ }
28
+ }));
29
+ });
30
+ afterEach(async () => {
31
+ await Promise.all(dbs.map(async (db) => {
32
+ await db.db.close();
33
+ await db.db.destroy();
34
+ }));
35
+ dbs.length = 0;
36
+ });
37
+ it("random access to multiple databases", async () => {
38
+ const random = shuffle(dbs);
39
+ const res = await Promise.all(random.map((di) => {
40
+ return Promise.all(Array(10)
41
+ .fill(0)
42
+ .map(async (_, i) => di.db.get(`${di.name}-${i}`)));
43
+ }));
44
+ res.forEach((res, i) => {
45
+ for (let j = 0; j < rows; j++) {
46
+ expect(res[j]._id).toBe(`${random[i].name}-${j}`);
47
+ }
48
+ });
49
+ });
50
+ });
51
+ //# sourceMappingURL=multiple-ledger.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multiple-ledger.test.js","sourceRoot":"","sources":["multiple-ledger.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import { ensureSuperThis } from "@fireproof/core-runtime";
2
+ import { Database } from "@fireproof/core-types-base";
3
+ import { fireproof } from "@fireproof/core-base";
4
+ import { describe, beforeEach, afterEach, it, expect } from "vitest";
5
+ interface DBItem {
6
+ readonly db: Database;
7
+ readonly name: string;
8
+ }
9
+
10
+ function shuffle(ina: DBItem[]): DBItem[] {
11
+ const array = [...ina];
12
+ for (let i = array.length - 1; i > 0; i--) {
13
+ const j = Math.floor(Math.random() * (i + 1));
14
+ [array[i], array[j]] = [array[j], array[i]];
15
+ }
16
+ return array;
17
+ }
18
+
19
+ describe("Multiple Databases", () => {
20
+ const dbs: DBItem[] = [];
21
+ const sthis = ensureSuperThis();
22
+ const rows = 10;
23
+ const concurrentDbs = 7;
24
+ beforeEach(async () => {
25
+ const group = sthis.nextId().str;
26
+ await Promise.all(
27
+ Array(concurrentDbs)
28
+ .fill(0)
29
+ .map(async (_, i) => {
30
+ const name = `db-${group}-${i}`;
31
+ const db = fireproof(name);
32
+ dbs.push({ db, name });
33
+ for (let i = 0; i < rows; i++) {
34
+ await db.put({ _id: `${name}-${i}`, hello: "world" });
35
+ }
36
+ }),
37
+ );
38
+ });
39
+ afterEach(async () => {
40
+ await Promise.all(
41
+ dbs.map(async (db) => {
42
+ await db.db.close();
43
+ await db.db.destroy();
44
+ }),
45
+ );
46
+ dbs.length = 0;
47
+ });
48
+
49
+ it("random access to multiple databases", async () => {
50
+ const random = shuffle(dbs);
51
+ const res = await Promise.all(
52
+ random.map((di) => {
53
+ return Promise.all(
54
+ Array(10)
55
+ .fill(0)
56
+ .map(async (_, i) => di.db.get(`${di.name}-${i}`)),
57
+ );
58
+ }),
59
+ );
60
+ // console.log(res)
61
+ res.forEach((res, i) => {
62
+ for (let j = 0; j < rows; j++) {
63
+ expect(res[j]._id).toBe(`${random[i].name}-${j}`);
64
+ }
65
+ });
66
+ });
67
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,69 @@
1
+ import { fireproof } from "@fireproof/core";
2
+ import { describe, beforeEach, afterEach, it, expect } from "vitest";
3
+ describe("query return value consistency", function () {
4
+ let db;
5
+ beforeEach(async () => {
6
+ db = fireproof("test-query-docs");
7
+ await db.put({ _id: "doc1", text: "hello world", category: "greeting", active: true });
8
+ await db.put({ _id: "doc2", text: "goodbye world", category: "farewell", active: true });
9
+ await db.put({ _id: "doc3", text: "hello again", category: "greeting", active: false });
10
+ });
11
+ afterEach(async () => {
12
+ await db.close();
13
+ await db.destroy();
14
+ });
15
+ it("database query should return docs property like useLiveQuery", async function () {
16
+ const result = await db.query("category");
17
+ expect(result).toHaveProperty("rows");
18
+ expect(result.rows.length).toBe(3);
19
+ expect(result).toHaveProperty("docs");
20
+ expect(Array.isArray(result.docs)).toBe(true);
21
+ expect(result.docs.length).toBe(3);
22
+ const docIds = result.docs.map((doc) => doc._id).sort();
23
+ expect(docIds).toEqual(["doc1", "doc2", "doc3"]);
24
+ });
25
+ it("should return docs with the same order as rows", async function () {
26
+ const result = await db.query("category");
27
+ expect(result).toHaveProperty("docs");
28
+ for (let i = 0; i < result.rows.length; i++) {
29
+ const row = result.rows[i];
30
+ const doc = result.docs[i];
31
+ expect(doc._id).toBe(row.id);
32
+ }
33
+ });
34
+ it("should work with complex map functions and query options", async function () {
35
+ const result = await db.query((doc) => doc.active, {
36
+ key: true,
37
+ includeDocs: true,
38
+ });
39
+ expect(result.rows.length).toBeGreaterThan(0);
40
+ expect(result).toHaveProperty("docs");
41
+ expect(result.docs.length).toBe(result.rows.length);
42
+ result.docs.forEach((doc) => {
43
+ expect(doc.active).toBe(true);
44
+ });
45
+ });
46
+ it("should only return docs with false value when queried with {key: false}", async function () {
47
+ const result = await db.query((doc) => doc.active, {
48
+ key: false,
49
+ includeDocs: true,
50
+ });
51
+ expect(result.rows.length).toBe(1);
52
+ expect(result).toHaveProperty("docs");
53
+ expect(result.docs.length).toBe(result.rows.length);
54
+ result.docs.forEach((doc) => {
55
+ expect(doc.active).toBe(false);
56
+ });
57
+ const activeTrue = result.docs.filter((doc) => doc.active === true);
58
+ expect(activeTrue.length).toBe(0);
59
+ const trueResult = await db.query((doc) => doc.active, {
60
+ key: true,
61
+ includeDocs: true,
62
+ });
63
+ expect(trueResult.rows.length).toBe(2);
64
+ trueResult.docs.forEach((doc) => {
65
+ expect(doc.active).toBe(true);
66
+ });
67
+ });
68
+ });
69
+ //# sourceMappingURL=query-docs.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-docs.test.js","sourceRoot":"","sources":["query-docs.test.ts"],"names":[],"mappings":"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"}