katagami 3.0.0 → 3.0.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.
Files changed (47) hide show
  1. package/README.md +140 -584
  2. package/dist/chunk-J2NYR3SH.js +6 -0
  3. package/dist/container/index.d.cts +108 -0
  4. package/dist/container/index.d.ts +2 -2
  5. package/dist/disposable/index.cjs +16 -25
  6. package/dist/disposable/index.d.cts +69 -0
  7. package/dist/disposable/index.d.ts +13 -5
  8. package/dist/disposable/index.js +1 -1
  9. package/dist/error/index.d.cts +11 -0
  10. package/dist/index.cjs +91 -55
  11. package/dist/index.d.cts +6 -0
  12. package/dist/index.d.ts +6 -6
  13. package/dist/index.js +76 -31
  14. package/dist/internal.d.cts +29 -0
  15. package/dist/internal.d.ts +3 -1
  16. package/dist/lazy/index.cjs +16 -25
  17. package/dist/lazy/index.d.cts +33 -0
  18. package/dist/lazy/index.d.ts +3 -3
  19. package/dist/lazy/index.js +1 -1
  20. package/dist/resolver/index.d.cts +93 -0
  21. package/dist/scope/index.d.cts +120 -0
  22. package/dist/scope/index.d.ts +4 -4
  23. package/docs/README.de.md +84 -0
  24. package/docs/README.es.md +84 -0
  25. package/docs/README.fr.md +84 -0
  26. package/docs/README.ja.md +105 -0
  27. package/docs/README.ko.md +84 -0
  28. package/docs/README.zh-CN.md +84 -0
  29. package/docs/README.zh-TW.md +84 -0
  30. package/docs/ai-coding-agents.md +78 -0
  31. package/docs/articles/ai-coding-agents.ja.md +83 -0
  32. package/docs/articles/ai-coding-agents.md +70 -0
  33. package/docs/articles/request-scope.md +48 -0
  34. package/docs/articles/without-decorators.md +54 -0
  35. package/docs/choosing-di.md +143 -0
  36. package/docs/growth/baseline-2026-09-11.json +68 -0
  37. package/docs/growth/github-metadata.json +13 -0
  38. package/docs/growth/rollout.md +77 -0
  39. package/docs/guide.md +186 -0
  40. package/docs/type-safety.md +126 -0
  41. package/examples/request-scope/README.md +37 -0
  42. package/examples/request-scope/app.ts +31 -0
  43. package/examples/request-scope/demo.ts +10 -0
  44. package/examples/request-scope/tsconfig.json +11 -0
  45. package/llms.txt +16 -0
  46. package/package.json +56 -23
  47. package/dist/index-jx8b52m0.js +0 -4
package/dist/index.js CHANGED
@@ -1,20 +1,24 @@
1
1
  import {
2
2
  INTERNALS
3
- } from "./index-jx8b52m0.js";
3
+ } from "./chunk-J2NYR3SH.js";
4
4
 
5
5
  // src/container/index.ts
6
6
  function createContainer() {
7
- return new Container;
7
+ return new Container();
8
8
  }
