@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.
Files changed (45) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +8 -5
  3. package/dist/binding-select.d.mts +2 -2
  4. package/dist/binding-select.mjs +5 -5
  5. package/dist/binding.d.mts +12 -12
  6. package/dist/binding.mjs +8 -8
  7. package/dist/constraints.d.mts +25 -9
  8. package/dist/constraints.mjs +47 -19
  9. package/dist/constructor-type.d.mts +2 -2
  10. package/dist/container.d.mts +6 -6
  11. package/dist/container.mjs +202 -121
  12. package/dist/decorators/inject.d.mts +4 -4
  13. package/dist/decorators/inject.mjs +21 -19
  14. package/dist/decorators/injectable.d.mts +1 -1
  15. package/dist/decorators/injectable.mjs +18 -14
  16. package/dist/decorators/lifecycle-decorators.mjs +3 -0
  17. package/dist/dependency-graph.d.mts +2 -2
  18. package/dist/dependency-graph.mjs +13 -13
  19. package/dist/environment.d.mts +17 -17
  20. package/dist/environment.mjs +21 -21
  21. package/dist/errors.d.mts +18 -8
  22. package/dist/errors.mjs +17 -1
  23. package/dist/graph-adapters/reactflow.d.mts +2 -2
  24. package/dist/index.d.mts +6 -5
  25. package/dist/index.mjs +5 -4
  26. package/dist/inspector.d.mts +2 -3
  27. package/dist/inspector.mjs +18 -16
  28. package/dist/lifecycle.d.mts +5 -6
  29. package/dist/lifecycle.mjs +45 -52
  30. package/dist/metadata/metadata-keys.d.mts +24 -1
  31. package/dist/metadata/metadata-keys.mjs +14 -1
  32. package/dist/metadata/metadata-types.d.mts +5 -5
  33. package/dist/metadata/symbol-metadata-reader.mjs +31 -24
  34. package/dist/module.d.mts +2 -2
  35. package/dist/module.mjs +2 -2
  36. package/dist/registry.d.mts +6 -6
  37. package/dist/registry.mjs +55 -62
  38. package/dist/resolve-options.d.mts +5 -5
  39. package/dist/resolve-options.mjs +8 -8
  40. package/dist/resolver.d.mts +22 -10
  41. package/dist/resolver.mjs +206 -185
  42. package/dist/token.d.mts +1 -1
  43. package/dist/token.mjs +4 -4
  44. package/dist/types.d.mts +12 -8
  45. 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 materialization. |
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((repo, cfg) => new UserService(repo, cfg), [UserRepository, AppConfigToken] as const);
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 materialization stack was registered for `key`. |
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`, `buildMaterializationFrame` |
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` | `injectableSlotToResolveOptions`, `slotKeyToResolveOptions` |
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: readonly Binding[], hint: ResolveOptions | undefined, ctx: ConstraintContext, tName: string): Binding | undefined;
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: readonly Binding[], hint: ResolveOptions | undefined, ctx: ConstraintContext): Binding[];
17
+ declare function selectAllBindings(bindings: ReadonlyArray<Binding>, hint: ResolveOptions | undefined, ctx: ConstraintContext): Array<Binding>;
18
18
  //#endregion
19
19
  export { selectAllBindings, selectBinding };
