@vielzeug/conduit 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- const e=require("./errors.cjs");var t=class t{#e=new Map;#t=new Set;#n=[];#r=new AbortController;#i=new Set;#a=`active`;#o;#s=[];#c;#l=new Map;#u;name;constructor(e,t={}){this.#c=e,this.#u=t.scope,e&&e.#t.add(this),this.name=t.name??(e?`${e.name}:${t.scope?.description??`child`}`:`root`)}get disposalSignal(){return this.#r.signal}get disposed(){return this.#a===`disposed`}value(e,t,n={}){this.#f(),this.#p(e);let r={dispose:n.dispose,kind:`value`,value:t};return this.#l.set(e,r),n.dispose&&this.#s.push({dispose:n.dispose,value:t}),this}factory(e,t,n,r={}){this.#f(),this.#p(e);let i={create:n,dependencies:Object.freeze([...t]),dispose:r.dispose,kind:`factory`,lifetime:r.lifetime??`singleton`};return this.#l.set(e,i),this}has(e){return this.#f(),this.#m(e)!==void 0}async resolve(e){return this.#f(),this.#_(e,[])}validate(){this.#f();for(let{owner:e,registration:t,token:n}of this.#h())e.#g(n,t,new Set,[]);return this}createScope(e,n){return this.#f(),new t(this,{name:n?.name,scope:e})}dispose(){return this.#a===`disposed`?Promise.resolve():this.#o?this.#o:(this.#a=`disposing`,this.#r.abort(),this.#o=this.#d(),this.#o)}async#d(){let t=await Promise.allSettled([...this.#t].map(e=>e.dispose()));await Promise.allSettled([...this.#i]);let n=[...this.#n,...t.flatMap(t=>t.status===`rejected`?t.reason instanceof e.ConduitDisposeError?t.reason.errors:[t.reason]:[])];for(let e of[...this.#s].reverse())if(e.dispose)try{await e.dispose(e.value)}catch(e){n.push(e)}if(this.#e.clear(),this.#t.clear(),this.#n=[],this.#s=[],this.#l.clear(),this.#c&&this.#c.#t.delete(this),this.#a=`disposed`,n.length)throw new e.ConduitDisposeError(n)}async[Symbol.asyncDispose](){await this.dispose()}#f(){if(this.#a!==`active`)throw new e.ConduitDisposedError(this.name)}#p(t){if(this.#l.has(t))throw new e.ConduitDuplicateRegistrationError(t)}#m(e){let t=this.#l.get(e);if(t)return{owner:this,registration:t};if(this.#c)return this.#c.#m(e)}#h(){let e=this.#c?this.#c.#h():[],t=[...this.#l].flatMap(([e,t])=>t.kind===`factory`?[{owner:this,registration:t,token:e}]:[]);return[...e,...t]}#g(t,n,r,i){if(r.has(t))throw new e.ConduitCircularDependencyError([...i,t]);r.add(t);for(let a of n.dependencies){let n=this.#m(a);if(!n)throw new e.ConduitProviderNotFoundError(a,this.name);n.registration.kind===`factory`&&n.owner.#g(a,n.registration,r,[...i,t])}r.delete(t)}async#_(t,n){if(n.includes(t))throw new e.ConduitCircularDependencyError([...n,t]);let r=this.#m(t);if(!r)throw new e.ConduitProviderNotFoundError(t,this.name);if(r.registration.kind===`value`)return r.registration.value;let i=this.#v(r.owner,r.registration,t);if(r.registration.lifetime===`transient`)return this.#b(r.registration,i,[...n,t]);let a=i.#e.get(r.registration);if(a?.value!==void 0)return a.value;if(a?.promise)return a.promise;let o={},s=i.#b(r.registration,i,[...n,t]).then(e=>(o.value=e,e));return o.promise=s,i.#e.set(r.registration,o),s}#v(t,n,r){if(n.lifetime===`singleton`)return t;if(n.lifetime===`transient`)return this;let i=this.#y(n.lifetime);if(!i)throw new e.ConduitScopedResolutionError(r,n.lifetime);return i}#y(e){return this.#u===e?this:this.#c?this.#c.#y(e):void 0}async#b(t,n,r){let i=Promise.all(t.dependencies.map(e=>n.#_(e,r))).then(e=>t.create(...e));n.#i.add(i);try{let r=await i;if(n.#a!==`active`){if(t.dispose)try{await t.dispose(r)}catch(e){n.#n.push(e)}throw new e.ConduitDisposedError(n.name)}return t.dispose&&n.#s.push({dispose:t.dispose,value:r}),r}finally{n.#i.delete(i)}}};function n(e){return new t(void 0,e)}exports.createContainer=n;
1
+ const e=require("./errors.cjs"),t=require("./types.cjs");var n=class n{#e=new Map;#t=new Set;#n=[];#r=new AbortController;#i=new Set;#a=`active`;#o;#s=[];#c;#l=new Map;#u;name;constructor(e,n,r){this.#c=e,this.#u=r.scope,e&&e.#t.add(this),this.name=r.name??(e?`${e.name}:${r.scope?.description??`child`}`:`root`),this.#l.set(t.disposalSignalToken,{kind:`value`,value:this.disposalSignal});try{this.#m(n),this.#v(),this.#h()}catch(t){throw e&&e.#t.delete(this),this.#l.clear(),t}}get disposalSignal(){return this.#r.signal}get disposed(){return this.#a===`disposed`}has(e){return this.#f(),this.#g(e)!==void 0}async resolve(t){if(this.#f(),typeof t==`symbol`)return this.#b(t,[]);if(typeof t!=`object`||!t||Array.isArray(t))throw new e.ConduitError(`resolve() requires a token or service map`);let n=Object.keys(t),r=await Promise.all(n.map(e=>this.#b(t[e],[]))),i={};return n.forEach((e,t)=>{Object.defineProperty(i,e,{configurable:!0,enumerable:!0,value:r[t],writable:!0})}),i}createScope(e,t){return this.#f(),new n(this,t?.providers??[],{name:t?.name,scope:e})}dispose(){return this.#a===`disposed`?Promise.resolve():this.#o?this.#o:(this.#a=`disposing`,this.#r.abort(),this.#o=this.#d(),this.#o)}async[Symbol.asyncDispose](){await this.dispose()}async#d(){let t=await Promise.allSettled([...this.#t].map(e=>e.dispose()));await Promise.allSettled([...this.#i]);let n=[...this.#n,...t.flatMap(t=>t.status===`rejected`?t.reason instanceof e.ConduitDisposeError?t.reason.errors:[t.reason]:[])];for(let e of[...this.#s].reverse())if(e.dispose)try{await e.dispose(e.value)}catch(e){n.push(e)}if(this.#e.clear(),this.#t.clear(),this.#n=[],this.#s=[],this.#l.clear(),this.#c&&this.#c.#t.delete(this),this.#a=`disposed`,n.length)throw new e.ConduitDisposeError(n)}#f(){if(this.#a!==`active`)throw new e.ConduitDisposedError(this.name)}#p(t){if(this.#l.has(t))throw new e.ConduitDuplicateRegistrationError(t)}#m(t){if(!Array.isArray(t))throw new e.ConduitError(`Container providers must be an array`);for(let n of t){if(typeof n!=`object`||!n||Array.isArray(n))throw new e.ConduitError(`Each provider must be an object`);let t=n,r=Object.hasOwn(t,`dependencies`),i=Object.hasOwn(t,`factory`),a=Object.hasOwn(t,`value`);if(typeof t.token!=`symbol`)throw new e.ConduitError(`Each provider requires a token`);if(t.dispose!==void 0&&typeof t.dispose!=`function`)throw new e.ConduitError(`Provider "${t.token.description??`anonymous`}" has an invalid disposer`);if(a===i||a===r||a&&Object.hasOwn(t,`lifetime`))throw new e.ConduitError(`Provider "${t.token.description??`anonymous`}" must define exactly one value or factory`);if(this.#p(t.token),i){let n=t;if(!Array.isArray(n.dependencies)||n.dependencies.some(e=>typeof e!=`symbol`))throw new e.ConduitError(`Factory provider "${t.token.description??`anonymous`}" has invalid dependencies`);if(typeof n.factory!=`function`)throw new e.ConduitError(`Factory provider "${t.token.description??`anonymous`}" requires a factory`);if(n.lifetime!==void 0&&n.lifetime!==`singleton`&&n.lifetime!==`transient`&&typeof n.lifetime!=`symbol`)throw new e.ConduitError(`Factory provider "${t.token.description??`anonymous`}" has an invalid lifetime`);this.#l.set(t.token,{dependencies:Object.freeze([...n.dependencies]),dispose:n.dispose,factory:n.factory,kind:`factory`,lifetime:n.lifetime??`singleton`})}else{let e=t;this.#l.set(t.token,{dispose:e.dispose,kind:`value`,value:e.value})}}}#h(){for(let e of this.#l.values())e.kind===`value`&&e.dispose&&this.#s.push({dispose:e.dispose,value:e.value})}#g(e){let t=this.#l.get(e);if(t)return{owner:this,registration:t};if(this.#c)return this.#c.#g(e)}#_(){let e=this.#c?this.#c.#_():[],t=[...this.#l].flatMap(([e,t])=>t.kind===`factory`?[{owner:this,registration:t,token:e}]:[]);return[...e,...t]}#v(){for(let{owner:e,registration:t,token:n}of this.#_())e.#y(n,t,new Set,[])}#y(t,n,r,i){if(r.has(t))throw new e.ConduitCircularDependencyError([...i,t]);r.add(t);for(let a of n.dependencies){let o=this.#g(a);if(!o)throw new e.ConduitProviderNotFoundError(a,this.name);if(o.registration.kind===`factory`){if(n.lifetime===`singleton`&&o.registration.lifetime===`transient`)throw new e.ConduitError(`Singleton "${t.description??`anonymous`}" cannot depend on a transient factory`);if(n.lifetime===`singleton`&&typeof o.registration.lifetime==`symbol`||typeof n.lifetime==`symbol`&&typeof o.registration.lifetime==`symbol`&&n.lifetime!==o.registration.lifetime)throw new e.ConduitScopedResolutionError(t,o.registration.lifetime);o.owner.#y(a,o.registration,r,[...i,t])}}r.delete(t)}async#b(t,n){if(n.includes(t))throw new e.ConduitCircularDependencyError([...n,t]);let r=this.#g(t);if(!r)throw new e.ConduitProviderNotFoundError(t,this.name);let i=r.registration;if(i.kind===`value`)return i.value;let a=this.#x(r.owner,i,t);if(i.lifetime===`transient`)return a.#C(a.#w(i,a,[...n,t]));let o=a.#e.get(i);if(o?.resolved)return o.value;if(o)return o.promise;let s={promise:Promise.resolve(),resolved:!1},c=a.#w(i,a,[...n,t]).then(e=>(s.resolved=!0,s.value=e,e),e=>{throw a.#e.get(i)===s&&a.#e.delete(i),e});return s.promise=a.#C(c),a.#e.set(i,s),s.promise}#x(t,n,r){if(n.lifetime===`singleton`)return t;if(n.lifetime===`transient`)return this;let i=this.#S(n.lifetime);if(!i)throw new e.ConduitScopedResolutionError(r,n.lifetime);return i}#S(e){return this.#u===e?this:this.#c?this.#c.#S(e):void 0}#C(e){return this.#i.add(e),e.then(()=>this.#i.delete(e),()=>this.#i.delete(e)),e}async#w(t,n,r){let i=await Promise.all(t.dependencies.map(e=>n.#b(e,r))).then(e=>t.factory(...e));if(n.#a!==`active`){if(t.dispose)try{await t.dispose(i)}catch(e){n.#n.push(e)}throw new e.ConduitDisposedError(n.name)}return t.dispose&&n.#s.push({dispose:t.dispose,value:i}),i}};function r(e,t){return new n(void 0,e,{name:t?.name})}exports.createContainer=r;
2
2
  //# sourceMappingURL=container.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"container.cjs","names":["#parent","#scope","#children","#disposalController","#lifecycle","#assertActive","#assertUnregistered","#registry","#owned","#lookup","#resolve","#factories","#validatePath","#disposePromise","#finishDisposal","#inFlight","#cleanupFailures","#cache","#ownerFor","#create","#scopeOwner"],"sources":["../src/container.ts"],"sourcesContent":["import {\n ConduitCircularDependencyError,\n ConduitDisposedError,\n ConduitDisposeError,\n ConduitDuplicateRegistrationError,\n ConduitProviderNotFoundError,\n ConduitScopedResolutionError,\n} from './errors.js';\nimport type { Container, FactoryOptions, InferTokens, Lifetime, ScopeToken, Token, ValueOptions } from './types.js';\n\ntype Disposer = (value: never) => Promise<void> | void;\n\ntype ValueRegistration<T> = Readonly<{\n dispose?: Disposer;\n kind: 'value';\n value: T;\n}>;\n\ntype FactoryRegistration<T = unknown> = Readonly<{\n create: (...values: unknown[]) => Promise<T> | T;\n dependencies: readonly Token<unknown>[];\n dispose?: Disposer;\n kind: 'factory';\n lifetime: Lifetime;\n}>;\n\ntype Registration<T = unknown> = FactoryRegistration<T> | ValueRegistration<T>;\ntype OwnedResource = Readonly<{ dispose?: Disposer; value: unknown }>;\ntype CacheEntry = { promise?: Promise<unknown>; value?: unknown };\ntype Lifecycle = 'active' | 'disposed' | 'disposing';\n\nclass ContainerImpl implements Container {\n #cache = new Map<FactoryRegistration<any>, CacheEntry>();\n #children = new Set<ContainerImpl>();\n #cleanupFailures: unknown[] = [];\n #disposalController = new AbortController();\n #inFlight = new Set<Promise<unknown>>();\n #lifecycle: Lifecycle = 'active';\n #disposePromise?: Promise<void>;\n #owned: OwnedResource[] = [];\n #parent?: ContainerImpl;\n #registry = new Map<Token<any>, Registration<any>>();\n #scope?: ScopeToken;\n readonly name: string;\n\n constructor(parent?: ContainerImpl, options: { name?: string; scope?: ScopeToken } = {}) {\n this.#parent = parent;\n this.#scope = options.scope;\n\n if (parent) parent.#children.add(this);\n\n this.name = options.name ?? (parent ? `${parent.name}:${options.scope?.description ?? 'child'}` : 'root');\n }\n\n get disposalSignal(): AbortSignal {\n return this.#disposalController.signal;\n }\n\n get disposed(): boolean {\n return this.#lifecycle === 'disposed';\n }\n\n value<T>(token: Token<T>, value: T, options: ValueOptions<T> = {}): this {\n this.#assertActive();\n this.#assertUnregistered(token);\n\n const registration: ValueRegistration<T> = {\n dispose: options.dispose as Disposer | undefined,\n kind: 'value',\n value,\n };\n\n this.#registry.set(token, registration);\n\n if (options.dispose) this.#owned.push({ dispose: options.dispose, value });\n\n return this;\n }\n\n factory<T, Dependencies extends readonly Token<unknown>[]>(\n token: Token<T>,\n dependencies: Dependencies,\n create: (...values: InferTokens<Dependencies>) => Promise<T> | T,\n options: FactoryOptions<T> = {},\n ): this {\n this.#assertActive();\n this.#assertUnregistered(token);\n\n const registration: FactoryRegistration<T> = {\n create: create as (...values: unknown[]) => Promise<T> | T,\n dependencies: Object.freeze([...dependencies]),\n dispose: options.dispose as Disposer | undefined,\n kind: 'factory',\n lifetime: options.lifetime ?? 'singleton',\n };\n\n this.#registry.set(token, registration);\n\n return this;\n }\n\n has<T>(token: Token<T>): boolean {\n this.#assertActive();\n\n return this.#lookup(token) !== undefined;\n }\n\n async resolve<T>(token: Token<T>): Promise<T> {\n this.#assertActive();\n\n return this.#resolve(token, []);\n }\n\n validate(): this {\n this.#assertActive();\n\n for (const { owner, registration, token } of this.#factories()) {\n owner.#validatePath(token, registration, new Set(), []);\n }\n\n return this;\n }\n\n createScope(scope?: ScopeToken, options?: { name?: string }): Container {\n this.#assertActive();\n\n return new ContainerImpl(this, { name: options?.name, scope });\n }\n\n dispose(): Promise<void> {\n if (this.#lifecycle === 'disposed') return Promise.resolve();\n\n if (this.#disposePromise) return this.#disposePromise;\n\n this.#lifecycle = 'disposing';\n this.#disposalController.abort();\n this.#disposePromise = this.#finishDisposal();\n\n return this.#disposePromise;\n }\n\n async #finishDisposal(): Promise<void> {\n const childOutcomes = await Promise.allSettled([...this.#children].map((child) => child.dispose()));\n\n await Promise.allSettled([...this.#inFlight]);\n\n const failures = [\n ...this.#cleanupFailures,\n ...childOutcomes.flatMap((outcome) => {\n if (outcome.status !== 'rejected') return [];\n\n return outcome.reason instanceof ConduitDisposeError ? outcome.reason.errors : [outcome.reason];\n }),\n ];\n\n for (const resource of [...this.#owned].reverse()) {\n if (!resource.dispose) continue;\n\n try {\n await resource.dispose(resource.value as never);\n } catch (error) {\n failures.push(error);\n }\n }\n\n this.#cache.clear();\n this.#children.clear();\n this.#cleanupFailures = [];\n this.#owned = [];\n this.#registry.clear();\n\n if (this.#parent) this.#parent.#children.delete(this);\n\n this.#lifecycle = 'disposed';\n\n if (failures.length) throw new ConduitDisposeError(failures);\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.dispose();\n }\n\n #assertActive(): void {\n if (this.#lifecycle !== 'active') throw new ConduitDisposedError(this.name);\n }\n\n #assertUnregistered(token: Token<unknown>): void {\n if (this.#registry.has(token)) throw new ConduitDuplicateRegistrationError(token);\n }\n\n #lookup<T>(token: Token<T>): { owner: ContainerImpl; registration: Registration<T> } | undefined {\n const local = this.#registry.get(token) as Registration<T> | undefined;\n\n if (local) return { owner: this, registration: local };\n\n if (!this.#parent) return undefined;\n\n return this.#parent.#lookup(token);\n }\n\n #factories(): { owner: ContainerImpl; registration: FactoryRegistration; token: Token<unknown> }[] {\n const parentFactories = this.#parent ? this.#parent.#factories() : [];\n const localFactories = [...this.#registry].flatMap(([token, registration]) =>\n registration.kind === 'factory' ? [{ owner: this, registration, token }] : [],\n );\n\n return [...parentFactories, ...localFactories];\n }\n\n #validatePath(\n token: Token<unknown>,\n registration: FactoryRegistration,\n visiting: Set<Token<unknown>>,\n path: Token<unknown>[],\n ): void {\n if (visiting.has(token)) throw new ConduitCircularDependencyError([...path, token]);\n\n visiting.add(token);\n\n for (const dependency of registration.dependencies) {\n const found = this.#lookup(dependency);\n\n if (!found) throw new ConduitProviderNotFoundError(dependency, this.name);\n\n if (found.registration.kind === 'factory') {\n found.owner.#validatePath(dependency, found.registration, visiting, [...path, token]);\n }\n }\n\n visiting.delete(token);\n }\n\n async #resolve<T>(token: Token<T>, path: Token<unknown>[]): Promise<T> {\n if (path.includes(token)) throw new ConduitCircularDependencyError([...path, token]);\n\n const found = this.#lookup(token);\n\n if (!found) throw new ConduitProviderNotFoundError(token, this.name);\n\n if (found.registration.kind === 'value') return found.registration.value as T;\n\n const owner = this.#ownerFor(found.owner, found.registration, token);\n\n if (found.registration.lifetime === 'transient') {\n return this.#create(found.registration, owner, [...path, token]) as Promise<T>;\n }\n\n const existing = owner.#cache.get(found.registration);\n\n if (existing?.value !== undefined) return existing.value as T;\n\n if (existing?.promise) return existing.promise as Promise<T>;\n\n const entry: CacheEntry = {};\n const promise = owner.#create(found.registration, owner, [...path, token]).then((value) => {\n entry.value = value;\n\n return value;\n });\n\n entry.promise = promise;\n owner.#cache.set(found.registration, entry);\n\n return promise as Promise<T>;\n }\n\n #ownerFor(owner: ContainerImpl, registration: FactoryRegistration, token: Token<unknown>): ContainerImpl {\n if (registration.lifetime === 'singleton') return owner;\n\n if (registration.lifetime === 'transient') return this;\n\n const scope = this.#scopeOwner(registration.lifetime);\n\n if (!scope) throw new ConduitScopedResolutionError(token, registration.lifetime);\n\n return scope;\n }\n\n #scopeOwner(scope: ScopeToken): ContainerImpl | undefined {\n if (this.#scope === scope) return this;\n\n return this.#parent ? this.#parent.#scopeOwner(scope) : undefined;\n }\n\n async #create(registration: FactoryRegistration, owner: ContainerImpl, path: Token<unknown>[]): Promise<unknown> {\n const promise = Promise.all(registration.dependencies.map((dependency) => owner.#resolve(dependency, path))).then(\n (dependencies) => registration.create(...dependencies),\n );\n\n owner.#inFlight.add(promise);\n\n try {\n const value = await promise;\n\n if (owner.#lifecycle !== 'active') {\n if (registration.dispose) {\n try {\n await registration.dispose(value as never);\n } catch (error) {\n owner.#cleanupFailures.push(error);\n }\n }\n\n throw new ConduitDisposedError(owner.name);\n }\n\n if (registration.dispose) owner.#owned.push({ dispose: registration.dispose, value });\n\n return value;\n } finally {\n owner.#inFlight.delete(promise);\n }\n }\n}\n\nexport function createContainer(options?: { name?: string }): Container {\n return new ContainerImpl(undefined, options);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"container.cjs","names":[],"sources":["../src/container.ts"],"sourcesContent":["import {\n ConduitCircularDependencyError,\n ConduitDisposedError,\n ConduitDisposeError,\n ConduitDuplicateRegistrationError,\n ConduitError,\n ConduitProviderNotFoundError,\n ConduitScopedResolutionError,\n} from './errors.js';\nimport type {\n Container,\n FactoryProvider,\n InferServices,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueProvider,\n} from './types.js';\nimport { disposalSignalToken } from './types.js';\n\ntype Disposer = (value: unknown) => Promise<void> | void;\n\ntype ValueRegistration<T> = Readonly<{\n dispose?: Disposer;\n kind: 'value';\n value: T;\n}>;\n\ntype FactoryRegistration<T = unknown> = Readonly<{\n factory: (...values: unknown[]) => Promise<T> | T;\n dependencies: readonly Token<unknown>[];\n dispose?: Disposer;\n kind: 'factory';\n lifetime: Lifetime;\n}>;\n\ntype Registration<T = unknown> = FactoryRegistration<T> | ValueRegistration<T>;\ntype OwnedResource = Readonly<{ dispose?: Disposer; value: unknown }>;\ntype CacheEntry = { promise: Promise<unknown>; resolved: boolean; value?: unknown };\ntype Lifecycle = 'active' | 'disposed' | 'disposing';\n\nclass ContainerImpl implements Container {\n #cache = new Map<FactoryRegistration<unknown>, CacheEntry>();\n #children = new Set<ContainerImpl>();\n #cleanupFailures: unknown[] = [];\n #disposalController = new AbortController();\n #inFlight = new Set<Promise<unknown>>();\n #lifecycle: Lifecycle = 'active';\n #disposePromise?: Promise<void>;\n #owned: OwnedResource[] = [];\n #parent?: ContainerImpl;\n #registry = new Map<Token<unknown>, Registration<unknown>>();\n #scope?: ScopeToken;\n readonly name: string;\n\n constructor(\n parent: ContainerImpl | undefined,\n providers: readonly Provider<any, any>[],\n options: { name?: string; scope?: ScopeToken },\n ) {\n this.#parent = parent;\n this.#scope = options.scope;\n\n if (parent) parent.#children.add(this);\n\n this.name = options.name ?? (parent ? `${parent.name}:${options.scope?.description ?? 'child'}` : 'root');\n this.#registry.set(disposalSignalToken, { kind: 'value', value: this.disposalSignal });\n\n try {\n this.#registerProviders(providers);\n this.#validateGraph();\n this.#claimValues();\n } catch (error) {\n if (parent) parent.#children.delete(this);\n this.#registry.clear();\n throw error;\n }\n }\n\n get disposalSignal(): AbortSignal {\n return this.#disposalController.signal;\n }\n\n get disposed(): boolean {\n return this.#lifecycle === 'disposed';\n }\n\n has<T>(token: Token<T>): boolean {\n this.#assertActive();\n\n return this.#lookup(token) !== undefined;\n }\n\n resolve<T>(token: Token<T>): Promise<T>;\n resolve<M extends ServiceMap>(map: M): Promise<InferServices<M>>;\n async resolve<T, M extends ServiceMap>(input: Token<T> | M): Promise<InferServices<M> | T> {\n this.#assertActive();\n\n if (typeof input === 'symbol') return this.#resolve(input, []);\n if (typeof input !== 'object' || input === null || Array.isArray(input)) {\n throw new ConduitError('resolve() requires a token or service map');\n }\n\n const entries = Object.keys(input) as (keyof M & string)[];\n const values = await Promise.all(entries.map((key) => this.#resolve(input[key] as Token<unknown>, [])));\n const services = {} as InferServices<M>;\n\n entries.forEach((key, index) => {\n Object.defineProperty(services, key, {\n configurable: true,\n enumerable: true,\n value: values[index],\n writable: true,\n });\n });\n\n return services;\n }\n\n createScope(\n scope?: ScopeToken,\n options?: { readonly name?: string; readonly providers?: readonly Provider<any, any>[] },\n ): Container {\n this.#assertActive();\n\n return new ContainerImpl(this, options?.providers ?? [], { name: options?.name, scope });\n }\n\n dispose(): Promise<void> {\n if (this.#lifecycle === 'disposed') return Promise.resolve();\n\n if (this.#disposePromise) return this.#disposePromise;\n\n this.#lifecycle = 'disposing';\n this.#disposalController.abort();\n this.#disposePromise = this.#finishDisposal();\n\n return this.#disposePromise;\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.dispose();\n }\n\n async #finishDisposal(): Promise<void> {\n const childOutcomes = await Promise.allSettled([...this.#children].map((child) => child.dispose()));\n\n await Promise.allSettled([...this.#inFlight]);\n\n const failures = [\n ...this.#cleanupFailures,\n ...childOutcomes.flatMap((outcome) => {\n if (outcome.status !== 'rejected') return [];\n\n return outcome.reason instanceof ConduitDisposeError ? outcome.reason.errors : [outcome.reason];\n }),\n ];\n\n for (const resource of [...this.#owned].reverse()) {\n if (!resource.dispose) continue;\n\n try {\n await resource.dispose(resource.value);\n } catch (error) {\n failures.push(error);\n }\n }\n\n this.#cache.clear();\n this.#children.clear();\n this.#cleanupFailures = [];\n this.#owned = [];\n this.#registry.clear();\n\n if (this.#parent) this.#parent.#children.delete(this);\n\n this.#lifecycle = 'disposed';\n\n if (failures.length) throw new ConduitDisposeError(failures);\n }\n\n #assertActive(): void {\n if (this.#lifecycle !== 'active') throw new ConduitDisposedError(this.name);\n }\n\n #assertUnregistered(token: Token<unknown>): void {\n if (this.#registry.has(token)) throw new ConduitDuplicateRegistrationError(token);\n }\n\n #registerProviders(providers: readonly Provider<any, any>[]): void {\n if (!Array.isArray(providers)) throw new ConduitError('Container providers must be an array');\n\n for (const input of providers) {\n if (typeof input !== 'object' || input === null || Array.isArray(input)) {\n throw new ConduitError('Each provider must be an object');\n }\n\n const provider = input as Provider;\n const hasDependencies = Object.hasOwn(provider, 'dependencies');\n const hasFactory = Object.hasOwn(provider, 'factory');\n const hasValue = Object.hasOwn(provider, 'value');\n\n if (typeof provider.token !== 'symbol') throw new ConduitError('Each provider requires a token');\n if (provider.dispose !== undefined && typeof provider.dispose !== 'function') {\n throw new ConduitError(`Provider \"${provider.token.description ?? 'anonymous'}\" has an invalid disposer`);\n }\n if (\n hasValue === hasFactory ||\n hasValue === hasDependencies ||\n (hasValue && Object.hasOwn(provider, 'lifetime'))\n ) {\n throw new ConduitError(\n `Provider \"${provider.token.description ?? 'anonymous'}\" must define exactly one value or factory`,\n );\n }\n\n this.#assertUnregistered(provider.token);\n\n if (hasFactory) {\n const factory = provider as FactoryProvider<unknown>;\n\n if (\n !Array.isArray(factory.dependencies) ||\n factory.dependencies.some((dependency) => typeof dependency !== 'symbol')\n ) {\n throw new ConduitError(\n `Factory provider \"${provider.token.description ?? 'anonymous'}\" has invalid dependencies`,\n );\n }\n if (typeof factory.factory !== 'function') {\n throw new ConduitError(`Factory provider \"${provider.token.description ?? 'anonymous'}\" requires a factory`);\n }\n if (\n factory.lifetime !== undefined &&\n factory.lifetime !== 'singleton' &&\n factory.lifetime !== 'transient' &&\n typeof factory.lifetime !== 'symbol'\n ) {\n throw new ConduitError(\n `Factory provider \"${provider.token.description ?? 'anonymous'}\" has an invalid lifetime`,\n );\n }\n\n this.#registry.set(provider.token, {\n dependencies: Object.freeze([...factory.dependencies]),\n dispose: factory.dispose as Disposer | undefined,\n factory: factory.factory as (...values: unknown[]) => Promise<unknown> | unknown,\n kind: 'factory',\n lifetime: factory.lifetime ?? 'singleton',\n });\n } else {\n const valueProvider = provider as ValueProvider<unknown>;\n\n this.#registry.set(provider.token, {\n dispose: valueProvider.dispose as Disposer | undefined,\n kind: 'value',\n value: valueProvider.value,\n });\n }\n }\n }\n\n #claimValues(): void {\n for (const registration of this.#registry.values()) {\n if (registration.kind === 'value' && registration.dispose) {\n this.#owned.push({ dispose: registration.dispose, value: registration.value });\n }\n }\n }\n\n #lookup<T>(token: Token<T>): { owner: ContainerImpl; registration: Registration<T> } | undefined {\n const local = this.#registry.get(token) as Registration<T> | undefined;\n\n if (local) return { owner: this, registration: local };\n\n if (!this.#parent) return undefined;\n\n return this.#parent.#lookup(token);\n }\n\n #factories(): { owner: ContainerImpl; registration: FactoryRegistration; token: Token<unknown> }[] {\n const parentFactories = this.#parent ? this.#parent.#factories() : [];\n const localFactories = [...this.#registry].flatMap(([token, registration]) =>\n registration.kind === 'factory' ? [{ owner: this, registration, token }] : [],\n );\n\n return [...parentFactories, ...localFactories];\n }\n\n #validateGraph(): void {\n for (const { owner, registration, token } of this.#factories()) {\n owner.#validatePath(token, registration, new Set(), []);\n }\n }\n\n #validatePath(\n token: Token<unknown>,\n registration: FactoryRegistration,\n visiting: Set<Token<unknown>>,\n path: Token<unknown>[],\n ): void {\n if (visiting.has(token)) throw new ConduitCircularDependencyError([...path, token]);\n\n visiting.add(token);\n\n for (const dependency of registration.dependencies) {\n const found = this.#lookup(dependency);\n\n if (!found) throw new ConduitProviderNotFoundError(dependency, this.name);\n\n if (found.registration.kind === 'factory') {\n if (registration.lifetime === 'singleton' && found.registration.lifetime === 'transient') {\n throw new ConduitError(\n `Singleton \"${token.description ?? 'anonymous'}\" cannot depend on a transient factory`,\n );\n }\n if (registration.lifetime === 'singleton' && typeof found.registration.lifetime === 'symbol') {\n throw new ConduitScopedResolutionError(token, found.registration.lifetime);\n }\n if (\n typeof registration.lifetime === 'symbol' &&\n typeof found.registration.lifetime === 'symbol' &&\n registration.lifetime !== found.registration.lifetime\n ) {\n throw new ConduitScopedResolutionError(token, found.registration.lifetime);\n }\n\n found.owner.#validatePath(dependency, found.registration, visiting, [...path, token]);\n }\n }\n\n visiting.delete(token);\n }\n\n async #resolve<T>(token: Token<T>, path: Token<unknown>[]): Promise<T> {\n if (path.includes(token)) throw new ConduitCircularDependencyError([...path, token]);\n\n const found = this.#lookup(token);\n\n if (!found) throw new ConduitProviderNotFoundError(token, this.name);\n\n const registration = found.registration;\n\n if (registration.kind === 'value') return registration.value as T;\n\n const owner = this.#ownerFor(found.owner, registration, token);\n\n if (registration.lifetime === 'transient') {\n return owner.#track(owner.#create(registration, owner, [...path, token])) as Promise<T>;\n }\n\n const existing = owner.#cache.get(registration);\n\n if (existing?.resolved) return existing.value as T;\n if (existing) return existing.promise as Promise<T>;\n\n const entry = { promise: Promise.resolve(), resolved: false } as CacheEntry;\n const creation = owner.#create(registration, owner, [...path, token]).then(\n (value) => {\n entry.resolved = true;\n entry.value = value;\n return value;\n },\n (error) => {\n if (owner.#cache.get(registration) === entry) owner.#cache.delete(registration);\n throw error;\n },\n );\n\n entry.promise = owner.#track(creation);\n owner.#cache.set(registration, entry);\n\n return entry.promise as Promise<T>;\n }\n\n #ownerFor(owner: ContainerImpl, registration: FactoryRegistration, token: Token<unknown>): ContainerImpl {\n if (registration.lifetime === 'singleton') return owner;\n if (registration.lifetime === 'transient') return this;\n\n const scopeOwner = this.#scopeOwner(registration.lifetime as ScopeToken);\n\n if (!scopeOwner) throw new ConduitScopedResolutionError(token, registration.lifetime as ScopeToken);\n\n return scopeOwner;\n }\n\n #scopeOwner(scope: ScopeToken): ContainerImpl | undefined {\n if (this.#scope === scope) return this;\n\n return this.#parent ? this.#parent.#scopeOwner(scope) : undefined;\n }\n\n #track<T>(promise: Promise<T>): Promise<T> {\n this.#inFlight.add(promise);\n void promise.then(\n () => this.#inFlight.delete(promise),\n () => this.#inFlight.delete(promise),\n );\n return promise;\n }\n\n async #create(registration: FactoryRegistration, owner: ContainerImpl, path: Token<unknown>[]): Promise<unknown> {\n const value = await Promise.all(\n registration.dependencies.map((dependency) => owner.#resolve(dependency, path)),\n ).then((dependencies) => registration.factory(...dependencies));\n\n if (owner.#lifecycle !== 'active') {\n if (registration.dispose) {\n try {\n await registration.dispose(value);\n } catch (error) {\n owner.#cleanupFailures.push(error);\n }\n }\n\n throw new ConduitDisposedError(owner.name);\n }\n\n if (registration.dispose) owner.#owned.push({ dispose: registration.dispose, value });\n\n return value;\n }\n}\n\nexport function createContainer(\n providers: readonly Provider<any, any>[],\n options?: { readonly name?: string },\n): Container {\n return new ContainerImpl(undefined, providers, { name: options?.name });\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import type { Container } from './types.js';
2
- export declare function createContainer(options?: {
3
- name?: string;
1
+ import type { Container, Provider } from './types.js';
2
+ export declare function createContainer(providers: readonly Provider<any, any>[], options?: {
3
+ readonly name?: string;
4
4
  }): Container;
5
5
  //# sourceMappingURL=container.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAA0E,MAAM,YAAY,CAAC;AAmTpH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAEtE"}
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,SAAS,EAIT,QAAQ,EAKT,MAAM,YAAY,CAAC;AAuZpB,wBAAgB,eAAe,CAC7B,SAAS,EAAE,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EACxC,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACnC,SAAS,CAEX"}
package/dist/container.js CHANGED
@@ -1,6 +1,7 @@
1
- import { ConduitCircularDependencyError as e, ConduitDisposeError as t, ConduitDisposedError as n, ConduitDuplicateRegistrationError as r, ConduitProviderNotFoundError as i, ConduitScopedResolutionError as a } from "./errors.js";
1
+ import { ConduitCircularDependencyError as e, ConduitDisposeError as t, ConduitDisposedError as n, ConduitDuplicateRegistrationError as r, ConduitError as i, ConduitProviderNotFoundError as a, ConduitScopedResolutionError as o } from "./errors.js";
2
+ import { disposalSignalToken as s } from "./types.js";
2
3
  //#region src/container.ts
3
- var o = class o {
4
+ var c = class c {
4
5
  #e = /* @__PURE__ */ new Map();
5
6
  #t = /* @__PURE__ */ new Set();
6
7
  #n = [];
@@ -13,8 +14,16 @@ var o = class o {
13
14
  #l = /* @__PURE__ */ new Map();
14
15
  #u;
15
16
  name;
16
- constructor(e, t = {}) {
17
- this.#c = e, this.#u = t.scope, e && e.#t.add(this), this.name = t.name ?? (e ? `${e.name}:${t.scope?.description ?? "child"}` : "root");
17
+ constructor(e, t, n) {
18
+ this.#c = e, this.#u = n.scope, e && e.#t.add(this), this.name = n.name ?? (e ? `${e.name}:${n.scope?.description ?? "child"}` : "root"), this.#l.set(s, {
19
+ kind: "value",
20
+ value: this.disposalSignal
21
+ });
22
+ try {
23
+ this.#m(t), this.#v(), this.#h();
24
+ } catch (t) {
25
+ throw e && e.#t.delete(this), this.#l.clear(), t;
26
+ }
18
27
  }
19
28
  get disposalSignal() {
20
29
  return this.#r.signal;
@@ -22,42 +31,24 @@ var o = class o {
22
31
  get disposed() {
23
32
  return this.#a === "disposed";
24
33
  }
25
- value(e, t, n = {}) {
26
- this.#f(), this.#p(e);
27
- let r = {
28
- dispose: n.dispose,
29
- kind: "value",
30
- value: t
31
- };
32
- return this.#l.set(e, r), n.dispose && this.#s.push({
33
- dispose: n.dispose,
34
- value: t
35
- }), this;
36
- }
37
- factory(e, t, n, r = {}) {
38
- this.#f(), this.#p(e);
39
- let i = {
40
- create: n,
41
- dependencies: Object.freeze([...t]),
42
- dispose: r.dispose,
43
- kind: "factory",
44
- lifetime: r.lifetime ?? "singleton"
45
- };
46
- return this.#l.set(e, i), this;
47
- }
48
34
  has(e) {
49
- return this.#f(), this.#m(e) !== void 0;
35
+ return this.#f(), this.#g(e) !== void 0;
50
36
  }
51
37
  async resolve(e) {
52
- return this.#f(), this.#_(e, []);
53
- }
54
- validate() {
55
- this.#f();
56
- for (let { owner: e, registration: t, token: n } of this.#h()) e.#g(n, t, /* @__PURE__ */ new Set(), []);
57
- return this;
38
+ if (this.#f(), typeof e == "symbol") return this.#b(e, []);
39
+ if (typeof e != "object" || !e || Array.isArray(e)) throw new i("resolve() requires a token or service map");
40
+ let t = Object.keys(e), n = await Promise.all(t.map((t) => this.#b(e[t], []))), r = {};
41
+ return t.forEach((e, t) => {
42
+ Object.defineProperty(r, e, {
43
+ configurable: !0,
44
+ enumerable: !0,
45
+ value: n[t],
46
+ writable: !0
47
+ });
48
+ }), r;
58
49
  }
59
50
  createScope(e, t) {
60
- return this.#f(), new o(this, {
51
+ return this.#f(), new c(this, t?.providers ?? [], {
61
52
  name: t?.name,
62
53
  scope: e
63
54
  });
@@ -65,6 +56,9 @@ var o = class o {
65
56
  dispose() {
66
57
  return this.#a === "disposed" ? Promise.resolve() : this.#o ? this.#o : (this.#a = "disposing", this.#r.abort(), this.#o = this.#d(), this.#o);
67
58
  }
59
+ async [Symbol.asyncDispose]() {
60
+ await this.dispose();
61
+ }
68
62
  async #d() {
69
63
  let e = await Promise.allSettled([...this.#t].map((e) => e.dispose()));
70
64
  await Promise.allSettled([...this.#i]);
@@ -76,9 +70,6 @@ var o = class o {
76
70
  }
77
71
  if (this.#e.clear(), this.#t.clear(), this.#n = [], this.#s = [], this.#l.clear(), this.#c && this.#c.#t.delete(this), this.#a = "disposed", n.length) throw new t(n);
78
72
  }
79
- async [Symbol.asyncDispose]() {
80
- await this.dispose();
81
- }
82
73
  #f() {
83
74
  if (this.#a !== "active") throw new n(this.name);
84
75
  }
@@ -86,80 +77,126 @@ var o = class o {
86
77
  if (this.#l.has(e)) throw new r(e);
87
78
  }
88
79
  #m(e) {
80
+ if (!Array.isArray(e)) throw new i("Container providers must be an array");
81
+ for (let t of e) {
82
+ if (typeof t != "object" || !t || Array.isArray(t)) throw new i("Each provider must be an object");
83
+ let e = t, n = Object.hasOwn(e, "dependencies"), r = Object.hasOwn(e, "factory"), a = Object.hasOwn(e, "value");
84
+ if (typeof e.token != "symbol") throw new i("Each provider requires a token");
85
+ if (e.dispose !== void 0 && typeof e.dispose != "function") throw new i(`Provider "${e.token.description ?? "anonymous"}" has an invalid disposer`);
86
+ if (a === r || a === n || a && Object.hasOwn(e, "lifetime")) throw new i(`Provider "${e.token.description ?? "anonymous"}" must define exactly one value or factory`);
87
+ if (this.#p(e.token), r) {
88
+ let t = e;
89
+ if (!Array.isArray(t.dependencies) || t.dependencies.some((e) => typeof e != "symbol")) throw new i(`Factory provider "${e.token.description ?? "anonymous"}" has invalid dependencies`);
90
+ if (typeof t.factory != "function") throw new i(`Factory provider "${e.token.description ?? "anonymous"}" requires a factory`);
91
+ if (t.lifetime !== void 0 && t.lifetime !== "singleton" && t.lifetime !== "transient" && typeof t.lifetime != "symbol") throw new i(`Factory provider "${e.token.description ?? "anonymous"}" has an invalid lifetime`);
92
+ this.#l.set(e.token, {
93
+ dependencies: Object.freeze([...t.dependencies]),
94
+ dispose: t.dispose,
95
+ factory: t.factory,
96
+ kind: "factory",
97
+ lifetime: t.lifetime ?? "singleton"
98
+ });
99
+ } else {
100
+ let t = e;
101
+ this.#l.set(e.token, {
102
+ dispose: t.dispose,
103
+ kind: "value",
104
+ value: t.value
105
+ });
106
+ }
107
+ }
108
+ }
109
+ #h() {
110
+ for (let e of this.#l.values()) e.kind === "value" && e.dispose && this.#s.push({
111
+ dispose: e.dispose,
112
+ value: e.value
113
+ });
114
+ }
115
+ #g(e) {
89
116
  let t = this.#l.get(e);
90
117
  if (t) return {
91
118
  owner: this,
92
119
  registration: t
93
120
  };
94
- if (this.#c) return this.#c.#m(e);
121
+ if (this.#c) return this.#c.#g(e);
95
122
  }
96
- #h() {
97
- let e = this.#c ? this.#c.#h() : [], t = [...this.#l].flatMap(([e, t]) => t.kind === "factory" ? [{
123
+ #_() {
124
+ let e = this.#c ? this.#c.#_() : [], t = [...this.#l].flatMap(([e, t]) => t.kind === "factory" ? [{
98
125
  owner: this,
99
126
  registration: t,
100
127
  token: e
101
128
  }] : []);
102
129
  return [...e, ...t];
103
130
  }
104
- #g(t, n, r, a) {
105
- if (r.has(t)) throw new e([...a, t]);
131
+ #v() {
132
+ for (let { owner: e, registration: t, token: n } of this.#_()) e.#y(n, t, /* @__PURE__ */ new Set(), []);
133
+ }
134
+ #y(t, n, r, s) {
135
+ if (r.has(t)) throw new e([...s, t]);
106
136
  r.add(t);
107
137
  for (let e of n.dependencies) {
108
- let n = this.#m(e);
109
- if (!n) throw new i(e, this.name);
110
- n.registration.kind === "factory" && n.owner.#g(e, n.registration, r, [...a, t]);
138
+ let c = this.#g(e);
139
+ if (!c) throw new a(e, this.name);
140
+ if (c.registration.kind === "factory") {
141
+ if (n.lifetime === "singleton" && c.registration.lifetime === "transient") throw new i(`Singleton "${t.description ?? "anonymous"}" cannot depend on a transient factory`);
142
+ if (n.lifetime === "singleton" && typeof c.registration.lifetime == "symbol" || typeof n.lifetime == "symbol" && typeof c.registration.lifetime == "symbol" && n.lifetime !== c.registration.lifetime) throw new o(t, c.registration.lifetime);
143
+ c.owner.#y(e, c.registration, r, [...s, t]);
144
+ }
111
145
  }
112
146
  r.delete(t);
113
147
  }
114
- async #_(t, n) {
148
+ async #b(t, n) {
115
149
  if (n.includes(t)) throw new e([...n, t]);
116
- let r = this.#m(t);
117
- if (!r) throw new i(t, this.name);
118
- if (r.registration.kind === "value") return r.registration.value;
119
- let a = this.#v(r.owner, r.registration, t);
120
- if (r.registration.lifetime === "transient") return this.#b(r.registration, a, [...n, t]);
121
- let o = a.#e.get(r.registration);
122
- if (o?.value !== void 0) return o.value;
123
- if (o?.promise) return o.promise;
124
- let s = {}, c = a.#b(r.registration, a, [...n, t]).then((e) => (s.value = e, e));
125
- return s.promise = c, a.#e.set(r.registration, s), c;
126
- }
127
- #v(e, t, n) {
150
+ let r = this.#g(t);
151
+ if (!r) throw new a(t, this.name);
152
+ let i = r.registration;
153
+ if (i.kind === "value") return i.value;
154
+ let o = this.#x(r.owner, i, t);
155
+ if (i.lifetime === "transient") return o.#C(o.#w(i, o, [...n, t]));
156
+ let s = o.#e.get(i);
157
+ if (s?.resolved) return s.value;
158
+ if (s) return s.promise;
159
+ let c = {
160
+ promise: Promise.resolve(),
161
+ resolved: !1
162
+ }, l = o.#w(i, o, [...n, t]).then((e) => (c.resolved = !0, c.value = e, e), (e) => {
163
+ throw o.#e.get(i) === c && o.#e.delete(i), e;
164
+ });
165
+ return c.promise = o.#C(l), o.#e.set(i, c), c.promise;
166
+ }
167
+ #x(e, t, n) {
128
168
  if (t.lifetime === "singleton") return e;
