ee-core 2.11.1 → 4.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/application.js +31 -0
- package/app/boot.js +81 -0
- package/app/dir.js +27 -0
- package/app/events.js +56 -0
- package/app/index.js +7 -0
- package/config/config_loader.js +66 -0
- package/config/default_config.js +110 -0
- package/config/index.js +21 -83
- package/const/channel.js +26 -16
- package/const/index.js +0 -4
- package/controller/controller_loader.js +78 -0
- package/controller/index.js +18 -19
- package/core/index.js +6 -5
- package/core/{lib/loader → loader}/file_loader.js +39 -156
- package/core/utils/index.js +83 -0
- package/core/{lib/utils → utils}/timing.js +3 -2
- package/cross/cross.js +152 -0
- package/cross/index.js +6 -181
- package/cross/spawnProcess.js +34 -51
- package/electron/app/index.js +38 -54
- package/electron/index.js +13 -17
- package/electron/window/index.js +260 -65
- package/exception/index.js +34 -32
- package/html/index.js +7 -10
- package/index.js +4 -52
- package/jobs/child/app.js +9 -9
- package/jobs/child/forkProcess.js +29 -45
- package/jobs/child/index.js +13 -10
- package/jobs/child-pool/index.js +13 -11
- package/jobs/index.js +2 -4
- package/loader/index.js +91 -144
- package/log/index.js +74 -57
- package/log/logger.js +76 -84
- package/message/childMessage.js +12 -13
- package/message/index.js +7 -16
- package/package.json +2 -2
- package/ps/index.js +137 -223
- package/socket/httpServer.js +46 -43
- package/socket/index.js +52 -69
- package/socket/ipcServer.js +80 -94
- package/socket/socketServer.js +31 -24
- package/storage/index.js +5 -37
- package/storage/sqliteStorage.js +18 -18
- package/utils/extend.js +10 -5
- package/utils/helper.js +38 -42
- package/utils/index.js +40 -23
- package/utils/ip.js +5 -45
- package/utils/is.js +107 -141
- package/utils/json.js +15 -7
- package/utils/pargv.js +5 -1
- package/utils/{get-port → port}/index.js +4 -26
- package/utils/wrap.js +8 -3
- package/addon/index.js +0 -35
- package/addon/window/index.js +0 -99
- package/bin/tools.js +0 -8
- package/config/cache.js +0 -42
- package/config/config.default.js +0 -331
- package/controller/baseContextClass.js +0 -25
- package/core/lib/ee.js +0 -216
- package/core/lib/loader/context_loader.js +0 -106
- package/core/lib/loader/ee_loader.js +0 -435
- package/core/lib/loader/mixin/addon.js +0 -32
- package/core/lib/loader/mixin/config.js +0 -130
- package/core/lib/loader/mixin/controller.js +0 -125
- package/core/lib/loader/mixin/service.js +0 -28
- package/core/lib/utils/base_context_class.js +0 -34
- package/core/lib/utils/function.js +0 -30
- package/core/lib/utils/index.js +0 -133
- package/core/lib/utils/sequencify.js +0 -59
- package/ee/appLoader.js +0 -48
- package/ee/application.js +0 -100
- package/ee/baseApp.js +0 -104
- package/ee/eeApp.js +0 -409
- package/ee/index.js +0 -58
- package/electron/window/winState.js +0 -186
- package/httpclient/index.js +0 -161
- package/jobs/baseJobClass.js +0 -16
- package/jobs/renderer/index.js +0 -141
- package/jobs/renderer/loadView.js +0 -41
- package/jobs/unification.js +0 -64
- package/main/index.js +0 -57
- package/old-utils/index.js +0 -91
- package/services/baseContextClass.js +0 -24
- package/services/index.js +0 -41
- package/socket/io.js +0 -28
- package/storage/jsondb/adapters/Base.js +0 -23
- package/storage/jsondb/adapters/FileSync.js +0 -64
- package/storage/jsondb/main.js +0 -55
- package/storage/jsondbStorage.js +0 -196
- package/utils/co.js +0 -237
- package/utils/copyto.js +0 -161
- package/utils/depd/index.js +0 -538
- package/utils/depd/lib/browser/index.js +0 -77
- package/utils/get-port/index.d.ts +0 -64
- package/utils/time/index.js +0 -20
- package/utils/time/ms.js +0 -162
|
@@ -1,35 +1,27 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const debug = require('debug')('ee-core:core:loader:file_loader');
|
|
3
4
|
const assert = require('assert');
|
|
4
5
|
const fs = require('fs');
|
|
5
|
-
const debug = require('debug')('ee-core:fileLoader');
|
|
6
6
|
const path = require('path');
|
|
7
7
|
const globby = require('globby');
|
|
8
8
|
const is = require('is-type-of');
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const EXPORTS = Symbol('EE_LOADER_ITEM_EXPORTS');
|
|
13
|
-
//const Addon = require('../../../addon');
|
|
9
|
+
const { isBytecodeClass, loadFile, filePatterns } = require('../utils');
|
|
10
|
+
const FULLPATH = Symbol('LOADER_ITEM_FULLPATH');
|
|
11
|
+
const EXPORTS = Symbol('LOADER_ITEM_EXPORTS');
|
|
14
12
|
|
|
15
13
|
const defaults = {
|
|
16
14
|
directory: null,
|
|
17
15
|
target: null,
|
|
18
16
|
match: undefined,
|
|
19
|
-
ignore: undefined,
|
|
20
|
-
lowercaseFirst: false,
|
|
21
17
|
caseStyle: 'camel',
|
|
22
18
|
initializer: null,
|
|
23
19
|
call: true,
|
|
24
|
-
override: false,
|
|
25
20
|
inject: undefined,
|
|
26
|
-
filter: null,
|
|
27
|
-
loader: undefined,
|
|
28
21
|
};
|
|
29
22
|
|
|
30
23
|
/**
|
|
31
24
|
* Load files from directory to target object.
|
|
32
|
-
* @since 1.0.0
|
|
33
25
|
*/
|
|
34
26
|
class FileLoader {
|
|
35
27
|
|
|
@@ -39,46 +31,31 @@ class FileLoader {
|
|
|
39
31
|
* @param {String|Array} options.directory - directories to be loaded
|
|
40
32
|
* @param {Object} options.target - attach the target object from loaded files
|
|
41
33
|
* @param {String} options.match - match the files when load, support glob, default to all js files
|
|
42
|
-
* @param {String} options.ignore - ignore the files when load, support glob
|
|
43
34
|
* @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`
|
|
44
35
|
* @param {Boolean} options.call - determine whether invoke when exports is function
|
|
45
|
-
* @param {Boolean} options.override - determine whether override the property when get the same name
|
|
46
36
|
* @param {Object} options.inject - an object that be the argument when invoke the function
|
|
47
|
-
* @param {Function} options.filter - a function that filter the exports which can be loaded
|
|
48
37
|
* @param {String|Function} options.caseStyle - set property's case when converting a filepath to property list.
|
|
49
|
-
* @param {Object} options.loader - an object that be the argument when invoke the function
|
|
50
38
|
*/
|
|
51
39
|
constructor(options) {
|
|
52
40
|
assert(options.directory, 'options.directory is required');
|
|
53
|
-
assert(options.target, 'options.target is required');
|
|
54
41
|
this.options = Object.assign({}, defaults, options);
|
|
55
|
-
|
|
56
|
-
// compatible old options _lowercaseFirst_
|
|
57
|
-
if (this.options.lowercaseFirst === true) {
|
|
58
|
-
deprecate('lowercaseFirst is deprecated, use caseStyle instead');
|
|
59
|
-
this.options.caseStyle = 'lower';
|
|
60
|
-
}
|
|
42
|
+
debug("[constructor] options: %o", this.options);
|
|
61
43
|
}
|
|
62
44
|
|
|
63
45
|
/**
|
|
64
46
|
* attach items to target object. Mapping the directory to properties.
|
|
65
|
-
* `
|
|
47
|
+
* `xxx/group/repository.js` => `target.group.repository`
|
|
66
48
|
* @return {Object} target
|
|
67
|
-
* @since 1.0.0
|
|
68
49
|
*/
|
|
69
50
|
load() {
|
|
70
51
|
const items = this.parse();
|
|
71
|
-
const target =
|
|
52
|
+
const target = {};
|
|
72
53
|
for (const item of items) {
|
|
73
|
-
// item { properties: [ 'a', 'b', 'c'], exports }
|
|
74
|
-
// => target.a.b.c = exports
|
|
54
|
+
// item { fullpath, properties: [ 'a', 'b', 'c'], exports }
|
|
75
55
|
item.properties.reduce((target, property, index) => {
|
|
76
56
|
let obj;
|
|
77
|
-
|
|
57
|
+
// properties is a path slice, only the last value is the file name
|
|
78
58
|
if (index === item.properties.length - 1) {
|
|
79
|
-
if (property in target) {
|
|
80
|
-
if (!this.options.override) throw new Error(`can't overwrite property '${properties}' from ${target[property][FULLPATH]} by ${item.fullpath}`);
|
|
81
|
-
}
|
|
82
59
|
obj = item.exports;
|
|
83
60
|
if (obj && !is.primitive(obj)) {
|
|
84
61
|
obj[FULLPATH] = item.fullpath;
|
|
@@ -89,166 +66,78 @@ class FileLoader {
|
|
|
89
66
|
}
|
|
90
67
|
|
|
91
68
|
target[property] = obj;
|
|
92
|
-
|
|
69
|
+
// const properties = item.properties.slice(0, index + 1).join('.');
|
|
70
|
+
// debug('[load] properties: %s', properties);
|
|
93
71
|
return obj;
|
|
94
72
|
}, target);
|
|
95
73
|
}
|
|
96
|
-
|
|
74
|
+
//debug('[load] target: %O', target);
|
|
97
75
|
return target;
|
|
98
76
|
}
|
|
99
77
|
|
|
100
78
|
/**
|
|
101
79
|
* Parse files from given directories, then return an items list, each item contains properties and exports.
|
|
102
|
-
*
|
|
103
|
-
* For example, parse `app/controller/group/repository.js`
|
|
104
|
-
*
|
|
105
|
-
* ```
|
|
106
|
-
* module.exports = app => {
|
|
107
|
-
* return class RepositoryController extends app.Controller {};
|
|
108
|
-
* }
|
|
109
|
-
* ```
|
|
110
|
-
*
|
|
80
|
+
* For example, parse `controller/group/repository.js`
|
|
111
81
|
* It returns a item
|
|
112
|
-
*
|
|
113
82
|
* ```
|
|
114
83
|
* {
|
|
84
|
+
* fullpath: '',
|
|
115
85
|
* properties: [ 'group', 'repository' ],
|
|
116
|
-
* exports:
|
|
86
|
+
* exports: { ... },
|
|
117
87
|
* }
|
|
118
88
|
* ```
|
|
119
|
-
*
|
|
120
89
|
* `Properties` is an array that contains the directory of a filepath.
|
|
121
|
-
*
|
|
122
90
|
* `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.
|
|
123
91
|
* @return {Array} items
|
|
124
|
-
* @since 1.0.0
|
|
125
92
|
*/
|
|
126
93
|
parse() {
|
|
127
94
|
let files = this.options.match;
|
|
128
95
|
if (!files) {
|
|
129
|
-
files = (
|
|
130
|
-
? [ '**/*.(js|ts)', '!**/*.d.ts' ]
|
|
131
|
-
: [ '**/*.js', '**/*.jsc'];
|
|
96
|
+
files = filePatterns();
|
|
132
97
|
} else {
|
|
133
98
|
files = Array.isArray(files) ? files : [ files ];
|
|
134
99
|
}
|
|
135
|
-
|
|
136
|
-
let ignore = this.options.ignore;
|
|
137
|
-
if (ignore) {
|
|
138
|
-
ignore = Array.isArray(ignore) ? ignore : [ ignore ];
|
|
139
|
-
ignore = ignore.filter(f => !!f).map(f => '!' + f);
|
|
140
|
-
files = files.concat(ignore);
|
|
141
|
-
}
|
|
142
100
|
|
|
143
101
|
let directories = this.options.directory;
|
|
144
102
|
if (!Array.isArray(directories)) {
|
|
145
103
|
directories = [ directories ];
|
|
146
104
|
}
|
|
147
105
|
|
|
148
|
-
const filter = is.function(this.options.filter) ? this.options.filter : null;
|
|
149
106
|
const items = [];
|
|
150
|
-
debug('
|
|
151
|
-
|
|
107
|
+
debug('[parse] directories %o', directories);
|
|
108
|
+
|
|
152
109
|
for (const directory of directories) {
|
|
153
110
|
const filepaths = globby.sync(files, { cwd: directory });
|
|
111
|
+
debug('[parse] filepaths %o', filepaths);
|
|
154
112
|
for (const filepath of filepaths) {
|
|
155
113
|
const fullpath = path.join(directory, filepath);
|
|
156
114
|
if (!fs.statSync(fullpath).isFile()) continue;
|
|
157
115
|
// get properties
|
|
158
|
-
//
|
|
116
|
+
// controller/foo/bar.js => [ 'foo', 'bar' ]
|
|
159
117
|
const properties = getProperties(filepath, this.options);
|
|
160
|
-
//
|
|
118
|
+
// debug('[parse] properties %o', properties);
|
|
119
|
+
// controller/foo/bar.js => controller.foo.bar
|
|
161
120
|
const pathName = directory.split(/[/\\]/).slice(-1) + '.' + properties.join('.');
|
|
121
|
+
// debug('[parse] pathName %s', pathName);
|
|
162
122
|
// get exports from the file
|
|
163
123
|
let exports = getExports(fullpath, this.options, pathName);
|
|
164
124
|
// ignore exports when it's null or false returned by filter function
|
|
165
|
-
if (exports == null
|
|
125
|
+
if (exports == null) continue;
|
|
166
126
|
|
|
167
127
|
// set properties of class
|
|
168
|
-
if (is.class(exports) ||
|
|
128
|
+
if (is.class(exports) || isBytecodeClass(exports)) {
|
|
169
129
|
exports.prototype.pathName = pathName;
|
|
170
130
|
exports.prototype.fullPath = fullpath;
|
|
171
131
|
}
|
|
172
|
-
|
|
173
132
|
items.push({ fullpath, properties, exports });
|
|
174
|
-
debug('parse %s, properties %
|
|
133
|
+
//debug('[parse] fullpath %s, properties %o, export %o', fullpath, properties, exports);
|
|
175
134
|
}
|
|
176
135
|
}
|
|
177
|
-
|
|
136
|
+
//debug('[parse] items %O', items);
|
|
178
137
|
return items;
|
|
179
138
|
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* attach items to target object for addons.
|
|
183
|
-
* `app/addon/group/index.js` => `target.group`
|
|
184
|
-
* @return {Object} target
|
|
185
|
-
* @since 1.0.0
|
|
186
|
-
*/
|
|
187
|
-
loadAddons() {
|
|
188
|
-
const items = [];
|
|
189
|
-
const files = '*';
|
|
190
|
-
const app = this.options.inject;
|
|
191
|
-
const loader = this.options.loader;
|
|
192
|
-
const target = this.options.target;
|
|
193
|
-
let directories = this.options.directory;
|
|
194
|
-
|
|
195
|
-
if (!Array.isArray(directories)) {
|
|
196
|
-
directories = [ directories ];
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// check addon
|
|
200
|
-
const config = app.config.addons;
|
|
201
|
-
let filterAddons = [];
|
|
202
|
-
for (let key of Object.keys(config)) {
|
|
203
|
-
if (!config[key].enable) {
|
|
204
|
-
filterAddons.push(key);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
for (const directory of directories) {
|
|
209
|
-
const addonpaths = globby.sync(files, { cwd: directory, deep: 1, onlyDirectories: true});
|
|
210
|
-
for (const addonName of addonpaths) {
|
|
211
|
-
if (filterAddons.includes(addonName)) continue;
|
|
212
|
-
|
|
213
|
-
const filepath = path.join(directory, addonName, 'index');
|
|
214
|
-
const fullpath = loader.resolveModule(filepath);
|
|
215
|
-
if (!fs.existsSync(fullpath)) {
|
|
216
|
-
throw new Error(`The ${filepath} file does not exist`);
|
|
217
|
-
}
|
|
218
|
-
if (!fs.statSync(fullpath).isFile()) continue;
|
|
219
|
-
|
|
220
|
-
let exports = getExports(fullpath, this.options, addonName);
|
|
221
|
-
if (exports == null) continue;
|
|
222
|
-
|
|
223
|
-
const properties = [addonName];
|
|
224
|
-
if (is.class(exports) || Utils.isBytecodeClass(exports)) {
|
|
225
|
-
exports.prototype.pathName = addonName;
|
|
226
|
-
exports.prototype.fullPath = fullpath;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
items.push({ fullpath, properties, exports });
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
for (const item of items) {
|
|
233
|
-
const property = item.properties[0];
|
|
234
|
-
let obj = item.exports;
|
|
235
|
-
if (obj && !is.primitive(obj)) {
|
|
236
|
-
obj[FULLPATH] = item.fullpath;
|
|
237
|
-
obj[EXPORTS] = true;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
target[property] = obj;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
return target;
|
|
245
|
-
}
|
|
246
139
|
}
|
|
247
140
|
|
|
248
|
-
module.exports = FileLoader;
|
|
249
|
-
module.exports.EXPORTS = EXPORTS;
|
|
250
|
-
module.exports.FULLPATH = FULLPATH;
|
|
251
|
-
|
|
252
141
|
// convert file path to an array of properties
|
|
253
142
|
// a/b/c.js => ['a', 'b', 'c']
|
|
254
143
|
function getProperties(filepath, { caseStyle }) {
|
|
@@ -265,29 +154,18 @@ function getProperties(filepath, { caseStyle }) {
|
|
|
265
154
|
// Get exports from filepath
|
|
266
155
|
// If exports is null/undefined, it will be ignored
|
|
267
156
|
function getExports(fullpath, { initializer, call, inject }, pathName) {
|
|
268
|
-
let exports =
|
|
269
|
-
|
|
270
|
-
// process exports as you like
|
|
157
|
+
let exports = loadFile(fullpath);
|
|
158
|
+
//debug('[getExports] exports %o', exports);
|
|
271
159
|
if (initializer) {
|
|
160
|
+
// exports type is Class or Object
|
|
272
161
|
exports = initializer(exports, { path: fullpath, pathName });
|
|
273
162
|
}
|
|
274
163
|
|
|
275
|
-
|
|
276
|
-
//
|
|
277
|
-
// module.exports = class Service {};
|
|
278
|
-
// or
|
|
279
|
-
// module.exports = function*() {}
|
|
280
|
-
//new exports;
|
|
281
|
-
|
|
282
|
-
if (is.class(exports) || is.generatorFunction(exports) || is.asyncFunction(exports) || Utils.isBytecodeClass(exports)) {
|
|
164
|
+
if (is.class(exports) || is.generatorFunction(exports) || is.asyncFunction(exports) || isBytecodeClass(exports)) {
|
|
283
165
|
return exports;
|
|
284
166
|
}
|
|
285
167
|
|
|
286
|
-
//
|
|
287
|
-
//
|
|
288
|
-
// module.exports = function(app) {
|
|
289
|
-
// return {};
|
|
290
|
-
// }
|
|
168
|
+
// whether to execute the function
|
|
291
169
|
if (call && is.function(exports)) {
|
|
292
170
|
exports = exports(inject);
|
|
293
171
|
if (exports != null) {
|
|
@@ -295,7 +173,6 @@ function getExports(fullpath, { initializer, call, inject }, pathName) {
|
|
|
295
173
|
}
|
|
296
174
|
}
|
|
297
175
|
|
|
298
|
-
// return exports what is
|
|
299
176
|
return exports;
|
|
300
177
|
}
|
|
301
178
|
|
|
@@ -311,7 +188,7 @@ function defaultCamelize(filepath, caseStyle) {
|
|
|
311
188
|
// fooBar.js > FooBar
|
|
312
189
|
// FooBar.js > FooBar
|
|
313
190
|
// FooBar.js > FooBar
|
|
314
|
-
// FooBar.js > fooBar
|
|
191
|
+
// FooBar.js > fooBar
|
|
315
192
|
property = property.replace(/[_-][a-z]/ig, s => s.substring(1).toUpperCase());
|
|
316
193
|
let first = property[0];
|
|
317
194
|
switch (caseStyle) {
|
|
@@ -327,3 +204,9 @@ function defaultCamelize(filepath, caseStyle) {
|
|
|
327
204
|
return first + property.substring(1);
|
|
328
205
|
});
|
|
329
206
|
}
|
|
207
|
+
|
|
208
|
+
module.exports = {
|
|
209
|
+
FileLoader,
|
|
210
|
+
EXPORTS,
|
|
211
|
+
FULLPATH,
|
|
212
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('bytenode');
|
|
4
|
+
const is = require('is-type-of');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const BuiltinModule = require('module');
|
|
8
|
+
|
|
9
|
+
// Guard against poorly mocked module constructors.
|
|
10
|
+
const Module = module.constructor.length > 1
|
|
11
|
+
? module.constructor
|
|
12
|
+
/* istanbul ignore next */
|
|
13
|
+
: BuiltinModule;
|
|
14
|
+
|
|
15
|
+
// Module._extensions:
|
|
16
|
+
// '.js': [Function (anonymous)],
|
|
17
|
+
// '.json': [Function (anonymous)],
|
|
18
|
+
// '.node': [Function: func],
|
|
19
|
+
// '.jsc': [Function (anonymous)]
|
|
20
|
+
|
|
21
|
+
const extensions = Module._extensions;
|
|
22
|
+
|
|
23
|
+
function loadFile(filepath) {
|
|
24
|
+
try {
|
|
25
|
+
// if not js module, just return content buffer
|
|
26
|
+
const extname = path.extname(filepath);
|
|
27
|
+
if (extname && !Module._extensions[extname]) {
|
|
28
|
+
return fs.readFileSync(filepath);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// require js module
|
|
32
|
+
const obj = require(filepath);
|
|
33
|
+
if (!obj) return obj;
|
|
34
|
+
// it's es module
|
|
35
|
+
if (obj.__esModule) return 'default' in obj ? obj.default : obj;
|
|
36
|
+
return obj;
|
|
37
|
+
} catch (err) {
|
|
38
|
+
err.message = `[ee-core] load file: ${filepath}, error: ${err.message}`;
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function callFn(fn, args, ctx) {
|
|
44
|
+
args = args || [];
|
|
45
|
+
if (!is.function(fn)) return;
|
|
46
|
+
return ctx ? fn.call(ctx, ...args) : fn(...args);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getResolvedFilename(filepath, baseDir) {
|
|
50
|
+
const reg = /[/\\]/g;
|
|
51
|
+
return filepath.replace(baseDir + path.sep, '').replace(reg, '/');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 字节码类
|
|
56
|
+
*/
|
|
57
|
+
function isBytecodeClass(exports) {
|
|
58
|
+
let isClass = false;
|
|
59
|
+
|
|
60
|
+
// 标识
|
|
61
|
+
if (exports.toString().indexOf('[class') != -1) {
|
|
62
|
+
isClass = true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return isClass;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 文件类型
|
|
70
|
+
*/
|
|
71
|
+
function filePatterns() {
|
|
72
|
+
const files = [ '**/*.js','**/*.jsc' ];
|
|
73
|
+
return files;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = {
|
|
77
|
+
extensions,
|
|
78
|
+
loadFile,
|
|
79
|
+
callFn,
|
|
80
|
+
getResolvedFilename,
|
|
81
|
+
isBytecodeClass,
|
|
82
|
+
filePatterns,
|
|
83
|
+
};
|
|
@@ -4,7 +4,6 @@ const assert = require('assert');
|
|
|
4
4
|
const MAP = Symbol('Timing#map');
|
|
5
5
|
const LIST = Symbol('Timing#list');
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
class Timing {
|
|
9
8
|
|
|
10
9
|
constructor() {
|
|
@@ -74,4 +73,6 @@ class Timing {
|
|
|
74
73
|
}
|
|
75
74
|
}
|
|
76
75
|
|
|
77
|
-
module.exports =
|
|
76
|
+
module.exports = {
|
|
77
|
+
Timing
|
|
78
|
+
};
|
package/cross/cross.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const EventEmitter = require('events');
|
|
4
|
+
const { getConfig } = require('../config');
|
|
5
|
+
const { sleep, getValueFromArgv, replaceArgsValue } = require('../utils/helper');
|
|
6
|
+
const { SpawnProcess } = require('./spawnProcess');
|
|
7
|
+
const { Events } = require('../const/channel');
|
|
8
|
+
const { extend } = require('../utils/extend');
|
|
9
|
+
const { getPort } = require('../utils/port');
|
|
10
|
+
|
|
11
|
+
class CrossProcess {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.emitter = undefined;
|
|
14
|
+
|
|
15
|
+
// pid唯一
|
|
16
|
+
// {pid:{name,entity}, pid:{name,entity}, ...}
|
|
17
|
+
this.children = {};
|
|
18
|
+
|
|
19
|
+
// name唯一
|
|
20
|
+
// {name:pid, name:pid, ...}
|
|
21
|
+
this.childrenMap = {};
|
|
22
|
+
|
|
23
|
+
// eventEmitter
|
|
24
|
+
this._initEventEmitter();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async create() {
|
|
28
|
+
|
|
29
|
+
// boot services
|
|
30
|
+
const crossCfg = getConfig().cross;
|
|
31
|
+
//await sleep(5 * 1000);
|
|
32
|
+
|
|
33
|
+
for (let key of Object.keys(crossCfg)) {
|
|
34
|
+
let val = crossCfg[key];
|
|
35
|
+
if (val.enable == true) {
|
|
36
|
+
this.run(key)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// run
|
|
42
|
+
async run(service, opt = {}) {
|
|
43
|
+
const crossConf = getConfig().cross;
|
|
44
|
+
const defaultOpt = crossConf[service] || {};
|
|
45
|
+
const targetConf = extend(true, {}, defaultOpt, opt);
|
|
46
|
+
if (Object.keys(targetConf).length == 0) {
|
|
47
|
+
throw new Error(`[ee-core] [cross] The service [${service}] config does not exit`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// format params
|
|
51
|
+
let tmpArgs = targetConf.args;
|
|
52
|
+
let confPort = parseInt(getValueFromArgv(tmpArgs, 'port'));
|
|
53
|
+
// 某些程序给它传入不存在的参数时会报错
|
|
54
|
+
if (isNaN(confPort) && targetConf.port > 0) {
|
|
55
|
+
confPort = targetConf.port;
|
|
56
|
+
}
|
|
57
|
+
if (confPort > 0) {
|
|
58
|
+
// 动态生成port,传入的端口必须为int
|
|
59
|
+
confPort = await getPort({ port: confPort });
|
|
60
|
+
// 替换port
|
|
61
|
+
targetConf.args = replaceArgsValue(tmpArgs, "port", String(confPort));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 创建进程
|
|
65
|
+
const subProcess = new SpawnProcess(this, { targetConf, port: confPort });
|
|
66
|
+
let uniqueName = targetConf.name;
|
|
67
|
+
if (this.childrenMap.hasOwnProperty(uniqueName)) {
|
|
68
|
+
uniqueName = uniqueName + "-" + String(subProcess.pid);
|
|
69
|
+
}
|
|
70
|
+
this.childrenMap[uniqueName] = subProcess.pid;
|
|
71
|
+
subProcess.name = uniqueName;
|
|
72
|
+
this.children[subProcess.pid] = {
|
|
73
|
+
name: uniqueName,
|
|
74
|
+
entity: subProcess
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
return subProcess;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
killAll() {
|
|
81
|
+
Object.keys(this.children).forEach(pid => {
|
|
82
|
+
this.kill(pid)
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
kill(pid) {
|
|
87
|
+
const entity = this.getProc(pid);
|
|
88
|
+
if (entity) {
|
|
89
|
+
entity.kill();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
killByName(name) {
|
|
94
|
+
const entity = this.getProcByName(name);
|
|
95
|
+
if (entity) {
|
|
96
|
+
entity.kill();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
getUrl(name) {
|
|
101
|
+
const entity = this.getProcByName(name);
|
|
102
|
+
const url = entity.getUrl();
|
|
103
|
+
|
|
104
|
+
return url;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 获取 proc
|
|
108
|
+
getProcByName(name) {
|
|
109
|
+
const pid = this.childrenMap[name];
|
|
110
|
+
if (!pid) {
|
|
111
|
+
throw new Error(`[ee-core] [cross] The process named [${name}] does not exit`);
|
|
112
|
+
}
|
|
113
|
+
const entity = this.getProc(pid);
|
|
114
|
+
|
|
115
|
+
return entity;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 获取 proc
|
|
119
|
+
getProc(pid) {
|
|
120
|
+
const child = this.children[pid];
|
|
121
|
+
if (!pid) {
|
|
122
|
+
throw new Error(`[ee-core] [cross] The process pid [${pid}] does not exit`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return child.entity;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 获取pids
|
|
129
|
+
getPids() {
|
|
130
|
+
let pids = Object.keys(this.children);
|
|
131
|
+
return pids;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
_initEventEmitter() {
|
|
135
|
+
this.emitter = new EventEmitter();
|
|
136
|
+
this.emitter.on(Events.childProcessExit, (data) => {
|
|
137
|
+
const child = this.children[data.pid];
|
|
138
|
+
delete this.childrenMap[child.name];
|
|
139
|
+
delete this.children[data.pid];
|
|
140
|
+
});
|
|
141
|
+
this.emitter.on(Events.childProcessError, (data) => {
|
|
142
|
+
const child = this.children[data.pid];
|
|
143
|
+
delete this.childrenMap[child.name];
|
|
144
|
+
delete this.children[data.pid];
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
module.exports = {
|
|
150
|
+
CrossProcess,
|
|
151
|
+
cross: new CrossProcess()
|
|
152
|
+
};
|