SoulCache

Architecture

Understand how SoulCache is designed and built

Architecture

SoulCache is designed with a modular, layered architecture that separates concerns while maintaining high performance.

High-Level Overview

Core Components

QueryClient

The central orchestration layer that owns all major subsystems:

  • Request deduplication via _pendingFetches Map
  • Query lifecycle management via QueryStateMachine instances
  • Observer coordination via QueryObserver instances
  • Mutation execution via MutationCache
  • Event emission via EventBus
  • Task scheduling via Scheduler

QueryEngine

QueryEngine is a higher-level wrapper around QueryClient that adds retry support (via RetryEngine), background refetch intervals, and stale-time-aware cache reads. Use QueryClient for direct control, or QueryEngine for automatic retry and polling.

CacheEngine

In-memory cache with O(1) Map-based lookups:

  • Automatic garbage collection based on gcTime
  • Stale-while-revalidate via staleTime
  • LRU eviction for memory management
  • Dependency tracking for invalidation propagation
  • Version tracking for consistency

MutationCache

Manages mutation lifecycle and optimistic updates:

  • MutationEntry creation and tracking
  • Optimistic update context management
  • Simple retry via MutationEntry.mutateWithRetry()
  • State machine for mutation states (idle → pending → success/error)

Scheduler

Priority-based task execution engine:

  • Priority levels: critical > high > normal > low > idle
  • Batch execution with observer notification deduplication
  • Task dependency resolution with circular dependency detection

EventBus

Internal typed event system for module communication:

  • FIFO event delivery
  • Typed subscriptions with event log
  • Decouples modules without direct dependencies

Query Execution Flow

Module Map

ModuleKey ClassesExported
client/QueryClientYes
query/QueryEngine, QueryStateMachineBoth
cache/CacheEngine, QueryEntryYes
mutation/MutationEntry, MutationCache, MutationObserverYes
infinite/InfiniteQueryYes
retry/RetryEngineNo (internal)
scheduler/Scheduler, createTaskYes
storage/StorageManager, MemoryAdapter, PersistenceCoordinatorYes
events/EventBusYes
observer/QueryObserverQueryObserver only
plugin/PluginManagerNo (internal)
hydration/dehydrate, hydrate, serialize, deserializeYes
subscription/SubscriptionManagerYes
snapshot/QuerySnapshotManagerYes
fetcher/FetcherNo (internal)

Packages

PackagePurpose
@soulcache/coreCore runtime with all modules
@soulcache/reactReact hooks via useSyncExternalStore
@soulcache/devtools-coreFramework-agnostic inspection layer
@soulcache/devtoolsReact DevTools panel

Design Principles

Separation of Concerns

Each module has a single responsibility:

  • CacheEngine: In-memory storage and eviction only
  • QueryClient: Orchestration and deduplication only
  • Scheduler: Task execution and batching only
  • EventBus: Cross-module communication only

Zero Runtime Dependencies

SoulCache has no runtime dependencies. All functionality is built from scratch for:

  • Minimal bundle size
  • No supply chain risks
  • Full control over behavior

Framework Independence

The core runtime is framework-agnostic. The React adapter provides hooks built on useSyncExternalStore for React 18+ concurrent mode compatibility.

Type Safety

End-to-end TypeScript with:

  • Strict mode enabled
  • Minimal any usage in source
  • Full inference support
  • Comprehensive type exports

Performance Characteristics

OperationTime ComplexitySpace Complexity
Cache GetO(1)O(1)
Cache SetO(1)O(1)
Observer NotifyO(n)O(1)
Query DedupO(1)O(1)
Mutation LookupO(1)O(1)

On this page