OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-social / hyper-daemon / lib / store.js

90 lines · javascript ref:
import Corestore from 'corestore'
import Hyperbee from 'hyperbee'

class DaemonStore {
  constructor (storage) {
    this._storage = storage
    this._store = null
    this._db = null
    this._ready = false
  }

  async ready () {
    if (this._ready) return

    this._store = new Corestore(this._storage)
    const core = this._store.get({ name: 'hyper-daemon' })
    this._db = new Hyperbee(core, {
      keyEncoding: 'utf-8',
      valueEncoding: 'utf-8'
    })
    await this._db.ready()
    this._ready = true
  }

  async saveScript (id, script) {
    await this.ready()
    await this._db.put(`script/${id}`, JSON.stringify(script))
  }

  async getScript (id) {
    await this.ready()
    const node = await this._db.get(`script/${id}`)
    if (!node) return null
    try {
      return JSON.parse(node.value)
    } catch {
      return null
    }
  }

  async deleteScript (id) {
    await this.ready()
    await this._db.del(`script/${id}`)
  }

  async listScripts () {
    await this.ready()
    const scripts = []
    for await (const node of this._db.createReadStream({
      gte: 'script/',
      lt: 'script/\xff'
    })) {
      const id = node.key.slice('script/'.length)
      try {
        scripts.push({ id, ...JSON.parse(node.value) })
      } catch {}
    }
    return scripts
  }

  async logEvent (id, event) {
    await this.ready()
    const key = `log/${id}/${Date.now()}`
    await this._db.put(key, JSON.stringify(event))
  }

  async getLog (id, limit = 20) {
    await this.ready()
    const events = []
    for await (const node of this._db.createReadStream({
      gte: `log/${id}/`,
      lt: `log/${id}/\xff`,
      reverse: true,
      limit
    })) {
      try {
        events.push(JSON.parse(node.value))
      } catch {}
    }
    return events
  }

  async close () {
    if (this._store) await this._store.close()
    this._ready = false
  }
}

export { DaemonStore }