Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | 1x 1x 435x 435x 435x 1x 1x 125x 125x 125x 125x 125x 125x 125x 125x 125x 125x 125x 125x 125x 125x 1x 63x 63x 63x 63x 63x 63x 63x 63x 63x 63x 63x 63x 1x 69x 2x 2x 67x 67x 69x 22x 22x 45x 45x 45x 45x 1x 7x 22x 22x 7x 7x 1x 19x 19x 55x 15x 15x 55x 19x 19x 1x 22x 22x 22x 22x 3x 3x 22x 55x 55x 19x 19x 19x 19x 55x 19x 19x 1x 1x 1x 1x 1x 1x 2x 2x 1x 1x 1x | import type {
NavigationResult,
NavigationState,
NavigationHistoryEntry,
QueryParams
} from '#src/types';
// Utility functions
const generateRandomId = () => Math.random().toString(36).substring(2, 9);
export const getHash = (url: string): string => {
const urlObject = new URL(url);
return urlObject.hash.slice(1).replace('/', '') || '/';
};
export const createHash = (hash: string) => `/${hash}`;
export const createHistoryEntry = (
url: string,
state: NavigationState = {},
index: number = 0
): NavigationHistoryEntry => {
return {
url,
key : generateRandomId(),
id : generateRandomId(),
index,
sameDocument: true,
state,
hash : getHash(url),
};
};
export const createNavigationResult = (destination: NavigationHistoryEntry): NavigationResult => {
let commitResolve: (value: NavigationHistoryEntry) => void;
let finishResolve: (value: NavigationHistoryEntry) => void;
const committed = new Promise<NavigationHistoryEntry>((resolve) => {
commitResolve = resolve;
});
const finished = new Promise<NavigationHistoryEntry>((resolve) => {
finishResolve = resolve;
});
// Use setTimeout to simulate the async nature of navigation
setTimeout(() => commitResolve(destination), 0);
setTimeout(() => finishResolve(destination), 10);
return { committed, finished, };
};
export const isRouteMatch = (pattern: string, hash: string) => {
// Handle null or undefined hash
if(hash === null || hash === undefined) {
return false;
}
// Split the pattern and URL into segments to ensure they have the same length
const patternSegments = pattern.split('/');
const hashSegments = hash.split('/');
// If the segments don't match in length, return false
if(patternSegments.length !== hashSegments.length) {
return false;
}
// Replace route parameters with a regex pattern that matches any characters
const patternRegex = pattern.replace(/:\w+/g, '([^/]+)');
// Create a regular expression for matching the URL
const regex = new RegExp(`^${patternRegex}$`);
// Check if the hash matches the pattern
return regex.test(hash);
};
export const getRouteMap = (routeNames: string[]) => {
return routeNames.reduce((acc, name) => {
acc[name] = name;
return acc;
}, {} as Record<string, string>);
};
export const getRouteItem = <T>(map: Record<string, T>, hash: string) => {
let route: T | undefined;
return Object.keys(map).reduce((acc, key) => {
if(isRouteMatch(key, hash)) {
acc = map[key];
}
return acc;
}, route);
};
export const getParamsFromUrl = (pattern: string, hash: string): Record<string, string> => {
const params: Record<string, string> = {};
// Split the pattern and URL into segments
const patternSegments = pattern.split('/');
const urlSegments = hash.split('/');
// If the segments don't match in length, return empty params
if(patternSegments.length !== urlSegments.length) {
return params;
}
// Iterate through the pattern segments
for(let i = 0; i < patternSegments.length; i++) {
const patternSegment = patternSegments[i];
// Check if the segment is a parameter (starts with ':')
if(patternSegment.startsWith(':')) {
// Extract the parameter name (remove the ':')
const paramName = patternSegment.substring(1);
// Get the corresponding value from the URL
const paramValue = urlSegments[i];
// Add to the params object
params[paramName] = paramValue;
}
}
return params;
};
export const parseQueryParams = <T extends QueryParams = QueryParams>(urlPart: string): T => {
const queryString = urlPart.split('?')[1];
if(!queryString) {
return {} as T;
}
const params = queryString.split('&');
const queryParams: { [key: string]: string } = {};
params.forEach((param) => {
const [key, value] = param.split('=');
queryParams[key] = value ? decodeURIComponent(value) : '';
});
return queryParams as T;
}; |