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 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
- if (opts.encryptionKey) {
195
- // Only override the block encryption if its either not already set or if
196
- // the caller provided a different key.
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
- ? this._snapshot.length
420
- : (this.core === null ? 0 : this.core.tree.length)
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
- ? this._snapshot.byteLength
426
- : (this.core === null ? 0 : this.core.tree.byteLength - (this.core.tree.length * this.padding))
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 c = this.cache && this.cache.get(index)
591
- if (c) return c
592
- const fork = this.core.tree.fork
593
- const b = await this._get(index, opts)
594
- if (this.cache && fork === this.core.tree.fork && b) this.cache.set(index, b)
595
- return b
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
- const encoding = (opts && opts.valueEncoding && c.from(codecs(opts.valueEncoding))) || this.valueEncoding
600
-
601
- let block
616
+ let req
602
617
 
603
618
  if (this.core.bitfield.get(index)) {
604
- block = await this.core.blocks.get(index)
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
- block = await req.promise
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
- if (this.encryption) this.encryption.decrypt(index, block)
616
- return this._decode(encoding, block)
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
- if (start >= blocks.length) start = blocks.length
911
- if (length === -1 || start + length > blocks.length) length = blocks.length - start
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore",
3
- "version": "10.0.0-alpha.41",
3
+ "version": "10.0.0-alpha.44",
4
4
  "description": "Hypercore 10",
5
5
  "main": "index.js",
6
6
  "scripts": {