UNPKG

cobox-group

Version:

a p2p private group for files and application-layer data

98 lines (82 loc) 2.56 kB
const Indexer = require('kappa-sparse-indexer') const Query = require('kappa-view-query') const sub = require('subleveldown') const { Header } = require('hypertrie/lib/messages') 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('cobox-crypto') const debug = require('debug')('cobox-group: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 = 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) }) }) } _open (callback) { } _validator (msg) { var value = tryDecode(msg.value) if (!value) return false msg.value = value debug(this._id, msg) return msg } } module.exports = (...args) => new StateHandler(...args) module.exports.StateHandler = StateHandler