wavegrid 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/receiver.js ADDED
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ /**
3
+ * The Receiver — the brain of the Illuminate installation.
4
+ *
5
+ * A pure state engine that:
6
+ * 1. Receives grid state from an InputAdapter (upstream source)
7
+ * 2. Runs an independent low-pass filter (smooth, never jolts)
8
+ * 3. Falls back to 3D sine waves on signal loss
9
+ * 4. Sends filtered output to an OutputAdapter (hardware target)
10
+ *
11
+ * Both input and output are pluggable adapters — swap them to connect
12
+ * to any protocol or hardware without modifying the receiver core.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.Receiver = exports.DEFAULT_RECEIVER_CONFIG = void 0;
16
+ const adapters_1 = require("./adapters");
17
+ const fallback_1 = require("./fallback");
18
+ const filter_1 = require("./filter");
19
+ exports.DEFAULT_RECEIVER_CONFIG = {
20
+ input: new adapters_1.WebSocketInput({ url: 'ws://localhost:3000' }),
21
+ output: new adapters_1.ConsoleOutput(),
22
+ alpha: filter_1.DEFAULT_RECEIVER_ALPHA,
23
+ fallbackDelay: 3000,
24
+ fallback: fallback_1.DEFAULT_FALLBACK_CONFIG,
25
+ tickMs: 1000 / 60
26
+ };
27
+ class Receiver {
28
+ config;
29
+ grid;
30
+ tickTimer = null;
31
+ tick = 0;
32
+ lastDataAt = Date.now();
33
+ _status = 'reconnecting';
34
+ _fallbackActive = false;
35
+ _running = false;
36
+ constructor(config = {}) {
37
+ this.config = { ...exports.DEFAULT_RECEIVER_CONFIG, ...config };
38
+ this.grid = (0, filter_1.createFilteredGrid)();
39
+ }
40
+ get status() { return this._status; }
41
+ get fallbackActive() { return this._fallbackActive; }
42
+ /** Get the current output state (after filtering). */
43
+ getOutputState() {
44
+ return this.grid.map(c => ({
45
+ h: c.h,
46
+ s: c.s,
47
+ b: c.b
48
+ }));
49
+ }
50
+ /** Start the receiver — connects input and begins the tick loop. */
51
+ start() {
52
+ if (this._running)
53
+ return;
54
+ this._running = true;
55
+ this.bindInput();
56
+ this.startTickLoop();
57
+ console.log(' \u25C8 Receiver started');
58
+ }
59
+ /** Stop the receiver — disconnects and stops the tick loop. */
60
+ stop() {
61
+ this._running = false;
62
+ if (this.tickTimer) {
63
+ clearInterval(this.tickTimer);
64
+ this.tickTimer = null;
65
+ }
66
+ this.config.input.disconnect();
67
+ this.config.output.close();
68
+ console.log(' \u25C8 Receiver stopped');
69
+ }
70
+ bindInput() {
71
+ const input = this.config.input;
72
+ input.on('connected', () => {
73
+ this._status = 'connected';
74
+ this.lastDataAt = Date.now();
75
+ console.log(' \u25C8 Input connected');
76
+ });
77
+ input.on('state', (upstream) => {
78
+ this.lastDataAt = Date.now();
79
+ (0, filter_1.applyUpstreamState)(this.grid, upstream);
80
+ if (this._fallbackActive) {
81
+ console.log('\n \u25C8 Signal restored \u2014 blending back from fallback');
82
+ this._fallbackActive = false;
83
+ }
84
+ });
85
+ input.on('disconnected', () => {
86
+ this._status = 'reconnecting';
87
+ console.log('\n \u25C8 Input disconnected');
88
+ });
89
+ input.connect();
90
+ }
91
+ startTickLoop() {
92
+ this.tickTimer = setInterval(() => {
93
+ this.tick++;
94
+ const now = Date.now();
95
+ const timeSinceData = now - this.lastDataAt;
96
+ // Check if we should switch to fallback
97
+ if (timeSinceData > this.config.fallbackDelay && !this._fallbackActive) {
98
+ this._fallbackActive = true;
99
+ this._status = 'fallback';
100
+ console.log('\n \u25C8 Signal lost \u2014 entering sine wave fallback');
101
+ }
102
+ // If fallback is active, compute sine wave targets
103
+ if (this._fallbackActive) {
104
+ (0, fallback_1.computeFallbackFrame)(this.grid, this.tick, this.config.fallback);
105
+ }
106
+ // Always tick the low-pass filter — this ensures smooth output
107
+ // whether receiving data, transitioning to fallback, or in fallback
108
+ (0, filter_1.tickFilter)(this.grid, this.config.alpha);
109
+ // Send filtered output to the output adapter
110
+ this.config.output.send(this.getOutputState());
111
+ }, this.config.tickMs);
112
+ }
113
+ }
114
+ exports.Receiver = Receiver;