@midwayjs/core 4.0.0-alpha.1 → 4.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/baseFramework.d.ts +13 -10
- package/dist/baseFramework.js +30 -15
- package/dist/common/applicationManager.js +6 -4
- package/dist/common/asyncContextManager.js +23 -0
- package/dist/common/dataListener.d.ts +5 -3
- package/dist/common/dataListener.js +11 -3
- package/dist/common/dataSourceManager.d.ts +18 -9
- package/dist/common/dataSourceManager.js +129 -77
- package/dist/common/fileDetector.js +2 -4
- package/dist/common/filterManager.js +6 -8
- package/dist/common/loggerFactory.js +1 -3
- package/dist/common/middlewareManager.js +2 -2
- package/dist/common/performanceManager.d.ts +0 -1
- package/dist/common/performanceManager.js +21 -20
- package/dist/common/priorityManager.js +2 -4
- package/dist/common/serviceDiscovery/healthCheck.d.ts +66 -0
- package/dist/common/serviceDiscovery/healthCheck.js +215 -0
- package/dist/common/serviceDiscovery/loadBalancer.d.ts +21 -0
- package/dist/common/serviceDiscovery/loadBalancer.js +49 -0
- package/dist/common/serviceDiscovery/serviceDiscovery.d.ts +59 -0
- package/dist/common/serviceDiscovery/serviceDiscovery.js +107 -0
- package/dist/common/serviceFactory.d.ts +5 -2
- package/dist/common/serviceFactory.js +47 -12
- package/dist/common/typedResourceManager.js +3 -2
- package/dist/common/webGenerator.js +2 -0
- package/dist/config/config.default.js +4 -1
- package/dist/context/componentLoader.js +3 -2
- package/dist/context/container.d.ts +4 -4
- package/dist/context/container.js +15 -10
- package/dist/context/definitionRegistry.d.ts +2 -0
- package/dist/context/definitionRegistry.js +11 -16
- package/dist/context/dynamicContainer.d.ts +17 -0
- package/dist/context/dynamicContainer.js +203 -0
- package/dist/context/managedResolverFactory.d.ts +1 -2
- package/dist/context/managedResolverFactory.js +16 -8
- package/dist/context/providerWrapper.js +1 -2
- package/dist/context/requestContainer.d.ts +1 -0
- package/dist/context/requestContainer.js +8 -2
- package/dist/decorator/common/aspect.js +1 -2
- package/dist/decorator/common/autoload.js +1 -2
- package/dist/decorator/common/configuration.js +1 -2
- package/dist/decorator/common/filter.js +2 -3
- package/dist/decorator/common/framework.js +8 -9
- package/dist/decorator/common/guard.js +2 -3
- package/dist/decorator/common/inject.js +4 -5
- package/dist/decorator/common/middleware.js +1 -2
- package/dist/decorator/common/mock.js +1 -2
- package/dist/decorator/common/objectDef.js +2 -3
- package/dist/decorator/common/pipe.js +1 -2
- package/dist/decorator/common/provide.js +1 -2
- package/dist/decorator/common/scope.js +2 -3
- package/dist/decorator/decoratorManager.js +4 -4
- package/dist/decorator/faas/serverlessTrigger.js +2 -3
- package/dist/decorator/metadataManager.d.ts +14 -6
- package/dist/decorator/metadataManager.js +49 -63
- package/dist/decorator/microservice/consumer.js +1 -2
- package/dist/decorator/microservice/kafkaListener.js +1 -2
- package/dist/decorator/microservice/provider.js +4 -4
- package/dist/decorator/microservice/rabbitmqListener.js +1 -2
- package/dist/decorator/task/queue.js +1 -2
- package/dist/decorator/task/schedule.js +1 -2
- package/dist/decorator/task/task.js +1 -2
- package/dist/decorator/task/taskLocal.js +1 -2
- package/dist/decorator/web/controller.d.ts +6 -0
- package/dist/decorator/web/controller.js +1 -2
- package/dist/decorator/web/response.js +5 -6
- package/dist/decorator/ws/webSocketController.js +1 -2
- package/dist/decorator/ws/webSocketEvent.js +6 -6
- package/dist/definitions/functionDefinition.js +21 -12
- package/dist/definitions/objectCreator.js +5 -2
- package/dist/definitions/objectDefinition.js +19 -17
- package/dist/error/base.js +5 -2
- package/dist/error/framework.d.ts +1 -1
- package/dist/error/framework.js +4 -2
- package/dist/error/http.d.ts +7 -0
- package/dist/error/http.js +11 -1
- package/dist/functional/configuration.d.ts +6 -6
- package/dist/functional/configuration.js +11 -10
- package/dist/functional/hooks.d.ts +3 -1
- package/dist/functional/hooks.js +18 -9
- package/dist/index.d.ts +5 -1
- package/dist/index.js +8 -2
- package/dist/interface.d.ts +179 -21
- package/dist/interface.js +15 -1
- package/dist/legacy/decorator.js +31 -32
- package/dist/response/base.d.ts +3 -5
- package/dist/response/base.js +22 -21
- package/dist/response/http.d.ts +4 -7
- package/dist/response/http.js +12 -12
- package/dist/response/sse.d.ts +0 -1
- package/dist/response/sse.js +4 -1
- package/dist/response/stream.d.ts +0 -1
- package/dist/response/stream.js +3 -1
- package/dist/service/aspectService.js +1 -0
- package/dist/service/configService.d.ts +1 -1
- package/dist/service/configService.js +16 -14
- package/dist/service/decoratorService.js +6 -4
- package/dist/service/environmentService.js +2 -3
- package/dist/service/frameworkService.js +9 -1
- package/dist/service/healthService.d.ts +2 -0
- package/dist/service/healthService.js +20 -8
- package/dist/service/informationService.d.ts +3 -0
- package/dist/service/informationService.js +13 -0
- package/dist/service/lifeCycleService.d.ts +13 -7
- package/dist/service/lifeCycleService.js +55 -33
- package/dist/service/loggerService.js +6 -2
- package/dist/service/middlewareService.js +1 -0
- package/dist/service/mockService.js +17 -15
- package/dist/service/slsFunctionService.js +1 -0
- package/dist/service/webRouterService.d.ts +25 -1
- package/dist/service/webRouterService.js +20 -3
- package/dist/setup.js +12 -6
- package/dist/util/camelCase.js +2 -3
- package/dist/util/contextUtil.d.ts +3 -3
- package/dist/util/extend.js +1 -2
- package/dist/util/flatted.js +2 -3
- package/dist/util/fs.js +2 -2
- package/dist/util/httpclient.d.ts +0 -4
- package/dist/util/httpclient.js +3 -2
- package/dist/util/index.d.ts +3 -18
- package/dist/util/index.js +49 -103
- package/dist/util/network.d.ts +10 -0
- package/dist/util/network.js +40 -0
- package/dist/util/pathFileUtil.d.ts +1 -2
- package/dist/util/pathFileUtil.js +7 -7
- package/dist/util/retry.js +2 -3
- package/dist/util/timeout.d.ts +56 -0
- package/dist/util/timeout.js +143 -0
- package/dist/util/types.d.ts +7 -7
- package/dist/util/types.js +17 -17
- package/dist/util/uuid.js +1 -2
- package/package.json +5 -5
|
@@ -13,15 +13,18 @@ exports.ServiceFactory = void 0;
|
|
|
13
13
|
const extend_1 = require("../util/extend");
|
|
14
14
|
const priorityManager_1 = require("./priorityManager");
|
|
15
15
|
const decorator_1 = require("../decorator");
|
|
16
|
+
const types_1 = require("../util/types");
|
|
16
17
|
/**
|
|
17
18
|
* 多客户端工厂实现
|
|
18
19
|
*/
|
|
19
20
|
class ServiceFactory {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
clients = new Map();
|
|
22
|
+
clientPriority;
|
|
23
|
+
options = {};
|
|
24
|
+
priorityManager;
|
|
25
|
+
// for multi client with initialization
|
|
26
|
+
creatingClients = new Map();
|
|
27
|
+
async initClients(options = {}, initOptions = {}) {
|
|
25
28
|
this.options = options;
|
|
26
29
|
// merge options.client to options.clients['default']
|
|
27
30
|
if (options.client) {
|
|
@@ -29,10 +32,17 @@ class ServiceFactory {
|
|
|
29
32
|
options.clients['default'] = options.clients['default'] || {};
|
|
30
33
|
(0, extend_1.extend)(true, options.clients['default'], options.client);
|
|
31
34
|
}
|
|
32
|
-
// multi client
|
|
33
35
|
if (options.clients) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
const entries = Object.entries(options.clients);
|
|
37
|
+
if (initOptions.concurrent) {
|
|
38
|
+
// multi client with concurrent initialization
|
|
39
|
+
await Promise.all(entries.map(([id, config]) => this.createInstance(config, id)));
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// multi client with serial initialization
|
|
43
|
+
for (const [id, config] of entries) {
|
|
44
|
+
await this.createInstance(config, id);
|
|
45
|
+
}
|
|
36
46
|
}
|
|
37
47
|
}
|
|
38
48
|
// set priority
|
|
@@ -45,21 +55,46 @@ class ServiceFactory {
|
|
|
45
55
|
return this.clients.has(id);
|
|
46
56
|
}
|
|
47
57
|
async createInstance(config, clientName) {
|
|
58
|
+
if (clientName) {
|
|
59
|
+
if (this.has(clientName)) {
|
|
60
|
+
return this.get(clientName);
|
|
61
|
+
}
|
|
62
|
+
if (this.creatingClients.has(clientName)) {
|
|
63
|
+
return this.creatingClients.get(clientName);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
48
66
|
// options.default will be merge in to options.clients[id]
|
|
49
67
|
config = (0, extend_1.extend)(true, {}, this.options['default'], config);
|
|
50
|
-
const
|
|
51
|
-
if (
|
|
68
|
+
const clientCreatingPromise = this.createClient(config, clientName);
|
|
69
|
+
if (clientCreatingPromise && types_1.Types.isPromise(clientCreatingPromise)) {
|
|
52
70
|
if (clientName) {
|
|
53
|
-
this.
|
|
71
|
+
this.creatingClients.set(clientName, clientCreatingPromise);
|
|
54
72
|
}
|
|
55
|
-
return
|
|
73
|
+
return clientCreatingPromise
|
|
74
|
+
.then(client => {
|
|
75
|
+
if (clientName) {
|
|
76
|
+
this.clients.set(clientName, client);
|
|
77
|
+
}
|
|
78
|
+
return client;
|
|
79
|
+
})
|
|
80
|
+
.finally(() => {
|
|
81
|
+
if (clientName) {
|
|
82
|
+
this.creatingClients.delete(clientName);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// 处理同步返回的情况
|
|
87
|
+
if (clientName) {
|
|
88
|
+
this.clients.set(clientName, clientCreatingPromise);
|
|
56
89
|
}
|
|
90
|
+
return clientCreatingPromise;
|
|
57
91
|
}
|
|
58
92
|
async destroyClient(client, clientName) { }
|
|
59
93
|
async stop() {
|
|
60
94
|
for (const [name, value] of this.clients.entries()) {
|
|
61
95
|
await this.destroyClient(value, name);
|
|
62
96
|
}
|
|
97
|
+
this.clients.clear();
|
|
63
98
|
}
|
|
64
99
|
getDefaultClientName() {
|
|
65
100
|
return this.options['defaultClientName'];
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TypedResourceManager = void 0;
|
|
4
4
|
class TypedResourceManager {
|
|
5
|
+
typedResourceInitializerOptions;
|
|
6
|
+
resourceMap = new Map();
|
|
7
|
+
resourceBindingMap = new Map();
|
|
5
8
|
constructor(typedResourceInitializerOptions) {
|
|
6
9
|
this.typedResourceInitializerOptions = typedResourceInitializerOptions;
|
|
7
|
-
this.resourceMap = new Map();
|
|
8
|
-
this.resourceBindingMap = new Map();
|
|
9
10
|
}
|
|
10
11
|
async createResource(resourceName, resourceInitializeConfig) {
|
|
11
12
|
const resource = await this.typedResourceInitializerOptions.resourceInitialize(resourceInitializeConfig, resourceName);
|
|
@@ -13,6 +13,8 @@ const error_1 = require("../error");
|
|
|
13
13
|
const middlewareService_1 = require("../service/middlewareService");
|
|
14
14
|
const debug = util.debuglog('midway:debug');
|
|
15
15
|
class WebControllerGenerator {
|
|
16
|
+
app;
|
|
17
|
+
midwayWebRouterService;
|
|
16
18
|
constructor(app, midwayWebRouterService) {
|
|
17
19
|
this.app = app;
|
|
18
20
|
this.midwayWebRouterService = midwayWebRouterService;
|
|
@@ -5,7 +5,10 @@ exports.default = (appInfo) => {
|
|
|
5
5
|
const isDevelopment = (0, util_1.isDevelopmentEnvironment)((0, util_1.getCurrentEnvironment)());
|
|
6
6
|
return {
|
|
7
7
|
core: {
|
|
8
|
-
healthCheckTimeout:
|
|
8
|
+
healthCheckTimeout: 1_000,
|
|
9
|
+
configLoadTimeout: 10_000,
|
|
10
|
+
readyTimeout: 30_000,
|
|
11
|
+
serverReadyTimeout: 30_000,
|
|
9
12
|
},
|
|
10
13
|
asyncContextManager: {
|
|
11
14
|
enable: true,
|
|
@@ -9,10 +9,11 @@ const util = require("util");
|
|
|
9
9
|
const util_1 = require("../util");
|
|
10
10
|
const debug = util.debuglog('midway:debug');
|
|
11
11
|
class ComponentConfigurationLoader {
|
|
12
|
+
container;
|
|
13
|
+
loadedMap = new WeakMap();
|
|
14
|
+
namespaceList = [];
|
|
12
15
|
constructor(container) {
|
|
13
16
|
this.container = container;
|
|
14
|
-
this.loadedMap = new WeakMap();
|
|
15
|
-
this.namespaceList = [];
|
|
16
17
|
}
|
|
17
18
|
async load(module) {
|
|
18
19
|
let namespace = decorator_1.MAIN_MODULE_KEY;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
import { ClassType, IIdentifierRelationShip, IMidwayContainer, IMidwayGlobalContainer, IObjectDefinition, IObjectDefinitionRegistry, ObjectIdentifier, ScopeEnum } from '../interface';
|
|
3
2
|
import { ManagedResolverFactory } from './managedResolverFactory';
|
|
4
3
|
import { EventEmitter } from 'events';
|
|
@@ -21,9 +20,9 @@ export declare class MidwayContainer implements IMidwayGlobalContainer {
|
|
|
21
20
|
get identifierMapping(): IIdentifierRelationShip;
|
|
22
21
|
addNamespace(ns: string): void;
|
|
23
22
|
bindClass(exports: any, options?: Partial<IObjectDefinition>): void;
|
|
24
|
-
bind<T>(target: T, options?: Partial<IObjectDefinition>):
|
|
25
|
-
bind<T>(identifier: ObjectIdentifier, target: T, options?: Partial<IObjectDefinition>):
|
|
26
|
-
protected bindModule(module: any, options: Partial<IObjectDefinition>):
|
|
23
|
+
bind<T>(target: T, options?: Partial<IObjectDefinition>): IObjectDefinition | undefined;
|
|
24
|
+
bind<T>(identifier: ObjectIdentifier, target: T, options?: Partial<IObjectDefinition>): IObjectDefinition | undefined;
|
|
25
|
+
protected bindModule(module: any, options: Partial<IObjectDefinition>): IObjectDefinition | undefined;
|
|
27
26
|
setAttr(key: string, value: any): void;
|
|
28
27
|
getAttr<T>(key: string): T;
|
|
29
28
|
getIdentifier(identifier: ClassType | string): string;
|
|
@@ -37,6 +36,7 @@ export declare class MidwayContainer implements IMidwayGlobalContainer {
|
|
|
37
36
|
* @param target
|
|
38
37
|
*/
|
|
39
38
|
registerObject(identifier: ObjectIdentifier, target: any): void;
|
|
39
|
+
removeObject(identifier: ObjectIdentifier): void;
|
|
40
40
|
onBeforeBind(fn: (Clzz: any, options: {
|
|
41
41
|
context: IMidwayContainer;
|
|
42
42
|
definition: IObjectDefinition;
|
|
@@ -17,18 +17,19 @@ const debug = util.debuglog('midway:debug');
|
|
|
17
17
|
const debugBind = util.debuglog('midway:bind');
|
|
18
18
|
const debugSpaceLength = 9;
|
|
19
19
|
class MidwayContainer {
|
|
20
|
+
_resolverFactory = null;
|
|
21
|
+
_registry = null;
|
|
22
|
+
_identifierMapping = null;
|
|
23
|
+
_objectCreateEventTarget;
|
|
24
|
+
// 仅仅用于兼容 requestContainer 的 ctx
|
|
25
|
+
ctx = constants_1.SINGLETON_CONTAINER_CTX;
|
|
26
|
+
attrMap = new Map();
|
|
27
|
+
namespaceSet = new Set();
|
|
28
|
+
_id = util_1.Utils.generateRandomId();
|
|
20
29
|
get id() {
|
|
21
30
|
return this._id;
|
|
22
31
|
}
|
|
23
32
|
constructor() {
|
|
24
|
-
this._resolverFactory = null;
|
|
25
|
-
this._registry = null;
|
|
26
|
-
this._identifierMapping = null;
|
|
27
|
-
// 仅仅用于兼容 requestContainer 的 ctx
|
|
28
|
-
this.ctx = constants_1.SINGLETON_CONTAINER_CTX;
|
|
29
|
-
this.attrMap = new Map();
|
|
30
|
-
this.namespaceSet = new Set();
|
|
31
|
-
this._id = util_1.Utils.generateRandomId();
|
|
32
33
|
// 防止直接从applicationContext.getAsync or get对象实例时依赖当前上下文信息出错
|
|
33
34
|
// ctx is in requestContainer
|
|
34
35
|
this.registerObject(constants_1.REQUEST_CTX_KEY, this.ctx);
|
|
@@ -162,13 +163,14 @@ class MidwayContainer {
|
|
|
162
163
|
if (definition) {
|
|
163
164
|
this.registry.registerDefinition(definition.id, definition);
|
|
164
165
|
}
|
|
166
|
+
return definition;
|
|
165
167
|
}
|
|
166
168
|
bindModule(module, options) {
|
|
167
169
|
if (types_1.Types.isClass(module)) {
|
|
168
170
|
const providerId = decorator_1.DecoratorManager.getProviderUUId(module);
|
|
169
171
|
if (providerId) {
|
|
170
172
|
this.identifierMapping.saveClassRelation(module, options?.namespace);
|
|
171
|
-
this.bind(providerId, module, options);
|
|
173
|
+
return this.bind(providerId, module, options);
|
|
172
174
|
}
|
|
173
175
|
else {
|
|
174
176
|
// no provide or js class must be skip
|
|
@@ -182,7 +184,7 @@ class MidwayContainer {
|
|
|
182
184
|
}
|
|
183
185
|
const uuid = util_1.Utils.generateRandomId();
|
|
184
186
|
this.identifierMapping.saveFunctionRelation(info.id, uuid);
|
|
185
|
-
this.bind(uuid, module, {
|
|
187
|
+
return this.bind(uuid, module, {
|
|
186
188
|
scope: info.scope,
|
|
187
189
|
namespace: options.namespace,
|
|
188
190
|
srcPath: options.srcPath,
|
|
@@ -231,6 +233,9 @@ class MidwayContainer {
|
|
|
231
233
|
registerObject(identifier, target) {
|
|
232
234
|
this.registry.registerObject(identifier, target);
|
|
233
235
|
}
|
|
236
|
+
removeObject(identifier) {
|
|
237
|
+
this.registry.removeObject(identifier);
|
|
238
|
+
}
|
|
234
239
|
onBeforeBind(fn) {
|
|
235
240
|
this.objectCreateEventTarget.on(interface_1.ObjectLifeCycleEvent.BEFORE_BIND, fn);
|
|
236
241
|
}
|
|
@@ -5,6 +5,7 @@ import { IIdentifierRelationShip, IObjectDefinition, IObjectDefinitionRegistry,
|
|
|
5
5
|
export declare class ObjectDefinitionRegistry extends Map implements IObjectDefinitionRegistry {
|
|
6
6
|
private singletonIds;
|
|
7
7
|
private _identifierRelation;
|
|
8
|
+
private objectCache;
|
|
8
9
|
get identifierRelation(): IIdentifierRelationShip;
|
|
9
10
|
set identifierRelation(identifierRelation: IIdentifierRelationShip);
|
|
10
11
|
get identifiers(): any[];
|
|
@@ -18,6 +19,7 @@ export declare class ObjectDefinitionRegistry extends Map implements IObjectDefi
|
|
|
18
19
|
clearAll(): void;
|
|
19
20
|
hasObject(identifier: ObjectIdentifier): boolean;
|
|
20
21
|
registerObject(identifier: ObjectIdentifier, target: any): void;
|
|
22
|
+
removeObject(identifier: ObjectIdentifier): void;
|
|
21
23
|
getObject(identifier: ObjectIdentifier): any;
|
|
22
24
|
getIdentifierRelation(): IIdentifierRelationShip;
|
|
23
25
|
setIdentifierRelation(identifierRelation: IIdentifierRelationShip): void;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ObjectDefinitionRegistry = void 0;
|
|
4
4
|
const decorator_1 = require("../decorator");
|
|
5
|
-
const PREFIX = '_id_default_';
|
|
6
5
|
class LegacyIdentifierRelation extends Map {
|
|
7
6
|
saveClassRelation(module, namespace) {
|
|
8
7
|
const providerId = decorator_1.DecoratorManager.getProviderUUId(module);
|
|
@@ -35,11 +34,9 @@ class LegacyIdentifierRelation extends Map {
|
|
|
35
34
|
}
|
|
36
35
|
}
|
|
37
36
|
class ObjectDefinitionRegistry extends Map {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this._identifierRelation = new LegacyIdentifierRelation();
|
|
42
|
-
}
|
|
37
|
+
singletonIds = [];
|
|
38
|
+
_identifierRelation = new LegacyIdentifierRelation();
|
|
39
|
+
objectCache = new Map();
|
|
43
40
|
get identifierRelation() {
|
|
44
41
|
if (!this._identifierRelation) {
|
|
45
42
|
this._identifierRelation = new LegacyIdentifierRelation();
|
|
@@ -50,13 +47,7 @@ class ObjectDefinitionRegistry extends Map {
|
|
|
50
47
|
this._identifierRelation = identifierRelation;
|
|
51
48
|
}
|
|
52
49
|
get identifiers() {
|
|
53
|
-
|
|
54
|
-
for (const key of this.keys()) {
|
|
55
|
-
if (key.indexOf(PREFIX) === -1) {
|
|
56
|
-
ids.push(key);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return ids;
|
|
50
|
+
return Array.from(this.keys());
|
|
60
51
|
}
|
|
61
52
|
get count() {
|
|
62
53
|
return this.size;
|
|
@@ -93,18 +84,22 @@ class ObjectDefinitionRegistry extends Map {
|
|
|
93
84
|
}
|
|
94
85
|
clearAll() {
|
|
95
86
|
this.singletonIds = [];
|
|
87
|
+
this.objectCache.clear();
|
|
96
88
|
this.clear();
|
|
97
89
|
}
|
|
98
90
|
hasObject(identifier) {
|
|
99
91
|
identifier = this.identifierRelation.getRelation(identifier) ?? identifier;
|
|
100
|
-
return this.has(
|
|
92
|
+
return this.objectCache.has(identifier);
|
|
101
93
|
}
|
|
102
94
|
registerObject(identifier, target) {
|
|
103
|
-
this.set(
|
|
95
|
+
this.objectCache.set(identifier, target);
|
|
96
|
+
}
|
|
97
|
+
removeObject(identifier) {
|
|
98
|
+
this.objectCache.delete(identifier);
|
|
104
99
|
}
|
|
105
100
|
getObject(identifier) {
|
|
106
101
|
identifier = this.identifierRelation.getRelation(identifier) ?? identifier;
|
|
107
|
-
return this.get(
|
|
102
|
+
return this.objectCache.get(identifier);
|
|
108
103
|
}
|
|
109
104
|
getIdentifierRelation() {
|
|
110
105
|
return this.identifierRelation;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { MidwayContainer } from './container';
|
|
2
|
+
import { ClassType } from '../interface';
|
|
3
|
+
/**
|
|
4
|
+
* 尝试用于开发时动态更新的 IoC 容器
|
|
5
|
+
*/
|
|
6
|
+
export declare class DynamicMidwayContainer extends MidwayContainer {
|
|
7
|
+
private moduleType;
|
|
8
|
+
private modifyClassMapping;
|
|
9
|
+
private idRefMapping;
|
|
10
|
+
constructor();
|
|
11
|
+
updateDefinition(modifyFilePath: string): Promise<boolean>;
|
|
12
|
+
getIdentifier(identifier: ClassType | string): string;
|
|
13
|
+
private findDefinitionByPath;
|
|
14
|
+
private findRequireCacheAndClear;
|
|
15
|
+
private remapping;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=dynamicContainer.d.ts.map
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DynamicMidwayContainer = void 0;
|
|
4
|
+
const container_1 = require("./container");
|
|
5
|
+
const environmentService_1 = require("../service/environmentService");
|
|
6
|
+
const util_1 = require("../util");
|
|
7
|
+
const types_1 = require("../util/types");
|
|
8
|
+
const decorator_1 = require("../decorator");
|
|
9
|
+
const util_2 = require("util");
|
|
10
|
+
const debug = (0, util_2.debuglog)('midway:container');
|
|
11
|
+
/**
|
|
12
|
+
* 尝试用于开发时动态更新的 IoC 容器
|
|
13
|
+
*/
|
|
14
|
+
class DynamicMidwayContainer extends container_1.MidwayContainer {
|
|
15
|
+
moduleType;
|
|
16
|
+
modifyClassMapping = new Map();
|
|
17
|
+
idRefMapping = new Map();
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
this.onBeforeBind((Clzz, options) => {
|
|
21
|
+
const definition = options.definition;
|
|
22
|
+
if (definition) {
|
|
23
|
+
if (definition.properties) {
|
|
24
|
+
// 处理属性
|
|
25
|
+
for (const propMetas of definition.properties.values()) {
|
|
26
|
+
// 这里未处理懒加载依赖
|
|
27
|
+
if (typeof propMetas.id === 'string') {
|
|
28
|
+
if (this.idRefMapping.has(propMetas.id)) {
|
|
29
|
+
this.idRefMapping.get(propMetas.id).push(definition.id);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
this.idRefMapping.set(propMetas.id, [definition.id]);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (definition.constructorArgs) {
|
|
38
|
+
// 处理构造器
|
|
39
|
+
for (const constructMeta of definition.constructorArgs) {
|
|
40
|
+
if (typeof constructMeta.id === 'string') {
|
|
41
|
+
if (this.idRefMapping.has(constructMeta.id)) {
|
|
42
|
+
this.idRefMapping.get(constructMeta.id).push(definition.id);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this.idRefMapping.set(constructMeta.id, [definition.id]);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async updateDefinition(modifyFilePath) {
|
|
54
|
+
debug('updateDefinition %s', modifyFilePath);
|
|
55
|
+
if (!this.moduleType) {
|
|
56
|
+
const environmentService = await this.getAsync(environmentService_1.MidwayEnvironmentService);
|
|
57
|
+
this.moduleType = environmentService.getModuleLoadType();
|
|
58
|
+
}
|
|
59
|
+
// 根据文件路径找到老的类
|
|
60
|
+
const oldDefinitionList = this.findDefinitionByPath(modifyFilePath);
|
|
61
|
+
debug('oldDefinitionList size %s', oldDefinitionList.length);
|
|
62
|
+
if (!oldDefinitionList.length) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// 一个文件可能对应多个不同的 ObjectDefinition,但是导出的类名可能是不同的,所以可以使用类名作为 key
|
|
66
|
+
const nameList = {};
|
|
67
|
+
// 拿到旧的标识符
|
|
68
|
+
for (const oldDefinition of oldDefinitionList) {
|
|
69
|
+
nameList[oldDefinition.name] = oldDefinition.id;
|
|
70
|
+
}
|
|
71
|
+
debug('nameList %j', nameList);
|
|
72
|
+
// 清除 require cache
|
|
73
|
+
const requireCacheCleaned = this.findRequireCacheAndClear(modifyFilePath);
|
|
74
|
+
// 清理历史 context 缓存
|
|
75
|
+
for (const oldDefinition of oldDefinitionList) {
|
|
76
|
+
// 清理依赖的缓存
|
|
77
|
+
if (this.idRefMapping.has(oldDefinition.id)) {
|
|
78
|
+
for (const refId of this.idRefMapping.get(oldDefinition.id)) {
|
|
79
|
+
if (this.hasObject(refId)) {
|
|
80
|
+
this.removeObject(refId);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else if (this.idRefMapping.has(oldDefinition.name)) {
|
|
85
|
+
for (const refId of this.idRefMapping.get(oldDefinition.name)) {
|
|
86
|
+
if (this.hasObject(refId)) {
|
|
87
|
+
this.removeObject(refId);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// 清理自身
|
|
92
|
+
this.removeObject(oldDefinition.id);
|
|
93
|
+
}
|
|
94
|
+
debug('ready to load module %s', modifyFilePath);
|
|
95
|
+
// 重新加载新的文件
|
|
96
|
+
const modLoaded = await (0, util_1.loadModule)(modifyFilePath, {
|
|
97
|
+
loadMode: this.moduleType,
|
|
98
|
+
});
|
|
99
|
+
const newClassList = [];
|
|
100
|
+
if (types_1.Types.isClass(modLoaded) || types_1.Types.isFunction(modLoaded)) {
|
|
101
|
+
newClassList.push(modLoaded);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
for (const m in modLoaded) {
|
|
105
|
+
const module = modLoaded[m];
|
|
106
|
+
newClassList.push(module);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
debug('newClassList size %s', newClassList.length);
|
|
110
|
+
let remapping = false;
|
|
111
|
+
if (types_1.Types.isClass(modLoaded) || types_1.Types.isFunction(modLoaded)) {
|
|
112
|
+
const newId = decorator_1.DecoratorManager.getProviderUUId(modLoaded);
|
|
113
|
+
const name = decorator_1.DecoratorManager.getProviderName(modLoaded);
|
|
114
|
+
if (nameList[name]) {
|
|
115
|
+
debug('find old class name %s and will be remapping', name);
|
|
116
|
+
this.remapping(nameList[name], newId);
|
|
117
|
+
}
|
|
118
|
+
debug('bindModule %s', newId);
|
|
119
|
+
remapping = true;
|
|
120
|
+
this.bindModule(modLoaded, {
|
|
121
|
+
namespace: decorator_1.MAIN_MODULE_KEY,
|
|
122
|
+
srcPath: modifyFilePath,
|
|
123
|
+
createFrom: 'file',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
for (const m in modLoaded) {
|
|
128
|
+
const module = modLoaded[m];
|
|
129
|
+
if (types_1.Types.isClass(module) || types_1.Types.isFunction(module)) {
|
|
130
|
+
const newId = decorator_1.DecoratorManager.getProviderUUId(module);
|
|
131
|
+
const name = decorator_1.DecoratorManager.getProviderName(module);
|
|
132
|
+
if (nameList[name] !== newId) {
|
|
133
|
+
if (nameList[name]) {
|
|
134
|
+
debug('find old class name %s and will be remapping', name);
|
|
135
|
+
this.remapping(nameList[name], newId);
|
|
136
|
+
}
|
|
137
|
+
debug('bindModule %s', newId);
|
|
138
|
+
remapping = true;
|
|
139
|
+
this.bindModule(module, {
|
|
140
|
+
namespace: decorator_1.MAIN_MODULE_KEY,
|
|
141
|
+
srcPath: modifyFilePath,
|
|
142
|
+
createFrom: 'file',
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return (requireCacheCleaned &&
|
|
149
|
+
oldDefinitionList.length > 0 &&
|
|
150
|
+
newClassList.length > 0 &&
|
|
151
|
+
remapping);
|
|
152
|
+
}
|
|
153
|
+
getIdentifier(identifier) {
|
|
154
|
+
// 从老的 id 映射成新的 id
|
|
155
|
+
let name = 'unknown';
|
|
156
|
+
if (typeof identifier !== 'string') {
|
|
157
|
+
name = decorator_1.DecoratorManager.getProviderName(identifier);
|
|
158
|
+
identifier = decorator_1.DecoratorManager.getProviderUUId(identifier);
|
|
159
|
+
}
|
|
160
|
+
debug('check identifier from %s %s', name, identifier);
|
|
161
|
+
if (this.modifyClassMapping.has(identifier)) {
|
|
162
|
+
debug('getIdentifier from modifyClassMapping %s -> %s', identifier, this.modifyClassMapping.get(identifier));
|
|
163
|
+
return this.modifyClassMapping.get(identifier);
|
|
164
|
+
}
|
|
165
|
+
return identifier;
|
|
166
|
+
}
|
|
167
|
+
findDefinitionByPath(filePath) {
|
|
168
|
+
const results = [];
|
|
169
|
+
// 遍历 registry
|
|
170
|
+
for (const definition of this.registry.values()) {
|
|
171
|
+
if (definition.srcPath === filePath) {
|
|
172
|
+
results.push(definition);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return results;
|
|
176
|
+
}
|
|
177
|
+
findRequireCacheAndClear(absolutePath) {
|
|
178
|
+
let cleaned = false;
|
|
179
|
+
const cacheKey = require.resolve(absolutePath);
|
|
180
|
+
const cache = require.cache[cacheKey];
|
|
181
|
+
if (cache) {
|
|
182
|
+
debug('clear cache %s', cacheKey);
|
|
183
|
+
delete require.cache[cacheKey];
|
|
184
|
+
cleaned = true;
|
|
185
|
+
}
|
|
186
|
+
return cleaned;
|
|
187
|
+
}
|
|
188
|
+
remapping(oldId, newId) {
|
|
189
|
+
// 新老 id 做个重新映射,如果第一次 1 -> 2, 第二次输入 2 -> 3,那么要变成 1 -> 3
|
|
190
|
+
for (const [key, value] of this.modifyClassMapping.entries()) {
|
|
191
|
+
if (value === oldId) {
|
|
192
|
+
debug('remapping key = %s, %s -> %s', key, oldId, newId);
|
|
193
|
+
// Update the mapping to the new newId
|
|
194
|
+
this.modifyClassMapping.set(key, newId);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
debug('new remapping key = %s, value = %s', oldId, newId);
|
|
198
|
+
// Set the new mapping
|
|
199
|
+
this.modifyClassMapping.set(oldId, newId);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
exports.DynamicMidwayContainer = DynamicMidwayContainer;
|
|
203
|
+
//# sourceMappingURL=dynamicContainer.js.map
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { ClassType, IMidwayContainer, IMidwayGlobalContainer
|
|
1
|
+
import { ClassType, IMidwayContainer, IMidwayGlobalContainer } from '../interface';
|
|
2
2
|
/**
|
|
3
3
|
* 解析工厂
|
|
4
4
|
*/
|
|
5
5
|
export declare class ManagedResolverFactory {
|
|
6
6
|
private creating;
|
|
7
|
-
singletonCache: Map<ObjectIdentifier, any>;
|
|
8
7
|
context: IMidwayGlobalContainer;
|
|
9
8
|
constructor(context: IMidwayGlobalContainer);
|
|
10
9
|
/**
|
|
@@ -31,9 +31,9 @@ function formatObjectIdentifier(identifier) {
|
|
|
31
31
|
* 解析工厂
|
|
32
32
|
*/
|
|
33
33
|
class ManagedResolverFactory {
|
|
34
|
+
creating = new Map();
|
|
35
|
+
context;
|
|
34
36
|
constructor(context) {
|
|
35
|
-
this.creating = new Map();
|
|
36
|
-
this.singletonCache = new Map();
|
|
37
37
|
this.context = context;
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
@@ -89,18 +89,19 @@ class ManagedResolverFactory {
|
|
|
89
89
|
return newInstance ?? instance;
|
|
90
90
|
}
|
|
91
91
|
async destroyCache() {
|
|
92
|
-
for (const key of this.
|
|
92
|
+
for (const key of this.context.registry.getSingletonDefinitionIds()) {
|
|
93
93
|
const definition = this.getObjectDefinition(key);
|
|
94
94
|
if (definition.creator) {
|
|
95
|
-
const inst = this.
|
|
95
|
+
const inst = this.context.getObject(key);
|
|
96
96
|
this.getObjectEventTarget().emit(interface_1.ObjectLifeCycleEvent.BEFORE_DESTROY, inst, {
|
|
97
97
|
context: this.context,
|
|
98
98
|
definition,
|
|
99
99
|
});
|
|
100
100
|
await definition.creator.doDestroyAsync(inst);
|
|
101
101
|
}
|
|
102
|
+
// clean singleton object cache
|
|
103
|
+
this.context.removeObject(key);
|
|
102
104
|
}
|
|
103
|
-
this.singletonCache.clear();
|
|
104
105
|
this.creating.clear();
|
|
105
106
|
}
|
|
106
107
|
getObjectEventTarget() {
|
|
@@ -149,10 +150,16 @@ class ManagedResolverFactory {
|
|
|
149
150
|
}
|
|
150
151
|
if (definition.isSingletonScope()) {
|
|
151
152
|
currentContext = this.context;
|
|
152
|
-
if (this.
|
|
153
|
+
if (this.context.hasObject(definition.id)) {
|
|
153
154
|
debug(`[core]: "${definition.id}(${definition.name})" get from singleton cache.`);
|
|
154
|
-
return this.
|
|
155
|
+
return this.context.getObject(definition.id);
|
|
155
156
|
}
|
|
157
|
+
// if (this.singletonCache.has(definition.id)) {
|
|
158
|
+
// debug(
|
|
159
|
+
// `[core]: "${definition.id}(${definition.name})" get from singleton cache.`
|
|
160
|
+
// );
|
|
161
|
+
// return this.singletonCache.get(definition.id);
|
|
162
|
+
// }
|
|
156
163
|
}
|
|
157
164
|
// 使用 creationPath 检查循环依赖
|
|
158
165
|
if (creationPath.has(definition.id)) {
|
|
@@ -323,7 +330,8 @@ class ManagedResolverFactory {
|
|
|
323
330
|
if (definition.id) {
|
|
324
331
|
if (definition.isSingletonScope()) {
|
|
325
332
|
debug(`[core]: "${definition.id}(${definition.name})" set to singleton cache`);
|
|
326
|
-
this.
|
|
333
|
+
this.context.registerObject(definition.id, instance);
|
|
334
|
+
// this.singletonCache.set(definition.id, instance);
|
|
327
335
|
this.setInstanceScope(instance, interface_1.ScopeEnum.Singleton);
|
|
328
336
|
}
|
|
329
337
|
else if (definition.isRequestScope()) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.providerWrapper =
|
|
3
|
+
exports.providerWrapper = providerWrapper;
|
|
4
4
|
const constants_1 = require("../constants");
|
|
5
5
|
function providerWrapper(wrapperInfo) {
|
|
6
6
|
for (const info of wrapperInfo) {
|
|
@@ -10,5 +10,4 @@ function providerWrapper(wrapperInfo) {
|
|
|
10
10
|
});
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
exports.providerWrapper = providerWrapper;
|
|
14
13
|
//# sourceMappingURL=providerWrapper.js.map
|
|
@@ -13,6 +13,7 @@ export declare class MidwayRequestContainer implements IMidwayRequestContainer {
|
|
|
13
13
|
hasDefinition(identifier: ObjectIdentifier): boolean;
|
|
14
14
|
getDefinition(identifier: ObjectIdentifier): import("../interface").IObjectDefinition;
|
|
15
15
|
registerObject(identifier: string, obj: any): void;
|
|
16
|
+
removeObject(identifier: ObjectIdentifier): void;
|
|
16
17
|
hasObject(identifier: ObjectIdentifier): boolean;
|
|
17
18
|
getObject<T>(identifier: ObjectIdentifier): T;
|
|
18
19
|
setAttr(key: string, value: any): void;
|
|
@@ -4,11 +4,14 @@ exports.MidwayRequestContainer = void 0;
|
|
|
4
4
|
const constants_1 = require("../constants");
|
|
5
5
|
const definitionRegistry_1 = require("./definitionRegistry");
|
|
6
6
|
class MidwayRequestContainer {
|
|
7
|
+
ctx;
|
|
8
|
+
applicationContext;
|
|
9
|
+
parent;
|
|
10
|
+
registry = new definitionRegistry_1.ObjectDefinitionRegistry();
|
|
11
|
+
attrMap = new Map();
|
|
7
12
|
constructor(ctx, applicationContext) {
|
|
8
13
|
this.ctx = ctx;
|
|
9
14
|
this.applicationContext = applicationContext;
|
|
10
|
-
this.registry = new definitionRegistry_1.ObjectDefinitionRegistry();
|
|
11
|
-
this.attrMap = new Map();
|
|
12
15
|
this.parent = applicationContext;
|
|
13
16
|
// update legacy relationship
|
|
14
17
|
this.registry.setIdentifierRelation(this.applicationContext.registry.getIdentifierRelation());
|
|
@@ -44,6 +47,9 @@ class MidwayRequestContainer {
|
|
|
44
47
|
registerObject(identifier, obj) {
|
|
45
48
|
this.registry.registerObject(identifier, obj);
|
|
46
49
|
}
|
|
50
|
+
removeObject(identifier) {
|
|
51
|
+
this.registry.removeObject(identifier);
|
|
52
|
+
}
|
|
47
53
|
hasObject(identifier) {
|
|
48
54
|
return this.registry.hasObject(identifier);
|
|
49
55
|
}
|