@qwik.dev/router 2.0.0-beta.42 → 2.0.0-beta.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -39,6 +39,7 @@
39
39
  tiff: "image/tiff",
40
40
  ts: "video/mp2t",
41
41
  txt: "text/plain",
42
+ wasm: "application/wasm",
42
43
  wbmp: "image/vnd.wap.wbmp",
43
44
  webm: "video/webm",
44
45
  webp: "image/webp",
@@ -225,6 +225,7 @@ var RequestEvSharedNonce = "@nonce";
225
225
  var RequestEvIsRewrite = "@rewrite";
226
226
  var RequestEvShareServerTiming = "@serverTiming";
227
227
  var RequestEvETagCacheKey = "@eTagCacheKey";
228
+ var RequestEvErrorBoundaryCaught = "@errorBoundaryCaught";
228
229
  var RequestEvHttpStatusMessage = "@httpStatusMessage";
229
230
  function getRequestRoute(requestEv) {
230
231
  return requestEv[RequestEvRoute];
@@ -851,7 +852,27 @@ async function runValidators(requestEv, validators, data, devMode) {
851
852
  requestEv.send(requestEv.status(), serialized);
852
853
  };
853
854
  }
854
- var staticPaths = /* @__PURE__ */ new Set(["__QWIK_ROUTER_STATIC_PATHS_ARRAY__"]);
855
+ /**
856
+ * A set of static paths generated by the SSG, including loader json. Routes always have a trailing
857
+ * slash, short for `.../index.html`
858
+ */ var staticPaths = /* @__PURE__ */ new Set(["__QWIK_ROUTER_STATIC_PATHS_ARRAY__"]);
859
+ /**
860
+ * Check if the current pathname needs a redirect due to trailing slash mismatch. If we're not sure,
861
+ * we fall through.
862
+ *
863
+ * Note that we ignore build/ and assets/, those never need trailing slash redirects.
864
+ *
865
+ * @returns The canonical path with the correct trailing slash if a redirect is needed, otherwise
866
+ * `undefined`.
867
+ */ function getStaticPathRedirect(method, url) {
868
+ const { pathname, search } = url;
869
+ if (method.toUpperCase() !== "GET" || pathname === "/" || !pathname.startsWith("/") || pathname.startsWith("//")) return;
870
+ const hasTrailingSlash = pathname.endsWith("/");
871
+ const routesHaveTrailingSlash = !globalThis.__NO_TRAILING_SLASH__;
872
+ if (hasTrailingSlash === routesHaveTrailingSlash) return;
873
+ const canonicalPathname = hasTrailingSlash ? pathname.slice(0, -1) : pathname + "/";
874
+ if (staticPaths.has(canonicalPathname) || !routesHaveTrailingSlash && staticPaths.has(pathname)) return canonicalPathname + search;
875
+ }
855
876
  /**
856
877
  * Decide whether a given request path is a static path, for optimizing file access.
857
878
  *
@@ -862,6 +883,7 @@ var staticPaths = /* @__PURE__ */ new Set(["__QWIK_ROUTER_STATIC_PATHS_ARRAY__"]
862
883
  const p = url.pathname;
863
884
  if (p.startsWith("/" + (globalThis.__QWIK_BUILD_DIR__ || "build") + "/")) return true;
864
885
  if (p.startsWith("/" + (globalThis.__QWIK_ASSETS_DIR__ || "assets") + "/")) return true;
886
+ if (globalThis.__NO_TRAILING_SLASH__ && p !== "/") return !p.endsWith("/") && (staticPaths.has(p) || staticPaths.has(p + "/"));
865
887
  return staticPaths.has(p);
866
888
  }
867
889
  /**
@@ -1565,6 +1587,7 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
1565
1587
  });
1566
1588
  if (typeof result.html === "string") await stream.write(result.html);
1567
1589
  boundaryErrored ||= result.errorBoundaryCaught === true;
1590
+ if (boundaryErrored) requestEv.sharedMap.set(RequestEvErrorBoundaryCaught, true);
1568
1591
  } finally {
1569
1592
  try {
1570
1593
  await stream.ready;
@@ -1750,4 +1773,4 @@ function runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRou
1750
1773
  };
1751
1774
  }
1752
1775
  }
1753
- export { isStaticPath as a, RewriteMessage as c, resolveRequestHandlers as i, mergeHeadersCookies as l, getErrorHtml as n, clearLoaderCache as o, renderQwikMiddleware as r, clearSsrCache as s, runQwikRouter as t };
1776
+ export { getStaticPathRedirect as a, clearSsrCache as c, mergeHeadersCookies as d, resolveRequestHandlers as i, RequestEvErrorBoundaryCaught as l, getErrorHtml as n, isStaticPath as o, renderQwikMiddleware as r, clearLoaderCache as s, runQwikRouter as t, RewriteMessage as u };
@@ -155,8 +155,16 @@ async function workerRender(sys, opts, staticRoute, pendingPromises, callback, d
155
155
  }
156
156
  }, opts, deps).then((rsp) => {
157
157
  if (rsp != null) return rsp.completion.then((r) => {
158
- if (routeWriter) return closePromise.then(() => r);
159
- return r;
158
+ const failRouteOnCaughtBoundary = (completion) => {
159
+ if (completion === void 0 && rsp.requestEv.sharedMap.get("@errorBoundaryCaught")) {
160
+ result.ok = false;
161
+ result.filePath = null;
162
+ return /* @__PURE__ */ new Error(`An <ErrorBoundary> caught an error while rendering ${staticRoute.pathname}`);
163
+ }
164
+ return completion;
165
+ };
166
+ if (routeWriter) return closePromise.then(() => failRouteOnCaughtBoundary(r));
167
+ return failRouteOnCaughtBoundary(r);
160
168
  });
