@frontmcp/di 0.0.1 → 0.7.1

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.
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Base class for registries with indexed lookups.
3
+ *
4
+ * Provides:
5
+ * - O(1) lookups by qualified ID, name, owner
6
+ * - Child registry adoption with live subscriptions
7
+ * - Lineage management for tracking ownership
8
+ * - Change event emission for subscribers
9
+ *
10
+ * Extended by ToolRegistry, ResourceRegistry, PromptRegistry, AgentRegistry.
11
+ */
12
+ import type { Token } from '../interfaces/base.interface.js';
13
+ import { RegistryAbstract, type RegistryKind } from './registry.base.js';
14
+ import type { IndexedEntry, EntryLineage, EntryOwnerRef, ChangeEvent, ChangeKind, SubscribeOptions, RegistryEmitter } from './indexed.types.js';
15
+ /**
16
+ * Abstract base class for registries with indexed lookups.
17
+ *
18
+ * @typeParam TInstance - Type of registry entry instances
19
+ * @typeParam TRecord - Type of registry records
20
+ * @typeParam TIndexed - Type of indexed entries (extends IndexedEntry)
21
+ * @typeParam TMetadata - Type of initialization metadata
22
+ * @typeParam TProviders - Type of parent provider registry
23
+ */
24
+ export declare abstract class IndexedRegistry<TInstance, TRecord, TIndexed extends IndexedEntry<TInstance>, TMetadata, TProviders = unknown> extends RegistryAbstract<TInstance, TRecord, TMetadata, TProviders> {
25
+ /** Entries created by this registry */
26
+ protected localRows: TIndexed[];
27
+ /** Entries adopted from child registries */
28
+ protected adopted: Map<IndexedRegistry<TInstance, TRecord, TIndexed, any, any>, TIndexed[]>;
29
+ /** Set of child registries */
30
+ protected children: Set<IndexedRegistry<TInstance, TRecord, TIndexed, any, any>>;
31
+ /** Unsubscribe functions for child subscriptions */
32
+ protected childSubscriptions: Map<IndexedRegistry<TInstance, TRecord, TIndexed, any, any>, () => void>;
33
+ /** O(1) lookup by qualified ID */
34
+ protected byQualifiedId: Map<string, TIndexed>;
35
+ /** O(1) lookup by base name (array for conflicts) */
36
+ protected byName: Map<string, TIndexed[]>;
37
+ /** O(1) lookup by owner key */
38
+ protected byOwner: Map<string, TIndexed[]>;
39
+ /** O(1) lookup by owner:name composite */
40
+ protected byOwnerAndName: Map<string, TIndexed>;
41
+ /** Version counter for change tracking */
42
+ protected version: number;
43
+ /** Event emitter for change notifications */
44
+ protected emitter: RegistryEmitter<ChangeEvent<TIndexed>>;
45
+ /**
46
+ * Create an event emitter for this registry.
47
+ * Override to use custom emitter implementation.
48
+ */
49
+ protected createEmitter(): RegistryEmitter<ChangeEvent<TIndexed>>;
50
+ protected constructor(name: RegistryKind, providers: TProviders, metadata: TMetadata, auto?: boolean);
51
+ /**
52
+ * Build additional indexes from rows.
53
+ * Called during reindex to populate custom indexes.
54
+ *
55
+ * @param rows - All indexed entries (local + adopted)
56
+ */
57
+ protected abstract buildIndexes(rows: TIndexed[]): void;
58
+ /**
59
+ * Create an indexed entry from a record.
60
+ * Called during initialization to wrap records.
61
+ *
62
+ * @param token - Entry token
63
+ * @param record - Entry record
64
+ * @param instance - Instantiated entry
65
+ * @returns Indexed entry wrapper
66
+ */
67
+ protected abstract makeRow(token: Token, record: TRecord, instance: TInstance): TIndexed;
68
+ /**
69
+ * Adopt entries from a child registry.
70
+ *
71
+ * @param child - Child registry to adopt from
72
+ * @param childOwner - Owner reference for lineage
73
+ */
74
+ adoptFromChild(child: IndexedRegistry<TInstance, TRecord, TIndexed, any, any>, childOwner: EntryOwnerRef): void;
75
+ /**
76
+ * Remove a child registry.
77
+ */
78
+ removeChild(child: IndexedRegistry<TInstance, TRecord, TIndexed, any, any>): void;
79
+ /**
80
+ * Relineage an entry with a new prefix.
81
+ * Creates a new indexed entry with updated lineage.
82
+ */
83
+ protected relineage(row: TIndexed, prepend: EntryLineage): TIndexed;
84
+ /**
85
+ * Remove adjacent duplicate segments from lineage.
86
+ */
87
+ protected dedupLineage(lineage: EntryLineage): EntryLineage;
88
+ /**
89
+ * Generate owner key from lineage.
90
+ */
91
+ protected ownerKeyOf(lineage: EntryLineage): string;
92
+ /**
93
+ * Generate qualified name from base name and lineage.
94
+ */
95
+ protected qualifiedNameOf(baseName: string, lineage: EntryLineage): string;
96
+ /**
97
+ * Rebuild all indexes from local and adopted entries.
98
+ */
99
+ protected reindex(): void;
100
+ /**
101
+ * Subscribe to change events.
102
+ */
103
+ subscribe(opts: SubscribeOptions<TInstance>, callback: (event: ChangeEvent<TIndexed>) => void): () => void;
104
+ /**
105
+ * Emit a change event.
106
+ */
107
+ protected bump(kind: ChangeKind): void;
108
+ /**
109
+ * Find by base name (returns first match).
110
+ */
111
+ findByName(name: string): TInstance | undefined;
112
+ /**
113
+ * Find all by base name.
114
+ */
115
+ findAllByName(name: string): TInstance[];
116
+ /**
117
+ * Find by qualified ID.
118
+ */
119
+ findByQualifiedId(qualifiedId: string): TInstance | undefined;
120
+ /**
121
+ * List all indexed entries by owner.
122
+ */
123
+ listByOwner(ownerKey: string): TIndexed[];
124
+ /**
125
+ * List all indexed entries.
126
+ */
127
+ listAllIndexed(): TIndexed[];
128
+ /**
129
+ * List all instances.
130
+ */
131
+ listAllInstances(): TInstance[];
132
+ /**
133
+ * Check if registry has any entries.
134
+ */
135
+ hasAny(): boolean;
136
+ /**
137
+ * Dispose of this registry and clean up subscriptions.
138
+ */
139
+ dispose(): void;
140
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Types for indexed registries with fast lookups.
3
+ */
4
+ import type { Token } from '../interfaces/base.interface.js';
5
+ /**
6
+ * Entry lineage segment describing the owner path.
7
+ */
8
+ export interface LineageSegment {
9
+ /** Type of owner (e.g., 'app', 'plugin', 'scope') */
10
+ type: string;
11
+ /** Identifier for this segment */
12
+ id: string;
13
+ /** Optional name for display purposes */
14
+ name?: string;
15
+ }
16
+ /**
17
+ * Complete lineage path from root to entry.
18
+ */
19
+ export type EntryLineage = LineageSegment[];
20
+ /**
21
+ * Reference to an entry owner for adoption tracking.
22
+ */
23
+ export interface EntryOwnerRef {
24
+ /** Lineage path to the owner */
25
+ lineage: EntryLineage;
26
+ /** String key representation of the owner */
27
+ ownerKey: string;
28
+ }
29
+ /**
30
+ * Base indexed entry interface.
31
+ * Extended by specific registries with additional fields.
32
+ */
33
+ export interface IndexedEntry<T> {
34
+ /** Token for this entry */
35
+ token: Token;
36
+ /** Instantiated entry */
37
+ instance: T;
38
+ /** Base name without qualification */
39
+ baseName: string;
40
+ /** Full lineage path */
41
+ lineage: EntryLineage;
42
+ /** String key for owner lookup */
43
+ ownerKey: string;
44
+ /** Fully qualified name including owner path */
45
+ qualifiedName: string;
46
+ /** Fully qualified ID for unique lookup */
47
+ qualifiedId: string;
48
+ }
49
+ /**
50
+ * Change event kinds.
51
+ */
52
+ export type ChangeKind = 'reset' | 'add' | 'remove' | 'update';
53
+ /**
54
+ * Change event scope.
55
+ */
56
+ export type ChangeScope = 'local' | 'global';
57
+ /**
58
+ * Base change event for indexed registries.
59
+ */
60
+ export interface ChangeEvent<TIndexed> {
61
+ /** Type of change */
62
+ kind: ChangeKind;
63
+ /** Scope of the change */
64
+ changeScope: ChangeScope;
65
+ /** Version counter after change */
66
+ version: number;
67
+ /** Current snapshot of all entries */
68
+ snapshot: TIndexed[];
69
+ }
70
+ /**
71
+ * Subscription options for change events.
72
+ */
73
+ export interface SubscribeOptions<T> {
74
+ /** Emit immediately with current state */
75
+ immediate?: boolean;
76
+ /** Filter function for entries */
77
+ filter?: (instance: T) => boolean;
78
+ }
79
+ /**
80
+ * Event emitter interface for change notifications.
81
+ */
82
+ export interface RegistryEmitter<TEvent> {
83
+ /** Emit an event to all subscribers */
84
+ emit(event: TEvent): void;
85
+ /** Subscribe to events, returns unsubscribe function */
86
+ on(handler: (event: TEvent) => void): () => void;
87
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Base abstract class for all registries.
3
+ *
4
+ * Provides the core structure for managing tokens, definitions, and
5
+ * dependency graphs. Subclasses implement specific initialization logic.
6
+ */
7
+ import type { Token } from '../interfaces/base.interface.js';
8
+ /**
9
+ * Result of the buildMap phase containing registry structures.
10
+ */
11
+ export type RegistryBuildMapResult<Record> = {
12
+ /** All tokens that are provided (graph nodes) */
13
+ tokens: Set<Token>;
14
+ /** Record definition by token */
15
+ defs: Map<Token, Record>;
16
+ /** Dependency graph by token */
17
+ graph: Map<Token, Set<Token>>;
18
+ };
19
+ /**
20
+ * Registry kind identifier for categorizing registries.
21
+ */
22
+ export type RegistryKind = string;
23
+ /**
24
+ * Abstract base class for registries.
25
+ *
26
+ * @typeParam Interface - The interface type for registry entries
27
+ * @typeParam Record - The record type stored in the registry
28
+ * @typeParam MetadataType - The metadata type for initialization
29
+ * @typeParam ProviderRegistryType - Optional parent provider registry type
30
+ */
31
+ export declare abstract class RegistryAbstract<Interface, Record, MetadataType, ProviderRegistryType = unknown> {
32
+ /** Default timeout for async operations in milliseconds */
33
+ protected asyncTimeoutMs: number;
34
+ /** Promise that resolves when the registry is fully initialized */
35
+ ready: Promise<void>;
36
+ /** Reference to parent provider registry for dependency resolution */
37
+ protected providers: ProviderRegistryType;
38
+ /** Metadata used for initialization */
39
+ protected list: MetadataType;
40
+ /** All tokens that are provided (graph nodes) */
41
+ protected tokens: Set<Token>;
42
+ /** Record definition by token */
43
+ protected defs: Map<Token, Record>;
44
+ /** Dependency graph by token */
45
+ protected graph: Map<Token, Set<Token>>;
46
+ /** Instantiated entries by token */
47
+ protected readonly instances: Map<Token<Interface>, Interface>;
48
+ /**
49
+ * Create a new registry.
50
+ *
51
+ * @param name - Registry kind name for identification
52
+ * @param providers - Parent provider registry
53
+ * @param metadata - Initialization metadata
54
+ * @param auto - Whether to automatically build and initialize
55
+ */
56
+ protected constructor(name: RegistryKind, providers: ProviderRegistryType, metadata: MetadataType, auto?: boolean);
57
+ /**
58
+ * Build the initial token/record/graph maps from metadata.
59
+ * Called during construction.
60
+ *
61
+ * @param list - Initialization metadata
62
+ * @returns Registry structures
63
+ */
64
+ protected abstract buildMap(list: MetadataType): RegistryBuildMapResult<Record>;
65
+ /**
66
+ * Build the dependency graph.
67
+ * Called after buildMap to establish dependencies.
68
+ */
69
+ protected abstract buildGraph(): void;
70
+ /**
71
+ * Initialize the registry by instantiating entries.
72
+ * Called after buildGraph.
73
+ *
74
+ * @returns Promise that resolves when initialization is complete
75
+ */
76
+ protected abstract initialize(): Promise<void>;
77
+ /**
78
+ * Check if the registry has any entries.
79
+ */
80
+ hasAny(): boolean;
81
+ /**
82
+ * Get all instances as a readonly map.
83
+ */
84
+ getAllInstances(): ReadonlyMap<Token<Interface>, Interface>;
85
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Simple registry base class without indexed lookups.
3
+ *
4
+ * Used for registries that don't need adoption or complex indexing:
5
+ * - AppRegistry
6
+ * - AuthRegistry
7
+ * - FlowRegistry
8
+ */
9
+ import { RegistryAbstract, type RegistryKind } from './registry.base.js';
10
+ /**
11
+ * Simple registry without indexed lookups or adoption.
12
+ *
13
+ * @typeParam TInstance - Type of registry entry instances
14
+ * @typeParam TRecord - Type of registry records
15
+ * @typeParam TMetadata - Type of initialization metadata
16
+ * @typeParam TProviders - Type of parent provider registry
17
+ */
18
+ export declare abstract class SimpleRegistry<TInstance, TRecord, TMetadata, TProviders = unknown> extends RegistryAbstract<TInstance, TRecord, TMetadata, TProviders> {
19
+ protected constructor(name: RegistryKind, providers: TProviders, metadata: TMetadata, auto?: boolean);
20
+ /**
21
+ * Get all entries as an array.
22
+ */
23
+ getAll(): TInstance[];
24
+ /**
25
+ * Get entry count.
26
+ */
27
+ count(): number;
28
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * DI-related metadata keys and constants.
3
+ *
4
+ * These symbols are used with reflect-metadata for storing and retrieving
5
+ * dependency injection metadata on classes.
6
+ */
7
+ /**
8
+ * Metadata key for design:paramtypes (TypeScript's emitted constructor parameter types).
9
+ * Used by reflect-metadata to store constructor parameter type information.
10
+ */
11
+ export declare const DESIGN_PARAMTYPES = "design:paramtypes";
12
+ /**
13
+ * Metadata key indicating a class uses async initialization via static `with()` method.
14
+ * When this metadata is present, the DI container will call the static `with()` method
15
+ * instead of the constructor for instantiation.
16
+ */
17
+ export declare const META_ASYNC_WITH: unique symbol;
18
+ /**
19
+ * Metadata key for storing the token array used by @AsyncWith decorator.
20
+ * Contains a function that returns the dependency tokens for the static `with()` method.
21
+ */
22
+ export declare const META_ASYNC_WITH_TOKENS: unique symbol;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Token system for dependency injection.
3
+ *
4
+ * This module provides:
5
+ * - Token factory for creating type-safe DI tokens
6
+ * - DI-related metadata constants
7
+ */
8
+ export { createTokenFactory, DiTokens, type TokenFactory, type TokenFactoryOptions } from './token.factory.js';
9
+ export { DESIGN_PARAMTYPES, META_ASYNC_WITH, META_ASYNC_WITH_TOKENS } from './di.constants.js';
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Token factory for creating type-safe DI tokens with configurable prefix.
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * // Create a factory with custom prefix
7
+ * const tokens = createTokenFactory({ prefix: 'MyApp' });
8
+ *
9
+ * // Create typed tokens
10
+ * const serviceToken = tokens.type('UserService');
11
+ * // => Symbol('MyApp:type:UserService')
12
+ *
13
+ * const metaToken = tokens.meta('config');
14
+ * // => Symbol('MyApp:meta:config')
15
+ * ```
16
+ */
17
+ export interface TokenFactoryOptions {
18
+ /**
19
+ * Prefix for generated token symbols.
20
+ * @default 'DI'
21
+ */
22
+ prefix?: string;
23
+ }
24
+ export interface TokenFactory {
25
+ /**
26
+ * Create a type token for a service/provider.
27
+ * @param name - The name of the type
28
+ * @returns A unique symbol for the type
29
+ */
30
+ type: (name: string) => symbol;
31
+ /**
32
+ * Create a metadata token for storing/retrieving metadata.
33
+ * @param name - The name of the metadata key
34
+ * @returns A unique symbol for the metadata key
35
+ */
36
+ meta: (name: string) => symbol;
37
+ }
38
+ /**
39
+ * Create a token factory with the given options.
40
+ *
41
+ * @param options - Factory configuration
42
+ * @returns A token factory instance
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const tokens = createTokenFactory({ prefix: 'FrontMcp' });
47
+ * const userToken = tokens.type('UserService');
48
+ * ```
49
+ */
50
+ export declare function createTokenFactory(options?: TokenFactoryOptions): TokenFactory;
51
+ /**
52
+ * Default token factory instance with 'DI' prefix.
53
+ * Use this for standalone DI usage without custom branding.
54
+ */
55
+ export declare const DiTokens: TokenFactory;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Utility functions for dependency injection.
3
+ */
4
+ export { getMetadata, setMetadata, hasAsyncWith } from './metadata.utils.js';
5
+ export { tokenName, isClass, isPromise, getAsyncWithTokens, readWithParamTypes, depsOfClass, depsOfFunc, } from './token.utils.js';
6
+ export { createProviderNormalizer, providerDiscoveryDeps, providerInvocationTokens, type ProviderTokens, type ProviderNormalizerOptions, } from './provider.utils.js';
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Metadata utilities for dependency injection.
3
+ *
4
+ * These utilities work with reflect-metadata to store and retrieve
5
+ * DI-related metadata on classes.
6
+ */
7
+ import 'reflect-metadata';
8
+ import type { Type } from '../interfaces/base.interface.js';
9
+ /**
10
+ * Get metadata value from a target.
11
+ *
12
+ * @param key - The metadata key
13
+ * @param target - The target object or class
14
+ * @param propertyKey - Optional property key for method/property metadata
15
+ * @returns The metadata value or undefined
16
+ */
17
+ export declare function getMetadata<T = any>(key: any, target: any, propertyKey?: string | symbol): T | undefined;
18
+ /**
19
+ * Set metadata value on a target.
20
+ *
21
+ * @param key - The metadata key
22
+ * @param value - The metadata value
23
+ * @param target - The target object or class
24
+ * @param propertyKey - Optional property key for method/property metadata
25
+ */
26
+ export declare function setMetadata(key: any, value: any, target: any, propertyKey?: string | symbol): void;
27
+ /**
28
+ * Check if a class uses async initialization via static `with()` method.
29
+ *
30
+ * Classes decorated with @AsyncWith will have this metadata set and
31
+ * should be instantiated using their static `with()` method instead
32
+ * of the constructor.
33
+ *
34
+ * @param klass - The class to check
35
+ * @returns True if the class uses async initialization
36
+ */
37
+ export declare function hasAsyncWith(klass: Type<any>): boolean;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Provider normalization and dependency discovery utilities.
3
+ *
4
+ * These utilities convert user-facing provider definitions to internal
5
+ * ProviderRecord format and discover dependencies.
6
+ */
7
+ import type { Token, Type } from '../interfaces/base.interface.js';
8
+ import type { ProviderType } from '../interfaces/provider.interface.js';
9
+ import { type ProviderRecord } from '../records/provider.record.js';
10
+ /**
11
+ * Token set for reading provider metadata from classes.
12
+ * Each key maps to a metadata symbol used with reflect-metadata.
13
+ */
14
+ export interface ProviderTokens {
15
+ /** Token indicating this is a provider class */
16
+ type: symbol;
17
+ /** Token for provider name */
18
+ name: symbol;
19
+ /** Token for provider scope */
20
+ scope: symbol;
21
+ /** Token for provider description */
22
+ description?: symbol;
23
+ /** Token for provider id */
24
+ id?: symbol;
25
+ }
26
+ /**
27
+ * Options for creating a provider normalizer.
28
+ */
29
+ export interface ProviderNormalizerOptions {
30
+ /**
31
+ * Metadata tokens for reading provider information from decorated classes.
32
+ */
33
+ tokens: ProviderTokens;
34
+ }
35
+ /**
36
+ * Create a provider normalizer function with the given metadata tokens.
37
+ *
38
+ * The normalizer converts user-facing provider definitions to internal
39
+ * ProviderRecord format. By injecting tokens, this works with any
40
+ * decorator system (FrontMCP, custom, etc.).
41
+ *
42
+ * @param options - Normalizer configuration with metadata tokens
43
+ * @returns A normalizer function
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * import { createProviderNormalizer } from '@frontmcp/di';
48
+ *
49
+ * const normalizeProvider = createProviderNormalizer({
50
+ * tokens: {
51
+ * type: Symbol('provider:type'),
52
+ * name: Symbol('provider:name'),
53
+ * scope: Symbol('provider:scope'),
54
+ * }
55
+ * });
56
+ *
57
+ * const record = normalizeProvider(MyService);
58
+ * ```
59
+ */
60
+ export declare function createProviderNormalizer(options: ProviderNormalizerOptions): (item: ProviderType) => ProviderRecord;
61
+ /**
62
+ * Discover dependencies for a provider record during the discovery phase.
63
+ *
64
+ * @param rec - The provider record
65
+ * @param localTokens - Set of locally registered tokens
66
+ * @param depsOfClassFn - Function to discover class dependencies
67
+ * @returns Array of dependency tokens
68
+ */
69
+ export declare function providerDiscoveryDeps(rec: ProviderRecord, localTokens: Set<Token>, depsOfClassFn: (klass: Type, phase: 'discovery' | 'invocation') => Type[]): Token[];
70
+ /**
71
+ * Get invocation tokens for a provider record.
72
+ *
73
+ * These are the tokens that need to be resolved when instantiating the provider.
74
+ *
75
+ * @param rec - The provider record
76
+ * @param depsOfClassFn - Function to discover class dependencies
77
+ * @returns Array of dependency tokens
78
+ */
79
+ export declare function providerInvocationTokens(rec: ProviderRecord, depsOfClassFn: (klass: Type, phase: 'discovery' | 'invocation') => Type[]): Token[];
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Token utilities for dependency injection.
3
+ *
4
+ * These utilities help with token resolution, type checking, and
5
+ * dependency discovery from class metadata.
6
+ */
7
+ import type { Token, Type } from '../interfaces/base.interface.js';
8
+ /**
9
+ * Get a human-readable name for a token.
10
+ *
11
+ * @param t - The token to get the name for
12
+ * @returns A string representation of the token
13
+ */
14
+ export declare const tokenName: (t: Token) => string;
15
+ /**
16
+ * Check if a value is a class constructor.
17
+ *
18
+ * @param x - The value to check
19
+ * @returns True if x is a class constructor
20
+ */
21
+ export declare const isClass: (x: any) => x is Type;
22
+ /**
23
+ * Check if a value is a Promise.
24
+ *
25
+ * @param v - The value to check
26
+ * @returns True if v is a Promise
27
+ */
28
+ export declare const isPromise: (v: any) => v is Promise<any>;
29
+ /**
30
+ * Get async-with dependency tokens from a class.
31
+ *
32
+ * If a class is decorated with @AsyncWith, this returns the token array
33
+ * that should be resolved and passed to the static `with()` method.
34
+ *
35
+ * @param klass - The class to get tokens from
36
+ * @returns Array of dependency tokens, or null if not decorated
37
+ */
38
+ export declare function getAsyncWithTokens(klass: Type<any>): Type<any>[] | null;
39
+ /**
40
+ * Read parameter types for static with(...) method.
41
+ *
42
+ * This function is TDZ-friendly and will use the @AsyncWith token array
43
+ * if available, falling back to design:paramtypes metadata.
44
+ *
45
+ * @param klass - The class to read parameter types from
46
+ * @param forWhat - Whether this is for 'discovery' or 'invocation' phase
47
+ * @returns Array of dependency types
48
+ * @throws If parameter types cannot be determined
49
+ */
50
+ export declare function readWithParamTypes(klass: Type, forWhat: 'discovery' | 'invocation'): Type[];
51
+ /**
52
+ * Discover dependencies for a CLASS token or concrete Type.
53
+ *
54
+ * For classes with @AsyncWith, reads from the static `with()` method.
55
+ * Otherwise, reads constructor parameter types.
56
+ *
57
+ * @param klass - The class to discover dependencies for
58
+ * @param phase - Whether this is 'discovery' or 'invocation' phase
59
+ * @returns Array of dependency types
60
+ * @throws If dependencies cannot be determined (TDZ issues, missing metadata)
61
+ */
62
+ export declare function depsOfClass(klass: Type, phase: 'discovery' | 'invocation'): Type[];
63
+ /**
64
+ * Discover dependencies for a function token.
65
+ *
66
+ * Reads design:paramtypes metadata, skipping the first parameter
67
+ * (which is typically the input argument, not a dependency).
68
+ *
69
+ * @param fn - The function to discover dependencies for
70
+ * @param phase - Whether this is 'discovery' or 'invocation' phase
71
+ * @returns Array of dependency types
72
+ * @throws If dependencies cannot be determined
73
+ */
74
+ export declare function depsOfFunc(fn: (...args: any[]) => any | Promise<any>, phase: 'discovery' | 'invocation'): Type[];