@navios/di 0.3.0 → 0.4.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 (96) hide show
  1. package/README.md +67 -6
  2. package/coverage/base.css +224 -0
  3. package/coverage/block-navigation.js +87 -0
  4. package/coverage/clover.xml +2659 -0
  5. package/coverage/coverage-final.json +46 -0
  6. package/coverage/docs/examples/basic-usage.mts.html +376 -0
  7. package/coverage/docs/examples/factory-pattern.mts.html +1039 -0
  8. package/coverage/docs/examples/index.html +176 -0
  9. package/coverage/docs/examples/injection-tokens.mts.html +760 -0
  10. package/coverage/docs/examples/request-scope-example.mts.html +847 -0
  11. package/coverage/docs/examples/service-lifecycle.mts.html +1162 -0
  12. package/coverage/favicon.png +0 -0
  13. package/coverage/index.html +236 -0
  14. package/coverage/lib/_tsup-dts-rollup.d.mts.html +2806 -0
  15. package/coverage/lib/index.d.mts.html +310 -0
  16. package/coverage/lib/index.html +131 -0
  17. package/coverage/prettify.css +1 -0
  18. package/coverage/prettify.js +2 -0
  19. package/coverage/sort-arrow-sprite.png +0 -0
  20. package/coverage/sorter.js +196 -0
  21. package/coverage/src/container.mts.html +586 -0
  22. package/coverage/src/decorators/factory.decorator.mts.html +322 -0
  23. package/coverage/src/decorators/index.html +146 -0
  24. package/coverage/src/decorators/index.mts.html +91 -0
  25. package/coverage/src/decorators/injectable.decorator.mts.html +394 -0
  26. package/coverage/src/enums/index.html +146 -0
  27. package/coverage/src/enums/index.mts.html +91 -0
  28. package/coverage/src/enums/injectable-scope.enum.mts.html +127 -0
  29. package/coverage/src/enums/injectable-type.enum.mts.html +97 -0
  30. package/coverage/src/errors/errors.enum.mts.html +109 -0
  31. package/coverage/src/errors/factory-not-found.mts.html +109 -0
  32. package/coverage/src/errors/factory-token-not-resolved.mts.html +115 -0
  33. package/coverage/src/errors/index.html +221 -0
  34. package/coverage/src/errors/index.mts.html +106 -0
  35. package/coverage/src/errors/instance-destroying.mts.html +109 -0
  36. package/coverage/src/errors/instance-expired.mts.html +109 -0
  37. package/coverage/src/errors/instance-not-found.mts.html +109 -0
  38. package/coverage/src/errors/unknown-error.mts.html +130 -0
  39. package/coverage/src/event-emitter.mts.html +400 -0
  40. package/coverage/src/factory-context.mts.html +109 -0
  41. package/coverage/src/index.html +296 -0
  42. package/coverage/src/index.mts.html +139 -0
  43. package/coverage/src/injection-token.mts.html +571 -0
  44. package/coverage/src/injector.mts.html +133 -0
  45. package/coverage/src/interfaces/factory.interface.mts.html +121 -0
  46. package/coverage/src/interfaces/index.html +161 -0
  47. package/coverage/src/interfaces/index.mts.html +94 -0
  48. package/coverage/src/interfaces/on-service-destroy.interface.mts.html +94 -0
  49. package/coverage/src/interfaces/on-service-init.interface.mts.html +94 -0
  50. package/coverage/src/registry.mts.html +247 -0
  51. package/coverage/src/request-context-holder.mts.html +607 -0
  52. package/coverage/src/service-instantiator.mts.html +559 -0
  53. package/coverage/src/service-locator-event-bus.mts.html +289 -0
  54. package/coverage/src/service-locator-instance-holder.mts.html +307 -0
  55. package/coverage/src/service-locator-manager.mts.html +604 -0
  56. package/coverage/src/service-locator.mts.html +2911 -0
  57. package/coverage/src/symbols/index.html +131 -0
  58. package/coverage/src/symbols/index.mts.html +88 -0
  59. package/coverage/src/symbols/injectable-token.mts.html +88 -0
  60. package/coverage/src/utils/defer.mts.html +304 -0
  61. package/coverage/src/utils/get-injectable-token.mts.html +142 -0
  62. package/coverage/src/utils/get-injectors.mts.html +691 -0
  63. package/coverage/src/utils/index.html +176 -0
  64. package/coverage/src/utils/index.mts.html +97 -0
  65. package/coverage/src/utils/types.mts.html +241 -0
  66. package/docs/README.md +5 -2
  67. package/docs/api-reference.md +38 -0
  68. package/docs/container.md +75 -0
  69. package/docs/getting-started.md +4 -3
  70. package/docs/injectable.md +4 -3
  71. package/docs/migration.md +177 -0
  72. package/docs/request-contexts.md +364 -0
  73. package/lib/_tsup-dts-rollup.d.mts +180 -35
  74. package/lib/_tsup-dts-rollup.d.ts +180 -35
  75. package/lib/index.d.mts +1 -0
  76. package/lib/index.d.ts +1 -0
  77. package/lib/index.js +485 -279
  78. package/lib/index.js.map +1 -1
  79. package/lib/index.mjs +485 -280
  80. package/lib/index.mjs.map +1 -1
  81. package/package.json +1 -1
  82. package/src/__tests__/defer.spec.mts +166 -0
  83. package/src/__tests__/errors.spec.mts +61 -0
  84. package/src/__tests__/event-emitter.spec.mts +163 -0
  85. package/src/__tests__/get-injectors.spec.mts +70 -0
  86. package/src/__tests__/registry.spec.mts +335 -0
  87. package/src/__tests__/request-scope.spec.mts +167 -4
  88. package/src/__tests__/service-instantiator.spec.mts +408 -0
  89. package/src/__tests__/service-locator-event-bus.spec.mts +242 -0
  90. package/src/__tests__/service-locator-manager.spec.mts +370 -0
  91. package/src/__tests__/unified-api.spec.mts +130 -0
  92. package/src/base-instance-holder-manager.mts +175 -0
  93. package/src/index.mts +1 -0
  94. package/src/request-context-holder.mts +85 -27
  95. package/src/service-locator-manager.mts +12 -70
  96. package/src/service-locator.mts +421 -226
