ts-ioc-container 72.0.0 → 72.2.0

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 (235) hide show
  1. package/AGENTS.md +179 -0
  2. package/README.md +94 -0
  3. package/cjm/container/Container.js +2 -2
  4. package/cjm/container/EmptyContainer.js +17 -15
  5. package/cjm/errors/ArgumentNotFoundError.js +1 -0
  6. package/cjm/errors/CannonSingletonApplyTwiceError.js +2 -14
  7. package/cjm/errors/CannotApplySingletonTwiceError.js +18 -0
  8. package/cjm/errors/ContainerDisposedError.js +1 -0
  9. package/cjm/errors/ContainerError.js +1 -0
  10. package/cjm/errors/ContainerNotFoundError.js +1 -0
  11. package/cjm/errors/DependencyMissingKeyError.js +1 -0
  12. package/cjm/errors/DependencyNotFoundError.js +1 -0
  13. package/cjm/errors/MethodNotImplementedError.js +1 -0
  14. package/cjm/errors/ProviderDisposedError.js +1 -0
  15. package/cjm/errors/TypedEventDisposedError.js +1 -0
  16. package/cjm/errors/UnsupportedTokenTypeError.js +1 -0
  17. package/cjm/index.js +8 -3
  18. package/cjm/metadata/class.js +3 -1
  19. package/cjm/metadata/method.js +3 -1
  20. package/cjm/metadata/parameter.js +7 -1
  21. package/cjm/provider/Provider.js +6 -6
  22. package/cjm/registration/Registration.js +2 -2
  23. package/cjm/token/ConstantToken.js +4 -4
  24. package/cjm/token/FunctionToken.js +1 -1
  25. package/cjm/token/GroupInstanceToken.js +4 -4
  26. package/cjm/token/toToken.js +1 -1
  27. package/cjm/utils/TypedEvent.js +1 -1
  28. package/cjm/utils/array.js +1 -1
  29. package/esm/container/Container.js +2 -2
  30. package/esm/container/EmptyContainer.js +17 -15
  31. package/esm/errors/ArgumentNotFoundError.js +1 -0
  32. package/esm/errors/CannonSingletonApplyTwiceError.js +2 -13
  33. package/esm/errors/CannotApplySingletonTwiceError.js +14 -0
  34. package/esm/errors/ContainerDisposedError.js +1 -0
  35. package/esm/errors/ContainerError.js +1 -0
  36. package/esm/errors/ContainerNotFoundError.js +1 -0
  37. package/esm/errors/DependencyMissingKeyError.js +1 -0
  38. package/esm/errors/DependencyNotFoundError.js +1 -0
  39. package/esm/errors/MethodNotImplementedError.js +1 -0
  40. package/esm/errors/ProviderDisposedError.js +1 -0
  41. package/esm/errors/TypedEventDisposedError.js +1 -0
  42. package/esm/errors/UnsupportedTokenTypeError.js +1 -0
  43. package/esm/index.js +4 -3
  44. package/esm/metadata/class.js +1 -0
  45. package/esm/metadata/method.js +1 -0
  46. package/esm/metadata/parameter.js +5 -0
  47. package/esm/provider/Provider.js +6 -6
  48. package/esm/registration/Registration.js +2 -2
  49. package/esm/token/ConstantToken.js +4 -4
  50. package/esm/token/FunctionToken.js +1 -1
  51. package/esm/token/GroupInstanceToken.js +4 -4
  52. package/esm/token/toToken.js +1 -1
  53. package/esm/utils/TypedEvent.js +1 -1
  54. package/esm/utils/array.js +1 -1
  55. package/lib/ExecutionContext.ts +6 -0
  56. package/lib/container/AliasMap.ts +30 -0
  57. package/lib/container/AutoResolveModule.ts +24 -0
  58. package/lib/container/Container.ts +311 -0
  59. package/lib/container/EmptyContainer.ts +166 -0
  60. package/lib/container/IContainer.ts +156 -0
  61. package/lib/errors/ArgumentNotFoundError.ts +13 -0
  62. package/lib/errors/CannonSingletonApplyTwiceError.ts +6 -0
  63. package/lib/errors/CannotApplySingletonTwiceError.ts +22 -0
  64. package/lib/errors/ContainerDisposedError.ts +13 -0
  65. package/lib/errors/ContainerError.ts +15 -0
  66. package/lib/errors/ContainerNotFoundError.ts +13 -0
  67. package/lib/errors/DependencyMissingKeyError.ts +13 -0
  68. package/lib/errors/DependencyNotFoundError.ts +13 -0
  69. package/lib/errors/MethodNotImplementedError.ts +13 -0
  70. package/lib/errors/ProviderDisposedError.ts +22 -0
  71. package/lib/errors/TypedEventDisposedError.ts +22 -0
  72. package/lib/errors/UnsupportedTokenTypeError.ts +13 -0
  73. package/lib/hooks/HookCollector.ts +109 -0
  74. package/lib/hooks/HookContext.ts +85 -0
  75. package/lib/hooks/combinators.ts +51 -0
  76. package/lib/hooks/hook.ts +89 -0
  77. package/lib/hooks/injectProp.ts +14 -0
  78. package/lib/index.ts +181 -0
  79. package/lib/injector/IInjector.ts +88 -0
  80. package/lib/injector/MetadataInjector.ts +100 -0
  81. package/lib/injector/ProxyInjector.ts +31 -0
  82. package/lib/injector/SimpleInjector.ts +20 -0
  83. package/lib/metadata/class.ts +50 -0
  84. package/lib/metadata/method.ts +47 -0
  85. package/lib/metadata/parameter.ts +60 -0
  86. package/lib/metadata/target.ts +25 -0
  87. package/lib/provider/IProvider.ts +65 -0
  88. package/lib/provider/Provider.ts +174 -0
  89. package/lib/registration/IRegistration.ts +235 -0
  90. package/lib/registration/Registration.ts +122 -0
  91. package/lib/select.ts +33 -0
  92. package/lib/token/BindToken.ts +13 -0
  93. package/lib/token/ClassToken.ts +72 -0
  94. package/lib/token/ConstantToken.ts +50 -0
  95. package/lib/token/FunctionToken.ts +79 -0
  96. package/lib/token/GroupAliasToken.ts +92 -0
  97. package/lib/token/GroupInstanceToken.ts +70 -0
  98. package/lib/token/InjectionToken.ts +46 -0
  99. package/lib/token/SingleAliasToken.ts +84 -0
  100. package/lib/token/SingleToken.ts +93 -0
  101. package/lib/token/toToken.ts +46 -0
  102. package/lib/utils/ProxyRegistry.ts +149 -0
  103. package/lib/utils/TypedEvent.ts +96 -0
  104. package/lib/utils/array.ts +28 -0
  105. package/lib/utils/basic.ts +34 -0
  106. package/lib/utils/debounce.ts +18 -0
  107. package/lib/utils/errorHandler.ts +34 -0
  108. package/lib/utils/fp.ts +86 -0
  109. package/lib/utils/getConstructorChain.ts +17 -0
  110. package/lib/utils/memoize.ts +24 -0
  111. package/lib/utils/once.ts +24 -0
  112. package/lib/utils/shallowCache.ts +22 -0
  113. package/lib/utils/task.ts +33 -0
  114. package/lib/utils/throttle.ts +17 -0
  115. package/package.json +5 -3
  116. package/typings/ExecutionContext.d.ts +2 -0
  117. package/typings/ExecutionContext.d.ts.map +1 -0
  118. package/typings/container/AliasMap.d.ts +1 -0
  119. package/typings/container/AliasMap.d.ts.map +1 -0
  120. package/typings/container/AutoResolveModule.d.ts +16 -0
  121. package/typings/container/AutoResolveModule.d.ts.map +1 -0
  122. package/typings/container/Container.d.ts +60 -0
  123. package/typings/container/Container.d.ts.map +1 -0
  124. package/typings/container/EmptyContainer.d.ts +51 -0
  125. package/typings/container/EmptyContainer.d.ts.map +1 -0
  126. package/typings/container/IContainer.d.ts +75 -0
  127. package/typings/container/IContainer.d.ts.map +1 -0
  128. package/typings/errors/ArgumentNotFoundError.d.ts +3 -0
  129. package/typings/errors/ArgumentNotFoundError.d.ts.map +1 -0
  130. package/typings/errors/CannonSingletonApplyTwiceError.d.ts +6 -6
  131. package/typings/errors/CannonSingletonApplyTwiceError.d.ts.map +1 -0
  132. package/typings/errors/CannotApplySingletonTwiceError.d.ts +12 -0
  133. package/typings/errors/CannotApplySingletonTwiceError.d.ts.map +1 -0
  134. package/typings/errors/ContainerDisposedError.d.ts +3 -0
  135. package/typings/errors/ContainerDisposedError.d.ts.map +1 -0
  136. package/typings/errors/ContainerError.d.ts +7 -0
  137. package/typings/errors/ContainerError.d.ts.map +1 -0
  138. package/typings/errors/ContainerNotFoundError.d.ts +3 -0
  139. package/typings/errors/ContainerNotFoundError.d.ts.map +1 -0
  140. package/typings/errors/DependencyMissingKeyError.d.ts +3 -0
  141. package/typings/errors/DependencyMissingKeyError.d.ts.map +1 -0
  142. package/typings/errors/DependencyNotFoundError.d.ts +3 -0
  143. package/typings/errors/DependencyNotFoundError.d.ts.map +1 -0
  144. package/typings/errors/MethodNotImplementedError.d.ts +3 -0
  145. package/typings/errors/MethodNotImplementedError.d.ts.map +1 -0
  146. package/typings/errors/ProviderDisposedError.d.ts +6 -0
  147. package/typings/errors/ProviderDisposedError.d.ts.map +1 -0
  148. package/typings/errors/TypedEventDisposedError.d.ts +6 -0
  149. package/typings/errors/TypedEventDisposedError.d.ts.map +1 -0
  150. package/typings/errors/UnsupportedTokenTypeError.d.ts +3 -0
  151. package/typings/errors/UnsupportedTokenTypeError.d.ts.map +1 -0
  152. package/typings/hooks/HookCollector.d.ts +36 -0
  153. package/typings/hooks/HookCollector.d.ts.map +1 -0
  154. package/typings/hooks/HookContext.d.ts +10 -0
  155. package/typings/hooks/HookContext.d.ts.map +1 -0
  156. package/typings/hooks/combinators.d.ts +23 -0
  157. package/typings/hooks/combinators.d.ts.map +1 -0
  158. package/typings/hooks/hook.d.ts +39 -0
  159. package/typings/hooks/hook.d.ts.map +1 -0
  160. package/typings/hooks/injectProp.d.ts +9 -0
  161. package/typings/hooks/injectProp.d.ts.map +1 -0
  162. package/typings/index.d.ts +5 -3
  163. package/typings/index.d.ts.map +1 -0
  164. package/typings/injector/IInjector.d.ts +32 -0
  165. package/typings/injector/IInjector.d.ts.map +1 -0
  166. package/typings/injector/MetadataInjector.d.ts +58 -0
  167. package/typings/injector/MetadataInjector.d.ts.map +1 -0
  168. package/typings/injector/ProxyInjector.d.ts +13 -0
  169. package/typings/injector/ProxyInjector.d.ts.map +1 -0
  170. package/typings/injector/SimpleInjector.d.ts +13 -0
  171. package/typings/injector/SimpleInjector.d.ts.map +1 -0
  172. package/typings/metadata/class.d.ts +28 -0
  173. package/typings/metadata/class.d.ts.map +1 -0
  174. package/typings/metadata/method.d.ts +25 -0
  175. package/typings/metadata/method.d.ts.map +1 -0
  176. package/typings/metadata/parameter.d.ts +22 -0
  177. package/typings/metadata/parameter.d.ts.map +1 -0
  178. package/typings/metadata/target.d.ts +19 -0
  179. package/typings/metadata/target.d.ts.map +1 -0
  180. package/typings/provider/IProvider.d.ts +25 -0
  181. package/typings/provider/IProvider.d.ts.map +1 -0
  182. package/typings/provider/Provider.d.ts +30 -0
  183. package/typings/provider/Provider.d.ts.map +1 -0
  184. package/typings/registration/IRegistration.d.ts +137 -0
  185. package/typings/registration/IRegistration.d.ts.map +1 -0
  186. package/typings/registration/Registration.d.ts +23 -0
  187. package/typings/registration/Registration.d.ts.map +1 -0
  188. package/typings/select.d.ts +15 -0
  189. package/typings/select.d.ts.map +1 -0
  190. package/typings/token/BindToken.d.ts +3 -0
  191. package/typings/token/BindToken.d.ts.map +1 -0
  192. package/typings/token/ClassToken.d.ts +2 -0
  193. package/typings/token/ClassToken.d.ts.map +1 -0
  194. package/typings/token/ConstantToken.d.ts +14 -0
  195. package/typings/token/ConstantToken.d.ts.map +1 -0
  196. package/typings/token/FunctionToken.d.ts +10 -0
  197. package/typings/token/FunctionToken.d.ts.map +1 -0
  198. package/typings/token/GroupAliasToken.d.ts +14 -0
  199. package/typings/token/GroupAliasToken.d.ts.map +1 -0
  200. package/typings/token/GroupInstanceToken.d.ts +19 -0
  201. package/typings/token/GroupInstanceToken.d.ts.map +1 -0
  202. package/typings/token/InjectionToken.d.ts +8 -0
  203. package/typings/token/InjectionToken.d.ts.map +1 -0
  204. package/typings/token/SingleAliasToken.d.ts +6 -0
  205. package/typings/token/SingleAliasToken.d.ts.map +1 -0
  206. package/typings/token/SingleToken.d.ts +18 -0
  207. package/typings/token/SingleToken.d.ts.map +1 -0
  208. package/typings/token/toToken.d.ts +12 -0
  209. package/typings/token/toToken.d.ts.map +1 -0
  210. package/typings/utils/ProxyRegistry.d.ts +63 -0
  211. package/typings/utils/ProxyRegistry.d.ts.map +1 -0
  212. package/typings/utils/TypedEvent.d.ts +42 -0
  213. package/typings/utils/TypedEvent.d.ts.map +1 -0
  214. package/typings/utils/array.d.ts +7 -0
  215. package/typings/utils/array.d.ts.map +1 -0
  216. package/typings/utils/basic.d.ts +12 -0
  217. package/typings/utils/basic.d.ts.map +1 -0
  218. package/typings/utils/debounce.d.ts +2 -0
  219. package/typings/utils/debounce.d.ts.map +1 -0
  220. package/typings/utils/errorHandler.d.ts +4 -0
  221. package/typings/utils/errorHandler.d.ts.map +1 -0
  222. package/typings/utils/fp.d.ts +8 -0
  223. package/typings/utils/fp.d.ts.map +1 -0
  224. package/typings/utils/getConstructorChain.d.ts +9 -0
  225. package/typings/utils/getConstructorChain.d.ts.map +1 -0
  226. package/typings/utils/memoize.d.ts +10 -0
  227. package/typings/utils/memoize.d.ts.map +1 -0
  228. package/typings/utils/once.d.ts +2 -0
  229. package/typings/utils/once.d.ts.map +1 -0
  230. package/typings/utils/shallowCache.d.ts +2 -0
  231. package/typings/utils/shallowCache.d.ts.map +1 -0
  232. package/typings/utils/task.d.ts +13 -0
  233. package/typings/utils/task.d.ts.map +1 -0
  234. package/typings/utils/throttle.d.ts +2 -0
  235. package/typings/utils/throttle.d.ts.map +1 -0
