jmri-client 4.2.0-beta.2 → 5.0.0

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.
Files changed (58) hide show
  1. package/README.md +3 -1
  2. package/dist/cjs/index.js +2382 -31
  3. package/dist/esm/index.js +2333 -17
  4. package/docs/BROWSER.md +4 -4
  5. package/docs/MIGRATION.md +30 -1
  6. package/package.json +17 -18
  7. package/dist/cjs/client.js +0 -366
  8. package/dist/cjs/core/connection-state-manager.js +0 -84
  9. package/dist/cjs/core/heartbeat-manager.js +0 -79
  10. package/dist/cjs/core/index.js +0 -25
  11. package/dist/cjs/core/message-queue.js +0 -59
  12. package/dist/cjs/core/reconnection-manager.js +0 -97
  13. package/dist/cjs/core/websocket-adapter.js +0 -135
  14. package/dist/cjs/core/websocket-client.js +0 -388
  15. package/dist/cjs/managers/index.js +0 -25
  16. package/dist/cjs/managers/light-manager.js +0 -111
  17. package/dist/cjs/managers/power-manager.js +0 -90
  18. package/dist/cjs/managers/roster-manager.js +0 -118
  19. package/dist/cjs/managers/system-connections-manager.js +0 -28
  20. package/dist/cjs/managers/throttle-manager.js +0 -233
  21. package/dist/cjs/managers/turnout-manager.js +0 -111
  22. package/dist/cjs/mocks/index.js +0 -12
  23. package/dist/cjs/mocks/mock-data.js +0 -237
  24. package/dist/cjs/mocks/mock-response-manager.js +0 -290
  25. package/dist/cjs/types/client-options.js +0 -66
  26. package/dist/cjs/types/events.js +0 -16
  27. package/dist/cjs/types/index.js +0 -23
  28. package/dist/cjs/types/jmri-messages.js +0 -95
  29. package/dist/cjs/types/throttle.js +0 -19
  30. package/dist/cjs/utils/exponential-backoff.js +0 -40
  31. package/dist/cjs/utils/index.js +0 -21
  32. package/dist/cjs/utils/message-id.js +0 -40
  33. package/dist/esm/client.js +0 -362
  34. package/dist/esm/core/connection-state-manager.js +0 -80
  35. package/dist/esm/core/heartbeat-manager.js +0 -75
  36. package/dist/esm/core/index.js +0 -9
  37. package/dist/esm/core/message-queue.js +0 -55
  38. package/dist/esm/core/reconnection-manager.js +0 -93
  39. package/dist/esm/core/websocket-adapter.js +0 -98
  40. package/dist/esm/core/websocket-client.js +0 -384
  41. package/dist/esm/managers/index.js +0 -9
  42. package/dist/esm/managers/light-manager.js +0 -107
  43. package/dist/esm/managers/power-manager.js +0 -86
  44. package/dist/esm/managers/roster-manager.js +0 -114
  45. package/dist/esm/managers/system-connections-manager.js +0 -24
  46. package/dist/esm/managers/throttle-manager.js +0 -229
  47. package/dist/esm/managers/turnout-manager.js +0 -107
  48. package/dist/esm/mocks/index.js +0 -6
  49. package/dist/esm/mocks/mock-data.js +0 -234
  50. package/dist/esm/mocks/mock-response-manager.js +0 -286
  51. package/dist/esm/types/client-options.js +0 -62
  52. package/dist/esm/types/events.js +0 -13
  53. package/dist/esm/types/index.js +0 -7
  54. package/dist/esm/types/jmri-messages.js +0 -89
  55. package/dist/esm/types/throttle.js +0 -15
  56. package/dist/esm/utils/exponential-backoff.js +0 -36
  57. package/dist/esm/utils/index.js +0 -5
  58. package/dist/esm/utils/message-id.js +0 -36
