@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
package/src/fireproof.js CHANGED
@@ -1,24 +1,28 @@
1
+ // @ts-nocheck
1
2
  import { randomBytes } from 'crypto'
2
3
  import { visMerkleClock, visMerkleTree, vis, put, get, getAll, eventsSince } from './prolly.js'
3
- import TransactionBlockstore, { doTransaction } from './blockstore.js'
4
+ import { TransactionBlockstore, doTransaction } from './blockstore.js'
4
5
  import charwise from 'charwise'
6
+ // import { CID } from 'multiformats/dist/types/src/cid.js'
5
7
 
6
8
  // const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
7
9
 
10
+ // class Proof {}
11
+
8
12
  /**
9
13
  * @class Fireproof
10
14
  * @classdesc Fireproof stores data in IndexedDB and provides a Merkle clock.
11
15
  * This is the main class for saving and loading JSON and other documents with the database. You can find additional examples and
12
16
  * usage guides in the repository README.
13
17
  *
14
- * @param {Blockstore} blocks - The block storage instance to use documents and indexes
18
+ * @param {import('./blockstore.js').TransactionBlockstore} blocks - The block storage instance to use documents and indexes
15
19
  * @param {CID[]} clock - The Merkle clock head to use for the Fireproof instance.
16
20
  * @param {object} [config] - Optional configuration options for the Fireproof instance.
17
21
  * @param {object} [authCtx] - Optional authorization context object to use for any authentication checks.
18
22
  *
19
23
  */
