ts-ioc-container 55.9.0 → 56.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/README.md +57 -6
- package/package.json +21 -68
- package/cjm/ExecutionContext.js +0 -2
- package/cjm/container/AliasMap.js +0 -25
- package/cjm/container/Container.js +0 -175
- package/cjm/container/EmptyContainer.js +0 -71
- package/cjm/container/IContainer.js +0 -6
- package/cjm/errors/CannonSingletonApplyTwiceError.js +0 -17
- package/cjm/errors/ContainerDisposedError.js +0 -12
- package/cjm/errors/ContainerError.js +0 -11
- package/cjm/errors/ContainerNotFoundError.js +0 -12
- package/cjm/errors/DependencyMissingKeyError.js +0 -12
- package/cjm/errors/DependencyNotFoundError.js +0 -12
- package/cjm/errors/MethodNotImplementedError.js +0 -12
- package/cjm/errors/ProviderDisposedError.js +0 -17
- package/cjm/errors/UnexpectedHookResultError.js +0 -12
- package/cjm/errors/UnsupportedTokenTypeError.js +0 -12
- package/cjm/hooks/HookContext.js +0 -42
- package/cjm/hooks/HooksRunner.js +0 -42
- package/cjm/hooks/hook.js +0 -49
- package/cjm/hooks/injectProp.js +0 -6
- package/cjm/hooks/onConstruct.js +0 -28
- package/cjm/hooks/onConstructAsync.js +0 -28
- package/cjm/hooks/onContainerDisposed.js +0 -18
- package/cjm/index.js +0 -133
- package/cjm/injector/IInjector.js +0 -14
- package/cjm/injector/MetadataInjector.js +0 -33
- package/cjm/injector/ProxyInjector.js +0 -18
- package/cjm/injector/SimpleInjector.js +0 -10
- package/cjm/metadata/class.js +0 -21
- package/cjm/metadata/method.js +0 -19
- package/cjm/metadata/parameter.js +0 -34
- package/cjm/provider/IProvider.js +0 -2
- package/cjm/provider/Provider.js +0 -80
- package/cjm/registration/IRegistration.js +0 -43
- package/cjm/registration/Registration.js +0 -85
- package/cjm/select.js +0 -16
- package/cjm/token/BindToken.js +0 -7
- package/cjm/token/ClassToken.js +0 -45
- package/cjm/token/ConstantToken.js +0 -25
- package/cjm/token/FunctionToken.js +0 -42
- package/cjm/token/GroupAliasToken.js +0 -50
- package/cjm/token/GroupInstanceToken.js +0 -33
- package/cjm/token/InjectionToken.js +0 -11
- package/cjm/token/SingleAliasToken.js +0 -50
- package/cjm/token/SingleToken.js +0 -48
- package/cjm/token/toToken.js +0 -29
- package/cjm/utils/array.js +0 -9
- package/cjm/utils/basic.js +0 -13
- package/cjm/utils/debounce.js +0 -16
- package/cjm/utils/errorHandler.js +0 -29
- package/cjm/utils/fp.js +0 -6
- package/cjm/utils/once.js +0 -20
- package/cjm/utils/promise.js +0 -5
- package/cjm/utils/proxy.js +0 -39
- package/cjm/utils/shallowCache.js +0 -23
- package/cjm/utils/throttle.js +0 -18
- package/esm/ExecutionContext.js +0 -1
- package/esm/container/AliasMap.js +0 -21
- package/esm/container/Container.js +0 -171
- package/esm/container/EmptyContainer.js +0 -67
- package/esm/container/IContainer.js +0 -3
- package/esm/errors/CannonSingletonApplyTwiceError.js +0 -13
- package/esm/errors/ContainerDisposedError.js +0 -8
- package/esm/errors/ContainerError.js +0 -7
- package/esm/errors/ContainerNotFoundError.js +0 -8
- package/esm/errors/DependencyMissingKeyError.js +0 -8
- package/esm/errors/DependencyNotFoundError.js +0 -8
- package/esm/errors/MethodNotImplementedError.js +0 -8
- package/esm/errors/ProviderDisposedError.js +0 -13
- package/esm/errors/UnexpectedHookResultError.js +0 -8
- package/esm/errors/UnsupportedTokenTypeError.js +0 -8
- package/esm/hooks/HookContext.js +0 -36
- package/esm/hooks/HooksRunner.js +0 -38
- package/esm/hooks/hook.js +0 -42
- package/esm/hooks/injectProp.js +0 -2
- package/esm/hooks/onConstruct.js +0 -23
- package/esm/hooks/onConstructAsync.js +0 -23
- package/esm/hooks/onContainerDisposed.js +0 -13
- package/esm/index.js +0 -44
- package/esm/injector/IInjector.js +0 -10
- package/esm/injector/MetadataInjector.js +0 -25
- package/esm/injector/ProxyInjector.js +0 -14
- package/esm/injector/SimpleInjector.js +0 -6
- package/esm/metadata/class.js +0 -12
- package/esm/metadata/method.js +0 -10
- package/esm/metadata/parameter.js +0 -25
- package/esm/package.json +0 -3
- package/esm/provider/IProvider.js +0 -1
- package/esm/provider/Provider.js +0 -76
- package/esm/registration/IRegistration.js +0 -28
- package/esm/registration/Registration.js +0 -81
- package/esm/select.js +0 -13
- package/esm/token/BindToken.js +0 -4
- package/esm/token/ClassToken.js +0 -41
- package/esm/token/ConstantToken.js +0 -21
- package/esm/token/FunctionToken.js +0 -38
- package/esm/token/GroupAliasToken.js +0 -45
- package/esm/token/GroupInstanceToken.js +0 -29
- package/esm/token/InjectionToken.js +0 -6
- package/esm/token/SingleAliasToken.js +0 -45
- package/esm/token/SingleToken.js +0 -44
- package/esm/token/toToken.js +0 -24
- package/esm/utils/array.js +0 -6
- package/esm/utils/basic.js +0 -9
- package/esm/utils/debounce.js +0 -12
- package/esm/utils/errorHandler.js +0 -24
- package/esm/utils/fp.js +0 -3
- package/esm/utils/once.js +0 -16
- package/esm/utils/promise.js +0 -1
- package/esm/utils/proxy.js +0 -33
- package/esm/utils/shallowCache.js +0 -19
- package/esm/utils/throttle.js +0 -14
- package/typings/ExecutionContext.d.ts +0 -4
- package/typings/container/AliasMap.d.ts +0 -8
- package/typings/container/Container.d.ts +0 -48
- package/typings/container/EmptyContainer.d.ts +0 -30
- package/typings/container/IContainer.d.ts +0 -56
- package/typings/errors/CannonSingletonApplyTwiceError.d.ts +0 -6
- package/typings/errors/ContainerDisposedError.d.ts +0 -5
- package/typings/errors/ContainerError.d.ts +0 -4
- package/typings/errors/ContainerNotFoundError.d.ts +0 -5
- package/typings/errors/DependencyMissingKeyError.d.ts +0 -5
- package/typings/errors/DependencyNotFoundError.d.ts +0 -5
- package/typings/errors/MethodNotImplementedError.d.ts +0 -5
- package/typings/errors/ProviderDisposedError.d.ts +0 -6
- package/typings/errors/UnexpectedHookResultError.d.ts +0 -5
- package/typings/errors/UnsupportedTokenTypeError.d.ts +0 -5
- package/typings/hooks/HookContext.d.ts +0 -35
- package/typings/hooks/HooksRunner.d.ts +0 -16
- package/typings/hooks/hook.d.ts +0 -14
- package/typings/hooks/injectProp.d.ts +0 -5
- package/typings/hooks/onConstruct.d.ts +0 -14
- package/typings/hooks/onConstructAsync.d.ts +0 -12
- package/typings/hooks/onContainerDisposed.d.ts +0 -10
- package/typings/index.d.ts +0 -46
- package/typings/injector/IInjector.d.ts +0 -17
- package/typings/injector/MetadataInjector.d.ts +0 -13
- package/typings/injector/ProxyInjector.d.ts +0 -6
- package/typings/injector/SimpleInjector.d.ts +0 -6
- package/typings/metadata/class.d.ts +0 -6
- package/typings/metadata/method.d.ts +0 -6
- package/typings/metadata/parameter.d.ts +0 -6
- package/typings/provider/IProvider.d.ts +0 -26
- package/typings/provider/Provider.d.ts +0 -26
- package/typings/registration/IRegistration.d.ts +0 -31
- package/typings/registration/Registration.d.ts +0 -28
- package/typings/select.d.ts +0 -12
- package/typings/token/BindToken.d.ts +0 -5
- package/typings/token/ClassToken.d.ts +0 -18
- package/typings/token/ConstantToken.d.ts +0 -10
- package/typings/token/FunctionToken.d.ts +0 -17
- package/typings/token/GroupAliasToken.d.ts +0 -21
- package/typings/token/GroupInstanceToken.d.ts +0 -15
- package/typings/token/InjectionToken.d.ts +0 -9
- package/typings/token/SingleAliasToken.d.ts +0 -21
- package/typings/token/SingleToken.d.ts +0 -19
- package/typings/token/toToken.d.ts +0 -6
- package/typings/utils/array.d.ts +0 -3
- package/typings/utils/basic.d.ts +0 -14
- package/typings/utils/debounce.d.ts +0 -1
- package/typings/utils/errorHandler.d.ts +0 -6
- package/typings/utils/fp.d.ts +0 -13
- package/typings/utils/once.d.ts +0 -8
- package/typings/utils/promise.d.ts +0 -1
- package/typings/utils/proxy.d.ts +0 -4
- package/typings/utils/shallowCache.d.ts +0 -1
- package/typings/utils/throttle.d.ts +0 -1
package/README.md
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|

