Docs: build hash grammar, theme rollback, reference-identity change detection, option-list boundary rule

This commit is contained in:
2026-06-12 21:53:42 +03:00
parent 5fe5aed50f
commit af9cc8a716
4 changed files with 48 additions and 12 deletions
+19
View File
@@ -351,6 +351,23 @@ test('deleting the active snippet selects the next one', () => {
> action. Local, throwaway UI state (a dropdown's open flag) may stay in component
> `useState`; anything another component reads belongs in a store behind an action.
### Change detection: reference identity, not serialization
Because every action replaces a state object via spread (never mutates it),
"has this changed since X" is **reference identity** against the object captured
at X. The Chart Builder's dataset switch keeps the exact config `init` produced
(`initialConfig`) and asks `config === initialConfig` to tell an untouched
opening default from built-on work. Field-level comparison against the source
record (the Theme Builder's draft-dirty selector) is the equivalent for forms
seeded from a saved record.
> Rule: never detect change by serializing and comparing
> (`JSON.stringify(a) === JSON.stringify(b)`) — it silently depends on key
> order, costs proportionally to state size, and a store that replaces objects
> immutably already has a cheaper, exact signal. The one sanctioned
> serialization is the modal coordinator's unsaved-change **snapshot**
> (architecture 03), where a cross-store, store-agnostic baseline is the point.
---
## 5. Effects: Persistence and External Sync
@@ -518,3 +535,5 @@ reset: () => set({ snippets: [], activeSnippetId: null, draftSpec: '' });
- Don't touch IndexedDB/`localStorage`/URL adapters from components.
- Don't thread global state down through props; don't pass per-instance or
presentational data via store imports.
- Don't detect change by serialize-and-compare; immutable replacement makes
reference identity the exact, cheap signal (§4 → Change detection).