Skip to main content

Batching & Deterministic Flush

Batching is the process of grouping multiple state updates into a single propagation cycle. SoulState provides two layers of batching: Automatic Microtask Batching and Explicit Transactions.

Layer 1: Automatic Microtask Batching

By default, every setState call in SoulState is deferred to the microtask queue using queueMicrotask.

  • Mechanism: When setState is called, the store schedules a "flush" in the next microtask. If more setState calls occur before that microtask executes, they are all merged into the same flush.
  • Benefit: This eliminates redundant re-renders and ensuring that components only see the final, "settled" state of a synchronous block of code.
function handleMultipleUpdates() {
store.setState({ a: 1 });
store.setState({ b: 2 });
store.setState({ c: 3 });

// Only ONE propagation cycle occurs after this function exits.
}

Layer 2: Explicit Transactions

For complex, multi-step operations that may span asynchronous boundaries or require atomicity with rollback support, SoulState provides a Transaction Engine.

store.beginTransaction();

try {
store.setState({ user: { name: 'Bob' } });
store.setState({ status: 'active' });

if (someError) throw new Error();

store.commitTransaction(); // Triggers exactly one flush
} catch (e) {
store.rollbackTransaction(); // State is restored, no flush occurs
}

Transaction Characteristics

  • Buffering: Updates are kept in a local buffer and are not applied to the main state tree until commitTransaction.
  • Atomic Propagation: Downstream subscribers (computeds, listeners, React components) are only notified once the transaction commits.
  • Rollback: If something goes wrong, you can discard the buffered changes entirely.

Deterministic Flush Ordering

SoulState's propagation engine ensures that once a batch or transaction is ready to flush, the updates are processed in a deterministic topological order.

  1. Key Settlement: All keys changed in the batch are identified.
  2. Level Sorting: Affected nodes in the InvalidationGraph are sorted by their topological level (Depth in the dependency tree).
  3. Topological Propagation: Level 1 nodes are notified, followed by Level 2, and so on.

This ordering is critical to prevent "Glitches"—situations where a component or computed value sees an inconsistent state because one of its dependencies updated before another.

Systems-Grade Consistency

By combining microtask batching with topological ordering, SoulState provides a deterministic execution environment where your UI state is always consistent, regardless of update complexity.