export interface BatchTableEmptyResult { succeeded: T[]; failed: Array<{ target: T; error: unknown }>; } export interface BatchTableEmptyPlanItem { target: T; sql: string; } export type BatchTableEmptyFeedback = "success" | "partial" | "submitted" | "submitted-partial"; export async function buildBatchTableEmptyPlan(targets: readonly T[], buildSql: (target: T) => Promise): Promise[]> { const plan: BatchTableEmptyPlanItem[] = []; for (const target of targets) { const sql = await buildSql(target); if (!sql.trim()) throw new Error("Empty table SQL preview is unavailable"); plan.push({ target, sql }); } return plan; } export async function runBatchTableEmpty(targets: readonly T[], execute: (target: T) => Promise): Promise> { const result: BatchTableEmptyResult = { succeeded: [], failed: [] }; for (const target of targets) { try { await execute(target); result.succeeded.push(target); } catch (error) { result.failed.push({ target, error }); } } return result; } export function batchTableEmptyFeedback(result: BatchTableEmptyResult, asynchronousMutation: boolean): BatchTableEmptyFeedback { if (asynchronousMutation) return result.failed.length > 0 ? "submitted-partial" : "submitted"; return result.failed.length > 0 ? "partial" : "success"; }