@navios/di 0.1.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 (41) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +2 -0
  3. package/dist/_tsup-dts-rollup.d.mts +536 -0
  4. package/dist/_tsup-dts-rollup.d.ts +536 -0
  5. package/dist/index.d.mts +54 -0
  6. package/dist/index.d.ts +54 -0
  7. package/dist/index.js +1019 -0
  8. package/dist/index.mjs +960 -0
  9. package/package.json +46 -0
  10. package/src/__tests__/injectable.spec.mts +167 -0
  11. package/src/__tests__/injection-token.spec.mts +127 -0
  12. package/src/decorators/index.mts +1 -0
  13. package/src/decorators/injectable.decorator.mts +107 -0
  14. package/src/enums/index.mts +2 -0
  15. package/src/enums/injectable-scope.enum.mts +10 -0
  16. package/src/enums/injectable-type.enum.mts +4 -0
  17. package/src/errors/errors.enum.mts +8 -0
  18. package/src/errors/factory-not-found.mts +8 -0
  19. package/src/errors/factory-token-not-resolved.mts +10 -0
  20. package/src/errors/index.mts +7 -0
  21. package/src/errors/instance-destroying.mts +8 -0
  22. package/src/errors/instance-expired.mts +8 -0
  23. package/src/errors/instance-not-found.mts +8 -0
  24. package/src/errors/unknown-error.mts +15 -0
  25. package/src/event-emitter.mts +107 -0
  26. package/src/factory-context.mts +16 -0
  27. package/src/index.mts +16 -0
  28. package/src/injection-token.mts +130 -0
  29. package/src/injector.mts +19 -0
  30. package/src/interfaces/factory.interface.mts +11 -0
  31. package/src/interfaces/index.mts +1 -0
  32. package/src/proxy-service-locator.mts +83 -0
  33. package/src/registry.mts +65 -0
  34. package/src/resolve-service.mts +43 -0
  35. package/src/service-locator-event-bus.mts +96 -0
  36. package/src/service-locator-instance-holder.mts +63 -0
  37. package/src/service-locator-manager.mts +89 -0
  38. package/src/service-locator.mts +571 -0
  39. package/src/utils/get-injectable-token.mts +19 -0
  40. package/src/utils/get-injectors.mts +133 -0
  41. package/src/utils/index.mts +2 -0
