autobee 2.0.0-rc.2 → 2.0.0-rc.4

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
@@ -105,6 +105,8 @@ module.exports = class Autobee extends ReadyResource {
105
105
  this._hasApply = !!handlers.apply
106
106
  this._hasUpdate = !!handlers.update
107
107
  this._needsUpdate = false
108
+ this._ackRequired = false
109
+ this._ackedHeads = new Map()
108
110
  this._updateLocalCore = null
109
111
  this._host = new ApplyCalls(this)
110
112
  this._notifyHandler = null
@@ -484,6 +486,8 @@ module.exports = class Autobee extends ReadyResource {
484
486
  // tracked across drain iteration
485
487
  this.system.shared = null
486
488
 
489
+ this._ackRequired = false
490
+
487
491
  const changes = this._hasUpdate ? new UpdateChanges(this) : null
488
492
  if (changes) changes.track()
489
493
 
@@ -503,7 +507,12 @@ module.exports = class Autobee extends ReadyResource {
503
507
  break // revaluate conditions...
504
508
  }
505
509
 
506
- if (!(await this._bumpPendingWriters())) break
510
+ if (await this._bumpPendingWriters()) {
511
+ this._needsUpdate = true
512
+ continue
513
+ }
514
+
515
+ if (!this._appendAck()) break
507
516
  this._needsUpdate = true
508
517
  }
509
518
 
@@ -744,6 +753,39 @@ module.exports = class Autobee extends ReadyResource {
744
753
  }
745
754
  }
746
755
 
756
+ // append a null value node to ack writer
757
+ _appendAck() {
758
+ if (!this._ackRequired) return false
759
+ if (!this.writers.writable) return false
760
+
761
+ if (this.writers.localWriter.pending !== null) return false
762
+
763
+ const links = this.system.getLinks(this.local.key)
764
+ const t = Math.max(this._now(), this.system.timestamp)
765
+
766
+ let unlinked = false
767
+ for (const { key, length } of links) {
768
+ const hex = b4a.toString(key, 'hex')
769
+ const acked = this._ackedHeads.get(hex) || 0
770
+ if (length > acked) {
771
+ unlinked = true
772
+ break
773
+ }
774
+ }
775
+ if (!unlinked) {
776
+ this._ackRequired = false
777
+ return false
778
+ }
779
+
780
+ for (const { key, length } of links) {
781
+ this._ackedHeads.set(b4a.toString(key, 'hex'), length)
782
+ }
783
+
784
+ this.writers.appendLocal(null, t, { start: 0, end: 0 }, links, false, null)
785
+ this._ackRequired = false
786
+ return true
787
+ }
788
+
747
789
  async _bumpPendingWriters() {
748
790
  if (this._catchupMigratedNodes !== null) {
749
791
  await this._bumpMigratedWriters()
@@ -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,6 +40,10 @@ class ApplyCalls {
39
40
 
40
41
  ackWriter(key) {
41
42
  if (typeof key === 'string') key = ID.decode(key)
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
+ }
42
47
  return this.auto.system.ackWriter(key)
43
48
  }
44
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.2",
3
+ "version": "2.0.0-rc.4",
4
4
  "description": "Bee based autobase",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Holepunch Inc.",