Append unique ids (e.g. infinite scroll) while merging meta; dedupes id order.
Clear sync metadata for one entity.
Drop all patches for an entity (e.g. after successful mutation when server data is authoritative).
Normalized server-confirmed records. Mutate only via upsert/replace/remove — not from components.
Per-entity fetch lifecycle keyed as ${type}:${id}.
Merge one fetched page, mark every row fetched, and update its list projections in one Zustand publication.
Insert or move an id in one list. If the id already exists, it is removed first then re-inserted at position.
"start", "end", or numeric index
Mark one or all entities of a type stale for subscriber-driven refetch. Does not delete data.
Optionalid: string
Omit to stale every entity of type
Mark lists stale by key prefix or custom predicate so the next access triggers background refresh without dropping ids immediately.
Convenience: stale all entities of a type and lists whose keys start with type.
List slots keyed by serialized query keys. Values hold id arrays and pagination — not entity clones.
Merge UI-only fields into patches so every subscriber sees selection, expansion, optimistic toggles, etc., without forking canonical data.
Local-only fields merged at read time (readEntity / hooks). Never send patches to the server.
Prepend ids (e.g. “new item at top”) with optional meta merge.
Single read path: { ...entities[type][id], ...patches[type][id] } or null if no canonical row exists.
Merged view suitable for rendering; not a deep clone
Sync-aware read path: canonical entity + patches + virtual sync metadata ($synced, $origin, $updatedAt).
Remove canonical entity, its patches, and its entityState. Does not remove the id from lists — use removeIdFromAllLists if needed.
After deletes, keep every list consistent by removing an id everywhere it appears and decrementing total when tracked.
Replace the canonical entity entirely (no merge). Use when the server returns a full snapshot and partial merge would leave stale keys behind.
Persist terminal fetch failure message and clear fetching — hooks surface error while leaving prior data if any.
Mark entity successfully loaded; clears error, fetching, stale, and updates lastFetched.
Reflect in-flight GET for a single entity (deduped fetches in the engine still flip this once per logical request).
Drive background revalidation: when true, hooks refetch while still showing cached readEntity data.
Merge sync metadata for one entity without polluting canonical server fields.
Record list fetch failure; clears both fetching flags.
The optional typed argument is the typed EntityError instance
(used by 2.0 hooks); when omitted only the string error field is
populated (back-compat with 1.x callers).
Initial or full list fetch in progress (not page-2+).
Pagination / “load more” in progress for the same list key.
Replace list ids and merge pagination meta after a primary list fetch (not load-more). Resets fetching flags and clears list error on success path (engine calls this after normalize).
Mark a list query stale so hooks can refetch without discarding current ids (stale-while-revalidate).
Optional sync/provenance state layered beside the canonical entity payload.
Remove specific patch keys; other patch keys remain.
Batch upsert for list endpoints — avoids N separate writes when hydrating many rows at once.
Entity kind
Pairs of id + partial/full payloads to merge
Shallow-merge data into the canonical entity. Use when the API returns partial updates or normalized fragments.
Entity kind
Entity id
Fields to merge into existing canonical data
Canonical Zustand store: entities (server truth), patches (UI-only overlay), lists (id order + list meta), and entityStates (per-entity fetch state). Framework bindings subscribe to the vanilla store; stores, adapters, and engines can read it synchronously through
graphStore.getState().