@qwik.dev/router 2.0.0-beta.36 → 2.0.0-beta.38

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.
Files changed (41) hide show
  1. package/lib/adapters/cloudflare-pages/vite/index.mjs +3 -5
  2. package/lib/adapters/shared/vite/index.d.ts +3 -4
  3. package/lib/adapters/shared/vite/index.mjs +167 -155
  4. package/lib/chunks/dev-preloaded-route-loader.mjs +3 -0
  5. package/lib/chunks/format.mjs +31 -0
  6. package/lib/chunks/fs.mjs +10 -8
  7. package/lib/chunks/head.qwik.mjs +1425 -0
  8. package/lib/chunks/http-error.qwik.mjs +2 -2
  9. package/lib/chunks/pathname.mjs +3 -32
  10. package/lib/chunks/request-body-limit.mjs +37 -0
  11. package/lib/chunks/request-path.mjs +60 -0
  12. package/lib/chunks/routes.mjs +47 -0
  13. package/lib/chunks/server-error.mjs +19 -0
  14. package/lib/chunks/system.mjs +8 -8
  15. package/lib/chunks/use-functions.qwik.mjs +3 -12
  16. package/lib/chunks/user-response.mjs +1875 -0
  17. package/lib/chunks/worker-thread.mjs +317 -0
  18. package/lib/index.d.ts +251 -44
  19. package/lib/index.qwik.mjs +734 -485
  20. package/lib/middleware/aws-lambda/index.mjs +2 -1
  21. package/lib/middleware/azure-swa/index.mjs +13 -9
  22. package/lib/middleware/cloudflare-pages/index.mjs +2 -2
  23. package/lib/middleware/deno/index.d.ts +2 -0
  24. package/lib/middleware/deno/index.mjs +2 -1
  25. package/lib/middleware/netlify-edge/index.mjs +2 -2
  26. package/lib/middleware/node/index.d.ts +9 -1
  27. package/lib/middleware/node/index.mjs +28 -3
  28. package/lib/middleware/request-handler/index.d.ts +65 -26
  29. package/lib/middleware/request-handler/index.mjs +38 -1679
  30. package/lib/middleware/vercel-edge/index.mjs +2 -2
  31. package/lib/ssg/index.d.ts +5 -13
  32. package/lib/ssg/index.mjs +14 -53
  33. package/lib/vite/index.d.ts +23 -0
  34. package/lib/vite/index.mjs +533 -122
  35. package/package.json +4 -3
  36. package/lib/chunks/deepFreeze.qwik.mjs +0 -18
  37. package/lib/chunks/error-handler.mjs +0 -57
  38. package/lib/chunks/not-found-wrapper.qwik.mjs +0 -25
  39. package/lib/chunks/redirect-handler.mjs +0 -6
  40. package/lib/chunks/routing.qwik.mjs +0 -821
  41. package/lib/chunks/worker-thread.qwik.mjs +0 -2585
@@ -1,11 +1,13 @@
1
- import { componentQrl, inlinedQrl, useErrorBoundary, useOnWindow, _captures, _jsxSorted, Slot, useSignal, untrack, _qrlSync, useVisibleTaskQrl, _jsxSplit, _getConstProps, _getVarProps, isDev, eventQrl, isServer, useStylesQrl, useServerData, useStore, useContextProvider, useTaskQrl, getLocale, noSerialize, isBrowser, useContext, SkipRender, implicit$FirstArg, withLocale, _wrapProp, _restProps, _fnSignal, createElement } from '@qwik.dev/core';
1
+ import { componentQrl, inlinedQrl, useErrorBoundary, useOnWindow, _captures, _jsxSorted, Slot, isBrowser, isDev, untrack, _qrlSync, _jsxSplit, _getConstProps, _getVarProps, eventQrl, isServer, useServerData, useStore, useSignal, useContextProvider, useTaskQrl, noSerialize, getLocale, createComputedQrl, useContext, SkipRender, implicit$FirstArg, withLocale, _wrapProp, _restProps, _fnSignal, createElement } from '@qwik.dev/core';
2
2
  import { Fragment } from '@qwik.dev/core/jsx-runtime';
3
- import { g as getClientNavPath, s as shouldPreload, p as preloadRouteBundles, l as loadClientData, i as isSamePath, c as createLoaderSignal, a as createDocumentHead, b as loadRoute, r as resolveHead, C as CLIENT_DATA_CACHE, d as isSameOrigin, Q as Q_ROUTE, D as DEFAULT_LOADERS_SERIALIZATION_STRATEGY, t as toUrl, e as clientNavigate, f as toPath, h as QFN_KEY, j as QACTION_KEY, k as QDATA_KEY } from './chunks/routing.qwik.mjs';
4
- import { u as useNavigate, a as useLocation, b as useQwikRouterEnv, C as ContentContext, c as ContentInternalContext, D as DocumentHeadContext, H as HttpStatusContext, R as RouteLocationContext, d as RouteNavigateContext, e as RouteStateContext, f as RouteActionContext, g as RoutePreventNavigateContext, h as useAction, i as useDocumentHead } from './chunks/use-functions.qwik.mjs';
5
- export { j as useContent, k as useHttpStatus, l as usePreventNavigate$, m as usePreventNavigateQrl } from './chunks/use-functions.qwik.mjs';
6
3
  import * as qwikRouterConfig from '@qwik-router-config';
7
- import { _getContextContainer, SerializerSymbol, _UNINITIALIZED, _hasStoreEffects, forceStoreEffects, _waitUntilRendered, _getContextHostElement, _getContextEvent, _serialize, _deserialize, _resolveContextWithoutSequentialScope } from '@qwik.dev/core/internal';
8
- import { _asyncRequestStore } from '@qwik.dev/router/middleware/request-handler';
4
+ import { p } from '@qwik.dev/core/preloader';
5
+ import { e as ensureSlash } from './chunks/pathname.mjs';
6
+ import { l as loadRoute, f as fetchRouteLoaderData, g as getClientNavPath, s as shouldPreload, i as isSamePath, t as toPath, a as isSameOrigin, Q as QACTION_KEY, e as ensureRouteLoaderSignals, b as setLoaderSignalValue, c as createDocumentHead, C as ContentContext, d as ContentInternalContext, D as DocumentHeadContext, H as HttpStatusContext, h as RouteLocationContext, j as RouteNavigateContext, k as RouteStateContext, m as RouteLoaderCtxContext, n as RouteActionContext, o as RoutePreventNavigateContext, u as updateRouteLoaderPaths, r as resolveHead, p as Q_ROUTE, q as toUrl, v as getRequestEvent, w as QFN_KEY, x as QDATA_KEY } from './chunks/head.qwik.mjs';
7
+ export { y as routeLoader$, z as routeLoaderQrl } from './chunks/head.qwik.mjs';
8
+ import { u as useNavigate, a as useLocation, b as useDocumentHead, c as useQwikRouterEnv, d as useAction } from './chunks/use-functions.qwik.mjs';
9
+ export { e as useContent, f as useHttpStatus, g as usePreventNavigate$, h as usePreventNavigateQrl } from './chunks/use-functions.qwik.mjs';
10
+ import { _deserialize, _hasStoreEffects, _getContextContainer, forceStoreEffects, _waitUntilRendered, _getContextHostElement, _serialize } from '@qwik.dev/core/internal';
9
11
  import * as v from 'valibot';
10
12
  import * as z from 'zod';
11
13
  export { z } from 'zod';
@@ -26,13 +28,53 @@ const ErrorBoundary = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((p
26
28
  return /* @__PURE__ */ _jsxSorted(Slot, null, null, null, 3, "bA_1");
27
29
  }, "ErrorBoundary_component_pOa6vjtC7ik"));
28
30
 
