vrack2-core 0.0.1 → 1.0.1

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 (148) hide show
  1. package/README.md +33 -4
  2. package/docs/Bootstrap.md +77 -0
  3. package/docs/Container.md +124 -0
  4. package/docs/Device.md +272 -0
  5. package/docs/FastStart.md +111 -0
  6. package/docs/Structure.md +148 -0
  7. package/lib/Bootstrap.d.ts +79 -0
  8. package/lib/Bootstrap.js +103 -0
  9. package/lib/Container.d.ts +202 -6
  10. package/lib/Container.js +295 -27
  11. package/lib/IServiceStructure.d.ts +8 -0
  12. package/lib/IStructureDevice.d.ts +5 -0
  13. package/lib/ImportManager.d.ts +85 -3
  14. package/lib/ImportManager.js +122 -16
  15. package/lib/MainProcess.d.ts +30 -3
  16. package/lib/MainProcess.js +28 -6
  17. package/lib/Utility.d.ts +15 -21
  18. package/lib/Utility.js +40 -40
  19. package/lib/actions/Action.d.ts +10 -0
  20. package/lib/actions/Action.js +10 -0
  21. package/lib/actions/BasicAction.d.ts +60 -0
  22. package/lib/actions/BasicAction.js +62 -0
  23. package/lib/actions/GlobalAction.d.ts +5 -0
  24. package/lib/actions/GlobalAction.js +5 -0
  25. package/lib/actions/IAction.d.ts +7 -0
  26. package/lib/actions/ILocalAction.d.ts +7 -0
  27. package/lib/boot/BootClass.d.ts +93 -0
  28. package/lib/boot/BootClass.js +101 -0
  29. package/lib/boot/DeviceFileStorage.d.ts +38 -0
  30. package/lib/boot/DeviceFileStorage.js +112 -0
  31. package/lib/boot/DeviceManager.d.ts +190 -0
  32. package/lib/boot/DeviceManager.js +311 -0
  33. package/lib/boot/DeviceMetrics.d.ts +82 -0
  34. package/lib/boot/DeviceMetrics.js +128 -0
  35. package/lib/boot/StructureStorage.d.ts +59 -0
  36. package/lib/boot/StructureStorage.js +125 -0
  37. package/lib/errors/CoreError.d.ts +42 -25
  38. package/lib/errors/CoreError.js +44 -24
  39. package/lib/errors/ErrorManager.d.ts +18 -20
  40. package/lib/errors/ErrorManager.js +23 -22
  41. package/lib/index.d.ts +20 -4
  42. package/lib/index.js +28 -4
  43. package/lib/metrics/BasicMetric.d.ts +49 -0
  44. package/lib/metrics/BasicMetric.js +79 -0
  45. package/lib/metrics/IMetricSettings.d.ts +32 -0
  46. package/lib/metrics/IMetricSettings.js +2 -0
  47. package/lib/metrics/IvMs.d.ts +9 -0
  48. package/lib/metrics/IvMs.js +22 -0
  49. package/lib/metrics/IvS.d.ts +9 -0
  50. package/lib/metrics/IvS.js +22 -0
  51. package/lib/metrics/IvUs.d.ts +9 -0
  52. package/lib/metrics/IvUs.js +22 -0
  53. package/lib/metrics/Metric.d.ts +17 -0
  54. package/lib/metrics/Metric.js +27 -0
  55. package/lib/ports/BasicPort.d.ts +39 -0
  56. package/lib/ports/BasicPort.js +39 -0
  57. package/lib/ports/ILocalPort.d.ts +7 -0
  58. package/lib/ports/IPort.d.ts +7 -0
  59. package/lib/ports/Port.d.ts +10 -0
  60. package/lib/ports/Port.js +10 -0
  61. package/lib/ports/ReturnPort.d.ts +5 -0
  62. package/lib/ports/ReturnPort.js +5 -0
  63. package/lib/service/Device.d.ts +213 -78
  64. package/lib/service/Device.js +185 -83
  65. package/lib/service/DeviceConnect.d.ts +4 -8
  66. package/lib/service/DeviceConnect.js +4 -8
  67. package/lib/service/DevicePort.d.ts +15 -6
  68. package/lib/service/DevicePort.js +29 -12
  69. package/lib/service/IDeviceEvent.d.ts +4 -1
  70. package/lib/validator/IValidationProblem.d.ts +7 -0
  71. package/lib/validator/IValidationRule.d.ts +12 -0
  72. package/lib/validator/IValidationSubrule.d.ts +2 -0
  73. package/lib/validator/Rule.d.ts +6 -2
  74. package/lib/validator/Rule.js +12 -2
  75. package/lib/validator/Validator.d.ts +48 -3
  76. package/lib/validator/Validator.js +70 -18
  77. package/lib/validator/types/AnyType.d.ts +17 -0
  78. package/lib/validator/types/AnyType.js +34 -0
  79. package/lib/validator/types/ArrayType.d.ts +37 -4
  80. package/lib/validator/types/ArrayType.js +42 -6
  81. package/lib/validator/types/BasicType.d.ts +67 -7
  82. package/lib/validator/types/BasicType.js +74 -8
  83. package/lib/validator/types/BooleanType.d.ts +23 -0
  84. package/lib/validator/types/BooleanType.js +47 -0
  85. package/lib/validator/types/FunctionType.d.ts +17 -0
  86. package/lib/validator/types/FunctionType.js +38 -0
  87. package/lib/validator/types/NumberType.d.ts +40 -5
  88. package/lib/validator/types/NumberType.js +53 -14
  89. package/lib/validator/types/ObjectType.d.ts +32 -5
  90. package/lib/validator/types/ObjectType.js +42 -8
  91. package/lib/validator/types/StringType.d.ts +30 -5
  92. package/lib/validator/types/StringType.js +33 -7
  93. package/package.json +15 -14
  94. package/src/Bootstrap.ts +122 -0
  95. package/src/Container.ts +411 -43
  96. package/src/IServiceStructure.ts +9 -0
  97. package/src/IStructureDevice.ts +5 -0
  98. package/src/ImportManager.ts +119 -11
  99. package/src/MainProcess.ts +53 -8
  100. package/src/Utility.ts +35 -36
  101. package/src/actions/Action.ts +12 -0
  102. package/src/actions/BasicAction.ts +63 -0
  103. package/src/actions/GlobalAction.ts +5 -0
  104. package/src/actions/IAction.ts +7 -0
  105. package/src/actions/ILocalAction.ts +7 -0
  106. package/src/boot/BootClass.ts +117 -0
  107. package/src/boot/DeviceFileStorage.ts +96 -0
  108. package/src/boot/DeviceManager.ts +346 -0
  109. package/src/boot/DeviceMetrics.ts +129 -0
  110. package/src/boot/StructureStorage.ts +108 -0
  111. package/src/errors/CoreError.ts +52 -26
  112. package/src/errors/ErrorManager.ts +46 -33
  113. package/src/index.ts +30 -6
  114. package/src/metrics/BasicMetric.ts +84 -0
  115. package/src/metrics/IMetricSettings.ts +38 -0
  116. package/src/metrics/IvMs.ts +18 -0
  117. package/src/metrics/IvS.ts +18 -0
  118. package/src/metrics/IvUs.ts +17 -0
  119. package/src/metrics/Metric.ts +25 -0
  120. package/src/ports/BasicPort.ts +39 -0
  121. package/src/ports/ILocalPort.ts +7 -0
  122. package/src/ports/IPort.ts +7 -0
  123. package/src/ports/Port.ts +11 -1
  124. package/src/ports/ReturnPort.ts +5 -0
  125. package/src/service/Device.ts +234 -103
  126. package/src/service/DeviceConnect.ts +4 -8
  127. package/src/service/DevicePort.ts +30 -11
  128. package/src/service/IDeviceEvent.ts +4 -1
  129. package/src/validator/IValidationProblem.ts +7 -0
  130. package/src/validator/IValidationRule.ts +12 -0
  131. package/src/validator/IValidationSubrule.ts +3 -0
  132. package/src/validator/Rule.ts +16 -2
  133. package/src/validator/Validator.ts +74 -23
  134. package/src/validator/types/AnyType.ts +32 -0
  135. package/src/validator/types/ArrayType.ts +43 -7
  136. package/src/validator/types/BasicType.ts +78 -9
  137. package/src/validator/types/BooleanType.ts +49 -0
  138. package/src/validator/types/FunctionType.ts +39 -0
  139. package/src/validator/types/NumberType.ts +53 -15
  140. package/src/validator/types/ObjectType.ts +52 -14
  141. package/src/validator/types/StringType.ts +34 -10
  142. package/docs/RU-README.md +0 -6
  143. package/lib/DeviceManager.d.ts +0 -32
  144. package/lib/DeviceManager.js +0 -143
  145. package/lib/test.d.ts +0 -1
  146. package/lib/test.js +0 -58
  147. package/src/DeviceManager.ts +0 -124
  148. package/src/test.ts +0 -82
