@qwik.dev/core 2.0.0-beta.2 → 2.0.0-beta.21

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 (136) hide show
  1. package/bindings/qwik.darwin-arm64.node +0 -0
  2. package/bindings/qwik.linux-x64-gnu.node +0 -0
  3. package/bindings/qwik.win32-x64-msvc.node +0 -0
  4. package/bindings/qwik_wasm_bg.wasm +0 -0
  5. package/dist/backpatch/index.d.ts +2 -0
  6. package/dist/backpatch/index.mjs +5 -0
  7. package/dist/backpatch/package.json +8 -0
  8. package/dist/backpatch-executor.debug.js +39 -0
  9. package/dist/backpatch-executor.js +1 -0
  10. package/dist/build/package.json +1 -1
  11. package/dist/cli.mjs +5633 -0
  12. package/dist/core-internal.d.ts +673 -396
  13. package/dist/core.min.mjs +2 -1
  14. package/dist/core.mjs +10168 -8294
  15. package/dist/core.mjs.map +1 -1
  16. package/dist/core.prod.mjs +5745 -4592
  17. package/dist/insights/vite/index.mjs +10 -10
  18. package/dist/loader/index.mjs +2 -2
  19. package/dist/loader/package.json +1 -1
  20. package/dist/optimizer.d.ts +16 -38
  21. package/dist/optimizer.mjs +2608 -3719
  22. package/dist/preloader.mjs +8 -11
  23. package/dist/qwikloader.debug.js +152 -132
  24. package/dist/qwikloader.js +1 -1
  25. package/dist/server.d.ts +38 -15
  26. package/dist/server.mjs +1209 -927
  27. package/dist/starters/adapters/aws-lambda/adapters/aws-lambda/{vite.config.mts → vite.config.ts} +2 -2
  28. package/dist/starters/adapters/aws-lambda/package.json +3 -2
  29. package/dist/starters/adapters/aws-lambda/src/entry_aws-lambda.tsx +2 -6
  30. package/dist/starters/adapters/azure-swa/adapters/azure-swa/{vite.config.mts → vite.config.ts} +2 -2
  31. package/dist/starters/adapters/azure-swa/package.json +3 -2
  32. package/dist/starters/adapters/azure-swa/src/entry.azure-swa.tsx +2 -3
  33. package/dist/starters/adapters/bun/adapters/bun/{vite.config.mts → vite.config.ts} +3 -3
  34. package/dist/starters/adapters/bun/package.json +3 -2
  35. package/dist/starters/adapters/bun/src/entry.bun.ts +0 -2
  36. package/dist/starters/adapters/cloud-run/adapters/cloud-run/{vite.config.mts → vite.config.ts} +2 -2
  37. package/dist/starters/adapters/cloud-run/package.json +3 -2
  38. package/dist/starters/adapters/cloud-run/src/entry.cloud-run.tsx +1 -3
  39. package/dist/starters/adapters/cloudflare-pages/adapters/cloudflare-pages/{vite.config.mts → vite.config.ts} +2 -2
  40. package/dist/starters/adapters/cloudflare-pages/package.json +3 -2
  41. package/dist/starters/adapters/cloudflare-pages/src/entry.cloudflare-pages.tsx +2 -3
  42. package/dist/starters/adapters/cloudflare-workers/README.md +52 -0
  43. package/dist/starters/adapters/cloudflare-workers/adapters/cloudflare-workers/vite.config.ts +15 -0
  44. package/dist/starters/adapters/cloudflare-workers/gitignore +3 -0
  45. package/dist/starters/adapters/cloudflare-workers/package.json +31 -0
  46. package/dist/starters/adapters/cloudflare-workers/public/.assetsignore +4 -0
  47. package/dist/starters/adapters/cloudflare-workers/public/_headers +11 -0
  48. package/dist/starters/adapters/cloudflare-workers/public/_redirects +1 -0
  49. package/dist/starters/adapters/cloudflare-workers/src/entry.cloudflare-pages.tsx +23 -0
  50. package/dist/starters/adapters/cloudflare-workers/worker-configuration.d.ts +5 -0
  51. package/dist/starters/adapters/cloudflare-workers/wrangler.jsonc +41 -0
  52. package/dist/starters/adapters/deno/adapters/deno/{vite.config.mts → vite.config.ts} +2 -2
  53. package/dist/starters/adapters/deno/package.json +3 -2
  54. package/dist/starters/adapters/deno/src/entry.deno.ts +0 -2
  55. package/dist/starters/adapters/express/adapters/express/{vite.config.mts → vite.config.ts} +2 -2
  56. package/dist/starters/adapters/express/package.json +4 -3
  57. package/dist/starters/adapters/express/src/entry.express.tsx +1 -3
  58. package/dist/starters/adapters/fastify/adapters/fastify/{vite.config.mts → vite.config.ts} +2 -2
  59. package/dist/starters/adapters/fastify/package.json +3 -2
  60. package/dist/starters/adapters/fastify/src/entry.fastify.tsx +1 -1
  61. package/dist/starters/adapters/fastify/src/plugins/fastify-qwik.ts +1 -2
  62. package/dist/starters/adapters/firebase/adapters/firebase/{vite.config.mts → vite.config.ts} +2 -2
  63. package/dist/starters/adapters/firebase/package.json +3 -2
  64. package/dist/starters/adapters/firebase/src/entry-firebase.tsx +2 -3
  65. package/dist/starters/adapters/netlify-edge/adapters/netlify-edge/{vite.config.mts → vite.config.ts} +2 -2
  66. package/dist/starters/adapters/netlify-edge/package.json +3 -2
  67. package/dist/starters/adapters/netlify-edge/src/entry.netlify-edge.tsx +2 -3
  68. package/dist/starters/adapters/node-server/adapters/node-server/{vite.config.mts → vite.config.ts} +2 -2
  69. package/dist/starters/adapters/node-server/package.json +3 -2
  70. package/dist/starters/adapters/node-server/src/entry.node-server.tsx +0 -2
  71. package/dist/starters/adapters/{static/adapters/static/vite.config.mts → ssg/adapters/ssg/vite.config.ts} +3 -3
  72. package/dist/starters/adapters/ssg/package.json +20 -0
  73. package/dist/starters/adapters/vercel-edge/README.md +2 -2
  74. package/dist/starters/adapters/vercel-edge/adapters/vercel-edge/{vite.config.mts → vite.config.ts} +2 -2
  75. package/dist/starters/adapters/vercel-edge/package.json +3 -2
  76. package/dist/starters/adapters/vercel-edge/src/entry.vercel-edge.tsx +2 -3
  77. package/dist/starters/adapters/vercel-edge/vercel.json +1 -1
  78. package/dist/starters/features/auth/package.json +1 -1
  79. package/dist/starters/features/compiled-i18n/package.json +37 -0
  80. package/dist/starters/features/compiled-i18n/src/components/locale-selector/locale-selector.tsx +30 -0
  81. package/dist/starters/features/compiled-i18n/src/entry.ssr.tsx +31 -0
  82. package/dist/starters/features/compiled-i18n/src/routes/plugin@compiled-i18n.ts +28 -0
  83. package/dist/starters/features/csr/index.html +23 -0
  84. package/dist/starters/features/csr/package.json +29 -0
  85. package/dist/starters/features/csr/src/root.tsx +15 -0
  86. package/dist/starters/features/csr/vite.config.ts +13 -0
  87. package/dist/starters/features/cypress/src/actions/example.action.ts +5 -0
  88. package/dist/starters/features/cypress/src/components/example/example.cy.tsx +50 -8
  89. package/dist/starters/features/cypress/src/components/example/example.tsx +13 -3
  90. package/dist/starters/features/cypress/src/loaders/example.loader.ts +5 -0
  91. package/dist/starters/features/pandacss/package.json +1 -1
  92. package/dist/starters/features/playwright/playwright-report/index.html +953 -930
  93. package/dist/starters/features/postcss/postcss.config.js +1 -1
  94. package/dist/starters/features/storybook/.storybook/tsconfig.json +0 -1
  95. package/dist/starters/features/styled-vanilla-extract/package.json +2 -1
  96. package/dist/starters/features/tailwind/package.json +2 -2
  97. package/dist/starters/features/tailwind/prettier.config.js +10 -0
  98. package/dist/starters/features/tailwind-v3/package.json +1 -1
  99. package/dist/starters/features/tailwind-v3/prettier.config.js +10 -0
  100. package/dist/testing/index.d.ts +775 -6
  101. package/dist/testing/index.mjs +14298 -10837
  102. package/dist/testing/package.json +1 -1
  103. package/handlers.mjs +1 -1
  104. package/package.json +30 -55
  105. package/public.d.ts +3 -1
  106. package/{qwik-cli.cjs → qwik-cli.mjs} +1 -1
  107. package/server.d.ts +2 -0
  108. package/bindings/qwik.darwin-x64.node +0 -0
  109. package/bindings/qwik.wasm.cjs +0 -471
  110. package/dist/build/index.cjs +0 -35
  111. package/dist/build/index.cjs.map +0 -7
  112. package/dist/build/index.dev.cjs +0 -37
  113. package/dist/build/index.dev.cjs.map +0 -7
  114. package/dist/build/index.prod.cjs +0 -37
  115. package/dist/build/index.prod.cjs.map +0 -7
  116. package/dist/cli.cjs +0 -5545
  117. package/dist/core.cjs +0 -11754
  118. package/dist/core.cjs.map +0 -1
  119. package/dist/core.prod.cjs +0 -5647
  120. package/dist/insights/index.qwik.cjs +0 -1
  121. package/dist/insights/vite/index.cjs +0 -1
  122. package/dist/loader/index.cjs +0 -4
  123. package/dist/optimizer.cjs +0 -4020
  124. package/dist/preloader.cjs +0 -269
  125. package/dist/server.cjs +0 -3027
  126. package/dist/starters/adapters/static/package.json +0 -19
  127. package/dist/starters/features/localize/package.json +0 -37
  128. package/dist/starters/features/localize/src/entry.ssr.tsx +0 -30
  129. package/dist/starters/features/localize/src/locales/message.en.json +0 -8
  130. package/dist/starters/features/localize/src/locales/message.it.json +0 -8
  131. package/dist/starters/features/localize/src/routes/[locale]/i18n-utils.ts +0 -94
  132. package/dist/starters/features/localize/src/routes/[locale]/index.tsx +0 -52
  133. package/dist/starters/features/localize/src/routes/[locale]/layout.tsx +0 -12
  134. package/dist/starters/features/tailwind/.prettierrc.js +0 -3
  135. package/dist/testing/index.cjs +0 -33287
  136. /package/dist/starters/adapters/{static → ssg}/README.md +0 -0
