@qwik.dev/router 2.0.0-beta.35 → 2.0.0-beta.37
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.
- package/lib/adapters/cloudflare-pages/vite/index.mjs +2 -4
- package/lib/adapters/shared/vite/index.mjs +26 -23
- package/lib/chunks/action-handler.mjs +782 -0
- package/lib/chunks/deepFreeze.qwik.mjs +591 -1
- package/lib/chunks/format.mjs +31 -0
- package/lib/chunks/fs.mjs +4 -6
- package/lib/chunks/{routing.qwik.mjs → head.qwik.mjs} +299 -416
- package/lib/chunks/http-error.qwik.mjs +2 -2
- package/lib/chunks/not-found-wrapper.qwik.mjs +2 -2
- package/lib/chunks/pathname.mjs +3 -32
- package/lib/chunks/request-path.mjs +60 -0
- package/lib/chunks/system.mjs +6 -7
- package/lib/chunks/use-functions.qwik.mjs +3 -15
- package/lib/chunks/worker-thread.qwik.mjs +436 -425
- package/lib/index.d.ts +180 -13
- package/lib/index.qwik.mjs +640 -447
- package/lib/middleware/aws-lambda/index.mjs +2 -1
- package/lib/middleware/request-handler/index.d.ts +56 -16
- package/lib/middleware/request-handler/index.mjs +198 -754
- package/lib/ssg/index.d.ts +3 -3
- package/lib/ssg/index.mjs +4 -3
- package/lib/vite/index.d.ts +15 -0
- package/lib/vite/index.mjs +145 -23
- package/package.json +3 -3
- package/lib/chunks/redirect-handler.mjs +0 -6
package/lib/index.d.ts
CHANGED
|
@@ -7,13 +7,15 @@ import { CookieOptions } from '@qwik.dev/router/middleware/request-handler';
|
|
|
7
7
|
import { CookieValue } from '@qwik.dev/router/middleware/request-handler';
|
|
8
8
|
import { DeferReturn } from '@qwik.dev/router/middleware/request-handler';
|
|
9
9
|
import type { EnvGetter } from '@qwik.dev/router/middleware/request-handler';
|
|
10
|
+
import { InternalRequest } from '@qwik.dev/router/middleware/request-handler';
|
|
10
11
|
import { JSXOutput } from '@qwik.dev/core';
|
|
12
|
+
import { NoSerialize } from '@qwik.dev/core';
|
|
11
13
|
import { QRL } from '@qwik.dev/core';
|
|
12
14
|
import { QRLEventHandlerMulti } from '@qwik.dev/core';
|
|
13
15
|
import { QwikIntrinsicElements } from '@qwik.dev/core';
|
|
14
16
|
import { QwikJSX } from '@qwik.dev/core';
|
|
15
17
|
import { Render } from '@qwik.dev/core/server';
|
|
16
|
-
import {
|
|
18
|
+
import { RenderToStreamOptions } from '@qwik.dev/core/server';
|
|
17
19
|
import { RequestEvent } from '@qwik.dev/router/middleware/request-handler';
|
|
18
20
|
import { RequestEventAction } from '@qwik.dev/router/middleware/request-handler';
|
|
19
21
|
import { RequestEventBase } from '@qwik.dev/router/middleware/request-handler';
|
|
@@ -162,15 +164,25 @@ export declare type ActionStore<RETURN, INPUT, OPTIONAL extends boolean = true>
|
|
|
162
164
|
declare type AnchorAttributes = QwikIntrinsicElements['a'];
|
|
163
165
|
|
|
164
166
|
/**
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
+
* Cache key function. Used by `routeConfig.cacheKey` (SSR HTML cache) and by `routeLoader$`'s
|
|
168
|
+
* `cacheKey` option (per-loader JSON cache).
|
|
167
169
|
*
|
|
168
|
-
* - `true`: use the default
|
|
169
|
-
*
|
|
170
|
+
* - `true`: use the surface's default key.
|
|
171
|
+
*
|
|
172
|
+
* - SSR default: `${status}|${eTag}|${pathname}` when an eTag is set, otherwise
|
|
173
|
+
* `${status}|${pathname}`.
|
|
174
|
+
* - Loader default: `${pathname}|${filteredSearch}|${loaderId}|${eTag}` when an eTag is set,
|
|
175
|
+
* otherwise `${pathname}|${filteredSearch}|${loaderId}`.
|
|
176
|
+
* - Function: receives the request event and the normalized, unquoted eTag (or an empty string when
|
|
177
|
+
* none was provided). Return the cache key string, or `null` or `''` to skip caching for this
|
|
178
|
+
* request. Loader callbacks receive the loader-scoped request event, with `url`, `query`, and
|
|
179
|
+
* `request.url` filtered by the loader's `search` allowlist.
|
|
180
|
+
*
|
|
181
|
+
* Note: valid cacheKeys are non-empty strings.
|
|
170
182
|
*
|
|
171
183
|
* @public
|
|
172
184
|
*/
|
|
173
|
-
export declare type CacheKeyFn = true | ((
|
|
185
|
+
export declare type CacheKeyFn = true | ((requestEv: RequestEvent, eTag: string) => string | null);
|
|
174
186
|
|
|
175
187
|
/** @public */
|
|
176
188
|
export declare interface ContentHeading {
|
|
@@ -189,7 +201,18 @@ export declare interface ContentMenu {
|
|
|
189
201
|
declare type ContentModule = PageModule | LayoutModule;
|
|
190
202
|
|
|
191
203
|
/**
|
|
192
|
-
* The eTag export type
|
|
204
|
+
* The eTag export type for routeConfig.
|
|
205
|
+
*
|
|
206
|
+
* - `string` — static ETag value.
|
|
207
|
+
* - `(props: DocumentHeadProps) => string | null` — compute the ETag from route context (params, URL,
|
|
208
|
+
* loaded data via `resolveValue`, etc.). Return `null` to skip eTag for this request.
|
|
209
|
+
*
|
|
210
|
+
* Qwik normalizes eTag values by stripping weak-form `W/` prefixes, quotes, and forbidden chars,
|
|
211
|
+
* then sends a strong `ETag` header. Values that normalize to an empty string are treated as
|
|
212
|
+
* absent.
|
|
213
|
+
*
|
|
214
|
+
* When set (and a value is produced), the server includes an `ETag` header and returns `304` if
|
|
215
|
+
* `If-None-Match` matches.
|
|
193
216
|
*
|
|
194
217
|
* @public
|
|
195
218
|
*/
|
|
@@ -357,10 +380,10 @@ declare type EndpointModuleLoader = () => ValueOrPromise<RouteModule>;
|
|
|
357
380
|
declare interface EndpointResponse {
|
|
358
381
|
status: number;
|
|
359
382
|
statusMessage?: string;
|
|
360
|
-
loaders: Record<string, unknown>;
|
|
361
|
-
loadersSerializationStrategy: Map<string, SerializationStrategy>;
|
|
362
383
|
formData?: FormData;
|
|
363
384
|
action?: string;
|
|
385
|
+
actionResult?: unknown;
|
|
386
|
+
loaderHashes?: string[];
|
|
364
387
|
}
|
|
365
388
|
|
|
366
389
|
/** @public */
|
|
@@ -433,6 +456,8 @@ export declare type HttpErrorProps = {
|
|
|
433
456
|
message: string;
|
|
434
457
|
};
|
|
435
458
|
|
|
459
|
+
export { InternalRequest }
|
|
460
|
+
|
|
436
461
|
declare type IsAny<Type> = 0 extends 1 & Type ? true : false;
|
|
437
462
|
|
|
438
463
|
/** @public */
|
|
@@ -511,6 +536,10 @@ declare interface LoadedRoute {
|
|
|
511
536
|
$notFound$?: boolean;
|
|
512
537
|
/** The error module loader (nearest _E ancestor), for rendering ServerErrors */
|
|
513
538
|
$errorLoader$?: ContentModuleLoader;
|
|
539
|
+
/** Merged array of routeLoader$ hashes from all matched nodes (layouts + page) */
|
|
540
|
+
$loaders$?: string[];
|
|
541
|
+
/** Runtime-only mapping of routeLoader$ hashes to the matched pathname used for q-loader fetches */
|
|
542
|
+
$loaderPaths$?: Record<string, string>;
|
|
514
543
|
}
|
|
515
544
|
|
|
516
545
|
/** @public */
|
|
@@ -537,9 +566,79 @@ declare type LoaderConstructorQRL = {
|
|
|
537
566
|
|
|
538
567
|
/** @public */
|
|
539
568
|
declare type LoaderOptions = {
|
|
569
|
+
/** @deprecated Unused */
|
|
540
570
|
readonly id?: string;
|
|
541
571
|
readonly validation?: DataValidator[];
|
|
542
572
|
readonly serializationStrategy?: SerializationStrategy;
|
|
573
|
+
/**
|
|
574
|
+
* Time in milliseconds after which the loader data is considered stale. The server derives
|
|
575
|
+
* `Cache-Control: max-age` seconds from this value on loader responses.
|
|
576
|
+
*
|
|
577
|
+
* On the client, the loader's AsyncSignal `expires` is set to this value. If `poll` is true, the
|
|
578
|
+
* signal auto-refetches when expired. If `poll` is false (default), the data is marked stale but
|
|
579
|
+
* not auto-refetched.
|
|
580
|
+
*/
|
|
581
|
+
readonly expires?: number;
|
|
582
|
+
/**
|
|
583
|
+
* When true AND `expires` is set, the loader data is automatically refetched when it expires
|
|
584
|
+
* (polling behavior). When false (default), expired data is marked stale but not auto-refetched.
|
|
585
|
+
*/
|
|
586
|
+
readonly poll?: boolean;
|
|
587
|
+
/**
|
|
588
|
+
* Enable ETag-based caching for this loader's JSON responses.
|
|
589
|
+
*
|
|
590
|
+
* - `string` — static ETag value; if `If-None-Match` matches, the loader is skipped entirely
|
|
591
|
+
* - `(ev: RequestEvent) => string | null` — compute the ETag from the request context (params, URL,
|
|
592
|
+
* headers, etc.); if `If-None-Match` matches, the loader is skipped entirely. Return null to
|
|
593
|
+
* skip eTag for this request.
|
|
594
|
+
*
|
|
595
|
+
* Qwik normalizes eTag values by stripping weak-form `W/` prefixes, quotes, and forbidden chars,
|
|
596
|
+
* then sends a strong `ETag` header. Values that normalize to an empty string are treated as
|
|
597
|
+
* absent.
|
|
598
|
+
*
|
|
599
|
+
* When set, the server includes an `ETag` header on `q-loader-*.json` responses and returns `304`
|
|
600
|
+
* if the client sends a matching `If-None-Match` header.
|
|
601
|
+
*
|
|
602
|
+
* For auto-computed eTags, use `cacheKey` instead — on cache write the eTag is hashed from the
|
|
603
|
+
* serialized response and stored alongside it, so subsequent hits get the same eTag.
|
|
604
|
+
*/
|
|
605
|
+
readonly eTag?: string | ((ev: RequestEvent) => string | null);
|
|
606
|
+
/**
|
|
607
|
+
* Enable in-memory server-side caching of this loader's serialized JSON response.
|
|
608
|
+
*
|
|
609
|
+
* - `true` — use the default key `${pathname}|${filteredSearch}|${loaderId}` (suffixed with
|
|
610
|
+
* `|${eTag}` when an eTag is set).
|
|
611
|
+
* - Function `(requestEv, eTag) => string | null` — return a custom key, or `null` to skip caching
|
|
612
|
+
* this request.
|
|
613
|
+
*
|
|
614
|
+
* On cache miss the loader runs, the serialized response is stored alongside its eTag (computed
|
|
615
|
+
* from the data when no `eTag` option is set), and the response is sent. On cache hit the stored
|
|
616
|
+
* `{ eTag, data }` pair is served directly — `If-None-Match` is checked against the stored eTag
|
|
617
|
+
* and a `304` is returned when it matches.
|
|
618
|
+
*/
|
|
619
|
+
readonly cacheKey?: CacheKeyFn;
|
|
620
|
+
/**
|
|
621
|
+
* Allowlist of URL search parameter names that this loader depends on.
|
|
622
|
+
*
|
|
623
|
+
* When set, the loader only re-fetches when the listed search params change — other param changes
|
|
624
|
+
* are ignored. Only the listed params are sent in the loader JSON request URL. During SSR and
|
|
625
|
+
* loader JSON requests, the loader receives a request event with `url`, `query`, and
|
|
626
|
+
* `request.url` filtered to the same params.
|
|
627
|
+
*
|
|
628
|
+
* When not set, the `qwikRouter()` plugin option `strictLoaders` determines the behavior. If
|
|
629
|
+
* `strictLoaders` is `true` (this is the default), no search params are sent and changes do not
|
|
630
|
+
* trigger a re-fetch. If `strictLoaders` is `false`, all search params are sent and any change
|
|
631
|
+
* triggers a re-fetch.
|
|
632
|
+
*/
|
|
633
|
+
readonly search?: string[];
|
|
634
|
+
/**
|
|
635
|
+
* When true (default), the previous value is kept while the loader re-fetches after navigation,
|
|
636
|
+
* so components see stale data until the new response arrives.
|
|
637
|
+
*
|
|
638
|
+
* When false, the value is cleared on re-fetch, causing reads to suspend (show a loading
|
|
639
|
+
* boundary). This is useful when showing old data during navigation would be confusing.
|
|
640
|
+
*/
|
|
641
|
+
readonly allowStale?: boolean;
|
|
543
642
|
};
|
|
544
643
|
|
|
545
644
|
/** @public */
|
|
@@ -673,6 +772,8 @@ export declare interface QwikRouterEnvData {
|
|
|
673
772
|
params: PathParams;
|
|
674
773
|
response: EndpointResponse;
|
|
675
774
|
loadedRoute: LoadedRoute;
|
|
775
|
+
routeLoaderCtx: RouteLoaderCtx;
|
|
776
|
+
loaderValues: Record<string, unknown>;
|
|
676
777
|
}
|
|
677
778
|
|
|
678
779
|
/** @public */
|
|
@@ -754,12 +855,12 @@ export declare interface QwikRouterProps {
|
|
|
754
855
|
export declare const QwikRouterProvider: Component<QwikRouterProps>;
|
|
755
856
|
|
|
756
857
|
/** @public */
|
|
757
|
-
export declare type RendererOptions = Omit<
|
|
858
|
+
export declare type RendererOptions = Omit<RenderToStreamOptions, 'serverData'> & {
|
|
758
859
|
serverData: ServerData;
|
|
759
860
|
};
|
|
760
861
|
|
|
761
862
|
/** @public */
|
|
762
|
-
export declare type RendererOutputOptions = Omit<
|
|
863
|
+
export declare type RendererOutputOptions = Omit<RenderToStreamOptions, 'serverData'> & {
|
|
763
864
|
serverData: ServerData & {
|
|
764
865
|
documentHead?: DocumentHeadValue;
|
|
765
866
|
} & Record<string, unknown>;
|
|
@@ -783,7 +884,26 @@ export declare type ResolvedDocumentHead<FrontMatter extends Record<string, any>
|
|
|
783
884
|
readonly manifestHash: string;
|
|
784
885
|
};
|
|
785
886
|
|
|
786
|
-
/**
|
|
887
|
+
/**
|
|
888
|
+
* Define a route action that handles form submissions or programmatic invocations.
|
|
889
|
+
*
|
|
890
|
+
* Actions run on the server when submitted from the client. The result is returned as an
|
|
891
|
+
* `ActionStore` with `.value` for success data and `.error` for errors (including validation errors
|
|
892
|
+
* from `zod$`/`valibot$` where `.fieldErrors` etc. are accessible directly on `.error`).
|
|
893
|
+
*
|
|
894
|
+
* By default, after an action completes, ALL current route loaders are invalidated on the client
|
|
895
|
+
* and re-fetched as needed (so that the browser cache is correct). This can be controlled with:
|
|
896
|
+
*
|
|
897
|
+
* - `invalidate: [loader1, loader2]`: Only invalidate specific loaders. The client re-fetches them
|
|
898
|
+
* individually. Other loaders keep their current data.
|
|
899
|
+
* - `invalidate: []`: No loaders are invalidated. The action response only contains the action
|
|
900
|
+
* result. Use this when the action doesn't affect any loader data.
|
|
901
|
+
*
|
|
902
|
+
* The `strictLoaders` Vite plugin option applies `invalidate: []` globally for all actions that
|
|
903
|
+
* don't specify an explicit `invalidate` option.
|
|
904
|
+
*
|
|
905
|
+
* @public
|
|
906
|
+
*/
|
|
787
907
|
export declare const routeAction$: ActionConstructor;
|
|
788
908
|
|
|
789
909
|
/* Excluded from this release type: routeActionQrl */
|
|
@@ -857,13 +977,59 @@ export declare interface RouteData {
|
|
|
857
977
|
_M?: RouteData[];
|
|
858
978
|
/** Menu loader for this subtree (from menu.md). Runtime uses nearest ancestor during traversal. */
|
|
859
979
|
_N?: MenuModuleLoader;
|
|
980
|
+
/** Array of routeLoader$ hashes for this node's loaders */
|
|
981
|
+
_R?: string[];
|
|
860
982
|
/** Child route segments (any key not starting with `_`) */
|
|
861
983
|
[part: string]: RouteData | RouteData[] | ModuleLoader[] | ContentModuleLoader | MenuModuleLoader | string[] | string | undefined;
|
|
862
984
|
}
|
|
863
985
|
|
|
864
|
-
/**
|
|
986
|
+
/**
|
|
987
|
+
* Define a route loader that fetches data before the route renders.
|
|
988
|
+
*
|
|
989
|
+
* Route loaders run on the server during SSR and return data as an `AsyncSignal`. On the client,
|
|
990
|
+
* loaders automatically re-fetch when the route changes (SPA navigation). Each loader gets its own
|
|
991
|
+
* JSON endpoint (`q-loader-{id}.{hash}.json`), so only the loaders present on the target route are
|
|
992
|
+
* fetched.
|
|
993
|
+
*
|
|
994
|
+
* **Important:** Route loader data uses Qwik's custom serialization format, not standard JSON. This
|
|
995
|
+
* means the data supports features like circular references, Dates, and other non-JSON types, but
|
|
996
|
+
* it cannot be consumed by external clients expecting plain JSON.
|
|
997
|
+
*
|
|
998
|
+
* ## Options
|
|
999
|
+
*
|
|
1000
|
+
* - `search: string[]`: Allowlist of URL search params the loader depends on. Only listed params are
|
|
1001
|
+
* sent in the request and changes to other params are ignored. During SSR and loader JSON
|
|
1002
|
+
* requests, the loader's request event is filtered to those params too. `search: []` means no
|
|
1003
|
+
* search params are sent and only route path changes trigger a re-fetch.
|
|
1004
|
+
* - `allowStale: false`: Clears the previous value when re-fetching, so components see a loading
|
|
1005
|
+
* state instead of stale data during navigation. Useful when old data would be confusing.
|
|
1006
|
+
* - `eTag`: Enable ETag-based caching. Can be `true` (auto-hash), a string, or a function.
|
|
1007
|
+
* - `expires` / `poll`: Control client-side caching and polling behavior.
|
|
1008
|
+
*
|
|
1009
|
+
* The `strictLoaders` Vite plugin option applies `search: []` globally for all loaders that don't
|
|
1010
|
+
* specify an explicit `search` option.
|
|
1011
|
+
*
|
|
1012
|
+
* @public
|
|
1013
|
+
*/
|
|
865
1014
|
export declare const routeLoader$: LoaderConstructor;
|
|
866
1015
|
|
|
1016
|
+
/**
|
|
1017
|
+
* Reactive context for route loaders. On the server this is stored in sharedMap, on the client it's
|
|
1018
|
+
* a store that gets updated on navigation.
|
|
1019
|
+
*
|
|
1020
|
+
* - `loaderPaths`: loader ID → fetch path (the longest route path for that loader)
|
|
1021
|
+
* - `pagePathname` / `pageSearch`: client-only navigation state used for loader invalidation and
|
|
1022
|
+
* q-loader fetches. They are intentionally omitted from SSR state and fall back to `location`
|
|
1023
|
+
* until the first SPA navigation.
|
|
1024
|
+
*/
|
|
1025
|
+
declare type RouteLoaderCtx = {
|
|
1026
|
+
loaderPaths: Record<string, string | undefined>;
|
|
1027
|
+
pagePathname?: string;
|
|
1028
|
+
pageSearch?: string;
|
|
1029
|
+
/** SPA navigation function. Client-only and intentionally omitted from SSR state. */
|
|
1030
|
+
goto?: NoSerialize<RouteNavigate>;
|
|
1031
|
+
};
|
|
1032
|
+
|
|
867
1033
|
/* Excluded from this release type: routeLoaderQrl */
|
|
868
1034
|
|
|
869
1035
|
/** @public */
|
|
@@ -911,6 +1077,7 @@ declare interface ServerConfig {
|
|
|
911
1077
|
export declare type ServerData = {
|
|
912
1078
|
url: string;
|
|
913
1079
|
requestHeaders: Record<string, string>;
|
|
1080
|
+
renderMode: 'static' | 'server';
|
|
914
1081
|
locale: string | undefined;
|
|
915
1082
|
nonce: string | undefined;
|
|
916
1083
|
containerAttributes: Record<string, string> & {
|