Remote / Server-derived state

Server-derived state: foldkit-surface + foldkit-remote

A Foldkit Model holds all application state. Some of it the client owns — the selected tab, a draft, the current route — and some of it is a cache of server data. foldkit-remote keeps that cache normalized and inside the Model, so server facts move through the same update as everything else. foldkit-surface is the projection layer underneath it.

  • foldkit-surface — the observation boundary: pure Model projections, field references, and Message subsets.
  • foldkit-remote — the normalized entity store, the requirement planner, and the Remote Submodel.
  • foldkit-remote-server — the Sources and authorization that answer the client.
  • foldkit-remote-drizzle — compiles selections and queries to Drizzle's typed query graph.

Remote is not a data-fetching hook. It answers one question:

What server-derived information does this feature require, what do we already know, what is missing, and how should incoming facts change the normalized Model?

The problem

Server data in a Foldkit app usually starts as ad-hoc fetching, and the usual things go wrong:

  • each view fetches what it renders, so two views fetch the same entity twice;
  • loading and error state is re-invented per view;
  • a mutation response patches some copies and misses others;
  • a retry or double-submit applies the same change twice;
  • a live update and a refetch race, and last-arrival wins;
  • "is this field missing, or is it legitimately null?" is unknowable.

The fix is a normalized cache: entities stored once by identity, field presence tracked explicitly, and every producer of new facts reconciled through one pure reducer that lives in the Model.