@qwik.dev/core 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.
Files changed (37) hide show
  1. package/dist/backpatch/package.json +1 -1
  2. package/dist/build/package.json +1 -1
  3. package/dist/cli.mjs +14 -5
  4. package/dist/core-internal.d.ts +397 -323
  5. package/dist/core.min.mjs +9 -8
  6. package/dist/core.mjs +1886 -1161
  7. package/dist/core.mjs.map +1 -1
  8. package/dist/core.prod.mjs +4646 -4048
  9. package/dist/loader/index.mjs +2 -2
  10. package/dist/loader/package.json +1 -1
  11. package/dist/optimizer.d.ts +5 -3
  12. package/dist/optimizer.mjs +1676 -1722
  13. package/dist/preloader.mjs +1 -1
  14. package/dist/qwikloader.debug.js +1 -1
  15. package/dist/qwikloader.js +1 -1
  16. package/dist/server.d.ts +7 -0
  17. package/dist/server.mjs +75 -34
  18. package/dist/server.prod.mjs +392 -345
  19. package/dist/starters/adapters/bun/src/entry.bun.ts +35 -0
  20. package/dist/starters/adapters/cloud-run/src/entry.cloud-run.tsx +20 -0
  21. package/dist/starters/adapters/deno/src/entry.deno.ts +41 -0
  22. package/dist/starters/adapters/express/src/entry.express.tsx +20 -0
  23. package/dist/starters/adapters/fastify/package.json +2 -2
  24. package/dist/starters/adapters/fastify/src/entry.fastify.tsx +20 -0
  25. package/dist/starters/adapters/fastify/src/plugins/fastify-qwik.ts +10 -1
  26. package/dist/starters/adapters/node-server/src/entry.node-server.tsx +20 -0
  27. package/dist/starters/features/csr/package.json +1 -1
  28. package/dist/starters/features/drizzle/package.json +1 -1
  29. package/dist/starters/features/vitest/package.json +1 -1
  30. package/dist/testing/index.d.ts +40 -31
  31. package/dist/testing/index.mjs +1568 -942
  32. package/dist/testing/package.json +1 -1
  33. package/dist/worker/package.json +1 -1
  34. package/dist/worker/worker.shared.js +1 -1
  35. package/handlers.mjs +3 -0
  36. package/package.json +7 -7
  37. package/public.d.ts +3 -0
@@ -8,6 +8,7 @@
8
8
  * - https://bun.sh/docs/api/http
9
9
  *
10
10
  */
11
+ import { getRequestEvent } from "@qwik.dev/router";
11
12
  import { createQwikRouter } from "@qwik.dev/router/middleware/bun";
12
13
  import render from "./entry.ssr";
13
14
 
@@ -25,7 +26,41 @@ const port = Number(Bun.env.PORT ?? 3000);
25
26
  // eslint-disable-next-line no-console
26
27
  console.log(`Server started: http://localhost:${port}/`);
27
28
 
