hypercore 11.20.0 → 11.20.2

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 CHANGED
@@ -605,6 +605,8 @@ class Hypercore extends EventEmitter {
605
605
 
606
606
  async setUserData(key, value) {
607
607
  if (this.opened === false) await this.opening
608
+ const existing = await this.getUserData(key)
609
+ if (existing && b4a.isBuffer(value) && b4a.equals(existing, value)) return
608
610
  await this.state.setUserData(key, value)
609
611
  }
610
612
 
package/lib/core.js CHANGED
@@ -55,6 +55,8 @@ module.exports = class Core {
55
55
  this.destroyed = false
56
56
  this.closed = false
57
57
 
58
+ this.hintsChanged = false
59
+
58
60
  this._bitfield = null
59
61
  this._verifies = null
60
62
  this._verifiesFlushed = null
@@ -282,7 +284,7 @@ module.exports = class Core {
282
284
  }
283
285
 
284
286
  const len = bitfield.findFirst(false, header.hints.contiguousLength)
285
- if (header.hints.contiguousLength !== len) {
287
+ if (header.hints.contiguousLength !== len && !storage.readOnly) {
286
288
  header.hints.contiguousLength = len
287
289
  const tx = storage.write()
288
290
  tx.setHints(header.hints)
@@ -531,6 +533,8 @@ module.exports = class Core {
531
533
  this.replicator.onhave(bitfield.start, bitfield.length, bitfield.drop)
532
534
  }
533
535
  }
536
+
537
+ if (this.hintsChanged) await this.flushHints()
534
538
  } finally {
535
539
  this.state._clearActiveBatch()
536
540
  this.state.mutex.unlock()
@@ -539,6 +543,20 @@ module.exports = class Core {
539
543
  return verifies[0] !== null
540
544
  }
541
545
 
546
+ async flushHints() {
547
+ if (!this.hintsChanged) return
548
+ this.hintsChanged = false // we unset this immediately as a "debounce"
549
+
550
+ const tx = this.state.storage.write()
551
+
552
+ tx.setHints({
553
+ contiguousLength: this.header.hints.contiguousLength,
554
+ remoteContiguousLength: this.header.hints.remoteContiguousLength
555
+ })
556
+
557
+ await tx.flush()
558
+ }
559
+
542
560
  async checkConflict(proof, from) {
543
561
  if (this.state.length < proof.upgrade.length || proof.fork !== this.state.fork) {
544
562
  // out of date this proof - ignore for now
@@ -716,13 +734,13 @@ module.exports = class Core {
716
734
 
717
735
  if (contig.length !== -1 && contig.length !== this.header.hints.contiguousLength) {
718
736
  this.header.hints.contiguousLength = contig.length
737
+ this.hintsChanged = true
719
738
  }
720
739
  }
721
740
 
722
- async updateRemoteContiguousLength(length) {
741
+ updateRemoteContiguousLength(length) {
723
742
  this.header.hints.remoteContiguousLength = length
724
- await this.state.flushHints()
725
- if (this.header.hints.remoteContiguousLength !== length) return
743
+ this.hintsChanged = true
726
744
 
727
745
  for (let i = this.monitors.length - 1; i >= 0; i--) {
728
746
  this.monitors[i].emit('remote-contiguous-length', length)
package/lib/replicator.js CHANGED
@@ -1166,7 +1166,7 @@ class Peer {
1166
1166
  this.remoteFork === this.core.state.fork &&
1167
1167
  length > this.core.header.hints.remoteContiguousLength
1168
1168
  ) {
1169
- await this.core.updateRemoteContiguousLength(length)
1169
+ this.core.updateRemoteContiguousLength(length)
1170
1170
  }
1171
1171
  }
1172
1172
  } else if (length === 1) {
@@ -1184,6 +1184,7 @@ class Peer {
1184
1184
  }
1185
1185
  }
1186
1186
 
1187
+ if (this.core.hintsChanged) await this.core.flushHints()
1187
1188
  if (drop === false) this._update()
1188
1189
  }
1189
1190
 
@@ -300,6 +300,8 @@ module.exports = class SessionState {
300
300
  const append = b ? { start: b.start, length: b.appends, drop: false } : null
301
301
 
302
302
  this.onappend(tree, append, true)
303
+
304
+ if (this.core.hintsChanged && this.isDefault()) await this.core.flushHints()
303
305
  } finally {
304
306
  this.mutex.unlock()
305
307
  this.core.checkIfIdle()
@@ -360,6 +362,8 @@ module.exports = class SessionState {
360
362
 
361
363
  this.onappend(head, bitfield, flushed)
362
364
  }
365
+
366
+ if (this.core.hintsChanged && this.isDefault()) await this.core.flushHints()
363
367
  } finally {
364
368
  this._clearActiveBatch()
365
369
  this.updating = false
@@ -419,6 +423,8 @@ module.exports = class SessionState {
419
423
  if (dependency) this.storage.setDependencyHead(dependency)
420
424
 
421
425
  this.ontruncate(tree, tree.length, batch.treeLength, flushed)
426
+
427
+ if (this.core.hintsChanged && this.isDefault()) await this.core.flushHints()
422
428
  } finally {
423
429
  this._unlock()
424
430
  }
@@ -445,6 +451,8 @@ module.exports = class SessionState {
445
451
  if (dependency) this.storage.setDependencyHead(dependency)
446
452
 
447
453
  this.ontruncate(tree, batch.ancestors, batch.treeLength, flushed)
454
+
455
+ if (this.core.hintsChanged && this.isDefault()) await this.core.flushHints()
448
456
  } finally {
449
457
  this._unlock()
450
458
  }
@@ -487,23 +495,6 @@ module.exports = class SessionState {
487
495
  return { dependency, tree, roots: batch.roots }
488
496
  }
489
497
 
490
- async flushHints() {
491
- await this.mutex.lock()
492
-
493
- try {
494
- const tx = this.createWriteBatch()
495
-
496
- tx.setHints({
497
- contiguousLength: this.core.header.hints.contiguousLength,
498
- remoteContiguousLength: this.core.header.hints.remoteContiguousLength
499
- })
500
-
501
- await tx.flush()
502
- } finally {
503
- this._unlock()
504
- }
505
- }
506
-
507
498
  async clear(start, end, cleared) {
508
499
  await this.mutex.lock()
509
500
 
@@ -548,9 +539,12 @@ module.exports = class SessionState {
548
539
  // todo: atomic event handle
549
540
  if (this.isDefault() && flushed) {
550
541
  const length = end - start
542
+
551
543
  this.core.updateContiguousLength({ start, length, drop: true })
552
544
  this.core._setBitfieldRanges(start, end, false)
553
545
  this.core.replicator.onhave(start, length, true)
546
+
547
+ if (this.core.hintsChanged) await this.core.flushHints()
554
548
  }
555
549
  } finally {
556
550
  this._unlock()
@@ -631,6 +625,8 @@ module.exports = class SessionState {
631
625
 
632
626
  this.onappend(tree, bitfield, flushed)
633
627
 
628
+ if (this.core.hintsChanged && this.isDefault()) await this.core.flushHints()
629
+
634
630
  return { length: this.length, byteLength: this.byteLength }
635
631
  } finally {
636
632
  this._unlock()
@@ -780,6 +776,8 @@ module.exports = class SessionState {
780
776
 
781
777
  if (truncating) this.ontruncate(tree, sharedLength, origLength, flushed)
782
778
  if (sharedLength < length) this.onappend(tree, null, flushed)
779
+
780
+ if (this.core.hintsChanged && this.isDefault()) await this.core.flushHints()
783
781
  } finally {
784
782
  this.mutex.unlock()
785
783
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore",
3
- "version": "11.20.0",
3
+ "version": "11.20.2",
4
4
  "description": "Hypercore is a secure, distributed append-only log",
5
5
  "main": "index.js",
6
6
  "scripts": {