{"version":3,"sources":["../../../src/client/core/pilot.ts"],"names":["createElement","createRouter","Default404","Default500","eventWaiter","generateNumber","matchesLocale","RadixRouter","defaultConfig","localUrl","tunnelUrl","PilotRoute","Pilot","config","_a","_b","_c","_d","redirect","rewrite","event","callback","id","route","previousPath","path","key","options","includeLocale","url","as","splitPath","acc","param","value","level","message","args","currentPath","index","hook","appRoute","Component","pageProps","action","addToStack","token","originalPath","result","e","hasQuery","locale","destination","props","_e","_f","_g","_h","_i","webProps","host","cache","cacheKey","cachedProps","isExpired"],"mappings":"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","sourcesContent":["/**\n * © 2022 WavePlay <dev@waveplay.com>\n */\nimport { createElement, FunctionComponent, ReactElement } from 'react'\nimport { createRouter } from 'radix3'\nimport type { ActionResult, DataMap, FlightOptions, PilotHookCallback, Redirect, Url } from '../../_internal/types'\nimport { Default404, Default500 } from '../../_internal/ui'\nimport { eventWaiter, generateNumber, matchesLocale } from '../../_internal/utils'\nimport { RadixRouter } from './radix-router'\nimport { config as defaultConfig } from '../../_generated/config'\nimport { localUrl, tunnelUrl } from '../../_generated/dev'\nimport type {\n\tPilotConfig,\n\tPilotEvent,\n\tPilotEventType,\n\tPilotFlyOptions,\n\tPilotHook,\n\tPilotPage,\n\tPilotRouteOptions,\n\tPilotRouteResult\n} from '../types'\n\nexport const PilotRoute: FunctionComponent<PilotRouteOptions> = () => null\n\nexport class Pilot {\n\t// Constructor parameters\n\tprivate _config: PilotConfig\n\n\t// State\n\tprivate _currentLocale?: string\n\tprivate _currentPage?: PilotPage\n\tprivate readonly _hooks: PilotHook[] = []\n\tprivate readonly _routerRedirects = createRouter<Redirect>()\n\tprivate readonly _routerRewrites = createRouter<Redirect>()\n\tprivate readonly _stack: string[] = []\n\n\t// Development only\n\tprivate readonly _localUrl?: string | null\n\tprivate readonly _localTunnel?: string | null\n\n\tconstructor(config?: PilotConfig) {\n\t\tthis._config = {\n\t\t\t...defaultConfig,\n\t\t\t...(config || {})\n\t\t}\n\n\t\t// Use built-in default router if none is specified\n\t\tif (!config?.router) {\n\t\t\tthis._config.router = new RadixRouter()\n\t\t}\n\n\t\t// Add redirects to router\n\t\tif (this._config?.redirects) {\n\t\t\tfor (const redirect of this._config.redirects) {\n\t\t\t\tthis._routerRedirects.insert(redirect.source, redirect)\n\t\t\t}\n\t\t}\n\n\t\t// Add rewrites to router\n\t\tif (this._config?.rewrites) {\n\t\t\tfor (const rewrite of this._config.rewrites) {\n\t\t\t\tthis._routerRewrites.insert(rewrite.source, rewrite)\n\t\t\t}\n\t\t}\n\n\t\t// Assign default locale if 18n is enabled\n\t\tthis._currentLocale = this._config?.i18n?.defaultLocale\n\n\t\t// Assign default path if router was provided\n\t\tif (config?.nextRouter) {\n\t\t\tthis._stack.push(config?.nextRouter.asPath)\n\t\t}\n\n\t\tthis.log('debug', `New instance created`)\n\n\t\t// Only use local tunnel outside of production\n\t\tif (process.env.NODE_ENV !== 'production') {\n\t\t\tthis._localUrl = localUrl\n\t\t\tthis._localTunnel = tunnelUrl\n\t\t}\n\t\tthis.log('debug', `Using host: ${this.getHost()}`)\n\t}\n\n\tpublic addHook(event: PilotEventType, callback: PilotHookCallback): number {\n\t\tthis.log('debug', `addHook()`)\n\t\tconst id = generateNumber()\n\t\tthis._hooks.push({\n\t\t\tcallback,\n\t\t\tid,\n\t\t\ttype: event\n\t\t})\n\t\treturn id\n\t}\n\n\tpublic addRoute(route: PilotRouteOptions) {\n\t\tthis.log('debug', `addRoute(${JSON.stringify(route)})`)\n\t\tif (!this._config.router) throw new Error('No router configured')\n\t\tthis._config.router.addRoute(route)\n\t}\n\n\tpublic async back() {\n\t\tthis.log('debug', `back()`)\n\n\t\t// Get previous page in stack\n\t\tthis._stack.pop()\n\t\tconst previousPath = this._stack[this._stack.length - 1]\n\n\t\treturn this._fly(previousPath, {\n\t\t\taction: async (path: string | undefined) => {\n\t\t\t\t// Delegate to NextJS router if one exists; use internal otherwise\n\t\t\t\tif (this._config.nextRouter) {\n\t\t\t\t\tconst event = eventWaiter('popstate')\n\t\t\t\t\tthis._config.nextRouter.back()\n\t\t\t\t\twindow.removeEventListener('popstate', await event)\n\t\t\t\t\treturn null\n\t\t\t\t} else {\n\t\t\t\t\treturn await this._load(path)\n\t\t\t\t}\n\t\t\t},\n\t\t\taddToStack: false\n\t\t})\n\t}\n\n\tpublic config(config?: PilotConfig): PilotConfig {\n\t\tthis.log('debug', `config(${JSON.stringify(config)})`)\n\n\t\t// It's perfectly fine to use this method just to get the current config\n\t\tif (!config) {\n\t\t\treturn this._config\n\t\t}\n\n\t\t// Update only defined properties from new config\n\t\t// You can still remove/reset a property by setting it to null\n\t\tfor (const key in config) {\n\t\t\tif (config[key] !== undefined) {\n\t\t\t\tthis._config[key] = config[key]\n\t\t\t}\n\t\t}\n\n\t\t// Assign current locale if 18n is enabled\n\t\tif (!this._currentLocale) {\n\t\t\tthis._currentLocale = config?.i18n?.defaultLocale\n\t\t}\n\n\t\t// Add redirects to router\n\t\tif (this._config?.redirects) {\n\t\t\tfor (const redirect of this._config.redirects) {\n\t\t\t\tthis._routerRedirects.insert(redirect.source, redirect)\n\t\t\t}\n\t\t}\n\n\t\t// Add rewrites to router\n\t\tif (this._config?.rewrites) {\n\t\t\tfor (const rewrite of this._config.rewrites) {\n\t\t\t\tthis._routerRewrites.insert(rewrite.source, rewrite)\n\t\t\t}\n\t\t}\n\n\t\treturn this._config\n\t}\n\n\tpublic getDefaultLocale(): string | undefined {\n\t\treturn this._config.i18n?.defaultLocale\n\t}\n\n\tpublic getHost(): string {\n\t\tthis.log('debug', `getHost()`)\n\t\treturn this._localTunnel ?? this._localUrl ?? this._config.host\n\t}\n\n\tpublic getLocale(): string | undefined {\n\t\tthis.log('debug', `getLocale()`)\n\t\treturn this._currentLocale\n\t}\n\n\tpublic getLocales(): string[] | undefined {\n\t\tthis.log('debug', `getLocales()`)\n\t\treturn this._config.i18n?.locales\n\t}\n\n\tpublic getParams(): DataMap {\n\t\tthis.log('debug', `getParams()`)\n\t\treturn this._currentPage?.params || {}\n\t}\n\n\tpublic getPath(options?: { includeLocale?: boolean }): string {\n\t\tthis.log('debug', `getPath()`)\n\t\tconst { includeLocale } = options || {}\n\n\t\tif (this._config.nextRouter) {\n\t\t\treturn this._config.nextRouter.asPath\n\t\t} else if (includeLocale && this._currentLocale) {\n\t\t\tconst path = this._stack[this._stack.length - 1]\n\t\t\treturn path ? '/' + this._currentLocale + path : undefined\n\t\t} else {\n\t\t\treturn this._stack[this._stack.length - 1]\n\t\t}\n\t}\n\n\tpublic getProps(): any {\n\t\tthis.log('debug', `getProps()`)\n\t\treturn this._currentPage?.pageProps || {}\n\t}\n\n\tpublic getQuery(): DataMap {\n\t\tthis.log('debug', `getQuery()`)\n\t\tif (this._config.nextRouter) {\n\t\t\treturn this._config.nextRouter.query as DataMap\n\t\t} else {\n\t\t\treturn this._currentPage?.query || {}\n\t\t}\n\t}\n\n\t/**\n\t * Equivalent to Next's router.push().\n\t * Updates content with registered path component, also loading their props.\n\t * If a placeholder has been specified, it'll render that while the props are fetching.\n\t *\n\t * @param path\n\t */\n\tpublic async fly(url: Url, as?: string, options?: PilotFlyOptions) {\n\t\tthis.log('debug', `fly(${JSON.stringify(url)})`)\n\n\t\treturn this._fly(url, {\n\t\t\taction: async (path: string) => {\n\t\t\t\t// Delegate to NextJS router if one exists; use internal router otherwise\n\t\t\t\tif (this._config.nextRouter) {\n\t\t\t\t\t// Account for updated path (e.g. hook overrides, redirects)\n\t\t\t\t\tif (typeof url !== 'string') {\n\t\t\t\t\t\t// Extract just the pathname from \"path\" along with any query params\n\t\t\t\t\t\tconst splitPath = path.split('?')\n\t\t\t\t\t\turl.pathname = splitPath?.[0]\n\t\t\t\t\t\turl.query = splitPath?.[1]?.split('&').reduce((acc, param) => {\n\t\t\t\t\t\t\tconst [key, value] = param.split('=')\n\t\t\t\t\t\t\tacc[key] = value\n\t\t\t\t\t\t\treturn acc\n\t\t\t\t\t\t}, {} as DataMap)\n\t\t\t\t\t}\n\n\t\t\t\t\tawait this._config.nextRouter.push(url, as, options)\n\t\t\t\t\treturn null\n\t\t\t\t} else {\n\t\t\t\t\treturn await this._load(path, options)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\n\tpublic log(level: 'trace' | 'debug' | 'info' | 'warn' | 'error', message?: string, ...args: any[]) {\n\t\tconst id = `PilotJS${this._config.id ? '-' + this._config.id : ''}`\n\t\tif (this._config.logger) {\n\t\t\tthis._config.logger?.[level]?.(`[${id}] ` + message, ...args)\n\t\t} else if (level === 'error') {\n\t\t\t// Error is the only level that should be logged to console by default\n\t\t\t// You can disable this by passing in a custom logger\n\t\t\tconsole.error(`[${id}] ` + message, ...args)\n\t\t}\n\t}\n\n\t/**\n\t * Alias for fly().\n\t *\n\t * See {@link fly} for more details.\n\t */\n\tpublic async push(url: Url, as?: string, options?: PilotFlyOptions) {\n\t\treturn this.fly(url, as, options)\n\t}\n\n\tpublic async reload() {\n\t\tthis.log('debug', `refresh()`)\n\n\t\t// Get current page in stack\n\t\tconst currentPath = this._stack[this._stack.length - 1]\n\n\t\treturn this._fly(currentPath, {\n\t\t\taction: async (path: string) => {\n\t\t\t\t// Delegate to NextJS router if one exists; use internal otherwise\n\t\t\t\tif (this._config.nextRouter) {\n\t\t\t\t\tconst event = eventWaiter('load')\n\t\t\t\t\tthis._config.nextRouter.reload()\n\t\t\t\t\twindow.removeEventListener('load', await event)\n\t\t\t\t\treturn null\n\t\t\t\t} else {\n\t\t\t\t\treturn await this._load(path)\n\t\t\t\t}\n\t\t\t},\n\t\t\taddToStack: false\n\t\t})\n\t}\n\n\tpublic removeHook(id: number) {\n\t\tthis.log('debug', `removeHook(${id})`)\n\t\tconst index = this._hooks.findIndex((hook) => hook.id === id)\n\t\tthis._hooks.splice(index, 1)\n\t}\n\n\tpublic removeRoute(path: string) {\n\t\tthis.log('debug', `removeRoute(${path})`)\n\t\tthis._config.router?.removeRoute(path)\n\t}\n\n\tpublic render(): ReactElement | null {\n\t\tthis.log('debug', `render()`)\n\n\t\t// Can't render anything if no page has been set\n\t\tif (!this._currentPage) return null\n\n\t\t// See if an _app component has been registered (without the unnecessary _load() overhead)\n\t\tconst appRoute = this._config.router?.find('/_app', { pilot: this })\n\n\t\t// Render whatever is currently set, plus the props!\n\t\t// If an _app component has been registered, wrap the page in it\n\t\tconst { Component, pageProps } = this._currentPage\n\t\tif (appRoute) {\n\t\t\treturn createElement(appRoute.Component, { Component, pageProps } as any) // safe to assume _app follows this prop signature\n\t\t} else {\n\t\t\treturn createElement(Component, pageProps)\n\t\t}\n\t}\n\n\tpublic stats() {\n\t\treturn {\n\t\t\tdev: {\n\t\t\t\tlocalUrl: this._localUrl,\n\t\t\t\ttunnelUrl: this._localTunnel\n\t\t\t},\n\t\t\thost: this._config.host,\n\t\t\tid: this._config.id,\n\t\t\ti18: this._config.i18n,\n\t\t\tlogger: this._config.logger,\n\t\t\tnextRouter: !!this._config.nextRouter,\n\t\t\tpath: this.getPath() || null,\n\t\t\tparams: this.getParams(),\n\t\t\trouterStats: this._config.router?.stats(),\n\t\t\tquery: this.getQuery(),\n\t\t\tstackLength: this._stack.length\n\t\t}\n\t}\n\n\t/**\n\t * Boilerplate function mainly used to de-duplicate a lot of logic.\n\t * To be called by certain other functions like back(), fly(), and refresh().\n\t *\n\t * @param path Path to navigate to. Mainly used for notifying listeners.\n\t * @param options Should contain action to execute + other options.\n\t */\n\tprivate async _fly(url: Url | undefined, options: FlightOptions) {\n\t\tconst { action, addToStack = true } = options\n\n\t\t// Get path from URL or use directly if string\n\t\tlet path: string\n\t\tif (url) {\n\t\t\tpath = typeof url === 'string' ? url : url.pathname\n\n\t\t\t// Query values are important too, ya know\n\t\t\tif (typeof url !== 'string' && url.query) {\n\t\t\t\tlet token = '?'\n\t\t\t\tfor (let key in url.query) {\n\t\t\t\t\tpath += `${token}${key}=${url.query[key]}`\n\t\t\t\t\ttoken = '&'\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Notify listeners and allow them to modify the path\n\t\t\tconst originalPath = path\n\t\t\tpath = await this._notify(path, { type: 'load-start' })\n\t\t\tif (path !== originalPath) {\n\t\t\t\tthis.log('info', `A hook has modified this path: ${path}`)\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\t// Execute specified action\n\t\t\tconst result = await action(path)\n\n\t\t\t// If redirected, recursively call this function again with the new path after notifying hooks\n\t\t\tif (result?.redirect) {\n\t\t\t\tthis._notify(path, { type: 'redirect' })\n\t\t\t\tconst redirect = typeof url === 'string' ? result.redirect : { ...url, pathname: result.redirect }\n\t\t\t\treturn await this._fly(redirect, options)\n\t\t\t}\n\t\t\tthis._currentPage = result?.page\n\t\t} catch (e) {\n\t\t\t// In case of error, exit early & notify listeners\n\t\t\tthis.log('error', `Error while executing action:`, e)\n\t\t\tthis._notify(path, {\n\t\t\t\ttype: 'error',\n\t\t\t\tpage: undefined\n\t\t\t})\n\t\t}\n\n\t\t// Add to stack\n\t\tif (path && addToStack) {\n\t\t\tthis._stack.push(path)\n\t\t\tthis.log('debug', `New stack size: ${this._stack.length}`)\n\t\t}\n\n\t\t// Notify listeners\n\t\tif (path) {\n\t\t\tthis._notify(path, {\n\t\t\t\ttype: this._config.nextRouter || this._currentPage ? 'load-complete' : 'error',\n\t\t\t\tpage: this._currentPage\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Loads a page and its props by calling it's `getServerSideProps()` or `getStaticProps()` function.\n\t * The result is then stored into _currentPage to be rendered via the `render()` function.\n\t *\n\t * This will not create an instance of the page component, but rather just call the props function.\n\t * The component instance will be created when the page is rendered.\n\t *\n\t * @param path Path to load.\n\t * @returns Component and props for the specified path. If no component is found, returns null.\n\t */\n\tprivate async _load(path: string, options?: PilotFlyOptions): Promise<ActionResult> {\n\t\tconst hasQuery = path.includes('?')\n\n\t\t// Handle locale prefix only as long as caller doesn't opt out\n\t\tif (options?.locale !== false) {\n\t\t\t// If this path starts with another registered locale, make sure to update the current locale\n\t\t\tconst locale = options?.locale ?? matchesLocale(path, this._config.i18n?.locales, hasQuery)\n\n\t\t\tif (locale && locale !== this._currentLocale) {\n\t\t\t\tthis.log('debug', `Locale changed from ${this._currentLocale} to ${locale}`)\n\t\t\t\tthis._currentLocale = locale\n\t\t\t}\n\n\t\t\t// Paths are handled internally, so we need to strip the locale prefix or router won't match\n\t\t\tif (path.startsWith(`/${this._currentLocale}/`)) {\n\t\t\t\tpath = path.replace(`/${this._currentLocale}`, '')\n\t\t\t} else if (path === `/${this._currentLocale}`) {\n\t\t\t\tpath = '/'\n\t\t\t} else if (hasQuery && path.substring(0, path.indexOf('?')) === `/${this._currentLocale}`) {\n\t\t\t\tpath = '/'\n\t\t\t}\n\t\t}\n\n\t\t// Check if this path matches any of the redirects defined in the config\n\t\tconst redirect = this._routerRedirects.lookup(hasQuery ? path.substring(0, path.indexOf('?')) : path)\n\n\t\tif (redirect) {\n\t\t\tlet destination = redirect.destination\n\t\t\tthis.log('info', `Redirect found for path \"${path}\" -> \"${destination}\"`)\n\n\t\t\t// Add query params to redirect destination\n\t\t\tif (hasQuery) {\n\t\t\t\tdestination += path.substring(path.indexOf('?'))\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tredirect: destination\n\t\t\t}\n\t\t}\n\n\t\t// Check if this path matches any of the rewrites defined in the config\n\t\tconst rewrite = this._routerRewrites.lookup(hasQuery ? path.substring(0, path.indexOf('?')) : path)\n\n\t\tif (rewrite) {\n\t\t\tlet destination = rewrite.destination\n\t\t\tthis.log('info', `Rewrite found for path \"${path}\" -> \"${destination}\"`)\n\n\t\t\t// Add query params to redirect destination\n\t\t\tif (hasQuery) {\n\t\t\t\tdestination += path.substring(path.indexOf('?'))\n\t\t\t}\n\n\t\t\tpath = destination\n\t\t}\n\n\t\t// Look up the route data for this path\n\t\tlet route = this._config.router?.find(path, { pilot: this })\n\n\t\t// If no route is found, load 404 page instead\n\t\tif (route) {\n\t\t\tthis.log('debug', `Route found for path: ${path} ...`, route)\n\t\t} else if (path === '/404' || path === '/500') {\n\t\t\t// Assign a default 404 page if none is found for convenience and to avoid infinite loops\n\t\t\tthis.log('warn', `Using default ${path} ...`)\n\t\t\troute = {\n\t\t\t\tComponent: path === '/404' ? Default404 : Default500,\n\t\t\t\tpath,\n\t\t\t\tparams: {},\n\t\t\t\tquery: {}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.log('warn', `No route found for path: ${path}`)\n\t\t\treturn await this._load('/404')\n\t\t}\n\n\t\t// Call this page's internal server side or static props function\n\t\t// This will emulate a NextJS page load, but without the usual server parameters, so be aware\n\t\tlet props: any\n\t\ttry {\n\t\t\tprops = await this._loadProps(path, route, options)\n\t\t} catch (e) {\n\t\t\tthis.log('error', `Error loading props for path: ${path}`, e)\n\t\t\tthis._notify(path, { error: e, type: 'error' })\n\n\t\t\t// If the 500 error page itself has errors, you've got a bigger problem... òwó\n\t\t\tif (path === '/500') {\n\t\t\t\tthis._notify(path, { error: e, type: 'load-complete' })\n\t\t\t\tthrow e\n\t\t\t} else {\n\t\t\t\treturn await this._load('/500')\n\t\t\t}\n\t\t}\n\n\t\tif (props?.props) {\n\t\t\tthis.log('info', `Loaded props for ${path}:`, Object.keys(props.props))\n\t\t} else if (props?.notFound) {\n\t\t\tthis.log('info', `Route responded with \"notFound\": ${path}`)\n\t\t\treturn await this._load('/404')\n\t\t} else if (props?.redirect?.destination) {\n\t\t\tthis.log('info', `Route responded with \"redirect\": ${path} -> ${props.redirect.destination}`)\n\t\t\treturn {\n\t\t\t\tredirect: props.redirect.destination\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tpage: {\n\t\t\t\tComponent: route.Component,\n\t\t\t\tparams: route.params || {},\n\t\t\t\tpageProps: props?.props,\n\t\t\t\tquery: route.query || {}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Calls route's getProps() function to load props for the specified path.\n\t * This basically emulates NextJS' getServerSideProps() or getStaticProps() function.\n\t * If a \"revalidate\" value is returned, it will be stored in our LRU memory cache.\n\t *\n\t * On native, these props are called on the server-side if \"host\" is set, otherwise they are called on the app.\n\t *\n\t * @param path Path to load.\n\t * @param route Route for the specified path.\n\t * @returns Props for the specified path.\n\t */\n\tprivate async _loadProps(path: string, route: PilotRouteResult, options?: PilotFlyOptions): Promise<any> {\n\t\tconst { webProps = this._config.webProps?.[route.path] ?? 'auto' } = options ?? {}\n\t\tlet props: any = null\n\n\t\t// Return early if there's nothing to load\n\t\tif (!route.getProps) {\n\t\t\treturn props\n\t\t}\n\n\t\tconst host = this.getHost()\n\t\tif (webProps === 'always' || (webProps === 'auto' && host)) {\n\t\t\tthis.log('debug', `Loading props remotely for path:`, path)\n\t\t\tconst response = await fetch(host + '/api/pilot/get-props', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json'\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tdefaultLocale: this._config.i18n?.defaultLocale,\n\t\t\t\t\tlocale: this._currentLocale,\n\t\t\t\t\tlocales: this._config.i18n?.locales,\n\t\t\t\t\tpath: path\n\t\t\t\t})\n\t\t\t})\n\t\t\tprops = await response.json()\n\t\t} else {\n\t\t\tthis.log('debug', `Loading props natively for path:`, path)\n\n\t\t\t// See if we can find a cached version of this page's props\n\t\t\tconst cache = this._config.nativeCache\n\t\t\tlet cacheKey: string\n\t\t\tif (cache) {\n\t\t\t\tcacheKey = (this._currentLocale || '') + path\n\t\t\t\tconst cachedProps = cache.get(cacheKey)\n\t\t\t\tconst isExpired = !cachedProps || cachedProps?.__pilot?.expires < Date.now()\n\t\t\t\tif (cachedProps && isExpired) {\n\t\t\t\t\tthis.log('debug', `Cached props for ${path} have expired, removing from cache...`)\n\t\t\t\t\tcache.delete(cacheKey)\n\t\t\t\t} else if (cachedProps && !isExpired) {\n\t\t\t\t\tthis.log('debug', `Found cached props for path: ${path}`)\n\t\t\t\t\treturn cachedProps\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Get props from route's getProps() function\n\t\t\tprops = await route.getProps({\n\t\t\t\tdefaultLocale: this._config.i18n?.defaultLocale,\n\t\t\t\tlocale: this._currentLocale,\n\t\t\t\tlocales: this._config.i18n?.locales,\n\t\t\t\tparams: route.params ?? {},\n\t\t\t\tquery: route.query ?? {},\n\t\t\t\treq: {} as any,\n\t\t\t\tres: {} as any,\n\t\t\t\tresolvedUrl: path\n\t\t\t})\n\n\t\t\t// If a \"revalidate\" value is returned, cache the props for that amount of time\n\t\t\t// This emulates ISR (Incremental Static Regeneration) from NextJS\n\t\t\tif (cache && props?.revalidate) {\n\t\t\t\tthis.log('debug', `Caching props for path: ${path} (revalidate: ${props.revalidate})`)\n\t\t\t\tcache.set(cacheKey, {\n\t\t\t\t\t...props,\n\t\t\t\t\t__pilot: {\n\t\t\t\t\t\texpires: Date.now() + props.revalidate * 1000\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\treturn props\n\t}\n\n\t/**\n\t * Notifies all added hooks of a certain event.\n\t * This allows hooks to modify the path, or do other things in response to events.\n\t *\n\t * @param path Path to notify listeners about.\n\t * @param event Event to notify listeners about.\n\t * @returns The modified path. If no hooks modify the path, this will be the same as the original.\n\t */\n\tprivate async _notify(path: string, event: PilotEvent): Promise<string> {\n\t\tthis.log('debug', `_notify(${path}, ${event.type})`)\n\t\tfor (let hook of this._hooks) {\n\t\t\tif (hook.type === event.type || hook.type === '*') {\n\t\t\t\tconst result = hook.callback(path, event)\n\t\t\t\tif (result) {\n\t\t\t\t\tpath = result\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn path\n\t}\n}\n"]}