const Flume = require('flumedb') const Reduce = require('flumeview-reduce') const FlumeLog = require('flumelog-offset') const {pull, once, drain} = require('pull-stream') const codec = require('flumecodec') function ledger (state, emitter) { state.accounts = {} state.entries = [] const db = Flume(FlumeLog('.test.db', {codec: codec.json})) .use('entries', Reduce( 1, entriesReducer, null, null, [])) .use('accounts', Reduce(1, accountReducer, null, null, {})) pull(db.accounts.stream({live: true}), drain(acct => console.log('account stream:', acct))) pull(db.entries.stream({live: true}), drain(entry => console.log('entries stream:', entry))) const onDone = () => console.log('DONE') pull(db.accounts.stream(), drain(acctState => { console.log('ACCOUNT STATE', acctState) state.accounts = acctState emitter.emit.RENDER }, onDone)) pull(db.entries.stream(), drain(entryState => { console.log('ENTRY STATE', entryState) state.entries = entryState emitter.emit.RENDER }, onDone)) function onLoad () { emitter.on('accounts', onEvent) emitter.on('entries', onEvent) } function onEvent (data) { db.append(data, (err, seq) => { if (err) throw err emitter.emit(state.events.RENDER) }) } emitter.on('DOMContentLoaded', onLoad) function entriesReducer (acc, item) { if (item.type !== 'entries') return acc acc.push(item) return acc } function accountReducer (acc, item) { // TODO account for account creation of existing account if (item.type === 'entries') { const {msg} = item const debit = acc[msg.debit].debit += msg.amount const credit = acc[msg.credit].credit += msg.amount return acc } if (item.type !== 'accounts') return acc const { msg } = item if (!acc[msg.name]) { acc[msg.name] = msg return acc } Object.assign(acc[msg.name], msg) Object.assign(state.accounts[msg.name], msg) return acc } } module.exports = ledger