@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.
@@ -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,14 +14669,20 @@ 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
  };
14665
14679
 
14680
+ // packages/qwik-router/src/middleware/request-handler/resolve-request-handlers.ts
14681
+ var import_internal4 = require("@qwik.dev/core/internal");
14682
+
14683
+ // packages/qwik-router/src/middleware/request-handler/request-event.ts
14684
+ var import_internal3 = require("@qwik.dev/core/internal");
14685
+
14666
14686
  // packages/qwik-router/src/middleware/request-handler/cache-control.ts
14667
14687
  function createCacheControl(cacheControl) {
14668
14688
  const controls = [];
@@ -14838,12 +14858,17 @@ var RequestEvLoaders = Symbol("RequestEvLoaders");
14838
14858
  var RequestEvMode = Symbol("RequestEvMode");
14839
14859
  var RequestEvRoute = Symbol("RequestEvRoute");
14840
14860
  var RequestEvQwikSerializer = Symbol("RequestEvQwikSerializer");
14861
+ var RequestEvLoaderSerializationStrategyMap = Symbol(
14862
+ "RequestEvLoaderSerializationStrategyMap"
14863
+ );
14841
14864
  var RequestEvTrailingSlash = Symbol("RequestEvTrailingSlash");
14842
14865
  var RequestRouteName = "@routeName";
14843
14866
  var RequestEvSharedActionId = "@actionId";
14844
14867
  var RequestEvSharedActionFormData = "@actionFormData";
14845
14868
  var RequestEvSharedNonce = "@nonce";
14846
14869
  var RequestEvIsRewrite = "@rewrite";
14870
+ var RequestEvShareServerTiming = "@serverTiming";
14871
+ var RequestEvShareQData = "qData";
14847
14872
  function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trailingSlash, basePathname, qwikSerializer, resolved) {
14848
14873
  const { request, platform, env: env2 } = serverRequestEv;
14849
14874
  const sharedMap = /* @__PURE__ */ new Map();
@@ -14927,6 +14952,7 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
14927
14952
  const loaders = {};
14928
14953
  const requestEv = {
14929
14954
  [RequestEvLoaders]: loaders,
14955
+ [RequestEvLoaderSerializationStrategyMap]: /* @__PURE__ */ new Map(),
14930
14956
  [RequestEvMode]: serverRequestEv.mode,
14931
14957
  [RequestEvTrailingSlash]: trailingSlash,
14932
14958
  get [RequestEvRoute]() {
@@ -14940,7 +14966,7 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
14940
14966
  signal: request.signal,
14941
14967
  originalUrl: new URL(url),
14942
14968
  get params() {
14943
- return (loadedRoute == null ? void 0 : loadedRoute[1]) ?? {};
14969
+ return (loadedRoute == null ? void 0 : loadedRoute[1 /* Params */]) ?? {};
14944
14970
  },
14945
14971
  get pathname() {
14946
14972
  return url.pathname;
@@ -14977,6 +15003,10 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
14977
15003
  "You can not get the returned data of a loader that has not been executed for this request."
14978
15004
  );
14979
15005
  }
15006
+ if (loaders[id] === import_internal3._UNINITIALIZED) {
15007
+ const isDev = getRequestMode(requestEv) === "dev";
15008
+ await getRouteLoaderPromise(loaderOrAction, loaders, requestEv, isDev, qwikSerializer);
15009
+ }
14980
15010
  }
14981
15011
  return loaders[id];
14982
15012
  },
