hypercore-storage 0.0.40 → 1.0.0

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.
@@ -1,438 +0,0 @@
1
- const { ASSERTION } = require('hypercore-errors')
2
- const { Readable, isEnded, getStreamError } = require('streamx')
3
-
4
- const TipList = require('./tip-list')
5
-
6
- class OverlayStream extends Readable {
7
- constructor (tip, storage, createStream, opts = {}) {
8
- super()
9
-
10
- this.tip = tip
11
- this.storage = storage
12
- this.options = opts
13
-
14
- this._reverse = !!opts.reverse
15
- this._active = null
16
- this._position = this._reverse ? tip.length() - 1 : tip.offset
17
-
18
- this._createStream = createStream
19
- this._pendingDestroy = null
20
-
21
- if (!opts.reverse) this._makeActiveStream()
22
- }
23
-
24
- _predestroy () {
25
- if (this._active) this._active.destroy()
26
- }
27
-
28
- _read (cb) {
29
- if (this._active === null) {
30
- if (this._yield()) {
31
- cb(null)
32
- return
33
- }
34
- }
35
-
36
- if (this._active) {
37
- this._active.resume()
38
- }
39
-
40
- cb(null)
41
- }
42
-
43
- _yield () {
44
- while (this._memoryRemaining()) {
45
- const { valid, value } = this.tip.get(this._position)
46
- const index = this._nextIndex()
47
-
48
- if (!valid) continue
49
- if (!this.push({ index, page: value })) break
50
- }
51
-
52
- return this._onmemorydrain()
53
- }
54
-
55
- _nextIndex () {
56
- if (this._reverse) return this._position--
57
- return this._position++
58
- }
59
-
60
- _memoryRemaining () {
61
- if (this._reverse) return this._position >= this.tip.offset
62
- return this._position < this.tip.length()
63
- }
64
-
65
- _onmemorydrain () {
66
- if (!this._reverse) {
67
- this.push(null)
68
- return true
69
- }
70
-
71
- this._makeActiveStream()
72
-
73
- return false
74
- }
75
-
76
- _makeActiveStream () {
77
- this._active = this._createStream(this.storage, this.options)
78
- this._active.on('error', noop) // handled in onclose
79
- this._active.on('close', this._onclose.bind(this))
80
- this._active.on('data', this._ondata.bind(this))
81
- }
82
-
83
- _ondata (data) {
84
- if (!this.push(data)) this._active.pause()
85
- }
86
-
87
- _onclose () {
88
- if (!isEnded(this._active)) {
89
- const error = getStreamError(this._active)
90
- this.destroy(error)
91
- return
92
- }
93
-
94
- if (this._reverse) {
95
- this.push(null)
96
- return
97
- }
98
-
99
- this._yield()
100
- }
101
- }
102
-
103
- class MemoryOverlay {
104
- constructor (storage) {
105
- this.storage = storage
106
- this.head = null
107
- this.auth = null
108
- this.localKeyPair = null
109
- this.encryptionKey = null
110
- this.dataDependency = null
111
- this.dataInfo = null
112
- this.userData = null
113
- this.blocks = null
114
- this.treeNodes = null
115
- this.bitfields = null
116
-
117
- this.snapshotted = false
118
- this.snapshotShared = null
119
- this.activeSnapshots = 0
120
- this.copied = false
121
- }
122
-
123
- async registerBatch (name, length, overwrite) {
124
- todo()
125
- }
126
-
127
- snapshot () {
128
- if (this.snapshotShared !== null) return this.snapshotShared.snapshot()
129
-
130
- this.activeSnapshots++
131
-
132
- const snap = new MemoryOverlay(this.storage.snapshot())
133
-
134
- snap.snapshotted = true
135
- snap.snapshotShared = this
136
-
137
- if (this.head !== null) snap.head = this.head
138
- if (this.auth !== null) snap.auth = this.auth
139
- if (this.localKeyPair !== null) snap.localKeyPair = this.localKeyPair
140
- if (this.encryptionKey !== null) snap.encryptionKey = this.encryptionKey
141
- if (this.dataDependency !== null) snap.dataDependency = this.dataDependency
142
- if (this.dataInfo !== null) snap.dataInfo = this.dataInfo
143
- if (this.userData !== null) snap.userData = this.userData
144
- if (this.blocks !== null) snap.blocks = this.blocks
145
- if (this.treeNodes !== null) snap.treeNodes = this.treeNodes
146
- if (this.bitfields !== null) snap.bitfields = this.bitfields
147
-
148
- return snap
149
- }
150
-
151
- _copy () {
152
- if (this.copied) return
153
- this.copied = true
154
-
155
- // clone state
156
- if (this.head !== null) this.head = Object.assign(this.head)
157
- if (this.auth !== null) this.auth = Object.assign(this.auth)
158
- if (this.localKeyPair !== null) this.localKeyPair = Object.assign(this.localKeyPair)
159
- if (this.encryptionKey !== null) this.encryptionKey = Object.assign(this.encryptionKey)
160
- if (this.dataDependency !== null) this.dataDependency = Object.assign(this.dataDependency)
161
- if (this.dataInfo !== null) this.dataInfo = Object.assign(this.dataInfo)
162
- if (this.userData !== null) this.userData = mergeMap(new Map(), this.userData)
163
- if (this.blocks !== null) this.blocks = mergeTip(new TipList(), this.blocks)
164
- if (this.treeNodes !== null) this.treeNodes = mergeMap(new Map(), this.treeNodes)
165
- if (this.bitfields !== null) this.bitfields = mergeTip(new TipList(), this.bitfields)
166
- }
167
-
168
- get dependencies () {
169
- return this.storage.dependencies
170
- }
171
-
172
- dependencyLength () {
173
- if (this.dataDependency) return this.dataDependency.length
174
- return this.storage.dependencyLength()
175
- }
176
-
177
- createReadBatch () {
178
- return new MemoryOverlayReadBatch(this, this.storage.createReadBatch())
179
- }
180
-
181
- createWriteBatch () {
182
- if (this.activeSnapshots > 0) this._copy()
183
- return new MemoryOverlayWriteBatch(this)
184
- }
185
-
186
- createBlockStream () {
187
- todo()
188
- }
189
-
190
- createUserDataStream () {
191
- todo()
192
- }
193
-
194
- createTreeNodeStream () {
195
- todo()
196
- }
197
-
198
- createBitfieldPageStream (opts) {
199
- if (this.bitfields === null) return createBitfieldPageStream(this.storage)
200
- return new OverlayStream(this.bitfields, this.storage, createBitfieldPageStream, opts)
201
- }
202
-
203
- findDependency () {
204
- return null
205
- }
206
-
207
- async peekLastTreeNode () {
208
- todo()
209
- }
210
-
211
- async peekLastBitfieldPage () {
212
- const mem = this.bitfields !== null ? this.bitfields.get(this.bitfields.length() - 1) : { valid: false }
213
-
214
- const page = mem.valid ? mem.value : null
215
- const index = page ? this.bitfields.length() - 1 : -1
216
-
217
- const disk = await this.storage.peekLastBitfieldPage()
218
-
219
- return (page && (!disk || index > disk.index)) ? { index, page } : disk
220
- }
221
-
222
- destroy () {
223
- if (this.snapshotted) this.storage.destroy()
224
- if (this.snapshotShared === null) return
225
- this.snapshotShared.activeSnapshots--
226
- this.snapshotShared = null
227
- }
228
-
229
- merge (overlay) {
230
- if (overlay.head !== null) this.head = overlay.head
231
- if (overlay.auth !== null) this.auth = overlay.auth
232
- if (overlay.localKeyPair !== null) this.localKeyPair = overlay.localKeyPair
233
- if (overlay.encryptionKey !== null) this.encryptionKey = overlay.encryptionKey
234
- if (overlay.dataDependency !== null) this.dataDependency = overlay.dataDependency
235
- if (overlay.dataInfo !== null) this.dataInfo = overlay.dataInfo
236
- if (overlay.userData !== null) this.userData = mergeMap(this.userData, overlay.userData)
237
- if (overlay.blocks !== null) this.blocks = mergeTip(this.blocks, overlay.blocks)
238
- if (overlay.treeNodes !== null) this.treeNodes = mergeMap(this.treeNodes, overlay.treeNodes)
239
- if (overlay.bitfields !== null) this.bitfields = mergeTip(this.bitfields, overlay.bitfields)
240
- }
241
- }
242
-
243
- module.exports = MemoryOverlay
244
-
245
- class MemoryOverlayReadBatch {
246
- constructor (overlay, read) {
247
- this.read = read
248
- this.overlay = overlay
249
- }
250
-
251
- async getCoreHead () {
252
- return this.overlay.head !== null ? this.overlay.head : this.read.getCoreHead()
253
- }
254
-
255
- async getCoreAuth () {
256
- return this.overlay.auth !== null ? this.overlay.auth : this.read.getCoreAuth()
257
- }
258
-
259
- async getDataDependency () {
260
- return this.overlay.dataDependency !== null ? this.overlay.dataDependency : this.read.getDataDependency()
261
- }
262
-
263
- async getLocalKeyPair () {
264
- return this.overlay.localKeyPair !== null ? this.overlay.localKeyPair : this.read.getLocalKeyPair()
265
- }
266
-
267
- async getEncryptionKey () {
268
- return this.overlay.encryptionKey !== null ? this.overlay.encryptionKey : this.read.getEncryptionKey()
269
- }
270
-
271
- async getDataInfo () {
272
- return this.overlay.dataInfo !== null ? this.overlay.dataInfo : this.read.getDataInfo()
273
- }
274
-
275
- async getUserData (key) {
276
- return this.overlay.userData !== null && this.overlay.userData.has(key)
277
- ? this.overlay.userData.get(key)
278
- : this.read.getUserData(key)
279
- }
280
-
281
- async hasBlock (index) {
282
- if (this.overlay.blocks !== null && index >= this.overlay.blocks.offset) {
283
- const blk = this.overlay.blocks.get(index)
284
- if (blk.valid) return true
285
- }
286
- return this.read.hasBlock(index)
287
- }
288
-
289
- async getBlock (index, error) {
290
- if (this.overlay.blocks !== null && index >= this.overlay.blocks.offset) {
291
- const blk = this.overlay.blocks.get(index)
292
- if (blk.valid) return blk.value
293
- }
294
- return this.read.getBlock(index, error)
295
- }
296
-
297
- async hasTreeNode (index) {
298
- return this.overlay.treeNodes !== null
299
- ? this.overlay.treeNodes.has(index)
300
- : this.read.hasTreeNode(index)
301
- }
302
-
303
- async getTreeNode (index, error) {
304
- return this.overlay.treeNodes !== null && this.overlay.treeNodes.has(index)
305
- ? this.overlay.treeNodes.get(index)
306
- : this.read.getTreeNode(index, error)
307
- }
308
-
309
- async getBitfieldPage (index) {
310
- if (this.overlay.bitfields !== null && index >= this.overlay.bitfields.offset) {
311
- const page = this.overlay.bitfields.get(index)
312
- if (page.valid) return page.value
313
- }
314
- return this.read.getBitfieldPage(index)
315
- }
316
-
317
- destroy () {
318
- this.read.destroy()
319
- }
320
-
321
- flush () {
322
- return this.read.flush()
323
- }
324
-
325
- tryFlush () {
326
- this.read.tryFlush()
327
- }
328
- }
329
-
330
- class MemoryOverlayWriteBatch {
331
- constructor (storage) {
332
- this.storage = storage
333
- this.overlay = new MemoryOverlay()
334
- }
335
-
336
- setCoreHead (head) {
337
- this.overlay.head = head
338
- }
339
-
340
- setCoreAuth (auth) {
341
- this.overlay.auth = auth
342
- }
343
-
344
- setBatchPointer (name, pointer) {
345
- todo()
346
- }
347
-
348
- setDataDependency (dependency) {
349
- this.overlay.dataDependency = dependency
350
- }
351
-
352
- setLocalKeyPair (keyPair) {
353
- this.overlay.localKeyPair = keyPair
354
- }
355
-
356
- setEncryptionKey (encryptionKey) {
357
- this.overlay.encryptionKey = encryptionKey
358
- }
359
-
360
- setDataInfo (info) {
361
- this.overlay.dataInfo = info
362
- }
363
-
364
- setUserData (key, value) {
365
- if (this.overlay.userData === null) this.overlay.userData = new Map()
366
- this.overlay.userData.set(key, value)
367
- }
368
-
369
- putBlock (index, data) {
370
- if (this.overlay.blocks === null) this.overlay.blocks = new TipList()
371
- this.overlay.blocks.put(index, data)
372
- }
373
-
374
- deleteBlock (index) {
375
- todo()
376
- }
377
-
378
- deleteBlockRange (start, end) {
379
- if (this.overlay.blocks === null) this.overlay.blocks = new TipList()
380
- this.overlay.blocks.delete(start, end)
381
- }
382
-
383
- putTreeNode (node) {
384
- if (this.overlay.treeNodes === null) this.overlay.treeNodes = new Map()
385
- this.overlay.treeNodes.set(node.index, node)
386
- }
387
-
388
- deleteTreeNode (index) {
389
- todo()
390
- }
391
-
392
- deleteTreeNodeRange (start, end) {
393
- todo()
394
- }
395
-
396
- putBitfieldPage (index, page) {
397
- if (this.overlay.bitfields === null) this.overlay.bitfields = new TipList()
398
- this.overlay.bitfields.put(index, page)
399
- }
400
-
401
- deleteBitfieldPage (index) {
402
- todo()
403
- }
404
-
405
- deleteBitfieldPageRange (start, end) {
406
- if (this.overlay.bitfields === null) this.overlay.bitfields = new TipList()
407
- this.overlay.bitfields.delete(start, end)
408
- }
409
-
410
- destroy () {}
411
-
412
- flush () {
413
- this.storage.merge(this.overlay)
414
- return Promise.resolve()
415
- }
416
- }
417
-
418
- function createBitfieldPageStream (storage, opts) {
419
- return storage.createBitfieldPageStream(opts)
420
- }
421
-
422
- function mergeMap (a, b) {
423
- if (a === null) return b
424
- for (const [key, value] of b) a.set(key, value)
425
- return a
426
- }
427
-
428
- function mergeTip (a, b) {
429
- if (a === null) return b
430
- a.merge(b)
431
- return a
432
- }
433
-
434
- function noop () {}
435
-
436
- function todo () {
437
- throw ASSERTION('Not supported yet, but will be')
438
- }
package/lib/messages.js DELETED
@@ -1,190 +0,0 @@
1
- const c = require('compact-encoding')
2
-
3
- exports.DataPointer = c.uint
4
-
5
- exports.KeyPair = {
6
- preencode (state, m) {
7
- c.uint.preencode(state, m.secretKey ? 1 : 0)
8
- c.fixed32.preencode(state, m.publicKey)
9
- if (m.secretKey) c.fixed64.preencode(state, m.secretKey)
10
- },
11
- encode (state, m) {
12
- c.uint.encode(state, m.secretKey ? 1 : 0)
13
- c.fixed32.encode(state, m.publicKey)
14
- if (m.secretKey) c.fixed64.encode(state, m.secretKey)
15
- },
16
- decode (state) {
17
- const flags = c.uint.decode(state)
18
-
19
- return {
20
- publicKey: c.fixed32.decode(state),
21
- secretKey: flags & 1 ? c.fixed64.decode(state) : null
22
- }
23
- }
24
- }
25
-
26
- exports.StorageInfo = {
27
- preencode (state, m) {
28
- c.uint.preencode(state, 0) // version
29
- c.uint.preencode(state, 0) // flags, reserved
30
- c.uint.preencode(state, m.free)
31
- c.uint.preencode(state, m.total)
32
- },
33
- encode (state, m) {
34
- c.uint.encode(state, 0) // version
35
- c.uint.encode(state, 0) // flags, reserved
36
- c.uint.encode(state, m.free)
37
- c.uint.encode(state, m.total)
38
- },
39
- decode (state, m) {
40
- const v = c.uint.decode(state)
41
- if (v !== 0) throw new Error('Invalid version: ' + v)
42
-
43
- c.uint.decode(state) // flags, ignore
44
-
45
- return {
46
- free: c.uint.decode(state),
47
- total: c.uint.decode(state)
48
- }
49
- }
50
- }
51
-
52
- exports.CorePointer = {
53
- preencode (state, m) {
54
- c.uint.preencode(state, m.core)
55
- c.uint.preencode(state, m.data)
56
- },
57
- encode (state, m) {
58
- c.uint.encode(state, m.core)
59
- c.uint.encode(state, m.data)
60
- },
61
- decode (state) {
62
- return {
63
- core: c.uint.decode(state),
64
- data: c.uint.decode(state)
65
- }
66
- }
67
- }
68
-
69
- exports.CoreHead = {
70
- preencode (state, m) {
71
- c.uint.preencode(state, m.fork)
72
- c.uint.preencode(state, m.length)
73
- c.fixed32.preencode(state, m.rootHash)
74
- c.buffer.preencode(state, m.signature)
75
- },
76
- encode (state, m) {
77
- c.uint.encode(state, m.fork)
78
- c.uint.encode(state, m.length)
79
- c.fixed32.encode(state, m.rootHash)
80
- c.buffer.encode(state, m.signature)
81
- },
82
- decode (state) {
83
- return {
84
- fork: c.uint.decode(state),
85
- length: c.uint.decode(state),
86
- rootHash: c.fixed32.decode(state),
87
- signature: c.buffer.decode(state)
88
- }
89
- }
90
- }
91
-
92
- exports.TreeNode = {
93
- preencode (state, m) {
94
- c.uint.preencode(state, m.index)
95
- c.uint.preencode(state, m.size)
96
- c.fixed32.preencode(state, m.hash)
97
- },
98
- encode (state, m) {
99
- c.uint.encode(state, m.index)
100
- c.uint.encode(state, m.size)
101
- c.fixed32.encode(state, m.hash)
102
- },
103
- decode (state) {
104
- return {
105
- index: c.uint.decode(state),
106
- size: c.uint.decode(state),
107
- hash: c.fixed32.decode(state)
108
- }
109
- }
110
- }
111
-
112
- exports.CoreAuth = {
113
- preencode (state, m) {
114
- c.uint.preencode(state, m.manifest ? 1 : 0)
115
- c.fixed32.preencode(state, m.key)
116
- if (m.manifest) c.buffer.preencode(state, m.manifest)
117
- },
118
- encode (state, m) {
119
- c.uint.encode(state, m.manifest ? 1 : 0)
120
- c.fixed32.encode(state, m.key)
121
- if (m.manifest) c.buffer.encode(state, m.manifest)
122
- },
123
- decode (state) {
124
- const flags = c.uint.decode(state)
125
-
126
- return {
127
- key: c.fixed32.decode(state),
128
- manifest: flags & 1 ? c.buffer.decode(state) : null
129
- }
130
- }
131
- }
132
-
133
- exports.DataDependency = {
134
- preencode (state, m) {
135
- c.uint.preencode(state, m.data)
136
- c.uint.preencode(state, m.length)
137
- },
138
- encode (state, m) {
139
- c.uint.encode(state, m.data)
140
- c.uint.encode(state, m.length)
141
- },
142
- decode (state) {
143
- return {
144
- data: c.uint.decode(state),
145
- length: c.uint.decode(state)
146
- }
147
- }
148
- }
149
-
150
- exports.CoreSeed = {
151
- preencode (state, m) {
152
- c.fixed32.preencode(state, m.seed)
153
- },
154
- encode (state, m) {
155
- c.fixed32.encode(state, m.seed)
156
- },
157
- decode (state) {
158
- return {
159
- seed: c.fixed32.decode(state)
160
- }
161
- }
162
- }
163
-
164
- exports.CoreEncryptionKey = {
165
- preencode (state, m) {
166
- c.fixed32.preencode(state, m.encryptionKey)
167
- },
168
- encode (state, m) {
169
- c.fixed32.encode(state, m.encryptionKey)
170
- },
171
- decode (state) {
172
- return {
173
- encryptionKey: c.fixed32.decode(state)
174
- }
175
- }
176
- }
177
-
178
- exports.DataInfo = {
179
- preencode (state, m) {
180
- c.uint.preencode(state, m.version)
181
- },
182
- encode (state, m) {
183
- c.uint.encode(state, m.version)
184
- },
185
- decode (state) {
186
- return {
187
- version: c.uint.decode(state)
188
- }
189
- }
190
- }
package/lib/tip-list.js DELETED
@@ -1,93 +0,0 @@
1
- const { ASSERTION } = require('hypercore-errors')
2
-
3
- module.exports = class TipList {
4
- constructor () {
5
- this.offset = 0
6
- this.removed = 0
7
- this.data = []
8
- }
9
-
10
- length () {
11
- return this.offset + this.data.length
12
- }
13
-
14
- end () {
15
- if (this.removed) return this.removed
16
- return this.offset + this.data.length
17
- }
18
-
19
- delete (start, end) {
20
- if (end !== -1) {
21
- if (end < this.length() || (this.length() < start && this.length() !== 0)) {
22
- throw ASSERTION('Invalid delete on tip list')
23
- }
24
- }
25
-
26
- if (this.end() === 0) this.offset = start
27
- if (this.removed < end || end === -1) this.removed = end
28
-
29
- if (start < this.offset) {
30
- this.offset = start
31
- this.data = [] // clear everything
32
- return
33
- }
34
-
35
- while (this.length() > start) this.data.pop()
36
- }
37
-
38
- put (index, value) {
39
- if (this.end() === 0) {
40
- this.offset = index
41
- this.data.push(value)
42
- return
43
- }
44
-
45
- if (!this.removed && this.end() === index) {
46
- this.data.push(value)
47
- return
48
- }
49
-
50
- throw ASSERTION('Invalid put on tip list')
51
- }
52
-
53
- get (index) {
54
- if (index < this.offset) {
55
- return {
56
- valid: false,
57
- value: null
58
- }
59
- }
60
-
61
- if (index - this.offset < this.data.length) {
62
- return {
63
- valid: true,
64
- value: this.data[index - this.offset]
65
- }
66
- }
67
-
68
- return {
69
- valid: index < this.end(),
70
- value: null
71
- }
72
- }
73
-
74
- * [Symbol.iterator] () {
75
- for (let i = 0; i < this.data.length; i++) {
76
- yield [i + this.offset, this.data[i]]
77
- }
78
- }
79
-
80
- merge (tip) {
81
- const invalidDeletion = tip.removed > 0 && tip.end() !== -1 && tip.end() < this.end()
82
- const invalidTip = (tip.removed !== -1 && tip.end() < this.offset) || this.end() < tip.offset
83
-
84
- if (invalidTip || invalidDeletion) throw ASSERTION('Cannot merge tip list')
85
-
86
- while (this.end() !== tip.offset && tip.offset >= this.offset && tip.end() >= this.end()) this.data.pop()
87
- while (tip.removed && this.end() > tip.length() && this.data.length) this.data.pop()
88
-
89
- for (const data of tip.data) this.data.push(data)
90
-
91
- return this
92
- }
93
- }