ts-ioc-container 56.1.0 → 56.2.0

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 (167) hide show
  1. package/cjm/ExecutionContext.js +2 -0
  2. package/cjm/container/AliasMap.js +25 -0
  3. package/cjm/container/Container.js +175 -0
  4. package/cjm/container/EmptyContainer.js +71 -0
  5. package/cjm/container/IContainer.js +6 -0
  6. package/cjm/errors/CannonSingletonApplyTwiceError.js +17 -0
  7. package/cjm/errors/ContainerDisposedError.js +12 -0
  8. package/cjm/errors/ContainerError.js +11 -0
  9. package/cjm/errors/ContainerNotFoundError.js +12 -0
  10. package/cjm/errors/DependencyMissingKeyError.js +12 -0
  11. package/cjm/errors/DependencyNotFoundError.js +12 -0
  12. package/cjm/errors/MethodNotImplementedError.js +12 -0
  13. package/cjm/errors/ProviderDisposedError.js +17 -0
  14. package/cjm/errors/UnexpectedHookResultError.js +12 -0
  15. package/cjm/errors/UnsupportedTokenTypeError.js +12 -0
  16. package/cjm/hooks/HookContext.js +42 -0
  17. package/cjm/hooks/HooksRunner.js +42 -0
  18. package/cjm/hooks/hook.js +55 -0
  19. package/cjm/hooks/injectProp.js +6 -0
  20. package/cjm/hooks/onConstruct.js +28 -0
  21. package/cjm/hooks/onConstructAsync.js +28 -0
  22. package/cjm/hooks/onContainerDisposed.js +18 -0
  23. package/cjm/index.js +141 -0
  24. package/cjm/injector/IInjector.js +14 -0
  25. package/cjm/injector/MetadataInjector.js +33 -0
  26. package/cjm/injector/ProxyInjector.js +18 -0
  27. package/cjm/injector/SimpleInjector.js +10 -0
  28. package/cjm/metadata/class.js +21 -0
  29. package/cjm/metadata/method.js +19 -0
  30. package/cjm/metadata/parameter.js +34 -0
  31. package/cjm/provider/IProvider.js +2 -0
  32. package/cjm/provider/Provider.js +80 -0
  33. package/cjm/registration/IRegistration.js +50 -0
  34. package/cjm/registration/Registration.js +85 -0
  35. package/cjm/select.js +16 -0
  36. package/cjm/token/BindToken.js +7 -0
  37. package/cjm/token/ClassToken.js +45 -0
  38. package/cjm/token/ConstantToken.js +25 -0
  39. package/cjm/token/FunctionToken.js +42 -0
  40. package/cjm/token/GroupAliasToken.js +50 -0
  41. package/cjm/token/GroupInstanceToken.js +33 -0
  42. package/cjm/token/InjectionToken.js +11 -0
  43. package/cjm/token/SingleAliasToken.js +50 -0
  44. package/cjm/token/SingleToken.js +48 -0
  45. package/cjm/token/toToken.js +29 -0
  46. package/cjm/utils/array.js +9 -0
  47. package/cjm/utils/basic.js +13 -0
  48. package/cjm/utils/debounce.js +16 -0
  49. package/cjm/utils/errorHandler.js +29 -0
  50. package/cjm/utils/fp.js +6 -0
  51. package/cjm/utils/once.js +20 -0
  52. package/cjm/utils/promise.js +5 -0
  53. package/cjm/utils/proxy.js +39 -0
  54. package/cjm/utils/shallowCache.js +23 -0
  55. package/cjm/utils/throttle.js +18 -0
  56. package/esm/ExecutionContext.js +1 -0
  57. package/esm/container/AliasMap.js +21 -0
  58. package/esm/container/Container.js +171 -0
  59. package/esm/container/EmptyContainer.js +67 -0
  60. package/esm/container/IContainer.js +3 -0
  61. package/esm/errors/CannonSingletonApplyTwiceError.js +13 -0
  62. package/esm/errors/ContainerDisposedError.js +8 -0
  63. package/esm/errors/ContainerError.js +7 -0
  64. package/esm/errors/ContainerNotFoundError.js +8 -0
  65. package/esm/errors/DependencyMissingKeyError.js +8 -0
  66. package/esm/errors/DependencyNotFoundError.js +8 -0
  67. package/esm/errors/MethodNotImplementedError.js +8 -0
  68. package/esm/errors/ProviderDisposedError.js +13 -0
  69. package/esm/errors/UnexpectedHookResultError.js +8 -0
  70. package/esm/errors/UnsupportedTokenTypeError.js +8 -0
  71. package/esm/hooks/HookContext.js +36 -0
  72. package/esm/hooks/HooksRunner.js +38 -0
  73. package/esm/hooks/hook.js +46 -0
  74. package/esm/hooks/injectProp.js +2 -0
  75. package/esm/hooks/onConstruct.js +23 -0
  76. package/esm/hooks/onConstructAsync.js +23 -0
  77. package/esm/hooks/onContainerDisposed.js +13 -0
  78. package/esm/index.js +46 -0
  79. package/esm/injector/IInjector.js +10 -0
  80. package/esm/injector/MetadataInjector.js +25 -0
  81. package/esm/injector/ProxyInjector.js +14 -0
  82. package/esm/injector/SimpleInjector.js +6 -0
  83. package/esm/metadata/class.js +12 -0
  84. package/esm/metadata/method.js +10 -0
  85. package/esm/metadata/parameter.js +25 -0
  86. package/esm/package.json +3 -0
  87. package/esm/provider/IProvider.js +1 -0
  88. package/esm/provider/Provider.js +76 -0
  89. package/esm/registration/IRegistration.js +35 -0
  90. package/esm/registration/Registration.js +81 -0
  91. package/esm/select.js +13 -0
  92. package/esm/token/BindToken.js +4 -0
  93. package/esm/token/ClassToken.js +41 -0
  94. package/esm/token/ConstantToken.js +21 -0
  95. package/esm/token/FunctionToken.js +38 -0
  96. package/esm/token/GroupAliasToken.js +45 -0
  97. package/esm/token/GroupInstanceToken.js +29 -0
  98. package/esm/token/InjectionToken.js +6 -0
  99. package/esm/token/SingleAliasToken.js +45 -0
  100. package/esm/token/SingleToken.js +44 -0
  101. package/esm/token/toToken.js +24 -0
  102. package/esm/utils/array.js +6 -0
  103. package/esm/utils/basic.js +9 -0
  104. package/esm/utils/debounce.js +12 -0
  105. package/esm/utils/errorHandler.js +24 -0
  106. package/esm/utils/fp.js +3 -0
  107. package/esm/utils/once.js +16 -0
  108. package/esm/utils/promise.js +1 -0
  109. package/esm/utils/proxy.js +33 -0
  110. package/esm/utils/shallowCache.js +19 -0
  111. package/esm/utils/throttle.js +14 -0
  112. package/package.json +1 -1
  113. package/typings/ExecutionContext.d.ts +4 -0
  114. package/typings/container/AliasMap.d.ts +8 -0
  115. package/typings/container/Container.d.ts +48 -0
  116. package/typings/container/EmptyContainer.d.ts +30 -0
  117. package/typings/container/IContainer.d.ts +56 -0
  118. package/typings/errors/CannonSingletonApplyTwiceError.d.ts +6 -0
  119. package/typings/errors/ContainerDisposedError.d.ts +5 -0
  120. package/typings/errors/ContainerError.d.ts +4 -0
  121. package/typings/errors/ContainerNotFoundError.d.ts +5 -0
  122. package/typings/errors/DependencyMissingKeyError.d.ts +5 -0
  123. package/typings/errors/DependencyNotFoundError.d.ts +5 -0
  124. package/typings/errors/MethodNotImplementedError.d.ts +5 -0
  125. package/typings/errors/ProviderDisposedError.d.ts +6 -0
  126. package/typings/errors/UnexpectedHookResultError.d.ts +5 -0
  127. package/typings/errors/UnsupportedTokenTypeError.d.ts +5 -0
  128. package/typings/hooks/HookContext.d.ts +35 -0
  129. package/typings/hooks/HooksRunner.d.ts +16 -0
  130. package/typings/hooks/hook.d.ts +20 -0
  131. package/typings/hooks/injectProp.d.ts +5 -0
  132. package/typings/hooks/onConstruct.d.ts +14 -0
  133. package/typings/hooks/onConstructAsync.d.ts +11 -0
  134. package/typings/hooks/onContainerDisposed.d.ts +9 -0
  135. package/typings/index.d.ts +48 -0
  136. package/typings/injector/IInjector.d.ts +17 -0
  137. package/typings/injector/MetadataInjector.d.ts +13 -0
  138. package/typings/injector/ProxyInjector.d.ts +6 -0
  139. package/typings/injector/SimpleInjector.d.ts +6 -0
  140. package/typings/metadata/class.d.ts +6 -0
  141. package/typings/metadata/method.d.ts +6 -0
  142. package/typings/metadata/parameter.d.ts +6 -0
  143. package/typings/provider/IProvider.d.ts +26 -0
  144. package/typings/provider/Provider.d.ts +26 -0
  145. package/typings/registration/IRegistration.d.ts +31 -0
  146. package/typings/registration/Registration.d.ts +28 -0
  147. package/typings/select.d.ts +12 -0
  148. package/typings/token/BindToken.d.ts +5 -0
  149. package/typings/token/ClassToken.d.ts +18 -0
  150. package/typings/token/ConstantToken.d.ts +10 -0
  151. package/typings/token/FunctionToken.d.ts +17 -0
  152. package/typings/token/GroupAliasToken.d.ts +21 -0
  153. package/typings/token/GroupInstanceToken.d.ts +15 -0
  154. package/typings/token/InjectionToken.d.ts +9 -0
  155. package/typings/token/SingleAliasToken.d.ts +21 -0
  156. package/typings/token/SingleToken.d.ts +19 -0
  157. package/typings/token/toToken.d.ts +6 -0
  158. package/typings/utils/array.d.ts +3 -0
  159. package/typings/utils/basic.d.ts +11 -0
  160. package/typings/utils/debounce.d.ts +1 -0
  161. package/typings/utils/errorHandler.d.ts +6 -0
  162. package/typings/utils/fp.d.ts +13 -0
  163. package/typings/utils/once.d.ts +8 -0
  164. package/typings/utils/promise.d.ts +1 -0
  165. package/typings/utils/proxy.d.ts +4 -0
  166. package/typings/utils/shallowCache.d.ts +1 -0
  167. package/typings/utils/throttle.d.ts +1 -0
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AliasMap = void 0;
4
+ class AliasMap {
5
+ aliasToKeySet = new Map();
6
+ getKeysByAlias(alias) {
7
+ return [...(this.aliasToKeySet.get(alias) ?? [])];
8
+ }
9
+ setAliasesByKey(key, aliases) {
10
+ for (const [alias, keySet] of this.aliasToKeySet) {
11
+ keySet.delete(key);
12
+ if (keySet.size === 0) {
13
+ this.aliasToKeySet.delete(alias);
14
+ }
15
+ }
16
+ for (const alias of aliases) {
17
+ const dependencyKeySet = this.aliasToKeySet.get(alias) ?? new Set();
18
+ this.aliasToKeySet.set(alias, dependencyKeySet.add(key));
19
+ }
20
+ }
21
+ destroy() {
22
+ this.aliasToKeySet.clear();
23
+ }
24
+ }
25
+ exports.AliasMap = AliasMap;
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Container = void 0;
4
+ const EmptyContainer_1 = require("./EmptyContainer");
5
+ const ContainerDisposedError_1 = require("../errors/ContainerDisposedError");
6
+ const MetadataInjector_1 = require("../injector/MetadataInjector");
7
+ const AliasMap_1 = require("./AliasMap");
8
+ const DependencyNotFoundError_1 = require("../errors/DependencyNotFoundError");
9
+ const basic_1 = require("../utils/basic");
10
+ const array_1 = require("../utils/array");
11
+ class Container {
12
+ isDisposed = false;
13
+ parent;
14
+ scopes = [];
15
+ instances = [];
16
+ registrations = [];
17
+ tags;
18
+ providers = new Map();
19
+ aliases = new AliasMap_1.AliasMap();
20
+ injector;
21
+ onConstructHookList = [];
22
+ onDisposeHookList = [];
23
+ constructor(options = {}) {
24
+ this.injector = options.injector ?? new MetadataInjector_1.MetadataInjector();
25
+ this.parent = options.parent ?? new EmptyContainer_1.EmptyContainer();
26
+ this.tags = new Set(options.tags ?? []);
27
+ }
28
+ register(key, provider, { aliases = [] } = {}) {
29
+ this.validateContainer();
30
+ this.providers.set(key, provider);
31
+ this.aliases.setAliasesByKey(key, aliases);
32
+ return this;
33
+ }
34
+ resolve(target, { args = [], child = this, lazy } = {}) {
35
+ this.validateContainer();
36
+ if (basic_1.Is.constructor(target)) {
37
+ return this.injector.resolve(this, target, { args, lazy });
38
+ }
39
+ const provider = this.providers.get(target);
40
+ return provider?.hasAccess({ invocationScope: child, providerScope: this, args })
41
+ ? provider.resolve(this, { args, lazy })
42
+ : this.parent.resolve(target, { args, child, lazy });
43
+ }
44
+ resolveByAlias(alias, { args = [], child = this, lazy, excludedKeys = [] } = {}) {
45
+ this.validateContainer();
46
+ const keys = [];
47
+ const deps = [];
48
+ for (const key of this.aliases.getKeysByAlias(alias).filter(array_1.Filter.exclude(excludedKeys))) {
49
+ const provider = this.findProviderByKeyOrFail(key);
50
+ if (!provider.hasAccess({ invocationScope: child, providerScope: this, args })) {
51
+ continue;
52
+ }
53
+ keys.push(key);
54
+ deps.push(provider.resolve(this, { args, lazy }));
55
+ }
56
+ const parentDeps = this.parent.resolveByAlias(alias, {
57
+ args,
58
+ child,
59
+ lazy,
60
+ excludedKeys: [...excludedKeys, ...keys],
61
+ });
62
+ return [...deps, ...parentDeps];
63
+ }
64
+ resolveOneByAlias(alias, { args = [], child = this, lazy } = {}) {
65
+ this.validateContainer();
66
+ const [key] = this.aliases.getKeysByAlias(alias);
67
+ const provider = key ? this.findProviderByKeyOrFail(key) : undefined;
68
+ return provider?.hasAccess({ invocationScope: child, providerScope: this, args })
69
+ ? provider.resolve(this, { args, lazy })
70
+ : this.parent.resolveOneByAlias(alias, { args, child, lazy });
71
+ }
72
+ createScope({ tags } = {}) {
73
+ this.validateContainer();
74
+ const scope = new Container({ injector: this.injector, parent: this, tags })
75
+ .addOnConstructHook(...this.onConstructHookList)
76
+ .addOnDisposeHook(...this.onDisposeHookList);
77
+ for (const registration of this.getRegistrations()) {
78
+ registration.applyTo(scope);
79
+ }
80
+ this.scopes.push(scope);
81
+ return scope;
82
+ }
83
+ dispose() {
84
+ this.validateContainer();
85
+ this.isDisposed = true;
86
+ while (this.onDisposeHookList.length) {
87
+ const onDispose = this.onDisposeHookList.shift();
88
+ onDispose(this);
89
+ }
90
+ this.parent.removeScope(this);
91
+ this.parent = new EmptyContainer_1.EmptyContainer();
92
+ for (const provider of this.providers.values()) {
93
+ provider.dispose();
94
+ }
95
+ this.providers.clear();
96
+ this.aliases.destroy();
97
+ this.instances = [];
98
+ this.registrations = [];
99
+ this.onConstructHookList.length = 0;
100
+ }
101
+ addRegistration(registration) {
102
+ this.registrations.push(registration);
103
+ registration.applyTo(this);
104
+ return this;
105
+ }
106
+ getRegistrations() {
107
+ return [...this.parent.getRegistrations(), ...this.registrations];
108
+ }
109
+ hasRegistration(key) {
110
+ return this.registrations.some((r) => r.getKeyOrFail() === key) || this.parent.hasRegistration(key);
111
+ }
112
+ addOnConstructHook(...hooks) {
113
+ this.onConstructHookList.push(...hooks);
114
+ return this;
115
+ }
116
+ addOnDisposeHook(...hooks) {
117
+ this.onDisposeHookList.push(...hooks);
118
+ return this;
119
+ }
120
+ addInstance(instance) {
121
+ this.instances.push(instance);
122
+ for (const onConstruct of this.onConstructHookList) {
123
+ onConstruct(instance, this);
124
+ }
125
+ }
126
+ getScopes() {
127
+ return [...this.scopes];
128
+ }
129
+ hasInstance(instance) {
130
+ return this.instances.includes(instance);
131
+ }
132
+ getScopeByInstanceOrFail(instance) {
133
+ this.validateContainer();
134
+ if (this.hasInstance(instance)) {
135
+ return this;
136
+ }
137
+ return this.parent.getScopeByInstanceOrFail(instance);
138
+ }
139
+ removeScope(child) {
140
+ this.scopes = this.scopes.filter((s) => s !== child);
141
+ }
142
+ useModule(module) {
143
+ module.applyTo(this);
144
+ return this;
145
+ }
146
+ getParent() {
147
+ return this.parent;
148
+ }
149
+ getInstances(cascade = false) {
150
+ if (!cascade) {
151
+ return [...this.instances];
152
+ }
153
+ return [...this.instances, ...this.scopes.flatMap((s) => s.getInstances(true))];
154
+ }
155
+ hasTag(tag) {
156
+ return this.tags.has(tag);
157
+ }
158
+ addTags(...tags) {
159
+ for (const tag of tags) {
160
+ this.tags.add(tag);
161
+ }
162
+ }
163
+ validateContainer() {
164
+ if (this.isDisposed) {
165
+ throw new ContainerDisposedError_1.ContainerDisposedError('Container is already disposed');
166
+ }
167
+ }
168
+ findProviderByKeyOrFail(key) {
169
+ if (!this.providers.has(key)) {
170
+ throw new DependencyNotFoundError_1.DependencyNotFoundError(`Provider ${key.toString()} does not exist`);
171
+ }
172
+ return this.providers.get(key);
173
+ }
174
+ }
175
+ exports.Container = Container;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmptyContainer = void 0;
4
+ const MethodNotImplementedError_1 = require("../errors/MethodNotImplementedError");
5
+ const DependencyNotFoundError_1 = require("../errors/DependencyNotFoundError");
6
+ const ContainerNotFoundError_1 = require("../errors/ContainerNotFoundError");
7
+ class EmptyContainer {
8
+ get isDisposed() {
9
+ throw new MethodNotImplementedError_1.MethodNotImplementedError();
10
+ }
11
+ addInstance(instance) { }
12
+ getParent() {
13
+ return undefined;
14
+ }
15
+ getScopes() {
16
+ return [];
17
+ }
18
+ getScopeByInstanceOrFail(instance) {
19
+ throw new ContainerNotFoundError_1.ContainerNotFoundError('Cannot find scope for the given instance');
20
+ }
21
+ getInstances() {
22
+ return [];
23
+ }
24
+ hasInstance(instance) {
25
+ return false;
26
+ }
27
+ createScope() {
28
+ throw new MethodNotImplementedError_1.MethodNotImplementedError();
29
+ }
30
+ dispose() {
31
+ throw new MethodNotImplementedError_1.MethodNotImplementedError();
32
+ }
33
+ register(key, value) {
34
+ throw new MethodNotImplementedError_1.MethodNotImplementedError();
35
+ }
36
+ hasTag(tag) {
37
+ throw new MethodNotImplementedError_1.MethodNotImplementedError();
38
+ }
39
+ addTags(...tags) {
40
+ throw new MethodNotImplementedError_1.MethodNotImplementedError();
41
+ }
42
+ getRegistrations() {
43
+ return [];
44
+ }
45
+ hasRegistration(key) {
46
+ return false;
47
+ }
48
+ removeScope() { }
49
+ useModule(module) {
50
+ throw new MethodNotImplementedError_1.MethodNotImplementedError();
51
+ }
52
+ addRegistration(registration) {
53
+ throw new MethodNotImplementedError_1.MethodNotImplementedError();
54
+ }
55
+ resolve(key, options) {
56
+ throw new DependencyNotFoundError_1.DependencyNotFoundError(`Cannot find ${key.toString()}`);
57
+ }
58
+ resolveByAlias(alias, options) {
59
+ return [];
60
+ }
61
+ resolveOneByAlias(alias, options) {
62
+ throw new DependencyNotFoundError_1.DependencyNotFoundError(`Cannot find alias ${alias.toString()}`);
63
+ }
64
+ addOnDisposeHook(...hooks) {
65
+ throw new MethodNotImplementedError_1.MethodNotImplementedError();
66
+ }
67
+ addOnConstructHook(...hooks) {
68
+ throw new MethodNotImplementedError_1.MethodNotImplementedError();
69
+ }
70
+ }
71
+ exports.EmptyContainer = EmptyContainer;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isDependencyKey = isDependencyKey;
4
+ function isDependencyKey(target) {
5
+ return typeof target === 'symbol' || typeof target === 'string';
6
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CannonSingletonApplyTwiceError = void 0;
4
+ const ContainerError_1 = require("./ContainerError");
5
+ class CannonSingletonApplyTwiceError extends ContainerError_1.ContainerError {
6
+ name = 'CannonSingletonApplyTwiceError';
7
+ constructor(message) {
8
+ super(message);
9
+ Object.setPrototypeOf(this, CannonSingletonApplyTwiceError.prototype);
10
+ }
11
+ static assert(isTrue, failMessage) {
12
+ if (!isTrue) {
13
+ throw new CannonSingletonApplyTwiceError(failMessage);
14
+ }
15
+ }
16
+ }
17
+ exports.CannonSingletonApplyTwiceError = CannonSingletonApplyTwiceError;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContainerDisposedError = void 0;
4
+ const ContainerError_1 = require("./ContainerError");
5
+ class ContainerDisposedError extends ContainerError_1.ContainerError {
6
+ name = 'ContainerDisposedError';
7
+ constructor(message) {
8
+ super(message);
9
+ Object.setPrototypeOf(this, ContainerDisposedError.prototype);
10
+ }
11
+ }
12
+ exports.ContainerDisposedError = ContainerDisposedError;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContainerError = void 0;
4
+ class ContainerError extends Error {
5
+ name = 'ContainerError';
6
+ constructor(message) {
7
+ super(message);
8
+ Object.setPrototypeOf(this, ContainerError.prototype);
9
+ }
10
+ }
11
+ exports.ContainerError = ContainerError;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContainerNotFoundError = void 0;
4
+ const ContainerError_1 = require("./ContainerError");
5
+ class ContainerNotFoundError extends ContainerError_1.ContainerError {
6
+ name = 'ContainerNotFoundError';
7
+ constructor(message) {
8
+ super(message);
9
+ Object.setPrototypeOf(this, ContainerNotFoundError.prototype);
10
+ }
11
+ }
12
+ exports.ContainerNotFoundError = ContainerNotFoundError;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DependencyMissingKeyError = void 0;
4
+ const ContainerError_1 = require("./ContainerError");
5
+ class DependencyMissingKeyError extends ContainerError_1.ContainerError {
6
+ name = 'DependencyMissingKeyError';
7
+ constructor(message) {
8
+ super(message);
9
+ Object.setPrototypeOf(this, DependencyMissingKeyError.prototype);
10
+ }
11
+ }
12
+ exports.DependencyMissingKeyError = DependencyMissingKeyError;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DependencyNotFoundError = void 0;
4
+ const ContainerError_1 = require("./ContainerError");
5
+ class DependencyNotFoundError extends ContainerError_1.ContainerError {
6
+ name = 'DependencyNotFoundError';
7
+ constructor(message) {
8
+ super(message);
9
+ Object.setPrototypeOf(this, DependencyNotFoundError.prototype);
10
+ }
11
+ }
12
+ exports.DependencyNotFoundError = DependencyNotFoundError;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MethodNotImplementedError = void 0;
4
+ const ContainerError_1 = require("./ContainerError");
5
+ class MethodNotImplementedError extends ContainerError_1.ContainerError {
6
+ name = 'MethodNotImplementedError';
7
+ constructor(message) {
8
+ super(message);
9
+ Object.setPrototypeOf(this, MethodNotImplementedError.prototype);
10
+ }
11
+ }
12
+ exports.MethodNotImplementedError = MethodNotImplementedError;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProviderDisposedError = void 0;
4
+ const ContainerError_1 = require("./ContainerError");
5
+ class ProviderDisposedError extends ContainerError_1.ContainerError {
6
+ name = 'ProviderDisposedError';
7
+ static assert(isTrue, failMessage) {
8
+ if (!isTrue) {
9
+ throw new ProviderDisposedError(failMessage);
10
+ }
11
+ }
12
+ constructor(message) {
13
+ super(message);
14
+ Object.setPrototypeOf(this, ProviderDisposedError.prototype);
15
+ }
16
+ }
17
+ exports.ProviderDisposedError = ProviderDisposedError;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UnexpectedHookResultError = void 0;
4
+ const ContainerError_1 = require("./ContainerError");
5
+ class UnexpectedHookResultError extends ContainerError_1.ContainerError {
6
+ name = 'UnexpectedHookResultError';
7
+ constructor(message) {
8
+ super(message);
9
+ Object.setPrototypeOf(this, UnexpectedHookResultError.prototype);
10
+ }
11
+ }
12
+ exports.UnexpectedHookResultError = UnexpectedHookResultError;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UnsupportedTokenTypeError = void 0;
4
+ const ContainerError_1 = require("./ContainerError");
5
+ class UnsupportedTokenTypeError extends ContainerError_1.ContainerError {
6
+ name = 'UnsupportedTokenTypeError';
7
+ constructor(message) {
8
+ super(message);
9
+ Object.setPrototypeOf(this, UnsupportedTokenTypeError.prototype);
10
+ }
11
+ }
12
+ exports.UnsupportedTokenTypeError = UnsupportedTokenTypeError;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createHookContextFactory = exports.createHookContext = exports.HookContext = void 0;
4
+ const proxy_1 = require("../utils/proxy");
5
+ const MetadataInjector_1 = require("../injector/MetadataInjector");
6
+ class HookContext {
7
+ scope;
8
+ methodName;
9
+ instance;
10
+ initialArgs = [];
11
+ constructor(instance, scope, methodName) {
12
+ this.scope = scope;
13
+ this.methodName = methodName;
14
+ this.instance = (0, proxy_1.isProxy)(instance) ? (0, proxy_1.getProxyTarget)(instance) : instance;
15
+ }
16
+ resolveArgs(...args) {
17
+ return (0, MetadataInjector_1.resolveArgs)(this.instance.constructor, this.methodName)(this.scope, {
18
+ args: [...this.initialArgs, ...args],
19
+ });
20
+ }
21
+ invokeMethod({ args = this.resolveArgs() } = {}) {
22
+ return this.instance[this.methodName](...args);
23
+ }
24
+ setProperty(fn) {
25
+ this.instance[this.methodName] = fn.resolve(this.scope);
26
+ }
27
+ getProperty() {
28
+ return this.instance[this.methodName];
29
+ }
30
+ setInitialArgs(...args) {
31
+ this.initialArgs = args;
32
+ return this;
33
+ }
34
+ getInitialArgs() {
35
+ return this.initialArgs;
36
+ }
37
+ }
38
+ exports.HookContext = HookContext;
39
+ const createHookContext = (Target, scope, methodName = 'constructor') => new HookContext(Target, scope, methodName);
40
+ exports.createHookContext = createHookContext;
41
+ const createHookContextFactory = ({ args = [] } = {}) => (Target, scope, methodName) => (0, exports.createHookContext)(Target, scope, methodName).setInitialArgs(...args);
42
+ exports.createHookContextFactory = createHookContextFactory;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HooksRunner = void 0;
4
+ const HookContext_1 = require("./HookContext");
5
+ const hook_1 = require("./hook");
6
+ const UnexpectedHookResultError_1 = require("../errors/UnexpectedHookResultError");
7
+ const promise_1 = require("../utils/promise");
8
+ class HooksRunner {
9
+ key;
10
+ constructor(key) {
11
+ this.key = key;
12
+ }
13
+ hasHooks(target) {
14
+ return (0, hook_1.hasHooks)(target, this.key);
15
+ }
16
+ execute(target, { scope, createContext = HookContext_1.createHookContext, mapContext = (context) => context, predicate = () => true, }) {
17
+ const hooks = Array.from((0, hook_1.getHooks)(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
18
+ const runMethodHooks = (methodName, executions) => {
19
+ const context = mapContext(createContext(target, scope, methodName));
20
+ for (const execute of executions) {
21
+ const result = execute(context);
22
+ if (result instanceof Promise) {
23
+ throw new UnexpectedHookResultError_1.UnexpectedHookResultError(`Hook ${methodName} returned a promise, use runHooksAsync instead`);
24
+ }
25
+ }
26
+ };
27
+ for (const [methodName, executions] of hooks) {
28
+ runMethodHooks(methodName, executions.map(hook_1.toHookFn));
29
+ }
30
+ }
31
+ async executeAsync(target, { scope, createContext = HookContext_1.createHookContext, mapContext = (context) => context, predicate = () => true, }) {
32
+ const hooks = Array.from((0, hook_1.getHooks)(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
33
+ const runMethodHooks = async (methodName, executions) => {
34
+ const context = mapContext(createContext(target, scope, methodName));
35
+ for (const execute of executions) {
36
+ await (0, promise_1.promisify)(execute(context));
37
+ }
38
+ };
39
+ return Promise.all(hooks.map(([methodName, executions]) => runMethodHooks(methodName, executions.map(hook_1.toHookFn))));
40
+ }
41
+ }
42
+ exports.HooksRunner = HooksRunner;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hook = exports.toHookFn = exports.prepend = exports.append = exports.prependHooks = exports.appendHooks = void 0;
4
+ exports.getHooks = getHooks;
5
+ exports.hasHooks = hasHooks;
6
+ const basic_1 = require("../utils/basic");
7
+ const proxy_1 = require("../utils/proxy");
8
+ const appendHooks = (...fns) => (...prev) => [...prev, ...fns];
9
+ exports.appendHooks = appendHooks;
10
+ const prependHooks = (...fns) => (...prev) => [...fns, ...prev];
11
+ exports.prependHooks = prependHooks;
12
+ exports.append = exports.appendHooks;
13
+ exports.prepend = exports.prependHooks;
14
+ const isHookClassConstructor = (execute) => {
15
+ return basic_1.Is.constructor(execute) && execute.prototype.execute;
16
+ };
17
+ const toHookFn = (execute) => isHookClassConstructor(execute) ? (context) => context.scope.resolve(execute).execute(context) : execute;
18
+ exports.toHookFn = toHookFn;
19
+ const getReflectionTarget = (target) => {
20
+ return (0, proxy_1.isProxy)(target) ? (0, proxy_1.getProxyTarget)(target) : target;
21
+ };
22
+ const getConstructorChain = (ctor) => {
23
+ const chain = [];
24
+ let current = ctor;
25
+ while (typeof current === 'function' && current !== Function.prototype) {
26
+ chain.push(current);
27
+ current = Object.getPrototypeOf(current);
28
+ }
29
+ return chain;
30
+ };
31
+ function getHooks(target, key) {
32
+ const reflectionTarget = getReflectionTarget(target);
33
+ const merged = new Map();
34
+ for (const ctor of getConstructorChain(reflectionTarget.constructor).reverse()) {
35
+ const ownHooks = Reflect.getOwnMetadata(key, ctor);
36
+ if (ownHooks) {
37
+ for (const [methodName, fns] of ownHooks) {
38
+ merged.set(methodName, fns);
39
+ }
40
+ }
41
+ }
42
+ return merged;
43
+ }
44
+ function hasHooks(target, key) {
45
+ const reflectionTarget = getReflectionTarget(target);
46
+ return getConstructorChain(reflectionTarget.constructor).some((ctor) => Reflect.hasOwnMetadata(key, ctor));
47
+ }
48
+ const hook = (key, mapFn) => (target, propertyKey) => {
49
+ const hooks = Reflect.hasOwnMetadata(key, target.constructor)
50
+ ? Reflect.getOwnMetadata(key, target.constructor)
51
+ : new Map();
52
+ hooks.set(propertyKey, mapFn(...(hooks.get(propertyKey) ?? [])));
53
+ Reflect.defineMetadata(key, hooks, target.constructor);
54
+ };
55
+ exports.hook = hook;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.injectProp = void 0;
4
+ const toToken_1 = require("../token/toToken");
5
+ const injectProp = (fn) => (context) => context.setProperty((0, toToken_1.toToken)(fn));
6
+ exports.injectProp = injectProp;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AddOnConstructHookModule = exports.onConstruct = exports.onConstructHooksRunner = void 0;
4
+ const hook_1 = require("./hook");
5
+ const HooksRunner_1 = require("./HooksRunner");
6
+ exports.onConstructHooksRunner = new HooksRunner_1.HooksRunner('onConstruct');
7
+ const onConstruct = (...fns) => (0, hook_1.hook)('onConstruct', (0, hook_1.prependHooks)(...fns));
8
+ exports.onConstruct = onConstruct;
9
+ class AddOnConstructHookModule {
10
+ onException;
11
+ constructor(onException) {
12
+ this.onException = onException;
13
+ }
14
+ applyTo(container) {
15
+ container.addOnConstructHook((instance, scope) => {
16
+ try {
17
+ exports.onConstructHooksRunner.execute(instance, { scope });
18
+ }
19
+ catch (ex) {
20
+ if (!this.onException) {
21
+ throw ex;
22
+ }
23
+ this.onException(ex, { scope });
24
+ }
25
+ });
26
+ }
27
+ }
28
+ exports.AddOnConstructHookModule = AddOnConstructHookModule;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AddOnConstructAsyncHookModule = exports.onConstructAsync = exports.onConstructAsyncHooksRunner = void 0;
4
+ const hook_1 = require("./hook");
5
+ const HooksRunner_1 = require("./HooksRunner");
6
+ exports.onConstructAsyncHooksRunner = new HooksRunner_1.HooksRunner('onConstructAsync');
7
+ const onConstructAsync = (...fns) => (0, hook_1.hook)('onConstructAsync', (0, hook_1.prependHooks)(...fns));
8
+ exports.onConstructAsync = onConstructAsync;
9
+ class AddOnConstructAsyncHookModule {
10
+ onException;
11
+ constructor(onException) {
12
+ this.onException = onException;
13
+ }
14
+ applyTo(container) {
15
+ container.addOnConstructHook((instance, scope) => {
16
+ if (!exports.onConstructAsyncHooksRunner.hasHooks(instance)) {
17
+ return;
18
+ }
19
+ exports.onConstructAsyncHooksRunner.executeAsync(instance, { scope }).catch((ex) => {
20
+ if (!this.onException) {
21
+ throw ex;
22
+ }
23
+ this.onException(ex, { scope });
24
+ });
25
+ });
26
+ }
27
+ }
28
+ exports.AddOnConstructAsyncHookModule = AddOnConstructAsyncHookModule;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AddOnDisposeHookModule = exports.onContainerDisposed = exports.onContainerDisposedHooksRunner = void 0;
4
+ const hook_1 = require("./hook");
5
+ const HooksRunner_1 = require("./HooksRunner");
6
+ exports.onContainerDisposedHooksRunner = new HooksRunner_1.HooksRunner('onContainerDisposed');
7
+ const onContainerDisposed = (...fns) => (0, hook_1.hook)('onContainerDisposed', (0, hook_1.prependHooks)(...fns));
8
+ exports.onContainerDisposed = onContainerDisposed;
9
+ class AddOnDisposeHookModule {
10
+ applyTo(container) {
11
+ container.addOnDisposeHook((scope) => {
12
+ for (const instance of scope.getInstances()) {
13
+ exports.onContainerDisposedHooksRunner.execute(instance, { scope });
14
+ }
15
+ });
16
+ }
17
+ }
18
+ exports.AddOnDisposeHookModule = AddOnDisposeHookModule;