@codefast/di 0.5.0-canary.5 → 0.5.0-canary.7

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 (214) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +73 -496
  3. package/dist/binding.d.ts +211 -0
  4. package/dist/binding.d.ts.map +1 -0
  5. package/dist/binding.js +46 -0
  6. package/dist/binding.js.map +1 -0
  7. package/dist/{constructor-type.d.mts → constructor-type.d.ts} +3 -5
  8. package/dist/constructor-type.d.ts.map +1 -0
  9. package/dist/constructor-type.js +2 -0
  10. package/dist/constructor-type.js.map +1 -0
  11. package/dist/container/binding-builders.d.ts +35 -0
  12. package/dist/container/binding-builders.d.ts.map +1 -0
  13. package/dist/container/binding-builders.js +247 -0
  14. package/dist/container/binding-builders.js.map +1 -0
  15. package/dist/container/container.d.ts +58 -0
  16. package/dist/container/container.d.ts.map +1 -0
  17. package/dist/container/container.js +641 -0
  18. package/dist/container/container.js.map +1 -0
  19. package/dist/decorators/inject.d.ts +57 -0
  20. package/dist/decorators/inject.d.ts.map +1 -0
  21. package/dist/decorators/inject.js +145 -0
  22. package/dist/decorators/inject.js.map +1 -0
  23. package/dist/decorators/injectable.d.ts +29 -0
  24. package/dist/decorators/injectable.d.ts.map +1 -0
  25. package/dist/decorators/injectable.js +53 -0
  26. package/dist/decorators/injectable.js.map +1 -0
  27. package/dist/decorators/lifecycle-decorators.d.ts +9 -0
  28. package/dist/decorators/lifecycle-decorators.d.ts.map +1 -0
  29. package/dist/decorators/lifecycle-decorators.js +40 -0
  30. package/dist/decorators/lifecycle-decorators.js.map +1 -0
  31. package/dist/errors.d.ts +150 -0
  32. package/dist/errors.d.ts.map +1 -0
  33. package/dist/errors.js +197 -0
  34. package/dist/errors.js.map +1 -0
  35. package/dist/index.d.ts +30 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +25 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/introspection/dependency-graph.d.ts +40 -0
  40. package/dist/introspection/dependency-graph.d.ts.map +1 -0
  41. package/dist/introspection/dependency-graph.js +66 -0
  42. package/dist/introspection/dependency-graph.js.map +1 -0
  43. package/dist/introspection/graph-adapters/cytoscape.d.ts +33 -0
  44. package/dist/introspection/graph-adapters/cytoscape.d.ts.map +1 -0
  45. package/dist/introspection/graph-adapters/cytoscape.js +30 -0
  46. package/dist/introspection/graph-adapters/cytoscape.js.map +1 -0
  47. package/dist/introspection/graph-adapters/dot.d.ts +6 -0
  48. package/dist/introspection/graph-adapters/dot.d.ts.map +1 -0
  49. package/dist/introspection/graph-adapters/dot.js +18 -0
  50. package/dist/introspection/graph-adapters/dot.js.map +1 -0
  51. package/dist/introspection/graph-adapters/reactflow.d.ts +38 -0
  52. package/dist/introspection/graph-adapters/reactflow.d.ts.map +1 -0
  53. package/dist/introspection/graph-adapters/reactflow.js +33 -0
  54. package/dist/introspection/graph-adapters/reactflow.js.map +1 -0
  55. package/dist/introspection/inspector.d.ts +39 -0
  56. package/dist/introspection/inspector.d.ts.map +1 -0
  57. package/dist/introspection/inspector.js +82 -0
  58. package/dist/introspection/inspector.js.map +1 -0
  59. package/dist/metadata/{metadata-keys.d.mts → metadata-keys.d.ts} +5 -7
  60. package/dist/metadata/metadata-keys.d.ts.map +1 -0
  61. package/dist/metadata/metadata-keys.js +25 -0
  62. package/dist/metadata/metadata-keys.js.map +1 -0
  63. package/dist/metadata/metadata-reader-token.d.ts +7 -0
  64. package/dist/metadata/metadata-reader-token.d.ts.map +1 -0
  65. package/dist/metadata/metadata-reader-token.js +6 -0
  66. package/dist/metadata/metadata-reader-token.js.map +1 -0
  67. package/dist/metadata/metadata-types.d.ts +48 -0
  68. package/dist/metadata/metadata-types.d.ts.map +1 -0
  69. package/dist/metadata/metadata-types.js +2 -0
  70. package/dist/metadata/metadata-types.js.map +1 -0
  71. package/dist/metadata/symbol-metadata-reader.d.ts +20 -0
  72. package/dist/metadata/symbol-metadata-reader.d.ts.map +1 -0
  73. package/dist/metadata/symbol-metadata-reader.js +34 -0
  74. package/dist/metadata/symbol-metadata-reader.js.map +1 -0
  75. package/dist/module.d.ts +67 -0
  76. package/dist/module.d.ts.map +1 -0
  77. package/dist/module.js +54 -0
  78. package/dist/module.js.map +1 -0
  79. package/dist/registry.d.ts +33 -0
  80. package/dist/registry.d.ts.map +1 -0
  81. package/dist/registry.js +249 -0
  82. package/dist/registry.js.map +1 -0
  83. package/dist/resolution/binding-scope.d.ts +10 -0
  84. package/dist/resolution/binding-scope.d.ts.map +1 -0
  85. package/dist/resolution/binding-scope.js +24 -0
  86. package/dist/resolution/binding-scope.js.map +1 -0
  87. package/dist/resolution/binding-select.d.ts +16 -0
  88. package/dist/resolution/binding-select.d.ts.map +1 -0
  89. package/dist/resolution/binding-select.js +143 -0
  90. package/dist/resolution/binding-select.js.map +1 -0
  91. package/dist/resolution/constraints.d.ts +51 -0
  92. package/dist/resolution/constraints.d.ts.map +1 -0
  93. package/dist/resolution/constraints.js +88 -0
  94. package/dist/resolution/constraints.js.map +1 -0
  95. package/dist/resolution/environment.d.ts +47 -0
  96. package/dist/resolution/environment.d.ts.map +1 -0
  97. package/dist/resolution/environment.js +100 -0
  98. package/dist/resolution/environment.js.map +1 -0
  99. package/dist/resolution/instantiation-plan.d.ts +67 -0
  100. package/dist/resolution/instantiation-plan.d.ts.map +1 -0
  101. package/dist/resolution/instantiation-plan.js +163 -0
  102. package/dist/resolution/instantiation-plan.js.map +1 -0
  103. package/dist/resolution/lifecycle.d.ts +21 -0
  104. package/dist/resolution/lifecycle.d.ts.map +1 -0
  105. package/dist/resolution/lifecycle.js +178 -0
  106. package/dist/resolution/lifecycle.js.map +1 -0
  107. package/dist/resolution/resolution-path.d.ts +31 -0
  108. package/dist/resolution/resolution-path.d.ts.map +1 -0
  109. package/dist/resolution/resolution-path.js +53 -0
  110. package/dist/resolution/resolution-path.js.map +1 -0
  111. package/dist/resolution/resolve-options.d.ts +19 -0
  112. package/dist/resolution/resolve-options.d.ts.map +1 -0
  113. package/dist/resolution/resolve-options.js +32 -0
  114. package/dist/resolution/resolve-options.js.map +1 -0
  115. package/dist/resolution/resolver.d.ts +35 -0
  116. package/dist/resolution/resolver.d.ts.map +1 -0
  117. package/dist/resolution/resolver.js +1320 -0
  118. package/dist/resolution/resolver.js.map +1 -0
  119. package/dist/resolution/scope.d.ts +32 -0
  120. package/dist/resolution/scope.d.ts.map +1 -0
  121. package/dist/resolution/scope.js +76 -0
  122. package/dist/resolution/scope.js.map +1 -0
  123. package/dist/token.d.ts +23 -0
  124. package/dist/token.d.ts.map +1 -0
  125. package/dist/token.js +22 -0
  126. package/dist/token.js.map +1 -0
  127. package/dist/types.d.ts +90 -0
  128. package/dist/types.d.ts.map +1 -0
  129. package/dist/types.js +2 -0
  130. package/dist/types.js.map +1 -0
  131. package/package.json +143 -120
  132. package/src/binding.ts +38 -22
  133. package/src/container/binding-builders.ts +397 -0
  134. package/src/container/container.ts +838 -0
  135. package/src/decorators/inject.ts +16 -3
  136. package/src/decorators/injectable.ts +3 -3
  137. package/src/index.ts +14 -7
  138. package/src/{dependency-graph.ts → introspection/dependency-graph.ts} +1 -1
  139. package/src/{graph-adapters → introspection/graph-adapters}/cytoscape.ts +1 -1
  140. package/src/{graph-adapters → introspection/graph-adapters}/dot.ts +1 -1
  141. package/src/{graph-adapters → introspection/graph-adapters}/reactflow.ts +13 -2
  142. package/src/{inspector.ts → introspection/inspector.ts} +26 -21
  143. package/src/metadata/symbol-metadata-reader.ts +4 -4
  144. package/src/module.ts +14 -6
  145. package/src/registry.ts +115 -61
  146. package/src/{binding-select.ts → resolution/binding-select.ts} +16 -3
  147. package/src/{environment.ts → resolution/environment.ts} +35 -35
  148. package/src/resolution/instantiation-plan.ts +240 -0
  149. package/src/{lifecycle.ts → resolution/lifecycle.ts} +20 -13
  150. package/src/resolution/resolution-path.ts +77 -0
  151. package/src/resolution/resolver.ts +1755 -0
  152. package/src/{scope.ts → resolution/scope.ts} +35 -18
  153. package/src/token.ts +0 -3
  154. package/dist/binding-scope.d.mts +0 -13
  155. package/dist/binding-scope.mjs +0 -21
  156. package/dist/binding-select.d.mts +0 -19
  157. package/dist/binding-select.mjs +0 -72
  158. package/dist/binding.d.mts +0 -191
  159. package/dist/binding.mjs +0 -36
  160. package/dist/constraints.d.mts +0 -55
  161. package/dist/constraints.mjs +0 -87
  162. package/dist/constructor-type.mjs +0 -1
  163. package/dist/container.d.mts +0 -62
  164. package/dist/container.mjs +0 -741
  165. package/dist/decorators/inject.d.mts +0 -49
  166. package/dist/decorators/inject.mjs +0 -136
  167. package/dist/decorators/injectable.d.mts +0 -32
  168. package/dist/decorators/injectable.mjs +0 -57
  169. package/dist/decorators/lifecycle-decorators.d.mts +0 -11
  170. package/dist/decorators/lifecycle-decorators.mjs +0 -38
  171. package/dist/dependency-graph.d.mts +0 -43
  172. package/dist/dependency-graph.mjs +0 -63
  173. package/dist/environment.d.mts +0 -55
  174. package/dist/environment.mjs +0 -98
  175. package/dist/errors.d.mts +0 -153
  176. package/dist/errors.mjs +0 -197
  177. package/dist/graph-adapters/cytoscape.d.mts +0 -36
  178. package/dist/graph-adapters/cytoscape.mjs +0 -26
  179. package/dist/graph-adapters/dot.d.mts +0 -9
  180. package/dist/graph-adapters/dot.mjs +0 -20
  181. package/dist/graph-adapters/reactflow.d.mts +0 -41
  182. package/dist/graph-adapters/reactflow.mjs +0 -29
  183. package/dist/index.d.mts +0 -18
  184. package/dist/index.mjs +0 -12
  185. package/dist/inspector.d.mts +0 -48
  186. package/dist/inspector.mjs +0 -71
  187. package/dist/lifecycle.d.mts +0 -25
  188. package/dist/lifecycle.mjs +0 -118
  189. package/dist/metadata/metadata-keys.mjs +0 -27
  190. package/dist/metadata/metadata-reader-token.d.mts +0 -10
  191. package/dist/metadata/metadata-reader-token.mjs +0 -8
  192. package/dist/metadata/metadata-types.d.mts +0 -51
  193. package/dist/metadata/metadata-types.mjs +0 -1
  194. package/dist/metadata/symbol-metadata-reader.d.mts +0 -23
  195. package/dist/metadata/symbol-metadata-reader.mjs +0 -29
  196. package/dist/module.d.mts +0 -62
  197. package/dist/module.mjs +0 -42
  198. package/dist/registry.d.mts +0 -45
  199. package/dist/registry.mjs +0 -163
  200. package/dist/resolve-options.d.mts +0 -22
  201. package/dist/resolve-options.mjs +0 -28
  202. package/dist/resolver.d.mts +0 -94
  203. package/dist/resolver.mjs +0 -767
  204. package/dist/scope.d.mts +0 -28
  205. package/dist/scope.mjs +0 -58
  206. package/dist/token.d.mts +0 -25
  207. package/dist/token.mjs +0 -22
  208. package/dist/types.d.mts +0 -92
  209. package/dist/types.mjs +0 -1
  210. package/src/container.ts +0 -1141
  211. package/src/resolver.ts +0 -1626
  212. /package/src/{binding-scope.ts → resolution/binding-scope.ts} +0 -0
  213. /package/src/{constraints.ts → resolution/constraints.ts} +0 -0
  214. /package/src/{resolve-options.ts → resolution/resolve-options.ts} +0 -0
