@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.
Files changed (58) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +4 -1
  3. package/dist/binding-scope.d.mts +2 -0
  4. package/dist/binding-scope.mjs +2 -0
  5. package/dist/binding-select.d.mts +6 -2
  6. package/dist/binding-select.mjs +4 -0
  7. package/dist/binding.d.mts +74 -7
  8. package/dist/binding.mjs +12 -0
  9. package/dist/constraints.d.mts +49 -9
  10. package/dist/constraints.mjs +71 -19
  11. package/dist/constructor-type.d.mts +6 -2
  12. package/dist/container.d.mts +15 -6
  13. package/dist/container.mjs +139 -55
  14. package/dist/decorators/inject.d.mts +27 -3
  15. package/dist/decorators/inject.mjs +28 -11
  16. package/dist/decorators/injectable.d.mts +13 -1
  17. package/dist/decorators/injectable.mjs +24 -14
  18. package/dist/decorators/lifecycle-decorators.d.mts +6 -0
  19. package/dist/decorators/lifecycle-decorators.mjs +9 -0
  20. package/dist/dependency-graph.d.mts +17 -2
  21. package/dist/dependency-graph.mjs +3 -0
  22. package/dist/environment.d.mts +27 -12
  23. package/dist/environment.mjs +12 -0
  24. package/dist/errors.d.mts +69 -8
  25. package/dist/errors.mjs +65 -1
  26. package/dist/graph-adapters/cytoscape.d.mts +12 -0
  27. package/dist/graph-adapters/cytoscape.mjs +3 -0
  28. package/dist/graph-adapters/dot.d.mts +3 -0
  29. package/dist/graph-adapters/dot.mjs +3 -0
  30. package/dist/graph-adapters/reactflow.d.mts +14 -2
  31. package/dist/graph-adapters/reactflow.mjs +3 -0
  32. package/dist/index.d.mts +4 -3
  33. package/dist/index.mjs +4 -3
  34. package/dist/inspector.d.mts +11 -3
  35. package/dist/inspector.mjs +8 -3
  36. package/dist/lifecycle.d.mts +8 -6
  37. package/dist/lifecycle.mjs +48 -52
  38. package/dist/metadata/metadata-keys.d.mts +42 -1
  39. package/dist/metadata/metadata-keys.mjs +32 -1
  40. package/dist/metadata/metadata-reader-token.d.mts +3 -0
  41. package/dist/metadata/metadata-reader-token.mjs +3 -0
  42. package/dist/metadata/metadata-types.d.mts +22 -6
  43. package/dist/metadata/symbol-metadata-reader.d.mts +6 -0
  44. package/dist/metadata/symbol-metadata-reader.mjs +37 -24
  45. package/dist/module.d.mts +25 -1
  46. package/dist/module.mjs +12 -0
  47. package/dist/registry.d.mts +8 -5
  48. package/dist/registry.mjs +38 -42
  49. package/dist/resolve-options.d.mts +4 -0
  50. package/dist/resolve-options.mjs +4 -0
  51. package/dist/resolver.d.mts +23 -8
  52. package/dist/resolver.mjs +67 -43
  53. package/dist/scope.d.mts +3 -0
  54. package/dist/scope.mjs +3 -0
  55. package/dist/token.d.mts +12 -0
  56. package/dist/token.mjs +9 -0
  57. package/dist/types.d.mts +44 -6
  58. package/package.json +11 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # @codefast/di
2
2
 
3
+ ## 0.3.16-canary.1
4
+
5
+ ## 0.3.16-canary.0
6
+
3
7
  ## 0.3.15
4
8
 
5
9
  ### Patch Changes
package/README.md CHANGED
@@ -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)
@@ -5,6 +5,8 @@ import { Binding } from "./binding.mjs";
5
5
  /**
6
6
  * Runtime scope used for validation and introspection. Alias bindings are treated as transient
7
7
  * because they defer scope to the aliased target at resolve time.
8
+ *
9
+ * @since 0.3.16-canary.0
8
10
  */
9
11
  declare function effectiveBindingScope(binding: Binding): BindingScope;
