hypercore 10.0.0-alpha.40 → 10.0.0-alpha.43
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/README.md +9 -2
- package/index.js +69 -32
- package/lib/replicator.js +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,6 +62,7 @@ Note that `tree`, `data`, and `bitfield` are normally heavily sparse files.
|
|
|
62
62
|
{
|
|
63
63
|
createIfMissing: true, // create a new Hypercore key pair if none was present in storage
|
|
64
64
|
overwrite: false, // overwrite any old Hypercore that might already exist
|
|
65
|
+
sparse: true, // enable sparse mode, counting unavailable blocks towards core.length and core.byteLength
|
|
65
66
|
valueEncoding: 'json' | 'utf-8' | 'binary', // defaults to binary
|
|
66
67
|
encodeBatch: batch => { ... }, // optionally apply an encoding to complete batches
|
|
67
68
|
keyPair: kp, // optionally pass the public key and secret key as a key pair
|
|
@@ -235,13 +236,13 @@ Buffer containing the optional block encryption key of this core. Will be `null`
|
|
|
235
236
|
|
|
236
237
|
#### `core.length`
|
|
237
238
|
|
|
238
|
-
How many blocks of data are available on this core?
|
|
239
|
+
How many blocks of data are available on this core? If `sparse: false`, this will equal `core.contiguousLength`.
|
|
239
240
|
|
|
240
241
|
Populated after `ready` has been emitted. Will be `0` before the event.
|
|
241
242
|
|
|
242
243
|
#### `core.byteLength`
|
|
243
244
|
|
|
244
|
-
How much data is available on this core in bytes?
|
|
245
|
+
How much data is available on this core in bytes? If `sparse: false`, this will equal `core.contiguousByteLength`.
|
|
245
246
|
|
|
246
247
|
Populated after `ready` has been emitted. Will be `0` before the event.
|
|
247
248
|
|
|
@@ -251,6 +252,12 @@ How many blocks are contiguously available starting from the first block of this
|
|
|
251
252
|
|
|
252
253
|
Populated after `ready` has been emitted. Will be `0` before the event.
|
|
253
254
|
|
|
255
|
+
#### `core.contiguousByteLength`
|
|
256
|
+
|
|
257
|
+
How much data is contiguously available starting from the first block of this core?
|
|
258
|
+
|
|
259
|
+
Populated after `ready` has been emitted. Will be `0` before the event.
|
|
260
|
+
|
|
254
261
|
#### `core.fork`
|
|
255
262
|
|
|
256
263
|
What is the current fork id of this core?
|
package/index.js
CHANGED
|
@@ -66,6 +66,7 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
66
66
|
this.opened = false
|
|
67
67
|
this.closed = false
|
|
68
68
|
this.snapshotted = !!opts.snapshot
|
|
69
|
+
this.sparse = opts.sparse !== false
|
|
69
70
|
this.sessions = opts._sessions || [this]
|
|
70
71
|
this.auth = opts.auth || null
|
|
71
72
|
this.autoClose = !!opts.autoClose
|
|
@@ -151,7 +152,6 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
151
152
|
}
|
|
152
153
|
if (opts.keepAlive !== false) {
|
|
153
154
|
noiseStream.setKeepAlive(5000)
|
|
154
|
-
noiseStream.setTimeout(10000)
|
|
155
155
|
}
|
|
156
156
|
noiseStream.userData = protocol
|
|
157
157
|
}
|
|
@@ -191,16 +191,10 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
191
191
|
|
|
192
192
|
s._passCapabilities(this)
|
|
193
193
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
!this.encryption ||
|
|
199
|
-
!b4a.equals(this.encryption.key, opts.encryptionKey)
|
|
200
|
-
) {
|
|
201
|
-
this.encryption = new BlockEncryption(opts.encryptionKey, this.key)
|
|
202
|
-
}
|
|
203
|
-
}
|
|
194
|
+
// Pass on the cache unless explicitly disabled.
|
|
195
|
+
if (opts.cache !== false) s.cache = this.cache
|
|
196
|
+
|
|
197
|
+
ensureEncryption(s, opts)
|
|
204
198
|
|
|
205
199
|
this.sessions.push(s)
|
|
206
200
|
|
|
@@ -229,6 +223,8 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
229
223
|
this.storage = from.storage
|
|
230
224
|
this.replicator.findingPeers += this._findingPeers
|
|
231
225
|
|
|
226
|
+
ensureEncryption(this, opts)
|
|
227
|
+
|
|
232
228
|
this.sessions.push(this)
|
|
233
229
|
}
|
|
234
230
|
|
|
@@ -275,6 +271,9 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
275
271
|
this.encodeBatch = opts.encodeBatch
|
|
276
272
|
}
|
|
277
273
|
|
|
274
|
+
// Start continous replication if not in sparse mode.
|
|
275
|
+
if (!this.sparse) this.download({ start: 0, end: -1 })
|
|
276
|
+
|
|
278
277
|
// This is a hidden option that's only used by Corestore.
|
|
279
278
|
// It's required so that corestore can load a name from userData before 'ready' is emitted.
|
|
280
279
|
if (opts._preready) await opts._preready(this)
|
|
@@ -415,21 +414,27 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
415
414
|
}
|
|
416
415
|
|
|
417
416
|
get length () {
|
|
418
|
-
return this._snapshot
|
|
419
|
-
|
|
420
|
-
|
|
417
|
+
if (this._snapshot) return this._snapshot.length
|
|
418
|
+
if (this.core === null) return 0
|
|
419
|
+
if (!this.sparse) return this.contiguousLength
|
|
420
|
+
return this.core.tree.length
|
|
421
421
|
}
|
|
422
422
|
|
|
423
423
|
get byteLength () {
|
|
424
|
-
return this._snapshot
|
|
425
|
-
|
|
426
|
-
|
|
424
|
+
if (this._snapshot) return this._snapshot.byteLength
|
|
425
|
+
if (this.core === null) return 0
|
|
426
|
+
if (!this.sparse) return this.contiguousByteLength
|
|
427
|
+
return this.core.tree.byteLength - (this.core.tree.length * this.padding)
|
|
427
428
|
}
|
|
428
429
|
|
|
429
430
|
get contiguousLength () {
|
|
430
431
|
return this.core === null ? 0 : this.core.header.contiguousLength
|
|
431
432
|
}
|
|
432
433
|
|
|
434
|
+
get contiguousByteLength () {
|
|
435
|
+
return 0
|
|
436
|
+
}
|
|
437
|
+
|
|
433
438
|
get fork () {
|
|
434
439
|
return this.core === null ? 0 : this.core.tree.fork
|
|
435
440
|
}
|
|
@@ -587,33 +592,57 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
587
592
|
if (this.closing !== null) throw SESSION_CLOSED()
|
|
588
593
|
if (this._snapshot !== null && index >= this._snapshot.compatLength) throw SNAPSHOT_NOT_AVAILABLE()
|
|
589
594
|
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
595
|
+
const encoding = (opts && opts.valueEncoding && c.from(codecs(opts.valueEncoding))) || this.valueEncoding
|
|
596
|
+
|
|
597
|
+
let req = this.cache && this.cache.get(index)
|
|
598
|
+
if (!req) req = this._get(index, opts)
|
|
599
|
+
|
|
600
|
+
let block = await req
|
|
601
|
+
if (!block) return null
|
|
602
|
+
|
|
603
|
+
if (this.encryption) {
|
|
604
|
+
// Copy the block as it might be shared with other sessions.
|
|
605
|
+
block = b4a.from(block)
|
|
606
|
+
|
|
607
|
+
this.encryption.decrypt(index, block)
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
return this._decode(encoding, block)
|
|
596
611
|
}
|
|
597
612
|
|
|
598
613
|
async _get (index, opts) {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
let block
|
|
614
|
+
let req
|
|
602
615
|
|
|
603
616
|
if (this.core.bitfield.get(index)) {
|
|
604
|
-
|
|
617
|
+
req = this.core.blocks.get(index)
|
|
618
|
+
|
|
619
|
+
if (this.cache) this.cache.set(index, req)
|
|
605
620
|
} else {
|
|
606
621
|
if (opts && opts.wait === false) return null
|
|
607
622
|
if (opts && opts.onwait) opts.onwait(index)
|
|
608
623
|
|
|
609
624
|
const activeRequests = (opts && opts.activeRequests) || this.activeRequests
|
|
610
|
-
const req = this.replicator.addBlock(activeRequests, index)
|
|
611
625
|
|
|
612
|
-
|
|
626
|
+
req = this._cacheOnResolve(
|
|
627
|
+
index,
|
|
628
|
+
this.replicator
|
|
629
|
+
.addBlock(activeRequests, index)
|
|
630
|
+
.promise,
|
|
631
|
+
this.core.tree.fork
|
|
632
|
+
)
|
|
613
633
|
}
|
|
614
634
|
|
|
615
|
-
|
|
616
|
-
|
|
635
|
+
return req
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
async _cacheOnResolve (index, req, fork) {
|
|
639
|
+
const block = await req
|
|
640
|
+
|
|
641
|
+
if (this.cache && fork === this.core.tree.fork) {
|
|
642
|
+
this.cache.set(index, Promise.resolve(block))
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
return block
|
|
617
646
|
}
|
|
618
647
|
|
|
619
648
|
createReadStream (opts) {
|
|
@@ -765,7 +794,7 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
765
794
|
}
|
|
766
795
|
|
|
767
796
|
_decode (enc, block) {
|
|
768
|
-
block = block.subarray(this.padding)
|
|
797
|
+
if (this.padding) block = block.subarray(this.padding)
|
|
769
798
|
if (enc) return c.decode(enc, block)
|
|
770
799
|
return block
|
|
771
800
|
}
|
|
@@ -797,3 +826,11 @@ function preappend (blocks) {
|
|
|
797
826
|
this.encryption.encrypt(offset + i, blocks[i], fork)
|
|
798
827
|
}
|
|
799
828
|
}
|
|
829
|
+
|
|
830
|
+
function ensureEncryption (core, opts) {
|
|
831
|
+
if (!opts.encryptionKey) return
|
|
832
|
+
// Only override the block encryption if its either not already set or if
|
|
833
|
+
// the caller provided a different key.
|
|
834
|
+
if (core.encryption && b4a.equals(core.encryption.key, opts.encryptionKey)) return
|
|
835
|
+
core.encryption = new BlockEncryption(opts.encryptionKey, core.key)
|
|
836
|
+
}
|
package/lib/replicator.js
CHANGED
|
@@ -726,6 +726,10 @@ class Peer {
|
|
|
726
726
|
b.inflight.push(req)
|
|
727
727
|
this._send(req)
|
|
728
728
|
|
|
729
|
+
// Don't think this will ever happen, as the pending queue is drained before the range queue
|
|
730
|
+
// but doesn't hurt to check this explicitly here also.
|
|
731
|
+
if (b.queued) b.queued = false
|
|
732
|
+
|
|
729
733
|
return true
|
|
730
734
|
}
|
|
731
735
|
|
|
@@ -1054,7 +1058,7 @@ module.exports = class Replicator {
|
|
|
1054
1058
|
}
|
|
1055
1059
|
|
|
1056
1060
|
_queueBlock (b) {
|
|
1057
|
-
if (b.queued === true) return
|
|
1061
|
+
if (b.inflight.length > 0 || b.queued === true) return
|
|
1058
1062
|
b.queued = true
|
|
1059
1063
|
this._queued.push(b)
|
|
1060
1064
|
}
|