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
package/docs/BROWSER.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Browser Usage Guide
2
2
 
3
- jmri-client v3.2.0+ supports both Node.js and browser environments. This guide shows how to use jmri-client in web applications.
3
+ jmri-client supports both Node.js and browser environments. This guide shows how to use jmri-client in web applications.
4
4
 
5
5
  ## Installation
6
6
 
@@ -112,7 +112,7 @@ For quick prototypes without a build step, use the browser bundle:
112
112
 
113
113
  <script type="module">
114
114
  // Use the browser bundle from CDN
115
- import { JmriClient } from 'https://unpkg.com/jmri-client@3.3.0/dist/browser/jmri-client.js';
115
+ import { JmriClient } from 'https://unpkg.com/jmri-client@5.0.0/dist/browser/jmri-client.js';
116
116
 
117
117
  const client = new JmriClient({
118
118
  host: 'localhost',
@@ -144,8 +144,8 @@ For quick prototypes without a build step, use the browser bundle:
144
144
  ```
145
145
 
146
146
  Alternative CDNs:
147
- - **unpkg**: `https://unpkg.com/jmri-client@3.3.0/dist/browser/jmri-client.js`
148
- - **jsDelivr**: `https://cdn.jsdelivr.net/npm/jmri-client@3.3.0/dist/browser/jmri-client.js`
147
+ - **unpkg**: `https://unpkg.com/jmri-client@5.0.0/dist/browser/jmri-client.js`
148
+ - **jsDelivr**: `https://cdn.jsdelivr.net/npm/jmri-client@5.0.0/dist/browser/jmri-client.js`
149
149
 
150
150
  ## React Example
151
151
 
package/docs/MIGRATION.md CHANGED
@@ -1,4 +1,33 @@
1
- # Migration Guide: v2.x to v3.x
1
+ # Migration Guide
2
+
3
+ ## v4.x to v5.0
4
+
5
+ ### Breaking Changes
6
+
7
+ #### Node.js version requirement
8
+
9
+ **v4.x:** Node.js 18+
10
+ **v5.0:** Node.js 22+
11
+
12
+ Node 18 reached end-of-life in April 2025 and Node 20 in April 2026. v5.0 requires Node 22 (Active LTS, EOL April 2027) or later.
13
+
14
+ ```bash
15
+ node --version # Should be >= 22.0.0
16
+ ```
17
+
18
+ #### No API changes
19
+
20
+ There are no API-level breaking changes between v4.x and v5.0. All existing code targeting v4.x will work without modification.
21
+
22
+ ### What's new in v5.0
23
+
24
+ - Node.js 22+ required (drops EOL Node 18 and 20)
25
+ - Built with TypeScript 6
26
+ - esbuild-based build pipeline — faster, smaller outputs, no more dual `tsc` compilation
27
+
28
+ ---
29
+
30
+ ## v2.x to v3.x
2
31
 
3
32
  ## Overview
4
33
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jmri-client",
3
- "version": "4.2.0-beta.2",
3
+ "version": "5.0.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",
@@ -8,19 +8,18 @@
8
8
  "types": "./dist/types/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
+ "types": "./dist/types/index.d.ts",
11
12
  "browser": "./dist/browser/jmri-client.js",
12
13
  "import": "./dist/esm/index.js",
13
- "require": "./dist/cjs/index.js",
14
- "types": "./dist/types/index.d.ts"
14
+ "require": "./dist/cjs/index.js"
15
15
  }
16
16
  },
17
17
  "scripts": {
18
18
  "prepublishOnly": "npm run build",
19
- "build": "npm run build:cjs && npm run build:esm && npm run build:types && npm run build:browser",
20
- "build:cjs": "tsc -p tsconfig.json",
21
- "build:esm": "tsc -p tsconfig.esm.json",
22
- "build:types": "tsc -p tsconfig.json --declaration --emitDeclarationOnly --outDir dist/types",
23
- "build:browser": "node build-browser.mjs",
19
+ "clean": "rm -rf dist",
20
+ "build": "npm run clean && node build.mjs && npm run build:types",
21
+ "build:types": "tsc -p tsconfig.json",
22
+ "typecheck": "tsc -p tsconfig.json --noEmit",
24
23
  "test": "jest --no-cache --coverage",
25
24
  "test:browser": "node ./tests/integration/serve-test.mjs",
26
25
  "test:reconnect": "node ./tests/integration/forced-reconnect.mjs",
@@ -59,21 +58,21 @@
59
58
  "url": "https://github.com/yamanote1138/jmri-client/issues"
60
59
  },