29
- const __vite_import_meta_env__ = {};
31
+ async function prefetchRoute(url, prefetchData, probability = 0.8, manifestHash, prefetchBundle = true) {
32
+ if (!isBrowser || isDev) {
33
+ return;
34
+ }
35
+ try {
36
+ const loadedRoute = await loadRoute(qwikRouterConfig.routes, qwikRouterConfig.cacheModules, url.pathname);
37
+ if (!loadedRoute) {
38
+ return;
39
+ }
40
+ if (prefetchBundle) {
41
+ let routeName = loadedRoute.$routeName$;
42
+ routeName = ensureSlash(routeName);
43
+ if (routeName.length > 1 && routeName.startsWith("/")) {
44
+ routeName = routeName.slice(1);
45
+ }
46
+ p(routeName, probability);
47
+ }
48
+ if (!prefetchData || !manifestHash) {
49
+ return;
50
+ }
51
+ if (loadedRoute.$loaders$?.length && loadedRoute.$loaderPaths$) {
52
+ const basePath = qwikRouterConfig.basePathname ?? "/";
53
+ for (const hash of loadedRoute.$loaders$) {
54
+ let loaderPath = loadedRoute.$loaderPaths$?.[hash];
55
+ if (!loaderPath) {
56
+ continue;
57
+ }
58
+ if (basePath !== "/" && !loaderPath.startsWith(basePath)) {
59
+ loaderPath = basePath + loaderPath.slice(1);
60
+ }
61
+ fetchRouteLoaderData(hash, loaderPath, manifestHash, {
62
+ pageUrl: url,
63
+ basePath
64
+ }).catch(() => {
65
+ });
66
+ }
67
+ }
68
+ } catch {
69
+ }
70
+ }
71
+
30
72
  const Link = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) => {
31
73
  const nav = useNavigate();
32
74
  const loc = useLocation();
75
+ const head = useDocumentHead();
33
76
  const originalHref = props.href;
34
- const anchorRef = useSignal();
35
- const { onClick$, prefetch: prefetchProp, reload, replaceState, scroll, prefetchBundle: prefetchBundleProp = "visible", prefetchData: prefetchDataProp = prefetchProp === "js" ? "off" : "intent", ...linkProps } = props;
77
+ const { onClick$, prefetch: prefetchProp, reload, replaceState, scroll, prefetchBundles: prefetchBundlesProp = "visible", prefetchData: prefetchDataProp = prefetchProp === "js" ? "off" : "intent", ...linkProps } = props;
36
78
  const clientNavPath = untrack(getClientNavPath, {
37
79
  ...linkProps,
38
80
  reload
@@ -40,29 +82,23 @@ const Link = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) =>
40
82
  linkProps.href = clientNavPath || originalHref;
41
83
  const isDepratedPrefetchDisabled = prefetchProp === false;
42
84
  const shouldPrefetch = untrack(shouldPreload, clientNavPath, loc);
43
- const shouldPrefetchBundle = !!clientNavPath && prefetchBundleProp !== "off" && shouldPrefetch && !isDepratedPrefetchDisabled;
85
+ const shouldVisiblePrefetchBundles = !!clientNavPath && shouldPrefetch && !isDepratedPrefetchDisabled && (prefetchBundlesProp === "visible" || // deprecated prop below, remove in favor of prefetchBundles
86
+ prefetchProp === "js" || prefetchProp === true);
87
+ const shouldVisiblePrefetchData = !!clientNavPath && shouldPrefetch && !isDepratedPrefetchDisabled && (prefetchDataProp === "visible" || // deprecated prop below, remove in favor of prefetchData
88
+ prefetchProp === true);
44
89
  const shouldPrefetchData = !!clientNavPath && prefetchDataProp !== "off" && shouldPrefetch && !isDepratedPrefetchDisabled;
45
- const handleBundlePrefetch = shouldPrefetchBundle ? /* @__PURE__ */ inlinedQrl((_, elm) => {
46
- if (navigator.connection?.saveData) {
47
- return;
48
- }
49
- if (elm && elm.href) {
50
- const url = new URL(elm.href);
51
- preloadRouteBundles(url.pathname);
52
- }
53
- }, "Link_component_handleBundlePrefetch_ZttUP0kLKj0") : null;
54
90
  const handleDataPrefetch = shouldPrefetchData ? /* @__PURE__ */ inlinedQrl((_, elm) => {
91
+ const head2 = _captures[0];
55
92
  if (navigator.connection?.saveData) {
56
93
  return;
57
94
  }
58
95
  if (elm && elm.href) {
59
96
  const url = new URL(elm.href);
60
- loadClientData(url, {
61
- preloadRouteBundles: false,
62
- isPrefetch: true
63
- });
97
+ prefetchRoute(url, true, 0.8, head2.manifestHash, false);
64
98
  }
65
- }, "Link_component_handleDataPrefetch_lcd4O9LHbbA") : null;
99
+ }, "Link_component_handleDataPrefetch_lcd4O9LHbbA", [
100
+ head
101
+ ]) : null;
66
102
  const preventDefault = clientNavPath ? _qrlSync((event) => {
67
103
  if (!(event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {
68
104
  event.preventDefault();
@@ -104,46 +140,13 @@ const Link = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) =>
104
140
  ]) : null;
105
141
  const handlePreload = /* @__PURE__ */ inlinedQrl((_, elm) => {
106
142
  const url = new URL(elm.href);
107
- preloadRouteBundles(url.pathname, 1);
143
+ prefetchRoute(url, false, 1);
108
144
  }, "Link_component_handlePreload_AAemwtuBjsE");
109
- useVisibleTaskQrl(/* @__PURE__ */ inlinedQrl(({ track }) => {
110
- const anchorRef2 = _captures[0], handleBundlePrefetch2 = _captures[1], handleDataPrefetch2 = _captures[2], linkProps2 = _captures[3], loc2 = _captures[4], prefetchBundleProp2 = _captures[5], prefetchDataProp2 = _captures[6], prefetchProp2 = _captures[7];
111
- track(() => loc2.url.pathname);
112
- const handler = linkProps2.onQVisible$;
113
- if (handler) {
114
- const event = new CustomEvent("qvisible");
115
- if (Array.isArray(handler)) {
116
- handler.flat(10).forEach((handler2) => handler2?.(event, anchorRef2.value));
117
- } else {
118
- handler?.(event, anchorRef2.value);
119
- }
120
- }
121
- const isProdOrTest = !isDev || __vite_import_meta_env__?.TEST;
122
- if (isProdOrTest && anchorRef2.value) {
123
- if (prefetchBundleProp2 === "visible" || // deprecated prop below, remove in favor of prefetchBundle
124
- prefetchProp2 === "js" || prefetchProp2 === true) {
125
- handleBundlePrefetch2?.(null, anchorRef2.value);
126
- }
127
- if (prefetchDataProp2 === "visible" || // deprecated prop below, remove in favor of prefetchData
128
- prefetchProp2 === true) {
129
- handleDataPrefetch2?.(null, anchorRef2.value);
130
- }
131
- }
132
- }, "Link_component_useVisibleTask_xKeuRmnoNSA", [
133
- anchorRef,
134
- handleBundlePrefetch,
135
- handleDataPrefetch,
136
- linkProps,
137
- loc,
138
- prefetchBundleProp,
139
- prefetchDataProp,
140
- prefetchProp
141
- ]));
142
145
  return /* @__PURE__ */ _jsxSplit("a", {
143
- ref: anchorRef,
144
146
  "q:link": !!clientNavPath,
145
147
  ..._getVarProps(linkProps),
146
148
  ..._getConstProps(linkProps),
149
+ "data-q-prefetch": shouldVisiblePrefetchBundles && shouldVisiblePrefetchData ? "bd" : shouldVisiblePrefetchBundles ? "b" : shouldVisiblePrefetchData ? "d" : null,
147
150
  "q-e:click": [
148
151
  preventDefault,
149
152
  handlePreload,
@@ -166,13 +169,105 @@ const Link = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) =>
166
169
  linkProps.onKeyDown$,
167
170
  prefetchDataProp === "commit" ? onEnterKeyDown : null
168
171
  ]
169
- }, {
170
- // We need to prevent the onQVisible$ from being called twice since it is handled in the visible task
171
- "q-e:qvisible": []
172
- }, /* @__PURE__ */ _jsxSorted(Slot, null, null, null, 3, "jO_0"), 0, "jO_1");
172
+ }, null, /* @__PURE__ */ _jsxSorted(Slot, null, null, null, 3, "jO_0"), 0, "jO_1");
173
173
  }, "Link_component_VPmar9tb3t4"));
174
174
 
175
- const transitionCss = "@layer qwik{@supports selector(html:active-view-transition-type(type)){html:active-view-transition-type(qwik-navigation){:root{view-transition-name:none}}}@supports not selector(html:active-view-transition-type(type)){:root{view-transition-name:none}}}";
175
+ const newScrollState = () => {
176
+ return {
177
+ x: 0,
178
+ y: 0,
179
+ w: 0,
180
+ h: 0
181
+ };
182
+ };
183
+ const clientNavigate = (win, navType, fromURL, toURL, replaceState = false) => {
184
+ if (navType !== "popstate") {
185
+ const samePath = isSamePath(fromURL, toURL);
186
+ const sameHash = fromURL.hash === toURL.hash;
187
+ if (!samePath || !sameHash) {
188
+ const newState = {
189
+ _qRouterScroll: newScrollState()
190
+ };
191
+ if (replaceState) {
192
+ win.history.replaceState(newState, "", toPath(toURL));
193
+ } else {
194
+ win.history.pushState(newState, "", toPath(toURL));
195
+ }
196
+ }
197
+ }
198
+ };
199
+ const preloadRouteBundles = (path, probability = 0.8) => {
200
+ if (isBrowser) {
201
+ path = ensureSlash(path);
202
+ path = path.length > 1 && path.startsWith("/") ? path.slice(1) : path;
203
+ p(path, probability);
204
+ }
205
+ };
206
+
207
+ let prefetchedLinks = /* @__PURE__ */ new WeakSet();
208
+ let cleanupPrefetchObserver;
209
+ const resetLinkPrefetchState = () => {
210
+ prefetchedLinks = /* @__PURE__ */ new WeakSet();
211
+ };
212
+ const createLinkPrefetchObserver = (manifestHash) => {
213
+ const anchors = document.querySelectorAll("a[q\\:link][data-q-prefetch]");
214
+ const prefetchAnchor = (anchor, observer2) => {
215
+ if (prefetchedLinks.has(anchor)) {
216
+ return;
217
+ }
218
+ prefetchedLinks.add(anchor);
219
+ observer2?.unobserve(anchor);
220
+ if (navigator.connection?.saveData || !anchor.href) {
221
+ return;
222
+ }
223
+ let url;
224
+ try {
225
+ url = new URL(anchor.href);
226
+ } catch {
227
+ return;
228
+ }
229
+ const currentUrl = new URL(location.href);
230
+ if (!isSameOrigin(url, currentUrl) || !shouldPreload(toPath(url), {
231
+ url: currentUrl
232
+ })) {
233
+ return;
234
+ }
235
+ const mode = anchor.getAttribute("data-q-prefetch") || "";
236
+ if (mode.includes("b")) {
237
+ preloadRouteBundles(url.pathname);
238
+ }
239
+ if (mode.includes("d")) {
240
+ prefetchRoute(url, true, 0.8, manifestHash, false);
241
+ }
242
+ };
243
+ if (typeof IntersectionObserver === "undefined") {
244
+ anchors.forEach((anchor) => prefetchAnchor(anchor));
245
+ return () => {
246
+ };
247
+ }
248
+ const observer = new IntersectionObserver((entries) => {
249
+ for (const entry of entries) {
250
+ if (entry.isIntersecting) {
251
+ prefetchAnchor(entry.target, observer);
252
+ }
253
+ }
254
+ });
255
+ anchors.forEach((anchor) => observer.observe(anchor));
256
+ return () => {
257
+ observer.disconnect();
258
+ };
259
+ };
260
+ const refreshLinkPrefetchObserver = (manifestHash) => {
261
+ resetLinkPrefetchState();
262
+ cleanupPrefetchObserver?.();
263
+ cleanupPrefetchObserver = createLinkPrefetchObserver(manifestHash);
264
+ };
265
+ const linkPrefetchInit = (manifestHash) => eventQrl(/* @__PURE__ */ inlinedQrl(() => {
266
+ const manifestHash2 = _captures[0];
267
+ refreshLinkPrefetchObserver(manifestHash2);
268
+ }, "linkPrefetchInit_event_hoZr9O26Irg", [
269
+ manifestHash
270
+ ]));
176
271
 
