@fireproof/core 0.8.0 → 0.10.1-dev

Sign up to get free protection for your applications and to get access to all the features.
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
- }