@@ -0,0 +1,96 @@
1
+ import { TypedEventDisposedError } from '../errors/TypedEventDisposedError';
2
+
3
+ export type TypedEventListener<TArgs extends unknown[]> = (...args: TArgs) => void;
4
+
5
+ export type Unsubscribe = () => void;
6
+
7
+ /**
8
+ * The subscriber's side of a {@link TypedEvent}: attach, detach, tear down.
9
+ * Hand this out instead of the event itself so that only the owner can `emit`.
10
+ */
11
+ export interface ITypedEvent<TArgs extends unknown[]> {
12
+ /**
13
+ * Attaches `listener` and returns a function which detaches it again. A
14
+ * listener subscribed more than once is still delivered each emission once.
15
+ *
16
+ * @throws {TypedEventDisposedError} when the event has already been disposed.
17
+ */
18
+ subscribe(listener: TypedEventListener<TArgs>): Unsubscribe;
19
+
20
+ /**
21
+ * Detaches `listener`. Harmless when it is not subscribed, or after `dispose`.
22
+ */
23
+ unsubscribe(listener: TypedEventListener<TArgs>): void;
24
+
25
+ /**
26
+ * Detaches every listener and rejects further `subscribe` / `emit` calls.
27
+ */
28
+ dispose(): void;
29
+ }
30
+
31
+ /**
32
+ * A typed, multi-listener event. `TArgs` is the argument list a listener
33
+ * receives, so a `TypedEvent<[IContainer]>` accepts `(scope: IContainer) => void`
34
+ * listeners unchanged.
35
+ *
36
+ * Emission delivers to the listeners subscribed at the moment `emit` is called,
37
+ * in subscription order. A listener detached mid-emission is skipped for the
38
+ * rest of that emission; one attached mid-emission receives only later ones.
39
+ */
40
+ export class TypedEvent<TArgs extends unknown[] = []> implements ITypedEvent<TArgs> {
41
+ private readonly listeners = new Set<TypedEventListener<TArgs>>();
42
+ private isDisposed = false;
43
+
44
+ /**
45
+ * @throws {TypedEventDisposedError} when the event has already been disposed.
46
+ */
47
+ subscribe(listener: TypedEventListener<TArgs>): Unsubscribe {
48
+ this.validate();
49
+ this.listeners.add(listener);
50
+ return () => this.unsubscribe(listener);
51
+ }
52
+
53
+ unsubscribe(listener: TypedEventListener<TArgs>): void {
54
+ this.listeners.delete(listener);
55
+ }
56
+
57
+ /**
58
+ * Calls every current listener with `args`. What a listener throws surfaces
59
+ * out of `emit` and stops delivery to the listeners after it.
60
+ *
61
+ * @throws {TypedEventDisposedError} when the event has already been disposed.
62
+ * @throws {unknown} rethrows whatever a listener threw.
63
+ */
64
+ emit(...args: TArgs): void {
65
+ this.validate();
66
+ // Iterate a snapshot so a listener can (un)subscribe without disturbing this emission;
67
+ // a listener detached mid-emission is still skipped for the rest of it.
68
+ for (const listener of [...this.listeners]) {
69
+ if (this.listeners.has(listener)) {
70
+ listener(...args);
71
+ }
72
+ }
73
+ }
74
+
75
+ /**
76
+ * A copy of the current listeners, in subscription order.
77
+ */
78
+ getListeners(): TypedEventListener<TArgs>[] {
79
+ return [...this.listeners];
80
+ }
81
+
82
+ dispose(): void {
83
+ this.listeners.clear();
84
+ this.isDisposed = true;
85
+ }
86
+
87
+ /**
88
+ * @throws {TypedEventDisposedError} when the event has already been disposed.
89
+ */
90
+ private validate(): void {
91
+ TypedEventDisposedError.assert(
92
+ !this.isDisposed,
93
+ 'TypedEvent is already disposed: its scope was disposed, so it accepts no new listeners.',
94
+ );
95
+ }
96
+ }
@@ -0,0 +1,28 @@
1
+ import { ArgumentNotFoundError } from '../errors/ArgumentNotFoundError';
2
+
3
+ export type Predicate<T> = (value: T) => boolean;
4
+
5
+ export const Filter = {
6
+ exclude: <T>(arr: Set<T> | T[]) => {
7
+ const excludeSet = arr instanceof Array ? new Set(arr) : arr;
8
+ return (v: T) => !excludeSet.has(v);
9
+ },
10
+ };
11
+
12
+ /**
13
+ * Returns a picker of the first argument in `args` matching `predicate` - the
14
+ * shape `singleton(getCacheKey)` consumers expect.
15
+ *
16
+ * @throws {ArgumentNotFoundError} when no argument matches `predicate`
17
+ */
18
+ export const findOrFail =
19
+ <T>(predicate: Predicate<T>) =>
20
+ (args: unknown[] = []): T => {
21
+ const index = args.findIndex((arg) => predicate(arg as T));
22
+
23
+ if (index === -1) {
24
+ throw new ArgumentNotFoundError(`No argument matches the predicate (received ${args.length} args).`);
25
+ }
26
+
27
+ return args[index] as T;
28
+ };
@@ -0,0 +1,34 @@
1
+ /** A class that constructs `T`. */
2
+ export type constructor<T> = new (...args: any[]) => T;
3
+
4
+ /** Something with a meaningful `toString()`, e.g. a token used as a cache key. */
5
+ export interface Serializable {
6
+ toString(): string;
7
+ }
8
+
9
+ /**
10
+ * Tags a structural type with a name, so `Instance` reads as its own type in
11
+ * signatures and error messages instead of a bare `object`. The tag is optional
12
+ * on purpose: values stay assignable without a cast.
13
+ */
14
+ export type Branded<TBrand extends string, T> = T & { readonly __brand?: TBrand };
15
+
16
+ /**
17
+ * What the container tracks and reflects on: the object a constructor produced.
18
+ * Deliberately not a constructor signature - an instance is not its own constructor.
19
+ */
20
+ export type Instance = Branded<'Instance', object>;
21
+
22
+ export const Is = {
23
+ nullish: <T>(value: T | undefined | null): value is null | undefined => value === undefined || value === null,
24
+ object: (target: unknown): target is object => target !== null && typeof target === 'object',
25
+ instance: (target: unknown): target is Instance => Object.prototype.hasOwnProperty.call(target, 'constructor'),
26
+ constructor: (target: unknown): target is constructor<unknown> => typeof target === 'function' && !!target.prototype,
27
+ };
28
+
29
+ // Every object inherits `Object.prototype.toString`, so only an overridden one counts as serialization.
30
+ export function isSerializable(target: unknown): target is Serializable {
31
+ return Is.object(target) && typeof target.toString === 'function' && target.toString !== Object.prototype.toString;
32
+ }
33
+
34
+ export const toString = (target: unknown): string => (isSerializable(target) ? target.toString() : String(target));
@@ -0,0 +1,18 @@
1
+ /** Method decorator: delays the call until `ms` passed without another call (per instance). */
2
+ export const debounce =
3
+ (ms: number): MethodDecorator =>
4
+ (target, propertyKey, descriptor: PropertyDescriptor) => {
5
+ const originalMethod = descriptor.value;
6
+ const timerMap = new WeakMap<object, ReturnType<typeof setTimeout>>();
7
+ descriptor.value = function (...args: unknown[]) {
8
+ const prev = timerMap.get(this);
9
+ if (prev !== undefined) {
10
+ clearTimeout(prev);
11
+ }
12
+ timerMap.set(
13
+ this,
14
+ setTimeout(() => originalMethod.apply(this, args), ms),
15
+ );
16
+ };
17
+ return descriptor;
18
+ };
@@ -0,0 +1,34 @@
1
+ import { resolveConstructor } from '../metadata/target';
2
+
3
+ /** Receives the error with the class and method it came from. */
4
+ export type HandleErrorParams = (error: unknown, context: { target: string; method: string }) => void;
5
+
6
+ /** Method decorator: routes a rejection of the async method to `errorHandler` instead of throwing. */
7
+ export const handleAsyncError =
8
+ (errorHandler: HandleErrorParams): MethodDecorator =>
9
+ (target, propertyKey, descriptor: PropertyDescriptor) => {
10
+ const originalMethod = descriptor.value;
11
+ descriptor.value = async function (...args: unknown[]) {
12
+ try {
13
+ return await originalMethod.apply(this, args);
14
+ } catch (e) {
15
+ errorHandler(e, { target: resolveConstructor(target).name, method: propertyKey as string });
16
+ }
17
+ };
18
+ return descriptor;
19
+ };
20
+
21
+ /** Method decorator: routes a throw of the method to `errorHandler` instead of throwing. */
22
+ export const handleError =
23
+ (errorHandler: HandleErrorParams): MethodDecorator =>
24
+ (target, propertyKey, descriptor: PropertyDescriptor) => {
25
+ const originalMethod = descriptor.value;
26
+ descriptor.value = function (...args: unknown[]) {
27
+ try {
28
+ return originalMethod.apply(this, args);
29
+ } catch (e) {
30
+ errorHandler(e, { target: resolveConstructor(target).name, method: propertyKey as string });
31
+ }
32
+ };
33
+ return descriptor;
34
+ };
@@ -0,0 +1,86 @@
1
+ /** A one-argument transform. */
2
+ export type MapFn<A, B = A> = (value: A) => B;
3
+
4
+ // Overloads for fp function to support up to 10 transformations
5
+ /**
6
+ * Composes functions left to right. With `by(...)` it maps an injected value.
7
+ *
8
+ * @example
9
+ * @inject(pipe(by(ConfigToken), (config) => config.apiUrl))
10
+ */
11
+ export function pipe<A>(fn1: MapFn<A>): MapFn<A>;
12
+ export function pipe<A, B>(fn1: MapFn<A, B>): MapFn<A, B>;
13
+ export function pipe<A, B, C>(fn1: MapFn<A, B>, fn2: MapFn<B, C>): MapFn<A, C>;
14
+ export function pipe<A, B, C, D>(fn1: MapFn<A, B>, fn2: MapFn<B, C>, fn3: MapFn<C, D>): MapFn<A, D>;
15
+ export function pipe<A, B, C, D, E>(
16
+ fn1: MapFn<A, B>,
17
+ fn2: MapFn<B, C>,
18
+ fn3: MapFn<C, D>,
19
+ fn4: MapFn<D, E>,
20
+ ): MapFn<A, E>;
21
+ export function pipe<A, B, C, D, E, F>(
22
+ fn1: MapFn<A, B>,
23
+ fn2: MapFn<B, C>,
24
+ fn3: MapFn<C, D>,
25
+ fn4: MapFn<D, E>,
26
+ fn5: MapFn<E, F>,
27
+ ): MapFn<A, F>;
28
+ export function pipe<A, B, C, D, E, F, G>(
29
+ fn1: MapFn<A, B>,
30
+ fn2: MapFn<B, C>,
31
+ fn3: MapFn<C, D>,
32
+ fn4: MapFn<D, E>,
33
+ fn5: MapFn<E, F>,
34
+ fn6: MapFn<F, G>,
35
+ ): MapFn<A, G>;
36
+ export function pipe<A, B, C, D, E, F, G, H>(
37
+ fn1: MapFn<A, B>,
38
+ fn2: MapFn<B, C>,
39
+ fn3: MapFn<C, D>,
40
+ fn4: MapFn<D, E>,
41
+ fn5: MapFn<E, F>,
42
+ fn6: MapFn<F, G>,
43
+ fn7: MapFn<G, H>,
44
+ ): MapFn<A, H>;
45
+ export function pipe<A, B, C, D, E, F, G, H, I>(
46
+ fn1: MapFn<A, B>,
47
+ fn2: MapFn<B, C>,
48
+ fn3: MapFn<C, D>,
49
+ fn4: MapFn<D, E>,
50
+ fn5: MapFn<E, F>,
51
+ fn6: MapFn<F, G>,
52
+ fn7: MapFn<G, H>,
53
+ fn8: MapFn<H, I>,
54
+ ): MapFn<A, I>;
55
+ export function pipe<A, B, C, D, E, F, G, H, I, J>(
56
+ fn1: MapFn<A, B>,
57
+ fn2: MapFn<B, C>,
58
+ fn3: MapFn<C, D>,
59
+ fn4: MapFn<D, E>,
60
+ fn5: MapFn<E, F>,
61
+ fn6: MapFn<F, G>,
62
+ fn7: MapFn<G, H>,
63
+ fn8: MapFn<H, I>,
64
+ fn9: MapFn<I, J>,
65
+ ): MapFn<A, J>;
66
+ export function pipe<A, B, C, D, E, F, G, H, I, J, K>(
67
+ fn1: MapFn<A, B>,
68
+ fn2: MapFn<B, C>,
69
+ fn3: MapFn<C, D>,
70
+ fn4: MapFn<D, E>,
71
+ fn5: MapFn<E, F>,
72
+ fn6: MapFn<F, G>,
73
+ fn7: MapFn<G, H>,
74
+ fn8: MapFn<H, I>,
75
+ fn9: MapFn<I, J>,
76
+ fn10: MapFn<J, K>,
77
+ ): MapFn<A, K>;
78
+ // Fallback for cases where pipes are used with spreads or variable length (same type)
79
+
80
+ export function pipe<T>(...mappers: MapFn<T>[]): MapFn<T>;
81
+ // Implementation
82
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
83
+ export function pipe(...mappers: MapFn<any, any>[]): MapFn<any, any> {
84
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
+ return (value: any) => mappers.reduce((acc, current) => current(acc), value);
86
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Walks a constructor's prototype chain, most-derived first, and collects each
3
+ * class in it: `[Derived, Base, ...]`, stopping before `Function.prototype`.
4
+ *
5
+ * Reading own metadata off each entry in turn is how a class inherits what its
6
+ * ancestors declared — `Reflect.getOwnMetadata` never looks up the chain itself.
7
+ * Anything which is not a function yields an empty chain.
8
+ */
9
+ export const getConstructorChain = (ctor: unknown): object[] => {
10
+ const chain: object[] = [];
11
+ let current = ctor;
12
+ while (typeof current === 'function' && current !== Function.prototype) {
13
+ chain.push(current);
14
+ current = Object.getPrototypeOf(current);
15
+ }
16
+ return chain;
17
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Wraps a two-argument function so each `(target, key)` pair is computed once
3
+ * and reused. `target` is held weakly, so memoizing against a class or an
4
+ * instance keeps nothing alive.
5
+ *
6
+ * ```typescript
7
+ * const hooksOf = memoize((Target: constructor<unknown>, key: string | symbol) => merge(Target, key));
8
+ * ```
9
+ */
10
+ export const memoize = <T extends object, K, R>(fn: (target: T, key: K) => R): ((target: T, key: K) => R) => {
11
+ const cache = new WeakMap<T, Map<K, R>>();
12
+
13
+ return (target, key) => {
14
+ let byKey = cache.get(target);
15
+ if (!byKey) {
16
+ byKey = new Map();
17
+ cache.set(target, byKey);
18
+ }
19
+ if (!byKey.has(key)) {
20
+ byKey.set(key, fn(target, key));
21
+ }
22
+ return byKey.get(key) as R;
23
+ };
24
+ };
@@ -0,0 +1,24 @@
1
+ type RepeatOptions = {
2
+ index: number;
3
+ args: unknown[];
4
+ };
5
+
6
+ /** Method decorator: runs the method once per instance and returns the cached result afterwards. */
7
+ export const once =
8
+ ({ onRepeat }: { onRepeat?: (options: RepeatOptions) => void } = {}): MethodDecorator =>
9
+ (target, propertyKey, descriptor: PropertyDescriptor) => {
10
+ const originalMethod = descriptor.value;
11
+ const cacheMap = new WeakMap<object, unknown>();
12
+ let index = 0;
13
+ descriptor.value = function (...args: unknown[]) {
14
+ index++;
15
+ if (cacheMap.has(this)) {
16
+ onRepeat?.({ index: index - 1, args });
17
+ return cacheMap.get(this);
18
+ }
19
+ const result = originalMethod.apply(this, args);
20
+ cacheMap.set(this, result);
21
+ return result;
22
+ };
23
+ return descriptor;
24
+ };
@@ -0,0 +1,22 @@
1
+ /** Method decorator: caches results per instance by the key `getKeyByArgs` returns. */
2
+ export const shallowCache =
3
+ (getKeyByArgs: (...args: unknown[]) => unknown): MethodDecorator =>
4
+ (target, propertyKey, descriptor: PropertyDescriptor) => {
5
+ const originalMethod = descriptor.value;
6
+ const cacheMap = new WeakMap<object, Map<unknown, unknown>>();
7
+ descriptor.value = function (...args: unknown[]) {
8
+ let cache = cacheMap.get(this);
9
+ if (cache === undefined) {
10
+ cache = new Map();
11
+ cacheMap.set(this, cache);
12
+ }
13
+ const key = getKeyByArgs(...args);
14
+ if (cache.has(key)) {
15
+ return cache.get(key);
16
+ }
17
+ const result = originalMethod.apply(this, args);
18
+ cache.set(key, result);
19
+ return result;
20
+ };
21
+ return descriptor;
22
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * A unit of work which may or may not go async: the sync-until-async shape the
3
+ * hook machinery is built on (ADR 0013).
4
+ */
5
+ export type Task = () => void | Promise<void>;
6
+
7
+ /**
8
+ * Runs `tasks` in order, staying synchronous until one returns a promise and
9
+ * awaiting the rest from that point. `undefined` when none went async.
10
+ */
11
+ export const runInOrder = (tasks: Task[], from = 0): void | Promise<void> => {
12
+ for (let i = from; i < tasks.length; i++) {
13
+ const result = tasks[i]();
14
+ if (result instanceof Promise) {
15
+ return result.then(() => runInOrder(tasks, i + 1));
16
+ }
17
+ }
18
+ };
19
+
20
+ /**
21
+ * Starts every task at once. Settles once all have; `undefined` when none went
22
+ * async, so a fully synchronous run hands back no promise.
23
+ */
24
+ export const runAtOnce = (tasks: Task[]): void | Promise<void> => {
25
+ const pending: Promise<void>[] = [];
26
+ for (const task of tasks) {
27
+ const result = task();
28
+ if (result instanceof Promise) {
29
+ pending.push(result);
30
+ }
31
+ }
32
+ return pending.length > 0 ? Promise.all(pending).then(() => undefined) : undefined;
33
+ };
@@ -0,0 +1,17 @@
1
+ /** Method decorator: ignores calls within `ms` of the last accepted one (per instance). */
2
+ export const throttle =
3
+ (ms: number): MethodDecorator =>
4
+ (target, propertyKey, descriptor: PropertyDescriptor) => {
5
+ const originalMethod = descriptor.value;
6
+ const lastCalledMap = new WeakMap<object, number>();
7
+ descriptor.value = function (...args: unknown[]) {
8
+ const now = Date.now();
9
+ const lastCalled = lastCalledMap.get(this) ?? -Infinity;
10
+ if (now - lastCalled < ms) {
11
+ return undefined;
12
+ }
13
+ lastCalledMap.set(this, now);
14
+ return originalMethod.apply(this, args);
15
+ };
16
+ return descriptor;
17
+ };
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "72.0.0",
3
+ "version": "72.2.0",
4
4
  "description": "Fast, lightweight TypeScript dependency injection container with a clean API, scoped lifecycles, decorators, tokens, hooks, lazy injection, customizable providers, and no global container objects.",
5
5
  "publishConfig": {
6
6
  "access": "public",
7
7
  "registry": "https://registry.npmjs.org/"
8
8
  },
9
9
  "author": "ibabkin <igba14@gmail.com>",
10
- "homepage": "https://igorbabkin.github.io/ts-ioc-container",
10
+ "homepage": "https://github.com/IgorBabkin/ts-ioc-container/tree/main/packages/ts-ioc-container#readme",
11
11
  "license": "ISC",
12
12
  "sideEffects": false,
13
13
  "main": "cjm/index.js",
@@ -54,7 +54,9 @@
54
54
  "files": [
55
55
  "cjm/**/*",
56
56
  "esm/**/*",
57
- "typings/**/*"
57
+ "typings/**/*",
58
+ "lib/**/*",
59
+ "AGENTS.md"
58
60
  ],
59
61
  "repository": {
60
62
  "type": "git",
@@ -1,4 +1,6 @@
1
1
  import type { IContainer } from './container/IContainer.js';
2
+ /** General execution context passed to callbacks that run within a scope. */
2
3
  export interface ExecutionContext {
3
4
  scope: IContainer;
4
5
  }
6
+ //# sourceMappingURL=ExecutionContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExecutionContext.d.ts","sourceRoot":"","sources":["../lib/ExecutionContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,UAAU,CAAC;CACnB"}
@@ -6,3 +6,4 @@ export declare class AliasMap {
6
6
  setAliasesByKey(key: DependencyKey, aliases: DependencyKey[]): void;
7
7
  destroy(): void;
8
8
  }
9
+ //# sourceMappingURL=AliasMap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AliasMap.d.ts","sourceRoot":"","sources":["../../lib/container/AliasMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,MAAM,KAAK,GAAG,aAAa,CAAC;AAElC,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwC;IAEtE,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,EAAE;IAIrD,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI;IAenE,OAAO,IAAI,IAAI;CAGhB"}
@@ -1,6 +1,22 @@
1
1
  import { type AutoResolveOptions, type IContainer, type IContainerModule } from './IContainer.js';
2
+ /**
3
+ * Enables eager resolution of providers marked with the `autoResolve()` pipe.
4
+ *
5
+ * Every scope created after this module is applied resolves its own
6
+ * auto-resolvable providers as part of `createScope`, so the instances exist
7
+ * before anyone asks for them. Child scopes inherit the behaviour, so a single
8
+ * `useModule` call on the root covers the whole scope tree.
9
+ *
10
+ * `options.args` are forwarded to every eagerly resolved provider of every such
11
+ * scope. Pass a per-scope value by calling `scope.autoResolve({ args })`
12
+ * directly instead.
13
+ *
14
+ * The container the module is applied to is not a created scope — call
15
+ * `container.autoResolve()` explicitly to eagerly resolve its own providers.
16
+ */
2
17
  export declare class AutoResolveModule implements IContainerModule {
3
18
  private readonly options;
4
19
  constructor(options?: AutoResolveOptions);
5
20
  applyTo(container: IContainer): void;
6
21
  }
22
+ //# sourceMappingURL=AutoResolveModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutoResolveModule.d.ts","sourceRoot":"","sources":["../../lib/container/AutoResolveModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAE/F;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAkB,YAAW,gBAAgB;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE,kBAAuB;IAE7D,OAAO,CAAC,SAAS,EAAE,UAAU,GAAG,IAAI;CAGrC"}
@@ -4,6 +4,22 @@ import { type IProvider } from '../provider/IProvider.js';
4
4
  import { type IRegistration } from '../registration/IRegistration.js';
5
5
  import { constructor, Instance } from '../utils/basic.js';
6
6
  import { type ITypedEvent } from '../utils/TypedEvent.js';
7
+ /**
8
+ * A dependency injection scope. Each container is a node in a parent chain:
9
+ * a key not found here (or denied by `scopeAccess`) is resolved from the parent,
10
+ * and the root's parent is an {@link EmptyContainer} that throws
11
+ * `DependencyNotFoundError`. Child scopes come from `createScope({ tags })`,
12
+ * which copies the matching registrations into the child at that moment.
13
+ *
14
+ * @example
15
+ * const app = new Container({ tags: ['application'] })
16
+ * .addRegistration(Registration.fromClass(Logger))
17
+ * .addRegistration(Registration.fromValue(config).bindTo('Config'));
18
+ *
19
+ * const request = app.createScope({ tags: ['request'] });
20
+ * const logger = ILoggerToken.resolve(request);
21
+ * request.dispose();
22
+ */
7
23
  export declare class Container implements IContainer {
8
24
  isDisposed: boolean;
9
25
  private parent;
@@ -25,12 +41,40 @@ export declare class Container implements IContainer {
25
41
  parent?: IContainer;
26
42
  tags?: Tag[];
27
43
  });
44
+ /**
45
+ * @throws {ContainerDisposedError} when the container has already been disposed.
46
+ */
28
47
  register(key: DependencyKey, provider: IProvider, { aliases }?: RegisterOptions): this;
48
+ /**
49
+ * @throws {ContainerDisposedError} when the container has already been disposed.
50
+ * @throws {DependencyNotFoundError} when `target` cannot be resolved in this container or any parent scope.
51
+ */
29
52
  resolve<T>(target: constructor<T> | DependencyKey, { args, child, lazy }?: ResolveOneOptions): T;
53
+ /**
54
+ * @throws {ContainerDisposedError} when the container has already been disposed.
55
+ * @throws {DependencyNotFoundError} when a key registered under `alias` has no matching provider.
56
+ */
30
57
  resolveByAlias<T>(alias: DependencyKey, { args, child, lazy, excludedKeys }?: ResolveManyOptions): T[];
58
+ /**
59
+ * @throws {ContainerDisposedError} when the container has already been disposed.
60
+ * @throws {DependencyNotFoundError} when `alias` cannot be resolved in this container or any parent scope.
61
+ */
31
62
  resolveOneByAlias<T>(alias: DependencyKey, { args, child, lazy }?: ResolveOneOptions): T;
63
+ /**
64
+ * @throws {ContainerDisposedError} when the container has already been disposed.
65
+ */
32
66
  createScope({ tags }?: CreateScopeOptions): IContainer;
67
+ /**
68
+ * Eagerly resolves every provider of this scope which was marked with `autoResolve()`.
69
+ *
70
+ * `args` are forwarded to each of those providers, exactly as `resolve` forwards them.
71
+ *
72
+ * @throws {ContainerDisposedError} when the container has already been disposed.
73
+ */
33
74
  autoResolve({ args }?: AutoResolveOptions): this;
75
+ /**
76
+ * @throws {ContainerDisposedError} when the container has already been disposed.
77
+ */
34
78
  dispose(): void;
35
79
  addRegistration(registration: IRegistration): this;
36
80
  getRegistrations(): IRegistration[];
@@ -38,6 +82,15 @@ export declare class Container implements IContainer {
38
82
  hasRegistration(key: DependencyKey): boolean;
39
83
  addInstance(instance: Instance): void;
40
84
  getScopes(): IContainer[];
85
+ /**
86
+ * Whether this scope created `instance`.
87
+ *
88
+ * A proxy stands for the object behind it, so it is unwrapped before the
89
+ * lookup - the container tracks real instances, and a caller asking about a
90
+ * proxy is asking about its target. Resolving a lazy proxy's target is what
91
+ * makes that answer possible, so a still-unresolved lazy proxy is resolved
92
+ * here.
93
+ */
41
94
  hasInstance(instance: Instance): boolean;
42
95
  removeScope(child: IContainer): void;
43
96
  useModule(module: IContainerModule): this;
@@ -45,6 +98,13 @@ export declare class Container implements IContainer {
45
98
  getInstances(cascade?: boolean): Instance[];
46
99
  hasTag(tag: Tag): boolean;
47
100
  addTags(...tags: Tag[]): void;
101
+ /**
102
+ * @throws {ContainerDisposedError} when the container has already been disposed.
103
+ */
48
104
  private validateContainer;
105
+ /**
106
+ * @throws {DependencyNotFoundError} when no provider is registered under `key` in this container.
107
+ */
49
108
  private findProviderByKeyOrFail;
50
109
  }
110
+ //# sourceMappingURL=Container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Container.d.ts","sourceRoot":"","sources":["../../lib/container/Container.ts"],"names":[],"mappings":"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"}