@@ -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, tName) {
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(tName, candidates.map((c) => c.id));
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, mode = "single") {
23
+ function filterBindings(bindings, hint, ctx, selectionMode = "single") {
24
24
  if (hint === void 0) {
25
25
  const resultWithoutHint = [];
26
- if (mode === "all") {
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 ((mode === "all" ? matchesSlotForResolveAll(binding, hint) : matchesSlot(binding, hint)) && matchesPredicate(binding, ctx)) result.push(binding);
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) {
@@ -7,26 +7,26 @@ import { InjectionDescriptor } from "./decorators/inject.mjs";
7
7
  /**
8
8
  * @since 0.3.16-canary.0
9
9
  */
10
- interface SlotKey {
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 slotKeyEquals(a: SlotKey, b: SlotKey): boolean;
17
+ declare function bindingSlotEquals(left: BindingSlot, right: BindingSlot): boolean;
18
18
  /**
19
19
  * @since 0.3.16-canary.0
20
20
  */
21
- declare const DEFAULT_SLOT: SlotKey;
21
+ declare const DEFAULT_BINDING_SLOT: BindingSlot;
22
22
  /**
23
23
  * @since 0.3.16-canary.0
24
24
  */
25
- declare function slotKeyToString(slot: SlotKey): string;
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: SlotKey;
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[]) => Value;
68
- readonly deps: readonly InjectionDescriptor[];
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[]) => Promise<Value>;
79
- readonly deps: readonly InjectionDescriptor[];
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 readonly DependencyKey[]>(factory: (...args: { [K in keyof Deps]: TokenValue<NoInfer<Deps>[K]> }) => Value, deps: Deps): BindingBuilder<Value>;
125
- toResolvedAsync<const Deps extends readonly DependencyKey[]>(factory: (...args: { [K in keyof Deps]: TokenValue<NoInfer<Deps>[K]> }) => Promise<Value>, deps: Deps): BindingBuilder<Value>;
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, DEFAULT_SLOT, DynamicAsyncBinding, DynamicBinding, PartialBinding, ResolvedAsyncBinding, ResolvedBinding, ScopedBindingBuilder, SingletonBindingBuilder, SingletonLifecycleBuilder, SlotKey, TransientBindingBuilder, generateBindingId, slotKeyEquals, slotKeyToString };
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 slotKeyEquals(a, b) {
6
- if (a.name !== b.name) return false;
7
- if (a.tags.length !== b.tags.length) return false;
8
- for (const [tagKey, tagValue] of a.tags) if (!b.tags.some(([k, v]) => k === tagKey && Object.is(v, tagValue))) return false;
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 DEFAULT_SLOT = {
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 slotKeyToString(slot) {
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 [k, v] of slot.tags) parts.push(`tag:${k}=${String(v)}`);
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 { DEFAULT_SLOT, generateBindingId, slotKeyEquals, slotKeyToString };
36
+ export { DEFAULT_BINDING_SLOT, bindingSlotEquals, bindingSlotToString, generateBindingId };
@@ -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(t: Token<unknown> | Constructor): (ctx: ConstraintContext) => boolean;
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(t: Token<unknown> | Constructor): (ctx: ConstraintContext) => boolean;
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(t: Token<unknown> | Constructor): (ctx: ConstraintContext) => boolean;
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(t: Token<unknown> | Constructor): (ctx: ConstraintContext) => boolean;
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): (ctx: ConstraintContext) => boolean;
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): (ctx: ConstraintContext) => boolean;
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): (ctx: ConstraintContext) => boolean;
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): (ctx: ConstraintContext) => boolean;
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 };
@@ -1,59 +1,87 @@
1
1
  import { tokenName } from "./token.mjs";
2
2
  //#region src/constraints.ts
3
- function tokenNameOf(t) {
4
- return tokenName(t);
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(t) {
10
- const name = tokenNameOf(t);
11
- return (ctx) => ctx.parent !== void 0 && ctx.parent.tokenName === name;
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(t) {
17
- const name = tokenNameOf(t);
18
- return (ctx) => ctx.parent === void 0 || ctx.parent.tokenName !== name;
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(t) {
24
- const name = tokenNameOf(t);
25
- return (ctx) => ctx.ancestors.some((f) => f.tokenName === name);
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(t) {
31
- const name = tokenNameOf(t);
32
- return (ctx) => ctx.ancestors.every((f) => f.tokenName !== name);
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 (ctx) => ctx.parent !== void 0 && ctx.parent.slot.name === name;
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 (ctx) => ctx.ancestors.some((f) => f.slot.name === name);
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 (ctx) => ctx.parent !== void 0 && ctx.parent.slot.tags.some(([t, v]) => t === tag && Object.is(v, value));
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 (ctx) => ctx.ancestors.some((f) => f.slot.tags.some(([t, v]) => t === tag && Object.is(v, value)));
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[]) => Value;
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[]) => unknown;
19
+ type ConstructorInvocation = new (...args: Array<unknown>) => unknown;
20
20
  //#endregion
21
21
  export { Constructor, ConstructorInvocation };
@@ -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[]): void;
22
+ load(...modules: Array<SyncModule>): void;
23
23
  loadAsync(...modules: Array<SyncModule | AsyncModule>): Promise<void>;
24
- unload(...modules: SyncModule[]): void;
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>): readonly BindingSnapshot[];
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[]): Container;
52
+ fromModules(...modules: Array<SyncModule>): Container;
53
53
  fromModulesAsync(...modules: Array<SyncModule | AsyncModule>): Promise<Container>;
54
54
  }
55
55
  /**