export interface NanoVDBDeviceLossReplayPlanIR { schemaVersion: 1; visiblePageIds: readonly number[]; replayedPageIds: readonly number[]; skippedPageIds: readonly number[]; pageCount: number; residentPageCapacity: number; } function invalid(message: string): never { throw new Error(`NANOVDB_INVALID_ARGUMENT: ${message}`); } export function planNanoVDBDeviceLossReplay( visiblePageIds: readonly number[], pageCount: number, residentPageCapacity: number, ): NanoVDBDeviceLossReplayPlanIR { if (!Array.isArray(visiblePageIds)) invalid("visible page IDs must be an array"); if (!Number.isSafeInteger(pageCount) || pageCount < 1 || pageCount > 8192) invalid("page count is outside the manifest limit"); if (!Number.isSafeInteger(residentPageCapacity) || residentPageCapacity < 1 || residentPageCapacity > pageCount) { invalid("resident page capacity is outside the virtual grid"); } const visible = [...new Set(visiblePageIds.map((pageId) => { if (!Number.isSafeInteger(pageId) || pageId < 0 || pageId >= pageCount) invalid("visible page ID is outside the virtual grid"); return pageId; }))].sort((left, right) => left - right); return { schemaVersion: 1, visiblePageIds: visible, replayedPageIds: visible.slice(0, residentPageCapacity), skippedPageIds: visible.slice(residentPageCapacity), pageCount, residentPageCapacity, }; }