129
169
  if (t.lifetime === "transient") return this;
130
- let r = this.#y(t.lifetime);
131
- if (!r) throw new a(n, t.lifetime);
170
+ let r = this.#S(t.lifetime);
171
+ if (!r) throw new o(n, t.lifetime);
132
172
  return r;
133
173
  }
134
- #y(e) {
135
- return this.#u === e ? this : this.#c ? this.#c.#y(e) : void 0;
174
+ #S(e) {
175
+ return this.#u === e ? this : this.#c ? this.#c.#S(e) : void 0;
136
176
  }
137
- async #b(e, t, r) {
138
- let i = Promise.all(e.dependencies.map((e) => t.#_(e, r))).then((t) => e.create(...t));
139
- t.#i.add(i);
140
- try {
141
- let r = await i;
142
- if (t.#a !== "active") {
143
- if (e.dispose) try {
144
- await e.dispose(r);
145
- } catch (e) {
146
- t.#n.push(e);
147
- }
148
- throw new n(t.name);
177
+ #C(e) {
178
+ return this.#i.add(e), e.then(() => this.#i.delete(e), () => this.#i.delete(e)), e;
179
+ }
180
+ async #w(e, t, r) {
181
+ let i = await Promise.all(e.dependencies.map((e) => t.#b(e, r))).then((t) => e.factory(...t));
182
+ if (t.#a !== "active") {
183
+ if (e.dispose) try {
184
+ await e.dispose(i);
185
+ } catch (e) {
186
+ t.#n.push(e);
149
187
  }
150
- return e.dispose && t.#s.push({
151
- dispose: e.dispose,
152
- value: r
153
- }), r;
154
- } finally {
155
- t.#i.delete(i);
188
+ throw new n(t.name);
156
189
  }
190
+ return e.dispose && t.#s.push({
191
+ dispose: e.dispose,
192
+ value: i
193
+ }), i;
157
194
  }
