phovea/phovea_core

custom loader support

Opened this issue · 0 comments

similar to webpack, the factory description can be preprocessed,

e.g. factory: react!new!ClassName
extension point: core-extension-loader
interface

interface ILoadResult {
  Promise<((...args: any[]) => object)>|((...args: any[]) => object));
}
interface IExtensionLoader {
  (desc: IPluginDesc, factory: string, module: object, next: (factory: string) =>ILoadResult ): ILoadResult ;
}
next(factory: string)
 factory === '' => (...args: any[]) => module.default(...args)
 factory === 'new' || factory === 'new!'=> (...args: any[]) => new module.default(...args)
 factory === 'new (.+)' || factory === 'new!(.+)' => (...args: any[]) => new module[$1](...args)
 factory === '(.+)!(.*)' => (...args: any[]) => loader[$1](desc, $2, module, next)
function extensionLoader(desc: IPluginDesc, factory: string, module: object): ILoadResult {
  const next = (factory: string) => {
    factory = factory.trim();
    if (!factory) {
      console.assert(typeof module.default === 'function')
      return (...args: any[]) => module.default(...args);
    }
    if (factory === 'new' || factory === 'new!') { // predefined loader + compatibility
      console.assert(typeof module.default === 'function')
      return (...args: any[]) => new module.default(...args);
    }
    const newMatch = factory.match(/new[! ](.+)/); //predefine loader + compatibility
    if (newMatch)  {
      console.assert(typeof module[newMatch[1] === 'function')
     return (...args: any[]) => new module[newMatch[1]](...args);
    }
    const loaderMatch = factory.match(/(.+)!(.*)/);
    if (loaderMatch )  {
      const loader = get('core-extension-loader', loaderMatch[1]);
      console.assert(loader);
      return loader.load().then((p) => p.factory(desc, loaderMatch[2], next);
    }
    
      console.assert(typeof module[factory] === 'function')
     return (...args: any[]) => module[factory](...args);
}