mm_machine 2.8.1 → 2.8.2
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/index.js +189 -21
- package/package.json +4 -4
package/index.js
CHANGED
|
@@ -79,7 +79,17 @@ class Manager extends Mod {
|
|
|
79
79
|
* 作用域
|
|
80
80
|
* @type {string}
|
|
81
81
|
*/
|
|
82
|
-
scope: $.val && $.val.scope ? $.val.scope + '' : 'server'
|
|
82
|
+
scope: $.val && $.val.scope ? $.val.scope + '' : 'server',
|
|
83
|
+
/**
|
|
84
|
+
* 是否启用快照加速
|
|
85
|
+
* @type {boolean}
|
|
86
|
+
*/
|
|
87
|
+
use_snapshot: true,
|
|
88
|
+
/**
|
|
89
|
+
* 快照文件路径
|
|
90
|
+
* @type {string}
|
|
91
|
+
*/
|
|
92
|
+
snapshot_file: './snapshot.json'
|
|
83
93
|
};
|
|
84
94
|
|
|
85
95
|
/**
|
|
@@ -102,8 +112,6 @@ class Manager extends Mod {
|
|
|
102
112
|
this.infos = [];
|
|
103
113
|
// 模块
|
|
104
114
|
this.mods = mods;
|
|
105
|
-
// getList 缓存
|
|
106
|
-
this._list_cache = null;
|
|
107
115
|
if (Drive) {
|
|
108
116
|
this.Drive = Drive;
|
|
109
117
|
}
|
|
@@ -156,7 +164,6 @@ Manager.prototype.newInfo = function (name, sort, state, file = '') {
|
|
|
156
164
|
* @param {object} info 模块信息
|
|
157
165
|
*/
|
|
158
166
|
Manager.prototype.setInfo = function (info) {
|
|
159
|
-
this._list_cache = null;
|
|
160
167
|
let has = false;
|
|
161
168
|
for (let i = 0; i < this.infos.length; i++) {
|
|
162
169
|
let o = this.infos[i];
|
|
@@ -176,17 +183,15 @@ Manager.prototype.setInfo = function (info) {
|
|
|
176
183
|
* @returns {object[]} 模块对象数组
|
|
177
184
|
*/
|
|
178
185
|
Manager.prototype.getList = function () {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
var mod = this.getMod(info.name);
|
|
186
|
+
let list = [];
|
|
187
|
+
for (let i = 0; i < this.infos.length; i++) {
|
|
188
|
+
let info = this.infos[i];
|
|
189
|
+
let mod = this.getMod(info.name);
|
|
184
190
|
if (mod) {
|
|
185
191
|
mod.config.state = info.state;
|
|
186
192
|
}
|
|
187
193
|
list.push(mod);
|
|
188
194
|
}
|
|
189
|
-
this._list_cache = list;
|
|
190
195
|
return list;
|
|
191
196
|
};
|
|
192
197
|
|
|
@@ -215,7 +220,6 @@ Manager.prototype.Drive = Drive;
|
|
|
215
220
|
* 更新模块信息
|
|
216
221
|
*/
|
|
217
222
|
Manager.prototype.updateInfo = function () {
|
|
218
|
-
this._list_cache = null;
|
|
219
223
|
this.infos = [];
|
|
220
224
|
let mods = this.getMods();
|
|
221
225
|
for (let name in mods) {
|
|
@@ -242,7 +246,6 @@ Manager.prototype._sort = function () {
|
|
|
242
246
|
* 排序
|
|
243
247
|
*/
|
|
244
248
|
Manager.prototype.sort = function () {
|
|
245
|
-
this._list_cache = null;
|
|
246
249
|
this._sort();
|
|
247
250
|
};
|
|
248
251
|
|
|
@@ -251,7 +254,6 @@ Manager.prototype.sort = function () {
|
|
|
251
254
|
* 清除所有模块
|
|
252
255
|
*/
|
|
253
256
|
Manager.prototype.clearMods = function () {
|
|
254
|
-
this._list_cache = null;
|
|
255
257
|
for (let name in this.mods) {
|
|
256
258
|
delete this.mods[name];
|
|
257
259
|
}
|
|
@@ -263,7 +265,6 @@ Manager.prototype.clearMods = function () {
|
|
|
263
265
|
* @returns {object|null} 删除的模块对象
|
|
264
266
|
*/
|
|
265
267
|
Manager.prototype.delMod = function (name) {
|
|
266
|
-
this._list_cache = null;
|
|
267
268
|
let mod = this.mods[name];
|
|
268
269
|
if (mod) {
|
|
269
270
|
delete this.mods[name];
|
|
@@ -278,7 +279,6 @@ Manager.prototype.delMod = function (name) {
|
|
|
278
279
|
* @returns {object|null} 设置的模块对象
|
|
279
280
|
*/
|
|
280
281
|
Manager.prototype.setMod = function (name, mod) {
|
|
281
|
-
this._list_cache = null;
|
|
282
282
|
this.mods[name] = mod;
|
|
283
283
|
return this.getMod(name);
|
|
284
284
|
};
|
|
@@ -477,6 +477,149 @@ Manager.prototype._findFiles = async function (dir) {
|
|
|
477
477
|
return await $.file.getAllAsync(dir, this.config.filename);
|
|
478
478
|
};
|
|
479
479
|
|
|
480
|
+
/**
|
|
481
|
+
* 获取快照文件路径
|
|
482
|
+
* @returns {string} 快照文件完整路径
|
|
483
|
+
*/
|
|
484
|
+
Manager.prototype.getSnapshotPath = function () {
|
|
485
|
+
var snapshot_file = this.config.snapshot_file || './snapshot.json';
|
|
486
|
+
return snapshot_file.fullname(__dirname);
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* 保存快照数据
|
|
491
|
+
* @param {object} files_map 目录到文件列表的映射 { dir: [file_path, ...] }
|
|
492
|
+
*/
|
|
493
|
+
Manager.prototype._saveSnapshot = function (files_map) {
|
|
494
|
+
try {
|
|
495
|
+
var snapshot_path = this.getSnapshotPath();
|
|
496
|
+
var snapshot = {
|
|
497
|
+
files_map: files_map,
|
|
498
|
+
updated_at: Date.now()
|
|
499
|
+
};
|
|
500
|
+
snapshot_path.saveJson(snapshot);
|
|
501
|
+
} catch (err) {
|
|
502
|
+
this.log('error', '保存快照失败', err);
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* 加载快照数据
|
|
508
|
+
* @returns {object|null} 快照数据,不存在时返回null
|
|
509
|
+
*/
|
|
510
|
+
Manager.prototype._loadSnapshot = function () {
|
|
511
|
+
try {
|
|
512
|
+
var snapshot_path = this.getSnapshotPath();
|
|
513
|
+
if (!snapshot_path.hasFile()) {
|
|
514
|
+
return null;
|
|
515
|
+
}
|
|
516
|
+
var snapshot = snapshot_path.loadJson();
|
|
517
|
+
if (!snapshot || !snapshot.files_map) {
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
return snapshot;
|
|
521
|
+
} catch (err) {
|
|
522
|
+
this.log('error', '加载快照失败', err);
|
|
523
|
+
return null;
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* 从快照快速加载模块,不进行文件系统扫描
|
|
529
|
+
* @param {object} files_map 目录到文件列表的映射
|
|
530
|
+
* @param {boolean} clear 是否清除已有模块
|
|
531
|
+
*/
|
|
532
|
+
Manager.prototype._loadFromSnapshot = function (files_map, clear = true) {
|
|
533
|
+
if (clear) {
|
|
534
|
+
this.clearMods();
|
|
535
|
+
}
|
|
536
|
+
for (var dir in files_map) {
|
|
537
|
+
var files = files_map[dir];
|
|
538
|
+
if (files && files.length > 0) {
|
|
539
|
+
this.registerMods(files);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
this.updateInfo();
|
|
543
|
+
this.is_loaded = true;
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* 后台增量同步:扫描文件系统并与快照进行diff,增减模块
|
|
548
|
+
* @param {object} snapshot 快照数据
|
|
549
|
+
*/
|
|
550
|
+
Manager.prototype._syncFromFile = async function (snapshot) {
|
|
551
|
+
try {
|
|
552
|
+
var old_dirs = snapshot.files_map || {};
|
|
553
|
+
var old = this._buildSet(old_dirs);
|
|
554
|
+
|
|
555
|
+
// 扫描目录并注册新模块
|
|
556
|
+
for (var dir in old_dirs) {
|
|
557
|
+
var current = await this._findFiles(dir);
|
|
558
|
+
for (var fi = 0; fi < current.length; fi++) {
|
|
559
|
+
var f = current[fi];
|
|
560
|
+
if (!old[f]) {
|
|
561
|
+
this.registerMod(f);
|
|
562
|
+
this.log('info', '快照同步: 新增模块 ' + f);
|
|
563
|
+
}
|
|
564
|
+
old[f] = false;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// 移除已删除的模块
|
|
569
|
+
this._removeStale(old);
|
|
570
|
+
this.updateInfo();
|
|
571
|
+
await this._saveSnapshotDirs(Object.keys(old_dirs));
|
|
572
|
+
} catch (err) {
|
|
573
|
+
this.log('error', '快照增量同步失败', err);
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* 构建文件集合
|
|
579
|
+
* @param {object} dirs 目录到文件列表的映射
|
|
580
|
+
* @returns {object} 文件集合 { file: true }
|
|
581
|
+
*/
|
|
582
|
+
Manager.prototype._buildSet = function (dirs) {
|
|
583
|
+
var set = {};
|
|
584
|
+
for (var dir in dirs) {
|
|
585
|
+
var files = dirs[dir];
|
|
586
|
+
for (var i = 0; i < files.length; i++) {
|
|
587
|
+
set[files[i]] = true;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return set;
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* 移除已删除的模块
|
|
595
|
+
* @param {object} old 旧文件集合,标记为false表示仍存在
|
|
596
|
+
*/
|
|
597
|
+
Manager.prototype._removeStale = function (old) {
|
|
598
|
+
for (var file in old) {
|
|
599
|
+
if (old[file] === true) {
|
|
600
|
+
var mod = this.getMod(file);
|
|
601
|
+
if (mod) {
|
|
602
|
+
this.unloadMod(mod.config.name);
|
|
603
|
+
this.delMod(mod.config.name);
|
|
604
|
+
this.log('info', '快照同步: 移除模块 ' + file);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* 保存快照目录
|
|
612
|
+
* @param {string[]} dirs 目录列表
|
|
613
|
+
*/
|
|
614
|
+
Manager.prototype._saveSnapshotDirs = async function (dirs) {
|
|
615
|
+
var new_dirs = {};
|
|
616
|
+
for (var i = 0; i < dirs.length; i++) {
|
|
617
|
+
var dir = dirs[i];
|
|
618
|
+
new_dirs[dir] = await this._findFiles(dir);
|
|
619
|
+
}
|
|
620
|
+
this._saveSnapshot(new_dirs);
|
|
621
|
+
};
|
|
622
|
+
|
|
480
623
|
/**
|
|
481
624
|
* 加载所有模块的脚本
|
|
482
625
|
*/
|
|
@@ -514,8 +657,9 @@ Manager.prototype.update = async function (dir, clear = true) {
|
|
|
514
657
|
this.clearMods();
|
|
515
658
|
}
|
|
516
659
|
|
|
660
|
+
var search_dir = dir || this.config.dir;
|
|
517
661
|
// 查找所有json文件
|
|
518
|
-
|
|
662
|
+
var files = await this._findFiles(search_dir);
|
|
519
663
|
// 批量注册模块
|
|
520
664
|
this.registerMods(files);
|
|
521
665
|
// 更新配置信息
|
|
@@ -634,14 +778,38 @@ Manager.prototype.getDir = function () {
|
|
|
634
778
|
* 加载资源
|
|
635
779
|
*/
|
|
636
780
|
Manager.prototype._loadSources = async function () {
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
781
|
+
var base_dir = this.getBaseDir();
|
|
782
|
+
var dir = this.getDir();
|
|
783
|
+
|
|
784
|
+
// 启用快照加速时,优先从快照加载
|
|
785
|
+
if (this.config.use_snapshot) {
|
|
786
|
+
var snapshot = this._loadSnapshot();
|
|
787
|
+
if (snapshot) {
|
|
788
|
+
// 快照存在,快速加载模块
|
|
789
|
+
this._loadFromSnapshot(snapshot.files_map);
|
|
790
|
+
this.log('info', '已从快照快速加载模块,正在后台同步文件变更...');
|
|
791
|
+
// 异步增量同步,不阻塞启动
|
|
792
|
+
this._syncFromFile(snapshot);
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// 无快照时走正常流程
|
|
640
798
|
if (base_dir) {
|
|
641
|
-
await this.call('update', base_dir);
|
|
799
|
+
await this.call('update', base_dir, true);
|
|
642
800
|
await this.call('update', dir, false);
|
|
643
801
|
} else {
|
|
644
|
-
await this.call('update', dir);
|
|
802
|
+
await this.call('update', dir, true);
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
// 首次扫描后保存快照
|
|
806
|
+
if (this.config.use_snapshot) {
|
|
807
|
+
var files_map = {};
|
|
808
|
+
if (base_dir) {
|
|
809
|
+
files_map[base_dir] = await this._findFiles(base_dir);
|
|
810
|
+
}
|
|
811
|
+
files_map[dir] = await this._findFiles(dir);
|
|
812
|
+
this._saveSnapshot(files_map);
|
|
645
813
|
}
|
|
646
814
|
};
|
|
647
815
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mm_machine",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.2",
|
|
4
4
|
"description": "A flexible Node.js plugin mechanism system for dynamic loading, management and execution of modules. Supports hot reload, lifecycle management, and modern JavaScript features.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@prettier/sync": "^0.6.1",
|
|
37
|
-
"mm_config": "^2.4.
|
|
38
|
-
"mm_hot_reload": "^1.
|
|
39
|
-
"mm_tpl": "^2.6.
|
|
37
|
+
"mm_config": "^2.4.3",
|
|
38
|
+
"mm_hot_reload": "^1.4.0",
|
|
39
|
+
"mm_tpl": "^2.6.2"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"eslint": "^10.6.0",
|