OverviewFilesCommitsIssuesDocsReleasesPeers

keet-daemon / test / probe-state-v3-autobase.cjs

48 lines · javascript ref:
// 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) })