158
195
  };
159
- function s(e) {
160
- return new o(void 0, e);
196
+ function l(e, t) {
197
+ return new c(void 0, e, { name: t?.name });
161
198
  }
162
199
  //#endregion
163
- export { s as createContainer };
200
+ export { l as createContainer };
164
201
 
165
202
  //# sourceMappingURL=container.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"container.js","names":["#parent","#scope","#children","#disposalController","#lifecycle","#assertActive","#assertUnregistered","#registry","#owned","#lookup","#resolve","#factories","#validatePath","#disposePromise","#finishDisposal","#inFlight","#cleanupFailures","#cache","#ownerFor","#create","#scopeOwner"],"sources":["../src/container.ts"],"sourcesContent":["import {\n ConduitCircularDependencyError,\n ConduitDisposedError,\n ConduitDisposeError,\n ConduitDuplicateRegistrationError,\n ConduitProviderNotFoundError,\n ConduitScopedResolutionError,\n} from './errors.js';\nimport type { Container, FactoryOptions, InferTokens, Lifetime, ScopeToken, Token, ValueOptions } from './types.js';\n\ntype Disposer = (value: never) => Promise<void> | void;\n\ntype ValueRegistration<T> = Readonly<{\n dispose?: Disposer;\n kind: 'value';\n value: T;\n}>;\n\ntype FactoryRegistration<T = unknown> = Readonly<{\n create: (...values: unknown[]) => Promise<T> | T;\n dependencies: readonly Token<unknown>[];\n dispose?: Disposer;\n kind: 'factory';\n lifetime: Lifetime;\n}>;\n\ntype Registration<T = unknown> = FactoryRegistration<T> | ValueRegistration<T>;\ntype OwnedResource = Readonly<{ dispose?: Disposer; value: unknown }>;\ntype CacheEntry = { promise?: Promise<unknown>; value?: unknown };\ntype Lifecycle = 'active' | 'disposed' | 'disposing';\n\nclass ContainerImpl implements Container {\n #cache = new Map<FactoryRegistration<any>, CacheEntry>();\n #children = new Set<ContainerImpl>();\n #cleanupFailures: unknown[] = [];\n #disposalController = new AbortController();\n #inFlight = new Set<Promise<unknown>>();\n #lifecycle: Lifecycle = 'active';\n #disposePromise?: Promise<void>;\n #owned: OwnedResource[] = [];\n #parent?: ContainerImpl;\n #registry = new Map<Token<any>, Registration<any>>();\n #scope?: ScopeToken;\n readonly name: string;\n\n constructor(parent?: ContainerImpl, options: { name?: string; scope?: ScopeToken } = {}) {\n this.#parent = parent;\n this.#scope = options.scope;\n\n if (parent) parent.#children.add(this);\n\n this.name = options.name ?? (parent ? `${parent.name}:${options.scope?.description ?? 'child'}` : 'root');\n }\n\n get disposalSignal(): AbortSignal {\n return this.#disposalController.signal;\n }\n\n get disposed(): boolean {\n return this.#lifecycle === 'disposed';\n }\n\n value<T>(token: Token<T>, value: T, options: ValueOptions<T> = {}): this {\n this.#assertActive();\n this.#assertUnregistered(token);\n\n const registration: ValueRegistration<T> = {\n dispose: options.dispose as Disposer | undefined,\n kind: 'value',\n value,\n };\n\n this.#registry.set(token, registration);\n\n if (options.dispose) this.#owned.push({ dispose: options.dispose, value });\n\n return this;\n }\n\n factory<T, Dependencies extends readonly Token<unknown>[]>(\n token: Token<T>,\n dependencies: Dependencies,\n create: (...values: InferTokens<Dependencies>) => Promise<T> | T,\n options: FactoryOptions<T> = {},\n ): this {\n this.#assertActive();\n this.#assertUnregistered(token);\n\n const registration: FactoryRegistration<T> = {\n create: create as (...values: unknown[]) => Promise<T> | T,\n dependencies: Object.freeze([...dependencies]),\n dispose: options.dispose as Disposer | undefined,\n kind: 'factory',\n lifetime: options.lifetime ?? 'singleton',\n };\n\n this.#registry.set(token, registration);\n\n return this;\n }\n\n has<T>(token: Token<T>): boolean {\n this.#assertActive();\n\n return this.#lookup(token) !== undefined;\n }\n\n async resolve<T>(token: Token<T>): Promise<T> {\n this.#assertActive();\n\n return this.#resolve(token, []);\n }\n\n validate(): this {\n this.#assertActive();\n\n for (const { owner, registration, token } of this.#factories()) {\n owner.#validatePath(token, registration, new Set(), []);\n }\n\n return this;\n }\n\n createScope(scope?: ScopeToken, options?: { name?: string }): Container {\n this.#assertActive();\n\n return new ContainerImpl(this, { name: options?.name, scope });\n }\n\n dispose(): Promise<void> {\n if (this.#lifecycle === 'disposed') return Promise.resolve();\n\n if (this.#disposePromise) return this.#disposePromise;\n\n this.#lifecycle = 'disposing';\n this.#disposalController.abort();\n this.#disposePromise = this.#finishDisposal();\n\n return this.#disposePromise;\n }\n\n async #finishDisposal(): Promise<void> {\n const childOutcomes = await Promise.allSettled([...this.#children].map((child) => child.dispose()));\n\n await Promise.allSettled([...this.#inFlight]);\n\n const failures = [\n ...this.#cleanupFailures,\n ...childOutcomes.flatMap((outcome) => {\n if (outcome.status !== 'rejected') return [];\n\n return outcome.reason instanceof ConduitDisposeError ? outcome.reason.errors : [outcome.reason];\n }),\n ];\n\n for (const resource of [...this.#owned].reverse()) {\n if (!resource.dispose) continue;\n\n try {\n await resource.dispose(resource.value as never);\n } catch (error) {\n failures.push(error);\n }\n }\n\n this.#cache.clear();\n this.#children.clear();\n this.#cleanupFailures = [];\n this.#owned = [];\n this.#registry.clear();\n\n if (this.#parent) this.#parent.#children.delete(this);\n\n this.#lifecycle = 'disposed';\n\n if (failures.length) throw new ConduitDisposeError(failures);\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.dispose();\n }\n\n #assertActive(): void {\n if (this.#lifecycle !== 'active') throw new ConduitDisposedError(this.name);\n }\n\n #assertUnregistered(token: Token<unknown>): void {\n if (this.#registry.has(token)) throw new ConduitDuplicateRegistrationError(token);\n }\n\n #lookup<T>(token: Token<T>): { owner: ContainerImpl; registration: Registration<T> } | undefined {\n const local = this.#registry.get(token) as Registration<T> | undefined;\n\n if (local) return { owner: this, registration: local };\n\n if (!this.#parent) return undefined;\n\n return this.#parent.#lookup(token);\n }\n\n #factories(): { owner: ContainerImpl; registration: FactoryRegistration; token: Token<unknown> }[] {\n const parentFactories = this.#parent ? this.#parent.#factories() : [];\n const localFactories = [...this.#registry].flatMap(([token, registration]) =>\n registration.kind === 'factory' ? [{ owner: this, registration, token }] : [],\n );\n\n return [...parentFactories, ...localFactories];\n }\n\n #validatePath(\n token: Token<unknown>,\n registration: FactoryRegistration,\n visiting: Set<Token<unknown>>,\n path: Token<unknown>[],\n ): void {\n if (visiting.has(token)) throw new ConduitCircularDependencyError([...path, token]);\n\n visiting.add(token);\n\n for (const dependency of registration.dependencies) {\n const found = this.#lookup(dependency);\n\n if (!found) throw new ConduitProviderNotFoundError(dependency, this.name);\n\n if (found.registration.kind === 'factory') {\n found.owner.#validatePath(dependency, found.registration, visiting, [...path, token]);\n }\n }\n\n visiting.delete(token);\n }\n\n async #resolve<T>(token: Token<T>, path: Token<unknown>[]): Promise<T> {\n if (path.includes(token)) throw new ConduitCircularDependencyError([...path, token]);\n\n const found = this.#lookup(token);\n\n if (!found) throw new ConduitProviderNotFoundError(token, this.name);\n\n if (found.registration.kind === 'value') return found.registration.value as T;\n\n const owner = this.#ownerFor(found.owner, found.registration, token);\n\n if (found.registration.lifetime === 'transient') {\n return this.#create(found.registration, owner, [...path, token]) as Promise<T>;\n }\n\n const existing = owner.#cache.get(found.registration);\n\n if (existing?.value !== undefined) return existing.value as T;\n\n if (existing?.promise) return existing.promise as Promise<T>;\n\n const entry: CacheEntry = {};\n const promise = owner.#create(found.registration, owner, [...path, token]).then((value) => {\n entry.value = value;\n\n return value;\n });\n\n entry.promise = promise;\n owner.#cache.set(found.registration, entry);\n\n return promise as Promise<T>;\n }\n\n #ownerFor(owner: ContainerImpl, registration: FactoryRegistration, token: Token<unknown>): ContainerImpl {\n if (registration.lifetime === 'singleton') return owner;\n\n if (registration.lifetime === 'transient') return this;\n\n const scope = this.#scopeOwner(registration.lifetime);\n\n if (!scope) throw new ConduitScopedResolutionError(token, registration.lifetime);\n\n return scope;\n }\n\n #scopeOwner(scope: ScopeToken): ContainerImpl | undefined {\n if (this.#scope === scope) return this;\n\n return this.#parent ? this.#parent.#scopeOwner(scope) : undefined;\n }\n\n async #create(registration: FactoryRegistration, owner: ContainerImpl, path: Token<unknown>[]): Promise<unknown> {\n const promise = Promise.all(registration.dependencies.map((dependency) => owner.#resolve(dependency, path))).then(\n (dependencies) => registration.create(...dependencies),\n );\n\n owner.#inFlight.add(promise);\n\n try {\n const value = await promise;\n\n if (owner.#lifecycle !== 'active') {\n if (registration.dispose) {\n try {\n await registration.dispose(value as never);\n } catch (error) {\n owner.#cleanupFailures.push(error);\n }\n }\n\n throw new ConduitDisposedError(owner.name);\n }\n\n if (registration.dispose) owner.#owned.push({ dispose: registration.dispose, value });\n\n return value;\n } finally {\n owner.#inFlight.delete(promise);\n }\n }\n}\n\nexport function createContainer(options?: { name?: string }): Container {\n return new ContainerImpl(undefined, options);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"container.js","names":[],"sources":["../src/container.ts"],"sourcesContent":["import {\n ConduitCircularDependencyError,\n ConduitDisposedError,\n ConduitDisposeError,\n ConduitDuplicateRegistrationError,\n ConduitError,\n ConduitProviderNotFoundError,\n ConduitScopedResolutionError,\n} from './errors.js';\nimport type {\n Container,\n FactoryProvider,\n InferServices,\n Lifetime,\n Provider,\n ScopeToken,\n ServiceMap,\n Token,\n ValueProvider,\n} from './types.js';\nimport { disposalSignalToken } from './types.js';\n\ntype Disposer = (value: unknown) => Promise<void> | void;\n\ntype ValueRegistration<T> = Readonly<{\n dispose?: Disposer;\n kind: 'value';\n value: T;\n}>;\n\ntype FactoryRegistration<T = unknown> = Readonly<{\n factory: (...values: unknown[]) => Promise<T> | T;\n dependencies: readonly Token<unknown>[];\n dispose?: Disposer;\n kind: 'factory';\n lifetime: Lifetime;\n}>;\n\ntype Registration<T = unknown> = FactoryRegistration<T> | ValueRegistration<T>;\ntype OwnedResource = Readonly<{ dispose?: Disposer; value: unknown }>;\ntype CacheEntry = { promise: Promise<unknown>; resolved: boolean; value?: unknown };\ntype Lifecycle = 'active' | 'disposed' | 'disposing';\n\nclass ContainerImpl implements Container {\n #cache = new Map<FactoryRegistration<unknown>, CacheEntry>();\n #children = new Set<ContainerImpl>();\n #cleanupFailures: unknown[] = [];\n #disposalController = new AbortController();\n #inFlight = new Set<Promise<unknown>>();\n #lifecycle: Lifecycle = 'active';\n #disposePromise?: Promise<void>;\n #owned: OwnedResource[] = [];\n #parent?: ContainerImpl;\n #registry = new Map<Token<unknown>, Registration<unknown>>();\n #scope?: ScopeToken;\n readonly name: string;\n\n constructor(\n parent: ContainerImpl | undefined,\n providers: readonly Provider<any, any>[],\n options: { name?: string; scope?: ScopeToken },\n ) {\n this.#parent = parent;\n this.#scope = options.scope;\n\n if (parent) parent.#children.add(this);\n\n this.name = options.name ?? (parent ? `${parent.name}:${options.scope?.description ?? 'child'}` : 'root');\n this.#registry.set(disposalSignalToken, { kind: 'value', value: this.disposalSignal });\n\n try {\n this.#registerProviders(providers);\n this.#validateGraph();\n this.#claimValues();\n } catch (error) {\n if (parent) parent.#children.delete(this);\n this.#registry.clear();\n throw error;\n }\n }\n\n get disposalSignal(): AbortSignal {\n return this.#disposalController.signal;\n }\n\n get disposed(): boolean {\n return this.#lifecycle === 'disposed';\n }\n\n has<T>(token: Token<T>): boolean {\n this.#assertActive();\n\n return this.#lookup(token) !== undefined;\n }\n\n resolve<T>(token: Token<T>): Promise<T>;\n resolve<M extends ServiceMap>(map: M): Promise<InferServices<M>>;\n async resolve<T, M extends ServiceMap>(input: Token<T> | M): Promise<InferServices<M> | T> {\n this.#assertActive();\n\n if (typeof input === 'symbol') return this.#resolve(input, []);\n if (typeof input !== 'object' || input === null || Array.isArray(input)) {\n throw new ConduitError('resolve() requires a token or service map');\n }\n\n const entries = Object.keys(input) as (keyof M & string)[];\n const values = await Promise.all(entries.map((key) => this.#resolve(input[key] as Token<unknown>, [])));\n const services = {} as InferServices<M>;\n\n entries.forEach((key, index) => {\n Object.defineProperty(services, key, {\n configurable: true,\n enumerable: true,\n value: values[index],\n writable: true,\n });\n });\n\n return services;\n }\n\n createScope(\n scope?: ScopeToken,\n options?: { readonly name?: string; readonly providers?: readonly Provider<any, any>[] },\n ): Container {\n this.#assertActive();\n\n return new ContainerImpl(this, options?.providers ?? [], { name: options?.name, scope });\n }\n\n dispose(): Promise<void> {\n if (this.#lifecycle === 'disposed') return Promise.resolve();\n\n if (this.#disposePromise) return this.#disposePromise;\n\n this.#lifecycle = 'disposing';\n this.#disposalController.abort();\n this.#disposePromise = this.#finishDisposal();\n\n return this.#disposePromise;\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.dispose();\n }\n\n async #finishDisposal(): Promise<void> {\n const childOutcomes = await Promise.allSettled([...this.#children].map((child) => child.dispose()));\n\n await Promise.allSettled([...this.#inFlight]);\n\n const failures = [\n ...this.#cleanupFailures,\n ...childOutcomes.flatMap((outcome) => {\n if (outcome.status !== 'rejected') return [];\n\n return outcome.reason instanceof ConduitDisposeError ? outcome.reason.errors : [outcome.reason];\n }),\n ];\n\n for (const resource of [...this.#owned].reverse()) {\n if (!resource.dispose) continue;\n\n try {\n await resource.dispose(resource.value);\n } catch (error) {\n failures.push(error);\n }\n }\n\n this.#cache.clear();\n this.#children.clear();\n this.#cleanupFailures = [];\n this.#owned = [];\n this.#registry.clear();\n\n if (this.#parent) this.#parent.#children.delete(this);\n\n this.#lifecycle = 'disposed';\n\n if (failures.length) throw new ConduitDisposeError(failures);\n }\n\n #assertActive(): void {\n if (this.#lifecycle !== 'active') throw new ConduitDisposedError(this.name);\n }\n\n #assertUnregistered(token: Token<unknown>): void {\n if (this.#registry.has(token)) throw new ConduitDuplicateRegistrationError(token);\n }\n\n #registerProviders(providers: readonly Provider<any, any>[]): void {\n if (!Array.isArray(providers)) throw new ConduitError('Container providers must be an array');\n\n for (const input of providers) {\n if (typeof input !== 'object' || input === null || Array.isArray(input)) {\n throw new ConduitError('Each provider must be an object');\n }\n\n const provider = input as Provider;\n const hasDependencies = Object.hasOwn(provider, 'dependencies');\n const hasFactory = Object.hasOwn(provider, 'factory');\n const hasValue = Object.hasOwn(provider, 'value');\n\n if (typeof provider.token !== 'symbol') throw new ConduitError('Each provider requires a token');\n if (provider.dispose !== undefined && typeof provider.dispose !== 'function') {\n throw new ConduitError(`Provider \"${provider.token.description ?? 'anonymous'}\" has an invalid disposer`);\n }\n if (\n hasValue === hasFactory ||\n hasValue === hasDependencies ||\n (hasValue && Object.hasOwn(provider, 'lifetime'))\n ) {\n throw new ConduitError(\n `Provider \"${provider.token.description ?? 'anonymous'}\" must define exactly one value or factory`,\n );\n }\n\n this.#assertUnregistered(provider.token);\n\n if (hasFactory) {\n const factory = provider as FactoryProvider<unknown>;\n\n if (\n !Array.isArray(factory.dependencies) ||\n factory.dependencies.some((dependency) => typeof dependency !== 'symbol')\n ) {\n throw new ConduitError(\n `Factory provider \"${provider.token.description ?? 'anonymous'}\" has invalid dependencies`,\n );\n }\n if (typeof factory.factory !== 'function') {\n throw new ConduitError(`Factory provider \"${provider.token.description ?? 'anonymous'}\" requires a factory`);\n }\n if (\n factory.lifetime !== undefined &&\n factory.lifetime !== 'singleton' &&\n factory.lifetime !== 'transient' &&\n typeof factory.lifetime !== 'symbol'\n ) {\n throw new ConduitError(\n `Factory provider \"${provider.token.description ?? 'anonymous'}\" has an invalid lifetime`,\n );\n }\n\n this.#registry.set(provider.token, {\n dependencies: Object.freeze([...factory.dependencies]),\n dispose: factory.dispose as Disposer | undefined,\n factory: factory.factory as (...values: unknown[]) => Promise<unknown> | unknown,\n kind: 'factory',\n lifetime: factory.lifetime ?? 'singleton',\n });\n } else {\n const valueProvider = provider as ValueProvider<unknown>;\n\n this.#registry.set(provider.token, {\n dispose: valueProvider.dispose as Disposer | undefined,\n kind: 'value',\n value: valueProvider.value,\n });\n }\n }\n }\n\n #claimValues(): void {\n for (const registration of this.#registry.values()) {\n if (registration.kind === 'value' && registration.dispose) {\n this.#owned.push({ dispose: registration.dispose, value: registration.value });\n }\n }\n }\n\n #lookup<T>(token: Token<T>): { owner: ContainerImpl; registration: Registration<T> } | undefined {\n const local = this.#registry.get(token) as Registration<T> | undefined;\n\n if (local) return { owner: this, registration: local };\n\n if (!this.#parent) return undefined;\n\n return this.#parent.#lookup(token);\n }\n\n #factories(): { owner: ContainerImpl; registration: FactoryRegistration; token: Token<unknown> }[] {\n const parentFactories = this.#parent ? this.#parent.#factories() : [];\n const localFactories = [...this.#registry].flatMap(([token, registration]) =>\n registration.kind === 'factory' ? [{ owner: this, registration, token }] : [],\n );\n\n return [...parentFactories, ...localFactories];\n }\n\n #validateGraph(): void {\n for (const { owner, registration, token } of this.#factories()) {\n owner.#validatePath(token, registration, new Set(), []);\n }\n }\n\n #validatePath(\n token: Token<unknown>,\n registration: FactoryRegistration,\n visiting: Set<Token<unknown>>,\n path: Token<unknown>[],\n ): void {\n if (visiting.has(token)) throw new ConduitCircularDependencyError([...path, token]);\n\n visiting.add(token);\n\n for (const dependency of registration.dependencies) {\n const found = this.#lookup(dependency);\n\n if (!found) throw new ConduitProviderNotFoundError(dependency, this.name);\n\n if (found.registration.kind === 'factory') {\n if (registration.lifetime === 'singleton' && found.registration.lifetime === 'transient') {\n throw new ConduitError(\n `Singleton \"${token.description ?? 'anonymous'}\" cannot depend on a transient factory`,\n );\n }\n if (registration.lifetime === 'singleton' && typeof found.registration.lifetime === 'symbol') {\n throw new ConduitScopedResolutionError(token, found.registration.lifetime);\n }\n if (\n typeof registration.lifetime === 'symbol' &&\n typeof found.registration.lifetime === 'symbol' &&\n registration.lifetime !== found.registration.lifetime\n ) {\n throw new ConduitScopedResolutionError(token, found.registration.lifetime);\n }\n\n found.owner.#validatePath(dependency, found.registration, visiting, [...path, token]);\n }\n }\n\n visiting.delete(token);\n }\n\n async #resolve<T>(token: Token<T>, path: Token<unknown>[]): Promise<T> {\n if (path.includes(token)) throw new ConduitCircularDependencyError([...path, token]);\n\n const found = this.#lookup(token);\n\n if (!found) throw new ConduitProviderNotFoundError(token, this.name);\n\n const registration = found.registration;\n\n if (registration.kind === 'value') return registration.value as T;\n\n const owner = this.#ownerFor(found.owner, registration, token);\n\n if (registration.lifetime === 'transient') {\n return owner.#track(owner.#create(registration, owner, [...path, token])) as Promise<T>;\n }\n\n const existing = owner.#cache.get(registration);\n\n if (existing?.resolved) return existing.value as T;\n if (existing) return existing.promise as Promise<T>;\n\n const entry = { promise: Promise.resolve(), resolved: false } as CacheEntry;\n const creation = owner.#create(registration, owner, [...path, token]).then(\n (value) => {\n entry.resolved = true;\n entry.value = value;\n return value;\n },\n (error) => {\n if (owner.#cache.get(registration) === entry) owner.#cache.delete(registration);\n throw error;\n },\n );\n\n entry.promise = owner.#track(creation);\n owner.#cache.set(registration, entry);\n\n return entry.promise as Promise<T>;\n }\n\n #ownerFor(owner: ContainerImpl, registration: FactoryRegistration, token: Token<unknown>): ContainerImpl {\n if (registration.lifetime === 'singleton') return owner;\n if (registration.lifetime === 'transient') return this;\n\n const scopeOwner = this.#scopeOwner(registration.lifetime as ScopeToken);\n\n if (!scopeOwner) throw new ConduitScopedResolutionError(token, registration.lifetime as ScopeToken);\n\n return scopeOwner;\n }\n\n #scopeOwner(scope: ScopeToken): ContainerImpl | undefined {\n if (this.#scope === scope) return this;\n\n return this.#parent ? this.#parent.#scopeOwner(scope) : undefined;\n }\n\n #track<T>(promise: Promise<T>): Promise<T> {\n this.#inFlight.add(promise);\n void promise.then(\n () => this.#inFlight.delete(promise),\n () => this.#inFlight.delete(promise),\n );\n return promise;\n }\n\n async #create(registration: FactoryRegistration, owner: ContainerImpl, path: Token<unknown>[]): Promise<unknown> {\n const value = await Promise.all(\n registration.dependencies.map((dependency) => owner.#resolve(dependency, path)),\n ).then((dependencies) => registration.factory(...dependencies));\n\n if (owner.#lifecycle !== 'active') {\n if (registration.dispose) {\n try {\n await registration.dispose(value);\n } catch (error) {\n owner.#cleanupFailures.push(error);\n }\n }\n\n throw new ConduitDisposedError(owner.name);\n }\n\n if (registration.dispose) owner.#owned.push({ dispose: registration.dispose, value });\n\n return value;\n }\n}\n\nexport function createContainer(\n providers: readonly Provider<any, any>[],\n options?: { readonly name?: string },\n): Container {\n return new ContainerImpl(undefined, providers, { name: options?.name });\n}\n"],"mappings":"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"}
package/dist/errors.cjs CHANGED
@@ -1,2 +1,2 @@
1
- function e(e){return e.description??`anonymous`}var t=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},n=class extends t{cycle;constructor(t){super(`Circular dependency detected: ${t.map(e).join(` -> `)}`),this.cycle=t}},r=class extends t{containerName;token;constructor(t,n){super(`No provider registered for token: ${e(t)} (in container '${n}')`),this.containerName=n,this.token=t}},i=class extends t{token;constructor(t){super(`Token "${e(t)}" is already registered.`),this.token=t}},a=class extends t{requiredScope;token;constructor(t,n){super(`Token "${e(t)}" requires scope "${n.description??`anonymous`}".`),this.requiredScope=n,this.token=t}},o=class extends t{containerName;constructor(e){super(`Cannot use disposed container '${e}'.`),this.containerName=e}},s=class extends t{errors;constructor(e){super(`Container disposal failed with ${e.length} cleanup error${e.length===1?``:`s`}.`),this.errors=e}};exports.ConduitCircularDependencyError=n,exports.ConduitDisposeError=s,exports.ConduitDisposedError=o,exports.ConduitDuplicateRegistrationError=i,exports.ConduitError=t,exports.ConduitProviderNotFoundError=r,exports.ConduitScopedResolutionError=a,exports.tokenName=e;
1
+ function e(e){return e.description??`anonymous`}var t=class extends Error{static errorName=`ConduitError`;constructor(e,t){super(e,t),this.name=new.target.errorName,Object.setPrototypeOf(this,new.target.prototype)}},n=class extends t{static errorName=`ConduitCircularDependencyError`;cycle;constructor(t){super(`Circular dependency detected: ${t.map(e).join(` -> `)}`),this.cycle=Object.freeze([...t])}},r=class extends t{static errorName=`ConduitProviderNotFoundError`;containerName;token;constructor(t,n){super(`No provider registered for token: ${e(t)} (in container '${n}')`),this.containerName=n,this.token=t}},i=class extends t{static errorName=`ConduitDuplicateRegistrationError`;token;constructor(t){super(`Token "${e(t)}" is already registered.`),this.token=t}},a=class extends t{static errorName=`ConduitScopedResolutionError`;requiredScope;token;constructor(t,n){super(`Token "${e(t)}" requires scope "${n.description??`anonymous`}".`),this.requiredScope=n,this.token=t}},o=class extends t{static errorName=`ConduitDisposedError`;containerName;constructor(e){super(`Cannot use disposed container '${e}'.`),this.containerName=e}},s=class extends t{static errorName=`ConduitDisposeError`;errors;constructor(e){super(`Container disposal failed with ${e.length} cleanup error${e.length===1?``:`s`}.`),this.errors=Object.freeze([...e])}};exports.ConduitCircularDependencyError=n,exports.ConduitDisposeError=s,exports.ConduitDisposedError=o,exports.ConduitDuplicateRegistrationError=i,exports.ConduitError=t,exports.ConduitProviderNotFoundError=r,exports.ConduitScopedResolutionError=a,exports.tokenName=e;
2
2
  //# sourceMappingURL=errors.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["import type { ScopeToken, Token } from './types.js';\n\nexport function tokenName(token: Token<unknown>): string {\n return token.description ?? 'anonymous';\n}\n\nexport class ConduitError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class ConduitCircularDependencyError extends ConduitError {\n readonly cycle: Token<unknown>[];\n\n constructor(cycle: Token<unknown>[]) {\n super(`Circular dependency detected: ${cycle.map(tokenName).join(' -> ')}`);\n this.cycle = cycle;\n }\n}\n\nexport class ConduitProviderNotFoundError extends ConduitError {\n readonly containerName: string;\n readonly token: Token<unknown>;\n\n constructor(token: Token<unknown>, containerName: string) {\n super(`No provider registered for token: ${tokenName(token)} (in container '${containerName}')`);\n this.containerName = containerName;\n this.token = token;\n }\n}\n\nexport class ConduitDuplicateRegistrationError extends ConduitError {\n readonly token: Token<unknown>;\n\n constructor(token: Token<unknown>) {\n super(`Token \"${tokenName(token)}\" is already registered.`);\n this.token = token;\n }\n}\n\nexport class ConduitScopedResolutionError extends ConduitError {\n readonly requiredScope: ScopeToken;\n readonly token: Token<unknown>;\n\n constructor(token: Token<unknown>, requiredScope: ScopeToken) {\n super(`Token \"${tokenName(token)}\" requires scope \"${requiredScope.description ?? 'anonymous'}\".`);\n this.requiredScope = requiredScope;\n this.token = token;\n }\n}\n\nexport class ConduitDisposedError extends ConduitError {\n readonly containerName: string;\n\n constructor(containerName: string) {\n super(`Cannot use disposed container '${containerName}'.`);\n this.containerName = containerName;\n }\n}\n\nexport class ConduitDisposeError extends ConduitError {\n readonly errors: unknown[];\n\n constructor(errors: unknown[]) {\n super(`Container disposal failed with ${errors.length} cleanup error${errors.length === 1 ? '' : 's'}.`);\n this.errors = errors;\n }\n}\n"],"mappings":"AAEA,SAAgB,EAAU,EAA+B,CACvD,OAAO,EAAM,aAAe,WAC9B,CAEA,IAAa,EAAb,cAAkC,KAAM,CACtC,YAAY,EAAiB,EAAwB,CACnD,MAAM,EAAS,CAAO,EACtB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAEa,EAAb,cAAoD,CAAa,CAC/D,MAEA,YAAY,EAAyB,CACnC,MAAM,iCAAiC,EAAM,IAAI,CAAS,CAAC,CAAC,KAAK,MAAM,GAAG,EAC1E,KAAK,MAAQ,CACf,CACF,EAEa,EAAb,cAAkD,CAAa,CAC7D,cACA,MAEA,YAAY,EAAuB,EAAuB,CACxD,MAAM,qCAAqC,EAAU,CAAK,EAAE,kBAAkB,EAAc,GAAG,EAC/F,KAAK,cAAgB,EACrB,KAAK,MAAQ,CACf,CACF,EAEa,EAAb,cAAuD,CAAa,CAClE,MAEA,YAAY,EAAuB,CACjC,MAAM,UAAU,EAAU,CAAK,EAAE,yBAAyB,EAC1D,KAAK,MAAQ,CACf,CACF,EAEa,EAAb,cAAkD,CAAa,CAC7D,cACA,MAEA,YAAY,EAAuB,EAA2B,CAC5D,MAAM,UAAU,EAAU,CAAK,EAAE,oBAAoB,EAAc,aAAe,YAAY,GAAG,EACjG,KAAK,cAAgB,EACrB,KAAK,MAAQ,CACf,CACF,EAEa,EAAb,cAA0C,CAAa,CACrD,cAEA,YAAY,EAAuB,CACjC,MAAM,kCAAkC,EAAc,GAAG,EACzD,KAAK,cAAgB,CACvB,CACF,EAEa,EAAb,cAAyC,CAAa,CACpD,OAEA,YAAY,EAAmB,CAC7B,MAAM,kCAAkC,EAAO,OAAO,gBAAgB,EAAO,SAAW,EAAI,GAAK,IAAI,EAAE,EACvG,KAAK,OAAS,CAChB,CACF"}
