Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: route loader type
  • Loading branch information
Varixo authored and wmertens committed Sep 21, 2025
commit 4b71f510b2793d29aed5000048ebb91e2d8f53fc
2 changes: 1 addition & 1 deletion packages/docs/src/routes/api/qwik-router/api.json
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@
}
],
"kind": "TypeAlias",
"content": "```typescript\nexport type LoaderSignal<TYPE> = TYPE extends () => ValueOrPromise<infer VALIDATOR> ? ReadonlySignal<ValueOrPromise<VALIDATOR>> : ReadonlySignal<TYPE>;\n```",
"content": "```typescript\nexport type LoaderSignal<TYPE> = TYPE extends () => ValueOrPromise<infer VALIDATOR> ? AsyncComputedReadonlySignal<ValueOrPromise<VALIDATOR>> : AsyncComputedReadonlySignal<TYPE>;\n```",
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/types.ts",
"mdFile": "router.loadersignal.md"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/docs/src/routes/api/qwik-router/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1166,8 +1166,8 @@ export type Loader<RETURN> = {
export type LoaderSignal<TYPE> = TYPE extends () => ValueOrPromise<
infer VALIDATOR
>
? ReadonlySignal<ValueOrPromise<VALIDATOR>>
: ReadonlySignal<TYPE>;
? AsyncComputedReadonlySignal<ValueOrPromise<VALIDATOR>>
: AsyncComputedReadonlySignal<TYPE>;
```

[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/types.ts)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,15 @@ export interface ResolveSyncValue {
// (undocumented)
<T>(loader: Loader_2<T>): Awaited<T> extends () => any ? never : Awaited<T>;
// (undocumented)
<T>(action: Action<T>): Awaited<T> | undefined;
<O, I, B extends boolean>(action: Action<O, I, B>): O | undefined;
}

// @public (undocumented)
export interface ResolveValue {
// (undocumented)
<T>(loader: Loader_2<T>): Awaited<T> extends () => any ? never : Promise<T>;
// (undocumented)
<T>(action: Action<T>): Promise<T | undefined>;
<O, I, B extends boolean>(action: Action<O, I, B>): Promise<O | undefined>;
}

// @public (undocumented)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,13 +503,13 @@ export interface RequestEventLoader<PLATFORM = QwikRouterPlatform>
/** @public */
export interface ResolveValue {
<T>(loader: Loader<T>): Awaited<T> extends () => any ? never : Promise<T>;
<T>(action: Action<T>): Promise<T | undefined>;
<O, I, B extends boolean>(action: Action<O, I, B>): Promise<O | undefined>;
}

/** @public */
export interface ResolveSyncValue {
<T>(loader: Loader<T>): Awaited<T> extends () => any ? never : Awaited<T>;
<T>(action: Action<T>): Awaited<T> | undefined;
<O, I, B extends boolean>(action: Action<O, I, B>): O | undefined;
}

/** @public */
Expand Down
3 changes: 2 additions & 1 deletion packages/qwik-router/src/runtime/src/contexts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createContextId, type Signal } from '@qwik.dev/core';
import type {
ContentState,
ContentStateInternal,
LoaderSignal,
ResolvedDocumentHead,
RouteAction,
RouteLocation,
Expand All @@ -11,7 +12,7 @@ import type {
} from './types';

export const RouteStateContext =
/*#__PURE__*/ createContextId<Record<string, Signal<unknown>>>('qc-s');
/*#__PURE__*/ createContextId<Record<string, LoaderSignal<unknown>>>('qc-s');

export const ContentContext = /*#__PURE__*/ createContextId<ContentState>('qc-c');
export const ContentInternalContext =
Expand Down
2 changes: 1 addition & 1 deletion packages/qwik-router/src/runtime/src/head.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const resolveHead = (
throw new Error('Loaders returning a promise can not be resolved for the head function.');
}
return data;
}) as any as ResolveSyncValue;
}) as ResolveSyncValue;
const headProps: DocumentHeadProps = {
head,
withLocale: (fn) => withLocale(locale, fn),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
forceStoreEffects,
SerializerSymbol,
type _ElementVNode,
type AsyncComputedReadonlySignal,
type SerializationStrategy,
} from '@qwik.dev/core/internal';
import { clientNavigate } from './client-navigate';
Expand Down Expand Up @@ -61,6 +60,7 @@ import type {
Editable,
EndpointResponse,
LoadedRoute,
LoaderSignal,
MutableRouteLocation,
PageModule,
PreventNavigateCallback,
Expand Down Expand Up @@ -172,7 +172,7 @@ export const useQwikRouter = (props?: QwikRouterProps) => {

// This object contains the signals for the loaders
// It is used for the loaders context RouteStateContext
const loaderState: Record<string, AsyncComputedReadonlySignal<unknown>> = {};
const loaderState: Record<string, LoaderSignal<unknown>> = {};

for (const [key, value] of Object.entries(env.response.loaders)) {
loadersObject[key] = value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

```ts

import type { AsyncComputedReadonlySignal } from '@qwik.dev/core/internal';
import { Component } from '@qwik.dev/core';
import { Cookie } from '@qwik.dev/router/middleware/request-handler';
import { CookieOptions } from '@qwik.dev/router/middleware/request-handler';
Expand All @@ -15,7 +16,6 @@ import { QRL } from '@qwik.dev/core';
import { QRLEventHandlerMulti } from '@qwik.dev/core';
import { QwikIntrinsicElements } from '@qwik.dev/core';
import { QwikJSX } from '@qwik.dev/core';
import type { ReadonlySignal } from '@qwik.dev/core';
import { Render } from '@qwik.dev/core/server';
import { RenderOptions } from '@qwik.dev/core/server';
import { RequestEvent } from '@qwik.dev/router/middleware/request-handler';
Expand Down Expand Up @@ -263,7 +263,7 @@ type Loader_2<RETURN> = {
export { Loader_2 as Loader }

// @public (undocumented)
export type LoaderSignal<TYPE> = TYPE extends () => ValueOrPromise<infer VALIDATOR> ? ReadonlySignal<ValueOrPromise<VALIDATOR>> : ReadonlySignal<TYPE>;
export type LoaderSignal<TYPE> = TYPE extends () => ValueOrPromise<infer VALIDATOR> ? AsyncComputedReadonlySignal<ValueOrPromise<VALIDATOR>> : AsyncComputedReadonlySignal<TYPE>;

// Warning: (ae-forgotten-export) The symbol "MenuModuleLoader" needs to be exported by the entry point index.d.ts
//
Expand Down
7 changes: 3 additions & 4 deletions packages/qwik-router/src/runtime/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import type {
NoSerialize,
QRL,
QwikIntrinsicElements,
ReadonlySignal,
Signal,
ValueOrPromise,
} from '@qwik.dev/core';
import type { SerializationStrategy } from '@qwik.dev/core/internal';
import type { AsyncComputedReadonlySignal, SerializationStrategy } from '@qwik.dev/core/internal';
import type {
EnvGetter,
RequestEvent,
Expand Down Expand Up @@ -810,8 +809,8 @@ export type FailReturn<T> = T & Failed;

/** @public */
export type LoaderSignal<TYPE> = TYPE extends () => ValueOrPromise<infer VALIDATOR>
? ReadonlySignal<ValueOrPromise<VALIDATOR>>
: ReadonlySignal<TYPE>;
? AsyncComputedReadonlySignal<ValueOrPromise<VALIDATOR>>
: AsyncComputedReadonlySignal<TYPE>;

/** @public */
export type Loader<RETURN> = {
Expand Down
6 changes: 3 additions & 3 deletions packages/qwik-router/src/runtime/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SimpleURL } from './types';
import type { LoaderSignal, SimpleURL } from './types';

import { createAsyncComputed$, isBrowser } from '@qwik.dev/core';
import {
Expand Down Expand Up @@ -74,7 +74,7 @@ export const createLoaderSignal = (
serializationStrategy: SerializationStrategy,
manifestHash: string,
container?: ClientContainer
) => {
): LoaderSignal<unknown> => {
return createAsyncComputed$(
async () => {
if (isBrowser && loadersObject[loaderId] === _UNINITIALIZED) {
Expand All @@ -87,5 +87,5 @@ export const createLoaderSignal = (
container: container as ClientContainer,
serializationStrategy,
}
);
) as LoaderSignal<unknown>;
};