async-injection 2.1.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ReadMe.md +1 -0
- package/lib/async-factory-provider.d.ts +4 -4
- package/lib/bindable-provider.d.ts +3 -3
- package/lib/binder.d.ts +6 -2
- package/lib/cjs/async-factory-provider.js +5 -5
- package/lib/cjs/async-factory-provider.js.map +1 -1
- package/lib/cjs/bindable-provider.js +33 -33
- package/lib/cjs/bindable-provider.js.map +1 -1
- package/lib/cjs/binder.js.map +1 -1
- package/lib/cjs/class-provider.js +36 -37
- package/lib/cjs/class-provider.js.map +1 -1
- package/lib/cjs/constant-provider.js +4 -4
- package/lib/cjs/constant-provider.js.map +1 -1
- package/lib/cjs/container.js +33 -23
- package/lib/cjs/container.js.map +1 -1
- package/lib/cjs/decorators.js +21 -25
- package/lib/cjs/decorators.js.map +1 -1
- package/lib/cjs/index.js +10 -10
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/injector.js +5 -5
- package/lib/cjs/injector.js.map +1 -1
- package/lib/cjs/provider.js +25 -11
- package/lib/cjs/provider.js.map +1 -1
- package/lib/cjs/state.js +2 -2
- package/lib/cjs/state.js.map +1 -1
- package/lib/cjs/sync-factory-provider.js +7 -7
- package/lib/cjs/sync-factory-provider.js.map +1 -1
- package/lib/cjs/utils.js +10 -13
- package/lib/cjs/utils.js.map +1 -1
- package/lib/class-provider.d.ts +4 -4
- package/lib/constant-provider.d.ts +2 -2
- package/lib/container.d.ts +15 -6
- package/lib/decorators.d.ts +1 -1
- package/lib/esm/async-factory-provider.js +1 -1
- package/lib/esm/async-factory-provider.js.map +1 -1
- package/lib/esm/bindable-provider.js +29 -29
- package/lib/esm/bindable-provider.js.map +1 -1
- package/lib/esm/binder.js.map +1 -1
- package/lib/esm/class-provider.js +17 -18
- package/lib/esm/class-provider.js.map +1 -1
- package/lib/esm/constant-provider.js.map +1 -1
- package/lib/esm/container.js +15 -5
- package/lib/esm/container.js.map +1 -1
- package/lib/esm/decorators.js +1 -4
- package/lib/esm/decorators.js.map +1 -1
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/injector.js +5 -5
- package/lib/esm/injector.js.map +1 -1
- package/lib/esm/provider.js +23 -9
- package/lib/esm/provider.js.map +1 -1
- package/lib/esm/state.js.map +1 -1
- package/lib/esm/sync-factory-provider.js +1 -1
- package/lib/esm/sync-factory-provider.js.map +1 -1
- package/lib/esm/utils.js +6 -8
- package/lib/esm/utils.js.map +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/provider.d.ts +9 -5
- package/lib/state.d.ts +3 -3
- package/lib/sync-factory-provider.d.ts +5 -5
- package/package.json +8 -19
package/lib/cjs/state.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.State = void 0;
|
|
4
|
-
const
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
5
|
/**
|
|
6
6
|
* Internal class that allows us to track the state of a promise (chain).
|
|
7
7
|
*/
|
|
8
8
|
class State {
|
|
9
9
|
static MakeState(promise, rejected, fulfilled) {
|
|
10
10
|
const retVal = new State();
|
|
11
|
-
if ((0,
|
|
11
|
+
if ((0, utils_1.isPromise)(promise)) {
|
|
12
12
|
retVal._pending = true;
|
|
13
13
|
retVal._promise = promise.then((v) => {
|
|
14
14
|
retVal._fulfilled = v;
|
package/lib/cjs/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/state.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/state.ts"],"names":[],"mappings":";;;AAAA,mCAAkC;AAElC;;GAEG;AACH,MAAa,KAAK;IACjB,MAAM,CAAC,SAAS,CAAe,OAA+B,EAAE,QAAkB,EAAE,SAAkB;QACrG,MAAM,MAAM,GAAG,IAAI,KAAK,EAAU,CAAC;QACnC,IAAI,IAAA,iBAAS,EAAC,OAAO,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;YACvB,MAAM,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAC7B,CAAC,CAAC,EAAE,EAAE;gBACL,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC;gBACtB,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;gBACxB,OAAO,CAAC,CAAC;YACV,CAAC,EACD,CAAC,CAAM,EAAE,EAAE;gBACV,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC;gBACrB,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;gBACxB,MAAM,CAAC,CAAC;YACT,CAAC,CACD,CAAC;QACH,CAAC;aACI,CAAC;YACL,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;YACxB,IAAI,QAAQ,EAAE,CAAC;gBACd,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC;YAC7B,CAAC;iBACI,CAAC;gBACL,MAAM,CAAC,UAAU,GAAG,SAAmB,CAAC;YACzC,CAAC;YACD,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAED;IACA,CAAC;IAID,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;IAID,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;IAID,IAAI,SAAS;QACZ,OAAO,IAAI,CAAC,UAAU,CAAC;IACxB,CAAC;IAID,IAAI,QAAQ;QACX,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;CACD;AAzDD,sBAyDC","sourcesContent":["import {isPromise} from './utils';\n\n/**\n * Internal class that allows us to track the state of a promise (chain).\n */\nexport class State<T = any> {\n\tstatic MakeState<TState = any>(promise: Promise<TState> | null, rejected?: unknown, fulfilled?: TState): State<TState> {\n\t\tconst retVal = new State<TState>();\n\t\tif (isPromise(promise)) {\n\t\t\tretVal._pending = true;\n\t\t\tretVal._promise = promise.then(\n\t\t\t\t(v) => {\n\t\t\t\t\tretVal._fulfilled = v;\n\t\t\t\t\tretVal._pending = false;\n\t\t\t\t\treturn v;\n\t\t\t\t},\n\t\t\t\t(e: any) => {\n\t\t\t\t\tretVal._rejected = e;\n\t\t\t\t\tretVal._pending = false;\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t\telse {\n\t\t\tretVal._pending = false;\n\t\t\tif (rejected) {\n\t\t\t\tretVal._rejected = rejected;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tretVal._fulfilled = fulfilled as TState;\n\t\t\t}\n\t\t\tretVal._promise = null;\n\t\t}\n\t\treturn retVal;\n\t}\n\n\tprotected constructor() {\n\t}\n\n\tprotected _promise!: Promise<T> | null;\n\n\tget promise(): Promise<T> | null {\n\t\treturn this._promise;\n\t}\n\n\tprotected _pending!: boolean;\n\n\tget pending(): boolean {\n\t\treturn this._pending;\n\t}\n\n\tprotected _fulfilled!: T;\n\n\tget fulfilled(): T {\n\t\treturn this._fulfilled;\n\t}\n\n\tprotected _rejected: unknown;\n\n\tget rejected(): unknown {\n\t\treturn this._rejected;\n\t}\n}\n"]}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FactoryBasedProvider = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const bindable_provider_1 = require("./bindable-provider");
|
|
5
|
+
const state_1 = require("./state");
|
|
6
6
|
/**
|
|
7
7
|
* @inheritDoc
|
|
8
8
|
* This specialization simply invokes it's configured Factory and provides the result.
|
|
9
9
|
*/
|
|
10
|
-
class FactoryBasedProvider extends
|
|
10
|
+
class FactoryBasedProvider extends bindable_provider_1.BindableProvider {
|
|
11
11
|
constructor(injector, id, maker) {
|
|
12
12
|
super(injector, id, maker);
|
|
13
13
|
}
|
|
@@ -19,17 +19,17 @@ class FactoryBasedProvider extends bindable_provider_js_1.BindableProvider {
|
|
|
19
19
|
let retVal = this.singleton;
|
|
20
20
|
if (!retVal) {
|
|
21
21
|
try {
|
|
22
|
-
retVal =
|
|
22
|
+
retVal = state_1.State.MakeState(null, undefined, this.maker(this.injector));
|
|
23
23
|
}
|
|
24
24
|
catch (err) {
|
|
25
25
|
// There was an error, give the errorHandler (if any) a crack at recovery.
|
|
26
26
|
try {
|
|
27
|
-
// queryErrorHandler will throw if it could not
|
|
28
|
-
retVal =
|
|
27
|
+
// queryErrorHandler will throw if it could not get a substitute object.
|
|
28
|
+
retVal = state_1.State.MakeState(null, undefined, this.queryErrorHandler(err));
|
|
29
29
|
}
|
|
30
30
|
catch (e) {
|
|
31
31
|
// could not recover, propagate the error.
|
|
32
|
-
retVal =
|
|
32
|
+
retVal = state_1.State.MakeState(null, e, undefined);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-factory-provider.js","sourceRoot":"","sources":["../../src/sync-factory-provider.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"sync-factory-provider.js","sourceRoot":"","sources":["../../src/sync-factory-provider.ts"],"names":[],"mappings":";;;AAAA,2DAAqD;AAGrD,mCAA8B;AAE9B;;;GAGG;AACH,MAAa,oBAAwB,SAAQ,oCAAmC;IAC/E,YAAY,QAAkB,EAAE,EAAmB,EAAE,KAAqB;QACzE,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,cAAc;QACb,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,IAAI,CAAC;gBACJ,MAAM,GAAG,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YACzE,CAAC;YACD,OAAO,GAAG,EAAE,CAAC;gBACZ,0EAA0E;gBAC1E,IAAI,CAAC;oBACJ,wEAAwE;oBACxE,MAAM,GAAG,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC3E,CAAC;gBACD,OAAO,CAAC,EAAE,CAAC;oBACV,0CAA0C;oBAC1C,MAAM,GAAG,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;gBACjD,CAAC;YACF,CAAC;QACF,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;YAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,kBAAkB,CAAC,SAAkB;QACpC,IAAI,SAAS;YACZ,OAAO,SAAS,CAAC;QAClB,OAAO,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;CACD;AAzCD,oDAyCC","sourcesContent":["import {BindableProvider} from './bindable-provider';\nimport {SyncFactory} from './binder';\nimport {InjectableId, Injector} from './injector';\nimport {State} from './state';\n\n/**\n * @inheritDoc\n * This specialization simply invokes it's configured Factory and provides the result.\n */\nexport class FactoryBasedProvider<T> extends BindableProvider<T, SyncFactory<T>> {\n\tconstructor(injector: Injector, id: InjectableId<T>, maker: SyncFactory<T>) {\n\t\tsuper(injector, id, maker);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization invokes it's configured Factory and provides the result (or invokes the error handler if necessary).\n\t */\n\tprovideAsState(): State<T> {\n\t\tlet retVal = this.singleton;\n\t\tif (!retVal) {\n\t\t\ttry {\n\t\t\t\tretVal = State.MakeState<T>(null, undefined, this.maker(this.injector));\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\t// queryErrorHandler will throw if it could not get a substitute object.\n\t\t\t\t\tretVal = 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\tretVal = State.MakeState<T>(null, e, undefined);\n\t\t\t\t}\n\t\t\t}\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 anytime 'asyncOnly' is true (since this Provider is by definition synchronous).\n\t */\n\tresolveIfSingleton(asyncOnly: boolean): Promise<T> | undefined {\n\t\tif (asyncOnly)\n\t\t\treturn undefined;\n\t\treturn super.resolveIfSingleton(false);\n\t}\n}\n"]}
|
package/lib/cjs/utils.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
exports.isErrorObj = isErrorObj;
|
|
4
|
+
exports.isPromise = isPromise;
|
|
5
|
+
exports.InvokeReleaseMethod = InvokeReleaseMethod;
|
|
6
|
+
const constants_1 = require("./constants");
|
|
6
7
|
/**
|
|
7
8
|
* Returns true if the specified object looks like a JavaScript Error object.
|
|
8
9
|
*/
|
|
@@ -11,9 +12,8 @@ function isErrorObj(err) {
|
|
|
11
12
|
return false;
|
|
12
13
|
if (err instanceof Error)
|
|
13
14
|
return true;
|
|
14
|
-
return err && typeof err.message === 'string' && typeof err.stack === 'string';
|
|
15
|
+
return !!(err && typeof err.message === 'string' && typeof err.stack === 'string');
|
|
15
16
|
}
|
|
16
|
-
exports.isErrorObj = isErrorObj;
|
|
17
17
|
/**
|
|
18
18
|
* Returns true if the specified value is "thenable" (aka a Promise).
|
|
19
19
|
*/
|
|
@@ -22,9 +22,8 @@ function isPromise(value) {
|
|
|
22
22
|
return false;
|
|
23
23
|
if (value instanceof Promise)
|
|
24
24
|
return true;
|
|
25
|
-
return value && typeof value.then === 'function';
|
|
25
|
+
return !!(value && typeof value.then === 'function');
|
|
26
26
|
}
|
|
27
|
-
exports.isPromise = isPromise;
|
|
28
27
|
/**
|
|
29
28
|
* Simple helper function to find the @Release decorated method of an object (if any), and invoke it.
|
|
30
29
|
* This is primarily an internal method as you probably know the exact method, and should invoke it yourself.
|
|
@@ -32,17 +31,15 @@ exports.isPromise = isPromise;
|
|
|
32
31
|
*/
|
|
33
32
|
function InvokeReleaseMethod(obj) {
|
|
34
33
|
var _a, _b;
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
if (releaseMethod &&
|
|
38
|
-
const releaseFn = (_b = (_a =
|
|
34
|
+
const o = obj;
|
|
35
|
+
const releaseMethod = Reflect.getMetadata(constants_1.RELEASE_METADATA_KEY, o.constructor);
|
|
36
|
+
if (releaseMethod && o.constructor.prototype[releaseMethod] && typeof o.constructor.prototype[releaseMethod] === 'function') {
|
|
37
|
+
const releaseFn = (_b = (_a = o[releaseMethod]).bind) === null || _b === void 0 ? void 0 : _b.call(_a, o);
|
|
39
38
|
if (releaseFn) {
|
|
40
39
|
releaseFn();
|
|
41
40
|
return true;
|
|
42
41
|
}
|
|
43
42
|
}
|
|
44
|
-
/* eslint-enable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
|
45
43
|
return false;
|
|
46
44
|
}
|
|
47
|
-
exports.InvokeReleaseMethod = InvokeReleaseMethod;
|
|
48
45
|
//# sourceMappingURL=utils.js.map
|
package/lib/cjs/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";;AAKA,gCAQC;AAKD,8BAQC;AAOD,kDAWC;AA5CD,2CAAiD;AAEjD;;GAEG;AACH,SAAgB,UAAU,CAAC,GAAQ;IAClC,IAAI,CAAC,GAAG;QACP,OAAO,KAAK,CAAC;IAEd,IAAI,GAAG,YAAY,KAAK;QACvB,OAAO,IAAI,CAAC;IAEb,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC;AACpF,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAI,KAAU;IACtC,IAAI,CAAC,KAAK;QACT,OAAO,KAAK,CAAC;IAEd,IAAI,KAAK,YAAY,OAAO;QAC3B,OAAO,IAAI,CAAC;IAEb,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,SAAgB,mBAAmB,CAAc,GAAM;;IACtD,MAAM,CAAC,GAAG,GAAU,CAAC;IACrB,MAAM,aAAa,GAAW,OAAO,CAAC,WAAW,CAAC,gCAAoB,EAAE,CAAC,CAAC,WAAW,CAAW,CAAC;IACjG,IAAI,aAAa,IAAI,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,UAAU,EAAE,CAAC;QAC7H,MAAM,SAAS,GAAG,MAAA,MAAA,CAAC,CAAC,aAAa,CAAC,EAAC,IAAI,mDAAG,CAAC,CAAC,CAAC;QAC7C,IAAI,SAAS,EAAE,CAAC;YACf,SAAS,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC","sourcesContent":["import {RELEASE_METADATA_KEY} from './constants';\n\n/**\n * Returns true if the specified object looks like a JavaScript Error object.\n */\nexport function isErrorObj(err: any): err is Error {\n\tif (!err)\n\t\treturn false;\n\n\tif (err instanceof Error)\n\t\treturn true;\n\n\treturn !!(err && typeof err.message === 'string' && typeof err.stack === 'string');\n}\n\n/**\n * Returns true if the specified value is \"thenable\" (aka a Promise).\n */\nexport function isPromise<T>(value: any): value is Promise<T> {\n\tif (!value)\n\t\treturn false;\n\n\tif (value instanceof Promise)\n\t\treturn true;\n\n\treturn !!(value && typeof value.then === 'function');\n}\n\n/**\n * Simple helper function to find the @Release decorated method of an object (if any), and invoke it.\n * This is primarily an internal method as you probably know the exact method, and should invoke it yourself.\n * async-injection uses this helper to allow Singletons to clean up any non-garbage-collectable resources they may have allocated.\n */\nexport function InvokeReleaseMethod<T = unknown>(obj: T): boolean {\n\tconst o = obj as any;\n\tconst releaseMethod: string = Reflect.getMetadata(RELEASE_METADATA_KEY, o.constructor) as string;\n\tif (releaseMethod && o.constructor.prototype[releaseMethod] && typeof o.constructor.prototype[releaseMethod] === 'function') {\n\t\tconst releaseFn = o[releaseMethod].bind?.(o);\n\t\tif (releaseFn) {\n\t\t\treleaseFn();\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n"]}
|
package/lib/class-provider.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { BindableProvider } from './bindable-provider
|
|
2
|
-
import { ClassConstructor, InjectableId, Injector } from './injector
|
|
3
|
-
import { State } from './state
|
|
1
|
+
import { BindableProvider } from './bindable-provider';
|
|
2
|
+
import { ClassConstructor, InjectableId, Injector } from './injector';
|
|
3
|
+
import { State } from './state';
|
|
4
4
|
interface StateResolvingInjector extends Injector {
|
|
5
5
|
resolveState<T>(id: InjectableId<T>): State<T>;
|
|
6
6
|
}
|
|
@@ -20,7 +20,7 @@ export declare class ClassBasedProvider<T> extends BindableProvider<T, ClassCons
|
|
|
20
20
|
* @inheritDoc
|
|
21
21
|
* This specialization returns undefined if 'asyncOnly' is true and there is no asynchronous PostConstruct annotation (since class constructors can never by asynchronous).
|
|
22
22
|
*/
|
|
23
|
-
resolveIfSingleton(asyncOnly: boolean): Promise<T
|
|
23
|
+
resolveIfSingleton(asyncOnly: boolean): Promise<T> | undefined;
|
|
24
24
|
/**
|
|
25
25
|
* Make a resolved or pending State that reflects any @PostConstruct annotations.
|
|
26
26
|
*/
|
package/lib/container.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { AsyncFactory, BindAs, Binder, SyncFactory } from './binder
|
|
2
|
-
import { AbstractConstructor, ClassConstructor, InjectableId, Injector } from './injector
|
|
3
|
-
import { Provider } from './provider
|
|
4
|
-
import { State } from './state
|
|
1
|
+
import { AsyncFactory, BindAs, Binder, SyncFactory } from './binder';
|
|
2
|
+
import { AbstractConstructor, ClassConstructor, InjectableId, Injector } from './injector';
|
|
3
|
+
import { Provider } from './provider';
|
|
4
|
+
import { State } from './state';
|
|
5
5
|
/**
|
|
6
6
|
* Binder and Injector (aka Container) to handle (a)synchronous dependency management.
|
|
7
7
|
*/
|
|
8
8
|
export declare class Container implements Binder {
|
|
9
|
-
protected parent?: Injector;
|
|
9
|
+
protected parent?: Injector | undefined;
|
|
10
10
|
/**
|
|
11
11
|
* Create a new Container, with an optional parent Injector which will be searched if any given InjectableId is not bound within this Container.
|
|
12
12
|
*/
|
|
13
|
-
constructor(parent?: Injector);
|
|
13
|
+
constructor(parent?: Injector | undefined);
|
|
14
14
|
protected providers: Map<InjectableId<any>, Provider<any>>;
|
|
15
15
|
/**
|
|
16
16
|
* @inheritDoc
|
|
@@ -70,6 +70,15 @@ export declare class Container implements Binder {
|
|
|
70
70
|
* In theory, you could handle all unsubscription and cleanup yourself, but the @Release decorator and this method are meant to simply make that easier.
|
|
71
71
|
*/
|
|
72
72
|
releaseSingletons(): void;
|
|
73
|
+
/**
|
|
74
|
+
* Releases a Singleton instance if it exists.
|
|
75
|
+
* However, it does **not** remove the binding, so if you call @get or @resolve (directly or indirectly) on the id, a new Singleton will be created.
|
|
76
|
+
* If not a singleton, this method returns undefined.
|
|
77
|
+
* If the singleton has been resolved, it is returned, otherwise null is returned.
|
|
78
|
+
* If the singleton is pending resolution, a Promise for the singleton (or for null) is returned.
|
|
79
|
+
* Note that if a singleton is returned, its Release method will already have been invoked.
|
|
80
|
+
*/
|
|
81
|
+
releaseSingleton<T>(id: InjectableId<T>): T | undefined | null | Promise<T | null>;
|
|
73
82
|
/**
|
|
74
83
|
* Make a copy of this @see Container.
|
|
75
84
|
* This is an experimental feature!
|
package/lib/decorators.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InjectableId } from './injector
|
|
1
|
+
import { InjectableId } from './injector';
|
|
2
2
|
/**
|
|
3
3
|
* 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.
|
|
4
4
|
* This decorator will throw if not placed on a class declaration, or if placed more than once on a class declaration.
|
|
@@ -16,7 +16,7 @@ export class AsyncFactoryBasedProvider extends BindableProvider {
|
|
|
16
16
|
let retVal = this.singleton;
|
|
17
17
|
if (!retVal) {
|
|
18
18
|
// Wrap the async factory's Promise in an errorHandler aware Promise.
|
|
19
|
-
// Our contract is that an AsyncFactory may not throw and must return a valid Promise (e.g
|
|
19
|
+
// Our contract is that an AsyncFactory may not throw and must return a valid Promise (e.g., pending, resolved, rejected, etc).
|
|
20
20
|
retVal = State.MakeState(this.makePromiseForObj(this.maker(this.injector), obj => obj));
|
|
21
21
|
}
|
|
22
22
|
if (this.singleton === null)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"async-factory-provider.js","sourceRoot":"","sources":["../../src/async-factory-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"async-factory-provider.js","sourceRoot":"","sources":["../../src/async-factory-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAC;AAE9B;;;GAGG;AACH,MAAM,OAAO,yBAA6B,SAAQ,gBAAoC;IACrF,YAAY,QAAkB,EAAE,EAAmB,EAAE,KAAsB;QAC1E,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,cAAc;QACb,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,qEAAqE;YACrE,+HAA+H;YAC/H,MAAM,GAAG,KAAK,CAAC,SAAS,CAAI,IAAI,CAAC,iBAAiB,CAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/F,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;YAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;CACD","sourcesContent":["import {BindableProvider} from './bindable-provider';\nimport {AsyncFactory} from './binder';\nimport {InjectableId, Injector} from './injector';\nimport {State} from './state';\n\n/**\n * @inheritDoc\n * This specialization invokes it's configured Factory asynchronously and waits until it can provide the result.\n */\nexport class AsyncFactoryBasedProvider<T> extends BindableProvider<T, AsyncFactory<T>> {\n\tconstructor(injector: Injector, id: InjectableId<T>, maker: AsyncFactory<T>) {\n\t\tsuper(injector, id, maker);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization invokes it's configured Factory and provides the result (or invokes the error handler if necessary).\n\t */\n\tprovideAsState(): State<T> {\n\t\tlet retVal = this.singleton;\n\t\tif (!retVal) {\n\t\t\t// Wrap the async factory's Promise in an errorHandler aware Promise.\n\t\t\t// Our contract is that an AsyncFactory may not throw and must return a valid Promise (e.g., pending, resolved, rejected, etc).\n\t\t\tretVal = State.MakeState<T>(this.makePromiseForObj<T>(this.maker(this.injector), obj => obj));\n\t\t}\n\t\tif (this.singleton === null)\n\t\t\tthis.singleton = retVal;\n\t\treturn retVal;\n\t}\n}\n"]}
|
|
@@ -63,35 +63,35 @@ export class BindableProvider extends Provider {
|
|
|
63
63
|
* @param waitFor The supplied Promise.
|
|
64
64
|
* @param cb Callback to be invoked if the supplied Promise resolves.
|
|
65
65
|
*/
|
|
66
|
-
makePromiseForObj(waitFor, cb) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
66
|
+
async makePromiseForObj(waitFor, cb) {
|
|
67
|
+
// Local helper: consults the errorHandler (if any) for recovery; returns a substitute or re-throws.
|
|
68
|
+
const handleError = (err, objValue) => {
|
|
69
|
+
if (this.errorHandler) {
|
|
70
|
+
const handlerResult = this.errorHandler(this.injector, this.id, this.maker, err, objValue);
|
|
71
|
+
// Error handler wants us to propagate an alternative error.
|
|
72
|
+
if (isErrorObj(handlerResult))
|
|
73
|
+
throw handlerResult;
|
|
74
|
+
// Error handler provided a valid (fully resolved) replacement.
|
|
75
|
+
else if (typeof handlerResult !== 'undefined')
|
|
76
|
+
return handlerResult;
|
|
77
|
+
}
|
|
78
|
+
throw err;
|
|
79
|
+
};
|
|
80
|
+
let result;
|
|
81
|
+
try {
|
|
82
|
+
result = await waitFor;
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
// waitFor rejected — ask the error handler for recovery, passing cb(undefined) as the partial object value.
|
|
86
|
+
return handleError(err, cb(undefined));
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
return cb(result);
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
// cb threw after a successful resolution — ask the error handler for recovery.
|
|
93
|
+
return handleError(err, cb(result));
|
|
94
|
+
}
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
//# sourceMappingURL=bindable-provider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bindable-provider.js","sourceRoot":"","sources":["../../src/bindable-provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,QAAQ,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"bindable-provider.js","sourceRoot":"","sources":["../../src/bindable-provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AACpC,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAC;AAEnC;;;GAGG;AACH,MAAM,OAAgB,gBAAgF,SAAQ,QAAW;IACxH,YAAgC,QAAkB,EAAY,EAAmB,EAAY,KAAQ;QACpG,KAAK,EAAE,CAAC;QADuB,aAAQ,GAAR,QAAQ,CAAU;QAAY,OAAE,GAAF,EAAE,CAAiB;QAAY,UAAK,GAAL,KAAK,CAAG;IAErG,CAAC;IAcD;;;;OAIG;IACH,UAAU;QACT,MAAM,MAAM,GAAiB;YAC5B,OAAO,EAAE,CAAC,EAAyB,EAAE,EAAE;gBACtC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;YACxB,CAAC;YACD,SAAS,EAAE,CAAC,EAA2B,EAAE,EAAE;gBAC1C,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;gBACzB,OAAO,MAAM,CAAC;YACf,CAAC;YACD,WAAW,EAAE,GAAG,EAAE;gBACjB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,qCAAqC;gBAC5D,OAAO,MAAM,CAAC;YACf,CAAC;SACD,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACO,iBAAiB,CAAC,GAAY,EAAE,GAAO;QAChD,oHAAoH;QACpH,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YACtF,gDAAgD;YAChD,IAAI,UAAU,CAAC,aAAa,CAAC;gBAC5B,MAAM,aAAa,CAAC;YACrB,kGAAkG;YAClG,IAAI,OAAO,aAAa,KAAK,WAAW;gBACvC,MAAM,GAAG,CAAC;YACX,+DAA+D;YAC/D,OAAO,aAAa,CAAC;QACtB,CAAC;QACD,mFAAmF;QACnF,MAAM,GAAG,CAAC;IACX,CAAC;IAED;;;;;;;OAOG;IACO,KAAK,CAAC,iBAAiB,CAAI,OAAmB,EAAE,EAAoB;QAC7E,oGAAoG;QACpG,MAAM,WAAW,GAAG,CAAC,GAAY,EAAE,QAAY,EAAK,EAAE;YACrD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACvB,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;gBAC3F,4DAA4D;gBAC5D,IAAI,UAAU,CAAC,aAAa,CAAC;oBAC5B,MAAM,aAAa,CAAC;gBACrB,+DAA+D;qBAC1D,IAAI,OAAO,aAAa,KAAK,WAAW;oBAC5C,OAAO,aAAa,CAAC;YACvB,CAAC;YACD,MAAM,GAAG,CAAC;QACX,CAAC,CAAC;QACF,IAAI,MAAS,CAAC;QACd,IAAI,CAAC;YACJ,MAAM,GAAG,MAAM,OAAO,CAAC;QACxB,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;YACZ,4GAA4G;YAC5G,OAAO,WAAW,CAAC,GAAG,EAAE,EAAE,CAAC,SAAyB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,CAAC;YACJ,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;YACZ,+EAA+E;YAC/E,OAAO,WAAW,CAAC,GAAG,EAAE,EAAE,CAAC,MAAW,CAAC,CAAC,CAAC;QAC1C,CAAC;IACF,CAAC;CACD","sourcesContent":["import {AsyncFactory, BindAs, OnErrorCallback, OnSuccessCallback, SyncFactory} from './binder';\nimport {ClassConstructor, InjectableId, Injector} from './injector';\nimport {Provider} from './provider';\nimport {isErrorObj} from './utils';\n\n/**\n * @inheritDoc\n * This abstraction is for Providers that can be additionally configured as Singletons and/or configured with error and/or success handling callback(s).\n */\nexport abstract class BindableProvider<T, M = ClassConstructor<T> | SyncFactory<T> | AsyncFactory<T>> extends Provider<T> {\n\tprotected constructor(protected injector: Injector, protected id: InjectableId<T>, protected maker: M) {\n\t\tsuper();\n\t}\n\n\t/**\n\t * A user supplied success handling function.\n\t * Default value is undefined.\n\t */\n\tprotected successHandler?: OnSuccessCallback<T, any>;\n\n\t/**\n\t * A user supplied error handling function.\n\t * Default value is undefined.\n\t */\n\tprotected errorHandler?: OnErrorCallback<T, any>;\n\n\t/**\n\t * Invoked by the Binder to create chain-able configuration\n\t *\n\t * @see BindAs\n\t */\n\tmakeBindAs(): BindAs<T, M> {\n\t\tconst retVal: BindAs<T, M> = {\n\t\t\tonError: (cb: OnErrorCallback<T, M>) => {\n\t\t\t\tthis.errorHandler = cb;\n\t\t\t},\n\t\t\tonSuccess: (cb: OnSuccessCallback<T, M>) => {\n\t\t\t\tthis.successHandler = cb;\n\t\t\t\treturn retVal;\n\t\t\t},\n\t\t\tasSingleton: () => {\n\t\t\t\tthis.singleton = null; // Flag state as no longer undefined.\n\t\t\t\treturn retVal;\n\t\t\t}\n\t\t};\n\t\treturn retVal;\n\t}\n\n\t/**\n\t * Encapsulate the logic of invoking any configured error handler, and processing it's result.\n\t *\n\t * @see OnErrorCallback\n\t *\n\t * @returns The object substituted by the callback (otherwise this method throws the appropriate error).\n\t */\n\tprotected queryErrorHandler(err: unknown, obj?: T): T {\n\t\t// There was an error during construction, see if an error handler was provided, and if so, see what it wants to do.\n\t\tif (this.errorHandler) {\n\t\t\tconst handlerResult = this.errorHandler(this.injector, this.id, this.maker, err, obj);\n\t\t\t// Error handler wants us to propagate an error.\n\t\t\tif (isErrorObj(handlerResult))\n\t\t\t\tthrow handlerResult;\n\t\t\t// Error handler has no opinion, so provideAsState a state that reflects the error we just caught.\n\t\t\tif (typeof handlerResult === 'undefined')\n\t\t\t\tthrow err;\n\t\t\t// Error handler provided a valid (fully resolved) replacement.\n\t\t\treturn handlerResult;\n\t\t}\n\t\t// No error handler, provideAsState a state that reflects the error we just caught.\n\t\tthrow err;\n\t}\n\n\t/**\n\t * This is like a retry mechanism that uses the Provider's errorHandler (if any) to attempt recovery whenever the supplied Promise rejects.\n\t * This method returns a Promise that rejects if recovery was not possible.\n\t * If the supplied Promise resolves, then this method passes the result to the callback, and then resolve as whatever that callback returns.\n\t *\n\t * @param waitFor The supplied Promise.\n\t * @param cb Callback to be invoked if the supplied Promise resolves.\n\t */\n\tprotected async makePromiseForObj<R>(waitFor: Promise<R>, cb: (result: R) => T): Promise<T> {\n\t\t// Local helper: consults the errorHandler (if any) for recovery; returns a substitute or re-throws.\n\t\tconst handleError = (err: unknown, objValue?: T): T => {\n\t\t\tif (this.errorHandler) {\n\t\t\t\tconst handlerResult = this.errorHandler(this.injector, this.id, this.maker, err, objValue);\n\t\t\t\t// Error handler wants us to propagate an alternative error.\n\t\t\t\tif (isErrorObj(handlerResult))\n\t\t\t\t\tthrow handlerResult;\n\t\t\t\t// Error handler provided a valid (fully resolved) replacement.\n\t\t\t\telse if (typeof handlerResult !== 'undefined')\n\t\t\t\t\treturn handlerResult;\n\t\t\t}\n\t\t\tthrow err;\n\t\t};\n\t\tlet result: R;\n\t\ttry {\n\t\t\tresult = await waitFor;\n\t\t}\n\t\tcatch (err) {\n\t\t\t// waitFor rejected — ask the error handler for recovery, passing cb(undefined) as the partial object value.\n\t\t\treturn handleError(err, cb(undefined as unknown as R));\n\t\t}\n\t\ttry {\n\t\t\treturn cb(result);\n\t\t}\n\t\tcatch (err) {\n\t\t\t// cb threw after a successful resolution — ask the error handler for recovery.\n\t\t\treturn handleError(err, cb(result as R));\n\t\t}\n\t}\n}\n"]}
|
package/lib/esm/binder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binder.js","sourceRoot":"","sources":["../../src/binder.ts"],"names":[],"mappings":"","sourcesContent":["import {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector
|
|
1
|
+
{"version":3,"file":"binder.js","sourceRoot":"","sources":["../../src/binder.ts"],"names":[],"mappings":"","sourcesContent":["import {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector';\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 *\n * @deprecated {@link Binder} was removed from index.ts long ago will be removed in a future release.\n * Use {@link Container} to build a context root — it provides all binding methods directly.\n * For type annotations, use {@link Injector}, which {@link Container} implements.\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"]}
|
|
@@ -39,7 +39,7 @@ export class ClassBasedProvider extends BindableProvider {
|
|
|
39
39
|
*/
|
|
40
40
|
makePostConstructState(obj) {
|
|
41
41
|
var _a, _b;
|
|
42
|
-
if (typeof obj === 'object' && (!Array.isArray(obj)) && obj.constructor) {
|
|
42
|
+
if (obj !== null && typeof obj === 'object' && (!Array.isArray(obj)) && obj.constructor) {
|
|
43
43
|
let maybeAsync = false;
|
|
44
44
|
let pcFn;
|
|
45
45
|
if (typeof this.successHandler === 'function') {
|
|
@@ -49,16 +49,15 @@ export class ClassBasedProvider extends BindableProvider {
|
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
51
|
else {
|
|
52
|
-
/* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
|
53
52
|
// Check to see if there is a @PostConstruct annotation on a method of the class.
|
|
54
|
-
|
|
53
|
+
const ctor = obj.constructor;
|
|
54
|
+
let postConstruct = Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, ctor);
|
|
55
55
|
if (!postConstruct) {
|
|
56
56
|
maybeAsync = true;
|
|
57
|
-
postConstruct = Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY,
|
|
57
|
+
postConstruct = Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, ctor);
|
|
58
58
|
}
|
|
59
|
-
if (postConstruct &&
|
|
59
|
+
if (postConstruct && ctor.prototype[postConstruct] && typeof ctor.prototype[postConstruct] === 'function')
|
|
60
60
|
pcFn = (_b = (_a = obj[postConstruct]).bind) === null || _b === void 0 ? void 0 : _b.call(_a, obj);
|
|
61
|
-
/* eslint-enable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
|
62
61
|
}
|
|
63
62
|
if (pcFn) {
|
|
64
63
|
let result;
|
|
@@ -79,7 +78,6 @@ export class ClassBasedProvider extends BindableProvider {
|
|
|
79
78
|
// The post construction method says it will let us know when it's finished.
|
|
80
79
|
if (result && (result instanceof Promise || (maybeAsync && isPromise(result)))) {
|
|
81
80
|
// Return a State that is pending (the other return statements in this method return a State which is resolved or rejected).
|
|
82
|
-
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
83
81
|
return State.MakeState(this.makePromiseForObj(result, () => obj));
|
|
84
82
|
}
|
|
85
83
|
}
|
|
@@ -107,7 +105,6 @@ export class ClassBasedProvider extends BindableProvider {
|
|
|
107
105
|
throw new Error(`Injection error. Unable to determine parameter ${index} type/value of ${this.maker.toString()} constructor`);
|
|
108
106
|
}
|
|
109
107
|
// Ask our container to resolve the parameter.
|
|
110
|
-
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
111
108
|
let param = this.injector.resolveState(actualToken);
|
|
112
109
|
// If the parameter could not be resolved, see if there is an @Optional annotation
|
|
113
110
|
if ((!param.pending) && param.rejected) {
|
|
@@ -134,41 +131,43 @@ export class ClassBasedProvider extends BindableProvider {
|
|
|
134
131
|
// We do this by mapping each param to a Promise (pending or not), and then awaiting them all.
|
|
135
132
|
// This might create some unnecessary (but immediately resolved) Promise objects,
|
|
136
133
|
// 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) => {
|
|
134
|
+
const objPromise = this.makePromiseForObj(Promise.all(params.map(async (p, idx) => {
|
|
138
135
|
if (p.pending) {
|
|
139
|
-
|
|
136
|
+
try {
|
|
137
|
+
return await p.promise;
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
140
|
// This was a promised param that failed to resolve.
|
|
141
141
|
// If there is an Optional decorator, use that, otherwise, failure is failure.
|
|
142
142
|
const md = _getOptionalDefaultAt(this.maker, idx);
|
|
143
143
|
if (!md)
|
|
144
144
|
throw err;
|
|
145
145
|
return md.value;
|
|
146
|
-
}
|
|
146
|
+
}
|
|
147
147
|
}
|
|
148
|
-
|
|
149
|
-
return Promise.reject(p.rejected);
|
|
150
|
-
return Promise.resolve(p.fulfilled);
|
|
148
|
+
return p.fulfilled;
|
|
151
149
|
})), (values) => {
|
|
152
150
|
if (values) {
|
|
153
151
|
// All the parameters are now available, instantiate the class.
|
|
154
152
|
// If this throws, it will be handled by our caller.
|
|
155
153
|
return Reflect.construct(this.maker, values);
|
|
156
154
|
}
|
|
155
|
+
return undefined;
|
|
157
156
|
});
|
|
158
157
|
// Once the obj is resolved, then we need to check for PostConstruct and if it was async, wait for that too.
|
|
159
|
-
return State.MakeState(
|
|
158
|
+
return State.MakeState((async () => {
|
|
159
|
+
const obj = await objPromise;
|
|
160
160
|
const state = this.makePostConstructState(obj);
|
|
161
161
|
if (state.pending) {
|
|
162
|
-
return state.promise; // chain (aka wait some more).
|
|
162
|
+
return await state.promise; // chain (aka wait some more).
|
|
163
163
|
}
|
|
164
164
|
else if (state.rejected) {
|
|
165
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
166
165
|
return state.rejected; // error
|
|
167
166
|
}
|
|
168
167
|
else {
|
|
169
168
|
return state.fulfilled; // value (aka obj).
|
|
170
169
|
}
|
|
171
|
-
}));
|
|
170
|
+
})());
|
|
172
171
|
}
|
|
173
172
|
else {
|
|
174
173
|
// All parameters needed for construction are available, instantiate the object.
|
|
@@ -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 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"]}
|
|
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';\nimport {POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_PARAMS} from './constants';\nimport {_getInjectedIdAt, _getOptionalDefaultAt} from './decorators';\nimport {ClassConstructor, InjectableId, Injector} from './injector';\nimport {State} from './state';\nimport {isPromise} from './utils';\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> | undefined {\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 (obj !== null && typeof obj === 'object' && (!Array.isArray(obj)) && (obj as any).constructor) {\n\t\t\tlet maybeAsync = false;\n\t\t\tlet pcFn: (() => void | Error | Promise<void | Error>) | undefined;\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// Check to see if there is a @PostConstruct annotation on a method of the class.\n\t\t\t\tconst ctor = (obj as any).constructor;\n\t\t\t\tlet postConstruct: string = Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, ctor) as string;\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, ctor) as string;\n\t\t\t\t}\n\t\t\t\tif (postConstruct && ctor.prototype[postConstruct] && typeof ctor.prototype[postConstruct] === 'function')\n\t\t\t\t\tpcFn = (obj as any)[postConstruct].bind?.(obj);\n\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\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\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(async (p, idx) => {\n\t\t\t\tif (p.pending) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn await p.promise!;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (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\treturn 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\treturn undefined as unknown as 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>((async () => {\n\t\t\t\tconst obj = await objPromise;\n\t\t\t\tconst state = this.makePostConstructState(obj);\n\t\t\t\tif (state.pending) {\n\t\t\t\t\treturn await 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\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constant-provider.js","sourceRoot":"","sources":["../../src/constant-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"constant-provider.js","sourceRoot":"","sources":["../../src/constant-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AACpC,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAC;AAE9B;;;GAGG;AACH,MAAM,OAAO,gBAAoB,SAAQ,QAAW;IACnD,YAAY,QAAW;QACtB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAI,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAChE,CAAC;IAED,cAAc;QACb,OAAO,IAAI,CAAC,SAAU,CAAC;IACxB,CAAC;CACD","sourcesContent":["import {Provider} from './provider';\nimport {State} from './state';\n\n/**\n * @inheritDoc\n * This specialization is always a Singleton.\n */\nexport class ConstantProvider<T> extends Provider<T> {\n\tconstructor(constant: T) {\n\t\tsuper();\n\t\tthis.singleton = State.MakeState<T>(null, undefined, constant);\n\t}\n\n\tprovideAsState(): State<T> {\n\t\treturn this.singleton!;\n\t}\n}\n"]}
|