UNPKG

hypercore-list

Version:

An ordered collection of hypercores

83 lines (69 loc) 2.27 kB
const { once } = require('events') const cenc = require('compact-encoding') const SubEncoder = require('sub-encoder') const idEnc = require('hypercore-id-encoding') const RehosterDb = require('hypercore-rehoster/db') class HypercoreList { constructor (bee) { this.bee = bee const subEncoder = new SubEncoder('collection') this.entriesEncs = { keyEncoding: subEncoder, valueEncoding: cenc.array(cenc.fixed32) } this.titleEncs = { keyEncoding: subEncoder, valueEncoding: cenc.string } this.rehosterDb = new RehosterDb(this.bee) } async setTitle (title) { await this.bee.put('TITLE', title, { ...this.titleEncs, cas: (prev, next) => prev !== next // no useless appends if it's the same }) } async getTitle () { return this._getWithWaiting('TITLE', this.titleEncs) } async setEntries (orderedEntries, { description } = {}) { if (!description) description = `List entry for ${idEnc.normalize(this.bee.key)}` if (!this.bee.opened) await this.bee.ready() const bufferEntries = [] const rehosterEntries = new Map() for (const key of orderedEntries) { bufferEntries.push(idEnc.decode(key)) rehosterEntries.set(key, { description }) } let inserted = true await this.bee.put('ENTRIES', bufferEntries, { ...this.entriesEncs, cas: (prev, next) => { if (!prev) return true // only if none exists, for simplicity (TODO:) inserted = false return false } }) if (!inserted) throw new Error('Updating the entries is not yet supported (TODO)') const synced = await this.rehosterDb.sync(rehosterEntries) if (!synced) throw new Error('Logical error in hypercore-collection.setEntries') } async getEntries () { return this._getWithWaiting('ENTRIES', this.entriesEncs) } async _getWithWaiting (key, opts = {}) { // TODO: timeout option with sensible default const watcher = await this.bee.getAndWatch(key, opts) try { if (watcher.node) { return watcher.node.value } else { await once(watcher, 'update') return watcher.node.value } } finally { await watcher.close() } } } module.exports = HypercoreList