import { Location } from 'history'; import { BehaviorSubject, EMPTY, Observable, of } from 'rxjs'; import ApolloClient from 'apollo-client'; import { catchError, map, mergeMap, switchMap, toArray } from 'rxjs/operators'; import { fileSystemResolver } from './fileSystemPageResolver'; import { componentLoader } from './componentLoader'; import { NOT_FOUND_NAME } from './vars'; import { applyMiddleware, MwOutput } from './middleware'; import { ResolvedPath } from './PageRouter'; import { AppContext, PageModule, PageResponse } from './index'; export interface ProcessedRoute { mod: PageModule; resolved: ResolvedPath; response: PageResponse; } export function processRoute( pathname: string, location: Location, store: BehaviorSubject, pages: string[], ctx: AppContext, ): Observable { return fileSystemResolver(pathname, pages).pipe( switchMap((resolved) => componentLoader(resolved, ctx)), switchMap(({ mod, resolved }) => { /** * The default response */ const defaultResponse: PageResponse = { kind: resolved.pageName === NOT_FOUND_NAME ? 'not-found' : 'success', statusCode: resolved.pageName === NOT_FOUND_NAME ? 404 : 200, }; /** * If there are no middlwares, just return the app */ if (!mod.middleware) { return of({ resolved, mod, response: defaultResponse }); } return applyMiddleware({ location, mod, resolved, store }, mod.middleware).pipe( toArray(), map((mwOutputs: MwOutput[]) => { /** * If a middleware returned a response, use that */ const last = mwOutputs[mwOutputs.length - 1]; if (last && last.response) { return { resolved, mod, response: last.response }; } return { resolved, mod, response: defaultResponse }; }), catchError((e) => { debugger; // return of({ // response: { kind: 'error' as const, message: e.message, statusCode: 500 }, // }); return EMPTY; }), ); }), ); }