9
-
10
- class Container {
9
+ var Container = class {
11
10
  registrations;
12
11
  singletonCache;
13
12
  disposed = false;
13
+ /**
14
+ * Internal state accessor for extension modules (scope, disposable).
15
+ *
16
+ * @internal
17
+ */
14
18
  [INTERNALS];
15
19
  constructor() {
16
- this.registrations = new Map;
17
- this.singletonCache = new Map;
20
+ this.registrations = /* @__PURE__ */ new Map();
21
+ this.singletonCache = /* @__PURE__ */ new Map();
18
22
  this[INTERNALS] = {
19
23
  isDisposed: () => this.disposed,
20
24
  markDisposed: () => {
@@ -40,23 +44,36 @@ class Container {
40
44
  }
41
45
  return this;
42
46
  }
47
+ /**
48
+ * Add a registration entry. Accumulates registrations for the same token.
49
+ *
50
+ * @param token Token
51
+ * @param factory Factory function
52
+ * @param lifetime Lifetime of the registration
53
+ * @returns The container for method chaining
54
+ */
43
55
  addRegistration(token, factory, lifetime) {
44
56
  const existing = this.registrations.get(token);
45
- if (existing !== undefined) {
57
+ if (existing !== void 0) {
46
58
  existing.push({ factory, lifetime });
47
59
  } else {
48
60
  this.registrations.set(token, [{ factory, lifetime }]);
49
61
  }
50
62
  return this;
51
63
  }
52
- }
64
+ };
65
+
53
66
  // src/error/index.ts
54
- class ContainerError extends Error {
67
+ var ContainerError = class extends Error {
68
+ /**
69
+ * @param message Error message
70
+ */
55
71
  constructor(message) {
56
72
  super(message);
57
73
  this.name = "ContainerError";
58
74
  }
59
- }
75
+ };
76
+
60
77
  // src/resolver/index.ts
61
78
  function tokenToString(token) {
62
79
  if (typeof token === "function") {
@@ -90,20 +107,24 @@ function createScope(source) {
90
107
  }
91
108
  return new Scope(internals.registrations, internals.singletonCache);
92
109
  }
93
-
94
- class Scope {
110
+ var Scope = class {
95
111
  registrations;
96
112
  singletonCache;
97
113
  scopedCache;
98
114
  resolvingTokens;
99
115
  singletonDepth = 0;
100
116
  disposed = false;
117
+ /**
118
+ * Internal state accessor for extension modules (scope, disposable).
119
+ *
120
+ * @internal
121
+ */
101
122
  [INTERNALS];
102
123
  constructor(registrations, singletonCache) {
103
124
  this.registrations = registrations;
104
125
  this.singletonCache = singletonCache;
105
- this.scopedCache = new Map;
106
- this.resolvingTokens = new Set;
126
+ this.scopedCache = /* @__PURE__ */ new Map();
127
+ this.resolvingTokens = /* @__PURE__ */ new Set();
107
128
  this[INTERNALS] = {
108
129
  isDisposed: () => this.disposed,
109
130
  markDisposed: () => {
@@ -126,27 +147,37 @@ class Scope {
126
147
  tryResolveAll(token) {
127
148
  return this.resolveAllTokens(token, false);
128
149
  }
150
+ /**
151
+ * Internal resolution logic shared by resolve and tryResolve.
152
+ * Resolves the last registered factory for the token.
153
+ *
154
+ * @param token Token to resolve
155
+ * @param required If true, throws when the token is not registered. If false, returns undefined.
156
+ * @returns The resolved instance, or undefined if not registered and required is false
157
+ */
129
158
  resolveToken(token, required) {
130
159
  if (this.disposed) {
131
160
  throw new ContainerError("Cannot resolve from a disposed scope.");
132
161
  }
133
162
  const registrations = this.registrations.get(token);
134
- if (registrations === undefined || registrations.length === 0) {
163
+ if (registrations === void 0 || registrations.length === 0) {
135
164
  if (required) {
136
165
  throw new ContainerError(`Token "${tokenToString(token)}" is not registered.`);
137
166
  }
138
- return;
167
+ return void 0;
139
168
  }
140
169
  const registration = registrations[registrations.length - 1];
141
170
  const singletonCached = this.singletonCache.get(registration);
142
- if (singletonCached !== undefined) {
171
+ if (singletonCached !== void 0) {
143
172
  return singletonCached;
144
173
  }
145
174
  if (registration.lifetime === "scoped" && this.singletonDepth > 0) {
146
- throw new ContainerError(`Captive dependency detected: scoped token "${tokenToString(token)}" cannot be resolved inside a singleton factory. Scoped instances must not be captured by singletons.`);
175
+ throw new ContainerError(
176
+ `Captive dependency detected: scoped token "${tokenToString(token)}" cannot be resolved inside a singleton factory. Scoped instances must not be captured by singletons.`
177
+ );
147
178
  }
148
179
  const scopedCached = this.scopedCache.get(registration);
149
- if (scopedCached !== undefined) {
180
+ if (scopedCached !== void 0) {
150
181
  return scopedCached;
151
182
  }
152
183
  if (this.resolvingTokens.has(token)) {
@@ -157,7 +188,9 @@ class Scope {
157
188
  this.singletonDepth++;
158
189
  }
159
190
  try {
160
- const instance = registration.factory(this);
191
+ const instance = registration.factory(
192
+ this
193
+ );
161
194
  if (registration.lifetime === "singleton") {
162
195
  this.singletonCache.set(registration, instance);
163
196
  } else if (registration.lifetime === "scoped") {
@@ -171,16 +204,24 @@ class Scope {
171
204
  this.resolvingTokens.delete(token);
172
205
  }
173
206
  }
207
+ /**
208
+ * Internal resolution logic shared by resolveAll and tryResolveAll.
209
+ * Resolves all registered factories for the token.
210
+ *
211
+ * @param token Token to resolve
212
+ * @param required If true, throws when the token is not registered. If false, returns undefined.
213
+ * @returns An array of resolved instances, or undefined if not registered and required is false
214
+ */
174
215
  resolveAllTokens(token, required) {
175
216
  if (this.disposed) {
176
217
  throw new ContainerError("Cannot resolve from a disposed scope.");
177
218
  }
178
219
  const registrations = this.registrations.get(token);
179
- if (registrations === undefined || registrations.length === 0) {
220
+ if (registrations === void 0 || registrations.length === 0) {
180
221
  if (required) {
181
222
  throw new ContainerError(`Token "${tokenToString(token)}" is not registered.`);
182
223
  }
183
- return;
224
+ return void 0;
184
225
  }
185
226
  if (this.resolvingTokens.has(token)) {
186
227
  throw new ContainerError(`Circular dependency detected: ${buildCircularPath(this.resolvingTokens, token)}`);
@@ -190,21 +231,25 @@ class Scope {
190
231
  return registrations.map((registration) => {
191
232
  const reg = registration;
192
233
  const singletonCached = this.singletonCache.get(registration);
193
- if (singletonCached !== undefined) {
234
+ if (singletonCached !== void 0) {
194
235
  return singletonCached;
195
236
  }
196
237
  if (reg.lifetime === "scoped" && this.singletonDepth > 0) {
197
- throw new ContainerError(`Captive dependency detected: scoped token "${tokenToString(token)}" cannot be resolved inside a singleton factory. Scoped instances must not be captured by singletons.`);
238
+ throw new ContainerError(
239
+ `Captive dependency detected: scoped token "${tokenToString(token)}" cannot be resolved inside a singleton factory. Scoped instances must not be captured by singletons.`
240
+ );
198
241
  }
199
242
  const scopedCached = this.scopedCache.get(registration);
200
- if (scopedCached !== undefined) {
243
+ if (scopedCached !== void 0) {
201
244
  return scopedCached;
202
245
  }
203
246
  if (reg.lifetime === "singleton") {
204
247
  this.singletonDepth++;
205
248
  }
206
249
  try {
207
- const instance = reg.factory(this);
250
+ const instance = reg.factory(
251
+ this
252
+ );
208
253
  if (reg.lifetime === "singleton") {
209
254
  this.singletonCache.set(registration, instance);
210
255
  } else if (reg.lifetime === "scoped") {
@@ -221,11 +266,11 @@ class Scope {
221
266
  this.resolvingTokens.delete(token);
222
267
  }
223
268
  }
224
- }
269
+ };
225
270
  export {
226
- createScope,
227
- createContainer,
228
- Scope,
271
+ Container,
229
272
  ContainerError,
230
- Container
273
+ Scope,
274
+ createContainer,
275
+ createScope
231
276
  };
@@ -0,0 +1,29 @@
1
+ import type { Registration } from './resolver/index.cjs';
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
+ /** Type-only registration state retained by disposable views. No runtime property is emitted. */
9
+ export declare const TYPE_STATE: unique symbol;
10
+ /**
11
+ * Internal state exposed via the INTERNALS symbol.
12
+ *
13
+ * Both Container and Scope implement this interface so that extension modules
14
+ * (scope, disposable) can operate on either without importing the concrete class.
15
+ *
16
+ * @internal
17
+ */
18
+ export interface ContainerInternals {
19
+ /** All registrations (singleton / transient / scoped). Each token maps to an array of registrations. */
20
+ readonly registrations: Map<unknown, Registration[]>;
21
+ /** Singleton cache keyed by Registration object (Container: singletons, Scope: shared with parent). */
22
+ readonly singletonCache: Map<Registration, unknown>;
23
+ /** Instances owned by this container / scope (disposal target), keyed by Registration object. */
24
+ readonly ownCache: Map<Registration, unknown>;
25
+ /** Whether this container / scope has been disposed. */
26
+ isDisposed(): boolean;
27
+ /** Mark this container / scope as disposed. */
28
+ markDisposed(): void;
29
+ }
@@ -1,10 +1,12 @@
1
- import type { Registration } from './resolver';
1
+ import type { Registration } from './resolver/index.js';
2
2
  /**
3
3
  * Symbol used by extension modules (scope, disposable) to access container/scope internals.
4
4
  *
5
5
  * @internal
6
6
  */
7
7
  export declare const INTERNALS: unique symbol;
8
+ /** Type-only registration state retained by disposable views. No runtime property is emitted. */
9
+ export declare const TYPE_STATE: unique symbol;
8
10
  /**
9
11
  * Internal state exposed via the INTERNALS symbol.
10
12
  *
@@ -1,37 +1,28 @@
1
+ "use strict";
1
2
  var __defProp = Object.defineProperty;
2
- var __getOwnPropNames = Object.getOwnPropertyNames;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
5
  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
6
  var __export = (target, all) => {
20
7
  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
- });
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
27
17
  };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
19
 
29
20
  // src/lazy/index.ts
30
- var exports_lazy = {};
31
- __export(exports_lazy, {
21
+ var lazy_exports = {};
22
+ __export(lazy_exports, {
32
23
  lazy: () => lazy
33
24
  });
34
- module.exports = __toCommonJS(exports_lazy);
25
+ module.exports = __toCommonJS(lazy_exports);
35
26
  function lazy(source, token) {
36
27
  let instance;
37
28
  let resolved = false;
@@ -42,7 +33,7 @@ function lazy(source, token) {
42
33
  }
43
34
  return instance;
44
35
  };
45
- const proxyTarget = Object.create(null);
36
+ const proxyTarget = /* @__PURE__ */ Object.create(null);
46
37
  return new Proxy(proxyTarget, {
47
38
  defineProperty(_, prop, desc) {
48
39
  return Reflect.defineProperty(ensureResolved(), prop, desc);
@@ -0,0 +1,33 @@
1
+ import type { DisposableScope } from '../disposable/index.cjs';
2
+ import type { AbstractConstructor } from '../resolver/index.cjs';
3
+ import type { Scope } from '../scope/index.cjs';
4
+ /**
5
+ * Create a lazy proxy that defers resolution until the first property access.
6
+ *
7
+ * The returned object looks and behaves like `V`, but the underlying instance
8
+ * is not created until a property is read, written, or otherwise accessed.
9
+ * Once resolved the instance is cached — subsequent accesses hit the cache.
10
+ *
11
+ * Only **sync class tokens** are supported. Async tokens and PropertyKey tokens
12
+ * are rejected at the type level.
13
+ *
14
+ * @param source A Scope or DisposableScope
15
+ * @param token A sync class constructor token
16
+ * @returns A proxy that transparently forwards to the lazily-resolved instance
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { createContainer, createScope } from 'katagami';
21
+ * import { lazy } from 'katagami/lazy';
22
+ *
23
+ * const container = createContainer()
24
+ * .registerSingleton(HeavyService, () => new HeavyService());
25
+ *
26
+ * const scope = createScope(container);
27
+ * const service = lazy(scope, HeavyService);
28
+ * // Instance is NOT created yet
29
+ * service.doSomething(); // resolved here, then cached
30
+ * ```
31
+ */
32
+ export declare function lazy<T, Sync extends AbstractConstructor, Async extends AbstractConstructor, ScopedT, ScopedSync extends AbstractConstructor, ScopedAsync extends AbstractConstructor, V>(source: Scope<T, Sync, Async, ScopedT, ScopedSync, ScopedAsync>, token: AbstractConstructor<V> & (Sync | ScopedSync)): V;
33
+ export declare function lazy<T, Sync extends AbstractConstructor, Async extends AbstractConstructor, ScopedT, ScopedSync extends AbstractConstructor, ScopedAsync extends AbstractConstructor, V>(source: DisposableScope<T, Sync, Async, ScopedT, ScopedSync, ScopedAsync>, token: AbstractConstructor<V> & (Sync | ScopedSync)): V;
@@ -1,6 +1,6 @@
1
- import type { DisposableScope } from '../disposable';
2
- import type { AbstractConstructor } from '../resolver';
3
- import type { Scope } from '../scope';
1
+ import type { DisposableScope } from '../disposable/index.js';
2
+ import type { AbstractConstructor } from '../resolver/index.js';
3
+ import type { Scope } from '../scope/index.js';
4
4
  /**
5
5
  * Create a lazy proxy that defers resolution until the first property access.
6
6
  *
@@ -9,7 +9,7 @@ function lazy(source, token) {
9
9
  }
10
10
  return instance;
11
11
  };
12
- const proxyTarget = Object.create(null);
12
+ const proxyTarget = /* @__PURE__ */ Object.create(null);
13
13
  return new Proxy(proxyTarget, {
14
14
  defineProperty(_, prop, desc) {
15
15
  return Reflect.defineProperty(ensureResolved(), prop, desc);
@@ -0,0 +1,93 @@
1
+ export type AbstractConstructor<T = unknown> = abstract new (...args: never[]) => T;
2
+ /**
3
+ * Resolver passed to factory callbacks.
4
+ *
5
+ * @template T PropertyKey-based type map (defined via interface, order-independent)
6
+ * @template Sync Union of registered sync class constructors (order-dependent)
7
+ * @template Async Union of registered async class constructors (order-dependent)
8
+ */
9
+ export interface Resolver<T, Sync extends AbstractConstructor = AbstractConstructor, Async extends AbstractConstructor = never> {
10
+ /**
11
+ * Resolve an instance for the given token.
12
+ *
13
+ * @param token A registered token
14
+ * @returns The instance associated with the token
15
+ */
16
+ resolve<V>(token: AbstractConstructor<V> & Async): Promise<V>;
17
+ resolve<V>(token: AbstractConstructor<V> & Sync): V;
18
+ resolve<K extends keyof T>(token: K): T[K];
19
+ /**
20
+ * Try to resolve an instance for the given token.
21
+ *
22
+ * Returns `undefined` instead of throwing when the token is not registered.
23
+ * Other errors (circular dependency, disposed container) are still thrown.
24
+ *
25
+ * @param token A token to resolve
26
+ * @returns The instance associated with the token, or `undefined` if not registered
27
+ */
28
+ tryResolve<V>(token: AbstractConstructor<V> & Async): Promise<V> | undefined;
29
+ tryResolve<V>(token: AbstractConstructor<V> & Sync): V | undefined;
30
+ tryResolve<K extends keyof T>(token: K): T[K] | undefined;
31
+ tryResolve<V>(token: AbstractConstructor<V>): V | Promise<V> | undefined;
32
+ tryResolve(token: PropertyKey): unknown;
33
+ /**
34
+ * Resolve all instances for the given token.
35
+ *
36
+ * Returns an array of instances from all registrations for the token.
37
+ *
38
+ * @param token A registered token
39
+ * @returns An array of instances associated with the token
40
+ */
41
+ resolveAll<V>(token: AbstractConstructor<V> & Async): Promise<V>[];
42
+ resolveAll<V>(token: AbstractConstructor<V> & Sync): V[];
43
+ resolveAll<K extends keyof T>(token: K): T[K][];
44
+ /**
45
+ * Try to resolve all instances for the given token.
46
+ *
47
+ * Returns `undefined` instead of throwing when the token is not registered.
48
+ * Other errors (circular dependency, disposed container) are still thrown.
49
+ *
50
+ * @param token A token to resolve
51
+ * @returns An array of instances associated with the token, or `undefined` if not registered
52
+ */
53
+ tryResolveAll<V>(token: AbstractConstructor<V> & Async): Promise<V>[] | undefined;
54
+ tryResolveAll<V>(token: AbstractConstructor<V> & Sync): V[] | undefined;
55
+ tryResolveAll<K extends keyof T>(token: K): T[K][] | undefined;
56
+ tryResolveAll<V>(token: AbstractConstructor<V>): (V | Promise<V>)[] | undefined;
57
+ tryResolveAll(token: PropertyKey): unknown;
58
+ }
59
+ /**
60
+ * Lifetime of a registration.
61
+ */
62
+ export type Lifetime = 'singleton' | 'transient' | 'scoped';
63
+ /**
64
+ * Factory registration entry.
65
+ */
66
+ export interface Registration {
67
+ /**
68
+ * Factory function.
69
+ *
70
+ * @param resolver Resolver
71
+ * @returns Instance
72
+ */
73
+ readonly factory: (resolver: Resolver<never, never>) => unknown;
74
+ /**
75
+ * Lifetime of the registration.
76
+ */
77
+ readonly lifetime: Lifetime;
78
+ }
79
+ /**
80
+ * Convert a token to a human-readable string.
81
+ */
82
+ export declare function tokenToString(token: unknown): string;
83
+ /**
84
+ * Build a human-readable circular dependency path from the resolving tokens.
85
+ *
86
+ * Uses the insertion order of Set to extract only the cycle portion.
87
+ * e.g. if resolvingTokens is [X, A, B, C] and token is A, returns "A -> B -> C -> A"
88
+ *
89
+ * @param resolvingTokens The set of tokens currently being resolved
90
+ * @param token The token that caused the circular dependency
91
+ * @returns Formatted cycle path string
92
+ */
93
+ export declare function buildCircularPath(resolvingTokens: Set<unknown>, token: unknown): string;
@@ -0,0 +1,120 @@
1
+ import type { Container } from '../container/index.cjs';
2
+ import type { DisposableContainer, DisposableScope } from '../disposable/index.cjs';
3
+ import { type ContainerInternals, INTERNALS } from '../internal.cjs';
4
+ import type { AbstractConstructor, Registration } from '../resolver/index.cjs';
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>;
19
+ /**
20
+ * Scoped child container.
21
+ *
22
+ * Inherits all registrations from the parent container.
23
+ * Singleton instances are shared with the parent, while scoped instances are local to this scope.
24
+ * Transient instances are always newly created.
25
+ *
26
+ * @template T PropertyKey-based token type map
27
+ * @template Sync Union of registered sync class constructors
28
+ * @template Async Union of registered async class constructors
29
+ * @template ScopedT PropertyKey-based token type map for scoped registrations
30
+ * @template ScopedSync Union of scoped sync class constructors
31
+ * @template ScopedAsync Union of scoped async class constructors
32
+ */
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> {
34
+ private readonly registrations;
35
+ private readonly singletonCache;
36
+ private readonly scopedCache;
37
+ private readonly resolvingTokens;
38
+ private singletonDepth;
39
+ private disposed;
40
+ /**
41
+ * Internal state accessor for extension modules (scope, disposable).
42
+ *
43
+ * @internal
44
+ */
45
+ readonly [INTERNALS]: ContainerInternals;
46
+ constructor(registrations: Map<unknown, Registration[]>, singletonCache: Map<Registration, unknown>);
47
+ /**
48
+ * Resolve an instance for the given token.
49
+ *
50
+ * - Singleton: Returns the shared instance from the parent container (creates and caches on first access).
51
+ * - Scoped: Returns an instance local to this scope (creates and caches on first access within the scope).
52
+ * - Transient: Creates a new instance on every call.
53
+ *
54
+ * @param token A registered token
55
+ * @returns The instance associated with the token
56
+ * @throws ContainerError if the token is not registered
57
+ */
58
+ resolve<V>(token: AbstractConstructor<V> & (Async | ScopedAsync)): Promise<V>;
59
+ resolve<V>(token: AbstractConstructor<V> & (Sync | ScopedSync)): V;
60
+ resolve<K extends keyof (T & ScopedT)>(token: K): (T & ScopedT)[K];
61
+ /**
62
+ * Try to resolve an instance for the given token.
63
+ *
64
+ * Returns `undefined` instead of throwing when the token is not registered.
65
+ * Other errors (circular dependency, disposed scope) are still thrown.
66
+ *
67
+ * @param token A token to resolve
68
+ * @returns The instance associated with the token, or `undefined` if not registered
69
+ */
70
+ tryResolve<V>(token: AbstractConstructor<V> & (Async | ScopedAsync)): Promise<V> | undefined;
71
+ tryResolve<V>(token: AbstractConstructor<V> & (Sync | ScopedSync)): V | undefined;
72
+ tryResolve<K extends keyof (T & ScopedT)>(token: K): (T & ScopedT)[K] | undefined;
73
+ tryResolve<V>(token: AbstractConstructor<V>): V | Promise<V> | undefined;
74
+ tryResolve(token: PropertyKey): unknown;
75
+ /**
76
+ * Resolve all instances for the given token.
77
+ *
78
+ * Returns an array of instances from all registered factories for the token,
79
+ * in registration order.
80
+ *
81
+ * @param token A registered token
82
+ * @returns An array of instances associated with the token
83
+ * @throws ContainerError if the token is not registered
84
+ */
85
+ resolveAll<V>(token: AbstractConstructor<V> & (Async | ScopedAsync)): Promise<V>[];
86
+ resolveAll<V>(token: AbstractConstructor<V> & (Sync | ScopedSync)): V[];
87
+ resolveAll<K extends keyof (T & ScopedT)>(token: K): (T & ScopedT)[K][];
88
+ /**
89
+ * Try to resolve all instances for the given token.
90
+ *
91
+ * Returns `undefined` instead of throwing when the token is not registered.
92
+ * Other errors (circular dependency, disposed scope) are still thrown.
93
+ *
94
+ * @param token A token to resolve
95
+ * @returns An array of instances associated with the token, or `undefined` if not registered
96
+ */
97
+ tryResolveAll<V>(token: AbstractConstructor<V> & (Async | ScopedAsync)): Promise<V>[] | undefined;
98
+ tryResolveAll<V>(token: AbstractConstructor<V> & (Sync | ScopedSync)): V[] | undefined;
99
+ tryResolveAll<K extends keyof (T & ScopedT)>(token: K): (T & ScopedT)[K][] | undefined;
100
+ tryResolveAll<V>(token: AbstractConstructor<V>): (V | Promise<V>)[] | undefined;
101
+ tryResolveAll(token: PropertyKey): unknown;
102
+ /**
103
+ * Internal resolution logic shared by resolve and tryResolve.
104
+ * Resolves the last registered factory for the token.
105
+ *
106
+ * @param token Token to resolve
107
+ * @param required If true, throws when the token is not registered. If false, returns undefined.
108
+ * @returns The resolved instance, or undefined if not registered and required is false
109
+ */
110
+ private resolveToken;
111
+ /**
112
+ * Internal resolution logic shared by resolveAll and tryResolveAll.
113
+ * Resolves all registered factories for the token.
114
+ *
115
+ * @param token Token to resolve
116
+ * @param required If true, throws when the token is not registered. If false, returns undefined.
117
+ * @returns An array of resolved instances, or undefined if not registered and required is false
118
+ */
119
+ private resolveAllTokens;
120
+ }
@@ -1,7 +1,7 @@
1
- import type { Container } from '../container';
2
- import type { DisposableContainer, DisposableScope } from '../disposable';
3
- import { type ContainerInternals, INTERNALS } from '../internal';
4
- import type { AbstractConstructor, Registration } from '../resolver';
1
+ import type { Container } from '../container/index.js';
2
+ import type { DisposableContainer, DisposableScope } from '../disposable/index.js';
3
+ import { type ContainerInternals, INTERNALS } from '../internal.js';
4
+ import type { AbstractConstructor, Registration } from '../resolver/index.js';
5
5
  /**
6
6
  * Create a new scope (child container) from a Container, Scope, or their disposable variants.
7
7
  *