README

mizchi/crater-core/node does not have a README file

#
DispatchFn

Dispatch function type - passed through layout computation to enable cross-layout-type dispatch without global state. The function takes (node, context, dispatch) and returns Layout.

#
LayoutDispatchFunc

@deprecated Use DispatchFn instead Layout dispatch function type (kept for backward compatibility with incremental compute)

#
Node

pub struct Node {
id : String
uid : Int
style :
Style

children : Array[Node]
measure :
MeasureFunc
?
text : String?
src : String?
dom_id : Int?
}

A node in the layout tree

#
Node::leaf

fn Node::leaf(id : String, style :
Style
) -> Node

#
Node::new

fn Node::new(id : String, style :
Style
, children : Array[Node]) -> Node

#
Node::set_dom_id

fn Node::set_dom_id(self : Node, dom_id : Int?) -> Unit

Attach the originating DomTree node id (dynamic-rendering path).

#
Node::set_uid

fn Node::set_uid(self : Node, uid : Int) -> Unit

Overwrite the cache uid. Used to stabilize uids across re-renders so incremental reflow can match a rebuilt node to its prior layout (see stabilize_uids).

#
Node::text

fn Node::text(id : String, style :
Style
, measure :
MeasureFunc
, content : String) -> Node

Create a text node with content

#
Node::with_measure

fn Node::with_measure(id : String, style :
Style
, measure :
MeasureFunc
, text? : String, src? : String?) -> Node

Create a leaf node with a custom measure function Optional text parameter for alt text (images) or other content

#
Node::with_uid

fn Node::with_uid(id : String, uid : Int, style :
Style
, children : Array[Node]) -> Node

Create a node with a specific uid (for incremental layout)

#
Node::with_uid_and_measure

fn Node::with_uid_and_measure(id : String, uid : Int, style :
Style
, children : Array[Node], measure :
MeasureFunc
?, text : String?, src? : String?) -> Node

Create a node with a specific uid and measure function

#
UidRegistry

pub struct UidRegistry {
dom_to_uid : Map[Int, Int]
anon_to_uid : Map[String, Int]
next : Int
}

Stable uid assignment for incremental reflow.

LayoutTree keys its per-node layout cache by Node.uid, but the dynamic- rendering path rebuilds the render node tree from scratch on every DOM mutation, so a plain next_uid() would hand every node a fresh uid and the cache would never match (see docs/incremental-reflow-design.md). A UidRegistry persists across rebuilds and maps a node's stable identity to a stable uid:

  • elements carry their originating DomTree node id (Node.dom_id, phase A), so they key on that and survive moves / re-renders;
  • anonymous / text boxes (no dom_id) key on their owning node's stable uid plus their child index, which is stable as long as the surrounding structure is.

uids are allocated from the registry's own monotonic counter, so they are unique within the registry (and therefore within any one LayoutTree built from a stabilized tree).

#
UidRegistry::new

#
clear_node_clean_predicate

fn clear_node_clean_predicate() -> Unit

Remove the subtree-clean predicate (back to the conservative default where every node reports not-clean, disabling block-flow memoization).

#
fallback_layout

Create a minimal fallback layout for a node (used when dispatch is unavailable)

#
get_layout_dispatcher

fn get_layout_dispatcher() -> LayoutDispatchFunc?

Get the global layout dispatcher

#
node_incremental_active

fn node_incremental_active() -> Bool

Whether an incremental layout is in progress (the clean predicate is installed). Block-flow memoization populates its cache only while this is true, so the static / full-layout path neither reads nor writes it.

#
node_is_clean

fn node_is_clean(uid : Int) -> Bool

Whether the node with this uid has an entirely unchanged subtree since the last layout, per the installed predicate. false when no predicate is installed (the safe default: recompute).

#
set_layout_dispatcher

fn set_layout_dispatcher(f : LayoutDispatchFunc) -> Unit

Set the global layout dispatcher (used by incremental compute for caching)

#
set_node_clean_predicate

fn set_node_clean_predicate(f : (Int) -> Bool) -> Unit

Install the subtree-clean predicate for the duration of an incremental layout. Pass None (via clear_node_clean_predicate) to remove it afterwards.

#
stabilize_uids

fn stabilize_uids(root : Node, registry : UidRegistry) -> Unit

Rewrite every uid in root to its stable value from registry, in place. Call this on a freshly built render node tree before handing it to LayoutTree::from_node / reconcile_from: nodes that map to the same DomTree element (or the same anonymous slot) keep their uid across rebuilds, so the incremental layout cache matches.

#
str_has_prefix

fn str_has_prefix(s : String, prefix : String) -> Bool

Allocation-free prefix test. String::has_prefix in core uses Boyer-Moore- Horspool and allocates a skip table per call; layout calls it per node (text detection via id.has_prefix("#text")), which made it the single largest allocation site in the render pipeline. This compares the prefix directly.

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io