@qwik.dev/router 2.0.0-beta.3 → 2.0.0-beta.5

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,14 +14660,20 @@ 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
  };
14654
14670
 
14671
+ // packages/qwik-router/src/middleware/request-handler/resolve-request-handlers.ts
14672
+ import { _UNINITIALIZED as _UNINITIALIZED3 } from "@qwik.dev/core/internal";
14673
+
14674
+ // packages/qwik-router/src/middleware/request-handler/request-event.ts
14675
+ import { _UNINITIALIZED as _UNINITIALIZED2 } from "@qwik.dev/core/internal";
14676
+
14655
14677
  // packages/qwik-router/src/middleware/request-handler/cache-control.ts
14656
14678
  function createCacheControl(cacheControl) {
14657
14679
  const controls = [];
@@ -14827,12 +14849,17 @@ var RequestEvLoaders = Symbol("RequestEvLoaders");
14827
14849
  var RequestEvMode = Symbol("RequestEvMode");
14828
14850
  var RequestEvRoute = Symbol("RequestEvRoute");
14829
14851
  var RequestEvQwikSerializer = Symbol("RequestEvQwikSerializer");
14852
+ var RequestEvLoaderSerializationStrategyMap = Symbol(
14853
+ "RequestEvLoaderSerializationStrategyMap"
14854
+ );
14830
14855
  var RequestEvTrailingSlash = Symbol("RequestEvTrailingSlash");
14831
14856
  var RequestRouteName = "@routeName";
14832
14857
  var RequestEvSharedActionId = "@actionId";
14833
14858
  var RequestEvSharedActionFormData = "@actionFormData";
14834
14859
  var RequestEvSharedNonce = "@nonce";
14835
14860
  var RequestEvIsRewrite = "@rewrite";
14861
+ var RequestEvShareServerTiming = "@serverTiming";
14862
+ var RequestEvShareQData = "qData";
14836
14863
  function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trailingSlash, basePathname, qwikSerializer, resolved) {
14837
14864
  const { request, platform, env: env2 } = serverRequestEv;
14838
14865
  const sharedMap = /* @__PURE__ */ new Map();
@@ -14916,6 +14943,7 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
14916
14943
  const loaders = {};
14917
14944
  const requestEv = {
14918
14945
  [RequestEvLoaders]: loaders,
14946
+ [RequestEvLoaderSerializationStrategyMap]: /* @__PURE__ */ new Map(),
14919
14947
  [RequestEvMode]: serverRequestEv.mode,
14920
14948
  [RequestEvTrailingSlash]: trailingSlash,
14921
14949
  get [RequestEvRoute]() {
@@ -14929,7 +14957,7 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
14929
14957
  signal: request.signal,
14930
14958
  originalUrl: new URL(url),
14931
14959
  get params() {
14932
- return (loadedRoute == null ? void 0 : loadedRoute[1]) ?? {};
14960
+ return (loadedRoute == null ? void 0 : loadedRoute[1 /* Params */]) ?? {};
14933
14961
  },
14934
14962
  get pathname() {
14935
14963
  return url.pathname;
@@ -14966,6 +14994,10 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
14966
14994
  "You can not get the returned data of a loader that has not been executed for this request."
14967
14995
  );
14968
14996
  }
14997
+ if (loaders[id] === _UNINITIALIZED2) {
14998
+ const isDev = getRequestMode(requestEv) === "dev";
14999
+ await getRouteLoaderPromise(loaderOrAction, loaders, requestEv, isDev, qwikSerializer);
15000
+ }
14969
15001
  }
14970
15002
  return loaders[id];
14971
15003
  },
