UNPKG

@coboxcoop/space

Version:

a peer-to-peer private and encrypted space

93 lines (78 loc) 2.49 kB
const Indexer = require('kappa-sparse-indexer') const Query = require('kappa-view-query') const sub = require('subleveldown') const { fromMultifeed } = require('kappa-view-query/util') const { State } = require('kappa-drive/messages') const { scopeFeeds, tryDecode } = require('kappa-drive') const maybe = require('call-me-maybe') const { EventEmitter } = require('events') const collect = require('collect-stream') const crypto = require('@coboxcoop/crypto') const debug = require('@coboxcoop/logger')('@coboxcoop/space:state-handler') const INDEXES = [ { key: 'log', value: [['value', 'timestamp']] }, { key: 'fil', value: [['value', 'filename'], ['value', 'timestamp']] } ] class StateHandler extends EventEmitter { /** * create a drive state handler * @constructor */ constructor (opts = {}) { super() this._id = opts._id || crypto.randomBytes(2).toString('hex') this.drive = opts.drive this.core = opts.core this.feeds = opts.feeds this.db = opts.db this._validator = this._validator.bind(this) this.idx = new Indexer({ db: sub(this.db, 'idx'), name: this._id }) this.view = Query(sub(this.db, 'view'), { indexes: INDEXES, validator: this._validator, getMessage: fromMultifeed(this.feeds, { validator: this._validator }) }) this.core.use('state', this.idx.source(), this.view) this.read = this.core.view.state.read this.feeds.on('feed', (feed) => { if (this.idx.feed(feed.key)) return scopeFeeds(feed, (err) => { if (!err) this.idx.add(feed, { scan: true }) }) }) } ready (callback) { return maybe(callback, new Promise((resolve, reject) => { this.drive.ready((err) => { if (err) return reject(err) this._feed = this.drive.metadata this.core.ready('state', (err) => { if (err) return reject(err) return resolve() }) }) })) } query (query, opts = {}) { if (opts.live) return this.read({ query: [query], live: true, ...opts }) return new Promise((resolve, reject) => { collect(this.read({ query: [query] }), (err, msgs) => { if (err) return reject(err) resolve(msgs) }) }) } _validator (msg) { var value = tryDecode(msg.value) if (!value) return false msg.value = value return msg } } module.exports = (...args) => new StateHandler(...args) module.exports.StateHandler = StateHandler