async-injection 2.3.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/ReadMe.md +133 -194
  2. package/lib/async-factory-provider.d.ts +1 -1
  3. package/lib/bindable-provider.d.ts +2 -2
  4. package/lib/binding.d.ts +80 -0
  5. package/lib/cjs/async-factory-provider.js.map +1 -1
  6. package/lib/cjs/bindable-provider.js +5 -18
  7. package/lib/cjs/bindable-provider.js.map +1 -1
  8. package/lib/cjs/{binder.js → binding.js} +1 -1
  9. package/lib/cjs/binding.js.map +1 -0
  10. package/lib/cjs/class-provider.js +142 -39
  11. package/lib/cjs/class-provider.js.map +1 -1
  12. package/lib/cjs/container.js +62 -22
  13. package/lib/cjs/container.js.map +1 -1
  14. package/lib/cjs/decorators.js +61 -17
  15. package/lib/cjs/decorators.js.map +1 -1
  16. package/lib/cjs/index.js.map +1 -1
  17. package/lib/cjs/injector.js.map +1 -1
  18. package/lib/cjs/provider.js.map +1 -1
  19. package/lib/cjs/sync-factory-provider.js.map +1 -1
  20. package/lib/class-provider.d.ts +16 -2
  21. package/lib/container.d.ts +40 -14
  22. package/lib/decorators.d.ts +15 -2
  23. package/lib/esm/async-factory-provider.js.map +1 -1
  24. package/lib/esm/bindable-provider.js +5 -18
  25. package/lib/esm/bindable-provider.js.map +1 -1
  26. package/lib/esm/binding.js +2 -0
  27. package/lib/esm/binding.js.map +1 -0
  28. package/lib/esm/class-provider.js +143 -40
  29. package/lib/esm/class-provider.js.map +1 -1
  30. package/lib/esm/container.js +62 -22
  31. package/lib/esm/container.js.map +1 -1
  32. package/lib/esm/decorators.js +60 -18
  33. package/lib/esm/decorators.js.map +1 -1
  34. package/lib/esm/index.js.map +1 -1
  35. package/lib/esm/injector.js.map +1 -1
  36. package/lib/esm/provider.js.map +1 -1
  37. package/lib/esm/sync-factory-provider.js.map +1 -1
  38. package/lib/index.d.ts +1 -0
  39. package/lib/injector.d.ts +1 -1
  40. package/lib/sync-factory-provider.d.ts +1 -1
  41. package/package.json +1 -1
  42. package/lib/binder.d.ts +0 -110
  43. package/lib/cjs/binder.js.map +0 -1
  44. package/lib/esm/binder.js +0 -2
  45. package/lib/esm/binder.js.map +0 -1
@@ -30,64 +30,167 @@ class ClassBasedProvider extends bindable_provider_1.BindableProvider {
30
30
  }
31
31
  /**
32
32
  * @inheritDoc
33
- * This specialization returns undefined if 'asyncOnly' is true and there is no asynchronous PostConstruct annotation (since class constructors can never by asynchronous).
33
+ * This specialization returns undefined if 'asyncOnly' is true **and** there is no asynchronous PostConstruct annotation (since class constructors can never by asynchronous),
34
+ * **unless** the @PostConstruct method has injectable parameters, which may themselves require async resolution.
34
35
  */
35
36
  resolveIfSingleton(asyncOnly) {
36
- if ((!asyncOnly) || Reflect.getMetadata(constants_1.POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker))
37
+ if (!asyncOnly || Reflect.getMetadata(constants_1.POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker) || this.postConstructHasParams())
37
38
  return super.resolveIfSingleton(false);
38
39
  return undefined;
39
40
  }
40
41
  /**
41
- * Make a resolved or pending State that reflects any @PostConstruct annotations.
42
+ * Returns true if the @PostConstruct method (if any) has at least one parameter.
43
+ * Any parameter may require async resolution, so this class must participate in resolveSingletons.
44
+ */
45
+ postConstructHasParams() {
46
+ var _a;
47
+ const pcMethod = (_a = Reflect.getMetadata(constants_1.POSTCONSTRUCT_SYNC_METADATA_KEY, this.maker)) !== null && _a !== void 0 ? _a : Reflect.getMetadata(constants_1.POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker);
48
+ if (!pcMethod)
49
+ return false;
50
+ const paramTypes = Reflect.getMetadata(constants_1.REFLECT_PARAMS, this.maker.prototype, pcMethod);
51
+ return Array.isArray(paramTypes) && paramTypes.length > 0;
52
+ }
53
+ /**
54
+ * Make a resolved or pending State that reflects any @PostConstruct annotations and/or onSuccess handler.
55
+ * Any @PostConstruct method (with any injected parameters) runs first; the onSuccess handler runs after.
42
56
  */
