hypercore-storage 0.0.21 → 0.0.23
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.
- package/index.js +35 -15
- package/lib/memory-overlay.js +285 -0
- package/lib/tip-list.js +93 -0
- package/package.json +2 -1
package/index.js
CHANGED
|
@@ -5,8 +5,10 @@ const RW = require('read-write-mutexify')
|
|
|
5
5
|
const b4a = require('b4a')
|
|
6
6
|
const flat = require('flat-tree')
|
|
7
7
|
const assert = require('nanoassert')
|
|
8
|
+
|
|
8
9
|
const m = require('./lib/messages')
|
|
9
10
|
const DependencyStream = require('./lib/dependency-stream')
|
|
11
|
+
const MemoryOverlay = require('./lib/memory-overlay')
|
|
10
12
|
|
|
11
13
|
const INF = b4a.from([0xff])
|
|
12
14
|
|
|
@@ -181,6 +183,10 @@ class ReadBatch {
|
|
|
181
183
|
return this._get(encodeCoreIndex(this.storage.corePointer, CORE.ENCRYPTION_KEY), null)
|
|
182
184
|
}
|
|
183
185
|
|
|
186
|
+
getDataDependency () {
|
|
187
|
+
return this._get(encodeDataIndex(this.storage.dataPointer, DATA.DEPENDENCY), m.DataDependency)
|
|
188
|
+
}
|
|
189
|
+
|
|
184
190
|
getDataInfo (info) {
|
|
185
191
|
return this._get(encodeDataIndex(this.storage.dataPointer, DATA.INFO), m.DataInfo)
|
|
186
192
|
}
|
|
@@ -426,23 +432,32 @@ class HypercoreStorage {
|
|
|
426
432
|
return this.dbSnapshot !== null
|
|
427
433
|
}
|
|
428
434
|
|
|
429
|
-
|
|
430
|
-
|
|
435
|
+
dependencyLength () {
|
|
436
|
+
return this.dependencies.length
|
|
437
|
+
? this.dependencies[this.dependencies.length - 1].length
|
|
438
|
+
: -1
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
async openBatch (name) {
|
|
431
442
|
const existing = await this.db.get(encodeBatch(this.corePointer, CORE.BATCHES, name))
|
|
432
|
-
|
|
443
|
+
if (!existing) return null
|
|
433
444
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
storage.dataPointer = dataPointer
|
|
437
|
-
storage.dependencies = await addDependencies(this.db, storage.dataPointer, length)
|
|
438
|
-
return storage
|
|
439
|
-
}
|
|
445
|
+
const storage = new HypercoreStorage(this.root, this.discoveryKey, this.corePointer, this.dataPointer, this.dbSnapshot)
|
|
446
|
+
const dataPointer = c.decode(m.DataPointer, existing)
|
|
440
447
|
|
|
448
|
+
storage.dataPointer = dataPointer
|
|
449
|
+
storage.dependencies = await addDependencies(this.db, storage.dataPointer, -1)
|
|
450
|
+
|
|
451
|
+
return storage
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
async registerBatch (name, head) {
|
|
441
455
|
await this.mutex.write.lock()
|
|
442
456
|
|
|
457
|
+
const storage = new HypercoreStorage(this.root, this.discoveryKey, this.corePointer, this.dataPointer, null)
|
|
458
|
+
|
|
443
459
|
try {
|
|
444
460
|
const info = await getStorageInfo(this.db)
|
|
445
|
-
|
|
446
461
|
const write = this.db.write()
|
|
447
462
|
|
|
448
463
|
storage.dataPointer = info.free++
|
|
@@ -453,18 +468,23 @@ class HypercoreStorage {
|
|
|
453
468
|
|
|
454
469
|
initialiseCoreData(batch)
|
|
455
470
|
|
|
456
|
-
batch.setDataDependency({ data: this.dataPointer, length })
|
|
471
|
+
batch.setDataDependency({ data: this.dataPointer, length: head.length })
|
|
457
472
|
batch.setBatchPointer(name, storage.dataPointer)
|
|
473
|
+
if (head.rootHash) batch.setCoreHead(head) // if no root hash its the empty core - no head yet
|
|
458
474
|
|
|
459
475
|
await write.flush()
|
|
460
476
|
|
|
461
|
-
storage.dependencies = await addDependencies(this.db, storage.dataPointer, length)
|
|
477
|
+
storage.dependencies = await addDependencies(this.db, storage.dataPointer, head.length)
|
|
462
478
|
return storage
|
|
463
479
|
} finally {
|
|
464
480
|
this.mutex.write.unlock()
|
|
465
481
|
}
|
|
466
482
|
}
|
|
467
483
|
|
|
484
|
+
createMemoryOverlay () {
|
|
485
|
+
return new MemoryOverlay(this)
|
|
486
|
+
}
|
|
487
|
+
|
|
468
488
|
snapshot () {
|
|
469
489
|
assert(this.closed === false)
|
|
470
490
|
return new HypercoreStorage(this.root, this.discoveryKey, this.corePointer, this.dataPointer, this.db.snapshot())
|
|
@@ -515,7 +535,7 @@ class HypercoreStorage {
|
|
|
515
535
|
return s
|
|
516
536
|
}
|
|
517
537
|
|
|
518
|
-
async
|
|
538
|
+
async peekLastTreeNode () {
|
|
519
539
|
assert(this.closed === false)
|
|
520
540
|
|
|
521
541
|
const last = await this.db.peek(encodeIndexRange(this.dataPointer, DATA.TREE, this.dbSnapshot, { reverse: true }))
|
|
@@ -523,7 +543,7 @@ class HypercoreStorage {
|
|
|
523
543
|
return c.decode(m.TreeNode, last.value)
|
|
524
544
|
}
|
|
525
545
|
|
|
526
|
-
async
|
|
546
|
+
async peekLastBitfieldPage () {
|
|
527
547
|
assert(this.closed === false)
|
|
528
548
|
|
|
529
549
|
const last = await this.db.peek(encodeIndexRange(this.dataPointer, DATA.BITFIELD, this.dbSnapshot, { reverse: true }))
|
|
@@ -709,7 +729,7 @@ async function addDependencies (db, dataPointer, treeLength) {
|
|
|
709
729
|
let dep = await db.get(encodeDataIndex(dataPointer, DATA.DEPENDENCY))
|
|
710
730
|
while (dep) {
|
|
711
731
|
const { data, length } = c.decode(m.DataDependency, dep)
|
|
712
|
-
if (length <= treeLength) dependencies.push({ data, length })
|
|
732
|
+
if (treeLength === -1 || length <= treeLength) dependencies.push({ data, length })
|
|
713
733
|
|
|
714
734
|
dep = await db.get(encodeDataIndex(data, DATA.DEPENDENCY))
|
|
715
735
|
}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
const { ASSERTION } = require('hypercore-errors')
|
|
2
|
+
|
|
3
|
+
const TipList = require('./tip-list')
|
|
4
|
+
|
|
5
|
+
class MemoryOverlay {
|
|
6
|
+
constructor (storage) {
|
|
7
|
+
this.storage = storage
|
|
8
|
+
this.head = null
|
|
9
|
+
this.auth = null
|
|
10
|
+
this.localKeyPair = null
|
|
11
|
+
this.encryptionKey = null
|
|
12
|
+
this.dataDependency = null
|
|
13
|
+
this.dataInfo = null
|
|
14
|
+
this.userData = null
|
|
15
|
+
this.blocks = null
|
|
16
|
+
this.treeNodes = null
|
|
17
|
+
this.bitfields = null
|
|
18
|
+
|
|
19
|
+
this.snapshotted = false
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async registerBatch (name, length, overwrite) {
|
|
23
|
+
todo()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
snapshot () {
|
|
27
|
+
todo()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get dependencies () {
|
|
31
|
+
return this.storage.dependencies
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
dependencyLength () {
|
|
35
|
+
if (this.dataDependency) return this.dataDependency.length
|
|
36
|
+
return this.storage.dependencyLength()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
createReadBatch () {
|
|
40
|
+
return new MemoryOverlayReadBatch(this, this.storage.createReadBatch())
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
createWriteBatch () {
|
|
44
|
+
return new MemoryOverlayWriteBatch(this)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
createBlockStream () {
|
|
48
|
+
todo()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
createUserDataStream () {
|
|
52
|
+
todo()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
createTreeNodeStream () {
|
|
56
|
+
todo()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
createBitfieldPageStream () {
|
|
60
|
+
todo()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async peekLastTreeNode () {
|
|
64
|
+
todo()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async peekLastBitfieldPage () {
|
|
68
|
+
const mem = this.bitfields !== null ? this.bitfields.get(this.bitfields.length() - 1) : { valid: false }
|
|
69
|
+
|
|
70
|
+
const page = mem.valid ? mem.value : null
|
|
71
|
+
const index = page ? this.bitfields.length() - 1 : -1
|
|
72
|
+
|
|
73
|
+
const disk = await this.storage.peekLastBitfieldPage()
|
|
74
|
+
|
|
75
|
+
return (page && (!disk || index > disk.index)) ? { index, page } : disk
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
close () {
|
|
79
|
+
return Promise.resolve()
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
merge (overlay) {
|
|
83
|
+
if (overlay.head !== null) this.head = overlay.head
|
|
84
|
+
if (overlay.auth !== null) this.auth = overlay.auth
|
|
85
|
+
if (overlay.localKeyPair !== null) this.localKeyPair = overlay.localKeyPair
|
|
86
|
+
if (overlay.encryptionKey !== null) this.encryptionKey = overlay.encryptionKey
|
|
87
|
+
if (overlay.dataDependency !== null) this.dataDependency = overlay.dataDependency
|
|
88
|
+
if (overlay.dataInfo !== null) this.dataInfo = overlay.dataInfo
|
|
89
|
+
if (overlay.userData !== null) this.userData = mergeMap(this.userData, overlay.userData)
|
|
90
|
+
if (overlay.blocks !== null) this.blocks = mergeTip(this.blocks, overlay.blocks)
|
|
91
|
+
if (overlay.treeNodes !== null) this.treeNodes = mergeMap(this.treeNodes, overlay.treeNodes)
|
|
92
|
+
if (overlay.bitfields !== null) this.bitfields = mergeTip(this.bitfields, overlay.bitfields)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module.exports = MemoryOverlay
|
|
97
|
+
|
|
98
|
+
class MemoryOverlayReadBatch {
|
|
99
|
+
constructor (overlay, read) {
|
|
100
|
+
this.read = read
|
|
101
|
+
this.overlay = overlay
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async getCoreHead () {
|
|
105
|
+
return this.overlay.head !== null ? this.overlay.head : this.read.getCoreHead()
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async getCoreAuth () {
|
|
109
|
+
return this.overlay.auth !== null ? this.overlay.auth : this.read.getCoreAuth()
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async getDataDependency () {
|
|
113
|
+
return this.overlay.dataDependency !== null ? this.overlay.dataDependency : this.read.getDataDependency()
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async getLocalKeyPair () {
|
|
117
|
+
return this.overlay.localKeyPair !== null ? this.overlay.localKeyPair : this.read.getLocalKeyPair()
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async getEncryptionKey () {
|
|
121
|
+
return this.overlay.encryptionKey !== null ? this.overlay.encryptionKey : this.read.getEncryptionKey()
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async getDataInfo () {
|
|
125
|
+
return this.overlay.dataInfo !== null ? this.overlay.dataInfo : this.read.getDataInfo()
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async getUserData (key) {
|
|
129
|
+
return this.overlay.userData !== null && this.overlay.userData.has(key)
|
|
130
|
+
? this.overlay.userData.get(key)
|
|
131
|
+
: this.read.getUserData(key)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async hasBlock (index) {
|
|
135
|
+
if (this.overlay.blocks !== null && index >= this.overlay.blocks.offset) {
|
|
136
|
+
const blk = this.overlay.blocks.get(index)
|
|
137
|
+
if (blk.valid) return true
|
|
138
|
+
}
|
|
139
|
+
return this.read.hasBlock(index)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async getBlock (index, error) {
|
|
143
|
+
if (this.overlay.blocks !== null && index >= this.overlay.blocks.offset) {
|
|
144
|
+
const blk = this.overlay.blocks.get(index)
|
|
145
|
+
if (blk.valid) return blk.value
|
|
146
|
+
}
|
|
147
|
+
return this.read.getBlock(index, error)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async hasTreeNode (index) {
|
|
151
|
+
return this.overlay.treeNodes !== null
|
|
152
|
+
? this.overlay.treeNodes.has(index)
|
|
153
|
+
: this.read.hasTreeNode(index)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async getTreeNode (index, error) {
|
|
157
|
+
return this.overlay.treeNodes !== null && this.overlay.treeNodes.has(index)
|
|
158
|
+
? this.overlay.treeNodes.get(index)
|
|
159
|
+
: this.read.getTreeNode(index, error)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async getBitfieldPage (index) {
|
|
163
|
+
if (this.overlay.bitfields !== null && index >= this.overlay.bitfields.offset) {
|
|
164
|
+
const page = this.overlay.bitfields.get(index)
|
|
165
|
+
if (page.valid) return page.value
|
|
166
|
+
}
|
|
167
|
+
return this.read.getBitfieldPage(index)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
destroy () {
|
|
171
|
+
this.read.destroy()
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
flush () {
|
|
175
|
+
return this.read.flush()
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
tryFlush () {
|
|
179
|
+
this.read.tryFlush()
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
class MemoryOverlayWriteBatch {
|
|
184
|
+
constructor (storage) {
|
|
185
|
+
this.storage = storage
|
|
186
|
+
this.overlay = new MemoryOverlay()
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
setCoreHead (head) {
|
|
190
|
+
this.overlay.head = head
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
setCoreAuth (auth) {
|
|
194
|
+
this.overlay.auth = auth
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
setBatchPointer (name, pointer) {
|
|
198
|
+
todo()
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
setDataDependency (dependency) {
|
|
202
|
+
this.overlay.dataDependency = dependency
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
setLocalKeyPair (keyPair) {
|
|
206
|
+
this.overlay.localKeyPair = keyPair
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
setEncryptionKey (encryptionKey) {
|
|
210
|
+
this.overlay.encryptionKey = encryptionKey
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
setDataInfo (info) {
|
|
214
|
+
this.overlay.dataInfo = info
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
setUserData (key, value) {
|
|
218
|
+
if (this.overlay.userData === null) this.overlay.userData = new Map()
|
|
219
|
+
this.overlay.userData.set(key, value)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
putBlock (index, data) {
|
|
223
|
+
if (this.overlay.blocks === null) this.overlay.blocks = new TipList()
|
|
224
|
+
this.overlay.blocks.put(index, data)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
deleteBlock (index) {
|
|
228
|
+
todo()
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
deleteBlockRange (start, end) {
|
|
232
|
+
if (this.overlay.blocks === null) this.overlay.blocks = new TipList()
|
|
233
|
+
this.overlay.blocks.delete(start, end)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
putTreeNode (node) {
|
|
237
|
+
if (this.overlay.treeNodes === null) this.overlay.treeNodes = new Map()
|
|
238
|
+
this.overlay.treeNodes.set(node.index, node)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
deleteTreeNode (index) {
|
|
242
|
+
todo()
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
deleteTreeNodeRange (start, end) {
|
|
246
|
+
todo()
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
putBitfieldPage (index, page) {
|
|
250
|
+
if (this.overlay.bitfields === null) this.overlay.bitfields = new TipList()
|
|
251
|
+
this.overlay.bitfields.put(index, page)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
deleteBitfieldPage (index) {
|
|
255
|
+
todo()
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
deleteBitfieldPageRange (start, end) {
|
|
259
|
+
if (this.overlay.bitfields === null) this.overlay.bitfields = new TipList()
|
|
260
|
+
this.overlay.bitfields.delete(start, end)
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
destroy () {}
|
|
264
|
+
|
|
265
|
+
flush () {
|
|
266
|
+
this.storage.merge(this.overlay)
|
|
267
|
+
return Promise.resolve()
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function mergeMap (a, b) {
|
|
272
|
+
if (a === null) return b
|
|
273
|
+
for (const [key, value] of b) a.set(key, value)
|
|
274
|
+
return a
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function mergeTip (a, b) {
|
|
278
|
+
if (a === null) return b
|
|
279
|
+
a.merge(b)
|
|
280
|
+
return a
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function todo () {
|
|
284
|
+
throw ASSERTION('Not supported yet, but will be')
|
|
285
|
+
}
|
package/lib/tip-list.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
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 && 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
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hypercore-storage",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.23",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"files": [
|
|
6
6
|
"index.js",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"b4a": "^1.6.6",
|
|
17
17
|
"compact-encoding": "^2.15.0",
|
|
18
18
|
"flat-tree": "^1.10.0",
|
|
19
|
+
"hypercore-errors": "^1.3.0",
|
|
19
20
|
"index-encoder": "^3.0.1",
|
|
20
21
|
"nanoassert": "^2.0.0",
|
|
21
22
|
"read-write-mutexify": "^2.1.0",
|