Internals: Core Engine Architecture
SoulState's engine is designed for deterministic updates, high-performance dispatch, and extreme scalability. It separates state management, dependency tracking, and update orchestration into distinct, optimized modules that form a Reactive Graph Runtime.
Architecture Overview
SoulState's runtime architecture consists of six primary components:
- StoreApi: The public interface (
getState,setState,subscribe,computed). - Runtime: The central orchestrator (in
src/core/runtime.ts) that manages the state transition and coordination pipeline. - InvalidationGraph: A Directed Acyclic Graph (DAG) for tracking state-to-subscriber and state-to-computed relationships (in
src/internals/graph.ts). - SubscriptionManager: A high-performance dual linked-list system for global and granular subscribers (in
src/core/subscriptions.ts). - Scheduler: A deterministic microtask-based batching engine (in
src/core/scheduler.ts). - TransactionEngine: A transaction buffering system with begin/commit/rollback lifecycle (in
src/core/transactions.ts).
graph TD
A[Public API] -->|setState| B[Runtime];
B -->|Batching| C[Scheduler];
C -->|Microtask| D[Runtime.processUpdate];
D -->|Bitmask/Key Dispatch| E[SubscriptionManager];
D -->|Graph Invalidation| F[InvalidationGraph];
F -->|Affected Nodes by Level| G[Level-by-Level Propagation];
G --> H[Surgical Dispatch];
H --> I[Component/Listener];
The Runtime Orchestrator
The Runtime class is the nervous system of SoulState. It manages the current and previous states and ensures that updates are batched and dispatched with systems-grade precision.
The Update Pipeline
When setState is called, the following happens:
- State Apply: The new partial state is applied immediately to the internal state tree.
- Key Detection: SoulState identifies which top-level keys changed.
- Scheduling: An update is requested via the
Scheduler. - Topological Propagation: During the flush phase, the
Runtimetraverses theInvalidationGraphin level order.
// src/core/runtime.ts (simplified logic)
processUpdate() {
const currentState = this.state;
const flushId = ++this.flushId;
this.subscriptions.startBatch();
// Phase 1: Bitmask/Key-based fast-path dispatch
if (this.changedKeys.size <= 64) {
this.subscriptions.notifyBitmask(currentState, this.maskLow, this.maskHigh, flushId);
} else {
this.subscriptions.notifyKeys(currentState, this.changedKeys, flushId);
}
// Phase 2: Graph-based granular notification (level-ordered)
if (this.hasGranularListeners) {
this.graph.invalidate(this.changedKeys, flushId);
const affectedByLevel = this.graph.consumeAffectedNodes();
if (affectedByLevel) {
for (const nodes of affectedByLevel) {
if (!nodes) continue;
for (const node of nodes) {
this.dispatch(node, currentState);
}
}
}
}
// Phase 3: Global listener notification
this.subscriptions.notify(currentState, this.prevState, flushId);
this.subscriptions.endBatch();
this.changedKeys.clear();
}
Invalidation Graph & Surgical Precision
SoulState uses an Invalidation Graph to map dependencies. Unlike global-broadcast systems, it knows exactly which leaf nodes in the tree are affected by a change at level 0.
Topological Leveling
To prevent "glitches" (inconsistent state views), every node in the graph is assigned a level:
- State Keys: Level 0.
- Computeds that depend directly on state are Level 1.
- Computeds that depend on other Computeds are Level 2, 3, etc.
- Subscribers are assigned levels based on their specific dependency chain.
Updates are processed level-by-level, ensuring that a node only executes after all its own dependencies have settled.
Runtime Observability
SoulState includes built-in metrics tracking via RuntimeMetrics (in src/internals/metrics.ts). This system records:
- Flush Durations: Time taken to propagate an update.
- Selector Runs: Number of times selectors are executed per flush.
- Invalidations: Number of nodes invalidated in the graph.
These metrics can be exposed via store.getMetrics() or used with enableInstrumentation for real-time profiling of your systems-grade runtime.