@nmtjs/core 0.12.5 → 0.12.6

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 (53) hide show
  1. package/dist/constants.d.ts +20 -0
  2. package/dist/constants.js +10 -12
  3. package/dist/container.d.ts +46 -0
  4. package/dist/container.js +310 -277
  5. package/dist/enums.d.ts +18 -0
  6. package/dist/enums.js +20 -22
  7. package/dist/hooks.d.ts +19 -0
  8. package/dist/hooks.js +39 -35
  9. package/dist/index.d.ts +11 -0
  10. package/dist/index.js +3 -2
  11. package/dist/injectables.d.ts +115 -0
  12. package/dist/injectables.js +194 -179
  13. package/dist/logger.d.ts +9 -0
  14. package/dist/logger.js +54 -58
  15. package/dist/metadata.d.ts +13 -0
  16. package/dist/metadata.js +10 -15
  17. package/dist/plugin.d.ts +12 -0
  18. package/dist/plugin.js +1 -7
  19. package/dist/registry.d.ts +19 -0
  20. package/dist/registry.js +17 -18
  21. package/dist/types.d.ts +11 -0
  22. package/dist/types.js +0 -2
  23. package/dist/utils/functions.d.ts +6 -0
  24. package/dist/utils/functions.js +30 -32
  25. package/dist/utils/index.d.ts +3 -0
  26. package/dist/utils/index.js +0 -2
  27. package/dist/utils/pool.d.ts +18 -0
  28. package/dist/utils/pool.js +103 -90
  29. package/dist/utils/semaphore.d.ts +13 -0
  30. package/dist/utils/semaphore.js +53 -46
  31. package/package.json +9 -8
  32. package/src/hooks.ts +1 -3
  33. package/src/index.ts +4 -0
  34. package/src/injectables.ts +2 -2
  35. package/src/logger.ts +1 -0
  36. package/src/plugin.ts +1 -1
  37. package/src/utils/pool.ts +1 -1
  38. package/src/utils/semaphore.ts +1 -1
  39. package/dist/constants.js.map +0 -1
  40. package/dist/container.js.map +0 -1
  41. package/dist/enums.js.map +0 -1
  42. package/dist/hooks.js.map +0 -1
  43. package/dist/index.js.map +0 -1
  44. package/dist/injectables.js.map +0 -1
  45. package/dist/logger.js.map +0 -1
  46. package/dist/metadata.js.map +0 -1
  47. package/dist/plugin.js.map +0 -1
  48. package/dist/registry.js.map +0 -1
  49. package/dist/types.js.map +0 -1
  50. package/dist/utils/functions.js.map +0 -1
  51. package/dist/utils/index.js.map +0 -1
  52. package/dist/utils/pool.js.map +0 -1
  53. package/dist/utils/semaphore.js.map +0 -1
package/dist/container.js CHANGED
@@ -1,280 +1,313 @@
1
- import assert from "node:assert";
2
- import { tryCaptureStackTrace } from "@nmtjs/common";
1
+ import assert from 'node:assert';
2
+ import { tryCaptureStackTrace } from '@nmtjs/common';
3
3
  import { Scope } from "./enums.js";
