@qwik.dev/router 2.0.0-beta.43 → 2.0.0-beta.47
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.
- package/lib/adapters/azure-swa/vite/index.d.ts +2 -2
- package/lib/adapters/azure-swa/vite/index.mjs +2 -1
- package/lib/adapters/bun-server/vite/index.d.ts +2 -2
- package/lib/adapters/bun-server/vite/index.mjs +2 -1
- package/lib/adapters/cloud-run/vite/index.d.ts +2 -2
- package/lib/adapters/cloud-run/vite/index.mjs +2 -1
- package/lib/adapters/cloudflare-pages/vite/index.d.ts +2 -2
- package/lib/adapters/cloudflare-pages/vite/index.mjs +2 -1
- package/lib/adapters/deno-server/vite/index.d.ts +2 -2
- package/lib/adapters/deno-server/vite/index.mjs +2 -1
- package/lib/adapters/netlify-edge/vite/index.d.ts +2 -2
- package/lib/adapters/netlify-edge/vite/index.mjs +2 -1
- package/lib/adapters/node-server/vite/index.d.ts +2 -2
- package/lib/adapters/node-server/vite/index.mjs +2 -1
- package/lib/adapters/shared/vite/index.d.ts +1 -1
- package/lib/adapters/shared/vite/index.mjs +36 -32
- package/lib/adapters/ssg/vite/index.d.ts +1 -1
- package/lib/adapters/ssg/vite/index.mjs +4 -2
- package/lib/adapters/vercel-edge/vite/index.d.ts +2 -2
- package/lib/adapters/vercel-edge/vite/index.mjs +18 -15
- package/lib/chunks/fs.mjs +28 -25
- package/lib/chunks/head.qwik.mjs +731 -448
- package/lib/chunks/http-error.qwik.mjs +8 -7
- package/lib/chunks/pathname.mjs +9 -8
- package/lib/chunks/request-path.mjs +8 -4
- package/lib/chunks/route-trie-key.mjs +10 -0
- package/lib/chunks/routes.mjs +14 -14
- package/lib/chunks/server-error.mjs +28 -6
- package/lib/chunks/{url.mjs → static-file.mjs} +12 -2
- package/lib/chunks/system.mjs +31 -25
- package/lib/chunks/user-response.mjs +455 -348
- package/lib/chunks/worker-thread.mjs +90 -88
- package/lib/index.d.ts +94 -63
- package/lib/index.qwik.mjs +615 -523
- package/lib/middleware/aws-lambda/index.mjs +6 -3
- package/lib/middleware/azure-swa/index.mjs +4 -2
- package/lib/middleware/bun/index.mjs +12 -12
- package/lib/middleware/cloudflare-pages/index.mjs +19 -4
- package/lib/middleware/deno/index.mjs +12 -12
- package/lib/middleware/firebase/index.mjs +4 -2
- package/lib/middleware/netlify-edge/index.mjs +4 -2
- package/lib/middleware/node/index.mjs +16 -15
- package/lib/middleware/request-handler/index.d.ts +102 -2
- package/lib/middleware/request-handler/index.mjs +30 -34
- package/lib/middleware/vercel-edge/index.mjs +4 -2
- package/lib/service-worker/index.mjs +2 -1
- package/lib/ssg/index.mjs +23 -18
- package/lib/vite/index.d.ts +1 -1
- package/lib/vite/index.mjs +669 -604
- package/package.json +5 -5
package/lib/index.qwik.mjs
CHANGED
|
@@ -1,36 +1,13 @@
|
|
|
1
1
|
import { t as ensureSlash } from "./chunks/pathname.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { SkipRender, Slot,
|
|
4
|
-
import
|
|
5
|
-
import { p } from "@qwik.dev/core/preloader";
|
|
6
|
-
import { _deserialize, _getContextContainer, _getContextHostElement, _hasStoreEffects, _serialize, _waitUntilRendered, forceStoreEffects } from "@qwik.dev/core/internal";
|
|
2
|
+
import { $ as RoutePreventNavigateContext, B as _setRouterConfig, C as getRequestEvent, F as routeLoader$, G as ContentContext, H as getRouterConfig, I as routeLoaderQrl, J as HttpStatusContext, K as ContentInternalContext, L as setLoaderSignalValue, M as prepareRouteLoaders, P as restoreRouteLoaders, Q as RouteNavigateContext, S as getModuleRouteLoaders, U as getRoutes, V as getBasePathname, W as getTrailingSlash, X as RouteLoaderCtxContext, Y as RouteActionContext, Z as RouteLocationContext, _ as commitRouteLoaders, a as isPromise, b as getClientRouteLoaders, c as shouldPreload, d as loadRoute, et as RouteStateContext, h as clearNavFetchCache, i as getClientNavPath, it as Q_ROUTE, k as isImmutableLoader, l as toPath, m as abortRouteLoaderNavigation, n as resolveHead, nt as QDATA_KEY, o as isSameOrigin, q as DocumentHeadContext, rt as QFN_KEY, s as isSamePath, t as createDocumentHead, tt as QACTION_KEY, u as toUrl, v as ensureRouteLoaderSignals, y as fetchRouteLoaderData, z as _getServiceWorkerUrl } from "./chunks/head.qwik.mjs";
|
|
3
|
+
import { SkipRender, Slot, _capturesObj, _fnSignal, _getConstProps, _getVarProps, _jsxSorted, _jsxSplit, _qrlSync, _restProps, _wrapProp, componentQrl, createComputedQrl, createElement, eventQrl, getLocale, implicit$FirstArg, inlinedQrl, isBrowser, isDev, isServer, noSerialize, untrack, useContext, useContextProvider, useServerData, useSignal, useStore, useTaskQrl, useVisibleTaskQrl, withLocale } from "@qwik.dev/core";
|
|
4
|
+
import { _deserialize, _getContextContainer, _getContextHostElement, _hasStoreEffects, _regInlinedQrl, _requestPreload, _serialize, _waitUntilRendered, forceStoreEffects } from "@qwik.dev/core/internal";
|
|
7
5
|
import { Fragment } from "@qwik.dev/core/jsx-runtime";
|
|
8
6
|
import * as v from "valibot";
|
|
9
7
|
import * as z$1 from "zod";
|
|
10
8
|
import { z } from "zod";
|
|
11
|
-
import swRegister from "@qwik-router-sw-register";
|
|
12
9
|
import { renderToStream } from "@qwik.dev/core/server";
|
|
13
10
|
/**
|
|
14
|
-
* Prefetch a route's loader data in parallel (fire-and-forget). The per-nav fetch map dedupes
|
|
15
|
-
* repeat hovers and shares the promise with the navigation's own fetch; the browser HTTP cache
|
|
16
|
-
* handles freshness. Immutable loaders are skipped: they download lazily on first actual read and
|
|
17
|
-
* are then browser-cached for the life of the deploy.
|
|
18
|
-
*/ var prefetchLoaderData = (loadedRoute, url, manifestHash) => {
|
|
19
|
-
if (!loadedRoute.$loaders$?.length || !loadedRoute.$loaderPaths$) return;
|
|
20
|
-
const immutableIds = new Set(getModuleRouteLoaders(loadedRoute.$mods$).filter((loader) => loader.__cacheControl === "immutable").map((loader) => loader.__id));
|
|
21
|
-
const basePath = qwikRouterConfig.basePathname ?? "/";
|
|
22
|
-
for (const hash of loadedRoute.$loaders$) {
|
|
23
|
-
if (immutableIds.has(hash)) continue;
|
|
24
|
-
let loaderPath = loadedRoute.$loaderPaths$[hash];
|
|
25
|
-
if (!loaderPath) continue;
|
|
26
|
-
if (basePath !== "/" && !loaderPath.startsWith(basePath)) loaderPath = basePath + loaderPath.slice(1);
|
|
27
|
-
fetchRouteLoaderData(hash, loaderPath, manifestHash, {
|
|
28
|
-
pageUrl: url,
|
|
29
|
-
basePath
|
|
30
|
-
}).catch(() => {});
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
/**
|
|
34
11
|
* Prefetch a route's JS bundles and optionally its loader data.
|
|
35
12
|
*
|
|
36
13
|
* Resolves the route from the trie to get the routeName (for the bundle graph preloader) and
|
|
@@ -42,34 +19,63 @@ import { renderToStream } from "@qwik.dev/core/server";
|
|
|
42
19
|
* @param probability - Bundle preload probability (0-1, default 0.8)
|
|
43
20
|
* @param manifestHash - Build manifest hash for loader URLs (from `useDocumentHead().manifestHash`)
|
|
44
21
|
* @param prefetchBundle - Whether to prefetch route JS bundles
|
|
45
|
-
*/
|
|
22
|
+
*/
|
|
23
|
+
async function prefetchRoute(url, prefetchData, probability = .8, manifestHash, prefetchBundle = true) {
|
|
46
24
|
if (!isBrowser || isDev) return;
|
|
47
25
|
try {
|
|
48
|
-
const
|
|
26
|
+
const { routes, cacheModules } = await getRouterConfig();
|
|
27
|
+
const loadedRoute = await loadRoute(routes, cacheModules, url.pathname);
|
|
49
28
|
if (!loadedRoute) return;
|
|
50
29
|
if (prefetchBundle) {
|
|
51
30
|
let routeName = loadedRoute.$routeName$;
|
|
52
31
|
routeName = ensureSlash(routeName);
|
|
53
32
|
if (routeName.length > 1 && routeName.startsWith("/")) routeName = routeName.slice(1);
|
|
54
|
-
|
|
33
|
+
_requestPreload(routeName, probability);
|
|
55
34
|
}
|
|
56
35
|
if (!prefetchData || !manifestHash) return;
|
|
57
36
|
prefetchLoaderData(loadedRoute, url, manifestHash);
|
|
58
37
|
} catch {}
|
|
59
38
|
}
|
|
60
|
-
/**
|
|
61
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Prefetch a route's loader data in parallel (fire-and-forget). The per-nav fetch map dedupes
|
|
41
|
+
* repeat hovers and shares the promise with the navigation's own fetch; the browser HTTP cache
|
|
42
|
+
* handles freshness. Immutable loaders are skipped: they download lazily on first actual read and
|
|
43
|
+
* are then browser-cached for the life of the deploy.
|
|
44
|
+
*/
|
|
45
|
+
var prefetchLoaderData = (loadedRoute, url, manifestHash) => {
|
|
46
|
+
if (!loadedRoute.$loaders$?.length || !loadedRoute.$loaderPaths$) return;
|
|
47
|
+
const immutableIds = new Set(getModuleRouteLoaders(loadedRoute.$mods$).filter((loader) => loader.__cacheControl === "immutable").map((loader) => loader.__id));
|
|
48
|
+
const basePath = getBasePathname();
|
|
49
|
+
for (const hash of loadedRoute.$loaders$) {
|
|
50
|
+
if (immutableIds.has(hash)) continue;
|
|
51
|
+
let loaderPath = loadedRoute.$loaderPaths$[hash];
|
|
52
|
+
if (!loaderPath) continue;
|
|
53
|
+
if (basePath !== "/" && !loaderPath.startsWith(basePath)) loaderPath = basePath + loaderPath.slice(1);
|
|
54
|
+
fetchRouteLoaderData(hash, loaderPath, manifestHash, {
|
|
55
|
+
pageUrl: url,
|
|
56
|
+
basePath
|
|
57
|
+
}).catch(() => {});
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
/** @public */
|
|
61
|
+
var useHttpStatus = () => useContext(HttpStatusContext).value;
|
|
62
|
+
/** @public */
|
|
63
|
+
var useContent = () => useContext(ContentContext);
|
|
62
64
|
/**
|
|
63
65
|
* Returns the document head for the current page. The generic type describes the front matter.
|
|
64
66
|
*
|
|
65
67
|
* @public
|
|
66
|
-
*/
|
|
67
|
-
|
|
68
|
-
/** @public */
|
|
69
|
-
|
|
68
|
+
*/
|
|
69
|
+
var useDocumentHead = () => useContext(DocumentHeadContext);
|
|
70
|
+
/** @public */
|
|
71
|
+
var useLocation = () => useContext(RouteLocationContext);
|
|
72
|
+
/** @public */
|
|
73
|
+
var useNavigate = () => useContext(RouteNavigateContext);
|
|
74
|
+
/** @internal Implementation of usePreventNavigate$ */
|
|
75
|
+
var usePreventNavigateQrl = (fn) => {
|
|
70
76
|
const registerPreventNav = useContext(RoutePreventNavigateContext);
|
|
71
77
|
useVisibleTaskQrl(/*#__PURE__*/ inlinedQrl(() => {
|
|
72
|
-
|
|
78
|
+
let fn = _capturesObj._[0], registerPreventNav = _capturesObj._[1];
|
|
73
79
|
return registerPreventNav(fn);
|
|
74
80
|
}, "usePreventNavigateQrl_useVisibleTask_BsYUaz9XhUs", [fn, registerPreventNav]));
|
|
75
81
|
};
|
|
@@ -106,26 +112,33 @@ import { renderToStream } from "@qwik.dev/core/server";
|
|
|
106
112
|
* you can show a dialog or just return `true` to prevent the navigation.
|
|
107
113
|
*
|
|
108
114
|
* @public
|
|
109
|
-
*/
|
|
115
|
+
*/
|
|
116
|
+
var usePreventNavigate$ = implicit$FirstArg(usePreventNavigateQrl);
|
|
110
117
|
var useAction = () => useContext(RouteActionContext);
|
|
111
118
|
var useQwikRouterEnv = () => noSerialize(useServerData("qwikrouter"));
|
|
112
|
-
/** @public */
|
|
119
|
+
/** @public */
|
|
120
|
+
var Link = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props) => {
|
|
113
121
|
const nav = useNavigate();
|
|
114
122
|
const loc = useLocation();
|
|
115
123
|
const head = useDocumentHead();
|
|
116
|
-
const originalHref = props.href;
|
|
117
124
|
const { onClick$, prefetch: prefetchProp, reload, replaceState, scroll, prefetchBundles: prefetchBundlesProp = "visible", prefetchData: prefetchDataProp = prefetchProp === "js" ? "off" : "intent", ...linkProps } = props;
|
|
118
125
|
const clientNavPath = untrack(getClientNavPath, {
|
|
119
126
|
...linkProps,
|
|
120
127
|
reload
|
|
121
128
|
}, loc);
|
|
122
|
-
linkProps.href = clientNavPath ||
|
|
129
|
+
linkProps.href = clientNavPath || props.href;
|
|
123
130
|
const isDepratedPrefetchDisabled = prefetchProp === false;
|
|
124
131
|
const shouldPrefetch = untrack(shouldPreload, clientNavPath, loc);
|
|
125
132
|
const shouldVisiblePrefetchBundles = !!clientNavPath && shouldPrefetch && !isDepratedPrefetchDisabled && (prefetchBundlesProp === "visible" || prefetchProp === "js" || prefetchProp === true);
|
|
126
133
|
const shouldVisiblePrefetchData = !!clientNavPath && shouldPrefetch && !isDepratedPrefetchDisabled && (prefetchDataProp === "visible" || prefetchProp === true);
|
|
127
|
-
const
|
|
128
|
-
|
|
134
|
+
const shouldPrefetchBundles = !!clientNavPath && prefetchBundlesProp !== "off" && shouldPrefetch && !isDepratedPrefetchDisabled;
|
|
135
|
+
const shouldPrefetchData = !!clientNavPath && prefetchDataProp !== "off" && shouldPrefetch && !isDepratedPrefetchDisabled;
|
|
136
|
+
const handleBundlePrefetch = shouldPrefetchBundles ? /*#__PURE__*/ inlinedQrl((_, elm) => {
|
|
137
|
+
if (navigator.connection?.saveData) return;
|
|
138
|
+
if (elm && elm.href) prefetchRoute(new URL(elm.href), false, .8);
|
|
139
|
+
}, "Link_component_handleBundlePrefetch_ZttUP0kLKj0") : null;
|
|
140
|
+
const handleDataPrefetch = shouldPrefetchData ? /*#__PURE__*/ inlinedQrl((_, elm) => {
|
|
141
|
+
let head = _capturesObj._[0];
|
|
129
142
|
if (navigator.connection?.saveData) return;
|
|
130
143
|
if (elm && elm.href) prefetchRoute(new URL(elm.href), true, .8, head.manifestHash, false);
|
|
131
144
|
}, "Link_component_handleDataPrefetch_lcd4O9LHbbA", [head]) : null;
|
|
@@ -133,15 +146,22 @@ var useQwikRouterEnv = () => noSerialize(useServerData("qwikrouter"));
|
|
|
133
146
|
if (!(event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) event.preventDefault();
|
|
134
147
|
}, "event=>{if(!(event.metaKey||event.ctrlKey||event.shiftKey||event.altKey)){event.preventDefault();}}") : null;
|
|
135
148
|
const prefetchData = /*#__PURE__*/ inlinedQrl(async (_, elm) => {
|
|
136
|
-
|
|
149
|
+
let handleDataPrefetch = _capturesObj._[0];
|
|
137
150
|
handleDataPrefetch?.(null, elm);
|
|
138
151
|
}, "Link_component_prefetchData_UwVx4NhHkSo", [handleDataPrefetch]);
|
|
139
152
|
const onEnterKeyDown = /*#__PURE__*/ inlinedQrl((event, element) => {
|
|
140
|
-
|
|
141
|
-
if (event.key
|
|
142
|
-
|
|
153
|
+
let handleBundlePrefetch = _capturesObj._[0], prefetchBundlesProp = _capturesObj._[1], prefetchData = _capturesObj._[2], prefetchDataProp = _capturesObj._[3];
|
|
154
|
+
if (event.key !== "Enter") return;
|
|
155
|
+
if (prefetchDataProp === "commit") prefetchData(null, element);
|
|
156
|
+
if (prefetchBundlesProp === "commit") handleBundlePrefetch?.(null, element);
|
|
157
|
+
}, "Link_component_onEnterKeyDown_z274ws00irY", [
|
|
158
|
+
handleBundlePrefetch,
|
|
159
|
+
prefetchBundlesProp,
|
|
160
|
+
prefetchData,
|
|
161
|
+
prefetchDataProp
|
|
162
|
+
]);
|
|
143
163
|
const handleClientSideNavigation = clientNavPath ? /*#__PURE__*/ inlinedQrl((event, elm) => {
|
|
144
|
-
|
|
164
|
+
let nav = _capturesObj._[0], reload = _capturesObj._[1], replaceState = _capturesObj._[2], scroll = _capturesObj._[3];
|
|
145
165
|
if (event.defaultPrevented) {
|
|
146
166
|
if (elm.href) {
|
|
147
167
|
elm.setAttribute("aria-pressed", "true");
|
|
@@ -160,34 +180,37 @@ var useQwikRouterEnv = () => noSerialize(useServerData("qwikrouter"));
|
|
|
160
180
|
replaceState,
|
|
161
181
|
scroll
|
|
162
182
|
]) : null;
|
|
163
|
-
const handlePreload = /*#__PURE__*/ inlinedQrl((_, elm) => {
|
|
164
|
-
prefetchRoute(new URL(elm.href), false, 1);
|
|
165
|
-
}, "Link_component_handlePreload_AAemwtuBjsE");
|
|
166
183
|
return /*#__PURE__*/ _jsxSplit("a", {
|
|
167
|
-
"q:link": !!clientNavPath,
|
|
168
|
-
...
|
|
169
|
-
...
|
|
184
|
+
..._getVarProps({ "q:link": !!clientNavPath }),
|
|
185
|
+
..._getConstProps({ "q:link": !!clientNavPath }),
|
|
186
|
+
...linkProps,
|
|
170
187
|
"data-q-prefetch": shouldVisiblePrefetchBundles && shouldVisiblePrefetchData ? "bd" : shouldVisiblePrefetchBundles ? "b" : shouldVisiblePrefetchData ? "d" : null,
|
|
171
188
|
"q-e:click": [
|
|
172
189
|
preventDefault,
|
|
173
|
-
|
|
190
|
+
/*#__PURE__*/ inlinedQrl((_, elm) => {
|
|
191
|
+
prefetchRoute(new URL(elm.href), false, 1);
|
|
192
|
+
}, "Link_component_handlePreload_AAemwtuBjsE"),
|
|
174
193
|
onClick$,
|
|
175
194
|
handleClientSideNavigation
|
|
176
195
|
],
|
|
177
|
-
"q-e:pointerenter": [
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
196
|
+
"q-e:pointerenter": [
|
|
197
|
+
linkProps.onPointerEnter$,
|
|
198
|
+
prefetchDataProp === "intent" ? prefetchData : null,
|
|
199
|
+
prefetchBundlesProp === "intent" ? handleBundlePrefetch : null
|
|
200
|
+
],
|
|
201
|
+
"q-e:focus": [
|
|
202
|
+
linkProps.onFocus$,
|
|
203
|
+
prefetchDataProp === "intent" ? prefetchData : null,
|
|
204
|
+
prefetchBundlesProp === "intent" ? handleBundlePrefetch : null
|
|
205
|
+
],
|
|
206
|
+
"q-e:pointerdown": [
|
|
207
|
+
linkProps.onPointerDown$,
|
|
208
|
+
prefetchDataProp === "commit" ? prefetchData : null,
|
|
209
|
+
prefetchBundlesProp === "commit" ? handleBundlePrefetch : null
|
|
210
|
+
],
|
|
211
|
+
"q-e:keydown": [linkProps.onKeyDown$, prefetchDataProp === "commit" || prefetchBundlesProp === "commit" ? onEnterKeyDown : null]
|
|
212
|
+
}, null, /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "xa_0"), 0, "xa_1");
|
|
182
213
|
}, "Link_component_VPmar9tb3t4"));
|
|
183
|
-
var newScrollState = () => {
|
|
184
|
-
return {
|
|
185
|
-
x: 0,
|
|
186
|
-
y: 0,
|
|
187
|
-
w: 0,
|
|
188
|
-
h: 0
|
|
189
|
-
};
|
|
190
|
-
};
|
|
191
214
|
var clientNavigate = (win, navType, fromURL, toURL, replaceState = false) => {
|
|
192
215
|
if (navType !== "popstate") {
|
|
193
216
|
const samePath = isSamePath(fromURL, toURL);
|
|
@@ -199,11 +222,19 @@ var clientNavigate = (win, navType, fromURL, toURL, replaceState = false) => {
|
|
|
199
222
|
}
|
|
200
223
|
}
|
|
201
224
|
};
|
|
225
|
+
var newScrollState = () => {
|
|
226
|
+
return {
|
|
227
|
+
x: 0,
|
|
228
|
+
y: 0,
|
|
229
|
+
w: 0,
|
|
230
|
+
h: 0
|
|
231
|
+
};
|
|
232
|
+
};
|
|
202
233
|
var preloadRouteBundles = (path, probability = .8) => {
|
|
203
234
|
if (isBrowser) {
|
|
204
235
|
path = ensureSlash(path);
|
|
205
236
|
path = path.length > 1 && path.startsWith("/") ? path.slice(1) : path;
|
|
206
|
-
|
|
237
|
+
_requestPreload(path, probability);
|
|
207
238
|
}
|
|
208
239
|
};
|
|
209
240
|
var prefetchedLinks = /* @__PURE__ */ new WeakSet();
|
|
@@ -211,6 +242,14 @@ var cleanupPrefetchObserver;
|
|
|
211
242
|
var resetLinkPrefetchState = () => {
|
|
212
243
|
prefetchedLinks = /* @__PURE__ */ new WeakSet();
|
|
213
244
|
};
|
|
245
|
+
var refreshLinkPrefetchObserver = (manifestHash) => {
|
|
246
|
+
resetLinkPrefetchState();
|
|
247
|
+
cleanupPrefetchObserver?.();
|
|
248
|
+
cleanupPrefetchObserver = createLinkPrefetchObserver(manifestHash);
|
|
249
|
+
};
|
|
250
|
+
var linkPrefetchInit = eventQrl(/*#__PURE__*/ inlinedQrl((_, element) => {
|
|
251
|
+
refreshLinkPrefetchObserver(element.closest("[q\\:manifest-hash]")?.getAttribute("q:manifest-hash") || void 0);
|
|
252
|
+
}, "linkPrefetchInit_event_hoZr9O26Irg"));
|
|
214
253
|
var createLinkPrefetchObserver = (manifestHash) => {
|
|
215
254
|
const anchors = document.querySelectorAll("a[q\\:link][data-q-prefetch]");
|
|
216
255
|
const prefetchAnchor = (anchor, observer) => {
|
|
@@ -242,20 +281,18 @@ var createLinkPrefetchObserver = (manifestHash) => {
|
|
|
242
281
|
observer.disconnect();
|
|
243
282
|
};
|
|
244
283
|
};
|
|
245
|
-
var refreshLinkPrefetchObserver = (manifestHash) => {
|
|
246
|
-
resetLinkPrefetchState();
|
|
247
|
-
cleanupPrefetchObserver?.();
|
|
248
|
-
cleanupPrefetchObserver = createLinkPrefetchObserver(manifestHash);
|
|
249
|
-
};
|
|
250
|
-
var linkPrefetchInit = eventQrl(/*#__PURE__*/ inlinedQrl((_, element) => {
|
|
251
|
-
refreshLinkPrefetchObserver(element.closest("[q\\:manifest-hash]")?.getAttribute("q:manifest-hash") || void 0);
|
|
252
|
-
}, "linkPrefetchInit_event_hoZr9O26Irg"));
|
|
253
284
|
function callRestoreScrollOnDocument() {
|
|
254
285
|
if (document.__q_scroll_restore__) {
|
|
255
286
|
document.__q_scroll_restore__();
|
|
256
287
|
document.__q_scroll_restore__ = void 0;
|
|
257
288
|
}
|
|
258
289
|
}
|
|
290
|
+
var restoreScroll = (type, toUrl, fromUrl, scroller, scrollState) => {
|
|
291
|
+
if (type === "popstate" && scrollState) scroller.scrollTo(scrollState.x, scrollState.y);
|
|
292
|
+
else if (type === "link" || type === "form") {
|
|
293
|
+
if (!hashScroll(toUrl, fromUrl)) scroller.scrollTo(0, 0);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
259
296
|
var hashScroll = (toUrl, fromUrl) => {
|
|
260
297
|
const elmId = toUrl.hash.slice(1);
|
|
261
298
|
const elm = elmId && document.getElementById(elmId);
|
|
@@ -265,12 +302,6 @@ var hashScroll = (toUrl, fromUrl) => {
|
|
|
265
302
|
} else if (!elm && toUrl.hash && isSamePath(toUrl, fromUrl)) return true;
|
|
266
303
|
return false;
|
|
267
304
|
};
|
|
268
|
-
var restoreScroll = (type, toUrl, fromUrl, scroller, scrollState) => {
|
|
269
|
-
if (type === "popstate" && scrollState) scroller.scrollTo(scrollState.x, scrollState.y);
|
|
270
|
-
else if (type === "link" || type === "form") {
|
|
271
|
-
if (!hashScroll(toUrl, fromUrl)) scroller.scrollTo(0, 0);
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
305
|
var currentScrollState = (elm) => {
|
|
275
306
|
return {
|
|
276
307
|
x: elm.scrollLeft,
|
|
@@ -411,7 +442,8 @@ var spa_init_default = eventQrl(/*#__PURE__*/ inlinedQrl((_, el) => {
|
|
|
411
442
|
* POSTs to the route URL with `qaction={actionId}` appended and `Accept: application/json`. The
|
|
412
443
|
* server runs the action and returns the action result, optionally with the loader hashes that
|
|
413
444
|
* should be invalidated.
|
|
414
|
-
*/
|
|
445
|
+
*/
|
|
446
|
+
async function submitAction(action, routeUrl) {
|
|
415
447
|
const pathBase = ensureSlash(routeUrl.pathname);
|
|
416
448
|
const searchParams = new URLSearchParams(routeUrl.search);
|
|
417
449
|
searchParams.set(QACTION_KEY, action.id);
|
|
@@ -433,15 +465,11 @@ var spa_init_default = eventQrl(/*#__PURE__*/ inlinedQrl((_, el) => {
|
|
|
433
465
|
}
|
|
434
466
|
};
|
|
435
467
|
const response = await fetch(url, fetchOptions);
|
|
436
|
-
if (response.redirected) {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
}
|
|
442
|
-
location.href = redirectedURL.href;
|
|
443
|
-
return;
|
|
444
|
-
}
|
|
468
|
+
if (response.redirected) return {
|
|
469
|
+
status: response.status,
|
|
470
|
+
result: void 0,
|
|
471
|
+
redirect: new URL(response.url)
|
|
472
|
+
};
|
|
445
473
|
if ((response.headers.get("content-type") || "").includes("json")) {
|
|
446
474
|
const text = await response.text();
|
|
447
475
|
const data = await _deserialize(text);
|
|
@@ -454,9 +482,11 @@ var spa_init_default = eventQrl(/*#__PURE__*/ inlinedQrl((_, el) => {
|
|
|
454
482
|
}
|
|
455
483
|
}
|
|
456
484
|
var qwik_view_transition_default = "@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}}}";
|
|
457
|
-
/** View transitions are opt-in and require browser support. */
|
|
485
|
+
/** View transitions are opt-in and require browser support. */
|
|
486
|
+
var shouldStartViewTransition = (viewTransition) => viewTransition === true && "startViewTransition" in document;
|
|
458
487
|
var VIEW_TRANSITION_STYLE_ID = "qwik-view-transition";
|
|
459
|
-
/** Inject the view-transition stylesheet once, only when a transition actually runs. */
|
|
488
|
+
/** Inject the view-transition stylesheet once, only when a transition actually runs. */
|
|
489
|
+
var ensureViewTransitionStyles = () => {
|
|
460
490
|
if (document.getElementById(VIEW_TRANSITION_STYLE_ID)) return;
|
|
461
491
|
const style = document.createElement("style");
|
|
462
492
|
style.id = VIEW_TRANSITION_STYLE_ID;
|
|
@@ -481,44 +511,17 @@ var startViewTransition = (params) => {
|
|
|
481
511
|
} else return { ready: params.update() };
|
|
482
512
|
};
|
|
483
513
|
/**
|
|
484
|
-
* Qwik Router Component
|
|
485
|
-
*
|
|
486
|
-
* This file contains the main Qwik Router component, which initializes the router and provides the
|
|
487
|
-
* necessary context for it to work. It also contains the logic for handling navigation, including
|
|
488
|
-
* updating the URL, managing scroll restoration, and resolving document head changes.
|
|
489
|
-
*
|
|
490
|
-
* Note: This component is designed to work both on the server and the client. During server-side
|
|
491
|
-
* rendering (SSR), it initializes the router state based on the URL and route data provided by the
|
|
492
|
-
* server environment. On the client, it handles navigation events and updates the router state
|
|
493
|
-
* accordingly.
|
|
494
|
-
*
|
|
495
|
-
* SSR is _required_ for the initial load.
|
|
496
|
-
*
|
|
497
|
-
* The flow of navigation is as follows:
|
|
498
|
-
*
|
|
499
|
-
* 1. During SSR, the server environment parses the initial URL and collects the route data.
|
|
500
|
-
* 2. It runs the middleware hooks (`onRequest`, `onGet`, `onPost`, etc.), and responds to q-loader,
|
|
501
|
-
* action$ and server$ requests.
|
|
502
|
-
* 3. If SSR is deemed appropriate, the route data is provided via `useServerData` and this component
|
|
503
|
-
* uses it to initialize the router contexts, register Tasks, and render the Slot. This component
|
|
504
|
-
* will never render again.
|
|
505
|
-
* 4. Then, slotted components like `<DocumentHeadTags />` and `<RouterOutlet />` can consume the route
|
|
506
|
-
* data to render the page.
|
|
507
|
-
* 5. On the client, when a navigation event occurs, this calls `goto()`, which updates the URL in the
|
|
508
|
-
* same tick, loads the route data and adjusts the router context.
|
|
509
|
-
* 6. The changed contexts trigger the slotted components to re-render with the new route data.
|
|
510
|
-
*
|
|
511
|
-
* Since the head data can depend on route loaders and they get their data asynchronously and can
|
|
512
|
-
* update without navigation, the head is resolved in a separate Task that tracks the relevant
|
|
513
|
-
* signals.
|
|
514
|
-
*/
|
|
515
|
-
/**
|
|
516
514
|
* @deprecated Use `QWIK_ROUTER_SCROLLER` instead (will be removed in V3)
|
|
517
515
|
* @public
|
|
518
|
-
*/
|
|
519
|
-
|
|
516
|
+
*/
|
|
517
|
+
var QWIK_CITY_SCROLLER = "_qCityScroller";
|
|
518
|
+
/** @public */
|
|
519
|
+
var QWIK_ROUTER_SCROLLER = "_qRouterScroller";
|
|
520
520
|
var preventNav = {};
|
|
521
|
-
var internalState = {
|
|
521
|
+
var internalState = {
|
|
522
|
+
navCount: 0,
|
|
523
|
+
attemptCount: 0
|
|
524
|
+
};
|
|
522
525
|
var getScroller = () => {
|
|
523
526
|
let scroller = document.getElementById(QWIK_ROUTER_SCROLLER);
|
|
524
527
|
if (!scroller) {
|
|
@@ -527,154 +530,13 @@ var getScroller = () => {
|
|
|
527
530
|
}
|
|
528
531
|
return scroller ?? document.documentElement;
|
|
529
532
|
};
|
|
530
|
-
/** @public */ var useQwikMockRouter = (props) => {
|
|
531
|
-
const urlEnv = props.url ?? "http://localhost/";
|
|
532
|
-
const url = new URL(urlEnv);
|
|
533
|
-
const routeLocation = useStore({
|
|
534
|
-
url,
|
|
535
|
-
params: props.params ?? {},
|
|
536
|
-
isNavigating: false,
|
|
537
|
-
prevUrl: void 0
|
|
538
|
-
}, { deep: false });
|
|
539
|
-
const loadersData = props.loaders?.reduce((acc, { loader, data }) => {
|
|
540
|
-
acc[loader.__id] = data;
|
|
541
|
-
return acc;
|
|
542
|
-
}, {});
|
|
543
|
-
const loadersState = useStore({}, { deep: false });
|
|
544
|
-
for (const [loaderId, data] of Object.entries(loadersData ?? {})) loadersState[loaderId] ||= createComputedQrl(/*#__PURE__*/ inlinedQrl(() => {
|
|
545
|
-
return _captures[0];
|
|
546
|
-
}, "useQwikMockRouter_createComputed_JL6bChMwwyc", [data]));
|
|
547
|
-
const goto = props.goto ?? /*#__PURE__*/ inlinedQrl(async () => {
|
|
548
|
-
console.warn("QwikRouterMockProvider: goto not provided");
|
|
549
|
-
}, "useQwikMockRouter_goto_aViHFxQ1a3s");
|
|
550
|
-
const documentHead = useStore(createDocumentHead, { deep: false });
|
|
551
|
-
const content = useStore({
|
|
552
|
-
headings: void 0,
|
|
553
|
-
menu: void 0
|
|
554
|
-
}, { deep: false });
|
|
555
|
-
const contentInternal = useSignal();
|
|
556
|
-
const actionState = useSignal();
|
|
557
|
-
const httpStatus = useSignal({
|
|
558
|
-
status: 200,
|
|
559
|
-
message: ""
|
|
560
|
-
});
|
|
561
|
-
useContextProvider(ContentContext, content);
|
|
562
|
-
useContextProvider(ContentInternalContext, contentInternal);
|
|
563
|
-
useContextProvider(DocumentHeadContext, documentHead);
|
|
564
|
-
useContextProvider(HttpStatusContext, httpStatus);
|
|
565
|
-
useContextProvider(RouteLocationContext, routeLocation);
|
|
566
|
-
useContextProvider(RouteNavigateContext, goto);
|
|
567
|
-
useContextProvider(RouteStateContext, loadersState);
|
|
568
|
-
useContextProvider(RouteActionContext, actionState);
|
|
569
|
-
const actionsMocks = props.actions?.reduce((acc, { action, handler }) => {
|
|
570
|
-
acc[action.__id] = handler;
|
|
571
|
-
return acc;
|
|
572
|
-
}, {});
|
|
573
|
-
useTaskQrl(/*#__PURE__*/ inlinedQrl(async ({ track }) => {
|
|
574
|
-
const actionState = _captures[0], actionsMocks = _captures[1];
|
|
575
|
-
const action = track(actionState);
|
|
576
|
-
if (!action?.resolve) return;
|
|
577
|
-
const mock = actionsMocks?.[action.id];
|
|
578
|
-
if (mock) {
|
|
579
|
-
const actionResult = await mock(action.data);
|
|
580
|
-
action.resolve(actionResult);
|
|
581
|
-
}
|
|
582
|
-
}, "useQwikMockRouter_useTask_tXTLR4tzCy0", [actionState, actionsMocks]));
|
|
583
|
-
};
|
|
584
|
-
/** @public */ var QwikRouterMockProvider = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props) => {
|
|
585
|
-
useQwikMockRouter(props);
|
|
586
|
-
return /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "5y_1");
|
|
587
|
-
}, "QwikRouterMockProvider_component_IN4dVpT0x74"));
|
|
588
|
-
/**
|
|
589
|
-
* @deprecated Use `useQwikMockRouter()` instead. Will be removed in V3
|
|
590
|
-
* @public
|
|
591
|
-
*/ var QwikCityMockProvider = QwikRouterMockProvider;
|
|
592
|
-
function initializeSPA(goto, scroller) {
|
|
593
|
-
if (!window._qRouterSPA) {
|
|
594
|
-
window._qRouterSPA = true;
|
|
595
|
-
history.scrollRestoration = "manual";
|
|
596
|
-
window.addEventListener("popstate", () => {
|
|
597
|
-
window._qRouterScrollEnabled = false;
|
|
598
|
-
clearTimeout(window._qRouterScrollDebounce);
|
|
599
|
-
goto(location.href, { type: "popstate" });
|
|
600
|
-
});
|
|
601
|
-
window.removeEventListener("popstate", window._qRouterInitPopstate);
|
|
602
|
-
window._qRouterInitPopstate = void 0;
|
|
603
|
-
if (!window._qRouterHistoryPatch) {
|
|
604
|
-
window._qRouterHistoryPatch = true;
|
|
605
|
-
const pushState = history.pushState;
|
|
606
|
-
const replaceState = history.replaceState;
|
|
607
|
-
const prepareState = (state) => {
|
|
608
|
-
if (state === null || typeof state === "undefined") state = {};
|
|
609
|
-
else if (state?.constructor !== Object) {
|
|
610
|
-
state = { _data: state };
|
|
611
|
-
if (isDev) 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`");
|
|
612
|
-
}
|
|
613
|
-
state._qRouterScroll = state._qRouterScroll || currentScrollState(scroller);
|
|
614
|
-
return state;
|
|
615
|
-
};
|
|
616
|
-
history.pushState = (state, title, url) => {
|
|
617
|
-
state = prepareState(state);
|
|
618
|
-
return pushState.call(history, state, title, url);
|
|
619
|
-
};
|
|
620
|
-
history.replaceState = (state, title, url) => {
|
|
621
|
-
state = prepareState(state);
|
|
622
|
-
return replaceState.call(history, state, title, url);
|
|
623
|
-
};
|
|
624
|
-
}
|
|
625
|
-
document.addEventListener("click", (event) => {
|
|
626
|
-
if (event.defaultPrevented) return;
|
|
627
|
-
const target = event.target.closest("a[href]");
|
|
628
|
-
if (target && !target.hasAttribute("preventdefault:click")) {
|
|
629
|
-
const href = target.getAttribute("href");
|
|
630
|
-
const prev = new URL(location.href);
|
|
631
|
-
const dest = new URL(href, prev);
|
|
632
|
-
if (isSameOrigin(dest, prev) && isSamePath(dest, prev)) {
|
|
633
|
-
event.preventDefault();
|
|
634
|
-
if (!dest.hash && !dest.href.endsWith("#")) {
|
|
635
|
-
if (dest.href !== prev.href) history.pushState(null, "", dest);
|
|
636
|
-
window._qRouterScrollEnabled = false;
|
|
637
|
-
clearTimeout(window._qRouterScrollDebounce);
|
|
638
|
-
saveScrollHistory({
|
|
639
|
-
...currentScrollState(scroller),
|
|
640
|
-
x: 0,
|
|
641
|
-
y: 0
|
|
642
|
-
});
|
|
643
|
-
location.reload();
|
|
644
|
-
return;
|
|
645
|
-
}
|
|
646
|
-
goto(target.getAttribute("href"));
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
});
|
|
650
|
-
document.removeEventListener("click", window._qRouterInitAnchors);
|
|
651
|
-
window._qRouterInitAnchors = void 0;
|
|
652
|
-
if (!window.navigation) {
|
|
653
|
-
document.addEventListener("visibilitychange", () => {
|
|
654
|
-
if (window._qRouterScrollEnabled && document.visibilityState === "hidden") saveScrollHistory(currentScrollState(scroller));
|
|
655
|
-
}, { passive: true });
|
|
656
|
-
document.removeEventListener("visibilitychange", window._qRouterInitVisibility);
|
|
657
|
-
window._qRouterInitVisibility = void 0;
|
|
658
|
-
}
|
|
659
|
-
window.addEventListener("scroll", () => {
|
|
660
|
-
if (!window._qRouterScrollEnabled) return;
|
|
661
|
-
clearTimeout(window._qRouterScrollDebounce);
|
|
662
|
-
window._qRouterScrollDebounce = setTimeout(() => {
|
|
663
|
-
saveScrollHistory(currentScrollState(scroller));
|
|
664
|
-
window._qRouterScrollDebounce = void 0;
|
|
665
|
-
}, 200);
|
|
666
|
-
}, { passive: true });
|
|
667
|
-
removeEventListener("scroll", window._qRouterInitScroll);
|
|
668
|
-
window._qRouterInitScroll = void 0;
|
|
669
|
-
spa_init_default.resolve();
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
533
|
/**
|
|
673
534
|
* @public
|
|
674
535
|
* This hook initializes Qwik Router, providing the necessary context for it to work.
|
|
675
536
|
*
|
|
676
537
|
* This hook should be used once, at the root of your application.
|
|
677
|
-
*/
|
|
538
|
+
*/
|
|
539
|
+
var useQwikRouter = (props) => {
|
|
678
540
|
if (!isServer) throw new Error("useQwikRouter can only run during SSR on the server. If you are seeing this, it means you are re-rendering the root of your application. Fix that or use the <QwikRouterProvider> component around the root of your application.");
|
|
679
541
|
const env = useQwikRouterEnv();
|
|
680
542
|
if (!env?.params) throw new Error(`Missing Qwik Router Env Data for help visit https://github.com/QwikDev/qwik/issues/6237`);
|
|
@@ -695,7 +557,7 @@ function initializeSPA(goto, scroller) {
|
|
|
695
557
|
routeLoaderCtx.manifestHash = manifestHash;
|
|
696
558
|
const loaderState = {};
|
|
697
559
|
const contentModulesForInit = env.loadedRoute.$mods$;
|
|
698
|
-
const loaders = ensureRouteLoaderSignals(contentModulesForInit, loaderState, routeLoaderCtx);
|
|
560
|
+
const loaders = ensureRouteLoaderSignals(contentModulesForInit, loaderState, routeLoaderCtx, env.ev);
|
|
699
561
|
for (const loader of loaders) if (loader.__id in env.loaderValues) {
|
|
700
562
|
const value = env.loaderValues[loader.__id];
|
|
701
563
|
setLoaderSignalValue(loaderState[loader.__id], value);
|
|
@@ -711,9 +573,10 @@ function initializeSPA(goto, scroller) {
|
|
|
711
573
|
});
|
|
712
574
|
const contentInternal = useSignal();
|
|
713
575
|
/**
|
|
714
|
-
* Non-serializable navigation context passed from the nav task to the
|
|
576
|
+
* Non-serializable navigation context passed from the nav task to the navigation task. Only the
|
|
715
577
|
* data that can't be derived from existing stores/signals.
|
|
716
|
-
*/
|
|
578
|
+
*/
|
|
579
|
+
const navContext = useSignal();
|
|
717
580
|
const httpStatus = useSignal({
|
|
718
581
|
status: env.response.status,
|
|
719
582
|
message: env.loadedRoute.$notFound$ ? "Not Found" : env.response.statusMessage ?? ""
|
|
@@ -736,7 +599,7 @@ function initializeSPA(goto, scroller) {
|
|
|
736
599
|
const registerPreventNav = /*#__PURE__*/ inlinedQrl((fn$) => {
|
|
737
600
|
if (!isBrowser) return;
|
|
738
601
|
preventNav.$handler$ ||= (event) => {
|
|
739
|
-
internalState.
|
|
602
|
+
internalState.attemptCount++;
|
|
740
603
|
if (!preventNav.$cbs$) return;
|
|
741
604
|
if ([...preventNav.$cbs$.values()].map((cb) => cb.resolved ? cb.resolved() : cb()).some(Boolean)) {
|
|
742
605
|
event.preventDefault();
|
|
@@ -763,8 +626,9 @@ function initializeSPA(goto, scroller) {
|
|
|
763
626
|
* Note: when goto is called, the address bar change must happen in the same tick for Safari to
|
|
764
627
|
* treat it as a user-initiated navigation and allow scroll restoration to work. For this reason,
|
|
765
628
|
* make sure to change the address bar before awaiting anything.
|
|
766
|
-
*/
|
|
767
|
-
|
|
629
|
+
*/
|
|
630
|
+
const goto = /*#__PURE__*/ inlinedQrl(async (path, opt) => {
|
|
631
|
+
let actionState = _capturesObj._[0], manifestHash = _capturesObj._[1], navResolver = _capturesObj._[2], routeInternal = _capturesObj._[3], routeLoaderCtx = _capturesObj._[4], routeLocation = _capturesObj._[5];
|
|
768
632
|
const { type = "link", forceReload = path === void 0, replaceState = false, scroll = true } = typeof opt === "object" ? opt : { forceReload: opt };
|
|
769
633
|
if (isBrowser && type === "link" && routeInternal.value.type === "initial") {
|
|
770
634
|
const url = new URL(window.location.href);
|
|
@@ -774,12 +638,11 @@ function initializeSPA(goto, scroller) {
|
|
|
774
638
|
const lastDest = routeInternal.value.dest;
|
|
775
639
|
const dest = path === void 0 ? lastDest : typeof path === "number" ? path : toUrl(path, routeLocation.url);
|
|
776
640
|
if (navResolver.p && !forceReload && typeof dest !== "number" && isSamePath(dest, lastDest) && dest.href === lastDest.href) return navResolver.p;
|
|
777
|
-
const
|
|
778
|
-
internalState.currentTransition?.skipTransition();
|
|
641
|
+
const attemptCount = ++internalState.attemptCount;
|
|
779
642
|
if (preventNav.$cbs$ && (forceReload || typeof dest === "number" || !isSamePath(dest, lastDest) || !isSameOrigin(dest, lastDest))) {
|
|
780
643
|
const prevents = await Promise.all([...preventNav.$cbs$.values()].map((cb) => cb(dest)));
|
|
781
|
-
if (
|
|
782
|
-
if (
|
|
644
|
+
if (attemptCount !== internalState.attemptCount || prevents.some(Boolean)) {
|
|
645
|
+
if (attemptCount === internalState.attemptCount && type === "popstate") history.pushState(null, "", lastDest);
|
|
783
646
|
return;
|
|
784
647
|
}
|
|
785
648
|
}
|
|
@@ -803,9 +666,15 @@ function initializeSPA(goto, scroller) {
|
|
|
803
666
|
routeInternal.value.dest = newUrl;
|
|
804
667
|
routeLocation.url = newUrl;
|
|
805
668
|
}
|
|
806
|
-
return;
|
|
669
|
+
return navResolver.p;
|
|
807
670
|
}
|
|
671
|
+
const navCount = ++internalState.navCount;
|
|
672
|
+
internalState.currentTransition?.skipTransition();
|
|
673
|
+
navResolver.cancel?.();
|
|
674
|
+
navResolver.cancel = void 0;
|
|
675
|
+
navResolver.r?.();
|
|
808
676
|
let historyUpdated = false;
|
|
677
|
+
if (isBrowser) getClientRouteLoaders(routeLoaderCtx, routeLocation.url.href);
|
|
809
678
|
if (isBrowser && type === "link" && !forceReload) {
|
|
810
679
|
const scroller = getScroller();
|
|
811
680
|
window._qRouterScrollEnabled = false;
|
|
@@ -814,9 +683,10 @@ function initializeSPA(goto, scroller) {
|
|
|
814
683
|
clientNavigate(window, type, new URL(location.href), dest, replaceState);
|
|
815
684
|
historyUpdated = true;
|
|
816
685
|
}
|
|
686
|
+
const wasNavigating = routeLocation.isNavigating;
|
|
817
687
|
routeLocation.isNavigating = true;
|
|
818
688
|
const container = isBrowser ? _getContextContainer() : void 0;
|
|
819
|
-
if (container) {
|
|
689
|
+
if (container && !wasNavigating) {
|
|
820
690
|
await _waitUntilRendered(container);
|
|
821
691
|
if (navCount !== internalState.navCount) return;
|
|
822
692
|
}
|
|
@@ -829,6 +699,7 @@ function initializeSPA(goto, scroller) {
|
|
|
829
699
|
scroll,
|
|
830
700
|
historyUpdated
|
|
831
701
|
};
|
|
702
|
+
if (wasNavigating) abortRouteLoaderNavigation(routeLoaderCtx);
|
|
832
703
|
if (isBrowser) prefetchRoute(dest, false, .8, manifestHash, true);
|
|
833
704
|
navResolver.p = new Promise((resolve) => {
|
|
834
705
|
navResolver.r = () => {
|
|
@@ -843,6 +714,7 @@ function initializeSPA(goto, scroller) {
|
|
|
843
714
|
manifestHash,
|
|
844
715
|
navResolver,
|
|
845
716
|
routeInternal,
|
|
717
|
+
routeLoaderCtx,
|
|
846
718
|
routeLocation
|
|
847
719
|
]);
|
|
848
720
|
useContextProvider(ContentContext, content);
|
|
@@ -858,10 +730,13 @@ function initializeSPA(goto, scroller) {
|
|
|
858
730
|
/**
|
|
859
731
|
* This is split in 3 tasks because we need to update the head once we figured out the route, and
|
|
860
732
|
* before we trigger the render, and we need to subscribe only head to loader signal updates
|
|
861
|
-
*/
|
|
862
|
-
|
|
733
|
+
*/
|
|
734
|
+
useTaskQrl(/*#__PURE__*/ inlinedQrl(async ({ track }) => {
|
|
735
|
+
let actionDataSignal = _capturesObj._[0], actionState = _capturesObj._[1], content = _capturesObj._[2], contentInternal = _capturesObj._[3], env = _capturesObj._[4], goto = _capturesObj._[5], httpStatus = _capturesObj._[6], loaderState = _capturesObj._[7], navContext = _capturesObj._[8], navResolver = _capturesObj._[9], routeInternal = _capturesObj._[10], routeLoaderCtx = _capturesObj._[11], routeLocation = _capturesObj._[12], routeLocationTarget = _capturesObj._[13];
|
|
863
736
|
const navigation = track(routeInternal);
|
|
864
737
|
const action = track(actionState);
|
|
738
|
+
action?.resolveDispatch?.();
|
|
739
|
+
if (action) action.resolveDispatch = void 0;
|
|
865
740
|
const prevUrl = routeLocation.url;
|
|
866
741
|
const navType = action ? "form" : navigation.type;
|
|
867
742
|
const replaceState = navigation.replaceState;
|
|
@@ -870,7 +745,6 @@ function initializeSPA(goto, scroller) {
|
|
|
870
745
|
let endpointResponse;
|
|
871
746
|
let actionData;
|
|
872
747
|
let actionLoaderHashes;
|
|
873
|
-
let shouldInvalidateActionLoaders = false;
|
|
874
748
|
let loadedRoute;
|
|
875
749
|
if (isServer) {
|
|
876
750
|
trackUrl = new URL(navigation.dest, routeLocation.url);
|
|
@@ -879,20 +753,42 @@ function initializeSPA(goto, scroller) {
|
|
|
879
753
|
actionData = endpointResponse;
|
|
880
754
|
} else {
|
|
881
755
|
trackUrl = new URL(navigation.dest, location);
|
|
756
|
+
const canceled = new Promise((resolve) => {
|
|
757
|
+
navResolver.cancel = () => resolve(void 0);
|
|
758
|
+
});
|
|
882
759
|
if (trackUrl.pathname.endsWith("/")) {
|
|
883
760
|
if (globalThis.__NO_TRAILING_SLASH__) trackUrl.pathname = trackUrl.pathname.slice(0, -1);
|
|
884
761
|
} else if (!globalThis.__NO_TRAILING_SLASH__) trackUrl.pathname = ensureSlash(trackUrl.pathname);
|
|
885
|
-
const loadRoutePromise =
|
|
762
|
+
const loadRoutePromise = getRouterConfig().then((config) => {
|
|
763
|
+
if (internalState.navCount !== navCountBefore) return;
|
|
764
|
+
return loadRoute(config.routes, config.cacheModules, trackUrl.pathname);
|
|
765
|
+
});
|
|
886
766
|
try {
|
|
887
|
-
|
|
767
|
+
const route = await Promise.race([loadRoutePromise, canceled]);
|
|
768
|
+
if (!route) return;
|
|
769
|
+
loadedRoute = route;
|
|
888
770
|
} catch (e) {
|
|
771
|
+
if (internalState.navCount !== navCountBefore) return;
|
|
772
|
+
const preparedNavCount = getClientRouteLoaders(routeLoaderCtx).navCount;
|
|
773
|
+
if (preparedNavCount !== void 0) restoreRouteLoaders(loaderState, routeLoaderCtx, preparedNavCount);
|
|
889
774
|
console.error(`Could not load route ${trackUrl.pathname}, reloading:`, e);
|
|
890
775
|
window.location.href = trackUrl.href;
|
|
891
776
|
return;
|
|
892
777
|
}
|
|
893
778
|
if (internalState.navCount !== navCountBefore) return;
|
|
894
779
|
if (action) {
|
|
895
|
-
const result = await submitAction(action, trackUrl)
|
|
780
|
+
const result = await Promise.race([submitAction(action, trackUrl).then((result) => {
|
|
781
|
+
if (result && action.resolve) {
|
|
782
|
+
action.resolve({
|
|
783
|
+
status: result.status,
|
|
784
|
+
result: result.result
|
|
785
|
+
});
|
|
786
|
+
action.resolve = void 0;
|
|
787
|
+
}
|
|
788
|
+
return result;
|
|
789
|
+
}), canceled]);
|
|
790
|
+
if (internalState.navCount !== navCountBefore || action !== actionState.untrackedValue) return;
|
|
791
|
+
navResolver.cancel = void 0;
|
|
896
792
|
if (!result) {
|
|
897
793
|
routeInternal.untrackedValue = {
|
|
898
794
|
type: navType,
|
|
@@ -900,15 +796,9 @@ function initializeSPA(goto, scroller) {
|
|
|
900
796
|
};
|
|
901
797
|
return;
|
|
902
798
|
}
|
|
903
|
-
if (action.resolve) {
|
|
904
|
-
action.resolve({
|
|
905
|
-
status: result.status,
|
|
906
|
-
result: result.result
|
|
907
|
-
});
|
|
908
|
-
action.resolve = void 0;
|
|
909
|
-
}
|
|
910
799
|
if (result.redirect) {
|
|
911
|
-
|
|
800
|
+
if (result.redirect instanceof URL) location.href = result.redirect.href;
|
|
801
|
+
else goto(result.redirect, { replaceState: true });
|
|
912
802
|
return;
|
|
913
803
|
}
|
|
914
804
|
actionData = {
|
|
@@ -917,19 +807,17 @@ function initializeSPA(goto, scroller) {
|
|
|
917
807
|
actionResult: result.result
|
|
918
808
|
};
|
|
919
809
|
actionLoaderHashes = result.loaderHashes;
|
|
920
|
-
shouldInvalidateActionLoaders = true;
|
|
921
810
|
}
|
|
811
|
+
navResolver.cancel = void 0;
|
|
922
812
|
}
|
|
923
813
|
const { $routeName$, $params$, $mods$, $menu$, $notFound$ } = loadedRoute;
|
|
924
814
|
const contentModules = $mods$;
|
|
925
815
|
if (!isServer) routeLoaderCtx.goto = noSerialize(goto);
|
|
926
|
-
|
|
927
|
-
if (
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
else for (const loader of routeLoaders) loaderState[loader.__id].invalidate(true);
|
|
932
|
-
}
|
|
816
|
+
let routeLoaders;
|
|
817
|
+
if (isServer) {
|
|
818
|
+
Object.assign(routeLoaderCtx.loaderPaths, loadedRoute.$loaderPaths$);
|
|
819
|
+
routeLoaders = ensureRouteLoaderSignals(contentModules, loaderState, routeLoaderCtx, env.ev);
|
|
820
|
+
} else routeLoaders = prepareRouteLoaders(contentModules, loaderState, routeLoaderCtx, loadedRoute.$loaderPaths$, trackUrl, prevUrl, navCountBefore, action ? actionLoaderHashes ?? null : void 0, action ?? navigation);
|
|
933
821
|
if (routeLoaders.length > 0) for (let i = 0; i < routeLoaders.length; i++) {
|
|
934
822
|
const loader = routeLoaders[i];
|
|
935
823
|
if (!isImmutableLoader(loader.__id)) loaderState[loader.__id].untrackedPending;
|
|
@@ -953,6 +841,7 @@ function initializeSPA(goto, scroller) {
|
|
|
953
841
|
message: "OK"
|
|
954
842
|
};
|
|
955
843
|
const pageModule = contentModules[contentModules.length - 1];
|
|
844
|
+
if (isSamePath(trackUrl, navigation.dest)) trackUrl.hash = navigation.dest.hash;
|
|
956
845
|
if (navigation.dest.search && !!isSamePath(trackUrl, prevUrl)) trackUrl.search = navigation.dest.search;
|
|
957
846
|
let shouldForcePrevUrl = false;
|
|
958
847
|
let shouldForceUrl = false;
|
|
@@ -1002,6 +891,7 @@ function initializeSPA(goto, scroller) {
|
|
|
1002
891
|
httpStatus,
|
|
1003
892
|
loaderState,
|
|
1004
893
|
navContext,
|
|
894
|
+
navResolver,
|
|
1005
895
|
routeInternal,
|
|
1006
896
|
routeLoaderCtx,
|
|
1007
897
|
routeLocation,
|
|
@@ -1012,9 +902,12 @@ function initializeSPA(goto, scroller) {
|
|
|
1012
902
|
* without re-running the navigation logic.
|
|
1013
903
|
*
|
|
1014
904
|
* Note that on the server these tasks run sequentially.
|
|
1015
|
-
*/
|
|
1016
|
-
|
|
905
|
+
*/
|
|
906
|
+
useTaskQrl(/*#__PURE__*/ inlinedQrl(({ track }) => {
|
|
907
|
+
let actionDataSignal = _capturesObj._[0], contentInternal = _capturesObj._[1], documentHead = _capturesObj._[2], loaderState = _capturesObj._[3], navContext = _capturesObj._[4], routeLocation = _capturesObj._[5], serverHead = _capturesObj._[6];
|
|
1017
908
|
const contentModules = track(contentInternal);
|
|
909
|
+
const nav = navContext.untrackedValue;
|
|
910
|
+
if (!isServer && routeLocation.isNavigating && nav && nav.navCount !== internalState.navCount) return;
|
|
1018
911
|
if (!contentModules) return;
|
|
1019
912
|
const actionData = track(actionDataSignal);
|
|
1020
913
|
let head;
|
|
@@ -1036,11 +929,13 @@ function initializeSPA(goto, scroller) {
|
|
|
1036
929
|
contentInternal,
|
|
1037
930
|
documentHead,
|
|
1038
931
|
loaderState,
|
|
932
|
+
navContext,
|
|
1039
933
|
routeLocation,
|
|
1040
934
|
serverHead
|
|
1041
935
|
]), { deferUpdates: isServer });
|
|
1042
|
-
/** Actual navigation */
|
|
1043
|
-
|
|
936
|
+
/** Actual navigation */
|
|
937
|
+
useTaskQrl(/*#__PURE__*/ inlinedQrl(({ track }) => {
|
|
938
|
+
let contentInternal = _capturesObj._[0], goto = _capturesObj._[1], loaderState = _capturesObj._[2], manifestHash = _capturesObj._[3], navContext = _capturesObj._[4], navResolver = _capturesObj._[5], props = _capturesObj._[6], routeInternal = _capturesObj._[7], routeLoaderCtx = _capturesObj._[8], routeLocation = _capturesObj._[9];
|
|
1044
939
|
const nav = track(navContext);
|
|
1045
940
|
if (isServer || !nav) return;
|
|
1046
941
|
if (nav.navCount !== internalState.navCount) return;
|
|
@@ -1071,7 +966,12 @@ function initializeSPA(goto, scroller) {
|
|
|
1071
966
|
if (currentPath !== nextPath) history.replaceState(history.state, "", nextPath);
|
|
1072
967
|
} else clientNavigate(window, navType, prevUrl, trackUrl, replaceState);
|
|
1073
968
|
contentInternal.trigger();
|
|
1074
|
-
return navigatePromise = _waitUntilRendered(container)
|
|
969
|
+
return navigatePromise = _waitUntilRendered(container).then(() => {
|
|
970
|
+
if (nav.navCount === internalState.navCount) commitRouteLoaders(loaderState, routeLoaderCtx, nav.navCount);
|
|
971
|
+
}, (error) => {
|
|
972
|
+
if (nav.navCount === internalState.navCount) restoreRouteLoaders(loaderState, routeLoaderCtx, nav.navCount);
|
|
973
|
+
throw error;
|
|
974
|
+
});
|
|
1075
975
|
};
|
|
1076
976
|
const _waitNextPage = () => {
|
|
1077
977
|
if (!shouldStartViewTransition(props?.viewTransition)) return navigate().then(() => void 0);
|
|
@@ -1104,40 +1004,192 @@ function initializeSPA(goto, scroller) {
|
|
|
1104
1004
|
}, "useQwikRouter_useTask_2_yw17chooOac", [
|
|
1105
1005
|
contentInternal,
|
|
1106
1006
|
goto,
|
|
1007
|
+
loaderState,
|
|
1107
1008
|
manifestHash,
|
|
1108
1009
|
navContext,
|
|
1109
1010
|
navResolver,
|
|
1110
1011
|
props,
|
|
1111
1012
|
routeInternal,
|
|
1013
|
+
routeLoaderCtx,
|
|
1112
1014
|
routeLocation
|
|
1113
1015
|
]), { deferUpdates: false });
|
|
1114
1016
|
};
|
|
1115
|
-
/** @public This is a wrapper around the `useQwikRouter()` hook. We recommend using the hook instead of this component, unless you have a good reason to make your root component reactive. */
|
|
1017
|
+
/** @public This is a wrapper around the `useQwikRouter()` hook. We recommend using the hook instead of this component, unless you have a good reason to make your root component reactive. */
|
|
1018
|
+
function initializeSPA(goto, scroller) {
|
|
1019
|
+
if (!window._qRouterSPA) {
|
|
1020
|
+
window._qRouterSPA = true;
|
|
1021
|
+
history.scrollRestoration = "manual";
|
|
1022
|
+
window.addEventListener("popstate", () => {
|
|
1023
|
+
window._qRouterScrollEnabled = false;
|
|
1024
|
+
clearTimeout(window._qRouterScrollDebounce);
|
|
1025
|
+
goto(location.href, { type: "popstate" });
|
|
1026
|
+
});
|
|
1027
|
+
window.removeEventListener("popstate", window._qRouterInitPopstate);
|
|
1028
|
+
window._qRouterInitPopstate = void 0;
|
|
1029
|
+
if (!window._qRouterHistoryPatch) {
|
|
1030
|
+
window._qRouterHistoryPatch = true;
|
|
1031
|
+
const pushState = history.pushState;
|
|
1032
|
+
const replaceState = history.replaceState;
|
|
1033
|
+
const prepareState = (state) => {
|
|
1034
|
+
if (state === null || typeof state === "undefined") state = {};
|
|
1035
|
+
else if (state?.constructor !== Object) {
|
|
1036
|
+
state = { _data: state };
|
|
1037
|
+
if (isDev) 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`");
|
|
1038
|
+
}
|
|
1039
|
+
state._qRouterScroll = state._qRouterScroll || currentScrollState(scroller);
|
|
1040
|
+
return state;
|
|
1041
|
+
};
|
|
1042
|
+
history.pushState = (state, title, url) => {
|
|
1043
|
+
state = prepareState(state);
|
|
1044
|
+
return pushState.call(history, state, title, url);
|
|
1045
|
+
};
|
|
1046
|
+
history.replaceState = (state, title, url) => {
|
|
1047
|
+
state = prepareState(state);
|
|
1048
|
+
return replaceState.call(history, state, title, url);
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
1051
|
+
document.addEventListener("click", (event) => {
|
|
1052
|
+
if (event.defaultPrevented) return;
|
|
1053
|
+
const target = event.target.closest("a[href]");
|
|
1054
|
+
if (target && !target.hasAttribute("preventdefault:click")) {
|
|
1055
|
+
const href = target.getAttribute("href");
|
|
1056
|
+
const prev = new URL(location.href);
|
|
1057
|
+
const dest = new URL(href, prev);
|
|
1058
|
+
if (isSameOrigin(dest, prev) && isSamePath(dest, prev)) {
|
|
1059
|
+
event.preventDefault();
|
|
1060
|
+
if (!dest.hash && !dest.href.endsWith("#")) {
|
|
1061
|
+
if (dest.href !== prev.href) history.pushState(null, "", dest);
|
|
1062
|
+
window._qRouterScrollEnabled = false;
|
|
1063
|
+
clearTimeout(window._qRouterScrollDebounce);
|
|
1064
|
+
saveScrollHistory({
|
|
1065
|
+
...currentScrollState(scroller),
|
|
1066
|
+
x: 0,
|
|
1067
|
+
y: 0
|
|
1068
|
+
});
|
|
1069
|
+
location.reload();
|
|
1070
|
+
return;
|
|
1071
|
+
}
|
|
1072
|
+
goto(target.getAttribute("href"));
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
});
|
|
1076
|
+
document.removeEventListener("click", window._qRouterInitAnchors);
|
|
1077
|
+
window._qRouterInitAnchors = void 0;
|
|
1078
|
+
if (!window.navigation) {
|
|
1079
|
+
document.addEventListener("visibilitychange", () => {
|
|
1080
|
+
if (window._qRouterScrollEnabled && document.visibilityState === "hidden") saveScrollHistory(currentScrollState(scroller));
|
|
1081
|
+
}, { passive: true });
|
|
1082
|
+
document.removeEventListener("visibilitychange", window._qRouterInitVisibility);
|
|
1083
|
+
window._qRouterInitVisibility = void 0;
|
|
1084
|
+
}
|
|
1085
|
+
window.addEventListener("scroll", () => {
|
|
1086
|
+
if (!window._qRouterScrollEnabled) return;
|
|
1087
|
+
clearTimeout(window._qRouterScrollDebounce);
|
|
1088
|
+
window._qRouterScrollDebounce = setTimeout(() => {
|
|
1089
|
+
saveScrollHistory(currentScrollState(scroller));
|
|
1090
|
+
window._qRouterScrollDebounce = void 0;
|
|
1091
|
+
}, 200);
|
|
1092
|
+
}, { passive: true });
|
|
1093
|
+
removeEventListener("scroll", window._qRouterInitScroll);
|
|
1094
|
+
window._qRouterInitScroll = void 0;
|
|
1095
|
+
spa_init_default.resolve();
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
var QwikRouterMockProvider = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props) => {
|
|
1099
|
+
useQwikMockRouter(props);
|
|
1100
|
+
return /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "dU_1");
|
|
1101
|
+
}, "QwikRouterMockProvider_component_IN4dVpT0x74"));
|
|
1102
|
+
var useQwikMockRouter = (props) => {
|
|
1103
|
+
const urlEnv = props.url ?? "http://localhost/";
|
|
1104
|
+
const url = new URL(urlEnv);
|
|
1105
|
+
const routeLocation = useStore({
|
|
1106
|
+
url,
|
|
1107
|
+
params: props.params ?? {},
|
|
1108
|
+
isNavigating: false,
|
|
1109
|
+
prevUrl: void 0
|
|
1110
|
+
}, { deep: false });
|
|
1111
|
+
const loadersData = props.loaders?.reduce((acc, { loader, data }) => {
|
|
1112
|
+
acc[loader.__id] = data;
|
|
1113
|
+
return acc;
|
|
1114
|
+
}, {});
|
|
1115
|
+
const loadersState = useStore({}, { deep: false });
|
|
1116
|
+
for (const [loaderId, data] of Object.entries(loadersData ?? {})) loadersState[loaderId] ||= createComputedQrl(/*#__PURE__*/ inlinedQrl(() => {
|
|
1117
|
+
return _capturesObj._[0];
|
|
1118
|
+
}, "useQwikMockRouter_createComputed_JL6bChMwwyc", [data]));
|
|
1119
|
+
const goto = props.goto ?? /*#__PURE__*/ inlinedQrl(async () => {
|
|
1120
|
+
console.warn("QwikRouterMockProvider: goto not provided");
|
|
1121
|
+
}, "useQwikMockRouter_goto_aViHFxQ1a3s");
|
|
1122
|
+
const documentHead = useStore(createDocumentHead, { deep: false });
|
|
1123
|
+
const content = useStore({
|
|
1124
|
+
headings: void 0,
|
|
1125
|
+
menu: void 0
|
|
1126
|
+
}, { deep: false });
|
|
1127
|
+
const contentInternal = useSignal();
|
|
1128
|
+
const actionState = useSignal();
|
|
1129
|
+
const httpStatus = useSignal({
|
|
1130
|
+
status: 200,
|
|
1131
|
+
message: ""
|
|
1132
|
+
});
|
|
1133
|
+
useContextProvider(ContentContext, content);
|
|
1134
|
+
useContextProvider(ContentInternalContext, contentInternal);
|
|
1135
|
+
useContextProvider(DocumentHeadContext, documentHead);
|
|
1136
|
+
useContextProvider(HttpStatusContext, httpStatus);
|
|
1137
|
+
useContextProvider(RouteLocationContext, routeLocation);
|
|
1138
|
+
useContextProvider(RouteNavigateContext, goto);
|
|
1139
|
+
useContextProvider(RouteStateContext, loadersState);
|
|
1140
|
+
useContextProvider(RouteActionContext, actionState);
|
|
1141
|
+
const actionsMocks = props.actions?.reduce((acc, { action, handler }) => {
|
|
1142
|
+
acc[action.__id] = handler;
|
|
1143
|
+
return acc;
|
|
1144
|
+
}, {});
|
|
1145
|
+
useTaskQrl(/*#__PURE__*/ inlinedQrl(async ({ track }) => {
|
|
1146
|
+
let actionState = _capturesObj._[0], actionsMocks = _capturesObj._[1];
|
|
1147
|
+
const action = track(actionState);
|
|
1148
|
+
action?.resolveDispatch?.();
|
|
1149
|
+
if (action) action.resolveDispatch = void 0;
|
|
1150
|
+
if (!action?.resolve) return;
|
|
1151
|
+
const mock = actionsMocks?.[action.id];
|
|
1152
|
+
if (mock) {
|
|
1153
|
+
const actionResult = await mock(action.data);
|
|
1154
|
+
action.resolve(actionResult);
|
|
1155
|
+
}
|
|
1156
|
+
}, "useQwikMockRouter_useTask_tXTLR4tzCy0", [actionState, actionsMocks]));
|
|
1157
|
+
};
|
|
1158
|
+
var QwikRouterProvider = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props) => {
|
|
1116
1159
|
useQwikRouter(props);
|
|
1117
|
-
return /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "
|
|
1160
|
+
return /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "dU_0");
|
|
1118
1161
|
}, "QwikRouterProvider_component_6Kjfa79mqlY"));
|
|
1119
1162
|
/**
|
|
1120
1163
|
* @deprecated Use `useQwikRouter()` instead. Will be removed in v3.
|
|
1121
1164
|
* @public
|
|
1122
|
-
*/
|
|
1165
|
+
*/
|
|
1166
|
+
var QwikCityProvider = QwikRouterProvider;
|
|
1167
|
+
/** @public */
|
|
1168
|
+
/** @public */
|
|
1169
|
+
/**
|
|
1170
|
+
* @deprecated Use `useQwikMockRouter()` instead. Will be removed in V3
|
|
1171
|
+
* @public
|
|
1172
|
+
*/
|
|
1173
|
+
var QwikCityMockProvider = QwikRouterMockProvider;
|
|
1123
1174
|
var handleRouterPopstate = (nav, event) => {
|
|
1124
1175
|
const href = event.detail?.href;
|
|
1125
1176
|
if (href) return nav(href, { type: "popstate" });
|
|
1126
1177
|
};
|
|
1127
|
-
/** @public */
|
|
1178
|
+
/** @public */
|
|
1179
|
+
var RouterOutlet = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(() => {
|
|
1128
1180
|
if (!useServerData("containerAttributes")) throw new Error("PrefetchServiceWorker component must be rendered on the server.");
|
|
1129
1181
|
const internalContext = useContext(ContentInternalContext);
|
|
1130
1182
|
const nav = useNavigate();
|
|
1131
1183
|
const contents = internalContext.value;
|
|
1132
1184
|
if (contents && contents.length > 0) {
|
|
1133
|
-
const contentsLen = contents.length;
|
|
1134
1185
|
let cmp = null;
|
|
1135
|
-
for (let i =
|
|
1186
|
+
for (let i = contents.length - 1; i >= 0; i--) if (contents[i].default) cmp = /*#__PURE__*/ _jsxSorted(contents[i].default, null, null, cmp, 1, "yd_0");
|
|
1136
1187
|
return /*#__PURE__*/ _jsxSorted(Fragment, null, null, [cmp, !__EXPERIMENTAL__.noSPA && /*#__PURE__*/ _jsxSorted("script", {
|
|
1188
|
+
"q-d:qcinit": [spa_init_default, linkPrefetchInit],
|
|
1137
1189
|
"q-d:qinit": _qrlSync(() => {
|
|
1138
1190
|
((w, h) => {
|
|
1139
1191
|
if (!w._qcs) {
|
|
1140
|
-
w._qcs =
|
|
1192
|
+
w._qcs = true;
|
|
1141
1193
|
const s = h.state?._qRouterScroll;
|
|
1142
1194
|
if (s) {
|
|
1143
1195
|
h.scrollRestoration = "manual";
|
|
@@ -1147,126 +1199,19 @@ var handleRouterPopstate = (nav, event) => {
|
|
|
1147
1199
|
}
|
|
1148
1200
|
})(window, history);
|
|
1149
1201
|
}, "()=>{((w,h)=>{if(!w._qcs){w._qcs=!0;const s=h.state?._qRouterScroll;if(s){h.scrollRestoration=\"manual\";w.scrollTo(s.x,s.y);}document.dispatchEvent(new Event(\"qcinit\"));}})(window,history);}"),
|
|
1150
|
-
"q-d:qrouterpopstate": /*#__PURE__*/ inlinedQrl((event, _1, nav) => handleRouterPopstate(nav, event), "RouterOutlet_component_Fragment_script_q_d_qrouterpopstate_aRL6GvFyews").m(),
|
|
1151
1202
|
"q:p": nav
|
|
1152
|
-
}, { "q-d:
|
|
1203
|
+
}, { "q-d:qrouterpopstate": /*#__PURE__*/ inlinedQrl((event, _1, nav) => handleRouterPopstate(nav, event), "RouterOutlet_component_Fragment_script_q_d_qrouterpopstate_aRL6GvFyews").m() }, null, 6, "yd_0")], 1, "yd_1");
|
|
1153
1204
|
}
|
|
1154
1205
|
return SkipRender;
|
|
1155
1206
|
}, "RouterOutlet_component_QwONcWD5gIg"));
|
|
1156
|
-
/**
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
const keySuffix = issue.expected === "Array" ? "[]" : "";
|
|
1165
|
-
const key = issue.path.map((item) => item.type === "array" ? "*" : item.key).join(".").replace(/\.\*/g, "[]") + keySuffix;
|
|
1166
|
-
acc[key] = acc[key] || [];
|
|
1167
|
-
if (Array.isArray(acc[key])) acc[key].push(issue.message);
|
|
1168
|
-
return acc;
|
|
1169
|
-
} else acc[issue.path.map((item) => item.key).join(".")] = issue.message;
|
|
1170
|
-
}
|
|
1171
|
-
return acc;
|
|
1172
|
-
}, {});
|
|
1173
|
-
};
|
|
1174
|
-
/** @internal */ var valibotQrl = (qrl) => {
|
|
1175
|
-
if (!__EXPERIMENTAL__.valibot) 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.");
|
|
1176
|
-
if (isServer) return {
|
|
1177
|
-
__brand: "valibot",
|
|
1178
|
-
async validate(ev, inputData) {
|
|
1179
|
-
const schema = await qrl.resolve().then((obj) => typeof obj === "function" ? obj(ev) : obj);
|
|
1180
|
-
const data = inputData ?? await ev.parseBody();
|
|
1181
|
-
const result = await v.safeParseAsync(schema, data);
|
|
1182
|
-
if (result.success) return {
|
|
1183
|
-
success: true,
|
|
1184
|
-
data: result.output
|
|
1185
|
-
};
|
|
1186
|
-
else {
|
|
1187
|
-
if (isDev) console.error("ERROR: Valibot validation failed", result.issues);
|
|
1188
|
-
return {
|
|
1189
|
-
success: false,
|
|
1190
|
-
status: 400,
|
|
1191
|
-
error: {
|
|
1192
|
-
formErrors: v.flatten(result.issues).root ?? [],
|
|
1193
|
-
fieldErrors: flattenValibotIssues(result.issues)
|
|
1194
|
-
}
|
|
1195
|
-
};
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
};
|
|
1199
|
-
};
|
|
1200
|
-
/** @beta */ var valibot$ = /*#__PURE__*/ implicit$FirstArg(valibotQrl);
|
|
1201
|
-
var flattenZodIssues = (issues) => {
|
|
1202
|
-
issues = Array.isArray(issues) ? issues : [issues];
|
|
1203
|
-
return issues.reduce((acc, issue) => {
|
|
1204
|
-
const isExpectingArray = "expected" in issue && issue.expected === "array";
|
|
1205
|
-
if (issue.path.some((path) => typeof path === "number") || isExpectingArray) {
|
|
1206
|
-
const keySuffix = "expected" in issue && issue.expected === "array" ? "[]" : "";
|
|
1207
|
-
const key = issue.path.map((path) => typeof path === "number" ? "*" : path).join(".").replace(/\.\*/g, "[]") + keySuffix;
|
|
1208
|
-
acc[key] = acc[key] || [];
|
|
1209
|
-
if (Array.isArray(acc[key])) acc[key].push(issue.message);
|
|
1210
|
-
return acc;
|
|
1211
|
-
} else acc[issue.path.join(".")] = issue.message;
|
|
1212
|
-
return acc;
|
|
1213
|
-
}, {});
|
|
1214
|
-
};
|
|
1215
|
-
/** @internal */ var zodQrl = (qrl) => {
|
|
1216
|
-
if (isServer) return {
|
|
1217
|
-
__brand: "zod",
|
|
1218
|
-
async validate(ev, inputData) {
|
|
1219
|
-
const schema = await qrl.resolve().then((obj) => {
|
|
1220
|
-
if (typeof obj === "function") obj = obj(z$1, ev);
|
|
1221
|
-
if (obj instanceof z$1.ZodType) return obj;
|
|
1222
|
-
else return z$1.object(obj);
|
|
1223
|
-
});
|
|
1224
|
-
const data = inputData ?? await ev.parseBody();
|
|
1225
|
-
const result = await withLocale(ev.locale(), () => schema.safeParseAsync(data));
|
|
1226
|
-
if (result.success) return result;
|
|
1227
|
-
else {
|
|
1228
|
-
if (isDev) console.error("ERROR: Zod validation failed", result.error.issues);
|
|
1229
|
-
return {
|
|
1230
|
-
success: false,
|
|
1231
|
-
status: 400,
|
|
1232
|
-
error: {
|
|
1233
|
-
formErrors: result.error.flatten().formErrors,
|
|
1234
|
-
fieldErrors: flattenZodIssues(result.error.issues)
|
|
1235
|
-
}
|
|
1236
|
-
};
|
|
1237
|
-
}
|
|
1238
|
-
}
|
|
1239
|
-
};
|
|
1240
|
-
};
|
|
1241
|
-
/** @public */ var zod$ = /*#__PURE__*/ implicit$FirstArg(zodQrl);
|
|
1242
|
-
var getValidators = (rest, qrl) => {
|
|
1243
|
-
let id;
|
|
1244
|
-
let invalidate;
|
|
1245
|
-
const validators = [];
|
|
1246
|
-
if (rest.length === 1) {
|
|
1247
|
-
const options = rest[0];
|
|
1248
|
-
if (options && typeof options === "object") {
|
|
1249
|
-
if ("validate" in options) validators.push(options);
|
|
1250
|
-
else {
|
|
1251
|
-
id = options.id;
|
|
1252
|
-
if (options.validation) validators.push(...options.validation);
|
|
1253
|
-
if (options.invalidate) invalidate = options.invalidate.map((loader) => loader.__id);
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
} else if (rest.length > 1) validators.push(...rest.filter((v) => !!v));
|
|
1257
|
-
if (typeof id === "string") {
|
|
1258
|
-
if (isDev) {
|
|
1259
|
-
if (!/^[\w/.-]+$/.test(id)) throw new Error(`Invalid id: ${id}, id can only contain [a-zA-Z0-9_.-]`);
|
|
1260
|
-
}
|
|
1261
|
-
id = `id_${id}`;
|
|
1262
|
-
} else id = qrl.getHash();
|
|
1263
|
-
return {
|
|
1264
|
-
validators: validators.reverse(),
|
|
1265
|
-
id,
|
|
1266
|
-
invalidate
|
|
1267
|
-
};
|
|
1268
|
-
};
|
|
1269
|
-
/** @public */ var routeActionQrl = (actionQrl, ...rest) => {
|
|
1207
|
+
/**
|
|
1208
|
+
* Hoisted function declarations (not consts) on purpose, like `routeLoaderQrl`: the app's route
|
|
1209
|
+
* modules call these factories during their own evaluation, which a bundle may run before this
|
|
1210
|
+
* module, where a `const` binding would throw a TDZ ReferenceError.
|
|
1211
|
+
*
|
|
1212
|
+
* @public
|
|
1213
|
+
*/
|
|
1214
|
+
function routeActionQrl(actionQrl, ...rest) {
|
|
1270
1215
|
const { id, validators, invalidate } = getValidators(rest, actionQrl);
|
|
1271
1216
|
function action() {
|
|
1272
1217
|
const loc = useLocation();
|
|
@@ -1293,7 +1238,7 @@ var getValidators = (rest, qrl) => {
|
|
|
1293
1238
|
return initialState;
|
|
1294
1239
|
});
|
|
1295
1240
|
initialState.submit = /* @__PURE__ */ inlinedQrl((input = {}) => {
|
|
1296
|
-
|
|
1241
|
+
let currentAction = _capturesObj._[0], id = _capturesObj._[1], latestSubmission = _capturesObj._[2], loc = _capturesObj._[3], state = _capturesObj._[4];
|
|
1297
1242
|
if (isServer) throw new Error(`Actions can not be invoked within the server during SSR.
|
|
1298
1243
|
Action.run() can only be called on the browser, for example when a user clicks a button, or submits a form.`);
|
|
1299
1244
|
let data;
|
|
@@ -1305,7 +1250,14 @@ Action.run() can only be called on the browser, for example when a user clicks a
|
|
|
1305
1250
|
if (input.submitter.name) data.append(input.submitter.name, input.submitter.value);
|
|
1306
1251
|
}
|
|
1307
1252
|
} else data = input;
|
|
1308
|
-
|
|
1253
|
+
const submission = {};
|
|
1254
|
+
latestSubmission.current = submission;
|
|
1255
|
+
const previousDispatch = currentAction.pendingDispatch ?? Promise.resolve();
|
|
1256
|
+
let resolveDispatch;
|
|
1257
|
+
currentAction.pendingDispatch = noSerialize(new Promise((resolve) => {
|
|
1258
|
+
resolveDispatch = resolve;
|
|
1259
|
+
}));
|
|
1260
|
+
return previousDispatch.then(() => new Promise((resolve) => {
|
|
1309
1261
|
if (data instanceof FormData) state.formData = data;
|
|
1310
1262
|
state.submitted = true;
|
|
1311
1263
|
state.isRunning = true;
|
|
@@ -1313,17 +1265,21 @@ Action.run() can only be called on the browser, for example when a user clicks a
|
|
|
1313
1265
|
currentAction.value = {
|
|
1314
1266
|
data,
|
|
1315
1267
|
id,
|
|
1316
|
-
resolve: noSerialize(resolve)
|
|
1268
|
+
resolve: noSerialize(resolve),
|
|
1269
|
+
resolveDispatch: noSerialize(resolveDispatch)
|
|
1317
1270
|
};
|
|
1318
|
-
}).then((
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1271
|
+
})).then(({ result, status }) => {
|
|
1272
|
+
const isLatestSubmission = latestSubmission.current === submission;
|
|
1273
|
+
if (isLatestSubmission) {
|
|
1274
|
+
state.isRunning = false;
|
|
1275
|
+
state.status = status;
|
|
1276
|
+
state.value = result;
|
|
1277
|
+
}
|
|
1322
1278
|
if (form) {
|
|
1323
|
-
if (form.getAttribute("data-spa-reset") === "true") form.reset();
|
|
1279
|
+
if (isLatestSubmission && form.getAttribute("data-spa-reset") === "true") form.reset();
|
|
1324
1280
|
const detail = {
|
|
1325
|
-
status
|
|
1326
|
-
value:
|
|
1281
|
+
status,
|
|
1282
|
+
value: result
|
|
1327
1283
|
};
|
|
1328
1284
|
form.dispatchEvent(new CustomEvent("submitcompleted", {
|
|
1329
1285
|
bubbles: false,
|
|
@@ -1333,13 +1289,14 @@ Action.run() can only be called on the browser, for example when a user clicks a
|
|
|
1333
1289
|
}));
|
|
1334
1290
|
}
|
|
1335
1291
|
return {
|
|
1336
|
-
status
|
|
1337
|
-
value:
|
|
1292
|
+
status,
|
|
1293
|
+
value: result
|
|
1338
1294
|
};
|
|
1339
1295
|
});
|
|
1340
1296
|
}, "routeActionQrl_action_submit_YuS5bpdQ360", [
|
|
1341
1297
|
currentAction,
|
|
1342
1298
|
id,
|
|
1299
|
+
{ current: void 0 },
|
|
1343
1300
|
loc,
|
|
1344
1301
|
state
|
|
1345
1302
|
]);
|
|
@@ -1352,15 +1309,16 @@ Action.run() can only be called on the browser, for example when a user clicks a
|
|
|
1352
1309
|
action.__invalidate = invalidate;
|
|
1353
1310
|
Object.freeze(action);
|
|
1354
1311
|
return action;
|
|
1355
|
-
}
|
|
1356
|
-
/** @internal */
|
|
1312
|
+
}
|
|
1313
|
+
/** @internal */
|
|
1314
|
+
function globalActionQrl(actionQrl, ...rest) {
|
|
1357
1315
|
const action = routeActionQrl(actionQrl, ...rest);
|
|
1358
1316
|
if (isServer) {
|
|
1359
1317
|
if (typeof globalThis._qwikActionsMap === "undefined") globalThis._qwikActionsMap = /* @__PURE__ */ new Map();
|
|
1360
1318
|
globalThis._qwikActionsMap.set(action.__id, action);
|
|
1361
1319
|
}
|
|
1362
1320
|
return action;
|
|
1363
|
-
}
|
|
1321
|
+
}
|
|
1364
1322
|
/**
|
|
1365
1323
|
* Define a route action that handles form submissions or programmatic invocations.
|
|
1366
1324
|
*
|
|
@@ -1380,27 +1338,106 @@ Action.run() can only be called on the browser, for example when a user clicks a
|
|
|
1380
1338
|
* don't specify an explicit `invalidate` option.
|
|
1381
1339
|
*
|
|
1382
1340
|
* @public
|
|
1383
|
-
*/
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1341
|
+
*/
|
|
1342
|
+
var routeAction$ = /*#__PURE__*/ implicit$FirstArg(routeActionQrl);
|
|
1343
|
+
/** @public */
|
|
1344
|
+
var globalAction$ = /*#__PURE__*/ implicit$FirstArg(globalActionQrl);
|
|
1345
|
+
/** @internal */
|
|
1346
|
+
function validatorQrl(validator) {
|
|
1347
|
+
if (isServer) return { validate: validator };
|
|
1348
|
+
}
|
|
1349
|
+
/** @public */
|
|
1350
|
+
var validator$ = /*#__PURE__*/ implicit$FirstArg(validatorQrl);
|
|
1351
|
+
var flattenValibotIssues = (issues) => {
|
|
1352
|
+
return issues.reduce((acc, issue) => {
|
|
1353
|
+
if (issue.path) {
|
|
1354
|
+
if (issue.path.some((path) => path.type === "array")) {
|
|
1355
|
+
const keySuffix = issue.expected === "Array" ? "[]" : "";
|
|
1356
|
+
const key = issue.path.map((item) => item.type === "array" ? "*" : item.key).join(".").replace(/\.\*/g, "[]") + keySuffix;
|
|
1357
|
+
acc[key] = acc[key] || [];
|
|
1358
|
+
if (Array.isArray(acc[key])) acc[key].push(issue.message);
|
|
1359
|
+
return acc;
|
|
1360
|
+
} else acc[issue.path.map((item) => item.key).join(".")] = issue.message;
|
|
1397
1361
|
}
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1362
|
+
return acc;
|
|
1363
|
+
}, {});
|
|
1364
|
+
};
|
|
1365
|
+
/** @internal */
|
|
1366
|
+
function valibotQrl(qrl) {
|
|
1367
|
+
if (!__EXPERIMENTAL__.valibot) 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.");
|
|
1368
|
+
if (isServer) return {
|
|
1369
|
+
__brand: "valibot",
|
|
1370
|
+
async validate(ev, inputData) {
|
|
1371
|
+
const schema = await qrl.resolve().then((obj) => typeof obj === "function" ? obj(ev) : obj);
|
|
1372
|
+
const data = inputData ?? await ev.parseBody();
|
|
1373
|
+
const result = await v.safeParseAsync(schema, data);
|
|
1374
|
+
if (result.success) return {
|
|
1375
|
+
success: true,
|
|
1376
|
+
data: result.output
|
|
1377
|
+
};
|
|
1378
|
+
else {
|
|
1379
|
+
if (isDev) console.error("ERROR: Valibot validation failed", result.issues);
|
|
1380
|
+
return {
|
|
1381
|
+
success: false,
|
|
1382
|
+
status: 400,
|
|
1383
|
+
error: {
|
|
1384
|
+
formErrors: v.flatten(result.issues).root ?? [],
|
|
1385
|
+
fieldErrors: flattenValibotIssues(result.issues)
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1392
|
+
/** @beta */
|
|
1393
|
+
var valibot$ = /*#__PURE__*/ implicit$FirstArg(valibotQrl);
|
|
1394
|
+
var flattenZodIssues = (issues) => {
|
|
1395
|
+
issues = Array.isArray(issues) ? issues : [issues];
|
|
1396
|
+
return issues.reduce((acc, issue) => {
|
|
1397
|
+
const isExpectingArray = "expected" in issue && issue.expected === "array";
|
|
1398
|
+
if (issue.path.some((path) => typeof path === "number") || isExpectingArray) {
|
|
1399
|
+
const keySuffix = "expected" in issue && issue.expected === "array" ? "[]" : "";
|
|
1400
|
+
const key = issue.path.map((path) => typeof path === "number" ? "*" : path).join(".").replace(/\.\*/g, "[]") + keySuffix;
|
|
1401
|
+
acc[key] = acc[key] || [];
|
|
1402
|
+
if (Array.isArray(acc[key])) acc[key].push(issue.message);
|
|
1403
|
+
return acc;
|
|
1404
|
+
} else acc[issue.path.join(".")] = issue.message;
|
|
1405
|
+
return acc;
|
|
1406
|
+
}, {});
|
|
1401
1407
|
};
|
|
1402
|
-
/** @internal */
|
|
1408
|
+
/** @internal */
|
|
1409
|
+
function zodQrl(qrl) {
|
|
1410
|
+
if (isServer) return {
|
|
1411
|
+
__brand: "zod",
|
|
1412
|
+
async validate(ev, inputData) {
|
|
1413
|
+
const schema = await qrl.resolve().then((obj) => {
|
|
1414
|
+
if (typeof obj === "function") obj = obj(z$1, ev);
|
|
1415
|
+
if (obj instanceof z$1.ZodType) return obj;
|
|
1416
|
+
else return z$1.object(obj);
|
|
1417
|
+
});
|
|
1418
|
+
const data = inputData ?? await ev.parseBody();
|
|
1419
|
+
const result = await withLocale(ev.locale(), () => schema.safeParseAsync(data));
|
|
1420
|
+
if (result.success) return result;
|
|
1421
|
+
else {
|
|
1422
|
+
if (isDev) console.error("ERROR: Zod validation failed", result.error.issues);
|
|
1423
|
+
return {
|
|
1424
|
+
success: false,
|
|
1425
|
+
status: 400,
|
|
1426
|
+
error: {
|
|
1427
|
+
formErrors: result.error.flatten().formErrors,
|
|
1428
|
+
fieldErrors: flattenZodIssues(result.error.issues)
|
|
1429
|
+
}
|
|
1430
|
+
};
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
};
|
|
1434
|
+
}
|
|
1435
|
+
/** @public */
|
|
1436
|
+
var zod$ = /*#__PURE__*/ implicit$FirstArg(zodQrl);
|
|
1437
|
+
/** @internal */
|
|
1438
|
+
function serverQrl(qrl, options) {
|
|
1403
1439
|
if (isServer) {
|
|
1440
|
+
_regInlinedQrl(qrl);
|
|
1404
1441
|
const captured = qrl.getCaptured();
|
|
1405
1442
|
if (captured && captured.length > 0 && !_getContextHostElement()) throw new Error("For security reasons, we cannot serialize QRLs that capture lexical scope.");
|
|
1406
1443
|
}
|
|
@@ -1409,7 +1446,7 @@ var deserializeStream = async function* (stream, abortSignal) {
|
|
|
1409
1446
|
const origin = options?.origin || "";
|
|
1410
1447
|
const fetchOptions = options?.fetchOptions || {};
|
|
1411
1448
|
return /*#__PURE__*/ inlinedQrl(async function(...args) {
|
|
1412
|
-
|
|
1449
|
+
let fetchOptions = _capturesObj._[0], headers = _capturesObj._[1], method = _capturesObj._[2], origin = _capturesObj._[3], qrl = _capturesObj._[4];
|
|
1413
1450
|
const abortSignal = args.length > 0 && args[0] instanceof AbortSignal ? args.shift() : void 0;
|
|
1414
1451
|
if (isServer) return qrl.apply(getRequestEvent(this), args);
|
|
1415
1452
|
else {
|
|
@@ -1442,13 +1479,13 @@ var deserializeStream = async function* (stream, abortSignal) {
|
|
|
1442
1479
|
else config.body = body;
|
|
1443
1480
|
const res = await fetch(`${origin}?${QFN_KEY}=${qrlHash}${query}`, config);
|
|
1444
1481
|
const contentType = res.headers.get("Content-Type");
|
|
1445
|
-
if (res.ok && contentType === "text/qwik-json-stream" && res.body) return async function* () {
|
|
1482
|
+
if (res.ok && contentType === "text/qwik-json-stream" && res.body) return (async function* () {
|
|
1446
1483
|
try {
|
|
1447
1484
|
for await (const result of deserializeStream(res.body, abortSignal)) yield result;
|
|
1448
1485
|
} finally {
|
|
1449
1486
|
if (!abortSignal?.aborted) await res.body.cancel();
|
|
1450
1487
|
}
|
|
1451
|
-
}();
|
|
1488
|
+
})();
|
|
1452
1489
|
else if (contentType === "application/qwik-json") {
|
|
1453
1490
|
const str = await res.text();
|
|
1454
1491
|
const obj = await _deserialize(str);
|
|
@@ -1471,8 +1508,57 @@ var deserializeStream = async function* (stream, abortSignal) {
|
|
|
1471
1508
|
origin,
|
|
1472
1509
|
qrl
|
|
1473
1510
|
]);
|
|
1511
|
+
}
|
|
1512
|
+
/** @public */
|
|
1513
|
+
var server$ = /*#__PURE__*/ implicit$FirstArg(serverQrl);
|
|
1514
|
+
function getValidators(rest, qrl) {
|
|
1515
|
+
let id;
|
|
1516
|
+
let invalidate;
|
|
1517
|
+
const validators = [];
|
|
1518
|
+
if (rest.length === 1) {
|
|
1519
|
+
const options = rest[0];
|
|
1520
|
+
if (options && typeof options === "object") {
|
|
1521
|
+
if ("validate" in options) validators.push(options);
|
|
1522
|
+
else {
|
|
1523
|
+
id = options.id;
|
|
1524
|
+
if (options.validation) validators.push(...options.validation);
|
|
1525
|
+
if (options.invalidate) invalidate = options.invalidate.map((loader) => loader.__id);
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
} else if (rest.length > 1) validators.push(...rest.filter((v) => !!v));
|
|
1529
|
+
if (typeof id === "string") {
|
|
1530
|
+
if (isDev) {
|
|
1531
|
+
if (!/^[\w/.-]+$/.test(id)) throw new Error(`Invalid id: ${id}, id can only contain [a-zA-Z0-9_.-]`);
|
|
1532
|
+
}
|
|
1533
|
+
id = `id_${id}`;
|
|
1534
|
+
} else id = qrl.getHash();
|
|
1535
|
+
return {
|
|
1536
|
+
validators: validators.reverse(),
|
|
1537
|
+
id,
|
|
1538
|
+
invalidate
|
|
1539
|
+
};
|
|
1540
|
+
}
|
|
1541
|
+
var deserializeStream = async function* (stream, abortSignal) {
|
|
1542
|
+
const reader = stream.getReader();
|
|
1543
|
+
try {
|
|
1544
|
+
let buffer = "";
|
|
1545
|
+
const decoder = new TextDecoder();
|
|
1546
|
+
while (!abortSignal?.aborted) {
|
|
1547
|
+
const result = await reader.read();
|
|
1548
|
+
if (result.done) break;
|
|
1549
|
+
buffer += decoder.decode(result.value, { stream: true });
|
|
1550
|
+
const lines = buffer.split(/\n/);
|
|
1551
|
+
buffer = lines.pop();
|
|
1552
|
+
for (const line of lines) yield await _deserialize(line);
|
|
1553
|
+
}
|
|
1554
|
+
} finally {
|
|
1555
|
+
reader.releaseLock();
|
|
1556
|
+
}
|
|
1474
1557
|
};
|
|
1475
|
-
|
|
1558
|
+
var SW_REGISTER = `(()=>{if("serviceWorker"in navigator){navigator.serviceWorker.register("__url").catch(e=>console.error(e));"caches"in window&&caches.keys().then(r=>{const e=r.find(c=>c.startsWith("QwikBuild"));e&&caches.delete(e).catch(console.error)}).catch(console.error)}else console.log("Service worker not supported in this browser.")})()`;
|
|
1559
|
+
var SW_UNREGISTER = `"serviceWorker"in navigator&&navigator.serviceWorker.getRegistrations().then(r=>{for(const e of r){const c="__url".split("/").pop();e.active?.scriptURL.endsWith(c||"service-worker.js")&&e.unregister().catch(console.error)}}),"caches"in window&&caches.keys().then(r=>{const e=r.find(c=>c.startsWith("QwikBuild"));e&&caches.delete(e).catch(console.error)}).catch(console.error)`;
|
|
1560
|
+
/** @internal */
|
|
1561
|
+
var _getServiceWorkerScript = (serviceWorkerUrl) => (serviceWorkerUrl ? SW_REGISTER : SW_UNREGISTER).replace("__url", serviceWorkerUrl ?? "/service-worker.js");
|
|
1476
1562
|
/**
|
|
1477
1563
|
* Loads the service workers that are defined in the routes. Any file named `service-worker.*` (all
|
|
1478
1564
|
* JS extensions are allowed) will be picked up, bundled into a separate file, and registered as a
|
|
@@ -1485,14 +1571,43 @@ var deserializeStream = async function* (stream, abortSignal) {
|
|
|
1485
1571
|
* service-worker.ts file) as long as you want to unregister the service-worker.js for your users.
|
|
1486
1572
|
*
|
|
1487
1573
|
* @public
|
|
1488
|
-
*/
|
|
1489
|
-
|
|
1490
|
-
dangerouslySetInnerHTML:
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
var
|
|
1494
|
-
var
|
|
1495
|
-
|
|
1574
|
+
*/
|
|
1575
|
+
var ServiceWorkerRegister = (props) => /*#__PURE__*/ _jsxSorted("script", {
|
|
1576
|
+
dangerouslySetInnerHTML: _getServiceWorkerScript(_getServiceWorkerUrl()),
|
|
1577
|
+
nonce: _wrapProp(props, "nonce")
|
|
1578
|
+
}, { type: "module" }, null, 3, "UM_0");
|
|
1579
|
+
var _hf0 = (p0) => p0.spaReset ? "true" : void 0;
|
|
1580
|
+
var _hf0_str = "p0.spaReset?\"true\":undefined";
|
|
1581
|
+
/** @public */
|
|
1582
|
+
var Form = ({ action, spaReset, reloadDocument, onSubmit$, ...rest }, key) => {
|
|
1583
|
+
if (action) {
|
|
1584
|
+
if (Array.isArray(onSubmit$)) return /*#__PURE__*/ _jsxSplit("form", {
|
|
1585
|
+
..._getVarProps(rest),
|
|
1586
|
+
..._getConstProps(rest),
|
|
1587
|
+
action: _wrapProp(action, "actionPath"),
|
|
1588
|
+
"preventdefault:submit": !reloadDocument,
|
|
1589
|
+
"q-e:submit": [...onSubmit$, !reloadDocument ? /*#__PURE__*/ inlinedQrl((evt) => {
|
|
1590
|
+
let action = _capturesObj._[0];
|
|
1591
|
+
if (!action.submitted) return action.submit(evt);
|
|
1592
|
+
}, "Form_form_q_e_submit_6i0Jq5q8JFg", [action]) : void 0],
|
|
1593
|
+
["data-spa-reset"]: spaReset ? "true" : void 0
|
|
1594
|
+
}, { method: "post" }, null, 0, key);
|
|
1595
|
+
return /*#__PURE__*/ _jsxSplit("form", {
|
|
1596
|
+
..._getVarProps(rest),
|
|
1597
|
+
..._getConstProps(rest),
|
|
1598
|
+
action: _wrapProp(action, "actionPath"),
|
|
1599
|
+
"preventdefault:submit": !reloadDocument,
|
|
1600
|
+
"q-e:submit": [onSubmit$, !reloadDocument ? action.submit : void 0],
|
|
1601
|
+
["data-spa-reset"]: spaReset ? "true" : void 0
|
|
1602
|
+
}, { method: "post" }, null, 0, key);
|
|
1603
|
+
} else return /*#__PURE__*/ createElement(GetForm, {
|
|
1604
|
+
...rest,
|
|
1605
|
+
spaReset,
|
|
1606
|
+
reloadDocument,
|
|
1607
|
+
onSubmit$,
|
|
1608
|
+
key
|
|
1609
|
+
});
|
|
1610
|
+
};
|
|
1496
1611
|
var GetForm = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((_rawProps) => {
|
|
1497
1612
|
const rest = _restProps(_rawProps, [
|
|
1498
1613
|
"action",
|
|
@@ -1503,14 +1618,12 @@ var GetForm = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((_rawProps) =>
|
|
|
1503
1618
|
const nav = useNavigate();
|
|
1504
1619
|
return /*#__PURE__*/ _jsxSplit("form", {
|
|
1505
1620
|
action: "get",
|
|
1506
|
-
"
|
|
1507
|
-
"data-spa-reset": _fnSignal(_hf1, [_rawProps], _hf1_str),
|
|
1621
|
+
"data-spa-reset": _fnSignal(_hf0, [_rawProps], _hf0_str),
|
|
1508
1622
|
..._getVarProps(rest),
|
|
1509
|
-
..._getConstProps(rest),
|
|
1510
1623
|
"q-e:submit": [
|
|
1511
1624
|
...Array.isArray(_rawProps.onSubmit$) ? _rawProps.onSubmit$ : [_rawProps.onSubmit$],
|
|
1512
1625
|
/*#__PURE__*/ inlinedQrl(async (_evt, form) => {
|
|
1513
|
-
|
|
1626
|
+
let nav = _capturesObj._[0];
|
|
1514
1627
|
const formData = new FormData(form);
|
|
1515
1628
|
const params = new URLSearchParams();
|
|
1516
1629
|
formData.forEach((value, key) => {
|
|
@@ -1531,40 +1644,16 @@ var GetForm = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((_rawProps) =>
|
|
|
1531
1644
|
}));
|
|
1532
1645
|
}, "GetForm_component_form_q_e_submit_1_cuYklZAOHrA")
|
|
1533
1646
|
]
|
|
1534
|
-
},
|
|
1647
|
+
}, {
|
|
1648
|
+
..._getConstProps(rest),
|
|
1649
|
+
"preventdefault:submit": true
|
|
1650
|
+
}, /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "TF_0"), 0, "TF_1");
|
|
1535
1651
|
}, "GetForm_component_2U5Z2Z8ryc0"));
|
|
1536
|
-
/** @public */ var Form = ({ action, spaReset, reloadDocument, onSubmit$, ...rest }, key) => {
|
|
1537
|
-
if (action) {
|
|
1538
|
-
if (Array.isArray(onSubmit$)) return _jsxSplit("form", {
|
|
1539
|
-
..._getVarProps(rest),
|
|
1540
|
-
..._getConstProps(rest),
|
|
1541
|
-
action: _wrapProp(action, "actionPath"),
|
|
1542
|
-
"preventdefault:submit": !reloadDocument,
|
|
1543
|
-
"q-e:submit": [...onSubmit$, !reloadDocument ? /*#__PURE__*/ inlinedQrl((evt) => {
|
|
1544
|
-
const action = _captures[0];
|
|
1545
|
-
if (!action.submitted) return action.submit(evt);
|
|
1546
|
-
}, "Form_form_q_e_submit_6i0Jq5q8JFg", [action]) : void 0],
|
|
1547
|
-
["data-spa-reset"]: spaReset ? "true" : void 0
|
|
1548
|
-
}, { method: "post" }, null, 0, key);
|
|
1549
|
-
return _jsxSplit("form", {
|
|
1550
|
-
..._getVarProps(rest),
|
|
1551
|
-
..._getConstProps(rest),
|
|
1552
|
-
action: _wrapProp(action, "actionPath"),
|
|
1553
|
-
"preventdefault:submit": !reloadDocument,
|
|
1554
|
-
"q-e:submit": [onSubmit$, !reloadDocument ? action.submit : void 0],
|
|
1555
|
-
["data-spa-reset"]: spaReset ? "true" : void 0
|
|
1556
|
-
}, { method: "post" }, null, 0, key);
|
|
1557
|
-
} else return /*#__PURE__*/ _jsxSplit(GetForm, {
|
|
1558
|
-
spaReset,
|
|
1559
|
-
reloadDocument,
|
|
1560
|
-
onSubmit$,
|
|
1561
|
-
...rest
|
|
1562
|
-
}, null, null, 0, key);
|
|
1563
|
-
};
|
|
1564
1652
|
/**
|
|
1565
1653
|
* @beta
|
|
1566
1654
|
* @experimental
|
|
1567
|
-
*/
|
|
1655
|
+
*/
|
|
1656
|
+
var untypedAppUrl = function appUrl(route, params, paramsPrefix = "") {
|
|
1568
1657
|
const path = route.split("/");
|
|
1569
1658
|
for (let i = 0; i < path.length; i++) {
|
|
1570
1659
|
const segment = path[i];
|
|
@@ -1590,7 +1679,8 @@ var GetForm = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((_rawProps) =>
|
|
|
1590
1679
|
*
|
|
1591
1680
|
* @beta
|
|
1592
1681
|
* @experimental
|
|
1593
|
-
*/
|
|
1682
|
+
*/
|
|
1683
|
+
function omitProps(obj, keys) {
|
|
1594
1684
|
const omittedObj = {};
|
|
1595
1685
|
for (const key in obj) if (!key.startsWith("param:") && !keys.includes(key)) omittedObj[key] = obj[key];
|
|
1596
1686
|
return omittedObj;
|
|
@@ -1621,8 +1711,9 @@ var GetForm = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((_rawProps) =>
|
|
|
1621
1711
|
* ```
|
|
1622
1712
|
*
|
|
1623
1713
|
* @public
|
|
1624
|
-
*/
|
|
1625
|
-
|
|
1714
|
+
*/
|
|
1715
|
+
var createRenderer = (getOptions) => {
|
|
1716
|
+
return ((opts) => {
|
|
1626
1717
|
const { jsx, options } = getOptions(opts);
|
|
1627
1718
|
const renderOptions = opts.serverData.renderMode === "static" ? {
|
|
1628
1719
|
...options,
|
|
@@ -1632,7 +1723,7 @@ var GetForm = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((_rawProps) =>
|
|
|
1632
1723
|
}
|
|
1633
1724
|
} : options;
|
|
1634
1725
|
return renderToStream(jsx, renderOptions);
|
|
1635
|
-
};
|
|
1726
|
+
});
|
|
1636
1727
|
};
|
|
1637
1728
|
/**
|
|
1638
1729
|
* This renders all the tags collected from `head`.
|
|
@@ -1655,16 +1746,17 @@ var GetForm = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((_rawProps) =>
|
|
|
1655
1746
|
* `src/root.tsx` to make runtime changes to `<head>` if needed.
|
|
1656
1747
|
*
|
|
1657
1748
|
* @public
|
|
1658
|
-
*/
|
|
1749
|
+
*/
|
|
1750
|
+
var DocumentHeadTags = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props) => {
|
|
1659
1751
|
let head = useDocumentHead();
|
|
1660
1752
|
if (props) head = {
|
|
1661
1753
|
...head,
|
|
1662
1754
|
...props
|
|
1663
1755
|
};
|
|
1664
1756
|
return /*#__PURE__*/ _jsxSorted(Fragment, null, null, [
|
|
1665
|
-
head.title && /*#__PURE__*/ _jsxSorted("title", null, null, head.title, 1, "
|
|
1666
|
-
head.meta.map((m) => /*#__PURE__*/ _jsxSplit("meta", { ..._getVarProps(m) }, _getConstProps(m), null, 0, "
|
|
1667
|
-
head.links.map((l) => /*#__PURE__*/ _jsxSplit("link", { ..._getVarProps(l) }, _getConstProps(l), null, 0, "
|
|
1757
|
+
head.title && /*#__PURE__*/ _jsxSorted("title", null, null, head.title, 1, "eL_0"),
|
|
1758
|
+
head.meta.map((m) => /*#__PURE__*/ _jsxSplit("meta", { ..._getVarProps(m) }, _getConstProps(m), null, 0, "eL_1")),
|
|
1759
|
+
head.links.map((l) => /*#__PURE__*/ _jsxSplit("link", { ..._getVarProps(l) }, _getConstProps(l), null, 0, "eL_2")),
|
|
1668
1760
|
head.styles.map((s) => {
|
|
1669
1761
|
const props = s.props || s;
|
|
1670
1762
|
return /*#__PURE__*/ createElement("style", {
|
|
@@ -1681,6 +1773,6 @@ var GetForm = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((_rawProps) =>
|
|
|
1681
1773
|
key: s.key
|
|
1682
1774
|
});
|
|
1683
1775
|
})
|
|
1684
|
-
], 1, "
|
|
1776
|
+
], 1, "eL_3");
|
|
1685
1777
|
}, "DocumentHeadTags_component_9CrWYOoCpgY"));
|
|
1686
|
-
export { DocumentHeadTags, Form, Link, QWIK_CITY_SCROLLER, QWIK_ROUTER_SCROLLER, QwikCityMockProvider, QwikCityProvider, QwikRouterMockProvider, QwikRouterProvider, RouterOutlet, ServiceWorkerRegister, createRenderer, getRequestEvent, globalAction$, globalActionQrl, omitProps, routeAction$, routeActionQrl, routeLoader$, routeLoaderQrl, server$, serverQrl, untypedAppUrl, useContent, useDocumentHead, useHttpStatus, useLocation, useNavigate, usePreventNavigate$, usePreventNavigateQrl, useQwikRouter, valibot$, valibotQrl, validator$, validatorQrl, z, zod$, zodQrl };
|
|
1778
|
+
export { DocumentHeadTags, Form, Link, QWIK_CITY_SCROLLER, QWIK_ROUTER_SCROLLER, QwikCityMockProvider, QwikCityProvider, QwikRouterMockProvider, QwikRouterProvider, RouterOutlet, ServiceWorkerRegister, _getServiceWorkerScript, _setRouterConfig, createRenderer, getBasePathname, getRequestEvent, getRouterConfig, getRoutes, getTrailingSlash, globalAction$, globalActionQrl, omitProps, routeAction$, routeActionQrl, routeLoader$, routeLoaderQrl, server$, serverQrl, untypedAppUrl, useContent, useDocumentHead, useHttpStatus, useLocation, useNavigate, usePreventNavigate$, usePreventNavigateQrl, useQwikRouter, valibot$, valibotQrl, validator$, validatorQrl, z, zod$, zodQrl };
|