Changes:
- Replace lastStateChangeSource with activeStateTangibles in tests
- Update tuioStore.test.ts to test array-based tracking
- Add tests for adding/removing multiple state tangibles
- Add test for duplicate prevention
- Update TUIO integration tests to use new API
- Pass fromTangible=true parameter to switchToState in tests
All 447 tests now passing.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements WebSocket-based TUIO protocol support to connect physical tangibles
to presentation mode. When tangibles are placed on/removed from a touch screen,
they trigger configured actions (label filtering or state switching).
Features:
- TUIO 1.1 and 2.0 protocol support with version selection
- WebSocket connection management with real-time status
- Test connection feature in configuration dialog
- Persistent settings (WebSocket URL and protocol version)
- Multi-tangible handling: union for filters, last-wins for states
- Automatic connection in presentation mode
Implementation:
- TuioClientManager: Wrapper for tuio-client library with dual protocol support
- WebsocketTuioReceiver: Custom OSC/WebSocket transport layer
- useTuioIntegration: React hook bridging TUIO events to app stores
- TuioConnectionConfig: Settings UI with real-time tangible detection
- tuioStore: Zustand store with localStorage persistence
Technical details:
- TUIO 1.1 uses symbolId for hardware identification
- TUIO 2.0 uses token.cId for hardware identification
- Filter mode: Activates labels, union of all active tangibles
- State mode: Switches timeline state, last tangible wins
- Cleanup: Removes only labels no longer in use by any tangible
- Unknown hardware IDs are silently ignored
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixes TypeScript compilation errors that prevented production build:
- Fix invalid node shape type in integration test (diamond → circle)
- Export WorkspaceSettings type from main types module
- Exclude test files from production build TypeScript check
All tests (368), linting, and build now pass successfully.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>