@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.
Files changed (133) hide show
  1. package/README.md +1 -1
  2. package/dist/baseFramework.d.ts +13 -10
  3. package/dist/baseFramework.js +30 -15
  4. package/dist/common/applicationManager.js +6 -4
  5. package/dist/common/asyncContextManager.js +23 -0
  6. package/dist/common/dataListener.d.ts +5 -3
  7. package/dist/common/dataListener.js +11 -3
  8. package/dist/common/dataSourceManager.d.ts +18 -9
  9. package/dist/common/dataSourceManager.js +129 -77
  10. package/dist/common/fileDetector.js +2 -4
  11. package/dist/common/filterManager.js +6 -8
  12. package/dist/common/loggerFactory.js +1 -3
  13. package/dist/common/middlewareManager.js +2 -2
  14. package/dist/common/performanceManager.d.ts +0 -1
  15. package/dist/common/performanceManager.js +21 -20
  16. package/dist/common/priorityManager.js +2 -4
  17. package/dist/common/serviceDiscovery/healthCheck.d.ts +66 -0
  18. package/dist/common/serviceDiscovery/healthCheck.js +215 -0
  19. package/dist/common/serviceDiscovery/loadBalancer.d.ts +21 -0
  20. package/dist/common/serviceDiscovery/loadBalancer.js +49 -0
  21. package/dist/common/serviceDiscovery/serviceDiscovery.d.ts +59 -0
  22. package/dist/common/serviceDiscovery/serviceDiscovery.js +107 -0
  23. package/dist/common/serviceFactory.d.ts +5 -2
  24. package/dist/common/serviceFactory.js +47 -12
  25. package/dist/common/typedResourceManager.js +3 -2
  26. package/dist/common/webGenerator.js +2 -0
  27. package/dist/config/config.default.js +4 -1
  28. package/dist/context/componentLoader.js +3 -2
  29. package/dist/context/container.d.ts +4 -4
  30. package/dist/context/container.js +15 -10
  31. package/dist/context/definitionRegistry.d.ts +2 -0
  32. package/dist/context/definitionRegistry.js +11 -16
  33. package/dist/context/dynamicContainer.d.ts +17 -0
  34. package/dist/context/dynamicContainer.js +203 -0
  35. package/dist/context/managedResolverFactory.d.ts +1 -2
  36. package/dist/context/managedResolverFactory.js +16 -8
  37. package/dist/context/providerWrapper.js +1 -2
  38. package/dist/context/requestContainer.d.ts +1 -0
  39. package/dist/context/requestContainer.js +8 -2
  40. package/dist/decorator/common/aspect.js +1 -2
  41. package/dist/decorator/common/autoload.js +1 -2
  42. package/dist/decorator/common/configuration.js +1 -2
  43. package/dist/decorator/common/filter.js +2 -3
  44. package/dist/decorator/common/framework.js +8 -9
  45. package/dist/decorator/common/guard.js +2 -3
  46. package/dist/decorator/common/inject.js +4 -5
  47. package/dist/decorator/common/middleware.js +1 -2
  48. package/dist/decorator/common/mock.js +1 -2
  49. package/dist/decorator/common/objectDef.js +2 -3
  50. package/dist/decorator/common/pipe.js +1 -2
  51. package/dist/decorator/common/provide.js +1 -2
  52. package/dist/decorator/common/scope.js +2 -3
  53. package/dist/decorator/decoratorManager.js +4 -4
  54. package/dist/decorator/faas/serverlessTrigger.js +2 -3
  55. package/dist/decorator/metadataManager.d.ts +14 -6
  56. package/dist/decorator/metadataManager.js +49 -63
  57. package/dist/decorator/microservice/consumer.js +1 -2
  58. package/dist/decorator/microservice/kafkaListener.js +1 -2
  59. package/dist/decorator/microservice/provider.js +4 -4
  60. package/dist/decorator/microservice/rabbitmqListener.js +1 -2
  61. package/dist/decorator/task/queue.js +1 -2
  62. package/dist/decorator/task/schedule.js +1 -2
  63. package/dist/decorator/task/task.js +1 -2
  64. package/dist/decorator/task/taskLocal.js +1 -2
  65. package/dist/decorator/web/controller.d.ts +6 -0
  66. package/dist/decorator/web/controller.js +1 -2
  67. package/dist/decorator/web/response.js +5 -6
  68. package/dist/decorator/ws/webSocketController.js +1 -2
  69. package/dist/decorator/ws/webSocketEvent.js +6 -6
  70. package/dist/definitions/functionDefinition.js +21 -12
  71. package/dist/definitions/objectCreator.js +5 -2
  72. package/dist/definitions/objectDefinition.js +19 -17
  73. package/dist/error/base.js +5 -2
  74. package/dist/error/framework.d.ts +1 -1
  75. package/dist/error/framework.js +4 -2
  76. package/dist/error/http.d.ts +7 -0
  77. package/dist/error/http.js +11 -1
  78. package/dist/functional/configuration.d.ts +6 -6
  79. package/dist/functional/configuration.js +11 -10
  80. package/dist/functional/hooks.d.ts +3 -1
  81. package/dist/functional/hooks.js +18 -9
  82. package/dist/index.d.ts +5 -1
  83. package/dist/index.js +8 -2
  84. package/dist/interface.d.ts +179 -21
  85. package/dist/interface.js +15 -1
  86. package/dist/legacy/decorator.js +31 -32
  87. package/dist/response/base.d.ts +3 -5
  88. package/dist/response/base.js +22 -21
  89. package/dist/response/http.d.ts +4 -7
  90. package/dist/response/http.js +12 -12
  91. package/dist/response/sse.d.ts +0 -1
  92. package/dist/response/sse.js +4 -1
  93. package/dist/response/stream.d.ts +0 -1
  94. package/dist/response/stream.js +3 -1
  95. package/dist/service/aspectService.js +1 -0
  96. package/dist/service/configService.d.ts +1 -1
  97. package/dist/service/configService.js +16 -14
  98. package/dist/service/decoratorService.js +6 -4
  99. package/dist/service/environmentService.js +2 -3
  100. package/dist/service/frameworkService.js +9 -1
  101. package/dist/service/healthService.d.ts +2 -0
  102. package/dist/service/healthService.js +20 -8
  103. package/dist/service/informationService.d.ts +3 -0
  104. package/dist/service/informationService.js +13 -0
  105. package/dist/service/lifeCycleService.d.ts +13 -7
  106. package/dist/service/lifeCycleService.js +55 -33
  107. package/dist/service/loggerService.js +6 -2
  108. package/dist/service/middlewareService.js +1 -0
  109. package/dist/service/mockService.js +17 -15
  110. package/dist/service/slsFunctionService.js +1 -0
  111. package/dist/service/webRouterService.d.ts +25 -1
  112. package/dist/service/webRouterService.js +20 -3
  113. package/dist/setup.js +12 -6
  114. package/dist/util/camelCase.js +2 -3
  115. package/dist/util/contextUtil.d.ts +3 -3
  116. package/dist/util/extend.js +1 -2
  117. package/dist/util/flatted.js +2 -3
  118. package/dist/util/fs.js +2 -2
  119. package/dist/util/httpclient.d.ts +0 -4
  120. package/dist/util/httpclient.js +3 -2
  121. package/dist/util/index.d.ts +3 -18
  122. package/dist/util/index.js +49 -103
  123. package/dist/util/network.d.ts +10 -0
  124. package/dist/util/network.js +40 -0
  125. package/dist/util/pathFileUtil.d.ts +1 -2
  126. package/dist/util/pathFileUtil.js +7 -7
  127. package/dist/util/retry.js +2 -3
  128. package/dist/util/timeout.d.ts +56 -0
  129. package/dist/util/timeout.js +143 -0
  130. package/dist/util/types.d.ts +7 -7
  131. package/dist/util/types.js +17 -17
  132. package/dist/util/uuid.js +1 -2
  133. 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
