@navios/di 0.5.1 → 0.6.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 (123) hide show
  1. package/CHANGELOG.md +146 -0
  2. package/README.md +196 -219
  3. package/docs/README.md +69 -11
  4. package/docs/api-reference.md +281 -117
  5. package/docs/container.md +220 -56
  6. package/docs/examples/request-scope-example.mts +2 -2
  7. package/docs/factory.md +3 -8
  8. package/docs/getting-started.md +37 -8
  9. package/docs/migration.md +318 -37
  10. package/docs/request-contexts.md +263 -175
  11. package/docs/scopes.md +79 -42
  12. package/lib/browser/index.d.mts +1577 -0
  13. package/lib/browser/index.d.mts.map +1 -0
  14. package/lib/browser/index.mjs +3012 -0
  15. package/lib/browser/index.mjs.map +1 -0
  16. package/lib/index-S_qX2VLI.d.mts +1211 -0
  17. package/lib/index-S_qX2VLI.d.mts.map +1 -0
  18. package/lib/index-fKPuT65j.d.cts +1206 -0
  19. package/lib/index-fKPuT65j.d.cts.map +1 -0
  20. package/lib/index.cjs +389 -0
  21. package/lib/index.cjs.map +1 -0
  22. package/lib/index.d.cts +376 -0
  23. package/lib/index.d.cts.map +1 -0
  24. package/lib/index.d.mts +371 -78
  25. package/lib/index.d.mts.map +1 -0
  26. package/lib/index.mjs +325 -63
  27. package/lib/index.mjs.map +1 -1
  28. package/lib/testing/index.cjs +9 -0
  29. package/lib/testing/index.d.cts +2 -0
  30. package/lib/testing/index.d.mts +2 -2
  31. package/lib/testing/index.mjs +2 -72
  32. package/lib/testing-BMGmmxH7.cjs +2895 -0
  33. package/lib/testing-BMGmmxH7.cjs.map +1 -0
  34. package/lib/testing-DCXz8AJD.mjs +2655 -0
  35. package/lib/testing-DCXz8AJD.mjs.map +1 -0
  36. package/package.json +23 -1
  37. package/project.json +2 -2
  38. package/src/__tests__/async-local-storage.browser.spec.mts +240 -0
  39. package/src/__tests__/async-local-storage.spec.mts +333 -0
  40. package/src/__tests__/container.spec.mts +30 -25
  41. package/src/__tests__/e2e.browser.spec.mts +790 -0
  42. package/src/__tests__/e2e.spec.mts +1222 -0
  43. package/src/__tests__/errors.spec.mts +6 -6
  44. package/src/__tests__/factory.spec.mts +1 -1
  45. package/src/__tests__/get-injectors.spec.mts +1 -1
  46. package/src/__tests__/injectable.spec.mts +1 -1
  47. package/src/__tests__/injection-token.spec.mts +1 -1
  48. package/src/__tests__/library-findings.spec.mts +563 -0
  49. package/src/__tests__/registry.spec.mts +2 -2
  50. package/src/__tests__/request-scope.spec.mts +266 -274
  51. package/src/__tests__/service-instantiator.spec.mts +18 -17
  52. package/src/__tests__/service-locator-event-bus.spec.mts +9 -9
  53. package/src/__tests__/service-locator-manager.spec.mts +15 -15
  54. package/src/__tests__/service-locator.spec.mts +167 -244
  55. package/src/__tests__/unified-api.spec.mts +27 -27
  56. package/src/__type-tests__/factory.spec-d.mts +2 -2
  57. package/src/__type-tests__/inject.spec-d.mts +2 -2
  58. package/src/__type-tests__/injectable.spec-d.mts +1 -1
  59. package/src/browser.mts +16 -0
  60. package/src/container/container.mts +319 -0
  61. package/src/container/index.mts +2 -0
  62. package/src/container/scoped-container.mts +350 -0
  63. package/src/decorators/factory.decorator.mts +4 -4
  64. package/src/decorators/injectable.decorator.mts +5 -5
  65. package/src/errors/di-error.mts +13 -7
  66. package/src/errors/index.mts +0 -8
  67. package/src/index.mts +156 -15
  68. package/src/interfaces/container.interface.mts +82 -0
  69. package/src/interfaces/factory.interface.mts +2 -2
  70. package/src/interfaces/index.mts +1 -0
  71. package/src/internal/context/async-local-storage.mts +120 -0
  72. package/src/internal/context/factory-context.mts +18 -0
  73. package/src/internal/context/index.mts +3 -0
  74. package/src/{request-context-holder.mts → internal/context/request-context.mts} +40 -27
  75. package/src/internal/context/resolution-context.mts +63 -0
  76. package/src/internal/context/sync-local-storage.mts +51 -0
  77. package/src/internal/core/index.mts +5 -0
  78. package/src/internal/core/instance-resolver.mts +641 -0
  79. package/src/{service-instantiator.mts → internal/core/instantiator.mts} +31 -27
  80. package/src/internal/core/invalidator.mts +437 -0
  81. package/src/internal/core/service-locator.mts +202 -0
  82. package/src/{token-processor.mts → internal/core/token-processor.mts} +79 -60
  83. package/src/{base-instance-holder-manager.mts → internal/holder/base-holder-manager.mts} +91 -21
  84. package/src/internal/holder/holder-manager.mts +85 -0
  85. package/src/internal/holder/holder-storage.interface.mts +116 -0
  86. package/src/internal/holder/index.mts +6 -0
  87. package/src/internal/holder/instance-holder.mts +109 -0
  88. package/src/internal/holder/request-storage.mts +134 -0
  89. package/src/internal/holder/singleton-storage.mts +105 -0
  90. package/src/internal/index.mts +4 -0
  91. package/src/internal/lifecycle/circular-detector.mts +77 -0
  92. package/src/internal/lifecycle/index.mts +2 -0
  93. package/src/{service-locator-event-bus.mts → internal/lifecycle/lifecycle-event-bus.mts} +11 -4
  94. package/src/testing/__tests__/test-container.spec.mts +2 -2
  95. package/src/testing/test-container.mts +4 -4
  96. package/src/token/index.mts +2 -0
  97. package/src/{injection-token.mts → token/injection-token.mts} +1 -1
  98. package/src/{registry.mts → token/registry.mts} +1 -1
  99. package/src/utils/get-injectable-token.mts +1 -1
  100. package/src/utils/get-injectors.mts +32 -15
  101. package/src/utils/types.mts +1 -1
  102. package/tsdown.config.mts +67 -0
  103. package/lib/_tsup-dts-rollup.d.mts +0 -1283
  104. package/lib/_tsup-dts-rollup.d.ts +0 -1283
  105. package/lib/chunk-2M576LCC.mjs +0 -2043
  106. package/lib/chunk-2M576LCC.mjs.map +0 -1
  107. package/lib/index.d.ts +0 -78
  108. package/lib/index.js +0 -2127
  109. package/lib/index.js.map +0 -1
  110. package/lib/testing/index.d.ts +0 -2
  111. package/lib/testing/index.js +0 -2060
  112. package/lib/testing/index.js.map +0 -1
  113. package/lib/testing/index.mjs.map +0 -1
  114. package/src/container.mts +0 -227
  115. package/src/factory-context.mts +0 -8
  116. package/src/instance-resolver.mts +0 -559
  117. package/src/request-context-manager.mts +0 -149
  118. package/src/service-invalidator.mts +0 -429
  119. package/src/service-locator-instance-holder.mts +0 -70
  120. package/src/service-locator-manager.mts +0 -85
  121. package/src/service-locator.mts +0 -246
  122. package/tsup.config.mts +0 -12
  123. /package/src/{injector.mts → injectors.mts} +0 -0
