@navios/di 0.5.1 → 0.6.1

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 (122) hide show
  1. package/CHANGELOG.md +145 -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 +3013 -0
  15. package/lib/browser/index.mjs.map +1 -0
  16. package/lib/index-7jfWsiG4.d.mts +1211 -0
  17. package/lib/index-7jfWsiG4.d.mts.map +1 -0
  18. package/lib/index-DW3K5sOX.d.cts +1206 -0
  19. package/lib/index-DW3K5sOX.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-BG_fa9TJ.mjs +2656 -0
  33. package/lib/testing-BG_fa9TJ.mjs.map +1 -0
  34. package/lib/testing-DIaIRiJz.cjs +2896 -0
  35. package/lib/testing-DIaIRiJz.cjs.map +1 -0
  36. package/package.json +29 -7
  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__/factory.spec.mts +1 -1
  44. package/src/__tests__/get-injectors.spec.mts +1 -1
  45. package/src/__tests__/injectable.spec.mts +1 -1
  46. package/src/__tests__/injection-token.spec.mts +1 -1
  47. package/src/__tests__/library-findings.spec.mts +563 -0
  48. package/src/__tests__/registry.spec.mts +2 -2
  49. package/src/__tests__/request-scope.spec.mts +266 -274
  50. package/src/__tests__/service-instantiator.spec.mts +18 -17
  51. package/src/__tests__/service-locator-event-bus.spec.mts +9 -9
  52. package/src/__tests__/service-locator-manager.spec.mts +15 -15
  53. package/src/__tests__/service-locator.spec.mts +167 -244
  54. package/src/__tests__/unified-api.spec.mts +27 -27
  55. package/src/__type-tests__/factory.spec-d.mts +2 -2
  56. package/src/__type-tests__/inject.spec-d.mts +2 -2
  57. package/src/__type-tests__/injectable.spec-d.mts +1 -1
  58. package/src/browser.mts +16 -0
  59. package/src/container/container.mts +319 -0
  60. package/src/container/index.mts +2 -0
  61. package/src/container/scoped-container.mts +350 -0
  62. package/src/decorators/factory.decorator.mts +4 -4
  63. package/src/decorators/injectable.decorator.mts +5 -5
  64. package/src/errors/di-error.mts +12 -5
  65. package/src/errors/index.mts +0 -8
  66. package/src/index.mts +156 -15
  67. package/src/interfaces/container.interface.mts +82 -0
  68. package/src/interfaces/factory.interface.mts +2 -2
  69. package/src/interfaces/index.mts +1 -0
  70. package/src/internal/context/async-local-storage.mts +120 -0
  71. package/src/internal/context/factory-context.mts +18 -0
  72. package/src/internal/context/index.mts +3 -0
  73. package/src/{request-context-holder.mts → internal/context/request-context.mts} +40 -27
  74. package/src/internal/context/resolution-context.mts +63 -0
  75. package/src/internal/context/sync-local-storage.mts +51 -0
  76. package/src/internal/core/index.mts +5 -0
  77. package/src/internal/core/instance-resolver.mts +641 -0
  78. package/src/{service-instantiator.mts → internal/core/instantiator.mts} +31 -27
  79. package/src/internal/core/invalidator.mts +437 -0
  80. package/src/internal/core/service-locator.mts +202 -0
  81. package/src/{token-processor.mts → internal/core/token-processor.mts} +79 -60
  82. package/src/{base-instance-holder-manager.mts → internal/holder/base-holder-manager.mts} +91 -21
  83. package/src/internal/holder/holder-manager.mts +85 -0
  84. package/src/internal/holder/holder-storage.interface.mts +116 -0
  85. package/src/internal/holder/index.mts +6 -0
  86. package/src/internal/holder/instance-holder.mts +109 -0
  87. package/src/internal/holder/request-storage.mts +134 -0
  88. package/src/internal/holder/singleton-storage.mts +105 -0
  89. package/src/internal/index.mts +4 -0
  90. package/src/internal/lifecycle/circular-detector.mts +77 -0
  91. package/src/internal/lifecycle/index.mts +2 -0
  92. package/src/{service-locator-event-bus.mts → internal/lifecycle/lifecycle-event-bus.mts} +11 -4
  93. package/src/testing/__tests__/test-container.spec.mts +2 -2
  94. package/src/testing/test-container.mts +4 -4
  95. package/src/token/index.mts +2 -0
  96. package/src/{injection-token.mts → token/injection-token.mts} +1 -1
  97. package/src/{registry.mts → token/registry.mts} +1 -1
  98. package/src/utils/get-injectable-token.mts +1 -1
  99. package/src/utils/get-injectors.mts +32 -15
  100. package/src/utils/types.mts +1 -1
  101. package/tsdown.config.mts +67 -0
  102. package/lib/_tsup-dts-rollup.d.mts +0 -1283
  103. package/lib/_tsup-dts-rollup.d.ts +0 -1283
  104. package/lib/chunk-2M576LCC.mjs +0 -2043
  105. package/lib/chunk-2M576LCC.mjs.map +0 -1
  106. package/lib/index.d.ts +0 -78
  107. package/lib/index.js +0 -2127
  108. package/lib/index.js.map +0 -1
  109. package/lib/testing/index.d.ts +0 -2
  110. package/lib/testing/index.js +0 -2060
  111. package/lib/testing/index.js.map +0 -1
  112. package/lib/testing/index.mjs.map +0 -1
  113. package/src/container.mts +0 -227
  114. package/src/factory-context.mts +0 -8
  115. package/src/instance-resolver.mts +0 -559
  116. package/src/request-context-manager.mts +0 -149
  117. package/src/service-invalidator.mts +0 -429
  118. package/src/service-locator-instance-holder.mts +0 -70
  119. package/src/service-locator-manager.mts +0 -85
  120. package/src/service-locator.mts +0 -246
  121. package/tsup.config.mts +0 -12
  122. /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
+ ])