electron-easymvc 1.0.5 → 1.0.7

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.
@@ -1,4674 +1,2 @@
1
- 'use strict';
2
-
3
- require('bytenode');
4
- var require$$0$1 = require('debug');
5
- var require$$1 = require('path');
6
- var require$$2 = require('dayjs');
7
- var require$$1$3 = require('egg-logger');
8
- var require$$1$1 = require('is-type-of');
9
- var require$$0 = require('fs');
10
- var require$$4 = require('module');
11
- var require$$1$2 = require('assert');
12
- var require$$9 = require('electron');
13
- var require$$0$2 = require('os');
14
- var require$$3 = require('child_process');
15
- var require$$4$1 = require('crypto');
16
- var require$$2$1 = require('mkdirp');
17
- var require$$0$3 = require('events');
18
- require('koa-convert');
19
- require('chalk');
20
- var require$$2$2 = require('cross-spawn');
21
- var require$$10 = require('tree-kill');
22
- var require$$0$4 = require('net');
23
- var require$$3$1 = require('axios');
24
- var require$$4$2 = require('globby');
25
- var require$$2$3 = require('socket.io');
26
- var require$$1$4 = require('socket.io-client');
27
- var require$$3$2 = require('koa');
28
- var require$$4$3 = require('koa2-cors');
29
- var require$$5 = require('koa-body');
30
- var require$$6 = require('https');
31
- var require$$9$1 = require('lodash');
32
- var require$$3$3 = require('better-sqlite3');
33
- var require$$2$4 = require('serialize-javascript');
34
-
35
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
36
-
37
- var require$$0__default$1 = /*#__PURE__*/_interopDefault(require$$0$1);
38
- var require$$1__default = /*#__PURE__*/_interopDefault(require$$1);
39
- var require$$2__default = /*#__PURE__*/_interopDefault(require$$2);
40
- var require$$1__default$3 = /*#__PURE__*/_interopDefault(require$$1$3);
41
- var require$$1__default$1 = /*#__PURE__*/_interopDefault(require$$1$1);
42
- var require$$0__default = /*#__PURE__*/_interopDefault(require$$0);
43
- var require$$4__default = /*#__PURE__*/_interopDefault(require$$4);
44
- var require$$1__default$2 = /*#__PURE__*/_interopDefault(require$$1$2);
45
- var require$$9__default = /*#__PURE__*/_interopDefault(require$$9);
46
- var require$$0__default$2 = /*#__PURE__*/_interopDefault(require$$0$2);
47
- var require$$3__default = /*#__PURE__*/_interopDefault(require$$3);
48
- var require$$4__default$1 = /*#__PURE__*/_interopDefault(require$$4$1);
49
- var require$$2__default$1 = /*#__PURE__*/_interopDefault(require$$2$1);
50
- var require$$0__default$3 = /*#__PURE__*/_interopDefault(require$$0$3);
51
- var require$$2__default$2 = /*#__PURE__*/_interopDefault(require$$2$2);
52
- var require$$10__default = /*#__PURE__*/_interopDefault(require$$10);
53
- var require$$0__default$4 = /*#__PURE__*/_interopDefault(require$$0$4);
54
- var require$$3__default$1 = /*#__PURE__*/_interopDefault(require$$3$1);
55
- var require$$4__default$2 = /*#__PURE__*/_interopDefault(require$$4$2);
56
- var require$$2__default$3 = /*#__PURE__*/_interopDefault(require$$2$3);
57
- var require$$1__default$4 = /*#__PURE__*/_interopDefault(require$$1$4);
58
- var require$$3__default$2 = /*#__PURE__*/_interopDefault(require$$3$2);
59
- var require$$4__default$3 = /*#__PURE__*/_interopDefault(require$$4$3);
60
- var require$$5__default = /*#__PURE__*/_interopDefault(require$$5);
61
- var require$$6__default = /*#__PURE__*/_interopDefault(require$$6);
62
- var require$$9__default$1 = /*#__PURE__*/_interopDefault(require$$9$1);
63
- var require$$3__default$3 = /*#__PURE__*/_interopDefault(require$$3$3);
64
- var require$$2__default$4 = /*#__PURE__*/_interopDefault(require$$2$4);
65
-
66
- function getDefaultExportFromCjs (x) {
67
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
68
- }
69
-
70
- const hasOwn = Object.prototype.hasOwnProperty;
71
- const toStr = Object.prototype.toString;
72
-
73
- function isPlainObject(obj) {
74
- if (!obj || toStr.call(obj) !== '[object Object]') {
75
- return false;
76
- }
77
-
78
- var hasOwnConstructor = hasOwn.call(obj, 'constructor');
79
- var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');
80
- // Not own constructor property must be Object
81
- if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {
82
- return false;
83
- }
84
-
85
- // Own properties are enumerated firstly, so to speed up,
86
- // if last one is own, then all properties are own.
87
- var key;
88
- for (key in obj) { /**/ }
89
-
90
- return typeof key === 'undefined' || hasOwn.call(obj, key);
91
- }
92
- function extend$6() {
93
- var options, name, src, copy, clone;
94
- var target = arguments[0];
95
- var i = 1;
96
- var length = arguments.length;
97
- var deep = false;
98
-
99
- // Handle a deep copy situation
100
- if (typeof target === 'boolean') {
101
- deep = target;
102
- target = arguments[1] || {};
103
- // skip the boolean and the target
104
- i = 2;
105
- } else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) {
106
- target = {};
107
- }
108
-
109
- for (; i < length; ++i) {
110
- options = arguments[i];
111
- // Only deal with non-null/undefined values
112
- if (options == null) continue;
113
-
114
- // Extend the base object
115
- for (name in options) {
116
- if (name === '__proto__') continue;
117
-
118
- src = target[name];
119
- copy = options[name];
120
-
121
- // Prevent never-ending loop
122
- if (target === copy) continue;
123
-
124
- // Recurse if we're merging plain objects
125
- if (deep && copy && isPlainObject(copy)) {
126
- clone = src && isPlainObject(src) ? src : {};
127
- // Never move original objects, clone them
128
- target[name] = extend$6(deep, clone, copy);
129
-
130
- // Don't bring in undefined values
131
- } else if (typeof copy !== 'undefined') {
132
- target[name] = copy;
133
- }
134
- }
135
- }
136
-
137
- // Return the modified object
138
- return target;
139
- }
140
- var extend_1 = {
141
- extend: extend$6};
142
-
143
- // Checks if we are in renderer process
144
- function renderer () {
145
- return process.type === 'renderer'
146
- }
147
-
148
- // Checks if we are in main process
149
- function main() {
150
- return process.type === 'browser'
151
- }
152
-
153
- // Checks if we are under Mac OS
154
- function osx() {
155
- return process.platform === 'darwin'
156
- }
157
-
158
- // Checks if we are under Mac OS
159
- function macOS() {
160
- return osx()
161
- }
162
-
163
- // Checks if we are under Windows OS
164
- function windows() {
165
- return process.platform === 'win32'
166
- }
167
-
168
- // Checks if we are under Linux OS
169
- function linux() {
170
- return process.platform === 'linux'
171
- }
172
-
173
- // Checks if we are the processor's arch is x86
174
- function x86() {
175
- return process.arch === 'ia32'
176
- }
177
-
178
- // Checks if we are the processor's arch is x64
179
- function x64() {
180
- return process.arch === 'x64'
181
- }
182
-
183
- // Checks if the app is running in a sandbox on macOS
184
- function sandbox() {
185
- return 'APP_SANDBOX_CONTAINER_ID' in process.env
186
- }
187
-
188
- // Checks if the app is running as a Mac App Store build
189
- function mas() {
190
- return process.mas === true
191
- }
192
-
193
- // Checks if the app is running as a Windows Store (appx) build
194
- function windowsStore() {
195
- return process.windowsStore === true
196
- }
197
-
198
- // checks if all the 'is functions' passed as arguments are true
199
- function all() {
200
- const isFunctions = new Array(arguments.length);
201
- for (var i = 0; i < isFunctions.length; i++) {
202
- isFunctions[i] = arguments[i];
203
- }
204
- if (!isFunctions.length) return
205
- for (i = 0; i < isFunctions.length; i++) {
206
- if (!isFunctions[i]()) return false
207
- }
208
- return true
209
- }
210
-
211
- // checks if all the 'is functions' passed as arguments are false
212
- function none() {
213
- const isFunctions = new Array(arguments.length);
214
- for (var i = 0; i < isFunctions.length; i++) {
215
- isFunctions[i] = arguments[i];
216
- }
217
- if (!isFunctions.length) return
218
- for (i = 0; i < isFunctions.length; i++) {
219
- if (isFunctions[i]()) return false
220
- }
221
- return true
222
- }
223
-
224
- // returns true if one of the 'is functions' passed as argument is true
225
- function one() {
226
- const isFunctions = new Array(arguments.length);
227
- for (var i = 0; i < isFunctions.length; i++) {
228
- isFunctions[i] = arguments[i];
229
- }
230
- if (!isFunctions.length) return
231
- for (i = 0; i < isFunctions.length; i++) {
232
- if (isFunctions[i]()) return true
233
- }
234
- return false
235
- }
236
-
237
- var is$b = {
238
- renderer,
239
- main,
240
- osx,
241
- macOS,
242
- windows,
243
- linux,
244
- x86,
245
- x64,
246
- sandbox,
247
- mas,
248
- windowsStore,
249
- all,
250
- none,
251
- one,
252
- };
253
-
254
- const path$e = require$$1__default.default;
255
- const is$a = is$b;
256
-
257
- // 当前进程的所有env
258
- function allEnv$1() {
259
- return process.env;
260
- }
261
-
262
- // 当前环境 - local | prod
263
- function env$4() {
264
- return process.env.EE_ENV;
265
- }
266
-
267
- // 是否生产环境
268
- function isProd() {
269
- return (process.env.EE_ENV === 'prod');
270
- }
271
-
272
- // 是否为开发环境
273
- function isDev$4() {
274
- if (process.env.EE_ENV === 'dev' || process.env.EE_ENV === 'local') {
275
- return true;
276
- }
277
-
278
- return false;
279
- }
280
- // 是否为渲染进程
281
- function isRenderer$1() {
282
- return (typeof process === 'undefined' ||
283
- !process ||
284
- process.type === 'renderer');
285
- }
286
- // 是否为主进程
287
- function isMain$1() {
288
- return ( typeof process !== 'undefined' &&
289
- process.type === 'browser');
290
- }
291
- // 是否为node子进程
292
- function isForkedChild$1() {
293
- return (Number(process.env.ELECTRON_RUN_AS_NODE) === 1);
294
- }
295
- // 当前进程类型
296
- function processType() {
297
- let type = '';
298
- if (isMain$1()) {
299
- type = 'browser';
300
- } else if (isRenderer$1()) {
301
- type = 'renderer';
302
- } else if (isForkedChild$1()) {
303
- type = 'child';
304
- }
305
-
306
- return type;
307
- }
308
- // app name
309
- function appName$1() {
310
- return process.env.EE_APP_NAME;
311
- }
312
-
313
- // app version
314
- function appVersion() {
315
- return process.env.EE_APP_VERSION;
316
- }
317
-
318
- // 获取数据存储路径
319
- function getDataDir$2() {
320
- const base = isDev$4() ? getBaseDir$7() : getUserHomeHiddenAppDir$1();
321
- const dataDir = path$e.join(base, 'data');
322
- return dataDir;
323
- }
324
-
325
- // 获取日志存储路径
326
- function getLogDir$3() {
327
- const base = isDev$4() ? getBaseDir$7() : getUserHomeHiddenAppDir$1();
328
- const dir = path$e.join(base, 'logs');
329
- return dir;
330
- }
331
-
332
- // 获取bundle文件路径
333
- function getBundleDir$1(basePath) {
334
- const base = basePath || process.cwd();
335
- const dir = path$e.join(base, 'public', 'electron');
336
- return dir;
337
- }
338
-
339
- // 获取electron 源码文件路径
340
- function getElectronCodeDir$1(basePath) {
341
- const base = basePath || process.cwd();
342
- const dir = path$e.join(base, 'electron');
343
- return dir;
344
- }
345
-
346
- // 获取frontend 源码文件路径
347
- function getFrontendCodeDir(basePath) {
348
- const base = basePath || process.cwd();
349
- const dir = path$e.join(base, 'frontend');
350
- return dir;
351
- }
352
-
353
- // 获取base目录
354
- function getBaseDir$7() {
355
- return process.env.EE_BASE_DIR;
356
- }
357
-
358
- // 获取electron目录
359
- function getElectronDir$3() {
360
- return process.env.EE_ELECTRON_DIR;
361
- }
362
-
363
- // 获取public目录
364
- function getPublicDir() {
365
- const dir = path$e.join(getBaseDir$7(), "public");
366
- return dir;
367
- }
368
-
369
- // 获取 额外资源目录
370
- function getExtraResourcesDir$1() {
371
- const execDir = getExecDir();
372
- const packaged = isPackaged$2();
373
-
374
- // 资源路径不同
375
- let dir = '';
376
- if (packaged) {
377
- // 打包后 execDir为 应用程序 exe\dmg\dep软件所在目录;打包前该值是项目根目录
378
- // windows和MacOs不一样
379
- dir = path$e.join(execDir, "resources", "extraResources");
380
- if (is$a.macOS()) {
381
- dir = path$e.join(execDir, "..", "Resources", "extraResources");
382
- }
383
- } else {
384
- // 打包前
385
- dir = path$e.join(execDir, "build", "extraResources");
386
- }
387
- return dir;
388
- }
389
-
390
- // 获取root目录 (dev-项目根目录,pro-app user data目录)
391
- function getRootDir$1() {
392
- const appDir = isDev$4() ? getBaseDir$7() : getAppUserDataDir();
393
- return appDir;
394
- }
395
-
396
- // 获取 appUserData目录
397
- function getAppUserDataDir() {
398
- return process.env.EE_APP_USER_DATA;
399
- }
400
-
401
- // 获取 exec目录
402
- function getExecDir() {
403
- return process.env.EE_EXEC_DIR;
404
- }
405
-
406
- // 获取操作系统用户目录
407
- function getUserHomeDir() {
408
- return process.env.EE_USER_HOME;
409
- }
410
-
411
- // 获取用户家目录中的隐藏的app目录
412
- function getUserHomeHiddenAppDir$1() {
413
- const appnameDir = "." + appName$1();
414
- const dir = path$e.join(getUserHomeDir(), appnameDir);
415
- return dir;
416
- }
417
-
418
- // 获取用户家目录中的app目录
419
- function getUserHomeAppDir() {
420
- const appnameDir = appName$1();
421
- const dir = path$e.join(getUserHomeDir(), appnameDir);
422
- return dir;
423
- }
424
-
425
- // 获取内置socket端口
426
- function getSocketPort() {
427
- return parseInt(process.env.EE_SOCKET_PORT) || 0;
428
- }
429
-
430
- // 获取内置http端口
431
- function getHttpPort() {
432
- return parseInt(process.env.EE_HTTP_PORT) || 0;
433
- }
434
-
435
- // 是否打包
436
- function isPackaged$2() {
437
- return process.env.EE_IS_PACKAGED === 'true';
438
- }
439
-
440
- // 进程退出
441
- function exit(code = 0) {
442
- return process.exit(code);
443
- }
444
-
445
- // 格式化message
446
- function makeMessage(msg = {}) {
447
- let message = Object.assign({
448
- channel: '',
449
- event: '',
450
- data: {}
451
- }, msg);
452
-
453
- return message;
454
- }
455
-
456
- // 退出ChildJob进程
457
- function exitChildJob(code = 0) {
458
- try {
459
- let args = JSON.parse(process.argv[2]);
460
- if (args.type == 'childJob') {
461
- process.exit(code);
462
- }
463
- } catch (e) {
464
- process.exit(code);
465
- }
466
- }
467
-
468
- // 任务类型 ChildJob
469
- function isChildJob() {
470
- try {
471
- let args = JSON.parse(process.argv[2]);
472
- if (args.type == 'childJob') {
473
- return true;
474
- }
475
- } catch (e) {
476
- return false;
477
- }
478
- }
479
-
480
- // 任务类型 ChildPoolJob
481
- function isChildPoolJob() {
482
- try {
483
- let args = JSON.parse(process.argv[2]);
484
- if (args.type == 'childPoolJob') {
485
- return true;
486
- }
487
- } catch (e) {
488
- return false;
489
- }
490
- }
491
-
492
- // Get cmd parameter by name
493
- function getArgumentByName$1(name, args) {
494
- if (!args) {
495
- args = process.argv;
496
- }
497
- for (let i = 0; i < args.length; i++) {
498
- const item = args[i];
499
- const prefixKey = `--${name}=`;
500
- if (item.indexOf(prefixKey) !== -1) {
501
- return item.substring(prefixKey.length);
502
- }
503
- }
504
- }
505
-
506
- var ps = {
507
- allEnv: allEnv$1,
508
- env: env$4,
509
- isProd,
510
- isDev: isDev$4,
511
- isRenderer: isRenderer$1,
512
- isMain: isMain$1,
513
- isForkedChild: isForkedChild$1,
514
- processType,
515
- appName: appName$1,
516
- appVersion,
517
- getDataDir: getDataDir$2,
518
- getLogDir: getLogDir$3,
519
- getBundleDir: getBundleDir$1,
520
- getElectronCodeDir: getElectronCodeDir$1,
521
- getFrontendCodeDir,
522
- getRootDir: getRootDir$1,
523
- getBaseDir: getBaseDir$7,
524
- getElectronDir: getElectronDir$3,
525
- getPublicDir,
526
- getExtraResourcesDir: getExtraResourcesDir$1,
527
- getAppUserDataDir,
528
- getExecDir,
529
- getUserHomeDir,
530
- getUserHomeAppDir,
531
- getUserHomeHiddenAppDir: getUserHomeHiddenAppDir$1,
532
- getSocketPort,
533
- getHttpPort,
534
- isPackaged: isPackaged$2,
535
- exit,
536
- makeMessage,
537
- exitChildJob,
538
- isChildJob,
539
- isChildPoolJob,
540
- getArgumentByName: getArgumentByName$1
541
- };
542
-
543
- var utils$1 = {exports: {}};
544
-
545
- (function (module) {
546
-
547
-
548
- const is = require$$1__default$1.default;
549
- const path = require$$1__default.default;
550
- const fs = require$$0__default.default;
551
- const BuiltinModule = require$$4__default.default;
552
-
553
- // Guard against poorly mocked module constructors.
554
- const Module = module.constructor.length > 1
555
- ? module.constructor
556
- /* istanbul ignore next */
557
- : BuiltinModule;
558
-
559
- // Module._extensions:
560
- // '.js': [Function (anonymous)],
561
- // '.json': [Function (anonymous)],
562
- // '.node': [Function: func],
563
- // '.jsc': [Function (anonymous)]
564
-
565
- const extensions = Module._extensions;
566
-
567
- function loadFile(filepath) {
568
- try {
569
- // if not js module, just return content buffer
570
- const extname = path.extname(filepath);
571
- if (extname && !Module._extensions[extname]) {
572
- return fs.readFileSync(filepath);
573
- }
574
-
575
- // require js module
576
- const obj = require(filepath);
577
- if (!obj) return obj;
578
- // it's es module
579
- if (obj.__esModule) return 'default' in obj ? obj.default : obj;
580
- return obj;
581
- } catch (err) {
582
- err.message = `[electron-easymvc] load file: ${filepath}, error: ${err.message}`;
583
- throw err;
584
- }
585
- }
586
-
587
- async function callFn(fn, args, ctx) {
588
- args = args || [];
589
- if (!is.function(fn)) return;
590
- return ctx ? fn.call(ctx, ...args) : fn(...args);
591
- }
592
-
593
- function getResolvedFilename(filepath, baseDir) {
594
- const reg = /[/\\]/g;
595
- return filepath.replace(baseDir + path.sep, '').replace(reg, '/');
596
- }
597
-
598
- /**
599
- * 字节码类
600
- */
601
- function isBytecodeClass(exports$1) {
602
- let isClass = false;
603
-
604
- // 标识
605
- if (exports$1.toString().indexOf('[class') != -1) {
606
- isClass = true;
607
- }
608
-
609
- return isClass;
610
- }
611
-
612
- /**
613
- * 文件类型
614
- */
615
- function filePatterns() {
616
- const files = [ '**/*.js','**/*.jsc' ];
617
- return files;
618
- }
619
-
620
- module.exports = {
621
- extensions,
622
- loadFile,
623
- callFn,
624
- getResolvedFilename,
625
- isBytecodeClass,
626
- filePatterns,
627
- };
628
- } (utils$1));
629
-
630
- var utilsExports = utils$1.exports;
631
-
632
- const is$9 = require$$1__default$1.default;
633
- const fs$7 = require$$0__default.default;
634
- const path$d = require$$1__default.default;
635
- const CoreUtils = utilsExports;
636
- const { getElectronDir: getElectronDir$2 } = ps;
637
-
638
- // 加载单个文件(如果是函数,将被执行)
639
- function loadFile$3(filepath, ...inject) {
640
- let fullpath = filepath;
641
- const isAbsolute = path$d.isAbsolute(fullpath);
642
- if (!isAbsolute) {
643
- fullpath = path$d.join(getElectronDir$2(), fullpath);
644
- }
645
-
646
- fullpath = fullpath && resolveModule(fullpath);
647
- if (!fs$7.existsSync(fullpath)) {
648
- let errorMsg = `[electron-easymvc] [loader/index] loadFile ${filepath} does not exist`;
649
- throw new Error(errorMsg);
650
- }
651
-
652
- let ret = CoreUtils.loadFile(fullpath);
653
- if (is$9.function(ret) && !is$9.class(ret) && !CoreUtils.isBytecodeClass(ret)) {
654
- ret = ret(...inject);
655
- }
656
- return ret;
657
- }
658
-
659
- // requireFile
660
- function requireFile(filepath) {
661
- return CoreUtils.loadFile(filepath);
662
- }
663
-
664
- // 加载并运行文件
665
- function execFile(filepath, ...inject) {
666
- let ret = CoreUtils.loadFile(filepath);
667
- if (is$9.class(ret) || CoreUtils.isBytecodeClass(ret)) {
668
- ret = new ret(inject);
669
- } else if (is$9.function(ret)) {
670
- ret = ret(inject);
671
- }
672
-
673
- return ret;
674
- }
675
-
676
- // 模块的绝对路径
677
- function resolveModule(filepath) {
678
- let fullpath;
679
- try {
680
- fullpath = require.resolve(filepath);
681
- } catch (e) {
682
-
683
- // 特殊后缀处理
684
- if (filepath && (filepath.endsWith('.defalut') || filepath.endsWith('.prod'))) {
685
- fullpath = filepath + '.jsc';
686
- } else if (filepath && filepath.endsWith('.js')) {
687
- fullpath = filepath + 'c';
688
- }
689
-
690
- if (!fs$7.existsSync(filepath) && !fs$7.existsSync(fullpath)) {
691
- let files = { filepath, fullpath };
692
- console.warn(`[electron-easymvc] [loader] resolveModule unknow filepath: ${files}`);
693
- return undefined;
694
- }
695
- }
696
-
697
- return fullpath;
698
- }
699
-
700
- // 获取electron目录下文件的绝对路径
701
- function getFullpath$3(filepath) {
702
- let fullpath;
703
- const isAbsolute = path$d.isAbsolute(filepath);
704
- if (!isAbsolute) {
705
- filepath = path$d.join(getElectronDir$2(), filepath);
706
- }
707
-
708
- fullpath = resolveModule(filepath);
709
- if (!fs$7.existsSync(fullpath)) {
710
- throw new Error(`[electron-easymvc] [loader] getFullpath filepath ${filepath} not exists`);
711
- }
712
-
713
- return fullpath;
714
- }
715
-
716
- var loader = {
717
- loadFile: loadFile$3,
718
- execFile,
719
- requireFile,
720
- resolveModule,
721
- getFullpath: getFullpath$3,
722
- };
723
-
724
- const assert$3 = require$$1__default$2.default;
725
- const MAP = Symbol('Timing#map');
726
- const LIST = Symbol('Timing#list');
727
-
728
- let Timing$2 = class Timing {
729
-
730
- constructor() {
731
- this._enable = true;
732
- this[MAP] = new Map();
733
- this[LIST] = [];
734
-
735
- this.init();
736
- }
737
-
738
- init() {
739
- // process start time
740
- this.start('Process Start', Date.now() - Math.floor((process.uptime() * 1000)));
741
- this.end('Process Start');
742
-
743
- if (typeof process.scriptStartTime === 'number') {
744
- // js script start execute time
745
- this.start('Script Start', process.scriptStartTime);
746
- this.end('Script Start');
747
- }
748
- }
749
-
750
- start(name, start) {
751
- if (!name || !this._enable) return;
752
-
753
- if (this[MAP].has(name)) this.end(name);
754
-
755
- start = start || Date.now();
756
- const item = {
757
- name,
758
- start,
759
- end: undefined,
760
- duration: undefined,
761
- pid: process.pid,
762
- index: this[LIST].length,
763
- };
764
- this[MAP].set(name, item);
765
- this[LIST].push(item);
766
- return item;
767
- }
768
-
769
- end(name) {
770
- if (!name || !this._enable) return;
771
- assert$3(this[MAP].has(name), `should run timing.start('${name}') first`);
772
-
773
- const item = this[MAP].get(name);
774
- item.end = Date.now();
775
- item.duration = item.end - item.start;
776
- return item;
777
- }
778
-
779
- enable() {
780
- this._enable = true;
781
- }
782
-
783
- disable() {
784
- this._enable = false;
785
- }
786
-
787
- clear() {
788
- this[MAP].clear();
789
- this[LIST] = [];
790
- }
791
-
792
- toJSON() {
793
- return this[LIST];
794
- }
795
- };
796
-
797
- var timing = {
798
- Timing: Timing$2
799
- };
800
-
801
- const Processes$2 = {
802
- showException: 'ee#showException',
803
- sendToMain: 'ee#sendToMain'
804
- };
805
-
806
- const SocketIO$2 = {
807
- partySoftware: 'socket-channel',
808
- };
809
-
810
- const Events$5 = {
811
- childProcessExit: 'ee#childProcess#exit',
812
- childProcessError: 'ee#childProcess#error',
813
- };
814
-
815
- const Receiver$2 = {
816
- childJob: 'job',
817
- forkProcess: 'task',
818
- all: 'all'
819
- };
820
-
821
- var channel = {
822
- Processes: Processes$2,
823
- SocketIO: SocketIO$2,
824
- Events: Events$5,
825
- Receiver: Receiver$2
826
- };
827
-
828
- const path$c = require$$1__default.default;
829
- const { env: env$3, getBaseDir: getBaseDir$6, getLogDir: getLogDir$2 } = ps;
830
- const { SocketIO: SocketIO$1 } = channel;
831
-
832
- /**
833
- * default
834
- */
835
- var default_config = () => {
836
- return {
837
- openDevTools: false,
838
- singleLock: true,
839
- windowsOption: {
840
- title: 'electron-egg',
841
- width: 980,
842
- height: 650,
843
- minWidth: 400,
844
- minHeight: 300,
845
- webPreferences: {
846
- //webSecurity: false,
847
- contextIsolation: false, // false -> 可在渲染进程中使用electron的api,true->需要bridge.js(contextBridge)
848
- nodeIntegration: true,
849
- //preload: path.join(appInfo.electronDir, 'preload', 'bridge.js'),
850
- },
851
- frame: true,
852
- show: false,
853
- icon: path$c.join(getBaseDir$6(), 'public', 'images', 'logo-32.png'),
854
- },
855
- logger: {
856
- type: 'application',
857
- dir: getLogDir$2(),
858
- encoding: 'utf8',
859
- env: env$3(),
860
- level: 'INFO',
861
- consoleLevel: 'INFO',
862
- disableConsoleAfterReady: env$3() !== 'local',
863
- outputJSON: false,
864
- buffer: true,
865
- appLogName: `ee.log`,
866
- coreLogName: 'electron-easymvc.log',
867
- agentLogName: 'ee-agent.log',
868
- errorLogName: `ee-error.log`,
869
- coreLogger: {},
870
- allowDebugAtProd: false,
871
- enablePerformanceTimer: false,
872
- rotator: 'day',
873
- },
874
- socketServer: {
875
- enable: false, // is it enabled
876
- port: 7070, // default port (if the port is in use, randomly select one)
877
- path: "/socket.io/", // path
878
- connectTimeout: 45000, // client connection timeout
879
- pingTimeout: 30000, // heartbeat detection timeout
880
- pingInterval: 25000, // heartbeat detection interval
881
- maxHttpBufferSize: 1e8, // the data size of each message 1M
882
- transports: ["polling", "websocket"], // http polling or websocket
883
- cors: {
884
- origin: true, // http协议时,要设置跨域 类型 Boolean String RegExp Array Function
885
- },
886
- channel: SocketIO$1.partySoftware
887
- },
888
- httpServer: {
889
- enable: false, // Is it enabled
890
- https: {
891
- enable: false,
892
- key: '/public/ssl/localhost+1.key',
893
- cert: '/public/ssl/localhost+1.pem'
894
- },
895
- protocol: 'http://',
896
- host: '127.0.0.1',
897
- port: 7071, // Default port (if the port is in use, randomly select one)
898
- cors: {
899
- origin: "*"
900
- },
901
- body: {
902
- multipart: true,
903
- formidable: {
904
- keepExtensions: true
905
- }
906
- },
907
- filterRequest: {
908
- uris: [
909
- 'favicon.ico'
910
- ],
911
- returnData: ''
912
- }
913
- },
914
- remote: {
915
- enable: false,
916
- url: ''
917
- },
918
- mainServer: {
919
- protocol: 'file://', // file://
920
- indexPath: '/public/dist/index.html',
921
- options: {},
922
- takeover: '',
923
- loadingPage: '',
924
- channelSeparator: '/',
925
- },
926
- exception: {
927
- mainExit: false,
928
- childExit: false,
929
- rendererExit: true,
930
- },
931
- jobs: {
932
- messageLog: false
933
- },
934
- cross: {}
935
- }
936
- };
937
-
938
- const debug$8 = require$$0__default$1.default('electron-easymvc:config:config_loader');
939
- const path$b = require$$1__default.default;
940
- const { appName, env: env$2, getElectronDir: getElectronDir$1, getBaseDir: getBaseDir$5, getRootDir } = ps;
941
- const { extend: extend$5 } = extend_1;
942
- const { loadFile: loadFile$2 } = loader;
943
- const { Timing: Timing$1 } = timing;
944
- const defaultConfig = default_config;
945
-
946
- let ConfigLoader$1 = class ConfigLoader {
947
- constructor() {
948
- this.timing = new Timing$1();
949
- }
950
-
951
- /**
952
- * Load config/config.xxx.js
953
- */
954
- load() {
955
- this.timing.start('Load Config');
956
-
957
- // Load Application config
958
- const appConfig = this._AppConfig();
959
- // debug("[load] appConfig: %O", appConfig);
960
-
961
- const defaultConf = defaultConfig();
962
- const config = extend$5(true, defaultConf, appConfig);
963
- debug$8("[load] config: %o", config);
964
-
965
- this.timing.end('Load Config');
966
- return config;
967
- }
968
-
969
- _AppConfig() {
970
- const names = [
971
- 'config.default',
972
- `config.${env$2()}`,
973
- ];
974
- const target = {};
975
- for (const filename of names) {
976
- const config = this._loadConfig(getElectronDir$1(), filename);
977
- extend$5(true, target, config);
978
- }
979
- return target;
980
- }
981
-
982
- _loadConfig(dirpath, filename) {
983
- const appInfo = {
984
- name: appName(),
985
- baseDir: getBaseDir$5(),
986
- electronDir: getElectronDir$1(),
987
- env: env$2(),
988
- root: getRootDir(),
989
- };
990
- const filepath = path$b.join(dirpath, 'config', filename);
991
- const config = loadFile$2(filepath, appInfo);
992
- debug$8("[_loadConfig] filepath: %s", filepath);
993
- if (!config) return null;
994
-
995
- return config;
996
- }
997
- };
998
-
999
- var config_loader = {
1000
- ConfigLoader: ConfigLoader$1
1001
- };
1002
-
1003
- const { ConfigLoader } = config_loader;
1004
-
1005
- const Instance$4 = {
1006
- config: null,
1007
- };
1008
-
1009
- function loadConfig$1() {
1010
- const configLoader = new ConfigLoader();
1011
- Instance$4["config"] = configLoader.load();
1012
- return Instance$4["config"];
1013
- }
1014
-
1015
- function getConfig$a() {
1016
- if (!Instance$4["config"]) {
1017
- loadConfig$1();
1018
- } return Instance$4["config"];
1019
- }
1020
-
1021
- var config = {
1022
- loadConfig: loadConfig$1,
1023
- getConfig: getConfig$a,
1024
- };
1025
-
1026
- const debug$7 = require$$0__default$1.default('electron-easymvc:log:logger');
1027
- const Loggers = require$$1__default$3.default.EggLoggers;
1028
- const dayjs$1 = require$$2__default.default;
1029
- const path$a = require$$1__default.default;
1030
- const { extend: extend$4 } = extend_1;
1031
- const { getConfig: getConfig$9 } = config;
1032
- const { getLogDir: getLogDir$1, env: env$1, isDev: isDev$3 } = ps;
1033
-
1034
- let LogDate = 0;
1035
- const TmpFileName = {
1036
- appLogName: '',
1037
- coreLogName: '',
1038
- errorLogName: '',
1039
- };
1040
-
1041
- // 创建
1042
- function create$1(config = {}) {
1043
- let opt = {};
1044
-
1045
- if (Object.keys(config).length == 0) {
1046
- const defaultConfig = {
1047
- logger: {
1048
- type: 'application',
1049
- dir: getLogDir$1(),
1050
- env: env$1(),
1051
- consoleLevel: 'INFO',
1052
- disableConsoleAfterReady: !isDev$3(),
1053
- coreLogger: {},
1054
- allowDebugAtProd: false,
1055
- agentLogName: 'ee-agent.log',
1056
- rotator: 'day',
1057
- },
1058
- customLogger: {}
1059
- };
1060
- const sysConfig = getConfig$9();
1061
- opt = extend$4(true, defaultConfig, {
1062
- logger: sysConfig.logger,
1063
- customLogger: sysConfig.customLogger || {}
1064
- });
1065
- } else {
1066
- opt.logger = config.logger;
1067
- opt.customLogger = config.customLogger;
1068
- }
1069
-
1070
- if (Object.keys(opt).length == 0) {
1071
- throw new Error("logger config is null");
1072
- }
1073
-
1074
- let rotateType = opt.logger.rotator;
1075
- if (rotateType == 'day') {
1076
- opt = _rotateByDay(opt);
1077
- }
1078
-
1079
- debug$7('[create] opt:%j', opt);
1080
- const loggers = new Loggers(opt);
1081
-
1082
- return loggers;
1083
- }
1084
-
1085
- /**
1086
- * 按天分割
1087
- */
1088
- function _rotateByDay(logOpt) {
1089
- const now = parseInt(dayjs$1().format('YYYYMMDD'));
1090
- if (LogDate != now) {
1091
- LogDate = now;
1092
-
1093
- // 保存一个临时文件名,防止文件名按日期累加
1094
- if (TmpFileName.appLogName.length == 0) {
1095
- TmpFileName.appLogName = logOpt.logger.appLogName;
1096
- }
1097
- if (TmpFileName.coreLogName.length == 0) {
1098
- TmpFileName.coreLogName = logOpt.logger.coreLogName;
1099
- }
1100
- if (TmpFileName.errorLogName.length == 0) {
1101
- TmpFileName.errorLogName = logOpt.logger.errorLogName;
1102
- }
1103
-
1104
- const {appLogName, coreLogName, errorLogName} = TmpFileName;
1105
- const appLogExtname = path$a.extname(appLogName);
1106
- const coreLogExtname = path$a.extname(coreLogName);
1107
- const errorLogExtname = path$a.extname(errorLogName);
1108
- logOpt.logger.appLogName = path$a.basename(appLogName, appLogExtname) + '-' + now + appLogExtname;
1109
- logOpt.logger.coreLogName = path$a.basename(coreLogName, coreLogExtname) + '-' + now + coreLogExtname;
1110
- logOpt.logger.errorLogName = path$a.basename(errorLogName, errorLogExtname) + '-' + now + errorLogExtname;
1111
- }
1112
-
1113
- return logOpt;
1114
- }
1115
-
1116
- var logger = {
1117
- create: create$1
1118
- };
1119
-
1120
- const dayjs = require$$2__default.default;
1121
- const { create } = logger;
1122
-
1123
- const Instance$3 = {
1124
- eelog: null,
1125
- logger: {},
1126
- coreLogger: {},
1127
- };
1128
- let logDate = 0;
1129
- const logProperties = ['error', 'warn', 'info', 'debug'];
1130
-
1131
- // define logger/coreLogger properties
1132
- defineLoggerProperty();
1133
- defineCoreLoggerProperty();
1134
-
1135
- // Create a log instance
1136
- function createLog(config) {
1137
- _delCache();
1138
- const eeLog = create(config);
1139
-
1140
- return eeLog;
1141
- }
1142
-
1143
- function loadLog$1() {
1144
- Instance$3.eelog = createLog();
1145
- return Instance$3.eelog;
1146
- }
1147
-
1148
- function defineLoggerProperty() {
1149
- for (const property of logProperties) {
1150
- Object.defineProperty(Instance$3.logger, property, {
1151
- get() {
1152
- //console.log('emit logger property: ', property);
1153
- let log = getLogger();
1154
- let val = log[property].bind(log);
1155
- return val;
1156
- },
1157
- });
1158
- }
1159
- }
1160
-
1161
- function defineCoreLoggerProperty() {
1162
- for (const property of logProperties) {
1163
- Object.defineProperty(Instance$3.coreLogger, property, {
1164
- get() {
1165
- let log = getCoreLogger();
1166
- let val = log[property].bind(log);
1167
- return val;
1168
- },
1169
- });
1170
- }
1171
- }
1172
-
1173
- function _delCache() {
1174
- const now = parseInt(dayjs().format('YYYYMMDD'));
1175
- if (logDate != now) {
1176
- logDate = now;
1177
- Instance$3.eelog = null;
1178
- }
1179
- }
1180
-
1181
- function getLogger() {
1182
- _delCache();
1183
- if (!Instance$3.eelog) {
1184
- loadLog$1();
1185
- }
1186
-
1187
- return Instance$3.eelog["logger"];
1188
- }
1189
-
1190
- function getCoreLogger() {
1191
- _delCache();
1192
- if (!Instance$3.eelog) {
1193
- loadLog$1();
1194
- }
1195
- return Instance$3.eelog["coreLogger"];
1196
- }
1197
-
1198
- var log = {
1199
- createLog,
1200
- loadLog: loadLog$1,
1201
- logger: Instance$3.logger,
1202
- coreLogger: Instance$3.coreLogger
1203
- };
1204
-
1205
- const { Receiver: Receiver$1, Processes: Processes$1 } = channel;
1206
-
1207
- let ChildMessage$1 = class ChildMessage {
1208
-
1209
- // Send a message to the main process for ChildJob instance
1210
- sendToMain(eventName, params = {}) {
1211
- const receiver = Receiver$1.childJob;
1212
- return this.send(eventName, params, receiver);
1213
- }
1214
-
1215
- // Send a message to the main process for a task instance
1216
- send(eventName, params = {}, receiver) {
1217
- const eventReceiver = receiver || Receiver$1.forkProcess;
1218
- const message = {
1219
- channel: Processes$1.sendToMain,
1220
- eventReceiver,
1221
- event: eventName,
1222
- data: params,
1223
- };
1224
-
1225
- return process.send(message);
1226
- }
1227
-
1228
- exit(code = 0) {
1229
- return process.exit(code);
1230
- }
1231
-
1232
- sendErrorToTerminal(err) {
1233
- let errTips = (err && typeof err == 'object') ? err.toString() : '';
1234
- errTips += ' Error !!! Please See file electron-easymvc.log or easymvc-error-xxx.log for details !';
1235
- const message = {
1236
- channel: Processes$1.showException,
1237
- data: errTips
1238
- };
1239
- process.send(message);
1240
- }
1241
- };
1242
-
1243
- var childMessage$2 = {
1244
- ChildMessage: ChildMessage$1
1245
- };
1246
-
1247
- const { ChildMessage } = childMessage$2;
1248
-
1249
- const childMessage$1 = new ChildMessage();
1250
-
1251
- var message = {
1252
- ChildMessage,
1253
- childMessage: childMessage$1
1254
- };
1255
-
1256
- const { coreLogger: coreLogger$7 } = log;
1257
- const { isForkedChild, isRenderer, isDev: isDev$2, isMain } = ps;
1258
- const { getConfig: getConfig$8 } = config;
1259
- const { childMessage } = message;
1260
-
1261
- // 捕获异常
1262
- function loadException$1() {
1263
- uncaughtExceptionHandler();
1264
- unhandledRejectionHandler();
1265
- }
1266
-
1267
- // 当进程上抛出异常而没有被捕获时触发该事件,并且使异常静默。
1268
- function uncaughtExceptionHandler() {
1269
- process.on('uncaughtException', function(err) {
1270
- if (!(err instanceof Error)) {
1271
- err = new Error(String(err));
1272
- }
1273
-
1274
- if (err.name === 'Error') {
1275
- err.name = 'unhandledExceptionError';
1276
- }
1277
-
1278
- coreLogger$7.error(err);
1279
-
1280
- _devError(err);
1281
-
1282
- _exit();
1283
- });
1284
- }
1285
-
1286
- // 当进程上抛出异常而没有被捕获时触发该事件。
1287
- function uncaughtExceptionMonitorHandler() {
1288
- process.on('uncaughtExceptionMonitor', function(err, origin) {
1289
- if (!(err instanceof Error)) {
1290
- err = new Error(String(err));
1291
- }
1292
- coreLogger$7.error('uncaughtExceptionMonitor:',err);
1293
- });
1294
- }
1295
-
1296
- // 当promise中reject的异常在同步任务中没有使用catch捕获就会触发该事件,
1297
- // 即便是在异步情况下使用了catch也会触发该事件
1298
- function unhandledRejectionHandler() {
1299
- process.on('unhandledRejection', function(err) {
1300
- if (!(err instanceof Error)) {
1301
- const newError = new Error(String(err));
1302
- // err maybe an object, try to copy the name, message and stack to the new error instance
1303
- if (err) {
1304
- if (err.name) newError.name = err.name;
1305
- if (err.message) newError.message = err.message;
1306
- if (err.stack) newError.stack = err.stack;
1307
- }
1308
- err = newError;
1309
- }
1310
- if (err.name === 'Error') {
1311
- err.name = 'unhandledRejectionError';
1312
- }
1313
- coreLogger$7.error(err);
1314
- _devError(err);
1315
- _exit();
1316
- });
1317
- }
1318
-
1319
- // 如果是子进程,发送错误到主进程控制台
1320
- function _devError (err) {
1321
- if (isForkedChild() && isDev$2()) {
1322
- childMessage.sendErrorToTerminal(err);
1323
- }
1324
- }
1325
-
1326
- // 捕获异常后是否退出
1327
- function _exit () {
1328
- const { mainExit, childExit, rendererExit } = getConfig$8().exception;
1329
-
1330
- if (isMain() && mainExit == true) {
1331
- _delayExit();
1332
- } else if (isForkedChild() && childExit == true) {
1333
- _delayExit();
1334
- } else if (isRenderer() && rendererExit == true) {
1335
- _delayExit();
1336
- } else ;
1337
- }
1338
-
1339
- // 捕获异常后是否退出
1340
- function _delayExit() {
1341
- // 等待日志等异步写入完成
1342
- setTimeout(() => {
1343
- process.exit();
1344
- }, 1500);
1345
- }
1346
-
1347
- var exception = {
1348
- loadException: loadException$1,
1349
- uncaughtExceptionHandler,
1350
- unhandledRejectionHandler,
1351
- uncaughtExceptionMonitorHandler
1352
- };
1353
-
1354
- const fs$6 = require$$0__default.default;
1355
-
1356
- function readSync$1(filepath) {
1357
- if (!fs$6.existsSync(filepath)) {
1358
- throw new Error(filepath + ' is not found');
1359
- }
1360
- return JSON.parse(fs$6.readFileSync(filepath));
1361
- }
1362
- var json = {
1363
- readSync: readSync$1};
1364
-
1365
- const os$1 = require$$0__default$2.default;
1366
- const path$9 = require$$1__default.default;
1367
- const fs$5 = require$$0__default.default;
1368
- const { exec, execSync } = require$$3__default.default;
1369
- const { createHash } = require$$4__default$1.default;
1370
- const { getBaseDir: getBaseDir$4 } = ps;
1371
- const { readSync } = json;
1372
- const is$8 = is$b;
1373
-
1374
- // machine id
1375
- const { platform } = process;
1376
- const win32RegBinPath = {
1377
- native: '%windir%\\System32',
1378
- mixed: '%windir%\\sysnative\\cmd.exe /c %windir%\\System32'
1379
- };
1380
- const MachineGuid = {
1381
- darwin: 'ioreg -rd1 -c IOPlatformExpertDevice',
1382
- win32: `${win32RegBinPath[_isWindowsProcessMixedOrNativeArchitecture()]}\\REG.exe ` +
1383
- 'QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography ' +
1384
- '/v MachineGuid',
1385
- linux: '( cat /var/lib/dbus/machine-id /etc/machine-id 2> /dev/null || hostname ) | head -n 1 || :',
1386
- freebsd: 'kenv -q smbios.system.uuid || sysctl -n kern.hostuuid'
1387
- };
1388
-
1389
- // 获取项目根目录package.json
1390
- function getPackage() {
1391
- const json = readSync(path$9.join(getBaseDir$4(), 'package.json'));
1392
-
1393
- return json;
1394
- }
1395
- // Get the first proper MAC address
1396
- // iface: If provided, restrict MAC address fetching to this interface
1397
- function getMAC(iface) {
1398
- const zeroRegex = /(?:[0]{1,2}[:-]){5}[0]{1,2}/;
1399
- const list = os$1.networkInterfaces();
1400
- if (iface) {
1401
- const parts = list[iface];
1402
- if (!parts) {
1403
- throw new Error(`interface ${iface} was not found`);
1404
- }
1405
- for (const part of parts) {
1406
- if (zeroRegex.test(part.mac) === false) {
1407
- return part.mac;
1408
- }
1409
- }
1410
- throw new Error(`interface ${iface} had no valid mac addresses`);
1411
- }
1412
- else {
1413
- for (const [key, parts] of Object.entries(list)) {
1414
- // for some reason beyond me, this is needed to satisfy typescript
1415
- // fix https://github.com/bevry/getmac/issues/100
1416
- if (!parts)
1417
- continue;
1418
- for (const part of parts) {
1419
- if (zeroRegex.test(part.mac) === false) {
1420
- return part.mac;
1421
- }
1422
- }
1423
- }
1424
- }
1425
- throw new Error('failed to get the MAC address');
1426
- }
1427
-
1428
- // Check if the input is a valid MAC address
1429
- function isMAC(macAddress) {
1430
- const macRegex = /(?:[a-z0-9]{1,2}[:-]){5}[a-z0-9]{1,2}/i;
1431
- return macRegex.test(macAddress);
1432
- }
1433
-
1434
- function isFileProtocol$1(protocol) {
1435
- return protocol == 'file://';
1436
- }
1437
-
1438
- function isWebProtocol(protocol) {
1439
- return ['http://', 'https://'].includes(protocol);
1440
- }
1441
-
1442
- function isJsProject(baseDir) {
1443
- const entryFile1 = path$9.join(baseDir, 'electron/main.js');
1444
- const entryFile2 = path$9.join(baseDir, 'electron/index.js');
1445
- if (fs$5.existsSync(entryFile1) || fs$5.existsSync(entryFile2)) {
1446
- return true;
1447
- }
1448
- return false;
1449
- }
1450
-
1451
- // get machine id
1452
- function machineIdSync(original) {
1453
- let id = _expose(execSync(MachineGuid[platform]).toString());
1454
- return original ? id : _hash(id);
1455
- }
1456
-
1457
- // get machine id (promise)
1458
- // original <Boolean>, If true return original value of machine id, otherwise return hashed value (sha-256), default: false
1459
- function machineId(original) {
1460
- return new Promise((resolve, reject) => {
1461
- return exec(MachineGuid[platform], {}, (err, stdout, stderr) => {
1462
- if (err) {
1463
- return reject(
1464
- new Error(`Error while obtaining machine id: ${err.stack}`)
1465
- );
1466
- }
1467
- let id = _expose(stdout.toString());
1468
- return resolve(original ? id : _hash(id));
1469
- });
1470
- });
1471
- }
1472
-
1473
- // get platform
1474
- // values: windows | windows_32 | windows_64 | macos_intel | macos_apple | linux
1475
- function getPlatform(delimiter = "_", isDiffArch = false) {
1476
- let osName = "";
1477
- if (is$8.windows()) {
1478
- osName = "windows";
1479
- if (isDiffArch) {
1480
- const arch = is$8.x64() ? "64" : "32";
1481
- osName += delimiter + arch;
1482
- }
1483
- } else if (is$8.macOS()) {
1484
- let isAppleSilicon = false;
1485
- const cpus = os$1.cpus();
1486
- for (let cpu of cpus) {
1487
- if (cpu.model.includes('Apple')) {
1488
- isAppleSilicon = true;
1489
- break;
1490
- }
1491
- }
1492
- const core = isAppleSilicon? "apple" : "intel";
1493
- osName = "macos" + delimiter + core;
1494
- } else if (is$8.linux()) {
1495
- osName = "linux";
1496
- }
1497
-
1498
- return osName;
1499
- }
1500
-
1501
-
1502
-
1503
- function _isWindowsProcessMixedOrNativeArchitecture() {
1504
- // detect if the node binary is the same arch as the Windows OS.
1505
- // or if this is 32 bit node on 64 bit windows.
1506
- if(process.platform !== 'win32') {
1507
- return '';
1508
- }
1509
- if( process.arch === 'ia32' && process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432') ) {
1510
- return 'mixed';
1511
- }
1512
- return 'native';
1513
- }
1514
-
1515
- function _hash(guid) {
1516
- return createHash('sha256').update(guid).digest('hex');
1517
- }
1518
-
1519
- function _expose(result) {
1520
- switch (platform) {
1521
- case 'darwin':
1522
- return result
1523
- .split('IOPlatformUUID')[1]
1524
- .split('\n')[0].replace(/\=|\s+|\"/ig, '')
1525
- .toLowerCase();
1526
- case 'win32':
1527
- return result
1528
- .toString()
1529
- .split('REG_SZ')[1]
1530
- .replace(/\r+|\n+|\s+/ig, '')
1531
- .toLowerCase();
1532
- case 'linux':
1533
- return result
1534
- .toString()
1535
- .replace(/\r+|\n+|\s+/ig, '')
1536
- .toLowerCase();
1537
- case 'freebsd':
1538
- return result
1539
- .toString()
1540
- .replace(/\r+|\n+|\s+/ig, '')
1541
- .toLowerCase();
1542
- default:
1543
- throw new Error(`Unsupported platform: ${process.platform}`);
1544
- }
1545
- }
1546
-
1547
- var utils = {
1548
- getPackage,
1549
- getMAC,
1550
- isMAC,
1551
- isFileProtocol: isFileProtocol$1,
1552
- isWebProtocol,
1553
- isJsProject,
1554
- machineIdSync,
1555
- machineId,
1556
- getPlatform,
1557
- is: is$8
1558
- };
1559
-
1560
- function hasKey(obj, keys) {
1561
- var o = obj;
1562
- keys.slice(0, -1).forEach(function (key) {
1563
- o = o[key] || {};
1564
- });
1565
-
1566
- var key = keys[keys.length - 1];
1567
- return key in o;
1568
- }
1569
-
1570
- function isNumber(x) {
1571
- if (typeof x === 'number') { return true; }
1572
- if ((/^0x[0-9a-f]+$/i).test(x)) { return true; }
1573
- return (/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/).test(x);
1574
- }
1575
-
1576
- function isConstructorOrProto(obj, key) {
1577
- return (key === 'constructor' && typeof obj[key] === 'function') || key === '__proto__';
1578
- }
1579
-
1580
- function parseArgv$2(args, opts) {
1581
- if (!opts) { opts = {}; }
1582
-
1583
- var flags = {
1584
- bools: {},
1585
- strings: {},
1586
- unknownFn: null,
1587
- };
1588
-
1589
- if (typeof opts.unknown === 'function') {
1590
- flags.unknownFn = opts.unknown;
1591
- }
1592
-
1593
- if (typeof opts.boolean === 'boolean' && opts.boolean) {
1594
- flags.allBools = true;
1595
- } else {
1596
- [].concat(opts.boolean).filter(Boolean).forEach(function (key) {
1597
- flags.bools[key] = true;
1598
- });
1599
- }
1600
-
1601
- var aliases = {};
1602
-
1603
- function aliasIsBoolean(key) {
1604
- return aliases[key].some(function (x) {
1605
- return flags.bools[x];
1606
- });
1607
- }
1608
-
1609
- Object.keys(opts.alias || {}).forEach(function (key) {
1610
- aliases[key] = [].concat(opts.alias[key]);
1611
- aliases[key].forEach(function (x) {
1612
- aliases[x] = [key].concat(aliases[key].filter(function (y) {
1613
- return x !== y;
1614
- }));
1615
- });
1616
- });
1617
-
1618
- [].concat(opts.string).filter(Boolean).forEach(function (key) {
1619
- flags.strings[key] = true;
1620
- if (aliases[key]) {
1621
- [].concat(aliases[key]).forEach(function (k) {
1622
- flags.strings[k] = true;
1623
- });
1624
- }
1625
- });
1626
-
1627
- var defaults = opts.default || {};
1628
-
1629
- var argv = { _: [] };
1630
-
1631
- function argDefined(key, arg) {
1632
- return (flags.allBools && (/^--[^=]+$/).test(arg))
1633
- || flags.strings[key]
1634
- || flags.bools[key]
1635
- || aliases[key];
1636
- }
1637
-
1638
- function setKey(obj, keys, value) {
1639
- var o = obj;
1640
- for (var i = 0; i < keys.length - 1; i++) {
1641
- var key = keys[i];
1642
- if (isConstructorOrProto(o, key)) { return; }
1643
- if (o[key] === undefined) { o[key] = {}; }
1644
- if (
1645
- o[key] === Object.prototype
1646
- || o[key] === Number.prototype
1647
- || o[key] === String.prototype
1648
- ) {
1649
- o[key] = {};
1650
- }
1651
- if (o[key] === Array.prototype) { o[key] = []; }
1652
- o = o[key];
1653
- }
1654
-
1655
- var lastKey = keys[keys.length - 1];
1656
- if (isConstructorOrProto(o, lastKey)) { return; }
1657
- if (
1658
- o === Object.prototype
1659
- || o === Number.prototype
1660
- || o === String.prototype
1661
- ) {
1662
- o = {};
1663
- }
1664
- if (o === Array.prototype) { o = []; }
1665
- if (o[lastKey] === undefined || flags.bools[lastKey] || typeof o[lastKey] === 'boolean') {
1666
- o[lastKey] = value;
1667
- } else if (Array.isArray(o[lastKey])) {
1668
- o[lastKey].push(value);
1669
- } else {
1670
- o[lastKey] = [o[lastKey], value];
1671
- }
1672
- }
1673
-
1674
- function setArg(key, val, arg) {
1675
- if (arg && flags.unknownFn && !argDefined(key, arg)) {
1676
- if (flags.unknownFn(arg) === false) { return; }
1677
- }
1678
-
1679
- var value = !flags.strings[key] && isNumber(val)
1680
- ? Number(val)
1681
- : val;
1682
- setKey(argv, key.split('.'), value);
1683
-
1684
- (aliases[key] || []).forEach(function (x) {
1685
- setKey(argv, x.split('.'), value);
1686
- });
1687
- }
1688
-
1689
- Object.keys(flags.bools).forEach(function (key) {
1690
- setArg(key, defaults[key] === undefined ? false : defaults[key]);
1691
- });
1692
-
1693
- var notFlags = [];
1694
-
1695
- if (args.indexOf('--') !== -1) {
1696
- notFlags = args.slice(args.indexOf('--') + 1);
1697
- args = args.slice(0, args.indexOf('--'));
1698
- }
1699
-
1700
- for (var i = 0; i < args.length; i++) {
1701
- var arg = args[i];
1702
- var key;
1703
- var next;
1704
-
1705
- if ((/^--.+=/).test(arg)) {
1706
- // Using [\s\S] instead of . because js doesn't support the
1707
- // 'dotall' regex modifier. See:
1708
- // http://stackoverflow.com/a/1068308/13216
1709
- var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
1710
- key = m[1];
1711
- var value = m[2];
1712
- if (flags.bools[key]) {
1713
- value = value !== 'false';
1714
- }
1715
- setArg(key, value, arg);
1716
- } else if ((/^--no-.+/).test(arg)) {
1717
- key = arg.match(/^--no-(.+)/)[1];
1718
- setArg(key, false, arg);
1719
- } else if ((/^--.+/).test(arg)) {
1720
- key = arg.match(/^--(.+)/)[1];
1721
- next = args[i + 1];
1722
- if (
1723
- next !== undefined
1724
- && !(/^(-|--)[^-]/).test(next)
1725
- && !flags.bools[key]
1726
- && !flags.allBools
1727
- && (aliases[key] ? !aliasIsBoolean(key) : true)
1728
- ) {
1729
- setArg(key, next, arg);
1730
- i += 1;
1731
- } else if ((/^(true|false)$/).test(next)) {
1732
- setArg(key, next === 'true', arg);
1733
- i += 1;
1734
- } else {
1735
- setArg(key, flags.strings[key] ? '' : true, arg);
1736
- }
1737
- } else if ((/^-[^-]+/).test(arg)) {
1738
- var letters = arg.slice(1, -1).split('');
1739
-
1740
- var broken = false;
1741
- for (var j = 0; j < letters.length; j++) {
1742
- next = arg.slice(j + 2);
1743
-
1744
- if (next === '-') {
1745
- setArg(letters[j], next, arg);
1746
- continue;
1747
- }
1748
-
1749
- if ((/[A-Za-z]/).test(letters[j]) && next[0] === '=') {
1750
- setArg(letters[j], next.slice(1), arg);
1751
- broken = true;
1752
- break;
1753
- }
1754
-
1755
- if (
1756
- (/[A-Za-z]/).test(letters[j])
1757
- && (/-?\d+(\.\d*)?(e-?\d+)?$/).test(next)
1758
- ) {
1759
- setArg(letters[j], next, arg);
1760
- broken = true;
1761
- break;
1762
- }
1763
-
1764
- if (letters[j + 1] && letters[j + 1].match(/\W/)) {
1765
- setArg(letters[j], arg.slice(j + 2), arg);
1766
- broken = true;
1767
- break;
1768
- } else {
1769
- setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
1770
- }
1771
- }
1772
-
1773
- key = arg.slice(-1)[0];
1774
- if (!broken && key !== '-') {
1775
- if (
1776
- args[i + 1]
1777
- && !(/^(-|--)[^-]/).test(args[i + 1])
1778
- && !flags.bools[key]
1779
- && (aliases[key] ? !aliasIsBoolean(key) : true)
1780
- ) {
1781
- setArg(key, args[i + 1], arg);
1782
- i += 1;
1783
- } else if (args[i + 1] && (/^(true|false)$/).test(args[i + 1])) {
1784
- setArg(key, args[i + 1] === 'true', arg);
1785
- i += 1;
1786
- } else {
1787
- setArg(key, flags.strings[key] ? '' : true, arg);
1788
- }
1789
- }
1790
- } else {
1791
- if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
1792
- argv._.push(flags.strings._ || !isNumber(arg) ? arg : Number(arg));
1793
- }
1794
- if (opts.stopEarly) {
1795
- argv._.push.apply(argv._, args.slice(i + 1));
1796
- break;
1797
- }
1798
- }
1799
- }
1800
-
1801
- Object.keys(defaults).forEach(function (k) {
1802
- if (!hasKey(argv, k.split('.'))) {
1803
- setKey(argv, k.split('.'), defaults[k]);
1804
-
1805
- (aliases[k] || []).forEach(function (x) {
1806
- setKey(argv, x.split('.'), defaults[k]);
1807
- });
1808
- }
1809
- });
1810
-
1811
- if (opts['--']) {
1812
- argv['--'] = notFlags.slice();
1813
- } else {
1814
- notFlags.forEach(function (k) {
1815
- argv._.push(k);
1816
- });
1817
- }
1818
-
1819
- return argv;
1820
- }
1821
- var pargv = {
1822
- parseArgv: parseArgv$2
1823
- };
1824
-
1825
- const fs$4 = require$$0__default.default;
1826
- const mkdirp = require$$2__default$1.default;
1827
- const { parseArgv: parseArgv$1 } = pargv;
1828
-
1829
- process.cwd();
1830
-
1831
- // 随机10位字符串
1832
- function getRandomString$2() {
1833
- return Math.random().toString(36).substring(2);
1834
- }
1835
- // 创建文件夹
1836
- function mkdir$2(filepath, opt = {}) {
1837
- mkdirp.sync(filepath, opt);
1838
- return
1839
- }
1840
-
1841
- // 是否有效值
1842
- function validValue$1(value) {
1843
- return (
1844
- value !== undefined &&
1845
- value !== null &&
1846
- value !== ''
1847
- );
1848
- }
1849
-
1850
- function sleep$2(ms) {
1851
- return new Promise(resolve => setTimeout(resolve, ms));
1852
- }
1853
- function replaceArgsValue$1(argv, key, value) {
1854
- key = key + "=";
1855
- for (let i = 0; i < argv.length; i++) {
1856
- let item = argv[i];
1857
- let pos = item.indexOf(key);
1858
- if (pos !== -1) {
1859
- pos = pos + key.length;
1860
- let tmpStr = item.substring(0, pos);
1861
- argv[i] = tmpStr + value;
1862
- break;
1863
- }
1864
- }
1865
-
1866
- return argv;
1867
- }
1868
- function getValueFromArgv$2(argv, key) {
1869
- const argvObj = parseArgv$1(argv);
1870
- if (argvObj.hasOwnProperty(key)) {
1871
- return argvObj[key];
1872
- }
1873
-
1874
- // match search
1875
- key = key + "=";
1876
- let value;
1877
- for (let i = 0; i < argv.length; i++) {
1878
- let item = argv[i];
1879
- let pos = item.indexOf(key);
1880
- if (pos !== -1) {
1881
- pos = pos + key.length;
1882
- value = item.substring(pos);
1883
- break;
1884
- }
1885
- }
1886
-
1887
- return value;
1888
- }
1889
- function fileIsExist$1(filepath) {
1890
- if (fs$4.existsSync(filepath) && fs$4.statSync(filepath).isFile()) {
1891
- return true;
1892
- }
1893
- return false;
1894
- }
1895
- var helper = {
1896
- getRandomString: getRandomString$2,
1897
- mkdir: mkdir$2,
1898
- validValue: validValue$1,
1899
- sleep: sleep$2,
1900
- replaceArgsValue: replaceArgsValue$1,
1901
- getValueFromArgv: getValueFromArgv$2,
1902
- fileIsExist: fileIsExist$1
1903
- };
1904
-
1905
- const EventEmitter$4 = require$$0__default$3.default;
1906
- const path$8 = require$$1__default.default;
1907
- const crossSpawn = require$$2__default$2.default;
1908
- const { coreLogger: coreLogger$6 } = log;
1909
- const { getExtraResourcesDir, isPackaged: isPackaged$1, isDev: isDev$1, getBaseDir: getBaseDir$3 } = ps;
1910
- const { Events: Events$4 } = channel;
1911
- const { getRandomString: getRandomString$1, getValueFromArgv: getValueFromArgv$1 } = helper;
1912
- const { is: is$7 } = utils;
1913
- const { parseArgv } = pargv;
1914
- const { app: electronApp$2 } = require$$9__default.default;
1915
- const tkill = require$$10__default.default;
1916
-
1917
- let CrossProcess$1 = class CrossProcess {
1918
- constructor(host, opt = {}) {
1919
- this.emitter = new EventEmitter$4();
1920
- this.host = host;
1921
- this.child = undefined;
1922
- this.pid = 0;
1923
- this.port = 0;
1924
- this.name = "";
1925
- this.config = {};
1926
- this._init(opt);
1927
- }
1928
-
1929
- /**
1930
- * 初始化子进程
1931
- */
1932
- _init(options = {}) {
1933
- const { targetConf, port } = options;
1934
- this.config = targetConf;
1935
- this.port = port;
1936
-
1937
- // 该名称如果在childrenMap重复,会被重写
1938
- this.name = targetConf.name;
1939
-
1940
- // Launch executable program
1941
- let cmdPath = '';
1942
- let cmdArgs = targetConf.args;
1943
- let execDir = getExtraResourcesDir();
1944
- let standardOutput = ['inherit', 'inherit', 'inherit', 'ipc'];
1945
- if (isPackaged$1()) {
1946
- standardOutput = ['ignore', 'ignore', 'ignore', 'ipc'];
1947
- }
1948
- if (targetConf.stdio) {
1949
- standardOutput = targetConf.stdio;
1950
- }
1951
-
1952
- const { cmd, directory } = targetConf;
1953
- // use cmd first
1954
- if (cmd) {
1955
- if (!directory) {
1956
- throw new Error(`[electron-easymvc] [cross] The config [directory] attribute does not exist`);
1957
- }
1958
- cmdPath = cmd;
1959
- if (!path$8.isAbsolute(cmd) && !isDev$1()) {
1960
- cmdPath = path$8.join(getExtraResourcesDir(), cmd);
1961
- }
1962
- } else {
1963
- cmdPath = path$8.join(getExtraResourcesDir(), targetConf.name);
1964
- }
1965
-
1966
- // windows
1967
- if (is$7.windows() && path$8.extname(cmdPath) != '.exe') {
1968
- // Complete the executable program extension
1969
- // notice: python.exe may bring up the App Store
1970
- if (targetConf.windowsExtname === true || !isDev$1()) {
1971
- cmdPath += ".exe";
1972
- }
1973
- }
1974
-
1975
- // executable program directory
1976
- if (directory && path$8.isAbsolute(directory)) {
1977
- execDir = directory;
1978
- } else if (directory && !path$8.isAbsolute(directory)) {
1979
- if (isDev$1()) {
1980
- execDir = path$8.join(getBaseDir$3(), directory);
1981
- } else {
1982
- execDir = path$8.join(getExtraResourcesDir(), directory);
1983
- }
1984
- } else {
1985
- execDir = getExtraResourcesDir();
1986
- }
1987
-
1988
- coreLogger$6.info(`[electron-easymvc] [cross/run] cmd: ${cmdPath}, args: ${cmdArgs}`);
1989
- const coreProcess = crossSpawn(cmdPath, cmdArgs, {
1990
- stdio: standardOutput,
1991
- detached: false,
1992
- cwd: execDir,
1993
- maxBuffer: 1024 * 1024 * 1024
1994
- });
1995
- this.child = coreProcess;
1996
- this.pid = coreProcess.pid;
1997
-
1998
- coreProcess.on('exit', (code, signal) => {
1999
- let data = {
2000
- pid: this.pid
2001
- };
2002
- this.host.emitter.emit(Events$4.childProcessExit, data);
2003
- // Child process closed: The child process was killed externally or an internal error caused the application to stop, resulting in the application exiting
2004
- coreLogger$6.info(`[electron-easymvc] [corss/process] received a exit from child-process, code:${code}, signal:${signal}, pid:${this.pid}, cmd:${cmdPath}, args: ${cmdArgs}`);
2005
- this._exitElectron();
2006
- });
2007
-
2008
- coreProcess.on('error', (err) => {
2009
- let data = {
2010
- pid: this.pid
2011
- };
2012
- this.host.emitter.emit(Events$4.childProcessError, data);
2013
- coreLogger$6.error(`[electron-easymvc] [corss/process] received a error from child-process, error: ${err}, pid:${this.pid}`);
2014
- this._exitElectron();
2015
- });
2016
- }
2017
-
2018
- /**
2019
- * kill
2020
- */
2021
- kill(timeout = 1000) {
2022
- tkill(this.pid, 'SIGINT', (err) => {
2023
- if (err) {
2024
- coreLogger$6.error(`[electron-easymvc] [corss/process] kill cross-process, error: ${err}, pid:${this.pid}`);
2025
- tkill(this.pid, 'SIGKILL');
2026
- }
2027
- setTimeout(() => {
2028
- this._exitElectron();
2029
- }, timeout);
2030
- });
2031
- }
2032
-
2033
- getUrl() {
2034
- const ssl = getValueFromArgv$1(this.config.args, 'ssl');
2035
- let hostname = getValueFromArgv$1(this.config.args, 'hostname');
2036
- let protocol = 'http://';
2037
- if (ssl && (ssl == 'true' || ssl == '1')) {
2038
- protocol = 'https://';
2039
- }
2040
- hostname = hostname ? hostname : '127.0.0.1';
2041
- const url = protocol + hostname + ":" + this.port;
2042
-
2043
- return url;
2044
- }
2045
-
2046
- getArgsObj() {
2047
- const obj = parseArgv(this.config.args);
2048
- return obj;
2049
- }
2050
-
2051
- setPort(port) {
2052
- this.port = parseInt(port);
2053
- }
2054
-
2055
- _generateId() {
2056
- const rid = getRandomString$1();
2057
- return `node:${this.pid}:${rid}`;
2058
- }
2059
-
2060
- /**
2061
- * exit electron
2062
- */
2063
- _exitElectron(timeout = 1000) {
2064
- if (this.config.appExit) {
2065
- setTimeout(() => {
2066
- // 主进程退出
2067
- electronApp$2.quit();
2068
- }, timeout);
2069
- }
2070
- }
2071
- };
2072
-
2073
- var crossProcess = {
2074
- CrossProcess: CrossProcess$1
2075
- };
2076
-
2077
- const net = require$$0__default$4.default;
2078
- const os = require$$0__default$2.default;
2079
-
2080
- class Locked extends Error {
2081
- constructor(port) {
2082
- super(`${port} is locked`);
2083
- }
2084
- }
2085
-
2086
- const lockedPorts = {
2087
- old: new Set(),
2088
- young: new Set()
2089
- };
2090
-
2091
- // On this interval, the old locked ports are discarded,
2092
- // the young locked ports are moved to old locked ports,
2093
- // and a new young set for locked ports are created.
2094
- const releaseOldLockedPortsIntervalMs = 1000 * 15;
2095
-
2096
- // Lazily create interval on first use
2097
- let interval;
2098
-
2099
- const getLocalHosts = () => {
2100
- const interfaces = os.networkInterfaces();
2101
-
2102
- // Add undefined value for createServer function to use default host,
2103
- // and default IPv4 host in case createServer defaults to IPv6.
2104
- const results = new Set([undefined, '0.0.0.0']);
2105
-
2106
- for (const _interface of Object.values(interfaces)) {
2107
- for (const config of _interface) {
2108
- results.add(config.address);
2109
- }
2110
- }
2111
-
2112
- return results;
2113
- };
2114
-
2115
- const checkAvailablePort = options =>
2116
- new Promise((resolve, reject) => {
2117
- const server = net.createServer();
2118
- server.unref();
2119
- server.on('error', reject);
2120
-
2121
- server.listen(options, () => {
2122
- const {port} = server.address();
2123
- server.close(() => {
2124
- resolve(port);
2125
- });
2126
- });
2127
- });
2128
-
2129
- const getAvailablePort = async (options, hosts) => {
2130
- if (options.host || options.port === 0) {
2131
- return checkAvailablePort(options);
2132
- }
2133
-
2134
- for (const host of hosts) {
2135
- try {
2136
- await checkAvailablePort({port: options.port, host}); // eslint-disable-line no-await-in-loop
2137
- } catch (error) {
2138
- if (!['EADDRNOTAVAIL', 'EINVAL'].includes(error.code)) {
2139
- throw error;
2140
- }
2141
- }
2142
- }
2143
-
2144
- return options.port;
2145
- };
2146
-
2147
- const portCheckSequence = function * (ports) {
2148
- if (ports) {
2149
- yield * ports;
2150
- }
2151
-
2152
- yield 0; // Fall back to 0 if anything else failed
2153
- };
2154
-
2155
- async function getPort$3(options) {
2156
- let ports;
2157
-
2158
- if (options) {
2159
- ports = typeof options.port === 'number' ? [options.port] : options.port;
2160
- }
2161
-
2162
- if (interval === undefined) {
2163
- interval = setInterval(() => {
2164
- lockedPorts.old = lockedPorts.young;
2165
- lockedPorts.young = new Set();
2166
- }, releaseOldLockedPortsIntervalMs);
2167
-
2168
- // Does not exist in some environments (Electron, Jest jsdom env, browser, etc).
2169
- if (interval.unref) {
2170
- interval.unref();
2171
- }
2172
- }
2173
-
2174
- const hosts = getLocalHosts();
2175
-
2176
- for (const port of portCheckSequence(ports)) {
2177
- try {
2178
- let availablePort = await getAvailablePort({...options, port}, hosts); // eslint-disable-line no-await-in-loop
2179
- while (lockedPorts.old.has(availablePort) || lockedPorts.young.has(availablePort)) {
2180
- if (port !== 0) {
2181
- throw new Locked(port);
2182
- }
2183
-
2184
- availablePort = await getAvailablePort({...options, port}, hosts); // eslint-disable-line no-await-in-loop
2185
- }
2186
-
2187
- lockedPorts.young.add(availablePort);
2188
- return availablePort;
2189
- } catch (error) {
2190
- if (!['EADDRINUSE', 'EACCES'].includes(error.code) && !(error instanceof Locked)) {
2191
- throw error;
2192
- }
2193
- }
2194
- }
2195
-
2196
- throw new Error('No available ports found');
2197
- }
2198
- var port = {
2199
- getPort: getPort$3
2200
- };
2201
-
2202
- const EventEmitter$3 = require$$0__default$3.default;
2203
- const { getConfig: getConfig$7 } = config;
2204
- const { sleep: sleep$1, getValueFromArgv, replaceArgsValue } = helper;
2205
- const { CrossProcess } = crossProcess;
2206
- const { Events: Events$3 } = channel;
2207
- const { extend: extend$3 } = extend_1;
2208
- const { getPort: getPort$2 } = port;
2209
-
2210
- let Cross$1 = class Cross {
2211
- constructor() {
2212
- this.emitter = undefined;
2213
-
2214
- // pid唯一
2215
- // {pid:{name,entity}, pid:{name,entity}, ...}
2216
- this.children = {};
2217
-
2218
- // name唯一
2219
- // {name:pid, name:pid, ...}
2220
- this.childrenMap = {};
2221
-
2222
- // eventEmitter
2223
- this._initEventEmitter();
2224
- }
2225
-
2226
- async create() {
2227
-
2228
- // boot services
2229
- const crossCfg = getConfig$7().cross;
2230
- //await sleep(5 * 1000);
2231
-
2232
- for (let key of Object.keys(crossCfg)) {
2233
- let val = crossCfg[key];
2234
- if (val.enable == true) {
2235
- this.run(key);
2236
- }
2237
- }
2238
- }
2239
-
2240
- // run
2241
- async run(service, opt = {}) {
2242
- const crossConf = getConfig$7().cross;
2243
- const defaultOpt = crossConf[service] || {};
2244
- const targetConf = extend$3(true, {}, defaultOpt, opt);
2245
- if (Object.keys(targetConf).length == 0) {
2246
- throw new Error(`[electron-easymvc] [cross] The service [${service}] config does not exit`);
2247
- }
2248
-
2249
- // format params
2250
- let tmpArgs = targetConf.args;
2251
- let confPort = parseInt(getValueFromArgv(tmpArgs, 'port'));
2252
- // 某些程序给它传入不存在的参数时会报错
2253
- if (isNaN(confPort) && targetConf.port > 0) {
2254
- confPort = targetConf.port;
2255
- }
2256
- if (confPort > 0) {
2257
- // 动态生成port,传入的端口必须为int
2258
- confPort = await getPort$2({ port: confPort });
2259
- // 替换port
2260
- targetConf.args = replaceArgsValue(tmpArgs, "port", String(confPort));
2261
- }
2262
-
2263
- // 创建进程
2264
- const subProcess = new CrossProcess(this, { targetConf, port: confPort });
2265
- let uniqueName = targetConf.name;
2266
- if (this.childrenMap.hasOwnProperty(uniqueName)) {
2267
- uniqueName = uniqueName + "-" + String(subProcess.pid);
2268
- }
2269
- this.childrenMap[uniqueName] = subProcess.pid;
2270
- subProcess.name = uniqueName;
2271
- this.children[subProcess.pid] = {
2272
- name: uniqueName,
2273
- entity: subProcess
2274
- };
2275
-
2276
- return subProcess;
2277
- }
2278
-
2279
- killAll() {
2280
- Object.keys(this.children).forEach(pid => {
2281
- this.kill(pid);
2282
- });
2283
- }
2284
-
2285
- kill(pid) {
2286
- const entity = this.getProc(pid);
2287
- if (entity) {
2288
- entity.kill();
2289
- }
2290
- }
2291
-
2292
- killByName(name) {
2293
- const entity = this.getProcByName(name);
2294
- if (entity) {
2295
- entity.kill();
2296
- }
2297
- }
2298
-
2299
- getUrl(name) {
2300
- const entity = this.getProcByName(name);
2301
- const url = entity.getUrl();
2302
-
2303
- return url;
2304
- }
2305
-
2306
- // 获取 proc
2307
- getProcByName(name) {
2308
- // [todo] 如果有名字一样的服务,需要加 pid
2309
- const pid = this.childrenMap[name];
2310
- if (!pid) {
2311
- throw new Error(`[electron-easymvc] [cross] The process named [${name}] does not exit`);
2312
- }
2313
- const entity = this.getProc(pid);
2314
-
2315
- return entity;
2316
- }
2317
-
2318
- // 获取 proc
2319
- getProc(pid) {
2320
- const child = this.children[pid];
2321
- if (!pid) {
2322
- throw new Error(`[electron-easymvc] [cross] The process pid [${pid}] does not exit`);
2323
- }
2324
-
2325
- return child.entity;
2326
- }
2327
-
2328
- // 获取pids
2329
- getPids() {
2330
- let pids = Object.keys(this.children);
2331
- return pids;
2332
- }
2333
-
2334
- _initEventEmitter() {
2335
- this.emitter = new EventEmitter$3();
2336
- this.emitter.on(Events$3.childProcessExit, (data) => {
2337
- const child = this.children[data.pid];
2338
- delete this.childrenMap[child.name];
2339
- delete this.children[data.pid];
2340
- });
2341
- this.emitter.on(Events$3.childProcessError, (data) => {
2342
- const child = this.children[data.pid];
2343
- delete this.childrenMap[child.name];
2344
- delete this.children[data.pid];
2345
- });
2346
- }
2347
- };
2348
-
2349
- var cross$3 = {
2350
- Cross: Cross$1,
2351
- cross: new Cross$1()
2352
- };
2353
-
2354
- const { Cross, cross: cross$2} = cross$3;
2355
-
2356
- var cross_1 = {
2357
- Cross,
2358
- cross: cross$2
2359
- };
2360
-
2361
- const Ready$1 = "ready";
2362
- const ElectronAppReady$1 = "electron-app-ready";
2363
- const WindowReady$1 = "window-ready";
2364
- const BeforeClose$1 = "before-close";
2365
- const Preload$1 = "preload";
2366
-
2367
- class EventBus {
2368
- constructor() {
2369
- this.lifecycleEvents = {};
2370
- this.eventsMap = {};
2371
- }
2372
-
2373
- // add lifecycle event
2374
- register(eventName, handler) {
2375
- if (!this.lifecycleEvents[eventName]) {
2376
- this.lifecycleEvents[eventName] = handler;
2377
- }
2378
- }
2379
-
2380
- // call lifecycle event
2381
- emitLifecycle(eventName, ...args) {
2382
- const eventFn = this.lifecycleEvents[eventName];
2383
- if (eventFn) {
2384
- eventFn(...args);
2385
- }
2386
- }
2387
-
2388
- // add listener
2389
- on(eventName, handler) {
2390
- if (!this.eventsMap[eventName]) {
2391
- this.eventsMap[eventName] = handler;
2392
- }
2393
- }
2394
-
2395
- // emit listener
2396
- emit(eventName, ...args) {
2397
- const eventFn = this.eventsMap[eventName];
2398
- if (eventFn) {
2399
- eventFn(...args);
2400
- }
2401
- }
2402
- }
2403
-
2404
- const eventBus$3 = new EventBus();
2405
-
2406
- var events = {
2407
- eventBus: eventBus$3,
2408
- Ready: Ready$1,
2409
- ElectronAppReady: ElectronAppReady$1,
2410
- WindowReady: WindowReady$1,
2411
- Preload: Preload$1,
2412
- BeforeClose: BeforeClose$1
2413
- };
2414
-
2415
- const path$7 = require$$1__default.default;
2416
-
2417
- // Html
2418
- function getHtmlFilepath$1(name){
2419
- const pagePath = path$7.join(__dirname, name);
2420
- return pagePath;
2421
- }
2422
-
2423
- var html = {
2424
- getHtmlFilepath: getHtmlFilepath$1
2425
- };
2426
-
2427
- const debug$6 = require$$0__default$1.default('electron-easymvc:electron:window');
2428
- const is$6 = require$$1__default$1.default;
2429
- const path$6 = require$$1__default.default;
2430
- const axios = require$$3__default$1.default;
2431
- const { BrowserWindow } = require$$9__default.default;
2432
- const { getConfig: getConfig$6 } = config;
2433
- const { eventBus: eventBus$2, WindowReady } = events;
2434
- const { env, isDev, getBaseDir: getBaseDir$2 } = ps;
2435
- const { loadFile: loadFile$1 } = loader;
2436
- const { isFileProtocol } = utils;
2437
- const { getHtmlFilepath } = html;
2438
- const { fileIsExist, sleep } = helper;
2439
- const { coreLogger: coreLogger$5 } = log;
2440
- const { extend: extend$2 } = extend_1;
2441
- const { cross: cross$1 } = cross_1;
2442
-
2443
- const Instance$2 = {
2444
- mainWindow: null,
2445
- closeAndQuit: true,
2446
- };
2447
-
2448
- // getMainWindow
2449
- function getMainWindow$1() {
2450
- return Instance$2.mainWindow;
2451
- }
2452
-
2453
- // Create the main application window
2454
- function createMainWindow$1() {
2455
- const { openDevTools, windowsOption } = getConfig$6();
2456
- const win = new BrowserWindow(windowsOption);
2457
- Instance$2.mainWindow = win;
2458
-
2459
- // DevTools
2460
- if (is$6.object(openDevTools)) {
2461
- win.webContents.openDevTools(openDevTools);
2462
- } else if (openDevTools === true) {
2463
- win.webContents.openDevTools({
2464
- mode: 'bottom'
2465
- });
2466
- }
2467
-
2468
- eventBus$2.emitLifecycle(WindowReady);
2469
- return win;
2470
- }
2471
-
2472
- // Set the flag for exiting after close all windows
2473
- function setCloseAndQuit$2(flag) {
2474
- Instance$2.closeAndQuit = flag;
2475
- }
2476
-
2477
- function getCloseAndQuit$1() {
2478
- return Instance$2.closeAndQuit;
2479
- }
2480
-
2481
- // load server
2482
- // type: remote | single
2483
- async function loadServer$1() {
2484
- let type = 'spa';
2485
- let url = '';
2486
- const { remote, mainServer } = getConfig$6();
2487
- const win = getMainWindow$1();
2488
-
2489
- // remote model
2490
- if (remote.enable == true) {
2491
- type = 'remote';
2492
- url = remote.url;
2493
- loadMainUrl(type, url);
2494
- return;
2495
- }
2496
-
2497
- // 开发环境
2498
- if (isDev()) {
2499
- let url;
2500
- let load = 'url';
2501
-
2502
- const binFile = path$6.join(getBaseDir$2(), "./cmd/bin.js");
2503
- const binConfig = loadFile$1(binFile);
2504
- const { dev } = binConfig;
2505
- // tips: match with ee-bin
2506
- const frontendConf = extend$2(true, {
2507
- protocol: 'http://',
2508
- hostname: 'localhost',
2509
- port: 8080,
2510
- indexPath: 'index.html',
2511
- }, dev.frontend);
2512
- const electronConf = extend$2(true, {
2513
- loadingPage: '/public/html/loading.html',
2514
- }, dev.electron);
2515
-
2516
- url = frontendConf.protocol + frontendConf.hostname + ':' + frontendConf.port;
2517
- if (isFileProtocol(frontendConf.protocol)) {
2518
- url = path$6.join(getBaseDir$2(), frontendConf.directory, frontendConf.indexPath);
2519
- load = 'file';
2520
- }
2521
-
2522
- // Check if UI serve is started, load a boot page first
2523
- if (load == 'url') {
2524
- // loading page
2525
- let lp = getHtmlFilepath('boot.html');
2526
- if (electronConf.hasOwnProperty('loadingPage') && electronConf.loadingPage != '') {
2527
- lp = path$6.join(getBaseDir$2(), electronConf.loadingPage);
2528
- }
2529
- _loadingPage(lp);
2530
-
2531
- // check frontend is ready
2532
- const retryTimes = frontendConf.force === true ? 3 : 60;
2533
- let count = 0;
2534
- let frontendReady = false;
2535
- while(!frontendReady && count < retryTimes){
2536
- await sleep(1 * 1000);
2537
- try {
2538
- await axios({
2539
- method: 'get',
2540
- url,
2541
- timeout: 1000,
2542
- proxy: false,
2543
- headers: {
2544
- 'Accept': 'text/html, application/json, text/plain, */*',
2545
- },
2546
- //responseType: 'text',
2547
- });
2548
- frontendReady = true;
2549
- } catch(err) {
2550
- // console.warn(err.stack)
2551
- }
2552
- count++;
2553
- }
2554
- debug$6('it takes %d seconds to start the frontend', count);
2555
-
2556
- if (frontendReady == false && frontendConf.force !== true) {
2557
- const bootFailurePage = getHtmlFilepath('failure.html');
2558
- win.loadFile(bootFailurePage);
2559
- coreLogger$5.error(`[electron-easymvc] Please check the ${url} !`);
2560
- return;
2561
- }
2562
- }
2563
-
2564
- loadMainUrl(type, url, load);
2565
- return;
2566
- }
2567
-
2568
- // 生产环境
2569
- // cross takeover web
2570
- if (mainServer.takeover.length > 0) {
2571
- await crossTakeover();
2572
- return
2573
- }
2574
-
2575
- // 主进程
2576
- url = path$6.join(getBaseDir$2(), mainServer.indexPath);
2577
- loadMainUrl(type, url, 'file');
2578
- }
2579
-
2580
- /**
2581
- * 主服务
2582
- * @params load <string> value: "url" 、 "file"
2583
- */
2584
- function loadMainUrl(type, url, load = 'url') {
2585
- const { mainServer } = getConfig$6();
2586
- const mainWindow = getMainWindow$1();
2587
- coreLogger$5.info('[electron-easymvc] Env: %s, Type: %s', env(), type);
2588
- coreLogger$5.info('[electron-easymvc] App running at: %s', url);
2589
- if (load == 'file') {
2590
- mainWindow.loadFile(url, mainServer.options)
2591
- .then()
2592
- .catch((err)=>{
2593
- coreLogger$5.error(`[electron-easymvc] Please check the ${url} !`);
2594
- });
2595
- } else {
2596
- mainWindow.loadURL(url, mainServer.options)
2597
- .then()
2598
- .catch((err)=>{
2599
- coreLogger$5.error(`[electron-easymvc] Please check the ${url} !`);
2600
- });
2601
- }
2602
- }
2603
-
2604
- // loading page
2605
- function _loadingPage(name) {
2606
- if (!fileIsExist(name)) {
2607
- return
2608
- }
2609
- const win = getMainWindow$1();
2610
- win.loadFile(name);
2611
- }
2612
-
2613
- /**
2614
- * cross takeover web
2615
- */
2616
- async function crossTakeover() {
2617
- const crossConf = getConfig$6().cross;
2618
- const mainConf = getConfig$6().mainServer;
2619
-
2620
- // loading page
2621
- if (mainConf.loadingPage.length > 0) {
2622
- const lp = path$6.join(getBaseDir$2, mainConf.loadingPage);
2623
- _loadingPage(lp);
2624
- }
2625
-
2626
- // cross service url
2627
- const service = mainConf.takeover;
2628
- if (!crossConf.hasOwnProperty(service)) {
2629
- throw new Error(`[electron-easymvc] Please Check the value of mainServer.takeover in the config file !`);
2630
- }
2631
- // check service
2632
- if (crossConf[service].enable != true) {
2633
- throw new Error(`[electron-easymvc] Please Check the value of cross.${service} enable is true !`);
2634
- }
2635
-
2636
- const entityName = crossConf[service].name;
2637
- const url = cross$1.getUrl(entityName);
2638
-
2639
- // 循环检查
2640
- let count = 0;
2641
- let serviceReady = false;
2642
- const times = isDev() ? 20 : 100;
2643
- const sleeptime = isDev() ? 1000 : 200;
2644
- while(!serviceReady && count < times){
2645
- await sleep(sleeptime);
2646
- try {
2647
- await axios({
2648
- method: 'get',
2649
- url,
2650
- timeout: 100,
2651
- proxy: false,
2652
- headers: {
2653
- 'Accept': 'text/html, application/json, text/plain, */*',
2654
- },
2655
- });
2656
- serviceReady = true;
2657
- } catch(err) {
2658
- // console.warn(err.stack)
2659
- }
2660
- count++;
2661
- }
2662
- debug$6('it takes %d seconds to start the cross serivce', count * sleeptime);
2663
-
2664
- if (serviceReady == false) {
2665
- const bootFailurePage = getHtmlFilepath('cross-failure.html');
2666
- const mainWindow = getMainWindow$1();
2667
- mainWindow.loadFile(bootFailurePage);
2668
- throw new Error(`[electron-easymvc] Please check cross service [${service}] ${url} !`)
2669
- }
2670
-
2671
- coreLogger$5.info(`[electron-easymvc] cross service [${service}] is started successfully`);
2672
- loadMainUrl('spa', url);
2673
- }
2674
-
2675
- var window = {
2676
- getMainWindow: getMainWindow$1,
2677
- createMainWindow: createMainWindow$1,
2678
- setCloseAndQuit: setCloseAndQuit$2,
2679
- getCloseAndQuit: getCloseAndQuit$1,
2680
- loadServer: loadServer$1
2681
- };
2682
-
2683
- const { app: electronApp$1 } = require$$9__default.default;
2684
- const { coreLogger: coreLogger$4 } = log;
2685
- const { is: is$5 } = utils;
2686
- const { cross } = cross_1;
2687
- const { createMainWindow, setCloseAndQuit: setCloseAndQuit$1, loadServer } = window;
2688
- const { eventBus: eventBus$1, ElectronAppReady, BeforeClose, Preload } = events;
2689
- const { getConfig: getConfig$5 } = config;
2690
-
2691
- /**
2692
- * 创建electron应用
2693
- */
2694
- function createElectron$1() {
2695
- const { singleLock } = getConfig$5();
2696
- // 允许多个实例
2697
- const gotTheLock = electronApp$1.requestSingleInstanceLock();
2698
- if (singleLock && !gotTheLock) {
2699
- electronApp$1.quit();
2700
- return;
2701
- }
2702
-
2703
- electronApp$1.whenReady().then(() => {
2704
- createMainWindow();
2705
- eventBus$1.emitLifecycle(Preload);
2706
- loadServer();
2707
- });
2708
-
2709
- electronApp$1.on('window-all-closed', () => {
2710
- if (!is$5.macOS()) {
2711
- coreLogger$4.info('[electron-easymvc] [lib/eeApp] window-all-closed quit');
2712
- electronApp$1.quit();
2713
- }
2714
- });
2715
-
2716
- electronApp$1.on('before-quit', () => {
2717
- setCloseAndQuit$1(true);
2718
- eventBus$1.emitLifecycle(BeforeClose);
2719
- cross.killAll();
2720
- });
2721
-
2722
- eventBus$1.emitLifecycle(ElectronAppReady);
2723
- }
2724
-
2725
- var app$3 = {
2726
- electronApp: electronApp$1,
2727
- createElectron: createElectron$1,
2728
- };
2729
-
2730
- const debug$5 = require$$0__default$1.default('electron-easymvc:core:loader:file_loader');
2731
- const assert$2 = require$$1__default$2.default;
2732
- const fs$3 = require$$0__default.default;
2733
- const path$5 = require$$1__default.default;
2734
- const globby = require$$4__default$2.default;
2735
- const is$4 = require$$1__default$1.default;
2736
- const { isBytecodeClass: isBytecodeClass$1, loadFile, filePatterns } = utilsExports;
2737
- const FULLPATH$1 = Symbol('LOADER_ITEM_FULLPATH');
2738
- const EXPORTS$1 = Symbol('LOADER_ITEM_EXPORTS');
2739
-
2740
- const defaults = {
2741
- directory: null,
2742
- target: null,
2743
- match: undefined,
2744
- caseStyle: 'camel',
2745
- initializer: null,
2746
- call: true,
2747
- inject: undefined,
2748
- };
2749
-
2750
- /**
2751
- * Load files from directory to target object.
2752
- */
2753
- let FileLoader$1 = class FileLoader {
2754
-
2755
- /**
2756
- * @class
2757
- * @param {Object} options - options
2758
- * @param {String|Array} options.directory - directories to be loaded
2759
- * @param {Object} options.target - attach the target object from loaded files
2760
- * @param {String} options.match - match the files when load, support glob, default to all js files
2761
- * @param {Function} options.initializer - custom file exports, receive two parameters, first is the inject object(if not js file, will be content buffer), second is an `options` object that contain `path`
2762
- * @param {Boolean} options.call - determine whether invoke when exports is function
2763
- * @param {Object} options.inject - an object that be the argument when invoke the function
2764
- * @param {String|Function} options.caseStyle - set property's case when converting a filepath to property list.
2765
- */
2766
- constructor(options) {
2767
- assert$2(options.directory, 'options.directory is required');
2768
- this.options = Object.assign({}, defaults, options);
2769
- debug$5("[constructor] options: %o", this.options);
2770
- }
2771
-
2772
- /**
2773
- * attach items to target object. Mapping the directory to properties.
2774
- * `xxx/group/repository.js` => `target.group.repository`
2775
- * @return {Object} target
2776
- */
2777
- load() {
2778
- const items = this.parse();
2779
- const target = {};
2780
- for (const item of items) {
2781
- // item { fullpath, properties: [ 'a', 'b', 'c'], exports }
2782
- item.properties.reduce((target, property, index) => {
2783
- let obj;
2784
- // properties is a path slice, only the last value is the file name
2785
- if (index === item.properties.length - 1) {
2786
- obj = item.exports;
2787
- if (obj && !is$4.primitive(obj)) {
2788
- obj[FULLPATH$1] = item.fullpath;
2789
- obj[EXPORTS$1] = true;
2790
- }
2791
- } else {
2792
- obj = target[property] || {};
2793
- }
2794
-
2795
- target[property] = obj;
2796
- // const properties = item.properties.slice(0, index + 1).join('.');
2797
- // debug('[load] properties: %s', properties);
2798
- return obj;
2799
- }, target);
2800
- }
2801
- //debug('[load] target: %O', target);
2802
- return target;
2803
- }
2804
-
2805
- /**
2806
- * Parse files from given directories, then return an items list, each item contains properties and exports.
2807
- * For example, parse `controller/group/repository.js`
2808
- * It returns a item
2809
- * ```
2810
- * {
2811
- * fullpath: '',
2812
- * properties: [ 'group', 'repository' ],
2813
- * exports: { ... },
2814
- * }
2815
- * ```
2816
- * `Properties` is an array that contains the directory of a filepath.
2817
- * `Exports` depends on type, if exports is a function, it will be called. if initializer is specified, it will be called with exports for customizing.
2818
- * @return {Array} items
2819
- */
2820
- parse() {
2821
- let files = this.options.match;
2822
- if (!files) {
2823
- files = filePatterns();
2824
- } else {
2825
- files = Array.isArray(files) ? files : [ files ];
2826
- }
2827
-
2828
- let directories = this.options.directory;
2829
- if (!Array.isArray(directories)) {
2830
- directories = [ directories ];
2831
- }
2832
-
2833
- const items = [];
2834
- debug$5('[parse] directories %o', directories);
2835
-
2836
- for (const directory of directories) {
2837
- const filepaths = globby.sync(files, { cwd: directory });
2838
- debug$5('[parse] filepaths %o', filepaths);
2839
- for (const filepath of filepaths) {
2840
- const fullpath = path$5.join(directory, filepath);
2841
- if (!fs$3.statSync(fullpath).isFile()) continue;
2842
- // get properties
2843
- // controller/foo/bar.js => [ 'foo', 'bar' ]
2844
- const properties = getProperties(filepath, this.options);
2845
- // debug('[parse] properties %o', properties);
2846
- // controller/foo/bar.js => controller.foo.bar
2847
- const pathName = directory.split(/[/\\]/).slice(-1) + '.' + properties.join('.');
2848
- // debug('[parse] pathName %s', pathName);
2849
- // get exports from the file
2850
- let exports$1 = getExports(fullpath, this.options, pathName);
2851
- // ignore exports when it's null or false returned by filter function
2852
- if (exports$1 == null) continue;
2853
-
2854
- // set properties of class
2855
- if (is$4.class(exports$1) || isBytecodeClass$1(exports$1)) {
2856
- exports$1.prototype.pathName = pathName;
2857
- exports$1.prototype.fullPath = fullpath;
2858
- }
2859
- items.push({ fullpath, properties, exports: exports$1 });
2860
- //debug('[parse] fullpath %s, properties %o, export %o', fullpath, properties, exports);
2861
- }
2862
- }
2863
- //debug('[parse] items %O', items);
2864
- return items;
2865
- }
2866
- };
2867
-
2868
- // convert file path to an array of properties
2869
- // a/b/c.js => ['a', 'b', 'c']
2870
- function getProperties(filepath, { caseStyle }) {
2871
- // if caseStyle is function, return the result of function
2872
- if (is$4.function(caseStyle)) {
2873
- const result = caseStyle(filepath);
2874
- assert$2(is$4.array(result), `caseStyle expect an array, but got ${result}`);
2875
- return result;
2876
- }
2877
- // use default camelize
2878
- return defaultCamelize(filepath, caseStyle);
2879
- }
2880
-
2881
- // Get exports from filepath
2882
- // If exports is null/undefined, it will be ignored
2883
- function getExports(fullpath, { initializer, call, inject }, pathName) {
2884
- let exports$1 = loadFile(fullpath);
2885
- //debug('[getExports] exports %o', exports);
2886
- if (initializer) {
2887
- // exports type is Class or Object
2888
- exports$1 = initializer(exports$1, { path: fullpath, pathName });
2889
- }
2890
-
2891
- if (is$4.class(exports$1) || is$4.generatorFunction(exports$1) || is$4.asyncFunction(exports$1) || isBytecodeClass$1(exports$1)) {
2892
- return exports$1;
2893
- }
2894
-
2895
- // whether to execute the function
2896
- if (call && is$4.function(exports$1)) {
2897
- exports$1 = exports$1(inject);
2898
- if (exports$1 != null) {
2899
- return exports$1;
2900
- }
2901
- }
2902
-
2903
- return exports$1;
2904
- }
2905
-
2906
- function defaultCamelize(filepath, caseStyle) {
2907
- const properties = filepath.substring(0, filepath.lastIndexOf('.')).split('/');
2908
- return properties.map(property => {
2909
- if (!/^[a-z][a-z0-9_-]*$/i.test(property)) {
2910
- throw new Error(`${property} is not match 'a-z0-9_-' in ${filepath}`);
2911
- }
2912
-
2913
- // use default camelize, will capitalize the first letter
2914
- // foo_bar.js > FooBar
2915
- // fooBar.js > FooBar
2916
- // FooBar.js > FooBar
2917
- // FooBar.js > FooBar
2918
- // FooBar.js > fooBar
2919
- property = property.replace(/[_-][a-z]/ig, s => s.substring(1).toUpperCase());
2920
- let first = property[0];
2921
- switch (caseStyle) {
2922
- case 'lower':
2923
- first = first.toLowerCase();
2924
- break;
2925
- case 'upper':
2926
- first = first.toUpperCase();
2927
- break;
2928
- }
2929
- return first + property.substring(1);
2930
- });
2931
- }
2932
-
2933
- var file_loader = {
2934
- FileLoader: FileLoader$1,
2935
- EXPORTS: EXPORTS$1,
2936
- FULLPATH: FULLPATH$1,
2937
- };
2938
-
2939
- const debug$4 = require$$0__default$1.default('electron-easymvc:controller:controller_loader');
2940
- const path$4 = require$$1__default.default;
2941
- const is$3 = require$$1__default$1.default;
2942
- const { getElectronDir } = ps;
2943
- const { Timing } = timing;
2944
- const { FileLoader, FULLPATH } = file_loader;
2945
- const { isBytecodeClass, callFn } = utilsExports;
2946
-
2947
- let ControllerLoader$1 = class ControllerLoader {
2948
- constructor() {
2949
- this.timing = new Timing();
2950
- }
2951
-
2952
- /**
2953
- * Load controller/xxx.js
2954
- */
2955
- load() {
2956
- this.timing.start('Load Controller');
2957
-
2958
- const opt = {
2959
- caseStyle: 'lower',
2960
- directory: path$4.join(getElectronDir(), 'controller'),
2961
- initializer: (obj, opt) => {
2962
- if (is$3.class(obj) || isBytecodeClass(obj)) {
2963
- obj.prototype.pathName = opt.pathName;
2964
- obj.prototype.fullPath = opt.path;
2965
- return wrapClass(obj);
2966
- }
2967
- return obj;
2968
- },
2969
- };
2970
- const target = new FileLoader(opt).load();
2971
- debug$4("[load] controllers: %o", target);
2972
- this.timing.end('Load Controller');
2973
- return target;
2974
- }
2975
- };
2976
-
2977
- // wrap the class, yield a object with middlewares
2978
- function wrapClass(Controller) {
2979
- let proto = Controller.prototype;
2980
- const ret = {};
2981
- // tracing the prototype chain
2982
- while (proto !== Object.prototype) {
2983
- const keys = Object.getOwnPropertyNames(proto);
2984
- // debug("[wrapClass] keys:", keys);
2985
- for (const key of keys) {
2986
- // getOwnPropertyNames will return constructor
2987
- // that should be ignored
2988
- if (key === 'constructor') {
2989
- continue;
2990
- }
2991
- // skip getter, setter & non-function properties
2992
- const d = Object.getOwnPropertyDescriptor(proto, key);
2993
- // prevent to override sub method
2994
- if (is$3.function(d.value) && !ret.hasOwnProperty(key)) {
2995
- ret[key] = methodToMiddleware(Controller, key);
2996
- ret[key][FULLPATH] = Controller.prototype.fullPath + '#' + Controller.name + '.' + key + '()';
2997
- }
2998
- }
2999
- proto = Object.getPrototypeOf(proto);
3000
- }
3001
-
3002
- return ret;
3003
- }
3004
-
3005
- function methodToMiddleware(Controller, key) {
3006
- return function classControllerMiddleware(...args) {
3007
- const controller = new Controller();
3008
- return callFn(controller[key], args, controller);
3009
- };
3010
- }
3011
-
3012
- var controller_loader = {
3013
- ControllerLoader: ControllerLoader$1
3014
- };
3015
-
3016
- const { ControllerLoader } = controller_loader;
3017
-
3018
- const Instance$1 = {
3019
- controller: null,
3020
- };
3021
-
3022
- function loadController$1() {
3023
- const controllerLoader = new ControllerLoader();
3024
- Instance$1.controller = controllerLoader.load();
3025
- }
3026
-
3027
- function getController$3() {
3028
- if (!Instance$1.controller) {
3029
- loadController$1();
3030
- }
3031
- return Instance$1.controller;
3032
- }
3033
-
3034
- var controller = {
3035
- loadController: loadController$1,
3036
- getController: getController$3
3037
- };
3038
-
3039
- const debug$3 = require$$0__default$1.default('electron-easymvc:socket:socketServer');
3040
- const is$2 = require$$1__default$1.default;
3041
- const { Server } = require$$2__default$3.default;
3042
- const { coreLogger: coreLogger$3 } = log;
3043
- const { getConfig: getConfig$4 } = config;
3044
- const { SocketIO } = channel;
3045
- const { getController: getController$2 } = controller;
3046
- const { getPort: getPort$1 } = port;
3047
-
3048
- /**
3049
- * socket server
3050
- */
3051
- let SocketServer$1 = class SocketServer {
3052
- constructor () {
3053
- const { socketServer, mainServer } = getConfig$4();
3054
- this.config = socketServer;
3055
- this.channelSeparator = mainServer.channelSeparator;
3056
- this.socket = undefined;
3057
- this.io = undefined;
3058
- this.init();
3059
- }
3060
-
3061
- async init() {
3062
- if (this.config.enable == false) {
3063
- return;
3064
- }
3065
-
3066
- const port = await getPort$1({port: parseInt(this.config.port)});
3067
- if (!port) {
3068
- throw new Error('[electron-easymvc] [socket/socketServer] socekt port required, and must be a number !');
3069
- }
3070
- coreLogger$3.info('[electron-easymvc] [socket/socketServer] port is:', port);
3071
-
3072
- process.env.EE_SOCKET_PORT = port;
3073
- this.config.port = port;
3074
- this.io = new Server(port, this.config);
3075
- this.connect();
3076
- }
3077
-
3078
- connect () {
3079
- const controller = getController$2();
3080
- this.io.on('connection', (socket) => {
3081
- const channel = this.config.channel || SocketIO.partySoftware;
3082
- this.socket = socket;
3083
- socket.on(channel, async (message, callback) => {
3084
- coreLogger$3.info('[electron-easymvc] [socket/socketServer] socket id:' + socket.id + ' message cmd: ' + message.cmd);
3085
-
3086
- try {
3087
- // find function
3088
- const cmd = message.cmd;
3089
- const args = message.args;
3090
- let fn = null;
3091
- debug$3('[socket] channel %s', cmd);
3092
- if (is$2.string(cmd)) {
3093
- const actions = cmd.split(this.channelSeparator);
3094
- debug$3('[findFn] channel %o', actions);
3095
- let obj = { controller };
3096
- actions.forEach(key => {
3097
- obj = obj[key];
3098
- if (!obj) throw new Error(`class or function '${key}' not exists`);
3099
- });
3100
- fn = obj;
3101
- }
3102
- if (!fn) throw new Error('function not exists');
3103
-
3104
- const result = await fn.call(controller, args);
3105
- if (callback) {
3106
- callback(result);
3107
- }
3108
- } catch (err) {
3109
- coreLogger$3.error('[electron-easymvc] [socket/socketServer] throw error:', err);
3110
- }
3111
- });
3112
- });
3113
- }
3114
- };
3115
-
3116
- var socketServer = {
3117
- SocketServer: SocketServer$1,
3118
- };
3119
-
3120
- const debug$2 = require$$0__default$1.default('electron-easymvc:socket:httpServer');
3121
- const assert$1 = require$$1__default$2.default;
3122
- const is$1 = require$$1__default$1.default;
3123
- const Koa$1 = require$$3__default$2.default;
3124
- const cors = require$$4__default$3.default;
3125
- const koaBody = require$$5__default.default;
3126
- const https = require$$6__default.default;
3127
- const fs$2 = require$$0__default.default;
3128
- const path$3 = require$$1__default.default;
3129
- const _ = require$$9__default$1.default;
3130
- const { coreLogger: coreLogger$2 } = log;
3131
- const { getBaseDir: getBaseDir$1 } = ps;
3132
- const { getController: getController$1 } = controller;
3133
- const { getConfig: getConfig$3 } = config;
3134
- const { getPort } = port;
3135
-
3136
- let channelSeparator = '/';
3137
-
3138
- /**
3139
- * http server
3140
- */
3141
- let HttpServer$1 = class HttpServer {
3142
- constructor () {
3143
- const { httpServer, mainServer } = getConfig$3();
3144
- this.config = httpServer;
3145
- channelSeparator = mainServer.channelSeparator;
3146
- this.httpApp = undefined;
3147
- this.init();
3148
- }
3149
-
3150
- async init() {
3151
- if (this.config.enable == false) {
3152
- return;
3153
- }
3154
-
3155
- const port = await getPort({port: parseInt(this.config.port)});
3156
- if (!port) {
3157
- throw new Error('[electron-easymvc] [socket/HttpServer] http port required, and must be a number !');
3158
- }
3159
- process.env.EE_HTTP_PORT = port;
3160
- this.config.port = port;
3161
-
3162
- this._create();
3163
- }
3164
-
3165
- /**
3166
- * 创建服务
3167
- */
3168
- _create () {
3169
- const config = this.config;
3170
- // config.default 增加koaConfig配置项
3171
- const koaConfig = config.koaConfig || {};
3172
- const { preMiddleware = [], postMiddleware = [], errorHandler = null } = koaConfig;
3173
- const isHttps = config?.https?.enable ?? false;
3174
- const sslOptions = {};
3175
-
3176
- if (isHttps === true) {
3177
- config.protocol = 'https://';
3178
- const keyFile = path$3.join(getBaseDir$1(), config.https.key);
3179
- const certFile = path$3.join(getBaseDir$1(), config.https.cert);
3180
- assert$1(fs$2.existsSync(keyFile), 'ssl key file is required');
3181
- assert$1(fs$2.existsSync(certFile), 'ssl cert file is required');
3182
-
3183
- sslOptions.key = fs$2.readFileSync(keyFile);
3184
- sslOptions.cert = fs$2.readFileSync(certFile);
3185
- }
3186
- const url = config.protocol + config.host + ':' + config.port;
3187
- const corsOptions = config.cors;
3188
-
3189
- const koaApp = new Koa$1();
3190
-
3191
- // 设置错误处理器,便于统一错误代码处理
3192
- this._setupErrorHandler(koaApp, errorHandler);
3193
-
3194
- // 加载前置中间件
3195
- this._loadMiddlewares(koaApp, preMiddleware);
3196
-
3197
- // 核心中间件
3198
- koaApp
3199
- .use(cors(corsOptions))
3200
- .use(koaBody(config.body))
3201
- .use(this._dispatch);
3202
-
3203
- // 加载后置中间件
3204
- this._loadMiddlewares(koaApp, postMiddleware, 'post');
3205
-
3206
- let msg = '[electron-easymvc] [socket/http] server is: ' + url;
3207
- const listenOpt = {
3208
- host: config.host,
3209
- port: config.port
3210
- };
3211
- if (isHttps) {
3212
- https.createServer(sslOptions, koaApp.callback()).listen(listenOpt, (err) => {
3213
- msg = err ? err : msg;
3214
- coreLogger$2.info(msg);
3215
- });
3216
- } else {
3217
- koaApp.listen(listenOpt, (e) => {
3218
- msg = e ? e : msg;
3219
- coreLogger$2.info(msg);
3220
- });
3221
- }
3222
-
3223
- this.httpApp = koaApp;
3224
- }
3225
-
3226
- /**
3227
- * 路由分发
3228
- */
3229
- async _dispatch (ctx, next) {
3230
- const controller = getController$1();
3231
- const { filterRequest } = getConfig$3().httpServer;
3232
- let uriPath = ctx.request.path;
3233
- const method = ctx.request.method;
3234
- let params = ctx.request.query;
3235
- params = is$1.object(params) ? JSON.parse(JSON.stringify(params)) : {};
3236
- const body = ctx.request.body;
3237
-
3238
- // 默认
3239
- ctx.response.status = 200;
3240
-
3241
- try {
3242
- // 找函数
3243
- // 去除开头的 '/'
3244
- if (uriPath.indexOf('/') == 0) {
3245
- uriPath = uriPath.substring(1);
3246
- }
3247
- // 过滤
3248
- if (_.includes(filterRequest.uris, uriPath)) {
3249
- ctx.response.body = filterRequest.returnData;
3250
- await next();
3251
- return
3252
- }
3253
- if (uriPath.slice(0, 10) != 'controller') {
3254
- uriPath = 'controller/' + uriPath;
3255
- }
3256
- const cmd = uriPath.split('/').join(channelSeparator);
3257
- debug$2('[request] uri %s', cmd);
3258
- const args = (method == 'POST') ? body: params;
3259
- let fn = null;
3260
- if (is$1.string(cmd)) {
3261
- const actions = cmd.split(channelSeparator);
3262
- debug$2('[findFn] channel %o', actions);
3263
- let obj = { controller };
3264
- actions.forEach(key => {
3265
- obj = obj[key];
3266
- if (!obj) throw new Error(`class or function '${key}' not exists`);
3267
- });
3268
- fn = obj;
3269
- }
3270
- if (!fn) throw new Error('function not exists');
3271
-
3272
- const result = await fn.call(controller, args, ctx);
3273
- ctx.response.body = result;
3274
- } catch (err) {
3275
- coreLogger$2.error('[electron-easymvc/httpServer] throw error:', err);
3276
- }
3277
-
3278
- await next();
3279
- }
3280
-
3281
- getHttpApp() {
3282
- return this.httpApp;
3283
- }
3284
-
3285
- // 设置错误处理函数
3286
- _setupErrorHandler(app, errorHandler) {
3287
- if (is$1.function(errorHandler)) {
3288
- app.on('error', errorHandler);
3289
- }
3290
- }
3291
-
3292
- /**
3293
- * 加载前置、后置中间件
3294
- * @param {*} app koaApp示例
3295
- * @param {*} middlewares 中间件数组
3296
- * @param {*} type 类型,pre/post
3297
- */
3298
- _loadMiddlewares(app, middlewares = [], type = 'pre') {
3299
- if (is$1.array(middlewares)) {
3300
- middlewares.forEach((middleware) => {
3301
- if (is$1.function(middleware)) {
3302
- // middleware是一个方法
3303
- // 返回值是中间件(ctx, next) => {}的异步函数
3304
- // 便于使用async/await进行同步编程
3305
- app.use(middleware());
3306
- } else {
3307
- coreLogger$2.warn(`[electron-easymvc/httpServer] Invalid ${type} middleware detected, skipping.`);
3308
- }
3309
- });
3310
- }
3311
- }
3312
- };
3313
-
3314
- var httpServer = {
3315
- HttpServer: HttpServer$1
3316
- };
3317
-
3318
- const debug$1 = require$$0__default$1.default('electron-easymvc:socket:ipcServer');
3319
- const is = require$$1__default$1.default;
3320
- const { ipcMain } = require$$9__default.default;
3321
- const { coreLogger: coreLogger$1 } = log;
3322
- const { getController } = controller;
3323
- const { EXPORTS } = file_loader;
3324
- const { getConfig: getConfig$2 } = config;
3325
-
3326
- let IpcServer$1 = class IpcServer {
3327
- constructor () {
3328
- const { mainServer } = getConfig$2();
3329
- this.channelSeparator = mainServer.channelSeparator;
3330
- this.directory = 'controller';
3331
- this.init();
3332
- }
3333
- init() {
3334
- const controller = getController();
3335
- this.loop(controller, this.directory);
3336
- }
3337
-
3338
- loop(obj, pathname) {
3339
- const keys = Object.keys(obj);
3340
- // debug("[loop] keys: %j", keys);
3341
- for (const key of keys) {
3342
- if (key === 'constructor') {
3343
- continue;
3344
- }
3345
- let subObj = obj[key];
3346
- let propertyChain = pathname + '.' + key;
3347
- if (subObj && subObj[EXPORTS] === true) {
3348
- this.register(subObj, propertyChain);
3349
- } else if (typeof subObj === 'object') {
3350
- // 如果子对象依然是对象,则递归调用继续判断
3351
- this.loop(subObj, propertyChain);
3352
- }
3353
- }
3354
- }
3355
-
3356
- register(exportObj, propertyChain) {
3357
- const controller = getController();
3358
- const keys = Object.keys(exportObj);
3359
- for (const key of keys) {
3360
- // Supports two types of routing separators
3361
- // channel: controller.file.function | controller/file/function
3362
- const tmpChannel = `${propertyChain}.${key}`;
3363
- const channel = tmpChannel.split('.').join(this.channelSeparator);
3364
- debug$1('[register] channel %s', channel);
3365
-
3366
- // send/on model
3367
- ipcMain.on(channel, async (event, params) => {
3368
- try {
3369
- const fn = this.findFn(controller, channel);
3370
- const result = await fn.call(controller, params, event);
3371
-
3372
- event.returnValue = result;
3373
- event.reply(`${channel}`, result);
3374
- } catch(e) {
3375
- coreLogger$1.error('[electron-easymvc] [socket/IpcServer] send/on throw error:', e);
3376
- }
3377
- });
3378
-
3379
- // invoke/handle model
3380
- ipcMain.handle(channel, async (event, params) => {
3381
- try {
3382
- const fn = this.findFn(controller, channel);
3383
- const result = await fn.call(controller, params, event);
3384
-
3385
- return result;
3386
- } catch(e) {
3387
- coreLogger$1.error('[electron-easymvc] [socket/IpcServer] invoke/handle throw error:', e);
3388
- }
3389
- });
3390
- }
3391
- }
3392
-
3393
- findFn (controller, c) {
3394
- try {
3395
- // 找函数
3396
- const cmd = c;
3397
- let fn = null;
3398
- if (is.string(cmd)) {
3399
- const actions = cmd.split(this.channelSeparator);
3400
- debug$1('[findFn] channel %o', actions);
3401
- let obj = { controller };
3402
- actions.forEach(key => {
3403
- obj = obj[key];
3404
- if (!obj) throw new Error(`class or function '${key}' not exists`);
3405
- });
3406
- fn = obj;
3407
- }
3408
- if (!fn) throw new Error('function not exists');
3409
-
3410
- return fn;
3411
- } catch (err) {
3412
- coreLogger$1.error('[electron-easymvc] [socket/IpcServer] throw error:', err);
3413
- }
3414
- return null;
3415
- }
3416
-
3417
- };
3418
-
3419
- var ipcServer = {
3420
- IpcServer: IpcServer$1
3421
- };
3422
-
3423
- const IoServer = require$$2__default$3.default;
3424
- const IoClient = require$$1__default$4.default;
3425
- const Koa = require$$3__default$2.default;
3426
- const { SocketServer } = socketServer;
3427
- const { HttpServer } = httpServer;
3428
- const { IpcServer } = ipcServer;
3429
-
3430
- const Instance = {
3431
- socketServer: null,
3432
- httpServer: null};
3433
-
3434
- // create SocketServer
3435
- function createSocketServer() {
3436
- Instance.socketServer = new SocketServer();
3437
- return Instance.socketServer;
3438
- }
3439
-
3440
- // socketServer
3441
- function getSocketServer() {
3442
- return Instance.socketServer;
3443
- }
3444
-
3445
- // create Http Server
3446
- function createHttpServer() {
3447
- Instance.httpServer = new HttpServer();
3448
- return Instance.httpServer;
3449
- }
3450
-
3451
- // httpServer
3452
- function getHttpServer() {
3453
- return Instance.httpServer;
3454
- }
3455
-
3456
- // create IPC Server
3457
- function createIpcServer() {
3458
- Instance.ipcServer = new IpcServer();
3459
- return Instance.ipcServer;
3460
- }
3461
-
3462
- // ipcServer
3463
- function getIpcServer() {
3464
- return Instance.ipcServer;
3465
- }
3466
-
3467
-
3468
- // load socket server
3469
- function loadSocket$1() {
3470
- createSocketServer();
3471
- createHttpServer();
3472
- createIpcServer();
3473
- }
3474
-
3475
- var socket = {
3476
- Koa,
3477
- IoServer,
3478
- IoClient,
3479
- loadSocket: loadSocket$1,
3480
- getSocketServer,
3481
- getHttpServer,
3482
- getIpcServer
3483
- };
3484
-
3485
- const { createElectron } = app$3;
3486
- const { getMainWindow, setCloseAndQuit, getCloseAndQuit } = window;
3487
-
3488
- // load socket server
3489
- function loadElectron$1() {
3490
- createElectron();
3491
- }
3492
-
3493
- var electron = {
3494
- loadElectron: loadElectron$1,
3495
- getMainWindow,
3496
- setCloseAndQuit,
3497
- getCloseAndQuit
3498
- };
3499
-
3500
- require$$0__default$1.default('electron-easymvc:app:appliaction');
3501
- const { loadController } = controller;
3502
- const { eventBus, Ready } = events;
3503
- const { loadSocket } = socket;
3504
- const { loadElectron } = electron;
3505
-
3506
- class Appliaction {
3507
- constructor() {
3508
-
3509
- }
3510
-
3511
- register(eventName, handler) {
3512
- return eventBus.register(eventName, handler);
3513
- }
3514
-
3515
- run() {
3516
- loadController();
3517
- loadSocket();
3518
- eventBus.emitLifecycle(Ready);
3519
- loadElectron();
3520
- }
3521
- }
3522
-
3523
- const app$2 = new Appliaction();
3524
-
3525
- var application = {
3526
- app: app$2,
3527
- };
3528
-
3529
- const fs$1 = require$$0__default.default;
3530
- const { getUserHomeHiddenAppDir, getLogDir, getDataDir: getDataDir$1 } = ps;
3531
- const { mkdir: mkdir$1 } = helper;
3532
- function loadDir$1() {
3533
- initDir();
3534
- }
3535
-
3536
- function initDir() {
3537
- const homeHiddenAppDir = getUserHomeHiddenAppDir();
3538
- if (!fs$1.existsSync(homeHiddenAppDir)) {
3539
- mkdir$1(homeHiddenAppDir, { mode: 0o755 });
3540
- }
3541
- const dataDir = getDataDir$1();
3542
- if (!fs$1.existsSync(dataDir)) {
3543
- mkdir$1(dataDir, { mode: 0o755 });
3544
- }
3545
- const logDir = getLogDir();
3546
- if (!fs$1.existsSync(logDir)) {
3547
- mkdir$1(logDir, { mode: 0o755 });
3548
- }
3549
- }
3550
-
3551
- var dir = {
3552
- loadDir: loadDir$1
3553
- };
3554
-
3555
- const debug = require$$0__default$1.default('electron-easymvc:app:boot');
3556
- const path$2 = require$$1__default.default;
3557
- const { loadException } = exception;
3558
- const { electronApp } = app$3;
3559
- const { getArgumentByName, getBundleDir, getElectronCodeDir } = ps;
3560
- const { loadConfig } = config;
3561
- const { loadLog } = log;
3562
- const { app: app$1 } = application;
3563
- const { loadDir } = dir;
3564
-
3565
- let ElectronEgg$3 = class ElectronEgg {
3566
- constructor() {
3567
- const baseDir = electronApp.getAppPath();
3568
- const { env } = process;
3569
- const environmet = getArgumentByName('env') || 'prod';
3570
- const debugging = getArgumentByName('debuger') == 'true'? true : false;
3571
-
3572
- // Debugging source code
3573
- let electronDir = getBundleDir(baseDir);
3574
- if (debugging) {
3575
- electronDir = getElectronCodeDir(baseDir);
3576
- }
3577
-
3578
- const options = {
3579
- env: environmet,
3580
- baseDir,
3581
- electronDir,
3582
- appName: electronApp.getName(),
3583
- userHome: electronApp.getPath('home'),
3584
- appData: electronApp.getPath('appData'),
3585
- appUserData: electronApp.getPath('userData'),
3586
- appVersion: electronApp.getVersion(),
3587
- isPackaged: electronApp.isPackaged,
3588
- execDir: baseDir,
3589
- };
3590
-
3591
- // exec directory (exe dmg dep) for prod
3592
- if (environmet == 'prod' && options.isPackaged) {
3593
- options.execDir = path$2.dirname(electronApp.getPath('exe'));
3594
- }
3595
-
3596
- // normalize env
3597
- env.EE_ENV = environmet;
3598
- env.EE_APP_NAME = options.appName;
3599
- env.EE_APP_VERSION = options.appVersion;
3600
- env.EE_BASE_DIR = options.baseDir;
3601
- env.EE_ELECTRON_DIR = options.electronDir;
3602
- env.EE_USER_HOME = options.userHome;
3603
- env.EE_APP_DATA = options.appData;
3604
- env.EE_APP_USER_DATA = options.appUserData;
3605
- env.EE_EXEC_DIR = options.execDir;
3606
- env.EE_IS_PACKAGED = options.isPackaged;
3607
- env.EE_SOCKET_PORT = null;
3608
- env.EE_HTTP_PORT = null;
3609
- debug('[constructor] options:%j', options);
3610
-
3611
- this.init();
3612
- }
3613
-
3614
- init() {
3615
- // basic functions
3616
- loadException();
3617
- loadConfig();
3618
- loadDir();
3619
- loadLog();
3620
- }
3621
-
3622
- register(eventName, handler) {
3623
- return app$1.register(eventName, handler);
3624
- }
3625
-
3626
- run() {
3627
- app$1.run();
3628
- }
3629
- };
3630
-
3631
- var boot = {
3632
- ElectronEgg: ElectronEgg$3,
3633
- };
3634
-
3635
- const { ElectronEgg: ElectronEgg$2 } = boot;
3636
-
3637
- var app = {
3638
- ElectronEgg: ElectronEgg$2,
3639
- };
3640
-
3641
- const { ElectronEgg: ElectronEgg$1 } = app;
3642
-
3643
- var eeCore = {
3644
- ElectronEgg: ElectronEgg$1
3645
- };
3646
-
3647
- const assert = require$$1__default$2.default;
3648
- const fs = require$$0__default.default;
3649
- const path$1 = require$$1__default.default;
3650
- const BSqlite = require$$3__default$3.default;
3651
- const { mkdir } = helper;
3652
- const { getDataDir } = ps;
3653
-
3654
- let SqliteStorage$1 = class SqliteStorage {
3655
- constructor (name, opt = {}) {
3656
- assert(name, `db name ${name} Cannot be empty`);
3657
-
3658
- this.name = name;
3659
- this.mode = this.getMode(name);
3660
- this.dbDir = this._createDatabaseDir();
3661
- this.fileName = this._formatFileName(name);
3662
- this.db = this._initDB(opt);
3663
- }
3664
-
3665
- /**
3666
- * 初始化db
3667
- */
3668
- _initDB (opt = {}) {
3669
- let options = Object.assign({
3670
- timeout: 5000,
3671
- }, opt);
3672
-
3673
- // 存储类型:db文件、内存(:memory:)
3674
- let dbPath = this.name;
3675
- if (this.mode != 'memory') {
3676
- dbPath = this.getFilePath();
3677
- }
3678
-
3679
- const db = new BSqlite(dbPath, options);
3680
-
3681
- // 如果是文件类型,判断文件是否创建成功
3682
- if (this.mode != 'memory') {
3683
- assert(fs.existsSync(dbPath), `error: db ${dbPath} not exists`);
3684
- }
3685
-
3686
- return db;
3687
- }
3688
-
3689
- /**
3690
- * 获取文件名
3691
- */
3692
- _formatFileName (name) {
3693
- let fileName = name;
3694
- if (this.mode != 'memory') {
3695
- fileName = path$1.basename(name);
3696
- }
3697
-
3698
- return fileName;
3699
- }
3700
-
3701
- /**
3702
- * 创建storage目录
3703
- */
3704
- _createDatabaseDir () {
3705
- let dbDir = path$1.join(getDataDir(), 'db');
3706
- if (this.mode == 'absolute') {
3707
- dbDir = path$1.dirname(this.name);
3708
- }
3709
-
3710
- if (!fs.existsSync(dbDir)) {
3711
- mkdir(dbDir, { mode: 0o755 });
3712
- }
3713
-
3714
- return dbDir;
3715
- }
3716
-
3717
- /**
3718
- * 获取file path 模式
3719
- */
3720
- getMode (name) {
3721
- let mode = '';
3722
-
3723
- // 内存模式
3724
- if (name == ':memory:') {
3725
- mode = 'memory';
3726
- return mode;
3727
- }
3728
-
3729
- assert(path$1.extname(name) == '.db', `error: db ${name} file ext name must be .db`);
3730
-
3731
- // 路径模式
3732
- name = name.replace(/[/\\]/g, '/');
3733
- if (name.indexOf('/') !== -1) {
3734
- const isAbsolute = path$1.isAbsolute(name);
3735
- if (isAbsolute) {
3736
- mode = 'absolute';
3737
- } else {
3738
- mode = 'relative';
3739
- }
3740
- return mode;
3741
- }
3742
-
3743
- // 仅文件名
3744
- mode = 'onlyName';
3745
-
3746
- return mode;
3747
- }
3748
-
3749
- /**
3750
- * 获取 db 文件目录
3751
- */
3752
- getDbDir () {
3753
- return this.dbDir;
3754
- }
3755
-
3756
- /**
3757
- * 获取文件绝对路径
3758
- */
3759
- getFilePath () {
3760
- const dbFile = path$1.join(this.dbDir, this.fileName);
3761
-
3762
- return dbFile;
3763
- }
3764
- };
3765
-
3766
- var sqliteStorage = {
3767
- SqliteStorage: SqliteStorage$1
3768
- };
3769
-
3770
- const { SqliteStorage } = sqliteStorage;
3771
-
3772
- var storage = {
3773
- SqliteStorage
3774
- };
3775
-
3776
- const path = require$$1__default.default;
3777
- const EventEmitter$2 = require$$0__default$3.default;
3778
- const serialize = require$$2__default$4.default;
3779
- const { fork } = require$$3__default.default;
3780
- const { coreLogger } = log;
3781
- const { getBaseDir, isPackaged, allEnv } = ps;
3782
- const { Processes, Events: Events$2, Receiver } = channel;
3783
- const { getRandomString } = helper;
3784
- const { getFullpath: getFullpath$2 } = loader;
3785
- const { extend: extend$1 } = extend_1;
3786
-
3787
- let JobProcess$2 = class JobProcess {
3788
- constructor(host, opt = {}) {
3789
-
3790
- let cwd = getBaseDir();
3791
- const appPath = path.join(__dirname, 'app.js');
3792
- if (isPackaged()) {
3793
- // todo fork的cwd目录为什么要在app.asar外 ?
3794
- cwd = path.join(getBaseDir(), '..');
3795
- }
3796
-
3797
- const options = extend$1(true, {
3798
- processArgs: {},
3799
- processOptions: {
3800
- cwd: cwd,
3801
- env: allEnv(),
3802
- stdio: 'ignore' // pipe
3803
- }
3804
- }, opt);
3805
-
3806
- this.emitter = new EventEmitter$2();
3807
- this.host = host;
3808
- this.args = [];
3809
- this.sleeping = false;
3810
-
3811
- // 传递给子进程的参数
3812
- this.args.push(JSON.stringify(options.processArgs));
3813
-
3814
- this.child = fork(appPath, this.args, options.processOptions);
3815
- this.pid = this.child.pid;
3816
- this._init();
3817
- }
3818
-
3819
- _init() {
3820
- const { messageLog } = this.host.config;
3821
- this.child.on('message', (m) => {
3822
- if (messageLog == true) {
3823
- coreLogger.info(`[electron-easymvc] [jobs/child] received a message from child-process, message: ${serialize(m)}`);
3824
- }
3825
-
3826
- if (m.channel == Processes.showException) {
3827
- coreLogger.error(`${m.data}`);
3828
- }
3829
-
3830
- // 收到子进程消息,转发到 event
3831
- if (m.channel == Processes.sendToMain) {
3832
- this._eventEmit(m);
3833
- }
3834
- });
3835
-
3836
- this.child.on('exit', (code, signal) => {
3837
- let data = {
3838
- pid: this.pid
3839
- };
3840
- this.host.emit(Events$2.childProcessExit, data);
3841
- coreLogger.info(`[electron-easymvc] [jobs/child] received a exit from child-process, code:${code}, signal:${signal}, pid:${this.pid}`);
3842
- });
3843
-
3844
- this.child.on('error', (err) => {
3845
- let data = {
3846
- pid: this.pid
3847
- };
3848
- this.host.emit(Events$2.childProcessError, data);
3849
- coreLogger.error(`[electron-easymvc] [jobs/child] received a error from child-process, error: ${err}, pid:${this.pid}`);
3850
- });
3851
- }
3852
-
3853
- _eventEmit(m) {
3854
- switch (m.eventReceiver) {
3855
- case Receiver.forkProcess:
3856
- this.emitter.emit(m.event, m.data);
3857
- break;
3858
- case Receiver.childJob:
3859
- this.host.emit(m.event, m.data);
3860
- break;
3861
- default:
3862
- this.host.emit(m.event, m.data);
3863
- this.emitter.emit(m.event, m.data);
3864
- break;
3865
- }
3866
- }
3867
-
3868
- dispatch(cmd, jobPath = '', ...params) {
3869
- // 消息对象
3870
- const mid = getRandomString();
3871
- let msg = {
3872
- mid,
3873
- cmd,
3874
- jobPath,
3875
- jobParams: params
3876
- };
3877
-
3878
- // todo 是否会发生监听未完成时,接收不到消息?
3879
- // 发消息到子进程
3880
- this.child.send(msg);
3881
- }
3882
-
3883
- callFunc(jobPath = '', funcName = '', ...params) {
3884
- jobPath = getFullpath$2(jobPath);
3885
-
3886
- // 消息对象
3887
- const mid = getRandomString();
3888
- let msg = {
3889
- mid,
3890
- cmd:'run',
3891
- jobPath,
3892
- jobFunc: funcName,
3893
- jobFuncParams: params
3894
- };
3895
- this.child.send(msg);
3896
- }
3897
-
3898
- kill(timeout = 1000) {
3899
- this.child.kill('SIGINT');
3900
- setTimeout(() => {
3901
- if (this.child.killed) return;
3902
- this.child.kill('SIGKILL');
3903
- }, timeout);
3904
- }
3905
- };
3906
-
3907
- var jobProcess = {
3908
- JobProcess: JobProcess$2
3909
- };
3910
-
3911
- const EventEmitter$1 = require$$0__default$3.default;
3912
- const { JobProcess: JobProcess$1 } = jobProcess;
3913
- const { getFullpath: getFullpath$1 } = loader;
3914
- const { Events: Events$1 } = channel;
3915
- const { getConfig: getConfig$1 } = config;
3916
- const { extend } = extend_1;
3917
-
3918
- let ChildJob$1 = class ChildJob extends EventEmitter$1 {
3919
-
3920
- constructor() {
3921
- super();
3922
- this.jobs = {};
3923
- this.config = {};
3924
-
3925
- const cfg = getConfig$1().jobs;
3926
- if (cfg) {
3927
- this.config = cfg;
3928
- }
3929
-
3930
- this._initEvents();
3931
- }
3932
-
3933
- /**
3934
- * 初始化监听
3935
- */
3936
- _initEvents() {
3937
- this.on(Events$1.childProcessExit, (data) => {
3938
- delete this.jobs[data.pid];
3939
- });
3940
- this.on(Events$1.childProcessError, (data) => {
3941
- delete this.jobs[data.pid];
3942
- });
3943
- }
3944
-
3945
- /**
3946
- * 执行一个job文件
3947
- */
3948
- exec(filepath, params = {}, opt = {}) {
3949
- const jobPath = getFullpath$1(filepath);
3950
- const proc = this.createProcess(opt);
3951
- const cmd = 'run';
3952
- proc.dispatch(cmd, jobPath, params);
3953
-
3954
- return proc;
3955
- }
3956
-
3957
- /**
3958
- * 创建子进程
3959
- */
3960
- createProcess(opt = {}) {
3961
- const options = extend(true, {
3962
- processArgs: {
3963
- type: 'childJob'
3964
- }
3965
- }, opt);
3966
- const proc = new JobProcess$1(this, options);
3967
- if (!proc) {
3968
- let errorMessage = `[electron-easymvc] [jobs/child] Failed to obtain the child process !`;
3969
- throw new Error(errorMessage);
3970
- }
3971
- this.jobs[proc.pid] = proc;
3972
-
3973
- return proc;
3974
- }
3975
-
3976
- /**
3977
- * 获取当前pids
3978
- */
3979
- getPids() {
3980
- let pids = Object.keys(this.jobs);
3981
- return pids;
3982
- }
3983
-
3984
- /**
3985
- * 异步执行一个job文件 todo this指向
3986
- */
3987
- async execPromise(filepath, params = {}, opt = {}) {
3988
- return this.exec(filepath, params, opt);
3989
- }
3990
-
3991
- };
3992
-
3993
- var child = {
3994
- ChildJob: ChildJob$1
3995
- };
3996
-
3997
- var consts = {
3998
- polling: 'polling', // 轮询
3999
- weights: 'weights', // 权重
4000
- random: 'random', // 随机
4001
- specify: 'specify', // 声明绑定
4002
- weightsPolling: 'weightsPolling', // 权重轮询
4003
- weightsRandom: 'weightsRandom', // 权重随机
4004
- minimumConnection: 'minimumConnection', // 最小连接数
4005
- weightsMinimumConnection: 'weightsMinimumConnection', // 权重最小连接数
4006
- };
4007
-
4008
- /**
4009
- * 轮询
4010
- */
4011
-
4012
- var polling = function (tasks, currentIndex, context) {
4013
- if (!tasks.length) return null;
4014
-
4015
- const task = tasks[currentIndex];
4016
- context.currentIndex ++;
4017
- context.currentIndex %= tasks.length;
4018
-
4019
- return task || null;
4020
- };
4021
-
4022
- /**
4023
- * 权重
4024
- */
4025
-
4026
- var weights = function (tasks, weightTotal, context) {
4027
-
4028
- if (!tasks.length) return null;
4029
-
4030
- let max = tasks[0].weight, maxIndex = 0, sum;
4031
-
4032
- for (let i = 0; i < tasks.length; i++) {
4033
- sum = (tasks[i].weight || 0) + Math.random() * weightTotal;
4034
- if (sum >= max) {
4035
- max = sum;
4036
- maxIndex = i;
4037
- }
4038
- }
4039
-
4040
- context.weightIndex += 1;
4041
- context.weightIndex %= (weightTotal + 1);
4042
-
4043
- return tasks[maxIndex];
4044
- };
4045
-
4046
- /**
4047
- * 随机
4048
- */
4049
-
4050
- var random = function (tasks) {
4051
-
4052
- const length = tasks.length;
4053
- const target = tasks[Math.floor(Math.random() * length)];
4054
-
4055
- return target || null;
4056
- };
4057
-
4058
- /**
4059
- * 声明绑定
4060
- */
4061
-
4062
- var specify = function (tasks, id) {
4063
- let task;
4064
-
4065
- for (let i = 0; i < tasks.length; i++) {
4066
- if (tasks[i].id === id) {
4067
- task = tasks[i];
4068
- break;
4069
- }
4070
- }
4071
-
4072
- return task || null;
4073
- };
4074
-
4075
- /**
4076
- * 最小连接数
4077
- */
4078
-
4079
- var minimumConnection = function (tasks, conMap={}) {
4080
- if (tasks.length < 2) return tasks[0] || null;
4081
-
4082
- let min = conMap[tasks[0].id];
4083
- let minIndex = 0;
4084
-
4085
- for (let i = 1; i < tasks.length; i++) {
4086
- const con = conMap[tasks[i].id] || 0;
4087
- if (con <= min) {
4088
- min = con;
4089
- minIndex = i;
4090
- }
4091
- }
4092
-
4093
- return tasks[minIndex] || null;
4094
- };
4095
-
4096
- /**
4097
- * 权重轮询
4098
- */
4099
-
4100
- var weightsPolling = function (tasks, weightIndex, weightTotal, context) {
4101
-
4102
- if (!tasks.length) return null;
4103
-
4104
- let weight = 0;
4105
- let task;
4106
-
4107
- for (let i = 0; i < tasks.length; i++) {
4108
- weight += tasks[i].weight || 0;
4109
- if (weight > weightIndex) {
4110
- task = tasks[i];
4111
- break;
4112
- }
4113
- }
4114
-
4115
- context.weightIndex += 1;
4116
- context.weightIndex %= (weightTotal + 1);
4117
-
4118
- return task;
4119
- };
4120
-
4121
- /**
4122
- * 权重随机
4123
- */
4124
-
4125
- var weightsRandom = function (tasks, weightTotal) {
4126
- let task;
4127
- let weight = Math.ceil(Math.random() * weightTotal);
4128
-
4129
- for (let i = 0; i < tasks.length; i++) {
4130
- weight -= tasks[i].weight || 0;
4131
- if (weight <= 0) {
4132
- task = tasks[i];
4133
- break;
4134
- }
4135
- }
4136
-
4137
- return task || null;
4138
- };
4139
-
4140
- /**
4141
- * 权重最小连接数
4142
- */
4143
-
4144
- var weightsMinimumConnection = function (tasks, weightTotal, connectionsMap, context) {
4145
-
4146
- if (!tasks.length) return null;
4147
-
4148
- let min = tasks[0].weight, minIndex = 0, sum;
4149
-
4150
- const connectionsTotal = tasks.reduce((total, cur) => {
4151
- total += (connectionsMap[cur.id] || 0);
4152
- return total;
4153
- }, 0);
4154
-
4155
- // algorithm: (weight + connections'weight) + random factor
4156
- for (let i = 0; i < tasks.length; i++) {
4157
- sum =
4158
- (tasks[i].weight || 0) + (Math.random() * weightTotal) +
4159
- (( (connectionsMap[tasks[i].id] || 0) * weightTotal ) / connectionsTotal);
4160
- if (sum <= min) {
4161
- min = sum;
4162
- minIndex = i;
4163
- }
4164
- }
4165
-
4166
- context.weightIndex += 1;
4167
- context.weightIndex %= (weightTotal + 1);
4168
-
4169
- return tasks[minIndex];
4170
- };
4171
-
4172
- const Consts$2 = consts;
4173
-
4174
- var algorithm$1 = {
4175
- [Consts$2.polling]: polling,
4176
- [Consts$2.weights]: weights,
4177
- [Consts$2.random]: random,
4178
- [Consts$2.specify]: specify,
4179
- [Consts$2.minimumConnection]: minimumConnection,
4180
- [Consts$2.weightsPolling]: weightsPolling,
4181
- [Consts$2.weightsRandom]: weightsRandom,
4182
- [Consts$2.weightsMinimumConnection]: weightsMinimumConnection,
4183
- };
4184
-
4185
- const Consts$1 = consts;
4186
- const algorithm = algorithm$1;
4187
-
4188
- /**
4189
- * 算法调度器
4190
- */
4191
- let Scheduler$1 = class Scheduler {
4192
- constructor(algorithm) {
4193
- this.algorithm = algorithm || Consts$1.polling;
4194
- }
4195
-
4196
- /**
4197
- * 计算
4198
- */
4199
- calculate(tasks, params) {
4200
- const results = algorithm[this.algorithm](tasks, ...params);
4201
- return results;
4202
- }
4203
-
4204
- /**
4205
- * 设置算法
4206
- */
4207
- setAlgorithm = (algorithm) => {
4208
- if (algorithm in Consts$1) {
4209
- this.algorithm = algorithm;
4210
- } else {
4211
- throw new Error(`Invalid algorithm: ${algorithm}, pick from ${Object.keys(Consts$1).join('|')}`);
4212
- }
4213
- }
4214
- };
4215
-
4216
- var scheduler = Scheduler$1;
4217
-
4218
- const Consts = consts;
4219
- const Scheduler = scheduler;
4220
-
4221
- /**
4222
- * 负载均衡器
4223
- * @intro 参考electron-re项目,并做了一些改动
4224
- * @since 1.0.0
4225
- */
4226
- let LoadBalancer$1 = class LoadBalancer {
4227
-
4228
- static Algorithm = Consts;
4229
-
4230
- /**
4231
- * @param {Object} options
4232
- * @param {Array } options.targets [ targets for load balancing calculation: [{id: 1, weight: 1}, {id: 2, weight: 2}] ]
4233
- * @param {String} options.algorithm
4234
- */
4235
- constructor(options) {
4236
- this.targets = options.targets;
4237
- this.algorithm = options.algorithm || Consts.polling;
4238
- this.params = { // data for algorithm
4239
- currentIndex: 0, // index
4240
- weightIndex: 0, // index for weight alogrithm
4241
- weightTotal: 0, // total weight
4242
- connectionsMap: {}, // connections of each target
4243
- cpuOccupancyMap: {}, // cpu occupancy of each target
4244
- memoryOccupancyMap: {}, // cpu occupancy of each target
4245
- };
4246
- this.scheduler = new Scheduler(this.algorithm);
4247
- this.memoParams = this.memorizedParams();
4248
- this.calculateWeightIndex();
4249
- }
4250
-
4251
- /**
4252
- * 算法参数
4253
- */
4254
- memorizedParams() {
4255
- return {
4256
- [Consts.random]: () => [],
4257
- [Consts.polling]: () => [this.params.currentIndex, this.params],
4258
- [Consts.weights]: () => [this.params.weightTotal, this.params],
4259
- [Consts.specify]: (id) => [id],
4260
- [Consts.weightsRandom]: () => [this.params.weightTotal],
4261
- [Consts.weightsPolling]: () => [this.params.weightIndex, this.params.weightTotal, this.params],
4262
- [Consts.minimumConnection]: () => [this.params.connectionsMap],
4263
- [Consts.weightsMinimumConnection]: () => [this.params.weightTotal, this.params.connectionsMap, this.params],
4264
- };
4265
- }
4266
-
4267
- /**
4268
- * 刷新参数
4269
- */
4270
- refreshParams(pidMap) {
4271
- const infos = Object.values(pidMap);
4272
- for (let info of infos) {
4273
- // this.params.connectionsMap[id] = connections;
4274
- this.params.cpuOccupancyMap[info.pid] = info.cpu;
4275
- this.params.memoryOccupancyMap[info.pid] = info.memory;
4276
- }
4277
- }
4278
-
4279
- /**
4280
- * 选举出一个进程
4281
- */
4282
- pickOne(...params) {
4283
- return this.scheduler.calculate(
4284
- this.targets, this.memoParams[this.algorithm](...params)
4285
- );
4286
- }
4287
-
4288
- /**
4289
- * 选举出多个进程
4290
- */
4291
- pickMulti(count = 1, ...params) {
4292
- return new Array(count).fill().map(
4293
- () => this.pickOne(...params)
4294
- );
4295
- }
4296
-
4297
- /**
4298
- * 计算权重
4299
- */
4300
- calculateWeightIndex() {
4301
- this.params.weightTotal = this.targets.reduce((total, cur) => total + (cur.weight || 0), 0);
4302
- if (this.params.weightIndex > this.params.weightTotal) {
4303
- this.params.weightIndex = this.params.weightTotal;
4304
- }
4305
- }
4306
-
4307
- /**
4308
- * 计算索引
4309
- */
4310
- calculateIndex() {
4311
- if (this.params.currentIndex >= this.targets.length) {
4312
- this.params.currentIndex = (this.params.currentIndex - 1 >= 0) ? (this.params.currentIndex - 1) : 0;
4313
- }
4314
- }
4315
-
4316
- /**
4317
- * 清除data
4318
- */
4319
- clean(id) {
4320
- if (id) {
4321
- delete this.params.connectionsMap[id];
4322
- delete this.params.cpuOccupancyMap[id];
4323
- delete this.params.memoryOccupancyMap[id];
4324
- } else {
4325
- this.params = {
4326
- currentIndex: 0,
4327
- connectionsMap: {},
4328
- cpuOccupancyMap: {},
4329
- memoryOccupancyMap: {},
4330
- };
4331
- }
4332
- }
4333
-
4334
- /**
4335
- * 添加一个进程信息
4336
- */
4337
- add(task) {
4338
- if (this.targets.find(target => target.id === task.id)) {
4339
- return console.warn(`Add Operation: the task ${task.id} already exists.`);
4340
- }
4341
- this.targets.push(task);
4342
- this.calculateWeightIndex();
4343
- }
4344
-
4345
- /**
4346
- * 删除一个进程信息
4347
- */
4348
- del(target) {
4349
- let found = false;
4350
- for (let i = 0; i < this.targets.length; i++) {
4351
- if (this.targets[i].id === target.id) {
4352
- this.targets.splice(i, 1);
4353
- this.clean(target.id);
4354
- this.calculateIndex();
4355
- found = true;
4356
- break;
4357
- }
4358
- }
4359
-
4360
- if (found) {
4361
- this.calculateWeightIndex();
4362
- } else {
4363
- console.warn(`Del Operation: the task ${target.id} is not found.`, this.targets);
4364
- }
4365
- }
4366
-
4367
- /**
4368
- * 擦除
4369
- */
4370
- wipe() {
4371
- this.targets = [];
4372
- this.calculateWeightIndex();
4373
- this.clean();
4374
- }
4375
-
4376
- /**
4377
- * 更新计算参数
4378
- */
4379
- updateParams(object) {
4380
- Object.entries(object).map(([key, value]) => {
4381
- if (key in this.params) {
4382
- this.params[key] = value;
4383
- }
4384
- });
4385
- }
4386
-
4387
- /**
4388
- * 设置targets
4389
- */
4390
- setTargets(targets) {
4391
- const targetsMap = targets.reduce((total, cur) => {
4392
- total[cur.id] = 1;
4393
- return total;
4394
- }, {});
4395
- this.targets.forEach(target => {
4396
- if (!(target.id in targetsMap)) {
4397
- this.clean(target.id);
4398
- this.calculateIndex();
4399
- }
4400
- });
4401
- this.targets = targets;
4402
- this.calculateWeightIndex();
4403
- }
4404
-
4405
- /**
4406
- * 设置算法
4407
- */
4408
- setAlgorithm = (algorithm) => {
4409
- if (algorithm in Consts) {
4410
- this.algorithm = algorithm;
4411
- this.params.weightIndex = 0;
4412
- this.scheduler.setAlgorithm(this.algorithm);
4413
- } else {
4414
- throw new Error(`Invalid algorithm: ${algorithm}, pick from ${Object.keys(Consts).join('|')}`);
4415
- }
4416
- }
4417
- };
4418
-
4419
- var loadBalancer = LoadBalancer$1;
4420
-
4421
- const EventEmitter = require$$0__default$3.default;
4422
- const LoadBalancer = loadBalancer;
4423
- const { getFullpath } = loader;
4424
- const { JobProcess } = jobProcess;
4425
- const { Events } = channel;
4426
- const { validValue } = helper;
4427
- const { getConfig } = config;
4428
-
4429
- let ChildPoolJob$1 = class ChildPoolJob extends EventEmitter {
4430
-
4431
- constructor(opt = {}) {
4432
- super();
4433
- let options = Object.assign({
4434
- weights: [],
4435
- }, opt);
4436
-
4437
- this.config = {};
4438
- this.boundMap = new Map();
4439
- this.children = {};
4440
- this.min = 3;
4441
- this.max = 6;
4442
- this.strategy = 'polling';
4443
- this.weights = new Array(this.max).fill().map((v, i) => {
4444
- let w = validValue(options.weights[i]) ? options.weights[i] : 1;
4445
- return w;
4446
- });
4447
-
4448
- let lbOpt = {
4449
- algorithm: LoadBalancer.Algorithm.polling,
4450
- targets: [],
4451
- };
4452
- this.LB = new LoadBalancer(lbOpt);
4453
-
4454
- const cfg = getConfig().jobs;
4455
- if (cfg) {
4456
- this.config = cfg;
4457
- }
4458
-
4459
- this._initEvents();
4460
- }
4461
-
4462
- _initEvents() {
4463
- this.on(Events.childProcessExit, (data) => {
4464
- this._removeChild(data.pid);
4465
- });
4466
- this.on(Events.childProcessError, (data) => {
4467
- this._removeChild(data.pid);
4468
- });
4469
- }
4470
-
4471
- _removeChild(pid) {
4472
- const length = Object.keys(this.children).length;
4473
- const lbOpt = {
4474
- id: pid,
4475
- weight: this.weights[length - 1],
4476
- };
4477
- this.LB.del(lbOpt);
4478
- delete this.children[pid];
4479
- }
4480
-
4481
- async create(number = 3) {
4482
- if (number < 0 || number > this.max) {
4483
- throw new Error(`[electron-easymvc] [jobs/child-pool] The number is invalid !`);
4484
- }
4485
- let currentNumber = this.children.length;
4486
- if (currentNumber > this.max) {
4487
- throw new Error(`[electron-easymvc] [jobs/child-pool] The number of current processes number: ${currentNumber} is greater than the maximum: ${this.max} !`);
4488
- }
4489
-
4490
- if (number + currentNumber > this.max) {
4491
- number = this.max - currentNumber;
4492
- }
4493
-
4494
- // args
4495
- let options = Object.assign({
4496
- processArgs: {
4497
- type: 'childPoolJob'
4498
- }
4499
- }, {});
4500
- for (let i = 1; i <= number; i++) {
4501
- let task = new JobProcess(this, options);
4502
- this._childCreated(task);
4503
- }
4504
-
4505
- let pids = Object.keys(this.children);
4506
-
4507
- return pids;
4508
- }
4509
-
4510
- // Post creation processing of child processes
4511
- _childCreated(childProcess) {
4512
- let pid = childProcess.pid;
4513
- this.children[pid] = childProcess;
4514
-
4515
- const length = Object.keys(this.children).length;
4516
- let lbTask = {
4517
- id: pid,
4518
- weight: this.weights[length - 1],
4519
- };
4520
- this.LB.add(lbTask);
4521
- }
4522
-
4523
- // Execute a job file
4524
- run(filepath, params = {}) {
4525
- const jobPath = getFullpath(filepath);
4526
- const childProcess = this.getChild();
4527
- childProcess.dispatch('run', jobPath, params);
4528
-
4529
- return childProcess;
4530
- }
4531
-
4532
- // Asynchronous execution of a job file
4533
- async runPromise(filepath, params = {}) {
4534
- return this.run(filepath, params);
4535
- }
4536
-
4537
- // Get the bound process object
4538
- getBoundChild(boundId) {
4539
- let proc;
4540
- const boundPid = this.boundMap.get(boundId);
4541
- if (boundPid) {
4542
- proc = this.children[boundPid];
4543
- return proc;
4544
- }
4545
-
4546
- // 获取进程并绑定
4547
- proc = this.getChild();
4548
- this.boundMap.set(boundId, proc.pid);
4549
-
4550
- return proc;
4551
- }
4552
-
4553
- // Retrieve a sub process object through PID
4554
- getChildByPid(pid) {
4555
- let proc = this.children[pid] || null;
4556
- return proc;
4557
- }
4558
-
4559
- // Get a sub process object
4560
- getChild() {
4561
- let proc;
4562
- const currentPids = Object.keys(this.children);
4563
-
4564
- // 没有则创建
4565
- if (currentPids.length == 0) {
4566
- let subIds = this.create(1);
4567
- proc = this.children[subIds[0]];
4568
- } else {
4569
- // 从池子中获取一个
4570
- let onePid = this.LB.pickOne().id;
4571
- proc = this.children[onePid];
4572
- }
4573
-
4574
- if (!proc) {
4575
- let errorMessage = `[electron-easymvc] [jobs/child-pool] Failed to obtain the child process !`;
4576
- throw new Error(errorMessage);
4577
- }
4578
-
4579
- return proc;
4580
- }
4581
-
4582
- // Get current pigs
4583
- getPids() {
4584
- let pids = Object.keys(this.children);
4585
- return pids;
4586
- }
4587
-
4588
- // kill all
4589
- // type: sequence | parallel
4590
- killAll(type = 'parallel') {
4591
- let i = 1;
4592
- Object.keys(this.children).forEach(key => {
4593
- let proc = this.children[key];
4594
- if (proc) {
4595
- if (type == 'sequence') {
4596
- setTimeout(()=>{
4597
- proc.kill();
4598
- }, i * 1000);
4599
- i++;
4600
- } else {
4601
- proc.kill();
4602
- }
4603
- }
4604
- });
4605
- }
4606
- };
4607
-
4608
- var childPool = {
4609
- ChildPoolJob: ChildPoolJob$1
4610
- };
4611
-
4612
- const { ChildJob } = child;
4613
- const { ChildPoolJob } = childPool;
4614
-
4615
- var jobs = {
4616
- ChildJob,
4617
- ChildPoolJob
4618
- };
4619
-
4620
- var version = "1.0.5";
4621
- var require$$17 = {
4622
- version: version};
4623
-
4624
- /**
4625
- * Electron EasyMVC 统一导出入口
4626
- * 此文件将被 Rollup 打包为单个 bundle
4627
- *
4628
- * 注意:必须使用显式 require,不能使用动态 require
4629
- * 原因:Rollup 配置了 ignoreDynamicRequires: true,动态 require 不会被打包
4630
- */
4631
-
4632
- // 确保 bytenode 优先加载(用于代码加密功能)
4633
-
4634
-
4635
- // 从 npm 包导入核心类
4636
- const { ElectronEgg } = eeCore;
4637
-
4638
- // 导出所有模块
4639
- // 注意:这些 require 必须是静态的,以便 Rollup 正确打包
4640
- var exports$1 = {
4641
- // 核心类
4642
- ElectronEgg,
4643
-
4644
- // 子模块(必须显式列出,不能使用动态 require)
4645
- log: log,
4646
- config: config,
4647
- controller: controller,
4648
- loader: loader,
4649
- ps: ps,
4650
- utils: utils,
4651
- socket: socket,
4652
- storage: storage,
4653
- jobs: jobs,
4654
- cross: cross_1,
4655
- electron: electron,
4656
- exception: exception,
4657
- message: message,
4658
- html: html,
4659
-
4660
- // 常量(特殊路径)
4661
- const: channel,
4662
-
4663
- // 内部元信息
4664
- __internal: {
4665
- version: require$$17.version,
4666
- bundled: true,
4667
- getBundlePath: () => __dirname,
4668
- }
4669
- };
4670
-
4671
- var _exports = /*@__PURE__*/getDefaultExportFromCjs(exports$1);
4672
-
4673
- module.exports = _exports;
1
+ "use strict";require("bytenode");var e=require("debug"),t=require("path"),r=require("dayjs"),o=require("egg-logger"),n=require("is-type-of"),i=require("fs"),s=require("module"),c=require("assert"),a=require("electron"),l=require("os"),u=require("child_process"),h=require("crypto"),d=require("mkdirp"),p=require("events");require("koa-convert"),require("chalk");var f=require("cross-spawn"),g=require("tree-kill"),m=require("net"),v=require("axios"),y=require("globby"),w=require("socket.io"),E=require("socket.io-client"),b=require("koa"),x=require("koa2-cors"),S=require("koa-body"),P=require("https"),k=require("lodash"),_=require("better-sqlite3"),j=require("serialize-javascript");function O(e){return e&&e.__esModule?e:{default:e}}var C=O(e),A=O(t),D=O(r),L=O(o),I=O(n),M=O(i),N=O(s),T=O(c),R=O(a),F=O(l),$=O(u),q=O(h),B=O(d),H=O(p),J=O(f),U=O(g),W=O(m),V=O(v),z=O(y),Q=O(w),Y=O(E),G=O(b),K=O(x),X=O(S),Z=O(P),ee=O(k),te=O(_),re=O(j);function oe(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}const ne=Object.prototype.hasOwnProperty,ie=Object.prototype.toString;function se(e){if(!e||"[object Object]"!==ie.call(e))return!1;var t,r=ne.call(e,"constructor"),o=e.constructor&&e.constructor.prototype&&ne.call(e.constructor.prototype,"isPrototypeOf");if(e.constructor&&!r&&!o)return!1;for(t in e);return void 0===t||ne.call(e,t)}var ce={extend:function e(){var t,r,o,n,i,s=arguments[0],c=1,a=arguments.length,l=!1;for("boolean"==typeof s?(l=s,s=arguments[1]||{},c=2):("object"!=typeof s&&"function"!=typeof s||null==s)&&(s={});c<a;++c)if(null!=(t=arguments[c]))for(r in t)"__proto__"!==r&&(o=s[r],s!==(n=t[r])&&(l&&n&&se(n)?(i=o&&se(o)?o:{},s[r]=e(l,i,n)):void 0!==n&&(s[r]=n)));return s}};function ae(){return"darwin"===process.platform}var le={renderer:function(){return"renderer"===process.type},main:function(){return"browser"===process.type},osx:ae,macOS:function(){return ae()},windows:function(){return"win32"===process.platform},linux:function(){return"linux"===process.platform},x86:function(){return"ia32"===process.arch},x64:function(){return"x64"===process.arch},sandbox:function(){return"APP_SANDBOX_CONTAINER_ID"in process.env},mas:function(){return!0===process.mas},windowsStore:function(){return!0===process.windowsStore},all:function(){const e=new Array(arguments.length);for(var t=0;t<e.length;t++)e[t]=arguments[t];if(e.length){for(t=0;t<e.length;t++)if(!e[t]())return!1;return!0}},none:function(){const e=new Array(arguments.length);for(var t=0;t<e.length;t++)e[t]=arguments[t];if(e.length){for(t=0;t<e.length;t++)if(e[t]())return!1;return!0}},one:function(){const e=new Array(arguments.length);for(var t=0;t<e.length;t++)e[t]=arguments[t];if(e.length){for(t=0;t<e.length;t++)if(e[t]())return!0;return!1}}};const ue=A.default,he=le;function de(){return"dev"===process.env.EE_ENV||"local"===process.env.EE_ENV}function pe(){return"undefined"==typeof process||!process||"renderer"===process.type}function fe(){return"undefined"!=typeof process&&"browser"===process.type}function ge(){return 1===Number(process.env.ELECTRON_RUN_AS_NODE)}function me(){return process.env.EE_APP_NAME}function ve(){return process.env.EE_BASE_DIR}function ye(){return process.env.EE_APP_USER_DATA}function we(){return process.env.EE_EXEC_DIR}function Ee(){return process.env.EE_USER_HOME}function be(){const e="."+me();return ue.join(Ee(),e)}function xe(){return"true"===process.env.EE_IS_PACKAGED}var Se={allEnv:function(){return process.env},env:function(){return process.env.EE_ENV},isProd:function(){return"prod"===process.env.EE_ENV},isDev:de,isRenderer:pe,isMain:fe,isForkedChild:ge,processType:function(){let e="";return fe()?e="browser":pe()?e="renderer":ge()&&(e="child"),e},appName:me,appVersion:function(){return process.env.EE_APP_VERSION},getDataDir:function(){const e=de()?ve():be();return ue.join(e,"data")},getLogDir:function(){const e=de()?ve():be();return ue.join(e,"logs")},getBundleDir:function(e){const t=e||process.cwd();return ue.join(t,"public","electron")},getElectronCodeDir:function(e){const t=e||process.cwd();return ue.join(t,"electron")},getFrontendCodeDir:function(e){const t=e||process.cwd();return ue.join(t,"frontend")},getRootDir:function(){return de()?ve():ye()},getBaseDir:ve,getElectronDir:function(){return process.env.EE_ELECTRON_DIR},getPublicDir:function(){return ue.join(ve(),"public")},getExtraResourcesDir:function(){const e=we();let t="";return xe()?(t=ue.join(e,"resources","extraResources"),he.macOS()&&(t=ue.join(e,"..","Resources","extraResources"))):t=ue.join(e,"build","extraResources"),t},getAppUserDataDir:ye,getExecDir:we,getUserHomeDir:Ee,getUserHomeAppDir:function(){const e=me();return ue.join(Ee(),e)},getUserHomeHiddenAppDir:be,getSocketPort:function(){return parseInt(process.env.EE_SOCKET_PORT)||0},getHttpPort:function(){return parseInt(process.env.EE_HTTP_PORT)||0},isPackaged:xe,exit:function(e=0){return process.exit(e)},makeMessage:function(e={}){return Object.assign({channel:"",event:"",data:{}},e)},exitChildJob:function(e=0){try{"childJob"==JSON.parse(process.argv[2]).type&&process.exit(e)}catch(t){process.exit(e)}},isChildJob:function(){try{if("childJob"==JSON.parse(process.argv[2]).type)return!0}catch(e){return!1}},isChildPoolJob:function(){try{if("childPoolJob"==JSON.parse(process.argv[2]).type)return!0}catch(e){return!1}},getArgumentByName:function(e,t){t||(t=process.argv);for(let r=0;r<t.length;r++){const o=t[r],n=`--${e}=`;if(-1!==o.indexOf(n))return o.substring(n.length)}}},Pe={exports:{}};!function(e){const t=I.default,r=A.default,o=M.default,n=N.default,i=e.constructor.length>1?e.constructor:n,s=i._extensions;e.exports={extensions:s,loadFile:function(e){try{const t=r.extname(e);if(t&&!i._extensions[t])return o.readFileSync(e);const n=require(e);return n&&(n.__esModule&&"default"in n)?n.default:n}catch(t){throw t.message=`[electron-easymvc] load file: ${e}, error: ${t.message}`,t}},callFn:async function(e,r,o){if(r=r||[],t.function(e))return o?e.call(o,...r):e(...r)},getResolvedFilename:function(e,t){return e.replace(t+r.sep,"").replace(/[/\\]/g,"/")},isBytecodeClass:function(e){let t=!1;return-1!=e.toString().indexOf("[class")&&(t=!0),t},filePatterns:function(){return["**/*.js","**/*.jsc"]}}}(Pe);var ke=Pe.exports;const _e=I.default,je=M.default,Oe=A.default,Ce=ke,{getElectronDir:Ae}=Se;function De(e){let t;try{t=require.resolve(e)}catch(r){if(e&&(e.endsWith(".defalut")||e.endsWith(".prod"))?t=e+".jsc":e&&e.endsWith(".js")&&(t=e+"c"),!je.existsSync(e)&&!je.existsSync(t)){return}}return t}var Le={loadFile:function(e,...t){let r=e;if(Oe.isAbsolute(r)||(r=Oe.join(Ae(),r)),r=r&&De(r),!je.existsSync(r)){throw new Error(`[electron-easymvc] [loader/index] loadFile ${e} does not exist`)}let o=Ce.loadFile(r);return!_e.function(o)||_e.class(o)||Ce.isBytecodeClass(o)||(o=o(...t)),o},execFile:function(e,...t){let r=Ce.loadFile(e);return _e.class(r)||Ce.isBytecodeClass(r)?r=new r(t):_e.function(r)&&(r=r(t)),r},requireFile:function(e){return Ce.loadFile(e)},resolveModule:De,getFullpath:function(e){let t;if(Oe.isAbsolute(e)||(e=Oe.join(Ae(),e)),t=De(e),!je.existsSync(t))throw new Error(`[electron-easymvc] [loader] getFullpath filepath ${e} not exists`);return t}};const Ie=T.default,Me=Symbol("Timing#map"),Ne=Symbol("Timing#list");var Te={Timing:class{constructor(){this._enable=!0,this[Me]=new Map,this[Ne]=[],this.init()}init(){this.start("Process Start",Date.now()-Math.floor(1e3*process.uptime())),this.end("Process Start"),"number"==typeof process.scriptStartTime&&(this.start("Script Start",process.scriptStartTime),this.end("Script Start"))}start(e,t){if(!e||!this._enable)return;this[Me].has(e)&&this.end(e);const r={name:e,start:t=t||Date.now(),end:void 0,duration:void 0,pid:process.pid,index:this[Ne].length};return this[Me].set(e,r),this[Ne].push(r),r}end(e){if(!e||!this._enable)return;Ie(this[Me].has(e),`should run timing.start('${e}') first`);const t=this[Me].get(e);return t.end=Date.now(),t.duration=t.end-t.start,t}enable(){this._enable=!0}disable(){this._enable=!1}clear(){this[Me].clear(),this[Ne]=[]}toJSON(){return this[Ne]}}};var Re={Processes:{showException:"ee#showException",sendToMain:"ee#sendToMain"},SocketIO:{partySoftware:"socket-channel"},Events:{childProcessExit:"ee#childProcess#exit",childProcessError:"ee#childProcess#error"},Receiver:{childJob:"job",forkProcess:"task",all:"all"}};const Fe=A.default,{env:$e,getBaseDir:qe,getLogDir:Be}=Se,{SocketIO:He}=Re;const Je=C.default("electron-easymvc:config:config_loader"),Ue=A.default,{appName:We,env:Ve,getElectronDir:ze,getBaseDir:Qe,getRootDir:Ye}=Se,{extend:Ge}=ce,{loadFile:Ke}=Le,{Timing:Xe}=Te,Ze=()=>({openDevTools:!1,singleLock:!0,windowsOption:{title:"electron-egg",width:980,height:650,minWidth:400,minHeight:300,webPreferences:{contextIsolation:!1,nodeIntegration:!0},frame:!0,show:!1,icon:Fe.join(qe(),"public","images","logo-32.png")},logger:{type:"application",dir:Be(),encoding:"utf8",env:$e(),level:"INFO",consoleLevel:"INFO",disableConsoleAfterReady:"local"!==$e(),outputJSON:!1,buffer:!0,appLogName:"ee.log",coreLogName:"electron-easymvc.log",agentLogName:"ee-agent.log",errorLogName:"ee-error.log",coreLogger:{},allowDebugAtProd:!1,enablePerformanceTimer:!1,rotator:"day"},socketServer:{enable:!1,port:7070,path:"/socket.io/",connectTimeout:45e3,pingTimeout:3e4,pingInterval:25e3,maxHttpBufferSize:1e8,transports:["polling","websocket"],cors:{origin:!0},channel:He.partySoftware},httpServer:{enable:!1,https:{enable:!1,key:"/public/ssl/localhost+1.key",cert:"/public/ssl/localhost+1.pem"},protocol:"http://",host:"127.0.0.1",port:7071,cors:{origin:"*"},body:{multipart:!0,formidable:{keepExtensions:!0}},filterRequest:{uris:["favicon.ico"],returnData:""}},remote:{enable:!1,url:""},mainServer:{protocol:"file://",indexPath:"/public/dist/index.html",options:{},takeover:"",loadingPage:"",channelSeparator:"/"},exception:{mainExit:!1,childExit:!1,rendererExit:!0},jobs:{messageLog:!1},cross:{}});var et={ConfigLoader:class{constructor(){this.timing=new Xe}load(){this.timing.start("Load Config");const e=this._AppConfig(),t=Ze(),r=Ge(!0,t,e);return Je("[load] config: %o",r),this.timing.end("Load Config"),r}_AppConfig(){const e=["config.default",`config.${Ve()}`],t={};for(const r of e){const e=this._loadConfig(ze(),r);Ge(!0,t,e)}return t}_loadConfig(e,t){const r={name:We(),baseDir:Qe(),electronDir:ze(),env:Ve(),root:Ye()},o=Ue.join(e,"config",t),n=Ke(o,r);return Je("[_loadConfig] filepath: %s",o),n||null}}};const{ConfigLoader:tt}=et,rt={config:null};function ot(){const e=new tt;return rt.config=e.load(),rt.config}var nt={loadConfig:ot,getConfig:function(){return rt.config||ot(),rt.config}};const it=C.default("electron-easymvc:log:logger"),st=L.default.EggLoggers,ct=D.default,at=A.default,{extend:lt}=ce,{getConfig:ut}=nt,{getLogDir:ht,env:dt,isDev:pt}=Se;let ft=0;const gt={appLogName:"",coreLogName:"",errorLogName:""};var mt={create:function(e={}){let t={};if(0==Object.keys(e).length){const e={logger:{type:"application",dir:ht(),env:dt(),consoleLevel:"INFO",disableConsoleAfterReady:!pt(),coreLogger:{},allowDebugAtProd:!1,agentLogName:"ee-agent.log",rotator:"day"},customLogger:{}},r=ut();t=lt(!0,e,{logger:r.logger,customLogger:r.customLogger||{}})}else t.logger=e.logger,t.customLogger=e.customLogger;if(0==Object.keys(t).length)throw new Error("logger config is null");return"day"==t.logger.rotator&&(t=function(e){const t=parseInt(ct().format("YYYYMMDD"));if(ft!=t){ft=t,0==gt.appLogName.length&&(gt.appLogName=e.logger.appLogName),0==gt.coreLogName.length&&(gt.coreLogName=e.logger.coreLogName),0==gt.errorLogName.length&&(gt.errorLogName=e.logger.errorLogName);const{appLogName:r,coreLogName:o,errorLogName:n}=gt,i=at.extname(r),s=at.extname(o),c=at.extname(n);e.logger.appLogName=at.basename(r,i)+"-"+t+i,e.logger.coreLogName=at.basename(o,s)+"-"+t+s,e.logger.errorLogName=at.basename(n,c)+"-"+t+c}return e}(t)),it("[create] opt:%j",t),new st(t)}};const vt=D.default,{create:yt}=mt,wt={eelog:null,logger:{},coreLogger:{}};let Et=0;const bt=["error","warn","info","debug"];function xt(e){Pt();return yt(e)}function St(){return wt.eelog=xt(),wt.eelog}function Pt(){const e=parseInt(vt().format("YYYYMMDD"));Et!=e&&(Et=e,wt.eelog=null)}function kt(){return Pt(),wt.eelog||St(),wt.eelog.logger}function _t(){return Pt(),wt.eelog||St(),wt.eelog.coreLogger}!function(){for(const e of bt)Object.defineProperty(wt.logger,e,{get(){let t=kt();return t[e].bind(t)}})}(),function(){for(const e of bt)Object.defineProperty(wt.coreLogger,e,{get(){let t=_t();return t[e].bind(t)}})}();var jt={createLog:xt,loadLog:St,logger:wt.logger,coreLogger:wt.coreLogger};const{Receiver:Ot,Processes:Ct}=Re;var At={ChildMessage:class{sendToMain(e,t={}){const r=Ot.childJob;return this.send(e,t,r)}send(e,t={},r){const o=r||Ot.forkProcess,n={channel:Ct.sendToMain,eventReceiver:o,event:e,data:t};return process.send(n)}exit(e=0){return process.exit(e)}sendErrorToTerminal(e){let t=e&&"object"==typeof e?e.toString():"";t+=" Error !!! Please See file electron-easymvc.log or easymvc-error-xxx.log for details !";const r={channel:Ct.showException,data:t};process.send(r)}}};const{ChildMessage:Dt}=At,Lt=new Dt;var It={ChildMessage:Dt,childMessage:Lt};const{coreLogger:Mt}=jt,{isForkedChild:Nt,isRenderer:Tt,isDev:Rt,isMain:Ft}=Se,{getConfig:$t}=nt,{childMessage:qt}=It;function Bt(){process.on("uncaughtException",function(e){e instanceof Error||(e=new Error(String(e))),"Error"===e.name&&(e.name="unhandledExceptionError"),Mt.error(e),Jt(e),Ut()})}function Ht(){process.on("unhandledRejection",function(e){if(!(e instanceof Error)){const t=new Error(String(e));e&&(e.name&&(t.name=e.name),e.message&&(t.message=e.message),e.stack&&(t.stack=e.stack)),e=t}"Error"===e.name&&(e.name="unhandledRejectionError"),Mt.error(e),Jt(e),Ut()})}function Jt(e){Nt()&&Rt()&&qt.sendErrorToTerminal(e)}function Ut(){const{mainExit:e,childExit:t,rendererExit:r}=$t().exception;(Ft()&&1==e||Nt()&&1==t||Tt()&&1==r)&&Wt()}function Wt(){setTimeout(()=>{process.exit()},1500)}var Vt={loadException:function(){Bt(),Ht()},uncaughtExceptionHandler:Bt,unhandledRejectionHandler:Ht,uncaughtExceptionMonitorHandler:function(){process.on("uncaughtExceptionMonitor",function(e,t){e instanceof Error||(e=new Error(String(e))),Mt.error("uncaughtExceptionMonitor:",e)})}};const zt=M.default;var Qt={readSync:function(e){if(!zt.existsSync(e))throw new Error(e+" is not found");return JSON.parse(zt.readFileSync(e))}};const Yt=F.default,Gt=A.default,Kt=M.default,{exec:Xt,execSync:Zt}=$.default,{createHash:er}=q.default,{getBaseDir:tr}=Se,{readSync:rr}=Qt,or=le,{platform:nr}=process,ir={darwin:"ioreg -rd1 -c IOPlatformExpertDevice",win32:`${{native:"%windir%\\System32",mixed:"%windir%\\sysnative\\cmd.exe /c %windir%\\System32"}[function(){if("win32"!==process.platform)return"";if("ia32"===process.arch&&process.env.hasOwnProperty("PROCESSOR_ARCHITEW6432"))return"mixed";return"native"}()]}\\REG.exe QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography /v MachineGuid`,linux:"( cat /var/lib/dbus/machine-id /etc/machine-id 2> /dev/null || hostname ) | head -n 1 || :",freebsd:"kenv -q smbios.system.uuid || sysctl -n kern.hostuuid"};function sr(e){return er("sha256").update(e).digest("hex")}function cr(e){switch(nr){case"darwin":return e.split("IOPlatformUUID")[1].split("\n")[0].replace(/\=|\s+|\"/gi,"").toLowerCase();case"win32":return e.toString().split("REG_SZ")[1].replace(/\r+|\n+|\s+/gi,"").toLowerCase();case"linux":case"freebsd":return e.toString().replace(/\r+|\n+|\s+/gi,"").toLowerCase();default:throw new Error(`Unsupported platform: ${process.platform}`)}}var ar={getPackage:function(){return rr(Gt.join(tr(),"package.json"))},getMAC:function(e){const t=/(?:[0]{1,2}[:-]){5}[0]{1,2}/,r=Yt.networkInterfaces();if(e){const o=r[e];if(!o)throw new Error(`interface ${e} was not found`);for(const e of o)if(!1===t.test(e.mac))return e.mac;throw new Error(`interface ${e} had no valid mac addresses`)}for(const[e,o]of Object.entries(r))if(o)for(const e of o)if(!1===t.test(e.mac))return e.mac;throw new Error("failed to get the MAC address")},isMAC:function(e){return/(?:[a-z0-9]{1,2}[:-]){5}[a-z0-9]{1,2}/i.test(e)},isFileProtocol:function(e){return"file://"==e},isWebProtocol:function(e){return["http://","https://"].includes(e)},isJsProject:function(e){const t=Gt.join(e,"electron/main.js"),r=Gt.join(e,"electron/index.js");return!(!Kt.existsSync(t)&&!Kt.existsSync(r))},machineIdSync:function(e){let t=cr(Zt(ir[nr]).toString());return e?t:sr(t)},machineId:function(e){return new Promise((t,r)=>Xt(ir[nr],{},(o,n,i)=>{if(o)return r(new Error(`Error while obtaining machine id: ${o.stack}`));let s=cr(n.toString());return t(e?s:sr(s))}))},getPlatform:function(e="_",t=!1){let r="";if(or.windows()){if(r="windows",t){r+=e+(or.x64()?"64":"32")}}else if(or.macOS()){let t=!1;const o=Yt.cpus();for(let e of o)if(e.model.includes("Apple")){t=!0;break}r="macos"+e+(t?"apple":"intel")}else or.linux()&&(r="linux");return r},is:or};function lr(e){return"number"==typeof e||(!!/^0x[0-9a-f]+$/i.test(e)||/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(e))}function ur(e,t){return"constructor"===t&&"function"==typeof e[t]||"__proto__"===t}var hr={parseArgv:function(e,t){t||(t={});var r={bools:{},strings:{},unknownFn:null};"function"==typeof t.unknown&&(r.unknownFn=t.unknown),"boolean"==typeof t.boolean&&t.boolean?r.allBools=!0:[].concat(t.boolean).filter(Boolean).forEach(function(e){r.bools[e]=!0});var o={};function n(e){return o[e].some(function(e){return r.bools[e]})}Object.keys(t.alias||{}).forEach(function(e){o[e]=[].concat(t.alias[e]),o[e].forEach(function(t){o[t]=[e].concat(o[e].filter(function(e){return t!==e}))})}),[].concat(t.string).filter(Boolean).forEach(function(e){r.strings[e]=!0,o[e]&&[].concat(o[e]).forEach(function(e){r.strings[e]=!0})});var i=t.default||{},s={_:[]};function c(e,t,o){for(var n=e,i=0;i<t.length-1;i++){var s=t[i];if(ur(n,s))return;void 0===n[s]&&(n[s]={}),n[s]!==Object.prototype&&n[s]!==Number.prototype&&n[s]!==String.prototype||(n[s]={}),n[s]===Array.prototype&&(n[s]=[]),n=n[s]}var c=t[t.length-1];ur(n,c)||(n!==Object.prototype&&n!==Number.prototype&&n!==String.prototype||(n={}),n===Array.prototype&&(n=[]),void 0===n[c]||r.bools[c]||"boolean"==typeof n[c]?n[c]=o:Array.isArray(n[c])?n[c].push(o):n[c]=[n[c],o])}function a(e,t,n){if(!n||!r.unknownFn||function(e,t){return r.allBools&&/^--[^=]+$/.test(t)||r.strings[e]||r.bools[e]||o[e]}(e,n)||!1!==r.unknownFn(n)){var i=!r.strings[e]&&lr(t)?Number(t):t;c(s,e.split("."),i),(o[e]||[]).forEach(function(e){c(s,e.split("."),i)})}}Object.keys(r.bools).forEach(function(e){a(e,void 0!==i[e]&&i[e])});var l=[];-1!==e.indexOf("--")&&(l=e.slice(e.indexOf("--")+1),e=e.slice(0,e.indexOf("--")));for(var u=0;u<e.length;u++){var h,d,p=e[u];if(/^--.+=/.test(p)){var f=p.match(/^--([^=]+)=([\s\S]*)$/);h=f[1];var g=f[2];r.bools[h]&&(g="false"!==g),a(h,g,p)}else if(/^--no-.+/.test(p))a(h=p.match(/^--no-(.+)/)[1],!1,p);else if(/^--.+/.test(p))h=p.match(/^--(.+)/)[1],void 0===(d=e[u+1])||/^(-|--)[^-]/.test(d)||r.bools[h]||r.allBools||o[h]&&n(h)?/^(true|false)$/.test(d)?(a(h,"true"===d,p),u+=1):a(h,!r.strings[h]||"",p):(a(h,d,p),u+=1);else if(/^-[^-]+/.test(p)){for(var m=p.slice(1,-1).split(""),v=!1,y=0;y<m.length;y++)if("-"!==(d=p.slice(y+2))){if(/[A-Za-z]/.test(m[y])&&"="===d[0]){a(m[y],d.slice(1),p),v=!0;break}if(/[A-Za-z]/.test(m[y])&&/-?\d+(\.\d*)?(e-?\d+)?$/.test(d)){a(m[y],d,p),v=!0;break}if(m[y+1]&&m[y+1].match(/\W/)){a(m[y],p.slice(y+2),p),v=!0;break}a(m[y],!r.strings[m[y]]||"",p)}else a(m[y],d,p);h=p.slice(-1)[0],v||"-"===h||(!e[u+1]||/^(-|--)[^-]/.test(e[u+1])||r.bools[h]||o[h]&&n(h)?e[u+1]&&/^(true|false)$/.test(e[u+1])?(a(h,"true"===e[u+1],p),u+=1):a(h,!r.strings[h]||"",p):(a(h,e[u+1],p),u+=1))}else if(r.unknownFn&&!1===r.unknownFn(p)||s._.push(r.strings._||!lr(p)?p:Number(p)),t.stopEarly){s._.push.apply(s._,e.slice(u+1));break}}return Object.keys(i).forEach(function(e){var t,r,n;t=s,r=e.split("."),n=t,r.slice(0,-1).forEach(function(e){n=n[e]||{}}),r[r.length-1]in n||(c(s,e.split("."),i[e]),(o[e]||[]).forEach(function(t){c(s,t.split("."),i[e])}))}),t["--"]?s["--"]=l.slice():l.forEach(function(e){s._.push(e)}),s}};const dr=M.default,pr=B.default,{parseArgv:fr}=hr;process.cwd();var gr={getRandomString:function(){return Math.random().toString(36).substring(2)},mkdir:function(e,t={}){pr.sync(e,t)},validValue:function(e){return null!=e&&""!==e},sleep:function(e){return new Promise(t=>setTimeout(t,e))},replaceArgsValue:function(e,t,r){t+="=";for(let o=0;o<e.length;o++){let n=e[o],i=n.indexOf(t);if(-1!==i){i+=t.length;let s=n.substring(0,i);e[o]=s+r;break}}return e},getValueFromArgv:function(e,t){const r=fr(e);if(r.hasOwnProperty(t))return r[t];let o;t+="=";for(let r=0;r<e.length;r++){let n=e[r],i=n.indexOf(t);if(-1!==i){i+=t.length,o=n.substring(i);break}}return o},fileIsExist:function(e){return!(!dr.existsSync(e)||!dr.statSync(e).isFile())}};const mr=H.default,vr=A.default,yr=J.default,{coreLogger:wr}=jt,{getExtraResourcesDir:Er,isPackaged:br,isDev:xr,getBaseDir:Sr}=Se,{Events:Pr}=Re,{getRandomString:kr,getValueFromArgv:_r}=gr,{is:jr}=ar,{parseArgv:Or}=hr,{app:Cr}=R.default,Ar=U.default;var Dr={CrossProcess:class{constructor(e,t={}){this.emitter=new mr,this.host=e,this.child=void 0,this.pid=0,this.port=0,this.name="",this.config={},this._init(t)}_init(e={}){const{targetConf:t,port:r}=e;this.config=t,this.port=r,this.name=t.name;let o="",n=t.args,i=Er(),s=["inherit","inherit","inherit","ipc"];br()&&(s=["ignore","ignore","ignore","ipc"]),t.stdio&&(s=t.stdio);const{cmd:c,directory:a}=t;if(c){if(!a)throw new Error("[electron-easymvc] [cross] The config [directory] attribute does not exist");o=c,vr.isAbsolute(c)||xr()||(o=vr.join(Er(),c))}else o=vr.join(Er(),t.name);jr.windows()&&".exe"!=vr.extname(o)&&(!0!==t.windowsExtname&&xr()||(o+=".exe")),i=a&&vr.isAbsolute(a)?a:a&&!vr.isAbsolute(a)?xr()?vr.join(Sr(),a):vr.join(Er(),a):Er(),wr.info(`[electron-easymvc] [cross/run] cmd: ${o}, args: ${n}`);const l=yr(o,n,{stdio:s,detached:!1,cwd:i,maxBuffer:1073741824});this.child=l,this.pid=l.pid,l.on("exit",(e,t)=>{let r={pid:this.pid};this.host.emitter.emit(Pr.childProcessExit,r),wr.info(`[electron-easymvc] [corss/process] received a exit from child-process, code:${e}, signal:${t}, pid:${this.pid}, cmd:${o}, args: ${n}`),this._exitElectron()}),l.on("error",e=>{let t={pid:this.pid};this.host.emitter.emit(Pr.childProcessError,t),wr.error(`[electron-easymvc] [corss/process] received a error from child-process, error: ${e}, pid:${this.pid}`),this._exitElectron()})}kill(e=1e3){Ar(this.pid,"SIGINT",t=>{t&&(wr.error(`[electron-easymvc] [corss/process] kill cross-process, error: ${t}, pid:${this.pid}`),Ar(this.pid,"SIGKILL")),setTimeout(()=>{this._exitElectron()},e)})}getUrl(){const e=_r(this.config.args,"ssl");let t=_r(this.config.args,"hostname"),r="http://";!e||"true"!=e&&"1"!=e||(r="https://"),t=t||"127.0.0.1";return r+t+":"+this.port}getArgsObj(){return Or(this.config.args)}setPort(e){this.port=parseInt(e)}_generateId(){const e=kr();return`node:${this.pid}:${e}`}_exitElectron(e=1e3){this.config.appExit&&setTimeout(()=>{Cr.quit()},e)}}};const Lr=W.default,Ir=F.default;class Mr extends Error{constructor(e){super(`${e} is locked`)}}const Nr={old:new Set,young:new Set};let Tr;const Rr=e=>new Promise((t,r)=>{const o=Lr.createServer();o.unref(),o.on("error",r),o.listen(e,()=>{const{port:e}=o.address();o.close(()=>{t(e)})})}),Fr=async(e,t)=>{if(e.host||0===e.port)return Rr(e);for(const r of t)try{await Rr({port:e.port,host:r})}catch(e){if(!["EADDRNOTAVAIL","EINVAL"].includes(e.code))throw e}return e.port};var $r={getPort:async function(e){let t;e&&(t="number"==typeof e.port?[e.port]:e.port),void 0===Tr&&(Tr=setInterval(()=>{Nr.old=Nr.young,Nr.young=new Set},15e3),Tr.unref&&Tr.unref());const r=(()=>{const e=Ir.networkInterfaces(),t=new Set([void 0,"0.0.0.0"]);for(const r of Object.values(e))for(const e of r)t.add(e.address);return t})();for(const o of function*(e){e&&(yield*e),yield 0}(t))try{let t=await Fr({...e,port:o},r);for(;Nr.old.has(t)||Nr.young.has(t);){if(0!==o)throw new Mr(o);t=await Fr({...e,port:o},r)}return Nr.young.add(t),t}catch(e){if(!(["EADDRINUSE","EACCES"].includes(e.code)||e instanceof Mr))throw e}throw new Error("No available ports found")}};const qr=H.default,{getConfig:Br}=nt,{sleep:Hr,getValueFromArgv:Jr,replaceArgsValue:Ur}=gr,{CrossProcess:Wr}=Dr,{Events:Vr}=Re,{extend:zr}=ce,{getPort:Qr}=$r;let Yr=class{constructor(){this.emitter=void 0,this.children={},this.childrenMap={},this._initEventEmitter()}async create(){const e=Br().cross;for(let t of Object.keys(e)){1==e[t].enable&&this.run(t)}}async run(e,t={}){const r=Br().cross[e]||{},o=zr(!0,{},r,t);if(0==Object.keys(o).length)throw new Error(`[electron-easymvc] [cross] The service [${e}] config does not exit`);let n=o.args,i=parseInt(Jr(n,"port"));isNaN(i)&&o.port>0&&(i=o.port),i>0&&(i=await Qr({port:i}),o.args=Ur(n,"port",String(i)));const s=new Wr(this,{targetConf:o,port:i});let c=o.name;return this.childrenMap.hasOwnProperty(c)&&(c=c+"-"+String(s.pid)),this.childrenMap[c]=s.pid,s.name=c,this.children[s.pid]={name:c,entity:s},s}killAll(){Object.keys(this.children).forEach(e=>{this.kill(e)})}kill(e){const t=this.getProc(e);t&&t.kill()}killByName(e){const t=this.getProcByName(e);t&&t.kill()}getUrl(e){return this.getProcByName(e).getUrl()}getProcByName(e){const t=this.childrenMap[e];if(!t)throw new Error(`[electron-easymvc] [cross] The process named [${e}] does not exit`);return this.getProc(t)}getProc(e){const t=this.children[e];if(!e)throw new Error(`[electron-easymvc] [cross] The process pid [${e}] does not exit`);return t.entity}getPids(){return Object.keys(this.children)}_initEventEmitter(){this.emitter=new qr,this.emitter.on(Vr.childProcessExit,e=>{const t=this.children[e.pid];delete this.childrenMap[t.name],delete this.children[e.pid]}),this.emitter.on(Vr.childProcessError,e=>{const t=this.children[e.pid];delete this.childrenMap[t.name],delete this.children[e.pid]})}};var Gr={Cross:Yr,cross:new Yr};const{Cross:Kr,cross:Xr}=Gr;var Zr={Cross:Kr,cross:Xr};var eo={eventBus:new class{constructor(){this.lifecycleEvents={},this.eventsMap={}}register(e,t){this.lifecycleEvents[e]||(this.lifecycleEvents[e]=t)}emitLifecycle(e,...t){const r=this.lifecycleEvents[e];r&&r(...t)}on(e,t){this.eventsMap[e]||(this.eventsMap[e]=t)}emit(e,...t){const r=this.eventsMap[e];r&&r(...t)}},Ready:"ready",ElectronAppReady:"electron-app-ready",WindowReady:"window-ready",Preload:"preload",BeforeClose:"before-close"};const to=A.default;var ro={getHtmlFilepath:function(e){return to.join(__dirname,e)}};const oo=C.default("electron-easymvc:electron:window"),no=I.default,io=A.default,so=V.default,{BrowserWindow:co}=R.default,{getConfig:ao}=nt,{eventBus:lo,WindowReady:uo}=eo,{env:ho,isDev:po,getBaseDir:fo}=Se,{loadFile:go}=Le,{isFileProtocol:mo}=ar,{getHtmlFilepath:vo}=ro,{fileIsExist:yo,sleep:wo}=gr,{coreLogger:Eo}=jt,{extend:bo}=ce,{cross:xo}=Zr,So={mainWindow:null,closeAndQuit:!0};function Po(){return So.mainWindow}function ko(e,t,r="url"){const{mainServer:o}=ao(),n=Po();Eo.info("[electron-easymvc] Env: %s, Type: %s",ho(),e),Eo.info("[electron-easymvc] App running at: %s",t),"file"==r?n.loadFile(t,o.options).then().catch(e=>{Eo.error(`[electron-easymvc] Please check the ${t} !`)}):n.loadURL(t,o.options).then().catch(e=>{Eo.error(`[electron-easymvc] Please check the ${t} !`)})}function _o(e){if(!yo(e))return;Po().loadFile(e)}var jo={getMainWindow:Po,createMainWindow:function(){const{openDevTools:e,windowsOption:t}=ao(),r=new co(t);return So.mainWindow=r,no.object(e)?r.webContents.openDevTools(e):!0===e&&r.webContents.openDevTools({mode:"bottom"}),lo.emitLifecycle(uo),r},setCloseAndQuit:function(e){So.closeAndQuit=e},getCloseAndQuit:function(){return So.closeAndQuit},loadServer:async function(){let e="spa",t="";const{remote:r,mainServer:o}=ao(),n=Po();if(1==r.enable)return e="remote",t=r.url,void ko(e,t);if(po()){let t,r="url";const o=io.join(fo(),"./cmd/bin.js"),i=go(o),{dev:s}=i,c=bo(!0,{protocol:"http://",hostname:"localhost",port:8080,indexPath:"index.html"},s.frontend),a=bo(!0,{loadingPage:"/public/html/loading.html"},s.electron);if(t=c.protocol+c.hostname+":"+c.port,mo(c.protocol)&&(t=io.join(fo(),c.directory,c.indexPath),r="file"),"url"==r){let e=vo("boot.html");a.hasOwnProperty("loadingPage")&&""!=a.loadingPage&&(e=io.join(fo(),a.loadingPage)),_o(e);const r=!0===c.force?3:60;let o=0,i=!1;for(;!i&&o<r;){await wo(1e3);try{await so({method:"get",url:t,timeout:1e3,proxy:!1,headers:{Accept:"text/html, application/json, text/plain, */*"}}),i=!0}catch(e){}o++}if(oo("it takes %d seconds to start the frontend",o),0==i&&!0!==c.force){const e=vo("failure.html");return n.loadFile(e),void Eo.error(`[electron-easymvc] Please check the ${t} !`)}}return void ko(e,t,r)}o.takeover.length>0?await async function(){const e=ao().cross,t=ao().mainServer;if(t.loadingPage.length>0){_o(io.join(fo,t.loadingPage))}const r=t.takeover;if(!e.hasOwnProperty(r))throw new Error("[electron-easymvc] Please Check the value of mainServer.takeover in the config file !");if(1!=e[r].enable)throw new Error(`[electron-easymvc] Please Check the value of cross.${r} enable is true !`);const o=e[r].name,n=xo.getUrl(o);let i=0,s=!1;const c=po()?20:100,a=po()?1e3:200;for(;!s&&i<c;){await wo(a);try{await so({method:"get",url:n,timeout:100,proxy:!1,headers:{Accept:"text/html, application/json, text/plain, */*"}}),s=!0}catch(e){}i++}if(oo("it takes %d seconds to start the cross serivce",i*a),0==s){const e=vo("cross-failure.html");throw Po().loadFile(e),new Error(`[electron-easymvc] Please check cross service [${r}] ${n} !`)}Eo.info(`[electron-easymvc] cross service [${r}] is started successfully`),ko("spa",n)}():(t=io.join(fo(),o.indexPath),ko(e,t,"file"))}};const{app:Oo}=R.default,{coreLogger:Co}=jt,{is:Ao}=ar,{cross:Do}=Zr,{createMainWindow:Lo,setCloseAndQuit:Io,loadServer:Mo}=jo,{eventBus:No,ElectronAppReady:To,BeforeClose:Ro,Preload:Fo}=eo,{getConfig:$o}=nt;var qo={electronApp:Oo,createElectron:function(){const{singleLock:e}=$o(),t=Oo.requestSingleInstanceLock();!e||t?(Oo.whenReady().then(()=>{Lo(),No.emitLifecycle(Fo),Mo()}),Oo.on("window-all-closed",()=>{Ao.macOS()||(Co.info("[electron-easymvc] [lib/eeApp] window-all-closed quit"),Oo.quit())}),Oo.on("before-quit",()=>{Io(!0),No.emitLifecycle(Ro),Do.killAll()}),No.emitLifecycle(To)):Oo.quit()}};const Bo=C.default("electron-easymvc:core:loader:file_loader"),Ho=T.default,Jo=M.default,Uo=A.default,Wo=z.default,Vo=I.default,{isBytecodeClass:zo,loadFile:Qo,filePatterns:Yo}=ke,Go=Symbol("LOADER_ITEM_FULLPATH"),Ko=Symbol("LOADER_ITEM_EXPORTS"),Xo={directory:null,target:null,match:void 0,caseStyle:"camel",initializer:null,call:!0,inject:void 0};function Zo(e,{caseStyle:t}){if(Vo.function(t)){const r=t(e);return Ho(Vo.array(r),`caseStyle expect an array, but got ${r}`),r}return function(e,t){const r=e.substring(0,e.lastIndexOf(".")).split("/");return r.map(r=>{if(!/^[a-z][a-z0-9_-]*$/i.test(r))throw new Error(`${r} is not match 'a-z0-9_-' in ${e}`);let o=(r=r.replace(/[_-][a-z]/gi,e=>e.substring(1).toUpperCase()))[0];switch(t){case"lower":o=o.toLowerCase();break;case"upper":o=o.toUpperCase()}return o+r.substring(1)})}(e,t)}function en(e,{initializer:t,call:r,inject:o},n){let i=Qo(e);return t&&(i=t(i,{path:e,pathName:n})),Vo.class(i)||Vo.generatorFunction(i)||Vo.asyncFunction(i)||zo(i)||r&&Vo.function(i)&&(i=i(o)),i}var tn={FileLoader:class{constructor(e){Ho(e.directory,"options.directory is required"),this.options=Object.assign({},Xo,e),Bo("[constructor] options: %o",this.options)}load(){const e=this.parse(),t={};for(const r of e)r.properties.reduce((e,t,o)=>{let n;return o===r.properties.length-1?(n=r.exports,n&&!Vo.primitive(n)&&(n[Go]=r.fullpath,n[Ko]=!0)):n=e[t]||{},e[t]=n,n},t);return t}parse(){let e=this.options.match;e=e?Array.isArray(e)?e:[e]:Yo();let t=this.options.directory;Array.isArray(t)||(t=[t]);const r=[];Bo("[parse] directories %o",t);for(const o of t){const t=Wo.sync(e,{cwd:o});Bo("[parse] filepaths %o",t);for(const e of t){const t=Uo.join(o,e);if(!Jo.statSync(t).isFile())continue;const n=Zo(e,this.options),i=o.split(/[/\\]/).slice(-1)+"."+n.join(".");let s=en(t,this.options,i);null!=s&&((Vo.class(s)||zo(s))&&(s.prototype.pathName=i,s.prototype.fullPath=t),r.push({fullpath:t,properties:n,exports:s}))}}return r}},EXPORTS:Ko,FULLPATH:Go};const rn=C.default("electron-easymvc:controller:controller_loader"),on=A.default,nn=I.default,{getElectronDir:sn}=Se,{Timing:cn}=Te,{FileLoader:an,FULLPATH:ln}=tn,{isBytecodeClass:un,callFn:hn}=ke;function dn(e,t){return function(...r){const o=new e;return hn(o[t],r,o)}}var pn={ControllerLoader:class{constructor(){this.timing=new cn}load(){this.timing.start("Load Controller");const e={caseStyle:"lower",directory:on.join(sn(),"controller"),initializer:(e,t)=>nn.class(e)||un(e)?(e.prototype.pathName=t.pathName,e.prototype.fullPath=t.path,function(e){let t=e.prototype;const r={};for(;t!==Object.prototype;){const o=Object.getOwnPropertyNames(t);for(const n of o){if("constructor"===n)continue;const o=Object.getOwnPropertyDescriptor(t,n);nn.function(o.value)&&!r.hasOwnProperty(n)&&(r[n]=dn(e,n),r[n][ln]=e.prototype.fullPath+"#"+e.name+"."+n+"()")}t=Object.getPrototypeOf(t)}return r}(e)):e},t=new an(e).load();return rn("[load] controllers: %o",t),this.timing.end("Load Controller"),t}}};const{ControllerLoader:fn}=pn,gn={controller:null};function mn(){const e=new fn;gn.controller=e.load()}var vn={loadController:mn,getController:function(){return gn.controller||mn(),gn.controller}};const yn=C.default("electron-easymvc:socket:socketServer"),wn=I.default,{Server:En}=Q.default,{coreLogger:bn}=jt,{getConfig:xn}=nt,{SocketIO:Sn}=Re,{getController:Pn}=vn,{getPort:kn}=$r;var _n={SocketServer:class{constructor(){const{socketServer:e,mainServer:t}=xn();this.config=e,this.channelSeparator=t.channelSeparator,this.socket=void 0,this.io=void 0,this.init()}async init(){if(0==this.config.enable)return;const e=await kn({port:parseInt(this.config.port)});if(!e)throw new Error("[electron-easymvc] [socket/socketServer] socekt port required, and must be a number !");bn.info("[electron-easymvc] [socket/socketServer] port is:",e),process.env.EE_SOCKET_PORT=e,this.config.port=e,this.io=new En(e,this.config),this.connect()}connect(){const e=Pn();this.io.on("connection",t=>{const r=this.config.channel||Sn.partySoftware;this.socket=t,t.on(r,async(r,o)=>{bn.info("[electron-easymvc] [socket/socketServer] socket id:"+t.id+" message cmd: "+r.cmd);try{const t=r.cmd,n=r.args;let i=null;if(yn("[socket] channel %s",t),wn.string(t)){const r=t.split(this.channelSeparator);yn("[findFn] channel %o",r);let o={controller:e};r.forEach(e=>{if(o=o[e],!o)throw new Error(`class or function '${e}' not exists`)}),i=o}if(!i)throw new Error("function not exists");const s=await i.call(e,n);o&&o(s)}catch(e){bn.error("[electron-easymvc] [socket/socketServer] throw error:",e)}})})}}};const jn=C.default("electron-easymvc:socket:httpServer"),On=T.default,Cn=I.default,An=G.default,Dn=K.default,Ln=X.default,In=Z.default,Mn=M.default,Nn=A.default,Tn=ee.default,{coreLogger:Rn}=jt,{getBaseDir:Fn}=Se,{getController:$n}=vn,{getConfig:qn}=nt,{getPort:Bn}=$r;let Hn="/";var Jn={HttpServer:class{constructor(){const{httpServer:e,mainServer:t}=qn();this.config=e,Hn=t.channelSeparator,this.httpApp=void 0,this.init()}async init(){if(0==this.config.enable)return;const e=await Bn({port:parseInt(this.config.port)});if(!e)throw new Error("[electron-easymvc] [socket/HttpServer] http port required, and must be a number !");process.env.EE_HTTP_PORT=e,this.config.port=e,this._create()}_create(){const e=this.config,t=e.koaConfig||{},{preMiddleware:r=[],postMiddleware:o=[],errorHandler:n=null}=t,i=e?.https?.enable??!1,s={};if(!0===i){e.protocol="https://";const t=Nn.join(Fn(),e.https.key),r=Nn.join(Fn(),e.https.cert);On(Mn.existsSync(t),"ssl key file is required"),On(Mn.existsSync(r),"ssl cert file is required"),s.key=Mn.readFileSync(t),s.cert=Mn.readFileSync(r)}const c=e.protocol+e.host+":"+e.port,a=e.cors,l=new An;this._setupErrorHandler(l,n),this._loadMiddlewares(l,r),l.use(Dn(a)).use(Ln(e.body)).use(this._dispatch),this._loadMiddlewares(l,o,"post");let u="[electron-easymvc] [socket/http] server is: "+c;const h={host:e.host,port:e.port};i?In.createServer(s,l.callback()).listen(h,e=>{u=e||u,Rn.info(u)}):l.listen(h,e=>{u=e||u,Rn.info(u)}),this.httpApp=l}async _dispatch(e,t){const r=$n(),{filterRequest:o}=qn().httpServer;let n=e.request.path;const i=e.request.method;let s=e.request.query;s=Cn.object(s)?JSON.parse(JSON.stringify(s)):{};const c=e.request.body;e.response.status=200;try{if(0==n.indexOf("/")&&(n=n.substring(1)),Tn.includes(o.uris,n))return e.response.body=o.returnData,void await t();"controller"!=n.slice(0,10)&&(n="controller/"+n);const a=n.split("/").join(Hn);jn("[request] uri %s",a);const l="POST"==i?c:s;let u=null;if(Cn.string(a)){const e=a.split(Hn);jn("[findFn] channel %o",e);let t={controller:r};e.forEach(e=>{if(t=t[e],!t)throw new Error(`class or function '${e}' not exists`)}),u=t}if(!u)throw new Error("function not exists");const h=await u.call(r,l,e);e.response.body=h}catch(e){Rn.error("[electron-easymvc/httpServer] throw error:",e)}await t()}getHttpApp(){return this.httpApp}_setupErrorHandler(e,t){Cn.function(t)&&e.on("error",t)}_loadMiddlewares(e,t=[],r="pre"){Cn.array(t)&&t.forEach(t=>{Cn.function(t)?e.use(t()):Rn.warn(`[electron-easymvc/httpServer] Invalid ${r} middleware detected, skipping.`)})}}};const Un=C.default("electron-easymvc:socket:ipcServer"),Wn=I.default,{ipcMain:Vn}=R.default,{coreLogger:zn}=jt,{getController:Qn}=vn,{EXPORTS:Yn}=tn,{getConfig:Gn}=nt;var Kn={IpcServer:class{constructor(){const{mainServer:e}=Gn();this.channelSeparator=e.channelSeparator,this.directory="controller",this.init()}init(){const e=Qn();this.loop(e,this.directory)}loop(e,t){const r=Object.keys(e);for(const o of r){if("constructor"===o)continue;let r=e[o],n=t+"."+o;r&&!0===r[Yn]?this.register(r,n):"object"==typeof r&&this.loop(r,n)}}register(e,t){const r=Qn(),o=Object.keys(e);for(const e of o){const o=`${t}.${e}`.split(".").join(this.channelSeparator);Un("[register] channel %s",o),Vn.on(o,async(e,t)=>{try{const n=this.findFn(r,o),i=await n.call(r,t,e);e.returnValue=i,e.reply(`${o}`,i)}catch(e){zn.error("[electron-easymvc] [socket/IpcServer] send/on throw error:",e)}}),Vn.handle(o,async(e,t)=>{try{const n=this.findFn(r,o);return await n.call(r,t,e)}catch(e){zn.error("[electron-easymvc] [socket/IpcServer] invoke/handle throw error:",e)}})}}findFn(e,t){try{const r=t;let o=null;if(Wn.string(r)){const t=r.split(this.channelSeparator);Un("[findFn] channel %o",t);let n={controller:e};t.forEach(e=>{if(n=n[e],!n)throw new Error(`class or function '${e}' not exists`)}),o=n}if(!o)throw new Error("function not exists");return o}catch(e){zn.error("[electron-easymvc] [socket/IpcServer] throw error:",e)}return null}}};const Xn=Q.default,Zn=Y.default,ei=G.default,{SocketServer:ti}=_n,{HttpServer:ri}=Jn,{IpcServer:oi}=Kn,ni={socketServer:null,httpServer:null};var ii={Koa:ei,IoServer:Xn,IoClient:Zn,loadSocket:function(){ni.socketServer=new ti,ni.socketServer,ni.httpServer=new ri,ni.httpServer,ni.ipcServer=new oi,ni.ipcServer},getSocketServer:function(){return ni.socketServer},getHttpServer:function(){return ni.httpServer},getIpcServer:function(){return ni.ipcServer}};const{createElectron:si}=qo,{getMainWindow:ci,setCloseAndQuit:ai,getCloseAndQuit:li}=jo;var ui={loadElectron:function(){si()},getMainWindow:ci,setCloseAndQuit:ai,getCloseAndQuit:li};C.default("electron-easymvc:app:appliaction");const{loadController:hi}=vn,{eventBus:di,Ready:pi}=eo,{loadSocket:fi}=ii,{loadElectron:gi}=ui;var mi={app:new class{constructor(){}register(e,t){return di.register(e,t)}run(){hi(),fi(),di.emitLifecycle(pi),gi()}}};const vi=M.default,{getUserHomeHiddenAppDir:yi,getLogDir:wi,getDataDir:Ei}=Se,{mkdir:bi}=gr;var xi={loadDir:function(){!function(){const e=yi();vi.existsSync(e)||bi(e,{mode:493});const t=Ei();vi.existsSync(t)||bi(t,{mode:493});const r=wi();vi.existsSync(r)||bi(r,{mode:493})}()}};const Si=C.default("electron-easymvc:app:boot"),Pi=A.default,{loadException:ki}=Vt,{electronApp:_i}=qo,{getArgumentByName:ji,getBundleDir:Oi,getElectronCodeDir:Ci}=Se,{loadConfig:Ai}=nt,{loadLog:Di}=jt,{app:Li}=mi,{loadDir:Ii}=xi;var Mi={ElectronEasyMvc:class{constructor(){const e=_i.getAppPath(),{env:t}=process,r=ji("env")||"prod",o="true"==ji("debuger");let n=Oi(e);o&&(n=Ci(e));const i={env:r,baseDir:e,electronDir:n,appName:_i.getName(),userHome:_i.getPath("home"),appData:_i.getPath("appData"),appUserData:_i.getPath("userData"),appVersion:_i.getVersion(),isPackaged:_i.isPackaged,execDir:e};"prod"==r&&i.isPackaged&&(i.execDir=Pi.dirname(_i.getPath("exe"))),t.EE_ENV=r,t.EE_APP_NAME=i.appName,t.EE_APP_VERSION=i.appVersion,t.EE_BASE_DIR=i.baseDir,t.EE_ELECTRON_DIR=i.electronDir,t.EE_USER_HOME=i.userHome,t.EE_APP_DATA=i.appData,t.EE_APP_USER_DATA=i.appUserData,t.EE_EXEC_DIR=i.execDir,t.EE_IS_PACKAGED=i.isPackaged,t.EE_SOCKET_PORT=null,t.EE_HTTP_PORT=null,Si("[constructor] options:%j",i),this.init()}init(){ki(),Ai(),Ii(),Di()}register(e,t){return Li.register(e,t)}run(){Li.run()}}};const{ElectronEasyMvc:Ni}=Mi;var Ti={ElectronEasyMvc:Ni};const{ElectronEasyMvc:Ri}=Ti;var Fi={ElectronEasyMvc:Ri};const $i=T.default,qi=M.default,Bi=A.default,Hi=te.default,{mkdir:Ji}=gr,{getDataDir:Ui}=Se;var Wi={SqliteStorage:class{constructor(e,t={}){$i(e,`db name ${e} Cannot be empty`),this.name=e,this.mode=this.getMode(e),this.dbDir=this._createDatabaseDir(),this.fileName=this._formatFileName(e),this.db=this._initDB(t)}_initDB(e={}){let t=Object.assign({timeout:5e3},e),r=this.name;"memory"!=this.mode&&(r=this.getFilePath());const o=new Hi(r,t);return"memory"!=this.mode&&$i(qi.existsSync(r),`error: db ${r} not exists`),o}_formatFileName(e){let t=e;return"memory"!=this.mode&&(t=Bi.basename(e)),t}_createDatabaseDir(){let e=Bi.join(Ui(),"db");return"absolute"==this.mode&&(e=Bi.dirname(this.name)),qi.existsSync(e)||Ji(e,{mode:493}),e}getMode(e){let t="";if(":memory:"==e)return t="memory",t;if($i(".db"==Bi.extname(e),`error: db ${e} file ext name must be .db`),-1!==(e=e.replace(/[/\\]/g,"/")).indexOf("/")){return t=Bi.isAbsolute(e)?"absolute":"relative",t}return t="onlyName",t}getDbDir(){return this.dbDir}getFilePath(){return Bi.join(this.dbDir,this.fileName)}}};const{SqliteStorage:Vi}=Wi;var zi={SqliteStorage:Vi};const Qi=A.default,Yi=H.default,Gi=re.default,{fork:Ki}=$.default,{coreLogger:Xi}=jt,{getBaseDir:Zi,isPackaged:es,allEnv:ts}=Se,{Processes:rs,Events:os,Receiver:ns}=Re,{getRandomString:is}=gr,{getFullpath:ss}=Le,{extend:cs}=ce;var as={JobProcess:class{constructor(e,t={}){let r=Zi();const o=Qi.join(__dirname,"app.js");es()&&(r=Qi.join(Zi(),".."));const n=cs(!0,{processArgs:{},processOptions:{cwd:r,env:ts(),stdio:"ignore"}},t);this.emitter=new Yi,this.host=e,this.args=[],this.sleeping=!1,this.args.push(JSON.stringify(n.processArgs)),this.child=Ki(o,this.args,n.processOptions),this.pid=this.child.pid,this._init()}_init(){const{messageLog:e}=this.host.config;this.child.on("message",t=>{1==e&&Xi.info(`[electron-easymvc] [jobs/child] received a message from child-process, message: ${Gi(t)}`),t.channel==rs.showException&&Xi.error(`${t.data}`),t.channel==rs.sendToMain&&this._eventEmit(t)}),this.child.on("exit",(e,t)=>{let r={pid:this.pid};this.host.emit(os.childProcessExit,r),Xi.info(`[electron-easymvc] [jobs/child] received a exit from child-process, code:${e}, signal:${t}, pid:${this.pid}`)}),this.child.on("error",e=>{let t={pid:this.pid};this.host.emit(os.childProcessError,t),Xi.error(`[electron-easymvc] [jobs/child] received a error from child-process, error: ${e}, pid:${this.pid}`)})}_eventEmit(e){switch(e.eventReceiver){case ns.forkProcess:this.emitter.emit(e.event,e.data);break;case ns.childJob:this.host.emit(e.event,e.data);break;default:this.host.emit(e.event,e.data),this.emitter.emit(e.event,e.data)}}dispatch(e,t="",...r){let o={mid:is(),cmd:e,jobPath:t,jobParams:r};this.child.send(o)}callFunc(e="",t="",...r){e=ss(e);let o={mid:is(),cmd:"run",jobPath:e,jobFunc:t,jobFuncParams:r};this.child.send(o)}kill(e=1e3){this.child.kill("SIGINT"),setTimeout(()=>{this.child.killed||this.child.kill("SIGKILL")},e)}}};const ls=H.default,{JobProcess:us}=as,{getFullpath:hs}=Le,{Events:ds}=Re,{getConfig:ps}=nt,{extend:fs}=ce;var gs={ChildJob:class extends ls{constructor(){super(),this.jobs={},this.config={};const e=ps().jobs;e&&(this.config=e),this._initEvents()}_initEvents(){this.on(ds.childProcessExit,e=>{delete this.jobs[e.pid]}),this.on(ds.childProcessError,e=>{delete this.jobs[e.pid]})}exec(e,t={},r={}){const o=hs(e),n=this.createProcess(r);return n.dispatch("run",o,t),n}createProcess(e={}){const t=fs(!0,{processArgs:{type:"childJob"}},e),r=new us(this,t);if(!r){throw new Error("[electron-easymvc] [jobs/child] Failed to obtain the child process !")}return this.jobs[r.pid]=r,r}getPids(){return Object.keys(this.jobs)}async execPromise(e,t={},r={}){return this.exec(e,t,r)}}},ms={polling:"polling",weights:"weights",random:"random",specify:"specify",weightsPolling:"weightsPolling",weightsRandom:"weightsRandom",minimumConnection:"minimumConnection",weightsMinimumConnection:"weightsMinimumConnection"};const vs=ms;const ys=ms,ws={[vs.polling]:function(e,t,r){if(!e.length)return null;const o=e[t];return r.currentIndex++,r.currentIndex%=e.length,o||null},[vs.weights]:function(e,t,r){if(!e.length)return null;let o,n=e[0].weight,i=0;for(let r=0;r<e.length;r++)o=(e[r].weight||0)+Math.random()*t,o>=n&&(n=o,i=r);return r.weightIndex+=1,r.weightIndex%=t+1,e[i]},[vs.random]:function(e){const t=e.length;return e[Math.floor(Math.random()*t)]||null},[vs.specify]:function(e,t){let r;for(let o=0;o<e.length;o++)if(e[o].id===t){r=e[o];break}return r||null},[vs.minimumConnection]:function(e,t={}){if(e.length<2)return e[0]||null;let r=t[e[0].id],o=0;for(let n=1;n<e.length;n++){const i=t[e[n].id]||0;i<=r&&(r=i,o=n)}return e[o]||null},[vs.weightsPolling]:function(e,t,r,o){if(!e.length)return null;let n,i=0;for(let r=0;r<e.length;r++)if(i+=e[r].weight||0,i>t){n=e[r];break}return o.weightIndex+=1,o.weightIndex%=r+1,n},[vs.weightsRandom]:function(e,t){let r,o=Math.ceil(Math.random()*t);for(let t=0;t<e.length;t++)if(o-=e[t].weight||0,o<=0){r=e[t];break}return r||null},[vs.weightsMinimumConnection]:function(e,t,r,o){if(!e.length)return null;let n,i=e[0].weight,s=0;const c=e.reduce((e,t)=>e+=r[t.id]||0,0);for(let o=0;o<e.length;o++)n=(e[o].weight||0)+Math.random()*t+(r[e[o].id]||0)*t/c,n<=i&&(i=n,s=o);return o.weightIndex+=1,o.weightIndex%=t+1,e[s]}};const Es=ms,bs=class{constructor(e){this.algorithm=e||ys.polling}calculate(e,t){return ws[this.algorithm](e,...t)}setAlgorithm=e=>{if(!(e in ys))throw new Error(`Invalid algorithm: ${e}, pick from ${Object.keys(ys).join("|")}`);this.algorithm=e}};var xs=class{static Algorithm=Es;constructor(e){this.targets=e.targets,this.algorithm=e.algorithm||Es.polling,this.params={currentIndex:0,weightIndex:0,weightTotal:0,connectionsMap:{},cpuOccupancyMap:{},memoryOccupancyMap:{}},this.scheduler=new bs(this.algorithm),this.memoParams=this.memorizedParams(),this.calculateWeightIndex()}memorizedParams(){return{[Es.random]:()=>[],[Es.polling]:()=>[this.params.currentIndex,this.params],[Es.weights]:()=>[this.params.weightTotal,this.params],[Es.specify]:e=>[e],[Es.weightsRandom]:()=>[this.params.weightTotal],[Es.weightsPolling]:()=>[this.params.weightIndex,this.params.weightTotal,this.params],[Es.minimumConnection]:()=>[this.params.connectionsMap],[Es.weightsMinimumConnection]:()=>[this.params.weightTotal,this.params.connectionsMap,this.params]}}refreshParams(e){const t=Object.values(e);for(let e of t)this.params.cpuOccupancyMap[e.pid]=e.cpu,this.params.memoryOccupancyMap[e.pid]=e.memory}pickOne(...e){return this.scheduler.calculate(this.targets,this.memoParams[this.algorithm](...e))}pickMulti(e=1,...t){return new Array(e).fill().map(()=>this.pickOne(...t))}calculateWeightIndex(){this.params.weightTotal=this.targets.reduce((e,t)=>e+(t.weight||0),0),this.params.weightIndex>this.params.weightTotal&&(this.params.weightIndex=this.params.weightTotal)}calculateIndex(){this.params.currentIndex>=this.targets.length&&(this.params.currentIndex=this.params.currentIndex-1>=0?this.params.currentIndex-1:0)}clean(e){e?(delete this.params.connectionsMap[e],delete this.params.cpuOccupancyMap[e],delete this.params.memoryOccupancyMap[e]):this.params={currentIndex:0,connectionsMap:{},cpuOccupancyMap:{},memoryOccupancyMap:{}}}add(e){this.targets.find(t=>t.id===e.id)||(this.targets.push(e),this.calculateWeightIndex())}del(e){let t=!1;for(let r=0;r<this.targets.length;r++)if(this.targets[r].id===e.id){this.targets.splice(r,1),this.clean(e.id),this.calculateIndex(),t=!0;break}t&&this.calculateWeightIndex()}wipe(){this.targets=[],this.calculateWeightIndex(),this.clean()}updateParams(e){Object.entries(e).map(([e,t])=>{e in this.params&&(this.params[e]=t)})}setTargets(e){const t=e.reduce((e,t)=>(e[t.id]=1,e),{});this.targets.forEach(e=>{e.id in t||(this.clean(e.id),this.calculateIndex())}),this.targets=e,this.calculateWeightIndex()}setAlgorithm=e=>{if(!(e in Es))throw new Error(`Invalid algorithm: ${e}, pick from ${Object.keys(Es).join("|")}`);this.algorithm=e,this.params.weightIndex=0,this.scheduler.setAlgorithm(this.algorithm)}};const Ss=H.default,Ps=xs,{getFullpath:ks}=Le,{JobProcess:_s}=as,{Events:js}=Re,{validValue:Os}=gr,{getConfig:Cs}=nt;var As={ChildPoolJob:class extends Ss{constructor(e={}){super();let t=Object.assign({weights:[]},e);this.config={},this.boundMap=new Map,this.children={},this.min=3,this.max=6,this.strategy="polling",this.weights=new Array(this.max).fill().map((e,r)=>Os(t.weights[r])?t.weights[r]:1);let r={algorithm:Ps.Algorithm.polling,targets:[]};this.LB=new Ps(r);const o=Cs().jobs;o&&(this.config=o),this._initEvents()}_initEvents(){this.on(js.childProcessExit,e=>{this._removeChild(e.pid)}),this.on(js.childProcessError,e=>{this._removeChild(e.pid)})}_removeChild(e){const t=Object.keys(this.children).length,r={id:e,weight:this.weights[t-1]};this.LB.del(r),delete this.children[e]}async create(e=3){if(e<0||e>this.max)throw new Error("[electron-easymvc] [jobs/child-pool] The number is invalid !");let t=this.children.length;if(t>this.max)throw new Error(`[electron-easymvc] [jobs/child-pool] The number of current processes number: ${t} is greater than the maximum: ${this.max} !`);e+t>this.max&&(e=this.max-t);let r=Object.assign({processArgs:{type:"childPoolJob"}},{});for(let t=1;t<=e;t++){let e=new _s(this,r);this._childCreated(e)}return Object.keys(this.children)}_childCreated(e){let t=e.pid;this.children[t]=e;const r=Object.keys(this.children).length;let o={id:t,weight:this.weights[r-1]};this.LB.add(o)}run(e,t={}){const r=ks(e),o=this.getChild();return o.dispatch("run",r,t),o}async runPromise(e,t={}){return this.run(e,t)}getBoundChild(e){let t;const r=this.boundMap.get(e);return r?(t=this.children[r],t):(t=this.getChild(),this.boundMap.set(e,t.pid),t)}getChildByPid(e){return this.children[e]||null}getChild(){let e;if(0==Object.keys(this.children).length){let t=this.create(1);e=this.children[t[0]]}else{let t=this.LB.pickOne().id;e=this.children[t]}if(!e){throw new Error("[electron-easymvc] [jobs/child-pool] Failed to obtain the child process !")}return e}getPids(){return Object.keys(this.children)}killAll(e="parallel"){let t=1;Object.keys(this.children).forEach(r=>{let o=this.children[r];o&&("sequence"==e?(setTimeout(()=>{o.kill()},1e3*t),t++):o.kill())})}}};const{ChildJob:Ds}=gs,{ChildPoolJob:Ls}=As;var Is={ChildJob:Ds,ChildPoolJob:Ls},Ms="1.0.7";const{ElectronEasyMvc:Ns}=Fi;var Ts=oe({ElectronEasyMvc:Ns,log:jt,config:nt,controller:vn,loader:Le,ps:Se,utils:ar,socket:ii,storage:zi,jobs:Is,cross:Zr,electron:ui,exception:Vt,message:It,html:ro,const:Re,__internal:{version:Ms,bundled:!0,getBundlePath:()=>__dirname}});module.exports=Ts;
4674
2
  //# sourceMappingURL=electron-easymvc.bundle.js.map