UNPKG

@virtualstate/navigation

Version:

Native JavaScript [navigation](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API) implementation

98 lines 3.31 kB
import { isPromise, like } from "../is.js"; import { getRouterRoutes, isRouter } from "./router.js"; import { exec } from "./url-pattern.js"; export async function transitionEvent(router, event) { const promises = []; const { signal, } = event; const url = getURL(event); const { pathname } = url; transitionPart("route", (route, match) => route.fn(event, match), handleResolve, handleReject); if (promises.length) { await Promise.all(promises); } function transitionPart(type, fn, resolve = handleResolve, reject = handleReject) { let isRoute = false; resolveRouter(router); return isRoute; function matchRoute(route, parentMatch) { const { router, pattern, string } = route; let match = parentMatch; if (string) { if (string !== pathname) { return; } } else if (pattern) { match = exec(pattern, url); if (!match) return; } if (isRouter(router)) { return resolveRouter(router, match); } isRoute = true; try { const maybe = fn(route, match); if (isPromise(maybe)) { promises.push(maybe .then(resolve) .catch(reject)); } else { resolve(maybe); } } catch (error) { reject(error); } } function resolveRouter(router, match) { const routes = getRouterRoutes(router); resolveRoutes(routes[type]); resolveRoutes(routes.router); function resolveRoutes(routes) { for (const route of routes) { if (signal?.aborted) break; matchRoute(route, match); } } } } function noop() { } function handleResolve(value) { transitionPart("resolve", (route, match) => route.fn(value, event, match), noop, handleReject); } function handleReject(error) { const isRoute = transitionPart("reject", (route, match) => route.fn(error, event, match), noop, (error) => Promise.reject(error)); if (!isRoute) { throw error; } } function getURL(event) { if (isDestination(event)) { return new URL(event.destination.url); } else if (isRequest(event)) { return new URL(event.request.url); } else if (isURL(event)) { return new URL(event.url); } throw new Error("Could not get url from event"); function isDestination(event) { return (like(event) && !!event.destination); } function isRequest(event) { return (like(event) && !!event.request); } function isURL(event) { return (like(event) && !!(event.url && (typeof event.url === "string" || event.url instanceof URL))); } } } //# sourceMappingURL=transition.js.map