@buddhacognitivelab/state-manager
v1.0.1
Published
Central state management package for Fluid Buddha Design System
Downloads
10
Maintainers
Readme
@fluid-buddha/state-manager
Central state management package for the Fluid Buddha Design System. Provides a type-safe, performant, and predictable state management solution using Zustand with Immer for immutable updates.
Features
- 🏪 Centralized Store: Single source of truth for application state
- 🔄 Immutable Updates: Built-in Immer integration for safe state mutations
- 🎯 Type Safety: Full TypeScript support with strict typing
- 🎨 Theme Management: Dynamic theme and skin switching
- 🌌 Spatial Layout: 3D zone management and camera controls
- 🎤 Voice Engine: Voice recognition and synthesis state
- 🤖 AI Integration: AI processing and conversation management
- 🔧 DevTools: Redux DevTools integration for debugging
- ⚡ Performance: Selective subscriptions to prevent unnecessary re-renders
Installation
npm install @fluid-buddha/state-manager
# or
yarn add @fluid-buddha/state-managerQuick Start
Basic Usage
import { useFluidBuddhaStore } from '@fluid-buddha/state-manager';
function MyComponent() {
// Subscribe to specific state (prevents unnecessary re-renders)
const activeTheme = useFluidBuddhaStore(state => state.activeTheme);
const setTheme = useFluidBuddhaStore(state => state.theme.setTheme);
return (
<div>
<p>Current theme: {activeTheme?.name}</p>
<button onClick={() => setTheme(newTheme)}>
Change Theme
</button>
</div>
);
}Multiple State Subscriptions
function VoiceStatus() {
const { engineStatus, isListening, isMuted } = useFluidBuddhaStore(state => ({
engineStatus: state.engineStatus,
isListening: state.isListening,
isMuted: state.isMuted
}));
return (
<div>
<p>Status: {engineStatus}</p>
<p>Listening: {isListening ? 'Yes' : 'No'}</p>
<p>Muted: {isMuted ? 'Yes' : 'No'}</p>
</div>
);
}Actions Only (No Re-renders)
function ActionButtons() {
// Get actions without subscribing to state changes
const actions = useFluidBuddhaStoreActions();
return (
<div>
<button onClick={() => actions.theme.clearTheme()}>
Clear Theme
</button>
<button onClick={() => actions.voice.startListening()}>
Start Listening
</button>
</div>
);
}State Structure
The store is organized into four main slices:
Theme State
interface ThemeState {
activeTheme: Theme | null;
activeSkin: Skin | null;
}
interface ThemeActions {
setTheme: (theme: Theme) => void;
setSkin: (skin: Skin) => void;
clearTheme: () => void;
}Spatial State
interface SpatialState {
layout: { zones: ZoneConfig[] } | null;
activeZoneId: string | null;
camera: {
position: [number, number, number];
target: [number, number, number];
};
}
interface SpatialActions {
setLayout: (layout: { zones: ZoneConfig[] }) => void;
setActiveZone: (zoneId: string) => void;
updateCamera: (position: [number, number, number], target: [number, number, number]) => void;
createZone: (zone: Omit<ZoneConfig, 'id'>) => string;
updateZone: (zoneId: string, updates: Partial<Omit<ZoneConfig, 'id'>>) => void;
deleteZone: (zoneId: string) => void;
// ... more actions
}Voice State
interface VoiceState {
engineStatus: 'IDLE' | 'INITIALIZING' | 'LISTENING' | 'PROCESSING' | 'SYNTHESIZING' | 'ERROR';
isInitialized: boolean;
isMuted: boolean;
isListening: boolean;
vad: VoiceActivityDetection;
currentTranscript: {
text: string;
confidence: number;
isFinal: boolean;
timestamp: number;
};
// ... more properties
}
interface VoiceActions {
initializeEngine: (config?: Partial<VoiceEngineConfig>) => Promise<boolean>;
startListening: () => void;
stopListening: () => void;
toggleMute: () => void;
updateTranscript: (text: string, confidence: number, isFinal: boolean) => void;
// ... more actions
}AI State
interface AIState {
isProcessing: boolean;
lastResponse: string | null;
conversationHistory: Array<{
id: string;
role: 'user' | 'assistant';
content: string;
timestamp: number;
}>;
error: string | null;
}
interface AIActions {
setProcessing: (processing: boolean) => void;
setLastResponse: (response: string) => void;
addToHistory: (role: 'user' | 'assistant', content: string) => void;
clearHistory: () => void;
setError: (error: string | null) => void;
}Advanced Usage
Custom Store Instance
import { createFluidBuddhaStore } from '@fluid-buddha/state-manager';
// Create a custom store instance
const customStore = createFluidBuddhaStore();
// Use with custom hook
function useCustomStore<T>(selector: (state: FluidBuddhaStore) => T): T {
return useStore(customStore, selector);
}Direct Store Access (Non-React)
import { store } from '@fluid-buddha/state-manager';
// Get current state
const currentState = store.getState();
// Subscribe to changes
const unsubscribe = store.subscribe((state) => {
console.log('State changed:', state);
});
// Update state
store.getState().theme.setTheme(newTheme);
// Cleanup
unsubscribe();Immer Utilities
import { withImmer, createImmerUpdater } from '@fluid-buddha/state-manager';
// Use Immer utilities for complex state updates
const updateComplexState = createImmerUpdater((draft, payload) => {
draft.someNestedProperty.value = payload.newValue;
draft.anotherProperty.push(payload.newItem);
});Performance Considerations
Selective Subscriptions
// ✅ Good - Only re-renders when activeTheme changes
const activeTheme = useFluidBuddhaStore(state => state.activeTheme);
// ❌ Bad - Re-renders on any state change
const state = useFluidBuddhaStoreState();
const activeTheme = state.activeTheme;Memoized Selectors
import { useMemo } from 'react';
function ExpensiveComponent() {
const expensiveValue = useFluidBuddhaStore(
useMemo(
() => (state) => {
// Expensive computation
return state.zones.filter(zone => zone.isActive).length;
},
[]
)
);
return <div>Active zones: {expensiveValue}</div>;
}Development
Building
npm run buildTesting
npm test
npm run test:watchType Checking
npm run type-checkLinting
npm run lintArchitecture
The state manager follows a slice-based architecture where each domain (theme, spatial, voice, AI) is managed in its own slice. All slices are combined into a single store with middleware for development tools and immutable updates.
@fluid-buddha/state-manager/
├── src/
│ ├── store/
│ │ ├── createStore.ts # Main store creation
│ │ └── types.ts # Type definitions
│ ├── slices/
│ │ ├── themeSlice.ts # Theme state management
│ │ ├── spatialSlice.ts # Spatial layout management
│ │ ├── voiceSlice.ts # Voice engine management
│ │ └── aiSlice.ts # AI processing management
│ ├── hooks/
│ │ └── useFluidBuddhaStore.ts # React hooks
│ ├── utils/
│ │ └── immerUtils.ts # Immer utilities
│ └── constants.ts # Default valuesDependencies
- zustand: Core state management library
- immer: Immutable state updates
- react: Peer dependency for hooks
License
MIT License - see LICENSE file for details.
Contributing
See the main project README for contribution guidelines.
