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

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.
@@ -14511,8 +14511,11 @@ var RewriteMessage = class extends AbortMessage {
14511
14511
 
14512
14512
  // packages/qwik-router/src/runtime/src/constants.ts
14513
14513
  var QACTION_KEY = "qaction";
14514
+ var QLOADER_KEY = "qloaders";
14514
14515
  var QFN_KEY = "qfunc";
14515
14516
  var QDATA_KEY = "qdata";
14517
+ var Q_ROUTE = "q:route";
14518
+ var DEFAULT_LOADERS_SERIALIZATION_STRATEGY = globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__ || "never";
14516
14519
 
14517
14520
  // packages/qwik-router/src/runtime/src/route-matcher.ts
14518
14521
  function matchRoute(route, path3) {
@@ -14634,6 +14637,19 @@ function lastIndexOf(text3, start, match, searchIdx, notFoundIdx) {
14634
14637
  return idx > start ? idx : notFoundIdx;
14635
14638
  }
14636
14639
 
14640
+ // packages/qwik-router/src/runtime/src/utils.ts
14641
+ import { createAsyncComputed$, isBrowser as isBrowser2 } from "@qwik.dev/core";
14642
+ import {
14643
+ _UNINITIALIZED
14644
+ } from "@qwik.dev/core/internal";
14645
+
14646
+ // packages/qwik-router/src/runtime/src/use-endpoint.ts
14647
+ import { _deserialize } from "@qwik.dev/core/internal";
14648
+
14649
+ // packages/qwik-router/src/runtime/src/client-navigate.ts
14650
+ import { isBrowser } from "@qwik.dev/core";
14651
+ import { p as preload } from "@qwik.dev/core/preloader";
14652
+
14637
14653
  // packages/qwik-router/src/runtime/src/utils.ts
14638
14654
  var isPromise = (value2) => {
14639
14655
  return value2 && typeof value2.then === "function";
@@ -14644,10 +14660,10 @@ var getMenuLoader = (menus, pathname) => {
14644
14660
  if (menus) {
14645
14661
  pathname = pathname.endsWith("/") ? pathname : pathname + "/";
14646
14662
  const menu = menus.find(
14647
- (m) => m[0] === pathname || pathname.startsWith(m[0] + (pathname.endsWith("/") ? "" : "/"))
14663
+ (m) => m[0 /* Pathname */] === pathname || pathname.startsWith(m[0 /* Pathname */] + (pathname.endsWith("/") ? "" : "/"))
14648
14664
  );
14649
14665
  if (menu) {
14650
- return menu[1];
14666
+ return menu[1 /* MenuLoader */];
14651
14667
  }
14652
14668
  }
14653
14669
  };
@@ -14827,12 +14843,17 @@ var RequestEvLoaders = Symbol("RequestEvLoaders");
14827
14843
  var RequestEvMode = Symbol("RequestEvMode");
14828
14844
  var RequestEvRoute = Symbol("RequestEvRoute");
14829
14845
  var RequestEvQwikSerializer = Symbol("RequestEvQwikSerializer");
14846
+ var RequestEvLoaderSerializationStrategyMap = Symbol(
14847
+ "RequestEvLoaderSerializationStrategyMap"
14848
+ );
14830
14849
  var RequestEvTrailingSlash = Symbol("RequestEvTrailingSlash");
14831
14850
  var RequestRouteName = "@routeName";
14832
14851
  var RequestEvSharedActionId = "@actionId";
14833
14852
  var RequestEvSharedActionFormData = "@actionFormData";
14834
14853
  var RequestEvSharedNonce = "@nonce";
14835
14854
  var RequestEvIsRewrite = "@rewrite";
14855
+ var RequestEvShareServerTiming = "@serverTiming";
14856
+ var RequestEvShareQData = "qData";
14836
14857
  function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trailingSlash, basePathname, qwikSerializer, resolved) {
14837
14858
  const { request, platform, env: env2 } = serverRequestEv;
14838
14859
  const sharedMap = /* @__PURE__ */ new Map();
@@ -14916,6 +14937,7 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
14916
14937
  const loaders = {};
14917
14938
  const requestEv = {
14918
14939
  [RequestEvLoaders]: loaders,
14940
+ [RequestEvLoaderSerializationStrategyMap]: /* @__PURE__ */ new Map(),
14919
14941
  [RequestEvMode]: serverRequestEv.mode,
14920
14942
  [RequestEvTrailingSlash]: trailingSlash,
14921
14943
  get [RequestEvRoute]() {
@@ -14929,7 +14951,7 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
14929
14951
  signal: request.signal,
14930
14952
  originalUrl: new URL(url),
14931
14953
  get params() {
14932
- return (loadedRoute == null ? void 0 : loadedRoute[1]) ?? {};
14954
+ return (loadedRoute == null ? void 0 : loadedRoute[1 /* Params */]) ?? {};
14933
14955
  },
14934
14956
  get pathname() {
14935
14957
  return url.pathname;
@@ -15047,9 +15069,12 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
15047
15069
  getWritableStream: () => {
15048
15070
  if (writableStream === null) {
15049
15071
  if (serverRequestEv.mode === "dev") {
15050
- const serverTiming = sharedMap.get("@serverTiming");
15072
+ const serverTiming = sharedMap.get(RequestEvShareServerTiming);
15051
15073
  if (serverTiming) {
15052
- headers.set("Server-Timing", serverTiming.map((a) => `${a[0]};dur=${a[1]}`).join(","));
15074
+ headers.set(
15075
+ "Server-Timing",
15076
+ serverTiming.map(([name, duration]) => `${name};dur=${duration}`).join(",")
15077
+ );
15053
15078
  }
15054
15079
  }
15055
15080
  writableStream = serverRequestEv.getWritableStream(
@@ -15068,6 +15093,9 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
15068
15093
  function getRequestLoaders(requestEv) {
15069
15094
  return requestEv[RequestEvLoaders];
15070
15095
  }
15096
+ function getRequestLoaderSerializationStrategyMap(requestEv) {
15097
+ return requestEv[RequestEvLoaderSerializationStrategyMap];
15098
+ }
15071
15099
  function getRequestTrailingSlash(requestEv) {
15072
15100
  return requestEv[RequestEvTrailingSlash];
15073
15101
  }
@@ -15140,13 +15168,15 @@ function getQwikRouterServerData(requestEv) {
15140
15168
  if (protocol) {
15141
15169
  reconstructedUrl.protocol = protocol;
15142
15170
  }
15171
+ const loaders = getRequestLoaders(requestEv);
15172
+ const loadersSerializationStrategy = getRequestLoaderSerializationStrategyMap(requestEv);
15143
15173
  return {
15144
15174
  url: reconstructedUrl.href,
15145
15175
  requestHeaders,
15146
15176
  locale: locale(),
15147
15177
  nonce,
15148
15178
  containerAttributes: {
15149
- "q:route": routeName
15179
+ [Q_ROUTE]: routeName
15150
15180
  },
15151
15181
  qwikrouter: {
15152
15182
  routeName,
@@ -15155,7 +15185,8 @@ function getQwikRouterServerData(requestEv) {
15155
15185
  loadedRoute: getRequestRoute(requestEv),
15156
15186
  response: {
15157
15187
  status: status(),
15158
- loaders: getRequestLoaders(requestEv),
15188
+ loaders,
15189
+ loadersSerializationStrategy,
15159
15190
  action,
15160
15191
  formData
15161
15192
  }
@@ -15168,7 +15199,7 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15168
15199
  const routeLoaders = [];
15169
15200
  const routeActions = [];
15170
15201
  const requestHandlers = [];
15171
- const isPageRoute = !!(route && isLastModulePageRoute(route[2]));
15202
+ const isPageRoute = !!(route && isLastModulePageRoute(route[2 /* Mods */]));
15172
15203
  if (serverPlugins) {
15173
15204
  _resolveRequestHandlers(
15174
15205
  routeLoaders,
@@ -15180,7 +15211,7 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15180
15211
  );
15181
15212
  }
15182
15213
  if (route) {
15183
- const routeName = route[0];
15214
+ const routeName = route[0 /* RouteName */];
15184
15215
  if (checkOrigin && (method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE")) {
15185
15216
  requestHandlers.unshift(csrfCheckMiddleware);
15186
15217
  }
@@ -15191,7 +15222,7 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15191
15222
  requestHandlers.push(fixTrailingSlash);
15192
15223
  requestHandlers.push(renderQData);
15193
15224
  }
15194
- const routeModules = route[2];
15225
+ const routeModules = route[2 /* Mods */];
15195
15226
  requestHandlers.push(handleRedirect);
15196
15227
  _resolveRequestHandlers(
15197
15228
  routeLoaders,
@@ -15205,7 +15236,8 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15205
15236
  requestHandlers.push((ev) => {
15206
15237
  ev.sharedMap.set(RequestRouteName, routeName);
15207
15238
  });
15208
- requestHandlers.push(actionsMiddleware(routeActions, routeLoaders));
15239
+ requestHandlers.push(actionsMiddleware(routeActions));
15240
+ requestHandlers.push(loadersMiddleware(routeLoaders));
15209
15241
  requestHandlers.push(renderHandler);
15210
15242
  }
15211
15243
  }
@@ -15270,8 +15302,9 @@ var _resolveRequestHandlers = (routeLoaders, routeActions, requestHandlers, rout
15270
15302
  var checkBrand = (obj, brand) => {
15271
15303
  return obj && typeof obj === "function" && obj.__brand === brand;
15272
15304
  };
15273
- function actionsMiddleware(routeActions, routeLoaders) {
15274
- return async (requestEv) => {
15305
+ function actionsMiddleware(routeActions) {
15306
+ return async (requestEvent) => {
15307
+ const requestEv = requestEvent;
15275
15308
  if (requestEv.headersSent) {
15276
15309
  requestEv.exit();
15277
15310
  return;
@@ -15306,7 +15339,7 @@ function actionsMiddleware(routeActions, routeLoaders) {
15306
15339
  } else {
15307
15340
  const actionResolved = isDev ? await measure(
15308
15341
  requestEv,
15309
- action.__qrl.getSymbol().split("_", 1)[0],
15342
+ action.__qrl.getHash(),
15310
15343
  () => action.__qrl.call(requestEv, result.data, requestEv)
15311
15344
  ) : await action.__qrl.call(requestEv, result.data, requestEv);
15312
15345
  if (isDev) {
@@ -15317,46 +15350,74 @@ function actionsMiddleware(routeActions, routeLoaders) {
15317
15350
  }
15318
15351
  }
15319
15352
  }
15353
+ };
15354
+ }
15355
+ function loadersMiddleware(routeLoaders) {
15356
+ return async (requestEvent) => {
15357
+ const requestEv = requestEvent;
15358
+ if (requestEv.headersSent) {
15359
+ requestEv.exit();
15360
+ return;
15361
+ }
15362
+ const loaders = getRequestLoaders(requestEv);
15363
+ const isDev = getRequestMode(requestEv) === "dev";
15364
+ const qwikSerializer = requestEv[RequestEvQwikSerializer];
15320
15365
  if (routeLoaders.length > 0) {
15321
- const resolvedLoadersPromises = routeLoaders.map((loader) => {
15322
- const loaderId = loader.__id;
15323
- loaders[loaderId] = runValidators(
15324
- requestEv,
15325
- loader.__validators,
15326
- void 0,
15327
- // data
15328
- isDev
15329
- ).then((res) => {
15330
- if (res.success) {
15331
- if (isDev) {
15332
- return measure(
15333
- requestEv,
15334
- loader.__qrl.getSymbol().split("_", 1)[0],
15335
- () => loader.__qrl.call(requestEv, requestEv)
15336
- );
15337
- } else {
15338
- return loader.__qrl.call(requestEv, requestEv);
15339
- }
15340
- } else {
15341
- return requestEv.fail(res.status ?? 500, res.error);
15342
- }
15343
- }).then((resolvedLoader) => {
15344
- if (typeof resolvedLoader === "function") {
15345
- loaders[loaderId] = resolvedLoader();
15346
- } else {
15347
- if (isDev) {
15348
- verifySerializable(qwikSerializer, resolvedLoader, loader.__qrl);
15349
- }
15350
- loaders[loaderId] = resolvedLoader;
15366
+ let currentLoaders = [];
15367
+ if (requestEv.query.has(QLOADER_KEY)) {
15368
+ const selectedLoaderIds = requestEv.query.getAll(QLOADER_KEY);
15369
+ for (const loader of routeLoaders) {
15370
+ if (selectedLoaderIds.includes(loader.__id)) {
15371
+ currentLoaders.push(loader);
15351
15372
  }
15352
- return resolvedLoader;
15353
- });
15354
- return loaders[loaderId];
15355
- });
15373
+ }
15374
+ } else {
15375
+ currentLoaders = routeLoaders;
15376
+ }
15377
+ const resolvedLoadersPromises = currentLoaders.map(
15378
+ (loader) => getRouteLoaderPromise(loader, loaders, requestEv, isDev, qwikSerializer)
15379
+ );
15356
15380
  await Promise.all(resolvedLoadersPromises);
15357
15381
  }
15358
15382
  };
15359
15383
  }
15384
+ async function getRouteLoaderPromise(loader, loaders, requestEv, isDev, qwikSerializer) {
15385
+ const loaderId = loader.__id;
15386
+ loaders[loaderId] = runValidators(
15387
+ requestEv,
15388
+ loader.__validators,
15389
+ void 0,
15390
+ // data
15391
+ isDev
15392
+ ).then((res) => {
15393
+ if (res.success) {
15394
+ if (isDev) {
15395
+ return measure(
15396
+ requestEv,
15397
+ loader.__qrl.getHash(),
15398
+ () => loader.__qrl.call(requestEv, requestEv)
15399
+ );
15400
+ } else {
15401
+ return loader.__qrl.call(requestEv, requestEv);
15402
+ }
15403
+ } else {
15404
+ return requestEv.fail(res.status ?? 500, res.error);
15405
+ }
15406
+ }).then((resolvedLoader) => {
15407
+ if (typeof resolvedLoader === "function") {
15408
+ loaders[loaderId] = resolvedLoader();
15409
+ } else {
15410
+ if (isDev) {
15411
+ verifySerializable(qwikSerializer, resolvedLoader, loader.__qrl);
15412
+ }
15413
+ loaders[loaderId] = resolvedLoader;
15414
+ }
15415
+ return resolvedLoader;
15416
+ });
15417
+ const loadersSerializationStrategy = getRequestLoaderSerializationStrategyMap(requestEv);
15418
+ loadersSerializationStrategy.set(loaderId, loader.__serializationStrategy);
15419
+ return loaders[loaderId];
15420
+ }
15360
15421
  async function runValidators(requestEv, validators, data, isDev) {
15361
15422
  let lastResult = {
15362
15423
  success: true,
@@ -15491,7 +15552,7 @@ function getPathname(url, trailingSlash) {
15491
15552
  url.pathname = url.pathname.slice(0, -1);
15492
15553
  }
15493
15554
  }
15494
- const search2 = url.search.slice(1).replaceAll(/&?q(action|data|func)=[^&]+/g, "");
15555
+ const search2 = url.search.slice(1).replaceAll(/&?q(action|data|func|loaders)=[^&]+/g, "");
15495
15556
  return `${url.pathname}${search2 ? `?${search2}` : ""}${url.hash}`;
15496
15557
  }
15497
15558
  var encoder = /* @__PURE__ */ new TextEncoder();
@@ -15531,10 +15592,10 @@ async function handleRedirect(requestEv) {
15531
15592
  return;
15532
15593
  }
15533
15594
  const status = requestEv.status();
15534
- const location = requestEv.headers.get("Location");
15535
- const isRedirect = status >= 301 && status <= 308 && location;
15595
+ const location2 = requestEv.headers.get("Location");
15596
+ const isRedirect = status >= 301 && status <= 308 && location2;
15536
15597
  if (isRedirect) {
15537
- const adaptedLocation = makeQDataPath(location);
15598
+ const adaptedLocation = makeQDataPath(location2);
15538
15599
  if (adaptedLocation) {
15539
15600
  requestEv.headers.set("Location", adaptedLocation);
15540
15601
  requestEv.getWritableStream().close();
@@ -15560,8 +15621,24 @@ async function renderQData(requestEv) {
15560
15621
  const requestHeaders = {};
15561
15622
  requestEv.request.headers.forEach((value2, key) => requestHeaders[key] = value2);
15562
15623
  requestEv.headers.set("Content-Type", "application/json; charset=utf-8");
15563
- const qData = {
15564
- loaders: getRequestLoaders(requestEv),
15624
+ let loaders = getRequestLoaders(requestEv);
15625
+ const selectedLoaderIds = requestEv.query.getAll(QLOADER_KEY);
15626
+ const hasCustomLoaders = selectedLoaderIds.length > 0;
15627
+ if (hasCustomLoaders) {
15628
+ const selectedLoaders = {};
15629
+ for (const loaderId of selectedLoaderIds) {
15630
+ const loader = loaders[loaderId];
15631
+ selectedLoaders[loaderId] = loader;
15632
+ }
15633
+ loaders = selectedLoaders;
15634
+ }
15635
+ const qData = hasCustomLoaders ? {
15636
+ // send minimal data to the client
15637
+ loaders,
15638
+ status: status !== 200 ? status : 200,
15639
+ href: getPathname(requestEv.url, trailingSlash)
15640
+ } : {
15641
+ loaders,
15565
15642
  action: requestEv.sharedMap.get(RequestEvSharedActionId),
15566
15643
  status: status !== 200 ? status : 200,
15567
15644
  href: getPathname(requestEv.url, trailingSlash),
@@ -15572,7 +15649,7 @@ async function renderQData(requestEv) {
15572
15649
  const qwikSerializer = requestEv[RequestEvQwikSerializer];
15573
15650
  const data = await qwikSerializer._serialize([qData]);
15574
15651
  writer.write(encoder.encode(data));
15575
- requestEv.sharedMap.set("qData", qData);
15652
+ requestEv.sharedMap.set(RequestEvShareQData, qData);
15576
15653
  writer.close();
15577
15654
  }
15578
15655
  function makeQDataPath(href) {
@@ -15594,9 +15671,9 @@ async function measure(requestEv, name, fn) {
15594
15671
  return await fn();
15595
15672
  } finally {
15596
15673
  const duration = now() - start;
15597
- let measurements = requestEv.sharedMap.get("@serverTiming");
15674
+ let measurements = requestEv.sharedMap.get(RequestEvShareServerTiming);
15598
15675
  if (!measurements) {
15599
- requestEv.sharedMap.set("@serverTiming", measurements = []);
15676
+ requestEv.sharedMap.set(RequestEvShareServerTiming, measurements = []);
15600
15677
  }
15601
15678
  measurements.push([name, duration]);
15602
15679
  }
@@ -26615,11 +26692,11 @@ function ssrDevMiddleware(ctx, server) {
26615
26692
  if (cookieHeaders.length > 0) {
26616
26693
  res.setHeader("Set-Cookie", cookieHeaders);
26617
26694
  }
26618
- const serverTiming = requestEv.sharedMap.get("@serverTiming");
26695
+ const serverTiming = requestEv.sharedMap.get(RequestEvShareServerTiming);
26619
26696
  if (serverTiming) {
26620
26697
  res.setHeader(
26621
26698
  "Server-Timing",
26622
- serverTiming.map((a) => `${a[0]};dur=${a[1]}`).join(",")
26699
+ serverTiming.map(([name, duration]) => `${name};dur=${duration}`).join(",")
26623
26700
  );
26624
26701
  }
26625
26702
  res._qwikEnvData = {
@@ -26643,8 +26720,8 @@ function ssrDevMiddleware(ctx, server) {
26643
26720
  if (requestHandlers.length > 0) {
26644
26721
  const serverRequestEv = await fromNodeHttp(url, req, res, "dev");
26645
26722
  Object.assign(serverRequestEv.platform, ctx.opts.platform);
26646
- const { _deserialize, _serialize, _verifySerializable } = await server.ssrLoadModule("@qwik-serializer");
26647
- const qwikSerializer = { _deserialize, _serialize, _verifySerializable };
26723
+ const { _deserialize: _deserialize2, _serialize, _verifySerializable } = await server.ssrLoadModule("@qwik-serializer");
26724
+ const qwikSerializer = { _deserialize: _deserialize2, _serialize, _verifySerializable };
26648
26725
  const rebuildRouteInfo = async (url2) => {
26649
26726
  const { serverPlugins: serverPlugins2, loadedRoute: loadedRoute2 } = await resolveRoute2(routeModulePaths, url2);
26650
26727
  const requestHandlers2 = resolveRequestHandlers(
@@ -27194,6 +27271,11 @@ function qwikRouterPlugin(userOpts) {
27194
27271
  api,
27195
27272
  async config() {
27196
27273
  const updatedViteConfig = {
27274
+ define: {
27275
+ "globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__": JSON.stringify(
27276
+ (userOpts == null ? void 0 : userOpts.defaultLoadersSerializationStrategy) || "never"
27277
+ )
27278
+ },
27197
27279
  appType: "custom",
27198
27280
  resolve: {
27199
27281
  alias: [
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.2",
4
+ "version": "2.0.0-beta.4",
5
5
  "bugs": "https://github.com/QwikDev/qwik/issues",
6
6
  "dependencies": {
7
7
  "@mdx-js/mdx": "^3",
@@ -11,8 +11,7 @@
11
11
  "undici": "*",
12
12
  "valibot": ">=0.36.0 <2",
13
13
  "vfile": "6.0.2",
14
- "vite": ">=5 <7",
15
- "vite-imagetools": "^7.0.5",
14
+ "vite-imagetools": "^7.1.0",
16
15
  "zod": "3.22.4"
17
16
  },
18
17
  "devDependencies": {
@@ -20,7 +19,7 @@
20
19
  "@microsoft/api-extractor": "7.52.4",
21
20
  "@netlify/edge-functions": "2.10.0",
22
21
  "@types/mdast": "4.0.4",
23
- "@types/node": "20.14.11",
22
+ "@types/node": "24.0.4",
24
23
  "@types/refractor": "3.4.1",
25
24
  "@types/set-cookie-parser": "2.4.10",
26
25
  "estree-util-value-to-estree": "3.1.2",
@@ -36,12 +35,12 @@
36
35
  "remark-gfm": "4.0.0",
37
36
  "set-cookie-parser": "2.6.0",
38
37
  "tsm": "2.3.0",
39
- "typescript": "5.8.2",
38
+ "typescript": "5.8.3",
40
39
  "unified": "11.0.5",
41
40
  "unist-util-visit": "5.0.0",
42
41
  "uvu": "0.5.6",
43
42
  "yaml": "2.4.5",
44
- "@qwik.dev/core": "2.0.0-beta.2"
43
+ "@qwik.dev/core": "2.0.0-beta.4"
45
44
  },
46
45
  "engines": {
47
46
  "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
@@ -176,7 +175,7 @@
176
175
  "license": "MIT",
177
176
  "main": "./lib/index.qwik.mjs",
178
177
  "peerDependencies": {
179
- "vite": ">=5 <7"
178
+ "vite": ">=5 <8"
180
179
  },
181
180
  "publishConfig": {
182
181
  "access": "public"