async-injection 2.1.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ReadMe.md +1 -0
- package/lib/async-factory-provider.d.ts +4 -4
- package/lib/bindable-provider.d.ts +3 -3
- package/lib/binder.d.ts +6 -2
- package/lib/cjs/async-factory-provider.js +5 -5
- package/lib/cjs/async-factory-provider.js.map +1 -1
- package/lib/cjs/bindable-provider.js +33 -33
- package/lib/cjs/bindable-provider.js.map +1 -1
- package/lib/cjs/binder.js.map +1 -1
- package/lib/cjs/class-provider.js +36 -37
- package/lib/cjs/class-provider.js.map +1 -1
- package/lib/cjs/constant-provider.js +4 -4
- package/lib/cjs/constant-provider.js.map +1 -1
- package/lib/cjs/container.js +33 -23
- package/lib/cjs/container.js.map +1 -1
- package/lib/cjs/decorators.js +21 -25
- package/lib/cjs/decorators.js.map +1 -1
- package/lib/cjs/index.js +10 -10
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/injector.js +5 -5
- package/lib/cjs/injector.js.map +1 -1
- package/lib/cjs/provider.js +25 -11
- package/lib/cjs/provider.js.map +1 -1
- package/lib/cjs/state.js +2 -2
- package/lib/cjs/state.js.map +1 -1
- package/lib/cjs/sync-factory-provider.js +7 -7
- package/lib/cjs/sync-factory-provider.js.map +1 -1
- package/lib/cjs/utils.js +10 -13
- package/lib/cjs/utils.js.map +1 -1
- package/lib/class-provider.d.ts +4 -4
- package/lib/constant-provider.d.ts +2 -2
- package/lib/container.d.ts +15 -6
- package/lib/decorators.d.ts +1 -1
- package/lib/esm/async-factory-provider.js +1 -1
- package/lib/esm/async-factory-provider.js.map +1 -1
- package/lib/esm/bindable-provider.js +29 -29
- package/lib/esm/bindable-provider.js.map +1 -1
- package/lib/esm/binder.js.map +1 -1
- package/lib/esm/class-provider.js +17 -18
- package/lib/esm/class-provider.js.map +1 -1
- package/lib/esm/constant-provider.js.map +1 -1
- package/lib/esm/container.js +15 -5
- package/lib/esm/container.js.map +1 -1
- package/lib/esm/decorators.js +1 -4
- package/lib/esm/decorators.js.map +1 -1
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/injector.js +5 -5
- package/lib/esm/injector.js.map +1 -1
- package/lib/esm/provider.js +23 -9
- package/lib/esm/provider.js.map +1 -1
- package/lib/esm/state.js.map +1 -1
- package/lib/esm/sync-factory-provider.js +1 -1
- package/lib/esm/sync-factory-provider.js.map +1 -1
- package/lib/esm/utils.js +6 -8
- package/lib/esm/utils.js.map +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/provider.d.ts +9 -5
- package/lib/state.d.ts +3 -3
- package/lib/sync-factory-provider.d.ts +5 -5
- package/package.json +8 -19
package/lib/esm/container.js
CHANGED
|
@@ -85,7 +85,6 @@ export class Container {
|
|
|
85
85
|
}
|
|
86
86
|
this.providers.delete(id);
|
|
87
87
|
if (ascending && this.parent) {
|
|
88
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
89
88
|
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.removeBinding(id, true, releaseIfSingleton);
|
|
90
89
|
}
|
|
91
90
|
}
|
|
@@ -103,10 +102,8 @@ export class Container {
|
|
|
103
102
|
if (!Reflect.getMetadata(INJECTABLE_METADATA_KEY, constructor)) {
|
|
104
103
|
throw new Error('Class not decorated with @Injectable [' + constructor.toString() + ']');
|
|
105
104
|
}
|
|
106
|
-
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
107
105
|
const provider = new ClassBasedProvider(this, id, constructor);
|
|
108
106
|
this.providers.set(id, provider);
|
|
109
|
-
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
110
107
|
return provider.makeBindAs();
|
|
111
108
|
}
|
|
112
109
|
/**
|
|
@@ -136,7 +133,7 @@ export class Container {
|
|
|
136
133
|
// Ask each provider to resolve itself *IF* it is a singleton.
|
|
137
134
|
this.providers.forEach((value, key) => {
|
|
138
135
|
// If the provider is a singleton *and* if resolution is being handled asynchronously, the provider will return a completion promise.
|
|
139
|
-
const p = value.resolveIfSingleton(asyncOnly);
|
|
136
|
+
const p = value.resolveIfSingleton(asyncOnly !== null && asyncOnly !== void 0 ? asyncOnly : false);
|
|
140
137
|
if (p !== null && typeof p !== 'undefined')
|
|
141
138
|
pending.set(key, p);
|
|
142
139
|
});
|
|
@@ -211,6 +208,20 @@ export class Container {
|
|
|
211
208
|
value.releaseIfSingleton();
|
|
212
209
|
});
|
|
213
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* Releases a Singleton instance if it exists.
|
|
213
|
+
* 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.
|
|
214
|
+
* If not a singleton, this method returns undefined.
|
|
215
|
+
* If the singleton has been resolved, it is returned, otherwise null is returned.
|
|
216
|
+
* If the singleton is pending resolution, a Promise for the singleton (or for null) is returned.
|
|
217
|
+
* Note that if a singleton is returned, its Release method will already have been invoked.
|
|
218
|
+
*/
|
|
219
|
+
releaseSingleton(id) {
|
|
220
|
+
const provider = this.providers.get(id);
|
|
221
|
+
if (provider)
|
|
222
|
+
return provider.releaseIfSingleton();
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
214
225
|
/**
|
|
215
226
|
* Make a copy of this @see Container.
|
|
216
227
|
* This is an experimental feature!
|
|
@@ -233,7 +244,6 @@ export class Container {
|
|
|
233
244
|
this.providers.forEach((v, k) => {
|
|
234
245
|
if (v instanceof BindableProvider) {
|
|
235
246
|
v = Object.assign(Object.create(Object.getPrototypeOf(v)), v);
|
|
236
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
237
247
|
v.injector = retVal;
|
|
238
248
|
}
|
|
239
249
|
retVal.providers.set(k, v);
|
package/lib/esm/container.js.map
CHANGED
|
@@ -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.js';\nimport {BindableProvider} from './bindable-provider.js';\nimport {AsyncFactory, BindAs, Binder, SyncFactory} from './binder.js';\nimport {ClassBasedProvider} from './class-provider.js';\nimport {ConstantProvider} from './constant-provider.js';\nimport {INJECTABLE_METADATA_KEY} from './constants.js';\nimport {AbstractConstructor, ClassConstructor, InjectableId, Injector} from './injector.js';\nimport {Provider} from './provider.js';\nimport {State} from './state.js';\nimport {FactoryBasedProvider} from './sync-factory-provider.js';\nimport {isPromise} from './utils.js';\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// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\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\t/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\t\tconst provider = new ClassBasedProvider(this as any, id, constructor);\n\t\tthis.providers.set(id, provider);\n\t\t/* eslint-disable @typescript-eslint/no-unsafe-return */\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);\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 * 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// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\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":"AAAA,OAAO,EAAC,yBAAyB,EAAC,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAC,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAC,uBAAuB,EAAC,MAAM,aAAa,CAAC;AAGpD,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAC,oBAAoB,EAAC,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAC,SAAS,EAAC,MAAM,SAAS,CAAC;AAElC;;;;GAIG;AACH,MAAM,aAAa;IAClB,YAAmB,MAAW;QAAX,WAAM,GAAN,MAAM,CAAK;IAC9B,CAAC;CACD;AAED;;GAEG;AACH,MAAM,OAAO,SAAS;IAErB;;OAEG;IACH,YAA6B,MAAiB;QAAjB,WAAM,GAAN,MAAM,CAAW;QAGpC,cAAS,GAAG,IAAI,GAAG,EAA+B,CAAC;IAF7D,CAAC;IAID;;OAEG;IACI,SAAS,CAAI,EAAmB,EAAE,SAAmB;QAC3D,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QACb,IAAI,SAAS,IAAI,IAAI,CAAC,MAAM;YAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;OAEG;IACI,GAAG,CAAI,EAAmB;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,IAAI,IAAI,CAAC,MAAM;gBACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAI,EAAE,CAAC,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,EAAE,CAAC;QACxC,IAAI,KAAK,CAAC,OAAO;YAChB,MAAM,IAAI,KAAK,CAAC,kEAAkE,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QACrG,IAAI,KAAK,CAAC,QAAQ;YACjB,MAAM,KAAK,CAAC,QAAQ,CAAC;QACtB,OAAO,KAAK,CAAC,SAAc,CAAC;IAC7B,CAAC;IAED;;OAEG;IACI,OAAO,CAAI,EAAmB;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QACpC,IAAI,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC,OAAO,CAAC;QACtB,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACpB,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC;QAED,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAED,qCAAqC;IACrC;;;;;;;OAOG;IACI,aAAa,CAAI,EAAmB,EAAE,SAAmB,EAAE,kBAA4B;;QAC7F,IAAI,kBAAkB,EAAE,CAAC;YACxB,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACjC,IAAI,CAAC;gBACJ,CAAC,CAAC,kBAAkB,EAAE,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAE1B,IAAI,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC9B,MAAC,IAAI,CAAC,MAAc,0CAAE,aAAa,CAAC,EAAE,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAC;QACnE,CAAC;IACF,CAAC;IAED;;OAEG;IACI,YAAY,CAAI,EAAmB,EAAE,KAAQ;QACnD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC;IACd,CAAC;IAOM,SAAS,CAAI,EAAkE,EAAE,WAAgC;QACvH,IAAI,OAAO,WAAW,KAAK,WAAW,EAAE,CAAC;YACxC,WAAW,GAAG,EAA+B,CAAC;QAC/C,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,uBAAuB,EAAE,WAAW,CAAC,EAAE,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC,wCAAwC,GAAG,WAAW,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC,CAAC;QAC1F,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,kBAAkB,CAAC,IAAW,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;QACtE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACjC,OAAO,QAAQ,CAAC,UAAU,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACI,WAAW,CAAI,EAAmB,EAAE,OAAuB;QACjE,MAAM,QAAQ,GAAG,IAAI,oBAAoB,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACjC,OAAO,QAAQ,CAAC,UAAU,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACI,gBAAgB,CAAI,EAAmB,EAAE,OAAwB;QACvE,MAAM,QAAQ,GAAG,IAAI,yBAAyB,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QAClE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACjC,OAAO,QAAQ,CAAC,UAAU,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACI,iBAAiB,CAAC,SAAmB,EAAE,eAAyB;;QACtE,MAAM,oBAAoB,GAAG,GAAG,EAAE;YACjC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC5C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoC,CAAC;gBAC5D,8DAA8D;gBAC9D,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAe,EAAE,GAAsB,EAAE,EAAE;oBAClE,qIAAqI;oBACrI,MAAM,CAAC,GAAG,KAAK,CAAC,kBAAkB,CAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,KAAK,CAAC,CAAC;oBACvD,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,WAAW;wBACzC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBACtB,CAAC,CAAC,CAAC;gBACH,oJAAoJ;gBACpJ,oPAAoP;gBACpP,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;gBACxC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;gBACxC,kHAAkH;gBAClH,OAAO,CAAC,GAAG,CAAC,EAAE;qBACZ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;qBAC7C,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;oBACjB,MAAM,OAAO,GAAG,IAAI,GAAG,EAA4B,CAAC;oBACpD,0LAA0L;oBAC1L,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;wBAC/B,IAAI,MAAM,YAAY,aAAa,EAAE,CAAC;4BACrC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;wBACvC,CAAC;oBACF,CAAC,CAAC,CAAC;oBACH,0DAA0D;oBAC1D,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC;wBACnB,MAAM,CAAC,OAAO,CAAC,CAAC;;wBAEhB,OAAO,EAAE,CAAC,CAAE,YAAY;gBAC1B,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC;QACF,IAAI,eAAe,IAAI,OAAO,CAAA,MAAC,IAAI,CAAC,MAAiB,0CAAE,iBAAiB,CAAA,KAAK,UAAU,EAAE,CAAC;YACzF,MAAM,EAAE,GAAW,IAAI,CAAC,MAAgB,CAAC;YACzC,OAAO,EAAE,CAAC,iBAAiB,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;gBACjE,OAAO,oBAAoB,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YAChD,CAAC,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,oBAAoB,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC;IAED;;;OAGG;IACO,YAAY,CAAI,EAAmB;QAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,IAAI,CAAC,MAAM,YAAY,SAAS,EAAE,CAAC;oBACtC,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAI,EAAE,CAAC,CAAC;gBACxC,CAAC;gBACD,+HAA+H;gBAC/H,2BAA2B;gBAC3B,IAAI,CAAC;oBACJ,OAAO,KAAK,CAAC,SAAS,CAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAI,EAAE,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;gBAC7E,CAAC;gBACD,OAAO,GAAG,EAAE,CAAC;oBACZ,OAAO,KAAK,CAAC,SAAS,CAAI,IAAI,EAAE,GAAG,CAAC,CAAC;gBACtC,CAAC;YACF,CAAC;YACD,OAAO,KAAK,CAAC,SAAS,CAAI,IAAI,EAAE,IAAI,KAAK,CAAC,oBAAoB,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAClF,CAAC;QACD,OAAO,QAAQ,CAAC,cAAc,EAAc,CAAC;IAC9C,CAAC;IAED,qCAAqC;IACrC;;;;;;;;;OASG;IACI,iBAAiB;QACvB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAe,EAAE,EAAE;YAC1C,KAAK,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACI,gBAAgB,CAAI,EAAmB;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,QAAQ;YACX,OAAO,QAAQ,CAAC,kBAAkB,EAAE,CAAC;QACtC,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,KAAmC;QACxC,IAAI,CAAC,KAAK;YACT,KAAK,GAAG,SAAS,CAAC;QACnB,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC/B,IAAI,CAAC,YAAY,gBAAgB,EAAE,CAAC;gBACnC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7D,CAAS,CAAC,QAAQ,GAAG,MAAM,CAAC;YAC9B,CAAC;YACD,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IACf,CAAC;CACD","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"]}
|
package/lib/esm/decorators.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/ban-types */
|
|
2
1
|
/**
|
|
3
2
|
* These decorators all apply the information they collect (whether class, method, or parameter data) as tagged metadata on the class's constructor
|
|
4
3
|
*/
|
|
@@ -12,13 +11,11 @@ function targetHint(target) {
|
|
|
12
11
|
hint = target.constructor.name;
|
|
13
12
|
}
|
|
14
13
|
}
|
|
15
|
-
return hint;
|
|
14
|
+
return hint !== null && hint !== void 0 ? hint : '';
|
|
16
15
|
}
|
|
17
16
|
// Validate that 'target' is a class constructor function.
|
|
18
17
|
function isClassConstructor(target) {
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
20
18
|
if (typeof target === 'function' && target.hasOwnProperty('prototype')) {
|
|
21
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
22
19
|
return target.prototype.constructor === target;
|
|
23
20
|
}
|
|
24
21
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\n/**\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.js';\nimport {InjectableId} from './injector.js';\n\n// Help user locate misapplied decorators.\nfunction targetHint(target: Function) {\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\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n\tif (typeof target === 'function' && target.hasOwnProperty('prototype')) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\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: Function, parameterName: string | symbol, parameterIndex: number): void {\n\t\tif (id === undefined) {\n\t\t\tthrow new Error('Undefined id passed to @Inject [' + targetHint(target) + ']');\n\t\t}\n\t\tconst paramKey = validateSingleConstructorParam('Inject', target, 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 { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types\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: Function, parameterName: string | symbol, parameterIndex: number): void {\n\t\tconst paramKey = validateSingleConstructorParam('Optional', target, 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) { // eslint-disable-line @typescript-eslint/no-unused-vars\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) { // eslint-disable-line @typescript-eslint/no-unused-vars\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":"AAAA;;GAEG;AACH,OAAO,EAAC,mBAAmB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,gCAAgC,EAAE,+BAA+B,EAAE,cAAc,EAAE,oBAAoB,EAAC,MAAM,aAAa,CAAC;AAGzM,0CAA0C;AAC1C,SAAS,UAAU,CAAC,MAAgB;IACnC,IAAI,IAAwB,CAAC;IAC7B,IAAI,MAAM,EAAE,CAAC;QACZ,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACnB,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACnC,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC;QAChC,CAAC;IACF,CAAC;IACD,OAAO,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC;AACnB,CAAC;AAED,0DAA0D;AAC1D,SAAS,kBAAkB,CAAC,MAAW;IACtC,IAAI,OAAO,MAAM,KAAK,UAAU,IAAI,MAAM,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC;QACxE,OAAO,MAAM,CAAC,SAAS,CAAC,WAAW,KAAK,MAAM,CAAC;IAChD,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,4DAA4D;AAC5D,SAAS,eAAe,CAAC,GAAW;IACnC,OAAO,SAAS,GAAG,EAAE,CAAC;AACvB,CAAC;AAED,2EAA2E;AAC3E,SAAS,wBAAwB,CAAC,SAAiB,EAAE,MAAgB,EAAE,GAAW;IACjF,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,SAAS,GAAG,sBAAsB,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,gDAAgD;AAChD,SAAS,8BAA8B,CAAC,SAAiB,EAAE,MAAgB,EAAE,GAAW;IACvF,MAAM,OAAO,GAAG,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IACjE,IAAI,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,SAAS,GAAG,2BAA2B,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU;IACzB;;;OAGG;IACH,OAAO,UAAU,MAAgB;QAChC,IAAI,OAAO,CAAC,cAAc,CAAC,uBAAuB,EAAE,MAAM,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,sCAAsC,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;QACpF,CAAC;QACD,OAAO,CAAC,cAAc,CAAC,uBAAuB,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,EAAqB;IAC3C;;;;;OAKG;IACH,OAAO,UAAU,MAAc,EAAE,aAA0C,EAAE,cAAsB;QAClG,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,UAAU,CAAC,MAAkB,CAAC,GAAG,GAAG,CAAC,CAAC;QAC5F,CAAC;QACD,MAAM,QAAQ,GAAG,8BAA8B,CAAC,QAAQ,EAAE,MAAkB,EAAE,cAAc,CAAC,CAAC;QAC9F,OAAO,CAAC,cAAc,CAAC,mBAAmB,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnE,CAAC,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAgB,EAAE,cAAsB;IACxE,OAAO,OAAO,CAAC,WAAW,CAAC,mBAAmB,EAAE,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,CAAsB,CAAC;AAC/G,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAS;IACjC;;;;;OAKG;IACH,OAAO,UAAU,MAAc,EAAE,aAA0C,EAAE,cAAsB;QAClG,MAAM,QAAQ,GAAG,8BAA8B,CAAC,UAAU,EAAE,MAAkB,EAAE,cAAc,CAAC,CAAC;QAChG,OAAO,CAAC,cAAc,CAAC,qBAAqB,EAAE,EAAC,KAAK,EAAE,GAAG,EAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/E,CAAC,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAgB,EAAE,cAAsB;IAC7E,OAAO,OAAO,CAAC,WAAW,CAAC,qBAAqB,EAAE,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,CAAmB,CAAC,CAAC,8DAA8D;AAC7K,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC5B;;;;;OAKG;IACH,oCAAoC;IACpC,OAAO,UAAU,MAAc,EAAE,UAA2B,EAAE,UAA8B;QAC3F,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YAC5E,MAAM,IAAI,KAAK,CAAC,iDAAiD,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG,UAAU,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC,CAAC;QAC5H,CAAC;QACD,IAAI,OAAO,CAAC,cAAc,CAAC,+BAA+B,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,cAAc,CAAC,gCAAgC,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;YACjK,MAAM,IAAI,KAAK,CAAC,yCAAyC,GAAG,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC;QACnG,CAAC;QACD,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACnE,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;YAC9B,OAAO,CAAC,cAAc,CAAC,gCAAgC,EAAE,UAAU,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QAC1F,CAAC;aACI,CAAC;YACL,OAAO,CAAC,cAAc,CAAC,+BAA+B,EAAE,UAAU,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QACzF,CAAC;IACF,CAAC,CAAC;AACH,CAAC;AAED,qCAAqC;AACrC;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,OAAO;IACtB;;;;;OAKG;IACH,oCAAoC;IACpC,OAAO,UAAU,MAAc,EAAE,UAA2B,EAAE,UAA8B;QAC3F,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YAC5E,MAAM,IAAI,KAAK,CAAC,2CAA2C,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG,UAAU,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC,CAAC;QACtH,CAAC;QACD,IAAI,OAAO,CAAC,cAAc,CAAC,oBAAoB,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC;QAC7F,CAAC;QACD,OAAO,CAAC,cAAc,CAAC,oBAAoB,EAAE,UAAU,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IAC9E,CAAC,CAAC;AACH,CAAC","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"]}
|
package/lib/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,OAAO,EAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAC,MAAM,cAAc,CAAC;AAClF,OAAO,EAAiC,cAAc,EAAW,MAAM,YAAY,CAAC","sourcesContent":["export {Container} from './container';\nexport {Inject, Injectable, Optional, PostConstruct, Release} from './decorators';\nexport {ClassConstructor, InjectableId, InjectionToken, Injector} from './injector';\n"]}
|
package/lib/esm/injector.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Allow for implicit typing of constants and interfaces.
|
|
3
3
|
* Inspired by Angular and some colleges at work.
|
|
4
4
|
*/
|
|
5
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
6
5
|
export class InjectionToken {
|
|
7
6
|
constructor(id) {
|
|
8
7
|
this.id = id;
|
|
@@ -11,10 +10,11 @@ export class InjectionToken {
|
|
|
11
10
|
return this.toString();
|
|
12
11
|
}
|
|
13
12
|
toString() {
|
|
14
|
-
//
|
|
15
|
-
if (typeof this.id === 'symbol'
|
|
16
|
-
|
|
17
|
-
return this.id.
|
|
13
|
+
// noinspection SuspiciousTypeOfGuard
|
|
14
|
+
if (typeof this.id === 'symbol') {
|
|
15
|
+
const desc = this.id.description;
|
|
16
|
+
return desc !== undefined ? desc : this.id.toString();
|
|
17
|
+
}
|
|
18
18
|
return this.id.toString();
|
|
19
19
|
}
|
|
20
20
|
}
|
package/lib/esm/injector.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injector.js","sourceRoot":"","sources":["../../src/injector.ts"],"names":[],"mappings":"AASA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"injector.js","sourceRoot":"","sources":["../../src/injector.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,MAAM,OAAO,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","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"]}
|
package/lib/esm/provider.js
CHANGED
|
@@ -10,10 +10,10 @@ export class Provider {
|
|
|
10
10
|
* Base method to initialize the state of this Provider *if* (and only if) it has been configured as a Singleton.
|
|
11
11
|
* If this Provider has not been configured as a singleton, this method is essentially a noop that returns undefined.
|
|
12
12
|
*
|
|
13
|
-
* @param
|
|
13
|
+
* @param _asyncOnly This default implementation ignores this parameter.
|
|
14
14
|
* @returns A completion Promise if initialization requires asynchronicity, otherwise the return value is undefined.
|
|
15
15
|
*/
|
|
16
|
-
resolveIfSingleton(
|
|
16
|
+
resolveIfSingleton(_asyncOnly) {
|
|
17
17
|
if (this.singleton === null) {
|
|
18
18
|
const s = this.provideAsState();
|
|
19
19
|
if (s.pending)
|
|
@@ -29,24 +29,38 @@ export class Provider {
|
|
|
29
29
|
* Also note that invoking this method does not release or invalidate the Provider;
|
|
30
30
|
* Rather, it resets a Singleton Provider to a fresh (unresolved/unqueried) state (aka sets this.singleton to null).
|
|
31
31
|
* It is assumed that the Singleton itself will no longer be used after this method returns.
|
|
32
|
+
* If not a singleton, this method returns undefined.
|
|
33
|
+
* If the singleton has been resolved, it is returned, otherwise null is returned.
|
|
34
|
+
* If the singleton is pending resolution, a Promise for the singleton or for null is returned.
|
|
35
|
+
* Note that if a singleton is returned, its Release method will already have been invoked.
|
|
32
36
|
*/
|
|
33
37
|
releaseIfSingleton() {
|
|
34
38
|
if (this.singleton) {
|
|
35
39
|
const s = this.provideAsState();
|
|
36
40
|
if (s.pending) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
return (async () => {
|
|
42
|
+
try {
|
|
43
|
+
const v = await s.promise;
|
|
44
|
+
this.singleton = null;
|
|
45
|
+
InvokeReleaseMethod(v);
|
|
46
|
+
return v;
|
|
47
|
+
}
|
|
48
|
+
catch (_a) {
|
|
49
|
+
this.singleton = null;
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
})();
|
|
43
53
|
}
|
|
44
54
|
else {
|
|
45
55
|
this.singleton = null;
|
|
46
|
-
if ((!s.rejected) && s.fulfilled)
|
|
56
|
+
if ((!s.rejected) && s.fulfilled) {
|
|
47
57
|
InvokeReleaseMethod(s.fulfilled);
|
|
58
|
+
return s.fulfilled;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
48
61
|
}
|
|
49
62
|
}
|
|
63
|
+
return undefined;
|
|
50
64
|
}
|
|
51
65
|
}
|
|
52
66
|
//# sourceMappingURL=provider.js.map
|
package/lib/esm/provider.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,mBAAmB,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,mBAAmB,EAAC,MAAM,SAAS,CAAC;AAG5C;;;GAGG;AACH,MAAM,OAAgB,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,mBAAmB,CAAC,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,mBAAmB,CAAC,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","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"]}
|
package/lib/esm/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,SAAS,CAAC;AAElC;;GAEG;AACH,MAAM,OAAO,KAAK;IACjB,MAAM,CAAC,SAAS,CAAe,OAA+B,EAAE,QAAkB,EAAE,SAAkB;QACrG,MAAM,MAAM,GAAG,IAAI,KAAK,EAAU,CAAC;QACnC,IAAI,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;YACvB,MAAM,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAC7B,CAAC,CAAC,EAAE,EAAE;gBACL,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC;gBACtB,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;gBACxB,OAAO,CAAC,CAAC;YACV,CAAC,EACD,CAAC,CAAM,EAAE,EAAE;gBACV,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC;gBACrB,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;gBACxB,MAAM,CAAC,CAAC;YACT,CAAC,CACD,CAAC;QACH,CAAC;aACI,CAAC;YACL,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;YACxB,IAAI,QAAQ,EAAE,CAAC;gBACd,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC;YAC7B,CAAC;iBACI,CAAC;gBACL,MAAM,CAAC,UAAU,GAAG,SAAmB,CAAC;YACzC,CAAC;YACD,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAED;IACA,CAAC;IAID,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;IAID,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;IAID,IAAI,SAAS;QACZ,OAAO,IAAI,CAAC,UAAU,CAAC;IACxB,CAAC;IAID,IAAI,QAAQ;QACX,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;CACD","sourcesContent":["import {isPromise} from './utils';\n\n/**\n * Internal class that allows us to track the state of a promise (chain).\n */\nexport class State<T = any> {\n\tstatic MakeState<TState = any>(promise: Promise<TState> | null, rejected?: unknown, fulfilled?: TState): State<TState> {\n\t\tconst retVal = new State<TState>();\n\t\tif (isPromise(promise)) {\n\t\t\tretVal._pending = true;\n\t\t\tretVal._promise = promise.then(\n\t\t\t\t(v) => {\n\t\t\t\t\tretVal._fulfilled = v;\n\t\t\t\t\tretVal._pending = false;\n\t\t\t\t\treturn v;\n\t\t\t\t},\n\t\t\t\t(e: any) => {\n\t\t\t\t\tretVal._rejected = e;\n\t\t\t\t\tretVal._pending = false;\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t\telse {\n\t\t\tretVal._pending = false;\n\t\t\tif (rejected) {\n\t\t\t\tretVal._rejected = rejected;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tretVal._fulfilled = fulfilled as TState;\n\t\t\t}\n\t\t\tretVal._promise = null;\n\t\t}\n\t\treturn retVal;\n\t}\n\n\tprotected constructor() {\n\t}\n\n\tprotected _promise!: Promise<T> | null;\n\n\tget promise(): Promise<T> | null {\n\t\treturn this._promise;\n\t}\n\n\tprotected _pending!: boolean;\n\n\tget pending(): boolean {\n\t\treturn this._pending;\n\t}\n\n\tprotected _fulfilled!: T;\n\n\tget fulfilled(): T {\n\t\treturn this._fulfilled;\n\t}\n\n\tprotected _rejected: unknown;\n\n\tget rejected(): unknown {\n\t\treturn this._rejected;\n\t}\n}\n"]}
|
|
@@ -21,7 +21,7 @@ export class FactoryBasedProvider extends BindableProvider {
|
|
|
21
21
|
catch (err) {
|
|
22
22
|
// There was an error, give the errorHandler (if any) a crack at recovery.
|
|
23
23
|
try {
|
|
24
|
-
// queryErrorHandler will throw if it could not
|
|
24
|
+
// queryErrorHandler will throw if it could not get a substitute object.
|
|
25
25
|
retVal = State.MakeState(null, undefined, this.queryErrorHandler(err));
|
|
26
26
|
}
|
|
27
27
|
catch (e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-factory-provider.js","sourceRoot":"","sources":["../../src/sync-factory-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"sync-factory-provider.js","sourceRoot":"","sources":["../../src/sync-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,oBAAwB,SAAQ,gBAAmC;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,KAAK,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,KAAK,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,KAAK,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","sourcesContent":["import {BindableProvider} from './bindable-provider';\nimport {SyncFactory} from './binder';\nimport {InjectableId, Injector} from './injector';\nimport {State} from './state';\n\n/**\n * @inheritDoc\n * This specialization simply invokes it's configured Factory and provides the result.\n */\nexport class FactoryBasedProvider<T> extends BindableProvider<T, SyncFactory<T>> {\n\tconstructor(injector: Injector, id: InjectableId<T>, maker: SyncFactory<T>) {\n\t\tsuper(injector, id, maker);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization invokes it's configured Factory and provides the result (or invokes the error handler if necessary).\n\t */\n\tprovideAsState(): State<T> {\n\t\tlet retVal = this.singleton;\n\t\tif (!retVal) {\n\t\t\ttry {\n\t\t\t\tretVal = State.MakeState<T>(null, undefined, this.maker(this.injector));\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\t// There was an error, give the errorHandler (if any) a crack at recovery.\n\t\t\t\ttry {\n\t\t\t\t\t// queryErrorHandler will throw if it could not get a substitute object.\n\t\t\t\t\tretVal = State.MakeState<T>(null, undefined, this.queryErrorHandler(err));\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\t// could not recover, propagate the error.\n\t\t\t\t\tretVal = State.MakeState<T>(null, e, undefined);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.singleton === null)\n\t\t\tthis.singleton = retVal;\n\t\treturn retVal;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * This specialization returns undefined anytime 'asyncOnly' is true (since this Provider is by definition synchronous).\n\t */\n\tresolveIfSingleton(asyncOnly: boolean): Promise<T> | undefined {\n\t\tif (asyncOnly)\n\t\t\treturn undefined;\n\t\treturn super.resolveIfSingleton(false);\n\t}\n}\n"]}
|
package/lib/esm/utils.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/explicit-module-boundary-types */
|
|
2
1
|
import { RELEASE_METADATA_KEY } from './constants.js';
|
|
3
2
|
/**
|
|
4
3
|
* Returns true if the specified object looks like a JavaScript Error object.
|
|
@@ -8,7 +7,7 @@ export function isErrorObj(err) {
|
|
|
8
7
|
return false;
|
|
9
8
|
if (err instanceof Error)
|
|
10
9
|
return true;
|
|
11
|
-
return err && typeof err.message === 'string' && typeof err.stack === 'string';
|
|
10
|
+
return !!(err && typeof err.message === 'string' && typeof err.stack === 'string');
|
|
12
11
|
}
|
|
13
12
|
/**
|
|
14
13
|
* Returns true if the specified value is "thenable" (aka a Promise).
|
|
@@ -18,7 +17,7 @@ export function isPromise(value) {
|
|
|
18
17
|
return false;
|
|
19
18
|
if (value instanceof Promise)
|
|
20
19
|
return true;
|
|
21
|
-
return value && typeof value.then === 'function';
|
|
20
|
+
return !!(value && typeof value.then === 'function');
|
|
22
21
|
}
|
|
23
22
|
/**
|
|
24
23
|
* Simple helper function to find the @Release decorated method of an object (if any), and invoke it.
|
|
@@ -27,16 +26,15 @@ export function isPromise(value) {
|
|
|
27
26
|
*/
|
|
28
27
|
export function InvokeReleaseMethod(obj) {
|
|
29
28
|
var _a, _b;
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
if (releaseMethod &&
|
|
33
|
-
const releaseFn = (_b = (_a =
|
|
29
|
+
const o = obj;
|
|
30
|
+
const releaseMethod = Reflect.getMetadata(RELEASE_METADATA_KEY, o.constructor);
|
|
31
|
+
if (releaseMethod && o.constructor.prototype[releaseMethod] && typeof o.constructor.prototype[releaseMethod] === 'function') {
|
|
32
|
+
const releaseFn = (_b = (_a = o[releaseMethod]).bind) === null || _b === void 0 ? void 0 : _b.call(_a, o);
|
|
34
33
|
if (releaseFn) {
|
|
35
34
|
releaseFn();
|
|
36
35
|
return true;
|
|
37
36
|
}
|
|
38
37
|
}
|
|
39
|
-
/* eslint-enable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
|
40
38
|
return false;
|
|
41
39
|
}
|
|
42
40
|
//# sourceMappingURL=utils.js.map
|
package/lib/esm/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,aAAa,CAAC;AAEjD;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,GAAQ;IAClC,IAAI,CAAC,GAAG;QACP,OAAO,KAAK,CAAC;IAEd,IAAI,GAAG,YAAY,KAAK;QACvB,OAAO,IAAI,CAAC;IAEb,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC;AACpF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAI,KAAU;IACtC,IAAI,CAAC,KAAK;QACT,OAAO,KAAK,CAAC;IAEd,IAAI,KAAK,YAAY,OAAO;QAC3B,OAAO,IAAI,CAAC;IAEb,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAc,GAAM;;IACtD,MAAM,CAAC,GAAG,GAAU,CAAC;IACrB,MAAM,aAAa,GAAW,OAAO,CAAC,WAAW,CAAC,oBAAoB,EAAE,CAAC,CAAC,WAAW,CAAW,CAAC;IACjG,IAAI,aAAa,IAAI,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,UAAU,EAAE,CAAC;QAC7H,MAAM,SAAS,GAAG,MAAA,MAAA,CAAC,CAAC,aAAa,CAAC,EAAC,IAAI,mDAAG,CAAC,CAAC,CAAC;QAC7C,IAAI,SAAS,EAAE,CAAC;YACf,SAAS,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC","sourcesContent":["import {RELEASE_METADATA_KEY} from './constants';\n\n/**\n * Returns true if the specified object looks like a JavaScript Error object.\n */\nexport function isErrorObj(err: any): err is Error {\n\tif (!err)\n\t\treturn false;\n\n\tif (err instanceof Error)\n\t\treturn true;\n\n\treturn !!(err && typeof err.message === 'string' && typeof err.stack === 'string');\n}\n\n/**\n * Returns true if the specified value is \"thenable\" (aka a Promise).\n */\nexport function isPromise<T>(value: any): value is Promise<T> {\n\tif (!value)\n\t\treturn false;\n\n\tif (value instanceof Promise)\n\t\treturn true;\n\n\treturn !!(value && typeof value.then === 'function');\n}\n\n/**\n * Simple helper function to find the @Release decorated method of an object (if any), and invoke it.\n * This is primarily an internal method as you probably know the exact method, and should invoke it yourself.\n * async-injection uses this helper to allow Singletons to clean up any non-garbage-collectable resources they may have allocated.\n */\nexport function InvokeReleaseMethod<T = unknown>(obj: T): boolean {\n\tconst o = obj as any;\n\tconst releaseMethod: string = Reflect.getMetadata(RELEASE_METADATA_KEY, o.constructor) as string;\n\tif (releaseMethod && o.constructor.prototype[releaseMethod] && typeof o.constructor.prototype[releaseMethod] === 'function') {\n\t\tconst releaseFn = o[releaseMethod].bind?.(o);\n\t\tif (releaseFn) {\n\t\t\treleaseFn();\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n"]}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { Container } from './container
|
|
2
|
-
export { Inject, Injectable, Optional, PostConstruct, Release } from './decorators
|
|
3
|
-
export { ClassConstructor, InjectableId, InjectionToken, Injector } from './injector
|
|
1
|
+
export { Container } from './container';
|
|
2
|
+
export { Inject, Injectable, Optional, PostConstruct, Release } from './decorators';
|
|
3
|
+
export { ClassConstructor, InjectableId, InjectionToken, Injector } from './injector';
|
package/lib/provider.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { State } from './state
|
|
1
|
+
import { State } from './state';
|
|
2
2
|
/**
|
|
3
3
|
* Internally all InjectableIds are mapped to an abstract Provider<T>.
|
|
4
4
|
* A Provider may choose to return a singleton or a new value each time it is queried.
|
|
@@ -10,7 +10,7 @@ export declare abstract class Provider<T = any> {
|
|
|
10
10
|
* 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.
|
|
11
11
|
* Default value is undefined (e.g. not a Singleton).
|
|
12
12
|
*/
|
|
13
|
-
protected singleton?: State<T
|
|
13
|
+
protected singleton?: State<T> | null;
|
|
14
14
|
/**
|
|
15
15
|
* This is the workhorse method of the Provider, and is invoked directly or indirectly by both Injector.get and Injector.resolve.
|
|
16
16
|
* This method returns the current State<T> if it is already known (which it might be for Singleton scenarios).
|
|
@@ -22,16 +22,20 @@ export declare abstract class Provider<T = any> {
|
|
|
22
22
|
* Base method to initialize the state of this Provider *if* (and only if) it has been configured as a Singleton.
|
|
23
23
|
* If this Provider has not been configured as a singleton, this method is essentially a noop that returns undefined.
|
|
24
24
|
*
|
|
25
|
-
* @param
|
|
25
|
+
* @param _asyncOnly This default implementation ignores this parameter.
|
|
26
26
|
* @returns A completion Promise if initialization requires asynchronicity, otherwise the return value is undefined.
|
|
27
27
|
*/
|
|
28
|
-
resolveIfSingleton(
|
|
28
|
+
resolveIfSingleton(_asyncOnly: boolean): Promise<T> | undefined;
|
|
29
29
|
/**
|
|
30
30
|
* 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).
|
|
31
31
|
* 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.
|
|
32
32
|
* Also note that invoking this method does not release or invalidate the Provider;
|
|
33
33
|
* Rather, it resets a Singleton Provider to a fresh (unresolved/unqueried) state (aka sets this.singleton to null).
|
|
34
34
|
* It is assumed that the Singleton itself will no longer be used after this method returns.
|
|
35
|
+
* If not a singleton, this method returns undefined.
|
|
36
|
+
* If the singleton has been resolved, it is returned, otherwise null is returned.
|
|
37
|
+
* If the singleton is pending resolution, a Promise for the singleton or for null is returned.
|
|
38
|
+
* Note that if a singleton is returned, its Release method will already have been invoked.
|
|
35
39
|
*/
|
|
36
|
-
releaseIfSingleton():
|
|
40
|
+
releaseIfSingleton(): T | undefined | null | Promise<T | null>;
|
|
37
41
|
}
|
package/lib/state.d.ts
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* Internal class that allows us to track the state of a promise (chain).
|
|
3
3
|
*/
|
|
4
4
|
export declare class State<T = any> {
|
|
5
|
-
static MakeState<TState = any>(promise: Promise<TState
|
|
5
|
+
static MakeState<TState = any>(promise: Promise<TState> | null, rejected?: unknown, fulfilled?: TState): State<TState>;
|
|
6
6
|
protected constructor();
|
|
7
|
-
protected _promise: Promise<T
|
|
8
|
-
get promise(): Promise<T
|
|
7
|
+
protected _promise: Promise<T> | null;
|
|
8
|
+
get promise(): Promise<T> | null;
|
|
9
9
|
protected _pending: boolean;
|
|
10
10
|
get pending(): boolean;
|
|
11
11
|
protected _fulfilled: T;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { BindableProvider } from './bindable-provider
|
|
2
|
-
import { SyncFactory } from './binder
|
|
3
|
-
import { InjectableId, Injector } from './injector
|
|
4
|
-
import { State } from './state
|
|
1
|
+
import { BindableProvider } from './bindable-provider';
|
|
2
|
+
import { SyncFactory } from './binder';
|
|
3
|
+
import { InjectableId, Injector } from './injector';
|
|
4
|
+
import { State } from './state';
|
|
5
5
|
/**
|
|
6
6
|
* @inheritDoc
|
|
7
7
|
* This specialization simply invokes it's configured Factory and provides the result.
|
|
@@ -17,5 +17,5 @@ export declare class FactoryBasedProvider<T> extends BindableProvider<T, SyncFac
|
|
|
17
17
|
* @inheritDoc
|
|
18
18
|
* This specialization returns undefined anytime 'asyncOnly' is true (since this Provider is by definition synchronous).
|
|
19
19
|
*/
|
|
20
|
-
resolveIfSingleton(asyncOnly: boolean): Promise<T
|
|
20
|
+
resolveIfSingleton(asyncOnly: boolean): Promise<T> | undefined;
|
|
21
21
|
}
|