hypercore-list
Version:
An ordered collection of hypercores
83 lines (69 loc) • 2.27 kB
JavaScript
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