2020-03-20 20:28:31 +00:00
|
|
|
import { EventEmitter } from 'events';
|
2019-04-30 00:46:08 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a lazy instance of modules that can't be required before the
|
|
|
|
* app 'ready' event by returning a proxy object to mitigate side effects
|
|
|
|
* on 'require'
|
|
|
|
*
|
|
|
|
* @param {Function} creator - Function that creates a new module instance
|
|
|
|
* @param {Object} holder - the object holding the module prototype
|
|
|
|
* @param {Boolean} isEventEmitter - whether or not the module is an EventEmitter
|
|
|
|
* @returns {Object} - a proxy object for the
|
|
|
|
*/
|
|
|
|
|
|
|
|
export function createLazyInstance (
|
|
|
|
creator: Function,
|
|
|
|
holder: Object,
|
|
|
|
isEventEmitter: Boolean
|
|
|
|
) {
|
2020-03-20 20:28:31 +00:00
|
|
|
let lazyModule: Object;
|
|
|
|
const module: any = {};
|
2020-03-17 20:17:55 +00:00
|
|
|
for (const method in (holder as any).prototype) { // eslint-disable-line guard-for-in
|
2019-04-30 00:46:08 +00:00
|
|
|
module[method] = (...args: any) => {
|
|
|
|
// create new instance of module at runtime if none exists
|
|
|
|
if (!lazyModule) {
|
2020-03-20 20:28:31 +00:00
|
|
|
lazyModule = creator();
|
|
|
|
if (isEventEmitter) EventEmitter.call(lazyModule as any);
|
2019-04-30 00:46:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// check for properties on the prototype chain that aren't functions
|
|
|
|
if (typeof (lazyModule as any)[method] !== 'function') {
|
2020-03-20 20:28:31 +00:00
|
|
|
return (lazyModule as any)[method];
|
2019-04-30 00:46:08 +00:00
|
|
|
}
|
|
|
|
|
2020-03-20 20:28:31 +00:00
|
|
|
return (lazyModule as any)[method](...args);
|
|
|
|
};
|
2019-04-30 00:46:08 +00:00
|
|
|
}
|
2020-03-20 20:28:31 +00:00
|
|
|
return module;
|
2019-04-30 00:46:08 +00:00
|
|
|
}
|