@ya-modbus/mqtt-bridge 0.4.1-refactor-scope-driver-packages.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 (65) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE +674 -0
  3. package/README.md +190 -0
  4. package/dist/bin/ya-modbus-bridge.d.ts +9 -0
  5. package/dist/bin/ya-modbus-bridge.d.ts.map +1 -0
  6. package/dist/bin/ya-modbus-bridge.js +10 -0
  7. package/dist/bin/ya-modbus-bridge.js.map +1 -0
  8. package/dist/src/cli.d.ts +4 -0
  9. package/dist/src/cli.d.ts.map +1 -0
  10. package/dist/src/cli.js +109 -0
  11. package/dist/src/cli.js.map +1 -0
  12. package/dist/src/device-manager.d.ts +17 -0
  13. package/dist/src/device-manager.d.ts.map +1 -0
  14. package/dist/src/device-manager.js +79 -0
  15. package/dist/src/device-manager.js.map +1 -0
  16. package/dist/src/driver-loader.d.ts +53 -0
  17. package/dist/src/driver-loader.d.ts.map +1 -0
  18. package/dist/src/driver-loader.js +120 -0
  19. package/dist/src/driver-loader.js.map +1 -0
  20. package/dist/src/index.d.ts +13 -0
  21. package/dist/src/index.d.ts.map +1 -0
  22. package/dist/src/index.js +285 -0
  23. package/dist/src/index.js.map +1 -0
  24. package/dist/src/polling-scheduler.d.ts +48 -0
  25. package/dist/src/polling-scheduler.d.ts.map +1 -0
  26. package/dist/src/polling-scheduler.js +128 -0
  27. package/dist/src/polling-scheduler.js.map +1 -0
  28. package/dist/src/types.d.ts +86 -0
  29. package/dist/src/types.d.ts.map +1 -0
  30. package/dist/src/types.js +2 -0
  31. package/dist/src/types.js.map +1 -0
  32. package/dist/src/utils/__mocks__/package-info.d.ts +9 -0
  33. package/dist/src/utils/__mocks__/package-info.d.ts.map +1 -0
  34. package/dist/src/utils/__mocks__/package-info.js +11 -0
  35. package/dist/src/utils/__mocks__/package-info.js.map +1 -0
  36. package/dist/src/utils/__mocks__/process.d.ts +20 -0
  37. package/dist/src/utils/__mocks__/process.d.ts.map +1 -0
  38. package/dist/src/utils/__mocks__/process.js +37 -0
  39. package/dist/src/utils/__mocks__/process.js.map +1 -0
  40. package/dist/src/utils/config-validator.d.ts +3 -0
  41. package/dist/src/utils/config-validator.d.ts.map +1 -0
  42. package/dist/src/utils/config-validator.js +32 -0
  43. package/dist/src/utils/config-validator.js.map +1 -0
  44. package/dist/src/utils/config.d.ts +3 -0
  45. package/dist/src/utils/config.d.ts.map +1 -0
  46. package/dist/src/utils/config.js +52 -0
  47. package/dist/src/utils/config.js.map +1 -0
  48. package/dist/src/utils/device-validation.d.ts +31 -0
  49. package/dist/src/utils/device-validation.d.ts.map +1 -0
  50. package/dist/src/utils/device-validation.js +70 -0
  51. package/dist/src/utils/device-validation.js.map +1 -0
  52. package/dist/src/utils/package-info.d.ts +5 -0
  53. package/dist/src/utils/package-info.d.ts.map +1 -0
  54. package/dist/src/utils/package-info.js +11 -0
  55. package/dist/src/utils/package-info.js.map +1 -0
  56. package/dist/src/utils/process.d.ts +10 -0
  57. package/dist/src/utils/process.d.ts.map +1 -0
  58. package/dist/src/utils/process.js +13 -0
  59. package/dist/src/utils/process.js.map +1 -0
  60. package/dist/src/utils/test-utils.d.ts +313 -0
  61. package/dist/src/utils/test-utils.d.ts.map +1 -0
  62. package/dist/src/utils/test-utils.js +535 -0
  63. package/dist/src/utils/test-utils.js.map +1 -0
  64. package/dist/tsconfig.tsbuildinfo +1 -0
  65. package/package.json +63 -0
