@navios/di 0.8.0 → 0.9.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 (264) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/README.md +117 -17
  3. package/lib/browser/container/abstract-container.d.mts +112 -0
  4. package/lib/browser/container/abstract-container.d.mts.map +1 -0
  5. package/lib/browser/container/abstract-container.mjs +100 -0
  6. package/lib/browser/container/abstract-container.mjs.map +1 -0
  7. package/lib/browser/container/container.d.mts +100 -0
  8. package/lib/browser/container/container.d.mts.map +1 -0
  9. package/lib/browser/container/container.mjs +424 -0
  10. package/lib/browser/container/container.mjs.map +1 -0
  11. package/lib/browser/container/scoped-container.d.mts +93 -0
  12. package/lib/browser/container/scoped-container.d.mts.map +1 -0
  13. package/lib/browser/container/scoped-container.mjs +119 -0
  14. package/lib/browser/container/scoped-container.mjs.map +1 -0
  15. package/lib/browser/decorators/factory.decorator.d.mts +26 -0
  16. package/lib/browser/decorators/factory.decorator.d.mts.map +1 -0
  17. package/lib/browser/decorators/factory.decorator.mjs +20 -0
  18. package/lib/browser/decorators/factory.decorator.mjs.map +1 -0
  19. package/lib/browser/decorators/injectable.decorator.d.mts +38 -0
  20. package/lib/browser/decorators/injectable.decorator.d.mts.map +1 -0
  21. package/lib/browser/decorators/injectable.decorator.mjs +21 -0
  22. package/lib/browser/decorators/injectable.decorator.mjs.map +1 -0
  23. package/lib/browser/enums/injectable-scope.enum.d.mts +18 -0
  24. package/lib/browser/enums/injectable-scope.enum.d.mts.map +1 -0
  25. package/lib/browser/enums/injectable-scope.enum.mjs +20 -0
  26. package/lib/browser/enums/injectable-scope.enum.mjs.map +1 -0
  27. package/lib/browser/enums/injectable-type.enum.d.mts +8 -0
  28. package/lib/browser/enums/injectable-type.enum.d.mts.map +1 -0
  29. package/lib/browser/enums/injectable-type.enum.mjs +10 -0
  30. package/lib/browser/enums/injectable-type.enum.mjs.map +1 -0
  31. package/lib/browser/errors/di-error.d.mts +43 -0
  32. package/lib/browser/errors/di-error.d.mts.map +1 -0
  33. package/lib/browser/errors/di-error.mjs +98 -0
  34. package/lib/browser/errors/di-error.mjs.map +1 -0
  35. package/lib/browser/event-emitter.d.mts +16 -0
  36. package/lib/browser/event-emitter.d.mts.map +1 -0
  37. package/lib/browser/event-emitter.mjs +320 -0
  38. package/lib/browser/event-emitter.mjs.map +1 -0
  39. package/lib/browser/index.d.mts +37 -1558
  40. package/lib/browser/index.mjs +29 -2749
  41. package/lib/browser/interfaces/container.interface.d.mts +59 -0
  42. package/lib/browser/interfaces/container.interface.d.mts.map +1 -0
  43. package/lib/browser/interfaces/factory.interface.d.mts +14 -0
  44. package/lib/browser/interfaces/factory.interface.d.mts.map +1 -0
  45. package/lib/browser/interfaces/on-service-destroy.interface.d.mts +7 -0
  46. package/lib/browser/interfaces/on-service-destroy.interface.d.mts.map +1 -0
  47. package/lib/browser/interfaces/on-service-init.interface.d.mts +7 -0
  48. package/lib/browser/interfaces/on-service-init.interface.d.mts.map +1 -0
  49. package/lib/browser/internal/context/async-local-storage.browser.mjs +20 -0
  50. package/lib/browser/internal/context/async-local-storage.browser.mjs.map +1 -0
  51. package/lib/browser/internal/context/async-local-storage.d.mts +9 -0
  52. package/lib/browser/internal/context/async-local-storage.d.mts.map +1 -0
  53. package/lib/browser/internal/context/async-local-storage.types.d.mts +11 -0
  54. package/lib/browser/internal/context/async-local-storage.types.d.mts.map +1 -0
  55. package/lib/browser/internal/context/factory-context.d.mts +23 -0
  56. package/lib/browser/internal/context/factory-context.d.mts.map +1 -0
  57. package/lib/browser/internal/context/resolution-context.d.mts +43 -0
  58. package/lib/browser/internal/context/resolution-context.d.mts.map +1 -0
  59. package/lib/browser/internal/context/resolution-context.mjs +56 -0
  60. package/lib/browser/internal/context/resolution-context.mjs.map +1 -0
  61. package/lib/browser/internal/context/service-initialization-context.d.mts +48 -0
  62. package/lib/browser/internal/context/service-initialization-context.d.mts.map +1 -0
  63. package/lib/browser/internal/context/sync-local-storage.mjs +53 -0
  64. package/lib/browser/internal/context/sync-local-storage.mjs.map +1 -0
  65. package/lib/browser/internal/core/instance-resolver.d.mts +119 -0
  66. package/lib/browser/internal/core/instance-resolver.d.mts.map +1 -0
  67. package/lib/browser/internal/core/instance-resolver.mjs +306 -0
  68. package/lib/browser/internal/core/instance-resolver.mjs.map +1 -0
  69. package/lib/browser/internal/core/name-resolver.d.mts +52 -0
  70. package/lib/browser/internal/core/name-resolver.d.mts.map +1 -0
  71. package/lib/browser/internal/core/name-resolver.mjs +118 -0
  72. package/lib/browser/internal/core/name-resolver.mjs.map +1 -0
  73. package/lib/browser/internal/core/scope-tracker.d.mts +65 -0
  74. package/lib/browser/internal/core/scope-tracker.d.mts.map +1 -0
  75. package/lib/browser/internal/core/scope-tracker.mjs +120 -0
  76. package/lib/browser/internal/core/scope-tracker.mjs.map +1 -0
  77. package/lib/browser/internal/core/service-initializer.d.mts +44 -0
  78. package/lib/browser/internal/core/service-initializer.d.mts.map +1 -0
  79. package/lib/browser/internal/core/service-initializer.mjs +109 -0
  80. package/lib/browser/internal/core/service-initializer.mjs.map +1 -0
  81. package/lib/browser/internal/core/service-invalidator.d.mts +81 -0
  82. package/lib/browser/internal/core/service-invalidator.d.mts.map +1 -0
  83. package/lib/browser/internal/core/service-invalidator.mjs +142 -0
  84. package/lib/browser/internal/core/service-invalidator.mjs.map +1 -0
  85. package/lib/browser/internal/core/token-resolver.d.mts +54 -0
  86. package/lib/browser/internal/core/token-resolver.d.mts.map +1 -0
  87. package/lib/browser/internal/core/token-resolver.mjs +77 -0
  88. package/lib/browser/internal/core/token-resolver.mjs.map +1 -0
  89. package/lib/browser/internal/holder/holder-storage.interface.d.mts +99 -0
  90. package/lib/browser/internal/holder/holder-storage.interface.d.mts.map +1 -0
  91. package/lib/browser/internal/holder/instance-holder.d.mts +101 -0
  92. package/lib/browser/internal/holder/instance-holder.d.mts.map +1 -0
  93. package/lib/browser/internal/holder/instance-holder.mjs +19 -0
  94. package/lib/browser/internal/holder/instance-holder.mjs.map +1 -0
  95. package/lib/browser/internal/holder/unified-storage.d.mts +53 -0
  96. package/lib/browser/internal/holder/unified-storage.d.mts.map +1 -0
  97. package/lib/browser/internal/holder/unified-storage.mjs +144 -0
  98. package/lib/browser/internal/holder/unified-storage.mjs.map +1 -0
  99. package/lib/browser/internal/lifecycle/circular-detector.d.mts +39 -0
  100. package/lib/browser/internal/lifecycle/circular-detector.d.mts.map +1 -0
  101. package/lib/browser/internal/lifecycle/circular-detector.mjs +55 -0
  102. package/lib/browser/internal/lifecycle/circular-detector.mjs.map +1 -0
  103. package/lib/browser/internal/lifecycle/lifecycle-event-bus.d.mts +18 -0
  104. package/lib/browser/internal/lifecycle/lifecycle-event-bus.d.mts.map +1 -0
  105. package/lib/browser/internal/lifecycle/lifecycle-event-bus.mjs +43 -0
  106. package/lib/browser/internal/lifecycle/lifecycle-event-bus.mjs.map +1 -0
  107. package/lib/browser/internal/stub-factory-class.d.mts +14 -0
  108. package/lib/browser/internal/stub-factory-class.d.mts.map +1 -0
  109. package/lib/browser/internal/stub-factory-class.mjs +18 -0
  110. package/lib/browser/internal/stub-factory-class.mjs.map +1 -0
  111. package/lib/browser/symbols/injectable-token.d.mts +5 -0
  112. package/lib/browser/symbols/injectable-token.d.mts.map +1 -0
  113. package/lib/browser/symbols/injectable-token.mjs +6 -0
  114. package/lib/browser/symbols/injectable-token.mjs.map +1 -0
  115. package/lib/browser/token/injection-token.d.mts +55 -0
  116. package/lib/browser/token/injection-token.d.mts.map +1 -0
  117. package/lib/browser/token/injection-token.mjs +100 -0
  118. package/lib/browser/token/injection-token.mjs.map +1 -0
  119. package/lib/browser/token/registry.d.mts +37 -0
  120. package/lib/browser/token/registry.d.mts.map +1 -0
  121. package/lib/browser/token/registry.mjs +86 -0
  122. package/lib/browser/token/registry.mjs.map +1 -0
  123. package/lib/browser/utils/default-injectors.d.mts +12 -0
  124. package/lib/browser/utils/default-injectors.d.mts.map +1 -0
  125. package/lib/browser/utils/default-injectors.mjs +13 -0
  126. package/lib/browser/utils/default-injectors.mjs.map +1 -0
  127. package/lib/browser/utils/get-injectable-token.d.mts +9 -0
  128. package/lib/browser/utils/get-injectable-token.d.mts.map +1 -0
  129. package/lib/browser/utils/get-injectable-token.mjs +13 -0
  130. package/lib/browser/utils/get-injectable-token.mjs.map +1 -0
  131. package/lib/browser/utils/get-injectors.d.mts +55 -0
  132. package/lib/browser/utils/get-injectors.d.mts.map +1 -0
  133. package/lib/browser/utils/get-injectors.mjs +121 -0
  134. package/lib/browser/utils/get-injectors.mjs.map +1 -0
  135. package/lib/browser/utils/types.d.mts +23 -0
  136. package/lib/browser/utils/types.d.mts.map +1 -0
  137. package/lib/{container-DAKOvAgr.mjs → container-8-z89TyQ.mjs} +1325 -1462
  138. package/lib/container-8-z89TyQ.mjs.map +1 -0
  139. package/lib/{container-Bp1W-pWJ.d.mts → container-CNiqesCL.d.mts} +598 -617
  140. package/lib/container-CNiqesCL.d.mts.map +1 -0
  141. package/lib/{container-DENMeJ87.cjs → container-CaY2fDuk.cjs} +1369 -1512
  142. package/lib/container-CaY2fDuk.cjs.map +1 -0
  143. package/lib/{container-YPwvmlK2.d.cts → container-D-0Ho3qL.d.cts} +598 -612
  144. package/lib/container-D-0Ho3qL.d.cts.map +1 -0
  145. package/lib/index.cjs +13 -15
  146. package/lib/index.cjs.map +1 -1
  147. package/lib/index.d.cts +58 -223
  148. package/lib/index.d.cts.map +1 -1
  149. package/lib/index.d.mts +62 -222
  150. package/lib/index.d.mts.map +1 -1
  151. package/lib/index.mjs +5 -6
  152. package/lib/index.mjs.map +1 -1
  153. package/lib/testing/index.cjs +569 -311
  154. package/lib/testing/index.cjs.map +1 -1
  155. package/lib/testing/index.d.cts +370 -41
  156. package/lib/testing/index.d.cts.map +1 -1
  157. package/lib/testing/index.d.mts +370 -41
  158. package/lib/testing/index.d.mts.map +1 -1
  159. package/lib/testing/index.mjs +568 -305
  160. package/lib/testing/index.mjs.map +1 -1
  161. package/package.json +2 -1
  162. package/src/__tests__/circular-detector.spec.mts +193 -0
  163. package/src/__tests__/concurrent.spec.mts +368 -0
  164. package/src/__tests__/container.spec.mts +32 -30
  165. package/src/__tests__/di-error.spec.mts +351 -0
  166. package/src/__tests__/e2e.browser.spec.mts +0 -4
  167. package/src/__tests__/e2e.spec.mts +10 -19
  168. package/src/__tests__/event-emitter.spec.mts +232 -109
  169. package/src/__tests__/get-injectors.spec.mts +250 -39
  170. package/src/__tests__/injection-token.spec.mts +293 -349
  171. package/src/__tests__/library-findings.spec.mts +8 -8
  172. package/src/__tests__/registry.spec.mts +358 -210
  173. package/src/__tests__/resolution-context.spec.mts +255 -0
  174. package/src/__tests__/scope-tracker.spec.mts +598 -0
  175. package/src/__tests__/scope-upgrade.spec.mts +808 -0
  176. package/src/__tests__/scoped-container.spec.mts +595 -0
  177. package/src/__tests__/test-container.spec.mts +293 -0
  178. package/src/__tests__/token-resolver.spec.mts +207 -0
  179. package/src/__tests__/unified-storage.spec.mts +535 -0
  180. package/src/__tests__/unit-test-container.spec.mts +405 -0
  181. package/src/__type-tests__/container.spec-d.mts +180 -0
  182. package/src/__type-tests__/factory.spec-d.mts +15 -3
  183. package/src/__type-tests__/inject.spec-d.mts +115 -20
  184. package/src/__type-tests__/injectable.spec-d.mts +69 -52
  185. package/src/__type-tests__/injection-token.spec-d.mts +176 -0
  186. package/src/__type-tests__/scoped-container.spec-d.mts +212 -0
  187. package/src/container/abstract-container.mts +327 -0
  188. package/src/container/container.mts +142 -170
  189. package/src/container/scoped-container.mts +126 -208
  190. package/src/decorators/factory.decorator.mts +16 -11
  191. package/src/decorators/injectable.decorator.mts +20 -16
  192. package/src/enums/index.mts +2 -2
  193. package/src/enums/injectable-scope.enum.mts +1 -0
  194. package/src/enums/injectable-type.enum.mts +1 -0
  195. package/src/errors/di-error.mts +96 -0
  196. package/src/event-emitter.mts +3 -27
  197. package/src/index.mts +6 -153
  198. package/src/interfaces/container.interface.mts +13 -0
  199. package/src/interfaces/factory.interface.mts +1 -1
  200. package/src/interfaces/index.mts +1 -1
  201. package/src/internal/context/async-local-storage.mts +3 -2
  202. package/src/internal/context/async-local-storage.types.mts +1 -0
  203. package/src/internal/context/factory-context.mts +1 -0
  204. package/src/internal/context/index.mts +3 -1
  205. package/src/internal/context/resolution-context.mts +1 -0
  206. package/src/internal/context/service-initialization-context.mts +43 -0
  207. package/src/internal/core/index.mts +5 -4
  208. package/src/internal/core/instance-resolver.mts +460 -302
  209. package/src/internal/core/name-resolver.mts +196 -0
  210. package/src/internal/core/scope-tracker.mts +242 -0
  211. package/src/internal/core/{instantiator.mts → service-initializer.mts} +51 -29
  212. package/src/internal/core/service-invalidator.mts +290 -0
  213. package/src/internal/core/token-resolver.mts +122 -0
  214. package/src/internal/holder/holder-storage.interface.mts +11 -5
  215. package/src/internal/holder/index.mts +2 -5
  216. package/src/internal/holder/instance-holder.mts +1 -3
  217. package/src/internal/holder/unified-storage.mts +245 -0
  218. package/src/internal/index.mts +2 -1
  219. package/src/internal/lifecycle/circular-detector.mts +1 -0
  220. package/src/internal/lifecycle/index.mts +1 -1
  221. package/src/internal/lifecycle/lifecycle-event-bus.mts +1 -0
  222. package/src/internal/stub-factory-class.mts +16 -0
  223. package/src/symbols/injectable-token.mts +3 -1
  224. package/src/testing/index.mts +2 -0
  225. package/src/testing/test-container.mts +546 -85
  226. package/src/testing/types.mts +117 -0
  227. package/src/testing/unit-test-container.mts +509 -0
  228. package/src/token/injection-token.mts +41 -4
  229. package/src/token/registry.mts +75 -9
  230. package/src/utils/default-injectors.mts +16 -0
  231. package/src/utils/get-injectable-token.mts +2 -3
  232. package/src/utils/get-injectors.mts +26 -15
  233. package/src/utils/index.mts +3 -1
  234. package/src/utils/types.mts +1 -0
  235. package/tsdown.config.mts +11 -1
  236. package/lib/browser/index.d.mts.map +0 -1
  237. package/lib/browser/index.mjs.map +0 -1
  238. package/lib/container-Bp1W-pWJ.d.mts.map +0 -1
  239. package/lib/container-DAKOvAgr.mjs.map +0 -1
  240. package/lib/container-DENMeJ87.cjs.map +0 -1
  241. package/lib/container-YPwvmlK2.d.cts.map +0 -1
  242. package/src/__tests__/async-local-storage.browser.spec.mts +0 -166
  243. package/src/__tests__/async-local-storage.spec.mts +0 -333
  244. package/src/__tests__/errors.spec.mts +0 -87
  245. package/src/__tests__/factory.spec.mts +0 -137
  246. package/src/__tests__/injectable.spec.mts +0 -246
  247. package/src/__tests__/request-scope.spec.mts +0 -416
  248. package/src/__tests__/service-instantiator.spec.mts +0 -410
  249. package/src/__tests__/service-locator-event-bus.spec.mts +0 -242
  250. package/src/__tests__/service-locator-manager.spec.mts +0 -300
  251. package/src/__tests__/service-locator.spec.mts +0 -966
  252. package/src/__tests__/unified-api.spec.mts +0 -130
  253. package/src/browser.mts +0 -11
  254. package/src/injectors.mts +0 -18
  255. package/src/internal/context/request-context.mts +0 -225
  256. package/src/internal/core/invalidator.mts +0 -437
  257. package/src/internal/core/service-locator.mts +0 -202
  258. package/src/internal/core/token-processor.mts +0 -252
  259. package/src/internal/holder/base-holder-manager.mts +0 -334
  260. package/src/internal/holder/holder-manager.mts +0 -85
  261. package/src/internal/holder/request-storage.mts +0 -127
  262. package/src/internal/holder/singleton-storage.mts +0 -92
  263. package/src/testing/README.md +0 -80
  264. package/src/testing/__tests__/test-container.spec.mts +0 -173
