moonrockz/notebooks
moonrockz/notebooks provides immutable notebook models and shared navigation and traversal. It lives in Moon-Lander and has no dependency on the framework module.
Types
CellKind
pub(all) enum CellKind {
Code
Markdown
Raw
Unknown(String)
} derive(Eq, @moonbitlang/core/debug.Debug)The common role of a cell, independent of its file format. Unknown retains the original format's cell-type name.
CellKind::equal
fn CellKind::equal(CellKind, CellKind) -> BoolCellKind::not_equal
fn CellKind::not_equal(x : CellKind, y : CellKind) -> BoolCellKind::to_repr
fn CellKind::to_repr(CellKind) -> @moonbitlang/core/debug.ReprControl
pub(all) enum Control {
Continue
SkipChildren
Stop
} derive(Eq, @moonbitlang/core/debug.Debug)A decision returned by an enter callback during depth-first traversal. Continue descends, SkipChildren prunes but still calls leave, and Stop returns immediately without calling any pending leave callbacks.
Control::equal
fn Control::equal(Control, Control) -> BoolControl::not_equal
fn Control::not_equal(x : Control, y : Control) -> BoolControl::to_repr
fn Control::to_repr(Control) -> @moonbitlang/core/debug.ReprCursor
type Cursor[N]An immutable position in a tree of concrete nodes N. Moves return new positions; retaining a cursor saves its node, path and ancestors. Parent navigation never goes above the root passed to the constructor.
Cursor::Cursor
fn[N] Cursor::Cursor(root : N) -> Cursor[N]Establish a new navigation root at this node, with depth zero and path $.
Constructing from a descendant discards its previous ancestor context.
Cursor::children
fn[N : Node] Cursor::children(self : Cursor[N]) -> ReadOnlyArray[Cursor[N]]Return immutable positions for all direct children in document order. Each position retains this cursor as its parent.
Cursor::depth
fn[N] Cursor::depth(self : Cursor[N]) -> IntReturn the number of edges from this cursor's navigation root.
Cursor::first_child
fn[N : Node] Cursor::first_child(self : Cursor[N]) -> Cursor[N]?Move to the first child in document order, or return None for a leaf.
Cursor::fold
fn[N : Node, A] Cursor::fold(self : Cursor[N], init : A, f : (A, Cursor[N]) -> A) -> AThread an accumulator through every node of this subtree in pre-order. Callbacks receive typed cursors with the original paths and ancestors. Use walk when pruning or early termination is needed.
Cursor::last_child
fn[N : Node] Cursor::last_child(self : Cursor[N]) -> Cursor[N]?Move to the last child in document order, or return None for a leaf.
Cursor::next_sibling
fn[N] Cursor::next_sibling(self : Cursor[N]) -> Cursor[N]?Move to the following sibling, retaining the same parent. Return None at the last sibling or at the navigation root.
Cursor::node
fn[N] Cursor::node(self : Cursor[N]) -> NReturn the concrete node at this position without converting its payload.
Cursor::parent
fn[N] Cursor::parent(self : Cursor[N]) -> Cursor[N]?Return the saved parent position, or None at the navigation root.
Cursor::path
fn[N] Cursor::path(self : Cursor[N]) -> NodePathBuild the path from this cursor's original root to its current node. The result remains stable when other cursors navigate the same tree.
Cursor::previous_sibling
fn[N] Cursor::previous_sibling(self : Cursor[N]) -> Cursor[N]?Move to the preceding sibling, retaining the same parent. Return None at the first sibling or at the navigation root.
Cursor::walk
fn[N : Node] Cursor::walk(self : Cursor[N], enter : (Cursor[N]) -> Control, leave? : (Cursor[N]) -> Unit) -> UnitWalk this subtree in depth-first pre-order, retaining original paths and ancestors. Call leave after descendants, including for a pruned node. Stop ends immediately without pending leaves. Saved positions and moves inside callbacks do not affect the walk. Uses an explicit stack.
Metadata
type Metadata derive(@moonbitlang/core/debug.Debug)Immutable Ion metadata with unique, textual top-level field names. Import and export copy nested containers and annotations defensively.
Metadata::Metadata
fn Metadata::Metadata(value : Json) -> Metadata raise MetadataErrorConstruct from a JSON object. Use from_ion for the richer Ion data model. This JSON input adapter retains the existing constructor's behavior.
Metadata::empty
fn Metadata::empty() -> MetadataMetadata::equal
fn Metadata::equal(self : Metadata, other : Metadata) -> BoolMetadata::from_ion
fn Metadata::from_ion(value : @moonrockz/ion/ion.Ion) -> Metadata raise MetadataErrorRequire a non-null Ion struct with unique, textual top-level field names. Nested Ion values retain their types, annotations and repeated fields.
Metadata::get
fn Metadata::get(self : Metadata, key : String) -> @moonrockz/ion/ion.Ion?Look up a field as an independent Ion value. Typed nulls are present; an absent field is None. No format conversion is performed.
Metadata::get_json
fn Metadata::get_json(self : Metadata, key : String) -> Json? raise MetadataErrorExplicit JSON lookup. Raise NotJson if the selected value needs Ion's richer types; None still means the key is absent.
Metadata::is_empty
fn Metadata::is_empty(self : Metadata) -> BoolMetadata::keys
fn Metadata::keys(self : Metadata) -> ReadOnlyArray[String]Metadata::not_equal
fn Metadata::not_equal(x : Metadata, y : Metadata) -> BoolMetadata::to_ion
fn Metadata::to_ion(self : Metadata) -> @moonrockz/ion/ion.IonExport a defensive copy of the native Ion value, retaining every type.
Metadata::to_json
fn Metadata::to_json(self : Metadata) -> Json raise MetadataErrorExport independent JSON. Reject annotations, typed nulls, non-finite floats, symbols, timestamps, lob values, sexps and repeated struct fields. Integers and decimals retain their exact numeric spelling.
Metadata::to_repr
fn Metadata::to_repr(Metadata) -> @moonbitlang/core/debug.Reprimpl Eq for Metadata
Eq::equal
fn equal(self : Metadata, other : Metadata) -> BoolNodeKind
pub(all) enum NodeKind {
Notebook
Cell(CellKind)
Output(String)
Attachment(String)
Directive(String)
} derive(Eq, @moonbitlang/core/debug.Debug)The role of a node during shared traversal. Output variants carry the output type; attachments carry filenames; directives carry command names. Use the concrete node value to inspect format-specific payloads.
NodeKind::equal
fn NodeKind::equal(NodeKind, NodeKind) -> BoolNodeKind::not_equal
fn NodeKind::not_equal(x : NodeKind, y : NodeKind) -> BoolNodeKind::to_repr
fn NodeKind::to_repr(NodeKind) -> @moonbitlang/core/debug.ReprNodePath
type NodePath derive(Eq, @moonbitlang/core/debug.Debug)An immutable sequence of zero-based child indices relative to a tree root. The empty path denotes that root. Paths describe traversal children, not JSON keys or persistent cell IDs; they may not resolve in another tree.
NodePath::NodePath
fn NodePath::NodePath(indices : ReadOnlyArray[Int]) -> NodePathCreate a path from immutable child indices. Negative and out-of-range
indices are permitted here and cause at to return None when resolved.
test "doc: describe a child path" {
let path = @notebooks.NodePath([1, 0])
@expect.expect_all(s => {
s.expect(path.indices()).to_equal([1, 0])
s.expect(path.to_string()).to_equal("$[1][0]")
s.expect(@notebooks.NodePath([]).to_string()).to_equal("$")
})
}
NodePath::equal
fn NodePath::equal(NodePath, NodePath) -> BoolNodePath::indices
fn NodePath::indices(self : NodePath) -> ReadOnlyArray[Int]Return the immutable child indices in root-to-node order.
NodePath::not_equal
fn NodePath::not_equal(x : NodePath, y : NodePath) -> BoolNodePath::to_repr
fn NodePath::to_repr(NodePath) -> @moonbitlang/core/debug.ReprNodePath::to_string
fn NodePath::to_string(self : NodePath) -> StringRender a traversal path, such as $, $[0] or $[0][1].
Errors
MetadataError
pub(all) suberror MetadataError {
ExpectedObject
InvalidKey(String)
NotJson(path~ : String, reason~ : String)
} derive(Eq, @moonbitlang/core/debug.Debug)A metadata shape or format-conversion failure.
MetadataError::equal
fn MetadataError::equal(MetadataError, MetadataError) -> BoolMetadataError::message
fn MetadataError::message(self : MetadataError) -> StringMetadataError::not_equal
fn MetadataError::not_equal(x : MetadataError, y : MetadataError) -> BoolMetadataError::to_repr
fn MetadataError::to_repr(MetadataError) -> @moonbitlang/core/debug.ReprTraits
CellView
pub(open) trait CellView {
fn kind(Self) -> CellKind
fn source(Self) -> String?
fn metadata(Self) -> Metadata? = _
fn mime_capability(Self) -> &MimeTyped? = _
}An immutable, format-independent cell view suitable for mixed collections. All methods are object-safe, so cells from different formats can be stored together as &CellView. Tree navigation remains on each format's Node type.
MimeTyped
pub(open) trait MimeTyped {
fn has_mime_type(Self, String) -> Bool
}An optional capability for querying the MIME representations of a cell. Implementing this trait means lookup is supported, even when a particular cell has no representations. Formats without MIME data should omit it.
Node
pub(open) trait Node {
fn children(Self) -> ReadOnlyArray[Self]
fn kind(Self) -> NodeKind
fn source(Self) -> String? = _
fn metadata(Self) -> Metadata? = _
}A contract for a finite, immutable notebook tree with stable child order. The concrete Self type retains format-specific payloads. Implementations must not return children that alias mutable state or introduce cycles.
Values
at
fn[N : Node] at(root : N, path : NodePath) -> N?Resolve a traversal path relative to root. Return None for any invalid child index, including a negative index. An empty path returns root.
cells_by_mime_type
fn[C : MimeTyped] cells_by_mime_type(cells : ReadOnlyArray[C], mime_type : String) -> ReadOnlyArray[C]Select MIME-capable cells in input order, retaining each matching input position once. The immutable result preserves the concrete cell type. The trait bound rejects unsupported cell types at compile time.
fold
fn[N : Node, A] fold(root : N, init : A, f : (A, Cursor[N]) -> A) -> AThread an accumulator through every node in pre-order, establishing a new cursor root. The callback returns the next accumulator and receives the concrete node through its typed cursor. Use walk for pruning or stop.
walk
fn[N : Node] walk(root : N, enter : (N) -> Control, leave? : (N) -> Unit) -> UnitWalk concrete nodes in depth-first pre-order from a new root. Use walk_cursor when callbacks need parent, sibling or path context. SkipChildren still receives leave; Stop cancels pending leave callbacks.
walk_cursor
fn[N : Node] walk_cursor(root : N, enter : (Cursor[N]) -> Control, leave? : (Cursor[N]) -> Unit) -> UnitWalk from a new root, supplying typed cursor positions to callbacks. Enter runs before children and leave after them. SkipChildren still receives leave; Stop returns immediately without pending leave calls.