1
+ {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["import type { ScopeToken, Token } from './types.js';\n\nexport function tokenName(token: Token<unknown>): string {\n return token.description ?? 'anonymous';\n}\n\nexport class ConduitError extends Error {\n protected static readonly errorName: string = 'ConduitError';\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = (new.target as typeof ConduitError).errorName;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class ConduitCircularDependencyError extends ConduitError {\n protected static override readonly errorName = 'ConduitCircularDependencyError';\n readonly cycle: readonly Token<unknown>[];\n\n constructor(cycle: readonly Token<unknown>[]) {\n super(`Circular dependency detected: ${cycle.map(tokenName).join(' -> ')}`);\n this.cycle = Object.freeze([...cycle]);\n }\n}\n\nexport class ConduitProviderNotFoundError extends ConduitError {\n protected static override readonly errorName = 'ConduitProviderNotFoundError';\n readonly containerName: string;\n readonly token: Token<unknown>;\n\n constructor(token: Token<unknown>, containerName: string) {\n super(`No provider registered for token: ${tokenName(token)} (in container '${containerName}')`);\n this.containerName = containerName;\n this.token = token;\n }\n}\n\nexport class ConduitDuplicateRegistrationError extends ConduitError {\n protected static override readonly errorName = 'ConduitDuplicateRegistrationError';\n readonly token: Token<unknown>;\n\n constructor(token: Token<unknown>) {\n super(`Token \"${tokenName(token)}\" is already registered.`);\n this.token = token;\n }\n}\n\nexport class ConduitScopedResolutionError extends ConduitError {\n protected static override readonly errorName = 'ConduitScopedResolutionError';\n readonly requiredScope: ScopeToken;\n readonly token: Token<unknown>;\n\n constructor(token: Token<unknown>, requiredScope: ScopeToken) {\n super(`Token \"${tokenName(token)}\" requires scope \"${requiredScope.description ?? 'anonymous'}\".`);\n this.requiredScope = requiredScope;\n this.token = token;\n }\n}\n\nexport class ConduitDisposedError extends ConduitError {\n protected static override readonly errorName = 'ConduitDisposedError';\n readonly containerName: string;\n\n constructor(containerName: string) {\n super(`Cannot use disposed container '${containerName}'.`);\n this.containerName = containerName;\n }\n}\n\nexport class ConduitDisposeError extends ConduitError {\n protected static override readonly errorName = 'ConduitDisposeError';\n readonly errors: readonly unknown[];\n\n constructor(errors: readonly unknown[]) {\n super(`Container disposal failed with ${errors.length} cleanup error${errors.length === 1 ? '' : 's'}.`);\n this.errors = Object.freeze([...errors]);\n }\n}\n"],"mappings":"AAEA,SAAgB,EAAU,EAA+B,CACvD,OAAO,EAAM,aAAe,WAC9B,CAEA,IAAa,EAAb,cAAkC,KAAM,CACtC,OAA0B,UAAoB,eAE9C,YAAY,EAAiB,EAAwB,CACnD,MAAM,EAAS,CAAO,EACtB,KAAK,KAAQ,WAAmC,UAChD,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAEa,EAAb,cAAoD,CAAa,CAC/D,OAAmC,UAAY,iCAC/C,MAEA,YAAY,EAAkC,CAC5C,MAAM,iCAAiC,EAAM,IAAI,CAAS,CAAC,CAAC,KAAK,MAAM,GAAG,EAC1E,KAAK,MAAQ,OAAO,OAAO,CAAC,GAAG,CAAK,CAAC,CACvC,CACF,EAEa,EAAb,cAAkD,CAAa,CAC7D,OAAmC,UAAY,+BAC/C,cACA,MAEA,YAAY,EAAuB,EAAuB,CACxD,MAAM,qCAAqC,EAAU,CAAK,EAAE,kBAAkB,EAAc,GAAG,EAC/F,KAAK,cAAgB,EACrB,KAAK,MAAQ,CACf,CACF,EAEa,EAAb,cAAuD,CAAa,CAClE,OAAmC,UAAY,oCAC/C,MAEA,YAAY,EAAuB,CACjC,MAAM,UAAU,EAAU,CAAK,EAAE,yBAAyB,EAC1D,KAAK,MAAQ,CACf,CACF,EAEa,EAAb,cAAkD,CAAa,CAC7D,OAAmC,UAAY,+BAC/C,cACA,MAEA,YAAY,EAAuB,EAA2B,CAC5D,MAAM,UAAU,EAAU,CAAK,EAAE,oBAAoB,EAAc,aAAe,YAAY,GAAG,EACjG,KAAK,cAAgB,EACrB,KAAK,MAAQ,CACf,CACF,EAEa,EAAb,cAA0C,CAAa,CACrD,OAAmC,UAAY,uBAC/C,cAEA,YAAY,EAAuB,CACjC,MAAM,kCAAkC,EAAc,GAAG,EACzD,KAAK,cAAgB,CACvB,CACF,EAEa,EAAb,cAAyC,CAAa,CACpD,OAAmC,UAAY,sBAC/C,OAEA,YAAY,EAA4B,CACtC,MAAM,kCAAkC,EAAO,OAAO,gBAAgB,EAAO,SAAW,EAAI,GAAK,IAAI,EAAE,EACvG,KAAK,OAAS,OAAO,OAAO,CAAC,GAAG,CAAM,CAAC,CACzC,CACF"}
package/dist/errors.d.ts CHANGED
@@ -1,32 +1,39 @@
1
1
  import type { ScopeToken, Token } from './types.js';