package/lib/Container.js CHANGED
@@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const events_1 = __importDefault(require("events"));
16
+ const DeviceManager_1 = __importDefault(require("./boot/DeviceManager"));
16
17
  const ErrorManager_1 = __importDefault(require("./errors/ErrorManager"));
17
18
  const Rule_1 = __importDefault(require("./validator/Rule"));
18
19
  const CoreError_1 = __importDefault(require("./errors/CoreError"));
@@ -20,6 +21,9 @@ const Validator_1 = __importDefault(require("./validator/Validator"));
20
21
  const ImportManager_1 = __importDefault(require("./ImportManager"));
21
22
  const DevicePort_1 = __importDefault(require("./service/DevicePort"));
22
23
  const DeviceConnect_1 = __importDefault(require("./service/DeviceConnect"));
24
+ const Utility_1 = __importDefault(require("./Utility"));
25
+ const fs_1 = require("fs");
26
+ /***** ******** DEVICE ERROR ********************/
23
27
  ErrorManager_1.default.register('Container', 'FBDRkSAWnlcc', 'CTR_ERROR_INIT_DEVICE', 'Device initialization error', {
24
28
  deviceConfig: Rule_1.default.object().description('Device configuration')
25
29
  });
@@ -32,9 +36,24 @@ ErrorManager_1.default.register('Container', '2RZznI3JDNUW', 'CTR_ERROR_PREPARE_
32
36
  message: Rule_1.default.string().description('Exception error string')
33
37
  });
