hypercore 10.0.0-alpha.41 → 10.0.0-alpha.44
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 +70 -31
- package/lib/replicator.js +8 -4
- 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,17 +191,13 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
191
191
|
|
|
192
192
|
s._passCapabilities(this)
|
|
193
193
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if (
|
|
198
|
-
!s.encryption ||
|
|
199
|
-
!b4a.equals(s.encryption.key, opts.encryptionKey)
|
|
200
|
-
) {
|
|
201
|
-
s.encryption = new BlockEncryption(opts.encryptionKey, s.key)
|
|
202
|
-
}
|
|
194
|
+
// Configure the cache unless explicitly disabled.
|
|
195
|
+
if (opts.cache !== false) {
|
|
196
|
+
s.cache = opts.cache === true || !opts.cache ? this.cache : opts.cache
|
|
203
197
|
}
|
|
204
198
|
|
|
199
|
+
ensureEncryption(s, opts)
|
|
200
|
+
|
|
205
201
|
this.sessions.push(s)
|
|
206
202
|
|
|
207
203
|
return s
|
|
@@ -229,6 +225,8 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
229
225
|
this.storage = from.storage
|
|
230
226
|
this.replicator.findingPeers += this._findingPeers
|
|
231
227
|
|
|
228
|
+
ensureEncryption(this, opts)
|
|
229
|
+
|
|
232
230
|
this.sessions.push(this)
|
|
233
231
|
}
|
|
234
232
|
|
|
@@ -275,6 +273,9 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
275
273
|
this.encodeBatch = opts.encodeBatch
|
|
276
274
|
}
|
|
277
275
|
|
|
276
|
+
// Start continous replication if not in sparse mode.
|
|
277
|
+
if (!this.sparse) this.download({ start: 0, end: -1 })
|
|
278
|
+
|
|
278
279
|
// This is a hidden option that's only used by Corestore.
|
|
279
280
|
// It's required so that corestore can load a name from userData before 'ready' is emitted.
|
|
280
281
|
if (opts._preready) await opts._preready(this)
|
|
@@ -415,21 +416,27 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
415
416
|
}
|
|
416
417
|
|
|
417
418
|
get length () {
|
|
418
|
-
return this._snapshot
|
|
419
|
-
|
|
420
|
-
|
|
419
|
+
if (this._snapshot) return this._snapshot.length
|
|
420
|
+
if (this.core === null) return 0
|
|
421
|
+
if (!this.sparse) return this.contiguousLength
|
|
422
|
+
return this.core.tree.length
|
|
421
423
|
}
|
|
422
424
|
|
|
423
425
|
get byteLength () {
|
|
424
|
-
return this._snapshot
|
|
425
|
-
|
|
426
|
-
|
|
426
|
+
if (this._snapshot) return this._snapshot.byteLength
|
|
427
|
+
if (this.core === null) return 0
|
|
428
|
+
if (!this.sparse) return this.contiguousByteLength
|
|
429
|
+
return this.core.tree.byteLength - (this.core.tree.length * this.padding)
|
|
427
430
|
}
|
|
428
431
|
|
|
429
432
|
get contiguousLength () {
|
|
430
433
|
return this.core === null ? 0 : this.core.header.contiguousLength
|
|
431
434
|
}
|
|
432
435
|
|
|
436
|
+
get contiguousByteLength () {
|
|
437
|
+
return 0
|
|
438
|
+
}
|
|
439
|
+
|
|
433
440
|
get fork () {
|
|
434
441
|
return this.core === null ? 0 : this.core.tree.fork
|
|
435
442
|
}
|
|
@@ -587,33 +594,57 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
587
594
|
if (this.closing !== null) throw SESSION_CLOSED()
|
|
588
595
|
if (this._snapshot !== null && index >= this._snapshot.compatLength) throw SNAPSHOT_NOT_AVAILABLE()
|
|
589
596
|
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
597
|
+
const encoding = (opts && opts.valueEncoding && c.from(codecs(opts.valueEncoding))) || this.valueEncoding
|
|
598
|
+
|
|
599
|
+
let req = this.cache && this.cache.get(index)
|
|
600
|
+
if (!req) req = this._get(index, opts)
|
|
601
|
+
|
|
602
|
+
let block = await req
|
|
603
|
+
if (!block) return null
|
|
604
|
+
|
|
605
|
+
if (this.encryption) {
|
|
606
|
+
// Copy the block as it might be shared with other sessions.
|
|
607
|
+
block = b4a.from(block)
|
|
608
|
+
|
|
609
|
+
this.encryption.decrypt(index, block)
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
return this._decode(encoding, block)
|
|
596
613
|
}
|
|
597
614
|
|
|
598
615
|
async _get (index, opts) {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
let block
|
|
616
|
+
let req
|
|
602
617
|
|
|
603
618
|
if (this.core.bitfield.get(index)) {
|
|
604
|
-
|
|
619
|
+
req = this.core.blocks.get(index)
|
|
620
|
+
|
|
621
|
+
if (this.cache) this.cache.set(index, req)
|
|
605
622
|
} else {
|
|
606
623
|
if (opts && opts.wait === false) return null
|
|
607
624
|
if (opts && opts.onwait) opts.onwait(index)
|
|
608
625
|
|
|
609
626
|
const activeRequests = (opts && opts.activeRequests) || this.activeRequests
|
|
610
|
-
const req = this.replicator.addBlock(activeRequests, index)
|
|
611
627
|
|
|
612
|
-
|
|
628
|
+
req = this._cacheOnResolve(
|
|
629
|
+
index,
|
|
630
|
+
this.replicator
|
|
631
|
+
.addBlock(activeRequests, index)
|
|
632
|
+
.promise,
|
|
633
|
+
this.core.tree.fork
|
|
634
|
+
)
|
|
613
635
|
}
|
|
614
636
|
|
|
615
|
-
|
|
616
|
-
|
|
637
|
+
return req
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
async _cacheOnResolve (index, req, fork) {
|
|
641
|
+
const block = await req
|
|
642
|
+
|
|
643
|
+
if (this.cache && fork === this.core.tree.fork) {
|
|
644
|
+
this.cache.set(index, Promise.resolve(block))
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
return block
|
|
617
648
|
}
|
|
618
649
|
|
|
619
650
|
createReadStream (opts) {
|
|
@@ -765,7 +796,7 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
765
796
|
}
|
|
766
797
|
|
|
767
798
|
_decode (enc, block) {
|
|
768
|
-
block = block.subarray(this.padding)
|
|
799
|
+
if (this.padding) block = block.subarray(this.padding)
|
|
769
800
|
if (enc) return c.decode(enc, block)
|
|
770
801
|
return block
|
|
771
802
|
}
|
|
@@ -797,3 +828,11 @@ function preappend (blocks) {
|
|
|
797
828
|
this.encryption.encrypt(offset + i, blocks[i], fork)
|
|
798
829
|
}
|
|
799
830
|
}
|
|
831
|
+
|
|
832
|
+
function ensureEncryption (core, opts) {
|
|
833
|
+
if (!opts.encryptionKey) return
|
|
834
|
+
// Only override the block encryption if its either not already set or if
|
|
835
|
+
// the caller provided a different key.
|
|
836
|
+
if (core.encryption && b4a.equals(core.encryption.key, opts.encryptionKey)) return
|
|
837
|
+
core.encryption = new BlockEncryption(opts.encryptionKey, core.key)
|
|
838
|
+
}
|
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
|
|
|
@@ -906,9 +910,9 @@ module.exports = class Replicator {
|
|
|
906
910
|
}
|
|
907
911
|
|
|
908
912
|
addRange (session, { start = 0, end = -1, length = toLength(start, end), blocks = null, linear = false } = {}) {
|
|
909
|
-
if (blocks !== null) {
|
|
910
|
-
|
|
911
|
-
|
|
913
|
+
if (blocks !== null) { // if using blocks, start, end just acts as frames around the blocks array
|
|
914
|
+
start = 0
|
|
915
|
+
end = length = blocks.length
|
|
912
916
|
}
|
|
913
917
|
|
|
914
918
|
const r = new RangeRequest(this._ranges, start, length === -1 ? -1 : start + length, linear, blocks)
|
|
@@ -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
|
}
|