2
2
  export declare function tokenName(token: Token<unknown>): string;
3
3
  export declare class ConduitError extends Error {
4
+ protected static readonly errorName: string;
4
5
  constructor(message: string, options?: ErrorOptions);
5
6
  }
6
7
  export declare class ConduitCircularDependencyError extends ConduitError {
7
- readonly cycle: Token<unknown>[];
8
- constructor(cycle: Token<unknown>[]);
8
+ protected static readonly errorName = "ConduitCircularDependencyError";
9
+ readonly cycle: readonly Token<unknown>[];
10
+ constructor(cycle: readonly Token<unknown>[]);
9
11
  }
10
12
  export declare class ConduitProviderNotFoundError extends ConduitError {
13
+ protected static readonly errorName = "ConduitProviderNotFoundError";
11
14
  readonly containerName: string;
12
15
  readonly token: Token<unknown>;
13
16
  constructor(token: Token<unknown>, containerName: string);
14
17
  }
15
18
  export declare class ConduitDuplicateRegistrationError extends ConduitError {
19
+ protected static readonly errorName = "ConduitDuplicateRegistrationError";
16
20
  readonly token: Token<unknown>;
17
21
  constructor(token: Token<unknown>);
18
22
  }
19
23
  export declare class ConduitScopedResolutionError extends ConduitError {
24
+ protected static readonly errorName = "ConduitScopedResolutionError";
20
25
  readonly requiredScope: ScopeToken;
21
26
  readonly token: Token<unknown>;
22
27
  constructor(token: Token<unknown>, requiredScope: ScopeToken);
23
28
  }
