@codefast/di 0.5.0-canary.6 → 0.5.0-canary.8

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 (195) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/README.md +15 -4
  3. package/dist/binding.d.ts +78 -19
  4. package/dist/binding.d.ts.map +1 -1
  5. package/dist/binding.js +46 -2
  6. package/dist/binding.js.map +1 -1
  7. package/dist/constructor-type.d.ts +4 -5
  8. package/dist/constructor-type.d.ts.map +1 -1
  9. package/dist/container/binding-builders.d.ts +56 -0
  10. package/dist/container/binding-builders.d.ts.map +1 -0
  11. package/dist/container/binding-builders.js +196 -0
  12. package/dist/container/binding-builders.js.map +1 -0
  13. package/dist/{container.d.ts → container/container.d.ts} +2 -2
  14. package/dist/container/container.d.ts.map +1 -0
  15. package/dist/container/container.js +624 -0
  16. package/dist/container/container.js.map +1 -0
  17. package/dist/decorators/inject.d.ts +10 -1
  18. package/dist/decorators/inject.d.ts.map +1 -1
  19. package/dist/decorators/inject.js +2 -2
  20. package/dist/decorators/inject.js.map +1 -1
  21. package/dist/decorators/injectable.js +3 -3
  22. package/dist/decorators/injectable.js.map +1 -1
  23. package/dist/errors.d.ts +14 -0
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js +17 -0
  26. package/dist/errors.js.map +1 -1
  27. package/dist/index.d.ts +13 -8
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +9 -5
  30. package/dist/index.js.map +1 -1
  31. package/dist/introspection/dependency-graph.d.ts.map +1 -0
  32. package/dist/{dependency-graph.js → introspection/dependency-graph.js} +1 -1
  33. package/dist/introspection/dependency-graph.js.map +1 -0
  34. package/dist/{graph-adapters → introspection/graph-adapters}/cytoscape.d.ts +1 -1
  35. package/dist/introspection/graph-adapters/cytoscape.d.ts.map +1 -0
  36. package/dist/introspection/graph-adapters/cytoscape.js.map +1 -0
  37. package/dist/introspection/graph-adapters/dot.d.ts +6 -0
  38. package/dist/introspection/graph-adapters/dot.d.ts.map +1 -0
  39. package/dist/introspection/graph-adapters/dot.js.map +1 -0
  40. package/dist/{graph-adapters → introspection/graph-adapters}/reactflow.d.ts +2 -2
  41. package/dist/introspection/graph-adapters/reactflow.d.ts.map +1 -0
  42. package/dist/{graph-adapters → introspection/graph-adapters}/reactflow.js +11 -1
  43. package/dist/introspection/graph-adapters/reactflow.js.map +1 -0
  44. package/dist/{inspector.d.ts → introspection/inspector.d.ts} +3 -8
  45. package/dist/introspection/inspector.d.ts.map +1 -0
  46. package/dist/{inspector.js → introspection/inspector.js} +23 -23
  47. package/dist/introspection/inspector.js.map +1 -0
  48. package/dist/metadata/metadata-keys.d.ts +3 -6
  49. package/dist/metadata/metadata-keys.d.ts.map +1 -1
  50. package/dist/metadata/metadata-keys.js +3 -6
  51. package/dist/metadata/metadata-keys.js.map +1 -1
  52. package/dist/metadata/symbol-metadata-reader.d.ts +1 -1
  53. package/dist/metadata/symbol-metadata-reader.d.ts.map +1 -1
  54. package/dist/metadata/symbol-metadata-reader.js +4 -4
  55. package/dist/metadata/symbol-metadata-reader.js.map +1 -1
  56. package/dist/module.d.ts +9 -2
  57. package/dist/module.d.ts.map +1 -1
  58. package/dist/module.js +9 -2
  59. package/dist/module.js.map +1 -1
  60. package/dist/registry.d.ts +17 -13
  61. package/dist/registry.d.ts.map +1 -1
  62. package/dist/registry.js +94 -63
  63. package/dist/registry.js.map +1 -1
  64. package/dist/resolution/activation-need.d.ts +25 -0
  65. package/dist/resolution/activation-need.d.ts.map +1 -0
  66. package/dist/resolution/activation-need.js +64 -0
  67. package/dist/resolution/activation-need.js.map +1 -0
  68. package/dist/resolution/binding-lookup-cache.d.ts +41 -0
  69. package/dist/resolution/binding-lookup-cache.d.ts.map +1 -0
  70. package/dist/resolution/binding-lookup-cache.js +102 -0
  71. package/dist/resolution/binding-lookup-cache.js.map +1 -0
  72. package/dist/resolution/binding-scope.d.ts.map +1 -0
  73. package/dist/resolution/binding-scope.js.map +1 -0
  74. package/dist/resolution/binding-select.d.ts.map +1 -0
  75. package/dist/{binding-select.js → resolution/binding-select.js} +17 -7
  76. package/dist/resolution/binding-select.js.map +1 -0
  77. package/dist/resolution/class-introspector.d.ts +27 -0
  78. package/dist/resolution/class-introspector.d.ts.map +1 -0
  79. package/dist/resolution/class-introspector.js +60 -0
  80. package/dist/resolution/class-introspector.js.map +1 -0
  81. package/dist/resolution/constraints.d.ts.map +1 -0
  82. package/dist/resolution/constraints.js.map +1 -0
  83. package/dist/resolution/diagnostics.d.ts +41 -0
  84. package/dist/resolution/diagnostics.d.ts.map +1 -0
  85. package/dist/resolution/diagnostics.js +18 -0
  86. package/dist/resolution/diagnostics.js.map +1 -0
  87. package/dist/{environment.d.ts → resolution/environment.d.ts} +24 -7
  88. package/dist/resolution/environment.d.ts.map +1 -0
  89. package/dist/resolution/environment.js +126 -0
  90. package/dist/resolution/environment.js.map +1 -0
  91. package/dist/resolution/instantiation-plan.d.ts +67 -0
  92. package/dist/resolution/instantiation-plan.d.ts.map +1 -0
  93. package/dist/resolution/instantiation-plan.js +183 -0
  94. package/dist/resolution/instantiation-plan.js.map +1 -0
  95. package/dist/{lifecycle.d.ts → resolution/lifecycle.d.ts} +5 -3
  96. package/dist/resolution/lifecycle.d.ts.map +1 -0
  97. package/dist/{lifecycle.js → resolution/lifecycle.js} +23 -14
  98. package/dist/resolution/lifecycle.js.map +1 -0
  99. package/dist/resolution/resolution-path.d.ts +22 -0
  100. package/dist/resolution/resolution-path.d.ts.map +1 -0
  101. package/dist/resolution/resolution-path.js +40 -0
  102. package/dist/resolution/resolution-path.js.map +1 -0
  103. package/dist/resolution/resolve-options.d.ts.map +1 -0
  104. package/dist/resolution/resolve-options.js.map +1 -0
  105. package/dist/resolution/resolver.d.ts +40 -0
  106. package/dist/resolution/resolver.d.ts.map +1 -0
  107. package/dist/resolution/resolver.js +1108 -0
  108. package/dist/resolution/resolver.js.map +1 -0
  109. package/dist/{scope.d.ts → resolution/scope.d.ts} +8 -9
  110. package/dist/resolution/scope.d.ts.map +1 -0
  111. package/dist/resolution/scope.js +80 -0
  112. package/dist/resolution/scope.js.map +1 -0
  113. package/dist/token.d.ts.map +1 -1
  114. package/dist/token.js +0 -3
  115. package/dist/token.js.map +1 -1
  116. package/package.json +19 -94
  117. package/src/binding.ts +137 -22
  118. package/src/constructor-type.ts +4 -5
  119. package/src/container/binding-builders.ts +294 -0
  120. package/src/container/container.ts +825 -0
  121. package/src/decorators/inject.ts +15 -4
  122. package/src/decorators/injectable.ts +3 -3
  123. package/src/errors.ts +21 -0
  124. package/src/index.ts +15 -7
  125. package/src/{dependency-graph.ts → introspection/dependency-graph.ts} +1 -1
  126. package/src/{graph-adapters → introspection/graph-adapters}/cytoscape.ts +1 -1
  127. package/src/{graph-adapters → introspection/graph-adapters}/dot.ts +1 -1
  128. package/src/{graph-adapters → introspection/graph-adapters}/reactflow.ts +13 -2
  129. package/src/{inspector.ts → introspection/inspector.ts} +26 -21
  130. package/src/metadata/metadata-keys.ts +3 -6
  131. package/src/metadata/symbol-metadata-reader.ts +4 -4
  132. package/src/module.ts +14 -6
  133. package/src/registry.ts +97 -64
  134. package/src/resolution/activation-need.ts +81 -0
  135. package/src/resolution/binding-lookup-cache.ts +132 -0
  136. package/src/{binding-select.ts → resolution/binding-select.ts} +17 -7
  137. package/src/resolution/class-introspector.ts +74 -0
  138. package/src/resolution/diagnostics.ts +43 -0
  139. package/src/{environment.ts → resolution/environment.ts} +65 -35
  140. package/src/resolution/instantiation-plan.ts +292 -0
  141. package/src/{lifecycle.ts → resolution/lifecycle.ts} +26 -14
  142. package/src/resolution/resolution-path.ts +62 -0
  143. package/src/resolution/resolver.ts +1526 -0
  144. package/src/resolution/scope.ts +95 -0
  145. package/src/token.ts +0 -3
  146. package/dist/binding-scope.d.ts.map +0 -1
  147. package/dist/binding-scope.js.map +0 -1
  148. package/dist/binding-select.d.ts.map +0 -1
  149. package/dist/binding-select.js.map +0 -1
  150. package/dist/constraints.d.ts.map +0 -1
  151. package/dist/constraints.js.map +0 -1
  152. package/dist/container.d.ts.map +0 -1
  153. package/dist/container.js +0 -853
  154. package/dist/container.js.map +0 -1
  155. package/dist/dependency-graph.d.ts.map +0 -1
  156. package/dist/dependency-graph.js.map +0 -1
  157. package/dist/environment.d.ts.map +0 -1
  158. package/dist/environment.js +0 -100
  159. package/dist/environment.js.map +0 -1
  160. package/dist/graph-adapters/cytoscape.d.ts.map +0 -1
  161. package/dist/graph-adapters/cytoscape.js.map +0 -1
  162. package/dist/graph-adapters/dot.d.ts +0 -6
  163. package/dist/graph-adapters/dot.d.ts.map +0 -1
  164. package/dist/graph-adapters/dot.js.map +0 -1
  165. package/dist/graph-adapters/reactflow.d.ts.map +0 -1
  166. package/dist/graph-adapters/reactflow.js.map +0 -1
  167. package/dist/inspector.d.ts.map +0 -1
  168. package/dist/inspector.js.map +0 -1
  169. package/dist/lifecycle.d.ts.map +0 -1
  170. package/dist/lifecycle.js.map +0 -1
  171. package/dist/resolve-options.d.ts.map +0 -1
  172. package/dist/resolve-options.js.map +0 -1
  173. package/dist/resolver.d.ts +0 -90
  174. package/dist/resolver.d.ts.map +0 -1
  175. package/dist/resolver.js +0 -1208
  176. package/dist/resolver.js.map +0 -1
  177. package/dist/scope.d.ts.map +0 -1
  178. package/dist/scope.js +0 -61
  179. package/dist/scope.js.map +0 -1
  180. package/src/container.ts +0 -1141
  181. package/src/resolver.ts +0 -1626
  182. package/src/scope.ts +0 -77
  183. /package/dist/{dependency-graph.d.ts → introspection/dependency-graph.d.ts} +0 -0
  184. /package/dist/{graph-adapters → introspection/graph-adapters}/cytoscape.js +0 -0
  185. /package/dist/{graph-adapters → introspection/graph-adapters}/dot.js +0 -0
  186. /package/dist/{binding-scope.d.ts → resolution/binding-scope.d.ts} +0 -0
  187. /package/dist/{binding-scope.js → resolution/binding-scope.js} +0 -0
  188. /package/dist/{binding-select.d.ts → resolution/binding-select.d.ts} +0 -0
  189. /package/dist/{constraints.d.ts → resolution/constraints.d.ts} +0 -0
  190. /package/dist/{constraints.js → resolution/constraints.js} +0 -0
  191. /package/dist/{resolve-options.d.ts → resolution/resolve-options.d.ts} +0 -0
  192. /package/dist/{resolve-options.js → resolution/resolve-options.js} +0 -0
  193. /package/src/{binding-scope.ts → resolution/binding-scope.ts} +0 -0
  194. /package/src/{constraints.ts → resolution/constraints.ts} +0 -0
  195. /package/src/{resolve-options.ts → resolution/resolve-options.ts} +0 -0
