@tstdl/base 0.93.125 → 0.93.126

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 (198) hide show
  1. package/ai/genkit/tests/multi-region.test.js +6 -6
  2. package/ai/index.d.ts +2 -6
  3. package/ai/index.js +2 -6
  4. package/ai/parser/index.d.ts +1 -0
  5. package/ai/parser/index.js +1 -0
  6. package/ai/parser/parser.d.ts +12 -0
  7. package/ai/parser/parser.js +28 -0
  8. package/ai/prompts/build.d.ts +21 -0
  9. package/ai/prompts/build.js +25 -0
  10. package/ai/prompts/index.d.ts +2 -0
  11. package/ai/prompts/index.js +2 -0
  12. package/ai/prompts/instructions-formatter.d.ts +9 -22
  13. package/ai/prompts/instructions-formatter.js +20 -7
  14. package/ai/prompts/instructions.js +1 -1
  15. package/ai/prompts/steering.d.ts +27 -0
  16. package/ai/prompts/steering.js +54 -0
  17. package/ai/tests/instructions-formatter.test.js +115 -0
  18. package/ai/tests/steering.test.js +37 -0
  19. package/application/application.d.ts +2 -1
  20. package/application/application.js +3 -0
  21. package/authentication/client/module.d.ts +1 -1
  22. package/authentication/client/module.js +4 -5
  23. package/authentication/tests/authentication-ancillary.service.test.js +1 -1
  24. package/authentication/tests/authentication.api-controller.test.js +3 -1
  25. package/authentication/tests/authentication.api-request-token.provider.test.js +1 -1
  26. package/authentication/tests/authentication.client-service.test.js +1 -1
  27. package/authentication/tests/authentication.service.test.js +1 -1
  28. package/authentication/tests/subject.service.test.js +1 -1
  29. package/circuit-breaker/tests/circuit-breaker.test.js +1 -1
  30. package/document-management/api/document-management.api.d.ts +16 -16
  31. package/document-management/api/document-management.api.js +12 -12
  32. package/document-management/models/ai-configuration.d.ts +59 -0
  33. package/document-management/models/ai-configuration.js +1 -0
  34. package/document-management/models/document-assignment-scope.model.js +2 -4
  35. package/document-management/models/document-assignment-task.model.js +2 -4
  36. package/document-management/models/document-collection-assignment.model.js +2 -4
  37. package/document-management/models/document-collection.model.js +2 -3
  38. package/document-management/models/document-content.model.d.ts +6 -0
  39. package/document-management/models/document-content.model.js +32 -0
  40. package/document-management/models/document-property-value.model.js +1 -2
  41. package/document-management/models/document-request-collection-assignment.model.js +2 -4
  42. package/document-management/models/document-request.model.js +2 -4
  43. package/document-management/models/document-tag-assignment.model.js +2 -3
  44. package/document-management/models/document-validation-execution-related-document.model.js +2 -4
  45. package/document-management/models/document-validation-execution.model.js +2 -5
  46. package/document-management/models/document-workflow.model.d.ts +2 -1
  47. package/document-management/models/document-workflow.model.js +4 -5
  48. package/document-management/models/document.model.js +2 -3
  49. package/document-management/models/index.d.ts +2 -0
  50. package/document-management/models/index.js +2 -0
  51. package/document-management/server/api/document-management.api.d.ts +7 -7
  52. package/document-management/server/api/document-management.api.js +9 -9
  53. package/document-management/server/configure.d.ts +4 -1
  54. package/document-management/server/configure.js +9 -4
  55. package/document-management/server/drizzle/{0000_complex_black_bird.sql → 0000_curious_nighthawk.sql} +7 -27
  56. package/document-management/server/drizzle/meta/0000_snapshot.json +12 -284
  57. package/document-management/server/drizzle/meta/_journal.json +2 -2
  58. package/document-management/server/module.d.ts +2 -0
  59. package/document-management/server/module.js +1 -0
  60. package/document-management/server/schemas.d.ts +2 -1
  61. package/document-management/server/services/document-file.service.d.ts +6 -6
  62. package/document-management/server/services/document-file.service.js +7 -81
  63. package/document-management/server/services/document-management-ai-provider.service.d.ts +66 -0
  64. package/document-management/server/services/document-management-ai-provider.service.js +2 -0
  65. package/document-management/server/services/document-management-ai.service.d.ts +44 -7
  66. package/document-management/server/services/document-management-ai.service.js +332 -329
  67. package/document-management/server/services/document-validation.service.d.ts +1 -1
  68. package/document-management/server/services/document-workflow.service.d.ts +4 -3
  69. package/document-management/server/services/document-workflow.service.js +26 -9
  70. package/document-management/server/services/document.service.d.ts +7 -3
  71. package/document-management/server/services/document.service.js +13 -4
  72. package/document-management/server/services/index.d.ts +1 -0
  73. package/document-management/server/services/index.js +1 -0
  74. package/document-management/server/validators/ai-validation-executor.d.ts +419 -12
  75. package/document-management/server/validators/ai-validation-executor.js +51 -46
  76. package/document-management/server/validators/single-document-validation-executor.d.ts +1 -3
  77. package/document-management/server/validators/single-document-validation-executor.js +2 -4
  78. package/document-management/service-models/document.service-model.d.ts +3 -3
  79. package/document-management/service-models/document.service-model.js +1 -1
  80. package/document-management/tests/ai-config-hierarchy.test.d.ts +1 -0
  81. package/document-management/tests/ai-config-hierarchy.test.js +64 -0
  82. package/document-management/tests/ai-config-integration.test.d.ts +1 -0
  83. package/document-management/tests/ai-config-integration.test.js +125 -0
  84. package/document-management/tests/ai-config-merge.test.d.ts +1 -0
  85. package/document-management/tests/ai-config-merge.test.js +38 -0
  86. package/document-management/tests/document-management-ai-overrides.test.d.ts +1 -0
  87. package/document-management/tests/document-management-ai-overrides.test.js +64 -0
  88. package/document-management/tests/document-management-core.test.js +6 -6
  89. package/document-management/tests/document-management.api.test.js +5 -5
  90. package/document-management/tests/document-statistics.service.test.js +10 -6
  91. package/document-management/tests/document-validation-ai-overrides.test.d.ts +1 -0
  92. package/document-management/tests/document-validation-ai-overrides.test.js +85 -0
  93. package/document-management/tests/document.service.test.js +15 -11
  94. package/document-management/tests/enum-helpers.test.js +5 -5
  95. package/examples/document-management/ai-provider.d.ts +20 -0
  96. package/examples/document-management/ai-provider.js +74 -0
  97. package/examples/document-management/main.js +9 -6
  98. package/examples/injector/graph-example.d.ts +1 -0
  99. package/examples/injector/graph-example.js +340 -0
  100. package/injector/decorators.d.ts +4 -4
  101. package/injector/decorators.js +5 -6
  102. package/injector/forward-ref.d.ts +15 -0
  103. package/injector/forward-ref.js +20 -0
  104. package/injector/graph.d.ts +113 -0
  105. package/injector/graph.js +631 -0
  106. package/injector/index.d.ts +2 -0
  107. package/injector/index.js +2 -0
  108. package/injector/inject.d.ts +15 -15
  109. package/injector/injector.d.ts +101 -13
  110. package/injector/injector.js +103 -59
  111. package/injector/resolve-chain.d.ts +20 -6
  112. package/injector/resolve-chain.js +39 -14
  113. package/injector/tests/advanced.test.d.ts +1 -0
  114. package/injector/tests/advanced.test.js +116 -0
  115. package/injector/tests/async-init.test.d.ts +1 -0
  116. package/injector/tests/async-init.test.js +77 -0
  117. package/injector/tests/basic.test.d.ts +1 -0
  118. package/injector/tests/basic.test.js +114 -0
  119. package/injector/tests/hierarchical.test.d.ts +1 -0
  120. package/injector/tests/hierarchical.test.js +59 -0
  121. package/injector/tests/lifecycles.test.d.ts +1 -0
  122. package/injector/tests/lifecycles.test.js +109 -0
  123. package/injector/token.d.ts +2 -1
  124. package/injector/token.js +4 -1
  125. package/injector/type-info.d.ts +1 -5
  126. package/injector/types.d.ts +4 -10
  127. package/logger/tests/pretty-print.test.d.ts +1 -0
  128. package/logger/{formatters → tests}/pretty-print.test.js +1 -1
  129. package/logger/transports/console.d.ts +3 -2
  130. package/logger/transports/console.js +4 -3
  131. package/notification/tests/notification-api.test.js +8 -5
  132. package/notification/tests/notification-client.test.d.ts +1 -0
  133. package/notification/tests/{unit/notification-client.test.js → notification-client.test.js} +5 -5
  134. package/notification/tests/notification-flow.test.js +6 -5
  135. package/notification/tests/notification-sse.service.test.js +1 -1
  136. package/notification/tests/notification-type.service.test.js +1 -1
  137. package/object-storage/s3/s3.object-storage.js +3 -0
  138. package/object-storage/s3/tests/s3.object-storage.integration.test.js +1 -1
  139. package/orm/tests/repository-attributes.test.js +10 -17
  140. package/orm/tests/repository-cti-mapping.test.js +2 -2
  141. package/orm/tests/repository-cti-soft-delete.test.js +1 -1
  142. package/orm/tests/repository-cti.test.js +19 -33
  143. package/orm/tests/repository-extra-coverage.test.js +1 -1
  144. package/orm/tests/repository-search.test.js +5 -2
  145. package/orm/tests/transaction-safety.test.js +1 -1
  146. package/package.json +7 -9
  147. package/rate-limit/tests/postgres-rate-limiter.test.js +6 -16
  148. package/renderer/d2.d.ts +77 -0
  149. package/renderer/d2.js +68 -0
  150. package/renderer/graphviz.d.ts +47 -0
  151. package/renderer/graphviz.js +58 -0
  152. package/renderer/index.d.ts +4 -0
  153. package/renderer/index.js +4 -0
  154. package/renderer/typst.d.ts +57 -0
  155. package/renderer/typst.js +62 -0
  156. package/rpc/adapters/readable-stream.adapter.d.ts +3 -0
  157. package/rpc/adapters/readable-stream.adapter.js +5 -1
  158. package/rpc/rpc.js +28 -3
  159. package/rpc/tests/rpc.integration.test.js +3 -1
  160. package/schema/schemas/nullable.js +1 -1
  161. package/task-queue/task-queue.d.ts +2 -0
  162. package/task-queue/task-queue.js +6 -2
  163. package/task-queue/tests/complex.test.js +1 -1
  164. package/task-queue/tests/dependencies.test.js +3 -3
  165. package/task-queue/tests/extensive-dependencies.test.js +1 -1
  166. package/task-queue/tests/queue.test.js +1 -1
  167. package/task-queue/tests/worker.test.js +4 -7
  168. package/test5.js +52 -8
  169. package/{unit-test → testing}/integration-setup.d.ts +1 -0
  170. package/{unit-test → testing}/integration-setup.js +13 -0
  171. package/utils/base64.d.ts +7 -0
  172. package/utils/base64.js +10 -1
  173. package/utils/noop.d.ts +7 -1
  174. package/utils/noop.js +7 -1
  175. package/ai/ai-file.service.d.ts +0 -57
  176. package/ai/ai-file.service.js +0 -233
  177. package/ai/ai-session.d.ts +0 -38
  178. package/ai/ai-session.js +0 -50
  179. package/ai/ai.service.d.ts +0 -126
  180. package/ai/ai.service.js +0 -481
  181. package/ai/functions.d.ts +0 -9
  182. package/ai/functions.js +0 -38
  183. package/ai/module.d.ts +0 -26
  184. package/ai/module.js +0 -25
  185. package/ai/types.d.ts +0 -229
  186. package/ai/types.js +0 -33
  187. package/latex/index.d.ts +0 -1
  188. package/latex/index.js +0 -1
  189. package/typst/index.d.ts +0 -1
  190. package/typst/index.js +0 -1
  191. package/typst/render.d.ts +0 -23
  192. package/typst/render.js +0 -32
  193. /package/{logger/formatters/pretty-print.test.d.ts → ai/tests/instructions-formatter.test.d.ts} +0 -0
  194. /package/{notification/tests/unit/notification-client.test.d.ts → ai/tests/steering.test.d.ts} +0 -0
  195. /package/{latex/render.d.ts → renderer/latex.d.ts} +0 -0
  196. /package/{latex/render.js → renderer/latex.js} +0 -0
  197. /package/{unit-test → testing}/index.d.ts +0 -0
  198. /package/{unit-test → testing}/index.js +0 -0
