@qwik.dev/router 2.0.0-beta.43 → 2.0.0-beta.47

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.
Files changed (50) hide show
  1. package/lib/adapters/azure-swa/vite/index.d.ts +2 -2
  2. package/lib/adapters/azure-swa/vite/index.mjs +2 -1
  3. package/lib/adapters/bun-server/vite/index.d.ts +2 -2
  4. package/lib/adapters/bun-server/vite/index.mjs +2 -1
  5. package/lib/adapters/cloud-run/vite/index.d.ts +2 -2
  6. package/lib/adapters/cloud-run/vite/index.mjs +2 -1
  7. package/lib/adapters/cloudflare-pages/vite/index.d.ts +2 -2
  8. package/lib/adapters/cloudflare-pages/vite/index.mjs +2 -1
  9. package/lib/adapters/deno-server/vite/index.d.ts +2 -2
  10. package/lib/adapters/deno-server/vite/index.mjs +2 -1
  11. package/lib/adapters/netlify-edge/vite/index.d.ts +2 -2
  12. package/lib/adapters/netlify-edge/vite/index.mjs +2 -1
  13. package/lib/adapters/node-server/vite/index.d.ts +2 -2
  14. package/lib/adapters/node-server/vite/index.mjs +2 -1
  15. package/lib/adapters/shared/vite/index.d.ts +1 -1
  16. package/lib/adapters/shared/vite/index.mjs +36 -32
  17. package/lib/adapters/ssg/vite/index.d.ts +1 -1
  18. package/lib/adapters/ssg/vite/index.mjs +4 -2
  19. package/lib/adapters/vercel-edge/vite/index.d.ts +2 -2
  20. package/lib/adapters/vercel-edge/vite/index.mjs +18 -15
  21. package/lib/chunks/fs.mjs +28 -25
  22. package/lib/chunks/head.qwik.mjs +731 -448
  23. package/lib/chunks/http-error.qwik.mjs +8 -7
  24. package/lib/chunks/pathname.mjs +9 -8
  25. package/lib/chunks/request-path.mjs +8 -4
  26. package/lib/chunks/route-trie-key.mjs +10 -0
  27. package/lib/chunks/routes.mjs +14 -14
  28. package/lib/chunks/server-error.mjs +28 -6
  29. package/lib/chunks/{url.mjs → static-file.mjs} +12 -2
  30. package/lib/chunks/system.mjs +31 -25
  31. package/lib/chunks/user-response.mjs +455 -348
  32. package/lib/chunks/worker-thread.mjs +90 -88
  33. package/lib/index.d.ts +94 -63
  34. package/lib/index.qwik.mjs +615 -523
  35. package/lib/middleware/aws-lambda/index.mjs +6 -3
  36. package/lib/middleware/azure-swa/index.mjs +4 -2
  37. package/lib/middleware/bun/index.mjs +12 -12
  38. package/lib/middleware/cloudflare-pages/index.mjs +19 -4
  39. package/lib/middleware/deno/index.mjs +12 -12
  40. package/lib/middleware/firebase/index.mjs +4 -2
  41. package/lib/middleware/netlify-edge/index.mjs +4 -2
  42. package/lib/middleware/node/index.mjs +16 -15
  43. package/lib/middleware/request-handler/index.d.ts +102 -2
  44. package/lib/middleware/request-handler/index.mjs +30 -34
  45. package/lib/middleware/vercel-edge/index.mjs +4 -2
  46. package/lib/service-worker/index.mjs +2 -1
  47. package/lib/ssg/index.mjs +23 -18
  48. package/lib/vite/index.d.ts +1 -1
  49. package/lib/vite/index.mjs +669 -604
  50. package/package.json +5 -5
@@ -4,13 +4,14 @@ var _hf0 = (p0) => p0.status || 500;
4
4
  var _hf0_str = "p0.status||500";
5
5
  var _hf1 = (p0) => p0.message || "";
6
6
  var _hf1_str = "p0.message||\"\"";
7
- /** Cache error pages per status code so all 404s (or 500s) share one cache entry. */ var cacheKey = (ev) => String(ev.status);
7
+ /** Cache error pages per status code so all 404s (or 500s) share one cache entry. */
8
+ var cacheKey = (ev) => String(ev.status);
8
9
  var COLOR_400 = "#006ce9";
9
10
  var COLOR_500 = "#713fc2";
