autobee 2.0.0-rc.3 → 2.0.0-rc.5

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
@@ -106,6 +106,7 @@ module.exports = class Autobee extends ReadyResource {
106
106
  this._hasUpdate = !!handlers.update
107
107
  this._needsUpdate = false
108
108
  this._ackRequired = false
109
+ this._ackedHeads = new Map()
109
110
  this._updateLocalCore = null
110
111
  this._host = new ApplyCalls(this)
111
112
  this._notifyHandler = null
@@ -477,6 +478,8 @@ module.exports = class Autobee extends ReadyResource {
477
478
  }
478
479
 
479
480
  async _drain() {
481
+ if (this._updating) await this._updating
482
+
480
483
  if (this.bootFrom) {
481
484
  await this._initFromHead(this.bootFrom)
482
485
  this.bootFrom = null
@@ -526,7 +529,15 @@ module.exports = class Autobee extends ReadyResource {
526
529
  if (this._interrupting) return
527
530
 
528
531
  if (this._needsUpdate) {
529
- await this._update(changes)
532
+ const updating = rrp()
533
+ this._updating = updating.promise
534
+
535
+ try {
536
+ await this._update(changes)
537
+ } finally {
538
+ this._updating = null
539
+ updating.resolve()
540
+ }
530
541
  }
531
542
  }
532
543
 
@@ -756,13 +767,30 @@ module.exports = class Autobee extends ReadyResource {
756
767
  _appendAck() {
757
768
  if (!this._ackRequired) return false
758
769
  if (!this.writers.writable) return false
759
- if (this.writers.attestations.length === 0) return false
760
770
 
761
771
  if (this.writers.localWriter.pending !== null) return false
762
772
 
763
773
  const links = this.system.getLinks(this.local.key)
764
774
  const t = Math.max(this._now(), this.system.timestamp)
765
775
 
776
+ let unlinked = false
777
+ for (const { key, length } of links) {
778
+ const hex = b4a.toString(key, 'hex')
779
+ const acked = this._ackedHeads.get(hex) || 0
780
+ if (length > acked) {
781
+ unlinked = true
782
+ break
783
+ }
784
+ }
785
+ if (!unlinked) {
786
+ this._ackRequired = false
787
+ return false
788
+ }
789
+
790
+ for (const { key, length } of links) {
791
+ this._ackedHeads.set(b4a.toString(key, 'hex'), length)
792
+ }
793
+
766
794
  this.writers.appendLocal(null, t, { start: 0, end: 0 }, links, false, null)
767
795
  this._ackRequired = false
768
796
  return true
@@ -1,4 +1,5 @@
1
1
  const ID = require('hypercore-id-encoding')
2
+ const b4a = require('b4a')
2
3
 
3
4
  class ApplyCalls {
4
5
  constructor(auto) {
@@ -39,7 +40,10 @@ class ApplyCalls {
39
40
 
40
41
  ackWriter(key) {
41
42
  if (typeof key === 'string') key = ID.decode(key)
42
- if (this.applying && this.applying[0].optimistic) this.auto._ackRequired = true
43
+ // acking an optimistic node means we owe it a linking node
44
+ if (this.applying && this.applying[0].optimistic && !b4a.equals(key, this.auto.local.key)) {
45
+ this.auto._ackRequired = true
46
+ }
43
47
  return this.auto.system.ackWriter(key)
44
48
  }
45
49
 
package/lib/system.js CHANGED
@@ -13,6 +13,27 @@ const INDEXER_LT = b4a.from([3])
13
13
  const EMPTY_HEAD = { length: 0, key: null }
14
14
  const EMPTY = b4a.from([])
15
15
 
16
+ class SystemSnapshot {
17
+ constructor(bee) {
18
+ this.bee = bee
19
+ }
20
+
21
+ async get(key, { timeout } = {}) {
22
+ const node = await this.bee.get(encoding.encodeSystemWriterKey(key), { timeout })
23
+ return node !== null ? encoding.decodeSystemWriter(node.key, node.value) : null
24
+ }
25
+
26
+ async has(link) {
27
+ const node = await this.get(link.key)
28
+ if (!node || node.length < link.length) return false
29
+ return true
30
+ }
31
+
32
+ close() {
33
+ return this.bee.close()
34
+ }
35
+ }
36
+
16
37
  module.exports = class Systembee {
17
38
  constructor(store, name, opts = {}) {
18
39
  this.name = name // for debuggin
@@ -230,6 +251,14 @@ module.exports = class Systembee {
230
251
  return info ? !info.isRemoved : !!optimistic
231
252
  }
232
253
 
254
+ snapshot(head = null) {
255
+ const bee =
256
+ head === null
257
+ ? this.bee.snapshot()
258
+ : this.bee.checkout({ length: head.length, key: head.key })
259
+ return new SystemSnapshot(bee)
260
+ }
261
+
233
262
  async get(key, { unflushed = false, timeout } = {}) {
234
263
  const node = await this.bee.get(encoding.encodeSystemWriterKey(key), { timeout })
235
264
  const info = node !== null ? encoding.decodeSystemWriter(node.key, node.value) : null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autobee",
3
- "version": "2.0.0-rc.3",
3
+ "version": "2.0.0-rc.5",
4
4
  "description": "Bee based autobase",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Holepunch Inc.",