@fireproof/core 0.3.1 → 0.3.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.
Files changed (51) hide show
  1. package/README.md +1 -1
  2. package/dist/src/blockstore.d.ts +115 -0
  3. package/dist/src/blockstore.d.ts.map +1 -0
  4. package/dist/src/clock.d.ts +98 -0
  5. package/dist/src/clock.d.ts.map +1 -0
  6. package/dist/src/crypto.d.ts +18 -0
  7. package/dist/src/crypto.d.ts.map +1 -0
  8. package/dist/src/db-index.d.ts +116 -0
  9. package/dist/src/db-index.d.ts.map +1 -0
  10. package/dist/src/fireproof.d.ts +167 -0
  11. package/dist/src/fireproof.d.ts.map +1 -0
  12. package/dist/src/hydrator.d.ts +6 -0
  13. package/dist/src/hydrator.d.ts.map +1 -0
  14. package/dist/src/index.d.ts +6 -0
  15. package/dist/src/index.d.ts.map +1 -0
  16. package/dist/src/listener.d.ts +36 -0
  17. package/dist/src/listener.d.ts.map +1 -0
  18. package/dist/src/prolly.d.ts +83 -0
  19. package/dist/src/prolly.d.ts.map +1 -0
  20. package/dist/src/sha1.d.ts +9 -0
  21. package/dist/src/sha1.d.ts.map +1 -0
  22. package/dist/src/valet.d.ts +34 -0
  23. package/dist/src/valet.d.ts.map +1 -0
  24. package/dist/tsconfig.tsbuildinfo +1 -0
  25. package/package.json +33 -3
  26. package/src/blockstore.js +24 -23
  27. package/src/clock.js +4 -3
  28. package/src/crypto.js +1 -0
  29. package/src/db-index.js +23 -18
  30. package/src/fireproof.js +31 -26
  31. package/src/hydrator.js +3 -3
  32. package/src/index.js +6 -0
  33. package/src/listener.js +9 -8
  34. package/src/prolly.js +11 -24
  35. package/src/sha1.js +2 -1
  36. package/src/valet.js +22 -20
  37. package/hooks/use-fireproof.js +0 -135
  38. package/index.js +0 -6
  39. package/scripts/keygen.js +0 -3
  40. package/test/block.js +0 -65
  41. package/test/clock.test.js +0 -694
  42. package/test/db-index.test.js +0 -261
  43. package/test/fireproof.test.js +0 -493
  44. package/test/fulltext.test.js +0 -66
  45. package/test/helpers.js +0 -45
  46. package/test/hydrator.test.js +0 -81
  47. package/test/listener.test.js +0 -102
  48. package/test/prolly.test.js +0 -190
  49. package/test/proofs.test.js +0 -53
  50. package/test/reproduce-fixture-bug.test.js +0 -65
  51. package/test/valet.test.js +0 -59
