fw-01 — Broader Ideas
Where the guards reappear
| Guard | Same bug elsewhere |
|---|---|
| Listener snapshot | event emitters, animation-frame callbacks, observer lists, live NodeList iteration |
| Re-entrancy guard | any callback that can trigger the thing that invoked it |
| Immutability for change detection | React props, layout results (bi-08), display items (bi-09) |
Iterating a collection that callbacks can mutate is a bug class, not an edge case. Having hit it once here, you will recognise it in unfamiliar code.
Narrow API over powerful API
applyMiddleware is an enhancer, packaged so the common case is easy. Middleware has a trivially
composable signature; enhancers are strictly more powerful and easy to make mutually incompatible.
That pattern — constrained interface for the 95% case, escape hatch for the rest, the former
implemented in terms of the latter — is one you will design yourself. Compare useState on
useReducer, or CSS custom properties versus Houdini.
The state-at-a-moment property
Explicit-update models make "the whole state at time T" a first-class value. Time travel, serialisation, undo, crash-report state dumps, and deterministic replay all follow from it — and none of them follow from update efficiency.
When you choose a state architecture, ask whether you will ever need to reproduce a user's exact
state. If yes, that requirement outranks per-update cost, and this is the trade fw-03 makes in
the other direction.
Next
fw-02 is the consumer that makes Redux's notify-everyone default expensive; fw-03 is the opposite
architecture; §47 is where you write the comparison rather than accept one.