@qwik.dev/router 2.0.0-beta.38 → 2.0.0-beta.39
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/chunks/head.qwik.mjs +72 -72
- package/lib/chunks/use-functions.qwik.mjs +1 -1
- package/lib/chunks/user-response.mjs +32 -12
- package/lib/chunks/worker-thread.mjs +2 -2
- package/lib/index.d.ts +15 -22
- package/lib/index.qwik.mjs +54 -37
- package/lib/middleware/request-handler/index.mjs +3 -2
- package/lib/vite/index.mjs +2 -2
- package/package.json +4 -4
package/lib/chunks/head.qwik.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { e as ensureSlash } from './pathname.mjs';
|
|
2
2
|
import { createContextId, isServer as isServer$1, implicit$FirstArg, isDev, createComputedQrl, inlinedQrl, _captures, withLocale } from '@qwik.dev/core';
|
|
3
3
|
import * as qwikRouterConfig from '@qwik-router-config';
|
|
4
|
-
import { _getAsyncLocalStorage, _getContextEvent, _resolveContextWithoutSequentialScope, _injectAsyncSignalValue, _UNINITIALIZED,
|
|
4
|
+
import { _getAsyncLocalStorage, _getContextEvent, _resolveContextWithoutSequentialScope, _injectAsyncSignalValue, _UNINITIALIZED, _deserialize, _markSignalAsExternallyOwned, SerializerSymbol, _verifySerializable } from '@qwik.dev/core/internal';
|
|
5
5
|
import { isServer } from '@qwik.dev/core/build';
|
|
6
6
|
import { g as getLoaderName } from './request-path.mjs';
|
|
7
7
|
import { R as RedirectMessage, S as ServerError, t as throwIfControlFlowSignal } from './server-error.mjs';
|
|
@@ -578,6 +578,7 @@ const RouteActionContext = /* @__PURE__ */ createContextId("qr-a");
|
|
|
578
578
|
const RoutePreventNavigateContext = /* @__PURE__ */ createContextId("qr-p");
|
|
579
579
|
const HttpStatusContext = /* @__PURE__ */ createContextId("qr-hs");
|
|
580
580
|
|
|
581
|
+
const REQUEST_ROUTE_LOADER_STATE = "@routeLoaderState";
|
|
581
582
|
const REQUEST_LOADER_PATHS_STORE = "@loaderPathsStore";
|
|
582
583
|
const REQUEST_ROUTE_LOADERS = "@routeLoaders";
|
|
583
584
|
const REQUEST_ROUTE_LOADER_PROMISES = "@routeLoaderPromises";
|
|
@@ -586,20 +587,9 @@ const REQUEST_ROUTE_LOADER_ROOT_EVENT = "@routeLoaderRootEvent";
|
|
|
586
587
|
const ROUTE_LOADER_VALUE_PREFIX = "__qwik_route_loader_value__";
|
|
587
588
|
const FULLPATH_HEADER = "X-Qwik-fullpath";
|
|
588
589
|
const ROUTE_PATH_HEADER = "X-Qwik-route-path";
|
|
589
|
-
const
|
|
590
|
-
const
|
|
591
|
-
const fetchCache = /* @__PURE__ */ new Map();
|
|
592
|
-
const perfNow = () => globalThis.performance?.now() ?? Date.now();
|
|
590
|
+
const navFetchCache = /* @__PURE__ */ new Map();
|
|
591
|
+
const clearNavFetchCache = () => navFetchCache.clear();
|
|
593
592
|
const isRedirectStatus = (status) => status >= 300 && status < 400;
|
|
594
|
-
const setCache = (key, entry) => {
|
|
595
|
-
fetchCache.set(key, entry);
|
|
596
|
-
if (fetchCache.size > LOADER_FETCH_CACHE_MAX) {
|
|
597
|
-
const oldestKey = fetchCache.keys().next().value;
|
|
598
|
-
if (oldestKey !== void 0) {
|
|
599
|
-
fetchCache.delete(oldestKey);
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
};
|
|
603
593
|
const wrapWithAbort = (promise, signal) => {
|
|
604
594
|
if (signal.aborted) {
|
|
605
595
|
return Promise.reject(signal.reason);
|
|
@@ -639,15 +629,9 @@ const fetchRouteLoaderData = async (loaderId, routePath, manifestHash, opts) =>
|
|
|
639
629
|
const cacheKey = `${url}
|
|
640
630
|
${headers[FULLPATH_HEADER] ?? ""}`;
|
|
641
631
|
if (!opts?.ignoreCache) {
|
|
642
|
-
const entry =
|
|
632
|
+
const entry = navFetchCache.get(cacheKey);
|
|
643
633
|
if (entry) {
|
|
644
|
-
|
|
645
|
-
return opts?.signal ? wrapWithAbort(entry.promise, opts.signal) : entry.promise;
|
|
646
|
-
}
|
|
647
|
-
if (entry.expires > perfNow()) {
|
|
648
|
-
return entry.value;
|
|
649
|
-
}
|
|
650
|
-
fetchCache.delete(cacheKey);
|
|
634
|
+
return opts?.signal ? wrapWithAbort(entry, opts.signal) : entry;
|
|
651
635
|
}
|
|
652
636
|
}
|
|
653
637
|
const request = async () => {
|
|
@@ -672,41 +656,31 @@ ${headers[FULLPATH_HEADER] ?? ""}`;
|
|
|
672
656
|
if (!response.ok) {
|
|
673
657
|
return void 0;
|
|
674
658
|
}
|
|
675
|
-
|
|
676
|
-
|
|
659
|
+
return {
|
|
660
|
+
raw: await response.text()
|
|
661
|
+
};
|
|
677
662
|
};
|
|
678
663
|
if (opts?.ignoreCache) {
|
|
679
664
|
return request();
|
|
680
665
|
}
|
|
681
666
|
if (opts?.signal) {
|
|
682
667
|
return request().then((value) => {
|
|
683
|
-
if (value !== void 0 && !
|
|
684
|
-
|
|
685
|
-
value,
|
|
686
|
-
expires: perfNow() + LOADER_FETCH_CACHE_TTL
|
|
687
|
-
});
|
|
668
|
+
if (value !== void 0 && !navFetchCache.has(cacheKey)) {
|
|
669
|
+
navFetchCache.set(cacheKey, Promise.resolve(value));
|
|
688
670
|
}
|
|
689
671
|
return value;
|
|
690
672
|
});
|
|
691
673
|
}
|
|
692
674
|
const promise = request().then((value) => {
|
|
693
675
|
if (value === void 0) {
|
|
694
|
-
|
|
695
|
-
} else {
|
|
696
|
-
setCache(cacheKey, {
|
|
697
|
-
value,
|
|
698
|
-
expires: perfNow() + LOADER_FETCH_CACHE_TTL
|
|
699
|
-
});
|
|
676
|
+
navFetchCache.delete(cacheKey);
|
|
700
677
|
}
|
|
701
678
|
return value;
|
|
702
679
|
}, (err) => {
|
|
703
|
-
|
|
680
|
+
navFetchCache.delete(cacheKey);
|
|
704
681
|
throw err;
|
|
705
682
|
});
|
|
706
|
-
|
|
707
|
-
promise,
|
|
708
|
-
expires: perfNow() + LOADER_FETCH_CACHE_TTL
|
|
709
|
-
});
|
|
683
|
+
navFetchCache.set(cacheKey, promise);
|
|
710
684
|
return promise;
|
|
711
685
|
};
|
|
712
686
|
const filterSearchParams = (params, allowed) => {
|
|
@@ -724,12 +698,10 @@ const filterSearchParams = (params, allowed) => {
|
|
|
724
698
|
const getLoaderOptions = (rest) => {
|
|
725
699
|
let id;
|
|
726
700
|
let serializationStrategy = DEFAULT_LOADERS_SERIALIZATION_STRATEGY;
|
|
727
|
-
let
|
|
728
|
-
let poll;
|
|
701
|
+
let cacheControl;
|
|
729
702
|
let eTag;
|
|
730
703
|
let cacheKey;
|
|
731
704
|
let search;
|
|
732
|
-
let allowStale = true;
|
|
733
705
|
let blockSSR = true;
|
|
734
706
|
const validators = [];
|
|
735
707
|
if (rest.length === 1) {
|
|
@@ -747,11 +719,8 @@ const getLoaderOptions = (rest) => {
|
|
|
747
719
|
if (options.validation) {
|
|
748
720
|
validators.push(...options.validation);
|
|
749
721
|
}
|
|
750
|
-
if ("
|
|
751
|
-
|
|
752
|
-
}
|
|
753
|
-
if ("poll" in options) {
|
|
754
|
-
poll = options.poll;
|
|
722
|
+
if ("cacheControl" in options) {
|
|
723
|
+
cacheControl = options.cacheControl;
|
|
755
724
|
}
|
|
756
725
|
if ("eTag" in options) {
|
|
757
726
|
eTag = options.eTag;
|
|
@@ -764,9 +733,6 @@ const getLoaderOptions = (rest) => {
|
|
|
764
733
|
} else if (globalThis.__STRICT_LOADERS__) {
|
|
765
734
|
search = [];
|
|
766
735
|
}
|
|
767
|
-
if (options.allowStale === false) {
|
|
768
|
-
allowStale = false;
|
|
769
|
-
}
|
|
770
736
|
if (options.blockSSR === false) {
|
|
771
737
|
if (!__EXPERIMENTAL__.blockSSR) {
|
|
772
738
|
throw new Error('`blockSSR: false` is an experimental feature and is not enabled. Please enable the feature flag by adding `experimental: ["blockSSR"]` to your qwikVite plugin options.');
|
|
@@ -782,12 +748,10 @@ const getLoaderOptions = (rest) => {
|
|
|
782
748
|
id,
|
|
783
749
|
validators: validators.reverse(),
|
|
784
750
|
serializationStrategy,
|
|
785
|
-
|
|
786
|
-
poll,
|
|
751
|
+
cacheControl,
|
|
787
752
|
eTag,
|
|
788
753
|
cacheKey,
|
|
789
754
|
search,
|
|
790
|
-
allowStale,
|
|
791
755
|
blockSSR
|
|
792
756
|
};
|
|
793
757
|
};
|
|
@@ -817,6 +781,14 @@ function getRouteLoaderPromises(requestEv) {
|
|
|
817
781
|
}
|
|
818
782
|
return promises;
|
|
819
783
|
}
|
|
784
|
+
function clearRouteLoaderData(requestEv) {
|
|
785
|
+
requestEv.sharedMap.delete(REQUEST_ROUTE_LOADER_STATE);
|
|
786
|
+
requestEv.sharedMap.delete(REQUEST_ROUTE_LOADER_VALUES);
|
|
787
|
+
requestEv.sharedMap.delete(REQUEST_ROUTE_LOADER_PROMISES);
|
|
788
|
+
requestEv.sharedMap.delete(REQUEST_ROUTE_LOADER_EVENTS);
|
|
789
|
+
requestEv.sharedMap.delete(REQUEST_ROUTE_LOADER_ROOT_EVENT);
|
|
790
|
+
requestEv.sharedMap.delete(REQUEST_ROUTE_LOADERS);
|
|
791
|
+
}
|
|
820
792
|
function setRouteLoaders(requestEv, loaders) {
|
|
821
793
|
requestEv.sharedMap.set(REQUEST_ROUTE_LOADERS, loaders);
|
|
822
794
|
}
|
|
@@ -875,6 +847,15 @@ const getModuleRouteLoaders = (mods) => {
|
|
|
875
847
|
}
|
|
876
848
|
return routeLoaders;
|
|
877
849
|
};
|
|
850
|
+
const immutableLoaderIds = /* @__PURE__ */ new Set();
|
|
851
|
+
const isImmutableLoader = (loaderId) => immutableLoaderIds.has(loaderId);
|
|
852
|
+
const invalidateNavRouteLoaders = (state) => {
|
|
853
|
+
for (const id in state) {
|
|
854
|
+
if (!id.startsWith(ROUTE_LOADER_VALUE_PREFIX) && !immutableLoaderIds.has(id)) {
|
|
855
|
+
state[id].invalidate();
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
};
|
|
878
859
|
const setLoaderSignalValue = (signal, value) => {
|
|
879
860
|
_injectAsyncSignalValue(signal, value);
|
|
880
861
|
};
|
|
@@ -907,7 +888,16 @@ ${filteredSearch}`;
|
|
|
907
888
|
if (!loaderRequestEv) {
|
|
908
889
|
url.pathname = pathname;
|
|
909
890
|
url.search = filteredSearch;
|
|
891
|
+
const request = new Request(url, rootRequestEv.request);
|
|
910
892
|
loaderRequestEv = Object.create(rootRequestEv, {
|
|
893
|
+
originalUrl: {
|
|
894
|
+
value: new URL(url),
|
|
895
|
+
enumerable: true
|
|
896
|
+
},
|
|
897
|
+
params: {
|
|
898
|
+
value: {},
|
|
899
|
+
enumerable: true
|
|
900
|
+
},
|
|
911
901
|
pathname: {
|
|
912
902
|
get: () => url.pathname,
|
|
913
903
|
enumerable: true
|
|
@@ -916,6 +906,10 @@ ${filteredSearch}`;
|
|
|
916
906
|
get: () => url.searchParams,
|
|
917
907
|
enumerable: true
|
|
918
908
|
},
|
|
909
|
+
request: {
|
|
910
|
+
value: request,
|
|
911
|
+
enumerable: true
|
|
912
|
+
},
|
|
919
913
|
url: {
|
|
920
914
|
value: url,
|
|
921
915
|
enumerable: true
|
|
@@ -1082,6 +1076,7 @@ const createRouteLoaderSignal = (loader, routeLoaderCtx, state) => {
|
|
|
1082
1076
|
if (!isServer$1 && resumeValueKey2 in stateValues2) {
|
|
1083
1077
|
stateValues2[resumeValueKey2] = value;
|
|
1084
1078
|
}
|
|
1079
|
+
lastFetch2.raw = void 0;
|
|
1085
1080
|
return value;
|
|
1086
1081
|
}
|
|
1087
1082
|
if (isServer$1) {
|
|
@@ -1099,24 +1094,30 @@ const createRouteLoaderSignal = (loader, routeLoaderCtx, state) => {
|
|
|
1099
1094
|
}
|
|
1100
1095
|
let fetchUrl = pageUrl;
|
|
1101
1096
|
if (searchFilter2) {
|
|
1102
|
-
const filteredSearch = filterSearchParams(pageUrl.searchParams, searchFilter2);
|
|
1103
|
-
if (ctx.previous !== void 0 && filteredSearch === lastFetch2.filteredSearch && fetchRoutePath === lastFetch2.routePath) {
|
|
1104
|
-
return ctx.previous;
|
|
1105
|
-
}
|
|
1106
|
-
lastFetch2.filteredSearch = filteredSearch;
|
|
1107
|
-
lastFetch2.routePath = fetchRoutePath;
|
|
1108
1097
|
fetchUrl = new URL(pageUrl.href);
|
|
1109
|
-
fetchUrl.search =
|
|
1098
|
+
fetchUrl.search = filterSearchParams(pageUrl.searchParams, searchFilter2);
|
|
1110
1099
|
}
|
|
1111
|
-
const
|
|
1100
|
+
const result = await fetchRouteLoaderData(id2, fetchRoutePath, mHash, {
|
|
1112
1101
|
pageUrl: fetchUrl,
|
|
1113
1102
|
basePath,
|
|
1114
1103
|
ignoreCache: ctx.info === true,
|
|
1115
1104
|
signal: ctx.abortSignal
|
|
1116
1105
|
});
|
|
1117
|
-
if (!
|
|
1106
|
+
if (!result) {
|
|
1118
1107
|
throw new Error(`Loader ${id2} returned empty response`);
|
|
1119
1108
|
}
|
|
1109
|
+
let response;
|
|
1110
|
+
if (result.raw === void 0) {
|
|
1111
|
+
response = result;
|
|
1112
|
+
} else {
|
|
1113
|
+
if (result.raw === lastFetch2.raw && ctx.previous !== void 0) {
|
|
1114
|
+
return ctx.previous;
|
|
1115
|
+
}
|
|
1116
|
+
response = await _deserialize(result.raw);
|
|
1117
|
+
if (!response) {
|
|
1118
|
+
throw new Error(`Loader ${id2} returned empty response`);
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1120
1121
|
if (response.r) {
|
|
1121
1122
|
const goto = routeLoaderCtx2.goto;
|
|
1122
1123
|
if (goto) {
|
|
@@ -1131,6 +1132,7 @@ const createRouteLoaderSignal = (loader, routeLoaderCtx, state) => {
|
|
|
1131
1132
|
if (response.e) {
|
|
1132
1133
|
throw response.e;
|
|
1133
1134
|
}
|
|
1135
|
+
lastFetch2.raw = result.raw;
|
|
1134
1136
|
if (needsResumeFetch) {
|
|
1135
1137
|
stateValues2[resumeValueKey2] = response.d;
|
|
1136
1138
|
}
|
|
@@ -1144,15 +1146,15 @@ const createRouteLoaderSignal = (loader, routeLoaderCtx, state) => {
|
|
|
1144
1146
|
searchFilter,
|
|
1145
1147
|
stateValues
|
|
1146
1148
|
]), {
|
|
1147
|
-
serializationStrategy: loader.__serializationStrategy
|
|
1148
|
-
expires: loader.__expires,
|
|
1149
|
-
poll: loader.__poll,
|
|
1150
|
-
allowStale: loader.__allowStale
|
|
1149
|
+
serializationStrategy: loader.__serializationStrategy
|
|
1151
1150
|
});
|
|
1152
1151
|
_markSignalAsExternallyOwned(signal);
|
|
1153
1152
|
return signal;
|
|
1154
1153
|
};
|
|
1155
1154
|
const ensureRouteLoaderSignal = (loader, state, routeLoaderCtx) => {
|
|
1155
|
+
if (loader.__cacheControl === "immutable") {
|
|
1156
|
+
immutableLoaderIds.add(loader.__id);
|
|
1157
|
+
}
|
|
1156
1158
|
if (isServer$1 && loader.__serializationStrategy === "never") {
|
|
1157
1159
|
state[getRouteLoaderValueStateKey(loader.__id)] = _UNINITIALIZED;
|
|
1158
1160
|
}
|
|
@@ -1205,7 +1207,7 @@ const getRouteLoaderResponse = async (loaderQrl, validators, requestEv) => {
|
|
|
1205
1207
|
}
|
|
1206
1208
|
};
|
|
1207
1209
|
const routeLoaderQrl = (loaderQrl, ...rest) => {
|
|
1208
|
-
const { id, validators, serializationStrategy,
|
|
1210
|
+
const { id, validators, serializationStrategy, cacheControl, eTag, cacheKey, search, blockSSR } = getLoaderOptions(rest);
|
|
1209
1211
|
function loader() {
|
|
1210
1212
|
const state = _resolveContextWithoutSequentialScope(RouteStateContext);
|
|
1211
1213
|
let signal = state[loader.__id];
|
|
@@ -1221,12 +1223,10 @@ const routeLoaderQrl = (loaderQrl, ...rest) => {
|
|
|
1221
1223
|
loader.__validators = validators;
|
|
1222
1224
|
loader.__id = id ?? loaderQrl.getHash();
|
|
1223
1225
|
loader.__serializationStrategy = serializationStrategy;
|
|
1224
|
-
loader.
|
|
1225
|
-
loader.__poll = poll ?? false;
|
|
1226
|
+
loader.__cacheControl = cacheControl;
|
|
1226
1227
|
loader.__eTag = eTag;
|
|
1227
1228
|
loader.__cacheKey = cacheKey;
|
|
1228
1229
|
loader.__search = search;
|
|
1229
|
-
loader.__allowStale = allowStale;
|
|
1230
1230
|
loader.__blockSSR = blockSSR;
|
|
1231
1231
|
Object.freeze(loader);
|
|
1232
1232
|
return loader;
|
|
@@ -1422,4 +1422,4 @@ const resolveHead = (actionData, loaderState, routeLocation, contentModules, loc
|
|
|
1422
1422
|
return resolveRouteConfig(getData, routeLocation, contentModules, locale, actionData?.status ?? 200, defaults).head;
|
|
1423
1423
|
};
|
|
1424
1424
|
|
|
1425
|
-
export {
|
|
1425
|
+
export { QFN_KEY as A, QDATA_KEY as B, ContentContext as C, DocumentHeadContext as D, routeLoader$ as E, FULLPATH_HEADER as F, routeLoaderQrl as G, HttpStatusContext as H, getRouteLoaders as I, getRouteLoaderValues as J, loadRouteLoader as K, isPromise as L, getLoaderRequestEvent as M, resolveRouteLoaderByHash as N, getRouteLoaderResponse as O, getRouteLoaderCtx as P, QACTION_KEY as Q, ROUTE_PATH_HEADER as R, setRouteLoaders as S, resolveRouteConfig as T, clearRouteLoaderData as U, matchesRouteLoaderId as V, _asyncRequestStore as _, getClientNavPath as a, isSameOrigin as b, setLoaderSignalValue as c, createDocumentHead as d, ensureRouteLoaderSignals as e, fetchRouteLoaderData as f, getModuleRouteLoaders as g, ContentInternalContext as h, isSamePath as i, RouteLocationContext as j, RouteNavigateContext as k, loadRoute as l, RouteStateContext as m, RouteLoaderCtxContext as n, RouteActionContext as o, RoutePreventNavigateContext as p, invalidateNavRouteLoaders as q, isImmutableLoader as r, shouldPreload as s, toPath as t, updateRouteLoaderPaths as u, clearNavFetchCache as v, resolveHead as w, Q_ROUTE as x, toUrl as y, getRequestEvent as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useContext, implicit$FirstArg, useVisibleTaskQrl, inlinedQrl, _captures, noSerialize, useServerData } from '@qwik.dev/core';
|
|
2
|
-
import { C as ContentContext, D as DocumentHeadContext, H as HttpStatusContext,
|
|
2
|
+
import { C as ContentContext, D as DocumentHeadContext, H as HttpStatusContext, j as RouteLocationContext, k as RouteNavigateContext, p as RoutePreventNavigateContext, o as RouteActionContext } from './head.qwik.mjs';
|
|
3
3
|
|
|
4
4
|
const useHttpStatus = () => useContext(HttpStatusContext).value;
|
|
5
5
|
const useContent = () => useContext(ContentContext);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isDev as isDev$1, inlinedQrl } from '@qwik.dev/core';
|
|
2
2
|
import { isDev, _deserialize, _serialize, _verifySerializable } from '@qwik.dev/core/internal';
|
|
3
|
-
import { Q as QACTION_KEY,
|
|
3
|
+
import { Q as QACTION_KEY, J as getRouteLoaderValues, K as loadRouteLoader, L as isPromise, B as QDATA_KEY, M as getLoaderRequestEvent, N as resolveRouteLoaderByHash, O as getRouteLoaderResponse, P as getRouteLoaderCtx, S as setRouteLoaders, F as FULLPATH_HEADER, x as Q_ROUTE, A as QFN_KEY, T as resolveRouteConfig, U as clearRouteLoaderData, V as matchesRouteLoaderId, _ as _asyncRequestStore } from './head.qwik.mjs';
|
|
4
4
|
import { e as ensureSlash } from './pathname.mjs';
|
|
5
5
|
import { r as recognizeRequest, t as trimRecognizedInternalPathname, Q as QLoaderId, c as IsQAction, d as QActionId, I as IsQLoader, a as resolveValidInternalFullPathname } from './request-path.mjs';
|
|
6
6
|
import { A as AbortMessage, S as ServerError, R as RedirectMessage, t as throwIfControlFlowSignal } from './server-error.mjs';
|
|
@@ -737,6 +737,20 @@ function createLoaderRequestEventFactory(requestEv) {
|
|
|
737
737
|
return (loader) => getLoaderRequestEvent(loader, requestEv);
|
|
738
738
|
}
|
|
739
739
|
|
|
740
|
+
function resolveLoaderCacheControl(option, requestEv) {
|
|
741
|
+
const value = typeof option === "function" ? option(requestEv) : option;
|
|
742
|
+
return value === void 0 ? "no-cache" : value;
|
|
743
|
+
}
|
|
744
|
+
async function runBlockingLoadersBeforeTarget(routeLoaders, targetLoader, requestEv) {
|
|
745
|
+
for (const loader of routeLoaders) {
|
|
746
|
+
if (loader === targetLoader) {
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
if (loader.__blockSSR) {
|
|
750
|
+
await loadRouteLoader(loader, requestEv);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
740
754
|
function setLoaderData(requestEv, routeLoaders, loaderPaths) {
|
|
741
755
|
if (loaderPaths) {
|
|
742
756
|
Object.assign(getRouteLoaderCtx(requestEv).loaderPaths, loaderPaths);
|
|
@@ -761,14 +775,11 @@ function addVaryHeader(requestEv, value) {
|
|
|
761
775
|
requestEv.headers.set("Vary", `${vary}, ${value}`);
|
|
762
776
|
}
|
|
763
777
|
}
|
|
764
|
-
async function sendLoaderResponse(requestEv, data,
|
|
778
|
+
async function sendLoaderResponse(requestEv, data, cacheControl) {
|
|
765
779
|
requestEv.headers.set("Content-Type", "application/json; charset=utf-8");
|
|
766
780
|
addVaryHeader(requestEv, FULLPATH_HEADER);
|
|
767
|
-
if (
|
|
768
|
-
requestEv.cacheControl(
|
|
769
|
-
maxAge: Math.ceil(loader.__expires / 1e3),
|
|
770
|
-
private: true
|
|
771
|
-
});
|
|
781
|
+
if (cacheControl !== null && !requestEv.headers.has("Cache-Control")) {
|
|
782
|
+
requestEv.cacheControl(cacheControl);
|
|
772
783
|
}
|
|
773
784
|
requestEv.send(200, data);
|
|
774
785
|
}
|
|
@@ -790,7 +801,9 @@ function loaderHandler(routeLoaders, loaderPaths) {
|
|
|
790
801
|
return;
|
|
791
802
|
}
|
|
792
803
|
setLoaderData(requestEv, routeLoaders, loaderPaths);
|
|
804
|
+
await runBlockingLoadersBeforeTarget(routeLoaders, loader, requestEv);
|
|
793
805
|
const loaderRequestEv = createLoaderRequestEventFactory(requestEv)(loader);
|
|
806
|
+
const cacheControl = resolveLoaderCacheControl(loader.__cacheControl, loaderRequestEv);
|
|
794
807
|
const normalizedETag = loader.__eTag !== void 0 ? resolvePreETag(loader.__eTag, loaderRequestEv) : "";
|
|
795
808
|
if (normalizedETag && performETagMatch(loaderRequestEv, normalizedETag)) {
|
|
796
809
|
return;
|
|
@@ -809,7 +822,7 @@ function loaderHandler(routeLoaders, loaderPaths) {
|
|
|
809
822
|
} else {
|
|
810
823
|
setETagHeader(loaderRequestEv, cached.eTag);
|
|
811
824
|
}
|
|
812
|
-
await sendLoaderResponse(requestEv, cached.body,
|
|
825
|
+
await sendLoaderResponse(requestEv, cached.body, cacheControl);
|
|
813
826
|
return;
|
|
814
827
|
}
|
|
815
828
|
}
|
|
@@ -827,7 +840,7 @@ function loaderHandler(routeLoaders, loaderPaths) {
|
|
|
827
840
|
if (!normalizedETag && finalETag && performETagMatch(loaderRequestEv, finalETag)) {
|
|
828
841
|
return;
|
|
829
842
|
}
|
|
830
|
-
await sendLoaderResponse(requestEv, data,
|
|
843
|
+
await sendLoaderResponse(requestEv, data, cacheControl);
|
|
831
844
|
};
|
|
832
845
|
}
|
|
833
846
|
async function sendJsonResponse(requestEv, responseData, status = 200) {
|
|
@@ -1157,6 +1170,9 @@ function createResolveRequestHandlers() {
|
|
|
1157
1170
|
if (serverPlugins) {
|
|
1158
1171
|
_resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, serverPlugins, isPageRoute, method);
|
|
1159
1172
|
}
|
|
1173
|
+
if (!route.$notFound$ && isPageRoute && (method === "POST" || method === "GET")) {
|
|
1174
|
+
requestHandlers.push(runServerFunction);
|
|
1175
|
+
}
|
|
1160
1176
|
const routeModules = route.$mods$;
|
|
1161
1177
|
_resolveRequestHandlers(routeLoaders, routeActions, requestHandlers, routeModules, isPageRoute, method, isPageRoute);
|
|
1162
1178
|
const routeName = route.$routeName$;
|
|
@@ -1170,9 +1186,6 @@ function createResolveRequestHandlers() {
|
|
|
1170
1186
|
if (isPageRoute) {
|
|
1171
1187
|
requestHandlers.push(loaderHandler(routeLoaders, route.$loaderPaths$));
|
|
1172
1188
|
requestHandlers.push(actionHandler(routeActions));
|
|
1173
|
-
if (method === "POST" || method === "GET") {
|
|
1174
|
-
requestHandlers.push(runServerFunction);
|
|
1175
|
-
}
|
|
1176
1189
|
if (!route.$notFound$) {
|
|
1177
1190
|
requestHandlers.push(fixTrailingSlash2);
|
|
1178
1191
|
}
|
|
@@ -1449,10 +1462,17 @@ function createResolveRequestHandlers() {
|
|
|
1449
1462
|
await loadHttpError()
|
|
1450
1463
|
];
|
|
1451
1464
|
requestEv.sharedMap.set(RequestEvHttpStatusMessage, typeof e.data === "string" ? e.data : "Server Error");
|
|
1465
|
+
clearErrorResponseData(requestEv);
|
|
1452
1466
|
await renderHandler(requestEv);
|
|
1453
1467
|
}
|
|
1454
1468
|
};
|
|
1455
1469
|
}
|
|
1470
|
+
function clearErrorResponseData(requestEv) {
|
|
1471
|
+
clearRouteLoaderData(requestEv);
|
|
1472
|
+
requestEv.sharedMap.delete(RequestEvSharedActionId);
|
|
1473
|
+
requestEv.sharedMap.delete(RequestEvSharedActionFormData);
|
|
1474
|
+
requestEv.sharedMap.delete("@actionResult");
|
|
1475
|
+
}
|
|
1456
1476
|
async function runValidators(requestEv, validators, data) {
|
|
1457
1477
|
let lastResult = {
|
|
1458
1478
|
success: true,
|
|
@@ -2,7 +2,7 @@ import { _serialize } from '@qwik.dev/core/internal';
|
|
|
2
2
|
import { parentPort } from 'node:worker_threads';
|
|
3
3
|
import { r as runQwikRouter, a as resolveRequestHandlers, b as renderQwikMiddleware } from './user-response.mjs';
|
|
4
4
|
import { b as trimInternalPathname } from './request-path.mjs';
|
|
5
|
-
import {
|
|
5
|
+
import { I as getRouteLoaders, J as getRouteLoaderValues, l as loadRoute } from './head.qwik.mjs';
|
|
6
6
|
|
|
7
7
|
const staticWorkerThreadDeps = {
|
|
8
8
|
loadRoute,
|
|
@@ -136,7 +136,7 @@ async function workerRender(sys, opts, staticRoute, pendingPromises, callback, d
|
|
|
136
136
|
const loaderValues = getRouteLoaderValues(requestEv);
|
|
137
137
|
const manifestHash = opts.manifest?.manifestHash || "dev";
|
|
138
138
|
for (const loader of routeLoaders) {
|
|
139
|
-
if (loader.
|
|
139
|
+
if (loader.__cacheControl !== "immutable") {
|
|
140
140
|
continue;
|
|
141
141
|
}
|
|
142
142
|
const data = loaderValues[loader.__id];
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference path="./modules.d.ts" />
|
|
2
2
|
|
|
3
3
|
import type { AbortMessage } from '@qwik.dev/router/middleware/request-handler';
|
|
4
|
+
import type { CacheControl } from '@qwik.dev/router/middleware/request-handler';
|
|
4
5
|
import { Component } from '@qwik.dev/core';
|
|
5
6
|
import type { ComputedSignal } from '@qwik.dev/core';
|
|
6
7
|
import { Cookie } from '@qwik.dev/router/middleware/request-handler';
|
|
@@ -594,19 +595,20 @@ declare type LoaderOptions = {
|
|
|
594
595
|
readonly validation?: DataValidator[];
|
|
595
596
|
readonly serializationStrategy?: SerializationStrategy;
|
|
596
597
|
/**
|
|
597
|
-
*
|
|
598
|
-
*
|
|
598
|
+
* Cache-Control for this loader's JSON responses. The browser HTTP cache is the single source of
|
|
599
|
+
* freshness for loader data: on every client navigation the loaders re-fetch, and this header
|
|
600
|
+
* decides whether the browser serves the fetch from cache, revalidates, or hits the server.
|
|
599
601
|
*
|
|
600
|
-
*
|
|
601
|
-
* the
|
|
602
|
-
*
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
*
|
|
607
|
-
*
|
|
602
|
+
* Accepts any `cacheControl()` value (`'immutable'`, `'no-cache'`, a max-age number, an options
|
|
603
|
+
* object) or a function of the request event; the function may return `null` to skip the header.
|
|
604
|
+
* A `Cache-Control` header set inside the loader function wins over this option.
|
|
605
|
+
*
|
|
606
|
+
* Defaults to `no-cache` (always revalidate; combine with `eTag` for cheap 304s).
|
|
607
|
+
*
|
|
608
|
+
* The literal value `'immutable'` also marks the loader's data as static, so SSG writes a
|
|
609
|
+
* per-loader JSON file at build time.
|
|
608
610
|
*/
|
|
609
|
-
readonly
|
|
611
|
+
readonly cacheControl?: CacheControl | ((ev: RequestEvent) => CacheControl | null);
|
|
610
612
|
/**
|
|
611
613
|
* Enable ETag-based caching for this loader's JSON responses.
|
|
612
614
|
*
|
|
@@ -654,14 +656,6 @@ declare type LoaderOptions = {
|
|
|
654
656
|
* triggers a re-fetch.
|
|
655
657
|
*/
|
|
656
658
|
readonly search?: string[];
|
|
657
|
-
/**
|
|
658
|
-
* When true (default), the previous value is kept while the loader re-fetches after navigation,
|
|
659
|
-
* so components see stale data until the new response arrives.
|
|
660
|
-
*
|
|
661
|
-
* When false, the value is cleared on re-fetch, causing reads to suspend (show a loading
|
|
662
|
-
* boundary). This is useful when showing old data during navigation would be confusing.
|
|
663
|
-
*/
|
|
664
|
-
readonly allowStale?: boolean;
|
|
665
659
|
/**
|
|
666
660
|
* When true (default), the loader is awaited before SSR renders, so its redirect or error can
|
|
667
661
|
* short-circuit the response and its value is ready for synchronous reads (e.g. in the head).
|
|
@@ -1040,10 +1034,9 @@ export declare interface RouteData {
|
|
|
1040
1034
|
* sent in the request and changes to other params are ignored. During SSR and loader JSON
|
|
1041
1035
|
* requests, the loader's request event is filtered to those params too. `search: []` means no
|
|
1042
1036
|
* search params are sent and only route path changes trigger a re-fetch.
|
|
1043
|
-
* - `allowStale: false`: Clears the previous value when re-fetching, so components see a loading
|
|
1044
|
-
* state instead of stale data during navigation. Useful when old data would be confusing.
|
|
1045
1037
|
* - `eTag`: Enable ETag-based caching. Can be `true` (auto-hash), a string, or a function.
|
|
1046
|
-
* - `
|
|
1038
|
+
* - `cacheControl`: Cache-Control for loader JSON responses; the browser HTTP cache controls
|
|
1039
|
+
* client-side freshness. `'immutable'` additionally lets SSG write the loader file.
|
|
1047
1040
|
*
|
|
1048
1041
|
* The `strictLoaders` Vite plugin option applies `search: []` globally for all loaders that don't
|
|
1049
1042
|
* specify an explicit `search` option.
|
package/lib/index.qwik.mjs
CHANGED
|
@@ -3,8 +3,8 @@ import { Fragment } from '@qwik.dev/core/jsx-runtime';
|
|
|
3
3
|
import * as qwikRouterConfig from '@qwik-router-config';
|
|
4
4
|
import { p } from '@qwik.dev/core/preloader';
|
|
5
5
|
import { e as ensureSlash } from './chunks/pathname.mjs';
|
|
6
|
-
import { l as loadRoute, f as fetchRouteLoaderData,
|
|
7
|
-
export {
|
|
6
|
+
import { l as loadRoute, g as getModuleRouteLoaders, f as fetchRouteLoaderData, a as getClientNavPath, s as shouldPreload, i as isSamePath, t as toPath, b as isSameOrigin, Q as QACTION_KEY, e as ensureRouteLoaderSignals, c as setLoaderSignalValue, d as createDocumentHead, C as ContentContext, h as ContentInternalContext, D as DocumentHeadContext, H as HttpStatusContext, j as RouteLocationContext, k as RouteNavigateContext, m as RouteStateContext, n as RouteLoaderCtxContext, o as RouteActionContext, p as RoutePreventNavigateContext, u as updateRouteLoaderPaths, q as invalidateNavRouteLoaders, r as isImmutableLoader, v as clearNavFetchCache, w as resolveHead, x as Q_ROUTE, y as toUrl, z as getRequestEvent, A as QFN_KEY, B as QDATA_KEY } from './chunks/head.qwik.mjs';
|
|
7
|
+
export { E as routeLoader$, G as routeLoaderQrl } from './chunks/head.qwik.mjs';
|
|
8
8
|
import { u as useNavigate, a as useLocation, b as useDocumentHead, c as useQwikRouterEnv, d as useAction } from './chunks/use-functions.qwik.mjs';
|
|
9
9
|
export { e as useContent, f as useHttpStatus, g as usePreventNavigate$, h as usePreventNavigateQrl } from './chunks/use-functions.qwik.mjs';
|
|
10
10
|
import { _deserialize, _hasStoreEffects, _getContextContainer, forceStoreEffects, _waitUntilRendered, _getContextHostElement, _serialize } from '@qwik.dev/core/internal';
|
|
@@ -28,6 +28,30 @@ const ErrorBoundary = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((p
|
|
|
28
28
|
return /* @__PURE__ */ _jsxSorted(Slot, null, null, null, 3, "bA_1");
|
|
29
29
|
}, "ErrorBoundary_component_pOa6vjtC7ik"));
|
|
30
30
|
|
|
31
|
+
const prefetchLoaderData = (loadedRoute, url, manifestHash) => {
|
|
32
|
+
if (!loadedRoute.$loaders$?.length || !loadedRoute.$loaderPaths$) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const immutableIds = new Set(getModuleRouteLoaders(loadedRoute.$mods$).filter((loader) => loader.__cacheControl === "immutable").map((loader) => loader.__id));
|
|
36
|
+
const basePath = qwikRouterConfig.basePathname ?? "/";
|
|
37
|
+
for (const hash of loadedRoute.$loaders$) {
|
|
38
|
+
if (immutableIds.has(hash)) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
let loaderPath = loadedRoute.$loaderPaths$[hash];
|
|
42
|
+
if (!loaderPath) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (basePath !== "/" && !loaderPath.startsWith(basePath)) {
|
|
46
|
+
loaderPath = basePath + loaderPath.slice(1);
|
|
47
|
+
}
|
|
48
|
+
fetchRouteLoaderData(hash, loaderPath, manifestHash, {
|
|
49
|
+
pageUrl: url,
|
|
50
|
+
basePath
|
|
51
|
+
}).catch(() => {
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
};
|
|
31
55
|
async function prefetchRoute(url, prefetchData, probability = 0.8, manifestHash, prefetchBundle = true) {
|
|
32
56
|
if (!isBrowser || isDev) {
|
|
33
57
|
return;
|
|
@@ -48,23 +72,7 @@ async function prefetchRoute(url, prefetchData, probability = 0.8, manifestHash,
|
|
|
48
72
|
if (!prefetchData || !manifestHash) {
|
|
49
73
|
return;
|
|
50
74
|
}
|
|
51
|
-
|
|
52
|
-
const basePath = qwikRouterConfig.basePathname ?? "/";
|
|
53
|
-
for (const hash of loadedRoute.$loaders$) {
|
|
54
|
-
let loaderPath = loadedRoute.$loaderPaths$?.[hash];
|
|
55
|
-
if (!loaderPath) {
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
if (basePath !== "/" && !loaderPath.startsWith(basePath)) {
|
|
59
|
-
loaderPath = basePath + loaderPath.slice(1);
|
|
60
|
-
}
|
|
61
|
-
fetchRouteLoaderData(hash, loaderPath, manifestHash, {
|
|
62
|
-
pageUrl: url,
|
|
63
|
-
basePath
|
|
64
|
-
}).catch(() => {
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
}
|
|
75
|
+
prefetchLoaderData(loadedRoute, url, manifestHash);
|
|
68
76
|
} catch {
|
|
69
77
|
}
|
|
70
78
|
}
|
|
@@ -262,12 +270,10 @@ const refreshLinkPrefetchObserver = (manifestHash) => {
|
|
|
262
270
|
cleanupPrefetchObserver?.();
|
|
263
271
|
cleanupPrefetchObserver = createLinkPrefetchObserver(manifestHash);
|
|
264
272
|
};
|
|
265
|
-
const linkPrefetchInit =
|
|
266
|
-
const
|
|
267
|
-
refreshLinkPrefetchObserver(
|
|
268
|
-
}, "linkPrefetchInit_event_hoZr9O26Irg"
|
|
269
|
-
manifestHash
|
|
270
|
-
]));
|
|
273
|
+
const linkPrefetchInit = eventQrl(/* @__PURE__ */ inlinedQrl((_, element) => {
|
|
274
|
+
const manifestHash = element.closest("[q\\:manifest-hash]")?.getAttribute("q:manifest-hash") || void 0;
|
|
275
|
+
refreshLinkPrefetchObserver(manifestHash);
|
|
276
|
+
}, "linkPrefetchInit_event_hoZr9O26Irg"));
|
|
271
277
|
|
|
272
278
|
function callRestoreScrollOnDocument() {
|
|
273
279
|
if (document.__q_scroll_restore__) {
|
|
@@ -465,9 +471,12 @@ const spaInit = eventQrl(/* @__PURE__ */ inlinedQrl((_, el) => {
|
|
|
465
471
|
}
|
|
466
472
|
}, "spa_init_event_igI1pUsax0E"));
|
|
467
473
|
|
|
468
|
-
async function submitAction(action,
|
|
469
|
-
const pathBase = ensureSlash(
|
|
470
|
-
const
|
|
474
|
+
async function submitAction(action, routeUrl) {
|
|
475
|
+
const pathBase = ensureSlash(routeUrl.pathname);
|
|
476
|
+
const searchParams = new URLSearchParams(routeUrl.search);
|
|
477
|
+
searchParams.set(QACTION_KEY, action.id);
|
|
478
|
+
const search = searchParams.toString();
|
|
479
|
+
const url = `${pathBase}?${search}`;
|
|
471
480
|
const actionData = action.data;
|
|
472
481
|
action.data = void 0;
|
|
473
482
|
let fetchOptions;
|
|
@@ -993,7 +1002,7 @@ const useQwikRouter = (props) => {
|
|
|
993
1002
|
return;
|
|
994
1003
|
}
|
|
995
1004
|
if (action) {
|
|
996
|
-
const result = await submitAction(action, trackUrl
|
|
1005
|
+
const result = await submitAction(action, trackUrl);
|
|
997
1006
|
if (!result) {
|
|
998
1007
|
routeInternal2.untrackedValue = {
|
|
999
1008
|
type: navType,
|
|
@@ -1030,6 +1039,9 @@ const useQwikRouter = (props) => {
|
|
|
1030
1039
|
}
|
|
1031
1040
|
updateRouteLoaderPaths(routeLoaderCtx2, loadedRoute.$loaderPaths$, trackUrl);
|
|
1032
1041
|
const routeLoaders = ensureRouteLoaderSignals(contentModules, loaderState2, routeLoaderCtx2);
|
|
1042
|
+
if (!isServer) {
|
|
1043
|
+
invalidateNavRouteLoaders(loaderState2);
|
|
1044
|
+
}
|
|
1033
1045
|
if (shouldInvalidateActionLoaders) {
|
|
1034
1046
|
if (actionLoaderHashes !== void 0) {
|
|
1035
1047
|
for (const hash of actionLoaderHashes) {
|
|
@@ -1044,9 +1056,14 @@ const useQwikRouter = (props) => {
|
|
|
1044
1056
|
if (routeLoaders.length > 0) {
|
|
1045
1057
|
for (let i = 0; i < routeLoaders.length; i++) {
|
|
1046
1058
|
const loader = routeLoaders[i];
|
|
1047
|
-
|
|
1059
|
+
if (!isImmutableLoader(loader.__id)) {
|
|
1060
|
+
loaderState2[loader.__id].untrackedPending;
|
|
1061
|
+
}
|
|
1048
1062
|
}
|
|
1049
1063
|
}
|
|
1064
|
+
if (!isServer) {
|
|
1065
|
+
clearNavFetchCache();
|
|
1066
|
+
}
|
|
1050
1067
|
if (internalState.navCount !== navCountBefore) {
|
|
1051
1068
|
return;
|
|
1052
1069
|
}
|
|
@@ -1304,7 +1321,6 @@ const RouterOutlet = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl(()
|
|
|
1304
1321
|
throw new Error("PrefetchServiceWorker component must be rendered on the server.");
|
|
1305
1322
|
}
|
|
1306
1323
|
const internalContext = useContext(ContentInternalContext);
|
|
1307
|
-
const head = useDocumentHead();
|
|
1308
1324
|
const nav = useNavigate();
|
|
1309
1325
|
const contents = internalContext.value;
|
|
1310
1326
|
if (contents && contents.length > 0) {
|
|
@@ -1318,10 +1334,6 @@ const RouterOutlet = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl(()
|
|
|
1318
1334
|
return /* @__PURE__ */ _jsxSorted(Fragment, null, null, [
|
|
1319
1335
|
cmp,
|
|
1320
1336
|
!__EXPERIMENTAL__.noSPA && /* @__PURE__ */ _jsxSorted("script", {
|
|
1321
|
-
"q-d:qcinit": [
|
|
1322
|
-
spaInit,
|
|
1323
|
-
linkPrefetchInit(head.manifestHash)
|
|
1324
|
-
],
|
|
1325
1337
|
"q-d:qinit": _qrlSync(() => {
|
|
1326
1338
|
((w, h) => {
|
|
1327
1339
|
if (!w._qcs) {
|
|
@@ -1335,9 +1347,14 @@ const RouterOutlet = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl(()
|
|
|
1335
1347
|
}
|
|
1336
1348
|
})(window, history);
|
|
1337
1349
|
}, '()=>{((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);}'),
|
|
1338
|
-
"q-d:qrouterpopstate": /* @__PURE__ */ inlinedQrl((event, _1, nav2) => handleRouterPopstate(nav2, event), "RouterOutlet_component_Fragment_script_q_d_qrouterpopstate_aRL6GvFyews"),
|
|
1350
|
+
"q-d:qrouterpopstate": /* @__PURE__ */ inlinedQrl((event, _1, nav2) => handleRouterPopstate(nav2, event), "RouterOutlet_component_Fragment_script_q_d_qrouterpopstate_aRL6GvFyews").m(),
|
|
1339
1351
|
"q:p": nav
|
|
1340
|
-
},
|
|
1352
|
+
}, {
|
|
1353
|
+
"q-d:qcinit": [
|
|
1354
|
+
spaInit,
|
|
1355
|
+
linkPrefetchInit
|
|
1356
|
+
]
|
|
1357
|
+
}, null, 6, "Fn_1")
|
|
1341
1358
|
], 1, "Fn_2");
|
|
1342
1359
|
}
|
|
1343
1360
|
return SkipRender;
|
|
@@ -17,7 +17,7 @@ async function getConfig() {
|
|
|
17
17
|
}
|
|
18
18
|
return qwikRouterConfig;
|
|
19
19
|
}
|
|
20
|
-
function getRequestHandlerPathname(serverRequestEv) {
|
|
20
|
+
function getRequestHandlerPathname(serverRequestEv, isDevRequest = isDev) {
|
|
21
21
|
const recognized = recognizeRequest(serverRequestEv.url.pathname);
|
|
22
22
|
if (!recognized) {
|
|
23
23
|
return serverRequestEv.url.pathname;
|
|
@@ -26,7 +26,8 @@ function getRequestHandlerPathname(serverRequestEv) {
|
|
|
26
26
|
if (recognized.type !== IsQLoader) {
|
|
27
27
|
return loaderPathname;
|
|
28
28
|
}
|
|
29
|
-
|
|
29
|
+
const routePath = serverRequestEv.request.headers.get(FULLPATH_HEADER) ?? (isDevRequest ? serverRequestEv.request.headers.get(ROUTE_PATH_HEADER) : null);
|
|
30
|
+
return resolveValidInternalFullPathname(loaderPathname, routePath) ?? loaderPathname;
|
|
30
31
|
}
|
|
31
32
|
async function loadRequestHandlers(qwikRouterConfig2, pathname, method, checkOrigin, renderFn, serverRequestEv) {
|
|
32
33
|
const { routes, serverPlugins, cacheModules } = qwikRouterConfig2;
|
package/lib/vite/index.mjs
CHANGED
|
@@ -2041,9 +2041,9 @@ function imagePlugin(userOpts) {
|
|
|
2041
2041
|
order: "pre",
|
|
2042
2042
|
async handler(id, importer, options) {
|
|
2043
2043
|
if (parseVirtualImageJsxId(id)) {
|
|
2044
|
-
return
|
|
2044
|
+
return id;
|
|
2045
2045
|
}
|
|
2046
|
-
if (id.endsWith(TO_IMG_ID)) {
|
|
2046
|
+
if (id.endsWith(TO_IMG_ID) || id === VIRTUAL_TO_IMG_ID) {
|
|
2047
2047
|
return VIRTUAL_TO_IMG_ID;
|
|
2048
2048
|
}
|
|
2049
2049
|
const { pathId, params } = parseId(id);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qwik.dev/router",
|
|
3
3
|
"description": "The router for Qwik.",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.39",
|
|
5
5
|
"bugs": "https://github.com/QwikDev/qwik/issues",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@azure/functions": "3.5.1",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"remark-gfm": "^4.0.1",
|
|
23
23
|
"set-cookie-parser": "^2.7.2",
|
|
24
24
|
"source-map": "^0.7.6",
|
|
25
|
-
"svgo": "^3.3.
|
|
25
|
+
"svgo": "^3.3.4",
|
|
26
26
|
"unified": "^11.0.5",
|
|
27
27
|
"unist-util-visit": "^5.0.0",
|
|
28
28
|
"valibot": ">=0.36.0 <2",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"tsm": "2.3.0",
|
|
42
42
|
"typescript": "5.9.3",
|
|
43
43
|
"uvu": "0.5.6",
|
|
44
|
-
"@qwik.dev/core": "2.0.0-beta.
|
|
44
|
+
"@qwik.dev/core": "2.0.0-beta.39"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
|
47
47
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
|
@@ -170,7 +170,7 @@
|
|
|
170
170
|
"main": "./lib/index.qwik.mjs",
|
|
171
171
|
"peerDependencies": {
|
|
172
172
|
"vite": ">=6 <9",
|
|
173
|
-
"@qwik.dev/core": "^2.0.0-beta.
|
|
173
|
+
"@qwik.dev/core": "^2.0.0-beta.39"
|
|
174
174
|
},
|
|
175
175
|
"publishConfig": {
|
|
176
176
|
"access": "public"
|