package/README.md ADDED
@@ -0,0 +1,190 @@
1
+ # @ya-modbus/mqtt-bridge
2
+
3
+ MQTT bridge for ya-modbus - orchestrates device management, polling, and MQTT publishing.
4
+
5
+ ## Overview
6
+
7
+ The MQTT bridge provides the foundational layer for connecting Modbus devices to MQTT:
8
+
9
+ ### Current Features (Phase 1)
10
+
11
+ - **MQTT Connection Management** - Connect to MQTT brokers with authentication
12
+ - **Topic Publish/Subscribe** - Publish and subscribe to MQTT topics with QoS support
13
+ - **Device Registry** - Add, remove, and track devices
14
+ - **Graceful Lifecycle** - Start, stop, and status reporting
15
+
16
+ ### Future Features
17
+
18
+ - Driver integration and polling coordination (Phase 2)
19
+ - State persistence and MQTT configuration topics (Phase 3)
20
+
21
+ See [Architecture documentation](./docs/ARCHITECTURE.md) for complete details and roadmap.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ npm install @ya-modbus/mqtt-bridge
27
+ ```
28
+
29
+ ## CLI Reference
30
+
31
+ The `ya-modbus-bridge` command-line tool provides the following commands:
32
+
33
+ ### Commands
34
+
35
+ - `run` - Run the MQTT bridge with a configuration file
36
+
37
+ ### Options
38
+
39
+ **Configuration:**
40
+
41
+ - `-c, --config <path>` - Path to configuration file (optional if using CLI options)
42
+ - `--mqtt-url <url>` - MQTT broker URL (mqtt://, mqtts://, ws://, wss://)
43
+ - `--mqtt-client-id <id>` - MQTT client identifier
44
+ - `--mqtt-username <username>` - MQTT authentication username
45
+ - `--mqtt-password <password>` - MQTT authentication password
46
+ - `--mqtt-reconnect-period <ms>` - Reconnection interval in milliseconds
47
+ - `--topic-prefix <prefix>` - Topic prefix for all MQTT topics (default: modbus)
48
+ - `--state-dir <path>` - Directory path for state persistence
49
+
50
+ **General:**
51
+
52
+ - `-h, --help` - Display help for command
53
+ - `-V, --version` - Output version number
54
+
55
+ ### Examples
56
+
57
+ ```bash
58
+ # Run with config file
59
+ ya-modbus-bridge run --config /path/to/config.json
60
+
61
+ # Run with CLI options only
62
+ ya-modbus-bridge run --mqtt-url mqtt://localhost:1883
63
+
64
+ # Run with config file and override options
65
+ ya-modbus-bridge run --config config.json --mqtt-url mqtt://broker.example.com:1883
66
+
67
+ # Run with authentication
68
+ ya-modbus-bridge run --mqtt-url mqtt://broker.example.com:1883 \
69
+ --mqtt-username user --mqtt-password pass
70
+
71
+ # Show help
72
+ ya-modbus-bridge --help
73
+ ya-modbus-bridge run --help
74
+
75
+ # Show version
76
+ ya-modbus-bridge --version
77
+ ```
78
+
79
+ ## CLI Usage
80
+
81
+ Run the MQTT bridge using the command-line interface:
82
+
83
+ ```bash
84
+ # Run with configuration file
85
+ ya-modbus-bridge run --config config.json
86
+
87
+ # Show help
88
+ ya-modbus-bridge --help
89
+
90
+ # Show version
91
+ ya-modbus-bridge --version
92
+ ```
93
+
94
+ ### Configuration File
95
+
96
+ Create a `config.json` file:
97
+
98
+ ```json
99
+ {
100
+ "mqtt": {
101
+ "url": "mqtt://localhost:1883",
102
+ "clientId": "modbus-bridge",
103
+ "username": "user",
104
+ "password": "pass"
105
+ },
106
+ "topicPrefix": "modbus"
107
+ }
108
+ ```
109
+
110
+ **Configuration options:**
111
+
112
+ - `mqtt.url` (required) - MQTT broker URL (mqtt://, mqtts://, ws://, wss://)
113
+ - `mqtt.clientId` (optional) - MQTT client identifier
114
+ - `mqtt.username` (optional) - Authentication username
115
+ - `mqtt.password` (optional) - Authentication password
116
+ - `mqtt.reconnectPeriod` (optional) - Reconnection interval in milliseconds (default: 5000)
117
+ - `topicPrefix` (optional) - Topic prefix for all MQTT topics (default: 'modbus')
118
+ - `stateDir` (optional) - Directory path for state persistence (future)
119
+
120
+ ## Programmatic Usage
121
+
122
+ ```typescript
123
+ import { createBridge } from '@ya-modbus/mqtt-bridge'
124
+
125
+ const bridge = createBridge({
126
+ mqtt: {
127
+ url: 'mqtt://localhost:1883',
128
+ clientId: 'modbus-bridge',
129
+ },
130
+ topicPrefix: 'modbus',
131
+ })
132
+
133
+ await bridge.start()
134
+
135
+ // Publish to topic
136
+ await bridge.publish('device1/data', JSON.stringify({ temp: 25.5 }))
137
+
138
+ // Subscribe to topic
139
+ await bridge.subscribe('device1/cmd', (message) => {
140
+ console.log('Received:', message.payload.toString())
141
+ })
142
+
143
+ // Add device
144
+ await bridge.addDevice({
145
+ deviceId: 'device1',
146
+ driver: 'ya-modbus-driver-example',
147
+ connection: {
148
+ type: 'tcp',
149
+ host: '192.168.1.100',
150
+ port: 502,
151
+ slaveId: 1,
152
+ },
153
+ })
154
+
155
+ // List devices
156
+ const devices = bridge.listDevices()
157
+
158
+ // Stop bridge
159
+ await bridge.stop()
160
+ ```
161
+
162
+ ## Architecture
163
+
164
+ See [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md) for complete bridge architecture including:
165
+
166
+ - Component structure
167
+ - MQTT topic structure
168
+ - State management
169
+ - Lifecycle and event handling
170
+ - Data flow and validation
171
+
172
+ ## Development
173
+
174
+ ```bash
175
+ # Build
176
+ npm run build
177
+
178
+ # Test
179
+ npm test
180
+
181
+ # Lint
182
+ npm run lint
183
+
184
+ # Clean
185
+ npm run clean
186
+ ```
187
+
188
+ ## License
189
+
190
+ GPL-3.0-or-later
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point
4
+ *
5
+ * This file is the executable entry point that parses command-line arguments.
6
+ * The actual CLI implementation is in src/cli.ts
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=ya-modbus-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ya-modbus-bridge.d.ts","sourceRoot":"","sources":["../../bin/ya-modbus-bridge.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point
4
+ *
5
+ * This file is the executable entry point that parses command-line arguments.
6
+ * The actual CLI implementation is in src/cli.ts
7
+ */
8
+ import { program } from '../src/cli.js';
9
+ program.parse();
10
+ //# sourceMappingURL=ya-modbus-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ya-modbus-bridge.js","sourceRoot":"","sources":["../../bin/ya-modbus-bridge.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,OAAO,CAAC,KAAK,EAAE,CAAA"}
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ export declare const program: Command;
4
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAUnC,eAAO,MAAM,OAAO,SAAgB,CAAA"}
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+ import chalk from 'chalk';
3
+ import { Command } from 'commander';
4
+ import { validateConfig } from './utils/config-validator.js';
5
+ import { loadConfig } from './utils/config.js';
6
+ import { getPackageInfo } from './utils/package-info.js';
7
+ import { processUtils } from './utils/process.js';
8
+ import { createBridge } from './index.js';
9
+ export const program = new Command();
10
+ const packageInfo = getPackageInfo();
11
+ program.name('ya-modbus-bridge').description(packageInfo.description).version(packageInfo.version);
12
+ // Error handler for command execution
13
+ program.exitOverride(); // Prevent automatic exit, let us handle errors
14
+ program.configureOutput({
15
+ /* istanbul ignore next - commander internal error output */
16
+ writeErr: (str) => process.stderr.write(str),
17
+ });
18
+ program
19
+ .command('run')
20
+ .description('Run the MQTT bridge')
21
+ .option('-c, --config <path>', 'Path to configuration file')
22
+ .option('--mqtt-url <url>', 'MQTT broker URL (mqtt://, mqtts://, ws://, wss://)')
23
+ .option('--mqtt-client-id <id>', 'MQTT client identifier')
24
+ .option('--mqtt-username <username>', 'MQTT authentication username')
25
+ .option('--mqtt-password <password>', 'MQTT authentication password')
26
+ .option('--mqtt-reconnect-period <ms>', 'Reconnection interval in milliseconds', parseInt)
27
+ .option('--topic-prefix <prefix>', 'Topic prefix for all MQTT topics (default: modbus)')
28
+ .option('--state-dir <path>', 'Directory path for state persistence')
29
+ .action(async (options) => {
30
+ try {
31
+ await runCommand(options);
32
+ }
33
+ catch (error) {
34
+ console.error(chalk.red('Error:'), error instanceof Error ? error.message : String(error));
35
+ processUtils.exit(1);
36
+ }
37
+ });
38
+ async function runCommand(options) {
39
+ console.log(chalk.blue('Loading configuration...'));
40
+ let config;
41
+ if (options.config) {
42
+ // Load from file
43
+ config = await loadConfig(options.config);
44
+ // Override with CLI options if provided
45
+ if (options.mqttUrl)
46
+ config.mqtt.url = options.mqttUrl;
47
+ if (options.mqttClientId)
48
+ config.mqtt.clientId = options.mqttClientId;
49
+ if (options.mqttUsername)
50
+ config.mqtt.username = options.mqttUsername;
51
+ if (options.mqttPassword)
52
+ config.mqtt.password = options.mqttPassword;
53
+ if (options.mqttReconnectPeriod)
54
+ config.mqtt.reconnectPeriod = options.mqttReconnectPeriod;
55
+ if (options.topicPrefix)
56
+ config.topicPrefix = options.topicPrefix;
57
+ if (options.stateDir)
58
+ config.stateDir = options.stateDir;
59
+ }
60
+ else {
61
+ // Build from CLI options only
62
+ if (!options.mqttUrl) {
63
+ throw new Error('Either --config or --mqtt-url must be provided');
64
+ }
65
+ config = {
66
+ mqtt: {
67
+ url: options.mqttUrl,
68
+ ...(options.mqttClientId && { clientId: options.mqttClientId }),
69
+ ...(options.mqttUsername && { username: options.mqttUsername }),
70
+ ...(options.mqttPassword && { password: options.mqttPassword }),
71
+ ...(options.mqttReconnectPeriod && { reconnectPeriod: options.mqttReconnectPeriod }),
72
+ },
73
+ ...(options.topicPrefix && { topicPrefix: options.topicPrefix }),
74
+ ...(options.stateDir && { stateDir: options.stateDir }),
75
+ };
76
+ }
77
+ // Validate configuration after merging CLI options
78
+ validateConfig(config);
79
+ // Sanitize URL to hide credentials
80
+ const sanitizedUrl = config.mqtt.url.replace(/:\/\/([^:]+):([^@]+)@/, '://$1:****@');
81
+ console.log(chalk.blue(`Starting MQTT bridge - connecting to ${sanitizedUrl}...`));
82
+ const bridge = createBridge(config);
83
+ await bridge.start();
84
+ console.log(chalk.green('Bridge started successfully'));
85
+ let isShuttingDown = false;
86
+ const handleShutdown = async (signal) => {
87
+ if (isShuttingDown) {
88
+ return;
89
+ }
90
+ isShuttingDown = true;
91
+ console.log(chalk.yellow(`\nReceived ${signal}, shutting down...`));
92
+ await bridge.stop();
93
+ console.log(chalk.green('Bridge stopped'));
94
+ processUtils.exit(0);
95
+ };
96
+ processUtils.onSignal('SIGINT', () => {
97
+ handleShutdown('SIGINT').catch((err) => {
98
+ console.error(chalk.red('Shutdown error:'), err);
99
+ processUtils.exit(1);
100
+ });
101
+ });
102
+ processUtils.onSignal('SIGTERM', () => {
103
+ handleShutdown('SIGTERM').catch((err) => {
104
+ console.error(chalk.red('Shutdown error:'), err);
105
+ processUtils.exit(1);
106
+ });
107
+ });
108
+ }
109
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { DriverLoader } from './driver-loader.js';
2
+ import type { DeviceConfig, DeviceStatus } from './types.js';
3
+ export declare class DeviceManager {
4
+ private driverLoader;
5
+ private devices;
6
+ private configs;
7
+ constructor(driverLoader: DriverLoader);
8
+ addDevice(config: DeviceConfig): Promise<void>;
9
+ removeDevice(deviceId: string): Promise<void>;
10
+ getDevice(deviceId: string): DeviceStatus | undefined;
11
+ listDevices(): DeviceStatus[];
12
+ getDeviceCount(): number;
13
+ updateDeviceState(deviceId: string, updates: Partial<Omit<DeviceStatus, 'deviceId'>>): void;
14
+ clear(): Promise<void>;
15
+ getDeviceConfig(deviceId: string): DeviceConfig | undefined;
16
+ }
17
+ //# sourceMappingURL=device-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-manager.d.ts","sourceRoot":"","sources":["../../src/device-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAG5D,qBAAa,aAAa;IAIZ,OAAO,CAAC,YAAY;IAHhC,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,OAAO,CAAkC;gBAE7B,YAAY,EAAE,YAAY;IAExC,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC9C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnD,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAIrD,WAAW,IAAI,YAAY,EAAE;IAI7B,cAAc,IAAI,MAAM;IAIxB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,GAAG,IAAI;IAYrF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;CAG5D"}
@@ -0,0 +1,79 @@
1
+ import { validateDeviceConfig } from './utils/device-validation.js';
2
+ export class DeviceManager {
3
+ driverLoader;
4
+ devices = new Map();
5
+ configs = new Map();
6
+ constructor(driverLoader) {
7
+ this.driverLoader = driverLoader;
8
+ }
9
+ async addDevice(config) {
10
+ validateDeviceConfig(config);
11
+ if (this.devices.has(config.deviceId)) {
12
+ throw new Error(`Device ${config.deviceId} already exists`);
13
+ }
14
+ const enabled = config.enabled ?? true;
15
+ const status = {
16
+ deviceId: config.deviceId,
17
+ state: 'disconnected',
18
+ enabled,
19
+ connected: false,
20
+ };
21
+ this.devices.set(config.deviceId, status);
22
+ this.configs.set(config.deviceId, config);
23
+ // Load driver if enabled
24
+ if (enabled) {
25
+ try {
26
+ this.updateDeviceState(config.deviceId, { state: 'connecting' });
27
+ await this.driverLoader.loadDriver(config.driver, config.connection, config.deviceId);
28
+ this.updateDeviceState(config.deviceId, {
29
+ state: 'connected',
30
+ connected: true,
31
+ lastUpdate: Date.now(),
32
+ });
33
+ }
34
+ catch (error) {
35
+ // Clean up device state to allow retry (make operation atomic)
36
+ this.devices.delete(config.deviceId);
37
+ this.configs.delete(config.deviceId);
38
+ throw error;
39
+ }
40
+ }
41
+ }
42
+ async removeDevice(deviceId) {
43
+ if (!this.devices.has(deviceId)) {
44
+ throw new Error(`Device ${deviceId} not found`);
45
+ }
46
+ await this.driverLoader.unloadDriver(deviceId);
47
+ this.devices.delete(deviceId);
48
+ this.configs.delete(deviceId);
49
+ }
50
+ getDevice(deviceId) {
51
+ return this.devices.get(deviceId);
52
+ }
53
+ listDevices() {
54
+ return Array.from(this.devices.values());
55
+ }
56
+ getDeviceCount() {
57
+ return this.devices.size;
58
+ }
59
+ updateDeviceState(deviceId, updates) {
60
+ const device = this.devices.get(deviceId);
61
+ if (!device) {
62
+ throw new Error(`Device ${deviceId} not found`);
63
+ }
64
+ this.devices.set(deviceId, {
65
+ ...device,
66
+ ...updates,
67
+ });
68
+ }
69
+ async clear() {
70
+ const deviceIds = Array.from(this.devices.keys());
71
+ await Promise.all(deviceIds.map((id) => this.driverLoader.unloadDriver(id)));
72
+ this.devices.clear();
73
+ this.configs.clear();
74
+ }
75
+ getDeviceConfig(deviceId) {
76
+ return this.configs.get(deviceId);
77
+ }
78
+ }
79
+ //# sourceMappingURL=device-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-manager.js","sourceRoot":"","sources":["../../src/device-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { loadDriver as loadDriverPackage } from '@ya-modbus/driver-loader';
2
+ import type { DeviceDriver } from '@ya-modbus/driver-types';
3
+ import { TransportManager } from '@ya-modbus/transport';
4
+ import type { DeviceConnection } from './types.js';
5
+ type LoadDriverFunction = typeof loadDriverPackage;
6
+ /**
7
+ * Manages dynamic loading and lifecycle of device drivers
8
+ * Uses TransportManager to pool RTU transports and prevent bus collisions
9
+ */
10
+ export declare class DriverLoader {
11
+ private readonly driverInstances;
12
+ private readonly devicePackages;
13
+ private readonly loadDriverFn;
14
+ private readonly transportManager;
15
+ constructor(loadDriverFn?: LoadDriverFunction, transportManager?: TransportManager);
16
+ /**
17
+ * Load a driver package and create an instance for a device
18
+ *
19
+ * @param packageName - NPM package name (e.g., '@ya-modbus/driver-xymd1' or 'ya-modbus-driver-test')
20
+ * @param connection - Device connection configuration
21
+ * @param deviceId - Unique device identifier for tracking the instance
22
+ * @returns Driver instance
23
+ */
24
+ loadDriver(packageName: string, connection: DeviceConnection, deviceId?: string): Promise<DeviceDriver>;
25
+ /**
26
+ * Unload a driver instance and clean up resources
27
+ * Note: Transport is managed by TransportManager and not closed here
28
+ *
29
+ * @param deviceId - Device identifier
30
+ */
31
+ unloadDriver(deviceId: string): Promise<void>;
32
+ /**
33
+ * Get a loaded driver instance
34
+ *
35
+ * @param deviceId - Device identifier
36
+ * @returns Driver instance or undefined if not loaded
37
+ */
38
+ getDriver(deviceId: string): DeviceDriver | undefined;
39
+ /**
40
+ * Close all managed transports
41
+ * Should be called when shutting down the bridge
42
+ */
43
+ closeAllTransports(): Promise<void>;
44
+ /**
45
+ * Convert DeviceConnection to TransportConfig
46
+ *
47
+ * @param connection - Device connection configuration
48
+ * @returns Transport configuration
49
+ */
50
+ private connectionToTransportConfig;
51
+ }
52
+ export {};
53
+ //# sourceMappingURL=driver-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver-loader.d.ts","sourceRoot":"","sources":["../../src/driver-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,gBAAgB,EAAwB,MAAM,sBAAsB,CAAA;AAE7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,KAAK,kBAAkB,GAAG,OAAO,iBAAiB,CAAA;AAElD;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkC;IAClE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA4B;IAC3D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IACjD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;gBAEvC,YAAY,CAAC,EAAE,kBAAkB,EAAE,gBAAgB,CAAC,EAAE,gBAAgB;IAKlF;;;;;;;OAOG;IACG,UAAU,CACd,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,gBAAgB,EAC5B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC;IA2CxB;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBnD;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAIrD;;;OAGG;IACG,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzC;;;;;OAKG;IACH,OAAO,CAAC,2BAA2B;CAkBpC"}
@@ -0,0 +1,120 @@
1
+ import { loadDriver as loadDriverPackage } from '@ya-modbus/driver-loader';
2
+ import { TransportManager } from '@ya-modbus/transport';
3
+ /**
4
+ * Manages dynamic loading and lifecycle of device drivers
5
+ * Uses TransportManager to pool RTU transports and prevent bus collisions
6
+ */
7
+ export class DriverLoader {
8
+ driverInstances = new Map();
9
+ devicePackages = new Map();
10
+ loadDriverFn;
11
+ transportManager;
12
+ constructor(loadDriverFn, transportManager) {
13
+ this.loadDriverFn = loadDriverFn ?? loadDriverPackage;
14
+ this.transportManager = transportManager ?? new TransportManager();
15
+ }
16
+ /**
17
+ * Load a driver package and create an instance for a device
18
+ *
19
+ * @param packageName - NPM package name (e.g., '@ya-modbus/driver-xymd1' or 'ya-modbus-driver-test')
20
+ * @param connection - Device connection configuration
21
+ * @param deviceId - Unique device identifier for tracking the instance
22
+ * @returns Driver instance
23
+ */
24
+ async loadDriver(packageName, connection, deviceId) {
25
+ // Security validation: prevent path traversal and code injection
26
+ // Accept both scoped (@ya-modbus/driver-*) and unscoped (ya-modbus-driver-*) packages
27
+ const isValidScopedDriver = packageName.startsWith('@ya-modbus/driver-');
28
+ const isValidUnscopedDriver = packageName.startsWith('ya-modbus-driver-');
29
+ if (!isValidScopedDriver && !isValidUnscopedDriver) {
30
+ throw new Error(`Invalid driver package name: must be @ya-modbus/driver-<name> or ya-modbus-driver-<name>`);
31
+ }
32
+ if (packageName.includes('..') || packageName.includes('\\')) {
33
+ throw new Error('Invalid driver package name: path traversal not allowed');
34
+ }
35
+ // Load driver package using driver-loader
36
+ const loadedDriver = await this.loadDriverFn({ driverPackage: packageName });
37
+ // Get transport from manager (shared for RTU, unique for TCP)
38
+ const config = this.connectionToTransportConfig(connection);
39
+ const transport = await this.transportManager.getTransport(config);
40
+ // Create driver instance
41
+ const driver = await loadedDriver.createDriver({
42
+ transport,
43
+ slaveId: connection.slaveId,
44
+ });
45
+ // Call initialize if available
46
+ if (driver.initialize) {
47
+ await driver.initialize();
48
+ }
49
+ // Cache instance if deviceId provided
50
+ if (deviceId) {
51
+ this.driverInstances.set(deviceId, driver);
52
+ this.devicePackages.set(deviceId, packageName);
53
+ }
54
+ // Note: Don't close transport on failure - it may be shared by other devices
55
+ // The transport manager will handle cleanup when closeAll() is called
56
+ return driver;
57
+ }
58
+ /**
59
+ * Unload a driver instance and clean up resources
60
+ * Note: Transport is managed by TransportManager and not closed here
61
+ *
62
+ * @param deviceId - Device identifier
63
+ */
64
+ async unloadDriver(deviceId) {
65
+ const driver = this.driverInstances.get(deviceId);
66
+ try {
67
+ if (driver?.destroy) {
68
+ await driver.destroy();
69
+ }
70
+ }
71
+ finally {
72
+ // Always remove from cache, even if destroy fails
73
+ this.driverInstances.delete(deviceId);
74
+ this.devicePackages.delete(deviceId);
75
+ }
76
+ // Note: Transport is managed by TransportManager and shared across devices
77
+ // It will be closed when the entire bridge shuts down via closeAll()
78
+ }
79
+ /**
80
+ * Get a loaded driver instance
81
+ *
82
+ * @param deviceId - Device identifier
83
+ * @returns Driver instance or undefined if not loaded
84
+ */
85
+ getDriver(deviceId) {
86
+ return this.driverInstances.get(deviceId);
87
+ }
88
+ /**
89
+ * Close all managed transports
90
+ * Should be called when shutting down the bridge
91
+ */
92
+ async closeAllTransports() {
93
+ await this.transportManager.closeAll();
94
+ }
95
+ /**
96
+ * Convert DeviceConnection to TransportConfig
97
+ *
98
+ * @param connection - Device connection configuration
99
+ * @returns Transport configuration
100
+ */
101
+ connectionToTransportConfig(connection) {
102
+ return connection.type === 'rtu'
103
+ ? {
104
+ port: connection.port,
105
+ baudRate: connection.baudRate,
106
+ dataBits: connection.dataBits,
107
+ parity: connection.parity,
108
+ stopBits: connection.stopBits,
109
+ slaveId: connection.slaveId,
110
+ timeout: connection.timeout,
111
+ }
112
+ : {
113
+ host: connection.host,
114
+ port: connection.port,
115
+ slaveId: connection.slaveId,
116
+ timeout: connection.timeout,
117
+ };
118
+ }
119
+ }
120
+ //# sourceMappingURL=driver-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver-loader.js","sourceRoot":"","sources":["../../src/driver-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { DeviceManager } from './device-manager.js';
2
+ import { DriverLoader } from './driver-loader.js';
3
+ import { PollingScheduler } from './polling-scheduler.js';
4
+ import type { MqttBridgeConfig, MqttBridge } from './types.js';
5
+ export type { MqttBridgeConfig, BridgeStatus, MqttBridge, PublishOptions, SubscribeOptions, MessageHandler, MqttMessage, DeviceConfig, DeviceStatus, DeviceConnection, RTUConnection, TCPConnection, } from './types.js';
6
+ export { loadConfig } from './utils/config.js';
7
+ interface BridgeDependencies {
8
+ driverLoader?: DriverLoader;
9
+ deviceManager?: DeviceManager;
10
+ pollingScheduler?: PollingScheduler;
11
+ }
12
+ export declare function createBridge(config: MqttBridgeConfig, dependencies?: BridgeDependencies): MqttBridge;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,KAAK,EACV,gBAAgB,EAChB,UAAU,EAMX,MAAM,YAAY,CAAA;AAQnB,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAG9C,UAAU,kBAAkB;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CACpC;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,gBAAgB,EACxB,YAAY,CAAC,EAAE,kBAAkB,GAChC,UAAU,CA0UZ"}