@fireproof/core 0.0.1 → 0.0.3
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/README.md +148 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/block.js.html +280 -0
- package/coverage/blockstore.js.html +916 -0
- package/coverage/clock.js.html +1141 -0
- package/coverage/db-index.js.html +694 -0
- package/coverage/favicon.png +0 -0
- package/coverage/fireproof.js.html +856 -0
- package/coverage/index.html +221 -0
- package/coverage/listener.js.html +421 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/prolly.js.html +883 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/coverage/tmp/coverage-42191-1678146904346-0.json +1 -0
- package/coverage/tmp/coverage-42193-1678146903521-0.json +1 -0
- package/coverage/tmp/coverage-42196-1678146904322-0.json +1 -0
- package/coverage/tmp/coverage-42197-1678146904292-0.json +1 -0
- package/coverage/valet.js.html +589 -0
- package/package.json +7 -4
- package/src/block.js +0 -10
- package/src/blockstore.js +53 -22
- package/src/db-index.js +47 -40
- package/src/fireproof.js +97 -43
- package/src/listener.js +18 -17
- package/src/prolly.js +52 -21
- package/src/valet.js +119 -93
- package/test/clock.test.js +60 -12
- package/test/db-index.test.js +3 -0
- package/test/listener.test.js +2 -3
- package/test/valet.test.js +59 -0
package/src/prolly.js
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
advance,
|
3
|
+
EventFetcher,
|
4
|
+
EventBlock,
|
5
|
+
findCommonAncestorWithSortedEvents,
|
6
|
+
findUnknownSortedEvents
|
7
|
+
} from './clock.js'
|
2
8
|
import { create, load } from 'prolly-trees/map'
|
3
9
|
import * as codec from '@ipld/dag-cbor'
|
4
10
|
import { sha256 as hasher } from 'multiformats/hashes/sha2'
|
@@ -21,7 +27,36 @@ const makeGetBlock = (blocks) => async (address) => {
|
|
21
27
|
return createBlock({ cid, bytes, hasher, codec })
|
22
28
|
}
|
23
29
|
|
24
|
-
|
30
|
+
/**
|
31
|
+
* Creates and saves a new event.
|
32
|
+
* @param {import('./blockstore.js').Blockstore} inBlocks - A persistent blockstore.
|
33
|
+
* @param {MemoryBlockstore} mblocks - A temporary blockstore.
|
34
|
+
* @param {Function} getBlock - A function that gets a block.
|
35
|
+
* @param {Function} bigPut - A function that puts a block.
|
36
|
+
* @param {import('prolly-trees/map').Root} root - The root node.
|
37
|
+
* @param {Object<{ key: string, value: any, del: boolean }>} event - The update event.
|
38
|
+
* @param {import('./clock').EventLink<import('./crdt').EventData>} head - The head of the event chain.
|
39
|
+
* @param {Array<import('multiformats/block').Block>} additions - A array of additions.
|
40
|
+
* @param {Array<mport('multiformats/block').Block>>} removals - An array of removals.
|
41
|
+
* @returns {Promise<{
|
42
|
+
* root: import('prolly-trees/map').Root,
|
43
|
+
* additions: Map<string, import('multiformats/block').Block>,
|
44
|
+
* removals: Array<string>,
|
45
|
+
* head: import('./clock').EventLink<import('./crdt').EventData>,
|
46
|
+
* event: import('./clock').EventLink<import('./crdt').EventData>
|
47
|
+
* }>}
|
48
|
+
*/
|
49
|
+
async function createAndSaveNewEvent (
|
50
|
+
inBlocks,
|
51
|
+
mblocks,
|
52
|
+
getBlock,
|
53
|
+
bigPut,
|
54
|
+
root,
|
55
|
+
{ key, value, del },
|
56
|
+
head,
|
57
|
+
additions,
|
58
|
+
removals = []
|
59
|
+
) {
|
25
60
|
const data = {
|
26
61
|
type: 'put',
|
27
62
|
root: {
|
@@ -132,8 +167,16 @@ export async function put (inBlocks, head, event, options) {
|
|
132
167
|
bigPut(nb, additions)
|
133
168
|
}
|
134
169
|
|
135
|
-
return createAndSaveNewEvent(
|
136
|
-
|
170
|
+
return createAndSaveNewEvent(
|
171
|
+
inBlocks,
|
172
|
+
mblocks,
|
173
|
+
getBlock,
|
174
|
+
bigPut,
|
175
|
+
prollyRootBlock,
|
176
|
+
event,
|
177
|
+
head,
|
178
|
+
Array.from(additions.values()) /*, Array.from(removals.values()) */
|
179
|
+
)
|
137
180
|
}
|
138
181
|
|
139
182
|
/**
|
@@ -180,8 +223,11 @@ export async function eventsSince (blocks, head, since) {
|
|
180
223
|
throw new Error('no head')
|
181
224
|
}
|
182
225
|
const sinceHead = [...since, ...head]
|
183
|
-
const unknownSorted3 = await findUnknownSortedEvents(
|
184
|
-
|
226
|
+
const unknownSorted3 = await findUnknownSortedEvents(
|
227
|
+
blocks,
|
228
|
+
sinceHead,
|
229
|
+
await findCommonAncestorWithSortedEvents(blocks, sinceHead)
|
230
|
+
)
|
185
231
|
return unknownSorted3.map(({ value: { data } }) => data)
|
186
232
|
}
|
187
233
|
|
@@ -218,18 +264,3 @@ export async function get (blocks, head, key) {
|
|
218
264
|
const { result } = await prollyRootNode.get(key)
|
219
265
|
return result
|
220
266
|
}
|
221
|
-
|
222
|
-
/**
|
223
|
-
* @typedef {{
|
224
|
-
* type: 'put'|'del'
|
225
|
-
* key: string
|
226
|
-
* value: import('./link').AnyLink
|
227
|
-
* root: import('./shard').ShardLink
|
228
|
-
* }} EventData
|
229
|
-
*
|
230
|
-
* @typedef {{
|
231
|
-
* root: import('./shard').ShardLink
|
232
|
-
* head: import('./clock').EventLink<EventData>[]
|
233
|
-
* event: import('./clock').EventBlockView<EventData>
|
234
|
-
* } & import('./db-index').ShardDiff} Result
|
235
|
-
*/
|
package/src/valet.js
CHANGED
@@ -1,27 +1,71 @@
|
|
1
1
|
import { CarReader } from '@ipld/car'
|
2
2
|
import { CID } from 'multiformats/cid'
|
3
3
|
import { openDB } from 'idb'
|
4
|
+
import cargoQueue from 'async/cargoQueue.js'
|
4
5
|
|
5
6
|
// const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
6
|
-
let storageSupported = false
|
7
|
-
try {
|
8
|
-
|
9
|
-
} catch (e) {
|
7
|
+
// let storageSupported = false
|
8
|
+
// try {
|
9
|
+
// storageSupported = window.localStorage && true
|
10
|
+
// } catch (e) {}
|
11
|
+
// const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
10
12
|
|
11
13
|
export default class Valet {
|
12
14
|
#cars = new Map() // cars by cid
|
13
15
|
#cidToCar = new Map() // cid to car
|
14
|
-
|
15
16
|
#db = null
|
17
|
+
#uploadQueue = null
|
18
|
+
#alreadyEnqueued = new Set()
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Function installed by the database to upload car files
|
22
|
+
* @type {null|function(string, Uint8Array):Promise<void>}
|
23
|
+
*/
|
24
|
+
uploadFunction = null
|
25
|
+
|
26
|
+
constructor () {
|
27
|
+
this.#uploadQueue = cargoQueue(async (tasks, callback) => {
|
28
|
+
console.log(
|
29
|
+
'queue worker',
|
30
|
+
tasks.length,
|
31
|
+
tasks.reduce((acc, t) => acc + t.value.length, 0)
|
32
|
+
)
|
33
|
+
if (this.uploadFunction) {
|
34
|
+
// todo we can coalesce these into a single car file
|
35
|
+
for (const task of tasks) {
|
36
|
+
await this.uploadFunction(task.carCid, task.value)
|
37
|
+
}
|
38
|
+
}
|
39
|
+
callback()
|
40
|
+
})
|
41
|
+
|
42
|
+
this.#uploadQueue.drain(async () => {
|
43
|
+
return await this.withDB(async (db) => {
|
44
|
+
const carKeys = (await db.getAllFromIndex('cidToCar', 'pending')).map((c) => c.car)
|
45
|
+
for (const carKey of carKeys) {
|
46
|
+
await this.uploadFunction(carKey, await db.get('cars', carKey))
|
47
|
+
const carMeta = await db.get('cidToCar', carKey)
|
48
|
+
delete carMeta.pending
|
49
|
+
await db.put('cidToCar', carMeta)
|
50
|
+
}
|
51
|
+
})
|
52
|
+
})
|
53
|
+
}
|
16
54
|
|
17
55
|
withDB = async (dbWorkFun) => {
|
18
|
-
if (!storageSupported) return
|
56
|
+
// if (!storageSupported) return
|
19
57
|
if (!this.#db) {
|
20
|
-
this.#db = await openDB('valet',
|
21
|
-
upgrade (db) {
|
22
|
-
|
23
|
-
|
24
|
-
|
58
|
+
this.#db = await openDB('valet', 2, {
|
59
|
+
upgrade (db, oldVersion, newVersion, transaction) {
|
60
|
+
if (oldVersion < 1) {
|
61
|
+
db.createObjectStore('cars') // todo use database name
|
62
|
+
const cidToCar = db.createObjectStore('cidToCar', { keyPath: 'car' })
|
63
|
+
cidToCar.createIndex('cids', 'cids', { multiEntry: true })
|
64
|
+
}
|
65
|
+
if (oldVersion < 2) {
|
66
|
+
const cidToCar = transaction.objectStore('cidToCar')
|
67
|
+
cidToCar.createIndex('pending', 'pending')
|
68
|
+
}
|
25
69
|
}
|
26
70
|
})
|
27
71
|
}
|
@@ -29,44 +73,47 @@ export default class Valet {
|
|
29
73
|
}
|
30
74
|
|
31
75
|
/**
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
76
|
+
*
|
77
|
+
* @param {string} carCid
|
78
|
+
* @param {*} value
|
79
|
+
*/
|
36
80
|
async parkCar (carCid, value, cids) {
|
37
|
-
this.#cars.set(carCid, value)
|
38
|
-
for (const cid of cids) {
|
39
|
-
|
40
|
-
}
|
81
|
+
// this.#cars.set(carCid, value)
|
82
|
+
// for (const cid of cids) {
|
83
|
+
// this.#cidToCar.set(cid, carCid)
|
84
|
+
// }
|
41
85
|
|
42
86
|
await this.withDB(async (db) => {
|
43
87
|
const tx = db.transaction(['cars', 'cidToCar'], 'readwrite')
|
44
88
|
await tx.objectStore('cars').put(value, carCid)
|
45
|
-
await tx.objectStore('cidToCar').put({ car: carCid, cids: Array.from(cids) })
|
89
|
+
await tx.objectStore('cidToCar').put({ pending: 'y', car: carCid, cids: Array.from(cids) })
|
46
90
|
return await tx.done
|
47
91
|
})
|
48
|
-
}
|
49
92
|
|
50
|
-
|
51
|
-
|
52
|
-
|
93
|
+
// upload to web3.storage if we have credentials
|
94
|
+
if (this.uploadFunction) {
|
95
|
+
if (this.#alreadyEnqueued.has(carCid)) {
|
96
|
+
// console.log('already enqueued', carCid)
|
97
|
+
return
|
98
|
+
}
|
99
|
+
// don't await this, it will be done in the queue
|
100
|
+
// console.log('add to queue', carCid, value.length)
|
101
|
+
this.#uploadQueue.push({ carCid, value })
|
102
|
+
this.#alreadyEnqueued.add(carCid)
|
103
|
+
} else {
|
104
|
+
// console.log('no upload function', carCid, value.length, this.uploadFunction)
|
105
|
+
}
|
106
|
+
}
|
53
107
|
|
54
|
-
|
55
|
-
// const tx = db.transaction(['cars', 'cidToCar'], 'readonly')
|
56
|
-
// const carBytes = await tx.objectStore('cars').get(MEMcarCid)
|
57
|
-
// const reader = await CarReader.fromBytes(carBytes)
|
58
|
-
// const gotBlock = await reader.get(CID.parse(dataCID))
|
59
|
-
// if (gotBlock) {
|
60
|
-
// return gotBlock.bytes
|
61
|
-
// }
|
62
|
-
// })
|
108
|
+
remoteBlockFunction = null
|
63
109
|
|
110
|
+
async getBlock (dataCID) {
|
64
111
|
return await this.withDB(async (db) => {
|
65
112
|
const tx = db.transaction(['cars', 'cidToCar'], 'readonly')
|
66
113
|
const indexResp = await tx.objectStore('cidToCar').index('cids').get(dataCID)
|
67
114
|
const carCid = indexResp?.car
|
68
115
|
if (!carCid) {
|
69
|
-
|
116
|
+
throw new Error('Missing block: ' + dataCID)
|
70
117
|
}
|
71
118
|
const carBytes = await tx.objectStore('cars').get(carCid)
|
72
119
|
const reader = await CarReader.fromBytes(carBytes)
|
@@ -76,67 +123,46 @@ export default class Valet {
|
|
76
123
|
}
|
77
124
|
})
|
78
125
|
}
|
79
|
-
|
80
|
-
/**
|
81
|
-
* Internal function to load blocks from persistent storage.
|
82
|
-
* Currently it just searches all the cars for the block, but in the future
|
83
|
-
* we need to index the block CIDs to the cars, and reference that to find the block.
|
84
|
-
* This index will also allow us to use accelerator links for the gateway when needed.
|
85
|
-
* It can itself be a prolly tree...
|
86
|
-
* @param {string} cid
|
87
|
-
* @returns {Promise<Uint8Array|undefined>}
|
88
|
-
*/
|
89
|
-
#valetGet = async (cid) => {
|
90
|
-
const carCid = this.#cidToCar.get(cid)
|
91
|
-
if (carCid) {
|
92
|
-
const carBytes = this.#cars.get(carCid)
|
93
|
-
const reader = await CarReader.fromBytes(carBytes)
|
94
|
-
const gotBlock = await reader.get(CID.parse(cid))
|
95
|
-
if (gotBlock) {
|
96
|
-
return gotBlock.bytes
|
97
|
-
}
|
98
|
-
}
|
99
|
-
}
|
100
126
|
}
|
101
127
|
|
102
|
-
export class MemoryValet {
|
103
|
-
|
104
|
-
|
128
|
+
// export class MemoryValet {
|
129
|
+
// #cars = new Map() // cars by cid
|
130
|
+
// #cidToCar = new Map() // cid to car
|
105
131
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
132
|
+
// /**
|
133
|
+
// *
|
134
|
+
// * @param {string} carCid
|
135
|
+
// * @param {*} value
|
136
|
+
// */
|
137
|
+
// async parkCar (carCid, value, cids) {
|
138
|
+
// this.#cars.set(carCid, value)
|
139
|
+
// for (const cid of cids) {
|
140
|
+
// this.#cidToCar.set(cid, carCid)
|
141
|
+
// }
|
142
|
+
// }
|
117
143
|
|
118
|
-
|
119
|
-
|
120
|
-
|
144
|
+
// async getBlock (dataCID) {
|
145
|
+
// return await this.#valetGet(dataCID)
|
146
|
+
// }
|
121
147
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
}
|
148
|
+
// /**
|
149
|
+
// * Internal function to load blocks from persistent storage.
|
150
|
+
// * Currently it just searches all the cars for the block, but in the future
|
151
|
+
// * we need to index the block CIDs to the cars, and reference that to find the block.
|
152
|
+
// * This index will also allow us to use accelerator links for the gateway when needed.
|
153
|
+
// * It can itself be a prolly tree...
|
154
|
+
// * @param {string} cid
|
155
|
+
// * @returns {Promise<Uint8Array|undefined>}
|
156
|
+
// */
|
157
|
+
// #valetGet = async (cid) => {
|
158
|
+
// const carCid = this.#cidToCar.get(cid)
|
159
|
+
// if (carCid) {
|
160
|
+
// const carBytes = this.#cars.get(carCid)
|
161
|
+
// const reader = await CarReader.fromBytes(carBytes)
|
162
|
+
// const gotBlock = await reader.get(CID.parse(cid))
|
163
|
+
// if (gotBlock) {
|
164
|
+
// return gotBlock.bytes
|
165
|
+
// }
|
166
|
+
// }
|
167
|
+
// }
|
168
|
+
// }
|
package/test/clock.test.js
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
-
|
1
|
+
/* global describe, it */
|
2
|
+
// import { describe, it } from 'mocha'
|
2
3
|
import assert from 'node:assert'
|
3
|
-
import {
|
4
|
+
import {
|
5
|
+
advance,
|
6
|
+
EventBlock,
|
7
|
+
findCommonAncestorWithSortedEvents,
|
8
|
+
findUnknownSortedEvents,
|
9
|
+
decodeEventBlock,
|
10
|
+
findEventsToSync
|
11
|
+
} from '../src/clock.js'
|
4
12
|
// import { vis } from '../src/clock.js'
|
5
13
|
import { Blockstore, seqEventData, setSeq } from './helpers.js'
|
6
14
|
|
@@ -34,7 +42,11 @@ describe('Clock', () => {
|
|
34
42
|
assert.equal(head[0].toString(), event.cid.toString())
|
35
43
|
|
36
44
|
const sinceHead = head
|
37
|
-
const toSync = await findUnknownSortedEvents(
|
45
|
+
const toSync = await findUnknownSortedEvents(
|
46
|
+
blocks,
|
47
|
+
sinceHead,
|
48
|
+
await findCommonAncestorWithSortedEvents(blocks, sinceHead)
|
49
|
+
)
|
38
50
|
assert.equal(toSync.length, 0)
|
39
51
|
})
|
40
52
|
|
@@ -418,7 +430,11 @@ describe('Clock', () => {
|
|
418
430
|
assert.equal(head[1].toString(), event1.cid.toString())
|
419
431
|
|
420
432
|
let sinceHead = head1
|
421
|
-
let toSync = await findUnknownSortedEvents(
|
433
|
+
let toSync = await findUnknownSortedEvents(
|
434
|
+
blocks,
|
435
|
+
sinceHead,
|
436
|
+
await findCommonAncestorWithSortedEvents(blocks, sinceHead)
|
437
|
+
)
|
422
438
|
// assert.equal(toSync.length, 1) // 0
|
423
439
|
// assert.equal(toSync[0].cid.toString(), event0.cid.toString())
|
424
440
|
|
@@ -430,12 +446,20 @@ describe('Clock', () => {
|
|
430
446
|
assert.equal(head.length, 1)
|
431
447
|
|
432
448
|
sinceHead = head2
|
433
|
-
toSync = await findUnknownSortedEvents(
|
449
|
+
toSync = await findUnknownSortedEvents(
|
450
|
+
blocks,
|
451
|
+
sinceHead,
|
452
|
+
await findCommonAncestorWithSortedEvents(blocks, sinceHead)
|
453
|
+
)
|
434
454
|
assert.equal(toSync.length, 0)
|
435
455
|
|
436
456
|
// todo do these since heads make sense?
|
437
457
|
sinceHead = [...head0, ...head2]
|
438
|
-
toSync = await findUnknownSortedEvents(
|
458
|
+
toSync = await findUnknownSortedEvents(
|
459
|
+
blocks,
|
460
|
+
sinceHead,
|
461
|
+
await findCommonAncestorWithSortedEvents(blocks, sinceHead)
|
462
|
+
)
|
439
463
|
// console.log('need', toSync.map(b => b.value.data))
|
440
464
|
// assert.equal(toSync.length, 2) // 0
|
441
465
|
// assert.equal(toSync[0].cid.toString(), event1.cid.toString())
|
@@ -668,7 +692,11 @@ describe('Clock', () => {
|
|
668
692
|
const roothead = head
|
669
693
|
// db root
|
670
694
|
let sinceHead = [...roothead]
|
671
|
-
let toSync = await findUnknownSortedEvents(
|
695
|
+
let toSync = await findUnknownSortedEvents(
|
696
|
+
blocks,
|
697
|
+
sinceHead,
|
698
|
+
await findCommonAncestorWithSortedEvents(blocks, sinceHead)
|
699
|
+
)
|
672
700
|
assert.equal(toSync.length, 0) // we use all docs for first query in Fireproof
|
673
701
|
|
674
702
|
// create bob
|
@@ -680,11 +708,19 @@ describe('Clock', () => {
|
|
680
708
|
|
681
709
|
const event0head = head
|
682
710
|
sinceHead = event0head
|
683
|
-
toSync = await findUnknownSortedEvents(
|
711
|
+
toSync = await findUnknownSortedEvents(
|
712
|
+
blocks,
|
713
|
+
sinceHead,
|
714
|
+
await findCommonAncestorWithSortedEvents(blocks, sinceHead)
|
715
|
+
)
|
684
716
|
assert.equal(toSync.length, 0)
|
685
717
|
|
686
718
|
sinceHead = [...roothead, ...event0head]
|
687
|
-
toSync = await findUnknownSortedEvents(
|
719
|
+
toSync = await findUnknownSortedEvents(
|
720
|
+
blocks,
|
721
|
+
sinceHead,
|
722
|
+
await findCommonAncestorWithSortedEvents(blocks, sinceHead)
|
723
|
+
)
|
688
724
|
assert.equal(toSync.length, 1)
|
689
725
|
|
690
726
|
// create carol
|
@@ -705,7 +741,11 @@ describe('Clock', () => {
|
|
705
741
|
// for await (const line of vis(blocks, head)) console.log(line)
|
706
742
|
|
707
743
|
sinceHead = [...event1head, ...roothead]
|
708
|
-
toSync = await findUnknownSortedEvents(
|
744
|
+
toSync = await findUnknownSortedEvents(
|
745
|
+
blocks,
|
746
|
+
sinceHead,
|
747
|
+
await findCommonAncestorWithSortedEvents(blocks, sinceHead)
|
748
|
+
)
|
709
749
|
|
710
750
|
assert.equal(toSync.length, 2)
|
711
751
|
|
@@ -715,11 +755,19 @@ describe('Clock', () => {
|
|
715
755
|
const event2head = head
|
716
756
|
|
717
757
|
sinceHead = [...event2head, ...event0head]
|
718
|
-
toSync = await findUnknownSortedEvents(
|
758
|
+
toSync = await findUnknownSortedEvents(
|
759
|
+
blocks,
|
760
|
+
sinceHead,
|
761
|
+
await findCommonAncestorWithSortedEvents(blocks, sinceHead)
|
762
|
+
)
|
719
763
|
assert.equal(toSync.length, 2)
|
720
764
|
|
721
765
|
sinceHead = [...event2head, ...event1head]
|
722
|
-
toSync = await findUnknownSortedEvents(
|
766
|
+
toSync = await findUnknownSortedEvents(
|
767
|
+
blocks,
|
768
|
+
sinceHead,
|
769
|
+
await findCommonAncestorWithSortedEvents(blocks, sinceHead)
|
770
|
+
)
|
723
771
|
assert.equal(toSync.length, 1)
|
724
772
|
})
|
725
773
|
})
|
package/test/db-index.test.js
CHANGED
@@ -207,8 +207,11 @@ describe('Index query with bad index definition', () => {
|
|
207
207
|
})
|
208
208
|
})
|
209
209
|
it('query index range', async () => {
|
210
|
+
const oldErrFn = console.error
|
211
|
+
console.error = () => {}
|
210
212
|
await index.query({ range: [41, 44] }).catch((e) => {
|
211
213
|
assert(/missingField/.test(e.message))
|
214
|
+
console.error = oldErrFn
|
212
215
|
})
|
213
216
|
})
|
214
217
|
})
|
package/test/listener.test.js
CHANGED
@@ -32,7 +32,6 @@ describe('Listener', () => {
|
|
32
32
|
it('all listeners get the reset event', (done) => {
|
33
33
|
let count = 0
|
34
34
|
const check = () => {
|
35
|
-
console.log('increment check count')
|
36
35
|
count++
|
37
36
|
if (count === 3) done()
|
38
37
|
}
|
@@ -76,7 +75,7 @@ describe('Listener', () => {
|
|
76
75
|
// it's safe to make this number longer if it start failing
|
77
76
|
await sleep(50)
|
78
77
|
assert.equal(people, 6)
|
79
|
-
}).timeout(
|
78
|
+
}).timeout(2000)
|
80
79
|
it('shares events since db.clock', (done) => {
|
81
80
|
const clock = database.clock
|
82
81
|
const afterEvent = () => {
|
@@ -96,7 +95,7 @@ describe('Listener', () => {
|
|
96
95
|
if (people === 1) afterEvent()
|
97
96
|
}, clock)
|
98
97
|
})
|
99
|
-
}).timeout(
|
98
|
+
}).timeout(2000)
|
100
99
|
})
|
101
100
|
|
102
101
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import { before, describe, it } from 'mocha'
|
2
|
+
import assert from 'node:assert'
|
3
|
+
import Valet from '../src/valet.js'
|
4
|
+
|
5
|
+
describe('new Valet', () => {
|
6
|
+
let val
|
7
|
+
const calls = []
|
8
|
+
|
9
|
+
before(async () => {
|
10
|
+
val = new Valet()
|
11
|
+
val.uploadFunction = async (carCid, value) => {
|
12
|
+
calls.push({ carCid, value })
|
13
|
+
}
|
14
|
+
})
|
15
|
+
it('has default attributes', async () => {
|
16
|
+
assert(val.getBlock)
|
17
|
+
assert(val.parkCar)
|
18
|
+
})
|
19
|
+
it('can park a car and serve the blocks', async () => {
|
20
|
+
await val
|
21
|
+
.parkCar('carCid', carBytes, [
|
22
|
+
'bafyreifwghknmzabvgearl72url3v5leqqhtafvybcsrceelc3psqkocoi',
|
23
|
+
'bafyreieth2ckopwivda5mf6vu76xwqvox3q5wsaxgbmxy2dgrd4hfuzmma'
|
24
|
+
])
|
25
|
+
.then((car) => {
|
26
|
+
assert('car parked')
|
27
|
+
val.getBlock('bafyreieth2ckopwivda5mf6vu76xwqvox3q5wsaxgbmxy2dgrd4hfuzmma').then((block) => {
|
28
|
+
assert.equal(block.length, carBytes.length)
|
29
|
+
})
|
30
|
+
})
|
31
|
+
})
|
32
|
+
it('calls the upload function', () => {
|
33
|
+
assert.equal(calls.length, 1)
|
34
|
+
assert.equal(calls[0].carCid, 'carCid')
|
35
|
+
})
|
36
|
+
})
|
37
|
+
|
38
|
+
const carBytes = new Uint8Array([
|
39
|
+
58, 162, 101, 114, 111, 111, 116, 115, 129, 216, 42, 88, 37, 0, 1, 113, 18, 32, 147, 62, 132, 167, 62, 200, 168, 193,
|
40
|
+
214, 23, 213, 167, 253, 123, 66, 174, 190, 225, 219, 72, 23, 48, 89, 124, 104, 102, 136, 248, 114, 211, 44, 96, 103,
|
41
|
+
118, 101, 114, 115, 105, 111, 110, 1, 108, 1, 113, 18, 32, 182, 49, 212, 214, 100, 1, 169, 136, 8, 175, 250, 164, 87,
|
42
|
+
186, 245, 100, 132, 15, 48, 22, 184, 8, 165, 17, 16, 139, 22, 223, 40, 41, 194, 114, 162, 100, 108, 101, 97, 102, 129,
|
43
|
+
130, 120, 36, 49, 101, 102, 51, 98, 51, 50, 97, 45, 51, 99, 51, 97, 45, 52, 98, 53, 101, 45, 57, 99, 49, 99, 45, 56,
|
44
|
+
99, 53, 99, 48, 99, 53, 99, 48, 99, 53, 99, 162, 99, 97, 103, 101, 24, 42, 100, 110, 97, 109, 101, 101, 97, 108, 105,
|
45
|
+
99, 101, 102, 99, 108, 111, 115, 101, 100, 244, 208, 2, 1, 113, 18, 32, 147, 62, 132, 167, 62, 200, 168, 193, 214, 23,
|
46
|
+
213, 167, 253, 123, 66, 174, 190, 225, 219, 72, 23, 48, 89, 124, 104, 102, 136, 248, 114, 211, 44, 96, 162, 100, 100,
|
47
|
+
97, 116, 97, 164, 99, 107, 101, 121, 120, 36, 49, 101, 102, 51, 98, 51, 50, 97, 45, 51, 99, 51, 97, 45, 52, 98, 53,
|
48
|
+
101, 45, 57, 99, 49, 99, 45, 56, 99, 53, 99, 48, 99, 53, 99, 48, 99, 53, 99, 100, 114, 111, 111, 116, 163, 99, 99,
|
49
|
+
105, 100, 216, 42, 88, 37, 0, 1, 113, 18, 32, 182, 49, 212, 214, 100, 1, 169, 136, 8, 175, 250, 164, 87, 186, 245,
|
50
|
+
100, 132, 15, 48, 22, 184, 8, 165, 17, 16, 139, 22, 223, 40, 41, 194, 114, 101, 98, 121, 116, 101, 115, 88, 72, 162,
|
51
|
+
100, 108, 101, 97, 102, 129, 130, 120, 36, 49, 101, 102, 51, 98, 51, 50, 97, 45, 51, 99, 51, 97, 45, 52, 98, 53, 101,
|
52
|
+
45, 57, 99, 49, 99, 45, 56, 99, 53, 99, 48, 99, 53, 99, 48, 99, 53, 99, 162, 99, 97, 103, 101, 24, 42, 100, 110, 97,
|
53
|
+
109, 101, 101, 97, 108, 105, 99, 101, 102, 99, 108, 111, 115, 101, 100, 244, 101, 118, 97, 108, 117, 101, 162, 100,
|
54
|
+
108, 101, 97, 102, 129, 130, 120, 36, 49, 101, 102, 51, 98, 51, 50, 97, 45, 51, 99, 51, 97, 45, 52, 98, 53, 101, 45,
|
55
|
+
57, 99, 49, 99, 45, 56, 99, 53, 99, 48, 99, 53, 99, 48, 99, 53, 99, 162, 99, 97, 103, 101, 24, 42, 100, 110, 97, 109,
|
56
|
+
101, 101, 97, 108, 105, 99, 101, 102, 99, 108, 111, 115, 101, 100, 244, 100, 116, 121, 112, 101, 99, 112, 117, 116,
|
57
|
+
101, 118, 97, 108, 117, 101, 162, 99, 97, 103, 101, 24, 42, 100, 110, 97, 109, 101, 101, 97, 108, 105, 99, 101, 103,
|
58
|
+
112, 97, 114, 101, 110, 116, 115, 128
|
59
|
+
])
|