161
169
  }).then((e) => {
162
170
  if (e !== void 0) {
@@ -829,7 +829,7 @@ function initializeSPA(goto, scroller) {
829
829
  scroll,
830
830
  historyUpdated
831
831
  };
832
- if (isBrowser) prefetchRoute(dest, true, .8, manifestHash);
832
+ if (isBrowser) prefetchRoute(dest, false, .8, manifestHash, true);
833
833
  navResolver.p = new Promise((resolve) => {
834
834
  navResolver.r = () => {
835
835
  navResolver.r = void 0;
@@ -924,8 +924,8 @@ function initializeSPA(goto, scroller) {
924
924
  const contentModules = $mods$;
925
925
  if (!isServer) routeLoaderCtx.goto = noSerialize(goto);
926
926
  updateRouteLoaderPaths(routeLoaderCtx, loadedRoute.$loaderPaths$, trackUrl);
927
- const routeLoaders = ensureRouteLoaderSignals(contentModules, loaderState, routeLoaderCtx);
928
927
  if (!isServer) invalidateNavRouteLoaders(loaderState);
928
+ const routeLoaders = ensureRouteLoaderSignals(contentModules, loaderState, routeLoaderCtx);
929
929
  if (shouldInvalidateActionLoaders) {
930
930
  if (actionLoaderHashes !== void 0) for (const hash of actionLoaderHashes) loaderState[hash]?.invalidate(true);
931
931
  else for (const loader of routeLoaders) loaderState[loader.__id].invalidate(true);
@@ -2,7 +2,7 @@ import { Y as _asyncRequestStore, d as loadRoute } from "../../chunks/head.qwik.
2
2
  import { c as resolveValidInternalFullPathname, l as trimInternalPathname, s as recognizeRequest, u as trimRecognizedInternalPathname } from "../../chunks/request-path.mjs";
3
3
  import { i as RedirectMessage, r as AbortMessage, t as ServerError } from "../../chunks/server-error.mjs";
4
4
  import { t as devPreloadedRouteLoaders } from "../../chunks/dev-preloaded-route-loader.mjs";
5
- import { a as isStaticPath, c as RewriteMessage, i as resolveRequestHandlers, l as mergeHeadersCookies, n as getErrorHtml, o as clearLoaderCache, r as renderQwikMiddleware, s as clearSsrCache, t as runQwikRouter } from "../../chunks/user-response.mjs";
5
+ import { a as getStaticPathRedirect, c as clearSsrCache, d as mergeHeadersCookies, i as resolveRequestHandlers, n as getErrorHtml, o as isStaticPath, r as renderQwikMiddleware, s as clearLoaderCache, t as runQwikRouter, u as RewriteMessage } from "../../chunks/user-response.mjs";
6
6
  import { isDev } from "@qwik.dev/core";
7
7
  var qwikRouterConfig;
8
8
  async function getConfig() {
@@ -38,12 +38,20 @@ async function loadRequestHandlers(qwikRouterConfig, pathname, method, checkOrig
38
38
  const config = await getConfig();
39
39
  const pathname = getRequestHandlerPathname(serverRequestEv);
40
40
  if (pathname === "/.well-known" || pathname.startsWith("/.well-known/")) return null;
41
- const { loadedRoute, requestHandlers } = await loadRequestHandlers(config, pathname, serverRequestEv.request.method, checkOrigin ?? true, render, serverRequestEv);
42
- if (config.fallthrough && loadedRoute.$notFound$) return null;
41
+ const staticPathRedirect = getStaticPathRedirect(serverRequestEv.request.method, serverRequestEv.url);
43
42
  const rebuildRouteInfo = async (url) => {
44
43
  const cleanPathname = trimInternalPathname(url.pathname);
45
44
  return loadRequestHandlers(config, cleanPathname, serverRequestEv.request.method, checkOrigin ?? true, render, serverRequestEv);
46
45
  };
46
+ if (staticPathRedirect) return runQwikRouter(serverRequestEv, {
47
+ $routeName$: pathname,
48
+ $params$: {},
49
+ $mods$: []
50
+ }, [(event) => {
51
+ throw event.redirect(301, staticPathRedirect);
52
+ }], rebuildRouteInfo, config.basePathname);
53
+ const { loadedRoute, requestHandlers } = await loadRequestHandlers(config, pathname, serverRequestEv.request.method, checkOrigin ?? true, render, serverRequestEv);
54
+ if (config.fallthrough && loadedRoute.$notFound$) return null;
47
55
  return runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, config.basePathname);
48
56
  }
49
57
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@qwik.dev/router",
3
3
  "description": "The router for Qwik.",
4
- "version": "2.0.0-beta.42",
4
+ "version": "2.0.0-beta.43",
5
5
  "bugs": "https://github.com/QwikDev/qwik/issues",
6
6
  "dependencies": {
7
7
  "@azure/functions": "3.5.1",
@@ -41,7 +41,7 @@
41
41
  "typescript": "5.9.3",
42
42
  "uvu": "0.5.6",
43
43
  "vite": "8.2.1",
44
- "@qwik.dev/core": "2.0.0-beta.42"
44
+ "@qwik.dev/core": "2.0.0-beta.43"
45
45
  },
46
46
  "engines": {
47
47
  "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
@@ -166,7 +166,7 @@
166
166
  "main": "./lib/index.qwik.mjs",
167
167
  "peerDependencies": {
168
168
  "vite": ">=8 <9",
169
- "@qwik.dev/core": "2.0.0-beta.42"
169
+ "@qwik.dev/core": "2.0.0-beta.43"
170
170
  },
171
171
  "publishConfig": {
172
172
  "access": "public"