@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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @codefast/di
|
|
2
2
|
|
|
3
|
+
## 0.3.16-canary.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`1ad2cb7`](https://github.com/codefastlabs/codefast/commit/1ad2cb73a3f6f8bff2b001e9df2f2492efd89aa2) Thanks [@thevuong](https://github.com/thevuong)! - chore: align package config globs
|
|
8
|
+
|
|
9
|
+
- [`4fda78b`](https://github.com/codefastlabs/codefast/commit/4fda78b20f98646d114cfddb09e66af609a625a2) Thanks [@thevuong](https://github.com/thevuong)! - fix: support Node 26 mirror export verification
|
|
10
|
+
|
|
11
|
+
- [`1b0df2e`](https://github.com/codefastlabs/codefast/commit/1b0df2e55140c927b7f3ba39ccdcb4cba87ec7ff) Thanks [@thevuong](https://github.com/thevuong)! - refactor(di): clarify contextual names
|
|
12
|
+
|
|
13
|
+
## 0.3.16-canary.1
|
|
14
|
+
|
|
3
15
|
## 0.3.16-canary.0
|
|
4
16
|
|
|
5
17
|
## 0.3.15
|
package/README.md
CHANGED
|
@@ -181,7 +181,7 @@ Start with `container.bind(key)` and chain a strategy, then optional constraints
|
|
|
181
181
|
| `.toDynamicAsync(factory)` | Async factory `(ctx: ResolutionContext) => Promise<Value>`. |
|
|
182
182
|
| `.toResolved(factory, deps)` | Factory with a typed dependency tuple; dependencies are resolved in order. |
|
|
183
183
|
| `.toResolvedAsync(factory, deps)` | Like `toResolved`, but the factory returns a `Promise`. |
|
|
184
|
-
| `.toAlias(targetToken)` | Redirect resolution to another token; the alias follows the target’s
|
|
184
|
+
| `.toAlias(targetToken)` | Redirect resolution to another token; the alias follows the target’s resolution. |
|
|
185
185
|
|
|
186
186
|
```typescript
|
|
187
187
|
container.bind(AppConfigToken).toConstantValue({ port: 3000 });
|
|
@@ -203,7 +203,10 @@ container.bind(DbToken).toDynamicAsync(async (ctx) => {
|
|
|
203
203
|
|
|
204
204
|
container
|
|
205
205
|
.bind(UserServiceToken)
|
|
206
|
-
.toResolved((
|
|
206
|
+
.toResolved((repository, config) => new UserService(repository, config), [
|
|
207
|
+
UserRepository,
|
|
208
|
+
AppConfigToken,
|
|
209
|
+
] as const);
|
|
207
210
|
|
|
208
211
|
container
|
|
209
212
|
.bind(MetricsToken)
|
|
@@ -268,7 +271,7 @@ Built-in predicates (all from `@codefast/di/constraints`):
|
|
|
268
271
|
| ----------------------------------- | -------------------------------------------------------------------------- |
|
|
269
272
|
| `whenParentIs(key)` | The direct parent binding was registered for `key`. |
|
|
270
273
|
| `whenNoParentIs(key)` | There is no parent, or the parent is not registered for `key`. |
|
|
271
|
-
| `whenAnyAncestorIs(key)` | Any ancestor on the
|
|
274
|
+
| `whenAnyAncestorIs(key)` | Any ancestor on the resolution stack was registered for `key`. |
|
|
272
275
|
| `whenNoAncestorIs(key)` | No ancestor was registered for `key`. |
|
|
273
276
|
| `whenParentNamed(name)` | The immediate parent binding’s slot name is `name`. |
|
|
274
277
|
| `whenAnyAncestorNamed(name)` | Some ancestor’s slot name is `name`. |
|
|
@@ -642,7 +645,7 @@ The root entry re-exports the full façade (`package.json` → `"."`). Subpaths
|
|
|
642
645
|
| `@codefast/di/decorators/injectable` | `injectable`, `createAutoRegisterRegistry`, `AutoRegisterRegistry` |
|
|
643
646
|
| `@codefast/di/decorators/lifecycle-decorators` | `postConstruct`, `preDestroy` |
|
|
644
647
|
| `@codefast/di/dependency-graph` | `buildDependencyGraph`, `ContainerGraphJson`, `GraphOptions`, … |
|
|
645
|
-
| `@codefast/di/environment` | `runWithContainer`, `getActiveContainer`, `DefaultResolutionContext`, `ResolverCallbacks`, `
|
|
648
|
+
| `@codefast/di/environment` | `runWithContainer`, `getActiveContainer`, `DefaultResolutionContext`, `ResolverCallbacks`, `buildResolutionFrame` |
|
|
646
649
|
| `@codefast/di/errors` | Full `DiError` hierarchy |
|
|
647
650
|
| `@codefast/di/graph-adapters/cytoscape` | `toCytoscapeGraph` |
|
|
648
651
|
| `@codefast/di/graph-adapters/dot` | `toDotGraph` |
|
|
@@ -656,7 +659,7 @@ The root entry re-exports the full façade (`package.json` → `"."`). Subpaths
|
|
|
656
659
|
| `@codefast/di/metadata/symbol-metadata-reader` | `SymbolMetadataReader`, `defaultMetadataReader` |
|
|
657
660
|
| `@codefast/di/module` | `Module`, `AsyncModule`, `SyncModule`, `isSyncModule`, builders |
|
|
658
661
|
| `@codefast/di/registry` | `BindingRegistry` |
|
|
659
|
-
| `@codefast/di/resolve-options` | `
|
|
662
|
+
| `@codefast/di/resolve-options` | `injectionSlotToResolveOptions`, `bindingSlotToResolveOptions` |
|
|
660
663
|
| `@codefast/di/resolver` | `DependencyResolver` |
|
|
661
664
|
| `@codefast/di/scope` | `ScopeManager` |
|
|
662
665
|
| `@codefast/di/token` | `token`, `Token`, `tokenName`, … |
|
|
@@ -8,12 +8,12 @@ import { Binding } from "./binding.mjs";
|
|
|
8
8
|
*
|
|
9
9
|
* @since 0.3.16-canary.0
|
|
10
10
|
*/
|
|
11
|
-
declare function selectBinding(bindings:
|
|
11
|
+
declare function selectBinding(bindings: ReadonlyArray<Binding>, hint: ResolveOptions | undefined, ctx: ConstraintContext, tokenDisplayName: string): Binding | undefined;
|
|
12
12
|
/**
|
|
13
13
|
* Select all candidates matching hint + predicates.
|
|
14
14
|
*
|
|
15
15
|
* @since 0.3.16-canary.0
|
|
16
16
|
*/
|
|
17
|
-
declare function selectAllBindings(bindings:
|
|
17
|
+
declare function selectAllBindings(bindings: ReadonlyArray<Binding>, hint: ResolveOptions | undefined, ctx: ConstraintContext): Array<Binding>;
|
|
18
18
|
//#endregion
|
|
19
19
|
export { selectAllBindings, selectBinding };
|
package/dist/binding-select.mjs
CHANGED
|
@@ -6,11 +6,11 @@ import { AmbiguousBindingError } from "./errors.mjs";
|
|
|
6
6
|
*
|
|
7
7
|
* @since 0.3.16-canary.0
|
|
8
8
|
*/
|
|
9
|
-
function selectBinding(bindings, hint, ctx,
|
|
9
|
+
function selectBinding(bindings, hint, ctx, tokenDisplayName) {
|
|
10
10
|
const candidates = filterBindings(bindings, hint, ctx);
|
|
11
11
|
if (candidates.length === 0) return;
|
|
12
12
|
if (candidates.length === 1) return candidates[0];
|
|
13
|
-
throw new AmbiguousBindingError(
|
|
13
|
+
throw new AmbiguousBindingError(tokenDisplayName, candidates.map((c) => c.id));
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* Select all candidates matching hint + predicates.
|
|
@@ -20,10 +20,10 @@ function selectBinding(bindings, hint, ctx, tName) {
|
|
|
20
20
|
function selectAllBindings(bindings, hint, ctx) {
|
|
21
21
|
return filterBindings(bindings, hint, ctx, "all");
|
|
22
22
|
}
|
|
23
|
-
function filterBindings(bindings, hint, ctx,
|
|
23
|
+
function filterBindings(bindings, hint, ctx, selectionMode = "single") {
|
|
24
24
|
if (hint === void 0) {
|
|
25
25
|
const resultWithoutHint = [];
|
|
26
|
-
if (
|
|
26
|
+
if (selectionMode === "all") {
|
|
27
27
|
for (const binding of bindings) if (matchesPredicate(binding, ctx)) resultWithoutHint.push(binding);
|
|
28
28
|
} else for (const binding of bindings) {
|
|
29
29
|
const slot = binding.slot;
|
|
@@ -32,7 +32,7 @@ function filterBindings(bindings, hint, ctx, mode = "single") {
|
|
|
32
32
|
return resultWithoutHint;
|
|
33
33
|
}
|
|
34
34
|
const result = [];
|
|
35
|
-
for (const binding of bindings) if ((
|
|
35
|
+
for (const binding of bindings) if ((selectionMode === "all" ? matchesSlotForResolveAll(binding, hint) : matchesSlot(binding, hint)) && matchesPredicate(binding, ctx)) result.push(binding);
|
|
36
36
|
return result;
|
|
37
37
|
}
|
|
38
38
|
function matchesSlotForResolveAll(binding, hint) {
|
package/dist/binding.d.mts
CHANGED
|
@@ -7,26 +7,26 @@ import { InjectionDescriptor } from "./decorators/inject.mjs";
|
|
|
7
7
|
/**
|
|
8
8
|
* @since 0.3.16-canary.0
|
|
9
9
|
*/
|
|
10
|
-
interface
|
|
10
|
+
interface BindingSlot {
|
|
11
11
|
readonly name: string | undefined;
|
|
12
12
|
readonly tags: ReadonlyArray<readonly [tag: string, value: unknown]>;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* @since 0.3.16-canary.0
|
|
16
16
|
*/
|
|
17
|
-
declare function
|
|
17
|
+
declare function bindingSlotEquals(left: BindingSlot, right: BindingSlot): boolean;
|
|
18
18
|
/**
|
|
19
19
|
* @since 0.3.16-canary.0
|
|
20
20
|
*/
|
|
21
|
-
declare const
|
|
21
|
+
declare const DEFAULT_BINDING_SLOT: BindingSlot;
|
|
22
22
|
/**
|
|
23
23
|
* @since 0.3.16-canary.0
|
|
24
24
|
*/
|
|
25
|
-
declare function
|
|
25
|
+
declare function bindingSlotToString(slot: BindingSlot): string;
|
|
26
26
|
interface BindingBase<Value> {
|
|
27
27
|
readonly id: BindingIdentifier;
|
|
28
28
|
readonly token: Token<Value> | Constructor<Value>;
|
|
29
|
-
readonly slot:
|
|
29
|
+
readonly slot: BindingSlot;
|
|
30
30
|
readonly predicate?: (ctx: ConstraintContext) => boolean;
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
@@ -64,8 +64,8 @@ interface DynamicAsyncBinding<Value> extends BindingBase<Value> {
|
|
|
64
64
|
*/
|
|
65
65
|
interface ResolvedBinding<Value> extends BindingBase<Value> {
|
|
66
66
|
readonly kind: "resolved";
|
|
67
|
-
readonly factory: (...args: unknown
|
|
68
|
-
readonly deps:
|
|
67
|
+
readonly factory: (...args: Array<unknown>) => Value;
|
|
68
|
+
readonly deps: ReadonlyArray<InjectionDescriptor>;
|
|
69
69
|
readonly scope: BindingScope;
|
|
70
70
|
readonly onActivation?: ActivationHandler<Value>;
|
|
71
71
|
readonly onDeactivation?: DeactivationHandler<Value>;
|
|
@@ -75,8 +75,8 @@ interface ResolvedBinding<Value> extends BindingBase<Value> {
|
|
|
75
75
|
*/
|
|
76
76
|
interface ResolvedAsyncBinding<Value> extends BindingBase<Value> {
|
|
77
77
|
readonly kind: "resolved-async";
|
|
78
|
-
readonly factory: (...args: unknown
|
|
79
|
-
readonly deps:
|
|
78
|
+
readonly factory: (...args: Array<unknown>) => Promise<Value>;
|
|
79
|
+
readonly deps: ReadonlyArray<InjectionDescriptor>;
|
|
80
80
|
readonly scope: BindingScope;
|
|
81
81
|
readonly onActivation?: ActivationHandler<Value>;
|
|
82
82
|
readonly onDeactivation?: DeactivationHandler<Value>;
|
|
@@ -121,8 +121,8 @@ interface BindToBuilder<Value> {
|
|
|
121
121
|
toConstantValue(value: Value): ConstantBindingBuilder<Value>;
|
|
122
122
|
toDynamic(factory: (ctx: ResolutionContext) => Value): BindingBuilder<Value>;
|
|
123
123
|
toDynamicAsync(factory: (ctx: ResolutionContext) => Promise<Value>): BindingBuilder<Value>;
|
|
124
|
-
toResolved<const Deps extends
|
|
125
|
-
toResolvedAsync<const Deps extends
|
|
124
|
+
toResolved<const Deps extends ReadonlyArray<DependencyKey>>(factory: (...args: { [K in keyof Deps]: TokenValue<NoInfer<Deps>[K]> }) => Value, deps: Deps): BindingBuilder<Value>;
|
|
125
|
+
toResolvedAsync<const Deps extends ReadonlyArray<DependencyKey>>(factory: (...args: { [K in keyof Deps]: TokenValue<NoInfer<Deps>[K]> }) => Promise<Value>, deps: Deps): BindingBuilder<Value>;
|
|
126
126
|
toAlias(target: Token<Value> | Constructor<Value>): AliasBindingBuilder;
|
|
127
127
|
}
|
|
128
128
|
/**
|
|
@@ -188,4 +188,4 @@ interface SingletonLifecycleBuilder<Value> {
|
|
|
188
188
|
id(): BindingIdentifier;
|
|
189
189
|
}
|
|
190
190
|
//#endregion
|
|
191
|
-
export { AliasBinding, AliasBindingBuilder, BindToBuilder, Binding, BindingBuilder, ClassBinding, ConstantBinding, ConstantBindingBuilder,
|
|
191
|
+
export { AliasBinding, AliasBindingBuilder, BindToBuilder, Binding, BindingBuilder, BindingSlot, ClassBinding, ConstantBinding, ConstantBindingBuilder, DEFAULT_BINDING_SLOT, DynamicAsyncBinding, DynamicBinding, PartialBinding, ResolvedAsyncBinding, ResolvedBinding, ScopedBindingBuilder, SingletonBindingBuilder, SingletonLifecycleBuilder, TransientBindingBuilder, bindingSlotEquals, bindingSlotToString, generateBindingId };
|
package/dist/binding.mjs
CHANGED
|
@@ -2,27 +2,27 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @since 0.3.16-canary.0
|
|
4
4
|
*/
|
|
5
|
-
function
|
|
6
|
-
if (
|
|
7
|
-
if (
|
|
8
|
-
for (const [tagKey, tagValue] of
|
|
5
|
+
function bindingSlotEquals(left, right) {
|
|
6
|
+
if (left.name !== right.name) return false;
|
|
7
|
+
if (left.tags.length !== right.tags.length) return false;
|
|
8
|
+
for (const [tagKey, tagValue] of left.tags) if (!right.tags.some(([otherKey, otherValue]) => otherKey === tagKey && Object.is(otherValue, tagValue))) return false;
|
|
9
9
|
return true;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* @since 0.3.16-canary.0
|
|
13
13
|
*/
|
|
14
|
-
const
|
|
14
|
+
const DEFAULT_BINDING_SLOT = {
|
|
15
15
|
name: void 0,
|
|
16
16
|
tags: []
|
|
17
17
|
};
|
|
18
18
|
/**
|
|
19
19
|
* @since 0.3.16-canary.0
|
|
20
20
|
*/
|
|
21
|
-
function
|
|
21
|
+
function bindingSlotToString(slot) {
|
|
22
22
|
if (slot.name === void 0 && slot.tags.length === 0) return "default";
|
|
23
23
|
const parts = [];
|
|
24
24
|
if (slot.name !== void 0) parts.push(`name:${slot.name}`);
|
|
25
|
-
for (const [
|
|
25
|
+
for (const [tagKey, tagValue] of slot.tags) parts.push(`tag:${tagKey}=${String(tagValue)}`);
|
|
26
26
|
return parts.join(",");
|
|
27
27
|
}
|
|
28
28
|
let _idCounter = 0;
|
|
@@ -33,4 +33,4 @@ function generateBindingId() {
|
|
|
33
33
|
return String(++_idCounter);
|
|
34
34
|
}
|
|
35
35
|
//#endregion
|
|
36
|
-
export {
|
|
36
|
+
export { DEFAULT_BINDING_SLOT, bindingSlotEquals, bindingSlotToString, generateBindingId };
|
package/dist/constraints.d.mts
CHANGED
|
@@ -6,34 +6,50 @@ import { ConstraintContext } from "./types.mjs";
|
|
|
6
6
|
/**
|
|
7
7
|
* @since 0.3.16-canary.0
|
|
8
8
|
*/
|
|
9
|
-
declare function whenParentIs(
|
|
9
|
+
declare function whenParentIs(token: Token<unknown> | Constructor): (constraintContext: ConstraintContext) => boolean;
|
|
10
10
|
/**
|
|
11
11
|
* @since 0.3.16-canary.0
|
|
12
12
|
*/
|
|
13
|
-
declare function whenNoParentIs(
|
|
13
|
+
declare function whenNoParentIs(token: Token<unknown> | Constructor): (constraintContext: ConstraintContext) => boolean;
|
|
14
14
|
/**
|
|
15
15
|
* @since 0.3.16-canary.0
|
|
16
16
|
*/
|
|
17
|
-
declare function whenAnyAncestorIs(
|
|
17
|
+
declare function whenAnyAncestorIs(token: Token<unknown> | Constructor): (constraintContext: ConstraintContext) => boolean;
|
|
18
18
|
/**
|
|
19
19
|
* @since 0.3.16-canary.0
|
|
20
20
|
*/
|
|
21
|
-
declare function whenNoAncestorIs(
|
|
21
|
+
declare function whenNoAncestorIs(token: Token<unknown> | Constructor): (constraintContext: ConstraintContext) => boolean;
|
|
22
22
|
/**
|
|
23
23
|
* @since 0.3.16-canary.0
|
|
24
24
|
*/
|
|
25
|
-
declare function whenParentNamed(name: string): (
|
|
25
|
+
declare function whenParentNamed(name: string): (constraintContext: ConstraintContext) => boolean;
|
|
26
26
|
/**
|
|
27
27
|
* @since 0.3.16-canary.0
|
|
28
28
|
*/
|
|
29
|
-
declare function whenAnyAncestorNamed(name: string): (
|
|
29
|
+
declare function whenAnyAncestorNamed(name: string): (constraintContext: ConstraintContext) => boolean;
|
|
30
30
|
/**
|
|
31
31
|
* @since 0.3.16-canary.0
|
|
32
32
|
*/
|
|
33
|
-
declare function whenParentTagged(tag: string, value: unknown): (
|
|
33
|
+
declare function whenParentTagged(tag: string, value: unknown): (constraintContext: ConstraintContext) => boolean;
|
|
34
34
|
/**
|
|
35
35
|
* @since 0.3.16-canary.0
|
|
36
36
|
*/
|
|
37
|
-
declare function whenAnyAncestorTagged(tag: string, value: unknown): (
|
|
37
|
+
declare function whenAnyAncestorTagged(tag: string, value: unknown): (constraintContext: ConstraintContext) => boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Matches when the direct parent slot carries **all** of the given tag pairs.
|
|
40
|
+
* Equivalent to AND-composing multiple `whenParentTagged` calls but evaluates
|
|
41
|
+
* in a single predicate invocation — no intermediate closure allocations.
|
|
42
|
+
*
|
|
43
|
+
* @since 0.3.16-canary.1
|
|
44
|
+
*/
|
|
45
|
+
declare function whenParentTaggedAll(tags: ReadonlyArray<readonly [tag: string, value: unknown]>): (constraintContext: ConstraintContext) => boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Matches when at least one ancestor slot carries **all** of the given tag pairs.
|
|
48
|
+
* Equivalent to AND-composing multiple `whenAnyAncestorTagged` calls but evaluates
|
|
49
|
+
* in a single predicate invocation — no intermediate closure allocations.
|
|
50
|
+
*
|
|
51
|
+
* @since 0.3.16-canary.1
|
|
52
|
+
*/
|
|
53
|
+
declare function whenAnyAncestorTaggedAll(tags: ReadonlyArray<readonly [tag: string, value: unknown]>): (constraintContext: ConstraintContext) => boolean;
|
|
38
54
|
//#endregion
|
|
39
|
-
export { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged };
|
|
55
|
+
export { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenAnyAncestorTaggedAll, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged, whenParentTaggedAll };
|
package/dist/constraints.mjs
CHANGED
|
@@ -1,59 +1,87 @@
|
|
|
1
1
|
import { tokenName } from "./token.mjs";
|
|
2
2
|
//#region src/constraints.ts
|
|
3
|
-
function tokenNameOf(
|
|
4
|
-
return tokenName(
|
|
3
|
+
function tokenNameOf(token) {
|
|
4
|
+
return tokenName(token);
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* @since 0.3.16-canary.0
|
|
8
8
|
*/
|
|
9
|
-
function whenParentIs(
|
|
10
|
-
const
|
|
11
|
-
return (
|
|
9
|
+
function whenParentIs(token) {
|
|
10
|
+
const tokenDisplayName = tokenNameOf(token);
|
|
11
|
+
return (constraintContext) => constraintContext.parent !== void 0 && constraintContext.parent.tokenName === tokenDisplayName;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* @since 0.3.16-canary.0
|
|
15
15
|
*/
|
|
16
|
-
function whenNoParentIs(
|
|
17
|
-
const
|
|
18
|
-
return (
|
|
16
|
+
function whenNoParentIs(token) {
|
|
17
|
+
const tokenDisplayName = tokenNameOf(token);
|
|
18
|
+
return (constraintContext) => constraintContext.parent === void 0 || constraintContext.parent.tokenName !== tokenDisplayName;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* @since 0.3.16-canary.0
|
|
22
22
|
*/
|
|
23
|
-
function whenAnyAncestorIs(
|
|
24
|
-
const
|
|
25
|
-
return (
|
|
23
|
+
function whenAnyAncestorIs(token) {
|
|
24
|
+
const tokenDisplayName = tokenNameOf(token);
|
|
25
|
+
return (constraintContext) => constraintContext.ancestors.some((ancestorFrame) => ancestorFrame.tokenName === tokenDisplayName);
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* @since 0.3.16-canary.0
|
|
29
29
|
*/
|
|
30
|
-
function whenNoAncestorIs(
|
|
31
|
-
const
|
|
32
|
-
return (
|
|
30
|
+
function whenNoAncestorIs(token) {
|
|
31
|
+
const tokenDisplayName = tokenNameOf(token);
|
|
32
|
+
return (constraintContext) => constraintContext.ancestors.every((ancestorFrame) => ancestorFrame.tokenName !== tokenDisplayName);
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* @since 0.3.16-canary.0
|
|
36
36
|
*/
|
|
37
37
|
function whenParentNamed(name) {
|
|
38
|
-
return (
|
|
38
|
+
return (constraintContext) => constraintContext.parent !== void 0 && constraintContext.parent.slot.name === name;
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
41
|
* @since 0.3.16-canary.0
|
|
42
42
|
*/
|
|
43
43
|
function whenAnyAncestorNamed(name) {
|
|
44
|
-
return (
|
|
44
|
+
return (constraintContext) => constraintContext.ancestors.some((ancestorFrame) => ancestorFrame.slot.name === name);
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
47
|
* @since 0.3.16-canary.0
|
|
48
48
|
*/
|
|
49
49
|
function whenParentTagged(tag, value) {
|
|
50
|
-
return (
|
|
50
|
+
return (constraintContext) => constraintContext.parent !== void 0 && constraintContext.parent.slot.tags.some(([tagKey, tagValue]) => tagKey === tag && Object.is(tagValue, value));
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
53
|
* @since 0.3.16-canary.0
|
|
54
54
|
*/
|
|
55
55
|
function whenAnyAncestorTagged(tag, value) {
|
|
56
|
-
return (
|
|
56
|
+
return (constraintContext) => constraintContext.ancestors.some((ancestorFrame) => ancestorFrame.slot.tags.some(([tagKey, tagValue]) => tagKey === tag && Object.is(tagValue, value)));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Matches when the direct parent slot carries **all** of the given tag pairs.
|
|
60
|
+
* Equivalent to AND-composing multiple `whenParentTagged` calls but evaluates
|
|
61
|
+
* in a single predicate invocation — no intermediate closure allocations.
|
|
62
|
+
*
|
|
63
|
+
* @since 0.3.16-canary.1
|
|
64
|
+
*/
|
|
65
|
+
function whenParentTaggedAll(tags) {
|
|
66
|
+
return (constraintContext) => {
|
|
67
|
+
const { parent } = constraintContext;
|
|
68
|
+
if (parent === void 0) return false;
|
|
69
|
+
const { tags: parentTags } = parent.slot;
|
|
70
|
+
return tags.every(([tagKey, tagValue]) => parentTags.some(([otherKey, otherValue]) => otherKey === tagKey && Object.is(otherValue, tagValue)));
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Matches when at least one ancestor slot carries **all** of the given tag pairs.
|
|
75
|
+
* Equivalent to AND-composing multiple `whenAnyAncestorTagged` calls but evaluates
|
|
76
|
+
* in a single predicate invocation — no intermediate closure allocations.
|
|
77
|
+
*
|
|
78
|
+
* @since 0.3.16-canary.1
|
|
79
|
+
*/
|
|
80
|
+
function whenAnyAncestorTaggedAll(tags) {
|
|
81
|
+
return (constraintContext) => constraintContext.ancestors.some((frame) => {
|
|
82
|
+
const { tags: frameTags } = frame.slot;
|
|
83
|
+
return tags.every(([tagKey, tagValue]) => frameTags.some(([otherKey, otherValue]) => otherKey === tagKey && Object.is(otherValue, tagValue)));
|
|
84
|
+
});
|
|
57
85
|
}
|
|
58
86
|
//#endregion
|
|
59
|
-
export { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged };
|
|
87
|
+
export { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenAnyAncestorTaggedAll, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged, whenParentTaggedAll };
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @since 0.3.16-canary.0
|
|
10
10
|
*/
|
|
11
|
-
type Constructor<Value = unknown> = new (...args: never
|
|
11
|
+
type Constructor<Value = unknown> = new (...args: Array<never>) => Value;
|
|
12
12
|
/**
|
|
13
13
|
* Class constructor as invoked by the resolver after metadata-driven
|
|
14
14
|
* resolution of `unknown[]` dependencies — separate from {@link Constructor},
|
|
@@ -16,6 +16,6 @@ type Constructor<Value = unknown> = new (...args: never[]) => Value;
|
|
|
16
16
|
*
|
|
17
17
|
* @since 0.3.16-canary.0
|
|
18
18
|
*/
|
|
19
|
-
type ConstructorInvocation = new (...args: unknown
|
|
19
|
+
type ConstructorInvocation = new (...args: Array<unknown>) => unknown;
|
|
20
20
|
//#endregion
|
|
21
21
|
export { Constructor, ConstructorInvocation };
|
package/dist/container.d.mts
CHANGED
|
@@ -19,9 +19,9 @@ interface Container {
|
|
|
19
19
|
unbindAll(): void;
|
|
20
20
|
unbindAllAsync(): Promise<void>;
|
|
21
21
|
rebind<const Value>(token: Token<Value> | Constructor<Value>): BindToBuilder<Value>;
|
|
22
|
-
load(...modules: SyncModule
|
|
22
|
+
load(...modules: Array<SyncModule>): void;
|
|
23
23
|
loadAsync(...modules: Array<SyncModule | AsyncModule>): Promise<void>;
|
|
24
|
-
unload(...modules: SyncModule
|
|
24
|
+
unload(...modules: Array<SyncModule>): void;
|
|
25
25
|
unloadAsync(...modules: Array<SyncModule | AsyncModule>): Promise<void>;
|
|
26
26
|
loadAutoRegistered(registry: AutoRegisterRegistry): number;
|
|
27
27
|
onActivation<const Value>(token: Token<Value> | Constructor<Value>, handler: ActivationHandler<Value>): void;
|
|
@@ -30,8 +30,8 @@ interface Container {
|
|
|
30
30
|
resolveAsync<const Value>(token: Token<Value> | Constructor<Value>, hint?: ResolveOptions): Promise<Value>;
|
|
31
31
|
resolveOptional<const Value>(token: Token<Value> | Constructor<Value>, hint?: ResolveOptions): Value | undefined;
|
|
32
32
|
resolveOptionalAsync<const Value>(token: Token<Value> | Constructor<Value>, hint?: ResolveOptions): Promise<Value | undefined>;
|
|
33
|
-
resolveAll<const Value>(token: Token<Value> | Constructor<Value>, hint?: ResolveOptions): Value
|
|
34
|
-
resolveAllAsync<const Value>(token: Token<Value> | Constructor<Value>, hint?: ResolveOptions): Promise<Value
|
|
33
|
+
resolveAll<const Value>(token: Token<Value> | Constructor<Value>, hint?: ResolveOptions): Array<Value>;
|
|
34
|
+
resolveAllAsync<const Value>(token: Token<Value> | Constructor<Value>, hint?: ResolveOptions): Promise<Array<Value>>;
|
|
35
35
|
createChild(): Container;
|
|
36
36
|
dispose(): Promise<void>;
|
|
37
37
|
[Symbol.asyncDispose](): Promise<void>;
|
|
@@ -40,7 +40,7 @@ interface Container {
|
|
|
40
40
|
validate(): void;
|
|
41
41
|
has(token: Token<unknown> | Constructor, hint?: ResolveOptions): boolean;
|
|
42
42
|
hasOwn(token: Token<unknown> | Constructor, hint?: ResolveOptions): boolean;
|
|
43
|
-
lookupBindings<const Value>(token: Token<Value> | Constructor<Value>):
|
|
43
|
+
lookupBindings<const Value>(token: Token<Value> | Constructor<Value>): ReadonlyArray<BindingSnapshot>;
|
|
44
44
|
inspect(): ContainerSnapshot;
|
|
45
45
|
generateDependencyGraph(options?: GraphOptions): ContainerGraphJson;
|
|
46
46
|
}
|
|
@@ -49,7 +49,7 @@ interface Container {
|
|
|
49
49
|
*/
|
|
50
50
|
interface ContainerStatic {
|
|
51
51
|
create(): Container;
|
|
52
|
-
fromModules(...modules: SyncModule
|
|
52
|
+
fromModules(...modules: Array<SyncModule>): Container;
|
|
53
53
|
fromModulesAsync(...modules: Array<SyncModule | AsyncModule>): Promise<Container>;
|
|
54
54
|
}
|
|
55
55
|
/**
|