@@ -1,127 +0,0 @@
1
- import type { RequestContext } from '../context/request-context.mjs'
2
- import type { BaseHolderManager } from './base-holder-manager.mjs'
3
- import type {
4
- HolderGetResult,
5
- IHolderStorage,
6
- } from './holder-storage.interface.mjs'
7
- import type { InstanceHolder } from './instance-holder.mjs'
8
-
9
- import { InjectableScope, InjectableType } from '../../enums/index.mjs'
10
- import { DIError } from '../../errors/index.mjs'
11
- import { InstanceStatus } from './instance-holder.mjs'
12
-
13
- /**
14
- * Storage implementation for Request-scoped services.
15
- *
16
- * Wraps a RequestContext instance from a ScopedContainer and provides
17
- * the IHolderStorage interface. This allows the InstanceResolver to work
18
- * with request-scoped storage using the same interface as singleton storage.
19
- */
20
- export class RequestStorage implements IHolderStorage {
21
- readonly scope = InjectableScope.Request
22
-
23
- constructor(
24
- private readonly contextHolder: RequestContext,
25
- private readonly holderManager: BaseHolderManager,
26
- ) {}
27
-
28
- get<T = unknown>(instanceName: string): HolderGetResult<T> {
29
- const holder = this.contextHolder.get(instanceName)
30
-
31
- if (!holder) {
32
- return null
33
- }
34
-
35
- // Check holder status for error states
36
- switch (holder.status) {
37
- case InstanceStatus.Destroying:
38
- return [
39
- DIError.instanceDestroying(instanceName),
40
- holder as InstanceHolder<T>,
41
- ]
42
-
43
- case InstanceStatus.Error:
44
- return [
45
- holder.instance as unknown as DIError,
46
- holder as InstanceHolder<T>,
47
- ]
48
-
49
- case InstanceStatus.Creating:
50
- case InstanceStatus.Created:
51
- return [undefined, holder as InstanceHolder<T>]
52
-
53
- default:
54
- return null
55
- }
56
- }
57
-
58
- set(instanceName: string, holder: InstanceHolder): void {
59
- this.contextHolder.set(instanceName, holder)
60
- }
61
-
62
- delete(instanceName: string): boolean {
63
- return this.contextHolder.delete(instanceName)
64
- }
65
-
66
- createHolder<T>(
67
- instanceName: string,
68
- type: InjectableType,
69
- deps: Set<string>,
70
- ): [
71
- ReturnType<typeof Promise.withResolvers<[undefined, T]>>,
72
- InstanceHolder<T>,
73
- ] {
74
- // Use the holderManager's createCreatingHolder method
75
- // which is inherited from BaseHolderManager
76
- return this.holderManager.createCreatingHolder<T>(
77
- instanceName,
78
- type,
79
- this.scope,
80
- deps,
81
- )
82
- }
83
-
84
- handles(scope: InjectableScope): boolean {
85
- return scope === InjectableScope.Request
86
- }
87
-
88
- // ============================================================================
89
- // ITERATION AND QUERY
90
- // ============================================================================
91
-
92
- getAllNames(): string[] {
93
- const names: string[] = []
94
- for (const [name] of this.contextHolder.holders) {
95
- names.push(name)
96
- }
97
- return names
98
- }
99
-
100
- forEach(callback: (name: string, holder: InstanceHolder) => void): void {
101
- for (const [name, holder] of this.contextHolder.holders) {
102
- callback(name, holder)
103
- }
104
- }
105
-
106
- findByInstance(instance: unknown): InstanceHolder | null {
107
- for (const holder of this.contextHolder.holders.values()) {
108
- if (holder.instance === instance) {
109
- return holder
110
- }
111
- }
112
- return null
113
- }
114
-
115
- findDependents(instanceName: string): string[] {
116
- // Get dependents from request context (O(1) using reverse index)
117
- const requestDependents = this.contextHolder.getDependents(instanceName)
118
-
119
- // Also check singleton holders - a singleton may depend on this request-scoped service
120
- const singletonDependents = this.holderManager.getDependents(instanceName)
121
-
122
- // Combine both arrays (avoid allocations if one is empty)
123
- if (requestDependents.length === 0) return singletonDependents
124
- if (singletonDependents.length === 0) return requestDependents
125
- return [...requestDependents, ...singletonDependents]
126
- }
127
- }
@@ -1,92 +0,0 @@
1
- import type { HolderManager } from './holder-manager.mjs'
2
- import type {
3
- HolderGetResult,
4
- IHolderStorage,
5
- } from './holder-storage.interface.mjs'
6
- import type { InstanceHolder } from './instance-holder.mjs'
7
-
8
- import { InjectableScope, InjectableType } from '../../enums/index.mjs'
9
- import { DIErrorCode } from '../../errors/index.mjs'
10
-
11
- /**
12
- * Storage implementation for Singleton-scoped services.
13
- *
14
- * Wraps a HolderManager instance and provides the IHolderStorage interface.
15
- * This allows the InstanceResolver to work with singleton storage
16
- * using the same interface as request-scoped storage.
17
- */
18
- export class SingletonStorage implements IHolderStorage {
19
- readonly scope = InjectableScope.Singleton
20
-
21
- constructor(private readonly manager: HolderManager) {}
22
-
23
- get<T = unknown>(instanceName: string): HolderGetResult<T> {
24
- const [error, holder] = this.manager.get(instanceName)
25
-
26
- if (!error) {
27
- return [undefined, holder as InstanceHolder<T>]
28
- }
29
-
30
- // Handle different error types
31
- switch (error.code) {
32
- case DIErrorCode.InstanceNotFound:
33
- return null
34
-
35
- case DIErrorCode.InstanceDestroying:
36
- return [error, holder as InstanceHolder<T> | undefined]
37
-
38
- default:
39
- return [error]
40
- }
41
- }
42
-
43
- set(instanceName: string, holder: InstanceHolder): void {
44
- this.manager.set(instanceName, holder)
45
- }
46
-
47
- delete(instanceName: string): boolean {
48
- return this.manager.delete(instanceName)
49
- }
50
-
51
- createHolder<T>(
52
- instanceName: string,
53
- type: InjectableType,
54
- deps: Set<string>,
55
- ): [
56
- ReturnType<typeof Promise.withResolvers<[undefined, T]>>,
57
- InstanceHolder<T>,
58
- ] {
59
- return this.manager.createCreatingHolder<T>(
60
- instanceName,
61
- type,
62
- this.scope,
63
- deps,
64
- )
65
- }
66
-
67
- handles(scope: InjectableScope): boolean {
68
- return scope === InjectableScope.Singleton
69
- }
70
-
71
- // ============================================================================
72
- // ITERATION AND QUERY
73
- // ============================================================================
74
-
75
- getAllNames(): string[] {
76
- return this.manager.getAllNames()
77
- }
78
-
79
- forEach(
80
- callback: (name: string, holder: InstanceHolder) => void,
81
- ): void {
82
- this.manager.forEachHolder((holder, name) => callback(name, holder))
83
- }
84
-
85
- findByInstance(instance: unknown): InstanceHolder | null {
86
- return this.manager.findHolder((h) => h.instance === instance) ?? null
87
- }
88
-
89
- findDependents(instanceName: string): string[] {
90
- return this.manager.getDependents(instanceName)
91
- }
92
- }
@@ -1,80 +0,0 @@
1
- # Testing Infrastructure
2
-
3
- The `@navios/di/testing` package provides a `TestContainer` class that extends the base `Container` with additional methods useful for testing.
4
-
5
- ## Features
6
-
7
- - **TestContainer**: A specialized container for testing with simplified binding methods
8
- - **bind().toValue()**: Bind tokens to specific values (useful for mocks)
9
- - **bind().toClass()**: Bind tokens to class constructors
10
- - **clear()**: Clear all instances and bindings from the container
11
- - **Convenience methods**: `bindValue()`, `bindClass()`, `createChild()`
12
-
13
- ## Usage
14
-
15
- ```typescript
16
- import { Injectable, InjectionToken } from '@navios/di'
17
- import { TestContainer } from '@navios/di/testing'
18
-
19
- // Create a test container
20
- const container = new TestContainer()
21
-
22
- // Create injection tokens
23
- const API_URL_TOKEN = InjectionToken.create<string>('api-url')
24
- const HTTP_CLIENT_TOKEN = InjectionToken.create<HttpClient>('http-client')
25
-
26
- // Mock implementations
27
- class MockHttpClient implements HttpClient {
28
- async get(url: string) {
29
- return { data: 'mocked response' }
30
- }
31
- }
32
-
33
- // Bind values for testing
34
- container.bindValue(API_URL_TOKEN, 'https://test-api.com')
35
- container.bindClass(HTTP_CLIENT_TOKEN, MockHttpClient)
36
-
37
- // Or use the fluent API
38
- container.bind(API_URL_TOKEN).toValue('https://test-api.com')
39
-
40
- container.bind(HTTP_CLIENT_TOKEN).toClass(MockHttpClient)
41
-
42
- // Bind a class to itself
43
- @Injectable()
44
- class UserService {
45
- constructor(
46
- @Inject(API_URL_TOKEN) private apiUrl: string,
47
- @Inject(HTTP_CLIENT_TOKEN) private httpClient: HttpClient,
48
- ) {}
49
- }
50
-
51
- container.bindSelf(UserService)
52
-
53
- // Clear the container between tests
54
- container.clear()
55
-
56
- // Create isolated child containers
57
- const childContainer = container.createChild()
58
- ```
59
-
60
- ## API Reference
61
-
62
- ### TestContainer
63
-
64
- #### Methods
65
-
66
- - `bind<T>(token: InjectionToken<T, any>): TestBindingBuilder<T>` - Creates a binding builder
67
- - `bind<T>(token: ClassType): TestBindingBuilder<T>` - Creates a binding builder
68
- - `bindValue<T>(token: InjectionToken<T, any>, value: T): TestContainer` - Binds a value to a token
69
- - `bindValue<T>(token: ClassType, value: T): TestContainer` - Binds a value to a token
70
- - `bindClass<T>(token: InjectionToken<T, any>, target: ClassType): TestContainer` - Binds a class to a token
71
- - `bindClass<T>(token: ClassType, target: ClassType): TestContainer` - Binds a class to a token
72
- - `createChild(): TestContainer` - Creates a new isolated test container
73
- - `clear(): void` - Clears all instances and bindings
74
-
75
- ### TestBindingBuilder
76
-
77
- #### Methods
78
-
79
- - `toValue(value: T): TestContainer` - Binds the token to a specific value
80
- - `toClass(target: ClassType): TestContainer` - Binds the token to a class constructor
@@ -1,173 +0,0 @@
1
- import { beforeEach, describe, expect, it } from 'vitest'
2
-
3
- import { Injectable } from '../../decorators/injectable.decorator.mjs'
4
- import { InjectionToken } from '../../token/injection-token.mjs'
5
- import { inject } from '../../injectors.mjs'
6
- import { TestContainer } from '../test-container.mjs'
7
-
8
- describe('TestContainer', () => {
9
- let container: TestContainer
10
-
11
- beforeEach(() => {
12
- container = new TestContainer()
13
- })
14
-
15
- describe('clear method', () => {
16
- it('should clear all instances from the container', () => {
17
- // This test verifies that the clear method exists and can be called
18
- expect(() => container.clear()).not.toThrow()
19
- })
20
- })
21
-
22
- describe('bind method', () => {
23
- it('should create a TestBindingBuilder', () => {
24
- const token = InjectionToken.create<string>('test-token')
25
- const builder = container.bind(token)
26
- expect(builder).toBeDefined()
27
- expect(builder).toHaveProperty('toValue')
28
- expect(builder).toHaveProperty('toClass')
29
- })
30
-
31
- it('should allow chaining bind operations', () => {
32
- const token = InjectionToken.create<string>('test-token')
33
- const result = container.bind(token).toValue('test-value')
34
- expect(result).toBe(container)
35
- })
36
-
37
- it('should bind value and retrieve it correctly', async () => {
38
- const token = InjectionToken.create<string>('test-token')
39
- const testValue = 'test-value'
40
-
41
- container.bind(token).toValue(testValue)
42
-
43
- const retrievedValue = await container.get(token)
44
- expect(retrievedValue).toBe(testValue)
45
- })
46
-
47
- it('should bind class and retrieve instance correctly', async () => {
48
- @Injectable()
49
- class TestService {
50
- getValue() {
51
- return 'test-service-value'
52
- }
53
- }
54
-
55
- const token = InjectionToken.create<TestService>('test-service')
56
-
57
- container.bind(token).toClass(TestService)
58
-
59
- const instance = await container.get(token)
60
- expect(instance).toBeInstanceOf(TestService)
61
- expect(instance.getValue()).toBe('test-service-value')
62
- })
63
- })
64
-
65
- describe('bindValue method', () => {
66
- it('should bind a value to a token', () => {
67
- const token = InjectionToken.create<string>('test-token')
68
- const result = container.bindValue(token, 'test-value')
69
- expect(result).toBe(container)
70
- })
71
-
72
- it('should bind value and retrieve it correctly', async () => {
73
- const token = InjectionToken.create<number>('number-token')
74
- const testValue = 42
75
-
76
- container.bindValue(token, testValue)
77
-
78
- const retrievedValue = await container.get(token)
79
- expect(retrievedValue).toBe(testValue)
80
- })
81
-
82
- it('should bind object value and retrieve it correctly', async () => {
83
- interface TestConfig {
84
- apiUrl: string
85
- timeout: number
86
- }
87
-
88
- const token = InjectionToken.create<TestConfig>('config-token')
89
- const testConfig: TestConfig = {
90
- apiUrl: 'https://api.example.com',
91
- timeout: 5000,
92
- }
93
-
94
- container.bindValue(token, testConfig)
95
-
96
- const retrievedConfig = await container.get(token)
97
- expect(retrievedConfig).toEqual(testConfig)
98
- expect(retrievedConfig.apiUrl).toBe('https://api.example.com')
99
- expect(retrievedConfig.timeout).toBe(5000)
100
- })
101
- })
102
-
103
- describe('bindClass method', () => {
104
- it('should bind a class to a token', () => {
105
- class TestClass {}
106
- const token = InjectionToken.create<TestClass>('test-token')
107
- const result = container.bindClass(token, TestClass)
108
- expect(result).toBe(container)
109
- })
110
-
111
- it('should bind class and retrieve instance correctly', async () => {
112
- @Injectable()
113
- class UserService {
114
- private users: string[] = ['alice', 'bob']
115
-
116
- getUsers() {
117
- return this.users
118
- }
119
-
120
- addUser(user: string) {
121
- this.users.push(user)
122
- }
123
- }
124
-
125
- const token = InjectionToken.create<UserService>('user-service')
126
-
127
- container.bindClass(token, UserService)
128
-
129
- const instance = await container.get(token)
130
- expect(instance).toBeInstanceOf(UserService)
131
- expect(instance.getUsers()).toEqual(['alice', 'bob'])
132
-
133
- instance.addUser('charlie')
134
- expect(instance.getUsers()).toEqual(['alice', 'bob', 'charlie'])
135
- })
136
-
137
- it('should bind class with dependencies and retrieve instance correctly', async () => {
138
- @Injectable()
139
- class DatabaseService {
140
- connect() {
141
- return 'connected'
142
- }
143
- }
144
-
145
- @Injectable()
146
- class UserRepository {
147
- db = inject(DatabaseService)
148
-
149
- findUser(id: string) {
150
- return `User ${id} from ${this.db.connect()}`
151
- }
152
- }
153
-
154
- const dbToken = InjectionToken.create<DatabaseService>('db-service')
155
- const userRepoToken = InjectionToken.create<UserRepository>('user-repo')
156
-
157
- container.bindClass(dbToken, DatabaseService)
158
- container.bindClass(userRepoToken, UserRepository)
159
-
160
- const userRepo = await container.get(userRepoToken)
161
- expect(userRepo).toBeInstanceOf(UserRepository)
162
- expect(userRepo.findUser('123')).toBe('User 123 from connected')
163
- })
164
- })
165
-
166
- describe('createChild method', () => {
167
- it('should create a new TestContainer instance', () => {
168
- const child = container.createChild()
169
- expect(child).toBeInstanceOf(TestContainer)
170
- expect(child).not.toBe(container)
171
- })
172
- })
173
- })