jmri-client 2.2.0 → 3.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.
- package/README.md +109 -47
- package/dist/cjs/client.js +245 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/core/connection-state-manager.js +85 -0
- package/dist/cjs/core/connection-state-manager.js.map +1 -0
- package/dist/cjs/core/heartbeat-manager.js +80 -0
- package/dist/cjs/core/heartbeat-manager.js.map +1 -0
- package/dist/cjs/core/index.js +25 -0
- package/dist/cjs/core/index.js.map +1 -0
- package/dist/cjs/core/message-queue.js +60 -0
- package/dist/cjs/core/message-queue.js.map +1 -0
- package/dist/cjs/core/reconnection-manager.js +98 -0
- package/dist/cjs/core/reconnection-manager.js.map +1 -0
- package/dist/cjs/core/websocket-client.js +374 -0
- package/dist/cjs/core/websocket-client.js.map +1 -0
- package/dist/cjs/index.js +25 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/managers/index.js +23 -0
- package/dist/cjs/managers/index.js.map +1 -0
- package/dist/cjs/managers/power-manager.js +81 -0
- package/dist/cjs/managers/power-manager.js.map +1 -0
- package/dist/cjs/managers/roster-manager.js +101 -0
- package/dist/cjs/managers/roster-manager.js.map +1 -0
- package/dist/cjs/managers/throttle-manager.js +230 -0
- package/dist/cjs/managers/throttle-manager.js.map +1 -0
- package/dist/cjs/mocks/index.js +13 -0
- package/dist/cjs/mocks/index.js.map +1 -0
- package/dist/cjs/mocks/mock-data.js +184 -0
- package/dist/cjs/mocks/mock-data.js.map +1 -0
- package/dist/cjs/mocks/mock-data.json +176 -0
- package/dist/cjs/mocks/mock-response-manager.js +207 -0
- package/dist/cjs/mocks/mock-response-manager.js.map +1 -0
- package/dist/cjs/types/client-options.js +67 -0
- package/dist/cjs/types/client-options.js.map +1 -0
- package/dist/cjs/types/events.js +17 -0
- package/dist/cjs/types/events.js.map +1 -0
- package/dist/cjs/types/index.js +24 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/types/jmri-messages.js +18 -0
- package/dist/cjs/types/jmri-messages.js.map +1 -0
- package/dist/cjs/types/throttle.js +20 -0
- package/dist/cjs/types/throttle.js.map +1 -0
- package/dist/cjs/utils/exponential-backoff.js +41 -0
- package/dist/cjs/utils/exponential-backoff.js.map +1 -0
- package/dist/cjs/utils/index.js +22 -0
- package/dist/cjs/utils/index.js.map +1 -0
- package/dist/cjs/utils/message-id.js +41 -0
- package/dist/cjs/utils/message-id.js.map +1 -0
- package/dist/esm/client.js +241 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/core/connection-state-manager.js +81 -0
- package/dist/esm/core/connection-state-manager.js.map +1 -0
- package/dist/esm/core/heartbeat-manager.js +76 -0
- package/dist/esm/core/heartbeat-manager.js.map +1 -0
- package/dist/esm/core/index.js +9 -0
- package/dist/esm/core/index.js.map +1 -0
- package/dist/esm/core/message-queue.js +56 -0
- package/dist/esm/core/message-queue.js.map +1 -0
- package/dist/esm/core/reconnection-manager.js +94 -0
- package/dist/esm/core/reconnection-manager.js.map +1 -0
- package/dist/esm/core/websocket-client.js +367 -0
- package/dist/esm/core/websocket-client.js.map +1 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/managers/index.js +7 -0
- package/dist/esm/managers/index.js.map +1 -0
- package/dist/esm/managers/power-manager.js +77 -0
- package/dist/esm/managers/power-manager.js.map +1 -0
- package/dist/esm/managers/roster-manager.js +97 -0
- package/dist/esm/managers/roster-manager.js.map +1 -0
- package/dist/esm/managers/throttle-manager.js +226 -0
- package/dist/esm/managers/throttle-manager.js.map +1 -0
- package/dist/esm/mocks/index.js +7 -0
- package/dist/esm/mocks/index.js.map +1 -0
- package/dist/esm/mocks/mock-data.js +181 -0
- package/dist/esm/mocks/mock-data.js.map +1 -0
- package/dist/esm/mocks/mock-data.json +176 -0
- package/dist/esm/mocks/mock-response-manager.js +203 -0
- package/dist/esm/mocks/mock-response-manager.js.map +1 -0
- package/dist/esm/types/client-options.js +63 -0
- package/dist/esm/types/client-options.js.map +1 -0
- package/dist/esm/types/events.js +14 -0
- package/dist/esm/types/events.js.map +1 -0
- package/dist/esm/types/index.js +8 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/jmri-messages.js +15 -0
- package/dist/esm/types/jmri-messages.js.map +1 -0
- package/dist/esm/types/throttle.js +16 -0
- package/dist/esm/types/throttle.js.map +1 -0
- package/dist/esm/utils/exponential-backoff.js +37 -0
- package/dist/esm/utils/exponential-backoff.js.map +1 -0
- package/dist/esm/utils/index.js +6 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/message-id.js +37 -0
- package/dist/esm/utils/message-id.js.map +1 -0
- package/dist/types/client.d.ts +154 -0
- package/dist/types/core/connection-state-manager.d.ts +44 -0
- package/dist/types/core/heartbeat-manager.d.ts +36 -0
- package/dist/types/core/index.d.ts +8 -0
- package/dist/types/core/message-queue.d.ts +38 -0
- package/dist/types/core/reconnection-manager.d.ts +44 -0
- package/dist/types/core/websocket-client.d.ts +88 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/managers/index.d.ts +6 -0
- package/dist/types/managers/power-manager.d.ts +38 -0
- package/dist/types/managers/roster-manager.d.ts +41 -0
- package/dist/types/managers/throttle-manager.d.ts +67 -0
- package/dist/types/mocks/index.d.ts +6 -0
- package/dist/types/mocks/mock-data.d.ts +180 -0
- package/dist/types/mocks/mock-response-manager.d.ts +77 -0
- package/dist/types/types/client-options.d.ts +129 -0
- package/dist/types/types/events.d.ts +44 -0
- package/dist/types/types/index.d.ts +7 -0
- package/dist/types/types/jmri-messages.d.ts +160 -0
- package/dist/types/types/throttle.d.ts +57 -0
- package/dist/types/utils/exponential-backoff.d.ts +20 -0
- package/dist/types/utils/index.d.ts +5 -0
- package/dist/types/utils/message-id.d.ts +24 -0
- package/docs/API.md +155 -0
- package/docs/EXAMPLES.md +260 -0
- package/docs/MIGRATION.md +273 -0
- package/docs/MOCK_MODE.md +211 -0
- package/docs/TESTING.md +187 -0
- package/docs/TROUBLESHOOTING.md +364 -0
- package/package.json +28 -15
- package/dist/index.d.ts +0 -15
- package/dist/index.js +0 -126
- package/index.js +0 -1
package/README.md
CHANGED
|
@@ -1,76 +1,138 @@
|
|
|
1
|
-
jmri-client
|
|
1
|
+
# jmri-client
|
|
2
|
+
|
|
2
3
|
[](https://github.com/yamanote1138/jmri-client/actions/workflows/build-and-test.yml)
|
|
3
4
|

|
|
4
5
|

|
|
5
|
-
=========
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
this allows basic control of a model railroad layout via DCC
|
|
7
|
+
WebSocket client for [JMRI](http://jmri.sourceforge.net/) with real-time updates and full throttle control.
|
|
9
8
|
|
|
10
9
|
[](https://nodei.co/npm/jmri-client/)
|
|
11
10
|
|
|
12
|
-
##
|
|
11
|
+
## Features
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
- ✅ **WebSocket-based** - Real-time bidirectional communication
|
|
14
|
+
- ✅ **Event-driven** - Subscribe to power changes, throttle updates, and more
|
|
15
|
+
- ✅ **Full Throttle Control** - Speed (0.0-1.0), direction, and functions (F0-F28)
|
|
16
|
+
- ✅ **Mock Mode** - Test and demo without JMRI hardware
|
|
17
|
+
- ✅ **Auto-reconnection** - Exponential backoff with jitter
|
|
18
|
+
- ✅ **Heartbeat monitoring** - Automatic ping/pong keepalive
|
|
19
|
+
- ✅ **TypeScript** - Full type definitions included
|
|
20
|
+
- ✅ **Dual module support** - ESM and CommonJS
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
## Installation
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
```bash
|
|
25
|
+
npm install jmri-client
|
|
21
26
|
```
|
|
22
27
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
**Requirements:** Node.js 18+
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { JmriClient, PowerState } from 'jmri-client';
|
|
34
|
+
|
|
35
|
+
// Create client
|
|
36
|
+
const client = new JmriClient({
|
|
37
|
+
host: 'jmri.local',
|
|
38
|
+
port: 12080
|
|
28
39
|
});
|
|
29
|
-
```
|
|
30
40
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
console.log(res);
|
|
41
|
+
// Listen for events
|
|
42
|
+
client.on('connected', () => console.log('Connected!'));
|
|
43
|
+
client.on('power:changed', (state) => {
|
|
44
|
+
console.log('Power:', state === PowerState.ON ? 'ON' : 'OFF');
|
|
36
45
|
});
|
|
46
|
+
|
|
47
|
+
// Control power
|
|
48
|
+
await client.powerOn();
|
|
49
|
+
|
|
50
|
+
// Acquire and control a throttle
|
|
51
|
+
const throttleId = await client.acquireThrottle({ address: 3 });
|
|
52
|
+
await client.setThrottleSpeed(throttleId, 0.5); // 50% speed
|
|
53
|
+
await client.setThrottleDirection(throttleId, true); // Forward
|
|
54
|
+
await client.setThrottleFunction(throttleId, 'F0', true); // Headlight on
|
|
55
|
+
|
|
56
|
+
// Clean up
|
|
57
|
+
await client.releaseThrottle(throttleId);
|
|
58
|
+
await client.disconnect();
|
|
37
59
|
```
|
|
38
60
|
|
|
39
|
-
##
|
|
61
|
+
## Documentation
|
|
62
|
+
|
|
63
|
+
- **[API Reference](docs/API.md)** - Complete API documentation
|
|
64
|
+
- **[Examples](docs/EXAMPLES.md)** - Common usage patterns
|
|
65
|
+
- **[Mock Mode](docs/MOCK_MODE.md)** - Testing without hardware
|
|
66
|
+
- **[Migration Guide](docs/MIGRATION.md)** - Upgrading from v2.x
|
|
67
|
+
- **[Troubleshooting](docs/TROUBLESHOOTING.md)** - Common issues and solutions
|
|
68
|
+
|
|
69
|
+
## Key Concepts
|
|
40
70
|
|
|
41
|
-
###
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
71
|
+
### Event-Driven Architecture
|
|
72
|
+
|
|
73
|
+
Subscribe to real-time updates from JMRI:
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
client.on('connected', () => { });
|
|
77
|
+
client.on('disconnected', (reason) => { });
|
|
78
|
+
client.on('power:changed', (state) => { });
|
|
79
|
+
client.on('throttle:updated', (id, data) => { });
|
|
45
80
|
```
|
|
46
81
|
|
|
47
|
-
###
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
82
|
+
### Throttle Control
|
|
83
|
+
|
|
84
|
+
Full control of DCC locomotives:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
const throttle = await client.acquireThrottle({ address: 3 });
|
|
88
|
+
await client.setThrottleSpeed(throttle, 0.5);
|
|
89
|
+
await client.setThrottleDirection(throttle, true);
|
|
90
|
+
await client.setThrottleFunction(throttle, 'F0', true);
|
|
91
|
+
await client.releaseThrottle(throttle);
|
|
51
92
|
```
|
|
52
93
|
|
|
53
|
-
###
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
94
|
+
### Auto-Reconnection
|
|
95
|
+
|
|
96
|
+
Automatically reconnects with exponential backoff:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
client.on('reconnecting', (attempt, delay) => {
|
|
100
|
+
console.log(`Reconnecting attempt ${attempt} in ${delay}ms`);
|
|
101
|
+
});
|
|
58
102
|
```
|
|
59
103
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
104
|
+
## Testing
|
|
105
|
+
|
|
106
|
+
**Unit Tests** (no hardware required):
|
|
107
|
+
```bash
|
|
108
|
+
npm test
|
|
64
109
|
```
|
|
65
110
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
await client.getTurnouts();
|
|
111
|
+
**Mock Mode Demo** (no hardware required):
|
|
112
|
+
```bash
|
|
113
|
+
npm run demo:mock
|
|
70
114
|
```
|
|
71
115
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
await client.setTurnout(address, value);
|
|
116
|
+
**Functional Test** (requires JMRI hardware):
|
|
117
|
+
```bash
|
|
118
|
+
npm run functional
|
|
76
119
|
```
|
|
120
|
+
|
|
121
|
+
⚠️ **Safety**: Includes automatic power-off on exit, errors, and Ctrl+C.
|
|
122
|
+
|
|
123
|
+
See **[Mock Mode Guide](docs/MOCK_MODE.md)** and **[Testing Guide](docs/TESTING.md)** for complete instructions.
|
|
124
|
+
|
|
125
|
+
## Contributing
|
|
126
|
+
|
|
127
|
+
Issues and pull requests welcome! Please see the [GitHub repository](https://github.com/yamanote1138/jmri-client).
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
MIT
|
|
132
|
+
|
|
133
|
+
## Links
|
|
134
|
+
|
|
135
|
+
- [GitHub Repository](https://github.com/yamanote1138/jmri-client)
|
|
136
|
+
- [NPM Package](https://www.npmjs.com/package/jmri-client)
|
|
137
|
+
- [JMRI Project](http://jmri.sourceforge.net/)
|
|
138
|
+
- [JMRI JSON Protocol](https://www.jmri.org/help/en/html/web/JsonServlet.shtml)
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Main JMRI client class
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.JmriClient = void 0;
|
|
7
|
+
const events_1 = require("events");
|
|
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 client_options_js_1 = require("./types/client-options.js");
|
|
13
|
+
/**
|
|
14
|
+
* JMRI WebSocket Client
|
|
15
|
+
* Provides event-driven interface to JMRI with throttle control
|
|
16
|
+
*/
|
|
17
|
+
class JmriClient extends events_1.EventEmitter {
|
|
18
|
+
/**
|
|
19
|
+
* Create a new JMRI client
|
|
20
|
+
*
|
|
21
|
+
* @param options - Client configuration options
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const client = new JmriClient({
|
|
26
|
+
* host: 'jmri.local',
|
|
27
|
+
* port: 12080
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* client.on('connected', () => console.log('Connected!'));
|
|
31
|
+
* client.on('power:changed', (state) => console.log('Power:', state));
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
constructor(options) {
|
|
35
|
+
super();
|
|
36
|
+
// Merge options with defaults
|
|
37
|
+
this.options = (0, client_options_js_1.mergeOptions)(options);
|
|
38
|
+
// Create WebSocket client
|
|
39
|
+
this.wsClient = new websocket_client_js_1.WebSocketClient(this.options);
|
|
40
|
+
// Create managers
|
|
41
|
+
this.powerManager = new power_manager_js_1.PowerManager(this.wsClient);
|
|
42
|
+
this.rosterManager = new roster_manager_js_1.RosterManager(this.wsClient);
|
|
43
|
+
this.throttleManager = new throttle_manager_js_1.ThrottleManager(this.wsClient);
|
|
44
|
+
// Forward events from WebSocket client
|
|
45
|
+
this.wsClient.on('connected', () => this.emit('connected'));
|
|
46
|
+
this.wsClient.on('disconnected', (reason) => this.emit('disconnected', reason));
|
|
47
|
+
this.wsClient.on('reconnecting', (attempt, delay) => this.emit('reconnecting', attempt, delay));
|
|
48
|
+
this.wsClient.on('reconnected', () => this.emit('reconnected'));
|
|
49
|
+
this.wsClient.on('reconnectionFailed', (attempts) => this.emit('reconnectionFailed', attempts));
|
|
50
|
+
this.wsClient.on('connectionStateChanged', (state) => this.emit('connectionStateChanged', state));
|
|
51
|
+
this.wsClient.on('error', (error) => this.emit('error', error));
|
|
52
|
+
this.wsClient.on('heartbeat:sent', () => this.emit('heartbeat:sent'));
|
|
53
|
+
this.wsClient.on('heartbeat:timeout', () => this.emit('heartbeat:timeout'));
|
|
54
|
+
// Forward events from managers
|
|
55
|
+
this.powerManager.on('power:changed', (state) => this.emit('power:changed', state));
|
|
56
|
+
this.throttleManager.on('throttle:acquired', (id) => this.emit('throttle:acquired', id));
|
|
57
|
+
this.throttleManager.on('throttle:updated', (id, data) => this.emit('throttle:updated', id, data));
|
|
58
|
+
this.throttleManager.on('throttle:released', (id) => this.emit('throttle:released', id));
|
|
59
|
+
this.throttleManager.on('throttle:lost', (id) => this.emit('throttle:lost', id));
|
|
60
|
+
// Auto-connect if enabled
|
|
61
|
+
if (this.options.autoConnect) {
|
|
62
|
+
this.connect().catch((error) => {
|
|
63
|
+
this.emit('error', error);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Connect to JMRI server
|
|
69
|
+
*/
|
|
70
|
+
async connect() {
|
|
71
|
+
return this.wsClient.connect();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Disconnect from JMRI server
|
|
75
|
+
* Releases all throttles and closes connection
|
|
76
|
+
*/
|
|
77
|
+
async disconnect() {
|
|
78
|
+
// Release all throttles first
|
|
79
|
+
await this.throttleManager.releaseAllThrottles();
|
|
80
|
+
// Disconnect WebSocket
|
|
81
|
+
return this.wsClient.disconnect();
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get current connection state
|
|
85
|
+
*/
|
|
86
|
+
getConnectionState() {
|
|
87
|
+
return this.wsClient.getState();
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Check if connected to JMRI
|
|
91
|
+
*/
|
|
92
|
+
isConnected() {
|
|
93
|
+
return this.wsClient.isConnected();
|
|
94
|
+
}
|
|
95
|
+
// ============================================================================
|
|
96
|
+
// Power Control
|
|
97
|
+
// ============================================================================
|
|
98
|
+
/**
|
|
99
|
+
* Get current track power state
|
|
100
|
+
*/
|
|
101
|
+
async getPower() {
|
|
102
|
+
return this.powerManager.getPower();
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Set track power state
|
|
106
|
+
*/
|
|
107
|
+
async setPower(state) {
|
|
108
|
+
return this.powerManager.setPower(state);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Turn track power on
|
|
112
|
+
*/
|
|
113
|
+
async powerOn() {
|
|
114
|
+
return this.powerManager.powerOn();
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Turn track power off
|
|
118
|
+
*/
|
|
119
|
+
async powerOff() {
|
|
120
|
+
return this.powerManager.powerOff();
|
|
121
|
+
}
|
|
122
|
+
// ============================================================================
|
|
123
|
+
// Roster Management
|
|
124
|
+
// ============================================================================
|
|
125
|
+
/**
|
|
126
|
+
* Get all roster entries
|
|
127
|
+
*/
|
|
128
|
+
async getRoster() {
|
|
129
|
+
return this.rosterManager.getRoster();
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get roster entry by name
|
|
133
|
+
*/
|
|
134
|
+
async getRosterEntryByName(name) {
|
|
135
|
+
return this.rosterManager.getRosterEntryByName(name);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get roster entry by address
|
|
139
|
+
*/
|
|
140
|
+
async getRosterEntryByAddress(address) {
|
|
141
|
+
return this.rosterManager.getRosterEntryByAddress(address);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Search roster by partial name match
|
|
145
|
+
*/
|
|
146
|
+
async searchRoster(query) {
|
|
147
|
+
return this.rosterManager.searchRoster(query);
|
|
148
|
+
}
|
|
149
|
+
// ============================================================================
|
|
150
|
+
// Throttle Control
|
|
151
|
+
// ============================================================================
|
|
152
|
+
/**
|
|
153
|
+
* Acquire a throttle for a locomotive
|
|
154
|
+
*
|
|
155
|
+
* @param options - Throttle acquisition options
|
|
156
|
+
* @returns Throttle ID for use in other throttle methods
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* const throttleId = await client.acquireThrottle({ address: 3 });
|
|
161
|
+
* await client.setThrottleSpeed(throttleId, 0.5); // Half speed
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
async acquireThrottle(options) {
|
|
165
|
+
return this.throttleManager.acquireThrottle(options);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Release a throttle
|
|
169
|
+
*/
|
|
170
|
+
async releaseThrottle(throttleId) {
|
|
171
|
+
return this.throttleManager.releaseThrottle(throttleId);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Set throttle speed (0.0 to 1.0)
|
|
175
|
+
*
|
|
176
|
+
* @param throttleId - Throttle ID from acquireThrottle
|
|
177
|
+
* @param speed - Speed value between 0.0 (stopped) and 1.0 (full speed)
|
|
178
|
+
*/
|
|
179
|
+
async setThrottleSpeed(throttleId, speed) {
|
|
180
|
+
return this.throttleManager.setSpeed(throttleId, speed);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Set throttle direction
|
|
184
|
+
*
|
|
185
|
+
* @param throttleId - Throttle ID from acquireThrottle
|
|
186
|
+
* @param forward - True for forward, false for reverse
|
|
187
|
+
*/
|
|
188
|
+
async setThrottleDirection(throttleId, forward) {
|
|
189
|
+
return this.throttleManager.setDirection(throttleId, forward);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Set throttle function (F0-F28)
|
|
193
|
+
*
|
|
194
|
+
* @param throttleId - Throttle ID from acquireThrottle
|
|
195
|
+
* @param functionKey - Function key (F0-F28)
|
|
196
|
+
* @param value - True to activate, false to deactivate
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```typescript
|
|
200
|
+
* await client.setThrottleFunction(throttleId, 'F0', true); // Headlight on
|
|
201
|
+
* await client.setThrottleFunction(throttleId, 'F2', true); // Horn
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
async setThrottleFunction(throttleId, functionKey, value) {
|
|
205
|
+
return this.throttleManager.setFunction(throttleId, functionKey, value);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Emergency stop for a throttle (speed to 0)
|
|
209
|
+
*/
|
|
210
|
+
async emergencyStop(throttleId) {
|
|
211
|
+
return this.throttleManager.emergencyStop(throttleId);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Set throttle to idle (speed to 0, maintain direction)
|
|
215
|
+
*/
|
|
216
|
+
async idleThrottle(throttleId) {
|
|
217
|
+
return this.throttleManager.idle(throttleId);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get throttle state
|
|
221
|
+
*/
|
|
222
|
+
getThrottleState(throttleId) {
|
|
223
|
+
return this.throttleManager.getThrottleState(throttleId);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get all throttle IDs
|
|
227
|
+
*/
|
|
228
|
+
getThrottleIds() {
|
|
229
|
+
return this.throttleManager.getThrottleIds();
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Get all throttle states
|
|
233
|
+
*/
|
|
234
|
+
getAllThrottles() {
|
|
235
|
+
return this.throttleManager.getAllThrottles();
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Release all throttles
|
|
239
|
+
*/
|
|
240
|
+
async releaseAllThrottles() {
|
|
241
|
+
return this.throttleManager.releaseAllThrottles();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
exports.JmriClient = JmriClient;
|
|
245
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,mCAAsC;AACtC,oEAA6D;AAC7D,kEAA2D;AAC3D,oEAA6D;AAC7D,wEAAiE;AACjE,iEAAkG;AAKlG;;;GAGG;AACH,MAAa,UAAW,SAAQ,qBAAY;IAO1C;;;;;;;;;;;;;;;OAeG;IACH,YAAY,OAA8B;QACxC,KAAK,EAAE,CAAC;QAER,8BAA8B;QAC9B,IAAI,CAAC,OAAO,GAAG,IAAA,gCAAY,EAAC,OAAO,CAAC,CAAC;QAErC,0BAA0B;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,qCAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAElD,kBAAkB;QAClB,IAAI,CAAC,YAAY,GAAG,IAAI,+BAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,aAAa,GAAG,IAAI,iCAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtD,IAAI,CAAC,eAAe,GAAG,IAAI,qCAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAE1D,uCAAuC;QACvC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;QACxF,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,OAAe,EAAE,KAAa,EAAE,EAAE,CAClE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,EAAE,KAAK,CAAC,CAC1C,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QAChE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,QAAgB,EAAE,EAAE,CAC1D,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAC1C,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,wBAAwB,EAAE,CAAC,KAAsB,EAAE,EAAE,CACpE,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAC3C,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QACtE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAE5E,+BAA+B;QAC/B,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,KAAiB,EAAE,EAAE,CAC1D,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAClC,CAAC;QACF,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAU,EAAE,EAAE,CAC1D,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAC,CACnC,CAAC;QACF,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,EAAU,EAAE,IAAS,EAAE,EAAE,CACpE,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,EAAE,IAAI,CAAC,CACxC,CAAC;QACF,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAU,EAAE,EAAE,CAC1D,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAC,CACnC,CAAC;QACF,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,EAAU,EAAE,EAAE,CACtD,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC,CAC/B,CAAC;QAEF,0BAA0B;QAC1B,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC7B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC5B,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU;QACd,8BAA8B;QAC9B,MAAM,IAAI,CAAC,eAAe,CAAC,mBAAmB,EAAE,CAAC;QAEjD,uBAAuB;QACvB,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,CAAC;IAED,+EAA+E;IAC/E,gBAAgB;IAChB,+EAA+E;IAE/E;;OAEG;IACH,KAAK,CAAC,QAAQ;QACZ,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,KAAiB;QAC9B,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACZ,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;IACtC,CAAC;IAED,+EAA+E;IAC/E,oBAAoB;IACpB,+EAA+E;IAE/E;;OAEG;IACH,KAAK,CAAC,SAAS;QACb,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,oBAAoB,CAAC,IAAY;QACrC,OAAO,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,uBAAuB,CAAC,OAAwB;QACpD,OAAO,IAAI,CAAC,aAAa,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,KAAa;QAC9B,OAAO,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IAED,+EAA+E;IAC/E,mBAAmB;IACnB,+EAA+E;IAE/E;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,eAAe,CAAC,OAA+B;QACnD,OAAO,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,UAAkB;QACtC,OAAO,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,gBAAgB,CAAC,UAAkB,EAAE,KAAa;QACtD,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,oBAAoB,CAAC,UAAkB,EAAE,OAAgB;QAC7D,OAAO,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAChE,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,mBAAmB,CACvB,UAAkB,EAClB,WAAgC,EAChC,KAAc;QAEd,OAAO,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,UAAU,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;IAC1E,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,UAAkB;QACpC,OAAO,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,UAAkB;QACnC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,UAAkB;QACjC,OAAO,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,eAAe,CAAC,eAAe,EAAE,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,mBAAmB;QACvB,OAAO,IAAI,CAAC,eAAe,CAAC,mBAAmB,EAAE,CAAC;IACpD,CAAC;CACF;AA7RD,gCA6RC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
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 events_1 = require("events");
|
|
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.CONNECTED, events_js_1.ConnectionState.DISCONNECTED]
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Manages connection state with validation
|
|
20
|
+
*/
|
|
21
|
+
class ConnectionStateManager extends events_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;
|
|
85
|
+
//# sourceMappingURL=connection-state-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-state-manager.js","sourceRoot":"","sources":["../../../src/core/connection-state-manager.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,mCAAsC;AACtC,kDAAqD;AAErD;;GAEG;AACH,MAAM,iBAAiB,GAA+C;IACpE,CAAC,2BAAe,CAAC,YAAY,CAAC,EAAE,CAAC,2BAAe,CAAC,UAAU,CAAC;IAC5D,CAAC,2BAAe,CAAC,UAAU,CAAC,EAAE,CAAC,2BAAe,CAAC,SAAS,EAAE,2BAAe,CAAC,YAAY,CAAC;IACvF,CAAC,2BAAe,CAAC,SAAS,CAAC,EAAE,CAAC,2BAAe,CAAC,YAAY,EAAE,2BAAe,CAAC,YAAY,CAAC;IACzF,CAAC,2BAAe,CAAC,YAAY,CAAC,EAAE,CAAC,2BAAe,CAAC,SAAS,EAAE,2BAAe,CAAC,YAAY,CAAC;CAC1F,CAAC;AAEF;;GAEG;AACH,MAAa,sBAAuB,SAAQ,qBAAY;IAAxD;;QACU,iBAAY,GAAoB,2BAAe,CAAC,YAAY,CAAC;IAuEvE,CAAC;IArEC;;OAEG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,IAAI,CAAC,YAAY,KAAK,2BAAe,CAAC,SAAS,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,YAAY,KAAK,2BAAe,CAAC,UAAU,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,YAAY,KAAK,2BAAe,CAAC,YAAY,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,YAAY,KAAK,2BAAe,CAAC,YAAY,CAAC;IAC5D,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,QAAyB;QAClC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE9D,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CACb,6BAA6B,IAAI,CAAC,YAAY,OAAO,QAAQ,EAAE,CAChE,CAAC;QACJ,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;QAE7B,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,QAAyB;QAClC,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,UAAU,CAAC,2BAAe,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC;CACF;AAxED,wDAwEC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Heartbeat (ping/pong) management
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.HeartbeatManager = void 0;
|
|
7
|
+
const events_1 = require("events");
|
|
8
|
+
/**
|
|
9
|
+
* Manages WebSocket heartbeat via ping/pong
|
|
10
|
+
*/
|
|
11
|
+
class HeartbeatManager extends events_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;
|
|
80
|
+
//# sourceMappingURL=heartbeat-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat-manager.js","sourceRoot":"","sources":["../../../src/core/heartbeat-manager.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,mCAAsC;AAGtC;;GAEG;AACH,MAAa,gBAAiB,SAAQ,qBAAY;IAMhD,YAAY,OAAyB;QACnC,KAAK,EAAE,CAAC;QAHF,cAAS,GAAY,KAAK,CAAC;QAIjC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,QAAoB;QACxB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC5C,OAAO;QACT,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,iCAAiC;QACjC,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE;YACnC,QAAQ,EAAE,CAAC;YACX,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAEtB,qBAAqB;YACrB,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,GAAG,EAAE;gBACjC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QAEvB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACjC,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAChC,CAAC;QAED,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC/B,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC/B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,YAAY;QACV,qBAAqB;QACrB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC/B,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,OAAkC;QAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;QAElC,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;QAE/C,iDAAiD;IACnD,CAAC;CACF;AApFD,4CAoFC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
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("./connection-state-manager.js"), exports);
|
|
22
|
+
__exportStar(require("./reconnection-manager.js"), exports);
|
|
23
|
+
__exportStar(require("./heartbeat-manager.js"), exports);
|
|
24
|
+
__exportStar(require("./message-queue.js"), exports);
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,wDAAsC;AACtC,gEAA8C;AAC9C,4DAA0C;AAC1C,yDAAuC;AACvC,qDAAmC"}
|