@@ -15058,9 +15088,12 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
15058
15088
  getWritableStream: () => {
15059
15089
  if (writableStream === null) {
15060
15090
  if (serverRequestEv.mode === "dev") {
15061
- const serverTiming = sharedMap.get("@serverTiming");
15091
+ const serverTiming = sharedMap.get(RequestEvShareServerTiming);
15062
15092
  if (serverTiming) {
15063
- headers.set("Server-Timing", serverTiming.map((a) => `${a[0]};dur=${a[1]}`).join(","));
15093
+ headers.set(
15094
+ "Server-Timing",
15095
+ serverTiming.map(([name, duration]) => `${name};dur=${duration}`).join(",")
15096
+ );
15064
15097
  }
15065
15098
  }
15066
15099
  writableStream = serverRequestEv.getWritableStream(
@@ -15079,6 +15112,9 @@ function createRequestEvent(serverRequestEv, loadedRoute, requestHandlers, trail
15079
15112
  function getRequestLoaders(requestEv) {
15080
15113
  return requestEv[RequestEvLoaders];
15081
15114
  }
15115
+ function getRequestLoaderSerializationStrategyMap(requestEv) {
15116
+ return requestEv[RequestEvLoaderSerializationStrategyMap];
15117
+ }
15082
15118
  function getRequestTrailingSlash(requestEv) {
15083
15119
  return requestEv[RequestEvTrailingSlash];
15084
15120
  }
@@ -15151,13 +15187,15 @@ function getQwikRouterServerData(requestEv) {
15151
15187
  if (protocol) {
15152
15188
  reconstructedUrl.protocol = protocol;
15153
15189
  }
15190
+ const loaders = getRequestLoaders(requestEv);
15191
+ const loadersSerializationStrategy = getRequestLoaderSerializationStrategyMap(requestEv);
15154
15192
  return {
15155
15193
  url: reconstructedUrl.href,
15156
15194
  requestHeaders,
15157
15195
  locale: locale(),
15158
15196
  nonce,
15159
15197
  containerAttributes: {
15160
- "q:route": routeName
15198
+ [Q_ROUTE]: routeName
15161
15199
  },
15162
15200
  qwikrouter: {
15163
15201
  routeName,
@@ -15166,7 +15204,8 @@ function getQwikRouterServerData(requestEv) {
15166
15204
  loadedRoute: getRequestRoute(requestEv),
15167
15205
  response: {
15168
15206
  status: status(),
15169
- loaders: getRequestLoaders(requestEv),
15207
+ loaders,
15208
+ loadersSerializationStrategy,
15170
15209
  action,
15171
15210
  formData
15172
15211
  }
@@ -15179,7 +15218,7 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15179
15218
  const routeLoaders = [];
15180
15219
  const routeActions = [];
15181
15220
  const requestHandlers = [];
15182
- const isPageRoute = !!(route && isLastModulePageRoute(route[2]));
15221
+ const isPageRoute = !!(route && isLastModulePageRoute(route[2 /* Mods */]));
15183
15222
  if (serverPlugins) {
15184
15223
  _resolveRequestHandlers(
15185
15224
  routeLoaders,
@@ -15191,7 +15230,7 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15191
15230
  );
15192
15231
  }
15193
15232
  if (route) {
15194
- const routeName = route[0];
15233
+ const routeName = route[0 /* RouteName */];
15195
15234
  if (checkOrigin && (method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE")) {
15196
15235
  requestHandlers.unshift(csrfCheckMiddleware);
15197
15236
  }
@@ -15202,7 +15241,7 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15202
15241
  requestHandlers.push(fixTrailingSlash);
15203
15242
  requestHandlers.push(renderQData);
15204
15243
  }
15205
- const routeModules = route[2];
15244
+ const routeModules = route[2 /* Mods */];
15206
15245
  requestHandlers.push(handleRedirect);
15207
15246
  _resolveRequestHandlers(
15208
15247
  routeLoaders,
@@ -15216,7 +15255,8 @@ var resolveRequestHandlers = (serverPlugins, route, method, checkOrigin, renderH
15216
15255
  requestHandlers.push((ev) => {
15217
15256
  ev.sharedMap.set(RequestRouteName, routeName);
15218
15257
  });
15219
- requestHandlers.push(actionsMiddleware(routeActions, routeLoaders));
15258
+ requestHandlers.push(actionsMiddleware(routeActions));
15259
+ requestHandlers.push(loadersMiddleware(routeLoaders));
15220
15260
  requestHandlers.push(renderHandler);
15221
15261
  }
15222
15262
  }
@@ -15281,8 +15321,9 @@ var _resolveRequestHandlers = (routeLoaders, routeActions, requestHandlers, rout
15281
15321
  var checkBrand = (obj, brand) => {
15282
15322
  return obj && typeof obj === "function" && obj.__brand === brand;
15283
15323
  };
15284
- function actionsMiddleware(routeActions, routeLoaders) {
15285
- return async (requestEv) => {
15324
+ function actionsMiddleware(routeActions) {
15325
+ return async (requestEvent) => {
15326
+ const requestEv = requestEvent;
15286
15327
  if (requestEv.headersSent) {
15287
15328
  requestEv.exit();
15288
15329
  return;
@@ -15317,7 +15358,7 @@ function actionsMiddleware(routeActions, routeLoaders) {
15317
15358
  } else {
15318
15359
  const actionResolved = isDev ? await measure(
15319
15360
  requestEv,
15320
- action.__qrl.getSymbol().split("_", 1)[0],
15361
+ action.__qrl.getHash(),
15321
15362
  () => action.__qrl.call(requestEv, result.data, requestEv)
15322
15363
  ) : await action.__qrl.call(requestEv, result.data, requestEv);
15323
15364
  if (isDev) {
@@ -15328,46 +15369,76 @@ function actionsMiddleware(routeActions, routeLoaders) {
15328
15369
  }
15329
15370
  }
15330
15371
  }
15372
+ };
15373
+ }
15374
+ function loadersMiddleware(routeLoaders) {
15375
+ return async (requestEvent) => {
15376
+ const requestEv = requestEvent;
15377
+ if (requestEv.headersSent) {
15378
+ requestEv.exit();
15379
+ return;
15380
+ }
15381
+ const loaders = getRequestLoaders(requestEv);
15382
+ const isDev = getRequestMode(requestEv) === "dev";
15383
+ const qwikSerializer = requestEv[RequestEvQwikSerializer];
15331
15384
  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();
15385
+ let currentLoaders = [];
15386
+ if (requestEv.query.has(QLOADER_KEY)) {
15387
+ const selectedLoaderIds = requestEv.query.getAll(QLOADER_KEY);
15388
+ for (const loader of routeLoaders) {
15389
+ if (selectedLoaderIds.includes(loader.__id)) {
15390
+ currentLoaders.push(loader);
15357
15391
  } else {
15358
- if (isDev) {
15359
- verifySerializable(qwikSerializer, resolvedLoader, loader.__qrl);
15360
- }
15361
- loaders[loaderId] = resolvedLoader;
15392
+ loaders[loader.__id] = import_internal4._UNINITIALIZED;
15362
15393
  }
15363
- return resolvedLoader;
15364
- });
15365
- return loaders[loaderId];
15366
- });
15394
+ }
15395
+ } else {
15396
+ currentLoaders = routeLoaders;
15397
+ }
15398
+ const resolvedLoadersPromises = currentLoaders.map(
15399
+ (loader) => getRouteLoaderPromise(loader, loaders, requestEv, isDev, qwikSerializer)
15400
+ );
15367
15401
  await Promise.all(resolvedLoadersPromises);
15368
15402
  }
15369
15403
  };
15370
15404
  }
15405
+ async function getRouteLoaderPromise(loader, loaders, requestEv, isDev, qwikSerializer) {
15406
+ const loaderId = loader.__id;
15407
+ loaders[loaderId] = runValidators(
15408
+ requestEv,
15409
+ loader.__validators,
15410
+ void 0,
15411
+ // data
15412
+ isDev
15413
+ ).then((res) => {
15414
+ if (res.success) {
15415
+ if (isDev) {
15416
+ return measure(
15417
+ requestEv,
15418
+ loader.__qrl.getHash(),
15419
+ () => loader.__qrl.call(requestEv, requestEv)
15420
+ );
15421
+ } else {
15422
+ return loader.__qrl.call(requestEv, requestEv);
15423
+ }
15424
+ } else {
15425
+ return requestEv.fail(res.status ?? 500, res.error);
15426
+ }
15427
+ }).then((resolvedLoader) => {
15428
+ if (typeof resolvedLoader === "function") {
15429
+ loaders[loaderId] = resolvedLoader();
15430
+ } else {
15431
+ if (isDev) {
15432
+ verifySerializable(qwikSerializer, resolvedLoader, loader.__qrl);
15433
+ }
15434
+ loaders[loaderId] = resolvedLoader;
15435
+ }
15436
+ return resolvedLoader;
15437
+ });
15438
+ const loadersSerializationStrategy = getRequestLoaderSerializationStrategyMap(requestEv);
15439
+ loadersSerializationStrategy.set(loaderId, loader.__serializationStrategy);
15440
+ return loaders[loaderId];
15441
+ }
15371
15442
  async function runValidators(requestEv, validators, data, isDev) {
15372
15443
  let lastResult = {
15373
15444
  success: true,
@@ -15502,7 +15573,7 @@ function getPathname(url, trailingSlash) {
15502
15573
  url.pathname = url.pathname.slice(0, -1);
15503
15574
  }
15504
15575
  }
15505
- const search2 = url.search.slice(1).replaceAll(/&?q(action|data|func)=[^&]+/g, "");
15576
+ const search2 = url.search.slice(1).replaceAll(/&?q(action|data|func|loaders)=[^&]+/g, "");
15506
15577
  return `${url.pathname}${search2 ? `?${search2}` : ""}${url.hash}`;
15507
15578
  }
15508
15579
  var encoder = /* @__PURE__ */ new TextEncoder();
@@ -15542,10 +15613,10 @@ async function handleRedirect(requestEv) {
15542
15613
  return;
15543
15614
  }
15544
15615
  const status = requestEv.status();
15545
- const location = requestEv.headers.get("Location");
15546
- const isRedirect = status >= 301 && status <= 308 && location;
15616
+ const location2 = requestEv.headers.get("Location");
15617
+ const isRedirect = status >= 301 && status <= 308 && location2;
15547
15618
  if (isRedirect) {
15548
- const adaptedLocation = makeQDataPath(location);
15619
+ const adaptedLocation = makeQDataPath(location2);
15549
15620
  if (adaptedLocation) {
15550
15621
  requestEv.headers.set("Location", adaptedLocation);
15551
15622
  requestEv.getWritableStream().close();
@@ -15571,8 +15642,24 @@ async function renderQData(requestEv) {
15571
15642
  const requestHeaders = {};
15572
15643
  requestEv.request.headers.forEach((value2, key) => requestHeaders[key] = value2);
15573
15644
  requestEv.headers.set("Content-Type", "application/json; charset=utf-8");
15574
- const qData = {
15575
- loaders: getRequestLoaders(requestEv),
15645
+ let loaders = getRequestLoaders(requestEv);
15646
+ const selectedLoaderIds = requestEv.query.getAll(QLOADER_KEY);
15647
+ const hasCustomLoaders = selectedLoaderIds.length > 0;
15648
+ if (hasCustomLoaders) {
15649
+ const selectedLoaders = {};
15650
+ for (const loaderId of selectedLoaderIds) {
15651
+ const loader = loaders[loaderId];
15652
+ selectedLoaders[loaderId] = loader;
15653
+ }
15654
+ loaders = selectedLoaders;
15655
+ }
15656
+ const qData = hasCustomLoaders ? {
15657
+ // send minimal data to the client
15658
+ loaders,
15659
+ status: status !== 200 ? status : 200,
15660
+ href: getPathname(requestEv.url, trailingSlash)
15661
+ } : {
15662
+ loaders,
15576
15663
  action: requestEv.sharedMap.get(RequestEvSharedActionId),
15577
15664
  status: status !== 200 ? status : 200,
15578
15665
  href: getPathname(requestEv.url, trailingSlash),
@@ -15583,7 +15670,7 @@ async function renderQData(requestEv) {
15583
15670
  const qwikSerializer = requestEv[RequestEvQwikSerializer];
15584
15671
  const data = await qwikSerializer._serialize([qData]);
15585
15672
  writer.write(encoder.encode(data));
15586
- requestEv.sharedMap.set("qData", qData);
15673
+ requestEv.sharedMap.set(RequestEvShareQData, qData);
15587
15674
  writer.close();
15588
15675
  }
15589
15676
  function makeQDataPath(href) {
@@ -15605,9 +15692,9 @@ async function measure(requestEv, name, fn) {
15605
15692
  return await fn();
15606
15693
  } finally {
15607
15694
  const duration = now() - start;
15608
- let measurements = requestEv.sharedMap.get("@serverTiming");
15695
+ let measurements = requestEv.sharedMap.get(RequestEvShareServerTiming);
15609
15696
  if (!measurements) {
15610
- requestEv.sharedMap.set("@serverTiming", measurements = []);
15697
+ requestEv.sharedMap.set(RequestEvShareServerTiming, measurements = []);
15611
15698
  }
15612
15699
  measurements.push([name, duration]);
15613
15700
  }
@@ -26626,11 +26713,11 @@ function ssrDevMiddleware(ctx, server) {
26626
26713
  if (cookieHeaders.length > 0) {
26627
26714
  res.setHeader("Set-Cookie", cookieHeaders);
26628
26715
  }
26629
- const serverTiming = requestEv.sharedMap.get("@serverTiming");
26716
+ const serverTiming = requestEv.sharedMap.get(RequestEvShareServerTiming);
26630
26717
  if (serverTiming) {
26631
26718
  res.setHeader(
26632
26719
  "Server-Timing",
26633
- serverTiming.map((a) => `${a[0]};dur=${a[1]}`).join(",")
26720
+ serverTiming.map(([name, duration]) => `${name};dur=${duration}`).join(",")
26634
26721
  );
26635
26722
  }
26636
26723
  res._qwikEnvData = {
@@ -26654,8 +26741,8 @@ function ssrDevMiddleware(ctx, server) {
26654
26741
  if (requestHandlers.length > 0) {
26655
26742
  const serverRequestEv = await fromNodeHttp(url, req, res, "dev");
26656
26743
  Object.assign(serverRequestEv.platform, ctx.opts.platform);
26657
- const { _deserialize, _serialize, _verifySerializable } = await server.ssrLoadModule("@qwik-serializer");
26658
- const qwikSerializer = { _deserialize, _serialize, _verifySerializable };
26744
+ const { _deserialize: _deserialize2, _serialize, _verifySerializable } = await server.ssrLoadModule("@qwik-serializer");
26745
+ const qwikSerializer = { _deserialize: _deserialize2, _serialize, _verifySerializable };
26659
26746
  const rebuildRouteInfo = async (url2) => {
26660
26747
  const { serverPlugins: serverPlugins2, loadedRoute: loadedRoute2 } = await resolveRoute2(routeModulePaths, url2);
26661
26748
  const requestHandlers2 = resolveRequestHandlers(
@@ -27205,6 +27292,11 @@ function qwikRouterPlugin(userOpts) {
27205
27292
  api,
27206
27293
  async config() {
27207
27294
  const updatedViteConfig = {
27295
+ define: {
27296
+ "globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__": JSON.stringify(
27297
+ (userOpts == null ? void 0 : userOpts.defaultLoadersSerializationStrategy) || "never"
27298
+ )
27299
+ },
27208
27300
  appType: "custom",
27209
27301
  resolve: {
27210
27302
  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
  /**