@fireproof/core 0.8.0 → 0.10.1-dev

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 (57) hide show
  1. package/README.md +5 -184
  2. package/dist/fireproof.browser.js +18879 -0
  3. package/dist/fireproof.browser.js.map +7 -0
  4. package/dist/fireproof.cjs.js +9305 -0
  5. package/dist/fireproof.cjs.js.map +7 -0
  6. package/dist/fireproof.esm.js +9295 -0
  7. package/dist/fireproof.esm.js.map +7 -0
  8. package/package.json +57 -105
  9. package/dist/blockstore.js +0 -268
  10. package/dist/clock.js +0 -459
  11. package/dist/crypto.js +0 -63
  12. package/dist/database.js +0 -434
  13. package/dist/db-index.js +0 -403
  14. package/dist/encrypted-block.js +0 -48
  15. package/dist/fireproof.js +0 -84
  16. package/dist/import.js +0 -29
  17. package/dist/listener.js +0 -111
  18. package/dist/loader.js +0 -13
  19. package/dist/prolly.js +0 -405
  20. package/dist/remote.js +0 -102
  21. package/dist/sha1.js +0 -74
  22. package/dist/src/fireproof.d.ts +0 -472
  23. package/dist/src/fireproof.js +0 -81191
  24. package/dist/src/fireproof.js.map +0 -1
  25. package/dist/src/fireproof.mjs +0 -81186
  26. package/dist/src/fireproof.mjs.map +0 -1
  27. package/dist/storage/base.js +0 -426
  28. package/dist/storage/blocksToEncryptedCarBlock.js +0 -144
  29. package/dist/storage/browser.js +0 -62
  30. package/dist/storage/filesystem.js +0 -67
  31. package/dist/storage/rest.js +0 -57
  32. package/dist/storage/ucan.js +0 -0
  33. package/dist/storage/utils.js +0 -144
  34. package/dist/sync.js +0 -218
  35. package/dist/utils.js +0 -16
  36. package/dist/valet.js +0 -102
  37. package/src/blockstore.js +0 -283
  38. package/src/clock.js +0 -486
  39. package/src/crypto.js +0 -70
  40. package/src/database.js +0 -469
  41. package/src/db-index.js +0 -426
  42. package/src/encrypted-block.js +0 -57
  43. package/src/fireproof.js +0 -98
  44. package/src/import.js +0 -34
  45. package/src/link.d.ts +0 -3
  46. package/src/loader.js +0 -16
  47. package/src/prolly.js +0 -445
  48. package/src/remote.js +0 -113
  49. package/src/sha1.js +0 -83
  50. package/src/storage/base.js +0 -463
  51. package/src/storage/browser.js +0 -67
  52. package/src/storage/filesystem.js +0 -73
  53. package/src/storage/rest.js +0 -59
  54. package/src/storage/ucan.js +0 -0
  55. package/src/storage/utils.js +0 -152
  56. package/src/sync.js +0 -237
  57. package/src/valet.js +0 -105
