KOS applications take a fundamentally different approach to state management compared to traditional web applications. Instead of managing distributed client state, KOS maintains a centralized source of truth that mirrors physical device reality.
The State Management Spectrum
Traditional Web App State Distribution
Traditional web applications spread state across multiple layers:
Client-Side State:
- Component local state (useState)
- Application state (Redux, Zustand, Context)
- Form state (React Hook Form, Formik)
- UI state (modals, loading, errors)
Server-Side State:
- Database records
- Session data
- Cache layers
- Background job status
Synchronization Challenges:
- Client state may be stale
- Cache invalidation complexity
- Optimistic update rollbacks
- Multiple users seeing different data
KOS Centralized State Philosophy
KOS applications maintain one authoritative source of truth: the backend that communicates with physical devices.
Single Source of Truth:
- Backend maintains current device state
- All clients receive same authoritative data
- No client-side state management needed for device data
- UI is a visualization layer, not a state container
Device Reality as State Authority
Physical Devices Define Truth
In KOS applications, physical reality determines what the state actually is:
- Temperature sensor reading = actual temperature
- Door position sensor = actual door state
- Ingredient level sensor = actual ingredient amount
- Motor encoder = actual position
Traditional Web Apps:
State is what the application says it is
KOS Apps:
State is what the physical device says it is
Models Reflect, Don’t Create State
KOS models are mirrors of device state, not independent state containers:
Not This (State Creation):
// Creating application state
const [temperature, setTemperature] = useState(20)
const [isHeating, setIsHeating] = useState(false)
// User interaction changes local state
const handleHeatUp = () => {
setIsHeating(true)
setTemperature(temp => temp + 1)
}But This (State Reflection):
// Model reflects actual device state
@kosModel({ modelTypeId: "heater-model", singleton: false })
class HeaterModel {
currentTemperature: number // From temperature sensor
isHeating: boolean // From heater controller
// User interaction sends command to device
startHeating(): Future<void> {
return this.sendCommand('/heater/start')
// State updates come from device, not local changes
}
@kosTopicHandler({ topic: '/sensors/temperature' })
handleTemperatureUpdate(temp: number): void {
this.currentTemperature = temp // State comes from device
}
}State Ownership Patterns
Traditional State Ownership
In traditional apps, different parts own different state:
Component Ownership:
- Form components own form data
- List components own filtering/sorting state
- Modal components own open/closed state
Global Ownership:
- Store owns application data
- Context owns shared preferences
- Server owns persisted data
Synchronization Required:
Components must sync with global state, global state must sync with server
KOS State Ownership
In KOS apps, devices own their own state:
Device Ownership:
- Temperature sensor owns temperature readings
- Door controller owns door position
- Dispenser owns pour status
- System controller owns operational mode
Model Subscription:
- Models subscribe to device state changes
- UI subscribes to model state changes
- No ownership conflicts or sync issues
The Flow of State Changes
Traditional State Flow (Bidirectional)
UI Component ←→ Local State ←→ Global State ←→ API ←→ Server ←→ DatabaseChanges can originate from any level and must be synchronized across all levels.
KOS State Flow (Unidirectional)
Physical Device → Backend → WebSocket → Model → UI Component
↑
User Interaction → CommandState changes originate from physical devices and flow in one direction to the UI.
Implications for Development
No Client-Side State Management Complexity
Traditional Challenges Eliminated:
- No stale data problems
- No cache invalidation strategies needed
- No optimistic update rollbacks
- No state synchronization bugs
- No race conditions between client updates
KOS Benefits:
- UI always shows current device state
- State updates are automatic
- No manual refresh needed
- Consistent data across all clients
Different State Categories
Device State (Managed by KOS):
- Sensor readings
- Actuator positions
- System operational status
- Device configuration
UI State (Managed by React):
- Modal open/closed
- Form validation messages
- Loading indicators
- Animation states
Clear Separation:
Device-related state is managed by KOS models
UI-related state is managed by React components
State Consistency Guarantees
Traditional Consistency Challenges
Eventually Consistent:
- Client state may be temporarily out of sync
- Multiple clients may see different data
- Manual refresh required to get latest state
Optimistic Updates:
- UI shows assumed state before confirmation
- Must handle rollback on failure
- Can show impossible states
KOS Consistency Guarantees
Always Current:
- UI reflects actual device state
- All clients see same authoritative data
- Automatic updates when devices change
No Optimistic Updates:
- UI only shows confirmed device state
- No rollback scenarios needed
- Never shows impossible device states
State Persistence Philosophy
Traditional Persistence
Applications must decide:
- What to persist locally vs remotely
- When to sync between client and server
- How to handle offline scenarios
- What to do with conflicting updates
KOS Persistence
Backend Handles All Persistence:
- Device state is naturally persistent (physical reality)
- Backend maintains device state history if needed
- No client-side persistence decisions
- No offline sync complexity
Client is Stateless:
- Browser can be refreshed without loss
- Multiple browser windows show same data
- No local storage or cache management
- Simplified debugging and testing
State Testing Implications
Traditional State Testing
Must test:
- Component state management
- State synchronization
- Cache invalidation
- Optimistic update rollbacks
- State consistency across components
KOS State Testing
Focus on:
- Device communication accuracy
- Model state reflection correctness
- UI response to model changes
- Command execution reliability
Simpler Testing:
Mock device events → Verify model updates → Verify UI changes
Mental Model for State
From “Managing Application State”
To “Visualizing Device State”
This shift changes how you think about every aspect of state:
Traditional Questions:
- Where should this state live?
- How do I sync between components?
- When should I update the server?
- How do I handle conflicting updates?
KOS Questions:
- What device state does this represent?
- How does the device report changes?
- What should happen when the device changes?
- How should the UI reflect device capabilities?
State Design Principles
For Device-Related Data:
- Never store device state locally
- Always get state from device sources
- Let device changes drive updates
- Trust device state over assumptions
For UI-Related Data:
- Use React state for pure UI concerns
- Keep UI state separate from device state
- Don’t persist UI state across sessions
- Reset UI state when device state changes
The Result: Simplified State Architecture
KOS state management eliminates the complexity of distributed state by recognizing that physical devices are the natural owners of their own state. This creates:
- Simpler code: No state synchronization logic needed
- More reliable UIs: Always show accurate device state
- Easier debugging: State comes from one authoritative source
- Better user experience: Real-time accuracy without manual refresh
The UI becomes a window into device state rather than a manager of application state, leading to more maintainable and reliable device interfaces.