61
60
  "engines": {
62
- "node": ">=18"
61
+ "node": ">=22"
63
62
  },
64
63
  "devDependencies": {
65
- "@types/jest": "^29.0.3",
66
- "@types/node": "^18.19.0",
67
- "@types/ws": "^8.5.10",
68
- "esbuild": "^0.27.3",
69
- "jest": "^29.0.3",
70
- "playwright": "^1.58.2",
71
- "ts-jest": "^29.4.6",
72
- "typescript": "^5.3.3"
64
+ "@types/jest": "^30.0.0",
65
+ "@types/node": "^22.0.0",
66
+ "@types/ws": "^8.18.0",
67
+ "esbuild": "^0.28.0",
68
+ "jest": "^30.0.0",
69
+ "playwright": "^1.60.0",
70
+ "ts-jest": "^29.4.11",
71
+ "typescript": "^6.0.0"
73
72
  },
74
73
  "dependencies": {
75
74
  "eventemitter3": "^5.0.4",
76
- "ws": "^8.16.0"
75
+ "ws": "^8.21.0"
77
76
  },
78
77
  "files": [
79
78
  "dist",
@@ -1,366 +0,0 @@
1
- "use strict";
2
- /**
3
- * Main JMRI client class
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.JmriClient = void 0;
7
- const eventemitter3_1 = require("eventemitter3");
8
- const websocket_client_js_1 = require("./core/websocket-client.js");
9
- const power_manager_js_1 = require("./managers/power-manager.js");
10
- const roster_manager_js_1 = require("./managers/roster-manager.js");
11
- const throttle_manager_js_1 = require("./managers/throttle-manager.js");
12
- const turnout_manager_js_1 = require("./managers/turnout-manager.js");
13
- const light_manager_js_1 = require("./managers/light-manager.js");
14
- const system_connections_manager_js_1 = require("./managers/system-connections-manager.js");
15
- const client_options_js_1 = require("./types/client-options.js");
16
- /**
17
- * JMRI WebSocket Client
18
- * Provides event-driven interface to JMRI with throttle control
19
- */
20
- class JmriClient extends eventemitter3_1.EventEmitter {
21
- /**
22
- * Create a new JMRI client
23
- *
24
- * @param options - Client configuration options
25
- *
26
- * @example
27
- * ```typescript
28
- * const client = new JmriClient({
29
- * host: 'jmri.local',
30
- * port: 12080
31
- * });
32
- *
33
- * client.on('connected', () => console.log('Connected!'));
34
- * client.on('power:changed', (state) => console.log('Power:', state));
35
- * ```
36
- */
37
- constructor(options) {
38
- super();
39
- // Merge options with defaults
40
- this.options = (0, client_options_js_1.mergeOptions)(options);
41
- // Create WebSocket client
42
- this.wsClient = new websocket_client_js_1.WebSocketClient(this.options);
43
- // Create managers
44
- this.powerManager = new power_manager_js_1.PowerManager(this.wsClient);
45
- this.rosterManager = new roster_manager_js_1.RosterManager(this.wsClient);
46
- this.throttleManager = new throttle_manager_js_1.ThrottleManager(this.wsClient);
47
- this.turnoutManager = new turnout_manager_js_1.TurnoutManager(this.wsClient);
48
- this.lightManager = new light_manager_js_1.LightManager(this.wsClient);
49
- this.systemConnectionsManager = new system_connections_manager_js_1.SystemConnectionsManager(this.wsClient);
50
- // Forward events from WebSocket client
51
- this.wsClient.on('connected', () => this.emit('connected'));
52
- this.wsClient.on('disconnected', (reason) => this.emit('disconnected', reason));
53
- this.wsClient.on('reconnecting', (attempt, delay) => this.emit('reconnecting', attempt, delay));
54
- this.wsClient.on('reconnected', () => this.emit('reconnected'));
55
- this.wsClient.on('reconnectionFailed', (attempts) => this.emit('reconnectionFailed', attempts));
56
- this.wsClient.on('connectionStateChanged', (state) => this.emit('connectionStateChanged', state));
57
- this.wsClient.on('error', (error) => this.emit('error', error));
58
- this.wsClient.on('heartbeat:sent', () => this.emit('heartbeat:sent'));
59
- this.wsClient.on('heartbeat:timeout', () => this.emit('heartbeat:timeout'));
60
- this.wsClient.on('hello', (data) => this.emit('hello', data));
61
- // Forward events from managers
62
- this.powerManager.on('power:changed', (state) => this.emit('power:changed', state));
63
- this.turnoutManager.on('turnout:changed', (name, state) => this.emit('turnout:changed', name, state));
64
- this.lightManager.on('light:changed', (name, state) => this.emit('light:changed', name, state));
65
- this.throttleManager.on('throttle:acquired', (id) => this.emit('throttle:acquired', id));
66
- this.throttleManager.on('throttle:updated', (id, data) => this.emit('throttle:updated', id, data));
67
- this.throttleManager.on('throttle:released', (id) => this.emit('throttle:released', id));
68
- this.throttleManager.on('throttle:lost', (id) => this.emit('throttle:lost', id));
69
- // Auto-connect if enabled
70
- if (this.options.autoConnect) {
71
- this.connect().catch((error) => {
72
- this.emit('error', error);
73
- });
74
- }
75
- }
76
- /**
77
- * Connect to JMRI server
78
- */
79
- async connect() {
80
- return this.wsClient.connect();
81
- }
82
- /**
83
- * Disconnect from JMRI server
84
- * Releases all throttles and closes connection
85
- */
86
- async disconnect() {
87
- // Release all throttles first
88
- await this.throttleManager.releaseAllThrottles();
89
- // Disconnect WebSocket
90
- return this.wsClient.disconnect();
91
- }
92
- /**
93
- * Get current connection state
94
- */
95
- getConnectionState() {
96
- return this.wsClient.getState();
97
- }
98
- /**
99
- * Check if connected to JMRI
100
- */
101
- isConnected() {
102
- return this.wsClient.isConnected();
103
- }
104
- // ============================================================================
105
- // Power Control
106
- // ============================================================================
107
- /**
108
- * Get current track power state
109
- * @param prefix - Optional JMRI connection prefix to target a specific hardware connection
110
- */
111
- async getPower(prefix) {
112
- return this.powerManager.getPower(prefix);
113
- }
114
- /**
115
- * Set track power state
116
- * @param state - The desired power state
117
- * @param prefix - Optional JMRI connection prefix to target a specific hardware connection
118
- */
119
- async setPower(state, prefix) {
120
- return this.powerManager.setPower(state, prefix);
121
- }
122
- /**
123
- * Turn track power on
124
- * @param prefix - Optional JMRI connection prefix to target a specific hardware connection
125
- */
126
- async powerOn(prefix) {
127
- return this.powerManager.powerOn(prefix);
128
- }
129
- /**
130
- * Turn track power off
131
- * @param prefix - Optional JMRI connection prefix to target a specific hardware connection
132
- */
133
- async powerOff(prefix) {
134
- return this.powerManager.powerOff(prefix);
135
- }
136
- // ============================================================================
137
- // System Connections
138
- // ============================================================================
139
- /**
140
- * List all available JMRI system connections and their prefixes.
141
- * Use the returned prefix values with power and throttle commands to
142
- * target a specific hardware connection when multiple are configured.
143
- *
144
- * @example
145
- * ```typescript
146
- * const connections = await client.getSystemConnections();
147
- * // [{ name: 'LocoNet', prefix: 'L' }, { name: 'DCC++', prefix: 'D' }]
148
- * await client.powerOn('L'); // power on via LocoNet only
149
- * ```
150
- */
151
- async getSystemConnections() {
152
- return this.systemConnectionsManager.getSystemConnections();
153
- }
154
- // ============================================================================
155
- // Roster Management
156
- // ============================================================================
157
- /**
158
- * Get all roster entries
159
- */
160
- async getRoster() {
161
- return this.rosterManager.getRoster();
162
- }
163
- /**
164
- * Get roster entry by name
165
- */
166
- async getRosterEntryByName(name) {
167
- return this.rosterManager.getRosterEntryByName(name);
168
- }
169
- /**
170
- * Get roster entry by address
171
- */
172
- async getRosterEntryByAddress(address) {
173
- return this.rosterManager.getRosterEntryByAddress(address);
174
- }
175
- /**
176
- * Search roster by partial name match
177
- */
178
- async searchRoster(query) {
179
- return this.rosterManager.searchRoster(query);
180
- }
181
- // ============================================================================
182
- // Turnout Control
183
- // ============================================================================
184
- /**
185
- * Get the current state of a turnout
186
- */
187
- async getTurnout(name) {
188
- return this.turnoutManager.getTurnout(name);
189
- }
190
- /**
191
- * Set a turnout to the given state
192
- */
193
- async setTurnout(name, state) {
194
- return this.turnoutManager.setTurnout(name, state);
195
- }
196
- /**
197
- * Throw a turnout (diverging route)
198
- */
199
- async throwTurnout(name) {
200
- return this.turnoutManager.throwTurnout(name);
201
- }
202
- /**
203
- * Close a turnout (straight through / normal)
204
- */
205
- async closeTurnout(name) {
206
- return this.turnoutManager.closeTurnout(name);
207
- }
208
- /**
209
- * List all turnouts known to JMRI
210
- */
211
- async listTurnouts() {
212
- return this.turnoutManager.listTurnouts();
213
- }
214
- /**
215
- * Get cached turnout state without a network request
216
- */
217
- getTurnoutState(name) {
218
- return this.turnoutManager.getTurnoutState(name);
219
- }
220
- /**
221
- * Get all cached turnout states
222
- */
223
- getCachedTurnouts() {
224
- return this.turnoutManager.getCachedTurnouts();
225
- }
226
- // ============================================================================
227
- // Light Control
228
- // ============================================================================
229
- /**
230
- * Get the current state of a light
231
- */
232
- async getLight(name) {
233
- return this.lightManager.getLight(name);
234
- }
235
- /**
236
- * Set a light to the given state
237
- */
238
- async setLight(name, state) {
239
- return this.lightManager.setLight(name, state);
240
- }
241
- /**
242
- * Turn a light on
243
- */
244
- async turnOnLight(name) {
245
- return this.lightManager.turnOnLight(name);
246
- }
247
- /**
248
- * Turn a light off
249
- */
250
- async turnOffLight(name) {
251
- return this.lightManager.turnOffLight(name);
252
- }
253
- /**
254
- * List all lights known to JMRI
255
- */
256
- async listLights() {
257
- return this.lightManager.listLights();
258
- }
259
- /**
260
- * Get cached light state without a network request
261
- */
262
- getLightState(name) {
263
- return this.lightManager.getLightState(name);
264
- }
265
- /**
266
- * Get all cached light states
267
- */
268
- getCachedLights() {
269
- return this.lightManager.getCachedLights();
270
- }
271
- // ============================================================================
272
- // Throttle Control
273
- // ============================================================================
274
- /**
275
- * Acquire a throttle for a locomotive
276
- *
277
- * @param options - Throttle acquisition options
278
- * @returns Throttle ID for use in other throttle methods
279
- *
280
- * @example
281
- * ```typescript
282
- * const throttleId = await client.acquireThrottle({ address: 3 });
283
- * await client.setThrottleSpeed(throttleId, 0.5); // Half speed
284
- * ```
285
- */
286
- async acquireThrottle(options) {
287
- return this.throttleManager.acquireThrottle(options);
288
- }
289
- /**
290
- * Release a throttle
291
- */
292
- async releaseThrottle(throttleId) {
293
- return this.throttleManager.releaseThrottle(throttleId);
294
- }
295
- /**
296
- * Set throttle speed (0.0 to 1.0)
297
- *
298
- * @param throttleId - Throttle ID from acquireThrottle
299
- * @param speed - Speed value between 0.0 (stopped) and 1.0 (full speed)
300
- */
301
- async setThrottleSpeed(throttleId, speed) {
302
- return this.throttleManager.setSpeed(throttleId, speed);
303
- }
304
- /**
305
- * Set throttle direction
306
- *
307
- * @param throttleId - Throttle ID from acquireThrottle
308
- * @param forward - True for forward, false for reverse
309
- */
310
- async setThrottleDirection(throttleId, forward) {
311
- return this.throttleManager.setDirection(throttleId, forward);
312
- }
313
- /**
314
- * Set throttle function (F0-F28)
315
- *
316
- * @param throttleId - Throttle ID from acquireThrottle
317
- * @param functionKey - Function key (F0-F28)
318
- * @param value - True to activate, false to deactivate
319
- *
320
- * @example
321
- * ```typescript
322
- * await client.setThrottleFunction(throttleId, 'F0', true); // Headlight on
323
- * await client.setThrottleFunction(throttleId, 'F2', true); // Horn
324
- * ```
325
- */
326
- async setThrottleFunction(throttleId, functionKey, value) {
327
- return this.throttleManager.setFunction(throttleId, functionKey, value);
328
- }
329
- /**
330
- * Emergency stop for a throttle (speed to 0)
331
- */
332
- async emergencyStop(throttleId) {
333
- return this.throttleManager.emergencyStop(throttleId);
334
- }
335
- /**
336
- * Set throttle to idle (speed to 0, maintain direction)
337
- */
338
- async idleThrottle(throttleId) {
339
- return this.throttleManager.idle(throttleId);
340
- }
341
- /**
342
- * Get throttle state
343
- */
344
- getThrottleState(throttleId) {
345
- return this.throttleManager.getThrottleState(throttleId);
346
- }
347
- /**
348
- * Get all throttle IDs
349
- */
350
- getThrottleIds() {
351
- return this.throttleManager.getThrottleIds();
352
- }
353
- /**
354
- * Get all throttle states
355
- */
356
- getAllThrottles() {
357
- return this.throttleManager.getAllThrottles();
358
- }
359
- /**
360
- * Release all throttles
361
- */
362
- async releaseAllThrottles() {
363
- return this.throttleManager.releaseAllThrottles();
364
- }
365
- }
366
- exports.JmriClient = JmriClient;
@@ -1,84 +0,0 @@
1
- "use strict";
2
- /**
3
- * Connection state management with state machine
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ConnectionStateManager = void 0;
7
- const eventemitter3_1 = require("eventemitter3");
8
- const events_js_1 = require("../types/events.js");
9
- /**
10
- * Valid state transitions
11
- */
12
- const VALID_TRANSITIONS = {
13
- [events_js_1.ConnectionState.DISCONNECTED]: [events_js_1.ConnectionState.CONNECTING],
14
- [events_js_1.ConnectionState.CONNECTING]: [events_js_1.ConnectionState.CONNECTED, events_js_1.ConnectionState.DISCONNECTED],
15
- [events_js_1.ConnectionState.CONNECTED]: [events_js_1.ConnectionState.DISCONNECTED, events_js_1.ConnectionState.RECONNECTING],
16
- [events_js_1.ConnectionState.RECONNECTING]: [events_js_1.ConnectionState.CONNECTING, events_js_1.ConnectionState.CONNECTED, events_js_1.ConnectionState.DISCONNECTED]
17
- };
18
- /**
19
- * Manages connection state with validation
20
- */
21
- class ConnectionStateManager extends eventemitter3_1.EventEmitter {
22
- constructor() {
23
- super(...arguments);
24
- this.currentState = events_js_1.ConnectionState.DISCONNECTED;
25
- }
26
- /**
27
- * Get current connection state
28
- */
29
- getState() {
30
- return this.currentState;
31
- }
32
- /**
33
- * Check if currently connected
34
- */
35
- isConnected() {
36
- return this.currentState === events_js_1.ConnectionState.CONNECTED;
37
- }
38
- /**
39
- * Check if currently connecting
40
- */
41
- isConnecting() {
42
- return this.currentState === events_js_1.ConnectionState.CONNECTING;
43
- }
44
- /**
45
- * Check if currently disconnected
46
- */
47
- isDisconnected() {
48
- return this.currentState === events_js_1.ConnectionState.DISCONNECTED;
49
- }
50
- /**
51
- * Check if currently reconnecting
52
- */
53
- isReconnecting() {
54
- return this.currentState === events_js_1.ConnectionState.RECONNECTING;
55
- }
56
- /**
57
- * Transition to new state
58
- * Validates transition and emits event
59
- */
60
- transition(newState) {
61
- const validTransitions = VALID_TRANSITIONS[this.currentState];
62
- if (!validTransitions.includes(newState)) {
63
- throw new Error(`Invalid state transition: ${this.currentState} -> ${newState}`);
64
- }
65
- const previousState = this.currentState;
66
- this.currentState = newState;
67
- this.emit('stateChanged', newState, previousState);
68
- }
69
- /**
70
- * Force state without validation (use with caution)
71
- */
72
- forceState(newState) {
73
- const previousState = this.currentState;
74
- this.currentState = newState;
75
- this.emit('stateChanged', newState, previousState);
76
- }
77
- /**
78
- * Reset to disconnected state
79
- */
80
- reset() {
81
- this.forceState(events_js_1.ConnectionState.DISCONNECTED);
82
- }
83
- }
84
- exports.ConnectionStateManager = ConnectionStateManager;
@@ -1,79 +0,0 @@
1
- "use strict";
2
- /**
3
- * Heartbeat (ping/pong) management
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.HeartbeatManager = void 0;
7
- const eventemitter3_1 = require("eventemitter3");
8
- /**
9
- * Manages WebSocket heartbeat via ping/pong
10
- */
11
- class HeartbeatManager extends eventemitter3_1.EventEmitter {
12
- constructor(options) {
13
- super();
14
- this.isRunning = false;
15
- this.options = options;
16
- }
17
- /**
18
- * Start heartbeat monitoring
19
- * @param sendPing - Callback to send ping message
20
- */
21
- start(sendPing) {
22
- if (!this.options.enabled || this.isRunning) {
23
- return;
24
- }
25
- this.isRunning = true;
26
- // Send ping at regular intervals
27
- this.pingInterval = setInterval(() => {
28
- sendPing();
29
- this.emit('pingSent');
30
- // Start pong timeout
31
- this.pongTimeout = setTimeout(() => {
32
- this.emit('timeout');
33
- }, this.options.timeout);
34
- }, this.options.interval);
35
- }
36
- /**
37
- * Stop heartbeat monitoring
38
- */
39
- stop() {
40
- this.isRunning = false;
41
- if (this.pingInterval) {
42
- clearInterval(this.pingInterval);
43
- this.pingInterval = undefined;
44
- }
45
- if (this.pongTimeout) {
46
- clearTimeout(this.pongTimeout);
47
- this.pongTimeout = undefined;
48
- }
49
- }
50
- /**
51
- * Handle pong received from server
52
- */
53
- receivedPong() {
54
- // Clear pong timeout
55
- if (this.pongTimeout) {
56
- clearTimeout(this.pongTimeout);
57
- this.pongTimeout = undefined;
58
- }
59
- this.emit('pongReceived');
60
- }
61
- /**
62
- * Check if heartbeat is running
63
- */
64
- running() {
65
- return this.isRunning;
66
- }
67
- /**
68
- * Update heartbeat options
69
- */
70
- updateOptions(options) {
71
- const wasRunning = this.isRunning;
72
- if (wasRunning) {
73
- this.stop();
74
- }
75
- this.options = { ...this.options, ...options };
76
- // Note: Caller must call start() again if needed
77
- }
78
- }
79
- exports.HeartbeatManager = HeartbeatManager;
@@ -1,25 +0,0 @@
1
- "use strict";
2
- /**
3
- * Core infrastructure exports
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("./websocket-client.js"), exports);
21
- __exportStar(require("./websocket-adapter.js"), exports);
22
- __exportStar(require("./connection-state-manager.js"), exports);
23
- __exportStar(require("./reconnection-manager.js"), exports);
24
- __exportStar(require("./heartbeat-manager.js"), exports);
25
- __exportStar(require("./message-queue.js"), exports);