@@ -1,741 +0,0 @@
1
- import { effectiveBindingScope } from "./binding-scope.mjs";
2
- import { AsyncModuleLoadError, CircularDependencyError, DisposedContainerError, InternalError, RebindUnboundTokenError, ScopeViolationError, SyncDisposalNotSupportedError } from "./errors.mjs";
3
- import { DEFAULT_BINDING_SLOT, generateBindingId } from "./binding.mjs";
4
- import { tokenName } from "./token.mjs";
5
- import { bindingSlotToResolveOptions, injectionSlotToResolveOptions } from "./resolve-options.mjs";
6
- import { normalizeToDescriptor } from "./decorators/inject.mjs";
7
- import { buildDependencyGraph } from "./dependency-graph.mjs";
8
- import { Inspector } from "./inspector.mjs";
9
- import { LifecycleManager } from "./lifecycle.mjs";
10
- import { MetadataReaderToken } from "./metadata/metadata-reader-token.mjs";
11
- import { defaultMetadataReader } from "./metadata/symbol-metadata-reader.mjs";
12
- import { isSyncModule } from "./module.mjs";
13
- import { BindingRegistry } from "./registry.mjs";
14
- import { DependencyResolver } from "./resolver.mjs";
15
- import { ScopeManager } from "./scope.mjs";
16
- //#region src/container.ts
17
- var DefaultContainer = class DefaultContainer {
18
- _disposed = false;
19
- _registry;
20
- _scope;
21
- _lifecycle;
22
- _resolver;
23
- _inspector;
24
- _parent;
25
- _moduleRefs = /* @__PURE__ */ new Map();
26
- _moduleBindingIds = /* @__PURE__ */ new Map();
27
- constructor(parent) {
28
- this._parent = parent;
29
- this._registry = new BindingRegistry();
30
- this._scope = new ScopeManager(parent !== void 0);
31
- this._lifecycle = new LifecycleManager();
32
- this._inspector = new Inspector(this._registry, this._scope, parent !== void 0, () => this._disposed);
33
- this._initResolver();
34
- }
35
- _initResolver() {
36
- const metadataReader = this._getMetadataReader();
37
- const parentResolver = this._parent?._resolver;
38
- this._resolver = new DependencyResolver(this._registry, this._scope, this._lifecycle, metadataReader, this, parentResolver);
39
- }
40
- _getMetadataReader() {
41
- if (this._registry.getAll(MetadataReaderToken).length > 0) try {
42
- return this._resolver.resolve(MetadataReaderToken, void 0, [], []);
43
- } catch {}
44
- if (this._parent !== void 0) return this._parent._getMetadataReader();
45
- return defaultMetadataReader;
46
- }
47
- get isDisposed() {
48
- return this._disposed;
49
- }
50
- bind(token) {
51
- this._assertNotDisposed();
52
- return this._createBindToBuilder(token);
53
- }
54
- _createBindToBuilder(token, moduleRef) {
55
- const registry = this._registry;
56
- const commitBinding = (binding, previousId) => {
57
- if (previousId !== void 0) {
58
- registry.removeById(previousId);
59
- if (moduleRef !== void 0) {
60
- const ids = this._moduleBindingIds.get(moduleRef);
61
- if (ids !== void 0) {
62
- const idx = ids.indexOf(previousId);
63
- if (idx !== -1) ids.splice(idx, 1);
64
- }
65
- }
66
- }
67
- registry.add(binding);
68
- if (moduleRef !== void 0) {
69
- let ids = this._moduleBindingIds.get(moduleRef);
70
- if (ids === void 0) {
71
- ids = [];
72
- this._moduleBindingIds.set(moduleRef, ids);
73
- }
74
- ids.push(binding.id);
75
- }
76
- return binding.id;
77
- };
78
- return new BindingEntry(token, commitBinding);
79
- }
80
- unbind(tokenOrId) {
81
- this._assertNotDisposed();
82
- this._unbindSync(tokenOrId);
83
- }
84
- /** Remove bindings from registry + scope and collect [binding, instance] pairs for deactivation. */
85
- _collectDeactivationPairs(tokenOrId) {
86
- const pairs = [];
87
- for (const binding of this._getBindingsForTokenOrId(tokenOrId)) {
88
- this._registry.removeById(binding.id);
89
- if (this._scope.hasSingleton(binding.id)) {
90
- pairs.push([binding, this._scope.getSingleton(binding.id)]);
91
- this._scope.deleteSingleton(binding.id);
92
- }
93
- }
94
- return pairs;
95
- }
96
- /** Drain singleton scope entries for a set of already-removed bindings. */
97
- _drainSingletons(bindings) {
98
- const pairs = [];
99
- for (const binding of bindings) if (this._scope.hasSingleton(binding.id)) {
100
- pairs.push([binding, this._scope.getSingleton(binding.id)]);
101
- this._scope.deleteSingleton(binding.id);
102
- }
103
- return pairs;
104
- }
105
- _unbindSync(tokenOrId) {
106
- const reader = this._getMetadataReader();
107
- for (const [binding, instance] of this._collectDeactivationPairs(tokenOrId)) this._lifecycle.runDeactivationSync(binding, instance, reader);
108
- }
109
- async unbindAsync(tokenOrId) {
110
- this._assertNotDisposed();
111
- const reader = this._getMetadataReader();
112
- for (const [binding, instance] of this._collectDeactivationPairs(tokenOrId)) await this._lifecycle.runDeactivation(binding, instance, reader);
113
- }
114
- unbindAll() {
115
- this._assertNotDisposed();
116
- const reader = this._getMetadataReader();
117
- for (const [binding, instance] of this._drainSingletons(this._registry.clear())) this._lifecycle.runDeactivationSync(binding, instance, reader);
118
- }
119
- async unbindAllAsync() {
120
- this._assertNotDisposed();
121
- const reader = this._getMetadataReader();
122
- for (const [binding, instance] of this._drainSingletons(this._registry.clear())) await this._lifecycle.runDeactivation(binding, instance, reader);
123
- }
124
- rebind(token) {
125
- this._assertNotDisposed();
126
- if (!this._registry.has(token)) throw new RebindUnboundTokenError(tokenName(token));
127
- this._unbindSync(token);
128
- return this._createBindToBuilder(token);
129
- }
130
- _getBindingsForTokenOrId(tokenOrId) {
131
- if (typeof tokenOrId === "string") {
132
- const binding = this._registry.getById(tokenOrId);
133
- return binding !== void 0 ? [binding] : [];
134
- }
135
- return [...this._registry.getAll(tokenOrId)];
136
- }
137
- load(...modules) {
138
- this._assertNotDisposed();
139
- this._loadSyncModules(modules);
140
- }
141
- _loadSyncModules(modules) {
142
- const toLoad = this._collectModuleDeps(modules);
143
- for (const module of toLoad) {
144
- if (!isSyncModule(module)) throw new AsyncModuleLoadError(module.name);
145
- const moduleRef = module;
146
- const existing = this._moduleRefs.get(moduleRef);
147
- if (existing !== void 0) {
148
- this._moduleRefs.set(moduleRef, existing + 1);
149
- continue;
150
- }
151
- this._moduleRefs.set(moduleRef, 1);
152
- const builder = this._createModuleBuilder(moduleRef);
153
- module._setup(builder);
154
- }
155
- }
156
- _collectModuleDeps(modules) {
157
- const seen = /* @__PURE__ */ new Set();
158
- const result = [];
159
- const visit = (module) => {
160
- const moduleRef = module;
161
- if (seen.has(moduleRef)) return;
162
- seen.add(moduleRef);
163
- result.push(module);
164
- };
165
- for (const module of modules) visit(module);
166
- return result;
167
- }
168
- async loadAsync(...modules) {
169
- this._assertNotDisposed();
170
- for (const module of modules) await this._loadOneModuleAsync(module);
171
- }
172
- async _loadOneModuleAsync(module) {
173
- const moduleRef = module;
174
- const existing = this._moduleRefs.get(moduleRef);
175
- if (existing !== void 0) {
176
- this._moduleRefs.set(moduleRef, existing + 1);
177
- return;
178
- }
179
- this._moduleRefs.set(moduleRef, 1);
180
- if (isSyncModule(module)) {
181
- const builder = this._createModuleBuilder(moduleRef);
182
- module._setup(builder);
183
- } else {
184
- const importPromises = [];
185
- const builder = this._createAsyncModuleBuilder(moduleRef, importPromises);
186
- await module._setup(builder);
187
- if (importPromises.length > 0) await Promise.all(importPromises);
188
- }
189
- }
190
- _createModuleBuilder(moduleRef) {
191
- return {
192
- bind: (token) => this._createBindToBuilder(token, moduleRef),
193
- import: (...modules) => {
194
- this._loadSyncModules(modules);
195
- }
196
- };
197
- }
198
- _createAsyncModuleBuilder(moduleRef, importPromises) {
199
- return {
200
- bind: (token) => this._createBindToBuilder(token, moduleRef),
201
- import: (...modules) => {
202
- for (const module of modules) importPromises.push(this._loadOneModuleAsync(module));
203
- }
204
- };
205
- }
206
- unload(...modules) {
207
- this._assertNotDisposed();
208
- for (const module of modules) this._unloadModuleSync(module);
209
- }
210
- /** Unregister module bindings and collect [binding, instance] pairs for deactivation. */
211
- _removeModuleBindings(ref) {
212
- this._moduleRefs.delete(ref);
213
- const ids = this._moduleBindingIds.get(ref) ?? [];
214
- this._moduleBindingIds.delete(ref);
215
- const pairs = [];
216
- for (const id of ids) {
217
- const binding = this._registry.getById(id);
218
- if (binding !== void 0) {
219
- this._registry.removeById(id);
220
- if (this._scope.hasSingleton(id)) {
221
- pairs.push([binding, this._scope.getSingleton(id)]);
222
- this._scope.deleteSingleton(id);
223
- }
224
- }
225
- }
226
- return pairs;
227
- }
228
- _unloadModuleSync(ref) {
229
- const count = this._moduleRefs.get(ref) ?? 0;
230
- if (count <= 1) {
231
- const reader = this._getMetadataReader();
232
- for (const [binding, instance] of this._removeModuleBindings(ref)) this._lifecycle.runDeactivationSync(binding, instance, reader);
233
- } else this._moduleRefs.set(ref, count - 1);
234
- }
235
- async unloadAsync(...modules) {
236
- this._assertNotDisposed();
237
- for (const module of modules) await this._unloadModuleAsync(module);
238
- }
239
- async _unloadModuleAsync(ref) {
240
- const count = this._moduleRefs.get(ref) ?? 0;
241
- if (count <= 1) {
242
- const reader = this._getMetadataReader();
243
- for (const [binding, instance] of this._removeModuleBindings(ref)) await this._lifecycle.runDeactivation(binding, instance, reader);
244
- } else this._moduleRefs.set(ref, count - 1);
245
- }
246
- loadAutoRegistered(registry) {
247
- this._assertNotDisposed();
248
- const entries = registry.entries();
249
- for (const { target, scope } of entries) {
250
- const bindingBuilder = this._createBindToBuilder(target).toSelf();
251
- if (scope === "singleton") bindingBuilder.singleton();
252
- else if (scope === "scoped") bindingBuilder.scoped();
253
- else bindingBuilder.transient();
254
- }
255
- return entries.length;
256
- }
257
- onActivation(token, handler) {
258
- this._assertNotDisposed();
259
- this._lifecycle.registerActivation(token, handler);
260
- }
261
- onDeactivation(token, handler) {
262
- this._assertNotDisposed();
263
- this._lifecycle.registerDeactivation(token, handler);
264
- }
265
- resolve(token, options) {
266
- this._assertNotDisposed();
267
- if (options === void 0) return this._resolver.resolveFromContext(token, [], []);
268
- return this._resolver.resolve(token, options, [], []);
269
- }
270
- resolveAsync(token, options) {
271
- this._assertNotDisposed();
272
- if (options === void 0) return this._resolver.resolveAsyncFromContext(token, [], []);
273
- return this._resolver.resolveAsync(token, options, [], []);
274
- }
275
- resolveOptional(token, options) {
276
- this._assertNotDisposed();
277
- return this._resolver.resolveOptional(token, options, [], []);
278
- }
279
- resolveOptionalAsync(token, options) {
280
- this._assertNotDisposed();
281
- return this._resolver.resolveOptionalAsync(token, options, [], []);
282
- }
283
- resolveAll(token, options) {
284
- this._assertNotDisposed();
285
- return this._resolver.resolveAll(token, options, [], []);
286
- }
287
- resolveAllAsync(token, options) {
288
- this._assertNotDisposed();
289
- return this._resolver.resolveAllAsync(token, options, [], []);
290
- }
291
- createChild() {
292
- this._assertNotDisposed();
293
- return new DefaultContainer(this);
294
- }
295
- async dispose() {
296
- if (this._disposed) return;
297
- this._disposed = true;
298
- const reader = this._getMetadataReader();
299
- for (const [id, instance] of this._scope.getAllSingletons()) {
300
- const binding = this._registry.getById(id);
301
- if (binding !== void 0) await this._lifecycle.runDeactivation(binding, instance, reader);
302
- }
303
- this._scope.clearAll();
304
- }
305
- [Symbol.asyncDispose]() {
306
- return this.dispose();
307
- }
308
- [Symbol.dispose]() {
309
- throw new SyncDisposalNotSupportedError();
310
- }
311
- async initializeAsync() {
312
- this._assertNotDisposed();
313
- const allBindings = this._registry.allBindings();
314
- for (const binding of allBindings) {
315
- if (binding.kind === "alias") continue;
316
- if (effectiveBindingScope(binding) === "singleton" && !this._scope.hasSingleton(binding.id)) {
317
- if (binding.predicate !== void 0) continue;
318
- if (binding.kind === "constant" && binding.onActivation === void 0) continue;
319
- const slotOptions = bindingSlotToResolveOptions(binding.slot);
320
- await this.resolveAsync(binding.token, slotOptions);
321
- }
322
- }
323
- }
324
- validate() {
325
- this._assertNotDisposed();
326
- const reader = this._getMetadataReader();
327
- const allBindings = this._registry.allBindings();
328
- for (const binding of allBindings) {
329
- if (!this._isSingletonStaticAnalyzableBinding(binding)) continue;
330
- this._validateSingletonBindingGraph(binding, reader);
331
- }
332
- }
333
- _isSingletonStaticAnalyzableBinding(binding) {
334
- if (effectiveBindingScope(binding) !== "singleton") return false;
335
- return binding.kind === "class" || binding.kind === "resolved" || binding.kind === "resolved-async";
336
- }
337
- /**
338
- * DFS over explicit constructor / `toResolved*` dependency edges. Follows `toAlias` chains to the
339
- * terminal binding for scope checks (SPEC §6.9). Skips `toDynamic*` subtrees (opaque).
340
- */
341
- _validateSingletonBindingGraph(root, reader) {
342
- const rootName = tokenName(root.token);
343
- const dfs = (current, pathNames, pathBindingIds) => {
344
- if (pathBindingIds.has(current.id)) return;
345
- const extendedPathIds = new Set(pathBindingIds);
346
- extendedPathIds.add(current.id);
347
- for (const edge of this._collectStaticDependencyEdges(current, reader)) {
348
- const { terminal, depTokenName } = edge;
349
- const depScope = this._validationScopeFromTerminal(terminal);
350
- if (depScope === "opaque") continue;
351
- if (depScope === "scoped" || depScope === "transient") throw new ScopeViolationError({
352
- consumerToken: rootName,
353
- consumerScope: "singleton",
354
- dependencyToken: depTokenName,
355
- dependencyScope: depScope,
356
- path: [...pathNames, depTokenName]
357
- });
358
- if (terminal.kind === "class" || terminal.kind === "resolved" || terminal.kind === "resolved-async") dfs(terminal, [...pathNames, depTokenName], extendedPathIds);
359
- }
360
- };
361
- dfs(root, [rootName], /* @__PURE__ */ new Set());
362
- }
363
- _validationScopeFromTerminal(terminal) {
364
- switch (terminal.kind) {
365
- case "constant": return "singleton";
366
- case "dynamic":
367
- case "dynamic-async": return "opaque";
368
- case "class":
369
- case "resolved":
370
- case "resolved-async": return terminal.scope;
371
- case "alias": throw new InternalError("validate: expected terminal binding after alias resolution");
372
- default: return terminal;
373
- }
374
- }
375
- _followAliasChainToTerminal(binding, options) {
376
- const cyclePath = [];
377
- const seenAliasIds = /* @__PURE__ */ new Set();
378
- let current = binding;
379
- while (current !== void 0 && current.kind === "alias") {
380
- if (seenAliasIds.has(current.id)) throw new CircularDependencyError(cyclePath);
381
- seenAliasIds.add(current.id);
382
- cyclePath.push(tokenName(current.token));
383
- const nextToken = current.target;
384
- const next = this._resolver.peekBindingForValidate(nextToken, options);
385
- if (next === void 0) return;
386
- current = next.binding;
387
- }
388
- return current;
389
- }
390
- _collectStaticDependencyEdges(binding, reader) {
391
- const edges = [];
392
- const pushTerminal = (terminal, displayName) => {
393
- if (terminal === void 0) return;
394
- edges.push({
395
- terminal,
396
- depTokenName: displayName
397
- });
398
- };
399
- if (binding.kind === "class") {
400
- const meta = reader.getConstructorMetadata(binding.target);
401
- if (meta === void 0) return edges;
402
- for (const param of meta.params) {
403
- const paramOptions = injectionSlotToResolveOptions(param);
404
- if (param.optional) continue;
405
- const tokenRef = param.token;
406
- if (param.multi) {
407
- const candidates = this._resolver.peekCandidateBindingsForValidate(tokenRef, paramOptions);
408
- for (const cand of candidates) {
409
- const term = this._followAliasChainToTerminal(cand, paramOptions);
410
- pushTerminal(term, term !== void 0 ? tokenName(term.token) : "");
411
- }
412
- continue;
413
- }
414
- const found = paramOptions === void 0 ? this._resolver.peekBindingForValidate(tokenRef, void 0) : this._resolver.peekBindingForValidate(tokenRef, paramOptions);
415
- if (found === void 0) continue;
416
- const term = this._followAliasChainToTerminal(found.binding, paramOptions);
417
- pushTerminal(term, term !== void 0 ? tokenName(term.token) : "");
418
- }
419
- return edges;
420
- }
421
- if (binding.kind === "resolved" || binding.kind === "resolved-async") for (const dep of binding.deps) {
422
- const depOptions = injectionSlotToResolveOptions(dep);
423
- if (dep.optional) continue;
424
- const tokenRef = dep.token;
425
- if (dep.multi) {
426
- const candidates = this._resolver.peekCandidateBindingsForValidate(tokenRef, depOptions);
427
- for (const cand of candidates) {
428
- const term = this._followAliasChainToTerminal(cand, depOptions);
429
- pushTerminal(term, term !== void 0 ? tokenName(term.token) : "");
430
- }
431
- continue;
432
- }
433
- const found = depOptions === void 0 ? this._resolver.peekBindingForValidate(tokenRef, void 0) : this._resolver.peekBindingForValidate(tokenRef, depOptions);
434
- if (found === void 0) continue;
435
- const term = this._followAliasChainToTerminal(found.binding, depOptions);
436
- pushTerminal(term, term !== void 0 ? tokenName(term.token) : "");
437
- }
438
- return edges;
439
- }
440
- has(token, options) {
441
- this._assertNotDisposed();
442
- return this._inspector.has(token, options, () => this._parent?.has(token, options) ?? false);
443
- }
444
- hasOwn(token, options) {
445
- this._assertNotDisposed();
446
- return this._inspector.hasOwn(token, options);
447
- }
448
- lookupBindings(token) {
449
- this._assertNotDisposed();
450
- return this._inspector.lookupBindings(token);
451
- }
452
- inspect() {
453
- this._assertNotDisposed();
454
- return this._inspector.inspect();
455
- }
456
- generateDependencyGraph(options) {
457
- this._assertNotDisposed();
458
- return buildDependencyGraph(this._registry, this._getMetadataReader(), options, this._parent?._registry);
459
- }
460
- _assertNotDisposed() {
461
- if (this._disposed) throw new DisposedContainerError();
462
- }
463
- };
464
- function updateSlotTag(slot, tag, value) {
465
- const existing = [...slot.tags];
466
- const idx = existing.findIndex(([k]) => k === tag);
467
- if (idx !== -1) existing[idx] = [tag, value];
468
- else existing.push([tag, value]);
469
- return {
470
- ...slot,
471
- tags: existing
472
- };
473
- }
474
- var SlotBuilder = class {
475
- _slot = DEFAULT_BINDING_SLOT;
476
- _predicate;
477
- _committed;
478
- when(predicate) {
479
- this._predicate = predicate;
480
- this._doCommit();
481
- return this;
482
- }
483
- whenNamed(name) {
484
- this._slot = {
485
- ...this._slot,
486
- name
487
- };
488
- this._doCommit();
489
- return this;
490
- }
491
- whenTagged(tag, value) {
492
- this._slot = updateSlotTag(this._slot, tag, value);
493
- this._doCommit();
494
- return this;
495
- }
496
- whenDefault() {
497
- return this;
498
- }
499
- id() {
500
- return this._committed;
501
- }
502
- };
503
- var BindingEntry = class {
504
- _token;
505
- _commit;
506
- constructor(_token, _commit) {
507
- this._token = _token;
508
- this._commit = _commit;
509
- }
510
- to(type) {
511
- return new ConstraintBuilder(this._token, {
512
- kind: "class",
513
- target: type,
514
- scope: "transient"
515
- }, this._commit);
516
- }
517
- toSelf() {
518
- if (typeof this._token !== "function") throw new Error("toSelf() requires token to be a Constructor");
519
- return new ConstraintBuilder(this._token, {
520
- kind: "class",
521
- target: this._token,
522
- scope: "transient"
523
- }, this._commit);
524
- }
525
- toConstantValue(value) {
526
- return new ConstantBuilder(this._token, value, this._commit);
527
- }
528
- toDynamic(factory) {
529
- return new ConstraintBuilder(this._token, {
530
- kind: "dynamic",
531
- factory,
532
- scope: "transient"
533
- }, this._commit);
534
- }
535
- toDynamicAsync(factory) {
536
- return new ConstraintBuilder(this._token, {
537
- kind: "dynamic-async",
538
- factory,
539
- scope: "transient"
540
- }, this._commit);
541
- }
542
- toResolved(factory, deps) {
543
- const normalizedDeps = deps.map((dependency) => normalizeToDescriptor(dependency));
544
- return new ConstraintBuilder(this._token, {
545
- kind: "resolved",
546
- factory,
547
- deps: normalizedDeps,
548
- scope: "transient"
549
- }, this._commit);
550
- }
551
- toResolvedAsync(factory, deps) {
552
- const normalizedDeps = deps.map((dependency) => normalizeToDescriptor(dependency));
553
- return new ConstraintBuilder(this._token, {
554
- kind: "resolved-async",
555
- factory,
556
- deps: normalizedDeps,
557
- scope: "transient"
558
- }, this._commit);
559
- }
560
- toAlias(target) {
561
- return new AliasBuilder(this._token, target, this._commit);
562
- }
563
- };
564
- var ConstraintBuilder = class extends SlotBuilder {
565
- _token;
566
- _partial;
567
- _commit;
568
- constructor(_token, _partial, _commit) {
569
- super();
570
- this._token = _token;
571
- this._partial = _partial;
572
- this._commit = _commit;
573
- this._doCommit();
574
- }
575
- _doCommit() {
576
- const previousId = this._committed;
577
- const binding = {
578
- ...this._partial,
579
- id: generateBindingId(),
580
- token: this._token,
581
- slot: this._slot,
582
- predicate: this._predicate
583
- };
584
- this._committed = this._commit(binding, previousId);
585
- }
586
- singleton() {
587
- const previousId = this._committed;
588
- this._committed = void 0;
589
- return new ScopeBuilder(this._token, {
590
- ...this._partial,
591
- scope: "singleton"
592
- }, this._slot, this._predicate, this._commit, "singleton", previousId);
593
- }
594
- transient() {
595
- const previousId = this._committed;
596
- this._committed = void 0;
597
- return new ScopeBuilder(this._token, {
598
- ...this._partial,
599
- scope: "transient"
600
- }, this._slot, this._predicate, this._commit, "transient", previousId);
601
- }
602
- scoped() {
603
- const previousId = this._committed;
604
- this._committed = void 0;
605
- return new ScopeBuilder(this._token, {
606
- ...this._partial,
607
- scope: "scoped"
608
- }, this._slot, this._predicate, this._commit, "scoped", previousId);
609
- }
610
- };
611
- var ScopeBuilder = class {
612
- _token;
613
- _partial;
614
- _slot;
615
- _predicate;
616
- _commit;
617
- _scope;
618
- _initialPreviousId;
619
- _onActivation;
620
- _onDeactivation;
621
- _committed;
622
- constructor(_token, _partial, _slot, _predicate, _commit, _scope, _initialPreviousId) {
623
- this._token = _token;
624
- this._partial = _partial;
625
- this._slot = _slot;
626
- this._predicate = _predicate;
627
- this._commit = _commit;
628
- this._scope = _scope;
629
- this._initialPreviousId = _initialPreviousId;
630
- this._doCommit();
631
- }
632
- _doCommit() {
633
- const previousId = this._committed ?? this._initialPreviousId;
634
- const binding = {
635
- ...this._partial,
636
- id: generateBindingId(),
637
- token: this._token,
638
- slot: this._slot,
639
- predicate: this._predicate,
640
- onActivation: this._onActivation,
641
- onDeactivation: this._onDeactivation
642
- };
643
- this._committed = this._commit(binding, previousId);
644
- }
645
- onActivation(fn) {
646
- this._onActivation = fn;
647
- this._doCommit();
648
- return this;
649
- }
650
- onDeactivation(fn) {
651
- this._onDeactivation = fn;
652
- this._doCommit();
653
- return this;
654
- }
655
- id() {
656
- return this._committed;
657
- }
658
- };
659
- var ConstantBuilder = class extends SlotBuilder {
660
- _token;
661
- _value;
662
- _commit;
663
- _onActivation;
664
- _onDeactivation;
665
- constructor(_token, _value, _commit) {
666
- super();
667
- this._token = _token;
668
- this._value = _value;
669
- this._commit = _commit;
670
- this._doCommit();
671
- }
672
- _doCommit() {
673
- const previousId = this._committed;
674
- const binding = {
675
- kind: "constant",
676
- id: generateBindingId(),
677
- token: this._token,
678
- slot: this._slot,
679
- predicate: this._predicate,
680
- value: this._value,
681
- scope: "singleton",
682
- onActivation: this._onActivation,
683
- onDeactivation: this._onDeactivation
684
- };
685
- this._committed = this._commit(binding, previousId);
686
- }
687
- onActivation(fn) {
688
- this._onActivation = fn;
689
- this._doCommit();
690
- return this;
691
- }
692
- onDeactivation(fn) {
693
- this._onDeactivation = fn;
694
- this._doCommit();
695
- return this;
696
- }
697
- };
698
- var AliasBuilder = class extends SlotBuilder {
699
- _token;
700
- _target;
701
- _commit;
702
- constructor(_token, _target, _commit) {
703
- super();
704
- this._token = _token;
705
- this._target = _target;
706
- this._commit = _commit;
707
- this._doCommit();
708
- }
709
- _doCommit() {
710
- const previousId = this._committed;
711
- const binding = {
712
- kind: "alias",
713
- id: generateBindingId(),
714
- token: this._token,
715
- slot: this._slot,
716
- predicate: this._predicate,
717
- target: this._target
718
- };
719
- this._committed = this._commit(binding, previousId);
720
- }
721
- };
722
- /**
723
- * @since 0.3.16-canary.0
724
- */
725
- const Container = {
726
- create() {
727
- return new DefaultContainer();
728
- },
729
- fromModules(...modules) {
730
- const container = new DefaultContainer();
731
- container.load(...modules);
732
- return container;
733
- },
734
- async fromModulesAsync(...modules) {
735
- const container = new DefaultContainer();
736
- await container.loadAsync(...modules);
737
- return container;
738
- }
739
- };
740
- //#endregion
741
- export { Container };