@mudah-cli/container 0.8.0 → 0.9.2
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 +21 -0
- package/README.md +40 -0
- package/dist/container.d.ts +73 -9
- package/dist/container.js +342 -35
- package/dist/container.js.map +1 -1
- package/dist/decorators.d.ts +25 -0
- package/dist/decorators.js +48 -0
- package/dist/decorators.js.map +1 -0
- package/dist/exceptions.d.ts +1 -1
- package/dist/exceptions.js +4 -2
- package/dist/exceptions.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +33 -0
- package/dist/providers.js +92 -0
- package/dist/providers.js.map +1 -0
- package/dist/types.d.ts +29 -0
- package/package.json +15 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mudah Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# @mudah-cli/container
|
|
2
|
+
|
|
3
|
+
High-performance IoC service container with constructor auto-injection.
|
|
4
|
+
|
|
5
|
+
Part of [Mudah](https://github.com/thesimonharms/mudah) — an ergonomic, animation-rich CLI
|
|
6
|
+
framework. This package has **no Mudah dependencies**, so you can use it in any TypeScript
|
|
7
|
+
project.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @mudah-cli/container
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { Container } from '@mudah-cli/container';
|
|
19
|
+
|
|
20
|
+
class Database {
|
|
21
|
+
connect(): void {
|
|
22
|
+
// …
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const container = new Container();
|
|
27
|
+
container.singleton(Database, Database); // or .bind(...) for a fresh instance each time
|
|
28
|
+
|
|
29
|
+
const db = container.make(Database);
|
|
30
|
+
db.connect();
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Bindings can be singletons, factories (sync or async), values, tagged, and contextual.
|
|
34
|
+
Decorate classes with `@inject` / `@singleton` for auto-injection, or resolve a whole provider
|
|
35
|
+
module with `loadProvidersFrom`.
|
|
36
|
+
|
|
37
|
+
## Links
|
|
38
|
+
|
|
39
|
+
- [Full documentation](https://github.com/thesimonharms/mudah#readme)
|
|
40
|
+
- [License: MIT](LICENSE)
|
package/dist/container.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type ProviderDef } from './providers.js';
|
|
2
|
+
import type { Abstract, AsyncFactory, BindingQuery, Constructor, ContainerSnapshot, Factory } from './types.js';
|
|
3
|
+
export interface ContextualBinder<TContext extends object> {
|
|
4
|
+
use<TDep>(abstract: Abstract<TDep>, factory: Factory<TDep> | Constructor<TDep>): Container;
|
|
5
|
+
}
|
|
2
6
|
/**
|
|
3
7
|
* True for class declarations and function declarations (values with their
|
|
4
8
|
* own `prototype.constructor`), false for arrow functions and plain objects.
|
|
@@ -12,37 +16,97 @@ export declare function isClassLike(value: unknown): value is Constructor;
|
|
|
12
16
|
* - `instance` registers a pre-built value.
|
|
13
17
|
* - `when` registers contextual bindings: an alternative factory that applies
|
|
14
18
|
* only when the dependency is injected into a specific context.
|
|
15
|
-
* - Classes declaring `static dependencies` get constructor auto-injection.
|
|
19
|
+
* - Classes declaring `static dependencies` (or `@inject(...)`) get constructor auto-injection.
|
|
16
20
|
*/
|
|
17
21
|
export declare class Container {
|
|
18
|
-
private readonly
|
|
19
|
-
private readonly
|
|
22
|
+
private readonly _bindings;
|
|
23
|
+
private readonly _instances;
|
|
20
24
|
private readonly contextual;
|
|
25
|
+
private readonly _tagIndex;
|
|
26
|
+
private readonly _scoped;
|
|
27
|
+
private readonly _scopeStack;
|
|
21
28
|
private readonly resolvingStack;
|
|
29
|
+
private readonly _groups;
|
|
22
30
|
/** Register a binding. A fresh instance is produced on every `make`. */
|
|
23
|
-
bind<T>(abstract: Abstract<T>, factory: Factory<T> | Constructor<T>): this;
|
|
31
|
+
bind<T>(abstract: Abstract<T>, factory: Factory<T> | AsyncFactory<T> | Constructor<T>): this;
|
|
24
32
|
/** Register a shared binding. The instance is resolved once, then cached. */
|
|
25
|
-
singleton<T>(abstract: Abstract<T>, factory: Factory<T> | Constructor<T>): this;
|
|
33
|
+
singleton<T>(abstract: Abstract<T>, factory: Factory<T> | AsyncFactory<T> | Constructor<T>): this;
|
|
26
34
|
/** Register a pre-built value under an abstract. */
|
|
27
35
|
instance<T>(abstract: Abstract<T>, value: T): this;
|
|
36
|
+
/**
|
|
37
|
+
* Drop a scoped binding when a plain binding replaces it. `scoped()` already
|
|
38
|
+
* clears `_bindings`; without the mirror image, a later `bind()`/`singleton()`
|
|
39
|
+
* would be shadowed forever (resolution checks `_scoped` first).
|
|
40
|
+
*/
|
|
41
|
+
private releaseScoped;
|
|
28
42
|
/** Make `abstract` an alias of `target` (resolves to the same instance). */
|
|
29
43
|
alias(abstract: Abstract, target: Abstract): this;
|
|
30
44
|
/**
|
|
31
|
-
* Contextual binding
|
|
32
|
-
*
|
|
45
|
+
* Contextual binding. Two forms:
|
|
46
|
+
* - `when(Context, abstract, factory)` — existing 3-arg form
|
|
47
|
+
* - `when(Context).use(abstract, factory)` — fluent ROADMAP form
|
|
33
48
|
*/
|
|
49
|
+
when<TContext extends object>(context: Constructor<TContext>): ContextualBinder<TContext>;
|
|
34
50
|
when<TContext extends object, TDep>(context: Constructor<TContext>, abstract: Abstract<TDep>, factory: Factory<TDep> | Constructor<TDep>): this;
|
|
35
|
-
|
|
51
|
+
private setContextual;
|
|
52
|
+
/** Whether the abstract is bound (explicitly or scoped), or is a constructible class. */
|
|
36
53
|
has(abstract: Abstract): boolean;
|
|
37
54
|
/** Resolve an abstract to an instance. */
|
|
38
55
|
make<T>(abstract: Abstract<T>): T;
|
|
56
|
+
/**
|
|
57
|
+
* Resolve an abstract, awaiting async factories / promises in the graph.
|
|
58
|
+
*/
|
|
59
|
+
makeAsync<T>(abstract: Abstract<T>): Promise<T>;
|
|
39
60
|
/** Alias for {@link make}. */
|
|
40
61
|
get<T>(abstract: Abstract<T>): T;
|
|
41
62
|
/** Forget all cached singleton instances (bindings are kept). */
|
|
42
63
|
flush(): void;
|
|
64
|
+
/**
|
|
65
|
+
* Call `dispose()` (or `close()`) on every cached instance, then flush.
|
|
66
|
+
* Used on application shutdown.
|
|
67
|
+
*/
|
|
68
|
+
dispose(): Promise<void>;
|
|
69
|
+
/** Tags a binding so it can be resolved as a group via {@link tagged}. */
|
|
70
|
+
tag(abstract: Abstract, ...tags: Array<string | symbol>): this;
|
|
71
|
+
/** Resolve every binding tagged with `tag`, in registration order. */
|
|
72
|
+
tagged<T = unknown>(tag: string | symbol): T[];
|
|
73
|
+
/**
|
|
74
|
+
* Register a binding whose instance is cached for the duration of a scope
|
|
75
|
+
* started by {@link runInScope}. Outside any scope it behaves as transient.
|
|
76
|
+
* Pass `group` to only cache inside `runInScope(group, fn)`.
|
|
77
|
+
*/
|
|
78
|
+
scoped<T>(abstract: Abstract<T>, factory: Factory<T> | Constructor<T>, group?: string): this;
|
|
79
|
+
/** Run `fn` within a fresh scope; scoped bindings cache per-scope. */
|
|
80
|
+
runInScope<T>(fn: (container: Container) => T): T;
|
|
81
|
+
runInScope<T>(group: string, fn: (container: Container) => T): T;
|
|
82
|
+
/** Registered abstracts, optionally filtered by tag or scoped group. */
|
|
83
|
+
bindings(query?: BindingQuery): Abstract[];
|
|
84
|
+
/** Abstracts whose shared instance has been resolved and cached. */
|
|
85
|
+
instances(query?: BindingQuery): Abstract[];
|
|
86
|
+
/** True only if `abstract` has an explicit binding registered (not auto-injection). */
|
|
87
|
+
isBound(abstract: Abstract): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Capture bindings and cached instances so tests can {@link rollback}.
|
|
90
|
+
*/
|
|
91
|
+
snapshot(): ContainerSnapshot;
|
|
92
|
+
/** Restore a {@link snapshot}. Bindings registered after the snapshot are dropped. */
|
|
93
|
+
rollback(snapshot: ContainerSnapshot): void;
|
|
94
|
+
/** Bind `@singleton` / `@inject` decorated classes (or a provider array). */
|
|
95
|
+
registerDecorated(...ctors: Constructor[]): this;
|
|
96
|
+
/** Bind a `providers` array. */
|
|
97
|
+
loadProviders(providers: readonly ProviderDef[]): this;
|
|
98
|
+
private filterAbstracts;
|
|
99
|
+
private currentScope;
|
|
100
|
+
private resolveSync;
|
|
101
|
+
private resolveAsync;
|
|
43
102
|
private sharedInstance;
|
|
44
103
|
private materialize;
|
|
104
|
+
private materializeAsync;
|
|
45
105
|
private instantiate;
|
|
106
|
+
private instantiateAsync;
|
|
46
107
|
private resolveDependency;
|
|
108
|
+
private resolveDependencyAsync;
|
|
47
109
|
private withResolving;
|
|
110
|
+
private withResolvingAsync;
|
|
111
|
+
private assertSync;
|
|
48
112
|
}
|
package/dist/container.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { decoratedSingletonAbstract } from './decorators.js';
|
|
1
2
|
import { BindingResolutionException, CircularDependencyException } from './exceptions.js';
|
|
3
|
+
import { loadProviders } from './providers.js';
|
|
2
4
|
/**
|
|
3
5
|
* True for class declarations and function declarations (values with their
|
|
4
6
|
* own `prototype.constructor`), false for arrow functions and plain objects.
|
|
@@ -8,7 +10,7 @@ export function isClassLike(value) {
|
|
|
8
10
|
if (typeof value !== 'function')
|
|
9
11
|
return false;
|
|
10
12
|
const proto = value.prototype;
|
|
11
|
-
return proto !== null && typeof proto === 'object' && Object.
|
|
13
|
+
return proto !== null && typeof proto === 'object' && Object.hasOwn(proto, 'constructor');
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
14
16
|
* High-performance IoC service container.
|
|
@@ -17,41 +19,61 @@ export function isClassLike(value) {
|
|
|
17
19
|
* - `instance` registers a pre-built value.
|
|
18
20
|
* - `when` registers contextual bindings: an alternative factory that applies
|
|
19
21
|
* only when the dependency is injected into a specific context.
|
|
20
|
-
* - Classes declaring `static dependencies` get constructor auto-injection.
|
|
22
|
+
* - Classes declaring `static dependencies` (or `@inject(...)`) get constructor auto-injection.
|
|
21
23
|
*/
|
|
22
24
|
export class Container {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
_bindings = new Map();
|
|
26
|
+
_instances = new Map();
|
|
25
27
|
contextual = new Map();
|
|
28
|
+
_tagIndex = new Map();
|
|
29
|
+
_scoped = new Map();
|
|
30
|
+
_scopeStack = [];
|
|
26
31
|
resolvingStack = [];
|
|
32
|
+
_groups = new Map();
|
|
27
33
|
/** Register a binding. A fresh instance is produced on every `make`. */
|
|
28
34
|
bind(abstract, factory) {
|
|
29
|
-
this.
|
|
30
|
-
this.
|
|
35
|
+
this._bindings.set(abstract, { factory, shared: false });
|
|
36
|
+
this._instances.delete(abstract);
|
|
37
|
+
this.releaseScoped(abstract);
|
|
31
38
|
return this;
|
|
32
39
|
}
|
|
33
40
|
/** Register a shared binding. The instance is resolved once, then cached. */
|
|
34
41
|
singleton(abstract, factory) {
|
|
35
|
-
this.
|
|
36
|
-
this.
|
|
42
|
+
this._bindings.set(abstract, { factory, shared: true });
|
|
43
|
+
this._instances.delete(abstract);
|
|
44
|
+
this.releaseScoped(abstract);
|
|
37
45
|
return this;
|
|
38
46
|
}
|
|
39
47
|
/** Register a pre-built value under an abstract. */
|
|
40
48
|
instance(abstract, value) {
|
|
41
|
-
this.
|
|
42
|
-
this.
|
|
49
|
+
this._bindings.set(abstract, { factory: () => value, shared: true });
|
|
50
|
+
this._instances.set(abstract, value);
|
|
51
|
+
this.releaseScoped(abstract);
|
|
43
52
|
return this;
|
|
44
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Drop a scoped binding when a plain binding replaces it. `scoped()` already
|
|
56
|
+
* clears `_bindings`; without the mirror image, a later `bind()`/`singleton()`
|
|
57
|
+
* would be shadowed forever (resolution checks `_scoped` first).
|
|
58
|
+
*/
|
|
59
|
+
releaseScoped(abstract) {
|
|
60
|
+
this._scoped.delete(abstract);
|
|
61
|
+
this._groups.delete(abstract);
|
|
62
|
+
}
|
|
45
63
|
/** Make `abstract` an alias of `target` (resolves to the same instance). */
|
|
46
64
|
alias(abstract, target) {
|
|
47
65
|
this.bind(abstract, (container) => container.make(target));
|
|
48
66
|
return this;
|
|
49
67
|
}
|
|
50
|
-
/**
|
|
51
|
-
* Contextual binding: when `abstract` is injected into `context`, resolve it
|
|
52
|
-
* with `factory` instead of its global binding.
|
|
53
|
-
*/
|
|
54
68
|
when(context, abstract, factory) {
|
|
69
|
+
if (abstract === undefined || factory === undefined) {
|
|
70
|
+
return {
|
|
71
|
+
use: (innerAbstract, innerFactory) => this.setContextual(context, innerAbstract, innerFactory),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return this.setContextual(context, abstract, factory);
|
|
75
|
+
}
|
|
76
|
+
setContextual(context, abstract, factory) {
|
|
55
77
|
let map = this.contextual.get(context);
|
|
56
78
|
if (!map) {
|
|
57
79
|
map = new Map();
|
|
@@ -60,67 +82,325 @@ export class Container {
|
|
|
60
82
|
map.set(abstract, factory);
|
|
61
83
|
return this;
|
|
62
84
|
}
|
|
63
|
-
/** Whether the abstract is bound, or is a constructible class. */
|
|
85
|
+
/** Whether the abstract is bound (explicitly or scoped), or is a constructible class. */
|
|
64
86
|
has(abstract) {
|
|
65
|
-
return this.
|
|
87
|
+
return this._bindings.has(abstract) || this._scoped.has(abstract) || isClassLike(abstract);
|
|
66
88
|
}
|
|
67
89
|
/** Resolve an abstract to an instance. */
|
|
68
90
|
make(abstract) {
|
|
69
|
-
|
|
70
|
-
|
|
91
|
+
const value = this.resolveSync(abstract);
|
|
92
|
+
if (isThenable(value)) {
|
|
93
|
+
throw new BindingResolutionException(abstract, `factory for "${describeAbstract(abstract)}" returned a Promise; use makeAsync()`);
|
|
94
|
+
}
|
|
95
|
+
return value;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Resolve an abstract, awaiting async factories / promises in the graph.
|
|
99
|
+
*/
|
|
100
|
+
async makeAsync(abstract) {
|
|
101
|
+
return (await this.resolveAsync(abstract));
|
|
102
|
+
}
|
|
103
|
+
/** Alias for {@link make}. */
|
|
104
|
+
get(abstract) {
|
|
105
|
+
return this.make(abstract);
|
|
106
|
+
}
|
|
107
|
+
/** Forget all cached singleton instances (bindings are kept). */
|
|
108
|
+
flush() {
|
|
109
|
+
this._instances.clear();
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Call `dispose()` (or `close()`) on every cached instance, then flush.
|
|
113
|
+
* Used on application shutdown.
|
|
114
|
+
*/
|
|
115
|
+
async dispose() {
|
|
116
|
+
const seen = new Set();
|
|
117
|
+
// `this` is skipped: a container (or an Application extending one) can be
|
|
118
|
+
// bound as its own instance, and calling its dispose() here would recurse
|
|
119
|
+
// without bound.
|
|
120
|
+
seen.add(this);
|
|
121
|
+
const victims = [
|
|
122
|
+
...this._instances.values(),
|
|
123
|
+
...this._scopeStack.flatMap((scope) => [...scope.values.values()]),
|
|
124
|
+
];
|
|
125
|
+
for (const value of victims) {
|
|
126
|
+
if (value === null || value === undefined || seen.has(value))
|
|
127
|
+
continue;
|
|
128
|
+
seen.add(value);
|
|
129
|
+
const disposable = value;
|
|
130
|
+
if (typeof disposable.dispose === 'function') {
|
|
131
|
+
await disposable.dispose();
|
|
132
|
+
}
|
|
133
|
+
else if (typeof disposable.close === 'function') {
|
|
134
|
+
await disposable.close();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
this._instances.clear();
|
|
138
|
+
this._scopeStack.length = 0;
|
|
139
|
+
}
|
|
140
|
+
/** Tags a binding so it can be resolved as a group via {@link tagged}. */
|
|
141
|
+
tag(abstract, ...tags) {
|
|
142
|
+
let set = this._tagIndex.get(abstract);
|
|
143
|
+
if (!set) {
|
|
144
|
+
set = new Set();
|
|
145
|
+
this._tagIndex.set(abstract, set);
|
|
146
|
+
}
|
|
147
|
+
for (const tag of tags)
|
|
148
|
+
set.add(tag);
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
/** Resolve every binding tagged with `tag`, in registration order. */
|
|
152
|
+
tagged(tag) {
|
|
153
|
+
const result = [];
|
|
154
|
+
for (const [abstract, tags] of this._tagIndex) {
|
|
155
|
+
if (tags.has(tag))
|
|
156
|
+
result.push(this.make(abstract));
|
|
157
|
+
}
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Register a binding whose instance is cached for the duration of a scope
|
|
162
|
+
* started by {@link runInScope}. Outside any scope it behaves as transient.
|
|
163
|
+
* Pass `group` to only cache inside `runInScope(group, fn)`.
|
|
164
|
+
*/
|
|
165
|
+
scoped(abstract, factory, group) {
|
|
166
|
+
this._scoped.set(abstract, { factory: factory, group });
|
|
167
|
+
this._instances.delete(abstract);
|
|
168
|
+
this._bindings.delete(abstract);
|
|
169
|
+
if (group)
|
|
170
|
+
this._groups.set(abstract, group);
|
|
171
|
+
else
|
|
172
|
+
this._groups.delete(abstract);
|
|
173
|
+
return this;
|
|
174
|
+
}
|
|
175
|
+
runInScope(groupOrFn, maybeFn) {
|
|
176
|
+
const group = typeof groupOrFn === 'string' ? groupOrFn : undefined;
|
|
177
|
+
const fn = typeof groupOrFn === 'function' ? groupOrFn : maybeFn;
|
|
178
|
+
if (!fn)
|
|
179
|
+
throw new TypeError('[container] runInScope requires a callback');
|
|
180
|
+
const scope = { group, values: new Map() };
|
|
181
|
+
this._scopeStack.push(scope);
|
|
182
|
+
try {
|
|
183
|
+
return fn(this);
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
this._scopeStack.pop();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/** Registered abstracts, optionally filtered by tag or scoped group. */
|
|
190
|
+
bindings(query) {
|
|
191
|
+
const keys = [...this._bindings.keys(), ...this._scoped.keys()].filter((key, index, all) => all.indexOf(key) === index);
|
|
192
|
+
return this.filterAbstracts(keys, query);
|
|
193
|
+
}
|
|
194
|
+
/** Abstracts whose shared instance has been resolved and cached. */
|
|
195
|
+
instances(query) {
|
|
196
|
+
return this.filterAbstracts([...this._instances.keys()], query);
|
|
197
|
+
}
|
|
198
|
+
/** True only if `abstract` has an explicit binding registered (not auto-injection). */
|
|
199
|
+
isBound(abstract) {
|
|
200
|
+
return this._bindings.has(abstract) || this._scoped.has(abstract);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Capture bindings and cached instances so tests can {@link rollback}.
|
|
204
|
+
*/
|
|
205
|
+
snapshot() {
|
|
206
|
+
const contextual = new Map();
|
|
207
|
+
for (const [ctor, map] of this.contextual)
|
|
208
|
+
contextual.set(ctor, new Map(map));
|
|
209
|
+
const tags = new Map();
|
|
210
|
+
for (const [abstract, set] of this._tagIndex)
|
|
211
|
+
tags.set(abstract, new Set(set));
|
|
212
|
+
const scoped = new Map();
|
|
213
|
+
for (const [abstract, binding] of this._scoped)
|
|
214
|
+
scoped.set(abstract, { ...binding });
|
|
215
|
+
return {
|
|
216
|
+
bindings: new Map(this._bindings),
|
|
217
|
+
instances: new Map(this._instances),
|
|
218
|
+
contextual,
|
|
219
|
+
tags,
|
|
220
|
+
scoped,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/** Restore a {@link snapshot}. Bindings registered after the snapshot are dropped. */
|
|
224
|
+
rollback(snapshot) {
|
|
225
|
+
this._bindings.clear();
|
|
226
|
+
for (const [abstract, binding] of snapshot.bindings)
|
|
227
|
+
this._bindings.set(abstract, { ...binding });
|
|
228
|
+
this._instances.clear();
|
|
229
|
+
for (const [abstract, value] of snapshot.instances)
|
|
230
|
+
this._instances.set(abstract, value);
|
|
231
|
+
this.contextual.clear();
|
|
232
|
+
for (const [ctor, map] of snapshot.contextual)
|
|
233
|
+
this.contextual.set(ctor, new Map(map));
|
|
234
|
+
this._tagIndex.clear();
|
|
235
|
+
for (const [abstract, set] of snapshot.tags)
|
|
236
|
+
this._tagIndex.set(abstract, new Set(set));
|
|
237
|
+
this._scoped.clear();
|
|
238
|
+
this._groups.clear();
|
|
239
|
+
for (const [abstract, binding] of snapshot.scoped) {
|
|
240
|
+
this._scoped.set(abstract, { ...binding });
|
|
241
|
+
if (binding.group)
|
|
242
|
+
this._groups.set(abstract, binding.group);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/** Bind `@singleton` / `@inject` decorated classes (or a provider array). */
|
|
246
|
+
registerDecorated(...ctors) {
|
|
247
|
+
for (const ctor of ctors) {
|
|
248
|
+
const abstract = decoratedSingletonAbstract(ctor) ?? ctor;
|
|
249
|
+
if (decoratedSingletonAbstract(ctor) !== undefined)
|
|
250
|
+
this.singleton(abstract, ctor);
|
|
251
|
+
else
|
|
252
|
+
this.bind(abstract, ctor);
|
|
253
|
+
}
|
|
254
|
+
return this;
|
|
255
|
+
}
|
|
256
|
+
/** Bind a `providers` array. */
|
|
257
|
+
loadProviders(providers) {
|
|
258
|
+
loadProviders(this, providers);
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
261
|
+
filterAbstracts(keys, query) {
|
|
262
|
+
if (!query)
|
|
263
|
+
return keys;
|
|
264
|
+
return keys.filter((abstract) => {
|
|
265
|
+
if (query.tag !== undefined) {
|
|
266
|
+
const tags = this._tagIndex.get(abstract);
|
|
267
|
+
if (!tags?.has(query.tag))
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
if (query.group !== undefined && this._groups.get(abstract) !== query.group)
|
|
271
|
+
return false;
|
|
272
|
+
return true;
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
currentScope(group) {
|
|
276
|
+
for (let i = this._scopeStack.length - 1; i >= 0; i--) {
|
|
277
|
+
const frame = this._scopeStack[i];
|
|
278
|
+
if (!frame)
|
|
279
|
+
continue;
|
|
280
|
+
if (group === undefined)
|
|
281
|
+
return frame.values;
|
|
282
|
+
if (frame.group === group)
|
|
283
|
+
return frame.values;
|
|
284
|
+
}
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
resolveSync(abstract) {
|
|
288
|
+
if (this._instances.has(abstract)) {
|
|
289
|
+
return this._instances.get(abstract);
|
|
71
290
|
}
|
|
72
|
-
const
|
|
291
|
+
const scoped = this._scoped.get(abstract);
|
|
292
|
+
if (scoped) {
|
|
293
|
+
const scope = this.currentScope(scoped.group);
|
|
294
|
+
if (scope) {
|
|
295
|
+
if (scope.has(abstract))
|
|
296
|
+
return scope.get(abstract);
|
|
297
|
+
return this.withResolving(abstract, () => {
|
|
298
|
+
const value = this.materialize(scoped.factory, undefined);
|
|
299
|
+
this.assertSync(abstract, value);
|
|
300
|
+
scope.set(abstract, value);
|
|
301
|
+
return value;
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
return this.withResolving(abstract, () => this.materialize(scoped.factory, undefined));
|
|
305
|
+
}
|
|
306
|
+
const binding = this._bindings.get(abstract);
|
|
73
307
|
if (binding) {
|
|
74
308
|
return binding.shared
|
|
75
|
-
? this.sharedInstance(abstract, () => this.materialize(
|
|
76
|
-
: this.withResolving(abstract, () => this.materialize(
|
|
309
|
+
? this.sharedInstance(abstract, () => this.materialize(binding.factory, undefined))
|
|
310
|
+
: this.withResolving(abstract, () => this.materialize(binding.factory, undefined));
|
|
77
311
|
}
|
|
78
312
|
if (isClassLike(abstract)) {
|
|
79
313
|
return this.withResolving(abstract, () => this.instantiate(abstract, undefined));
|
|
80
314
|
}
|
|
81
315
|
throw new BindingResolutionException(abstract);
|
|
82
316
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
317
|
+
async resolveAsync(abstract) {
|
|
318
|
+
if (this._instances.has(abstract)) {
|
|
319
|
+
return this._instances.get(abstract);
|
|
320
|
+
}
|
|
321
|
+
const scoped = this._scoped.get(abstract);
|
|
322
|
+
if (scoped) {
|
|
323
|
+
const scope = this.currentScope(scoped.group);
|
|
324
|
+
if (scope?.has(abstract))
|
|
325
|
+
return scope.get(abstract);
|
|
326
|
+
return this.withResolvingAsync(abstract, async () => {
|
|
327
|
+
const value = await this.materializeAsync(scoped.factory, undefined);
|
|
328
|
+
if (scope)
|
|
329
|
+
scope.set(abstract, value);
|
|
330
|
+
return value;
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
const binding = this._bindings.get(abstract);
|
|
334
|
+
if (binding) {
|
|
335
|
+
if (binding.shared && this._instances.has(abstract))
|
|
336
|
+
return this._instances.get(abstract);
|
|
337
|
+
return this.withResolvingAsync(abstract, async () => {
|
|
338
|
+
const value = await this.materializeAsync(binding.factory, undefined);
|
|
339
|
+
if (binding.shared)
|
|
340
|
+
this._instances.set(abstract, value);
|
|
341
|
+
return value;
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
if (isClassLike(abstract)) {
|
|
345
|
+
return this.withResolvingAsync(abstract, () => this.instantiateAsync(abstract, undefined));
|
|
346
|
+
}
|
|
347
|
+
throw new BindingResolutionException(abstract);
|
|
90
348
|
}
|
|
91
349
|
sharedInstance(abstract, producer) {
|
|
92
|
-
if (this.
|
|
93
|
-
return this.
|
|
350
|
+
if (this._instances.has(abstract)) {
|
|
351
|
+
return this._instances.get(abstract);
|
|
94
352
|
}
|
|
95
353
|
return this.withResolving(abstract, () => {
|
|
96
354
|
const value = producer();
|
|
97
|
-
this.
|
|
355
|
+
this.assertSync(abstract, value);
|
|
356
|
+
this._instances.set(abstract, value);
|
|
98
357
|
return value;
|
|
99
358
|
});
|
|
100
359
|
}
|
|
101
|
-
materialize(
|
|
360
|
+
materialize(factory, context) {
|
|
102
361
|
if (isClassLike(factory)) {
|
|
103
362
|
return this.instantiate(factory, context);
|
|
104
363
|
}
|
|
105
364
|
return factory(this);
|
|
106
365
|
}
|
|
366
|
+
async materializeAsync(factory, context) {
|
|
367
|
+
if (isClassLike(factory)) {
|
|
368
|
+
return this.instantiateAsync(factory, context);
|
|
369
|
+
}
|
|
370
|
+
return factory(this);
|
|
371
|
+
}
|
|
107
372
|
instantiate(ctor, context) {
|
|
108
|
-
// Contextual bindings resolve against the class currently being
|
|
109
|
-
// constructed (the immediate context), matching standard merge semantics.
|
|
110
373
|
const immediate = context ?? ctor;
|
|
111
374
|
const deps = ctor.dependencies ?? [];
|
|
112
375
|
const args = deps.map((dep) => this.resolveDependency(dep, immediate));
|
|
113
376
|
return new ctor(...args);
|
|
114
377
|
}
|
|
378
|
+
async instantiateAsync(ctor, context) {
|
|
379
|
+
const immediate = context ?? ctor;
|
|
380
|
+
const deps = ctor.dependencies ?? [];
|
|
381
|
+
const args = [];
|
|
382
|
+
for (const dep of deps)
|
|
383
|
+
args.push(await this.resolveDependencyAsync(dep, immediate));
|
|
384
|
+
return new ctor(...args);
|
|
385
|
+
}
|
|
115
386
|
resolveDependency(dep, context) {
|
|
116
387
|
if (context) {
|
|
117
388
|
const override = this.contextual.get(context)?.get(dep);
|
|
118
389
|
if (override !== undefined) {
|
|
119
|
-
return this.withResolving(dep, () => this.materialize(
|
|
390
|
+
return this.withResolving(dep, () => this.materialize(override, context));
|
|
120
391
|
}
|
|
121
392
|
}
|
|
122
393
|
return this.make(dep);
|
|
123
394
|
}
|
|
395
|
+
async resolveDependencyAsync(dep, context) {
|
|
396
|
+
if (context) {
|
|
397
|
+
const override = this.contextual.get(context)?.get(dep);
|
|
398
|
+
if (override !== undefined) {
|
|
399
|
+
return this.withResolvingAsync(dep, () => this.materializeAsync(override, context));
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return this.makeAsync(dep);
|
|
403
|
+
}
|
|
124
404
|
withResolving(abstract, fn) {
|
|
125
405
|
if (this.resolvingStack.includes(abstract)) {
|
|
126
406
|
throw new CircularDependencyException(abstract, this.resolvingStack);
|
|
@@ -133,5 +413,32 @@ export class Container {
|
|
|
133
413
|
this.resolvingStack.pop();
|
|
134
414
|
}
|
|
135
415
|
}
|
|
416
|
+
async withResolvingAsync(abstract, fn) {
|
|
417
|
+
if (this.resolvingStack.includes(abstract)) {
|
|
418
|
+
throw new CircularDependencyException(abstract, this.resolvingStack);
|
|
419
|
+
}
|
|
420
|
+
this.resolvingStack.push(abstract);
|
|
421
|
+
try {
|
|
422
|
+
return await fn();
|
|
423
|
+
}
|
|
424
|
+
finally {
|
|
425
|
+
this.resolvingStack.pop();
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
assertSync(abstract, value) {
|
|
429
|
+
if (isThenable(value)) {
|
|
430
|
+
throw new BindingResolutionException(abstract, `factory for "${describeAbstract(abstract)}" returned a Promise; use makeAsync()`);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
function isThenable(value) {
|
|
435
|
+
return (typeof value === 'object' && value !== null && typeof value.then === 'function');
|
|
436
|
+
}
|
|
437
|
+
function describeAbstract(abstract) {
|
|
438
|
+
if (typeof abstract === 'string')
|
|
439
|
+
return abstract;
|
|
440
|
+
if (typeof abstract === 'symbol')
|
|
441
|
+
return abstract.description ?? String(abstract);
|
|
442
|
+
return abstract.name || '<anonymous class>';
|
|
136
443
|
}
|
|
137
444
|
//# sourceMappingURL=container.js.map
|
package/dist/container.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Abstract, Constructor } from './types.js';
|
|
2
|
+
declare const SINGLETON_KEY: unique symbol;
|
|
3
|
+
/**
|
|
4
|
+
* IsolatedModules-safe class decorator: writes `static dependencies` so the
|
|
5
|
+
* container can auto-inject without `emitDecoratorMetadata`.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* @inject('logger', 'name')
|
|
9
|
+
* class Service {
|
|
10
|
+
* constructor(public logger: Logger, public name: string) {}
|
|
11
|
+
* }
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function inject(...deps: Abstract[]): <T extends Constructor>(target: T, _context?: ClassDecoratorContext) => T;
|
|
15
|
+
/**
|
|
16
|
+
* IsolatedModules-safe class decorator: mark a class as a singleton so
|
|
17
|
+
* {@link Container.registerDecorated} binds it once.
|
|
18
|
+
*
|
|
19
|
+
* Pass an abstract to register under a string/symbol key; omit it to use
|
|
20
|
+
* the class itself as the abstract.
|
|
21
|
+
*/
|
|
22
|
+
export declare function singleton(abstract?: Abstract): <T extends Constructor>(target: T, _context?: ClassDecoratorContext) => T;
|
|
23
|
+
export declare function decoratedSingletonAbstract(target: Constructor): Abstract | undefined;
|
|
24
|
+
export declare function decoratedDependencies(target: Constructor): readonly Abstract[];
|
|
25
|
+
export { SINGLETON_KEY };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const SINGLETON_KEY = Symbol.for('mudah.container.singleton');
|
|
2
|
+
/**
|
|
3
|
+
* IsolatedModules-safe class decorator: writes `static dependencies` so the
|
|
4
|
+
* container can auto-inject without `emitDecoratorMetadata`.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* @inject('logger', 'name')
|
|
8
|
+
* class Service {
|
|
9
|
+
* constructor(public logger: Logger, public name: string) {}
|
|
10
|
+
* }
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export function inject(...deps) {
|
|
14
|
+
return (target, _context) => {
|
|
15
|
+
Object.defineProperty(target, 'dependencies', {
|
|
16
|
+
value: Object.freeze([...deps]),
|
|
17
|
+
configurable: true,
|
|
18
|
+
writable: true,
|
|
19
|
+
});
|
|
20
|
+
return target;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* IsolatedModules-safe class decorator: mark a class as a singleton so
|
|
25
|
+
* {@link Container.registerDecorated} binds it once.
|
|
26
|
+
*
|
|
27
|
+
* Pass an abstract to register under a string/symbol key; omit it to use
|
|
28
|
+
* the class itself as the abstract.
|
|
29
|
+
*/
|
|
30
|
+
export function singleton(abstract) {
|
|
31
|
+
return (target, _context) => {
|
|
32
|
+
Object.defineProperty(target, SINGLETON_KEY, {
|
|
33
|
+
value: abstract ?? target,
|
|
34
|
+
configurable: true,
|
|
35
|
+
});
|
|
36
|
+
return target;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function decoratedSingletonAbstract(target) {
|
|
40
|
+
const value = target[SINGLETON_KEY];
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
export function decoratedDependencies(target) {
|
|
44
|
+
return (target.dependencies ??
|
|
45
|
+
[]);
|
|
46
|
+
}
|
|
47
|
+
export { SINGLETON_KEY };
|
|
48
|
+
//# sourceMappingURL=decorators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;AAE9D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,MAAM,CAAC,GAAG,IAAgB;IACxC,OAAO,CAAwB,MAAS,EAAE,QAAgC,EAAK,EAAE;QAC/E,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE;YAC5C,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YAC/B,YAAY,EAAE,IAAI;YAClB,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,QAAmB;IAC3C,OAAO,CAAwB,MAAS,EAAE,QAAgC,EAAK,EAAE;QAC/E,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE;YAC3C,KAAK,EAAE,QAAQ,IAAI,MAAM;YACzB,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,MAAmB;IAC5D,MAAM,KAAK,GAAI,MAAuD,CAAC,aAAa,CAAC,CAAC;IACtF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAmB;IACvD,OAAO,CAAE,MAA2E,CAAC,YAAY;QAC/F,EAAE,CAAwB,CAAC;AAC/B,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/exceptions.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Abstract } from './types.js';
|
|
2
2
|
/** Thrown when an abstract has no binding and is not a constructible class. */
|
|
3
3
|
export declare class BindingResolutionException extends Error {
|
|
4
|
-
constructor(abstract: Abstract);
|
|
4
|
+
constructor(abstract: Abstract, detail?: string);
|
|
5
5
|
}
|
|
6
6
|
/** Thrown when resolving a binding requires itself, directly or transitively. */
|
|
7
7
|
export declare class CircularDependencyException extends Error {
|
package/dist/exceptions.js
CHANGED
|
@@ -7,8 +7,10 @@ function describe(abstract) {
|
|
|
7
7
|
}
|
|
8
8
|
/** Thrown when an abstract has no binding and is not a constructible class. */
|
|
9
9
|
export class BindingResolutionException extends Error {
|
|
10
|
-
constructor(abstract) {
|
|
11
|
-
super(
|
|
10
|
+
constructor(abstract, detail) {
|
|
11
|
+
super(detail
|
|
12
|
+
? `[container] Unable to resolve "${describe(abstract)}": ${detail}`
|
|
13
|
+
: `[container] Unable to resolve "${describe(abstract)}": no binding is registered and it is not a constructible class.`);
|
|
12
14
|
this.name = 'BindingResolutionException';
|
|
13
15
|
}
|
|
14
16
|
}
|
package/dist/exceptions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exceptions.js","sourceRoot":"","sources":["../src/exceptions.ts"],"names":[],"mappings":"AAEA,SAAS,QAAQ,CAAC,QAAkB;IAClC,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAClD,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC;IAClF,OAAO,QAAQ,CAAC,IAAI,IAAI,mBAAmB,CAAC;AAC9C,CAAC;AAED,+EAA+E;AAC/E,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IACnD,YAAY,QAAkB;
|
|
1
|
+
{"version":3,"file":"exceptions.js","sourceRoot":"","sources":["../src/exceptions.ts"],"names":[],"mappings":"AAEA,SAAS,QAAQ,CAAC,QAAkB;IAClC,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAClD,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC;IAClF,OAAO,QAAQ,CAAC,IAAI,IAAI,mBAAmB,CAAC;AAC9C,CAAC;AAED,+EAA+E;AAC/E,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IACnD,YAAY,QAAkB,EAAE,MAAe;QAC7C,KAAK,CACH,MAAM;YACJ,CAAC,CAAC,kCAAkC,QAAQ,CAAC,QAAQ,CAAC,MAAM,MAAM,EAAE;YACpE,CAAC,CAAC,kCAAkC,QAAQ,CAAC,QAAQ,CAAC,kEAAkE,CAC3H,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAED,iFAAiF;AACjF,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IACpD,YAAY,QAAkB,EAAE,KAA0B;QACxD,KAAK,CAAC,6CAA6C,CAAC,GAAG,KAAK,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtG,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export { Container, isClassLike } from './container.js';
|
|
1
|
+
export { Container, type ContextualBinder, isClassLike } from './container.js';
|
|
2
|
+
export { decoratedDependencies, decoratedSingletonAbstract, inject, SINGLETON_KEY, singleton, } from './decorators.js';
|
|
2
3
|
export { BindingResolutionException, CircularDependencyException } from './exceptions.js';
|
|
3
|
-
export type
|
|
4
|
+
export { type ClassProvider, type FactoryProvider, isClassProvider, isFactoryProvider, isValueProvider, loadProviderModule, loadProviders, loadProvidersFrom, type ProviderDef, type ValueProvider, } from './providers.js';
|
|
5
|
+
export type { Abstract, AsyncFactory, BindingQuery, Constructor, ContainerSnapshot, Disposable, Factory, Injectable, } from './types.js';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { Container, isClassLike } from './container.js';
|
|
2
|
+
export { decoratedDependencies, decoratedSingletonAbstract, inject, SINGLETON_KEY, singleton, } from './decorators.js';
|
|
2
3
|
export { BindingResolutionException, CircularDependencyException } from './exceptions.js';
|
|
4
|
+
export { isClassProvider, isFactoryProvider, isValueProvider, loadProviderModule, loadProviders, loadProvidersFrom, } from './providers.js';
|
|
3
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,MAAM,EACN,aAAa,EACb,SAAS,GACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAC1F,OAAO,EAGL,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,iBAAiB,GAGlB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Container } from './container.js';
|
|
2
|
+
import type { Abstract, AsyncFactory, Constructor, Factory } from './types.js';
|
|
3
|
+
export interface ClassProvider {
|
|
4
|
+
provide: Abstract;
|
|
5
|
+
useClass: Constructor;
|
|
6
|
+
shared?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface FactoryProvider {
|
|
9
|
+
provide: Abstract;
|
|
10
|
+
useFactory: Factory | AsyncFactory;
|
|
11
|
+
shared?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface ValueProvider {
|
|
14
|
+
provide: Abstract;
|
|
15
|
+
useValue: unknown;
|
|
16
|
+
}
|
|
17
|
+
/** Provider definition accepted by {@link loadProviders}. */
|
|
18
|
+
export type ProviderDef = Constructor | ClassProvider | FactoryProvider | ValueProvider;
|
|
19
|
+
export declare function isClassProvider(value: ProviderDef): value is ClassProvider;
|
|
20
|
+
export declare function isFactoryProvider(value: ProviderDef): value is FactoryProvider;
|
|
21
|
+
export declare function isValueProvider(value: ProviderDef): value is ValueProvider;
|
|
22
|
+
/** Bind an array of provider definitions onto `container`. */
|
|
23
|
+
export declare function loadProviders(container: Container, providers: readonly ProviderDef[]): Container;
|
|
24
|
+
/**
|
|
25
|
+
* Load a `providers.ts` module. Accepts `export const providers = [...]` or
|
|
26
|
+
* a default export array. Missing files yield `[]`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function loadProviderModule(path: string, importer?: (url: string) => Promise<Record<string, unknown>>): Promise<ProviderDef[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Auto-loader: import `providers.ts` / `providers.js` from `dir` (or
|
|
31
|
+
* `dir/providers.ts` when `dir` is a folder). Single providers file.
|
|
32
|
+
*/
|
|
33
|
+
export declare function loadProvidersFrom(dir: string, importer?: (url: string) => Promise<Record<string, unknown>>): Promise<ProviderDef[]>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { readdir } from 'node:fs/promises';
|
|
2
|
+
import { isAbsolute, join } from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import { decoratedSingletonAbstract } from './decorators.js';
|
|
5
|
+
export function isClassProvider(value) {
|
|
6
|
+
return typeof value === 'object' && value !== null && 'useClass' in value;
|
|
7
|
+
}
|
|
8
|
+
export function isFactoryProvider(value) {
|
|
9
|
+
return typeof value === 'object' && value !== null && 'useFactory' in value;
|
|
10
|
+
}
|
|
11
|
+
export function isValueProvider(value) {
|
|
12
|
+
return typeof value === 'object' && value !== null && 'useValue' in value;
|
|
13
|
+
}
|
|
14
|
+
/** Bind an array of provider definitions onto `container`. */
|
|
15
|
+
export function loadProviders(container, providers) {
|
|
16
|
+
for (const provider of providers) {
|
|
17
|
+
if (typeof provider === 'function') {
|
|
18
|
+
const abstract = decoratedSingletonAbstract(provider) ?? provider;
|
|
19
|
+
const shared = decoratedSingletonAbstract(provider) !== undefined;
|
|
20
|
+
if (shared)
|
|
21
|
+
container.singleton(abstract, provider);
|
|
22
|
+
else
|
|
23
|
+
container.bind(abstract, provider);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (isValueProvider(provider)) {
|
|
27
|
+
container.instance(provider.provide, provider.useValue);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (isClassProvider(provider)) {
|
|
31
|
+
if (provider.shared === false)
|
|
32
|
+
container.bind(provider.provide, provider.useClass);
|
|
33
|
+
else
|
|
34
|
+
container.singleton(provider.provide, provider.useClass);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (isFactoryProvider(provider)) {
|
|
38
|
+
if (provider.shared === false)
|
|
39
|
+
container.bind(provider.provide, provider.useFactory);
|
|
40
|
+
else
|
|
41
|
+
container.singleton(provider.provide, provider.useFactory);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return container;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Load a `providers.ts` module. Accepts `export const providers = [...]` or
|
|
48
|
+
* a default export array. Missing files yield `[]`.
|
|
49
|
+
*/
|
|
50
|
+
export async function loadProviderModule(path, importer = defaultImport) {
|
|
51
|
+
try {
|
|
52
|
+
const url = path.startsWith('file:') ? path : pathToFileURL(path).href;
|
|
53
|
+
const mod = await importer(url);
|
|
54
|
+
const declared = mod.providers ?? mod.default;
|
|
55
|
+
if (!Array.isArray(declared))
|
|
56
|
+
return [];
|
|
57
|
+
return declared.filter((value) => value !== undefined);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Auto-loader: import `providers.ts` / `providers.js` from `dir` (or
|
|
65
|
+
* `dir/providers.ts` when `dir` is a folder). Single providers file.
|
|
66
|
+
*/
|
|
67
|
+
export async function loadProvidersFrom(dir, importer) {
|
|
68
|
+
const candidates = isAbsolute(dir)
|
|
69
|
+
? [dir, `${dir}.ts`, `${dir}.js`, join(dir, 'providers.ts'), join(dir, 'providers.js')]
|
|
70
|
+
: [dir];
|
|
71
|
+
for (const candidate of candidates) {
|
|
72
|
+
const loaded = await loadProviderModule(candidate, importer);
|
|
73
|
+
if (loaded.length > 0)
|
|
74
|
+
return loaded;
|
|
75
|
+
}
|
|
76
|
+
if (!isAbsolute(dir))
|
|
77
|
+
return [];
|
|
78
|
+
try {
|
|
79
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
80
|
+
const file = entries.map((entry) => entry.name).find((name) => /^providers\.(ts|mts|js|mjs)$/.test(name));
|
|
81
|
+
if (!file)
|
|
82
|
+
return [];
|
|
83
|
+
return loadProviderModule(join(dir, file), importer);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function defaultImport(url) {
|
|
90
|
+
return import(/* @vite-ignore */ url);
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -9,6 +9,35 @@ export type Abstract<T = unknown> = string | symbol | Constructor<T>;
|
|
|
9
9
|
* class values are treated as injectable constructors instead.
|
|
10
10
|
*/
|
|
11
11
|
export type Factory<T = unknown> = (container: Container) => T;
|
|
12
|
+
/**
|
|
13
|
+
* Factory that may return a Promise. Resolve these with {@link Container.makeAsync};
|
|
14
|
+
* sync {@link Container.make} throws if the factory yields a Promise.
|
|
15
|
+
*/
|
|
16
|
+
export type AsyncFactory<T = unknown> = (container: Container) => T | Promise<T>;
|
|
17
|
+
/** Filter for {@link Container.bindings} / {@link Container.instances}. */
|
|
18
|
+
export interface BindingQuery {
|
|
19
|
+
tag?: string | symbol;
|
|
20
|
+
group?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Snapshot of container state for deterministic tests. */
|
|
23
|
+
export interface ContainerSnapshot {
|
|
24
|
+
readonly bindings: ReadonlyMap<Abstract, {
|
|
25
|
+
readonly factory: Factory | Constructor;
|
|
26
|
+
readonly shared: boolean;
|
|
27
|
+
}>;
|
|
28
|
+
readonly instances: ReadonlyMap<Abstract, unknown>;
|
|
29
|
+
readonly contextual: ReadonlyMap<Constructor, ReadonlyMap<Abstract, Factory | Constructor>>;
|
|
30
|
+
readonly tags: ReadonlyMap<Abstract, ReadonlySet<string | symbol>>;
|
|
31
|
+
readonly scoped: ReadonlyMap<Abstract, {
|
|
32
|
+
readonly factory: Factory | Constructor;
|
|
33
|
+
readonly group?: string;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
/** Object that can be disposed when the container shuts down. */
|
|
37
|
+
export interface Disposable {
|
|
38
|
+
dispose?(): void | Promise<void>;
|
|
39
|
+
close?(): void | Promise<void>;
|
|
40
|
+
}
|
|
12
41
|
/**
|
|
13
42
|
* Optional contract for classes the container should instantiate with
|
|
14
43
|
* constructor auto-injection. List the abstracts to inject, in order.
|
package/package.json
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mudah-cli/container",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "High-performance IoC service container with constructor auto-injection.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
|
+
"author": "Mudah Contributors",
|
|
8
|
+
"homepage": "https://github.com/thesimonharms/mudah#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/thesimonharms/mudah.git",
|
|
12
|
+
"directory": "packages/container"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"ioc",
|
|
16
|
+
"dependency-injection",
|
|
17
|
+
"container",
|
|
18
|
+
"di",
|
|
19
|
+
"typescript"
|
|
20
|
+
],
|
|
7
21
|
"engines": {
|
|
8
22
|
"node": ">=26"
|
|
9
23
|
},
|