@@ -1,102 +0,0 @@
1
- import { describe, it, beforeEach } from 'mocha'
2
- import assert from 'node:assert'
3
- import Blockstore from '../src/blockstore.js'
4
- import Fireproof from '../src/fireproof.js'
5
- import Listener from '../src/listener.js'
6
- import Hydrator from '../src/hydrator.js'
7
-
8
- let database, listener, star
9
-
10
- describe('Listener', () => {
11
- beforeEach(async () => {
12
- database = new Fireproof(new Blockstore(), []) // todo: these need a cloud name aka w3name, add this after we have cloud storage of blocks
13
- const docs = [ // dave is first today
14
- { _id: 'd4s3b32a-3c3a', name: 'dave', age: 48 },
15
- { _id: 'a1s3b32a-3c3a', name: 'alice', age: 40 },
16
- { _id: 'b2s3b32a-3c3a', name: 'bob', age: 40 },
17
- { _id: 'c3s3b32a-3c3a', name: 'carol', age: 43 },
18
- { _id: 'e4s3b32a-3c3a', name: 'emily', age: 4 },
19
- { _id: 'f4s3b32a-3c3a', name: 'frank', age: 7 }
20
- ]
21
- for (const doc of docs) {
22
- const id = doc._id
23
- const response = await database.put(doc)
24
- assert(response)
25
- assert(response.id, 'should have id')
26
- assert.equal(response.id, id)
27
- }
28
- listener = new Listener(database, function (doc, emit) {
29
- if (doc.name) { emit('person') }
30
- })
31
- star = new Listener(database)
32
- })
33
- it('all listeners get the reset event', (done) => {
34
- let count = 0
35
- const check = () => {
36
- count++
37
- if (count === 3) done()
38
- }
39
- const startClock = database.clock
40
- database.put({ _id: 'k645-87tk', name: 'karl' }).then((ok) => {
41
- listener.on('person', check)
42
- listener.on('not-found', check)
43
- star.on('*', check)
44
- database.put({ _id: 'k645-87tk', name: 'karl2' }).then((ok) => {
45
- assert(ok.id)
46
- assert.notEqual(database.clock, startClock)
47
- Hydrator.zoom(database, startClock)
48
- }).catch(done)
49
- })
50
- })
51
-
52
- it('can listen to all events', (done) => {
53
- star.on('*', (key) => {
54
- assert.equal(key, 'i645-87ti')
55
- done()
56
- })
57
- database.put({ _id: 'i645-87ti', name: 'isaac' }).then((ok) => {
58
- assert(ok.id)
59
- }).catch(done)
60
- })
61
- it('shares only new events by default', (done) => {
62
- listener.on('person', (key) => {
63
- assert.equal(key, 'g645-87tg')
64
- done()
65
- })
66
- database.put({ _id: 'g645-87tg', name: 'gwen' }).then((ok) => {
67
- assert(ok.id)
68
- }).catch(done)
69
- }).timeout(200)
70
- it('shares all events if asked', async () => {
71
- let people = 0
72
- listener.on('person', (key) => {
73
- people++
74
- }, null)
75
- // this has to take longer than the database save operation
76
- // it's safe to make this number longer if it start failing
77
- await sleep(50)
78
- assert.equal(people, 6)
79
- }).timeout(2000)
80
- it('shares events since db.clock', (done) => {
81
- const clock = database.clock
82
- const afterEvent = () => {
83
- database.put({ _id: 'j645-87tj', name: 'jimmy' })
84
- }
85
- let people = 0
86
- database.put({ _id: 'h645-87th', name: 'harold' }).then(newPerson => {
87
- assert(newPerson.id)
88
- listener.on('person', (key) => {
89
- people++
90
- if (people === 1) {
91
- assert.equal(key, 'h645-87th')
92
- } else {
93
- assert.equal(key, 'j645-87tj')
94
- done()
95
- }
96
- if (people === 1) afterEvent()
97
- }, clock)
98
- })
99
- }).timeout(2000)
100
- })
101
-
102
- const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
@@ -1,190 +0,0 @@
1
- import { describe, it } from 'mocha'
2
- import assert from 'node:assert'
3
- import { advance } from '../src/clock.js'
4
-
5
- import { put, get, getAll, root, eventsSince } from '../src/prolly.js'
6
- import { Blockstore, seqEventData, setSeq } from './helpers.js'
7
-
8
- describe('Prolly', () => {
9
- it('put a value to a new clock', async () => {
10
- const blocks = new Blockstore()
11
- const alice = new TestPail(blocks, [])
12
- const key = 'key'
13
- const value = seqEventData()
14
- const { event, head } = await alice.put(key, value)
15
-
16
- assert.equal(event.value.data.type, 'put')
17
- assert.equal(event.value.data.key, key)
18
- assert.equal(event.value.data.value.toString(), value.toString())
19
- assert.equal(head.length, 1)
20
- assert.equal(head[0].toString(), event.cid.toString())
21
-
22
- const avalue = await alice.get('key')
23
- assert(avalue)
24
- assert.equal(JSON.stringify(avalue), JSON.stringify(value))
25
- })
26
-
27
- it('linear put multiple values', async () => {
28
- setSeq(-1)
29
- const blocks = new Blockstore()
30
- const alice = new TestPail(blocks, [])
31
-
32
- const key0 = 'key0'
33
- const value0 = seqEventData()
34
- const { head: oldHead } = await alice.put(key0, value0)
35
-
36
- const key1 = 'key1'
37
- const value1 = seqEventData()
38
- const result = await alice.put(key1, value1)
39
-
40
- assert.equal(result.event.value.data.type, 'put')
41
- assert.equal(result.event.value.data.key, key1)
42
- assert.equal(result.event.value.data.value.toString(), value1.toString())
43
- assert.equal(result.head.length, 1)
44
- assert.equal(result.head[0].toString(), result.event.cid.toString())
45
-
46
- const allResp = await alice.getAll()
47
- assert(allResp)
48
- assert.equal(allResp.length, 2)
49
- assert.equal(allResp[0].key, key0)
50
-
51
- // add a third value
52
- // try getSince
53
- const sinceResp = await alice.getSince(oldHead)
54
- assert.equal(sinceResp.length, 1)
55
- assert.equal(sinceResp[0].value.value, 'event0')
56
- })
57
-
58
- it('get missing', async () => {
59
- const blocks = new Blockstore()
60
- const alice = new TestPail(blocks, [])
61
- const key = 'key'
62
- const value = seqEventData('test-missing-root')
63
- await alice.put(key, value)
64
-
65
- await alice.get('missing').then((value) => {
66
- assert('false', 'should not get here')
67
- }).catch((err) => {
68
- assert.equal(err.message, 'Not found')
69
- })
70
- })
71
-
72
- it('simple parallel put multiple values', async () => {
73
- const blocks = new Blockstore()
74
- const alice = new TestPail(blocks, [])
75
- await alice.put('key0', seqEventData())
76
- const bob = new TestPail(blocks, alice.head)
77
-
78
- /** @type {Array<[string, import('../src/link').AnyLink]>} */
79
- const data = [
80
- ['key1', seqEventData()],
81
- ['key2', seqEventData()],
82
- ['key3', seqEventData()],
83
- ['key4', seqEventData()]
84
- ]
85
-
86
- const { event: aevent0 } = await alice.put(data[0][0], data[0][1])
87
- const { event: bevent0 } = await bob.put(data[1][0], data[1][1])
88
- const { event: bevent1 } = await bob.put(data[2][0], data[2][1])
89
-
90
- await alice.advance(bevent0.cid)
91
- await alice.advance(bevent1.cid)
92
- await bob.advance(aevent0.cid)
93
-
94
- const { event: aevent1 } = await alice.put(data[3][0], data[3][1])
95
-
96
- await bob.advance(aevent1.cid)
97
-
98
- assert(alice.root)
99
- assert(bob.root)
100
- assert.equal(alice.root.toString(), bob.root.toString())
101
-
102
- // get item put to bob
103
- const avalue = await alice.get(data[1][0])
104
- assert(avalue)
105
- assert.equal(avalue.toString(), data[1][1].toString())
106
-
107
- // get item put to alice
108
- const bvalue = await bob.get(data[0][0])
109
- assert(bvalue)
110
- assert.equal(bvalue.toString(), data[0][1].toString())
111
- })
112
-
113
- it.skip('passing, slow: linear put hundreds of values', async () => {
114
- const blocks = new Blockstore()
115
- const alice = new TestPail(blocks, [])
116
-
117
- for (let i = 0; i < 100; i++) {
118
- await alice.put('key' + i, seqEventData())
119
- }
120
-
121
- for (let i = 0; i < 100; i++) {
122
- const vx = await alice.get('key' + i)
123
- assert(vx)
124
- // console.log('vx', vx)
125
- // assert.equal(vx.toString(), value.toString())
126
- }
127
- console.log('blocks', Array.from(blocks.entries()).length)
128
- }).timeout(10000)
129
- })
130
-
131
- class TestPail {
132
- /**
133
- * @param {Blockstore} blocks
134
- * @param {import('../src/clock').EventLink<import('../src/crdt').EventData>[]} head
135
- */
136
- constructor (blocks, head) {
137
- this.blocks = blocks
138
- this.head = head
139
- /** @type {import('../src/shard.js').ShardLink?} */
140
- this.root = null
141
- }
142
-
143
- /**
144
- * @param {string} key
145
- * @param {import('../src/link').AnyLink} value
146
- */
147
- async put (key, value) {
148
- const result = await put(this.blocks, this.head, { key, value })
149
- if (!result) {
150
- console.log('failed', key, value)
151
- }
152
- this.blocks.putSync(result.event.cid, result.event.bytes)
153
- result.additions.forEach((a) => this.blocks.putSync(a.cid, a.bytes))
154
- this.head = result.head
155
- this.root = result.root.cid
156
- // this difference probably matters, but we need to test it
157
- // this.root = await root(this.blocks, this.head)
158
- // console.log('prolly PUT', key, value, { head: result.head, additions: result.additions.map(a => a.cid), event: result.event.cid })
159
- return result
160
- }
161
-
162
- // todo make bulk ops which should be easy at the prolly layer by passing a list of events instead of one
163
- // async bulk() {}
164
-
165
- /** @param {import('../src/clock').EventLink<import('../src/crdt').EventData>} event */
166
- async advance (event) {
167
- const { head } = await advance(this.blocks, this.head, event)
168
- this.head = head
169
- this.root = (await root(this.blocks, this.head)).node.block.cid
170
- return this.head
171
- }
172
-
173
- /** @param {string} key */
174
- async get (key) {
175
- const resp = await get(this.blocks, this.head, key)
176
- // console.log('prolly GET', key, resp)
177
- return resp.result
178
- }
179
-
180
- /** @param {string} key */
181
- async getAll () {
182
- const resp = await getAll(this.blocks, this.head)
183
- return resp.result
184
- }
185
-
186
- async getSince (since) {
187
- const resp = await eventsSince(this.blocks, this.head, since)
188
- return resp.result
189
- }
190
- }
@@ -1,53 +0,0 @@
1
- import { describe, it, beforeEach } from 'mocha'
2
- import assert from 'node:assert'
3
- import Fireproof from '../src/fireproof.js'
4
-
5
- let database, ok, doc
6
-
7
- describe('Proofs', () => {
8
- beforeEach(async () => {
9
- database = Fireproof.storage()
10
- ok = await database.put({
11
- _id: 'test1',
12
- score: 75
13
- })
14
- doc = await database.get(ok.id, { mvcc: true })
15
- })
16
-
17
- it('first put result shoud not include proof', async () => {
18
- assert(ok.proof)
19
- assert(ok.proof.data)
20
- assert(ok.proof.clock)
21
- // console.log('ok', ok)
22
- assert.equal(ok.proof.data.length, 0)
23
- assert.equal(ok.proof.clock.length, 0)
24
-
25
- // assert.equal(ok.proof.data[0], 'bafyreibsbxxd4ueujryihk6xza2ekwhzsh6pzuu5fysft5ilz7cbw6bjju')
26
- // assert.equal(ok.proof.clock[0].toString(), 'bafyreiactx5vku7zueq27i5zdrgcjnczxvepceo5yszjqb2exufwrwxg44')
27
- })
28
-
29
- it.skip('second put result shoud include proof', async () => {
30
- const ok2 = await database.put({ ...doc, winner: true })
31
- assert(ok2.proof)
32
- assert(ok2.proof.data)
33
- assert(ok2.proof.clock)
34
- // console.log('ok2', ok2)
35
- assert.equal(ok2.proof.data.length, 1)
36
- assert.equal(ok2.proof.clock.length, 1)
37
-
38
- // assert.equal(ok.proof.data[0], 'bafyreibsbxxd4ueujryihk6xza2ekwhzsh6pzuu5fysft5ilz7cbw6bjju')
39
- // assert.equal(ok.proof.clock[0].toString(), 'bafyreiactx5vku7zueq27i5zdrgcjnczxvepceo5yszjqb2exufwrwxg44')
40
- })
41
-
42
- it('get result shoud include proof', async () => {
43
- assert(doc._clock)
44
- assert(doc._proof)
45
-
46
- assert(doc._proof.data)
47
- assert(doc._proof.clock)
48
- assert.equal(doc._proof.data.length, 1)
49
- assert.equal(doc._proof.clock.length, 1)
50
- assert.equal(doc._proof.data[0], 'bafyreieilmvxq6wudu46i2ssmuyrmaszr4onzlqxzlvngrczbn7ppyvloq')
51
- assert.equal(doc._proof.clock[0].toString(), 'bafyreict4aip45uwnm4xcsn4oikh73t5n7nzdmc2u36rdbguroun2yaf2y')
52
- })
53
- })
@@ -1,65 +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
-
6
- let database
7
-
8
- describe('IPLD encode error', () => {
9
- beforeEach(async () => {
10
- database = Fireproof.storage()
11
- defineIndexes(database)
12
- })
13
-
14
- it('reproduce', async () => {
15
- await loadFixtures(database)
16
- assert(true)
17
- })
18
- })
19
-
20
- const defineIndexes = (database) => {
21
- database.allLists = new DbIndex(database, function (doc, map) {
22
- if (doc.type === 'list') map(doc.type, doc)
23
- })
24
- database.todosByList = new DbIndex(database, function (doc, map) {
25
- if (doc.type === 'todo' && doc.listId) {
26
- map([doc.listId, doc.createdAt], doc)
27
- }
28
- })
29
- return database
30
- }
31
-
32
- function mulberry32 (a) {
33
- return function () {
34
- let t = (a += 0x6d2b79f5)
35
- t = Math.imul(t ^ (t >>> 15), t | 1)
36
- t ^= t + Math.imul(t ^ (t >>> 7), t | 61)
37
- return ((t ^ (t >>> 14)) >>> 0) / 4294967296
38
- }
39
- }
40
- const rand = mulberry32(1) // determinstic fixtures
41
-
42
- async function loadFixtures (database) {
43
- const nextId = (prefix = '') => prefix + rand().toString(32).slice(2)
44
- const ok = await database.put({ title: 'Building Apps', type: 'list', _id: nextId() })
45
-
46
- await database.put({
47
- _id: nextId(),
48
- title: 'In the browser',
49
- listId: ok.id,
50
- completed: rand() > 0.75,
51
- type: 'todo',
52
- createdAt: '2'
53
- })
54
- await reproduceBug(database)
55
- }
56
-
57
- const reproduceBug = async (database) => {
58
- const id = '02pkji8'
59
- const doc = await database.get(id)
60
- // (await database.put({ completed: !completed, ...doc }))
61
- await database.put(doc)
62
- await database.todosByList.query({ range: [0, 1] })
63
-
64
- // console.log('ok', ok)
65
- }
@@ -1,59 +0,0 @@
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
- ])