@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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container-8-z89TyQ.mjs","names":["simpleHash","str","hash","i","length","char","charCodeAt","Math","abs","toString","generateTokenId","name","customId","base","split","InjectionToken","id","formattedName","schema","create","bound","token","value","BoundInjectionToken","factory","FactoryInjectionToken","refineType","className","resolved","resolve","ctx","Registry","factories","Map","highestPriority","parent","has","token","id","get","factory","Error","toString","getAll","records","length","sort","a","b","priority","set","scope","target","type","record","originalToken","existing","push","currentHighest","delete","deletedHighest","remaining","filter","r","newHighest","reduce","max","current","updateScope","forEach","highest","globalRegistry","InjectableScope","InjectableType","InjectableTokenMeta","InjectionToken","globalRegistry","Injectable","scope","Singleton","token","schema","registry","priority","target","context","kind","Function","Error","injectableToken","create","set","Class","DIErrorCode","DIError","Error","context","code","message","name","factoryNotFound","factoryTokenNotResolved","token","toString","instanceNotFound","instanceDestroying","unknown","parent","circularDependency","cycle","cycleStr","join","tokenValidationError","schema","value","tokenSchemaRequiredError","classNotInjectable","className","scopeMismatchError","expectedScope","actualScope","priorityConflictError","records","storageError","operation","instanceName","initializationError","serviceName","error","dependencyResolutionError","dependencyName","isProduction","loadedModule: {\n createAsyncLocalStorage: <T>() => IAsyncLocalStorage<T>\n isUsingNativeAsyncLocalStorage: () => boolean\n} | null","createAsyncLocalStorage","resolutionContext","getResolutionContext","withResolutionContext","waiterHolder","getHolder","fn","run","getCurrentResolutionContext","getStore","withoutResolutionContext","undefined","isProduction","process","env","NODE_ENV","CircularDetector","detectCycle","waiterName","targetName","getHolder","visited","Set","queue","name","path","length","currentName","shift","has","add","holder","waitingForName","waitingFor","push","formatCycle","cycle","join","InjectableScope","DIError","DIErrorCode","FactoryInjectionToken","getCurrentResolutionContext","withResolutionContext","InstanceStatus","CircularDetector","InstanceResolver","registry","storage","serviceInitializer","tokenResolver","nameResolver","scopeTracker","serviceInvalidator","eventBus","logger","resolveInstance","token","args","contextContainer","requestStorage","requestId","resolveWithStorage","undefined","resolveRequestScopedInstance","scopedContainer","getParent","getStorage","getRequestId","err","data","resolveTokenAndPrepareInstanceName","instanceName","validatedArgs","realToken","scope","getResult","get","getHolder","name","result","reqResult","error","holder","resolutionCtx","waiterHolder","readyResult","waitForInstanceReady","instance","handledResult","handleStorageError","createError","createAndStoreInstance","actualToken","validateAndResolveTokenArgs","code","TokenValidationError","FactoryTokenNotResolved","log","factoryCtx","inject","t","a","container","addDestroyListener","resolve","getRealToken","record","generateInstanceName","InstanceDestroying","destroyPromise","newResult","delete","has","factoryNotFound","toString","type","recordScope","serviceScope","Transient","createTransientInstance","Request","initializationError","storageToUse","deferred","createHolder","Set","set","ctx","createServiceInitializationContext","deps","destroyListeners","getDestroyListeners","instantiateService","then","length","newScope","newName","handleInstantiationResult","catch","handleInstantiationError","originalToken","tempHolder","status","Created","creationPromise","dependencies","createdAt","Date","now","waitingFor","handleInstantiationSuccess","_scopedContainer","_requestId","storageForSubscriptions","size","setupDependencySubscriptions","Error","unknown","reject","Creating","cycle","detectCycle","circularDependency","process","env","NODE_ENV","add","Destroying","instanceDestroying","instanceNotFound","serviceName","serviceToken","normalizeToken","depRecord","depScope","dependencyRequestId","finalDepName","Singleton","needsUpgrade","newServiceName","checkAndUpgradeScope","listener","push","trackDependency","InjectableScope","InstanceNameCache","cache","Map","maxSize","get","key","value","undefined","delete","set","has","size","firstKey","keys","next","clear","hashArgs","args","str","JSON","stringify","Object","sort","hash","i","length","char","charCodeAt","Math","abs","toString","NameResolver","instanceNameCache","logger","generateInstanceName","token","requestId","scope","tokenStr","isRequest","Request","Error","cacheKey","cached","result","argsHash","upgradeInstanceNameToRequest","existingName","includes","requestIdPattern","hasRequestId","test","colonIndex","indexOf","tokenPart","substring","argsPart","startsWith","formatArgValue","name","slice","InjectableScope","Scope","DIError","InstanceStatus","ScopeTracker","registry","nameResolver","logger","checkAndUpgradeScope","currentServiceName","currentServiceScope","dependencyName","dependencyScope","dependencyToken","singletonStorage","requestStorage","requestId","Singleton","Request","warn","log","success","newName","upgradeScopeToRequestSync","error","upgradeScopeToRequest","serviceName","token","undefined","storageError","unknown","upgradeInstanceNameToRequest","updated","updateScope","holderResult","get","holder","message","status","Creating","name","set","delete","updateParentDependencies","oldName","updateDependencyReference","InjectableType","DIError","ServiceInitializer","injectors","instantiateService","ctx","record","args","undefined","type","Class","instantiateClass","Factory","instantiateFactory","unknown","error","initializationError","target","name","tryLoad","wrapSyncInit","original","provideFactoryContext","result","instance","promises","injectState","length","results","Promise","allSettled","some","status","Error","newRes","console","onServiceInit","addDestroyListener","onServiceDestroy","builder","create","InstanceStatus","ServiceInvalidator","eventBus","logger","invalidateWithStorage","service","storage","options","emitEvents","onInvalidated","log","result","get","holder","invalidateHolderWithStorage","setupDependencySubscriptions","serviceName","dependencies","dependencyName","unsubscribe","on","catch","error","destroyListeners","push","clearAllWithStorage","waitForSettlement","readyWithStorage","allServiceNames","getAllNames","length","join","clearPromises","map","Promise","all","holders","forEach","_","waitForHolderToSettle","key","invalidateHolderByStatus","context","onDestroy","destroyHolderWithStorage","status","Destroying","destroyPromise","Creating","creationPromise","listener","then","deps","clear","delete","emitInstanceEvent","Created","Error","name","event","resolve","emit","withoutResolutionContext","InjectableTokenMeta","getInjectors","currentFactoryContext","provideFactoryContext","context","original","getFactoryContext","Error","promiseCollector","injectState","getRequest","token","args","skipCycleTracking","isFrozen","idx","currentIndex","request","requests","toString","result","error","doInject","inject","then","r","catch","e","promise","push","asyncInject","realToken","wrapSyncInit","cb","previousState","promises","originalPromiseCollector","originalInjectState","newInjectState","ctx","instance","container","tryGetSync","Proxy","get","optional","injectors","inject: Injectors['inject']","optional: Injectors['optional']","asyncInject: Injectors['asyncInject']","wrapSyncInit: Injectors['wrapSyncInit']","provideFactoryContext: Injectors['provideFactoryContext']","DIError","InjectableTokenMeta","getInjectableToken","target","token","classNotInjectable","name","DIError","BoundInjectionToken","FactoryInjectionToken","getInjectableToken","TokenResolver","logger","normalizeToken","token","getRealToken","getRegistryToken","validateAndResolveTokenArgs","args","actualToken","realArgs","value","resolved","factoryTokenNotResolved","name","schema","undefined","validatedArgs","safeParse","success","error","toString","tokenValidationError","data","InjectableScope","InjectableType","DIError","InstanceStatus","UnifiedStorage","scope","holders","Map","dependents","Singleton","get","instanceName","holder","status","Destroying","instanceDestroying","Error","instance","Creating","Created","undefined","set","deps","size","registerDependencies","delete","removeFromDependentsIndex","createHolder","type","deferred","Promise","withResolvers","name","creationPromise","promise","destroyPromise","destroyListeners","createdAt","Date","now","waitingFor","Set","storeInstance","storageError","Class","onServiceDestroy","handles","getAllNames","Array","from","keys","forEach","callback","findByInstance","values","findDependents","updateDependencyReference","oldName","newName","has","add","oldDependents","newDependents","dependent","depName","entries","holderName","dep","LifecycleEventBus","listeners","Map","logger","on","ns","event","listener","debug","has","set","nsEvents","get","Set","add","delete","size","emit","key","events","res","Promise","allSettled","map","then","results","filter","result","status","warn","reason","length","reject","DIError","StubFactoryClass","factoryNotFound","InjectableScope","InjectableType","DIError","DIErrorCode","InstanceStatus","StubFactoryClass","BoundInjectionToken","InjectionToken","AbstractContainer","calculateInstanceName","token","args","tokenResolver","getTokenResolver","err","actualToken","validatedArgs","validateAndResolveTokenArgs","code","FactoryTokenNotResolved","TokenValidationError","realToken","getRealToken","registry","getRegistry","scope","has","get","defaultScope","getNameResolver","generateInstanceName","Request","requestId","undefined","isRegistered","getRegistryToken","ready","getServiceInvalidator","readyWithStorage","getStorage","tryGetSync","tryGetSyncFromStorage","storage","Singleton","instanceName","normalizeToken","result","holder","status","Created","instance","addInstance","addInstanceToStorage","schema","schemaType","def","type","tokenSchemaRequiredError","name","normalizedToken","set","Class","value","storeInstance","InjectableScope","UnifiedStorage","AbstractContainer","ScopedContainer","defaultScope","Request","storage","disposed","metadata","parent","registry","requestId","getStorage","getRegistry","getTokenResolver","getNameResolver","getServiceInvalidator","getRequestId","getParent","getMetadata","key","setMetadata","value","get","token","args","Error","tokenResolver","realToken","getRegistryToken","has","record","scope","error","instance","getInstanceResolver","resolveRequestScopedInstance","resolveInstance","invalidate","service","holder","findByInstance","invalidateWithStorage","name","dispose","endRequest","tryGetSync","Singleton","result","tryGetSyncFromStorage","addInstance","clearAllWithStorage","removeRequestId","AbstractContainer","Injectable","InjectableScope","InjectableType","DIError","InstanceResolver","NameResolver","ScopeTracker","ServiceInitializer","ServiceInvalidator","TokenResolver","UnifiedStorage","LifecycleEventBus","globalRegistry","defaultInjectors","getInjectableToken","ScopedContainer","Container","registry","logger","injectors","storage","Singleton","eventBus","nameResolver","tokenResolver","scopeTracker","serviceInitializer","serviceInvalidator","instanceResolver","registerSelf","defaultScope","requestId","undefined","activeRequestIds","Set","token","set","Class","instanceName","generateInstanceName","storeInstance","get","args","realToken","getRegistryToken","has","record","scope","Request","scopeMismatchError","name","error","instance","resolveInstance","invalidate","service","holder","findByInstance","warn","invalidateWithStorage","dispose","clearAllWithStorage","tryGetSync","tryGetSyncFromStorage","beginRequest","metadata","Error","add","getActiveRequestIds","hasActiveRequest","removeRequestId","delete","getStorage","getServiceInitializer","getServiceInvalidator","getTokenResolver","getNameResolver","getScopeTracker","getEventBus","getRegistry","getInstanceResolver"],"sources":["../src/enums/injectable-scope.enum.mts","../src/enums/injectable-type.enum.mts","../src/symbols/injectable-token.mts","../src/token/injection-token.mts","../src/token/registry.mts","../src/decorators/injectable.decorator.mts","../src/errors/di-error.mts","../src/internal/context/async-local-storage.mts","../src/internal/context/resolution-context.mts","../src/internal/holder/instance-holder.mts","../src/internal/lifecycle/circular-detector.mts","../src/internal/core/instance-resolver.mts","../src/internal/core/name-resolver.mts","../src/internal/core/scope-tracker.mts","../src/internal/core/service-initializer.mts","../src/internal/core/service-invalidator.mts","../src/utils/get-injectors.mts","../src/utils/default-injectors.mts","../src/utils/get-injectable-token.mts","../src/internal/core/token-resolver.mts","../src/internal/holder/unified-storage.mts","../src/internal/lifecycle/lifecycle-event-bus.mts","../src/internal/stub-factory-class.mts","../src/container/abstract-container.mts","../src/container/scoped-container.mts","../src/container/container.mts"],"sourcesContent":["export enum InjectableScope {\n /**\n * Singleton scope: The instance is created once and shared across the application.\n */\n Singleton = 'Singleton',\n /**\n * Instance scope: A new instance is created for each injection.\n */\n Transient = 'Transient',\n /**\n * Request scope: The instance is created once per request and shared within that request context.\n */\n Request = 'Request',\n}\n\n","export enum InjectableType {\n Class = 'Class',\n Factory = 'Factory',\n}\n\n","export const InjectableTokenMeta = /* #__PURE__ */ Symbol.for(\n 'InjectableTokenMeta',\n)\n","import type { z, ZodObject, ZodOptional, ZodRecord } from 'zod/v4'\n\nimport type { FactoryContext } from '../internal/context/factory-context.mjs'\n\nexport type ClassType = new (...args: any[]) => any\nexport type ClassTypeWithoutArguments = new () => any\nexport type ClassTypeWithArgument<Arg> = new (arg: Arg) => any\nexport type ClassTypeWithOptionalArgument<Arg> = new (arg?: Arg) => any\n\nexport type ClassTypeWithInstance<T> = new (...args: any[]) => T\nexport type ClassTypeWithInstanceAndArgument<T, Arg> = new (arg: Arg) => T\nexport type ClassTypeWithInstanceAndOptionalArgument<T, Arg> = new (\n arg?: Arg,\n) => T\n\nexport type BaseInjectionTokenSchemaType = ZodObject | ZodRecord\n\nexport type OptionalInjectionTokenSchemaType =\n | ZodOptional<ZodObject>\n | ZodOptional<ZodRecord>\n\nexport type InjectionTokenSchemaType =\n | BaseInjectionTokenSchemaType\n | OptionalInjectionTokenSchemaType\n\n/**\n * Simple hash function for deterministic ID generation\n */\nfunction simpleHash(str: string): string {\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash = hash & hash // Convert to 32-bit integer\n }\n return Math.abs(hash).toString(36)\n}\n\n/**\n * Generate deterministic ID from token name\n */\nfunction generateTokenId(name: string | symbol | ClassType, customId?: string): string {\n if (customId) {\n return customId\n }\n\n let base: string\n if (typeof name === 'function') {\n base = `${name.name}_${name.toString()}`\n } else if (typeof name === 'symbol') {\n base = `symbol_${name.toString()}`\n } else {\n base = `token_${name}`\n }\n\n return `${base.split('_')[0]}_${simpleHash(base)}`\n}\n\nexport class InjectionToken<\n // oxlint-disable-next-line no-unused-vars\n T,\n S extends InjectionTokenSchemaType | unknown = unknown,\n // oxlint-disable-next-line no-unused-vars\n Required extends boolean = S extends ZodOptional<ZodObject>\n ? false\n : S extends ZodOptional<ZodRecord>\n ? false\n : S extends ZodObject\n ? true\n : S extends ZodRecord\n ? true\n : false,\n> {\n public readonly id: string\n private formattedName: string | null = null\n\n constructor(\n public readonly name: string | symbol | ClassType,\n public readonly schema: ZodObject | undefined,\n customId?: string,\n ) {\n this.id = generateTokenId(name, customId)\n }\n\n static create<T extends ClassType>(\n name: T,\n ): InjectionToken<InstanceType<T>, undefined>\n static create<T extends ClassType, Schema extends InjectionTokenSchemaType>(\n name: T,\n schema: Schema,\n ): Schema['_def']['type'] extends 'ZodOptional'\n ? InjectionToken<InstanceType<T>, Schema, false>\n : InjectionToken<InstanceType<T>, Schema, true>\n static create<T>(name: string | symbol): InjectionToken<T, undefined>\n static create<T, Schema extends InjectionTokenSchemaType>(\n name: string | any,\n schema: Schema,\n ): InjectionToken<T, Schema>\n static create(name: string | symbol, schema?: unknown, customId?: string) {\n // @ts-expect-error\n return new InjectionToken(name, schema, customId)\n }\n\n static bound<T, S extends InjectionTokenSchemaType>(\n token: InjectionToken<T, S>,\n value: z.input<S>,\n ): BoundInjectionToken<T, S> {\n return new BoundInjectionToken(token, value)\n }\n\n static factory<T, S extends InjectionTokenSchemaType>(\n token: InjectionToken<T, S>,\n factory: (ctx: FactoryContext) => Promise<z.input<S>>,\n ): FactoryInjectionToken<T, S> {\n return new FactoryInjectionToken(token, factory)\n }\n\n static refineType<T>(\n token: BoundInjectionToken<any, any>,\n ): BoundInjectionToken<T, any> {\n return token as BoundInjectionToken<T, any>\n }\n\n toString() {\n if (this.formattedName) {\n return this.formattedName\n }\n const { name } = this\n if (typeof name === 'function') {\n const className = name.name\n this.formattedName = `${className}(${this.id})`\n } else if (typeof name === 'symbol') {\n this.formattedName = `${name.toString()}(${this.id})`\n } else {\n this.formattedName = `${name}(${this.id})`\n }\n\n return this.formattedName\n }\n}\n\nexport class BoundInjectionToken<T, S extends InjectionTokenSchemaType> {\n public id: string\n public name: string | symbol | ClassType\n public schema: InjectionTokenSchemaType\n\n constructor(\n public readonly token: InjectionToken<T, S>,\n public readonly value: z.input<S>,\n ) {\n this.name = token.name\n this.id = token.id\n this.schema = token.schema as InjectionTokenSchemaType\n }\n\n toString() {\n return this.token.toString()\n }\n}\n\nexport class FactoryInjectionToken<T, S extends InjectionTokenSchemaType> {\n public value?: z.input<S>\n public resolved = false\n public id: string\n public name: string | symbol | ClassType\n public schema: InjectionTokenSchemaType\n\n constructor(\n public readonly token: InjectionToken<T, S>,\n public readonly factory: (ctx: FactoryContext) => Promise<z.input<S>>,\n ) {\n this.name = token.name\n this.id = token.id\n this.schema = token.schema as InjectionTokenSchemaType\n }\n\n async resolve(ctx: FactoryContext): Promise<z.input<S>> {\n if (!this.value) {\n this.value = await this.factory(ctx)\n this.resolved = true\n }\n return this.value\n }\n\n toString() {\n return this.token.toString()\n }\n}\n\nexport type AnyInjectableType =\n | ClassType\n | InjectionToken<any, any>\n | BoundInjectionToken<any, any>\n | FactoryInjectionToken<any, any>\n\nexport type InjectionTokenType =\n | InjectionToken<any, any>\n | BoundInjectionToken<any, any>\n | FactoryInjectionToken<any, any>\n\n","import type { ClassType, InjectionToken } from './injection-token.mjs'\n\nimport { InjectableScope, InjectableType } from '../enums/index.mjs'\n\nexport type FactoryRecord<Instance = any, Schema = any> = {\n scope: InjectableScope\n originalToken: InjectionToken<Instance, Schema>\n target: ClassType\n type: InjectableType\n priority: number\n}\n\nexport class Registry {\n private readonly factories = new Map<string, FactoryRecord[]>()\n private readonly highestPriority = new Map<string, FactoryRecord>()\n\n constructor(private readonly parent?: Registry) {}\n\n has(token: InjectionToken<any, any>): boolean {\n if (this.factories.has(token.id)) {\n return true\n }\n if (this.parent) {\n return this.parent.has(token)\n }\n return false\n }\n\n get<Instance, Schema>(\n token: InjectionToken<Instance, Schema>,\n ): FactoryRecord<Instance, Schema> {\n const factory = this.highestPriority.get(token.id)\n if (!factory) {\n if (this.parent) {\n return this.parent.get(token)\n }\n throw new Error(`[Registry] No factory found for ${token.toString()}`)\n }\n return factory\n }\n\n getAll<Instance, Schema>(\n token: InjectionToken<Instance, Schema>,\n ): FactoryRecord<Instance, Schema>[] {\n const records = this.factories.get(token.id)\n if (!records || records.length === 0) {\n if (this.parent) {\n return this.parent.getAll(token)\n }\n return []\n }\n // Return sorted by priority (highest first)\n return [...records].sort((a, b) => b.priority - a.priority)\n }\n\n set<Instance, Schema>(\n token: InjectionToken<Instance, Schema>,\n scope: InjectableScope,\n target: ClassType,\n type: InjectableType,\n priority: number = 0,\n ) {\n const record: FactoryRecord<Instance, Schema> = {\n scope,\n originalToken: token,\n target,\n type,\n priority,\n }\n\n // Add to factories array\n const existing = this.factories.get(token.id) || []\n existing.push(record)\n this.factories.set(token.id, existing)\n\n // Update highest priority cache if needed\n const currentHighest = this.highestPriority.get(token.id)\n if (!currentHighest || priority > currentHighest.priority) {\n this.highestPriority.set(token.id, record)\n }\n }\n\n delete(token: InjectionToken<any, any>) {\n const records = this.factories.get(token.id)\n if (records) {\n const deletedHighest = this.highestPriority.get(token.id)\n this.factories.delete(token.id)\n this.highestPriority.delete(token.id)\n\n // If we deleted the highest priority record, recalculate from remaining records\n if (deletedHighest && records.length > 1) {\n const remaining = records.filter(\n (r) =>\n r.originalToken.id !== deletedHighest.originalToken.id ||\n r.priority !== deletedHighest.priority,\n )\n if (remaining.length > 0) {\n const newHighest = remaining.reduce((max, current) =>\n current.priority > max.priority ? current : max,\n )\n this.highestPriority.set(token.id, newHighest)\n this.factories.set(token.id, remaining)\n }\n }\n }\n }\n\n /**\n * Updates the scope of an already registered factory.\n * This is useful when you need to dynamically change a service's scope\n * (e.g., when a singleton controller has request-scoped dependencies).\n *\n * @param token The injection token to update\n * @param scope The new scope to set\n * @returns true if the scope was updated, false if the token was not found\n */\n updateScope(\n token: InjectionToken<any, any>,\n scope: InjectableScope,\n ): boolean {\n const records = this.factories.get(token.id)\n if (records && records.length > 0) {\n // Update all records\n records.forEach((record) => {\n record.scope = scope\n })\n // Update highest priority cache if it exists\n const highest = this.highestPriority.get(token.id)\n if (highest) {\n highest.scope = scope\n }\n return true\n }\n if (this.parent) {\n return this.parent.updateScope(token, scope)\n }\n return false\n }\n}\n\nexport const globalRegistry = /* #__PURE__ */ new Registry()\n","import type { z } from 'zod/v4'\n\nimport type {\n BaseInjectionTokenSchemaType,\n ClassType,\n ClassTypeWithArgument,\n ClassTypeWithInstance,\n ClassTypeWithInstanceAndArgument,\n ClassTypeWithInstanceAndOptionalArgument,\n ClassTypeWithOptionalArgument,\n ClassTypeWithoutArguments,\n InjectionTokenSchemaType,\n OptionalInjectionTokenSchemaType,\n} from '../token/injection-token.mjs'\nimport type { Registry } from '../token/registry.mjs'\n\nimport { InjectableScope, InjectableType } from '../enums/index.mjs'\nimport { InjectableTokenMeta } from '../symbols/index.mjs'\nimport { InjectionToken } from '../token/injection-token.mjs'\nimport { globalRegistry } from '../token/registry.mjs'\n\nexport interface InjectableOptions {\n scope?: InjectableScope\n token?: InjectionToken<any, any>\n schema?: InjectionTokenSchemaType\n registry?: Registry\n priority?: number\n}\n\n// #1 Simple constructorless class\nexport function Injectable(): <T extends ClassTypeWithoutArguments>(\n target: T,\n context?: ClassDecoratorContext,\n) => T\nexport function Injectable(options: {\n scope?: InjectableScope\n registry: Registry\n priority?: number\n}): <T extends ClassTypeWithoutArguments>(\n target: T,\n context?: ClassDecoratorContext,\n) => T\nexport function Injectable(options: {\n scope: InjectableScope\n priority?: number\n}): <T extends ClassTypeWithoutArguments>(\n target: T,\n context?: ClassDecoratorContext,\n) => T\n// #2 Class with schema\nexport function Injectable<Schema extends InjectionTokenSchemaType>(options: {\n scope?: InjectableScope\n schema: Schema\n registry?: Registry\n priority?: number\n}): <T extends ClassTypeWithArgument<z.output<Schema>>>(\n target: T,\n context?: ClassDecoratorContext,\n) => T\n\n// #3 Class with typeless token and schema\nexport function Injectable<Type, Schema>(options: {\n scope?: InjectableScope\n token: InjectionToken<Type, Schema>\n registry?: Registry\n priority?: number\n}): Schema extends BaseInjectionTokenSchemaType\n ? Type extends undefined\n ? <T extends ClassTypeWithArgument<z.output<Schema>>>(\n target: T,\n context?: ClassDecoratorContext,\n ) => T\n : <T extends ClassTypeWithInstanceAndArgument<Type, z.output<Schema>>>(\n target: T,\n context?: ClassDecoratorContext,\n ) => T\n : Schema extends OptionalInjectionTokenSchemaType\n ? Type extends undefined\n ? <T extends ClassTypeWithOptionalArgument<z.output<Schema>>>(\n target: T,\n context?: ClassDecoratorContext,\n ) => T\n : <\n T extends ClassTypeWithInstanceAndOptionalArgument<\n Type,\n z.output<Schema>\n >,\n >(\n target: T,\n context?: ClassDecoratorContext,\n ) => T\n : Schema extends undefined\n ? <R extends ClassTypeWithInstance<Type>>(\n target: R,\n context?: ClassDecoratorContext,\n ) => R\n : never\n\nexport function Injectable({\n scope = InjectableScope.Singleton,\n token,\n schema,\n registry = globalRegistry,\n priority = 0,\n}: InjectableOptions = {}) {\n return <T extends ClassType>(\n target: T,\n context?: ClassDecoratorContext,\n ): T => {\n if (\n (context && context.kind !== 'class') ||\n (target instanceof Function && !context)\n ) {\n throw new Error('[DI] @Injectable decorator can only be used on classes.')\n }\n if (schema && token) {\n throw new Error(\n '[DI] @Injectable decorator cannot have both a token and a schema',\n )\n }\n let injectableToken: InjectionToken<any, any> =\n token ?? InjectionToken.create(target, schema as InjectionTokenSchemaType)\n\n registry.set(injectableToken, scope, target, InjectableType.Class, priority)\n\n // @ts-expect-error\n target[InjectableTokenMeta] = injectableToken\n\n return target\n }\n}\n","import type { InjectionTokenSchemaType } from '../token/injection-token.mjs'\nimport type { FactoryRecord } from '../token/registry.mjs'\n\nexport enum DIErrorCode {\n FactoryNotFound = 'FactoryNotFound',\n FactoryTokenNotResolved = 'FactoryTokenNotResolved',\n InstanceNotFound = 'InstanceNotFound',\n InstanceDestroying = 'InstanceDestroying',\n CircularDependency = 'CircularDependency',\n TokenValidationError = 'TokenValidationError',\n TokenSchemaRequiredError = 'TokenSchemaRequiredError',\n ClassNotInjectable = 'ClassNotInjectable',\n ScopeMismatchError = 'ScopeMismatchError',\n PriorityConflictError = 'PriorityConflictError',\n StorageError = 'StorageError',\n InitializationError = 'InitializationError',\n DependencyResolutionError = 'DependencyResolutionError',\n UnknownError = 'UnknownError',\n}\n\nexport class DIError extends Error {\n public readonly context?: Record<string, unknown>\n\n constructor(\n public readonly code: DIErrorCode,\n public readonly message: string,\n context?: Record<string, unknown>,\n ) {\n super(message)\n this.context = context\n this.name = 'DIError'\n }\n\n // Static factory methods for common error types\n static factoryNotFound(name: string): DIError {\n return new DIError(\n DIErrorCode.FactoryNotFound,\n `Factory ${name} not found`,\n { name },\n )\n }\n\n static factoryTokenNotResolved(token: string | symbol | unknown): DIError {\n return new DIError(\n DIErrorCode.FactoryTokenNotResolved,\n `Factory token not resolved: ${token?.toString() ?? 'unknown'}`,\n { token },\n )\n }\n\n static instanceNotFound(name: string): DIError {\n return new DIError(\n DIErrorCode.InstanceNotFound,\n `Instance ${name} not found`,\n { name },\n )\n }\n\n static instanceDestroying(name: string): DIError {\n return new DIError(\n DIErrorCode.InstanceDestroying,\n `Instance ${name} destroying`,\n { name },\n )\n }\n\n static unknown(\n message: string | Error,\n context?: Record<string, unknown>,\n ): DIError {\n if (message instanceof Error) {\n return new DIError(DIErrorCode.UnknownError, message.message, {\n ...context,\n parent: message,\n })\n }\n return new DIError(DIErrorCode.UnknownError, message, context)\n }\n\n static circularDependency(cycle: string[]): DIError {\n const cycleStr = cycle.join(' -> ')\n return new DIError(\n DIErrorCode.CircularDependency,\n `Circular dependency detected: ${cycleStr}`,\n { cycle },\n )\n }\n\n static tokenValidationError(\n message: string,\n schema: InjectionTokenSchemaType | undefined,\n value: unknown,\n ): DIError {\n return new DIError(DIErrorCode.TokenValidationError, message, {\n schema,\n value,\n })\n }\n\n static tokenSchemaRequiredError(token: string | symbol | unknown): DIError {\n return new DIError(\n DIErrorCode.TokenSchemaRequiredError,\n `Token ${token?.toString() ?? 'unknown'} requires schema arguments and cannot be used with addInstance. Use BoundInjectionToken or provide arguments when resolving.`,\n { token },\n )\n }\n\n static classNotInjectable(className: string): DIError {\n return new DIError(\n DIErrorCode.ClassNotInjectable,\n `Class ${className} is not decorated with @Injectable.`,\n { className },\n )\n }\n\n static scopeMismatchError(\n token: string | symbol | unknown,\n expectedScope: string,\n actualScope: string,\n ): DIError {\n return new DIError(\n DIErrorCode.ScopeMismatchError,\n `Scope mismatch for ${token?.toString() ?? 'unknown'}: expected ${expectedScope}, got ${actualScope}`,\n { token, expectedScope, actualScope },\n )\n }\n\n static priorityConflictError(\n token: string | symbol | unknown,\n records: FactoryRecord[],\n ): DIError {\n return new DIError(\n DIErrorCode.PriorityConflictError,\n `Priority conflict for ${token?.toString() ?? 'unknown'}: multiple bindings with same priority`,\n { token, records },\n )\n }\n\n static storageError(\n message: string,\n operation: string,\n instanceName?: string,\n ): DIError {\n return new DIError(DIErrorCode.StorageError, `Storage error: ${message}`, {\n operation,\n instanceName,\n })\n }\n\n static initializationError(\n serviceName: string,\n error: Error | string,\n ): DIError {\n return new DIError(\n DIErrorCode.InitializationError,\n `Service ${serviceName} initialization failed: ${error instanceof Error ? error.message : error}`,\n { serviceName, error },\n )\n }\n\n static dependencyResolutionError(\n serviceName: string,\n dependencyName: string,\n error: Error | string,\n ): DIError {\n return new DIError(\n DIErrorCode.DependencyResolutionError,\n `Failed to resolve dependency ${dependencyName} for service ${serviceName}: ${error instanceof Error ? error.message : error}`,\n { serviceName, dependencyName, error },\n )\n }\n}\n","import type { IAsyncLocalStorage } from './async-local-storage.types.mjs'\n\nimport { AsyncLocalStorage } from 'node:async_hooks'\n\n/**\n * Cross-platform AsyncLocalStorage switcher.\n *\n * Provides the appropriate implementation based on environment:\n * - Production: No-op implementation (circular detection disabled)\n * - Development: Native AsyncLocalStorage from node:async_hooks\n *\n * Browser environments use a separate entry point via package.json exports\n * that directly uses SyncLocalStorage.\n *\n * Uses lazy initialization to avoid import overhead until first use,\n * and works with both ESM and CJS builds.\n */\n\nexport type { IAsyncLocalStorage }\n\nconst isProduction = process.env.NODE_ENV === 'production'\n\n// Lazy-loaded module cache\nlet loadedModule: {\n createAsyncLocalStorage: <T>() => IAsyncLocalStorage<T>\n isUsingNativeAsyncLocalStorage: () => boolean\n} | null = null\n\nfunction getModule() {\n if (loadedModule) {\n return loadedModule\n }\n\n if (isProduction) {\n // In production, use the noop implementation\n // Inline to avoid any import overhead\n class NoopLocalStorage<T> implements IAsyncLocalStorage<T> {\n run<R>(_store: T, fn: () => R): R {\n return fn()\n }\n getStore(): T | undefined {\n return undefined\n }\n }\n\n loadedModule = {\n createAsyncLocalStorage: <T,>() => new NoopLocalStorage<T>(),\n isUsingNativeAsyncLocalStorage: () => false,\n }\n } else {\n // In development, use native AsyncLocalStorage\n\n loadedModule = {\n createAsyncLocalStorage: <T,>() => new AsyncLocalStorage<T>(),\n isUsingNativeAsyncLocalStorage: () => true,\n }\n }\n\n return loadedModule\n}\n\nexport function createAsyncLocalStorage<T>(): IAsyncLocalStorage<T> {\n return getModule().createAsyncLocalStorage<T>()\n}\n\nexport function isUsingNativeAsyncLocalStorage(): boolean {\n return getModule().isUsingNativeAsyncLocalStorage()\n}\n\n","import type { InstanceHolder } from '../holder/instance-holder.mjs'\nimport type { IAsyncLocalStorage } from './async-local-storage.types.mjs'\n\nimport { createAsyncLocalStorage } from './async-local-storage.mjs'\n\n/**\n * Data stored in the resolution context during service instantiation.\n */\nexport interface ResolutionContextData {\n /** The holder that is currently being instantiated */\n waiterHolder: InstanceHolder\n /** Function to get a holder by name (for cycle detection) */\n getHolder: (name: string) => InstanceHolder | undefined\n}\n\n/**\n * AsyncLocalStorage for tracking the current resolution context.\n *\n * This allows tracking which service is being instantiated even across\n * async boundaries (like when inject() is called inside a constructor).\n * Essential for circular dependency detection.\n *\n * The actual implementation varies by environment:\n * - Production: No-op (returns undefined, run() just calls fn directly)\n * - Development: Real AsyncLocalStorage with full async tracking\n * - Browser: SyncLocalStorage for synchronous-only tracking\n */\nlet resolutionContext: IAsyncLocalStorage<ResolutionContextData> | null = null\n\nfunction getResolutionContext(): IAsyncLocalStorage<ResolutionContextData> {\n if (!resolutionContext) {\n resolutionContext = createAsyncLocalStorage<ResolutionContextData>()\n }\n return resolutionContext\n}\n\n/**\n * Runs a function within a resolution context.\n *\n * The context tracks which holder is currently being instantiated,\n * allowing circular dependency detection to work correctly.\n *\n * @param waiterHolder The holder being instantiated\n * @param getHolder Function to retrieve holders by name\n * @param fn The function to run within the context\n */\nexport function withResolutionContext<T>(\n waiterHolder: InstanceHolder,\n getHolder: (name: string) => InstanceHolder | undefined,\n fn: () => T,\n): T {\n return getResolutionContext().run({ waiterHolder, getHolder }, fn)\n}\n\n/**\n * Gets the current resolution context, if any.\n *\n * Returns undefined if we're not inside a resolution context\n * (e.g., when resolving a top-level service that has no parent).\n */\nexport function getCurrentResolutionContext():\n | ResolutionContextData\n | undefined {\n return getResolutionContext().getStore()\n}\n\n/**\n * Runs a function outside any resolution context.\n *\n * This is useful for async injections that should not participate\n * in circular dependency detection since they don't block.\n *\n * @param fn The function to run without resolution context\n */\nexport function withoutResolutionContext<T>(fn: () => T): T {\n // Run with undefined context to clear any current context\n return getResolutionContext().run(\n undefined as unknown as ResolutionContextData,\n fn,\n )\n}\n\n","import type { InjectableScope, InjectableType } from '../../enums/index.mjs'\n\n/**\n * Represents the lifecycle status of an instance holder.\n */\nexport enum InstanceStatus {\n /** Instance has been successfully created and is ready for use */\n Created = 'created',\n /** Instance is currently being created (async initialization in progress) */\n Creating = 'creating',\n /** Instance is being destroyed (cleanup in progress) */\n Destroying = 'destroying',\n /** Instance creation failed with an error */\n Error = 'error',\n}\n\n/** Callback function for instance destruction listeners */\nexport type InstanceDestroyListener = () => void | Promise<void>\n\n/**\n * Instance holder in the Creating state.\n * The instance is null while creation is in progress.\n */\nexport interface InstanceHolderCreating<Instance> {\n status: InstanceStatus.Creating\n name: string\n instance: null\n creationPromise: Promise<[undefined, Instance]> | null\n destroyPromise: null\n type: InjectableType\n scope: InjectableScope\n deps: Set<string>\n destroyListeners: InstanceDestroyListener[]\n createdAt: number\n /** Tracks which services this holder is currently waiting for (for circular dependency detection) */\n waitingFor: Set<string>\n}\n\n/**\n * Instance holder in the Created state.\n * The instance is available and ready for use.\n */\nexport interface InstanceHolderCreated<Instance> {\n status: InstanceStatus.Created\n name: string\n instance: Instance\n creationPromise: null\n destroyPromise: null\n type: InjectableType\n scope: InjectableScope\n deps: Set<string>\n destroyListeners: InstanceDestroyListener[]\n createdAt: number\n /** Tracks which services this holder is currently waiting for (for circular dependency detection) */\n waitingFor: Set<string>\n}\n\n/**\n * Instance holder in the Destroying state.\n * The instance may still be available but is being cleaned up.\n */\nexport interface InstanceHolderDestroying<Instance> {\n status: InstanceStatus.Destroying\n name: string\n instance: Instance | null\n creationPromise: null\n destroyPromise: Promise<void>\n type: InjectableType\n scope: InjectableScope\n deps: Set<string>\n destroyListeners: InstanceDestroyListener[]\n createdAt: number\n /** Tracks which services this holder is currently waiting for (for circular dependency detection) */\n waitingFor: Set<string>\n}\n\n/**\n * Instance holder in the Error state.\n * The instance field contains the error that occurred during creation.\n */\nexport interface InstanceHolderError {\n status: InstanceStatus.Error\n name: string\n instance: Error\n creationPromise: null\n destroyPromise: null\n type: InjectableType\n scope: InjectableScope\n deps: Set<string>\n destroyListeners: InstanceDestroyListener[]\n createdAt: number\n /** Tracks which services this holder is currently waiting for (for circular dependency detection) */\n waitingFor: Set<string>\n}\n\n/**\n * Holds the state of a service instance throughout its lifecycle.\n *\n * Tracks creation/destruction promises, dependency relationships,\n * destroy listeners, and current status (Creating, Created, Destroying, Error).\n */\nexport type InstanceHolder<Instance = unknown> =\n | InstanceHolderCreating<Instance>\n | InstanceHolderCreated<Instance>\n | InstanceHolderDestroying<Instance>\n | InstanceHolderError\n\n","import type { InstanceHolder } from '../holder/instance-holder.mjs'\n\n/**\n * Whether we're running in production mode.\n * In production, circular dependency detection is skipped for performance.\n */\nconst isProduction = process.env.NODE_ENV === 'production'\n\n/**\n * Detects circular dependencies by analyzing the waitingFor relationships\n * between service holders.\n *\n * Uses BFS to traverse the waitingFor graph starting from a target holder\n * and checks if following the chain leads back to the waiter, indicating a circular dependency.\n *\n * Note: In production (NODE_ENV === 'production'), detection is skipped for performance.\n */\nexport class CircularDetector {\n /**\n * Detects if waiting for `targetName` from `waiterName` would create a cycle.\n *\n * This works by checking if `targetName` (or any holder in its waitingFor chain)\n * is currently waiting for `waiterName`. If so, waiting would create a deadlock.\n *\n * In production mode, this always returns null to skip the BFS traversal overhead.\n *\n * @param waiterName The name of the holder that wants to wait\n * @param targetName The name of the holder being waited on\n * @param getHolder Function to retrieve a holder by name\n * @returns The cycle path if a cycle is detected, null otherwise\n */\n static detectCycle(\n waiterName: string,\n targetName: string,\n getHolder: (name: string) => InstanceHolder | undefined,\n ): string[] | null {\n // Skip circular dependency detection in production for performance\n if (isProduction) {\n return null\n }\n\n // Use BFS to find if there's a path from targetName back to waiterName\n const visited = new Set<string>()\n const queue: Array<{ name: string; path: string[] }> = [\n { name: targetName, path: [waiterName, targetName] },\n ]\n\n while (queue.length > 0) {\n const { name: currentName, path } = queue.shift()!\n\n // If we've reached back to the waiter, we have a cycle\n if (currentName === waiterName) {\n return path\n }\n\n // Skip if already visited\n if (visited.has(currentName)) {\n continue\n }\n visited.add(currentName)\n\n // Get the holder and check what it's waiting for\n const holder = getHolder(currentName)\n if (!holder) {\n continue\n }\n\n // Add all services this holder is waiting for to the queue\n for (const waitingForName of holder.waitingFor) {\n if (!visited.has(waitingForName)) {\n queue.push({\n name: waitingForName,\n path: [...path, waitingForName],\n })\n }\n }\n }\n\n // No path found from target back to waiter, no cycle\n return null\n }\n\n /**\n * Formats a cycle path into a human-readable string.\n *\n * @param cycle The cycle path (array of service names)\n * @returns Formatted string like \"ServiceA -> ServiceB -> ServiceA\"\n */\n static formatCycle(cycle: string[]): string {\n return cycle.join(' -> ')\n }\n}\n\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { ScopedContainer } from '../../container/scoped-container.mjs'\nimport type { IContainer } from '../../interfaces/container.interface.mjs'\nimport type {\n AnyInjectableType,\n InjectionTokenType,\n} from '../../token/injection-token.mjs'\nimport type { Registry } from '../../token/registry.mjs'\nimport type { ServiceInitializationContext } from '../context/service-initialization-context.mjs'\nimport type { IHolderStorage } from '../holder/holder-storage.interface.mjs'\nimport type { InstanceHolder } from '../holder/instance-holder.mjs'\nimport type { LifecycleEventBus } from '../lifecycle/lifecycle-event-bus.mjs'\n\nimport { InjectableScope } from '../../enums/index.mjs'\nimport { DIError, DIErrorCode } from '../../errors/index.mjs'\nimport {\n BoundInjectionToken,\n FactoryInjectionToken,\n InjectionToken,\n} from '../../token/injection-token.mjs'\nimport {\n getCurrentResolutionContext,\n withResolutionContext,\n} from '../context/resolution-context.mjs'\nimport { InstanceStatus } from '../holder/instance-holder.mjs'\nimport { CircularDetector } from '../lifecycle/circular-detector.mjs'\nimport { NameResolver } from './name-resolver.mjs'\nimport { ScopeTracker } from './scope-tracker.mjs'\nimport { ServiceInitializer } from './service-initializer.mjs'\nimport { ServiceInvalidator } from './service-invalidator.mjs'\nimport { TokenResolver } from './token-resolver.mjs'\n\n/**\n * Resolves instances from tokens, handling caching, creation, and scope rules.\n *\n * Uses unified storage for both singleton and request-scoped services.\n * Coordinates with ServiceInitializer for actual service creation.\n * Integrates ScopeTracker for automatic scope upgrades.\n */\nexport class InstanceResolver {\n constructor(\n private readonly registry: Registry,\n private readonly storage: IHolderStorage,\n private readonly serviceInitializer: ServiceInitializer,\n private readonly tokenResolver: TokenResolver,\n private readonly nameResolver: NameResolver,\n private readonly scopeTracker: ScopeTracker,\n private readonly serviceInvalidator: ServiceInvalidator,\n private readonly eventBus: LifecycleEventBus,\n private readonly logger: Console | null = null,\n ) {}\n\n // ============================================================================\n // PUBLIC RESOLUTION METHODS\n // ============================================================================\n\n /**\n * Resolves an instance for the given token and arguments.\n * This method is used for singleton and transient services.\n *\n * @param token The injection token\n * @param args Optional arguments\n * @param contextContainer The container to use for creating context\n * @param requestStorage Optional request storage (for scope upgrades)\n * @param requestId Optional request ID (for scope upgrades)\n */\n async resolveInstance(\n token: AnyInjectableType,\n args: any,\n contextContainer: IContainer,\n requestStorage?: IHolderStorage,\n requestId?: string,\n ): Promise<[undefined, any] | [DIError]> {\n return this.resolveWithStorage(\n token,\n args,\n contextContainer,\n this.storage,\n undefined,\n requestStorage,\n requestId,\n )\n }\n\n /**\n * Resolves a request-scoped instance for a ScopedContainer.\n * The service will be stored in the ScopedContainer's request storage.\n *\n * @param token The injection token\n * @param args Optional arguments\n * @param scopedContainer The ScopedContainer that owns the request context\n */\n async resolveRequestScopedInstance(\n token: AnyInjectableType,\n args: any,\n scopedContainer: ScopedContainer,\n ): Promise<[undefined, any] | [DIError]> {\n return this.resolveWithStorage(\n token,\n args,\n scopedContainer.getParent(),\n scopedContainer.getParent().getStorage(),\n scopedContainer,\n scopedContainer.getStorage(),\n scopedContainer.getRequestId(),\n )\n }\n\n // ============================================================================\n // UNIFIED RESOLUTION (Storage Strategy Pattern)\n // ============================================================================\n\n /**\n * Unified resolution method that works with any IHolderStorage.\n * This eliminates duplication between singleton and request-scoped resolution.\n *\n * IMPORTANT: The check-and-store logic is carefully designed to avoid race conditions.\n * The storage check and holder creation must happen synchronously (no awaits between).\n *\n * @param token The injection token\n * @param args Optional arguments\n * @param contextContainer The container for context\n * @param storage The storage strategy to use\n * @param scopedContainer Optional scoped container for request-scoped services\n * @param requestStorage Optional request storage (for scope upgrades)\n * @param requestId Optional request ID (for scope upgrades)\n */\n private async resolveWithStorage(\n token: AnyInjectableType,\n args: any,\n contextContainer: IContainer,\n storage: IHolderStorage,\n scopedContainer?: ScopedContainer,\n requestStorage?: IHolderStorage,\n requestId?: string,\n ): Promise<[undefined, any] | [DIError]> {\n // Step 1: Resolve token and prepare instance name\n const [err, data] = await this.resolveTokenAndPrepareInstanceName(\n token,\n args,\n contextContainer,\n requestId,\n scopedContainer,\n )\n if (err) {\n return [err]\n }\n\n const { instanceName, validatedArgs, realToken, scope } = data!\n\n // Step 2: Check for existing holder SYNCHRONOUSLY (no await between check and store)\n // This is critical for preventing race conditions with concurrent resolution\n const getResult =\n storage.get(instanceName) ?? requestStorage?.get(instanceName) ?? null\n\n // Create getHolder function for circular dependency detection\n const getHolder = (name: string): InstanceHolder | undefined => {\n // Check both storages\n const result = storage.get(name)\n if (result && result[0] === undefined && result[1]) {\n return result[1]\n }\n if (requestStorage) {\n const reqResult = requestStorage.get(name)\n if (reqResult && reqResult[0] === undefined && reqResult[1]) {\n return reqResult[1]\n }\n }\n return undefined\n }\n\n if (getResult !== null) {\n const [error, holder] = getResult\n if (!error && holder) {\n // Found existing holder - wait for it to be ready\n // Try to get waiterHolder from resolution context if available\n const resolutionCtx = getCurrentResolutionContext()\n const waiterHolder = resolutionCtx?.waiterHolder\n const readyResult = await this.waitForInstanceReady(\n holder,\n waiterHolder,\n getHolder,\n )\n if (readyResult[0]) {\n return [readyResult[0]]\n }\n return [undefined, readyResult[1]!.instance]\n }\n // Handle error states (destroying, etc.)\n if (error) {\n const handledResult = await this.handleStorageError(\n instanceName,\n error,\n holder,\n storage,\n )\n if (handledResult) {\n return handledResult\n }\n }\n }\n\n // Step 3: Create new instance and store it\n // NOTE: Holder is stored synchronously inside createAndStoreInstance before any await\n const [createError, holder] = await this.createAndStoreInstance(\n instanceName,\n realToken,\n validatedArgs,\n contextContainer,\n storage,\n scopedContainer,\n requestStorage,\n requestId,\n scope,\n )\n if (createError) {\n return [createError]\n }\n\n return [undefined, holder!.instance]\n }\n\n /**\n * Internal method to resolve token args and create instance name.\n * Handles factory token resolution and validation.\n */\n private async resolveTokenAndPrepareInstanceName(\n token: AnyInjectableType,\n args: any,\n contextContainer: IContainer,\n requestId?: string,\n scopedContainer?: ScopedContainer,\n ): Promise<\n | [\n undefined,\n {\n instanceName: string\n validatedArgs: any\n actualToken: InjectionTokenType\n realToken: InjectionToken<any, any>\n scope: InjectableScope\n },\n ]\n | [DIError]\n > {\n const [err, { actualToken, validatedArgs }] =\n this.tokenResolver.validateAndResolveTokenArgs(token, args)\n if (\n err instanceof DIError &&\n err.code === DIErrorCode.TokenValidationError\n ) {\n return [err]\n } else if (\n err instanceof DIError &&\n err.code === DIErrorCode.FactoryTokenNotResolved &&\n actualToken instanceof FactoryInjectionToken\n ) {\n this.logger?.log(\n `[InstanceResolver]#resolveTokenAndPrepareInstanceName() Factory token not resolved, resolving it`,\n )\n // Create a simple factory context for resolving the factory token\n const factoryCtx = {\n inject: async (t: any, a?: any) =>\n (scopedContainer ?? contextContainer).get(t, a),\n container: scopedContainer ?? contextContainer,\n addDestroyListener: () => {},\n }\n await actualToken.resolve(factoryCtx as any)\n return this.resolveTokenAndPrepareInstanceName(\n token,\n undefined,\n contextContainer,\n requestId,\n scopedContainer,\n )\n }\n\n // Get the real token for registry lookup\n const realToken = this.tokenResolver.getRealToken(actualToken)\n // Get scope from registry\n const record = this.registry.get(realToken)\n const scope = record.scope\n\n // Generate instance name with requestId if needed\n const instanceName = this.nameResolver.generateInstanceName(\n actualToken,\n validatedArgs,\n requestId,\n scope,\n )\n\n return [\n undefined,\n { instanceName, validatedArgs, actualToken, realToken, scope },\n ]\n }\n\n /**\n * Handles storage error states (destroying, error, etc.).\n * Returns a result if handled, null if should proceed with creation.\n */\n private async handleStorageError(\n instanceName: string,\n error: DIError,\n holder: InstanceHolder | undefined,\n storage: IHolderStorage,\n ): Promise<[undefined, any] | [DIError] | null> {\n switch (error.code) {\n case DIErrorCode.InstanceDestroying:\n // Wait for destruction then retry\n this.logger?.log(\n `[InstanceResolver] Instance ${instanceName} is being destroyed, waiting...`,\n )\n if (holder?.destroyPromise) {\n await holder.destroyPromise\n }\n // Re-check after destruction\n const newResult = storage.get(instanceName)\n if (newResult !== null && !newResult[0]) {\n // Create getHolder for circular dependency detection\n const getHolder = (name: string): InstanceHolder | undefined => {\n const result = storage.get(name)\n return result && result[0] === undefined && result[1]\n ? result[1]\n : undefined\n }\n const readyResult = await this.waitForInstanceReady(\n newResult[1]!,\n undefined,\n getHolder,\n )\n if (readyResult[0]) {\n return [readyResult[0]]\n }\n return [undefined, readyResult[1]!.instance]\n }\n return null // Proceed with creation\n\n default:\n // For error states, remove the failed holder from storage so we can retry\n if (holder) {\n this.logger?.log(\n `[InstanceResolver] Removing failed instance ${instanceName} from storage to allow retry`,\n )\n storage.delete(instanceName)\n }\n return null // Proceed with creation\n }\n }\n\n /**\n * Creates a new instance and stores it using the provided storage strategy.\n * This unified method replaces instantiateServiceFromRegistry and createRequestScopedInstance.\n *\n * For transient services, the instance is created but not stored (no caching).\n */\n private async createAndStoreInstance<Instance>(\n instanceName: string,\n realToken: InjectionToken<Instance, any>,\n args: any,\n contextContainer: IContainer,\n storage: IHolderStorage,\n scopedContainer?: ScopedContainer,\n requestStorage?: IHolderStorage,\n requestId?: string,\n scope?: InjectableScope,\n ): Promise<[undefined, InstanceHolder<Instance>] | [DIError]> {\n this.logger?.log(\n `[InstanceResolver]#createAndStoreInstance() Creating instance for ${instanceName}`,\n )\n\n if (!this.registry.has(realToken)) {\n return [DIError.factoryNotFound(realToken.name.toString())]\n }\n\n const record = this.registry.get<Instance, any>(realToken)\n const { type, scope: recordScope } = record\n const serviceScope = scope || recordScope\n\n // For transient services, don't use storage locking - create directly\n if (serviceScope === InjectableScope.Transient) {\n return this.createTransientInstance(\n instanceName,\n record,\n args,\n contextContainer,\n scopedContainer,\n requestStorage,\n requestId,\n )\n }\n if (serviceScope === InjectableScope.Request && !requestStorage) {\n return [\n DIError.initializationError(\n `Request storage is required for request-scoped services`,\n instanceName,\n ),\n ]\n }\n\n let storageToUse: IHolderStorage\n if (serviceScope === InjectableScope.Request) {\n storageToUse = requestStorage!\n } else {\n storageToUse = storage\n }\n\n // Create holder in \"Creating\" state\n const [deferred, holder] = storageToUse.createHolder<Instance>(\n instanceName,\n type,\n new Set(),\n )\n // Store holder immediately (for lock mechanism)\n storageToUse.set(instanceName, holder)\n\n // Create context for service initialization\n const ctx = this.createServiceInitializationContext(\n scopedContainer ?? contextContainer,\n instanceName,\n serviceScope,\n holder.deps,\n realToken,\n requestStorage,\n requestId,\n )\n\n holder.destroyListeners = ctx.getDestroyListeners()\n\n // Create getHolder function for resolution context\n const getHolder = (name: string): InstanceHolder | undefined => {\n // Check both storages\n const result = storage.get(name)\n if (result && result[0] === undefined && result[1]) {\n return result[1]\n }\n if (requestStorage) {\n const reqResult = requestStorage.get(name)\n if (reqResult && reqResult[0] === undefined && reqResult[1]) {\n return reqResult[1]\n }\n }\n return undefined\n }\n\n // Start async instantiation within resolution context for circular dependency detection\n withResolutionContext(holder, getHolder, () => {\n this.serviceInitializer\n .instantiateService(ctx, record, args)\n .then(async (result: [undefined, Instance] | [DIError]) => {\n const [error, instance] =\n result.length === 2 ? result : [result[0], undefined]\n const newScope = record.scope\n const newName = this.nameResolver.generateInstanceName(\n realToken,\n args,\n requestId,\n newScope,\n )\n await this.handleInstantiationResult(\n newName,\n holder,\n ctx,\n deferred,\n newScope,\n error,\n instance,\n scopedContainer,\n requestStorage,\n requestId,\n )\n })\n .catch(async (error: Error) => {\n const newScope = record.scope\n const newName = this.nameResolver.generateInstanceName(\n realToken,\n args,\n requestId,\n newScope,\n )\n\n await this.handleInstantiationError(\n newName,\n holder,\n deferred,\n newScope,\n error,\n )\n })\n .catch(() => {\n // Suppress unhandled rejections from the async chain.\n // Errors are communicated to awaiters via deferred.reject() which\n // rejects holder.creationPromise. This catch is a safety net for\n // any errors that might occur in the error handling itself.\n })\n })\n\n // Wait for instance to be ready\n // Use resolution context to get waiterHolder if available\n const resolutionCtx = getCurrentResolutionContext()\n const waiterHolder = resolutionCtx?.waiterHolder\n return this.waitForInstanceReady(holder, waiterHolder, getHolder)\n }\n\n /**\n * Creates a transient instance without storage or locking.\n * Each call creates a new instance.\n */\n private async createTransientInstance<Instance>(\n instanceName: string,\n record: any,\n args: any,\n contextContainer: IContainer,\n scopedContainer?: ScopedContainer,\n requestStorage?: IHolderStorage,\n requestId?: string,\n ): Promise<[undefined, InstanceHolder<Instance>] | [DIError]> {\n this.logger?.log(\n `[InstanceResolver]#createTransientInstance() Creating transient instance for ${instanceName}`,\n )\n\n // Create a temporary holder for resolution context (transient instances can still have deps)\n const ctx = this.createServiceInitializationContext(\n scopedContainer ?? contextContainer,\n instanceName,\n InjectableScope.Transient,\n new Set(),\n record.originalToken,\n requestStorage,\n requestId,\n )\n\n const [error, instance] = await this.serviceInitializer.instantiateService(\n ctx,\n record,\n args,\n )\n\n if (error) {\n return [error]\n }\n\n // Create a temporary holder for the result\n const tempHolder: InstanceHolder<Instance> = {\n status: InstanceStatus.Created,\n name: instanceName,\n instance: instance as Instance,\n creationPromise: null,\n destroyPromise: null,\n type: record.type,\n scope: InjectableScope.Transient,\n deps: ctx.dependencies,\n destroyListeners: ctx.getDestroyListeners(),\n createdAt: Date.now(),\n waitingFor: new Set(),\n }\n\n return [undefined, tempHolder]\n }\n\n /**\n * Handles successful service instantiation.\n */\n private async handleInstantiationSuccess(\n instanceName: string,\n holder: InstanceHolder<any>,\n ctx: ServiceInitializationContext,\n deferred: any,\n instance: any,\n _scopedContainer?: ScopedContainer,\n requestStorage?: IHolderStorage,\n _requestId?: string,\n ): Promise<void> {\n holder.instance = instance\n holder.status = InstanceStatus.Created\n\n // Set up dependency subscriptions for event-based invalidation\n // Determine which storage to use for subscriptions\n const storageForSubscriptions = requestStorage || this.storage\n\n // Set up subscriptions via ServiceInvalidator\n if (ctx.dependencies.size > 0) {\n this.serviceInvalidator.setupDependencySubscriptions(\n instanceName,\n ctx.dependencies,\n storageForSubscriptions,\n holder,\n )\n }\n\n this.logger?.log(\n `[InstanceResolver] Instance ${instanceName} created successfully`,\n )\n deferred.resolve([undefined, instance])\n }\n\n /**\n * Handles service instantiation errors.\n */\n private async handleInstantiationError(\n instanceName: string,\n holder: InstanceHolder<any>,\n deferred: any,\n scope: InjectableScope,\n error: any,\n ): Promise<void> {\n holder.status = InstanceStatus.Error\n holder.instance = error instanceof DIError ? error : DIError.unknown(error)\n this.logger?.error(\n `[InstanceResolver] Instance ${instanceName} creation failed:`,\n error,\n )\n deferred.reject(error instanceof DIError ? error : DIError.unknown(error))\n }\n\n /**\n * Handles instantiation result (success or error).\n */\n private async handleInstantiationResult(\n instanceName: string,\n holder: InstanceHolder<any>,\n ctx: ServiceInitializationContext,\n deferred: any,\n scope: InjectableScope,\n error: any,\n instance: any,\n scopedContainer?: ScopedContainer,\n requestStorage?: IHolderStorage,\n requestId?: string,\n ): Promise<void> {\n if (error) {\n await this.handleInstantiationError(\n instanceName,\n holder,\n deferred,\n scope,\n error,\n )\n } else {\n await this.handleInstantiationSuccess(\n instanceName,\n holder,\n ctx,\n deferred,\n instance,\n scopedContainer,\n requestStorage,\n requestId,\n )\n }\n }\n\n /**\n * Waits for an instance holder to be ready and returns the appropriate result.\n *\n * @param holder The holder to wait for\n * @param waiterHolder Optional holder that is doing the waiting (for circular dependency detection)\n * @param getHolder Optional function to retrieve holders by name (required if waiterHolder is provided)\n */\n private async waitForInstanceReady<T>(\n holder: InstanceHolder<T>,\n waiterHolder?: InstanceHolder,\n getHolder?: (name: string) => InstanceHolder | undefined,\n ): Promise<[undefined, InstanceHolder<T>] | [DIError]> {\n switch (holder.status) {\n case InstanceStatus.Creating: {\n // Check for circular dependency before waiting\n if (waiterHolder && getHolder) {\n const cycle = CircularDetector.detectCycle(\n waiterHolder.name,\n holder.name,\n getHolder,\n )\n if (cycle) {\n return [DIError.circularDependency(cycle)]\n }\n\n if (process.env.NODE_ENV !== 'production') {\n // Track the waiting relationship\n waiterHolder.waitingFor.add(holder.name)\n }\n }\n\n try {\n await holder.creationPromise\n } finally {\n if (process.env.NODE_ENV !== 'production') {\n // Clean up the waiting relationship\n if (waiterHolder) {\n waiterHolder.waitingFor.delete(holder.name)\n }\n }\n }\n\n // Recursively check after creation completes\n return this.waitForInstanceReady(holder, waiterHolder, getHolder)\n }\n\n case InstanceStatus.Destroying:\n return [DIError.instanceDestroying(holder.name)]\n\n case InstanceStatus.Error:\n return [holder.instance as unknown as DIError]\n\n case InstanceStatus.Created:\n return [undefined, holder]\n\n default:\n // @ts-expect-error Maybe we will use this in the future\n return [DIError.instanceNotFound(holder?.name ?? 'unknown')]\n }\n }\n\n /**\n * Creates a ServiceInitializationContext for service instantiation.\n */\n private createServiceInitializationContext(\n container: IContainer,\n serviceName: string,\n scope: InjectableScope,\n deps: Set<string>,\n serviceToken: InjectionToken<any, any>,\n requestStorage?: IHolderStorage,\n requestId?: string,\n ): ServiceInitializationContext {\n const destroyListeners: Array<() => void> = []\n\n return {\n inject: async (token: any, args?: any) => {\n // Track dependency and check for scope upgrade\n const actualToken =\n typeof token === 'function'\n ? this.tokenResolver.normalizeToken(token)\n : token\n const realToken = this.tokenResolver.getRealToken(actualToken)\n const depRecord = this.registry.get(realToken)\n const depScope = depRecord.scope\n\n // Generate dependency name - if dependency is Request-scoped and we have requestId, use it\n const dependencyRequestId =\n depScope === InjectableScope.Request ? requestId : undefined\n const finalDepName = this.nameResolver.generateInstanceName(\n actualToken,\n args,\n dependencyRequestId,\n depScope,\n )\n\n // Check if current service needs scope upgrade\n // If current service is Singleton and dependency is Request, upgrade current service\n if (\n scope === InjectableScope.Singleton &&\n depScope === InjectableScope.Request &&\n requestStorage &&\n requestId\n ) {\n // Check and perform scope upgrade for current service\n // Use the dependency name with requestId for the check\n const [needsUpgrade, newServiceName] =\n this.scopeTracker.checkAndUpgradeScope(\n serviceName,\n scope,\n finalDepName,\n depScope,\n serviceToken,\n this.storage,\n requestStorage,\n requestId,\n )\n\n if (needsUpgrade && newServiceName) {\n // Service was upgraded - update the service name in context\n // The holder will be moved to request storage by ScopeTracker\n // For now, we continue with the current resolution\n // Future resolutions will use the new name\n }\n }\n\n // Track dependency\n deps.add(finalDepName)\n\n // Resolve dependency\n // Resolution context is automatically used by the injectors system for circular dependency detection\n return container.get(token, args)\n },\n container,\n addDestroyListener: (listener: () => void) => {\n destroyListeners.push(listener)\n },\n getDestroyListeners: () => destroyListeners,\n serviceName,\n dependencies: deps,\n scope,\n trackDependency: (name: string, depScope: InjectableScope) => {\n deps.add(name)\n // Check for scope upgrade\n if (\n scope === InjectableScope.Singleton &&\n depScope === InjectableScope.Request &&\n requestStorage &&\n requestId\n ) {\n this.scopeTracker.checkAndUpgradeScope(\n serviceName,\n scope,\n name,\n depScope,\n serviceToken,\n this.storage,\n requestStorage,\n requestId,\n )\n }\n },\n }\n }\n}\n","import type { InjectionTokenType } from '../../token/injection-token.mjs'\n\nimport { InjectableScope } from '../../enums/index.mjs'\n\n/**\n * Simple LRU cache for instance name generation.\n * Uses a Map which maintains insertion order for efficient LRU eviction.\n */\nclass InstanceNameCache {\n private readonly cache = new Map<string, string>()\n private readonly maxSize: number\n\n constructor(maxSize = 1000) {\n this.maxSize = maxSize\n }\n\n get(key: string): string | undefined {\n const value = this.cache.get(key)\n if (value !== undefined) {\n // Move to end (most recently used)\n this.cache.delete(key)\n this.cache.set(key, value)\n }\n return value\n }\n\n set(key: string, value: string): void {\n if (this.cache.has(key)) {\n this.cache.delete(key)\n } else if (this.cache.size >= this.maxSize) {\n // Remove least recently used (first item)\n const firstKey = this.cache.keys().next().value\n if (firstKey !== undefined) {\n this.cache.delete(firstKey)\n }\n }\n this.cache.set(key, value)\n }\n\n clear(): void {\n this.cache.clear()\n }\n}\n\n/**\n * Simple hash function for deterministic hashing of arguments\n */\nfunction hashArgs(args: any): string {\n const str = JSON.stringify(args, Object.keys(args || {}).sort())\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash = hash & hash // Convert to 32-bit integer\n }\n return Math.abs(hash).toString(36)\n}\n\n/**\n * Handles instance name generation with support for requestId and scope.\n *\n * Generates unique instance identifiers based on token, arguments, and scope.\n * Request-scoped services MUST include requestId in their name for proper isolation.\n */\nexport class NameResolver {\n private readonly instanceNameCache = new InstanceNameCache()\n\n constructor(private readonly logger: Console | null = null) {}\n\n /**\n * Generates a unique instance name based on token, arguments, requestId, and scope.\n *\n * Name formats:\n * - Singleton/Transient without args: `${tokenId}`\n * - Singleton/Transient with args: `${tokenId}:${argsHash}`\n * - Request without args: `${tokenId}:requestId=${requestId}`\n * - Request with args: `${tokenId}:requestId=${requestId}:${argsHash}`\n *\n * @param token The injection token\n * @param args Optional arguments\n * @param requestId Optional request ID (required for request-scoped services)\n * @param scope Optional scope (used to determine if requestId should be included)\n * @returns The generated instance name\n */\n generateInstanceName(\n token: InjectionTokenType,\n args?: any,\n requestId?: string,\n scope?: InjectableScope,\n ): string {\n const tokenStr = token.toString()\n const isRequest = scope === InjectableScope.Request\n\n // For request-scoped services, requestId is required\n if (isRequest && !requestId) {\n throw new Error(\n `[NameResolver] requestId is required for request-scoped services`,\n )\n }\n\n // Build cache key\n const cacheKey = `${tokenStr}:${scope}:${requestId || ''}:${args ? JSON.stringify(args) : ''}`\n\n // Check cache first\n const cached = this.instanceNameCache.get(cacheKey)\n if (cached !== undefined) {\n return cached\n }\n\n // Generate the instance name\n let result = tokenStr\n\n // Add requestId for request-scoped services\n if (isRequest && requestId) {\n result = `${result}:requestId=${requestId}`\n }\n\n // Add args hash if args are provided\n if (args) {\n const argsHash = hashArgs(args)\n result = `${result}:${argsHash}`\n }\n\n // Cache the result\n this.instanceNameCache.set(cacheKey, result)\n\n return result\n }\n\n /**\n * Upgrades an existing instance name to include requestId.\n * Preserves any args hash that might already be in the name.\n *\n * Examples:\n * - `TokenName` → `TokenName:requestId=req-123`\n * - `TokenName:abc123` → `TokenName:requestId=req-123:abc123`\n *\n * @param existingName The existing instance name (without requestId)\n * @param requestId The request ID to add\n * @returns The upgraded instance name with requestId\n */\n upgradeInstanceNameToRequest(\n existingName: string,\n requestId: string,\n ): string {\n // Check if requestId is already in the name\n if (existingName.includes(`:requestId=${requestId}`)) {\n return existingName\n }\n\n // Find where to insert requestId\n // Format: TokenName or TokenName:argsHash\n // We want: TokenName:requestId=req-123 or TokenName:requestId=req-123:argsHash\n\n // Check if there's an args hash (starts after first colon, but not requestId=)\n const requestIdPattern = /:requestId=/\n const hasRequestId = requestIdPattern.test(existingName)\n\n if (hasRequestId) {\n // Already has a requestId, don't upgrade\n return existingName\n }\n\n // Find the token part (everything before first colon, or entire string if no colon)\n const colonIndex = existingName.indexOf(':')\n if (colonIndex === -1) {\n // No colon, just token name: TokenName → TokenName:requestId=req-123\n return `${existingName}:requestId=${requestId}`\n }\n\n // Has colon, means there's an args hash: TokenName:abc123 → TokenName:requestId=req-123:abc123\n const tokenPart = existingName.substring(0, colonIndex)\n const argsPart = existingName.substring(colonIndex + 1)\n\n // Check if argsPart looks like an args hash (not requestId=)\n if (argsPart.startsWith('requestId=')) {\n // Already has requestId, return as is\n return existingName\n }\n\n return `${tokenPart}:requestId=${requestId}:${argsPart}`\n }\n\n /**\n * Formats a single argument value for instance name generation.\n */\n formatArgValue(value: any): string {\n if (typeof value === 'function') {\n return `fn_${value.name}(${value.length})`\n }\n if (typeof value === 'symbol') {\n return value.toString()\n }\n return JSON.stringify(value).slice(0, 40)\n }\n}\n","import type { InjectableScope } from '../../enums/index.mjs'\nimport type { InjectionToken } from '../../token/injection-token.mjs'\nimport type { IHolderStorage } from '../holder/holder-storage.interface.mjs'\n\nimport { InjectableScope as Scope } from '../../enums/index.mjs'\nimport { DIError } from '../../errors/index.mjs'\nimport { InstanceStatus } from '../holder/instance-holder.mjs'\nimport { Registry } from '../../token/registry.mjs'\nimport { NameResolver } from './name-resolver.mjs'\n\n/**\n * Component for tracking and handling scope upgrades.\n *\n * Detects when a Singleton service needs to be upgraded to Request scope\n * and coordinates the scope upgrade process atomically.\n */\nexport class ScopeTracker {\n constructor(\n private readonly registry: Registry,\n private readonly nameResolver: NameResolver,\n private readonly logger: Console | null = null,\n ) {}\n\n /**\n * Checks if a dependency requires scope upgrade and performs it if needed.\n * Called during service resolution when a dependency is resolved.\n *\n * @param currentServiceName - Name of the service being created\n * @param currentServiceScope - Current scope of the service being created\n * @param dependencyName - Name of the dependency being resolved\n * @param dependencyScope - Scope of the dependency\n * @param dependencyToken - Token of the dependency\n * @param singletonStorage - Singleton storage instance\n * @param requestStorage - Request storage instance (if in request context)\n * @param requestId - Request ID (if in request context)\n * @returns [needsUpgrade: boolean, newName?: string] - whether upgrade occurred and new name\n */\n checkAndUpgradeScope(\n currentServiceName: string,\n currentServiceScope: InjectableScope,\n dependencyName: string,\n dependencyScope: InjectableScope,\n dependencyToken: InjectionToken<any, any>,\n singletonStorage: IHolderStorage,\n requestStorage?: IHolderStorage,\n requestId?: string,\n ): [boolean, string?] {\n // Only upgrade if current service is Singleton and dependency is Request\n if (\n currentServiceScope !== Scope.Singleton ||\n dependencyScope !== Scope.Request\n ) {\n return [false]\n }\n\n // Need request storage and requestId for upgrade\n if (!requestStorage || !requestId) {\n this.logger?.warn(\n `[ScopeTracker] Cannot upgrade scope for ${currentServiceName}: missing requestStorage or requestId`,\n )\n return [false]\n }\n\n // Perform the upgrade\n this.logger?.log(\n `[ScopeTracker] Upgrading ${currentServiceName} from Singleton to Request scope`,\n )\n\n try {\n const [success, newName] = this.upgradeScopeToRequestSync(\n currentServiceName,\n dependencyToken,\n singletonStorage,\n requestStorage,\n requestId,\n )\n\n if (success && newName) {\n return [true, newName]\n }\n } catch (error) {\n this.logger?.error(\n `[ScopeTracker] Error upgrading scope for ${currentServiceName}:`,\n error,\n )\n }\n\n return [false]\n }\n\n /**\n * Performs the actual scope upgrade from Singleton to Request.\n * This is the core migration logic.\n *\n * @param serviceName - Current service name (without requestId)\n * @param token - Service injection token\n * @param singletonStorage - Source storage\n * @param requestStorage - Target storage\n * @param requestId - Request ID to include in new name\n * @returns [success: boolean, newName?: string, error?: DIError]\n */\n async upgradeScopeToRequest(\n serviceName: string,\n token: InjectionToken<any, any>,\n singletonStorage: IHolderStorage,\n requestStorage: IHolderStorage,\n requestId: string,\n ): Promise<[boolean, string?, DIError?]> {\n try {\n const [success, newName] = this.upgradeScopeToRequestSync(\n serviceName,\n token,\n singletonStorage,\n requestStorage,\n requestId,\n )\n\n if (success && newName) {\n return [true, newName]\n }\n return [\n false,\n undefined,\n DIError.storageError(\n 'Scope upgrade failed',\n 'upgradeScopeToRequest',\n serviceName,\n ),\n ]\n } catch (error) {\n return [\n false,\n undefined,\n error instanceof DIError ? error : DIError.unknown(error as Error),\n ]\n }\n }\n\n /**\n * Synchronous part of scope upgrade - handles immediate updates.\n * Async operations (like waiting for holder creation) should be done separately.\n */\n private upgradeScopeToRequestSync(\n serviceName: string,\n token: InjectionToken<any, any>,\n singletonStorage: IHolderStorage,\n requestStorage: IHolderStorage,\n requestId: string,\n ): [boolean, string?] {\n // 1. Upgrade existing instance name to include requestId\n // This preserves any args hash that might be in the original name\n const newName = this.nameResolver.upgradeInstanceNameToRequest(\n serviceName,\n requestId,\n )\n\n // 2. Update Registry scope to Request (synchronous)\n const updated = this.registry.updateScope(token, Scope.Request)\n if (!updated) {\n this.logger?.warn(\n `[ScopeTracker] Could not update scope in registry for ${serviceName}`,\n )\n return [false]\n }\n\n // 3. Check if holder exists in singleton storage\n const holderResult = singletonStorage.get(serviceName)\n if (holderResult === null) {\n // No holder exists yet - just update registry, future resolutions will use request storage\n return [true, newName]\n }\n\n const [error, holder] = holderResult\n if (error) {\n this.logger?.warn(\n `[ScopeTracker] Holder for ${serviceName} is in error state: ${error.message}`,\n )\n return [false]\n }\n\n if (!holder) {\n return [false]\n }\n\n // 4. If holder is in \"Creating\" state, we need to wait for it before migrating\n // For now, we'll update the name and move it, but the caller should wait for creation\n if (holder.status === InstanceStatus.Creating) {\n // Update holder name\n holder.name = newName\n // Move to request storage\n requestStorage.set(newName, holder)\n // Remove from singleton storage\n singletonStorage.delete(serviceName)\n // Update parent dependencies\n this.updateParentDependencies(\n serviceName,\n newName,\n singletonStorage,\n requestStorage,\n )\n return [true, newName]\n }\n\n // 5. Move holder from singleton to request storage\n holder.name = newName\n requestStorage.set(newName, holder)\n singletonStorage.delete(serviceName)\n\n // 6. Update all parent dependencies\n this.updateParentDependencies(\n serviceName,\n newName,\n singletonStorage,\n requestStorage,\n )\n\n return [true, newName]\n }\n\n /**\n * Updates all parent dependencies to reference the new service name.\n *\n * @param oldName - Original service name\n * @param newName - New service name with requestId\n * @param singletonStorage - Singleton storage to check\n * @param requestStorage - Request storage to check\n */\n updateParentDependencies(\n oldName: string,\n newName: string,\n singletonStorage: IHolderStorage,\n requestStorage?: IHolderStorage,\n ): void {\n // Update dependencies in singleton storage\n singletonStorage.updateDependencyReference(oldName, newName)\n\n // Update dependencies in request storage if provided\n if (requestStorage) {\n requestStorage.updateDependencyReference(oldName, newName)\n }\n }\n}\n","import type { FactoryRecord } from '../../token/registry.mjs'\nimport type { Injectors } from '../../utils/index.mjs'\nimport type { ServiceInitializationContext } from '../context/service-initialization-context.mjs'\n\nimport { InjectableType } from '../../enums/index.mjs'\nimport { DIError } from '../../errors/index.mjs'\n\n/**\n * Creates service instances from registry records.\n *\n * Handles both class-based (@Injectable) and factory-based (@Factory) services,\n * managing the instantiation lifecycle including lifecycle hook invocation.\n */\nexport class ServiceInitializer {\n constructor(private readonly injectors: Injectors) {}\n\n /**\n * Instantiates a service based on its registry record.\n * @param ctx The factory context for dependency injection\n * @param record The factory record from the registry\n * @param args Optional arguments for the service\n * @returns Promise resolving to [undefined, instance] or [error]\n */\n async instantiateService<T>(\n ctx: ServiceInitializationContext,\n record: FactoryRecord<T, any>,\n args: any = undefined,\n ): Promise<[undefined, T] | [DIError]> {\n try {\n switch (record.type) {\n case InjectableType.Class:\n return this.instantiateClass(ctx, record, args)\n case InjectableType.Factory:\n return this.instantiateFactory(ctx, record, args)\n default:\n throw DIError.unknown(\n `[ServiceInitializer] Unknown service type: ${record.type}`,\n )\n }\n } catch (error) {\n return [\n error instanceof DIError\n ? error\n : DIError.initializationError(record.target.name, error as Error),\n ]\n }\n }\n\n /**\n * Instantiates a class-based service (Injectable decorator).\n * @param ctx The factory context for dependency injection\n * @param record The factory record from the registry\n * @param args Optional arguments for the service constructor\n * @returns Promise resolving to [undefined, instance] or [error]\n */\n private async instantiateClass<T>(\n ctx: ServiceInitializationContext,\n record: FactoryRecord<T, any>,\n args: any,\n ): Promise<[undefined, T] | [DIError]> {\n try {\n const tryLoad = this.injectors.wrapSyncInit(() => {\n const original = this.injectors.provideFactoryContext(\n ctx as ServiceInitializationContext,\n )\n let result = new record.target(...(args ? [args] : []))\n this.injectors.provideFactoryContext(original)\n return result\n })\n\n let [instance, promises, injectState] = tryLoad()\n if (promises.length > 0) {\n const results = await Promise.allSettled(promises)\n if (results.some((result) => result.status === 'rejected')) {\n throw DIError.initializationError(\n record.target.name,\n new Error('Service cannot be instantiated'),\n )\n }\n const newRes = tryLoad(injectState)\n instance = newRes[0]\n promises = newRes[1]\n }\n\n if (promises.length > 0) {\n console.error(\n `[ServiceInitializer] ${record.target.name} has problem with it's definition.\n\n One or more of the dependencies are registered as a InjectableScope.Transient and are used with inject.\n\n Please use asyncInject instead of inject to load those dependencies.`,\n )\n throw DIError.initializationError(\n record.target.name,\n new Error('Service cannot be instantiated'),\n )\n }\n\n // Handle lifecycle hooks\n if ('onServiceInit' in instance) {\n await (instance as any).onServiceInit()\n }\n if ('onServiceDestroy' in instance) {\n ctx.addDestroyListener(async () => {\n await (instance as any).onServiceDestroy()\n })\n }\n\n return [undefined, instance]\n } catch (error) {\n return [\n error instanceof DIError\n ? error\n : DIError.initializationError(record.target.name, error as Error),\n ]\n }\n }\n\n /**\n * Instantiates a factory-based service (Factory decorator).\n * @param ctx The factory context for dependency injection\n * @param record The factory record from the registry\n * @param args Optional arguments for the factory\n * @returns Promise resolving to [undefined, instance] or [error]\n */\n private async instantiateFactory<T>(\n ctx: ServiceInitializationContext,\n record: FactoryRecord<T, any>,\n args: any,\n ): Promise<[undefined, T] | [DIError]> {\n try {\n const tryLoad = this.injectors.wrapSyncInit(() => {\n const original = this.injectors.provideFactoryContext(ctx)\n let result = new record.target()\n this.injectors.provideFactoryContext(original)\n return result\n })\n\n let [builder, promises, injectState] = tryLoad()\n if (promises.length > 0) {\n const results = await Promise.allSettled(promises)\n if (results.some((result) => result.status === 'rejected')) {\n throw DIError.initializationError(\n record.target.name,\n new Error('Service cannot be instantiated'),\n )\n }\n const newRes = tryLoad(injectState)\n builder = newRes[0]\n promises = newRes[1]\n }\n\n if (promises.length > 0) {\n console.error(\n `[ServiceInitializer] ${record.target.name} has problem with it's definition.\n\n One or more of the dependencies are registered as a InjectableScope.Transient and are used with inject.\n\n Please use asyncInject instead of inject to load those dependencies.`,\n )\n throw DIError.initializationError(\n record.target.name,\n new Error('Service cannot be instantiated'),\n )\n }\n\n if (typeof builder.create !== 'function') {\n throw DIError.initializationError(\n record.target.name,\n new Error('Factory does not implement the create method'),\n )\n }\n\n const instance = await builder.create(ctx, args)\n return [undefined, instance]\n } catch (error) {\n return [\n error instanceof DIError\n ? error\n : DIError.initializationError(record.target.name, error as Error),\n ]\n }\n }\n}\n","import type { IHolderStorage } from '../holder/holder-storage.interface.mjs'\nimport type { InstanceHolder } from '../holder/instance-holder.mjs'\nimport type { LifecycleEventBus } from '../lifecycle/lifecycle-event-bus.mjs'\n\nimport { InstanceStatus } from '../holder/instance-holder.mjs'\n\nexport interface ClearAllOptions {\n /** Whether to wait for all services to settle before starting (default: true) */\n waitForSettlement?: boolean\n}\n\nexport interface InvalidationOptions {\n /** Whether to emit events after invalidation (default: true) */\n emitEvents?: boolean\n /** Custom event emitter function */\n onInvalidated?: (instanceName: string) => Promise<void>\n /** Whether to cascade invalidation to dependents (default: false - events handle it) */\n cascade?: boolean\n}\n\n/**\n * Manages graceful service cleanup with event-based invalidation.\n *\n * Uses event subscriptions instead of manual dependent finding.\n * When a service is created, it subscribes to destroy events of its dependencies.\n * When a dependency is destroyed, the event automatically invalidates dependents.\n */\nexport class ServiceInvalidator {\n constructor(\n private readonly eventBus: LifecycleEventBus | null,\n private readonly logger: Console | null = null,\n ) {}\n\n /**\n * Invalidates a service using a specific storage.\n * Event-based invalidation means dependents are automatically invalidated\n * via destroy event subscriptions - no need to manually find dependents.\n *\n * @param service The instance name to invalidate\n * @param storage The storage to use for this invalidation\n * @param options Additional options for invalidation behavior\n */\n async invalidateWithStorage(\n service: string,\n storage: IHolderStorage,\n options: InvalidationOptions = {},\n ): Promise<void> {\n const { emitEvents = true, onInvalidated } = options\n\n this.logger?.log(\n `[ServiceInvalidator] Starting invalidation process for ${service}`,\n )\n\n const result = storage.get(service)\n if (result === null) {\n return\n }\n\n const [, holder] = result\n if (holder) {\n await this.invalidateHolderWithStorage(\n service,\n holder,\n storage,\n emitEvents,\n onInvalidated,\n )\n }\n }\n\n /**\n * Sets up destroy event subscriptions for a service's dependencies.\n * Called when a service is successfully instantiated.\n *\n * @param serviceName The name of the service\n * @param dependencies The set of dependency names\n * @param storage The storage to use for invalidation\n * @param holder The holder for the service (to add unsubscribe to destroy listeners)\n */\n setupDependencySubscriptions(\n serviceName: string,\n dependencies: Set<string>,\n storage: IHolderStorage,\n holder: InstanceHolder,\n ): void {\n if (!this.eventBus) {\n return\n }\n\n for (const dependencyName of dependencies) {\n // Subscribe to the dependency's destroy event\n const unsubscribe = this.eventBus.on(dependencyName, 'destroy', () => {\n this.logger?.log(\n `[ServiceInvalidator] Dependency ${dependencyName} destroyed, invalidating ${serviceName}`,\n )\n // Automatically invalidate this service when dependency is destroyed\n this.invalidateWithStorage(serviceName, storage).catch((error) => {\n this.logger?.error(\n `[ServiceInvalidator] Error invalidating ${serviceName} after dependency ${dependencyName} destroyed:`,\n error,\n )\n })\n })\n\n // Store unsubscribe function in the service's destroy listeners\n // so it's cleaned up when the service is destroyed\n holder.destroyListeners.push(unsubscribe)\n }\n }\n\n /**\n * Gracefully clears all services in a specific storage.\n * This allows clearing request-scoped services using a RequestStorage.\n */\n async clearAllWithStorage(\n storage: IHolderStorage,\n options: ClearAllOptions = {},\n ): Promise<void> {\n const { waitForSettlement = true } = options\n\n this.logger?.log(\n '[ServiceInvalidator] Starting graceful clearing of all services',\n )\n\n // Wait for all services to settle if requested\n if (waitForSettlement) {\n this.logger?.log(\n '[ServiceInvalidator] Waiting for all services to settle...',\n )\n await this.readyWithStorage(storage)\n }\n\n // Get all service names that need to be cleared\n const allServiceNames = storage.getAllNames()\n\n if (allServiceNames.length === 0) {\n this.logger?.log('[ServiceInvalidator] No services to clear')\n } else {\n this.logger?.log(\n `[ServiceInvalidator] Found ${allServiceNames.length} services to clear: ${allServiceNames.join(', ')}`,\n )\n\n // Clear services - events will handle dependent invalidation\n const clearPromises = allServiceNames.map((serviceName) =>\n this.invalidateWithStorage(serviceName, storage),\n )\n\n await Promise.all(clearPromises)\n }\n\n this.logger?.log('[ServiceInvalidator] Graceful clearing completed')\n }\n\n /**\n * Waits for all services in a specific storage to settle.\n */\n async readyWithStorage(storage: IHolderStorage): Promise<void> {\n const holders: InstanceHolder<any>[] = []\n storage.forEach((_: string, holder: InstanceHolder) => holders.push(holder))\n await Promise.all(\n holders.map((holder) => this.waitForHolderToSettle(holder)),\n )\n }\n\n // ============================================================================\n // INTERNAL INVALIDATION HELPERS\n // ============================================================================\n\n /**\n * Invalidates a single holder using a specific storage.\n */\n private async invalidateHolderWithStorage(\n key: string,\n holder: InstanceHolder<any>,\n storage: IHolderStorage,\n emitEvents: boolean,\n onInvalidated?: (instanceName: string) => Promise<void>,\n ): Promise<void> {\n await this.invalidateHolderByStatus(holder, {\n context: key,\n onDestroy: () =>\n this.destroyHolderWithStorage(\n key,\n holder,\n storage,\n emitEvents,\n onInvalidated,\n ),\n })\n }\n\n /**\n * Common invalidation logic for holders based on their status.\n */\n private async invalidateHolderByStatus(\n holder: InstanceHolder<any>,\n options: {\n context: string\n onDestroy: () => Promise<void>\n },\n ): Promise<void> {\n switch (holder.status) {\n case InstanceStatus.Destroying:\n await holder.destroyPromise\n break\n\n case InstanceStatus.Creating:\n // Wait for creation to complete before destroying\n await holder.creationPromise\n await options.onDestroy()\n break\n\n default:\n await options.onDestroy()\n break\n }\n }\n\n /**\n * Destroys a holder using a specific storage.\n */\n private async destroyHolderWithStorage(\n key: string,\n holder: InstanceHolder<any>,\n storage: IHolderStorage,\n emitEvents: boolean,\n onInvalidated?: (instanceName: string) => Promise<void>,\n ): Promise<void> {\n holder.status = InstanceStatus.Destroying\n this.logger?.log(\n `[ServiceInvalidator] Invalidating ${key} and notifying listeners`,\n )\n\n holder.destroyPromise = Promise.all(\n holder.destroyListeners.map((listener) => listener()),\n ).then(async () => {\n holder.destroyListeners = []\n holder.deps.clear()\n storage.delete(key)\n\n // Emit events if enabled and event bus exists\n if (emitEvents && this.eventBus) {\n await this.emitInstanceEvent(key, 'destroy')\n }\n\n // Call custom callback if provided\n if (onInvalidated) {\n await onInvalidated(key)\n }\n })\n\n await holder.destroyPromise\n }\n\n /**\n * Waits for a holder to settle (either created, destroyed, or error state).\n */\n private async waitForHolderToSettle(\n holder: InstanceHolder<any>,\n ): Promise<void> {\n switch (holder.status) {\n case InstanceStatus.Creating:\n await holder.creationPromise\n break\n case InstanceStatus.Destroying:\n await holder.destroyPromise\n break\n // Already settled states\n case InstanceStatus.Created:\n case InstanceStatus.Error:\n break\n }\n }\n\n /**\n * Emits events to listeners for instance lifecycle events.\n */\n private emitInstanceEvent(\n name: string,\n event: 'create' | 'destroy' = 'create',\n ) {\n if (!this.eventBus) {\n return Promise.resolve()\n }\n this.logger?.log(\n `[ServiceInvalidator]#emitInstanceEvent() Notifying listeners for ${name} with event ${event}`,\n )\n return this.eventBus.emit(name, event)\n }\n}\n","import type { z, ZodObject, ZodType } from 'zod/v4'\n\nimport type {\n Factorable,\n FactorableWithArgs,\n} from '../interfaces/factory.interface.mjs'\nimport type { ServiceInitializationContext } from '../internal/context/service-initialization-context.mjs'\nimport type {\n BoundInjectionToken,\n ClassType,\n ClassTypeWithArgument,\n ClassTypeWithoutArguments,\n FactoryInjectionToken,\n InjectionToken,\n InjectionTokenSchemaType,\n} from '../token/injection-token.mjs'\nimport type {\n InjectRequest,\n InjectState,\n Join,\n UnionToArray,\n} from './types.mjs'\n\nimport { withoutResolutionContext } from '../internal/context/resolution-context.mjs'\nimport { InjectableTokenMeta } from '../symbols/index.mjs'\n\nexport interface Injectors {\n // #1 Simple class\n asyncInject<T extends ClassTypeWithoutArguments>(\n token: T,\n ): InstanceType<T> extends Factorable<infer R>\n ? Promise<R>\n : Promise<InstanceType<T>>\n asyncInject<Args, T extends ClassTypeWithArgument<Args>>(\n token: T,\n args: Args,\n ): Promise<InstanceType<T>>\n asyncInject<\n Schema extends InjectionTokenSchemaType,\n R,\n T extends FactorableWithArgs<R, Schema>,\n >(\n token: T,\n args: z.input<Schema>,\n ): Promise<R>\n\n // #2 Token with required Schema\n asyncInject<T, S extends InjectionTokenSchemaType>(\n token: InjectionToken<T, S>,\n args: z.input<S>,\n ): Promise<T>\n // #3 Token with optional Schema\n asyncInject<T, S extends InjectionTokenSchemaType, R extends boolean>(\n token: InjectionToken<T, S, R>,\n ): R extends false\n ? Promise<T>\n : S extends ZodType<infer Type>\n ? `Error: Your token requires args: ${Join<\n UnionToArray<keyof Type>,\n ', '\n >}`\n : 'Error: Your token requires args'\n // #4 Token with no Schema\n asyncInject<T>(token: InjectionToken<T, undefined>): Promise<T>\n asyncInject<T>(token: BoundInjectionToken<T, any>): Promise<T>\n asyncInject<T>(token: FactoryInjectionToken<T, any>): Promise<T>\n\n inject<T extends ClassTypeWithoutArguments>(\n token: T,\n ): InstanceType<T> extends Factorable<infer R> ? R : InstanceType<T>\n inject<Args, T extends ClassTypeWithArgument<Args>>(\n token: T,\n args: Args,\n ): InstanceType<T>\n inject<\n Schema extends InjectionTokenSchemaType,\n R,\n T extends FactorableWithArgs<R, Schema>,\n >(\n token: T,\n args: z.input<Schema>,\n ): R\n\n inject<T, S extends InjectionTokenSchemaType>(\n token: InjectionToken<T, S>,\n args: z.input<S>,\n ): T\n // #3 Token with optional Schema\n inject<T, S extends InjectionTokenSchemaType, R extends boolean>(\n token: InjectionToken<T, S, R>,\n ): R extends false\n ? T\n : S extends ZodType<infer Type>\n ? `Error: Your token requires args: ${Join<\n UnionToArray<keyof Type>,\n ', '\n >}`\n : 'Error: Your token requires args'\n inject<T>(token: InjectionToken<T, undefined>): T\n inject<T>(token: BoundInjectionToken<T, any>): T\n inject<T>(token: FactoryInjectionToken<T, any>): T\n\n /**\n * Optional injection that returns null if the service fails to initialize\n * or is not available. This is useful when you want to inject a service\n * that may not be configured or may fail gracefully.\n *\n * @example\n * ```ts\n * class MyService {\n * constructor() {\n * const optionalService = optional(OptionalServiceToken)\n * // optionalService will be null if initialization fails\n * if (optionalService) {\n * optionalService.doSomething()\n * }\n * }\n * }\n * ```\n */\n optional<T extends ClassType>(\n token: T,\n ): (InstanceType<T> extends Factorable<infer R> ? R : InstanceType<T>) | null\n optional<T, S extends InjectionTokenSchemaType>(\n token: InjectionToken<T, S>,\n args: z.input<S>,\n ): T | null\n optional<T, S extends InjectionTokenSchemaType, R extends boolean>(\n token: InjectionToken<T, S, R>,\n ): R extends false\n ? T | null\n : S extends ZodType<infer Type>\n ? `Error: Your token requires args: ${Join<\n UnionToArray<keyof Type>,\n ', '\n >}`\n : 'Error: Your token requires args'\n optional<T>(token: InjectionToken<T, undefined>): T | null\n optional<T>(token: BoundInjectionToken<T, any>): T | null\n optional<T>(token: FactoryInjectionToken<T, any>): T | null\n\n wrapSyncInit(\n cb: () => any,\n ): (injectState?: InjectState) => [any, Promise<any>[], InjectState]\n\n provideFactoryContext(\n context: ServiceInitializationContext | null,\n ): ServiceInitializationContext | null\n}\n\nexport function getInjectors() {\n let currentFactoryContext: ServiceInitializationContext | null = null\n\n function provideFactoryContext(\n context: ServiceInitializationContext | null,\n ): ServiceInitializationContext | null {\n const original = currentFactoryContext\n currentFactoryContext = context\n return original\n }\n function getFactoryContext(): ServiceInitializationContext {\n if (!currentFactoryContext) {\n throw new Error(\n '[Injector] Trying to access injection context outside of a injectable context',\n )\n }\n return currentFactoryContext\n }\n\n let promiseCollector: null | ((promise: Promise<any>) => void) = null\n let injectState: InjectState | null = null\n\n function getRequest(\n token: InjectionToken<any>,\n args?: unknown,\n skipCycleTracking = false,\n ) {\n if (!injectState) {\n throw new Error(\n '[Injector] Trying to make a request outside of a injectable context',\n )\n }\n if (injectState.isFrozen) {\n const idx = injectState.currentIndex++\n const request = injectState.requests[idx]\n if (request.token !== token) {\n throw new Error(\n `[Injector] Wrong token order. Expected ${request.token.toString()} but got ${token.toString()}`,\n )\n }\n return request\n }\n let result: any = null\n let error: Error | null = null\n\n // For async inject, we run outside the resolution context to skip cycle tracking.\n // This is because asyncInject returns a promise that doesn't block the constructor,\n // so it cannot cause a deadlock even with circular dependencies.\n const doInject = () =>\n getFactoryContext()\n .inject(token as any, args as any)\n .then((r) => {\n result = r\n return r\n })\n .catch((e) => {\n // We don't throw here because we have a mechanism to handle errors\n error = e\n })\n\n const promise = skipCycleTracking\n ? withoutResolutionContext(doInject)\n : doInject()\n\n const request: InjectRequest = {\n token,\n promise,\n get result() {\n return result\n },\n get error() {\n return error\n },\n }\n injectState.requests.push(request)\n injectState.currentIndex++\n\n return request\n }\n\n function asyncInject(\n token:\n | ClassType\n | InjectionToken<any>\n | BoundInjectionToken<any, any>\n | FactoryInjectionToken<any, any>,\n args?: unknown,\n ) {\n if (!injectState) {\n throw new Error(\n '[Injector] Trying to access inject outside of a injectable context',\n )\n }\n // @ts-expect-error In case we have a class\n const realToken = token[InjectableTokenMeta] ?? token\n // Pass skipCycleTracking=true because asyncInject returns a promise that doesn't\n // block the constructor, so it cannot cause a deadlock even with circular dependencies.\n const request = getRequest(realToken, args, true)\n return request.promise.then((result) => {\n if (request.error) {\n // We throw here because we want to fail the asyncInject call if the dependency fails to initialize\n throw request.error\n }\n return result\n })\n }\n\n function wrapSyncInit(cb: () => any) {\n return (previousState?: InjectState) => {\n const promises: Promise<any>[] = []\n const originalPromiseCollector = promiseCollector\n const originalInjectState = injectState\n injectState = previousState\n ? {\n ...previousState,\n currentIndex: 0,\n }\n : {\n currentIndex: 0,\n isFrozen: false,\n requests: [],\n }\n promiseCollector = (promise) => {\n promises.push(promise)\n }\n const result = cb()\n promiseCollector = originalPromiseCollector\n const newInjectState = {\n ...injectState,\n isFrozen: true,\n }\n injectState = originalInjectState\n return [result, promises, newInjectState]\n }\n }\n\n function inject<\n T,\n Token extends\n | InjectionToken<T>\n | BoundInjectionToken<T, any>\n | FactoryInjectionToken<T, any>,\n S extends ZodObject | unknown = Token['schema'],\n >(token: Token, args?: S extends ZodObject ? z.input<S> : never): T {\n // @ts-expect-error In case we have a class\n const realToken = token[InjectableTokenMeta] ?? token\n\n if (!injectState) {\n throw new Error(\n '[Injector] Trying to access inject outside of a injectable context',\n )\n }\n\n const ctx = getFactoryContext()\n const instance = ctx.container.tryGetSync(realToken, args)\n if (!instance) {\n const request = getRequest(realToken, args)\n if (request.error) {\n throw request.error\n } else if (request.result) {\n return request.result\n }\n if (promiseCollector) {\n promiseCollector(request.promise)\n }\n // Return a dynamic proxy that looks up the instance when accessed\n return new Proxy(\n {},\n {\n get() {\n throw new Error(\n `[Injector] Trying to access ${realToken.toString()} before it's initialized, please move the code to a onServiceInit method`,\n )\n },\n },\n ) as unknown as T\n }\n\n // Even when tryGetSync returns an existing instance, we still need to\n // track the dependency for scope upgrade. This ensures that if a Singleton\n // service depends on an already-created Request-scoped service, the\n // Singleton will be properly upgraded to Request scope.\n // The ctx.inject call handles dependency tracking and scope upgrades.\n // We fire-and-forget this since we already have the instance.\n ctx.inject(realToken, args).catch(() => {\n // Ignore errors - we already have the instance\n })\n\n return instance as unknown as T\n }\n\n function optional<\n T,\n Token extends\n | InjectionToken<T>\n | BoundInjectionToken<T, any>\n | FactoryInjectionToken<T, any>,\n S extends ZodObject | unknown = Token['schema'],\n >(token: Token, args?: S extends ZodObject ? z.input<S> : never): T | null {\n try {\n return inject(token, args)\n } catch {\n // If injection fails, return null instead of throwing\n return null\n }\n }\n\n const injectors: Injectors = {\n asyncInject,\n inject,\n optional,\n wrapSyncInit,\n provideFactoryContext,\n } as Injectors\n\n return injectors\n}\n","import type { Injectors } from './get-injectors.mjs'\n\nimport { getInjectors } from './get-injectors.mjs'\n\nexport const defaultInjectors = /* #__PURE__ */ getInjectors()\n\nexport const inject: Injectors['inject'] =\n /* #__PURE__ */ defaultInjectors.inject\nexport const optional: Injectors['optional'] =\n /* #__PURE__ */ defaultInjectors.optional\nexport const asyncInject: Injectors['asyncInject'] =\n /* #__PURE__ */ defaultInjectors.asyncInject\nexport const wrapSyncInit: Injectors['wrapSyncInit'] =\n /* #__PURE__ */ defaultInjectors.wrapSyncInit\nexport const provideFactoryContext: Injectors['provideFactoryContext'] =\n /* #__PURE__ */ defaultInjectors.provideFactoryContext\n","import type { ClassType, InjectionToken } from '../token/injection-token.mjs'\n\nimport { DIError } from '../errors/di-error.mjs'\nimport { InjectableTokenMeta } from '../symbols/index.mjs'\n\nexport function getInjectableToken<R>(\n target: ClassType,\n): R extends { create(...args: any[]): infer V }\n ? InjectionToken<V>\n : InjectionToken<R> {\n // @ts-expect-error We inject the token into the class itself\n const token = target[InjectableTokenMeta] as InjectionToken<any, any>\n if (!token) {\n throw DIError.classNotInjectable(target.name)\n }\n // @ts-expect-error We detect factory or class\n return token\n}\n","import type {\n AnyInjectableType,\n InjectionTokenType,\n} from '../../token/injection-token.mjs'\n\nimport { DIError } from '../../errors/index.mjs'\nimport {\n BoundInjectionToken,\n FactoryInjectionToken,\n InjectionToken,\n} from '../../token/injection-token.mjs'\nimport { getInjectableToken } from '../../utils/index.mjs'\n\n/**\n * Handles token validation and resolution.\n *\n * Focuses on token validation, normalization, and argument validation.\n * Name generation is handled by NameResolver.\n */\nexport class TokenResolver {\n constructor(private readonly logger: Console | null = null) {}\n\n // ============================================================================\n // TOKEN NORMALIZATION\n // ============================================================================\n\n /**\n * Normalizes a token to an InjectionToken.\n * Handles class constructors by getting their injectable token.\n *\n * @param token A class constructor, InjectionToken, BoundInjectionToken, or FactoryInjectionToken\n * @returns The normalized InjectionTokenType\n */\n normalizeToken(token: AnyInjectableType): InjectionTokenType {\n if (typeof token === 'function') {\n return getInjectableToken(token)\n }\n return token as InjectionTokenType\n }\n\n /**\n * Gets the underlying \"real\" token from wrapped tokens.\n * For BoundInjectionToken and FactoryInjectionToken, returns the wrapped token.\n * For other tokens, returns the token itself.\n *\n * @param token The token to unwrap\n * @returns The underlying InjectionToken\n */\n getRealToken<T = unknown>(token: InjectionTokenType): InjectionToken<T> {\n if (\n token instanceof BoundInjectionToken ||\n token instanceof FactoryInjectionToken\n ) {\n return token.token as InjectionToken<T>\n }\n return token as InjectionToken<T>\n }\n\n /**\n * Convenience method that normalizes a token and then gets the real token.\n * Useful for checking registry entries where you need the actual registered token.\n *\n * @param token Any injectable type\n * @returns The underlying InjectionToken\n */\n getRegistryToken<T = unknown>(token: AnyInjectableType): InjectionToken<T> {\n return this.getRealToken(this.normalizeToken(token))\n }\n\n // ============================================================================\n // TOKEN VALIDATION\n // ============================================================================\n\n /**\n * Validates and resolves token arguments, handling factory token resolution and validation.\n *\n * @param token The token to validate\n * @param args Optional arguments\n * @returns [error, { actualToken, validatedArgs }]\n */\n validateAndResolveTokenArgs(\n token: AnyInjectableType,\n args?: any,\n ): [\n DIError | undefined,\n { actualToken: InjectionTokenType; validatedArgs?: any },\n ] {\n let actualToken = token as InjectionToken<any, any>\n if (typeof token === 'function') {\n actualToken = getInjectableToken(token)\n }\n let realArgs = args\n if (actualToken instanceof BoundInjectionToken) {\n realArgs = actualToken.value\n } else if (actualToken instanceof FactoryInjectionToken) {\n if (actualToken.resolved) {\n realArgs = actualToken.value\n } else {\n return [DIError.factoryTokenNotResolved(token.name), { actualToken }]\n }\n }\n if (!actualToken.schema) {\n return [undefined, { actualToken, validatedArgs: realArgs }]\n }\n const validatedArgs = actualToken.schema?.safeParse(realArgs)\n if (validatedArgs && !validatedArgs.success) {\n this.logger?.error(\n `[TokenResolver]#validateAndResolveTokenArgs(): Error validating args for ${actualToken.name.toString()}`,\n validatedArgs.error,\n )\n return [\n DIError.tokenValidationError(\n `Validation failed for ${actualToken.name.toString()}`,\n actualToken.schema,\n realArgs,\n ),\n { actualToken },\n ]\n }\n return [undefined, { actualToken, validatedArgs: validatedArgs?.data }]\n }\n}\n","import type { OnServiceDestroy } from '../../interfaces/index.mjs'\nimport type {\n HolderGetResult,\n IHolderStorage,\n} from './holder-storage.interface.mjs'\nimport type { InstanceHolder } from './instance-holder.mjs'\n\nimport { InjectableScope, InjectableType } from '../../enums/index.mjs'\nimport { DIError } from '../../errors/index.mjs'\nimport { InstanceStatus } from './instance-holder.mjs'\n\n/**\n * Unified storage implementation that works the same way regardless of scope.\n * Replaces RequestContext, HolderManager, SingletonStorage, RequestStorage.\n *\n * Scope is just metadata - storage operations are identical for all scopes.\n * Different storage instances are just isolated storage spaces.\n */\nexport class UnifiedStorage implements IHolderStorage {\n readonly scope: InjectableScope\n\n private readonly holders = new Map<string, InstanceHolder>()\n /**\n * Reverse dependency index: maps a dependency name to the set of holder names that depend on it.\n * This allows O(1) lookup of dependents instead of O(n) iteration.\n */\n private readonly dependents = new Map<string, Set<string>>()\n\n constructor(scope: InjectableScope = InjectableScope.Singleton) {\n this.scope = scope\n }\n\n get<T = unknown>(instanceName: string): HolderGetResult<T> {\n const holder = this.holders.get(instanceName)\n\n if (!holder) {\n return null\n }\n\n // Check holder status for error states\n switch (holder.status) {\n case InstanceStatus.Destroying:\n return [\n DIError.instanceDestroying(instanceName),\n holder as InstanceHolder<T>,\n ]\n\n case InstanceStatus.Error:\n return [\n holder.instance as unknown as DIError,\n holder as InstanceHolder<T>,\n ]\n\n case InstanceStatus.Creating:\n case InstanceStatus.Created:\n return [undefined, holder as InstanceHolder<T>]\n\n default:\n return null\n }\n }\n\n set(instanceName: string, holder: InstanceHolder): void {\n this.holders.set(instanceName, holder)\n // Register dependencies in reverse index\n if (holder.deps.size > 0) {\n this.registerDependencies(instanceName, holder.deps)\n }\n }\n\n delete(instanceName: string): boolean {\n const holder = this.holders.get(instanceName)\n if (holder) {\n // Remove this holder from the reverse index for all its dependencies\n this.removeFromDependentsIndex(instanceName, holder.deps)\n }\n return this.holders.delete(instanceName)\n }\n\n createHolder<T>(\n instanceName: string,\n type: InjectableType,\n deps: Set<string>,\n ): [\n ReturnType<typeof Promise.withResolvers<[undefined, T]>>,\n InstanceHolder<T>,\n ] {\n const deferred = Promise.withResolvers<[undefined, T]>()\n\n const holder: InstanceHolder<T> = {\n status: InstanceStatus.Creating,\n name: instanceName,\n instance: null,\n creationPromise: deferred.promise,\n destroyPromise: null,\n type,\n scope: this.scope,\n deps,\n destroyListeners: [],\n createdAt: Date.now(),\n waitingFor: new Set(),\n }\n\n return [deferred, holder]\n }\n\n storeInstance(instanceName: string, instance: unknown): void {\n const holder = this.holders.get(instanceName)\n if (holder) {\n throw DIError.storageError(\n 'Instance already stored',\n 'storeInstance',\n instanceName,\n )\n }\n this.set(instanceName, {\n status: InstanceStatus.Created,\n name: instanceName,\n instance,\n creationPromise: null,\n destroyPromise: null,\n type: InjectableType.Class,\n scope: this.scope,\n deps: new Set(),\n destroyListeners:\n typeof instance === 'object' &&\n instance !== null &&\n 'onServiceDestroy' in instance\n ? [(instance as OnServiceDestroy).onServiceDestroy]\n : [],\n createdAt: Date.now(),\n waitingFor: new Set(),\n })\n }\n\n handles(scope: InjectableScope): boolean {\n return scope === this.scope\n }\n\n // ============================================================================\n // ITERATION AND QUERY\n // ============================================================================\n\n getAllNames(): string[] {\n return Array.from(this.holders.keys())\n }\n\n forEach(callback: (name: string, holder: InstanceHolder) => void): void {\n for (const [name, holder] of this.holders) {\n callback(name, holder)\n }\n }\n\n findByInstance(instance: unknown): InstanceHolder | null {\n for (const holder of this.holders.values()) {\n if (holder.instance === instance) {\n return holder\n }\n }\n return null\n }\n\n findDependents(instanceName: string): string[] {\n const dependents = this.dependents.get(instanceName)\n return dependents ? Array.from(dependents) : []\n }\n\n /**\n * Updates dependency references when instance names change.\n * Used during scope upgrades when instance names are regenerated with requestId.\n *\n * @param oldName The old instance name\n * @param newName The new instance name\n */\n updateDependencyReference(oldName: string, newName: string): void {\n // Update all holders that reference oldName in their deps Set\n for (const holder of this.holders.values()) {\n if (holder.deps.has(oldName)) {\n holder.deps.delete(oldName)\n holder.deps.add(newName)\n }\n }\n\n // Update reverse dependency index\n const oldDependents = this.dependents.get(oldName)\n if (oldDependents) {\n // Move dependents from old name to new name\n const newDependents = this.dependents.get(newName) || new Set<string>()\n for (const dependent of oldDependents) {\n newDependents.add(dependent)\n }\n this.dependents.set(newName, newDependents)\n this.dependents.delete(oldName)\n }\n\n // Update reverse index entries - if oldName was a dependency, update all holders that depend on it\n for (const [depName, dependents] of this.dependents.entries()) {\n if (depName === oldName) {\n // This shouldn't happen, but handle it just in case\n const newDependents = this.dependents.get(newName) || new Set<string>()\n for (const dependent of dependents) {\n newDependents.add(dependent)\n }\n this.dependents.set(newName, newDependents)\n this.dependents.delete(oldName)\n }\n }\n }\n\n // ============================================================================\n // INTERNAL HELPERS\n // ============================================================================\n\n /**\n * Registers a holder's dependencies in the reverse index.\n */\n private registerDependencies(holderName: string, deps: Set<string>): void {\n for (const dep of deps) {\n let dependents = this.dependents.get(dep)\n if (!dependents) {\n dependents = new Set()\n this.dependents.set(dep, dependents)\n }\n dependents.add(holderName)\n }\n }\n\n /**\n * Removes a holder from the reverse dependency index.\n */\n private removeFromDependentsIndex(\n holderName: string,\n deps: Set<string>,\n ): void {\n for (const dep of deps) {\n const dependents = this.dependents.get(dep)\n if (dependents) {\n dependents.delete(holderName)\n if (dependents.size === 0) {\n this.dependents.delete(dep)\n }\n }\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-empty-object-type */\n/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n\ntype ListenersMap = Map<string, Map<string, Set<Function>>>\n\n/**\n * Event bus for service lifecycle events (create, destroy, etc.).\n *\n * Enables loose coupling between services by allowing them to subscribe\n * to lifecycle events of their dependencies without direct references.\n * Used primarily for invalidation cascading.\n */\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\nexport class LifecycleEventBus {\n private listeners: ListenersMap = new Map()\n constructor(private readonly logger: Console | null = null) {}\n\n on<Event extends string | `pre:${string}` | `post:${string}`>(\n ns: string,\n event: Event,\n listener: (event: Event) => void,\n ) {\n this.logger?.debug(`[LifecycleEventBus]#on(): ns:${ns} event:${event}`)\n if (!this.listeners.has(ns)) {\n this.listeners.set(ns, new Map())\n }\n\n const nsEvents = this.listeners.get(ns)!\n if (!nsEvents.has(event)) {\n nsEvents.set(event, new Set())\n }\n\n nsEvents.get(event)!.add(listener)\n\n return () => {\n nsEvents.get(event)?.delete(listener)\n if (nsEvents.get(event)?.size === 0) {\n nsEvents.delete(event)\n }\n if (nsEvents.size === 0) {\n this.listeners.delete(ns)\n }\n }\n }\n\n async emit(key: string, event: string) {\n if (!this.listeners.has(key)) {\n return\n }\n\n const events = this.listeners.get(key)!\n\n this.logger?.debug(`[LifecycleEventBus]#emit(): ${key}:${event}`)\n\n const res = await Promise.allSettled(\n [...(events.get(event) ?? [])!].map((listener) => listener(event)),\n ).then((results) => {\n const res = results\n .filter((result) => result.status === 'rejected')\n .map((result: PromiseRejectedResult) => {\n this.logger?.warn(\n `[LifecycleEventBus]#emit(): ${key}:${event} rejected with`,\n result.reason,\n )\n return result\n })\n\n if (res.length > 0) {\n return Promise.reject(res)\n }\n return results\n })\n return res\n }\n}\n\n","import { DIError } from '../errors/di-error.mjs'\n\n/**\n * Stub factory class used when registering InjectionTokens without a real class implementation.\n * This is used in ScopedContainer.addInstance() to allow registering tokens that don't have\n * a corresponding class, while preventing accidental instantiation.\n *\n * @internal\n */\nexport class StubFactoryClass {\n constructor() {\n throw DIError.factoryNotFound(\n 'Trying to get instance of factory without real implementation',\n )\n }\n}\n","import type { z, ZodType } from 'zod/v4'\n\nimport type { IContainer } from '../interfaces/container.interface.mjs'\nimport type { Factorable } from '../interfaces/factory.interface.mjs'\nimport type { NameResolver } from '../internal/core/name-resolver.mjs'\nimport type { ServiceInvalidator } from '../internal/core/service-invalidator.mjs'\nimport type { TokenResolver } from '../internal/core/token-resolver.mjs'\nimport type {\n ClassType,\n ClassTypeWithArgument,\n InjectionTokenSchemaType,\n} from '../token/injection-token.mjs'\nimport type { Registry } from '../token/registry.mjs'\nimport type { Join, UnionToArray } from '../utils/types.mjs'\n\nimport { InjectableScope, InjectableType } from '../enums/index.mjs'\nimport { DIError, DIErrorCode } from '../errors/index.mjs'\nimport { InstanceStatus } from '../internal/holder/instance-holder.mjs'\nimport { UnifiedStorage } from '../internal/holder/unified-storage.mjs'\nimport { StubFactoryClass } from '../internal/index.mjs'\nimport {\n BoundInjectionToken,\n FactoryInjectionToken,\n InjectionToken,\n} from '../token/injection-token.mjs'\n\n/**\n * Abstract base class for dependency injection containers.\n *\n * Provides shared implementation for common container operations.\n * Both Container and ScopedContainer extend this class.\n */\nexport abstract class AbstractContainer implements IContainer {\n /**\n * The default scope used when adding instances without explicit registration.\n */\n protected abstract readonly defaultScope: InjectableScope\n\n /**\n * The request ID for scoped containers, undefined for root container.\n */\n protected abstract readonly requestId: string | undefined\n\n // ============================================================================\n // ABSTRACT METHODS - Must be implemented by subclasses\n // ============================================================================\n\n /**\n * Gets the storage for this container.\n */\n abstract getStorage(): UnifiedStorage\n\n /**\n * Gets the registry for this container.\n */\n protected abstract getRegistry(): Registry\n\n /**\n * Gets the token resolver.\n */\n protected abstract getTokenResolver(): TokenResolver\n\n /**\n * Gets the name resolver.\n */\n protected abstract getNameResolver(): NameResolver\n\n /**\n * Gets the service invalidator.\n */\n protected abstract getServiceInvalidator(): ServiceInvalidator\n\n /**\n * Gets an instance from the container.\n */\n // #1 Simple class\n abstract get<T extends ClassType>(\n token: T,\n ): InstanceType<T> extends Factorable<infer R>\n ? Promise<R>\n : Promise<InstanceType<T>>\n // #1.1 Simple class with args\n abstract get<T extends ClassTypeWithArgument<R>, R>(\n token: T,\n args: R,\n ): Promise<InstanceType<T>>\n // #2 Token with required Schema\n abstract get<T, S extends InjectionTokenSchemaType>(\n token: InjectionToken<T, S>,\n args: z.input<S>,\n ): Promise<T>\n // #3 Token with optional Schema\n abstract get<T, S extends InjectionTokenSchemaType, R extends boolean>(\n token: InjectionToken<T, S, R>,\n ): R extends false\n ? Promise<T>\n : S extends ZodType<infer Type>\n ? `Error: Your token requires args: ${Join<\n UnionToArray<keyof Type>,\n ', '\n >}`\n : 'Error: Your token requires args'\n // #4 Token with no Schema\n abstract get<T>(token: InjectionToken<T, undefined>): Promise<T>\n abstract get<T>(token: BoundInjectionToken<T, any>): Promise<T>\n abstract get<T>(token: FactoryInjectionToken<T, any>): Promise<T>\n\n /**\n * Invalidates a service and its dependencies.\n */\n abstract invalidate(service: unknown): Promise<void>\n\n /**\n * Disposes the container and cleans up all resources.\n */\n abstract dispose(): Promise<void>\n\n // ============================================================================\n // SHARED IMPLEMENTATIONS\n // ============================================================================\n\n /**\n * Calculates the instance name for a given token and optional arguments.\n *\n * @internal\n * @param token The class type, InjectionToken, BoundInjectionToken, or FactoryInjectionToken\n * @param args Optional arguments (ignored for BoundInjectionToken which uses its bound value)\n * @returns The calculated instance name string, or null if the token is a FactoryInjectionToken that is not yet resolved\n */\n calculateInstanceName(\n token:\n | ClassType\n | InjectionToken<any, any>\n | BoundInjectionToken<any, any>\n | FactoryInjectionToken<any, any>,\n args?: unknown,\n ): string | null {\n const tokenResolver = this.getTokenResolver()\n\n // Use validateAndResolveTokenArgs to handle token normalization and arg resolution\n const [err, { actualToken, validatedArgs }] =\n tokenResolver.validateAndResolveTokenArgs(token, args)\n\n if (err) {\n // Return null if factory token is not resolved\n if (\n err instanceof DIError &&\n err.code === DIErrorCode.FactoryTokenNotResolved\n ) {\n return null\n }\n\n // Return null if validation fails (can't calculate name with invalid args)\n if (\n err instanceof DIError &&\n err.code === DIErrorCode.TokenValidationError\n ) {\n return null\n }\n }\n\n // Get the real token for registry lookup to determine scope\n const realToken = this.getTokenResolver().getRealToken(actualToken)\n\n const registry = this.getRegistry()\n\n // Get scope from registry, or use default scope if not registered\n const scope = registry.has(realToken)\n ? registry.get(realToken).scope\n : this.defaultScope\n\n // Generate instance name using the name resolver with actual token and validated args\n return this.getNameResolver().generateInstanceName(\n actualToken,\n validatedArgs,\n scope === InjectableScope.Request ? this.requestId : undefined,\n scope,\n )\n }\n\n /**\n * Checks if a service is registered in the container.\n */\n isRegistered(token: any): boolean {\n const realToken = this.getTokenResolver().getRegistryToken(token)\n return this.getRegistry().has(realToken)\n }\n\n /**\n * Waits for all pending operations to complete.\n */\n async ready(): Promise<void> {\n await this.getServiceInvalidator().readyWithStorage(this.getStorage())\n }\n\n /**\n * @internal\n * Attempts to get an instance synchronously if it already exists.\n */\n tryGetSync<T>(token: any, args?: any): T | null {\n return this.tryGetSyncFromStorage(\n token,\n args,\n this.getStorage(),\n this.requestId,\n )\n }\n\n /**\n * @internal\n * Internal method for getting instances synchronously with configurable storage.\n */\n protected tryGetSyncFromStorage<T>(\n token: any,\n args: any,\n storage: UnifiedStorage,\n requestId?: string,\n ): T | null {\n const tokenResolver = this.getTokenResolver()\n const realToken = tokenResolver.getRegistryToken(token)\n const registry = this.getRegistry()\n const scope = registry.has(realToken)\n ? registry.get(realToken).scope\n : InjectableScope.Singleton\n\n try {\n const instanceName = this.getNameResolver().generateInstanceName(\n tokenResolver.normalizeToken(token),\n args,\n requestId,\n scope,\n )\n\n const result = storage.get(instanceName)\n if (result && result[0] === undefined && result[1]) {\n const holder = result[1]\n if (holder.status === InstanceStatus.Created) {\n return holder.instance as T\n }\n }\n } catch {\n // Ignore error\n }\n\n return null\n }\n\n /**\n * Adds an instance to the container.\n * Accepts class types, InjectionTokens, and BoundInjectionTokens.\n * Rejects InjectionTokens with required schemas (use BoundInjectionToken instead).\n *\n * @param token The class type, InjectionToken, or BoundInjectionToken to register the instance for\n * @param instance The instance to store\n */\n addInstance<T>(\n token: ClassType | InjectionToken<T, any> | BoundInjectionToken<T, any>,\n instance: T,\n ): void {\n this.addInstanceToStorage(\n token,\n instance,\n this.getStorage(),\n this.defaultScope,\n this.requestId,\n )\n }\n\n /**\n * @internal\n * Internal method for adding instances with configurable scope and storage.\n */\n protected addInstanceToStorage<T>(\n token: ClassType | InjectionToken<T, any> | BoundInjectionToken<T, any>,\n instance: T,\n storage: UnifiedStorage,\n scope: InjectableScope,\n requestId?: string,\n ): void {\n // Check if token is an InjectionToken with required schema\n // BoundInjectionToken is allowed (it already has a value bound)\n if (token instanceof InjectionToken) {\n // Check if schema exists and is required (not optional)\n if (token.schema) {\n const schemaType = (token.schema as ZodType)?.def?.type\n if (schemaType !== 'optional') {\n throw DIError.tokenSchemaRequiredError(token.name)\n }\n }\n }\n\n const tokenResolver = this.getTokenResolver()\n const registry = this.getRegistry()\n\n // Normalize the token\n const normalizedToken = tokenResolver.normalizeToken(token)\n const realToken = tokenResolver.getRegistryToken(token)\n\n // If it's a class type and not registered, register it with the given scope\n if (typeof token === 'function' && !registry.has(realToken)) {\n registry.set(realToken, scope, token, InjectableType.Class)\n } else if (!registry.has(realToken)) {\n // Set a stub factory class to avoid errors when getting instances of unregistered factory tokens\n registry.set(\n realToken,\n scope,\n StubFactoryClass,\n InjectableType.Class,\n // Lowest priority to avoid conflicts with other registered tokens\n -1,\n )\n }\n\n // Generate instance name with the given scope\n const instanceName = this.getNameResolver().generateInstanceName(\n normalizedToken,\n normalizedToken instanceof BoundInjectionToken\n ? normalizedToken.value\n : undefined,\n requestId,\n scope,\n )\n\n // Store the instance\n storage.storeInstance(instanceName, instance)\n }\n}\n","import type { z, ZodType } from 'zod/v4'\n\nimport type { Factorable } from '../interfaces/factory.interface.mjs'\nimport type {\n ClassType,\n ClassTypeWithArgument,\n FactoryInjectionToken,\n InjectionTokenSchemaType,\n} from '../token/injection-token.mjs'\nimport type { Registry } from '../token/registry.mjs'\nimport type { Join, UnionToArray } from '../utils/types.mjs'\nimport type { NameResolver } from '../internal/core/name-resolver.mjs'\nimport type { ServiceInvalidator } from '../internal/core/service-invalidator.mjs'\nimport type { TokenResolver } from '../internal/core/token-resolver.mjs'\n\nimport { InjectableScope } from '../enums/index.mjs'\nimport { UnifiedStorage } from '../internal/holder/unified-storage.mjs'\nimport {\n BoundInjectionToken,\n InjectionToken,\n} from '../token/injection-token.mjs'\nimport { AbstractContainer } from './abstract-container.mjs'\nimport { Container } from './container.mjs'\n\n/**\n * Request-scoped dependency injection container.\n *\n * Wraps a parent Container and provides isolated request-scoped instances\n * while delegating singleton and transient resolution to the parent.\n * This design eliminates race conditions that can occur with async operations\n * when multiple requests are processed concurrently.\n */\nexport class ScopedContainer extends AbstractContainer {\n protected readonly defaultScope = InjectableScope.Request\n\n private readonly storage: UnifiedStorage\n private disposed = false\n private readonly metadata: Record<string, any>\n\n constructor(\n private readonly parent: Container,\n private readonly registry: Registry,\n public readonly requestId: string,\n metadata?: Record<string, any>,\n ) {\n super()\n // Create own unified storage for request-scoped services\n this.storage = new UnifiedStorage(InjectableScope.Request)\n this.metadata = metadata || {}\n }\n\n // ============================================================================\n // ABSTRACT METHOD IMPLEMENTATIONS - Delegate to parent\n // ============================================================================\n\n getStorage(): UnifiedStorage {\n return this.storage\n }\n\n protected getRegistry(): Registry {\n return this.registry\n }\n\n protected getTokenResolver(): TokenResolver {\n return this.parent.getTokenResolver()\n }\n\n protected getNameResolver(): NameResolver {\n return this.parent.getNameResolver()\n }\n\n protected getServiceInvalidator(): ServiceInvalidator {\n return this.parent.getServiceInvalidator()\n }\n\n // ============================================================================\n // SCOPED CONTAINER SPECIFIC METHODS\n // ============================================================================\n\n /**\n * Gets the request ID for this scoped container.\n */\n getRequestId(): string {\n return this.requestId\n }\n\n /**\n * Gets the parent container.\n */\n getParent(): Container {\n return this.parent\n }\n\n /**\n * Gets metadata from the request context.\n */\n getMetadata(key: string): any | undefined {\n return this.metadata[key]\n }\n\n /**\n * Sets metadata on the request context.\n */\n setMetadata(key: string, value: any): void {\n this.metadata[key] = value\n }\n\n /**\n * Gets an instance from the container.\n * Request-scoped services are resolved from this container's storage.\n * All other services are delegated to the parent container.\n */\n // #1 Simple class\n get<T extends ClassType>(\n token: T,\n ): InstanceType<T> extends Factorable<infer R>\n ? Promise<R>\n : Promise<InstanceType<T>>\n // #1.1 Simple class with args\n get<T extends ClassTypeWithArgument<R>, R>(\n token: T,\n args: R,\n ): Promise<InstanceType<T>>\n // #2 Token with required Schema\n get<T, S extends InjectionTokenSchemaType>(\n token: InjectionToken<T, S>,\n args: z.input<S>,\n ): Promise<T>\n // #3 Token with optional Schema\n get<T, S extends InjectionTokenSchemaType, R extends boolean>(\n token: InjectionToken<T, S, R>,\n ): R extends false\n ? Promise<T>\n : S extends ZodType<infer Type>\n ? `Error: Your token requires args: ${Join<\n UnionToArray<keyof Type>,\n ', '\n >}`\n : 'Error: Your token requires args'\n // #4 Token with no Schema\n get<T>(token: InjectionToken<T, undefined>): Promise<T>\n get<T>(token: BoundInjectionToken<T, any>): Promise<T>\n get<T>(token: FactoryInjectionToken<T, any>): Promise<T>\n\n async get(\n token:\n | ClassType\n | InjectionToken<any>\n | BoundInjectionToken<any, any>\n | FactoryInjectionToken<any, any>,\n args?: unknown,\n ) {\n if (this.disposed) {\n throw new Error('ScopedContainer has been disposed')\n }\n\n // Check if this is a request-scoped service\n const tokenResolver = this.getTokenResolver()\n const realToken = tokenResolver.getRegistryToken(token)\n\n if (this.registry.has(realToken)) {\n const record = this.registry.get(realToken)\n if (record.scope === InjectableScope.Request) {\n // Resolve request-scoped service from this container\n const [error, instance] = await this.parent\n .getInstanceResolver()\n .resolveRequestScopedInstance(token, args, this)\n\n if (error) {\n throw error\n }\n\n return instance\n }\n }\n\n // Delegate singleton/transient services to parent\n const [error, instance] = await this.parent\n .getInstanceResolver()\n .resolveInstance(token, args, this, this.storage, this.requestId)\n\n if (error) {\n throw error\n }\n\n return instance\n }\n\n /**\n * Invalidates a service and its dependencies.\n */\n async invalidate(service: unknown): Promise<void> {\n // Find the service by instance in request storage\n const holder = this.storage.findByInstance(service)\n if (!holder) {\n // Try parent storage\n return this.parent.invalidate(service)\n }\n\n await this.getServiceInvalidator().invalidateWithStorage(\n holder.name,\n this.storage,\n )\n }\n\n /**\n * Disposes the container and cleans up all resources.\n * Alias for endRequest().\n */\n async dispose(): Promise<void> {\n return this.endRequest()\n }\n\n /**\n * @internal\n * Attempts to get an instance synchronously if it already exists.\n * Checks request storage first, then delegates to parent.\n */\n override tryGetSync<T>(token: any, args?: any): T | null {\n // Check request storage first for request-scoped services\n const tokenResolver = this.getTokenResolver()\n const realToken = tokenResolver.getRegistryToken(token)\n const scope = this.registry.has(realToken)\n ? this.registry.get(realToken).scope\n : InjectableScope.Singleton\n\n if (scope === InjectableScope.Request) {\n const result = this.tryGetSyncFromStorage<T>(\n token,\n args,\n this.storage,\n this.requestId,\n )\n if (result !== null) {\n return result\n }\n }\n\n // Delegate to parent for singleton/transient\n return this.parent.tryGetSync<T>(token, args, this.requestId)\n }\n\n /**\n * Adds an instance to the container.\n * Overrides base class to check disposed state.\n */\n override addInstance<T>(\n token: ClassType | InjectionToken<T, any> | BoundInjectionToken<T, any>,\n instance: T,\n ): void {\n if (this.disposed) {\n throw new Error('ScopedContainer has been disposed')\n }\n\n super.addInstance(token, instance)\n }\n\n /**\n * Ends the request and cleans up all request-scoped services.\n */\n async endRequest(): Promise<void> {\n if (this.disposed) {\n return\n }\n\n this.disposed = true\n\n // Clear all request-scoped services\n await this.getServiceInvalidator().clearAllWithStorage(this.storage)\n\n // Remove request ID from parent\n this.parent.removeRequestId(this.requestId)\n }\n}\n","import type { z, ZodType } from 'zod/v4'\n\nimport type { Factorable } from '../interfaces/factory.interface.mjs'\nimport type {\n ClassType,\n ClassTypeWithArgument,\n InjectionTokenSchemaType,\n} from '../token/injection-token.mjs'\nimport type { Registry } from '../token/registry.mjs'\nimport type { Injectors } from '../utils/get-injectors.mjs'\nimport type { Join, UnionToArray } from '../utils/types.mjs'\n\nimport { Injectable } from '../decorators/injectable.decorator.mjs'\nimport { InjectableScope, InjectableType } from '../enums/index.mjs'\nimport { DIError } from '../errors/index.mjs'\nimport { InstanceResolver } from '../internal/core/instance-resolver.mjs'\nimport { NameResolver } from '../internal/core/name-resolver.mjs'\nimport { ScopeTracker } from '../internal/core/scope-tracker.mjs'\nimport { ServiceInitializer } from '../internal/core/service-initializer.mjs'\nimport { ServiceInvalidator } from '../internal/core/service-invalidator.mjs'\nimport { TokenResolver } from '../internal/core/token-resolver.mjs'\nimport { UnifiedStorage } from '../internal/holder/unified-storage.mjs'\nimport { LifecycleEventBus } from '../internal/lifecycle/lifecycle-event-bus.mjs'\nimport {\n BoundInjectionToken,\n FactoryInjectionToken,\n InjectionToken,\n} from '../token/injection-token.mjs'\nimport { globalRegistry } from '../token/registry.mjs'\nimport { defaultInjectors } from '../utils/default-injectors.mjs'\nimport { getInjectableToken } from '../utils/index.mjs'\nimport { AbstractContainer } from './abstract-container.mjs'\nimport { ScopedContainer } from './scoped-container.mjs'\n\n/**\n * Main dependency injection container.\n *\n * Provides a simplified public API for dependency injection.\n * Handles singleton and transient services directly,\n * while request-scoped services require using beginRequest() to create a ScopedContainer.\n */\n@Injectable()\nexport class Container extends AbstractContainer {\n protected readonly defaultScope = InjectableScope.Singleton\n protected readonly requestId = undefined\n\n private readonly storage: UnifiedStorage\n private readonly serviceInitializer: ServiceInitializer\n private readonly serviceInvalidator: ServiceInvalidator\n private readonly tokenResolver: TokenResolver\n private readonly nameResolver: NameResolver\n private readonly scopeTracker: ScopeTracker\n private readonly eventBus: LifecycleEventBus\n private readonly instanceResolver: InstanceResolver\n private readonly activeRequestIds = new Set<string>()\n\n constructor(\n protected readonly registry: Registry = globalRegistry,\n protected readonly logger: Console | null = null,\n protected readonly injectors: Injectors = defaultInjectors,\n ) {\n super()\n // Initialize components\n this.storage = new UnifiedStorage(InjectableScope.Singleton)\n this.eventBus = new LifecycleEventBus(logger)\n this.nameResolver = new NameResolver(logger)\n this.tokenResolver = new TokenResolver(logger)\n this.scopeTracker = new ScopeTracker(registry, this.nameResolver, logger)\n this.serviceInitializer = new ServiceInitializer(injectors)\n this.serviceInvalidator = new ServiceInvalidator(this.eventBus, logger)\n this.instanceResolver = new InstanceResolver(\n registry,\n this.storage,\n this.serviceInitializer,\n this.tokenResolver,\n this.nameResolver,\n this.scopeTracker,\n this.serviceInvalidator,\n this.eventBus,\n logger,\n )\n this.registerSelf()\n }\n\n private registerSelf() {\n const token = getInjectableToken(Container)\n this.registry.set(\n token,\n InjectableScope.Singleton,\n Container,\n InjectableType.Class,\n )\n const instanceName = this.nameResolver.generateInstanceName(\n token,\n undefined,\n undefined,\n InjectableScope.Singleton,\n )\n this.storage.storeInstance(instanceName, this)\n }\n\n /**\n * Gets an instance from the container.\n * NOTE: Request-scoped services cannot be resolved directly from Container.\n * Use beginRequest() to create a ScopedContainer for request-scoped services.\n */\n // #1 Simple class\n get<T extends ClassType>(\n token: T,\n ): InstanceType<T> extends Factorable<infer R>\n ? Promise<R>\n : Promise<InstanceType<T>>\n // #1.1 Simple class with args\n get<T extends ClassTypeWithArgument<R>, R>(\n token: T,\n args: R,\n ): Promise<InstanceType<T>>\n // #2 Token with required Schema\n get<T, S extends InjectionTokenSchemaType>(\n token: InjectionToken<T, S>,\n args: z.input<S>,\n ): Promise<T>\n // #3 Token with optional Schema\n get<T, S extends InjectionTokenSchemaType, R extends boolean>(\n token: InjectionToken<T, S, R>,\n ): R extends false\n ? Promise<T>\n : S extends ZodType<infer Type>\n ? `Error: Your token requires args: ${Join<\n UnionToArray<keyof Type>,\n ', '\n >}`\n : 'Error: Your token requires args'\n // #4 Token with no Schema\n get<T>(token: InjectionToken<T, undefined>): Promise<T>\n get<T>(token: BoundInjectionToken<T, any>): Promise<T>\n get<T>(token: FactoryInjectionToken<T, any>): Promise<T>\n\n async get(\n token:\n | ClassType\n | InjectionToken<any>\n | BoundInjectionToken<any, any>\n | FactoryInjectionToken<any, any>,\n args?: unknown,\n ) {\n // Check if this is a request-scoped service\n const realToken = this.tokenResolver.getRegistryToken(token)\n\n if (this.registry.has(realToken)) {\n const record = this.registry.get(realToken)\n if (record.scope === InjectableScope.Request) {\n throw DIError.scopeMismatchError(\n realToken.name,\n 'ScopedContainer',\n 'Container',\n )\n }\n }\n\n const [error, instance] = await this.instanceResolver.resolveInstance(\n token,\n args,\n this,\n )\n\n if (error) {\n throw error\n }\n\n return instance\n }\n\n /**\n * Invalidates a service and its dependencies.\n */\n async invalidate(service: unknown): Promise<void> {\n // Find the service by instance\n const holder = this.storage.findByInstance(service)\n if (!holder) {\n this.logger?.warn(\n `[Container] Service instance not found for invalidation`,\n )\n return\n }\n\n await this.serviceInvalidator.invalidateWithStorage(\n holder.name,\n this.storage,\n )\n }\n\n /**\n * Disposes the container and cleans up all resources.\n */\n async dispose(): Promise<void> {\n await this.serviceInvalidator.clearAllWithStorage(this.storage)\n }\n\n /**\n * @internal\n * Attempts to get an instance synchronously if it already exists.\n * Overrides base class to support requestId parameter for ScopedContainer compatibility.\n */\n override tryGetSync<T>(token: any, args?: any, requestId?: string): T | null {\n return this.tryGetSyncFromStorage(\n token,\n args,\n this.storage,\n requestId ?? this.requestId,\n )\n }\n\n /**\n * Begins a new request context and returns a ScopedContainer.\n */\n beginRequest(\n requestId: string,\n metadata?: Record<string, any>,\n ): ScopedContainer {\n if (this.activeRequestIds.has(requestId)) {\n throw new Error(`Request with ID ${requestId} already exists`)\n }\n\n this.activeRequestIds.add(requestId)\n\n return new ScopedContainer(this, this.registry, requestId, metadata)\n }\n\n /**\n * Gets all active request IDs.\n */\n getActiveRequestIds(): ReadonlySet<string> {\n return this.activeRequestIds\n }\n\n /**\n * Checks if a request is active.\n */\n hasActiveRequest(requestId: string): boolean {\n return this.activeRequestIds.has(requestId)\n }\n\n /**\n * Removes a request ID from active requests.\n * Called by ScopedContainer when request ends.\n */\n removeRequestId(requestId: string): void {\n this.activeRequestIds.delete(requestId)\n }\n\n // ============================================================================\n // INTERNAL METHODS FOR COMPONENT ACCESS\n // ============================================================================\n\n getStorage(): UnifiedStorage {\n return this.storage\n }\n\n getServiceInitializer(): ServiceInitializer {\n return this.serviceInitializer\n }\n\n getServiceInvalidator(): ServiceInvalidator {\n return this.serviceInvalidator\n }\n\n getTokenResolver(): TokenResolver {\n return this.tokenResolver\n }\n\n getNameResolver(): NameResolver {\n return this.nameResolver\n }\n\n getScopeTracker(): ScopeTracker {\n return this.scopeTracker\n }\n\n getEventBus(): LifecycleEventBus {\n return this.eventBus\n }\n\n getRegistry(): Registry {\n return this.registry\n }\n\n getInstanceResolver(): InstanceResolver {\n return this.instanceResolver\n }\n}\n"],"mappings":"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"}