jmri-client 3.4.0 → 3.5.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.
@@ -7,8 +7,10 @@ export declare const mockData: {
7
7
  readonly type: "hello";
8
8
  readonly data: {
9
9
  readonly JMRI: "5.9.2";
10
- readonly JSON: "5.0";
11
- readonly Railroad: "Demo Railroad";
10
+ readonly json: "5.0";
11
+ readonly version: "v5";
12
+ readonly heartbeat: 13500;
13
+ readonly railroad: "Demo Railroad";
12
14
  readonly node: "jmri-server";
13
15
  readonly activeProfile: "Demo Profile";
14
16
  };
@@ -38,149 +40,181 @@ export declare const mockData: {
38
40
  };
39
41
  };
40
42
  readonly roster: {
41
- readonly list: {
42
- readonly type: "roster";
43
+ readonly list: readonly [{
44
+ readonly type: "rosterEntry";
43
45
  readonly data: {
44
- readonly CSX754: {
45
- readonly name: "CSX754";
46
- readonly address: "754";
47
- readonly isLongAddress: true;
48
- readonly road: "CSX";
49
- readonly number: "754";
50
- readonly mfg: "Athearn";
51
- readonly model: "GP38-2";
52
- readonly comment: "Blue and yellow scheme";
53
- readonly maxSpeed: 126;
54
- readonly functionKeys: readonly [{
55
- readonly name: "F0";
56
- readonly label: "Headlight";
57
- readonly lockable: true;
58
- readonly icon: null;
59
- readonly selectedIcon: null;
60
- }, {
61
- readonly name: "F1";
62
- readonly label: "Bell";
63
- readonly lockable: true;
64
- readonly icon: null;
65
- readonly selectedIcon: null;
66
- }, {
67
- readonly name: "F2";
68
- readonly label: "Horn";
69
- readonly lockable: false;
70
- readonly icon: null;
71
- readonly selectedIcon: null;
72
- }, {
73
- readonly name: "F3";
74
- readonly label: null;
75
- readonly lockable: false;
76
- readonly icon: null;
77
- readonly selectedIcon: null;
78
- }, {
79
- readonly name: "F4";
80
- readonly label: "Dynamic Brake";
81
- readonly lockable: true;
82
- readonly icon: null;
83
- readonly selectedIcon: null;
84
- }, {
85
- readonly name: "F5";
86
- readonly label: null;
87
- readonly lockable: false;
88
- readonly icon: null;
89
- readonly selectedIcon: null;
90
- }];
91
- };
92
- readonly UP3985: {
93
- readonly name: "UP3985";
94
- readonly address: "3985";
95
- readonly isLongAddress: true;
96
- readonly road: "Union Pacific";
97
- readonly number: "3985";
98
- readonly mfg: "Rivarossi";
99
- readonly model: "Challenger 4-6-6-4";
100
- readonly comment: "Steam locomotive";
101
- readonly maxSpeed: 126;
102
- readonly functionKeys: readonly [{
103
- readonly name: "F0";
104
- readonly label: "Headlight";
105
- readonly lockable: true;
106
- readonly icon: null;
107
- readonly selectedIcon: null;
108
- }, {
109
- readonly name: "F1";
110
- readonly label: "Bell";
111
- readonly lockable: true;
112
- readonly icon: null;
113
- readonly selectedIcon: null;
114
- }, {
115
- readonly name: "F2";
116
- readonly label: "Whistle";
117
- readonly lockable: false;
118
- readonly icon: null;
119
- readonly selectedIcon: null;
120
- }, {
121
- readonly name: "F3";
122
- readonly label: "Steam";
123
- readonly lockable: true;
124
- readonly icon: null;
125
- readonly selectedIcon: null;
126
- }, {
127
- readonly name: "F4";
128
- readonly label: null;
129
- readonly lockable: false;
130
- readonly icon: null;
131
- readonly selectedIcon: null;
132
- }];
133
- };
134
- readonly BNSF5240: {
135
- readonly name: "BNSF5240";
136
- readonly address: "5240";
137
- readonly isLongAddress: true;
138
- readonly road: "BNSF";
139
- readonly number: "5240";
140
- readonly mfg: "Kato";
141
- readonly model: "SD40-2";
142
- readonly comment: "Heritage II paint";
143
- readonly maxSpeed: 126;
144
- readonly functionKeys: readonly [{
145
- readonly name: "F0";
146
- readonly label: "Headlight";
147
- readonly lockable: true;
148
- readonly icon: null;
149
- readonly selectedIcon: null;
150
- }, {
151
- readonly name: "F1";
152
- readonly label: "Bell";
153
- readonly lockable: true;
154
- readonly icon: null;
155
- readonly selectedIcon: null;
156
- }, {
157
- readonly name: "F2";
158
- readonly label: "Horn";
159
- readonly lockable: false;
160
- readonly icon: null;
161
- readonly selectedIcon: null;
162
- }, {
163
- readonly name: "F3";
164
- readonly label: "Dynamic Brake";
165
- readonly lockable: true;
166
- readonly icon: null;
167
- readonly selectedIcon: null;
168
- }, {
169
- readonly name: "F4";
170
- readonly label: null;
171
- readonly lockable: false;
172
- readonly icon: null;
173
- readonly selectedIcon: null;
174
- }, {
175
- readonly name: "F5";
176
- readonly label: "Mars Light";
177
- readonly lockable: true;
178
- readonly icon: null;
179
- readonly selectedIcon: null;
180
- }];
181
- };
46
+ readonly name: "CSX754";
47
+ readonly address: "754";
48
+ readonly isLongAddress: true;
49
+ readonly road: "CSX";
50
+ readonly number: "754";
51
+ readonly mfg: "Athearn";
52
+ readonly decoderModel: "DH163D";
53
+ readonly decoderFamily: "Digitrax DH163";
54
+ readonly model: "GP38-2";
55
+ readonly comment: "Blue and yellow scheme";
56
+ readonly maxSpeedPct: 100;
57
+ readonly image: null;
58
+ readonly icon: "/roster/CSX754/icon";
59
+ readonly shuntingFunction: "";
60
+ readonly owner: "";
61
+ readonly dateModified: "2026-02-10T00:00:00.000+00:00";
62
+ readonly functionKeys: readonly [{
63
+ readonly name: "F0";
64
+ readonly label: "Headlight";
65
+ readonly lockable: true;
66
+ readonly icon: null;
67
+ readonly selectedIcon: null;
68
+ }, {
69
+ readonly name: "F1";
70
+ readonly label: "Bell";
71
+ readonly lockable: true;
72
+ readonly icon: null;
73
+ readonly selectedIcon: null;
74
+ }, {
75
+ readonly name: "F2";
76
+ readonly label: "Horn";
77
+ readonly lockable: false;
78
+ readonly icon: null;
79
+ readonly selectedIcon: null;
80
+ }, {
81
+ readonly name: "F3";
82
+ readonly label: null;
83
+ readonly lockable: false;
84
+ readonly icon: null;
85
+ readonly selectedIcon: null;
86
+ }, {
87
+ readonly name: "F4";
88
+ readonly label: "Dynamic Brake";
89
+ readonly lockable: true;
90
+ readonly icon: null;
91
+ readonly selectedIcon: null;
92
+ }, {
93
+ readonly name: "F5";
94
+ readonly label: null;
95
+ readonly lockable: false;
96
+ readonly icon: null;
97
+ readonly selectedIcon: null;
98
+ }];
99
+ readonly attributes: readonly [];
100
+ readonly rosterGroups: readonly [];
182
101
  };
183
- };
102
+ readonly id: 1;
103
+ }, {
104
+ readonly type: "rosterEntry";
105
+ readonly data: {
106
+ readonly name: "UP3985";
107
+ readonly address: "3985";
108
+ readonly isLongAddress: true;
109
+ readonly road: "Union Pacific";
110
+ readonly number: "3985";
111
+ readonly mfg: "Rivarossi";
112
+ readonly decoderModel: "Sound decoder";
113
+ readonly decoderFamily: "ESU LokSound";
114
+ readonly model: "Challenger 4-6-6-4";
115
+ readonly comment: "Steam locomotive";
116
+ readonly maxSpeedPct: 100;
117
+ readonly image: null;
118
+ readonly icon: "/roster/UP3985/icon";
119
+ readonly shuntingFunction: "";
120
+ readonly owner: "";
121
+ readonly dateModified: "2026-02-10T00:00:00.000+00:00";
122
+ readonly functionKeys: readonly [{
123
+ readonly name: "F0";
124
+ readonly label: "Headlight";
125
+ readonly lockable: true;
126
+ readonly icon: null;
127
+ readonly selectedIcon: null;
128
+ }, {
129
+ readonly name: "F1";
130
+ readonly label: "Bell";
131
+ readonly lockable: true;
132
+ readonly icon: null;
133
+ readonly selectedIcon: null;
134
+ }, {
135
+ readonly name: "F2";
136
+ readonly label: "Whistle";
137
+ readonly lockable: false;
138
+ readonly icon: null;
139
+ readonly selectedIcon: null;
140
+ }, {
141
+ readonly name: "F3";
142
+ readonly label: "Steam";
143
+ readonly lockable: true;
144
+ readonly icon: null;
145
+ readonly selectedIcon: null;
146
+ }, {
147
+ readonly name: "F4";
148
+ readonly label: null;
149
+ readonly lockable: false;
150
+ readonly icon: null;
151
+ readonly selectedIcon: null;
152
+ }];
153
+ readonly attributes: readonly [];
154
+ readonly rosterGroups: readonly [];
155
+ };
156
+ readonly id: 2;
157
+ }, {
158
+ readonly type: "rosterEntry";
159
+ readonly data: {
160
+ readonly name: "BNSF5240";
161
+ readonly address: "5240";
162
+ readonly isLongAddress: true;
163
+ readonly road: "BNSF";
164
+ readonly number: "5240";
165
+ readonly mfg: "Kato";
166
+ readonly decoderModel: "DCC Sound";
167
+ readonly decoderFamily: "Kato";
168
+ readonly model: "SD40-2";
169
+ readonly comment: "Heritage II paint";
170
+ readonly maxSpeedPct: 100;
171
+ readonly image: null;
172
+ readonly icon: "/roster/BNSF5240/icon";
173
+ readonly shuntingFunction: "";
174
+ readonly owner: "";
175
+ readonly dateModified: "2026-02-10T00:00:00.000+00:00";
176
+ readonly functionKeys: readonly [{
177
+ readonly name: "F0";
178
+ readonly label: "Headlight";
179
+ readonly lockable: true;
180
+ readonly icon: null;
181
+ readonly selectedIcon: null;
182
+ }, {
183
+ readonly name: "F1";
184
+ readonly label: "Bell";
185
+ readonly lockable: true;
186
+ readonly icon: null;
187
+ readonly selectedIcon: null;
188
+ }, {
189
+ readonly name: "F2";
190
+ readonly label: "Horn";
191
+ readonly lockable: false;
192
+ readonly icon: null;
193
+ readonly selectedIcon: null;
194
+ }, {
195
+ readonly name: "F3";
196
+ readonly label: "Dynamic Brake";
197
+ readonly lockable: true;
198
+ readonly icon: null;
199
+ readonly selectedIcon: null;
200
+ }, {
201
+ readonly name: "F4";
202
+ readonly label: null;
203
+ readonly lockable: false;
204
+ readonly icon: null;
205
+ readonly selectedIcon: null;
206
+ }, {
207
+ readonly name: "F5";
208
+ readonly label: "Mars Light";
209
+ readonly lockable: true;
210
+ readonly icon: null;
211
+ readonly selectedIcon: null;
212
+ }];
213
+ readonly attributes: readonly [];
214
+ readonly rosterGroups: readonly [];
215
+ };
216
+ readonly id: 3;
217
+ }];
184
218
  };
