Skip to main content

Crate cranpose_core

Crate cranpose_core 

Source
Expand description

§cranpose-core

cranpose-core provides the composition runtime, reactive state, composition locals, runtime scheduler support, and coroutine hooks used by Cranpose. Most application code uses these services through the cranpose facade.

Depend directly on cranpose-core when you build a host integration, a framework crate, or a lower-level runtime tool. App code with ordinary UI needs the facade and widget crates instead.

§State and runtime

The host creates a Runtime with a scheduler. The runtime gives state a place to live and accepts snapshot commits. State changes mark subscribed scopes for recomposition.

use cranpose_core::{
    DefaultScheduler, Runtime, mutableStateOf, run_in_mutable_snapshot, scheduler_ref,
};

let _runtime = Runtime::new(scheduler_ref(DefaultScheduler));
let count = mutableStateOf(0);

assert_eq!(count.value(), 0);
let applied = run_in_mutable_snapshot(|| count.set(1));
assert!(applied.is_ok());
assert_eq!(count.value(), 1);

Composition code uses remember for values tied to a composition position and CompositionLocalProvider for scoped values. ownedMutableStateOf gives Rust owners an explicit state lifetime.

§Blocking work

withBlocking runs synchronous work on a shared native executor and returns Result<T, BlockingError>. The pool starts threads on demand up to the available CPU count, allows four waiting jobs per CPU, and retires idle threads after 30 seconds. A full queue suspends the future until capacity is available, without blocking the UI thread or requiring an application retry loop. BlockingExecutor provides explicit thread, queue, and idle limits: submit(work).await waits for capacity, while try_submit(work) returns Saturated immediately when full. Suspended callers still own their captured data; bound concurrent producers when creating large batches.

Dropping a work future removes a waiting job and releases its captures. A running closure cannot be interrupted. Use withBlocking inside a composition’s rememberCoroutineScope().launch(...) to cancel pending work when that scope leaves. launchBlocking delivers Result to a UI callback and returns a Result<TaskHandle, BlockingError> for runtime ownership; capacity waits and execution failures are handled inside that task. Cancel the handle to cancel pending work and delivery. It requires a live runtime and never falls back to running a closure on the caller thread.

Shutting down an executor, or dropping its last owner, rejects new work and resolves waiting tasks with Shutdown. Running work may finish. Unwinding panics resolve as Panicked; a binary built with panic = "abort" still aborts. Web calls return Unsupported without executing the blocking closure. Use browser asynchronous APIs or an application-owned Web Worker on that target.

§Features

The default feature set is empty. hot-reload selects source-structure keys for development hot reload. std-hash selects the standard library hasher.

§Runtime structure

The slot table stores active groups, payloads, and nodes. Retained inactive branches use detached subtrees. See the slot table invariants and the current slot table design.

Re-exports§

pub extern crate self as cranpose_core;

Re-exports§

pub use composer::CapturedCompositionContext;
pub use composer::Composer;
pub use composer::ValueSlotHandle;
pub use concurrency::CollectEvents;
pub use concurrency::CoroutineScope;
pub use concurrency::Delay;
pub use concurrency::EventChannel;
pub use concurrency::EventSender;
pub use concurrency::EventStream;
pub use concurrency::EventStreamNext;
pub use concurrency::ProduceScope;
pub use concurrency::collectAsState;
pub use concurrency::delay;
pub use concurrency::interval;
pub use concurrency::produceState;
pub use concurrency::rememberCoroutineScope;
pub use concurrency::rememberEventStream;
pub use concurrency::spawn_ui_task;
pub use launched_effect::__launched_effect_async_impl;
pub use launched_effect::CancelToken;
pub use launched_effect::LaunchedEffect;
pub use launched_effect::LaunchedEffectAsync;
pub use launched_effect::LaunchedEffectScope;
pub use launched_effect::TaskSite;
pub use owned::Owned;
pub use platform::Clock;
pub use platform::RuntimeScheduler;
pub use platform::SchedulerRef;
pub use platform::scheduler_ref;
pub use subcompose::ContentTypeReusePolicy;
pub use subcompose::DefaultSlotReusePolicy;
pub use subcompose::SlotId;
pub use subcompose::SlotReusePolicy;
pub use subcompose::SubcomposeState;
pub use composer_context::note_nested_slots_host;
pub use composer_context::with_composer as with_current_composer;
pub use test_scratch::test_scratch_dir;

