inkferro-core 0.1.0

Layout, text measurement, ANSI render, and frame-diff engine for inkferro — a Rust-backed, byte-for-byte drop-in for the ink terminal UI library.
Documentation
//! DOM node arena and op application for inkferro.
//!
//! # Design decisions
//!
//! ## Id storage: `Vec<Option<Node>>`
//! Node ids are allocated externally (by the JS reconciler in M3, not here).
//! The arena uses `Vec<Option<Node>>` grown on demand to accommodate any u32 id.
//! A large gap id causes over-allocation; this is acceptable because the React
//! reconciler allocates ids densely and sequentially.  `Create` on an occupied
//! slot is treated as a no-op (React allocates each id exactly once).
//!
//! ## Text storage
//! ink models text as a separate `#text` `TextNode` child of `ink-text` /
//! `ink-virtual-text` elements (dom.ts:78-81, createTextNode dom.ts:208-220).
//! This port folds `nodeValue` into a `text: Option<String>` field on `Node`
//! per the task spec; `SetText` drives it.  On Box/Root nodes the field is
//! unused but still present (simplest uniform struct).
//!
//! ## Free does NOT cascade
//! `detachDeletedInstance` is a no-op in the reconciler (reconciler.ts:298).
//! React calls it *per deleted instance*, so a subtree deletion = one
//! `RemoveChild` at the root followed by one `Free` per node.  Therefore
//! `Free` drops exactly one slot and must **not** recurse; cascading would
//! double-free children that arrive in their own `Free` ops.
//!
//! ## Error philosophy
//! `apply` is total: malformed ops (unknown id, missing parent) are silent
//! no-ops, mirroring ink's JS behaviour where `removeChildNode` guards with
//! `indexOf >= 0` (dom.ts:178-182) rather than throwing.  There are no
//! `debug_assert!` calls on externally-supplied ids because tests explicitly
//! exercise the no-panic path.

mod arena;
mod decode;
mod node;
mod op;

pub use arena::Arena;
pub use decode::{DecodeError, decode_ops};
pub use node::{
    Align, AttrValue, BorderStyle, ContentAlign, Dim, Display, FlexDir, FlexWrap, Kind, Lp, Node,
    Overflow, Position, Style, TextStyle, TextWrap,
};
pub use op::{Op, apply};