refactor: Route every input state mutation through one untracked gateway

The untrack()/persistAndProcess() pair was a per-function convention:
each update function had to remember both, a forgotten untrack would let
calling effects subscribe to input state (the bug fixed in 6a9a306e),
and a forgotten persistAndProcess would silently skip persistence and
re-validation. A single update(mutate) gateway now makes both structural,
and the scattered untrack calls (three of which were dead) are gone.

Also:
- Export inputState as Readonly<State> so writes outside the update
  functions are type errors instead of comment violations.
- Share the 'codeStore' key as a constant instead of two literals.
- Reuse validatedStateOf() in processState instead of duplicating the
  validated-state defaults.
- Use $state.raw for validatedCurrent: it is only ever replaced
  wholesale, so deep proxying every published state was pure overhead.

The new state.svelte.test.ts pins the invariants: update functions never
make a calling effect track input state, and every mutation persists.
Vitest needed resolve.conditions=['browser'] for those tests — it was
loading Svelte's server build, where $effect is a no-op.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sidharth Vinod
2026-06-10 23:57:01 +05:30
co-authored by Claude Fable 5
parent 59105628f4
commit d2f067a540
3 changed files with 167 additions and 55 deletions
+2
View File
@@ -33,6 +33,8 @@ export default defineConfig({
envPrefix: 'MERMAID_',
server: { port: 3000, host: true },
preview: { port: 3000, host: true },
// Vitest otherwise resolves Svelte's server build, where $effect is a no-op.
resolve: process.env.VITEST ? { conditions: ['browser'] } : undefined,
test: {
environment: 'jsdom',
// in-source testing