@codefast/di 0.3.14-canary.1 → 0.3.14
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 +58 -0
- package/README.md +42 -26
- package/dist/binding-scope.d.mts +11 -0
- package/dist/binding-scope.mjs +19 -0
- package/dist/binding-select.d.mts +8 -26
- package/dist/binding-select.mjs +56 -49
- package/dist/binding.d.mts +107 -335
- package/dist/binding.mjs +19 -332
- package/dist/constraints.d.mts +11 -29
- package/dist/constraints.mjs +32 -36
- package/dist/constructor-type.d.mts +17 -0
- package/dist/constructor-type.mjs +1 -0
- package/dist/container.d.mts +43 -122
- package/dist/container.mjs +667 -482
- package/dist/decorators/inject.d.mts +19 -50
- package/dist/decorators/inject.mjs +131 -93
- package/dist/decorators/injectable.d.mts +16 -37
- package/dist/decorators/injectable.mjs +47 -66
- package/dist/decorators/lifecycle-decorators.d.mts +2 -22
- package/dist/decorators/lifecycle-decorators.mjs +81 -37
- package/dist/dependency-graph.d.mts +24 -54
- package/dist/dependency-graph.mjs +51 -153
- package/dist/environment.d.mts +38 -12
- package/dist/environment.mjs +82 -16
- package/dist/errors.d.mts +70 -189
- package/dist/errors.mjs +92 -219
- package/dist/graph-adapters/cytoscape.d.mts +21 -7
- package/dist/graph-adapters/cytoscape.mjs +18 -35
- package/dist/graph-adapters/dot.d.mts +1 -4
- package/dist/graph-adapters/dot.mjs +6 -86
- package/dist/graph-adapters/reactflow.d.mts +26 -7
- package/dist/graph-adapters/reactflow.mjs +21 -72
- package/dist/graph-adapters/types.d.mts +2 -91
- package/dist/index.d.mts +16 -8
- package/dist/index.mjs +8 -5
- package/dist/inspector.d.mts +35 -74
- package/dist/inspector.mjs +61 -88
- package/dist/lifecycle.d.mts +20 -53
- package/dist/lifecycle.mjs +129 -99
- package/dist/metadata/metadata-keys.d.mts +9 -26
- package/dist/metadata/metadata-keys.mjs +7 -28
- package/dist/metadata/metadata-reader-token.d.mts +7 -0
- package/dist/metadata/metadata-reader-token.mjs +5 -0
- package/dist/metadata/metadata-types.d.mts +26 -75
- package/dist/metadata/symbol-metadata-reader.d.mts +10 -26
- package/dist/metadata/symbol-metadata-reader.mjs +32 -45
- package/dist/module.d.mts +30 -96
- package/dist/module.mjs +26 -72
- package/dist/registry.d.mts +32 -63
- package/dist/registry.mjs +131 -82
- package/dist/resolve-options.d.mts +18 -0
- package/dist/resolve-options.mjs +22 -0
- package/dist/resolver.d.mts +67 -190
- package/dist/resolver.mjs +715 -424
- package/dist/scope.d.mts +19 -106
- package/dist/scope.mjs +37 -196
- package/dist/token.d.mts +8 -22
- package/dist/token.mjs +9 -11
- package/dist/types.d.mts +48 -0
- package/dist/types.mjs +1 -0
- package/package.json +36 -14
- package/dist/metadata/param-registry.d.mts +0 -16
- package/dist/metadata/param-registry.mjs +0 -31
- package/dist/scope-validation.d.mts +0 -21
- package/dist/scope-validation.mjs +0 -35
package/dist/registry.mjs
CHANGED
|
@@ -1,95 +1,144 @@
|
|
|
1
|
+
import { slotKeyEquals } from "./binding.mjs";
|
|
1
2
|
//#region src/registry.ts
|
|
2
|
-
/**
|
|
3
|
-
* Flat, in-memory storage for {@link Binding} entries keyed by {@link RegistryKey}.
|
|
4
|
-
* Each key maps to an ordered list of bindings (multi-binding support).
|
|
5
|
-
*
|
|
6
|
-
* The registry is a "dumb" store — it does not perform selection, scope caching, or
|
|
7
|
-
* lifecycle management. Those concerns live in `DependencyResolver` and `ScopeManager`.
|
|
8
|
-
*
|
|
9
|
-
* Mutation styles:
|
|
10
|
-
* - `add` — append-only; never removes existing entries.
|
|
11
|
-
* - `replaceById` — swaps a single binding in place by ID; no removal callback.
|
|
12
|
-
* - `remove` / `removeById` — delete entries **without** notifying callers; the caller
|
|
13
|
-
* is responsible for draining the scope cache before calling these.
|
|
14
|
-
* - `replaceKeyLastWins` — replaces all bindings for a key with a single new one **and**
|
|
15
|
-
* invokes the `onReplaced` callback for each evicted binding, giving the caller
|
|
16
|
-
* (typically the container or scope manager) a chance to run deactivation.
|
|
17
|
-
*/
|
|
18
3
|
var BindingRegistry = class {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
4
|
+
_bindings = /* @__PURE__ */ new Map();
|
|
5
|
+
_byId = /* @__PURE__ */ new Map();
|
|
6
|
+
_simpleNamed = /* @__PURE__ */ new Map();
|
|
7
|
+
_fastDefault = /* @__PURE__ */ new Map();
|
|
8
|
+
/** Add or replace binding using slot-aware last-wins. */
|
|
9
|
+
add(binding) {
|
|
10
|
+
const key = binding.token;
|
|
11
|
+
let list = this._bindings.get(key);
|
|
12
|
+
if (list === void 0) {
|
|
13
|
+
list = [];
|
|
14
|
+
this._bindings.set(key, list);
|
|
15
|
+
}
|
|
16
|
+
if (!this._isPurePredicateBinding(binding)) {
|
|
17
|
+
const existingIndex = list.findIndex((b) => !this._isPurePredicateBinding(b) && slotKeyEquals(b.slot, binding.slot));
|
|
18
|
+
if (existingIndex !== -1) {
|
|
19
|
+
const old = list[existingIndex];
|
|
20
|
+
this._byId.delete(old.id);
|
|
21
|
+
list.splice(existingIndex, 1);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
list.push(binding);
|
|
25
|
+
this._byId.set(binding.id, binding);
|
|
26
|
+
this._indexSimpleNamedBinding(key, binding);
|
|
27
|
+
this._refreshFastDefaultForToken(key);
|
|
33
28
|
}
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
/** Remove all bindings for a token. Returns removed bindings. */
|
|
30
|
+
removeByToken(t) {
|
|
31
|
+
const key = t;
|
|
32
|
+
const list = this._bindings.get(key) ?? [];
|
|
33
|
+
this._bindings.delete(key);
|
|
34
|
+
this._simpleNamed.delete(key);
|
|
35
|
+
this._fastDefault.delete(key);
|
|
36
|
+
for (const b of list) this._byId.delete(b.id);
|
|
37
|
+
return list;
|
|
39
38
|
}
|
|
40
|
-
/**
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
/** Remove a specific binding by ID. Returns the removed binding or undefined. */
|
|
40
|
+
removeById(id) {
|
|
41
|
+
const binding = this._byId.get(id);
|
|
42
|
+
if (binding === void 0) return;
|
|
43
|
+
this._byId.delete(id);
|
|
44
|
+
const key = binding.token;
|
|
45
|
+
const list = this._bindings.get(key);
|
|
46
|
+
if (list !== void 0) {
|
|
47
|
+
const idx = list.findIndex((b) => b.id === id);
|
|
48
|
+
if (idx !== -1) list.splice(idx, 1);
|
|
49
|
+
this._deindexSimpleNamedBinding(key, binding);
|
|
50
|
+
if (list.length === 0) {
|
|
51
|
+
this._bindings.delete(key);
|
|
52
|
+
this._simpleNamed.delete(key);
|
|
53
|
+
this._fastDefault.delete(key);
|
|
54
|
+
} else this._refreshFastDefaultForToken(key);
|
|
55
|
+
}
|
|
56
|
+
return binding;
|
|
46
57
|
}
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
listEntries() {
|
|
51
|
-
return [...this.bindingsByKey.entries()].map(([key, bindings]) => ({
|
|
52
|
-
key,
|
|
53
|
-
bindings
|
|
54
|
-
}));
|
|
58
|
+
/** Get all bindings for a token. */
|
|
59
|
+
getAll(t) {
|
|
60
|
+
return this._bindings.get(t) ?? [];
|
|
55
61
|
}
|
|
56
|
-
/**
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
/** Get binding by ID. */
|
|
63
|
+
getById(id) {
|
|
64
|
+
return this._byId.get(id);
|
|
65
|
+
}
|
|
66
|
+
/** Check if any binding exists for token. */
|
|
67
|
+
has(t) {
|
|
68
|
+
const key = t;
|
|
69
|
+
const list = this._bindings.get(key);
|
|
70
|
+
return list !== void 0 && list.length > 0;
|
|
71
|
+
}
|
|
72
|
+
/** All bindings in the registry. */
|
|
73
|
+
allBindings() {
|
|
74
|
+
const result = [];
|
|
75
|
+
for (const list of this._bindings.values()) result.push(...list);
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
/** Remove all bindings. Returns all removed. */
|
|
79
|
+
clear() {
|
|
80
|
+
const all = this.allBindings();
|
|
81
|
+
this._bindings.clear();
|
|
82
|
+
this._byId.clear();
|
|
83
|
+
this._simpleNamed.clear();
|
|
84
|
+
this._fastDefault.clear();
|
|
85
|
+
return all;
|
|
86
|
+
}
|
|
87
|
+
getSimpleNamed(token, name) {
|
|
88
|
+
return this._simpleNamed.get(token)?.get(name);
|
|
89
|
+
}
|
|
90
|
+
getFastDefault(token) {
|
|
91
|
+
return this._fastDefault.get(token);
|
|
92
|
+
}
|
|
93
|
+
/** Summarize available slot strings for a token (for error messages). */
|
|
94
|
+
availableSlotStrings(t) {
|
|
95
|
+
return (this._bindings.get(t) ?? []).map((b) => {
|
|
96
|
+
const s = b.slot;
|
|
97
|
+
if (s.name === void 0 && s.tags.length === 0) return "default";
|
|
98
|
+
const parts = [];
|
|
99
|
+
if (s.name !== void 0) parts.push(`name:${s.name}`);
|
|
100
|
+
for (const [k, v] of s.tags) parts.push(`tag:${k}=${String(v)}`);
|
|
101
|
+
return parts.join(",");
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
_isPurePredicateBinding(binding) {
|
|
105
|
+
const slot = binding.slot;
|
|
106
|
+
const hasPredicate = binding.predicate !== void 0;
|
|
107
|
+
const hasConstraint = slot.name !== void 0 || slot.tags.length > 0;
|
|
108
|
+
return hasPredicate && !hasConstraint;
|
|
109
|
+
}
|
|
110
|
+
_indexSimpleNamedBinding(tokenKeyValue, binding) {
|
|
111
|
+
const slot = binding.slot;
|
|
112
|
+
if (slot.name === void 0 || slot.tags.length > 0) return;
|
|
113
|
+
let byName = this._simpleNamed.get(tokenKeyValue);
|
|
114
|
+
if (byName === void 0) {
|
|
115
|
+
byName = /* @__PURE__ */ new Map();
|
|
116
|
+
this._simpleNamed.set(tokenKeyValue, byName);
|
|
66
117
|
}
|
|
118
|
+
byName.set(slot.name, binding);
|
|
67
119
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
updated[index] = next;
|
|
77
|
-
this.bindingsByKey.set(registryKey, updated);
|
|
78
|
-
return;
|
|
120
|
+
_deindexSimpleNamedBinding(tokenKeyValue, binding) {
|
|
121
|
+
const slot = binding.slot;
|
|
122
|
+
if (slot.name === void 0 || slot.tags.length > 0) return;
|
|
123
|
+
const byName = this._simpleNamed.get(tokenKeyValue);
|
|
124
|
+
if (byName === void 0) return;
|
|
125
|
+
if (byName.get(slot.name)?.id === binding.id) {
|
|
126
|
+
byName.delete(slot.name);
|
|
127
|
+
if (byName.size === 0) this._simpleNamed.delete(tokenKeyValue);
|
|
79
128
|
}
|
|
80
129
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
this.
|
|
130
|
+
_refreshFastDefaultForToken(tokenKeyValue) {
|
|
131
|
+
const list = this._bindings.get(tokenKeyValue);
|
|
132
|
+
if (list === void 0 || list.length !== 1) {
|
|
133
|
+
this._fastDefault.delete(tokenKeyValue);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const onlyBinding = list[0];
|
|
137
|
+
if (!(onlyBinding.slot.name === void 0 && onlyBinding.slot.tags.length === 0) || onlyBinding.predicate !== void 0) {
|
|
138
|
+
this._fastDefault.delete(tokenKeyValue);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
this._fastDefault.set(tokenKeyValue, onlyBinding);
|
|
93
142
|
}
|
|
94
143
|
};
|
|
95
144
|
//#endregion
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ResolveOptions } from "./types.mjs";
|
|
2
|
+
import { SlotKey } from "./binding.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/resolve-options.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Builds a {@link ResolveOptions} safe for `exactOptionalPropertyTypes`:
|
|
7
|
+
* omits keys instead of assigning `undefined`.
|
|
8
|
+
*/
|
|
9
|
+
declare function injectableSlotToResolveOptions(slot: {
|
|
10
|
+
readonly name?: string;
|
|
11
|
+
readonly tags?: ReadonlyArray<readonly [string, unknown]>;
|
|
12
|
+
}): ResolveOptions | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Hint from a binding {@link SlotKey} (tags may be empty; omits when nothing to match).
|
|
15
|
+
*/
|
|
16
|
+
declare function slotKeyToResolveOptions(slot: SlotKey): ResolveOptions | undefined;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { injectableSlotToResolveOptions, slotKeyToResolveOptions };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/resolve-options.ts
|
|
2
|
+
/**
|
|
3
|
+
* Builds a {@link ResolveOptions} safe for `exactOptionalPropertyTypes`:
|
|
4
|
+
* omits keys instead of assigning `undefined`.
|
|
5
|
+
*/
|
|
6
|
+
function injectableSlotToResolveOptions(slot) {
|
|
7
|
+
const options = {};
|
|
8
|
+
if (slot.name !== void 0) options.name = slot.name;
|
|
9
|
+
if (slot.tags !== void 0) options.tags = slot.tags;
|
|
10
|
+
return options.name !== void 0 || options.tags !== void 0 ? options : void 0;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Hint from a binding {@link SlotKey} (tags may be empty; omits when nothing to match).
|
|
14
|
+
*/
|
|
15
|
+
function slotKeyToResolveOptions(slot) {
|
|
16
|
+
const options = {};
|
|
17
|
+
if (slot.name !== void 0) options.name = slot.name;
|
|
18
|
+
if (slot.tags.length > 0) options.tags = slot.tags;
|
|
19
|
+
return options.name !== void 0 || options.tags !== void 0 ? options : void 0;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { injectableSlotToResolveOptions, slotKeyToResolveOptions };
|
package/dist/resolver.d.mts
CHANGED
|
@@ -1,197 +1,74 @@
|
|
|
1
|
+
import { Constructor } from "./constructor-type.mjs";
|
|
1
2
|
import { Token } from "./token.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { MetadataReader } from "./metadata/metadata-types.mjs";
|
|
3
|
+
import { MaterializationFrame, ResolveOptions } from "./types.mjs";
|
|
4
|
+
import { BindingRegistry } from "./registry.mjs";
|
|
5
5
|
import { ScopeManager } from "./scope.mjs";
|
|
6
|
+
import { MetadataReader } from "./metadata/metadata-types.mjs";
|
|
7
|
+
import { Container } from "./container.mjs";
|
|
8
|
+
import { LifecycleManager } from "./lifecycle.mjs";
|
|
6
9
|
|
|
7
10
|
//#region src/resolver.d.ts
|
|
8
|
-
/**
|
|
9
|
-
* Dependencies injected into {@link DependencyResolver} at construction time.
|
|
10
|
-
*/
|
|
11
|
-
type ResolverDependencies = {
|
|
12
|
-
/**
|
|
13
|
-
* Looks up all bindings registered for a given registry key (own + parent containers).
|
|
14
|
-
*/
|
|
15
|
-
readonly lookup: (key: RegistryKey) => readonly Binding<unknown>[] | undefined;
|
|
16
|
-
/**
|
|
17
|
-
* Manages singleton/scoped instance caches and deactivation.
|
|
18
|
-
*/
|
|
19
|
-
readonly scopeManager: ScopeManager;
|
|
20
|
-
/**
|
|
21
|
-
* Reads `@injectable()` and lifecycle metadata from constructors. Omit to disable decorator support.
|
|
22
|
-
*/
|
|
23
|
-
readonly metadataReader?: MetadataReader;
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Stateless graph walker: selects a binding, checks for cycles and scope violations,
|
|
27
|
-
* delegates instance caching to `ScopeManager`, and runs lifecycle hooks.
|
|
28
|
-
*
|
|
29
|
-
* Resolution algorithm (per token):
|
|
30
|
-
* 1. Lookup all bindings for the registry key.
|
|
31
|
-
* 2. Apply name/tag hint and `when()` constraint filtering.
|
|
32
|
-
* 3. Circular-dependency check via a mutable `visiting` set (per call tree).
|
|
33
|
-
* 4. Captive-dependency check via the `materializationStack`.
|
|
34
|
-
* 5. Scope-cache hit → return cached instance.
|
|
35
|
-
* 6. Scope-cache miss → `materialize` → `@postConstruct` → `onActivation` → cache.
|
|
36
|
-
*
|
|
37
|
-
* Used exclusively by `DefaultContainer`; not part of the public API.
|
|
38
|
-
*/
|
|
39
11
|
declare class DependencyResolver {
|
|
40
|
-
private readonly
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
* @throws {@link CircularDependencyError} — cycle while materializing a candidate.
|
|
101
|
-
* @throws {@link ScopeViolationError} — captive dependency during materialization.
|
|
102
|
-
* @throws {@link MissingMetadataError} — class binding lacks injectable metadata when required.
|
|
103
|
-
*/
|
|
104
|
-
resolveAllAsyncRoot<Value>(key: Token<Value> | Constructor<Value>, hint?: ResolveHint): Promise<Value[]>;
|
|
105
|
-
/**
|
|
106
|
-
* Context-aware sync `resolveAll`: extends the current resolution path and preserves
|
|
107
|
-
* visiting/materialization stacks so nested multi-resolution participates in cycle and
|
|
108
|
-
* captive-dependency checks exactly like single-value {@link resolve}.
|
|
109
|
-
*/
|
|
110
|
-
private resolveAll;
|
|
111
|
-
/**
|
|
112
|
-
* Async counterpart of {@link resolveAll}: keeps the current path and materialization stack
|
|
113
|
-
* so `when()` constraints and scope validation behave consistently for nested multi-resolution.
|
|
114
|
-
*/
|
|
115
|
-
private resolveAllAsync;
|
|
116
|
-
/**
|
|
117
|
-
* Assembles the read-only {@link ConstraintContext} snapshot passed to `when()` predicates.
|
|
118
|
-
* Extracts the top-of-stack frame as `parent` and the rest as `ancestors`.
|
|
119
|
-
*/
|
|
120
|
-
private buildConstraintContext;
|
|
121
|
-
/**
|
|
122
|
-
* Throws {@link ScopeViolationError} when the immediate consumer on the stack is a singleton
|
|
123
|
-
* and the dependency has `"scoped"` or `"transient"` lifetime (captive dependency).
|
|
124
|
-
* Constants are exempt — they have no scope cache.
|
|
125
|
-
*/
|
|
126
|
-
private assertDependencyScopeAllowed;
|
|
127
|
-
/**
|
|
128
|
-
* Builds a {@link ResolutionContext} for use inside factories and lifecycle hooks.
|
|
129
|
-
* The `resolve` / `resolveAsync` / `resolveOptional` closures carry the current path and
|
|
130
|
-
* materialization stack forward so nested calls inherit captive-dependency checks.
|
|
131
|
-
*/
|
|
132
|
-
private createContext;
|
|
133
|
-
/**
|
|
134
|
-
* Core synchronous resolution: lookup → filter → cycle check → scope check → instantiate.
|
|
135
|
-
* Called recursively when a binding's dependencies need resolution.
|
|
136
|
-
*
|
|
137
|
-
* @param key - Token or constructor being resolved.
|
|
138
|
-
* @param hint - Optional name/tag filter for multi-binding selection.
|
|
139
|
-
* @param pathLabels - Mutable label path accumulated during graph walk; extended in place.
|
|
140
|
-
* @param visiting - Registry keys currently on the call stack; used for circular-dependency detection.
|
|
141
|
-
* @param materializationStack - Bindings along the current construction chain; used to block singleton→scoped/transient.
|
|
142
|
-
*/
|
|
143
|
-
private resolve;
|
|
144
|
-
/**
|
|
145
|
-
* Core async resolution: same pipeline as {@link resolve} but awaits `async-dynamic`
|
|
146
|
-
* factories and async lifecycle hooks instead of throwing {@link AsyncResolutionError}.
|
|
147
|
-
*
|
|
148
|
-
* @param key - Token or constructor being resolved.
|
|
149
|
-
* @param hint - Optional name/tag filter for multi-binding selection.
|
|
150
|
-
* @param pathLabels - Mutable label path accumulated during graph walk; extended in place.
|
|
151
|
-
* @param visiting - Registry keys currently on the call stack; used for circular-dependency detection.
|
|
152
|
-
* @param materializationStack - Same captive-dependency chain as {@link resolve}.
|
|
153
|
-
*/
|
|
154
|
-
private resolveAsync;
|
|
155
|
-
/**
|
|
156
|
-
* Handles scope-cache lookup / storage and lifecycle hooks (`@postConstruct`, `onActivation`)
|
|
157
|
-
* around a synchronous call to {@link materialize}.
|
|
158
|
-
*/
|
|
159
|
-
private instantiateBinding;
|
|
160
|
-
/**
|
|
161
|
-
* Async counterpart of {@link instantiateBinding}: delegates to {@link materializeAsync}
|
|
162
|
-
* and awaits `@postConstruct` and `onActivation` hooks.
|
|
163
|
-
*/
|
|
164
|
-
private instantiateBindingAsync;
|
|
165
|
-
/**
|
|
166
|
-
* Duplicate captive-dependency guard applied at instantiation time (after scope-cache miss),
|
|
167
|
-
* checking the top of the materialization stack rather than the raw `ConstraintContext`.
|
|
168
|
-
*/
|
|
169
|
-
private assertCaptiveDependencyFromMaterializationStack;
|
|
170
|
-
/**
|
|
171
|
-
* Synchronously produces the raw instance for a binding **without** touching the scope cache
|
|
172
|
-
* or running lifecycle hooks. The caller ({@link instantiateBinding}) wraps this with
|
|
173
|
-
* cache logic and post-construction hooks.
|
|
174
|
-
*
|
|
175
|
-
* Dispatches on `binding.kind`; throws {@link AsyncResolutionError} if the binding is
|
|
176
|
-
* `async-dynamic` or if a `dynamic` / `resolved` factory returns a Promise.
|
|
177
|
-
*/
|
|
178
|
-
private materialize;
|
|
179
|
-
/**
|
|
180
|
-
* Async counterpart of {@link materialize}; awaits `async-dynamic` factories and
|
|
181
|
-
* recursively resolves `resolved`-binding dependencies with {@link resolveAsync}.
|
|
182
|
-
*/
|
|
183
|
-
private materializeAsync;
|
|
184
|
-
/**
|
|
185
|
-
* Reads `@injectable()` constructor metadata and synchronously resolves each parameter,
|
|
186
|
-
* then calls `new ImplementationClass(...deps)`. Throws {@link MissingMetadataError} when
|
|
187
|
-
* the class has constructor parameters but no metadata.
|
|
188
|
-
*/
|
|
189
|
-
private instantiateClassBinding;
|
|
190
|
-
/**
|
|
191
|
-
* Async counterpart of {@link instantiateClassBinding}: resolves constructor dependencies
|
|
192
|
-
* with {@link resolveAsync} so `async-dynamic` parameters are awaited in order.
|
|
193
|
-
*/
|
|
194
|
-
private instantiateClassBindingAsync;
|
|
12
|
+
private readonly _registry;
|
|
13
|
+
private readonly _scope;
|
|
14
|
+
private readonly _lifecycle;
|
|
15
|
+
private readonly _metadataReader;
|
|
16
|
+
private readonly _container;
|
|
17
|
+
private readonly _parent;
|
|
18
|
+
private readonly _frameByBindingId;
|
|
19
|
+
private readonly _syncResolutionContextPool;
|
|
20
|
+
private readonly _deepCycleMarks;
|
|
21
|
+
private _deepCycleGen;
|
|
22
|
+
private _deepActiveLevels;
|
|
23
|
+
private _deepSyncCtx;
|
|
24
|
+
private _deepSyncCtxPath;
|
|
25
|
+
private _deepAsyncCtx;
|
|
26
|
+
private _deepAsyncCtxPath;
|
|
27
|
+
private _deepAsyncActiveLevels;
|
|
28
|
+
private readonly _classHasPostConstruct;
|
|
29
|
+
private readonly _classNeedsActiveContainer;
|
|
30
|
+
private readonly _classConstructorMetadata;
|
|
31
|
+
private readonly _activationNeedByBindingId;
|
|
32
|
+
private _activationCacheVersion;
|
|
33
|
+
constructor(_registry: BindingRegistry, _scope: ScopeManager, _lifecycle: LifecycleManager, _metadataReader: MetadataReader, _container: Container, _parent: DependencyResolver | undefined);
|
|
34
|
+
private _findBinding;
|
|
35
|
+
resolveFromContext<const Value>(token: Token<Value> | Constructor<Value>, resolutionPath: string[], materializationStack: MaterializationFrame[]): Value;
|
|
36
|
+
resolve<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: string[], materializationStack: MaterializationFrame[]): Value;
|
|
37
|
+
private _resolveBinding;
|
|
38
|
+
private _instantiateSync;
|
|
39
|
+
private _resolveClassDeps;
|
|
40
|
+
private _resolveDescriptorDeps;
|
|
41
|
+
resolveOptional<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: string[], materializationStack: MaterializationFrame[]): Value | undefined;
|
|
42
|
+
resolveAll<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: string[], materializationStack: MaterializationFrame[]): Value[];
|
|
43
|
+
resolveAsyncFromContext<const Value>(token: Token<Value> | Constructor<Value>, resolutionPath: string[], materializationStack: MaterializationFrame[]): Promise<Value>;
|
|
44
|
+
resolveAsync<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: string[], materializationStack: MaterializationFrame[]): Promise<Value>;
|
|
45
|
+
private _resolveBindingAsync;
|
|
46
|
+
private _instantiateAsync;
|
|
47
|
+
private _resolveClassDepsAsync;
|
|
48
|
+
private _resolveDescriptorDepsAsync;
|
|
49
|
+
resolveOptionalAsync<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: string[], materializationStack: MaterializationFrame[]): Promise<Value | undefined>;
|
|
50
|
+
resolveAllAsync<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: string[], materializationStack: MaterializationFrame[]): Promise<Value[]>;
|
|
51
|
+
private _getAllBindingsFromChain;
|
|
52
|
+
private _getSimpleNamedBindingsFromChain;
|
|
53
|
+
private _getAvailableSlots;
|
|
54
|
+
private _makeConstraintContext;
|
|
55
|
+
private _matchesBindingFast;
|
|
56
|
+
private _matchesSlotFast;
|
|
57
|
+
private _getTokenName;
|
|
58
|
+
private _getConstructorMetadata;
|
|
59
|
+
private _instantiateClass;
|
|
60
|
+
private _matchesHintTag;
|
|
61
|
+
private _resolveTransientDynamicSyncFromContext;
|
|
62
|
+
private _resolveTransientDynamicSyncSlow;
|
|
63
|
+
private _resolveTransientDynamicAsyncFromContext;
|
|
64
|
+
private _resolveTransientDynamicAsyncSlow;
|
|
65
|
+
private _resolveCandidateSync;
|
|
66
|
+
private _resolveCandidateAsync;
|
|
67
|
+
private _getMaterializationFrame;
|
|
68
|
+
private _needsActivation;
|
|
69
|
+
private _refreshClassPostConstructCache;
|
|
70
|
+
private _requiresResolutionContext;
|
|
71
|
+
private _acquireSyncResolutionContext;
|
|
195
72
|
}
|
|
196
73
|
//#endregion
|
|
197
|
-
export { DependencyResolver
|
|
74
|
+
export { DependencyResolver };
|