import { defer, Observable, of } from 'rxjs'; import { catchError, map, mergeMap } from 'rxjs/operators'; import { ResolvedPage, ResolvedPath } from './PageRouter'; import { AppContext, PageModule, PluginFn, PluginParams } from './index'; export function componentLoader(resolved: ResolvedPath, ctx: AppContext): Observable { const deferred$ = defer(() => ctx.componentLoader(resolved)); const mod$: Observable = deferred$; return mod$.pipe( mergeMap((mod) => { if (mod.loadComponent) { return mod.loadComponent(resolved, ctx); } // eslint-disable-next-line @typescript-eslint/consistent-type-assertions return of({ mod, resolved }); }), catchError((e) => { console.error('error from component loader', e); return ( deferred$ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions .pipe(map((mod) => { mod, resolved })) ); }), ); } export function componentLoaderPlugin(loaderFn: (resolved: ResolvedPath) => Promise): PluginFn { return function (params: PluginParams, appCtx: AppContext): AppContext { return { ...appCtx, componentLoader: loaderFn, }; }; }