@@ -1,9 +1,9 @@
1
- import { getActiveContainer } from "#/environment";
2
1
  import { InternalError, MissingContainerContextError } from "#/errors";
3
2
  import { INJECT_ACCESSOR_KEY } from "#/metadata/metadata-keys";
4
- import { injectionSlotToResolveOptions } from "#/resolve-options";
3
+ import { getActiveContainer } from "#/resolution/environment";
4
+ import { injectionSlotToResolveOptions } from "#/resolution/resolve-options";
5
5
  import type { Token } from "#/token";
6
- import type { BindingTag, Constructor } from "#/types";
6
+ import type { BindingTag, Constructor, TokenValue } from "#/types";
7
7
 
8
8
  // ── InjectionDescriptor ───────────────────────────────────────────────────────
9
9
 
@@ -31,6 +31,17 @@ export interface InjectionDescriptor<Value = unknown> {
31
31
  */
32
32
  export type InjectableDependency<Value = unknown> = Token<Value> | Constructor<Value> | InjectionDescriptor<Value>;
33
33
 
34
+ /**
35
+ * The value a factory receives for one declared dependency.
36
+ *
37
+ * @remarks `optional()` and `injectAll()` fold their effect into the descriptor's own type
38
+ * parameter, so reading it back is enough; bare tokens fall through to {@link TokenValue}.
39
+ *
40
+ * @since 0.5.0-canary.7
41
+ */
42
+ export type ResolvedDependencyValue<Dependency> =
43
+ Dependency extends InjectionDescriptor<infer Value> ? Value : TokenValue<Dependency>;
44
+
34
45
  /**
35
46
  * @since 0.3.16-canary.0
36
47
  */
@@ -182,7 +193,7 @@ export function inject<const Value>(
182
193
  }
183
194
  Object.defineProperties(decoratorFn, props);
184
195
 
185
- return decoratorFn as unknown as InjectionDescriptor<Value> & ClassAccessorDecorator<unknown, Value>;
196
+ return decoratorFn as InjectionDescriptor<Value> & ClassAccessorDecorator<unknown, Value>;
186
197
  }
