// test-autobase-single.cjs - Test Autobase with single device
// This verifies the apply() function works correctly before multi-device testing
require('bare-node-runtime/global')
const path = require('bare-path')
const os = require('bare-os')
const fs = require('bare-fs')
const Corestore = require('corestore')
const Hyperbee = require('hyperbee')
const Autobase = require('autobase')
const b4a = require('b4a')
// Test storage directory
const TEST_DIR = path.join(os.homedir(), '.hyper-wallet-test', 'autobase-single')
// Clean test directory
if (fs.existsSync(TEST_DIR)) {
fs.rmSync(TEST_DIR, { recursive: true })
}
fs.mkdirSync(TEST_DIR, { recursive: true, mode: 0o700 })
/**
* View class for Autobase
* Pattern from autobase-example
*/
class View {
/**
* Open function - creates Hyperbee view
* This is called by Autobase to create the view core
*/
open(store) {
const core = store.get('view')
// Note: Don't use valueEncoding - handle JSON manually
return new Hyperbee(core, {
keyEncoding: 'utf-8',
valueEncoding: 'binary'
})
}
/**
* Apply function - processes operations from input cores
* Based on autobase examples pattern
* Note: Parse JSON manually since we're not using valueEncoding
*/
async apply(nodes, view, base) {
console.log(`📝 Applying ${nodes.length} operations...`)
const b = view.batch({ update: false })
for (const node of nodes) {
// Parse JSON manually
const value = JSON.parse(node.value)
// Handle writer management
if (value.addWriter) {
console.log(' ➕ Adding writer:', value.addWriter)
await base.addWriter(Buffer.from(value.addWriter, 'hex'))
continue
}
// Handle transaction operations
if (value.type === 'put-tx') {
console.log(' 💾 Storing tx:', value.key)
// Store value as JSON string
await b.put(value.key, JSON.stringify(value.value))
} else if (value.type === 'del-tx') {
console.log(' 🗑️ Deleting tx:', value.key)
await b.del(value.key)
}
}
await b.flush()
console.log('✅ Apply complete\n')
}
close(view) {
return view.close()
}
}
async function runTest() {
console.log('🧪 Testing Autobase Single Device\n')
console.log('Test directory:', TEST_DIR, '\n')
// Initialize Corestore
const store = new Corestore(TEST_DIR)
await store.ready()
console.log('✅ Corestore initialized')
// Get or create namespace for this autobase
// Pattern from autobase-example
const namespace = await Autobase.getLocalKey(store)
console.log('✅ Namespace key:', b4a.toString(namespace, 'hex').slice(0, 16) + '...')
// Initialize Autobase
// First param: Namespaced corestore
// Second param: bootstrap key (null for new autobase)
// Third param: View instance with open/apply/close methods
// Note: No valueEncoding - handle JSON manually
const autobase = new Autobase(store.namespace(namespace), null, new View())
await autobase.ready()
console.log('✅ Autobase initialized')
console.log(' Autobase key:', b4a.toString(autobase.key, 'hex').slice(0, 16) + '...')
console.log(' Local writer key:', b4a.toString(autobase.local.key, 'hex').slice(0, 16) + '...')
console.log(' View length:', autobase.view.length)
console.log()
// Test 1: Append a transaction
console.log('Test 1: Append transaction')
const tx1 = {
type: 'put-tx',
key: 'tx:1234567890:abc123',
value: {
hash: 'abc123',
chain: 'bitcoin',
to: 'tb1qtest',
amount: '0.001',
fee: '0.0001',
timestamp: 1234567890,
status: 'pending'
}
}
// Append as JSON string
await autobase.append(JSON.stringify(tx1))
console.log('📤 Appended operation')
// Wait for view to update
await new Promise(resolve => setTimeout(resolve, 100))
console.log(' View length after append:', autobase.view.length)
// Test 2: Read from view
console.log('\nTest 2: Read from Hyperbee view')
const entry = await autobase.view.get('tx:1234567890:abc123')
if (entry) {
const tx = JSON.parse(entry.value)
console.log('✅ Transaction found!')
console.log(' Hash:', tx.hash)
console.log(' Chain:', tx.chain)
console.log(' Amount:', tx.amount)
} else {
console.log('❌ Transaction not found!')
}
// Test 3: Append multiple transactions
console.log('\nTest 3: Append multiple transactions')
const tx2 = {
type: 'put-tx',
key: 'tx:1234567891:def456',
value: {
hash: 'def456',
chain: 'ethereum',
to: '0xtest',
amount: '0.1',
fee: '0.001',
timestamp: 1234567891,
status: 'confirmed'
}
}
const tx3 = {
type: 'put-tx',
key: 'tx:1234567892:ghi789',
value: {
hash: 'ghi789',
chain: 'bitcoin',
to: 'tb1qtest2',
amount: '0.002',
fee: '0.0001',
timestamp: 1234567892,
status: 'pending'
}
}
await autobase.append(JSON.stringify(tx2))
await autobase.append(JSON.stringify(tx3))
console.log('📤 Appended 2 more operations')
await new Promise(resolve => setTimeout(resolve, 100))
// Test 4: List all transactions
console.log('\nTest 4: List all transactions from Hyperbee')
let count = 0
for await (const entry of autobase.view.createReadStream()) {
count++
const tx = JSON.parse(entry.value)
console.log(` ${count}. ${entry.key}`)
console.log(` ${tx.chain} - ${tx.amount} - ${tx.status}`)
}
console.log(`✅ Found ${count} transactions`)
// Cleanup
await autobase.close()
await store.close()
console.log('\n✅ All tests passed!')
console.log('\n💡 The apply() function is working correctly!')
console.log(' Next: Test multi-device replication')
}
// Run the test
runTest().catch(err => {
console.error('❌ Test failed:', err)
process.exit(1)
})