Mirror / foldkit-mirror

Two lifecycles to remember

The URL and a key-value store represent the same ownership model, but they come back into the application at different times.

URL mirror

Model changes filter
      |
      v
Filters.subscriptions
      |
      v
history.pushState / replaceState
      |
  user navigates
      v
UrlChanged
      |
      v
Filters.reduce(model, url)
      |
      v
Model

The URL participates in navigation, so the runtime hands navigation back to the application and the mirror reduces the URL into its slice.

Key-value mirror

cold load
   |
   v
Prefs.restore Command
   |
   v
MirrorRestored Message
   |
   v
Prefs.reduce(model, message)
   |
   v
Model

later Model changes
   |
   v
Prefs.subscriptions
   |
   v
KeyValueStore

That is why the full integration has three seams:

reduce         read an external representation back into Model
restore        ask a store for its cold-load value
subscriptions  write Model changes outward

A URL mirror does not need a restore Command because the initial URL is already available to application startup. A store mirror does — unless the store's keys are already in hand at boot, in which case it bootstraps them into the initial Model instead (see "Restore before the first render with bootstrap").

Install

bash
pnpm add foldkit-mirror

foldkit and effect are peer dependencies; foldkit-surface comes with the package.