@navios/di 0.3.1 → 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 +177 -36
  74. package/lib/_tsup-dts-rollup.d.ts +177 -36
  75. package/lib/index.d.mts +1 -0
  76. package/lib/index.d.ts +1 -0
  77. package/lib/index.js +480 -294
  78. package/lib/index.js.map +1 -1
  79. package/lib/index.mjs +480 -295
  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 +34 -35
  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 +73 -44
  95. package/src/service-locator-manager.mts +12 -70
  96. package/src/service-locator.mts +421 -226
@@ -1,5 +1,6 @@
1
1
  import type { ServiceLocatorInstanceHolder } from './service-locator-instance-holder.mjs'
2
2
 
3
+ import { BaseInstanceHolderManager } from './base-instance-holder-manager.mjs'
3
4
  import { InjectableScope, InjectableType } from './enums/index.mjs'
4
5
  import { InjectionToken } from './injection-token.mjs'
5
6
  import { ServiceLocatorInstanceHolderStatus } from './service-locator-instance-holder.mjs'
@@ -14,11 +15,6 @@ export interface RequestContextHolder {
14
15
  */
15
16
  readonly requestId: string
16
17
 
17
- /**
18
- * Pre-prepared instances for this request, keyed by instance name.
19
- */
20
- readonly instances: Map<string, any>
21
-
22
18
  /**
23
19
  * Instance holders for request-scoped services.
24
20
  */
@@ -54,20 +50,15 @@ export interface RequestContextHolder {
54
50
  */
55
51
  addInstance(token: InjectionToken<any, undefined>, instance: any): void
56
52
 
57
- /**
58
- * Gets a pre-prepared instance from this context.
59
- */
60
- getInstance(instanceName: string): any | undefined
61
-
62
53
  /**
63
54
  * Gets an instance holder from this context.
64
55
  */
65
- getHolder(instanceName: string): ServiceLocatorInstanceHolder | undefined
56
+ get(instanceName: string): ServiceLocatorInstanceHolder | undefined
66
57
 
67
58
  /**
68
59
  * Checks if this context has a pre-prepared instance.
69
60
  */
70
- hasInstance(instanceName: string): boolean
61
+ has(instanceName: string): boolean
71
62
 
72
63
  /**
73
64
  * Clears all instances and holders from this context.
@@ -83,14 +74,41 @@ export interface RequestContextHolder {
83
74
  * Sets metadata value by key.
84
75
  */
85
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
86
103
  }
87
104
 
88
105
  /**
89
106
  * Default implementation of RequestContextHolder.
90
107
  */
91
- export class DefaultRequestContextHolder implements RequestContextHolder {
92
- public readonly instances = new Map<string, any>()
93
- public readonly holders = new Map<string, ServiceLocatorInstanceHolder>()
108
+ export class DefaultRequestContextHolder
109
+ extends BaseInstanceHolderManager
110
+ implements RequestContextHolder
111
+ {
94
112
  public readonly metadata = new Map<string, any>()
95
113
  public readonly createdAt = Date.now()
96
114
 
@@ -99,6 +117,7 @@ export class DefaultRequestContextHolder implements RequestContextHolder {
99
117
  public readonly priority: number = 100,
100
118
  initialMetadata?: Record<string, any>,
101
119
  ) {
120
+ super(null) // RequestContextHolder doesn't need logging
102
121
  if (initialMetadata) {
103
122
  Object.entries(initialMetadata).forEach(([key, value]) => {
104
123
  this.metadata.set(key, value)
@@ -106,50 +125,60 @@ export class DefaultRequestContextHolder implements RequestContextHolder {
106
125
  }
107
126
  }
108
127
 
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)
140
+ }
141
+
142
+ /**
143
+ * Sets a holder by name.
144
+ */
145
+ set(name: string, holder: ServiceLocatorInstanceHolder): void {
146
+ this._holders.set(name, holder)
147
+ }
148
+
149
+ /**
150
+ * Checks if a holder exists by name.
151
+ */
152
+ has(name: string): boolean {
153
+ return this._holders.has(name)
154
+ }
155
+
109
156
  addInstance(
110
157
  instanceName: string | InjectionToken<any, undefined>,
111
158
  instance: any,
112
159
  holder?: ServiceLocatorInstanceHolder,
113
160
  ): void {
114
161
  if (instanceName instanceof InjectionToken) {
115
- this.instances.set(instanceName.toString(), instance)
116
- this.holders.set(instanceName.toString(), {
162
+ const name = instanceName.toString()
163
+ const createdHolder = this.createCreatedHolder(
164
+ name,
117
165
  instance,
118
- status: ServiceLocatorInstanceHolderStatus.Created,
119
- creationPromise: null,
120
- destroyPromise: null,
121
- destroyListeners: [],
122
- deps: new Set(),
123
- name: instanceName.toString(),
124
- type: InjectableType.Class,
125
- scope: InjectableScope.Singleton,
126
- createdAt: Date.now(),
127
- ttl: Infinity,
128
- })
166
+ InjectableType.Class,
167
+ InjectableScope.Singleton,
168
+ new Set(),
169
+ Infinity,
170
+ )
171
+ this._holders.set(name, createdHolder)
129
172
  } else {
130
173
  if (!holder) {
131
174
  throw new Error('Holder is required when adding an instance by name')
132
175
  }
133
- this.instances.set(instanceName, instance)
134
- this.holders.set(instanceName, holder)
176
+ this._holders.set(instanceName, holder)
135
177
  }
136
178
  }
137
179
 
138
- getInstance(instanceName: string): any | undefined {
139
- return this.instances.get(instanceName)
140
- }
141
-
142
- getHolder(instanceName: string): ServiceLocatorInstanceHolder | undefined {
143
- return this.holders.get(instanceName)
144
- }
145
-
146
- hasInstance(instanceName: string): boolean {
147
- return this.instances.has(instanceName)
148
- }
149
-
150
180
  clear(): void {
151
- this.instances.clear()
152
- this.holders.clear()
181
+ super.clear() // Use the base class clear method for holders
153
182
  this.metadata.clear()
154
183
  }
155
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
  }