34
38
  ErrorManager_1.default.register('Container', 'NDW2oD7mFxqB', 'CTR_DEVICE_ACTION_NF', 'Action on device not found', {
39
+ device: Rule_1.default.string().description('Device ID'),
35
40
  action: Rule_1.default.string().description('Action name'),
36
- method: Rule_1.default.string().description('Method name')
41
+ method: Rule_1.default.string().description('Method name'),
37
42
  });
43
+ ErrorManager_1.default.register('Container', 'XOXLMVCN9OBI', 'CTR_DEVICE_NF', 'Device in container found', {
44
+ device: Rule_1.default.string().description('Device ID'),
45
+ });
46
+ ErrorManager_1.default.register('Container', '570RD59JEYVN', 'CTR_DEVICE_ACTION_HANDLER_NF', 'Device handler action not found', {
47
+ device: Rule_1.default.string().description('Device ID'),
48
+ action: Rule_1.default.string().description('Device action name'),
49
+ });
50
+ ErrorManager_1.default.register('Container', 'RJV0KT2DFZBZ', 'CTR_DEVICE_PROCESS_EXCEPTION', 'During process execution - the device threw an exception', {
51
+ device: Rule_1.default.string().description('Device ID'),
52
+ });
53
+ ErrorManager_1.default.register('Container', 'K65XWSYOBVFG', 'CTR_DEVICE_PROCESS_PROMISE_EXCEPTION', 'During processPromise execution - the device threw an exception', {
54
+ device: Rule_1.default.string().description('Device ID'),
55
+ });
56
+ /***** ******** PORTS ERROR ********************/
38
57
  ErrorManager_1.default.register('Container', 'jkIpU1p4z5uz', 'CTR_INCORRECT_DYNAMIC_PN', 'Incorrect dynamic port name', {
39
58
  port: Rule_1.default.string().description('Incorrect port name')
40
59
  });
@@ -45,6 +64,10 @@ ErrorManager_1.default.register('Container', 'qPevPU6SRJ18', 'CTR_INPUT_HANDLER_
45
64
  port: Rule_1.default.string().description('Port name for handler'),
46
65
  handler: Rule_1.default.string().description('Handler name')
47
66
  });
