@codefast/di 0.3.15 → 0.3.16-canary.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/README.md +4 -1
- package/dist/binding-scope.d.mts +2 -0
- package/dist/binding-scope.mjs +2 -0
- package/dist/binding-select.d.mts +6 -2
- package/dist/binding-select.mjs +4 -0
- package/dist/binding.d.mts +74 -7
- package/dist/binding.mjs +12 -0
- package/dist/constraints.d.mts +49 -9
- package/dist/constraints.mjs +71 -19
- package/dist/constructor-type.d.mts +6 -2
- package/dist/container.d.mts +15 -6
- package/dist/container.mjs +139 -55
- package/dist/decorators/inject.d.mts +27 -3
- package/dist/decorators/inject.mjs +28 -11
- package/dist/decorators/injectable.d.mts +13 -1
- package/dist/decorators/injectable.mjs +24 -14
- package/dist/decorators/lifecycle-decorators.d.mts +6 -0
- package/dist/decorators/lifecycle-decorators.mjs +9 -0
- package/dist/dependency-graph.d.mts +17 -2
- package/dist/dependency-graph.mjs +3 -0
- package/dist/environment.d.mts +27 -12
- package/dist/environment.mjs +12 -0
- package/dist/errors.d.mts +69 -8
- package/dist/errors.mjs +65 -1
- package/dist/graph-adapters/cytoscape.d.mts +12 -0
- package/dist/graph-adapters/cytoscape.mjs +3 -0
- package/dist/graph-adapters/dot.d.mts +3 -0
- package/dist/graph-adapters/dot.mjs +3 -0
- package/dist/graph-adapters/reactflow.d.mts +14 -2
- package/dist/graph-adapters/reactflow.mjs +3 -0
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +4 -3
- package/dist/inspector.d.mts +11 -3
- package/dist/inspector.mjs +8 -3
- package/dist/lifecycle.d.mts +8 -6
- package/dist/lifecycle.mjs +48 -52
- package/dist/metadata/metadata-keys.d.mts +42 -1
- package/dist/metadata/metadata-keys.mjs +32 -1
- package/dist/metadata/metadata-reader-token.d.mts +3 -0
- package/dist/metadata/metadata-reader-token.mjs +3 -0
- package/dist/metadata/metadata-types.d.mts +22 -6
- package/dist/metadata/symbol-metadata-reader.d.mts +6 -0
- package/dist/metadata/symbol-metadata-reader.mjs +37 -24
- package/dist/module.d.mts +25 -1
- package/dist/module.mjs +12 -0
- package/dist/registry.d.mts +8 -5
- package/dist/registry.mjs +38 -42
- package/dist/resolve-options.d.mts +4 -0
- package/dist/resolve-options.mjs +4 -0
- package/dist/resolver.d.mts +23 -8
- package/dist/resolver.mjs +67 -43
- package/dist/scope.d.mts +3 -0
- package/dist/scope.mjs +3 -0
- package/dist/token.d.mts +12 -0
- package/dist/token.mjs +9 -0
- package/dist/types.d.mts +44 -6
- package/package.json +11 -5
package/dist/registry.mjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { slotKeyEquals } from "./binding.mjs";
|
|
1
|
+
import { slotKeyEquals, slotKeyToString } from "./binding.mjs";
|
|
2
2
|
//#region src/registry.ts
|
|
3
|
+
/**
|
|
4
|
+
* @since 0.3.16-canary.0
|
|
5
|
+
*/
|
|
3
6
|
var BindingRegistry = class {
|
|
4
7
|
_bindings = /* @__PURE__ */ new Map();
|
|
5
8
|
_byId = /* @__PURE__ */ new Map();
|
|
@@ -9,20 +12,20 @@ var BindingRegistry = class {
|
|
|
9
12
|
/** Add or replace binding using slot-aware last-wins. */
|
|
10
13
|
add(binding) {
|
|
11
14
|
const key = binding.token;
|
|
12
|
-
let
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
this._bindings.set(key,
|
|
15
|
+
let bindingsForToken = this._bindings.get(key);
|
|
16
|
+
if (bindingsForToken === void 0) {
|
|
17
|
+
bindingsForToken = [];
|
|
18
|
+
this._bindings.set(key, bindingsForToken);
|
|
16
19
|
}
|
|
17
20
|
if (!this._isPurePredicateBinding(binding)) {
|
|
18
|
-
const existingIndex =
|
|
21
|
+
const existingIndex = bindingsForToken.findIndex((b) => !this._isPurePredicateBinding(b) && slotKeyEquals(b.slot, binding.slot));
|
|
19
22
|
if (existingIndex !== -1) {
|
|
20
|
-
const
|
|
21
|
-
this._byId.delete(
|
|
22
|
-
|
|
23
|
+
const replacedBinding = bindingsForToken[existingIndex];
|
|
24
|
+
this._byId.delete(replacedBinding.id);
|
|
25
|
+
bindingsForToken.splice(existingIndex, 1);
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
|
-
|
|
28
|
+
bindingsForToken.push(binding);
|
|
26
29
|
this._byId.set(binding.id, binding);
|
|
27
30
|
this._indexSimpleNamedBinding(key, binding);
|
|
28
31
|
this._indexSimpleTaggedBinding(key, binding);
|
|
@@ -31,13 +34,13 @@ var BindingRegistry = class {
|
|
|
31
34
|
/** Remove all bindings for a token. Returns removed bindings. */
|
|
32
35
|
removeByToken(t) {
|
|
33
36
|
const key = t;
|
|
34
|
-
const
|
|
37
|
+
const bindingsForToken = this._bindings.get(key) ?? [];
|
|
35
38
|
this._bindings.delete(key);
|
|
36
39
|
this._simpleNamed.delete(key);
|
|
37
40
|
this._simpleTagged.delete(key);
|
|
38
41
|
this._fastDefault.delete(key);
|
|
39
|
-
for (const
|
|
40
|
-
return
|
|
42
|
+
for (const binding of bindingsForToken) this._byId.delete(binding.id);
|
|
43
|
+
return bindingsForToken;
|
|
41
44
|
}
|
|
42
45
|
/** Remove a specific binding by ID. Returns the removed binding or undefined. */
|
|
43
46
|
removeById(id) {
|
|
@@ -45,13 +48,13 @@ var BindingRegistry = class {
|
|
|
45
48
|
if (binding === void 0) return;
|
|
46
49
|
this._byId.delete(id);
|
|
47
50
|
const key = binding.token;
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
50
|
-
const
|
|
51
|
-
if (
|
|
51
|
+
const bindingsForToken = this._bindings.get(key);
|
|
52
|
+
if (bindingsForToken !== void 0) {
|
|
53
|
+
const bindingIndex = bindingsForToken.findIndex((candidate) => candidate.id === id);
|
|
54
|
+
if (bindingIndex !== -1) bindingsForToken.splice(bindingIndex, 1);
|
|
52
55
|
this._deindexSimpleNamedBinding(key, binding);
|
|
53
56
|
this._deindexSimpleTaggedBinding(key, binding);
|
|
54
|
-
if (
|
|
57
|
+
if (bindingsForToken.length === 0) {
|
|
55
58
|
this._bindings.delete(key);
|
|
56
59
|
this._simpleNamed.delete(key);
|
|
57
60
|
this._simpleTagged.delete(key);
|
|
@@ -76,9 +79,9 @@ var BindingRegistry = class {
|
|
|
76
79
|
}
|
|
77
80
|
/** All bindings in the registry. */
|
|
78
81
|
allBindings() {
|
|
79
|
-
const
|
|
80
|
-
for (const
|
|
81
|
-
return
|
|
82
|
+
const allBindings = [];
|
|
83
|
+
for (const bindingsForToken of this._bindings.values()) allBindings.push(...bindingsForToken);
|
|
84
|
+
return allBindings;
|
|
82
85
|
}
|
|
83
86
|
/** Remove all bindings. Returns all removed. */
|
|
84
87
|
clear() {
|
|
@@ -101,14 +104,7 @@ var BindingRegistry = class {
|
|
|
101
104
|
}
|
|
102
105
|
/** Summarize available slot strings for a token (for error messages). */
|
|
103
106
|
availableSlotStrings(t) {
|
|
104
|
-
return (this._bindings.get(t) ?? []).map((
|
|
105
|
-
const s = b.slot;
|
|
106
|
-
if (s.name === void 0 && s.tags.length === 0) return "default";
|
|
107
|
-
const parts = [];
|
|
108
|
-
if (s.name !== void 0) parts.push(`name:${s.name}`);
|
|
109
|
-
for (const [k, v] of s.tags) parts.push(`tag:${k}=${String(v)}`);
|
|
110
|
-
return parts.join(",");
|
|
111
|
-
});
|
|
107
|
+
return (this._bindings.get(t) ?? []).map((binding) => slotKeyToString(binding.slot));
|
|
112
108
|
}
|
|
113
109
|
_indexSimpleTaggedBinding(tokenKeyValue, binding) {
|
|
114
110
|
const slot = binding.slot;
|
|
@@ -151,30 +147,30 @@ var BindingRegistry = class {
|
|
|
151
147
|
_indexSimpleNamedBinding(tokenKeyValue, binding) {
|
|
152
148
|
const slot = binding.slot;
|
|
153
149
|
if (slot.name === void 0 || slot.tags.length > 0) return;
|
|
154
|
-
let
|
|
155
|
-
if (
|
|
156
|
-
|
|
157
|
-
this._simpleNamed.set(tokenKeyValue,
|
|
150
|
+
let bindingsByName = this._simpleNamed.get(tokenKeyValue);
|
|
151
|
+
if (bindingsByName === void 0) {
|
|
152
|
+
bindingsByName = /* @__PURE__ */ new Map();
|
|
153
|
+
this._simpleNamed.set(tokenKeyValue, bindingsByName);
|
|
158
154
|
}
|
|
159
|
-
|
|
155
|
+
bindingsByName.set(slot.name, binding);
|
|
160
156
|
}
|
|
161
157
|
_deindexSimpleNamedBinding(tokenKeyValue, binding) {
|
|
162
158
|
const slot = binding.slot;
|
|
163
159
|
if (slot.name === void 0 || slot.tags.length > 0) return;
|
|
164
|
-
const
|
|
165
|
-
if (
|
|
166
|
-
if (
|
|
167
|
-
|
|
168
|
-
if (
|
|
160
|
+
const bindingsByName = this._simpleNamed.get(tokenKeyValue);
|
|
161
|
+
if (bindingsByName === void 0) return;
|
|
162
|
+
if (bindingsByName.get(slot.name)?.id === binding.id) {
|
|
163
|
+
bindingsByName.delete(slot.name);
|
|
164
|
+
if (bindingsByName.size === 0) this._simpleNamed.delete(tokenKeyValue);
|
|
169
165
|
}
|
|
170
166
|
}
|
|
171
167
|
_refreshFastDefaultForToken(tokenKeyValue) {
|
|
172
|
-
const
|
|
173
|
-
if (
|
|
168
|
+
const bindingsForToken = this._bindings.get(tokenKeyValue);
|
|
169
|
+
if (bindingsForToken === void 0 || bindingsForToken.length !== 1) {
|
|
174
170
|
this._fastDefault.delete(tokenKeyValue);
|
|
175
171
|
return;
|
|
176
172
|
}
|
|
177
|
-
const onlyBinding =
|
|
173
|
+
const onlyBinding = bindingsForToken[0];
|
|
178
174
|
if (!(onlyBinding.slot.name === void 0 && onlyBinding.slot.tags.length === 0) || onlyBinding.predicate !== void 0) {
|
|
179
175
|
this._fastDefault.delete(tokenKeyValue);
|
|
180
176
|
return;
|
|
@@ -5,6 +5,8 @@ import { SlotKey } from "./binding.mjs";
|
|
|
5
5
|
/**
|
|
6
6
|
* Builds a {@link ResolveOptions} safe for `exactOptionalPropertyTypes`:
|
|
7
7
|
* omits keys instead of assigning `undefined`.
|
|
8
|
+
*
|
|
9
|
+
* @since 0.3.16-canary.0
|
|
8
10
|
*/
|
|
9
11
|
declare function injectableSlotToResolveOptions(slot: {
|
|
10
12
|
readonly name?: string;
|
|
@@ -12,6 +14,8 @@ declare function injectableSlotToResolveOptions(slot: {
|
|
|
12
14
|
}): ResolveOptions | undefined;
|
|
13
15
|
/**
|
|
14
16
|
* Hint from a binding {@link SlotKey} (tags may be empty; omits when nothing to match).
|
|
17
|
+
*
|
|
18
|
+
* @since 0.3.16-canary.0
|
|
15
19
|
*/
|
|
16
20
|
declare function slotKeyToResolveOptions(slot: SlotKey): ResolveOptions | undefined;
|
|
17
21
|
//#endregion
|
package/dist/resolve-options.mjs
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Builds a {@link ResolveOptions} safe for `exactOptionalPropertyTypes`:
|
|
4
4
|
* omits keys instead of assigning `undefined`.
|
|
5
|
+
*
|
|
6
|
+
* @since 0.3.16-canary.0
|
|
5
7
|
*/
|
|
6
8
|
function injectableSlotToResolveOptions(slot) {
|
|
7
9
|
const options = {};
|
|
@@ -11,6 +13,8 @@ function injectableSlotToResolveOptions(slot) {
|
|
|
11
13
|
}
|
|
12
14
|
/**
|
|
13
15
|
* Hint from a binding {@link SlotKey} (tags may be empty; omits when nothing to match).
|
|
16
|
+
*
|
|
17
|
+
* @since 0.3.16-canary.0
|
|
14
18
|
*/
|
|
15
19
|
function slotKeyToResolveOptions(slot) {
|
|
16
20
|
const options = {};
|
package/dist/resolver.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Constructor } from "./constructor-type.mjs";
|
|
2
2
|
import { Token } from "./token.mjs";
|
|
3
3
|
import { MaterializationFrame, ResolveOptions } from "./types.mjs";
|
|
4
|
+
import { Binding } from "./binding.mjs";
|
|
4
5
|
import { BindingRegistry } from "./registry.mjs";
|
|
5
6
|
import { ScopeManager } from "./scope.mjs";
|
|
6
7
|
import { MetadataReader } from "./metadata/metadata-types.mjs";
|
|
@@ -8,6 +9,9 @@ import { Container } from "./container.mjs";
|
|
|
8
9
|
import { LifecycleManager } from "./lifecycle.mjs";
|
|
9
10
|
|
|
10
11
|
//#region src/resolver.d.ts
|
|
12
|
+
/**
|
|
13
|
+
* @since 0.3.16-canary.0
|
|
14
|
+
*/
|
|
11
15
|
declare class DependencyResolver {
|
|
12
16
|
private readonly _registry;
|
|
13
17
|
private readonly _scope;
|
|
@@ -32,22 +36,33 @@ declare class DependencyResolver {
|
|
|
32
36
|
private _activationCacheVersion;
|
|
33
37
|
constructor(_registry: BindingRegistry, _scope: ScopeManager, _lifecycle: LifecycleManager, _metadataReader: MetadataReader, _container: Container, _parent: DependencyResolver | undefined);
|
|
34
38
|
private _findBinding;
|
|
35
|
-
|
|
36
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Binding lookup aligned with `resolve` — used by `Container.validate` without instantiating.
|
|
41
|
+
*/
|
|
42
|
+
peekBindingForValidate(token: Token<unknown> | Constructor, hint: ResolveOptions | undefined): {
|
|
43
|
+
binding: Binding;
|
|
44
|
+
owner: DependencyResolver;
|
|
45
|
+
} | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Mirrors {@link DependencyResolver.resolveAll} candidate selection only (no instantiation).
|
|
48
|
+
*/
|
|
49
|
+
peekCandidateBindingsForValidate(token: Token<unknown> | Constructor, hint: ResolveOptions | undefined): Array<Binding>;
|
|
50
|
+
resolveFromContext<const Value>(token: Token<Value> | Constructor<Value>, resolutionPath: Array<string>, materializationStack: Array<MaterializationFrame>): Value;
|
|
51
|
+
resolve<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: Array<string>, materializationStack: Array<MaterializationFrame>): Value;
|
|
37
52
|
private _resolveBinding;
|
|
38
53
|
private _instantiateSync;
|
|
39
54
|
private _resolveClassDeps;
|
|
40
55
|
private _resolveDescriptorDeps;
|
|
41
|
-
resolveOptional<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: string
|
|
42
|
-
resolveAll<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: string
|
|
43
|
-
resolveAsyncFromContext<const Value>(token: Token<Value> | Constructor<Value>, resolutionPath: string
|
|
44
|
-
resolveAsync<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: string
|
|
56
|
+
resolveOptional<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: Array<string>, materializationStack: Array<MaterializationFrame>): Value | undefined;
|
|
57
|
+
resolveAll<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: Array<string>, materializationStack: Array<MaterializationFrame>): Array<Value>;
|
|
58
|
+
resolveAsyncFromContext<const Value>(token: Token<Value> | Constructor<Value>, resolutionPath: Array<string>, materializationStack: Array<MaterializationFrame>): Promise<Value>;
|
|
59
|
+
resolveAsync<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: Array<string>, materializationStack: Array<MaterializationFrame>): Promise<Value>;
|
|
45
60
|
private _resolveBindingAsync;
|
|
46
61
|
private _instantiateAsync;
|
|
47
62
|
private _resolveClassDepsAsync;
|
|
48
63
|
private _resolveDescriptorDepsAsync;
|
|
49
|
-
resolveOptionalAsync<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: string
|
|
50
|
-
resolveAllAsync<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: string
|
|
64
|
+
resolveOptionalAsync<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: Array<string>, materializationStack: Array<MaterializationFrame>): Promise<Value | undefined>;
|
|
65
|
+
resolveAllAsync<const Value>(token: Token<Value> | Constructor<Value>, hint: ResolveOptions | undefined, resolutionPath: Array<string>, materializationStack: Array<MaterializationFrame>): Promise<Array<Value>>;
|
|
51
66
|
private _getAllBindingsFromChain;
|
|
52
67
|
private _getSimpleNamedBindingsFromChain;
|
|
53
68
|
private _getAvailableSlots;
|
package/dist/resolver.mjs
CHANGED
|
@@ -15,7 +15,16 @@ const ROOT_CONSTRAINT_CONTEXT = {
|
|
|
15
15
|
ancestors: EMPTY_FRAME_LIST,
|
|
16
16
|
currentResolveHint: void 0
|
|
17
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* @since 0.3.16-canary.0
|
|
20
|
+
*/
|
|
18
21
|
var DependencyResolver = class {
|
|
22
|
+
_registry;
|
|
23
|
+
_scope;
|
|
24
|
+
_lifecycle;
|
|
25
|
+
_metadataReader;
|
|
26
|
+
_container;
|
|
27
|
+
_parent;
|
|
19
28
|
_frameByBindingId = /* @__PURE__ */ new Map();
|
|
20
29
|
_syncResolutionContextPool = [];
|
|
21
30
|
_deepCycleMarks = /* @__PURE__ */ new Map();
|
|
@@ -84,6 +93,21 @@ var DependencyResolver = class {
|
|
|
84
93
|
}
|
|
85
94
|
if (this._parent !== void 0) return this._parent._findBinding(token, hint, resolutionPath, materializationStack);
|
|
86
95
|
}
|
|
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
|
+
}
|
|
87
111
|
resolveFromContext(token, resolutionPath, materializationStack) {
|
|
88
112
|
const fastBinding = this._registry.getFastDefault(token);
|
|
89
113
|
if (fastBinding !== void 0) {
|
|
@@ -121,16 +145,16 @@ var DependencyResolver = class {
|
|
|
121
145
|
if (this._scope.hasScoped(binding.id)) return this._scope.getScoped(binding.id);
|
|
122
146
|
}
|
|
123
147
|
const frame = this._getMaterializationFrame(binding);
|
|
124
|
-
const
|
|
148
|
+
const tokenDisplayName = frame.tokenName;
|
|
125
149
|
const pathWithSet = resolutionPath;
|
|
126
150
|
let resolutionSet = pathWithSet[RESOLUTION_SET_KEY];
|
|
127
151
|
if (resolutionSet === void 0 && resolutionPath.length >= RESOLUTION_SET_THRESHOLD) {
|
|
128
152
|
resolutionSet = new Set(resolutionPath);
|
|
129
153
|
pathWithSet[RESOLUTION_SET_KEY] = resolutionSet;
|
|
130
154
|
}
|
|
131
|
-
if (resolutionSet !== void 0 ? resolutionSet.has(
|
|
132
|
-
resolutionPath.push(
|
|
133
|
-
resolutionSet?.add(
|
|
155
|
+
if (resolutionSet !== void 0 ? resolutionSet.has(tokenDisplayName) : resolutionPath.includes(tokenDisplayName)) throw new CircularDependencyError([...resolutionPath, tokenDisplayName]);
|
|
156
|
+
resolutionPath.push(tokenDisplayName);
|
|
157
|
+
resolutionSet?.add(tokenDisplayName);
|
|
134
158
|
materializationStack.push(frame);
|
|
135
159
|
const needsActivation = this._needsActivation(binding);
|
|
136
160
|
if (!needsActivation && scope === "transient" && binding.kind === "dynamic") {
|
|
@@ -140,18 +164,18 @@ var DependencyResolver = class {
|
|
|
140
164
|
if (dynamicResult instanceof Promise) throw new AsyncResolutionError(tokenName(binding.token), tokenName(binding.token));
|
|
141
165
|
materializationStack.pop();
|
|
142
166
|
resolutionPath.pop();
|
|
143
|
-
resolutionSet?.delete(
|
|
167
|
+
resolutionSet?.delete(tokenDisplayName);
|
|
144
168
|
return dynamicResult;
|
|
145
169
|
} catch (error) {
|
|
146
170
|
materializationStack.pop();
|
|
147
171
|
resolutionPath.pop();
|
|
148
|
-
resolutionSet?.delete(
|
|
172
|
+
resolutionSet?.delete(tokenDisplayName);
|
|
149
173
|
throw error;
|
|
150
174
|
}
|
|
151
175
|
}
|
|
152
176
|
try {
|
|
153
177
|
const resolutionCtx = needsActivation || this._requiresResolutionContext(binding) ? this._acquireSyncResolutionContext(resolutionPath, materializationStack, hint) : void 0;
|
|
154
|
-
const instance = this._instantiateSync(binding, resolutionCtx, resolutionPath, materializationStack
|
|
178
|
+
const instance = this._instantiateSync(binding, resolutionCtx, resolutionPath, materializationStack);
|
|
155
179
|
let shouldActivate = needsActivation;
|
|
156
180
|
if (binding.kind === "class" && this._classHasPostConstruct.get(binding.target) === void 0) {
|
|
157
181
|
this._refreshClassPostConstructCache(binding.target);
|
|
@@ -165,17 +189,17 @@ var DependencyResolver = class {
|
|
|
165
189
|
} finally {
|
|
166
190
|
materializationStack.pop();
|
|
167
191
|
resolutionPath.pop();
|
|
168
|
-
resolutionSet?.delete(
|
|
192
|
+
resolutionSet?.delete(tokenDisplayName);
|
|
169
193
|
}
|
|
170
194
|
}
|
|
171
|
-
_instantiateSync(binding, ctx, resolutionPath, materializationStack
|
|
195
|
+
_instantiateSync(binding, ctx, resolutionPath, materializationStack) {
|
|
172
196
|
switch (binding.kind) {
|
|
173
197
|
case "constant": return binding.value;
|
|
174
198
|
case "dynamic": {
|
|
175
199
|
if (ctx === void 0) throw new InternalError("dynamic binding requires resolution context");
|
|
176
|
-
const
|
|
177
|
-
if (
|
|
178
|
-
return
|
|
200
|
+
const factoryResult = binding.factory(ctx);
|
|
201
|
+
if (factoryResult instanceof Promise) throw new AsyncResolutionError(tokenName(binding.token), tokenName(binding.token));
|
|
202
|
+
return factoryResult;
|
|
179
203
|
}
|
|
180
204
|
case "dynamic-async": throw new AsyncResolutionError(tokenName(binding.token), tokenName(binding.token));
|
|
181
205
|
case "class": {
|
|
@@ -183,7 +207,7 @@ var DependencyResolver = class {
|
|
|
183
207
|
return this._instantiateClass(binding.target, deps);
|
|
184
208
|
}
|
|
185
209
|
case "resolved": {
|
|
186
|
-
const deps = this._resolveDescriptorDeps(binding.deps, resolutionPath, materializationStack
|
|
210
|
+
const deps = this._resolveDescriptorDeps(binding.deps, resolutionPath, materializationStack);
|
|
187
211
|
const r = binding.factory(...deps);
|
|
188
212
|
if (r instanceof Promise) throw new AsyncResolutionError(tokenName(binding.token), tokenName(binding.token));
|
|
189
213
|
return r;
|
|
@@ -223,7 +247,7 @@ var DependencyResolver = class {
|
|
|
223
247
|
}
|
|
224
248
|
return deps;
|
|
225
249
|
}
|
|
226
|
-
_resolveDescriptorDeps(deps, resolutionPath, materializationStack
|
|
250
|
+
_resolveDescriptorDeps(deps, resolutionPath, materializationStack) {
|
|
227
251
|
const resolved = new Array(deps.length);
|
|
228
252
|
for (let index = 0; index < deps.length; index += 1) {
|
|
229
253
|
const dep = deps[index];
|
|
@@ -326,7 +350,7 @@ var DependencyResolver = class {
|
|
|
326
350
|
try {
|
|
327
351
|
if (scope === "singleton") {
|
|
328
352
|
const createSingletonPromise = async () => {
|
|
329
|
-
const instance = await this._instantiateAsync(binding, resolutionCtx, resolutionPath, materializationStack
|
|
353
|
+
const instance = await this._instantiateAsync(binding, resolutionCtx, resolutionPath, materializationStack);
|
|
330
354
|
let shouldActivate = needsActivation;
|
|
331
355
|
if (binding.kind === "class" && this._classHasPostConstruct.get(binding.target) === void 0) {
|
|
332
356
|
this._refreshClassPostConstructCache(binding.target);
|
|
@@ -338,14 +362,14 @@ var DependencyResolver = class {
|
|
|
338
362
|
this._scope.clearInflight(binding.id);
|
|
339
363
|
return activated;
|
|
340
364
|
};
|
|
341
|
-
const
|
|
365
|
+
const singletonPromise = createSingletonPromise().catch((err) => {
|
|
342
366
|
this._scope.clearInflight(binding.id);
|
|
343
367
|
throw err;
|
|
344
368
|
});
|
|
345
|
-
this._scope.setInflight(binding.id,
|
|
346
|
-
return await
|
|
369
|
+
this._scope.setInflight(binding.id, singletonPromise);
|
|
370
|
+
return await singletonPromise;
|
|
347
371
|
}
|
|
348
|
-
const instance = await this._instantiateAsync(binding, resolutionCtx, resolutionPath, materializationStack
|
|
372
|
+
const instance = await this._instantiateAsync(binding, resolutionCtx, resolutionPath, materializationStack);
|
|
349
373
|
let shouldActivate = needsActivation;
|
|
350
374
|
if (binding.kind === "class" && this._classHasPostConstruct.get(binding.target) === void 0) {
|
|
351
375
|
this._refreshClassPostConstructCache(binding.target);
|
|
@@ -361,7 +385,7 @@ var DependencyResolver = class {
|
|
|
361
385
|
resolutionSet?.delete(tName);
|
|
362
386
|
}
|
|
363
387
|
}
|
|
364
|
-
async _instantiateAsync(binding, ctx, resolutionPath, materializationStack
|
|
388
|
+
async _instantiateAsync(binding, ctx, resolutionPath, materializationStack) {
|
|
365
389
|
switch (binding.kind) {
|
|
366
390
|
case "constant": return binding.value;
|
|
367
391
|
case "dynamic": {
|
|
@@ -378,12 +402,12 @@ var DependencyResolver = class {
|
|
|
378
402
|
}
|
|
379
403
|
case "resolved": {
|
|
380
404
|
if (ctx === void 0) throw new InternalError("resolved binding requires resolution context");
|
|
381
|
-
const deps = await this._resolveDescriptorDepsAsync(binding.deps, resolutionPath, materializationStack
|
|
405
|
+
const deps = await this._resolveDescriptorDepsAsync(binding.deps, resolutionPath, materializationStack);
|
|
382
406
|
const r = binding.factory(...deps);
|
|
383
407
|
return r instanceof Promise ? r : Promise.resolve(r);
|
|
384
408
|
}
|
|
385
409
|
case "resolved-async": {
|
|
386
|
-
const deps = await this._resolveDescriptorDepsAsync(binding.deps, resolutionPath, materializationStack
|
|
410
|
+
const deps = await this._resolveDescriptorDepsAsync(binding.deps, resolutionPath, materializationStack);
|
|
387
411
|
return binding.factory(...deps);
|
|
388
412
|
}
|
|
389
413
|
case "alias": throw new InternalError("alias should have been followed before instantiation");
|
|
@@ -415,7 +439,7 @@ var DependencyResolver = class {
|
|
|
415
439
|
}
|
|
416
440
|
return Promise.all(pending);
|
|
417
441
|
}
|
|
418
|
-
async _resolveDescriptorDepsAsync(deps, resolutionPath, materializationStack
|
|
442
|
+
async _resolveDescriptorDepsAsync(deps, resolutionPath, materializationStack) {
|
|
419
443
|
const pending = new Array(deps.length);
|
|
420
444
|
const shouldCloneContext = deps.length > 1;
|
|
421
445
|
for (let index = 0; index < deps.length; index += 1) {
|
|
@@ -536,14 +560,14 @@ var DependencyResolver = class {
|
|
|
536
560
|
_resolveTransientDynamicSyncFromContext(binding, resolutionPath, materializationStack) {
|
|
537
561
|
if (resolutionPath.length < RESOLUTION_SET_THRESHOLD) {
|
|
538
562
|
const frame = this._getMaterializationFrame(binding);
|
|
539
|
-
const
|
|
540
|
-
if (resolutionPath.includes(
|
|
541
|
-
resolutionPath.push(
|
|
563
|
+
const tokenDisplayName = frame.tokenName;
|
|
564
|
+
if (resolutionPath.includes(tokenDisplayName)) throw new CircularDependencyError([...resolutionPath, tokenDisplayName]);
|
|
565
|
+
resolutionPath.push(tokenDisplayName);
|
|
542
566
|
materializationStack.push(frame);
|
|
543
567
|
const resolutionCtx = this._acquireSyncResolutionContext(resolutionPath, materializationStack, void 0);
|
|
544
568
|
try {
|
|
545
569
|
const dynamicResult = binding.factory(resolutionCtx);
|
|
546
|
-
if (dynamicResult instanceof Promise) throw new AsyncResolutionError(
|
|
570
|
+
if (dynamicResult instanceof Promise) throw new AsyncResolutionError(tokenDisplayName, tokenDisplayName);
|
|
547
571
|
return dynamicResult;
|
|
548
572
|
} finally {
|
|
549
573
|
materializationStack.pop();
|
|
@@ -574,33 +598,33 @@ var DependencyResolver = class {
|
|
|
574
598
|
}
|
|
575
599
|
_resolveTransientDynamicSyncSlow(binding, resolutionPath, materializationStack) {
|
|
576
600
|
const frame = this._getMaterializationFrame(binding);
|
|
577
|
-
const
|
|
601
|
+
const tokenDisplayName = frame.tokenName;
|
|
578
602
|
const pathWithSet = resolutionPath;
|
|
579
603
|
let resolutionSet = pathWithSet[RESOLUTION_SET_KEY];
|
|
580
604
|
if (resolutionSet === void 0) {
|
|
581
605
|
resolutionSet = new Set(resolutionPath);
|
|
582
606
|
pathWithSet[RESOLUTION_SET_KEY] = resolutionSet;
|
|
583
607
|
}
|
|
584
|
-
if (resolutionSet.has(
|
|
585
|
-
resolutionPath.push(
|
|
586
|
-
resolutionSet.add(
|
|
608
|
+
if (resolutionSet.has(tokenDisplayName)) throw new CircularDependencyError([...resolutionPath, tokenDisplayName]);
|
|
609
|
+
resolutionPath.push(tokenDisplayName);
|
|
610
|
+
resolutionSet.add(tokenDisplayName);
|
|
587
611
|
materializationStack.push(frame);
|
|
588
612
|
const resolutionCtx = this._acquireSyncResolutionContext(resolutionPath, materializationStack, void 0);
|
|
589
613
|
try {
|
|
590
614
|
const dynamicResult = binding.factory(resolutionCtx);
|
|
591
|
-
if (dynamicResult instanceof Promise) throw new AsyncResolutionError(
|
|
615
|
+
if (dynamicResult instanceof Promise) throw new AsyncResolutionError(tokenDisplayName, tokenDisplayName);
|
|
592
616
|
return dynamicResult;
|
|
593
617
|
} finally {
|
|
594
618
|
materializationStack.pop();
|
|
595
619
|
resolutionPath.pop();
|
|
596
|
-
resolutionSet.delete(
|
|
620
|
+
resolutionSet.delete(tokenDisplayName);
|
|
597
621
|
}
|
|
598
622
|
}
|
|
599
623
|
_resolveTransientDynamicAsyncFromContext(binding, resolutionPath, materializationStack) {
|
|
600
624
|
if (resolutionPath.length < RESOLUTION_SET_THRESHOLD) {
|
|
601
|
-
const
|
|
602
|
-
if (resolutionPath.includes(
|
|
603
|
-
resolutionPath.push(
|
|
625
|
+
const tokenDisplayName = tokenName(binding.token);
|
|
626
|
+
if (resolutionPath.includes(tokenDisplayName)) return Promise.reject(new CircularDependencyError([...resolutionPath, tokenDisplayName]));
|
|
627
|
+
resolutionPath.push(tokenDisplayName);
|
|
604
628
|
let ctx;
|
|
605
629
|
let isOwnerLevel;
|
|
606
630
|
if (this._deepAsyncCtxPath === resolutionPath) {
|
|
@@ -626,8 +650,8 @@ var DependencyResolver = class {
|
|
|
626
650
|
try {
|
|
627
651
|
if (binding.kind === "dynamic-async") factoryPromise = binding.factory(ctx);
|
|
628
652
|
else {
|
|
629
|
-
const
|
|
630
|
-
factoryPromise =
|
|
653
|
+
const factoryResult = binding.factory(ctx);
|
|
654
|
+
factoryPromise = factoryResult instanceof Promise ? factoryResult : Promise.resolve(factoryResult);
|
|
631
655
|
}
|
|
632
656
|
} catch (err) {
|
|
633
657
|
resolutionPath.pop();
|
|
@@ -648,16 +672,16 @@ var DependencyResolver = class {
|
|
|
648
672
|
}
|
|
649
673
|
async _resolveTransientDynamicAsyncSlow(binding, resolutionPath, materializationStack) {
|
|
650
674
|
const frame = this._getMaterializationFrame(binding);
|
|
651
|
-
const
|
|
675
|
+
const tokenDisplayName = frame.tokenName;
|
|
652
676
|
const pathWithSet = resolutionPath;
|
|
653
677
|
let resolutionSet = pathWithSet[RESOLUTION_SET_KEY];
|
|
654
678
|
if (resolutionSet === void 0) {
|
|
655
679
|
resolutionSet = new Set(resolutionPath);
|
|
656
680
|
pathWithSet[RESOLUTION_SET_KEY] = resolutionSet;
|
|
657
681
|
}
|
|
658
|
-
if (resolutionSet.has(
|
|
659
|
-
resolutionPath.push(
|
|
660
|
-
resolutionSet.add(
|
|
682
|
+
if (resolutionSet.has(tokenDisplayName)) throw new CircularDependencyError([...resolutionPath, tokenDisplayName]);
|
|
683
|
+
resolutionPath.push(tokenDisplayName);
|
|
684
|
+
resolutionSet.add(tokenDisplayName);
|
|
661
685
|
materializationStack.push(frame);
|
|
662
686
|
const resolutionCtx = new DefaultResolutionContext(this, resolutionPath, materializationStack, void 0);
|
|
663
687
|
try {
|
|
@@ -667,7 +691,7 @@ var DependencyResolver = class {
|
|
|
667
691
|
} finally {
|
|
668
692
|
materializationStack.pop();
|
|
669
693
|
resolutionPath.pop();
|
|
670
|
-
resolutionSet.delete(
|
|
694
|
+
resolutionSet.delete(tokenDisplayName);
|
|
671
695
|
}
|
|
672
696
|
}
|
|
673
697
|
_resolveCandidateSync(binding, hint, resolutionPath, materializationStack) {
|
package/dist/scope.d.mts
CHANGED
package/dist/scope.mjs
CHANGED
package/dist/token.d.mts
CHANGED
|
@@ -2,12 +2,24 @@ import { Constructor } from "./constructor-type.mjs";
|
|
|
2
2
|
|
|
3
3
|
//#region src/token.d.ts
|
|
4
4
|
declare const TOKEN_BRAND: unique symbol;
|
|
5
|
+
/**
|
|
6
|
+
* @since 0.3.16-canary.0
|
|
7
|
+
*/
|
|
5
8
|
interface Token<Value> {
|
|
6
9
|
readonly name: string;
|
|
7
10
|
readonly [TOKEN_BRAND]: Value;
|
|
8
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* @since 0.3.16-canary.0
|
|
14
|
+
*/
|
|
9
15
|
declare function token<Value>(name: string): Token<Value>;
|
|
16
|
+
/**
|
|
17
|
+
* @since 0.3.16-canary.0
|
|
18
|
+
*/
|
|
10
19
|
declare function tokenName(t: Token<unknown> | Constructor): string;
|
|
20
|
+
/**
|
|
21
|
+
* @since 0.3.16-canary.0
|
|
22
|
+
*/
|
|
11
23
|
declare function isToken(value: unknown): value is Token<unknown>;
|
|
12
24
|
//#endregion
|
|
13
25
|
export { Token, isToken, token, tokenName };
|
package/dist/token.mjs
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
//#region src/token.ts
|
|
2
|
+
/**
|
|
3
|
+
* @since 0.3.16-canary.0
|
|
4
|
+
*/
|
|
2
5
|
function token(name) {
|
|
3
6
|
return { name };
|
|
4
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* @since 0.3.16-canary.0
|
|
10
|
+
*/
|
|
5
11
|
function tokenName(t) {
|
|
6
12
|
if (typeof t === "function") return t.name;
|
|
7
13
|
return t.name;
|
|
8
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* @since 0.3.16-canary.0
|
|
17
|
+
*/
|
|
9
18
|
function isToken(value) {
|
|
10
19
|
return typeof value === "object" && value !== null && "name" in value && typeof value["name"] === "string" && typeof value !== "function";
|
|
11
20
|
}
|