@qwik.dev/router 2.0.0-beta.1 → 2.0.0-beta.11

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 (149) hide show
  1. package/adapters/static/vite.d.ts +1 -1
  2. package/lib/adapters/azure-swa/vite/index-BqUeglYs.cjs +1 -0
  3. package/lib/adapters/azure-swa/vite/index-CBIchDYq.js +651 -0
  4. package/lib/adapters/azure-swa/vite/index-ClHGw5z1.js +6 -0
  5. package/lib/adapters/azure-swa/vite/index-CrwlB95_.js +22 -0
  6. package/lib/adapters/azure-swa/vite/index-DTIOTwZo.cjs +11 -0
  7. package/lib/adapters/azure-swa/vite/index-vQuPcef3.cjs +1 -0
  8. package/lib/adapters/azure-swa/vite/index.cjs +5 -96
  9. package/lib/adapters/azure-swa/vite/index.d.ts +2 -2
  10. package/lib/adapters/azure-swa/vite/index.mjs +205 -26
  11. package/lib/adapters/bun-server/vite/index-BqUeglYs.cjs +1 -0
  12. package/lib/adapters/bun-server/vite/index-CBIchDYq.js +651 -0
  13. package/lib/adapters/bun-server/vite/index-ClHGw5z1.js +6 -0
  14. package/lib/adapters/bun-server/vite/index-CrwlB95_.js +22 -0
  15. package/lib/adapters/bun-server/vite/index-DTIOTwZo.cjs +11 -0
  16. package/lib/adapters/bun-server/vite/index-vQuPcef3.cjs +1 -0
  17. package/lib/adapters/bun-server/vite/index.cjs +5 -50
  18. package/lib/adapters/bun-server/vite/index.d.ts +2 -2
  19. package/lib/adapters/bun-server/vite/index.mjs +200 -12
  20. package/lib/adapters/cloud-run/vite/index-BqUeglYs.cjs +1 -0
  21. package/lib/adapters/cloud-run/vite/index-CBIchDYq.js +651 -0
  22. package/lib/adapters/cloud-run/vite/index-ClHGw5z1.js +6 -0
  23. package/lib/adapters/cloud-run/vite/index-CrwlB95_.js +22 -0
  24. package/lib/adapters/cloud-run/vite/index-DTIOTwZo.cjs +11 -0
  25. package/lib/adapters/cloud-run/vite/index-vQuPcef3.cjs +1 -0
  26. package/lib/adapters/cloud-run/vite/index.cjs +5 -47
  27. package/lib/adapters/cloud-run/vite/index.d.ts +2 -2
  28. package/lib/adapters/cloud-run/vite/index.mjs +199 -11
  29. package/lib/adapters/cloudflare-pages/vite/index-Bg_9YkM5.js +22 -0
  30. package/lib/adapters/cloudflare-pages/vite/index-C1aDmh1S.cjs +1 -0
  31. package/lib/adapters/cloudflare-pages/vite/index-CHT9Y93A.js +254 -0
  32. package/lib/adapters/cloudflare-pages/vite/index-Ck7KvpK1.cjs +11 -0
  33. package/lib/adapters/cloudflare-pages/vite/index-ClHGw5z1.js +6 -0
  34. package/lib/adapters/cloudflare-pages/vite/index-Cp1cjAds.js +645 -0
  35. package/lib/adapters/cloudflare-pages/vite/index-D9RL9dvJ.cjs +5 -0
  36. package/lib/adapters/cloudflare-pages/vite/index-vQuPcef3.cjs +1 -0
  37. package/lib/adapters/cloudflare-pages/vite/index.cjs +1 -115
  38. package/lib/adapters/cloudflare-pages/vite/index.d.ts +2 -2
  39. package/lib/adapters/cloudflare-pages/vite/index.mjs +4 -78
  40. package/lib/adapters/deno-server/vite/index-BqUeglYs.cjs +1 -0
  41. package/lib/adapters/deno-server/vite/index-CBIchDYq.js +651 -0
  42. package/lib/adapters/deno-server/vite/index-ClHGw5z1.js +6 -0
  43. package/lib/adapters/deno-server/vite/index-CrwlB95_.js +22 -0
  44. package/lib/adapters/deno-server/vite/index-DTIOTwZo.cjs +11 -0
  45. package/lib/adapters/deno-server/vite/index-vQuPcef3.cjs +1 -0
  46. package/lib/adapters/deno-server/vite/index.cjs +5 -62
  47. package/lib/adapters/deno-server/vite/index.d.ts +2 -2
  48. package/lib/adapters/deno-server/vite/index.mjs +202 -14
  49. package/lib/adapters/netlify-edge/vite/index-BqUeglYs.cjs +1 -0
  50. package/lib/adapters/netlify-edge/vite/index-CBIchDYq.js +651 -0
  51. package/lib/adapters/netlify-edge/vite/index-ClHGw5z1.js +6 -0
  52. package/lib/adapters/netlify-edge/vite/index-CrwlB95_.js +22 -0
  53. package/lib/adapters/netlify-edge/vite/index-DTIOTwZo.cjs +11 -0
  54. package/lib/adapters/netlify-edge/vite/index-vQuPcef3.cjs +1 -0
  55. package/lib/adapters/netlify-edge/vite/index.cjs +6 -129
  56. package/lib/adapters/netlify-edge/vite/index.d.ts +2 -2
  57. package/lib/adapters/netlify-edge/vite/index.mjs +244 -60
  58. package/lib/adapters/node-server/vite/index-BqUeglYs.cjs +1 -0
  59. package/lib/adapters/node-server/vite/index-CBIchDYq.js +651 -0
  60. package/lib/adapters/node-server/vite/index-ClHGw5z1.js +6 -0
  61. package/lib/adapters/node-server/vite/index-CrwlB95_.js +22 -0
  62. package/lib/adapters/node-server/vite/index-DTIOTwZo.cjs +11 -0
  63. package/lib/adapters/node-server/vite/index-vQuPcef3.cjs +1 -0
  64. package/lib/adapters/node-server/vite/index.cjs +5 -50
  65. package/lib/adapters/node-server/vite/index.d.ts +2 -2
  66. package/lib/adapters/node-server/vite/index.mjs +200 -12
  67. package/lib/adapters/shared/vite/index-BqUeglYs.cjs +1 -0
  68. package/lib/adapters/shared/vite/index-CBIchDYq.js +651 -0
  69. package/lib/adapters/shared/vite/index-ClHGw5z1.js +6 -0
  70. package/lib/adapters/shared/vite/index-CrwlB95_.js +22 -0
  71. package/lib/adapters/shared/vite/index-DTIOTwZo.cjs +11 -0
  72. package/lib/adapters/shared/vite/index-vQuPcef3.cjs +1 -0
  73. package/lib/adapters/shared/vite/index.cjs +2 -375
  74. package/lib/adapters/shared/vite/index.d.ts +9 -15
  75. package/lib/adapters/shared/vite/index.mjs +159 -292
  76. package/lib/adapters/ssg/vite/index-BqUeglYs.cjs +1 -0
  77. package/lib/adapters/ssg/vite/index-CBIchDYq.js +651 -0
  78. package/lib/adapters/ssg/vite/index-ClHGw5z1.js +6 -0
  79. package/lib/adapters/ssg/vite/index-CrwlB95_.js +22 -0
  80. package/lib/adapters/ssg/vite/index-DTIOTwZo.cjs +11 -0
  81. package/lib/adapters/ssg/vite/index-vQuPcef3.cjs +1 -0
  82. package/lib/adapters/ssg/vite/index.cjs +5 -0
  83. package/lib/adapters/ssg/vite/index.d.ts +13 -0
  84. package/lib/adapters/ssg/vite/index.mjs +205 -0
  85. package/lib/adapters/vercel-edge/vite/index-BqUeglYs.cjs +1 -0
  86. package/lib/adapters/vercel-edge/vite/index-CBIchDYq.js +651 -0
  87. package/lib/adapters/vercel-edge/vite/index-ClHGw5z1.js +6 -0
  88. package/lib/adapters/vercel-edge/vite/index-CrwlB95_.js +22 -0
  89. package/lib/adapters/vercel-edge/vite/index-DTIOTwZo.cjs +11 -0
  90. package/lib/adapters/vercel-edge/vite/index-vQuPcef3.cjs +1 -0
  91. package/lib/adapters/vercel-edge/vite/index.cjs +5 -118
  92. package/lib/adapters/vercel-edge/vite/index.d.ts +2 -2
  93. package/lib/adapters/vercel-edge/vite/index.mjs +234 -51
  94. package/lib/index.d.ts +172 -50
  95. package/lib/index.qwik.cjs +370 -191
  96. package/lib/index.qwik.mjs +372 -193
  97. package/lib/middleware/aws-lambda/index.cjs +1 -0
  98. package/lib/middleware/aws-lambda/index.d.ts +3 -2
  99. package/lib/middleware/aws-lambda/index.mjs +27 -41
  100. package/lib/middleware/azure-swa/index.cjs +1 -0
  101. package/lib/middleware/azure-swa/index.mjs +46 -269
  102. package/lib/middleware/bun/index.cjs +1 -0
  103. package/lib/middleware/bun/index.mjs +68 -120
  104. package/lib/middleware/cloudflare-pages/index.cjs +1 -0
  105. package/lib/middleware/cloudflare-pages/index.mjs +48 -80
  106. package/lib/middleware/deno/index.cjs +1 -0
  107. package/lib/middleware/deno/index.mjs +63 -110
  108. package/lib/middleware/firebase/index.cjs +1 -0
  109. package/lib/middleware/firebase/index.mjs +16 -28
  110. package/lib/middleware/netlify-edge/index.cjs +1 -0
  111. package/lib/middleware/netlify-edge/index.mjs +36 -64
  112. package/lib/middleware/node/index.cjs +1 -314
  113. package/lib/middleware/node/index.mjs +116 -198
  114. package/lib/middleware/request-handler/index.cjs +11 -1607
  115. package/lib/middleware/request-handler/index.d.ts +63 -62
  116. package/lib/middleware/request-handler/index.mjs +890 -1333
  117. package/lib/middleware/vercel-edge/index.cjs +1 -0
  118. package/lib/middleware/vercel-edge/index.mjs +47 -82
  119. package/lib/modules.d.ts +4 -12
  120. package/lib/service-worker.cjs +1 -17
  121. package/lib/service-worker.mjs +5 -15
  122. package/lib/ssg/deno.cjs +1 -0
  123. package/lib/ssg/deno.mjs +6 -0
  124. package/lib/ssg/index-CBIchDYq.js +651 -0
  125. package/lib/ssg/index-ClHGw5z1.js +6 -0
  126. package/lib/ssg/index-DTIOTwZo.cjs +11 -0
  127. package/lib/ssg/index-vQuPcef3.cjs +1 -0
  128. package/lib/ssg/index.cjs +1 -0
  129. package/lib/{static → ssg}/index.d.ts +17 -17
  130. package/lib/ssg/index.mjs +22 -0
  131. package/lib/ssg/node.cjs +11 -0
  132. package/lib/ssg/node.mjs +651 -0
  133. package/lib/vite/index.cjs +28 -27431
  134. package/lib/vite/index.d.ts +19 -3
  135. package/lib/vite/index.mjs +1425 -27227
  136. package/modules.d.ts +4 -12
  137. package/package.json +50 -39
  138. package/ssg.d.ts +2 -0
  139. package/static.d.ts +1 -1
  140. package/lib/adapters/static/vite/index.cjs +0 -368
  141. package/lib/adapters/static/vite/index.d.ts +0 -10
  142. package/lib/adapters/static/vite/index.mjs +0 -331
  143. package/lib/static/deno.mjs +0 -8
  144. package/lib/static/index.cjs +0 -67
  145. package/lib/static/index.mjs +0 -48
  146. package/lib/static/node.cjs +0 -1124
  147. package/lib/static/node.mjs +0 -1086
  148. package/middleware/request-handler/generated/not-found-paths.ts +0 -7
  149. package/middleware/request-handler/generated/static-paths.ts +0 -35