67
+ ErrorManager_1.default.register('Container', 'QlcUh744VzAG', 'CTR_DEVICE_PORT_NF', 'Port on device not found', {
68
+ port: Rule_1.default.string().description('Port name'),
69
+ });
70
+ /***** ******** CONNECTION ERROR ********************/
48
71
  ErrorManager_1.default.register('Container', 'Kp74OuVGNU0u', 'CTR_CONNECTION_INCORRECT', 'Incorrect connection format', {
49
72
  connection: Rule_1.default.string().description('Connection string'),
50
73
  error: Rule_1.default.string().description('String of error problem'),
@@ -57,58 +80,234 @@ ErrorManager_1.default.register('Container', 'CwFj1G47H45E', 'CTR_CONNECTION_POR
57
80
  connection: Rule_1.default.string().description('Connection string'),
58
81
  port: Rule_1.default.string().description('Port name not found')
59
82
  });
83
+ ErrorManager_1.default.register('Container', 'XR1K10R0OOUC', 'CTR_INCOMPATIBLE_PORTS', 'Incompatible ports', {
84
+ connection: Rule_1.default.string().description('Connection string'),
85
+ });
86
+ ErrorManager_1.default.register('Container', 'MmVoDOQwaYkx', 'CTR_INCORRECT_BOOSTRAP', 'The required DeviceManager class is not specified correctly', {});
87
+ ErrorManager_1.default.register('Container', 'e090R0MLyb7y', 'CTR_CONF_EXTENDS_PROBLEM', 'Problem with extending service configuration.', {});
88
+ /**
89
+ * Service Load Class. It loads all devices in the list,
90
+ * establishes connections between them, and performs device startup.
91
+ *
92
+ * This class is a bit complicated for a simple description.
93
+ * It is recommended to familiarize yourself with the source code
94
+ */
60
95
  class Container extends events_1.default {
61
- constructor(config, dm) {
96
+ /**
97
+ * Create container needed service structure & device manager
98
+ *
99
+ * @param service Service structure
100
+ * @param bootstrap Bootstrap class Object
101
+ *
102
+ * */
103
+ constructor(id, service, Bootstrap, confFile) {
62
104
  super();
105
+ /** Unique service ID */
106
+ this.id = '';
107
+ /** List of devices in container */
63
108
  this.devices = {};
64
- this.config = config;
65
- this.DeviceManager = dm;
109
+ /** inited flag */
110
+ this.inited = false;
111
+ /** run flag */
112
+ this.runned = false;
113
+ /**
114
+ * Container structure
115
+ */
116
+ this.structure = {};
117
+ this.id = id;
118
+ this.service = service;
66
119
  this.deviceActions = {};
120
+ this.deviceMetrics = {};
121
+ this.confFile = confFile;
122
+ this.Bootstrap = Bootstrap;
67
123
  }
124
+ /**
125
+ * Run container
126
+ */
68
127
  run() {
69
128
  return __awaiter(this, void 0, void 0, function* () {
70
- for (const device of this.config.devices) {
129
+ yield this.init();
130
+ yield this.runProcess();
131
+ });
132
+ }
133
+ /**
134
+ * Extends service from config file
135
+ *
136
+ * Sometimes there is a need to override the settings of some devices.
137
+ * To do this, you can use a special configuration file of the service.
138
+ * It contains the same as the main service file and replaces with its settings
139
+ * and parameters the settings and parameters of the main service.
140
+ *
141
+ * @see init()
142
+ */
143
+ fillConfFile() {
144
+ if (!this.confFile || !(0, fs_1.existsSync)(this.confFile))
145
+ return;
146
+ const conf = ImportManager_1.default.importJSON(this.confFile);
147
+ if (conf.devices === undefined || !Array.isArray(conf.devices))
148
+ conf.devices = [];
149
+ for (const device of conf.devices) {
150
+ if (!device.id || device.options === undefined || typeof device.options !== 'object')
151
+ continue;
152
+ for (const cdev of this.service.devices) {
153
+ if (cdev.id === device.id) {
154
+ for (const pname in device.options)
155
+ cdev.options[pname] = device.options[pname];
156
+ if (device.connections)
157
+ cdev.connections = device.connections;
158
+ }
159
+ }
160
+ }
161
+ }
162
+ /**
163
+ * Creates device classes. Preprocesses the device,
164
+ * then adds ports to it and creates connections between ports.
165
+ *
166
+ * When adding and creating devices, ports and connections,
167
+ * the service structure is also created
168
+ *
169
+ * 1. Init device
170
+ * 2. Init individual device connections
171
+ * 3. Init other connections
172
+ *
173
+ * @see structure
174
+ */
175
+ init() {
176
+ return __awaiter(this, void 0, void 0, function* () {
177
+ if (this.inited)
178
+ return;
179
+ this.inited = true;
180
+ this.emit('configure');
181
+ try {
182
+ this.fillConfFile();
183
+ }
184
+ catch (err) {
185
+ if (err instanceof Error) {
186
+ const ner = ErrorManager_1.default.make('CTR_CONF_EXTENDS_PROBLEM', {}).setTrace(err).add(err);
187
+ throw ner;
188
+ }
189
+ throw err;
190
+ }
191
+ this.emit('beforeInit');
192
+ this.emit('init');
193
+ for (const device of this.service.devices) {
71
194
  try {
195
+ this.emit('initDevice', device);
72
196
  yield this.initDevice(device);
73
197
  }
74
198
  catch (error) {
75
199
  const ner = ErrorManager_1.default.make('CTR_ERROR_INIT_DEVICE', { deviceConfig: device });
76
- if (error instanceof CoreError_1.default)
77
- ner.add(error);
200
+ ner.add(error);
78
201
  throw ner;
79
202
  }
80
203
  }
81
- for (const conn of this.config.connections) {
204
+ this.emit('afterInit');
205
+ this.emit('beforeConnections');
206
+ this.emit('connections');
207
+ for (const device of this.service.devices) {
208
+ if (!device.connections)
209
+ continue;
210
+ for (const conn of device.connections) {
211
+ this.emit('connection', conn);
212
+ this.initConnection(conn);
213
+ }
214
+ }
215
+ if (Array.isArray(this.service.connections)) {
216
+ for (const conn of this.service.connections) {
217
+ this.initConnection(conn);
218
+ }
219
+ }
220
+ this.emit('afterConnections');
221
+ });
222
+ }
223
+ /**
224
+ * Run process & processPromise of all devices
225
+ */
226
+ runProcess() {
227
+ return __awaiter(this, void 0, void 0, function* () {
228
+ if (this.runned)
229
+ return;
230
+ this.runned = true;
231
+ this.emit('beforeProcess');
232
+ for (const key in this.devices) {
82
233
  try {
83
- yield this.initConnection(conn);
234
+ this.emit('process', key);
235
+ this.devices[key].process();
84
236
  }
85
237
  catch (error) {
86
- const ner = ErrorManager_1.default.make('CTR_ERROR_INIT_CONNECTION', { connection: conn });
87
- if (error instanceof CoreError_1.default)
88
- ner.add(error);
89
- throw ner;
238
+ throw ErrorManager_1.default.make('CTR_DEVICE_PROCESS_EXCEPTION', { device: key }).add(error);
239
+ }
240
+ }
241
+ this.emit('afterProcess');
242
+ this.emit('beforeProcessPromise');
243
+ for (const key in this.devices) {
244
+ try {
245
+ this.emit('processPromise', key);
246
+ yield this.devices[key].processPromise();
247
+ }
248
+ catch (error) {
249
+ throw ErrorManager_1.default.make('CTR_DEVICE_PROCESS_PROMISE_EXCEPTION', { device: key }).add(error);
90
250
  }
91
251
  }
92
- for (const key in this.devices)
93
- this.devices[key].process();
94
- for (const key in this.devices)
95
- yield this.devices[key].processPromise();
96
- // const cs = await this.DeviceManager.get('vrack.Master')
97
- // const cse = new cs()
98
- // console.log(cse)
99
- // cse.run()
252
+ this.emit('afterProcessPromise');
253
+ this.emit('beforeLoaded');
254
+ this.emit('loaded');
100
255
  });
101
256
  }
257
+ /**
258
+ * Check device action and run him
259
+ *
260
+ * @param device Device ID
261
+ * @param action Device action (as 'action.name')
262
+ * @param data Data for action
263
+ */
264
+ deviceAction(device, action, data) {
265
+ return __awaiter(this, void 0, void 0, function* () {
266
+ if (!this.deviceActions[device])
267
+ throw ErrorManager_1.default.make('CTR_DEVICE_NF', { device });
268
+ const deviceClass = this.devices[device];
269
+ const deviceActions = this.deviceActions[device];
270
+ const method = ImportManager_1.default.camelize('action.' + action);
271
+ if (!deviceActions[action])
272
+ throw ErrorManager_1.default.make('CTR_DEVICE_ACTION_NF', { device, action, method });
273
+ if (!deviceClass[method])
274
+ throw ErrorManager_1.default.make('CTR_DEVICE_ACTION_HANDLER_NF', { device, action });
275
+ const actionExport = deviceActions[action].exportRaw();
276
+ Validator_1.default.validate(actionExport.requirements, data);
277
+ return yield deviceClass[method](data);
278
+ });
279
+ }
280
+ /**
281
+ * Return structure
282
+ */
283
+ getStructure() {
284
+ return __awaiter(this, void 0, void 0, function* () {
285
+ return this.structure;
286
+ });
287
+ }
288
+ /**
289
+ * Init one device
290
+ *
291
+ * 1. Make device class object
292
+ * 2. Fill device options
293
+ * 3. Run device prepareOptions method
294
+ * 4. Validating device options
295
+ * 5. Check device actions
296
+ * 6. make device inputs ports
297
+ * 7. make device outputs ports
298
+ **/
102
299
  initDevice(dconf) {
103
300
  return __awaiter(this, void 0, void 0, function* () {
104
- const cs = yield this.DeviceManager.get(dconf.type);
301
+ const DM = this.Bootstrap.getBootClass('DeviceManager', DeviceManager_1.default);
302
+ const cs = yield DM.get(dconf.type);
105
303
  //
106
- if (dconf.id === undefined || !dconf.id || typeof dconf.id !== 'string') {
304
+ if (dconf.id === undefined || !dconf.id || typeof dconf.id !== 'string' || !Utility_1.default.isDeviceName(dconf.id)) {
107
305
  throw ErrorManager_1.default.make('CTR_INCORRECT_DEVICE_ID');
108
306
  }
109
307
  // Device id is dublicated
110
308
  if (dconf.id in this.devices)
111
309
  throw ErrorManager_1.default.make('CTR_DEVICE_DUBLICATE');
310
+ // Create device
112
311
  const dev = new cs(dconf.id, dconf.type, this);
113
312
  this.devices[dconf.id] = dev;
114
313
  // Fill options
@@ -130,6 +329,17 @@ class Container extends events_1.default {
130
329
  const rules = dev.checkOptions();
131
330
  // Validating
132
331
  Validator_1.default.validate(rules, dev.options);
332
+ /** create structure */
333
+ this.structure[dconf.id] = {
334
+ id: dconf.id,
335
+ type: dconf.type,
336
+ actions: {},
337
+ outputs: {},
338
+ inputs: {},
339
+ ports: [],
340
+ settings: {},
341
+ metrics: {},
342
+ };
133
343
  dev.preProcess();
134
344
  // Check actions
135
345
  this.deviceActions[dev.id] = dev.actions();
@@ -137,9 +347,18 @@ class Container extends events_1.default {
137
347
  const method = ImportManager_1.default.camelize('action.' + action);
138
348
  if (!(method in dev))
139
349
  throw ErrorManager_1.default.make('CTR_DEVICE_ACTION_NF', { action, method });
350
+ // add structure device action
351
+ this.structure[dconf.id].actions[action] = this.deviceActions[dev.id][action].export();
352
+ }
353
+ this.structure[dconf.id].settings = dev.settings();
354
+ // Make Metrics
355
+ this.deviceMetrics[dev.id] = dev.metrics();
356
+ for (const metric in this.deviceMetrics[dev.id]) {
357
+ const raw = this.deviceMetrics[dev.id][metric].export();
358
+ const nEvent = { device: dev.id, data: metric, trace: raw };
359
+ this.emit('device.register.metric', nEvent);
360
+ this.structure[dconf.id].metrics[metric] = raw;
140
361
  }
141
- // make ports
142
- // prepare ports
143
362
  // make inputPorts
144
363
  const iPorts = dev.inputs();
145
364
  for (const key in iPorts) {
@@ -151,10 +370,14 @@ class Container extends events_1.default {
151
370
  this.checkInputHandler(subkey, handler, dev);
152
371
  const ndp = new DevicePort_1.default(subkey, pList[subkey]);
153
372
  dev.ports.input[subkey] = ndp;
373
+ // add structure device input ports
374
+ this.structure[dconf.id].inputs[subkey] = [];
375
+ this.structure[dconf.id].ports.push(Object.assign({ port: subkey, direct: 'input' }, pList[subkey]));
154
376
  if (handler in dev)
155
377
  ndp.push = dev[handler].bind(dev);
156
378
  }
157
379
  }
380
+ // make output ports
158
381
  const oPorts = dev.outputs();
159
382
  for (const key in oPorts) {
160
383
  const exp = oPorts[key].export();
@@ -163,17 +386,31 @@ class Container extends events_1.default {
163
386
  this.checkPortName(subkey);
164
387
  const ndp = new DevicePort_1.default(subkey, pList[subkey]);
165
388
  dev.ports.output[subkey] = ndp;
389
+ // add structure device output ports
390
+ this.structure[dconf.id].outputs[subkey] = [];
391
+ this.structure[dconf.id].ports.push(Object.assign({ port: subkey, direct: 'output' }, pList[subkey]));
166
392
  }
167
393
  }
168
394
  });
169
395
  }
396
+ /**
397
+ * Check device input handler
398
+ * Make CTR_INPUT_HANDLER_NF error if not exists
399
+ * @see initDevice make inputPorts
400
+ */
170
401
  checkInputHandler(port, handler, device) {
171
402
  if (!(handler in device))
172
403
  throw ErrorManager_1.default.make('CTR_INPUT_HANDLER_NF', { port, handler });
173
404
  }
405
+ /**
406
+ * Init device connection
407
+ *
408
+ * @param conn Device connection string like a "DevID.port -> DevIDTO.port"
409
+ */
174
410
  initConnection(conn) {
175
- return __awaiter(this, void 0, void 0, function* () {
411
+ try {
176
412
  const cc = this.toConnection(conn);
413
+ this.emit('connection', cc);
177
414
  if (!(cc.outputDevice in this.devices))
178
415
  throw ErrorManager_1.default.make('CTR_CONNECTION_DEVICE_NF', { connection: conn, device: cc.outputDevice });
179
416
  if (!(cc.outputPort in this.devices[cc.outputDevice].ports.output))
@@ -182,11 +419,31 @@ class Container extends events_1.default {
182
419
  throw ErrorManager_1.default.make('CTR_CONNECTION_DEVICE_NF', { connection: conn, device: cc.inputDevice });
183
420
  if (!(cc.inputPort in this.devices[cc.inputDevice].ports.input))
184
421
  throw ErrorManager_1.default.make('CTR_CONNECTION_PORT_NF', { connection: conn, port: cc.inputPort });
422
+ if (this.devices[cc.inputDevice].ports.input[cc.inputPort].type !== this.devices[cc.outputDevice].ports.output[cc.outputPort].type)
423
+ throw ErrorManager_1.default.make('CTR_INCOMPATIBLE_PORTS', { connection: conn });
185
424
  const outPort = this.devices[cc.outputDevice].ports.output[cc.outputPort];
186
425
  const inPort = this.devices[cc.inputDevice].ports.input[cc.inputPort];
426
+ // Set structure connections
427
+ if (this.structure[cc.outputDevice].outputs[cc.outputPort] === undefined)
428
+ this.structure[cc.outputDevice].outputs[cc.outputPort] = [];
429
+ this.structure[cc.outputDevice].outputs[cc.outputPort].push({ device: cc.inputDevice, port: cc.inputPort });
430
+ if (this.structure[cc.inputDevice].inputs[cc.inputPort] === undefined)
431
+ this.structure[cc.inputDevice].inputs[cc.inputPort] = [];
432
+ this.structure[cc.inputDevice].inputs[cc.inputPort].push({ device: cc.outputDevice, port: cc.outputPort });
187
433
  new DeviceConnect_1.default(outPort, inPort);
188
- });
434
+ }
435
+ catch (error) {
436
+ const ner = ErrorManager_1.default.make('CTR_ERROR_INIT_CONNECTION', { connection: conn });
437
+ if (error instanceof CoreError_1.default)
438
+ ner.add(error);
439
+ throw ner;
440
+ }
189
441
  }
442
+ /**
443
+ * Container Helper - parse connection string to format object
444
+ *
445
+ * @return Connection object
446
+ */
190
447
  toConnection(con) {
191
448
  var _a, _b;
192
449
  const act = con.split('->');
@@ -211,10 +468,21 @@ class Container extends events_1.default {
211
468
  };
212
469
  return result;
213
470
  }
471
+ /**
472
+ * Check Port name (strict format a-zA-Z0-9.)
473
+ *
474
+ * @param port Port name
475
+ */
214
476
  checkPortName(port) {
215
477
  if (!port.match(/[a-zA-Z0-9.]/))
216
478
  throw ErrorManager_1.default.make('CTR_INCORRECT_PN', { port });
217
479
  }
480
+ /**
481
+ * Convert dynamic port to ports list
482
+ *
483
+ * @param name Port name with %d symbols
484
+ * @param iPort IPort object (port settings)
485
+ */
218
486
  getPortList(name, iPort) {
219
487
  const result = {};
220
488
  if (!iPort.dynamic) {
@@ -1,5 +1,13 @@
1
1
  import IStructureDevice from "./IStructureDevice";
2
+ /** Basic service file structure */
2
3
  export default interface IServiceStructure {
4
+ /**
5
+ * Devices list
6
+ * @see IStructureDevice
7
+ */
3
8
  devices: Array<IStructureDevice>;
9
+ /**
10
+ * Connections list
11
+ */
4
12
  connections: Array<string>;
5
13
  }
@@ -1,7 +1,12 @@
1
1
  export default interface IStructureDevice {
2
+ /** Device ID */
2
3
  id: string;
4
+ /** Device type in VRack style like a 'vendor.Device' */
3
5
  type: string;
6
+ /** Device options */
4
7
  options: {
5
8
  [key: string]: any;
6
9
  };
10
+ /** Device connections */
11
+ connections?: Array<string>;
7
12
  }
@@ -5,11 +5,93 @@ export default class ImportManager {
5
5
  * @param {string} path Full or relative path to file
6
6
  */
7
7
  static importPath(raPath: string): Promise<any>;
8
+ /**
9
+ * Import class like a vrack2 device style
10
+ *
11
+ * Разделяюет переданную строку пути на 2 части.
12
+ * Первая честь является названием модуля, а вторая часть классом внутри него
13
+ *
14
+ * @example ImportManager.importClass('vrack2-core.Container')
15
+ */
8
16
  static importClass(cs: string): Promise<any>;
9
- static importJSON(filePath: string): Promise<any>;
17
+ /**
18
+ * Attempts to open a file and use its contents as json
19
+ *
20
+ * Returns the result of parsing json
21
+ *
22
+ * @returns {any} json parsing result
23
+ */
24
+ static importJSON(filePath: string): any;
25
+ /**
26
+ * Returns the class name in the style of import vrack
27
+ *
28
+ * return `Container` from 'vrack2-core.Container' string
29
+ *
30
+ * @param cs Import class string
31
+ *
32
+ */
33
+ static importClassName(cs: string): string | undefined;
34
+ /**
35
+ * Returns the vendor name in the style of import vrack
36
+ *
37
+ * return `vrack2-core` from 'vrack2-core.Container' string
38
+ *
39
+ * @param cs Import class string
40
+ */
41
+ static importVendorName(cs: string): string | undefined;
42
+ /**
43
+ * Returns a list of directories in the specified directory.
44
+ *
45
+ * @param dir path to directory
46
+ */
47
+ static dirList(dir: string): string[];
48
+ /**
49
+ * Returns a list of files in the specified directory.
50
+ *
51
+ * @param dir path to directory
52
+ */
53
+ static fileList(dir: string): string[];
54
+ /**
55
+ * Checks if a path is a directory
56
+ *
57
+ * @param dir path to directory
58
+ */
59
+ static isDir(dir: string): boolean;
60
+ /**
61
+ * Checks if a path is a directory
62
+ *
63
+ * @param f path to file
64
+ */
65
+ static isFile(f: string): boolean;
66
+ /**
67
+ * Try JSON parse
68
+ *
69
+ * Returns an CoreError[IM_JSON_INCORRECT] if there is a parsing error.
70
+ *
71
+ * @param jsonRaw JSON raw string
72
+ *
73
+ */
10
74
  static tryJsonParse(jsonRaw: string): any;
11
- static camelize(text: string): string;
12
- protected static getSub(imp: any, get: string): any;
75
+ /**
76
+ * Return directory where VRack was launched from
77
+ */
13
78
  static systemPath(): string;
79
+ /**
80
+ * Camelize string for input & action handlers
81
+ *
82
+ * Splits a string with a dot and returns the string
83
+ * with capital letters starting from the second word
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * ImportManager.camelize('input.device.port') // return inputDevicePort
88
+ * ```
89
+ *
90
+ * @param text Like a `input.device.port` string
91
+ */
92
+ static camelize(text: string): string;
93
+ /**
94
+ * Try import method
95
+ */
14
96
  protected static tryImport(p: string): Promise<any>;
15
97
  }