187
198
 
188
199
  // ── optional() ────────────────────────────────────────────────────────────────
@@ -18,13 +18,13 @@ export interface AutoRegisterRegistry {
18
18
  * @since 0.3.16-canary.0
19
19
  */
20
20
  export function createAutoRegisterRegistry(): AutoRegisterRegistry {
21
- const _registeredEntries: Array<{ target: Constructor; scope: BindingScope }> = [];
21
+ const registeredEntries: Array<{ target: Constructor; scope: BindingScope }> = [];
22
22
  return {
23
23
  register(target: Constructor, scope: BindingScope): void {
24
- _registeredEntries.push({ target, scope });
24
+ registeredEntries.push({ target, scope });
25
25
  },
26
26
  entries(): ReadonlyArray<{ target: Constructor; scope: BindingScope }> {
27
- return _registeredEntries;
27
+ return registeredEntries;
28
28
  },
29
29
  };
30
30
  }
package/src/errors.ts CHANGED
@@ -212,6 +212,27 @@ export class MissingContainerContextError extends DiError {
212
212
  }
213
213
  }
214
214
 
215
+ /**
216
+ * A fluent chain was refined before a `to*()` call gave it a binding to refine.
217
+ *
218
+ * @remarks The builder types make this unreachable from TypeScript — `bind()` returns
219
+ * `BindToBuilder`, which exposes only `to*()`. It exists for JavaScript callers and for anyone who
220
+ * casts past the types, so the misuse fails loudly instead of mutating nothing.
221
+ *
222
+ * @since 0.5.0-canary.8
223
+ */
224
+ export class ChainNotRegisteredError extends DiError {
225
+ readonly code = "CHAIN_NOT_REGISTERED";
226
+ readonly tokenName: string;
227
+
228
+ constructor(tokenName: string) {
229
+ super(
230
+ `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).`,
231
+ );
232
+ this.tokenName = tokenName;
233
+ }
234
+ }
235
+
215
236
  /**
216
237
  * @since 0.3.16-canary.0
217
238
  */
