Every record of one layer, via the composed key — no secondary index needed.
Records in a given sync state, across every layer.
Writes a pulled batch in ONE transaction, skipping every record that holds unsynchronised local work.
🛑 The rule lives here, and not in the caller, because get and put above open
SEPARATE transactions: reading the state in the orchestrator and writing after it
would leave a window in which the optimistic write lands between the two
— and property 1 of the sync contract ("a capture never silently disappears") would
hold only by timing.
A record is skipped when it already exists with syncState !== "synced" (preserved),
or when it is synced and the source serves it under the very marker already stored
(unchanged). Everything else is inserted or rewritten.
tombstones are entities the source served as DELETED: never written, their stored copy
is removed when it is synced (removed) and kept when it holds local work
(preserved) — in the same transaction, under the same identity resolution.
⚠️ Each record carries the source that served it (sourceKey). A copy another source
served is never unchanged — it is rewritten, and becomes this source's — and a
tombstone never removes it: that source's deletion says nothing of this one's rows.
Optionaltombstones: readonly FeatureRecord[]Removes, in ONE transaction, every record of layerId that keep does not name, is
synced, and carries a server identity — what a complete pull did not return.
🛑 Local work is never removed, and neither is what has no server identity. A record
holding an unsynchronised capture is not synced; an entity created here has no row to
be absent from. The state is read in the same transaction as the removal, for the reason
putManyPreservingLocal gives: an optimistic write must not slip between the two.
⚠️ With sourceKey, only that source's records are candidates, and those written before
records carried one: what another source served on a layer of the same id is not this
pull's answer to judge. Without it, every record of the layer is, as before.
OptionalsourceKey: stringHow many records were removed.
Public API of the features store.