Remote / foldkit-remote

The mental model

Surface Projection → requirements → active Subscription → RemoteClient I/O
        ↑                                                    |
        └──────── read Model ← Data.reduce ← Remote Message ──┘

A Projection reads the current cache and carries requirements such as Project:p1.name and User:u7.name. An active Subscription compares those requirements with the cache, then requests missing or stale fields. The result returns as a Message; only reducing it changes what the next read sees. Rendering the same Projection twice starts no work by itself.

A Remote Projection does not fetch. It declares what server-owned facts a consumer requires. I/O happens outside render, and its results reduce back into the Model.

Four roles carry the loop, and most application code needs no more:

PieceResponsibility
Data.get / Data.live / Data.querycreate pure Projections that declare what a consumer needs
Data.subscriptionsturn the requirements of active Surfaces into reads, live subscriptions, and retention roots
Data.reducereduce returned Remote Messages into the application's Remote.Model
RemoteClientperform the actual read/query/mutate/live I/O

One rule keeps the cache coherent: Data.reduce is the only writer. Local application state changes with modifyFields inside update, like anywhere else; a server fact only enters the cache as a Remote Message. Never install cache state with a ref set: requirements, staleness and tombstones stay consistent only because every fact arrives through the reducer.

Install

bash
pnpm add foldkit-remote foldkit-entity

foldkit and effect are peer dependencies; foldkit-surface comes with the package. The server-side interpreter is foldkit-remote-server.