@mudah-cli/container 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/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)
@@ -1,4 +1,8 @@
1
- import type { Abstract, Constructor, Factory } from './types.js';
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 bindings;
19
- private readonly instances;
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: when `abstract` is injected into `context`, resolve it
32
- * with `factory` instead of its global binding.
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
- /** Whether the abstract is bound, or is a constructible class. */
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 an Angular-style `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.prototype.hasOwnProperty.call(proto, 'constructor');
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
- bindings = new Map();
24
- instances = new Map();
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.bindings.set(abstract, { factory, shared: false });
30
- this.instances.delete(abstract);
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.bindings.set(abstract, { factory, shared: true });
36
- this.instances.delete(abstract);
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.bindings.set(abstract, { factory: () => value, shared: true });
42
- this.instances.set(abstract, value);
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.bindings.has(abstract) || isClassLike(abstract);
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
- if (this.instances.has(abstract)) {
70
- return this.instances.get(abstract);
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 an Angular-style `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 binding = this.bindings.get(abstract);
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(abstract, binding.factory, undefined))
76
- : this.withResolving(abstract, () => this.materialize(abstract, binding.factory, undefined));
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
- /** Alias for {@link make}. */
84
- get(abstract) {
85
- return this.make(abstract);
86
- }
87
- /** Forget all cached singleton instances (bindings are kept). */
88
- flush() {
89
- this.instances.clear();
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.instances.has(abstract)) {
93
- return this.instances.get(abstract);
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.instances.set(abstract, value);
355
+ this.assertSync(abstract, value);
356
+ this._instances.set(abstract, value);
98
357
  return value;
99
358
  });
100
359
  }
101
- materialize(abstract, factory, context) {
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(dep, override, context));
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
@@ -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"}
@@ -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 {
@@ -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(`[container] Unable to resolve "${describe(abstract)}": no binding is registered and it is not a constructible class.`);
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
  }
@@ -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;QAC5B,KAAK,CACH,kCAAkC,QAAQ,CAAC,QAAQ,CAAC,kEAAkE,CACvH,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"}
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 { Abstract, Constructor, Factory, Injectable } from './types.js';
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,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC"}
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
+ /** Angular-style 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). Angular-style single 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). Angular-style single 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.8.0",
3
+ "version": "0.9.0",
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
  },