10
11
  var DisplayHttpStatus = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(() => {
11
- const httpstatus = useHttpStatus();
12
- const width = httpstatus.message ? "600px" : "300px";
13
- const color = httpstatus.status < 500 ? COLOR_400 : COLOR_500;
12
+ const httpStatus = useHttpStatus();
13
+ const width = httpStatus.message ? "600px" : "300px";
14
+ const color = httpStatus.status < 500 ? COLOR_400 : COLOR_500;
14
15
  const style = `
15
16
  body { color: ${color}; background-color: #fafafa; padding: 30px; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Roboto, sans-serif; }
16
17
  p { max-width: ${width}; margin: 60px auto 30px auto; background: white; border-radius: 4px; box-shadow: 0px 0px 50px -20px ${color}; overflow: hidden; }
@@ -19,9 +20,9 @@ var DisplayHttpStatus = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(() =
19
20
  `;
20
21
  return /*#__PURE__*/ _jsxSorted("p", null, null, [
21
22
  /*#__PURE__*/ _jsxSorted("style", { dangerouslySetInnerHTML: style }, null, null, 3, null),
22
- /*#__PURE__*/ _jsxSorted("strong", null, null, _fnSignal(_hf0, [httpstatus], _hf0_str), 3, null),
23
+ /*#__PURE__*/ _jsxSorted("strong", null, null, _fnSignal(_hf0, [httpStatus], _hf0_str), 3, null),
23
24
  " ",
24
- /*#__PURE__*/ _jsxSorted("span", null, null, _fnSignal(_hf1, [httpstatus], _hf1_str), 3, null)
25
- ], 1, "vY_0");
25
+ /*#__PURE__*/ _jsxSorted("span", null, null, _fnSignal(_hf1, [httpStatus], _hf1_str), 3, null)
26
+ ], 1, "Ds_0");
26
27
  }, "DisplayHttpStatus_component_PJf4K4PL7Oc"));
27
28
  export { cacheKey, DisplayHttpStatus as default };
