Mirror / foldkit-mirror
Key-value restore semantics
A store restore is intentionally conservative. Prefs.reduce(model, message)
only restores fields that are still at their initial value.
That protects an edit made before the asynchronous restore finished:
initial draft = ''
store draft = 'remembered'
user types 'new text' before restore returns
MirrorRestored arrives
|
v
current draft is no longer initial
|
v
keep 'new text'The write Subscription starts with the initial Model, before the store has answered. Until the Model has taken in what the store holds, writing it would replace the stored document with the initial slice, so a key-value mirror holds each write until its slice is one the restore leaves unchanged:
cold load: Model at defaults, store holds { sidebar: 'closed' }
write (after the throttle) held: a restore would still change the Model
restore answers MirrorRestored -> reduce -> Model has sidebar 'closed'
write goes ahead: the Model holds what the store heldThe check is against the latest restore's answer, or, before any answer, the
store's own content at the first write, so a mirror nobody restores (a test
harness, a Model kept across a hot reload) writes once its slice agrees with
the store. An empty store holds back nothing. A read that fails answers as an empty store: MirrorRestored
carries no keys, and later writes replace whatever the store held. A second
restore holds writes again until its answer is taken in. The hold is per
runtime (per built KeyValueStore), so two runtimes never wait on each other.
When URL and KV mirrors both represent one field, cold-load precedence is:
URL value, when present
>
key-value restore
>
initial valuebecause startup reduces the URL first and the later store restore only fills fields still at their defaults.