# Data Flow Diagram: ..listen and ..emit System ## Overview This diagram shows how data flows through the functional scripting language with `..listen` and `..emit` IO words. ## Flow Diagram ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ External │ │ Adapter │ │ Functional │ │ System │ │ (WebSocket/ │ │ Harness │ │ │ │ HTTP/etc) │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ │ 1. Send Data │ │ │ (JSON state) │ │ │──────────────────────▶│ │ │ │ │ │ │ 2. processState() │ │ │──────────────────────▶│ │ │ │ │ │ │ 3. Script Execution │ │ │ ┌─────────────┐ │ │ │ │ Script │ │ │ │ │ │ │ │ │ │ ..listen │ │ │ │ │ (get state) │ │ │ │ │ │ │ │ │ │ ..emit │ │ │ │ │ (commands) │ │ │ │ └─────────────┘ │ │ │ │ │ 4. Return {model, │ │ │ commands, results} │ │ │◀──────────────────────│ │ │ │ │ 5. Send Response │ │ │ (model + emitted │ │ │ data) │ │ │◀──────────────────────│ │ │ │ │ ``` ## Detailed Flow ### 1. External System Sends Data ``` WebSocket Client → WebSocket Server HTTP Client → HTTP Server Game Client → Game Server ``` ### 2. Adapter Receives and Processes ```javascript // WebSocket example ws.on('message', async (data) => { const state = JSON.parse(data); const result = await harness.processState(state, { ws }); // Handle result... }); ``` ### 3. Harness Processes State ```javascript // FunctionalHarness.processState() async processState(newState, context = {}) { const { model, commands } = await this.update(newState); const results = await this.processCommands(commands, context); return { model, commands, results }; } ``` ### 4. Script Execution ```javascript // Script runs with environment game_state : ..listen; // Gets current state new_score : game_state.score + 10; ..emit { score: new_score }; // Creates command ``` ### 5. Commands Processed ```javascript // Adapter processes commands for (const result of results) { if (result.type === 'emit') { ws.send(JSON.stringify({ type: 'emitted', data: result.value })); } } ``` ### 6. Response Sent ```javascript // Send updated model and emitted data ws.send(JSON.stringify({ type: 'model', data: model })); ``` ## Key Points 1. **Unidirectional Flow**: Data flows in one direction through the system 2. **Pure Scripts**: Scripts are pure functions (state in → commands out) 3. **Side Effects Isolated**: Only adapters handle side effects 4. **Command Batching**: Multiple `..emit` calls become multiple commands 5. **Context Passing**: Adapters can pass context for command processing ## Example: Game State Update ``` 1. Game Client sends: { action: "collect_coin", player: "player1" } 2. WebSocket Adapter receives 3. Harness processes with game script 4. Script: ..listen gets state, ..emit { score: 110, coins: 5 } 5. Adapter sends: { type: "emitted", data: { score: 110, coins: 5 } } 6. Game Client receives updated state ``` This flow ensures that: - Scripts remain pure and functional - Side effects are isolated to adapters - Data flows predictably through the system - The system is easy to reason about and test