185
219
  readonly throttle: {
186
220
  readonly acquire: {
@@ -99,7 +99,7 @@ export interface FunctionKey {
99
99
  selectedIcon: string | null;
100
100
  }
101
101
  /**
102
- * Roster entry
102
+ * Roster entry data
103
103
  */
104
104
  export interface RosterEntry {
105
105
  name: string;
@@ -108,26 +108,46 @@ export interface RosterEntry {
108
108
  road?: string;
109
109
  number?: string;
110
110
  mfg?: string;
111
+ decoderModel?: string;
112
+ decoderFamily?: string;
111
113
  model?: string;
112
114
  comment?: string;
113
- maxSpeed?: number;
114
- imageFilePath?: string;
115
- iconFilePath?: string;
115
+ maxSpeedPct?: number;
116
+ image?: string | null;
117
+ icon?: string | null;
118
+ shuntingFunction?: string;
119
+ owner?: string;
120
+ dateModified?: string;
116
121
  functionKeys?: FunctionKey[];
122
+ attributes?: any[];
123
+ rosterGroups?: string[];
117
124
  }
118
125
  /**
119
- * Roster data structure
126
+ * Roster entry wrapper (as returned by JMRI server)
120
127
  */
121
- export interface RosterData {
122
- [key: string]: RosterEntry;
128
+ export interface RosterEntryWrapper {
129
+ type: 'rosterEntry';
130
+ data: RosterEntry;
131
+ id: number;
123
132
  }
124
133
  /**
125
- * Roster message
134
+ * Roster response (array of roster entries)
135
+ */
136
+ export type RosterResponse = RosterEntryWrapper[];
137
+ /**
138
+ * Roster message (deprecated - kept for backward compatibility)
126
139
  */
127
140
  export interface RosterMessage extends JmriMessage {
128
141
  type: 'roster';
129
142
  method: 'list';
130
- data?: RosterData;
143
+ data?: RosterResponse;
144
+ }
145
+ /**
146
+ * Legacy roster data structure (deprecated - kept for backward compatibility)
147
+ * @deprecated Use RosterResponse instead
148
+ */
149
+ export interface RosterData {
150
+ [key: string]: RosterEntry;
131
151
  }
132
152
  /**
133
153
  * Ping message (heartbeat)
@@ -148,10 +168,14 @@ export interface HelloMessage extends JmriMessage {
148
168
  type: 'hello';
149
169
  data?: {
150
170
  JMRI?: string;
151
- JSON?: string;
152
- Railroad?: string;
171
+ json?: string;
172
+ version?: string;
173
+ heartbeat?: number;
174
+ railroad?: string;
153
175
  node?: string;
154
176
  activeProfile?: string;
177
+ JSON?: string;
178
+ Railroad?: string;
155
179
  };
156
180
  }
157
181
  /**
package/docs/MOCK_MODE.md CHANGED
@@ -51,8 +51,12 @@ Connection establishment response with JMRI version info:
51
51
  "type": "hello",
52
52
  "data": {
53
53
  "JMRI": "5.9.2",
54
- "JSON": "5.0",
55
- "Railroad": "Demo Railroad"
54
+ "json": "5.0",
55
+ "version": "v5",
56
+ "heartbeat": 13500,
57
+ "railroad": "Demo Railroad",
58
+ "node": "jmri-server",
59
+ "activeProfile": "Demo Profile"
56
60
  }
57
61
  }
58
62
  ```
@@ -97,7 +101,7 @@ async function demo() {
97
101
 
98
102
  // Get roster
99
103
  const roster = await client.getRoster();
100
- console.log(`Found ${Object.keys(roster).length} locomotives`);
104
+ console.log(`Found ${roster.length} locomotives`);
101
105
 
102
106
  // Turn power on
103
107
  await client.powerOn();
@@ -132,8 +136,8 @@ The mock data is shared between the mock system and unit tests, ensuring consist
132
136
  ```typescript
133
137
  import { mockData, MockResponseManager } from 'jmri-client';
134
138
 
135
- // Access mock data directly
136
- const rosterData = mockData.roster.list.data;
139
+ // Access mock data directly (array of roster entry wrappers)
140
+ const rosterData = mockData.roster.list;
137
141
 
138
142
  // Or use the response manager
139
143
  const mockManager = new MockResponseManager();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jmri-client",
3
- "version": "3.4.0",
3
+ "version": "3.5.0",
4
4
  "description": "WebSocket client for JMRI with real-time updates and throttle control - works in both Node.js and browsers",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -1,176 +0,0 @@
1
- {
2
- "hello": {
3
- "type": "hello",
4
- "data": {
5
- "JMRI": "5.9.2",
6
- "JSON": "5.0",
7
- "Railroad": "Demo Railroad",
8
- "node": "jmri-server",
9
- "activeProfile": "Demo Profile"
10
- }
11
- },
12
- "power": {
13
- "get": {
14
- "on": {
15
- "type": "power",
16
- "data": {
17
- "state": 2
18
- }
19
- },
20
- "off": {
21
- "type": "power",
22
- "data": {
23
- "state": 4
24
- }
25
- }
26
- },
27
- "post": {
28
- "success": {
29
- "type": "power",
30
- "data": {
31
- "state": 2
32
- }
33
- }
34
- }
35
- },
36
- "roster": {
37
- "list": {
38
- "type": "roster",
39
- "data": {
40
- "CSX754": {
41
- "name": "CSX754",
42
- "address": "754",
43
- "isLongAddress": true,
44
- "road": "CSX",
45
- "number": "754",
46
- "mfg": "Athearn",
47
- "model": "GP38-2",
48
- "comment": "Blue and yellow scheme",
49
- "maxSpeed": 126,
50
- "functionKeys": {
51
- "F0": "Headlight",
52
- "F1": "Bell",
53
- "F2": "Horn",
54
- "F3": "Air Release",
55
- "F4": "Dynamic Brake"
56
- }
57
- },
58
- "UP3985": {
59
- "name": "UP3985",
60
- "address": "3985",
61
- "isLongAddress": true,
62
- "road": "Union Pacific",
63
- "number": "3985",
64
- "mfg": "Rivarossi",
65
- "model": "Challenger 4-6-6-4",
66
- "comment": "Steam locomotive",
67
- "maxSpeed": 126,
68
- "functionKeys": {
69
- "F0": "Headlight",
70
- "F1": "Bell",
71
- "F2": "Whistle",
72
- "F3": "Steam",
73
- "F4": "Coupler"
74
- }
75
- },
76
- "BNSF5240": {
77
- "name": "BNSF5240",
78
- "address": "5240",
79
- "isLongAddress": true,
80
- "road": "BNSF",
81
- "number": "5240",
82
- "mfg": "Kato",
83
- "model": "SD40-2",
84
- "comment": "Heritage II paint",
85
- "maxSpeed": 126,
86
- "functionKeys": {
87
- "F0": "Headlight",
88
- "F1": "Bell",
89
- "F2": "Horn",
90
- "F3": "Dynamic Brake",
91
- "F4": "Mars Light"
92
- }
93
- }
94
- }
95
- }
96
- },
97
- "throttle": {
98
- "acquire": {
99
- "success": {
100
- "type": "throttle",
101
- "data": {
102
- "throttle": "{THROTTLE_ID}",
103
- "address": "{ADDRESS}",
104
- "speed": 0,
105
- "forward": true,
106
- "F0": false,
107
- "F1": false,
108
- "F2": false,
109
- "F3": false,
110
- "F4": false
111
- }
112
- }
113
- },
114
- "release": {
115
- "success": {
116
- "type": "throttle",
117
- "data": {}
118
- }
119
- },
120
- "control": {
121
- "speed": {
122
- "type": "throttle",
123
- "data": {
124
- "throttle": "{THROTTLE_ID}",
125
- "speed": "{SPEED}"
126
- }
127
- },
128
- "direction": {
129
- "type": "throttle",
130
- "data": {
131
- "throttle": "{THROTTLE_ID}",
132
- "forward": "{FORWARD}"
133
- }
134
- },
135
- "function": {
136
- "type": "throttle",
137
- "data": {
138
- "throttle": "{THROTTLE_ID}",
139
- "{FUNCTION}": "{VALUE}"
140
- }
141
- }
142
- }
143
- },
144
- "ping": {
145
- "type": "ping"
146
- },
147
- "pong": {
148
- "type": "pong"
149
- },
150
- "goodbye": {
151
- "type": "goodbye"
152
- },
153
- "error": {
154
- "throttleNotFound": {
155
- "type": "error",
156
- "data": {
157
- "code": 404,
158
- "message": "Throttle not found"
159
- }
160
- },
161
- "invalidSpeed": {
162
- "type": "error",
163
- "data": {
164
- "code": 400,
165
- "message": "Invalid speed value"
166
- }
167
- },
168
- "connectionError": {
169
- "type": "error",
170
- "data": {
171
- "code": 500,
172
- "message": "Connection error"
173
- }
174
- }
175
- }
176
- }