import type { EdgeBatch } from './range_indexer.js' /** An EdgeBatch as JSON: chunk payloads in base64. */ export type WireBatch = Omit & { releases: (Omit & { payload: string })[] samples: (Omit & { payload: string })[] } export function toWire(batch: EdgeBatch): WireBatch { return { ...batch, releases: batch.releases.map((r) => ({ ...r, payload: r.payload.toString('base64') })), samples: batch.samples.map((s) => ({ ...s, payload: s.payload.toString('base64') })), } } /** Strings without NUL: Postgres takes it in neither text nor jsonb, and a file name with one failed every batch of its range (LOG.md 2026-10-10 (3)). */ function withoutNul(value: T): T { if (typeof value === 'string') return (value.includes('\u0000') ? value.replaceAll('\u0000', '') : value) as T if (Array.isArray(value)) return value.map(withoutNul) as T if (value && typeof value === 'object') { const out: Record = {} for (const [k, v] of Object.entries(value)) out[k] = withoutNul(v) return out as T } return value } export function fromWire(raw: WireBatch): EdgeBatch { const wire = withoutNul(raw) return { ...wire, releases: wire.releases.map((r) => ({ ...r, payload: Buffer.from(r.payload, 'base64') })), samples: wire.samples.map((s) => ({ ...s, payload: Buffer.from(s.payload, 'base64') })), } }