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
@@ -3,8 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Injectable = Injectable;
4
4
  exports.Inject = Inject;
5
5
  exports._getInjectedIdAt = _getInjectedIdAt;
6
+ exports._getInjectedIdForMethod = _getInjectedIdForMethod;
6
7
  exports.Optional = Optional;
7
8
  exports._getOptionalDefaultAt = _getOptionalDefaultAt;
9
+ exports._getOptionalDefaultForMethod = _getOptionalDefaultForMethod;
8
10
  exports.PostConstruct = PostConstruct;
9
11
  exports.Release = Release;
10
12
  /**
@@ -33,6 +35,10 @@ function isClassConstructor(target) {
33
35
  function makeParamIdxKey(idx) {
34
36
  return `index-${idx}`;
35
37
  }
38
+ // Key for @Inject/@Optional metadata stored on a method parameter.
39
+ function makeMethodParamIdxKey(methodName, idx) {
40
+ return `${String(methodName)}:index-${idx}`;
41
+ }
36
42
  // Validate that the specified target is a parameter of a class constructor
37
43
  function validateConstructorParam(decorator, target, idx) {
38
44
  if (!isClassConstructor(target)) {
@@ -40,6 +46,16 @@ function validateConstructorParam(decorator, target, idx) {
40
46
  }
41
47
  return makeParamIdxKey(idx);
42
48
  }
49
+ // Validate that the target is an instance method parameter (non-constructor).
50
+ function validateMethodParam(decorator, target, methodName, idx) {
51
+ if (typeof target !== 'object' || typeof target.constructor !== 'function') {
52
+ throw new Error('@' + decorator + ' is not valid here [' + targetHint(target) + ']');
53
+ }
54
+ if (!Reflect.hasOwnMetadata(constants_1.REFLECT_PARAMS, target, methodName)) {
55
+ // REFLECT_PARAMS not yet set (decoration order), so we cannot pre-validate the method; accept silently.
56
+ }
57
+ return makeMethodParamIdxKey(methodName, idx);
58
+ }
43
59
  // Validate the decorator was only applied once.
44
60
  function validateSingleConstructorParam(decorator, target, idx) {
45
61
  const propKey = validateConstructorParam(decorator, target, idx);
@@ -65,15 +81,16 @@ function Injectable() {
65
81
  };
66
82
  }
67
83
  /**
68
- * Placed just before a constructor parameter, this parameter decorator allows for specificity and control over the type of the type of Object that will be injected into the parameter.
84
+ * Placed just before a constructor parameter, this parameter decorator allows for specificity and control over the type of Object that will be injected into the parameter.
69
85
  * In the absence of this decorator the container will use whatever is bound to a parameter's type (or throw an error if it is unable to recognize the type).
86
+ * This decorator may also be placed on a parameter of a method annotated with @PostConstruct, in which case the container will resolve and inject the value before invoking that method.
70
87
  *
71
88
  * @param id The identifier of the bound type that should be injected.
72
89
  */
73
90
  function Inject(id) {
74
91
  /**
75
- * @param target The constructor function of the class (we don't allow @Inject on anything else).
76
- * @param parameterName The name of the parameter
92
+ * @param target The constructor function of the class (for constructor params), or the class prototype (for method params).
93
+ * @param parameterName The name of the parameter (undefined for constructor params, the method name for method params)
77
94
  * @param parameterIndex The ordinal index of the parameter in the function’s parameter list
78
95
  * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.
79
96
  */
@@ -81,8 +98,16 @@ function Inject(id) {
81
98
  if (id === undefined) {
82
99
  throw new Error('Undefined id passed to @Inject [' + targetHint(target) + ']');
83
100
  }
84
- const paramKey = validateSingleConstructorParam('Inject', target, parameterIndex);
85
- Reflect.defineMetadata(constants_1.INJECT_METADATA_KEY, id, target, paramKey);
101
+ if (parameterName === undefined) {
102
+ // Constructor parameter
103
+ const paramKey = validateSingleConstructorParam('Inject', target, parameterIndex);
104
+ Reflect.defineMetadata(constants_1.INJECT_METADATA_KEY, id, target, paramKey);
105
+ }
106
+ else {
107
+ // Method parameter — silently accepted (intended for @PostConstruct methods)
108
+ const paramKey = validateMethodParam('Inject', target, parameterName, parameterIndex);
109
+ Reflect.defineMetadata(constants_1.INJECT_METADATA_KEY, id, target, paramKey);
110
+ }
86
111
  };
87
112
  }
88
113
  /**
@@ -95,20 +120,35 @@ function Inject(id) {
95
120
  function _getInjectedIdAt(target, parameterIndex) {
96
121
  return Reflect.getMetadata(constants_1.INJECT_METADATA_KEY, target, makeParamIdxKey(parameterIndex));
97
122
  }
123
+ /**
124
+ * Retrieve the @Inject metadata for a specifically indexed parameter of a named method.
125
+ */
126
+ function _getInjectedIdForMethod(prototype, methodName, parameterIndex) {
127
+ return Reflect.getMetadata(constants_1.INJECT_METADATA_KEY, prototype, makeMethodParamIdxKey(methodName, parameterIndex));
128
+ }
98
129
  /**
99
130
  * Placed just before a constructor parameter, this parameter decorator signals the container that it should supply the 'alt' constant value (undefined by default) if for *any* reason it is unable to otherwise resolve the type of the parameter.
131
+ * This decorator may also be placed on a parameter of a method annotated with @PostConstruct.
100
132
  * WARNING! It is your responsibility to ensure that alt is of the appropriate type/value.
101
133
  */
102
134
  function Optional(alt) {
103
135
  /**
104
- * @param target The constructor function of the class (we don't allow @Optional on anything else).
105
- * @param parameterName The name of the parameter
136
+ * @param target The constructor function of the class (for constructor params), or the class prototype (for method params).
137
+ * @param parameterName The name of the parameter (undefined for constructor params, the method name for method params)
106
138
  * @param parameterIndex The ordinal index of the parameter in the function’s parameter list
107
139
  * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.
108
140
  */
109
141
  return function (target, parameterName, parameterIndex) {
110
- const paramKey = validateSingleConstructorParam('Optional', target, parameterIndex);
111
- Reflect.defineMetadata(constants_1.OPTIONAL_METADATA_KEY, { value: alt }, target, paramKey);
142
+ if (parameterName === undefined) {
143
+ // Constructor parameter
144
+ const paramKey = validateSingleConstructorParam('Optional', target, parameterIndex);
145
+ Reflect.defineMetadata(constants_1.OPTIONAL_METADATA_KEY, { value: alt }, target, paramKey);
146
+ }
147
+ else {
148
+ // Method parameter — silently accepted (intended for @PostConstruct methods)
149
+ const paramKey = validateMethodParam('Optional', target, parameterName, parameterIndex);
150
+ Reflect.defineMetadata(constants_1.OPTIONAL_METADATA_KEY, { value: alt }, target, paramKey);
151
+ }
112
152
  };
113
153
  }
114
154
  /**
@@ -122,20 +162,26 @@ function Optional(alt) {
122
162
  function _getOptionalDefaultAt(target, parameterIndex) {
123
163
  return Reflect.getMetadata(constants_1.OPTIONAL_METADATA_KEY, target, makeParamIdxKey(parameterIndex)); // See the @Optional decorator before making any changes here.
124
164
  }
165
+ /**
166
+ * Retrieve the @Optional metadata for a specifically indexed parameter of a named method.
167
+ */
168
+ function _getOptionalDefaultForMethod(prototype, methodName, parameterIndex) {
169
+ return Reflect.getMetadata(constants_1.OPTIONAL_METADATA_KEY, prototype, makeMethodParamIdxKey(methodName, parameterIndex));
170
+ }
125
171
  /**
126
172
  * Placed just before a class method, this method decorator flags a method that should be called after an object has been instantiated by the container, but before it is put into service.
127
- * The method will be assumed to be synchronous unless the method signature explicitly declares it's return type to be ": Promise<something>"
173
+ * The method will be assumed to be synchronous unless the method signature explicitly declares its return type to be ": Promise<something>".
174
+ * Parameters will be resolved by the container just as they are for constructors.
128
175
  * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.
129
176
  */