29
+ // Optional request-aware diagnostics for crashes that escape request boundaries.
30
+ // This does not prevent Bun from crashing, but it does provide better diagnostics.
31
+ // See Bun and Node process event docs for runtime-specific behavior.
32
+ process.on("uncaughtException", (error) => {
33
+ const requestEv = getRequestEvent();
34
+ if (requestEv) {
35
+ console.error("Unhandled exception during request", {
36
+ method: requestEv.method,
37
+ url: requestEv.url.href,
38
+ headersSent: requestEv.headersSent,
39
+ error,
40
+ });
41
+ return;
42
+ }
43
+
44
+ console.error("Unhandled exception outside request", { error });
45
+ });
46
+
47
+ process.on("unhandledRejection", (reason) => {
48
+ const requestEv = getRequestEvent();
49
+ if (requestEv) {
50
+ console.error("Unhandled rejection during request", {
51
+ method: requestEv.method,
52
+ url: requestEv.url.href,
53
+ headersSent: requestEv.headersSent,
54
+ reason,
55
+ });
56
+ return;
57
+ }
58
+
59
+ console.error("Unhandled rejection outside request", { reason });
60
+ });
61
+
28
62
  Bun.serve({
63
+ maxRequestBodySize: 10 * 1024 * 1024,
29
64
  async fetch(request: Request) {
30
65
  const staticResponse = await staticFile(request);
31
66
  if (staticResponse) {
@@ -7,6 +7,7 @@
7
7
  * - https://qwik.dev/docs/deployments/gcp-cloud-run/
8
8
  *
9
9
  */
10
+ import { getRequestEvent } from "@qwik.dev/router";
10
11
  import {
11
12
  createQwikRouter,
12
13
  type PlatformNode,
@@ -77,6 +78,25 @@ const { router, staticFile } = createQwikRouter({
77
78
 
78
79
  const server = createServer();
79
80
 
81
+ // Optional request-aware diagnostics for crashes that escape request boundaries.
82
+ // This does not prevent Node from crashing, but it does provide better diagnostics for uncaught exceptions.
83
+ // See the Node documentation to handle uncaught exceptions and unhandled rejections in your app.
84
+ process.on("uncaughtExceptionMonitor", (error, origin) => {
85
+ const requestEv = getRequestEvent();
86
+ if (requestEv) {
87
+ console.error("Unhandled exception during request", {
88
+ origin,
89
+ method: requestEv.method,
90
+ url: requestEv.url.href,
91
+ headersSent: requestEv.headersSent,
92
+ error,
93
+ });
94
+ return;
95
+ }
96
+
97
+ console.error("Unhandled exception outside request", { origin, error });
98
+ });
99
+
80
100
  server.on("request", (req, res) => {
81
101
  for (const header of Object.entries(DEFAULT_HEADERS)) {
82
102
  res.setHeader(...header);
@@ -8,6 +8,7 @@
8
8
  * - https://docs.deno.com/runtime/tutorials/http_server
9
9
  *
10
10
  */
11
+ import { getRequestEvent } from "@qwik.dev/router";
11
12
  import { createQwikRouter } from "@qwik.dev/router/middleware/deno";
12
13
  import render from "./entry.ssr";
13
14
 
@@ -25,6 +26,46 @@ const port = Number(Deno.env.get("PORT") ?? 3009);
25
26
  /* eslint-disable */
26
27
  console.log(`Server starter: http://localhost:${port}/app/`);
27
28
 
29
+ // Optional request-aware diagnostics for crashes that escape request boundaries.
30
+ // This does not prevent Deno from crashing, but it does provide better diagnostics.
31
+ // See Deno runtime event docs for error and unhandled rejection behavior.
32
+ globalThis.addEventListener("error", (event: ErrorEvent) => {
33
+ const requestEv = getRequestEvent();
34
+ if (requestEv) {
35
+ console.error("Unhandled exception during request", {
36
+ method: requestEv.method,
37
+ url: requestEv.url.href,
38
+ headersSent: requestEv.headersSent,
39
+ error: event.error,
40
+ });
41
+ return;
42
+ }
43
+
44
+ console.error("Unhandled exception outside request", {
45
+ error: event.error,
46
+ });
47
+ });
48
+
49
+ globalThis.addEventListener(
50
+ "unhandledrejection",
51
+ (event: PromiseRejectionEvent) => {
52
+ const requestEv = getRequestEvent();
53
+ if (requestEv) {
54
+ console.error("Unhandled rejection during request", {
55
+ method: requestEv.method,
56
+ url: requestEv.url.href,
57
+ headersSent: requestEv.headersSent,
58
+ reason: event.reason,
59
+ });
60
+ return;
61
+ }
62
+
63
+ console.error("Unhandled rejection outside request", {
64
+ reason: event.reason,
65
+ });
66
+ },
67
+ );
68
+
28
69
  Deno.serve({ port }, async (request: Request, info: any) => {
29
70
  const staticResponse = await staticFile(request);
30
71
  if (staticResponse) {
@@ -7,6 +7,7 @@
7
7
  * - https://qwik.dev/docs/deployments/node/
8
8
  *
9
9
  */
10
+ import { getRequestEvent } from "@qwik.dev/router";
10
11
  import {
11
12
  createQwikRouter,
12
13
  type PlatformNode,
@@ -46,6 +47,25 @@ const { router } = createQwikRouter({
46
47
  // https://expressjs.com/
47
48
  const app = express();
48
49
 
50
+ // Optional request-aware diagnostics for crashes that escape request boundaries.
51
+ // This does not prevent Node from crashing, but it does provide better diagnostics for uncaught exceptions.
52
+ // See the Node documentation to handle uncaught exceptions and unhandled rejections in your app.
53
+ process.on("uncaughtExceptionMonitor", (error, origin) => {
54
+ const requestEv = getRequestEvent();
55
+ if (requestEv) {
56
+ console.error("Unhandled exception during request", {
57
+ origin,
58
+ method: requestEv.method,
59
+ url: requestEv.url.href,
60
+ headersSent: requestEv.headersSent,
61
+ error,
62
+ });
63
+ return;
64
+ }
65
+
66
+ console.error("Unhandled exception outside request", { origin, error });
67
+ });
68
+
49
69
  // Enable gzip compression
50
70
  // app.use(compression());
51
71
 
@@ -6,8 +6,8 @@
6
6
  },
7
7
  "dependencies": {
8
8
  "@fastify/compress": "^6.2.1",
9
- "@fastify/static": "^6.10.1",
10
- "fastify": "^5.7.3",
9
+ "@fastify/static": "^10.1.2",
10
+ "fastify": "^5.8.5",
11
11
  "fastify-plugin": "^4.5.0"
12
12
  },
13
13
  "devDependencies": {
@@ -7,6 +7,7 @@
7
7
  * - https://qwik.dev/docs/deployments/node/
8
8
  *
9
9
  */
10
+ import { getRequestEvent } from "@qwik.dev/router";
10
11
  import { type PlatformNode } from "@qwik.dev/router/middleware/node";
11
12
  import "dotenv/config";
12
13
  import Fastify from "fastify";
@@ -27,6 +28,25 @@ const assetsDir = join(distDir, "assets");
27
28
  const PORT = parseInt(process.env.PORT ?? "3000");
28
29
  const HOST = process.env.HOST ?? "0.0.0.0";
29
30
 
31
+ // Optional request-aware diagnostics for crashes that escape request boundaries.
32
+ // This does not prevent Node from crashing, but it does provide better diagnostics for uncaught exceptions.
33
+ // See the Node documentation to handle uncaught exceptions and unhandled rejections in your app.
34
+ process.on("uncaughtExceptionMonitor", (error, origin) => {
35
+ const requestEv = getRequestEvent();
36
+ if (requestEv) {
37
+ console.error("Unhandled exception during request", {
38
+ origin,
39
+ method: requestEv.method,
40
+ url: requestEv.url.href,
41
+ headersSent: requestEv.headersSent,
42
+ error,
43
+ });
44
+ return;
45
+ }
46
+
47
+ console.error("Unhandled exception outside request", { origin, error });
48
+ });
49
+
30
50
  const start = async () => {
31
51
  // Create the fastify server
32
52
  // https://fastify.dev/docs/latest/Guides/Getting-Started/
@@ -43,7 +43,16 @@ const qwikPlugin: FastifyPluginAsync<FastifyQwikOptions> = async (
43
43
  fastify.removeAllContentTypeParsers();
44
44
 
45
45
  fastify.setNotFoundHandler(async (request, response) => {
46
- await router(request.raw, response.raw, (err) => fastify.log.error(err));
46
+ await router(
47
+ request.raw,
48
+ response.raw,
49
+ (err) => {
50
+ if (err) {
51
+ response.send(err);
52
+ }
53
+ },
54
+ { bodyLimit: request.routeOptions.bodyLimit },
55
+ );
47
56
  });
48
57
  };
49
58
 
@@ -7,6 +7,7 @@
7
7
  * - https://qwik.dev/docs/deployments/node/
8
8
  *
9
9
  */
10
+ import { getRequestEvent } from "@qwik.dev/router";
10
11
  import { createQwikRouter } from "@qwik.dev/router/middleware/node";
11
12
  import { createServer } from "node:http";
12
13
  import render from "./entry.ssr";
@@ -24,6 +25,25 @@ const { router, staticFile } = createQwikRouter({
24
25
 
25
26
  const server = createServer();
26
27
 
28
+ // Optional request-aware diagnostics for crashes that escape request boundaries.
29
+ // This does not prevent Node from crashing, but it does provide better diagnostics for uncaught exceptions.
30
+ // See the Node documentation to handle uncaught exceptions and unhandled rejections in your app.
31
+ process.on("uncaughtExceptionMonitor", (error, origin) => {
32
+ const requestEv = getRequestEvent();
33
+ if (requestEv) {
34
+ console.error("Unhandled exception during request", {
35
+ origin,
36
+ method: requestEv.method,
37
+ url: requestEv.url.href,
38
+ headersSent: requestEv.headersSent,
39
+ error,
40
+ });
41
+ return;
42
+ }
43
+
44
+ console.error("Unhandled exception outside request", { origin, error });
45
+ });
46
+
27
47
  server.on("request", (req, res) => {
28
48
  staticFile(req, res, () => {
29
49
  router(req, res, () => {});
@@ -20,7 +20,7 @@
20
20
  "@qwik.dev/core": "workspace:*"
21
21
  },
22
22
  "devDependencies": {
23
- "vite": "7.3.1"
23
+ "vite": "7.3.5"
24
24
  },
25
25
  "scripts": {
26
26
  "dev": "vite",
@@ -30,7 +30,7 @@
30
30
  "@types/better-sqlite3": "^7.6.12",
31
31
  "drizzle-kit": "^0.30.3",
32
32
  "better-sqlite3": "^11.8.1",
33
- "drizzle-orm": "^0.39.0"
33
+ "drizzle-orm": "^0.45.2"
34
34
  },
35
35
  "scripts": {
36
36
  "drizzle:generate": "drizzle-kit generate",
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "devDependencies": {
13
13
  "@vitest/ui": "^0.34.6",
14
- "vitest": "^0.34.6"
14
+ "vitest": "^4.1.10"
15
15
  },
16
16
  "scripts": {
17
17
  "test.unit": "vitest components",
@@ -17,13 +17,15 @@ declare interface AddRootFn {
17
17
  (obj: unknown, returnRef: true): SeenRef;
18
18
  }
19
19
 
20
- declare type AllSignalFlags = SignalFlags | WrappedSignalFlags | SerializationSignalFlags | AsyncSignalFlags;
20
+ declare type AllSignalFlags = ComputedSignalFlags | SerializationSignalFlags | AsyncSignalFlags;
21
21
 
22
22
  declare const enum AsyncSignalFlags {
23
23
  EAGER_CLEANUP = 32,
24
24
  CLIENT_ONLY = 64,
25
- CLEAR_ON_INVALIDATE = 128,
26
- NO_POLL = 256
25
+ /** The compute fn is async: the async engine (jobs, loading, error) is active */
26
+ ASYNC_MODE = 512,
27
+ /** Invoke the compute fn AsyncSignal-style: pass the ComputeCtx argument, no auto-tracking */
28
+ CTX_ARG = 1024
27
29
  }
28
30
 
29
31
  /** Class for back reference to the EffectSubscription */
@@ -56,6 +58,12 @@ declare const enum ChoreBits {
56
58
  DIRTY_MASK = 1023
57
59
  }
58
60
 
61
+ declare const enum ComputedSignalFlags {
62
+ INVALID = 1,
63
+ RUN_EFFECTS = 2,
64
+ PRESERVE_ON_SEQ_CLEANUP = 4
65
+ }
66
+
59
67
  /** @internal */
60
68
  declare const _CONST_PROPS: unique symbol;
61
69
 
@@ -190,15 +198,6 @@ export declare const createDOM: ({ html }?: {
190
198
  userEvent: (queryOrElement: string | Element | keyof HTMLElementTagNameMap | null, eventNameCamel: string | keyof WindowEventMap, eventPayload?: any) => Promise<Event | null>;
191
199
  }>;
192
200
 
193
- declare interface DescriptorBase<T = unknown, B = unknown> extends BackRef {
194
- $flags$: number;
195
- $index$: number;
196
- $el$: HostElement;
197
- $qrl$: QRLInternal<T>;
198
- $state$: B | undefined;
199
- $destroy$: (() => void) | null;
200
- }
201
-
202
201
  /** @public */
203
202
  declare interface DevJSX {
204
203
  fileName: string;
@@ -472,6 +471,7 @@ declare class LazyRef<TYPE = unknown> {
472
471
  readonly $symbolFn$: undefined | null | (() => Promise<Record<string, TYPE>>);
473
472
  $ref$?: (null | ValueOrPromise<TYPE>) | undefined;
474
473
  $container$: Container | undefined;
474
+ $hasMovedCaptures$?: boolean;
475
475
  dev?: QRLDev | null | undefined;
476
476
  qrls?: Set<any>;
477
477
  constructor($chunk$: string | null, $symbol$: string, $symbolFn$: undefined | null | (() => Promise<Record<string, TYPE>>), $ref$?: (null | ValueOrPromise<TYPE>) | undefined, container?: Container | null);
@@ -678,6 +678,8 @@ declare type QRL<TYPE = unknown> = {
678
678
 
679
679
  declare type QrlArgs<T> = T extends (...args: infer ARGS) => any ? ARGS : unknown[];
680
680
 
681
+ declare type QrlCaptures = Readonly<unknown[]> | string | null;
682
+
681
683
  /** @public */
682
684
  declare interface QRLDev {
683
685
  file: string;
@@ -692,8 +694,9 @@ declare type QRLInternalMethods<TYPE> = {
692
694
  readonly $chunk$: string | null;
693
695
  readonly $symbol$: string;
694
696
  readonly $hash$: string;
695
- /** If it's a string it's serialized */
696
- readonly $captures$?: Readonly<unknown[]> | string | null;
697
+ /** Captures are stored lazily after deserialization. */
698
+ readonly $captures$?: QrlCaptures;
699
+ readonly $hasMovedCaptures$?: boolean;
697
700
  dev?: QRLDev | null;
698
701
  resolve(container?: Container): Promise<TYPE>;
699
702
  resolved: undefined | TYPE;
@@ -710,7 +713,9 @@ declare type QRLInternalMethods<TYPE> = {
710
713
  * method but we need to have a stable name because it gets called in user code by the optimizer,
711
714
  * after the $name$ props are mangled
712
715
  */
713
- w(captures: Readonly<unknown[]> | string | null): QRLInternal<TYPE>;
716
+ w(captures: QrlCaptures): QRLInternal<TYPE>;
717
+ /** Mark that the handler receives captures moved to its element. */
718
+ m(): QRLInternal<TYPE>;
714
719
  /**
715
720
  * "set ref" - Set the ref of the QRL. It's an internal method but we need to have a stable name
716
721
  * because it gets called in user code by the optimizer, after the $name$ props are mangled
@@ -819,11 +824,6 @@ declare interface Signal<T = any> {
819
824
  trigger(): void;
820
825
  }
821
826
 
822
- declare const enum SignalFlags {
823
- INVALID = 1,
824
- RUN_EFFECTS = 2
825
- }
826
-
827
827
  declare class SignalImpl<T = any> implements Signal<T> {
828
828
  $untrackedValue$: T;
829
829
  /** Store a list of effects which are dependent on this signal. */
@@ -859,11 +859,13 @@ declare interface SimplifiedServerRequestEvent<T = unknown> {
859
859
  declare interface SSRInternalStreamWriter extends StreamWriter_2 {
860
860
  writeRootRef(id: number): ValueOrPromise<void>;
861
861
  writeRootRefPath(path: number[]): ValueOrPromise<void>;
862
+ writeRootRefDelta(id: number, base: number): ValueOrPromise<void>;
862
863
  toString(remap?: number[]): string;
863
864
  }
864
865
 
865
866
  declare const enum SsrNodeFlags {
866
- Updatable = 1
867
+ Updatable = 1,
868
+ WarnedStreamedChore = 2
867
869
  }
868
870
 
869
871
  /** @public */
@@ -876,6 +878,8 @@ export declare function ssrRenderToDom(jsx: JSXOutput, opts?: {
876
878
  qwikLoader?: boolean;
877
879
  /** Override the SSR container tag name. */
878
880
  containerTagName?: string;
881
+ /** Root-count threshold for eager yielded state prewarm during client resume. */
882
+ statePrewarm?: number | false;
879
883
  /** Stream rendered chunks while still collecting the final HTML. */
880
884
  stream?: StreamWriter;
881
885
  /** Configure SSR streaming. */
@@ -914,20 +918,29 @@ declare class SubscriptionData {
914
918
  declare type SymbolToChunkResolver = (symbol: string) => string;
915
919
 
916
920
  /** @internal */
917
- declare class Task<T = unknown, B = T> extends BackRef implements DescriptorBase<unknown, Signal<B>> {
918
- $flags$: number;
921
+ declare class Task<T = unknown, B = T> extends BackRef {
922
+ $flags$: TaskFlags;
919
923
  $index$: number;
920
924
  $el$: HostElement;
921
925
  $qrl$: QRLInternal<T>;
922
- $state$: Signal<B> | undefined;
923
926
  $destroy$: (() => void) | null;
924
927
  $destroyPromise$: Promise<void> | undefined;
925
928
  $taskPromise$: Promise<void> | null;
926
- constructor($flags$: number, $index$: number, $el$: HostElement, $qrl$: QRLInternal<T>, $state$: Signal<B> | undefined, $destroy$: (() => void) | null);
929
+ constructor($flags$: TaskFlags, $index$: number, $el$: HostElement, $qrl$: QRLInternal<T>, $destroy$: (() => void) | null);
927
930
  }
928
931
 
929
932
  declare const TaskEvent = "qTask";
930
933
 
934
+ /** @internal */
935
+ declare const enum TaskFlags {
936
+ VISIBLE_TASK = 1,
937
+ TASK = 2,
938
+ DIRTY = 4,
939
+ RENDER_BLOCKING = 8,
940
+ NEEDS_CLEANUP = 16,
941
+ EVENTS_REGISTERED = 32
942
+ }
943
+
931
944
  /** @public */
932
945
  declare interface TestPlatform extends CorePlatform {
933
946
  /**
@@ -995,7 +1008,7 @@ declare abstract class VNode implements BackRef {
995
1008
 
996
1009
  /** @public */
997
1010
  export declare function vnode_fromJSX(jsx: JSXOutput): {
998
- vParent: _VirtualVNode | _ElementVNode;
1011
+ vParent: _ElementVNode | _VirtualVNode;
999
1012
  vNode: _VNode | null;
1000
1013
  document: _QDocument;
1001
1014
  container: ClientContainer_2;
@@ -1102,10 +1115,6 @@ export declare function walkJSX(jsx: JSXOutput, apply: {
1102
1115
  text: (text: _Stringifiable) => void;
1103
1116
  }): void;
1104
1117
 
1105
- declare const enum WrappedSignalFlags {
1106
- UNWRAP = 4
1107
- }
1108
-
1109
1118
  declare class WrappedSignalImpl<T> extends SignalImpl<T> {
1110
1119
  $args$: any[];
1111
1120
  $func$: (...args: any[]) => T;
@@ -1113,7 +1122,7 @@ declare class WrappedSignalImpl<T> extends SignalImpl<T> {
1113
1122
  $flags$: AllSignalFlags;
1114
1123
  $hostElement$: HostElement | undefined;
1115
1124
  [_EFFECT_BACK_REF]: Map<EffectProperty | string, EffectSubscription> | undefined;
1116
- constructor(container: Container | null, fn: (...args: any[]) => T, args: any[], fnStr: string | null, flags?: SignalFlags);
1125
+ constructor(container: Container | null, fn: (...args: any[]) => T, args: any[], fnStr: string | null, flags?: AllSignalFlags);
1117
1126
  invalidate(): void;
1118
1127
  get untrackedValue(): T;
1119
1128
  $computeIfNeeded$(): void;