package/src/index.ts CHANGED
@@ -33,17 +33,17 @@ export type {
33
33
  } from "#/binding";
34
34
 
35
35
  // Container
36
- export { Container } from "#/container";
37
- export type { Container as ContainerInterface, ContainerStatic } from "#/container";
36
+ export { Container } from "#/container/container";
37
+ export type { Container as ContainerInterface, ContainerStatic } from "#/container/container";
38
38
 
39
- export { effectiveBindingScope } from "#/binding-scope";
40
- export { injectionSlotToResolveOptions, bindingSlotToResolveOptions } from "#/resolve-options";
39
+ export { effectiveBindingScope } from "#/resolution/binding-scope";
40
+ export { injectionSlotToResolveOptions, bindingSlotToResolveOptions } from "#/resolution/resolve-options";
41
41
 
42
42
  // Introspection types
43
- export type { BindingSnapshot, ContainerSnapshot } from "#/inspector";
43
+ export type { BindingSnapshot, ContainerSnapshot } from "#/introspection/inspector";
44
44
 
45
45
  // Graph types
46
- export type { ContainerGraphJson, GraphEdge, GraphNode, GraphOptions } from "#/dependency-graph";
46
+ export type { ContainerGraphJson, GraphEdge, GraphNode, GraphOptions } from "#/introspection/dependency-graph";
47
47
 