177
272
  function callRestoreScrollOnDocument() {
178
273
  if (document.__q_scroll_restore__) {
@@ -357,26 +452,82 @@ const spaInit = eventQrl(/* @__PURE__ */ inlinedQrl((_, el) => {
357
452
  }, 200);
358
453
  };
359
454
  window._qRouterScrollEnabled = true;
360
- setTimeout(() => {
361
- window.addEventListener("popstate", window._qRouterInitPopstate);
362
- window.addEventListener("scroll", window._qRouterInitScroll, {
455
+ window.addEventListener("popstate", window._qRouterInitPopstate);
456
+ window.addEventListener("scroll", window._qRouterInitScroll, {
457
+ passive: true
458
+ });
459
+ document.addEventListener("click", window._qRouterInitAnchors);
460
+ if (!window.navigation) {
461
+ document.addEventListener("visibilitychange", window._qRouterInitVisibility, {
363
462
  passive: true
364
463
  });
365
- document.addEventListener("click", window._qRouterInitAnchors);
366
- if (!window.navigation) {
367
- document.addEventListener("visibilitychange", window._qRouterInitVisibility, {
368
- passive: true
369
- });
370
- }
371
- }, 0);
464
+ }
372
465
  }
373
466
  }, "spa_init_event_igI1pUsax0E"));
374
467
 
