🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@autometa/injection

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@autometa/injection - npm Package Compare versions

Comparing version
1.0.0-rc.1
to
1.0.0-rc.2
+31
.turbo/turbo-coverage.log
> @autometa/injection@1.0.0-rc.1 coverage /Users/ben.aherne/Documents/GitHub/autometa/packages/injection
> vitest run --coverage --passWithNoTests
(node:25038) [DEP0180] DeprecationWarning: fs.Stats constructor is deprecated.
(Use `node --trace-deprecation ...` to show where the warning was created)
RUN v1.4.0 /Users/ben.aherne/Documents/GitHub/autometa/packages/injection
Coverage enabled with v8
✓ src/__tests__/integration/token-factory-binding.test.ts (2 tests) 3ms
✓ src/__tests__/integration/tagged-binding.test.ts (4 tests) 6ms
✓ src/__tests__/integration/factory-binding.test.ts (4 tests) 6ms
✓ src/__tests__/integration/mixed-injection.test.ts (3 tests) 3ms
✓ src/__tests__/integration/property-injection-with-token.test.ts (2 tests) 6ms
✓ src/__tests__/integration/scope-management.test.ts (2 tests) 8ms
✓ src/__tests__/integration/child-container-resolution.test.ts (5 tests) 7ms
✓ src/__tests__/coverage-thresholds.test.ts (5 tests) 12ms
✓ src/__tests__/container.test.ts (25 tests) 29ms
✓ src/__tests__/integration/simple-dependency-resolution.test.ts (1 test) 2ms
✓ src/__tests__/integration/disposal.test.ts (3 tests) 3ms
✓ src/__tests__/integration/error-handling.test.ts (2 tests) 4ms
↓ src/__tests__/integration/registration-override.test.ts (2 tests | 2 skipped)
✓ src/__tests__/integration/circular-dependency-detection.test.ts (1 test) 3ms
↓ src/__tests__/integration/scope-interaction.test.ts (2 tests | 2 skipped)
Test Files 13 passed | 2 skipped (15)
Tests 59 passed | 4 skipped (63)
Start at 13:55:59
Duration 6.54s (transform 3.61s, setup 0ms, collect 6.37s, tests 92ms, environment 3ms, prepare 19.69s)

> @autometa/injection@1.0.0-rc.1 type-check /Users/ben.aherne/Documents/GitHub/autometa/packages/injection
> tsc --noEmit -p tsconfig.dev.json

Sorry, the diff of this file is too big to display