@@ -1,111 +0,0 @@
1
- "use strict";
2
- /**
3
- * Turnout (switch) manager
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.TurnoutManager = void 0;
7
- const eventemitter3_1 = require("eventemitter3");
8
- const jmri_messages_js_1 = require("../types/jmri-messages.js");
9
- /**
10
- * Manages JMRI turnout (track switch) state
11
- */
12
- class TurnoutManager extends eventemitter3_1.EventEmitter {
13
- constructor(client) {
14
- super();
15
- this.turnouts = new Map();
16
- this.client = client;
17
- this.client.on('update', (message) => {
18
- if (message.type === 'turnout') {
19
- this.handleTurnoutUpdate(message);
20
- }
21
- });
22
- }
23
- /**
24
- * Get the current state of a turnout.
25
- * Also registers a server-side listener so subsequent changes are pushed.
26
- */
27
- async getTurnout(name) {
28
- const message = {
29
- type: 'turnout',
30
- data: { name }
31
- };
32
- const response = await this.client.request(message);
33
- const state = response.data?.state ?? jmri_messages_js_1.TurnoutState.UNKNOWN;
34
- this.turnouts.set(name, state);
35
- return state;
36
- }
37
- /**
38
- * Set a turnout to the given state
39
- */
40
- async setTurnout(name, state) {
41
- const message = {
42
- type: 'turnout',
43
- method: 'post',
44
- data: { name, state }
45
- };
46
- await this.client.request(message);
47
- const oldState = this.turnouts.get(name);
48
- this.turnouts.set(name, state);
49
- if (oldState !== state) {
50
- this.emit('turnout:changed', name, state);
51
- }
52
- }
53
- /**
54
- * Throw a turnout (diverging route)
55
- */
56
- async throwTurnout(name) {
57
- return this.setTurnout(name, jmri_messages_js_1.TurnoutState.THROWN);
58
- }
59
- /**
60
- * Close a turnout (straight through / normal)
61
- */
62
- async closeTurnout(name) {
63
- return this.setTurnout(name, jmri_messages_js_1.TurnoutState.CLOSED);
64
- }
65
- /**
66
- * List all turnouts known to JMRI
67
- */
68
- async listTurnouts() {
69
- const message = {
70
- type: 'turnout',
71
- method: 'list'
72
- };
73
- const response = await this.client.request(message);
74
- const entries = Array.isArray(response?.data)
75
- ? response.data.map((r) => r.data ?? r)
76
- : [];
77
- for (const entry of entries) {
78
- if (entry.name && entry.state !== undefined) {
79
- this.turnouts.set(entry.name, entry.state);
80
- }
81
- }
82
- return entries;
83
- }
84
- /**
85
- * Get cached turnout state without a network request
86
- */
87
- getTurnoutState(name) {
88
- return this.turnouts.get(name);
89
- }
90
- /**
91
- * Get all cached turnout states
92
- */
93
- getCachedTurnouts() {
94
- return new Map(this.turnouts);
95
- }
96
- /**
97
- * Handle unsolicited turnout state updates from JMRI
98
- */
99
- handleTurnoutUpdate(message) {
100
- const name = message.data?.name;
101
- const state = message.data?.state;
102
- if (!name || state === undefined)
103
- return;
104
- const oldState = this.turnouts.get(name);
105
- this.turnouts.set(name, state);
106
- if (oldState !== state) {
107
- this.emit('turnout:changed', name, state);
108
- }
109
- }
110
- }
111
- exports.TurnoutManager = TurnoutManager;
@@ -1,12 +0,0 @@
1
- "use strict";
2
- /**
3
- * Mock system exports
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.mockData = exports.mockResponseManager = exports.MockResponseManager = void 0;
7
- var mock_response_manager_js_1 = require("./mock-response-manager.js");
8
- Object.defineProperty(exports, "MockResponseManager", { enumerable: true, get: function () { return mock_response_manager_js_1.MockResponseManager; } });
9
- Object.defineProperty(exports, "mockResponseManager", { enumerable: true, get: function () { return mock_response_manager_js_1.mockResponseManager; } });
10
- // Re-export mock data for direct access if needed
11
- var mock_data_js_1 = require("./mock-data.js");
12
- Object.defineProperty(exports, "mockData", { enumerable: true, get: function () { return mock_data_js_1.mockData; } });
@@ -1,237 +0,0 @@
1
- "use strict";
2
- /**
3
- * Mock data for JMRI responses
4
- * Used for testing and demo mode
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.mockData = void 0;
8
- exports.mockData = {
9
- "hello": {
10
- "type": "hello",
11
- "data": {
12
- "JMRI": "5.9.2",
13
- "json": "5.0",
14
- "version": "v5",
15
- "heartbeat": 13500,
16
- "railroad": "Demo Railroad",
17
- "node": "jmri-server",
18
- "activeProfile": "Demo Profile"
19
- }
20
- },
21
- "power": {
22
- "get": {
23
- "on": {
24
- "type": "power",
25
- "data": {
26
- "state": 2
27
- }
28
- },
29
- "off": {
30
- "type": "power",
31
- "data": {
32
- "state": 4
33
- }
34
- }
35
- },
36
- "post": {
37
- "success": {
38
- "type": "power",
39
- "data": {
40
- "state": 2
41
- }
42
- }
43
- }
44
- },
45
- "roster": {
46
- "list": [
47
- {
48
- "type": "rosterEntry",
49
- "data": {
50
- "name": "CSX754",
51
- "address": "754",
52
- "isLongAddress": true,
53
- "road": "CSX",
54
- "number": "754",
55
- "mfg": "Athearn",
56
- "decoderModel": "DH163D",
57
- "decoderFamily": "Digitrax DH163",
58
- "model": "GP38-2",
59
- "comment": "Blue and yellow scheme",
60
- "maxSpeedPct": 100,
61
- "image": null,
62
- "icon": "/roster/CSX754/icon",
63
- "shuntingFunction": "",
64
- "owner": "",
65
- "dateModified": "2026-02-10T00:00:00.000+00:00",
66
- "functionKeys": [
67
- { "name": "F0", "label": "Headlight", "lockable": true, "icon": null, "selectedIcon": null },
68
- { "name": "F1", "label": "Bell", "lockable": true, "icon": null, "selectedIcon": null },
69
- { "name": "F2", "label": "Horn", "lockable": false, "icon": null, "selectedIcon": null },
70
- { "name": "F3", "label": null, "lockable": false, "icon": null, "selectedIcon": null },
71
- { "name": "F4", "label": "Dynamic Brake", "lockable": true, "icon": null, "selectedIcon": null },
72
- { "name": "F5", "label": null, "lockable": false, "icon": null, "selectedIcon": null }
73
- ],
74
- "attributes": [],
75
- "rosterGroups": []
76
- },
77
- "id": 1
78
- },
79
- {
80
- "type": "rosterEntry",
81
- "data": {
82
- "name": "UP3985",
83
- "address": "3985",
84
- "isLongAddress": true,
85
- "road": "Union Pacific",
86
- "number": "3985",
87
- "mfg": "Rivarossi",
88
- "decoderModel": "Sound decoder",
89
- "decoderFamily": "ESU LokSound",
90
- "model": "Challenger 4-6-6-4",
91
- "comment": "Steam locomotive",
92
- "maxSpeedPct": 100,
93
- "image": null,
94
- "icon": "/roster/UP3985/icon",
95
- "shuntingFunction": "",
96
- "owner": "",
97
- "dateModified": "2026-02-10T00:00:00.000+00:00",
98
- "functionKeys": [
99
- { "name": "F0", "label": "Headlight", "lockable": true, "icon": null, "selectedIcon": null },
100
- { "name": "F1", "label": "Bell", "lockable": true, "icon": null, "selectedIcon": null },
101
- { "name": "F2", "label": "Whistle", "lockable": false, "icon": null, "selectedIcon": null },
102
- { "name": "F3", "label": "Steam", "lockable": true, "icon": null, "selectedIcon": null },
103
- { "name": "F4", "label": null, "lockable": false, "icon": null, "selectedIcon": null }
104
- ],
105
- "attributes": [],
106
- "rosterGroups": []
107
- },
108
- "id": 2
109
- },
110
- {
111
- "type": "rosterEntry",
112
- "data": {
113
- "name": "BNSF5240",
114
- "address": "5240",
115
- "isLongAddress": true,
116
- "road": "BNSF",
117
- "number": "5240",
118
- "mfg": "Kato",
119
- "decoderModel": "DCC Sound",
120
- "decoderFamily": "Kato",
121
- "model": "SD40-2",
122
- "comment": "Heritage II paint",
123
- "maxSpeedPct": 100,
124
- "image": null,
125
- "icon": "/roster/BNSF5240/icon",
126
- "shuntingFunction": "",
127
- "owner": "",
128
- "dateModified": "2026-02-10T00:00:00.000+00:00",
129
- "functionKeys": [
130
- { "name": "F0", "label": "Headlight", "lockable": true, "icon": null, "selectedIcon": null },
131
- { "name": "F1", "label": "Bell", "lockable": true, "icon": null, "selectedIcon": null },
132
- { "name": "F2", "label": "Horn", "lockable": false, "icon": null, "selectedIcon": null },
133
- { "name": "F3", "label": "Dynamic Brake", "lockable": true, "icon": null, "selectedIcon": null },
134
- { "name": "F4", "label": null, "lockable": false, "icon": null, "selectedIcon": null },
135
- { "name": "F5", "label": "Mars Light", "lockable": true, "icon": null, "selectedIcon": null }
136
- ],
137
- "attributes": [],
138
- "rosterGroups": []
139
- },
140
- "id": 3
141
- }
142
- ]
143
- },
144
- "throttle": {
145
- "acquire": {
146
- "success": {
147
- "type": "throttle",
148
- "data": {
149
- "throttle": "{THROTTLE_ID}",
150
- "address": "{ADDRESS}",
151
- "speed": 0,
152
- "forward": true,
153
- "F0": false,
154
- "F1": false,
155
- "F2": false,
156
- "F3": false,
157
- "F4": false
158
- }
159
- }
160
- },
161
- "release": {
162
- "success": {
163
- "type": "throttle",
164
- "data": {}
165
- }
166
- },
167
- "control": {
168
- "speed": {
169
- "type": "throttle",
170
- "data": {
171
- "throttle": "{THROTTLE_ID}",
172
- "speed": "{SPEED}"
173
- }
174
- },
175
- "direction": {
176
- "type": "throttle",
177
- "data": {
178
- "throttle": "{THROTTLE_ID}",
179
- "forward": "{FORWARD}"
180
- }
181
- },
182
- "function": {
183
- "type": "throttle",
184
- "data": {
185
- "throttle": "{THROTTLE_ID}",
186
- "{FUNCTION}": "{VALUE}"
187
- }
188
- }
189
- }
190
- },
191
- "light": {
192
- "list": [
193
- { "type": "light", "data": { "name": "IL1", "userName": "Yard Light", "comment": null, "properties": [], "state": 4 } },
194
- { "type": "light", "data": { "name": "IL2", "userName": "Platform Light", "comment": null, "properties": [], "state": 4 } },
195
- { "type": "light", "data": { "name": "IL3", "userName": "Signal Lamp", "comment": null, "properties": [], "state": 2 } }
196
- ]
197
- },
198
- "turnout": {
199
- "list": [
200
- { "type": "turnout", "data": { "name": "LT1", "userName": "Main Diverge", "state": 2 } },
201
- { "type": "turnout", "data": { "name": "LT2", "userName": "Yard Lead", "state": 2 } },
202
- { "type": "turnout", "data": { "name": "LT3", "userName": "Siding Entry", "state": 4 } }
203
- ]
204
- },
205
- "ping": {
206
- "type": "ping"
207
- },
208
- "pong": {
209
- "type": "pong"
210
- },
211
- "goodbye": {
212
- "type": "goodbye"
213
- },
214
- "error": {
215
- "throttleNotFound": {
216
- "type": "error",
217
- "data": {
218
- "code": 404,
219
- "message": "Throttle not found"
220
- }
221
- },
222
- "invalidSpeed": {
223
- "type": "error",
224
- "data": {
225
- "code": 400,
226
- "message": "Invalid speed value"
227
- }
228
- },
229
- "connectionError": {
230
- "type": "error",
231
- "data": {
232
- "code": 500,
233
- "message": "Connection error"
234
- }
235
- }
236
- }
237
- };
@@ -1,290 +0,0 @@
1
- "use strict";
2
- /**
3
- * Mock Response Manager
4
- * Generates mock JMRI responses for testing and demo purposes
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.mockResponseManager = exports.MockResponseManager = void 0;
8
- const jmri_messages_js_1 = require("../types/jmri-messages.js");
9
- const mock_data_js_1 = require("./mock-data.js");
10
- /**
11
- * Manages mock responses for JMRI protocol
12
- */
13
- class MockResponseManager {
14
- constructor(options = {}) {
15
- this.throttles = new Map();
16
- this.lights = new Map([
17
- ['IL1', jmri_messages_js_1.LightState.OFF],
18
- ['IL2', jmri_messages_js_1.LightState.OFF],
19
- ['IL3', jmri_messages_js_1.LightState.ON]
20
- ]);
21
- this.turnouts = new Map([
22
- ['LT1', jmri_messages_js_1.TurnoutState.CLOSED],
23
- ['LT2', jmri_messages_js_1.TurnoutState.CLOSED],
24
- ['LT3', jmri_messages_js_1.TurnoutState.THROWN]
25
- ]);
26
- this.responseDelay = options.responseDelay ?? 50;
27
- this.powerState = options.initialPowerState ?? jmri_messages_js_1.PowerState.OFF;
28
- }
29
- /**
30
- * Get a mock response for a given message
31
- */
32
- async getMockResponse(message) {
33
- // Simulate network delay
34
- if (this.responseDelay > 0) {
35
- await this.delay(this.responseDelay);
36
- }
37
- // Route to appropriate handler based on message type
38
- switch (message.type) {
39
- case 'hello':
40
- return this.getHelloResponse();
41
- case 'power':
42
- return this.getPowerResponse(message);
43
- case 'roster':
44
- return this.getRosterResponse(message);
45
- case 'throttle':
46
- return this.getThrottleResponse(message);
47
- case 'light':
48
- return this.getLightResponse(message);
49
- case 'turnout':
50
- return this.getTurnoutResponse(message);
51
- case 'ping':
52
- return this.getPingResponse();
53
- case 'goodbye':
54
- return this.getGoodbyeResponse();
55
- default:
56
- return null;
57
- }
58
- }
59
- /**
60
- * Get hello response (connection establishment)
61
- */
62
- getHelloResponse() {
63
- return JSON.parse(JSON.stringify(mock_data_js_1.mockData.hello));
64
- }
65
- /**
66
- * Get power response
67
- */
68
- getPowerResponse(message) {
69
- // Handle power state change
70
- if (message.data?.state !== undefined) {
71
- this.powerState = message.data.state;
72
- return {
73
- type: 'power',
74
- data: { state: this.powerState }
75
- };
76
- }
77
- // Return current power state
78
- return {
79
- type: 'power',
80
- data: { state: this.powerState }
81
- };
82
- }
83
- /**
84
- * Get roster response
85
- */
86
- getRosterResponse(message) {
87
- if (message.type === 'roster' && message.method === 'list') {
88
- return {
89
- type: 'roster',
90
- data: JSON.parse(JSON.stringify(mock_data_js_1.mockData.roster.list))
91
- };
92
- }
93
- return {
94
- type: 'roster',
95
- data: []
96
- };
97
- }
98
- /**
99
- * Get throttle response
100
- */
101
- getThrottleResponse(message) {
102
- const data = message.data || {};
103
- // Acquire throttle
104
- if (data.address !== undefined && !data.throttle) {
105
- const throttleId = data.name || `MOCK-${data.address}`;
106
- const throttleState = {
107
- throttle: throttleId,
108
- address: data.address,
109
- speed: 0,
110
- forward: true,
111
- F0: false,
112
- F1: false,
113
- F2: false,
114
- F3: false,
115
- F4: false
116
- };
117
- this.throttles.set(throttleId, throttleState);
118
- return {
119
- type: 'throttle',
120
- data: { ...throttleState }
121
- };
122
- }
123
- // Release throttle
124
- if (data.release !== undefined && data.throttle) {
125
- this.throttles.delete(data.throttle);
126
- return {
127
- type: 'throttle',
128
- data: {}
129
- };
130
- }
131
- // Throttle control (speed, direction, functions)
132
- if (data.throttle) {
133
- const throttleState = this.throttles.get(data.throttle);
134
- if (!throttleState) {
135
- // Throttle not found - this shouldn't normally happen in mock mode
136
- // but we'll create it on the fly
137
- const newState = {
138
- throttle: data.throttle,
139
- address: 0,
140
- speed: 0,
141
- forward: true
142
- };
143
- this.throttles.set(data.throttle, newState);
144
- return {
145
- type: 'throttle',
146
- data: { ...newState }
147
- };
148
- }
149
- // Update throttle state
150
- if (data.speed !== undefined) {
151
- throttleState.speed = data.speed;
152
- }
153
- if (data.forward !== undefined) {
154
- throttleState.forward = data.forward;
155
- }
156
- // Update function keys
157
- for (let i = 0; i <= 28; i++) {
158
- const key = `F${i}`;
159
- if (data[key] !== undefined) {
160
- throttleState[key] = data[key];
161
- }
162
- }
163
- // Return updated state (no response for throttle control commands)
164
- return {
165
- type: 'throttle',
166
- data: {}
167
- };
168
- }
169
- return {
170
- type: 'throttle',
171
- data: {}
172
- };
173
- }
174
- /**
175
- * Get light response
176
- */
177
- getLightResponse(message) {
178
- // List all lights
179
- if (message.method === 'list') {
180
- return {
181
- type: 'light',
182
- data: JSON.parse(JSON.stringify(mock_data_js_1.mockData.light.list))
183
- };
184
- }
185
- const name = message.data?.name;
186
- if (!name) {
187
- return { type: 'light', data: { name: '', state: jmri_messages_js_1.LightState.UNKNOWN } };
188
- }
189
- // Set light state
190
- if (message.method === 'post' && message.data?.state !== undefined) {
191
- this.lights.set(name, message.data.state);
192
- }
193
- // Get or confirm current state
194
- const state = this.lights.get(name) ?? jmri_messages_js_1.LightState.UNKNOWN;
195
- return { type: 'light', data: { name, state } };
196
- }
197
- /**
198
- * Get turnout response
199
- */
200
- getTurnoutResponse(message) {
201
- // List all turnouts
202
- if (message.method === 'list') {
203
- return {
204
- type: 'turnout',
205
- data: JSON.parse(JSON.stringify(mock_data_js_1.mockData.turnout.list))
206
- };
207
- }
208
- const name = message.data?.name;
209
- if (!name) {
210
- return { type: 'turnout', data: { name: '', state: jmri_messages_js_1.TurnoutState.UNKNOWN } };
211
- }
212
- // Set turnout state
213
- if (message.method === 'post' && message.data?.state !== undefined) {
214
- this.turnouts.set(name, message.data.state);
215
- }
216
- // Get or confirm current state
217
- const state = this.turnouts.get(name) ?? jmri_messages_js_1.TurnoutState.UNKNOWN;
218
- return { type: 'turnout', data: { name, state } };
219
- }
220
- /**
221
- * Get ping response (pong)
222
- */
223
- getPingResponse() {
224
- return JSON.parse(JSON.stringify(mock_data_js_1.mockData.pong));
225
- }
226
- /**
227
- * Get goodbye response
228
- */
229
- getGoodbyeResponse() {
230
- return JSON.parse(JSON.stringify(mock_data_js_1.mockData.goodbye));
231
- }
232
- /**
233
- * Get current power state
234
- */
235
- getPowerState() {
236
- return this.powerState;
237
- }
238
- /**
239
- * Set power state (for testing)
240
- */
241
- setPowerState(state) {
242
- this.powerState = state;
243
- }
244
- /**
245
- * Get all throttles (for testing)
246
- */
247
- getThrottles() {
248
- return this.throttles;
249
- }
250
- /**
251
- * Get all light states (for testing)
252
- */
253
- getLights() {
254
- return this.lights;
255
- }
256
- /**
257
- * Get all turnout states (for testing)
258
- */
259
- getTurnouts() {
260
- return this.turnouts;
261
- }
262
- /**
263
- * Reset all state (for testing)
264
- */
265
- reset() {
266
- this.powerState = jmri_messages_js_1.PowerState.OFF;
267
- this.throttles.clear();
268
- this.lights = new Map([
269
- ['IL1', jmri_messages_js_1.LightState.OFF],
270
- ['IL2', jmri_messages_js_1.LightState.OFF],
271
- ['IL3', jmri_messages_js_1.LightState.ON]
272
- ]);
273
- this.turnouts = new Map([
274
- ['LT1', jmri_messages_js_1.TurnoutState.CLOSED],
275
- ['LT2', jmri_messages_js_1.TurnoutState.CLOSED],
276
- ['LT3', jmri_messages_js_1.TurnoutState.THROWN]
277
- ]);
278
- }
279
- /**
280
- * Delay helper
281
- */
282
- delay(ms) {
283
- return new Promise(resolve => setTimeout(resolve, ms));
284
- }
285
- }
286
- exports.MockResponseManager = MockResponseManager;
287
- /**
288
- * Singleton instance for shared use across tests
289
- */
290
- exports.mockResponseManager = new MockResponseManager({ responseDelay: 0 });