375
- const startViewTransition = (params) => {
376
- if (!params.update) {
468
+ async function submitAction(action, routePath) {
469
+ const pathBase = ensureSlash(routePath);
470
+ const url = `${pathBase}?${QACTION_KEY}=${encodeURIComponent(action.id)}`;
471
+ const actionData = action.data;
472
+ action.data = void 0;
473
+ let fetchOptions;
474
+ if (actionData instanceof FormData) {
475
+ fetchOptions = {
476
+ method: "POST",
477
+ body: actionData,
478
+ headers: {
479
+ Accept: "application/json"
480
+ }
481
+ };
482
+ } else {
483
+ fetchOptions = {
484
+ method: "POST",
485
+ body: JSON.stringify(actionData),
486
+ headers: {
487
+ "Content-Type": "application/json; charset=UTF-8",
488
+ Accept: "application/json"
489
+ }
490
+ };
491
+ }
492
+ const response = await fetch(url, fetchOptions);
493
+ if (response.redirected) {
494
+ const redirectedURL = new URL(response.url);
495
+ if (redirectedURL.origin !== location.origin) {
496
+ location.href = redirectedURL.href;
497
+ return void 0;
498
+ }
499
+ location.href = redirectedURL.href;
500
+ return void 0;
501
+ }
502
+ if ((response.headers.get("content-type") || "").includes("json")) {
503
+ const text = await response.text();
504
+ const data = await _deserialize(text);
505
+ return {
506
+ status: response.status,
507
+ result: data?.result,
508
+ redirect: data?.redirect,
509
+ loaderHashes: data?.loaderHashes
510
+ };
511
+ }
512
+ return void 0;
513
+ }
514
+
515
+ const transitionCss = "@layer qwik{@supports selector(html:active-view-transition-type(type)){html:active-view-transition-type(qwik-navigation){:root{view-transition-name:none}}}@supports not selector(html:active-view-transition-type(type)){:root{view-transition-name:none}}}";
516
+
517
+ const shouldStartViewTransition = (viewTransition) => viewTransition === true && "startViewTransition" in document;
518
+ const VIEW_TRANSITION_STYLE_ID = "qwik-view-transition";
519
+ const ensureViewTransitionStyles = () => {
520
+ if (document.getElementById(VIEW_TRANSITION_STYLE_ID)) {
377
521
  return;
378
522
  }
523
+ const style = document.createElement("style");
524
+ style.id = VIEW_TRANSITION_STYLE_ID;
525
+ style.textContent = transitionCss;
526
+ document.head.appendChild(style);
527
+ };
528
+ const startViewTransition = (params) => {
379
529
  if ("startViewTransition" in document) {
530
+ ensureViewTransitionStyles();
380
531
  let transition;
381
532
  try {
382
533
  transition = document.startViewTransition(params);
@@ -387,9 +538,14 @@ const startViewTransition = (params) => {
387
538
  detail: transition
388
539
  });
389
540
  document.dispatchEvent(event);
390
- return transition;
541
+ return {
542
+ ready: transition.ready,
543
+ transition
544
+ };
391
545
  } else {
392
- params.update?.();
546
+ return {
547
+ ready: params.update()
548
+ };
393
549
  }
394
550
  };
395
551
 
@@ -399,11 +555,198 @@ const preventNav = {};
399
555
  const internalState = {
400
556
  navCount: 0
401
557
  };
558
+ const getScroller = () => {
559
+ let scroller = document.getElementById(QWIK_ROUTER_SCROLLER);
560
+ if (!scroller) {
561
+ scroller = document.getElementById(QWIK_CITY_SCROLLER);
562
+ if (scroller && isDev) {
563
+ console.warn(`Please update your scroller ID to "${QWIK_ROUTER_SCROLLER}" as "${QWIK_CITY_SCROLLER}" is deprecated and will be removed in V3`);
564
+ }
565
+ }
566
+ return scroller ?? document.documentElement;
567
+ };
568
+ const useQwikMockRouter = (props) => {
569
+ const urlEnv = props.url ?? "http://localhost/";
570
+ const url = new URL(urlEnv);
571
+ const routeLocation = useStore({
572
+ url,
573
+ params: props.params ?? {},
574
+ isNavigating: false,
575
+ prevUrl: void 0
576
+ }, {
577
+ deep: false
578
+ });
579
+ const loadersData = props.loaders?.reduce((acc, { loader, data }) => {
580
+ acc[loader.__id] = data;
581
+ return acc;
582
+ }, {});
583
+ const loadersState = useStore({}, {
584
+ deep: false
585
+ });
586
+ for (const [loaderId, data] of Object.entries(loadersData ?? {})) {
587
+ loadersState[loaderId] ||= createComputedQrl(/* @__PURE__ */ inlinedQrl(() => {
588
+ const data2 = _captures[0];
589
+ return data2;
590
+ }, "useQwikMockRouter_createComputed_JL6bChMwwyc", [
591
+ data
592
+ ]));
593
+ }
594
+ const goto = props.goto ?? /* @__PURE__ */ inlinedQrl(async () => {
595
+ console.warn("QwikRouterMockProvider: goto not provided");
596
+ }, "useQwikMockRouter_goto_aViHFxQ1a3s");
597
+ const documentHead = useStore(createDocumentHead, {
598
+ deep: false
599
+ });
600
+ const content = useStore({
601
+ headings: void 0,
602
+ menu: void 0
603
+ }, {
604
+ deep: false
605
+ });
606
+ const contentInternal = useSignal();
607
+ const actionState = useSignal();
608
+ const httpStatus = useSignal({
609
+ status: 200,
610
+ message: ""
611
+ });
612
+ useContextProvider(ContentContext, content);
613
+ useContextProvider(ContentInternalContext, contentInternal);
614
+ useContextProvider(DocumentHeadContext, documentHead);
615
+ useContextProvider(HttpStatusContext, httpStatus);
616
+ useContextProvider(RouteLocationContext, routeLocation);
617
+ useContextProvider(RouteNavigateContext, goto);
618
+ useContextProvider(RouteStateContext, loadersState);
619
+ useContextProvider(RouteActionContext, actionState);
620
+ const actionsMocks = props.actions?.reduce((acc, { action, handler }) => {
621
+ acc[action.__id] = handler;
622
+ return acc;
623
+ }, {});
624
+ useTaskQrl(/* @__PURE__ */ inlinedQrl(async ({ track }) => {
625
+ const actionState2 = _captures[0], actionsMocks2 = _captures[1];
626
+ const action = track(actionState2);
627
+ if (!action?.resolve) {
628
+ return;
629
+ }
630
+ const mock = actionsMocks2?.[action.id];
631
+ if (mock) {
632
+ const actionResult = await mock(action.data);
633
+ action.resolve(actionResult);
634
+ }
635
+ }, "useQwikMockRouter_useTask_tXTLR4tzCy0", [
636
+ actionState,
637
+ actionsMocks
638
+ ]));
639
+ };
640
+ const QwikRouterMockProvider = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) => {
641
+ useQwikMockRouter(props);
642
+ return /* @__PURE__ */ _jsxSorted(Slot, null, null, null, 3, "5y_1");
643
+ }, "QwikRouterMockProvider_component_IN4dVpT0x74"));
644
+ const QwikCityMockProvider = QwikRouterMockProvider;
645
+ function initializeSPA(goto, scroller) {
646
+ if (!window._qRouterSPA) {
647
+ window._qRouterSPA = true;
648
+ history.scrollRestoration = "manual";
649
+ window.addEventListener("popstate", () => {
650
+ window._qRouterScrollEnabled = false;
651
+ clearTimeout(window._qRouterScrollDebounce);
652
+ goto(location.href, {
653
+ type: "popstate"
654
+ });
655
+ });
656
+ window.removeEventListener("popstate", window._qRouterInitPopstate);
657
+ window._qRouterInitPopstate = void 0;
658
+ if (!window._qRouterHistoryPatch) {
659
+ window._qRouterHistoryPatch = true;
660
+ const pushState = history.pushState;
661
+ const replaceState = history.replaceState;
662
+ const prepareState = (state) => {
663
+ if (state === null || typeof state === "undefined") {
664
+ state = {};
665
+ } else if (state?.constructor !== Object) {
666
+ state = {
667
+ _data: state
668
+ };
669
+ if (isDev) {
670
+ console.warn("In a Qwik SPA context, `history.state` is used to store scroll state. Direct calls to `pushState()` and `replaceState()` must supply an actual Object type. We need to be able to automatically attach the scroll state to your state object. A new state object has been created, your data has been moved to: `history.state._data`");
671
+ }
672
+ }
673
+ state._qRouterScroll = state._qRouterScroll || currentScrollState(scroller);
674
+ return state;
675
+ };
676
+ history.pushState = (state, title, url) => {
677
+ state = prepareState(state);
678
+ return pushState.call(history, state, title, url);
679
+ };
680
+ history.replaceState = (state, title, url) => {
681
+ state = prepareState(state);
682
+ return replaceState.call(history, state, title, url);
683
+ };
684
+ }
685
+ document.addEventListener("click", (event) => {
686
+ if (event.defaultPrevented) {
687
+ return;
688
+ }
689
+ const target = event.target.closest("a[href]");
690
+ if (target && !target.hasAttribute("preventdefault:click")) {
691
+ const href = target.getAttribute("href");
692
+ const prev = new URL(location.href);
693
+ const dest = new URL(href, prev);
694
+ if (isSameOrigin(dest, prev) && isSamePath(dest, prev)) {
695
+ event.preventDefault();
696
+ if (!dest.hash && !dest.href.endsWith("#")) {
697
+ if (dest.href !== prev.href) {
698
+ history.pushState(null, "", dest);
699
+ }
700
+ window._qRouterScrollEnabled = false;
701
+ clearTimeout(window._qRouterScrollDebounce);
702
+ saveScrollHistory({
703
+ ...currentScrollState(scroller),
704
+ x: 0,
705
+ y: 0
706
+ });
707
+ location.reload();
708
+ return;
709
+ }
710
+ goto(target.getAttribute("href"));
711
+ }
712
+ }
713
+ });
714
+ document.removeEventListener("click", window._qRouterInitAnchors);
715
+ window._qRouterInitAnchors = void 0;
716
+ if (!window.navigation) {
717
+ document.addEventListener("visibilitychange", () => {
718
+ if (window._qRouterScrollEnabled && document.visibilityState === "hidden") {
719
+ const scrollState = currentScrollState(scroller);
720
+ saveScrollHistory(scrollState);
721
+ }
722
+ }, {
723
+ passive: true
724
+ });
725
+ document.removeEventListener("visibilitychange", window._qRouterInitVisibility);
726
+ window._qRouterInitVisibility = void 0;
727
+ }
728
+ window.addEventListener("scroll", () => {
729
+ if (!window._qRouterScrollEnabled) {
730
+ return;
731
+ }
732
+ clearTimeout(window._qRouterScrollDebounce);
733
+ window._qRouterScrollDebounce = setTimeout(() => {
734
+ const scrollState = currentScrollState(scroller);
735
+ saveScrollHistory(scrollState);
736
+ window._qRouterScrollDebounce = void 0;
737
+ }, 200);
738
+ }, {
739
+ passive: true
740
+ });
741
+ removeEventListener("scroll", window._qRouterInitScroll);
742
+ window._qRouterInitScroll = void 0;
743
+ spaInit.resolve();
744
+ }
745
+ }
402
746
  const useQwikRouter = (props) => {
403
747
  if (!isServer) {
404
748
  throw new Error("useQwikRouter can only run during SSR on the server. If you are seeing this, it means you are re-rendering the root of your application. Fix that or use the <QwikRouterProvider> component around the root of your application.");
405
749
  }
406
- useStylesQrl(/* @__PURE__ */ inlinedQrl(transitionCss, "qwik_view_transition_css_inline_vNfd9raIMI0"));
407
750
  const env = useQwikRouterEnv();
408
751
  if (!env?.params) {
409
752
  throw new Error(`Missing Qwik Router Env Data for help visit https://github.com/QwikDev/qwik/issues/6237`);
@@ -425,27 +768,20 @@ const useQwikRouter = (props) => {
425
768
  deep: false
426
769
  });
427
770
  const navResolver = {};
428
- const container = _getContextContainer();
429
- const getSerializationStrategy = (loaderId) => {
430
- return env.response.loadersSerializationStrategy.get(loaderId) || DEFAULT_LOADERS_SERIALIZATION_STRATEGY;
431
- };
432
- const loadersObject = {};
771
+ const routeLoaderCtx = useStore(env.routeLoaderCtx);
772
+ routeLoaderCtx.manifestHash = manifestHash;
433
773
  const loaderState = {};
434
- for (const [key, value] of Object.entries(env.response.loaders)) {
435
- loadersObject[key] = value;
436
- loaderState[key] = createLoaderSignal(loadersObject, key, url, getSerializationStrategy(key), container);
437
- }
438
- loadersObject[SerializerSymbol] = (obj) => {
439
- const loadersSerializationObject = {};
440
- for (const [k, v] of Object.entries(obj)) {
441
- loadersSerializationObject[k] = getSerializationStrategy(k) === "always" ? v : _UNINITIALIZED;
774
+ const contentModulesForInit = env.loadedRoute.$mods$;
775
+ const loaders = ensureRouteLoaderSignals(contentModulesForInit, loaderState, routeLoaderCtx);
776
+ for (const loader of loaders) {
777
+ if (loader.__id in env.loaderValues) {
778
+ const value = env.loaderValues[loader.__id];
779
+ setLoaderSignalValue(loaderState[loader.__id], value);
442
780
  }
443
- return loadersSerializationObject;
444
- };
781
+ }
445
782
  const routeInternal = useSignal({
446
783
  type: "initial",
447
- dest: url,
448
- scroll: true
784
+ dest: url
449
785
  });
450
786
  const documentHead = useStore(() => createDocumentHead(serverHead, manifestHash));
451
787
  const content = useStore({
@@ -453,12 +789,13 @@ const useQwikRouter = (props) => {
453
789
  menu: void 0
454
790
  });
455
791
  const contentInternal = useSignal();
792
+ const navContext = useSignal();
456
793
  const httpStatus = useSignal({
457
794
  status: env.response.status,
458
795
  message: env.loadedRoute.$notFound$ ? "Not Found" : env.response.statusMessage ?? ""
459
796
  });
460
797
  const currentActionId = env.response.action;
461
- const currentAction = currentActionId ? env.response.loaders[currentActionId] : void 0;
798
+ const currentAction = currentActionId ? env.response.actionResult : void 0;
462
799
  const actionState = useSignal(currentAction ? {
463
800
  id: currentActionId,
464
801
  data: env.response.formData,
@@ -467,6 +804,11 @@ const useQwikRouter = (props) => {
467
804
  status: env.response.status
468
805
  }
469
806
  } : void 0);
807
+ const actionDataSignal = useSignal(currentActionId ? {
808
+ action: currentActionId,
809
+ actionResult: currentAction,
810
+ status: env.response.status
811
+ } : void 0);
470
812
  const registerPreventNav = /* @__PURE__ */ inlinedQrl((fn$) => {
471
813
  if (!isBrowser) {
472
814
  return;
@@ -497,22 +839,11 @@ const useQwikRouter = (props) => {
497
839
  }
498
840
  };
499
841
  }, "useQwikRouter_registerPreventNav_69B0DK0eZJc");
500
- const getScroller = /* @__PURE__ */ inlinedQrl(() => {
501
- let scroller = document.getElementById(QWIK_ROUTER_SCROLLER);
502
- if (!scroller) {
503
- scroller = document.getElementById(QWIK_CITY_SCROLLER);
504
- if (scroller && isDev) {
505
- console.warn(`Please update your scroller ID to "${QWIK_ROUTER_SCROLLER}" as "${QWIK_CITY_SCROLLER}" is deprecated and will be removed in V3`);
506
- }
507
- }
508
- return scroller ?? document.documentElement;
509
- }, "useQwikRouter_getScroller_0UhDFwlxeFQ");
510
842
  const goto = /* @__PURE__ */ inlinedQrl(async (path, opt) => {
511
- const actionState2 = _captures[0], getScroller2 = _captures[1], navResolver2 = _captures[2], routeInternal2 = _captures[3], routeLocation2 = _captures[4];
843
+ const actionState2 = _captures[0], manifestHash2 = _captures[1], navResolver2 = _captures[2], routeInternal2 = _captures[3], routeLocation2 = _captures[4];
512
844
  const { type = "link", forceReload = path === void 0, replaceState = false, scroll = true } = typeof opt === "object" ? opt : {
513
845
  forceReload: opt
514
846
  };
515
- internalState.navCount++;
516
847
  if (isBrowser && type === "link" && routeInternal2.value.type === "initial") {
517
848
  const url2 = new URL(window.location.href);
518
849
  routeInternal2.value.dest = url2;
@@ -520,13 +851,17 @@ const useQwikRouter = (props) => {
520
851
  }
521
852
  const lastDest = routeInternal2.value.dest;
522
853
  const dest = path === void 0 ? lastDest : typeof path === "number" ? path : toUrl(path, routeLocation2.url);
854
+ if (navResolver2.p && !forceReload && typeof dest !== "number" && isSamePath(dest, lastDest) && dest.href === lastDest.href) {
855
+ return navResolver2.p;
856
+ }
857
+ const navCount = ++internalState.navCount;
858
+ internalState.currentTransition?.skipTransition();
523
859
  if (preventNav.$cbs$ && (forceReload || typeof dest === "number" || !isSamePath(dest, lastDest) || !isSameOrigin(dest, lastDest))) {
524
- const ourNavId = internalState.navCount;
525
860
  const prevents = await Promise.all([
526
861
  ...preventNav.$cbs$.values()
527
862
  ].map((cb) => cb(dest)));
528
- if (ourNavId !== internalState.navCount || prevents.some(Boolean)) {
529
- if (ourNavId === internalState.navCount && type === "popstate") {
863
+ if (navCount !== internalState.navCount || prevents.some(Boolean)) {
864
+ if (navCount === internalState.navCount && type === "popstate") {
530
865
  history.pushState(null, "", lastDest);
531
866
  }
532
867
  return;
@@ -549,7 +884,7 @@ const useQwikRouter = (props) => {
549
884
  if (type === "link" && dest.href !== location.href) {
550
885
  history.pushState(null, "", dest);
551
886
  }
552
- const scroller = await getScroller2();
887
+ const scroller = getScroller();
553
888
  restoreScroll(type, dest, new URL(location.href), scroller, getScrollHistory());
554
889
  if (type === "popstate") {
555
890
  window._qRouterScrollEnabled = true;
@@ -564,7 +899,7 @@ const useQwikRouter = (props) => {
564
899
  }
565
900
  let historyUpdated = false;
566
901
  if (isBrowser && type === "link" && !forceReload) {
567
- const scroller = await getScroller2();
902
+ const scroller = getScroller();
568
903
  window._qRouterScrollEnabled = false;
569
904
  clearTimeout(window._qRouterScrollDebounce);
570
905
  const scrollState = currentScrollState(scroller);
@@ -572,6 +907,15 @@ const useQwikRouter = (props) => {
572
907
  clientNavigate(window, type, new URL(location.href), dest, replaceState);
573
908
  historyUpdated = true;
574
909
  }
910
+ routeLocation2.isNavigating = true;
911
+ const container = isBrowser ? _getContextContainer() : void 0;
912
+ if (container) {
913
+ await _waitUntilRendered(container);
914
+ if (navCount !== internalState.navCount) {
915
+ return;
916
+ }
917
+ }
918
+ actionState2.value = void 0;
575
919
  routeInternal2.value = {
576
920
  type,
577
921
  dest,
@@ -581,17 +925,19 @@ const useQwikRouter = (props) => {
581
925
  historyUpdated
582
926
  };
583
927
  if (isBrowser) {
584
- loadClientData(dest);
585
- loadRoute(qwikRouterConfig.routes, qwikRouterConfig.cacheModules, dest.pathname);
928
+ prefetchRoute(dest, true, 0.8, manifestHash2);
586
929
  }
587
- actionState2.value = void 0;
588
- routeLocation2.isNavigating = true;
589
- return new Promise((resolve) => {
590
- navResolver2.r = resolve;
930
+ navResolver2.p = new Promise((resolve) => {
931
+ navResolver2.r = () => {
932
+ navResolver2.r = void 0;
933
+ navResolver2.p = void 0;
934
+ resolve();
935
+ };
591
936
  });
937
+ return navResolver2.p;
592
938
  }, "useQwikRouter_goto_8j8Vrz2yUIM", [
593
939
  actionState,
594
- getScroller,
940
+ manifestHash,
595
941
  navResolver,
596
942
  routeInternal,
597
943
  routeLocation
@@ -603,25 +949,29 @@ const useQwikRouter = (props) => {
603
949
  useContextProvider(RouteLocationContext, routeLocation);
604
950
  useContextProvider(RouteNavigateContext, goto);
605
951
  useContextProvider(RouteStateContext, loaderState);
952
+ useContextProvider(RouteLoaderCtxContext, routeLoaderCtx);
606
953
  useContextProvider(RouteActionContext, actionState);
607
954
  useContextProvider(RoutePreventNavigateContext, registerPreventNav);
608
955
  useTaskQrl(
609
956
  /* @__PURE__ */ inlinedQrl(async ({ track }) => {
610
- const actionState2 = _captures[0], content2 = _captures[1], contentInternal2 = _captures[2], documentHead2 = _captures[3], env2 = _captures[4], getScroller2 = _captures[5], goto2 = _captures[6], httpStatus2 = _captures[7], loaderState2 = _captures[8], loadersObject2 = _captures[9], navResolver2 = _captures[10], props2 = _captures[11], routeInternal2 = _captures[12], routeLocation2 = _captures[13], routeLocationTarget2 = _captures[14], serverHead2 = _captures[15];
611
- const container2 = _getContextContainer();
957
+ const actionDataSignal2 = _captures[0], actionState2 = _captures[1], content2 = _captures[2], contentInternal2 = _captures[3], env2 = _captures[4], goto2 = _captures[5], httpStatus2 = _captures[6], loaderState2 = _captures[7], navContext2 = _captures[8], routeInternal2 = _captures[9], routeLoaderCtx2 = _captures[10], routeLocation2 = _captures[11], routeLocationTarget2 = _captures[12];
612
958
  const navigation = track(routeInternal2);
613
959
  const action = track(actionState2);
614
- const locale = getLocale("");
615
960
  const prevUrl = routeLocation2.url;
616
961
  const navType = action ? "form" : navigation.type;
617
962
  const replaceState = navigation.replaceState;
963
+ const navCountBefore = internalState.navCount;
618
964
  let trackUrl;
619
- let clientPageData;
965
+ let endpointResponse;
966
+ let actionData;
967
+ let actionLoaderHashes;
968
+ let shouldInvalidateActionLoaders = false;
620
969
  let loadedRoute;
621
970
  if (isServer) {
622
971
  trackUrl = new URL(navigation.dest, routeLocation2.url);
623
972
  loadedRoute = env2.loadedRoute;
624
- clientPageData = env2.response;
973
+ endpointResponse = env2.response;
974
+ actionData = endpointResponse;
625
975
  } else {
626
976
  trackUrl = new URL(navigation.dest, location);
627
977
  if (trackUrl.pathname.endsWith("/")) {
@@ -629,52 +979,96 @@ const useQwikRouter = (props) => {
629
979
  trackUrl.pathname = trackUrl.pathname.slice(0, -1);
630
980
  }
631
981
  } else if (!globalThis.__NO_TRAILING_SLASH__) {
632
- trackUrl.pathname += "/";
633
- }
634
- let loadRoutePromise = loadRoute(qwikRouterConfig.routes, qwikRouterConfig.cacheModules, trackUrl.pathname);
635
- const pageData = clientPageData = await loadClientData(trackUrl, {
636
- action,
637
- clearCache: true
638
- });
639
- if (!pageData) {
640
- routeInternal2.untrackedValue = {
641
- type: navType,
642
- dest: trackUrl
643
- };
644
- return;
645
- }
646
- const newHref = pageData.href;
647
- const newURL = new URL(newHref, trackUrl);
648
- if (!isSamePath(newURL, trackUrl)) {
649
- if (!pageData.isRewrite) {
650
- trackUrl = newURL;
651
- }
652
- loadRoutePromise = loadRoute(
653
- qwikRouterConfig.routes,
654
- qwikRouterConfig.cacheModules,
655
- newURL.pathname
656
- // Load the actual required path.
657
- );
982
+ trackUrl.pathname = ensureSlash(trackUrl.pathname);
658
983
  }
984
+ const loadRoutePromise = loadRoute(qwikRouterConfig.routes, qwikRouterConfig.cacheModules, trackUrl.pathname);
659
985
  try {
660
986
  loadedRoute = await loadRoutePromise;
661
987
  } catch (e) {
662
- console.error(e);
663
- window.location.href = newHref;
988
+ console.error(`Could not load route ${trackUrl.pathname}, reloading:`, e);
989
+ window.location.href = trackUrl.href;
990
+ return;
991
+ }
992
+ if (internalState.navCount !== navCountBefore) {
664
993
  return;
665
994
  }
995
+ if (action) {
996
+ const result = await submitAction(action, trackUrl.pathname);
997
+ if (!result) {
998
+ routeInternal2.untrackedValue = {
999
+ type: navType,
1000
+ dest: trackUrl
1001
+ };
1002
+ return;
1003
+ }
1004
+ if (action.resolve) {
1005
+ action.resolve({
1006
+ status: result.status,
1007
+ result: result.result
1008
+ });
1009
+ action.resolve = void 0;
1010
+ }
1011
+ if (result.redirect) {
1012
+ goto2(result.redirect, {
1013
+ replaceState: true
1014
+ });
1015
+ return;
1016
+ }
1017
+ actionData = {
1018
+ status: result.status,
1019
+ action: action.id,
1020
+ actionResult: result.result
1021
+ };
1022
+ actionLoaderHashes = result.loaderHashes;
1023
+ shouldInvalidateActionLoaders = true;
1024
+ }
666
1025
  }
667
1026
  const { $routeName$, $params$, $mods$, $menu$, $notFound$ } = loadedRoute;
668
1027
  const contentModules = $mods$;
1028
+ if (!isServer) {
1029
+ routeLoaderCtx2.goto = noSerialize(goto2);
1030
+ }
1031
+ updateRouteLoaderPaths(routeLoaderCtx2, loadedRoute.$loaderPaths$, trackUrl);
1032
+ const routeLoaders = ensureRouteLoaderSignals(contentModules, loaderState2, routeLoaderCtx2);
1033
+ if (shouldInvalidateActionLoaders) {
1034
+ if (actionLoaderHashes !== void 0) {
1035
+ for (const hash of actionLoaderHashes) {
1036
+ loaderState2[hash]?.invalidate(true);
1037
+ }
1038
+ } else {
1039
+ for (const loader of routeLoaders) {
1040
+ loaderState2[loader.__id].invalidate(true);
1041
+ }
1042
+ }
1043
+ }
1044
+ if (routeLoaders.length > 0) {
1045
+ for (let i = 0; i < routeLoaders.length; i++) {
1046
+ const loader = routeLoaders[i];
1047
+ loaderState2[loader.__id].untrackedPending;
1048
+ }
1049
+ }
1050
+ if (internalState.navCount !== navCountBefore) {
1051
+ return;
1052
+ }
669
1053
  if ($notFound$) {
670
1054
  httpStatus2.value = {
671
1055
  status: 404,
672
1056
  message: "Not Found"
673
1057
  };
1058
+ } else if (endpointResponse) {
1059
+ httpStatus2.value = {
1060
+ status: endpointResponse.status,
1061
+ message: endpointResponse.statusMessage ?? "OK"
1062
+ };
1063
+ } else if (actionData) {
1064
+ httpStatus2.value = {
1065
+ status: actionData.status,
1066
+ message: "OK"
1067
+ };
674
1068
  } else {
675
1069
  httpStatus2.value = {
676
- status: clientPageData?.status ?? 200,
677
- message: clientPageData?.statusMessage ?? ""
1070
+ status: 200,
1071
+ message: "OK"
678
1072
  };
679
1073
  }
680
1074
  const pageModule = contentModules[contentModules.length - 1];
@@ -702,310 +1096,199 @@ const useQwikRouter = (props) => {
702
1096
  }
703
1097
  routeLocationTarget2.params = $params$;
704
1098
  }
705
- routeInternal2.untrackedValue = {
1099
+ const nextRouteInternal = {
706
1100
  type: navType,
707
1101
  dest: trackUrl
708
1102
  };
709
- const resolvedHead = resolveHead(clientPageData, routeLocation2, contentModules, locale, serverHead2);
1103
+ if (navigation.forceReload !== void 0) {
1104
+ nextRouteInternal.forceReload = navigation.forceReload;
1105
+ }
1106
+ if (navigation.replaceState !== void 0) {
1107
+ nextRouteInternal.replaceState = navigation.replaceState;
1108
+ }
1109
+ if (navigation.scroll !== void 0) {
1110
+ nextRouteInternal.scroll = navigation.scroll;
1111
+ }
1112
+ if (navigation.historyUpdated !== void 0) {
1113
+ nextRouteInternal.historyUpdated = navigation.historyUpdated;
1114
+ }
1115
+ routeInternal2.untrackedValue = nextRouteInternal;
710
1116
  content2.headings = pageModule.headings;
711
1117
  content2.menu = $menu$;
712
1118
  contentInternal2.untrackedValue = noSerialize(contentModules);
713
- documentHead2.links = resolvedHead.links;
714
- documentHead2.meta = resolvedHead.meta;
715
- documentHead2.styles = resolvedHead.styles;
716
- documentHead2.scripts = resolvedHead.scripts;
717
- documentHead2.title = resolvedHead.title;
718
- documentHead2.frontmatter = resolvedHead.frontmatter;
719
- if (isBrowser) {
720
- let scrollState;
721
- if (navType === "popstate") {
722
- scrollState = getScrollHistory();
723
- }
724
- const scroller = await getScroller2();
725
- if (navigation.scroll && (!navigation.forceReload || !isSamePath(trackUrl, prevUrl)) && (navType === "link" || navType === "popstate") || navType === "form" && !isSamePath(trackUrl, prevUrl)) {
726
- document.__q_scroll_restore__ = () => restoreScroll(navType, trackUrl, prevUrl, scroller, scrollState);
727
- }
728
- const loaders = clientPageData?.loaders;
729
- if (loaders) {
730
- for (const [key, value] of Object.entries(loaders)) {
731
- const signal = loaderState2[key];
732
- const awaitedValue = await value;
733
- loadersObject2[key] = awaitedValue;
734
- if (!signal) {
735
- loaderState2[key] = createLoaderSignal(loadersObject2, key, trackUrl, DEFAULT_LOADERS_SERIALIZATION_STRATEGY, container2);
736
- } else {
737
- signal.invalidate();
738
- }
739
- }
740
- }
741
- CLIENT_DATA_CACHE.clear();
742
- if (!window._qRouterSPA) {
743
- window._qRouterSPA = true;
744
- history.scrollRestoration = "manual";
745
- window.addEventListener("popstate", () => {
746
- window._qRouterScrollEnabled = false;
747
- clearTimeout(window._qRouterScrollDebounce);
748
- goto2(location.href, {
749
- type: "popstate"
750
- });
751
- });
752
- window.removeEventListener("popstate", window._qRouterInitPopstate);
753
- window._qRouterInitPopstate = void 0;
754
- if (!window._qRouterHistoryPatch) {
755
- window._qRouterHistoryPatch = true;
756
- const pushState = history.pushState;
757
- const replaceState2 = history.replaceState;
758
- const prepareState = (state) => {
759
- if (state === null || typeof state === "undefined") {
760
- state = {};
761
- } else if (state?.constructor !== Object) {
762
- state = {
763
- _data: state
764
- };
765
- if (isDev) {
766
- console.warn("In a Qwik SPA context, `history.state` is used to store scroll state. Direct calls to `pushState()` and `replaceState()` must supply an actual Object type. We need to be able to automatically attach the scroll state to your state object. A new state object has been created, your data has been moved to: `history.state._data`");
767
- }
768
- }
769
- state._qRouterScroll = state._qRouterScroll || currentScrollState(scroller);
770
- return state;
771
- };
772
- history.pushState = (state, title, url2) => {
773
- state = prepareState(state);
774
- return pushState.call(history, state, title, url2);
775
- };
776
- history.replaceState = (state, title, url2) => {
777
- state = prepareState(state);
778
- return replaceState2.call(history, state, title, url2);
779
- };
780
- }
781
- document.addEventListener("click", (event) => {
782
- if (event.defaultPrevented) {
783
- return;
784
- }
785
- const target = event.target.closest("a[href]");
786
- if (target && !target.hasAttribute("preventdefault:click")) {
787
- const href = target.getAttribute("href");
788
- const prev = new URL(location.href);
789
- const dest = new URL(href, prev);
790
- if (isSameOrigin(dest, prev) && isSamePath(dest, prev)) {
791
- event.preventDefault();
792
- if (!dest.hash && !dest.href.endsWith("#")) {
793
- if (dest.href !== prev.href) {
794
- history.pushState(null, "", dest);
795
- }
796
- window._qRouterScrollEnabled = false;
797
- clearTimeout(window._qRouterScrollDebounce);
798
- saveScrollHistory({
799
- ...currentScrollState(scroller),
800
- x: 0,
801
- y: 0
802
- });
803
- location.reload();
804
- return;
805
- }
806
- goto2(target.getAttribute("href"));
807
- }
808
- }
809
- });
810
- document.removeEventListener("click", window._qRouterInitAnchors);
811
- window._qRouterInitAnchors = void 0;
812
- if (!window.navigation) {
813
- document.addEventListener("visibilitychange", () => {
814
- if ((window._qRouterScrollEnabled || window._qCityScrollEnabled) && document.visibilityState === "hidden") {
815
- if (window._qCityScrollEnabled) {
816
- console.warn('"_qCityScrollEnabled" is deprecated. Use "_qRouterScrollEnabled" instead.');
817
- }
818
- const scrollState2 = currentScrollState(scroller);
819
- saveScrollHistory(scrollState2);
820
- }
821
- }, {
822
- passive: true
823
- });
824
- document.removeEventListener("visibilitychange", window._qRouterInitVisibility);
825
- window._qRouterInitVisibility = void 0;
826
- }
827
- window.addEventListener("scroll", () => {
828
- if (!window._qRouterScrollEnabled && !window._qCityScrollEnabled) {
829
- return;
830
- }
831
- clearTimeout(window._qRouterScrollDebounce);
832
- window._qRouterScrollDebounce = setTimeout(() => {
833
- const scrollState2 = currentScrollState(scroller);
834
- saveScrollHistory(scrollState2);
835
- window._qRouterScrollDebounce = void 0;
836
- }, 200);
837
- }, {
838
- passive: true
839
- });
840
- removeEventListener("scroll", window._qRouterInitScroll);
841
- window._qRouterInitScroll = void 0;
842
- spaInit.resolve();
843
- }
844
- if (navType !== "popstate") {
845
- window._qRouterScrollEnabled = false;
846
- clearTimeout(window._qRouterScrollDebounce);
847
- if (!navigation.historyUpdated) {
848
- const scrollState2 = currentScrollState(scroller);
849
- saveScrollHistory(scrollState2);
850
- }
851
- }
852
- const navigate = () => {
853
- if (navigation.historyUpdated) {
854
- const currentPath = location.pathname + location.search + location.hash;
855
- const nextPath = toPath(trackUrl);
856
- if (currentPath !== nextPath) {
857
- history.replaceState(history.state, "", nextPath);
858
- }
859
- } else {
860
- clientNavigate(window, navType, prevUrl, trackUrl, replaceState);
861
- }
862
- contentInternal2.trigger();
863
- return _waitUntilRendered(container2);
864
- };
865
- const _waitNextPage = () => {
866
- if (isServer || props2?.viewTransition === false) {
867
- return navigate();
868
- } else {
869
- const viewTransition = startViewTransition({
870
- update: navigate,
871
- types: [
872
- "qwik-navigation"
873
- ]
874
- });
875
- if (!viewTransition) {
876
- return Promise.resolve();
877
- }
878
- return viewTransition.ready;
879
- }
880
- };
881
- _waitNextPage().catch((err) => {
882
- navigate();
883
- if (err instanceof DOMException && err.name === "TimeoutError") {
884
- throw new Error('View transition timed out. This can happen if you have "disableCache" in your browser devtools enabled.');
885
- }
886
- throw err;
887
- }).finally(() => {
888
- container2.element.setAttribute?.(Q_ROUTE, $routeName$);
889
- const scrollState2 = currentScrollState(scroller);
890
- saveScrollHistory(scrollState2);
891
- window._qRouterScrollEnabled = true;
892
- if (isBrowser) {
893
- callRestoreScrollOnDocument();
894
- }
895
- if (shouldForcePrevUrl) {
896
- forceStoreEffects(routeLocation2, "prevUrl");
897
- }
898
- if (shouldForceUrl) {
899
- forceStoreEffects(routeLocation2, "url");
900
- }
901
- if (shouldForceParams) {
902
- forceStoreEffects(routeLocation2, "params");
903
- }
904
- routeLocation2.isNavigating = false;
905
- navResolver2.r?.();
906
- });
907
- }
1119
+ actionDataSignal2.value = actionData;
1120
+ navContext2.value = noSerialize({
1121
+ routeName: $routeName$,
1122
+ navType,
1123
+ prevUrl,
1124
+ replaceState,
1125
+ shouldForcePrevUrl,
1126
+ shouldForceUrl,
1127
+ shouldForceParams,
1128
+ navCount: navCountBefore
1129
+ });
908
1130
  }, "useQwikRouter_useTask_XpalYii770E", [
1131
+ actionDataSignal,
909
1132
  actionState,
910
1133
  content,
911
1134
  contentInternal,
912
- documentHead,
913
1135
  env,
914
- getScroller,
915
1136
  goto,
916
1137
  httpStatus,
917
1138
  loaderState,
918
- loadersObject,
919
- navResolver,
920
- props,
1139
+ navContext,
921
1140
  routeInternal,
1141
+ routeLoaderCtx,
922
1142
  routeLocation,
923
- routeLocationTarget,
924
- serverHead
1143
+ routeLocationTarget
925
1144
  ]),
926
- // We should only wait for navigation to complete on the server
1145
+ // We should only wait for head calculation to complete on the server
927
1146
  {
928
1147
  deferUpdates: isServer
929
1148
  }
930
1149
  );
931
- };
932
- const QwikRouterProvider = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) => {
933
- useQwikRouter(props);
934
- return /* @__PURE__ */ _jsxSorted(Slot, null, null, null, 3, "5y_0");
935
- }, "QwikRouterProvider_component_6Kjfa79mqlY"));
936
- const QwikCityProvider = QwikRouterProvider;
937
- const useQwikMockRouter = (props) => {
938
- const urlEnv = props.url ?? "http://localhost/";
939
- const url = new URL(urlEnv);
940
- const routeLocation = useStore({
941
- url,
942
- params: props.params ?? {},
943
- isNavigating: false,
944
- prevUrl: void 0
945
- }, {
946
- deep: false
947
- });
948
- const container = _getContextContainer();
949
- const loadersObject = {};
950
- const loadersState = {};
951
- if (props.loaders) {
952
- for (const { loader, data } of props.loaders) {
953
- const id = loader.__id;
954
- loadersObject[id] = data;
955
- loadersState[id] = createLoaderSignal(loadersObject, id, url, DEFAULT_LOADERS_SERIALIZATION_STRATEGY, container);
1150
+ useTaskQrl(/* @__PURE__ */ inlinedQrl(({ track }) => {
1151
+ const actionDataSignal2 = _captures[0], contentInternal2 = _captures[1], documentHead2 = _captures[2], loaderState2 = _captures[3], routeLocation2 = _captures[4], serverHead2 = _captures[5];
1152
+ const contentModules = track(contentInternal2);
1153
+ if (!contentModules) {
1154
+ return;
956
1155
  }
957
- }
958
- const goto = props.goto ?? /* @__PURE__ */ inlinedQrl(async () => {
959
- console.warn("QwikRouterMockProvider: goto not provided");
960
- }, "useQwikMockRouter_goto_aViHFxQ1a3s");
961
- const documentHead = useStore(createDocumentHead, {
962
- deep: false
963
- });
964
- const content = useStore({
965
- headings: void 0,
966
- menu: void 0
967
- }, {
968
- deep: false
1156
+ const actionData = track(actionDataSignal2);
1157
+ const head = track(() => resolveHead(actionData, loaderState2, routeLocation2, contentModules, getLocale(""), serverHead2));
1158
+ documentHead2.links = head.links;
1159
+ documentHead2.meta = head.meta;
1160
+ documentHead2.styles = head.styles;
1161
+ documentHead2.scripts = head.scripts;
1162
+ documentHead2.title = head.title;
1163
+ documentHead2.frontmatter = head.frontmatter;
1164
+ }, "useQwikRouter_useTask_1_1sKEZ9Pg1ow", [
1165
+ actionDataSignal,
1166
+ contentInternal,
1167
+ documentHead,
1168
+ loaderState,
1169
+ routeLocation,
1170
+ serverHead
1171
+ ]), {
1172
+ deferUpdates: isServer
969
1173
  });
970
- const contentInternal = useSignal();
971
- const actionState = useSignal();
972
- const httpStatus = useSignal({
973
- status: 200,
974
- message: ""
975
- });
976
- useContextProvider(ContentContext, content);
977
- useContextProvider(ContentInternalContext, contentInternal);
978
- useContextProvider(DocumentHeadContext, documentHead);
979
- useContextProvider(HttpStatusContext, httpStatus);
980
- useContextProvider(RouteLocationContext, routeLocation);
981
- useContextProvider(RouteNavigateContext, goto);
982
- useContextProvider(RouteStateContext, loadersState);
983
- useContextProvider(RouteActionContext, actionState);
984
- const actionsMocks = props.actions?.reduce((acc, { action, handler }) => {
985
- acc[action.__id] = handler;
986
- return acc;
987
- }, {});
988
- useTaskQrl(/* @__PURE__ */ inlinedQrl(async ({ track }) => {
989
- const actionState2 = _captures[0], actionsMocks2 = _captures[1];
990
- const action = track(actionState2);
991
- if (!action?.resolve) {
1174
+ useTaskQrl(/* @__PURE__ */ inlinedQrl(({ track }) => {
1175
+ const contentInternal2 = _captures[0], goto2 = _captures[1], manifestHash2 = _captures[2], navContext2 = _captures[3], navResolver2 = _captures[4], props2 = _captures[5], routeInternal2 = _captures[6], routeLocation2 = _captures[7];
1176
+ const nav = track(navContext2);
1177
+ if (isServer || !nav) {
992
1178
  return;
993
1179
  }
994
- const mock = actionsMocks2?.[action.id];
995
- if (mock) {
996
- const actionResult = await mock(action.data);
997
- action.resolve(actionResult);
1180
+ if (nav.navCount !== internalState.navCount) {
1181
+ return;
998
1182
  }
999
- }, "useQwikMockRouter_useTask_tXTLR4tzCy0", [
1000
- actionState,
1001
- actionsMocks
1002
- ]));
1183
+ const container = _getContextContainer();
1184
+ const navigation = routeInternal2.untrackedValue;
1185
+ const { navType, prevUrl, replaceState, routeName } = nav;
1186
+ const trackUrl = routeLocation2.url;
1187
+ const scroller = getScroller();
1188
+ let scrollState;
1189
+ if (navType === "popstate") {
1190
+ scrollState = getScrollHistory();
1191
+ }
1192
+ if (navigation.scroll && (!navigation.forceReload || !isSamePath(trackUrl, prevUrl)) && (navType === "link" || navType === "popstate") || navType === "form" && !isSamePath(trackUrl, prevUrl)) {
1193
+ document.__q_scroll_restore__ = () => restoreScroll(navType, trackUrl, prevUrl, scroller, scrollState);
1194
+ }
1195
+ initializeSPA(goto2, scroller);
1196
+ if (navType !== "popstate") {
1197
+ window._qRouterScrollEnabled = false;
1198
+ clearTimeout(window._qRouterScrollDebounce);
1199
+ if (!navigation.historyUpdated) {
1200
+ const scrollState2 = currentScrollState(scroller);
1201
+ saveScrollHistory(scrollState2);
1202
+ }
1203
+ }
1204
+ let didNavigate = false;
1205
+ let navigatePromise;
1206
+ let currentTransition;
1207
+ const navigate = () => {
1208
+ if (navigatePromise) {
1209
+ return navigatePromise;
1210
+ }
1211
+ if (nav.navCount !== internalState.navCount) {
1212
+ return Promise.resolve();
1213
+ }
1214
+ didNavigate = true;
1215
+ if (navigation.historyUpdated) {
1216
+ const currentPath = location.pathname + location.search + location.hash;
1217
+ const nextPath = toPath(trackUrl);
1218
+ if (currentPath !== nextPath) {
1219
+ history.replaceState(history.state, "", nextPath);
1220
+ }
1221
+ } else {
1222
+ clientNavigate(window, navType, prevUrl, trackUrl, replaceState);
1223
+ }
1224
+ contentInternal2.trigger();
1225
+ return navigatePromise = _waitUntilRendered(container);
1226
+ };
1227
+ const _waitNextPage = () => {
1228
+ if (!shouldStartViewTransition(props2?.viewTransition)) {
1229
+ return navigate().then(() => void 0);
1230
+ }
1231
+ const { ready, transition } = startViewTransition({
1232
+ update: navigate,
1233
+ types: [
1234
+ "qwik-navigation"
1235
+ ]
1236
+ });
1237
+ currentTransition = transition;
1238
+ internalState.currentTransition = transition;
1239
+ return ready.then(() => transition, (reason) => {
1240
+ if (!didNavigate && nav.navCount === internalState.navCount) {
1241
+ return navigate().then(() => transition);
1242
+ }
1243
+ if (reason?.name === "AbortError") {
1244
+ return transition;
1245
+ }
1246
+ throw reason;
1247
+ });
1248
+ };
1249
+ _waitNextPage().finally(() => {
1250
+ if (currentTransition && internalState.currentTransition === currentTransition) {
1251
+ internalState.currentTransition = void 0;
1252
+ }
1253
+ if (nav.navCount !== internalState.navCount) {
1254
+ return;
1255
+ }
1256
+ container.element.setAttribute?.(Q_ROUTE, routeName);
1257
+ const scrollState2 = currentScrollState(scroller);
1258
+ saveScrollHistory(scrollState2);
1259
+ window._qRouterScrollEnabled = true;
1260
+ callRestoreScrollOnDocument();
1261
+ refreshLinkPrefetchObserver(manifestHash2);
1262
+ if (nav.shouldForcePrevUrl) {
1263
+ forceStoreEffects(routeLocation2, "prevUrl");
1264
+ }
1265
+ if (nav.shouldForceUrl) {
1266
+ forceStoreEffects(routeLocation2, "url");
1267
+ }
1268
+ if (nav.shouldForceParams) {
1269
+ forceStoreEffects(routeLocation2, "params");
1270
+ }
1271
+ routeLocation2.isNavigating = false;
1272
+ navResolver2.r?.();
1273
+ });
1274
+ }, "useQwikRouter_useTask_2_yw17chooOac", [
1275
+ contentInternal,
1276
+ goto,
1277
+ manifestHash,
1278
+ navContext,
1279
+ navResolver,
1280
+ props,
1281
+ routeInternal,
1282
+ routeLocation
1283
+ ]), {
1284
+ deferUpdates: false
1285
+ });
1003
1286
  };
1004
- const QwikRouterMockProvider = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) => {
1005
- useQwikMockRouter(props);
1006
- return /* @__PURE__ */ _jsxSorted(Slot, null, null, null, 3, "5y_1");
1007
- }, "QwikRouterMockProvider_component_IN4dVpT0x74"));
1008
- const QwikCityMockProvider = QwikRouterMockProvider;
1287
+ const QwikRouterProvider = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) => {
1288
+ useQwikRouter(props);
1289
+ return /* @__PURE__ */ _jsxSorted(Slot, null, null, null, 3, "5y_0");
1290
+ }, "QwikRouterProvider_component_6Kjfa79mqlY"));
1291
+ const QwikCityProvider = QwikRouterProvider;
1009
1292
 
1010
1293
  const handleRouterPopstate = (nav, event) => {
1011
1294
  const href = event.detail?.href;
@@ -1021,6 +1304,7 @@ const RouterOutlet = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl(()
1021
1304
  throw new Error("PrefetchServiceWorker component must be rendered on the server.");
1022
1305
  }
1023
1306
  const internalContext = useContext(ContentInternalContext);
1307
+ const head = useDocumentHead();
1024
1308
  const nav = useNavigate();
1025
1309
  const contents = internalContext.value;
1026
1310
  if (contents && contents.length > 0) {
@@ -1034,6 +1318,10 @@ const RouterOutlet = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl(()
1034
1318
  return /* @__PURE__ */ _jsxSorted(Fragment, null, null, [
1035
1319
  cmp,
1036
1320
  !__EXPERIMENTAL__.noSPA && /* @__PURE__ */ _jsxSorted("script", {
1321
+ "q-d:qcinit": [
1322
+ spaInit,
1323
+ linkPrefetchInit(head.manifestHash)
1324
+ ],
1037
1325
  "q-d:qinit": _qrlSync(() => {
1038
1326
  ((w, h) => {
1039
1327
  if (!w._qcs) {
@@ -1049,15 +1337,12 @@ const RouterOutlet = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl(()
1049
1337
  }, '()=>{((w,h)=>{if(!w._qcs){w._qcs=!0;const s=h.state?._qRouterScroll;if(s){h.scrollRestoration="manual";w.scrollTo(s.x,s.y);}document.dispatchEvent(new Event("qcinit"));}})(window,history);}'),
1050
1338
  "q-d:qrouterpopstate": /* @__PURE__ */ inlinedQrl((event, _1, nav2) => handleRouterPopstate(nav2, event), "RouterOutlet_component_Fragment_script_q_d_qrouterpopstate_aRL6GvFyews"),
1051
1339
  "q:p": nav
1052
- }, {
1053
- "q-d:qcinit": spaInit
1054
- }, null, 6, "Fn_1")
1340
+ }, null, null, 6, "Fn_1")
1055
1341
  ], 1, "Fn_2");
1056
1342
  }
1057
1343
  return SkipRender;
1058
1344
  }, "RouterOutlet_component_QwONcWD5gIg"));
1059
1345
 
1060
- const getValue = (obj) => obj.value;
1061
1346
  const validatorQrl = (validator) => {
1062
1347
  if (isServer) {
1063
1348
  return {
@@ -1182,7 +1467,7 @@ const zodQrl = (qrl) => {
1182
1467
  const zod$ = /* @__PURE__ */ implicit$FirstArg(zodQrl);
1183
1468
  const getValidators = (rest, qrl) => {
1184
1469
  let id;
1185
- let serializationStrategy = DEFAULT_LOADERS_SERIALIZATION_STRATEGY;
1470
+ let invalidate;
1186
1471
  const validators = [];
1187
1472
  if (rest.length === 1) {
1188
1473
  const options = rest[0];
@@ -1191,12 +1476,12 @@ const getValidators = (rest, qrl) => {
1191
1476
  validators.push(options);
1192
1477
  } else {
1193
1478
  id = options.id;
1194
- if (options.serializationStrategy) {
1195
- serializationStrategy = options.serializationStrategy;
1196
- }
1197
1479
  if (options.validation) {
1198
1480
  validators.push(...options.validation);
1199
1481
  }
1482
+ if (options.invalidate) {
1483
+ invalidate = options.invalidate.map((loader) => loader.__id);
1484
+ }
1200
1485
  }
1201
1486
  }
1202
1487
  } else if (rest.length > 1) {
@@ -1215,11 +1500,11 @@ const getValidators = (rest, qrl) => {
1215
1500
  return {
1216
1501
  validators: validators.reverse(),
1217
1502
  id,
1218
- serializationStrategy
1503
+ invalidate
1219
1504
  };
1220
1505
  };
1221
1506
  const routeActionQrl = (actionQrl, ...rest) => {
1222
- const { id, validators } = getValidators(rest, actionQrl);
1507
+ const { id, validators, invalidate } = getValidators(rest, actionQrl);
1223
1508
  function action() {
1224
1509
  const loc = useLocation();
1225
1510
  const currentAction = useAction();
@@ -1314,6 +1599,7 @@ Action.run() can only be called on the browser, for example when a user clicks a
1314
1599
  action.__validators = validators;
1315
1600
  action.__qrl = actionQrl;
1316
1601
  action.__id = id;
1602
+ action.__invalidate = invalidate;
1317
1603
  Object.freeze(action);
1318
1604
  return action;
1319
1605
  };
@@ -1329,32 +1615,6 @@ const globalActionQrl = (actionQrl, ...rest) => {
1329
1615
  };
1330
1616
  const routeAction$ = /* @__PURE__ */ implicit$FirstArg(routeActionQrl);
1331
1617
  const globalAction$ = /* @__PURE__ */ implicit$FirstArg(globalActionQrl);
1332
- const routeLoaderQrl = (loaderQrl, ...rest) => {
1333
- const { id, validators, serializationStrategy } = getValidators(rest, loaderQrl);
1334
- function loader() {
1335
- const state = _resolveContextWithoutSequentialScope(RouteStateContext);
1336
- if (!(id in state)) {
1337
- throw new Error(`routeLoader$ "${loaderQrl.getSymbol()}" was invoked in a route where it was not declared.
1338
- This is because the routeLoader$ was not exported in a 'layout.tsx' or 'index.tsx' file of the existing route.
1339
- For more information check: https://qwik.dev/docs/route-loader/
1340
-
1341
- If your are managing reusable logic or a library it is essential that this function is re-exported from within 'layout.tsx' or 'index.tsx file of the existing route otherwise it will not run or throw exception.
1342
- For more information check: https://qwik.dev/docs/re-exporting-loaders/`);
1343
- }
1344
- const loaderData = state[id];
1345
- untrack(getValue, loaderData);
1346
- return loaderData;
1347
- }
1348
- loader.__brand = "server_loader";
1349
- loader.__qrl = loaderQrl;
1350
- loader.__validators = validators;
1351
- loader.__id = id;
1352
- loader.__serializationStrategy = serializationStrategy;
1353
- loader.__expires = -1;
1354
- Object.freeze(loader);
1355
- return loader;
1356
- };
1357
- const routeLoader$ = /* @__PURE__ */ implicit$FirstArg(routeLoaderQrl);
1358
1618
  const deserializeStream = async function* (stream, abortSignal) {
1359
1619
  const reader = stream.getReader();
1360
1620
  try {
@@ -1371,7 +1631,7 @@ const deserializeStream = async function* (stream, abortSignal) {
1371
1631
  const lines = buffer.split(/\n/);
1372
1632
  buffer = lines.pop();
1373
1633
  for (const line of lines) {
1374
- const deserializedData = _deserialize(line);
1634
+ const deserializedData = await _deserialize(line);
1375
1635
  yield deserializedData;
1376
1636
  }
1377
1637
  }
@@ -1394,16 +1654,7 @@ const serverQrl = (qrl, options) => {
1394
1654
  const fetchOptions2 = _captures[0], headers2 = _captures[1], method2 = _captures[2], origin2 = _captures[3], qrl2 = _captures[4];
1395
1655
  const abortSignal = args.length > 0 && args[0] instanceof AbortSignal ? args.shift() : void 0;
1396
1656
  if (isServer) {
1397
- let requestEvent = _asyncRequestStore?.getStore();
1398
- if (!requestEvent) {
1399
- const contexts = [
1400
- useQwikRouterEnv()?.ev,
1401
- this,
1402
- _getContextEvent()
1403
- ];
1404
- requestEvent = contexts.find((v2) => v2 && Object.prototype.hasOwnProperty.call(v2, "sharedMap") && Object.prototype.hasOwnProperty.call(v2, "cookie"));
1405
- }
1406
- return qrl2.apply(requestEvent, args);
1657
+ return qrl2.apply(getRequestEvent(this), args);
1407
1658
  } else {
1408
1659
  let filteredArgs = args.map((arg) => {
1409
1660
  if (arg instanceof SubmitEvent && arg.target instanceof HTMLFormElement) {
@@ -1468,7 +1719,7 @@ const serverQrl = (qrl, options) => {
1468
1719
  })();
1469
1720
  } else if (contentType === "application/qwik-json") {
1470
1721
  const str = await res.text();
1471
- const obj = _deserialize(str);
1722
+ const obj = await _deserialize(str);
1472
1723
  if (res.status >= 400) {
1473
1724
  throw obj;
1474
1725
  }
@@ -1630,9 +1881,7 @@ const untypedAppUrl = function appUrl(route, params, paramsPrefix = "") {
1630
1881
  let url = path.join("/");
1631
1882
  let baseURL = "/";
1632
1883
  if (baseURL) {
1633
- if (!baseURL.endsWith("/")) {
1634
- baseURL += "/";
1635
- }
1884
+ baseURL = ensureSlash(baseURL);
1636
1885
  while (url.startsWith("/")) {
1637
1886
  url = url.substring(1);
1638
1887
  }
@@ -1700,4 +1949,4 @@ const DocumentHeadTags = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl
1700
1949
  ], 1, "r5_3");
1701
1950
  }, "DocumentHeadTags_component_9CrWYOoCpgY"));
1702
1951
 
1703
- export { DocumentHeadTags, ErrorBoundary, Form, Link, QWIK_CITY_SCROLLER, QWIK_ROUTER_SCROLLER, QwikCityMockProvider, QwikCityProvider, QwikRouterMockProvider, QwikRouterProvider, RouterOutlet, ServiceWorkerRegister, createRenderer, globalAction$, globalActionQrl, omitProps, routeAction$, routeActionQrl, routeLoader$, routeLoaderQrl, server$, serverQrl, untypedAppUrl, useDocumentHead, useLocation, useNavigate, useQwikRouter, valibot$, valibotQrl, validator$, validatorQrl, zod$, zodQrl };
1952
+ export { DocumentHeadTags, ErrorBoundary, Form, Link, QWIK_CITY_SCROLLER, QWIK_ROUTER_SCROLLER, QwikCityMockProvider, QwikCityProvider, QwikRouterMockProvider, QwikRouterProvider, RouterOutlet, ServiceWorkerRegister, createRenderer, getRequestEvent, globalAction$, globalActionQrl, omitProps, routeAction$, routeActionQrl, server$, serverQrl, untypedAppUrl, useDocumentHead, useLocation, useNavigate, useQwikRouter, valibot$, valibotQrl, validator$, validatorQrl, zod$, zodQrl };