24
29
  export declare class ConduitDisposedError extends ConduitError {
30
+ protected static readonly errorName = "ConduitDisposedError";
25
31
  readonly containerName: string;
26
32
  constructor(containerName: string);
27
33
  }
28
34
  export declare class ConduitDisposeError extends ConduitError {
29
- readonly errors: unknown[];
30
- constructor(errors: unknown[]);
35
+ protected static readonly errorName = "ConduitDisposeError";
36
+ readonly errors: readonly unknown[];
37
+ constructor(errors: readonly unknown[]);
31
38
  }
32
39
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEpD,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,MAAM,CAEvD;AAED,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAKpD;AAED,qBAAa,8BAA+B,SAAQ,YAAY;IAC9D,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;gBAErB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE;CAIpC;AAED,qBAAa,4BAA6B,SAAQ,YAAY;IAC5D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBAEnB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,MAAM;CAKzD;AAED,qBAAa,iCAAkC,SAAQ,YAAY;IACjE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBAEnB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;CAIlC;AAED,qBAAa,4BAA6B,SAAQ,YAAY;IAC5D,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBAEnB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,UAAU;CAK7D;AAED,qBAAa,oBAAqB,SAAQ,YAAY;IACpD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBAEnB,aAAa,EAAE,MAAM;CAIlC;AAED,qBAAa,mBAAoB,SAAQ,YAAY;IACnD,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;gBAEf,MAAM,EAAE,OAAO,EAAE;CAI9B"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEpD,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,MAAM,CAEvD;AAED,qBAAa,YAAa,SAAQ,KAAK;IACrC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAkB;gBAEjD,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAKpD;AAED,qBAAa,8BAA+B,SAAQ,YAAY;IAC9D,0BAAmC,SAAS,oCAAoC;IAChF,QAAQ,CAAC,KAAK,EAAE,SAAS,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;gBAE9B,KAAK,EAAE,SAAS,KAAK,CAAC,OAAO,CAAC,EAAE;CAI7C;AAED,qBAAa,4BAA6B,SAAQ,YAAY;IAC5D,0BAAmC,SAAS,kCAAkC;IAC9E,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBAEnB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,MAAM;CAKzD;AAED,qBAAa,iCAAkC,SAAQ,YAAY;IACjE,0BAAmC,SAAS,uCAAuC;IACnF,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBAEnB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;CAIlC;AAED,qBAAa,4BAA6B,SAAQ,YAAY;IAC5D,0BAAmC,SAAS,kCAAkC;IAC9E,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBAEnB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,UAAU;CAK7D;AAED,qBAAa,oBAAqB,SAAQ,YAAY;IACpD,0BAAmC,SAAS,0BAA0B;IACtE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBAEnB,aAAa,EAAE,MAAM;CAIlC;AAED,qBAAa,mBAAoB,SAAQ,YAAY;IACnD,0BAAmC,SAAS,yBAAyB;IACrE,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;gBAExB,MAAM,EAAE,SAAS,OAAO,EAAE;CAIvC"}