/** * static/js/state.js * Centralised reactive state store. * Components subscribe to state slices and are notified on change. */ const _state = { instructions: [], // InstructionItem[] status: null, // StatusResponse | null config: null, // ConfigResponse | null serverOnline: false, }; const _listeners = {}; // key -> Set export const state = { get(key) { return _state[key]; }, set(key, value) { _state[key] = value; (_listeners[key] || new Set()).forEach(fn => fn(value)); }, subscribe(key, fn) { if (!_listeners[key]) _listeners[key] = new Set(); _listeners[key].add(fn); // Immediately call with current value fn(_state[key]); return () => _listeners[key].delete(fn); // unsubscribe }, };