Modules§

collections
Collections the framework’s crates share: the hash map every crate uses, the bounded caches their hot paths keep, and the box that holds the properties few values set.
composer_context
The composer that is current on this thread, which composable code reaches without passing it as a parameter.
concurrency
Composition-scoped structured concurrency.
env_flags
Cached reads of the CRANPOSE_* diagnostic environment variables.
hash
The hasher type and constructor that the framework uses by default.
owned
Owned, the handle to a value that a composition remembers.
platform
Platform abstraction traits for Compose runtime services.
runtime
The runtime in which a composition runs: state cells, UI tasks, frame callbacks and the queue of invalidated scopes.
snapshot_double_index_heap
A min-heap of snapshot ids that supports removal by handle.
snapshot_id_set
A compact set of snapshot ids.
snapshot_pinning
Tracks the pinned snapshots, which bound the state records that may be reclaimed.
snapshot_state_observer
Records which state objects a scope reads and calls back when one of them changes.
snapshot_v2
Snapshot system for managing isolated state changes.
source_trace
Optional composition origins for development tools.
subcompose
State tracking for measure-time subcomposition.
test_scratch
Where a test writes real files. Behind test-helpers so only a test build of the workspace carries it. Where a test writes real files.

Macros§

clone_captures
Clones values into new bindings and evaluates a body with those bindings in scope, which saves writing out the clones before a move closure. Each alias before the semicolon is either a name, which clones the variable of that name, or name = expression, which clones the value of the expression. The body follows the semicolon.
env_flag
Reads a presence-style environment switch once and caches the answer.
env_threshold_ms
Reads a millisecond-threshold environment variable once and caches it.
location_key
location_key() of the place it is written, worked out at build time instead of hashing the source path on every call.

Structs§