|
|
6
6
|
[](https://coveralls.io/github/IgorBabkin/ts-ioc-container?branch=master)
|
|
7
7
|

|
|
8
|
-
[](https://github.com/semantic-release/semantic-release)
|
|
9
8
|
|
|
10
9
|
`ts-ioc-container` is a fast, lightweight TypeScript dependency injection
|
|
11
10
|
container for applications that need more than basic constructor injection:
|
|
@@ -2167,6 +2166,8 @@ Registration is provider factory which registers provider in container.
|
|
|
2167
2166
|
|
|
2168
2167
|
Use `bindTo(key)` to register a provider under a specific key. By default the key is the class name. Multiple registrations can share the same key.
|
|
2169
2168
|
|
|
2169
|
+
A plain `DependencyKey` (`string` / `symbol`) or an `InjectionToken` that implements `BindToken` (`SingleToken`, `SingleAliasToken`, `GroupAliasToken`) can also be passed directly to `@register(...)` — it binds under the hood exactly like `bindTo(...)`, so `@register('ILogger')` / `@register(LoggerToken)` and `@register(bindTo('ILogger'))` / `@register(bindTo(LoggerToken))` are equivalent.
|
|
2170
|
+
|
|
2170
2171
|
> [!TIP]
|
|
2171
2172
|
> Prefer `SingleToken<T>` over plain string literals as registration keys. Tokens are type-safe, rename-friendly, and prevent typos that only surface at runtime.
|
|
2172
2173
|
|
|
@@ -2179,6 +2180,7 @@ import {
|
|
|
2179
2180
|
Registration as R,
|
|
2180
2181
|
scope,
|
|
2181
2182
|
select as s,
|
|
2183
|
+
SingleToken,
|
|
2182
2184
|
singleton,
|
|
2183
2185
|
} from 'ts-ioc-container';
|
|
2184
2186
|
|
|
@@ -2240,6 +2242,28 @@ describe('Registration module', function () {
|
|
|
2240
2242
|
expect(appContainer.resolve('FileLogger')).toBeInstanceOf(FileLogger);
|
|
2241
2243
|
});
|
|
2242
2244
|
|
|
2245
|
+
it('should register directly from a token passed to @register, without wrapping it in bindTo()', function () {
|
|
2246
|
+
// Passing an InjectionToken straight to @register binds to it under the hood
|
|
2247
|
+
const LoggerToken = new SingleToken<FileLogger>('ILogger');
|
|
2248
|
+
|
|
2249
|
+
@register(LoggerToken, singleton())
|
|
2250
|
+
class FileLogger {}
|
|
2251
|
+
|
|
2252
|
+
const appContainer = createAppContainer().addRegistration(R.fromClass(FileLogger));
|
|
2253
|
+
|
|
2254
|
+
expect(LoggerToken.resolve(appContainer)).toBeInstanceOf(FileLogger);
|
|
2255
|
+
});
|
|
2256
|
+
|
|
2257
|
+
it('should register directly from a plain key passed to @register, without wrapping it in bindTo()', function () {
|
|
2258
|
+
// A plain DependencyKey straight in @register binds to it under the hood
|
|
2259
|
+
@register('PlainLogger')
|
|
2260
|
+
class Logger {}
|
|
2261
|
+
|
|
2262
|
+
const appContainer = createAppContainer().addRegistration(R.fromClass(Logger));
|
|
2263
|
+
|
|
2264
|
+
expect(appContainer.resolve('PlainLogger')).toBeInstanceOf(Logger);
|
|
2265
|
+
});
|
|
2266
|
+
|
|
2243
2267
|
it('should register with multiple keys using aliases', function () {
|
|
2244
2268
|
// Same service accessible via direct key and alias
|
|
2245
2269
|
@register(bindTo('ILogger'), bindTo(s.alias('Logger')), singleton())
|
|
@@ -2482,6 +2506,30 @@ describe('Container Modules', function () {
|
|
|
2482
2506
|
|
|
2483
2507
|
Sometimes you need to invoke methods after construct or dispose of class. This is what hooks are for.
|
|
2484
2508
|
|
|
2509
|
+
The generic `@hook` decorator takes a hook key and a map function
|
|
2510
|
+
`(...prev: HookType[]) => HookType[]`, where `prev` is the list of hooks already
|
|
2511
|
+
registered on the class for the decorated member. Use `appendHooks` /
|
|
2512
|
+
`prependHooks` (exported as `append` / `prepend` too) to place new hooks around
|
|
2513
|
+
the existing ones:
|
|
2514
|
+
|
|
2515
|
+
```typescript
|
|
2516
|
+
class OrderService {
|
|
2517
|
+
@hook('actions', append(validate, persist))
|
|
2518
|
+
@hook('actions', prepend(authorize))
|
|
2519
|
+
submit() {}
|
|
2520
|
+
}
|
|
2521
|
+
```
|
|
2522
|
+
|
|
2523
|
+
Decorators are applied bottom-up, so `authorize` runs first, then `validate` and
|
|
2524
|
+
`persist`. Any other map function works as well — for example
|
|
2525
|
+
`(...prev) => [...prev].reverse()` to reorder, or `() => [onlyThisOne]` to
|
|
2526
|
+
replace the accumulated hooks.
|
|
2527
|
+
|
|
2528
|
+
`@onConstruct`, `@onConstructAsync` and `@onContainerDisposed` keep their
|
|
2529
|
+
variadic signature and compensate for the bottom-up application order, so
|
|
2530
|
+
stacked decorators run in declaration order: `@onConstruct(h1) @onConstruct(h2)`
|
|
2531
|
+
runs `h1` before `h2`.
|
|
2532
|
+
|
|
2485
2533
|
### OnConstruct
|
|
2486
2534
|
|
|
2487
2535
|
```typescript
|
|
@@ -2741,7 +2789,7 @@ describe('onContainerDisposed', function () {
|
|
|
2741
2789
|
|
|
2742
2790
|
```typescript
|
|
2743
2791
|
import 'reflect-metadata';
|
|
2744
|
-
import { Container, hook, HooksRunner, injectProp, Registration } from 'ts-ioc-container';
|
|
2792
|
+
import { append, Container, hook, HooksRunner, injectProp, Registration } from 'ts-ioc-container';
|
|
2745
2793
|
|
|
2746
2794
|
/**
|
|
2747
2795
|
* UI Components - Property Injection
|
|
@@ -2761,7 +2809,7 @@ describe('inject property', () => {
|
|
|
2761
2809
|
|
|
2762
2810
|
class UserViewModel {
|
|
2763
2811
|
// Inject 'GreetingService' into 'greeting' property during 'onInit'
|
|
2764
|
-
@hook('onInit', injectProp('GreetingService'))
|
|
2812
|
+
@hook('onInit', append(injectProp('GreetingService')))
|
|
2765
2813
|
greetingService!: string;
|
|
2766
2814
|
|
|
2767
2815
|
display(): string {
|
|
@@ -2787,9 +2835,12 @@ describe('inject property', () => {
|
|
|
2787
2835
|
let injectedValue: unknown;
|
|
2788
2836
|
|
|
2789
2837
|
class UserViewModel {
|
|
2790
|
-
@hook(
|
|
2791
|
-
|
|
2792
|
-
|
|
2838
|
+
@hook(
|
|
2839
|
+
'onInit',
|
|
2840
|
+
append(injectProp('GreetingService'), (context) => {
|
|
2841
|
+
injectedValue = context.getProperty();
|
|
2842
|
+
}),
|
|
2843
|
+
)
|
|
2793
2844
|
greetingService!: string;
|
|
2794
2845
|
}
|
|
2795
2846
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-ioc-container",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "56.1.0",
|
|
4
4
|
"description": "Fast, lightweight TypeScript dependency injection container with a clean API, scoped lifecycles, decorators, tokens, hooks, lazy injection, customizable providers, and no global container objects.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -58,31 +58,8 @@
|
|
|
58
58
|
],
|
|
59
59
|
"repository": {
|
|
60
60
|
"type": "git",
|
|
61
|
-
"url": "git+https://github.com/IgorBabkin/ts-ioc-container"
|
|
62
|
-
|
|
63
|
-
"scripts": {
|
|
64
|
-
"build:cjm": "rimraf cjm && tsc -p tsconfig.production.json --outDir cjm --module CommonJS",
|
|
65
|
-
"build:esm": "rimraf esm && tsc -p tsconfig.production.json --outDir esm && node scripts/postbuild-extensions.mjs esm --esm",
|
|
66
|
-
"build:types": "rimraf typings && tsc -p tsconfig.production.json --outDir typings --emitDeclarationOnly --declaration && node scripts/postbuild-extensions.mjs typings",
|
|
67
|
-
"generate:docs": "scripts/generate-readme/generate-readme.ts && git add README.md",
|
|
68
|
-
"build": "npm run build:cjm && npm run build:esm && npm run build:types",
|
|
69
|
-
"test": "vitest run",
|
|
70
|
-
"test:spec": "vitest run __tests__/specs",
|
|
71
|
-
"bench:spec": "vitest bench __benchmarks__/specs/*.bench.ts",
|
|
72
|
-
"test:coverage": "vitest run --coverage --coverage.reporter=lcov",
|
|
73
|
-
"type-check": "tsc --noEmit",
|
|
74
|
-
"type-check:watch": "tsc --noEmit --watch",
|
|
75
|
-
"commit": "cz",
|
|
76
|
-
"format": "prettier --write \"**/*.ts\"",
|
|
77
|
-
"lint": "eslint lib/**/*.ts __tests__/**/*.ts __benchmarks__/**/*.ts scripts/**/*.ts",
|
|
78
|
-
"lint:fix": "npm run lint --fix",
|
|
79
|
-
"audit": "npm audit",
|
|
80
|
-
"prepare": "husky",
|
|
81
|
-
"release": "npm run build && npm test && npm publish",
|
|
82
|
-
"docs:dev": "pnpm --filter ts-ioc-container-docs run dev",
|
|
83
|
-
"docs:serve": "pnpm --filter ts-ioc-container-docs run dev",
|
|
84
|
-
"docs:build": "pnpm --filter ts-ioc-container-docs run build",
|
|
85
|
-
"docs:preview": "pnpm --filter ts-ioc-container-docs run preview"
|
|
61
|
+
"url": "git+https://github.com/IgorBabkin/ts-ioc-container",
|
|
62
|
+
"directory": "packages/ts-ioc-container"
|
|
86
63
|
},
|
|
87
64
|
"peerDependencies": {
|
|
88
65
|
"reflect-metadata": "^0.2.0"
|
|
@@ -93,59 +70,35 @@
|
|
|
93
70
|
}
|
|
94
71
|
},
|
|
95
72
|
"devDependencies": {
|
|
96
|
-
"@commitlint/cli": "^20.2.0",
|
|
97
|
-
"@commitlint/config-conventional": "^20.2.0",
|
|
98
|
-
"@eslint/eslintrc": "^3.3.5",
|
|
99
|
-
"@eslint/js": "^9.24.0",
|
|
100
|
-
"@semantic-release/changelog": "^6.0.3",
|
|
101
|
-
"@semantic-release/git": "^10.0.1",
|
|
102
|
-
"@semantic-release/github": "^12.0.2",
|
|
103
|
-
"@semantic-release/npm": "^13.1.2",
|
|
104
73
|
"@swc/core": "^1.15.24",
|
|
105
74
|
"@types/node": "^25.5.2",
|
|
106
|
-
"@typescript-eslint/eslint-plugin": "8.32.1",
|
|
107
|
-
"@typescript-eslint/parser": "8.58.2",
|
|
108
75
|
"@vitest/coverage-v8": "^4.1.2",
|
|
109
|
-
"cz-conventional-changelog": "^3.3.0",
|
|
110
|
-
"eslint": "9.24.0",
|
|
111
|
-
"eslint-config-prettier": "10.1.8",
|
|
112
|
-
"eslint-plugin-prettier": "5.2.6",
|
|
113
|
-
"handlebars": "^4.7.8",
|
|
114
|
-
"husky": "^9.1.7",
|
|
115
|
-
"lint-staged": "^16.4.0",
|
|
116
76
|
"moq.ts": "^10.0.8",
|
|
117
|
-
"prettier": "3.5.3",
|
|
118
|
-
"prettier-plugin-astro": "^0.14.1",
|
|
119
77
|
"reflect-metadata": "^0.2.2",
|
|
120
|
-
"rimraf": "6.1.3",
|
|
121
|
-
"semantic-release": "^25.0.2",
|
|
122
|
-
"tsx": "^4.21.0",
|
|
123
78
|
"tsyringe": "^4.10.0",
|
|
124
79
|
"typescript": "5.8.3",
|
|
125
80
|
"unplugin-swc": "^1.5.9",
|
|
126
81
|
"vite": "^6.4.1",
|
|
127
82
|
"vitest": "^4.1.2"
|
|
128
83
|
},
|
|
129
|
-
"lint-staged": {
|
|
130
|
-
"*.{js,ts,tsx}": [
|
|
131
|
-
"eslint --fix",
|
|
132
|
-
"prettier --write"
|
|
133
|
-
],
|
|
134
|
-
"docs/**/*.{js,ts,tsx,mjs,astro}": [
|
|
135
|
-
"prettier --write"
|
|
136
|
-
],
|
|
137
|
-
"docs/**/*.astro": [
|
|
138
|
-
"eslint --fix"
|
|
139
|
-
]
|
|
140
|
-
},
|
|
141
|
-
"gitHead": "ae10f302c7e0f55196b42669040735112479a854",
|
|
142
|
-
"config": {
|
|
143
|
-
"commitizen": {
|
|
144
|
-
"path": "./node_modules/cz-conventional-changelog"
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
"packageManager": "pnpm@10.20.0+sha512.cf9998222162dd85864d0a8102e7892e7ba4ceadebbf5a31f9c2fce48dfce317a9c53b9f6464d1ef9042cba2e02ae02a9f7c143a2b438cd93c91840f0192b9dd",
|
|
148
84
|
"engines": {
|
|
149
85
|
"node": ">= 18"
|
|
86
|
+
},
|
|
87
|
+
"scripts": {
|
|
88
|
+
"build:cjm": "node ../scripts/build.mjs cjm",
|
|
89
|
+
"build:esm": "node ../scripts/build.mjs esm",
|
|
90
|
+
"build:types": "node ../scripts/build.mjs types",
|
|
91
|
+
"generate:docs": "../scripts/generate-readme/generate-readme.ts && git add README.md",
|
|
92
|
+
"build": "pnpm run build:cjm && pnpm run build:esm && pnpm run build:types",
|
|
93
|
+
"test": "vitest run",
|
|
94
|
+
"test:spec": "vitest run __tests__/specs",
|
|
95
|
+
"bench:spec": "vitest bench __benchmarks__/specs/*.bench.ts",
|
|
96
|
+
"test:coverage": "vitest run --coverage --coverage.reporter=lcov --maxWorkers=2",
|
|
97
|
+
"type-check": "tsc --noEmit",
|
|
98
|
+
"type-check:watch": "tsc --noEmit --watch",
|
|
99
|
+
"format": "prettier --write \"**/*.ts\"",
|
|
100
|
+
"format:check": "prettier --check \"lib/**/*.ts\" \"__tests__/**/*.ts\" \"__benchmarks__/**/*.ts\"",
|
|
101
|
+
"lint": "eslint lib/**/*.ts __tests__/**/*.ts __benchmarks__/**/*.ts",
|
|
102
|
+
"lint:fix": "pnpm run lint --fix"
|
|
150
103
|
}
|
|
151
|
-
}
|
|
104
|
+
}
|
package/cjm/ExecutionContext.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AliasMap = void 0;
|
|
4
|
-
class AliasMap {
|
|
5
|
-
aliasToKeySet = new Map();
|
|
6
|
-
getKeysByAlias(alias) {
|
|
7
|
-
return [...(this.aliasToKeySet.get(alias) ?? [])];
|
|
8
|
-
}
|
|
9
|
-
setAliasesByKey(key, aliases) {
|
|
10
|
-
for (const [alias, keySet] of this.aliasToKeySet) {
|
|
11
|
-
keySet.delete(key);
|
|
12
|
-
if (keySet.size === 0) {
|
|
13
|
-
this.aliasToKeySet.delete(alias);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
for (const alias of aliases) {
|
|
17
|
-
const dependencyKeySet = this.aliasToKeySet.get(alias) ?? new Set();
|
|
18
|
-
this.aliasToKeySet.set(alias, dependencyKeySet.add(key));
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
destroy() {
|
|
22
|
-
this.aliasToKeySet.clear();
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
exports.AliasMap = AliasMap;
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Container = void 0;
|
|
4
|
-
const EmptyContainer_1 = require("./EmptyContainer");
|
|
5
|
-
const ContainerDisposedError_1 = require("../errors/ContainerDisposedError");
|
|
6
|
-
const MetadataInjector_1 = require("../injector/MetadataInjector");
|
|
7
|
-
const AliasMap_1 = require("./AliasMap");
|
|
8
|
-
const DependencyNotFoundError_1 = require("../errors/DependencyNotFoundError");
|
|
9
|
-
const basic_1 = require("../utils/basic");
|
|
10
|
-
const array_1 = require("../utils/array");
|
|
11
|
-
class Container {
|
|
12
|
-
isDisposed = false;
|
|
13
|
-
parent;
|
|
14
|
-
scopes = [];
|
|
15
|
-
instances = [];
|
|
16
|
-
registrations = [];
|
|
17
|
-
tags;
|
|
18
|
-
providers = new Map();
|
|
19
|
-
aliases = new AliasMap_1.AliasMap();
|
|
20
|
-
injector;
|
|
21
|
-
onConstructHookList = [];
|
|
22
|
-
onDisposeHookList = [];
|
|
23
|
-
constructor(options = {}) {
|
|
24
|
-
this.injector = options.injector ?? new MetadataInjector_1.MetadataInjector();
|
|
25
|
-
this.parent = options.parent ?? new EmptyContainer_1.EmptyContainer();
|
|
26
|
-
this.tags = new Set(options.tags ?? []);
|
|
27
|
-
}
|
|
28
|
-
register(key, provider, { aliases = [] } = {}) {
|
|
29
|
-
this.validateContainer();
|
|
30
|
-
this.providers.set(key, provider);
|
|
31
|
-
this.aliases.setAliasesByKey(key, aliases);
|
|
32
|
-
return this;
|
|
33
|
-
}
|
|
34
|
-
resolve(target, { args = [], child = this, lazy } = {}) {
|
|
35
|
-
this.validateContainer();
|
|
36
|
-
if (basic_1.Is.constructor(target)) {
|
|
37
|
-
return this.injector.resolve(this, target, { args, lazy });
|
|
38
|
-
}
|
|
39
|
-
const provider = this.providers.get(target);
|
|
40
|
-
return provider?.hasAccess({ invocationScope: child, providerScope: this, args })
|
|
41
|
-
? provider.resolve(this, { args, lazy })
|
|
42
|
-
: this.parent.resolve(target, { args, child, lazy });
|
|
43
|
-
}
|
|
44
|
-
resolveByAlias(alias, { args = [], child = this, lazy, excludedKeys = [] } = {}) {
|
|
45
|
-
this.validateContainer();
|
|
46
|
-
const keys = [];
|
|
47
|
-
const deps = [];
|
|
48
|
-
for (const key of this.aliases.getKeysByAlias(alias).filter(array_1.Filter.exclude(excludedKeys))) {
|
|
49
|
-
const provider = this.findProviderByKeyOrFail(key);
|
|
50
|
-
if (!provider.hasAccess({ invocationScope: child, providerScope: this, args })) {
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
keys.push(key);
|
|
54
|
-
deps.push(provider.resolve(this, { args, lazy }));
|
|
55
|
-
}
|
|
56
|
-
const parentDeps = this.parent.resolveByAlias(alias, {
|
|
57
|
-
args,
|
|
58
|
-
child,
|
|
59
|
-
lazy,
|
|
60
|
-
excludedKeys: [...excludedKeys, ...keys],
|
|
61
|
-
});
|
|
62
|
-
return [...deps, ...parentDeps];
|
|
63
|
-
}
|
|
64
|
-
resolveOneByAlias(alias, { args = [], child = this, lazy } = {}) {
|
|
65
|
-
this.validateContainer();
|
|
66
|
-
const [key, ..._] = this.aliases.getKeysByAlias(alias);
|
|
67
|
-
const provider = key ? this.findProviderByKeyOrFail(key) : undefined;
|
|
68
|
-
return provider?.hasAccess({ invocationScope: child, providerScope: this, args })
|
|
69
|
-
? provider.resolve(this, { args, lazy })
|
|
70
|
-
: this.parent.resolveOneByAlias(alias, { args, child, lazy });
|
|
71
|
-
}
|
|
72
|
-
createScope({ tags } = {}) {
|
|
73
|
-
this.validateContainer();
|
|
74
|
-
const scope = new Container({ injector: this.injector, parent: this, tags })
|
|
75
|
-
.addOnConstructHook(...this.onConstructHookList)
|
|
76
|
-
.addOnDisposeHook(...this.onDisposeHookList);
|
|
77
|
-
for (const registration of [...this.parent.getRegistrations(), ...this.registrations]) {
|
|
78
|
-
registration.applyTo(scope);
|
|
79
|
-
}
|
|
80
|
-
this.scopes.push(scope);
|
|
81
|
-
return scope;
|
|
82
|
-
}
|
|
83
|
-
dispose() {
|
|
84
|
-
this.validateContainer();
|
|
85
|
-
this.isDisposed = true;
|
|
86
|
-
while (this.onDisposeHookList.length) {
|
|
87
|
-
const onDispose = this.onDisposeHookList.shift();
|
|
88
|
-
onDispose(this);
|
|
89
|
-
}
|
|
90
|
-
this.parent.removeScope(this);
|
|
91
|
-
this.parent = new EmptyContainer_1.EmptyContainer();
|
|
92
|
-
for (const [_, provider] of this.providers) {
|
|
93
|
-
provider.dispose();
|
|
94
|
-
}
|
|
95
|
-
this.providers.clear();
|
|
96
|
-
this.aliases.destroy();
|
|
97
|
-
this.instances = [];
|
|
98
|
-
this.registrations = [];
|
|
99
|
-
this.onConstructHookList.splice(0, this.onConstructHookList.length);
|
|
100
|
-
}
|
|
101
|
-
addRegistration(registration) {
|
|
102
|
-
this.registrations.push(registration);
|
|
103
|
-
registration.applyTo(this);
|
|
104
|
-
return this;
|
|
105
|
-
}
|
|
106
|
-
getRegistrations() {
|
|
107
|
-
return [...this.parent.getRegistrations(), ...this.registrations];
|
|
108
|
-
}
|
|
109
|
-
hasRegistration(key) {
|
|
110
|
-
return this.registrations.some((r) => r.getKeyOrFail() === key) || this.parent.hasRegistration(key);
|
|
111
|
-
}
|
|
112
|
-
addOnConstructHook(...hooks) {
|
|
113
|
-
this.onConstructHookList.push(...hooks);
|
|
114
|
-
return this;
|
|
115
|
-
}
|
|
116
|
-
addOnDisposeHook(...hooks) {
|
|
117
|
-
this.onDisposeHookList.push(...hooks);
|
|
118
|
-
return this;
|
|
119
|
-
}
|
|
120
|
-
addInstance(instance) {
|
|
121
|
-
this.instances.push(instance);
|
|
122
|
-
for (const onConstruct of this.onConstructHookList) {
|
|
123
|
-
onConstruct(instance, this);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
getScopes() {
|
|
127
|
-
return [...this.scopes];
|
|
128
|
-
}
|
|
129
|
-
hasInstance(instance) {
|
|
130
|
-
return this.instances.includes(instance);
|
|
131
|
-
}
|
|
132
|
-
getScopeByInstanceOrFail(instance) {
|
|
133
|
-
this.validateContainer();
|
|
134
|
-
if (this.hasInstance(instance)) {
|
|
135
|
-
return this;
|
|
136
|
-
}
|
|
137
|
-
return this.parent.getScopeByInstanceOrFail(instance);
|
|
138
|
-
}
|
|
139
|
-
removeScope(child) {
|
|
140
|
-
this.scopes = this.scopes.filter((s) => s !== child);
|
|
141
|
-
}
|
|
142
|
-
useModule(module) {
|
|
143
|
-
module.applyTo(this);
|
|
144
|
-
return this;
|
|
145
|
-
}
|
|
146
|
-
getParent() {
|
|
147
|
-
return this.parent;
|
|
148
|
-
}
|
|
149
|
-
getInstances(cascade = false) {
|
|
150
|
-
if (!cascade) {
|
|
151
|
-
return [...this.instances];
|
|
152
|
-
}
|
|
153
|
-
return [...this.instances, ...this.scopes.flatMap((s) => s.getInstances(true))];
|
|
154
|
-
}
|
|
155
|
-
hasTag(tag) {
|
|
156
|
-
return this.tags.has(tag);
|
|
157
|
-
}
|
|
158
|
-
addTags(...tags) {
|
|
159
|
-
for (const tag of tags) {
|
|
160
|
-
this.tags.add(tag);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
validateContainer() {
|
|
164
|
-
if (this.isDisposed) {
|
|
165
|
-
throw new ContainerDisposedError_1.ContainerDisposedError('Container is already disposed');
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
findProviderByKeyOrFail(key) {
|
|
169
|
-
if (!this.providers.has(key)) {
|
|
170
|
-
throw new DependencyNotFoundError_1.DependencyNotFoundError(`Provider ${key.toString()} does not exist`);
|
|
171
|
-
}
|
|
172
|
-
return this.providers.get(key);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
exports.Container = Container;
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EmptyContainer = void 0;
|
|
4
|
-
const MethodNotImplementedError_1 = require("../errors/MethodNotImplementedError");
|
|
5
|
-
const DependencyNotFoundError_1 = require("../errors/DependencyNotFoundError");
|
|
6
|
-
const ContainerNotFoundError_1 = require("../errors/ContainerNotFoundError");
|
|
7
|
-
class EmptyContainer {
|
|
8
|
-
get isDisposed() {
|
|
9
|
-
throw new MethodNotImplementedError_1.MethodNotImplementedError();
|
|
10
|
-
}
|
|
11
|
-
addInstance(instance) { }
|
|
12
|
-
getParent() {
|
|
13
|
-
return undefined;
|
|
14
|
-
}
|
|
15
|
-
getScopes() {
|
|
16
|
-
return [];
|
|
17
|
-
}
|
|
18
|
-
getScopeByInstanceOrFail(instance) {
|
|
19
|
-
throw new ContainerNotFoundError_1.ContainerNotFoundError('Cannot find scope for the given instance');
|
|
20
|
-
}
|
|
21
|
-
getInstances() {
|
|
22
|
-
return [];
|
|
23
|
-
}
|
|
24
|
-
hasInstance(instance) {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
createScope() {
|
|
28
|
-
throw new MethodNotImplementedError_1.MethodNotImplementedError();
|
|
29
|
-
}
|
|
30
|
-
dispose() {
|
|
31
|
-
throw new MethodNotImplementedError_1.MethodNotImplementedError();
|
|
32
|
-
}
|
|
33
|
-
register(key, value) {
|
|
34
|
-
throw new MethodNotImplementedError_1.MethodNotImplementedError();
|
|
35
|
-
}
|
|
36
|
-
hasTag(tag) {
|
|
37
|
-
throw new MethodNotImplementedError_1.MethodNotImplementedError();
|
|
38
|
-
}
|
|
39
|
-
addTags(...tags) {
|
|
40
|
-
throw new MethodNotImplementedError_1.MethodNotImplementedError();
|
|
41
|
-
}
|
|
42
|
-
getRegistrations() {
|
|
43
|
-
return [];
|
|
44
|
-
}
|
|
45
|
-
hasRegistration(key) {
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
removeScope() { }
|
|
49
|
-
useModule(module) {
|
|
50
|
-
throw new MethodNotImplementedError_1.MethodNotImplementedError();
|
|
51
|
-
}
|
|
52
|
-
addRegistration(registration) {
|
|
53
|
-
throw new MethodNotImplementedError_1.MethodNotImplementedError();
|
|
54
|
-
}
|
|
55
|
-
resolve(key, options) {
|
|
56
|
-
throw new DependencyNotFoundError_1.DependencyNotFoundError(`Cannot find ${key.toString()}`);
|
|
57
|
-
}
|
|
58
|
-
resolveByAlias(alias, options) {
|
|
59
|
-
return [];
|
|
60
|
-
}
|
|
61
|
-
resolveOneByAlias(alias, options) {
|
|
62
|
-
throw new DependencyNotFoundError_1.DependencyNotFoundError(`Cannot find alias ${alias.toString()}`);
|
|
63
|
-
}
|
|
64
|
-
addOnDisposeHook(...hooks) {
|
|
65
|
-
throw new MethodNotImplementedError_1.MethodNotImplementedError();
|
|
66
|
-
}
|
|
67
|
-
addOnConstructHook(...hooks) {
|
|
68
|
-
throw new MethodNotImplementedError_1.MethodNotImplementedError();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
exports.EmptyContainer = EmptyContainer;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CannonSingletonApplyTwiceError = void 0;
|
|
4
|
-
const ContainerError_1 = require("./ContainerError");
|
|
5
|
-
class CannonSingletonApplyTwiceError extends ContainerError_1.ContainerError {
|
|
6
|
-
name = 'CannonSingletonApplyTwiceError';
|
|
7
|
-
constructor(message) {
|
|
8
|
-
super(message);
|
|
9
|
-
Object.setPrototypeOf(this, CannonSingletonApplyTwiceError.prototype);
|
|
10
|
-
}
|
|
11
|
-
static assert(isTrue, failMessage) {
|
|
12
|
-
if (!isTrue) {
|
|
13
|
-
throw new CannonSingletonApplyTwiceError(failMessage);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
exports.CannonSingletonApplyTwiceError = CannonSingletonApplyTwiceError;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ContainerDisposedError = void 0;
|
|
4
|
-
const ContainerError_1 = require("./ContainerError");
|
|
5
|
-
class ContainerDisposedError extends ContainerError_1.ContainerError {
|
|
6
|
-
name = 'ContainerDisposedError';
|
|
7
|
-
constructor(message) {
|
|
8
|
-
super(message);
|
|
9
|
-
Object.setPrototypeOf(this, ContainerDisposedError.prototype);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
exports.ContainerDisposedError = ContainerDisposedError;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ContainerError = void 0;
|
|
4
|
-
class ContainerError extends Error {
|
|
5
|
-
name = 'ContainerError';
|
|
6
|
-
constructor(message) {
|
|
7
|
-
super(message);
|
|
8
|
-
Object.setPrototypeOf(this, ContainerError.prototype);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
exports.ContainerError = ContainerError;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ContainerNotFoundError = void 0;
|
|
4
|
-
const ContainerError_1 = require("./ContainerError");
|
|
5
|
-
class ContainerNotFoundError extends ContainerError_1.ContainerError {
|
|
6
|
-
name = 'ContainerNotFoundError';
|
|
7
|
-
constructor(message) {
|
|
8
|
-
super(message);
|
|
9
|
-
Object.setPrototypeOf(this, ContainerNotFoundError.prototype);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
exports.ContainerNotFoundError = ContainerNotFoundError;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DependencyMissingKeyError = void 0;
|
|
4
|
-
const ContainerError_1 = require("./ContainerError");
|
|
5
|
-
class DependencyMissingKeyError extends ContainerError_1.ContainerError {
|
|
6
|
-
name = 'DependencyMissingKeyError';
|
|
7
|
-
constructor(message) {
|
|
8
|
-
super(message);
|
|
9
|
-
Object.setPrototypeOf(this, DependencyMissingKeyError.prototype);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
exports.DependencyMissingKeyError = DependencyMissingKeyError;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DependencyNotFoundError = void 0;
|
|
4
|
-
const ContainerError_1 = require("./ContainerError");
|
|
5
|
-
class DependencyNotFoundError extends ContainerError_1.ContainerError {
|
|
6
|
-
name = 'DependencyNotFoundError';
|
|
7
|
-
constructor(message) {
|
|
8
|
-
super(message);
|
|
9
|
-
Object.setPrototypeOf(this, DependencyNotFoundError.prototype);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
exports.DependencyNotFoundError = DependencyNotFoundError;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MethodNotImplementedError = void 0;
|
|
4
|
-
const ContainerError_1 = require("./ContainerError");
|
|
5
|
-
class MethodNotImplementedError extends ContainerError_1.ContainerError {
|
|
6
|
-
name = 'MethodNotImplementedError';
|
|
7
|
-
constructor(message) {
|
|
8
|
-
super(message);
|
|
9
|
-
Object.setPrototypeOf(this, MethodNotImplementedError.prototype);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
exports.MethodNotImplementedError = MethodNotImplementedError;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ProviderDisposedError = void 0;
|
|
4
|
-
const ContainerError_1 = require("./ContainerError");
|
|
5
|
-
class ProviderDisposedError extends ContainerError_1.ContainerError {
|
|
6
|
-
name = 'ProviderDisposedError';
|
|
7
|
-
static assert(isTrue, failMessage) {
|
|
8
|
-
if (!isTrue) {
|
|
9
|
-
throw new ProviderDisposedError(failMessage);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
constructor(message) {
|
|
13
|
-
super(message);
|
|
14
|
-
Object.setPrototypeOf(this, ProviderDisposedError.prototype);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
exports.ProviderDisposedError = ProviderDisposedError;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.UnexpectedHookResultError = void 0;
|
|
4
|
-
const ContainerError_1 = require("./ContainerError");
|
|
5
|
-
class UnexpectedHookResultError extends ContainerError_1.ContainerError {
|
|
6
|
-
name = 'UnexpectedHookResultError';
|
|
7
|
-
constructor(message) {
|
|
8
|
-
super(message);
|
|
9
|
-
Object.setPrototypeOf(this, UnexpectedHookResultError.prototype);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
exports.UnexpectedHookResultError = UnexpectedHookResultError;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.UnsupportedTokenTypeError = void 0;
|
|
4
|
-
const ContainerError_1 = require("./ContainerError");
|
|
5
|
-
class UnsupportedTokenTypeError extends ContainerError_1.ContainerError {
|
|
6
|
-
name = 'UnsupportedTokenTypeError';
|
|
7
|
-
constructor(message) {
|
|
8
|
-
super(message);
|
|
9
|
-
Object.setPrototypeOf(this, UnsupportedTokenTypeError.prototype);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
exports.UnsupportedTokenTypeError = UnsupportedTokenTypeError;
|