@codefast/di 0.3.16-canary.0 → 0.3.16-canary.2
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 +12 -0
- package/README.md +8 -5
- package/dist/binding-select.d.mts +2 -2
- package/dist/binding-select.mjs +5 -5
- package/dist/binding.d.mts +12 -12
- package/dist/binding.mjs +8 -8
- package/dist/constraints.d.mts +25 -9
- package/dist/constraints.mjs +47 -19
- package/dist/constructor-type.d.mts +2 -2
- package/dist/container.d.mts +6 -6
- package/dist/container.mjs +202 -121
- package/dist/decorators/inject.d.mts +4 -4
- package/dist/decorators/inject.mjs +21 -19
- package/dist/decorators/injectable.d.mts +1 -1
- package/dist/decorators/injectable.mjs +18 -14
- package/dist/decorators/lifecycle-decorators.mjs +3 -0
- package/dist/dependency-graph.d.mts +2 -2
- package/dist/dependency-graph.mjs +13 -13
- package/dist/environment.d.mts +17 -17
- package/dist/environment.mjs +21 -21
- package/dist/errors.d.mts +18 -8
- package/dist/errors.mjs +17 -1
- package/dist/graph-adapters/reactflow.d.mts +2 -2
- package/dist/index.d.mts +6 -5
- package/dist/index.mjs +5 -4
- package/dist/inspector.d.mts +2 -3
- package/dist/inspector.mjs +18 -16
- package/dist/lifecycle.d.mts +5 -6
- package/dist/lifecycle.mjs +45 -52
- package/dist/metadata/metadata-keys.d.mts +24 -1
- package/dist/metadata/metadata-keys.mjs +14 -1
- package/dist/metadata/metadata-types.d.mts +5 -5
- package/dist/metadata/symbol-metadata-reader.mjs +31 -24
- package/dist/module.d.mts +2 -2
- package/dist/module.mjs +2 -2
- package/dist/registry.d.mts +6 -6
- package/dist/registry.mjs +55 -62
- package/dist/resolve-options.d.mts +5 -5
- package/dist/resolve-options.mjs +8 -8
- package/dist/resolver.d.mts +22 -10
- package/dist/resolver.mjs +206 -185
- package/dist/token.d.mts +1 -1
- package/dist/token.mjs +4 -4
- package/dist/types.d.mts +12 -8
- package/package.json +15 -8
package/dist/resolver.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { AsyncResolutionError, CircularDependencyError, InternalError, MissingMetadataError, MissingScopeContextError, NoMatchingBindingError, TokenNotBoundError } from "./errors.mjs";
|
|
2
2
|
import { selectAllBindings, selectBinding } from "./binding-select.mjs";
|
|
3
3
|
import { tokenName } from "./token.mjs";
|
|
4
|
-
import { DefaultResolutionContext,
|
|
5
|
-
import {
|
|
4
|
+
import { DefaultResolutionContext, buildResolutionFrame, runWithContainer } from "./environment.mjs";
|
|
5
|
+
import { injectionSlotToResolveOptions } from "./resolve-options.mjs";
|
|
6
6
|
//#region src/resolver.ts
|
|
7
7
|
const RESOLUTION_SET_KEY = Symbol("di:resolution-set");
|
|
8
8
|
const RESOLUTION_SET_THRESHOLD = 32;
|
|
@@ -10,7 +10,7 @@ const EMPTY_STRING_LIST = [];
|
|
|
10
10
|
const EMPTY_FRAME_LIST = [];
|
|
11
11
|
const ROOT_CONSTRAINT_CONTEXT = {
|
|
12
12
|
resolutionPath: EMPTY_STRING_LIST,
|
|
13
|
-
|
|
13
|
+
resolutionStack: EMPTY_FRAME_LIST,
|
|
14
14
|
parent: void 0,
|
|
15
15
|
ancestors: EMPTY_FRAME_LIST,
|
|
16
16
|
currentResolveHint: void 0
|
|
@@ -19,6 +19,12 @@ const ROOT_CONSTRAINT_CONTEXT = {
|
|
|
19
19
|
* @since 0.3.16-canary.0
|
|
20
20
|
*/
|
|
21
21
|
var DependencyResolver = class {
|
|
22
|
+
_registry;
|
|
23
|
+
_scope;
|
|
24
|
+
_lifecycle;
|
|
25
|
+
_metadataReader;
|
|
26
|
+
_container;
|
|
27
|
+
_parent;
|
|
22
28
|
_frameByBindingId = /* @__PURE__ */ new Map();
|
|
23
29
|
_syncResolutionContextPool = [];
|
|
24
30
|
_deepCycleMarks = /* @__PURE__ */ new Map();
|
|
@@ -42,7 +48,7 @@ var DependencyResolver = class {
|
|
|
42
48
|
this._container = _container;
|
|
43
49
|
this._parent = _parent;
|
|
44
50
|
}
|
|
45
|
-
_findBinding(token, hint, resolutionPath,
|
|
51
|
+
_findBinding(token, hint, resolutionPath, resolutionStack) {
|
|
46
52
|
if (hint === void 0) {
|
|
47
53
|
const fastDefaultBinding = this._registry.getFastDefault(token);
|
|
48
54
|
if (fastDefaultBinding !== void 0) return {
|
|
@@ -52,7 +58,7 @@ var DependencyResolver = class {
|
|
|
52
58
|
}
|
|
53
59
|
if (hint?.name !== void 0 && hint.tag === void 0 && (hint.tags?.length ?? 0) === 0) {
|
|
54
60
|
const namedBinding = this._registry.getSimpleNamed(token, hint.name);
|
|
55
|
-
if (namedBinding !== void 0 && this._matchesBindingFast(namedBinding, hint, resolutionPath,
|
|
61
|
+
if (namedBinding !== void 0 && this._matchesBindingFast(namedBinding, hint, resolutionPath, resolutionStack)) return {
|
|
56
62
|
binding: namedBinding,
|
|
57
63
|
owner: this
|
|
58
64
|
};
|
|
@@ -74,46 +80,61 @@ var DependencyResolver = class {
|
|
|
74
80
|
binding: onlyBinding,
|
|
75
81
|
owner: this
|
|
76
82
|
};
|
|
77
|
-
if (this._matchesBindingFast(onlyBinding, hint, resolutionPath,
|
|
83
|
+
if (this._matchesBindingFast(onlyBinding, hint, resolutionPath, resolutionStack)) return {
|
|
78
84
|
binding: onlyBinding,
|
|
79
85
|
owner: this
|
|
80
86
|
};
|
|
81
87
|
}
|
|
82
|
-
const binding = selectBinding(bindings, hint, this._makeConstraintContext(resolutionPath,
|
|
88
|
+
const binding = selectBinding(bindings, hint, this._makeConstraintContext(resolutionPath, resolutionStack, hint), this._getTokenName(token));
|
|
83
89
|
if (binding !== void 0) return {
|
|
84
90
|
binding,
|
|
85
91
|
owner: this
|
|
86
92
|
};
|
|
87
93
|
}
|
|
88
|
-
if (this._parent !== void 0) return this._parent._findBinding(token, hint, resolutionPath,
|
|
94
|
+
if (this._parent !== void 0) return this._parent._findBinding(token, hint, resolutionPath, resolutionStack);
|
|
89
95
|
}
|
|
90
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Binding lookup aligned with `resolve` — used by `Container.validate` without instantiating.
|
|
98
|
+
*/
|
|
99
|
+
peekBindingForValidate(token, hint) {
|
|
100
|
+
return this._findBinding(token, hint, [], []);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Mirrors {@link DependencyResolver.resolveAll} candidate selection only (no instantiation).
|
|
104
|
+
*/
|
|
105
|
+
peekCandidateBindingsForValidate(token, hint) {
|
|
106
|
+
if (hint?.name !== void 0 && hint.tag === void 0 && (hint.tags?.length ?? 0) === 0) return this._getSimpleNamedBindingsFromChain(token, hint.name);
|
|
107
|
+
const allBindings = this._getAllBindingsFromChain(token);
|
|
108
|
+
if (allBindings.length === 0) return [];
|
|
109
|
+
return selectAllBindings(allBindings, hint, this._makeConstraintContext([], [], hint));
|
|
110
|
+
}
|
|
111
|
+
resolveFromContext(token, resolutionPath, resolutionStack) {
|
|
91
112
|
const fastBinding = this._registry.getFastDefault(token);
|
|
92
113
|
if (fastBinding !== void 0) {
|
|
93
|
-
if (fastBinding.kind === "alias") return this.resolveFromContext(fastBinding.target, resolutionPath,
|
|
114
|
+
if (fastBinding.kind === "alias") return this.resolveFromContext(fastBinding.target, resolutionPath, resolutionStack);
|
|
94
115
|
const scope = fastBinding.scope ?? "transient";
|
|
95
|
-
if (scope === "transient" && fastBinding.kind === "dynamic" && fastBinding.onActivation === void 0 && (this._lifecycle.activationVersion === 0 || !this._lifecycle.hasActivationHandlers(fastBinding.token))) return this._resolveTransientDynamicSyncFromContext(fastBinding, resolutionPath,
|
|
116
|
+
if (scope === "transient" && fastBinding.kind === "dynamic" && fastBinding.onActivation === void 0 && (this._lifecycle.activationVersion === 0 || !this._lifecycle.hasActivationHandlers(fastBinding.token))) return this._resolveTransientDynamicSyncFromContext(fastBinding, resolutionPath, resolutionStack);
|
|
96
117
|
if (scope === "singleton" && this._scope.hasSingleton(fastBinding.id)) return this._scope.getSingleton(fastBinding.id);
|
|
97
118
|
if (scope === "scoped") {
|
|
98
119
|
if (!this._scope.isChild) throw new MissingScopeContextError(this._getTokenName(fastBinding.token));
|
|
99
120
|
if (this._scope.hasScoped(fastBinding.id)) return this._scope.getScoped(fastBinding.id);
|
|
100
121
|
}
|
|
101
|
-
return this._resolveBinding(fastBinding, void 0, resolutionPath,
|
|
122
|
+
return this._resolveBinding(fastBinding, void 0, resolutionPath, resolutionStack);
|
|
102
123
|
}
|
|
103
|
-
return this.resolve(token, void 0, resolutionPath,
|
|
124
|
+
return this.resolve(token, void 0, resolutionPath, resolutionStack);
|
|
104
125
|
}
|
|
105
|
-
resolve(token, hint, resolutionPath,
|
|
106
|
-
const found = this._findBinding(token, hint, resolutionPath,
|
|
126
|
+
resolve(token, hint, resolutionPath, resolutionStack) {
|
|
127
|
+
const found = this._findBinding(token, hint, resolutionPath, resolutionStack);
|
|
107
128
|
if (found === void 0) {
|
|
108
129
|
if (this._registry.getAll(token).length > 0) throw new NoMatchingBindingError(this._getTokenName(token), hint ?? {}, this._getAvailableSlots(token));
|
|
109
130
|
throw new TokenNotBoundError(this._getTokenName(token));
|
|
110
131
|
}
|
|
111
132
|
const { binding, owner } = found;
|
|
112
|
-
if (binding.kind === "alias") return this.resolve(binding.target, hint, resolutionPath,
|
|
113
|
-
if ((binding.scope ?? "transient") === "singleton" && owner !== this) return owner._resolveBinding(binding, hint, resolutionPath,
|
|
114
|
-
return this._resolveBinding(binding, hint, resolutionPath,
|
|
133
|
+
if (binding.kind === "alias") return this.resolve(binding.target, hint, resolutionPath, resolutionStack);
|
|
134
|
+
if ((binding.scope ?? "transient") === "singleton" && owner !== this) return owner._resolveBinding(binding, hint, resolutionPath, resolutionStack);
|
|
135
|
+
return this._resolveBinding(binding, hint, resolutionPath, resolutionStack);
|
|
115
136
|
}
|
|
116
|
-
_resolveBinding(binding, hint, resolutionPath,
|
|
137
|
+
_resolveBinding(binding, hint, resolutionPath, resolutionStack) {
|
|
117
138
|
if (binding.kind === "constant" && binding.onActivation === void 0 && !this._lifecycle.hasActivationHandlers(binding.token)) return binding.value;
|
|
118
139
|
const scope = binding.scope ?? "transient";
|
|
119
140
|
if (scope === "singleton") {
|
|
@@ -123,38 +144,38 @@ var DependencyResolver = class {
|
|
|
123
144
|
if (!this._scope.isChild) throw new MissingScopeContextError(this._getTokenName(binding.token));
|
|
124
145
|
if (this._scope.hasScoped(binding.id)) return this._scope.getScoped(binding.id);
|
|
125
146
|
}
|
|
126
|
-
const frame = this.
|
|
127
|
-
const
|
|
147
|
+
const frame = this._getResolutionFrame(binding);
|
|
148
|
+
const tokenDisplayName = frame.tokenName;
|
|
128
149
|
const pathWithSet = resolutionPath;
|
|
129
150
|
let resolutionSet = pathWithSet[RESOLUTION_SET_KEY];
|
|
130
151
|
if (resolutionSet === void 0 && resolutionPath.length >= RESOLUTION_SET_THRESHOLD) {
|
|
131
152
|
resolutionSet = new Set(resolutionPath);
|
|
132
153
|
pathWithSet[RESOLUTION_SET_KEY] = resolutionSet;
|
|
133
154
|
}
|
|
134
|
-
if (resolutionSet !== void 0 ? resolutionSet.has(
|
|
135
|
-
resolutionPath.push(
|
|
136
|
-
resolutionSet?.add(
|
|
137
|
-
|
|
155
|
+
if (resolutionSet !== void 0 ? resolutionSet.has(tokenDisplayName) : resolutionPath.includes(tokenDisplayName)) throw new CircularDependencyError([...resolutionPath, tokenDisplayName]);
|
|
156
|
+
resolutionPath.push(tokenDisplayName);
|
|
157
|
+
resolutionSet?.add(tokenDisplayName);
|
|
158
|
+
resolutionStack.push(frame);
|
|
138
159
|
const needsActivation = this._needsActivation(binding);
|
|
139
160
|
if (!needsActivation && scope === "transient" && binding.kind === "dynamic") {
|
|
140
|
-
const resolutionCtx = this._acquireSyncResolutionContext(resolutionPath,
|
|
161
|
+
const resolutionCtx = this._acquireSyncResolutionContext(resolutionPath, resolutionStack, hint);
|
|
141
162
|
try {
|
|
142
163
|
const dynamicResult = binding.factory(resolutionCtx);
|
|
143
164
|
if (dynamicResult instanceof Promise) throw new AsyncResolutionError(tokenName(binding.token), tokenName(binding.token));
|
|
144
|
-
|
|
165
|
+
resolutionStack.pop();
|
|
145
166
|
resolutionPath.pop();
|
|
146
|
-
resolutionSet?.delete(
|
|
167
|
+
resolutionSet?.delete(tokenDisplayName);
|
|
147
168
|
return dynamicResult;
|
|
148
169
|
} catch (error) {
|
|
149
|
-
|
|
170
|
+
resolutionStack.pop();
|
|
150
171
|
resolutionPath.pop();
|
|
151
|
-
resolutionSet?.delete(
|
|
172
|
+
resolutionSet?.delete(tokenDisplayName);
|
|
152
173
|
throw error;
|
|
153
174
|
}
|
|
154
175
|
}
|
|
155
176
|
try {
|
|
156
|
-
const resolutionCtx = needsActivation || this._requiresResolutionContext(binding) ? this._acquireSyncResolutionContext(resolutionPath,
|
|
157
|
-
const instance = this._instantiateSync(binding, resolutionCtx, resolutionPath,
|
|
177
|
+
const resolutionCtx = needsActivation || this._requiresResolutionContext(binding) ? this._acquireSyncResolutionContext(resolutionPath, resolutionStack, hint) : void 0;
|
|
178
|
+
const instance = this._instantiateSync(binding, resolutionCtx, resolutionPath, resolutionStack);
|
|
158
179
|
let shouldActivate = needsActivation;
|
|
159
180
|
if (binding.kind === "class" && this._classHasPostConstruct.get(binding.target) === void 0) {
|
|
160
181
|
this._refreshClassPostConstructCache(binding.target);
|
|
@@ -166,36 +187,36 @@ var DependencyResolver = class {
|
|
|
166
187
|
else if (scope === "scoped") this._scope.setScoped(binding.id, activated);
|
|
167
188
|
return activated;
|
|
168
189
|
} finally {
|
|
169
|
-
|
|
190
|
+
resolutionStack.pop();
|
|
170
191
|
resolutionPath.pop();
|
|
171
|
-
resolutionSet?.delete(
|
|
192
|
+
resolutionSet?.delete(tokenDisplayName);
|
|
172
193
|
}
|
|
173
194
|
}
|
|
174
|
-
_instantiateSync(binding, ctx, resolutionPath,
|
|
195
|
+
_instantiateSync(binding, ctx, resolutionPath, resolutionStack) {
|
|
175
196
|
switch (binding.kind) {
|
|
176
197
|
case "constant": return binding.value;
|
|
177
198
|
case "dynamic": {
|
|
178
199
|
if (ctx === void 0) throw new InternalError("dynamic binding requires resolution context");
|
|
179
|
-
const
|
|
180
|
-
if (
|
|
181
|
-
return
|
|
200
|
+
const factoryResult = binding.factory(ctx);
|
|
201
|
+
if (factoryResult instanceof Promise) throw new AsyncResolutionError(tokenName(binding.token), tokenName(binding.token));
|
|
202
|
+
return factoryResult;
|
|
182
203
|
}
|
|
183
204
|
case "dynamic-async": throw new AsyncResolutionError(tokenName(binding.token), tokenName(binding.token));
|
|
184
205
|
case "class": {
|
|
185
|
-
const deps = this._resolveClassDeps(binding.target, resolutionPath,
|
|
206
|
+
const deps = this._resolveClassDeps(binding.target, resolutionPath, resolutionStack);
|
|
186
207
|
return this._instantiateClass(binding.target, deps);
|
|
187
208
|
}
|
|
188
209
|
case "resolved": {
|
|
189
|
-
const deps = this._resolveDescriptorDeps(binding.deps, resolutionPath,
|
|
190
|
-
const
|
|
191
|
-
if (
|
|
192
|
-
return
|
|
210
|
+
const deps = this._resolveDescriptorDeps(binding.deps, resolutionPath, resolutionStack);
|
|
211
|
+
const factoryResult = binding.factory(...deps);
|
|
212
|
+
if (factoryResult instanceof Promise) throw new AsyncResolutionError(tokenName(binding.token), tokenName(binding.token));
|
|
213
|
+
return factoryResult;
|
|
193
214
|
}
|
|
194
215
|
case "resolved-async": throw new AsyncResolutionError(tokenName(binding.token), tokenName(binding.token));
|
|
195
216
|
case "alias": throw new InternalError("alias should have been followed before instantiation");
|
|
196
217
|
}
|
|
197
218
|
}
|
|
198
|
-
_resolveClassDeps(target, resolutionPath,
|
|
219
|
+
_resolveClassDeps(target, resolutionPath, resolutionStack) {
|
|
199
220
|
const meta = this._getConstructorMetadata(target);
|
|
200
221
|
if (meta === void 0) {
|
|
201
222
|
if (target.length === 0) return [];
|
|
@@ -204,91 +225,91 @@ var DependencyResolver = class {
|
|
|
204
225
|
if (meta.params.length === 0) return [];
|
|
205
226
|
if (meta.params.length === 1) {
|
|
206
227
|
const param = meta.params[0];
|
|
207
|
-
const paramHint =
|
|
208
|
-
if (param.multi) return [this.resolveAll(param.token, paramHint, resolutionPath,
|
|
209
|
-
if (param.optional) return [this.resolveOptional(param.token, paramHint, resolutionPath,
|
|
210
|
-
if (paramHint === void 0) return [this.resolveFromContext(param.token, resolutionPath,
|
|
211
|
-
return [this.resolve(param.token, paramHint, resolutionPath,
|
|
228
|
+
const paramHint = injectionSlotToResolveOptions(param);
|
|
229
|
+
if (param.multi) return [this.resolveAll(param.token, paramHint, resolutionPath, resolutionStack)];
|
|
230
|
+
if (param.optional) return [this.resolveOptional(param.token, paramHint, resolutionPath, resolutionStack)];
|
|
231
|
+
if (paramHint === void 0) return [this.resolveFromContext(param.token, resolutionPath, resolutionStack)];
|
|
232
|
+
return [this.resolve(param.token, paramHint, resolutionPath, resolutionStack)];
|
|
212
233
|
}
|
|
213
234
|
const deps = new Array(meta.params.length);
|
|
214
235
|
for (let index = 0; index < meta.params.length; index += 1) {
|
|
215
236
|
const param = meta.params[index];
|
|
216
|
-
const paramHint =
|
|
237
|
+
const paramHint = injectionSlotToResolveOptions(param);
|
|
217
238
|
if (param.multi) {
|
|
218
|
-
deps[index] = this.resolveAll(param.token, paramHint, resolutionPath,
|
|
239
|
+
deps[index] = this.resolveAll(param.token, paramHint, resolutionPath, resolutionStack);
|
|
219
240
|
continue;
|
|
220
241
|
}
|
|
221
242
|
if (param.optional) {
|
|
222
|
-
deps[index] = this.resolveOptional(param.token, paramHint, resolutionPath,
|
|
243
|
+
deps[index] = this.resolveOptional(param.token, paramHint, resolutionPath, resolutionStack);
|
|
223
244
|
continue;
|
|
224
245
|
}
|
|
225
|
-
deps[index] = paramHint === void 0 ? this.resolveFromContext(param.token, resolutionPath,
|
|
246
|
+
deps[index] = paramHint === void 0 ? this.resolveFromContext(param.token, resolutionPath, resolutionStack) : this.resolve(param.token, paramHint, resolutionPath, resolutionStack);
|
|
226
247
|
}
|
|
227
248
|
return deps;
|
|
228
249
|
}
|
|
229
|
-
_resolveDescriptorDeps(deps, resolutionPath,
|
|
250
|
+
_resolveDescriptorDeps(deps, resolutionPath, resolutionStack) {
|
|
230
251
|
const resolved = new Array(deps.length);
|
|
231
252
|
for (let index = 0; index < deps.length; index += 1) {
|
|
232
253
|
const dep = deps[index];
|
|
233
|
-
const depHint =
|
|
254
|
+
const depHint = injectionSlotToResolveOptions(dep);
|
|
234
255
|
if (dep.multi) {
|
|
235
|
-
resolved[index] = this.resolveAll(dep.token, depHint, resolutionPath,
|
|
256
|
+
resolved[index] = this.resolveAll(dep.token, depHint, resolutionPath, resolutionStack);
|
|
236
257
|
continue;
|
|
237
258
|
}
|
|
238
259
|
if (dep.optional) {
|
|
239
|
-
resolved[index] = this.resolveOptional(dep.token, depHint, resolutionPath,
|
|
260
|
+
resolved[index] = this.resolveOptional(dep.token, depHint, resolutionPath, resolutionStack);
|
|
240
261
|
continue;
|
|
241
262
|
}
|
|
242
|
-
resolved[index] = depHint === void 0 ? this.resolveFromContext(dep.token, resolutionPath,
|
|
263
|
+
resolved[index] = depHint === void 0 ? this.resolveFromContext(dep.token, resolutionPath, resolutionStack) : this.resolve(dep.token, depHint, resolutionPath, resolutionStack);
|
|
243
264
|
}
|
|
244
265
|
return resolved;
|
|
245
266
|
}
|
|
246
|
-
resolveOptional(token, hint, resolutionPath,
|
|
247
|
-
if (this._findBinding(token, hint, resolutionPath,
|
|
248
|
-
return this.resolve(token, hint, resolutionPath,
|
|
267
|
+
resolveOptional(token, hint, resolutionPath, resolutionStack) {
|
|
268
|
+
if (this._findBinding(token, hint, resolutionPath, resolutionStack) === void 0) return;
|
|
269
|
+
return this.resolve(token, hint, resolutionPath, resolutionStack);
|
|
249
270
|
}
|
|
250
|
-
resolveAll(token, hint, resolutionPath,
|
|
271
|
+
resolveAll(token, hint, resolutionPath, resolutionStack) {
|
|
251
272
|
if (hint?.name !== void 0 && hint.tag === void 0 && (hint.tags?.length ?? 0) === 0) {
|
|
252
273
|
const namedCandidates = this._getSimpleNamedBindingsFromChain(token, hint.name);
|
|
253
274
|
if (namedCandidates.length === 0) return [];
|
|
254
275
|
const resolved = new Array(namedCandidates.length);
|
|
255
|
-
for (let index = 0; index < namedCandidates.length; index += 1) resolved[index] = this._resolveCandidateSync(namedCandidates[index], hint, resolutionPath,
|
|
276
|
+
for (let index = 0; index < namedCandidates.length; index += 1) resolved[index] = this._resolveCandidateSync(namedCandidates[index], hint, resolutionPath, resolutionStack);
|
|
256
277
|
return resolved;
|
|
257
278
|
}
|
|
258
279
|
const allBindings = this._getAllBindingsFromChain(token);
|
|
259
280
|
if (allBindings.length === 0) return [];
|
|
260
|
-
const candidates = selectAllBindings(allBindings, hint, this._makeConstraintContext(resolutionPath,
|
|
281
|
+
const candidates = selectAllBindings(allBindings, hint, this._makeConstraintContext(resolutionPath, resolutionStack, hint));
|
|
261
282
|
const resolved = new Array(candidates.length);
|
|
262
|
-
for (let index = 0; index < candidates.length; index += 1) resolved[index] = this._resolveCandidateSync(candidates[index], hint, resolutionPath,
|
|
283
|
+
for (let index = 0; index < candidates.length; index += 1) resolved[index] = this._resolveCandidateSync(candidates[index], hint, resolutionPath, resolutionStack);
|
|
263
284
|
return resolved;
|
|
264
285
|
}
|
|
265
|
-
resolveAsyncFromContext(token, resolutionPath,
|
|
286
|
+
resolveAsyncFromContext(token, resolutionPath, resolutionStack) {
|
|
266
287
|
const fastBinding = this._registry.getFastDefault(token);
|
|
267
288
|
if (fastBinding !== void 0) {
|
|
268
|
-
if (fastBinding.kind === "alias") return this.resolveAsyncFromContext(fastBinding.target, resolutionPath,
|
|
289
|
+
if (fastBinding.kind === "alias") return this.resolveAsyncFromContext(fastBinding.target, resolutionPath, resolutionStack);
|
|
269
290
|
const scope = fastBinding.scope ?? "transient";
|
|
270
|
-
if (scope === "transient" && (fastBinding.kind === "dynamic" || fastBinding.kind === "dynamic-async") && fastBinding.onActivation === void 0 && (this._lifecycle.activationVersion === 0 || !this._lifecycle.hasActivationHandlers(fastBinding.token))) return this._resolveTransientDynamicAsyncFromContext(fastBinding, resolutionPath,
|
|
291
|
+
if (scope === "transient" && (fastBinding.kind === "dynamic" || fastBinding.kind === "dynamic-async") && fastBinding.onActivation === void 0 && (this._lifecycle.activationVersion === 0 || !this._lifecycle.hasActivationHandlers(fastBinding.token))) return this._resolveTransientDynamicAsyncFromContext(fastBinding, resolutionPath, resolutionStack);
|
|
271
292
|
if (scope === "singleton" && this._scope.hasSingleton(fastBinding.id)) return Promise.resolve(this._scope.getSingleton(fastBinding.id));
|
|
272
293
|
if (scope === "scoped") {
|
|
273
294
|
if (!this._scope.isChild) return Promise.reject(new MissingScopeContextError(this._getTokenName(fastBinding.token)));
|
|
274
295
|
if (this._scope.hasScoped(fastBinding.id)) return Promise.resolve(this._scope.getScoped(fastBinding.id));
|
|
275
296
|
}
|
|
276
|
-
return this._resolveBindingAsync(fastBinding, void 0, resolutionPath,
|
|
297
|
+
return this._resolveBindingAsync(fastBinding, void 0, resolutionPath, resolutionStack);
|
|
277
298
|
}
|
|
278
|
-
return this.resolveAsync(token, void 0, resolutionPath,
|
|
299
|
+
return this.resolveAsync(token, void 0, resolutionPath, resolutionStack);
|
|
279
300
|
}
|
|
280
|
-
async resolveAsync(token, hint, resolutionPath,
|
|
281
|
-
const found = this._findBinding(token, hint, resolutionPath,
|
|
301
|
+
async resolveAsync(token, hint, resolutionPath, resolutionStack) {
|
|
302
|
+
const found = this._findBinding(token, hint, resolutionPath, resolutionStack);
|
|
282
303
|
if (found === void 0) {
|
|
283
304
|
if (this._registry.getAll(token).length > 0) throw new NoMatchingBindingError(this._getTokenName(token), hint ?? {}, this._getAvailableSlots(token));
|
|
284
305
|
throw new TokenNotBoundError(this._getTokenName(token));
|
|
285
306
|
}
|
|
286
307
|
const { binding, owner } = found;
|
|
287
|
-
if (binding.kind === "alias") return this.resolveAsync(binding.target, hint, resolutionPath,
|
|
288
|
-
if ((binding.scope ?? "transient") === "singleton" && owner !== this) return owner._resolveBindingAsync(binding, hint, resolutionPath,
|
|
289
|
-
return this._resolveBindingAsync(binding, hint, resolutionPath,
|
|
308
|
+
if (binding.kind === "alias") return this.resolveAsync(binding.target, hint, resolutionPath, resolutionStack);
|
|
309
|
+
if ((binding.scope ?? "transient") === "singleton" && owner !== this) return owner._resolveBindingAsync(binding, hint, resolutionPath, resolutionStack);
|
|
310
|
+
return this._resolveBindingAsync(binding, hint, resolutionPath, resolutionStack);
|
|
290
311
|
}
|
|
291
|
-
async _resolveBindingAsync(binding, hint, resolutionPath,
|
|
312
|
+
async _resolveBindingAsync(binding, hint, resolutionPath, resolutionStack) {
|
|
292
313
|
if (binding.kind === "constant" && binding.onActivation === void 0 && !this._lifecycle.hasActivationHandlers(binding.token)) return binding.value;
|
|
293
314
|
const scope = binding.scope ?? "transient";
|
|
294
315
|
if (scope === "singleton") {
|
|
@@ -300,36 +321,36 @@ var DependencyResolver = class {
|
|
|
300
321
|
if (!this._scope.isChild) throw new MissingScopeContextError(this._getTokenName(binding.token));
|
|
301
322
|
if (this._scope.hasScoped(binding.id)) return this._scope.getScoped(binding.id);
|
|
302
323
|
}
|
|
303
|
-
const frame = this.
|
|
304
|
-
const
|
|
324
|
+
const frame = this._getResolutionFrame(binding);
|
|
325
|
+
const frameName = frame.tokenName;
|
|
305
326
|
const pathWithSet = resolutionPath;
|
|
306
327
|
let resolutionSet = pathWithSet[RESOLUTION_SET_KEY];
|
|
307
328
|
if (resolutionSet === void 0 && resolutionPath.length >= RESOLUTION_SET_THRESHOLD) {
|
|
308
329
|
resolutionSet = new Set(resolutionPath);
|
|
309
330
|
pathWithSet[RESOLUTION_SET_KEY] = resolutionSet;
|
|
310
331
|
}
|
|
311
|
-
if (resolutionSet !== void 0 ? resolutionSet.has(
|
|
312
|
-
resolutionPath.push(
|
|
313
|
-
resolutionSet?.add(
|
|
314
|
-
|
|
332
|
+
if (resolutionSet !== void 0 ? resolutionSet.has(frameName) : resolutionPath.includes(frameName)) throw new CircularDependencyError([...resolutionPath, frameName]);
|
|
333
|
+
resolutionPath.push(frameName);
|
|
334
|
+
resolutionSet?.add(frameName);
|
|
335
|
+
resolutionStack.push(frame);
|
|
315
336
|
const needsActivation = this._needsActivation(binding);
|
|
316
337
|
if (!needsActivation && scope === "transient" && (binding.kind === "dynamic" || binding.kind === "dynamic-async")) {
|
|
317
|
-
const resolutionCtx = new DefaultResolutionContext(this, resolutionPath,
|
|
338
|
+
const resolutionCtx = new DefaultResolutionContext(this, resolutionPath, resolutionStack, hint);
|
|
318
339
|
try {
|
|
319
340
|
if (binding.kind === "dynamic-async") return await binding.factory(resolutionCtx);
|
|
320
341
|
const dynamicResult = binding.factory(resolutionCtx);
|
|
321
342
|
return dynamicResult instanceof Promise ? await dynamicResult : dynamicResult;
|
|
322
343
|
} finally {
|
|
323
|
-
|
|
344
|
+
resolutionStack.pop();
|
|
324
345
|
resolutionPath.pop();
|
|
325
|
-
resolutionSet?.delete(
|
|
346
|
+
resolutionSet?.delete(frameName);
|
|
326
347
|
}
|
|
327
348
|
}
|
|
328
|
-
const resolutionCtx = needsActivation || this._requiresResolutionContext(binding) ? new DefaultResolutionContext(this, resolutionPath,
|
|
349
|
+
const resolutionCtx = needsActivation || this._requiresResolutionContext(binding) ? new DefaultResolutionContext(this, resolutionPath, resolutionStack, hint) : void 0;
|
|
329
350
|
try {
|
|
330
351
|
if (scope === "singleton") {
|
|
331
352
|
const createSingletonPromise = async () => {
|
|
332
|
-
const instance = await this._instantiateAsync(binding, resolutionCtx, resolutionPath,
|
|
353
|
+
const instance = await this._instantiateAsync(binding, resolutionCtx, resolutionPath, resolutionStack);
|
|
333
354
|
let shouldActivate = needsActivation;
|
|
334
355
|
if (binding.kind === "class" && this._classHasPostConstruct.get(binding.target) === void 0) {
|
|
335
356
|
this._refreshClassPostConstructCache(binding.target);
|
|
@@ -341,14 +362,14 @@ var DependencyResolver = class {
|
|
|
341
362
|
this._scope.clearInflight(binding.id);
|
|
342
363
|
return activated;
|
|
343
364
|
};
|
|
344
|
-
const
|
|
365
|
+
const singletonPromise = createSingletonPromise().catch((err) => {
|
|
345
366
|
this._scope.clearInflight(binding.id);
|
|
346
367
|
throw err;
|
|
347
368
|
});
|
|
348
|
-
this._scope.setInflight(binding.id,
|
|
349
|
-
return await
|
|
369
|
+
this._scope.setInflight(binding.id, singletonPromise);
|
|
370
|
+
return await singletonPromise;
|
|
350
371
|
}
|
|
351
|
-
const instance = await this._instantiateAsync(binding, resolutionCtx, resolutionPath,
|
|
372
|
+
const instance = await this._instantiateAsync(binding, resolutionCtx, resolutionPath, resolutionStack);
|
|
352
373
|
let shouldActivate = needsActivation;
|
|
353
374
|
if (binding.kind === "class" && this._classHasPostConstruct.get(binding.target) === void 0) {
|
|
354
375
|
this._refreshClassPostConstructCache(binding.target);
|
|
@@ -359,40 +380,40 @@ var DependencyResolver = class {
|
|
|
359
380
|
if (scope === "scoped") this._scope.setScoped(binding.id, activated);
|
|
360
381
|
return activated;
|
|
361
382
|
} finally {
|
|
362
|
-
|
|
383
|
+
resolutionStack.pop();
|
|
363
384
|
resolutionPath.pop();
|
|
364
|
-
resolutionSet?.delete(
|
|
385
|
+
resolutionSet?.delete(frameName);
|
|
365
386
|
}
|
|
366
387
|
}
|
|
367
|
-
async _instantiateAsync(binding, ctx, resolutionPath,
|
|
388
|
+
async _instantiateAsync(binding, ctx, resolutionPath, resolutionStack) {
|
|
368
389
|
switch (binding.kind) {
|
|
369
390
|
case "constant": return binding.value;
|
|
370
391
|
case "dynamic": {
|
|
371
392
|
if (ctx === void 0) throw new InternalError("dynamic binding requires resolution context");
|
|
372
|
-
const
|
|
373
|
-
return
|
|
393
|
+
const factoryResult = binding.factory(ctx);
|
|
394
|
+
return factoryResult instanceof Promise ? factoryResult : Promise.resolve(factoryResult);
|
|
374
395
|
}
|
|
375
396
|
case "dynamic-async":
|
|
376
397
|
if (ctx === void 0) throw new InternalError("dynamic-async binding requires resolution context");
|
|
377
398
|
return binding.factory(ctx);
|
|
378
399
|
case "class": {
|
|
379
|
-
const deps = await this._resolveClassDepsAsync(binding.target, resolutionPath,
|
|
400
|
+
const deps = await this._resolveClassDepsAsync(binding.target, resolutionPath, resolutionStack);
|
|
380
401
|
return this._instantiateClass(binding.target, deps);
|
|
381
402
|
}
|
|
382
403
|
case "resolved": {
|
|
383
404
|
if (ctx === void 0) throw new InternalError("resolved binding requires resolution context");
|
|
384
|
-
const deps = await this._resolveDescriptorDepsAsync(binding.deps, resolutionPath,
|
|
385
|
-
const
|
|
386
|
-
return
|
|
405
|
+
const deps = await this._resolveDescriptorDepsAsync(binding.deps, resolutionPath, resolutionStack);
|
|
406
|
+
const factoryResult = binding.factory(...deps);
|
|
407
|
+
return factoryResult instanceof Promise ? factoryResult : Promise.resolve(factoryResult);
|
|
387
408
|
}
|
|
388
409
|
case "resolved-async": {
|
|
389
|
-
const deps = await this._resolveDescriptorDepsAsync(binding.deps, resolutionPath,
|
|
410
|
+
const deps = await this._resolveDescriptorDepsAsync(binding.deps, resolutionPath, resolutionStack);
|
|
390
411
|
return binding.factory(...deps);
|
|
391
412
|
}
|
|
392
413
|
case "alias": throw new InternalError("alias should have been followed before instantiation");
|
|
393
414
|
}
|
|
394
415
|
}
|
|
395
|
-
async _resolveClassDepsAsync(target, resolutionPath,
|
|
416
|
+
async _resolveClassDepsAsync(target, resolutionPath, resolutionStack) {
|
|
396
417
|
const meta = this._getConstructorMetadata(target);
|
|
397
418
|
if (meta === void 0) {
|
|
398
419
|
if (target.length === 0) return [];
|
|
@@ -401,52 +422,52 @@ var DependencyResolver = class {
|
|
|
401
422
|
if (meta.params.length === 0) return [];
|
|
402
423
|
if (meta.params.length === 1) {
|
|
403
424
|
const param = meta.params[0];
|
|
404
|
-
const paramHint =
|
|
405
|
-
if (param.multi) return [await this.resolveAllAsync(param.token, paramHint, resolutionPath,
|
|
406
|
-
if (param.optional) return [await this.resolveOptionalAsync(param.token, paramHint, resolutionPath,
|
|
407
|
-
if (paramHint === void 0) return [await this.resolveAsyncFromContext(param.token, resolutionPath,
|
|
408
|
-
return [await this.resolveAsync(param.token, paramHint, resolutionPath,
|
|
425
|
+
const paramHint = injectionSlotToResolveOptions(param);
|
|
426
|
+
if (param.multi) return [await this.resolveAllAsync(param.token, paramHint, resolutionPath, resolutionStack)];
|
|
427
|
+
if (param.optional) return [await this.resolveOptionalAsync(param.token, paramHint, resolutionPath, resolutionStack)];
|
|
428
|
+
if (paramHint === void 0) return [await this.resolveAsyncFromContext(param.token, resolutionPath, resolutionStack)];
|
|
429
|
+
return [await this.resolveAsync(param.token, paramHint, resolutionPath, resolutionStack)];
|
|
409
430
|
}
|
|
410
431
|
const pending = new Array(meta.params.length);
|
|
411
432
|
const shouldCloneContext = meta.params.length > 1;
|
|
412
433
|
for (let index = 0; index < meta.params.length; index += 1) {
|
|
413
434
|
const param = meta.params[index];
|
|
414
|
-
const paramHint =
|
|
415
|
-
if (param.multi) pending[index] = this.resolveAllAsync(param.token, paramHint, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...
|
|
416
|
-
else if (param.optional) pending[index] = this.resolveOptionalAsync(param.token, paramHint, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...
|
|
417
|
-
else pending[index] = paramHint === void 0 ? this.resolveAsyncFromContext(param.token, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...
|
|
435
|
+
const paramHint = injectionSlotToResolveOptions(param);
|
|
436
|
+
if (param.multi) pending[index] = this.resolveAllAsync(param.token, paramHint, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...resolutionStack] : resolutionStack);
|
|
437
|
+
else if (param.optional) pending[index] = this.resolveOptionalAsync(param.token, paramHint, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...resolutionStack] : resolutionStack);
|
|
438
|
+
else pending[index] = paramHint === void 0 ? this.resolveAsyncFromContext(param.token, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...resolutionStack] : resolutionStack) : this.resolveAsync(param.token, paramHint, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...resolutionStack] : resolutionStack);
|
|
418
439
|
}
|
|
419
440
|
return Promise.all(pending);
|
|
420
441
|
}
|
|
421
|
-
async _resolveDescriptorDepsAsync(deps, resolutionPath,
|
|
442
|
+
async _resolveDescriptorDepsAsync(deps, resolutionPath, resolutionStack) {
|
|
422
443
|
const pending = new Array(deps.length);
|
|
423
444
|
const shouldCloneContext = deps.length > 1;
|
|
424
445
|
for (let index = 0; index < deps.length; index += 1) {
|
|
425
446
|
const dep = deps[index];
|
|
426
|
-
const depHint =
|
|
427
|
-
if (dep.multi) pending[index] = this.resolveAllAsync(dep.token, depHint, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...
|
|
428
|
-
else if (dep.optional) pending[index] = this.resolveOptionalAsync(dep.token, depHint, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...
|
|
429
|
-
else pending[index] = depHint === void 0 ? this.resolveAsyncFromContext(dep.token, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...
|
|
447
|
+
const depHint = injectionSlotToResolveOptions(dep);
|
|
448
|
+
if (dep.multi) pending[index] = this.resolveAllAsync(dep.token, depHint, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...resolutionStack] : resolutionStack);
|
|
449
|
+
else if (dep.optional) pending[index] = this.resolveOptionalAsync(dep.token, depHint, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...resolutionStack] : resolutionStack);
|
|
450
|
+
else pending[index] = depHint === void 0 ? this.resolveAsyncFromContext(dep.token, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...resolutionStack] : resolutionStack) : this.resolveAsync(dep.token, depHint, shouldCloneContext ? [...resolutionPath] : resolutionPath, shouldCloneContext ? [...resolutionStack] : resolutionStack);
|
|
430
451
|
}
|
|
431
452
|
return Promise.all(pending);
|
|
432
453
|
}
|
|
433
|
-
async resolveOptionalAsync(token, hint, resolutionPath,
|
|
434
|
-
if (this._findBinding(token, hint, resolutionPath,
|
|
435
|
-
return this.resolveAsync(token, hint, resolutionPath,
|
|
454
|
+
async resolveOptionalAsync(token, hint, resolutionPath, resolutionStack) {
|
|
455
|
+
if (this._findBinding(token, hint, resolutionPath, resolutionStack) === void 0) return;
|
|
456
|
+
return this.resolveAsync(token, hint, resolutionPath, resolutionStack);
|
|
436
457
|
}
|
|
437
|
-
async resolveAllAsync(token, hint, resolutionPath,
|
|
458
|
+
async resolveAllAsync(token, hint, resolutionPath, resolutionStack) {
|
|
438
459
|
if (hint?.name !== void 0 && hint.tag === void 0 && (hint.tags?.length ?? 0) === 0) {
|
|
439
460
|
const namedCandidates = this._getSimpleNamedBindingsFromChain(token, hint.name);
|
|
440
461
|
if (namedCandidates.length === 0) return [];
|
|
441
462
|
const pending = new Array(namedCandidates.length);
|
|
442
|
-
for (let index = 0; index < namedCandidates.length; index += 1) pending[index] = this._resolveCandidateAsync(namedCandidates[index], hint, resolutionPath,
|
|
463
|
+
for (let index = 0; index < namedCandidates.length; index += 1) pending[index] = this._resolveCandidateAsync(namedCandidates[index], hint, resolutionPath, resolutionStack);
|
|
443
464
|
return Promise.all(pending);
|
|
444
465
|
}
|
|
445
466
|
const allBindings = this._getAllBindingsFromChain(token);
|
|
446
467
|
if (allBindings.length === 0) return [];
|
|
447
|
-
const candidates = selectAllBindings(allBindings, hint, this._makeConstraintContext(resolutionPath,
|
|
468
|
+
const candidates = selectAllBindings(allBindings, hint, this._makeConstraintContext(resolutionPath, resolutionStack, hint));
|
|
448
469
|
const pending = new Array(candidates.length);
|
|
449
|
-
for (let index = 0; index < candidates.length; index += 1) pending[index] = this._resolveCandidateAsync(candidates[index], hint, resolutionPath,
|
|
470
|
+
for (let index = 0; index < candidates.length; index += 1) pending[index] = this._resolveCandidateAsync(candidates[index], hint, resolutionPath, resolutionStack);
|
|
450
471
|
return Promise.all(pending);
|
|
451
472
|
}
|
|
452
473
|
_getAllBindingsFromChain(token) {
|
|
@@ -477,20 +498,20 @@ var DependencyResolver = class {
|
|
|
477
498
|
_getAvailableSlots(token) {
|
|
478
499
|
return this._registry.availableSlotStrings(token);
|
|
479
500
|
}
|
|
480
|
-
_makeConstraintContext(resolutionPath,
|
|
481
|
-
if (hint === void 0 && resolutionPath.length === 0 &&
|
|
501
|
+
_makeConstraintContext(resolutionPath, resolutionStack, hint) {
|
|
502
|
+
if (hint === void 0 && resolutionPath.length === 0 && resolutionStack.length === 0) return ROOT_CONSTRAINT_CONTEXT;
|
|
482
503
|
return {
|
|
483
504
|
resolutionPath,
|
|
484
|
-
|
|
485
|
-
parent:
|
|
486
|
-
ancestors:
|
|
505
|
+
resolutionStack,
|
|
506
|
+
parent: resolutionStack.at(-1),
|
|
507
|
+
ancestors: resolutionStack.length > 1 ? resolutionStack.slice(0, -1) : [],
|
|
487
508
|
currentResolveHint: hint
|
|
488
509
|
};
|
|
489
510
|
}
|
|
490
|
-
_matchesBindingFast(binding, hint, resolutionPath,
|
|
511
|
+
_matchesBindingFast(binding, hint, resolutionPath, resolutionStack) {
|
|
491
512
|
if (!this._matchesSlotFast(binding.slot, hint)) return false;
|
|
492
513
|
if (binding.predicate === void 0) return true;
|
|
493
|
-
const ctx = this._makeConstraintContext(resolutionPath,
|
|
514
|
+
const ctx = this._makeConstraintContext(resolutionPath, resolutionStack, hint);
|
|
494
515
|
return binding.predicate(ctx);
|
|
495
516
|
}
|
|
496
517
|
_matchesSlotFast(slot, hint) {
|
|
@@ -536,32 +557,32 @@ var DependencyResolver = class {
|
|
|
536
557
|
}
|
|
537
558
|
return false;
|
|
538
559
|
}
|
|
539
|
-
_resolveTransientDynamicSyncFromContext(binding, resolutionPath,
|
|
560
|
+
_resolveTransientDynamicSyncFromContext(binding, resolutionPath, resolutionStack) {
|
|
540
561
|
if (resolutionPath.length < RESOLUTION_SET_THRESHOLD) {
|
|
541
|
-
const frame = this.
|
|
542
|
-
const
|
|
543
|
-
if (resolutionPath.includes(
|
|
544
|
-
resolutionPath.push(
|
|
545
|
-
|
|
546
|
-
const resolutionCtx = this._acquireSyncResolutionContext(resolutionPath,
|
|
562
|
+
const frame = this._getResolutionFrame(binding);
|
|
563
|
+
const tokenDisplayName = frame.tokenName;
|
|
564
|
+
if (resolutionPath.includes(tokenDisplayName)) throw new CircularDependencyError([...resolutionPath, tokenDisplayName]);
|
|
565
|
+
resolutionPath.push(tokenDisplayName);
|
|
566
|
+
resolutionStack.push(frame);
|
|
567
|
+
const resolutionCtx = this._acquireSyncResolutionContext(resolutionPath, resolutionStack, void 0);
|
|
547
568
|
try {
|
|
548
569
|
const dynamicResult = binding.factory(resolutionCtx);
|
|
549
|
-
if (dynamicResult instanceof Promise) throw new AsyncResolutionError(
|
|
570
|
+
if (dynamicResult instanceof Promise) throw new AsyncResolutionError(tokenDisplayName, tokenDisplayName);
|
|
550
571
|
return dynamicResult;
|
|
551
572
|
} finally {
|
|
552
|
-
|
|
573
|
+
resolutionStack.pop();
|
|
553
574
|
resolutionPath.pop();
|
|
554
575
|
}
|
|
555
576
|
}
|
|
556
|
-
if (this._deepActiveLevels > 0 && this._deepSyncCtxPath !== resolutionPath) return this._resolveTransientDynamicSyncSlow(binding, resolutionPath,
|
|
577
|
+
if (this._deepActiveLevels > 0 && this._deepSyncCtxPath !== resolutionPath) return this._resolveTransientDynamicSyncSlow(binding, resolutionPath, resolutionStack);
|
|
557
578
|
if (this._deepActiveLevels === 0) {
|
|
558
579
|
const gen = ++this._deepCycleGen;
|
|
559
|
-
for (const stackFrame of
|
|
580
|
+
for (const stackFrame of resolutionStack) this._deepCycleMarks.set(stackFrame.bindingId, gen);
|
|
560
581
|
let ctx = this._deepSyncCtx;
|
|
561
582
|
if (ctx === void 0) {
|
|
562
|
-
ctx = new DefaultResolutionContext(this, resolutionPath,
|
|
583
|
+
ctx = new DefaultResolutionContext(this, resolutionPath, resolutionStack, void 0);
|
|
563
584
|
this._deepSyncCtx = ctx;
|
|
564
|
-
} else ctx.reset(this, resolutionPath,
|
|
585
|
+
} else ctx.reset(this, resolutionPath, resolutionStack, void 0);
|
|
565
586
|
this._deepSyncCtxPath = resolutionPath;
|
|
566
587
|
}
|
|
567
588
|
if (this._deepCycleMarks.get(binding.id) === this._deepCycleGen) throw new CircularDependencyError([...resolutionPath, tokenName(binding.token)]);
|
|
@@ -575,35 +596,35 @@ var DependencyResolver = class {
|
|
|
575
596
|
if (--this._deepActiveLevels === 0) this._deepSyncCtxPath = void 0;
|
|
576
597
|
}
|
|
577
598
|
}
|
|
578
|
-
_resolveTransientDynamicSyncSlow(binding, resolutionPath,
|
|
579
|
-
const frame = this.
|
|
580
|
-
const
|
|
599
|
+
_resolveTransientDynamicSyncSlow(binding, resolutionPath, resolutionStack) {
|
|
600
|
+
const frame = this._getResolutionFrame(binding);
|
|
601
|
+
const tokenDisplayName = frame.tokenName;
|
|
581
602
|
const pathWithSet = resolutionPath;
|
|
582
603
|
let resolutionSet = pathWithSet[RESOLUTION_SET_KEY];
|
|
583
604
|
if (resolutionSet === void 0) {
|
|
584
605
|
resolutionSet = new Set(resolutionPath);
|
|
585
606
|
pathWithSet[RESOLUTION_SET_KEY] = resolutionSet;
|
|
586
607
|
}
|
|
587
|
-
if (resolutionSet.has(
|
|
588
|
-
resolutionPath.push(
|
|
589
|
-
resolutionSet.add(
|
|
590
|
-
|
|
591
|
-
const resolutionCtx = this._acquireSyncResolutionContext(resolutionPath,
|
|
608
|
+
if (resolutionSet.has(tokenDisplayName)) throw new CircularDependencyError([...resolutionPath, tokenDisplayName]);
|
|
609
|
+
resolutionPath.push(tokenDisplayName);
|
|
610
|
+
resolutionSet.add(tokenDisplayName);
|
|
611
|
+
resolutionStack.push(frame);
|
|
612
|
+
const resolutionCtx = this._acquireSyncResolutionContext(resolutionPath, resolutionStack, void 0);
|
|
592
613
|
try {
|
|
593
614
|
const dynamicResult = binding.factory(resolutionCtx);
|
|
594
|
-
if (dynamicResult instanceof Promise) throw new AsyncResolutionError(
|
|
615
|
+
if (dynamicResult instanceof Promise) throw new AsyncResolutionError(tokenDisplayName, tokenDisplayName);
|
|
595
616
|
return dynamicResult;
|
|
596
617
|
} finally {
|
|
597
|
-
|
|
618
|
+
resolutionStack.pop();
|
|
598
619
|
resolutionPath.pop();
|
|
599
|
-
resolutionSet.delete(
|
|
620
|
+
resolutionSet.delete(tokenDisplayName);
|
|
600
621
|
}
|
|
601
622
|
}
|
|
602
|
-
_resolveTransientDynamicAsyncFromContext(binding, resolutionPath,
|
|
623
|
+
_resolveTransientDynamicAsyncFromContext(binding, resolutionPath, resolutionStack) {
|
|
603
624
|
if (resolutionPath.length < RESOLUTION_SET_THRESHOLD) {
|
|
604
|
-
const
|
|
605
|
-
if (resolutionPath.includes(
|
|
606
|
-
resolutionPath.push(
|
|
625
|
+
const tokenDisplayName = tokenName(binding.token);
|
|
626
|
+
if (resolutionPath.includes(tokenDisplayName)) return Promise.reject(new CircularDependencyError([...resolutionPath, tokenDisplayName]));
|
|
627
|
+
resolutionPath.push(tokenDisplayName);
|
|
607
628
|
let ctx;
|
|
608
629
|
let isOwnerLevel;
|
|
609
630
|
if (this._deepAsyncCtxPath === resolutionPath) {
|
|
@@ -612,16 +633,16 @@ var DependencyResolver = class {
|
|
|
612
633
|
} else if (this._deepAsyncCtxPath === void 0) {
|
|
613
634
|
const existing = this._deepAsyncCtx;
|
|
614
635
|
if (existing === void 0) {
|
|
615
|
-
ctx = new DefaultResolutionContext(this, resolutionPath,
|
|
636
|
+
ctx = new DefaultResolutionContext(this, resolutionPath, resolutionStack, void 0);
|
|
616
637
|
this._deepAsyncCtx = ctx;
|
|
617
638
|
} else {
|
|
618
|
-
existing.reset(this, resolutionPath,
|
|
639
|
+
existing.reset(this, resolutionPath, resolutionStack, void 0);
|
|
619
640
|
ctx = existing;
|
|
620
641
|
}
|
|
621
642
|
this._deepAsyncCtxPath = resolutionPath;
|
|
622
643
|
isOwnerLevel = true;
|
|
623
644
|
} else {
|
|
624
|
-
ctx = new DefaultResolutionContext(this, resolutionPath,
|
|
645
|
+
ctx = new DefaultResolutionContext(this, resolutionPath, resolutionStack, void 0);
|
|
625
646
|
isOwnerLevel = false;
|
|
626
647
|
}
|
|
627
648
|
if (isOwnerLevel) this._deepAsyncActiveLevels++;
|
|
@@ -629,8 +650,8 @@ var DependencyResolver = class {
|
|
|
629
650
|
try {
|
|
630
651
|
if (binding.kind === "dynamic-async") factoryPromise = binding.factory(ctx);
|
|
631
652
|
else {
|
|
632
|
-
const
|
|
633
|
-
factoryPromise =
|
|
653
|
+
const factoryResult = binding.factory(ctx);
|
|
654
|
+
factoryPromise = factoryResult instanceof Promise ? factoryResult : Promise.resolve(factoryResult);
|
|
634
655
|
}
|
|
635
656
|
} catch (err) {
|
|
636
657
|
resolutionPath.pop();
|
|
@@ -647,47 +668,47 @@ var DependencyResolver = class {
|
|
|
647
668
|
throw err;
|
|
648
669
|
});
|
|
649
670
|
}
|
|
650
|
-
return this._resolveTransientDynamicAsyncSlow(binding, resolutionPath,
|
|
671
|
+
return this._resolveTransientDynamicAsyncSlow(binding, resolutionPath, resolutionStack);
|
|
651
672
|
}
|
|
652
|
-
async _resolveTransientDynamicAsyncSlow(binding, resolutionPath,
|
|
653
|
-
const frame = this.
|
|
654
|
-
const
|
|
673
|
+
async _resolveTransientDynamicAsyncSlow(binding, resolutionPath, resolutionStack) {
|
|
674
|
+
const frame = this._getResolutionFrame(binding);
|
|
675
|
+
const tokenDisplayName = frame.tokenName;
|
|
655
676
|
const pathWithSet = resolutionPath;
|
|
656
677
|
let resolutionSet = pathWithSet[RESOLUTION_SET_KEY];
|
|
657
678
|
if (resolutionSet === void 0) {
|
|
658
679
|
resolutionSet = new Set(resolutionPath);
|
|
659
680
|
pathWithSet[RESOLUTION_SET_KEY] = resolutionSet;
|
|
660
681
|
}
|
|
661
|
-
if (resolutionSet.has(
|
|
662
|
-
resolutionPath.push(
|
|
663
|
-
resolutionSet.add(
|
|
664
|
-
|
|
665
|
-
const resolutionCtx = new DefaultResolutionContext(this, resolutionPath,
|
|
682
|
+
if (resolutionSet.has(tokenDisplayName)) throw new CircularDependencyError([...resolutionPath, tokenDisplayName]);
|
|
683
|
+
resolutionPath.push(tokenDisplayName);
|
|
684
|
+
resolutionSet.add(tokenDisplayName);
|
|
685
|
+
resolutionStack.push(frame);
|
|
686
|
+
const resolutionCtx = new DefaultResolutionContext(this, resolutionPath, resolutionStack, void 0);
|
|
666
687
|
try {
|
|
667
688
|
if (binding.kind === "dynamic-async") return await binding.factory(resolutionCtx);
|
|
668
689
|
const dynamicResult = binding.factory(resolutionCtx);
|
|
669
690
|
return dynamicResult instanceof Promise ? await dynamicResult : dynamicResult;
|
|
670
691
|
} finally {
|
|
671
|
-
|
|
692
|
+
resolutionStack.pop();
|
|
672
693
|
resolutionPath.pop();
|
|
673
|
-
resolutionSet.delete(
|
|
694
|
+
resolutionSet.delete(tokenDisplayName);
|
|
674
695
|
}
|
|
675
696
|
}
|
|
676
|
-
_resolveCandidateSync(binding, hint, resolutionPath,
|
|
697
|
+
_resolveCandidateSync(binding, hint, resolutionPath, resolutionStack) {
|
|
677
698
|
if (binding.kind === "constant" && binding.onActivation === void 0 && !this._lifecycle.hasActivationHandlers(binding.token)) return binding.value;
|
|
678
|
-
if (binding.kind === "alias") return this.resolve(binding.target, hint, resolutionPath,
|
|
699
|
+
if (binding.kind === "alias") return this.resolve(binding.target, hint, resolutionPath, resolutionStack);
|
|
679
700
|
const scope = binding.scope ?? "transient";
|
|
680
701
|
if (scope === "singleton" && this._scope.hasSingleton(binding.id)) return this._scope.getSingleton(binding.id);
|
|
681
702
|
if (scope === "scoped") {
|
|
682
703
|
if (!this._scope.isChild) throw new MissingScopeContextError(this._getTokenName(binding.token));
|
|
683
704
|
if (this._scope.hasScoped(binding.id)) return this._scope.getScoped(binding.id);
|
|
684
705
|
}
|
|
685
|
-
return this._resolveBinding(binding, hint, resolutionPath,
|
|
706
|
+
return this._resolveBinding(binding, hint, resolutionPath, resolutionStack);
|
|
686
707
|
}
|
|
687
|
-
_resolveCandidateAsync(binding, hint, resolutionPath,
|
|
708
|
+
_resolveCandidateAsync(binding, hint, resolutionPath, resolutionStack) {
|
|
688
709
|
if (binding.kind === "constant" && binding.onActivation === void 0 && !this._lifecycle.hasActivationHandlers(binding.token)) return Promise.resolve(binding.value);
|
|
689
710
|
const isolatedPath = [...resolutionPath];
|
|
690
|
-
const isolatedStack = [...
|
|
711
|
+
const isolatedStack = [...resolutionStack];
|
|
691
712
|
if (binding.kind === "alias") return this.resolveAsync(binding.target, hint, isolatedPath, isolatedStack);
|
|
692
713
|
const scope = binding.scope ?? "transient";
|
|
693
714
|
if (scope === "singleton" && this._scope.hasSingleton(binding.id)) return Promise.resolve(this._scope.getSingleton(binding.id));
|
|
@@ -697,11 +718,11 @@ var DependencyResolver = class {
|
|
|
697
718
|
}
|
|
698
719
|
return this._resolveBindingAsync(binding, hint, isolatedPath, isolatedStack);
|
|
699
720
|
}
|
|
700
|
-
|
|
721
|
+
_getResolutionFrame(binding) {
|
|
701
722
|
const existing = this._frameByBindingId.get(binding.id);
|
|
702
723
|
if (existing !== void 0) return existing;
|
|
703
724
|
const scope = binding.scope ?? "transient";
|
|
704
|
-
const frame =
|
|
725
|
+
const frame = buildResolutionFrame(tokenName(binding.token), scope, binding.id, binding.kind, binding.slot);
|
|
705
726
|
this._frameByBindingId.set(binding.id, frame);
|
|
706
727
|
return frame;
|
|
707
728
|
}
|
|
@@ -736,14 +757,14 @@ var DependencyResolver = class {
|
|
|
736
757
|
_requiresResolutionContext(binding) {
|
|
737
758
|
return binding.kind === "dynamic" || binding.kind === "dynamic-async";
|
|
738
759
|
}
|
|
739
|
-
_acquireSyncResolutionContext(resolutionPath,
|
|
740
|
-
const depth =
|
|
760
|
+
_acquireSyncResolutionContext(resolutionPath, resolutionStack, hint) {
|
|
761
|
+
const depth = resolutionStack.length;
|
|
741
762
|
const existing = this._syncResolutionContextPool[depth];
|
|
742
763
|
if (existing !== void 0) {
|
|
743
|
-
existing.reset(this, resolutionPath,
|
|
764
|
+
existing.reset(this, resolutionPath, resolutionStack, hint);
|
|
744
765
|
return existing;
|
|
745
766
|
}
|
|
746
|
-
const created = new DefaultResolutionContext(this, resolutionPath,
|
|
767
|
+
const created = new DefaultResolutionContext(this, resolutionPath, resolutionStack, hint);
|
|
747
768
|
this._syncResolutionContextPool[depth] = created;
|
|
748
769
|
return created;
|
|
749
770
|
}
|