async-injection 1.5.3 → 1.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Changelog.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 1.5.5 / 2024-01-18
2
+ * Backwards compatibly binder api updates.
3
+ * Update patch level dependencies.
4
+
5
+ ## 1.5.4 / 2023-11-15
6
+ * Improved handling of class constructor parameter type recognition.
7
+ * Update dependencies.
8
+
1
9
  ## 1.5.3 / 2023-06-05
2
10
  * Address esm issues [#10](https://github.com/pcafstockf/async-injection/issues/10) and [#15](https://github.com/pcafstockf/async-injection/issues/15)
3
11
  * Fix missing type overload on Binder interface.
@@ -73,7 +73,7 @@ export interface Binder extends Injector {
73
73
  * Bind an InjectableId to a constant value.
74
74
  * Constants are by their very nature singleton, and are assumed to be error proof.
75
75
  */
76
- bindConstant<T>(id: InjectableId<T>, value: T): void;
76
+ bindConstant<T>(id: InjectableId<T>, value: T): T;
77
77
  /**
78
78
  * Bind an InjectableId to a class (actually it's constructor).
79
79
  * As a shortcut, you may use the class constructor as the 'id' (e.g. container.bindClass(A); ).
@@ -1 +1 @@
1
- {"version":3,"file":"binder.js","sourceRoot":"","sources":["../../src/binder.ts"],"names":[],"mappings":"","sourcesContent":["import {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector.js';\n\n/**\n * Type definition for functions that return a value.\n * The function should return a valid value, but may throw an exception if it cannot.\n */\nexport type SyncFactory<T> = (injector: Injector) => T;\n\n/**\n * Type definition for functions that return a Promise for a value.\n * The function *must* not throw and must return a valid Promise (e.g. pending, resolved, rejected).\n */\nexport type AsyncFactory<T> = (injector: Injector) => Promise<T>;\n\n/**\n * You may bind an error handler which will be invoked, if the bound InjectableId could not be put into service.\n * An error handler *must* not throw, but may return an Error that will be propagated back up the call chain.\n *\n * @param binder The Binder that experienced the error.\n * @param id The identifier for what was trying to be made.\n * @param maker The thing that made (or tried to provideAsState). Will be one of type ClassConstructor, SyncFactory, or AsyncFactory, depending on how you registered the binding.\n * @param error Identifies the problem that occurred.\n * @param value If the 'maker' was able to create the thing, but it had an error during post construction, the made thing will be passed here.\n * @returns one of 3 results...\n * A substitute thing (kind of like a 'maker' do-over) which must be fully operational (e.g. any `@PostConstruct` will be ignored).\n * An alternate Error which will be propagated back up the call chain.\n * Undefined, which means the 'error' parameter will be propagated back up the call chain.\n */\nexport type OnErrorCallback<T, M> = (injector: Injector, id: InjectableId<T>, maker: M, error: unknown, value?: T) => T | Error | void;\n\n/**\n * You may bind a success handler which will be invoked just before the bound InjectableId is put into service.\n * This is an alternative to the more preferred `@PostConstruct` decorator for scenarios when usage of that decorator is not feasible.\n * WARNING:\n * By registering a success handler, you override and nullify any `@PostConstruct` decorator on the class.\n * In such a scenario, the success handler should perform whatever care and feeding the class expected from the `@PostConstruct` decorator.\n * A success handler *must* not throw, but may return an Error that will be propagated back up the call chain.\n *\n * @param binder The Binder that performed the construction.\n * @param id The identifier for what was made.\n * @param maker The thing that made. Will be one of type ClassConstructor, SyncFactory, or AsyncFactory, depending on how you registered the binding.\n * @param value The thing that was made.\n * @returns one of 3 results...\n * An Error which will be propagated back up the call chain.\n * Undefined, which means the object is ready to be placed into service.\n * A Promise that resolves to one of the above two values (undefined or Error).\n */\nexport type OnSuccessCallback<T, M> = (value: T, injector: Injector, id: InjectableId<T>, maker: M) => Promise<Error | void> | Error | void;\n\n/**\n * An interface allowing binding of an error handler.\n *\n * @see OnErrorCallback\n */\nexport interface BindErrHandler<T, M> {\n\tonError(cb: OnErrorCallback<T, M>): void;\n}\n\n/**\n * An interface allowing binding of a post construction handler.\n *\n * @see OnSuccessCallback\n */\nexport interface BindHandler<T, M> extends BindErrHandler<T, M> {\n\tonSuccess(cb: OnSuccessCallback<T, M>): BindErrHandler<T, M>;\n}\n\n/**\n * @inheritDoc\n * This specialization also allows you to specify that the binding is 'Singleton' (e.g. only one in the system).\n */\nexport interface BindAs<T, M> extends BindHandler<T, M> {\n\tasSingleton(): BindHandler<T, M>;\n}\n\n/**\n * Bind Ids to producers.\n */\nexport interface Binder extends Injector {\n\n\t/**\n\t * Bind an InjectableId to a constant value.\n\t * Constants are by their very nature singleton, and are assumed to be error proof.\n\t */\n\tbindConstant<T>(id: InjectableId<T>, value: T): void;\n\n\t/**\n\t * Bind an InjectableId to a class (actually it's constructor).\n\t * As a shortcut, you may use the class constructor as the 'id' (e.g. container.bindClass(A); ).\n\t * The container will also invoke any `@PostConstruct` present on the class.\n\t */\n\tbindClass<T>(id: ClassConstructor<T>, constructor?: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\n\tbindClass<T>(id: string | symbol | AbstractConstructor<T> | InjectableId<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\n\t/**\n\t * Bind an InjectableId to a synchronous factory that will be invoked on demand when the object is needed.\n\t * The factory should produce the needed value\n\t * NOTE: The container will not invoke any `@PostConstruct` present on the class, this is the responsibility of the factory.\n\t */\n\tbindFactory<T>(id: InjectableId<T>, factory: SyncFactory<T>): BindAs<T, SyncFactory<T>>;\n\n\t/**\n\t * Bind an InjectableId to an asynchronous factory that will be invoked on demand when the object is needed.\n\t * The factory should produce the needed value (asynchronously of course).\n\t * NOTE: The container will not invoke any `@PostConstruct` present on the class, this is the responsibility of the factory.\n\t * WARNING!!! The factory may not throw and must return a valid Promise (which can be pending, resolved, rejected, etc.).\n\t */\n\tbindAsyncFactory<T>(id: InjectableId<T>, factory: AsyncFactory<T>): BindAs<T, AsyncFactory<T>>;\n\n\t/**\n\t * This essentially pre creates/loads all *singleton* InjectableIds currently known to the Binder.\n\t * This *may* be helpful if you wish to use Injector.get on a dependency tree that has asynchronous singletons within the tree.\n\t *\n\t * @param asyncOnly Only resolve AsyncFactorys as well as any bound classes that have an asynchronous `@PostConstruct` decorator. WARNING: If true, SyncFactorys will *not* be resolved even if they are Singletons.\n\t * @param parentRecursion If true and the the container has a parent, resolveIfSingleton will first be called for the parent\n\t * @returns A Promise that resolves when all Singleton's have been resolved, OR rejects if one or more of the Singleton's failed to resolve. NOTE: Rejection does not occur until all Singleton resolutions have settled, and the rejection reason/err will be a Map<InjectableId, Error>\n\t */\n\tresolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this>;\n}\n"]}
1
+ {"version":3,"file":"binder.js","sourceRoot":"","sources":["../../src/binder.ts"],"names":[],"mappings":"","sourcesContent":["import {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector.js';\n\n/**\n * Type definition for functions that return a value.\n * The function should return a valid value, but may throw an exception if it cannot.\n */\nexport type SyncFactory<T> = (injector: Injector) => T;\n\n/**\n * Type definition for functions that return a Promise for a value.\n * The function *must* not throw and must return a valid Promise (e.g. pending, resolved, rejected).\n */\nexport type AsyncFactory<T> = (injector: Injector) => Promise<T>;\n\n/**\n * You may bind an error handler which will be invoked, if the bound InjectableId could not be put into service.\n * An error handler *must* not throw, but may return an Error that will be propagated back up the call chain.\n *\n * @param binder The Binder that experienced the error.\n * @param id The identifier for what was trying to be made.\n * @param maker The thing that made (or tried to provideAsState). Will be one of type ClassConstructor, SyncFactory, or AsyncFactory, depending on how you registered the binding.\n * @param error Identifies the problem that occurred.\n * @param value If the 'maker' was able to create the thing, but it had an error during post construction, the made thing will be passed here.\n * @returns one of 3 results...\n * A substitute thing (kind of like a 'maker' do-over) which must be fully operational (e.g. any `@PostConstruct` will be ignored).\n * An alternate Error which will be propagated back up the call chain.\n * Undefined, which means the 'error' parameter will be propagated back up the call chain.\n */\nexport type OnErrorCallback<T, M> = (injector: Injector, id: InjectableId<T>, maker: M, error: unknown, value?: T) => T | Error | void;\n\n/**\n * You may bind a success handler which will be invoked just before the bound InjectableId is put into service.\n * This is an alternative to the more preferred `@PostConstruct` decorator for scenarios when usage of that decorator is not feasible.\n * WARNING:\n * By registering a success handler, you override and nullify any `@PostConstruct` decorator on the class.\n * In such a scenario, the success handler should perform whatever care and feeding the class expected from the `@PostConstruct` decorator.\n * A success handler *must* not throw, but may return an Error that will be propagated back up the call chain.\n *\n * @param binder The Binder that performed the construction.\n * @param id The identifier for what was made.\n * @param maker The thing that made. Will be one of type ClassConstructor, SyncFactory, or AsyncFactory, depending on how you registered the binding.\n * @param value The thing that was made.\n * @returns one of 3 results...\n * An Error which will be propagated back up the call chain.\n * Undefined, which means the object is ready to be placed into service.\n * A Promise that resolves to one of the above two values (undefined or Error).\n */\nexport type OnSuccessCallback<T, M> = (value: T, injector: Injector, id: InjectableId<T>, maker: M) => Promise<Error | void> | Error | void;\n\n/**\n * An interface allowing binding of an error handler.\n *\n * @see OnErrorCallback\n */\nexport interface BindErrHandler<T, M> {\n\tonError(cb: OnErrorCallback<T, M>): void;\n}\n\n/**\n * An interface allowing binding of a post construction handler.\n *\n * @see OnSuccessCallback\n */\nexport interface BindHandler<T, M> extends BindErrHandler<T, M> {\n\tonSuccess(cb: OnSuccessCallback<T, M>): BindErrHandler<T, M>;\n}\n\n/**\n * @inheritDoc\n * This specialization also allows you to specify that the binding is 'Singleton' (e.g. only one in the system).\n */\nexport interface BindAs<T, M> extends BindHandler<T, M> {\n\tasSingleton(): BindHandler<T, M>;\n}\n\n/**\n * Bind Ids to producers.\n */\nexport interface Binder extends Injector {\n\n\t/**\n\t * Bind an InjectableId to a constant value.\n\t * Constants are by their very nature singleton, and are assumed to be error proof.\n\t */\n\tbindConstant<T>(id: InjectableId<T>, value: T): T;\n\n\t/**\n\t * Bind an InjectableId to a class (actually it's constructor).\n\t * As a shortcut, you may use the class constructor as the 'id' (e.g. container.bindClass(A); ).\n\t * The container will also invoke any `@PostConstruct` present on the class.\n\t */\n\tbindClass<T>(id: ClassConstructor<T>, constructor?: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\n\tbindClass<T>(id: string | symbol | AbstractConstructor<T> | InjectableId<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\n\t/**\n\t * Bind an InjectableId to a synchronous factory that will be invoked on demand when the object is needed.\n\t * The factory should produce the needed value\n\t * NOTE: The container will not invoke any `@PostConstruct` present on the class, this is the responsibility of the factory.\n\t */\n\tbindFactory<T>(id: InjectableId<T>, factory: SyncFactory<T>): BindAs<T, SyncFactory<T>>;\n\n\t/**\n\t * Bind an InjectableId to an asynchronous factory that will be invoked on demand when the object is needed.\n\t * The factory should produce the needed value (asynchronously of course).\n\t * NOTE: The container will not invoke any `@PostConstruct` present on the class, this is the responsibility of the factory.\n\t * WARNING!!! The factory may not throw and must return a valid Promise (which can be pending, resolved, rejected, etc.).\n\t */\n\tbindAsyncFactory<T>(id: InjectableId<T>, factory: AsyncFactory<T>): BindAs<T, AsyncFactory<T>>;\n\n\t/**\n\t * This essentially pre creates/loads all *singleton* InjectableIds currently known to the Binder.\n\t * This *may* be helpful if you wish to use Injector.get on a dependency tree that has asynchronous singletons within the tree.\n\t *\n\t * @param asyncOnly Only resolve AsyncFactorys as well as any bound classes that have an asynchronous `@PostConstruct` decorator. WARNING: If true, SyncFactorys will *not* be resolved even if they are Singletons.\n\t * @param parentRecursion If true and the the container has a parent, resolveIfSingleton will first be called for the parent\n\t * @returns A Promise that resolves when all Singleton's have been resolved, OR rejects if one or more of the Singleton's failed to resolve. NOTE: Rejection does not occur until all Singleton resolutions have settled, and the rejection reason/err will be a Map<InjectableId, Error>\n\t */\n\tresolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this>;\n}\n"]}
@@ -99,13 +99,16 @@ class ClassBasedProvider extends bindable_provider_js_1.BindableProvider {
99
99
  return [];
100
100
  }
101
101
  return argTypes.map((argType, index) => {
102
- // The reflect-metadata API fails on circular dependencies, and will return undefined for the argument instead.
103
- if (argType === undefined) {
104
- throw new Error(`Injection error. Recursive dependency in constructor for ${this.maker.toString()} at index ${index}`);
105
- }
106
- // Check if an Inject annotation precedes the parameter.
102
+ // The reflect-metadata API fails on circular dependencies returning undefined instead.
103
+ // Additionally, it cannot return generic types (no runtime type info).
104
+ // If an Inject annotation precedes the parameter, then that is what should get injected.
107
105
  const overrideToken = (0, decorators_js_1._getInjectedIdAt)(this.maker, index);
106
+ // If there was no Inject annotation, we might still be able to determine what to inject using the 'argType' (aka Reflect design:paramtypes).
108
107
  const actualToken = overrideToken === undefined ? argType : overrideToken;
108
+ if (actualToken === undefined) {
109
+ // No Inject annotation, and the type is not known.
110
+ throw new Error(`Injection error. Unable to determine parameter ${index} type/value of ${this.maker.toString()} constructor`);
111
+ }
109
112
  // Ask our container to resolve the parameter.
110
113
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
111
114
  let param = this.injector.resolveState(actualToken);
@@ -1 +1 @@
1
- {"version":3,"file":"class-provider.js","sourceRoot":"","sources":["../../src/class-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import {BindableProvider} from './bindable-provider.js';\nimport {POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_PARAMS} from './constants.js';\nimport {_getInjectedIdAt, _getOptionalDefaultAt} from './decorators.js';\nimport {ClassConstructor, InjectableId, Injector} from './injector.js';\nimport {State} from './state.js';\nimport {isPromise} from './utils.js';\n\n/*\n * This is a bit of a hack, but it avoids a ton of alternative hacks.\n * Note that in the Container, resolveState is a protected method.\n * Injector was never meant to publicly expose State.\n * Gotta love JS!\n */\ninterface StateResolvingInjector extends Injector {\n\tresolveState<T>(id: InjectableId<T>): State<T>;\n}\n\n/**\n * @inheritDoc\n * This specialization invokes it's configured class constructor synchronously and then scans for (and invokes) any @PostConstruct (which may be synchronous or asynchronous).\n */\nexport class ClassBasedProvider<T> extends BindableProvider<T, ClassConstructor<T>> {\n\tconstructor(injector: StateResolvingInjector, id: InjectableId<T>, maker: ClassConstructor<T>) {\n\t\tsuper(injector, id, maker);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @see the class description for this Provider.\n\t * This method is just a singleton guard, the real work is done by provideAsStateImpl.\n\t */\n\tprovideAsState(): State<T> {\n\t\tlet retVal = this.singleton;\n\t\tif (!retVal) {\n\t\t\tretVal = this.provideAsStateImpl();\n\t\t}\n\t\tif (this.singleton === null)\n\t\t\tthis.singleton = retVal;\n\t\treturn retVal;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization returns undefined if 'asyncOnly' is true and there is no asynchronous PostConstruct annotation (since class constructors can never by asynchronous).\n\t */\n\tresolveIfSingleton(asyncOnly: boolean): Promise<T> {\n\t\tif ((!asyncOnly) || Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker))\n\t\t\treturn super.resolveIfSingleton(false);\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Make a resolved or pending State that reflects any @PostConstruct annotations.\n\t */\n\tprotected makePostConstructState(obj: T): State<T> {\n\t\tif (typeof obj === 'object' && (!Array.isArray(obj)) && obj.constructor) {\n\t\t\tlet maybeAsync = false;\n\t\t\tlet pcFn: () => void | Error | Promise<void | Error>;\n\t\t\tif (typeof this.successHandler === 'function') {\n\t\t\t\tmaybeAsync = true;\n\t\t\t\tpcFn = () => {\n\t\t\t\t\treturn this.successHandler(obj, this.injector, this.id, this.maker);\n\t\t\t\t};\n\t\t\t}\n\t\t\telse {\n\t\t\t\t/* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */\n\t\t\t\t// Check to see if there is a @PostConstruct annotation on a method of the class.\n\t\t\t\tlet postConstruct: string = Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, obj.constructor);\n\t\t\t\tif (!postConstruct) {\n\t\t\t\t\tmaybeAsync = true;\n\t\t\t\t\tpostConstruct = Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, obj.constructor);\n\t\t\t\t}\n\t\t\t\tif (postConstruct && obj.constructor.prototype[postConstruct] && typeof obj.constructor.prototype[postConstruct] === 'function')\n\t\t\t\t\tpcFn = obj[postConstruct].bind?.(obj);\n\n\t\t\t\t/* eslint-enable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */\n\t\t\t}\n\t\t\tif (pcFn) {\n\t\t\t\tlet result: any;\n\t\t\t\ttry {\n\t\t\t\t\tresult = pcFn();\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\t// The post construction method threw while executing, give the errorHandler (if any) a crack at recovery.\n\t\t\t\t\ttry {\n\t\t\t\t\t\tobj = this.queryErrorHandler(err, obj); // The returned obj is unlikely to be the original obj.\n\t\t\t\t\t\treturn State.MakeState<T>(null, undefined, obj);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (e) {\n\t\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// The post construction method says it will let us know when it's finished.\n\t\t\t\tif (result && (result instanceof Promise || (maybeAsync && isPromise<void>(result)))) {\n\t\t\t\t\t// Return a State that is pending (the other return statements in this method return a State which is resolved or rejected).\n\t\t\t\t\t/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\t\t\t\t\treturn State.MakeState<T>(this.makePromiseForObj<T>(result, () => obj));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// No PostConstruct, just return a resolved State\n\t\treturn State.MakeState<T>(null, undefined, obj);\n\t}\n\n\t/**\n\t * This method collects the States of all the constructor parameters for our target class.\n\t */\n\tprotected getConstructorParameterStates(): State[] {\n\t\tconst argTypes = Reflect.getMetadata(REFLECT_PARAMS, this.maker);\n\t\tif (argTypes === undefined || !Array.isArray(argTypes)) {\n\t\t\treturn [];\n\t\t}\n\t\treturn argTypes.map((argType, index) => {\n\t\t\t// The reflect-metadata API fails on circular dependencies, and will return undefined for the argument instead.\n\t\t\tif (argType === undefined) {\n\t\t\t\tthrow new Error(`Injection error. Recursive dependency in constructor for ${this.maker.toString()} at index ${index}`);\n\t\t\t}\n\t\t\t// Check if an Inject annotation precedes the parameter.\n\t\t\tconst overrideToken = _getInjectedIdAt(this.maker, index);\n\t\t\tconst actualToken = overrideToken === undefined ? argType : overrideToken;\n\t\t\t// Ask our container to resolve the parameter.\n\t\t\t/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\t\t\tlet param = (this.injector as StateResolvingInjector).resolveState(actualToken);\n\t\t\t// If the parameter could not be resolved, see if there is an @Optional annotation\n\t\t\tif ((!param.pending) && param.rejected) {\n\t\t\t\tconst md = _getOptionalDefaultAt(this.maker, index);\n\t\t\t\tif (md)\n\t\t\t\t\tparam = State.MakeState<any>(null, undefined, md.value);\n\t\t\t}\n\t\t\treturn param;\n\t\t});\n\t}\n\n\t/**\n\t * Gather the needed constructor parameters, invoke the constructor, and figure out what post construction needs done.\n\t */\n\tprivate provideAsStateImpl(): State<T> {\n\t\tconst params = this.getConstructorParameterStates();\n\n\t\t// If any of the params are in a rejected state, we cannot construct.\n\t\tconst paramRejection = params.find((p) => {\n\t\t\treturn (!p.pending) && p.rejected;\n\t\t});\n\t\tif (paramRejection) {\n\t\t\treturn paramRejection as State<T>;\n\t\t}\n\t\t// If any of the params are in a pending state, we will have to wait for them to be resolved before we can construct.\n\t\tconst pendingParams = params.filter((p) => {\n\t\t\treturn p.pending;\n\t\t}).map((p) => {\n\t\t\treturn p.promise;\n\t\t});\n\t\tif (pendingParams.length > 0) {\n\t\t\t// Some of the parameters needed for construction are not yet available, wait for them and then attempt construction.\n\t\t\tconst objPromise = this.makePromiseForObj<any[]>(Promise.all(pendingParams), () => {\n\t\t\t\t// All the parameters are now available, instantiate the class.\n\t\t\t\t// If this throws, it will be handled by our caller.\n\t\t\t\treturn Reflect.construct(this.maker, params.map((p) => p.fulfilled as unknown));\n\t\t\t});\n\t\t\t// Once the obj is resolved, then we need to check for PostConstruct and if it was async, wait for that too.\n\t\t\treturn State.MakeState<T>(objPromise.then((obj) => {\n\t\t\t\tconst state = this.makePostConstructState(obj);\n\t\t\t\tif (state.pending) {\n\t\t\t\t\treturn state.promise; // chain (aka wait some more).\n\t\t\t\t}\n\t\t\t\telse if (state.rejected) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\t\t\treturn state.rejected as any; // error\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn state.fulfilled; // value (aka obj).\n\t\t\t\t}\n\t\t\t}));\n\t\t}\n\t\telse {\n\t\t\t// All parameters needed for construction are available, instantiate the object.\n\t\t\ttry {\n\t\t\t\tconst newObj = Reflect.construct(this.maker, params.map((p) => p.fulfilled as unknown));\n\t\t\t\treturn this.makePostConstructState(newObj);\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\t// There was an error, give the errorHandler (if any) a crack at recovery.\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(null, undefined, this.queryErrorHandler(err));\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"class-provider.js","sourceRoot":"","sources":["../../src/class-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import {BindableProvider} from './bindable-provider.js';\nimport {POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_PARAMS} from './constants.js';\nimport {_getInjectedIdAt, _getOptionalDefaultAt} from './decorators.js';\nimport {ClassConstructor, InjectableId, Injector} from './injector.js';\nimport {State} from './state.js';\nimport {isPromise} from './utils.js';\n\n/*\n * This is a bit of a hack, but it avoids a ton of alternative hacks.\n * Note that in the Container, resolveState is a protected method.\n * Injector was never meant to publicly expose State.\n * Gotta love JS!\n */\ninterface StateResolvingInjector extends Injector {\n\tresolveState<T>(id: InjectableId<T>): State<T>;\n}\n\n/**\n * @inheritDoc\n * This specialization invokes it's configured class constructor synchronously and then scans for (and invokes) any @PostConstruct (which may be synchronous or asynchronous).\n */\nexport class ClassBasedProvider<T> extends BindableProvider<T, ClassConstructor<T>> {\n\tconstructor(injector: StateResolvingInjector, id: InjectableId<T>, maker: ClassConstructor<T>) {\n\t\tsuper(injector, id, maker);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @see the class description for this Provider.\n\t * This method is just a singleton guard, the real work is done by provideAsStateImpl.\n\t */\n\tprovideAsState(): State<T> {\n\t\tlet retVal = this.singleton;\n\t\tif (!retVal) {\n\t\t\tretVal = this.provideAsStateImpl();\n\t\t}\n\t\tif (this.singleton === null)\n\t\t\tthis.singleton = retVal;\n\t\treturn retVal;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization returns undefined if 'asyncOnly' is true and there is no asynchronous PostConstruct annotation (since class constructors can never by asynchronous).\n\t */\n\tresolveIfSingleton(asyncOnly: boolean): Promise<T> {\n\t\tif ((!asyncOnly) || Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker))\n\t\t\treturn super.resolveIfSingleton(false);\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Make a resolved or pending State that reflects any @PostConstruct annotations.\n\t */\n\tprotected makePostConstructState(obj: T): State<T> {\n\t\tif (typeof obj === 'object' && (!Array.isArray(obj)) && obj.constructor) {\n\t\t\tlet maybeAsync = false;\n\t\t\tlet pcFn: () => void | Error | Promise<void | Error>;\n\t\t\tif (typeof this.successHandler === 'function') {\n\t\t\t\tmaybeAsync = true;\n\t\t\t\tpcFn = () => {\n\t\t\t\t\treturn this.successHandler(obj, this.injector, this.id, this.maker);\n\t\t\t\t};\n\t\t\t}\n\t\t\telse {\n\t\t\t\t/* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */\n\t\t\t\t// Check to see if there is a @PostConstruct annotation on a method of the class.\n\t\t\t\tlet postConstruct: string = Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, obj.constructor);\n\t\t\t\tif (!postConstruct) {\n\t\t\t\t\tmaybeAsync = true;\n\t\t\t\t\tpostConstruct = Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, obj.constructor);\n\t\t\t\t}\n\t\t\t\tif (postConstruct && obj.constructor.prototype[postConstruct] && typeof obj.constructor.prototype[postConstruct] === 'function')\n\t\t\t\t\tpcFn = obj[postConstruct].bind?.(obj);\n\n\t\t\t\t/* eslint-enable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */\n\t\t\t}\n\t\t\tif (pcFn) {\n\t\t\t\tlet result: any;\n\t\t\t\ttry {\n\t\t\t\t\tresult = pcFn();\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\t// The post construction method threw while executing, give the errorHandler (if any) a crack at recovery.\n\t\t\t\t\ttry {\n\t\t\t\t\t\tobj = this.queryErrorHandler(err, obj); // The returned obj is unlikely to be the original obj.\n\t\t\t\t\t\treturn State.MakeState<T>(null, undefined, obj);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (e) {\n\t\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// The post construction method says it will let us know when it's finished.\n\t\t\t\tif (result && (result instanceof Promise || (maybeAsync && isPromise<void>(result)))) {\n\t\t\t\t\t// Return a State that is pending (the other return statements in this method return a State which is resolved or rejected).\n\t\t\t\t\t/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\t\t\t\t\treturn State.MakeState<T>(this.makePromiseForObj<T>(result, () => obj));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// No PostConstruct, just return a resolved State\n\t\treturn State.MakeState<T>(null, undefined, obj);\n\t}\n\n\t/**\n\t * This method collects the States of all the constructor parameters for our target class.\n\t */\n\tprotected getConstructorParameterStates(): State[] {\n\t\tconst argTypes = Reflect.getMetadata(REFLECT_PARAMS, this.maker);\n\t\tif (argTypes === undefined || !Array.isArray(argTypes)) {\n\t\t\treturn [];\n\t\t}\n\t\treturn argTypes.map((argType, index) => {\n\t\t\t// The reflect-metadata API fails on circular dependencies returning undefined instead.\n\t\t\t// Additionally, it cannot return generic types (no runtime type info).\n\t\t\t// If an Inject annotation precedes the parameter, then that is what should get injected.\n\t\t\tconst overrideToken = _getInjectedIdAt(this.maker, index);\n\t\t\t// If there was no Inject annotation, we might still be able to determine what to inject using the 'argType' (aka Reflect design:paramtypes).\n\t\t\tconst actualToken = overrideToken === undefined ? argType : overrideToken;\n\t\t\tif (actualToken === undefined) {\n\t\t\t\t// No Inject annotation, and the type is not known.\n\t\t\t\tthrow new Error(`Injection error. Unable to determine parameter ${index} type/value of ${this.maker.toString()} constructor`);\n\t\t\t}\n\t\t\t// Ask our container to resolve the parameter.\n\t\t\t/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\t\t\tlet param = (this.injector as StateResolvingInjector).resolveState(actualToken);\n\t\t\t// If the parameter could not be resolved, see if there is an @Optional annotation\n\t\t\tif ((!param.pending) && param.rejected) {\n\t\t\t\tconst md = _getOptionalDefaultAt(this.maker, index);\n\t\t\t\tif (md)\n\t\t\t\t\tparam = State.MakeState<any>(null, undefined, md.value);\n\t\t\t}\n\t\t\treturn param;\n\t\t});\n\t}\n\n\t/**\n\t * Gather the needed constructor parameters, invoke the constructor, and figure out what post construction needs done.\n\t */\n\tprivate provideAsStateImpl(): State<T> {\n\t\tconst params = this.getConstructorParameterStates();\n\n\t\t// If any of the params are in a rejected state, we cannot construct.\n\t\tconst paramRejection = params.find((p) => {\n\t\t\treturn (!p.pending) && p.rejected;\n\t\t});\n\t\tif (paramRejection) {\n\t\t\treturn paramRejection as State<T>;\n\t\t}\n\t\t// If any of the params are in a pending state, we will have to wait for them to be resolved before we can construct.\n\t\tconst pendingParams = params.filter((p) => {\n\t\t\treturn p.pending;\n\t\t}).map((p) => {\n\t\t\treturn p.promise;\n\t\t});\n\t\tif (pendingParams.length > 0) {\n\t\t\t// Some of the parameters needed for construction are not yet available, wait for them and then attempt construction.\n\t\t\tconst objPromise = this.makePromiseForObj<any[]>(Promise.all(pendingParams), () => {\n\t\t\t\t// All the parameters are now available, instantiate the class.\n\t\t\t\t// If this throws, it will be handled by our caller.\n\t\t\t\treturn Reflect.construct(this.maker, params.map((p) => p.fulfilled as unknown));\n\t\t\t});\n\t\t\t// Once the obj is resolved, then we need to check for PostConstruct and if it was async, wait for that too.\n\t\t\treturn State.MakeState<T>(objPromise.then((obj) => {\n\t\t\t\tconst state = this.makePostConstructState(obj);\n\t\t\t\tif (state.pending) {\n\t\t\t\t\treturn state.promise; // chain (aka wait some more).\n\t\t\t\t}\n\t\t\t\telse if (state.rejected) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\t\t\treturn state.rejected as any; // error\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn state.fulfilled; // value (aka obj).\n\t\t\t\t}\n\t\t\t}));\n\t\t}\n\t\telse {\n\t\t\t// All parameters needed for construction are available, instantiate the object.\n\t\t\ttry {\n\t\t\t\tconst newObj = Reflect.construct(this.maker, params.map((p) => p.fulfilled as unknown));\n\t\t\t\treturn this.makePostConstructState(newObj);\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\t// There was an error, give the errorHandler (if any) a crack at recovery.\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(null, undefined, this.queryErrorHandler(err));\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -36,7 +36,7 @@ export declare class Container implements Binder {
36
36
  /**
37
37
  * @inheritDoc
38
38
  */
39
- bindConstant<T>(id: InjectableId<T>, value: T): void;
39
+ bindConstant<T>(id: InjectableId<T>, value: T): T;
40
40
  /**
41
41
  * @inheritDoc
42
42
  */
@@ -97,6 +97,7 @@ class Container {
97
97
  */
98
98
  bindConstant(id, value) {
99
99
  this.providers.set(id, new constant_provider_js_1.ConstantProvider(value));
100
+ return value;
100
101
  }
101
102
  bindClass(id, constructor) {
102
103
  if (typeof constructor === 'undefined') {
@@ -1 +1 @@
1
- {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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","sourcesContent":["import {AsyncFactoryBasedProvider} from './async-factory-provider.js';\nimport {BindableProvider} from './bindable-provider.js';\nimport {AsyncFactory, BindAs, Binder, SyncFactory} from './binder.js';\nimport {ClassBasedProvider} from './class-provider.js';\nimport {ConstantProvider} from './constant-provider.js';\nimport {INJECTABLE_METADATA_KEY} from './constants.js';\nimport {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector.js';\nimport {Provider} from './provider.js';\nimport {State} from './state.js';\nimport {FactoryBasedProvider} from './sync-factory-provider.js';\nimport {isPromise} from './utils.js';\n\n/**\n * Helper class to ensure we can distinguish between Error instances legitimately returned from Providers, and Errors thrown by Providers.\n *\n * @see resolveSingletons.\n */\nclass ReasonWrapper {\n\tconstructor(public reason: any) {\n\t}\n}\n\n/**\n * Binder and Injector (aka Container) to handle (a)synchronous dependency management.\n */\nexport class Container implements Binder {\n\n\t/**\n\t * Create a new Container, with an optional parent Injector which will be searched if any given InjectableId is not bound within this Container.\n\t */\n\tpublic constructor(protected parent?: Injector) {\n\t}\n\n\tprotected providers = new Map<InjectableId<any>, Provider>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic isIdKnown<T>(id: InjectableId<T>, ascending?: boolean): boolean {\n\t\tif (!!this.providers.get(id))\n\t\t\treturn true;\n\t\tif (ascending && this.parent)\n\t\t\treturn this.parent.isIdKnown(id, true);\n\t\treturn false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get<T>(id: InjectableId<T>): T {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent)\n\t\t\t\treturn this.parent.get<T>(id);\n\t\t\tthrow new Error('Symbol not bound: ' + id.toString());\n\t\t}\n\t\tconst state = provider.provideAsState();\n\t\tif (state.pending)\n\t\t\tthrow new Error('Synchronous request on unresolved asynchronous dependency tree: ' + id.toString());\n\t\tif (state.rejected)\n\t\t\tthrow state.rejected;\n\t\treturn state.fulfilled as T;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolve<T>(id: InjectableId<T>): Promise<T> {\n\t\tconst state = this.resolveState(id);\n\t\tif (isPromise(state.promise)) {\n\t\t\treturn state.promise;\n\t\t}\n\n\t\tif (state.rejected) {\n\t\t\treturn Promise.reject(state.rejected);\n\t\t}\n\n\t\treturn Promise.resolve(state.fulfilled);\n\t}\n\n\t// noinspection JSUnusedGlobalSymbols\n\t/**\n\t * This method is not part of the Binding interface, because it is highly unusual.\n\t * But that doesn't mean we can't imagine scenarios where you might require it.\n\t *\n\t * @param id The id to be removed.\n\t * @param ascending If true, this will remove all bindings of the specified id all the way up the parent container chain (if it exists).\n\t * @param releaseIfSingleton If true, @Provider.releaseIfSingleton will be invoked before the binding is removed.\n\t */\n\tpublic removeBinding<T>(id: InjectableId<T>, ascending?: boolean, releaseIfSingleton?: boolean): void {\n\t\tif (releaseIfSingleton) {\n\t\t\tconst p = this.providers.get(id);\n\t\t\tif (p)\n\t\t\t\tp.releaseIfSingleton();\n\t\t}\n\t\tthis.providers.delete(id);\n\n\t\tif (ascending && this.parent) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n\t\t\t(this.parent as any)?.removeBinding(id, true, releaseIfSingleton);\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindConstant<T>(id: InjectableId<T>, value: T): void {\n\t\tthis.providers.set(id, new ConstantProvider(value));\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindClass<T>(id: ClassConstructor<T>, constructor?: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | InjectableId<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | ClassConstructor<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>> {\n\t\tif (typeof constructor === 'undefined') {\n\t\t\tconstructor = id as new (...args: any[]) => T;\n\t\t}\n\t\tif (!Reflect.getMetadata(INJECTABLE_METADATA_KEY, constructor)) {\n\t\t\tthrow new Error('Class not decorated with @Injectable [' + constructor.toString() + ']');\n\t\t}\n\t\t/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\t\tconst provider = new ClassBasedProvider(this as any, id, constructor);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindFactory<T>(id: InjectableId<T>, factory: SyncFactory<T>): BindAs<T, SyncFactory<T>> {\n\t\tconst provider = new FactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindAsyncFactory<T>(id: InjectableId<T>, factory: AsyncFactory<T>): BindAs<T, AsyncFactory<T>> {\n\t\tconst provider = new AsyncFactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this> {\n\t\tconst makePromiseToResolve = () => {\n\t\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\t\tconst pending = new Map<InjectableId<any>, Promise<void>>();\n\t\t\t\t// Ask each provider to resolve itself *IF* it is a singleton.\n\t\t\t\tthis.providers.forEach((value: Provider, key: InjectableId<any>) => {\n\t\t\t\t\t// If the provider is a singleton *and* if resolution is being handled asynchronously, the provider will return a completion promise.\n\t\t\t\t\tconst p = value.resolveIfSingleton(asyncOnly);\n\t\t\t\t\tif (p !== null && typeof p !== 'undefined')\n\t\t\t\t\t\tpending.set(key, p);\n\t\t\t\t});\n\t\t\t\t// The contract for this method is that it behaves somewhat like Promise.allSettled (e.g. won't complete until all pending Singletons have settled).\n\t\t\t\t// Further the contract states that if any of the asynchronous Singletons rejected, that we will also return a rejected Promise, and that the rejection reason will be a Map of the InjectableId's that did not resolve, and the Error they emitted.\n\t\t\t\tconst pp = Array.from(pending.values());\n\t\t\t\tconst keys = Array.from(pending.keys());\n\t\t\t\t// Mapping the catch is an alternate version of Promise.allSettled (e.g. keeps Promise.all from short-circuiting).\n\t\t\t\tPromise.all(pp\n\t\t\t\t\t.map(p => p.catch(e => new ReasonWrapper(e))))\n\t\t\t\t\t.then((results) => {\n\t\t\t\t\t\tconst rejects = new Map<InjectableId<any>, Error>();\n\t\t\t\t\t\t// Check the results. Since we don't export ReasonWrapper, it is safe to assume that an instance of that was produced by our map => catch code above, so it's a rejected Singleton error.\n\t\t\t\t\t\tresults.forEach((result, idx) => {\n\t\t\t\t\t\t\tif (result instanceof ReasonWrapper) {\n\t\t\t\t\t\t\t\trejects.set(keys[idx], result.reason);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// If we had rejections, notify our caller what they were.\n\t\t\t\t\t\tif (rejects.size > 0)\n\t\t\t\t\t\t\treject(rejects);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tresolve(); // All good.\n\t\t\t\t\t});\n\t\t\t});\n\t\t};\n\t\tif (parentRecursion && typeof (this.parent as Binder)?.resolveSingletons === 'function') {\n\t\t\tconst pb: Binder = this.parent as Binder;\n\t\t\treturn pb.resolveSingletons(asyncOnly, parentRecursion).then(() => {\n\t\t\t\treturn makePromiseToResolve().then(() => this);\n\t\t\t});\n\t\t}\n\t\treturn makePromiseToResolve().then(() => this);\n\t}\n\n\t/**\n\t * As implied by the name prefix, this is a factored out method invoked only by the 'resolve' method.\n\t * It makes searching our parent (if it exists) easier (and quicker) IF our parent is a fellow instance of Container.\n\t */\n\tprotected resolveState<T>(id: InjectableId<T>): State<T> {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent) {\n\t\t\t\tif (this.parent instanceof Container) {\n\t\t\t\t\treturn this.parent.resolveState<T>(id);\n\t\t\t\t}\n\t\t\t\t// This code (below) will only ever execute if the creator of this container passes in their own implementation of an Injector.\n\t\t\t\t/* istanbul ignore next */\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(this.parent.resolve<T>(id), undefined, undefined);\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\treturn State.MakeState<T>(null, err);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn State.MakeState<T>(null, new Error('Symbol not bound: ' + id.toString()));\n\t\t}\n\t\treturn provider.provideAsState() as State<T>;\n\t}\n\n\t// noinspection JSUnusedGlobalSymbols\n\t/**\n\t * Convenience method to assist in releasing non-garbage-collectable resources that Singletons in this Container may have allocated.\n\t * It will walk through all registered Providers (of this Container only), and invoke their @see Provider.releaseIfSingleton method.\n\t * This method is not part of the Binding interface, because you normally only create (and release) Containers.\n\t * NOTE:\n\t * This *only* releases active/pending Singleton's that have already been created by this Container.\n\t * The most likely use of this method would be when you have created a new child Container for a limited duration transaction, and you want to easily cleanup temporary resources.\n\t * For example, your service object may need to know when it should unsubscribe from an RxJs stream (failure to do so can result in your Singleton not being garbage collected at the end of a transaction).\n\t * In theory, you could handle all unsubscription and cleanup yourself, but the @Release decorator and this method are meant to simply make that easier.\n\t */\n\tpublic releaseSingletons(): void {\n\t\tthis.providers.forEach((value: Provider) => {\n\t\t\tvalue.releaseIfSingleton();\n\t\t});\n\t}\n\n\t/**\n\t * Make a copy of this @see Container.\n\t * This is an experimental feature!\n\t * I have not thought through all the dark corners, so use at your own peril!\n\t * Here are some notes:\n\t * The injector parameter for SyncFactory and AsyncFactory callbacks will be the Container invoking the factory.\n\t * So a factory that uses a parent closure instead of the supplied injector may get unexpected results.\n\t * The injector parameter for OnSuccess and OnError callbacks will be the Container performing the resolution.\n\t * Singletons are cloned at their *existing* state..\n\t * If resolved in \"this\" container, they will not be re-resolved for the clone.\n\t * If released by the clone, they will be considered released by \"this\" container.\n\t * If a singleton is currently being asynchronously constructed any callbacks will reference \"this\" Container, however both Containers should have no problem awaiting resolution.\n\t * If a singleton is not resolved when the container is cloned, then if both containers resolve, you will create *two* \"singletons\".\n\t * The way to avoid this last effect is to @see resolveSingletons\n\t */\n\tclone(clazz?: ClassConstructor<Container>): Container {\n\t\tif (!clazz)\n\t\t\tclazz = Container;\n\t\tconst retVal = new clazz(this.parent);\n\t\tthis.providers.forEach((v, k) => {\n\t\t\tif (v instanceof BindableProvider) {\n\t\t\t\tv = Object.assign(Object.create(Object.getPrototypeOf(v)), v);\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t(v as any).injector = retVal;\n\t\t\t}\n\t\t\tretVal.providers.set(k, v);\n\t\t});\n\t\treturn retVal;\n\t}\n}\n"]}
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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","sourcesContent":["import {AsyncFactoryBasedProvider} from './async-factory-provider.js';\nimport {BindableProvider} from './bindable-provider.js';\nimport {AsyncFactory, BindAs, Binder, SyncFactory} from './binder.js';\nimport {ClassBasedProvider} from './class-provider.js';\nimport {ConstantProvider} from './constant-provider.js';\nimport {INJECTABLE_METADATA_KEY} from './constants.js';\nimport {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector.js';\nimport {Provider} from './provider.js';\nimport {State} from './state.js';\nimport {FactoryBasedProvider} from './sync-factory-provider.js';\nimport {isPromise} from './utils.js';\n\n/**\n * Helper class to ensure we can distinguish between Error instances legitimately returned from Providers, and Errors thrown by Providers.\n *\n * @see resolveSingletons.\n */\nclass ReasonWrapper {\n\tconstructor(public reason: any) {\n\t}\n}\n\n/**\n * Binder and Injector (aka Container) to handle (a)synchronous dependency management.\n */\nexport class Container implements Binder {\n\n\t/**\n\t * Create a new Container, with an optional parent Injector which will be searched if any given InjectableId is not bound within this Container.\n\t */\n\tpublic constructor(protected parent?: Injector) {\n\t}\n\n\tprotected providers = new Map<InjectableId<any>, Provider>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic isIdKnown<T>(id: InjectableId<T>, ascending?: boolean): boolean {\n\t\tif (!!this.providers.get(id))\n\t\t\treturn true;\n\t\tif (ascending && this.parent)\n\t\t\treturn this.parent.isIdKnown(id, true);\n\t\treturn false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get<T>(id: InjectableId<T>): T {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent)\n\t\t\t\treturn this.parent.get<T>(id);\n\t\t\tthrow new Error('Symbol not bound: ' + id.toString());\n\t\t}\n\t\tconst state = provider.provideAsState();\n\t\tif (state.pending)\n\t\t\tthrow new Error('Synchronous request on unresolved asynchronous dependency tree: ' + id.toString());\n\t\tif (state.rejected)\n\t\t\tthrow state.rejected;\n\t\treturn state.fulfilled as T;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolve<T>(id: InjectableId<T>): Promise<T> {\n\t\tconst state = this.resolveState(id);\n\t\tif (isPromise(state.promise)) {\n\t\t\treturn state.promise;\n\t\t}\n\n\t\tif (state.rejected) {\n\t\t\treturn Promise.reject(state.rejected);\n\t\t}\n\n\t\treturn Promise.resolve(state.fulfilled);\n\t}\n\n\t// noinspection JSUnusedGlobalSymbols\n\t/**\n\t * This method is not part of the Binding interface, because it is highly unusual.\n\t * But that doesn't mean we can't imagine scenarios where you might require it.\n\t *\n\t * @param id The id to be removed.\n\t * @param ascending If true, this will remove all bindings of the specified id all the way up the parent container chain (if it exists).\n\t * @param releaseIfSingleton If true, @Provider.releaseIfSingleton will be invoked before the binding is removed.\n\t */\n\tpublic removeBinding<T>(id: InjectableId<T>, ascending?: boolean, releaseIfSingleton?: boolean): void {\n\t\tif (releaseIfSingleton) {\n\t\t\tconst p = this.providers.get(id);\n\t\t\tif (p)\n\t\t\t\tp.releaseIfSingleton();\n\t\t}\n\t\tthis.providers.delete(id);\n\n\t\tif (ascending && this.parent) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n\t\t\t(this.parent as any)?.removeBinding(id, true, releaseIfSingleton);\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindConstant<T>(id: InjectableId<T>, value: T): T {\n\t\tthis.providers.set(id, new ConstantProvider(value));\n\t\treturn value;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindClass<T>(id: ClassConstructor<T>, constructor?: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | InjectableId<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | ClassConstructor<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>> {\n\t\tif (typeof constructor === 'undefined') {\n\t\t\tconstructor = id as new (...args: any[]) => T;\n\t\t}\n\t\tif (!Reflect.getMetadata(INJECTABLE_METADATA_KEY, constructor)) {\n\t\t\tthrow new Error('Class not decorated with @Injectable [' + constructor.toString() + ']');\n\t\t}\n\t\t/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\t\tconst provider = new ClassBasedProvider(this as any, id, constructor);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindFactory<T>(id: InjectableId<T>, factory: SyncFactory<T>): BindAs<T, SyncFactory<T>> {\n\t\tconst provider = new FactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindAsyncFactory<T>(id: InjectableId<T>, factory: AsyncFactory<T>): BindAs<T, AsyncFactory<T>> {\n\t\tconst provider = new AsyncFactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this> {\n\t\tconst makePromiseToResolve = () => {\n\t\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\t\tconst pending = new Map<InjectableId<any>, Promise<void>>();\n\t\t\t\t// Ask each provider to resolve itself *IF* it is a singleton.\n\t\t\t\tthis.providers.forEach((value: Provider, key: InjectableId<any>) => {\n\t\t\t\t\t// If the provider is a singleton *and* if resolution is being handled asynchronously, the provider will return a completion promise.\n\t\t\t\t\tconst p = value.resolveIfSingleton(asyncOnly);\n\t\t\t\t\tif (p !== null && typeof p !== 'undefined')\n\t\t\t\t\t\tpending.set(key, p);\n\t\t\t\t});\n\t\t\t\t// The contract for this method is that it behaves somewhat like Promise.allSettled (e.g. won't complete until all pending Singletons have settled).\n\t\t\t\t// Further the contract states that if any of the asynchronous Singletons rejected, that we will also return a rejected Promise, and that the rejection reason will be a Map of the InjectableId's that did not resolve, and the Error they emitted.\n\t\t\t\tconst pp = Array.from(pending.values());\n\t\t\t\tconst keys = Array.from(pending.keys());\n\t\t\t\t// Mapping the catch is an alternate version of Promise.allSettled (e.g. keeps Promise.all from short-circuiting).\n\t\t\t\tPromise.all(pp\n\t\t\t\t\t.map(p => p.catch(e => new ReasonWrapper(e))))\n\t\t\t\t\t.then((results) => {\n\t\t\t\t\t\tconst rejects = new Map<InjectableId<any>, Error>();\n\t\t\t\t\t\t// Check the results. Since we don't export ReasonWrapper, it is safe to assume that an instance of that was produced by our map => catch code above, so it's a rejected Singleton error.\n\t\t\t\t\t\tresults.forEach((result, idx) => {\n\t\t\t\t\t\t\tif (result instanceof ReasonWrapper) {\n\t\t\t\t\t\t\t\trejects.set(keys[idx], result.reason);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// If we had rejections, notify our caller what they were.\n\t\t\t\t\t\tif (rejects.size > 0)\n\t\t\t\t\t\t\treject(rejects);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tresolve(); // All good.\n\t\t\t\t\t});\n\t\t\t});\n\t\t};\n\t\tif (parentRecursion && typeof (this.parent as Binder)?.resolveSingletons === 'function') {\n\t\t\tconst pb: Binder = this.parent as Binder;\n\t\t\treturn pb.resolveSingletons(asyncOnly, parentRecursion).then(() => {\n\t\t\t\treturn makePromiseToResolve().then(() => this);\n\t\t\t});\n\t\t}\n\t\treturn makePromiseToResolve().then(() => this);\n\t}\n\n\t/**\n\t * As implied by the name prefix, this is a factored out method invoked only by the 'resolve' method.\n\t * It makes searching our parent (if it exists) easier (and quicker) IF our parent is a fellow instance of Container.\n\t */\n\tprotected resolveState<T>(id: InjectableId<T>): State<T> {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent) {\n\t\t\t\tif (this.parent instanceof Container) {\n\t\t\t\t\treturn this.parent.resolveState<T>(id);\n\t\t\t\t}\n\t\t\t\t// This code (below) will only ever execute if the creator of this container passes in their own implementation of an Injector.\n\t\t\t\t/* istanbul ignore next */\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(this.parent.resolve<T>(id), undefined, undefined);\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\treturn State.MakeState<T>(null, err);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn State.MakeState<T>(null, new Error('Symbol not bound: ' + id.toString()));\n\t\t}\n\t\treturn provider.provideAsState() as State<T>;\n\t}\n\n\t// noinspection JSUnusedGlobalSymbols\n\t/**\n\t * Convenience method to assist in releasing non-garbage-collectable resources that Singletons in this Container may have allocated.\n\t * It will walk through all registered Providers (of this Container only), and invoke their @see Provider.releaseIfSingleton method.\n\t * This method is not part of the Binding interface, because you normally only create (and release) Containers.\n\t * NOTE:\n\t * This *only* releases active/pending Singleton's that have already been created by this Container.\n\t * The most likely use of this method would be when you have created a new child Container for a limited duration transaction, and you want to easily cleanup temporary resources.\n\t * For example, your service object may need to know when it should unsubscribe from an RxJs stream (failure to do so can result in your Singleton not being garbage collected at the end of a transaction).\n\t * In theory, you could handle all unsubscription and cleanup yourself, but the @Release decorator and this method are meant to simply make that easier.\n\t */\n\tpublic releaseSingletons(): void {\n\t\tthis.providers.forEach((value: Provider) => {\n\t\t\tvalue.releaseIfSingleton();\n\t\t});\n\t}\n\n\t/**\n\t * Make a copy of this @see Container.\n\t * This is an experimental feature!\n\t * I have not thought through all the dark corners, so use at your own peril!\n\t * Here are some notes:\n\t * The injector parameter for SyncFactory and AsyncFactory callbacks will be the Container invoking the factory.\n\t * So a factory that uses a parent closure instead of the supplied injector may get unexpected results.\n\t * The injector parameter for OnSuccess and OnError callbacks will be the Container performing the resolution.\n\t * Singletons are cloned at their *existing* state..\n\t * If resolved in \"this\" container, they will not be re-resolved for the clone.\n\t * If released by the clone, they will be considered released by \"this\" container.\n\t * If a singleton is currently being asynchronously constructed any callbacks will reference \"this\" Container, however both Containers should have no problem awaiting resolution.\n\t * If a singleton is not resolved when the container is cloned, then if both containers resolve, you will create *two* \"singletons\".\n\t * The way to avoid this last effect is to @see resolveSingletons\n\t */\n\tclone(clazz?: ClassConstructor<Container>): Container {\n\t\tif (!clazz)\n\t\t\tclazz = Container;\n\t\tconst retVal = new clazz(this.parent);\n\t\tthis.providers.forEach((v, k) => {\n\t\t\tif (v instanceof BindableProvider) {\n\t\t\t\tv = Object.assign(Object.create(Object.getPrototypeOf(v)), v);\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t(v as any).injector = retVal;\n\t\t\t}\n\t\t\tretVal.providers.set(k, v);\n\t\t});\n\t\treturn retVal;\n\t}\n}\n"]}
@@ -76,9 +76,8 @@ function Inject(id) {
76
76
  * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.
77
77
  */
78
78
  return function (target, parameterName, parameterIndex) {
79
- const hint = targetHint(target);
80
79
  if (id === undefined) {
81
- throw new Error('Undefined id passed to @Inject [' + hint + ']');
80
+ throw new Error('Undefined id passed to @Inject [' + targetHint(target) + ']');
82
81
  }
83
82
  const paramKey = validateSingleConstructorParam('Inject', target, parameterIndex);
84
83
  Reflect.defineMetadata(constants_js_1.INJECT_METADATA_KEY, id, target, paramKey);
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\n/**\n * These decorators all apply the information they collect (whether class, method, or parameter data) as tagged metadata on the class's constructor\n */\nimport {INJECT_METADATA_KEY, INJECTABLE_METADATA_KEY, OPTIONAL_METADATA_KEY, POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_RETURN, RELEASE_METADATA_KEY} from './constants.js';\nimport {InjectableId} from './injector.js';\n\n// Help user locate misapplied decorators.\nfunction targetHint(target: Function) {\n\tlet hint: string | undefined;\n\tif (target) {\n\t\thint = target.name;\n\t\tif ((!hint) && target.constructor) {\n\t\t\thint = target.constructor.name;\n\t\t}\n\t}\n\treturn hint;\n}\n\n// Validate that 'target' is a class constructor function.\nfunction isClassConstructor(target: any) {\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n\tif (typeof target === 'function' && target.hasOwnProperty('prototype')) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\treturn target.prototype.constructor === target;\n\t}\n\treturn false;\n}\n\n// Ensure consistency in our meta-data name getting/setting.\nfunction makeParamIdxKey(idx: number): string {\n\treturn `index-${idx}`;\n}\n\n// Validate that the specified target is a parameter of a class constructor\nfunction validateConstructorParam(decorator: string, target: Function, idx: number): string {\n\tif (!isClassConstructor(target)) {\n\t\tthrow new Error('@' + decorator + ' is not valid here [' + targetHint(target) + ']');\n\t}\n\treturn makeParamIdxKey(idx);\n}\n\n// Validate the decorator was only applied once.\nfunction validateSingleConstructorParam(decorator: string, target: Function, idx: number): string {\n\tconst propKey = validateConstructorParam(decorator, target, idx);\n\tif (Reflect.hasOwnMetadata(decorator, target, propKey)) {\n\t\tthrow new Error('@' + decorator + ' applied multiple times [' + target.constructor.name + ']');\n\t}\n\treturn propKey;\n}\n\n/**\n * Placed just before the class declaration, this class decorator applies metadata to the class constructor indicating that the user intends to bind the class into the container.\n * This decorator will throw if not placed on a class declaration, or if placed more than once on a class declaration.\n */\nexport function Injectable(): ClassDecorator {\n\t/**\n\t * @param target The constructor function of the class that is being decorated\n\t * @returns Undefined (nothing), as this decorator does not modify the constructor in any way.\n\t */\n\treturn function (target: Function): void {\n\t\tif (Reflect.hasOwnMetadata(INJECTABLE_METADATA_KEY, target)) {\n\t\t\tthrow new Error('@Injectable applied multiple times [' + targetHint(target) + ']');\n\t\t}\n\t\tReflect.defineMetadata(INJECTABLE_METADATA_KEY, true, target);\n\t};\n}\n\n/**\n * Placed just before a constructor parameter, this parameter decorator allows for specificity and control over the type of the type of Object that will be injected into the parameter.\n * In the absence of this decorator the container will use whatever is bound to a parameter's type (or throw an error if it is unable to recognize the type).\n *\n * @param id The identifier of the bound type that should be injected.\n */\nexport function Inject(id: InjectableId<any>): ParameterDecorator {\n\t/**\n\t * @param target The constructor function of the class (we don't allow @Inject on anything else).\n\t * @param parameterName The name of the parameter\n\t * @param parameterIndex The ordinal index of the parameter in the function’s parameter list\n\t * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.\n\t */\n\treturn function (target: Function, parameterName: string | symbol, parameterIndex: number): void {\n\t\tconst hint = targetHint(target);\n\t\tif (id === undefined) {\n\t\t\tthrow new Error('Undefined id passed to @Inject [' + hint + ']');\n\t\t}\n\t\tconst paramKey = validateSingleConstructorParam('Inject', target, parameterIndex);\n\t\tReflect.defineMetadata(INJECT_METADATA_KEY, id, target, paramKey);\n\t};\n}\n\n/**\n * This is a helper function used by the container to retrieve the @Inject metadata for a specifically indexed constructor parameter\n *\n * @param target The constructor function of the class (we don't allow @Inject on anything else).\n * @param parameterIndex The ordinal index of the parameter in the constructor’s parameter list\n * @see Inject\n */\nexport function _getInjectedIdAt(target: Function, parameterIndex: number): InjectableId<any> {\n\treturn Reflect.getMetadata(INJECT_METADATA_KEY, target, makeParamIdxKey(parameterIndex)) as InjectableId<any>;\n}\n\n/**\n * Placed just before a constructor parameter, this parameter decorator signals the container that it should supply the 'alt' constant value (undefined by default) if for *any* reason it is unable to otherwise resolve the type of the parameter.\n * WARNING! It is your responsibility to ensure that alt is of the appropriate type/value.\n */\nexport function Optional(alt?: any): ParameterDecorator { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types\n\t/**\n\t * @param target The constructor function of the class (we don't allow @Optional on anything else).\n\t * @param parameterName The name of the parameter\n\t * @param parameterIndex The ordinal index of the parameter in the function’s parameter list\n\t * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.\n\t */\n\treturn function (target: Function, parameterName: string | symbol, parameterIndex: number): void {\n\t\tconst paramKey = validateSingleConstructorParam('Optional', target, parameterIndex);\n\t\tReflect.defineMetadata(OPTIONAL_METADATA_KEY, {value: alt}, target, paramKey);\n\t};\n}\n\n/**\n * This is a helper function used by the container to retrieve the @Optional metadata for a specifically indexed constructor parameter\n *\n * @param target The constructor function of the class (we don't allow @Optional on anything else).\n * @param parameterIndex The ordinal index of the parameter in the constructor’s parameter list\n * @see Optional\n * @returns an object containing the value provided in the decorator, or undefined if no annotation was present.\n */\nexport function _getOptionalDefaultAt(target: Function, parameterIndex: number): { value: any } {\n\treturn Reflect.getMetadata(OPTIONAL_METADATA_KEY, target, makeParamIdxKey(parameterIndex)) as { value: any }; // See the @Optional decorator before making any changes here.\n}\n\n/**\n * Placed just before a class method, this method decorator flags a method that should be called after an object has been instantiated by the container, but before it is put into service.\n * The method will be assumed to be synchronous unless the method signature explicitly declares it's return type to be \": Promise<something>\"\n * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.\n */\nexport function PostConstruct(): MethodDecorator {\n\t/**\n\t * @param prototypeOrConstructor The prototype of the class (we don't allow @PostConstruct on anything other than a class instance method.\n\t * @param methodName The name of the method.\n\t * @param descriptor The Property Descriptor for the method.\n\t * @returns Undefined (nothing), as this decorator does not modify the method in any way.\n\t */\n\t// noinspection JSUnusedLocalSymbols\n\treturn function (target: Object, methodName: string | symbol, descriptor: PropertyDescriptor) { // eslint-disable-line @typescript-eslint/no-unused-vars\n\t\tif (typeof target !== 'object' || typeof target.constructor !== 'function') {\n\t\t\tthrow new Error('@PostConstruct not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');\n\t\t}\n\t\tif (Reflect.hasOwnMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, target.constructor) || Reflect.hasOwnMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, target.constructor)) {\n\t\t\tthrow new Error('@PostConstruct applied multiple times [' + targetHint(target.constructor) + ']');\n\t\t}\n\t\tconst rt = Reflect.getMetadata(REFLECT_RETURN, target, methodName);\n\t\tif (typeof rt === 'function') {\n\t\t\tReflect.defineMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, methodName, target.constructor);\n\t\t}\n\t\telse {\n\t\t\tReflect.defineMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, methodName, target.constructor);\n\t\t}\n\t};\n}\n\n// noinspection JSUnusedGlobalSymbols\n/**\n * Placed just before a class method, this decorator identifies a method which should be called when an object is removed from service.\n * If invoked by the container, the container will drop any references it has to the object when the method returns.\n * Note that this decorator is *not* a guarantee (or even an implication) that the decorated method will be called (JavaScript has no mechanism to enforce such a contract).\n * This decorator simply serves as a flag to indicate a method which is intended to clean up resources allocated by the object *which would not otherwise be garbage collected*.\n * You should *not* use this decorator as a general \"object finalization\" method. It has very limited scope and purpose.\n * The decorated method must complete normally (no throwing), as \"release\" is not an abort-able process.\n * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.\n * The @see InvokeReleaseMethod helper function can search for and invoke the @Release decorated method of an object.\n * Also @see Container.releaseSingletons for the intended usage of this decorator.\n * It is intended that after the @Release decorated method of an object is called, that object will not be used again, but this is of course not enforced).\n */\nexport function Release(): MethodDecorator {\n\t/**\n\t * @param prototypeOrConstructor The prototype of the class (we don't allow @Release on anything other than a class instance method.\n\t * @param methodName The name of the method.\n\t * @param descriptor The Property Descriptor for the method.\n\t * @returns Undefined (nothing), as this decorator does not modify the method in any way.\n\t */\n\t// noinspection JSUnusedLocalSymbols\n\treturn function (target: Object, methodName: string | symbol, descriptor: PropertyDescriptor) { // eslint-disable-line @typescript-eslint/no-unused-vars\n\t\tif (typeof target !== 'object' || typeof target.constructor !== 'function') {\n\t\t\tthrow new Error('@Release not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');\n\t\t}\n\t\tif (Reflect.hasOwnMetadata(RELEASE_METADATA_KEY, target.constructor)) {\n\t\t\tthrow new Error('@Release applied multiple times [' + targetHint(target.constructor) + ']');\n\t\t}\n\t\tReflect.defineMetadata(RELEASE_METADATA_KEY, methodName, target.constructor);\n\t};\n}\n"]}
1
+ {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\n/**\n * These decorators all apply the information they collect (whether class, method, or parameter data) as tagged metadata on the class's constructor\n */\nimport {INJECT_METADATA_KEY, INJECTABLE_METADATA_KEY, OPTIONAL_METADATA_KEY, POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_RETURN, RELEASE_METADATA_KEY} from './constants.js';\nimport {InjectableId} from './injector.js';\n\n// Help user locate misapplied decorators.\nfunction targetHint(target: Function) {\n\tlet hint: string | undefined;\n\tif (target) {\n\t\thint = target.name;\n\t\tif ((!hint) && target.constructor) {\n\t\t\thint = target.constructor.name;\n\t\t}\n\t}\n\treturn hint;\n}\n\n// Validate that 'target' is a class constructor function.\nfunction isClassConstructor(target: any) {\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n\tif (typeof target === 'function' && target.hasOwnProperty('prototype')) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\treturn target.prototype.constructor === target;\n\t}\n\treturn false;\n}\n\n// Ensure consistency in our meta-data name getting/setting.\nfunction makeParamIdxKey(idx: number): string {\n\treturn `index-${idx}`;\n}\n\n// Validate that the specified target is a parameter of a class constructor\nfunction validateConstructorParam(decorator: string, target: Function, idx: number): string {\n\tif (!isClassConstructor(target)) {\n\t\tthrow new Error('@' + decorator + ' is not valid here [' + targetHint(target) + ']');\n\t}\n\treturn makeParamIdxKey(idx);\n}\n\n// Validate the decorator was only applied once.\nfunction validateSingleConstructorParam(decorator: string, target: Function, idx: number): string {\n\tconst propKey = validateConstructorParam(decorator, target, idx);\n\tif (Reflect.hasOwnMetadata(decorator, target, propKey)) {\n\t\tthrow new Error('@' + decorator + ' applied multiple times [' + target.constructor.name + ']');\n\t}\n\treturn propKey;\n}\n\n/**\n * Placed just before the class declaration, this class decorator applies metadata to the class constructor indicating that the user intends to bind the class into the container.\n * This decorator will throw if not placed on a class declaration, or if placed more than once on a class declaration.\n */\nexport function Injectable(): ClassDecorator {\n\t/**\n\t * @param target The constructor function of the class that is being decorated\n\t * @returns Undefined (nothing), as this decorator does not modify the constructor in any way.\n\t */\n\treturn function (target: Function): void {\n\t\tif (Reflect.hasOwnMetadata(INJECTABLE_METADATA_KEY, target)) {\n\t\t\tthrow new Error('@Injectable applied multiple times [' + targetHint(target) + ']');\n\t\t}\n\t\tReflect.defineMetadata(INJECTABLE_METADATA_KEY, true, target);\n\t};\n}\n\n/**\n * Placed just before a constructor parameter, this parameter decorator allows for specificity and control over the type of the type of Object that will be injected into the parameter.\n * In the absence of this decorator the container will use whatever is bound to a parameter's type (or throw an error if it is unable to recognize the type).\n *\n * @param id The identifier of the bound type that should be injected.\n */\nexport function Inject(id: InjectableId<any>): ParameterDecorator {\n\t/**\n\t * @param target The constructor function of the class (we don't allow @Inject on anything else).\n\t * @param parameterName The name of the parameter\n\t * @param parameterIndex The ordinal index of the parameter in the function’s parameter list\n\t * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.\n\t */\n\treturn function (target: Function, parameterName: string | symbol, parameterIndex: number): void {\n\t\tif (id === undefined) {\n\t\t\tthrow new Error('Undefined id passed to @Inject [' + targetHint(target) + ']');\n\t\t}\n\t\tconst paramKey = validateSingleConstructorParam('Inject', target, parameterIndex);\n\t\tReflect.defineMetadata(INJECT_METADATA_KEY, id, target, paramKey);\n\t};\n}\n\n/**\n * This is a helper function used by the container to retrieve the @Inject metadata for a specifically indexed constructor parameter\n *\n * @param target The constructor function of the class (we don't allow @Inject on anything else).\n * @param parameterIndex The ordinal index of the parameter in the constructor’s parameter list\n * @see Inject\n */\nexport function _getInjectedIdAt(target: Function, parameterIndex: number): InjectableId<any> {\n\treturn Reflect.getMetadata(INJECT_METADATA_KEY, target, makeParamIdxKey(parameterIndex)) as InjectableId<any>;\n}\n\n/**\n * Placed just before a constructor parameter, this parameter decorator signals the container that it should supply the 'alt' constant value (undefined by default) if for *any* reason it is unable to otherwise resolve the type of the parameter.\n * WARNING! It is your responsibility to ensure that alt is of the appropriate type/value.\n */\nexport function Optional(alt?: any): ParameterDecorator { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types\n\t/**\n\t * @param target The constructor function of the class (we don't allow @Optional on anything else).\n\t * @param parameterName The name of the parameter\n\t * @param parameterIndex The ordinal index of the parameter in the function’s parameter list\n\t * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.\n\t */\n\treturn function (target: Function, parameterName: string | symbol, parameterIndex: number): void {\n\t\tconst paramKey = validateSingleConstructorParam('Optional', target, parameterIndex);\n\t\tReflect.defineMetadata(OPTIONAL_METADATA_KEY, {value: alt}, target, paramKey);\n\t};\n}\n\n/**\n * This is a helper function used by the container to retrieve the @Optional metadata for a specifically indexed constructor parameter\n *\n * @param target The constructor function of the class (we don't allow @Optional on anything else).\n * @param parameterIndex The ordinal index of the parameter in the constructor’s parameter list\n * @see Optional\n * @returns an object containing the value provided in the decorator, or undefined if no annotation was present.\n */\nexport function _getOptionalDefaultAt(target: Function, parameterIndex: number): { value: any } {\n\treturn Reflect.getMetadata(OPTIONAL_METADATA_KEY, target, makeParamIdxKey(parameterIndex)) as { value: any }; // See the @Optional decorator before making any changes here.\n}\n\n/**\n * Placed just before a class method, this method decorator flags a method that should be called after an object has been instantiated by the container, but before it is put into service.\n * The method will be assumed to be synchronous unless the method signature explicitly declares it's return type to be \": Promise<something>\"\n * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.\n */\nexport function PostConstruct(): MethodDecorator {\n\t/**\n\t * @param prototypeOrConstructor The prototype of the class (we don't allow @PostConstruct on anything other than a class instance method.\n\t * @param methodName The name of the method.\n\t * @param descriptor The Property Descriptor for the method.\n\t * @returns Undefined (nothing), as this decorator does not modify the method in any way.\n\t */\n\t// noinspection JSUnusedLocalSymbols\n\treturn function (target: Object, methodName: string | symbol, descriptor: PropertyDescriptor) { // eslint-disable-line @typescript-eslint/no-unused-vars\n\t\tif (typeof target !== 'object' || typeof target.constructor !== 'function') {\n\t\t\tthrow new Error('@PostConstruct not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');\n\t\t}\n\t\tif (Reflect.hasOwnMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, target.constructor) || Reflect.hasOwnMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, target.constructor)) {\n\t\t\tthrow new Error('@PostConstruct applied multiple times [' + targetHint(target.constructor) + ']');\n\t\t}\n\t\tconst rt = Reflect.getMetadata(REFLECT_RETURN, target, methodName);\n\t\tif (typeof rt === 'function') {\n\t\t\tReflect.defineMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, methodName, target.constructor);\n\t\t}\n\t\telse {\n\t\t\tReflect.defineMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, methodName, target.constructor);\n\t\t}\n\t};\n}\n\n// noinspection JSUnusedGlobalSymbols\n/**\n * Placed just before a class method, this decorator identifies a method which should be called when an object is removed from service.\n * If invoked by the container, the container will drop any references it has to the object when the method returns.\n * Note that this decorator is *not* a guarantee (or even an implication) that the decorated method will be called (JavaScript has no mechanism to enforce such a contract).\n * This decorator simply serves as a flag to indicate a method which is intended to clean up resources allocated by the object *which would not otherwise be garbage collected*.\n * You should *not* use this decorator as a general \"object finalization\" method. It has very limited scope and purpose.\n * The decorated method must complete normally (no throwing), as \"release\" is not an abort-able process.\n * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.\n * The @see InvokeReleaseMethod helper function can search for and invoke the @Release decorated method of an object.\n * Also @see Container.releaseSingletons for the intended usage of this decorator.\n * It is intended that after the @Release decorated method of an object is called, that object will not be used again, but this is of course not enforced).\n */\nexport function Release(): MethodDecorator {\n\t/**\n\t * @param prototypeOrConstructor The prototype of the class (we don't allow @Release on anything other than a class instance method.\n\t * @param methodName The name of the method.\n\t * @param descriptor The Property Descriptor for the method.\n\t * @returns Undefined (nothing), as this decorator does not modify the method in any way.\n\t */\n\t// noinspection JSUnusedLocalSymbols\n\treturn function (target: Object, methodName: string | symbol, descriptor: PropertyDescriptor) { // eslint-disable-line @typescript-eslint/no-unused-vars\n\t\tif (typeof target !== 'object' || typeof target.constructor !== 'function') {\n\t\t\tthrow new Error('@Release not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');\n\t\t}\n\t\tif (Reflect.hasOwnMetadata(RELEASE_METADATA_KEY, target.constructor)) {\n\t\t\tthrow new Error('@Release applied multiple times [' + targetHint(target.constructor) + ']');\n\t\t}\n\t\tReflect.defineMetadata(RELEASE_METADATA_KEY, methodName, target.constructor);\n\t};\n}\n"]}
@@ -1,4 +1,4 @@
1
- export { Binder } from './binder.js';
1
+ export { Binder, SyncFactory, AsyncFactory, BindAs } from './binder.js';
2
2
  export { Container } from './container.js';
3
3
  export { Inject, Injectable, Optional, PostConstruct, Release } from './decorators.js';
4
4
  export { ClassConstructor, InjectableId, InjectionToken, Injector } from './injector.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AACA,+CAAyC;AAAjC,yGAAA,SAAS,OAAA;AACjB,iDAAqF;AAA7E,uGAAA,MAAM,OAAA;AAAE,2GAAA,UAAU,OAAA;AAAE,yGAAA,QAAQ,OAAA;AAAE,8GAAA,aAAa,OAAA;AAAE,wGAAA,OAAO,OAAA;AAC5D,6CAAuF;AAA/C,6GAAA,cAAc,OAAA","sourcesContent":["export {Binder} from './binder.js';\nexport {Container} from './container.js';\nexport {Inject, Injectable, Optional, PostConstruct, Release} from './decorators.js';\nexport {ClassConstructor, InjectableId, InjectionToken, Injector} from './injector.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AACA,+CAAyC;AAAjC,yGAAA,SAAS,OAAA;AACjB,iDAAqF;AAA7E,uGAAA,MAAM,OAAA;AAAE,2GAAA,UAAU,OAAA;AAAE,yGAAA,QAAQ,OAAA;AAAE,8GAAA,aAAa,OAAA;AAAE,wGAAA,OAAO,OAAA;AAC5D,6CAAuF;AAA/C,6GAAA,cAAc,OAAA","sourcesContent":["export {Binder, SyncFactory, AsyncFactory, BindAs} from './binder.js';\nexport {Container} from './container.js';\nexport {Inject, Injectable, Optional, PostConstruct, Release} from './decorators.js';\nexport {ClassConstructor, InjectableId, InjectionToken, Injector} from './injector.js';\n"]}
@@ -73,7 +73,7 @@ export interface Binder extends Injector {
73
73
  * Bind an InjectableId to a constant value.
74
74
  * Constants are by their very nature singleton, and are assumed to be error proof.
75
75
  */
76
- bindConstant<T>(id: InjectableId<T>, value: T): void;
76
+ bindConstant<T>(id: InjectableId<T>, value: T): T;
77
77
  /**
78
78
  * Bind an InjectableId to a class (actually it's constructor).
79
79
  * As a shortcut, you may use the class constructor as the 'id' (e.g. container.bindClass(A); ).
@@ -1 +1 @@
1
- {"version":3,"file":"binder.js","sourceRoot":"","sources":["../../src/binder.ts"],"names":[],"mappings":"","sourcesContent":["import {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector.js';\n\n/**\n * Type definition for functions that return a value.\n * The function should return a valid value, but may throw an exception if it cannot.\n */\nexport type SyncFactory<T> = (injector: Injector) => T;\n\n/**\n * Type definition for functions that return a Promise for a value.\n * The function *must* not throw and must return a valid Promise (e.g. pending, resolved, rejected).\n */\nexport type AsyncFactory<T> = (injector: Injector) => Promise<T>;\n\n/**\n * You may bind an error handler which will be invoked, if the bound InjectableId could not be put into service.\n * An error handler *must* not throw, but may return an Error that will be propagated back up the call chain.\n *\n * @param binder The Binder that experienced the error.\n * @param id The identifier for what was trying to be made.\n * @param maker The thing that made (or tried to provideAsState). Will be one of type ClassConstructor, SyncFactory, or AsyncFactory, depending on how you registered the binding.\n * @param error Identifies the problem that occurred.\n * @param value If the 'maker' was able to create the thing, but it had an error during post construction, the made thing will be passed here.\n * @returns one of 3 results...\n * A substitute thing (kind of like a 'maker' do-over) which must be fully operational (e.g. any `@PostConstruct` will be ignored).\n * An alternate Error which will be propagated back up the call chain.\n * Undefined, which means the 'error' parameter will be propagated back up the call chain.\n */\nexport type OnErrorCallback<T, M> = (injector: Injector, id: InjectableId<T>, maker: M, error: unknown, value?: T) => T | Error | void;\n\n/**\n * You may bind a success handler which will be invoked just before the bound InjectableId is put into service.\n * This is an alternative to the more preferred `@PostConstruct` decorator for scenarios when usage of that decorator is not feasible.\n * WARNING:\n * By registering a success handler, you override and nullify any `@PostConstruct` decorator on the class.\n * In such a scenario, the success handler should perform whatever care and feeding the class expected from the `@PostConstruct` decorator.\n * A success handler *must* not throw, but may return an Error that will be propagated back up the call chain.\n *\n * @param binder The Binder that performed the construction.\n * @param id The identifier for what was made.\n * @param maker The thing that made. Will be one of type ClassConstructor, SyncFactory, or AsyncFactory, depending on how you registered the binding.\n * @param value The thing that was made.\n * @returns one of 3 results...\n * An Error which will be propagated back up the call chain.\n * Undefined, which means the object is ready to be placed into service.\n * A Promise that resolves to one of the above two values (undefined or Error).\n */\nexport type OnSuccessCallback<T, M> = (value: T, injector: Injector, id: InjectableId<T>, maker: M) => Promise<Error | void> | Error | void;\n\n/**\n * An interface allowing binding of an error handler.\n *\n * @see OnErrorCallback\n */\nexport interface BindErrHandler<T, M> {\n\tonError(cb: OnErrorCallback<T, M>): void;\n}\n\n/**\n * An interface allowing binding of a post construction handler.\n *\n * @see OnSuccessCallback\n */\nexport interface BindHandler<T, M> extends BindErrHandler<T, M> {\n\tonSuccess(cb: OnSuccessCallback<T, M>): BindErrHandler<T, M>;\n}\n\n/**\n * @inheritDoc\n * This specialization also allows you to specify that the binding is 'Singleton' (e.g. only one in the system).\n */\nexport interface BindAs<T, M> extends BindHandler<T, M> {\n\tasSingleton(): BindHandler<T, M>;\n}\n\n/**\n * Bind Ids to producers.\n */\nexport interface Binder extends Injector {\n\n\t/**\n\t * Bind an InjectableId to a constant value.\n\t * Constants are by their very nature singleton, and are assumed to be error proof.\n\t */\n\tbindConstant<T>(id: InjectableId<T>, value: T): void;\n\n\t/**\n\t * Bind an InjectableId to a class (actually it's constructor).\n\t * As a shortcut, you may use the class constructor as the 'id' (e.g. container.bindClass(A); ).\n\t * The container will also invoke any `@PostConstruct` present on the class.\n\t */\n\tbindClass<T>(id: ClassConstructor<T>, constructor?: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\n\tbindClass<T>(id: string | symbol | AbstractConstructor<T> | InjectableId<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\n\t/**\n\t * Bind an InjectableId to a synchronous factory that will be invoked on demand when the object is needed.\n\t * The factory should produce the needed value\n\t * NOTE: The container will not invoke any `@PostConstruct` present on the class, this is the responsibility of the factory.\n\t */\n\tbindFactory<T>(id: InjectableId<T>, factory: SyncFactory<T>): BindAs<T, SyncFactory<T>>;\n\n\t/**\n\t * Bind an InjectableId to an asynchronous factory that will be invoked on demand when the object is needed.\n\t * The factory should produce the needed value (asynchronously of course).\n\t * NOTE: The container will not invoke any `@PostConstruct` present on the class, this is the responsibility of the factory.\n\t * WARNING!!! The factory may not throw and must return a valid Promise (which can be pending, resolved, rejected, etc.).\n\t */\n\tbindAsyncFactory<T>(id: InjectableId<T>, factory: AsyncFactory<T>): BindAs<T, AsyncFactory<T>>;\n\n\t/**\n\t * This essentially pre creates/loads all *singleton* InjectableIds currently known to the Binder.\n\t * This *may* be helpful if you wish to use Injector.get on a dependency tree that has asynchronous singletons within the tree.\n\t *\n\t * @param asyncOnly Only resolve AsyncFactorys as well as any bound classes that have an asynchronous `@PostConstruct` decorator. WARNING: If true, SyncFactorys will *not* be resolved even if they are Singletons.\n\t * @param parentRecursion If true and the the container has a parent, resolveIfSingleton will first be called for the parent\n\t * @returns A Promise that resolves when all Singleton's have been resolved, OR rejects if one or more of the Singleton's failed to resolve. NOTE: Rejection does not occur until all Singleton resolutions have settled, and the rejection reason/err will be a Map<InjectableId, Error>\n\t */\n\tresolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this>;\n}\n"]}
1
+ {"version":3,"file":"binder.js","sourceRoot":"","sources":["../../src/binder.ts"],"names":[],"mappings":"","sourcesContent":["import {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector.js';\n\n/**\n * Type definition for functions that return a value.\n * The function should return a valid value, but may throw an exception if it cannot.\n */\nexport type SyncFactory<T> = (injector: Injector) => T;\n\n/**\n * Type definition for functions that return a Promise for a value.\n * The function *must* not throw and must return a valid Promise (e.g. pending, resolved, rejected).\n */\nexport type AsyncFactory<T> = (injector: Injector) => Promise<T>;\n\n/**\n * You may bind an error handler which will be invoked, if the bound InjectableId could not be put into service.\n * An error handler *must* not throw, but may return an Error that will be propagated back up the call chain.\n *\n * @param binder The Binder that experienced the error.\n * @param id The identifier for what was trying to be made.\n * @param maker The thing that made (or tried to provideAsState). Will be one of type ClassConstructor, SyncFactory, or AsyncFactory, depending on how you registered the binding.\n * @param error Identifies the problem that occurred.\n * @param value If the 'maker' was able to create the thing, but it had an error during post construction, the made thing will be passed here.\n * @returns one of 3 results...\n * A substitute thing (kind of like a 'maker' do-over) which must be fully operational (e.g. any `@PostConstruct` will be ignored).\n * An alternate Error which will be propagated back up the call chain.\n * Undefined, which means the 'error' parameter will be propagated back up the call chain.\n */\nexport type OnErrorCallback<T, M> = (injector: Injector, id: InjectableId<T>, maker: M, error: unknown, value?: T) => T | Error | void;\n\n/**\n * You may bind a success handler which will be invoked just before the bound InjectableId is put into service.\n * This is an alternative to the more preferred `@PostConstruct` decorator for scenarios when usage of that decorator is not feasible.\n * WARNING:\n * By registering a success handler, you override and nullify any `@PostConstruct` decorator on the class.\n * In such a scenario, the success handler should perform whatever care and feeding the class expected from the `@PostConstruct` decorator.\n * A success handler *must* not throw, but may return an Error that will be propagated back up the call chain.\n *\n * @param binder The Binder that performed the construction.\n * @param id The identifier for what was made.\n * @param maker The thing that made. Will be one of type ClassConstructor, SyncFactory, or AsyncFactory, depending on how you registered the binding.\n * @param value The thing that was made.\n * @returns one of 3 results...\n * An Error which will be propagated back up the call chain.\n * Undefined, which means the object is ready to be placed into service.\n * A Promise that resolves to one of the above two values (undefined or Error).\n */\nexport type OnSuccessCallback<T, M> = (value: T, injector: Injector, id: InjectableId<T>, maker: M) => Promise<Error | void> | Error | void;\n\n/**\n * An interface allowing binding of an error handler.\n *\n * @see OnErrorCallback\n */\nexport interface BindErrHandler<T, M> {\n\tonError(cb: OnErrorCallback<T, M>): void;\n}\n\n/**\n * An interface allowing binding of a post construction handler.\n *\n * @see OnSuccessCallback\n */\nexport interface BindHandler<T, M> extends BindErrHandler<T, M> {\n\tonSuccess(cb: OnSuccessCallback<T, M>): BindErrHandler<T, M>;\n}\n\n/**\n * @inheritDoc\n * This specialization also allows you to specify that the binding is 'Singleton' (e.g. only one in the system).\n */\nexport interface BindAs<T, M> extends BindHandler<T, M> {\n\tasSingleton(): BindHandler<T, M>;\n}\n\n/**\n * Bind Ids to producers.\n */\nexport interface Binder extends Injector {\n\n\t/**\n\t * Bind an InjectableId to a constant value.\n\t * Constants are by their very nature singleton, and are assumed to be error proof.\n\t */\n\tbindConstant<T>(id: InjectableId<T>, value: T): T;\n\n\t/**\n\t * Bind an InjectableId to a class (actually it's constructor).\n\t * As a shortcut, you may use the class constructor as the 'id' (e.g. container.bindClass(A); ).\n\t * The container will also invoke any `@PostConstruct` present on the class.\n\t */\n\tbindClass<T>(id: ClassConstructor<T>, constructor?: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\n\tbindClass<T>(id: string | symbol | AbstractConstructor<T> | InjectableId<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\n\t/**\n\t * Bind an InjectableId to a synchronous factory that will be invoked on demand when the object is needed.\n\t * The factory should produce the needed value\n\t * NOTE: The container will not invoke any `@PostConstruct` present on the class, this is the responsibility of the factory.\n\t */\n\tbindFactory<T>(id: InjectableId<T>, factory: SyncFactory<T>): BindAs<T, SyncFactory<T>>;\n\n\t/**\n\t * Bind an InjectableId to an asynchronous factory that will be invoked on demand when the object is needed.\n\t * The factory should produce the needed value (asynchronously of course).\n\t * NOTE: The container will not invoke any `@PostConstruct` present on the class, this is the responsibility of the factory.\n\t * WARNING!!! The factory may not throw and must return a valid Promise (which can be pending, resolved, rejected, etc.).\n\t */\n\tbindAsyncFactory<T>(id: InjectableId<T>, factory: AsyncFactory<T>): BindAs<T, AsyncFactory<T>>;\n\n\t/**\n\t * This essentially pre creates/loads all *singleton* InjectableIds currently known to the Binder.\n\t * This *may* be helpful if you wish to use Injector.get on a dependency tree that has asynchronous singletons within the tree.\n\t *\n\t * @param asyncOnly Only resolve AsyncFactorys as well as any bound classes that have an asynchronous `@PostConstruct` decorator. WARNING: If true, SyncFactorys will *not* be resolved even if they are Singletons.\n\t * @param parentRecursion If true and the the container has a parent, resolveIfSingleton will first be called for the parent\n\t * @returns A Promise that resolves when all Singleton's have been resolved, OR rejects if one or more of the Singleton's failed to resolve. NOTE: Rejection does not occur until all Singleton resolutions have settled, and the rejection reason/err will be a Map<InjectableId, Error>\n\t */\n\tresolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this>;\n}\n"]}
@@ -96,13 +96,16 @@ export class ClassBasedProvider extends BindableProvider {
96
96
  return [];
97
97
  }
98
98
  return argTypes.map((argType, index) => {
99
- // The reflect-metadata API fails on circular dependencies, and will return undefined for the argument instead.
100
- if (argType === undefined) {
101
- throw new Error(`Injection error. Recursive dependency in constructor for ${this.maker.toString()} at index ${index}`);
102
- }
103
- // Check if an Inject annotation precedes the parameter.
99
+ // The reflect-metadata API fails on circular dependencies returning undefined instead.
100
+ // Additionally, it cannot return generic types (no runtime type info).
101
+ // If an Inject annotation precedes the parameter, then that is what should get injected.
104
102
  const overrideToken = _getInjectedIdAt(this.maker, index);
103
+ // If there was no Inject annotation, we might still be able to determine what to inject using the 'argType' (aka Reflect design:paramtypes).
105
104
  const actualToken = overrideToken === undefined ? argType : overrideToken;
105
+ if (actualToken === undefined) {
106
+ // No Inject annotation, and the type is not known.
107
+ throw new Error(`Injection error. Unable to determine parameter ${index} type/value of ${this.maker.toString()} constructor`);
108
+ }
106
109
  // Ask our container to resolve the parameter.
107
110
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
108
111
  let param = this.injector.resolveState(actualToken);
@@ -1 +1 @@
1
- {"version":3,"file":"class-provider.js","sourceRoot":"","sources":["../../src/class-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import {BindableProvider} from './bindable-provider.js';\nimport {POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_PARAMS} from './constants.js';\nimport {_getInjectedIdAt, _getOptionalDefaultAt} from './decorators.js';\nimport {ClassConstructor, InjectableId, Injector} from './injector.js';\nimport {State} from './state.js';\nimport {isPromise} from './utils.js';\n\n/*\n * This is a bit of a hack, but it avoids a ton of alternative hacks.\n * Note that in the Container, resolveState is a protected method.\n * Injector was never meant to publicly expose State.\n * Gotta love JS!\n */\ninterface StateResolvingInjector extends Injector {\n\tresolveState<T>(id: InjectableId<T>): State<T>;\n}\n\n/**\n * @inheritDoc\n * This specialization invokes it's configured class constructor synchronously and then scans for (and invokes) any @PostConstruct (which may be synchronous or asynchronous).\n */\nexport class ClassBasedProvider<T> extends BindableProvider<T, ClassConstructor<T>> {\n\tconstructor(injector: StateResolvingInjector, id: InjectableId<T>, maker: ClassConstructor<T>) {\n\t\tsuper(injector, id, maker);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @see the class description for this Provider.\n\t * This method is just a singleton guard, the real work is done by provideAsStateImpl.\n\t */\n\tprovideAsState(): State<T> {\n\t\tlet retVal = this.singleton;\n\t\tif (!retVal) {\n\t\t\tretVal = this.provideAsStateImpl();\n\t\t}\n\t\tif (this.singleton === null)\n\t\t\tthis.singleton = retVal;\n\t\treturn retVal;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization returns undefined if 'asyncOnly' is true and there is no asynchronous PostConstruct annotation (since class constructors can never by asynchronous).\n\t */\n\tresolveIfSingleton(asyncOnly: boolean): Promise<T> {\n\t\tif ((!asyncOnly) || Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker))\n\t\t\treturn super.resolveIfSingleton(false);\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Make a resolved or pending State that reflects any @PostConstruct annotations.\n\t */\n\tprotected makePostConstructState(obj: T): State<T> {\n\t\tif (typeof obj === 'object' && (!Array.isArray(obj)) && obj.constructor) {\n\t\t\tlet maybeAsync = false;\n\t\t\tlet pcFn: () => void | Error | Promise<void | Error>;\n\t\t\tif (typeof this.successHandler === 'function') {\n\t\t\t\tmaybeAsync = true;\n\t\t\t\tpcFn = () => {\n\t\t\t\t\treturn this.successHandler(obj, this.injector, this.id, this.maker);\n\t\t\t\t};\n\t\t\t}\n\t\t\telse {\n\t\t\t\t/* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */\n\t\t\t\t// Check to see if there is a @PostConstruct annotation on a method of the class.\n\t\t\t\tlet postConstruct: string = Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, obj.constructor);\n\t\t\t\tif (!postConstruct) {\n\t\t\t\t\tmaybeAsync = true;\n\t\t\t\t\tpostConstruct = Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, obj.constructor);\n\t\t\t\t}\n\t\t\t\tif (postConstruct && obj.constructor.prototype[postConstruct] && typeof obj.constructor.prototype[postConstruct] === 'function')\n\t\t\t\t\tpcFn = obj[postConstruct].bind?.(obj);\n\n\t\t\t\t/* eslint-enable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */\n\t\t\t}\n\t\t\tif (pcFn) {\n\t\t\t\tlet result: any;\n\t\t\t\ttry {\n\t\t\t\t\tresult = pcFn();\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\t// The post construction method threw while executing, give the errorHandler (if any) a crack at recovery.\n\t\t\t\t\ttry {\n\t\t\t\t\t\tobj = this.queryErrorHandler(err, obj); // The returned obj is unlikely to be the original obj.\n\t\t\t\t\t\treturn State.MakeState<T>(null, undefined, obj);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (e) {\n\t\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// The post construction method says it will let us know when it's finished.\n\t\t\t\tif (result && (result instanceof Promise || (maybeAsync && isPromise<void>(result)))) {\n\t\t\t\t\t// Return a State that is pending (the other return statements in this method return a State which is resolved or rejected).\n\t\t\t\t\t/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\t\t\t\t\treturn State.MakeState<T>(this.makePromiseForObj<T>(result, () => obj));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// No PostConstruct, just return a resolved State\n\t\treturn State.MakeState<T>(null, undefined, obj);\n\t}\n\n\t/**\n\t * This method collects the States of all the constructor parameters for our target class.\n\t */\n\tprotected getConstructorParameterStates(): State[] {\n\t\tconst argTypes = Reflect.getMetadata(REFLECT_PARAMS, this.maker);\n\t\tif (argTypes === undefined || !Array.isArray(argTypes)) {\n\t\t\treturn [];\n\t\t}\n\t\treturn argTypes.map((argType, index) => {\n\t\t\t// The reflect-metadata API fails on circular dependencies, and will return undefined for the argument instead.\n\t\t\tif (argType === undefined) {\n\t\t\t\tthrow new Error(`Injection error. Recursive dependency in constructor for ${this.maker.toString()} at index ${index}`);\n\t\t\t}\n\t\t\t// Check if an Inject annotation precedes the parameter.\n\t\t\tconst overrideToken = _getInjectedIdAt(this.maker, index);\n\t\t\tconst actualToken = overrideToken === undefined ? argType : overrideToken;\n\t\t\t// Ask our container to resolve the parameter.\n\t\t\t/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\t\t\tlet param = (this.injector as StateResolvingInjector).resolveState(actualToken);\n\t\t\t// If the parameter could not be resolved, see if there is an @Optional annotation\n\t\t\tif ((!param.pending) && param.rejected) {\n\t\t\t\tconst md = _getOptionalDefaultAt(this.maker, index);\n\t\t\t\tif (md)\n\t\t\t\t\tparam = State.MakeState<any>(null, undefined, md.value);\n\t\t\t}\n\t\t\treturn param;\n\t\t});\n\t}\n\n\t/**\n\t * Gather the needed constructor parameters, invoke the constructor, and figure out what post construction needs done.\n\t */\n\tprivate provideAsStateImpl(): State<T> {\n\t\tconst params = this.getConstructorParameterStates();\n\n\t\t// If any of the params are in a rejected state, we cannot construct.\n\t\tconst paramRejection = params.find((p) => {\n\t\t\treturn (!p.pending) && p.rejected;\n\t\t});\n\t\tif (paramRejection) {\n\t\t\treturn paramRejection as State<T>;\n\t\t}\n\t\t// If any of the params are in a pending state, we will have to wait for them to be resolved before we can construct.\n\t\tconst pendingParams = params.filter((p) => {\n\t\t\treturn p.pending;\n\t\t}).map((p) => {\n\t\t\treturn p.promise;\n\t\t});\n\t\tif (pendingParams.length > 0) {\n\t\t\t// Some of the parameters needed for construction are not yet available, wait for them and then attempt construction.\n\t\t\tconst objPromise = this.makePromiseForObj<any[]>(Promise.all(pendingParams), () => {\n\t\t\t\t// All the parameters are now available, instantiate the class.\n\t\t\t\t// If this throws, it will be handled by our caller.\n\t\t\t\treturn Reflect.construct(this.maker, params.map((p) => p.fulfilled as unknown));\n\t\t\t});\n\t\t\t// Once the obj is resolved, then we need to check for PostConstruct and if it was async, wait for that too.\n\t\t\treturn State.MakeState<T>(objPromise.then((obj) => {\n\t\t\t\tconst state = this.makePostConstructState(obj);\n\t\t\t\tif (state.pending) {\n\t\t\t\t\treturn state.promise; // chain (aka wait some more).\n\t\t\t\t}\n\t\t\t\telse if (state.rejected) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\t\t\treturn state.rejected as any; // error\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn state.fulfilled; // value (aka obj).\n\t\t\t\t}\n\t\t\t}));\n\t\t}\n\t\telse {\n\t\t\t// All parameters needed for construction are available, instantiate the object.\n\t\t\ttry {\n\t\t\t\tconst newObj = Reflect.construct(this.maker, params.map((p) => p.fulfilled as unknown));\n\t\t\t\treturn this.makePostConstructState(newObj);\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\t// There was an error, give the errorHandler (if any) a crack at recovery.\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(null, undefined, this.queryErrorHandler(err));\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"class-provider.js","sourceRoot":"","sources":["../../src/class-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import {BindableProvider} from './bindable-provider.js';\nimport {POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_PARAMS} from './constants.js';\nimport {_getInjectedIdAt, _getOptionalDefaultAt} from './decorators.js';\nimport {ClassConstructor, InjectableId, Injector} from './injector.js';\nimport {State} from './state.js';\nimport {isPromise} from './utils.js';\n\n/*\n * This is a bit of a hack, but it avoids a ton of alternative hacks.\n * Note that in the Container, resolveState is a protected method.\n * Injector was never meant to publicly expose State.\n * Gotta love JS!\n */\ninterface StateResolvingInjector extends Injector {\n\tresolveState<T>(id: InjectableId<T>): State<T>;\n}\n\n/**\n * @inheritDoc\n * This specialization invokes it's configured class constructor synchronously and then scans for (and invokes) any @PostConstruct (which may be synchronous or asynchronous).\n */\nexport class ClassBasedProvider<T> extends BindableProvider<T, ClassConstructor<T>> {\n\tconstructor(injector: StateResolvingInjector, id: InjectableId<T>, maker: ClassConstructor<T>) {\n\t\tsuper(injector, id, maker);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @see the class description for this Provider.\n\t * This method is just a singleton guard, the real work is done by provideAsStateImpl.\n\t */\n\tprovideAsState(): State<T> {\n\t\tlet retVal = this.singleton;\n\t\tif (!retVal) {\n\t\t\tretVal = this.provideAsStateImpl();\n\t\t}\n\t\tif (this.singleton === null)\n\t\t\tthis.singleton = retVal;\n\t\treturn retVal;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization returns undefined if 'asyncOnly' is true and there is no asynchronous PostConstruct annotation (since class constructors can never by asynchronous).\n\t */\n\tresolveIfSingleton(asyncOnly: boolean): Promise<T> {\n\t\tif ((!asyncOnly) || Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker))\n\t\t\treturn super.resolveIfSingleton(false);\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Make a resolved or pending State that reflects any @PostConstruct annotations.\n\t */\n\tprotected makePostConstructState(obj: T): State<T> {\n\t\tif (typeof obj === 'object' && (!Array.isArray(obj)) && obj.constructor) {\n\t\t\tlet maybeAsync = false;\n\t\t\tlet pcFn: () => void | Error | Promise<void | Error>;\n\t\t\tif (typeof this.successHandler === 'function') {\n\t\t\t\tmaybeAsync = true;\n\t\t\t\tpcFn = () => {\n\t\t\t\t\treturn this.successHandler(obj, this.injector, this.id, this.maker);\n\t\t\t\t};\n\t\t\t}\n\t\t\telse {\n\t\t\t\t/* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */\n\t\t\t\t// Check to see if there is a @PostConstruct annotation on a method of the class.\n\t\t\t\tlet postConstruct: string = Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, obj.constructor);\n\t\t\t\tif (!postConstruct) {\n\t\t\t\t\tmaybeAsync = true;\n\t\t\t\t\tpostConstruct = Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, obj.constructor);\n\t\t\t\t}\n\t\t\t\tif (postConstruct && obj.constructor.prototype[postConstruct] && typeof obj.constructor.prototype[postConstruct] === 'function')\n\t\t\t\t\tpcFn = obj[postConstruct].bind?.(obj);\n\n\t\t\t\t/* eslint-enable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */\n\t\t\t}\n\t\t\tif (pcFn) {\n\t\t\t\tlet result: any;\n\t\t\t\ttry {\n\t\t\t\t\tresult = pcFn();\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\t// The post construction method threw while executing, give the errorHandler (if any) a crack at recovery.\n\t\t\t\t\ttry {\n\t\t\t\t\t\tobj = this.queryErrorHandler(err, obj); // The returned obj is unlikely to be the original obj.\n\t\t\t\t\t\treturn State.MakeState<T>(null, undefined, obj);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (e) {\n\t\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// The post construction method says it will let us know when it's finished.\n\t\t\t\tif (result && (result instanceof Promise || (maybeAsync && isPromise<void>(result)))) {\n\t\t\t\t\t// Return a State that is pending (the other return statements in this method return a State which is resolved or rejected).\n\t\t\t\t\t/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\t\t\t\t\treturn State.MakeState<T>(this.makePromiseForObj<T>(result, () => obj));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// No PostConstruct, just return a resolved State\n\t\treturn State.MakeState<T>(null, undefined, obj);\n\t}\n\n\t/**\n\t * This method collects the States of all the constructor parameters for our target class.\n\t */\n\tprotected getConstructorParameterStates(): State[] {\n\t\tconst argTypes = Reflect.getMetadata(REFLECT_PARAMS, this.maker);\n\t\tif (argTypes === undefined || !Array.isArray(argTypes)) {\n\t\t\treturn [];\n\t\t}\n\t\treturn argTypes.map((argType, index) => {\n\t\t\t// The reflect-metadata API fails on circular dependencies returning undefined instead.\n\t\t\t// Additionally, it cannot return generic types (no runtime type info).\n\t\t\t// If an Inject annotation precedes the parameter, then that is what should get injected.\n\t\t\tconst overrideToken = _getInjectedIdAt(this.maker, index);\n\t\t\t// If there was no Inject annotation, we might still be able to determine what to inject using the 'argType' (aka Reflect design:paramtypes).\n\t\t\tconst actualToken = overrideToken === undefined ? argType : overrideToken;\n\t\t\tif (actualToken === undefined) {\n\t\t\t\t// No Inject annotation, and the type is not known.\n\t\t\t\tthrow new Error(`Injection error. Unable to determine parameter ${index} type/value of ${this.maker.toString()} constructor`);\n\t\t\t}\n\t\t\t// Ask our container to resolve the parameter.\n\t\t\t/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\t\t\tlet param = (this.injector as StateResolvingInjector).resolveState(actualToken);\n\t\t\t// If the parameter could not be resolved, see if there is an @Optional annotation\n\t\t\tif ((!param.pending) && param.rejected) {\n\t\t\t\tconst md = _getOptionalDefaultAt(this.maker, index);\n\t\t\t\tif (md)\n\t\t\t\t\tparam = State.MakeState<any>(null, undefined, md.value);\n\t\t\t}\n\t\t\treturn param;\n\t\t});\n\t}\n\n\t/**\n\t * Gather the needed constructor parameters, invoke the constructor, and figure out what post construction needs done.\n\t */\n\tprivate provideAsStateImpl(): State<T> {\n\t\tconst params = this.getConstructorParameterStates();\n\n\t\t// If any of the params are in a rejected state, we cannot construct.\n\t\tconst paramRejection = params.find((p) => {\n\t\t\treturn (!p.pending) && p.rejected;\n\t\t});\n\t\tif (paramRejection) {\n\t\t\treturn paramRejection as State<T>;\n\t\t}\n\t\t// If any of the params are in a pending state, we will have to wait for them to be resolved before we can construct.\n\t\tconst pendingParams = params.filter((p) => {\n\t\t\treturn p.pending;\n\t\t}).map((p) => {\n\t\t\treturn p.promise;\n\t\t});\n\t\tif (pendingParams.length > 0) {\n\t\t\t// Some of the parameters needed for construction are not yet available, wait for them and then attempt construction.\n\t\t\tconst objPromise = this.makePromiseForObj<any[]>(Promise.all(pendingParams), () => {\n\t\t\t\t// All the parameters are now available, instantiate the class.\n\t\t\t\t// If this throws, it will be handled by our caller.\n\t\t\t\treturn Reflect.construct(this.maker, params.map((p) => p.fulfilled as unknown));\n\t\t\t});\n\t\t\t// Once the obj is resolved, then we need to check for PostConstruct and if it was async, wait for that too.\n\t\t\treturn State.MakeState<T>(objPromise.then((obj) => {\n\t\t\t\tconst state = this.makePostConstructState(obj);\n\t\t\t\tif (state.pending) {\n\t\t\t\t\treturn state.promise; // chain (aka wait some more).\n\t\t\t\t}\n\t\t\t\telse if (state.rejected) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\t\t\treturn state.rejected as any; // error\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn state.fulfilled; // value (aka obj).\n\t\t\t\t}\n\t\t\t}));\n\t\t}\n\t\telse {\n\t\t\t// All parameters needed for construction are available, instantiate the object.\n\t\t\ttry {\n\t\t\t\tconst newObj = Reflect.construct(this.maker, params.map((p) => p.fulfilled as unknown));\n\t\t\t\treturn this.makePostConstructState(newObj);\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\t// There was an error, give the errorHandler (if any) a crack at recovery.\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(null, undefined, this.queryErrorHandler(err));\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -36,7 +36,7 @@ export declare class Container implements Binder {
36
36
  /**
37
37
  * @inheritDoc
38
38
  */
39
- bindConstant<T>(id: InjectableId<T>, value: T): void;
39
+ bindConstant<T>(id: InjectableId<T>, value: T): T;
40
40
  /**
41
41
  * @inheritDoc
42
42
  */
@@ -94,6 +94,7 @@ export class Container {
94
94
  */
95
95
  bindConstant(id, value) {
96
96
  this.providers.set(id, new ConstantProvider(value));
97
+ return value;
97
98
  }
98
99
  bindClass(id, constructor) {
99
100
  if (typeof constructor === 'undefined') {
@@ -1 +1 @@
1
- {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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","sourcesContent":["import {AsyncFactoryBasedProvider} from './async-factory-provider.js';\nimport {BindableProvider} from './bindable-provider.js';\nimport {AsyncFactory, BindAs, Binder, SyncFactory} from './binder.js';\nimport {ClassBasedProvider} from './class-provider.js';\nimport {ConstantProvider} from './constant-provider.js';\nimport {INJECTABLE_METADATA_KEY} from './constants.js';\nimport {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector.js';\nimport {Provider} from './provider.js';\nimport {State} from './state.js';\nimport {FactoryBasedProvider} from './sync-factory-provider.js';\nimport {isPromise} from './utils.js';\n\n/**\n * Helper class to ensure we can distinguish between Error instances legitimately returned from Providers, and Errors thrown by Providers.\n *\n * @see resolveSingletons.\n */\nclass ReasonWrapper {\n\tconstructor(public reason: any) {\n\t}\n}\n\n/**\n * Binder and Injector (aka Container) to handle (a)synchronous dependency management.\n */\nexport class Container implements Binder {\n\n\t/**\n\t * Create a new Container, with an optional parent Injector which will be searched if any given InjectableId is not bound within this Container.\n\t */\n\tpublic constructor(protected parent?: Injector) {\n\t}\n\n\tprotected providers = new Map<InjectableId<any>, Provider>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic isIdKnown<T>(id: InjectableId<T>, ascending?: boolean): boolean {\n\t\tif (!!this.providers.get(id))\n\t\t\treturn true;\n\t\tif (ascending && this.parent)\n\t\t\treturn this.parent.isIdKnown(id, true);\n\t\treturn false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get<T>(id: InjectableId<T>): T {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent)\n\t\t\t\treturn this.parent.get<T>(id);\n\t\t\tthrow new Error('Symbol not bound: ' + id.toString());\n\t\t}\n\t\tconst state = provider.provideAsState();\n\t\tif (state.pending)\n\t\t\tthrow new Error('Synchronous request on unresolved asynchronous dependency tree: ' + id.toString());\n\t\tif (state.rejected)\n\t\t\tthrow state.rejected;\n\t\treturn state.fulfilled as T;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolve<T>(id: InjectableId<T>): Promise<T> {\n\t\tconst state = this.resolveState(id);\n\t\tif (isPromise(state.promise)) {\n\t\t\treturn state.promise;\n\t\t}\n\n\t\tif (state.rejected) {\n\t\t\treturn Promise.reject(state.rejected);\n\t\t}\n\n\t\treturn Promise.resolve(state.fulfilled);\n\t}\n\n\t// noinspection JSUnusedGlobalSymbols\n\t/**\n\t * This method is not part of the Binding interface, because it is highly unusual.\n\t * But that doesn't mean we can't imagine scenarios where you might require it.\n\t *\n\t * @param id The id to be removed.\n\t * @param ascending If true, this will remove all bindings of the specified id all the way up the parent container chain (if it exists).\n\t * @param releaseIfSingleton If true, @Provider.releaseIfSingleton will be invoked before the binding is removed.\n\t */\n\tpublic removeBinding<T>(id: InjectableId<T>, ascending?: boolean, releaseIfSingleton?: boolean): void {\n\t\tif (releaseIfSingleton) {\n\t\t\tconst p = this.providers.get(id);\n\t\t\tif (p)\n\t\t\t\tp.releaseIfSingleton();\n\t\t}\n\t\tthis.providers.delete(id);\n\n\t\tif (ascending && this.parent) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n\t\t\t(this.parent as any)?.removeBinding(id, true, releaseIfSingleton);\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindConstant<T>(id: InjectableId<T>, value: T): void {\n\t\tthis.providers.set(id, new ConstantProvider(value));\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindClass<T>(id: ClassConstructor<T>, constructor?: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | InjectableId<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | ClassConstructor<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>> {\n\t\tif (typeof constructor === 'undefined') {\n\t\t\tconstructor = id as new (...args: any[]) => T;\n\t\t}\n\t\tif (!Reflect.getMetadata(INJECTABLE_METADATA_KEY, constructor)) {\n\t\t\tthrow new Error('Class not decorated with @Injectable [' + constructor.toString() + ']');\n\t\t}\n\t\t/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\t\tconst provider = new ClassBasedProvider(this as any, id, constructor);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindFactory<T>(id: InjectableId<T>, factory: SyncFactory<T>): BindAs<T, SyncFactory<T>> {\n\t\tconst provider = new FactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindAsyncFactory<T>(id: InjectableId<T>, factory: AsyncFactory<T>): BindAs<T, AsyncFactory<T>> {\n\t\tconst provider = new AsyncFactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this> {\n\t\tconst makePromiseToResolve = () => {\n\t\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\t\tconst pending = new Map<InjectableId<any>, Promise<void>>();\n\t\t\t\t// Ask each provider to resolve itself *IF* it is a singleton.\n\t\t\t\tthis.providers.forEach((value: Provider, key: InjectableId<any>) => {\n\t\t\t\t\t// If the provider is a singleton *and* if resolution is being handled asynchronously, the provider will return a completion promise.\n\t\t\t\t\tconst p = value.resolveIfSingleton(asyncOnly);\n\t\t\t\t\tif (p !== null && typeof p !== 'undefined')\n\t\t\t\t\t\tpending.set(key, p);\n\t\t\t\t});\n\t\t\t\t// The contract for this method is that it behaves somewhat like Promise.allSettled (e.g. won't complete until all pending Singletons have settled).\n\t\t\t\t// Further the contract states that if any of the asynchronous Singletons rejected, that we will also return a rejected Promise, and that the rejection reason will be a Map of the InjectableId's that did not resolve, and the Error they emitted.\n\t\t\t\tconst pp = Array.from(pending.values());\n\t\t\t\tconst keys = Array.from(pending.keys());\n\t\t\t\t// Mapping the catch is an alternate version of Promise.allSettled (e.g. keeps Promise.all from short-circuiting).\n\t\t\t\tPromise.all(pp\n\t\t\t\t\t.map(p => p.catch(e => new ReasonWrapper(e))))\n\t\t\t\t\t.then((results) => {\n\t\t\t\t\t\tconst rejects = new Map<InjectableId<any>, Error>();\n\t\t\t\t\t\t// Check the results. Since we don't export ReasonWrapper, it is safe to assume that an instance of that was produced by our map => catch code above, so it's a rejected Singleton error.\n\t\t\t\t\t\tresults.forEach((result, idx) => {\n\t\t\t\t\t\t\tif (result instanceof ReasonWrapper) {\n\t\t\t\t\t\t\t\trejects.set(keys[idx], result.reason);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// If we had rejections, notify our caller what they were.\n\t\t\t\t\t\tif (rejects.size > 0)\n\t\t\t\t\t\t\treject(rejects);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tresolve(); // All good.\n\t\t\t\t\t});\n\t\t\t});\n\t\t};\n\t\tif (parentRecursion && typeof (this.parent as Binder)?.resolveSingletons === 'function') {\n\t\t\tconst pb: Binder = this.parent as Binder;\n\t\t\treturn pb.resolveSingletons(asyncOnly, parentRecursion).then(() => {\n\t\t\t\treturn makePromiseToResolve().then(() => this);\n\t\t\t});\n\t\t}\n\t\treturn makePromiseToResolve().then(() => this);\n\t}\n\n\t/**\n\t * As implied by the name prefix, this is a factored out method invoked only by the 'resolve' method.\n\t * It makes searching our parent (if it exists) easier (and quicker) IF our parent is a fellow instance of Container.\n\t */\n\tprotected resolveState<T>(id: InjectableId<T>): State<T> {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent) {\n\t\t\t\tif (this.parent instanceof Container) {\n\t\t\t\t\treturn this.parent.resolveState<T>(id);\n\t\t\t\t}\n\t\t\t\t// This code (below) will only ever execute if the creator of this container passes in their own implementation of an Injector.\n\t\t\t\t/* istanbul ignore next */\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(this.parent.resolve<T>(id), undefined, undefined);\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\treturn State.MakeState<T>(null, err);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn State.MakeState<T>(null, new Error('Symbol not bound: ' + id.toString()));\n\t\t}\n\t\treturn provider.provideAsState() as State<T>;\n\t}\n\n\t// noinspection JSUnusedGlobalSymbols\n\t/**\n\t * Convenience method to assist in releasing non-garbage-collectable resources that Singletons in this Container may have allocated.\n\t * It will walk through all registered Providers (of this Container only), and invoke their @see Provider.releaseIfSingleton method.\n\t * This method is not part of the Binding interface, because you normally only create (and release) Containers.\n\t * NOTE:\n\t * This *only* releases active/pending Singleton's that have already been created by this Container.\n\t * The most likely use of this method would be when you have created a new child Container for a limited duration transaction, and you want to easily cleanup temporary resources.\n\t * For example, your service object may need to know when it should unsubscribe from an RxJs stream (failure to do so can result in your Singleton not being garbage collected at the end of a transaction).\n\t * In theory, you could handle all unsubscription and cleanup yourself, but the @Release decorator and this method are meant to simply make that easier.\n\t */\n\tpublic releaseSingletons(): void {\n\t\tthis.providers.forEach((value: Provider) => {\n\t\t\tvalue.releaseIfSingleton();\n\t\t});\n\t}\n\n\t/**\n\t * Make a copy of this @see Container.\n\t * This is an experimental feature!\n\t * I have not thought through all the dark corners, so use at your own peril!\n\t * Here are some notes:\n\t * The injector parameter for SyncFactory and AsyncFactory callbacks will be the Container invoking the factory.\n\t * So a factory that uses a parent closure instead of the supplied injector may get unexpected results.\n\t * The injector parameter for OnSuccess and OnError callbacks will be the Container performing the resolution.\n\t * Singletons are cloned at their *existing* state..\n\t * If resolved in \"this\" container, they will not be re-resolved for the clone.\n\t * If released by the clone, they will be considered released by \"this\" container.\n\t * If a singleton is currently being asynchronously constructed any callbacks will reference \"this\" Container, however both Containers should have no problem awaiting resolution.\n\t * If a singleton is not resolved when the container is cloned, then if both containers resolve, you will create *two* \"singletons\".\n\t * The way to avoid this last effect is to @see resolveSingletons\n\t */\n\tclone(clazz?: ClassConstructor<Container>): Container {\n\t\tif (!clazz)\n\t\t\tclazz = Container;\n\t\tconst retVal = new clazz(this.parent);\n\t\tthis.providers.forEach((v, k) => {\n\t\t\tif (v instanceof BindableProvider) {\n\t\t\t\tv = Object.assign(Object.create(Object.getPrototypeOf(v)), v);\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t(v as any).injector = retVal;\n\t\t\t}\n\t\t\tretVal.providers.set(k, v);\n\t\t});\n\t\treturn retVal;\n\t}\n}\n"]}
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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","sourcesContent":["import {AsyncFactoryBasedProvider} from './async-factory-provider.js';\nimport {BindableProvider} from './bindable-provider.js';\nimport {AsyncFactory, BindAs, Binder, SyncFactory} from './binder.js';\nimport {ClassBasedProvider} from './class-provider.js';\nimport {ConstantProvider} from './constant-provider.js';\nimport {INJECTABLE_METADATA_KEY} from './constants.js';\nimport {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector.js';\nimport {Provider} from './provider.js';\nimport {State} from './state.js';\nimport {FactoryBasedProvider} from './sync-factory-provider.js';\nimport {isPromise} from './utils.js';\n\n/**\n * Helper class to ensure we can distinguish between Error instances legitimately returned from Providers, and Errors thrown by Providers.\n *\n * @see resolveSingletons.\n */\nclass ReasonWrapper {\n\tconstructor(public reason: any) {\n\t}\n}\n\n/**\n * Binder and Injector (aka Container) to handle (a)synchronous dependency management.\n */\nexport class Container implements Binder {\n\n\t/**\n\t * Create a new Container, with an optional parent Injector which will be searched if any given InjectableId is not bound within this Container.\n\t */\n\tpublic constructor(protected parent?: Injector) {\n\t}\n\n\tprotected providers = new Map<InjectableId<any>, Provider>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic isIdKnown<T>(id: InjectableId<T>, ascending?: boolean): boolean {\n\t\tif (!!this.providers.get(id))\n\t\t\treturn true;\n\t\tif (ascending && this.parent)\n\t\t\treturn this.parent.isIdKnown(id, true);\n\t\treturn false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get<T>(id: InjectableId<T>): T {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent)\n\t\t\t\treturn this.parent.get<T>(id);\n\t\t\tthrow new Error('Symbol not bound: ' + id.toString());\n\t\t}\n\t\tconst state = provider.provideAsState();\n\t\tif (state.pending)\n\t\t\tthrow new Error('Synchronous request on unresolved asynchronous dependency tree: ' + id.toString());\n\t\tif (state.rejected)\n\t\t\tthrow state.rejected;\n\t\treturn state.fulfilled as T;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolve<T>(id: InjectableId<T>): Promise<T> {\n\t\tconst state = this.resolveState(id);\n\t\tif (isPromise(state.promise)) {\n\t\t\treturn state.promise;\n\t\t}\n\n\t\tif (state.rejected) {\n\t\t\treturn Promise.reject(state.rejected);\n\t\t}\n\n\t\treturn Promise.resolve(state.fulfilled);\n\t}\n\n\t// noinspection JSUnusedGlobalSymbols\n\t/**\n\t * This method is not part of the Binding interface, because it is highly unusual.\n\t * But that doesn't mean we can't imagine scenarios where you might require it.\n\t *\n\t * @param id The id to be removed.\n\t * @param ascending If true, this will remove all bindings of the specified id all the way up the parent container chain (if it exists).\n\t * @param releaseIfSingleton If true, @Provider.releaseIfSingleton will be invoked before the binding is removed.\n\t */\n\tpublic removeBinding<T>(id: InjectableId<T>, ascending?: boolean, releaseIfSingleton?: boolean): void {\n\t\tif (releaseIfSingleton) {\n\t\t\tconst p = this.providers.get(id);\n\t\t\tif (p)\n\t\t\t\tp.releaseIfSingleton();\n\t\t}\n\t\tthis.providers.delete(id);\n\n\t\tif (ascending && this.parent) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n\t\t\t(this.parent as any)?.removeBinding(id, true, releaseIfSingleton);\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindConstant<T>(id: InjectableId<T>, value: T): T {\n\t\tthis.providers.set(id, new ConstantProvider(value));\n\t\treturn value;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindClass<T>(id: ClassConstructor<T>, constructor?: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | InjectableId<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | ClassConstructor<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>> {\n\t\tif (typeof constructor === 'undefined') {\n\t\t\tconstructor = id as new (...args: any[]) => T;\n\t\t}\n\t\tif (!Reflect.getMetadata(INJECTABLE_METADATA_KEY, constructor)) {\n\t\t\tthrow new Error('Class not decorated with @Injectable [' + constructor.toString() + ']');\n\t\t}\n\t\t/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\t\tconst provider = new ClassBasedProvider(this as any, id, constructor);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindFactory<T>(id: InjectableId<T>, factory: SyncFactory<T>): BindAs<T, SyncFactory<T>> {\n\t\tconst provider = new FactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindAsyncFactory<T>(id: InjectableId<T>, factory: AsyncFactory<T>): BindAs<T, AsyncFactory<T>> {\n\t\tconst provider = new AsyncFactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this> {\n\t\tconst makePromiseToResolve = () => {\n\t\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\t\tconst pending = new Map<InjectableId<any>, Promise<void>>();\n\t\t\t\t// Ask each provider to resolve itself *IF* it is a singleton.\n\t\t\t\tthis.providers.forEach((value: Provider, key: InjectableId<any>) => {\n\t\t\t\t\t// If the provider is a singleton *and* if resolution is being handled asynchronously, the provider will return a completion promise.\n\t\t\t\t\tconst p = value.resolveIfSingleton(asyncOnly);\n\t\t\t\t\tif (p !== null && typeof p !== 'undefined')\n\t\t\t\t\t\tpending.set(key, p);\n\t\t\t\t});\n\t\t\t\t// The contract for this method is that it behaves somewhat like Promise.allSettled (e.g. won't complete until all pending Singletons have settled).\n\t\t\t\t// Further the contract states that if any of the asynchronous Singletons rejected, that we will also return a rejected Promise, and that the rejection reason will be a Map of the InjectableId's that did not resolve, and the Error they emitted.\n\t\t\t\tconst pp = Array.from(pending.values());\n\t\t\t\tconst keys = Array.from(pending.keys());\n\t\t\t\t// Mapping the catch is an alternate version of Promise.allSettled (e.g. keeps Promise.all from short-circuiting).\n\t\t\t\tPromise.all(pp\n\t\t\t\t\t.map(p => p.catch(e => new ReasonWrapper(e))))\n\t\t\t\t\t.then((results) => {\n\t\t\t\t\t\tconst rejects = new Map<InjectableId<any>, Error>();\n\t\t\t\t\t\t// Check the results. Since we don't export ReasonWrapper, it is safe to assume that an instance of that was produced by our map => catch code above, so it's a rejected Singleton error.\n\t\t\t\t\t\tresults.forEach((result, idx) => {\n\t\t\t\t\t\t\tif (result instanceof ReasonWrapper) {\n\t\t\t\t\t\t\t\trejects.set(keys[idx], result.reason);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// If we had rejections, notify our caller what they were.\n\t\t\t\t\t\tif (rejects.size > 0)\n\t\t\t\t\t\t\treject(rejects);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tresolve(); // All good.\n\t\t\t\t\t});\n\t\t\t});\n\t\t};\n\t\tif (parentRecursion && typeof (this.parent as Binder)?.resolveSingletons === 'function') {\n\t\t\tconst pb: Binder = this.parent as Binder;\n\t\t\treturn pb.resolveSingletons(asyncOnly, parentRecursion).then(() => {\n\t\t\t\treturn makePromiseToResolve().then(() => this);\n\t\t\t});\n\t\t}\n\t\treturn makePromiseToResolve().then(() => this);\n\t}\n\n\t/**\n\t * As implied by the name prefix, this is a factored out method invoked only by the 'resolve' method.\n\t * It makes searching our parent (if it exists) easier (and quicker) IF our parent is a fellow instance of Container.\n\t */\n\tprotected resolveState<T>(id: InjectableId<T>): State<T> {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent) {\n\t\t\t\tif (this.parent instanceof Container) {\n\t\t\t\t\treturn this.parent.resolveState<T>(id);\n\t\t\t\t}\n\t\t\t\t// This code (below) will only ever execute if the creator of this container passes in their own implementation of an Injector.\n\t\t\t\t/* istanbul ignore next */\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(this.parent.resolve<T>(id), undefined, undefined);\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\treturn State.MakeState<T>(null, err);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn State.MakeState<T>(null, new Error('Symbol not bound: ' + id.toString()));\n\t\t}\n\t\treturn provider.provideAsState() as State<T>;\n\t}\n\n\t// noinspection JSUnusedGlobalSymbols\n\t/**\n\t * Convenience method to assist in releasing non-garbage-collectable resources that Singletons in this Container may have allocated.\n\t * It will walk through all registered Providers (of this Container only), and invoke their @see Provider.releaseIfSingleton method.\n\t * This method is not part of the Binding interface, because you normally only create (and release) Containers.\n\t * NOTE:\n\t * This *only* releases active/pending Singleton's that have already been created by this Container.\n\t * The most likely use of this method would be when you have created a new child Container for a limited duration transaction, and you want to easily cleanup temporary resources.\n\t * For example, your service object may need to know when it should unsubscribe from an RxJs stream (failure to do so can result in your Singleton not being garbage collected at the end of a transaction).\n\t * In theory, you could handle all unsubscription and cleanup yourself, but the @Release decorator and this method are meant to simply make that easier.\n\t */\n\tpublic releaseSingletons(): void {\n\t\tthis.providers.forEach((value: Provider) => {\n\t\t\tvalue.releaseIfSingleton();\n\t\t});\n\t}\n\n\t/**\n\t * Make a copy of this @see Container.\n\t * This is an experimental feature!\n\t * I have not thought through all the dark corners, so use at your own peril!\n\t * Here are some notes:\n\t * The injector parameter for SyncFactory and AsyncFactory callbacks will be the Container invoking the factory.\n\t * So a factory that uses a parent closure instead of the supplied injector may get unexpected results.\n\t * The injector parameter for OnSuccess and OnError callbacks will be the Container performing the resolution.\n\t * Singletons are cloned at their *existing* state..\n\t * If resolved in \"this\" container, they will not be re-resolved for the clone.\n\t * If released by the clone, they will be considered released by \"this\" container.\n\t * If a singleton is currently being asynchronously constructed any callbacks will reference \"this\" Container, however both Containers should have no problem awaiting resolution.\n\t * If a singleton is not resolved when the container is cloned, then if both containers resolve, you will create *two* \"singletons\".\n\t * The way to avoid this last effect is to @see resolveSingletons\n\t */\n\tclone(clazz?: ClassConstructor<Container>): Container {\n\t\tif (!clazz)\n\t\t\tclazz = Container;\n\t\tconst retVal = new clazz(this.parent);\n\t\tthis.providers.forEach((v, k) => {\n\t\t\tif (v instanceof BindableProvider) {\n\t\t\t\tv = Object.assign(Object.create(Object.getPrototypeOf(v)), v);\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t(v as any).injector = retVal;\n\t\t\t}\n\t\t\tretVal.providers.set(k, v);\n\t\t});\n\t\treturn retVal;\n\t}\n}\n"]}
@@ -72,9 +72,8 @@ export function Inject(id) {
72
72
  * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.
73
73
  */
74
74
  return function (target, parameterName, parameterIndex) {
75
- const hint = targetHint(target);
76
75
  if (id === undefined) {
77
- throw new Error('Undefined id passed to @Inject [' + hint + ']');
76
+ throw new Error('Undefined id passed to @Inject [' + targetHint(target) + ']');
78
77
  }
79
78
  const paramKey = validateSingleConstructorParam('Inject', target, parameterIndex);
80
79
  Reflect.defineMetadata(INJECT_METADATA_KEY, id, target, paramKey);
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\n/**\n * These decorators all apply the information they collect (whether class, method, or parameter data) as tagged metadata on the class's constructor\n */\nimport {INJECT_METADATA_KEY, INJECTABLE_METADATA_KEY, OPTIONAL_METADATA_KEY, POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_RETURN, RELEASE_METADATA_KEY} from './constants.js';\nimport {InjectableId} from './injector.js';\n\n// Help user locate misapplied decorators.\nfunction targetHint(target: Function) {\n\tlet hint: string | undefined;\n\tif (target) {\n\t\thint = target.name;\n\t\tif ((!hint) && target.constructor) {\n\t\t\thint = target.constructor.name;\n\t\t}\n\t}\n\treturn hint;\n}\n\n// Validate that 'target' is a class constructor function.\nfunction isClassConstructor(target: any) {\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n\tif (typeof target === 'function' && target.hasOwnProperty('prototype')) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\treturn target.prototype.constructor === target;\n\t}\n\treturn false;\n}\n\n// Ensure consistency in our meta-data name getting/setting.\nfunction makeParamIdxKey(idx: number): string {\n\treturn `index-${idx}`;\n}\n\n// Validate that the specified target is a parameter of a class constructor\nfunction validateConstructorParam(decorator: string, target: Function, idx: number): string {\n\tif (!isClassConstructor(target)) {\n\t\tthrow new Error('@' + decorator + ' is not valid here [' + targetHint(target) + ']');\n\t}\n\treturn makeParamIdxKey(idx);\n}\n\n// Validate the decorator was only applied once.\nfunction validateSingleConstructorParam(decorator: string, target: Function, idx: number): string {\n\tconst propKey = validateConstructorParam(decorator, target, idx);\n\tif (Reflect.hasOwnMetadata(decorator, target, propKey)) {\n\t\tthrow new Error('@' + decorator + ' applied multiple times [' + target.constructor.name + ']');\n\t}\n\treturn propKey;\n}\n\n/**\n * Placed just before the class declaration, this class decorator applies metadata to the class constructor indicating that the user intends to bind the class into the container.\n * This decorator will throw if not placed on a class declaration, or if placed more than once on a class declaration.\n */\nexport function Injectable(): ClassDecorator {\n\t/**\n\t * @param target The constructor function of the class that is being decorated\n\t * @returns Undefined (nothing), as this decorator does not modify the constructor in any way.\n\t */\n\treturn function (target: Function): void {\n\t\tif (Reflect.hasOwnMetadata(INJECTABLE_METADATA_KEY, target)) {\n\t\t\tthrow new Error('@Injectable applied multiple times [' + targetHint(target) + ']');\n\t\t}\n\t\tReflect.defineMetadata(INJECTABLE_METADATA_KEY, true, target);\n\t};\n}\n\n/**\n * Placed just before a constructor parameter, this parameter decorator allows for specificity and control over the type of the type of Object that will be injected into the parameter.\n * In the absence of this decorator the container will use whatever is bound to a parameter's type (or throw an error if it is unable to recognize the type).\n *\n * @param id The identifier of the bound type that should be injected.\n */\nexport function Inject(id: InjectableId<any>): ParameterDecorator {\n\t/**\n\t * @param target The constructor function of the class (we don't allow @Inject on anything else).\n\t * @param parameterName The name of the parameter\n\t * @param parameterIndex The ordinal index of the parameter in the function’s parameter list\n\t * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.\n\t */\n\treturn function (target: Function, parameterName: string | symbol, parameterIndex: number): void {\n\t\tconst hint = targetHint(target);\n\t\tif (id === undefined) {\n\t\t\tthrow new Error('Undefined id passed to @Inject [' + hint + ']');\n\t\t}\n\t\tconst paramKey = validateSingleConstructorParam('Inject', target, parameterIndex);\n\t\tReflect.defineMetadata(INJECT_METADATA_KEY, id, target, paramKey);\n\t};\n}\n\n/**\n * This is a helper function used by the container to retrieve the @Inject metadata for a specifically indexed constructor parameter\n *\n * @param target The constructor function of the class (we don't allow @Inject on anything else).\n * @param parameterIndex The ordinal index of the parameter in the constructor’s parameter list\n * @see Inject\n */\nexport function _getInjectedIdAt(target: Function, parameterIndex: number): InjectableId<any> {\n\treturn Reflect.getMetadata(INJECT_METADATA_KEY, target, makeParamIdxKey(parameterIndex)) as InjectableId<any>;\n}\n\n/**\n * Placed just before a constructor parameter, this parameter decorator signals the container that it should supply the 'alt' constant value (undefined by default) if for *any* reason it is unable to otherwise resolve the type of the parameter.\n * WARNING! It is your responsibility to ensure that alt is of the appropriate type/value.\n */\nexport function Optional(alt?: any): ParameterDecorator { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types\n\t/**\n\t * @param target The constructor function of the class (we don't allow @Optional on anything else).\n\t * @param parameterName The name of the parameter\n\t * @param parameterIndex The ordinal index of the parameter in the function’s parameter list\n\t * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.\n\t */\n\treturn function (target: Function, parameterName: string | symbol, parameterIndex: number): void {\n\t\tconst paramKey = validateSingleConstructorParam('Optional', target, parameterIndex);\n\t\tReflect.defineMetadata(OPTIONAL_METADATA_KEY, {value: alt}, target, paramKey);\n\t};\n}\n\n/**\n * This is a helper function used by the container to retrieve the @Optional metadata for a specifically indexed constructor parameter\n *\n * @param target The constructor function of the class (we don't allow @Optional on anything else).\n * @param parameterIndex The ordinal index of the parameter in the constructor’s parameter list\n * @see Optional\n * @returns an object containing the value provided in the decorator, or undefined if no annotation was present.\n */\nexport function _getOptionalDefaultAt(target: Function, parameterIndex: number): { value: any } {\n\treturn Reflect.getMetadata(OPTIONAL_METADATA_KEY, target, makeParamIdxKey(parameterIndex)) as { value: any }; // See the @Optional decorator before making any changes here.\n}\n\n/**\n * Placed just before a class method, this method decorator flags a method that should be called after an object has been instantiated by the container, but before it is put into service.\n * The method will be assumed to be synchronous unless the method signature explicitly declares it's return type to be \": Promise<something>\"\n * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.\n */\nexport function PostConstruct(): MethodDecorator {\n\t/**\n\t * @param prototypeOrConstructor The prototype of the class (we don't allow @PostConstruct on anything other than a class instance method.\n\t * @param methodName The name of the method.\n\t * @param descriptor The Property Descriptor for the method.\n\t * @returns Undefined (nothing), as this decorator does not modify the method in any way.\n\t */\n\t// noinspection JSUnusedLocalSymbols\n\treturn function (target: Object, methodName: string | symbol, descriptor: PropertyDescriptor) { // eslint-disable-line @typescript-eslint/no-unused-vars\n\t\tif (typeof target !== 'object' || typeof target.constructor !== 'function') {\n\t\t\tthrow new Error('@PostConstruct not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');\n\t\t}\n\t\tif (Reflect.hasOwnMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, target.constructor) || Reflect.hasOwnMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, target.constructor)) {\n\t\t\tthrow new Error('@PostConstruct applied multiple times [' + targetHint(target.constructor) + ']');\n\t\t}\n\t\tconst rt = Reflect.getMetadata(REFLECT_RETURN, target, methodName);\n\t\tif (typeof rt === 'function') {\n\t\t\tReflect.defineMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, methodName, target.constructor);\n\t\t}\n\t\telse {\n\t\t\tReflect.defineMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, methodName, target.constructor);\n\t\t}\n\t};\n}\n\n// noinspection JSUnusedGlobalSymbols\n/**\n * Placed just before a class method, this decorator identifies a method which should be called when an object is removed from service.\n * If invoked by the container, the container will drop any references it has to the object when the method returns.\n * Note that this decorator is *not* a guarantee (or even an implication) that the decorated method will be called (JavaScript has no mechanism to enforce such a contract).\n * This decorator simply serves as a flag to indicate a method which is intended to clean up resources allocated by the object *which would not otherwise be garbage collected*.\n * You should *not* use this decorator as a general \"object finalization\" method. It has very limited scope and purpose.\n * The decorated method must complete normally (no throwing), as \"release\" is not an abort-able process.\n * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.\n * The @see InvokeReleaseMethod helper function can search for and invoke the @Release decorated method of an object.\n * Also @see Container.releaseSingletons for the intended usage of this decorator.\n * It is intended that after the @Release decorated method of an object is called, that object will not be used again, but this is of course not enforced).\n */\nexport function Release(): MethodDecorator {\n\t/**\n\t * @param prototypeOrConstructor The prototype of the class (we don't allow @Release on anything other than a class instance method.\n\t * @param methodName The name of the method.\n\t * @param descriptor The Property Descriptor for the method.\n\t * @returns Undefined (nothing), as this decorator does not modify the method in any way.\n\t */\n\t// noinspection JSUnusedLocalSymbols\n\treturn function (target: Object, methodName: string | symbol, descriptor: PropertyDescriptor) { // eslint-disable-line @typescript-eslint/no-unused-vars\n\t\tif (typeof target !== 'object' || typeof target.constructor !== 'function') {\n\t\t\tthrow new Error('@Release not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');\n\t\t}\n\t\tif (Reflect.hasOwnMetadata(RELEASE_METADATA_KEY, target.constructor)) {\n\t\t\tthrow new Error('@Release applied multiple times [' + targetHint(target.constructor) + ']');\n\t\t}\n\t\tReflect.defineMetadata(RELEASE_METADATA_KEY, methodName, target.constructor);\n\t};\n}\n"]}
1
+ {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\n/**\n * These decorators all apply the information they collect (whether class, method, or parameter data) as tagged metadata on the class's constructor\n */\nimport {INJECT_METADATA_KEY, INJECTABLE_METADATA_KEY, OPTIONAL_METADATA_KEY, POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_RETURN, RELEASE_METADATA_KEY} from './constants.js';\nimport {InjectableId} from './injector.js';\n\n// Help user locate misapplied decorators.\nfunction targetHint(target: Function) {\n\tlet hint: string | undefined;\n\tif (target) {\n\t\thint = target.name;\n\t\tif ((!hint) && target.constructor) {\n\t\t\thint = target.constructor.name;\n\t\t}\n\t}\n\treturn hint;\n}\n\n// Validate that 'target' is a class constructor function.\nfunction isClassConstructor(target: any) {\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n\tif (typeof target === 'function' && target.hasOwnProperty('prototype')) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\treturn target.prototype.constructor === target;\n\t}\n\treturn false;\n}\n\n// Ensure consistency in our meta-data name getting/setting.\nfunction makeParamIdxKey(idx: number): string {\n\treturn `index-${idx}`;\n}\n\n// Validate that the specified target is a parameter of a class constructor\nfunction validateConstructorParam(decorator: string, target: Function, idx: number): string {\n\tif (!isClassConstructor(target)) {\n\t\tthrow new Error('@' + decorator + ' is not valid here [' + targetHint(target) + ']');\n\t}\n\treturn makeParamIdxKey(idx);\n}\n\n// Validate the decorator was only applied once.\nfunction validateSingleConstructorParam(decorator: string, target: Function, idx: number): string {\n\tconst propKey = validateConstructorParam(decorator, target, idx);\n\tif (Reflect.hasOwnMetadata(decorator, target, propKey)) {\n\t\tthrow new Error('@' + decorator + ' applied multiple times [' + target.constructor.name + ']');\n\t}\n\treturn propKey;\n}\n\n/**\n * Placed just before the class declaration, this class decorator applies metadata to the class constructor indicating that the user intends to bind the class into the container.\n * This decorator will throw if not placed on a class declaration, or if placed more than once on a class declaration.\n */\nexport function Injectable(): ClassDecorator {\n\t/**\n\t * @param target The constructor function of the class that is being decorated\n\t * @returns Undefined (nothing), as this decorator does not modify the constructor in any way.\n\t */\n\treturn function (target: Function): void {\n\t\tif (Reflect.hasOwnMetadata(INJECTABLE_METADATA_KEY, target)) {\n\t\t\tthrow new Error('@Injectable applied multiple times [' + targetHint(target) + ']');\n\t\t}\n\t\tReflect.defineMetadata(INJECTABLE_METADATA_KEY, true, target);\n\t};\n}\n\n/**\n * Placed just before a constructor parameter, this parameter decorator allows for specificity and control over the type of the type of Object that will be injected into the parameter.\n * In the absence of this decorator the container will use whatever is bound to a parameter's type (or throw an error if it is unable to recognize the type).\n *\n * @param id The identifier of the bound type that should be injected.\n */\nexport function Inject(id: InjectableId<any>): ParameterDecorator {\n\t/**\n\t * @param target The constructor function of the class (we don't allow @Inject on anything else).\n\t * @param parameterName The name of the parameter\n\t * @param parameterIndex The ordinal index of the parameter in the function’s parameter list\n\t * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.\n\t */\n\treturn function (target: Function, parameterName: string | symbol, parameterIndex: number): void {\n\t\tif (id === undefined) {\n\t\t\tthrow new Error('Undefined id passed to @Inject [' + targetHint(target) + ']');\n\t\t}\n\t\tconst paramKey = validateSingleConstructorParam('Inject', target, parameterIndex);\n\t\tReflect.defineMetadata(INJECT_METADATA_KEY, id, target, paramKey);\n\t};\n}\n\n/**\n * This is a helper function used by the container to retrieve the @Inject metadata for a specifically indexed constructor parameter\n *\n * @param target The constructor function of the class (we don't allow @Inject on anything else).\n * @param parameterIndex The ordinal index of the parameter in the constructor’s parameter list\n * @see Inject\n */\nexport function _getInjectedIdAt(target: Function, parameterIndex: number): InjectableId<any> {\n\treturn Reflect.getMetadata(INJECT_METADATA_KEY, target, makeParamIdxKey(parameterIndex)) as InjectableId<any>;\n}\n\n/**\n * Placed just before a constructor parameter, this parameter decorator signals the container that it should supply the 'alt' constant value (undefined by default) if for *any* reason it is unable to otherwise resolve the type of the parameter.\n * WARNING! It is your responsibility to ensure that alt is of the appropriate type/value.\n */\nexport function Optional(alt?: any): ParameterDecorator { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types\n\t/**\n\t * @param target The constructor function of the class (we don't allow @Optional on anything else).\n\t * @param parameterName The name of the parameter\n\t * @param parameterIndex The ordinal index of the parameter in the function’s parameter list\n\t * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.\n\t */\n\treturn function (target: Function, parameterName: string | symbol, parameterIndex: number): void {\n\t\tconst paramKey = validateSingleConstructorParam('Optional', target, parameterIndex);\n\t\tReflect.defineMetadata(OPTIONAL_METADATA_KEY, {value: alt}, target, paramKey);\n\t};\n}\n\n/**\n * This is a helper function used by the container to retrieve the @Optional metadata for a specifically indexed constructor parameter\n *\n * @param target The constructor function of the class (we don't allow @Optional on anything else).\n * @param parameterIndex The ordinal index of the parameter in the constructor’s parameter list\n * @see Optional\n * @returns an object containing the value provided in the decorator, or undefined if no annotation was present.\n */\nexport function _getOptionalDefaultAt(target: Function, parameterIndex: number): { value: any } {\n\treturn Reflect.getMetadata(OPTIONAL_METADATA_KEY, target, makeParamIdxKey(parameterIndex)) as { value: any }; // See the @Optional decorator before making any changes here.\n}\n\n/**\n * Placed just before a class method, this method decorator flags a method that should be called after an object has been instantiated by the container, but before it is put into service.\n * The method will be assumed to be synchronous unless the method signature explicitly declares it's return type to be \": Promise<something>\"\n * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.\n */\nexport function PostConstruct(): MethodDecorator {\n\t/**\n\t * @param prototypeOrConstructor The prototype of the class (we don't allow @PostConstruct on anything other than a class instance method.\n\t * @param methodName The name of the method.\n\t * @param descriptor The Property Descriptor for the method.\n\t * @returns Undefined (nothing), as this decorator does not modify the method in any way.\n\t */\n\t// noinspection JSUnusedLocalSymbols\n\treturn function (target: Object, methodName: string | symbol, descriptor: PropertyDescriptor) { // eslint-disable-line @typescript-eslint/no-unused-vars\n\t\tif (typeof target !== 'object' || typeof target.constructor !== 'function') {\n\t\t\tthrow new Error('@PostConstruct not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');\n\t\t}\n\t\tif (Reflect.hasOwnMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, target.constructor) || Reflect.hasOwnMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, target.constructor)) {\n\t\t\tthrow new Error('@PostConstruct applied multiple times [' + targetHint(target.constructor) + ']');\n\t\t}\n\t\tconst rt = Reflect.getMetadata(REFLECT_RETURN, target, methodName);\n\t\tif (typeof rt === 'function') {\n\t\t\tReflect.defineMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, methodName, target.constructor);\n\t\t}\n\t\telse {\n\t\t\tReflect.defineMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, methodName, target.constructor);\n\t\t}\n\t};\n}\n\n// noinspection JSUnusedGlobalSymbols\n/**\n * Placed just before a class method, this decorator identifies a method which should be called when an object is removed from service.\n * If invoked by the container, the container will drop any references it has to the object when the method returns.\n * Note that this decorator is *not* a guarantee (or even an implication) that the decorated method will be called (JavaScript has no mechanism to enforce such a contract).\n * This decorator simply serves as a flag to indicate a method which is intended to clean up resources allocated by the object *which would not otherwise be garbage collected*.\n * You should *not* use this decorator as a general \"object finalization\" method. It has very limited scope and purpose.\n * The decorated method must complete normally (no throwing), as \"release\" is not an abort-able process.\n * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.\n * The @see InvokeReleaseMethod helper function can search for and invoke the @Release decorated method of an object.\n * Also @see Container.releaseSingletons for the intended usage of this decorator.\n * It is intended that after the @Release decorated method of an object is called, that object will not be used again, but this is of course not enforced).\n */\nexport function Release(): MethodDecorator {\n\t/**\n\t * @param prototypeOrConstructor The prototype of the class (we don't allow @Release on anything other than a class instance method.\n\t * @param methodName The name of the method.\n\t * @param descriptor The Property Descriptor for the method.\n\t * @returns Undefined (nothing), as this decorator does not modify the method in any way.\n\t */\n\t// noinspection JSUnusedLocalSymbols\n\treturn function (target: Object, methodName: string | symbol, descriptor: PropertyDescriptor) { // eslint-disable-line @typescript-eslint/no-unused-vars\n\t\tif (typeof target !== 'object' || typeof target.constructor !== 'function') {\n\t\t\tthrow new Error('@Release not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');\n\t\t}\n\t\tif (Reflect.hasOwnMetadata(RELEASE_METADATA_KEY, target.constructor)) {\n\t\t\tthrow new Error('@Release applied multiple times [' + targetHint(target.constructor) + ']');\n\t\t}\n\t\tReflect.defineMetadata(RELEASE_METADATA_KEY, methodName, target.constructor);\n\t};\n}\n"]}
@@ -1,4 +1,4 @@
1
- export { Binder } from './binder.js';
1
+ export { Binder, SyncFactory, AsyncFactory, BindAs } from './binder.js';
2
2
  export { Container } from './container.js';
3
3
  export { Inject, Injectable, Optional, PostConstruct, Release } from './decorators.js';
4
4
  export { ClassConstructor, InjectableId, InjectionToken, Injector } from './injector.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAC,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAiC,cAAc,EAAW,MAAM,eAAe,CAAC","sourcesContent":["export {Binder} from './binder.js';\nexport {Container} from './container.js';\nexport {Inject, Injectable, Optional, PostConstruct, Release} from './decorators.js';\nexport {ClassConstructor, InjectableId, InjectionToken, Injector} from './injector.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAC,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAiC,cAAc,EAAW,MAAM,eAAe,CAAC","sourcesContent":["export {Binder, SyncFactory, AsyncFactory, BindAs} from './binder.js';\nexport {Container} from './container.js';\nexport {Inject, Injectable, Optional, PostConstruct, Release} from './decorators.js';\nexport {ClassConstructor, InjectableId, InjectionToken, Injector} from './injector.js';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "async-injection",
3
- "version": "1.5.3",
3
+ "version": "1.5.5",
4
4
  "description": "A robust lightweight dependency injection library for TypeScript.",
5
5
  "author": "Frank Stock",
6
6
  "license": "MIT",
@@ -51,22 +51,22 @@
51
51
  },
52
52
  "devDependencies": {
53
53
  "@istanbuljs/nyc-config-typescript": "~1.0.2",
54
- "@types/jasmine": "~4.3.2",
55
- "@typescript-eslint/eslint-plugin": "~5.48.2",
56
- "@typescript-eslint/parser": "~5.48.2",
57
- "eslint": "~8.32.0",
58
- "eslint-plugin-import": "~2.27.5",
59
- "eslint-plugin-jsdoc": "~39.6.10",
54
+ "@types/jasmine": "~5.1.4",
55
+ "@typescript-eslint/eslint-plugin": "~5.62.0",
56
+ "@typescript-eslint/parser": "~5.62.0",
57
+ "eslint": "~8.53.0",
58
+ "eslint-plugin-import": "~2.29.1",
59
+ "eslint-plugin-jsdoc": "~39.9.1",
60
60
  "eslint-plugin-prefer-arrow": "~1.2.3",
61
- "jasmine": "~4.5.0",
61
+ "jasmine": "~5.1.0",
62
62
  "jasmine-console-reporter": "~3.1.0",
63
63
  "nyc": "~15.1.0",
64
- "reflect-metadata": "~0.1.13",
65
- "rimraf": "~4.4.1",
64
+ "reflect-metadata": "~0.1.14",
65
+ "rimraf": "~5.0.5",
66
66
  "source-map-support": "~0.5.21",
67
- "ts-node": "~10.9.1",
67
+ "ts-node": "~10.9.2",
68
68
  "tsconfig-paths": "~4.2.0",
69
- "tslib": "~2.4.1",
69
+ "tslib": "~2.6.2",
70
70
  "typescript": "~4.9.5"
71
71
  },
72
72
  "nyc": {