20
- export default class Fireproof {
21
- #listeners = new Set()
24
+ export class Fireproof {
25
+ listeners = new Set()
22
26
 
23
27
  /**
24
28
  * @function storage
@@ -82,12 +86,12 @@ export default class Fireproof {
82
86
  * @instance
83
87
  */
84
88
  async notifyReset () {
85
- await this.#notifyListeners({ _reset: true, _clock: this.clockToJSON() })
89
+ await this.notifyListeners({ _reset: true, _clock: this.clockToJSON() })
86
90
  }
87
91
 
88
92
  // used be indexes etc to notify database listeners of new availability
89
93
  async notifyExternal (source = 'unknown') {
90
- await this.#notifyListeners({ _external: source, _clock: this.clockToJSON() })
94
+ await this.notifyListeners({ _external: source, _clock: this.clockToJSON() })
91
95
  }
92
96
 
93
97
  /**
@@ -147,7 +151,7 @@ export default class Fireproof {
147
151
  * @memberof Fireproof
148
152
  * @instance
149
153
  */
150
- async #runValidation (doc) {
154
+ async runValidation (doc) {
151
155
  if (this.config && this.config.validateChange) {
152
156
  const oldDoc = await this.get(doc._id)
153
157
  .then((doc) => doc)
@@ -161,7 +165,7 @@ export default class Fireproof {
161
165
  *
162
166
  * @param {string} key - the ID of the document to retrieve
163
167
  * @param {Object} [opts] - options
164
- * @returns {Object<{_id: string, ...doc: Object}>} - the document with the specified ID
168
+ * @returns {Promise<{_id: string}>} - the document with the specified ID
165
169
  * @memberof Fireproof
166
170
  * @instance
167
171
  */
@@ -190,21 +194,22 @@ export default class Fireproof {
190
194
  *
191
195
  * @param {Object} doc - the document to be added
192
196
  * @param {string} doc._id - the document ID. If not provided, a random ID will be generated.
193
- * @param {Object} doc.* - the document data to be added
194
- * @returns {Object<{ id: string, clock: CID[] }>} - The result of adding the document to the database
197
+ * @param {CID[]} doc._clock - the document ID. If not provided, a random ID will be generated.
198
+ * @param {Proof} doc._proof - CIDs referenced by the update
199
+ * @returns {Promise<{ id: string, clock: CID[] }>} - The result of adding the document to the database
195
200
  * @memberof Fireproof
196
201
  * @instance
197
202
  */
198
203
  async put ({ _id, _proof, ...doc }) {
199
204
  const id = _id || 'f' + Math.random().toString(36).slice(2)
200
- await this.#runValidation({ _id: id, ...doc })
201
- return await this.#putToProllyTree({ key: id, value: doc }, doc._clock)
205
+ await this.runValidation({ _id: id, ...doc })
206
+ return await this.putToProllyTree({ key: id, value: doc }, doc._clock)
202
207
  }
203
208
 
204
209
  /**
205
210
  * Deletes a document from the database
206
- * @param {string} id - the document ID
207
- * @returns {Object<{ id: string, clock: CID[] }>} - The result of deleting the document from the database
211
+ * @param {string | any} docOrId - the document ID
212
+ * @returns {Promise<{ id: string, clock: CID[] }>} - The result of deleting the document from the database
208
213
  * @memberof Fireproof
209
214
  * @instance
210
215
  */
@@ -217,19 +222,19 @@ export default class Fireproof {
217
222
  } else {
218
223
  id = docOrId
219
224
  }
220
- await this.#runValidation({ _id: id, _deleted: true })
221
- return await this.#putToProllyTree({ key: id, del: true }, clock) // not working at prolly tree layer?
225
+ await this.runValidation({ _id: id, _deleted: true })
226
+ return await this.putToProllyTree({ key: id, del: true }, clock) // not working at prolly tree layer?
222
227
  // this tombstone is temporary until we can get the prolly tree to delete
223
- // return await this.#putToProllyTree({ key: id, value: null }, clock)
228
+ // return await this.putToProllyTree({ key: id, value: null }, clock)
224
229
  }
225
230
 
226
231
  /**
227
232
  * Updates the underlying storage with the specified event.
228
233
  * @private
229
- * @param {Object<{key : string, value: any}>} event - the event to add
230
- * @returns {Object<{ id: string, clock: CID[] }>} - The result of adding the event to storage
234
+ * @param {{del?: true, key : string, value?: any}} decodedEvent - the event to add
235
+ * @returns {Promise<{ proof:{}, id: string, clock: CID[] }>} - The result of adding the event to storage
231
236
  */
232
- async #putToProllyTree (decodedEvent, clock = null) {
237
+ async putToProllyTree (decodedEvent, clock = null) {
233
238
  const event = encodeEvent(decodedEvent)
234
239
  if (clock && JSON.stringify(clock) !== JSON.stringify(this.clockToJSON())) {
235
240
  // we need to check and see what version of the document exists at the clock specified
@@ -241,7 +246,7 @@ export default class Fireproof {
241
246
  }
242
247
  }
243
248
  const result = await doTransaction(
244
- '#putToProllyTree',
249
+ 'putToProllyTree',
245
250
  this.blocks,
246
251
  async (blocks) => await put(blocks, this.clock, event)
247
252
  )
@@ -251,7 +256,7 @@ export default class Fireproof {
251
256
  }
252
257
  // console.log('new clock head', this.instanceId, result.head.toString())
253
258
  this.clock = result.head // do we want to do this as a finally block
254
- await this.#notifyListeners([decodedEvent]) // this type is odd
259
+ await this.notifyListeners([decodedEvent]) // this type is odd
255
260
  return {
256
261
  id: decodedEvent.key,
257
262
  clock: this.clockToJSON(),
@@ -290,15 +295,15 @@ export default class Fireproof {
290
295
  * @memberof Fireproof
291
296
  */
292
297
  registerListener (listener) {
293
- this.#listeners.add(listener)
298
+ this.listeners.add(listener)
294
299
  return () => {
295
- this.#listeners.delete(listener)
300
+ this.listeners.delete(listener)
296
301
  }
297
302
  }
298
303
 
299
- async #notifyListeners (changes) {
304
+ async notifyListeners (changes) {
300
305
  // await sleep(10)
301
- for (const listener of this.#listeners) {
306
+ for (const listener of this.listeners) {
302
307
  await listener(changes)
303
308
  }
304
309
  }
package/src/hydrator.js CHANGED
@@ -1,10 +1,10 @@
1
- import DbIndex from './db-index.js'
2
- import Fireproof from './fireproof.js'
1
+ import { DbIndex } from './db-index.js'
2
+ import { Fireproof } from './fireproof.js'
3
3
  import { CID } from 'multiformats'
4
4
 
5
5
  const parseCID = cid => typeof cid === 'string' ? CID.parse(cid) : cid
6
6
 
7
- export default class Hydrator {
7
+ export class Hydrator {
8
8
  static fromJSON (json, database) {
9
9
  database.hydrate({ clock: json.clock.map(c => parseCID(c)), name: json.name, key: json.key })
10
10
  if (json.indexes) {
package/src/index.js ADDED
@@ -0,0 +1,6 @@
1
+ import { Fireproof } from './fireproof'
2
+ import { DbIndex as Index } from './db-index'
3
+ import { Listener } from './listener'
4
+ import { Hydrator } from './hydrator'
5
+
6
+ export { Fireproof, Index, Listener, Hydrator }
package/src/listener.js CHANGED
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  /**
2
3
  * A Fireproof database Listener allows you to react to events in the database.
3
4
  *
@@ -9,9 +10,9 @@
9
10
  */
10
11
  // import { ChangeEvent } from './db-index'
11
12
 
12
- export default class Listener {
13
- #subcribers = new Map()
14
- #doStopListening = null
13
+ export class Listener {
14
+ subcribers = new Map()
15
+ doStopListening = null
15
16
 
16
17
  constructor (database, routingFn) {
17
18
  /** routingFn
@@ -19,7 +20,7 @@ export default class Listener {
19
20
  * @type {Fireproof}
20
21
  */
21
22
  this.database = database
22
- this.#doStopListening = database.registerListener(changes => this.#onChanges(changes))
23
+ this.doStopListening = database.registerListener(changes => this.onChanges(changes))
23
24
  /**
24
25
  * The map function to apply to each entry in the database.
25
26
  * @type {Function}
@@ -41,7 +42,7 @@ export default class Listener {
41
42
  * @instance
42
43
  */
43
44
  on (topic, subscriber, since) {
44
- const listOfTopicSubscribers = getTopicList(this.#subcribers, topic)
45
+ const listOfTopicSubscribers = getTopicList(this.subcribers, topic)
45
46
  listOfTopicSubscribers.push(subscriber)
46
47
  if (typeof since !== 'undefined') {
47
48
  this.database.changesSince(since).then(({ rows: changes }) => {
@@ -55,16 +56,16 @@ export default class Listener {
55
56
  }
56
57
  }
57
58
 
58
- #onChanges (changes) {
59
+ onChanges (changes) {
59
60
  if (Array.isArray(changes)) {
60
61
  const seenTopics = topicsForChanges(changes, this.routingFn)
61
62
  for (const [topic, keys] of seenTopics) {
62
- const listOfTopicSubscribers = getTopicList(this.#subcribers, topic)
63
+ const listOfTopicSubscribers = getTopicList(this.subcribers, topic)
63
64
  listOfTopicSubscribers.forEach(subscriber => keys.forEach(key => subscriber(key)))
64
65
  }
65
66
  } else {
66
67
  // non-arrays go to all subscribers
67
- for (const [, listOfTopicSubscribers] of this.#subcribers) {
68
+ for (const [, listOfTopicSubscribers] of this.subcribers) {
68
69
  listOfTopicSubscribers.forEach(subscriber => subscriber(changes))
69
70
  }
70
71
  }
package/src/prolly.js CHANGED
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import {
2
3
  advance,
3
4
  EventFetcher,
@@ -37,23 +38,9 @@ export const makeGetBlock = (blocks) => {
37
38
  }
38
39
 
39
40
  /**
40
- * Creates and saves a new event.
41
- * @param {import('./blockstore.js').Blockstore} inBlocks - A persistent blockstore.
42
- * @param {MemoryBlockstore} mblocks - A temporary blockstore.
43
- * @param {Function} getBlock - A function that gets a block.
44
- * @param {Function} bigPut - A function that puts a block.
45
- * @param {import('prolly-trees/map').Root} root - The root node.
46
- * @param {Object<{ key: string, value: any, del: boolean }>} event - The update event.
47
- * @param {CID[]} head - The head of the event chain.
48
- * @param {Array<import('multiformats/block').Block>} additions - A array of additions.
49
- * @param {Array<mport('multiformats/block').Block>>} removals - An array of removals.
50
- * @returns {Promise<{
51
- * root: import('prolly-trees/map').Root,
52
- * additions: Map<string, import('multiformats/block').Block>,
53
- * removals: Array<string>,
54
- * head: CID[],
55
- * event: CID[]
56
- * }>}
41
+ *
42
+ * @param {*} param0
43
+ * @returns
57
44
  */
58
45
  async function createAndSaveNewEvent ({
59
46
  inBlocks,
@@ -198,7 +185,7 @@ const doProllyBulk = async (inBlocks, head, event) => {
198
185
  /**
199
186
  * Put a value (a CID) for the given key. If the key exists it's value is overwritten.
200
187
  *
201
- * @param {import('../test/block.js').BlockFetcher} blocks Bucket block storage.
188
+ * @param {import('./blockstore.js').BlockFetcher} blocks Bucket block storage.
202
189
  * @param {import('./clock').EventLink<EventData>[]} head Merkle clock head.
203
190
  * @param {string} key The key of the value to put.
204
191
  * @param {CID} value The value to put.
@@ -250,7 +237,7 @@ export async function put (inBlocks, head, event, options) {
250
237
  /**
251
238
  * Determine the effective prolly root given the current merkle clock head.
252
239
  *
253
- * @param {import('../test/block.js').BlockFetcher} blocks Bucket block storage.
240
+ * @param {import('./blockstore.js').BlockFetcher} blocks Bucket block storage.
254
241
  * @param {import('./clock').EventLink<EventData>[]} head Merkle clock head.
255
242
  */
256
243
  export async function root (inBlocks, head) {
@@ -270,10 +257,10 @@ export async function root (inBlocks, head) {
270
257
 
271
258
  /**
272
259
  * Get the list of events not known by the `since` event
273
- * @param {import('../test/block.js').BlockFetcher} blocks Bucket block storage.
260
+ * @param {import('./blockstore.js').BlockFetcher} blocks Bucket block storage.
274
261
  * @param {import('./clock').EventLink<EventData>[]} head Merkle clock head.
275
262
  * @param {import('./clock').EventLink<EventData>} since Event to compare against.
276
- * @returns {Promise<import('./clock').EventLink<EventData>[]>}
263
+ * @returns {Promise<{clockCIDs: CIDCounter, result: EventData[]}>}
277
264
  */
278
265
  export async function eventsSince (blocks, head, since) {
279
266
  if (!head.length) {
@@ -286,10 +273,10 @@ export async function eventsSince (blocks, head, since) {
286
273
 
287
274
  /**
288
275
  *
289
- * @param {import('../test/block.js').BlockFetcher} blocks Bucket block storage.
276
+ * @param {import('./blockstore.js').BlockFetcher} blocks Bucket block storage.
290
277
  * @param {import('./clock').EventLink<EventData>[]} head Merkle clock head.
291
278
  *
292
- * @returns {Promise<import('./prolly').Entry[]>}
279
+ * @returns {Promise<{clockCIDs: CIDCounter, result: EventData[]}>}
293
280
  *
294
281
  */
295
282
  export async function getAll (blocks, head) {
@@ -307,7 +294,7 @@ export async function getAll (blocks, head) {
307
294
  }
308
295
 
309
296
  /**
310
- * @param {import('../test/block.js').BlockFetcher} blocks Bucket block storage.
297
+ * @param {import('./blockstore.js').BlockFetcher} blocks Bucket block storage.
311
298
  * @param {import('./clock').EventLink<EventData>[]} head Merkle clock head.
312
299
  * @param {string} key The key of the value to retrieve.
313
300
  */
package/src/sha1.js CHANGED
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  // from https://github.com/duzun/sync-sha1/blob/master/rawSha1.js
2
3
  // MIT License Copyright (c) 2020 Dumitru Uzun
3
4
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -29,7 +30,7 @@
29
30
  *
30
31
  * @return {Uint8Array} sha1 hash
31
32
  */
32
- export default function rawSha1 (b) {
33
+ export function rawSha1 (b) {
33
34
  let i = b.byteLength
34
35
  let bs = 0
35
36
  let A; let B; let C; let D; let G
package/src/valet.js CHANGED
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import { CarReader } from '@ipld/car'
2
3
  import { CID } from 'multiformats/cid'
3
4
  import { sha256 } from 'multiformats/hashes/sha2'
@@ -12,18 +13,18 @@ import { nocache as cache } from 'prolly-trees/cache'
12
13
  import { encrypt, decrypt } from './crypto.js'
13
14
  import { Buffer } from 'buffer'
14
15
  import * as codec from 'encrypted-block'
15
- import sha1sync from './sha1.js'
16
+ import { rawSha1 as sha1sync } from './sha1.js'
16
17
  const chunker = bf(3)
17
18
 
18
19
  const NO_ENCRYPT =
19
20
  typeof process !== 'undefined' ? process.env.NO_ENCRYPT : import.meta && import.meta.env.VITE_NO_ENCRYPT
20
21
 
21
- export default class Valet {
22
+ export class Valet {
22
23
  idb = null
23
24
  name = null
24
- #uploadQueue = null
25
- #alreadyEnqueued = new Set()
26
- #keyMaterial = null
25
+ uploadQueue = null
26
+ alreadyEnqueued = new Set()
27
+ keyMaterial = null
27
28
  keyId = 'null'
28
29
 
29
30
  /**
@@ -35,7 +36,7 @@ export default class Valet {
35
36
  constructor (name = 'default', keyMaterial) {
36
37
  this.name = name
37
38
  this.setKeyMaterial(keyMaterial)
38
- this.#uploadQueue = cargoQueue(async (tasks, callback) => {
39
+ this.uploadQueue = cargoQueue(async (tasks, callback) => {
39
40
  console.log(
40
41
  'queue worker',
41
42
  tasks.length,
@@ -56,7 +57,7 @@ export default class Valet {
56
57
  callback()
57
58
  })
58
59
 
59
- this.#uploadQueue.drain(async () => {
60
+ this.uploadQueue.drain(async () => {
60
61
  return await this.withDB(async db => {
61
62
  const carKeys = (await db.getAllFromIndex('cidToCar', 'pending')).map(c => c.car)
62
63
  for (const carKey of carKeys) {
@@ -70,17 +71,17 @@ export default class Valet {
70
71
  }
71
72
 
72
73
  getKeyMaterial () {
73
- return this.#keyMaterial
74
+ return this.keyMaterial
74
75
  }
75
76
 
76
77
  setKeyMaterial (km) {
77
78
  if (km && !NO_ENCRYPT) {
78
79
  const hex = Uint8Array.from(Buffer.from(km, 'hex'))
79
- this.#keyMaterial = km
80
+ this.keyMaterial = km
80
81
  const hash = sha1sync(hex)
81
82
  this.keyId = Buffer.from(hash).toString('hex')
82
83
  } else {
83
- this.#keyMaterial = null
84
+ this.keyMaterial = null
84
85
  this.keyId = 'null'
85
86
  }
86
87
  // console.trace('keyId', this.name, this.keyId)
@@ -95,9 +96,9 @@ export default class Valet {
95
96
  */
96
97
  async writeTransaction (innerBlockstore, cids) {
97
98
  if (innerBlockstore.lastCid) {
98
- if (this.#keyMaterial) {
99
+ if (this.keyMaterial) {
99
100
  // console.log('encrypting car', innerBlockstore.label)
100
- const newCar = await blocksToEncryptedCarBlock(innerBlockstore.lastCid, innerBlockstore, this.#keyMaterial)
101
+ const newCar = await blocksToEncryptedCarBlock(innerBlockstore.lastCid, innerBlockstore, this.keyMaterial)
101
102
  await this.parkCar(newCar.cid.toString(), newCar.bytes, cids)
102
103
  } else {
103
104
  const newCar = await blocksToCarBlock(innerBlockstore.lastCid, innerBlockstore)
@@ -140,14 +141,14 @@ export default class Valet {
140
141
 
141
142
  // upload to web3.storage if we have credentials
142
143
  if (this.uploadFunction) {
143
- if (this.#alreadyEnqueued.has(carCid)) {
144
+ if (this.alreadyEnqueued.has(carCid)) {
144
145
  // console.log('already enqueued', carCid)
145
146
  return
146
147
  }
147
148
  // don't await this, it will be done in the queue
148
149
  // console.log('add to queue', carCid, value.length)
149
- this.#uploadQueue.push({ carCid, value })
150
- this.#alreadyEnqueued.add(carCid)
150
+ this.uploadQueue.push({ carCid, value })
151
+ this.alreadyEnqueued.add(carCid)
151
152
  } else {
152
153
  // console.log('no upload function', carCid, value.length, this.uploadFunction)
153
154
  }
@@ -165,7 +166,7 @@ export default class Valet {
165
166
  }
166
167
  const carBytes = await tx.objectStore('cars').get(carCid)
167
168
  const reader = await CarReader.fromBytes(carBytes)
168
- if (this.#keyMaterial) {
169
+ if (this.keyMaterial) {
169
170
  const roots = await reader.getRoots()
170
171
  const readerGetWithCodec = async cid => {
171
172
  const got = await reader.get(cid)
@@ -182,7 +183,7 @@ export default class Valet {
182
183
  // console.log('decoded', decoded.value)
183
184
  return decoded
184
185
  }
185
- const { blocks } = await blocksFromEncryptedCarBlock(roots[0], readerGetWithCodec, this.#keyMaterial)
186
+ const { blocks } = await blocksFromEncryptedCarBlock(roots[0], readerGetWithCodec, this.keyMaterial)
186
187
  const block = blocks.find(b => b.cid.toString() === dataCID)
187
188
  if (block) {
188
189
  return block.bytes
@@ -234,7 +235,8 @@ const blocksToEncryptedCarBlock = async (innerBlockStoreClockRootCid, blocks, ke
234
235
  key: encryptionKey,
235
236
  hasher: sha256,
236
237
  chunker,
237
- codec: dagcbor, // should be crypto?
238
+ cache,
239
+ // codec: dagcbor, // should be crypto?
238
240
  root: innerBlockStoreClockRootCid
239
241
  })) {
240
242
  encryptedBlocks.push(block)
@@ -262,8 +264,8 @@ const blocksFromEncryptedCarBlock = async (cid, get, keyMaterial) => {
262
264
  key: decryptionKey,
263
265
  chunker,
264
266
  hasher: sha256,
265
- cache,
266
- codec: dagcbor
267
+ cache
268
+ // codec: dagcbor
267
269
  })) {
268
270
  decryptedBlocks.push(block)
269
271
  cids.add(block.cid.toString())
@@ -1,135 +0,0 @@
1
- /* global localStorage */
2
- // @ts-ignore
3
- import { useEffect, useState, createContext } from 'react'
4
- import { Fireproof, Listener, Hydrator } from '../index'
5
-
6
- // export interface FireproofCtxValue {
7
- // addSubscriber: (label: String, fn: Function) => void
8
- // database: Fireproof
9
- // ready: boolean
10
- // persist: () => void
11
- // }
12
- export const FireproofCtx = createContext({
13
- addSubscriber: () => {},
14
- database: null,
15
- ready: false
16
- })
17
-
18
- const inboundSubscriberQueue = new Map()
19
-
20
- let startedSetup = false
21
- let database
22
- let listener
23
- const initializeDatabase = name => {
24
- if (database) return
25
- database = Fireproof.storage(name)
26
- listener = new Listener(database)
27
- }
28
-
29
- /**
30
- * @function useFireproof
31
- * React hook to initialize a Fireproof database, automatically saving and loading the clock.
32
- * You might need to `import { nodePolyfills } from 'vite-plugin-node-polyfills'` in your vite.config.ts
33
- * @param [defineDatabaseFn] Synchronous function that defines the database, run this before any async calls
34
- * @param [setupDatabaseFn] Asynchronous function that sets up the database, run this to load fixture data etc
35
- * @returns {FireproofCtxValue} { addSubscriber, database, ready }
36
- */
37
- export function useFireproof (
38
- defineDatabaseFn = () => {},
39
- setupDatabaseFn = async () => {},
40
- name
41
- ) {
42
- const [ready, setReady] = useState(false)
43
- initializeDatabase(name || 'useFireproof')
44
- const localStorageKey = 'fp.' + database.name
45
-
46
- const addSubscriber = (label, fn) => {
47
- inboundSubscriberQueue.set(label, fn)
48
- }
49
-
50
- const listenerCallback = async event => {
51
- localSet(localStorageKey, JSON.stringify(database))
52
- if (event._external) return
53
- for (const [, fn] of inboundSubscriberQueue) fn()
54
- }
55
-
56
- useEffect(() => {
57
- const doSetup = async () => {
58
- if (ready) return
59
- if (startedSetup) return
60
- startedSetup = true
61
- defineDatabaseFn(database) // define indexes before querying them
62
- console.log('Initializing database', database.name)
63
- const fp = localGet(localStorageKey) // todo use db.name
64
- if (fp) {
65
- try {
66
- const serialized = JSON.parse(fp)
67
- // console.log('serialized', JSON.stringify(serialized.indexes.map(c => c.clock)))
68
- console.log(`Loading previous database clock. (localStorage.removeItem('${localStorageKey}') to reset)`)
69
- await Hydrator.fromJSON(serialized, database)
70
- const changes = await database.changesSince()
71
- if (changes.rows.length < 2) {
72
- // console.log('Resetting database')
73
- throw new Error('Resetting database')
74
- }
75
- } catch (e) {
76
- console.error(`Error loading previous database clock. ${fp} Resetting.`, e)
77
- await Hydrator.zoom(database, [])
78
- await setupDatabaseFn(database)
79
- localSet(localStorageKey, JSON.stringify(database))
80
- }
81
- } else {
82
- await setupDatabaseFn(database)
83
- localSet(localStorageKey, JSON.stringify(database))
84
- }
85
- setReady(true)
86
- listener.on('*', listenerCallback)// hushed('*', listenerCallback, 250))
87
- }
88
- doSetup()
89
- }, [ready])
90
-
91
- return {
92
- addSubscriber,
93
- database,
94
- ready,
95
- persist: () => {
96
- localSet(localStorageKey, JSON.stringify(database))
97
- }
98
- }
99
- }
100
-
101
- // const husherMap = new Map()
102
- // const husher = (id, workFn, ms) => {
103
- // if (!husherMap.has(id)) {
104
- // const start = Date.now()
105
- // husherMap.set(
106
- // id,
107
- // workFn().finally(() => setTimeout(() => husherMap.delete(id), ms - (Date.now() - start)))
108
- // )
109
- // }
110
- // return husherMap.get(id)
111
- // }
112
- // const hushed =
113
- // (id, workFn, ms) =>
114
- // (...args) =>
115
- // husher(id, () => workFn(...args), ms)
116
-
117
- let storageSupported = false
118
- try {
119
- storageSupported = window.localStorage && true
120
- } catch (e) {}
121
- export function localGet (key) {
122
- if (storageSupported) {
123
- return localStorage && localStorage.getItem(key)
124
- }
125
- }
126
- function localSet (key, value) {
127
- if (storageSupported) {
128
- return localStorage && localStorage.setItem(key, value)
129
- }
130
- }
131
- // function localRemove(key) {
132
- // if (storageSupported) {
133
- // return localStorage && localStorage.removeItem(key)
134
- // }
135
- // }
package/index.js DELETED
@@ -1,6 +0,0 @@
1
- import Fireproof from './src/fireproof'
2
- import Index from './src/db-index'
3
- import Listener from './src/listener'
4
- import Hydrator from './src/hydrator'
5
-
6
- export { Fireproof, Index, Listener, Hydrator }
package/scripts/keygen.js DELETED
@@ -1,3 +0,0 @@
1
- import { randomBytes } from 'crypto'
2
-
3
- console.log(randomBytes(32).toString('hex'))
package/test/block.js DELETED
@@ -1,65 +0,0 @@
1
- import { parse } from 'multiformats/link'
2
-
3
- /**
4
- * @typedef {{ cid: import('../src/link').AnyLink, bytes: Uint8Array }} AnyBlock
5
- * @typedef {{ get: (link: import('../src/link').AnyLink) => Promise<AnyBlock | undefined> }} BlockFetcher
6
- */
7
-
8
- /** @implements {BlockFetcher} */
9
- export class MemoryBlockstore {
10
- /** @type {Map<string, Uint8Array>} */
11
- #blocks = new Map()
12
-
13
- /**
14
- * @param {import('../src/link').AnyLink} cid
15
- * @returns {Promise<AnyBlock | undefined>}
16
- */
17
- async get (cid) {
18
- const bytes = this.#blocks.get(cid.toString())
19
- if (!bytes) return
20
- return { cid, bytes }
21
- }
22
-
23
- /**
24
- * @param {import('../src/link').AnyLink} cid
25
- * @param {Uint8Array} bytes
26
- */
27
- async put (cid, bytes) {
28
- // console.log('put', cid)
29
- this.#blocks.set(cid.toString(), bytes)
30
- }
31
-
32
- /**
33
- * @param {import('../src/link').AnyLink} cid
34
- * @param {Uint8Array} bytes
35
- */
36
- putSync (cid, bytes) {
37
- this.#blocks.set(cid.toString(), bytes)
38
- }
39
-
40
- * entries () {
41
- for (const [str, bytes] of this.#blocks) {
42
- yield { cid: parse(str), bytes }
43
- }
44
- }
45
- }
46
-
47
- export class MultiBlockFetcher {
48
- /** @type {BlockFetcher[]} */
49
- #fetchers
50
-
51
- /** @param {BlockFetcher[]} fetchers */
52
- constructor (...fetchers) {
53
- this.#fetchers = fetchers
54
- }
55
-
56
- /** @param {import('../src/link').AnyLink} link */
57
- async get (link) {
58
- for (const f of this.#fetchers) {
59
- const v = await f.get(link)
60
- if (v) {
61
- return v
62
- }
63
- }
64
- }
65
- }