usePreview
Mutation dry-run — the {old,new} diff in a rolled-back transaction before commit.
"What will this change?" The app exposes a preview action that runs the real
handler in a transaction the framework rolls back (previewInRollback +
buildPreview from @voltro/runtime); usePreview returns the {old,new} diff
before commit. Actions (external I/O) aren't previewable — same boundary as undo.
const p = usePreview('app', 'todos.update.preview')
const diff = await p.preview({ id, title }) // { rows, summary } — nothing committed