48
48
  // Module
49
49
  export { AsyncModule, isSyncModule, Module, SyncModule } from "#/module";
@@ -76,7 +76,7 @@ export {
76
76
  whenParentNamed,
77
77
  whenParentTagged,
78
78
  whenParentTaggedAll,
79
- } from "#/constraints";
79
+ } from "#/resolution/constraints";
80
80
 
81
81
  // Errors
82
82
  export {
@@ -85,6 +85,7 @@ export {
85
85
  AsyncDeactivationError,
86
86
  AsyncModuleLoadError,
87
87
  AsyncResolutionError,
88
+ ChainNotRegisteredError,
88
89
  CircularDependencyError,
89
90
  DiError,
90
91
  DisposedContainerError,
@@ -99,3 +100,10 @@ export {
99
100
  TokenNotBoundError,
100
101
  } from "#/errors";
101
102
  export type { ScopeViolationDetails } from "#/errors";
103
+
104
+ // Graph adapters — render `generateDependencyGraph()` output for common viewers
105
+ export { toDotGraph } from "#/introspection/graph-adapters/dot";
106
+ export { toCytoscapeGraph } from "#/introspection/graph-adapters/cytoscape";
107
+ export type { CytoscapeEdge, CytoscapeElements, CytoscapeNode } from "#/introspection/graph-adapters/cytoscape";
108
+ export { toReactFlowGraph } from "#/introspection/graph-adapters/reactflow";
109
+ export type { ReactFlowEdge, ReactFlowGraph, ReactFlowNode } from "#/introspection/graph-adapters/reactflow";
@@ -1,6 +1,6 @@
1
- import { effectiveBindingScope } from "#/binding-scope";
2
1
  import type { MetadataReader } from "#/metadata/metadata-types";
3
2
  import type { BindingRegistry } from "#/registry";
3
+ import { effectiveBindingScope } from "#/resolution/binding-scope";
4
4
  import { tokenName } from "#/token";
5
5
  import type { BindingScope, Constructor } from "#/types";
6
6
 
@@ -1,4 +1,4 @@
1
- import type { ContainerGraphJson } from "#/dependency-graph";
1
+ import type { ContainerGraphJson } from "#/introspection/dependency-graph";
2
2
 
3
3
  /**
4
4
  * @since 0.3.16-canary.0
@@ -1,4 +1,4 @@
1
- import type { ContainerGraphJson } from "#/dependency-graph";
1
+ import type { ContainerGraphJson } from "#/introspection/dependency-graph";
2
2
 
3
3
  /**
4
4
  * @since 0.3.16-canary.0
@@ -1,4 +1,4 @@
1
- import type { ContainerGraphJson } from "#/dependency-graph";
1
+ import type { ContainerGraphJson } from "#/introspection/dependency-graph";
2
2
 
3
3
  /**
4
4
  * @since 0.3.16-canary.0
@@ -35,6 +35,14 @@ export interface ReactFlowGraph {
35
35
  /**
36
36
  * @since 0.3.16-canary.0
37
37
  */
38
+ // Initial grid layout: React Flow expects concrete positions; viewers re-layout anyway.
39
+ const GRID_COLUMN_COUNT = 5;
40
+ const GRID_CELL_WIDTH_PX = 200;
41
+ const GRID_CELL_HEIGHT_PX = 100;
42
+
43
+ /**
44
+ * @since 0.5.0-canary.7
45
+ */
38
46
  export function toReactFlowGraph(graph: ContainerGraphJson): ReactFlowGraph {
39
47
  const nodes: Array<ReactFlowNode> = graph.nodes.map((node, idx) => ({
40
48
  id: node.id,
@@ -44,7 +52,10 @@ export function toReactFlowGraph(graph: ContainerGraphJson): ReactFlowGraph {
44
52
  scope: node.scope,
45
53
  fromParent: node.fromParent,
46
54
  },
47
- position: { x: (idx % 5) * 200, y: Math.floor(idx / 5) * 100 },
55
+ position: {
56
+ x: (idx % GRID_COLUMN_COUNT) * GRID_CELL_WIDTH_PX,
57
+ y: Math.floor(idx / GRID_COLUMN_COUNT) * GRID_CELL_HEIGHT_PX,
58
+ },
48
59
  }));
49
60
 
50
61
  const edges: Array<ReactFlowEdge> = graph.edges.map((edge, idx) => ({
@@ -1,8 +1,8 @@
1
1
  import type { Binding } from "#/binding";
2
- import { effectiveBindingScope } from "#/binding-scope";
3
- import { selectBinding } from "#/binding-select";
4
2
  import type { BindingRegistry } from "#/registry";
5
- import type { ScopeManager } from "#/scope";
3
+ import { effectiveBindingScope } from "#/resolution/binding-scope";
4
+ import { selectBinding } from "#/resolution/binding-select";
5
+ import type { ScopeManager } from "#/resolution/scope";
6
6
  import type { Token } from "#/token";
7
7
  import { tokenName } from "#/token";
8
8
  import type {
@@ -47,33 +47,38 @@ export interface ContainerSnapshot {
47
47
  * @since 0.3.16-canary.0
48
48
  */
49
49
  export class Inspector {
50
- constructor(
51
- private readonly _registry: BindingRegistry,
52
- private readonly _scope: ScopeManager,
53
- private readonly _hasParent: boolean,
54
- private readonly _isDisposed: () => boolean,
55
- ) {}
50
+ readonly #registry: BindingRegistry;
51
+ readonly #scope: ScopeManager;
52
+ readonly #hasParent: boolean;
53
+ readonly #isDisposed: () => boolean;
54
+
55
+ constructor(registry: BindingRegistry, scope: ScopeManager, hasParent: boolean, isDisposed: () => boolean) {
56
+ this.#registry = registry;
57
+ this.#scope = scope;
58
+ this.#hasParent = hasParent;
59
+ this.#isDisposed = isDisposed;
60
+ }
56
61
 
57
62
  inspect(): ContainerSnapshot {
58
63
  const snapshots = this.allBindingSnapshots();
59
64
  return {
60
65
  ownBindings: snapshots,
61
- cachedSingletonCount: this._scope.getAllSingletons().size,
62
- hasParent: this._hasParent,
63
- isDisposed: this._isDisposed(),
66
+ cachedSingletonCount: this.#scope.cachedSingletons().length,
67
+ hasParent: this.#hasParent,
68
+ isDisposed: this.#isDisposed(),
64
69
  };
65
70
  }
66
71
 
67
72
  lookupBindings<Value>(token: Token<Value> | Constructor<Value>): ReadonlyArray<BindingSnapshot> {
68
- const bindings = this._registry.getAll(token);
69
- return bindings.map((binding) => this._toSnapshot(binding));
73
+ const bindings = this.#registry.getAll(token);
74
+ return bindings.map((binding) => this.#toSnapshot(binding));
70
75
  }
71
76
 
72
77
  has(token: Token<unknown> | Constructor, options?: ResolveOptions, parentHas?: () => boolean): boolean {
73
- const bindings = this._registry.getAll(token);
78
+ const bindings = this.#registry.getAll(token);
74
79
  if (bindings.length > 0) {
75
80
  if (options !== undefined) {
76
- if (selectBinding(bindings, options, this._makeConstraintContext(options), tokenName(token)) !== undefined) {
81
+ if (selectBinding(bindings, options, this.#makeConstraintContext(options), tokenName(token)) !== undefined) {
77
82
  return true;
78
83
  }
79
84
  } else {
@@ -84,17 +89,17 @@ export class Inspector {
84
89
  }
85
90
 
86
91
  hasOwn(token: Token<unknown> | Constructor, options?: ResolveOptions): boolean {
87
- const bindings = this._registry.getAll(token);
92
+ const bindings = this.#registry.getAll(token);
88
93
  if (bindings.length === 0) {
89
94
  return false;
90
95
  }
91
96
  if (options !== undefined) {
92
- return selectBinding(bindings, options, this._makeConstraintContext(options), tokenName(token)) !== undefined;
97
+ return selectBinding(bindings, options, this.#makeConstraintContext(options), tokenName(token)) !== undefined;
93
98
  }
94
99
  return true;
95
100
  }
96
101
 
97
- private _makeConstraintContext(options: ResolveOptions): ConstraintContext {
102
+ #makeConstraintContext(options: ResolveOptions): ConstraintContext {
98
103
  return {
99
104
  resolutionPath: [],
100
105
  resolutionStack: [],
@@ -105,10 +110,10 @@ export class Inspector {
105
110
  }
106
111
 
107
112
  private allBindingSnapshots(): ReadonlyArray<BindingSnapshot> {
108
- return this._registry.allBindings().map((binding) => this._toSnapshot(binding));
113
+ return this.#registry.allBindings().map((binding) => this.#toSnapshot(binding));
109
114
  }
110
115
 
111
- private _toSnapshot(binding: Binding): BindingSnapshot {
116
+ #toSnapshot(binding: Binding): BindingSnapshot {
112
117
  const scope = effectiveBindingScope(binding);
113
118
  const slot: BindingSnapshot["slot"] =
114
119
  binding.slot.name !== undefined
@@ -12,13 +12,10 @@ export const LIFECYCLE_KEY: unique symbol = Symbol("di:lifecycle");
12
12
  export const INJECT_ACCESSOR_KEY: unique symbol = Symbol("di:inject-accessor");
13
13
 
14
14
  /**
15
- * The well-known symbol used by TC39 Stage 3 decorator transforms to store class metadata.
15
+ * The symbol TC39 Stage 3 decorator transforms store class metadata under.
16
16
  *
17
- * `Symbol.metadata` is defined natively once the runtime ships the full TC39 decorator
18
- * proposal. Until then (current Node.js / browsers), Babel and esbuild both fall back to
19
- * `Symbol.for("Symbol.metadata")` — a global-registry symbol with the same string key.
20
- * Resolving it here once keeps the reader and the decorator transforms in sync regardless
21
- * of which path is taken.
17
+ * @remarks Falls back to the global-registry symbol, which is what Babel and esbuild emit until
18
+ * a runtime ships `Symbol.metadata` natively.
22
19
  *
23
20
  * @since 0.3.16-canary.0
24
21
  */
@@ -7,7 +7,7 @@ import type { Constructor } from "#/types";
7
7
  * @since 0.3.16-canary.0
8
8
  */
9
9
  export class SymbolMetadataReader implements MetadataReader {
10
- private _getMetadataRecord(target: Constructor, key: string | symbol): Record<string | symbol, unknown> | undefined {
10
+ #getMetadataRecord(target: Constructor, key: string | symbol): Record<string | symbol, unknown> | undefined {
11
11
  const descriptor = Object.getOwnPropertyDescriptor(target, METADATA_SYMBOL);
12
12
  if (descriptor === undefined) {
13
13
  return undefined;
@@ -20,19 +20,19 @@ export class SymbolMetadataReader implements MetadataReader {
20
20
  }
21
21
 
22
22
  getConstructorMetadata(target: Constructor): ConstructorMetadata | undefined {
23
- const record = this._getMetadataRecord(target, INJECTABLE_KEY);
23
+ const record = this.#getMetadataRecord(target, INJECTABLE_KEY);
24
24
  return record?.[INJECTABLE_KEY] as ConstructorMetadata | undefined;
25
25
  }
26
26
 
27
27
  getLifecycleMetadata(target: Constructor): LifecycleMetadata | undefined {
28
- const record = this._getMetadataRecord(target, LIFECYCLE_KEY);
28
+ const record = this.#getMetadataRecord(target, LIFECYCLE_KEY);
29
29
  return record?.[LIFECYCLE_KEY] as LifecycleMetadata | undefined;
30
30
  }
31
31
 
32
32
  getAccessorMetadata(
33
33
  target: Constructor,
34
34
  ): Array<{ key: string | symbol; descriptor: InjectionDescriptor }> | undefined {
35
- const record = this._getMetadataRecord(target, INJECT_ACCESSOR_KEY);
35
+ const record = this.#getMetadataRecord(target, INJECT_ACCESSOR_KEY);
36
36
  return record?.[INJECT_ACCESSOR_KEY] as
37
37
  | Array<{ key: string | symbol; descriptor: InjectionDescriptor }>
38
38
  | undefined;
package/src/module.ts CHANGED
@@ -7,13 +7,21 @@ import type { Constructor } from "#/types";
7
7
  const SYNC_MODULE_BRAND: unique symbol = Symbol("di:sync-module");
8
8
  const ASYNC_MODULE_BRAND: unique symbol = Symbol("di:async-module");
9
9
 
10
+ /**
11
+ * Key for the module's setup callback. A symbol (not exported from the package root)
12
+ * keeps the container-only member out of consumer-facing autocomplete entirely.
13
+ *
14
+ * @since 0.5.0-canary.7
15
+ */
16
+ export const MODULE_SETUP: unique symbol = Symbol("di:module-setup");
17
+
10
18
  /**
11
19
  * @since 0.3.16-canary.0
12
20
  */
13
21
  export interface SyncModule {
14
22
  readonly name: string;
15
23
  readonly [SYNC_MODULE_BRAND]: true;
16
- readonly _setup: (builder: ModuleBuilder) => void;
24
+ readonly [MODULE_SETUP]: (builder: ModuleBuilder) => void;
17
25
  }
18
26
 
19
27
  /**
@@ -22,7 +30,7 @@ export interface SyncModule {
22
30
  export interface AsyncModule {
23
31
  readonly name: string;
24
32
  readonly [ASYNC_MODULE_BRAND]: true;
25
- readonly _setup: (builder: AsyncModuleBuilder) => Promise<void>;
33
+ readonly [MODULE_SETUP]: (builder: AsyncModuleBuilder) => Promise<void>;
26
34
  }
27
35
 
28
36
  // ── Builder interfaces ────────────────────────────────────────────────────────
@@ -53,8 +61,8 @@ export const SyncModule = {
53
61
  return {
54
62
  name,
55
63
  [SYNC_MODULE_BRAND]: true as const,
56
- _setup: setup,
57
- } as SyncModule;
64
+ [MODULE_SETUP]: setup,
65
+ };
58
66
  },
59
67
  };
60
68
 
@@ -66,8 +74,8 @@ export const AsyncModule = {
66
74
  return {
67
75
  name,
68
76
  [ASYNC_MODULE_BRAND]: true as const,
69
- _setup: setup,
70
- } as AsyncModule;
77
+ [MODULE_SETUP]: setup,
78
+ };
71
79
  },
72
80
  };
73
81