@@ -15047,9 +15079,12 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
15047
15079
  getWritableStream: () => {
15048
15080
  if (writableStream === null) {
15049
15081
  if (serverRequestEv.mode === "dev") {
15050
- const serverTiming = sharedMap.get("@serverTiming");
15082
+ const serverTiming = sharedMap.get(RequestEvShareServerTiming);
15051
15083
  if (serverTiming) {
15052
- headers.set("Server-Timing", serverTiming.map((a) => `${a[0]};dur=${a[1]}`).join(","));
15084
+ headers.set(
15085
+ "Server-Timing",
15086
+ serverTiming.map(([name, duration]) => `${name};dur=${duration}`).join(",")
15087
+ );
15053
15088
  }
15054
15089
  }
15055
15090
  writableStream = serverRequestEv.getWritableStream(
@@ -15068,6 +15103,9 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
15068
15103
  function getRequestLoaders(requestEv) {
15069
15104
  return requestEv[RequestEvLoaders];
15070
15105
  }
15106
+ function getRequestLoaderSerializationStrategyMap(requestEv) {
15107
+ return requestEv[RequestEvLoaderSerializationStrategyMap];
15108
+ }
15071
15109
  function getRequestTrailingSlash(requestEv) {
15072
15110
  return requestEv[RequestEvTrailingSlash];
15073
15111
  }
@@ -15140,13 +15178,15 @@ function getQwikRouterServerData(requestEv) {
15140
15178
  if (protocol) {
15141
15179
  reconstructedUrl.protocol = protocol;
15142
15180
  }
15181
+ const loaders = getRequestLoaders(requestEv);
15182
+ const loadersSerializationStrategy = getRequestLoaderSerializationStrategyMap(requestEv);
15143
15183
  return {
15144
15184
  url: reconstructedUrl.href,
15145
15185
  requestHeaders,
15146
15186
  locale: locale(),
15147
15187
  nonce,
15148
15188
  containerAttributes: {
15149
- "q:route": routeName
15189
+ [Q_ROUTE]: routeName
15150
15190
  },
15151
15191
  qwikrouter: {
15152
15192
  routeName,
@@ -15155,7 +15195,8 @@ function getQwikRouterServerData(requestEv) {
15155
15195
  loadedRoute: getRequestRoute(requestEv),
15156
15196
  response: {
15157
15197
  status: status(),
15158
- loaders: getRequestLoaders(requestEv),
15198
+ loaders,
15199
+ loadersSerializationStrategy,
15159
15200
  action,
15160
15201
  formData
15161
15202
  }
@@ -15168,7 +15209,7 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15168
15209
  const routeLoaders = [];
15169
15210
  const routeActions = [];
15170
15211
  const requestHandlers = [];
15171
- const isPageRoute = !!(route && isLastModulePageRoute(route[2]));
15212
+ const isPageRoute = !!(route && isLastModulePageRoute(route[2 /* Mods */]));
15172
15213
  if (serverPlugins) {
15173
15214
  _resolveRequestHandlers(
15174
15215
  routeLoaders,
@@ -15180,7 +15221,7 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15180
15221
  );
15181
15222
  }
15182
15223
  if (route) {
15183
- const routeName = route[0];
15224
+ const routeName = route[0 /* RouteName */];
15184
15225
  if (checkOrigin && (method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE")) {
15185
15226
  requestHandlers.unshift(csrfCheckMiddleware);
15186
15227
  }
@@ -15191,7 +15232,7 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15191
15232
  requestHandlers.push(fixTrailingSlash);
15192
15233
  requestHandlers.push(renderQData);
15193
15234
  }
15194
- const routeModules = route[2];
15235
+ const routeModules = route[2 /* Mods */];
15195
15236
  requestHandlers.push(handleRedirect);
15196
15237
  _resolveRequestHandlers(
15197
15238
  routeLoaders,
@@ -15205,7 +15246,8 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15205
15246
  requestHandlers.push((ev) => {
15206
15247
  ev.sharedMap.set(RequestRouteName, routeName);
15207
15248
  });
15208
- requestHandlers.push(actionsMiddleware(routeActions, routeLoaders));
15249
+ requestHandlers.push(actionsMiddleware(routeActions));
15250
+ requestHandlers.push(loadersMiddleware(routeLoaders));
15209
15251
  requestHandlers.push(renderHandler);
15210
15252
  }
15211
15253
  }
@@ -15270,8 +15312,9 @@ var _resolveRequestHandlers = (routeLoaders, routeActions, requestHandlers, rout
15270
15312
  var checkBrand = (obj, brand) => {
15271
15313
  return obj && typeof obj === "function" && obj.__brand === brand;
15272
15314
  };
15273
- function actionsMiddleware(routeActions, routeLoaders) {
15274
- return async (requestEv) => {
15315
+ function actionsMiddleware(routeActions) {
15316
+ return async (requestEvent) => {
15317
+ const requestEv = requestEvent;
15275
15318
  if (requestEv.headersSent) {
15276
15319
  requestEv.exit();
15277
15320
  return;
@@ -15306,7 +15349,7 @@ function actionsMiddleware(routeActions, routeLoaders) {
15306
15349
  } else {
15307
15350
  const actionResolved = isDev ? await measure(
15308
15351
  requestEv,
15309
- action.__qrl.getSymbol().split("_", 1)[0],
15352
+ action.__qrl.getHash(),
15310
15353
  () => action.__qrl.call(requestEv, result.data, requestEv)
15311
15354
  ) : await action.__qrl.call(requestEv, result.data, requestEv);
15312
15355
  if (isDev) {
@@ -15317,46 +15360,76 @@ function actionsMiddleware(routeActions, routeLoaders) {
15317
15360
  }
15318
15361
  }
15319
15362
  }
15363
+ };
15364
+ }
15365
+ function loadersMiddleware(routeLoaders) {
15366
+ return async (requestEvent) => {
15367
+ const requestEv = requestEvent;
15368
+ if (requestEv.headersSent) {
15369
+ requestEv.exit();
15370
+ return;
15371
+ }
15372
+ const loaders = getRequestLoaders(requestEv);
15373
+ const isDev = getRequestMode(requestEv) === "dev";
15374
+ const qwikSerializer = requestEv[RequestEvQwikSerializer];
15320
15375
  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();
15376
+ let currentLoaders = [];
15377
+ if (requestEv.query.has(QLOADER_KEY)) {
15378
+ const selectedLoaderIds = requestEv.query.getAll(QLOADER_KEY);
15379
+ for (const loader of routeLoaders) {
15380
+ if (selectedLoaderIds.includes(loader.__id)) {
15381
+ currentLoaders.push(loader);
15346
15382
  } else {
15347
- if (isDev) {
15348
- verifySerializable(qwikSerializer, resolvedLoader, loader.__qrl);
15349
- }
15350
- loaders[loaderId] = resolvedLoader;
15383
+ loaders[loader.__id] = _UNINITIALIZED3;
15351
15384
  }
15352
- return resolvedLoader;
15353
- });
15354
- return loaders[loaderId];
15355
- });
15385
+ }
15386
+ } else {
15387
+ currentLoaders = routeLoaders;
15388
+ }
15389
+ const resolvedLoadersPromises = currentLoaders.map(
15390
+ (loader) => getRouteLoaderPromise(loader, loaders, requestEv, isDev, qwikSerializer)
15391
+ );
15356
15392
  await Promise.all(resolvedLoadersPromises);
15357
15393
  }
15358
15394
  };
15359
15395
  }
15396
+ async function getRouteLoaderPromise(loader, loaders, requestEv, isDev, qwikSerializer) {
15397
+ const loaderId = loader.__id;
15398
+ loaders[loaderId] = runValidators(
15399
+ requestEv,
15400
+ loader.__validators,
15401
+ void 0,
15402
+ // data
15403
+ isDev
15404
+ ).then((res) => {
15405
+ if (res.success) {
15406
+ if (isDev) {
15407
+ return measure(
15408
+ requestEv,
15409
+ loader.__qrl.getHash(),
15410
+ () => loader.__qrl.call(requestEv, requestEv)
15411
+ );
15412
+ } else {
15413
+ return loader.__qrl.call(requestEv, requestEv);
15414
+ }
15415
+ } else {
15416
+ return requestEv.fail(res.status ?? 500, res.error);
15417
+ }
15418
+ }).then((resolvedLoader) => {
15419
+ if (typeof resolvedLoader === "function") {
15420
+ loaders[loaderId] = resolvedLoader();
15421
+ } else {
15422
+ if (isDev) {
15423
+ verifySerializable(qwikSerializer, resolvedLoader, loader.__qrl);
15424
+ }
15425
+ loaders[loaderId] = resolvedLoader;
15426
+ }
15427
+ return resolvedLoader;
15428
+ });
15429
+ const loadersSerializationStrategy = getRequestLoaderSerializationStrategyMap(requestEv);
15430
+ loadersSerializationStrategy.set(loaderId, loader.__serializationStrategy);
15431
+ return loaders[loaderId];
15432
+ }
15360
15433
  async function runValidators(requestEv, validators, data, isDev) {
15361
15434
  let lastResult = {
15362
15435
  success: true,
@@ -15491,7 +15564,7 @@ function getPathname(url, trailingSlash) {
15491
15564
  url.pathname = url.pathname.slice(0, -1);
15492
15565
  }
15493
15566
  }
15494
- const search2 = url.search.slice(1).replaceAll(/&?q(action|data|func)=[^&]+/g, "");
15567
+ const search2 = url.search.slice(1).replaceAll(/&?q(action|data|func|loaders)=[^&]+/g, "");
15495
15568
  return `${url.pathname}${search2 ? `?${search2}` : ""}${url.hash}`;
15496
15569
  }
15497
15570
  var encoder = /* @__PURE__ */ new TextEncoder();
@@ -15531,10 +15604,10 @@ async function handleRedirect(requestEv) {
15531
15604
  return;
15532
15605
  }
15533
15606
  const status = requestEv.status();
15534
- const location = requestEv.headers.get("Location");
15535
- const isRedirect = status >= 301 && status <= 308 && location;
15607
+ const location2 = requestEv.headers.get("Location");
15608
+ const isRedirect = status >= 301 && status <= 308 && location2;
15536
15609
  if (isRedirect) {
15537
- const adaptedLocation = makeQDataPath(location);
15610
+ const adaptedLocation = makeQDataPath(location2);
15538
15611
  if (adaptedLocation) {
15539
15612
  requestEv.headers.set("Location", adaptedLocation);
15540
15613
  requestEv.getWritableStream().close();
@@ -15560,8 +15633,24 @@ async function renderQData(requestEv) {
15560
15633
  const requestHeaders = {};
15561
15634
  requestEv.request.headers.forEach((value2, key) => requestHeaders[key] = value2);
15562
15635
  requestEv.headers.set("Content-Type", "application/json; charset=utf-8");
15563
- const qData = {
15564
- loaders: getRequestLoaders(requestEv),
15636
+ let loaders = getRequestLoaders(requestEv);
15637
+ const selectedLoaderIds = requestEv.query.getAll(QLOADER_KEY);
15638
+ const hasCustomLoaders = selectedLoaderIds.length > 0;
15639
+ if (hasCustomLoaders) {
15640
+ const selectedLoaders = {};
15641
+ for (const loaderId of selectedLoaderIds) {
15642
+ const loader = loaders[loaderId];
15643
+ selectedLoaders[loaderId] = loader;
15644
+ }
15645
+ loaders = selectedLoaders;
15646
+ }
15647
+ const qData = hasCustomLoaders ? {
15648
+ // send minimal data to the client
15649
+ loaders,
15650
+ status: status !== 200 ? status : 200,
15651
+ href: getPathname(requestEv.url, trailingSlash)
15652
+ } : {
15653
+ loaders,
15565
15654
  action: requestEv.sharedMap.get(RequestEvSharedActionId),
15566
15655
  status: status !== 200 ? status : 200,
15567
15656
  href: getPathname(requestEv.url, trailingSlash),
@@ -15572,7 +15661,7 @@ async function renderQData(requestEv) {
15572
15661
  const qwikSerializer = requestEv[RequestEvQwikSerializer];
15573
15662
  const data = await qwikSerializer._serialize([qData]);
15574
15663
  writer.write(encoder.encode(data));
15575
- requestEv.sharedMap.set("qData", qData);
15664
+ requestEv.sharedMap.set(RequestEvShareQData, qData);
15576
15665
  writer.close();
15577
15666
  }
15578
15667
  function makeQDataPath(href) {
@@ -15594,9 +15683,9 @@ async function measure(requestEv, name, fn) {
15594
15683
  return await fn();
15595
15684
  } finally {
15596
15685
  const duration = now() - start;
15597
- let measurements = requestEv.sharedMap.get("@serverTiming");
15686
+ let measurements = requestEv.sharedMap.get(RequestEvShareServerTiming);
15598
15687
  if (!measurements) {
15599
- requestEv.sharedMap.set("@serverTiming", measurements = []);
15688
+ requestEv.sharedMap.set(RequestEvShareServerTiming, measurements = []);
15600
15689
  }
15601
15690
  measurements.push([name, duration]);
15602
15691
  }
@@ -26615,11 +26704,11 @@ function ssrDevMiddleware(ctx, server) {
26615
26704
  if (cookieHeaders.length > 0) {
26616
26705
  res.setHeader("Set-Cookie", cookieHeaders);
26617
26706
  }
26618
- const serverTiming = requestEv.sharedMap.get("@serverTiming");
26707
+ const serverTiming = requestEv.sharedMap.get(RequestEvShareServerTiming);
26619
26708
  if (serverTiming) {
26620
26709
  res.setHeader(
26621
26710
  "Server-Timing",
26622
- serverTiming.map((a) => `${a[0]};dur=${a[1]}`).join(",")
26711
+ serverTiming.map(([name, duration]) => `${name};dur=${duration}`).join(",")
26623
26712
  );
26624
26713
  }
26625
26714
  res._qwikEnvData = {
@@ -26643,8 +26732,8 @@ function ssrDevMiddleware(ctx, server) {
26643
26732
  if (requestHandlers.length > 0) {
26644
26733
  const serverRequestEv = await fromNodeHttp(url, req, res, "dev");
26645
26734
  Object.assign(serverRequestEv.platform, ctx.opts.platform);
26646
- const { _deserialize, _serialize, _verifySerializable } = await server.ssrLoadModule("@qwik-serializer");
26647
- const qwikSerializer = { _deserialize, _serialize, _verifySerializable };
26735
+ const { _deserialize: _deserialize2, _serialize, _verifySerializable } = await server.ssrLoadModule("@qwik-serializer");
26736
+ const qwikSerializer = { _deserialize: _deserialize2, _serialize, _verifySerializable };
26648
26737
  const rebuildRouteInfo = async (url2) => {
26649
26738
  const { serverPlugins: serverPlugins2, loadedRoute: loadedRoute2 } = await resolveRoute2(routeModulePaths, url2);
26650
26739
  const requestHandlers2 = resolveRequestHandlers(
@@ -27194,6 +27283,11 @@ function qwikRouterPlugin(userOpts) {
27194
27283
  api,
27195
27284
  async config() {
27196
27285
  const updatedViteConfig = {
27286
+ define: {
27287
+ "globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__": JSON.stringify(
27288
+ (userOpts == null ? void 0 : userOpts.defaultLoadersSerializationStrategy) || "never"
27289
+ )
27290
+ },
27197
27291
  appType: "custom",
27198
27292
  resolve: {
27199
27293
  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.3",
4
+ "version": "2.0.0-beta.5",
5
5
  "bugs": "https://github.com/QwikDev/qwik/issues",
6
6
  "dependencies": {
7
7
  "@mdx-js/mdx": "^3",
@@ -40,7 +40,7 @@
40
40
  "unist-util-visit": "5.0.0",
41
41
  "uvu": "0.5.6",
42
42
  "yaml": "2.4.5",
43
- "@qwik.dev/core": "2.0.0-beta.3"
43
+ "@qwik.dev/core": "2.0.0-beta.5"
44
44
  },
45
45
  "engines": {
46
46
  "node": "^18.17.0 || ^20.3.0 || >=21.0.0"