OverviewFilesCommitsIssuesDocsReleasesPeers

autobase-doctor / node_modules / autobase / lib / local-state.js

84 lines · javascript ref:
const c = require('compact-encoding')
const b4a = require('b4a')

const messages = require('./messages.js')

const GTE = b4a.from([messages.LINEARIZER_PREFIX])
const LT = b4a.from([messages.LINEARIZER_PREFIX + 1])

module.exports = class LocalState {
  constructor(core) {
    this.core = core
    this.tx = null
  }

  static clear(core) {
    const tx = core.state.storage.write()
    tx.deleteLocalRange(GTE, LT)
    return tx.flush()
  }

  static async moveTo(src, dst) {
    const boot = await src.getUserData('autobase/boot')
    const tx = dst.state.storage.write()

    tx.deleteLocalRange(GTE, LT)

    for await (const data of src.state.storage.createLocalStream({ gte: GTE, lt: LT })) {
      tx.putLocal(data.key, data.value)
    }

    tx.putUserData('autobase/boot', boot)

    await tx.flush()
  }

  setBootRecord(boot) {
    if (this.tx === null) this.tx = this.core.state.storage.write()

    this.tx.putUserData('autobase/boot', c.encode(messages.BootRecord, boot))
  }

  async listUpdates() {
    const updates = []

    for await (const data of this.core.state.storage.createLocalStream({ gte: GTE, lt: LT })) {
      const update = c.decode(messages.LinearizerUpdate, data.value)
      const seq = c.decode(messages.LinearizerKey, data.key)
      update.seq = seq
      updates.push(update)
    }

    return updates
  }

  clearUpdates() {
    if (this.tx === null) this.tx = this.core.state.storage.write()

    this.tx.deleteLocalRange(GTE, LT)
  }

  deleteUpdate(update) {
    if (this.tx === null) this.tx = this.core.state.storage.write()

    this.tx.deleteLocal(c.encode(messages.LinearizerKey, update.seq))
  }

  insertUpdate(update) {
    if (this.tx === null) this.tx = this.core.state.storage.write()

    this.tx.putLocal(
      c.encode(messages.LinearizerKey, update.seq),
      c.encode(messages.LinearizerUpdate, update)
    )
  }

  flush() {
    if (!this.tx) return Promise.resolve()

    const flushing = this.tx.flush()
    this.tx = null
    return flushing
  }
}