OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-vdrive / test / serve-reopen.mjs

74 lines · javascript ref:
// Publish, then reopen for serving WITHOUT the chunker — the locations index
// must carry everything needed to resolve bytes, and a stock peer must be able
// to replicate the whole drive out of the reopened one.
import { createRequire } from 'module'
const require = createRequire(import.meta.url)

const fs = require('fs')
const path = require('path')
const crypto = require('hypercore-crypto')
const Corestore = require('corestore')
const Hyperdrive = require('hyperdrive')
const { publishTree } = require('../lib/publish.cjs')
const { openDrive, closeDrive } = require('../lib/serve.cjs')
const { locationsPath } = require('../lib/locations.cjs')
const { chunk } = await import('../../hyper-overlay/lib/chunker.js')

const ROOT = process.argv[2]
const releaseDir = path.join(ROOT, 'releases')
const storeDir = path.join(ROOT, 'drive')
fs.mkdirSync(path.join(releaseDir, 'v1'), { recursive: true })

const payload = crypto.randomBytes(6 * 1024 * 1024)
const small = Buffer.from('{"name":"demo"}')
fs.writeFileSync(path.join(releaseDir, 'v1', 'app.bin'), payload)
fs.writeFileSync(path.join(releaseDir, 'v1', 'package.json'), small)

const published = await publishTree({
  storeDir,
  root: releaseDir,
  chunk,
  files: [
    { name: '/app.bin', file: path.join(releaseDir, 'v1', 'app.bin') },
    { name: '/package.json', file: path.join(releaseDir, 'v1', 'package.json') }
  ]
})

// Reopen with NO chunker in sight — everything must come from the index.
const opened = await openDrive({ storeDir, root: releaseDir })

const gotBin = await opened.drive.get('/app.bin')
const gotPkg = await opened.drive.get('/package.json')

// And a stock peer must be able to pull it out of the reopened drive.
const peerStore = new Corestore(path.join(ROOT, 'peer'))
const peerDrive = new Hyperdrive(peerStore, Buffer.from(published.key, 'hex'))
await peerDrive.ready()
const s1 = opened.store.replicate(true)
const s2 = peerStore.replicate(false)
s1.pipe(s2).pipe(s1)
await peerDrive.core.update({ wait: true })
const peerBin = await peerDrive.get('/app.bin', { timeout: 15000 }).catch(() => null)

s1.destroy()
s2.destroy()
await peerDrive.close()
await peerStore.close()
await closeDrive(opened)

console.log(
  JSON.stringify(
    {
      locationsWritten: published.locations,
      locationsLoaded: opened.locations,
      indexBytes: fs.statSync(locationsPath(storeDir)).size,
      sameKey: published.key === opened.key,
      reopenedReadsOk: gotBin !== null && gotBin.equals(payload) && gotPkg.equals(small),
      stockPeerGotBytes: peerBin !== null && peerBin.equals(payload),
      payloadBytes: payload.length
    },
    null,
    2
  )
)