Spell Architecture
This guide provides a deep dive into the technical architecture of Cedar-OS’s spell system, explaining how spells work under the hood and how the various components interact.Architecture Overview
The spell system consists of three main components working in harmony:- useSpell Hook - React interface for components
- SpellSlice - State management and coordination
- SpellActivationManager - Event handling and routing
Component Deep Dive
1. SpellActivationManager
TheSpellActivationManager
is a singleton class that manages all low-level event handling for spells. It’s the bridge between DOM events and spell activations.
Key Responsibilities
- Centralized Event Listening: Maintains a single set of event listeners for all spells
- Event Routing: Routes events to the appropriate registered spells
- Activation Logic: Handles different activation modes (toggle, hold, trigger)
- Performance Optimization: Prevents duplicate listeners and manages cleanup
How It Works
- Event Detection: Captures keyboard, mouse, and selection events
- Spell Matching: Checks which registered spells should respond
- State Management: Tracks held keys, cooldowns, and active states
- Callback Execution: Triggers appropriate spell callbacks
Event Processing Flow
2. SpellSlice
TheSpellSlice
is a Zustand store slice that provides high-level spell management and integrates with Cedar’s state system.
Core State Structure
Integration Points
The SpellSlice acts as the coordination layer:- Store Integration: Provides access to Cedar store for spell callbacks
- Lifecycle Management: Handles spell registration/unregistration
- State Synchronization: Keeps UI state in sync with activation manager
- Programmatic Control: Enables manual spell activation/deactivation
Registration Flow
When a spell is registered:3. useSpell Hook
TheuseSpell
hook provides the React-friendly interface for components to use spells.
Hook Lifecycle
Performance Optimizations
- Ref-based Callbacks: Prevents unnecessary re-registrations
- Dependency Tracking: Only re-registers when conditions change
- Automatic Cleanup: Ensures no memory leaks
Activation Modes Explained
Toggle Mode
- User presses key/button → spell activates
- User presses again → spell deactivates
- Good for persistent UI elements
Hold Mode
- Activates on keydown/mousedown
- Deactivates on keyup/mouseup
- Perfect for temporary overlays
Trigger Mode
- Fires once when triggered
- Auto-deactivates after brief period
- Optional cooldown prevents spam
Event Processing Details
Keyboard Event Handling
The system handles both single keys and combinations:Mouse Event Handling
Mouse events include position tracking:Selection Event Handling
Text selection is debounced for performance:Performance Considerations
Event Listener Management
The system uses a single set of listeners for all spells:Memory Management
- Singleton Pattern: One manager instance for entire app
- Automatic Cleanup: Listeners removed when no spells registered
- Ref-based Callbacks: Prevents closure memory leaks
React Integration
The hook optimizes React re-renders:Advanced Features
Input Element Handling
Spells can be configured to ignore input elements:Cooldown System
Prevents rapid re-triggering:Multi-Event Support
Spells can respond to multiple triggers:Data Flow Diagram
Best Practices for Performance
1. Use Appropriate Activation Modes
2. Optimize Spell IDs
3. Leverage Refs for Callbacks
4. Consider Event Delegation
For many similar spells, consider a single parent spell:Debugging Spells
Enable Debug Logging
Monitor Registration
Track Event Flow
Add logging to understand event propagation:Summary
The spell architecture provides a robust, performant system for gesture-based interactions:- Centralized Management: Single manager handles all events efficiently
- React Integration: Hooks provide clean component interface
- State Synchronization: Zustand slice keeps everything in sync
- Performance Optimized: Singleton pattern, ref-based callbacks, debouncing
- Flexible Activation: Multiple modes and event types supported