{"total": {"lines":{"total":853,"covered":820,"skipped":0,"pct":96.13},"statements":{"total":853,"covered":820,"skipped":0,"pct":96.13},"functions":{"total":52,"covered":48,"skipped":0,"pct":92.3},"branches":{"total":147,"covered":135,"skipped":0,"pct":91.83},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":"Unknown"}}
,"/Users/ben.aherne/Documents/GitHub/autometa/packages/injection/src/container.ts": {"lines":{"total":517,"covered":484,"skipped":0,"pct":93.61},"functions":{"total":41,"covered":37,"skipped":0,"pct":90.24},"statements":{"total":517,"covered":484,"skipped":0,"pct":93.61},"branches":{"total":115,"covered":103,"skipped":0,"pct":89.56}}
,"/Users/ben.aherne/Documents/GitHub/autometa/packages/injection/src/decorators.ts": {"lines":{"total":107,"covered":107,"skipped":0,"pct":100},"functions":{"total":6,"covered":6,"skipped":0,"pct":100},"statements":{"total":107,"covered":107,"skipped":0,"pct":100},"branches":{"total":18,"covered":18,"skipped":0,"pct":100}}
,"/Users/ben.aherne/Documents/GitHub/autometa/packages/injection/src/index.ts": {"lines":{"total":33,"covered":33,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":33,"covered":33,"skipped":0,"pct":100},"branches":{"total":2,"covered":2,"skipped":0,"pct":100}}
,"/Users/ben.aherne/Documents/GitHub/autometa/packages/injection/src/types.ts": {"lines":{"total":196,"covered":196,"skipped":0,"pct":100},"functions":{"total":5,"covered":5,"skipped":0,"pct":100},"statements":{"total":196,"covered":196,"skipped":0,"pct":100},"branches":{"total":12,"covered":12,"skipped":0,"pct":100}}
}
+6
-7

> @autometa/injection@0.1.5 build /Users/ben.aherne/Documents/GitHub/autometa/packages/injection
> @autometa/injection@1.0.0-rc.1 build /Users/ben.aherne/Documents/GitHub/autometa/packages/injection
> tsup && pnpm run build:types

@@ -11,14 +11,13 @@

CLI Target: es2020
CLI Cleaning output folder
CJS Build start
ESM Build start
ESM dist/index.js 13.66 KB
ESM dist/index.js.map 32.43 KB
ESM ⚡️ Build success in 886ms
CJS dist/index.cjs 13.94 KB
CJS dist/index.cjs.map 32.43 KB
CJS ⚡️ Build success in 386ms
ESM dist/index.js 13.66 KB
ESM dist/index.js.map 32.43 KB
ESM ⚡️ Build success in 385ms
CJS ⚡️ Build success in 886ms
> @autometa/injection@0.1.5 build:types /Users/ben.aherne/Documents/GitHub/autometa/packages/injection
> @autometa/injection@1.0.0-rc.1 build:types /Users/ben.aherne/Documents/GitHub/autometa/packages/injection
> rimraf tsconfig.types.tsbuildinfo && tsc --build tsconfig.types.json
> @autometa/injection@0.1.5 build:types /Users/ben.aherne/Documents/GitHub/autometa/packages/injection
> tsc -p tsconfig.types.json

> @autometa/injection@1.0.0-rc.1 build:types /Users/ben.aherne/Documents/GitHub/autometa/packages/injection
> rimraf tsconfig.types.tsbuildinfo && tsc --build tsconfig.types.json

> @autometa/injection@0.1.5 lint /Users/ben.aherne/Documents/GitHub/autometa/packages/injection
> @autometa/injection@1.0.0-rc.1 lint /Users/ben.aherne/Documents/GitHub/autometa/packages/injection
> eslint . --max-warnings 0
# @autometa/injection
## 1.0.0-rc.2
### Patch Changes
- 194871e0: Introduce the unified umbrella package `@autometa/core` that re-exports user-facing APIs and exposes the `autometa` CLI. Migrate example projects to use `@autometa/core` subpaths to simplify installation and imports.
Internal fixes:
- Remove TypeScript `declare` fields in `@autometa/injection` and `@autometa/errors` to improve compatibility with certain transpilers.
- Convert several `@autometa/executor` re-exports to type-only to avoid runtime export issues under various transforms.
Example improvements:
- Playwright example now uses ESNext/Bundler module resolution and exports a fully-typed `ensure` facade with domain plugins (response/json/recipes/order/runtime) to fix `ensure.response` typing.
- Parameter types updated to avoid `unknown` on region expectations.
No breaking API changes to existing packages, but consumers are encouraged to adopt `@autometa/core` for a simpler DX.
## 1.0.0-rc.1

@@ -4,0 +22,0 @@

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/types.ts","../src/container.ts","../src/decorators.ts"],"names":["Scope"],"mappings":"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","sourcesContent":["/**\n * Core types for the dependency injection framework\n */\n\n// Constructor type for classes\nexport interface Constructor<T = object> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- constructors often declare specific dependency types; we need a permissive arg signature\n new (...args: any[]): T;\n name?: string;\n prototype?: T;\n}\n\n// Token type for symbolic references\nexport type Token<T = object> = symbol & { __type?: T };\n\n// Identifier can be a constructor, token, or string\nexport type Identifier<T = object> = Constructor<T> | Token<T> | string;\n\n// Scope definitions\nexport enum Scope {\n SINGLETON = \"singleton\",\n TRANSIENT = \"transient\",\n REQUEST = \"request\",\n SESSION = \"session\",\n SCENARIO = \"scenario\",\n}\n\n// Registration options\nexport type PropertyInjectionDescriptor =\n | Identifier\n | {\n readonly token: Identifier;\n readonly lazy?: boolean;\n };\n\nexport type PropertyInjectionMap = {\n readonly [Key in string | number | symbol]?: PropertyInjectionDescriptor;\n};\n\nexport interface RegistrationOptions {\n scope?: Scope;\n tags?: string[];\n factory?: boolean;\n deps?: Identifier[];\n props?: PropertyDep[] | PropertyInjectionMap;\n}\n\n// Binding types\nexport interface ClassBinding<T = object> {\n type: \"class\";\n target: Constructor<T>;\n scope: Scope;\n tags: string[];\n deps?: Identifier[];\n props?: PropertyDep[];\n}\n\nexport interface ValueBinding<T = object> {\n type: \"value\";\n value: T;\n scope: Scope;\n tags: string[];\n}\n\nexport interface FactoryBinding<T = object> {\n type: \"factory\";\n factory: (container: IContainer) => T;\n scope: Scope;\n tags: string[];\n}\n\nexport interface TokenBinding<T = object> {\n type: \"token\";\n token: Token<T>;\n target: Constructor<T> | ((container: IContainer) => T);\n scope: Scope;\n tags: string[];\n}\n\nexport type Binding<T = object> =\n | ClassBinding<T>\n | ValueBinding<T>\n | FactoryBinding<T>\n | TokenBinding<T>;\n\n// Resolution context for circular dependency detection\nexport interface ResolutionContext {\n path: Set<Identifier>;\n depth: number;\n maxDepth: number;\n}\n\n// Container interface\nexport interface IContainer {\n // Registration methods\n register<T>(\n identifier: Identifier<T>,\n binding: Partial<Binding<T>>\n ): IContainer;\n registerClass<T>(\n target: Constructor<T>,\n options?: RegistrationOptions\n ): IContainer;\n registerValue<T>(\n identifier: Identifier<T>,\n value: T,\n options?: RegistrationOptions\n ): IContainer;\n registerFactory<T>(\n identifier: Identifier<T>,\n factory: (container: IContainer) => T,\n options?: RegistrationOptions\n ): IContainer;\n registerToken<T>(\n token: Token<T>,\n target: Constructor<T> | ((container: IContainer) => T),\n options?: RegistrationOptions\n ): IContainer;\n\n // Resolution methods\n resolve<T>(identifier: Identifier<T>): T;\n resolveAll<T>(identifier: Identifier<T>): T[];\n tryResolve<T>(identifier: Identifier<T>): T | undefined;\n\n // Introspection\n isRegistered<T>(identifier: Identifier<T>): boolean;\n getBinding<T>(identifier: Identifier<T>): Binding<T> | undefined;\n\n // Container hierarchy\n createChild(): IContainer;\n parent?: IContainer;\n\n // Lifecycle\n dispose(): Promise<void>;\n\n // Tagged resolution\n resolveByTag<T>(tag: string): T[];\n}\n\n// Dependency injection errors\nexport class DependencyInjectionError extends Error {\n constructor(\n message: string,\n public readonly identifier?: Identifier,\n public readonly context?: ResolutionContext\n ) {\n super(message);\n this.name = \"DependencyInjectionError\";\n }\n}\n\nexport class CircularDependencyError extends DependencyInjectionError {\n constructor(identifier: Identifier, context: ResolutionContext) {\n const identifierName = getIdentifierName(identifier);\n const pathNames = [...context.path].map(getIdentifierName);\n const path = pathNames.join(\" -> \");\n\n super(\n `Circular dependency detected: ${path} -> ${identifierName}`,\n identifier,\n context\n );\n this.name = \"CircularDependencyError\";\n }\n}\n\nexport class UnregisteredDependencyError extends DependencyInjectionError {\n constructor(identifier: Identifier) {\n const name = getIdentifierName(identifier);\n\n super(`No registration found for identifier: ${name}`, identifier);\n this.name = \"UnregisteredDependencyError\";\n }\n}\n\n// Helper function to get identifier name\nexport function getIdentifierName(identifier: Identifier): string {\n if (typeof identifier === \"string\") {\n return identifier;\n }\n if (typeof identifier === \"symbol\") {\n return identifier.toString();\n }\n return identifier.name || \"anonymous\";\n}\n\n// Helper to create tokens\nexport function createToken<T>(description?: string): Token<T> {\n return Symbol(description) as Token<T>;\n}\n\nexport interface PropertyDep {\n property: string | symbol;\n token: Identifier;\n lazy?: boolean;\n}\n","/**\n * Core container implementation for dependency injection\n */\n\nimport {\n IContainer,\n Identifier,\n Constructor,\n Token,\n Binding,\n ClassBinding,\n ValueBinding,\n FactoryBinding,\n TokenBinding,\n Scope,\n RegistrationOptions,\n PropertyDep,\n PropertyInjectionDescriptor,\n PropertyInjectionMap,\n ResolutionContext,\n CircularDependencyError,\n UnregisteredDependencyError,\n} from \"./types\";\n\nexport class Container implements IContainer {\n private readonly bindings = new Map<Identifier, Binding>();\n private readonly instances = new Map<Identifier, unknown>();\n private readonly scopedInstances = new Map<\n string,\n Map<Identifier, unknown>\n >();\n private readonly children = new Set<Container>();\n declare public readonly parent?: IContainer;\n\n constructor(parent?: IContainer) {\n if (parent !== undefined) {\n this.parent = parent;\n }\n }\n\n // Registration methods\n register<T>(\n identifier: Identifier<T>,\n binding: Partial<Binding<T>>\n ): IContainer {\n const fullBinding: Binding<T> = {\n scope: Scope.TRANSIENT,\n tags: [],\n ...binding,\n } as Binding<T>;\n\n this.bindings.set(identifier as Identifier, fullBinding as Binding);\n return this;\n }\n\n registerClass<T>(\n target: Constructor<T>,\n options: RegistrationOptions = {}\n ): IContainer {\n const propertyDeps = this.normalizePropertyOptions(options.props);\n const binding: ClassBinding<T> = {\n type: \"class\",\n target,\n scope: options.scope || Scope.TRANSIENT,\n tags: options.tags || [],\n deps: options.deps || [],\n ...(propertyDeps.length > 0 ? { props: propertyDeps } : {}),\n };\n\n this.bindings.set(target as Identifier, binding as Binding);\n return this;\n }\n\n registerValue<T>(\n identifier: Identifier<T>,\n value: T,\n options: RegistrationOptions = {}\n ): IContainer {\n const binding: ValueBinding<T> = {\n type: \"value\",\n value,\n scope: options.scope || Scope.SINGLETON,\n tags: options.tags || [],\n };\n\n this.bindings.set(identifier as Identifier, binding as Binding);\n return this;\n }\n\n registerFactory<T>(\n identifier: Identifier<T>,\n factory: (container: IContainer) => T,\n options: RegistrationOptions = {}\n ): IContainer {\n const binding: FactoryBinding<T> = {\n type: \"factory\",\n factory,\n scope: options.scope || Scope.TRANSIENT,\n tags: options.tags || [],\n };\n\n this.bindings.set(identifier as Identifier, binding as Binding);\n return this;\n }\n\n registerToken<T>(\n token: Token<T>,\n target: Constructor<T> | ((container: IContainer) => T),\n options: RegistrationOptions = {}\n ): IContainer {\n const binding: TokenBinding<T> = {\n type: \"token\",\n token,\n target,\n scope: options.scope || Scope.TRANSIENT,\n tags: options.tags || [],\n };\n\n this.bindings.set(token as Identifier, binding as Binding);\n return this;\n }\n\n // Resolution methods\n resolve<T>(identifier: Identifier<T>): T {\n const context: ResolutionContext = {\n path: new Set(),\n depth: 0,\n maxDepth: 50,\n };\n\n return this.resolveWithContext(identifier as Identifier, context) as T;\n }\n\n resolveAll<T>(identifier: Identifier<T>): T[] {\n const results: T[] = [];\n\n // Collect from this container\n for (const [key, binding] of this.bindings.entries()) {\n if (\n this.identifierMatches(key, identifier as Identifier) ||\n this.bindingHasMatchingTag(binding, identifier as Identifier)\n ) {\n try {\n const instance = this.resolve(key as Identifier<T>);\n results.push(instance);\n } catch {\n // Skip failed resolutions\n }\n }\n }\n\n // Collect from parent\n if (this.parent) {\n results.push(...this.parent.resolveAll(identifier));\n }\n\n return results;\n }\n\n tryResolve<T>(identifier: Identifier<T>): T | undefined {\n try {\n return this.resolve(identifier);\n } catch {\n return undefined;\n }\n }\n\n // Introspection\n isRegistered<T>(identifier: Identifier<T>): boolean {\n return (\n this.bindings.has(identifier as Identifier) ||\n (this.parent?.isRegistered(identifier) ?? false)\n );\n }\n\n getBinding<T>(identifier: Identifier<T>): Binding<T> | undefined {\n const binding = this.bindings.get(identifier as Identifier) as\n | Binding<T>\n | undefined;\n return binding || this.parent?.getBinding(identifier);\n }\n\n // Container hierarchy\n createChild(): IContainer {\n const child = new Container(this);\n this.children.add(child);\n return child;\n }\n\n // Tagged resolution\n resolveByTag<T>(tag: string): T[] {\n const results: T[] = [];\n\n for (const [identifier, binding] of this.bindings.entries()) {\n if (binding.tags.includes(tag)) {\n try {\n const instance = this.resolve(identifier as Identifier<T>);\n results.push(instance);\n } catch {\n // Skip failed resolutions\n }\n }\n }\n\n if (this.parent) {\n results.push(...this.parent.resolveByTag<T>(tag));\n }\n\n return results;\n }\n\n // Lifecycle\n async dispose(): Promise<void> {\n // Dispose children first\n await Promise.all([...this.children].map((child) => child.dispose()));\n this.children.clear();\n\n // Dispose instances that implement disposal\n for (const instance of this.instances.values()) {\n if (instance && typeof instance === \"object\" && \"dispose\" in instance) {\n const disposable = instance as { dispose(): Promise<void> | void };\n await disposable.dispose();\n }\n }\n\n // Clear all caches\n this.instances.clear();\n this.scopedInstances.clear();\n this.bindings.clear();\n }\n\n // Private resolution implementation\n private resolveWithContext<T>(\n identifier: Identifier,\n context: ResolutionContext\n ): T {\n // Check for circular dependencies\n if (context.path.has(identifier)) {\n throw new CircularDependencyError(identifier, context);\n }\n\n if (context.depth >= context.maxDepth) {\n throw new Error(\n `Maximum resolution depth exceeded (${context.maxDepth})`\n );\n }\n\n // Get binding first to check scope\n const binding = this.getBindingInternal(identifier);\n if (!binding) {\n throw new UnregisteredDependencyError(identifier);\n }\n\n // Check for cached instances based on scope\n if (binding.scope === Scope.SINGLETON && this.instances.has(identifier)) {\n return this.instances.get(identifier) as T;\n }\n\n // Check scoped cache for other scopes\n const scopedCache = this.getScopedCache(binding.scope);\n if (scopedCache?.has(identifier)) {\n return scopedCache.get(identifier) as T;\n }\n\n // Add to resolution path\n context.path.add(identifier);\n context.depth++;\n\n try {\n // Create instance\n const instance = this.createInstance(binding, context) as T;\n\n // Cache based on scope\n if (binding.scope === Scope.SINGLETON) {\n this.instances.set(identifier, instance);\n } else if (scopedCache) {\n scopedCache.set(identifier, instance);\n }\n\n return instance;\n } finally {\n // Clean up resolution path\n context.path.delete(identifier);\n context.depth--;\n }\n }\n\n private getBindingInternal<T>(\n identifier: Identifier<T>\n ): Binding<T> | undefined {\n const binding = this.bindings.get(identifier as Identifier);\n return (binding ||\n (this.parent as Container)?.getBindingInternal?.(identifier)) as\n | Binding<T>\n | undefined;\n }\n\n private createInstance<T>(\n binding: Binding<T>,\n context: ResolutionContext\n ): T {\n switch (binding.type) {\n case \"value\":\n return binding.value;\n\n case \"factory\": {\n // Create a context-aware container for factories\n const contextAwareContainer = this.createContextAwareContainer(context);\n return binding.factory(contextAwareContainer);\n }\n\n case \"class\":\n return this.instantiateClass(\n binding.target as unknown as Constructor<T & object>,\n context\n ) as T;\n\n case \"token\": {\n if (typeof binding.target === \"function\") {\n if (this.isConstructor(binding.target)) {\n return this.instantiateClass(\n binding.target as Constructor<T & object>,\n context\n );\n } else {\n // Create a context-aware container for token factories\n const contextAwareContainer =\n this.createContextAwareContainer(context);\n return (binding.target as (container: IContainer) => T)(\n contextAwareContainer\n );\n }\n }\n throw new Error(\n `Invalid token binding target for ${binding.token.toString()}`\n );\n }\n\n default:\n throw new Error(`Unknown binding type: ${(binding as Binding).type}`);\n }\n }\n\n private instantiateClass<T extends object>(\n constructor: Constructor<T>,\n context: ResolutionContext\n ): T {\n const binding = this.getBindingInternal(constructor) as ClassBinding<T>;\n if (!binding || binding.type !== \"class\") {\n throw new Error(\n `No class binding found for constructor: ${constructor.name}`\n );\n }\n\n // Resolve constructor dependencies from the 'deps' array\n const constructorArgs = (binding.deps || []).map((dep) => {\n return this.resolveWithContext(dep, context);\n });\n\n // Create the instance\n const instance = new constructor(...constructorArgs);\n\n // Resolve and set property dependencies from the 'props' array\n if (binding.props) {\n for (const prop of binding.props) {\n if (prop.lazy) {\n Object.defineProperty(instance, prop.property, {\n configurable: true,\n enumerable: true,\n get: () => {\n const resolved = this.resolveWithContext(prop.token, context);\n Object.defineProperty(instance, prop.property, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: resolved,\n });\n return resolved;\n },\n });\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (instance as any)[prop.property] = this.resolveWithContext(\n prop.token,\n context\n );\n }\n }\n\n return instance;\n }\n\n private isConstructor(fn: unknown): fn is Constructor {\n return typeof fn === \"function\" && fn.prototype !== undefined;\n }\n\n private createContextAwareContainer(context: ResolutionContext): IContainer {\n return {\n register: <T>(identifier: Identifier<T>, binding: Partial<Binding<T>>) =>\n this.register(identifier, binding),\n registerClass: <T>(\n target: Constructor<T>,\n options?: RegistrationOptions\n ) => this.registerClass(target, options),\n registerValue: <T>(\n identifier: Identifier<T>,\n value: T,\n options?: RegistrationOptions\n ) => this.registerValue(identifier, value, options),\n registerFactory: <T>(\n identifier: Identifier<T>,\n factory: (container: IContainer) => T,\n options?: RegistrationOptions\n ) => this.registerFactory(identifier, factory, options),\n registerToken: <T>(\n token: Token<T>,\n target: Constructor<T> | ((container: IContainer) => T),\n options?: RegistrationOptions\n ) => this.registerToken(token, target, options),\n\n resolve: <T>(identifier: Identifier<T>): T => {\n return this.resolveWithContext(identifier as Identifier, context) as T;\n },\n\n resolveAll: <T>(identifier: Identifier<T>) => this.resolveAll(identifier),\n tryResolve: <T>(identifier: Identifier<T>) => this.tryResolve(identifier),\n isRegistered: <T>(identifier: Identifier<T>) =>\n this.isRegistered(identifier),\n getBinding: <T>(identifier: Identifier<T>) => this.getBinding(identifier),\n createChild: () => this.createChild(),\n resolveByTag: <T>(tag: string) => this.resolveByTag<T>(tag),\n dispose: () => this.dispose(),\n };\n }\n\n private getScopedCache(scope: Scope): Map<Identifier, unknown> | undefined {\n if (scope === Scope.SINGLETON || scope === Scope.TRANSIENT) {\n return undefined; // Singletons use global cache, transients are never cached\n }\n\n if (!this.scopedInstances.has(scope)) {\n this.scopedInstances.set(scope, new Map());\n }\n\n return this.scopedInstances.get(scope);\n }\n\n private identifierMatches(a: Identifier, b: Identifier): boolean {\n return a === b;\n }\n\n private bindingHasMatchingTag(\n binding: Binding,\n identifier: Identifier\n ): boolean {\n if (typeof identifier !== \"string\") {\n return false;\n }\n return binding.tags.includes(identifier);\n }\n\n private normalizePropertyOptions(\n props?: RegistrationOptions[\"props\"]\n ): PropertyDep[] {\n if (!props) {\n return [];\n }\n\n if (Array.isArray(props)) {\n return props.map((prop) => ({ ...prop }));\n }\n\n const map = props as PropertyInjectionMap;\n const normalized: PropertyDep[] = [];\n const descriptorMap = map as Record<PropertyKey, PropertyInjectionDescriptor>;\n\n for (const key of Reflect.ownKeys(descriptorMap)) {\n const descriptor = descriptorMap[key as PropertyKey];\n if (!descriptor) {\n continue;\n }\n\n if (!this.isPropertyInjectionObject(descriptor)) {\n normalized.push({\n property: key,\n token: descriptor as Identifier,\n });\n continue;\n }\n\n normalized.push({\n property: key,\n token: descriptor.token,\n ...(descriptor.lazy ? { lazy: descriptor.lazy } : {}),\n });\n }\n\n return normalized;\n }\n\n private isPropertyInjectionObject(\n descriptor: PropertyInjectionDescriptor\n ): descriptor is { token: Identifier; lazy?: boolean } {\n return typeof descriptor === \"object\" && descriptor !== null && \"token\" in descriptor;\n }\n}\n\n// Export convenience functions\nexport function createContainer(): IContainer {\n return new Container();\n}\n\nexport function createChildContainer(parent: IContainer): IContainer {\n return parent.createChild();\n}","import \"reflect-metadata\";\nimport { Scope } from \"./types\";\nimport type { Identifier, PropertyDep, IContainer } from \"./types\";\n\n// Define unique keys for storing metadata via reflect-metadata\nconst INJECT_PARAM_KEY = \"autometa:inject_param\";\nconst INJECT_PROP_KEY = \"autometa:inject_prop\";\n\nexport interface InjectableOptions {\n scope?: Scope;\n deps?: Identifier[];\n}\n\ntype InjectableTarget = new (...args: unknown[]) => object;\n\nfunction ensureInjectableTarget(value: unknown, decorator: string): asserts value is InjectableTarget {\n if (typeof value !== \"function\") {\n throw new TypeError(\n `[${decorator}] can only be used on classes. Received ${typeof value}.`\n );\n }\n}\n\n/**\n * Creates a set of decorators bound to a specific container instance.\n * This factory pattern ensures the decorators are decoupled from a global\n * container and can be used with multiple, separate containers.\n * @param container The container instance to which the decorators will register classes.\n */\nexport function createDecorators(container: IContainer) {\n function registerPropertyDependency(\n target: object,\n propertyKey: string | symbol,\n token: Identifier,\n lazy: boolean\n ): void {\n const existing =\n (Reflect.getMetadata(INJECT_PROP_KEY, target) as PropertyDep[] | undefined) || [];\n const filtered = existing.filter((dep) => dep.property !== propertyKey);\n filtered.push({ property: propertyKey, token, lazy });\n Reflect.defineMetadata(INJECT_PROP_KEY, filtered, target);\n }\n\n /**\n * A class decorator that marks a class as available for injection.\n * It gathers all dependency metadata from `@Inject` decorators and\n * `reflect-metadata` and registers the class with the container.\n */\n function Injectable(options: InjectableOptions = {}): ClassDecorator {\n return (target) => {\n ensureInjectableTarget(target, \"Injectable\");\n const ctor = target;\n // --- Constructor Injection ---\n const deps = options.deps || [];\n\n // --- Property Injection ---\n const props =\n (Reflect.getMetadata(INJECT_PROP_KEY, ctor.prototype) as PropertyDep[] | undefined) || [];\n\n // --- Registration ---\n // The container's `register` method expects an identifier and a binding object.\n const identifier = ctor as unknown as Identifier;\n const binding = {\n type: \"class\" as const,\n target: ctor,\n scope: options.scope || Scope.TRANSIENT,\n tags: [],\n deps,\n props,\n };\n\n container.register(identifier, binding);\n };\n }\n\n /**\n * A decorator that can be used on constructor parameters or class properties\n * to specify a dependency token.\n * @param token The token representing the dependency to inject.\n */\n function Inject(token: Identifier): PropertyDecorator & ParameterDecorator {\n return ((...args: [object, string | symbol, number?]) => {\n const [target, propertyKey, parameterIndex] = args;\n\n if (typeof parameterIndex === \"number\") {\n ensureInjectableTarget(target, \"Inject parameter\");\n const ctor = target;\n const paramTokens =\n (Reflect.getMetadata(INJECT_PARAM_KEY, ctor) as Map<number, Identifier> | undefined) ||\n new Map<number, Identifier>();\n paramTokens.set(parameterIndex, token);\n Reflect.defineMetadata(INJECT_PARAM_KEY, paramTokens, ctor);\n return;\n }\n\n registerPropertyDependency(target, propertyKey, token, false);\n }) as PropertyDecorator & ParameterDecorator;\n }\n\n function LazyInject(token: Identifier): PropertyDecorator {\n return (target, propertyKey) => {\n registerPropertyDependency(target, propertyKey, token, true);\n };\n }\n\n return { Injectable, Inject, LazyInject };\n}\n"]}
{"version":3,"sources":["../src/types.ts","../src/container.ts","../src/decorators.ts"],"names":["Scope"],"mappings":"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","sourcesContent":["/**\n * Core types for the dependency injection framework\n */\n\n// Constructor type for classes\nexport interface Constructor<T = object> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- constructors often declare specific dependency types; we need a permissive arg signature\n new (...args: any[]): T;\n name?: string;\n prototype?: T;\n}\n\n// Token type for symbolic references\nexport type Token<T = object> = symbol & { __type?: T };\n\n// Identifier can be a constructor, token, or string\nexport type Identifier<T = object> = Constructor<T> | Token<T> | string;\n\n// Scope definitions\nexport enum Scope {\n SINGLETON = \"singleton\",\n TRANSIENT = \"transient\",\n REQUEST = \"request\",\n SESSION = \"session\",\n SCENARIO = \"scenario\",\n}\n\n// Registration options\nexport type PropertyInjectionDescriptor =\n | Identifier\n | {\n readonly token: Identifier;\n readonly lazy?: boolean;\n };\n\nexport type PropertyInjectionMap = {\n readonly [Key in string | number | symbol]?: PropertyInjectionDescriptor;\n};\n\nexport interface RegistrationOptions {\n scope?: Scope;\n tags?: string[];\n factory?: boolean;\n deps?: Identifier[];\n props?: PropertyDep[] | PropertyInjectionMap;\n}\n\n// Binding types\nexport interface ClassBinding<T = object> {\n type: \"class\";\n target: Constructor<T>;\n scope: Scope;\n tags: string[];\n deps?: Identifier[];\n props?: PropertyDep[];\n}\n\nexport interface ValueBinding<T = object> {\n type: \"value\";\n value: T;\n scope: Scope;\n tags: string[];\n}\n\nexport interface FactoryBinding<T = object> {\n type: \"factory\";\n factory: (container: IContainer) => T;\n scope: Scope;\n tags: string[];\n}\n\nexport interface TokenBinding<T = object> {\n type: \"token\";\n token: Token<T>;\n target: Constructor<T> | ((container: IContainer) => T);\n scope: Scope;\n tags: string[];\n}\n\nexport type Binding<T = object> =\n | ClassBinding<T>\n | ValueBinding<T>\n | FactoryBinding<T>\n | TokenBinding<T>;\n\n// Resolution context for circular dependency detection\nexport interface ResolutionContext {\n path: Set<Identifier>;\n depth: number;\n maxDepth: number;\n}\n\n// Container interface\nexport interface IContainer {\n // Registration methods\n register<T>(\n identifier: Identifier<T>,\n binding: Partial<Binding<T>>\n ): IContainer;\n registerClass<T>(\n target: Constructor<T>,\n options?: RegistrationOptions\n ): IContainer;\n registerValue<T>(\n identifier: Identifier<T>,\n value: T,\n options?: RegistrationOptions\n ): IContainer;\n registerFactory<T>(\n identifier: Identifier<T>,\n factory: (container: IContainer) => T,\n options?: RegistrationOptions\n ): IContainer;\n registerToken<T>(\n token: Token<T>,\n target: Constructor<T> | ((container: IContainer) => T),\n options?: RegistrationOptions\n ): IContainer;\n\n // Resolution methods\n resolve<T>(identifier: Identifier<T>): T;\n resolveAll<T>(identifier: Identifier<T>): T[];\n tryResolve<T>(identifier: Identifier<T>): T | undefined;\n\n // Introspection\n isRegistered<T>(identifier: Identifier<T>): boolean;\n getBinding<T>(identifier: Identifier<T>): Binding<T> | undefined;\n\n // Container hierarchy\n createChild(): IContainer;\n parent?: IContainer;\n\n // Lifecycle\n dispose(): Promise<void>;\n\n // Tagged resolution\n resolveByTag<T>(tag: string): T[];\n}\n\n// Dependency injection errors\nexport class DependencyInjectionError extends Error {\n constructor(\n message: string,\n public readonly identifier?: Identifier,\n public readonly context?: ResolutionContext\n ) {\n super(message);\n this.name = \"DependencyInjectionError\";\n }\n}\n\nexport class CircularDependencyError extends DependencyInjectionError {\n constructor(identifier: Identifier, context: ResolutionContext) {\n const identifierName = getIdentifierName(identifier);\n const pathNames = [...context.path].map(getIdentifierName);\n const path = pathNames.join(\" -> \");\n\n super(\n `Circular dependency detected: ${path} -> ${identifierName}`,\n identifier,\n context\n );\n this.name = \"CircularDependencyError\";\n }\n}\n\nexport class UnregisteredDependencyError extends DependencyInjectionError {\n constructor(identifier: Identifier) {\n const name = getIdentifierName(identifier);\n\n super(`No registration found for identifier: ${name}`, identifier);\n this.name = \"UnregisteredDependencyError\";\n }\n}\n\n// Helper function to get identifier name\nexport function getIdentifierName(identifier: Identifier): string {\n if (typeof identifier === \"string\") {\n return identifier;\n }\n if (typeof identifier === \"symbol\") {\n return identifier.toString();\n }\n return identifier.name || \"anonymous\";\n}\n\n// Helper to create tokens\nexport function createToken<T>(description?: string): Token<T> {\n return Symbol(description) as Token<T>;\n}\n\nexport interface PropertyDep {\n property: string | symbol;\n token: Identifier;\n lazy?: boolean;\n}\n","/**\n * Core container implementation for dependency injection\n */\n\nimport {\n IContainer,\n Identifier,\n Constructor,\n Token,\n Binding,\n ClassBinding,\n ValueBinding,\n FactoryBinding,\n TokenBinding,\n Scope,\n RegistrationOptions,\n PropertyDep,\n PropertyInjectionDescriptor,\n PropertyInjectionMap,\n ResolutionContext,\n CircularDependencyError,\n UnregisteredDependencyError,\n} from \"./types\";\n\nexport class Container implements IContainer {\n private readonly bindings = new Map<Identifier, Binding>();\n private readonly instances = new Map<Identifier, unknown>();\n private readonly scopedInstances = new Map<\n string,\n Map<Identifier, unknown>\n >();\n private readonly children = new Set<Container>();\n public readonly parent?: IContainer;\n\n constructor(parent?: IContainer) {\n if (parent !== undefined) {\n this.parent = parent;\n }\n }\n\n // Registration methods\n register<T>(\n identifier: Identifier<T>,\n binding: Partial<Binding<T>>\n ): IContainer {\n const fullBinding: Binding<T> = {\n scope: Scope.TRANSIENT,\n tags: [],\n ...binding,\n } as Binding<T>;\n\n this.bindings.set(identifier as Identifier, fullBinding as Binding);\n return this;\n }\n\n registerClass<T>(\n target: Constructor<T>,\n options: RegistrationOptions = {}\n ): IContainer {\n const propertyDeps = this.normalizePropertyOptions(options.props);\n const binding: ClassBinding<T> = {\n type: \"class\",\n target,\n scope: options.scope || Scope.TRANSIENT,\n tags: options.tags || [],\n deps: options.deps || [],\n ...(propertyDeps.length > 0 ? { props: propertyDeps } : {}),\n };\n\n this.bindings.set(target as Identifier, binding as Binding);\n return this;\n }\n\n registerValue<T>(\n identifier: Identifier<T>,\n value: T,\n options: RegistrationOptions = {}\n ): IContainer {\n const binding: ValueBinding<T> = {\n type: \"value\",\n value,\n scope: options.scope || Scope.SINGLETON,\n tags: options.tags || [],\n };\n\n this.bindings.set(identifier as Identifier, binding as Binding);\n return this;\n }\n\n registerFactory<T>(\n identifier: Identifier<T>,\n factory: (container: IContainer) => T,\n options: RegistrationOptions = {}\n ): IContainer {\n const binding: FactoryBinding<T> = {\n type: \"factory\",\n factory,\n scope: options.scope || Scope.TRANSIENT,\n tags: options.tags || [],\n };\n\n this.bindings.set(identifier as Identifier, binding as Binding);\n return this;\n }\n\n registerToken<T>(\n token: Token<T>,\n target: Constructor<T> | ((container: IContainer) => T),\n options: RegistrationOptions = {}\n ): IContainer {\n const binding: TokenBinding<T> = {\n type: \"token\",\n token,\n target,\n scope: options.scope || Scope.TRANSIENT,\n tags: options.tags || [],\n };\n\n this.bindings.set(token as Identifier, binding as Binding);\n return this;\n }\n\n // Resolution methods\n resolve<T>(identifier: Identifier<T>): T {\n const context: ResolutionContext = {\n path: new Set(),\n depth: 0,\n maxDepth: 50,\n };\n\n return this.resolveWithContext(identifier as Identifier, context) as T;\n }\n\n resolveAll<T>(identifier: Identifier<T>): T[] {\n const results: T[] = [];\n\n // Collect from this container\n for (const [key, binding] of this.bindings.entries()) {\n if (\n this.identifierMatches(key, identifier as Identifier) ||\n this.bindingHasMatchingTag(binding, identifier as Identifier)\n ) {\n try {\n const instance = this.resolve(key as Identifier<T>);\n results.push(instance);\n } catch {\n // Skip failed resolutions\n }\n }\n }\n\n // Collect from parent\n if (this.parent) {\n results.push(...this.parent.resolveAll(identifier));\n }\n\n return results;\n }\n\n tryResolve<T>(identifier: Identifier<T>): T | undefined {\n try {\n return this.resolve(identifier);\n } catch {\n return undefined;\n }\n }\n\n // Introspection\n isRegistered<T>(identifier: Identifier<T>): boolean {\n return (\n this.bindings.has(identifier as Identifier) ||\n (this.parent?.isRegistered(identifier) ?? false)\n );\n }\n\n getBinding<T>(identifier: Identifier<T>): Binding<T> | undefined {\n const binding = this.bindings.get(identifier as Identifier) as\n | Binding<T>\n | undefined;\n return binding || this.parent?.getBinding(identifier);\n }\n\n // Container hierarchy\n createChild(): IContainer {\n const child = new Container(this);\n this.children.add(child);\n return child;\n }\n\n // Tagged resolution\n resolveByTag<T>(tag: string): T[] {\n const results: T[] = [];\n\n for (const [identifier, binding] of this.bindings.entries()) {\n if (binding.tags.includes(tag)) {\n try {\n const instance = this.resolve(identifier as Identifier<T>);\n results.push(instance);\n } catch {\n // Skip failed resolutions\n }\n }\n }\n\n if (this.parent) {\n results.push(...this.parent.resolveByTag<T>(tag));\n }\n\n return results;\n }\n\n // Lifecycle\n async dispose(): Promise<void> {\n // Dispose children first\n await Promise.all([...this.children].map((child) => child.dispose()));\n this.children.clear();\n\n // Dispose instances that implement disposal\n for (const instance of this.instances.values()) {\n if (instance && typeof instance === \"object\" && \"dispose\" in instance) {\n const disposable = instance as { dispose(): Promise<void> | void };\n await disposable.dispose();\n }\n }\n\n // Clear all caches\n this.instances.clear();\n this.scopedInstances.clear();\n this.bindings.clear();\n }\n\n // Private resolution implementation\n private resolveWithContext<T>(\n identifier: Identifier,\n context: ResolutionContext\n ): T {\n // Check for circular dependencies\n if (context.path.has(identifier)) {\n throw new CircularDependencyError(identifier, context);\n }\n\n if (context.depth >= context.maxDepth) {\n throw new Error(\n `Maximum resolution depth exceeded (${context.maxDepth})`\n );\n }\n\n // Get binding first to check scope\n const binding = this.getBindingInternal(identifier);\n if (!binding) {\n throw new UnregisteredDependencyError(identifier);\n }\n\n // Check for cached instances based on scope\n if (binding.scope === Scope.SINGLETON && this.instances.has(identifier)) {\n return this.instances.get(identifier) as T;\n }\n\n // Check scoped cache for other scopes\n const scopedCache = this.getScopedCache(binding.scope);\n if (scopedCache?.has(identifier)) {\n return scopedCache.get(identifier) as T;\n }\n\n // Add to resolution path\n context.path.add(identifier);\n context.depth++;\n\n try {\n // Create instance\n const instance = this.createInstance(binding, context) as T;\n\n // Cache based on scope\n if (binding.scope === Scope.SINGLETON) {\n this.instances.set(identifier, instance);\n } else if (scopedCache) {\n scopedCache.set(identifier, instance);\n }\n\n return instance;\n } finally {\n // Clean up resolution path\n context.path.delete(identifier);\n context.depth--;\n }\n }\n\n private getBindingInternal<T>(\n identifier: Identifier<T>\n ): Binding<T> | undefined {\n const binding = this.bindings.get(identifier as Identifier);\n return (binding ||\n (this.parent as Container)?.getBindingInternal?.(identifier)) as\n | Binding<T>\n | undefined;\n }\n\n private createInstance<T>(\n binding: Binding<T>,\n context: ResolutionContext\n ): T {\n switch (binding.type) {\n case \"value\":\n return binding.value;\n\n case \"factory\": {\n // Create a context-aware container for factories\n const contextAwareContainer = this.createContextAwareContainer(context);\n return binding.factory(contextAwareContainer);\n }\n\n case \"class\":\n return this.instantiateClass(\n binding.target as unknown as Constructor<T & object>,\n context\n ) as T;\n\n case \"token\": {\n if (typeof binding.target === \"function\") {\n if (this.isConstructor(binding.target)) {\n return this.instantiateClass(\n binding.target as Constructor<T & object>,\n context\n );\n } else {\n // Create a context-aware container for token factories\n const contextAwareContainer =\n this.createContextAwareContainer(context);\n return (binding.target as (container: IContainer) => T)(\n contextAwareContainer\n );\n }\n }\n throw new Error(\n `Invalid token binding target for ${binding.token.toString()}`\n );\n }\n\n default:\n throw new Error(`Unknown binding type: ${(binding as Binding).type}`);\n }\n }\n\n private instantiateClass<T extends object>(\n constructor: Constructor<T>,\n context: ResolutionContext\n ): T {\n const binding = this.getBindingInternal(constructor) as ClassBinding<T>;\n if (!binding || binding.type !== \"class\") {\n throw new Error(\n `No class binding found for constructor: ${constructor.name}`\n );\n }\n\n // Resolve constructor dependencies from the 'deps' array\n const constructorArgs = (binding.deps || []).map((dep) => {\n return this.resolveWithContext(dep, context);\n });\n\n // Create the instance\n const instance = new constructor(...constructorArgs);\n\n // Resolve and set property dependencies from the 'props' array\n if (binding.props) {\n for (const prop of binding.props) {\n if (prop.lazy) {\n Object.defineProperty(instance, prop.property, {\n configurable: true,\n enumerable: true,\n get: () => {\n const resolved = this.resolveWithContext(prop.token, context);\n Object.defineProperty(instance, prop.property, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: resolved,\n });\n return resolved;\n },\n });\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (instance as any)[prop.property] = this.resolveWithContext(\n prop.token,\n context\n );\n }\n }\n\n return instance;\n }\n\n private isConstructor(fn: unknown): fn is Constructor {\n return typeof fn === \"function\" && fn.prototype !== undefined;\n }\n\n private createContextAwareContainer(context: ResolutionContext): IContainer {\n return {\n register: <T>(identifier: Identifier<T>, binding: Partial<Binding<T>>) =>\n this.register(identifier, binding),\n registerClass: <T>(\n target: Constructor<T>,\n options?: RegistrationOptions\n ) => this.registerClass(target, options),\n registerValue: <T>(\n identifier: Identifier<T>,\n value: T,\n options?: RegistrationOptions\n ) => this.registerValue(identifier, value, options),\n registerFactory: <T>(\n identifier: Identifier<T>,\n factory: (container: IContainer) => T,\n options?: RegistrationOptions\n ) => this.registerFactory(identifier, factory, options),\n registerToken: <T>(\n token: Token<T>,\n target: Constructor<T> | ((container: IContainer) => T),\n options?: RegistrationOptions\n ) => this.registerToken(token, target, options),\n\n resolve: <T>(identifier: Identifier<T>): T => {\n return this.resolveWithContext(identifier as Identifier, context) as T;\n },\n\n resolveAll: <T>(identifier: Identifier<T>) => this.resolveAll(identifier),\n tryResolve: <T>(identifier: Identifier<T>) => this.tryResolve(identifier),\n isRegistered: <T>(identifier: Identifier<T>) =>\n this.isRegistered(identifier),\n getBinding: <T>(identifier: Identifier<T>) => this.getBinding(identifier),\n createChild: () => this.createChild(),\n resolveByTag: <T>(tag: string) => this.resolveByTag<T>(tag),\n dispose: () => this.dispose(),\n };\n }\n\n private getScopedCache(scope: Scope): Map<Identifier, unknown> | undefined {\n if (scope === Scope.SINGLETON || scope === Scope.TRANSIENT) {\n return undefined; // Singletons use global cache, transients are never cached\n }\n\n if (!this.scopedInstances.has(scope)) {\n this.scopedInstances.set(scope, new Map());\n }\n\n return this.scopedInstances.get(scope);\n }\n\n private identifierMatches(a: Identifier, b: Identifier): boolean {\n return a === b;\n }\n\n private bindingHasMatchingTag(\n binding: Binding,\n identifier: Identifier\n ): boolean {\n if (typeof identifier !== \"string\") {\n return false;\n }\n return binding.tags.includes(identifier);\n }\n\n private normalizePropertyOptions(\n props?: RegistrationOptions[\"props\"]\n ): PropertyDep[] {\n if (!props) {\n return [];\n }\n\n if (Array.isArray(props)) {\n return props.map((prop) => ({ ...prop }));\n }\n\n const map = props as PropertyInjectionMap;\n const normalized: PropertyDep[] = [];\n const descriptorMap = map as Record<PropertyKey, PropertyInjectionDescriptor>;\n\n for (const key of Reflect.ownKeys(descriptorMap)) {\n const descriptor = descriptorMap[key as PropertyKey];\n if (!descriptor) {\n continue;\n }\n\n if (!this.isPropertyInjectionObject(descriptor)) {\n normalized.push({\n property: key,\n token: descriptor as Identifier,\n });\n continue;\n }\n\n normalized.push({\n property: key,\n token: descriptor.token,\n ...(descriptor.lazy ? { lazy: descriptor.lazy } : {}),\n });\n }\n\n return normalized;\n }\n\n private isPropertyInjectionObject(\n descriptor: PropertyInjectionDescriptor\n ): descriptor is { token: Identifier; lazy?: boolean } {\n return typeof descriptor === \"object\" && descriptor !== null && \"token\" in descriptor;\n }\n}\n\n// Export convenience functions\nexport function createContainer(): IContainer {\n return new Container();\n}\n\nexport function createChildContainer(parent: IContainer): IContainer {\n return parent.createChild();\n}","import \"reflect-metadata\";\nimport { Scope } from \"./types\";\nimport type { Identifier, PropertyDep, IContainer } from \"./types\";\n\n// Define unique keys for storing metadata via reflect-metadata\nconst INJECT_PARAM_KEY = \"autometa:inject_param\";\nconst INJECT_PROP_KEY = \"autometa:inject_prop\";\n\nexport interface InjectableOptions {\n scope?: Scope;\n deps?: Identifier[];\n}\n\ntype InjectableTarget = new (...args: unknown[]) => object;\n\nfunction ensureInjectableTarget(value: unknown, decorator: string): asserts value is InjectableTarget {\n if (typeof value !== \"function\") {\n throw new TypeError(\n `[${decorator}] can only be used on classes. Received ${typeof value}.`\n );\n }\n}\n\n/**\n * Creates a set of decorators bound to a specific container instance.\n * This factory pattern ensures the decorators are decoupled from a global\n * container and can be used with multiple, separate containers.\n * @param container The container instance to which the decorators will register classes.\n */\nexport function createDecorators(container: IContainer) {\n function registerPropertyDependency(\n target: object,\n propertyKey: string | symbol,\n token: Identifier,\n lazy: boolean\n ): void {\n const existing =\n (Reflect.getMetadata(INJECT_PROP_KEY, target) as PropertyDep[] | undefined) || [];\n const filtered = existing.filter((dep) => dep.property !== propertyKey);\n filtered.push({ property: propertyKey, token, lazy });\n Reflect.defineMetadata(INJECT_PROP_KEY, filtered, target);\n }\n\n /**\n * A class decorator that marks a class as available for injection.\n * It gathers all dependency metadata from `@Inject` decorators and\n * `reflect-metadata` and registers the class with the container.\n */\n function Injectable(options: InjectableOptions = {}): ClassDecorator {\n return (target) => {\n ensureInjectableTarget(target, \"Injectable\");\n const ctor = target;\n // --- Constructor Injection ---\n const deps = options.deps || [];\n\n // --- Property Injection ---\n const props =\n (Reflect.getMetadata(INJECT_PROP_KEY, ctor.prototype) as PropertyDep[] | undefined) || [];\n\n // --- Registration ---\n // The container's `register` method expects an identifier and a binding object.\n const identifier = ctor as unknown as Identifier;\n const binding = {\n type: \"class\" as const,\n target: ctor,\n scope: options.scope || Scope.TRANSIENT,\n tags: [],\n deps,\n props,\n };\n\n container.register(identifier, binding);\n };\n }\n\n /**\n * A decorator that can be used on constructor parameters or class properties\n * to specify a dependency token.\n * @param token The token representing the dependency to inject.\n */\n function Inject(token: Identifier): PropertyDecorator & ParameterDecorator {\n return ((...args: [object, string | symbol, number?]) => {\n const [target, propertyKey, parameterIndex] = args;\n\n if (typeof parameterIndex === \"number\") {\n ensureInjectableTarget(target, \"Inject parameter\");\n const ctor = target;\n const paramTokens =\n (Reflect.getMetadata(INJECT_PARAM_KEY, ctor) as Map<number, Identifier> | undefined) ||\n new Map<number, Identifier>();\n paramTokens.set(parameterIndex, token);\n Reflect.defineMetadata(INJECT_PARAM_KEY, paramTokens, ctor);\n return;\n }\n\n registerPropertyDependency(target, propertyKey, token, false);\n }) as PropertyDecorator & ParameterDecorator;\n }\n\n function LazyInject(token: Identifier): PropertyDecorator {\n return (target, propertyKey) => {\n registerPropertyDependency(target, propertyKey, token, true);\n };\n }\n\n return { Injectable, Inject, LazyInject };\n}\n"]}

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/types.ts","../src/container.ts","../src/decorators.ts"],"names":["Scope"],"mappings":";AAmBO,IAAK,QAAL,kBAAKA,WAAL;AACL,EAAAA,OAAA,eAAY;AACZ,EAAAA,OAAA,eAAY;AACZ,EAAAA,OAAA,aAAU;AACV,EAAAA,OAAA,aAAU;AACV,EAAAA,OAAA,cAAW;AALD,SAAAA;AAAA,GAAA;AAyHL,IAAM,2BAAN,cAAuC,MAAM;AAAA,EAClD,YACE,SACgB,YACA,SAChB;AACA,UAAM,OAAO;AAHG;AACA;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,0BAAN,cAAsC,yBAAyB;AAAA,EACpE,YAAY,YAAwB,SAA4B;AAC9D,UAAM,iBAAiB,kBAAkB,UAAU;AACnD,UAAM,YAAY,CAAC,GAAG,QAAQ,IAAI,EAAE,IAAI,iBAAiB;AACzD,UAAM,OAAO,UAAU,KAAK,MAAM;AAElC;AAAA,MACE,iCAAiC,IAAI,OAAO,cAAc;AAAA,MAC1D;AAAA,MACA;AAAA,IACF;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,8BAAN,cAA0C,yBAAyB;AAAA,EACxE,YAAY,YAAwB;AAClC,UAAM,OAAO,kBAAkB,UAAU;AAEzC,UAAM,yCAAyC,IAAI,IAAI,UAAU;AACjE,SAAK,OAAO;AAAA,EACd;AACF;AAGO,SAAS,kBAAkB,YAAgC;AAChE,MAAI,OAAO,eAAe,UAAU;AAClC,WAAO;AAAA,EACT;AACA,MAAI,OAAO,eAAe,UAAU;AAClC,WAAO,WAAW,SAAS;AAAA,EAC7B;AACA,SAAO,WAAW,QAAQ;AAC5B;AAGO,SAAS,YAAe,aAAgC;AAC7D,SAAO,OAAO,WAAW;AAC3B;;;ACrKO,IAAM,YAAN,MAAM,WAAgC;AAAA,EAU3C,YAAY,QAAqB;AATjC,SAAiB,WAAW,oBAAI,IAAyB;AACzD,SAAiB,YAAY,oBAAI,IAAyB;AAC1D,SAAiB,kBAAkB,oBAAI,IAGrC;AACF,SAAiB,WAAW,oBAAI,IAAe;AAI7C,QAAI,WAAW,QAAW;AACxB,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAAA;AAAA,EAGA,SACE,YACA,SACY;AACZ,UAAM,cAA0B;AAAA,MAC9B;AAAA,MACA,MAAM,CAAC;AAAA,MACP,GAAG;AAAA,IACL;AAEA,SAAK,SAAS,IAAI,YAA0B,WAAsB;AAClE,WAAO;AAAA,EACT;AAAA,EAEA,cACE,QACA,UAA+B,CAAC,GACpB;AACZ,UAAM,eAAe,KAAK,yBAAyB,QAAQ,KAAK;AAChE,UAAM,UAA2B;AAAA,MAC/B,MAAM;AAAA,MACN;AAAA,MACA,OAAO,QAAQ;AAAA,MACf,MAAM,QAAQ,QAAQ,CAAC;AAAA,MACvB,MAAM,QAAQ,QAAQ,CAAC;AAAA,MACvB,GAAI,aAAa,SAAS,IAAI,EAAE,OAAO,aAAa,IAAI,CAAC;AAAA,IAC3D;AAEA,SAAK,SAAS,IAAI,QAAsB,OAAkB;AAC1D,WAAO;AAAA,EACT;AAAA,EAEA,cACE,YACA,OACA,UAA+B,CAAC,GACpB;AACZ,UAAM,UAA2B;AAAA,MAC/B,MAAM;AAAA,MACN;AAAA,MACA,OAAO,QAAQ;AAAA,MACf,MAAM,QAAQ,QAAQ,CAAC;AAAA,IACzB;AAEA,SAAK,SAAS,IAAI,YAA0B,OAAkB;AAC9D,WAAO;AAAA,EACT;AAAA,EAEA,gBACE,YACA,SACA,UAA+B,CAAC,GACpB;AACZ,UAAM,UAA6B;AAAA,MACjC,MAAM;AAAA,MACN;AAAA,MACA,OAAO,QAAQ;AAAA,MACf,MAAM,QAAQ,QAAQ,CAAC;AAAA,IACzB;AAEA,SAAK,SAAS,IAAI,YAA0B,OAAkB;AAC9D,WAAO;AAAA,EACT;AAAA,EAEA,cACE,OACA,QACA,UAA+B,CAAC,GACpB;AACZ,UAAM,UAA2B;AAAA,MAC/B,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,OAAO,QAAQ;AAAA,MACf,MAAM,QAAQ,QAAQ,CAAC;AAAA,IACzB;AAEA,SAAK,SAAS,IAAI,OAAqB,OAAkB;AACzD,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,QAAW,YAA8B;AACvC,UAAM,UAA6B;AAAA,MACjC,MAAM,oBAAI,IAAI;AAAA,MACd,OAAO;AAAA,MACP,UAAU;AAAA,IACZ;AAEA,WAAO,KAAK,mBAAmB,YAA0B,OAAO;AAAA,EAClE;AAAA,EAEA,WAAc,YAAgC;AAC5C,UAAM,UAAe,CAAC;AAGtB,eAAW,CAAC,KAAK,OAAO,KAAK,KAAK,SAAS,QAAQ,GAAG;AACpD,UACE,KAAK,kBAAkB,KAAK,UAAwB,KACpD,KAAK,sBAAsB,SAAS,UAAwB,GAC5D;AACA,YAAI;AACF,gBAAM,WAAW,KAAK,QAAQ,GAAoB;AAClD,kBAAQ,KAAK,QAAQ;AAAA,QACvB,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAGA,QAAI,KAAK,QAAQ;AACf,cAAQ,KAAK,GAAG,KAAK,OAAO,WAAW,UAAU,CAAC;AAAA,IACpD;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,WAAc,YAA0C;AACtD,QAAI;AACF,aAAO,KAAK,QAAQ,UAAU;AAAA,IAChC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGA,aAAgB,YAAoC;AAClD,WACE,KAAK,SAAS,IAAI,UAAwB,MACzC,KAAK,QAAQ,aAAa,UAAU,KAAK;AAAA,EAE9C;AAAA,EAEA,WAAc,YAAmD;AAC/D,UAAM,UAAU,KAAK,SAAS,IAAI,UAAwB;AAG1D,WAAO,WAAW,KAAK,QAAQ,WAAW,UAAU;AAAA,EACtD;AAAA;AAAA,EAGA,cAA0B;AACxB,UAAM,QAAQ,IAAI,WAAU,IAAI;AAChC,SAAK,SAAS,IAAI,KAAK;AACvB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,aAAgB,KAAkB;AAChC,UAAM,UAAe,CAAC;AAEtB,eAAW,CAAC,YAAY,OAAO,KAAK,KAAK,SAAS,QAAQ,GAAG;AAC3D,UAAI,QAAQ,KAAK,SAAS,GAAG,GAAG;AAC9B,YAAI;AACF,gBAAM,WAAW,KAAK,QAAQ,UAA2B;AACzD,kBAAQ,KAAK,QAAQ;AAAA,QACvB,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,QAAQ;AACf,cAAQ,KAAK,GAAG,KAAK,OAAO,aAAgB,GAAG,CAAC;AAAA,IAClD;AAEA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,UAAyB;AAE7B,UAAM,QAAQ,IAAI,CAAC,GAAG,KAAK,QAAQ,EAAE,IAAI,CAAC,UAAU,MAAM,QAAQ,CAAC,CAAC;AACpE,SAAK,SAAS,MAAM;AAGpB,eAAW,YAAY,KAAK,UAAU,OAAO,GAAG;AAC9C,UAAI,YAAY,OAAO,aAAa,YAAY,aAAa,UAAU;AACrE,cAAM,aAAa;AACnB,cAAM,WAAW,QAAQ;AAAA,MAC3B;AAAA,IACF;AAGA,SAAK,UAAU,MAAM;AACrB,SAAK,gBAAgB,MAAM;AAC3B,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA;AAAA,EAGQ,mBACN,YACA,SACG;AAEH,QAAI,QAAQ,KAAK,IAAI,UAAU,GAAG;AAChC,YAAM,IAAI,wBAAwB,YAAY,OAAO;AAAA,IACvD;AAEA,QAAI,QAAQ,SAAS,QAAQ,UAAU;AACrC,YAAM,IAAI;AAAA,QACR,sCAAsC,QAAQ,QAAQ;AAAA,MACxD;AAAA,IACF;AAGA,UAAM,UAAU,KAAK,mBAAmB,UAAU;AAClD,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,4BAA4B,UAAU;AAAA,IAClD;AAGA,QAAI,QAAQ,yCAA6B,KAAK,UAAU,IAAI,UAAU,GAAG;AACvE,aAAO,KAAK,UAAU,IAAI,UAAU;AAAA,IACtC;AAGA,UAAM,cAAc,KAAK,eAAe,QAAQ,KAAK;AACrD,QAAI,aAAa,IAAI,UAAU,GAAG;AAChC,aAAO,YAAY,IAAI,UAAU;AAAA,IACnC;AAGA,YAAQ,KAAK,IAAI,UAAU;AAC3B,YAAQ;AAER,QAAI;AAEF,YAAM,WAAW,KAAK,eAAe,SAAS,OAAO;AAGrD,UAAI,QAAQ,uCAA2B;AACrC,aAAK,UAAU,IAAI,YAAY,QAAQ;AAAA,MACzC,WAAW,aAAa;AACtB,oBAAY,IAAI,YAAY,QAAQ;AAAA,MACtC;AAEA,aAAO;AAAA,IACT,UAAE;AAEA,cAAQ,KAAK,OAAO,UAAU;AAC9B,cAAQ;AAAA,IACV;AAAA,EACF;AAAA,EAEQ,mBACN,YACwB;AACxB,UAAM,UAAU,KAAK,SAAS,IAAI,UAAwB;AAC1D,WAAQ,WACL,KAAK,QAAsB,qBAAqB,UAAU;AAAA,EAG/D;AAAA,EAEQ,eACN,SACA,SACG;AACH,YAAQ,QAAQ,MAAM;AAAA,MACpB,KAAK;AACH,eAAO,QAAQ;AAAA,MAEjB,KAAK,WAAW;AAEd,cAAM,wBAAwB,KAAK,4BAA4B,OAAO;AACtE,eAAO,QAAQ,QAAQ,qBAAqB;AAAA,MAC9C;AAAA,MAEA,KAAK;AACH,eAAO,KAAK;AAAA,UACV,QAAQ;AAAA,UACR;AAAA,QACF;AAAA,MAEF,KAAK,SAAS;AACZ,YAAI,OAAO,QAAQ,WAAW,YAAY;AACxC,cAAI,KAAK,cAAc,QAAQ,MAAM,GAAG;AACtC,mBAAO,KAAK;AAAA,cACV,QAAQ;AAAA,cACR;AAAA,YACF;AAAA,UACF,OAAO;AAEL,kBAAM,wBACJ,KAAK,4BAA4B,OAAO;AAC1C,mBAAQ,QAAQ;AAAA,cACd;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,cAAM,IAAI;AAAA,UACR,oCAAoC,QAAQ,MAAM,SAAS,CAAC;AAAA,QAC9D;AAAA,MACF;AAAA,MAEA;AACE,cAAM,IAAI,MAAM,yBAA0B,QAAoB,IAAI,EAAE;AAAA,IACxE;AAAA,EACF;AAAA,EAEQ,iBACN,aACA,SACG;AACH,UAAM,UAAU,KAAK,mBAAmB,WAAW;AACnD,QAAI,CAAC,WAAW,QAAQ,SAAS,SAAS;AACxC,YAAM,IAAI;AAAA,QACR,2CAA2C,YAAY,IAAI;AAAA,MAC7D;AAAA,IACF;AAGA,UAAM,mBAAmB,QAAQ,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ;AACxD,aAAO,KAAK,mBAAmB,KAAK,OAAO;AAAA,IAC7C,CAAC;AAGD,UAAM,WAAW,IAAI,YAAY,GAAG,eAAe;AAGnD,QAAI,QAAQ,OAAO;AACjB,iBAAW,QAAQ,QAAQ,OAAO;AAChC,YAAI,KAAK,MAAM;AACb,iBAAO,eAAe,UAAU,KAAK,UAAU;AAAA,YAC7C,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,KAAK,MAAM;AACT,oBAAM,WAAW,KAAK,mBAAmB,KAAK,OAAO,OAAO;AAC5D,qBAAO,eAAe,UAAU,KAAK,UAAU;AAAA,gBAC7C,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,UAAU;AAAA,gBACV,OAAO;AAAA,cACT,CAAC;AACD,qBAAO;AAAA,YACT;AAAA,UACF,CAAC;AACD;AAAA,QACF;AAGA,QAAC,SAAiB,KAAK,QAAQ,IAAI,KAAK;AAAA,UACtC,KAAK;AAAA,UACL;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,IAAgC;AACpD,WAAO,OAAO,OAAO,cAAc,GAAG,cAAc;AAAA,EACtD;AAAA,EAEQ,4BAA4B,SAAwC;AAC1E,WAAO;AAAA,MACL,UAAU,CAAI,YAA2B,YACvC,KAAK,SAAS,YAAY,OAAO;AAAA,MACnC,eAAe,CACb,QACA,YACG,KAAK,cAAc,QAAQ,OAAO;AAAA,MACvC,eAAe,CACb,YACA,OACA,YACG,KAAK,cAAc,YAAY,OAAO,OAAO;AAAA,MAClD,iBAAiB,CACf,YACA,SACA,YACG,KAAK,gBAAgB,YAAY,SAAS,OAAO;AAAA,MACtD,eAAe,CACb,OACA,QACA,YACG,KAAK,cAAc,OAAO,QAAQ,OAAO;AAAA,MAE9C,SAAS,CAAI,eAAiC;AAC5C,eAAO,KAAK,mBAAmB,YAA0B,OAAO;AAAA,MAClE;AAAA,MAEA,YAAY,CAAI,eAA8B,KAAK,WAAW,UAAU;AAAA,MACxE,YAAY,CAAI,eAA8B,KAAK,WAAW,UAAU;AAAA,MACxE,cAAc,CAAI,eAChB,KAAK,aAAa,UAAU;AAAA,MAC9B,YAAY,CAAI,eAA8B,KAAK,WAAW,UAAU;AAAA,MACxE,aAAa,MAAM,KAAK,YAAY;AAAA,MACpC,cAAc,CAAI,QAAgB,KAAK,aAAgB,GAAG;AAAA,MAC1D,SAAS,MAAM,KAAK,QAAQ;AAAA,IAC9B;AAAA,EACF;AAAA,EAEQ,eAAe,OAAoD;AACzE,QAAI,yCAA6B,uCAA2B;AAC1D,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,KAAK,gBAAgB,IAAI,KAAK,GAAG;AACpC,WAAK,gBAAgB,IAAI,OAAO,oBAAI,IAAI,CAAC;AAAA,IAC3C;AAEA,WAAO,KAAK,gBAAgB,IAAI,KAAK;AAAA,EACvC;AAAA,EAEQ,kBAAkB,GAAe,GAAwB;AAC/D,WAAO,MAAM;AAAA,EACf;AAAA,EAEQ,sBACN,SACA,YACS;AACT,QAAI,OAAO,eAAe,UAAU;AAClC,aAAO;AAAA,IACT;AACA,WAAO,QAAQ,KAAK,SAAS,UAAU;AAAA,EACzC;AAAA,EAEQ,yBACN,OACe;AACf,QAAI,CAAC,OAAO;AACV,aAAO,CAAC;AAAA,IACV;AAEA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,aAAO,MAAM,IAAI,CAAC,UAAU,EAAE,GAAG,KAAK,EAAE;AAAA,IAC1C;AAEA,UAAM,MAAM;AACZ,UAAM,aAA4B,CAAC;AACnC,UAAM,gBAAgB;AAEtB,eAAW,OAAO,QAAQ,QAAQ,aAAa,GAAG;AAChD,YAAM,aAAa,cAAc,GAAkB;AACnD,UAAI,CAAC,YAAY;AACf;AAAA,MACF;AAEA,UAAI,CAAC,KAAK,0BAA0B,UAAU,GAAG;AAC/C,mBAAW,KAAK;AAAA,UACd,UAAU;AAAA,UACV,OAAO;AAAA,QACT,CAAC;AACD;AAAA,MACF;AAEA,iBAAW,KAAK;AAAA,QACd,UAAU;AAAA,QACV,OAAO,WAAW;AAAA,QAClB,GAAI,WAAW,OAAO,EAAE,MAAM,WAAW,KAAK,IAAI,CAAC;AAAA,MACrD,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,0BACN,YACqD;AACrD,WAAO,OAAO,eAAe,YAAY,eAAe,QAAQ,WAAW;AAAA,EAC7E;AACF;AAGO,SAAS,kBAA8B;AAC5C,SAAO,IAAI,UAAU;AACvB;AAEO,SAAS,qBAAqB,QAAgC;AACnE,SAAO,OAAO,YAAY;AAC5B;;;ACpgBA,OAAO;AAKP,IAAM,mBAAmB;AACzB,IAAM,kBAAkB;AASxB,SAAS,uBAAuB,OAAgB,WAAsD;AACpG,MAAI,OAAO,UAAU,YAAY;AAC/B,UAAM,IAAI;AAAA,MACR,IAAI,SAAS,2CAA2C,OAAO,KAAK;AAAA,IACtE;AAAA,EACF;AACF;AAQO,SAAS,iBAAiB,WAAuB;AACtD,WAAS,2BACP,QACA,aACA,OACA,MACM;AACN,UAAM,WACH,QAAQ,YAAY,iBAAiB,MAAM,KAAmC,CAAC;AAClF,UAAM,WAAW,SAAS,OAAO,CAAC,QAAQ,IAAI,aAAa,WAAW;AACtE,aAAS,KAAK,EAAE,UAAU,aAAa,OAAO,KAAK,CAAC;AACpD,YAAQ,eAAe,iBAAiB,UAAU,MAAM;AAAA,EAC1D;AAOA,WAAS,WAAW,UAA6B,CAAC,GAAmB;AACnE,WAAO,CAAC,WAAW;AACjB,6BAAuB,QAAQ,YAAY;AAC3C,YAAM,OAAO;AAEb,YAAM,OAAO,QAAQ,QAAQ,CAAC;AAG9B,YAAM,QACH,QAAQ,YAAY,iBAAiB,KAAK,SAAS,KAAmC,CAAC;AAI1F,YAAM,aAAa;AACnB,YAAM,UAAU;AAAA,QACd,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,OAAO,QAAQ;AAAA,QACf,MAAM,CAAC;AAAA,QACP;AAAA,QACA;AAAA,MACF;AAEA,gBAAU,SAAS,YAAY,OAAO;AAAA,IACxC;AAAA,EACF;AAOA,WAAS,OAAO,OAA2D;AACzE,WAAQ,IAAI,SAA6C;AACvD,YAAM,CAAC,QAAQ,aAAa,cAAc,IAAI;AAE9C,UAAI,OAAO,mBAAmB,UAAU;AACtC,+BAAuB,QAAQ,kBAAkB;AACjD,cAAM,OAAO;AACb,cAAM,cACH,QAAQ,YAAY,kBAAkB,IAAI,KAC3C,oBAAI,IAAwB;AAC9B,oBAAY,IAAI,gBAAgB,KAAK;AACrC,gBAAQ,eAAe,kBAAkB,aAAa,IAAI;AAC1D;AAAA,MACF;AAEA,iCAA2B,QAAQ,aAAa,OAAO,KAAK;AAAA,IAC9D;AAAA,EACF;AAEA,WAAS,WAAW,OAAsC;AACxD,WAAO,CAAC,QAAQ,gBAAgB;AAC9B,iCAA2B,QAAQ,aAAa,OAAO,IAAI;AAAA,IAC7D;AAAA,EACF;AAEA,SAAO,EAAE,YAAY,QAAQ,WAAW;AAC1C","sourcesContent":["/**\n * Core types for the dependency injection framework\n */\n\n// Constructor type for classes\nexport interface Constructor<T = object> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- constructors often declare specific dependency types; we need a permissive arg signature\n new (...args: any[]): T;\n name?: string;\n prototype?: T;\n}\n\n// Token type for symbolic references\nexport type Token<T = object> = symbol & { __type?: T };\n\n// Identifier can be a constructor, token, or string\nexport type Identifier<T = object> = Constructor<T> | Token<T> | string;\n\n// Scope definitions\nexport enum Scope {\n SINGLETON = \"singleton\",\n TRANSIENT = \"transient\",\n REQUEST = \"request\",\n SESSION = \"session\",\n SCENARIO = \"scenario\",\n}\n\n// Registration options\nexport type PropertyInjectionDescriptor =\n | Identifier\n | {\n readonly token: Identifier;\n readonly lazy?: boolean;\n };\n\nexport type PropertyInjectionMap = {\n readonly [Key in string | number | symbol]?: PropertyInjectionDescriptor;\n};\n\nexport interface RegistrationOptions {\n scope?: Scope;\n tags?: string[];\n factory?: boolean;\n deps?: Identifier[];\n props?: PropertyDep[] | PropertyInjectionMap;\n}\n\n// Binding types\nexport interface ClassBinding<T = object> {\n type: \"class\";\n target: Constructor<T>;\n scope: Scope;\n tags: string[];\n deps?: Identifier[];\n props?: PropertyDep[];\n}\n\nexport interface ValueBinding<T = object> {\n type: \"value\";\n value: T;\n scope: Scope;\n tags: string[];\n}\n\nexport interface FactoryBinding<T = object> {\n type: \"factory\";\n factory: (container: IContainer) => T;\n scope: Scope;\n tags: string[];\n}\n\nexport interface TokenBinding<T = object> {\n type: \"token\";\n token: Token<T>;\n target: Constructor<T> | ((container: IContainer) => T);\n scope: Scope;\n tags: string[];\n}\n\nexport type Binding<T = object> =\n | ClassBinding<T>\n | ValueBinding<T>\n | FactoryBinding<T>\n | TokenBinding<T>;\n\n// Resolution context for circular dependency detection\nexport interface ResolutionContext {\n path: Set<Identifier>;\n depth: number;\n maxDepth: number;\n}\n\n// Container interface\nexport interface IContainer {\n // Registration methods\n register<T>(\n identifier: Identifier<T>,\n binding: Partial<Binding<T>>\n ): IContainer;\n registerClass<T>(\n target: Constructor<T>,\n options?: RegistrationOptions\n ): IContainer;\n registerValue<T>(\n identifier: Identifier<T>,\n value: T,\n options?: RegistrationOptions\n ): IContainer;\n registerFactory<T>(\n identifier: Identifier<T>,\n factory: (container: IContainer) => T,\n options?: RegistrationOptions\n ): IContainer;\n registerToken<T>(\n token: Token<T>,\n target: Constructor<T> | ((container: IContainer) => T),\n options?: RegistrationOptions\n ): IContainer;\n\n // Resolution methods\n resolve<T>(identifier: Identifier<T>): T;\n resolveAll<T>(identifier: Identifier<T>): T[];\n tryResolve<T>(identifier: Identifier<T>): T | undefined;\n\n // Introspection\n isRegistered<T>(identifier: Identifier<T>): boolean;\n getBinding<T>(identifier: Identifier<T>): Binding<T> | undefined;\n\n // Container hierarchy\n createChild(): IContainer;\n parent?: IContainer;\n\n // Lifecycle\n dispose(): Promise<void>;\n\n // Tagged resolution\n resolveByTag<T>(tag: string): T[];\n}\n\n// Dependency injection errors\nexport class DependencyInjectionError extends Error {\n constructor(\n message: string,\n public readonly identifier?: Identifier,\n public readonly context?: ResolutionContext\n ) {\n super(message);\n this.name = \"DependencyInjectionError\";\n }\n}\n\nexport class CircularDependencyError extends DependencyInjectionError {\n constructor(identifier: Identifier, context: ResolutionContext) {\n const identifierName = getIdentifierName(identifier);\n const pathNames = [...context.path].map(getIdentifierName);\n const path = pathNames.join(\" -> \");\n\n super(\n `Circular dependency detected: ${path} -> ${identifierName}`,\n identifier,\n context\n );\n this.name = \"CircularDependencyError\";\n }\n}\n\nexport class UnregisteredDependencyError extends DependencyInjectionError {\n constructor(identifier: Identifier) {\n const name = getIdentifierName(identifier);\n\n super(`No registration found for identifier: ${name}`, identifier);\n this.name = \"UnregisteredDependencyError\";\n }\n}\n\n// Helper function to get identifier name\nexport function getIdentifierName(identifier: Identifier): string {\n if (typeof identifier === \"string\") {\n return identifier;\n }\n if (typeof identifier === \"symbol\") {\n return identifier.toString();\n }\n return identifier.name || \"anonymous\";\n}\n\n// Helper to create tokens\nexport function createToken<T>(description?: string): Token<T> {\n return Symbol(description) as Token<T>;\n}\n\nexport interface PropertyDep {\n property: string | symbol;\n token: Identifier;\n lazy?: boolean;\n}\n","/**\n * Core container implementation for dependency injection\n */\n\nimport {\n IContainer,\n Identifier,\n Constructor,\n Token,\n Binding,\n ClassBinding,\n ValueBinding,\n FactoryBinding,\n TokenBinding,\n Scope,\n RegistrationOptions,\n PropertyDep,\n PropertyInjectionDescriptor,\n PropertyInjectionMap,\n ResolutionContext,\n CircularDependencyError,\n UnregisteredDependencyError,\n} from \"./types\";\n\nexport class Container implements IContainer {\n private readonly bindings = new Map<Identifier, Binding>();\n private readonly instances = new Map<Identifier, unknown>();\n private readonly scopedInstances = new Map<\n string,\n Map<Identifier, unknown>\n >();\n private readonly children = new Set<Container>();\n declare public readonly parent?: IContainer;\n\n constructor(parent?: IContainer) {\n if (parent !== undefined) {\n this.parent = parent;\n }\n }\n\n // Registration methods\n register<T>(\n identifier: Identifier<T>,\n binding: Partial<Binding<T>>\n ): IContainer {\n const fullBinding: Binding<T> = {\n scope: Scope.TRANSIENT,\n tags: [],\n ...binding,\n } as Binding<T>;\n\n this.bindings.set(identifier as Identifier, fullBinding as Binding);\n return this;\n }\n\n registerClass<T>(\n target: Constructor<T>,\n options: RegistrationOptions = {}\n ): IContainer {\n const propertyDeps = this.normalizePropertyOptions(options.props);\n const binding: ClassBinding<T> = {\n type: \"class\",\n target,\n scope: options.scope || Scope.TRANSIENT,\n tags: options.tags || [],\n deps: options.deps || [],\n ...(propertyDeps.length > 0 ? { props: propertyDeps } : {}),\n };\n\n this.bindings.set(target as Identifier, binding as Binding);\n return this;\n }\n\n registerValue<T>(\n identifier: Identifier<T>,\n value: T,\n options: RegistrationOptions = {}\n ): IContainer {\n const binding: ValueBinding<T> = {\n type: \"value\",\n value,\n scope: options.scope || Scope.SINGLETON,\n tags: options.tags || [],\n };\n\n this.bindings.set(identifier as Identifier, binding as Binding);\n return this;\n }\n\n registerFactory<T>(\n identifier: Identifier<T>,\n factory: (container: IContainer) => T,\n options: RegistrationOptions = {}\n ): IContainer {\n const binding: FactoryBinding<T> = {\n type: \"factory\",\n factory,\n scope: options.scope || Scope.TRANSIENT,\n tags: options.tags || [],\n };\n\n this.bindings.set(identifier as Identifier, binding as Binding);\n return this;\n }\n\n registerToken<T>(\n token: Token<T>,\n target: Constructor<T> | ((container: IContainer) => T),\n options: RegistrationOptions = {}\n ): IContainer {\n const binding: TokenBinding<T> = {\n type: \"token\",\n token,\n target,\n scope: options.scope || Scope.TRANSIENT,\n tags: options.tags || [],\n };\n\n this.bindings.set(token as Identifier, binding as Binding);\n return this;\n }\n\n // Resolution methods\n resolve<T>(identifier: Identifier<T>): T {\n const context: ResolutionContext = {\n path: new Set(),\n depth: 0,\n maxDepth: 50,\n };\n\n return this.resolveWithContext(identifier as Identifier, context) as T;\n }\n\n resolveAll<T>(identifier: Identifier<T>): T[] {\n const results: T[] = [];\n\n // Collect from this container\n for (const [key, binding] of this.bindings.entries()) {\n if (\n this.identifierMatches(key, identifier as Identifier) ||\n this.bindingHasMatchingTag(binding, identifier as Identifier)\n ) {\n try {\n const instance = this.resolve(key as Identifier<T>);\n results.push(instance);\n } catch {\n // Skip failed resolutions\n }\n }\n }\n\n // Collect from parent\n if (this.parent) {\n results.push(...this.parent.resolveAll(identifier));\n }\n\n return results;\n }\n\n tryResolve<T>(identifier: Identifier<T>): T | undefined {\n try {\n return this.resolve(identifier);\n } catch {\n return undefined;\n }\n }\n\n // Introspection\n isRegistered<T>(identifier: Identifier<T>): boolean {\n return (\n this.bindings.has(identifier as Identifier) ||\n (this.parent?.isRegistered(identifier) ?? false)\n );\n }\n\n getBinding<T>(identifier: Identifier<T>): Binding<T> | undefined {\n const binding = this.bindings.get(identifier as Identifier) as\n | Binding<T>\n | undefined;\n return binding || this.parent?.getBinding(identifier);\n }\n\n // Container hierarchy\n createChild(): IContainer {\n const child = new Container(this);\n this.children.add(child);\n return child;\n }\n\n // Tagged resolution\n resolveByTag<T>(tag: string): T[] {\n const results: T[] = [];\n\n for (const [identifier, binding] of this.bindings.entries()) {\n if (binding.tags.includes(tag)) {\n try {\n const instance = this.resolve(identifier as Identifier<T>);\n results.push(instance);\n } catch {\n // Skip failed resolutions\n }\n }\n }\n\n if (this.parent) {\n results.push(...this.parent.resolveByTag<T>(tag));\n }\n\n return results;\n }\n\n // Lifecycle\n async dispose(): Promise<void> {\n // Dispose children first\n await Promise.all([...this.children].map((child) => child.dispose()));\n this.children.clear();\n\n // Dispose instances that implement disposal\n for (const instance of this.instances.values()) {\n if (instance && typeof instance === \"object\" && \"dispose\" in instance) {\n const disposable = instance as { dispose(): Promise<void> | void };\n await disposable.dispose();\n }\n }\n\n // Clear all caches\n this.instances.clear();\n this.scopedInstances.clear();\n this.bindings.clear();\n }\n\n // Private resolution implementation\n private resolveWithContext<T>(\n identifier: Identifier,\n context: ResolutionContext\n ): T {\n // Check for circular dependencies\n if (context.path.has(identifier)) {\n throw new CircularDependencyError(identifier, context);\n }\n\n if (context.depth >= context.maxDepth) {\n throw new Error(\n `Maximum resolution depth exceeded (${context.maxDepth})`\n );\n }\n\n // Get binding first to check scope\n const binding = this.getBindingInternal(identifier);\n if (!binding) {\n throw new UnregisteredDependencyError(identifier);\n }\n\n // Check for cached instances based on scope\n if (binding.scope === Scope.SINGLETON && this.instances.has(identifier)) {\n return this.instances.get(identifier) as T;\n }\n\n // Check scoped cache for other scopes\n const scopedCache = this.getScopedCache(binding.scope);\n if (scopedCache?.has(identifier)) {\n return scopedCache.get(identifier) as T;\n }\n\n // Add to resolution path\n context.path.add(identifier);\n context.depth++;\n\n try {\n // Create instance\n const instance = this.createInstance(binding, context) as T;\n\n // Cache based on scope\n if (binding.scope === Scope.SINGLETON) {\n this.instances.set(identifier, instance);\n } else if (scopedCache) {\n scopedCache.set(identifier, instance);\n }\n\n return instance;\n } finally {\n // Clean up resolution path\n context.path.delete(identifier);\n context.depth--;\n }\n }\n\n private getBindingInternal<T>(\n identifier: Identifier<T>\n ): Binding<T> | undefined {\n const binding = this.bindings.get(identifier as Identifier);\n return (binding ||\n (this.parent as Container)?.getBindingInternal?.(identifier)) as\n | Binding<T>\n | undefined;\n }\n\n private createInstance<T>(\n binding: Binding<T>,\n context: ResolutionContext\n ): T {\n switch (binding.type) {\n case \"value\":\n return binding.value;\n\n case \"factory\": {\n // Create a context-aware container for factories\n const contextAwareContainer = this.createContextAwareContainer(context);\n return binding.factory(contextAwareContainer);\n }\n\n case \"class\":\n return this.instantiateClass(\n binding.target as unknown as Constructor<T & object>,\n context\n ) as T;\n\n case \"token\": {\n if (typeof binding.target === \"function\") {\n if (this.isConstructor(binding.target)) {\n return this.instantiateClass(\n binding.target as Constructor<T & object>,\n context\n );\n } else {\n // Create a context-aware container for token factories\n const contextAwareContainer =\n this.createContextAwareContainer(context);\n return (binding.target as (container: IContainer) => T)(\n contextAwareContainer\n );\n }\n }\n throw new Error(\n `Invalid token binding target for ${binding.token.toString()}`\n );\n }\n\n default:\n throw new Error(`Unknown binding type: ${(binding as Binding).type}`);\n }\n }\n\n private instantiateClass<T extends object>(\n constructor: Constructor<T>,\n context: ResolutionContext\n ): T {\n const binding = this.getBindingInternal(constructor) as ClassBinding<T>;\n if (!binding || binding.type !== \"class\") {\n throw new Error(\n `No class binding found for constructor: ${constructor.name}`\n );\n }\n\n // Resolve constructor dependencies from the 'deps' array\n const constructorArgs = (binding.deps || []).map((dep) => {\n return this.resolveWithContext(dep, context);\n });\n\n // Create the instance\n const instance = new constructor(...constructorArgs);\n\n // Resolve and set property dependencies from the 'props' array\n if (binding.props) {\n for (const prop of binding.props) {\n if (prop.lazy) {\n Object.defineProperty(instance, prop.property, {\n configurable: true,\n enumerable: true,\n get: () => {\n const resolved = this.resolveWithContext(prop.token, context);\n Object.defineProperty(instance, prop.property, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: resolved,\n });\n return resolved;\n },\n });\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (instance as any)[prop.property] = this.resolveWithContext(\n prop.token,\n context\n );\n }\n }\n\n return instance;\n }\n\n private isConstructor(fn: unknown): fn is Constructor {\n return typeof fn === \"function\" && fn.prototype !== undefined;\n }\n\n private createContextAwareContainer(context: ResolutionContext): IContainer {\n return {\n register: <T>(identifier: Identifier<T>, binding: Partial<Binding<T>>) =>\n this.register(identifier, binding),\n registerClass: <T>(\n target: Constructor<T>,\n options?: RegistrationOptions\n ) => this.registerClass(target, options),\n registerValue: <T>(\n identifier: Identifier<T>,\n value: T,\n options?: RegistrationOptions\n ) => this.registerValue(identifier, value, options),\n registerFactory: <T>(\n identifier: Identifier<T>,\n factory: (container: IContainer) => T,\n options?: RegistrationOptions\n ) => this.registerFactory(identifier, factory, options),\n registerToken: <T>(\n token: Token<T>,\n target: Constructor<T> | ((container: IContainer) => T),\n options?: RegistrationOptions\n ) => this.registerToken(token, target, options),\n\n resolve: <T>(identifier: Identifier<T>): T => {\n return this.resolveWithContext(identifier as Identifier, context) as T;\n },\n\n resolveAll: <T>(identifier: Identifier<T>) => this.resolveAll(identifier),\n tryResolve: <T>(identifier: Identifier<T>) => this.tryResolve(identifier),\n isRegistered: <T>(identifier: Identifier<T>) =>\n this.isRegistered(identifier),\n getBinding: <T>(identifier: Identifier<T>) => this.getBinding(identifier),\n createChild: () => this.createChild(),\n resolveByTag: <T>(tag: string) => this.resolveByTag<T>(tag),\n dispose: () => this.dispose(),\n };\n }\n\n private getScopedCache(scope: Scope): Map<Identifier, unknown> | undefined {\n if (scope === Scope.SINGLETON || scope === Scope.TRANSIENT) {\n return undefined; // Singletons use global cache, transients are never cached\n }\n\n if (!this.scopedInstances.has(scope)) {\n this.scopedInstances.set(scope, new Map());\n }\n\n return this.scopedInstances.get(scope);\n }\n\n private identifierMatches(a: Identifier, b: Identifier): boolean {\n return a === b;\n }\n\n private bindingHasMatchingTag(\n binding: Binding,\n identifier: Identifier\n ): boolean {\n if (typeof identifier !== \"string\") {\n return false;\n }\n return binding.tags.includes(identifier);\n }\n\n private normalizePropertyOptions(\n props?: RegistrationOptions[\"props\"]\n ): PropertyDep[] {\n if (!props) {\n return [];\n }\n\n if (Array.isArray(props)) {\n return props.map((prop) => ({ ...prop }));\n }\n\n const map = props as PropertyInjectionMap;\n const normalized: PropertyDep[] = [];\n const descriptorMap = map as Record<PropertyKey, PropertyInjectionDescriptor>;\n\n for (const key of Reflect.ownKeys(descriptorMap)) {\n const descriptor = descriptorMap[key as PropertyKey];\n if (!descriptor) {\n continue;\n }\n\n if (!this.isPropertyInjectionObject(descriptor)) {\n normalized.push({\n property: key,\n token: descriptor as Identifier,\n });\n continue;\n }\n\n normalized.push({\n property: key,\n token: descriptor.token,\n ...(descriptor.lazy ? { lazy: descriptor.lazy } : {}),\n });\n }\n\n return normalized;\n }\n\n private isPropertyInjectionObject(\n descriptor: PropertyInjectionDescriptor\n ): descriptor is { token: Identifier; lazy?: boolean } {\n return typeof descriptor === \"object\" && descriptor !== null && \"token\" in descriptor;\n }\n}\n\n// Export convenience functions\nexport function createContainer(): IContainer {\n return new Container();\n}\n\nexport function createChildContainer(parent: IContainer): IContainer {\n return parent.createChild();\n}","import \"reflect-metadata\";\nimport { Scope } from \"./types\";\nimport type { Identifier, PropertyDep, IContainer } from \"./types\";\n\n// Define unique keys for storing metadata via reflect-metadata\nconst INJECT_PARAM_KEY = \"autometa:inject_param\";\nconst INJECT_PROP_KEY = \"autometa:inject_prop\";\n\nexport interface InjectableOptions {\n scope?: Scope;\n deps?: Identifier[];\n}\n\ntype InjectableTarget = new (...args: unknown[]) => object;\n\nfunction ensureInjectableTarget(value: unknown, decorator: string): asserts value is InjectableTarget {\n if (typeof value !== \"function\") {\n throw new TypeError(\n `[${decorator}] can only be used on classes. Received ${typeof value}.`\n );\n }\n}\n\n/**\n * Creates a set of decorators bound to a specific container instance.\n * This factory pattern ensures the decorators are decoupled from a global\n * container and can be used with multiple, separate containers.\n * @param container The container instance to which the decorators will register classes.\n */\nexport function createDecorators(container: IContainer) {\n function registerPropertyDependency(\n target: object,\n propertyKey: string | symbol,\n token: Identifier,\n lazy: boolean\n ): void {\n const existing =\n (Reflect.getMetadata(INJECT_PROP_KEY, target) as PropertyDep[] | undefined) || [];\n const filtered = existing.filter((dep) => dep.property !== propertyKey);\n filtered.push({ property: propertyKey, token, lazy });\n Reflect.defineMetadata(INJECT_PROP_KEY, filtered, target);\n }\n\n /**\n * A class decorator that marks a class as available for injection.\n * It gathers all dependency metadata from `@Inject` decorators and\n * `reflect-metadata` and registers the class with the container.\n */\n function Injectable(options: InjectableOptions = {}): ClassDecorator {\n return (target) => {\n ensureInjectableTarget(target, \"Injectable\");\n const ctor = target;\n // --- Constructor Injection ---\n const deps = options.deps || [];\n\n // --- Property Injection ---\n const props =\n (Reflect.getMetadata(INJECT_PROP_KEY, ctor.prototype) as PropertyDep[] | undefined) || [];\n\n // --- Registration ---\n // The container's `register` method expects an identifier and a binding object.\n const identifier = ctor as unknown as Identifier;\n const binding = {\n type: \"class\" as const,\n target: ctor,\n scope: options.scope || Scope.TRANSIENT,\n tags: [],\n deps,\n props,\n };\n\n container.register(identifier, binding);\n };\n }\n\n /**\n * A decorator that can be used on constructor parameters or class properties\n * to specify a dependency token.\n * @param token The token representing the dependency to inject.\n */\n function Inject(token: Identifier): PropertyDecorator & ParameterDecorator {\n return ((...args: [object, string | symbol, number?]) => {\n const [target, propertyKey, parameterIndex] = args;\n\n if (typeof parameterIndex === \"number\") {\n ensureInjectableTarget(target, \"Inject parameter\");\n const ctor = target;\n const paramTokens =\n (Reflect.getMetadata(INJECT_PARAM_KEY, ctor) as Map<number, Identifier> | undefined) ||\n new Map<number, Identifier>();\n paramTokens.set(parameterIndex, token);\n Reflect.defineMetadata(INJECT_PARAM_KEY, paramTokens, ctor);\n return;\n }\n\n registerPropertyDependency(target, propertyKey, token, false);\n }) as PropertyDecorator & ParameterDecorator;\n }\n\n function LazyInject(token: Identifier): PropertyDecorator {\n return (target, propertyKey) => {\n registerPropertyDependency(target, propertyKey, token, true);\n };\n }\n\n return { Injectable, Inject, LazyInject };\n}\n"]}
{"version":3,"sources":["../src/types.ts","../src/container.ts","../src/decorators.ts"],"names":["Scope"],"mappings":"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","sourcesContent":["/**\n * Core types for the dependency injection framework\n */\n\n// Constructor type for classes\nexport interface Constructor<T = object> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- constructors often declare specific dependency types; we need a permissive arg signature\n new (...args: any[]): T;\n name?: string;\n prototype?: T;\n}\n\n// Token type for symbolic references\nexport type Token<T = object> = symbol & { __type?: T };\n\n// Identifier can be a constructor, token, or string\nexport type Identifier<T = object> = Constructor<T> | Token<T> | string;\n\n// Scope definitions\nexport enum Scope {\n SINGLETON = \"singleton\",\n TRANSIENT = \"transient\",\n REQUEST = \"request\",\n SESSION = \"session\",\n SCENARIO = \"scenario\",\n}\n\n// Registration options\nexport type PropertyInjectionDescriptor =\n | Identifier\n | {\n readonly token: Identifier;\n readonly lazy?: boolean;\n };\n\nexport type PropertyInjectionMap = {\n readonly [Key in string | number | symbol]?: PropertyInjectionDescriptor;\n};\n\nexport interface RegistrationOptions {\n scope?: Scope;\n tags?: string[];\n factory?: boolean;\n deps?: Identifier[];\n props?: PropertyDep[] | PropertyInjectionMap;\n}\n\n// Binding types\nexport interface ClassBinding<T = object> {\n type: \"class\";\n target: Constructor<T>;\n scope: Scope;\n tags: string[];\n deps?: Identifier[];\n props?: PropertyDep[];\n}\n\nexport interface ValueBinding<T = object> {\n type: \"value\";\n value: T;\n scope: Scope;\n tags: string[];\n}\n\nexport interface FactoryBinding<T = object> {\n type: \"factory\";\n factory: (container: IContainer) => T;\n scope: Scope;\n tags: string[];\n}\n\nexport interface TokenBinding<T = object> {\n type: \"token\";\n token: Token<T>;\n target: Constructor<T> | ((container: IContainer) => T);\n scope: Scope;\n tags: string[];\n}\n\nexport type Binding<T = object> =\n | ClassBinding<T>\n | ValueBinding<T>\n | FactoryBinding<T>\n | TokenBinding<T>;\n\n// Resolution context for circular dependency detection\nexport interface ResolutionContext {\n path: Set<Identifier>;\n depth: number;\n maxDepth: number;\n}\n\n// Container interface\nexport interface IContainer {\n // Registration methods\n register<T>(\n identifier: Identifier<T>,\n binding: Partial<Binding<T>>\n ): IContainer;\n registerClass<T>(\n target: Constructor<T>,\n options?: RegistrationOptions\n ): IContainer;\n registerValue<T>(\n identifier: Identifier<T>,\n value: T,\n options?: RegistrationOptions\n ): IContainer;\n registerFactory<T>(\n identifier: Identifier<T>,\n factory: (container: IContainer) => T,\n options?: RegistrationOptions\n ): IContainer;\n registerToken<T>(\n token: Token<T>,\n target: Constructor<T> | ((container: IContainer) => T),\n options?: RegistrationOptions\n ): IContainer;\n\n // Resolution methods\n resolve<T>(identifier: Identifier<T>): T;\n resolveAll<T>(identifier: Identifier<T>): T[];\n tryResolve<T>(identifier: Identifier<T>): T | undefined;\n\n // Introspection\n isRegistered<T>(identifier: Identifier<T>): boolean;\n getBinding<T>(identifier: Identifier<T>): Binding<T> | undefined;\n\n // Container hierarchy\n createChild(): IContainer;\n parent?: IContainer;\n\n // Lifecycle\n dispose(): Promise<void>;\n\n // Tagged resolution\n resolveByTag<T>(tag: string): T[];\n}\n\n// Dependency injection errors\nexport class DependencyInjectionError extends Error {\n constructor(\n message: string,\n public readonly identifier?: Identifier,\n public readonly context?: ResolutionContext\n ) {\n super(message);\n this.name = \"DependencyInjectionError\";\n }\n}\n\nexport class CircularDependencyError extends DependencyInjectionError {\n constructor(identifier: Identifier, context: ResolutionContext) {\n const identifierName = getIdentifierName(identifier);\n const pathNames = [...context.path].map(getIdentifierName);\n const path = pathNames.join(\" -> \");\n\n super(\n `Circular dependency detected: ${path} -> ${identifierName}`,\n identifier,\n context\n );\n this.name = \"CircularDependencyError\";\n }\n}\n\nexport class UnregisteredDependencyError extends DependencyInjectionError {\n constructor(identifier: Identifier) {\n const name = getIdentifierName(identifier);\n\n super(`No registration found for identifier: ${name}`, identifier);\n this.name = \"UnregisteredDependencyError\";\n }\n}\n\n// Helper function to get identifier name\nexport function getIdentifierName(identifier: Identifier): string {\n if (typeof identifier === \"string\") {\n return identifier;\n }\n if (typeof identifier === \"symbol\") {\n return identifier.toString();\n }\n return identifier.name || \"anonymous\";\n}\n\n// Helper to create tokens\nexport function createToken<T>(description?: string): Token<T> {\n return Symbol(description) as Token<T>;\n}\n\nexport interface PropertyDep {\n property: string | symbol;\n token: Identifier;\n lazy?: boolean;\n}\n","/**\n * Core container implementation for dependency injection\n */\n\nimport {\n IContainer,\n Identifier,\n Constructor,\n Token,\n Binding,\n ClassBinding,\n ValueBinding,\n FactoryBinding,\n TokenBinding,\n Scope,\n RegistrationOptions,\n PropertyDep,\n PropertyInjectionDescriptor,\n PropertyInjectionMap,\n ResolutionContext,\n CircularDependencyError,\n UnregisteredDependencyError,\n} from \"./types\";\n\nexport class Container implements IContainer {\n private readonly bindings = new Map<Identifier, Binding>();\n private readonly instances = new Map<Identifier, unknown>();\n private readonly scopedInstances = new Map<\n string,\n Map<Identifier, unknown>\n >();\n private readonly children = new Set<Container>();\n public readonly parent?: IContainer;\n\n constructor(parent?: IContainer) {\n if (parent !== undefined) {\n this.parent = parent;\n }\n }\n\n // Registration methods\n register<T>(\n identifier: Identifier<T>,\n binding: Partial<Binding<T>>\n ): IContainer {\n const fullBinding: Binding<T> = {\n scope: Scope.TRANSIENT,\n tags: [],\n ...binding,\n } as Binding<T>;\n\n this.bindings.set(identifier as Identifier, fullBinding as Binding);\n return this;\n }\n\n registerClass<T>(\n target: Constructor<T>,\n options: RegistrationOptions = {}\n ): IContainer {\n const propertyDeps = this.normalizePropertyOptions(options.props);\n const binding: ClassBinding<T> = {\n type: \"class\",\n target,\n scope: options.scope || Scope.TRANSIENT,\n tags: options.tags || [],\n deps: options.deps || [],\n ...(propertyDeps.length > 0 ? { props: propertyDeps } : {}),\n };\n\n this.bindings.set(target as Identifier, binding as Binding);\n return this;\n }\n\n registerValue<T>(\n identifier: Identifier<T>,\n value: T,\n options: RegistrationOptions = {}\n ): IContainer {\n const binding: ValueBinding<T> = {\n type: \"value\",\n value,\n scope: options.scope || Scope.SINGLETON,\n tags: options.tags || [],\n };\n\n this.bindings.set(identifier as Identifier, binding as Binding);\n return this;\n }\n\n registerFactory<T>(\n identifier: Identifier<T>,\n factory: (container: IContainer) => T,\n options: RegistrationOptions = {}\n ): IContainer {\n const binding: FactoryBinding<T> = {\n type: \"factory\",\n factory,\n scope: options.scope || Scope.TRANSIENT,\n tags: options.tags || [],\n };\n\n this.bindings.set(identifier as Identifier, binding as Binding);\n return this;\n }\n\n registerToken<T>(\n token: Token<T>,\n target: Constructor<T> | ((container: IContainer) => T),\n options: RegistrationOptions = {}\n ): IContainer {\n const binding: TokenBinding<T> = {\n type: \"token\",\n token,\n target,\n scope: options.scope || Scope.TRANSIENT,\n tags: options.tags || [],\n };\n\n this.bindings.set(token as Identifier, binding as Binding);\n return this;\n }\n\n // Resolution methods\n resolve<T>(identifier: Identifier<T>): T {\n const context: ResolutionContext = {\n path: new Set(),\n depth: 0,\n maxDepth: 50,\n };\n\n return this.resolveWithContext(identifier as Identifier, context) as T;\n }\n\n resolveAll<T>(identifier: Identifier<T>): T[] {\n const results: T[] = [];\n\n // Collect from this container\n for (const [key, binding] of this.bindings.entries()) {\n if (\n this.identifierMatches(key, identifier as Identifier) ||\n this.bindingHasMatchingTag(binding, identifier as Identifier)\n ) {\n try {\n const instance = this.resolve(key as Identifier<T>);\n results.push(instance);\n } catch {\n // Skip failed resolutions\n }\n }\n }\n\n // Collect from parent\n if (this.parent) {\n results.push(...this.parent.resolveAll(identifier));\n }\n\n return results;\n }\n\n tryResolve<T>(identifier: Identifier<T>): T | undefined {\n try {\n return this.resolve(identifier);\n } catch {\n return undefined;\n }\n }\n\n // Introspection\n isRegistered<T>(identifier: Identifier<T>): boolean {\n return (\n this.bindings.has(identifier as Identifier) ||\n (this.parent?.isRegistered(identifier) ?? false)\n );\n }\n\n getBinding<T>(identifier: Identifier<T>): Binding<T> | undefined {\n const binding = this.bindings.get(identifier as Identifier) as\n | Binding<T>\n | undefined;\n return binding || this.parent?.getBinding(identifier);\n }\n\n // Container hierarchy\n createChild(): IContainer {\n const child = new Container(this);\n this.children.add(child);\n return child;\n }\n\n // Tagged resolution\n resolveByTag<T>(tag: string): T[] {\n const results: T[] = [];\n\n for (const [identifier, binding] of this.bindings.entries()) {\n if (binding.tags.includes(tag)) {\n try {\n const instance = this.resolve(identifier as Identifier<T>);\n results.push(instance);\n } catch {\n // Skip failed resolutions\n }\n }\n }\n\n if (this.parent) {\n results.push(...this.parent.resolveByTag<T>(tag));\n }\n\n return results;\n }\n\n // Lifecycle\n async dispose(): Promise<void> {\n // Dispose children first\n await Promise.all([...this.children].map((child) => child.dispose()));\n this.children.clear();\n\n // Dispose instances that implement disposal\n for (const instance of this.instances.values()) {\n if (instance && typeof instance === \"object\" && \"dispose\" in instance) {\n const disposable = instance as { dispose(): Promise<void> | void };\n await disposable.dispose();\n }\n }\n\n // Clear all caches\n this.instances.clear();\n this.scopedInstances.clear();\n this.bindings.clear();\n }\n\n // Private resolution implementation\n private resolveWithContext<T>(\n identifier: Identifier,\n context: ResolutionContext\n ): T {\n // Check for circular dependencies\n if (context.path.has(identifier)) {\n throw new CircularDependencyError(identifier, context);\n }\n\n if (context.depth >= context.maxDepth) {\n throw new Error(\n `Maximum resolution depth exceeded (${context.maxDepth})`\n );\n }\n\n // Get binding first to check scope\n const binding = this.getBindingInternal(identifier);\n if (!binding) {\n throw new UnregisteredDependencyError(identifier);\n }\n\n // Check for cached instances based on scope\n if (binding.scope === Scope.SINGLETON && this.instances.has(identifier)) {\n return this.instances.get(identifier) as T;\n }\n\n // Check scoped cache for other scopes\n const scopedCache = this.getScopedCache(binding.scope);\n if (scopedCache?.has(identifier)) {\n return scopedCache.get(identifier) as T;\n }\n\n // Add to resolution path\n context.path.add(identifier);\n context.depth++;\n\n try {\n // Create instance\n const instance = this.createInstance(binding, context) as T;\n\n // Cache based on scope\n if (binding.scope === Scope.SINGLETON) {\n this.instances.set(identifier, instance);\n } else if (scopedCache) {\n scopedCache.set(identifier, instance);\n }\n\n return instance;\n } finally {\n // Clean up resolution path\n context.path.delete(identifier);\n context.depth--;\n }\n }\n\n private getBindingInternal<T>(\n identifier: Identifier<T>\n ): Binding<T> | undefined {\n const binding = this.bindings.get(identifier as Identifier);\n return (binding ||\n (this.parent as Container)?.getBindingInternal?.(identifier)) as\n | Binding<T>\n | undefined;\n }\n\n private createInstance<T>(\n binding: Binding<T>,\n context: ResolutionContext\n ): T {\n switch (binding.type) {\n case \"value\":\n return binding.value;\n\n case \"factory\": {\n // Create a context-aware container for factories\n const contextAwareContainer = this.createContextAwareContainer(context);\n return binding.factory(contextAwareContainer);\n }\n\n case \"class\":\n return this.instantiateClass(\n binding.target as unknown as Constructor<T & object>,\n context\n ) as T;\n\n case \"token\": {\n if (typeof binding.target === \"function\") {\n if (this.isConstructor(binding.target)) {\n return this.instantiateClass(\n binding.target as Constructor<T & object>,\n context\n );\n } else {\n // Create a context-aware container for token factories\n const contextAwareContainer =\n this.createContextAwareContainer(context);\n return (binding.target as (container: IContainer) => T)(\n contextAwareContainer\n );\n }\n }\n throw new Error(\n `Invalid token binding target for ${binding.token.toString()}`\n );\n }\n\n default:\n throw new Error(`Unknown binding type: ${(binding as Binding).type}`);\n }\n }\n\n private instantiateClass<T extends object>(\n constructor: Constructor<T>,\n context: ResolutionContext\n ): T {\n const binding = this.getBindingInternal(constructor) as ClassBinding<T>;\n if (!binding || binding.type !== \"class\") {\n throw new Error(\n `No class binding found for constructor: ${constructor.name}`\n );\n }\n\n // Resolve constructor dependencies from the 'deps' array\n const constructorArgs = (binding.deps || []).map((dep) => {\n return this.resolveWithContext(dep, context);\n });\n\n // Create the instance\n const instance = new constructor(...constructorArgs);\n\n // Resolve and set property dependencies from the 'props' array\n if (binding.props) {\n for (const prop of binding.props) {\n if (prop.lazy) {\n Object.defineProperty(instance, prop.property, {\n configurable: true,\n enumerable: true,\n get: () => {\n const resolved = this.resolveWithContext(prop.token, context);\n Object.defineProperty(instance, prop.property, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: resolved,\n });\n return resolved;\n },\n });\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (instance as any)[prop.property] = this.resolveWithContext(\n prop.token,\n context\n );\n }\n }\n\n return instance;\n }\n\n private isConstructor(fn: unknown): fn is Constructor {\n return typeof fn === \"function\" && fn.prototype !== undefined;\n }\n\n private createContextAwareContainer(context: ResolutionContext): IContainer {\n return {\n register: <T>(identifier: Identifier<T>, binding: Partial<Binding<T>>) =>\n this.register(identifier, binding),\n registerClass: <T>(\n target: Constructor<T>,\n options?: RegistrationOptions\n ) => this.registerClass(target, options),\n registerValue: <T>(\n identifier: Identifier<T>,\n value: T,\n options?: RegistrationOptions\n ) => this.registerValue(identifier, value, options),\n registerFactory: <T>(\n identifier: Identifier<T>,\n factory: (container: IContainer) => T,\n options?: RegistrationOptions\n ) => this.registerFactory(identifier, factory, options),\n registerToken: <T>(\n token: Token<T>,\n target: Constructor<T> | ((container: IContainer) => T),\n options?: RegistrationOptions\n ) => this.registerToken(token, target, options),\n\n resolve: <T>(identifier: Identifier<T>): T => {\n return this.resolveWithContext(identifier as Identifier, context) as T;\n },\n\n resolveAll: <T>(identifier: Identifier<T>) => this.resolveAll(identifier),\n tryResolve: <T>(identifier: Identifier<T>) => this.tryResolve(identifier),\n isRegistered: <T>(identifier: Identifier<T>) =>\n this.isRegistered(identifier),\n getBinding: <T>(identifier: Identifier<T>) => this.getBinding(identifier),\n createChild: () => this.createChild(),\n resolveByTag: <T>(tag: string) => this.resolveByTag<T>(tag),\n dispose: () => this.dispose(),\n };\n }\n\n private getScopedCache(scope: Scope): Map<Identifier, unknown> | undefined {\n if (scope === Scope.SINGLETON || scope === Scope.TRANSIENT) {\n return undefined; // Singletons use global cache, transients are never cached\n }\n\n if (!this.scopedInstances.has(scope)) {\n this.scopedInstances.set(scope, new Map());\n }\n\n return this.scopedInstances.get(scope);\n }\n\n private identifierMatches(a: Identifier, b: Identifier): boolean {\n return a === b;\n }\n\n private bindingHasMatchingTag(\n binding: Binding,\n identifier: Identifier\n ): boolean {\n if (typeof identifier !== \"string\") {\n return false;\n }\n return binding.tags.includes(identifier);\n }\n\n private normalizePropertyOptions(\n props?: RegistrationOptions[\"props\"]\n ): PropertyDep[] {\n if (!props) {\n return [];\n }\n\n if (Array.isArray(props)) {\n return props.map((prop) => ({ ...prop }));\n }\n\n const map = props as PropertyInjectionMap;\n const normalized: PropertyDep[] = [];\n const descriptorMap = map as Record<PropertyKey, PropertyInjectionDescriptor>;\n\n for (const key of Reflect.ownKeys(descriptorMap)) {\n const descriptor = descriptorMap[key as PropertyKey];\n if (!descriptor) {\n continue;\n }\n\n if (!this.isPropertyInjectionObject(descriptor)) {\n normalized.push({\n property: key,\n token: descriptor as Identifier,\n });\n continue;\n }\n\n normalized.push({\n property: key,\n token: descriptor.token,\n ...(descriptor.lazy ? { lazy: descriptor.lazy } : {}),\n });\n }\n\n return normalized;\n }\n\n private isPropertyInjectionObject(\n descriptor: PropertyInjectionDescriptor\n ): descriptor is { token: Identifier; lazy?: boolean } {\n return typeof descriptor === \"object\" && descriptor !== null && \"token\" in descriptor;\n }\n}\n\n// Export convenience functions\nexport function createContainer(): IContainer {\n return new Container();\n}\n\nexport function createChildContainer(parent: IContainer): IContainer {\n return parent.createChild();\n}","import \"reflect-metadata\";\nimport { Scope } from \"./types\";\nimport type { Identifier, PropertyDep, IContainer } from \"./types\";\n\n// Define unique keys for storing metadata via reflect-metadata\nconst INJECT_PARAM_KEY = \"autometa:inject_param\";\nconst INJECT_PROP_KEY = \"autometa:inject_prop\";\n\nexport interface InjectableOptions {\n scope?: Scope;\n deps?: Identifier[];\n}\n\ntype InjectableTarget = new (...args: unknown[]) => object;\n\nfunction ensureInjectableTarget(value: unknown, decorator: string): asserts value is InjectableTarget {\n if (typeof value !== \"function\") {\n throw new TypeError(\n `[${decorator}] can only be used on classes. Received ${typeof value}.`\n );\n }\n}\n\n/**\n * Creates a set of decorators bound to a specific container instance.\n * This factory pattern ensures the decorators are decoupled from a global\n * container and can be used with multiple, separate containers.\n * @param container The container instance to which the decorators will register classes.\n */\nexport function createDecorators(container: IContainer) {\n function registerPropertyDependency(\n target: object,\n propertyKey: string | symbol,\n token: Identifier,\n lazy: boolean\n ): void {\n const existing =\n (Reflect.getMetadata(INJECT_PROP_KEY, target) as PropertyDep[] | undefined) || [];\n const filtered = existing.filter((dep) => dep.property !== propertyKey);\n filtered.push({ property: propertyKey, token, lazy });\n Reflect.defineMetadata(INJECT_PROP_KEY, filtered, target);\n }\n\n /**\n * A class decorator that marks a class as available for injection.\n * It gathers all dependency metadata from `@Inject` decorators and\n * `reflect-metadata` and registers the class with the container.\n */\n function Injectable(options: InjectableOptions = {}): ClassDecorator {\n return (target) => {\n ensureInjectableTarget(target, \"Injectable\");\n const ctor = target;\n // --- Constructor Injection ---\n const deps = options.deps || [];\n\n // --- Property Injection ---\n const props =\n (Reflect.getMetadata(INJECT_PROP_KEY, ctor.prototype) as PropertyDep[] | undefined) || [];\n\n // --- Registration ---\n // The container's `register` method expects an identifier and a binding object.\n const identifier = ctor as unknown as Identifier;\n const binding = {\n type: \"class\" as const,\n target: ctor,\n scope: options.scope || Scope.TRANSIENT,\n tags: [],\n deps,\n props,\n };\n\n container.register(identifier, binding);\n };\n }\n\n /**\n * A decorator that can be used on constructor parameters or class properties\n * to specify a dependency token.\n * @param token The token representing the dependency to inject.\n */\n function Inject(token: Identifier): PropertyDecorator & ParameterDecorator {\n return ((...args: [object, string | symbol, number?]) => {\n const [target, propertyKey, parameterIndex] = args;\n\n if (typeof parameterIndex === \"number\") {\n ensureInjectableTarget(target, \"Inject parameter\");\n const ctor = target;\n const paramTokens =\n (Reflect.getMetadata(INJECT_PARAM_KEY, ctor) as Map<number, Identifier> | undefined) ||\n new Map<number, Identifier>();\n paramTokens.set(parameterIndex, token);\n Reflect.defineMetadata(INJECT_PARAM_KEY, paramTokens, ctor);\n return;\n }\n\n registerPropertyDependency(target, propertyKey, token, false);\n }) as PropertyDecorator & ParameterDecorator;\n }\n\n function LazyInject(token: Identifier): PropertyDecorator {\n return (target, propertyKey) => {\n registerPropertyDependency(target, propertyKey, token, true);\n };\n }\n\n return { Injectable, Inject, LazyInject };\n}\n"]}
{
"name": "@autometa/injection",
"version": "1.0.0-rc.1",
"version": "1.0.0-rc.2",
"description": "",

@@ -28,4 +28,4 @@ "type": "module",

"vitest": "^1.4.0",
"tsconfig": "0.7.0",
"eslint-config-custom": "0.6.0",
"tsconfig": "0.7.0",
"tsup-config": "0.1.0"

@@ -38,2 +38,4 @@ },

"test": "vitest run src/__tests__/integration/mixed-injection.test.ts",
"type-check": "tsc --noEmit -p tsconfig.dev.json",
"coverage": "vitest run --coverage --passWithNoTests",
"prettify": "prettier --config .prettierrc 'src/**/*.ts' --write",

@@ -40,0 +42,0 @@ "lint": "eslint . --max-warnings 0",

Sorry, the diff of this file is not supported yet