autobee 2.11.4 → 2.11.6

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
@@ -691,10 +691,14 @@ module.exports = class Autobee extends ReadyResource {
691
691
  const latest = await this.writers.getLatestLocalOplog()
692
692
  const views = latest ? latest.views : null
693
693
 
694
+ const from = this._workingBee.head()
694
695
  await this._reindexBee(this._workingBee, views ? views.view : null)
695
696
  this.bee.move(this._workingBee.head())
696
697
 
697
- await this._reindexBee(this.system.bee, views ? views.system : null)
698
+ const map = await migrations.mapReindexedView(this, from, REINDEX_PREFETCH)
699
+ await this._reindexBee(this.system.bee, views ? views.system : null, map)
700
+
701
+ await this.system.reset()
698
702
 
699
703
  this._reindexed = true
700
704
  }
@@ -709,7 +713,7 @@ module.exports = class Autobee extends ReadyResource {
709
713
  return !(await this._shouldReindex(view.key))
710
714
  }
711
715
 
712
- async _reindexBee(bee, flushed) {
716
+ async _reindexBee(bee, flushed, map = null) {
713
717
  const head = bee.head()
714
718
  const local = bee.context.local
715
719
  if (head === null) return
@@ -721,7 +725,8 @@ module.exports = class Autobee extends ReadyResource {
721
725
  }
722
726
 
723
727
  await bee.reindex(async (change) => !(await this._shouldReindex(change.head.key)), {
724
- prefetch: REINDEX_PREFETCH
728
+ prefetch: REINDEX_PREFETCH,
729
+ map
725
730
  })
726
731
  bee.move({ key: local.key, length: local.length })
727
732
  }
@@ -1660,17 +1665,16 @@ module.exports = class Autobee extends ReadyResource {
1660
1665
  const hints = await this._applyWakeupHints()
1661
1666
  if (hints.length) this._queueFastForward(hints)
1662
1667
 
1663
- const remaining = deadline - Date.now()
1664
- if (remaining <= 0 || this.fastForwardTo !== null) return
1665
-
1668
+ // the search bounds its own reads, so it always settles
1666
1669
  if (this._ffSearching !== null) {
1667
- await Promise.race([this._ffSearching, this._bumpSignal.wait(remaining)])
1668
- this._bumpSignal.notify()
1669
- if (this._ffSearching === null) return
1670
- continue
1670
+ await this._ffSearching
1671
+ return
1671
1672
  }
1672
1673
 
1673
- if (hints.length) return
1674
+ if (hints.length || this.fastForwardTo !== null) return
1675
+
1676
+ const remaining = deadline - Date.now()
1677
+ if (remaining <= 0) return
1674
1678
 
1675
1679
  await this._bumpSignal.wait(remaining)
1676
1680
  }
package/lib/migrations.js CHANGED
@@ -6,6 +6,7 @@ const { decodeBlock } = require('hyperbee2/lib/encoding.js')
6
6
  const { AutobeeEncryption } = require('./encryption.js')
7
7
  const encoding = require('./encoding.js')
8
8
  const { assert, bail } = require('./asserts.js')
9
+ const { LEGACY_AUTOBASE_VERSION } = require('./constants.js')
9
10
 
10
11
  const { getEncoding } = require('../encoding/spec/autobee')
11
12
 
@@ -15,6 +16,7 @@ const SystemInfoV2 = getEncoding('@autobase-compat/info-v2')
15
16
  const EMPTY = b4a.alloc(0)
16
17
  const INDEX_VERSION = 1
17
18
  const INFO = b4a.from([0x00, 0x00, 0x69, 0x6e, 0x66, 0x6f])
19
+ const INFO_V3 = b4a.from([0])
18
20
  const [NS_SIGNER_NAMESPACE] = crypto.namespace('autobase', 1)
19
21
 
20
22
  module.exports = {
@@ -23,6 +25,7 @@ module.exports = {
23
25
  checkAutobaseMigration,
24
26
  readLegacySystemInfo,
25
27
  inflateLegacyOplog,
28
+ mapReindexedView,
26
29
  coreLength
27
30
  }
28
31
 
@@ -381,3 +384,51 @@ async function viewsReached(store, info) {
381
384
  }
382
385
  return true
383
386
  }
387
+
388
+ // the reindex copies the view batch for batch, so old and new heads line up
389
+ async function mapReindexedView(auto, from, prefetch) {
390
+ const bee = auto._workingBee
391
+ const to = bee.head()
392
+
393
+ if (from === null || to === null || b4a.equals(from.key, to.key)) return null
394
+
395
+ const olds = []
396
+ for await (const { head } of bee.createChangesStream({ head: from, prefetch })) {
397
+ if (!(await auto._shouldReindex(head.key))) break
398
+ olds.push(head)
399
+ }
400
+
401
+ const news = []
402
+ for await (const { head } of bee.createChangesStream({ head: to })) {
403
+ if (news.length === olds.length) break
404
+ news.push(head)
405
+ }
406
+
407
+ assert(news.length === olds.length, 'Reindexed view is missing changes')
408
+
409
+ const moved = new Map()
410
+ const empty = { key: to.key, length: 0 }
411
+
412
+ for (let i = 0; i < olds.length; i++) {
413
+ moved.set(headId(olds[i]), news[i])
414
+ }
415
+
416
+ return function (key, value) {
417
+ if (!b4a.equals(key, INFO_V3) && !b4a.equals(key, INFO)) return null
418
+
419
+ const info = encoding.decodeSystemInfo(value)
420
+ if (info.version <= LEGACY_AUTOBASE_VERSION) return null
421
+ if (!info.view || !info.view.key) return null
422
+
423
+ // an empty view is recorded under the local key of whoever flushed it
424
+ const view = info.view.length === 0 ? empty : moved.get(headId(info.view))
425
+ if (!view) return null
426
+
427
+ info.view = view
428
+ return encoding.encodeSystemInfo(info)
429
+ }
430
+ }
431
+
432
+ function headId(head) {
433
+ return b4a.toString(head.key, 'hex') + ':' + head.length
434
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autobee",
3
- "version": "2.11.4",
3
+ "version": "2.11.6",
4
4
  "description": "Bee based autobase",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Holepunch Inc.",
@@ -26,7 +26,7 @@
26
26
  "autobee-wakeup": "^1.1.3",
27
27
  "b4a": "^1.8.0",
28
28
  "compact-encoding": "^3.4.0",
29
- "hyperbee2": "^2.17.1",
29
+ "hyperbee2": "^2.18.0",
30
30
  "hypercore": "^11.37.0",
31
31
  "hypercore-id-encoding": "^1.3.0",
32
32
  "hyperschema": "^1.26.2",