@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.
- package/CHANGELOG.md +123 -0
- package/README.md +15 -4
- package/dist/binding.d.ts +78 -19
- package/dist/binding.d.ts.map +1 -1
- package/dist/binding.js +46 -2
- package/dist/binding.js.map +1 -1
- package/dist/constructor-type.d.ts +4 -5
- package/dist/constructor-type.d.ts.map +1 -1
- package/dist/container/binding-builders.d.ts +56 -0
- package/dist/container/binding-builders.d.ts.map +1 -0
- package/dist/container/binding-builders.js +196 -0
- package/dist/container/binding-builders.js.map +1 -0
- package/dist/{container.d.ts → container/container.d.ts} +2 -2
- package/dist/container/container.d.ts.map +1 -0
- package/dist/container/container.js +624 -0
- package/dist/container/container.js.map +1 -0
- package/dist/decorators/inject.d.ts +10 -1
- package/dist/decorators/inject.d.ts.map +1 -1
- package/dist/decorators/inject.js +2 -2
- package/dist/decorators/inject.js.map +1 -1
- package/dist/decorators/injectable.js +3 -3
- package/dist/decorators/injectable.js.map +1 -1
- package/dist/errors.d.ts +14 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +17 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +13 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/introspection/dependency-graph.d.ts.map +1 -0
- package/dist/{dependency-graph.js → introspection/dependency-graph.js} +1 -1
- package/dist/introspection/dependency-graph.js.map +1 -0
- package/dist/{graph-adapters → introspection/graph-adapters}/cytoscape.d.ts +1 -1
- package/dist/introspection/graph-adapters/cytoscape.d.ts.map +1 -0
- package/dist/introspection/graph-adapters/cytoscape.js.map +1 -0
- package/dist/introspection/graph-adapters/dot.d.ts +6 -0
- package/dist/introspection/graph-adapters/dot.d.ts.map +1 -0
- package/dist/introspection/graph-adapters/dot.js.map +1 -0
- package/dist/{graph-adapters → introspection/graph-adapters}/reactflow.d.ts +2 -2
- package/dist/introspection/graph-adapters/reactflow.d.ts.map +1 -0
- package/dist/{graph-adapters → introspection/graph-adapters}/reactflow.js +11 -1
- package/dist/introspection/graph-adapters/reactflow.js.map +1 -0
- package/dist/{inspector.d.ts → introspection/inspector.d.ts} +3 -8
- package/dist/introspection/inspector.d.ts.map +1 -0
- package/dist/{inspector.js → introspection/inspector.js} +23 -23
- package/dist/introspection/inspector.js.map +1 -0
- package/dist/metadata/metadata-keys.d.ts +3 -6
- package/dist/metadata/metadata-keys.d.ts.map +1 -1
- package/dist/metadata/metadata-keys.js +3 -6
- package/dist/metadata/metadata-keys.js.map +1 -1
- package/dist/metadata/symbol-metadata-reader.d.ts +1 -1
- package/dist/metadata/symbol-metadata-reader.d.ts.map +1 -1
- package/dist/metadata/symbol-metadata-reader.js +4 -4
- package/dist/metadata/symbol-metadata-reader.js.map +1 -1
- package/dist/module.d.ts +9 -2
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +9 -2
- package/dist/module.js.map +1 -1
- package/dist/registry.d.ts +17 -13
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +94 -63
- package/dist/registry.js.map +1 -1
- package/dist/resolution/activation-need.d.ts +25 -0
- package/dist/resolution/activation-need.d.ts.map +1 -0
- package/dist/resolution/activation-need.js +64 -0
- package/dist/resolution/activation-need.js.map +1 -0
- package/dist/resolution/binding-lookup-cache.d.ts +41 -0
- package/dist/resolution/binding-lookup-cache.d.ts.map +1 -0
- package/dist/resolution/binding-lookup-cache.js +102 -0
- package/dist/resolution/binding-lookup-cache.js.map +1 -0
- package/dist/resolution/binding-scope.d.ts.map +1 -0
- package/dist/resolution/binding-scope.js.map +1 -0
- package/dist/resolution/binding-select.d.ts.map +1 -0
- package/dist/{binding-select.js → resolution/binding-select.js} +17 -7
- package/dist/resolution/binding-select.js.map +1 -0
- package/dist/resolution/class-introspector.d.ts +27 -0
- package/dist/resolution/class-introspector.d.ts.map +1 -0
- package/dist/resolution/class-introspector.js +60 -0
- package/dist/resolution/class-introspector.js.map +1 -0
- package/dist/resolution/constraints.d.ts.map +1 -0
- package/dist/resolution/constraints.js.map +1 -0
- package/dist/resolution/diagnostics.d.ts +41 -0
- package/dist/resolution/diagnostics.d.ts.map +1 -0
- package/dist/resolution/diagnostics.js +18 -0
- package/dist/resolution/diagnostics.js.map +1 -0
- package/dist/{environment.d.ts → resolution/environment.d.ts} +24 -7
- package/dist/resolution/environment.d.ts.map +1 -0
- package/dist/resolution/environment.js +126 -0
- package/dist/resolution/environment.js.map +1 -0
- package/dist/resolution/instantiation-plan.d.ts +67 -0
- package/dist/resolution/instantiation-plan.d.ts.map +1 -0
- package/dist/resolution/instantiation-plan.js +183 -0
- package/dist/resolution/instantiation-plan.js.map +1 -0
- package/dist/{lifecycle.d.ts → resolution/lifecycle.d.ts} +5 -3
- package/dist/resolution/lifecycle.d.ts.map +1 -0
- package/dist/{lifecycle.js → resolution/lifecycle.js} +23 -14
- package/dist/resolution/lifecycle.js.map +1 -0
- package/dist/resolution/resolution-path.d.ts +22 -0
- package/dist/resolution/resolution-path.d.ts.map +1 -0
- package/dist/resolution/resolution-path.js +40 -0
- package/dist/resolution/resolution-path.js.map +1 -0
- package/dist/resolution/resolve-options.d.ts.map +1 -0
- package/dist/resolution/resolve-options.js.map +1 -0
- package/dist/resolution/resolver.d.ts +40 -0
- package/dist/resolution/resolver.d.ts.map +1 -0
- package/dist/resolution/resolver.js +1108 -0
- package/dist/resolution/resolver.js.map +1 -0
- package/dist/{scope.d.ts → resolution/scope.d.ts} +8 -9
- package/dist/resolution/scope.d.ts.map +1 -0
- package/dist/resolution/scope.js +80 -0
- package/dist/resolution/scope.js.map +1 -0
- package/dist/token.d.ts.map +1 -1
- package/dist/token.js +0 -3
- package/dist/token.js.map +1 -1
- package/package.json +19 -94
- package/src/binding.ts +137 -22
- package/src/constructor-type.ts +4 -5
- package/src/container/binding-builders.ts +294 -0
- package/src/container/container.ts +825 -0
- package/src/decorators/inject.ts +15 -4
- package/src/decorators/injectable.ts +3 -3
- package/src/errors.ts +21 -0
- package/src/index.ts +15 -7
- package/src/{dependency-graph.ts → introspection/dependency-graph.ts} +1 -1
- package/src/{graph-adapters → introspection/graph-adapters}/cytoscape.ts +1 -1
- package/src/{graph-adapters → introspection/graph-adapters}/dot.ts +1 -1
- package/src/{graph-adapters → introspection/graph-adapters}/reactflow.ts +13 -2
- package/src/{inspector.ts → introspection/inspector.ts} +26 -21
- package/src/metadata/metadata-keys.ts +3 -6
- package/src/metadata/symbol-metadata-reader.ts +4 -4
- package/src/module.ts +14 -6
- package/src/registry.ts +97 -64
- package/src/resolution/activation-need.ts +81 -0
- package/src/resolution/binding-lookup-cache.ts +132 -0
- package/src/{binding-select.ts → resolution/binding-select.ts} +17 -7
- package/src/resolution/class-introspector.ts +74 -0
- package/src/resolution/diagnostics.ts +43 -0
- package/src/{environment.ts → resolution/environment.ts} +65 -35
- package/src/resolution/instantiation-plan.ts +292 -0
- package/src/{lifecycle.ts → resolution/lifecycle.ts} +26 -14
- package/src/resolution/resolution-path.ts +62 -0
- package/src/resolution/resolver.ts +1526 -0
- package/src/resolution/scope.ts +95 -0
- package/src/token.ts +0 -3
- package/dist/binding-scope.d.ts.map +0 -1
- package/dist/binding-scope.js.map +0 -1
- package/dist/binding-select.d.ts.map +0 -1
- package/dist/binding-select.js.map +0 -1
- package/dist/constraints.d.ts.map +0 -1
- package/dist/constraints.js.map +0 -1
- package/dist/container.d.ts.map +0 -1
- package/dist/container.js +0 -853
- package/dist/container.js.map +0 -1
- package/dist/dependency-graph.d.ts.map +0 -1
- package/dist/dependency-graph.js.map +0 -1
- package/dist/environment.d.ts.map +0 -1
- package/dist/environment.js +0 -100
- package/dist/environment.js.map +0 -1
- package/dist/graph-adapters/cytoscape.d.ts.map +0 -1
- package/dist/graph-adapters/cytoscape.js.map +0 -1
- package/dist/graph-adapters/dot.d.ts +0 -6
- package/dist/graph-adapters/dot.d.ts.map +0 -1
- package/dist/graph-adapters/dot.js.map +0 -1
- package/dist/graph-adapters/reactflow.d.ts.map +0 -1
- package/dist/graph-adapters/reactflow.js.map +0 -1
- package/dist/inspector.d.ts.map +0 -1
- package/dist/inspector.js.map +0 -1
- package/dist/lifecycle.d.ts.map +0 -1
- package/dist/lifecycle.js.map +0 -1
- package/dist/resolve-options.d.ts.map +0 -1
- package/dist/resolve-options.js.map +0 -1
- package/dist/resolver.d.ts +0 -90
- package/dist/resolver.d.ts.map +0 -1
- package/dist/resolver.js +0 -1208
- package/dist/resolver.js.map +0 -1
- package/dist/scope.d.ts.map +0 -1
- package/dist/scope.js +0 -61
- package/dist/scope.js.map +0 -1
- package/src/container.ts +0 -1141
- package/src/resolver.ts +0 -1626
- package/src/scope.ts +0 -77
- /package/dist/{dependency-graph.d.ts → introspection/dependency-graph.d.ts} +0 -0
- /package/dist/{graph-adapters → introspection/graph-adapters}/cytoscape.js +0 -0
- /package/dist/{graph-adapters → introspection/graph-adapters}/dot.js +0 -0
- /package/dist/{binding-scope.d.ts → resolution/binding-scope.d.ts} +0 -0
- /package/dist/{binding-scope.js → resolution/binding-scope.js} +0 -0
- /package/dist/{binding-select.d.ts → resolution/binding-select.d.ts} +0 -0
- /package/dist/{constraints.d.ts → resolution/constraints.d.ts} +0 -0
- /package/dist/{constraints.js → resolution/constraints.js} +0 -0
- /package/dist/{resolve-options.d.ts → resolution/resolve-options.d.ts} +0 -0
- /package/dist/{resolve-options.js → resolution/resolve-options.js} +0 -0
- /package/src/{binding-scope.ts → resolution/binding-scope.ts} +0 -0
- /package/src/{constraints.ts → resolution/constraints.ts} +0 -0
- /package/src/{resolve-options.ts → resolution/resolve-options.ts} +0 -0
package/src/decorators/inject.ts
CHANGED
|
@@ -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 {
|
|
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
|
|
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
|
|
21
|
+
const registeredEntries: Array<{ target: Constructor; scope: BindingScope }> = [];
|
|
22
22
|
return {
|
|
23
23
|
register(target: Constructor, scope: BindingScope): void {
|
|
24
|
-
|
|
24
|
+
registeredEntries.push({ target, scope });
|
|
25
25
|
},
|
|
26
26
|
entries(): ReadonlyArray<{ target: Constructor; scope: BindingScope }> {
|
|
27
|
-
return
|
|
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
|
|
@@ -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: {
|
|
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
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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.
|
|
62
|
-
hasParent: this
|
|
63
|
-
isDisposed: this
|
|
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.
|
|
69
|
-
return bindings.map((binding) => this
|
|
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.
|
|
78
|
+
const bindings = this.#registry.getAll(token);
|
|
74
79
|
if (bindings.length > 0) {
|
|
75
80
|
if (options !== undefined) {
|
|
76
|
-
if (selectBinding(bindings, options, this
|
|
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.
|
|
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
|
|
97
|
+
return selectBinding(bindings, options, this.#makeConstraintContext(options), tokenName(token)) !== undefined;
|
|
93
98
|
}
|
|
94
99
|
return true;
|
|
95
100
|
}
|
|
96
101
|
|
|
97
|
-
|
|
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.
|
|
113
|
+
return this.#registry.allBindings().map((binding) => this.#toSnapshot(binding));
|
|
109
114
|
}
|
|
110
115
|
|
|
111
|
-
|
|
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
|
|
15
|
+
* The symbol TC39 Stage 3 decorator transforms store class metadata under.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
57
|
-
}
|
|
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
|
-
|
|
70
|
-
}
|
|
77
|
+
[MODULE_SETUP]: setup,
|
|
78
|
+
};
|
|
71
79
|
},
|
|
72
80
|
};
|
|
73
81
|
|