async-injection 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Changelog.md +4 -0
- package/lib/cjs/class-provider.js +27 -15
- package/lib/cjs/class-provider.js.map +1 -1
- package/lib/esm/class-provider.js +27 -15
- package/lib/esm/class-provider.js.map +1 -1
- package/package.json +2 -2
package/Changelog.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
## 2.0.2 / 2025-03-13
|
|
2
|
+
* Fix failure to use `@Optional` when async object construction fails [#19](https://github.com/pcafstockf/async-injection/issues/19).
|
|
3
|
+
Thanks to [@dmtaub](https://github.com/pcafstockf/async-injection/issues/19) for finding this and providing a reproducible unit test.
|
|
4
|
+
|
|
1
5
|
## 2.0.1 / 2024-09-11
|
|
2
6
|
* Fix package.json exports [#18](https://github.com/pcafstockf/async-injection/issues/18).
|
|
3
7
|
* Thanks to [@IvanLi-CN](https://github.com/pcafstockf/async-injection/issues/18) for finding this, and the solution.
|
|
@@ -127,24 +127,36 @@ class ClassBasedProvider extends bindable_provider_js_1.BindableProvider {
|
|
|
127
127
|
provideAsStateImpl() {
|
|
128
128
|
const params = this.getConstructorParameterStates();
|
|
129
129
|
// If any of the params are in a rejected state, we cannot construct.
|
|
130
|
-
const
|
|
130
|
+
const firstRejectedParam = params.find((p) => {
|
|
131
131
|
return (!p.pending) && p.rejected;
|
|
132
132
|
});
|
|
133
|
-
if (
|
|
134
|
-
return
|
|
135
|
-
|
|
136
|
-
// If any of the params are in a pending state, we will have to wait for them to be resolved before we can construct.
|
|
137
|
-
const pendingParams = params.filter((p) => {
|
|
138
|
-
return p.pending;
|
|
139
|
-
}).map((p) => {
|
|
140
|
-
return p.promise;
|
|
141
|
-
});
|
|
142
|
-
if (pendingParams.length > 0) {
|
|
133
|
+
if (firstRejectedParam)
|
|
134
|
+
return firstRejectedParam;
|
|
135
|
+
if (params.some(p => p.pending)) {
|
|
143
136
|
// Some of the parameters needed for construction are not yet available, wait for them and then attempt construction.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
137
|
+
// We do this by mapping each param to a Promise (pending or not), and then awaiting them all.
|
|
138
|
+
// This might create some unnecessary (but immediately resolved) Promise objects,
|
|
139
|
+
// BUT, it allows us to chain for failure *and* substitute the Optional (if one exists).
|
|
140
|
+
const objPromise = this.makePromiseForObj(Promise.all(params.map((p, idx) => {
|
|
141
|
+
if (p.pending) {
|
|
142
|
+
return p.promise.catch(err => {
|
|
143
|
+
// This was a promised param that failed to resolve.
|
|
144
|
+
// If there is an Optional decorator, use that, otherwise, failure is failure.
|
|
145
|
+
const md = (0, decorators_js_1._getOptionalDefaultAt)(this.maker, idx);
|
|
146
|
+
if (!md)
|
|
147
|
+
throw err;
|
|
148
|
+
return md.value;
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (p.rejected)
|
|
152
|
+
return Promise.reject(p.rejected);
|
|
153
|
+
return Promise.resolve(p.fulfilled);
|
|
154
|
+
})), (values) => {
|
|
155
|
+
if (values) {
|
|
156
|
+
// All the parameters are now available, instantiate the class.
|
|
157
|
+
// If this throws, it will be handled by our caller.
|
|
158
|
+
return Reflect.construct(this.maker, values);
|
|
159
|
+
}
|
|
148
160
|
});
|
|
149
161
|
// Once the obj is resolved, then we need to check for PostConstruct and if it was async, wait for that too.
|
|
150
162
|
return state_js_1.State.MakeState(objPromise.then((obj) => {
|
|
@@ -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 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"]}
|
|
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 firstRejectedParam = params.find((p) => {\n\t\t\treturn (!p.pending) && p.rejected;\n\t\t});\n\t\tif (firstRejectedParam)\n\t\t\treturn firstRejectedParam as State<T>;\n\t\tif (params.some(p => p.pending)) {\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\t// We do this by mapping each param to a Promise (pending or not), and then awaiting them all.\n\t\t\t// This might create some unnecessary (but immediately resolved) Promise objects,\n\t\t\t// BUT, it allows us to chain for failure *and* substitute the Optional (if one exists).\n\t\t\tconst objPromise = this.makePromiseForObj<any[]>(Promise.all(params.map((p, idx) => {\n\t\t\t\tif (p.pending) {\n\t\t\t\t\treturn p.promise.catch(err => {\n\t\t\t\t\t\t// This was a promised param that failed to resolve.\n\t\t\t\t\t\t// If there is an Optional decorator, use that, otherwise, failure is failure.\n\t\t\t\t\t\tconst md = _getOptionalDefaultAt(this.maker, idx);\n\t\t\t\t\t\tif (!md)\n\t\t\t\t\t\t\tthrow err;\n\t\t\t\t\t\treturn md.value as unknown;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (p.rejected)\n\t\t\t\t\treturn Promise.reject(p.rejected);\n\t\t\t\treturn Promise.resolve(p.fulfilled);\n\t\t\t})), (values) => {\n\t\t\t\tif (values) {\n\t\t\t\t\t// All the parameters are now available, instantiate the class.\n\t\t\t\t\t// If this throws, it will be handled by our caller.\n\t\t\t\t\treturn Reflect.construct(this.maker, values);\n\t\t\t\t}\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"]}
|
|
@@ -124,24 +124,36 @@ export class ClassBasedProvider extends BindableProvider {
|
|
|
124
124
|
provideAsStateImpl() {
|
|
125
125
|
const params = this.getConstructorParameterStates();
|
|
126
126
|
// If any of the params are in a rejected state, we cannot construct.
|
|
127
|
-
const
|
|
127
|
+
const firstRejectedParam = params.find((p) => {
|
|
128
128
|
return (!p.pending) && p.rejected;
|
|
129
129
|
});
|
|
130
|
-
if (
|
|
131
|
-
return
|
|
132
|
-
|
|
133
|
-
// If any of the params are in a pending state, we will have to wait for them to be resolved before we can construct.
|
|
134
|
-
const pendingParams = params.filter((p) => {
|
|
135
|
-
return p.pending;
|
|
136
|
-
}).map((p) => {
|
|
137
|
-
return p.promise;
|
|
138
|
-
});
|
|
139
|
-
if (pendingParams.length > 0) {
|
|
130
|
+
if (firstRejectedParam)
|
|
131
|
+
return firstRejectedParam;
|
|
132
|
+
if (params.some(p => p.pending)) {
|
|
140
133
|
// Some of the parameters needed for construction are not yet available, wait for them and then attempt construction.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
134
|
+
// We do this by mapping each param to a Promise (pending or not), and then awaiting them all.
|
|
135
|
+
// This might create some unnecessary (but immediately resolved) Promise objects,
|
|
136
|
+
// BUT, it allows us to chain for failure *and* substitute the Optional (if one exists).
|
|
137
|
+
const objPromise = this.makePromiseForObj(Promise.all(params.map((p, idx) => {
|
|
138
|
+
if (p.pending) {
|
|
139
|
+
return p.promise.catch(err => {
|
|
140
|
+
// This was a promised param that failed to resolve.
|
|
141
|
+
// If there is an Optional decorator, use that, otherwise, failure is failure.
|
|
142
|
+
const md = _getOptionalDefaultAt(this.maker, idx);
|
|
143
|
+
if (!md)
|
|
144
|
+
throw err;
|
|
145
|
+
return md.value;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
if (p.rejected)
|
|
149
|
+
return Promise.reject(p.rejected);
|
|
150
|
+
return Promise.resolve(p.fulfilled);
|
|
151
|
+
})), (values) => {
|
|
152
|
+
if (values) {
|
|
153
|
+
// All the parameters are now available, instantiate the class.
|
|
154
|
+
// If this throws, it will be handled by our caller.
|
|
155
|
+
return Reflect.construct(this.maker, values);
|
|
156
|
+
}
|
|
145
157
|
});
|
|
146
158
|
// Once the obj is resolved, then we need to check for PostConstruct and if it was async, wait for that too.
|
|
147
159
|
return State.MakeState(objPromise.then((obj) => {
|
|
@@ -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 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"]}
|
|
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 firstRejectedParam = params.find((p) => {\n\t\t\treturn (!p.pending) && p.rejected;\n\t\t});\n\t\tif (firstRejectedParam)\n\t\t\treturn firstRejectedParam as State<T>;\n\t\tif (params.some(p => p.pending)) {\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\t// We do this by mapping each param to a Promise (pending or not), and then awaiting them all.\n\t\t\t// This might create some unnecessary (but immediately resolved) Promise objects,\n\t\t\t// BUT, it allows us to chain for failure *and* substitute the Optional (if one exists).\n\t\t\tconst objPromise = this.makePromiseForObj<any[]>(Promise.all(params.map((p, idx) => {\n\t\t\t\tif (p.pending) {\n\t\t\t\t\treturn p.promise.catch(err => {\n\t\t\t\t\t\t// This was a promised param that failed to resolve.\n\t\t\t\t\t\t// If there is an Optional decorator, use that, otherwise, failure is failure.\n\t\t\t\t\t\tconst md = _getOptionalDefaultAt(this.maker, idx);\n\t\t\t\t\t\tif (!md)\n\t\t\t\t\t\t\tthrow err;\n\t\t\t\t\t\treturn md.value as unknown;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (p.rejected)\n\t\t\t\t\treturn Promise.reject(p.rejected);\n\t\t\t\treturn Promise.resolve(p.fulfilled);\n\t\t\t})), (values) => {\n\t\t\t\tif (values) {\n\t\t\t\t\t// All the parameters are now available, instantiate the class.\n\t\t\t\t\t// If this throws, it will be handled by our caller.\n\t\t\t\t\treturn Reflect.construct(this.maker, values);\n\t\t\t\t}\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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "async-injection",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "A robust lightweight dependency injection library for TypeScript.",
|
|
5
5
|
"author": "Frank Stock",
|
|
6
6
|
"license": "MIT",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@istanbuljs/nyc-config-typescript": "~1.0.2",
|
|
60
|
-
"@types/jasmine": "~5.1.
|
|
60
|
+
"@types/jasmine": "~5.1.7",
|
|
61
61
|
"@typescript-eslint/eslint-plugin": "~5.62.0",
|
|
62
62
|
"@typescript-eslint/parser": "~5.62.0",
|
|
63
63
|
"eslint": "~8.57.0",
|