Mirror / foldkit-mirror

The generic store seam

Mirror.url and Mirror.kv are convenience constructors over the kernel:

ts
Mirror.make(App, store, config)

A MirrorStore only needs:

ts
interface MirrorStore<R = never> {
  readonly read: Effect.Effect<Encoded | undefined, never, R>
  readonly write: (
    write: {
      set: Encoded
      remove: ReadonlyArray<string>
      intent: 'push' | 'replace'
    },
  ) => Effect.Effect<void, never, R>
}

Built-ins:

MirrorStore.url(...)     browser URL representation
MirrorStore.kv(...)      Effect KeyValueStore representation
MirrorStore.memory(...)  test/in-memory representation

applyToHref(href, { set, remove }) is the pure URL transformation used by the URL store.

A kernel mirror holds its writes until the Model has taken in its restore, as a key-value mirror does, with one store object as the session. A URL mirror does not: startup reduces the URL before the first write.

Most applications should use Mirror.url / Mirror.kv rather than starting at this kernel.

Limits

  • A mirror is last-write-wins. Two tabs writing one KV document do not converge; use foldkit-sync when ordering and convergence matter.
  • Arrays and objects use JSON in the URL by default; provide a codec for a more readable representation.
  • Two different mirror kinds may observe the same Model field. That is not two owners; cold-load precedence follows the URL -> KV -> initial rule above.
  • A URL mirror only touches the keys it owns. It composes with a Foldkit router's route.query(schema) when they use different keys.
  • Mirror stores have no durable operation log, conflict resolution, or multi-device synchronization.

See also