@qwik.dev/router 2.0.0-beta.2 → 2.0.0-beta.21

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 (78) hide show
  1. package/adapters/static/vite.d.ts +1 -1
  2. package/lib/adapters/azure-swa/vite/index.d.ts +2 -2
  3. package/lib/adapters/azure-swa/vite/index.mjs +9 -9
  4. package/lib/adapters/bun-server/vite/index.d.ts +2 -2
  5. package/lib/adapters/bun-server/vite/index.mjs +9 -7
  6. package/lib/adapters/cloud-run/vite/index.d.ts +2 -2
  7. package/lib/adapters/cloud-run/vite/index.mjs +9 -7
  8. package/lib/adapters/cloudflare-pages/vite/index.d.ts +2 -2
  9. package/lib/adapters/cloudflare-pages/vite/index.mjs +9 -24
  10. package/lib/adapters/deno-server/vite/index.d.ts +2 -2
  11. package/lib/adapters/deno-server/vite/index.mjs +9 -7
  12. package/lib/adapters/netlify-edge/vite/index.d.ts +2 -2
  13. package/lib/adapters/netlify-edge/vite/index.mjs +10 -14
  14. package/lib/adapters/node-server/vite/index.d.ts +2 -2
  15. package/lib/adapters/node-server/vite/index.mjs +9 -7
  16. package/lib/adapters/shared/vite/index.d.ts +13 -19
  17. package/lib/adapters/shared/vite/index.mjs +107 -139
  18. package/lib/adapters/ssg/vite/index.d.ts +13 -0
  19. package/lib/adapters/ssg/vite/index.mjs +18 -0
  20. package/lib/adapters/vercel-edge/vite/index.d.ts +3 -3
  21. package/lib/adapters/vercel-edge/vite/index.mjs +9 -11
  22. package/lib/chunks/error-handler.mjs +57 -0
  23. package/lib/chunks/format-error.mjs +137 -0
  24. package/lib/chunks/fs.mjs +254 -0
  25. package/lib/{static/node.mjs → chunks/index.mjs} +361 -563
  26. package/lib/chunks/mime-types.mjs +52 -0
  27. package/lib/chunks/routing.qwik.mjs +429 -0
  28. package/lib/chunks/types.qwik.mjs +22 -0
  29. package/lib/index.d.ts +240 -60
  30. package/lib/index.qwik.mjs +698 -983
  31. package/lib/middleware/aws-lambda/index.d.ts +3 -2
  32. package/lib/middleware/aws-lambda/index.mjs +8 -12
  33. package/lib/middleware/azure-swa/index.mjs +10 -216
  34. package/lib/middleware/bun/index.d.ts +11 -0
  35. package/lib/middleware/bun/index.mjs +24 -83
  36. package/lib/middleware/cloudflare-pages/index.mjs +10 -22
  37. package/lib/middleware/deno/index.d.ts +11 -0
  38. package/lib/middleware/deno/index.mjs +24 -83
  39. package/lib/middleware/firebase/index.mjs +7 -11
  40. package/lib/middleware/netlify-edge/index.mjs +10 -23
  41. package/lib/middleware/node/index.mjs +22 -87
  42. package/lib/middleware/request-handler/index.d.ts +89 -70
  43. package/lib/middleware/request-handler/index.mjs +584 -659
  44. package/lib/middleware/vercel-edge/index.mjs +15 -27
  45. package/lib/modules.d.ts +4 -12
  46. package/lib/service-worker/index.mjs +4 -0
  47. package/lib/{static → ssg}/index.d.ts +17 -17
  48. package/lib/ssg/index.mjs +14 -0
  49. package/lib/vite/index.d.ts +32 -10
  50. package/lib/vite/index.mjs +1524 -26934
  51. package/modules.d.ts +4 -12
  52. package/package.json +62 -68
  53. package/ssg.d.ts +2 -0
  54. package/static.d.ts +1 -1
  55. package/lib/adapters/azure-swa/vite/index.cjs +0 -96
  56. package/lib/adapters/bun-server/vite/index.cjs +0 -50
  57. package/lib/adapters/cloud-run/vite/index.cjs +0 -47
  58. package/lib/adapters/cloudflare-pages/vite/index.cjs +0 -115
  59. package/lib/adapters/deno-server/vite/index.cjs +0 -62
  60. package/lib/adapters/netlify-edge/vite/index.cjs +0 -129
  61. package/lib/adapters/node-server/vite/index.cjs +0 -50
  62. package/lib/adapters/shared/vite/index.cjs +0 -378
  63. package/lib/adapters/static/vite/index.cjs +0 -368
  64. package/lib/adapters/static/vite/index.d.ts +0 -10
  65. package/lib/adapters/static/vite/index.mjs +0 -331
  66. package/lib/adapters/vercel-edge/vite/index.cjs +0 -118
  67. package/lib/index.qwik.cjs +0 -1947
  68. package/lib/middleware/node/index.cjs +0 -314
  69. package/lib/middleware/request-handler/index.cjs +0 -1614
  70. package/lib/service-worker.cjs +0 -17
  71. package/lib/service-worker.mjs +0 -15
  72. package/lib/static/deno.mjs +0 -8
  73. package/lib/static/index.cjs +0 -67
  74. package/lib/static/index.mjs +0 -48
  75. package/lib/static/node.cjs +0 -1124
  76. package/lib/vite/index.cjs +0 -27445
  77. package/middleware/request-handler/generated/not-found-paths.ts +0 -7
  78. package/middleware/request-handler/generated/static-paths.ts +0 -35
