@codefast/di 0.8.0 → 0.8.1

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 (218) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +242 -159
  3. package/dist/ambient/active-container.d.ts +1 -2
  4. package/dist/ambient/active-container.js +1 -2
  5. package/dist/container/binding-builders.d.ts +1 -2
  6. package/dist/container/binding-builders.js +1 -2
  7. package/dist/container/container.d.ts +1 -2
  8. package/dist/container/container.js +1 -2
  9. package/dist/core/binding-scope.d.ts +1 -2
  10. package/dist/core/binding-scope.js +1 -2
  11. package/dist/core/binding.d.ts +1 -2
  12. package/dist/core/binding.js +1 -2
  13. package/dist/core/constraint-requirement.d.ts +1 -2
  14. package/dist/core/constraint-requirement.js +1 -2
  15. package/dist/core/constructor-type.d.ts +1 -2
  16. package/dist/core/constructor-type.js +1 -2
  17. package/dist/core/map-upsert.d.ts +1 -2
  18. package/dist/core/map-upsert.js +1 -2
  19. package/dist/core/module.d.ts +1 -2
  20. package/dist/core/module.js +1 -2
  21. package/dist/core/registry.d.ts +1 -2
  22. package/dist/core/registry.js +1 -2
  23. package/dist/core/tag.d.ts +1 -2
  24. package/dist/core/tag.js +1 -2
  25. package/dist/core/token.d.ts +1 -2
  26. package/dist/core/token.js +1 -2
  27. package/dist/core/types.d.ts +1 -2
  28. package/dist/core/types.js +1 -2
  29. package/dist/decorators/inject.d.ts +1 -2
  30. package/dist/decorators/inject.js +1 -2
  31. package/dist/decorators/injectable.d.ts +1 -2
  32. package/dist/decorators/injectable.js +1 -2
  33. package/dist/decorators/lifecycle-decorators.d.ts +1 -2
  34. package/dist/decorators/lifecycle-decorators.js +1 -2
  35. package/dist/errors/diagnostics.d.ts +1 -2
  36. package/dist/errors/diagnostics.js +1 -2
  37. package/dist/errors/errors.d.ts +1 -2
  38. package/dist/errors/errors.js +1 -2
  39. package/dist/index.d.ts +1 -2
  40. package/dist/index.js +1 -2
  41. package/dist/injection/descriptor.d.ts +1 -2
  42. package/dist/injection/descriptor.js +1 -2
  43. package/dist/injection/resolve-options.d.ts +1 -2
  44. package/dist/injection/resolve-options.js +1 -2
  45. package/dist/introspection/dependency-graph.d.ts +1 -2
  46. package/dist/introspection/dependency-graph.js +1 -2
  47. package/dist/introspection/graph-adapters/cytoscape.d.ts +1 -2
  48. package/dist/introspection/graph-adapters/cytoscape.js +1 -2
  49. package/dist/introspection/graph-adapters/dot.d.ts +1 -2
  50. package/dist/introspection/graph-adapters/dot.js +1 -2
  51. package/dist/introspection/graph-adapters/mermaid.d.ts +1 -2
  52. package/dist/introspection/graph-adapters/mermaid.js +1 -2
  53. package/dist/introspection/graph-adapters/reactflow.d.ts +1 -2
  54. package/dist/introspection/graph-adapters/reactflow.js +1 -2
  55. package/dist/introspection/inspector.d.ts +1 -2
  56. package/dist/introspection/inspector.js +1 -2
  57. package/dist/lifecycle/lifecycle-manager.d.ts +1 -2
  58. package/dist/lifecycle/lifecycle-manager.js +1 -2
  59. package/dist/lifecycle/scope-manager.d.ts +1 -2
  60. package/dist/lifecycle/scope-manager.js +1 -2
  61. package/dist/metadata/metadata-keys.d.ts +1 -2
  62. package/dist/metadata/metadata-keys.js +1 -2
  63. package/dist/metadata/metadata-reader-token.d.ts +1 -2
  64. package/dist/metadata/metadata-reader-token.js +1 -2
  65. package/dist/metadata/metadata-types.d.ts +1 -2
  66. package/dist/metadata/metadata-types.js +1 -2
  67. package/dist/metadata/symbol-metadata-reader.d.ts +1 -2
  68. package/dist/metadata/symbol-metadata-reader.js +1 -2
  69. package/dist/metadata/verifying-metadata-reader.d.ts +1 -2
  70. package/dist/metadata/verifying-metadata-reader.js +1 -2
  71. package/dist/resolution/cache/activation-need.d.ts +1 -2
  72. package/dist/resolution/cache/activation-need.js +1 -2
  73. package/dist/resolution/cache/binding-lookup-cache.d.ts +1 -2
  74. package/dist/resolution/cache/binding-lookup-cache.js +1 -2
  75. package/dist/resolution/cache/class-introspector.d.ts +1 -2
  76. package/dist/resolution/cache/class-introspector.js +1 -2
  77. package/dist/resolution/context.d.ts +1 -2
  78. package/dist/resolution/context.js +1 -2
  79. package/dist/resolution/path/resolution-path.d.ts +1 -2
  80. package/dist/resolution/path/resolution-path.js +1 -2
  81. package/dist/resolution/plan/instantiation-plan.d.ts +1 -2
  82. package/dist/resolution/plan/instantiation-plan.js +1 -2
  83. package/dist/resolution/resolver.d.ts +1 -2
  84. package/dist/resolution/resolver.js +1 -2
  85. package/dist/resolution/select/binding-select.d.ts +1 -2
  86. package/dist/resolution/select/binding-select.js +1 -2
  87. package/dist/resolution/select/constraints.d.ts +1 -2
  88. package/dist/resolution/select/constraints.js +1 -2
  89. package/package.json +6 -58
  90. package/dist/ambient/active-container.d.ts.map +0 -1
  91. package/dist/ambient/active-container.js.map +0 -1
  92. package/dist/container/binding-builders.d.ts.map +0 -1
  93. package/dist/container/binding-builders.js.map +0 -1
  94. package/dist/container/container.d.ts.map +0 -1
  95. package/dist/container/container.js.map +0 -1
  96. package/dist/core/binding-scope.d.ts.map +0 -1
  97. package/dist/core/binding-scope.js.map +0 -1
  98. package/dist/core/binding.d.ts.map +0 -1
  99. package/dist/core/binding.js.map +0 -1
  100. package/dist/core/constraint-requirement.d.ts.map +0 -1
  101. package/dist/core/constraint-requirement.js.map +0 -1
  102. package/dist/core/constructor-type.d.ts.map +0 -1
  103. package/dist/core/constructor-type.js.map +0 -1
  104. package/dist/core/map-upsert.d.ts.map +0 -1
  105. package/dist/core/map-upsert.js.map +0 -1
  106. package/dist/core/module.d.ts.map +0 -1
  107. package/dist/core/module.js.map +0 -1
  108. package/dist/core/registry.d.ts.map +0 -1
  109. package/dist/core/registry.js.map +0 -1
  110. package/dist/core/tag.d.ts.map +0 -1
  111. package/dist/core/tag.js.map +0 -1
  112. package/dist/core/token.d.ts.map +0 -1
  113. package/dist/core/token.js.map +0 -1
  114. package/dist/core/types.d.ts.map +0 -1
  115. package/dist/core/types.js.map +0 -1
  116. package/dist/decorators/inject.d.ts.map +0 -1
  117. package/dist/decorators/inject.js.map +0 -1
  118. package/dist/decorators/injectable.d.ts.map +0 -1
  119. package/dist/decorators/injectable.js.map +0 -1
  120. package/dist/decorators/lifecycle-decorators.d.ts.map +0 -1
  121. package/dist/decorators/lifecycle-decorators.js.map +0 -1
  122. package/dist/errors/diagnostics.d.ts.map +0 -1
  123. package/dist/errors/diagnostics.js.map +0 -1
  124. package/dist/errors/errors.d.ts.map +0 -1
  125. package/dist/errors/errors.js.map +0 -1
  126. package/dist/index.d.ts.map +0 -1
  127. package/dist/index.js.map +0 -1
  128. package/dist/injection/descriptor.d.ts.map +0 -1
  129. package/dist/injection/descriptor.js.map +0 -1
  130. package/dist/injection/resolve-options.d.ts.map +0 -1
  131. package/dist/injection/resolve-options.js.map +0 -1
  132. package/dist/introspection/dependency-graph.d.ts.map +0 -1
  133. package/dist/introspection/dependency-graph.js.map +0 -1
  134. package/dist/introspection/graph-adapters/cytoscape.d.ts.map +0 -1
  135. package/dist/introspection/graph-adapters/cytoscape.js.map +0 -1
  136. package/dist/introspection/graph-adapters/dot.d.ts.map +0 -1
  137. package/dist/introspection/graph-adapters/dot.js.map +0 -1
  138. package/dist/introspection/graph-adapters/mermaid.d.ts.map +0 -1
  139. package/dist/introspection/graph-adapters/mermaid.js.map +0 -1
  140. package/dist/introspection/graph-adapters/reactflow.d.ts.map +0 -1
  141. package/dist/introspection/graph-adapters/reactflow.js.map +0 -1
  142. package/dist/introspection/inspector.d.ts.map +0 -1
  143. package/dist/introspection/inspector.js.map +0 -1
  144. package/dist/lifecycle/lifecycle-manager.d.ts.map +0 -1
  145. package/dist/lifecycle/lifecycle-manager.js.map +0 -1
  146. package/dist/lifecycle/scope-manager.d.ts.map +0 -1
  147. package/dist/lifecycle/scope-manager.js.map +0 -1
  148. package/dist/metadata/metadata-keys.d.ts.map +0 -1
  149. package/dist/metadata/metadata-keys.js.map +0 -1
  150. package/dist/metadata/metadata-reader-token.d.ts.map +0 -1
  151. package/dist/metadata/metadata-reader-token.js.map +0 -1
  152. package/dist/metadata/metadata-types.d.ts.map +0 -1
  153. package/dist/metadata/metadata-types.js.map +0 -1
  154. package/dist/metadata/symbol-metadata-reader.d.ts.map +0 -1
  155. package/dist/metadata/symbol-metadata-reader.js.map +0 -1
  156. package/dist/metadata/verifying-metadata-reader.d.ts.map +0 -1
  157. package/dist/metadata/verifying-metadata-reader.js.map +0 -1
  158. package/dist/resolution/cache/activation-need.d.ts.map +0 -1
  159. package/dist/resolution/cache/activation-need.js.map +0 -1
  160. package/dist/resolution/cache/binding-lookup-cache.d.ts.map +0 -1
  161. package/dist/resolution/cache/binding-lookup-cache.js.map +0 -1
  162. package/dist/resolution/cache/class-introspector.d.ts.map +0 -1
  163. package/dist/resolution/cache/class-introspector.js.map +0 -1
  164. package/dist/resolution/context.d.ts.map +0 -1
  165. package/dist/resolution/context.js.map +0 -1
  166. package/dist/resolution/path/resolution-path.d.ts.map +0 -1
  167. package/dist/resolution/path/resolution-path.js.map +0 -1
  168. package/dist/resolution/plan/instantiation-plan.d.ts.map +0 -1
  169. package/dist/resolution/plan/instantiation-plan.js.map +0 -1
  170. package/dist/resolution/resolver.d.ts.map +0 -1
  171. package/dist/resolution/resolver.js.map +0 -1
  172. package/dist/resolution/select/binding-select.d.ts.map +0 -1
  173. package/dist/resolution/select/binding-select.js.map +0 -1
  174. package/dist/resolution/select/constraints.d.ts.map +0 -1
  175. package/dist/resolution/select/constraints.js.map +0 -1
  176. package/src/ambient/active-container.ts +0 -69
  177. package/src/container/binding-builders.ts +0 -337
  178. package/src/container/container.ts +0 -972
  179. package/src/core/binding-scope.ts +0 -15
  180. package/src/core/binding.ts +0 -505
  181. package/src/core/constraint-requirement.ts +0 -94
  182. package/src/core/constructor-type.ts +0 -18
  183. package/src/core/map-upsert.ts +0 -53
  184. package/src/core/module.ts +0 -117
  185. package/src/core/registry.ts +0 -319
  186. package/src/core/tag.ts +0 -212
  187. package/src/core/token.ts +0 -31
  188. package/src/core/types.ts +0 -149
  189. package/src/decorators/inject.ts +0 -101
  190. package/src/decorators/injectable.ts +0 -134
  191. package/src/decorators/lifecycle-decorators.ts +0 -43
  192. package/src/errors/diagnostics.ts +0 -45
  193. package/src/errors/errors.ts +0 -499
  194. package/src/index.ts +0 -139
  195. package/src/injection/descriptor.ts +0 -218
  196. package/src/injection/resolve-options.ts +0 -201
  197. package/src/introspection/dependency-graph.ts +0 -296
  198. package/src/introspection/graph-adapters/cytoscape.ts +0 -78
  199. package/src/introspection/graph-adapters/dot.ts +0 -32
  200. package/src/introspection/graph-adapters/mermaid.ts +0 -61
  201. package/src/introspection/graph-adapters/reactflow.ts +0 -84
  202. package/src/introspection/inspector.ts +0 -134
  203. package/src/lifecycle/lifecycle-manager.ts +0 -272
  204. package/src/lifecycle/scope-manager.ts +0 -158
  205. package/src/metadata/metadata-keys.ts +0 -28
  206. package/src/metadata/metadata-reader-token.ts +0 -10
  207. package/src/metadata/metadata-types.ts +0 -57
  208. package/src/metadata/symbol-metadata-reader.ts +0 -126
  209. package/src/metadata/verifying-metadata-reader.ts +0 -41
  210. package/src/resolution/cache/activation-need.ts +0 -87
  211. package/src/resolution/cache/binding-lookup-cache.ts +0 -169
  212. package/src/resolution/cache/class-introspector.ts +0 -256
  213. package/src/resolution/context.ts +0 -331
  214. package/src/resolution/path/resolution-path.ts +0 -167
  215. package/src/resolution/plan/instantiation-plan.ts +0 -592
  216. package/src/resolution/resolver.ts +0 -1654
  217. package/src/resolution/select/binding-select.ts +0 -207
  218. package/src/resolution/select/constraints.ts +0 -146
