Sign in

    marianoguerra/tutuca/core does not have a README file

    Ctx

    pub(open) trait Ctx {
    fn path(Self) -> DispatchPath = _
    fn target_path(Self) -> DispatchPath = _
    fn name(Self) -> String? = _
    fn send(Self, name : String, args : Array[Value]) -> Unit = _
    fn bubble(Self, name : String, args : Array[Value]) -> Unit = _
    fn send_at_path(Self, path : DispatchPath, name : String, args : Array[Value]) -> Unit = _
    fn bubble_at_path(Self, path : DispatchPath, name : String, args : Array[Value]) -> Unit = _
    fn request(Self, name : String, args : Array[Value], opts : RequestOpts) -> Unit = _
    fn stop_propagation(Self) -> Unit = _
    fn at(Self) -> PathChanges = _
    fn walk_path(Self, callback : (Int, Value) -> Bool) -> Unit = _
    }

    What a handler can do besides transforming its leaf (JS EventContext). Defined here so Handler can carry it without depending on the transactor; every method defaults to a no-op so tests and Path::update can run handlers without a dispatcher. The transactor implements the real thing.

    Fields

    pub(open) trait Fields {
    fn schema() -> SchemaInfo
    fn encode(Self) -> Map[String, Value]
    fn decode(Map[String, Value]) -> Self?
    }

    What a typed state struct states about itself: its declared schema and its conversion to and from the fields map the render and path layers read.

    A generic BOUND, not a trait object — schema and decode are facts about the TYPE, and Value::Obj already carries the object-safe half of the protocol (Obj). Nothing ever needs a &Fields.

    Three methods, all of them things only the author (or the generator reading the author's WIT) knows. There is no fourth: every dynamic operation OVER the result — typed reads, defaults, sizes, item lookup, method calls, field enumeration — is a free function in this package, written once rather than implemented per type.

    Obj

    pub(open) trait Obj {
    fn component_id(Self) -> Int? = _
    fn obj_field(Self, name : String) -> Value? = _
    fn obj_with_field(Self, name : String, v : Value) -> Value? = _
    fn obj_item(Self, key : PathKey) -> Value? = _
    fn obj_with_item(Self, key : PathKey, v : Value) -> Value? = _
    fn obj_seq_entries(Self) -> Array[(PathKey, Value)]? = _
    fn obj_callable(Self, name : String, ns : HandlerNamespace) -> Value? = _
    fn obj_handler(Self, bucket : HandlerBucket, name : String) -> Handler? = _
    fn obj_schema(Self) -> SchemaInfo? = _
    fn obj_size(Self) -> Int? = _
    fn obj_eq(Self, other : &Obj) -> Bool = _
    fn obj_debug(Self) -> String = _
    }

    Component-instance protocol (the port of JS's runtime Records tagged with a hidden component symbol). ONE trait serves both hybrid representations: the Value-backed Instance (component package) and user-defined typed structs. Instances live INSIDE Value so they flow through every Value-typed seam (binds, handler args, dynamic lookups, iterated seqs). Fns returned by obj_field / obj_callable and the Handler returned by obj_handler are SELF-PRE-BOUND (they close over the concrete Self — the no-downcast analogue of JS late this) and ignore args element 0. Every method defaults to an empty/None answer.

    Stack

    pub(open) trait Stack {
    fn lookup_name(Self, String) -> Value = _
    fn lookup_bind(Self, String) -> Value = _
    fn lookup_dynamic(Self, String) -> Value = _
    fn lookup_field_raw(Self, String) -> Value = _
    fn lookup_method(Self, String) -> Value = _
    fn get_handler_for(Self, String, HandlerNamespace) -> Value = _
    }

    Evaluation environment (JS stack). Every method defaults to Null so implementations (and test mocks) provide only the lookups they use. lookup_method returns the RESULT of the no-arg call — the stack invokes. get_handler_for returns Null when no handler is registered.

    DispatchPath

    pub(all) struct DispatchPath {
    items : Array[DispatchStep]
    } derive(Eq,
    Debug
    )

    A path that still knows which component contributed each hop. Bubbling pops one hop per component; converting to a transaction Path teleports every Dyn marker so mutations land on the data's real location.

    DispatchPath::compact

    fn DispatchPath::compact(self : DispatchPath) -> DispatchPath

    DispatchPath::concat

    fn DispatchPath::concat(self : DispatchPath, steps : Array[Step]) -> DispatchPath

    DispatchPath::new

    DispatchPath::of_steps

    fn DispatchPath::of_steps(steps : Array[Step]) -> DispatchPath

    DispatchPath::pop_step

    fn DispatchPath::pop_step(self : DispatchPath) -> DispatchPath

    DispatchPath::to_transaction_path

    fn DispatchPath::to_transaction_path(self : DispatchPath) -> Path

    DispatchStep

    pub(all) enum DispatchStep {
    Plain(step~ : Step, origin~ : Int?)
    Dyn(producer~ : Int, steps~ : Array[Step], interior~ : Array[Int], key~ : PathKey?)
    } derive(Eq,
    Debug
    )

    One hop of a dispatch path — the component-boundary projection of an event path. Plain wraps an addressing step with its origin (the id of the component that contributed it — teleport provenance); Dyn marks a dynamic variable (*dyn) used as a render target: the rendered data lives at the PRODUCER component (where the dynamic was defined), not at the consumer that wrote <x render="*dyn">, so interior lists the component ids crossed between producer and consumer, and steps is the producer's own path to the data. key is set when the dynamic is ITERATED (the item lives at the producer's sequence field under that key) — the one thing that used to be a whole second variant, DynEach, which differed in nothing else and so was matched alongside Dyn everywhere except the one line that reads the key.

    FieldInfo

    pub(all) struct FieldInfo {
    name : String
    ty : TyInfo
    }

    One declared field of a component's state.

    Two parts, where there were six. The WIT spelling, the runtime kind, a collection's element type, a slot's component and a closed set's members are all FUNCTIONS of the type (ty_info.mbt), so they are asked rather than stored — which is what stops them from contradicting each other, and what lets a reader descend into list<card> instead of receiving the string "card" and having nowhere to take it.

    FieldInfo::default

    fn FieldInfo::default(self : FieldInfo) -> Value

    FieldInfo::kind

    fn FieldInfo::kind(self : FieldInfo) -> FieldKind

    The runtime kind this field carries — a projection of its type, never a second statement about it.

    FieldInfo::new

    fn FieldInfo::new(name : String, ty : TyInfo) -> FieldInfo

    FieldKind

    pub(all) enum FieldKind {
    FBool
    FText
    FInt
    FFloat
    FList
    FMap
    FAny
    FComp(comp~ : String, args~ : Map[String, Value])
    FSet
    FOMap
    } derive(
    Debug
    )

    What a field carries at runtime. DECLARED, never inferred: reading the kind off a seed value is what used to make FInt vs FFloat depend on whether a double happened to be integral.

    FComp fields hold a child component instance created through the registration scope; FSet/FOMap are the Map-backed set / ordered-map refinements.

    Handler

    pub(all) struct Handler((Array[Value], &Ctx) -> Value?)

    A leaf-update handler, resolved ON the leaf so self is pre-bound (the JS handler.apply(instance, args) binds this at call time; binding at resolution time is equivalent — same instance either way). Receives its args and the dispatch Ctx (JS appends ctx as the last handler argument). Returns the new leaf, or None for "no change" (the port of the JS newLeaf !== curLeaf identity check — answering None lets the traversal skip the spine rebuild without comparing anything).

    HandlerBucket

    pub(all) enum HandlerBucket {
    Receive
    Input
    Bubble
    Response
    } derive(Eq,
    Debug
    )

    Dispatch buckets a handler can live in (semantics.md §6). Alter is render-time only and never dispatched, so it is not a bucket here.

    HandlerNamespace

    pub(all) enum HandlerNamespace {
    Input
    Alter
    } derive(Eq,
    Debug
    )

    Handler namespaces are a fixed enumeration (JS passes "input"/"alter" strings)

    HandlerParse

    pub(all) struct HandlerParse {
    handler : Val
    args : Array[Val]
    } derive(Eq,
    Debug
    )

    Handler reference plus parsed args for @on.

    Issue

    pub(all) struct Issue {
    kind : IssueKind
    role : IssueRole
    value : String
    } derive(Eq,
    Debug
    )

    A parse issue, collected on the ParseCtx (JS px.onParseIssue callback)

    IssueKind

    pub(all) enum IssueKind {
    BadValue
    } derive(Eq,
    Debug
    )

    JS onParseIssue kind — only "bad-value" occurs in value.js; other kinds (x-op, x-attr, …) join this enum when their modules are ported.

    IssueRole

    pub(all) enum IssueRole {
    BadMacroVar
    BadHandlerName
    BadHandlerArg
    UnknownPredicate
    PredicateArity(Pred)
    BadPredicateArg
    } derive(Eq,
    Debug
    )

    What was malformed (JS info.role)

    Lit

    pub(all) enum Lit {
    LNull
    LBool(Bool)
    LNum(Double)
    LStr(String)
    } derive(Eq,
    Debug
    )

    Literal constant payload (JS ConstVal.val: string | number | boolean | null)

    NullCtx

    pub(all) struct NullCtx {
    }

    A Ctx that dispatches nothing (JS eval(null) analogue for handlers).
    impl Ctx for NullCtx

    NullStack

    pub(all) struct NullStack {
    }

    Stand-in for JS eval(null) on values that touch no stack
    impl Stack for NullStack

    ParseCtx

    pub struct ParseCtx {
    macro_vars : Map[String, String]
    issues : Array[Issue]
    }

    Parse context (JS px): macro variables in scope plus collected issues

    ParseCtx::new

    fn ParseCtx::new(macro_vars? : Map[String, String]) -> ParseCtx

    Path

    pub(all) struct Path {
    steps : Array[Step]
    } derive(Eq,
    Debug
    )

    An address into the component/state tree: a sequence of steps root→leaf.
    impl Show for Path

    Path::concat

    fn Path::concat(self : Path, steps : Array[Step]) -> Path

    Path::field

    fn Path::field(self : Path, name : String) -> Path

    Path::new().field("rows").index("rows", 2) — the absolute twin of the relative PathChanges builder, which delegates to these so the two spell a step the same way. Each returns a fresh Path, so a base is reusable.

    Path::index

    fn Path::index(self : Path, name : String, i : Int) -> Path

    A positional item of a sequence FIELD. There is no bare-index step: a Path addresses field-then-key, so a nested .a[0][1] is not expressible and the value-level item/index are what read one.

    Path::key

    fn Path::key(self : Path, name : String, k : String) -> Path

    A keyed item of a sequence field.

    Path::lookup

    fn Path::lookup(self : Path, root : Value) -> Value?

    Path::new

    fn Path::new(steps? : Array[Step]) -> Path

    Path::pin_keys

    fn Path::pin_keys(self : Path, root : Value) -> Path

    Path::pop_step

    fn Path::pop_step(self : Path) -> Path

    Path::resolve_chain

    fn Path::resolve_chain(self : Path, root : Value) -> Array[Value]

    Path::set_value

    fn Path::set_value(self : Path, root : Value, v : Value) -> Value

    Path::to_keys

    fn Path::to_keys(self : Path) -> Array[StepKey]

    Path::to_label

    fn Path::to_label(self : Path) -> String

    The addressing steps as readable text.

    Over to_keys, so the frame-only steps (which address nothing) are absent and a seq-access step shows as its field.

    Path::update

    fn Path::update(self : Path, root : Value, bucket : HandlerBucket, name : String, args : Array[Value]) -> Value

    PathChanges

    pub struct PathChanges {
    ctx : &Ctx
    steps : Array[Step]
    }

    PathChanges::bubble

    fn PathChanges::bubble(self : PathChanges, name : String, args : Array[Value]) -> Unit

    Bubble name from the built path (JS PathChanges.bubble: skipSelf + bubbles).

    PathChanges::build_path

    fn PathChanges::build_path(self : PathChanges) -> DispatchPath

    The absolute dispatch path this builder addresses: the ctx's path with the accumulated steps appended (JS PathChanges.buildPath).

    PathChanges::field

    fn PathChanges::field(self : PathChanges, name : String) -> PathChanges

    Descend into field name (JS PathBuilder.field).

    PathChanges::index

    fn PathChanges::index(self : PathChanges, name : String, i : Int) -> PathChanges

    Descend into element i of sequence field name (JS PathBuilder.index).

    PathChanges::key

    fn PathChanges::key(self : PathChanges, name : String, key : String) -> PathChanges

    Descend into keyed element key of map field name (JS PathBuilder.key).

    PathChanges::send

    fn PathChanges::send(self : PathChanges, name : String, args : Array[Value]) -> Unit

    Send name at the built path (JS PathChanges.send).

    PathKey

    pub(all) enum PathKey {
    KInt(Int)
    KStr(String)
    } derive(Eq,
    Debug
    )

    A concrete sequence key: list index or map key (JS SeqStep.key is int|string)

    PathKey::to_label

    fn PathKey::to_label(self : PathKey) -> String

    A key as its addressing text: 2 or title.

    PathKey::to_value

    fn PathKey::to_value(self : PathKey) -> Value

    A key as a Value — what @key binds to inside a loop, and what a seq-access read compares against.

    Pred

    pub(all) enum Pred {
    IsEmpty
    IsTruthy
    IsFalsy
    IsNull
    Equals
    } derive(Eq,
    Debug
    )

    Boolean predicates usable in conditional slots (JS PREDICATES table)

    Pred::name

    fn Pred::name(self : Pred) -> String

    RequestOpts

    pub(all) struct RequestOpts {
    on_ok_name : String?
    on_error_name : String?
    on_res_name : String?
    live_path : Bool
    } derive(Eq,
    Debug
    )

    Options for Ctx::request (JS pushRequest opts): response-handler routing (on_ok_name / on_error_name / on_res_name) and live_path, which opts out of pinning field-resolved keys at request time.

    RequestOpts::new

    fn RequestOpts::new(on_ok_name? : String, on_error_name? : String, on_res_name? : String, live_path? : Bool) -> RequestOpts

    SchemaInfo

    pub(all) struct SchemaInfo {
    name : String
    fingerprint : String
    fields : Array[FieldInfo]
    inputs : Array[String]
    receives : Array[String]
    bubbles : Array[String]
    responses : Array[String]
    methods : Array[String]
    ids : Array[String]
    view_names : Array[String]
    init_names : Array[String]
    }

    What a component declares, as static metadata.

    inputs is the one that matters most: the names update answers are UNKNOWABLE at runtime (it is one opaque pattern match), so introspection could only ever report THAT an update exists. The generator knows them.

    SchemaInfo::field

    fn SchemaInfo::field(self : SchemaInfo, name : String) -> FieldInfo?

    Linear over fields, which is the right shape at these sizes: a component has a handful of them and the array preserves declaration order, which the callers below read as much as they read the entries themselves.

    SchemaInfo::field_names

    fn SchemaInfo::field_names(self : SchemaInfo) -> Array[String]

    SchemaInfo::new

    fn SchemaInfo::new(name? : String, fingerprint~ : String, fields? : Array[FieldInfo], inputs? : Array[String], receives? : Array[String], bubbles? : Array[String], responses? : Array[String], methods? : Array[String], ids? : Array[String], view_names? : Array[String], init_names? : Array[String]) -> SchemaInfo

    Step

    pub(all) enum Step {
    FieldStep(String)
    SeqStep(field~ : String, key~ : PathKey)
    SeqAccessStep(seq_field~ : String, key_field~ : String)
    EachRenderItStep(field~ : String, key~ : PathKey)
    BindStep(binds~ : Map[String, Value])
    ScopeBindStep(val~ : Val)
    EachBindStep(val~ : Val, when_val~ : Val?, enrich_with_val~ : Val?, loop_with_val~ : Val?, key~ : PathKey)
    } derive(Eq,
    Debug
    )

    Path steps (src/path.js). FieldStep/SeqAccessStep are what values address (Val::to_path_item); SeqStep is a field + concrete key (also the pinned form of SeqAccessStep); EachRenderItStep is an iterated render target that compacts to a SeqStep; Bind/ScopeBind/EachBind are frame-only (stack rebuild). Dynamic-var markers live on DispatchStep in the path package.

    StepKey

    pub(all) struct StepKey {
    field : String
    key : PathKey?
    } derive(Eq,
    Debug
    )

    A generic {field, key?} descriptor of an addressing step (JS Step.toKey), so tooling can introspect a path without matching on Step.

    TyInfo

    pub(all) enum TyInfo {
    TyBool
    TyInt
    TyFloat
    TyText
    TyList(TyInfo)
    TyTuple(Array[TyInfo])
    TyOption(TyInfo)
    TyRecord(String)
    TyEnum(String)
    TyVariant(String)
    TyFlags(String, Array[String])
    TySet
    TyOMap(TyInfo)
    TyComp(String?)
    TyAny
    } derive(Eq,
    Debug
    )

    What a declared field carries.

    TyInfo::elem

    fn TyInfo::elem(self : TyInfo) -> TyInfo?

    What this type CONTAINS, or None when it contains nothing.

    Strict, and deliberately not the same question @statedef.StateTy::elem answers. That one asks "may a view @each over this?", where any and a child slot must both say yes — a dynamic value may turn out to be a list and a component iterates its own entries, neither knowable at generation time. Answering the two with one method put a meaningless elem: any on 117 fields of the corpus and showed it in the inspector, where the question is the other one: what is in here?

    TyInfo::kind

    fn TyInfo::kind(self : TyInfo) -> FieldKind

    The runtime kind: how a value of this type is REPRESENTED, once the shape that distinguishes it no longer matters.

    A projection rather than a stored field, which is the point — the kind used to be written beside the spelling and could contradict it.

    TyInfo::members

    fn TyInfo::members(self : TyInfo) -> Array[String]

    A closed set's declared members. Empty for every other type, and for a set with open membership — which is a real answer, not a missing one.

    TyInfo::show_wit

    fn TyInfo::show_wit(self : TyInfo) -> String

    How the author wrote it. The WIT spelling, because that is what is in the file and what they will edit.

    TyInfo::slot

    fn TyInfo::slot(self : TyInfo) -> String?

    The component a child slot holds, or None for a data field. Some("") is a slot whose component the schema did not name.

    TyInfo::zero

    fn TyInfo::zero(self : TyInfo) -> Value

    The empty value of this type, as the runtime carries it.

    Type-directed, like the generated <T>State::zero() — which is the point: a default is not an independent fact about a field, so storing one beside the type would be a second thing to keep true. The one default a TYPE cannot give is a child slot's construction arguments, and those are a value the author chooses rather than anything the schema knows.

    This is what an inspector shows in a field's "default" column, reachable from a bare Value — it used to come off Component.specs, which a holder of an instance and no registry could not get to.

    Val

    pub(all) enum Val {
    Const(lit~ : Lit, from_macro~ : Bool)
    StrTpl(Array[Val?])
    Predicate(pred~ : Pred, args~ : Array[Val])
    Name(String)
    HandlerName(name~ : String, ns~ : HandlerNamespace)
    TypeName(String)
    Bind(String)
    BindMember(name~ : String, prop~ : String)
    Dyn(String)
    Field(String)
    Method(String)
    SeqAccess(seq~ : String, key~ : String)
    } derive(Eq,
    Debug
    )

    Parsed value AST. One variant per JS BaseVal subclass. from_macro ports ConstVal.fromMacroVar: set when a ^name macro var resolves to a constant, which makes an enclosing template non-literal. StrTpl parts alternate text constants and placeholder expressions; a None part is a placeholder whose inner expression failed to parse (JS keeps null there).
    impl Show for Val

    Val::eval

    fn Val::eval(self : Val, stack : &Stack) -> Value

    Val::eval_as_handler

    fn Val::eval_as_handler(self : Val, stack : &Stack) -> Value

    Val::is_literal

    fn Val::is_literal(self : Val) -> Bool

    Val::to_path_item

    fn Val::to_path_item(self : Val) -> Step?

    Value

    pub(all) enum Value {
    Null
    Bool(Bool)
    Num(Double)
    Str(String)
    List(Array[Value])
    Map(Map[String, Value])
    Fn((Array[Value]) -> Value)
    Obj(&Obj)
    }

    Dynamic runtime value: what eval(stack) reads and returns.
    impl Eq for Value
    impl ToJson for Value
    impl FromJson for Value

    Value::as_key

    fn Value::as_key(self : Value) -> PathKey?

    This value AS a sequence key: a string keys a map, an integral number indexes a list. None for everything else — including a non-integral number, which is not an index and must not be rounded into one.

    The bridge between the value world and the addressing world: it is how a .seq[.key] read turns the key FIELD into the key it looks up, and how the renderer names an iterated item in its §Each§ breadcrumb.

    Value::at

    fn Value::at(self : Value, p : Path) -> Value

    The value at a path, or Null at the first step that does not resolve.

    This is the composition, not a new primitive: one-hop reads stay field/item, because building a one-element Path to replace a match costs three allocations. Reach for a Path when the ADDRESS is the thing being passed around — a transaction target, an observed change, a test's assertion site.

    Value::at_opt

    fn Value::at_opt(self : Value, p : Path) -> Value?

    The value at a path, distinguishing "no such place" from a Null stored there — the one distinction at cannot express and no coercer can recover.

    Value::bool

    fn Value::bool(self : Value, default? : Bool) -> Bool

    Value::bool_opt

    fn Value::bool_opt(self : Value) -> Bool?

    Value::call

    fn Value::call(self : Value, args : Array[Value], this? : Value) -> Value

    Call a function value under the Fn convention: element 0 of the argument array is the this slot, which self-pre-bound callees ignore. Null for a non-function.

    The convention was hand-rolled at every call site — match v { Fn(f) =>f([Null, x]) ... } — with the dummy slot spelled out each time.

    Value::call_field

    fn Value::call_field(self : Value, name : String, args : Array[Value]) -> Value

    Call a method OF this value, with this value in the this slot: the $name read followed by the invocation, which is how a view calls one and how a handler filters a list of instances it cannot downcast.

    Value::entries

    fn Value::entries(self : Value) -> Array[(PathKey, Value)]

    The ordered (key, value) entries of any container: a list keyed by index, a map by name, a custom collection by whatever obj_seq_entries says. Empty for anything that is not one (the JS unkIter default).

    TOOLING and one-off use: this materializes. The renderer's @each keeps indexing List and Map directly, because allocating a tuple per item on every render is not what a convenience is for.

    Value::field

    fn Value::field(self : Value, name : String) -> Value

    Field access that works on Map values and Obj instances alike; Null for anything else (including missing fields).

    Value::field_info

    fn Value::field_info(self : Value, name : String) -> FieldInfo?

    The declared description of one field.

    Value::field_names

    fn Value::field_names(self : Value) -> Array[String]

    Every field name: declaration order for a described instance, key order for a Map, empty for anything else (including an instance that declares nothing — "no schema" is not "no fields", and guessing is what the schema work removed).

    Value::field_opt

    fn Value::field_opt(self : Value, name : String) -> Value?

    A field, or None when there is no such field. Map and Obj answer, anything else has no fields.

    Value::from_json

    fn Value::from_json(j : Json) -> Value

    Build a Value from parsed JSON. Lossless: every JSON shape has a Value.

    Value::handler

    fn Value::handler(self : Value, bucket : HandlerBucket, name : String) -> Handler?

    The handlers a value carries: component instances answer through the Obj trait, pure data has none.

    Value::index

    fn Value::index(self : Value, i : Int, default? : Value) -> Value

    v.index(2) — an item by position.

    Value::int

    fn Value::int(self : Value, default? : Int) -> Int

    Value::int_opt

    fn Value::int_opt(self : Value) -> Int?

    Value::is_truthy

    fn Value::is_truthy(self : Value) -> Bool

    JS truthiness: Null/false/0/NaN/"" are false; lists, maps and functions are always true (like JS objects). The truthy? predicate differs on purpose: it treats empty collections as falsy (see pred_truthy).

    Value::item

    fn Value::item(self : Value, key : PathKey, default? : Value) -> Value

    An item by key, or the default.

    Value::item_opt

    fn Value::item_opt(self : Value, key : PathKey) -> Value?

    An item by key: a list index, a map key, or whatever a custom collection resolves through obj_item. None when there is no such item.

    Value::key

    fn Value::key(self : Value, k : String, default? : Value) -> Value

    v.key("id") — an item by name. Distinct from field: a Map answers both, but a component instance keys its SEQUENCE here and its FIELDS there.

    Value::list

    fn Value::list(self : Value) -> Array[Value]

    The list payload; [] for non-lists (shared empty NOT returned — fresh).

    Value::list_opt

    fn Value::list_opt(self : Value) -> Array[Value]?

    Value::map

    fn Value::map(self : Value) -> Map[String, Value]

    The map payload; empty for non-maps (fresh, like Value::list).

    Value::map_opt

    fn Value::map_opt(self : Value) -> Map[String, Value]?

    Value::num

    fn Value::num(self : Value, default? : Double) -> Double

    Value::num_opt

    fn Value::num_opt(self : Value) -> Double?

    Value::schema

    fn Value::schema(self : Value) -> SchemaInfo?

    What this value DECLARES, when it is a component instance that says.

    Value::size

    fn Value::size(self : Value, default? : Int) -> Int

    How many items, or 0. The total form of size_of.

    Value::snapshot

    fn Value::snapshot(self : Value) -> Map[String, Value]

    name -> value for every declared field, in declaration order.

    What every consumer that wanted to SHOW an instance had been faking: the inspector read the names off a Components registry, the example builder took them as a parameter, the dyncomp host parsed them out of a JSON projection.

    Value::str

    fn Value::str(self : Value, default? : String) -> String

    Value::str_opt

    fn Value::str_opt(self : Value) -> String?

    Value::to_display_string

    fn Value::to_display_string(self : Value) -> String

    JS ${v} template-interpolation semantics. Approximations: List joins elements with ","; Map and Fn render as opaque markers (JS "[object Object]" / function source are not worth mirroring).

    Value::to_json

    fn Value::to_json(self : Value) -> Json

    Json shape of a Value.

    A DESCRIBED instance projects to its declared fields, recursively — which is what makes a state dump JSON rather than a debug string. It used to flatten to null along with Fn, because nothing could enumerate an Obj; the consequence was a state_json() that returned the Show rendering and said so in a comment, and a dyncomp migration path that parsed a __dyncomp_state_json pseudo-field instead.

    An instance that declares nothing is still null: with no schema there is no field list to project, and inventing one is what the schema work removed. Fn stays null unconditionally (JS structured clone would throw on a function too), so a method or an unrendered handler inside a described instance projects as null rather than taking the whole object with it.

    Value::with_at

    fn Value::with_at(self : Value, p : Path, v : Value) -> Value

    Copy-on-write write at a path, total: the SAME value back when the path does not resolve (Path::set_value's own contract).

    Value::with_field

    fn Value::with_field(self : Value, name : String, v : Value) -> Value

    Copy-on-write field write, total: the value unchanged when the field cannot be written.

    Value::with_field_opt

    fn Value::with_field_opt(self : Value, name : String, v : Value) -> Value?

    Copy-on-write field write; None when there is no such field to write (no such field on an instance, not a container at all). The partial form is what step_put needs: a step that cannot be addressed must leave the whole tree untouched rather than silently write nothing.

    Value::with_item

    fn Value::with_item(self : Value, key : PathKey, v : Value) -> Value

    Copy-on-write item write, total. Same identity contract as with_field.

    Value::with_item_opt

    fn Value::with_item_opt(self : Value, key : PathKey, v : Value) -> Value?

    Copy-on-write item write; None when the key addresses no item (an index out of range, a key of the wrong kind for the container).

    mutator_name

    fn mutator_name(verb : String, field : String) -> String

    The name of a field's generated mutator: count + set -> setCount.

    The convention lives HERE, in one function, because two places have to agree on it and neither can see the other. component() builds the mutators by concatenating it, and the state editor — which holds a bare Value and calls them by name through Obj::obj_field — reconstructed the same string from its own copy. Two spellings of one convention, either of which could have been changed alone.

    parse_alter_handler

    fn parse_alter_handler(s : String, ctx : ParseCtx) -> Val?

    parse_bool

    fn parse_bool(s : String, ctx : ParseCtx) -> Val?

    parse_component

    fn parse_component(s : String, ctx : ParseCtx) -> Val?

    parse_field

    fn parse_field(s : String, ctx : ParseCtx) -> Val?

    parse_input_handler

    fn parse_input_handler(s : String, ctx : ParseCtx) -> HandlerParse?

    parse_macro_attr

    fn parse_macro_attr(s : String, ctx : ParseCtx) -> Val?

    parse_provide

    fn parse_provide(s : String, ctx : ParseCtx) -> Val?

    parse_sequence

    fn parse_sequence(s : String, ctx : ParseCtx) -> Val?

    parse_text

    fn parse_text(s : String, ctx : ParseCtx) -> Val?

    parse_token

    fn parse_token(s : String, ctx : ParseCtx) -> Val?

    size_of

    fn size_of(v : Value) -> Int?

    JS sizeOf: .size (immutable collections) or .length (string/array).

    A custom collection answers too, through obj_size. It used to be None — so an instance @each iterated happily had no length, empty? was always false for it and the generated xLen mutator returned Null. An instance that is NOT a sequence still answers None, which is the honest reading: a component has fields, not a size.

    step_get

    fn step_get(node : Value, step : Step) -> Value?

    step_keys_label

    fn step_keys_label(keys : Array[StepKey]) -> String

    Addressing steps as readable text: value.rows[1].title.

    Over StepKey rather than Step, because that is the projection a transaction is RECORDED as (ObserveRecord.path_keys) — so a log line and a Path print the same way without the log having to keep the Path.

    step_with_key

    fn step_with_key(step : Step, key : PathKey) -> Step

    Key a step with the si/sk an §Each§ meta carried (JS Step.withIndex / withKey, used by event reconstruction's applyKey): a plain field access under a keyed meta addresses the keyed item. Steps that carry their own key (or no field) are returned unchanged.

    tokenize_value

    fn tokenize_value(s : String) -> Array[String]

    The single value tokenizer: a $'…' template run, a plain '…' literal (escapes kept in the token), or a maximal non-whitespace run. Quoted alternatives win only at their start; an unterminated quote falls back to the plain run (mirrors the JS regex alternation).

    warn

    fn warn(msg : String) -> Unit

    Report a runtime warning through warn_hook.

    warn_hook

    let warn_hook :
    Ref
    [(String) -> Unit]

    Where runtime warnings go. Defaults to println (the closest portable analogue of JS console.warn); a host can redirect it — e.g. into an error pane or the browser console — without threading a context through eval.