File size: 3,336 Bytes
96027bb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// static/js/core/ConfigState.js

class ConfigState extends EventTarget {
    constructor() {
        super();
        this.state = {};
    }

    /**
     * Re-reads all configuration values from the DOM.
     * This acts as the single source of truth parser.
     */
    refreshFromDOM() {
        const newState = {
            cashiers: parseInt(document.getElementById('cfg-cashiers')?.value || 1),
            baristas: parseInt(document.getElementById('cfg-baristas')?.value || 2),
            tables: parseInt(document.getElementById('cfg-tables')?.value || 5),
            resArrivalMin: parseFloat(document.getElementById('cfg-res-arrival-min')?.value || 30.0),
            resArrivalMax: parseFloat(document.getElementById('cfg-res-arrival-max')?.value || 180.0),
            
            arrival: parseFloat(document.getElementById('cfg-arrival')?.value || 45.0),
            duration: parseInt(document.getElementById('cfg-duration')?.value || 0),
            warmupTime: parseFloat(document.getElementById('cfg-warmup')?.value || 0),
            
            takeoutProb: (parseFloat(document.getElementById('cfg-takeout-prob')?.value || 50)) / 100.0,
            resProb: (parseFloat(document.getElementById('cfg-res-prob')?.value || 20)) / 100.0,
            balkProb: (parseFloat(document.getElementById('cfg-balk-prob')?.value || 50)) / 100.0,
            balkThreshold: parseInt(document.getElementById('cfg-balk-threshold')?.value || 8),
            renegeProb: (parseFloat(document.getElementById('cfg-renege-prob')?.value || 30)) / 100.0,
            maxStrikes: parseInt(document.getElementById('cfg-max-strikes')?.value || 3),
            
            decideMin: parseFloat(document.getElementById('cfg-decide-min')?.value || 10.0),
            decideMax: parseFloat(document.getElementById('cfg-decide-max')?.value || 60.0),
            payMin: parseFloat(document.getElementById('cfg-pay-min')?.value || 2.0),
            payMax: parseFloat(document.getElementById('cfg-pay-max')?.value || 10.0),
            prepMin: parseFloat(document.getElementById('cfg-prep-min')?.value || 60.0),
            prepMax: parseFloat(document.getElementById('cfg-prep-max')?.value || 180.0),
            dwellMin: parseFloat(document.getElementById('cfg-dwell-min')?.value || 900.0),
            dwellMax: parseFloat(document.getElementById('cfg-dwell-max')?.value || 3600.0),
            
            replications: parseInt(document.getElementById('cfg-replications')?.value || 10),
            shiftHours: parseFloat(document.getElementById('cfg-shift-hours')?.value || 2)
        };
        
        // Only emit if state actually changed
        if (JSON.stringify(this.state) !== JSON.stringify(newState)) {
            this.state = newState;
            this.dispatchEvent(new CustomEvent('updated', { detail: this.state }));
        }
    }

    /**
     * Get the current state as a query string for WebSockets
     */
    toQueryString() {
        const params = new URLSearchParams();
        for (const [key, value] of Object.entries(this.state)) {
            params.append(key, value);
        }
        return params.toString();
    }

    /**
     * Get the raw config JSON
     */
    getConfig() {
        return { ...this.state };
    }
}

// Singleton instance
export const configState = new ConfigState();