package/src/blockstore.js DELETED
@@ -1,283 +0,0 @@
1
- import { parse } from 'multiformats/link'
2
- import { CID } from 'multiformats'
3
- import { Valet } from './valet.js'
4
-
5
- // const sleep = ms => new Promise(r => setTimeout(r, ms))
6
-
7
- const husherMap = new Map()
8
- const husher = (id, workFn) => {
9
- if (!husherMap.has(id)) {
10
- husherMap.set(
11
- id,
12
- workFn().finally(() => setTimeout(() => husherMap.delete(id), 100))
13
- )
14
- }
15
- return husherMap.get(id)
16
- }
17
-
18
- /**
19
- * @typedef {{ get: (link: import('../src/link').AnyLink) => Promise<AnyBlock | undefined> }} BlockFetcher
20
- */
21
-
22
- /**
23
- * @typedef {Object} AnyBlock
24
- * @property {import('./link').AnyLink} cid - The CID of the block
25
- * @property {Uint8Array} bytes - The block's data
26
- *
27
- * @typedef {Object} Blockstore
28
- * @property {function(import('./link').AnyLink): Promise<AnyBlock|undefined>} get - A function to retrieve a block by CID
29
- * @property {function(import('./link').AnyLink, Uint8Array): Promise<void>} put - A function to store a block's data and CID
30
- *
31
- * A blockstore that caches writes to a transaction and only persists them when committed.
32
- */
33
- export class TransactionBlockstore {
34
- /** @type {Map<string, Uint8Array>} */
35
- committedBlocks = new Map()
36
-
37
- /** @type {Valet} */
38
- valet = null
39
-
40
- instanceId = 'blkz.' + Math.random().toString(36).substring(2, 4)
41
- inflightTransactions = new Set()
42
- syncs = new Set()
43
-
44
- constructor (name, config) {
45
- if (name) {
46
- this.valet = new Valet(name, config)
47
- this.ready = this.valet.ready
48
- } else {
49
- this.ready = Promise.resolve()
50
- }
51
- this.remoteBlockFunction = null
52
- }
53
-
54
- /**
55
- * Get a block from the store.
56
- *
57
- * @param {import('./link').AnyLink} cid
58
- * @returns {Promise<AnyBlock | undefined>}
59
- */
60
- async get (cid) {
61
- const key = cid.toString()
62
- // it is safe to read from the in-flight transactions becauase they are immutable
63
- const bytes = await Promise.any([this.transactionsGet(key), this.committedGet(key)]).catch(e => {
64
- console.log('get error', cid.toString(), e)
65
- return this.networkGet(key)
66
- })
67
- if (!bytes) throw new Error('Missing block: ' + key)
68
- return { cid, bytes }
69
- }
70
-
71
- // this iterates over the in-flight transactions
72
- // and returns the first matching block it finds
73
- async transactionsGet (key) {
74
- for (const transaction of this.inflightTransactions) {
75
- const got = await transaction.get(key)
76
- if (got && got.bytes) return got.bytes
77
- }
78
- throw new Error('Missing block: ' + key)
79
- }
80
-
81
- async committedGet (key) {
82
- const old = this.committedBlocks.get(key)
83
- // console.log('committedGet: ' + key + ' ' + this.instanceId, old.length)
84
- if (old) return old
85
- if (!this.valet) throw new Error('Missing block: ' + key)
86
- const got = await this.valet.getValetBlock(key)
87
- this.committedBlocks.set(key, got)
88
- return got
89
- }
90
-
91
- async clearCommittedCache () {
92
- this.committedBlocks.clear()
93
- }
94
-
95
- async networkGet (key) {
96
- if (this.remoteBlockFunction) {
97
- const value = await husher(key, async () => await this.remoteBlockFunction(key))
98
- if (value) {
99
- // console.log('networkGot: ' + key, value.length)
100
- doTransaction('networkGot: ' + key, this, async innerBlockstore => {
101
- await innerBlockstore.put(CID.parse(key), value)
102
- })
103
- return value
104
- }
105
- } else {
106
- return false
107
- }
108
- }
109
-
110
- /**
111
- * Add a block to the store. Usually bound to a transaction by a closure.
112
- * It sets the lastCid property to the CID of the block that was put.
113
- * This is used by the transaction as the head of the car when written to the valet.
114
- * We don't have to worry about which transaction we are when we are here because
115
- * we are the transactionBlockstore.
116
- *
117
- * @param {import('./link').AnyLink} cid
118
- * @param {Uint8Array} bytes
119
- */
120
- put (cid, bytes) {
121
- throw new Error('use a transaction to put')
122
- }
123
-
124
- /**
125
- * Iterate over all blocks in the store.
126
- *
127
- * @yields {{cid: string, bytes: Uint8Array}}
128
- * @returns {AsyncGenerator<any, any, any>}
129
- */
130
- async * entries () {
131
- for (const transaction of this.inflightTransactions) {
132
- for (const [cid, bytes] of transaction.entries()) { // test for this?
133
- yield { cid: cid.toString(), bytes }
134
- }
135
- }
136
- for (const [str, bytes] of this.committedBlocks) {
137
- yield { cid: str, bytes }
138
- }
139
- if (this.valet) {
140
- for await (const { cid } of this.valet.cids()) {
141
- yield { cid }
142
- }
143
- }
144
- }
145
-
146
- /**
147
- * Begin a transaction. Ensures the uncommited blocks are empty at the begining.
148
- * Returns the blocks to read and write during the transaction.
149
- * @returns {InnerBlockstore}
150
- * @memberof TransactionBlockstore
151
- */
152
- begin (label = '') {
153
- const innerTransactionBlockstore = new InnerBlockstore(label, this)
154
- this.inflightTransactions.add(innerTransactionBlockstore)
155
- return innerTransactionBlockstore
156
- }
157
-
158
- /**
159
- * Commit the transaction. Writes the blocks to the store.
160
- * @returns {Promise<void>}
161
- * @memberof TransactionBlockstore
162
- */
163
- async commit (innerBlockstore, doSync = true) {
164
- // console.log('commit', doSync, innerBlockstore.label)
165
- await this.doCommit(innerBlockstore)
166
- if (doSync) {
167
- // const all =
168
- // console.log('syncing', innerBlockstore.label)
169
- await Promise.all([...this.syncs].map(async sync => sync.sendUpdate(innerBlockstore).catch(e => {
170
- console.error('sync error, cancelling', e)
171
- sync.destroy()
172
- })))
173
- }
174
- }
175
-
176
- // first get the transaction blockstore from the map of transaction blockstores
177
- // then copy it to committedBlocks
178
- // then write the transaction blockstore to a car
179
- // then write the car to the valet
180
- // then remove the transaction blockstore from the map of transaction blockstores
181
- doCommit = async innerBlockstore => {
182
- const cids = new Set()
183
- for (const { cid, bytes } of innerBlockstore.entries()) {
184
- const stringCid = cid.toString()
185
- if (this.committedBlocks.has(stringCid)) {
186
- // console.log('Duplicate block: ' + stringCid) // todo some of this can be avoided, cost is extra size on car files
187
- } else {
188
- this.committedBlocks.set(stringCid, bytes)
189
- cids.add(stringCid)
190
- }
191
- }
192
- // console.log(innerBlockstore.label, 'committing', cids.size, 'blocks', [...cids].map(cid => cid.toString()), this.valet)
193
- if (cids.size > 0 && this.valet) {
194
- await this.valet.writeTransaction(innerBlockstore, cids)
195
- }
196
- }
197
-
198
- /**
199
- * Retire the transaction. Clears the uncommited blocks.
200
- * @returns {void}
201
- * @memberof TransactionBlockstore
202
- */
203
- retire (innerBlockstore) {
204
- this.inflightTransactions.delete(innerBlockstore)
205
- }
206
- }
207
-
208
- /**
209
- * Runs a function on an inner blockstore, then persists the change to a car writer
210
- * or other outer blockstore.
211
- * @param {string} label
212
- * @param {TransactionBlockstore} blockstore
213
- * @param {(innerBlockstore: Blockstore) => Promise<any>} doFun
214
- * @returns {Promise<any>}
215
- * @memberof TransactionBlockstore
216
- */
217
- export const doTransaction = async (label, blockstore, doFun, doSync = true) => {
218
- // @ts-ignore
219
- if (!blockstore.commit) return await doFun(blockstore)
220
- // @ts-ignore
221
- const innerBlockstore = blockstore.begin(label)
222
- try {
223
- const result = await doFun(innerBlockstore)
224
- // console.log('doTransaction', label, 'result', result.head)
225
- if (result && result.head) { innerBlockstore.head = result.head }
226
- // pass the latest clock head for writing to the valet
227
- // @ts-ignore
228
- await blockstore.commit(innerBlockstore, doSync)
229
- return result
230
- } catch (e) {
231
- console.error(`Transaction ${label} failed`, e, e.stack)
232
- throw e
233
- } finally {
234
- // @ts-ignore
235
- blockstore.retire(innerBlockstore)
236
- }
237
- }
238
-
239
- export class InnerBlockstore {
240
- /** @type {Map<string, Uint8Array>} */
241
- blocks = new Map()
242
- head = []
243
- lastCid = null
244
- label = ''
245
- parentBlockstore = null
246
-
247
- constructor (label, parentBlockstore) {
248
- this.label = label
249
- this.parentBlockstore = parentBlockstore
250
- }
251
-
252
- /**
253
- * @param {import('./link').AnyLink} cid
254
- * @returns {Promise<AnyBlock | undefined>}
255
- */
256
- async get (cid) {
257
- const key = cid.toString()
258
- let bytes = this.blocks.get(key)
259
- if (bytes) {
260
- return { cid, bytes }
261
- }
262
- bytes = await this.parentBlockstore.committedGet(key)
263
- if (bytes) {
264
- return { cid, bytes }
265
- }
266
- }
267
-
268
- /**
269
- * @param {import('./link').AnyLink} cid
270
- * @param {Uint8Array} bytes
271
- */
272
- async put (cid, bytes) {
273
- // console.log('put', cid)
274
- this.blocks.set(cid.toString(), bytes)
275
- this.lastCid = cid
276
- }
277
-
278
- * entries () {
279
- for (const [str, bytes] of this.blocks) {
280
- yield { cid: parse(str), bytes }
281
- }
282
- }
283
- }