autobee 2.0.0-rc.6 → 2.0.0-rc.7
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 +6 -1
- package/lib/system.js +76 -30
- package/lib/topo.js +1 -0
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -253,7 +253,12 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
253
253
|
view: info ? info.view : EMPTY_HEAD
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
|
|
256
|
+
// no common ancestor (null) -> flushes -1 never matches, forcing a full diff
|
|
257
|
+
const shared = (await this.system.commonAncestor(system || EMPTY_HEAD)) || {
|
|
258
|
+
flushes: -1,
|
|
259
|
+
system: EMPTY_HEAD,
|
|
260
|
+
view: EMPTY_HEAD
|
|
261
|
+
}
|
|
257
262
|
|
|
258
263
|
return UpdateChanges.from(shared, current)
|
|
259
264
|
}
|
package/lib/system.js
CHANGED
|
@@ -2,7 +2,6 @@ const Hyperbee = require('hyperbee2')
|
|
|
2
2
|
const b4a = require('b4a')
|
|
3
3
|
|
|
4
4
|
const { AUTOBEE_VERSION } = require('./constants')
|
|
5
|
-
const asserts = require('./asserts.js')
|
|
6
5
|
const encoding = require('./encoding.js')
|
|
7
6
|
const topo = require('./topo.js')
|
|
8
7
|
|
|
@@ -117,46 +116,57 @@ module.exports = class Systembee {
|
|
|
117
116
|
}
|
|
118
117
|
|
|
119
118
|
async commonAncestor(head) {
|
|
120
|
-
const info = await this.getInfo()
|
|
121
|
-
|
|
122
119
|
const snap = this.bee.checkout(head)
|
|
123
120
|
|
|
124
|
-
const
|
|
125
|
-
const
|
|
121
|
+
const ca = infoIterator(this.bee)
|
|
122
|
+
const cb = infoIterator(snap)
|
|
123
|
+
|
|
124
|
+
let l = await next(ca)
|
|
125
|
+
let r = await next(cb)
|
|
126
|
+
|
|
127
|
+
while (l && r) {
|
|
128
|
+
if (l.legacy && r.legacy) {
|
|
129
|
+
// legacy nodes just compare head
|
|
130
|
+
if (sameHead(l.node.head, r.node.head)) {
|
|
131
|
+
return {
|
|
132
|
+
flushes: l.info.flushes,
|
|
133
|
+
system: l.node.head,
|
|
134
|
+
view: l.info.view || EMPTY_HEAD
|
|
135
|
+
}
|
|
136
|
+
}
|
|
126
137
|
|
|
127
|
-
|
|
128
|
-
|
|
138
|
+
// different legacy cores never converge - genuinely unrelated history
|
|
139
|
+
if (!b4a.equals(l.node.head.key, r.node.head.key)) return null
|
|
129
140
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
141
|
+
if (l.node.head.length >= r.node.head.length) l = await next(ca)
|
|
142
|
+
else r = await next(cb)
|
|
143
|
+
continue
|
|
144
|
+
}
|
|
133
145
|
|
|
134
|
-
|
|
135
|
-
|
|
146
|
+
if (l.legacy !== r.legacy) {
|
|
147
|
+
// current-format history sits above the legacy band: descend it
|
|
148
|
+
if (!l.legacy) l = await next(ca)
|
|
149
|
+
else r = await next(cb)
|
|
150
|
+
continue
|
|
151
|
+
}
|
|
136
152
|
|
|
137
|
-
|
|
138
|
-
if (l.flushes === r.flushes && sameHead(l.view, r.view)) {
|
|
153
|
+
if (l.info.flushes === r.info.flushes && sameHead(l.info.view, r.info.view)) {
|
|
139
154
|
return {
|
|
140
|
-
flushes: l.flushes,
|
|
141
|
-
system:
|
|
142
|
-
view: l.view || EMPTY_HEAD
|
|
155
|
+
flushes: l.info.flushes,
|
|
156
|
+
system: l.node.head,
|
|
157
|
+
view: l.info.view || EMPTY_HEAD
|
|
143
158
|
}
|
|
144
159
|
}
|
|
145
160
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
a = await hist1.next()
|
|
149
|
-
if (a.value) l = getInfo(a.value)
|
|
150
|
-
}
|
|
161
|
+
const lf = l.info.flushes
|
|
162
|
+
const rf = r.info.flushes
|
|
151
163
|
|
|
152
|
-
if (
|
|
153
|
-
|
|
154
|
-
b = await hist2.next()
|
|
155
|
-
if (b.value) r = getInfo(b.value)
|
|
156
|
-
}
|
|
164
|
+
if (lf >= rf) l = await next(ca)
|
|
165
|
+
if (rf >= lf) r = await next(cb)
|
|
157
166
|
}
|
|
158
167
|
|
|
159
|
-
|
|
168
|
+
// no common ancestor
|
|
169
|
+
return null
|
|
160
170
|
}
|
|
161
171
|
|
|
162
172
|
async reset({ timeout } = {}) {
|
|
@@ -491,12 +501,16 @@ function getInfo(data) {
|
|
|
491
501
|
const prefix = k.key[0]
|
|
492
502
|
|
|
493
503
|
if (prefix === 0) {
|
|
494
|
-
|
|
504
|
+
try {
|
|
505
|
+
return encoding.decodeSystemInfo(k.value)
|
|
506
|
+
} catch {
|
|
507
|
+
return null
|
|
508
|
+
}
|
|
495
509
|
}
|
|
496
510
|
}
|
|
497
511
|
}
|
|
498
512
|
|
|
499
|
-
|
|
513
|
+
return null
|
|
500
514
|
}
|
|
501
515
|
|
|
502
516
|
function sameHead(a, b) {
|
|
@@ -504,3 +518,35 @@ function sameHead(a, b) {
|
|
|
504
518
|
if (!a.key || !b.key) return a.key === b.key
|
|
505
519
|
return b4a.equals(a.key, b.key)
|
|
506
520
|
}
|
|
521
|
+
|
|
522
|
+
async function* infoIterator(bee) {
|
|
523
|
+
try {
|
|
524
|
+
for await (const node of bee.createChangesStream()) {
|
|
525
|
+
const legacy = topo.isLegacyNode(node)
|
|
526
|
+
const info = legacy ? getLegacyInfo(node) : getInfo(node)
|
|
527
|
+
if (info) yield { node, info, legacy }
|
|
528
|
+
}
|
|
529
|
+
} catch {
|
|
530
|
+
// fall through
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
async function next(it) {
|
|
535
|
+
const res = await it.next()
|
|
536
|
+
return res.done ? null : res.value
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
function getLegacyInfo(data) {
|
|
540
|
+
for (const { keys } of data.batch) {
|
|
541
|
+
for (const k of keys) {
|
|
542
|
+
if (b4a.equals(k.key, INFO_LEGACY_KEY)) {
|
|
543
|
+
try {
|
|
544
|
+
return encoding.decodeSystemInfo(k.value)
|
|
545
|
+
} catch {
|
|
546
|
+
return null
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return null
|
|
552
|
+
}
|
package/lib/topo.js
CHANGED