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 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
- 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
- !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
- ? this._snapshot.length
420
- : (this.core === null ? 0 : this.core.tree.length)
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
- ? this._snapshot.byteLength
426
- : (this.core === null ? 0 : this.core.tree.byteLength - (this.core.tree.length * this.padding))
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 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
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
- const encoding = (opts && opts.valueEncoding && c.from(codecs(opts.valueEncoding))) || this.valueEncoding
600
-
601
- let block
614
+ let req
602
615
 
603
616
  if (this.core.bitfield.get(index)) {
604
- block = await this.core.blocks.get(index)
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
- block = await req.promise
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
- if (this.encryption) this.encryption.decrypt(index, block)
616
- return this._decode(encoding, block)
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore",
3
- "version": "10.0.0-alpha.40",
3
+ "version": "10.0.0-alpha.43",
4
4
  "description": "Hypercore 10",
5
5
  "main": "index.js",
6
6
  "scripts": {