// The real Autobase binding. Everything above this file was provable against a Map; this is where
// it meets the linearizer, and the properties worth asserting are the ones a Map cannot show:
// a write is not state until it linearizes, and the view survives a restart because it is REBUILT
// from the ops rather than stored.
import test from 'brittle'
import fs from '#node:fs'
import os from '#node:os'
import { join } from '#node:path'
import Corestore from 'corestore'
import { RecordStore } from '../lib/record-store.js'
import { Feed } from '../lib/feed-base.js'
import { DELETED, ABSENT } from '../lib/log.js'
import { attest } from './helpers.js'
const tmp = () => fs.mkdtempSync(join(os.tmpdir(), 'favela-feed-'))
const rec = (body) => ({ frontmatter: { createdAt: '2026-09-06T00:00:00Z' }, body })
// Corestore 7.x is on the RocksDB storage engine, so storage is a directory, not RAM.
async function feed (storage = tmp()) {
const f = new Feed(new Corestore(storage), null, { store: new RecordStore(tmp()) })
await f.ready()
await f.addDevice(await attest(f))
await f.update()
return f
}
test('the founding device admits itself and becomes writable', async (t) => {
const f = await feed()
t.teardown(() => f.close())
t.alike(await f.devices(), [f.deviceKey], 'roster is exactly this device')
t.is((await f.founder()).device, f.deviceKey, 'genesis recorded in the view')
t.ok((await f.founder()).identityRoot, 'and it bound an identity root — the feed has an owner')
t.ok(f.writable, 'and the feed is writable')
})
test('a record round-trips through the linearized view', async (t) => {
const f = await feed()
t.teardown(() => f.close())
await f.put('post', 'a1', rec('hello from a real base'))
await f.update()
const r = await f.resolve('post', 'a1')
t.is(r.status, 'ok')
t.is(r.record.body, 'hello from a real base\n')
t.ok(r.pointer.$oid === null || typeof r.pointer.$oid === 'string', 'the log carries a pointer, not the record')
})
test('★ the log carries pointers, never bytes — its size does not scale with the record', async (t) => {
// NOT a threshold. A threshold only ever encodes whatever number today produced — this test
// passed by accident across the autobase→autobee port because the encoding changed underneath it.
// The actual property is that a 20KB record and a 1-byte one cost the SAME in the append-only
// core, because only the pointer is appended. A regression that inlined the record would blow the
// difference open no matter what the absolute numbers are.
const measure = async (body) => {
const f = await feed()
await f.put('post', 'a1', rec(body))
await f.update()
let bytes = 0
for (let i = 0; i < f.base.local.length; i++) {
const b = await f.base.local.get(i)
bytes += b == null ? 0 : (b.byteLength != null ? b.byteLength : Buffer.byteLength(JSON.stringify(b)))
}
const read = (await f.get('post', 'a1')).body
await f.close()
return { bytes, read }
}
const small = await measure('x')
const big = await measure('x'.repeat(20000))
t.is(big.read.length, 20001, 'the 20KB record is fully readable')
t.is(small.read.length, 2, 'and so is the small one')
t.ok(Math.abs(big.bytes - small.bytes) < 64,
'log cost is the same either way (' + small.bytes + ' vs ' + big.bytes + ' bytes)')
})
test('del is a tombstone in the view, distinct from absent', async (t) => {
const f = await feed()
t.teardown(() => f.close())
await f.put('post', 'a1', rec('x'))
await f.update()
await f.del('post', 'a1')
await f.update()
t.is((await f.resolve('post', 'a1')).status, DELETED)
t.is((await f.resolve('post', 'never')).status, ABSENT)
t.alike(await f.list(), [], 'and it leaves the listing')
})
test('list scopes by collection and skips reserved keys', async (t) => {
const f = await feed()
t.teardown(() => f.close())
await f.put('post', 'b1', rec('p'))
await f.put('like', 'a1', rec(''))
await f.update()
t.alike((await f.list()).map((x) => x.key), ['like/a1', 'post/b1'], 'roster keys never appear')
t.alike((await f.list('post')).map((x) => x.key), ['post/b1'])
})
test('★ the view is REBUILT from the ops across a restart', async (t) => {
const storage = tmp()
const records = tmp()
const a = new Feed(new Corestore(storage), null, { store: new RecordStore(records) })
await a.ready()
await a.addDevice(await attest(a))
await a.update()
await a.put('post', 'a1', rec('survives'))
await a.update()
const key = a.key
await a.close()
const b = new Feed(new Corestore(storage), key, { store: new RecordStore(records) })
await b.ready()
t.teardown(() => b.close())
await b.update()
t.is((await b.get('post', 'a1')).body, 'survives\n', 'replayed, not restored')
t.alike(await b.devices(), [b.deviceKey], 'and the roster came back with it')
})
test('⛔ the view cannot be written directly — a write is an append', async (t) => {
const f = await feed()
t.teardown(() => f.close())
await t.exception(() => f._readKv().set('post/a1', { $oid: 'x', size: 1 }))
})