10
12
  //#endregion
@@ -2,6 +2,8 @@
2
2
  /**
3
3
  * Runtime scope used for validation and introspection. Alias bindings are treated as transient
4
4
  * because they defer scope to the aliased target at resolve time.
5
+ *
6
+ * @since 0.3.16-canary.0
5
7
  */
6
8
  function effectiveBindingScope(binding) {
7
9
  switch (binding.kind) {
@@ -5,11 +5,15 @@ import { Binding } from "./binding.mjs";
5
5
  /**
6
6
  * Select a single candidate from a list of bindings using slot matching + predicates.
7
7
  * Returns undefined if no match, throws AmbiguousBindingError if multiple match.
8
+ *
9
+ * @since 0.3.16-canary.0
8
10
  */
9
- 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, tName: string): Binding | undefined;
10
12
  /**
11
13
  * Select all candidates matching hint + predicates.
14
+ *
15
+ * @since 0.3.16-canary.0
12
16
  */
13
- 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>;
14
18
  //#endregion
15
19
  export { selectAllBindings, selectBinding };
@@ -3,6 +3,8 @@ import { AmbiguousBindingError } from "./errors.mjs";
3
3
  /**
4
4
  * Select a single candidate from a list of bindings using slot matching + predicates.
5
5
  * Returns undefined if no match, throws AmbiguousBindingError if multiple match.
6
+ *
7
+ * @since 0.3.16-canary.0
6
8
  */
7
9
  function selectBinding(bindings, hint, ctx, tName) {
8
10
  const candidates = filterBindings(bindings, hint, ctx);
@@ -12,6 +14,8 @@ function selectBinding(bindings, hint, ctx, tName) {
12
14
  }
13
15
  /**
14
16
  * Select all candidates matching hint + predicates.
17
+ *
18
+ * @since 0.3.16-canary.0
15
19
  */
16
20
  function selectAllBindings(bindings, hint, ctx) {
17
21
  return filterBindings(bindings, hint, ctx, "all");
@@ -4,12 +4,24 @@ import { ActivationHandler, BindingIdentifier, BindingScope, ConstraintContext,
4
4
  import { InjectionDescriptor } from "./decorators/inject.mjs";
5
5
 
6
6
  //#region src/binding.d.ts
7
+ /**
8
+ * @since 0.3.16-canary.0
9
+ */
7
10
  interface SlotKey {
8
11
  readonly name: string | undefined;
9
12
  readonly tags: ReadonlyArray<readonly [tag: string, value: unknown]>;
10
13
  }
14
+ /**
15
+ * @since 0.3.16-canary.0
16
+ */
11
17
  declare function slotKeyEquals(a: SlotKey, b: SlotKey): boolean;
18
+ /**
19
+ * @since 0.3.16-canary.0
20
+ */
12
21
  declare const DEFAULT_SLOT: SlotKey;
22
+ /**
23
+ * @since 0.3.16-canary.0
24
+ */
13
25
  declare function slotKeyToString(slot: SlotKey): string;
14
26
  interface BindingBase<Value> {
15
27
  readonly id: BindingIdentifier;
@@ -17,6 +29,9 @@ interface BindingBase<Value> {
17
29
  readonly slot: SlotKey;
18
30
  readonly predicate?: (ctx: ConstraintContext) => boolean;
19
31
  }
32
+ /**
33
+ * @since 0.3.16-canary.0
34
+ */
20
35
  interface ClassBinding<Value> extends BindingBase<Value> {
21
36
  readonly kind: "class";
22
37
  readonly target: Constructor<Value>;
@@ -24,6 +39,9 @@ interface ClassBinding<Value> extends BindingBase<Value> {
24
39
  readonly onActivation?: ActivationHandler<Value>;
25
40
  readonly onDeactivation?: DeactivationHandler<Value>;
26
41
  }
42
+ /**
43
+ * @since 0.3.16-canary.0
44
+ */
27
45
  interface DynamicBinding<Value> extends BindingBase<Value> {
28
46
  readonly kind: "dynamic";
29
47
  readonly factory: (ctx: ResolutionContext) => Value;
@@ -31,6 +49,9 @@ interface DynamicBinding<Value> extends BindingBase<Value> {
31
49
  readonly onActivation?: ActivationHandler<Value>;
32
50
  readonly onDeactivation?: DeactivationHandler<Value>;
33
51
  }
52
+ /**
53
+ * @since 0.3.16-canary.0
54
+ */
34
55
  interface DynamicAsyncBinding<Value> extends BindingBase<Value> {
35
56
  readonly kind: "dynamic-async";
36
57
  readonly factory: (ctx: ResolutionContext) => Promise<Value>;
@@ -38,22 +59,31 @@ interface DynamicAsyncBinding<Value> extends BindingBase<Value> {
38
59
  readonly onActivation?: ActivationHandler<Value>;
39
60
  readonly onDeactivation?: DeactivationHandler<Value>;
40
61
  }
62
+ /**
63
+ * @since 0.3.16-canary.0
64
+ */
41
65
  interface ResolvedBinding<Value> extends BindingBase<Value> {
42
66
  readonly kind: "resolved";
43
- readonly factory: (...args: unknown[]) => Value;
44
- readonly deps: readonly InjectionDescriptor[];
67
+ readonly factory: (...args: Array<unknown>) => Value;
68
+ readonly deps: ReadonlyArray<InjectionDescriptor>;
45
69
  readonly scope: BindingScope;
46
70
  readonly onActivation?: ActivationHandler<Value>;
47
71
  readonly onDeactivation?: DeactivationHandler<Value>;
48
72
  }
73
+ /**
74
+ * @since 0.3.16-canary.0
75
+ */
49
76
  interface ResolvedAsyncBinding<Value> extends BindingBase<Value> {
50
77
  readonly kind: "resolved-async";
51
- readonly factory: (...args: unknown[]) => Promise<Value>;
52
- readonly deps: readonly InjectionDescriptor[];
78
+ readonly factory: (...args: Array<unknown>) => Promise<Value>;
79
+ readonly deps: ReadonlyArray<InjectionDescriptor>;
53
80
  readonly scope: BindingScope;
54
81
  readonly onActivation?: ActivationHandler<Value>;
55
82
  readonly onDeactivation?: DeactivationHandler<Value>;
56
83
  }
84
+ /**
85
+ * @since 0.3.16-canary.0
86
+ */
57
87
  interface ConstantBinding<Value> extends BindingBase<Value> {
58
88
  readonly kind: "constant";
59
89
  readonly value: Value;
@@ -61,24 +91,43 @@ interface ConstantBinding<Value> extends BindingBase<Value> {
61
91
  readonly onActivation?: ActivationHandler<Value>;
62
92
  readonly onDeactivation?: DeactivationHandler<Value>;
63
93
  }
94
+ /**
95
+ * @since 0.3.16-canary.0
96
+ */
64
97
  interface AliasBinding<Value> extends BindingBase<Value> {
65
98
  readonly kind: "alias";
66
99
  readonly target: Token<Value> | Constructor<Value>;
67
100
  }
101
+ /**
102
+ * @since 0.3.16-canary.0
103
+ */
68
104
  type Binding<Value = unknown> = ClassBinding<Value> | DynamicBinding<Value> | DynamicAsyncBinding<Value> | ResolvedBinding<Value> | ResolvedAsyncBinding<Value> | ConstantBinding<Value> | AliasBinding<Value>;
69
- /** Builder-only payload before `id`, `token`, `slot`, and `predicate` are applied. */
105
+ /**
106
+ * Builder-only payload before `id`, `token`, `slot`, and `predicate` are applied.
107
+ *
108
+ * @since 0.3.16-canary.0
109
+ */
70
110
  type PartialBinding<Value> = Omit<ClassBinding<Value>, "id" | "token" | "slot" | "predicate"> | Omit<DynamicBinding<Value>, "id" | "token" | "slot" | "predicate"> | Omit<DynamicAsyncBinding<Value>, "id" | "token" | "slot" | "predicate"> | Omit<ResolvedBinding<Value>, "id" | "token" | "slot" | "predicate"> | Omit<ResolvedAsyncBinding<Value>, "id" | "token" | "slot" | "predicate"> | Omit<ConstantBinding<Value>, "id" | "token" | "slot" | "predicate"> | Omit<AliasBinding<Value>, "id" | "token" | "slot" | "predicate">;
111
+ /**
112
+ * @since 0.3.16-canary.0
113
+ */
71
114
  declare function generateBindingId(): BindingIdentifier;
115
+ /**
116
+ * @since 0.3.16-canary.0
117
+ */
72
118
  interface BindToBuilder<Value> {
73
119
  to(type: Constructor<Value>): BindingBuilder<Value>;
74
120
  toSelf(): BindingBuilder<Value>;
75
121
  toConstantValue(value: Value): ConstantBindingBuilder<Value>;
76
122
  toDynamic(factory: (ctx: ResolutionContext) => Value): BindingBuilder<Value>;
77
123
  toDynamicAsync(factory: (ctx: ResolutionContext) => Promise<Value>): BindingBuilder<Value>;
78
- toResolved<const Deps extends readonly DependencyKey[]>(factory: (...args: { [K in keyof Deps]: TokenValue<NoInfer<Deps>[K]> }) => Value, deps: Deps): BindingBuilder<Value>;
79
- 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>;
80
126
  toAlias(target: Token<Value> | Constructor<Value>): AliasBindingBuilder;
81
127
  }
128
+ /**
129
+ * @since 0.3.16-canary.0
130
+ */
82
131
  interface BindingBuilder<Value> {
83
132
  when(predicate: (ctx: ConstraintContext) => boolean): this;
84
133
  whenNamed(name: string): this;
@@ -89,6 +138,9 @@ interface BindingBuilder<Value> {
89
138
  scoped(): ScopedBindingBuilder<Value>;
90
139
  id(): BindingIdentifier;
91
140
  }
141
+ /**
142
+ * @since 0.3.16-canary.0
143
+ */
92
144
  interface ConstantBindingBuilder<Value> {
93
145
  when(predicate: (ctx: ConstraintContext) => boolean): this;
94
146
  whenNamed(name: string): this;
@@ -98,6 +150,9 @@ interface ConstantBindingBuilder<Value> {
98
150
  onDeactivation(fn: DeactivationHandler<Value>): SingletonLifecycleBuilder<Value>;
99
151
  id(): BindingIdentifier;
100
152
  }
153
+ /**
154
+ * @since 0.3.16-canary.0
155
+ */
101
156
  interface AliasBindingBuilder {
102
157
  when(predicate: (ctx: ConstraintContext) => boolean): this;
103
158
  whenNamed(name: string): this;
@@ -105,16 +160,28 @@ interface AliasBindingBuilder {
105
160
  whenDefault(): this;
106
161
  id(): BindingIdentifier;
107
162
  }
163
+ /**
164
+ * @since 0.3.16-canary.0
165
+ */
108
166
  interface SingletonBindingBuilder<Value> {
109
167
  onActivation(fn: ActivationHandler<Value>): this;
110
168
  onDeactivation(fn: DeactivationHandler<Value>): this;
111
169
  id(): BindingIdentifier;
112
170
  }
171
+ /**
172
+ * @since 0.3.16-canary.0
173
+ */
113
174
  interface TransientBindingBuilder<Value> {
114
175
  onActivation(fn: ActivationHandler<Value>): this;
115
176
  id(): BindingIdentifier;
116
177
  }
178
+ /**
179
+ * @since 0.3.16-canary.0
180
+ */
117
181
  interface ScopedBindingBuilder<Value> extends TransientBindingBuilder<Value> {}
182
+ /**
183
+ * @since 0.3.16-canary.0
184
+ */
118
185
  interface SingletonLifecycleBuilder<Value> {
119
186
  onActivation(fn: ActivationHandler<Value>): this;
120
187
  onDeactivation(fn: DeactivationHandler<Value>): this;
package/dist/binding.mjs CHANGED
@@ -1,14 +1,23 @@
1
1
  //#region src/binding.ts
2
+ /**
3
+ * @since 0.3.16-canary.0
4
+ */
2
5
  function slotKeyEquals(a, b) {
3
6
  if (a.name !== b.name) return false;
4
7
  if (a.tags.length !== b.tags.length) return false;
5
8
  for (const [tagKey, tagValue] of a.tags) if (!b.tags.some(([k, v]) => k === tagKey && Object.is(v, tagValue))) return false;
6
9
  return true;
7
10
  }
11
+ /**
12
+ * @since 0.3.16-canary.0
13
+ */
8
14
  const DEFAULT_SLOT = {
9
15
  name: void 0,
10
16
  tags: []
11
17
  };
18
+ /**
19
+ * @since 0.3.16-canary.0
20
+ */
12
21
  function slotKeyToString(slot) {
13
22
  if (slot.name === void 0 && slot.tags.length === 0) return "default";
14
23
  const parts = [];
@@ -17,6 +26,9 @@ function slotKeyToString(slot) {
17
26
  return parts.join(",");
18
27
  }
19
28
  let _idCounter = 0;
29
+ /**
30
+ * @since 0.3.16-canary.0
31
+ */
20
32
  function generateBindingId() {
21
33
  return String(++_idCounter);
22
34
  }
@@ -3,13 +3,53 @@ import { Token } from "./token.mjs";
3
3
  import { ConstraintContext } from "./types.mjs";
4
4
 
5
5
  //#region src/constraints.d.ts
6
- declare function whenParentIs(t: Token<unknown> | Constructor): (ctx: ConstraintContext) => boolean;
7
- declare function whenNoParentIs(t: Token<unknown> | Constructor): (ctx: ConstraintContext) => boolean;
8
- declare function whenAnyAncestorIs(t: Token<unknown> | Constructor): (ctx: ConstraintContext) => boolean;
9
- declare function whenNoAncestorIs(t: Token<unknown> | Constructor): (ctx: ConstraintContext) => boolean;
10
- declare function whenParentNamed(name: string): (ctx: ConstraintContext) => boolean;
11
- declare function whenAnyAncestorNamed(name: string): (ctx: ConstraintContext) => boolean;
12
- declare function whenParentTagged(tag: string, value: unknown): (ctx: ConstraintContext) => boolean;
13
- declare function whenAnyAncestorTagged(tag: string, value: unknown): (ctx: ConstraintContext) => boolean;
6
+ /**
7
+ * @since 0.3.16-canary.0
8
+ */
9
+ declare function whenParentIs(token: Token<unknown> | Constructor): (constraintContext: ConstraintContext) => boolean;
10
+ /**
11
+ * @since 0.3.16-canary.0
12
+ */
13
+ declare function whenNoParentIs(token: Token<unknown> | Constructor): (constraintContext: ConstraintContext) => boolean;
14
+ /**
15
+ * @since 0.3.16-canary.0
16
+ */
17
+ declare function whenAnyAncestorIs(token: Token<unknown> | Constructor): (constraintContext: ConstraintContext) => boolean;
18
+ /**
19
+ * @since 0.3.16-canary.0
20
+ */
21
+ declare function whenNoAncestorIs(token: Token<unknown> | Constructor): (constraintContext: ConstraintContext) => boolean;
22
+ /**
23
+ * @since 0.3.16-canary.0
24
+ */
25
+ declare function whenParentNamed(name: string): (constraintContext: ConstraintContext) => boolean;
26
+ /**
27
+ * @since 0.3.16-canary.0
28
+ */
29
+ declare function whenAnyAncestorNamed(name: string): (constraintContext: ConstraintContext) => boolean;
30
+ /**
31
+ * @since 0.3.16-canary.0
32
+ */
33
+ declare function whenParentTagged(tag: string, value: unknown): (constraintContext: ConstraintContext) => boolean;
34
+ /**
35
+ * @since 0.3.16-canary.0
36
+ */
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;
14
54
  //#endregion
15
- export { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged };
55
+ export { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenAnyAncestorTaggedAll, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged, whenParentTaggedAll };
@@ -1,35 +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
- function whenParentIs(t) {
7
- const name = tokenNameOf(t);
8
- return (ctx) => ctx.parent !== void 0 && ctx.parent.tokenName === name;
6
+ /**
7
+ * @since 0.3.16-canary.0
8
+ */
9
+ function whenParentIs(token) {
10
+ const tokenDisplayName = tokenNameOf(token);
11
+ return (constraintContext) => constraintContext.parent !== void 0 && constraintContext.parent.tokenName === tokenDisplayName;
9
12
  }
10
- function whenNoParentIs(t) {
11
- const name = tokenNameOf(t);
12
- return (ctx) => ctx.parent === void 0 || ctx.parent.tokenName !== name;
13
+ /**
14
+ * @since 0.3.16-canary.0
15
+ */
16
+ function whenNoParentIs(token) {
17
+ const tokenDisplayName = tokenNameOf(token);
18
+ return (constraintContext) => constraintContext.parent === void 0 || constraintContext.parent.tokenName !== tokenDisplayName;
13
19
  }
14
- function whenAnyAncestorIs(t) {
15
- const name = tokenNameOf(t);
16
- return (ctx) => ctx.ancestors.some((f) => f.tokenName === name);
20
+ /**
21
+ * @since 0.3.16-canary.0
22
+ */
23
+ function whenAnyAncestorIs(token) {
24
+ const tokenDisplayName = tokenNameOf(token);
25
+ return (constraintContext) => constraintContext.ancestors.some((ancestorFrame) => ancestorFrame.tokenName === tokenDisplayName);
17
26
  }
18
- function whenNoAncestorIs(t) {
19
- const name = tokenNameOf(t);
20
- return (ctx) => ctx.ancestors.every((f) => f.tokenName !== name);
27
+ /**
28
+ * @since 0.3.16-canary.0
29
+ */
30
+ function whenNoAncestorIs(token) {
31
+ const tokenDisplayName = tokenNameOf(token);
32
+ return (constraintContext) => constraintContext.ancestors.every((ancestorFrame) => ancestorFrame.tokenName !== tokenDisplayName);
21
33
  }
34
+ /**
35
+ * @since 0.3.16-canary.0
36
+ */
22
37
  function whenParentNamed(name) {
23
- return (ctx) => ctx.parent !== void 0 && ctx.parent.slot.name === name;
38
+ return (constraintContext) => constraintContext.parent !== void 0 && constraintContext.parent.slot.name === name;
24
39
  }
40
+ /**
41
+ * @since 0.3.16-canary.0
42
+ */
25
43
  function whenAnyAncestorNamed(name) {
26
- return (ctx) => ctx.ancestors.some((f) => f.slot.name === name);
44
+ return (constraintContext) => constraintContext.ancestors.some((ancestorFrame) => ancestorFrame.slot.name === name);
27
45
  }
46
+ /**
47
+ * @since 0.3.16-canary.0
48
+ */
28
49
  function whenParentTagged(tag, value) {
29
- 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));
30
51
  }
52
+ /**
53
+ * @since 0.3.16-canary.0
54
+ */
31
55
  function whenAnyAncestorTagged(tag, value) {
32
- 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(([k, v]) => k === tagKey && Object.is(v, 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(([k, v]) => k === tagKey && Object.is(v, tagValue)));
84
+ });
33
85
  }
34
86
  //#endregion
35
- export { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged };
87
+ export { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenAnyAncestorTaggedAll, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged, whenParentTaggedAll };
@@ -5,13 +5,17 @@
5
5
  * `strictFunctionTypes` (unlike `unknown[]`, which is not assignable from
6
6
  * narrower parameter types). Runtime construction still uses the real shape;
7
7
  * this alias is the DI “class token” surface only.
8
+ *
9
+ * @since 0.3.16-canary.0
8
10
  */
9
- type Constructor<Value = unknown> = new (...args: never[]) => Value;
11
+ type Constructor<Value = unknown> = new (...args: Array<never>) => Value;
10
12
  /**
11
13
  * Class constructor as invoked by the resolver after metadata-driven
12
14
  * resolution of `unknown[]` dependencies — separate from {@link Constructor},
13
15
  * which is the public assignable class token.
16
+ *
17
+ * @since 0.3.16-canary.0
14
18
  */
15
- type ConstructorInvocation = new (...args: unknown[]) => unknown;
19
+ type ConstructorInvocation = new (...args: Array<unknown>) => unknown;
16
20
  //#endregion
17
21
  export { Constructor, ConstructorInvocation };
@@ -8,6 +8,9 @@ import { ContainerGraphJson, GraphOptions } from "./dependency-graph.mjs";
8
8
  import { AutoRegisterRegistry } from "./decorators/injectable.mjs";
9
9
 
10
10
  //#region src/container.d.ts
11
+ /**
12
+ * @since 0.3.16-canary.0
13
+ */
11
14
  interface Container {
12
15
  readonly isDisposed: boolean;
13
16
  bind<const Value>(token: Token<Value> | Constructor<Value>): BindToBuilder<Value>;
@@ -16,9 +19,9 @@ interface Container {
16
19
  unbindAll(): void;
17
20
  unbindAllAsync(): Promise<void>;
18
21
  rebind<const Value>(token: Token<Value> | Constructor<Value>): BindToBuilder<Value>;
19
- load(...modules: SyncModule[]): void;
22
+ load(...modules: Array<SyncModule>): void;
20
23
  loadAsync(...modules: Array<SyncModule | AsyncModule>): Promise<void>;
21
- unload(...modules: SyncModule[]): void;
24
+ unload(...modules: Array<SyncModule>): void;
22
25
  unloadAsync(...modules: Array<SyncModule | AsyncModule>): Promise<void>;
23
26
  loadAutoRegistered(registry: AutoRegisterRegistry): number;
24
27
  onActivation<const Value>(token: Token<Value> | Constructor<Value>, handler: ActivationHandler<Value>): void;
@@ -27,8 +30,8 @@ interface Container {
27
30
  resolveAsync<const Value>(token: Token<Value> | Constructor<Value>, hint?: ResolveOptions): Promise<Value>;
28
31
  resolveOptional<const Value>(token: Token<Value> | Constructor<Value>, hint?: ResolveOptions): Value | undefined;
29
32
  resolveOptionalAsync<const Value>(token: Token<Value> | Constructor<Value>, hint?: ResolveOptions): Promise<Value | undefined>;
30
- resolveAll<const Value>(token: Token<Value> | Constructor<Value>, hint?: ResolveOptions): Value[];
31
- 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>>;
32
35
  createChild(): Container;
33
36
  dispose(): Promise<void>;
34
37
  [Symbol.asyncDispose](): Promise<void>;
@@ -37,15 +40,21 @@ interface Container {
37
40
  validate(): void;
38
41
  has(token: Token<unknown> | Constructor, hint?: ResolveOptions): boolean;
39
42
  hasOwn(token: Token<unknown> | Constructor, hint?: ResolveOptions): boolean;
40
- lookupBindings<const Value>(token: Token<Value> | Constructor<Value>): readonly BindingSnapshot[];
43
+ lookupBindings<const Value>(token: Token<Value> | Constructor<Value>): ReadonlyArray<BindingSnapshot>;
41
44
  inspect(): ContainerSnapshot;
42
45
  generateDependencyGraph(options?: GraphOptions): ContainerGraphJson;
43
46
  }
47
+ /**
48
+ * @since 0.3.16-canary.0
49
+ */
44
50
  interface ContainerStatic {
45
51
  create(): Container;
46
- fromModules(...modules: SyncModule[]): Container;
52
+ fromModules(...modules: Array<SyncModule>): Container;
47
53
  fromModulesAsync(...modules: Array<SyncModule | AsyncModule>): Promise<Container>;
48
54
  }
55
+ /**
56
+ * @since 0.3.16-canary.0
57
+ */
49
58
  declare const Container: ContainerStatic & {
50
59
  create(): Container;
51
60
  };