@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.
@@ -14522,8 +14522,11 @@ var RewriteMessage = class extends AbortMessage {
14522
14522
 
14523
14523
  // packages/qwik-router/src/runtime/src/constants.ts
14524
14524
  var QACTION_KEY = "qaction";
14525
+ var QLOADER_KEY = "qloaders";
14525
14526
  var QFN_KEY = "qfunc";
14526
14527
  var QDATA_KEY = "qdata";
14528
+ var Q_ROUTE = "q:route";
14529
+ var DEFAULT_LOADERS_SERIALIZATION_STRATEGY = globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__ || "never";
14527
14530
 
14528
14531
  // packages/qwik-router/src/runtime/src/route-matcher.ts
14529
14532
  function matchRoute(route, path3) {
@@ -14645,6 +14648,17 @@ function lastIndexOf(text3, start, match, searchIdx, notFoundIdx) {
14645
14648
  return idx > start ? idx : notFoundIdx;
14646
14649
  }
14647
14650
 
14651
+ // packages/qwik-router/src/runtime/src/utils.ts
14652
+ var import_core2 = require("@qwik.dev/core");
14653
+ var import_internal2 = require("@qwik.dev/core/internal");
14654
+
14655
+ // packages/qwik-router/src/runtime/src/use-endpoint.ts
14656
+ var import_internal = require("@qwik.dev/core/internal");
14657
+
14658
+ // packages/qwik-router/src/runtime/src/client-navigate.ts
14659
+ var import_core = require("@qwik.dev/core");
14660
+ var import_preloader = require("@qwik.dev/core/preloader");
14661
+
14648
14662
  // packages/qwik-router/src/runtime/src/utils.ts
14649
14663
  var isPromise = (value2) => {
14650
14664
  return value2 && typeof value2.then === "function";
@@ -14655,10 +14669,10 @@ var getMenuLoader = (menus, pathname) => {
14655
14669
  if (menus) {
14656
14670
  pathname = pathname.endsWith("/") ? pathname : pathname + "/";
14657
14671
  const menu = menus.find(
14658
- (m) => m[0] === pathname || pathname.startsWith(m[0] + (pathname.endsWith("/") ? "" : "/"))
14672
+ (m) => m[0 /* Pathname */] === pathname || pathname.startsWith(m[0 /* Pathname */] + (pathname.endsWith("/") ? "" : "/"))
14659
14673
  );
14660
14674
  if (menu) {
14661
- return menu[1];
14675
+ return menu[1 /* MenuLoader */];
14662
14676
  }
14663
14677
  }
14664
14678
  };
@@ -14838,12 +14852,17 @@ var RequestEvLoaders = Symbol("RequestEvLoaders");
14838
14852
  var RequestEvMode = Symbol("RequestEvMode");
14839
14853
  var RequestEvRoute = Symbol("RequestEvRoute");
14840
14854
  var RequestEvQwikSerializer = Symbol("RequestEvQwikSerializer");
14855
+ var RequestEvLoaderSerializationStrategyMap = Symbol(
14856
+ "RequestEvLoaderSerializationStrategyMap"
14857
+ );
14841
14858
  var RequestEvTrailingSlash = Symbol("RequestEvTrailingSlash");
14842
14859
  var RequestRouteName = "@routeName";
14843
14860
  var RequestEvSharedActionId = "@actionId";
14844
14861
  var RequestEvSharedActionFormData = "@actionFormData";
14845
14862
  var RequestEvSharedNonce = "@nonce";
14846
14863
  var RequestEvIsRewrite = "@rewrite";
14864
+ var RequestEvShareServerTiming = "@serverTiming";
14865
+ var RequestEvShareQData = "qData";
14847
14866
  function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trailingSlash, basePathname, qwikSerializer, resolved) {
14848
14867
  const { request, platform, env: env2 } = serverRequestEv;
14849
14868
  const sharedMap = /* @__PURE__ */ new Map();
@@ -14927,6 +14946,7 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
14927
14946
  const loaders = {};
14928
14947
  const requestEv = {
14929
14948
  [RequestEvLoaders]: loaders,
14949
+ [RequestEvLoaderSerializationStrategyMap]: /* @__PURE__ */ new Map(),
14930
14950
  [RequestEvMode]: serverRequestEv.mode,
14931
14951
  [RequestEvTrailingSlash]: trailingSlash,
14932
14952
  get [RequestEvRoute]() {
@@ -14940,7 +14960,7 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
14940
14960
  signal: request.signal,
14941
14961
  originalUrl: new URL(url),
14942
14962
  get params() {
14943
- return (loadedRoute == null ? void 0 : loadedRoute[1]) ?? {};
14963
+ return (loadedRoute == null ? void 0 : loadedRoute[1 /* Params */]) ?? {};
14944
14964
  },
14945
14965
  get pathname() {
14946
14966
  return url.pathname;
@@ -15058,9 +15078,12 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
15058
15078
  getWritableStream: () => {
15059
15079
  if (writableStream === null) {
15060
15080
  if (serverRequestEv.mode === "dev") {
15061
- const serverTiming = sharedMap.get("@serverTiming");
15081
+ const serverTiming = sharedMap.get(RequestEvShareServerTiming);
15062
15082
  if (serverTiming) {
15063
- headers.set("Server-Timing", serverTiming.map((a) => `${a[0]};dur=${a[1]}`).join(","));
15083
+ headers.set(
15084
+ "Server-Timing",
15085
+ serverTiming.map(([name, duration]) => `${name};dur=${duration}`).join(",")
15086
+ );
15064
15087
  }
15065
15088
  }
15066
15089
  writableStream = serverRequestEv.getWritableStream(
@@ -15079,6 +15102,9 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
15079
15102
  function getRequestLoaders(requestEv) {
15080
15103
  return requestEv[RequestEvLoaders];
15081
15104
  }
15105
+ function getRequestLoaderSerializationStrategyMap(requestEv) {
15106
+ return requestEv[RequestEvLoaderSerializationStrategyMap];
15107
+ }
15082
15108
  function getRequestTrailingSlash(requestEv) {
15083
15109
  return requestEv[RequestEvTrailingSlash];
15084
15110
  }
@@ -15151,13 +15177,15 @@ function getQwikRouterServerData(requestEv) {
15151
15177
  if (protocol) {
15152
15178
  reconstructedUrl.protocol = protocol;
15153
15179
  }
15180
+ const loaders = getRequestLoaders(requestEv);
15181
+ const loadersSerializationStrategy = getRequestLoaderSerializationStrategyMap(requestEv);
15154
15182
  return {
15155
15183
  url: reconstructedUrl.href,
15156
15184
  requestHeaders,
15157
15185
  locale: locale(),
15158
15186
  nonce,
15159
15187
  containerAttributes: {
15160
- "q:route": routeName
15188
+ [Q_ROUTE]: routeName
15161
15189
  },
15162
15190
  qwikrouter: {
15163
15191
  routeName,
@@ -15166,7 +15194,8 @@ function getQwikRouterServerData(requestEv) {
15166
15194
  loadedRoute: getRequestRoute(requestEv),
15167
15195
  response: {
15168
15196
  status: status(),
15169
- loaders: getRequestLoaders(requestEv),
15197
+ loaders,
15198
+ loadersSerializationStrategy,
15170
15199
  action,
15171
15200
  formData
15172
15201
  }
@@ -15179,7 +15208,7 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15179
15208
  const routeLoaders = [];
15180
15209
  const routeActions = [];
15181
15210
  const requestHandlers = [];
15182
- const isPageRoute = !!(route && isLastModulePageRoute(route[2]));
15211
+ const isPageRoute = !!(route && isLastModulePageRoute(route[2 /* Mods */]));
15183
15212
  if (serverPlugins) {
15184
15213
  _resolveRequestHandlers(
15185
15214
  routeLoaders,
@@ -15191,7 +15220,7 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15191
15220
  );
15192
15221
  }
15193
15222
  if (route) {
15194
- const routeName = route[0];
15223
+ const routeName = route[0 /* RouteName */];
15195
15224
  if (checkOrigin && (method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE")) {
15196
15225
  requestHandlers.unshift(csrfCheckMiddleware);
15197
15226
  }
@@ -15202,7 +15231,7 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15202
15231
  requestHandlers.push(fixTrailingSlash);
15203
15232
  requestHandlers.push(renderQData);
15204
15233
  }
15205
- const routeModules = route[2];
15234
+ const routeModules = route[2 /* Mods */];
15206
15235
  requestHandlers.push(handleRedirect);
15207
15236
  _resolveRequestHandlers(
15208
15237
  routeLoaders,
@@ -15216,7 +15245,8 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15216
15245
  requestHandlers.push((ev) => {
15217
15246
  ev.sharedMap.set(RequestRouteName, routeName);
15218
15247
  });
15219
- requestHandlers.push(actionsMiddleware(routeActions, routeLoaders));
15248
+ requestHandlers.push(actionsMiddleware(routeActions));
15249
+ requestHandlers.push(loadersMiddleware(routeLoaders));
15220
15250
  requestHandlers.push(renderHandler);
15221
15251
  }
15222
15252
  }
@@ -15281,8 +15311,9 @@ var _resolveRequestHandlers = (routeLoaders, routeActions, requestHandlers, rout
15281
15311
  var checkBrand = (obj, brand) => {
15282
15312
  return obj && typeof obj === "function" && obj.__brand === brand;
15283
15313
  };
15284
- function actionsMiddleware(routeActions, routeLoaders) {
15285
- return async (requestEv) => {
15314
+ function actionsMiddleware(routeActions) {
15315
+ return async (requestEvent) => {
15316
+ const requestEv = requestEvent;
15286
15317
  if (requestEv.headersSent) {
15287
15318
  requestEv.exit();
15288
15319
  return;
@@ -15317,7 +15348,7 @@ function actionsMiddleware(routeActions, routeLoaders) {
15317
15348
  } else {
15318
15349
  const actionResolved = isDev ? await measure(
15319
15350
  requestEv,
15320
- action.__qrl.getSymbol().split("_", 1)[0],
15351
+ action.__qrl.getHash(),
15321
15352
  () => action.__qrl.call(requestEv, result.data, requestEv)
15322
15353
  ) : await action.__qrl.call(requestEv, result.data, requestEv);
15323
15354
  if (isDev) {
@@ -15328,46 +15359,74 @@ function actionsMiddleware(routeActions, routeLoaders) {
15328
15359
  }
15329
15360
  }
15330
15361
  }
15362
+ };
15363
+ }
15364
+ function loadersMiddleware(routeLoaders) {
15365
+ return async (requestEvent) => {
15366
+ const requestEv = requestEvent;
15367
+ if (requestEv.headersSent) {
15368
+ requestEv.exit();
15369
+ return;
15370
+ }
15371
+ const loaders = getRequestLoaders(requestEv);
15372
+ const isDev = getRequestMode(requestEv) === "dev";
15373
+ const qwikSerializer = requestEv[RequestEvQwikSerializer];
15331
15374
  if (routeLoaders.length > 0) {
15332
- const resolvedLoadersPromises = routeLoaders.map((loader) => {
15333
- const loaderId = loader.__id;
15334
- loaders[loaderId] = runValidators(
15335
- requestEv,
15336
- loader.__validators,
15337
- void 0,
15338
- // data
15339
- isDev
15340
- ).then((res) => {
15341
- if (res.success) {
15342
- if (isDev) {
15343
- return measure(
15344
- requestEv,
15345
- loader.__qrl.getSymbol().split("_", 1)[0],
15346
- () => loader.__qrl.call(requestEv, requestEv)
15347
- );
15348
- } else {
15349
- return loader.__qrl.call(requestEv, requestEv);
15350
- }
15351
- } else {
15352
- return requestEv.fail(res.status ?? 500, res.error);
15353
- }
15354
- }).then((resolvedLoader) => {
15355
- if (typeof resolvedLoader === "function") {
15356
- loaders[loaderId] = resolvedLoader();
15357
- } else {
15358
- if (isDev) {
15359
- verifySerializable(qwikSerializer, resolvedLoader, loader.__qrl);
15360
- }
15361
- loaders[loaderId] = resolvedLoader;
15375
+ let currentLoaders = [];
15376
+ if (requestEv.query.has(QLOADER_KEY)) {
15377
+ const selectedLoaderIds = requestEv.query.getAll(QLOADER_KEY);
15378
+ for (const loader of routeLoaders) {
15379
+ if (selectedLoaderIds.includes(loader.__id)) {
15380
+ currentLoaders.push(loader);
15362
15381
  }
15363
- return resolvedLoader;
15364
- });
15365
- return loaders[loaderId];
15366
- });
15382
+ }
15383
+ } else {
15384
+ currentLoaders = routeLoaders;
15385
+ }
15386
+ const resolvedLoadersPromises = currentLoaders.map(
15387
+ (loader) => getRouteLoaderPromise(loader, loaders, requestEv, isDev, qwikSerializer)
15388
+ );
15367
15389
  await Promise.all(resolvedLoadersPromises);
15368
15390
  }
15369
15391
  };
15370
15392
  }
15393
+ async function getRouteLoaderPromise(loader, loaders, requestEv, isDev, qwikSerializer) {
15394
+ const loaderId = loader.__id;
15395
+ loaders[loaderId] = runValidators(
15396
+ requestEv,
15397
+ loader.__validators,
15398
+ void 0,
15399
+ // data
15400
+ isDev
15401
+ ).then((res) => {
15402
+ if (res.success) {
15403
+ if (isDev) {
15404
+ return measure(
15405
+ requestEv,
15406
+ loader.__qrl.getHash(),
15407
+ () => loader.__qrl.call(requestEv, requestEv)
15408
+ );
15409
+ } else {
15410
+ return loader.__qrl.call(requestEv, requestEv);
15411
+ }
15412
+ } else {
15413
+ return requestEv.fail(res.status ?? 500, res.error);
15414
+ }
15415
+ }).then((resolvedLoader) => {
15416
+ if (typeof resolvedLoader === "function") {
15417
+ loaders[loaderId] = resolvedLoader();
15418
+ } else {
15419
+ if (isDev) {
15420
+ verifySerializable(qwikSerializer, resolvedLoader, loader.__qrl);
15421
+ }
15422
+ loaders[loaderId] = resolvedLoader;
15423
+ }
15424
+ return resolvedLoader;
15425
+ });
15426
+ const loadersSerializationStrategy = getRequestLoaderSerializationStrategyMap(requestEv);
15427
+ loadersSerializationStrategy.set(loaderId, loader.__serializationStrategy);
15428
+ return loaders[loaderId];
15429
+ }
15371
15430
  async function runValidators(requestEv, validators, data, isDev) {
15372
15431
  let lastResult = {
15373
15432
  success: true,
@@ -15502,7 +15561,7 @@ function getPathname(url, trailingSlash) {
15502
15561
  url.pathname = url.pathname.slice(0, -1);
15503
15562
  }
15504
15563
  }
15505
- const search2 = url.search.slice(1).replaceAll(/&?q(action|data|func)=[^&]+/g, "");
15564
+ const search2 = url.search.slice(1).replaceAll(/&?q(action|data|func|loaders)=[^&]+/g, "");
15506
15565
  return `${url.pathname}${search2 ? `?${search2}` : ""}${url.hash}`;
15507
15566
  }
15508
15567
  var encoder = /* @__PURE__ */ new TextEncoder();
@@ -15542,10 +15601,10 @@ async function handleRedirect(requestEv) {
15542
15601
  return;
15543
15602
  }
15544
15603
  const status = requestEv.status();
15545
- const location = requestEv.headers.get("Location");
15546
- const isRedirect = status >= 301 && status <= 308 && location;
15604
+ const location2 = requestEv.headers.get("Location");
15605
+ const isRedirect = status >= 301 && status <= 308 && location2;
15547
15606
  if (isRedirect) {
15548
- const adaptedLocation = makeQDataPath(location);
15607
+ const adaptedLocation = makeQDataPath(location2);
15549
15608
  if (adaptedLocation) {
15550
15609
  requestEv.headers.set("Location", adaptedLocation);
15551
15610
  requestEv.getWritableStream().close();
@@ -15571,8 +15630,24 @@ async function renderQData(requestEv) {
15571
15630
  const requestHeaders = {};
15572
15631
  requestEv.request.headers.forEach((value2, key) => requestHeaders[key] = value2);
15573
15632
  requestEv.headers.set("Content-Type", "application/json; charset=utf-8");
15574
- const qData = {
15575
- loaders: getRequestLoaders(requestEv),
15633
+ let loaders = getRequestLoaders(requestEv);
15634
+ const selectedLoaderIds = requestEv.query.getAll(QLOADER_KEY);
15635
+ const hasCustomLoaders = selectedLoaderIds.length > 0;
15636
+ if (hasCustomLoaders) {
15637
+ const selectedLoaders = {};
15638
+ for (const loaderId of selectedLoaderIds) {
15639
+ const loader = loaders[loaderId];
15640
+ selectedLoaders[loaderId] = loader;
15641
+ }
15642
+ loaders = selectedLoaders;
15643
+ }
15644
+ const qData = hasCustomLoaders ? {
15645
+ // send minimal data to the client
15646
+ loaders,
15647
+ status: status !== 200 ? status : 200,
15648
+ href: getPathname(requestEv.url, trailingSlash)
15649
+ } : {
15650
+ loaders,
15576
15651
  action: requestEv.sharedMap.get(RequestEvSharedActionId),
15577
15652
  status: status !== 200 ? status : 200,
15578
15653
  href: getPathname(requestEv.url, trailingSlash),
@@ -15583,7 +15658,7 @@ async function renderQData(requestEv) {
15583
15658
  const qwikSerializer = requestEv[RequestEvQwikSerializer];
15584
15659
  const data = await qwikSerializer._serialize([qData]);
15585
15660
  writer.write(encoder.encode(data));
15586
- requestEv.sharedMap.set("qData", qData);
15661
+ requestEv.sharedMap.set(RequestEvShareQData, qData);
15587
15662
  writer.close();
15588
15663
  }
15589
15664
  function makeQDataPath(href) {
@@ -15605,9 +15680,9 @@ async function measure(requestEv, name, fn) {
15605
15680
  return await fn();
15606
15681
  } finally {
15607
15682
  const duration = now() - start;
15608
- let measurements = requestEv.sharedMap.get("@serverTiming");
15683
+ let measurements = requestEv.sharedMap.get(RequestEvShareServerTiming);
15609
15684
  if (!measurements) {
15610
- requestEv.sharedMap.set("@serverTiming", measurements = []);
15685
+ requestEv.sharedMap.set(RequestEvShareServerTiming, measurements = []);
15611
15686
  }
15612
15687
  measurements.push([name, duration]);
15613
15688
  }
@@ -26626,11 +26701,11 @@ function ssrDevMiddleware(ctx, server) {
26626
26701
  if (cookieHeaders.length > 0) {
26627
26702
  res.setHeader("Set-Cookie", cookieHeaders);
26628
26703
  }
26629
- const serverTiming = requestEv.sharedMap.get("@serverTiming");
26704
+ const serverTiming = requestEv.sharedMap.get(RequestEvShareServerTiming);
26630
26705
  if (serverTiming) {
26631
26706
  res.setHeader(
26632
26707
  "Server-Timing",
26633
- serverTiming.map((a) => `${a[0]};dur=${a[1]}`).join(",")
26708
+ serverTiming.map(([name, duration]) => `${name};dur=${duration}`).join(",")
26634
26709
  );
26635
26710
  }
26636
26711
  res._qwikEnvData = {
@@ -26654,8 +26729,8 @@ function ssrDevMiddleware(ctx, server) {
26654
26729
  if (requestHandlers.length > 0) {
26655
26730
  const serverRequestEv = await fromNodeHttp(url, req, res, "dev");
26656
26731
  Object.assign(serverRequestEv.platform, ctx.opts.platform);
26657
- const { _deserialize, _serialize, _verifySerializable } = await server.ssrLoadModule("@qwik-serializer");
26658
- const qwikSerializer = { _deserialize, _serialize, _verifySerializable };
26732
+ const { _deserialize: _deserialize2, _serialize, _verifySerializable } = await server.ssrLoadModule("@qwik-serializer");
26733
+ const qwikSerializer = { _deserialize: _deserialize2, _serialize, _verifySerializable };
26659
26734
  const rebuildRouteInfo = async (url2) => {
26660
26735
  const { serverPlugins: serverPlugins2, loadedRoute: loadedRoute2 } = await resolveRoute2(routeModulePaths, url2);
26661
26736
  const requestHandlers2 = resolveRequestHandlers(
@@ -27205,6 +27280,11 @@ function qwikRouterPlugin(userOpts) {
27205
27280
  api,
27206
27281
  async config() {
27207
27282
  const updatedViteConfig = {
27283
+ define: {
27284
+ "globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__": JSON.stringify(
27285
+ (userOpts == null ? void 0 : userOpts.defaultLoadersSerializationStrategy) || "never"
27286
+ )
27287
+ },
27208
27288
  appType: "custom",
27209
27289
  resolve: {
27210
27290
  alias: [
@@ -4,6 +4,7 @@ import type { Config } from 'svgo';
4
4
  import { ConfigEnv } from 'vite';
5
5
  import type { Plugin as Plugin_2 } from 'vite';
6
6
  import type { PluginOption } from 'vite';
7
+ import type { SerializationStrategy } from '@qwik.dev/core/internal';
7
8
  import { UserConfigExport } from 'vite';
8
9
 
9
10
  declare interface BuildEntry extends ParsedPathname {
@@ -102,6 +103,8 @@ declare interface PluginOptions {
102
103
  platform?: Record<string, unknown>;
103
104
  /** Configuration to rewrite url paths */
104
105
  rewriteRoutes?: RewriteRouteOption[];
106
+ /** The serialization strategy for route loaders. Defaults to `never`. */
107
+ defaultLoadersSerializationStrategy?: SerializationStrategy;
105
108
  }
106
109
 
107
110
  /**