vrack2-core 1.0.5 → 1.1.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 +8 -2
- package/lib/Bootstrap.js +12 -23
- package/lib/Container.js +179 -201
- package/lib/ImportManager.js +36 -51
- package/lib/MainProcess.js +6 -19
- package/lib/ReactiveRef.d.ts +48 -0
- package/lib/ReactiveRef.js +74 -0
- package/lib/UniversalWorkers.d.ts +59 -0
- package/lib/UniversalWorkers.js +119 -0
- package/lib/Utility.js +11 -15
- package/lib/boot/BootClass.js +1 -12
- package/lib/boot/DeviceFileStorage.js +20 -33
- package/lib/boot/DeviceManager.js +42 -55
- package/lib/boot/StructureStorage.js +20 -35
- package/lib/errors/ErrorManager.js +1 -1
- package/lib/service/Device.js +1 -12
- package/package.json +1 -1
- package/src/ReactiveRef.ts +83 -0
- package/src/UniversalWorkers.ts +127 -0
- package/tsconfig.json +3 -2
package/lib/ImportManager.js
CHANGED
|
@@ -22,15 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
27
|
};
|
|
@@ -61,23 +52,21 @@ class ImportManager {
|
|
|
61
52
|
*
|
|
62
53
|
* @param {string} path Full or relative path to file
|
|
63
54
|
*/
|
|
64
|
-
static importPath(raPath) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return ti;
|
|
80
|
-
});
|
|
55
|
+
static async importPath(raPath) {
|
|
56
|
+
// IF we have absolute path
|
|
57
|
+
if (path_1.default.isAbsolute(raPath)) {
|
|
58
|
+
const ti = await ImportManager.tryImport(raPath);
|
|
59
|
+
if (ti !== false)
|
|
60
|
+
return ti;
|
|
61
|
+
}
|
|
62
|
+
const mbfp = path_1.default.join(ImportManager.systemPath(), raPath);
|
|
63
|
+
if ((0, fs_1.existsSync)(mbfp)) {
|
|
64
|
+
const ti = await ImportManager.tryImport(raPath);
|
|
65
|
+
if (ti !== false)
|
|
66
|
+
return ti;
|
|
67
|
+
}
|
|
68
|
+
const ti = await Promise.resolve(`${raPath}`).then(s => __importStar(require(s)));
|
|
69
|
+
return ti;
|
|
81
70
|
}
|
|
82
71
|
/**
|
|
83
72
|
* Import class like a vrack2 device style
|
|
@@ -87,22 +76,20 @@ class ImportManager {
|
|
|
87
76
|
*
|
|
88
77
|
* @example ImportManager.importClass('vrack2-core.Container')
|
|
89
78
|
*/
|
|
90
|
-
static importClass(cs) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return ret;
|
|
105
|
-
});
|
|
79
|
+
static async importClass(cs) {
|
|
80
|
+
const acts = cs.split('.');
|
|
81
|
+
const vendor = acts.shift();
|
|
82
|
+
if (typeof vendor !== 'string')
|
|
83
|
+
throw ErrorManager_1.default.make('IM_CLASS_PATH_ERROR', { path: cs });
|
|
84
|
+
let ret = await ImportManager.tryImport(vendor);
|
|
85
|
+
if (ret === false)
|
|
86
|
+
throw ErrorManager_1.default.make('IM_CLASS_VENDOR_ERROR', { path: cs });
|
|
87
|
+
for (const act of acts) {
|
|
88
|
+
ret = ret[act];
|
|
89
|
+
if (ret === undefined)
|
|
90
|
+
throw ErrorManager_1.default.make('IM_CLASS_ACT_ERROR', { path: cs });
|
|
91
|
+
}
|
|
92
|
+
return ret;
|
|
106
93
|
}
|
|
107
94
|
/**
|
|
108
95
|
* Attempts to open a file and use its contents as json
|
|
@@ -237,15 +224,13 @@ class ImportManager {
|
|
|
237
224
|
/**
|
|
238
225
|
* Try import method
|
|
239
226
|
*/
|
|
240
|
-
static tryImport(p) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
});
|
|
227
|
+
static async tryImport(p) {
|
|
228
|
+
try {
|
|
229
|
+
return await Promise.resolve(`${p}`).then(s => __importStar(require(s)));
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
249
234
|
}
|
|
250
235
|
}
|
|
251
236
|
exports.default = ImportManager;
|
package/lib/MainProcess.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -34,17 +25,13 @@ class MainProcess {
|
|
|
34
25
|
this.Bootstrap = new Bootstrap_1.default(this.options.bootstrap);
|
|
35
26
|
this.Container = new this.options.ContainerClass(this.options.id, this.options.service, this.Bootstrap, this.options.confFile);
|
|
36
27
|
}
|
|
37
|
-
run() {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
yield this.Container.runProcess();
|
|
41
|
-
});
|
|
28
|
+
async run() {
|
|
29
|
+
await this.check();
|
|
30
|
+
await this.Container.runProcess();
|
|
42
31
|
}
|
|
43
|
-
check() {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
yield this.Container.init();
|
|
47
|
-
});
|
|
32
|
+
async check() {
|
|
33
|
+
await this.Bootstrap.loadBootList(this.Container);
|
|
34
|
+
await this.Container.init();
|
|
48
35
|
}
|
|
49
36
|
}
|
|
50
37
|
exports.default = MainProcess;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Простой реактивный ref-аналог (как в Vue 3), но только для объектов.
|
|
3
|
+
* Поддерживает глубокую реактивность вложенных plain-объектов.
|
|
4
|
+
* Массивы НЕ отслеживаются внутри — только при переприсвоении свойства целиком.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* const state = new ReactiveRef({ user: { name: 'Alice' }, items: [1, 2] });
|
|
9
|
+
*
|
|
10
|
+
* state.watch(() => console.log('изменилось!'));
|
|
11
|
+
*
|
|
12
|
+
* state.value.user.name = 'Bob'; // вызовет callback
|
|
13
|
+
* state.value.items = [1, 2, 3]; // вызовет callback
|
|
14
|
+
* state.value.items.push(4); // НЕ вызовет (мутация массива)
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export default class ReactiveRef<T extends object> {
|
|
18
|
+
/**
|
|
19
|
+
* Хранимое значение
|
|
20
|
+
*/
|
|
21
|
+
private _value;
|
|
22
|
+
/**
|
|
23
|
+
* Калбек для обработки при измении значения
|
|
24
|
+
*/
|
|
25
|
+
private watcher;
|
|
26
|
+
/**
|
|
27
|
+
* При создании иницируем объектом
|
|
28
|
+
*/
|
|
29
|
+
constructor(initialValue: T);
|
|
30
|
+
/**
|
|
31
|
+
* Getter value
|
|
32
|
+
*/
|
|
33
|
+
get value(): T;
|
|
34
|
+
/**
|
|
35
|
+
* Назначает обработчик который будет вызван при изменении объекта
|
|
36
|
+
*/
|
|
37
|
+
watch(callback: () => void): void;
|
|
38
|
+
/**
|
|
39
|
+
* Возвращает true если это простой объект не являющийся массивом или null
|
|
40
|
+
* Null кстати тоже объект внутри JS из-за чего эта проверка очень актуальна
|
|
41
|
+
*/
|
|
42
|
+
private isPlainObject;
|
|
43
|
+
/**
|
|
44
|
+
* Делает переданный объект (если он объект) реактивным
|
|
45
|
+
* Причем делает свойства объекта тоже реактивными рекурсивно
|
|
46
|
+
*/
|
|
47
|
+
private makeReactive;
|
|
48
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Простой реактивный ref-аналог (как в Vue 3), но только для объектов.
|
|
5
|
+
* Поддерживает глубокую реактивность вложенных plain-объектов.
|
|
6
|
+
* Массивы НЕ отслеживаются внутри — только при переприсвоении свойства целиком.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const state = new ReactiveRef({ user: { name: 'Alice' }, items: [1, 2] });
|
|
11
|
+
*
|
|
12
|
+
* state.watch(() => console.log('изменилось!'));
|
|
13
|
+
*
|
|
14
|
+
* state.value.user.name = 'Bob'; // вызовет callback
|
|
15
|
+
* state.value.items = [1, 2, 3]; // вызовет callback
|
|
16
|
+
* state.value.items.push(4); // НЕ вызовет (мутация массива)
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
class ReactiveRef {
|
|
20
|
+
/**
|
|
21
|
+
* При создании иницируем объектом
|
|
22
|
+
*/
|
|
23
|
+
constructor(initialValue) {
|
|
24
|
+
/**
|
|
25
|
+
* Калбек для обработки при измении значения
|
|
26
|
+
*/
|
|
27
|
+
this.watcher = () => { };
|
|
28
|
+
this._value = this.makeReactive(initialValue);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Getter value
|
|
32
|
+
*/
|
|
33
|
+
get value() {
|
|
34
|
+
return this._value;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Назначает обработчик который будет вызван при изменении объекта
|
|
38
|
+
*/
|
|
39
|
+
watch(callback) {
|
|
40
|
+
this.watcher = callback;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Возвращает true если это простой объект не являющийся массивом или null
|
|
44
|
+
* Null кстати тоже объект внутри JS из-за чего эта проверка очень актуальна
|
|
45
|
+
*/
|
|
46
|
+
isPlainObject(val) {
|
|
47
|
+
return val !== null && typeof val === 'object' && !Array.isArray(val);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Делает переданный объект (если он объект) реактивным
|
|
51
|
+
* Причем делает свойства объекта тоже реактивными рекурсивно
|
|
52
|
+
*/
|
|
53
|
+
makeReactive(obj) {
|
|
54
|
+
if (obj.__isReactive)
|
|
55
|
+
return obj;
|
|
56
|
+
const handler = {
|
|
57
|
+
set: (target, key, value) => {
|
|
58
|
+
const oldValue = target[key];
|
|
59
|
+
const isOwn = Object.prototype.hasOwnProperty.call(target, key);
|
|
60
|
+
// Рекурсивно реактивизируем только обычные объекты (не массивы!)
|
|
61
|
+
const nextValue = this.isPlainObject(value) ? this.makeReactive(value) : value;
|
|
62
|
+
target[key] = nextValue;
|
|
63
|
+
// Уведомляем только при изменении значения
|
|
64
|
+
if (!isOwn || oldValue !== nextValue)
|
|
65
|
+
this.watcher();
|
|
66
|
+
return true;
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
const proxy = new Proxy(obj, handler);
|
|
70
|
+
proxy.__isReactive = true;
|
|
71
|
+
return proxy;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.default = ReactiveRef;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
type UniversalWorkerOptions = {
|
|
2
|
+
isolated?: boolean;
|
|
3
|
+
scriptPath: string;
|
|
4
|
+
workerData?: any;
|
|
5
|
+
};
|
|
6
|
+
export default class UniversalWorker {
|
|
7
|
+
private impl;
|
|
8
|
+
/**
|
|
9
|
+
* Создает новые воркер
|
|
10
|
+
*
|
|
11
|
+
* Если параметр isolated = true будет создан форк
|
|
12
|
+
* иначе будет использоваться WorkerThread
|
|
13
|
+
*/
|
|
14
|
+
constructor(options: UniversalWorkerOptions);
|
|
15
|
+
/**
|
|
16
|
+
* Отправляет внутрь воркера обхект способный к сериализации
|
|
17
|
+
*/
|
|
18
|
+
send(msg: any): void;
|
|
19
|
+
/**
|
|
20
|
+
* Подписывает на события воркера
|
|
21
|
+
*
|
|
22
|
+
* Доступно только message exit error
|
|
23
|
+
*/
|
|
24
|
+
on(event: 'message' | 'exit' | 'error', handler: (...args: any[]) => void): void;
|
|
25
|
+
/**
|
|
26
|
+
* Убивает процесс
|
|
27
|
+
*/
|
|
28
|
+
kill(): void;
|
|
29
|
+
/**
|
|
30
|
+
* @see kill
|
|
31
|
+
*/
|
|
32
|
+
terminate(): void;
|
|
33
|
+
}
|
|
34
|
+
export type WorkerMessageHandler = (message: any) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Определяет - является ли процесс форкнутым
|
|
37
|
+
* Основанно на проверке метода process.send которая есть только у фокрнутого процесса
|
|
38
|
+
*/
|
|
39
|
+
export declare const isForked: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Определяет - является ли данный инстанс дочерним - не важно используя worker_threads или fork
|
|
42
|
+
* Проверяет !isMainThread || isForked
|
|
43
|
+
*/
|
|
44
|
+
export declare const isChild: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Получение данных сверху, которые были переданны при создании воркера
|
|
47
|
+
* В случае использования worker_threads - workerData
|
|
48
|
+
* Если же это форк - парсит устаноленнюу переменную окружения VRACK2_WORKER_DATA
|
|
49
|
+
*/
|
|
50
|
+
export declare function getWorkerData(): any;
|
|
51
|
+
/**
|
|
52
|
+
* Отправка данных наверх в родительский процесс
|
|
53
|
+
*/
|
|
54
|
+
export declare function sendMessage(message: any): void;
|
|
55
|
+
/**
|
|
56
|
+
* Позволяет подписаться на данные которые приходят сверху
|
|
57
|
+
*/
|
|
58
|
+
export declare function onMessage(handler: WorkerMessageHandler): void;
|
|
59
|
+
export {};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.onMessage = exports.sendMessage = exports.getWorkerData = exports.isChild = exports.isForked = void 0;
|
|
4
|
+
// UniversalWorker.ts
|
|
5
|
+
const child_process_1 = require("child_process");
|
|
6
|
+
const worker_threads_1 = require("worker_threads");
|
|
7
|
+
class UniversalWorker {
|
|
8
|
+
/**
|
|
9
|
+
* Создает новые воркер
|
|
10
|
+
*
|
|
11
|
+
* Если параметр isolated = true будет создан форк
|
|
12
|
+
* иначе будет использоваться WorkerThread
|
|
13
|
+
*/
|
|
14
|
+
constructor(options) {
|
|
15
|
+
const { isolated = true, scriptPath, workerData } = options;
|
|
16
|
+
if (isolated) {
|
|
17
|
+
// child_process
|
|
18
|
+
const proc = (0, child_process_1.fork)(scriptPath, [], {
|
|
19
|
+
env: { ...process.env, VRACK2_WORKER_DATA: JSON.stringify(workerData) }
|
|
20
|
+
});
|
|
21
|
+
this.impl = {
|
|
22
|
+
send: (msg) => proc.send(msg),
|
|
23
|
+
on: (ev, handler) => proc.on(ev, handler),
|
|
24
|
+
kill: () => proc.kill()
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// worker_threads
|
|
29
|
+
const wt = new worker_threads_1.Worker(scriptPath, { workerData });
|
|
30
|
+
this.impl = {
|
|
31
|
+
send: (msg) => wt.postMessage(msg),
|
|
32
|
+
on: (ev, handler) => {
|
|
33
|
+
if (ev === 'message')
|
|
34
|
+
wt.on('message', handler);
|
|
35
|
+
else if (ev === 'error')
|
|
36
|
+
wt.on('error', handler);
|
|
37
|
+
else if (ev === 'exit')
|
|
38
|
+
wt.on('exit', handler);
|
|
39
|
+
},
|
|
40
|
+
kill: () => wt.terminate()
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Отправляет внутрь воркера обхект способный к сериализации
|
|
46
|
+
*/
|
|
47
|
+
send(msg) {
|
|
48
|
+
this.impl.send(msg);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Подписывает на события воркера
|
|
52
|
+
*
|
|
53
|
+
* Доступно только message exit error
|
|
54
|
+
*/
|
|
55
|
+
on(event, handler) {
|
|
56
|
+
this.impl.on(event, handler);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Убивает процесс
|
|
60
|
+
*/
|
|
61
|
+
kill() {
|
|
62
|
+
this.impl.kill();
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* @see kill
|
|
66
|
+
*/
|
|
67
|
+
terminate() {
|
|
68
|
+
this.impl.kill();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.default = UniversalWorker;
|
|
72
|
+
/**
|
|
73
|
+
* Определяет - является ли процесс форкнутым
|
|
74
|
+
* Основанно на проверке метода process.send которая есть только у фокрнутого процесса
|
|
75
|
+
*/
|
|
76
|
+
exports.isForked = typeof process.send === 'function';
|
|
77
|
+
/**
|
|
78
|
+
* Определяет - является ли данный инстанс дочерним - не важно используя worker_threads или fork
|
|
79
|
+
* Проверяет !isMainThread || isForked
|
|
80
|
+
*/
|
|
81
|
+
exports.isChild = !worker_threads_1.isMainThread || exports.isForked;
|
|
82
|
+
/**
|
|
83
|
+
* Получение данных сверху, которые были переданны при создании воркера
|
|
84
|
+
* В случае использования worker_threads - workerData
|
|
85
|
+
* Если же это форк - парсит устаноленнюу переменную окружения VRACK2_WORKER_DATA
|
|
86
|
+
*/
|
|
87
|
+
function getWorkerData() {
|
|
88
|
+
if (!worker_threads_1.isMainThread)
|
|
89
|
+
return worker_threads_1.workerData;
|
|
90
|
+
if (exports.isForked)
|
|
91
|
+
return JSON.parse(process.env.VRACK2_WORKER_DATA || '{}');
|
|
92
|
+
throw new Error('getWorkerData() called in main process');
|
|
93
|
+
}
|
|
94
|
+
exports.getWorkerData = getWorkerData;
|
|
95
|
+
/**
|
|
96
|
+
* Отправка данных наверх в родительский процесс
|
|
97
|
+
*/
|
|
98
|
+
function sendMessage(message) {
|
|
99
|
+
if (!worker_threads_1.isMainThread)
|
|
100
|
+
return worker_threads_1.parentPort?.postMessage(message);
|
|
101
|
+
if (exports.isForked) {
|
|
102
|
+
process.send?.(message);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
throw new Error('sendMessage() called in main process');
|
|
106
|
+
}
|
|
107
|
+
exports.sendMessage = sendMessage;
|
|
108
|
+
/**
|
|
109
|
+
* Позволяет подписаться на данные которые приходят сверху
|
|
110
|
+
*/
|
|
111
|
+
function onMessage(handler) {
|
|
112
|
+
if (!worker_threads_1.isMainThread)
|
|
113
|
+
worker_threads_1.parentPort?.on('message', handler);
|
|
114
|
+
else if (exports.isForked)
|
|
115
|
+
process.on('message', handler);
|
|
116
|
+
else
|
|
117
|
+
throw new Error('onMessage() called in main process');
|
|
118
|
+
}
|
|
119
|
+
exports.onMessage = onMessage;
|
package/lib/Utility.js
CHANGED
|
@@ -3,15 +3,6 @@
|
|
|
3
3
|
* Copyright © 2025 Boris Bobylev. All rights reserved.
|
|
4
4
|
* Licensed under the Apache License, Version 2.0
|
|
5
5
|
*/
|
|
6
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
7
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
8
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
9
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
10
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
11
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
12
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13
|
-
});
|
|
14
|
-
};
|
|
15
6
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
8
|
};
|
|
@@ -21,10 +12,8 @@ class Utility {
|
|
|
21
12
|
/**
|
|
22
13
|
* Check device name (device ID)
|
|
23
14
|
* */
|
|
24
|
-
static isDeviceName(name) {
|
|
25
|
-
return
|
|
26
|
-
return /^[a-zA-Z0-9_*-:]+$/.test(name);
|
|
27
|
-
});
|
|
15
|
+
static async isDeviceName(name) {
|
|
16
|
+
return /^[a-zA-Z0-9_*-:]+$/.test(name);
|
|
28
17
|
}
|
|
29
18
|
/**
|
|
30
19
|
* Форматирует любое значение в красивую строку (с отступами, подсветкой и т. д.).
|
|
@@ -35,8 +24,15 @@ class Utility {
|
|
|
35
24
|
* @returns {string} Отформатированная строка
|
|
36
25
|
*/
|
|
37
26
|
static prettyFormat(value, options = {}) {
|
|
38
|
-
const defaultOptions =
|
|
39
|
-
|
|
27
|
+
const defaultOptions = {
|
|
28
|
+
depth: null,
|
|
29
|
+
colors: true,
|
|
30
|
+
compact: false,
|
|
31
|
+
breakLength: 80,
|
|
32
|
+
sorted: false,
|
|
33
|
+
showHidden: false,
|
|
34
|
+
...options // Переопределение дефолтных опций
|
|
35
|
+
};
|
|
40
36
|
// Особые случаи (если нужно обработать их по-особому)
|
|
41
37
|
if (value instanceof Error) {
|
|
42
38
|
return value.stack; // Стек ошибки
|
package/lib/boot/BootClass.js
CHANGED
|
@@ -3,15 +3,6 @@
|
|
|
3
3
|
* Copyright © 2024 Boris Bobylev. All rights reserved.
|
|
4
4
|
* Licensed under the Apache License, Version 2.0
|
|
5
5
|
*/
|
|
6
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
7
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
8
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
9
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
10
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
11
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
12
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13
|
-
});
|
|
14
|
-
};
|
|
15
6
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
8
|
};
|
|
@@ -88,9 +79,7 @@ class BootClass {
|
|
|
88
79
|
* the bootstrap loader will wait for the execution of all
|
|
89
80
|
* the `processPromise` methods of all bootstrap classes.
|
|
90
81
|
*/
|
|
91
|
-
processPromise() {
|
|
92
|
-
return __awaiter(this, void 0, void 0, function* () { return; });
|
|
93
|
-
}
|
|
82
|
+
async processPromise() { return; }
|
|
94
83
|
/**
|
|
95
84
|
* Method for calling container system errors
|
|
96
85
|
*/
|
|
@@ -3,15 +3,6 @@
|
|
|
3
3
|
* Copyright © 2024 Boris Bobylev. All rights reserved.
|
|
4
4
|
* Licensed under the Apache License, Version 2.0
|
|
5
5
|
*/
|
|
6
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
7
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
8
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
9
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
10
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
11
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
12
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13
|
-
});
|
|
14
|
-
};
|
|
15
6
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
8
|
};
|
|
@@ -65,17 +56,15 @@ class DeviceFileStorage extends BootClass_1.default {
|
|
|
65
56
|
* @param deviceId Device ID
|
|
66
57
|
* @returns {any} Imported JSON
|
|
67
58
|
*/
|
|
68
|
-
loadDeviceStorage(deviceId) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (!fs_1.default.existsSync(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return ImportManager_1.default.importJSON(fp);
|
|
78
|
-
});
|
|
59
|
+
async loadDeviceStorage(deviceId) {
|
|
60
|
+
const fp = this.makeDeviceStoragePath(deviceId);
|
|
61
|
+
const fptmp = this.makeDeviceStoragePath(deviceId, '-tmp');
|
|
62
|
+
if (!fs_1.default.existsSync(fp)) {
|
|
63
|
+
if (!fs_1.default.existsSync(fptmp))
|
|
64
|
+
return {};
|
|
65
|
+
fs_1.default.renameSync(fptmp, fp);
|
|
66
|
+
}
|
|
67
|
+
return ImportManager_1.default.importJSON(fp);
|
|
79
68
|
}
|
|
80
69
|
/**
|
|
81
70
|
* Save data device to storage
|
|
@@ -85,19 +74,17 @@ class DeviceFileStorage extends BootClass_1.default {
|
|
|
85
74
|
* @param deviceId Device ID
|
|
86
75
|
* @param trace Data object for storage
|
|
87
76
|
*/
|
|
88
|
-
saveDeviceStorage(deviceId, trace) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
fs_1.default.renameSync(fptmp, fp);
|
|
100
|
-
});
|
|
77
|
+
async saveDeviceStorage(deviceId, trace) {
|
|
78
|
+
const fp = this.makeDeviceStoragePath(deviceId);
|
|
79
|
+
const dp = path_1.default.join(this.options.storageDir, this.Container.id);
|
|
80
|
+
const fptmp = this.makeDeviceStoragePath(deviceId, '-tmp');
|
|
81
|
+
if (!fs_1.default.existsSync(dp)) {
|
|
82
|
+
fs_1.default.mkdirSync(dp, { recursive: true });
|
|
83
|
+
}
|
|
84
|
+
fs_1.default.writeFileSync(fptmp, JSON.stringify(trace));
|
|
85
|
+
if (fs_1.default.existsSync(fp))
|
|
86
|
+
fs_1.default.rmSync(fp);
|
|
87
|
+
fs_1.default.renameSync(fptmp, fp);
|
|
101
88
|
}
|
|
102
89
|
/**
|
|
103
90
|
* Forms the path to the storage file
|