Remote / foldkit-remote
When it does not do what you expect
Each of these is a design of the package showing through, not a fault. The symptom names the section; the cure is one call.
Why is it still Initial?
Initial means required data is absent and nothing is fetching it, so a
spinner here hides a wiring mistake. Ask the Model:
Data.why(model, projection, { surfaces }) // the record you give Data.subscriptions
// { state: 'Initial', reason: 'NotFetching', surfaces: ['ProjectPage'],
// message: 'ProjectPage reads it and is active, yet nothing is fetching it. …' }NotObserved: no active Surface reads it. The Surface is not in the record you gaveData.subscriptions, or its params areundefinedfor this Model (the route is not there yet).NotFetching: an active Surface reads it and nothing started a request, which almost always means Remote's Subscriptions are not installed in the runtime.- Without
surfacesit can only sayUnknown. For every other state it says what the state means in words.
Data.plan(model, projection) shows whether Remote believes anything is
missing at all.
Why is it stale?
Under the default RemotePolicy.cacheFirst, a present field is never asked for
again. That is the point of a cache, and the reason a list shows what the
server said last time. To see change:
- On demand:
Data.refresh(model, projection)fromupdatemarks what the screen readsRefreshingand the active Subscription fetches it again, old value still on screen. A refresh button, a window regaining focus. - By age:
RemotePolicy.staleWhileRevalidate({ maxAge })refetches a value older thanmaxAgethe next time it is planned. - Always:
RemotePolicy.networkOnlyrequests every selected field, cached value visible meanwhile. - As it happens:
Data.liveinstead ofData.get, with a server that publishes changes; see Live data.
Connections have no age: a list re-queries when invalidated, refreshed, or
under networkOnly. See Reading, policies, and prefetch.
Why did my change disappear?
A mutation's optimistic patches are layers over the store while the request
is in flight. When the server answers, the layers come off and the cache shows
what the server said:
- It failed.
MutationFailedremoves the layers;Data.mutation(model, requestId)readsFailedwith the error. Nothing retries it: the mutation is not a durable queue, and if losing it is data loss the edit belongs tofoldkit-sync. - It succeeded, but the server's result did not include the field. The
layer came off and the store still holds the old value, until a read or the
result writes the new one. A mutation
Outputthat returns the changed entity settles this at once. - A preview shown with
Data.overlaystays untilData.lift; a settled mutation never takes it along.
See Mutations and optimistic state.
Why is it gone after navigating away?
Remote is a cache, and it forgets facts no active feature needs. Retention
roots come from the active Surfaces; after the grace period, RetentionChanged
collects everything they do not reach. A screen you left, and nothing else
reads, loses its rows, which is safe because coming back refetches them. To
keep something a screen does not read, name it in a retain entry or a
connections list; see Retention.
Why does a value the server has read Failed?
Failed with no previous and no request error means the stored value did not
decode against the Selection: the server's shape and the entity's Schema
disagree; the error is a DecodeError with the Schema's message. An
Unavailable error means the server answered without a field the Selection
names and will not answer with it; see
When a field is withheld. A failed request reads
the same way, with the request's error; see
When a read fails. A
RemoteProtocolError means the client and server disagree on
REMOTE_PROTOCOL_VERSION, and nothing is silently accepted.
Why did a live update not show?
Live events carry cursors. One behind the Model's is a duplicate and is
dropped; one ahead of the next is a gap, recorded in RemoteModel.gaps
and not applied, so the screen keeps what the server last said rather than
a history with a hole in it. The live entry then restarts the stream and
refetches what it covers; see When a stream breaks.