@fireproof/core 0.3.6 → 0.3.7
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.
- package/dist/main.js +2 -0
- package/dist/main.js.LICENSE.txt +17 -0
- package/package.json +28 -2
- package/hooks/use-fireproof.js +0 -135
- package/scripts/keygen.js +0 -3
- package/test/block.js +0 -65
- package/test/clock.test.js +0 -694
- package/test/db-index.test.js +0 -261
- package/test/fireproof.test.js +0 -491
- package/test/fulltext.test.js +0 -66
- package/test/helpers.js +0 -45
- package/test/hydrator.test.js +0 -81
- package/test/listener.test.js +0 -102
- package/test/prolly.test.js +0 -190
- package/test/proofs.test.js +0 -53
- package/test/reproduce-fixture-bug.test.js +0 -65
- package/test/valet.test.js +0 -59
- package/tsconfig.json +0 -104
- package/webpack.config.js +0 -8
package/test/fireproof.test.js
DELETED
@@ -1,491 +0,0 @@
|
|
1
|
-
import { describe, it, beforeEach } from 'mocha'
|
2
|
-
import assert from 'node:assert'
|
3
|
-
import { TransactionBlockstore as Blockstore } from '../src/blockstore.js'
|
4
|
-
import { Fireproof } from '../src/fireproof.js'
|
5
|
-
import { Hydrator } from '../src/hydrator.js'
|
6
|
-
// import * as codec from '@ipld/dag-cbor'
|
7
|
-
|
8
|
-
let database, resp0
|
9
|
-
|
10
|
-
// const sleep = (ms) => new Promise((r) => setTimeout(r, ms))
|
11
|
-
|
12
|
-
describe('Fireproof', () => {
|
13
|
-
beforeEach(async () => {
|
14
|
-
database = Fireproof.storage('helloName')
|
15
|
-
resp0 = await database.put({
|
16
|
-
_id: '1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c',
|
17
|
-
name: 'alice',
|
18
|
-
age: 42
|
19
|
-
})
|
20
|
-
})
|
21
|
-
it('takes an optional name', () => {
|
22
|
-
assert.equal(database.name, 'helloName')
|
23
|
-
const km = database.blocks.valet.getKeyMaterial()
|
24
|
-
if (process.env.NO_ENCRYPT) { assert.equal(km, null) } else { assert.equal(km.length, 64) }
|
25
|
-
const x = database.blocks.valet.idb
|
26
|
-
const keyId = database.blocks.valet.keyId
|
27
|
-
assert.equal(x.name.toString(), `fp.${keyId}.helloName.valet`)
|
28
|
-
})
|
29
|
-
it('only put and get document', async () => {
|
30
|
-
assert(resp0.id, 'should have id')
|
31
|
-
assert.equal(resp0.id, '1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
32
|
-
const avalue = await database.get('1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
33
|
-
assert.equal(avalue.name, 'alice')
|
34
|
-
assert.equal(avalue.age, 42)
|
35
|
-
assert.equal(avalue._id, '1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
36
|
-
})
|
37
|
-
it('mvcc put and get document with _clock that matches', async () => {
|
38
|
-
assert(resp0.clock, 'should have clock')
|
39
|
-
assert.equal(resp0.clock[0].toString(), 'bafyreiadhnnxgaeeqdxujfew6zxr4lnjyskkrg26cdjvk7tivy6dt4xmsm')
|
40
|
-
const theDoc = await database.get('1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
41
|
-
theDoc._clock = database.clock
|
42
|
-
const put2 = await database.put(theDoc)
|
43
|
-
assert.equal(put2.id, '1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
44
|
-
assert.equal(put2.clock.length, 1)
|
45
|
-
assert.equal(put2.clock[0].toString(), 'bafyreib2kck2fv73lgahfcd5imarslgxcmachbxxavhtwahx5ppjfts4qe')
|
46
|
-
})
|
47
|
-
it('get should return an object instance that is not the same as the one in the db', async () => {
|
48
|
-
const theDoc = await database.get('1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
49
|
-
const theDoc2 = await database.get('1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
50
|
-
assert.notEqual(theDoc, theDoc2)
|
51
|
-
theDoc.name = 'really alice'
|
52
|
-
assert.equal(theDoc.name, 'really alice')
|
53
|
-
assert.equal(theDoc2.name, 'alice')
|
54
|
-
})
|
55
|
-
it('get with mvcc option', async () => {
|
56
|
-
const theDoc = await database.get('1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c', { mvcc: true })
|
57
|
-
assert(theDoc._clock, 'should have _clock')
|
58
|
-
assert.equal(theDoc._clock[0].toString(), 'bafyreiadhnnxgaeeqdxujfew6zxr4lnjyskkrg26cdjvk7tivy6dt4xmsm')
|
59
|
-
})
|
60
|
-
it('get with mvcc option where someone else changed another document first', async () => {
|
61
|
-
const theDoc = await database.get('1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c', { mvcc: true })
|
62
|
-
const put2 = await database.put({ something: 'else' })
|
63
|
-
assert(put2.clock, 'should have clock')
|
64
|
-
assert.notEqual(put2.clock.toString(), resp0.clock.toString())
|
65
|
-
assert.equal(theDoc._clock.toString(), resp0.clock.toString())
|
66
|
-
theDoc.name = 'somone else'
|
67
|
-
const put3works = await database.put(theDoc)
|
68
|
-
assert(put3works.clock, 'should have id')
|
69
|
-
})
|
70
|
-
it('get from an old snapshot with mvcc option', async () => {
|
71
|
-
const ogClock = resp0.clock
|
72
|
-
const theDoc = await database.get('1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
73
|
-
theDoc.name = 'not alice'
|
74
|
-
const put2 = await database.put(theDoc)
|
75
|
-
assert.equal(put2.id, '1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
76
|
-
assert.notEqual(put2.clock.toString(), ogClock.toString())
|
77
|
-
const theDoc2 = await database.get('1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c', { clock: ogClock })
|
78
|
-
assert.equal(theDoc2.name, 'alice')
|
79
|
-
})
|
80
|
-
it('put and get document with _clock that does not match b/c the doc changed', async () => {
|
81
|
-
const theDoc = await database.get('1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c', { mvcc: true })
|
82
|
-
theDoc.name = 'not alice'
|
83
|
-
const put2 = await database.put(theDoc)
|
84
|
-
assert.equal(put2.id, '1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
85
|
-
assert.notEqual(put2.clock.toString(), theDoc._clock.toString())
|
86
|
-
|
87
|
-
const err = await database.put(theDoc).catch((err) => err)
|
88
|
-
assert.match(err.message, /MVCC conflict/)
|
89
|
-
})
|
90
|
-
it('put and get document with _clock that does not match b/c a different doc changed should succeed', async () => {
|
91
|
-
const theDoc = await database.get('1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c', { mvcc: true })
|
92
|
-
assert.equal(theDoc.name, 'alice')
|
93
|
-
|
94
|
-
const putAnotherDoc = await database.put({ nothing: 'to see here' })
|
95
|
-
assert.notEqual(putAnotherDoc.clock.toString(), theDoc._clock.toString())
|
96
|
-
|
97
|
-
const ok = await database.put({ name: "isn't alice", ...theDoc })
|
98
|
-
assert.equal(ok.id, '1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
99
|
-
})
|
100
|
-
it('put and get document with _clock that does not match b/c the doc was deleted', async () => {
|
101
|
-
const theDoc = await database.get('1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c', { mvcc: true })
|
102
|
-
assert.equal(theDoc.name, 'alice')
|
103
|
-
const del = await database.del(theDoc)
|
104
|
-
assert(del.id)
|
105
|
-
const err = await database.put(theDoc).catch((err) => err)
|
106
|
-
console.log('err', err)
|
107
|
-
assert.match(err.message, /MVCC conflict/)
|
108
|
-
})
|
109
|
-
it('allDocuments', async () => {
|
110
|
-
await database.put({ name: 'bob' })
|
111
|
-
const allDocs = await database.allDocuments()
|
112
|
-
assert.equal(allDocs.rows.length, 2)
|
113
|
-
})
|
114
|
-
it('has a factory for making new instances with default settings', async () => {
|
115
|
-
// TODO if you pass it an email it asks the local keyring, and if no key, does the email validation thing
|
116
|
-
const db = await Fireproof.storage('test')
|
117
|
-
assert.equal(db.name, 'test')
|
118
|
-
})
|
119
|
-
it('an empty database has no documents', async () => {
|
120
|
-
const db = Fireproof.storage()
|
121
|
-
const e = await db.get('8c5c0c5c0c5c').catch((err) => err)
|
122
|
-
assert.equal(e.message, 'Not found')
|
123
|
-
const changes = await db.changesSince()
|
124
|
-
assert.equal(changes.rows.length, 0)
|
125
|
-
})
|
126
|
-
it('delete on an empty database', async () => {
|
127
|
-
const db = Fireproof.storage()
|
128
|
-
const e = await db.del('8c5c0c5c0c5c').catch((err) => err)
|
129
|
-
assert.equal(e.id, '8c5c0c5c0c5c')
|
130
|
-
const changes = await db.changesSince()
|
131
|
-
assert.equal(changes.rows.length, 0)
|
132
|
-
})
|
133
|
-
it('update existing document', async () => {
|
134
|
-
// const alice = await database.get('1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
135
|
-
// assert.equal(alice.name, 'alice')
|
136
|
-
|
137
|
-
const dogKey = 'aster-3c3a-4b5e-9c1c-8c5c0c5c0c5c'
|
138
|
-
const value = {
|
139
|
-
_id: dogKey,
|
140
|
-
name: 'aster',
|
141
|
-
age: 2
|
142
|
-
}
|
143
|
-
const response = await database.put(value)
|
144
|
-
assert(response.id, 'should have id')
|
145
|
-
assert.equal(response.id, dogKey)
|
146
|
-
assert.equal(value._id, dogKey)
|
147
|
-
const snapshot = Hydrator.snapshot(database)
|
148
|
-
|
149
|
-
const avalue = await database.get(dogKey)
|
150
|
-
assert.equal(avalue.name, value.name)
|
151
|
-
assert.equal(avalue.age, value.age)
|
152
|
-
assert.equal(avalue._id, dogKey)
|
153
|
-
|
154
|
-
avalue.age = 3
|
155
|
-
const response2 = await database.put(avalue)
|
156
|
-
assert(response2.id, 'should have id')
|
157
|
-
assert.equal(response2.id, dogKey)
|
158
|
-
|
159
|
-
const bvalue = await database.get(dogKey)
|
160
|
-
assert.equal(bvalue.name, value.name)
|
161
|
-
assert.equal(bvalue.age, 3)
|
162
|
-
assert.equal(bvalue._id, dogKey)
|
163
|
-
|
164
|
-
const snapdoc = await snapshot.get(dogKey)
|
165
|
-
// console.log('snapdoc', snapdoc)
|
166
|
-
// assert(snapdoc.id, 'should have id')
|
167
|
-
assert.equal(snapdoc._id, dogKey)
|
168
|
-
assert.equal(snapdoc.age, 2)
|
169
|
-
})
|
170
|
-
it("update document with validation function that doesn't allow it", async () => {
|
171
|
-
const validationDatabase = new Fireproof(new Blockstore(), [], {
|
172
|
-
validateChange: (newDoc, oldDoc, authCtx) => {
|
173
|
-
if (newDoc.name === 'bob') {
|
174
|
-
throw new Error('no bobs allowed')
|
175
|
-
}
|
176
|
-
}
|
177
|
-
})
|
178
|
-
const validResp = await validationDatabase.put({
|
179
|
-
_id: '111-alice',
|
180
|
-
name: 'alice',
|
181
|
-
age: 42
|
182
|
-
})
|
183
|
-
const getResp = await validationDatabase.get(validResp.id)
|
184
|
-
assert.equal(getResp.name, 'alice')
|
185
|
-
|
186
|
-
let e = await validationDatabase
|
187
|
-
.put({
|
188
|
-
_id: '222-bob',
|
189
|
-
name: 'bob',
|
190
|
-
age: 11
|
191
|
-
})
|
192
|
-
.catch((e) => e)
|
193
|
-
assert.equal(e.message, 'no bobs allowed')
|
194
|
-
|
195
|
-
e = await validationDatabase.get('222-bob').catch((e) => e)
|
196
|
-
assert.equal(e.message, 'Not found')
|
197
|
-
})
|
198
|
-
|
199
|
-
it('get missing document', async () => {
|
200
|
-
const e = await database.get('missing').catch((e) => e)
|
201
|
-
assert.equal(e.message, 'Not found')
|
202
|
-
})
|
203
|
-
it('delete the only document', async () => {
|
204
|
-
const id = '1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c'
|
205
|
-
const found = await database.get(id)
|
206
|
-
assert.equal(found._id, id)
|
207
|
-
const deleted = await database.del(id)
|
208
|
-
assert.equal(deleted.id, id)
|
209
|
-
const e = await database
|
210
|
-
.get(id)
|
211
|
-
.then((doc) => assert.equal('should be deleted', JSON.stringify(doc)))
|
212
|
-
.catch((e) => {
|
213
|
-
if (e.message !== 'Not found') {
|
214
|
-
throw e
|
215
|
-
}
|
216
|
-
return e
|
217
|
-
})
|
218
|
-
assert.equal(e.message, 'Not found')
|
219
|
-
})
|
220
|
-
|
221
|
-
it('delete not last document', async () => {
|
222
|
-
const resp1 = await database.put({
|
223
|
-
_id: 'second',
|
224
|
-
name: 'bob',
|
225
|
-
age: 39
|
226
|
-
})
|
227
|
-
|
228
|
-
// const id = '1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c'
|
229
|
-
const id = resp1.id
|
230
|
-
const found = await database.get(id)
|
231
|
-
assert.equal(found._id, id)
|
232
|
-
const deleted = await database.del(id)
|
233
|
-
assert.equal(deleted.id, id)
|
234
|
-
const e = await database
|
235
|
-
.get(id)
|
236
|
-
.then((doc) => assert.equal('should be deleted', JSON.stringify(doc)))
|
237
|
-
.catch((e) => {
|
238
|
-
if (e.message !== 'Not found') {
|
239
|
-
throw e
|
240
|
-
}
|
241
|
-
return e
|
242
|
-
})
|
243
|
-
assert.equal(e.message, 'Not found')
|
244
|
-
})
|
245
|
-
|
246
|
-
it("delete a document with validation function that doesn't allow it", async () => {
|
247
|
-
const validationDatabase = new Fireproof(new Blockstore(), [], {
|
248
|
-
validateChange: (newDoc, oldDoc, authCtx) => {
|
249
|
-
if (oldDoc.name === 'bob') {
|
250
|
-
throw new Error('no changing bob')
|
251
|
-
}
|
252
|
-
}
|
253
|
-
})
|
254
|
-
const validResp = await validationDatabase.put({
|
255
|
-
_id: '222-bob',
|
256
|
-
name: 'bob',
|
257
|
-
age: 11
|
258
|
-
})
|
259
|
-
const getResp = await validationDatabase.get(validResp.id)
|
260
|
-
assert.equal(getResp.name, 'bob')
|
261
|
-
|
262
|
-
const e = await validationDatabase
|
263
|
-
.put({
|
264
|
-
_id: '222-bob',
|
265
|
-
name: 'bob',
|
266
|
-
age: 12
|
267
|
-
})
|
268
|
-
.catch((e) => e)
|
269
|
-
assert.equal(e.message, 'no changing bob')
|
270
|
-
|
271
|
-
let prevBob = await validationDatabase.get('222-bob')
|
272
|
-
assert.equal(prevBob.name, 'bob')
|
273
|
-
assert.equal(prevBob.age, 11)
|
274
|
-
|
275
|
-
const e2 = await validationDatabase.del('222-bob').catch((e) => e)
|
276
|
-
assert.equal(e2.message, 'no changing bob')
|
277
|
-
|
278
|
-
prevBob = await validationDatabase.get('222-bob')
|
279
|
-
assert.equal(prevBob.name, 'bob')
|
280
|
-
assert.equal(prevBob.age, 11)
|
281
|
-
})
|
282
|
-
|
283
|
-
it('provides docs since tiny', async () => {
|
284
|
-
const result = await database.changesSince()
|
285
|
-
assert.equal(result.rows.length, 1)
|
286
|
-
assert.equal(result.rows[0].key, '1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
287
|
-
|
288
|
-
// console.log('result', result)
|
289
|
-
|
290
|
-
// const result2 = await database.changesSince(result.clock)
|
291
|
-
// console.log('result2', result2)
|
292
|
-
// assert.equal(result2.rows.length, 0)
|
293
|
-
|
294
|
-
const bKey = 'befbef-3c3a-4b5e-9c1c-bbbbbb'
|
295
|
-
const bvalue = {
|
296
|
-
_id: bKey,
|
297
|
-
name: 'bob',
|
298
|
-
age: 44
|
299
|
-
}
|
300
|
-
const response = await database.put(bvalue)
|
301
|
-
assert(response.id, 'should have id')
|
302
|
-
assert.equal(response.id, bKey)
|
303
|
-
|
304
|
-
const res3 = await database.changesSince()
|
305
|
-
assert.equal(res3.rows.length, 2)
|
306
|
-
|
307
|
-
const res4 = await database.changesSince(result.clock)
|
308
|
-
assert.equal(res4.rows.length, 1)
|
309
|
-
})
|
310
|
-
|
311
|
-
it('provides docs since', async () => {
|
312
|
-
const result = await database.changesSince()
|
313
|
-
assert.equal(result.rows.length, 1)
|
314
|
-
assert.equal(result.rows[0].key, '1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
315
|
-
|
316
|
-
const result2 = await database.changesSince(result.clock)
|
317
|
-
assert.equal(result2.rows.length, 0)
|
318
|
-
|
319
|
-
const bKey = 'befbef-3c3a-4b5e-9c1c-bbbbbb'
|
320
|
-
const bvalue = {
|
321
|
-
_id: bKey,
|
322
|
-
name: 'bob',
|
323
|
-
age: 44
|
324
|
-
}
|
325
|
-
const response = await database.put(bvalue)
|
326
|
-
assert(response.id, 'should have id')
|
327
|
-
assert.equal(response.id, bKey)
|
328
|
-
|
329
|
-
const res3 = await database.changesSince(result2.clock)
|
330
|
-
assert.equal(res3.rows.length, 1)
|
331
|
-
|
332
|
-
const res4 = await database.changesSince(res3.clock)
|
333
|
-
assert.equal(res4.rows.length, 0)
|
334
|
-
assert.equal(res4.clock[0], res3.clock[0])
|
335
|
-
assert.equal(res4.clock.length, res3.clock.length)
|
336
|
-
|
337
|
-
const cKey = 'cefecef-3c3a-4b5e-9c1c-bbbbbb'
|
338
|
-
const value = {
|
339
|
-
_id: cKey,
|
340
|
-
name: 'carol',
|
341
|
-
age: 44
|
342
|
-
}
|
343
|
-
const response2 = await database.put(value)
|
344
|
-
assert(response2.id, 'should have id')
|
345
|
-
assert.equal(response2.id, cKey)
|
346
|
-
|
347
|
-
const res5 = await database.changesSince(res4.clock)
|
348
|
-
|
349
|
-
assert.equal(res5.rows.length, 1)
|
350
|
-
|
351
|
-
const res6 = await database.changesSince(result2.clock)
|
352
|
-
assert.equal(res6.rows.length, 2)
|
353
|
-
|
354
|
-
const resultAll = await database.changesSince()
|
355
|
-
assert.equal(resultAll.rows.length, 3)
|
356
|
-
assert.equal(resultAll.rows[0].key, '1ef3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c')
|
357
|
-
|
358
|
-
const res7 = await database.changesSince(resultAll.clock)
|
359
|
-
assert.equal(res7.rows.length, 0)
|
360
|
-
|
361
|
-
const valueCupdate = {
|
362
|
-
_id: cKey,
|
363
|
-
name: 'carol update',
|
364
|
-
age: 45
|
365
|
-
}
|
366
|
-
const responseUpdate = await database.put(valueCupdate)
|
367
|
-
assert(responseUpdate.id)
|
368
|
-
|
369
|
-
const res8 = await database.changesSince(resultAll.clock)
|
370
|
-
assert.equal(res8.rows.length, 1)
|
371
|
-
|
372
|
-
const res9 = await database.changesSince(res8.clock)
|
373
|
-
assert.equal(res9.rows.length, 0)
|
374
|
-
})
|
375
|
-
|
376
|
-
it('docs since repeated changes', async () => {
|
377
|
-
assert.equal((await database.changesSince()).rows.length, 1)
|
378
|
-
let resp, doc, changes
|
379
|
-
for (let index = 0; index < 30; index++) {
|
380
|
-
const id = '1' + (301 - index).toString()
|
381
|
-
// console.log(`Putting id: ${id}, index: ${index}`)
|
382
|
-
resp = await database.put({ index, _id: id }).catch(e => {
|
383
|
-
assert.fail(`put failed on _id: ${id}, error: ${e.message}`)
|
384
|
-
})
|
385
|
-
assert(resp.id, `Failed to obtain resp.id for _id: ${id}`)
|
386
|
-
|
387
|
-
// console.log(`vis for update id: ${id}, index:`, index)
|
388
|
-
// for await (const line of database.vis()) {
|
389
|
-
// console.log(line)
|
390
|
-
// }
|
391
|
-
|
392
|
-
doc = await database.get(resp.id).catch(e => {
|
393
|
-
console.log('failed', e)
|
394
|
-
assert.fail(`get failed on _id: ${id}, error: ${e.message}`)
|
395
|
-
})
|
396
|
-
|
397
|
-
assert.equal(doc.index, index, `doc.index is not equal to index for _id: ${id}`)
|
398
|
-
changes = await database.changesSince().catch(async e => {
|
399
|
-
assert.fail(`changesSince failed on _id: ${id}, error: ${e.message}`)
|
400
|
-
})
|
401
|
-
changes.rows.forEach(row => {
|
402
|
-
for (const key in row) {
|
403
|
-
const value = row[key]
|
404
|
-
assert(!/^bafy/.test(value), `Unexpected "bafy..." value found at index ${index} in row ${JSON.stringify(row)}`)
|
405
|
-
}
|
406
|
-
})
|
407
|
-
|
408
|
-
database.blocks.clearCommittedCache() // clear cache to force re-reading from encrypted store
|
409
|
-
|
410
|
-
doc = await database.get(resp.id).catch(e => {
|
411
|
-
console.log('failed', e)
|
412
|
-
assert.fail(`get failed on _id: ${id}, error: ${e.message}`)
|
413
|
-
})
|
414
|
-
|
415
|
-
assert.equal(doc.index, index, `doc.index is not equal to index for _id: ${id}`)
|
416
|
-
changes = await database.changesSince().catch(async e => {
|
417
|
-
assert.fail(`changesSince failed on _id: ${id}, error: ${e.message}`)
|
418
|
-
})
|
419
|
-
changes.rows.forEach(row => {
|
420
|
-
for (const key in row) {
|
421
|
-
const value = row[key]
|
422
|
-
assert(!/^bafy/.test(value), `Unexpected "bafy..." value found at index ${index} in row ${JSON.stringify(row)}`)
|
423
|
-
}
|
424
|
-
})
|
425
|
-
|
426
|
-
// console.log('changes: ', index, changes.rows.length, JSON.stringify(changes.rows))
|
427
|
-
assert.equal(changes.rows.length, index + 2, `failed on ${index}, with ${changes.rows.length} ${id}`)
|
428
|
-
}
|
429
|
-
}).timeout(30000)
|
430
|
-
|
431
|
-
it('concurrent transactions', async () => {
|
432
|
-
assert.equal((await database.changesSince()).rows.length, 1)
|
433
|
-
const promises = []
|
434
|
-
let putYes = 0
|
435
|
-
for (let index = 0; index < 20; index++) {
|
436
|
-
const id = 'a' + (300 - index).toString()
|
437
|
-
promises.push(database.put({ index, _id: id }).catch(e => {
|
438
|
-
assert.equal(e.message, 'put failed on _id: ' + id)
|
439
|
-
}).then(r => {
|
440
|
-
if (r.id) {
|
441
|
-
putYes++
|
442
|
-
return database.get(r.id).catch(e => {
|
443
|
-
// assert.equal(e.message, 'get failed on _id: ' + r.id)
|
444
|
-
}).then(d => {
|
445
|
-
// assert.equal(d.index, index)
|
446
|
-
return r.id
|
447
|
-
})
|
448
|
-
}
|
449
|
-
}))
|
450
|
-
promises.push(database.changesSince().catch(e => {
|
451
|
-
assert.equal(e.message, 'changesSince failed')
|
452
|
-
}).then(c => {
|
453
|
-
assert(c.rows.length > 0)
|
454
|
-
return c.rows.length
|
455
|
-
}))
|
456
|
-
}
|
457
|
-
const got = await Promise.all(promises)
|
458
|
-
assert.equal(got.length, putYes * 2)
|
459
|
-
// console.log('putYes', putYes)
|
460
|
-
// await sleep(1000)
|
461
|
-
assert.equal((await database.changesSince()).rows.length, 2)
|
462
|
-
}).timeout(20000)
|
463
|
-
it('serialize database', async () => {
|
464
|
-
await database.put({ _id: 'rehy', name: 'drate' })
|
465
|
-
assert.equal((await database.changesSince()).rows.length, 2)
|
466
|
-
const serialized = JSON.parse(JSON.stringify(database))
|
467
|
-
assert.equal(serialized.name, 'helloName')
|
468
|
-
assert.equal(serialized.clock.length, 1)
|
469
|
-
})
|
470
|
-
it('clocked changes in order', async () => {
|
471
|
-
await database.put({ _id: '2' })
|
472
|
-
await database.put({ _id: 'three' })
|
473
|
-
await database.put({ _id: '4' })
|
474
|
-
const changes = await database.changesSince(resp0.clock)
|
475
|
-
assert.equal(changes.rows.length, 3)
|
476
|
-
assert.equal(changes.rows[0].key, '2')
|
477
|
-
assert.equal(changes.rows[1].key, 'three')
|
478
|
-
assert.equal(changes.rows[2].key, '4')
|
479
|
-
})
|
480
|
-
it.skip('changes in order', async () => {
|
481
|
-
await database.put({ _id: '2' })
|
482
|
-
await database.put({ _id: 'three' })
|
483
|
-
await database.put({ _id: '4' })
|
484
|
-
const changes = await database.changesSince()
|
485
|
-
assert.equal(changes.rows.length, 4)
|
486
|
-
assert.equal(changes.rows[0].key, resp0.id)
|
487
|
-
assert.equal(changes.rows[1].key, '2')
|
488
|
-
assert.equal(changes.rows[2].key, 'three')
|
489
|
-
assert.equal(changes.rows[3].key, '4')
|
490
|
-
})
|
491
|
-
})
|
package/test/fulltext.test.js
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
import { describe, it, beforeEach } from 'mocha'
|
2
|
-
import assert from 'node:assert'
|
3
|
-
import { Fireproof } from '../src/fireproof.js'
|
4
|
-
import flexsearch from 'flexsearch'
|
5
|
-
const { Index } = flexsearch
|
6
|
-
// this is an illustration of how to use the flexsearch library
|
7
|
-
|
8
|
-
let database, flexed
|
9
|
-
|
10
|
-
describe('Fulltext with flexsearch', () => {
|
11
|
-
beforeEach(async () => {
|
12
|
-
database = Fireproof.storage()
|
13
|
-
flexed = withFlexsearch(database) // this is a function that adds the flexsearch library to the database object
|
14
|
-
|
15
|
-
const messages = [
|
16
|
-
'Hello World, this is a test',
|
17
|
-
'We are testing the flexsearch library',
|
18
|
-
'When we test we test',
|
19
|
-
'Apples are red',
|
20
|
-
'Bananas are yellow',
|
21
|
-
'Oranges are orange',
|
22
|
-
'Pears are green',
|
23
|
-
'Grapes are purple',
|
24
|
-
'Strawberries are red',
|
25
|
-
'Blueberries are blue',
|
26
|
-
'Raspberries are red',
|
27
|
-
'Watermelons are green',
|
28
|
-
'Pineapples are yellow'
|
29
|
-
]
|
30
|
-
for (let i = 0, len = messages.length; i < len; i++) {
|
31
|
-
await database.put({
|
32
|
-
_id: `message-${i}`,
|
33
|
-
message: messages[i]
|
34
|
-
})
|
35
|
-
}
|
36
|
-
})
|
37
|
-
|
38
|
-
it('search the index', async () => {
|
39
|
-
const changes = await database.changesSince()
|
40
|
-
assert.equal(changes.rows.length, 13)
|
41
|
-
const results = await flexed.search('red')
|
42
|
-
assert.equal(results.length, 3)
|
43
|
-
for (let i = 0, len = results.length; i < len; i++) {
|
44
|
-
const doc = await database.get(results[i])
|
45
|
-
assert.match(doc.message, /red/)
|
46
|
-
}
|
47
|
-
})
|
48
|
-
// it('add more docs and search again', async () => {})
|
49
|
-
// it('delete some docs and search again', async () => {})
|
50
|
-
// it('update some docs and search again', async () => {})
|
51
|
-
})
|
52
|
-
|
53
|
-
function withFlexsearch (database, flexsearchOptions = {}) {
|
54
|
-
const index = new Index(flexsearchOptions)
|
55
|
-
let clock = null
|
56
|
-
const search = async (query, options) => {
|
57
|
-
const changes = await database.changesSince(clock)
|
58
|
-
clock = changes.clock
|
59
|
-
for (let i = 0; i < changes.rows.length; i++) {
|
60
|
-
const { key, value } = changes.rows[i]
|
61
|
-
await index.add(key, value.message)
|
62
|
-
}
|
63
|
-
return index.search(query, options)
|
64
|
-
}
|
65
|
-
return { search }
|
66
|
-
}
|
package/test/helpers.js
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
import crypto from 'node:crypto'
|
2
|
-
// import assert from 'node:assert'
|
3
|
-
import * as Link from 'multiformats/link'
|
4
|
-
import * as raw from 'multiformats/codecs/raw'
|
5
|
-
import { sha256 } from 'multiformats/hashes/sha2'
|
6
|
-
import { MemoryBlockstore } from './block.js'
|
7
|
-
|
8
|
-
// console.x = console.log
|
9
|
-
// console.log = function (...args) {
|
10
|
-
// // window.mutedLog = window.mutedLog || []
|
11
|
-
// // window.mutedLog.push(args)
|
12
|
-
// }
|
13
|
-
|
14
|
-
/** @param {number} size */
|
15
|
-
export async function randomCID (size) {
|
16
|
-
const hash = await sha256.digest(await randomBytes(size))
|
17
|
-
return Link.create(raw.code, hash)
|
18
|
-
}
|
19
|
-
|
20
|
-
/** @param {number} size */
|
21
|
-
export async function randomBytes (size) {
|
22
|
-
const bytes = new Uint8Array(size)
|
23
|
-
while (size) {
|
24
|
-
const chunk = new Uint8Array(Math.min(size, 65_536))
|
25
|
-
crypto.getRandomValues(chunk)
|
26
|
-
size -= bytes.length
|
27
|
-
bytes.set(chunk, size)
|
28
|
-
}
|
29
|
-
return bytes
|
30
|
-
}
|
31
|
-
|
32
|
-
export class Blockstore extends MemoryBlockstore {
|
33
|
-
|
34
|
-
}
|
35
|
-
|
36
|
-
let seq = 0
|
37
|
-
export function seqEventData (tag = '') {
|
38
|
-
return {
|
39
|
-
type: 'put',
|
40
|
-
value: `event${seq++}${tag}`
|
41
|
-
}
|
42
|
-
}
|
43
|
-
export function setSeq (n) {
|
44
|
-
seq = n
|
45
|
-
}
|
package/test/hydrator.test.js
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
import { describe, it, beforeEach } from 'mocha'
|
2
|
-
import assert from 'node:assert'
|
3
|
-
import { Fireproof } from '../src/fireproof.js'
|
4
|
-
import { DbIndex } from '../src/db-index.js'
|
5
|
-
import { Hydrator } from '../src/hydrator.js'
|
6
|
-
|
7
|
-
describe('DbIndex query', () => {
|
8
|
-
let database, index
|
9
|
-
beforeEach(async () => {
|
10
|
-
database = Fireproof.storage()
|
11
|
-
const docs = [
|
12
|
-
{ _id: 'a1s3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c', name: 'alice', age: 40 },
|
13
|
-
{ _id: 'b2s3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c', name: 'bob', age: 40 },
|
14
|
-
{ _id: 'c3s3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c', name: 'carol', age: 43 },
|
15
|
-
{ _id: 'd4s3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c', name: 'dave', age: 48 },
|
16
|
-
{ _id: 'e4s3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c', name: 'emily', age: 4 },
|
17
|
-
{ _id: 'f4s3b32a-3c3a-4b5e-9c1c-8c5c0c5c0c5c', name: 'frank', age: 7 }
|
18
|
-
]
|
19
|
-
for (const doc of docs) {
|
20
|
-
const id = doc._id
|
21
|
-
const response = await database.put(doc)
|
22
|
-
assert(response)
|
23
|
-
assert(response.id, 'should have id')
|
24
|
-
assert.equal(response.id, id)
|
25
|
-
}
|
26
|
-
index = new DbIndex(database, function (doc, map) {
|
27
|
-
map(doc.age, doc.name)
|
28
|
-
}, null, { name: 'names_by_age' })
|
29
|
-
})
|
30
|
-
it('serialize database with index', async () => {
|
31
|
-
await database.put({ _id: 'rehy', name: 'drate', age: 1 })
|
32
|
-
assert.equal((await database.changesSince()).rows.length, 7)
|
33
|
-
const result = await index.query({ range: [0, 54] })
|
34
|
-
assert.equal(result.rows[0].value, 'drate')
|
35
|
-
const serialized = database.toJSON()
|
36
|
-
// console.log('serialized', serialized)
|
37
|
-
assert.equal(serialized.name, 'global')
|
38
|
-
if (database.blocks.valet.keyId !== 'null') {
|
39
|
-
assert.equal(serialized.key.length, 64)
|
40
|
-
}
|
41
|
-
assert.equal(serialized.clock.length, 1)
|
42
|
-
assert.equal(serialized.clock[0].constructor.name, 'String')
|
43
|
-
assert.equal(serialized.indexes.length, 1)
|
44
|
-
assert.equal(serialized.indexes[0].code, `function (doc, map) {
|
45
|
-
map(doc.age, doc.name)
|
46
|
-
}`)
|
47
|
-
assert.equal(serialized.indexes[0].name, 'names_by_age')
|
48
|
-
|
49
|
-
assert.equal(serialized.indexes[0].clock.byId.constructor.name, 'String')
|
50
|
-
assert.equal(serialized.indexes[0].clock.byKey.constructor.name, 'String')
|
51
|
-
assert.equal(serialized.indexes[0].clock.db[0].constructor.name, 'String')
|
52
|
-
})
|
53
|
-
it('rehydrate database', async () => {
|
54
|
-
await database.put({ _id: 'rehy', name: 'drate', age: 1 })
|
55
|
-
assert.equal((await database.changesSince()).rows.length, 7)
|
56
|
-
const result = await index.query({ range: [0, 54] })
|
57
|
-
assert.equal(result.rows[0].value, 'drate')
|
58
|
-
|
59
|
-
const serialized = JSON.parse(JSON.stringify(database))
|
60
|
-
// console.log('serialized', JSON.stringify(serialized))
|
61
|
-
// connect it to the same blockstore for testing
|
62
|
-
const newDb = Hydrator.fromJSON(serialized, database)
|
63
|
-
assert.equal(newDb.name, 'global')
|
64
|
-
assert.equal(newDb.clock.length, 1)
|
65
|
-
assert.equal((await newDb.changesSince()).rows.length, 7)
|
66
|
-
const newIndex = [...newDb.indexes.values()][0]
|
67
|
-
assert.equal(newIndex.mapFn, `function (doc, map) {
|
68
|
-
map(doc.age, doc.name)
|
69
|
-
}`)
|
70
|
-
assert.equal(newIndex.indexById.cid, 'bafyreifuz54ugnq77fur47vwv3dwab7p3gpnf5to6hlnbhv5p4kwo7auoi')
|
71
|
-
// assert.equal(newIndex.indexById.root, null)
|
72
|
-
|
73
|
-
assert.equal(newIndex.indexByKey.cid, 'bafyreicr5rpvsxnqchcwk5rxlmdvd3fah2vexmbsp2dvr4cfdxd2q2ycgu')
|
74
|
-
// assert.equal(newIndex.indexByKey.root, null)
|
75
|
-
|
76
|
-
assert.equal(newIndex.name, 'names_by_age')
|
77
|
-
|
78
|
-
const newResult = await newIndex.query({ range: [0, 54] })
|
79
|
-
assert.equal(newResult.rows[0].value, 'drate')
|
80
|
-
})
|
81
|
-
})
|