katagami 1.1.0 → 2.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/dist/index.cjs CHANGED
@@ -30,7 +30,6 @@ var __export = (target, all) => {
30
30
  var exports_src = {};
31
31
  __export(exports_src, {
32
32
  createContainer: () => createContainer,
33
- Scope: () => Scope,
34
33
  ContainerError: () => ContainerError,
35
34
  Container: () => Container
36
35
  });
@@ -44,6 +43,9 @@ class ContainerError extends Error {
44
43
  }
45
44
  }
46
45
 
46
+ // src/internal.ts
47
+ var INTERNALS = Symbol("katagami.internals");
48
+
47
49
  // src/resolver/index.ts
48
50
  function tokenToString(token) {
49
51
  if (typeof token === "function") {
@@ -69,97 +71,6 @@ function buildCircularPath(resolvingTokens, token) {
69
71
  return path.join(" -> ");
70
72
  }
71
73
 
72
- // src/scope/index.ts
73
- class Scope {
74
- registrations;
75
- singletonInstances;
76
- scopedInstances;
77
- resolvingTokens;
78
- disposed = false;
79
- constructor(registrations, singletonInstances) {
80
- this.registrations = registrations;
81
- this.singletonInstances = singletonInstances;
82
- this.scopedInstances = new Map;
83
- this.resolvingTokens = new Set;
84
- }
85
- resolve(token) {
86
- return this.resolveToken(token, true);
87
- }
88
- tryResolve(token) {
89
- return this.resolveToken(token, false);
90
- }
91
- resolveToken(token, required) {
92
- if (this.disposed) {
93
- throw new ContainerError("Cannot resolve from a disposed scope.");
94
- }
95
- const singletonCached = this.singletonInstances.get(token);
96
- if (singletonCached !== undefined) {
97
- return singletonCached;
98
- }
99
- const scopedCached = this.scopedInstances.get(token);
100
- if (scopedCached !== undefined) {
101
- return scopedCached;
102
- }
103
- const registration = this.registrations.get(token);
104
- if (registration === undefined) {
105
- if (required) {
106
- throw new ContainerError(`Token "${tokenToString(token)}" is not registered.`);
107
- }
108
- return;
109
- }
110
- if (this.resolvingTokens.has(token)) {
111
- throw new ContainerError(`Circular dependency detected: ${buildCircularPath(this.resolvingTokens, token)}`);
112
- }
113
- this.resolvingTokens.add(token);
114
- try {
115
- const instance = registration.factory(this);
116
- if (registration.lifetime === "singleton") {
117
- this.singletonInstances.set(token, instance);
118
- } else if (registration.lifetime === "scoped") {
119
- this.scopedInstances.set(token, instance);
120
- }
121
- return instance;
122
- } finally {
123
- this.resolvingTokens.delete(token);
124
- }
125
- }
126
- createScope() {
127
- if (this.disposed) {
128
- throw new ContainerError("Cannot create a scope from a disposed scope.");
129
- }
130
- return new Scope(this.registrations, this.singletonInstances);
131
- }
132
- async[Symbol.asyncDispose]() {
133
- if (this.disposed) {
134
- return;
135
- }
136
- this.disposed = true;
137
- const instances = [...this.scopedInstances.values()].reverse();
138
- const errors = [];
139
- for (const instance of instances) {
140
- try {
141
- let resolved = instance;
142
- if (instance instanceof Promise) {
143
- resolved = await instance;
144
- }
145
- if (resolved != null && typeof resolved === "object") {
146
- if (Symbol.asyncDispose in resolved) {
147
- await resolved[Symbol.asyncDispose]();
148
- } else if (Symbol.dispose in resolved) {
149
- resolved[Symbol.dispose]();
150
- }
151
- }
152
- } catch (error) {
153
- errors.push(error);
154
- }
155
- }
156
- this.scopedInstances.clear();
157
- if (errors.length > 0) {
158
- throw new AggregateError(errors, "One or more errors occurred during disposal.");
159
- }
160
- }
161
- }
162
-
163
74
  // src/container/index.ts
164
75
  function createContainer() {
165
76
  return new Container;
@@ -170,10 +81,20 @@ class Container {
170
81
  instances;
171
82
  resolvingTokens;
172
83
  disposed = false;
84
+ [INTERNALS];
173
85
  constructor() {
174
86
  this.registrations = new Map;
175
87
  this.instances = new Map;
176
88
  this.resolvingTokens = new Set;
89
+ this[INTERNALS] = {
90
+ instances: this.instances,
91
+ isDisposed: () => this.disposed,
92
+ markDisposed: () => {
93
+ this.disposed = true;
94
+ },
95
+ ownInstances: this.instances,
96
+ registrations: this.registrations
97
+ };
177
98
  }
178
99
  registerSingleton(token, factory) {
179
100
  return this.addRegistration(token, factory, "singleton");
@@ -184,11 +105,11 @@ class Container {
184
105
  registerScoped(token, factory) {
185
106
  return this.addRegistration(token, factory, "scoped");
186
107
  }
187
- createScope() {
188
- if (this.disposed) {
189
- throw new ContainerError("Cannot create a scope from a disposed container.");
108
+ use(source) {
109
+ for (const [token, registration] of source[INTERNALS].registrations) {
110
+ this.registrations.set(token, registration);
190
111
  }
191
- return new Scope(this.registrations, this.instances);
112
+ return this;
192
113
  }
193
114
  resolve(token) {
194
115
  return this.resolveToken(token, true);
@@ -228,35 +149,6 @@ class Container {
228
149
  this.resolvingTokens.delete(token);
229
150
  }
230
151
  }
231
- async[Symbol.asyncDispose]() {
232
- if (this.disposed) {
233
- return;
234
- }
235
- this.disposed = true;
236
- const instances = [...this.instances.values()].reverse();
237
- const errors = [];
238
- for (const instance of instances) {
239
- try {
240
- let resolved = instance;
241
- if (instance instanceof Promise) {
242
- resolved = await instance;
243
- }
244
- if (resolved != null && typeof resolved === "object") {
245
- if (Symbol.asyncDispose in resolved) {
246
- await resolved[Symbol.asyncDispose]();
247
- } else if (Symbol.dispose in resolved) {
248
- resolved[Symbol.dispose]();
249
- }
250
- }
251
- } catch (error) {
252
- errors.push(error);
253
- }
254
- }
255
- this.instances.clear();
256
- if (errors.length > 0) {
257
- throw new AggregateError(errors, "One or more errors occurred during disposal.");
258
- }
259
- }
260
152
  addRegistration(token, factory, lifetime) {
261
153
  this.registrations.set(token, { factory, lifetime });
262
154
  return this;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { Container, createContainer } from './container';
2
+ export type { DisposableContainer, DisposableScope, disposable } from './disposable';
2
3
  export { ContainerError } from './error';
3
4
  export type { Resolver } from './resolver';
4
- export { Scope } from './scope';
5
+ export type { createScope, Scope } from './scope';
package/dist/index.js CHANGED
@@ -1,126 +1,11 @@
1
- // src/error/index.ts
2
- class ContainerError extends Error {
3
- constructor(message) {
4
- super(message);
5
- this.name = "ContainerError";
6
- }
7
- }
8
-
9
- // src/resolver/index.ts
10
- function tokenToString(token) {
11
- if (typeof token === "function") {
12
- return token.name || "anonymous function";
13
- }
14
- if (typeof token === "symbol") {
15
- return token.toString();
16
- }
17
- return String(token);
18
- }
19
- function buildCircularPath(resolvingTokens, token) {
20
- const path = [];
21
- let found = false;
22
- for (const t of resolvingTokens) {
23
- if (t === token) {
24
- found = true;
25
- }
26
- if (found) {
27
- path.push(tokenToString(t));
28
- }
29
- }
30
- path.push(tokenToString(token));
31
- return path.join(" -> ");
32
- }
33
-
34
- // src/scope/index.ts
35
- class Scope {
36
- registrations;
37
- singletonInstances;
38
- scopedInstances;
39
- resolvingTokens;
40
- disposed = false;
41
- constructor(registrations, singletonInstances) {
42
- this.registrations = registrations;
43
- this.singletonInstances = singletonInstances;
44
- this.scopedInstances = new Map;
45
- this.resolvingTokens = new Set;
46
- }
47
- resolve(token) {
48
- return this.resolveToken(token, true);
49
- }
50
- tryResolve(token) {
51
- return this.resolveToken(token, false);
52
- }
53
- resolveToken(token, required) {
54
- if (this.disposed) {
55
- throw new ContainerError("Cannot resolve from a disposed scope.");
56
- }
57
- const singletonCached = this.singletonInstances.get(token);
58
- if (singletonCached !== undefined) {
59
- return singletonCached;
60
- }
61
- const scopedCached = this.scopedInstances.get(token);
62
- if (scopedCached !== undefined) {
63
- return scopedCached;
64
- }
65
- const registration = this.registrations.get(token);
66
- if (registration === undefined) {
67
- if (required) {
68
- throw new ContainerError(`Token "${tokenToString(token)}" is not registered.`);
69
- }
70
- return;
71
- }
72
- if (this.resolvingTokens.has(token)) {
73
- throw new ContainerError(`Circular dependency detected: ${buildCircularPath(this.resolvingTokens, token)}`);
74
- }
75
- this.resolvingTokens.add(token);
76
- try {
77
- const instance = registration.factory(this);
78
- if (registration.lifetime === "singleton") {
79
- this.singletonInstances.set(token, instance);
80
- } else if (registration.lifetime === "scoped") {
81
- this.scopedInstances.set(token, instance);
82
- }
83
- return instance;
84
- } finally {
85
- this.resolvingTokens.delete(token);
86
- }
87
- }
88
- createScope() {
89
- if (this.disposed) {
90
- throw new ContainerError("Cannot create a scope from a disposed scope.");
91
- }
92
- return new Scope(this.registrations, this.singletonInstances);
93
- }
94
- async[Symbol.asyncDispose]() {
95
- if (this.disposed) {
96
- return;
97
- }
98
- this.disposed = true;
99
- const instances = [...this.scopedInstances.values()].reverse();
100
- const errors = [];
101
- for (const instance of instances) {
102
- try {
103
- let resolved = instance;
104
- if (instance instanceof Promise) {
105
- resolved = await instance;
106
- }
107
- if (resolved != null && typeof resolved === "object") {
108
- if (Symbol.asyncDispose in resolved) {
109
- await resolved[Symbol.asyncDispose]();
110
- } else if (Symbol.dispose in resolved) {
111
- resolved[Symbol.dispose]();
112
- }
113
- }
114
- } catch (error) {
115
- errors.push(error);
116
- }
117
- }
118
- this.scopedInstances.clear();
119
- if (errors.length > 0) {
120
- throw new AggregateError(errors, "One or more errors occurred during disposal.");
121
- }
122
- }
123
- }
1
+ import {
2
+ ContainerError,
3
+ buildCircularPath,
4
+ tokenToString
5
+ } from "./index-g50fxds1.js";
6
+ import {
7
+ INTERNALS
8
+ } from "./index-jx8b52m0.js";
124
9
 
125
10
  // src/container/index.ts
126
11
  function createContainer() {
@@ -132,10 +17,20 @@ class Container {
132
17
  instances;
133
18
  resolvingTokens;
134
19
  disposed = false;
20
+ [INTERNALS];
135
21
  constructor() {
136
22
  this.registrations = new Map;
137
23
  this.instances = new Map;
138
24
  this.resolvingTokens = new Set;
25
+ this[INTERNALS] = {
26
+ instances: this.instances,
27
+ isDisposed: () => this.disposed,
28
+ markDisposed: () => {
29
+ this.disposed = true;
30
+ },
31
+ ownInstances: this.instances,
32
+ registrations: this.registrations
33
+ };
139
34
  }
140
35
  registerSingleton(token, factory) {
141
36
  return this.addRegistration(token, factory, "singleton");
@@ -146,11 +41,11 @@ class Container {
146
41
  registerScoped(token, factory) {
147
42
  return this.addRegistration(token, factory, "scoped");
148
43
  }
149
- createScope() {
150
- if (this.disposed) {
151
- throw new ContainerError("Cannot create a scope from a disposed container.");
44
+ use(source) {
45
+ for (const [token, registration] of source[INTERNALS].registrations) {
46
+ this.registrations.set(token, registration);
152
47
  }
153
- return new Scope(this.registrations, this.instances);
48
+ return this;
154
49
  }
155
50
  resolve(token) {
156
51
  return this.resolveToken(token, true);
@@ -190,35 +85,6 @@ class Container {
190
85
  this.resolvingTokens.delete(token);
191
86
  }
192
87
  }
193
- async[Symbol.asyncDispose]() {
194
- if (this.disposed) {
195
- return;
196
- }
197
- this.disposed = true;
198
- const instances = [...this.instances.values()].reverse();
199
- const errors = [];
200
- for (const instance of instances) {
201
- try {
202
- let resolved = instance;
203
- if (instance instanceof Promise) {
204
- resolved = await instance;
205
- }
206
- if (resolved != null && typeof resolved === "object") {
207
- if (Symbol.asyncDispose in resolved) {
208
- await resolved[Symbol.asyncDispose]();
209
- } else if (Symbol.dispose in resolved) {
210
- resolved[Symbol.dispose]();
211
- }
212
- }
213
- } catch (error) {
214
- errors.push(error);
215
- }
216
- }
217
- this.instances.clear();
218
- if (errors.length > 0) {
219
- throw new AggregateError(errors, "One or more errors occurred during disposal.");
220
- }
221
- }
222
88
  addRegistration(token, factory, lifetime) {
223
89
  this.registrations.set(token, { factory, lifetime });
224
90
  return this;
@@ -226,7 +92,6 @@ class Container {
226
92
  }
227
93
  export {
228
94
  createContainer,
229
- Scope,
230
95
  ContainerError,
231
96
  Container
232
97
  };
@@ -0,0 +1,27 @@
1
+ import type { Registration } from './resolver';
2
+ /**
3
+ * Symbol used by extension modules (scope, disposable) to access container/scope internals.
4
+ *
5
+ * @internal
6
+ */
7
+ export declare const INTERNALS: unique symbol;
8
+ /**
9
+ * Internal state exposed via the INTERNALS symbol.
10
+ *
11
+ * Both Container and Scope implement this interface so that extension modules
12
+ * (scope, disposable) can operate on either without importing the concrete class.
13
+ *
14
+ * @internal
15
+ */
16
+ export interface ContainerInternals {
17
+ /** All registrations (singleton / transient / scoped). */
18
+ readonly registrations: Map<unknown, Registration>;
19
+ /** Instance cache used during resolution (Container: singletons, Scope: singletonInstances). */
20
+ readonly instances: Map<unknown, unknown>;
21
+ /** Instances owned by this container / scope (disposal target). */
22
+ readonly ownInstances: Map<unknown, unknown>;
23
+ /** Whether this container / scope has been disposed. */
24
+ isDisposed(): boolean;
25
+ /** Mark this container / scope as disposed. */
26
+ markDisposed(): void;
27
+ }
@@ -0,0 +1,145 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
6
+ var __toCommonJS = (from) => {
7
+ var entry = __moduleCache.get(from), desc;
8
+ if (entry)
9
+ return entry;
10
+ entry = __defProp({}, "__esModule", { value: true });
11
+ if (from && typeof from === "object" || typeof from === "function")
12
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
13
+ get: () => from[key],
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ }));
16
+ __moduleCache.set(from, entry);
17
+ return entry;
18
+ };
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+
29
+ // src/scope/index.ts
30
+ var exports_scope = {};
31
+ __export(exports_scope, {
32
+ createScope: () => createScope,
33
+ Scope: () => Scope
34
+ });
35
+ module.exports = __toCommonJS(exports_scope);
36
+
37
+ // src/error/index.ts
38
+ class ContainerError extends Error {
39
+ constructor(message) {
40
+ super(message);
41
+ this.name = "ContainerError";
42
+ }
43
+ }
44
+
45
+ // src/internal.ts
46
+ var INTERNALS = Symbol("katagami.internals");
47
+
48
+ // src/resolver/index.ts
49
+ function tokenToString(token) {
50
+ if (typeof token === "function") {
51
+ return token.name || "anonymous function";
52
+ }
53
+ if (typeof token === "symbol") {
54
+ return token.toString();
55
+ }
56
+ return String(token);
57
+ }
58
+ function buildCircularPath(resolvingTokens, token) {
59
+ const path = [];
60
+ let found = false;
61
+ for (const t of resolvingTokens) {
62
+ if (t === token) {
63
+ found = true;
64
+ }
65
+ if (found) {
66
+ path.push(tokenToString(t));
67
+ }
68
+ }
69
+ path.push(tokenToString(token));
70
+ return path.join(" -> ");
71
+ }
72
+
73
+ // src/scope/index.ts
74
+ function createScope(source) {
75
+ const internals = source[INTERNALS];
76
+ if (internals.isDisposed()) {
77
+ throw new ContainerError("Cannot create a scope from a disposed container.");
78
+ }
79
+ return new Scope(internals.registrations, internals.instances);
80
+ }
81
+
82
+ class Scope {
83
+ registrations;
84
+ singletonInstances;
85
+ scopedInstances;
86
+ resolvingTokens;
87
+ disposed = false;
88
+ [INTERNALS];
89
+ constructor(registrations, singletonInstances) {
90
+ this.registrations = registrations;
91
+ this.singletonInstances = singletonInstances;
92
+ this.scopedInstances = new Map;
93
+ this.resolvingTokens = new Set;
94
+ this[INTERNALS] = {
95
+ instances: this.singletonInstances,
96
+ isDisposed: () => this.disposed,
97
+ markDisposed: () => {
98
+ this.disposed = true;
99
+ },
100
+ ownInstances: this.scopedInstances,
101
+ registrations: this.registrations
102
+ };
103
+ }
104
+ resolve(token) {
105
+ return this.resolveToken(token, true);
106
+ }
107
+ tryResolve(token) {
108
+ return this.resolveToken(token, false);
109
+ }
110
+ resolveToken(token, required) {
111
+ if (this.disposed) {
112
+ throw new ContainerError("Cannot resolve from a disposed scope.");
113
+ }
114
+ const singletonCached = this.singletonInstances.get(token);
115
+ if (singletonCached !== undefined) {
116
+ return singletonCached;
117
+ }
118
+ const scopedCached = this.scopedInstances.get(token);
119
+ if (scopedCached !== undefined) {
120
+ return scopedCached;
121
+ }
122
+ const registration = this.registrations.get(token);
123
+ if (registration === undefined) {
124
+ if (required) {
125
+ throw new ContainerError(`Token "${tokenToString(token)}" is not registered.`);
126
+ }
127
+ return;
128
+ }
129
+ if (this.resolvingTokens.has(token)) {
130
+ throw new ContainerError(`Circular dependency detected: ${buildCircularPath(this.resolvingTokens, token)}`);
131
+ }
132
+ this.resolvingTokens.add(token);
133
+ try {
134
+ const instance = registration.factory(this);
135
+ if (registration.lifetime === "singleton") {
136
+ this.singletonInstances.set(token, instance);
137
+ } else if (registration.lifetime === "scoped") {
138
+ this.scopedInstances.set(token, instance);
139
+ }
140
+ return instance;
141
+ } finally {
142
+ this.resolvingTokens.delete(token);
143
+ }
144
+ }
145
+ }
@@ -1,4 +1,21 @@
1
+ import type { Container } from '../container';
2
+ import type { DisposableContainer, DisposableScope } from '../disposable';
3
+ import { type ContainerInternals, INTERNALS } from '../internal';
1
4
  import type { AbstractConstructor, Registration } from '../resolver';
5
+ /**
6
+ * Create a new scope (child container) from a Container, Scope, or their disposable variants.
7
+ *
8
+ * The scope inherits all registrations from the source.
9
+ * Singleton instances are shared with the parent, while scoped instances are local to the scope.
10
+ *
11
+ * @param source A Container, Scope, DisposableContainer, or DisposableScope to create a child scope from
12
+ * @returns A new Scope instance
13
+ * @throws ContainerError if the source has been disposed
14
+ */
15
+ export declare function createScope<T, Sync extends AbstractConstructor, Async extends AbstractConstructor, ScopedT, ScopedSync extends AbstractConstructor, ScopedAsync extends AbstractConstructor>(source: Container<T, Sync, Async, ScopedT, ScopedSync, ScopedAsync>): Scope<T, Sync, Async, ScopedT, ScopedSync, ScopedAsync>;
16
+ export declare function createScope<T, Sync extends AbstractConstructor, Async extends AbstractConstructor, ScopedT, ScopedSync extends AbstractConstructor, ScopedAsync extends AbstractConstructor>(source: Scope<T, Sync, Async, ScopedT, ScopedSync, ScopedAsync>): Scope<T, Sync, Async, ScopedT, ScopedSync, ScopedAsync>;
17
+ export declare function createScope<T, Sync extends AbstractConstructor, Async extends AbstractConstructor, ScopedT, ScopedSync extends AbstractConstructor, ScopedAsync extends AbstractConstructor>(source: DisposableContainer<T, Sync, Async, ScopedT, ScopedSync, ScopedAsync>): Scope<T, Sync, Async, ScopedT, ScopedSync, ScopedAsync>;
18
+ export declare function createScope<T, Sync extends AbstractConstructor, Async extends AbstractConstructor, ScopedT, ScopedSync extends AbstractConstructor, ScopedAsync extends AbstractConstructor>(source: DisposableScope<T, Sync, Async, ScopedT, ScopedSync, ScopedAsync>): Scope<T, Sync, Async, ScopedT, ScopedSync, ScopedAsync>;
2
19
  /**
3
20
  * Scoped child container.
4
21
  *
@@ -13,12 +30,18 @@ import type { AbstractConstructor, Registration } from '../resolver';
13
30
  * @template ScopedSync Union of scoped sync class constructors
14
31
  * @template ScopedAsync Union of scoped async class constructors
15
32
  */
16
- export declare class Scope<T = Record<never, never>, Sync extends AbstractConstructor = never, Async extends AbstractConstructor = never, ScopedT = Record<never, never>, ScopedSync extends AbstractConstructor = never, ScopedAsync extends AbstractConstructor = never> implements AsyncDisposable {
33
+ export declare class Scope<T = Record<never, never>, Sync extends AbstractConstructor = never, Async extends AbstractConstructor = never, ScopedT = Record<never, never>, ScopedSync extends AbstractConstructor = never, ScopedAsync extends AbstractConstructor = never> {
17
34
  private readonly registrations;
18
35
  private readonly singletonInstances;
19
36
  private readonly scopedInstances;
20
37
  private readonly resolvingTokens;
21
38
  private disposed;
39
+ /**
40
+ * Internal state accessor for extension modules (scope, disposable).
41
+ *
42
+ * @internal
43
+ */
44
+ readonly [INTERNALS]: ContainerInternals;
22
45
  constructor(registrations: Map<unknown, Registration>, singletonInstances: Map<unknown, unknown>);
23
46
  /**
24
47
  * Resolve an instance for the given token.
@@ -56,26 +79,4 @@ export declare class Scope<T = Record<never, never>, Sync extends AbstractConstr
56
79
  * @returns The resolved instance, or undefined if not registered and required is false
57
80
  */
58
81
  private resolveToken;
59
- /**
60
- * Create a nested scope.
61
- *
62
- * The nested scope shares singleton instances with the parent but has its own scoped instance cache.
63
- *
64
- * @returns A new Scope instance
65
- * @throws ContainerError if the scope has been disposed
66
- */
67
- createScope(): Scope<T, Sync, Async, ScopedT, ScopedSync, ScopedAsync>;
68
- /**
69
- * Dispose all scoped instances managed by this scope.
70
- *
71
- * Iterates through scoped instances in reverse creation order (LIFO) and calls
72
- * `[Symbol.asyncDispose]()` or `[Symbol.dispose]()` on each instance that implements them.
73
- * Singleton instances are not disposed as they are owned by the parent container.
74
- *
75
- * This method is idempotent — subsequent calls after the first are no-ops.
76
- * After disposal, `resolve()` and `createScope()` will throw `ContainerError`.
77
- *
78
- * @throws AggregateError if one or more instances throw during disposal
79
- */
80
- [Symbol.asyncDispose](): Promise<void>;
81
82
  }