Refactor routing in App component to enhance navigation and improve error handling by integrating dynamic routes and updating the NotFound route.
This commit is contained in:
39
node_modules/astro/dist/prefetch/index.d.ts
generated
vendored
Normal file
39
node_modules/astro/dist/prefetch/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
interface InitOptions {
|
||||
defaultStrategy?: string;
|
||||
prefetchAll?: boolean;
|
||||
}
|
||||
/**
|
||||
* Initialize the prefetch script, only works once.
|
||||
*
|
||||
* @param defaultOpts Default options for prefetching if not already set by the user config.
|
||||
*/
|
||||
export declare function init(defaultOpts?: InitOptions): void;
|
||||
export interface PrefetchOptions {
|
||||
/**
|
||||
* How the prefetch should prioritize the URL. (default `'link'`)
|
||||
* - `'link'`: use `<link rel="prefetch">`.
|
||||
* - `'fetch'`: use `fetch()`.
|
||||
*
|
||||
* @deprecated It is recommended to not use this option, and let prefetch use `'link'` whenever it's supported,
|
||||
* or otherwise fall back to `'fetch'`. `'link'` works better if the URL doesn't set an appropriate cache header,
|
||||
* as the browser will continue to cache it as long as it's used subsequently.
|
||||
*/
|
||||
with?: 'link' | 'fetch';
|
||||
/**
|
||||
* Should prefetch even on data saver mode or slow connection. (default `false`)
|
||||
*/
|
||||
ignoreSlowConnection?: boolean;
|
||||
}
|
||||
/**
|
||||
* Prefetch a URL so it's cached when the user navigates to it.
|
||||
*
|
||||
* @param url A full or partial URL string based on the current `location.href`. They are only fetched if:
|
||||
* - The user is online
|
||||
* - The user is not in data saver mode
|
||||
* - The URL is within the same origin
|
||||
* - The URL is not the current page
|
||||
* - The URL has not already been prefetched
|
||||
* @param opts Additional options for prefetching.
|
||||
*/
|
||||
export declare function prefetch(url: string, opts?: PrefetchOptions): void;
|
||||
export {};
|
210
node_modules/astro/dist/prefetch/index.js
generated
vendored
Normal file
210
node_modules/astro/dist/prefetch/index.js
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
const debug = import.meta.env.DEV ? console.debug : void 0;
|
||||
const inBrowser = import.meta.env.SSR === false;
|
||||
const prefetchedUrls = /* @__PURE__ */ new Set();
|
||||
const listenedAnchors = /* @__PURE__ */ new WeakSet();
|
||||
let prefetchAll = __PREFETCH_PREFETCH_ALL__;
|
||||
let defaultStrategy = __PREFETCH_DEFAULT_STRATEGY__;
|
||||
let clientPrerender = __EXPERIMENTAL_CLIENT_PRERENDER__;
|
||||
let inited = false;
|
||||
function init(defaultOpts) {
|
||||
if (!inBrowser) return;
|
||||
if (inited) return;
|
||||
inited = true;
|
||||
debug?.(`[astro] Initializing prefetch script`);
|
||||
prefetchAll ??= defaultOpts?.prefetchAll ?? false;
|
||||
defaultStrategy ??= defaultOpts?.defaultStrategy ?? "hover";
|
||||
initTapStrategy();
|
||||
initHoverStrategy();
|
||||
initViewportStrategy();
|
||||
initLoadStrategy();
|
||||
}
|
||||
function initTapStrategy() {
|
||||
for (const event of ["touchstart", "mousedown"]) {
|
||||
document.body.addEventListener(
|
||||
event,
|
||||
(e) => {
|
||||
if (elMatchesStrategy(e.target, "tap")) {
|
||||
prefetch(e.target.href, { ignoreSlowConnection: true });
|
||||
}
|
||||
},
|
||||
{ passive: true }
|
||||
);
|
||||
}
|
||||
}
|
||||
function initHoverStrategy() {
|
||||
let timeout;
|
||||
document.body.addEventListener(
|
||||
"focusin",
|
||||
(e) => {
|
||||
if (elMatchesStrategy(e.target, "hover")) {
|
||||
handleHoverIn(e);
|
||||
}
|
||||
},
|
||||
{ passive: true }
|
||||
);
|
||||
document.body.addEventListener("focusout", handleHoverOut, { passive: true });
|
||||
onPageLoad(() => {
|
||||
for (const anchor of document.getElementsByTagName("a")) {
|
||||
if (listenedAnchors.has(anchor)) continue;
|
||||
if (elMatchesStrategy(anchor, "hover")) {
|
||||
listenedAnchors.add(anchor);
|
||||
anchor.addEventListener("mouseenter", handleHoverIn, { passive: true });
|
||||
anchor.addEventListener("mouseleave", handleHoverOut, { passive: true });
|
||||
}
|
||||
}
|
||||
});
|
||||
function handleHoverIn(e) {
|
||||
const href = e.target.href;
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
timeout = setTimeout(() => {
|
||||
prefetch(href);
|
||||
}, 80);
|
||||
}
|
||||
function handleHoverOut() {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
function initViewportStrategy() {
|
||||
let observer;
|
||||
onPageLoad(() => {
|
||||
for (const anchor of document.getElementsByTagName("a")) {
|
||||
if (listenedAnchors.has(anchor)) continue;
|
||||
if (elMatchesStrategy(anchor, "viewport")) {
|
||||
listenedAnchors.add(anchor);
|
||||
observer ??= createViewportIntersectionObserver();
|
||||
observer.observe(anchor);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function createViewportIntersectionObserver() {
|
||||
const timeouts = /* @__PURE__ */ new WeakMap();
|
||||
return new IntersectionObserver((entries, observer) => {
|
||||
for (const entry of entries) {
|
||||
const anchor = entry.target;
|
||||
const timeout = timeouts.get(anchor);
|
||||
if (entry.isIntersecting) {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
timeouts.set(
|
||||
anchor,
|
||||
setTimeout(() => {
|
||||
observer.unobserve(anchor);
|
||||
timeouts.delete(anchor);
|
||||
prefetch(anchor.href);
|
||||
}, 300)
|
||||
);
|
||||
} else {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeouts.delete(anchor);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function initLoadStrategy() {
|
||||
onPageLoad(() => {
|
||||
for (const anchor of document.getElementsByTagName("a")) {
|
||||
if (elMatchesStrategy(anchor, "load")) {
|
||||
prefetch(anchor.href);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function prefetch(url, opts) {
|
||||
url = url.replace(/#.*/, "");
|
||||
const ignoreSlowConnection = opts?.ignoreSlowConnection ?? false;
|
||||
if (!canPrefetchUrl(url, ignoreSlowConnection)) return;
|
||||
prefetchedUrls.add(url);
|
||||
if (clientPrerender && HTMLScriptElement.supports?.("speculationrules")) {
|
||||
debug?.(`[astro] Prefetching ${url} with <script type="speculationrules">`);
|
||||
appendSpeculationRules(url);
|
||||
} else if (document.createElement("link").relList?.supports?.("prefetch") && opts?.with !== "fetch") {
|
||||
debug?.(`[astro] Prefetching ${url} with <link rel="prefetch">`);
|
||||
const link = document.createElement("link");
|
||||
link.rel = "prefetch";
|
||||
link.setAttribute("href", url);
|
||||
document.head.append(link);
|
||||
} else {
|
||||
debug?.(`[astro] Prefetching ${url} with fetch`);
|
||||
fetch(url, { priority: "low" });
|
||||
}
|
||||
}
|
||||
function canPrefetchUrl(url, ignoreSlowConnection) {
|
||||
if (!navigator.onLine) return false;
|
||||
if (!ignoreSlowConnection && isSlowConnection()) return false;
|
||||
try {
|
||||
const urlObj = new URL(url, location.href);
|
||||
return location.origin === urlObj.origin && (location.pathname !== urlObj.pathname || location.search !== urlObj.search) && !prefetchedUrls.has(url);
|
||||
} catch {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function elMatchesStrategy(el, strategy) {
|
||||
if (el?.tagName !== "A") return false;
|
||||
const attrValue = el.dataset.astroPrefetch;
|
||||
if (attrValue === "false") {
|
||||
return false;
|
||||
}
|
||||
if (strategy === "tap" && (attrValue != null || prefetchAll) && isSlowConnection()) {
|
||||
return true;
|
||||
}
|
||||
if (attrValue == null && prefetchAll || attrValue === "") {
|
||||
return strategy === defaultStrategy;
|
||||
}
|
||||
if (attrValue === strategy) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function isSlowConnection() {
|
||||
if ("connection" in navigator) {
|
||||
const conn = navigator.connection;
|
||||
return conn.saveData || /2g/.test(conn.effectiveType);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function onPageLoad(cb) {
|
||||
cb();
|
||||
let firstLoad = false;
|
||||
document.addEventListener("astro:page-load", () => {
|
||||
if (!firstLoad) {
|
||||
firstLoad = true;
|
||||
return;
|
||||
}
|
||||
cb();
|
||||
});
|
||||
}
|
||||
function appendSpeculationRules(url) {
|
||||
const script = document.createElement("script");
|
||||
script.type = "speculationrules";
|
||||
script.textContent = JSON.stringify({
|
||||
prerender: [
|
||||
{
|
||||
source: "list",
|
||||
urls: [url]
|
||||
}
|
||||
],
|
||||
// Currently, adding `prefetch` is required to fallback if `prerender` fails.
|
||||
// Possibly will be automatic in the future, in which case it can be removed.
|
||||
// https://github.com/WICG/nav-speculation/issues/162#issuecomment-1977818473
|
||||
prefetch: [
|
||||
{
|
||||
source: "list",
|
||||
urls: [url]
|
||||
}
|
||||
]
|
||||
});
|
||||
document.head.append(script);
|
||||
}
|
||||
export {
|
||||
init,
|
||||
prefetch
|
||||
};
|
5
node_modules/astro/dist/prefetch/vite-plugin-prefetch.d.ts
generated
vendored
Normal file
5
node_modules/astro/dist/prefetch/vite-plugin-prefetch.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type * as vite from 'vite';
|
||||
import type { AstroSettings } from '../@types/astro.js';
|
||||
export default function astroPrefetch({ settings }: {
|
||||
settings: AstroSettings;
|
||||
}): vite.Plugin;
|
53
node_modules/astro/dist/prefetch/vite-plugin-prefetch.js
generated
vendored
Normal file
53
node_modules/astro/dist/prefetch/vite-plugin-prefetch.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
const virtualModuleId = "astro:prefetch";
|
||||
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
||||
const prefetchInternalModuleFsSubpath = "astro/dist/prefetch/index.js";
|
||||
const prefetchCode = `import { init } from 'astro/virtual-modules/prefetch.js';init()`;
|
||||
function astroPrefetch({ settings }) {
|
||||
const prefetchOption = settings.config.prefetch;
|
||||
const prefetch = prefetchOption ? typeof prefetchOption === "object" ? prefetchOption : {} : void 0;
|
||||
if (prefetch && settings.scripts.every((s) => s.content !== prefetchCode)) {
|
||||
settings.scripts.push({
|
||||
stage: "page",
|
||||
content: `import { init } from 'astro/virtual-modules/prefetch.js';init()`
|
||||
});
|
||||
}
|
||||
const throwPrefetchNotEnabledError = () => {
|
||||
throw new Error("You need to enable the `prefetch` Astro config to import `astro:prefetch`");
|
||||
};
|
||||
return {
|
||||
name: "astro:prefetch",
|
||||
async resolveId(id) {
|
||||
if (id === virtualModuleId) {
|
||||
if (!prefetch) throwPrefetchNotEnabledError();
|
||||
return resolvedVirtualModuleId;
|
||||
}
|
||||
},
|
||||
load(id) {
|
||||
if (id === resolvedVirtualModuleId) {
|
||||
if (!prefetch) throwPrefetchNotEnabledError();
|
||||
return `export { prefetch } from "astro/virtual-modules/prefetch.js";`;
|
||||
}
|
||||
},
|
||||
transform(code, id) {
|
||||
if (id.includes(prefetchInternalModuleFsSubpath)) {
|
||||
code = code.replace(
|
||||
"__PREFETCH_PREFETCH_ALL__",
|
||||
// length: 25
|
||||
`${JSON.stringify(prefetch?.prefetchAll)}`.padEnd(25)
|
||||
).replace(
|
||||
"__PREFETCH_DEFAULT_STRATEGY__",
|
||||
// length: 29
|
||||
`${JSON.stringify(prefetch?.defaultStrategy)}`.padEnd(29)
|
||||
).replace(
|
||||
"__EXPERIMENTAL_CLIENT_PRERENDER__",
|
||||
// length: 33
|
||||
`${JSON.stringify(settings.config.experimental.clientPrerender)}`.padEnd(33)
|
||||
);
|
||||
return { code, map: null };
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
astroPrefetch as default
|
||||
};
|
Reference in New Issue
Block a user