AnchorId
Stable identifier for a slot in the slot table.
ApplierGuard
A mutable applier borrow that drains recursive node disposal before returning.
BlockingExecutor
A bounded, lazily started executor for synchronous work.
BlockingExecutorConfig
Bounds for a native blocking executor. Running closures cannot be interrupted.
BlockingTask
Completion of an admitted job. Dropping it cancels work still waiting to run.
CallbackHolder
Keeps the latest zero-argument callback alive across recompositions. The forwarder from clone_rc always calls the callback stored last, and does nothing once the scope that stored it is no longer active.
CallbackHolder1
CallbackHolder1 keeps the latest single-argument callback closure alive across recompositions. It mirrors CallbackHolder but supports callbacks that receive one argument.
CancelToken
Cooperative cancellation token passed into background LaunchedEffect work.
CapturedCompositionContext
The composition context inherited by work that is composed in another slot host. Besides composition locals, this carries the source owner scope so a secondary tree cannot outlive the composition that supplied its callbacks.
Composer
The state of one composition pass. It writes the slot table and queues node changes for the applier. Clones share the same pass. Composable functions reach the current composer through with_current_composer.
Composition
A running composition that turns root content into nodes. A is the applier type that creates and edits those nodes.
CompositionLocal
A value that composables read from their surroundings without passing it as a parameter, as Jetpack Compose’s compositionLocalOf. A scope that reads current recomposes when the provided value changes.
CompositionPassDebugStats
The largest sizes that the command queues and the side effect list reached during one composition pass, for debugging memory use.
ConcreteApplierHost
An ApplierHost that stores one applier of the concrete type A.
DisposableEffectResult
What a DisposableEffect body returns: the cleanup to run when the effect is disposed. Make it with DisposableEffectScope::on_dispose.
DisposableEffectScope
The value a DisposableEffect body receives. Its on_dispose method makes the result that the body returns.
EventHandlerScopeGuard
Ends the event handler scope when dropped, restoring the setting that held before it.
LaunchedEffectScope
The scope a LaunchedEffect receives. It reports whether the effect is still active and queues follow-up work on the UI thread.
MemoryApplier
The stock Applier: it keeps nodes in memory under ids that stay stable for the life of the node.
MemoryApplierDebugStats
Sizes of a MemoryApplier’s tables, for leak and memory checks. A _len field counts entries and a _cap field the capacity reserved.
MovableContent
Movable content held as a value. See rememberMovableContentOf.
MutableState
Cheap copyable mutable view of a state cell.
NodeDisposal
Detached node identities and the resources that must outlive their unmount.
NodeMarks
Marks on the nodes of one MemoryApplier, for one walk over its tree.
OwnedMutableState
Owning state handle for reclaimable state cells.
ParamReturnState
A call’s stored parameters and the value its body last returned, held in one slot: a call that skips its body finds both with one lookup.
ParamSlot
ParamSlot holds function/closure parameters by ownership (no PartialEq/Clone required). Used by the #[composable] macro to store Fn-like parameters in the slot table.
ParamState
The parameters of one composable call, kept in a slot between recompositions so the call can skip its body when they are unchanged. Generated by the #[composable] macro.
ProvidedValue
A composition local paired with the value to provide, made by provides and passed to CompositionLocalProvider.
RecomposeOptions
Options that a composable group passes to its recompose scope.
RecomposeScope
The unit of recomposition. State read inside a scope invalidates it, and a recomposition runs only the content of the invalid scopes. Clones refer to the same scope.
RecomposeScopeRegistryDebugStats
Size of the registry of live recompose scopes, for leak checks.
RecycledNode
A removed node kept in a pool with its old id, so that a later node of the same type can reuse it.
RecycledNodeInsertion
The result of putting a recycled node back into an applier.
RetentionBudget
Limits on how much content a composition keeps for groups that left it. Content over a limit is evicted in the order of the RetentionEvictionPolicy.
RetentionPolicy
How a composition limits and evicts retained content: the budget it may keep and the order in which it drops subtrees that exceed the budget.
ReturnSlot
Holds the value a composable call returned, so a later composition that skips the call can return it again.
SceneNodeAttachmentScratch
Reusable ancestry storage for MemoryApplier::scene_nodes_attached_to_into.
SlotDebugAnchor
A live group anchor and the group it points at, in a SlotDebugSnapshot.
SlotDebugEntry
One row in the slot table dump returned by SlotTable::debug_dump_slot_entries.
SlotDebugGroup
One group of a slot table as seen in a SlotDebugSnapshot.
SlotDebugScope
A recompose scope and the group that owns it, in a SlotDebugSnapshot.
SlotDebugSnapshot
A copy of the groups, anchors and scopes of a slot table, for tests and diagnostics.
SlotRetentionDebugStats
Counters for subtrees the composer keeps for hidden content, from the retention state. Counts are in items and sizes are in bytes.
SlotTable
Storage for the groups, remembered values and nodes that one composition produced.
SlotTableDebugStats
Combined size and count figures for a slot table: the table’s own figures, its pending drops and its retained subtrees. Counts are in items and sizes are in bytes.
SlotTableLocalDebugStats
Size and count figures for one slot table, from SlotTable::debug_stats. Counts are in items and sizes are in bytes.
SlotTableMutationDebugStats
Counters for work the slot table does when groups move, from the table’s debug stats. *_count fields count operations or items summed over all operations; *_max_span fields hold the largest single operation.
SlotsHost
Holds a slot table into which a composition writes: the main composition has one, and each subcomposition has its own.
SnapshotStateList
A list whose reads subscribe the current scope and whose writes notify its readers, as Jetpack Compose’s SnapshotStateList. Clones share the same list.
SnapshotStateMap
A hash map whose reads subscribe the current scope and whose writes notify its readers, as Jetpack Compose’s SnapshotStateMap. Clones share the same map.
State
Cheap copyable read-only view of a state cell.
StateSubscriptionHold
Keeps a State counted as subscribed while alive; see State::subscription_hold.
StaticCompositionLocal
A composition local for values that rarely change, as Jetpack Compose’s staticCompositionLocalOf. A read of .current() subscribes nothing, so it costs less than a read of a CompositionLocal. In return, a provider whose value changes recomposes everything it provides to, not only the readers: every composable call under it runs its body, and every subcomposition under it composes again the same way.
TaskSite
Where an effect was written, carried onto the task it spawns.
ValueSlotHandle
A typed reference to a value stored in a slot, made by Composer::use_value_slot. It is valid for the composition pass that made it, and Composer::with_slot_value reads through it.

