/**
* DeployFacade — SharedDeployRegistry-compatible facade over unified MetadataBase
*
* Implements the exact same public API as SharedDeployRegistry but delegates
* all operations to MetadataBase. Zero changes needed in route files.
*
* Key renames: app:{repoName} → deploy:{repoName}
*/
export class DeployFacade {
constructor ({ metadataBase }) {
this._meta = metadataBase
}
// ── Properties (delegate to MetadataBase) ────────────────────
get bootstrapKey () { return this._meta.key }
get bootstrapKeyHex () { return this._meta.bootstrapKeyHex }
get discoveryKey () { return this._meta.discoveryKey }
get localKey () { return this._meta.localKey }
get writable () { return this._meta.writable }
get view () { return this._meta.view }
// Expose _base for wakeup protocol compatibility
get _base () { return this._meta._base }
async ready () {}
// ── Write operations ─────────────────────────────────────────
async registerServer (serverKey, opts = {}) {
await this._meta.append({
v: 2,
ns: 'deploy',
type: 'register-server',
serverKey,
instanceUrl: opts.instanceUrl || null,
hostname: opts.hostname || null,
timestamp: Date.now()
})
}
async deployComplete (repoName, opts) {
await this._meta.append({
v: 2,
ns: 'deploy',
type: 'deploy-complete',
repoName,
commitHash: opts.commitHash,
branch: opts.branch,
channel: opts.channel || repoName,
serverKey: opts.serverKey || null,
timestamp: Date.now()
})
}
async addWriter (writerKey) {
const keyHex = Buffer.isBuffer(writerKey) ? writerKey.toString('hex') : writerKey
await this._meta.append({
v: 2,
ns: 'deploy',
type: 'add-writer',
writerKey: keyHex,
timestamp: Date.now()
})
}
// ── Read operations ──────────────────────────────────────────
async getServer (serverKey) {
return this._meta.getByKey(`server:${serverKey}`)
}
async listServers () {
return this._meta.list('server')
}
async getApp (repoName) {
return this._meta.getByKey(`deploy:${repoName}`)
}
async listApps () {
return this._meta.list('deploy')
}
async getDeployLog (repoName, opts = {}) {
await this._meta.update()
const results = []
const limit = opts.limit || 50
for await (const entry of this._meta.view.createReadStream({
gt: `deploy-log:${repoName}:`,
lt: `deploy-log:${repoName}:\xff`,
reverse: true,
limit
})) {
results.push(entry.value)
}
return results
}
// ── Lifecycle ────────────────────────────────────────────────
async replicate (stream) {
// Replication handled by MetadataBase's corestore
return stream
}
async update () {
await this._meta.update()
}
async close () {
// MetadataBase owns the Autobase lifecycle
}
}