@huukhanhnguyen/model / core/renderDiff
core/renderDiff
contentKey()
contentKey(
data):string
Geometry content key. For multi-face wraps, compose FNV over per-face serializations (not one whole-brep stringify) so editing one face of a body does not re-key the entire interned table blob budget-unfriendly.
Parameters
data
Returns
string
diffDataFrame()
diffDataFrame<
T>(previous,next):FrameDiff<T>
Multiset reconcile of the previous frame's cells against the next frame's data documents. Order-independent: cells bucket by content key; each next document pops a matching cell (kept/updated) or lands in added; unclaimed cells are removed. O(previous + next).
Type Parameters
T
T
Parameters
previous
RenderCell<T>[]
next
Returns
FrameDiff<T>
documentKey()
documentKey(
data):string
Identity of the WHOLE document — the geometry AND the paint contentKey strips.
The two keys answer different questions and must not be shared. contentKey asks "is this the same SHAPE?", so it drops material/layer/name on purpose: the render diff turns "same shape, new paint" into a cheap props update. The object channel (ObjectNode) asks "did anything inside change?" (CLAUDE.md), and a FILTERED faceMaterial is exactly the case that splits them — liftable refuses to lift it, so the name bakes onto BrepFace.material inside the content, where contentKey cannot see it and the host would never repaint.
Parameters
data
Returns
string
fireFrameHooks()
fireFrameHooks<
T>(host,diff):void
Fire the crossing-into-the-scene points over one frame transition. The diff already computed the transition — added IS a mount, updated IS a props update, removed IS an unmount, kept is nothing at all — so this only brackets it; see SceneHooks (schema/renderDiff.ts) for what the six points mean, why kept has none, and why there is no insert.
PAIRING IS THE LAW, the same law the node tier states: every before gets exactly one after, including when a handler throws. A throwing handler also may not blank the rest of the frame — observers are per document, one bad one must not stop the others — but it is not swallowed either: every error is collected and rethrown as one AggregateError AFTER the whole frame has fired, by which point the caller already holds the diff it passed in.
Type Parameters
T
T
Parameters
host
diff
FrameDiff<T>
Returns
void
toRenderCell()
toRenderCell<
T>(objectData,key,data):RenderCell<T>
Build the RenderCell for a data document a host just mounted.
Type Parameters
T
T
Parameters
objectData
key
string
data
T
Returns
RenderCell<T>