Enums§

BlockingError
Failure to admit or complete blocking work.
NodeError
An error from an applier or from applying composition commands to nodes.
Phase
The stage of a frame in which a composer is used.
RetentionEvictionPolicy
Which retained subtree is evicted first when a RetentionBudget is exceeded.
RetentionMode
What a group’s content becomes when the group leaves the composition.
SlotDebugEntryKind
The kind of row in the slot table dump returned by SlotTable::debug_dump_slot_entries.

Constants§

ROOT_RENDER_REPLAY_LIMIT
Upper bound on chained root-render replays and scope-recomposition rounds.

Traits§

Applier
Stores the nodes that a composition builds and applies changes to them. The UI layer supplies an applier; MemoryApplier is the stock one.
ApplierHost
Owns an applier and completes node disposal when an outstanding borrow ends.
Node
A node of the tree that a composition builds. An applier stores the nodes by id. Every method has a default, so a simple node implements none of them.
SharedParam
A parameter that points at a shared allocation: two that point at the same one are equal without comparing what it holds.

Functions§

CompositionLocalProvider
Makes values available to content and everything it composes. Where two values are for the same local, the last wins. Compose’s CompositionLocalProvider.
DisposableEffect
Runs effect when this call site first enters composition, and again whenever keys no longer equals the value it ran with last time; the previous run’s DisposableEffectScope::on_dispose cleanup, if any, runs first, and also when the call site leaves composition entirely.
LaunchedEffect
Runs effect when this call site first enters composition, and again whenever keys no longer equals the value it ran with last time.
LaunchedEffectAsync
Like LaunchedEffect, but mk_future builds the future to drive rather than receiving a scope to call back into synchronously.
SideEffect
Queues effect to run each time this call site is composed, after the node changes of the pass are applied. Compose’s SideEffect.
__launched_effect_async_impl
site is where the effect was written. It travels onto the task the effect spawns, so a task the runtime is still holding says which effect started it.
bubble_layout_dirty
Unified API for bubbling layout dirty flags from a node to the root (Applier context).
bubble_layout_dirty_in_composer
Unified API for bubbling layout dirty flags from a node to the root (Composer context).
bubble_measure_dirty
Unified API for bubbling measure dirty flags from a node to the root (Applier context).
bubble_measure_dirty_in_composer
Unified API for bubbling measure dirty flags from a node to the root during composition.
bubble_semantics_dirty
Unified API for bubbling semantics dirty flags from a node to the root (Applier context).
bubble_semantics_dirty_in_composer
Unified API for bubbling semantics dirty flags from a node to the root (Composer context).
compositionLocalOf
Creates a CompositionLocal whose default is made by default. A provided value replaces the previous one when it differs by ==. Compose’s compositionLocalOf.
compositionLocalOfWithPolicy
Creates a CompositionLocal whose default is made by default. A provided value replaces the previous one only when equivalent returns false for the two.
derivedStateOf
A state computed from other states, as in Kotlin.
dispatch_ui_event
Dispatches a UI event in a proper snapshot context.
enter_event_handler_scope
Marks the thread as inside an event handler until the returned guard is dropped. In debug builds, a state write there that is not inside a snapshot logs a warning.
forget_movable
Releases the state of movable content with identity key that no parent is showing. Call it when the item is closed for good, from an event handler or inside composition. Content a parent is still showing is unaffected. Needs a runtime: an active composition or one created on this thread.
in_applied_snapshot
Returns true if currently in an applied snapshot context.
in_event_handler
Returns true if currently in an event handler context.
key
Scopes composition identity to keys for the duration of content.
launchBlocking
Starts blocking work and delivers its result on the current runtime’s UI thread. A full queue waits asynchronously inside the runtime-owned task. Execution errors are delivered to on_ui; only a missing runtime is returned immediately without invoking the callback.
location_key
Returns the key of a source location: a hash of the file path together with the line and column. The same location always gives the same key.
movable
Composes content under an identity that is key alone, the same at every call site, so the subtree can be emitted from any parent and keep its remembered values, its running effects and its nodes.
movableContentOf
Movable content whose identity is key, the same at every call site.
mutableStateList
Creates an empty snapshot-aware list. Must be called during composition.
mutableStateListOf
Creates a snapshot-aware list holding values. Must be called during composition. Compose’s mutableStateListOf.
mutableStateMap
Creates an empty snapshot-aware map. Must be called during composition.
mutableStateMapOf
Creates a snapshot-aware map holding pairs. Must be called during composition. Compose’s mutableStateMapOf.
mutableStateOf
Creates a new MutableState initialized with the given value.
mutableStateOfNeverEqual
Like mutableStateOf, for a value that cannot be compared or whose every write must count as a change.
ownedMutableStateOf
Creates an OwnedMutableState holding initial, which is released when its owner is dropped. Writing an equal value is not a change. Panics without an active runtime.
ownedMutableStateOfNeverEqual
Like ownedMutableStateOf, for a value that cannot be compared.
pop_parent
Closes the parent that the matching push_parent opened, using the current composer. Must be called during composition.
push_parent
Makes the node id the parent of the nodes emitted next, using the current composer. Needs a matching pop_parent. Must be called during composition.
queue_semantics_invalidation
Schedules semantics bubbling for a node using the active composer if present.
refresh_param
Updates one stored parameter to new and says whether it differed, reusing the stored value’s allocations where Clone::clone_from can.
refresh_shared_param
refresh_param for an Rc or Arc parameter: the same allocation is unchanged without comparing its contents, which PartialEq on a pointer to a type that is not Eq otherwise walks in full on every recomposition.
remember
Returns the value init made on the first composition at this call site. Later compositions return the same value until the call site leaves the composition. Compose’s remember.
rememberKeyed
Like remember, but recomputes whenever key changes.
rememberMovableContentOf
Content written once that keeps its identity wherever it is shown.
rememberMutableStateOf
A composable hook that creates and remembers a MutableState.
rememberMutableStateOfNeverEqual
Like rememberMutableStateOf, for a value that cannot be compared or whose every write must count as a change.
rememberUpdatedState
Returns a MutableState that always holds the latest value.
run_in_mutable_snapshot
Runs the provided closure inside a mutable snapshot and applies the result.
staticCompositionLocalOf
A StaticCompositionLocal whose provided values compare with ==.
staticCompositionLocalOfWithPolicy
A StaticCompositionLocal whose provider recomposes its content when equivalent says a new value differs from the last one.
try_mutableStateOf
Like mutableStateOf but returns None if no runtime is available.
withBlocking
Runs synchronous work on the shared bounded executor when first polled.
withCurrentComposer
Runs f with the composer that is current on this thread. Panics if there is none. Same as with_current_composer.
with_key
Runs content in a group identified by key, so state and nodes follow the key when siblings move. Like key for a single key and no return value.
with_node_mut
Runs f on the node id as an N, using the current composer. Returns an error if the node does not exist or is not an N. Must be called during composition.

Type Aliases§

Key
Identifies a composition group: the hash of its call site, or of an explicit key together with its call site.
NodeId
Identifies a node in an applier.