@@ -1,499 +0,0 @@
1
- import type { BindingTag } from "#/core/tag";
2
- import { slotName } from "#/core/tag";
3
- import type { BindingIdentifier, BindingScope, ResolveOptions } from "#/core/types";
4
-
5
- /**
6
- * Base class for every error the library throws, each carrying a machine-readable `code`.
7
- *
8
- * @since 0.3.16-canary.0
9
- */
10
- export abstract class DiError extends Error {
11
- abstract readonly code: string;
12
-
13
- constructor(message: string) {
14
- super(message);
15
- this.name = this.constructor.name;
16
- }
17
- }
18
-
19
- /**
20
- * An internal assertion failure — a library bug, never caller misuse.
21
- *
22
- * @since 0.3.16-canary.0
23
- */
24
- export class InternalError extends DiError {
25
- readonly code = "INTERNAL_ERROR";
26
-
27
- constructor(message: string) {
28
- super(message);
29
- }
30
- }
31
-
32
- /**
33
- * A token with no binding at all, even after walking the parent container chain.
34
- *
35
- * @since 0.3.16-canary.0
36
- */
37
- export class TokenNotBoundError extends DiError {
38
- readonly code = "TOKEN_NOT_BOUND";
39
- readonly tokenName: string;
40
-
41
- constructor(tokenName: string) {
42
- super(`No binding found for token '${tokenName}'. Did you forget container.bind(${tokenName})?`);
43
- this.tokenName = tokenName;
44
- }
45
- }
46
-
47
- // Options carry caller values a tag may hold — a bigint or a circular object must not make the
48
- // diagnostic itself throw and mask the real error. The reserved criterion renders as `name`.
49
- function describeResolveOptions(options: ResolveOptions): string {
50
- try {
51
- let name = options.name;
52
- const criteria: Array<string> = [];
53
- const add = (criterion: BindingTag): void => {
54
- if (criterion.key === slotName) {
55
- name ??= String(criterion.value);
56
- } else {
57
- criteria.push(`${criterion.key.name}=${String(criterion.value)}`);
58
- }
59
- };
60
- if (options.tag !== undefined) {
61
- add(options.tag);
62
- }
63
- if (options.tags !== undefined) {
64
- for (const criterion of options.tags) {
65
- add(criterion);
66
- }
67
- }
68
- const display: { name?: string; tags?: Array<string> } = {};
69
- if (name !== undefined) {
70
- display.name = name;
71
- }
72
- if (criteria.length > 0) {
73
- display.tags = criteria;
74
- }
75
- return JSON.stringify(display) ?? "undefined";
76
- } catch {
77
- return "[unserializable options]";
78
- }
79
- }
80
-
81
- /**
82
- * A token that has bindings, none of whose slots match the given `ResolveOptions`.
83
- *
84
- * @since 0.3.16-canary.0
85
- */
86
- export class NoMatchingBindingError extends DiError {
87
- readonly code = "NO_MATCHING_BINDING";
88
- readonly tokenName: string;
89
- readonly options: ResolveOptions;
90
- readonly availableSlots: Array<string>;
91
-
92
- constructor(tokenName: string, options: ResolveOptions, availableSlots: Array<string>) {
93
- const optionsString = describeResolveOptions(options);
94
- const slotsStr = availableSlots.join(", ");
95
- super(`No binding for '${tokenName}' matching ${optionsString}. Available slots: [${slotsStr}].`);
96
- this.tokenName = tokenName;
97
- this.options = options;
98
- this.availableSlots = availableSlots;
99
- }
100
- }
101
-
102
- /**
103
- * Two or more candidate bindings that matched without the more-specific rule deciding a winner.
104
- *
105
- * @since 0.3.16-canary.0
106
- */
107
- export class AmbiguousBindingError extends DiError {
108
- readonly code = "AMBIGUOUS_BINDING";
109
- readonly tokenName: string;
110
- readonly candidateIds: ReadonlyArray<BindingIdentifier>;
111
-
112
- constructor(tokenName: string, candidateIds: ReadonlyArray<BindingIdentifier>) {
113
- super(
114
- `Multiple bindings for '${tokenName}' matched without a clear winner. Candidates: [${candidateIds.join(", ")}]. Ensure when() predicates are mutually exclusive.`,
115
- );
116
- this.tokenName = tokenName;
117
- this.candidateIds = candidateIds;
118
- }
119
- }
120
-
121
- /**
122
- * A dependency cycle detected along the resolution path, alias chains included.
123
- *
124
- * @since 0.3.16-canary.0
125
- */
126
- export class CircularDependencyError extends DiError {
127
- readonly code = "CIRCULAR_DEPENDENCY";
128
- readonly cycle: Array<string>;
129
-
130
- constructor(cycle: Array<string>) {
131
- super(`Circular dependency detected: ${cycle.join(" → ")}`);
132
- this.cycle = cycle;
133
- }
134
- }
135
-
136
- /**
137
- * A sync `resolve()` of a token whose factory — or a dependency's factory — is async.
138
- *
139
- * @since 0.3.16-canary.0
140
- */
141
- export class AsyncResolutionError extends DiError {
142
- readonly code = "ASYNC_RESOLUTION";
143
- /** The token the caller asked for — what `resolveAsync` has to be called with. */
144
- readonly tokenName: string;
145
- /** The token whose factory is async: `tokenName` itself unless a dependency forced it. */
146
- readonly asyncSourceToken: string;
147
-
148
- constructor(tokenName: string, asyncSourceToken: string = tokenName) {
149
- super(
150
- asyncSourceToken === tokenName
151
- ? `Token '${tokenName}' requires async resolution because its factory is async. Use container.resolveAsync(${tokenName}).`
152
- : `Token '${tokenName}' requires async resolution because '${asyncSourceToken}' in its dependency chain has an async factory. Use container.resolveAsync(${tokenName}).`,
153
- );
154
- this.tokenName = tokenName;
155
- this.asyncSourceToken = asyncSourceToken;
156
- }
157
- }
158
-
159
- /**
160
- * A sync `unbind()` of a binding whose `onDeactivation` handler is async.
161
- *
162
- * @since 0.3.16-canary.0
163
- */
164
- export class AsyncDeactivationError extends DiError {
165
- readonly code = "ASYNC_DEACTIVATION";
166
- readonly tokenName: string;
167
-
168
- constructor(tokenName: string) {
169
- super(`Token '${tokenName}' has an async onDeactivation handler. Use unbindAsync() instead.`);
170
- this.tokenName = tokenName;
171
- }
172
- }
173
-
174
- /**
175
- * The tokens, scopes, and resolution path describing a captive-dependency violation.
176
- *
177
- * @since 0.3.16-canary.0
178
- */
179
- export interface ScopeViolationDetails {
180
- readonly consumerToken: string;
181
- readonly consumerScope: BindingScope;
182
- readonly dependencyToken: string;
183
- readonly dependencyScope: BindingScope;
184
- readonly path: Array<string>;
185
- }
186
-
187
- /**
188
- * A captive dependency — a longer-lived binding depending on a shorter-lived one.
189
- *
190
- * @since 0.3.16-canary.0
191
- */
192
- export class ScopeViolationError extends DiError {
193
- readonly code = "SCOPE_VIOLATION";
194
- readonly details: ScopeViolationDetails;
195
-
196
- constructor(details: ScopeViolationDetails) {
197
- super(
198
- `Scope violation: '${details.consumerToken}' (${details.consumerScope}) depends on '${details.dependencyToken}' (${details.dependencyScope}). Path: ${details.path.join(" → ")}`,
199
- );
200
- this.details = details;
201
- }
202
- }
203
-
204
- /**
205
- * A `…TaggedAll` constraint built from a criteria list with nothing in it.
206
- *
207
- * @remarks Reported where the list is passed rather than where it fails to match, because it does
208
- * not fail to match — "carries all of no criteria" holds for any ancestor, so the constraint quietly
209
- * becomes a weaker one that still outranks an unconstrained binding.
210
- *
211
- * @since 0.6.0
212
- */
213
- export class EmptyTagCriteriaError extends DiError {
214
- readonly code = "EMPTY_TAG_CRITERIA";
215
- readonly helperName: string;
216
-
217
- constructor(helperName: string) {
218
- super(
219
- `${helperName}() was given no criteria. An empty list matches any ancestor, which is not what the call says — pass the criteria to require, or drop the constraint if there are none.`,
220
- );
221
- this.helperName = helperName;
222
- }
223
- }
224
-
225
- /**
226
- * A constraint waiting on a slot name that nothing in the container chain declares.
227
- *
228
- * @remarks A name is a bare string, so a typo produces a constraint that is never satisfied and
229
- * never reported. Reported by `validate()` rather than at bind time, because the binding carrying
230
- * the name may be registered after the constraint is built.
231
- *
232
- * @since 0.6.0
233
- */
234
- export class UnreachableConstraintError extends DiError {
235
- readonly code = "UNREACHABLE_CONSTRAINT";
236
- readonly tokenName: string;
237
- readonly requiredName: string;
238
- readonly helperName: string;
239
-
240
- constructor(tokenName: string, requiredName: string, helperName: string) {
241
- super(
242
- `The binding for '${tokenName}' is constrained by ${helperName}('${requiredName}'), but no binding in this container or its ancestors declares the slot name '${requiredName}', so the constraint can never hold. Name the slot with .whenNamed('${requiredName}') on the binding it should match, or correct the name here.`,
243
- );
244
- this.tokenName = tokenName;
245
- this.requiredName = requiredName;
246
- this.helperName = helperName;
247
- }
248
- }
249
-
250
- /**
251
- * A container-level lifecycle hook whose token nothing is bound to, so it can never run.
252
- *
253
- * @remarks Hooks are keyed by token identity, which makes a class that is only ever a `to()` target
254
- * look like a token and match nothing. Reported by `validate()` rather than at registration, because
255
- * binding after registering the hook is a supported order.
256
- *
257
- * @since 0.6.0
258
- */
259
- export class UnreachableLifecycleHookError extends DiError {
260
- readonly code = "UNREACHABLE_LIFECYCLE_HOOK";
261
- readonly tokenName: string;
262
- readonly phase: "onActivation" | "onDeactivation";
263
-
264
- constructor(tokenName: string, phase: "onActivation" | "onDeactivation") {
265
- super(
266
- `${phase}() is registered for '${tokenName}', which nothing is bound to in this container or its ancestors, so the hook can never run. Bind the token, or — if '${tokenName}' is a class you bound as an implementation via .to(${tokenName}) — register the hook against the token you bound instead.`,
267
- );
268
- this.tokenName = tokenName;
269
- this.phase = phase;
270
- }
271
- }
272
-
273
- /**
274
- * A {@link MetadataReader} described a class with something the container cannot use.
275
- *
276
- * @remarks Separate from {@link MissingMetadataError}: absent metadata is a class the container was
277
- * never told about, while invalid metadata is a reader that answered wrongly. Covers both the
278
- * constructor answer and the lifecycle one, since only the `reason` differs.
279
- *
280
- * @since 0.6.0
281
- */
282
- export class InvalidMetadataError extends DiError {
283
- readonly code = "INVALID_METADATA";
284
- readonly targetName: string;
285
- readonly reason: string;
286
-
287
- constructor(targetName: string, reason: string) {
288
- super(
289
- `MetadataReader returned invalid metadata for class '${targetName}': ${reason}. Check the reader bound to MetadataReaderToken or passed to Container.create().`,
290
- );
291
- this.targetName = targetName;
292
- this.reason = reason;
293
- }
294
- }
295
-
296
- /**
297
- * A class the container must construct but that carries no `@injectable()` metadata.
298
- *
299
- * @since 0.3.16-canary.0
300
- */
301
- export class MissingMetadataError extends DiError {
302
- readonly code = "MISSING_METADATA";
303
- readonly targetName: string;
304
-
305
- constructor(targetName: string) {
306
- super(
307
- `Class '${targetName}' is missing @injectable() decorator. Add @injectable([...deps]) or use toDynamic()/toResolved() instead.`,
308
- );
309
- this.targetName = targetName;
310
- }
311
- }
312
-
313
- /**
314
- * A sync `load()` given a module that needs async setup.
315
- *
316
- * @since 0.3.16-canary.0
317
- */
318
- export class AsyncModuleLoadError extends DiError {
319
- readonly code = "ASYNC_MODULE_LOAD";
320
- readonly moduleName: string;
321
-
322
- constructor(moduleName: string) {
323
- super(`Module '${moduleName}' is async. Use container.loadAsync() instead.`);
324
- this.moduleName = moduleName;
325
- }
326
- }
327
-
328
- /**
329
- * A synchronous disposal attempt on a container whose `onDeactivation` handlers may be async.
330
- *
331
- * @since 0.3.16-canary.0
332
- */
333
- export class SyncDisposalNotSupportedError extends DiError {
334
- readonly code = "SYNC_DISPOSAL_NOT_SUPPORTED";
335
-
336
- constructor() {
337
- super(
338
- "Container cannot be disposed synchronously because onDeactivation handlers may be async. Use `await using` or call container.dispose() explicitly.",
339
- );
340
- }
341
- }
342
-
343
- /**
344
- * A `scoped` binding resolved from a container with no child scope context.
345
- *
346
- * @since 0.3.16-canary.0
347
- */
348
- export class MissingScopeContextError extends DiError {
349
- readonly code = "MISSING_SCOPE_CONTEXT";
350
- readonly tokenName: string;
351
-
352
- constructor(tokenName: string) {
353
- super(
354
- `Token '${tokenName}' is scoped but was resolved from a container without a child scope context. Use container.createChild() to create a scoped context.`,
355
- );
356
- this.tokenName = tokenName;
357
- }
358
- }
359
-
360
- /**
361
- * An `@inject` accessor initialized with no container context open.
362
- *
363
- * @remarks Carries the class and the accessor separately: a nameless class is possible (an anonymous
364
- * class expression has an empty `name`), and a message that claims a class it does not have is what
365
- * sent readers looking for a class called `clock`.
366
- *
367
- * @since 0.3.16-canary.0
368
- */
369
- export class MissingContainerContextError extends DiError {
370
- readonly code = "MISSING_CONTAINER_CONTEXT";
371
- /** The class being constructed, or `undefined` when it has no readable name. */
372
- readonly className: string | undefined;
373
- readonly accessorName: string | symbol;
374
-
375
- constructor(className: string | undefined, accessorName: string | symbol) {
376
- const accessor = `@inject accessor '${String(accessorName)}'`;
377
- super(
378
- className === undefined
379
- ? `An ${accessor} was initialized outside a container context. Resolve its class through a container, or open a context with runWithContainer().`
380
- : `Class '${className}' has an ${accessor} but was constructed outside a container context. Resolve it via container.resolve(${className}), or open a context with runWithContainer().`,
381
- );
382
- this.className = className;
383
- this.accessorName = accessorName;
384
- }
385
- }
386
-
387
- /**
388
- * A fluent chain was refined before a `to*()` call gave it a binding to refine.
389
- *
390
- * @remarks The builder types make this unreachable from TypeScript — `bind()` returns
391
- * `BindToBuilder`, which exposes only `to*()`. It exists for JavaScript callers and for anyone who
392
- * casts past the types, so the misuse fails loudly instead of mutating nothing.
393
- *
394
- * @since 0.5.0-canary.8
395
- */
396
- export class ChainNotRegisteredError extends DiError {
397
- readonly code = "CHAIN_NOT_REGISTERED";
398
- readonly tokenName: string;
399
-
400
- constructor(tokenName: string) {
401
- super(
402
- `Cannot refine the binding for token '${tokenName}' before choosing a target. Call a to*() method first — for example .to(SomeClass), .toConstantValue(value) or .toDynamic(factory).`,
403
- );
404
- this.tokenName = tokenName;
405
- }
406
- }
407
-
408
- /**
409
- * A `rebind()` of a token that has no own binding in this container.
410
- *
411
- * @since 0.3.16-canary.0
412
- */
413
- export class RebindUnboundTokenError extends DiError {
414
- readonly code = "REBIND_UNBOUND_TOKEN";
415
- readonly tokenName: string;
416
-
417
- constructor(tokenName: string) {
418
- super(
419
- `Cannot rebind token '${tokenName}' because it has no own binding in this container. Use container.bind(${tokenName}) to create a new binding instead.`,
420
- );
421
- this.tokenName = tokenName;
422
- }
423
- }
424
-
425
- /**
426
- * `toSelf()` on a token that is not a class, so there is nothing to construct.
427
- *
428
- * @since 0.5.0-canary.9
429
- */
430
- export class SelfBindingRequiresClassError extends DiError {
431
- readonly code = "SELF_BINDING_REQUIRES_CLASS";
432
- readonly tokenName: string;
433
-
434
- constructor(tokenName: string) {
435
- super(
436
- `toSelf() needs the token to be the class it constructs, and '${tokenName}' is not a class. Use .to(SomeClass) to name the implementation, or bind the class itself with container.bind(SomeClass).toSelf().`,
437
- );
438
- this.tokenName = tokenName;
439
- }
440
- }
441
-
442
- /**
443
- * A decorator that acts on one instance was applied to a static member.
444
- *
445
- * @remarks Instance-only by construction: `@inject` resolves through the container active while an
446
- * instance is built, and `@postConstruct`/`@preDestroy` bracket one instance's lifecycle. A static
447
- * member belongs to the class, which no container constructs.
448
- *
449
- * @since 0.6.0
450
- */
451
- export class StaticMemberDecoratorError extends DiError {
452
- readonly code = "STATIC_MEMBER_DECORATOR";
453
- readonly decoratorName: string;
454
- readonly memberName: string;
455
-
456
- constructor(decoratorName: string, memberName: string) {
457
- super(
458
- `@${decoratorName}() applies to instance members only, and '${memberName}' is static. Move it to an instance member, or read the value from the container where the static member is used.`,
459
- );
460
- this.decoratorName = decoratorName;
461
- this.memberName = memberName;
462
- }
463
- }
464
-
465
- /**
466
- * An operation attempted on a container that has already been disposed.
467
- *
468
- * @since 0.3.16-canary.0
469
- */
470
- export class DisposedContainerError extends DiError {
471
- readonly code = "DISPOSED_CONTAINER";
472
-
473
- constructor() {
474
- super("Cannot perform operations on a disposed container.");
475
- }
476
- }
477
-
478
- /**
479
- * A `@postConstruct` or `onActivation` hook that returned a `Promise` on a sync resolution path.
480
- *
481
- * @since 0.3.16-canary.0
482
- */
483
- export class AsyncActivationError extends DiError {
484
- readonly code = "ASYNC_ACTIVATION";
485
- readonly tokenName: string;
486
- readonly hookKind: "postConstruct" | "onActivation";
487
- readonly methodName: string | undefined;
488
-
489
- constructor(tokenName: string, hookKind: "postConstruct" | "onActivation", methodName?: string) {
490
- const detail =
491
- hookKind === "postConstruct"
492
- ? `@postConstruct method '${methodName ?? ""}' returned a Promise`
493
- : `onActivation for '${tokenName}' returned a Promise`;
494
- super(`${detail}. Use resolveAsync() instead.`);
495
- this.tokenName = tokenName;
496
- this.hookKind = hookKind;
497
- this.methodName = methodName;
498
- }
499
- }
package/src/index.ts DELETED
@@ -1,139 +0,0 @@
1
- // Foundation types
2
- export type {
3
- ActivationHandler,
4
- BindingConstraint,
5
- BindingIdentifier,
6
- BindingKind,
7
- BindingScope,
8
- BindingTag,
9
- ConstraintContext,
10
- Constructor,
11
- DependencyKey,
12
- DeactivationHandler,
13
- ResolutionFrame,
14
- ResolveOptions,
15
- ResolutionContext,
16
- TokenValue,
17
- } from "#/core/types";
18
-
19
- // Token
20
- export { token, tokenName } from "#/core/token";
21
- export type { Token } from "#/core/token";
22
-
23
- // Tag — the interned slot criteria a `whenTagged` and a resolve both take
24
- export { coversTagKeys, NO_TAG_KEYS, slotName, tag, tagKeyMaskOf } from "#/core/tag";
25
- export type { TagKey, TagKeyMask } from "#/core/tag";
26
-
27
- // Binding builders — types only
28
- export type {
29
- AliasBindingBuilder,
30
- BindToBuilder,
31
- BindingBuilder,
32
- ConstantBindingBuilder,
33
- ScopedBindingBuilder,
34
- SingletonBindingBuilder,
35
- SingletonLifecycleBuilder,
36
- SlotConstrainedBuilder,
37
- TransientBindingBuilder,
38
- } from "#/core/binding";
39
-
40
- // Container
41
- export { Container } from "#/container/container";
42
- export type { Container as ContainerInterface, ContainerOptions, ContainerStatic } from "#/container/container";
43
-
44
- // Ambient container — the context an `@inject` accessor initializer resolves from. `resolution/context`
45
- // stays internal: it hands out resolver callbacks, not public values.
46
- export { getActiveContainer, runWithContainer } from "#/ambient/active-container";
47
-
48
- // `effectiveBindingScope` is deliberately absent: it reads a `Binding`, which is internal, and no
49
- // public API hands one out. `BindingSnapshot.scope` and `GraphNode.scope` are the public answers.
50
- export {
51
- bindingSlotToResolveOptions,
52
- injectionSlotToResolveOptions,
53
- resolveOptionsForSlot,
54
- } from "#/injection/resolve-options";
55
- export type { DependencySlot } from "#/injection/resolve-options";
56
-
57
- // Introspection types
58
- export type { BindingSnapshot, ContainerSnapshot } from "#/introspection/inspector";
59
-
60
- // Graph types
61
- export type { ContainerGraphJson, GraphEdge, GraphNode, GraphOptions } from "#/introspection/dependency-graph";
62
-
63
- // Module
64
- export { AsyncModule, isSyncModule, Module, SyncModule } from "#/core/module";
65
- export type { AsyncModuleBuilder, ModuleBuilder } from "#/core/module";
66
-
67
- // Decorators
68
- export { inject } from "#/decorators/inject";
69
- export { injectAll, isInjectionDescriptor, optional } from "#/injection/descriptor";
70
- export type { InjectionDescriptor, InjectOptions } from "#/injection/descriptor";
71
- export { injectable } from "#/decorators/injectable";
72
- export type { InjectableDependency, InjectableOptions } from "#/decorators/injectable";
73
- export { postConstruct, preDestroy } from "#/decorators/lifecycle-decorators";
74
-
75
- // Auto-register
76
- export { createAutoRegisterRegistry } from "#/decorators/injectable";
77
- export type { AutoRegisterRegistry } from "#/decorators/injectable";
78
-
79
- // MetadataReader — everything a consumer needs to write one and pass it to Container.create()
80
- export { MetadataReaderToken } from "#/metadata/metadata-reader-token";
81
- export type {
82
- ConstructorMetadata,
83
- LifecycleMetadata,
84
- MetadataReader,
85
- MutableLifecycleMetadata,
86
- ParamMetadata,
87
- } from "#/metadata/metadata-types";
88
- export { defaultMetadataReader, SymbolMetadataReader } from "#/metadata/symbol-metadata-reader";
89
-
90
- // Constraints — contextual injection predicates for .when()
91
- export {
92
- whenAnyAncestorIs,
93
- whenAnyAncestorNamed,
94
- whenAnyAncestorTagged,
95
- whenAnyAncestorTaggedAll,
96
- whenNoAncestorIs,
97
- whenNoParentIs,
98
- whenParentIs,
99
- whenParentNamed,
100
- whenParentTagged,
101
- whenParentTaggedAll,
102
- } from "#/resolution/select/constraints";
103
-
104
- // Errors
105
- export {
106
- AmbiguousBindingError,
107
- AsyncActivationError,
108
- AsyncDeactivationError,
109
- AsyncModuleLoadError,
110
- AsyncResolutionError,
111
- ChainNotRegisteredError,
112
- CircularDependencyError,
113
- DiError,
114
- DisposedContainerError,
115
- InternalError,
116
- InvalidMetadataError,
117
- MissingContainerContextError,
118
- MissingMetadataError,
119
- MissingScopeContextError,
120
- NoMatchingBindingError,
121
- RebindUnboundTokenError,
122
- ScopeViolationError,
123
- SelfBindingRequiresClassError,
124
- StaticMemberDecoratorError,
125
- SyncDisposalNotSupportedError,
126
- EmptyTagCriteriaError,
127
- TokenNotBoundError,
128
- UnreachableConstraintError,
129
- UnreachableLifecycleHookError,
130
- } from "#/errors/errors";
131
- export type { ScopeViolationDetails } from "#/errors/errors";
132
-
133
- // Graph adapters — render `generateDependencyGraph()` output for common viewers
134
- export { toDotGraph } from "#/introspection/graph-adapters/dot";
135
- export { toCytoscapeGraph } from "#/introspection/graph-adapters/cytoscape";
136
- export type { CytoscapeEdge, CytoscapeElements, CytoscapeNode } from "#/introspection/graph-adapters/cytoscape";
137
- export { toReactFlowGraph } from "#/introspection/graph-adapters/reactflow";
138
- export type { ReactFlowEdge, ReactFlowGraph, ReactFlowNode } from "#/introspection/graph-adapters/reactflow";
139
- export { toMermaidGraph } from "#/introspection/graph-adapters/mermaid";