@@ -0,0 +1,133 @@
1
+ import type { AnyZodObject, z, ZodOptional } from 'zod'
2
+
3
+ import type { ClassType } from '../injection-token.mjs'
4
+ import type { ServiceLocator } from '../service-locator.mjs'
5
+
6
+ import { InjectableTokenMeta } from '../decorators/index.mjs'
7
+ import {
8
+ BoundInjectionToken,
9
+ FactoryInjectionToken,
10
+ InjectionToken,
11
+ } from '../injection-token.mjs'
12
+
13
+ export interface CreateInjectorsOptions {
14
+ baseLocator: ServiceLocator
15
+ }
16
+
17
+ export interface Injectors {
18
+ inject<T extends ClassType>(token: T): Promise<InstanceType<T>>
19
+ inject<T, S extends AnyZodObject>(
20
+ token: InjectionToken<T, S>,
21
+ args: z.input<S>,
22
+ ): Promise<T>
23
+ inject<T, S extends ZodOptional<AnyZodObject>>(
24
+ token: InjectionToken<T, S>,
25
+ args?: z.input<S>,
26
+ ): Promise<T>
27
+ inject<T>(token: InjectionToken<T, undefined>): Promise<T>
28
+ inject<T>(token: BoundInjectionToken<T, any>): Promise<T>
29
+ inject<T>(token: FactoryInjectionToken<T, any>): Promise<T>
30
+
31
+ syncInject<T extends ClassType>(token: T): InstanceType<T>
32
+ syncInject<T, S extends AnyZodObject>(
33
+ token: InjectionToken<T, S>,
34
+ args: z.input<S>,
35
+ ): T
36
+ syncInject<T, S extends ZodOptional<AnyZodObject>>(
37
+ token: InjectionToken<T, S>,
38
+ args: z.input<S>,
39
+ ): T
40
+ syncInject<T>(token: InjectionToken<T, undefined>): T
41
+ syncInject<T>(token: BoundInjectionToken<T, any>): T
42
+ syncInject<T>(token: FactoryInjectionToken<T, any>): T
43
+
44
+ wrapSyncInit(cb: () => any): () => [any, Promise<any>[]]
45
+
46
+ provideServiceLocator(locator: ServiceLocator): ServiceLocator
47
+ }
48
+
49
+ export const InjectorsBase = new Map<ServiceLocator, Injectors>()
50
+
51
+ export function getInjectors({ baseLocator }: CreateInjectorsOptions) {
52
+ if (InjectorsBase.has(baseLocator)) {
53
+ return InjectorsBase.get(baseLocator)!
54
+ }
55
+ let currentLocator: ServiceLocator = baseLocator
56
+
57
+ function getServiceLocator() {
58
+ if (!currentLocator) {
59
+ throw new Error(
60
+ '[Injector] Service locator is not initialized. Please provide the service locator before using the @Injectable decorator.',
61
+ )
62
+ }
63
+ return currentLocator
64
+ }
65
+ function provideServiceLocator(locator: ServiceLocator): ServiceLocator {
66
+ const original = currentLocator
67
+ currentLocator = locator
68
+ return original
69
+ }
70
+
71
+ function inject(
72
+ token:
73
+ | ClassType
74
+ | InjectionToken<any>
75
+ | BoundInjectionToken<any, any>
76
+ | FactoryInjectionToken<any, any>,
77
+ args?: unknown,
78
+ ) {
79
+ // @ts-expect-error In case we have a class
80
+ const realToken = token[InjectableTokenMeta] ?? token
81
+
82
+ // @ts-expect-error We check the type in overload
83
+ return getServiceLocator().getOrThrowInstance(realToken, args)
84
+ }
85
+
86
+ let promiseCollector: null | ((promise: Promise<any>) => void) = null
87
+
88
+ function wrapSyncInit(cb: () => any) {
89
+ return () => {
90
+ const promises: Promise<any>[] = []
91
+ const originalPromiseCollector = promiseCollector
92
+ promiseCollector = (promise) => {
93
+ promises.push(promise)
94
+ }
95
+ const result = cb()
96
+ promiseCollector = originalPromiseCollector
97
+ return [result, promises]
98
+ }
99
+ }
100
+
101
+ function syncInject<
102
+ T,
103
+ Token extends
104
+ | InjectionToken<T>
105
+ | BoundInjectionToken<T, any>
106
+ | FactoryInjectionToken<T, any>,
107
+ S extends AnyZodObject | unknown = Token['schema'],
108
+ >(token: Token, args?: S extends AnyZodObject ? z.input<S> : never): T {
109
+ // @ts-expect-error In case we have a class
110
+ const realToken = token[InjectableTokenMeta] ?? token
111
+
112
+ const instance = getServiceLocator().getSyncInstance(realToken, args)
113
+ if (!instance) {
114
+ if (promiseCollector) {
115
+ const promise = getServiceLocator().getInstance(realToken, args)
116
+ promiseCollector(promise)
117
+ } else {
118
+ throw new Error(`[Injector] Cannot initiate ${realToken.toString()}`)
119
+ }
120
+ }
121
+ return instance as unknown as T
122
+ }
123
+
124
+ const injectors: Injectors = {
125
+ inject,
126
+ syncInject,
127
+ wrapSyncInit,
128
+ provideServiceLocator,
129
+ } as Injectors
130
+ InjectorsBase.set(baseLocator, injectors)
131
+
132
+ return injectors
133
+ }
@@ -0,0 +1,2 @@
1
+ export * from './get-injectors.mjs'
2
+ export * from './get-injectable-token.mjs'