43
57
  makePostConstructState(obj) {
44
- var _a, _b;
45
- if (obj !== null && typeof obj === 'object' && (!Array.isArray(obj)) && obj.constructor) {
46
- let maybeAsync = false;
47
- let pcFn;
48
- if (typeof this.successHandler === 'function') {
49
- maybeAsync = true;
50
- pcFn = () => {
51
- return this.successHandler(obj, this.injector, this.id, this.maker);
52
- };
58
+ if (obj === null || typeof obj !== 'object' || Array.isArray(obj) || !obj.constructor) {
59
+ return state_1.State.MakeState(null, undefined, obj);
60
+ }
61
+ const ctor = obj.constructor;
62
+ // Look up the @PostConstruct method name (sync or async).
63
+ let pcMaybeAsync = false;
64
+ let pcMethodName = Reflect.getMetadata(constants_1.POSTCONSTRUCT_SYNC_METADATA_KEY, ctor);
65
+ if (!pcMethodName) {
66
+ pcMethodName = Reflect.getMetadata(constants_1.POSTCONSTRUCT_ASYNC_METADATA_KEY, ctor);
67
+ pcMaybeAsync = !!pcMethodName;
68
+ }
69
+ const pcValid = !!(pcMethodName && typeof ctor.prototype[pcMethodName] === 'function');
70
+ const hasSuccess = typeof this.successHandler === 'function';
71
+ if (!pcValid && !hasSuccess) {
72
+ return state_1.State.MakeState(null, undefined, obj);
73
+ }
74
+ // Resolve any injectable parameters declared on the @PostConstruct method.
75
+ const paramStates = pcValid ? this.getMethodParameterStates(ctor, pcMethodName) : [];
76
+ // A synchronously rejected param (with no @Optional fallback) is treated as a PostConstruct error.
77
+ const firstRejected = paramStates.find(p => !p.pending && p.rejected);
78
+ if (firstRejected) {
79
+ try {
80
+ obj = this.queryErrorHandler(firstRejected.rejected, obj);
81
+ return state_1.State.MakeState(null, undefined, obj);
53
82
  }
54
- else {
55
- // Check to see if there is a @PostConstruct annotation on a method of the class.
56
- const ctor = obj.constructor;
57
- let postConstruct = Reflect.getMetadata(constants_1.POSTCONSTRUCT_SYNC_METADATA_KEY, ctor);
58
- if (!postConstruct) {
59
- maybeAsync = true;
60
- postConstruct = Reflect.getMetadata(constants_1.POSTCONSTRUCT_ASYNC_METADATA_KEY, ctor);
61
- }
62
- if (postConstruct && ctor.prototype[postConstruct] && typeof ctor.prototype[postConstruct] === 'function')
63
- pcFn = (_b = (_a = obj[postConstruct]).bind) === null || _b === void 0 ? void 0 : _b.call(_a, obj);
83
+ catch (e) {
84
+ return state_1.State.MakeState(null, e, undefined);
64
85
  }
65
- if (pcFn) {
66
- let result;
86
+ }
87
+ if (paramStates.some(p => p.pending)) {
88
+ // One or more params require async resolution — wait for them, then invoke.
89
+ const paramsPromise = Promise.all(paramStates.map(async (p, idx) => {
90
+ if (p.pending) {
91
+ try {
92
+ return await p.promise;
93
+ }
94
+ catch (err) {
95
+ const md = (0, decorators_1._getOptionalDefaultForMethod)(ctor.prototype, pcMethodName, idx);
96
+ if (!md)
97
+ throw err;
98
+ return md.value;
99
+ }
100
+ }
101
+ return p.fulfilled;
102
+ }));
103
+ return state_1.State.MakeState((async () => {
104
+ let args;
67
105
  try {
68
- result = pcFn();
106
+ args = await paramsPromise;
69
107
  }
70
108
  catch (err) {
71
- // The post construction method threw while executing, give the errorHandler (if any) a crack at recovery.
72
- try {
73
- obj = this.queryErrorHandler(err, obj); // The returned obj is unlikely to be the original obj.
74
- return state_1.State.MakeState(null, undefined, obj);
75
- }
76
- catch (e) {
77
- // could not recover, propagate the error.
78
- return state_1.State.MakeState(null, e, undefined);
109
+ return this.queryErrorHandler(err, obj);
110
+ }
111
+ try {
112
+ const pcResult = obj[pcMethodName](...args);
113
+ if (pcResult && (pcResult instanceof Promise || (pcMaybeAsync && (0, utils_1.isPromise)(pcResult))))
114
+ await pcResult;
115
+ if (hasSuccess) {
116
+ const sResult = this.successHandler(obj, this.injector, this.id, this.maker);
117
+ if (sResult && (0, utils_1.isPromise)(sResult))
118
+ await sResult;
79
119
  }
120
+ return obj;
121
+ }
122
+ catch (err) {
123
+ return this.queryErrorHandler(err, obj);
80
124
  }
81
- // The post construction method says it will let us know when it's finished.
82
- if (result && (result instanceof Promise || (maybeAsync && (0, utils_1.isPromise)(result)))) {
83
- // Return a State that is pending (the other return statements in this method return a State which is resolved or rejected).
84
- return state_1.State.MakeState(this.makePromiseForObj(result, () => obj));
125
+ })());
126
+ }
127
+ // All params are synchronously available (or there are no params).
128
+ const pcArgs = paramStates.map(p => p.fulfilled);
129
+ const maybeAsync = pcMaybeAsync || hasSuccess;
130
+ // Build a single function that calls PostConstruct (with resolved args) then onSuccess.
131
+ let pcFn;
132
+ if (pcValid) {
133
+ pcFn = () => {
134
+ const pcResult = obj[pcMethodName](...pcArgs);
135
+ if (pcResult && (pcResult instanceof Promise || (pcMaybeAsync && (0, utils_1.isPromise)(pcResult)))) {
136
+ // PostConstruct is async — chain onSuccess after it resolves.
137
+ return hasSuccess
138
+ ? pcResult.then(() => this.successHandler(obj, this.injector, this.id, this.maker))
139
+ : pcResult;
85
140
  }
141
+ // PostConstruct is sync — call onSuccess immediately.
142
+ if (hasSuccess)
143
+ return this.successHandler(obj, this.injector, this.id, this.maker);
144
+ return pcResult;
145
+ };
146
+ }
147
+ else {
148
+ // No PostConstruct — just call onSuccess.
149
+ pcFn = () => this.successHandler(obj, this.injector, this.id, this.maker);
150
+ }
151
+ let result;
152
+ try {
153
+ result = pcFn();
154
+ }
155
+ catch (err) {
156
+ try {
157
+ obj = this.queryErrorHandler(err, obj);
158
+ return state_1.State.MakeState(null, undefined, obj);
86
159
  }
160
+ catch (e) {
161
+ return state_1.State.MakeState(null, e, undefined);
162
+ }
163
+ }
164
+ if (result && (result instanceof Promise || (maybeAsync && (0, utils_1.isPromise)(result)))) {
165
+ return state_1.State.MakeState(this.makePromiseForObj(result, () => obj));
87
166
  }
88
- // No PostConstruct, just return a resolved State
89
167
  return state_1.State.MakeState(null, undefined, obj);
90
168
  }
169
+ /**
170
+ * Collects the resolved States for all injectable parameters of a @PostConstruct method.
171
+ * Uses the same resolution rules as constructor parameters: the reflected type (or an explicit @Inject token) is used to look up the binding, and an error is thrown if the type cannot be determined.
172
+ * Use @Optional() on a parameter to supply a fallback when no binding is found.
173
+ * Returns an empty array if the method has no parameters.
174
+ */
175
+ getMethodParameterStates(ctor, methodName) {
176
+ const argTypes = Reflect.getMetadata(constants_1.REFLECT_PARAMS, ctor.prototype, methodName);
177
+ if (!Array.isArray(argTypes) || argTypes.length === 0)
178
+ return [];
179
+ return argTypes.map((argType, index) => {
180
+ const overrideToken = (0, decorators_1._getInjectedIdForMethod)(ctor.prototype, methodName, index);
181
+ const actualToken = overrideToken !== undefined ? overrideToken : argType;
182
+ if (actualToken == null) {
183
+ throw new Error(`Injection error. Unable to determine parameter ${index} type/value of ${ctor.name}.${methodName}`);
184
+ }
185
+ let param = this.injector.resolveState(actualToken);
186
+ if (!param.pending && param.rejected) {
187
+ const optionalDefault = (0, decorators_1._getOptionalDefaultForMethod)(ctor.prototype, methodName, index);
188
+ if (optionalDefault)
189
+ param = state_1.State.MakeState(null, undefined, optionalDefault.value);
190
+ }
191
+ return param;
192
+ });
193
+ }
91
194
  /**
92
195
  * This method collects the States of all the constructor parameters for our target class.
93
196
  */
@@ -165,7 +268,7 @@ class ClassBasedProvider extends bindable_provider_1.BindableProvider {
165
268
  return await state.promise; // chain (aka wait some more).
166
269
  }
167
270
  else if (state.rejected) {
168
- return state.rejected; // error
271
+ throw state.rejected; // error
169
272
  }
170
273
  else {
171
274
  return state.fulfilled; // value (aka obj).
@@ -1 +1 @@
1
- {"version":3,"file":"class-provider.js","sourceRoot":"","sources":["../../src/class-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import {BindableProvider} from './bindable-provider';\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
+ {"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, _getInjectedIdForMethod, _getOptionalDefaultAt, _getOptionalDefaultForMethod} 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 * **unless** the @PostConstruct method has injectable parameters, which may themselves require async resolution.\n\t */\n\tresolveIfSingleton(asyncOnly: boolean): Promise<T> | undefined {\n\t\tif (!asyncOnly || Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker) || this.postConstructHasParams())\n\t\t\treturn super.resolveIfSingleton(false);\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Returns true if the @PostConstruct method (if any) has at least one parameter.\n\t * Any parameter may require async resolution, so this class must participate in resolveSingletons.\n\t */\n\tprivate postConstructHasParams(): boolean {\n\t\tconst pcMethod =\n\t\t\t(Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, this.maker) as string | undefined) ??\n\t\t\t(Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, this.maker) as string | undefined);\n\t\tif (!pcMethod)\n\t\t\treturn false;\n\t\tconst paramTypes = Reflect.getMetadata(REFLECT_PARAMS, this.maker.prototype, pcMethod) as unknown[] | undefined;\n\t\treturn Array.isArray(paramTypes) && paramTypes.length > 0;\n\t}\n\n\t/**\n\t * Make a resolved or pending State that reflects any @PostConstruct annotations and/or onSuccess handler.\n\t * Any @PostConstruct method (with any injected parameters) runs first; the onSuccess handler runs after.\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\treturn State.MakeState<T>(null, undefined, obj);\n\t\t}\n\t\tconst ctor = (obj as any).constructor;\n\n\t\t// Look up the @PostConstruct method name (sync or async).\n\t\tlet pcMaybeAsync = false;\n\t\tlet pcMethodName: string | undefined = Reflect.getMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, ctor) as string | undefined;\n\t\tif (!pcMethodName) {\n\t\t\tpcMethodName = Reflect.getMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, ctor) as string | undefined;\n\t\t\tpcMaybeAsync = !!pcMethodName;\n\t\t}\n\t\tconst pcValid = !!(pcMethodName && typeof ctor.prototype[pcMethodName] === 'function');\n\t\tconst hasSuccess = typeof this.successHandler === 'function';\n\n\t\tif (!pcValid && !hasSuccess) {\n\t\t\treturn State.MakeState<T>(null, undefined, obj);\n\t\t}\n\n\t\t// Resolve any injectable parameters declared on the @PostConstruct method.\n\t\tconst paramStates = pcValid ? this.getMethodParameterStates(ctor, pcMethodName!) : [];\n\n\t\t// A synchronously rejected param (with no @Optional fallback) is treated as a PostConstruct error.\n\t\tconst firstRejected = paramStates.find(p => !p.pending && p.rejected);\n\t\tif (firstRejected) {\n\t\t\ttry {\n\t\t\t\tobj = this.queryErrorHandler(firstRejected.rejected, obj);\n\t\t\t\treturn State.MakeState<T>(null, undefined, obj);\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t}\n\t\t}\n\n\t\tif (paramStates.some(p => p.pending)) {\n\t\t\t// One or more params require async resolution — wait for them, then invoke.\n\t\t\tconst paramsPromise = Promise.all(paramStates.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\tconst md = _getOptionalDefaultForMethod(ctor.prototype, pcMethodName!, idx);\n\t\t\t\t\t\tif (!md) throw err;\n\t\t\t\t\t\treturn md.value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn p.fulfilled;\n\t\t\t}));\n\t\t\treturn State.MakeState<T>((async () => {\n\t\t\t\tlet args: any[];\n\t\t\t\ttry {\n\t\t\t\t\targs = await paramsPromise;\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\treturn this.queryErrorHandler(err, obj);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst pcResult = (obj as any)[pcMethodName!](...args);\n\t\t\t\t\tif (pcResult && (pcResult instanceof Promise || (pcMaybeAsync && isPromise(pcResult))))\n\t\t\t\t\t\tawait pcResult;\n\t\t\t\t\tif (hasSuccess) {\n\t\t\t\t\t\tconst sResult = this.successHandler!(obj, this.injector, this.id, this.maker);\n\t\t\t\t\t\tif (sResult && isPromise(sResult)) await sResult;\n\t\t\t\t\t}\n\t\t\t\t\treturn obj;\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\treturn this.queryErrorHandler(err, obj);\n\t\t\t\t}\n\t\t\t})());\n\t\t}\n\n\t\t// All params are synchronously available (or there are no params).\n\t\tconst pcArgs = paramStates.map(p => p.fulfilled);\n\t\tconst maybeAsync = pcMaybeAsync || hasSuccess;\n\n\t\t// Build a single function that calls PostConstruct (with resolved args) then onSuccess.\n\t\tlet pcFn: (() => void | Error | Promise<void | Error>) | undefined;\n\t\tif (pcValid) {\n\t\t\tpcFn = () => {\n\t\t\t\tconst pcResult = (obj as any)[pcMethodName!](...pcArgs);\n\t\t\t\tif (pcResult && (pcResult instanceof Promise || (pcMaybeAsync && isPromise<void>(pcResult)))) {\n\t\t\t\t\t// PostConstruct is async — chain onSuccess after it resolves.\n\t\t\t\t\treturn hasSuccess\n\t\t\t\t\t\t? (pcResult as Promise<void>).then(() => this.successHandler!(obj, this.injector, this.id, this.maker))\n\t\t\t\t\t\t: pcResult as Promise<void>;\n\t\t\t\t}\n\t\t\t\t// PostConstruct is sync — call onSuccess immediately.\n\t\t\t\tif (hasSuccess)\n\t\t\t\t\treturn this.successHandler!(obj, this.injector, this.id, this.maker) as void | Error | Promise<void | Error>;\n\t\t\t\treturn pcResult;\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\t// No PostConstruct — just call onSuccess.\n\t\t\tpcFn = () => this.successHandler!(obj, this.injector, this.id, this.maker) as void | Error | Promise<void | Error>;\n\t\t}\n\n\t\tlet result: any;\n\t\ttry {\n\t\t\tresult = pcFn();\n\t\t}\n\t\tcatch (err) {\n\t\t\ttry {\n\t\t\t\tobj = this.queryErrorHandler(err, obj);\n\t\t\t\treturn State.MakeState<T>(null, undefined, obj);\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\treturn State.MakeState<T>(null, e, undefined);\n\t\t\t}\n\t\t}\n\t\tif (result && (result instanceof Promise || (maybeAsync && isPromise<void>(result)))) {\n\t\t\treturn State.MakeState<T>(this.makePromiseForObj<T>(result, () => obj));\n\t\t}\n\t\treturn State.MakeState<T>(null, undefined, obj);\n\t}\n\n\t/**\n\t * Collects the resolved States for all injectable parameters of a @PostConstruct method.\n\t * Uses the same resolution rules as constructor parameters: the reflected type (or an explicit @Inject token) is used to look up the binding, and an error is thrown if the type cannot be determined.\n\t * Use @Optional() on a parameter to supply a fallback when no binding is found.\n\t * Returns an empty array if the method has no parameters.\n\t */\n\tprotected getMethodParameterStates(ctor: Function, methodName: string): State[] {\n\t\tconst argTypes = Reflect.getMetadata(REFLECT_PARAMS, ctor.prototype, methodName) as unknown[] | undefined;\n\t\tif (!Array.isArray(argTypes) || argTypes.length === 0)\n\t\t\treturn [];\n\t\treturn argTypes.map((argType, index) => {\n\t\t\tconst overrideToken = _getInjectedIdForMethod(ctor.prototype, methodName, index);\n\t\t\tconst actualToken = overrideToken !== undefined ? overrideToken : argType;\n\t\t\tif (actualToken == null) {\n\t\t\t\tthrow new Error(`Injection error. Unable to determine parameter ${index} type/value of ${(ctor as any).name}.${methodName}`);\n\t\t\t}\n\t\t\tlet param = (this.injector as StateResolvingInjector).resolveState(actualToken as InjectableId<unknown>);\n\t\t\tif (!param.pending && param.rejected) {\n\t\t\t\tconst optionalDefault = _getOptionalDefaultForMethod(ctor.prototype, methodName, index);\n\t\t\t\tif (optionalDefault)\n\t\t\t\t\tparam = State.MakeState<any>(null, undefined, optionalDefault.value);\n\t\t\t}\n\t\t\treturn param;\n\t\t});\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\tthrow state.rejected; // 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"]}
@@ -20,7 +20,7 @@ class ReasonWrapper {
20
20
  }
21
21
  }
22
22
  /**
23
- * Binder and Injector (aka Container) to handle (a)synchronous dependency management.
23
+ * Injector (aka Container) to handle (a)synchronous dependency management.
24
24
  */
25
25
  class Container {
26
26
  /**
@@ -34,7 +34,7 @@ class Container {
34
34
  * @inheritDoc
35
35
  */
36
36
  isIdKnown(id, ascending) {
37
- if (!!this.providers.get(id))
37
+ if (this.providers.has(id))
38
38
  return true;
39
39
  if (ascending && this.parent)
40
40
  return this.parent.isIdKnown(id, true);
@@ -70,27 +70,70 @@ class Container {
70
70
  }
71
71
  return Promise.resolve(state.fulfilled);
72
72
  }
73
- // noinspection JSUnusedGlobalSymbols
74
73
  /**
75
- * This method is not part of the Binding interface, because it is highly unusual.
76
- * But that doesn't mean we can't imagine scenarios where you might require it.
74
+ * Removes a binding from this Container (and optionally its ancestor chain).
75
+ * Most useful in unit tests to replace or clear bindings between test cases.
76
+ * **Caution:** Removing a binding after initialization may have unexpected consequences if other parts of the application still hold or expect to obtain an instance of the removed id.
77
77
  *
78
- * @param id The id to be removed.
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.
78
+ * @param id The id of the binding to remove.
79
+ * @param ascending If true, the binding is also removed from every Container in the parent chain.
80
+ * @param releaseIfSingleton If true, Provider.releaseIfSingleton is called before removal.
81
81
  */
82
82
  removeBinding(id, ascending, releaseIfSingleton) {
83
- var _a;
84
83
  if (releaseIfSingleton) {
85
84
  const p = this.providers.get(id);
86
85
  if (p)
87
86
  p.releaseIfSingleton();
88
87
  }
89
88
  this.providers.delete(id);
90
- if (ascending && this.parent) {
91
- (_a = this.parent) === null || _a === void 0 ? void 0 : _a.removeBinding(id, true, releaseIfSingleton);
89
+ if (ascending && this.parent instanceof Container) {
90
+ this.parent.removeBinding(id, true, releaseIfSingleton);
92
91
  }
93
92
  }
93
+ /**
94
+ * Alias for {@link isIdKnown}. Familiar to users migrating from TypeDI.
95
+ */
96
+ has(id, ascending) {
97
+ return this.isIdKnown(id, ascending);
98
+ }
99
+ /**
100
+ * Alias for {@link removeBinding}. Familiar to users migrating from InversifyJS.
101
+ */
102
+ unbind(id, ascending, releaseIfSingleton) {
103
+ this.removeBinding(id, ascending, releaseIfSingleton);
104
+ }
105
+ /**
106
+ * Creates a new child Container that inherits unbound ids from this Container.
107
+ * Familiar to users migrating from TSyringe.
108
+ */
109
+ createChildContainer() {
110
+ return new Container(this);
111
+ }
112
+ /**
113
+ * Descriptor-based binding dispatching to the appropriate bindXXX method.
114
+ * Familiar to users migrating from TSyringe.
115
+ * Returns a {@link BindAs} chain for class and factory bindings; returns undefined for value bindings (which are always singletons).
116
+ */
117
+ register(id, descriptor) {
118
+ if ('useClass' in descriptor)
119
+ return this.bindClass(id, descriptor.useClass);
120
+ if ('useValue' in descriptor) {
121
+ this.bindConstant(id, descriptor.useValue);
122
+ return undefined;
123
+ }
124
+ if ('useFactory' in descriptor)
125
+ return this.bindFactory(id, descriptor.useFactory);
126
+ // useAsyncFactory
127
+ return this.bindAsyncFactory(id, descriptor.useAsyncFactory);
128
+ }
129
+ /**
130
+ * Binds a class as a singleton in one step.
131
+ * Shorthand for {@link bindClass}(...).{@link BindAs.asSingleton asSingleton}().
132
+ * Familiar to users migrating from TSyringe.
133
+ */
134
+ registerSingleton(id, constructor) {
135
+ this.bindClass(id, constructor).asSingleton();
136
+ }
94
137
  /**
95
138
  * @inheritDoc
96
139
  */
@@ -129,7 +172,6 @@ class Container {
129
172
  * @inheritDoc
130
173
  */
131
174
  resolveSingletons(asyncOnly, parentRecursion) {
132
- var _a;
133
175
  const makePromiseToResolve = () => {
134
176
  return new Promise((resolve, reject) => {
135
177
  const pending = new Map();
@@ -163,9 +205,8 @@ class Container {
163
205
  });
164
206
  });
165
207
  };
166
- if (parentRecursion && typeof ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.resolveSingletons) === 'function') {
167
- const pb = this.parent;
168
- return pb.resolveSingletons(asyncOnly, parentRecursion).then(() => {
208
+ if (parentRecursion && this.parent instanceof Container) {
209
+ return this.parent.resolveSingletons(asyncOnly, parentRecursion).then(() => {
169
210
  return makePromiseToResolve().then(() => this);
170
211
  });
171
212
  }
@@ -195,14 +236,13 @@ class Container {
195
236
  }
196
237
  return provider.provideAsState();
197
238
  }
198
- // noinspection JSUnusedGlobalSymbols
199
239
  /**
200
240
  * 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.
241
+ * It will walk through all registered Providers (of this Container only), and invoke their Provider.releaseIfSingleton method.
242
+ * This method is not part of the Injector interface, because you normally only create (and release) from Containers.
203
243
  * NOTE:
204
244
  * 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.
245
+ * 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 clean up temporary resources.
206
246
  * 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
247
  * 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
248
  */
@@ -213,7 +253,7 @@ class Container {
213
253
  }
214
254
  /**
215
255
  * Releases a Singleton instance if it exists.
216
- * 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.
256
+ * 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.
217
257
  * If not a singleton, this method returns undefined.
218
258
  * If the singleton has been resolved, it is returned, otherwise null is returned.
219
259
  * If the singleton is pending resolution, a Promise for the singleton (or for null) is returned.
@@ -226,7 +266,7 @@ class Container {
226
266
  return undefined;
227
267
  }
228
268
  /**
229
- * Make a copy of this @see Container.
269
+ * Make a copy of this Container.
230
270
  * This is an experimental feature!
231
271
  * I have not thought through all the dark corners, so use at your own peril!
232
272
  * Here are some notes:
@@ -238,7 +278,7 @@ class Container {
238
278
  * If released by the clone, they will be considered released by "this" container.
239
279
  * If a singleton is currently being asynchronously constructed any callbacks will reference "this" Container, however both Containers should have no problem awaiting resolution.
240
280
  * If a singleton is not resolved when the container is cloned, then if both containers resolve, you will create *two* "singletons".
241
- * The way to avoid this last effect is to @see resolveSingletons
281
+ * The way to avoid this last effect is to call resolveSingletons first
242
282
  */
243
283
  clone(clazz) {
244
284
  if (!clazz)
@@ -1 +1 @@
1
- {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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","sourcesContent":["import {AsyncFactoryBasedProvider} from './async-factory-provider';\nimport {BindableProvider} from './bindable-provider';\nimport {AsyncFactory, BindAs, Binder, SyncFactory} from './binder';\nimport {ClassBasedProvider} from './class-provider';\nimport {ConstantProvider} from './constant-provider';\nimport {INJECTABLE_METADATA_KEY} from './constants';\nimport {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector';\nimport {Provider} from './provider';\nimport {State} from './state';\nimport {FactoryBasedProvider} from './sync-factory-provider';\nimport {isPromise} from './utils';\n\n/**\n * Helper class to ensure we can distinguish between Error instances legitimately returned from Providers, and Errors thrown by Providers.\n *\n * @see resolveSingletons.\n */\nclass ReasonWrapper {\n\tconstructor(public reason: any) {\n\t}\n}\n\n/**\n * Binder and Injector (aka Container) to handle (a)synchronous dependency management.\n */\nexport class Container implements Binder {\n\n\t/**\n\t * Create a new Container, with an optional parent Injector which will be searched if any given InjectableId is not bound within this Container.\n\t */\n\tpublic constructor(protected parent?: Injector) {\n\t}\n\n\tprotected providers = new Map<InjectableId<any>, Provider>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic isIdKnown<T>(id: InjectableId<T>, ascending?: boolean): boolean {\n\t\tif (!!this.providers.get(id))\n\t\t\treturn true;\n\t\tif (ascending && this.parent)\n\t\t\treturn this.parent.isIdKnown(id, true);\n\t\treturn false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get<T>(id: InjectableId<T>): T {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent)\n\t\t\t\treturn this.parent.get<T>(id);\n\t\t\tthrow new Error('Symbol not bound: ' + id.toString());\n\t\t}\n\t\tconst state = provider.provideAsState();\n\t\tif (state.pending)\n\t\t\tthrow new Error('Synchronous request on unresolved asynchronous dependency tree: ' + id.toString());\n\t\tif (state.rejected)\n\t\t\tthrow state.rejected;\n\t\treturn state.fulfilled as T;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolve<T>(id: InjectableId<T>): Promise<T> {\n\t\tconst state = this.resolveState(id);\n\t\tif (isPromise(state.promise)) {\n\t\t\treturn state.promise;\n\t\t}\n\n\t\tif (state.rejected) {\n\t\t\treturn Promise.reject(state.rejected);\n\t\t}\n\n\t\treturn Promise.resolve(state.fulfilled);\n\t}\n\n\t// noinspection JSUnusedGlobalSymbols\n\t/**\n\t * This method is not part of the Binding interface, because it is highly unusual.\n\t * But that doesn't mean we can't imagine scenarios where you might require it.\n\t *\n\t * @param id The id to be removed.\n\t * @param ascending If true, this will remove all bindings of the specified id all the way up the parent container chain (if it exists).\n\t * @param releaseIfSingleton If true, @Provider.releaseIfSingleton will be invoked before the binding is removed.\n\t */\n\tpublic removeBinding<T>(id: InjectableId<T>, ascending?: boolean, releaseIfSingleton?: boolean): void {\n\t\tif (releaseIfSingleton) {\n\t\t\tconst p = this.providers.get(id);\n\t\t\tif (p)\n\t\t\t\tp.releaseIfSingleton();\n\t\t}\n\t\tthis.providers.delete(id);\n\n\t\tif (ascending && this.parent) {\n\t\t\t(this.parent as any)?.removeBinding(id, true, releaseIfSingleton);\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindConstant<T>(id: InjectableId<T>, value: T): T {\n\t\tthis.providers.set(id, new ConstantProvider(value));\n\t\treturn value;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindClass<T>(id: ClassConstructor<T>, constructor?: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | InjectableId<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | ClassConstructor<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>> {\n\t\tif (typeof constructor === 'undefined') {\n\t\t\tconstructor = id as new (...args: any[]) => T;\n\t\t}\n\t\tif (!Reflect.getMetadata(INJECTABLE_METADATA_KEY, constructor)) {\n\t\t\tthrow new Error('Class not decorated with @Injectable [' + constructor.toString() + ']');\n\t\t}\n\t\tconst provider = new ClassBasedProvider(this as any, id, constructor);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindFactory<T>(id: InjectableId<T>, factory: SyncFactory<T>): BindAs<T, SyncFactory<T>> {\n\t\tconst provider = new FactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindAsyncFactory<T>(id: InjectableId<T>, factory: AsyncFactory<T>): BindAs<T, AsyncFactory<T>> {\n\t\tconst provider = new AsyncFactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this> {\n\t\tconst makePromiseToResolve = () => {\n\t\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\t\tconst pending = new Map<InjectableId<any>, Promise<void>>();\n\t\t\t\t// Ask each provider to resolve itself *IF* it is a singleton.\n\t\t\t\tthis.providers.forEach((value: Provider, key: InjectableId<any>) => {\n\t\t\t\t\t// If the provider is a singleton *and* if resolution is being handled asynchronously, the provider will return a completion promise.\n\t\t\t\t\tconst p = value.resolveIfSingleton(asyncOnly ?? false);\n\t\t\t\t\tif (p !== null && typeof p !== 'undefined')\n\t\t\t\t\t\tpending.set(key, p);\n\t\t\t\t});\n\t\t\t\t// The contract for this method is that it behaves somewhat like Promise.allSettled (e.g. won't complete until all pending Singletons have settled).\n\t\t\t\t// Further the contract states that if any of the asynchronous Singletons rejected, that we will also return a rejected Promise, and that the rejection reason will be a Map of the InjectableId's that did not resolve, and the Error they emitted.\n\t\t\t\tconst pp = Array.from(pending.values());\n\t\t\t\tconst keys = Array.from(pending.keys());\n\t\t\t\t// Mapping the catch is an alternate version of Promise.allSettled (e.g. keeps Promise.all from short-circuiting).\n\t\t\t\tPromise.all(pp\n\t\t\t\t\t.map(p => p.catch(e => new ReasonWrapper(e))))\n\t\t\t\t\t.then((results) => {\n\t\t\t\t\t\tconst rejects = new Map<InjectableId<any>, Error>();\n\t\t\t\t\t\t// Check the results. Since we don't export ReasonWrapper, it is safe to assume that an instance of that was produced by our map => catch code above, so it's a rejected Singleton error.\n\t\t\t\t\t\tresults.forEach((result, idx) => {\n\t\t\t\t\t\t\tif (result instanceof ReasonWrapper) {\n\t\t\t\t\t\t\t\trejects.set(keys[idx], result.reason);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// If we had rejections, notify our caller what they were.\n\t\t\t\t\t\tif (rejects.size > 0)\n\t\t\t\t\t\t\treject(rejects);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tresolve(); // All good.\n\t\t\t\t\t});\n\t\t\t});\n\t\t};\n\t\tif (parentRecursion && typeof (this.parent as Binder)?.resolveSingletons === 'function') {\n\t\t\tconst pb: Binder = this.parent as Binder;\n\t\t\treturn pb.resolveSingletons(asyncOnly, parentRecursion).then(() => {\n\t\t\t\treturn makePromiseToResolve().then(() => this);\n\t\t\t});\n\t\t}\n\t\treturn makePromiseToResolve().then(() => this);\n\t}\n\n\t/**\n\t * As implied by the name prefix, this is a factored out method invoked only by the 'resolve' method.\n\t * It makes searching our parent (if it exists) easier (and quicker) IF our parent is a fellow instance of Container.\n\t */\n\tprotected resolveState<T>(id: InjectableId<T>): State<T> {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent) {\n\t\t\t\tif (this.parent instanceof Container) {\n\t\t\t\t\treturn this.parent.resolveState<T>(id);\n\t\t\t\t}\n\t\t\t\t// This code (below) will only ever execute if the creator of this container passes in their own implementation of an Injector.\n\t\t\t\t/* istanbul ignore next */\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(this.parent.resolve<T>(id), undefined, undefined);\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\treturn State.MakeState<T>(null, err);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn State.MakeState<T>(null, new Error('Symbol not bound: ' + id.toString()));\n\t\t}\n\t\treturn provider.provideAsState() as State<T>;\n\t}\n\n\t// noinspection JSUnusedGlobalSymbols\n\t/**\n\t * Convenience method to assist in releasing non-garbage-collectable resources that Singletons in this Container may have allocated.\n\t * It will walk through all registered Providers (of this Container only), and invoke their @see Provider.releaseIfSingleton method.\n\t * This method is not part of the Binding interface, because you normally only create (and release) Containers.\n\t * NOTE:\n\t * This *only* releases active/pending Singleton's that have already been created by this Container.\n\t * The most likely use of this method would be when you have created a new child Container for a limited duration transaction, and you want to easily cleanup temporary resources.\n\t * For example, your service object may need to know when it should unsubscribe from an RxJs stream (failure to do so can result in your Singleton not being garbage collected at the end of a transaction).\n\t * In theory, you could handle all unsubscription and cleanup yourself, but the @Release decorator and this method are meant to simply make that easier.\n\t */\n\tpublic releaseSingletons(): void {\n\t\tthis.providers.forEach((value: Provider) => {\n\t\t\tvalue.releaseIfSingleton();\n\t\t});\n\t}\n\n\t/**\n\t * Releases a Singleton instance if it exists.\n\t * 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.\n\t * If not a singleton, this method returns undefined.\n\t * If the singleton has been resolved, it is returned, otherwise null is returned.\n\t * If the singleton is pending resolution, a Promise for the singleton (or for null) is returned.\n\t * Note that if a singleton is returned, its Release method will already have been invoked.\n\t */\n\tpublic releaseSingleton<T>(id: InjectableId<T>): T | undefined | null | Promise<T | null> {\n\t\tconst provider = this.providers.get(id);\n\t\tif (provider)\n\t\t\treturn provider.releaseIfSingleton();\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Make a copy of this @see Container.\n\t * This is an experimental feature!\n\t * I have not thought through all the dark corners, so use at your own peril!\n\t * Here are some notes:\n\t * The injector parameter for SyncFactory and AsyncFactory callbacks will be the Container invoking the factory.\n\t * So a factory that uses a parent closure instead of the supplied injector may get unexpected results.\n\t * The injector parameter for OnSuccess and OnError callbacks will be the Container performing the resolution.\n\t * Singletons are cloned at their *existing* state..\n\t * If resolved in \"this\" container, they will not be re-resolved for the clone.\n\t * If released by the clone, they will be considered released by \"this\" container.\n\t * If a singleton is currently being asynchronously constructed any callbacks will reference \"this\" Container, however both Containers should have no problem awaiting resolution.\n\t * If a singleton is not resolved when the container is cloned, then if both containers resolve, you will create *two* \"singletons\".\n\t * The way to avoid this last effect is to @see resolveSingletons\n\t */\n\tclone(clazz?: ClassConstructor<Container>): Container {\n\t\tif (!clazz)\n\t\t\tclazz = Container;\n\t\tconst retVal = new clazz(this.parent);\n\t\tthis.providers.forEach((v, k) => {\n\t\t\tif (v instanceof BindableProvider) {\n\t\t\t\tv = Object.assign(Object.create(Object.getPrototypeOf(v)), v);\n\t\t\t\t(v as any).injector = retVal;\n\t\t\t}\n\t\t\tretVal.providers.set(k, v);\n\t\t});\n\t\treturn retVal;\n\t}\n}\n"]}
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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","sourcesContent":["import {AsyncFactoryBasedProvider} from './async-factory-provider';\nimport {BindableProvider} from './bindable-provider';\nimport {AsyncFactory, BindAs, RegisterDescriptor, SyncFactory} from './binding';\nimport {ClassBasedProvider} from './class-provider';\nimport {ConstantProvider} from './constant-provider';\nimport {INJECTABLE_METADATA_KEY} from './constants';\nimport {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector';\nimport {Provider} from './provider';\nimport {State} from './state';\nimport {FactoryBasedProvider} from './sync-factory-provider';\nimport {isPromise} from './utils';\n\n/**\n * Helper class to ensure we can distinguish between Error instances legitimately returned from Providers, and Errors thrown by Providers.\n *\n * @see resolveSingletons.\n */\nclass ReasonWrapper {\n\tconstructor(public reason: any) {\n\t}\n}\n\n/**\n * Injector (aka Container) to handle (a)synchronous dependency management.\n */\nexport class Container implements Injector {\n\n\t/**\n\t * Create a new Container, with an optional parent Injector which will be searched if any given InjectableId is not bound within this Container.\n\t */\n\tpublic constructor(protected parent?: Injector) {\n\t}\n\n\tprotected providers = new Map<InjectableId<any>, Provider>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic isIdKnown<T>(id: InjectableId<T>, ascending?: boolean): boolean {\n\t\tif (this.providers.has(id))\n\t\t\treturn true;\n\t\tif (ascending && this.parent)\n\t\t\treturn this.parent.isIdKnown(id, true);\n\t\treturn false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get<T>(id: InjectableId<T>): T {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent)\n\t\t\t\treturn this.parent.get<T>(id);\n\t\t\tthrow new Error('Symbol not bound: ' + id.toString());\n\t\t}\n\t\tconst state = provider.provideAsState();\n\t\tif (state.pending)\n\t\t\tthrow new Error('Synchronous request on unresolved asynchronous dependency tree: ' + id.toString());\n\t\tif (state.rejected)\n\t\t\tthrow state.rejected;\n\t\treturn state.fulfilled as T;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolve<T>(id: InjectableId<T>): Promise<T> {\n\t\tconst state = this.resolveState(id);\n\t\tif (isPromise(state.promise)) {\n\t\t\treturn state.promise;\n\t\t}\n\n\t\tif (state.rejected) {\n\t\t\treturn Promise.reject(state.rejected);\n\t\t}\n\n\t\treturn Promise.resolve(state.fulfilled);\n\t}\n\n\t/**\n\t * Removes a binding from this Container (and optionally its ancestor chain).\n\t * Most useful in unit tests to replace or clear bindings between test cases.\n\t * **Caution:** Removing a binding after initialization may have unexpected consequences if other parts of the application still hold or expect to obtain an instance of the removed id.\n\t *\n\t * @param id The id of the binding to remove.\n\t * @param ascending If true, the binding is also removed from every Container in the parent chain.\n\t * @param releaseIfSingleton If true, Provider.releaseIfSingleton is called before removal.\n\t */\n\tpublic removeBinding<T>(id: InjectableId<T>, ascending?: boolean, releaseIfSingleton?: boolean): void {\n\t\tif (releaseIfSingleton) {\n\t\t\tconst p = this.providers.get(id);\n\t\t\tif (p)\n\t\t\t\tp.releaseIfSingleton();\n\t\t}\n\t\tthis.providers.delete(id);\n\n\t\tif (ascending && this.parent instanceof Container) {\n\t\t\tthis.parent.removeBinding(id, true, releaseIfSingleton);\n\t\t}\n\t}\n\n\n\t/**\n\t * Alias for {@link isIdKnown}. Familiar to users migrating from TypeDI.\n\t */\n\tpublic has<T>(id: InjectableId<T>, ascending?: boolean): boolean {\n\t\treturn this.isIdKnown(id, ascending);\n\t}\n\n\t/**\n\t * Alias for {@link removeBinding}. Familiar to users migrating from InversifyJS.\n\t */\n\tpublic unbind<T>(id: InjectableId<T>, ascending?: boolean, releaseIfSingleton?: boolean): void {\n\t\tthis.removeBinding(id, ascending, releaseIfSingleton);\n\t}\n\n\t/**\n\t * Creates a new child Container that inherits unbound ids from this Container.\n\t * Familiar to users migrating from TSyringe.\n\t */\n\tpublic createChildContainer(): Container {\n\t\treturn new Container(this);\n\t}\n\n\t/**\n\t * Descriptor-based binding dispatching to the appropriate bindXXX method.\n\t * Familiar to users migrating from TSyringe.\n\t * Returns a {@link BindAs} chain for class and factory bindings; returns undefined for value bindings (which are always singletons).\n\t */\n\tpublic register<T>(id: InjectableId<T>, descriptor: RegisterDescriptor<T>): BindAs<T, any> | undefined {\n\t\tif ('useClass' in descriptor)\n\t\t\treturn this.bindClass(id as any, descriptor.useClass);\n\t\tif ('useValue' in descriptor) {\n\t\t\tthis.bindConstant(id, descriptor.useValue);\n\t\t\treturn undefined;\n\t\t}\n\t\tif ('useFactory' in descriptor)\n\t\t\treturn this.bindFactory(id, descriptor.useFactory);\n\t\t// useAsyncFactory\n\t\treturn this.bindAsyncFactory(id, (descriptor as {useAsyncFactory: AsyncFactory<T>}).useAsyncFactory);\n\t}\n\n\t/**\n\t * Binds a class as a singleton in one step.\n\t * Shorthand for {@link bindClass}(...).{@link BindAs.asSingleton asSingleton}().\n\t * Familiar to users migrating from TSyringe.\n\t */\n\tpublic registerSingleton<T>(id: InjectableId<T>, constructor: ClassConstructor<T>): void {\n\t\tthis.bindClass(id as any, constructor).asSingleton();\n\t}\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindConstant<T>(id: InjectableId<T>, value: T): T {\n\t\tthis.providers.set(id, new ConstantProvider(value));\n\t\treturn value;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindClass<T>(id: ClassConstructor<T>, constructor?: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | InjectableId<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>>;\n\tpublic bindClass<T>(id: string | symbol | AbstractConstructor<T> | ClassConstructor<T>, constructor: ClassConstructor<T>): BindAs<T, ClassConstructor<T>> {\n\t\tif (typeof constructor === 'undefined') {\n\t\t\tconstructor = id as new (...args: any[]) => T;\n\t\t}\n\t\tif (!Reflect.getMetadata(INJECTABLE_METADATA_KEY, constructor)) {\n\t\t\tthrow new Error('Class not decorated with @Injectable [' + constructor.toString() + ']');\n\t\t}\n\t\tconst provider = new ClassBasedProvider(this as any, id, constructor);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindFactory<T>(id: InjectableId<T>, factory: SyncFactory<T>): BindAs<T, SyncFactory<T>> {\n\t\tconst provider = new FactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic bindAsyncFactory<T>(id: InjectableId<T>, factory: AsyncFactory<T>): BindAs<T, AsyncFactory<T>> {\n\t\tconst provider = new AsyncFactoryBasedProvider(this, id, factory);\n\t\tthis.providers.set(id, provider);\n\t\treturn provider.makeBindAs();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic resolveSingletons(asyncOnly?: boolean, parentRecursion?: boolean): Promise<this> {\n\t\tconst makePromiseToResolve = () => {\n\t\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\t\tconst pending = new Map<InjectableId<any>, Promise<void>>();\n\t\t\t\t// Ask each provider to resolve itself *IF* it is a singleton.\n\t\t\t\tthis.providers.forEach((value: Provider, key: InjectableId<any>) => {\n\t\t\t\t\t// If the provider is a singleton *and* if resolution is being handled asynchronously, the provider will return a completion promise.\n\t\t\t\t\tconst p = value.resolveIfSingleton(asyncOnly ?? false);\n\t\t\t\t\tif (p !== null && typeof p !== 'undefined')\n\t\t\t\t\t\tpending.set(key, p);\n\t\t\t\t});\n\t\t\t\t// The contract for this method is that it behaves somewhat like Promise.allSettled (e.g. won't complete until all pending Singletons have settled).\n\t\t\t\t// Further the contract states that if any of the asynchronous Singletons rejected, that we will also return a rejected Promise, and that the rejection reason will be a Map of the InjectableId's that did not resolve, and the Error they emitted.\n\t\t\t\tconst pp = Array.from(pending.values());\n\t\t\t\tconst keys = Array.from(pending.keys());\n\t\t\t\t// Mapping the catch is an alternate version of Promise.allSettled (e.g. keeps Promise.all from short-circuiting).\n\t\t\t\tPromise.all(pp\n\t\t\t\t\t.map(p => p.catch(e => new ReasonWrapper(e))))\n\t\t\t\t\t.then((results) => {\n\t\t\t\t\t\tconst rejects = new Map<InjectableId<any>, Error>();\n\t\t\t\t\t\t// Check the results. Since we don't export ReasonWrapper, it is safe to assume that an instance of that was produced by our map => catch code above, so it's a rejected Singleton error.\n\t\t\t\t\t\tresults.forEach((result, idx) => {\n\t\t\t\t\t\t\tif (result instanceof ReasonWrapper) {\n\t\t\t\t\t\t\t\trejects.set(keys[idx], result.reason);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// If we had rejections, notify our caller what they were.\n\t\t\t\t\t\tif (rejects.size > 0)\n\t\t\t\t\t\t\treject(rejects);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tresolve(); // All good.\n\t\t\t\t\t});\n\t\t\t});\n\t\t};\n\t\tif (parentRecursion && this.parent instanceof Container) {\n\t\t\treturn this.parent.resolveSingletons(asyncOnly, parentRecursion).then(() => {\n\t\t\t\treturn makePromiseToResolve().then(() => this);\n\t\t\t});\n\t\t}\n\t\treturn makePromiseToResolve().then(() => this);\n\t}\n\n\t/**\n\t * As implied by the name prefix, this is a factored out method invoked only by the 'resolve' method.\n\t * It makes searching our parent (if it exists) easier (and quicker) IF our parent is a fellow instance of Container.\n\t */\n\tprotected resolveState<T>(id: InjectableId<T>): State<T> {\n\t\tconst provider = this.providers.get(id);\n\t\tif (!provider) {\n\t\t\tif (this.parent) {\n\t\t\t\tif (this.parent instanceof Container) {\n\t\t\t\t\treturn this.parent.resolveState<T>(id);\n\t\t\t\t}\n\t\t\t\t// This code (below) will only ever execute if the creator of this container passes in their own implementation of an Injector.\n\t\t\t\t/* istanbul ignore next */\n\t\t\t\ttry {\n\t\t\t\t\treturn State.MakeState<T>(this.parent.resolve<T>(id), undefined, undefined);\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\treturn State.MakeState<T>(null, err);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn State.MakeState<T>(null, new Error('Symbol not bound: ' + id.toString()));\n\t\t}\n\t\treturn provider.provideAsState() as State<T>;\n\t}\n\n\t/**\n\t * Convenience method to assist in releasing non-garbage-collectable resources that Singletons in this Container may have allocated.\n\t * It will walk through all registered Providers (of this Container only), and invoke their Provider.releaseIfSingleton method.\n\t * This method is not part of the Injector interface, because you normally only create (and release) from Containers.\n\t * NOTE:\n\t * This *only* releases active/pending Singleton's that have already been created by this Container.\n\t * The most likely use of this method would be when you have created a new child Container for a limited-duration transaction, and you want to easily clean up temporary resources.\n\t * For example, your service object may need to know when it should unsubscribe from an RxJs stream (failure to do so can result in your Singleton not being garbage collected at the end of a transaction).\n\t * In theory, you could handle all unsubscription and cleanup yourself, but the @Release decorator and this method are meant to simply make that easier.\n\t */\n\tpublic releaseSingletons(): void {\n\t\tthis.providers.forEach((value: Provider) => {\n\t\t\tvalue.releaseIfSingleton();\n\t\t});\n\t}\n\n\t/**\n\t * Releases a Singleton instance if it exists.\n\t * 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.\n\t * If not a singleton, this method returns undefined.\n\t * If the singleton has been resolved, it is returned, otherwise null is returned.\n\t * If the singleton is pending resolution, a Promise for the singleton (or for null) is returned.\n\t * Note that if a singleton is returned, its Release method will already have been invoked.\n\t */\n\tpublic releaseSingleton<T>(id: InjectableId<T>): T | undefined | null | Promise<T | null> {\n\t\tconst provider = this.providers.get(id);\n\t\tif (provider)\n\t\t\treturn provider.releaseIfSingleton();\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Make a copy of this Container.\n\t * This is an experimental feature!\n\t * I have not thought through all the dark corners, so use at your own peril!\n\t * Here are some notes:\n\t * The injector parameter for SyncFactory and AsyncFactory callbacks will be the Container invoking the factory.\n\t * So a factory that uses a parent closure instead of the supplied injector may get unexpected results.\n\t * The injector parameter for OnSuccess and OnError callbacks will be the Container performing the resolution.\n\t * Singletons are cloned at their *existing* state..\n\t * If resolved in \"this\" container, they will not be re-resolved for the clone.\n\t * If released by the clone, they will be considered released by \"this\" container.\n\t * If a singleton is currently being asynchronously constructed any callbacks will reference \"this\" Container, however both Containers should have no problem awaiting resolution.\n\t * If a singleton is not resolved when the container is cloned, then if both containers resolve, you will create *two* \"singletons\".\n\t * The way to avoid this last effect is to call resolveSingletons first\n\t */\n\tclone(clazz?: ClassConstructor<Container>): Container {\n\t\tif (!clazz)\n\t\t\tclazz = Container;\n\t\tconst retVal = new clazz(this.parent);\n\t\tthis.providers.forEach((v, k) => {\n\t\t\tif (v instanceof BindableProvider) {\n\t\t\t\tv = Object.assign(Object.create(Object.getPrototypeOf(v)), v);\n\t\t\t\t(v as any).injector = retVal;\n\t\t\t}\n\t\t\tretVal.providers.set(k, v);\n\t\t});\n\t\treturn retVal;\n\t}\n}\n"]}