@@ -1,5 +1,10 @@
1
1
  import type { ServiceLocatorInstanceHolder } from './service-locator-instance-holder.mjs'
2
2
 
3
+ import { BaseInstanceHolderManager } from './base-instance-holder-manager.mjs'
4
+ import { InjectableScope, InjectableType } from './enums/index.mjs'
5
+ import { InjectionToken } from './injection-token.mjs'
6
+ import { ServiceLocatorInstanceHolderStatus } from './service-locator-instance-holder.mjs'
7
+
3
8
  /**
4
9
  * Request context holder that manages pre-prepared instances for a specific request.
5
10
  * This allows for efficient instantiation of request-scoped services.
@@ -10,11 +15,6 @@ export interface RequestContextHolder {
10
15
  */
11
16
  readonly requestId: string
12
17
 
13
- /**
14
- * Pre-prepared instances for this request, keyed by instance name.
15
- */
16
- readonly instances: Map<string, any>
17
-
18
18
  /**
19
19
  * Instance holders for request-scoped services.
20
20
  */
@@ -46,19 +46,19 @@ export interface RequestContextHolder {
46
46
  ): void
47
47
 
48
48
  /**
49
- * Gets a pre-prepared instance from this context.
49
+ * Adds a pre-prepared instance to this context.
50
50
  */
51
- getInstance(instanceName: string): any | undefined
51
+ addInstance(token: InjectionToken<any, undefined>, instance: any): void
52
52
 
53
53
  /**
54
54
  * Gets an instance holder from this context.
55
55
  */
56
- getHolder(instanceName: string): ServiceLocatorInstanceHolder | undefined
56
+ get(instanceName: string): ServiceLocatorInstanceHolder | undefined
57
57
 
58
58
  /**
59
59
  * Checks if this context has a pre-prepared instance.
60
60
  */
61
- hasInstance(instanceName: string): boolean
61
+ has(instanceName: string): boolean
62
62
 
63
63
  /**
64
64
  * Clears all instances and holders from this context.
@@ -74,14 +74,41 @@ export interface RequestContextHolder {
74
74
  * Sets metadata value by key.
75
75
  */
76
76
  setMetadata(key: string, value: any): void
77
+
78
+ // Methods inherited from BaseInstanceHolderManager
79
+ /**
80
+ * Filters holders based on a predicate function.
81
+ */
82
+ filter(
83
+ predicate: (
84
+ value: ServiceLocatorInstanceHolder<any>,
85
+ key: string,
86
+ ) => boolean,
87
+ ): Map<string, ServiceLocatorInstanceHolder>
88
+
89
+ /**
90
+ * Deletes a holder by name.
91
+ */
92
+ delete(name: string): boolean
93
+
94
+ /**
95
+ * Gets the number of holders currently managed.
96
+ */
97
+ size(): number
98
+
99
+ /**
100
+ * Checks if this manager has any holders.
101
+ */
102
+ isEmpty(): boolean
77
103
  }
