@qwik.dev/router 2.0.0-beta.37 → 2.0.0-beta.39
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 -2
- package/lib/adapters/shared/vite/index.d.ts +3 -4
- package/lib/adapters/shared/vite/index.mjs +158 -143
- package/lib/chunks/dev-preloaded-route-loader.mjs +3 -0
- package/lib/chunks/fs.mjs +6 -2
- package/lib/chunks/head.qwik.mjs +814 -93
- package/lib/chunks/request-body-limit.mjs +37 -0
- package/lib/chunks/request-path.mjs +2 -2
- package/lib/chunks/routes.mjs +47 -0
- package/lib/chunks/server-error.mjs +19 -0
- package/lib/chunks/system.mjs +2 -1
- package/lib/chunks/use-functions.qwik.mjs +1 -1
- package/lib/chunks/{worker-thread.qwik.mjs → user-response.mjs} +1053 -1749
- package/lib/chunks/worker-thread.mjs +317 -0
- package/lib/index.d.ts +89 -55
- package/lib/index.qwik.mjs +178 -100
- package/lib/middleware/azure-swa/index.mjs +13 -9
- package/lib/middleware/cloudflare-pages/index.mjs +2 -2
- package/lib/middleware/deno/index.d.ts +2 -0
- package/lib/middleware/deno/index.mjs +2 -1
- package/lib/middleware/netlify-edge/index.mjs +2 -2
- package/lib/middleware/node/index.d.ts +9 -1
- package/lib/middleware/node/index.mjs +28 -3
- package/lib/middleware/request-handler/index.d.ts +9 -10
- package/lib/middleware/request-handler/index.mjs +26 -1105
- package/lib/middleware/vercel-edge/index.mjs +2 -2
- package/lib/ssg/index.d.ts +2 -10
- package/lib/ssg/index.mjs +10 -50
- package/lib/vite/index.d.ts +8 -0
- package/lib/vite/index.mjs +406 -117
- package/package.json +5 -4
- package/lib/chunks/action-handler.mjs +0 -782
- package/lib/chunks/deepFreeze.qwik.mjs +0 -608
- package/lib/chunks/error-handler.mjs +0 -57
- package/lib/chunks/not-found-wrapper.qwik.mjs +0 -25
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { _serialize } from '@qwik.dev/core/internal';
|
|
2
|
+
import { parentPort } from 'node:worker_threads';
|
|
3
|
+
import { r as runQwikRouter, a as resolveRequestHandlers, b as renderQwikMiddleware } from './user-response.mjs';
|
|
4
|
+
import { b as trimInternalPathname } from './request-path.mjs';
|
|
5
|
+
import { I as getRouteLoaders, J as getRouteLoaderValues, l as loadRoute } from './head.qwik.mjs';
|
|
6
|
+
|
|
7
|
+
const staticWorkerThreadDeps = {
|
|
8
|
+
loadRoute,
|
|
9
|
+
renderQwikMiddleware,
|
|
10
|
+
resolveRequestHandlers,
|
|
11
|
+
trimInternalPathname,
|
|
12
|
+
runQwikRouter
|
|
13
|
+
};
|
|
14
|
+
const createNoopWritableStream = () => new WritableStream();
|
|
15
|
+
function isRedirectMessage(value) {
|
|
16
|
+
return typeof value === "object" && value !== null && value.constructor?.name === "RedirectMessage";
|
|
17
|
+
}
|
|
18
|
+
async function requestHandlerForSsg(serverRequestEv, opts, deps) {
|
|
19
|
+
const { render, checkOrigin, qwikRouterConfig } = opts;
|
|
20
|
+
if (!qwikRouterConfig) {
|
|
21
|
+
throw new Error("qwikRouterConfig is required.");
|
|
22
|
+
}
|
|
23
|
+
const pathname = deps.trimInternalPathname(serverRequestEv.url.pathname);
|
|
24
|
+
if (pathname === "/.well-known" || pathname.startsWith("/.well-known/")) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const { routes, serverPlugins, cacheModules } = qwikRouterConfig;
|
|
28
|
+
const loadedRoute = await deps.loadRoute(routes, cacheModules, pathname);
|
|
29
|
+
const requestHandlers = deps.resolveRequestHandlers(serverPlugins, loadedRoute, serverRequestEv.request.method, checkOrigin ?? true, deps.renderQwikMiddleware(render));
|
|
30
|
+
if (qwikRouterConfig.fallthrough && loadedRoute.$notFound$ && !pathname.endsWith("/404.html")) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const rebuildRouteInfo = async (url) => {
|
|
34
|
+
const cleanPathname = deps.trimInternalPathname(url.pathname);
|
|
35
|
+
const loadedRoute2 = await deps.loadRoute(routes, cacheModules, cleanPathname);
|
|
36
|
+
const requestHandlers2 = deps.resolveRequestHandlers(serverPlugins, loadedRoute2, serverRequestEv.request.method, checkOrigin ?? true, deps.renderQwikMiddleware(render));
|
|
37
|
+
return {
|
|
38
|
+
loadedRoute: loadedRoute2,
|
|
39
|
+
requestHandlers: requestHandlers2
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
return deps.runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, qwikRouterConfig.basePathname);
|
|
43
|
+
}
|
|
44
|
+
async function workerRender(sys, opts, staticRoute, pendingPromises, callback, deps) {
|
|
45
|
+
const url = new URL(staticRoute.pathname, opts.origin);
|
|
46
|
+
const result = {
|
|
47
|
+
type: "render",
|
|
48
|
+
pathname: staticRoute.pathname,
|
|
49
|
+
url: url.href,
|
|
50
|
+
ok: false,
|
|
51
|
+
error: null,
|
|
52
|
+
filePath: null,
|
|
53
|
+
contentType: null,
|
|
54
|
+
resourceType: null
|
|
55
|
+
};
|
|
56
|
+
try {
|
|
57
|
+
let routeWriter = null;
|
|
58
|
+
let closeResolved;
|
|
59
|
+
const closePromise = new Promise((closePromiseResolve) => {
|
|
60
|
+
closeResolved = closePromiseResolve;
|
|
61
|
+
});
|
|
62
|
+
const request = new Request(url);
|
|
63
|
+
const requestCtx = {
|
|
64
|
+
mode: "static",
|
|
65
|
+
locale: void 0,
|
|
66
|
+
url,
|
|
67
|
+
request,
|
|
68
|
+
env: {
|
|
69
|
+
get(key) {
|
|
70
|
+
return sys.getEnv(key);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
platform: sys.platform,
|
|
74
|
+
getClientConn: () => {
|
|
75
|
+
return {};
|
|
76
|
+
},
|
|
77
|
+
getWritableStream: (status, headers, _, _r, requestEv) => {
|
|
78
|
+
const isNotFoundPage = url.pathname.endsWith("/404.html");
|
|
79
|
+
result.ok = status >= 200 && status < 300 || isNotFoundPage && status === 404;
|
|
80
|
+
if (!result.ok) {
|
|
81
|
+
return createNoopWritableStream();
|
|
82
|
+
}
|
|
83
|
+
result.contentType = (headers.get("Content-Type") || "").toLowerCase();
|
|
84
|
+
const isHtml = result.contentType.includes("text/html");
|
|
85
|
+
const routeFilePath = sys.getRouteFilePath(url.pathname, isHtml);
|
|
86
|
+
if (isHtml) {
|
|
87
|
+
result.resourceType = "page";
|
|
88
|
+
}
|
|
89
|
+
const hasRouteWriter = isHtml ? opts.emitHtml !== false : true;
|
|
90
|
+
const writeLoaderDataEnabled = isHtml && opts.emitData !== false;
|
|
91
|
+
const stream = new WritableStream({
|
|
92
|
+
async start() {
|
|
93
|
+
try {
|
|
94
|
+
if (hasRouteWriter || writeLoaderDataEnabled) {
|
|
95
|
+
await sys.ensureDir(routeFilePath);
|
|
96
|
+
}
|
|
97
|
+
if (hasRouteWriter) {
|
|
98
|
+
routeWriter = sys.createWriteStream(routeFilePath);
|
|
99
|
+
routeWriter.on("error", (e) => {
|
|
100
|
+
console.error(e);
|
|
101
|
+
routeWriter = null;
|
|
102
|
+
result.error = {
|
|
103
|
+
message: e.message,
|
|
104
|
+
stack: e.stack
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
} catch (e) {
|
|
109
|
+
console.error("Error during stream start", staticRoute.pathname, e);
|
|
110
|
+
routeWriter = null;
|
|
111
|
+
result.error = {
|
|
112
|
+
message: String(e),
|
|
113
|
+
stack: e.stack || ""
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
write(chunk) {
|
|
118
|
+
try {
|
|
119
|
+
if (routeWriter) {
|
|
120
|
+
routeWriter.write(Buffer.from(chunk.buffer));
|
|
121
|
+
}
|
|
122
|
+
} catch (e) {
|
|
123
|
+
console.error("Error during stream write", staticRoute.pathname, e);
|
|
124
|
+
routeWriter = null;
|
|
125
|
+
result.error = {
|
|
126
|
+
message: String(e),
|
|
127
|
+
stack: e.stack || ""
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
async close() {
|
|
132
|
+
const writePromises = [];
|
|
133
|
+
try {
|
|
134
|
+
if (writeLoaderDataEnabled && !isNotFoundPage) {
|
|
135
|
+
const routeLoaders = getRouteLoaders(requestEv);
|
|
136
|
+
const loaderValues = getRouteLoaderValues(requestEv);
|
|
137
|
+
const manifestHash = opts.manifest?.manifestHash || "dev";
|
|
138
|
+
for (const loader of routeLoaders) {
|
|
139
|
+
if (loader.__cacheControl !== "immutable") {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const data = loaderValues[loader.__id];
|
|
143
|
+
if (data === void 0) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
const loaderFilePath = sys.getLoaderFilePath(url.pathname, loader.__id, manifestHash);
|
|
147
|
+
const loaderWriter = sys.createWriteStream(loaderFilePath);
|
|
148
|
+
loaderWriter.on("error", (e) => {
|
|
149
|
+
console.error(e);
|
|
150
|
+
result.error = {
|
|
151
|
+
message: e.message,
|
|
152
|
+
stack: e.stack
|
|
153
|
+
};
|
|
154
|
+
});
|
|
155
|
+
const serialized = await deps.serialize({
|
|
156
|
+
d: data
|
|
157
|
+
});
|
|
158
|
+
loaderWriter.write(serialized);
|
|
159
|
+
writePromises.push(new Promise((resolve) => {
|
|
160
|
+
result.filePath = routeFilePath;
|
|
161
|
+
loaderWriter.end(resolve);
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (routeWriter) {
|
|
166
|
+
writePromises.push(new Promise((resolve) => {
|
|
167
|
+
result.filePath = routeFilePath;
|
|
168
|
+
routeWriter.end(resolve);
|
|
169
|
+
}).finally(closeResolved));
|
|
170
|
+
}
|
|
171
|
+
if (writePromises.length > 0) {
|
|
172
|
+
await Promise.all(writePromises);
|
|
173
|
+
}
|
|
174
|
+
} catch (e) {
|
|
175
|
+
console.error("Error during stream close", staticRoute.pathname, e);
|
|
176
|
+
routeWriter = null;
|
|
177
|
+
result.error = {
|
|
178
|
+
message: String(e),
|
|
179
|
+
stack: e.stack || ""
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
return stream;
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const promise = requestHandlerForSsg(requestCtx, opts, deps).then((rsp) => {
|
|
188
|
+
if (rsp != null) {
|
|
189
|
+
return rsp.completion.then((r) => {
|
|
190
|
+
if (routeWriter) {
|
|
191
|
+
return closePromise.then(() => r);
|
|
192
|
+
}
|
|
193
|
+
return r;
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}).then((e) => {
|
|
197
|
+
if (e !== void 0) {
|
|
198
|
+
if (isRedirectMessage(e)) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (e instanceof Error) {
|
|
202
|
+
result.error = {
|
|
203
|
+
message: e.message,
|
|
204
|
+
stack: e.stack
|
|
205
|
+
};
|
|
206
|
+
} else {
|
|
207
|
+
result.error = {
|
|
208
|
+
message: String(e),
|
|
209
|
+
stack: void 0
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
console.error("Error during request handling", staticRoute.pathname, e);
|
|
213
|
+
}
|
|
214
|
+
}).catch((e) => {
|
|
215
|
+
console.error("Unhandled error during request handling", staticRoute.pathname, e);
|
|
216
|
+
result.error = {
|
|
217
|
+
message: String(e),
|
|
218
|
+
stack: e.stack || ""
|
|
219
|
+
};
|
|
220
|
+
}).finally(() => {
|
|
221
|
+
pendingPromises.delete(promise);
|
|
222
|
+
callback(result);
|
|
223
|
+
});
|
|
224
|
+
pendingPromises.add(promise);
|
|
225
|
+
} catch (e) {
|
|
226
|
+
console.error("Error during render", staticRoute.pathname, e);
|
|
227
|
+
if (e instanceof Error) {
|
|
228
|
+
result.error = {
|
|
229
|
+
message: e.message,
|
|
230
|
+
stack: e.stack
|
|
231
|
+
};
|
|
232
|
+
} else {
|
|
233
|
+
result.error = {
|
|
234
|
+
message: String(e),
|
|
235
|
+
stack: void 0
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
callback(result);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
async function workerThread(sys) {
|
|
242
|
+
const opts = sys.getOptions();
|
|
243
|
+
const pendingPromises = /* @__PURE__ */ new Set();
|
|
244
|
+
const deps = {
|
|
245
|
+
...staticWorkerThreadDeps,
|
|
246
|
+
serialize: _serialize
|
|
247
|
+
};
|
|
248
|
+
process.on("uncaughtException", (e) => {
|
|
249
|
+
console.error("Worker uncaught exception (suppressed):", e.message);
|
|
250
|
+
});
|
|
251
|
+
process.on("unhandledRejection", (e) => {
|
|
252
|
+
console.error("Worker unhandled rejection (suppressed):", e instanceof Error ? e.message : e);
|
|
253
|
+
});
|
|
254
|
+
const onMessage = async (msg) => {
|
|
255
|
+
switch (msg.type) {
|
|
256
|
+
case "render": {
|
|
257
|
+
return new Promise((resolve) => {
|
|
258
|
+
workerRender(sys, opts, msg, pendingPromises, resolve, deps).catch((e) => {
|
|
259
|
+
console.error("Error during render", msg.pathname, e);
|
|
260
|
+
resolve({
|
|
261
|
+
type: "render",
|
|
262
|
+
pathname: msg.pathname,
|
|
263
|
+
url: "",
|
|
264
|
+
ok: false,
|
|
265
|
+
error: {
|
|
266
|
+
message: e instanceof Error ? e.message : String(e),
|
|
267
|
+
stack: e instanceof Error ? e.stack : void 0
|
|
268
|
+
},
|
|
269
|
+
filePath: null,
|
|
270
|
+
contentType: null,
|
|
271
|
+
resourceType: null
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
case "close": {
|
|
277
|
+
if (pendingPromises.size) {
|
|
278
|
+
const promises = Array.from(pendingPromises);
|
|
279
|
+
pendingPromises.clear();
|
|
280
|
+
await Promise.all(promises);
|
|
281
|
+
}
|
|
282
|
+
return {
|
|
283
|
+
type: "close"
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
parentPort?.on("message", async (msg) => {
|
|
289
|
+
try {
|
|
290
|
+
parentPort?.postMessage(await onMessage(msg));
|
|
291
|
+
} catch (e) {
|
|
292
|
+
if (msg.type === "render") {
|
|
293
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
294
|
+
parentPort?.postMessage({
|
|
295
|
+
type: "render",
|
|
296
|
+
pathname: msg.pathname,
|
|
297
|
+
url: "",
|
|
298
|
+
ok: false,
|
|
299
|
+
error: {
|
|
300
|
+
message: error.message,
|
|
301
|
+
stack: error.stack
|
|
302
|
+
},
|
|
303
|
+
filePath: null,
|
|
304
|
+
contentType: null,
|
|
305
|
+
resourceType: null
|
|
306
|
+
});
|
|
307
|
+
} else {
|
|
308
|
+
console.error("Worker message handler error", e);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (msg.type === "close") {
|
|
312
|
+
parentPort?.close();
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export { workerThread };
|
package/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/// <reference path="./modules.d.ts" />
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { AbortMessage } from '@qwik.dev/router/middleware/request-handler';
|
|
4
|
+
import type { CacheControl } from '@qwik.dev/router/middleware/request-handler';
|
|
4
5
|
import { Component } from '@qwik.dev/core';
|
|
6
|
+
import type { ComputedSignal } from '@qwik.dev/core';
|
|
5
7
|
import { Cookie } from '@qwik.dev/router/middleware/request-handler';
|
|
6
8
|
import { CookieOptions } from '@qwik.dev/router/middleware/request-handler';
|
|
7
9
|
import { CookieValue } from '@qwik.dev/router/middleware/request-handler';
|
|
@@ -24,6 +26,7 @@ import { RequestEventLoader } from '@qwik.dev/router/middleware/request-handler'
|
|
|
24
26
|
import { RequestHandler } from '@qwik.dev/router/middleware/request-handler';
|
|
25
27
|
import type { ResolveSyncValue } from '@qwik.dev/router/middleware/request-handler';
|
|
26
28
|
import type { SerializationStrategy } from '@qwik.dev/core/internal';
|
|
29
|
+
import type { ServerError } from '@qwik.dev/router/middleware/request-handler';
|
|
27
30
|
import type { Signal } from '@qwik.dev/core';
|
|
28
31
|
import type * as v from 'valibot';
|
|
29
32
|
import type { ValueOrPromise } from '@qwik.dev/core';
|
|
@@ -38,51 +41,53 @@ export declare type Action<RETURN, INPUT = Record<string, unknown>, OPTIONAL ext
|
|
|
38
41
|
* component$(). Like all `use-` functions and methods, it can only be invoked within a
|
|
39
42
|
* `component$()`.
|
|
40
43
|
*/
|
|
41
|
-
(): ActionStore<RETURN
|
|
44
|
+
(): ActionStore<ExcludeControlFlow<RETURN>, INPUT, OPTIONAL>;
|
|
42
45
|
};
|
|
43
46
|
|
|
44
47
|
/** @public */
|
|
45
48
|
export declare type ActionConstructor = {
|
|
46
|
-
<OBJ extends Record<string, any> | void | null, VALIDATOR extends TypedDataValidator, REST extends [DataValidator, ...DataValidator[]]>(actionQrl: (data: GetValidatorOutputType<VALIDATOR>, event: RequestEventAction) => ValueOrPromise<OBJ>, options: {
|
|
47
|
-
readonly id?: string;
|
|
49
|
+
<OBJ extends Record<string, any> | void | null, VALIDATOR extends TypedDataValidator, REST extends [DataValidator, ...DataValidator[]]>(actionQrl: (data: GetValidatorOutputType<VALIDATOR>, event: RequestEventAction) => ValueOrPromise<OBJ>, options: ActionOptions & {
|
|
48
50
|
readonly validation: [VALIDATOR, ...REST];
|
|
49
51
|
}): Action<StrictUnion<OBJ | FailReturn<ValidatorErrorType<GetValidatorInputType<VALIDATOR>>> | FailReturn<FailOfRest<REST>>>, GetValidatorInputType<VALIDATOR>, false>;
|
|
50
|
-
<OBJ extends Record<string, any> | void | null, VALIDATOR extends TypedDataValidator>(actionQrl: (data: GetValidatorOutputType<VALIDATOR>, event: RequestEventAction) => ValueOrPromise<OBJ>, options: {
|
|
51
|
-
readonly id?: string;
|
|
52
|
+
<OBJ extends Record<string, any> | void | null, VALIDATOR extends TypedDataValidator>(actionQrl: (data: GetValidatorOutputType<VALIDATOR>, event: RequestEventAction) => ValueOrPromise<OBJ>, options: ActionOptions & {
|
|
52
53
|
readonly validation: [VALIDATOR];
|
|
53
54
|
}): Action<StrictUnion<OBJ | FailReturn<ValidatorErrorType<GetValidatorInputType<VALIDATOR>>>>, GetValidatorInputType<VALIDATOR>, false>;
|
|
54
|
-
<OBJ extends Record<string, any> | void | null, REST extends [DataValidator, ...DataValidator[]]>(actionQrl: (data: JSONObject, event: RequestEventAction) => ValueOrPromise<OBJ>, options: {
|
|
55
|
-
readonly id?: string;
|
|
55
|
+
<OBJ extends Record<string, any> | void | null, REST extends [DataValidator, ...DataValidator[]]>(actionQrl: (data: JSONObject, event: RequestEventAction) => ValueOrPromise<OBJ>, options: ActionOptions & {
|
|
56
56
|
readonly validation: REST;
|
|
57
57
|
}): Action<StrictUnion<OBJ | FailReturn<FailOfRest<REST>>>>;
|
|
58
58
|
<OBJ extends Record<string, any> | void | null, VALIDATOR extends TypedDataValidator, REST extends [DataValidator, ...DataValidator[]]>(actionQrl: (data: GetValidatorOutputType<VALIDATOR>, event: RequestEventAction) => ValueOrPromise<OBJ>, options: VALIDATOR, ...rest: REST): Action<StrictUnion<OBJ | FailReturn<ValidatorErrorType<GetValidatorInputType<VALIDATOR>>> | FailReturn<FailOfRest<REST>>>, GetValidatorInputType<VALIDATOR>, false>;
|
|
59
59
|
<OBJ extends Record<string, any> | void | null, VALIDATOR extends TypedDataValidator>(actionQrl: (data: GetValidatorOutputType<VALIDATOR>, event: RequestEventAction) => ValueOrPromise<OBJ>, options: VALIDATOR): Action<StrictUnion<OBJ | FailReturn<ValidatorErrorType<GetValidatorInputType<VALIDATOR>>>>, GetValidatorInputType<VALIDATOR>, false>;
|
|
60
60
|
<OBJ extends Record<string, any> | void | null, REST extends [DataValidator, ...DataValidator[]]>(actionQrl: (form: JSONObject, event: RequestEventAction) => ValueOrPromise<OBJ>, ...rest: REST): Action<StrictUnion<OBJ | FailReturn<FailOfRest<REST>>>>;
|
|
61
|
-
<OBJ>(actionQrl: (form: JSONObject, event: RequestEventAction) => ValueOrPromise<OBJ>, options?:
|
|
62
|
-
readonly id?: string;
|
|
63
|
-
}): Action<StrictUnion<OBJ>>;
|
|
61
|
+
<OBJ>(actionQrl: (form: JSONObject, event: RequestEventAction) => ValueOrPromise<OBJ>, options?: ActionOptions): Action<StrictUnion<OBJ>>;
|
|
64
62
|
};
|
|
65
63
|
|
|
66
64
|
/** @public */
|
|
67
65
|
declare type ActionConstructorQRL = {
|
|
68
|
-
<OBJ extends Record<string, any> | void | null, VALIDATOR extends TypedDataValidator, REST extends [DataValidator, ...DataValidator[]]>(actionQrl: QRL<(data: GetValidatorOutputType<VALIDATOR>, event: RequestEventAction) => ValueOrPromise<OBJ>>, options: {
|
|
69
|
-
readonly id?: string;
|
|
66
|
+
<OBJ extends Record<string, any> | void | null, VALIDATOR extends TypedDataValidator, REST extends [DataValidator, ...DataValidator[]]>(actionQrl: QRL<(data: GetValidatorOutputType<VALIDATOR>, event: RequestEventAction) => ValueOrPromise<OBJ>>, options: ActionOptions & {
|
|
70
67
|
readonly validation: [VALIDATOR, ...REST];
|
|
71
68
|
}): Action<StrictUnion<OBJ | FailReturn<ValidatorErrorType<GetValidatorInputType<VALIDATOR>>> | FailReturn<FailOfRest<REST>>>, GetValidatorInputType<VALIDATOR>, false>;
|
|
72
|
-
<OBJ extends Record<string, any> | void | null, VALIDATOR extends TypedDataValidator>(actionQrl: QRL<(data: GetValidatorOutputType<VALIDATOR>, event: RequestEventAction) => ValueOrPromise<OBJ>>, options: {
|
|
73
|
-
readonly id?: string;
|
|
69
|
+
<OBJ extends Record<string, any> | void | null, VALIDATOR extends TypedDataValidator>(actionQrl: QRL<(data: GetValidatorOutputType<VALIDATOR>, event: RequestEventAction) => ValueOrPromise<OBJ>>, options: ActionOptions & {
|
|
74
70
|
readonly validation: [VALIDATOR];
|
|
75
71
|
}): Action<StrictUnion<OBJ | FailReturn<ValidatorErrorType<GetValidatorInputType<VALIDATOR>>>>, GetValidatorInputType<VALIDATOR>, false>;
|
|
76
|
-
<OBJ extends Record<string, any> | void | null, REST extends [DataValidator, ...DataValidator[]]>(actionQrl: QRL<(data: JSONObject, event: RequestEventAction) => ValueOrPromise<OBJ>>, options: {
|
|
77
|
-
readonly id?: string;
|
|
72
|
+
<OBJ extends Record<string, any> | void | null, REST extends [DataValidator, ...DataValidator[]]>(actionQrl: QRL<(data: JSONObject, event: RequestEventAction) => ValueOrPromise<OBJ>>, options: ActionOptions & {
|
|
78
73
|
readonly validation: REST;
|
|
79
74
|
}): Action<StrictUnion<OBJ | FailReturn<FailOfRest<REST>>>>;
|
|
80
75
|
<OBJ extends Record<string, any> | void | null, VALIDATOR extends TypedDataValidator, REST extends [DataValidator, ...DataValidator[]]>(actionQrl: QRL<(data: GetValidatorOutputType<VALIDATOR>, event: RequestEventAction) => ValueOrPromise<OBJ>>, options: VALIDATOR, ...rest: REST): Action<StrictUnion<OBJ | FailReturn<ValidatorErrorType<GetValidatorInputType<VALIDATOR>>> | FailReturn<FailOfRest<REST>>>, GetValidatorInputType<VALIDATOR>, false>;
|
|
81
76
|
<OBJ extends Record<string, any> | void | null, VALIDATOR extends TypedDataValidator>(actionQrl: QRL<(data: GetValidatorOutputType<VALIDATOR>, event: RequestEventAction) => ValueOrPromise<OBJ>>, options: VALIDATOR): Action<StrictUnion<OBJ | FailReturn<ValidatorErrorType<GetValidatorInputType<VALIDATOR>>>>, GetValidatorInputType<VALIDATOR>, false>;
|
|
82
77
|
<OBJ extends Record<string, any> | void | null, REST extends [DataValidator, ...DataValidator[]]>(actionQrl: QRL<(form: JSONObject, event: RequestEventAction) => ValueOrPromise<OBJ>>, ...rest: REST): Action<StrictUnion<OBJ | FailReturn<FailOfRest<REST>>>>;
|
|
83
|
-
<OBJ>(actionQrl: QRL<(form: JSONObject, event: RequestEventAction) => ValueOrPromise<OBJ>>, options?:
|
|
84
|
-
|
|
85
|
-
|
|
78
|
+
<OBJ>(actionQrl: QRL<(form: JSONObject, event: RequestEventAction) => ValueOrPromise<OBJ>>, options?: ActionOptions): Action<StrictUnion<OBJ>>;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/** @public */
|
|
82
|
+
export declare type ActionOptions = {
|
|
83
|
+
readonly id?: string;
|
|
84
|
+
readonly validation?: DataValidator[];
|
|
85
|
+
/**
|
|
86
|
+
* Route loaders to invalidate after this action completes. The loader hooks' hashes are sent to
|
|
87
|
+
* the client so it knows which loaders to re-fetch. If omitted, ALL route loaders are invalidated
|
|
88
|
+
* (unless `strictLoaders` is enabled globally in the Vite plugin).
|
|
89
|
+
*/
|
|
90
|
+
readonly invalidate?: Loader_2<any>[];
|
|
86
91
|
};
|
|
87
92
|
|
|
88
93
|
/** @public */
|
|
@@ -394,6 +399,14 @@ declare interface ErrorBoundaryProps {
|
|
|
394
399
|
fallback$?: QRL<(error: any) => any>;
|
|
395
400
|
}
|
|
396
401
|
|
|
402
|
+
/**
|
|
403
|
+
* Drops control-flow signals (`ev.redirect()`, `ev.error()`, etc.) from a loader/action return
|
|
404
|
+
* type: those are thrown, not surfaced as data. `ev.fail()` is plain data and is kept.
|
|
405
|
+
*
|
|
406
|
+
* @public
|
|
407
|
+
*/
|
|
408
|
+
export declare type ExcludeControlFlow<T> = Exclude<T, AbortMessage | ServerError>;
|
|
409
|
+
|
|
397
410
|
declare type Failed = {
|
|
398
411
|
failed: true;
|
|
399
412
|
};
|
|
@@ -434,6 +447,14 @@ export declare interface FormSubmitSuccessDetail<T> {
|
|
|
434
447
|
value: T;
|
|
435
448
|
}
|
|
436
449
|
|
|
450
|
+
/**
|
|
451
|
+
* Returns the current RequestEvent if possible. Only usable on the server, and only during request
|
|
452
|
+
* processing.
|
|
453
|
+
*
|
|
454
|
+
* @public
|
|
455
|
+
*/
|
|
456
|
+
export declare const getRequestEvent: (thisArg?: unknown) => RequestEvent | undefined;
|
|
457
|
+
|
|
437
458
|
/** @public */
|
|
438
459
|
export declare type GetValidatorInputType<VALIDATOR extends TypedDataValidator> = VALIDATOR extends ValibotDataValidator<infer TYPE> ? v.InferInput<TYPE> : VALIDATOR extends ZodDataValidator<infer TYPE> ? z_2.input<TYPE> : never;
|
|
439
460
|
|
|
@@ -482,8 +503,8 @@ export declare const Link: Component<LinkProps>;
|
|
|
482
503
|
/** @public */
|
|
483
504
|
export declare interface LinkProps extends AnchorAttributes {
|
|
484
505
|
/**
|
|
485
|
-
* @deprecated Use `
|
|
486
|
-
* is prefetched and when. This prop will be removed in a future major version.
|
|
506
|
+
* @deprecated Use `prefetchBundles` and `prefetchData` instead for more granular control over
|
|
507
|
+
* what is prefetched and when. This prop will be removed in a future major version.
|
|
487
508
|
*
|
|
488
509
|
* Legacy prefetch control for this **`Link`**.
|
|
489
510
|
*
|
|
@@ -501,7 +522,7 @@ export declare interface LinkProps extends AnchorAttributes {
|
|
|
501
522
|
*
|
|
502
523
|
* Prefetching will not occur if the user has the **data saver** setting enabled.
|
|
503
524
|
*/
|
|
504
|
-
|
|
525
|
+
prefetchBundles?: PrefetchStrategy;
|
|
505
526
|
/**
|
|
506
527
|
* Controls when Qwik should prefetch and cache route data for this **`Link`** target, including
|
|
507
528
|
* invoking any **`routeLoader$`**, **`onGet`**, etc.
|
|
@@ -534,8 +555,8 @@ declare interface LoadedRoute {
|
|
|
534
555
|
$routeBundleNames$?: string[] | undefined;
|
|
535
556
|
/** Whether this route is a not-found (404) route */
|
|
536
557
|
$notFound$?: boolean;
|
|
537
|
-
/** The error
|
|
538
|
-
$errorLoader$?:
|
|
558
|
+
/** The nearest _E (error.tsx) boundary's chain to render on a thrown ServerError (in its layouts). */
|
|
559
|
+
$errorLoader$?: ModuleLoader[];
|
|
539
560
|
/** Merged array of routeLoader$ hashes from all matched nodes (layouts + page) */
|
|
540
561
|
$loaders$?: string[];
|
|
541
562
|
/** Runtime-only mapping of routeLoader$ hashes to the matched pathname used for q-loader fetches */
|
|
@@ -548,7 +569,7 @@ declare type Loader_2<RETURN> = {
|
|
|
548
569
|
* Returns the `Signal` containing the data returned by the `loader$` function. Like all `use-`
|
|
549
570
|
* functions and methods, it can only be invoked within a `component$()`.
|
|
550
571
|
*/
|
|
551
|
-
(): LoaderSignal<RETURN
|
|
572
|
+
(): LoaderSignal<ExcludeControlFlow<RETURN>>;
|
|
552
573
|
};
|
|
553
574
|
export { Loader_2 as Loader }
|
|
554
575
|
|
|
@@ -566,24 +587,28 @@ declare type LoaderConstructorQRL = {
|
|
|
566
587
|
|
|
567
588
|
/** @public */
|
|
568
589
|
declare type LoaderOptions = {
|
|
569
|
-
/**
|
|
590
|
+
/**
|
|
591
|
+
* Explicit loader id, overriding the QRL hash. Pass a distinct value (e.g. `fn.getHash()`) when
|
|
592
|
+
* loaders share a wrapper QRL.
|
|
593
|
+
*/
|
|
570
594
|
readonly id?: string;
|
|
571
595
|
readonly validation?: DataValidator[];
|
|
572
596
|
readonly serializationStrategy?: SerializationStrategy;
|
|
573
597
|
/**
|
|
574
|
-
*
|
|
575
|
-
*
|
|
598
|
+
* Cache-Control for this loader's JSON responses. The browser HTTP cache is the single source of
|
|
599
|
+
* freshness for loader data: on every client navigation the loaders re-fetch, and this header
|
|
600
|
+
* decides whether the browser serves the fetch from cache, revalidates, or hits the server.
|
|
576
601
|
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
*
|
|
584
|
-
*
|
|
602
|
+
* Accepts any `cacheControl()` value (`'immutable'`, `'no-cache'`, a max-age number, an options
|
|
603
|
+
* object) or a function of the request event; the function may return `null` to skip the header.
|
|
604
|
+
* A `Cache-Control` header set inside the loader function wins over this option.
|
|
605
|
+
*
|
|
606
|
+
* Defaults to `no-cache` (always revalidate; combine with `eTag` for cheap 304s).
|
|
607
|
+
*
|
|
608
|
+
* The literal value `'immutable'` also marks the loader's data as static, so SSG writes a
|
|
609
|
+
* per-loader JSON file at build time.
|
|
585
610
|
*/
|
|
586
|
-
readonly
|
|
611
|
+
readonly cacheControl?: CacheControl | ((ev: RequestEvent) => CacheControl | null);
|
|
587
612
|
/**
|
|
588
613
|
* Enable ETag-based caching for this loader's JSON responses.
|
|
589
614
|
*
|
|
@@ -632,17 +657,21 @@ declare type LoaderOptions = {
|
|
|
632
657
|
*/
|
|
633
658
|
readonly search?: string[];
|
|
634
659
|
/**
|
|
635
|
-
* When true (default), the
|
|
636
|
-
*
|
|
660
|
+
* When true (default), the loader is awaited before SSR renders, so its redirect or error can
|
|
661
|
+
* short-circuit the response and its value is ready for synchronous reads (e.g. in the head).
|
|
662
|
+
*
|
|
663
|
+
* When false, the loader runs in the background without blocking SSR: rendering starts
|
|
664
|
+
* immediately and reading its `.value` suspends until it resolves. A background loader cannot
|
|
665
|
+
* redirect or error the initial SSR response; treat it as a separate request.
|
|
637
666
|
*
|
|
638
|
-
*
|
|
639
|
-
*
|
|
667
|
+
* Setting `false` is experimental and requires adding `experimental: ["blockSSR"]` to your
|
|
668
|
+
* qwikVite plugin options.
|
|
640
669
|
*/
|
|
641
|
-
readonly
|
|
670
|
+
readonly blockSSR?: boolean;
|
|
642
671
|
};
|
|
643
672
|
|
|
644
673
|
/** @public */
|
|
645
|
-
export declare type LoaderSignal<TYPE> = (TYPE extends () => ValueOrPromise<infer VALIDATOR> ? Signal<ValueOrPromise<VALIDATOR>> : Signal<TYPE>) & Pick<
|
|
674
|
+
export declare type LoaderSignal<TYPE> = (TYPE extends () => ValueOrPromise<infer VALIDATOR> ? Signal<ValueOrPromise<VALIDATOR>> : Signal<TYPE>) & Pick<ComputedSignal<any>, 'promise' | 'pending' | 'error' | 'loading'>;
|
|
646
675
|
|
|
647
676
|
declare interface MenuModule {
|
|
648
677
|
readonly default: ContentMenu;
|
|
@@ -840,9 +869,9 @@ export declare const QwikRouterMockProvider: Component<QwikRouterMockProps>;
|
|
|
840
869
|
/** @public */
|
|
841
870
|
export declare interface QwikRouterProps {
|
|
842
871
|
/**
|
|
843
|
-
* Enable the ViewTransition API
|
|
872
|
+
* Enable the ViewTransition API on SPA navigation. Opt-in: set to `true` to enable.
|
|
844
873
|
*
|
|
845
|
-
* Default: `
|
|
874
|
+
* Default: `false`
|
|
846
875
|
*
|
|
847
876
|
* @see https://github.com/WICG/view-transitions/blob/main/explainer.md
|
|
848
877
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
|
|
@@ -906,7 +935,8 @@ export declare type ResolvedDocumentHead<FrontMatter extends Record<string, any>
|
|
|
906
935
|
*/
|
|
907
936
|
export declare const routeAction$: ActionConstructor;
|
|
908
937
|
|
|
909
|
-
|
|
938
|
+
/** @public */
|
|
939
|
+
export declare const routeActionQrl: ActionConstructorQRL;
|
|
910
940
|
|
|
911
941
|
declare type RouteActionResolver = {
|
|
912
942
|
status: number;
|
|
@@ -963,10 +993,13 @@ export declare interface RouteData {
|
|
|
963
993
|
_G?: string;
|
|
964
994
|
/** The JS bundle names for this route (SSR only) */
|
|
965
995
|
_B?: string[];
|
|
966
|
-
/**
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
996
|
+
/**
|
|
997
|
+
* Not-found (404) boundary: single loader (runtime prepends layouts) or override chain
|
|
998
|
+
* (`404@layout`/`!`).
|
|
999
|
+
*/
|
|
1000
|
+
_4?: ContentModuleLoader | ModuleLoader[];
|
|
1001
|
+
/** Error (error.tsx) boundary, same single-or-override-chain shape as `_4`. */
|
|
1002
|
+
_E?: ContentModuleLoader | ModuleLoader[];
|
|
970
1003
|
/** The parameter name when this node is reached via `_W` or `_A` from the parent */
|
|
971
1004
|
_P?: string;
|
|
972
1005
|
/** Prefix for infix params (e.g. "pre" for `pre[slug]post`) — only on `_W` nodes */
|
|
@@ -986,7 +1019,7 @@ export declare interface RouteData {
|
|
|
986
1019
|
/**
|
|
987
1020
|
* Define a route loader that fetches data before the route renders.
|
|
988
1021
|
*
|
|
989
|
-
* Route loaders run on the server during SSR and return data as
|
|
1022
|
+
* Route loaders run on the server during SSR and return data as a `ComputedSignal`. On the client,
|
|
990
1023
|
* loaders automatically re-fetch when the route changes (SPA navigation). Each loader gets its own
|
|
991
1024
|
* JSON endpoint (`q-loader-{id}.{hash}.json`), so only the loaders present on the target route are
|
|
992
1025
|
* fetched.
|
|
@@ -1001,10 +1034,9 @@ export declare interface RouteData {
|
|
|
1001
1034
|
* sent in the request and changes to other params are ignored. During SSR and loader JSON
|
|
1002
1035
|
* requests, the loader's request event is filtered to those params too. `search: []` means no
|
|
1003
1036
|
* 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
1037
|
* - `eTag`: Enable ETag-based caching. Can be `true` (auto-hash), a string, or a function.
|
|
1007
|
-
* - `
|
|
1038
|
+
* - `cacheControl`: Cache-Control for loader JSON responses; the browser HTTP cache controls
|
|
1039
|
+
* client-side freshness. `'immutable'` additionally lets SSG write the loader file.
|
|
1008
1040
|
*
|
|
1009
1041
|
* The `strictLoaders` Vite plugin option applies `search: []` globally for all loaders that don't
|
|
1010
1042
|
* specify an explicit `search` option.
|
|
@@ -1028,6 +1060,8 @@ declare type RouteLoaderCtx = {
|
|
|
1028
1060
|
pageSearch?: string;
|
|
1029
1061
|
/** SPA navigation function. Client-only and intentionally omitted from SSR state. */
|
|
1030
1062
|
goto?: NoSerialize<RouteNavigate>;
|
|
1063
|
+
/** Client manifest hash for q-loader fetch URLs. */
|
|
1064
|
+
manifestHash?: string;
|
|
1031
1065
|
};
|
|
1032
1066
|
|
|
1033
1067
|
/* Excluded from this release type: routeLoaderQrl */
|