- constructor() {
21
- this.clients = new Map();
22
- this.options = {};
23
- }
24
- async initClients(options = {}) {
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
- for (const id of Object.keys(options.clients)) {
35
- await this.createInstance(options.clients[id], id);
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 client = await this.createClient(config, clientName);
51
- if (client) {
68
+ const clientCreatingPromise = this.createClient(config, clientName);
69
+ if (clientCreatingPromise && types_1.Types.isPromise(clientCreatingPromise)) {
52
70
  if (clientName) {
53
- this.clients.set(clientName, client);
71
+ this.creatingClients.set(clientName, clientCreatingPromise);
54
72
  }
55
- return client;
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: 1000,
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>): void;
25
- bind<T>(identifier: ObjectIdentifier, target: T, options?: Partial<IObjectDefinition>): void;
26
- protected bindModule(module: any, options: Partial<IObjectDefinition>): void;
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
- constructor() {
39
- super(...arguments);
40
- this.singletonIds = [];
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
- const ids = [];
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(PREFIX + identifier);
92
+ return this.objectCache.has(identifier);
101
93
  }
102
94
  registerObject(identifier, target) {
103
- this.set(PREFIX + identifier, target);
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(PREFIX + identifier);
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, ObjectIdentifier } from '../interface';
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.singletonCache.keys()) {
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.singletonCache.get(key);
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.singletonCache.has(definition.id)) {
153
+ if (this.context.hasObject(definition.id)) {
153
154
  debug(`[core]: "${definition.id}(${definition.name})" get from singleton cache.`);
154
- return this.singletonCache.get(definition.id);
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.singletonCache.set(definition.id, instance);
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 = void 0;
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
  }