@@ -29,12 +29,9 @@ const trigger = () => {
29
29
  const e = queue[0];
30
30
  const t = e.u;
31
31
  const o = 1 - t;
32
- const n = graph ? (
33
- // The more likely the bundle, the more simultaneous preloads we want to allow
34
- Math.max(1, config.o * o)
35
- ) : (
36
- // While the graph is not available, we limit to 2 preloads
37
- 2
32
+ const n = graph ? config.o : (
33
+ // While the graph is not available, we limit to 5 preloads
34
+ 5
38
35
  );
39
36
  if (o >= 0.99 || preloadCount < n) {
40
37
  queue.shift();
@@ -71,13 +68,13 @@ const preloadOne = (e) => {
71
68
  doc.head.appendChild(o);
72
69
  };
73
70
  const adjustProbabilities = (e, t, o) => {
74
- if (o == null ? void 0 : o.has(e)) return;
71
+ if (o?.has(e)) return;
75
72
  const n = e.u;
76
73
  e.u = t;
77
74
  if (n - e.u < 0.01) return;
78
75
  if (
79
76
  // don't queue until we have initialized the preloader
80
- base != null && e.i < BundleImportState_Preload && e.u < config.l
77
+ base != null && e.i < BundleImportState_Preload
81
78
  ) {
82
79
  if (e.i === BundleImportState_None) {
83
80
  e.i = BundleImportState_Queued;
@@ -87,14 +84,14 @@ const adjustProbabilities = (e, t, o) => {
87
84
  queueDirty = 1;
88
85
  }
89
86
  if (e.h) {
90
- o || (o = /* @__PURE__ */ new Set());
87
+ o ||= /* @__PURE__ */ new Set();
91
88
  o.add(e);
92
89
  const t2 = 1 - e.u;
93
90
  for (const n2 of e.h) {
94
91
  const e2 = getBundle(n2.m);
95
92
  if (e2.u === 0) continue;
96
93
  let r;
97
- if (n2.S > 0.5 && (t2 === 1 || t2 >= 0.99 && depsCount < 100)) {
94
+ if (t2 === 1 || t2 >= 0.99 && depsCount < 100) {
98
95
  depsCount++;
99
96
  r = Math.min(0.01, 1 - n2.S);
100
97
  } else {
@@ -114,7 +111,7 @@ const handleBundle = (e, t) => {
114
111
  };
115
112
  let depsCount;
116
113
  const preload = (e, t) => {
117
- if (!(e == null ? void 0 : e.length)) return;
114
+ if (!e?.length) return;
118
115
  depsCount = 0;
119
116
  let o = t ? 1 - t : 0.4;
120
117
  if (Array.isArray(e)) for (let t2 = e.length - 1; t2 >= 0; t2--) {
@@ -1,7 +1,11 @@
1
1
  const doc = document;
2
2
  const win = window;
3
+ const windowPrefix = "w";
4
+ const documentPrefix = "d";
3
5
  const events = /* @__PURE__ */ new Set();
4
6
  const roots = /* @__PURE__ */ new Set([doc]);
7
+ const symbols = /* @__PURE__ */ new Map();
8
+ let observer;
5
9
  let hasInitialized;
6
10
  const nativeQuerySelectorAll = (root, selector) => Array.from(root.querySelectorAll(selector));
7
11
  const querySelectorAll = (query) => {
@@ -9,28 +13,15 @@ const querySelectorAll = (query) => {
9
13
  roots.forEach((root) => elements.push(...nativeQuerySelectorAll(root, query)));
10
14
  return elements;
11
15
  };
16
+ const addEventListener = (el, eventName, handler, capture = false) => el.addEventListener(eventName, handler, { capture, passive: false });
12
17
  const findShadowRoots = (fragment) => {
13
- processEventOrNode(fragment);
18
+ addEventOrRoot(fragment);
14
19
  nativeQuerySelectorAll(fragment, "[q\\:shadowroot]").forEach((parent) => {
15
20
  const shadowRoot = parent.shadowRoot;
16
21
  shadowRoot && findShadowRoots(shadowRoot);
17
22
  });
18
23
  };
19
24
  const isPromise = (promise) => promise && typeof promise.then === "function";
20
- let doNotClean = true;
21
- const broadcast = (infix, ev, type = ev.type) => {
22
- let found = doNotClean;
23
- querySelectorAll("[on" + infix + "\\:" + type + "]").forEach((el) => {
24
- found = true;
25
- dispatch(el, infix, ev, type);
26
- });
27
- if (!found) {
28
- window[infix.slice(1)].removeEventListener(
29
- type,
30
- infix === "-window" ? processWindowEvent : processDocumentEvent
31
- );
32
- }
33
- };
34
25
  const resolveContainer = (containerEl) => {
35
26
  if (containerEl._qwikjson_ === void 0) {
36
27
  const parentJSON = containerEl === doc.documentElement ? doc.body : containerEl;
@@ -46,64 +37,59 @@ const resolveContainer = (containerEl) => {
46
37
  }
47
38
  }
48
39
  };
49
- const createEvent = (eventName, detail) => new CustomEvent(eventName, {
50
- detail
40
+ const createEvent = (eventName, detail) => new CustomEvent(eventName, { detail });
41
+ const emitEvent = (eventName, detail) => {
42
+ doc.dispatchEvent(createEvent(eventName, detail));
43
+ };
44
+ const camelToKebab = (str) => str.replace(/([A-Z-])/g, (a) => "-" + a.toLowerCase());
45
+ const kebabToCamel = (eventName) => eventName.replace(/-./g, (a) => a[1].toUpperCase());
46
+ const parseKebabEvent = (event) => ({
47
+ scope: event.charAt(0),
48
+ eventName: kebabToCamel(event.slice(2))
51
49
  });
52
- const dispatch = async (element, scope, ev, eventName = ev.type) => {
53
- const attrName = "on" + scope + ":" + eventName;
54
- if (element.hasAttribute("preventdefault:" + eventName)) {
55
- ev.preventDefault();
56
- }
57
- if (element.hasAttribute("stoppropagation:" + eventName)) {
58
- ev.stopPropagation();
50
+ const dispatch = async (element, ev, scopedKebabName, kebabName) => {
51
+ if (kebabName) {
52
+ if (element.hasAttribute("preventdefault:" + kebabName)) {
53
+ ev.preventDefault();
54
+ }
55
+ if (element.hasAttribute("stoppropagation:" + kebabName)) {
56
+ ev.stopPropagation();
57
+ }
59
58
  }
60
- const ctx = element._qc_;
61
- const relevantListeners = ctx && ctx.li.filter((li) => li[0] === attrName);
62
- if (relevantListeners && relevantListeners.length > 0) {
63
- for (const listener of relevantListeners) {
64
- const results = listener[1].getFn([element, ev], () => element.isConnected)(ev, element);
65
- const cancelBubble = ev.cancelBubble;
66
- if (isPromise(results)) {
67
- await results;
68
- }
69
- if (cancelBubble) {
70
- ev.stopPropagation();
59
+ const handlers = element._qDispatch?.[scopedKebabName];
60
+ if (handlers) {
61
+ if (handlers.length) {
62
+ for (const handler of handlers) {
63
+ const result = handler?.(ev, element);
64
+ if (isPromise(result)) {
65
+ await result;
66
+ }
71
67
  }
68
+ } else {
69
+ await handlers(ev, element);
72
70
  }
73
71
  return;
74
72
  }
75
- const attrValue = element.getAttribute(attrName);
76
- const qDispatchEvent = element.qDispatchEvent;
77
- if (qDispatchEvent) {
78
- return qDispatchEvent(ev, scope);
79
- }
73
+ const attrValue = element.getAttribute("q-" + scopedKebabName);
80
74
  if (attrValue) {
81
75
  const container = element.closest(
82
76
  "[q\\:container]:not([q\\:container=html]):not([q\\:container=text])"
83
77
  );
84
78
  const qBase = container.getAttribute("q:base");
85
- const qVersion = container.getAttribute("q:version") || "unknown";
86
- const qManifest = container.getAttribute("q:manifest-hash") || "dev";
87
79
  const base = new URL(qBase, doc.baseURI);
88
- for (const qrl of attrValue.split("\n")) {
89
- const url = new URL(qrl, base);
90
- const href = url.href;
91
- const symbol = url.hash.replace(/^#?([^?[|]*).*$/, "$1") || "default";
80
+ for (const qrl of attrValue.split("|")) {
92
81
  const reqTime = performance.now();
93
- let handler;
94
- let importError;
95
- let error;
96
- const isSync = qrl.startsWith("#");
82
+ const [chunk, symbol, capturedIds] = qrl.split("#");
97
83
  const eventData = {
98
84
  qBase,
99
- qManifest,
100
- qVersion,
101
- href,
102
85
  symbol,
103
86
  element,
104
87
  reqTime
105
88
  };
106
- if (isSync) {
89
+ let handler;
90
+ let importError;
91
+ let error;
92
+ if (chunk === "") {
107
93
  const hash = container.getAttribute("q:instance");
108
94
  handler = (doc["qFuncs_" + hash] || [])[Number.parseInt(symbol)];
109
95
  if (!handler) {
@@ -111,22 +97,28 @@ const dispatch = async (element, scope, ev, eventName = ev.type) => {
111
97
  error = new Error("sym:" + symbol);
112
98
  }
113
99
  } else {
114
- emitEvent("qsymbol", eventData);
115
- const uri = url.href.split("#")[0];
116
- try {
117
- const module = import(
118
- /* @vite-ignore */
119
- uri
120
- );
121
- resolveContainer(container);
122
- handler = (await module)[symbol];
123
- if (!handler) {
124
- importError = "no-symbol";
125
- error = new Error(`${symbol} not in ${uri}`);
100
+ const key = `${symbol}|${qBase}|${chunk}`;
101
+ handler = symbols.get(key);
102
+ if (!handler) {
103
+ const href = new URL(chunk, base).href;
104
+ try {
105
+ const module = import(
106
+ /* @vite-ignore */
107
+ href
108
+ );
109
+ resolveContainer(container);
110
+ handler = (await module)[symbol];
111
+ if (!handler) {
112
+ importError = "no-symbol";
113
+ error = new Error(`${symbol} not in ${href}`);
114
+ } else {
115
+ symbols.set(key, handler);
116
+ emitEvent("qsymbol", eventData);
117
+ }
118
+ } catch (err) {
119
+ importError = "async";
120
+ error = err;
126
121
  }
127
- } catch (err) {
128
- importError || (importError = "async");
129
- error = err;
130
122
  }
131
123
  }
132
124
  if (!handler) {
@@ -136,110 +128,138 @@ const dispatch = async (element, scope, ev, eventName = ev.type) => {
136
128
  ...eventData
137
129
  });
138
130
  console.error(error);
139
- break;
131
+ continue;
140
132
  }
141
- const previousCtx = doc.__q_context__;
142
133
  if (element.isConnected) {
143
134
  try {
144
- doc.__q_context__ = [element, ev, url];
145
- const results = handler(ev, element);
146
- if (isPromise(results)) {
147
- await results;
135
+ const result = handler.call(capturedIds, ev, element);
136
+ if (isPromise(result)) {
137
+ await result;
148
138
  }
149
139
  } catch (error2) {
150
140
  emitEvent("qerror", { error: error2, ...eventData });
151
- } finally {
152
- doc.__q_context__ = previousCtx;
153
141
  }
154
142
  }
155
143
  }
156
144
  }
157
145
  };
158
- const emitEvent = (eventName, detail) => {
159
- doc.dispatchEvent(createEvent(eventName, detail));
160
- };
161
- const camelToKebab = (str) => str.replace(/([A-Z])/g, (a) => "-" + a.toLowerCase());
162
- const processDocumentEvent = async (ev) => {
163
- let type = camelToKebab(ev.type);
146
+ const processElementEvent = async (ev) => {
147
+ const kebabName = camelToKebab(ev.type);
148
+ const scopedKebabName = "e:" + kebabName;
164
149
  let element = ev.target;
165
- broadcast("-document", ev, type);
166
150
  while (element && element.getAttribute) {
167
- const results = dispatch(element, "", ev, type);
168
- let cancelBubble = ev.cancelBubble;
151
+ const results = dispatch(element, ev, scopedKebabName, kebabName);
152
+ const doBubble = ev.bubbles && !ev.cancelBubble;
169
153
  if (isPromise(results)) {
170
154
  await results;
171
155
  }
172
- cancelBubble || (cancelBubble = cancelBubble || ev.cancelBubble || element.hasAttribute("stoppropagation:" + ev.type));
173
- element = ev.bubbles && cancelBubble !== true ? element.parentElement : null;
156
+ element = doBubble && ev.bubbles && !ev.cancelBubble ? element.parentElement : null;
174
157
  }
175
158
  };
159
+ const broadcast = (infix, ev) => {
160
+ const kebabName = camelToKebab(ev.type);
161
+ const scopedKebabName = infix + ":" + kebabName;
162
+ querySelectorAll("[q-" + infix + "\\:" + kebabName + "]").forEach(
163
+ (el) => dispatch(el, ev, scopedKebabName, kebabName)
164
+ );
165
+ };
166
+ const processDocumentEvent = async (ev) => {
167
+ broadcast(documentPrefix, ev);
168
+ };
176
169
  const processWindowEvent = (ev) => {
177
- broadcast("-window", ev, camelToKebab(ev.type));
170
+ broadcast(windowPrefix, ev);
178
171
  };
179
172
  const processReadyStateChange = () => {
180
- var _a;
181
173
  const readyState = doc.readyState;
182
- if (!hasInitialized && (readyState == "interactive" || readyState == "complete")) {
183
- roots.forEach(findShadowRoots);
174
+ if (readyState == "interactive" || readyState == "complete") {
184
175
  hasInitialized = 1;
185
- emitEvent("qinit");
186
- const riC = (_a = win.requestIdleCallback) != null ? _a : win.setTimeout;
187
- riC.bind(win)(() => emitEvent("qidle"));
188
- if (events.has("qvisible")) {
189
- const results = querySelectorAll("[on\\:qvisible]");
190
- const observer = new IntersectionObserver((entries) => {
176
+ roots.forEach(findShadowRoots);
177
+ if (events.has("d:qinit")) {
178
+ events.delete("d:qinit");
179
+ const ev = createEvent("qinit");
180
+ querySelectorAll("[q-d\\:qinit]").forEach((el) => {
181
+ dispatch(el, ev, "d:qinit");
182
+ el.removeAttribute("q-d:qinit");
183
+ });
184
+ }
185
+ if (events.has("d:qidle")) {
186
+ events.delete("d:qidle");
187
+ const riC = win.requestIdleCallback ?? win.setTimeout;
188
+ riC.bind(win)(() => {
189
+ const ev = createEvent("qidle");
190
+ querySelectorAll("[q-d\\:qidle]").forEach((el) => {
191
+ dispatch(el, ev, "d:qidle");
192
+ el.removeAttribute("q-d:qidle");
193
+ });
194
+ });
195
+ }
196
+ if (events.has("e:qvisible")) {
197
+ observer || (observer = new IntersectionObserver((entries) => {
191
198
  for (const entry of entries) {
192
199
  if (entry.isIntersecting) {
193
200
  observer.unobserve(entry.target);
194
- dispatch(entry.target, "", createEvent("qvisible", entry));
201
+ dispatch(entry.target, createEvent("qvisible", entry), "e:qvisible");
195
202
  }
196
203
  }
204
+ }));
205
+ querySelectorAll("[q-e\\:qvisible]:not([q\\:observed])").forEach((el) => {
206
+ observer.observe(el);
207
+ el.setAttribute("q:observed", "true");
197
208
  });
198
- results.forEach((el) => observer.observe(el));
199
209
  }
200
210
  }
201
211
  };
202
- const addEventListener = (el, eventName, handler, capture = false) => {
203
- el.addEventListener(eventName, handler, { capture, passive: false });
204
- };
205
- let cleanTimer;
206
- const processEventOrNode = (...eventNames) => {
207
- doNotClean = true;
208
- clearTimeout(cleanTimer);
209
- cleanTimer = setTimeout(() => doNotClean = false, 2e4);
210
- for (const eventNameOrNode of eventNames) {
211
- if (typeof eventNameOrNode === "string") {
212
- if (!events.has(eventNameOrNode)) {
213
- roots.forEach(
214
- (root) => addEventListener(root, eventNameOrNode, processDocumentEvent, true)
215
- );
216
- addEventListener(win, eventNameOrNode, processWindowEvent, true);
217
- events.add(eventNameOrNode);
212
+ const addEventOrRoot = (...eventNames) => {
213
+ for (const eventNameOrRoot of eventNames) {
214
+ if (typeof eventNameOrRoot === "string") {
215
+ if (!events.has(eventNameOrRoot)) {
216
+ events.add(eventNameOrRoot);
217
+ const { scope, eventName } = parseKebabEvent(eventNameOrRoot);
218
+ if (scope === windowPrefix) {
219
+ addEventListener(win, eventName, processWindowEvent, true);
220
+ } else {
221
+ roots.forEach(
222
+ (root) => addEventListener(
223
+ root,
224
+ eventName,
225
+ scope === documentPrefix ? processDocumentEvent : processElementEvent,
226
+ true
227
+ )
228
+ );
229
+ }
230
+ if (hasInitialized === 1 && (eventNameOrRoot === "e:qvisible" || eventNameOrRoot === "d:qinit" || eventNameOrRoot === "d:qidle")) {
231
+ processReadyStateChange();
232
+ }
218
233
  }
219
234
  } else {
220
- if (!roots.has(eventNameOrNode)) {
221
- events.forEach(
222
- (eventName) => addEventListener(eventNameOrNode, eventName, processDocumentEvent, true)
223
- );
224
- roots.add(eventNameOrNode);
235
+ if (!roots.has(eventNameOrRoot)) {
236
+ events.forEach((kebabEventName) => {
237
+ const { scope, eventName } = parseKebabEvent(kebabEventName);
238
+ if (scope !== windowPrefix) {
239
+ addEventListener(
240
+ eventNameOrRoot,
241
+ eventName,
242
+ scope === documentPrefix ? processDocumentEvent : processElementEvent,
243
+ true
244
+ );
245
+ }
246
+ });
247
+ roots.add(eventNameOrRoot);
225
248
  }
226
249
  }
227
250
  }
228
251
  };
229
- if (!("__q_context__" in doc)) {
230
- doc.__q_context__ = 0;
231
- const qwikevents = win.qwikevents;
232
- if (qwikevents) {
233
- if (Array.isArray(qwikevents)) {
234
- processEventOrNode(...qwikevents);
235
- } else {
236
- processEventOrNode("click", "input");
237
- }
252
+ const _qwikEv = win._qwikEv;
253
+ if (!_qwikEv?.roots) {
254
+ if (Array.isArray(_qwikEv)) {
255
+ addEventOrRoot(..._qwikEv);
256
+ } else {
257
+ addEventOrRoot("e:click", "e:input");
238
258
  }
239
- win.qwikevents = {
259
+ win._qwikEv = {
240
260
  events,
241
261
  roots,
242
- push: processEventOrNode
262
+ push: addEventOrRoot
243
263
  };
244
264
  addEventListener(doc, "readystatechange", processReadyStateChange);
245
265
  processReadyStateChange();
@@ -1 +1 @@
1
- const t=document,e=window,n=new Set,o=new Set([t]);let r;const s=(t,e)=>Array.from(t.querySelectorAll(e)),i=t=>{const e=[];return o.forEach((n=>e.push(...s(n,t)))),e},a=t=>{v(t),s(t,"[q\\:shadowroot]").forEach((t=>{const e=t.shadowRoot;e&&a(e)}))},c=t=>t&&"function"==typeof t.then;let l=!0;const f=(t,e,n=e.type)=>{let o=l;i("[on"+t+"\\:"+n+"]").forEach((r=>{o=!0,b(r,t,e,n)})),o||window[t.slice(1)].removeEventListener(n,"-window"===t?d:_)},p=e=>{if(void 0===e._qwikjson_){let n=(e===t.documentElement?t.body:e).lastElementChild;for(;n;){if("SCRIPT"===n.tagName&&"qwik/json"===n.getAttribute("type")){e._qwikjson_=JSON.parse(n.textContent.replace(/\\x3C(\/?script)/gi,"<$1"));break}n=n.previousElementSibling}}},u=(t,e)=>new CustomEvent(t,{detail:e}),b=async(e,n,o,r=o.type)=>{const s="on"+n+":"+r;e.hasAttribute("preventdefault:"+r)&&o.preventDefault(),e.hasAttribute("stoppropagation:"+r)&&o.stopPropagation();const i=e._qc_,a=i&&i.li.filter((t=>t[0]===s));if(a&&a.length>0){for(const t of a){const n=t[1].getFn([e,o],(()=>e.isConnected))(o,e),r=o.cancelBubble;c(n)&&await n,r&&o.stopPropagation()}return}const l=e.getAttribute(s),f=e.qDispatchEvent;if(f)return f(o,n);if(l){const n=e.closest("[q\\:container]:not([q\\:container=html]):not([q\\:container=text])"),r=n.getAttribute("q:base"),s=n.getAttribute("q:version")||"unknown",i=n.getAttribute("q:manifest-hash")||"dev",a=new URL(r,t.baseURI);for(const f of l.split("\n")){const l=new URL(f,a),u=l.href,b=l.hash.replace(/^#?([^?[|]*).*$/,"$1")||"default",h=performance.now();let _,d,w;const m=f.startsWith("#"),y={qBase:r,qManifest:i,qVersion:s,href:u,symbol:b,element:e,reqTime:h};if(m){const e=n.getAttribute("q:instance");_=(t["qFuncs_"+e]||[])[Number.parseInt(b)],_||(d="sync",w=Error("sym:"+b))}else{q("qsymbol",y);const t=l.href.split("#")[0];try{const e=import(t);p(n),_=(await e)[b],_||(d="no-symbol",w=Error(`${b} not in ${t}`))}catch(t){d||(d="async"),w=t}}if(!_){q("qerror",{importError:d,error:w,...y}),console.error(w);break}const v=t.__q_context__;if(e.isConnected)try{t.__q_context__=[e,o,l];const n=_(o,e);c(n)&&await n}catch(t){q("qerror",{error:t,...y})}finally{t.__q_context__=v}}}},q=(e,n)=>{t.dispatchEvent(u(e,n))},h=t=>t.replace(/([A-Z])/g,(t=>"-"+t.toLowerCase())),_=async t=>{let e=h(t.type),n=t.target;for(f("-document",t,e);n&&n.getAttribute;){const o=b(n,"",t,e);let r=t.cancelBubble;c(o)&&await o,r||(r=r||t.cancelBubble||n.hasAttribute("stoppropagation:"+t.type)),n=t.bubbles&&!0!==r?n.parentElement:null}},d=t=>{f("-window",t,h(t.type))},w=()=>{var s;const c=t.readyState;if(!r&&("interactive"==c||"complete"==c)&&(o.forEach(a),r=1,q("qinit"),(null!=(s=e.requestIdleCallback)?s:e.setTimeout).bind(e)((()=>q("qidle"))),n.has("qvisible"))){const t=i("[on\\:qvisible]"),e=new IntersectionObserver((t=>{for(const n of t)n.isIntersecting&&(e.unobserve(n.target),b(n.target,"",u("qvisible",n)))}));t.forEach((t=>e.observe(t)))}},m=(t,e,n,o=!1)=>{t.addEventListener(e,n,{capture:o,passive:!1})};let y;const v=(...t)=>{l=!0,clearTimeout(y),y=setTimeout((()=>l=!1),2e4);for(const r of t)"string"==typeof r?n.has(r)||(o.forEach((t=>m(t,r,_,!0))),m(e,r,d,!0),n.add(r)):o.has(r)||(n.forEach((t=>m(r,t,_,!0))),o.add(r))};if(!("__q_context__"in t)){t.__q_context__=0;const r=e.qwikevents;r&&(Array.isArray(r)?v(...r):v("click","input")),e.qwikevents={events:n,roots:o,push:v},m(t,"readystatechange",w),w()}
1
+ const e=document,t=window,o="w",r="d",n=new Set,s=new Set([e]),i=new Map;let a,c;const l=(e,t)=>Array.from(e.querySelectorAll(t)),q=e=>{const t=[];return s.forEach(o=>t.push(...l(o,e))),t},d=(e,t,o,r=!1)=>e.addEventListener(t,o,{capture:r,passive:!1}),b=e=>{_(e),l(e,"[q\\:shadowroot]").forEach(e=>{const t=e.shadowRoot;t&&b(t)})},f=e=>e&&"function"==typeof e.then,p=t=>{if(void 0===t._qwikjson_){let o=(t===e.documentElement?e.body:t).lastElementChild;for(;o;){if("SCRIPT"===o.tagName&&"qwik/json"===o.getAttribute("type")){t._qwikjson_=JSON.parse(o.textContent.replace(/\\x3C(\/?script)/gi,"<$1"));break}o=o.previousElementSibling}}},u=(e,t)=>new CustomEvent(e,{detail:t}),h=(t,o)=>{e.dispatchEvent(u(t,o))},m=e=>e.replace(/([A-Z-])/g,e=>"-"+e.toLowerCase()),v=e=>e.replace(/-./g,e=>e[1].toUpperCase()),w=e=>({scope:e.charAt(0),eventName:v(e.slice(2))}),y=async(t,o,r,n)=>{n&&(t.hasAttribute("preventdefault:"+n)&&o.preventDefault(),t.hasAttribute("stoppropagation:"+n)&&o.stopPropagation());const s=t._qDispatch?.[r];if(s){if(s.length)for(const e of s){const r=e?.(o,t);f(r)&&await r}else await s(o,t);return}const a=t.getAttribute("q-"+r);if(a){const r=t.closest("[q\\:container]:not([q\\:container=html]):not([q\\:container=text])"),n=r.getAttribute("q:base"),s=new URL(n,e.baseURI);for(const c of a.split("|")){const a=performance.now(),[l,q,d]=c.split("#"),b={qBase:n,symbol:q,element:t,reqTime:a};let u,m,v;if(""===l){const t=r.getAttribute("q:instance");u=(e["qFuncs_"+t]||[])[Number.parseInt(q)],u||(m="sync",v=Error("sym:"+q))}else{const e=`${q}|${n}|${l}`;if(u=i.get(e),!u){const t=new URL(l,s).href;try{const o=import(t);p(r),u=(await o)[q],u?(i.set(e,u),h("qsymbol",b)):(m="no-symbol",v=Error(`${q} not in ${t}`))}catch(e){m="async",v=e}}}if(u){if(t.isConnected)try{const e=u.call(d,o,t);f(e)&&await e}catch(e){h("qerror",{error:e,...b})}}else h("qerror",{importError:m,error:v,...b}),console.error(v)}}},E=async e=>{const t=m(e.type),o="e:"+t;let r=e.target;for(;r&&r.getAttribute;){const n=y(r,e,o,t),s=e.bubbles&&!e.cancelBubble;f(n)&&await n,r=s&&e.bubbles&&!e.cancelBubble?r.parentElement:null}},g=(e,t)=>{const o=m(t.type),r=e+":"+o;q("[q-"+e+"\\:"+o+"]").forEach(e=>y(e,t,r,o))},A=async e=>{g(r,e)},C=e=>{g(o,e)},k=()=>{const o=e.readyState;if("interactive"==o||"complete"==o){if(c=1,s.forEach(b),n.has("d:qinit")){n.delete("d:qinit");const e=u("qinit");q("[q-d\\:qinit]").forEach(t=>{y(t,e,"d:qinit"),t.removeAttribute("q-d:qinit")})}n.has("d:qidle")&&(n.delete("d:qidle"),(t.requestIdleCallback??t.setTimeout).bind(t)(()=>{const e=u("qidle");q("[q-d\\:qidle]").forEach(t=>{y(t,e,"d:qidle"),t.removeAttribute("q-d:qidle")})})),n.has("e:qvisible")&&(a||(a=new IntersectionObserver(e=>{for(const t of e)t.isIntersecting&&(a.unobserve(t.target),y(t.target,u("qvisible",t),"e:qvisible"))})),q("[q-e\\:qvisible]:not([q\\:observed])").forEach(e=>{a.observe(e),e.setAttribute("q:observed","true")}))}},_=(...e)=>{for(const i of e)if("string"==typeof i){if(!n.has(i)){n.add(i);const{scope:e,eventName:a}=w(i);e===o?d(t,a,C,!0):s.forEach(t=>d(t,a,e===r?A:E,!0)),1!==c||"e:qvisible"!==i&&"d:qinit"!==i&&"d:qidle"!==i||k()}}else s.has(i)||(n.forEach(e=>{const{scope:t,eventName:n}=w(e);t!==o&&d(i,n,t===r?A:E,!0)}),s.add(i))},S=t._qwikEv;S?.roots||(Array.isArray(S)?_(...S):_("e:click","e:input"),t._qwikEv={events:n,roots:s,push:_},d(e,"readystatechange",k),k());
package/dist/server.d.ts CHANGED
@@ -4,7 +4,7 @@ import type { QwikManifest } from './optimizer';
4
4
  import type { ResolvedManifest } from './optimizer';
5
5
  import type { ServerQwikManifest } from './optimizer';
6
6
  import type { SnapshotResult } from '.';
7
- import type { StreamWriter } from '.';
7
+ import type { StreamWriter } from './internal';
8
8
  import type { SymbolMapperFn } from './optimizer';
9
9
 
10
10
  /** @public */
@@ -35,6 +35,15 @@ declare type FunctionComponent<P = unknown> = {
35
35
  renderFn(props: P, key: string | null, flags: number, dev?: DevJSX): JSXOutput;
36
36
  }['renderFn'];
37
37
 
38
+ /**
39
+ * Provides the `backpatch-executor.js` executor script as a string.
40
+ *
41
+ * @public
42
+ */
43
+ export declare function getQwikBackpatchExecutorScript(opts?: {
44
+ debug?: boolean;
45
+ }): string;
46
+
38
47
  /**
39
48
  * Provides the `qwikloader.js` file as a string. Useful for tooling to inline the qwikloader script
40
49
  * into HTML.
@@ -166,6 +175,8 @@ export declare interface PreloaderOptions {
166
175
  * The minimum probability for a bundle to be added as a preload link during SSR.
167
176
  *
168
177
  * Defaults to `0.7` (70% probability)
178
+ *
179
+ * This makes sure that the most likely bundles are preloaded ahead of time.
169
180
  */
170
181
  ssrPreloadProbability?: number;
171
182
  /**
@@ -187,9 +198,12 @@ export declare interface PreloaderOptions {
187
198
  */
188
199
  maxIdlePreloads?: number;
189
200
  /**
190
- * The minimum probability for a bundle to be added to the preload queue.
201
+ * @deprecated The minimum probability for a bundle to be added to the preload queue.
191
202
  *
192
- * Defaults to `0.35` (35% probability)
203
+ * Defaulted to `0.35` (35% probability).
204
+ *
205
+ * Deprecated because this could cause performance issues with bundles fetched on on click instead
206
+ * of being preloaded ahead of time.
193
207
  */
194
208
  preloadProbability?: number;
195
209
  }
@@ -231,18 +245,12 @@ declare interface QwikBundle {
231
245
  declare type QwikBundleGraph = Array<string | number>;
232
246
 
233
247
  /** @public */
234
- export declare interface QwikLoaderOptions {
235
- /**
236
- * Whether to include the qwikloader script in the document. Normally you don't need to worry
237
- * about this, but in case of multi-container apps using different Qwik versions, you might want
238
- * to only enable it on one of the containers.
239
- *
240
- * Defaults to `'auto'`.
241
- */
248
+ export declare type QwikLoaderOptions = 'module' | 'inline' | 'never' | {
249
+ /** @deprecated No longer used. */
242
250
  include?: 'always' | 'never' | 'auto';
243
- /** @deprecated No longer used, the qwikloader is always loaded as soon as possible */
251
+ /** @deprecated No longer used. */
244
252
  position?: 'top' | 'bottom';
245
- }
253
+ };
246
254
 
247
255
  /**
248
256
  * The metadata of the build. One of its uses is storing where QRL symbols are located.
@@ -337,11 +345,25 @@ export declare interface RenderOptions extends SerializeDocumentOptions {
337
345
  /** Language to use when rendering the document. */
338
346
  locale?: string | ((options: RenderOptions) => string);
339
347
  /**
340
- * Specifies if the Qwik Loader script is added to the document or not.
348
+ * Specifies how the Qwik Loader is included in the document. This enables interactivity and lazy
349
+ * loading.
350
+ *
351
+ * `module`: Use a `<script>` tag to load the Qwik Loader. Subsequent page loads will have the
352
+ * script cached and instantly running.
353
+ *
354
+ * `inline`: This embeds the Qwik Loader script directly in the document. This adds about 3kB
355
+ * before compression, which typically is reduced to about 1.6kB with gzip.
356
+ *
357
+ * `never`: Do not include the Qwik Loader script. This is mostly useful when embedding multiple
358
+ * containers on the same page.
359
+ *
360
+ * Defaults to `module`.
341
361
  *
342
- * Defaults to `{ include: true }`.
362
+ * Note that the Qwik Loader is absolutely required for Qwik to work. There must be an instance of
363
+ * it loaded for any interactivity to happen.
343
364
  */
344
365
  qwikLoader?: QwikLoaderOptions;
366
+ /** Specifies how preloading is handled. This ensures that code is instantly available when needed. */
345
367
  preloader?: PreloaderOptions | false;
346
368
  /** @deprecated Use `preloader` instead */
347
369
  prefetchStrategy?: PrefetchStrategy | null;
@@ -351,6 +373,7 @@ export declare interface RenderOptions extends SerializeDocumentOptions {
351
373
  */
352
374
  containerTagName?: string;
353
375
  containerAttributes?: Record<string, string>;
376
+ /** Metadata that can be retrieved during SSR with `useServerData()`. */
354
377
  serverData?: Record<string, any>;
355
378
  }
356
379