@@ -2,24 +2,24 @@ import { Injector, type ResolveManyItem, type ResolveManyReturnType } from './in
2
2
  import type { Resolvable, ResolveArgument } from './interfaces.js';
3
3
  import type { InjectionToken } from './token.js';
4
4
  import type { ResolveOptions } from './types.js';
5
- export type InjectOptions<T, A> = ResolveOptions<T, A>;
5
+ export type InjectOptions = ResolveOptions;
6
6
  export type InjectArgumentOptions = {
7
7
  optional?: boolean;
8
8
  };
9
9
  export type InjectionContext = {
10
10
  injector: Injector;
11
11
  argument: unknown;
12
- inject<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument: ResolveArgument<T, A>, options: InjectOptions<T, A> & {
12
+ inject<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument: ResolveArgument<T, A>, options: InjectOptions & {
13
13
  optional: true;
14
14
  }): T | undefined;
15
- inject<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions<T, A> & {
15
+ inject<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions & {
16
16
  optional?: false;
17
17
  }): T;
18
- inject<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions<T, A>): T | undefined;
19
- injectAll<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions<T, A>): T[];
18
+ inject<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions): T | undefined;
19
+ injectAll<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions): T[];
20
20
  injectMany<T extends InjectManyItem<any, any>[]>(...tokens: T): InjectManyReturnType<T>;
