Skip to content

Commit b64c34a

Browse files
committed
feat: global config for loader serialization strategy
1 parent 1b03e9d commit b64c34a

File tree

15 files changed

+99
-17
lines changed

15 files changed

+99
-17
lines changed

packages/docs/src/routes/docs/(qwikrouter)/route-loader/index.mdx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,28 @@ export const Child = component$(() => {
193193
});
194194
```
195195

196+
### Global default serialization strategy
197+
It is possible to set a global default serialization strategy for all `routeLoader$`s in your application. This can be done by configuring the `qwikRouter` Vite plugin.
198+
Default value is `never`.
199+
200+
```ts title="vite.config.ts"
201+
import { qwikRouter } from '@qwik.dev/vite-plugin-qwik-router';
202+
203+
export default () => {
204+
return {
205+
//...
206+
plugins: [
207+
//...
208+
qwikRouter({
209+
// Set the default serialization strategy for all route loaders
210+
defaultSerializationStrategy: 'always', // 'never' | 'always' | 'auto'
211+
}),
212+
//...
213+
],
214+
}
215+
};
216+
```
217+
196218
## RequestEvent
197219

198220
Just like [middleware](/docs/middleware/) or [endpoint](/docs/endpoints/) `onRequest` and `onGet`, `routeLoader$`s have access to the [`RequestEvent`](/docs/middleware#requestevent) API which includes information about the current HTTP request.

packages/qwik-router/global.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
type RequestEventInternal =
55
import('./middleware/request-handler/request-event').RequestEventInternal;
66
type AsyncStore = import('node:async_hooks').AsyncLocalStorage<RequestEventInternal>;
7+
type SerializationStrategy = import('@qwik.dev/core/internal').SerializationStrategy;
78

89
declare var qcAsyncRequestStore: AsyncStore | undefined;
910
declare var _qwikActionsMap: Map<string, ActionInternal> | undefined;
@@ -18,3 +19,5 @@ type ExperimentalFeatures = import('@qwik.dev/core/optimizer').ExperimentalFeatu
1819
declare var __EXPERIMENTAL__: {
1920
[K in ExperimentalFeatures]: boolean;
2021
};
22+
23+
declare var __DEFAULT_LOADERS_SERIALIZATION_STRATEGY__: SerializationStrategy;

packages/qwik-router/src/buildtime/markdown/markdown-url.unit.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ const menuFilePath = join(routesDir, 'docs', 'menu.md');
8080
mdx: {},
8181
platform: {},
8282
rewriteRoutes: [],
83+
defaultLoadersSerializationStrategy: 'never',
8384
};
8485
assert.equal(getMarkdownRelativeUrl(opts, menuFilePath, t.href), t.expect);
8586
});

packages/qwik-router/src/buildtime/routing/resolve-source-file.unit.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ test('resolveLayout', () => {
4949
mdx: {},
5050
platform: {},
5151
rewriteRoutes: [],
52+
defaultLoadersSerializationStrategy: 'never',
5253
};
5354
const sourceFile: RouteSourceFile = {
5455
...getSourceFile(c.fileName)!,

packages/qwik-router/src/buildtime/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { SerializationStrategy } from '@qwik.dev/core/internal';
2+
13
export interface BuildContext {
24
rootDir: string;
35
opts: NormalizedPluginOptions;
@@ -133,6 +135,8 @@ export interface PluginOptions {
133135
platform?: Record<string, unknown>;
134136
/** Configuration to rewrite url paths */
135137
rewriteRoutes?: RewriteRouteOption[];
138+
/** The serialization strategy for route loaders. Defaults to `never`. */
139+
defaultLoadersSerializationStrategy?: SerializationStrategy;
136140
}
137141

138142
export interface MdxPlugins {

packages/qwik-router/src/buildtime/vite/plugin.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ function qwikRouterPlugin(userOpts?: QwikRouterVitePluginOptions): any {
7878

7979
async config() {
8080
const updatedViteConfig: UserConfig = {
81+
define: {
82+
'globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__': JSON.stringify(
83+
userOpts?.defaultLoadersSerializationStrategy || 'never'
84+
),
85+
},
8186
appType: 'custom',
8287
resolve: {
8388
alias: [
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { describe, expect, it } from 'vitest';
2+
import { qwikRouter } from './plugin';
3+
4+
describe('qwikRouter plugin', () => {
5+
describe('defaultLoadersSerializationStrategy', () => {
6+
it('should set the defaultLoadersSerializationStrategy to "never" when not provided', async () => {
7+
const plugins = qwikRouter();
8+
9+
await expect((plugins[0] as any)?.config?.()).resolves.toMatchObject({
10+
define: {
11+
'globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__': '"never"',
12+
},
13+
});
14+
});
15+
16+
it('should set the defaultLoadersSerializationStrategy to "always" when provided', async () => {
17+
const plugins = qwikRouter({
18+
defaultLoadersSerializationStrategy: 'always',
19+
});
20+
21+
await expect((plugins[0] as any)?.config?.()).resolves.toMatchObject({
22+
define: {
23+
'globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__': '"always"',
24+
},
25+
});
26+
});
27+
});
28+
});

packages/qwik-router/src/buildtime/vite/qwik-router.buildtime.api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { Config } from 'svgo';
1010
import { ConfigEnv } from 'vite';
1111
import type { Plugin as Plugin_2 } from 'vite';
1212
import type { PluginOption } from 'vite';
13+
import type { SerializationStrategy } from '@qwik.dev/core/internal';
1314
import { UserConfigExport } from 'vite';
1415

1516
// @public (undocumented)

packages/qwik-router/src/middleware/request-handler/request-event.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ const RequestEvLoaders = Symbol('RequestEvLoaders');
3434
const RequestEvMode = Symbol('RequestEvMode');
3535
const RequestEvRoute = Symbol('RequestEvRoute');
3636
export const RequestEvQwikSerializer = Symbol('RequestEvQwikSerializer');
37-
export const RequestEvLoadersSerializationStrategy = Symbol(
38-
'RequestEvLoadersSerializationStrategy'
37+
export const RequestEvLoaderSerializationStrategyMap = Symbol(
38+
'RequestEvLoaderSerializationStrategyMap'
3939
);
4040
export const RequestEvTrailingSlash = Symbol('RequestEvTrailingSlash');
4141
export const RequestRouteName = '@routeName';
@@ -153,7 +153,7 @@ export function createRequestEvent(
153153
const loaders: Record<string, Promise<any>> = {};
154154
const requestEv: RequestEventInternal = {
155155
[RequestEvLoaders]: loaders,
156-
[RequestEvLoadersSerializationStrategy]: new Map(),
156+
[RequestEvLoaderSerializationStrategyMap]: new Map(),
157157
[RequestEvMode]: serverRequestEv.mode,
158158
[RequestEvTrailingSlash]: trailingSlash,
159159
get [RequestEvRoute]() {
@@ -333,7 +333,7 @@ export function createRequestEvent(
333333

334334
export interface RequestEventInternal extends RequestEvent, RequestEventLoader {
335335
[RequestEvLoaders]: Record<string, ValueOrPromise<unknown> | undefined>;
336-
[RequestEvLoadersSerializationStrategy]: Map<string, SerializationStrategy>;
336+
[RequestEvLoaderSerializationStrategyMap]: Map<string, SerializationStrategy>;
337337
[RequestEvMode]: ServerRequestMode;
338338
[RequestEvTrailingSlash]: boolean;
339339
[RequestEvRoute]: LoadedRoute | null;
@@ -364,8 +364,8 @@ export function getRequestLoaders(requestEv: RequestEventCommon) {
364364
return (requestEv as RequestEventInternal)[RequestEvLoaders];
365365
}
366366

367-
export function getRequestLoadersSerializationStrategy(requestEv: RequestEventCommon) {
368-
return (requestEv as RequestEventInternal)[RequestEvLoadersSerializationStrategy];
367+
export function getRequestLoaderSerializationStrategyMap(requestEv: RequestEventCommon) {
368+
return (requestEv as RequestEventInternal)[RequestEvLoaderSerializationStrategyMap];
369369
}
370370

371371
export function getRequestTrailingSlash(requestEv: RequestEventCommon) {

packages/qwik-router/src/middleware/request-handler/resolve-request-handlers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
RequestEvSharedActionId,
2525
RequestRouteName,
2626
getRequestLoaders,
27-
getRequestLoadersSerializationStrategy,
27+
getRequestLoaderSerializationStrategyMap,
2828
getRequestMode,
2929
getRequestTrailingSlash,
3030
type RequestEventInternal,
@@ -301,7 +301,7 @@ async function getRouteLoaderPromise(
301301
}
302302
return resolvedLoader;
303303
});
304-
const loadersSerializationStrategy = getRequestLoadersSerializationStrategy(requestEv);
304+
const loadersSerializationStrategy = getRequestLoaderSerializationStrategyMap(requestEv);
305305
loadersSerializationStrategy.set(loaderId, loader.__serializationStrategy);
306306
return loaders[loaderId];
307307
}

0 commit comments

Comments
 (0)