Translates a neutral diff into the engine's shape, or returns null when the diff
names something the engine could not address.
🛑 null is a REFUSAL, and refusing is the only safe answer. MapLibre does not
report an unusable diff to its caller: _dispatchWorkerUpdate wraps the whole update
in a try/catch that ends in fire(new ErrorEvent(...)), so the promise it returns
RESOLVES either way — and the incompatibility is detected on the main thread only
after the worker has already applied the diff. There is no .catch() that could
rescue this downstream. Anything doubtful must therefore be refused BEFORE the call,
and the caller re-feeds the whole collection.
🛑 Every added feature is SHALLOW-COPIED, and the copy is not hygiene — it is
required twice over.
The engine mutates what it is given.promoteFeatureIds writes feature.id
and demoteFeatureIds deletes it, on the very objects handed over. Those objects
are the store's own features: passing them uncopied would let the engine add and
remove a field on GeoLeaf's state.
A top-level id is mandatory, because of an engine defect.updateData calls
mergeSourceDiffs(pending, diff) with two arguments where the function takes
three — promoteId is never passed — and the coalescing it performs hashes
add by the TOP-LEVEL feature.id (diffToHashed). Two adds coalesced while
the worker is busy, carrying their id only under properties.id, therefore both
hash under undefined, and the Map keeps one: the other is lost, silently.
Setting the top-level id makes the coalescing key correct.
A shallow copy suffices: id is the only field the engine writes, and it is at the
top level.
Translates a neutral diff into the engine's shape, or returns
nullwhen the diff names something the engine could not address.🛑
nullis a REFUSAL, and refusing is the only safe answer. MapLibre does not report an unusable diff to its caller:_dispatchWorkerUpdatewraps the whole update in atry/catchthat ends infire(new ErrorEvent(...)), so the promise it returns RESOLVES either way — and the incompatibility is detected on the main thread only after the worker has already applied the diff. There is no.catch()that could rescue this downstream. Anything doubtful must therefore be refused BEFORE the call, and the caller re-feeds the whole collection.🛑 Every added feature is SHALLOW-COPIED, and the copy is not hygiene — it is required twice over.
promoteFeatureIdswritesfeature.idanddemoteFeatureIdsdeletes it, on the very objects handed over. Those objects are the store's own features: passing them uncopied would let the engine add and remove a field on GeoLeaf's state.idis mandatory, because of an engine defect.updateDatacallsmergeSourceDiffs(pending, diff)with two arguments where the function takes three —promoteIdis never passed — and the coalescing it performs hashesaddby the TOP-LEVELfeature.id(diffToHashed). Two adds coalesced while the worker is busy, carrying their id only underproperties.id, therefore both hash underundefined, and theMapkeeps one: the other is lost, silently. Setting the top-level id makes the coalescing key correct.A shallow copy suffices:
idis the only field the engine writes, and it is at the top level.