2022-08-18 16:23:16 +02:00
|
|
|
export type CachedServices = Record<string, any>;
|
|
|
|
|
|
|
|
export type FactoryOptions = {
|
|
|
|
alwaysInitializeNewService?: boolean;
|
|
|
|
doNotStoreInitializedService?: boolean;
|
|
|
|
[optionsKey: string]: unknown;
|
|
|
|
};
|
|
|
|
|
2022-08-29 20:46:42 +02:00
|
|
|
export async function factory<
|
2022-08-18 16:23:16 +02:00
|
|
|
TCache extends CachedServices,
|
|
|
|
TName extends keyof TCache,
|
|
|
|
TOpts extends FactoryOptions
|
2022-08-29 20:46:42 +02:00
|
|
|
>(
|
|
|
|
cachedServices: TCache,
|
|
|
|
name: TName,
|
|
|
|
opts: TOpts,
|
|
|
|
factory: () => TCache[TName] | Promise<TCache[TName]>
|
|
|
|
): Promise<TCache[TName]> {
|
2022-08-18 16:23:16 +02:00
|
|
|
let instance = cachedServices[name];
|
|
|
|
if (opts.alwaysInitializeNewService || !instance) {
|
2022-08-29 20:46:42 +02:00
|
|
|
const instanceOrPromise = factory();
|
|
|
|
instance = instanceOrPromise instanceof Promise ? await instanceOrPromise : instanceOrPromise;
|
2022-08-18 16:23:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!opts.doNotStoreInitializedService) {
|
|
|
|
cachedServices[name] = instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
return instance as TCache[TName];
|
|
|
|
}
|