4
- import { CoreInjectables, compareScope, createExtendableClassInjectable, createValueInjectable, getDepedencencyInjectable, isClassInjectable, isFactoryInjectable, isInjectable, isLazyInjectable, isOptionalInjectable, isValueInjectable } from "./injectables.js";
4
+ import { CoreInjectables, compareScope, createExtendableClassInjectable, createValueInjectable, getDepedencencyInjectable, isClassInjectable, isFactoryInjectable, isInjectable, isLazyInjectable, isOptionalInjectable, isValueInjectable, } from "./injectables.js";
5
5
  export class Container {
6
- instances = new Map();
7
- resolvers = new Map();
8
- injectables = new Set();
9
- dependants = new Map();
10
- disposing = false;
11
- constructor(application, scope = Scope.Global, parent) {
12
- this.application = application;
13
- this.scope = scope;
14
- this.parent = parent;
15
- if (scope === Scope.Transient) {
16
- throw new Error("Invalid scope");
17
- }
18
- this.provide(CoreInjectables.inject, this.createInjectFunction());
19
- this.provide(CoreInjectables.dispose, this.createDisposeFunction());
20
- this.provide(CoreInjectables.registry, application.registry);
21
- }
22
- async load() {
23
- const traverse = (dependencies) => {
24
- for (const key in dependencies) {
25
- const dependency = dependencies[key];
26
- const injectable = getDepedencencyInjectable(dependency);
27
- this.injectables.add(injectable);
28
- traverse(injectable.dependencies);
29
- }
30
- };
31
- for (const dependant of this.application.registry.getDependants()) {
32
- traverse(dependant.dependencies);
33
- }
34
- const injectables = Array.from(this.findCurrentScopeInjectables());
35
- await Promise.all(injectables.map((injectable) => this.resolve(injectable)));
36
- }
37
- fork(scope) {
38
- return new Container(this.application, scope, this);
39
- }
40
- async dispose() {
41
- this.application.logger.trace("Disposing [%s] scope context...", this.scope);
42
- this.disposing = true;
43
- const disposalOrder = this.getDisposalOrder();
44
- for (const injectable of disposalOrder) {
45
- if (this.instances.has(injectable)) {
46
- await this.disposeInjectableInstances(injectable);
47
- }
48
- }
49
- this.instances.clear();
50
- this.injectables.clear();
51
- this.resolvers.clear();
52
- this.dependants.clear();
53
- this.disposing = false;
54
- }
55
- containsWithinSelf(injectable) {
56
- return this.instances.has(injectable) || this.resolvers.has(injectable);
57
- }
58
- contains(injectable) {
59
- return this.containsWithinSelf(injectable) || (this.parent?.contains(injectable) ?? false);
60
- }
61
- get(injectable) {
62
- if (injectable.scope === Scope.Transient) {
63
- throw new Error("Cannot get transient injectable directly");
64
- }
65
- if (this.instances.has(injectable)) {
66
- return this.instances.get(injectable).at(0).public;
67
- }
68
- if (this.parent?.contains(injectable)) {
69
- return this.parent.get(injectable);
70
- }
71
- throw new Error("No instance found");
72
- }
73
- resolve(injectable) {
74
- return this.resolveInjectable(injectable);
75
- }
76
- async createContext(dependencies) {
77
- return this.createInjectableContext(dependencies);
78
- }
79
- async createInjectableContext(dependencies, dependant) {
80
- const injections = {};
81
- const deps = Object.entries(dependencies);
82
- const resolvers = Array(deps.length);
83
- for (let i = 0; i < deps.length; i++) {
84
- const [key, dependency] = deps[i];
85
- const injectable = getDepedencencyInjectable(dependency);
86
- const resolver = this.resolveInjectable(injectable, dependant);
87
- resolvers[i] = resolver.then((value) => injections[key] = value);
88
- }
89
- await Promise.all(resolvers);
90
- return Object.freeze(injections);
91
- }
92
- async provide(injectable, instance) {
93
- if (compareScope(injectable.scope, ">", this.scope)) {
94
- throw new Error("Invalid scope");
95
- }
96
- this.instances.set(injectable, [{
97
- private: instance,
98
- public: instance,
99
- context: undefined
100
- }]);
101
- }
102
- satisfies(injectable) {
103
- return compareScope(injectable.scope, "<=", this.scope);
104
- }
105
- *findCurrentScopeInjectables() {
106
- for (const injectable of this.injectables) {
107
- if (injectable.scope === this.scope) {
108
- yield injectable;
109
- }
110
- }
111
- }
112
- resolveInjectable(injectable, dependant) {
113
- if (this.disposing) {
114
- return Promise.reject(new Error("Cannot resolve during disposal"));
115
- }
116
- if (dependant && compareScope(dependant.scope, "<", injectable.scope)) {
117
- return Promise.reject(new Error("Invalid scope: dependant is looser than injectable"));
118
- }
119
- if (isValueInjectable(injectable)) {
120
- return Promise.resolve(injectable.value);
121
- } else if (this.parent?.contains(injectable) || this.parent?.satisfies(injectable) && compareScope(this.parent.scope, "<", this.scope)) {
122
- return this.parent.resolveInjectable(injectable, dependant);
123
- } else {
124
- const { stack, label } = injectable;
125
- if (dependant) {
126
- let dependants = this.dependants.get(injectable);
127
- if (!dependants) {
128
- this.dependants.set(injectable, dependants = new Set());
129
- }
130
- dependants.add(dependant);
131
- }
132
- const isTransient = injectable.scope === Scope.Transient;
133
- if (!isTransient && this.instances.has(injectable)) {
134
- return Promise.resolve(this.instances.get(injectable).at(0).public);
135
- } else if (!isTransient && this.resolvers.has(injectable)) {
136
- return this.resolvers.get(injectable);
137
- } else {
138
- const isLazy = isLazyInjectable(injectable);
139
- if (isLazy) {
140
- const isOptional = isOptionalInjectable(injectable);
141
- if (isOptional) return Promise.resolve(undefined);
142
- return Promise.reject(new Error(`No instance provided for ${label || "an"} injectable:\n${stack}`));
143
- } else {
144
- const resolution = this.createResolution(injectable).finally(() => {
145
- this.resolvers.delete(injectable);
146
- });
147
- if (injectable.scope !== Scope.Transient) {
148
- this.resolvers.set(injectable, resolution);
149
- }
150
- return resolution;
151
- }
152
- }
153
- }
154
- }
155
- async createResolution(injectable) {
156
- const { dependencies } = injectable;
157
- const context = await this.createInjectableContext(dependencies, injectable);
158
- const wrapper = {
159
- private: null,
160
- public: null,
161
- context
162
- };
163
- if (isFactoryInjectable(injectable)) {
164
- wrapper.private = await Promise.resolve(injectable.factory(wrapper.context));
165
- wrapper.public = injectable.pick(wrapper.private);
166
- } else if (isClassInjectable(injectable)) {
167
- wrapper.private = new injectable(context);
168
- wrapper.public = wrapper.private;
169
- await wrapper.private.$onCreate();
170
- } else {
171
- throw new Error("Invalid injectable type");
172
- }
173
- let instances = this.instances.get(injectable);
174
- if (!instances) {
175
- instances = [];
176
- this.instances.set(injectable, instances);
177
- }
178
- instances.push(wrapper);
179
- return wrapper.public;
180
- }
181
- createInjectFunction() {
182
- const inject = (injectable, context) => {
183
- const dependencies = { ...injectable.dependencies };
184
- for (const key in context) {
185
- const dep = context[key];
186
- if (isInjectable(dep) || isOptionalInjectable(dep)) {
187
- dependencies[key] = dep;
188
- } else {
189
- dependencies[key] = createValueInjectable(dep);
190
- }
191
- }
192
- const newInjectable = isClassInjectable(injectable) ? createExtendableClassInjectable(injectable, dependencies, Scope.Transient, 1) : {
193
- ...injectable,
194
- dependencies,
195
- scope: Scope.Transient,
196
- stack: tryCaptureStackTrace(1)
197
- };
198
- return this.resolve(newInjectable);
199
- };
200
- const explicit = async (injectable, context) => {
201
- if ("asyncDispose" in Symbol === false) {
202
- throw new Error("Symbol.asyncDispose is not supported in this environment");
203
- }
204
- const instance = await inject(injectable, context);
205
- const dispose = this.createDisposeFunction();
206
- return Object.assign(instance, { [Symbol.asyncDispose]: async () => {
207
- await dispose(injectable, instance);
208
- } });
209
- };
210
- return Object.assign(inject, { explicit });
211
- }
212
- createDisposeFunction() {
213
- return async (injectable, instance) => {
214
- if (injectable.scope === Scope.Transient) {
215
- assert(instance, "Instance is required for transient injectable disposal");
216
- const wrappers = this.instances.get(injectable);
217
- if (wrappers) {
218
- for (const wrapper of wrappers) {
219
- if (wrapper.public === instance) {
220
- await this.disposeInjectableInstance(injectable, wrapper.private, wrapper.context);
221
- const index = wrappers.indexOf(wrapper);
222
- wrappers.splice(index, 1);
223
- }
224
- }
225
- if (wrappers.length === 0) {
226
- this.instances.delete(injectable);
227
- }
228
- }
229
- } else {
230
- await this.disposeInjectableInstances(injectable);
231
- }
232
- };
233
- }
234
- getDisposalOrder() {
235
- const visited = new Set();
236
- const result = [];
237
- const visit = (injectable) => {
238
- if (visited.has(injectable)) return;
239
- visited.add(injectable);
240
- const dependants = this.dependants.get(injectable);
241
- if (dependants) {
242
- for (const dependant of dependants) {
243
- if (this.instances.has(dependant)) {
244
- visit(dependant);
245
- }
246
- }
247
- }
248
- if (this.instances.has(injectable)) {
249
- result.push(injectable);
250
- }
251
- };
252
- for (const injectable of this.instances.keys()) {
253
- visit(injectable);
254
- }
255
- return result;
256
- }
257
- async disposeInjectableInstances(injectable) {
258
- try {
259
- if (this.instances.has(injectable)) {
260
- const wrappers = this.instances.get(injectable);
261
- await Promise.all(wrappers.map((wrapper) => this.disposeInjectableInstance(injectable, wrapper.private, wrapper.context)));
262
- }
263
- } catch (cause) {
264
- const error = new Error("Injectable disposal error. Potential memory leak", { cause });
265
- this.application.logger.error(error);
266
- } finally {
267
- this.instances.delete(injectable);
268
- }
269
- }
270
- async disposeInjectableInstance(injectable, instance, context) {
271
- if (isFactoryInjectable(injectable)) {
272
- const { dispose } = injectable;
273
- if (dispose) await dispose(instance, context);
274
- } else if (isClassInjectable(injectable)) {
275
- await instance.$onDispose();
276
- }
277
- }
6
+ application;
7
+ scope;
8
+ parent;
9
+ instances = new Map();
10
+ resolvers = new Map();
11
+ injectables = new Set();
12
+ dependants = new Map();
13
+ // private readonly transients = new Map<any, any>()
14
+ disposing = false;
15
+ constructor(application, scope = Scope.Global, parent) {
16
+ this.application = application;
17
+ this.scope = scope;
18
+ this.parent = parent;
19
+ if (scope === Scope.Transient) {
20
+ throw new Error('Invalid scope');
21
+ }
22
+ this.provide(CoreInjectables.inject, this.createInjectFunction());
23
+ this.provide(CoreInjectables.dispose, this.createDisposeFunction());
24
+ this.provide(CoreInjectables.registry, application.registry);
25
+ }
26
+ async load() {
27
+ const traverse = (dependencies) => {
28
+ for (const key in dependencies) {
29
+ const dependency = dependencies[key];
30
+ const injectable = getDepedencencyInjectable(dependency);
31
+ this.injectables.add(injectable);
32
+ traverse(injectable.dependencies);
33
+ }
34
+ };
35
+ for (const dependant of this.application.registry.getDependants()) {
36
+ traverse(dependant.dependencies);
37
+ }
38
+ const injectables = Array.from(this.findCurrentScopeInjectables());
39
+ await Promise.all(injectables.map((injectable) => this.resolve(injectable)));
40
+ }
41
+ fork(scope) {
42
+ return new Container(this.application, scope, this);
43
+ }
44
+ async dispose() {
45
+ this.application.logger.trace('Disposing [%s] scope context...', this.scope);
46
+ // Prevent new resolutions during disposal
47
+ this.disposing = true;
48
+ // Get proper disposal order using topological sort
49
+ const disposalOrder = this.getDisposalOrder();
50
+ // Dispose in the correct order
51
+ for (const injectable of disposalOrder) {
52
+ if (this.instances.has(injectable)) {
53
+ await this.disposeInjectableInstances(injectable);
54
+ }
55
+ }
56
+ this.instances.clear();
57
+ this.injectables.clear();
58
+ this.resolvers.clear();
59
+ this.dependants.clear();
60
+ this.disposing = false;
61
+ }
62
+ containsWithinSelf(injectable) {
63
+ return this.instances.has(injectable) || this.resolvers.has(injectable);
64
+ }
65
+ contains(injectable) {
66
+ return (this.containsWithinSelf(injectable) ||
67
+ (this.parent?.contains(injectable) ?? false));
68
+ }
69
+ get(injectable) {
70
+ if (injectable.scope === Scope.Transient) {
71
+ throw new Error('Cannot get transient injectable directly');
72
+ }
73
+ if (this.instances.has(injectable)) {
74
+ return this.instances.get(injectable).at(0).public;
75
+ }
76
+ if (this.parent?.contains(injectable)) {
77
+ return this.parent.get(injectable);
78
+ }
79
+ throw new Error('No instance found');
80
+ }
81
+ resolve(injectable) {
82
+ return this.resolveInjectable(injectable);
83
+ }
84
+ async createContext(dependencies) {
85
+ return this.createInjectableContext(dependencies);
86
+ }
87
+ async createInjectableContext(dependencies, dependant) {
88
+ const injections = {};
89
+ const deps = Object.entries(dependencies);
90
+ const resolvers = Array(deps.length);
91
+ for (let i = 0; i < deps.length; i++) {
92
+ const [key, dependency] = deps[i];
93
+ const injectable = getDepedencencyInjectable(dependency);
94
+ const resolver = this.resolveInjectable(injectable, dependant);
95
+ resolvers[i] = resolver.then((value) => (injections[key] = value));
96
+ }
97
+ await Promise.all(resolvers);
98
+ return Object.freeze(injections);
99
+ }
100
+ async provide(injectable, instance) {
101
+ if (compareScope(injectable.scope, '>', this.scope)) {
102
+ throw new Error('Invalid scope'); // TODO: more informative error
103
+ }
104
+ this.instances.set(injectable, [
105
+ {
106
+ private: instance,
107
+ public: instance,
108
+ context: undefined,
109
+ },
110
+ ]);
111
+ }
112
+ satisfies(injectable) {
113
+ return compareScope(injectable.scope, '<=', this.scope);
114
+ }
115
+ *findCurrentScopeInjectables() {
116
+ for (const injectable of this.injectables) {
117
+ if (injectable.scope === this.scope) {
118
+ yield injectable;
119
+ }
120
+ }
121
+ }
122
+ resolveInjectable(injectable, dependant) {
123
+ if (this.disposing) {
124
+ return Promise.reject(new Error('Cannot resolve during disposal'));
125
+ }
126
+ if (dependant && compareScope(dependant.scope, '<', injectable.scope)) {
127
+ // TODO: more informative error
128
+ return Promise.reject(new Error('Invalid scope: dependant is looser than injectable'));
129
+ }
130
+ if (isValueInjectable(injectable)) {
131
+ return Promise.resolve(injectable.value);
132
+ }
133
+ else if (this.parent?.contains(injectable) ||
134
+ (this.parent?.satisfies(injectable) &&
135
+ compareScope(this.parent.scope, '<', this.scope))) {
136
+ return this.parent.resolveInjectable(injectable, dependant);
137
+ }
138
+ else {
139
+ const { stack, label } = injectable;
140
+ if (dependant) {
141
+ let dependants = this.dependants.get(injectable);
142
+ if (!dependants) {
143
+ this.dependants.set(injectable, (dependants = new Set()));
144
+ }
145
+ dependants.add(dependant);
146
+ }
147
+ const isTransient = injectable.scope === Scope.Transient;
148
+ if (!isTransient && this.instances.has(injectable)) {
149
+ return Promise.resolve(this.instances.get(injectable).at(0).public);
150
+ }
151
+ else if (!isTransient && this.resolvers.has(injectable)) {
152
+ return this.resolvers.get(injectable);
153
+ }
154
+ else {
155
+ const isLazy = isLazyInjectable(injectable);
156
+ if (isLazy) {
157
+ const isOptional = isOptionalInjectable(injectable);
158
+ if (isOptional)
159
+ return Promise.resolve(undefined);
160
+ return Promise.reject(new Error(`No instance provided for ${label || 'an'} injectable:\n${stack}`));
161
+ }
162
+ else {
163
+ const resolution = this.createResolution(injectable).finally(() => {
164
+ this.resolvers.delete(injectable);
165
+ });
166
+ if (injectable.scope !== Scope.Transient) {
167
+ this.resolvers.set(injectable, resolution);
168
+ }
169
+ return resolution;
170
+ }
171
+ }
172
+ }
173
+ }
174
+ async createResolution(injectable) {
175
+ const { dependencies } = injectable;
176
+ const context = await this.createInjectableContext(dependencies, injectable);
177
+ const wrapper = {
178
+ private: null,
179
+ public: null,
180
+ context,
181
+ };
182
+ if (isFactoryInjectable(injectable)) {
183
+ wrapper.private = await Promise.resolve(injectable.factory(wrapper.context));
184
+ wrapper.public = injectable.pick(wrapper.private);
185
+ }
186
+ else if (isClassInjectable(injectable)) {
187
+ wrapper.private = new injectable(context);
188
+ wrapper.public = wrapper.private;
189
+ await wrapper.private.$onCreate();
190
+ }
191
+ else {
192
+ throw new Error('Invalid injectable type');
193
+ }
194
+ let instances = this.instances.get(injectable);
195
+ if (!instances) {
196
+ instances = [];
197
+ this.instances.set(injectable, instances);
198
+ }
199
+ instances.push(wrapper);
200
+ return wrapper.public;
201
+ }
202
+ createInjectFunction() {
203
+ const inject = (injectable, context) => {
204
+ const dependencies = {
205
+ ...injectable.dependencies,
206
+ };
207
+ for (const key in context) {
208
+ const dep = context[key];
209
+ if (isInjectable(dep) || isOptionalInjectable(dep)) {
210
+ dependencies[key] = dep;
211
+ }
212
+ else {
213
+ dependencies[key] = createValueInjectable(dep);
214
+ }
215
+ }
216
+ const newInjectable = isClassInjectable(injectable)
217
+ ? createExtendableClassInjectable(injectable, dependencies, Scope.Transient, 1)
218
+ : {
219
+ ...injectable,
220
+ dependencies,
221
+ scope: Scope.Transient,
222
+ stack: tryCaptureStackTrace(1),
223
+ };
224
+ return this.resolve(newInjectable);
225
+ };
226
+ const explicit = async (injectable, context) => {
227
+ if ('asyncDispose' in Symbol === false) {
228
+ throw new Error('Symbol.asyncDispose is not supported in this environment');
229
+ }
230
+ const instance = await inject(injectable, context);
231
+ const dispose = this.createDisposeFunction();
232
+ return Object.assign(instance, {
233
+ [Symbol.asyncDispose]: async () => {
234
+ await dispose(injectable, instance);
235
+ },
236
+ });
237
+ };
238
+ return Object.assign(inject, { explicit });
239
+ }
240
+ createDisposeFunction() {
241
+ return async (injectable, instance) => {
242
+ if (injectable.scope === Scope.Transient) {
243
+ assert(instance, 'Instance is required for transient injectable disposal');
244
+ const wrappers = this.instances.get(injectable);
245
+ if (wrappers) {
246
+ for (const wrapper of wrappers) {
247
+ if (wrapper.public === instance) {
248
+ await this.disposeInjectableInstance(injectable, wrapper.private, wrapper.context);
249
+ const index = wrappers.indexOf(wrapper);
250
+ wrappers.splice(index, 1);
251
+ }
252
+ }
253
+ if (wrappers.length === 0) {
254
+ this.instances.delete(injectable);
255
+ }
256
+ }
257
+ }
258
+ else {
259
+ await this.disposeInjectableInstances(injectable);
260
+ }
261
+ };
262
+ }
263
+ getDisposalOrder() {
264
+ const visited = new Set();
265
+ const result = [];
266
+ const visit = (injectable) => {
267
+ if (visited.has(injectable))
268
+ return;
269
+ visited.add(injectable);
270
+ const dependants = this.dependants.get(injectable);
271
+ if (dependants) {
272
+ for (const dependant of dependants) {
273
+ if (this.instances.has(dependant)) {
274
+ visit(dependant);
275
+ }
276
+ }
277
+ }
278
+ // Only add to result if this container owns the instance
279
+ if (this.instances.has(injectable)) {
280
+ result.push(injectable);
281
+ }
282
+ };
283
+ for (const injectable of this.instances.keys()) {
284
+ visit(injectable);
285
+ }
286
+ return result;
287
+ }
288
+ async disposeInjectableInstances(injectable) {
289
+ try {
290
+ if (this.instances.has(injectable)) {
291
+ const wrappers = this.instances.get(injectable);
292
+ await Promise.all(wrappers.map((wrapper) => this.disposeInjectableInstance(injectable, wrapper.private, wrapper.context)));
293
+ }
294
+ }
295
+ catch (cause) {
296
+ const error = new Error('Injectable disposal error. Potential memory leak', { cause });
297
+ this.application.logger.error(error);
298
+ }
299
+ finally {
300
+ this.instances.delete(injectable);
301
+ }
302
+ }
303
+ async disposeInjectableInstance(injectable, instance, context) {
304
+ if (isFactoryInjectable(injectable)) {
305
+ const { dispose } = injectable;
306
+ if (dispose)
307
+ await dispose(instance, context);
308
+ }
309
+ else if (isClassInjectable(injectable)) {
310
+ await instance.$onDispose();
311
+ }
312
+ }
278
313
  }
279
-
280
- //# sourceMappingURL=container.js.map
@@ -0,0 +1,18 @@
1
+ export declare enum Scope {
2
+ Global = "Global",
3
+ Connection = "Connection",
4
+ Call = "Call",
5
+ Transient = "Transient"
6
+ }
7
+ export declare enum Hook {
8
+ BeforeInitialize = "BeforeInitialize",
9
+ AfterInitialize = "AfterInitialize",
10
+ BeforeStart = "BeforeStart",
11
+ AfterStart = "AfterStart",
12
+ BeforeStop = "BeforeStop",
13
+ AfterStop = "AfterStop",
14
+ BeforeTerminate = "BeforeTerminate",
15
+ AfterTerminate = "AfterTerminate",
16
+ OnConnect = "OnConnect",
17
+ OnDisconnect = "OnDisconnect"
18
+ }