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

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.
@@ -1380,6 +1380,7 @@ function createResolveRequestHandlers() {
1380
1380
  if (accept && !accept.includes("text/html")) throw e;
1381
1381
  const status = e.status;
1382
1382
  requestEv.status(status);
1383
+ requestEv.headers.set("Cache-Control", "no-store");
1383
1384
  const errorLoader = route.$errorLoader$;
1384
1385
  route.$mods$ = errorLoader ? await Promise.all(errorLoader.map((load) => load())) : [await loadHttpError()];
1385
1386
  requestEv.sharedMap.set(RequestEvHttpStatusMessage, typeof e.data === "string" ? e.data : "Server Error");
@@ -1393,6 +1394,7 @@ function createResolveRequestHandlers() {
1393
1394
  requestEv.sharedMap.delete(RequestEvSharedActionId);
1394
1395
  requestEv.sharedMap.delete(RequestEvSharedActionFormData);
1395
1396
  requestEv.sharedMap.delete("@actionResult");
1397
+ requestEv.sharedMap.delete(RequestEvETagCacheKey);
1396
1398
  }
1397
1399
  async function runValidators(requestEv, validators, data) {
1398
1400
  let lastResult = {
@@ -1517,7 +1519,11 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
1517
1519
  if (!responseHeaders.has("Content-Type")) responseHeaders.set("Content-Type", "text/html; charset=utf-8");
1518
1520
  const cachePlan = requestEv.sharedMap.get(RequestEvETagCacheKey);
1519
1521
  const { readable, writable } = new TextEncoderStream();
1520
- const writableStream = requestEv.getWritableStream();
1522
+ let responseWriter;
1523
+ const lazyResponseSink = new WritableStream({ write(chunk) {
1524
+ responseWriter ||= requestEv.getWritableStream().getWriter();
1525
+ return responseWriter.write(chunk);
1526
+ } });
1521
1527
  let cacheChunks;
1522
1528
  let pipeSource = readable;
1523
1529
  if (cachePlan) {
@@ -1529,7 +1535,10 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
1529
1535
  pipeSource = readable.pipeThrough(capture);
1530
1536
  }
1531
1537
  let pipeError;
1532
- const pipe = pipeSource.pipeTo(writableStream, { preventClose: true }).catch((error) => {
1538
+ let boundaryErrored = false;
1539
+ let noStoreSent = false;
1540
+ let overrodeCacheControl = false;
1541
+ const pipe = pipeSource.pipeTo(lazyResponseSink, { preventClose: true }).catch((error) => {
1533
1542
  pipeError = error;
1534
1543
  });
1535
1544
  const stream = writable.getWriter();
@@ -1544,16 +1553,30 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
1544
1553
  containerAttributes: {
1545
1554
  ["q:render"]: isStatic ? "static" : "",
1546
1555
  ...serverData.containerAttributes
1556
+ },
1557
+ onBeforeFirstFlush: (info) => {
1558
+ if (info.errorBoundaryCaught) {
1559
+ boundaryErrored = true;
1560
+ noStoreSent = true;
1561
+ overrodeCacheControl = responseHeaders.has("Cache-Control");
1562
+ responseHeaders.set("Cache-Control", "no-store");
1563
+ }
1547
1564
  }
1548
1565
  });
1549
1566
  if (typeof result.html === "string") await stream.write(result.html);
1567
+ boundaryErrored ||= result.errorBoundaryCaught === true;
1550
1568
  } finally {
1551
- await stream.ready;
1552
- await stream.close();
1553
- await pipe;
1569
+ try {
1570
+ await stream.ready;
1571
+ await stream.close();
1572
+ } finally {
1573
+ await pipe;
1574
+ responseWriter?.releaseLock();
1575
+ }
1554
1576
  }
1555
1577
  if (pipeError) throw pipeError;
1556
- if (cachePlan && cacheChunks && cacheChunks.length > 0) {
1578
+ if (boundaryErrored && (noStoreSent ? cachePlan || overrodeCacheControl : !!cachePlan)) console.warn(`An <ErrorBoundary> caught during SSR of ${requestEv.url.pathname} — configured caching disabled: ` + (noStoreSent ? "the response was sent with Cache-Control: no-store." : "the SSR cache was skipped (response headers were already sent)."));
1579
+ if (cachePlan && cacheChunks && cacheChunks.length > 0 && !boundaryErrored) {
1557
1580
  const totalLength = cacheChunks.reduce((sum, chunk) => sum + chunk.length, 0);
1558
1581
  const combined = new Uint8Array(totalLength);
1559
1582
  let offset = 0;
@@ -1568,7 +1591,7 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
1568
1591
  body: html
1569
1592
  });
1570
1593
  }
1571
- await writableStream.close();
1594
+ if (responseWriter) await requestEv.getWritableStream().close();
1572
1595
  };
1573
1596
  }