21
- injectAsync<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions<T, A>): Promise<T>;
22
- injectAllAsync<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions<T, A>): Promise<T[]>;
21
+ injectAsync<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions): Promise<T>;
22
+ injectAllAsync<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions): Promise<T[]>;
23
23
  injectManyAsync<T extends InjectManyItem<any, any>[]>(...tokens: T): Promise<InjectManyReturnType<T>>;
24
24
  };
25
25
  export type InjectManyItem<T, A> = ResolveManyItem<T, A>;
@@ -31,13 +31,13 @@ export type InjectManyReturnType<T extends InjectManyItem<any, any>[]> = Resolve
31
31
  * @param argument argument to resolve token with
32
32
  * @param options resolve options
33
33
  */
34
- export declare function inject<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument: ResolveArgument<T, A>, options: InjectOptions<T, A> & {
34
+ export declare function inject<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument: ResolveArgument<T, A>, options: InjectOptions & {
35
35
  optional: true;
36
36
  }): T | undefined;
37
- export declare function inject<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions<T, A> & {
37
+ export declare function inject<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions & {
38
38
  optional?: false;
39
39
  }): T;
40
- export declare function inject<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions<T, A>): T | undefined;
40
+ export declare function inject<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions): T | undefined;
41
41
  /**
42
42
  * Resolves tokens using the {@link Injector} of the current injection context
43
43
  *
@@ -51,13 +51,13 @@ export declare function injectMany<T extends InjectManyItem<any, any>[]>(...toke
51
51
  * @param argument argument to resolve token with
52
52
  * @param options resolve options
53
53
  */
54
- export declare function injectAsync<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument: ResolveArgument<T, A>, options: InjectOptions<T, A> & {
54
+ export declare function injectAsync<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument: ResolveArgument<T, A>, options: InjectOptions & {
55
55
  optional: true;
56
56
  }): Promise<T | undefined>;
57
- export declare function injectAsync<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions<T, A> & {
57
+ export declare function injectAsync<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions & {
58
58
  optional?: false;
59
59
  }): Promise<T>;
60
- export declare function injectAsync<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions<T, A>): Promise<T | undefined>;
60
+ export declare function injectAsync<T = unknown, A = unknown>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions): Promise<T | undefined>;
61
61
  /**
62
62
  * Resolves tokens using the {@link Injector} of the current injection context
63
63
  *
@@ -71,7 +71,7 @@ export declare function injectManyAsync<T extends InjectManyItem<any, any>[]>(..
71
71
  * @param argument argument to resolve token with
72
72
  * @param options resolve options
73
73
  */
74
- export declare function injectAll<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions<T, A>): T[];
74
+ export declare function injectAll<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions): T[];
75
75
  /**
76
76
  * Resolves a token using the {@link Injector} of the current injection context
77
77
  *
@@ -79,7 +79,7 @@ export declare function injectAll<T, A>(token: InjectionToken<T, A>, argument?:
79
79
  * @param argument argument to resolve token with
80
80
  * @param options resolve options
81
81
  */