78
104
 
79
105
  /**
80
106
  * Default implementation of RequestContextHolder.
81
107
  */
82
- export class DefaultRequestContextHolder implements RequestContextHolder {
83
- public readonly instances = new Map<string, any>()
84
- public readonly holders = new Map<string, ServiceLocatorInstanceHolder>()
108
+ export class DefaultRequestContextHolder
109
+ extends BaseInstanceHolderManager
110
+ implements RequestContextHolder
111
+ {
85
112
  public readonly metadata = new Map<string, any>()
86
113
  public readonly createdAt = Date.now()
87
114
 
@@ -90,6 +117,7 @@ export class DefaultRequestContextHolder implements RequestContextHolder {
90
117
  public readonly priority: number = 100,
91
118
  initialMetadata?: Record<string, any>,
92
119
  ) {
120
+ super(null) // RequestContextHolder doesn't need logging
93
121
  if (initialMetadata) {
94
122
  Object.entries(initialMetadata).forEach(([key, value]) => {
95
123
  this.metadata.set(key, value)
@@ -97,30 +125,60 @@ export class DefaultRequestContextHolder implements RequestContextHolder {
97
125
  }
98
126
  }
99
127
 
100
- addInstance(
101
- instanceName: string,
102
- instance: any,
103
- holder: ServiceLocatorInstanceHolder,
104
- ): void {
105
- this.instances.set(instanceName, instance)
106
- this.holders.set(instanceName, holder)
128
+ /**
129
+ * Public getter for holders to maintain interface compatibility.
130
+ */
131
+ get holders(): Map<string, ServiceLocatorInstanceHolder> {
132
+ return this._holders
133
+ }
134
+
135
+ /**
136
+ * Gets a holder by name. For RequestContextHolder, this is a simple lookup.
137
+ */
138
+ get(name: string): ServiceLocatorInstanceHolder | undefined {
139
+ return this._holders.get(name)
107
140
  }
108
141
 
109
- getInstance(instanceName: string): any | undefined {
110
- return this.instances.get(instanceName)
142
+ /**
143
+ * Sets a holder by name.
144
+ */
145
+ set(name: string, holder: ServiceLocatorInstanceHolder): void {
146
+ this._holders.set(name, holder)
111
147
  }
112
148
 
113
- getHolder(instanceName: string): ServiceLocatorInstanceHolder | undefined {
114
- return this.holders.get(instanceName)
149
+ /**
150
+ * Checks if a holder exists by name.
151
+ */
152
+ has(name: string): boolean {
153
+ return this._holders.has(name)
115
154
  }
116
155
 
117
- hasInstance(instanceName: string): boolean {
118
- return this.instances.has(instanceName)
156
+ addInstance(
157
+ instanceName: string | InjectionToken<any, undefined>,
158
+ instance: any,
159
+ holder?: ServiceLocatorInstanceHolder,
160
+ ): void {
161
+ if (instanceName instanceof InjectionToken) {
162
+ const name = instanceName.toString()
163
+ const createdHolder = this.createCreatedHolder(
164
+ name,
165
+ instance,
166
+ InjectableType.Class,
167
+ InjectableScope.Singleton,
168
+ new Set(),
169
+ Infinity,
170
+ )
171
+ this._holders.set(name, createdHolder)
172
+ } else {
173
+ if (!holder) {
174
+ throw new Error('Holder is required when adding an instance by name')
175
+ }
176
+ this._holders.set(instanceName, holder)
177
+ }
119
178
  }
120
179
 
121
180
  clear(): void {
122
- this.instances.clear()
123
- this.holders.clear()
181
+ super.clear() // Use the base class clear method for holders
124
182
  this.metadata.clear()
125
183
  }
126
184
 
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-empty-object-type */
2
2
  import type { ServiceLocatorInstanceHolder } from './service-locator-instance-holder.mjs'
3
3
 
4
+ import { BaseInstanceHolderManager } from './base-instance-holder-manager.mjs'
4
5
  import { InjectableScope, InjectableType } from './enums/index.mjs'
5
6
  import {
6
7
  ErrorsEnum,
@@ -9,13 +10,11 @@ import {
9
10
  InstanceNotFound,
10
11
  } from './errors/index.mjs'
11
12
  import { ServiceLocatorInstanceHolderStatus } from './service-locator-instance-holder.mjs'
12
- import { createDeferred } from './utils/defer.mjs'
13
13
 
14
- export class ServiceLocatorManager {
15
- private readonly instancesHolders: Map<string, ServiceLocatorInstanceHolder> =
16
- new Map()
17
-
18
- constructor(private readonly logger: Console | null = null) {}
14
+ export class ServiceLocatorManager extends BaseInstanceHolderManager {
15
+ constructor(logger: Console | null = null) {
16
+ super(logger)
17
+ }
19
18
 
20
19
  get(
21
20
  name: string,
@@ -23,7 +22,7 @@ export class ServiceLocatorManager {
23
22
  | [InstanceExpired | InstanceDestroying, ServiceLocatorInstanceHolder]
24
23
  | [InstanceNotFound]
25
24
  | [undefined, ServiceLocatorInstanceHolder] {
26
- const holder = this.instancesHolders.get(name)
25
+ const holder = this._holders.get(name)
27
26
  if (holder) {
28
27
  if (holder.ttl !== Infinity) {
29
28
  const now = Date.now()
@@ -57,7 +56,7 @@ export class ServiceLocatorManager {
57
56
  }
58
57
 
59
58
  set(name: string, holder: ServiceLocatorInstanceHolder): void {
60
- this.instancesHolders.set(name, holder)
59
+ this._holders.set(name, holder)
61
60
  }
62
61
 
63
62
  has(
@@ -77,61 +76,9 @@ export class ServiceLocatorManager {
77
76
  return [undefined, !!holder]
78
77
  }
79
78
 
80
- delete(name: string): boolean {
81
- return this.instancesHolders.delete(name)
82
- }
79
+ // delete and filter methods are inherited from BaseInstanceHolderManager
83
80
 
84
- filter(
85
- predicate: (
86
- value: ServiceLocatorInstanceHolder<any>,
87
- key: string,
88
- ) => boolean,
89
- ): Map<string, ServiceLocatorInstanceHolder> {
90
- return new Map(
91
- [...this.instancesHolders].filter(([key, value]) =>
92
- predicate(value, key),
93
- ),
94
- )
95
- }
96
-
97
- /**
98
- * Creates a new holder with Creating status and a deferred creation promise.
99
- * This is useful for creating placeholder holders that can be fulfilled later.
100
- * @param name The name of the instance
101
- * @param type The injectable type
102
- * @param scope The injectable scope
103
- * @param deps Optional set of dependencies
104
- * @param ttl Optional time-to-live in milliseconds (defaults to Infinity)
105
- * @returns A tuple containing the deferred promise and the holder
106
- */
107
- createCreatingHolder<Instance>(
108
- name: string,
109
- type: InjectableType,
110
- scope: InjectableScope,
111
- deps: Set<string> = new Set(),
112
- ttl: number = Infinity,
113
- ): [
114
- ReturnType<typeof createDeferred<[undefined, Instance]>>,
115
- ServiceLocatorInstanceHolder<Instance>,
116
- ] {
117
- const deferred = createDeferred<[undefined, Instance]>()
118
-
119
- const holder: ServiceLocatorInstanceHolder<Instance> = {
120
- status: ServiceLocatorInstanceHolderStatus.Creating,
121
- name,
122
- instance: null,
123
- creationPromise: deferred.promise,
124
- destroyPromise: null,
125
- type,
126
- scope,
127
- deps,
128
- destroyListeners: [],
129
- createdAt: Date.now(),
130
- ttl,
131
- }
132
-
133
- return [deferred, holder]
134
- }
81
+ // createCreatingHolder method is inherited from BaseInstanceHolderManager
135
82
 
136
83
  /**
137
84
  * Creates a new holder with Created status and an actual instance.
@@ -152,21 +99,16 @@ export class ServiceLocatorManager {
152
99
  deps: Set<string> = new Set(),
153
100
  ttl: number = Infinity,
154
101
  ): ServiceLocatorInstanceHolder<Instance> {
155
- const holder: ServiceLocatorInstanceHolder<Instance> = {
156
- status: ServiceLocatorInstanceHolderStatus.Created,
102
+ const holder = this.createCreatedHolder(
157
103
  name,
158
104
  instance,
159
- creationPromise: null,
160
- destroyPromise: null,
161
105
  type,
162
106
  scope,
163
107
  deps,
164
- destroyListeners: [],
165
- createdAt: Date.now(),
166
108
  ttl,
167
- }
109
+ )
168
110
 
169
- this.instancesHolders.set(name, holder)
111
+ this._holders.set(name, holder)
170
112
 
171
113
  return holder
172
114
  }