Chapter 02 @dirtytalk/structural
Paths light up.
State is a tree, and every component reads a few paths of it. Structural records those reads, so a change wakes only the readers. This stage runs the real @dirtytalk/structural.
01
State is a tree of paths.
A StructuralContainer holds plain state. Every key is a path:
user.name, cart.total, theme. The tree on the
left is the live state, and nothing in it is hot yet.
02
Reads are recorded.
A component renders against a tracking proxy, and each property it touches is
recorded. Header read user.name. CartBadge
read only the length of the items. The cyan paths are what each one subscribed
to.
const { value, paths } = trackRender(state, interner);
// paths: Set { user.name }
channel.subscribe(() => paths, rerender); 03
A patch marks paths.
patch({ user: { name } }) marks the keys you gave it, plus
their parents. update(fn) and emit(next) diff the old state
against the new one, but only along paths somebody read.
container.patch({ user: { name: 'Grace' } });
container.update((s) => ({ ...s, theme: 'light' })); 04
Only readers wake.
The channel intersects the changed paths with each reader's paths. Adding an item
changes cart.items.length and cart.total, which wakes
CartBadge and Total. Header and ThemeToggle never hear about it.
05
Absent keys are tracked too.
NickTag read user.nickname, which doesn't exist yet.
The miss is recorded like any other read, so setting the key later wakes it. Changing
user.avatar, which nobody read, marks the path but wakes nobody.
container.patch({ user: { nickname: 'Ada' } }); 06
Your turn.
Fire any mutation and watch the counters: paths changed, then consumers woken out of five. Try changing the avatar, then the nickname.
0 paths changed → 0 / 5 woken