jmri-client 4.2.0-beta.2 → 5.1.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.
- package/README.md +3 -1
- package/dist/browser/jmri-client.js +88 -28
- package/dist/cjs/index.js +2442 -31
- package/dist/esm/index.js +2393 -17
- package/dist/types/client.d.ts +9 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/managers/roster-manager.d.ts +9 -1
- package/dist/types/mocks/mock-data.d.ts +30 -6
- package/dist/types/mocks/mock-response-manager.d.ts +7 -2
- package/dist/types/types/jmri-messages.d.ts +22 -0
- package/docs/API.md +8 -0
- package/docs/BROWSER.md +4 -4
- package/docs/MIGRATION.md +30 -1
- package/docs/MOCK_MODE.md +15 -9
- package/package.json +17 -18
- package/dist/cjs/client.js +0 -366
- package/dist/cjs/core/connection-state-manager.js +0 -84
- package/dist/cjs/core/heartbeat-manager.js +0 -79
- package/dist/cjs/core/index.js +0 -25
- package/dist/cjs/core/message-queue.js +0 -59
- package/dist/cjs/core/reconnection-manager.js +0 -97
- package/dist/cjs/core/websocket-adapter.js +0 -135
- package/dist/cjs/core/websocket-client.js +0 -388
- package/dist/cjs/managers/index.js +0 -25
- package/dist/cjs/managers/light-manager.js +0 -111
- package/dist/cjs/managers/power-manager.js +0 -90
- package/dist/cjs/managers/roster-manager.js +0 -118
- package/dist/cjs/managers/system-connections-manager.js +0 -28
- package/dist/cjs/managers/throttle-manager.js +0 -233
- package/dist/cjs/managers/turnout-manager.js +0 -111
- package/dist/cjs/mocks/index.js +0 -12
- package/dist/cjs/mocks/mock-data.js +0 -237
- package/dist/cjs/mocks/mock-response-manager.js +0 -290
- package/dist/cjs/types/client-options.js +0 -66
- package/dist/cjs/types/events.js +0 -16
- package/dist/cjs/types/index.js +0 -23
- package/dist/cjs/types/jmri-messages.js +0 -95
- package/dist/cjs/types/throttle.js +0 -19
- package/dist/cjs/utils/exponential-backoff.js +0 -40
- package/dist/cjs/utils/index.js +0 -21
- package/dist/cjs/utils/message-id.js +0 -40
- package/dist/esm/client.js +0 -362
- package/dist/esm/core/connection-state-manager.js +0 -80
- package/dist/esm/core/heartbeat-manager.js +0 -75
- package/dist/esm/core/index.js +0 -9
- package/dist/esm/core/message-queue.js +0 -55
- package/dist/esm/core/reconnection-manager.js +0 -93
- package/dist/esm/core/websocket-adapter.js +0 -98
- package/dist/esm/core/websocket-client.js +0 -384
- package/dist/esm/managers/index.js +0 -9
- package/dist/esm/managers/light-manager.js +0 -107
- package/dist/esm/managers/power-manager.js +0 -86
- package/dist/esm/managers/roster-manager.js +0 -114
- package/dist/esm/managers/system-connections-manager.js +0 -24
- package/dist/esm/managers/throttle-manager.js +0 -229
- package/dist/esm/managers/turnout-manager.js +0 -107
- package/dist/esm/mocks/index.js +0 -6
- package/dist/esm/mocks/mock-data.js +0 -234
- package/dist/esm/mocks/mock-response-manager.js +0 -286
- package/dist/esm/types/client-options.js +0 -62
- package/dist/esm/types/events.js +0 -13
- package/dist/esm/types/index.js +0 -7
- package/dist/esm/types/jmri-messages.js +0 -89
- package/dist/esm/types/throttle.js +0 -15
- package/dist/esm/utils/exponential-backoff.js +0 -36
- package/dist/esm/utils/index.js +0 -5
- package/dist/esm/utils/message-id.js +0 -36
|
@@ -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 });
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Client configuration options
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.DEFAULT_CLIENT_OPTIONS = void 0;
|
|
7
|
-
exports.mergeOptions = mergeOptions;
|
|
8
|
-
/**
|
|
9
|
-
* Default client options
|
|
10
|
-
*/
|
|
11
|
-
exports.DEFAULT_CLIENT_OPTIONS = {
|
|
12
|
-
host: 'localhost',
|
|
13
|
-
port: 12080,
|
|
14
|
-
protocol: 'ws',
|
|
15
|
-
autoConnect: true,
|
|
16
|
-
reconnection: {
|
|
17
|
-
enabled: true,
|
|
18
|
-
maxAttempts: 0, // infinite
|
|
19
|
-
initialDelay: 1000,
|
|
20
|
-
maxDelay: 30000,
|
|
21
|
-
multiplier: 1.5,
|
|
22
|
-
jitter: true
|
|
23
|
-
},
|
|
24
|
-
heartbeat: {
|
|
25
|
-
enabled: true,
|
|
26
|
-
interval: 30000,
|
|
27
|
-
timeout: 5000
|
|
28
|
-
},
|
|
29
|
-
messageQueueSize: 100,
|
|
30
|
-
requestTimeout: 10000,
|
|
31
|
-
mock: {
|
|
32
|
-
enabled: false,
|
|
33
|
-
responseDelay: 50
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* Merge user options with defaults
|
|
38
|
-
*/
|
|
39
|
-
function mergeOptions(userOptions) {
|
|
40
|
-
const options = { ...exports.DEFAULT_CLIENT_OPTIONS };
|
|
41
|
-
if (!userOptions) {
|
|
42
|
-
return options;
|
|
43
|
-
}
|
|
44
|
-
if (userOptions.host !== undefined)
|
|
45
|
-
options.host = userOptions.host;
|
|
46
|
-
if (userOptions.port !== undefined)
|
|
47
|
-
options.port = userOptions.port;
|
|
48
|
-
if (userOptions.protocol !== undefined)
|
|
49
|
-
options.protocol = userOptions.protocol;
|
|
50
|
-
if (userOptions.autoConnect !== undefined)
|
|
51
|
-
options.autoConnect = userOptions.autoConnect;
|
|
52
|
-
if (userOptions.messageQueueSize !== undefined)
|
|
53
|
-
options.messageQueueSize = userOptions.messageQueueSize;
|
|
54
|
-
if (userOptions.requestTimeout !== undefined)
|
|
55
|
-
options.requestTimeout = userOptions.requestTimeout;
|
|
56
|
-
if (userOptions.reconnection) {
|
|
57
|
-
options.reconnection = { ...exports.DEFAULT_CLIENT_OPTIONS.reconnection, ...userOptions.reconnection };
|
|
58
|
-
}
|
|
59
|
-
if (userOptions.heartbeat) {
|
|
60
|
-
options.heartbeat = { ...exports.DEFAULT_CLIENT_OPTIONS.heartbeat, ...userOptions.heartbeat };
|
|
61
|
-
}
|
|
62
|
-
if (userOptions.mock) {
|
|
63
|
-
options.mock = { ...exports.DEFAULT_CLIENT_OPTIONS.mock, ...userOptions.mock };
|
|
64
|
-
}
|
|
65
|
-
return options;
|
|
66
|
-
}
|
package/dist/cjs/types/events.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Event types for JmriClient EventEmitter
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ConnectionState = void 0;
|
|
7
|
-
/**
|
|
8
|
-
* Connection states
|
|
9
|
-
*/
|
|
10
|
-
var ConnectionState;
|
|
11
|
-
(function (ConnectionState) {
|
|
12
|
-
ConnectionState["DISCONNECTED"] = "disconnected";
|
|
13
|
-
ConnectionState["CONNECTING"] = "connecting";
|
|
14
|
-
ConnectionState["CONNECTED"] = "connected";
|
|
15
|
-
ConnectionState["RECONNECTING"] = "reconnecting";
|
|
16
|
-
})(ConnectionState || (exports.ConnectionState = ConnectionState = {}));
|
package/dist/cjs/types/index.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Type definitions for jmri-client
|
|
4
|
-
*/
|
|
5
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
-
}
|
|
11
|
-
Object.defineProperty(o, k2, desc);
|
|
12
|
-
}) : (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
o[k2] = m[k];
|
|
15
|
-
}));
|
|
16
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
-
};
|
|
19
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
__exportStar(require("./jmri-messages.js"), exports);
|
|
21
|
-
__exportStar(require("./events.js"), exports);
|
|
22
|
-
__exportStar(require("./throttle.js"), exports);
|
|
23
|
-
__exportStar(require("./client-options.js"), exports);
|