armature library

Core public surface of package:armature.

This barrel exposes the ~25 symbols needed to author features, stores, tasks, and declare ports. Framework plumbing — internal typedefs, port base classes, debug mirrors, and the individual TaskStrategy* constructors — lives in package:armature/advanced.dart. Reach for it only when you need to annotate a field with a handler signature, build a debug overlay, or extend the framework itself.

Classes

AppContainer
Manages feature lifecycle, dependency resolution, and port application.
Behavior<TBranch extends Enum, TPayload extends Object?, THandler extends BehaviorHandler<TBranch, TPayload>>
Port that selects the highest-priority handler descriptor.
BehaviorDescriptor<TBranch extends Enum, TPayload extends Object?>
Descriptor returned by a behavior handler, specifying branch and payload.
Cleanup
Bag of cleanup callbacks collected during onStart, executed in LIFO order on feature deactivation.
ContainerOptions
Configuration options for an AppContainer.
Feature<TStores extends Object?, TExports extends Object?, TPorts extends Object?>
A modular unit of functionality with typed stores and dependencies.
FeatureHandlerContext
Context passed to port handlers (usePipe / useBehavior / slot handlers). Exposes the feature's own stores plus a parent accessor for declared parent stores and a container reference for framework-internal plumbing.
FeatureParentApi
Provides typed access to parent feature stores for a specific AppContainer.
FeatureScopeApi<TStores>
Typed scope passed into a feature's own callbacks — activation setup, onStart, and port handlers registered via usePipe / useBehavior.
Logger
Interface for logging framework events.
Pipe<TValue extends Object, THandler extends PipeHandler<TValue>>
Port that chains handlers to transform a value sequentially.
PrintLogger
Logger that routes messages to print (the Dart / Flutter console). Suitable for local development; consider a structured logger (or your observability stack's adapter) for production.
Store<TState extends Object?>
Base class for feature stores with reactive state.
Task<TParams, TResult, TError>
Async operation with an observable state machine (TaskState).
TaskDone<TParams, TResult, TError>
The most recent Task.call completed successfully with result.
TaskFailed<TParams, TResult, TError>
The most recent Task.call threw an error of type TError.
TaskIdle<TParams, TResult, TError>
The task has not started yet, or the previous non-matching throw reverted it.
TaskPending<TParams, TResult, TError>
The task is currently executing with params.
TaskState<TParams, TResult, TError>
Atomic snapshot of a Task's lifecycle. Observers see a single value that transitions through the cases below.
TaskStrategy
Execution strategy for a Task.

Enums

ContainerStatus
Lifecycle status of a AppContainer.
FeatureResolutionReason
Reason classification for FeatureResolutionError. Lets callers distinguish configuration errors (e.g. missing parent) from runtime failures (e.g. stores factory threw) without parsing the message.
FeatureStatus
Lifecycle state of a feature, as observed from the AppContainer.
LogLevel
Severity levels for log messages, ordered from least to most severe. Loggers compare by LogLevel.index to implement minimum-level filtering.
ThrottleEdge
Edge semantics for TaskStrategy.throttle.
ToggleState
Target state a FeatureToggle call sets the feature to.

Extensions

TaskStateExtensions on TaskState<TParams, TResult, TError>
Ergonomic pattern matching for TaskState. when requires all four branches and is checked for exhaustiveness; maybeWhen accepts a subset and falls through to orElse. Boolean and nullable getters give one-line access to a specific branch.

Functions

createBehavior<TBranch extends Enum, TPayload extends Object?>({required String name, Feature<Object?, Object?, Object?>? feature}) Behavior<TBranch, TPayload, BehaviorHandler<TBranch, TPayload>>
Creates a Behavior owned by feature.
createFeature<TStores extends Object?, TExports extends Object?, TPorts extends Object?>({required String name, List<AnyFeature> dependsOn = const [], List<AnyFeature> optionalDependsOn = const [], TPorts? ports, StoresFactory<TStores>? stores, ExportsFactory<TStores, TExports>? exports}) Feature<TStores, TExports, TPorts>
Creates a Feature with typed dependencies, stores, and exports.
createPipe<TValue extends Object>({required String name, Feature<Object?, Object?, Object?>? feature}) Pipe<TValue, PipeHandler<TValue>>
Creates a Pipe, optionally owned by feature.
manualActivation() ActivationSetup
Activation setup that installs no triggers — the feature stays FeatureStatus.disabled until driven externally via AppContainer.toggleFeature(feature, ToggleState.active).
whenActive(AnyFeature feature) ActivationSetup
Activation setup that mirrors a declared parent feature's lifecycle — the owning feature toggles .active whenever feature is FeatureStatus.active, .inactive otherwise.
whenAllActive(List<AnyFeature> features) ActivationSetup
Activation setup that stays .active only while every parent in features is FeatureStatus.active. Any parent flipping away from .active deactivates the owning feature; a return to "all active" re-activates it.
whenInactive(AnyFeature feature) ActivationSetup
Inverse of whenActive — the owning feature is active while feature is not FeatureStatus.active (i.e. .disabled or .pending). Useful for fallback / "offline" UI features that live only while their main counterpart is off.
whenStoreState<TExports, TState>({required Feature<dynamic, TExports, dynamic> feature, required Store<TState> store(TExports exports), required bool predicate(TState state)}) ActivationSetup
Activation setup that gates the feature on a Store reached through a declared parent feature's exports.

Typedefs

ActivationSetup = FutureOr<void> Function(FeatureParentApi parentApi, FeatureToggle toggle, Cleanup cleanup)
Imperative setup for reactive feature activation.
AnyFeature = Feature
Type alias for a Feature with all type parameters erased.
ContainerErrorHandler = void Function({required ArmatureError error, required Map<String, String> meta, required String source})
Error handler callback for recoverable feature errors.
ExportsFactory<TStores, TExports> = TExports Function(FeatureScopeApi<TStores> api)
Synchronous factory that builds this feature's public exports record.
FeatureToggle = Future<void> Function(ToggleState state)
Callable that sets a feature's activation state from user code.
StartCallback<TStores> = FutureOr<void> Function(FeatureScopeApi<TStores> api, Cleanup cleanup)
Per-activation callback run by AppContainer on inactive→active transitions. The user registers teardown via cleanup.add(disposer) — all registered disposers run in LIFO order on deactivation.
StoresFactory<TStores> = TStores Function(FeatureParentApi parentApi)
Synchronous factory that builds this feature's stores record. Runs once during AppContainer.start's construct phase with the feature's FeatureParentApi, so it can reach already-built parent stores.

Exceptions / Errors

ArmatureError
Base class for every error the framework produces.
ContainerError
Thrown when an AppContainer operation is invoked in the wrong lifecycle state — e.g. double start() without an intervening stop(), apply() before start().
ContainerUsageError
Thrown when AppContainer is used in a way that can only be a bug in calling code: stop() from inside a user callback (would self-deadlock), reaching into orchestrator internals before start(), etc.
FeatureConfigurationError
Thrown when a Feature is misconfigured: activation() / onStart() called more than once, a duplicate Store registered under the same runtime type inside the same feature, or a feature's scope API accessed before its construct phase.
FeatureResolutionError
Thrown when a feature fails to resolve during AppContainer.start(). The reason field pins down which kind of failure this is; message has the human-readable details.
HandlerError
Reported to ContainerErrorHandler when a user-supplied handler — an activation setup, onStart, or a port handler (usePipe / useBehavior / useSingleSlot / useMultiSlot) — throws.
ListenerError
Reported to ContainerErrorHandler when a user-supplied event listener registered via AppContainer.onFeatureStatusChanged or AppContainer.onPortChanged throws. Never thrown directly — one misbehaving listener never breaks siblings or bubbles up into framework code.
PortError
Thrown when a port is used incorrectly — duplicate handler from the same feature, handler registered by the owner, handler registered by a feature that didn't declare the owner as a parent.
RenderError
Reported to ContainerErrorHandler when a slot widget's build throws. Never thrown directly — the slot renders a fallback widget (or the application's errorBuilder) instead.
StoreLookupError
Thrown when FeatureHandlerContext.store cannot find a store by type.
TaskError
Thrown when a Task is called after it — or the owning Store — has been disposed, or surfaced through a pending future when Task.reset() cancels coalesced callers from .latest, .debounce, or .throttle(trailing).