@@ -1,214 +1,31 @@
1
- import { jsx, Fragment, jsxs } from "@qwik.dev/core/jsx-runtime";
2
- import { component$, useErrorBoundary, useOnWindow, $, Slot, isBrowser, createContextId, implicit$FirstArg, useContext, useVisibleTask$, noSerialize, useServerData, useSignal, untrack, sync$, isDev, withLocale, event$, useStyles$, isServer, useStore, useContextProvider, useTask$, getLocale, jsx as jsx$1, SkipRender } from "@qwik.dev/core";
3
- import { p } from "@qwik.dev/core/preloader";
4
- import { _deserialize, _weakSerialize, _getContextElement, _getQContainerElement, _waitUntilRendered, _wrapStore, _getContextEvent, _serialize } from "@qwik.dev/core/internal";
5
- import * as qwikRouterConfig from "@qwik-router-config";
6
- import { z } from "zod";
7
- import { z as z2 } from "zod";
8
- import swRegister from "@qwik-router-sw-register";
1
+ import { jsx, Fragment, jsxs } from '@qwik.dev/core/jsx-runtime';
2
+ import { component$, useErrorBoundary, useOnWindow, $, Slot, createContextId, useContext, implicit$FirstArg, noSerialize, useVisibleTask$, useServerData, useSignal, untrack, sync$, isDev, withLocale, event$, isServer, useStyles$, useStore, isBrowser, useContextProvider, useTask$, getLocale, jsx as jsx$1, SkipRender, createElement } from '@qwik.dev/core';
3
+ import { g as getClientNavPath, s as shouldPreload, p as preloadRouteBundles, l as loadClientData, i as isPromise, a as isSamePath, c as createLoaderSignal, t as toUrl, b as isSameOrigin, d as loadRoute, D as DEFAULT_LOADERS_SERIALIZATION_STRATEGY, C as CLIENT_DATA_CACHE, Q as Q_ROUTE, e as clientNavigate, f as deepFreeze, h as QFN_KEY, j as QACTION_KEY, k as QDATA_KEY } from './chunks/routing.qwik.mjs';
4
+ import * as qwikRouterConfig from '@qwik-router-config';
5
+ import { _getContextContainer, SerializerSymbol, _UNINITIALIZED, _hasStoreEffects, forceStoreEffects, _waitUntilRendered, _getContextHostElement, _getContextEvent, _serialize, _deserialize, _resolveContextWithoutSequentialScope } from '@qwik.dev/core/internal';
6
+ import { _asyncRequestStore } from '@qwik.dev/router/middleware/request-handler';
7
+ import * as v from 'valibot';
8
+ import * as z from 'zod';
9
+ export { z } from 'zod';
10
+ import swRegister from '@qwik-router-sw-register';
11
+ import { renderToStream } from '@qwik.dev/core/server';
12
+ import '@qwik.dev/core/preloader';
13
+ import './chunks/types.qwik.mjs';
14
+
9
15
  const ErrorBoundary = component$((props) => {
10
- const store2 = useErrorBoundary();
11
- useOnWindow("qerror", $((e) => {
12
- store2.error = e.detail.error;
13
- }));
14
- if (store2.error && props.fallback$) {
15
- return /* @__PURE__ */ jsx(Fragment, {
16
- children: props.fallback$(store2.error)
17
- });
16
+ const store = useErrorBoundary();
17
+ useOnWindow(
18
+ "qerror",
19
+ $((e) => {
20
+ store.error = e.detail.error;
21
+ })
22
+ );
23
+ if (store.error && props.fallback$) {
24
+ return /* @__PURE__ */ jsx(Fragment, { children: props.fallback$(store.error) });
18
25
  }
19
26
  return /* @__PURE__ */ jsx(Slot, {});
20
27
  });
21
- const MODULE_CACHE = /* @__PURE__ */ new WeakMap();
22
- const CLIENT_DATA_CACHE = /* @__PURE__ */ new Map();
23
- const QACTION_KEY = "qaction";
24
- const QFN_KEY = "qfunc";
25
- const QDATA_KEY = "qdata";
26
- const toPath = (url) => url.pathname + url.search + url.hash;
27
- const toUrl = (url, baseUrl) => new URL(url, baseUrl.href);
28
- const isSameOrigin = (a, b) => a.origin === b.origin;
29
- const withSlash = (path) => path.endsWith("/") ? path : path + "/";
30
- const isSamePathname = ({ pathname: a }, { pathname: b }) => {
31
- const lDiff = Math.abs(a.length - b.length);
32
- return lDiff === 0 ? a === b : lDiff === 1 && withSlash(a) === withSlash(b);
33
- };
34
- const isSameSearchQuery = (a, b) => a.search === b.search;
35
- const isSamePath = (a, b) => isSameSearchQuery(a, b) && isSamePathname(a, b);
36
- const getClientDataPath = (pathname, pageSearch, action) => {
37
- let search = pageSearch ?? "";
38
- if (action) {
39
- search += (search ? "&" : "?") + QACTION_KEY + "=" + encodeURIComponent(action.id);
40
- }
41
- return pathname + (pathname.endsWith("/") ? "" : "/") + "q-data.json" + search;
42
- };
43
- const getClientNavPath = (props, baseUrl) => {
44
- const href = props.href;
45
- if (typeof href === "string" && typeof props.target !== "string" && !props.reload) {
46
- try {
47
- const linkUrl = toUrl(href.trim(), baseUrl.url);
48
- const currentUrl = toUrl("", baseUrl.url);
49
- if (isSameOrigin(linkUrl, currentUrl)) {
50
- return toPath(linkUrl);
51
- }
52
- } catch (e) {
53
- console.error(e);
54
- }
55
- } else if (props.reload) {
56
- return toPath(toUrl("", baseUrl.url));
57
- }
58
- return null;
59
- };
60
- const shouldPreload = (clientNavPath, currentLoc) => {
61
- if (clientNavPath) {
62
- const prefetchUrl = toUrl(clientNavPath, currentLoc.url);
63
- const currentUrl = toUrl("", currentLoc.url);
64
- return !isSamePathname(prefetchUrl, currentUrl);
65
- }
66
- return false;
67
- };
68
- const isPromise = (value) => {
69
- return value && typeof value.then === "function";
70
- };
71
- const deepFreeze = (obj) => {
72
- if (obj == null) {
73
- return obj;
74
- }
75
- Object.getOwnPropertyNames(obj).forEach((prop) => {
76
- const value = obj[prop];
77
- if (value && typeof value === "object" && !Object.isFrozen(value)) {
78
- deepFreeze(value);
79
- }
80
- });
81
- return Object.freeze(obj);
82
- };
83
- const clientNavigate = (win, navType, fromURL, toURL, replaceState = false) => {
84
- if (navType !== "popstate") {
85
- const samePath = isSamePath(fromURL, toURL);
86
- const sameHash = fromURL.hash === toURL.hash;
87
- if (!samePath || !sameHash) {
88
- const newState = {
89
- _qRouterScroll: newScrollState()
90
- };
91
- if (replaceState) {
92
- win.history.replaceState(newState, "", toPath(toURL));
93
- } else {
94
- win.history.pushState(newState, "", toPath(toURL));
95
- }
96
- }
97
- }
98
- };
99
- const newScrollState = () => {
100
- return {
101
- x: 0,
102
- y: 0,
103
- w: 0,
104
- h: 0
105
- };
106
- };
107
- const prefetchSymbols = (path) => {
108
- if (isBrowser) {
109
- path = path.endsWith("/") ? path : path + "/";
110
- path = path.length > 1 && path.startsWith("/") ? path.slice(1) : path;
111
- p(path, 0.8);
112
- }
113
- };
114
- const loadClientData = async (url, element, opts) => {
115
- const pagePathname = url.pathname;
116
- const pageSearch = url.search;
117
- const clientDataPath = getClientDataPath(pagePathname, pageSearch, opts?.action);
118
- let qData;
119
- if (!opts?.action) {
120
- qData = CLIENT_DATA_CACHE.get(clientDataPath);
121
- }
122
- if (opts?.prefetchSymbols !== false) {
123
- prefetchSymbols(pagePathname);
124
- }
125
- let resolveFn;
126
- if (!qData) {
127
- const fetchOptions = getFetchOptions(opts?.action, opts?.clearCache);
128
- if (opts?.action) {
129
- opts.action.data = void 0;
130
- }
131
- qData = fetch(clientDataPath, fetchOptions).then((rsp) => {
132
- if (rsp.redirected) {
133
- const redirectedURL = new URL(rsp.url);
134
- const isQData = redirectedURL.pathname.endsWith("/q-data.json");
135
- if (!isQData || redirectedURL.origin !== location.origin) {
136
- location.href = redirectedURL.href;
137
- return;
138
- }
139
- }
140
- if ((rsp.headers.get("content-type") || "").includes("json")) {
141
- return rsp.text().then((text) => {
142
- const [clientData] = _deserialize(text, element);
143
- if (!clientData) {
144
- location.href = url.href;
145
- return;
146
- }
147
- if (opts?.clearCache) {
148
- CLIENT_DATA_CACHE.delete(clientDataPath);
149
- }
150
- if (clientData.redirect) {
151
- location.href = clientData.redirect;
152
- } else if (opts?.action) {
153
- const { action } = opts;
154
- const actionData = clientData.loaders[action.id];
155
- resolveFn = () => {
156
- action.resolve({
157
- status: rsp.status,
158
- result: actionData
159
- });
160
- };
161
- }
162
- return clientData;
163
- });
164
- } else {
165
- if (opts?.isPrefetch !== true) {
166
- location.href = url.href;
167
- }
168
- return void 0;
169
- }
170
- });
171
- if (!opts?.action) {
172
- CLIENT_DATA_CACHE.set(clientDataPath, qData);
173
- }
174
- }
175
- return qData.then((v) => {
176
- if (!v) {
177
- CLIENT_DATA_CACHE.delete(clientDataPath);
178
- }
179
- resolveFn && resolveFn();
180
- return v;
181
- });
182
- };
183
- const getFetchOptions = (action, noCache) => {
184
- const actionData = action?.data;
185
- if (!actionData) {
186
- if (noCache) {
187
- return {
188
- cache: "no-cache",
189
- headers: {
190
- "Cache-Control": "no-cache",
191
- Pragma: "no-cache"
192
- }
193
- };
194
- }
195
- return void 0;
196
- }
197
- if (actionData instanceof FormData) {
198
- return {
199
- method: "POST",
200
- body: actionData
201
- };
202
- } else {
203
- return {
204
- method: "POST",
205
- body: JSON.stringify(actionData),
206
- headers: {
207
- "Content-Type": "application/json, charset=UTF-8"
208
- }
209
- };
210
- }
211
- };
28
+
212
29
  const RouteStateContext = /* @__PURE__ */ createContextId("qc-s");
213
30
  const ContentContext = /* @__PURE__ */ createContextId("qc-c");
214
31
  const ContentInternalContext = /* @__PURE__ */ createContextId("qc-ic");
@@ -216,15 +33,17 @@ const DocumentHeadContext = /* @__PURE__ */ createContextId("qc-h");
216
33
  const RouteLocationContext = /* @__PURE__ */ createContextId("qc-l");
217
34
  const RouteNavigateContext = /* @__PURE__ */ createContextId("qc-n");
218
35
  const RouteActionContext = /* @__PURE__ */ createContextId("qc-a");
219
- const RouteInternalContext = /* @__PURE__ */ createContextId("qc-ir");
220
36
  const RoutePreventNavigateContext = /* @__PURE__ */ createContextId("qc-p");
37
+
221
38
  const useContent = () => useContext(ContentContext);
222
39
  const useDocumentHead = () => useContext(DocumentHeadContext);
223
40
  const useLocation = () => useContext(RouteLocationContext);
224
41
  const useNavigate = () => useContext(RouteNavigateContext);
225
42
  const usePreventNavigateQrl = (fn) => {
226
43
  if (!__EXPERIMENTAL__.preventNavigate) {
227
- throw new Error('usePreventNavigate$ is experimental and must be enabled with `experimental: ["preventNavigate"]` in the `qwikVite` plugin.');
44
+ throw new Error(
45
+ 'usePreventNavigate$ is experimental and must be enabled with `experimental: ["preventNavigate"]` in the `qwikVite` plugin.'
46
+ );
228
47
  }
229
48
  const registerPreventNav = useContext(RoutePreventNavigateContext);
230
49
  useVisibleTask$(() => registerPreventNav(fn));
@@ -232,59 +51,67 @@ const usePreventNavigateQrl = (fn) => {
232
51
  const usePreventNavigate$ = implicit$FirstArg(usePreventNavigateQrl);
233
52
  const useAction = () => useContext(RouteActionContext);
234
53
  const useQwikRouterEnv = () => noSerialize(useServerData("qwikrouter"));
54
+
235
55
  const Link = component$((props) => {
236
56
  const nav = useNavigate();
237
57
  const loc = useLocation();
238
58
  const originalHref = props.href;
239
59
  const anchorRef = useSignal();
240
- const { onClick$, prefetch: prefetchProp, reload, replaceState, scroll, ...linkProps } = /* @__PURE__ */ (() => props)();
241
- const clientNavPath = untrack(() => getClientNavPath({
242
- ...linkProps,
243
- reload
244
- }, loc));
60
+ const {
61
+ onClick$,
62
+ prefetch: prefetchProp,
63
+ reload,
64
+ replaceState,
65
+ scroll,
66
+ ...linkProps
67
+ } = /* @__PURE__ */ (() => props)();
68
+ const clientNavPath = untrack(getClientNavPath, { ...linkProps, reload }, loc);
245
69
  linkProps.href = clientNavPath || originalHref;
246
- const prefetchData = untrack(() => !!clientNavPath && prefetchProp !== false && prefetchProp !== "js" || void 0);
247
- const prefetch = untrack(() => prefetchData || !!clientNavPath && prefetchProp !== false && shouldPreload(clientNavPath, loc));
70
+ const prefetchData = !!clientNavPath && prefetchProp !== false && prefetchProp !== "js" || void 0;
71
+ const prefetch = prefetchData || !!clientNavPath && prefetchProp !== false && untrack(shouldPreload, clientNavPath, loc);
248
72
  const handlePrefetch = prefetch ? $((_, elm) => {
249
73
  if (navigator.connection?.saveData) {
250
74
  return;
251
75
  }
252
76
  if (elm && elm.href) {
253
77
  const url = new URL(elm.href);
254
- prefetchSymbols(url.pathname);
78
+ preloadRouteBundles(url.pathname);
255
79
  if (elm.hasAttribute("data-prefetch")) {
256
- loadClientData(url, elm, {
257
- prefetchSymbols: false,
80
+ loadClientData(url, {
81
+ preloadRouteBundles: false,
258
82
  isPrefetch: true
259
83
  });
260
84
  }
261
85
  }
262
86
  }) : void 0;
263
- const preventDefault = clientNavPath ? sync$((event, target) => {
87
+ const preventDefault = clientNavPath ? sync$((event) => {
264
88
  if (!(event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {
265
89
  event.preventDefault();
266
90
  }
267
91
  }) : void 0;
268
- const handleClick = clientNavPath ? $(async (event, elm) => {
92
+ const handleClientSideNavigation = clientNavPath ? $((event, elm) => {
269
93
  if (event.defaultPrevented) {
270
94
  if (elm.href) {
271
95
  elm.setAttribute("aria-pressed", "true");
272
- await nav(elm.href, {
273
- forceReload: reload,
274
- replaceState,
275
- scroll
96
+ nav(elm.href, { forceReload: reload, replaceState, scroll }).then(() => {
97
+ elm.removeAttribute("aria-pressed");
276
98
  });
277
- elm.removeAttribute("aria-pressed");
278
99
  }
279
100
  }
280
101
  }) : void 0;
102
+ const handlePreload = $((_, elm) => {
103
+ const url = new URL(elm.href);
104
+ preloadRouteBundles(url.pathname, 1);
105
+ });
281
106
  useVisibleTask$(({ track }) => {
282
107
  track(() => loc.url.pathname);
283
108
  const handler = linkProps.onQVisible$;
284
109
  if (handler) {
285
110
  const event = new CustomEvent("qvisible");
286
111
  if (Array.isArray(handler)) {
287
- handler.flat(10).forEach((handler2) => handler2?.(event, anchorRef.value));
112
+ handler.flat(10).forEach(
113
+ (handler2) => handler2?.(event, anchorRef.value)
114
+ );
288
115
  } else {
289
116
  handler?.(event, anchorRef.value);
290
117
  }
@@ -293,36 +120,37 @@ const Link = component$((props) => {
293
120
  handlePrefetch?.(void 0, anchorRef.value);
294
121
  }
295
122
  });
296
- return /* @__PURE__ */ jsx("a", {
297
- ref: anchorRef,
298
- "q:link": !!clientNavPath,
299
- ...linkProps,
300
- onClick$: [
301
- preventDefault,
302
- onClick$,
303
- handleClick
304
- ],
305
- "data-prefetch": prefetchData,
306
- onMouseOver$: [
307
- linkProps.onMouseOver$,
308
- handlePrefetch
309
- ],
310
- onFocus$: [
311
- linkProps.onFocus$,
312
- handlePrefetch
313
- ],
314
- // We need to prevent the onQVisible$ from being called twice since it is handled in the visible task
315
- onQVisible$: [],
316
- children: /* @__PURE__ */ jsx(Slot, {})
317
- });
123
+ return /* @__PURE__ */ jsx(
124
+ "a",
125
+ {
126
+ ref: anchorRef,
127
+ ...{ "q:link": !!clientNavPath },
128
+ ...linkProps,
129
+ onClick$: [
130
+ preventDefault,
131
+ handlePreload,
132
+ // needs to be in between preventDefault and onClick$ to ensure it starts asap.
133
+ onClick$,
134
+ handleClientSideNavigation
135
+ ],
136
+ "data-prefetch": prefetchData,
137
+ onMouseOver$: [linkProps.onMouseOver$, handlePrefetch],
138
+ onFocus$: [linkProps.onFocus$, handlePrefetch],
139
+ onQVisible$: [],
140
+ children: /* @__PURE__ */ jsx(Slot, {})
141
+ }
142
+ );
318
143
  });
319
- const resolveHead = (endpoint, routeLocation, contentModules, locale) => {
320
- const head = createDocumentHead();
321
- const getData = (loaderOrAction) => {
144
+
145
+ const resolveHead = (endpoint, routeLocation, contentModules, locale, defaults) => withLocale(locale, () => {
146
+ const head = createDocumentHead(defaults);
147
+ const getData = ((loaderOrAction) => {
322
148
  const id = loaderOrAction.__id;
323
149
  if (loaderOrAction.__brand === "server_loader") {
324
150
  if (!(id in endpoint.loaders)) {
325
- throw new Error("You can not get the returned data of a loader that has not been executed for this request.");
151
+ throw new Error(
152
+ "You can not get the returned data of a loader that has not been executed for this request."
153
+ );
326
154
  }
327
155
  }
328
156
  const data = endpoint.loaders[id];
@@ -330,25 +158,31 @@ const resolveHead = (endpoint, routeLocation, contentModules, locale) => {
330
158
  throw new Error("Loaders returning a promise can not be resolved for the head function.");
331
159
  }
332
160
  return data;
333
- };
334
- const headProps = {
335
- head,
336
- withLocale: (fn) => withLocale(locale, fn),
337
- resolveValue: getData,
338
- ...routeLocation
339
- };
340
- for (let i = contentModules.length - 1; i >= 0; i--) {
341
- const contentModuleHead = contentModules[i] && contentModules[i].head;
161
+ });
162
+ const fns = [];
163
+ for (const contentModule of contentModules) {
164
+ const contentModuleHead = contentModule?.head;
342
165
  if (contentModuleHead) {
343
166
  if (typeof contentModuleHead === "function") {
344
- resolveDocumentHead(head, withLocale(locale, () => contentModuleHead(headProps)));
167
+ fns.unshift(contentModuleHead);
345
168
  } else if (typeof contentModuleHead === "object") {
346
169
  resolveDocumentHead(head, contentModuleHead);
347
170
  }
348
171
  }
349
172
  }
350
- return headProps.head;
351
- };
173
+ if (fns.length) {
174
+ const headProps = {
175
+ head,
176
+ withLocale: (fn) => fn(),
177
+ resolveValue: getData,
178
+ ...routeLocation
179
+ };
180
+ for (const fn of fns) {
181
+ resolveDocumentHead(head, fn(headProps));
182
+ }
183
+ }
184
+ return head;
185
+ });
352
186
  const resolveDocumentHead = (resolvedHead, updatedHead) => {
353
187
  if (typeof updatedHead.title === "string") {
354
188
  resolvedHead.title = updatedHead.title;
@@ -373,207 +207,39 @@ const mergeArray = (existingArr, newArr) => {
373
207
  }
374
208
  }
375
209
  };
376
- const createDocumentHead = () => ({
377
- title: "",
378
- meta: [],
379
- links: [],
380
- styles: [],
381
- scripts: [],
382
- frontmatter: {}
210
+ const createDocumentHead = (defaults) => ({
211
+ title: defaults?.title || "",
212
+ meta: [...defaults?.meta || []],
213
+ links: [...defaults?.links || []],
214
+ styles: [...defaults?.styles || []],
215
+ scripts: [...defaults?.scripts || []],
216
+ frontmatter: { ...defaults?.frontmatter }
383
217
  });
384
- function matchRoute(route, path) {
385
- const routeIdx = startIdxSkipSlash(route);
386
- const routeLength = lengthNoTrailingSlash(route);
387
- const pathIdx = startIdxSkipSlash(path);
388
- const pathLength = lengthNoTrailingSlash(path);
389
- return matchRoutePart(route, routeIdx, routeLength, path, pathIdx, pathLength);
390
- }
391
- function matchRoutePart(route, routeIdx, routeLength, path, pathIdx, pathLength) {
392
- let params = null;
393
- while (routeIdx < routeLength) {
394
- const routeCh = route.charCodeAt(routeIdx++);
395
- const pathCh = path.charCodeAt(pathIdx++);
396
- if (routeCh === 91) {
397
- const isMany = isThreeDots(route, routeIdx);
398
- const paramNameStart = routeIdx + (isMany ? 3 : 0);
399
- const paramNameEnd = scan(route, paramNameStart, routeLength, 93);
400
- const paramName = route.substring(paramNameStart, paramNameEnd);
401
- const paramSuffixEnd = scan(route, paramNameEnd + 1, routeLength, 47);
402
- const suffix = route.substring(paramNameEnd + 1, paramSuffixEnd);
403
- routeIdx = paramNameEnd + 1;
404
- const paramValueStart = pathIdx - 1;
405
- if (isMany) {
406
- const match = recursiveScan(paramName, suffix, path, paramValueStart, pathLength, route, routeIdx + suffix.length + 1, routeLength);
407
- if (match) {
408
- return Object.assign(params || (params = {}), match);
409
- }
410
- }
411
- const paramValueEnd = scan(path, paramValueStart, pathLength, 47, suffix);
412
- if (paramValueEnd == -1) {
413
- return null;
414
- }
415
- const paramValue = path.substring(paramValueStart, paramValueEnd);
416
- if (!isMany && !suffix && !paramValue) {
417
- return null;
418
- }
419
- pathIdx = paramValueEnd;
420
- (params || (params = {}))[paramName] = decodeURIComponent(paramValue);
421
- } else if (routeCh !== pathCh) {
422
- if (!(isNaN(pathCh) && isRestParameter(route, routeIdx))) {
423
- return null;
424
- }
425
- }
426
- }
427
- if (allConsumed(route, routeIdx) && allConsumed(path, pathIdx)) {
428
- return params || {};
429
- } else {
430
- return null;
431
- }
432
- }
433
- function isRestParameter(text, idx) {
434
- return text.charCodeAt(idx) === 91 && isThreeDots(text, idx + 1);
435
- }
436
- function lengthNoTrailingSlash(text) {
437
- const length = text.length;
438
- return length > 1 && text.charCodeAt(length - 1) === 47 ? length - 1 : length;
439
- }
440
- function allConsumed(text, idx) {
441
- const length = text.length;
442
- return idx >= length || idx == length - 1 && text.charCodeAt(idx) === 47;
443
- }
444
- function startIdxSkipSlash(text) {
445
- return text.charCodeAt(0) === 47 ? 1 : 0;
446
- }
447
- function isThreeDots(text, idx) {
448
- return text.charCodeAt(idx) === 46 && text.charCodeAt(idx + 1) === 46 && text.charCodeAt(idx + 2) === 46;
449
- }
450
- function scan(text, idx, end, ch, suffix = "") {
451
- while (idx < end && text.charCodeAt(idx) !== ch) {
452
- idx++;
453
- }
454
- const suffixLength = suffix.length;
455
- for (let i = 0; i < suffixLength; i++) {
456
- if (text.charCodeAt(idx - suffixLength + i) !== suffix.charCodeAt(i)) {
457
- return -1;
458
- }
459
- }
460
- return idx - suffixLength;
461
- }
462
- function recursiveScan(paramName, suffix, path, pathStart, pathLength, route, routeStart, routeLength) {
463
- if (path.charCodeAt(pathStart) === 47) {
464
- pathStart++;
465
- }
466
- let pathIdx = pathLength;
467
- const sep = suffix + "/";
468
- while (pathIdx >= pathStart) {
469
- const match = matchRoutePart(route, routeStart, routeLength, path, pathIdx, pathLength);
470
- if (match) {
471
- let value = path.substring(pathStart, Math.min(pathIdx, pathLength));
472
- if (value.endsWith(sep)) {
473
- value = value.substring(0, value.length - sep.length);
474
- }
475
- match[paramName] = decodeURIComponent(value);
476
- return match;
477
- }
478
- const newPathIdx = lastIndexOf(path, pathStart, sep, pathIdx, pathStart - 1) + sep.length;
479
- if (pathIdx === newPathIdx) {
480
- break;
481
- }
482
- pathIdx = newPathIdx;
483
- }
484
- return null;
485
- }
486
- function lastIndexOf(text, start, match, searchIdx, notFoundIdx) {
487
- let idx = text.lastIndexOf(match, searchIdx);
488
- if (idx == searchIdx - match.length) {
489
- idx = text.lastIndexOf(match, searchIdx - match.length - 1);
490
- }
491
- return idx > start ? idx : notFoundIdx;
492
- }
493
- const loadRoute = async (routes, menus, cacheModules, pathname) => {
494
- if (!Array.isArray(routes)) {
495
- return null;
496
- }
497
- for (const routeData of routes) {
498
- const routeName = routeData[0];
499
- const params = matchRoute(routeName, pathname);
500
- if (!params) {
501
- continue;
502
- }
503
- const loaders = routeData[1];
504
- const routeBundleNames = routeData[3];
505
- const modules = new Array(loaders.length);
506
- const pendingLoads = [];
507
- loaders.forEach((moduleLoader, i) => {
508
- loadModule(moduleLoader, pendingLoads, (routeModule) => modules[i] = routeModule, cacheModules);
509
- });
510
- const menuLoader = getMenuLoader(menus, pathname);
511
- let menu = void 0;
512
- loadModule(menuLoader, pendingLoads, (menuModule) => menu = menuModule?.default, cacheModules);
513
- if (pendingLoads.length > 0) {
514
- await Promise.all(pendingLoads);
515
- }
516
- return [
517
- routeName,
518
- params,
519
- modules,
520
- deepFreeze(menu),
521
- routeBundleNames
522
- ];
523
- }
524
- return null;
525
- };
526
- const loadModule = (moduleLoader, pendingLoads, moduleSetter, cacheModules) => {
527
- if (typeof moduleLoader === "function") {
528
- const loadedModule = MODULE_CACHE.get(moduleLoader);
529
- if (loadedModule) {
530
- moduleSetter(loadedModule);
531
- } else {
532
- const moduleOrPromise = moduleLoader();
533
- if (typeof moduleOrPromise.then === "function") {
534
- pendingLoads.push(moduleOrPromise.then((loadedModule2) => {
535
- if (cacheModules !== false) {
536
- MODULE_CACHE.set(moduleLoader, loadedModule2);
537
- }
538
- moduleSetter(loadedModule2);
539
- }));
540
- } else if (moduleOrPromise) {
541
- moduleSetter(moduleOrPromise);
542
- }
543
- }
544
- }
545
- };
546
- const getMenuLoader = (menus, pathname) => {
547
- if (menus) {
548
- pathname = pathname.endsWith("/") ? pathname : pathname + "/";
549
- const menu = menus.find((m) => m[0] === pathname || pathname.startsWith(m[0] + (pathname.endsWith("/") ? "" : "/")));
550
- if (menu) {
551
- return menu[1];
552
- }
553
- }
554
- };
218
+
219
+ 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}}}";
220
+
555
221
  function callRestoreScrollOnDocument() {
556
222
  if (document.__q_scroll_restore__) {
557
223
  document.__q_scroll_restore__();
558
224
  document.__q_scroll_restore__ = void 0;
559
225
  }
560
226
  }
561
- const restoreScroll = (type, toUrl2, fromUrl, scroller, scrollState) => {
227
+ const restoreScroll = (type, toUrl, fromUrl, scroller, scrollState) => {
562
228
  if (type === "popstate" && scrollState) {
563
229
  scroller.scrollTo(scrollState.x, scrollState.y);
564
230
  } else if (type === "link" || type === "form") {
565
- if (!hashScroll(toUrl2, fromUrl)) {
231
+ if (!hashScroll(toUrl, fromUrl)) {
566
232
  scroller.scrollTo(0, 0);
567
233
  }
568
234
  }
569
235
  };
570
- const hashScroll = (toUrl2, fromUrl) => {
571
- const elmId = toUrl2.hash.slice(1);
236
+ const hashScroll = (toUrl, fromUrl) => {
237
+ const elmId = toUrl.hash.slice(1);
572
238
  const elm = elmId && document.getElementById(elmId);
573
239
  if (elm) {
574
240
  elm.scrollIntoView();
575
241
  return true;
576
- } else if (!elm && toUrl2.hash && isSamePath(toUrl2, fromUrl)) {
242
+ } else if (!elm && toUrl.hash && isSamePath(toUrl, fromUrl)) {
577
243
  return true;
578
244
  }
579
245
  return false;
@@ -595,25 +261,16 @@ const saveScrollHistory = (scrollState) => {
595
261
  state._qRouterScroll = scrollState;
596
262
  history.replaceState(state, "");
597
263
  };
264
+
598
265
  const spaInit = event$((_, el) => {
599
- const win = window;
600
- const spa = "_qRouterSPA";
601
- const initPopstate = "_qRouterInitPopstate";
602
- const initAnchors = "_qRouterInitAnchors";
603
- const initVisibility = "_qRouterInitVisibility";
604
- const initScroll = "_qRouterInitScroll";
605
- if (!win[spa] && !win[initPopstate] && !win[initAnchors] && !win[initVisibility] && !win[initScroll]) {
266
+ if (!window._qRouterSPA && !window._qRouterInitPopstate) {
606
267
  const currentPath = location.pathname + location.search;
607
- const historyPatch = "_qRouterHistoryPatch";
608
- const scrollEnabled = "_qRouterScrollEnabled";
609
- const debounceTimeout = "_qRouterScrollDebounce";
610
- const scrollHistory = "_qRouterScroll";
611
268
  const checkAndScroll = (scrollState) => {
612
269
  if (scrollState) {
613
- win.scrollTo(scrollState.x, scrollState.y);
270
+ window.scrollTo(scrollState.x, scrollState.y);
614
271
  }
615
272
  };
616
- const currentScrollState2 = () => {
273
+ const currentScrollState = () => {
617
274
  const elm = document.documentElement;
618
275
  return {
619
276
  x: elm.scrollLeft,
@@ -624,16 +281,16 @@ const spaInit = event$((_, el) => {
624
281
  };
625
282
  const saveScrollState = (scrollState) => {
626
283
  const state = history.state || {};
627
- state[scrollHistory] = scrollState || currentScrollState2();
284
+ state._qRouterScroll = scrollState || currentScrollState();
628
285
  history.replaceState(state, "");
629
286
  };
630
287
  saveScrollState();
631
- win[initPopstate] = () => {
632
- if (win[spa]) {
288
+ window._qRouterInitPopstate = () => {
289
+ if (window._qRouterSPA) {
633
290
  return;
634
291
  }
635
- win[scrollEnabled] = false;
636
- clearTimeout(win[debounceTimeout]);
292
+ window._qRouterScrollEnabled = false;
293
+ clearTimeout(window._qRouterScrollDebounce);
637
294
  if (currentPath !== location.pathname + location.search) {
638
295
  const getContainer = (el2) => el2.closest("[q\\:container]:not([q\\:container=html]):not([q\\:container=text])");
639
296
  const container = getContainer(el);
@@ -643,36 +300,34 @@ const spaInit = event$((_, el) => {
643
300
  id: "qc--n"
644
301
  });
645
302
  if (nav) {
646
- nav(location.href, {
647
- type: "popstate"
648
- });
303
+ nav(location.href, { type: "popstate" });
649
304
  } else {
650
305
  location.reload();
651
306
  }
652
307
  } else {
653
308
  if (history.scrollRestoration === "manual") {
654
- const scrollState = history.state?.[scrollHistory];
309
+ const scrollState = history.state?._qRouterScroll;
655
310
  checkAndScroll(scrollState);
656
- win[scrollEnabled] = true;
311
+ window._qRouterScrollEnabled = true;
657
312
  }
658
313
  }
659
314
  };
660
- if (!win[historyPatch]) {
661
- win[historyPatch] = true;
315
+ if (!window._qRouterHistoryPatch) {
316
+ window._qRouterHistoryPatch = true;
662
317
  const pushState = history.pushState;
663
318
  const replaceState = history.replaceState;
664
319
  const prepareState = (state) => {
665
320
  if (state === null || typeof state === "undefined") {
666
321
  state = {};
667
322
  } else if (state?.constructor !== Object) {
668
- state = {
669
- _data: state
670
- };
323
+ state = { _data: state };
671
324
  if (isDev) {
672
- 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`");
325
+ console.warn(
326
+ "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`"
327
+ );
673
328
  }
674
329
  }
675
- state._qRouterScroll = state._qRouterScroll || currentScrollState2();
330
+ state._qRouterScroll = state._qRouterScroll || currentScrollState();
676
331
  return state;
677
332
  };
678
333
  history.pushState = (state, title, url) => {
@@ -684,8 +339,8 @@ const spaInit = event$((_, el) => {
684
339
  return replaceState.call(history, state, title, url);
685
340
  };
686
341
  }
687
- win[initAnchors] = (event) => {
688
- if (win[spa] || event.defaultPrevented) {
342
+ window._qRouterInitAnchors = (event) => {
343
+ if (window._qRouterSPA || event.defaultPrevented) {
689
344
  return;
690
345
  }
691
346
  const target = event.target.closest("a[href]");
@@ -704,13 +359,9 @@ const spaInit = event$((_, el) => {
704
359
  if (dest.href.endsWith("#")) {
705
360
  window.scrollTo(0, 0);
706
361
  } else {
707
- win[scrollEnabled] = false;
708
- clearTimeout(win[debounceTimeout]);
709
- saveScrollState({
710
- ...currentScrollState2(),
711
- x: 0,
712
- y: 0
713
- });
362
+ window._qRouterScrollEnabled = false;
363
+ clearTimeout(window._qRouterScrollDebounce);
364
+ saveScrollState({ ...currentScrollState(), x: 0, y: 0 });
714
365
  location.reload();
715
366
  }
716
367
  } else {
@@ -723,36 +374,35 @@ const spaInit = event$((_, el) => {
723
374
  }
724
375
  }
725
376
  };
726
- win[initVisibility] = () => {
727
- if (!win[spa] && win[scrollEnabled] && document.visibilityState === "hidden") {
377
+ window._qRouterInitVisibility = () => {
378
+ if (!window._qRouterSPA && window._qRouterScrollEnabled && document.visibilityState === "hidden") {
728
379
  saveScrollState();
729
380
  }
730
381
  };
731
- win[initScroll] = () => {
732
- if (win[spa] || !win[scrollEnabled]) {
382
+ window._qRouterInitScroll = () => {
383
+ if (window._qRouterSPA || !window._qRouterScrollEnabled) {
733
384
  return;
734
385
  }
735
- clearTimeout(win[debounceTimeout]);
736
- win[debounceTimeout] = setTimeout(() => {
386
+ clearTimeout(window._qRouterScrollDebounce);
387
+ window._qRouterScrollDebounce = setTimeout(() => {
737
388
  saveScrollState();
738
- win[debounceTimeout] = void 0;
389
+ window._qRouterScrollDebounce = void 0;
739
390
  }, 200);
740
391
  };
741
- win[scrollEnabled] = true;
392
+ window._qRouterScrollEnabled = true;
742
393
  setTimeout(() => {
743
- addEventListener("popstate", win[initPopstate]);
744
- addEventListener("scroll", win[initScroll], {
745
- passive: true
746
- });
747
- document.body.addEventListener("click", win[initAnchors]);
748
- if (!win.navigation) {
749
- document.addEventListener("visibilitychange", win[initVisibility], {
394
+ window.addEventListener("popstate", window._qRouterInitPopstate);
395
+ window.addEventListener("scroll", window._qRouterInitScroll, { passive: true });
396
+ document.addEventListener("click", window._qRouterInitAnchors);
397
+ if (!window.navigation) {
398
+ document.addEventListener("visibilitychange", window._qRouterInitVisibility, {
750
399
  passive: true
751
400
  });
752
401
  }
753
402
  }, 0);
754
403
  }
755
404
  });
405
+
756
406
  const startViewTransition = (params) => {
757
407
  if (!params.update) {
758
408
  return;
@@ -764,68 +414,81 @@ const startViewTransition = (params) => {
764
414
  } catch {
765
415
  transition = document.startViewTransition(params.update);
766
416
  }
767
- const event = new CustomEvent("qviewtransition", {
768
- detail: transition
769
- });
417
+ const event = new CustomEvent("qviewtransition", { detail: transition });
770
418
  document.dispatchEvent(event);
771
419
  return transition;
772
420
  } else {
773
421
  params.update?.();
774
422
  }
775
423
  };
424
+
776
425
  const QWIK_CITY_SCROLLER = "_qCityScroller";
777
426
  const QWIK_ROUTER_SCROLLER = "_qRouterScroller";
778
427
  const preventNav = {};
779
- const internalState = {
780
- navCount: 0
781
- };
782
- const QwikRouterProvider = component$((props) => {
783
- useStyles$(`
784
- @layer qwik {
785
- @supports selector(html:active-view-transition-type(type)) {
786
- html:active-view-transition-type(qwik-router-spa) {
787
- :root{view-transition-name:none}
788
- }
789
- }
790
- @supports not selector(html:active-view-transition-type(type)) {
791
- :root{view-transition-name:none}
792
- }
793
- }
794
- `);
428
+ const internalState = { navCount: 0 };
429
+ const useQwikRouter = (props) => {
430
+ if (!isServer) {
431
+ throw new Error(
432
+ "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."
433
+ );
434
+ }
435
+ useStyles$(transitionCss);
795
436
  const env = useQwikRouterEnv();
796
437
  if (!env?.params) {
797
- throw new Error(`Missing Qwik Router Env Data for help visit https://github.com/QwikDev/qwik/issues/6237`);
438
+ throw new Error(
439
+ `Missing Qwik Router Env Data for help visit https://github.com/QwikDev/qwik/issues/6237`
440
+ );
798
441
  }
799
442
  const urlEnv = useServerData("url");
800
443
  if (!urlEnv) {
801
444
  throw new Error(`Missing Qwik URL Env Data`);
802
445
  }
803
- if (isServer) {
804
- if (env.ev.originalUrl.pathname !== env.ev.url.pathname && !__EXPERIMENTAL__.enableRequestRewrite) {
805
- throw new Error(`enableRequestRewrite is an experimental feature and is not enabled. Please enable the feature flag by adding \`experimental: ["enableRequestRewrite"]\` to your qwikVite plugin options.`);
806
- }
446
+ const serverHead = useServerData("documentHead");
447
+ if (env.ev.originalUrl.pathname !== env.ev.url.pathname && !__EXPERIMENTAL__.enableRequestRewrite) {
448
+ throw new Error(
449
+ `enableRequestRewrite is an experimental feature and is not enabled. Please enable the feature flag by adding \`experimental: ["enableRequestRewrite"]\` to your qwikVite plugin options.`
450
+ );
807
451
  }
808
452
  const url = new URL(urlEnv);
809
- const routeLocation = useStore({
453
+ const routeLocationTarget = {
810
454
  url,
811
455
  params: env.params,
812
456
  isNavigating: false,
813
457
  prevUrl: void 0
814
- }, {
815
- deep: false
816
- });
458
+ };
459
+ const routeLocation = useStore(routeLocationTarget, { deep: false });
817
460
  const navResolver = {};
818
- const loaderState = _weakSerialize(useStore(env.response.loaders, {
819
- deep: false
820
- }));
461
+ const container = _getContextContainer();
462
+ const getSerializationStrategy = (loaderId) => {
463
+ return env.response.loadersSerializationStrategy.get(loaderId) || DEFAULT_LOADERS_SERIALIZATION_STRATEGY;
464
+ };
465
+ const loadersObject = {};
466
+ const loaderState = {};
467
+ for (const [key, value] of Object.entries(env.response.loaders)) {
468
+ loadersObject[key] = value;
469
+ loaderState[key] = createLoaderSignal(
470
+ loadersObject,
471
+ key,
472
+ url,
473
+ getSerializationStrategy(key),
474
+ container
475
+ );
476
+ }
477
+ loadersObject[SerializerSymbol] = (obj) => {
478
+ const loadersSerializationObject = {};
479
+ for (const [k, v] of Object.entries(obj)) {
480
+ loadersSerializationObject[k] = getSerializationStrategy(k) === "always" ? v : _UNINITIALIZED;
481
+ }
482
+ return loadersSerializationObject;
483
+ };
821
484
  const routeInternal = useSignal({
822
485
  type: "initial",
823
486
  dest: url,
824
- forceReload: false,
825
- replaceState: false,
826
487
  scroll: true
827
488
  });
828
- const documentHead = useStore(createDocumentHead);
489
+ const documentHead = useStore(
490
+ () => createDocumentHead(serverHead)
491
+ );
829
492
  const content = useStore({
830
493
  headings: void 0,
831
494
  menu: void 0
@@ -833,32 +496,34 @@ const QwikRouterProvider = component$((props) => {
833
496
  const contentInternal = useSignal();
834
497
  const currentActionId = env.response.action;
835
498
  const currentAction = currentActionId ? env.response.loaders[currentActionId] : void 0;
836
- const actionState = useSignal(currentAction ? {
837
- id: currentActionId,
838
- data: env.response.formData,
839
- output: {
840
- result: currentAction,
841
- status: env.response.status
842
- }
843
- } : void 0);
499
+ const actionState = useSignal(
500
+ currentAction ? {
501
+ id: currentActionId,
502
+ data: env.response.formData,
503
+ output: {
504
+ result: currentAction,
505
+ status: env.response.status
506
+ }
507
+ } : void 0
508
+ );
844
509
  const registerPreventNav = $((fn$) => {
845
510
  if (!isBrowser) {
846
511
  return;
847
512
  }
848
- preventNav.$handler$ || (preventNav.$handler$ = (event) => {
513
+ preventNav.$handler$ ||= (event) => {
849
514
  internalState.navCount++;
850
515
  if (!preventNav.$cbs$) {
851
516
  return;
852
517
  }
853
- const prevents = [
854
- ...preventNav.$cbs$.values()
855
- ].map((cb) => cb.resolved ? cb.resolved() : cb());
518
+ const prevents = [...preventNav.$cbs$.values()].map(
519
+ (cb) => cb.resolved ? cb.resolved() : cb()
520
+ );
856
521
  if (prevents.some(Boolean)) {
857
522
  event.preventDefault();
858
523
  event.returnValue = true;
859
524
  }
860
- });
861
- (preventNav.$cbs$ || (preventNav.$cbs$ = /* @__PURE__ */ new Set())).add(fn$);
525
+ };
526
+ (preventNav.$cbs$ ||= /* @__PURE__ */ new Set()).add(fn$);
862
527
  fn$.resolve();
863
528
  window.addEventListener("beforeunload", preventNav.$handler$);
864
529
  return () => {
@@ -872,17 +537,24 @@ const QwikRouterProvider = component$((props) => {
872
537
  };
873
538
  });
874
539
  const goto = $(async (path, opt) => {
875
- const { type = "link", forceReload = path === void 0, replaceState = false, scroll = true } = typeof opt === "object" ? opt : {
876
- forceReload: opt
877
- };
540
+ const {
541
+ type = "link",
542
+ forceReload = path === void 0,
543
+ // Hack for nav() because this API is already set.
544
+ replaceState = false,
545
+ scroll = true
546
+ } = typeof opt === "object" ? opt : { forceReload: opt };
878
547
  internalState.navCount++;
548
+ if (isBrowser && type === "link" && routeInternal.value.type === "initial") {
549
+ const url2 = new URL(window.location.href);
550
+ routeInternal.value.dest = url2;
551
+ routeLocation.url = url2;
552
+ }
879
553
  const lastDest = routeInternal.value.dest;
880
554
  const dest = path === void 0 ? lastDest : typeof path === "number" ? path : toUrl(path, routeLocation.url);
881
555
  if (preventNav.$cbs$ && (forceReload || typeof dest === "number" || !isSamePath(dest, lastDest) || !isSameOrigin(dest, lastDest))) {
882
556
  const ourNavId = internalState.navCount;
883
- const prevents = await Promise.all([
884
- ...preventNav.$cbs$.values()
885
- ].map((cb) => cb(dest)));
557
+ const prevents = await Promise.all([...preventNav.$cbs$.values()].map((cb) => cb(dest)));
886
558
  if (ourNavId !== internalState.navCount || prevents.some(Boolean)) {
887
559
  if (ourNavId === internalState.navCount && type === "popstate") {
888
560
  history.pushState(null, "", lastDest);
@@ -910,8 +582,10 @@ const QwikRouterProvider = component$((props) => {
910
582
  let scroller = document.getElementById(QWIK_ROUTER_SCROLLER);
911
583
  if (!scroller) {
912
584
  scroller = document.getElementById(QWIK_CITY_SCROLLER);
913
- if (scroller) {
914
- console.warn(`Please update your scroller ID to "${QWIK_ROUTER_SCROLLER}" as "${QWIK_CITY_SCROLLER}" is deprecated and will be removed in V3`);
585
+ if (scroller && isDev) {
586
+ console.warn(
587
+ `Please update your scroller ID to "${QWIK_ROUTER_SCROLLER}" as "${QWIK_CITY_SCROLLER}" is deprecated and will be removed in V3`
588
+ );
915
589
  }
916
590
  }
917
591
  if (!scroller) {
@@ -932,8 +606,13 @@ const QwikRouterProvider = component$((props) => {
932
606
  scroll
933
607
  };
934
608
  if (isBrowser) {
935
- loadClientData(dest, _getContextElement());
936
- loadRoute(qwikRouterConfig.routes, qwikRouterConfig.menus, qwikRouterConfig.cacheModules, dest.pathname);
609
+ loadClientData(dest);
610
+ loadRoute(
611
+ qwikRouterConfig.routes,
612
+ qwikRouterConfig.menus,
613
+ qwikRouterConfig.cacheModules,
614
+ dest.pathname
615
+ );
937
616
  }
938
617
  actionState.value = void 0;
939
618
  routeLocation.isNavigating = true;
@@ -948,14 +627,11 @@ const QwikRouterProvider = component$((props) => {
948
627
  useContextProvider(RouteNavigateContext, goto);
949
628
  useContextProvider(RouteStateContext, loaderState);
950
629
  useContextProvider(RouteActionContext, actionState);
951
- useContextProvider(RouteInternalContext, routeInternal);
952
630
  useContextProvider(RoutePreventNavigateContext, registerPreventNav);
953
631
  useTask$(({ track }) => {
954
632
  async function run() {
955
- const [navigation, action] = track(() => [
956
- routeInternal.value,
957
- actionState.value
958
- ]);
633
+ const navigation = track(routeInternal);
634
+ const action = track(actionState);
959
635
  const locale = getLocale("");
960
636
  const prevUrl = routeLocation.url;
961
637
  const navType = action ? "form" : navigation.type;
@@ -963,7 +639,7 @@ const QwikRouterProvider = component$((props) => {
963
639
  let trackUrl;
964
640
  let clientPageData;
965
641
  let loadedRoute = null;
966
- let elm;
642
+ let container2;
967
643
  if (isServer) {
968
644
  trackUrl = new URL(navigation.dest, routeLocation.url);
969
645
  loadedRoute = env.loadedRoute;
@@ -971,23 +647,25 @@ const QwikRouterProvider = component$((props) => {
971
647
  } else {
972
648
  trackUrl = new URL(navigation.dest, location);
973
649
  if (trackUrl.pathname.endsWith("/")) {
974
- if (!qwikRouterConfig.trailingSlash) {
650
+ if (globalThis.__NO_TRAILING_SLASH__) {
975
651
  trackUrl.pathname = trackUrl.pathname.slice(0, -1);
976
652
  }
977
- } else if (qwikRouterConfig.trailingSlash) {
653
+ } else if (!globalThis.__NO_TRAILING_SLASH__) {
978
654
  trackUrl.pathname += "/";
979
655
  }
980
- let loadRoutePromise = loadRoute(qwikRouterConfig.routes, qwikRouterConfig.menus, qwikRouterConfig.cacheModules, trackUrl.pathname);
981
- elm = _getContextElement();
982
- const pageData = clientPageData = await loadClientData(trackUrl, elm, {
656
+ let loadRoutePromise = loadRoute(
657
+ qwikRouterConfig.routes,
658
+ qwikRouterConfig.menus,
659
+ qwikRouterConfig.cacheModules,
660
+ trackUrl.pathname
661
+ );
662
+ container2 = _getContextContainer();
663
+ const pageData = clientPageData = await loadClientData(trackUrl, {
983
664
  action,
984
665
  clearCache: true
985
666
  });
986
667
  if (!pageData) {
987
- routeInternal.untrackedValue = {
988
- type: navType,
989
- dest: trackUrl
990
- };
668
+ routeInternal.untrackedValue = { type: navType, dest: trackUrl };
991
669
  return;
992
670
  }
993
671
  const newHref = pageData.href;
@@ -1016,25 +694,41 @@ const QwikRouterProvider = component$((props) => {
1016
694
  const [routeName, params, mods, menu] = loadedRoute;
1017
695
  const contentModules = mods;
1018
696
  const pageModule = contentModules[contentModules.length - 1];
1019
- const isRedirect = navType === "form" && !isSamePath(trackUrl, prevUrl);
1020
- if (navigation.dest.search && !isRedirect) {
697
+ if (navigation.dest.search && !!isSamePath(trackUrl, prevUrl)) {
1021
698
  trackUrl.search = navigation.dest.search;
1022
699
  }
700
+ let shouldForcePrevUrl = false;
701
+ let shouldForceUrl = false;
702
+ let shouldForceParams = false;
1023
703
  if (!isSamePath(trackUrl, prevUrl)) {
1024
- routeLocation.prevUrl = prevUrl;
704
+ if (_hasStoreEffects(routeLocation, "prevUrl")) {
705
+ shouldForcePrevUrl = true;
706
+ }
707
+ routeLocationTarget.prevUrl = prevUrl;
1025
708
  }
1026
- routeLocation.url = trackUrl;
1027
- routeLocation.params = {
1028
- ...params
1029
- };
1030
- routeInternal.untrackedValue = {
1031
- type: navType,
1032
- dest: trackUrl
1033
- };
1034
- const resolvedHead = resolveHead(clientPageData, routeLocation, contentModules, locale);
709
+ if (routeLocationTarget.url !== trackUrl) {
710
+ if (_hasStoreEffects(routeLocation, "url")) {
711
+ shouldForceUrl = true;
712
+ }
713
+ routeLocationTarget.url = trackUrl;
714
+ }
715
+ if (routeLocationTarget.params !== params) {
716
+ if (_hasStoreEffects(routeLocation, "params")) {
717
+ shouldForceParams = true;
718
+ }
719
+ routeLocationTarget.params = params;
720
+ }
721
+ routeInternal.untrackedValue = { type: navType, dest: trackUrl };
722
+ const resolvedHead = resolveHead(
723
+ clientPageData,
724
+ routeLocation,
725
+ contentModules,
726
+ locale,
727
+ serverHead
728
+ );
1035
729
  content.headings = pageModule.headings;
1036
730
  content.menu = menu;
1037
- contentInternal.value = noSerialize(contentModules);
731
+ contentInternal.untrackedValue = noSerialize(contentModules);
1038
732
  documentHead.links = resolvedHead.links;
1039
733
  documentHead.meta = resolvedHead.meta;
1040
734
  documentHead.styles = resolvedHead.styles;
@@ -1047,40 +741,56 @@ const QwikRouterProvider = component$((props) => {
1047
741
  scrollState = getScrollHistory();
1048
742
  }
1049
743
  const scroller = document.getElementById(QWIK_ROUTER_SCROLLER) ?? document.documentElement;
1050
- if (navigation.scroll && (!navigation.forceReload || !isSamePath(trackUrl, prevUrl)) && (navType === "link" || navType === "popstate") || isRedirect) {
744
+ if (navigation.scroll && (!navigation.forceReload || !isSamePath(trackUrl, prevUrl)) && (navType === "link" || navType === "popstate") || // Action might have responded with a redirect.
745
+ navType === "form" && !isSamePath(trackUrl, prevUrl)) {
1051
746
  document.__q_scroll_restore__ = () => restoreScroll(navType, trackUrl, prevUrl, scroller, scrollState);
1052
747
  }
1053
748
  const loaders = clientPageData?.loaders;
1054
- const win = window;
1055
749
  if (loaders) {
1056
- Object.assign(loaderState, loaders);
750
+ const container3 = _getContextContainer();
751
+ for (const [key, value] of Object.entries(loaders)) {
752
+ const signal = loaderState[key];
753
+ const awaitedValue = await value;
754
+ loadersObject[key] = awaitedValue;
755
+ if (!signal) {
756
+ loaderState[key] = createLoaderSignal(
757
+ loadersObject,
758
+ key,
759
+ trackUrl,
760
+ DEFAULT_LOADERS_SERIALIZATION_STRATEGY,
761
+ container3
762
+ );
763
+ } else {
764
+ signal.invalidate();
765
+ }
766
+ }
1057
767
  }
1058
768
  CLIENT_DATA_CACHE.clear();
1059
- if (!win._qRouterSPA) {
1060
- win._qRouterSPA = true;
769
+ if (!window._qRouterSPA) {
770
+ window._qRouterSPA = true;
1061
771
  history.scrollRestoration = "manual";
1062
- win.addEventListener("popstate", () => {
1063
- win._qRouterScrollEnabled = false;
1064
- clearTimeout(win._qRouterScrollDebounce);
772
+ window.addEventListener("popstate", () => {
773
+ window._qRouterScrollEnabled = false;
774
+ clearTimeout(window._qRouterScrollDebounce);
1065
775
  goto(location.href, {
1066
776
  type: "popstate"
1067
777
  });
1068
778
  });
1069
- win.removeEventListener("popstate", win._qRouterInitPopstate);
1070
- win._qRouterInitPopstate = void 0;
1071
- if (!win._qRouterHistoryPatch) {
1072
- win._qRouterHistoryPatch = true;
779
+ window.removeEventListener("popstate", window._qRouterInitPopstate);
780
+ window._qRouterInitPopstate = void 0;
781
+ if (!window._qRouterHistoryPatch) {
782
+ window._qRouterHistoryPatch = true;
1073
783
  const pushState = history.pushState;
1074
784
  const replaceState2 = history.replaceState;
1075
785
  const prepareState = (state) => {
1076
786
  if (state === null || typeof state === "undefined") {
1077
787
  state = {};
1078
788
  } else if (state?.constructor !== Object) {
1079
- state = {
1080
- _data: state
1081
- };
789
+ state = { _data: state };
1082
790
  if (isDev) {
1083
- 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`");
791
+ console.warn(
792
+ "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`"
793
+ );
1084
794
  }
1085
795
  }
1086
796
  state._qRouterScroll = state._qRouterScroll || currentScrollState(scroller);
@@ -1095,7 +805,7 @@ const QwikRouterProvider = component$((props) => {
1095
805
  return replaceState2.call(history, state, title, url2);
1096
806
  };
1097
807
  }
1098
- document.body.addEventListener("click", (event) => {
808
+ document.addEventListener("click", (event) => {
1099
809
  if (event.defaultPrevented) {
1100
810
  return;
1101
811
  }
@@ -1110,8 +820,8 @@ const QwikRouterProvider = component$((props) => {
1110
820
  if (dest.href !== prev.href) {
1111
821
  history.pushState(null, "", dest);
1112
822
  }
1113
- win._qRouterScrollEnabled = false;
1114
- clearTimeout(win._qRouterScrollDebounce);
823
+ window._qRouterScrollEnabled = false;
824
+ clearTimeout(window._qRouterScrollDebounce);
1115
825
  saveScrollHistory({
1116
826
  ...currentScrollState(scroller),
1117
827
  x: 0,
@@ -1124,59 +834,64 @@ const QwikRouterProvider = component$((props) => {
1124
834
  }
1125
835
  }
1126
836
  });
1127
- document.body.removeEventListener("click", win._qRouterInitAnchors);
1128
- win._qRouterInitAnchors = void 0;
837
+ document.removeEventListener("click", window._qRouterInitAnchors);
838
+ window._qRouterInitAnchors = void 0;
1129
839
  if (!window.navigation) {
1130
- document.addEventListener("visibilitychange", () => {
1131
- if ((win._qRouterScrollEnabled || win._qCityScrollEnabled) && document.visibilityState === "hidden") {
1132
- if (win._qCityScrollEnabled) {
1133
- console.warn('"_qCityScrollEnabled" is deprecated. Use "_qRouterScrollEnabled" instead.');
840
+ document.addEventListener(
841
+ "visibilitychange",
842
+ () => {
843
+ if ((window._qRouterScrollEnabled || window._qCityScrollEnabled) && document.visibilityState === "hidden") {
844
+ if (window._qCityScrollEnabled) {
845
+ console.warn(
846
+ '"_qCityScrollEnabled" is deprecated. Use "_qRouterScrollEnabled" instead.'
847
+ );
848
+ }
849
+ const scrollState2 = currentScrollState(scroller);
850
+ saveScrollHistory(scrollState2);
1134
851
  }
852
+ },
853
+ { passive: true }
854
+ );
855
+ document.removeEventListener("visibilitychange", window._qRouterInitVisibility);
856
+ window._qRouterInitVisibility = void 0;
857
+ }
858
+ window.addEventListener(
859
+ "scroll",
860
+ () => {
861
+ if (!window._qRouterScrollEnabled && !window._qCityScrollEnabled) {
862
+ return;
863
+ }
864
+ clearTimeout(window._qRouterScrollDebounce);
865
+ window._qRouterScrollDebounce = setTimeout(() => {
1135
866
  const scrollState2 = currentScrollState(scroller);
1136
867
  saveScrollHistory(scrollState2);
1137
- }
1138
- }, {
1139
- passive: true
1140
- });
1141
- document.removeEventListener("visibilitychange", win._qRouterInitVisibility);
1142
- win._qRouterInitVisibility = void 0;
1143
- }
1144
- win.addEventListener("scroll", () => {
1145
- if (!win._qRouterScrollEnabled && !win._qCityScrollEnabled) {
1146
- return;
1147
- }
1148
- clearTimeout(win._qRouterScrollDebounce);
1149
- win._qRouterScrollDebounce = setTimeout(() => {
1150
- const scrollState2 = currentScrollState(scroller);
1151
- saveScrollHistory(scrollState2);
1152
- win._qRouterScrollDebounce = void 0;
1153
- }, 200);
1154
- }, {
1155
- passive: true
1156
- });
1157
- removeEventListener("scroll", win._qRouterInitScroll);
1158
- win._qRouterInitScroll = void 0;
868
+ window._qRouterScrollDebounce = void 0;
869
+ }, 200);
870
+ },
871
+ { passive: true }
872
+ );
873
+ removeEventListener("scroll", window._qRouterInitScroll);
874
+ window._qRouterInitScroll = void 0;
1159
875
  spaInit.resolve();
1160
876
  }
1161
877
  if (navType !== "popstate") {
1162
- win._qRouterScrollEnabled = false;
1163
- clearTimeout(win._qRouterScrollDebounce);
878
+ window._qRouterScrollEnabled = false;
879
+ clearTimeout(window._qRouterScrollDebounce);
1164
880
  const scrollState2 = currentScrollState(scroller);
1165
881
  saveScrollHistory(scrollState2);
1166
882
  }
1167
883
  const navigate = () => {
1168
884
  clientNavigate(window, navType, prevUrl, trackUrl, replaceState);
1169
- return _waitUntilRendered(elm);
885
+ contentInternal.force();
886
+ return _waitUntilRendered(container2);
1170
887
  };
1171
888
  const _waitNextPage = () => {
1172
- if (isServer || props.viewTransition === false) {
889
+ if (isServer || props?.viewTransition === false) {
1173
890
  return navigate();
1174
891
  } else {
1175
892
  const viewTransition = startViewTransition({
1176
893
  update: navigate,
1177
- types: [
1178
- "qwik-navigation"
1179
- ]
894
+ types: ["qwik-navigation"]
1180
895
  });
1181
896
  if (!viewTransition) {
1182
897
  return Promise.resolve();
@@ -1184,15 +899,26 @@ const QwikRouterProvider = component$((props) => {
1184
899
  return viewTransition.ready;
1185
900
  }
1186
901
  };
1187
- _waitNextPage().then(() => {
1188
- const container = _getQContainerElement(elm);
1189
- container.setAttribute("q:route", routeName);
902
+ _waitNextPage().catch((err) => {
903
+ navigate();
904
+ throw err;
905
+ }).finally(() => {
906
+ container2.element.setAttribute?.(Q_ROUTE, routeName);
1190
907
  const scrollState2 = currentScrollState(scroller);
1191
908
  saveScrollHistory(scrollState2);
1192
- win._qRouterScrollEnabled = true;
909
+ window._qRouterScrollEnabled = true;
1193
910
  if (isBrowser) {
1194
911
  callRestoreScrollOnDocument();
1195
912
  }
913
+ if (shouldForcePrevUrl) {
914
+ forceStoreEffects(routeLocation, "prevUrl");
915
+ }
916
+ if (shouldForceUrl) {
917
+ forceStoreEffects(routeLocation, "url");
918
+ }
919
+ if (shouldForceParams) {
920
+ forceStoreEffects(routeLocation, "params");
921
+ }
1196
922
  routeLocation.isNavigating = false;
1197
923
  navResolver.r?.();
1198
924
  });
@@ -1205,37 +931,43 @@ const QwikRouterProvider = component$((props) => {
1205
931
  run();
1206
932
  }
1207
933
  });
934
+ };
935
+ const QwikRouterProvider = component$((props) => {
936
+ useQwikRouter(props);
1208
937
  return /* @__PURE__ */ jsx(Slot, {});
1209
938
  });
1210
939
  const QwikCityProvider = QwikRouterProvider;
1211
- const QwikRouterMockProvider = component$((props) => {
940
+ const useQwikMockRouter = (props) => {
1212
941
  const urlEnv = props.url ?? "http://localhost/";
1213
942
  const url = new URL(urlEnv);
1214
- const routeLocation = useStore({
1215
- url,
1216
- params: props.params ?? {},
1217
- isNavigating: false,
1218
- prevUrl: void 0
1219
- }, {
1220
- deep: false
1221
- });
1222
- const loaderState = useSignal({});
1223
- const routeInternal = useSignal({
1224
- type: "initial",
1225
- dest: url
1226
- });
943
+ const routeLocation = useStore(
944
+ {
945
+ url,
946
+ params: props.params ?? {},
947
+ isNavigating: false,
948
+ prevUrl: void 0
949
+ },
950
+ { deep: false }
951
+ );
952
+ const loadersData = props.loaders?.reduce(
953
+ (acc, { loader, data }) => {
954
+ acc[loader.__id] = data;
955
+ return acc;
956
+ },
957
+ {}
958
+ );
959
+ const loaderState = useStore(loadersData ?? {}, { deep: false });
1227
960
  const goto = props.goto ?? $(async () => {
1228
961
  console.warn("QwikRouterMockProvider: goto not provided");
1229
962
  });
1230
- const documentHead = useStore(createDocumentHead, {
1231
- deep: false
1232
- });
1233
- const content = useStore({
1234
- headings: void 0,
1235
- menu: void 0
1236
- }, {
1237
- deep: false
1238
- });
963
+ const documentHead = useStore(createDocumentHead, { deep: false });
964
+ const content = useStore(
965
+ {
966
+ headings: void 0,
967
+ menu: void 0
968
+ },
969
+ { deep: false }
970
+ );
1239
971
  const contentInternal = useSignal();
1240
972
  const actionState = useSignal();
1241
973
  useContextProvider(ContentContext, content);
@@ -1245,30 +977,53 @@ const QwikRouterMockProvider = component$((props) => {
1245
977
  useContextProvider(RouteNavigateContext, goto);
1246
978
  useContextProvider(RouteStateContext, loaderState);
1247
979
  useContextProvider(RouteActionContext, actionState);
1248
- useContextProvider(RouteInternalContext, routeInternal);
980
+ const actionsMocks = props.actions?.reduce(
981
+ (acc, { action, handler }) => {
982
+ acc[action.__id] = handler;
983
+ return acc;
984
+ },
985
+ {}
986
+ );
987
+ useTask$(async ({ track }) => {
988
+ const action = track(actionState);
989
+ if (!action?.resolve) {
990
+ return;
991
+ }
992
+ const mock = actionsMocks?.[action.id];
993
+ if (mock) {
994
+ const actionResult = await mock(action.data);
995
+ action.resolve(actionResult);
996
+ }
997
+ });
998
+ };
999
+ const QwikRouterMockProvider = component$((props) => {
1000
+ useQwikMockRouter(props);
1249
1001
  return /* @__PURE__ */ jsx(Slot, {});
1250
1002
  });
1251
1003
  const QwikCityMockProvider = QwikRouterMockProvider;
1004
+
1252
1005
  const RouterOutlet = component$(() => {
1253
1006
  const serverData = useServerData("containerAttributes");
1254
1007
  if (!serverData) {
1255
1008
  throw new Error("PrefetchServiceWorker component must be rendered on the server.");
1256
1009
  }
1257
- const { value } = useContext(ContentInternalContext);
1258
- if (value && value.length > 0) {
1259
- const contentsLen = value.length;
1010
+ const internalContext = useContext(ContentInternalContext);
1011
+ const contents = internalContext.value;
1012
+ if (contents && contents.length > 0) {
1013
+ const contentsLen = contents.length;
1260
1014
  let cmp = null;
1261
1015
  for (let i = contentsLen - 1; i >= 0; i--) {
1262
- if (value[i].default) {
1263
- cmp = jsx$1(value[i].default, {
1016
+ if (contents[i].default) {
1017
+ cmp = jsx$1(contents[i].default, {
1264
1018
  children: cmp
1265
1019
  });
1266
1020
  }
1267
1021
  }
1268
- return /* @__PURE__ */ jsxs(Fragment, {
1269
- children: [
1270
- cmp,
1271
- !__EXPERIMENTAL__.noSPA && /* @__PURE__ */ jsx("script", {
1022
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1023
+ cmp,
1024
+ !__EXPERIMENTAL__.noSPA && /* @__PURE__ */ jsx(
1025
+ "script",
1026
+ {
1272
1027
  "document:onQCInit$": spaInit,
1273
1028
  "document:onQInit$": sync$(() => {
1274
1029
  ((w, h) => {
@@ -1282,83 +1037,14 @@ const RouterOutlet = component$(() => {
1282
1037
  }
1283
1038
  })(window, history);
1284
1039
  })
1285
- })
1286
- ]
1287
- });
1040
+ }
1041
+ )
1042
+ ] });
1288
1043
  }
1289
1044
  return SkipRender;
1290
1045
  });
1291
- var store;
1292
- function getGlobalConfig(config2) {
1293
- return {
1294
- lang: config2?.lang ?? store?.lang,
1295
- message: config2?.message,
1296
- abortEarly: config2?.abortEarly ?? store?.abortEarly,
1297
- abortPipeEarly: config2?.abortPipeEarly ?? store?.abortPipeEarly
1298
- };
1299
- }
1300
- function getDotPath(issue) {
1301
- if (issue.path) {
1302
- let key = "";
1303
- for (const item of issue.path) {
1304
- if (typeof item.key === "string" || typeof item.key === "number") {
1305
- if (key) {
1306
- key += `.${item.key}`;
1307
- } else {
1308
- key += item.key;
1309
- }
1310
- } else {
1311
- return null;
1312
- }
1313
- }
1314
- return key;
1315
- }
1316
- return null;
1317
- }
1318
- function flatten(issues) {
1319
- const flatErrors = {};
1320
- for (const issue of issues) {
1321
- if (issue.path) {
1322
- const dotPath = getDotPath(issue);
1323
- if (dotPath) {
1324
- if (!flatErrors.nested) {
1325
- flatErrors.nested = {};
1326
- }
1327
- if (flatErrors.nested[dotPath]) {
1328
- flatErrors.nested[dotPath].push(issue.message);
1329
- } else {
1330
- flatErrors.nested[dotPath] = [issue.message];
1331
- }
1332
- } else {
1333
- if (flatErrors.other) {
1334
- flatErrors.other.push(issue.message);
1335
- } else {
1336
- flatErrors.other = [issue.message];
1337
- }
1338
- }
1339
- } else {
1340
- if (flatErrors.root) {
1341
- flatErrors.root.push(issue.message);
1342
- } else {
1343
- flatErrors.root = [issue.message];
1344
- }
1345
- }
1346
- }
1347
- return flatErrors;
1348
- }
1349
- async function safeParseAsync(schema, input, config2) {
1350
- const dataset = await schema._run(
1351
- { typed: false, value: input },
1352
- getGlobalConfig(config2)
1353
- );
1354
- return {
1355
- typed: dataset.typed,
1356
- success: !dataset.issues,
1357
- output: dataset.value,
1358
- issues: dataset.issues
1359
- };
1360
- }
1361
- const routeActionQrl = (actionQrl, ...rest) => {
1046
+
1047
+ const routeActionQrl = ((actionQrl, ...rest) => {
1362
1048
  const { id, validators } = getValidators(rest, actionQrl);
1363
1049
  function action() {
1364
1050
  const loc = useLocation();
@@ -1424,16 +1110,15 @@ Action.run() can only be called on the browser, for example when a user clicks a
1424
1110
  if (form.getAttribute("data-spa-reset") === "true") {
1425
1111
  form.reset();
1426
1112
  }
1427
- const detail = {
1428
- status,
1429
- value: result
1430
- };
1431
- form.dispatchEvent(new CustomEvent("submitcompleted", {
1432
- bubbles: false,
1433
- cancelable: false,
1434
- composed: false,
1435
- detail
1436
- }));
1113
+ const detail = { status, value: result };
1114
+ form.dispatchEvent(
1115
+ new CustomEvent("submitcompleted", {
1116
+ bubbles: false,
1117
+ cancelable: false,
1118
+ composed: false,
1119
+ detail
1120
+ })
1121
+ );
1437
1122
  }
1438
1123
  return {
1439
1124
  status,
@@ -1450,8 +1135,8 @@ Action.run() can only be called on the browser, for example when a user clicks a
1450
1135
  action.__id = id;
1451
1136
  Object.freeze(action);
1452
1137
  return action;
1453
- };
1454
- const globalActionQrl = (actionQrl, ...rest) => {
1138
+ });
1139
+ const globalActionQrl = ((actionQrl, ...rest) => {
1455
1140
  const action = routeActionQrl(actionQrl, ...rest);
1456
1141
  if (isServer) {
1457
1142
  if (typeof globalThis._qwikActionsMap === "undefined") {
@@ -1460,40 +1145,48 @@ const globalActionQrl = (actionQrl, ...rest) => {
1460
1145
  globalThis._qwikActionsMap.set(action.__id, action);
1461
1146
  }
1462
1147
  return action;
1463
- };
1464
- const routeAction$ = /* @__PURE__ */ implicit$FirstArg(routeActionQrl);
1465
- const globalAction$ = /* @__PURE__ */ implicit$FirstArg(globalActionQrl);
1466
- const routeLoaderQrl = (loaderQrl, ...rest) => {
1467
- const { id, validators } = getValidators(rest, loaderQrl);
1148
+ });
1149
+ const routeAction$ = /* @__PURE__ */ implicit$FirstArg(
1150
+ routeActionQrl
1151
+ );
1152
+ const globalAction$ = /* @__PURE__ */ implicit$FirstArg(
1153
+ globalActionQrl
1154
+ );
1155
+ const getValue = (obj) => obj.value;
1156
+ const routeLoaderQrl = ((loaderQrl, ...rest) => {
1157
+ const { id, validators, serializationStrategy } = getValidators(rest, loaderQrl);
1468
1158
  function loader() {
1469
- return useContext(RouteStateContext, (state) => {
1470
- if (!(id in state)) {
1471
- throw new Error(`routeLoader$ "${loaderQrl.getSymbol()}" was invoked in a route where it was not declared.
1159
+ const state = _resolveContextWithoutSequentialScope(RouteStateContext);
1160
+ if (!(id in state)) {
1161
+ throw new Error(`routeLoader$ "${loaderQrl.getSymbol()}" was invoked in a route where it was not declared.
1472
1162
  This is because the routeLoader$ was not exported in a 'layout.tsx' or 'index.tsx' file of the existing route.
1473
1163
  For more information check: https://qwik.dev/docs/route-loader/
1474
1164
 
1475
1165
  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.
1476
1166
  For more information check: https://qwik.dev/docs/re-exporting-loaders/`);
1477
- }
1478
- return _wrapStore(state, id);
1479
- });
1167
+ }
1168
+ const loaderData = state[id];
1169
+ untrack(getValue, loaderData);
1170
+ return loaderData;
1480
1171
  }
1481
1172
  loader.__brand = "server_loader";
1482
1173
  loader.__qrl = loaderQrl;
1483
1174
  loader.__validators = validators;
1484
1175
  loader.__id = id;
1176
+ loader.__serializationStrategy = serializationStrategy;
1177
+ loader.__expires = -1;
1485
1178
  Object.freeze(loader);
1486
1179
  return loader;
1487
- };
1180
+ });
1488
1181
  const routeLoader$ = /* @__PURE__ */ implicit$FirstArg(routeLoaderQrl);
1489
- const validatorQrl = (validator) => {
1182
+ const validatorQrl = ((validator) => {
1490
1183
  if (isServer) {
1491
1184
  return {
1492
1185
  validate: validator
1493
1186
  };
1494
1187
  }
1495
1188
  return void 0;
1496
- };
1189
+ });
1497
1190
  const validator$ = /* @__PURE__ */ implicit$FirstArg(validatorQrl);
1498
1191
  const flattenValibotIssues = (issues) => {
1499
1192
  return issues.reduce((acc, issue) => {
@@ -1516,7 +1209,9 @@ const flattenValibotIssues = (issues) => {
1516
1209
  };
1517
1210
  const valibotQrl = (qrl) => {
1518
1211
  if (!__EXPERIMENTAL__.valibot) {
1519
- throw new Error('Valibot is an experimental feature and is not enabled. Please enable the feature flag by adding `experimental: ["valibot"]` to your qwikVite plugin options.');
1212
+ throw new Error(
1213
+ 'Valibot is an experimental feature and is not enabled. Please enable the feature flag by adding `experimental: ["valibot"]` to your qwikVite plugin options.'
1214
+ );
1520
1215
  }
1521
1216
  if (isServer) {
1522
1217
  return {
@@ -1524,7 +1219,7 @@ const valibotQrl = (qrl) => {
1524
1219
  async validate(ev, inputData) {
1525
1220
  const schema = await qrl.resolve().then((obj) => typeof obj === "function" ? obj(ev) : obj);
1526
1221
  const data = inputData ?? await ev.parseBody();
1527
- const result = await safeParseAsync(schema, data);
1222
+ const result = await v.safeParseAsync(schema, data);
1528
1223
  if (result.success) {
1529
1224
  return {
1530
1225
  success: true,
@@ -1538,7 +1233,7 @@ const valibotQrl = (qrl) => {
1538
1233
  success: false,
1539
1234
  status: 400,
1540
1235
  error: {
1541
- formErrors: flatten(result.issues).root ?? [],
1236
+ formErrors: v.flatten(result.issues).root ?? [],
1542
1237
  fieldErrors: flattenValibotIssues(result.issues)
1543
1238
  }
1544
1239
  };
@@ -1550,9 +1245,7 @@ const valibotQrl = (qrl) => {
1550
1245
  };
1551
1246
  const valibot$ = /* @__PURE__ */ implicit$FirstArg(valibotQrl);
1552
1247
  const flattenZodIssues = (issues) => {
1553
- issues = Array.isArray(issues) ? issues : [
1554
- issues
1555
- ];
1248
+ issues = Array.isArray(issues) ? issues : [issues];
1556
1249
  return issues.reduce((acc, issue) => {
1557
1250
  const isExpectingArray = "expected" in issue && issue.expected === "array";
1558
1251
  const hasArrayType = issue.path.some((path) => typeof path === "number") || isExpectingArray;
@@ -1586,7 +1279,7 @@ const zodQrl = (qrl) => {
1586
1279
  }
1587
1280
  });
1588
1281
  const data = inputData ?? await ev.parseBody();
1589
- const result = await schema.safeParseAsync(data);
1282
+ const result = await withLocale(ev.locale(), () => schema.safeParseAsync(data));
1590
1283
  if (result.success) {
1591
1284
  return result;
1592
1285
  } else {
@@ -1611,7 +1304,7 @@ const zod$ = /* @__PURE__ */ implicit$FirstArg(zodQrl);
1611
1304
  const serverQrl = (qrl, options) => {
1612
1305
  if (isServer) {
1613
1306
  const captured = qrl.getCaptured();
1614
- if (captured && captured.length > 0 && !_getContextElement()) {
1307
+ if (captured && captured.length > 0 && !_getContextHostElement()) {
1615
1308
  throw new Error("For security reasons, we cannot serialize QRLs that capture lexical scope.");
1616
1309
  }
1617
1310
  }
@@ -1619,97 +1312,96 @@ const serverQrl = (qrl, options) => {
1619
1312
  const headers = options?.headers || {};
1620
1313
  const origin = options?.origin || "";
1621
1314
  const fetchOptions = options?.fetchOptions || {};
1622
- function rpc() {
1623
- return $(async function(...args) {
1624
- const abortSignal = args.length > 0 && args[0] instanceof AbortSignal ? args.shift() : void 0;
1625
- if (isServer) {
1626
- let requestEvent = globalThis.qcAsyncRequestStore?.getStore();
1627
- if (!requestEvent) {
1628
- const contexts = [
1629
- useQwikRouterEnv()?.ev,
1630
- this,
1631
- _getContextEvent()
1632
- ];
1633
- requestEvent = contexts.find((v2) => v2 && Object.prototype.hasOwnProperty.call(v2, "sharedMap") && Object.prototype.hasOwnProperty.call(v2, "cookie"));
1315
+ return $(async function(...args) {
1316
+ const abortSignal = args.length > 0 && args[0] instanceof AbortSignal ? args.shift() : void 0;
1317
+ if (isServer) {
1318
+ let requestEvent = _asyncRequestStore?.getStore();
1319
+ if (!requestEvent) {
1320
+ const contexts = [useQwikRouterEnv()?.ev, this, _getContextEvent()];
1321
+ requestEvent = contexts.find(
1322
+ (v2) => v2 && Object.prototype.hasOwnProperty.call(v2, "sharedMap") && Object.prototype.hasOwnProperty.call(v2, "cookie")
1323
+ );
1324
+ }
1325
+ return qrl.apply(requestEvent, isDev ? deepFreeze(args) : args);
1326
+ } else {
1327
+ const filteredArgs = args.map((arg) => {
1328
+ if (arg instanceof SubmitEvent && arg.target instanceof HTMLFormElement) {
1329
+ return new FormData(arg.target);
1330
+ } else if (arg instanceof Event) {
1331
+ return null;
1332
+ } else if (arg instanceof Node) {
1333
+ return null;
1634
1334
  }
1635
- return qrl.apply(requestEvent, isDev ? deepFreeze(args) : args);
1335
+ return arg;
1336
+ });
1337
+ const qrlHash = qrl.getHash();
1338
+ let query = "";
1339
+ const config = {
1340
+ ...fetchOptions,
1341
+ method,
1342
+ headers: {
1343
+ ...headers,
1344
+ "Content-Type": "application/qwik-json",
1345
+ Accept: "application/json, application/qwik-json, text/qwik-json-stream, text/plain",
1346
+ // Required so we don't call accidentally
1347
+ "X-QRL": qrlHash
1348
+ },
1349
+ signal: abortSignal
1350
+ };
1351
+ const captured = qrl.getCaptured();
1352
+ let toSend;
1353
+ if (captured?.length) {
1354
+ toSend = [filteredArgs, captured];
1636
1355
  } else {
1637
- const ctxElm = _getContextElement();
1638
- const filteredArgs = args.map((arg) => {
1639
- if (arg instanceof SubmitEvent && arg.target instanceof HTMLFormElement) {
1640
- return new FormData(arg.target);
1641
- } else if (arg instanceof Event) {
1642
- return null;
1643
- } else if (arg instanceof Node) {
1644
- return null;
1645
- }
1646
- return arg;
1647
- });
1648
- const qrlHash = qrl.getHash();
1649
- let query = "";
1650
- const config = {
1651
- ...fetchOptions,
1652
- method,
1653
- headers: {
1654
- ...headers,
1655
- "Content-Type": "application/qwik-json",
1656
- Accept: "application/json, application/qwik-json, text/qwik-json-stream, text/plain",
1657
- // Required so we don't call accidentally
1658
- "X-QRL": qrlHash
1659
- },
1660
- signal: abortSignal
1661
- };
1662
- const body = await _serialize([
1663
- qrl,
1664
- ...filteredArgs
1665
- ]);
1666
- if (method === "GET") {
1667
- query += `&${QDATA_KEY}=${encodeURIComponent(body)}`;
1668
- } else {
1669
- config.body = body;
1670
- }
1671
- const res = await fetch(`${origin}?${QFN_KEY}=${qrlHash}${query}`, config);
1672
- const contentType = res.headers.get("Content-Type");
1673
- if (res.ok && contentType === "text/qwik-json-stream" && res.body) {
1674
- return async function* () {
1675
- try {
1676
- for await (const result of deserializeStream(res.body, ctxElm ?? document.documentElement, abortSignal)) {
1677
- yield result;
1678
- }
1679
- } finally {
1680
- if (!abortSignal?.aborted) {
1681
- await res.body.cancel();
1682
- }
1356
+ toSend = filteredArgs.length ? [filteredArgs] : [];
1357
+ }
1358
+ const body = await _serialize(toSend);
1359
+ if (method === "GET") {
1360
+ query += `&${QDATA_KEY}=${encodeURIComponent(body)}`;
1361
+ } else {
1362
+ config.body = body;
1363
+ }
1364
+ const res = await fetch(`${origin}?${QFN_KEY}=${qrlHash}${query}`, config);
1365
+ const contentType = res.headers.get("Content-Type");
1366
+ if (res.ok && contentType === "text/qwik-json-stream" && res.body) {
1367
+ return (async function* () {
1368
+ try {
1369
+ for await (const result of deserializeStream(res.body, abortSignal)) {
1370
+ yield result;
1371
+ }
1372
+ } finally {
1373
+ if (!abortSignal?.aborted) {
1374
+ await res.body.cancel();
1683
1375
  }
1684
- }();
1685
- } else if (contentType === "application/qwik-json") {
1686
- const str = await res.text();
1687
- const [obj] = _deserialize(str, ctxElm ?? document.documentElement);
1688
- if (res.status >= 400) {
1689
- throw obj;
1690
- }
1691
- return obj;
1692
- } else if (contentType === "application/json") {
1693
- const obj = await res.json();
1694
- if (res.status >= 400) {
1695
- throw obj;
1696
- }
1697
- return obj;
1698
- } else if (contentType === "text/plain" || contentType === "text/html") {
1699
- const str = await res.text();
1700
- if (res.status >= 400) {
1701
- throw str;
1702
1376
  }
1703
- return str;
1377
+ })();
1378
+ } else if (contentType === "application/qwik-json") {
1379
+ const str = await res.text();
1380
+ const [obj] = _deserialize(str);
1381
+ if (res.status >= 400) {
1382
+ throw obj;
1383
+ }
1384
+ return obj;
1385
+ } else if (contentType === "application/json") {
1386
+ const obj = await res.json();
1387
+ if (res.status >= 400) {
1388
+ throw obj;
1389
+ }
1390
+ return obj;
1391
+ } else if (contentType === "text/plain" || contentType === "text/html") {
1392
+ const str = await res.text();
1393
+ if (res.status >= 400) {
1394
+ throw str;
1704
1395
  }
1396
+ return str;
1705
1397
  }
1706
- });
1707
- }
1708
- return rpc();
1398
+ }
1399
+ });
1709
1400
  };
1710
1401
  const server$ = /* @__PURE__ */ implicit$FirstArg(serverQrl);
1711
1402
  const getValidators = (rest, qrl) => {
1712
1403
  let id;
1404
+ let serializationStrategy = DEFAULT_LOADERS_SERIALIZATION_STRATEGY;
1713
1405
  const validators = [];
1714
1406
  if (rest.length === 1) {
1715
1407
  const options = rest[0];
@@ -1718,6 +1410,9 @@ const getValidators = (rest, qrl) => {
1718
1410
  validators.push(options);
1719
1411
  } else {
1720
1412
  id = options.id;
1413
+ if (options.serializationStrategy) {
1414
+ serializationStrategy = options.serializationStrategy;
1415
+ }
1721
1416
  if (options.validation) {
1722
1417
  validators.push(...options.validation);
1723
1418
  }
@@ -1738,10 +1433,11 @@ const getValidators = (rest, qrl) => {
1738
1433
  }
1739
1434
  return {
1740
1435
  validators: validators.reverse(),
1741
- id
1436
+ id,
1437
+ serializationStrategy
1742
1438
  };
1743
1439
  };
1744
- const deserializeStream = async function* (stream, ctxElm, abortSignal) {
1440
+ const deserializeStream = async function* (stream, abortSignal) {
1745
1441
  const reader = stream.getReader();
1746
1442
  try {
1747
1443
  let buffer = "";
@@ -1751,13 +1447,11 @@ const deserializeStream = async function* (stream, ctxElm, abortSignal) {
1751
1447
  if (result.done) {
1752
1448
  break;
1753
1449
  }
1754
- buffer += decoder.decode(result.value, {
1755
- stream: true
1756
- });
1450
+ buffer += decoder.decode(result.value, { stream: true });
1757
1451
  const lines = buffer.split(/\n/);
1758
1452
  buffer = lines.pop();
1759
1453
  for (const line of lines) {
1760
- const [deserializedData] = _deserialize(line, ctxElm);
1454
+ const [deserializedData] = _deserialize(line);
1761
1455
  yield deserializedData;
1762
1456
  }
1763
1457
  }
@@ -1765,95 +1459,109 @@ const deserializeStream = async function* (stream, ctxElm, abortSignal) {
1765
1459
  reader.releaseLock();
1766
1460
  }
1767
1461
  };
1768
- const ServiceWorkerRegister = (props) => /* @__PURE__ */ jsx("script", {
1769
- type: "module",
1770
- dangerouslySetInnerHTML: swRegister,
1771
- nonce: props.nonce
1772
- });
1462
+
1463
+ const ServiceWorkerRegister = (props) => /* @__PURE__ */ jsx("script", { type: "module", dangerouslySetInnerHTML: swRegister, nonce: props.nonce });
1464
+
1773
1465
  const Form = ({ action, spaReset, reloadDocument, onSubmit$, ...rest }, key) => {
1774
1466
  if (action) {
1775
1467
  const isArrayApi = Array.isArray(onSubmit$);
1776
1468
  if (isArrayApi) {
1777
- return jsx$1("form", {
1469
+ return jsx$1(
1470
+ "form",
1471
+ {
1472
+ ...rest,
1473
+ action: action.actionPath,
1474
+ "preventdefault:submit": !reloadDocument,
1475
+ onSubmit$: [
1476
+ ...onSubmit$,
1477
+ // action.submit "submitcompleted" event for onSubmitCompleted$ events
1478
+ !reloadDocument ? $((evt) => {
1479
+ if (!action.submitted) {
1480
+ return action.submit(evt);
1481
+ }
1482
+ }) : void 0
1483
+ ],
1484
+ method: "post",
1485
+ ["data-spa-reset"]: spaReset ? "true" : void 0
1486
+ },
1487
+ key
1488
+ );
1489
+ }
1490
+ return jsx$1(
1491
+ "form",
1492
+ {
1778
1493
  ...rest,
1779
1494
  action: action.actionPath,
1780
1495
  "preventdefault:submit": !reloadDocument,
1781
1496
  onSubmit$: [
1782
- ...onSubmit$,
1497
+ // Since v2, this fires before the action is executed so it can be prevented
1498
+ onSubmit$,
1783
1499
  // action.submit "submitcompleted" event for onSubmitCompleted$ events
1784
- !reloadDocument ? $((evt) => {
1785
- if (!action.submitted) {
1786
- return action.submit(evt);
1787
- }
1788
- }) : void 0
1500
+ !reloadDocument ? action.submit : void 0
1789
1501
  ],
1790
1502
  method: "post",
1791
1503
  ["data-spa-reset"]: spaReset ? "true" : void 0
1792
- }, key);
1793
- }
1794
- return jsx$1("form", {
1795
- ...rest,
1796
- action: action.actionPath,
1797
- "preventdefault:submit": !reloadDocument,
1798
- onSubmit$: [
1799
- // Since v2, this fires before the action is executed so it can be prevented
1800
- onSubmit$,
1801
- // action.submit "submitcompleted" event for onSubmitCompleted$ events
1802
- !reloadDocument ? action.submit : void 0
1803
- ],
1804
- method: "post",
1805
- ["data-spa-reset"]: spaReset ? "true" : void 0
1806
- }, key);
1504
+ },
1505
+ key
1506
+ );
1807
1507
  } else {
1808
- return /* @__PURE__ */ jsx(GetForm, {
1809
- spaReset,
1810
- reloadDocument,
1811
- onSubmit$,
1812
- ...rest
1813
- }, key);
1508
+ return /* @__PURE__ */ jsx(
1509
+ GetForm,
1510
+ {
1511
+ spaReset,
1512
+ reloadDocument,
1513
+ onSubmit$,
1514
+ ...rest
1515
+ },
1516
+ key
1517
+ );
1814
1518
  }
1815
1519
  };
1816
- const GetForm = component$(({ action: _0, spaReset, reloadDocument, onSubmit$, ...rest }) => {
1817
- const nav = useNavigate();
1818
- return /* @__PURE__ */ jsx("form", {
1819
- action: "get",
1820
- "preventdefault:submit": !reloadDocument,
1821
- "data-spa-reset": spaReset ? "true" : void 0,
1822
- ...rest,
1823
- onSubmit$: [
1824
- ...Array.isArray(onSubmit$) ? onSubmit$ : [
1825
- onSubmit$
1826
- ],
1827
- $(async (_evt, form) => {
1828
- const formData = new FormData(form);
1829
- const params = new URLSearchParams();
1830
- formData.forEach((value, key) => {
1831
- if (typeof value === "string") {
1832
- params.append(key, value);
1833
- }
1834
- });
1835
- await nav("?" + params.toString(), {
1836
- type: "form",
1837
- forceReload: true
1838
- });
1839
- }),
1840
- $((_evt, form) => {
1841
- if (form.getAttribute("data-spa-reset") === "true") {
1842
- form.reset();
1843
- }
1844
- form.dispatchEvent(new CustomEvent("submitcompleted", {
1845
- bubbles: false,
1846
- cancelable: false,
1847
- composed: false,
1848
- detail: {
1849
- status: 200
1850
- }
1851
- }));
1852
- })
1853
- ],
1854
- children: /* @__PURE__ */ jsx(Slot, {})
1855
- });
1856
- });
1520
+ const GetForm = component$(
1521
+ ({ action: _0, spaReset, reloadDocument, onSubmit$, ...rest }) => {
1522
+ const nav = useNavigate();
1523
+ return /* @__PURE__ */ jsx(
1524
+ "form",
1525
+ {
1526
+ action: "get",
1527
+ "preventdefault:submit": !reloadDocument,
1528
+ "data-spa-reset": spaReset ? "true" : void 0,
1529
+ ...rest,
1530
+ onSubmit$: [
1531
+ ...Array.isArray(onSubmit$) ? onSubmit$ : [onSubmit$],
1532
+ $(async (_evt, form) => {
1533
+ const formData = new FormData(form);
1534
+ const params = new URLSearchParams();
1535
+ formData.forEach((value, key) => {
1536
+ if (typeof value === "string") {
1537
+ params.append(key, value);
1538
+ }
1539
+ });
1540
+ await nav("?" + params.toString(), { type: "form", forceReload: true });
1541
+ }),
1542
+ $((_evt, form) => {
1543
+ if (form.getAttribute("data-spa-reset") === "true") {
1544
+ form.reset();
1545
+ }
1546
+ form.dispatchEvent(
1547
+ new CustomEvent("submitcompleted", {
1548
+ bubbles: false,
1549
+ cancelable: false,
1550
+ composed: false,
1551
+ detail: {
1552
+ status: 200
1553
+ }
1554
+ })
1555
+ );
1556
+ })
1557
+ // end of array
1558
+ ],
1559
+ children: /* @__PURE__ */ jsx(Slot, {})
1560
+ }
1561
+ );
1562
+ }
1563
+ );
1564
+
1857
1565
  const untypedAppUrl = function appUrl(route, params, paramsPrefix = "") {
1858
1566
  const path = route.split("/");
1859
1567
  for (let i = 0; i < path.length; i++) {
@@ -1890,39 +1598,46 @@ function omitProps(obj, keys) {
1890
1598
  }
1891
1599
  return omittedObj;
1892
1600
  }
1893
- export {
1894
- ErrorBoundary,
1895
- Form,
1896
- Link,
1897
- QWIK_CITY_SCROLLER,
1898
- QWIK_ROUTER_SCROLLER,
1899
- QwikCityMockProvider,
1900
- QwikCityProvider,
1901
- QwikRouterMockProvider,
1902
- QwikRouterProvider,
1903
- RouterOutlet,
1904
- ServiceWorkerRegister,
1905
- globalAction$,
1906
- globalActionQrl,
1907
- omitProps,
1908
- routeAction$,
1909
- routeActionQrl,
1910
- routeLoader$,
1911
- routeLoaderQrl,
1912
- server$,
1913
- serverQrl,
1914
- untypedAppUrl,
1915
- useContent,
1916
- useDocumentHead,
1917
- useLocation,
1918
- useNavigate,
1919
- usePreventNavigate$,
1920
- usePreventNavigateQrl,
1921
- valibot$,
1922
- valibotQrl,
1923
- validator$,
1924
- validatorQrl,
1925
- z2 as z,
1926
- zod$,
1927
- zodQrl
1601
+
1602
+ const createRenderer = (getOptions) => {
1603
+ return ((opts) => {
1604
+ const { jsx, options } = getOptions(opts);
1605
+ return renderToStream(jsx, options);
1606
+ });
1928
1607
  };
1608
+
1609
+ const DocumentHeadTags = component$((props) => {
1610
+ let head = useDocumentHead();
1611
+ if (props) {
1612
+ head = { ...head, ...props };
1613
+ }
1614
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1615
+ head.title && /* @__PURE__ */ jsx("title", { children: head.title }),
1616
+ head.meta.map((m) => /* @__PURE__ */ jsx("meta", { ...m })),
1617
+ head.links.map((l) => /* @__PURE__ */ jsx("link", { ...l })),
1618
+ head.styles.map((s) => {
1619
+ const props2 = s.props || s;
1620
+ return /* @__PURE__ */ createElement(
1621
+ "style",
1622
+ {
1623
+ ...props2,
1624
+ dangerouslySetInnerHTML: s.style || props2.dangerouslySetInnerHTML,
1625
+ key: s.key
1626
+ }
1627
+ );
1628
+ }),
1629
+ head.scripts.map((s) => {
1630
+ const props2 = s.props || s;
1631
+ return /* @__PURE__ */ createElement(
1632
+ "script",
1633
+ {
1634
+ ...props2,
1635
+ dangerouslySetInnerHTML: s.script || props2.dangerouslySetInnerHTML,
1636
+ key: s.key
1637
+ }
1638
+ );
1639
+ })
1640
+ ] });
1641
+ });
1642
+
1643
+ 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, useContent, useDocumentHead, useLocation, useNavigate, usePreventNavigate$, usePreventNavigateQrl, useQwikRouter, valibot$, valibotQrl, validator$, validatorQrl, zod$, zodQrl };