@@ -1,11 +1,12 @@
1
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";
2
+ import { component$, useErrorBoundary, useOnWindow, $, Slot, createAsyncComputed$, isBrowser, createContextId, useContext, implicit$FirstArg, noSerialize, useVisibleTask$, useServerData, useSignal, untrack, sync$, isDev, withLocale, event$, useStyles$, isServer, useStore, useContextProvider, useTask$, getLocale, jsx as jsx$1, SkipRender, createElement } from "@qwik.dev/core";
3
3
  import { p } from "@qwik.dev/core/preloader";
4
- import { _deserialize, _weakSerialize, _getContextElement, _getQContainerElement, _waitUntilRendered, _wrapStore, _getContextEvent, _serialize } from "@qwik.dev/core/internal";
4
+ import { _deserialize, _UNINITIALIZED, _getContextContainer, SerializerSymbol, _getContextElement, _hasStoreEffects, _getQContainerElement, forceStoreEffects, _waitUntilRendered, _resolveContextWithoutSequentialScope, _getContextEvent, _serialize } from "@qwik.dev/core/internal";
5
5
  import * as qwikRouterConfig from "@qwik-router-config";
6
6
  import { z } from "zod";
7
7
  import { z as z2 } from "zod";
8
8
  import swRegister from "@qwik-router-sw-register";