@@ -1,6 +1,6 @@
1
1
  import type { z, ZodObject, ZodType } from 'zod/v4'
2
2
 
3
- import type { FactoryContext } from '../factory-context.mjs'
3
+ import type { FactoryContext } from '../internal/context/factory-context.mjs'
4
4
  import type {
5
5
  BoundInjectionToken,
6
6
  ClassType,
@@ -9,7 +9,7 @@ import type {
9
9
  FactoryInjectionToken,
10
10
  InjectionToken,
11
11
  InjectionTokenSchemaType,
12
- } from '../injection-token.mjs'
12
+ } from '../token/injection-token.mjs'
13
13
  import type {
14
14
  Factorable,
15
15
  FactorableWithArgs,
@@ -22,6 +22,7 @@ import type {
22
22
  } from './types.mjs'
23
23
 
24
24
  import { InjectableTokenMeta } from '../symbols/index.mjs'
25
+ import { withoutResolutionContext } from '../internal/context/resolution-context.mjs'
25
26
 
26
27
  export interface Injectors {
27
28
  // #1 Simple class
@@ -167,7 +168,11 @@ export function getInjectors() {
167
168
  let promiseCollector: null | ((promise: Promise<any>) => void) = null
168
169
  let injectState: InjectState | null = null
169
170
 
170
- function getRequest(token: InjectionToken<any>, args?: unknown) {
171
+ function getRequest(
172
+ token: InjectionToken<any>,
173
+ args?: unknown,
174
+ skipCycleTracking = false,
175
+ ) {
171
176
  if (!injectState) {
172
177
  throw new Error(
173
178
  '[Injector] Trying to make a request outside of a injectable context',
@@ -185,16 +190,26 @@ export function getInjectors() {
185
190
  }
186
191
  let result: any = null
187
192
  let error: Error | null = null
188
- const promise = getFactoryContext()
189
- .inject(token as any, args as any)
190
- .then((r) => {
191
- result = r
192
- return r
193
- })
194
- .catch((e) => {
195
- // We don't throw here because we have a mechanism to handle errors
196
- error = e
197
- })
193
+
194
+ // For async inject, we run outside the resolution context to skip cycle tracking.
195
+ // This is because asyncInject returns a promise that doesn't block the constructor,
196
+ // so it cannot cause a deadlock even with circular dependencies.
197
+ const doInject = () =>
198
+ getFactoryContext()
199
+ .inject(token as any, args as any)
200
+ .then((r) => {
201
+ result = r
202
+ return r
203
+ })
204
+ .catch((e) => {
205
+ // We don't throw here because we have a mechanism to handle errors
206
+ error = e
207
+ })
208
+
209
+ const promise = skipCycleTracking
210
+ ? withoutResolutionContext(doInject)
211
+ : doInject()
212
+
198
213
  const request: InjectRequest = {
199
214
  token,
200
215
  promise,
@@ -226,7 +241,9 @@ export function getInjectors() {
226
241
  }
227
242
  // @ts-expect-error In case we have a class
228
243
  const realToken = token[InjectableTokenMeta] ?? token
229
- const request = getRequest(realToken, args)
244
+ // Pass skipCycleTracking=true because asyncInject returns a promise that doesn't
245
+ // block the constructor, so it cannot cause a deadlock even with circular dependencies.
246
+ const request = getRequest(realToken, args, true)
230
247
  return request.promise.then((result) => {
231
248
  if (request.error) {
232
249
  // We throw here because we want to fail the asyncInject call if the dependency fails to initialize
@@ -282,7 +299,7 @@ export function getInjectors() {
282
299
  )
283
300
  }
284
301
 
285
- const instance = getFactoryContext().locator.getSyncInstance(
302
+ const instance = getFactoryContext().container.tryGetSync(
286
303
  realToken,
287
304
  args,
288
305
  )
@@ -3,7 +3,7 @@ import type {
3
3
  ClassType,
4
4
  FactoryInjectionToken,
5
5
  InjectionToken,
6
- } from '../injection-token.mjs'
6
+ } from '../token/injection-token.mjs'
7
7
 
8
8
  // Utility types for string manipulation and union handling
9
9
  export type Join<TElements, TSeparator extends string> =
@@ -0,0 +1,67 @@
1
+ import { withFilter } from 'rolldown/filter'
2
+ import { defineConfig } from 'tsdown'
3
+ import swc from 'unplugin-swc'
4
+
5
+ export default defineConfig([
6
+ // Node.js build (default)
7
+ {
8
+ entry: ['src/index.mts', 'src/testing/index.mts'],
9
+ outDir: 'lib',
10
+ format: ['esm', 'cjs'],
11
+ clean: true,
12
+ treeshake: true,
13
+ sourcemap: true,
14
+ platform: 'node',
15
+ dts: true,
16
+ target: 'es2022',
17
+ plugins: [
18
+ withFilter(
19
+ swc.rolldown({
20
+ jsc: {
21
+ target: 'es2022',
22
+ parser: {
23
+ syntax: 'typescript',
24
+ decorators: true,
25
+ },
26
+ transform: {
27
+ decoratorVersion: '2022-03',
28
+ },
29
+ },
30
+ }),
31
+ // Only run this transform if the file contains a decorator.
32
+ { transform: { code: '@' } },
33
+ ),
34
+ ],
35
+ },
36
+ // Browser build - uses dedicated entry that forces SyncLocalStorage
37
+ {
38
+ entry: {
39
+ 'browser/index': 'src/browser.mts',
40
+ },
41
+ outDir: 'lib',
42
+ format: ['esm'],
43
+ treeshake: true,
44
+ sourcemap: true,
45
+ platform: 'browser',
46
+ dts: true,
47
+ target: 'es2022',
48
+ plugins: [
49
+ withFilter(
50
+ swc.rolldown({
51
+ jsc: {
52
+ target: 'es2022',
53
+ parser: {
54
+ syntax: 'typescript',
55
+ decorators: true,
56
+ },
57
+ transform: {
58
+ decoratorVersion: '2022-03',
59
+ },
60
+ },
61
+ }),
62
+ // Only run this transform if the file contains a decorator.
63
+ { transform: { code: '@' } },
64
+ ),
65
+ ],
66
+ },
67
+ ])