82
- export declare function injectAllAsync<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions<T, A>): Promise<T[]>;
82
+ export declare function injectAllAsync<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions): Promise<T[]>;
83
83
  /**
84
84
  * Injects the resolve argument from the current resolution
85
85
  * @param _this can be used for type infer by simply passing `this`. Requires class to implement {@link Resolvable}.
@@ -1,10 +1,47 @@
1
- import type { OneOrMany, Record, TypedOmit } from '../types/index.js';
1
+ import { CircularBuffer } from '../data-structures/circular-buffer.js';
2
+ import { MultiKeyMap } from '../data-structures/multi-key-map.js';
3
+ import { DeferredPromise } from '../promise/deferred-promise.js';
4
+ import type { OneOrMany, Record, TypedOmit, WritableOneOrMany } from '../types/index.js';
5
+ import { FactoryMap } from '../utils/factory-map.js';
6
+ import { ForwardRef } from '../utils/object/forward-ref.js';
2
7
  import { type InjectOptions } from './inject.js';
3
8
  import { type ResolveArgument } from './interfaces.js';
4
9
  import { type Provider } from './provider.js';
10
+ import { type AfterResolveHandler } from './resolution.js';
11
+ import { ResolveChain } from './resolve-chain.js';
5
12
  import { type InjectionToken } from './token.js';
6
- import type { RegistrationOptions, ResolveOptions } from './types.js';
7
- export type DisposeHandler = Disposable | AsyncDisposable | (() => PromiseLike<void> | void);
13
+ import type { AfterResolveContext, RegistrationOptions, ResolveContextData, ResolveOptions } from './types.js';
14
+ export type DisposeHandler = Disposable | AsyncDisposable | (() => any);
15
+ type ResolutionTag = symbol;
16
+ type RegistrationsMap = Map<InjectionToken, WritableOneOrMany<Registration>>;
17
+ type GlobalRegistrationsMap = Map<InjectionToken, WritableOneOrMany<GlobalRegistration>>;
18
+ export type InternalResolveContext = {
19
+ resolves: number;
20
+ /** Currently resolving tokens (for circular dependency detection) */
21
+ resolving: FactoryMap<Injector, Set<InjectionToken>>;
22
+ /** Resolutions for resolution scoped dependencies */
23
+ resolutionScopedResolutions: MultiKeyMap<[InjectionToken, unknown], Resolution<any, any>>;
24
+ /** All resolutions in this chain for postprocessing */
25
+ resolutions: Resolution<any, any>[];
26
+ /** All dependency accesses (including cached ones) for graph generation */
27
+ accesses: {
28
+ chain: ResolveChain;
29
+ }[];
30
+ recordAccess(chain: ResolveChain): void;
31
+ resolutionContextData: FactoryMap<ResolutionTag, ResolveContextData<Record>>;
32
+ forwardRefQueue: CircularBuffer<() => void>;
33
+ forwardRefs: Set<ForwardRef>;
34
+ $done: DeferredPromise;
35
+ };
36
+ export type Resolution<T, A> = {
37
+ tag: ResolutionTag;
38
+ registration: Registration<T>;
39
+ value: T;
40
+ argument: ResolveArgument<T, A>;
41
+ afterResolveRegistrations: AfterResolveHandler<A, Record>[];
42
+ afterResolveContext: AfterResolveContext<any>;
43
+ chain: ResolveChain;
44
+ };
8
45
  export type ProvidersItem<T = any, A = any, D extends Record = Record> = Provider<T, A, D> & {
9
46
  provide: InjectionToken<T, A>;
10
47
  multi?: boolean;
@@ -16,6 +53,10 @@ export type GlobalRegistration<T = any, A = any> = {
16
53
  options: RegistrationOptions<T, A>;
17
54
  };
18
55
  export type Registration<T = any, A = any> = GlobalRegistration<T, A> & {
56
+ /**
57
+ * The injector this registration belongs to.
58
+ */
59
+ injector: Injector;
19
60
  /**
20
61
  * A map associating argument identities to their resolved instances of type `T`.
21
62
  */
@@ -25,7 +66,7 @@ export type GetRegistrationOptions = {
25
66
  skipSelf?: boolean | number;
26
67
  onlySelf?: boolean;
27
68
  };
28
- export type ResolveManyArrayItem<T, A> = [token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions<T, A>];
69
+ export type ResolveManyArrayItem<T, A> = [token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: InjectOptions];
29
70
  export type ResolveManyItem<T, A> = InjectionToken<T, A> | ResolveManyArrayItem<T, A>;
30
71
  export type ResolveManyItemReturnType<T extends ResolveManyItem<any, any>> = T extends ResolveManyItem<infer U, any> ? U | (T extends (ResolveManyArrayItem<any, any> & [any, any, {
31
72
  optional: true;
@@ -33,14 +74,27 @@ export type ResolveManyItemReturnType<T extends ResolveManyItem<any, any>> = T e
33
74
  export type ResolveManyReturnType<T extends ResolveManyItem<any, any>[]> = {
34
75
  [I in keyof T]: ResolveManyItemReturnType<T[I]>;
35
76
  };
36
- export type AddDisposeHandler = (handler: Disposable | AsyncDisposable | (() => any)) => void;
37
77
  export declare class Injector implements AsyncDisposable {
38
78
  #private;
39
79
  readonly id: number;
40
80
  readonly name: string;
81
+ readonly ownerToken?: InjectionToken;
41
82
  get parent(): Injector | null;
83
+ get accesses(): {
84
+ chain: ResolveChain;
85
+ }[];
42
86
  get disposed(): boolean;
43
- constructor(name: string, parent?: Injector | null);
87
+ constructor(name: string, parent?: Injector | null, ownerToken?: InjectionToken);
88
+ /**
89
+ * Add a dispose handler to this injector. The handler can be a disposable, async disposable, or a simple function. If the handler is a disposable or async disposable, it will be disposed when the injector is disposed.
90
+ * If the handler is a function, it will be called when the injector is disposed.
91
+ * @param handler dispose handler to add
92
+ */
93
+ addDisposeHandler(handler: DisposeHandler): void;
94
+ /** @internal */
95
+ static getGlobalRegistrations(): GlobalRegistrationsMap;
96
+ /** @internal */
97
+ getRegistrations(): RegistrationsMap;
44
98
  /**
45
99
  * Globally register a provider for a token
46
100
  * @param token token to register
@@ -61,9 +115,10 @@ export declare class Injector implements AsyncDisposable {
61
115
  * Creates a new child `Injector` instance with the specified name.
62
116
  *
63
117
  * @param name - The name to assign to the child injector.
118
+ * @param ownerToken - The token that owns this injector.
64
119
  * @returns The newly created child `Injector` instance.
65
120
  */
66
- fork(name: string): Injector;
121
+ fork(name: string, ownerToken?: InjectionToken): Injector;
67
122
  /**
68
123
  * Register a provider for a token
69
124
  * @param token token to register
@@ -93,17 +148,49 @@ export declare class Injector implements AsyncDisposable {
93
148
  * @param token token to get registration for
94
149
  */
95
150
  getRegistration<T, A>(token: InjectionToken<T, A>, options?: GetRegistrationOptions): Registration<T, A> | Registration<T, A>[];
96
- resolve<T, A>(token: InjectionToken<T, A>, argument: ResolveArgument<T, A>, options: ResolveOptions<T, A> & {
151
+ resolve<T, A>(token: InjectionToken<T, A>, argument: ResolveArgument<T, A>, options: ResolveOptions & {
97
152
  optional: true;
98
153
  }): T | undefined;
99
- resolve<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: ResolveOptions<T, A>): T;
100
- resolveAll<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: ResolveOptions<T, A>): T[];
154
+ resolve<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: ResolveOptions): T;
155
+ resolveWithResolutions<T, A>(token: InjectionToken<T, A>, argument: ResolveArgument<T, A>, options: ResolveOptions & {
156
+ optional: true;
157
+ }): {
158
+ value: T | undefined;
159
+ resolutions: Resolution<any, any>[];
160
+ accesses: {
161
+ chain: ResolveChain;
162
+ }[];
163
+ };
164
+ resolveWithResolutions<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: ResolveOptions): {
165
+ value: T;
166
+ resolutions: Resolution<any, any>[];
167
+ accesses: {
168
+ chain: ResolveChain;
169
+ }[];
170
+ };
171
+ resolveAll<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: ResolveOptions): T[];
101
172
  resolveMany<T extends ResolveManyItem<any, any>[]>(...tokens: T): ResolveManyReturnType<T>;
102
- resolveAsync<T, A>(token: InjectionToken<T, A>, argument: ResolveArgument<T, A>, options: ResolveOptions<T, A> & {
173
+ resolveAsync<T, A>(token: InjectionToken<T, A>, argument: ResolveArgument<T, A>, options: ResolveOptions & {
103
174
  optional: true;
104
175
  }): Promise<T | undefined>;
105
- resolveAsync<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: ResolveOptions<T, A>): Promise<T>;
106
- resolveAllAsync<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: ResolveOptions<T, A>): Promise<T[]>;
176
+ resolveAsync<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: ResolveOptions): Promise<T>;
177
+ resolveWithResolutionsAsync<T, A>(token: InjectionToken<T, A>, argument: ResolveArgument<T, A>, options: ResolveOptions & {
178
+ optional: true;
179
+ }): Promise<{
180
+ value: T | undefined;
181
+ resolutions: Resolution<any, any>[];
182
+ accesses: {
183
+ chain: ResolveChain;
184
+ }[];
185
+ }>;
186
+ resolveWithResolutionsAsync<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: ResolveOptions): Promise<{
187
+ value: T;
188
+ resolutions: Resolution<any, any>[];
189
+ accesses: {
190
+ chain: ResolveChain;
191
+ }[];
192
+ }>;
193
+ resolveAllAsync<T, A>(token: InjectionToken<T, A>, argument?: ResolveArgument<T, A>, options?: ResolveOptions): Promise<T[]>;
107
194
  resolveManyAsync<T extends ResolveManyItem<any, any>[]>(...tokens: T): Promise<ResolveManyReturnType<T>>;
108
195
  private _resolveManyTokens;
109
196
  private _resolve;
@@ -123,3 +210,4 @@ export declare class Injector implements AsyncDisposable {
123
210
  export declare function provide<T = any, A = any, D extends Record = Record>(token: InjectionToken<T, A>, provider: Provider<T, A, D> & {
124
211
  multi?: boolean;
125
212
  }): ProvidersItem<T, A, D>;
213
+ export {};
@@ -1,4 +1,5 @@
1
1
  import { CancellationSignal, CancellationToken } from '../cancellation/index.js';
2
+ import { isDevMode } from '../core.js';
2
3
  import { CircularBuffer } from '../data-structures/circular-buffer.js';
3
4
  import { MultiKeyMap } from '../data-structures/multi-key-map.js';
4
5
  import { isSyncOrAsyncDisposable } from '../disposable/disposable.js';
@@ -8,7 +9,8 @@ import { toArray } from '../utils/array/array.js';
8
9
  import { FactoryMap } from '../utils/factory-map.js';
9
10
  import { ForwardRef } from '../utils/object/forward-ref.js';
10
11
  import { objectEntries } from '../utils/object/object.js';
11
- import { assert, isArray, isBoolean, isDefined, isFunction, isNotNull, isNotObject, isNull, isPromise, isUndefined } from '../utils/type-guards.js';
12
+ import { assert, isArray, isDefined, isFunction, isNotNull, isNotObject, isNull, isPromise, isUndefined } from '../utils/type-guards.js';
13
+ import { isForwardRefToken } from './forward-ref.js';
12
14
  import { setCurrentInjectionContext } from './inject.js';
13
15
  import { afterResolve } from './interfaces.js';
14
16
  import { isClassProvider, isFactoryProvider, isProviderWithInitializer, isTokenProvider, isValueProvider } from './provider.js';
@@ -28,32 +30,50 @@ export class Injector {
28
30
  #disposableStackRegistrations = new Set();
29
31
  #registrations = new Map();
30
32
  #injectorScopedResolutions = new MultiKeyMap();
31
- #addDisposeHandler;
33
+ #accesses = [];
32
34
  id = _id++;
33
35
  name;
36
+ ownerToken;
34
37
  get parent() {
35
38
  return this.#parent;
36
39
  }
40
+ get accesses() {
41
+ return this.#accesses;
42
+ }
37
43
  get disposed() {
38
44
  return this.#disposableStack.disposed;
39
45
  }
40
- constructor(name, parent = null) {
46
+ constructor(name, parent = null, ownerToken) {
41
47
  this.name = name;
42
48
  this.#parent = parent;
49
+ this.ownerToken = ownerToken;
43
50
  this.register(Injector, { useValue: this });
44
51
  this.register(CancellationSignal, { useValue: this.#disposeToken.signal });
45
- this.#addDisposeHandler = (handler) => {
46
- if (isSyncOrAsyncDisposable(handler)) {
47
- this.#disposableStack.use(handler);
48
- }
49
- else {
50
- this.#disposableStack.defer(handler);
51
- }
52
- };
53
52
  this.#disposableStack.defer(() => this.#registrations.clear());
54
53
  this.#disposableStack.defer(() => this.#injectorScopedResolutions.clear());
55
54
  this.#disposableStack.defer(() => this.#disposableStackRegistrations.clear());
56
55
  }
56
+ /**
57
+ * Add a dispose handler to this injector. The handler can be a disposable, async disposable, or a simple function. If the handler is a disposable or async disposable, it will be disposed when the injector is disposed.
58
+ * If the handler is a function, it will be called when the injector is disposed.
59
+ * @param handler dispose handler to add
60
+ */
61
+ addDisposeHandler(handler) {
62
+ if (isSyncOrAsyncDisposable(handler)) {
63
+ this.#disposableStack.use(handler);
64
+ }
65
+ else {
66
+ this.#disposableStack.defer(handler);
67
+ }
68
+ }
69
+ /** @internal */
70
+ static getGlobalRegistrations() {
71
+ return Injector.#globalRegistrations;
72
+ }
73
+ /** @internal */
74
+ getRegistrations() {
75
+ return this.#registrations;
76
+ }
57
77
  /**
58
78
  * Globally register a provider for a token
59
79
  * @param token token to register
@@ -92,10 +112,11 @@ export class Injector {
92
112
  * Creates a new child `Injector` instance with the specified name.
93
113
  *
94
114
  * @param name - The name to assign to the child injector.
115
+ * @param ownerToken - The token that owns this injector.
95
116
  * @returns The newly created child `Injector` instance.
96
117
  */
97
- fork(name) {
98
- const child = new Injector(name, this);
118
+ fork(name, ownerToken) {
119
+ const child = new Injector(name, this, ownerToken);
99
120
  this.#children.push(child);
100
121
  this.#disposableStack.use(child);
101
122
  return child;
@@ -115,6 +136,7 @@ export class Injector {
115
136
  provider,
116
137
  providers: options.providers ?? [],
117
138
  options: { multi, ...options },
139
+ injector: this,
118
140
  resolutions: new Map(),
119
141
  };
120
142
  addRegistration(this.#registrations, registration);
@@ -176,8 +198,12 @@ export class Injector {
176
198
  return registration;
177
199
  }
178
200
  resolve(token, argument, options = {}) {
179
- const context = newInternalResolveContext();
180
- const value = this._resolve(token, argument, options, context, ResolveChain.startWith(this, token));
201
+ const { value } = this.resolveWithResolutions(token, argument, options);
202
+ return value;
203
+ }
204
+ resolveWithResolutions(token, argument, options = {}) {
205
+ const context = newInternalResolveContext(this);
206
+ const value = this._resolve(token, argument, options, context, ResolveChain.startWith(this, token, options));
181
207
  try {
182
208
  postProcess(context);
183
209
  context.$done.resolve();
@@ -187,13 +213,13 @@ export class Injector {
187
213
  throw error;
188
214
  }
189
215
  if (context.forwardRefs.has(value)) {
190
- return ForwardRef.deref(value);
216
+ return { value: ForwardRef.deref(value), resolutions: context.resolutions, accesses: context.accesses };
191
217
  }
192
- return value;
218
+ return { value, resolutions: context.resolutions, accesses: context.accesses };
193
219
  }
194
220
  resolveAll(token, argument, options = {}) {
195
- const context = newInternalResolveContext();
196
- const values = this._resolveAll(token, argument, options, context, ResolveChain.startWith(this, token));
221
+ const context = newInternalResolveContext(this);
222
+ const values = this._resolveAll(token, argument, options, context, ResolveChain.startWith(this, token, { ...options, multi: true }));
197
223
  try {
198
224
  postProcess(context);
199
225
  context.$done.resolve();
@@ -208,7 +234,7 @@ export class Injector {
208
234
  return values;
209
235
  }
210
236
  resolveMany(...tokens) {
211
- const context = newInternalResolveContext();
237
+ const context = newInternalResolveContext(this);
212
238
  const values = this._resolveManyTokens(tokens, context);
213
239
  try {
214
240
  postProcess(context);
@@ -223,8 +249,12 @@ export class Injector {
223
249
  : value);
224
250
  }
225
251
  async resolveAsync(token, argument, options = {}) {
226
- const context = newInternalResolveContext();
227
- const value = this._resolve(token, argument, options, context, ResolveChain.startWith(this, token));
252
+ const { value } = await this.resolveWithResolutionsAsync(token, argument, options);
253
+ return value;
254
+ }
255
+ async resolveWithResolutionsAsync(token, argument, options = {}) {
256
+ const context = newInternalResolveContext(this);
257
+ const value = this._resolve(token, argument, options, context, ResolveChain.startWith(this, token, options));
228
258
  try {
229
259
  await postProcessAsync(context);
230
260
  context.$done.resolve();
@@ -234,13 +264,13 @@ export class Injector {
234
264
  throw error;
235
265
  }
236
266
  if (context.forwardRefs.has(value)) {
237
- return ForwardRef.deref(value);
267
+ return { value: ForwardRef.deref(value), resolutions: context.resolutions, accesses: context.accesses };
238
268
  }
239
- return value;
269
+ return { value, resolutions: context.resolutions, accesses: context.accesses };
240
270
  }
241
271
  async resolveAllAsync(token, argument, options = {}) {
242
- const context = newInternalResolveContext();
243
- const values = this._resolveAll(token, argument, options, context, ResolveChain.startWith(this, token));
272
+ const context = newInternalResolveContext(this);
273
+ const values = this._resolveAll(token, argument, options, context, ResolveChain.startWith(this, token, { ...options, multi: true }));
244
274
  try {
245
275
  await postProcessAsync(context);
246
276
  context.$done.resolve();
@@ -255,7 +285,7 @@ export class Injector {
255
285
  return values;
256
286
  }
257
287
  async resolveManyAsync(...tokens) {
258
- const context = newInternalResolveContext();
288
+ const context = newInternalResolveContext(this);
259
289
  const values = this._resolveManyTokens(tokens, context);
260
290
  try {
261
291
  await postProcessAsync(context);
@@ -271,7 +301,7 @@ export class Injector {
271
301
  }
272
302
  _resolveManyTokens(tokens, context) {
273
303
  return tokens.map((token) => (isArray(token)
274
- ? this._resolve(token[0], token[1], token[2] ?? {}, context, ResolveChain.startWith(this, token[0]))
304
+ ? this._resolve(token[0], token[1], token[2] ?? {}, context, ResolveChain.startWith(this, token[0], token[2] ?? {}))
275
305
  : this._resolve(token, undefined, {}, context, ResolveChain.startWith(this, token))));
276
306
  }
277
307
  _resolve(token, argument, options, context, chain) {
@@ -283,11 +313,11 @@ export class Injector {
283
313
  }
284
314
  return this.#parent?._resolve(token, argument, { ...options, skipSelf: skipSelf - 1 }, context, chain);
285
315
  }
286
- if (isDefined(options.forwardRef) && (options.forwardRef != false)) {
316
+ if (isForwardRefToken(token)) {
287
317
  assert(options.optional != true, 'ForwardRef does not support optional without resolveAll/injectAll as undefined is not forwardable.');
288
- const forwardToken = isFunction(options.forwardRef) ? options.forwardRef() : token;
289
- const forwardRef = ForwardRef.create({ typeHint: options.forwardRefTypeHint ?? isFunction(forwardToken) ? forwardToken : undefined });
290
- context.forwardRefQueue.add(() => ForwardRef.setRef(forwardRef, this._resolve(forwardToken, argument, { ...options, forwardRef: false }, context, chain.markAsForwardRef(forwardToken))));
318
+ const forwardToken = token.tokenFactory();
319
+ const forwardRef = ForwardRef.create({ typeHint: token.typeHint ?? (isFunction(forwardToken) ? forwardToken : undefined) });
320
+ context.forwardRefQueue.add(() => ForwardRef.setRef(forwardRef, this._resolve(forwardToken, argument, { ...options }, context, chain.markAsForwardRef(forwardToken))));
291
321
  context.forwardRefs.add(forwardRef);
292
322
  return forwardRef;
293
323
  }
@@ -297,7 +327,7 @@ export class Injector {
297
327
  const registration = this.tryGetRegistration(token, options);
298
328
  if (isDefined(registration)) {
299
329
  const singleRegistration = isArray(registration) ? registration[0] : registration;
300
- return this._resolveRegistration(singleRegistration, argument, options, context, chain);
330
+ return this._resolveRegistration(singleRegistration, argument, options, context, chain.withResolvedBy(singleRegistration.injector));
301
331
  }
302
332
  if ((options.onlySelf != true) && isNotNull(this.#parent)) {
303
333
  return this.#parent._resolve(token, argument, options, context, chain);
@@ -316,10 +346,10 @@ export class Injector {
316
346
  }
317
347
  return this.#parent?._resolveAll(token, argument, { ...options, skipSelf: skipSelf - 1 }, context, chain) ?? [];
318
348
  }
319
- if (isDefined(options.forwardRef) && (options.forwardRef != false)) {
320
- const forwardToken = isFunction(options.forwardRef) ? options.forwardRef() : token;
321
- const forwardRef = ForwardRef.create({ typeHint: options.forwardRefTypeHint ?? isFunction(forwardToken) ? forwardToken : undefined });
322
- context.forwardRefQueue.add(() => ForwardRef.setRef(forwardRef, this._resolveAll(forwardToken, argument, { ...options, forwardRef: false }, context, chain.markAsForwardRef(forwardToken))));
349
+ if (isForwardRefToken(token)) {
350
+ const forwardToken = token.tokenFactory();
351
+ const forwardRef = ForwardRef.create({ typeHint: token.typeHint ?? (isFunction(forwardToken) ? forwardToken : undefined) });
352
+ context.forwardRefQueue.add(() => ForwardRef.setRef(forwardRef, this._resolveAll(forwardToken, argument, { ...options }, context, chain.markAsForwardRef(forwardToken))));
323
353
  context.forwardRefs.add(forwardRef);
324
354
  return forwardRef;
325
355
  }
@@ -329,7 +359,7 @@ export class Injector {
329
359
  const registration = this.tryGetRegistration(token);
330
360
  if (isDefined(registration)) {
331
361
  const registrations = isArray(registration) ? registration : [registration];
332
- return registrations.map((reg) => this._resolveRegistration(reg, argument, options, context, chain));
362
+ return registrations.map((reg) => this._resolveRegistration(reg, argument, options, context, chain.withResolvedBy(reg.injector)));
333
363
  }
334
364
  if ((options.onlySelf != true) && isNotNull(this.#parent)) {
335
365
  return this.#parent._resolveAll(token, argument, { ...options, skipSelf: false }, context, chain);
@@ -351,18 +381,22 @@ export class Injector {
351
381
  resolveArgument = wrapInResolveError(() => registration.options.defaultArgumentProvider(this.getResolveContext(resolutionTag, context, chain)), 'Error in defaultArgumentProvider', chain);
352
382
  }
353
383
  const argumentIdentity = resolveArgumentIdentity(registration, resolveArgument, chain);
384
+ chain = chain.withArgument(resolveArgument).withMetadata({ registration });
354
385
  if (resolutionScoped && context.resolutionScopedResolutions.hasFlat(token, argumentIdentity)) {
386
+ context.recordAccess(chain.withMetadata({ isCached: true }));
355
387
  return context.resolutionScopedResolutions.getFlat(token, argumentIdentity).value;
356
388
  }
357
389
  else if (injectorScoped && this.#injectorScopedResolutions.hasFlat(token, argumentIdentity)) {
390
+ context.recordAccess(chain.withMetadata({ isCached: true }));
358
391
  return this.#injectorScopedResolutions.getFlat(token, argumentIdentity).value;
359
392
  }
360
393
  else if (singletonScoped && registration.resolutions.has(argumentIdentity)) {
394
+ context.recordAccess(chain.withMetadata({ isCached: true }));
361
395
  return registration.resolutions.get(argumentIdentity);
362
396
  }
363
397
  // A new scope is only needed if we are instantiating a class, running a factory, or if the registration explicitly defines scoped providers.
364
398
  const needsNewScope = isClassProvider(provider) || isFactoryProvider(provider) || (providers.length > 0);
365
- const injector = needsNewScope ? this.fork(`[${getTokenName(token)}]Injector`) : this;
399
+ const injector = needsNewScope ? this.fork(`${getTokenName(token)}Injector`, token) : this;
366
400
  for (const nestedProvider of providers) {
367
401
  injector.registerSingleton(nestedProvider.provide, nestedProvider, { multi: nestedProvider.multi });
368
402
  }
@@ -371,6 +405,8 @@ export class Injector {
371
405
  try {
372
406
  const resolutionContext = { afterResolveRegistrations: [] };
373
407
  const value = injector._resolveProvider(resolutionTag, registration, resolveArgument, options, context, resolutionContext, injectionContext, chain);
408
+ chain = chain.withMetadata({ isCached: false });
409
+ context.recordAccess(chain);
374
410
  const resolution = {
375
411
  tag: resolutionTag,
376
412
  registration,
@@ -444,27 +480,18 @@ export class Injector {
444
480
  }
445
481
  }
446
482
  resolveClassInjection(resolutionTag, context, constructor, metadata, resolveArgument, chain) {
447
- const getChain = (injectToken) => chain.addParameter(this, constructor, metadata.index, injectToken);
448
483
  const injectMetadata = metadata.data.tryGet(injectMetadataSymbol) ?? {};
449
484
  const injectToken = (injectMetadata.injectToken ?? metadata.type);
485
+ const getChain = (injectToken) => chain.addParameter(this, constructor, metadata.index, injectToken, { optional: injectMetadata.optional, multi: injectMetadata.resolveAll });
450
486
  if (isDefined(injectMetadata.injectArgumentMapper) && (!this.hasRegistration(injectToken) || isDefined(resolveArgument) || isUndefined(injectToken))) {
451
487
  return wrapInResolveError(() => injectMetadata.injectArgumentMapper(resolveArgument), 'Error in injectArgumentMapper', getChain(injectToken));
452
488
  }
453
489
  const parameterResolveArgument = wrapInResolveError(() => injectMetadata.forwardArgumentMapper?.(resolveArgument) ?? injectMetadata.resolveArgumentProvider?.(this.getResolveContext(resolutionTag, context, getChain(injectToken))), 'Error in parameter argument provider (forwardArgumentMapper or resolveArgumentProvider)', getChain(injectToken));
454
- const { forwardRef } = injectMetadata;
455
- if (isDefined(forwardRef) && isDefined(injectMetadata.mapper)) {
456
- const forwardToken = isFunction(forwardRef) ? forwardRef() : isBoolean(forwardRef) ? injectToken : forwardRef;
457
- throw new ResolveError('Cannot use inject mapper with forwardRef.', getChain(forwardToken));
458
- }
459
490
  const resolveFn = (injectMetadata.resolveAll == true) ? '_resolveAll' : '_resolve';
460
- const resolved = this[resolveFn](injectToken, parameterResolveArgument, { optional: injectMetadata.optional, forwardRef, forwardRefTypeHint: injectMetadata.forwardRefTypeHint }, context, getChain(injectToken));
461
- if (isDefined(injectMetadata.mapper)) {
462
- return wrapInResolveError(() => injectMetadata.mapper(resolved), 'Error in inject mapper', getChain(injectToken));
463
- }
464
- return resolved;
491
+ return this[resolveFn](injectToken, parameterResolveArgument, { optional: injectMetadata.optional }, context, getChain(injectToken));
465
492
  }
466
493
  resolveInjection(token, argument, options, context, injectIndex, chain) {
467
- return this._resolve(token, argument, options, context, chain.addInject(this, token, injectIndex));
494
+ return this._resolve(token, argument, options, context, chain.addInject(this, token, injectIndex, { optional: options.optional }));
468
495
  }
469
496
  async resolveInjectionAsync(token, argument, options, context, injectIndex, chain) {
470
497
  const value = this.resolveInjection(token, argument, options, context, injectIndex, chain);
@@ -472,7 +499,7 @@ export class Injector {
472
499
  return value;
473
500
  }
474
501
  resolveInjectionAll(token, argument, options, context, injectIndex, chain) {
475
- return this._resolveAll(token, argument, options, context, chain.addInject(this, token, injectIndex));
502
+ return this._resolveAll(token, argument, options, context, chain.addInject(this, token, injectIndex, { optional: options.optional, multi: true }));
476
503
  }
477
504
  async resolveInjectionAllAsync(token, argument, options, context, injectIndex, chain) {
478
505
  const values = this.resolveInjectionAll(token, argument, options, context, injectIndex, chain);
@@ -484,7 +511,7 @@ export class Injector {
484
511
  resolve: (token, argument, options) => this._resolve(token, argument, options ?? {}, resolveContext, chain.addToken(this, token)),
485
512
  resolveAll: (token, argument, options) => this._resolveAll(token, argument, options ?? {}, resolveContext, chain.addToken(this, token)),
486
513
  cancellationSignal: this.#disposeToken,
487
- addDisposeHandler: this.#addDisposeHandler,
514
+ addDisposeHandler: (handler) => this.addDisposeHandler(handler),
488
515
  get data() {
489
516
  return resolveContext.resolutionContextData.get(resolutionTag);
490
517
  },
@@ -493,7 +520,7 @@ export class Injector {
493
520
  getAfterResolveContext(resolutionTag, resolveContext) {
494
521
  return {
495
522
  cancellationSignal: this.#disposeToken,
496
- addDisposeHandler: this.#addDisposeHandler,
523
+ addDisposeHandler: (handler) => this.addDisposeHandler(handler),
497
524
  get data() {
498
525
  return resolveContext.resolutionContextData.get(resolutionTag);
499
526
  },
@@ -536,24 +563,41 @@ function addRegistration(registrations, registration) {
536
563
  const tokenName = getTokenName(registration.token);
537
564
  throw new RegistrationError(`Cannot mix multi and non-multi registrations for token: ${tokenName}.`);
538
565
  }
539
- if (multi && existingIsMulti) {
540
- existingRegistration.push(registration);
566
+ if (multi) {
567
+ if (existingIsMulti) {
568
+ existingRegistration.push(registration);
569
+ }
570
+ else {
571
+ registrations.set(registration.token, [registration]);
572
+ }
541
573
  }
542
574
  else {
543
- registrations.set(registration.token, multi ? [registration] : registration);
575
+ registrations.set(registration.token, registration);
544
576
  }
545
577
  }
546
- function newInternalResolveContext() {
547
- return {
578
+ function newInternalResolveContext(injector) {
579
+ const context = {
548
580
  resolves: 0,
549
581
  resolving: new FactoryMap(() => new Set()),
550
582
  resolutionScopedResolutions: new MultiKeyMap(),
551
583
  resolutions: [],
584
+ accesses: [],
585
+ recordAccess(chain) {
586
+ context.accesses.push({ chain });
587
+ if (isDevMode()) {
588
+ let current = injector;
589
+ while (current != null) {
590
+ current.accesses.push({ chain });
591
+ current = current.parent;
592
+ }
593
+ }
594
+ },
552
595
  resolutionContextData: new FactoryMap(() => ({})),
553
596
  forwardRefQueue: new CircularBuffer(),
554
597
  forwardRefs: new Set(),
555
598
  $done: new DeferredPromise(),
556
599
  };
600
+ return context;
557
601
  }
558
602
  function postProcess(context) {
559
603
  for (const fn of context.forwardRefQueue.consume()) {