9
+ import { renderToStream } from "@qwik.dev/core/server";
9
10
  const ErrorBoundary = component$((props) => {
10
11
  const store2 = useErrorBoundary();
11
12
  useOnWindow("qerror", $((e) => {
@@ -21,106 +22,25 @@ const ErrorBoundary = component$((props) => {
21
22
  const MODULE_CACHE = /* @__PURE__ */ new WeakMap();
22
23
  const CLIENT_DATA_CACHE = /* @__PURE__ */ new Map();
23
24
  const QACTION_KEY = "qaction";
25
+ const QLOADER_KEY = "qloaders";
24
26
  const QFN_KEY = "qfunc";
25
27
  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) => {
28
+ const Q_ROUTE = "q:route";
29
+ const DEFAULT_LOADERS_SERIALIZATION_STRATEGY = globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__ || "never";
30
+ const MAX_Q_DATA_RETRY_COUNT = 3;
31
+ const loadClientData = async (url, element, opts, retryCount = 0) => {
115
32
  const pagePathname = url.pathname;
116
33
  const pageSearch = url.search;
117
- const clientDataPath = getClientDataPath(pagePathname, pageSearch, opts?.action);
34
+ const clientDataPath = getClientDataPath(pagePathname, pageSearch, {
35
+ actionId: opts?.action?.id,
36
+ loaderIds: opts?.loaderIds
37
+ });
118
38
  let qData;
119
39
  if (!opts?.action) {
120
40
  qData = CLIENT_DATA_CACHE.get(clientDataPath);
121
41
  }
122
- if (opts?.prefetchSymbols !== false) {
123
- prefetchSymbols(pagePathname);
42
+ if (opts?.preloadRouteBundles !== false) {
43
+ preloadRouteBundles(pagePathname, 0.8);
124
44
  }
125
45
  let resolveFn;
126
46
  if (!qData) {
@@ -129,11 +49,17 @@ const loadClientData = async (url, element, opts) => {
129
49
  opts.action.data = void 0;
130
50
  }
131
51
  qData = fetch(clientDataPath, fetchOptions).then((rsp) => {
52
+ if (rsp.status === 404 && opts?.loaderIds && retryCount < MAX_Q_DATA_RETRY_COUNT) {
53
+ opts.loaderIds = void 0;
54
+ return loadClientData(url, element, opts, retryCount + 1);
55
+ }
132
56
  if (rsp.redirected) {
133
57
  const redirectedURL = new URL(rsp.url);
134
58
  const isQData = redirectedURL.pathname.endsWith("/q-data.json");
135
59
  if (!isQData || redirectedURL.origin !== location.origin) {
136
- location.href = redirectedURL.href;
60
+ if (!opts?.isPrefetch) {
61
+ location.href = redirectedURL.href;
62
+ }
137
63
  return;
138
64
  }
139
65
  }
@@ -204,11 +130,108 @@ const getFetchOptions = (action, noCache) => {
204
130
  method: "POST",
205
131
  body: JSON.stringify(actionData),
206
132
  headers: {
207
- "Content-Type": "application/json, charset=UTF-8"
133
+ "Content-Type": "application/json; charset=UTF-8"
208
134
  }
209
135
  };
210
136
  }
211
137
  };
138
+ const toPath = (url) => url.pathname + url.search + url.hash;
139
+ const toUrl = (url, baseUrl) => new URL(url, baseUrl.href);
140
+ const isSameOrigin = (a, b) => a.origin === b.origin;
141
+ const withSlash = (path) => path.endsWith("/") ? path : path + "/";
142
+ const isSamePathname = ({ pathname: a }, { pathname: b }) => {
143
+ const lDiff = Math.abs(a.length - b.length);
144
+ return lDiff === 0 ? a === b : lDiff === 1 && withSlash(a) === withSlash(b);
145
+ };
146
+ const isSameSearchQuery = (a, b) => a.search === b.search;
147
+ const isSamePath = (a, b) => isSameSearchQuery(a, b) && isSamePathname(a, b);
148
+ const getClientDataPath = (pathname, pageSearch, options) => {
149
+ let search = pageSearch ?? "";
150
+ if (options?.actionId) {
151
+ search += (search ? "&" : "?") + QACTION_KEY + "=" + encodeURIComponent(options.actionId);
152
+ }
153
+ if (options?.loaderIds) {
154
+ for (const loaderId of options.loaderIds) {
155
+ search += (search ? "&" : "?") + QLOADER_KEY + "=" + encodeURIComponent(loaderId);
156
+ }
157
+ }
158
+ return pathname + (pathname.endsWith("/") ? "" : "/") + "q-data.json" + search;
159
+ };
160
+ const getClientNavPath = (props, baseUrl) => {
161
+ const href = props.href;
162
+ if (typeof href === "string" && typeof props.target !== "string" && !props.reload) {
163
+ try {
164
+ const linkUrl = toUrl(href.trim(), baseUrl.url);
165
+ const currentUrl = toUrl("", baseUrl.url);
166
+ if (isSameOrigin(linkUrl, currentUrl)) {
167
+ return toPath(linkUrl);
168
+ }
169
+ } catch (e) {
170
+ console.error(e);
171
+ }
172
+ } else if (props.reload) {
173
+ return toPath(toUrl("", baseUrl.url));
174
+ }
175
+ return null;
176
+ };
177
+ const shouldPreload = (clientNavPath, currentLoc) => {
178
+ if (clientNavPath) {
179
+ const prefetchUrl = toUrl(clientNavPath, currentLoc.url);
180
+ const currentUrl = toUrl("", currentLoc.url);
181
+ return !isSamePathname(prefetchUrl, currentUrl);
182
+ }
183
+ return false;
184
+ };
185
+ const isPromise = (value) => {
186
+ return value && typeof value.then === "function";
187
+ };
188
+ const createLoaderSignal = (loadersObject, loaderId, url, serializationStrategy, container) => {
189
+ return createAsyncComputed$(async () => {
190
+ if (isBrowser && loadersObject[loaderId] === _UNINITIALIZED) {
191
+ const data = await loadClientData(url, void 0, {
192
+ loaderIds: [
193
+ loaderId
194
+ ]
195
+ });
196
+ loadersObject[loaderId] = data?.loaders[loaderId] ?? _UNINITIALIZED;
197
+ }
198
+ return loadersObject[loaderId];
199
+ }, {
200
+ container,
201
+ serializationStrategy
202
+ });
203
+ };
204
+ const clientNavigate = (win, navType, fromURL, toURL, replaceState = false) => {
205
+ if (navType !== "popstate") {
206
+ const samePath = isSamePath(fromURL, toURL);
207
+ const sameHash = fromURL.hash === toURL.hash;
208
+ if (!samePath || !sameHash) {
209
+ const newState = {
210
+ _qRouterScroll: newScrollState()
211
+ };
212
+ if (replaceState) {
213
+ win.history.replaceState(newState, "", toPath(toURL));
214
+ } else {
215
+ win.history.pushState(newState, "", toPath(toURL));
216
+ }
217
+ }
218
+ }
219
+ };
220
+ const newScrollState = () => {
221
+ return {
222
+ x: 0,
223
+ y: 0,
224
+ w: 0,
225
+ h: 0
226
+ };
227
+ };
228
+ const preloadRouteBundles = (path, probability = 0.8) => {
229
+ if (isBrowser) {
230
+ path = path.endsWith("/") ? path : path + "/";
231
+ path = path.length > 1 && path.startsWith("/") ? path.slice(1) : path;
232
+ p(path, probability);
233
+ }
234
+ };
212
235
  const RouteStateContext = /* @__PURE__ */ createContextId("qc-s");
213
236
  const ContentContext = /* @__PURE__ */ createContextId("qc-c");
214
237
  const ContentInternalContext = /* @__PURE__ */ createContextId("qc-ic");
@@ -251,33 +274,38 @@ const Link = component$((props) => {
251
274
  }
252
275
  if (elm && elm.href) {
253
276
  const url = new URL(elm.href);
254
- prefetchSymbols(url.pathname);
277
+ preloadRouteBundles(url.pathname);
255
278
  if (elm.hasAttribute("data-prefetch")) {
256
279
  loadClientData(url, elm, {
257
- prefetchSymbols: false,
280
+ preloadRouteBundles: false,
258
281
  isPrefetch: true
259
282
  });
260
283
  }
261
284
  }
262
285
  }) : void 0;
263
- const preventDefault = clientNavPath ? sync$((event, target) => {
286
+ const preventDefault = clientNavPath ? sync$((event) => {
264
287
  if (!(event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {
265
288
  event.preventDefault();
266
289
  }
267
290
  }) : void 0;
268
- const handleClick = clientNavPath ? $(async (event, elm) => {
291
+ const handleClientSideNavigation = clientNavPath ? $((event, elm) => {
269
292
  if (event.defaultPrevented) {
270
293
  if (elm.href) {
271
294
  elm.setAttribute("aria-pressed", "true");
272
- await nav(elm.href, {
295
+ nav(elm.href, {
273
296
  forceReload: reload,
274
297
  replaceState,
275
298
  scroll
299
+ }).then(() => {
300
+ elm.removeAttribute("aria-pressed");
276
301
  });
277
- elm.removeAttribute("aria-pressed");
278
302
  }
279
303
  }
280
304
  }) : void 0;
305
+ const handlePreload = $((_, elm) => {
306
+ const url = new URL(elm.href);
307
+ preloadRouteBundles(url.pathname, 1);
308
+ });
281
309
  useVisibleTask$(({ track }) => {
282
310
  track(() => loc.url.pathname);
283
311
  const handler = linkProps.onQVisible$;
@@ -299,8 +327,9 @@ const Link = component$((props) => {
299
327
  ...linkProps,
300
328
  onClick$: [
301
329
  preventDefault,
330
+ handlePreload,
302
331
  onClick$,
303
- handleClick
332
+ handleClientSideNavigation
304
333
  ],
305
334
  "data-prefetch": prefetchData,
306
335
  onMouseOver$: [
@@ -316,8 +345,8 @@ const Link = component$((props) => {
316
345
  children: /* @__PURE__ */ jsx(Slot, {})
317
346
  });
318
347
  });
319
- const resolveHead = (endpoint, routeLocation, contentModules, locale) => {
320
- const head = createDocumentHead();
348
+ const resolveHead = (endpoint, routeLocation, contentModules, locale, defaults) => {
349
+ const head = createDocumentHead(defaults);
321
350
  const getData = (loaderOrAction) => {
322
351
  const id = loaderOrAction.__id;
323
352
  if (loaderOrAction.__brand === "server_loader") {
@@ -331,23 +360,31 @@ const resolveHead = (endpoint, routeLocation, contentModules, locale) => {
331
360
  }
332
361
  return data;
333
362
  };
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;
363
+ const fns = [];
364
+ for (const contentModule of contentModules) {
365
+ const contentModuleHead = contentModule?.head;
342
366
  if (contentModuleHead) {
343
367
  if (typeof contentModuleHead === "function") {
344
- resolveDocumentHead(head, withLocale(locale, () => contentModuleHead(headProps)));
368
+ fns.unshift(contentModuleHead);
345
369
  } else if (typeof contentModuleHead === "object") {
346
370
  resolveDocumentHead(head, contentModuleHead);
347
371
  }
348
372
  }
349
373
  }
350
- return headProps.head;
374
+ if (fns.length) {
375
+ const headProps = {
376
+ head,
377
+ withLocale: (fn) => withLocale(locale, fn),
378
+ resolveValue: getData,
379
+ ...routeLocation
380
+ };
381
+ withLocale(locale, () => {
382
+ for (const fn of fns) {
383
+ resolveDocumentHead(head, fn(headProps));
384
+ }
385
+ });
386
+ }
387
+ return head;
351
388
  };
352
389
  const resolveDocumentHead = (resolvedHead, updatedHead) => {
353
390
  if (typeof updatedHead.title === "string") {
@@ -373,13 +410,23 @@ const mergeArray = (existingArr, newArr) => {
373
410
  }
374
411
  }
375
412
  };
376
- const createDocumentHead = () => ({
377
- title: "",
378
- meta: [],
379
- links: [],
380
- styles: [],
381
- scripts: [],
382
- frontmatter: {}
413
+ const createDocumentHead = (defaults) => ({
414
+ title: defaults?.title || "",
415
+ meta: [
416
+ ...defaults?.meta || []
417
+ ],
418
+ links: [
419
+ ...defaults?.links || []
420
+ ],
421
+ styles: [
422
+ ...defaults?.styles || []
423
+ ],
424
+ scripts: [
425
+ ...defaults?.scripts || []
426
+ ],
427
+ frontmatter: {
428
+ ...defaults?.frontmatter
429
+ }
383
430
  });
384
431
  function matchRoute(route, path) {
385
432
  const routeIdx = startIdxSkipSlash(route);
@@ -389,6 +436,9 @@ function matchRoute(route, path) {
389
436
  return matchRoutePart(route, routeIdx, routeLength, path, pathIdx, pathLength);
390
437
  }
391
438
  function matchRoutePart(route, routeIdx, routeLength, path, pathIdx, pathLength) {
439
+ if (path.startsWith("/build/")) {
440
+ return null;
441
+ }
392
442
  let params = null;
393
443
  while (routeIdx < routeLength) {
394
444
  const routeCh = route.charCodeAt(routeIdx++);
@@ -490,26 +540,52 @@ function lastIndexOf(text, start, match, searchIdx, notFoundIdx) {
490
540
  }
491
541
  return idx > start ? idx : notFoundIdx;
492
542
  }
493
- const loadRoute = async (routes, menus, cacheModules, pathname) => {
543
+ var RouteDataProp = /* @__PURE__ */ (function(RouteDataProp2) {
544
+ RouteDataProp2[RouteDataProp2["RouteName"] = 0] = "RouteName";
545
+ RouteDataProp2[RouteDataProp2["Loaders"] = 1] = "Loaders";
546
+ RouteDataProp2[RouteDataProp2["OriginalPathname"] = 2] = "OriginalPathname";
547
+ RouteDataProp2[RouteDataProp2["RouteBundleNames"] = 3] = "RouteBundleNames";
548
+ return RouteDataProp2;
549
+ })({});
550
+ var MenuDataProp = /* @__PURE__ */ (function(MenuDataProp2) {
551
+ MenuDataProp2[MenuDataProp2["Pathname"] = 0] = "Pathname";
552
+ MenuDataProp2[MenuDataProp2["MenuLoader"] = 1] = "MenuLoader";
553
+ return MenuDataProp2;
554
+ })({});
555
+ const deepFreeze = (obj) => {
556
+ if (obj == null) {
557
+ return obj;
558
+ }
559
+ Object.getOwnPropertyNames(obj).forEach((prop) => {
560
+ const value = obj[prop];
561
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
562
+ deepFreeze(value);
563
+ }
564
+ });
565
+ return Object.freeze(obj);
566
+ };
567
+ const loadRoute = async (routes, menus, cacheModules, pathname, isInternal) => {
494
568
  if (!Array.isArray(routes)) {
495
569
  return null;
496
570
  }
497
571
  for (const routeData of routes) {
498
- const routeName = routeData[0];
572
+ const routeName = routeData[RouteDataProp.RouteName];
499
573
  const params = matchRoute(routeName, pathname);
500
574
  if (!params) {
501
575
  continue;
502
576
  }
503
- const loaders = routeData[1];
504
- const routeBundleNames = routeData[3];
577
+ const loaders = routeData[RouteDataProp.Loaders];
578
+ const routeBundleNames = routeData[RouteDataProp.RouteBundleNames];
505
579
  const modules = new Array(loaders.length);
506
580
  const pendingLoads = [];
507
581
  loaders.forEach((moduleLoader, i) => {
508
582
  loadModule(moduleLoader, pendingLoads, (routeModule) => modules[i] = routeModule, cacheModules);
509
583
  });
510
- const menuLoader = getMenuLoader(menus, pathname);
511
584
  let menu = void 0;
512
- loadModule(menuLoader, pendingLoads, (menuModule) => menu = menuModule?.default, cacheModules);
585
+ {
586
+ const menuLoader = getMenuLoader(menus, pathname);
587
+ loadModule(menuLoader, pendingLoads, (menuModule) => menu = menuModule?.default, cacheModules);
588
+ }
513
589
  if (pendingLoads.length > 0) {
514
590
  await Promise.all(pendingLoads);
515
591
  }
@@ -546,9 +622,9 @@ const loadModule = (moduleLoader, pendingLoads, moduleSetter, cacheModules) => {
546
622
  const getMenuLoader = (menus, pathname) => {
547
623
  if (menus) {
548
624
  pathname = pathname.endsWith("/") ? pathname : pathname + "/";
549
- const menu = menus.find((m) => m[0] === pathname || pathname.startsWith(m[0] + (pathname.endsWith("/") ? "" : "/")));
625
+ const menu = menus.find((m) => m[MenuDataProp.Pathname] === pathname || pathname.startsWith(m[MenuDataProp.Pathname]));
550
626
  if (menu) {
551
- return menu[1];
627
+ return menu[MenuDataProp.MenuLoader];
552
628
  }
553
629
  }
554
630
  };
@@ -740,8 +816,8 @@ const spaInit = event$((_, el) => {
740
816
  };
741
817
  win[scrollEnabled] = true;
742
818
  setTimeout(() => {
743
- addEventListener("popstate", win[initPopstate]);
744
- addEventListener("scroll", win[initScroll], {
819
+ win.addEventListener("popstate", win[initPopstate]);
820
+ win.addEventListener("scroll", win[initScroll], {
745
821
  passive: true
746
822
  });
747
823
  document.body.addEventListener("click", win[initAnchors]);
@@ -773,25 +849,15 @@ const startViewTransition = (params) => {
773
849
  params.update?.();
774
850
  }
775
851
  };
852
+ const transitionCss = "@layer qwik {\n @supports selector(html:active-view-transition-type(type)) {\n html:active-view-transition-type(qwik-navigation) {\n :root {\n view-transition-name: none;\n }\n }\n }\n @supports not selector(html:active-view-transition-type(type)) {\n :root {\n view-transition-name: none;\n }\n }\n}\n";
776
853
  const QWIK_CITY_SCROLLER = "_qCityScroller";
777
854
  const QWIK_ROUTER_SCROLLER = "_qRouterScroller";
778
855
  const preventNav = {};
779
856
  const internalState = {
780
857
  navCount: 0
781
858
  };
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
- `);
859
+ const useQwikRouter = (props) => {
860
+ useStyles$(transitionCss);
795
861
  const env = useQwikRouterEnv();
796
862
  if (!env?.params) {
797
863
  throw new Error(`Missing Qwik Router Env Data for help visit https://github.com/QwikDev/qwik/issues/6237`);
@@ -800,24 +866,40 @@ const QwikRouterProvider = component$((props) => {
800
866
  if (!urlEnv) {
801
867
  throw new Error(`Missing Qwik URL Env Data`);
802
868
  }
869
+ const serverHead = useServerData("documentHead");
803
870
  if (isServer) {
804
871
  if (env.ev.originalUrl.pathname !== env.ev.url.pathname && !__EXPERIMENTAL__.enableRequestRewrite) {
805
872
  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
873
  }
807
874
  }
808
875
  const url = new URL(urlEnv);
809
- const routeLocation = useStore({
876
+ const routeLocationTarget = {
810
877
  url,
811
878
  params: env.params,
812
879
  isNavigating: false,
813
880
  prevUrl: void 0
814
- }, {
881
+ };
882
+ const routeLocation = useStore(routeLocationTarget, {
815
883
  deep: false
816
884
  });
817
885
  const navResolver = {};
818
- const loaderState = _weakSerialize(useStore(env.response.loaders, {
819
- deep: false
820
- }));
886
+ const container = _getContextContainer();
887
+ const getSerializationStrategy = (loaderId) => {
888
+ return env.response.loadersSerializationStrategy.get(loaderId) || DEFAULT_LOADERS_SERIALIZATION_STRATEGY;
889
+ };
890
+ const loadersObject = {};
891
+ const loaderState = {};
892
+ for (const [key, value] of Object.entries(env.response.loaders)) {
893
+ loadersObject[key] = value;
894
+ loaderState[key] = createLoaderSignal(loadersObject, key, url, getSerializationStrategy(key), container);
895
+ }
896
+ loadersObject[SerializerSymbol] = (obj) => {
897
+ const loadersSerializationObject = {};
898
+ for (const [k, v] of Object.entries(obj)) {
899
+ loadersSerializationObject[k] = getSerializationStrategy(k) === "always" ? v : _UNINITIALIZED;
900
+ }
901
+ return loadersSerializationObject;
902
+ };
821
903
  const routeInternal = useSignal({
822
904
  type: "initial",
823
905
  dest: url,
@@ -825,7 +907,7 @@ const QwikRouterProvider = component$((props) => {
825
907
  replaceState: false,
826
908
  scroll: true
827
909
  });
828
- const documentHead = useStore(createDocumentHead);
910
+ const documentHead = useStore(() => createDocumentHead(serverHead));
829
911
  const content = useStore({
830
912
  headings: void 0,
831
913
  menu: void 0
@@ -910,7 +992,7 @@ const QwikRouterProvider = component$((props) => {
910
992
  let scroller = document.getElementById(QWIK_ROUTER_SCROLLER);
911
993
  if (!scroller) {
912
994
  scroller = document.getElementById(QWIK_CITY_SCROLLER);
913
- if (scroller) {
995
+ if (scroller && isDev) {
914
996
  console.warn(`Please update your scroller ID to "${QWIK_ROUTER_SCROLLER}" as "${QWIK_CITY_SCROLLER}" is deprecated and will be removed in V3`);
915
997
  }
916
998
  }
@@ -971,10 +1053,10 @@ const QwikRouterProvider = component$((props) => {
971
1053
  } else {
972
1054
  trackUrl = new URL(navigation.dest, location);
973
1055
  if (trackUrl.pathname.endsWith("/")) {
974
- if (!qwikRouterConfig.trailingSlash) {
1056
+ if (globalThis.__NO_TRAILING_SLASH__) {
975
1057
  trackUrl.pathname = trackUrl.pathname.slice(0, -1);
976
1058
  }
977
- } else if (qwikRouterConfig.trailingSlash) {
1059
+ } else if (!globalThis.__NO_TRAILING_SLASH__) {
978
1060
  trackUrl.pathname += "/";
979
1061
  }
980
1062
  let loadRoutePromise = loadRoute(qwikRouterConfig.routes, qwikRouterConfig.menus, qwikRouterConfig.cacheModules, trackUrl.pathname);
@@ -1016,25 +1098,38 @@ const QwikRouterProvider = component$((props) => {
1016
1098
  const [routeName, params, mods, menu] = loadedRoute;
1017
1099
  const contentModules = mods;
1018
1100
  const pageModule = contentModules[contentModules.length - 1];
1019
- const isRedirect = navType === "form" && !isSamePath(trackUrl, prevUrl);
1020
- if (navigation.dest.search && !isRedirect) {
1101
+ if (navigation.dest.search && !!isSamePath(trackUrl, prevUrl)) {
1021
1102
  trackUrl.search = navigation.dest.search;
1022
1103
  }
1104
+ let shouldForcePrevUrl = false;
1105
+ let shouldForceUrl = false;
1106
+ let shouldForceParams = false;
1023
1107
  if (!isSamePath(trackUrl, prevUrl)) {
1024
- routeLocation.prevUrl = prevUrl;
1108
+ if (_hasStoreEffects(routeLocation, "prevUrl")) {
1109
+ shouldForcePrevUrl = true;
1110
+ }
1111
+ routeLocationTarget.prevUrl = prevUrl;
1112
+ }
1113
+ if (routeLocationTarget.url !== trackUrl) {
1114
+ if (_hasStoreEffects(routeLocation, "url")) {
1115
+ shouldForceUrl = true;
1116
+ }
1117
+ routeLocationTarget.url = trackUrl;
1118
+ }
1119
+ if (routeLocationTarget.params !== params) {
1120
+ if (_hasStoreEffects(routeLocation, "params")) {
1121
+ shouldForceParams = true;
1122
+ }
1123
+ routeLocationTarget.params = params;
1025
1124
  }
1026
- routeLocation.url = trackUrl;
1027
- routeLocation.params = {
1028
- ...params
1029
- };
1030
1125
  routeInternal.untrackedValue = {
1031
1126
  type: navType,
1032
1127
  dest: trackUrl
1033
1128
  };
1034
- const resolvedHead = resolveHead(clientPageData, routeLocation, contentModules, locale);
1129
+ const resolvedHead = resolveHead(clientPageData, routeLocation, contentModules, locale, serverHead);
1035
1130
  content.headings = pageModule.headings;
1036
1131
  content.menu = menu;
1037
- contentInternal.value = noSerialize(contentModules);
1132
+ contentInternal.untrackedValue = noSerialize(contentModules);
1038
1133
  documentHead.links = resolvedHead.links;
1039
1134
  documentHead.meta = resolvedHead.meta;
1040
1135
  documentHead.styles = resolvedHead.styles;
@@ -1047,15 +1142,25 @@ const QwikRouterProvider = component$((props) => {
1047
1142
  scrollState = getScrollHistory();
1048
1143
  }
1049
1144
  const scroller = document.getElementById(QWIK_ROUTER_SCROLLER) ?? document.documentElement;
1050
- if (navigation.scroll && (!navigation.forceReload || !isSamePath(trackUrl, prevUrl)) && (navType === "link" || navType === "popstate") || isRedirect) {
1145
+ if (navigation.scroll && (!navigation.forceReload || !isSamePath(trackUrl, prevUrl)) && (navType === "link" || navType === "popstate") || navType === "form" && !isSamePath(trackUrl, prevUrl)) {
1051
1146
  document.__q_scroll_restore__ = () => restoreScroll(navType, trackUrl, prevUrl, scroller, scrollState);
1052
1147
  }
1053
1148
  const loaders = clientPageData?.loaders;
1054
- const win = window;
1055
1149
  if (loaders) {
1056
- Object.assign(loaderState, loaders);
1150
+ const container2 = _getContextContainer();
1151
+ for (const [key, value] of Object.entries(loaders)) {
1152
+ const signal = loaderState[key];
1153
+ const awaitedValue = await value;
1154
+ loadersObject[key] = awaitedValue;
1155
+ if (!signal) {
1156
+ loaderState[key] = createLoaderSignal(loadersObject, key, trackUrl, DEFAULT_LOADERS_SERIALIZATION_STRATEGY, container2);
1157
+ } else {
1158
+ signal.invalidate();
1159
+ }
1160
+ }
1057
1161
  }
1058
1162
  CLIENT_DATA_CACHE.clear();
1163
+ const win = window;
1059
1164
  if (!win._qRouterSPA) {
1060
1165
  win._qRouterSPA = true;
1061
1166
  history.scrollRestoration = "manual";
@@ -1166,10 +1271,11 @@ const QwikRouterProvider = component$((props) => {
1166
1271
  }
1167
1272
  const navigate = () => {
1168
1273
  clientNavigate(window, navType, prevUrl, trackUrl, replaceState);
1274
+ contentInternal.force();
1169
1275
  return _waitUntilRendered(elm);
1170
1276
  };
1171
1277
  const _waitNextPage = () => {
1172
- if (isServer || props.viewTransition === false) {
1278
+ if (isServer || props?.viewTransition === false) {
1173
1279
  return navigate();
1174
1280
  } else {
1175
1281
  const viewTransition = startViewTransition({
@@ -1185,14 +1291,23 @@ const QwikRouterProvider = component$((props) => {
1185
1291
  }
1186
1292
  };
1187
1293
  _waitNextPage().then(() => {
1188
- const container = _getQContainerElement(elm);
1189
- container.setAttribute("q:route", routeName);
1294
+ const container2 = _getQContainerElement(elm);
1295
+ container2.setAttribute(Q_ROUTE, routeName);
1190
1296
  const scrollState2 = currentScrollState(scroller);
1191
1297
  saveScrollHistory(scrollState2);
1192
1298
  win._qRouterScrollEnabled = true;
1193
1299
  if (isBrowser) {
1194
1300
  callRestoreScrollOnDocument();
1195
1301
  }
1302
+ if (shouldForcePrevUrl) {
1303
+ forceStoreEffects(routeLocation, "prevUrl");
1304
+ }
1305
+ if (shouldForceUrl) {
1306
+ forceStoreEffects(routeLocation, "url");
1307
+ }
1308
+ if (shouldForceParams) {
1309
+ forceStoreEffects(routeLocation, "params");
1310
+ }
1196
1311
  routeLocation.isNavigating = false;
1197
1312
  navResolver.r?.();
1198
1313
  });
@@ -1205,10 +1320,13 @@ const QwikRouterProvider = component$((props) => {
1205
1320
  run();
1206
1321
  }
1207
1322
  });
1323
+ };
1324
+ const QwikRouterProvider = component$((props) => {
1325
+ useQwikRouter(props);
1208
1326
  return /* @__PURE__ */ jsx(Slot, {});
1209
1327
  });
1210
1328
  const QwikCityProvider = QwikRouterProvider;
1211
- const QwikRouterMockProvider = component$((props) => {
1329
+ const useQwikMockRouter = (props) => {
1212
1330
  const urlEnv = props.url ?? "http://localhost/";
1213
1331
  const url = new URL(urlEnv);
1214
1332
  const routeLocation = useStore({
@@ -1219,7 +1337,7 @@ const QwikRouterMockProvider = component$((props) => {
1219
1337
  }, {
1220
1338
  deep: false
1221
1339
  });
1222
- const loaderState = useSignal({});
1340
+ const loaderState = {};
1223
1341
  const routeInternal = useSignal({
1224
1342
  type: "initial",
1225
1343
  dest: url
@@ -1246,6 +1364,9 @@ const QwikRouterMockProvider = component$((props) => {
1246
1364
  useContextProvider(RouteStateContext, loaderState);
1247
1365
  useContextProvider(RouteActionContext, actionState);
1248
1366
  useContextProvider(RouteInternalContext, routeInternal);
1367
+ };
1368
+ const QwikRouterMockProvider = component$((props) => {
1369
+ useQwikMockRouter(props);
1249
1370
  return /* @__PURE__ */ jsx(Slot, {});
1250
1371
  });
1251
1372
  const QwikCityMockProvider = QwikRouterMockProvider;
@@ -1254,13 +1375,14 @@ const RouterOutlet = component$(() => {
1254
1375
  if (!serverData) {
1255
1376
  throw new Error("PrefetchServiceWorker component must be rendered on the server.");
1256
1377
  }
1257
- const { value } = useContext(ContentInternalContext);
1258
- if (value && value.length > 0) {
1259
- const contentsLen = value.length;
1378
+ const internalContext = useContext(ContentInternalContext);
1379
+ const contents = internalContext.value;
1380
+ if (contents && contents.length > 0) {
1381
+ const contentsLen = contents.length;
1260
1382
  let cmp = null;
1261
1383
  for (let i = contentsLen - 1; i >= 0; i--) {
1262
- if (value[i].default) {
1263
- cmp = jsx$1(value[i].default, {
1384
+ if (contents[i].default) {
1385
+ cmp = jsx$1(contents[i].default, {
1264
1386
  children: cmp
1265
1387
  });
1266
1388
  }
@@ -1289,6 +1411,7 @@ const RouterOutlet = component$(() => {
1289
1411
  return SkipRender;
1290
1412
  });
1291
1413
  var store;
1414
+ // @__NO_SIDE_EFFECTS__
1292
1415
  function getGlobalConfig(config2) {
1293
1416
  return {
1294
1417
  lang: config2?.lang ?? store?.lang,
@@ -1297,6 +1420,7 @@ function getGlobalConfig(config2) {
1297
1420
  abortPipeEarly: config2?.abortPipeEarly ?? store?.abortPipeEarly
1298
1421
  };
1299
1422
  }
1423
+ // @__NO_SIDE_EFFECTS__
1300
1424
  function getDotPath(issue) {
1301
1425
  if (issue.path) {
1302
1426
  let key = "";
@@ -1315,11 +1439,12 @@ function getDotPath(issue) {
1315
1439
  }
1316
1440
  return null;
1317
1441
  }
1442
+ // @__NO_SIDE_EFFECTS__
1318
1443
  function flatten(issues) {
1319
1444
  const flatErrors = {};
1320
1445
  for (const issue of issues) {
1321
1446
  if (issue.path) {
1322
- const dotPath = getDotPath(issue);
1447
+ const dotPath = /* @__PURE__ */ getDotPath(issue);
1323
1448
  if (dotPath) {
1324
1449
  if (!flatErrors.nested) {
1325
1450
  flatErrors.nested = {};
@@ -1346,10 +1471,11 @@ function flatten(issues) {
1346
1471
  }
1347
1472
  return flatErrors;
1348
1473
  }
1474
+ // @__NO_SIDE_EFFECTS__
1349
1475
  async function safeParseAsync(schema, input, config2) {
1350
- const dataset = await schema._run(
1351
- { typed: false, value: input },
1352
- getGlobalConfig(config2)
1476
+ const dataset = await schema["~run"](
1477
+ { value: input },
1478
+ /* @__PURE__ */ getGlobalConfig(config2)
1353
1479
  );
1354
1480
  return {
1355
1481
  typed: dataset.typed,
@@ -1464,24 +1590,25 @@ const globalActionQrl = (actionQrl, ...rest) => {
1464
1590
  const routeAction$ = /* @__PURE__ */ implicit$FirstArg(routeActionQrl);
1465
1591
  const globalAction$ = /* @__PURE__ */ implicit$FirstArg(globalActionQrl);
1466
1592
  const routeLoaderQrl = (loaderQrl, ...rest) => {
1467
- const { id, validators } = getValidators(rest, loaderQrl);
1593
+ const { id, validators, serializationStrategy } = getValidators(rest, loaderQrl);
1468
1594
  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.
1595
+ const state = _resolveContextWithoutSequentialScope(RouteStateContext);
1596
+ if (!(id in state)) {
1597
+ throw new Error(`routeLoader$ "${loaderQrl.getSymbol()}" was invoked in a route where it was not declared.
1472
1598
  This is because the routeLoader$ was not exported in a 'layout.tsx' or 'index.tsx' file of the existing route.
1473
1599
  For more information check: https://qwik.dev/docs/route-loader/
1474
1600
 
1475
1601
  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
1602
  For more information check: https://qwik.dev/docs/re-exporting-loaders/`);
1477
- }
1478
- return _wrapStore(state, id);
1479
- });
1603
+ }
1604
+ untrack(() => state[id].value);
1605
+ return state[id];
1480
1606
  }
1481
1607
  loader.__brand = "server_loader";
1482
1608
  loader.__qrl = loaderQrl;
1483
1609
  loader.__validators = validators;
1484
1610
  loader.__id = id;
1611
+ loader.__serializationStrategy = serializationStrategy;
1485
1612
  Object.freeze(loader);
1486
1613
  return loader;
1487
1614
  };
@@ -1524,7 +1651,7 @@ const valibotQrl = (qrl) => {
1524
1651
  async validate(ev, inputData) {
1525
1652
  const schema = await qrl.resolve().then((obj) => typeof obj === "function" ? obj(ev) : obj);
1526
1653
  const data = inputData ?? await ev.parseBody();
1527
- const result = await safeParseAsync(schema, data);
1654
+ const result = await /* @__PURE__ */ safeParseAsync(schema, data);
1528
1655
  if (result.success) {
1529
1656
  return {
1530
1657
  success: true,
@@ -1538,7 +1665,7 @@ const valibotQrl = (qrl) => {
1538
1665
  success: false,
1539
1666
  status: 400,
1540
1667
  error: {
1541
- formErrors: flatten(result.issues).root ?? [],
1668
+ formErrors: (/* @__PURE__ */ flatten(result.issues)).root ?? [],
1542
1669
  fieldErrors: flattenValibotIssues(result.issues)
1543
1670
  }
1544
1671
  };
@@ -1586,7 +1713,7 @@ const zodQrl = (qrl) => {
1586
1713
  }
1587
1714
  });
1588
1715
  const data = inputData ?? await ev.parseBody();
1589
- const result = await schema.safeParseAsync(data);
1716
+ const result = await withLocale(ev.locale(), () => schema.safeParseAsync(data));
1590
1717
  if (result.success) {
1591
1718
  return result;
1592
1719
  } else {
@@ -1671,7 +1798,7 @@ const serverQrl = (qrl, options) => {
1671
1798
  const res = await fetch(`${origin}?${QFN_KEY}=${qrlHash}${query}`, config);
1672
1799
  const contentType = res.headers.get("Content-Type");
1673
1800
  if (res.ok && contentType === "text/qwik-json-stream" && res.body) {
1674
- return async function* () {
1801
+ return (async function* () {
1675
1802
  try {
1676
1803
  for await (const result of deserializeStream(res.body, ctxElm ?? document.documentElement, abortSignal)) {
1677
1804
  yield result;
@@ -1681,7 +1808,7 @@ const serverQrl = (qrl, options) => {
1681
1808
  await res.body.cancel();
1682
1809
  }
1683
1810
  }
1684
- }();
1811
+ })();
1685
1812
  } else if (contentType === "application/qwik-json") {
1686
1813
  const str = await res.text();
1687
1814
  const [obj] = _deserialize(str, ctxElm ?? document.documentElement);
@@ -1710,6 +1837,7 @@ const serverQrl = (qrl, options) => {
1710
1837
  const server$ = /* @__PURE__ */ implicit$FirstArg(serverQrl);
1711
1838
  const getValidators = (rest, qrl) => {
1712
1839
  let id;
1840
+ let serializationStrategy = DEFAULT_LOADERS_SERIALIZATION_STRATEGY;
1713
1841
  const validators = [];
1714
1842
  if (rest.length === 1) {
1715
1843
  const options = rest[0];
@@ -1718,6 +1846,9 @@ const getValidators = (rest, qrl) => {
1718
1846
  validators.push(options);
1719
1847
  } else {
1720
1848
  id = options.id;
1849
+ if (options.serializationStrategy) {
1850
+ serializationStrategy = options.serializationStrategy;
1851
+ }
1721
1852
  if (options.validation) {
1722
1853
  validators.push(...options.validation);
1723
1854
  }
@@ -1738,7 +1869,8 @@ const getValidators = (rest, qrl) => {
1738
1869
  }
1739
1870
  return {
1740
1871
  validators: validators.reverse(),
1741
- id
1872
+ id,
1873
+ serializationStrategy
1742
1874
  };
1743
1875
  };
1744
1876
  const deserializeStream = async function* (stream, ctxElm, abortSignal) {
@@ -1890,7 +2022,52 @@ function omitProps(obj, keys) {
1890
2022
  }
1891
2023
  return omittedObj;
1892
2024
  }
2025
+ const createRenderer = (getOptions) => {
2026
+ return (opts) => {
2027
+ const { jsx: jsx2, options } = getOptions(opts);
2028
+ return renderToStream(jsx2, options);
2029
+ };
2030
+ };
2031
+ const DocumentHeadTags = component$((props) => {
2032
+ let head = useDocumentHead();
2033
+ if (props) {
2034
+ head = {
2035
+ ...head,
2036
+ ...props
2037
+ };
2038
+ }
2039
+ return /* @__PURE__ */ jsxs(Fragment, {
2040
+ children: [
2041
+ head.title && /* @__PURE__ */ jsx("title", {
2042
+ children: head.title
2043
+ }),
2044
+ head.meta.map((m) => /* @__PURE__ */ jsx("meta", {
2045
+ ...m
2046
+ })),
2047
+ head.links.map((l) => /* @__PURE__ */ jsx("link", {
2048
+ ...l
2049
+ })),
2050
+ head.styles.map((s) => {
2051
+ const props2 = s.props || s;
2052
+ return /* @__PURE__ */ createElement("style", {
2053
+ ...props2,
2054
+ dangerouslySetInnerHTML: s.style || props2.dangerouslySetInnerHTML,
2055
+ key: s.key
2056
+ });
2057
+ }),
2058
+ head.scripts.map((s) => {
2059
+ const props2 = s.props || s;
2060
+ return /* @__PURE__ */ createElement("script", {
2061
+ ...props2,
2062
+ dangerouslySetInnerHTML: s.script || props2.dangerouslySetInnerHTML,
2063
+ key: s.key
2064
+ });
2065
+ })
2066
+ ]
2067
+ });
2068
+ });
1893
2069
  export {
2070
+ DocumentHeadTags,
1894
2071
  ErrorBoundary,
1895
2072
  Form,
1896
2073
  Link,
@@ -1902,6 +2079,7 @@ export {
1902
2079
  QwikRouterProvider,
1903
2080
  RouterOutlet,
1904
2081
  ServiceWorkerRegister,
2082
+ createRenderer,
1905
2083
  globalAction$,
1906
2084
  globalActionQrl,
1907
2085
  omitProps,
@@ -1918,6 +2096,7 @@ export {
1918
2096
  useNavigate,
1919
2097
  usePreventNavigate$,
1920
2098
  usePreventNavigateQrl,
2099
+ useQwikRouter,
1921
2100
  valibot$,
1922
2101
  valibotQrl,
1923
2102
  validator$,