UNPKG

@virtualstate/navigation

Version:

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

101 lines 3.2 kB
import { defer } from "../defer.js"; import { getNavigation } from "../get-navigation.js"; import { isPromise } from "../is.js"; export function createRepeatingPromise(fn) { let promise; function getPromise() { if (promise) return promise; const current = promise = fn(); promise.finally(() => { if (promise === current) { promise = undefined; } }); return promise; } return { get [Symbol.toStringTag]() { return "[Promise Repeating]"; }, then(onResolve, onReject) { return getPromise().then(onResolve, onReject); }, catch(onReject) { return getPromise().catch(onReject); }, finally(onFinally) { return getPromise().finally(onFinally); } }; } export function createNavigationEvent(type, navigation = getNavigation()) { return createRepeatingPromise(getNavigationPromise); function getNavigationPromise() { return createNavigationPromise(type, navigation); } } export function createNavigationEvents(navigation = getNavigation()) { return { navigate: createNavigationEvent("navigate", navigation), navigateerror: createNavigationEvent("navigateerror", navigation), navigatesuccess: createNavigationEvent("navigatesuccess", navigation), entrieschange: createNavigationEvent("entrieschange", navigation), currententrychange: createNavigationEvent("currententrychange", navigation) }; } export async function createNavigationPromise(type, navigation = getNavigation(), onEventFn) { const { promise, resolve, reject } = defer(); navigation.addEventListener(type, onEvent, { once: true }); if (type !== "navigate") { navigation.addEventListener("navigate", onNavigate, { once: true }); } if (type !== "navigateerror") { navigation.addEventListener("navigateerror", onError, { once: true }); } return promise; function removeListeners() { navigation.removeEventListener(type, onEvent); if (type !== "navigate") { navigation.removeEventListener("navigate", onNavigate); } if (type !== "navigateerror") { navigation.removeEventListener("navigateerror", onError); } } function onEvent(event) { removeListeners(); if (onEventFn) { try { const result = onEventFn(event); if (isPromise(result)) { return result.then(() => resolve(event), reject); } } catch (error) { return reject(error); } } else if (isNavigateEvent(event)) { onNavigate(event); } resolve(event); } function isNavigateEvent(event) { return event.type === "navigate"; } function onNavigate(event) { event.intercept(); } function onError(event) { removeListeners(); reject(event.error); } } //# sourceMappingURL=create-promise.js.map