1574
1597
  function now() {
package/lib/index.d.ts CHANGED
@@ -391,14 +391,6 @@ declare interface EndpointResponse {
391
391
  loaderHashes?: string[];
392
392
  }
393
393
 
394
- /** @public */
395
- export declare const ErrorBoundary: Component<ErrorBoundaryProps>;
396
-
397
- /** @public */
398
- declare interface ErrorBoundaryProps {
399
- fallback$?: QRL<(error: any) => any>;
400
- }
401
-
402
394
  /**
403
395
  * Drops control-flow signals (`ev.redirect()`, `ev.error()`, etc.) from a loader/action return
404
396
  * type: those are thrown, not surfaced as data. `ev.fail()` is plain data and is kept.
@@ -1,24 +1,15 @@
1
1
  import { t as ensureSlash } from "./chunks/pathname.mjs";
2
2
  import { A as routeLoader$, B as RouteLoaderCtxContext, E as isImmutableLoader, F as ContentContext, G as QACTION_KEY, H as RouteNavigateContext, I as ContentInternalContext, J as Q_ROUTE, K as QDATA_KEY, L as DocumentHeadContext, M as setLoaderSignalValue, P as updateRouteLoaderPaths, R as HttpStatusContext, T as invalidateNavRouteLoaders, U as RoutePreventNavigateContext, V as RouteLocationContext, W as RouteStateContext, _ as fetchRouteLoaderData, a as isPromise, b as getRequestEvent, c as shouldPreload, d as loadRoute, g as ensureRouteLoaderSignals, i as getClientNavPath, j as routeLoaderQrl, l as toPath, m as clearNavFetchCache, n as resolveHead, o as isSameOrigin, q as QFN_KEY, s as isSamePath, t as createDocumentHead, u as toUrl, y as getModuleRouteLoaders, z as RouteActionContext } from "./chunks/head.qwik.mjs";
3
- import { SkipRender, Slot, _captures, _fnSignal, _getConstProps, _getVarProps, _jsxSorted, _jsxSplit, _qrlSync, _restProps, _wrapProp, componentQrl, createComputedQrl, createElement, eventQrl, getLocale, implicit$FirstArg, inlinedQrl, isBrowser, isDev, isServer, noSerialize, untrack, useContext, useContextProvider, useErrorBoundary, useOnWindow, useServerData, useSignal, useStore, useTaskQrl, useVisibleTaskQrl, withLocale } from "@qwik.dev/core";
4
- import { Fragment } from "@qwik.dev/core/jsx-runtime";
3
+ import { SkipRender, Slot, _captures, _fnSignal, _getConstProps, _getVarProps, _jsxSorted, _jsxSplit, _qrlSync, _restProps, _wrapProp, componentQrl, createComputedQrl, createElement, eventQrl, getLocale, implicit$FirstArg, inlinedQrl, isBrowser, isDev, isServer, noSerialize, untrack, useContext, useContextProvider, useServerData, useSignal, useStore, useTaskQrl, useVisibleTaskQrl, withLocale } from "@qwik.dev/core";
5
4
  import * as qwikRouterConfig from "@qwik-router-config";
6
5
  import { p } from "@qwik.dev/core/preloader";
7
6
  import { _deserialize, _getContextContainer, _getContextHostElement, _hasStoreEffects, _serialize, _waitUntilRendered, forceStoreEffects } from "@qwik.dev/core/internal";
7
+ import { Fragment } from "@qwik.dev/core/jsx-runtime";
8
8
  import * as v from "valibot";
9
9
  import * as z$1 from "zod";
10
10
  import { z } from "zod";
11
11
  import swRegister from "@qwik-router-sw-register";
12
12
  import { renderToStream } from "@qwik.dev/core/server";
13
- /** @public */ var ErrorBoundary = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props) => {
14
- const store = useErrorBoundary();
15
- useOnWindow("qerror", /*#__PURE__*/ inlinedQrl((e) => {
16
- const store = _captures[0];
17
- store.error = e.detail.error;
18
- }, "ErrorBoundary_component_useOnWindow_G0jFRpoNY0M", [store]));
19
- if (store.error && props.fallback$) return /*#__PURE__*/ _jsxSorted(Fragment, null, null, props.fallback$(store.error), 1, "bA_0");
20
- return /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "bA_1");
21
- }, "ErrorBoundary_component_pOa6vjtC7ik"));
22
13
  /**
23
14
  * Prefetch a route's loader data in parallel (fire-and-forget). The per-nav fetch map dedupes
24
15
  * repeat hovers and shares the promise with the navigation's own fetch; the browser HTTP cache
@@ -1692,4 +1683,4 @@ var GetForm = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((_rawProps) =>
1692
1683
  })
1693
1684
  ], 1, "r5_3");
1694
1685
  }, "DocumentHeadTags_component_9CrWYOoCpgY"));
1695
- export { DocumentHeadTags, ErrorBoundary, Form, Link, QWIK_CITY_SCROLLER, QWIK_ROUTER_SCROLLER, QwikCityMockProvider, QwikCityProvider, QwikRouterMockProvider, QwikRouterProvider, RouterOutlet, ServiceWorkerRegister, createRenderer, getRequestEvent, globalAction$, globalActionQrl, omitProps, routeAction$, routeActionQrl, routeLoader$, routeLoaderQrl, server$, serverQrl, untypedAppUrl, useContent, useDocumentHead, useHttpStatus, useLocation, useNavigate, usePreventNavigate$, usePreventNavigateQrl, useQwikRouter, valibot$, valibotQrl, validator$, validatorQrl, z, zod$, zodQrl };
1686
+ export { DocumentHeadTags, Form, Link, QWIK_CITY_SCROLLER, QWIK_ROUTER_SCROLLER, QwikCityMockProvider, QwikCityProvider, QwikRouterMockProvider, QwikRouterProvider, RouterOutlet, ServiceWorkerRegister, createRenderer, getRequestEvent, globalAction$, globalActionQrl, omitProps, routeAction$, routeActionQrl, routeLoader$, routeLoaderQrl, server$, serverQrl, untypedAppUrl, useContent, useDocumentHead, useHttpStatus, useLocation, useNavigate, usePreventNavigate$, usePreventNavigateQrl, useQwikRouter, valibot$, valibotQrl, validator$, validatorQrl, z, zod$, zodQrl };
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.41",
4
+ "version": "2.0.0-beta.42",
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.41"
44
+ "@qwik.dev/core": "2.0.0-beta.42"
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.41"
169
+ "@qwik.dev/core": "2.0.0-beta.42"
170
170
  },
171
171
  "publishConfig": {
172
172
  "access": "public"