@navios/di 0.8.0 → 0.9.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/CHANGELOG.md +87 -0
- package/README.md +117 -17
- package/lib/browser/container/abstract-container.d.mts +112 -0
- package/lib/browser/container/abstract-container.d.mts.map +1 -0
- package/lib/browser/container/abstract-container.mjs +100 -0
- package/lib/browser/container/abstract-container.mjs.map +1 -0
- package/lib/browser/container/container.d.mts +100 -0
- package/lib/browser/container/container.d.mts.map +1 -0
- package/lib/browser/container/container.mjs +424 -0
- package/lib/browser/container/container.mjs.map +1 -0
- package/lib/browser/container/scoped-container.d.mts +93 -0
- package/lib/browser/container/scoped-container.d.mts.map +1 -0
- package/lib/browser/container/scoped-container.mjs +119 -0
- package/lib/browser/container/scoped-container.mjs.map +1 -0
- package/lib/browser/decorators/factory.decorator.d.mts +26 -0
- package/lib/browser/decorators/factory.decorator.d.mts.map +1 -0
- package/lib/browser/decorators/factory.decorator.mjs +20 -0
- package/lib/browser/decorators/factory.decorator.mjs.map +1 -0
- package/lib/browser/decorators/injectable.decorator.d.mts +38 -0
- package/lib/browser/decorators/injectable.decorator.d.mts.map +1 -0
- package/lib/browser/decorators/injectable.decorator.mjs +21 -0
- package/lib/browser/decorators/injectable.decorator.mjs.map +1 -0
- package/lib/browser/enums/injectable-scope.enum.d.mts +18 -0
- package/lib/browser/enums/injectable-scope.enum.d.mts.map +1 -0
- package/lib/browser/enums/injectable-scope.enum.mjs +20 -0
- package/lib/browser/enums/injectable-scope.enum.mjs.map +1 -0
- package/lib/browser/enums/injectable-type.enum.d.mts +8 -0
- package/lib/browser/enums/injectable-type.enum.d.mts.map +1 -0
- package/lib/browser/enums/injectable-type.enum.mjs +10 -0
- package/lib/browser/enums/injectable-type.enum.mjs.map +1 -0
- package/lib/browser/errors/di-error.d.mts +43 -0
- package/lib/browser/errors/di-error.d.mts.map +1 -0
- package/lib/browser/errors/di-error.mjs +98 -0
- package/lib/browser/errors/di-error.mjs.map +1 -0
- package/lib/browser/event-emitter.d.mts +16 -0
- package/lib/browser/event-emitter.d.mts.map +1 -0
- package/lib/browser/event-emitter.mjs +320 -0
- package/lib/browser/event-emitter.mjs.map +1 -0
- package/lib/browser/index.d.mts +37 -1558
- package/lib/browser/index.mjs +29 -2749
- package/lib/browser/interfaces/container.interface.d.mts +59 -0
- package/lib/browser/interfaces/container.interface.d.mts.map +1 -0
- package/lib/browser/interfaces/factory.interface.d.mts +14 -0
- package/lib/browser/interfaces/factory.interface.d.mts.map +1 -0
- package/lib/browser/interfaces/on-service-destroy.interface.d.mts +7 -0
- package/lib/browser/interfaces/on-service-destroy.interface.d.mts.map +1 -0
- package/lib/browser/interfaces/on-service-init.interface.d.mts +7 -0
- package/lib/browser/interfaces/on-service-init.interface.d.mts.map +1 -0
- package/lib/browser/internal/context/async-local-storage.browser.mjs +20 -0
- package/lib/browser/internal/context/async-local-storage.browser.mjs.map +1 -0
- package/lib/browser/internal/context/async-local-storage.d.mts +9 -0
- package/lib/browser/internal/context/async-local-storage.d.mts.map +1 -0
- package/lib/browser/internal/context/async-local-storage.types.d.mts +11 -0
- package/lib/browser/internal/context/async-local-storage.types.d.mts.map +1 -0
- package/lib/browser/internal/context/factory-context.d.mts +23 -0
- package/lib/browser/internal/context/factory-context.d.mts.map +1 -0
- package/lib/browser/internal/context/resolution-context.d.mts +43 -0
- package/lib/browser/internal/context/resolution-context.d.mts.map +1 -0
- package/lib/browser/internal/context/resolution-context.mjs +56 -0
- package/lib/browser/internal/context/resolution-context.mjs.map +1 -0
- package/lib/browser/internal/context/service-initialization-context.d.mts +48 -0
- package/lib/browser/internal/context/service-initialization-context.d.mts.map +1 -0
- package/lib/browser/internal/context/sync-local-storage.mjs +53 -0
- package/lib/browser/internal/context/sync-local-storage.mjs.map +1 -0
- package/lib/browser/internal/core/instance-resolver.d.mts +119 -0
- package/lib/browser/internal/core/instance-resolver.d.mts.map +1 -0
- package/lib/browser/internal/core/instance-resolver.mjs +306 -0
- package/lib/browser/internal/core/instance-resolver.mjs.map +1 -0
- package/lib/browser/internal/core/name-resolver.d.mts +52 -0
- package/lib/browser/internal/core/name-resolver.d.mts.map +1 -0
- package/lib/browser/internal/core/name-resolver.mjs +118 -0
- package/lib/browser/internal/core/name-resolver.mjs.map +1 -0
- package/lib/browser/internal/core/scope-tracker.d.mts +65 -0
- package/lib/browser/internal/core/scope-tracker.d.mts.map +1 -0
- package/lib/browser/internal/core/scope-tracker.mjs +120 -0
- package/lib/browser/internal/core/scope-tracker.mjs.map +1 -0
- package/lib/browser/internal/core/service-initializer.d.mts +44 -0
- package/lib/browser/internal/core/service-initializer.d.mts.map +1 -0
- package/lib/browser/internal/core/service-initializer.mjs +109 -0
- package/lib/browser/internal/core/service-initializer.mjs.map +1 -0
- package/lib/browser/internal/core/service-invalidator.d.mts +81 -0
- package/lib/browser/internal/core/service-invalidator.d.mts.map +1 -0
- package/lib/browser/internal/core/service-invalidator.mjs +142 -0
- package/lib/browser/internal/core/service-invalidator.mjs.map +1 -0
- package/lib/browser/internal/core/token-resolver.d.mts +54 -0
- package/lib/browser/internal/core/token-resolver.d.mts.map +1 -0
- package/lib/browser/internal/core/token-resolver.mjs +77 -0
- package/lib/browser/internal/core/token-resolver.mjs.map +1 -0
- package/lib/browser/internal/holder/holder-storage.interface.d.mts +99 -0
- package/lib/browser/internal/holder/holder-storage.interface.d.mts.map +1 -0
- package/lib/browser/internal/holder/instance-holder.d.mts +101 -0
- package/lib/browser/internal/holder/instance-holder.d.mts.map +1 -0
- package/lib/browser/internal/holder/instance-holder.mjs +19 -0
- package/lib/browser/internal/holder/instance-holder.mjs.map +1 -0
- package/lib/browser/internal/holder/unified-storage.d.mts +53 -0
- package/lib/browser/internal/holder/unified-storage.d.mts.map +1 -0
- package/lib/browser/internal/holder/unified-storage.mjs +144 -0
- package/lib/browser/internal/holder/unified-storage.mjs.map +1 -0
- package/lib/browser/internal/lifecycle/circular-detector.d.mts +39 -0
- package/lib/browser/internal/lifecycle/circular-detector.d.mts.map +1 -0
- package/lib/browser/internal/lifecycle/circular-detector.mjs +55 -0
- package/lib/browser/internal/lifecycle/circular-detector.mjs.map +1 -0
- package/lib/browser/internal/lifecycle/lifecycle-event-bus.d.mts +18 -0
- package/lib/browser/internal/lifecycle/lifecycle-event-bus.d.mts.map +1 -0
- package/lib/browser/internal/lifecycle/lifecycle-event-bus.mjs +43 -0
- package/lib/browser/internal/lifecycle/lifecycle-event-bus.mjs.map +1 -0
- package/lib/browser/internal/stub-factory-class.d.mts +14 -0
- package/lib/browser/internal/stub-factory-class.d.mts.map +1 -0
- package/lib/browser/internal/stub-factory-class.mjs +18 -0
- package/lib/browser/internal/stub-factory-class.mjs.map +1 -0
- package/lib/browser/symbols/injectable-token.d.mts +5 -0
- package/lib/browser/symbols/injectable-token.d.mts.map +1 -0
- package/lib/browser/symbols/injectable-token.mjs +6 -0
- package/lib/browser/symbols/injectable-token.mjs.map +1 -0
- package/lib/browser/token/injection-token.d.mts +55 -0
- package/lib/browser/token/injection-token.d.mts.map +1 -0
- package/lib/browser/token/injection-token.mjs +100 -0
- package/lib/browser/token/injection-token.mjs.map +1 -0
- package/lib/browser/token/registry.d.mts +37 -0
- package/lib/browser/token/registry.d.mts.map +1 -0
- package/lib/browser/token/registry.mjs +86 -0
- package/lib/browser/token/registry.mjs.map +1 -0
- package/lib/browser/utils/default-injectors.d.mts +12 -0
- package/lib/browser/utils/default-injectors.d.mts.map +1 -0
- package/lib/browser/utils/default-injectors.mjs +13 -0
- package/lib/browser/utils/default-injectors.mjs.map +1 -0
- package/lib/browser/utils/get-injectable-token.d.mts +9 -0
- package/lib/browser/utils/get-injectable-token.d.mts.map +1 -0
- package/lib/browser/utils/get-injectable-token.mjs +13 -0
- package/lib/browser/utils/get-injectable-token.mjs.map +1 -0
- package/lib/browser/utils/get-injectors.d.mts +55 -0
- package/lib/browser/utils/get-injectors.d.mts.map +1 -0
- package/lib/browser/utils/get-injectors.mjs +121 -0
- package/lib/browser/utils/get-injectors.mjs.map +1 -0
- package/lib/browser/utils/types.d.mts +23 -0
- package/lib/browser/utils/types.d.mts.map +1 -0
- package/lib/{container-DAKOvAgr.mjs → container-8-z89TyQ.mjs} +1325 -1462
- package/lib/container-8-z89TyQ.mjs.map +1 -0
- package/lib/{container-Bp1W-pWJ.d.mts → container-CNiqesCL.d.mts} +598 -617
- package/lib/container-CNiqesCL.d.mts.map +1 -0
- package/lib/{container-DENMeJ87.cjs → container-CaY2fDuk.cjs} +1369 -1512
- package/lib/container-CaY2fDuk.cjs.map +1 -0
- package/lib/{container-YPwvmlK2.d.cts → container-D-0Ho3qL.d.cts} +598 -612
- package/lib/container-D-0Ho3qL.d.cts.map +1 -0
- package/lib/index.cjs +13 -15
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +58 -223
- package/lib/index.d.cts.map +1 -1
- package/lib/index.d.mts +62 -222
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +5 -6
- package/lib/index.mjs.map +1 -1
- package/lib/testing/index.cjs +569 -311
- package/lib/testing/index.cjs.map +1 -1
- package/lib/testing/index.d.cts +370 -41
- package/lib/testing/index.d.cts.map +1 -1
- package/lib/testing/index.d.mts +370 -41
- package/lib/testing/index.d.mts.map +1 -1
- package/lib/testing/index.mjs +568 -305
- package/lib/testing/index.mjs.map +1 -1
- package/package.json +2 -1
- package/src/__tests__/circular-detector.spec.mts +193 -0
- package/src/__tests__/concurrent.spec.mts +368 -0
- package/src/__tests__/container.spec.mts +32 -30
- package/src/__tests__/di-error.spec.mts +351 -0
- package/src/__tests__/e2e.browser.spec.mts +0 -4
- package/src/__tests__/e2e.spec.mts +10 -19
- package/src/__tests__/event-emitter.spec.mts +232 -109
- package/src/__tests__/get-injectors.spec.mts +250 -39
- package/src/__tests__/injection-token.spec.mts +293 -349
- package/src/__tests__/library-findings.spec.mts +8 -8
- package/src/__tests__/registry.spec.mts +358 -210
- package/src/__tests__/resolution-context.spec.mts +255 -0
- package/src/__tests__/scope-tracker.spec.mts +598 -0
- package/src/__tests__/scope-upgrade.spec.mts +808 -0
- package/src/__tests__/scoped-container.spec.mts +595 -0
- package/src/__tests__/test-container.spec.mts +293 -0
- package/src/__tests__/token-resolver.spec.mts +207 -0
- package/src/__tests__/unified-storage.spec.mts +535 -0
- package/src/__tests__/unit-test-container.spec.mts +405 -0
- package/src/__type-tests__/container.spec-d.mts +180 -0
- package/src/__type-tests__/factory.spec-d.mts +15 -3
- package/src/__type-tests__/inject.spec-d.mts +115 -20
- package/src/__type-tests__/injectable.spec-d.mts +69 -52
- package/src/__type-tests__/injection-token.spec-d.mts +176 -0
- package/src/__type-tests__/scoped-container.spec-d.mts +212 -0
- package/src/container/abstract-container.mts +327 -0
- package/src/container/container.mts +142 -170
- package/src/container/scoped-container.mts +126 -208
- package/src/decorators/factory.decorator.mts +16 -11
- package/src/decorators/injectable.decorator.mts +20 -16
- package/src/enums/index.mts +2 -2
- package/src/enums/injectable-scope.enum.mts +1 -0
- package/src/enums/injectable-type.enum.mts +1 -0
- package/src/errors/di-error.mts +96 -0
- package/src/event-emitter.mts +3 -27
- package/src/index.mts +6 -153
- package/src/interfaces/container.interface.mts +13 -0
- package/src/interfaces/factory.interface.mts +1 -1
- package/src/interfaces/index.mts +1 -1
- package/src/internal/context/async-local-storage.mts +3 -2
- package/src/internal/context/async-local-storage.types.mts +1 -0
- package/src/internal/context/factory-context.mts +1 -0
- package/src/internal/context/index.mts +3 -1
- package/src/internal/context/resolution-context.mts +1 -0
- package/src/internal/context/service-initialization-context.mts +43 -0
- package/src/internal/core/index.mts +5 -4
- package/src/internal/core/instance-resolver.mts +460 -302
- package/src/internal/core/name-resolver.mts +196 -0
- package/src/internal/core/scope-tracker.mts +242 -0
- package/src/internal/core/{instantiator.mts → service-initializer.mts} +51 -29
- package/src/internal/core/service-invalidator.mts +290 -0
- package/src/internal/core/token-resolver.mts +122 -0
- package/src/internal/holder/holder-storage.interface.mts +11 -5
- package/src/internal/holder/index.mts +2 -5
- package/src/internal/holder/instance-holder.mts +1 -3
- package/src/internal/holder/unified-storage.mts +245 -0
- package/src/internal/index.mts +2 -1
- package/src/internal/lifecycle/circular-detector.mts +1 -0
- package/src/internal/lifecycle/index.mts +1 -1
- package/src/internal/lifecycle/lifecycle-event-bus.mts +1 -0
- package/src/internal/stub-factory-class.mts +16 -0
- package/src/symbols/injectable-token.mts +3 -1
- package/src/testing/index.mts +2 -0
- package/src/testing/test-container.mts +546 -85
- package/src/testing/types.mts +117 -0
- package/src/testing/unit-test-container.mts +509 -0
- package/src/token/injection-token.mts +41 -4
- package/src/token/registry.mts +75 -9
- package/src/utils/default-injectors.mts +16 -0
- package/src/utils/get-injectable-token.mts +2 -3
- package/src/utils/get-injectors.mts +26 -15
- package/src/utils/index.mts +3 -1
- package/src/utils/types.mts +1 -0
- package/tsdown.config.mts +11 -1
- package/lib/browser/index.d.mts.map +0 -1
- package/lib/browser/index.mjs.map +0 -1
- package/lib/container-Bp1W-pWJ.d.mts.map +0 -1
- package/lib/container-DAKOvAgr.mjs.map +0 -1
- package/lib/container-DENMeJ87.cjs.map +0 -1
- package/lib/container-YPwvmlK2.d.cts.map +0 -1
- package/src/__tests__/async-local-storage.browser.spec.mts +0 -166
- package/src/__tests__/async-local-storage.spec.mts +0 -333
- package/src/__tests__/errors.spec.mts +0 -87
- package/src/__tests__/factory.spec.mts +0 -137
- package/src/__tests__/injectable.spec.mts +0 -246
- package/src/__tests__/request-scope.spec.mts +0 -416
- package/src/__tests__/service-instantiator.spec.mts +0 -410
- package/src/__tests__/service-locator-event-bus.spec.mts +0 -242
- package/src/__tests__/service-locator-manager.spec.mts +0 -300
- package/src/__tests__/service-locator.spec.mts +0 -966
- package/src/__tests__/unified-api.spec.mts +0 -130
- package/src/browser.mts +0 -11
- package/src/injectors.mts +0 -18
- package/src/internal/context/request-context.mts +0 -225
- package/src/internal/core/invalidator.mts +0 -437
- package/src/internal/core/service-locator.mts +0 -202
- package/src/internal/core/token-processor.mts +0 -252
- package/src/internal/holder/base-holder-manager.mts +0 -334
- package/src/internal/holder/holder-manager.mts +0 -85
- package/src/internal/holder/request-storage.mts +0 -127
- package/src/internal/holder/singleton-storage.mts +0 -92
- package/src/testing/README.md +0 -80
- package/src/testing/__tests__/test-container.spec.mts +0 -173
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import type { RequestContext } from '../context/request-context.mjs'
|
|
2
|
-
import type { BaseHolderManager } from './base-holder-manager.mjs'
|
|
3
|
-
import type {
|
|
4
|
-
HolderGetResult,
|
|
5
|
-
IHolderStorage,
|
|
6
|
-
} from './holder-storage.interface.mjs'
|
|
7
|
-
import type { InstanceHolder } from './instance-holder.mjs'
|
|
8
|
-
|
|
9
|
-
import { InjectableScope, InjectableType } from '../../enums/index.mjs'
|
|
10
|
-
import { DIError } from '../../errors/index.mjs'
|
|
11
|
-
import { InstanceStatus } from './instance-holder.mjs'
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Storage implementation for Request-scoped services.
|
|
15
|
-
*
|
|
16
|
-
* Wraps a RequestContext instance from a ScopedContainer and provides
|
|
17
|
-
* the IHolderStorage interface. This allows the InstanceResolver to work
|
|
18
|
-
* with request-scoped storage using the same interface as singleton storage.
|
|
19
|
-
*/
|
|
20
|
-
export class RequestStorage implements IHolderStorage {
|
|
21
|
-
readonly scope = InjectableScope.Request
|
|
22
|
-
|
|
23
|
-
constructor(
|
|
24
|
-
private readonly contextHolder: RequestContext,
|
|
25
|
-
private readonly holderManager: BaseHolderManager,
|
|
26
|
-
) {}
|
|
27
|
-
|
|
28
|
-
get<T = unknown>(instanceName: string): HolderGetResult<T> {
|
|
29
|
-
const holder = this.contextHolder.get(instanceName)
|
|
30
|
-
|
|
31
|
-
if (!holder) {
|
|
32
|
-
return null
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Check holder status for error states
|
|
36
|
-
switch (holder.status) {
|
|
37
|
-
case InstanceStatus.Destroying:
|
|
38
|
-
return [
|
|
39
|
-
DIError.instanceDestroying(instanceName),
|
|
40
|
-
holder as InstanceHolder<T>,
|
|
41
|
-
]
|
|
42
|
-
|
|
43
|
-
case InstanceStatus.Error:
|
|
44
|
-
return [
|
|
45
|
-
holder.instance as unknown as DIError,
|
|
46
|
-
holder as InstanceHolder<T>,
|
|
47
|
-
]
|
|
48
|
-
|
|
49
|
-
case InstanceStatus.Creating:
|
|
50
|
-
case InstanceStatus.Created:
|
|
51
|
-
return [undefined, holder as InstanceHolder<T>]
|
|
52
|
-
|
|
53
|
-
default:
|
|
54
|
-
return null
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
set(instanceName: string, holder: InstanceHolder): void {
|
|
59
|
-
this.contextHolder.set(instanceName, holder)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
delete(instanceName: string): boolean {
|
|
63
|
-
return this.contextHolder.delete(instanceName)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
createHolder<T>(
|
|
67
|
-
instanceName: string,
|
|
68
|
-
type: InjectableType,
|
|
69
|
-
deps: Set<string>,
|
|
70
|
-
): [
|
|
71
|
-
ReturnType<typeof Promise.withResolvers<[undefined, T]>>,
|
|
72
|
-
InstanceHolder<T>,
|
|
73
|
-
] {
|
|
74
|
-
// Use the holderManager's createCreatingHolder method
|
|
75
|
-
// which is inherited from BaseHolderManager
|
|
76
|
-
return this.holderManager.createCreatingHolder<T>(
|
|
77
|
-
instanceName,
|
|
78
|
-
type,
|
|
79
|
-
this.scope,
|
|
80
|
-
deps,
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
handles(scope: InjectableScope): boolean {
|
|
85
|
-
return scope === InjectableScope.Request
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// ============================================================================
|
|
89
|
-
// ITERATION AND QUERY
|
|
90
|
-
// ============================================================================
|
|
91
|
-
|
|
92
|
-
getAllNames(): string[] {
|
|
93
|
-
const names: string[] = []
|
|
94
|
-
for (const [name] of this.contextHolder.holders) {
|
|
95
|
-
names.push(name)
|
|
96
|
-
}
|
|
97
|
-
return names
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
forEach(callback: (name: string, holder: InstanceHolder) => void): void {
|
|
101
|
-
for (const [name, holder] of this.contextHolder.holders) {
|
|
102
|
-
callback(name, holder)
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
findByInstance(instance: unknown): InstanceHolder | null {
|
|
107
|
-
for (const holder of this.contextHolder.holders.values()) {
|
|
108
|
-
if (holder.instance === instance) {
|
|
109
|
-
return holder
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return null
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
findDependents(instanceName: string): string[] {
|
|
116
|
-
// Get dependents from request context (O(1) using reverse index)
|
|
117
|
-
const requestDependents = this.contextHolder.getDependents(instanceName)
|
|
118
|
-
|
|
119
|
-
// Also check singleton holders - a singleton may depend on this request-scoped service
|
|
120
|
-
const singletonDependents = this.holderManager.getDependents(instanceName)
|
|
121
|
-
|
|
122
|
-
// Combine both arrays (avoid allocations if one is empty)
|
|
123
|
-
if (requestDependents.length === 0) return singletonDependents
|
|
124
|
-
if (singletonDependents.length === 0) return requestDependents
|
|
125
|
-
return [...requestDependents, ...singletonDependents]
|
|
126
|
-
}
|
|
127
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import type { HolderManager } from './holder-manager.mjs'
|
|
2
|
-
import type {
|
|
3
|
-
HolderGetResult,
|
|
4
|
-
IHolderStorage,
|
|
5
|
-
} from './holder-storage.interface.mjs'
|
|
6
|
-
import type { InstanceHolder } from './instance-holder.mjs'
|
|
7
|
-
|
|
8
|
-
import { InjectableScope, InjectableType } from '../../enums/index.mjs'
|
|
9
|
-
import { DIErrorCode } from '../../errors/index.mjs'
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Storage implementation for Singleton-scoped services.
|
|
13
|
-
*
|
|
14
|
-
* Wraps a HolderManager instance and provides the IHolderStorage interface.
|
|
15
|
-
* This allows the InstanceResolver to work with singleton storage
|
|
16
|
-
* using the same interface as request-scoped storage.
|
|
17
|
-
*/
|
|
18
|
-
export class SingletonStorage implements IHolderStorage {
|
|
19
|
-
readonly scope = InjectableScope.Singleton
|
|
20
|
-
|
|
21
|
-
constructor(private readonly manager: HolderManager) {}
|
|
22
|
-
|
|
23
|
-
get<T = unknown>(instanceName: string): HolderGetResult<T> {
|
|
24
|
-
const [error, holder] = this.manager.get(instanceName)
|
|
25
|
-
|
|
26
|
-
if (!error) {
|
|
27
|
-
return [undefined, holder as InstanceHolder<T>]
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Handle different error types
|
|
31
|
-
switch (error.code) {
|
|
32
|
-
case DIErrorCode.InstanceNotFound:
|
|
33
|
-
return null
|
|
34
|
-
|
|
35
|
-
case DIErrorCode.InstanceDestroying:
|
|
36
|
-
return [error, holder as InstanceHolder<T> | undefined]
|
|
37
|
-
|
|
38
|
-
default:
|
|
39
|
-
return [error]
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
set(instanceName: string, holder: InstanceHolder): void {
|
|
44
|
-
this.manager.set(instanceName, holder)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
delete(instanceName: string): boolean {
|
|
48
|
-
return this.manager.delete(instanceName)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
createHolder<T>(
|
|
52
|
-
instanceName: string,
|
|
53
|
-
type: InjectableType,
|
|
54
|
-
deps: Set<string>,
|
|
55
|
-
): [
|
|
56
|
-
ReturnType<typeof Promise.withResolvers<[undefined, T]>>,
|
|
57
|
-
InstanceHolder<T>,
|
|
58
|
-
] {
|
|
59
|
-
return this.manager.createCreatingHolder<T>(
|
|
60
|
-
instanceName,
|
|
61
|
-
type,
|
|
62
|
-
this.scope,
|
|
63
|
-
deps,
|
|
64
|
-
)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
handles(scope: InjectableScope): boolean {
|
|
68
|
-
return scope === InjectableScope.Singleton
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// ============================================================================
|
|
72
|
-
// ITERATION AND QUERY
|
|
73
|
-
// ============================================================================
|
|
74
|
-
|
|
75
|
-
getAllNames(): string[] {
|
|
76
|
-
return this.manager.getAllNames()
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
forEach(
|
|
80
|
-
callback: (name: string, holder: InstanceHolder) => void,
|
|
81
|
-
): void {
|
|
82
|
-
this.manager.forEachHolder((holder, name) => callback(name, holder))
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
findByInstance(instance: unknown): InstanceHolder | null {
|
|
86
|
-
return this.manager.findHolder((h) => h.instance === instance) ?? null
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
findDependents(instanceName: string): string[] {
|
|
90
|
-
return this.manager.getDependents(instanceName)
|
|
91
|
-
}
|
|
92
|
-
}
|
package/src/testing/README.md
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# Testing Infrastructure
|
|
2
|
-
|
|
3
|
-
The `@navios/di/testing` package provides a `TestContainer` class that extends the base `Container` with additional methods useful for testing.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **TestContainer**: A specialized container for testing with simplified binding methods
|
|
8
|
-
- **bind().toValue()**: Bind tokens to specific values (useful for mocks)
|
|
9
|
-
- **bind().toClass()**: Bind tokens to class constructors
|
|
10
|
-
- **clear()**: Clear all instances and bindings from the container
|
|
11
|
-
- **Convenience methods**: `bindValue()`, `bindClass()`, `createChild()`
|
|
12
|
-
|
|
13
|
-
## Usage
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
import { Injectable, InjectionToken } from '@navios/di'
|
|
17
|
-
import { TestContainer } from '@navios/di/testing'
|
|
18
|
-
|
|
19
|
-
// Create a test container
|
|
20
|
-
const container = new TestContainer()
|
|
21
|
-
|
|
22
|
-
// Create injection tokens
|
|
23
|
-
const API_URL_TOKEN = InjectionToken.create<string>('api-url')
|
|
24
|
-
const HTTP_CLIENT_TOKEN = InjectionToken.create<HttpClient>('http-client')
|
|
25
|
-
|
|
26
|
-
// Mock implementations
|
|
27
|
-
class MockHttpClient implements HttpClient {
|
|
28
|
-
async get(url: string) {
|
|
29
|
-
return { data: 'mocked response' }
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Bind values for testing
|
|
34
|
-
container.bindValue(API_URL_TOKEN, 'https://test-api.com')
|
|
35
|
-
container.bindClass(HTTP_CLIENT_TOKEN, MockHttpClient)
|
|
36
|
-
|
|
37
|
-
// Or use the fluent API
|
|
38
|
-
container.bind(API_URL_TOKEN).toValue('https://test-api.com')
|
|
39
|
-
|
|
40
|
-
container.bind(HTTP_CLIENT_TOKEN).toClass(MockHttpClient)
|
|
41
|
-
|
|
42
|
-
// Bind a class to itself
|
|
43
|
-
@Injectable()
|
|
44
|
-
class UserService {
|
|
45
|
-
constructor(
|
|
46
|
-
@Inject(API_URL_TOKEN) private apiUrl: string,
|
|
47
|
-
@Inject(HTTP_CLIENT_TOKEN) private httpClient: HttpClient,
|
|
48
|
-
) {}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
container.bindSelf(UserService)
|
|
52
|
-
|
|
53
|
-
// Clear the container between tests
|
|
54
|
-
container.clear()
|
|
55
|
-
|
|
56
|
-
// Create isolated child containers
|
|
57
|
-
const childContainer = container.createChild()
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## API Reference
|
|
61
|
-
|
|
62
|
-
### TestContainer
|
|
63
|
-
|
|
64
|
-
#### Methods
|
|
65
|
-
|
|
66
|
-
- `bind<T>(token: InjectionToken<T, any>): TestBindingBuilder<T>` - Creates a binding builder
|
|
67
|
-
- `bind<T>(token: ClassType): TestBindingBuilder<T>` - Creates a binding builder
|
|
68
|
-
- `bindValue<T>(token: InjectionToken<T, any>, value: T): TestContainer` - Binds a value to a token
|
|
69
|
-
- `bindValue<T>(token: ClassType, value: T): TestContainer` - Binds a value to a token
|
|
70
|
-
- `bindClass<T>(token: InjectionToken<T, any>, target: ClassType): TestContainer` - Binds a class to a token
|
|
71
|
-
- `bindClass<T>(token: ClassType, target: ClassType): TestContainer` - Binds a class to a token
|
|
72
|
-
- `createChild(): TestContainer` - Creates a new isolated test container
|
|
73
|
-
- `clear(): void` - Clears all instances and bindings
|
|
74
|
-
|
|
75
|
-
### TestBindingBuilder
|
|
76
|
-
|
|
77
|
-
#### Methods
|
|
78
|
-
|
|
79
|
-
- `toValue(value: T): TestContainer` - Binds the token to a specific value
|
|
80
|
-
- `toClass(target: ClassType): TestContainer` - Binds the token to a class constructor
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import { Injectable } from '../../decorators/injectable.decorator.mjs'
|
|
4
|
-
import { InjectionToken } from '../../token/injection-token.mjs'
|
|
5
|
-
import { inject } from '../../injectors.mjs'
|
|
6
|
-
import { TestContainer } from '../test-container.mjs'
|
|
7
|
-
|
|
8
|
-
describe('TestContainer', () => {
|
|
9
|
-
let container: TestContainer
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
container = new TestContainer()
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
describe('clear method', () => {
|
|
16
|
-
it('should clear all instances from the container', () => {
|
|
17
|
-
// This test verifies that the clear method exists and can be called
|
|
18
|
-
expect(() => container.clear()).not.toThrow()
|
|
19
|
-
})
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
describe('bind method', () => {
|
|
23
|
-
it('should create a TestBindingBuilder', () => {
|
|
24
|
-
const token = InjectionToken.create<string>('test-token')
|
|
25
|
-
const builder = container.bind(token)
|
|
26
|
-
expect(builder).toBeDefined()
|
|
27
|
-
expect(builder).toHaveProperty('toValue')
|
|
28
|
-
expect(builder).toHaveProperty('toClass')
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('should allow chaining bind operations', () => {
|
|
32
|
-
const token = InjectionToken.create<string>('test-token')
|
|
33
|
-
const result = container.bind(token).toValue('test-value')
|
|
34
|
-
expect(result).toBe(container)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it('should bind value and retrieve it correctly', async () => {
|
|
38
|
-
const token = InjectionToken.create<string>('test-token')
|
|
39
|
-
const testValue = 'test-value'
|
|
40
|
-
|
|
41
|
-
container.bind(token).toValue(testValue)
|
|
42
|
-
|
|
43
|
-
const retrievedValue = await container.get(token)
|
|
44
|
-
expect(retrievedValue).toBe(testValue)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('should bind class and retrieve instance correctly', async () => {
|
|
48
|
-
@Injectable()
|
|
49
|
-
class TestService {
|
|
50
|
-
getValue() {
|
|
51
|
-
return 'test-service-value'
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const token = InjectionToken.create<TestService>('test-service')
|
|
56
|
-
|
|
57
|
-
container.bind(token).toClass(TestService)
|
|
58
|
-
|
|
59
|
-
const instance = await container.get(token)
|
|
60
|
-
expect(instance).toBeInstanceOf(TestService)
|
|
61
|
-
expect(instance.getValue()).toBe('test-service-value')
|
|
62
|
-
})
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
describe('bindValue method', () => {
|
|
66
|
-
it('should bind a value to a token', () => {
|
|
67
|
-
const token = InjectionToken.create<string>('test-token')
|
|
68
|
-
const result = container.bindValue(token, 'test-value')
|
|
69
|
-
expect(result).toBe(container)
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('should bind value and retrieve it correctly', async () => {
|
|
73
|
-
const token = InjectionToken.create<number>('number-token')
|
|
74
|
-
const testValue = 42
|
|
75
|
-
|
|
76
|
-
container.bindValue(token, testValue)
|
|
77
|
-
|
|
78
|
-
const retrievedValue = await container.get(token)
|
|
79
|
-
expect(retrievedValue).toBe(testValue)
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
it('should bind object value and retrieve it correctly', async () => {
|
|
83
|
-
interface TestConfig {
|
|
84
|
-
apiUrl: string
|
|
85
|
-
timeout: number
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const token = InjectionToken.create<TestConfig>('config-token')
|
|
89
|
-
const testConfig: TestConfig = {
|
|
90
|
-
apiUrl: 'https://api.example.com',
|
|
91
|
-
timeout: 5000,
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
container.bindValue(token, testConfig)
|
|
95
|
-
|
|
96
|
-
const retrievedConfig = await container.get(token)
|
|
97
|
-
expect(retrievedConfig).toEqual(testConfig)
|
|
98
|
-
expect(retrievedConfig.apiUrl).toBe('https://api.example.com')
|
|
99
|
-
expect(retrievedConfig.timeout).toBe(5000)
|
|
100
|
-
})
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
describe('bindClass method', () => {
|
|
104
|
-
it('should bind a class to a token', () => {
|
|
105
|
-
class TestClass {}
|
|
106
|
-
const token = InjectionToken.create<TestClass>('test-token')
|
|
107
|
-
const result = container.bindClass(token, TestClass)
|
|
108
|
-
expect(result).toBe(container)
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
it('should bind class and retrieve instance correctly', async () => {
|
|
112
|
-
@Injectable()
|
|
113
|
-
class UserService {
|
|
114
|
-
private users: string[] = ['alice', 'bob']
|
|
115
|
-
|
|
116
|
-
getUsers() {
|
|
117
|
-
return this.users
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
addUser(user: string) {
|
|
121
|
-
this.users.push(user)
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const token = InjectionToken.create<UserService>('user-service')
|
|
126
|
-
|
|
127
|
-
container.bindClass(token, UserService)
|
|
128
|
-
|
|
129
|
-
const instance = await container.get(token)
|
|
130
|
-
expect(instance).toBeInstanceOf(UserService)
|
|
131
|
-
expect(instance.getUsers()).toEqual(['alice', 'bob'])
|
|
132
|
-
|
|
133
|
-
instance.addUser('charlie')
|
|
134
|
-
expect(instance.getUsers()).toEqual(['alice', 'bob', 'charlie'])
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
it('should bind class with dependencies and retrieve instance correctly', async () => {
|
|
138
|
-
@Injectable()
|
|
139
|
-
class DatabaseService {
|
|
140
|
-
connect() {
|
|
141
|
-
return 'connected'
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
@Injectable()
|
|
146
|
-
class UserRepository {
|
|
147
|
-
db = inject(DatabaseService)
|
|
148
|
-
|
|
149
|
-
findUser(id: string) {
|
|
150
|
-
return `User ${id} from ${this.db.connect()}`
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const dbToken = InjectionToken.create<DatabaseService>('db-service')
|
|
155
|
-
const userRepoToken = InjectionToken.create<UserRepository>('user-repo')
|
|
156
|
-
|
|
157
|
-
container.bindClass(dbToken, DatabaseService)
|
|
158
|
-
container.bindClass(userRepoToken, UserRepository)
|
|
159
|
-
|
|
160
|
-
const userRepo = await container.get(userRepoToken)
|
|
161
|
-
expect(userRepo).toBeInstanceOf(UserRepository)
|
|
162
|
-
expect(userRepo.findUser('123')).toBe('User 123 from connected')
|
|
163
|
-
})
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
describe('createChild method', () => {
|
|
167
|
-
it('should create a new TestContainer instance', () => {
|
|
168
|
-
const child = container.createChild()
|
|
169
|
-
expect(child).toBeInstanceOf(TestContainer)
|
|
170
|
-
expect(child).not.toBe(container)
|
|
171
|
-
})
|
|
172
|
-
})
|
|
173
|
-
})
|