// P1 verify (autobase): entry collection via the hyperdispatch router, as the
// Autobase VIEW (HyperDB.bee), with 2-writer replication.
const path = require('path'); const os = require('os'); const fs = require('fs')
const Corestore = require('corestore'); const Autobase = require('autobase'); const HyperDB = require('hyperdb')
const definition = require('../spec/state-base/contract/hyperdb')
const { Router, encode } = require('../spec/state-base/contract/hyperdispatch')
function makeRouter () {
const r = new Router()
r.add('@state/set-entry', async (rec, ctx) => { await ctx.tx.insert('@state/entries', { key: rec.key, value: rec.value, ts: rec.ts || 0 }) })
r.add('@state/del-entry', async (rec, ctx) => { await ctx.tx.delete('@state/entries', { key: rec.key }) })
return r
}
const router = makeRouter()
function open (store) { return HyperDB.bee(store.get('view'), definition, { autoUpdate: true }) }
async function apply (nodes, view) {
const tx = view.transaction()
try { for (const n of nodes) { if (Buffer.isBuffer(n.value)) await router.dispatch(n.value, { tx }) } await tx.flush() }
catch (e) { await tx.close(); throw e }
}
const baseOpts = { open, apply, valueEncoding: 'binary', optimistic: true, ackInterval: 1000, ackThreshold: 4 }
let pass = 0; let fail = 0
const ok = (c, m) => { if (c) { pass++; console.log(' ok ' + m) } else { fail++; console.log(' FAIL ' + m) } }
const tmp = (n) => { const d = path.join(os.tmpdir(), 'sbv3ab-' + n + '-' + process.pid); fs.rmSync(d, { recursive: true, force: true }); return d }
async function main () {
const dirA = tmp('A'); const storeA = new Corestore(dirA)
const a = new Autobase(storeA, null, baseOpts); await a.ready()
await a.append(encode('@state/set-entry', { key: 'world:players:m1', value: '{"level":"town"}', ts: 10 }))
await a.update()
const p = await a.view.get('@state/entries', { key: 'world:players:m1' })
ok(p && p.value === '{"level":"town"}', 'single-writer: entry applied via router (' + (p && p.value) + ')')
const dirB = tmp('B'); const storeB = new Corestore(dirB)
const b = new Autobase(storeB, a.key, baseOpts); await b.ready()
const s1 = storeA.replicate(true); const s2 = storeB.replicate(false); s1.pipe(s2).pipe(s1)
await a.update(); await b.update()
await a.append(encode('@state/set-entry', { key: 'world:settings:sky', value: '12.5', ts: 5 })); await a.update()
await a.update(); await b.update()
const sB = await b.view.get('@state/entries', { key: 'world:settings:sky' })
ok(sB && sB.value === '12.5', "2-writer: B replicates A's entry through the HyperDB view (" + (sB && sB.value) + ')')
await a.close(); await b.close()
for (const d of [dirA, dirB]) fs.rmSync(d, { recursive: true, force: true })
console.log('\n[probe] pass=' + pass + ' fail=' + fail)
process.exit(fail ? 1 : 0)
}
main().catch((e) => { console.error('[probe] THREW:', e && e.stack ? e.stack : e); process.exit(2) })