async-injection 1.2.7 → 1.5.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/Changelog.md +11 -2
- package/License.txt +1 -1
- package/ReadMe.md +9 -5
- package/lib/cjs/async-factory-provider.js.map +1 -1
- package/lib/cjs/bindable-provider.js +6 -6
- package/lib/cjs/bindable-provider.js.map +1 -1
- package/lib/cjs/binder.d.ts +1 -1
- package/lib/cjs/binder.js.map +1 -1
- package/lib/cjs/class-provider.d.ts +5 -3
- package/lib/cjs/class-provider.js +6 -7
- package/lib/cjs/class-provider.js.map +1 -1
- package/lib/cjs/constant-provider.js.map +1 -1
- package/lib/cjs/constants.d.ts +1 -0
- package/lib/cjs/constants.js +2 -1
- package/lib/cjs/constants.js.map +1 -1
- package/lib/cjs/container.d.ts +30 -2
- package/lib/cjs/container.js +59 -9
- package/lib/cjs/container.js.map +1 -1
- package/lib/cjs/decorators.d.ts +13 -0
- package/lib/cjs/decorators.js +33 -1
- package/lib/cjs/decorators.js.map +1 -1
- package/lib/cjs/index.d.ts +1 -1
- package/lib/cjs/index.js +3 -1
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/injector.d.ts +10 -1
- package/lib/cjs/injector.js +15 -0
- package/lib/cjs/injector.js.map +1 -1
- package/lib/cjs/provider.d.ts +8 -0
- package/lib/cjs/provider.js +26 -0
- package/lib/cjs/provider.js.map +1 -1
- package/lib/cjs/state.js +1 -1
- package/lib/cjs/state.js.map +1 -1
- package/lib/cjs/sync-factory-provider.js.map +1 -1
- package/lib/cjs/utils.d.ts +12 -0
- package/lib/cjs/utils.js +29 -2
- package/lib/cjs/utils.js.map +1 -1
- package/lib/esm/async-factory-provider.js.map +1 -1
- package/lib/esm/bindable-provider.js +4 -4
- package/lib/esm/bindable-provider.js.map +1 -1
- package/lib/esm/binder.d.ts +1 -1
- package/lib/esm/binder.js.map +1 -1
- package/lib/esm/class-provider.d.ts +5 -3
- package/lib/esm/class-provider.js +3 -4
- package/lib/esm/class-provider.js.map +1 -1
- package/lib/esm/constant-provider.js.map +1 -1
- package/lib/esm/constants.d.ts +1 -0
- package/lib/esm/constants.js +1 -0
- package/lib/esm/constants.js.map +1 -1
- package/lib/esm/container.d.ts +30 -2
- package/lib/esm/container.js +58 -8
- package/lib/esm/container.js.map +1 -1
- package/lib/esm/decorators.d.ts +13 -0
- package/lib/esm/decorators.js +32 -1
- package/lib/esm/decorators.js.map +1 -1
- package/lib/esm/index.d.ts +1 -1
- package/lib/esm/index.js +1 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/injector.d.ts +10 -1
- package/lib/esm/injector.js +13 -1
- package/lib/esm/injector.js.map +1 -1
- package/lib/esm/provider.d.ts +8 -0
- package/lib/esm/provider.js +26 -0
- package/lib/esm/provider.js.map +1 -1
- package/lib/esm/state.js +1 -1
- package/lib/esm/state.js.map +1 -1
- package/lib/esm/sync-factory-provider.js.map +1 -1
- package/lib/esm/utils.d.ts +12 -0
- package/lib/esm/utils.js +26 -0
- package/lib/esm/utils.js.map +1 -1
- package/package.json +13 -13
package/Changelog.md
CHANGED
|
@@ -42,12 +42,21 @@ Update tsc devDependency from 4.3.3 to 4.3.4.
|
|
|
42
42
|
Update the ChangeLog to properly reflect recent GitHub releases.
|
|
43
43
|
|
|
44
44
|
**1.2.6 / 2021-07-14**
|
|
45
|
-
Merge PR [https://github.com/pcafstockf/async-injection/pull/9
|
|
45
|
+
Merge PR #9 [ESLINT integration + Improvements](https://github.com/pcafstockf/async-injection/pull/9).
|
|
46
46
|
Update devDependencies.
|
|
47
47
|
Resolved a couple of eslint warnings.
|
|
48
48
|
tsc no longer removes comments in generated code. This can cause problems with post-processing tools such as istanbul. If file size is of concern to you, you should probably be minifying anyway.
|
|
49
49
|
|
|
50
50
|
**1.2.7 / 2021-08-02**
|
|
51
|
-
Revert type declaration for AbstractConstructor which was broken during eslint integration.
|
|
51
|
+
Revert type declaration for AbstractConstructor which was broken during eslint integration.
|
|
52
52
|
Update eslint related dev-dependencies.
|
|
53
53
|
|
|
54
|
+
**1.3.0 / 2021-11-27**
|
|
55
|
+
Support Container driven release of Singleton allocated resources (see Container.releaseSingletons).
|
|
56
|
+
Update devDependencies.
|
|
57
|
+
Minor updates to ReadMe.
|
|
58
|
+
|
|
59
|
+
**1.4.0 / 2022-02-16**
|
|
60
|
+
Add Angular style InjectionToken class as a variant of InjectableId to support implicit typing of constants and interfaces.
|
|
61
|
+
Minor update to Binder.resolveSingletons to make it chainable (aka return the Container/Binder instance).
|
|
62
|
+
Minor updates to ReadMe.
|
package/License.txt
CHANGED
package/ReadMe.md
CHANGED
|
@@ -18,7 +18,8 @@ You can get the latest release using npm:
|
|
|
18
18
|
$ npm install async-injection --save
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
To enhance flexibility, Async-Injection does not dictate which Reflect API implementation you use. However, you will need to explicitly choose and load one.
|
|
22
|
+
You can use:
|
|
22
23
|
|
|
23
24
|
- [reflect-metadata](https://www.npmjs.com/package/reflect-metadata)
|
|
24
25
|
- [core-js (core-js/es7/reflect)](https://www.npmjs.com/package/core-js)
|
|
@@ -32,6 +33,9 @@ import "reflect-metadata";
|
|
|
32
33
|
// Your code here...
|
|
33
34
|
```
|
|
34
35
|
|
|
36
|
+
Please note that this library supports a wide variety of runtimes and is distributed as both esm and cjs modules, side by side.
|
|
37
|
+
Please see this [link](https://github.com/pcafstockf/async-injection/issues/10) if you experience module errors when compiling.
|
|
38
|
+
|
|
35
39
|
## Basic Usage (synchronous)
|
|
36
40
|
Here we 'get' a new transaction handling object, that itself, relies on a shared service:
|
|
37
41
|
|
|
@@ -210,8 +214,8 @@ Async-Injection tries to follow the common API patterns found in most other DI i
|
|
|
210
214
|
[@Injectable](https://pcafstockf.github.io/async-injection/api-docs/globals.html#injectable) decorator (aka annotation) to your class (see examples above).
|
|
211
215
|
- You may optionally add a
|
|
212
216
|
[@PostConstruct](https://pcafstockf.github.io/async-injection/api-docs/globals.html#postconstruct) decorator to a method of your class to perform synchronous or asynchronous initialization of a new instance.
|
|
213
|
-
- By default, Async-
|
|
214
|
-
[
|
|
217
|
+
- By default, Async-Injection will examine the parameters of a class constructor and do it's best to match those to a bound
|
|
218
|
+
[InjectableId](https://pcafstockf.github.io/async-injection/api-docs/globals.html#injectableid).
|
|
215
219
|
- You may use the
|
|
216
220
|
[@Inject](https://pcafstockf.github.io/async-injection/api-docs/globals.html#inject) decorator to explicitly declare which
|
|
217
221
|
[InjectableId](https://pcafstockf.github.io/async-injection/api-docs/globals.html#injectableid) should be used (generally required for a
|
|
@@ -220,7 +224,7 @@ Async-Injection tries to follow the common API patterns found in most other DI i
|
|
|
220
224
|
[@Optional](https://pcafstockf.github.io/async-injection/api-docs/globals.html#optional) decorator allows you to specify a default value for a class constructor parameter in the event that no matching
|
|
221
225
|
[InjectableId](https://pcafstockf.github.io/async-injection/api-docs/globals.html#injectableid) can be found.
|
|
222
226
|
- The Container's
|
|
223
|
-
[resolveSingletons](https://pcafstockf.github.io/async-injection/api-docs/container.html#resolvesingletons) method may be used to wait for any bound
|
|
227
|
+
[resolveSingletons](https://pcafstockf.github.io/async-injection/api-docs/container.html#resolvesingletons) method may be used to wait for any bound (a)synchronous [Singletons](https://en.wikipedia.org/wiki/Singleton_pattern) to finish initialization before continuing execution of your application.
|
|
224
228
|
|
|
225
229
|
## Acknowledgements
|
|
226
230
|
Thanks to all the contributors at [InversifyJS](https://github.com/inversify/InversifyJS). It is a powerful, clean, flexible, inspiring design.
|
|
@@ -233,7 +237,7 @@ Thanks to Carlos Delgado for the idea of a ["QuerablePromise"](https://ourcodewo
|
|
|
233
237
|
|
|
234
238
|
## MIT License
|
|
235
239
|
|
|
236
|
-
Copyright (c) 2020 Frank Stock
|
|
240
|
+
Copyright (c) 2020-2022 Frank Stock
|
|
237
241
|
|
|
238
242
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
239
243
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"async-factory-provider.js","sourceRoot":"","sources":["../../src/async-factory-provider.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"async-factory-provider.js","sourceRoot":"","sources":["../../src/async-factory-provider.ts"],"names":[],"mappings":";;;AAAA,2DAAqD;AAGrD,mCAA8B;AAE9B;;;GAGG;AACH,MAAa,yBAA6B,SAAQ,oCAAoC;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;YACZ,qEAAqE;YACrE,8HAA8H;YAC9H,MAAM,GAAG,aAAK,CAAC,SAAS,CAAI,IAAI,CAAC,iBAAiB,CAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;SAC9F;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;YAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;CACD;AApBD,8DAoBC","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"]}
|
|
@@ -47,7 +47,7 @@ class BindableProvider extends provider_1.Provider {
|
|
|
47
47
|
if (this.errorHandler) {
|
|
48
48
|
const handlerResult = this.errorHandler(this.injector, this.id, this.maker, err, obj);
|
|
49
49
|
// Error handler wants us to propagate an error.
|
|
50
|
-
if (utils_1.isErrorObj(handlerResult))
|
|
50
|
+
if ((0, utils_1.isErrorObj)(handlerResult))
|
|
51
51
|
throw handlerResult;
|
|
52
52
|
// Error handler has no opinion, so provideAsState a state that reflects the error we just caught.
|
|
53
53
|
if (typeof handlerResult === 'undefined')
|
|
@@ -68,12 +68,12 @@ class BindableProvider extends provider_1.Provider {
|
|
|
68
68
|
*/
|
|
69
69
|
makePromiseForObj(waitFor, cb) {
|
|
70
70
|
return new Promise((resolve, reject) => {
|
|
71
|
-
const errHandlerFn = (err) => {
|
|
71
|
+
const errHandlerFn = (err, objValue) => {
|
|
72
72
|
// There was an error during async post construction, see if an error handler was provided, and if so, see what it wants to do.
|
|
73
73
|
if (this.errorHandler) {
|
|
74
|
-
const handlerResult = this.errorHandler(this.injector, this.id, this.maker, err);
|
|
74
|
+
const handlerResult = this.errorHandler(this.injector, this.id, this.maker, err, objValue);
|
|
75
75
|
// Error handler wants us to propagate an alternative error.
|
|
76
|
-
if (utils_1.isErrorObj(handlerResult))
|
|
76
|
+
if ((0, utils_1.isErrorObj)(handlerResult))
|
|
77
77
|
err = handlerResult; // Fall thru
|
|
78
78
|
else if (typeof handlerResult !== 'undefined') {
|
|
79
79
|
resolve(handlerResult); // Error handler provided a replacement, so change the State that we returned from pending to resolved.
|
|
@@ -89,10 +89,10 @@ class BindableProvider extends provider_1.Provider {
|
|
|
89
89
|
resolve(cb(result));
|
|
90
90
|
}
|
|
91
91
|
catch (err) {
|
|
92
|
-
errHandlerFn(err);
|
|
92
|
+
errHandlerFn(err, cb(result));
|
|
93
93
|
}
|
|
94
94
|
}).catch((err) => {
|
|
95
|
-
errHandlerFn(err);
|
|
95
|
+
errHandlerFn(err, cb(undefined));
|
|
96
96
|
});
|
|
97
97
|
});
|
|
98
98
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bindable-provider.js","sourceRoot":"","sources":["../../src/bindable-provider.ts"],"names":[],"mappings":";;;AAEA,
|
|
1
|
+
{"version":3,"file":"bindable-provider.js","sourceRoot":"","sources":["../../src/bindable-provider.ts"],"names":[],"mappings":"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","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: Error, 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 makePromiseForObj<R>(waitFor: Promise<R>, cb: (result: R) => T): Promise<T> {\n\t\treturn new Promise<T>((resolve, reject) => {\n\t\t\tconst errHandlerFn = (err: any, objValue?: T) => {\n\t\t\t\t// There was an error during async post construction, see if an error handler was provided, and if so, see what it wants to do.\n\t\t\t\tif (this.errorHandler) {\n\t\t\t\t\tconst handlerResult = this.errorHandler(this.injector, this.id, this.maker, err, objValue);\n\t\t\t\t\t// Error handler wants us to propagate an alternative error.\n\t\t\t\t\tif (isErrorObj(handlerResult))\n\t\t\t\t\t\terr = handlerResult; // Fall thru\n\t\t\t\t\telse if (typeof handlerResult !== 'undefined') {\n\t\t\t\t\t\tresolve(handlerResult); // Error handler provided a replacement, so change the State that we returned from pending to resolved.\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// This will change the State that we returned from pending to rejected.\n\t\t\t\treject(err);\n\t\t\t};\n\t\t\twaitFor.then(\n\t\t\t\t(result) => {\n\t\t\t\t\t// This will change the State that we returned from pending to resolved.\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresolve(cb(result));\n\t\t\t\t\t}\n\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\terrHandlerFn(err, cb(result));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t).catch(\n\t\t\t\t(err) => {\n\t\t\t\t\terrHandlerFn(err, cb(undefined));\n\t\t\t\t}\n\t\t\t);\n\t\t});\n\t}\n}\n"]}
|
package/lib/cjs/binder.d.ts
CHANGED
|
@@ -102,5 +102,5 @@ export interface Binder extends Injector {
|
|
|
102
102
|
* @param parentRecursion If true and the the container has a parent, resolveIfSingleton will first be called for the parent
|
|
103
103
|
* @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>
|
|
104
104
|
*/
|
|
105
|
-
resolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<
|
|
105
|
+
resolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this>;
|
|
106
106
|
}
|
package/lib/cjs/binder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binder.js","sourceRoot":"","sources":["../../src/binder.ts"],"names":[],"mappings":"","sourcesContent":["import {
|
|
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: Error, value?: T) => T | Error | void;\n\n/**\n * You may bind a success handler which will be invoked just before the bound InjectableId is put into service.\n * This is an alternative to the more preferred `@PostConstruct` decorator for scenarios when usage of that decorator is not feasible.\n * WARNING:\n * By registering a success handler, you override and nullify any `@PostConstruct` decorator on the class.\n * In such a scenario, the success handler should perform whatever care and feeding the class expected from the `@PostConstruct` decorator.\n * A success handler *must* not throw, but may return an Error that will be propagated back up the call chain.\n *\n * @param binder The Binder that performed the construction.\n * @param id The identifier for what was made.\n * @param maker The thing that made. Will be one of type ClassConstructor, SyncFactory, or AsyncFactory, depending on how you registered the binding.\n * @param value The thing that was made.\n * @returns one of 3 results...\n * An Error which will be propagated back up the call chain.\n * Undefined, which means the object is ready to be placed into service.\n * A Promise that resolves to one of the above two values (undefined or Error).\n */\nexport type OnSuccessCallback<T, M> = (value: T, injector: Injector, id: InjectableId<T>, maker: M) => Promise<Error | void> | Error | void;\n\n/**\n * An interface allowing binding of an error handler.\n *\n * @see OnErrorCallback\n */\nexport interface BindErrHandler<T, M> {\n\tonError(cb: OnErrorCallback<T, M>): void;\n}\n\n/**\n * An interface allowing binding of a post construction handler.\n *\n * @see OnSuccessCallback\n */\nexport interface BindHandler<T, M> extends BindErrHandler<T, M> {\n\tonSuccess(cb: OnSuccessCallback<T, M>): BindErrHandler<T, M>;\n}\n\n/**\n * @inheritDoc\n * This specialization also allows you to specify that the binding is 'Singleton' (e.g. only one in the system).\n */\nexport interface BindAs<T, M> extends BindHandler<T, M> {\n\tasSingleton(): BindHandler<T, M>;\n}\n\n/**\n * Bind Ids to producers.\n */\nexport interface Binder extends Injector {\n\n\t/**\n\t * Bind an InjectableId to a constant value.\n\t * Constants are by their very nature singleton, and are assumed to be error proof.\n\t */\n\tbindConstant<T>(id: InjectableId<T>, value: T): void;\n\n\t/**\n\t * Bind an InjectableId to a class (actually it's constructor).\n\t * As a shortcut, you may use the class constructor as the 'id' (e.g. container.bindClass(A); ).\n\t * The container will also invoke any `@PostConstruct` present on the class.\n\t */\n\tbindClass<T>(id: ClassConstructor<T>, constructor?: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\n\tbindClass<T>(id: string | symbol | AbstractConstructor<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\n\t/**\n\t * Bind an InjectableId to a synchronous factory that will be invoked on demand when the object is needed.\n\t * The factory should produce the needed value\n\t * NOTE: The container will not invoke any `@PostConstruct` present on the class, this is the responsibility of the factory.\n\t */\n\tbindFactory<T>(id: InjectableId<T>, factory: SyncFactory<T>): BindAs<T, SyncFactory<T>>;\n\n\t/**\n\t * Bind an InjectableId to an asynchronous factory that will be invoked on demand when the object is needed.\n\t * The factory should produce the needed value (asynchronously of course).\n\t * NOTE: The container will not invoke any `@PostConstruct` present on the class, this is the responsibility of the factory.\n\t * WARNING!!! The factory may not throw and must return a valid Promise (which can be pending, resolved, rejected, etc.).\n\t */\n\tbindAsyncFactory<T>(id: InjectableId<T>, factory: AsyncFactory<T>): BindAs<T, AsyncFactory<T>>;\n\n\t/**\n\t * This essentially pre creates/loads all *singleton* InjectableIds currently known to the Binder.\n\t * This *may* be helpful if you wish to use Injector.get on a dependency tree that has asynchronous singletons within the tree.\n\t *\n\t * @param asyncOnly Only resolve AsyncFactorys as well as any bound classes that have an asynchronous `@PostConstruct` decorator. WARNING: If true, SyncFactorys will *not* be resolved even if they are Singletons.\n\t * @param parentRecursion If true and the the container has a parent, resolveIfSingleton will first be called for the parent\n\t * @returns A Promise that resolves when all Singleton's have been resolved, OR rejects if one or more of the Singleton's failed to resolve. NOTE: Rejection does not occur until all Singleton resolutions have settled, and the rejection reason/err will be a Map<InjectableId, Error>\n\t */\n\tresolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this>;\n}\n"]}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { BindableProvider } from './bindable-provider';
|
|
2
2
|
import { ClassConstructor, InjectableId, Injector } from './injector';
|
|
3
3
|
import { State } from './state';
|
|
4
|
-
|
|
4
|
+
interface StateResolvingInjector extends Injector {
|
|
5
|
+
resolveState<T>(id: InjectableId<T>): State<T>;
|
|
6
|
+
}
|
|
5
7
|
/**
|
|
6
8
|
* @inheritDoc
|
|
7
9
|
* This specialization invokes it's configured class constructor synchronously and then scans for (and invokes) any @PostConstruct (which may be synchronous or asynchronous).
|
|
8
10
|
*/
|
|
9
11
|
export declare class ClassBasedProvider<T> extends BindableProvider<T, ClassConstructor<T>> {
|
|
10
|
-
|
|
11
|
-
constructor(injector: Injector, id: InjectableId<T>, maker: ClassConstructor<T>, stateResolver: ResolveStateCallback);
|
|
12
|
+
constructor(injector: StateResolvingInjector, id: InjectableId<T>, maker: ClassConstructor<T>);
|
|
12
13
|
/**
|
|
13
14
|
* @inheritDoc
|
|
14
15
|
* @see the class description for this Provider.
|
|
@@ -33,3 +34,4 @@ export declare class ClassBasedProvider<T> extends BindableProvider<T, ClassCons
|
|
|
33
34
|
*/
|
|
34
35
|
private provideAsStateImpl;
|
|
35
36
|
}
|
|
37
|
+
export {};
|
|
@@ -11,9 +11,8 @@ const utils_1 = require("./utils");
|
|
|
11
11
|
* This specialization invokes it's configured class constructor synchronously and then scans for (and invokes) any @PostConstruct (which may be synchronous or asynchronous).
|
|
12
12
|
*/
|
|
13
13
|
class ClassBasedProvider extends bindable_provider_1.BindableProvider {
|
|
14
|
-
constructor(injector, id, maker
|
|
14
|
+
constructor(injector, id, maker) {
|
|
15
15
|
super(injector, id, maker);
|
|
16
|
-
this.stateResolver = stateResolver;
|
|
17
16
|
}
|
|
18
17
|
/**
|
|
19
18
|
* @inheritDoc
|
|
@@ -81,7 +80,7 @@ class ClassBasedProvider extends bindable_provider_1.BindableProvider {
|
|
|
81
80
|
}
|
|
82
81
|
}
|
|
83
82
|
// The post construction method says it will let us know when it's finished.
|
|
84
|
-
if (result && (result instanceof Promise || (maybeAsync && utils_1.isPromise(result)))) {
|
|
83
|
+
if (result && (result instanceof Promise || (maybeAsync && (0, utils_1.isPromise)(result)))) {
|
|
85
84
|
// Return a State that is pending (the other return statements in this method return a State which is resolved or rejected).
|
|
86
85
|
return state_1.State.MakeState(this.makePromiseForObj(result, () => obj));
|
|
87
86
|
}
|
|
@@ -104,13 +103,13 @@ class ClassBasedProvider extends bindable_provider_1.BindableProvider {
|
|
|
104
103
|
throw new Error(`Injection error. Recursive dependency in constructor for ${this.maker.toString()} at index ${index}`);
|
|
105
104
|
}
|
|
106
105
|
// Check if an Inject annotation precedes the parameter.
|
|
107
|
-
const overrideToken = decorators_1._getInjectedIdAt(this.maker, index);
|
|
106
|
+
const overrideToken = (0, decorators_1._getInjectedIdAt)(this.maker, index);
|
|
108
107
|
const actualToken = overrideToken === undefined ? argType : overrideToken;
|
|
109
|
-
// Ask our
|
|
110
|
-
let param = this.
|
|
108
|
+
// Ask our container to resolve the parameter.
|
|
109
|
+
let param = this.injector.resolveState(actualToken);
|
|
111
110
|
// If the parameter could not be resolved, see if there is an @Optional annotation
|
|
112
111
|
if ((!param.pending) && param.rejected) {
|
|
113
|
-
const md = decorators_1._getOptionalDefaultAt(this.maker, index);
|
|
112
|
+
const md = (0, decorators_1._getOptionalDefaultAt)(this.maker, index);
|
|
114
113
|
if (md)
|
|
115
114
|
param = state_1.State.MakeState(null, undefined, md.value);
|
|
116
115
|
}
|
|
@@ -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';\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\nexport type ResolveStateCallback = (id: InjectableId<any>) => State;\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: Injector, id: InjectableId<T>, maker: ClassConstructor<T>, protected stateResolver: ResolveStateCallback) {\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} else {\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\treturn State.MakeState<T>(this.makePromiseForObj<void>(result, () => obj));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// No PostConstruct, just return a resolved State\n\t\treturn State.MakeState<T>(null, undefined, obj);\n\t}\n\n\t/**\n\t * This method collects the States of all the constructor parameters for our target class.\n\t */\n\tprotected getConstructorParameterStates(): State[] {\n\t\tconst argTypes = Reflect.getMetadata(REFLECT_PARAMS, this.maker);\n\t\tif (argTypes === undefined || !Array.isArray(argTypes)) {\n\t\t\treturn [];\n\t\t}\n\t\treturn argTypes.map((argType, index) => {\n\t\t\t// The reflect-metadata API fails on circular dependencies, and will return undefined for the argument instead.\n\t\t\tif (argType === undefined) {\n\t\t\t\tthrow new Error(`Injection error. Recursive dependency in constructor for ${this.maker.toString()} at index ${index}`);\n\t\t\t}\n\t\t\t// Check if an Inject annotation precedes the parameter.\n\t\t\tconst overrideToken = _getInjectedIdAt(this.maker, index);\n\t\t\tconst actualToken = overrideToken === undefined ? argType : overrideToken;\n\t\t\t// Ask our configured container to resolve the parameter.\n\t\t\tlet param = this.stateResolver(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)) 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>(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":";;;AAAA,2DAAqD;AACrD,2CAA8G;AAC9G,6CAAqE;AAErE,mCAA8B;AAC9B,mCAAkC;AAYlC;;;GAGG;AACH,MAAa,kBAAsB,SAAQ,oCAAwC;IAClF,YAAY,QAAgC,EAAE,EAAmB,EAAE,KAA0B;QAC5F,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,cAAc;QACb,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE;YACZ,MAAM,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;SACnC;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,CAAC,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,WAAW,CAAC,4CAAgC,EAAE,IAAI,CAAC,KAAK,CAAC;YACpF,OAAO,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACxC,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;OAEG;IACO,sBAAsB,CAAC,GAAM;;QACtC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,WAAW,EAAE;YACxE,IAAI,UAAU,GAAG,KAAK,CAAC;YACvB,IAAI,IAAgD,CAAC;YACrD,IAAI,OAAO,IAAI,CAAC,cAAc,KAAK,UAAU,EAAE;gBAC9C,UAAU,GAAG,IAAI,CAAC;gBAClB,IAAI,GAAG,GAAG,EAAE;oBACX,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBACrE,CAAC,CAAC;aACF;iBACI;gBACJ,kGAAkG;gBAClG,iFAAiF;gBACjF,IAAI,aAAa,GAAW,OAAO,CAAC,WAAW,CAAC,2CAA+B,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;gBAClG,IAAI,CAAC,aAAa,EAAE;oBACnB,UAAU,GAAG,IAAI,CAAC;oBAClB,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,4CAAgC,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;iBACvF;gBACD,IAAI,aAAa,IAAI,GAAG,CAAC,WAAW,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,OAAO,GAAG,CAAC,WAAW,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,UAAU;oBAC9H,IAAI,GAAG,MAAA,MAAA,GAAG,CAAC,aAAa,CAAC,EAAC,IAAI,mDAAG,GAAG,CAAC,CAAC;gBAEvC,iGAAiG;aACjG;YACD,IAAI,IAAI,EAAE;gBACT,IAAI,MAAW,CAAC;gBAChB,IAAI;oBACH,MAAM,GAAG,IAAI,EAAE,CAAC;iBAChB;gBACD,OAAO,GAAG,EAAE;oBACX,0GAA0G;oBAC1G,IAAI;wBACH,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,uDAAuD;wBAC/F,OAAO,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;qBAChD;oBACD,OAAO,CAAC,EAAE;wBACT,0CAA0C;wBAC1C,OAAO,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;qBAC9C;iBACD;gBACD,4EAA4E;gBAC5E,IAAI,MAAM,IAAI,CAAC,MAAM,YAAY,OAAO,IAAI,CAAC,UAAU,IAAI,IAAA,iBAAS,EAAO,MAAM,CAAC,CAAC,CAAC,EAAE;oBACrF,4HAA4H;oBAC5H,OAAO,aAAK,CAAC,SAAS,CAAI,IAAI,CAAC,iBAAiB,CAAO,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;iBAC3E;aACD;SACD;QACD,iDAAiD;QACjD,OAAO,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACO,6BAA6B;QACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,0BAAc,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACjE,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YACvD,OAAO,EAAE,CAAC;SACV;QACD,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;YACtC,+GAA+G;YAC/G,IAAI,OAAO,KAAK,SAAS,EAAE;gBAC1B,MAAM,IAAI,KAAK,CAAC,4DAA4D,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,aAAa,KAAK,EAAE,CAAC,CAAC;aACvH;YACD,wDAAwD;YACxD,MAAM,aAAa,GAAG,IAAA,6BAAgB,EAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC1D,MAAM,WAAW,GAAG,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;YAC1E,8CAA8C;YAC9C,IAAI,KAAK,GAAI,IAAI,CAAC,QAAmC,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;YAChF,kFAAkF;YAClF,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE;gBACvC,MAAM,EAAE,GAAG,IAAA,kCAAqB,EAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;gBACpD,IAAI,EAAE;oBACL,KAAK,GAAG,aAAK,CAAC,SAAS,CAAM,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;aACzD;YACD,OAAO,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,kBAAkB;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,6BAA6B,EAAE,CAAC;QAEpD,qEAAqE;QACrE,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;YACxC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;QACnC,CAAC,CAAC,CAAC;QACH,IAAI,cAAc,EAAE;YACnB,OAAO,cAA0B,CAAC;SAClC;QACD,qHAAqH;QACrH,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACzC,OAAO,CAAC,CAAC,OAAO,CAAC;QAClB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACZ,OAAO,CAAC,CAAC,OAAO,CAAC;QAClB,CAAC,CAAC,CAAC;QACH,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;YAC7B,qHAAqH;YACrH,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAQ,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE;gBACjF,+DAA+D;gBAC/D,oDAAoD;gBACpD,OAAO,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAoB,CAAC,CAAM,CAAC;YACtF,CAAC,CAAC,CAAC;YACH,4GAA4G;YAC5G,OAAO,aAAK,CAAC,SAAS,CAAI,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;gBACjD,MAAM,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;gBAC/C,IAAI,KAAK,CAAC,OAAO,EAAE;oBAClB,OAAO,KAAK,CAAC,OAAO,CAAC,CAAG,8BAA8B;iBACtD;qBACI,IAAI,KAAK,CAAC,QAAQ,EAAE;oBACxB,+DAA+D;oBAC/D,OAAO,KAAK,CAAC,QAAe,CAAC,CAAC,QAAQ;iBACtC;qBACI;oBACJ,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,mBAAmB;iBAC3C;YACF,CAAC,CAAC,CAAC,CAAC;SACJ;aACI;YACJ,gFAAgF;YAChF,IAAI;gBACH,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAoB,CAAC,CAAC,CAAC;gBACxF,OAAO,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;aAC3C;YACD,OAAO,GAAG,EAAE;gBACX,0EAA0E;gBAC1E,IAAI;oBACH,OAAO,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;iBACxE;gBACD,OAAO,CAAC,EAAE;oBACT,0CAA0C;oBAC1C,OAAO,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;iBAC9C;aACD;SACD;IACF,CAAC;CACD;AA1KD,gDA0KC","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> {\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\treturn State.MakeState<T>(this.makePromiseForObj<void>(result, () => obj));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// No PostConstruct, just return a resolved State\n\t\treturn State.MakeState<T>(null, undefined, obj);\n\t}\n\n\t/**\n\t * This method collects the States of all the constructor parameters for our target class.\n\t */\n\tprotected getConstructorParameterStates(): State[] {\n\t\tconst argTypes = Reflect.getMetadata(REFLECT_PARAMS, this.maker);\n\t\tif (argTypes === undefined || !Array.isArray(argTypes)) {\n\t\t\treturn [];\n\t\t}\n\t\treturn argTypes.map((argType, index) => {\n\t\t\t// The reflect-metadata API fails on circular dependencies, and will return undefined for the argument instead.\n\t\t\tif (argType === undefined) {\n\t\t\t\tthrow new Error(`Injection error. Recursive dependency in constructor for ${this.maker.toString()} at index ${index}`);\n\t\t\t}\n\t\t\t// Check if an Inject annotation precedes the parameter.\n\t\t\tconst overrideToken = _getInjectedIdAt(this.maker, index);\n\t\t\tconst actualToken = overrideToken === undefined ? argType : overrideToken;\n\t\t\t// Ask our container to resolve the parameter.\n\t\t\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)) 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>(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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constant-provider.js","sourceRoot":"","sources":["../../src/constant-provider.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"constant-provider.js","sourceRoot":"","sources":["../../src/constant-provider.ts"],"names":[],"mappings":";;;AAAA,yCAAoC;AACpC,mCAA8B;AAE9B;;;GAGG;AACH,MAAa,gBAAoB,SAAQ,mBAAW;IACnD,YAAY,QAAW;QACtB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,SAAS,GAAG,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAChE,CAAC;IAED,cAAc;QACb,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;CACD;AATD,4CASC","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"]}
|
package/lib/cjs/constants.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export declare const INJECTABLE_METADATA_KEY: unique symbol;
|
|
|
2
2
|
export declare const INJECT_METADATA_KEY: unique symbol;
|
|
3
3
|
export declare const POSTCONSTRUCT_SYNC_METADATA_KEY: unique symbol;
|
|
4
4
|
export declare const POSTCONSTRUCT_ASYNC_METADATA_KEY: unique symbol;
|
|
5
|
+
export declare const RELEASE_METADATA_KEY: unique symbol;
|
|
5
6
|
export declare const OPTIONAL_METADATA_KEY: unique symbol;
|
|
6
7
|
export declare const REFLECT_PARAMS = "design:paramtypes";
|
|
7
8
|
export declare const REFLECT_RETURN = "design:returntype";
|
package/lib/cjs/constants.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.REFLECT_RETURN = exports.REFLECT_PARAMS = exports.OPTIONAL_METADATA_KEY = exports.POSTCONSTRUCT_ASYNC_METADATA_KEY = exports.POSTCONSTRUCT_SYNC_METADATA_KEY = exports.INJECT_METADATA_KEY = exports.INJECTABLE_METADATA_KEY = void 0;
|
|
3
|
+
exports.REFLECT_RETURN = exports.REFLECT_PARAMS = exports.OPTIONAL_METADATA_KEY = exports.RELEASE_METADATA_KEY = exports.POSTCONSTRUCT_ASYNC_METADATA_KEY = exports.POSTCONSTRUCT_SYNC_METADATA_KEY = exports.INJECT_METADATA_KEY = exports.INJECTABLE_METADATA_KEY = void 0;
|
|
4
4
|
exports.INJECTABLE_METADATA_KEY = Symbol('INJECTABLE_KEY');
|
|
5
5
|
exports.INJECT_METADATA_KEY = Symbol('INJECT_KEY');
|
|
6
6
|
exports.POSTCONSTRUCT_SYNC_METADATA_KEY = Symbol('POSTCONSTRUCT_SYNC_KEY');
|
|
7
7
|
exports.POSTCONSTRUCT_ASYNC_METADATA_KEY = Symbol('POSTCONSTRUCT_ASYNC_KEY');
|
|
8
|
+
exports.RELEASE_METADATA_KEY = Symbol('RELEASE_KEY');
|
|
8
9
|
exports.OPTIONAL_METADATA_KEY = Symbol('OPTIONAL_KEY');
|
|
9
10
|
exports.REFLECT_PARAMS = 'design:paramtypes';
|
|
10
11
|
exports.REFLECT_RETURN = 'design:returntype';
|
package/lib/cjs/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,uBAAuB,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AACnD,QAAA,mBAAmB,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AAC3C,QAAA,+BAA+B,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;AACnE,QAAA,gCAAgC,GAAG,MAAM,CAAC,yBAAyB,CAAC,CAAC;AACrE,QAAA,qBAAqB,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AAE/C,QAAA,cAAc,GAAG,mBAAmB,CAAC;AACrC,QAAA,cAAc,GAAG,mBAAmB,CAAC","sourcesContent":["export const INJECTABLE_METADATA_KEY = Symbol('INJECTABLE_KEY');\nexport const INJECT_METADATA_KEY = Symbol('INJECT_KEY');\nexport const POSTCONSTRUCT_SYNC_METADATA_KEY = Symbol('POSTCONSTRUCT_SYNC_KEY');\nexport const POSTCONSTRUCT_ASYNC_METADATA_KEY = Symbol('POSTCONSTRUCT_ASYNC_KEY');\nexport const OPTIONAL_METADATA_KEY = Symbol('OPTIONAL_KEY');\n\nexport const REFLECT_PARAMS = 'design:paramtypes';\nexport const REFLECT_RETURN = 'design:returntype';\n"]}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,uBAAuB,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AACnD,QAAA,mBAAmB,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AAC3C,QAAA,+BAA+B,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;AACnE,QAAA,gCAAgC,GAAG,MAAM,CAAC,yBAAyB,CAAC,CAAC;AACrE,QAAA,oBAAoB,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;AAC7C,QAAA,qBAAqB,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AAE/C,QAAA,cAAc,GAAG,mBAAmB,CAAC;AACrC,QAAA,cAAc,GAAG,mBAAmB,CAAC","sourcesContent":["export const INJECTABLE_METADATA_KEY = Symbol('INJECTABLE_KEY');\nexport const INJECT_METADATA_KEY = Symbol('INJECT_KEY');\nexport const POSTCONSTRUCT_SYNC_METADATA_KEY = Symbol('POSTCONSTRUCT_SYNC_KEY');\nexport const POSTCONSTRUCT_ASYNC_METADATA_KEY = Symbol('POSTCONSTRUCT_ASYNC_KEY');\nexport const RELEASE_METADATA_KEY = Symbol('RELEASE_KEY');\nexport const OPTIONAL_METADATA_KEY = Symbol('OPTIONAL_KEY');\n\nexport const REFLECT_PARAMS = 'design:paramtypes';\nexport const REFLECT_RETURN = 'design:returntype';\n"]}
|
package/lib/cjs/container.d.ts
CHANGED
|
@@ -30,8 +30,9 @@ export declare class Container implements Binder {
|
|
|
30
30
|
*
|
|
31
31
|
* @param id The id to be removed.
|
|
32
32
|
* @param ascending If true, this will remove all bindings of the specified id all the way up the parent container chain (if it exists).
|
|
33
|
+
* @param releaseIfSingleton If true, @Provider.releaseIfSingleton will be invoked before the binding is removed.
|
|
33
34
|
*/
|
|
34
|
-
removeBinding<T>(id: InjectableId<T>, ascending?: boolean): void;
|
|
35
|
+
removeBinding<T>(id: InjectableId<T>, ascending?: boolean, releaseIfSingleton?: boolean): void;
|
|
35
36
|
/**
|
|
36
37
|
* @inheritDoc
|
|
37
38
|
*/
|
|
@@ -52,10 +53,37 @@ export declare class Container implements Binder {
|
|
|
52
53
|
/**
|
|
53
54
|
* @inheritDoc
|
|
54
55
|
*/
|
|
55
|
-
resolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<
|
|
56
|
+
resolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this>;
|
|
56
57
|
/**
|
|
57
58
|
* As implied by the name prefix, this is a factored out method invoked only by the 'resolve' method.
|
|
58
59
|
* It makes searching our parent (if it exists) easier (and quicker) IF our parent is a fellow instance of Container.
|
|
59
60
|
*/
|
|
60
61
|
protected resolveState<T>(id: InjectableId<T>): State<T>;
|
|
62
|
+
/**
|
|
63
|
+
* Convenience method to assist in releasing non-garbage-collectable resources that Singletons in this Container may have allocated.
|
|
64
|
+
* It will walk through all registered Providers (of this Container only), and invoke their @see Provider.releaseIfSingleton method.
|
|
65
|
+
* This method is not part of the Binding interface, because you normally only create (and release) Containers.
|
|
66
|
+
* NOTE:
|
|
67
|
+
* This *only* releases active/pending Singleton's that have already been created by this Container.
|
|
68
|
+
* The most likely use of this method would be when you have created a new child Container for a limited duration transaction, and you want to easily cleanup temporary resources.
|
|
69
|
+
* For example, your service object may need to know when it should unsubscribe from an RxJs stream (failure to do so can result in your Singleton not being garbage collected at the end of a transaction).
|
|
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
|
+
*/
|
|
72
|
+
releaseSingletons(): void;
|
|
73
|
+
/**
|
|
74
|
+
* Make a copy of this @see Container.
|
|
75
|
+
* This is an experimental feature!
|
|
76
|
+
* I have not thought through all the dark corners, so use at your own peril!
|
|
77
|
+
* Here are some notes:
|
|
78
|
+
* The injector parameter for SyncFactory and AsyncFactory callbacks will be the Container invoking the factory.
|
|
79
|
+
* So a factory that uses a parent closure instead of the supplied injector may get unexpected results.
|
|
80
|
+
* The injector parameter for OnSuccess and OnError callbacks will be the Container performing the resolution.
|
|
81
|
+
* Singletons are cloned at their *existing* state..
|
|
82
|
+
* If resolved in "this" container, they will not be re-resolved for the clone.
|
|
83
|
+
* If released by the clone, they will be considered released by "this" container.
|
|
84
|
+
* If a singleton is currently being asynchronously constructed any callbacks will reference "this" Container, however both Containers should have no problem awaiting resolution.
|
|
85
|
+
* If a singleton is not resolved when the container is cloned, then if both containers resolve, you will create *two* "singletons".
|
|
86
|
+
* The way to avoid this last effect is to @see resolveSingletons
|
|
87
|
+
*/
|
|
88
|
+
clone(clazz?: ClassConstructor<Container>): Container;
|
|
61
89
|
}
|
package/lib/cjs/container.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Container = void 0;
|
|
4
4
|
const async_factory_provider_1 = require("./async-factory-provider");
|
|
5
|
+
const bindable_provider_1 = require("./bindable-provider");
|
|
5
6
|
const class_provider_1 = require("./class-provider");
|
|
6
7
|
const constant_provider_1 = require("./constant-provider");
|
|
7
8
|
const constants_1 = require("./constants");
|
|
@@ -61,7 +62,7 @@ class Container {
|
|
|
61
62
|
*/
|
|
62
63
|
resolve(id) {
|
|
63
64
|
const state = this.resolveState(id);
|
|
64
|
-
if (utils_1.isPromise(state.promise)) {
|
|
65
|
+
if ((0, utils_1.isPromise)(state.promise)) {
|
|
65
66
|
return state.promise;
|
|
66
67
|
}
|
|
67
68
|
if (state.rejected) {
|
|
@@ -76,13 +77,19 @@ class Container {
|
|
|
76
77
|
*
|
|
77
78
|
* @param id The id to be removed.
|
|
78
79
|
* @param ascending If true, this will remove all bindings of the specified id all the way up the parent container chain (if it exists).
|
|
80
|
+
* @param releaseIfSingleton If true, @Provider.releaseIfSingleton will be invoked before the binding is removed.
|
|
79
81
|
*/
|
|
80
|
-
removeBinding(id, ascending) {
|
|
82
|
+
removeBinding(id, ascending, releaseIfSingleton) {
|
|
81
83
|
var _a;
|
|
84
|
+
if (releaseIfSingleton) {
|
|
85
|
+
const p = this.providers.get(id);
|
|
86
|
+
if (p)
|
|
87
|
+
p.releaseIfSingleton();
|
|
88
|
+
}
|
|
82
89
|
this.providers.delete(id);
|
|
83
90
|
if (ascending && this.parent) {
|
|
84
91
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
85
|
-
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.removeBinding(id, true);
|
|
92
|
+
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.removeBinding(id, true, releaseIfSingleton);
|
|
86
93
|
}
|
|
87
94
|
}
|
|
88
95
|
/**
|
|
@@ -98,9 +105,7 @@ class Container {
|
|
|
98
105
|
if (!Reflect.getMetadata(constants_1.INJECTABLE_METADATA_KEY, constructor)) {
|
|
99
106
|
throw new Error('Class not decorated with @Injectable [' + constructor.toString() + ']');
|
|
100
107
|
}
|
|
101
|
-
const provider = new class_provider_1.ClassBasedProvider(this, id, constructor
|
|
102
|
-
return this.resolveState(i);
|
|
103
|
-
});
|
|
108
|
+
const provider = new class_provider_1.ClassBasedProvider(this, id, constructor);
|
|
104
109
|
this.providers.set(id, provider);
|
|
105
110
|
return provider.makeBindAs();
|
|
106
111
|
}
|
|
@@ -158,13 +163,13 @@ class Container {
|
|
|
158
163
|
});
|
|
159
164
|
});
|
|
160
165
|
};
|
|
161
|
-
if (parentRecursion && typeof ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.resolveSingletons) ===
|
|
166
|
+
if (parentRecursion && typeof ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.resolveSingletons) === 'function') {
|
|
162
167
|
const pb = this.parent;
|
|
163
168
|
return pb.resolveSingletons(asyncOnly, parentRecursion).then(() => {
|
|
164
|
-
return makePromiseToResolve();
|
|
169
|
+
return makePromiseToResolve().then(() => this);
|
|
165
170
|
});
|
|
166
171
|
}
|
|
167
|
-
return makePromiseToResolve();
|
|
172
|
+
return makePromiseToResolve().then(() => this);
|
|
168
173
|
}
|
|
169
174
|
/**
|
|
170
175
|
* As implied by the name prefix, this is a factored out method invoked only by the 'resolve' method.
|
|
@@ -190,6 +195,51 @@ class Container {
|
|
|
190
195
|
}
|
|
191
196
|
return provider.provideAsState();
|
|
192
197
|
}
|
|
198
|
+
// noinspection JSUnusedGlobalSymbols
|
|
199
|
+
/**
|
|
200
|
+
* Convenience method to assist in releasing non-garbage-collectable resources that Singletons in this Container may have allocated.
|
|
201
|
+
* It will walk through all registered Providers (of this Container only), and invoke their @see Provider.releaseIfSingleton method.
|
|
202
|
+
* This method is not part of the Binding interface, because you normally only create (and release) Containers.
|
|
203
|
+
* NOTE:
|
|
204
|
+
* This *only* releases active/pending Singleton's that have already been created by this Container.
|
|
205
|
+
* The most likely use of this method would be when you have created a new child Container for a limited duration transaction, and you want to easily cleanup temporary resources.
|
|
206
|
+
* For example, your service object may need to know when it should unsubscribe from an RxJs stream (failure to do so can result in your Singleton not being garbage collected at the end of a transaction).
|
|
207
|
+
* In theory, you could handle all unsubscription and cleanup yourself, but the @Release decorator and this method are meant to simply make that easier.
|
|
208
|
+
*/
|
|
209
|
+
releaseSingletons() {
|
|
210
|
+
this.providers.forEach((value) => {
|
|
211
|
+
value.releaseIfSingleton();
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Make a copy of this @see Container.
|
|
216
|
+
* This is an experimental feature!
|
|
217
|
+
* I have not thought through all the dark corners, so use at your own peril!
|
|
218
|
+
* Here are some notes:
|
|
219
|
+
* The injector parameter for SyncFactory and AsyncFactory callbacks will be the Container invoking the factory.
|
|
220
|
+
* So a factory that uses a parent closure instead of the supplied injector may get unexpected results.
|
|
221
|
+
* The injector parameter for OnSuccess and OnError callbacks will be the Container performing the resolution.
|
|
222
|
+
* Singletons are cloned at their *existing* state..
|
|
223
|
+
* If resolved in "this" container, they will not be re-resolved for the clone.
|
|
224
|
+
* If released by the clone, they will be considered released by "this" container.
|
|
225
|
+
* If a singleton is currently being asynchronously constructed any callbacks will reference "this" Container, however both Containers should have no problem awaiting resolution.
|
|
226
|
+
* If a singleton is not resolved when the container is cloned, then if both containers resolve, you will create *two* "singletons".
|
|
227
|
+
* The way to avoid this last effect is to @see resolveSingletons
|
|
228
|
+
*/
|
|
229
|
+
clone(clazz) {
|
|
230
|
+
if (!clazz)
|
|
231
|
+
clazz = Container;
|
|
232
|
+
const retVal = new clazz(this.parent);
|
|
233
|
+
this.providers.forEach((v, k) => {
|
|
234
|
+
if (v instanceof bindable_provider_1.BindableProvider) {
|
|
235
|
+
v = Object.assign(Object.create(Object.getPrototypeOf(v)), v);
|
|
236
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
237
|
+
v.injector = retVal;
|
|
238
|
+
}
|
|
239
|
+
retVal.providers.set(k, v);
|
|
240
|
+
});
|
|
241
|
+
return retVal;
|
|
242
|
+
}
|
|
193
243
|
}
|
|
194
244
|
exports.Container = Container;
|
|
195
245
|
//# sourceMappingURL=container.js.map
|