130
177
  function PostConstruct() {
131
178
  /**
132
179
  * @param prototypeOrConstructor The prototype of the class (we don't allow @PostConstruct on anything other than a class instance method.
133
180
  * @param methodName The name of the method.
134
- * @param descriptor The Property Descriptor for the method.
181
+ * @param _descriptor The Property Descriptor for the method.
135
182
  * @returns Undefined (nothing), as this decorator does not modify the method in any way.
136
183
  */
137
- // noinspection JSUnusedLocalSymbols
138
- return function (target, methodName, descriptor) {
184
+ return function (target, methodName, _descriptor) {
139
185
  if (typeof target !== 'object' || typeof target.constructor !== 'function') {
140
186
  throw new Error('@PostConstruct not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');
141
187
  }
@@ -151,7 +197,6 @@ function PostConstruct() {
151
197
  }
152
198
  };
153
199
  }
154
- // noinspection JSUnusedGlobalSymbols
155
200
  /**
156
201
  * Placed just before a class method, this decorator identifies a method which should be called when an object is removed from service.
157
202
  * If invoked by the container, the container will drop any references it has to the object when the method returns.
@@ -168,11 +213,10 @@ function Release() {
168
213
  /**
169
214
  * @param prototypeOrConstructor The prototype of the class (we don't allow @Release on anything other than a class instance method.
170
215
  * @param methodName The name of the method.
171
- * @param descriptor The Property Descriptor for the method.
216
+ * @param _descriptor The Property Descriptor for the method.
172
217
  * @returns Undefined (nothing), as this decorator does not modify the method in any way.
173
218
  */
174
- // noinspection JSUnusedLocalSymbols
175
- return function (target, methodName, descriptor) {
219
+ return function (target, methodName, _descriptor) {
176
220
  if (typeof target !== 'object' || typeof target.constructor !== 'function') {
177
221
  throw new Error('@Release not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');
178
222
  }
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * These decorators all apply the information they collect (whether class, method, or parameter data) as tagged metadata on the class's constructor\n */\nimport {INJECT_METADATA_KEY, INJECTABLE_METADATA_KEY, OPTIONAL_METADATA_KEY, POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_RETURN, RELEASE_METADATA_KEY} from './constants';\nimport {InjectableId} from './injector';\n\n// Help user locate misapplied decorators.\nfunction targetHint(target: Function): string {\n\tlet hint: string | undefined;\n\tif (target) {\n\t\thint = target.name;\n\t\tif ((!hint) && target.constructor) {\n\t\t\thint = target.constructor.name;\n\t\t}\n\t}\n\treturn hint ?? '';\n}\n\n// Validate that 'target' is a class constructor function.\nfunction isClassConstructor(target: any) {\n\tif (typeof target === 'function' && target.hasOwnProperty('prototype')) {\n\t\treturn target.prototype.constructor === target;\n\t}\n\treturn false;\n}\n\n// Ensure consistency in our meta-data name getting/setting.\nfunction makeParamIdxKey(idx: number): string {\n\treturn `index-${idx}`;\n}\n\n// Validate that the specified target is a parameter of a class constructor\nfunction validateConstructorParam(decorator: string, target: Function, idx: number): string {\n\tif (!isClassConstructor(target)) {\n\t\tthrow new Error('@' + decorator + ' is not valid here [' + targetHint(target) + ']');\n\t}\n\treturn makeParamIdxKey(idx);\n}\n\n// Validate the decorator was only applied once.\nfunction validateSingleConstructorParam(decorator: string, target: Function, idx: number): string {\n\tconst propKey = validateConstructorParam(decorator, target, idx);\n\tif (Reflect.hasOwnMetadata(decorator, target, propKey)) {\n\t\tthrow new Error('@' + decorator + ' applied multiple times [' + target.constructor.name + ']');\n\t}\n\treturn propKey;\n}\n\n/**\n * Placed just before the class declaration, this class decorator applies metadata to the class constructor indicating that the user intends to bind the class into the container.\n * This decorator will throw if not placed on a class declaration, or if placed more than once on a class declaration.\n */\nexport function Injectable(): ClassDecorator {\n\t/**\n\t * @param target The constructor function of the class that is being decorated\n\t * @returns Undefined (nothing), as this decorator does not modify the constructor in any way.\n\t */\n\treturn function (target: Function): void {\n\t\tif (Reflect.hasOwnMetadata(INJECTABLE_METADATA_KEY, target)) {\n\t\t\tthrow new Error('@Injectable applied multiple times [' + targetHint(target) + ']');\n\t\t}\n\t\tReflect.defineMetadata(INJECTABLE_METADATA_KEY, true, target);\n\t};\n}\n\n/**\n * Placed just before a constructor parameter, this parameter decorator allows for specificity and control over the type of the type of Object that will be injected into the parameter.\n * In the absence of this decorator the container will use whatever is bound to a parameter's type (or throw an error if it is unable to recognize the type).\n *\n * @param id The identifier of the bound type that should be injected.\n */\nexport function Inject(id: InjectableId<any>): ParameterDecorator {\n\t/**\n\t * @param target The constructor function of the class (we don't allow @Inject on anything else).\n\t * @param parameterName The name of the parameter\n\t * @param parameterIndex The ordinal index of the parameter in the function’s parameter list\n\t * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.\n\t */\n\treturn function (target: object, parameterName: string | symbol | undefined, parameterIndex: number): void {\n\t\tif (id === undefined) {\n\t\t\tthrow new Error('Undefined id passed to @Inject [' + targetHint(target as Function) + ']');\n\t\t}\n\t\tconst paramKey = validateSingleConstructorParam('Inject', target as Function, parameterIndex);\n\t\tReflect.defineMetadata(INJECT_METADATA_KEY, id, target, paramKey);\n\t};\n}\n\n/**\n * This is a helper function used by the container to retrieve the @Inject metadata for a specifically indexed constructor parameter\n *\n * @param target The constructor function of the class (we don't allow @Inject on anything else).\n * @param parameterIndex The ordinal index of the parameter in the constructor’s parameter list\n * @see Inject\n */\nexport function _getInjectedIdAt(target: Function, parameterIndex: number): InjectableId<any> {\n\treturn Reflect.getMetadata(INJECT_METADATA_KEY, target, makeParamIdxKey(parameterIndex)) as InjectableId<any>;\n}\n\n/**\n * Placed just before a constructor parameter, this parameter decorator signals the container that it should supply the 'alt' constant value (undefined by default) if for *any* reason it is unable to otherwise resolve the type of the parameter.\n * WARNING! It is your responsibility to ensure that alt is of the appropriate type/value.\n */\nexport function Optional(alt?: any): ParameterDecorator {\n\t/**\n\t * @param target The constructor function of the class (we don't allow @Optional on anything else).\n\t * @param parameterName The name of the parameter\n\t * @param parameterIndex The ordinal index of the parameter in the function’s parameter list\n\t * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.\n\t */\n\treturn function (target: object, parameterName: string | symbol | undefined, parameterIndex: number): void {\n\t\tconst paramKey = validateSingleConstructorParam('Optional', target as Function, parameterIndex);\n\t\tReflect.defineMetadata(OPTIONAL_METADATA_KEY, {value: alt}, target, paramKey);\n\t};\n}\n\n/**\n * This is a helper function used by the container to retrieve the @Optional metadata for a specifically indexed constructor parameter\n *\n * @param target The constructor function of the class (we don't allow @Optional on anything else).\n * @param parameterIndex The ordinal index of the parameter in the constructor’s parameter list\n * @see Optional\n * @returns an object containing the value provided in the decorator, or undefined if no annotation was present.\n */\nexport function _getOptionalDefaultAt(target: Function, parameterIndex: number): { value: any } {\n\treturn Reflect.getMetadata(OPTIONAL_METADATA_KEY, target, makeParamIdxKey(parameterIndex)) as { value: any }; // See the @Optional decorator before making any changes here.\n}\n\n/**\n * Placed just before a class method, this method decorator flags a method that should be called after an object has been instantiated by the container, but before it is put into service.\n * The method will be assumed to be synchronous unless the method signature explicitly declares it's return type to be \": Promise<something>\"\n * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.\n */\nexport function PostConstruct(): MethodDecorator {\n\t/**\n\t * @param prototypeOrConstructor The prototype of the class (we don't allow @PostConstruct on anything other than a class instance method.\n\t * @param methodName The name of the method.\n\t * @param descriptor The Property Descriptor for the method.\n\t * @returns Undefined (nothing), as this decorator does not modify the method in any way.\n\t */\n\t// noinspection JSUnusedLocalSymbols\n\treturn function (target: Object, methodName: string | symbol, descriptor: PropertyDescriptor) {\n\t\tif (typeof target !== 'object' || typeof target.constructor !== 'function') {\n\t\t\tthrow new Error('@PostConstruct not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');\n\t\t}\n\t\tif (Reflect.hasOwnMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, target.constructor) || Reflect.hasOwnMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, target.constructor)) {\n\t\t\tthrow new Error('@PostConstruct applied multiple times [' + targetHint(target.constructor) + ']');\n\t\t}\n\t\tconst rt = Reflect.getMetadata(REFLECT_RETURN, target, methodName);\n\t\tif (typeof rt === 'function') {\n\t\t\tReflect.defineMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, methodName, target.constructor);\n\t\t}\n\t\telse {\n\t\t\tReflect.defineMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, methodName, target.constructor);\n\t\t}\n\t};\n}\n\n// noinspection JSUnusedGlobalSymbols\n/**\n * Placed just before a class method, this decorator identifies a method which should be called when an object is removed from service.\n * If invoked by the container, the container will drop any references it has to the object when the method returns.\n * Note that this decorator is *not* a guarantee (or even an implication) that the decorated method will be called (JavaScript has no mechanism to enforce such a contract).\n * This decorator simply serves as a flag to indicate a method which is intended to clean up resources allocated by the object *which would not otherwise be garbage collected*.\n * You should *not* use this decorator as a general \"object finalization\" method. It has very limited scope and purpose.\n * The decorated method must complete normally (no throwing), as \"release\" is not an abort-able process.\n * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.\n * The @see InvokeReleaseMethod helper function can search for and invoke the @Release decorated method of an object.\n * Also @see Container.releaseSingletons for the intended usage of this decorator.\n * It is intended that after the @Release decorated method of an object is called, that object will not be used again, but this is of course not enforced).\n */\nexport function Release(): MethodDecorator {\n\t/**\n\t * @param prototypeOrConstructor The prototype of the class (we don't allow @Release on anything other than a class instance method.\n\t * @param methodName The name of the method.\n\t * @param descriptor The Property Descriptor for the method.\n\t * @returns Undefined (nothing), as this decorator does not modify the method in any way.\n\t */\n\t// noinspection JSUnusedLocalSymbols\n\treturn function (target: Object, methodName: string | symbol, descriptor: PropertyDescriptor) {\n\t\tif (typeof target !== 'object' || typeof target.constructor !== 'function') {\n\t\t\tthrow new Error('@Release not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');\n\t\t}\n\t\tif (Reflect.hasOwnMetadata(RELEASE_METADATA_KEY, target.constructor)) {\n\t\t\tthrow new Error('@Release applied multiple times [' + targetHint(target.constructor) + ']');\n\t\t}\n\t\tReflect.defineMetadata(RELEASE_METADATA_KEY, methodName, target.constructor);\n\t};\n}\n"]}
1
+ {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * These decorators all apply the information they collect (whether class, method, or parameter data) as tagged metadata on the class's constructor\n */\nimport {INJECT_METADATA_KEY, INJECTABLE_METADATA_KEY, OPTIONAL_METADATA_KEY, POSTCONSTRUCT_ASYNC_METADATA_KEY, POSTCONSTRUCT_SYNC_METADATA_KEY, REFLECT_PARAMS, REFLECT_RETURN, RELEASE_METADATA_KEY} from './constants';\nimport {InjectableId} from './injector';\n\n// Help user locate misapplied decorators.\nfunction targetHint(target: Function): string {\n\tlet hint: string | undefined;\n\tif (target) {\n\t\thint = target.name;\n\t\tif ((!hint) && target.constructor) {\n\t\t\thint = target.constructor.name;\n\t\t}\n\t}\n\treturn hint ?? '';\n}\n\n// Validate that 'target' is a class constructor function.\nfunction isClassConstructor(target: any) {\n\tif (typeof target === 'function' && target.hasOwnProperty('prototype')) {\n\t\treturn target.prototype.constructor === target;\n\t}\n\treturn false;\n}\n\n// Ensure consistency in our meta-data name getting/setting.\nfunction makeParamIdxKey(idx: number): string {\n\treturn `index-${idx}`;\n}\n\n// Key for @Inject/@Optional metadata stored on a method parameter.\nfunction makeMethodParamIdxKey(methodName: string | symbol, idx: number): string {\n\treturn `${String(methodName)}:index-${idx}`;\n}\n\n// Validate that the specified target is a parameter of a class constructor\nfunction validateConstructorParam(decorator: string, target: Function, idx: number): string {\n\tif (!isClassConstructor(target)) {\n\t\tthrow new Error('@' + decorator + ' is not valid here [' + targetHint(target) + ']');\n\t}\n\treturn makeParamIdxKey(idx);\n}\n\n// Validate that the target is an instance method parameter (non-constructor).\nfunction validateMethodParam(decorator: string, target: object, methodName: string | symbol, idx: number): string {\n\tif (typeof target !== 'object' || typeof (target as any).constructor !== 'function') {\n\t\tthrow new Error('@' + decorator + ' is not valid here [' + targetHint(target as Function) + ']');\n\t}\n\tif (!Reflect.hasOwnMetadata(REFLECT_PARAMS, target, methodName)) {\n\t\t// REFLECT_PARAMS not yet set (decoration order), so we cannot pre-validate the method; accept silently.\n\t}\n\treturn makeMethodParamIdxKey(methodName, idx);\n}\n\n// Validate the decorator was only applied once.\nfunction validateSingleConstructorParam(decorator: string, target: Function, idx: number): string {\n\tconst propKey = validateConstructorParam(decorator, target, idx);\n\tif (Reflect.hasOwnMetadata(decorator, target, propKey)) {\n\t\tthrow new Error('@' + decorator + ' applied multiple times [' + target.constructor.name + ']');\n\t}\n\treturn propKey;\n}\n\n/**\n * Placed just before the class declaration, this class decorator applies metadata to the class constructor indicating that the user intends to bind the class into the container.\n * This decorator will throw if not placed on a class declaration, or if placed more than once on a class declaration.\n */\nexport function Injectable(): ClassDecorator {\n\t/**\n\t * @param target The constructor function of the class that is being decorated\n\t * @returns Undefined (nothing), as this decorator does not modify the constructor in any way.\n\t */\n\treturn function (target: Function): void {\n\t\tif (Reflect.hasOwnMetadata(INJECTABLE_METADATA_KEY, target)) {\n\t\t\tthrow new Error('@Injectable applied multiple times [' + targetHint(target) + ']');\n\t\t}\n\t\tReflect.defineMetadata(INJECTABLE_METADATA_KEY, true, target);\n\t};\n}\n\n/**\n * Placed just before a constructor parameter, this parameter decorator allows for specificity and control over the type of Object that will be injected into the parameter.\n * In the absence of this decorator the container will use whatever is bound to a parameter's type (or throw an error if it is unable to recognize the type).\n * This decorator may also be placed on a parameter of a method annotated with @PostConstruct, in which case the container will resolve and inject the value before invoking that method.\n *\n * @param id The identifier of the bound type that should be injected.\n */\nexport function Inject(id: InjectableId<any>): ParameterDecorator {\n\t/**\n\t * @param target The constructor function of the class (for constructor params), or the class prototype (for method params).\n\t * @param parameterName The name of the parameter (undefined for constructor params, the method name for method params)\n\t * @param parameterIndex The ordinal index of the parameter in the function’s parameter list\n\t * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.\n\t */\n\treturn function (target: object, parameterName: string | symbol | undefined, parameterIndex: number): void {\n\t\tif (id === undefined) {\n\t\t\tthrow new Error('Undefined id passed to @Inject [' + targetHint(target as Function) + ']');\n\t\t}\n\t\tif (parameterName === undefined) {\n\t\t\t// Constructor parameter\n\t\t\tconst paramKey = validateSingleConstructorParam('Inject', target as Function, parameterIndex);\n\t\t\tReflect.defineMetadata(INJECT_METADATA_KEY, id, target, paramKey);\n\t\t}\n\t\telse {\n\t\t\t// Method parameter — silently accepted (intended for @PostConstruct methods)\n\t\t\tconst paramKey = validateMethodParam('Inject', target, parameterName, parameterIndex);\n\t\t\tReflect.defineMetadata(INJECT_METADATA_KEY, id, target, paramKey);\n\t\t}\n\t};\n}\n\n/**\n * This is a helper function used by the container to retrieve the @Inject metadata for a specifically indexed constructor parameter\n *\n * @param target The constructor function of the class (we don't allow @Inject on anything else).\n * @param parameterIndex The ordinal index of the parameter in the constructor’s parameter list\n * @see Inject\n */\nexport function _getInjectedIdAt(target: Function, parameterIndex: number): InjectableId<any> {\n\treturn Reflect.getMetadata(INJECT_METADATA_KEY, target, makeParamIdxKey(parameterIndex)) as InjectableId<any>;\n}\n\n/**\n * Retrieve the @Inject metadata for a specifically indexed parameter of a named method.\n */\nexport function _getInjectedIdForMethod(prototype: object, methodName: string | symbol, parameterIndex: number): InjectableId<any> {\n\treturn Reflect.getMetadata(INJECT_METADATA_KEY, prototype, makeMethodParamIdxKey(methodName, parameterIndex)) as InjectableId<any>;\n}\n\n/**\n * Placed just before a constructor parameter, this parameter decorator signals the container that it should supply the 'alt' constant value (undefined by default) if for *any* reason it is unable to otherwise resolve the type of the parameter.\n * This decorator may also be placed on a parameter of a method annotated with @PostConstruct.\n * WARNING! It is your responsibility to ensure that alt is of the appropriate type/value.\n */\nexport function Optional(alt?: any): ParameterDecorator {\n\t/**\n\t * @param target The constructor function of the class (for constructor params), or the class prototype (for method params).\n\t * @param parameterName The name of the parameter (undefined for constructor params, the method name for method params)\n\t * @param parameterIndex The ordinal index of the parameter in the function’s parameter list\n\t * @returns Undefined (nothing), as this decorator does not modify the parameter in any way.\n\t */\n\treturn function (target: object, parameterName: string | symbol | undefined, parameterIndex: number): void {\n\t\tif (parameterName === undefined) {\n\t\t\t// Constructor parameter\n\t\t\tconst paramKey = validateSingleConstructorParam('Optional', target as Function, parameterIndex);\n\t\t\tReflect.defineMetadata(OPTIONAL_METADATA_KEY, {value: alt}, target, paramKey);\n\t\t}\n\t\telse {\n\t\t\t// Method parameter — silently accepted (intended for @PostConstruct methods)\n\t\t\tconst paramKey = validateMethodParam('Optional', target, parameterName, parameterIndex);\n\t\t\tReflect.defineMetadata(OPTIONAL_METADATA_KEY, {value: alt}, target, paramKey);\n\t\t}\n\t};\n}\n\n/**\n * This is a helper function used by the container to retrieve the @Optional metadata for a specifically indexed constructor parameter\n *\n * @param target The constructor function of the class (we don't allow @Optional on anything else).\n * @param parameterIndex The ordinal index of the parameter in the constructor’s parameter list\n * @see Optional\n * @returns an object containing the value provided in the decorator, or undefined if no annotation was present.\n */\nexport function _getOptionalDefaultAt(target: Function, parameterIndex: number): { value: any } {\n\treturn Reflect.getMetadata(OPTIONAL_METADATA_KEY, target, makeParamIdxKey(parameterIndex)) as { value: any }; // See the @Optional decorator before making any changes here.\n}\n\n/**\n * Retrieve the @Optional metadata for a specifically indexed parameter of a named method.\n */\nexport function _getOptionalDefaultForMethod(prototype: object, methodName: string | symbol, parameterIndex: number): { value: any } {\n\treturn Reflect.getMetadata(OPTIONAL_METADATA_KEY, prototype, makeMethodParamIdxKey(methodName, parameterIndex)) as { value: any };\n}\n\n/**\n * Placed just before a class method, this method decorator flags a method that should be called after an object has been instantiated by the container, but before it is put into service.\n * The method will be assumed to be synchronous unless the method signature explicitly declares its return type to be \": Promise<something>\".\n * Parameters will be resolved by the container just as they are for constructors.\n * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.\n */\nexport function PostConstruct(): MethodDecorator {\n\t/**\n\t * @param prototypeOrConstructor The prototype of the class (we don't allow @PostConstruct on anything other than a class instance method.\n\t * @param methodName The name of the method.\n\t * @param _descriptor The Property Descriptor for the method.\n\t * @returns Undefined (nothing), as this decorator does not modify the method in any way.\n\t */\n\treturn function (target: Object, methodName: string | symbol, _descriptor: PropertyDescriptor) {\n\t\tif (typeof target !== 'object' || typeof target.constructor !== 'function') {\n\t\t\tthrow new Error('@PostConstruct not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');\n\t\t}\n\t\tif (Reflect.hasOwnMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, target.constructor) || Reflect.hasOwnMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, target.constructor)) {\n\t\t\tthrow new Error('@PostConstruct applied multiple times [' + targetHint(target.constructor) + ']');\n\t\t}\n\t\tconst rt = Reflect.getMetadata(REFLECT_RETURN, target, methodName);\n\t\tif (typeof rt === 'function') {\n\t\t\tReflect.defineMetadata(POSTCONSTRUCT_ASYNC_METADATA_KEY, methodName, target.constructor);\n\t\t}\n\t\telse {\n\t\t\tReflect.defineMetadata(POSTCONSTRUCT_SYNC_METADATA_KEY, methodName, target.constructor);\n\t\t}\n\t};\n}\n\n/**\n * Placed just before a class method, this decorator identifies a method which should be called when an object is removed from service.\n * If invoked by the container, the container will drop any references it has to the object when the method returns.\n * Note that this decorator is *not* a guarantee (or even an implication) that the decorated method will be called (JavaScript has no mechanism to enforce such a contract).\n * This decorator simply serves as a flag to indicate a method which is intended to clean up resources allocated by the object *which would not otherwise be garbage collected*.\n * You should *not* use this decorator as a general \"object finalization\" method. It has very limited scope and purpose.\n * The decorated method must complete normally (no throwing), as \"release\" is not an abort-able process.\n * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.\n * The @see InvokeReleaseMethod helper function can search for and invoke the @Release decorated method of an object.\n * Also @see Container.releaseSingletons for the intended usage of this decorator.\n * It is intended that after the @Release decorated method of an object is called, that object will not be used again, but this is of course not enforced).\n */\nexport function Release(): MethodDecorator {\n\t/**\n\t * @param prototypeOrConstructor The prototype of the class (we don't allow @Release on anything other than a class instance method.\n\t * @param methodName The name of the method.\n\t * @param _descriptor The Property Descriptor for the method.\n\t * @returns Undefined (nothing), as this decorator does not modify the method in any way.\n\t */\n\treturn function (target: Object, methodName: string | symbol, _descriptor: PropertyDescriptor) {\n\t\tif (typeof target !== 'object' || typeof target.constructor !== 'function') {\n\t\t\tthrow new Error('@Release not applied to instance method [' + target.toString() + '/' + methodName.toString() + ']');\n\t\t}\n\t\tif (Reflect.hasOwnMetadata(RELEASE_METADATA_KEY, target.constructor)) {\n\t\t\tthrow new Error('@Release applied multiple times [' + targetHint(target.constructor) + ']');\n\t\t}\n\t\tReflect.defineMetadata(RELEASE_METADATA_KEY, methodName, target.constructor);\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAA9B,sGAAA,SAAS,OAAA;AACjB,2CAAkF;AAA1E,oGAAA,MAAM,OAAA;AAAE,wGAAA,UAAU,OAAA;AAAE,sGAAA,QAAQ,OAAA;AAAE,2GAAA,aAAa,OAAA;AAAE,qGAAA,OAAO,OAAA;AAC5D,uCAAoF;AAA5C,0GAAA,cAAc,OAAA","sourcesContent":["export {Container} from './container';\nexport {Inject, Injectable, Optional, PostConstruct, Release} from './decorators';\nexport {ClassConstructor, InjectableId, InjectionToken, Injector} from './injector';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAA9B,sGAAA,SAAS,OAAA;AACjB,2CAAkF;AAA1E,oGAAA,MAAM,OAAA;AAAE,wGAAA,UAAU,OAAA;AAAE,sGAAA,QAAQ,OAAA;AAAE,2GAAA,aAAa,OAAA;AAAE,qGAAA,OAAO,OAAA;AAC5D,uCAAoF;AAA5C,0GAAA,cAAc,OAAA","sourcesContent":["export {Container} from './container';\nexport {Inject, Injectable, Optional, PostConstruct, Release} from './decorators';\nexport {ClassConstructor, InjectableId, InjectionToken, Injector} from './injector';\nexport {AsyncFactory, OnErrorCallback, OnSuccessCallback, RegisterDescriptor, SyncFactory} from './binding';\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"injector.js","sourceRoot":"","sources":["../../src/injector.ts"],"names":[],"mappings":";;;AASA;;;GAGG;AACH,MAAa,cAAc;IAC1B,YAAoB,EAAmB;QAAnB,OAAE,GAAF,EAAE,CAAiB;IACvC,CAAC;IAED,IAAI,WAAW;QACd,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED,QAAQ;QACP,qCAAqC;QACrC,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,IAAI,GAAI,IAAI,CAAC,EAA0C,CAAC,WAAW,CAAC;YAC1E,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;QACvD,CAAC;QACD,OAAO,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;IAC3B,CAAC;CACD;AAhBD,wCAgBC","sourcesContent":["/**\n * This is about as close as we can get in Typescript\n */\nexport type AbstractConstructor<T> = Function & { prototype: T };\n/**\n * Standard definition of a constructor.\n */\nexport type ClassConstructor<T> = new (...args: any[]) => T;\n\n/**\n * Allow for implicit typing of constants and interfaces.\n * Inspired by Angular and some colleges at work.\n */\nexport class InjectionToken<T> {\n\tconstructor(private id: string | symbol) {\n\t}\n\n\tget description(): string {\n\t\treturn this.toString();\n\t}\n\n\ttoString(): string {\n\t\t// noinspection SuspiciousTypeOfGuard\n\t\tif (typeof this.id === 'symbol') {\n\t\t\tconst desc = (this.id as unknown as { description?: string }).description;\n\t\t\treturn desc !== undefined ? desc : this.id.toString();\n\t\t}\n\t\treturn this.id.toString();\n\t}\n}\n\n/**\n * Universal id that can be bound to a constant, class, or factories.\n */\nexport type InjectableId<T> = (string | symbol | AbstractConstructor<T> | ClassConstructor<T> | InjectionToken<T>) & { readonly description?: string };\n\n/**\n * Retrieve instances previously bound to the specified InjectableId.\n */\nexport interface Injector {\n\t/**\n\t * Check to see if the existing InjectableId is known (aka has been bound).\n\t * Error callbacks may wish to know if a particular InjectableId is available.\n\t * Also the Binder's bindXXX calls always overwrite any previous bindings, so you may want to use this as a gate.\n\t *\n\t * @param id The id to check for.\n\t * @param ascending If true, this will search up the chain of parent containers (if they exist). Default is false (only checks if the id is bound within this container).\n\t */\n\tisIdKnown<T>(id: InjectableId<T> | AbstractConstructor<T>, ascending?: boolean): boolean;\n\n\t/**\n\t * Return an instance of <T> previously bound to 'id'.\n\t *\n\t * @throws Error if the InjectableId was never registered, OR if there are unresolved asynchronous dependencies in the dependency tree for 'id'.\n\t */\n\tget<T>(id: InjectableId<T> | AbstractConstructor<T>): T;\n\n\t/**\n\t * awaits the asynchronous resolution of all dependencies in the tree for 'id'.\n\t */\n\tresolve<T>(id?: InjectableId<T> | AbstractConstructor<T>): Promise<T>;\n}\n"]}
1
+ {"version":3,"file":"injector.js","sourceRoot":"","sources":["../../src/injector.ts"],"names":[],"mappings":";;;AASA;;;GAGG;AACH,MAAa,cAAc;IAC1B,YAAoB,EAAmB;QAAnB,OAAE,GAAF,EAAE,CAAiB;IACvC,CAAC;IAED,IAAI,WAAW;QACd,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED,QAAQ;QACP,qCAAqC;QACrC,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,IAAI,GAAI,IAAI,CAAC,EAA0C,CAAC,WAAW,CAAC;YAC1E,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;QACvD,CAAC;QACD,OAAO,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;IAC3B,CAAC;CACD;AAhBD,wCAgBC","sourcesContent":["/**\n * This is about as close as we can get in Typescript\n */\nexport type AbstractConstructor<T> = Function & { prototype: T };\n/**\n * Standard definition of a constructor.\n */\nexport type ClassConstructor<T> = new (...args: any[]) => T;\n\n/**\n * Allow for implicit typing of constants and interfaces.\n * Inspired by Angular and some colleges at work.\n */\nexport class InjectionToken<T> {\n\tconstructor(private id: string | symbol) {\n\t}\n\n\tget description(): string {\n\t\treturn this.toString();\n\t}\n\n\ttoString(): string {\n\t\t// noinspection SuspiciousTypeOfGuard\n\t\tif (typeof this.id === 'symbol') {\n\t\t\tconst desc = (this.id as unknown as { description?: string }).description;\n\t\t\treturn desc !== undefined ? desc : this.id.toString();\n\t\t}\n\t\treturn this.id.toString();\n\t}\n}\n\n/**\n * Universal id that can be bound to a constant, class, or factories.\n */\nexport type InjectableId<T> = (string | symbol | AbstractConstructor<T> | ClassConstructor<T> | InjectionToken<T>) & { readonly description?: string };\n\n/**\n * Retrieve instances previously bound to the specified InjectableId.\n */\nexport interface Injector {\n\t/**\n\t * Check to see if the existing InjectableId is known (aka has been bound).\n\t * Error callbacks may wish to know if a particular InjectableId is available.\n\t * Also the Container's bindXXX calls always overwrite any previous bindings, so you may want to use this as a gate.\n\t *\n\t * @param id The id to check for.\n\t * @param ascending If true, this will search up the chain of parent containers (if they exist). Default is false (only checks if the id is bound within this container).\n\t */\n\tisIdKnown<T>(id: InjectableId<T> | AbstractConstructor<T>, ascending?: boolean): boolean;\n\n\t/**\n\t * Return an instance of <T> previously bound to 'id'.\n\t *\n\t * @throws Error if the InjectableId was never registered, OR if there are unresolved asynchronous dependencies in the dependency tree for 'id'.\n\t */\n\tget<T>(id: InjectableId<T> | AbstractConstructor<T>): T;\n\n\t/**\n\t * awaits the asynchronous resolution of all dependencies in the tree for 'id'.\n\t */\n\tresolve<T>(id?: InjectableId<T> | AbstractConstructor<T>): Promise<T>;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/provider.ts"],"names":[],"mappings":";;;AACA,mCAA4C;AAG5C;;;GAGG;AACH,MAAsB,QAAQ;IAC7B;IACA,CAAC;IAiBD;;;;;;OAMG;IACH,kBAAkB,CAAC,UAAmB;QACrC,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YAChC,IAAI,CAAC,CAAC,OAAO;gBACZ,OAAO,CAAC,CAAC,OAAQ,CAAC;iBACd,IAAI,CAAC,CAAC,QAAQ;gBAClB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;;;;;;;;OAUG;IACH,kBAAkB;QACjB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YAChC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,IAAI,EAAE;oBAClB,IAAI,CAAC;wBACJ,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,OAAQ,CAAC;wBAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;wBACtB,IAAA,2BAAmB,EAAC,CAAC,CAAC,CAAC;wBACvB,OAAO,CAAC,CAAC;oBACV,CAAC;oBACD,WAAM,CAAC;wBACN,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;wBACtB,OAAO,IAAI,CAAC;oBACb,CAAC;gBACF,CAAC,CAAC,EAAE,CAAC;YACN,CAAC;iBACI,CAAC;gBACL,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;oBAClC,IAAA,2BAAmB,EAAC,CAAC,CAAC,SAAS,CAAC,CAAC;oBACjC,OAAO,CAAC,CAAC,SAAS,CAAC;gBACpB,CAAC;gBACD,OAAO,IAAI,CAAC;YACb,CAAC;QACF,CAAC;QACD,OAAO,SAAS,CAAA;IACjB,CAAC;CACD;AA5ED,4BA4EC","sourcesContent":["import {State} from './state';\nimport {InvokeReleaseMethod} from './utils';\n\n\n/**\n * Internally all InjectableIds are mapped to an abstract Provider<T>.\n * A Provider may choose to return a singleton or a new value each time it is queried.\n */\nexport abstract class Provider<T = any> {\n\tprotected constructor() {\n\t}\n\n\t/**\n\t * If the provider is configured as a singleton, this property will be the state of that singleton.\n\t * This value will be defined for resolved/resolving Singletons, null for Singletons that have not yet been queried, and will remain undefined for non-Singleton Providers.\n\t * Default value is undefined (e.g. not a Singleton).\n\t */\n\tprotected singleton?: State<T> | null;\n\n\t/**\n\t * This is the workhorse method of the Provider, and is invoked directly or indirectly by both Injector.get and Injector.resolve.\n\t * This method returns the current State<T> if it is already known (which it might be for Singleton scenarios).\n\t * Otherwise it resolves the State<T>.\n\t * IF the Provider<T> is a Singleton, it's State<T> is updated before returning.\n\t */\n\tabstract provideAsState(): State<T>;\n\n\t/**\n\t * Base method to initialize the state of this Provider *if* (and only if) it has been configured as a Singleton.\n\t * If this Provider has not been configured as a singleton, this method is essentially a noop that returns undefined.\n\t *\n\t * @param _asyncOnly This default implementation ignores this parameter.\n\t * @returns A completion Promise if initialization requires asynchronicity, otherwise the return value is undefined.\n\t */\n\tresolveIfSingleton(_asyncOnly: boolean): Promise<T> | undefined {\n\t\tif (this.singleton === null) {\n\t\t\tconst s = this.provideAsState();\n\t\t\tif (s.pending)\n\t\t\t\treturn s.promise!;\n\t\t\telse if (s.rejected)\n\t\t\t\treturn Promise.reject(s.rejected);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * If (and only if) this Provider has been configured as a Singleton, and if it has been (or is being resolved), find and invoke the @Release decorated method (if there is one).\n\t * NOTE that if the singleton is actively being resolved when this method is called, this method waits for the resolution to complete and then invokes the @Release decorated method; But in any case this is a synchronous method and returns immediately to it's caller.\n\t * Also note that invoking this method does not release or invalidate the Provider;\n\t * Rather, it resets a Singleton Provider to a fresh (unresolved/unqueried) state (aka sets this.singleton to null).\n\t * It is assumed that the Singleton itself will no longer be used after this method returns.\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\treleaseIfSingleton(): T | undefined | null | Promise<T | null> {\n\t\tif (this.singleton) {\n\t\t\tconst s = this.provideAsState();\n\t\t\tif (s.pending) {\n\t\t\t\treturn (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst v = await s.promise!;\n\t\t\t\t\t\tthis.singleton = null;\n\t\t\t\t\t\tInvokeReleaseMethod(v);\n\t\t\t\t\t\treturn v;\n\t\t\t\t\t}\n\t\t\t\t\tcatch {\n\t\t\t\t\t\tthis.singleton = null;\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.singleton = null;\n\t\t\t\tif ((!s.rejected) && s.fulfilled) {\n\t\t\t\t\tInvokeReleaseMethod(s.fulfilled);\n\t\t\t\t\treturn s.fulfilled;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\treturn undefined\n\t}\n}\n"]}
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/provider.ts"],"names":[],"mappings":";;;AACA,mCAA4C;AAG5C;;;GAGG;AACH,MAAsB,QAAQ;IAC7B;IACA,CAAC;IAiBD;;;;;;OAMG;IACH,kBAAkB,CAAC,UAAmB;QACrC,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YAChC,IAAI,CAAC,CAAC,OAAO;gBACZ,OAAO,CAAC,CAAC,OAAQ,CAAC;iBACd,IAAI,CAAC,CAAC,QAAQ;gBAClB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;;;;;;;;OAUG;IACH,kBAAkB;QACjB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YAChC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,IAAI,EAAE;oBAClB,IAAI,CAAC;wBACJ,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,OAAQ,CAAC;wBAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;wBACtB,IAAA,2BAAmB,EAAC,CAAC,CAAC,CAAC;wBACvB,OAAO,CAAC,CAAC;oBACV,CAAC;oBACD,WAAM,CAAC;wBACN,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;wBACtB,OAAO,IAAI,CAAC;oBACb,CAAC;gBACF,CAAC,CAAC,EAAE,CAAC;YACN,CAAC;iBACI,CAAC;gBACL,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;oBAClC,IAAA,2BAAmB,EAAC,CAAC,CAAC,SAAS,CAAC,CAAC;oBACjC,OAAO,CAAC,CAAC,SAAS,CAAC;gBACpB,CAAC;gBACD,OAAO,IAAI,CAAC;YACb,CAAC;QACF,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;CACD;AA5ED,4BA4EC","sourcesContent":["import {State} from './state';\nimport {InvokeReleaseMethod} from './utils';\n\n\n/**\n * Internally all InjectableIds are mapped to an abstract Provider<T>.\n * A Provider may choose to return a singleton or a new value each time it is queried.\n */\nexport abstract class Provider<T = any> {\n\tprotected constructor() {\n\t}\n\n\t/**\n\t * If the provider is configured as a singleton, this property will be the state of that singleton.\n\t * This value will be defined for resolved/resolving Singletons, null for Singletons that have not yet been queried, and will remain undefined for non-Singleton Providers.\n\t * Default value is undefined (e.g. not a Singleton).\n\t */\n\tprotected singleton?: State<T> | null;\n\n\t/**\n\t * This is the workhorse method of the Provider, and is invoked directly or indirectly by both Injector.get and Injector.resolve.\n\t * This method returns the current State<T> if it is already known (which it might be for Singleton scenarios).\n\t * Otherwise it resolves the State<T>.\n\t * IF the Provider<T> is a Singleton, it's State<T> is updated before returning.\n\t */\n\tabstract provideAsState(): State<T>;\n\n\t/**\n\t * Base method to initialize the state of this Provider *if* (and only if) it has been configured as a Singleton.\n\t * If this Provider has not been configured as a singleton, this method is essentially a noop that returns undefined.\n\t *\n\t * @param _asyncOnly This default implementation ignores this parameter.\n\t * @returns A completion Promise if initialization requires asynchronicity, otherwise the return value is undefined.\n\t */\n\tresolveIfSingleton(_asyncOnly: boolean): Promise<T> | undefined {\n\t\tif (this.singleton === null) {\n\t\t\tconst s = this.provideAsState();\n\t\t\tif (s.pending)\n\t\t\t\treturn s.promise!;\n\t\t\telse if (s.rejected)\n\t\t\t\treturn Promise.reject(s.rejected);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * If (and only if) this Provider has been configured as a Singleton, and if it has been (or is being resolved), find and invoke the @Release decorated method (if there is one).\n\t * NOTE that if the singleton is actively being resolved when this method is called, this method waits for the resolution to complete and then invokes the @Release decorated method; But in any case this is a synchronous method and returns immediately to it's caller.\n\t * Also note that invoking this method does not release or invalidate the Provider;\n\t * Rather, it resets a Singleton Provider to a fresh (unresolved/unqueried) state (aka sets this.singleton to null).\n\t * It is assumed that the Singleton itself will no longer be used after this method returns.\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\treleaseIfSingleton(): T | undefined | null | Promise<T | null> {\n\t\tif (this.singleton) {\n\t\t\tconst s = this.provideAsState();\n\t\t\tif (s.pending) {\n\t\t\t\treturn (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst v = await s.promise!;\n\t\t\t\t\t\tthis.singleton = null;\n\t\t\t\t\t\tInvokeReleaseMethod(v);\n\t\t\t\t\t\treturn v;\n\t\t\t\t\t}\n\t\t\t\t\tcatch {\n\t\t\t\t\t\tthis.singleton = null;\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.singleton = null;\n\t\t\t\tif ((!s.rejected) && s.fulfilled) {\n\t\t\t\t\tInvokeReleaseMethod(s.fulfilled);\n\t\t\t\t\treturn s.fulfilled;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"sync-factory-provider.js","sourceRoot":"","sources":["../../src/sync-factory-provider.ts"],"names":[],"mappings":";;;AAAA,2DAAqD;AAGrD,mCAA8B;AAE9B;;;GAGG;AACH,MAAa,oBAAwB,SAAQ,oCAAmC;IAC/E,YAAY,QAAkB,EAAE,EAAmB,EAAE,KAAqB;QACzE,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,cAAc;QACb,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,IAAI,CAAC;gBACJ,MAAM,GAAG,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YACzE,CAAC;YACD,OAAO,GAAG,EAAE,CAAC;gBACZ,0EAA0E;gBAC1E,IAAI,CAAC;oBACJ,wEAAwE;oBACxE,MAAM,GAAG,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC3E,CAAC;gBACD,OAAO,CAAC,EAAE,CAAC;oBACV,0CAA0C;oBAC1C,MAAM,GAAG,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;gBACjD,CAAC;YACF,CAAC;QACF,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;YAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,kBAAkB,CAAC,SAAkB;QACpC,IAAI,SAAS;YACZ,OAAO,SAAS,CAAC;QAClB,OAAO,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;CACD;AAzCD,oDAyCC","sourcesContent":["import {BindableProvider} from './bindable-provider';\nimport {SyncFactory} from './binder';\nimport {InjectableId, Injector} from './injector';\nimport {State} from './state';\n\n/**\n * @inheritDoc\n * This specialization simply invokes it's configured Factory and provides the result.\n */\nexport class FactoryBasedProvider<T> extends BindableProvider<T, SyncFactory<T>> {\n\tconstructor(injector: Injector, id: InjectableId<T>, maker: SyncFactory<T>) {\n\t\tsuper(injector, id, maker);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization invokes it's configured Factory and provides the result (or invokes the error handler if necessary).\n\t */\n\tprovideAsState(): State<T> {\n\t\tlet retVal = this.singleton;\n\t\tif (!retVal) {\n\t\t\ttry {\n\t\t\t\tretVal = State.MakeState<T>(null, undefined, this.maker(this.injector));\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\t// There was an error, give the errorHandler (if any) a crack at recovery.\n\t\t\t\ttry {\n\t\t\t\t\t// queryErrorHandler will throw if it could not get a substitute object.\n\t\t\t\t\tretVal = State.MakeState<T>(null, undefined, this.queryErrorHandler(err));\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\tretVal = State.MakeState<T>(null, e, undefined);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.singleton === null)\n\t\t\tthis.singleton = retVal;\n\t\treturn retVal;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization returns undefined anytime 'asyncOnly' is true (since this Provider is by definition synchronous).\n\t */\n\tresolveIfSingleton(asyncOnly: boolean): Promise<T> | undefined {\n\t\tif (asyncOnly)\n\t\t\treturn undefined;\n\t\treturn super.resolveIfSingleton(false);\n\t}\n}\n"]}
1
+ {"version":3,"file":"sync-factory-provider.js","sourceRoot":"","sources":["../../src/sync-factory-provider.ts"],"names":[],"mappings":";;;AAAA,2DAAqD;AAGrD,mCAA8B;AAE9B;;;GAGG;AACH,MAAa,oBAAwB,SAAQ,oCAAmC;IAC/E,YAAY,QAAkB,EAAE,EAAmB,EAAE,KAAqB;QACzE,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,cAAc;QACb,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,IAAI,CAAC;gBACJ,MAAM,GAAG,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YACzE,CAAC;YACD,OAAO,GAAG,EAAE,CAAC;gBACZ,0EAA0E;gBAC1E,IAAI,CAAC;oBACJ,wEAAwE;oBACxE,MAAM,GAAG,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC3E,CAAC;gBACD,OAAO,CAAC,EAAE,CAAC;oBACV,0CAA0C;oBAC1C,MAAM,GAAG,aAAK,CAAC,SAAS,CAAI,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;gBACjD,CAAC;YACF,CAAC;QACF,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;YAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,kBAAkB,CAAC,SAAkB;QACpC,IAAI,SAAS;YACZ,OAAO,SAAS,CAAC;QAClB,OAAO,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;CACD;AAzCD,oDAyCC","sourcesContent":["import {BindableProvider} from './bindable-provider';\nimport {SyncFactory} from './binding';\nimport {InjectableId, Injector} from './injector';\nimport {State} from './state';\n\n/**\n * @inheritDoc\n * This specialization simply invokes it's configured Factory and provides the result.\n */\nexport class FactoryBasedProvider<T> extends BindableProvider<T, SyncFactory<T>> {\n\tconstructor(injector: Injector, id: InjectableId<T>, maker: SyncFactory<T>) {\n\t\tsuper(injector, id, maker);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization invokes it's configured Factory and provides the result (or invokes the error handler if necessary).\n\t */\n\tprovideAsState(): State<T> {\n\t\tlet retVal = this.singleton;\n\t\tif (!retVal) {\n\t\t\ttry {\n\t\t\t\tretVal = State.MakeState<T>(null, undefined, this.maker(this.injector));\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\t// There was an error, give the errorHandler (if any) a crack at recovery.\n\t\t\t\ttry {\n\t\t\t\t\t// queryErrorHandler will throw if it could not get a substitute object.\n\t\t\t\t\tretVal = State.MakeState<T>(null, undefined, this.queryErrorHandler(err));\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\tretVal = State.MakeState<T>(null, e, undefined);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.singleton === null)\n\t\t\tthis.singleton = retVal;\n\t\treturn retVal;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization returns undefined anytime 'asyncOnly' is true (since this Provider is by definition synchronous).\n\t */\n\tresolveIfSingleton(asyncOnly: boolean): Promise<T> | undefined {\n\t\tif (asyncOnly)\n\t\t\treturn undefined;\n\t\treturn super.resolveIfSingleton(false);\n\t}\n}\n"]}
@@ -18,13 +18,27 @@ export declare class ClassBasedProvider<T> extends BindableProvider<T, ClassCons
18
18
  provideAsState(): State<T>;
19
19
  /**
20
20
  * @inheritDoc
21
- * This specialization returns undefined if 'asyncOnly' is true and there is no asynchronous PostConstruct annotation (since class constructors can never by asynchronous).
21
+ * This specialization returns undefined if 'asyncOnly' is true **and** there is no asynchronous PostConstruct annotation (since class constructors can never by asynchronous),
22
+ * **unless** the @PostConstruct method has injectable parameters, which may themselves require async resolution.
22
23
  */
23
24
  resolveIfSingleton(asyncOnly: boolean): Promise<T> | undefined;
24
25
  /**
25
- * Make a resolved or pending State that reflects any @PostConstruct annotations.
26
+ * Returns true if the @PostConstruct method (if any) has at least one parameter.
27
+ * Any parameter may require async resolution, so this class must participate in resolveSingletons.
28
+ */
29
+ private postConstructHasParams;
30
+ /**
31
+ * Make a resolved or pending State that reflects any @PostConstruct annotations and/or onSuccess handler.
32
+ * Any @PostConstruct method (with any injected parameters) runs first; the onSuccess handler runs after.
26
33
  */
27
34
  protected makePostConstructState(obj: T): State<T>;
35
+ /**
36
+ * Collects the resolved States for all injectable parameters of a @PostConstruct method.
37
+ * 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.
38
+ * Use @Optional() on a parameter to supply a fallback when no binding is found.
39
+ * Returns an empty array if the method has no parameters.
40
+ */
41
+ protected getMethodParameterStates(ctor: Function, methodName: string): State[];
28
42
  /**
29
43
  * This method collects the States of all the constructor parameters for our target class.
30
44
  */
@@ -1,11 +1,11 @@
1
- import { AsyncFactory, BindAs, Binder, SyncFactory } from './binder';
1
+ import { AsyncFactory, BindAs, RegisterDescriptor, SyncFactory } from './binding';
2
2
  import { AbstractConstructor, ClassConstructor, InjectableId, Injector } from './injector';
3
3
  import { Provider } from './provider';
4
4
  import { State } from './state';
5
5
  /**
6
- * Binder and Injector (aka Container) to handle (a)synchronous dependency management.
6
+ * Injector (aka Container) to handle (a)synchronous dependency management.
7
7
  */
8
- export declare class Container implements Binder {
8
+ export declare class Container implements Injector {
9
9
  protected parent?: Injector | undefined;
10
10
  /**
11
11
  * Create a new Container, with an optional parent Injector which will be searched if any given InjectableId is not bound within this Container.
@@ -25,14 +25,40 @@ export declare class Container implements Binder {
25
25
  */
26
26
  resolve<T>(id: InjectableId<T>): Promise<T>;
27
27
  /**
28
- * This method is not part of the Binding interface, because it is highly unusual.
29
- * But that doesn't mean we can't imagine scenarios where you might require it.
28
+ * Removes a binding from this Container (and optionally its ancestor chain).
29
+ * Most useful in unit tests to replace or clear bindings between test cases.
30
+ * **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.
30
31
  *
31
- * @param id The id to be removed.
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.
32
+ * @param id The id of the binding to remove.
33
+ * @param ascending If true, the binding is also removed from every Container in the parent chain.
34
+ * @param releaseIfSingleton If true, Provider.releaseIfSingleton is called before removal.
34
35
  */
35
36
  removeBinding<T>(id: InjectableId<T>, ascending?: boolean, releaseIfSingleton?: boolean): void;
37
+ /**
38
+ * Alias for {@link isIdKnown}. Familiar to users migrating from TypeDI.
39
+ */
40
+ has<T>(id: InjectableId<T>, ascending?: boolean): boolean;
41
+ /**
42
+ * Alias for {@link removeBinding}. Familiar to users migrating from InversifyJS.
43
+ */
44
+ unbind<T>(id: InjectableId<T>, ascending?: boolean, releaseIfSingleton?: boolean): void;
45
+ /**
46
+ * Creates a new child Container that inherits unbound ids from this Container.
47
+ * Familiar to users migrating from TSyringe.
48
+ */
49
+ createChildContainer(): Container;
50
+ /**
51
+ * Descriptor-based binding dispatching to the appropriate bindXXX method.
52
+ * Familiar to users migrating from TSyringe.
53
+ * Returns a {@link BindAs} chain for class and factory bindings; returns undefined for value bindings (which are always singletons).
54
+ */
55
+ register<T>(id: InjectableId<T>, descriptor: RegisterDescriptor<T>): BindAs<T, any> | undefined;
56
+ /**
57
+ * Binds a class as a singleton in one step.
58
+ * Shorthand for {@link bindClass}(...).{@link BindAs.asSingleton asSingleton}().
59
+ * Familiar to users migrating from TSyringe.
60
+ */
61
+ registerSingleton<T>(id: InjectableId<T>, constructor: ClassConstructor<T>): void;
36
62
  /**
37
63
  * @inheritDoc
38
64
  */
@@ -61,18 +87,18 @@ export declare class Container implements Binder {
61
87
  protected resolveState<T>(id: InjectableId<T>): State<T>;
62
88
  /**
63
89
  * 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.
90
+ * It will walk through all registered Providers (of this Container only), and invoke their Provider.releaseIfSingleton method.
91
+ * This method is not part of the Injector interface, because you normally only create (and release) from Containers.
66
92
  * NOTE:
67
93
  * 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.
94
+ * 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.
69
95
  * 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
96
  * 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
97
  */
72
98
  releaseSingletons(): void;
73
99
  /**
74
100
  * Releases a Singleton instance if it exists.
75
- * However, it does **not** remove the binding, so if you call @get or @resolve (directly or indirectly) on the id, a new Singleton will be created.
101
+ * However, it does **not** remove the binding, so if you call get or resolve (directly or indirectly) on the id, a new Singleton will be created.
76
102
  * If not a singleton, this method returns undefined.
77
103
  * If the singleton has been resolved, it is returned, otherwise null is returned.
78
104
  * If the singleton is pending resolution, a Promise for the singleton (or for null) is returned.
@@ -80,7 +106,7 @@ export declare class Container implements Binder {
80
106
  */
81
107
  releaseSingleton<T>(id: InjectableId<T>): T | undefined | null | Promise<T | null>;
82
108
  /**
83
- * Make a copy of this @see Container.
109
+ * Make a copy of this Container.
84
110
  * This is an experimental feature!
85
111
  * I have not thought through all the dark corners, so use at your own peril!
86
112
  * Here are some notes:
@@ -92,7 +118,7 @@ export declare class Container implements Binder {
92
118
  * If released by the clone, they will be considered released by "this" container.
93
119
  * If a singleton is currently being asynchronously constructed any callbacks will reference "this" Container, however both Containers should have no problem awaiting resolution.
94
120
  * If a singleton is not resolved when the container is cloned, then if both containers resolve, you will create *two* "singletons".
95
- * The way to avoid this last effect is to @see resolveSingletons
121
+ * The way to avoid this last effect is to call resolveSingletons first
96
122
  */
97
123
  clone(clazz?: ClassConstructor<Container>): Container;
98
124
  }
@@ -5,8 +5,9 @@ import { InjectableId } from './injector';
5
5
  */
6
6
  export declare function Injectable(): ClassDecorator;
7
7
  /**
8
- * Placed just before a constructor parameter, this parameter decorator allows for specificity and control over the type of the type of Object that will be injected into the parameter.
8
+ * Placed just before a constructor parameter, this parameter decorator allows for specificity and control over the type of Object that will be injected into the parameter.
9
9
  * In the absence of this decorator the container will use whatever is bound to a parameter's type (or throw an error if it is unable to recognize the type).
10
+ * This decorator may also be placed on a parameter of a method annotated with @PostConstruct, in which case the container will resolve and inject the value before invoking that method.
10
11
  *
11
12
  * @param id The identifier of the bound type that should be injected.
12
13
  */
@@ -19,8 +20,13 @@ export declare function Inject(id: InjectableId<any>): ParameterDecorator;
19
20
  * @see Inject
20
21
  */
21
22
  export declare function _getInjectedIdAt(target: Function, parameterIndex: number): InjectableId<any>;
23
+ /**
24
+ * Retrieve the @Inject metadata for a specifically indexed parameter of a named method.
25
+ */
26
+ export declare function _getInjectedIdForMethod(prototype: object, methodName: string | symbol, parameterIndex: number): InjectableId<any>;
22
27
  /**
23
28
  * Placed just before a constructor parameter, this parameter decorator signals the container that it should supply the 'alt' constant value (undefined by default) if for *any* reason it is unable to otherwise resolve the type of the parameter.
29
+ * This decorator may also be placed on a parameter of a method annotated with @PostConstruct.
24
30
  * WARNING! It is your responsibility to ensure that alt is of the appropriate type/value.
25
31
  */
26
32
  export declare function Optional(alt?: any): ParameterDecorator;
@@ -35,9 +41,16 @@ export declare function Optional(alt?: any): ParameterDecorator;
35
41
  export declare function _getOptionalDefaultAt(target: Function, parameterIndex: number): {
36
42
  value: any;
37
43
  };
44
+ /**
45
+ * Retrieve the @Optional metadata for a specifically indexed parameter of a named method.
46
+ */
47
+ export declare function _getOptionalDefaultForMethod(prototype: object, methodName: string | symbol, parameterIndex: number): {
48
+ value: any;
49
+ };
38
50
  /**
39
51
  * Placed just before a class method, this method decorator flags a method that should be called after an object has been instantiated by the container, but before it is put into service.
40
- * The method will be assumed to be synchronous unless the method signature explicitly declares it's return type to be ": Promise<something>"
52
+ * The method will be assumed to be synchronous unless the method signature explicitly declares its return type to be ": Promise<something>".
53
+ * Parameters will be resolved by the container just as they are for constructors.
41
54
  * This decorator will throw if placed on a non-method or a static method of a class, or if placed on a method more than once, or if placed on more than one method for a class.
42
55
  */
43
56
  export declare function PostConstruct(): MethodDecorator;
@@ -1 +1 @@
1
- {"version":3,"file":"async-factory-provider.js","sourceRoot":"","sources":["../../src/async-factory-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAC;AAE9B;;;GAGG;AACH,MAAM,OAAO,yBAA6B,SAAQ,gBAAoC;IACrF,YAAY,QAAkB,EAAE,EAAmB,EAAE,KAAsB;QAC1E,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,cAAc;QACb,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,qEAAqE;YACrE,+HAA+H;YAC/H,MAAM,GAAG,KAAK,CAAC,SAAS,CAAI,IAAI,CAAC,iBAAiB,CAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/F,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;YAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;CACD","sourcesContent":["import {BindableProvider} from './bindable-provider';\nimport {AsyncFactory} from './binder';\nimport {InjectableId, Injector} from './injector';\nimport {State} from './state';\n\n/**\n * @inheritDoc\n * This specialization invokes it's configured Factory asynchronously and waits until it can provide the result.\n */\nexport class AsyncFactoryBasedProvider<T> extends BindableProvider<T, AsyncFactory<T>> {\n\tconstructor(injector: Injector, id: InjectableId<T>, maker: AsyncFactory<T>) {\n\t\tsuper(injector, id, maker);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization invokes it's configured Factory and provides the result (or invokes the error handler if necessary).\n\t */\n\tprovideAsState(): State<T> {\n\t\tlet retVal = this.singleton;\n\t\tif (!retVal) {\n\t\t\t// Wrap the async factory's Promise in an errorHandler aware Promise.\n\t\t\t// Our contract is that an AsyncFactory may not throw and must return a valid Promise (e.g., pending, resolved, rejected, etc).\n\t\t\tretVal = State.MakeState<T>(this.makePromiseForObj<T>(this.maker(this.injector), obj => obj));\n\t\t}\n\t\tif (this.singleton === null)\n\t\t\tthis.singleton = retVal;\n\t\treturn retVal;\n\t}\n}\n"]}
1
+ {"version":3,"file":"async-factory-provider.js","sourceRoot":"","sources":["../../src/async-factory-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAC;AAE9B;;;GAGG;AACH,MAAM,OAAO,yBAA6B,SAAQ,gBAAoC;IACrF,YAAY,QAAkB,EAAE,EAAmB,EAAE,KAAsB;QAC1E,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,cAAc;QACb,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,qEAAqE;YACrE,+HAA+H;YAC/H,MAAM,GAAG,KAAK,CAAC,SAAS,CAAI,IAAI,CAAC,iBAAiB,CAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/F,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;YAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;CACD","sourcesContent":["import {BindableProvider} from './bindable-provider';\nimport {AsyncFactory} from './binding';\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"]}
@@ -12,7 +12,7 @@ export class BindableProvider extends Provider {
12
12
  this.maker = maker;
13
13
  }
14
14
  /**
15
- * Invoked by the Binder to create chain-able configuration
15
+ * Invoked by the Container to create chain-able configuration
16
16
  *
17
17
  * @see BindAs
18
18
  */
@@ -46,13 +46,13 @@ export class BindableProvider extends Provider {
46
46
  // Error handler wants us to propagate an error.
47
47
  if (isErrorObj(handlerResult))
48
48
  throw handlerResult;
49
- // Error handler has no opinion, so provideAsState a state that reflects the error we just caught.
49
+ // Error handler has no opinion, so propagate the error we just caught.
50
50
  if (typeof handlerResult === 'undefined')
51
51
  throw err;
52
52
  // Error handler provided a valid (fully resolved) replacement.
53
53
  return handlerResult;
54
54
  }
55
- // No error handler, provideAsState a state that reflects the error we just caught.
55
+ // No error handler, propagate the error we just caught.
56
56
  throw err;
57
57
  }
58
58
  /**
@@ -64,33 +64,20 @@ export class BindableProvider extends Provider {
64
64
  * @param cb Callback to be invoked if the supplied Promise resolves.
65
65
  */
66
66
  async makePromiseForObj(waitFor, cb) {
67
- // Local helper: consults the errorHandler (if any) for recovery; returns a substitute or re-throws.
68
- const handleError = (err, objValue) => {
69
- if (this.errorHandler) {
70
- const handlerResult = this.errorHandler(this.injector, this.id, this.maker, err, objValue);
71
- // Error handler wants us to propagate an alternative error.
72
- if (isErrorObj(handlerResult))
73
- throw handlerResult;
74
- // Error handler provided a valid (fully resolved) replacement.
75
- else if (typeof handlerResult !== 'undefined')
76
- return handlerResult;
77
- }
78
- throw err;
79
- };
80
67
  let result;
81
68
  try {
82
69
  result = await waitFor;
83
70
  }
84
71
  catch (err) {
85
72
  // waitFor rejected — ask the error handler for recovery, passing cb(undefined) as the partial object value.
86
- return handleError(err, cb(undefined));
73
+ return this.queryErrorHandler(err, cb(undefined));
87
74
  }
88
75
  try {
89
76
  return cb(result);
90
77
  }
91
78
  catch (err) {
92
79
  // cb threw after a successful resolution — ask the error handler for recovery.
93
- return handleError(err, cb(result));
80
+ return this.queryErrorHandler(err, cb(result));
94
81
  }
95
82
  }
96
83
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bindable-provider.js","sourceRoot":"","sources":["../../src/bindable-provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AACpC,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAC;AAEnC;;;GAGG;AACH,MAAM,OAAgB,gBAAgF,SAAQ,QAAW;IACxH,YAAgC,QAAkB,EAAY,EAAmB,EAAY,KAAQ;QACpG,KAAK,EAAE,CAAC;QADuB,aAAQ,GAAR,QAAQ,CAAU;QAAY,OAAE,GAAF,EAAE,CAAiB;QAAY,UAAK,GAAL,KAAK,CAAG;IAErG,CAAC;IAcD;;;;OAIG;IACH,UAAU;QACT,MAAM,MAAM,GAAiB;YAC5B,OAAO,EAAE,CAAC,EAAyB,EAAE,EAAE;gBACtC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;YACxB,CAAC;YACD,SAAS,EAAE,CAAC,EAA2B,EAAE,EAAE;gBAC1C,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;gBACzB,OAAO,MAAM,CAAC;YACf,CAAC;YACD,WAAW,EAAE,GAAG,EAAE;gBACjB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,qCAAqC;gBAC5D,OAAO,MAAM,CAAC;YACf,CAAC;SACD,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACO,iBAAiB,CAAC,GAAY,EAAE,GAAO;QAChD,oHAAoH;QACpH,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YACtF,gDAAgD;YAChD,IAAI,UAAU,CAAC,aAAa,CAAC;gBAC5B,MAAM,aAAa,CAAC;YACrB,kGAAkG;YAClG,IAAI,OAAO,aAAa,KAAK,WAAW;gBACvC,MAAM,GAAG,CAAC;YACX,+DAA+D;YAC/D,OAAO,aAAa,CAAC;QACtB,CAAC;QACD,mFAAmF;QACnF,MAAM,GAAG,CAAC;IACX,CAAC;IAED;;;;;;;OAOG;IACO,KAAK,CAAC,iBAAiB,CAAI,OAAmB,EAAE,EAAoB;QAC7E,oGAAoG;QACpG,MAAM,WAAW,GAAG,CAAC,GAAY,EAAE,QAAY,EAAK,EAAE;YACrD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACvB,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;gBAC3F,4DAA4D;gBAC5D,IAAI,UAAU,CAAC,aAAa,CAAC;oBAC5B,MAAM,aAAa,CAAC;gBACrB,+DAA+D;qBAC1D,IAAI,OAAO,aAAa,KAAK,WAAW;oBAC5C,OAAO,aAAa,CAAC;YACvB,CAAC;YACD,MAAM,GAAG,CAAC;QACX,CAAC,CAAC;QACF,IAAI,MAAS,CAAC;QACd,IAAI,CAAC;YACJ,MAAM,GAAG,MAAM,OAAO,CAAC;QACxB,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;YACZ,4GAA4G;YAC5G,OAAO,WAAW,CAAC,GAAG,EAAE,EAAE,CAAC,SAAyB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,CAAC;YACJ,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;YACZ,+EAA+E;YAC/E,OAAO,WAAW,CAAC,GAAG,EAAE,EAAE,CAAC,MAAW,CAAC,CAAC,CAAC;QAC1C,CAAC;IACF,CAAC;CACD","sourcesContent":["import {AsyncFactory, BindAs, OnErrorCallback, OnSuccessCallback, SyncFactory} from './binder';\nimport {ClassConstructor, InjectableId, Injector} from './injector';\nimport {Provider} from './provider';\nimport {isErrorObj} from './utils';\n\n/**\n * @inheritDoc\n * This abstraction is for Providers that can be additionally configured as Singletons and/or configured with error and/or success handling callback(s).\n */\nexport abstract class BindableProvider<T, M = ClassConstructor<T> | SyncFactory<T> | AsyncFactory<T>> extends Provider<T> {\n\tprotected constructor(protected injector: Injector, protected id: InjectableId<T>, protected maker: M) {\n\t\tsuper();\n\t}\n\n\t/**\n\t * A user supplied success handling function.\n\t * Default value is undefined.\n\t */\n\tprotected successHandler?: OnSuccessCallback<T, any>;\n\n\t/**\n\t * A user supplied error handling function.\n\t * Default value is undefined.\n\t */\n\tprotected errorHandler?: OnErrorCallback<T, any>;\n\n\t/**\n\t * Invoked by the Binder to create chain-able configuration\n\t *\n\t * @see BindAs\n\t */\n\tmakeBindAs(): BindAs<T, M> {\n\t\tconst retVal: BindAs<T, M> = {\n\t\t\tonError: (cb: OnErrorCallback<T, M>) => {\n\t\t\t\tthis.errorHandler = cb;\n\t\t\t},\n\t\t\tonSuccess: (cb: OnSuccessCallback<T, M>) => {\n\t\t\t\tthis.successHandler = cb;\n\t\t\t\treturn retVal;\n\t\t\t},\n\t\t\tasSingleton: () => {\n\t\t\t\tthis.singleton = null; // Flag state as no longer undefined.\n\t\t\t\treturn retVal;\n\t\t\t}\n\t\t};\n\t\treturn retVal;\n\t}\n\n\t/**\n\t * Encapsulate the logic of invoking any configured error handler, and processing it's result.\n\t *\n\t * @see OnErrorCallback\n\t *\n\t * @returns The object substituted by the callback (otherwise this method throws the appropriate error).\n\t */\n\tprotected queryErrorHandler(err: unknown, obj?: T): T {\n\t\t// There was an error during construction, see if an error handler was provided, and if so, see what it wants to do.\n\t\tif (this.errorHandler) {\n\t\t\tconst handlerResult = this.errorHandler(this.injector, this.id, this.maker, err, obj);\n\t\t\t// Error handler wants us to propagate an error.\n\t\t\tif (isErrorObj(handlerResult))\n\t\t\t\tthrow handlerResult;\n\t\t\t// Error handler has no opinion, so provideAsState a state that reflects the error we just caught.\n\t\t\tif (typeof handlerResult === 'undefined')\n\t\t\t\tthrow err;\n\t\t\t// Error handler provided a valid (fully resolved) replacement.\n\t\t\treturn handlerResult;\n\t\t}\n\t\t// No error handler, provideAsState a state that reflects the error we just caught.\n\t\tthrow err;\n\t}\n\n\t/**\n\t * This is like a retry mechanism that uses the Provider's errorHandler (if any) to attempt recovery whenever the supplied Promise rejects.\n\t * This method returns a Promise that rejects if recovery was not possible.\n\t * If the supplied Promise resolves, then this method passes the result to the callback, and then resolve as whatever that callback returns.\n\t *\n\t * @param waitFor The supplied Promise.\n\t * @param cb Callback to be invoked if the supplied Promise resolves.\n\t */\n\tprotected async makePromiseForObj<R>(waitFor: Promise<R>, cb: (result: R) => T): Promise<T> {\n\t\t// Local helper: consults the errorHandler (if any) for recovery; returns a substitute or re-throws.\n\t\tconst handleError = (err: unknown, objValue?: T): T => {\n\t\t\tif (this.errorHandler) {\n\t\t\t\tconst handlerResult = this.errorHandler(this.injector, this.id, this.maker, err, objValue);\n\t\t\t\t// Error handler wants us to propagate an alternative error.\n\t\t\t\tif (isErrorObj(handlerResult))\n\t\t\t\t\tthrow handlerResult;\n\t\t\t\t// Error handler provided a valid (fully resolved) replacement.\n\t\t\t\telse if (typeof handlerResult !== 'undefined')\n\t\t\t\t\treturn handlerResult;\n\t\t\t}\n\t\t\tthrow err;\n\t\t};\n\t\tlet result: R;\n\t\ttry {\n\t\t\tresult = await waitFor;\n\t\t}\n\t\tcatch (err) {\n\t\t\t// waitFor rejected — ask the error handler for recovery, passing cb(undefined) as the partial object value.\n\t\t\treturn handleError(err, cb(undefined as unknown as R));\n\t\t}\n\t\ttry {\n\t\t\treturn cb(result);\n\t\t}\n\t\tcatch (err) {\n\t\t\t// cb threw after a successful resolution — ask the error handler for recovery.\n\t\t\treturn handleError(err, cb(result as R));\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"bindable-provider.js","sourceRoot":"","sources":["../../src/bindable-provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AACpC,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAC;AAEnC;;;GAGG;AACH,MAAM,OAAgB,gBAAgF,SAAQ,QAAW;IACxH,YAAgC,QAAkB,EAAY,EAAmB,EAAY,KAAQ;QACpG,KAAK,EAAE,CAAC;QADuB,aAAQ,GAAR,QAAQ,CAAU;QAAY,OAAE,GAAF,EAAE,CAAiB;QAAY,UAAK,GAAL,KAAK,CAAG;IAErG,CAAC;IAcD;;;;OAIG;IACH,UAAU;QACT,MAAM,MAAM,GAAiB;YAC5B,OAAO,EAAE,CAAC,EAAyB,EAAE,EAAE;gBACtC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;YACxB,CAAC;YACD,SAAS,EAAE,CAAC,EAA2B,EAAE,EAAE;gBAC1C,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;gBACzB,OAAO,MAAM,CAAC;YACf,CAAC;YACD,WAAW,EAAE,GAAG,EAAE;gBACjB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,qCAAqC;gBAC5D,OAAO,MAAM,CAAC;YACf,CAAC;SACD,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACO,iBAAiB,CAAC,GAAY,EAAE,GAAO;QAChD,oHAAoH;QACpH,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YACtF,gDAAgD;YAChD,IAAI,UAAU,CAAC,aAAa,CAAC;gBAC5B,MAAM,aAAa,CAAC;YACrB,uEAAuE;YACvE,IAAI,OAAO,aAAa,KAAK,WAAW;gBACvC,MAAM,GAAG,CAAC;YACX,+DAA+D;YAC/D,OAAO,aAAa,CAAC;QACtB,CAAC;QACD,wDAAwD;QACxD,MAAM,GAAG,CAAC;IACX,CAAC;IAED;;;;;;;OAOG;IACO,KAAK,CAAC,iBAAiB,CAAI,OAAmB,EAAE,EAAoB;QAC7E,IAAI,MAAS,CAAC;QACd,IAAI,CAAC;YACJ,MAAM,GAAG,MAAM,OAAO,CAAC;QACxB,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;YACZ,4GAA4G;YAC5G,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,EAAE,CAAC,SAAyB,CAAC,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,CAAC;YACJ,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;YACZ,+EAA+E;YAC/E,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,EAAE,CAAC,MAAW,CAAC,CAAC,CAAC;QACrD,CAAC;IACF,CAAC;CACD","sourcesContent":["import {AsyncFactory, BindAs, OnErrorCallback, OnSuccessCallback, SyncFactory} from './binding';\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 Container to create chain-able configuration\n\t *\n\t * @see BindAs\n\t */\n\tmakeBindAs(): BindAs<T, M> {\n\t\tconst retVal: BindAs<T, M> = {\n\t\t\tonError: (cb: OnErrorCallback<T, M>) => {\n\t\t\t\tthis.errorHandler = cb;\n\t\t\t},\n\t\t\tonSuccess: (cb: OnSuccessCallback<T, M>) => {\n\t\t\t\tthis.successHandler = cb;\n\t\t\t\treturn retVal;\n\t\t\t},\n\t\t\tasSingleton: () => {\n\t\t\t\tthis.singleton = null; // Flag state as no longer undefined.\n\t\t\t\treturn retVal;\n\t\t\t}\n\t\t};\n\t\treturn retVal;\n\t}\n\n\t/**\n\t * Encapsulate the logic of invoking any configured error handler, and processing it's result.\n\t *\n\t * @see OnErrorCallback\n\t *\n\t * @returns The object substituted by the callback (otherwise this method throws the appropriate error).\n\t */\n\tprotected queryErrorHandler(err: unknown, obj?: T): T {\n\t\t// There was an error during construction, see if an error handler was provided, and if so, see what it wants to do.\n\t\tif (this.errorHandler) {\n\t\t\tconst handlerResult = this.errorHandler(this.injector, this.id, this.maker, err, obj);\n\t\t\t// Error handler wants us to propagate an error.\n\t\t\tif (isErrorObj(handlerResult))\n\t\t\t\tthrow handlerResult;\n\t\t\t// Error handler has no opinion, so propagate 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, propagate the error we just caught.\n\t\tthrow err;\n\t}\n\n\t/**\n\t * This is like a retry mechanism that uses the Provider's errorHandler (if any) to attempt recovery whenever the supplied Promise rejects.\n\t * This method returns a Promise that rejects if recovery was not possible.\n\t * If the supplied Promise resolves, then this method passes the result to the callback, and then resolve as whatever that callback returns.\n\t *\n\t * @param waitFor The supplied Promise.\n\t * @param cb Callback to be invoked if the supplied Promise resolves.\n\t */\n\tprotected async makePromiseForObj<R>(waitFor: Promise<R>, cb: (result: R) => T): Promise<T> {\n\t\tlet result: R;\n\t\ttry {\n\t\t\tresult = await waitFor;\n\t\t}\n\t\tcatch (err) {\n\t\t\t// waitFor rejected — ask the error handler for recovery, passing cb(undefined) as the partial object value.\n\t\t\treturn this.queryErrorHandler(err, cb(undefined as unknown as R));\n\t\t}\n\t\ttry {\n\t\t\treturn cb(result);\n\t\t}\n\t\tcatch (err) {\n\t\t\t// cb threw after a successful resolution — ask the error handler for recovery.\n\t\t\treturn this.queryErrorHandler(err, cb(result as R));\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=binding.js.map