UNPKG

@jay-js/system

Version:

A powerful and flexible TypeScript library for UI, state management, lazy loading, routing and managing draggable elements in modern web applications.

101 lines 4.07 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { routerOptions } from "../configuration"; import { getRoute } from "./get-route"; // Store for beforeNavigate functions - functions are automatically destroyed after execution const navigationGuards = new Set(); /** * Register a function to be executed before the next navigation. * The navigation will only proceed if the function returns true. * The function is automatically removed after being executed once. * * @param {Function} guardFn - Function that returns boolean or Promise<boolean> * @param {Object} options - Additional options (reserved for future use) * @returns {Function} - Function to manually remove the guard if needed * * @example * // Prevent navigation if form has unsaved changes * beforeNavigate(() => { * if (formHasUnsavedChanges()) { * return confirm('You have unsaved changes. Are you sure you want to leave?'); * } * return true; * }); */ export function beforeNavigate(guardFn) { navigationGuards.add(guardFn); // Return a function to manually remove the guard if needed return () => { navigationGuards.delete(guardFn); }; } /** * Executes all registered navigation guards. * Returns true if all guards pass, false otherwise. */ function runNavigationGuards() { return __awaiter(this, void 0, void 0, function* () { // Convert to array to ensure we work with a fixed set even if guards modify the set const guards = Array.from(navigationGuards); for (const guard of guards) { // Remove the guard as it should only run once navigationGuards.delete(guard); try { // Execute the guard and await if it's a promise const result = guard(); const canProceed = result instanceof Promise ? yield result : result; if (!canProceed) { return false; } } catch (error) { console.error("Navigation guard failed:", error); return false; } } return true; }); } /** * Navigates to a specified path programmatically * * This function updates the browser URL and triggers route resolution without requiring a full page reload. * If a prefix is configured in the router options, it will be automatically applied to the path. * * Before navigation occurs, any registered beforeNavigate guards are executed. * The navigation will only proceed if all guards return true. * * @param {string} path - The target path to navigate to (without the prefix) * * @example * // Navigate to the about page * navigate('/about'); * * // With a configured prefix of '/app', this would navigate to '/app/about' */ export function navigate(path) { return __awaiter(this, void 0, void 0, function* () { // Run navigation guards before proceeding const canProceed = yield runNavigationGuards(); if (!canProceed) { return; // Stop navigation if any guard returned false } const prefixOptions = routerOptions.prefix || ""; if (prefixOptions) { path = [prefixOptions, path] .join("/") .replace(/\/+$/, "") .replace(/\/{2,}/g, "/"); } history.pushState(null, "", path); getRoute(); }); } //# sourceMappingURL=navigate.js.map