@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.
- package/LICENSE +7 -0
- package/README.md +2 -0
- package/dist/_tsup-dts-rollup.d.mts +536 -0
- package/dist/_tsup-dts-rollup.d.ts +536 -0
- package/dist/index.d.mts +54 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +1019 -0
- package/dist/index.mjs +960 -0
- package/package.json +46 -0
- package/src/__tests__/injectable.spec.mts +167 -0
- package/src/__tests__/injection-token.spec.mts +127 -0
- package/src/decorators/index.mts +1 -0
- package/src/decorators/injectable.decorator.mts +107 -0
- package/src/enums/index.mts +2 -0
- package/src/enums/injectable-scope.enum.mts +10 -0
- package/src/enums/injectable-type.enum.mts +4 -0
- package/src/errors/errors.enum.mts +8 -0
- package/src/errors/factory-not-found.mts +8 -0
- package/src/errors/factory-token-not-resolved.mts +10 -0
- package/src/errors/index.mts +7 -0
- package/src/errors/instance-destroying.mts +8 -0
- package/src/errors/instance-expired.mts +8 -0
- package/src/errors/instance-not-found.mts +8 -0
- package/src/errors/unknown-error.mts +15 -0
- package/src/event-emitter.mts +107 -0
- package/src/factory-context.mts +16 -0
- package/src/index.mts +16 -0
- package/src/injection-token.mts +130 -0
- package/src/injector.mts +19 -0
- package/src/interfaces/factory.interface.mts +11 -0
- package/src/interfaces/index.mts +1 -0
- package/src/proxy-service-locator.mts +83 -0
- package/src/registry.mts +65 -0
- package/src/resolve-service.mts +43 -0
- package/src/service-locator-event-bus.mts +96 -0
- package/src/service-locator-instance-holder.mts +63 -0
- package/src/service-locator-manager.mts +89 -0
- package/src/service-locator.mts +571 -0
- package/src/utils/get-injectable-token.mts +19 -0
- package/src/utils/get-injectors.mts +133 -0
- 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
|
+
}
|