Skip to content
Shapemetry

@huukhanhnguyen/model / schema/renderDiff

schema/renderDiff

FrameDiff

FrameDiff<T> = { added: ObjectData[]; kept: { cell: RenderCell<T>; objectData: ObjectData; }[]; removed: RenderCell<T>[]; updated: { cell: RenderCell<T>; objectData: ObjectData; }[]; }

Type Parameters

T

T = unknown

added

added: ObjectData[]

New geometry — host builds (tessellates) a fresh object.

kept

kept: { cell: RenderCell<T>; objectData: ObjectData; }[]

Same geometry, same props — host keeps the object untouched.

cell

cell: RenderCell<T>

objectData

objectData: ObjectData

removed

removed: RenderCell<T>[]

Gone — host removes + disposes.

updated

updated: { cell: RenderCell<T>; objectData: ObjectData; }[]

Same geometry, different props — host updates material/layer/name only.

cell

cell: RenderCell<T>

objectData

objectData: ObjectData


RenderCell

RenderCell<T> = { data: T; key: string; layer?: string; material?: string; name?: string; objectData: ObjectData; }

One mounted render object in the previous frame: its content key, the props it was rendered with, and the host payload (a Three Object3D, SU entity ids, …) the host needs back on keep/update/remove.

Type Parameters

T

T = unknown

data

data: T

key

key: string

layer?

optional layer?: string

material?

optional material?: string

name?

optional name?: string

objectData

objectData: ObjectData

The data document this cell was mounted FROM. The diff itself only needs key + the props, but an unmount hook is handed a DOCUMENT like every other scene point (see SceneHooks) — so the cell keeps the one it was built from, and the previous frame's documents stay reachable for exactly one frame.


SceneHooks

SceneHooks = { afterMount?: (data) => void; afterUnmount?: (data) => void; afterUpdate?: (data) => void; beforeMount?: (data) => void; beforeUnmount?: (data) => void; beforeUpdate?: (data) => void; }

The moment a node's output CROSSES INTO THE SCENE, observed per document over a frame transition (renderDiff.ts's fireFrameHooks).

These are NODE-SIDE points, not events of a renderer. The engine says "this document entered / changed / left"; what a host does about it is the host's business. So do NOT complete the analogy with three.js — nothing here is shaped like onBeforeRender / onAfterRender / onBeforeShadow / onBeforeCompile, because those belong to ONE renderer and this kernel has to run in a viewer, an editor, headless, or under a renderer nobody has written yet.

Different words from the node tier (NodeHooks' beforeRemove/afterRemove) on purpose: a node leaving the GRAPH and a document leaving the SCENE are different events, and one node can mount and unmount many times without ever being removed.

THREE PAIRS, one per transition the diff actually computes: added → beforeMount / afterMount props-updated → beforeUpdate / afterUpdate removed → beforeUnmount / afterUnmount kept → NO point at all kept gets nothing because nothing happened — the same test that keeps a cache point out of the node tier: a moment with no value gets no name. props-updated is its own transition and not a rebuild: contentKey excludes props deliberately, so "same shape, new paint" arrives here (with the NEW document) instead of as an unmount+mount pair.

There is deliberately NO insert point. domphy separates Insert from Mount because a DOM subtree can be inserted while still detached — "in the tree" and "live" are two moments there. Here the frame IS the scene: a document is in it or it is not, so mount is ONE moment and a second point would name nothing.

A hook OBSERVES — never DECIDES, exactly as at the node tier: the return value is discarded (callHook), so a handler cannot veto a mount or rewrite what the diff decided.

afterMount?

optional afterMount?: (data) => void

Parameters

data

ObjectData

Returns

void

afterUnmount?

optional afterUnmount?: (data) => void

Parameters

data

ObjectData

Returns

void

afterUpdate?

optional afterUpdate?: (data) => void

Parameters

data

ObjectData

Returns

void

beforeMount?

optional beforeMount?: (data) => void

Parameters

data

ObjectData

Returns

void

beforeUnmount?

optional beforeUnmount?: (data) => void

Parameters

data

ObjectData

Returns

void

beforeUpdate?

optional beforeUpdate?: (data) => void

Same geometry, new material/layer/name — handed the NEW document.

Parameters

data

ObjectData

Returns

void

Last updated: 📖 4 min readEdit on GitHub