@@ -1,4 +1,5 @@
1
- /** Ensures the pathname ends with a slash */ var ensureSlash = (pathname) => pathname.endsWith("/") ? pathname : pathname + "/";
1
+ /** Ensures the pathname ends with a slash */
2
+ var ensureSlash = (pathname) => pathname.endsWith("/") ? pathname : pathname + "/";
2
3
  function normalizePathname(pathname, basePathname) {
3
4
  if (typeof pathname === "string") {
4
5
  pathname = pathname.trim();
@@ -32,13 +33,6 @@ function getPathnameForDynamicRoute(originalPathname, paramNames, params) {
32
33
  }
33
34
  return pathname;
34
35
  }
35
- var PROTOCOLS = {
36
- https: true,
37
- http: true,
38
- about: true,
39
- javascript: true,
40
- file: true
41
- };
42
36
  function isSameOriginUrl(url) {
43
37
  if (typeof url === "string") {
44
38
  url = url.trim();
@@ -54,4 +48,11 @@ function isSameOriginUrl(url) {
54
48
  }
55
49
  return false;
56
50
  }
51
+ var PROTOCOLS = {
52
+ https: true,
53
+ http: true,
54
+ about: true,
55
+ javascript: true,
56
+ file: true
57
+ };
57
58
  export { normalizePathname as i, getPathnameForDynamicRoute as n, isSameOriginUrl as r, ensureSlash as t };
@@ -3,14 +3,16 @@ var IsQLoader = "@isQLoader";
3
3
  var IsQAction = "@isQAction";
4
4
  var QLoaderId = "@loaderId";
5
5
  var QActionId = "@actionId";
6
- /** Matches the final `/q-loader-{loaderId}.{manifestHash}.json` path segment. */ var LOADER_REGEX = /\/(q-loader-([^/.]+)\.([^/.]+)\.json)$/;
6
+ /** Matches the final `/q-loader-{loaderId}.{manifestHash}.json` path segment. */
7
+ var LOADER_REGEX = /\/(q-loader-([^/.]+)\.([^/.]+)\.json)$/;
7
8
  var getLoaderName = (loaderId, manifestHash) => `q-loader-${loaderId}.${manifestHash}.json`;
8
9
  /**
9
10
  * Recognize internal request types from the URL pathname.
10
11
  *
11
12
  * Returns the request type, how many characters to trim from the pathname, and any extracted data
12
13
  * (e.g. loaderId for loader requests).
13
- */ function recognizeRequest(pathname) {
14
+ */
15
+ function recognizeRequest(pathname) {
14
16
  if (pathname.length < 10) return null;
15
17
  const loaderMatch = pathname.match(LOADER_REGEX);
16
18
  if (loaderMatch) return {
@@ -23,12 +25,14 @@ var getLoaderName = (loaderId, manifestHash) => `q-loader-${loaderId}.${manifest
23
25
  };
24
26
  return null;
25
27
  }
26
- /** Trim a recognized internal URL suffix from a pathname, returning the clean route pathname. */ function trimRecognizedInternalPathname(pathname, recognized) {
28
+ /** Trim a recognized internal URL suffix from a pathname, returning the clean route pathname. */
29
+ function trimRecognizedInternalPathname(pathname, recognized) {
27
30
  let trimmed = pathname.slice(0, pathname.length - recognized.trimLength) || "/";
28
31
  if (!globalThis.__NO_TRAILING_SLASH__ && !trimmed.endsWith("/")) trimmed = ensureSlash(trimmed);
29
32
  return trimmed;
30
33
  }
31
- /** Trim any recognized internal URL suffix from a pathname, returning the clean route pathname. */ function trimInternalPathname(pathname) {
34
+ /** Trim any recognized internal URL suffix from a pathname, returning the clean route pathname. */
35
+ function trimInternalPathname(pathname) {
32
36
  const recognized = recognizeRequest(pathname);
33
37
  if (recognized) return trimRecognizedInternalPathname(pathname, recognized);
34
38
  return pathname;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Route trie metadata keys start with `_` (`_4`, `_W`, …), so static segments that start with `_`
3
+ * are stored with an extra `_` to keep the two apart.
4
+ */
5
+ var escapeStaticTrieKey = (segment) => segment.startsWith("_") ? "_" + segment : segment;
6
+ /** The URL segment for a static trie key. */
7
+ var unescapeStaticTrieKey = (key) => key.startsWith("_") ? key.slice(1) : key;
8
+ /** Whether a trie key is a static segment rather than metadata. */
9
+ var isStaticTrieKey = (key) => !key.startsWith("_") || key.startsWith("__");
10
+ export { isStaticTrieKey as n, unescapeStaticTrieKey as r, escapeStaticTrieKey as t };
@@ -1,17 +1,3 @@
1
- function routeToRegExp(rule) {
2
- let transformedRule;
3
- if (rule === "/" || rule === "/*") transformedRule = rule;
4
- else if (rule.endsWith("/*")) transformedRule = `${rule.substring(0, rule.length - 2)}(/*)?`;
5
- else if (rule.endsWith("/")) transformedRule = `${rule.substring(0, rule.length - 1)}(/)?`;
6
- else if (rule.endsWith("*")) transformedRule = rule;
7
- else transformedRule = `${rule}(/)?`;
8
- transformedRule = `^${transformedRule.replace(/\*/g, ".*")}$`;
9
- return new RegExp(transformedRule);
10
- }
11
- function routesToRegExps(routes) {
12
- if (!Array.isArray(routes)) return [];
13
- return routes.filter((r) => typeof r === "string").map(routeToRegExp);
14
- }
15
1
  function createRouteTester(basePathname, includeRoutes, excludeRoutes) {
16
2
  const includes = routesToRegExps(includeRoutes);
17
3
  const excludes = routesToRegExps(excludeRoutes);
@@ -23,4 +9,18 @@ function createRouteTester(basePathname, includeRoutes, excludeRoutes) {
23
9
  return false;
24
10
  };
25
11
  }
12
+ function routesToRegExps(routes) {
13
+ if (!Array.isArray(routes)) return [];
14
+ return routes.filter((r) => typeof r === "string").map(routeToRegExp);
15
+ }
16
+ function routeToRegExp(rule) {
17
+ let transformedRule;
18
+ if (rule === "/" || rule === "/*") transformedRule = rule;
19
+ else if (rule.endsWith("/*")) transformedRule = `${rule.substring(0, rule.length - 2)}(/*)?`;
20
+ else if (rule.endsWith("/")) transformedRule = `${rule.substring(0, rule.length - 1)}(/)?`;
21
+ else if (rule.endsWith("*")) transformedRule = rule;
22
+ else transformedRule = `${rule}(/)?`;
23
+ transformedRule = `^${transformedRule.replace(/\*/g, ".*")}$`;
24
+ return new RegExp(transformedRule);
25
+ }
26
26
  export { createRouteTester as t };
@@ -1,16 +1,38 @@
1
- /** @public */ var AbortMessage = class {};
2
- /** @public */ var RedirectMessage = class extends AbortMessage {};
3
- /** @public */ var ServerError = class extends Error {
1
+ import { _qwikSymbol } from "@qwik.dev/core/internal";
2
+ /**
3
+ * Makes `instanceof cls` also match instances made by another copy of the router, such as the one a
4
+ * Qwik library kept external on the server evaluates. Subclasses need their own call.
5
+ */
6
+ var shareClassIdentity = (cls, name) => {
7
+ const tag = _qwikSymbol(`router.${name}`);
8
+ cls.prototype[tag] = true;
9
+ Object.defineProperty(cls, Symbol.hasInstance, { value(value) {
10
+ if (this !== cls) return Function.prototype[Symbol.hasInstance].call(this, value);
11
+ return value != null && typeof value === "object" && tag in value;
12
+ } });
13
+ };
14
+ /** @public */
15
+ var AbortMessage = class {};
16
+ shareClassIdentity(AbortMessage, "AbortMessage");
17
+ /** @public */
18
+ var RedirectMessage = class extends AbortMessage {};
19
+ shareClassIdentity(RedirectMessage, "RedirectMessage");
20
+ /** @public */
21
+ var ServerError = class extends Error {
4
22
  status;
5
23
  data;
6
24
  constructor(status, data) {
7
- super(typeof data === "string" ? data : void 0), this.status = status, this.data = data;
25
+ super(typeof data === "string" ? data : void 0);
26
+ this.status = status;
27
+ this.data = data;
8
28
  }
9
29
  };
30
+ shareClassIdentity(ServerError, "ServerError");
10
31
  /**
11
32
  * `ev.redirect()`, `ev.error()`, etc. return a control-flow signal meant to be thrown. Throw it for
12
33
  * the user when they return it instead, so returning and throwing behave the same.
13
- */ var throwIfControlFlowSignal = (value) => {
34
+ */
35
+ var throwIfControlFlowSignal = (value) => {
14
36
  if (value instanceof AbortMessage || value instanceof ServerError) throw value;
15
37
  };
16
- export { RedirectMessage as i, throwIfControlFlowSignal as n, AbortMessage as r, ServerError as t };
38
+ export { shareClassIdentity as a, RedirectMessage as i, throwIfControlFlowSignal as n, AbortMessage as r, ServerError as t };
@@ -1,4 +1,6 @@
1
- /** Common mime types mapped to Content-Type headers */ var MIME_TYPES = {
1
+ import { t as ensureSlash } from "./pathname.mjs";
2
+ /** Common mime types mapped to Content-Type headers */
3
+ var MIME_TYPES = {
2
4
  "3gp": "video/3gpp",
3
5
  "3gpp": "video/3gpp",
4
6
  asf: "video/x-ms-asf",
@@ -57,4 +59,12 @@ function normalizeRequestUrl(url, base) {
57
59
  const suffix = queryOrHashIndex === -1 ? "" : url.slice(queryOrHashIndex);
58
60
  return new URL(`${path.replace(LEADING_DOUBLE_SLASH_REG, "/").replace(DOUBLE_SLASH_REG, "/")}${suffix}`, base);
59
61
  }
60
- export { MIME_TYPES as n, normalizeRequestUrl as t };
62
+ function getStaticFilePath(pathname) {
63
+ const basePathname = globalThis.__QWIK_ROUTER_BASE_PATHNAME__ || "/";
64
+ if (pathname === basePathname.slice(0, -1)) return "/index.html";
65
+ if (!pathname.startsWith(basePathname)) return;
66
+ const relativePathname = pathname.slice(basePathname.length - 1);
67
+ if (relativePathname.slice(relativePathname.lastIndexOf("/") + 1).includes(".")) return relativePathname;
68
+ return ensureSlash(relativePathname) + "index.html";
69
+ }
70
+ export { normalizeRequestUrl as n, MIME_TYPES as r, getStaticFilePath as t };
@@ -5,11 +5,6 @@ import fs from "node:fs";
5
5
  import { dirname, isAbsolute, join, resolve } from "node:path";
6
6
  import { cpus } from "node:os";
7
7
  import { Worker } from "node:worker_threads";
8
- function ssgWorkerCompare(a, b) {
9
- if (a.activeTasks < b.activeTasks) return -1;
10
- if (a.activeTasks > b.activeTasks) return 1;
11
- return a.totalTasks < b.totalTasks ? -1 : 1;
12
- }
13
8
  async function createWorkerPool(sys, opts) {
14
9
  const log = await sys.createLogger();
15
10
  const ssgWorkers = [];
@@ -36,6 +31,10 @@ async function createWorkerPool(sys, opts) {
36
31
  let terminateResolve = null;
37
32
  const mainTasks = /* @__PURE__ */ new Map();
38
33
  let terminateTimeout = null;
34
+ let markWorkerReady;
35
+ const workerReady = new Promise((resolve) => {
36
+ markWorkerReady = resolve;
37
+ });
39
38
  const nodeWorker = new Worker(workerFilePath, { workerData });
40
39
  nodeWorker.unref();
41
40
  const ssgWorker = {
@@ -43,16 +42,14 @@ async function createWorkerPool(sys, opts) {
43
42
  totalTasks: 0,
44
43
  render: (staticRoute) => {
45
44
  return new Promise((resolve, reject) => {
46
- try {
47
- ssgWorker.activeTasks++;
48
- ssgWorker.totalTasks++;
49
- mainTasks.set(staticRoute.pathname, resolve);
50
- nodeWorker.postMessage(staticRoute);
51
- } catch (e) {
45
+ ssgWorker.activeTasks++;
46
+ ssgWorker.totalTasks++;
47
+ mainTasks.set(staticRoute.pathname, resolve);
48
+ workerReady.then(() => nodeWorker.postMessage(staticRoute)).catch((e) => {
52
49
  ssgWorker.activeTasks--;
53
50
  mainTasks.delete(staticRoute.pathname);
54
51
  reject(e);
55
- }
52
+ });
56
53
  });
57
54
  },
58
55
  terminate: async () => {
@@ -68,7 +65,7 @@ async function createWorkerPool(sys, opts) {
68
65
  await nodeWorker.terminate();
69
66
  resolve();
70
67
  }, 1e3);
71
- nodeWorker.postMessage(msg);
68
+ workerReady.then(() => nodeWorker.postMessage(msg));
72
69
  });
73
70
  if (terminateTimeout) {
74
71
  clearTimeout(terminateTimeout);
@@ -78,6 +75,9 @@ async function createWorkerPool(sys, opts) {
78
75
  };
79
76
  nodeWorker.on("message", (msg) => {
80
77
  switch (msg.type) {
78
+ case "ready":
79
+ markWorkerReady();
80
+ break;
81
81
  case "render": {
82
82
  const mainTask = mainTasks.get(msg.pathname);
83
83
  if (mainTask) {
@@ -186,18 +186,13 @@ async function createWorkerPool(sys, opts) {
186
186
  close
187
187
  };
188
188
  }
189
- var ensureDir = async (filePath) => {
190
- await fs.promises.mkdir(dirname(filePath), { recursive: true });
191
- };
192
- var access = async (path) => {
193
- try {
194
- await fs.promises.access(path);
195
- return true;
196
- } catch {
197
- return false;
198
- }
199
- };
200
- /** @public */ async function createSystem(opts, threadId) {
189
+ function ssgWorkerCompare(a, b) {
190
+ if (a.activeTasks < b.activeTasks) return -1;
191
+ if (a.activeTasks > b.activeTasks) return 1;
192
+ return a.totalTasks < b.totalTasks ? -1 : 1;
193
+ }
194
+ /** @public */
195
+ async function createSystem(opts, threadId) {
201
196
  const createWriteStream = (filePath) => {
202
197
  return fs.createWriteStream(filePath, { flags: "w" });
203
198
  };
@@ -262,4 +257,15 @@ var access = async (path) => {
262
257
  sys.createMainProcess = () => createWorkerPool(sys, opts);
263
258
  return sys;
264
259
  }
260
+ var ensureDir = async (filePath) => {
261
+ await fs.promises.mkdir(dirname(filePath), { recursive: true });
262
+ };
263
+ var access = async (path) => {
264
+ try {
265
+ await fs.promises.access(path);
266
+ return true;
267
+ } catch {
268
+ return false;
269
+ }
270
+ };
265
271
  export { createSystem };