@qwik.dev/core 2.0.0-beta.43 → 2.0.0-beta.45

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/dist/core.mjs CHANGED
@@ -1,12 +1,14 @@
1
1
  /**
2
2
  * @license
3
- * @qwik.dev/core 2.0.0-beta.43-dev+e478dfb
3
+ * @qwik.dev/core 2.0.0-beta.45-dev+596de70
4
4
  * Copyright QwikDev. All Rights Reserved.
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://github.com/QwikDev/qwik/blob/main/LICENSE
7
7
  */
8
- import { isDev, isServer, isBrowser as isBrowser$1 } from '@qwik.dev/core/build';
8
+ import { isDev, isServer, isBrowser } from '@qwik.dev/core/build';
9
9
  export { isBrowser, isDev, isServer } from '@qwik.dev/core/build';
10
+ import { getAsyncLocalStorage } from '@qwik.dev/core/async-local-storage';
11
+ export { getAsyncLocalStorage as _getAsyncLocalStorage } from '@qwik.dev/core/async-local-storage';
10
12
  import { p } from '@qwik.dev/core/preloader';
11
13
 
12
14
  // Direct `globalThis.X` accesses (no alias) so Terser's `global_defs` engages
@@ -76,102 +78,6 @@ const createAndLogError = (asyncThrow, message, ...optionalParams) => {
76
78
  return err;
77
79
  };
78
80
 
79
- const ASSERT_DISCLAIMER = 'Internal assert, this is likely caused by a bug in Qwik: ';
80
- /*@__INLINE__*/
81
- function assertDefined(value, text, ...parts) {
82
- if (isDev) {
83
- if (value != null) {
84
- return;
85
- }
86
- throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts);
87
- }
88
- }
89
- /*@__INLINE__*/
90
- function assertEqual(value1, value2, text, ...parts) {
91
- if (isDev) {
92
- if (value1 === value2) {
93
- return;
94
- }
95
- throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts);
96
- }
97
- }
98
- /*@__INLINE__*/
99
- function assertTrue(value1, text, ...parts) {
100
- if (isDev) {
101
- if (value1 === true) {
102
- return;
103
- }
104
- throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts);
105
- }
106
- }
107
- /*@__INLINE__*/
108
- function assertFalse(value1, text, ...parts) {
109
- if (isDev) {
110
- if (value1 === false) {
111
- return;
112
- }
113
- throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts);
114
- }
115
- }
116
- /*@__INLINE__*/
117
- function assertNumber(value1, text, ...parts) {
118
- if (isDev) {
119
- if (typeof value1 === 'number') {
120
- return;
121
- }
122
- throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts);
123
- }
124
- }
125
-
126
- /** @internal */
127
- const mapApp_findIndx = (array, key, start) => {
128
- isDev && assertTrue(start % 2 === 0, 'Expecting even number.');
129
- let bottom = start >> 1;
130
- let top = (array.length - 2) >> 1;
131
- while (bottom <= top) {
132
- const mid = bottom + ((top - bottom) >> 1);
133
- const midKey = array[mid << 1];
134
- if (midKey === key) {
135
- return mid << 1;
136
- }
137
- if (midKey < key) {
138
- bottom = mid + 1;
139
- }
140
- else {
141
- top = mid - 1;
142
- }
143
- }
144
- return (bottom << 1) ^ -1;
145
- };
146
- /** @internal */
147
- const mapArray_set = (array, key, value, start, allowNullValue = false) => {
148
- const indx = mapApp_findIndx(array, key, start);
149
- if (indx >= 0) {
150
- if (value == null && !allowNullValue) {
151
- array.splice(indx, 2);
152
- }
153
- else {
154
- array[indx + 1] = value;
155
- }
156
- }
157
- else if (value != null || allowNullValue) {
158
- array.splice(indx ^ -1, 0, key, value);
159
- }
160
- };
161
- /** @internal */
162
- const mapArray_get = (array, key, start) => {
163
- const indx = mapApp_findIndx(array, key, start);
164
- if (indx >= 0) {
165
- return array[indx + 1];
166
- }
167
- else {
168
- return null;
169
- }
170
- };
171
- const mapArray_has = (array, key, start) => {
172
- return mapApp_findIndx(array, key, start) >= 0;
173
- };
174
-
175
81
  /** @private */
176
82
  const isSerializableObject = (v) => {
177
83
  const proto = Object.getPrototypeOf(v);
@@ -231,10 +137,11 @@ const codeToText = (code, ...parts) => {
231
137
  'Attribute value is unsafe for SSR {{0}}', // 32
232
138
  'SerializerSymbol function returned rejected promise', // 33
233
139
  'Serialization Error: Cannot serialize function: {{0}}', // 34
234
- 'Cannot read .value of a clientOnly async signal during SSR. Use .loading to check state, or provide an initial value.', // 35
140
+ 'Cannot read .value of a clientOnly async signal during SSR. Provide an initial value.', // 35
235
141
  'Invalid element name for SSR {{0}}', // 36
236
142
  'Invalid serialized Promise dependency', // 37
237
143
  'Invalid serialized Uint8Array payload', // 38
144
+ 'Computed signal was disposed', // 39
238
145
  ];
239
146
  let text = MAP[code] ?? '';
240
147
  if (parts.length) {
@@ -257,6 +164,13 @@ const qError = (code, errorMessageArgs = []) => {
257
164
  return logErrorAndStop(text, ...errorMessageArgs);
258
165
  };
259
166
 
167
+ /**
168
+ * QWIK_VERSION
169
+ *
170
+ * @public
171
+ */
172
+ const version = "2.0.0-beta.45-dev+596de70";
173
+
260
174
  /** QRL related utilities that you can import without importing all of Qwik. */
261
175
  const SYNC_QRL = '<sync>';
262
176
  /** Sync QRL is a function which is serialized into `<script q:func="qwik/json">` tag. */
@@ -278,132 +192,6 @@ const getSymbolHash = (symbolName) => {
278
192
  return symbolName.slice(index);
279
193
  };
280
194
 
281
- /**
282
- * A friendly name tag for a VirtualVNode.
283
- *
284
- * Theses are used to give a name to a VirtualVNode. This is useful for debugging and testing.
285
- *
286
- * The name is only added in development mode and is not included in production builds.
287
- */
288
- const DEBUG_TYPE = 'q:type';
289
- const VirtualTypeName = {
290
- ["V" /* VirtualType.Virtual */]: /* ********* */ 'Virtual', //
291
- ["F" /* VirtualType.Fragment */]: /* ******** */ 'Fragment', //
292
- ["S" /* VirtualType.WrappedSignal */]: /* *** */ 'Signal', //
293
- ["A" /* VirtualType.Awaited */]: /* ********* */ 'Awaited', //
294
- ["C" /* VirtualType.Component */]: /* ******* */ 'Component', //
295
- ["I" /* VirtualType.InlineComponent */]: /* * */ 'InlineComponent', //
296
- ["P" /* VirtualType.Projection */]: /* ****** */ 'Projection', //
297
- };
298
-
299
- /**
300
- * @file
301
- *
302
- * VNodeData is additional information which allows the `vnode` to recover virtual VNode information
303
- * from the HTML.
304
- */
305
- /**
306
- * VNodeDataSeparator contains information about splitting up the VNodeData and attaching it to the
307
- * HTML.
308
- */
309
- const VNodeDataSeparator = {
310
- REFERENCE: /* ******** */ 126, // `~` is a reference to the node. Save it.
311
- ADVANCE_1: /* ********* */ 33, // `!` is vNodeData separator skipping 0. (ie next vNode)
312
- ADVANCE_8192: /* ****** */ 46, // `.` is vNodeData separator skipping 4096.
313
- };
314
- /**
315
- * VNodeDataChar contains information about the VNodeData used for encoding props.
316
- *
317
- * Available character ranges: 59 - 64, 91 - 94, 96, 123 - 126
318
- */
319
- const VNodeDataChar = {
320
- OPEN: /* ************** */ 123, // `{` is the start of the VNodeData for a virtual element.
321
- CLOSE: /* ************* */ 125, // `}` is the end of the VNodeData for a virtual element.
322
- SCOPED_STYLE: /* ******* */ 59, // `;` - `q:sstyle` - Style attribute.
323
- RENDER_FN: /* ********** */ 60, // `<` - `q:renderFn' - Component QRL render function (body)
324
- RENDER_HASH_PREFIX: /* **/ 95, // `_` after `<` identifies a component hash.
325
- ID: /* ***************** */ 61, // `=` - `q:id` - ID of the element.
326
- PROPS: /* ************** */ 62, // `>` - `q:props' - Component Props
327
- SLOT_PARENT: /* ******** */ 63, // `?` - `q:sparent` - Slot parent.
328
- KEY: /* **************** */ 64, // `@` - `q:key` - Element key.
329
- SEQ: /* **************** */ 91, // `[` - `q:seq' - Seq value from `useSequentialScope()`
330
- CONTEXT: /* ************ */ 93, // `]` - `q:ctx' - Component context/props
331
- SEQ_IDX: /* ************ */ 94, // `^` - `q:seqIdx' - Sequential scope id
332
- BACK_REFS: /* ********** */ 96, // '`' - `q:brefs' - Effect dependencies/subscriptions
333
- SEPARATOR: /* ********* */ 124, // `|` - Separator char to encode any key/value pairs.
334
- SLOT: /* ************** */ 126};
335
- /**
336
- * Convert a segment-local vnode index into a key for the root container's shared qVNodeRefs map.
337
- *
338
- * Out-of-order Suspense segments each start counting vnode refs from 0, but the client merges all
339
- * segment refs into one root-level map. This uses a Cantor-style pairing function for the
340
- * zero-based pair `(segmentIndex, localIndex)`, then makes it negative so segment refs cannot
341
- * collide with root refs, which are non-negative.
342
- *
343
- * Examples:
344
- *
345
- * - Segment 1, local 0 -> -1
346
- * - Segment 2, local 0 -> -2
347
- * - Segment 1, local 1 -> -3
348
- */
349
- const getSegmentVNodeRefId = (segmentId, localIndex) => {
350
- const segmentIndex = parseInt(segmentId, 10) - 1;
351
- const diagonal = segmentIndex + localIndex;
352
- return -((diagonal * (diagonal + 1)) / 2 + localIndex + 1);
353
- };
354
-
355
- function escapeHTML(html) {
356
- let escapedHTML = '';
357
- const length = html.length;
358
- let idx = 0;
359
- let lastIdx = idx;
360
- for (; idx < length; idx++) {
361
- // We get the charCode NOT string. String would allocate memory.
362
- const ch = html.charCodeAt(idx);
363
- // Every time we concat a string we allocate memory. We want to minimize that.
364
- if (ch === 60 /* < */) {
365
- escapedHTML += html.substring(lastIdx, idx) + '&lt;';
366
- }
367
- else if (ch === 62 /* > */) {
368
- escapedHTML += html.substring(lastIdx, idx) + '&gt;';
369
- }
370
- else if (ch === 38 /* & */) {
371
- escapedHTML += html.substring(lastIdx, idx) + '&amp;';
372
- }
373
- else if (ch === 34 /* " */) {
374
- escapedHTML += html.substring(lastIdx, idx) + '&quot;';
375
- }
376
- else if (ch === 39 /* ' */) {
377
- escapedHTML += html.substring(lastIdx, idx) + '&#39;';
378
- }
379
- else {
380
- continue;
381
- }
382
- lastIdx = idx + 1;
383
- }
384
- if (lastIdx === 0) {
385
- // This is most common case, just return previous string no memory allocation.
386
- return html;
387
- }
388
- else {
389
- // Add the tail of replacement.
390
- return escapedHTML + html.substring(lastIdx);
391
- }
392
- }
393
- function decodeVNodeDataString(str) {
394
- let result = '';
395
- for (let i = 0; i < str.length; i++) {
396
- if (str.charAt(i) === '\\' && i + 1 < str.length) {
397
- result += str.charAt(i + 1);
398
- i++;
399
- }
400
- else {
401
- result += str.charAt(i);
402
- }
403
- }
404
- return result;
405
- }
406
-
407
195
  /** State factory of the component. */
408
196
  const OnRenderProp = 'q:renderFn';
409
197
  const QComponentHash = 'q:componentHash';
@@ -459,6 +247,8 @@ const XLINK_NS = 'http://www.w3.org/1999/xlink';
459
247
  const XML_NS = 'http://www.w3.org/XML/1998/namespace';
460
248
  const RenderEvent = 'qRender';
461
249
  const TaskEvent = 'qTask';
250
+ /** Scoped qvisible listener attribute; the qwik loader observes elements carrying it. */
251
+ const QVisibleAttr = 'q-e:qvisible';
462
252
  /** `<q:slot name="...">` */
463
253
  const QDefaultSlot = '';
464
254
  /**
@@ -490,399 +280,6 @@ const dangerouslySetInnerHTML = 'dangerouslySetInnerHTML';
490
280
  const qwikInspectorAttr = 'data-qwik-inspector';
491
281
  const debugStyleScopeIdPrefixAttr = '__scopedStyleIdPrefix__';
492
282
 
493
- const MAX_RETRY_ON_PROMISE_COUNT = 100;
494
- const isPromise = (value) => {
495
- try {
496
- // not using "value instanceof Promise" to have zone.js support
497
- return !!value && typeof value == 'object' && typeof value.then === 'function';
498
- }
499
- catch {
500
- return false;
501
- }
502
- };
503
- const safeCall = (call, thenFn, rejectFn) => {
504
- try {
505
- const result = call();
506
- if (isPromise(result)) {
507
- return result.then(thenFn, rejectFn);
508
- }
509
- else {
510
- return thenFn(result);
511
- }
512
- }
513
- catch (e) {
514
- return rejectFn(e);
515
- }
516
- };
517
- const maybeThen = (valueOrPromise, thenFn) => {
518
- return isPromise(valueOrPromise)
519
- ? valueOrPromise.then(thenFn)
520
- : thenFn(valueOrPromise);
521
- };
522
- /** @internal */
523
- const delay = (timeout) => {
524
- return new Promise((resolve) => {
525
- setTimeout(resolve, timeout);
526
- });
527
- };
528
- const checkError = (e) => {
529
- try {
530
- if (isServer && e instanceof ReferenceError && e.message.includes('window')) {
531
- e.message = 'It seems like you forgot to add "if (isBrowser) {...}" here:' + e.message;
532
- }
533
- }
534
- catch {
535
- // ignore
536
- }
537
- };
538
- const justThrow = (e) => {
539
- throw e;
540
- };
541
- /**
542
- * Retries a function that throws a promise. If you pass `onError`, you're responsible for handling
543
- * errors.
544
- *
545
- * @internal
546
- */
547
- function retryOnPromise(fn, onError = justThrow) {
548
- let ok = false;
549
- let result;
550
- try {
551
- result = fn();
552
- ok = true;
553
- }
554
- catch (e) {
555
- result = e;
556
- }
557
- if (!isPromise(result)) {
558
- // Synchronous function or error, no need to retry
559
- if (ok) {
560
- return result;
561
- }
562
- isDev && checkError(result);
563
- return onError(result);
564
- }
565
- let retryCount = MAX_RETRY_ON_PROMISE_COUNT;
566
- const retry = async (p) => {
567
- while (isPromise(p)) {
568
- try {
569
- await p;
570
- // We waited for the thrown promise, now try again
571
- return await fn();
572
- }
573
- catch (err) {
574
- if (isPromise(err)) {
575
- if (!--retryCount) {
576
- p = new Error('Exceeded max retry count in retryOnPromise');
577
- break;
578
- }
579
- else {
580
- p = err;
581
- }
582
- }
583
- else {
584
- p = err;
585
- break;
586
- }
587
- }
588
- }
589
- isDev && checkError(p);
590
- return onError(p);
591
- };
592
- return ok ? result.catch(retry) : retry(result);
593
- }
594
-
595
- const styleContent = (styleId) => {
596
- return ComponentStylesPrefixContent + styleId;
597
- };
598
- function isClassAttr(key) {
599
- return key === 'class';
600
- }
601
- function convertScopedStyleIdsToArray(scopedStyleIds) {
602
- return scopedStyleIds?.split(' ') ?? null;
603
- }
604
- function convertStyleIdsToString(scopedStyleIds) {
605
- return Array.from(scopedStyleIds).join(' ');
606
- }
607
- const addComponentStylePrefix = (styleId) => {
608
- if (styleId) {
609
- let idx = 0;
610
- do {
611
- styleId = styleId.substring(0, idx) + styleContent(styleId.substring(idx));
612
- } while ((idx = styleId.indexOf(' ', idx) + 1) !== 0);
613
- }
614
- return styleId || null;
615
- };
616
-
617
- /**
618
- * Think of `-` as an escape character which makes the next character uppercase. `--` is just `-`.
619
- *
620
- * Rules for JSX property event names starting with `on`:
621
- *
622
- * - Are case insensitive: `onClick$` is same `onclick$`
623
- * - A `--` is `-`: `dbl--click` => `dbl-click`
624
- * - Become case sensitive if prefixed by `-`: `-Click` is `Click`
625
- * - A `-` (not at the beginning) makes next character uppercase: `dbl-click` => `dblClick`
626
- */
627
- const EVENT_SUFFIX = '$';
628
- const DOM_CONTENT_LOADED_EVENT = 'DOMContentLoaded';
629
- const isHtmlAttributeAnEventName = (name) => {
630
- return (name.charCodeAt(0) === 113 /* q */ &&
631
- name.charCodeAt(1) === 45 /* - */ &&
632
- (name.charCodeAt(3) === 58 /* : */ ||
633
- (name.charCodeAt(3) === 112 /* p */ && name.charCodeAt(4) === 58)) /* : */);
634
- };
635
- function jsxEventToHtmlAttribute(jsxEvent, isPassive = false) {
636
- if (jsxEvent.endsWith(EVENT_SUFFIX)) {
637
- const [prefix, idx] = getEventScopeDataFromJsxEvent(jsxEvent, isPassive);
638
- if (idx !== -1) {
639
- return prefix + normalizeJsxEventName(jsxEvent.slice(idx, -1));
640
- }
641
- }
642
- return null; // Return null if not matching expected format
643
- }
644
- function createEventName(event, prefix = '') {
645
- const eventName = fromCamelToKebabCase(event);
646
- return prefix + eventName;
647
- }
648
- function getEventScopeDataFromJsxEvent(eventName, isPassive = false) {
649
- let prefix;
650
- let idx = -1;
651
- // set prefix and idx based on the scope
652
- if (eventName.startsWith("on" /* EventNameJSXScope.on */)) {
653
- prefix = isPassive ? "q-ep:" /* EventNameHtmlScope.onPassive */ : "q-e:" /* EventNameHtmlScope.on */;
654
- idx = 2;
655
- }
656
- else if (eventName.startsWith("window:on" /* EventNameJSXScope.window */)) {
657
- prefix = isPassive ? "q-wp:" /* EventNameHtmlScope.windowPassive */ : "q-w:" /* EventNameHtmlScope.window */;
658
- idx = 9;
659
- }
660
- else if (eventName.startsWith("document:on" /* EventNameJSXScope.document */)) {
661
- prefix = isPassive ? "q-dp:" /* EventNameHtmlScope.documentPassive */ : "q-d:" /* EventNameHtmlScope.document */;
662
- idx = 11;
663
- }
664
- return [prefix, idx];
665
- }
666
- const normalizeJsxEventName = (name) => {
667
- return name === DOM_CONTENT_LOADED_EVENT
668
- ? '-d-o-m-content-loaded'
669
- : createEventName(name.charAt(0) === '-'
670
- ? // marker for case sensitive event name
671
- name.slice(1)
672
- : name.toLowerCase());
673
- };
674
- function isPreventDefault(key) {
675
- return key.startsWith('preventdefault:');
676
- }
677
- /** Converts a camelCase string to kebab-case. This is used for event names. */
678
- const fromCamelToKebabCase = (text) => {
679
- return text.replace(/([A-Z-])/g, (a) => '-' + a.toLowerCase());
680
- };
681
- /** E.g. `"q-e:click"` => `['e', 'click']`, `"q-ep:click"` => `['ep', 'click']` */
682
- const getEventDataFromHtmlAttribute = (htmlKey) => {
683
- const separatorIndex = htmlKey.indexOf(':');
684
- return [htmlKey.slice(2, separatorIndex), htmlKey.slice(separatorIndex + 1)];
685
- };
686
- /** E.g. `"e:click"`, `"w:load"` */
687
- const getScopedEventName = (scope, eventName) => scope + ':' + eventName;
688
-
689
- /** CSS properties which accept numbers but are not in units of "px". */
690
- const unitlessNumbers = new Set([
691
- 'animationIterationCount',
692
- 'aspectRatio',
693
- 'borderImageOutset',
694
- 'borderImageSlice',
695
- 'borderImageWidth',
696
- 'boxFlex',
697
- 'boxFlexGroup',
698
- 'boxOrdinalGroup',
699
- 'columnCount',
700
- 'columns',
701
- 'flex',
702
- 'flexGrow',
703
- 'flexShrink',
704
- 'gridArea',
705
- 'gridRow',
706
- 'gridRowEnd',
707
- 'gridRowStart',
708
- 'gridColumn',
709
- 'gridColumnEnd',
710
- 'gridColumnStart',
711
- 'fontWeight',
712
- 'lineClamp',
713
- 'lineHeight',
714
- 'opacity',
715
- 'order',
716
- 'orphans',
717
- 'scale',
718
- 'tabSize',
719
- 'widows',
720
- 'zIndex',
721
- 'zoom',
722
- 'MozAnimationIterationCount', // Known Prefixed Properties
723
- 'MozBoxFlex', // TODO: Remove these since they shouldn't be used in modern code
724
- 'msFlex',
725
- 'msFlexPositive',
726
- 'WebkitAnimationIterationCount',
727
- 'WebkitBoxFlex',
728
- 'WebkitBoxOrdinalGroup',
729
- 'WebkitColumnCount',
730
- 'WebkitColumns',
731
- 'WebkitFlex',
732
- 'WebkitFlexGrow',
733
- 'WebkitFlexShrink',
734
- 'WebkitLineClamp',
735
- ]);
736
- const isUnitlessNumber = (name) => {
737
- return unitlessNumbers.has(name);
738
- };
739
-
740
- const hashCode = (text, hash = 0) => {
741
- for (let i = 0; i < text.length; i++) {
742
- const chr = text.charCodeAt(i);
743
- hash = (hash << 5) - hash + chr;
744
- hash |= 0; // Convert to 32bit integer
745
- }
746
- return Number(Math.abs(hash)).toString(36);
747
- };
748
-
749
- const serializeClass = (obj) => {
750
- if (!obj) {
751
- return '';
752
- }
753
- if (isString(obj)) {
754
- return obj.trim();
755
- }
756
- const classes = [];
757
- if (isArray(obj)) {
758
- for (let i = 0; i < obj.length; i++) {
759
- const o = obj[i];
760
- const classList = serializeClass(o);
761
- if (classList) {
762
- classes.push(classList);
763
- }
764
- }
765
- }
766
- else {
767
- for (const [key, value] of Object.entries(obj)) {
768
- if (value) {
769
- classes.push(key.trim());
770
- }
771
- }
772
- }
773
- return classes.join(' ');
774
- };
775
- // Unlike fromCamelToKebabCase, this leaves `-` so that `background-color` stays `background-color`
776
- const fromCamelToKebabCaseWithDash = (text) => {
777
- return text.replace(/([A-Z])/g, '-$1').toLowerCase();
778
- };
779
- const stringifyStyle = (obj) => {
780
- if (obj == null) {
781
- return '';
782
- }
783
- if (typeof obj == 'object') {
784
- if (isArray(obj)) {
785
- throw qError(0 /* QError.stringifyClassOrStyle */, [obj, 'style']);
786
- }
787
- else {
788
- const chunks = [];
789
- for (const key in obj) {
790
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
791
- const value = obj[key];
792
- if (value != null && typeof value !== 'function') {
793
- if (key.startsWith('--')) {
794
- chunks.push(key + ':' + value);
795
- }
796
- else {
797
- chunks.push(fromCamelToKebabCaseWithDash(key) + ':' + setValueForStyle(key, value));
798
- }
799
- }
800
- }
801
- }
802
- return chunks.join(';');
803
- }
804
- }
805
- return String(obj);
806
- };
807
- const serializeBooleanOrNumberAttribute = (value) => {
808
- return value != null ? String(value) : null;
809
- };
810
- function serializeAttribute(key, value, styleScopedId) {
811
- if (isClassAttr(key)) {
812
- const serializedClass = serializeClass(value);
813
- value = styleScopedId
814
- ? styleScopedId + (serializedClass.length ? ' ' + serializedClass : serializedClass)
815
- : serializedClass;
816
- }
817
- else if (key === 'style') {
818
- value = stringifyStyle(value);
819
- }
820
- else if (isEnumeratedBooleanAttribute(key) || typeof value === 'number') {
821
- // aria attrs, tabindex etc.
822
- value = serializeBooleanOrNumberAttribute(value);
823
- }
824
- else if (value === false || value == null) {
825
- value = null;
826
- }
827
- else if (value === true && isPreventDefault(key)) {
828
- value = '';
829
- }
830
- return value;
831
- }
832
- function isEnumeratedBooleanAttribute(key) {
833
- return isAriaAttribute(key) || ['spellcheck', 'draggable', 'contenteditable'].includes(key);
834
- }
835
- const setValueForStyle = (styleName, value) => {
836
- if (typeof value === 'number' && value !== 0 && !isUnitlessNumber(styleName)) {
837
- return value + 'px';
838
- }
839
- return value;
840
- };
841
- function isAriaAttribute(prop) {
842
- return prop.startsWith('aria-');
843
- }
844
- const styleKey = (qStyles, index) => {
845
- assertQrl(qStyles);
846
- return `${hashCode(qStyles.$hash$)}-${index}`;
847
- };
848
-
849
- /**
850
- * Creates a function that schedules `fn` to run as a microtask. Microtasks run before browser
851
- * paint, preventing flickering.
852
- */
853
- const createMicroTask = (fn) => {
854
- return () => queueMicrotask(fn);
855
- };
856
- /**
857
- * Creates a function that schedules `fn` to run as a macrotask. Macrotasks yield to the browser,
858
- * allowing paint and user input. Used for time-slicing to avoid blocking the main thread.
859
- */
860
- const createMacroTask = (fn) => {
861
- let macroTask;
862
- if (typeof MessageChannel !== 'undefined') {
863
- const channel = new MessageChannel();
864
- let active = true;
865
- channel.port1.onmessage = () => fn();
866
- macroTask = () => {
867
- if (active) {
868
- channel.port2.postMessage(null);
869
- }
870
- };
871
- macroTask.$destroy$ = () => {
872
- if (active) {
873
- active = false;
874
- channel.port1.onmessage = null;
875
- channel.port1.close();
876
- channel.port2.close();
877
- }
878
- };
879
- }
880
- else {
881
- macroTask = () => setTimeout(fn);
882
- }
883
- return macroTask;
884
- };
885
-
886
283
  // keep this import from core/build so the cjs build works
887
284
  const createPlatform = () => {
888
285
  return {
@@ -983,303 +380,101 @@ const isServerPlatform = () => {
983
380
  return false;
984
381
  };
985
382
 
986
- const hasDocument = typeof document !== 'undefined';
987
- const isBrowser = (qTest ? !isServerPlatform() : !isServer) && hasDocument;
988
- // Browser-specific setup
989
- const doc = isBrowser ? document : undefined;
990
- const config = {
991
- $maxIdlePreloads$: 25,
992
- };
993
- // Determine which rel attribute to use based on browser support
994
- const rel = isBrowser && doc.createElement('link').relList?.supports?.('modulepreload')
995
- ? 'modulePreload'
996
- : 'preload';
997
- const isJSRegex = /\.[mc]?js$/;
998
- const yieldInterval = 10;
999
-
1000
- const BundleImportState_None = 0;
1001
- const BundleImportState_Preload = 2;
1002
- const BundleImportState_Alias = 3;
1003
- const BundleImportState_Loaded = 4;
1004
-
1005
- let base;
1006
- const makeBundle = (name, deps) => {
1007
- return {
1008
- $name$: name,
1009
- $state$: isJSRegex.test(name) ? BundleImportState_None : BundleImportState_Alias,
1010
- $deps$: deps,
1011
- $inverseProbability$: 1,
1012
- $createdTs$: performance.now(),
1013
- $waitedMs$: 0,
1014
- $loadedMs$: 0,
1015
- };
1016
- };
1017
- const getBundle = (name) => {
1018
- let bundle = bundles.get(name);
1019
- if (!bundle) {
1020
- let deps;
1021
- bundle = makeBundle(name, deps);
1022
- bundles.set(name, bundle);
1023
- }
1024
- return bundle;
1025
- };
1026
-
1027
- const bundles = new Map();
1028
- let preloadCount = 0;
1029
- const queue = [];
1030
- const nextTriggerMacroTask = createMacroTask(trigger);
1031
- const nextAdjustmentMacroTask = createMacroTask(processPendingAdjustments);
1032
- let isTriggerScheduled = false;
1033
- let isAdjustmentScheduled = false;
1034
- let isProcessingAdjustments = false;
1035
- const adjustmentStack = [];
1036
- /**
1037
- * This is called when a bundle is queued, or finished loading.
1038
- *
1039
- * Because Chrome doesn't treat new modulepreloads as higher priority, we only make
1040
- * maxSimultaneousPreloads links available at a time, so that when a new high priority bundle comes
1041
- * in, it is soon preloaded.
1042
- *
1043
- * We make sure to first preload the high priority items.
1044
- */
1045
- function trigger() {
1046
- isTriggerScheduled = false;
1047
- if (!queue.length) {
1048
- return;
1049
- }
1050
- const deadline = performance.now() + yieldInterval;
1051
- let shouldYield = false;
1052
- while (queue.length) {
1053
- const bundle = queue[0];
1054
- const inverseProbability = bundle.$inverseProbability$;
1055
- const probability = 1 - inverseProbability;
1056
- // We want to preload all the transitive static (1) and dynamic (0.99) dependencies, throttled by the user defined maxIdlePreloads.
1057
- if (probability >= 0.99 || preloadCount < config.$maxIdlePreloads$) {
1058
- queue.shift();
1059
- preloadOne(bundle);
1060
- if (performance.now() >= deadline) {
1061
- shouldYield = true;
1062
- break;
1063
- }
1064
- }
1065
- else {
1066
- break;
383
+ const ASSERT_DISCLAIMER = 'Internal assert, this is likely caused by a bug in Qwik: ';
384
+ /*@__INLINE__*/
385
+ function assertDefined(value, text, ...parts) {
386
+ if (isDev) {
387
+ if (value != null) {
388
+ return;
1067
389
  }
1068
- }
1069
- if (shouldYield && queue.length && !isTriggerScheduled) {
1070
- isTriggerScheduled = true;
1071
- nextTriggerMacroTask();
390
+ throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts);
1072
391
  }
1073
392
  }
1074
- const enqueueAdjustment = (bundle, inverseProbability, seen) => {
1075
- // Keep existing work on the stack hot and append new roots behind it.
1076
- adjustmentStack.unshift({
1077
- $bundle$: bundle,
1078
- $inverseProbability$: inverseProbability,
1079
- $seen$: seen,
1080
- });
1081
- };
1082
- const processAdjustmentFrame = () => {
1083
- const frame = adjustmentStack[adjustmentStack.length - 1];
1084
- const bundle = frame.$bundle$;
1085
- if (frame.$deps$) {
1086
- const index = frame.$index$;
1087
- if (index >= frame.$deps$.length) {
1088
- adjustmentStack.pop();
1089
- return false;
1090
- }
1091
- const dep = frame.$deps$[index];
1092
- frame.$index$ = index + 1;
1093
- const depBundle = getBundle(dep.$name$);
1094
- if (depBundle.$inverseProbability$ === 0) {
1095
- return true;
1096
- }
1097
- const probability = 1 - bundle.$inverseProbability$;
1098
- let newInverseProbability;
1099
- if (probability === 1 || probability >= 0.99) {
1100
- // bundle is requested at max probability, so elevate all its transitive static and dynamic deps to 99% sure
1101
- newInverseProbability = Math.min(0.01, 1 - dep.$importProbability$);
393
+ /*@__INLINE__*/
394
+ function assertEqual(value1, value2, text, ...parts) {
395
+ if (isDev) {
396
+ if (value1 === value2) {
397
+ return;
1102
398
  }
1103
- else {
1104
- const newInverseImportProbability = 1 - dep.$importProbability$ * probability;
1105
- /** We need to undo the previous adjustment */
1106
- const prevAdjust = dep.$factor$;
1107
- const factor = newInverseImportProbability / prevAdjust;
1108
- // limit organic probability to 98%
1109
- newInverseProbability = Math.max(0.02, depBundle.$inverseProbability$ * factor);
1110
- dep.$factor$ = factor;
1111
- }
1112
- adjustmentStack.push({
1113
- $bundle$: depBundle,
1114
- $inverseProbability$: newInverseProbability,
1115
- $seen$: frame.$seen$,
1116
- });
1117
- return true;
1118
- }
1119
- if (frame.$seen$?.has(bundle)) {
1120
- adjustmentStack.pop();
1121
- return false;
1122
- }
1123
- const previousInverseProbability = bundle.$inverseProbability$;
1124
- bundle.$inverseProbability$ = frame.$inverseProbability$;
1125
- // Don't propagate tiny changes
1126
- if (previousInverseProbability - bundle.$inverseProbability$ < 0.01) {
1127
- adjustmentStack.pop();
1128
- return false;
1129
- }
1130
- if (bundle.$deps$?.length) {
1131
- const seen = frame.$seen$ || new Set();
1132
- seen.add(bundle);
1133
- frame.$seen$ = seen;
1134
- frame.$deps$ = bundle.$deps$;
1135
- frame.$index$ = 0;
1136
- return false;
1137
- }
1138
- adjustmentStack.pop();
1139
- return false;
1140
- };
1141
- function processPendingAdjustments() {
1142
- if (isProcessingAdjustments || !adjustmentStack.length) {
1143
- return;
399
+ throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts);
1144
400
  }
1145
- isAdjustmentScheduled = false;
1146
- isProcessingAdjustments = true;
1147
- const deadline = isBrowser ? performance.now() + yieldInterval : 0;
1148
- let processed = false;
1149
- while (adjustmentStack.length) {
1150
- processed = true;
1151
- const checkDeadline = processAdjustmentFrame();
1152
- if (isBrowser && checkDeadline && performance.now() >= deadline) {
1153
- if (!isAdjustmentScheduled) {
1154
- isAdjustmentScheduled = true;
1155
- nextAdjustmentMacroTask();
1156
- }
1157
- break;
401
+ }
402
+ /*@__INLINE__*/
403
+ function assertTrue(value1, text, ...parts) {
404
+ if (isDev) {
405
+ if (value1 === true) {
406
+ return;
1158
407
  }
1159
- }
1160
- isProcessingAdjustments = false;
1161
- if (processed && isBrowser) {
1162
- nextTriggerMacroTask();
408
+ throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts);
1163
409
  }
1164
410
  }
1165
- const preloadOne = (bundle) => {
1166
- if (bundle.$state$ >= BundleImportState_Preload) {
1167
- return;
1168
- }
1169
- preloadCount++;
1170
- const start = performance.now();
1171
- bundle.$waitedMs$ = start - bundle.$createdTs$;
1172
- bundle.$state$ = BundleImportState_Preload;
1173
- const link = doc.createElement('link');
1174
- // Only bundles with state none are js bundles
1175
- link.href = new URL(`${base}${bundle.$name$}`, doc.baseURI).toString();
1176
- link.rel = rel;
1177
- // Needed when rel is 'preload'
1178
- link.as = 'script';
1179
- // Handle completion of the preload
1180
- link.onload = link.onerror = () => {
1181
- preloadCount--;
1182
- const end = performance.now();
1183
- bundle.$loadedMs$ = end - start;
1184
- bundle.$state$ = BundleImportState_Loaded;
1185
- // Keep the <head> clean
1186
- link.remove();
1187
- // More bundles may be ready to preload
1188
- nextTriggerMacroTask();
1189
- };
1190
- doc.head.appendChild(link);
1191
- };
1192
- const handleBundle = (name, inverseProbability) => {
1193
- const bundle = getBundle(name);
1194
- if (bundle) {
1195
- enqueueAdjustment(bundle, inverseProbability);
1196
- }
1197
- };
1198
- const preload = (item, probability) => {
1199
- if (!item?.length) {
1200
- return;
1201
- }
1202
- const inverseProbability = 1 - probability ;
1203
- if (Array.isArray(item)) {
1204
- // We must process in reverse order to ensure first bundles are handled first
1205
- for (let i = item.length - 1; i >= 0; i--) {
1206
- const bundle = item[i];
1207
- handleBundle(bundle, inverseProbability);
411
+ /*@__INLINE__*/
412
+ function assertFalse(value1, text, ...parts) {
413
+ if (isDev) {
414
+ if (value1 === false) {
415
+ return;
1208
416
  }
417
+ throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts);
1209
418
  }
1210
- else {
1211
- handleBundle(item, inverseProbability);
1212
- }
1213
- if (isBrowser) {
1214
- nextAdjustmentMacroTask();
1215
- }
1216
- else {
1217
- processPendingAdjustments();
1218
- }
1219
- };
1220
- if (isBrowser) {
1221
- // Get early hints from qwikloader
1222
- document.addEventListener('qsymbol', (ev) => {
1223
- const { symbol, href } = ev.detail;
1224
- // the qrl class doesn't emit href, we don't need to preload
1225
- if (href) {
1226
- const hash = symbol.slice(symbol.lastIndexOf('_') + 1);
1227
- preload(hash, 1);
1228
- }
1229
- });
1230
419
  }
1231
-
1232
- const isObjectEmpty = (obj) => {
1233
- for (const key in obj) {
1234
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
1235
- return false;
420
+ /*@__INLINE__*/
421
+ function assertNumber(value1, text, ...parts) {
422
+ if (isDev) {
423
+ if (typeof value1 === 'number') {
424
+ return;
1236
425
  }
426
+ throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts);
1237
427
  }
1238
- return true;
1239
- };
428
+ }
1240
429
 
1241
430
  /** @internal */
1242
- const stringifyRootRefPath = (path) => {
1243
- let text = String(path[0]);
1244
- for (let i = 1; i < path.length; i++) {
1245
- text += ' ' + path[i];
431
+ const mapApp_findIndx = (array, key, start) => {
432
+ isDev && assertTrue(start % 2 === 0, 'Expecting even number.');
433
+ let bottom = start >> 1;
434
+ let top = (array.length - 2) >> 1;
435
+ while (bottom <= top) {
436
+ const mid = bottom + ((top - bottom) >> 1);
437
+ const midKey = array[mid << 1];
438
+ if (midKey === key) {
439
+ return mid << 1;
440
+ }
441
+ if (midKey < key) {
442
+ bottom = mid + 1;
443
+ }
444
+ else {
445
+ top = mid - 1;
446
+ }
1246
447
  }
1247
- return text;
448
+ return (bottom << 1) ^ -1;
1248
449
  };
1249
450
  /** @internal */
1250
- const writeStringRootRef = (writer, id) => writer.write(String(id));
1251
- /** @internal */
1252
- const writeStringRootRefPath = (writer, path) => writer.write(stringifyRootRefPath(path));
1253
- /** @internal */
1254
- const writeStringRootRefDelta = (writer, id, base) => writer.write(String(id - base));
1255
- /** @internal */
1256
- const createStringStreamWriter = (write) => ({
1257
- write,
1258
- writeRootRef(id) {
1259
- return writeStringRootRef(this, id);
1260
- },
1261
- writeRootRefPath(path) {
1262
- return writeStringRootRefPath(this, path);
1263
- },
1264
- writeRootRefDelta(id, base) {
1265
- return writeStringRootRefDelta(this, id, base);
1266
- },
1267
- });
1268
-
1269
- // Pre-allocated common strings to reduce allocation overhead
1270
- const CLOSE_TAG = '</';
1271
- const ESCAPED_CLOSE_TAG = '<\\/';
1272
- const QUOTE = '"';
1273
- const BRACKET_OPEN = '[';
1274
- const BRACKET_CLOSE = ']';
1275
- const COMMA = ',';
1276
-
1277
- /**
1278
- * QWIK_VERSION
1279
- *
1280
- * @public
1281
- */
1282
- const version = "2.0.0-beta.43-dev+e478dfb";
451
+ const mapArray_set = (array, key, value, start, allowNullValue = false) => {
452
+ const indx = mapApp_findIndx(array, key, start);
453
+ if (indx >= 0) {
454
+ if (value == null && !allowNullValue) {
455
+ array.splice(indx, 2);
456
+ }
457
+ else {
458
+ array[indx + 1] = value;
459
+ }
460
+ }
461
+ else if (value != null || allowNullValue) {
462
+ array.splice(indx ^ -1, 0, key, value);
463
+ }
464
+ };
465
+ /** @internal */
466
+ const mapArray_get = (array, key, start) => {
467
+ const indx = mapApp_findIndx(array, key, start);
468
+ if (indx >= 0) {
469
+ return array[indx + 1];
470
+ }
471
+ else {
472
+ return null;
473
+ }
474
+ };
475
+ const mapArray_has = (array, key, start) => {
476
+ return mapApp_findIndx(array, key, start) >= 0;
477
+ };
1283
478
 
1284
479
  const isNode = (value) => {
1285
480
  return value && typeof value.nodeType === 'number';
@@ -1291,6 +486,108 @@ const isElement$1 = (value) => {
1291
486
  return value.nodeType === 1;
1292
487
  };
1293
488
 
489
+ const MAX_RETRY_ON_PROMISE_COUNT = 100;
490
+ const isPromise = (value) => {
491
+ try {
492
+ // not using "value instanceof Promise" to have zone.js support
493
+ return !!value && typeof value == 'object' && typeof value.then === 'function';
494
+ }
495
+ catch {
496
+ return false;
497
+ }
498
+ };
499
+ const safeCall = (call, thenFn, rejectFn) => {
500
+ try {
501
+ const result = call();
502
+ if (isPromise(result)) {
503
+ return result.then(thenFn, rejectFn);
504
+ }
505
+ else {
506
+ return thenFn(result);
507
+ }
508
+ }
509
+ catch (e) {
510
+ return rejectFn(e);
511
+ }
512
+ };
513
+ const maybeThen = (valueOrPromise, thenFn) => {
514
+ return isPromise(valueOrPromise)
515
+ ? valueOrPromise.then(thenFn)
516
+ : thenFn(valueOrPromise);
517
+ };
518
+ /** @internal */
519
+ const delay = (timeout) => {
520
+ return new Promise((resolve) => {
521
+ setTimeout(resolve, timeout);
522
+ });
523
+ };
524
+ const checkError = (e) => {
525
+ try {
526
+ if (isServer && e instanceof ReferenceError && e.message.includes('window')) {
527
+ e.message = 'It seems like you forgot to add "if (isBrowser) {...}" here:' + e.message;
528
+ }
529
+ }
530
+ catch {
531
+ // ignore
532
+ }
533
+ };
534
+ const justThrow = (e) => {
535
+ throw e;
536
+ };
537
+ /**
538
+ * Retries a function that throws a promise. If you pass `onError`, you're responsible for handling
539
+ * errors.
540
+ *
541
+ * @internal
542
+ */
543
+ function retryOnPromise(fn, onError = justThrow) {
544
+ let ok = false;
545
+ let result;
546
+ try {
547
+ result = fn();
548
+ ok = true;
549
+ }
550
+ catch (e) {
551
+ result = e;
552
+ }
553
+ if (!isPromise(result)) {
554
+ // Synchronous function or error, no need to retry
555
+ if (ok) {
556
+ return result;
557
+ }
558
+ isDev && checkError(result);
559
+ return onError(result);
560
+ }
561
+ let retryCount = MAX_RETRY_ON_PROMISE_COUNT;
562
+ const retry = async (p) => {
563
+ while (isPromise(p)) {
564
+ try {
565
+ await p;
566
+ // We waited for the thrown promise, now try again
567
+ return await fn();
568
+ }
569
+ catch (err) {
570
+ if (isPromise(err)) {
571
+ if (!--retryCount) {
572
+ p = new Error('Exceeded max retry count in retryOnPromise');
573
+ break;
574
+ }
575
+ else {
576
+ p = err;
577
+ }
578
+ }
579
+ else {
580
+ p = err;
581
+ break;
582
+ }
583
+ }
584
+ }
585
+ isDev && checkError(p);
586
+ return onError(p);
587
+ };
588
+ return ok ? result.catch(retry) : retry(result);
589
+ }
590
+
1294
591
  /** @internal */
1295
592
  const getRootContainer = (container) => {
1296
593
  const rootContainer = container.$rootContainer$;
@@ -1312,6 +609,80 @@ class BackRef {
1312
609
  [_EFFECT_BACK_REF] = undefined;
1313
610
  }
1314
611
 
612
+ /**
613
+ * A friendly name tag for a VirtualVNode.
614
+ *
615
+ * Theses are used to give a name to a VirtualVNode. This is useful for debugging and testing.
616
+ *
617
+ * The name is only added in development mode and is not included in production builds.
618
+ */
619
+ const DEBUG_TYPE = 'q:type';
620
+ const VirtualTypeName = {
621
+ ["V" /* VirtualType.Virtual */]: /* ********* */ 'Virtual', //
622
+ ["F" /* VirtualType.Fragment */]: /* ******** */ 'Fragment', //
623
+ ["S" /* VirtualType.WrappedSignal */]: /* *** */ 'Signal', //
624
+ ["A" /* VirtualType.Awaited */]: /* ********* */ 'Awaited', //
625
+ ["C" /* VirtualType.Component */]: /* ******* */ 'Component', //
626
+ ["I" /* VirtualType.InlineComponent */]: /* * */ 'InlineComponent', //
627
+ ["P" /* VirtualType.Projection */]: /* ****** */ 'Projection', //
628
+ };
629
+
630
+ /**
631
+ * @file
632
+ *
633
+ * VNodeData is additional information which allows the `vnode` to recover virtual VNode information
634
+ * from the HTML.
635
+ */
636
+ /**
637
+ * VNodeDataSeparator contains information about splitting up the VNodeData and attaching it to the
638
+ * HTML.
639
+ */
640
+ const VNodeDataSeparator = {
641
+ REFERENCE: /* ******** */ 126, // `~` is a reference to the node. Save it.
642
+ ADVANCE_1: /* ********* */ 33, // `!` is vNodeData separator skipping 0. (ie next vNode)
643
+ ADVANCE_8192: /* ****** */ 46, // `.` is vNodeData separator skipping 4096.
644
+ };
645
+ /**
646
+ * VNodeDataChar contains information about the VNodeData used for encoding props.
647
+ *
648
+ * Available character ranges: 59 - 64, 91 - 94, 96, 123 - 126
649
+ */
650
+ const VNodeDataChar = {
651
+ OPEN: /* ************** */ 123, // `{` is the start of the VNodeData for a virtual element.
652
+ CLOSE: /* ************* */ 125, // `}` is the end of the VNodeData for a virtual element.
653
+ SCOPED_STYLE: /* ******* */ 59, // `;` - `q:sstyle` - Style attribute.
654
+ RENDER_FN: /* ********** */ 60, // `<` - `q:renderFn' - Component QRL render function (body)
655
+ RENDER_HASH_PREFIX: /* **/ 95, // `_` after `<` identifies a component hash.
656
+ ID: /* ***************** */ 61, // `=` - `q:id` - ID of the element.
657
+ PROPS: /* ************** */ 62, // `>` - `q:props' - Component Props
658
+ SLOT_PARENT: /* ******** */ 63, // `?` - `q:sparent` - Slot parent.
659
+ KEY: /* **************** */ 64, // `@` - `q:key` - Element key.
660
+ SEQ: /* **************** */ 91, // `[` - `q:seq' - Seq value from `useSequentialScope()`
661
+ CONTEXT: /* ************ */ 93, // `]` - `q:ctx' - Component context/props
662
+ SEQ_IDX: /* ************ */ 94, // `^` - `q:seqIdx' - Sequential scope id
663
+ BACK_REFS: /* ********** */ 96, // '`' - `q:brefs' - Effect dependencies/subscriptions
664
+ SEPARATOR: /* ********* */ 124, // `|` - Separator char to encode any key/value pairs.
665
+ SLOT: /* ************** */ 126};
666
+ /**
667
+ * Convert a segment-local vnode index into a key for the root container's shared qVNodeRefs map.
668
+ *
669
+ * Out-of-order Suspense segments each start counting vnode refs from 0, but the client merges all
670
+ * segment refs into one root-level map. This uses a Cantor-style pairing function for the
671
+ * zero-based pair `(segmentIndex, localIndex)`, then makes it negative so segment refs cannot
672
+ * collide with root refs, which are non-negative.
673
+ *
674
+ * Examples:
675
+ *
676
+ * - Segment 1, local 0 -> -1
677
+ * - Segment 2, local 0 -> -2
678
+ * - Segment 1, local 1 -> -3
679
+ */
680
+ const getSegmentVNodeRefId = (segmentId, localIndex) => {
681
+ const segmentIndex = parseInt(segmentId, 10) - 1;
682
+ const diagonal = segmentIndex + localIndex;
683
+ return -((diagonal * (diagonal + 1)) / 2 + localIndex + 1);
684
+ };
685
+
1315
686
  const isForeignObjectElement = (elementName) => {
1316
687
  return isDev ? elementName.toLowerCase() === 'foreignobject' : elementName === 'foreignObject';
1317
688
  };
@@ -1528,13 +899,85 @@ function getAttributeNamespace(attributeName) {
1528
899
  return null;
1529
900
  }
1530
901
  }
1531
-
1532
- const mergeMaps = (map1, map2) => {
1533
- for (const [k, v] of map2) {
1534
- map1.set(k, v);
1535
- }
1536
- return map1;
902
+
903
+ const mergeMaps = (map1, map2) => {
904
+ for (const [k, v] of map2) {
905
+ map1.set(k, v);
906
+ }
907
+ return map1;
908
+ };
909
+
910
+ /**
911
+ * Think of `-` as an escape character which makes the next character uppercase. `--` is just `-`.
912
+ *
913
+ * Rules for JSX property event names starting with `on`:
914
+ *
915
+ * - Are case insensitive: `onClick$` is same `onclick$`
916
+ * - A `--` is `-`: `dbl--click` => `dbl-click`
917
+ * - Become case sensitive if prefixed by `-`: `-Click` is `Click`
918
+ * - A `-` (not at the beginning) makes next character uppercase: `dbl-click` => `dblClick`
919
+ */
920
+ const EVENT_SUFFIX = '$';
921
+ const DOM_CONTENT_LOADED_EVENT = 'DOMContentLoaded';
922
+ const isHtmlAttributeAnEventName = (name) => {
923
+ return (name.charCodeAt(0) === 113 /* q */ &&
924
+ name.charCodeAt(1) === 45 /* - */ &&
925
+ (name.charCodeAt(3) === 58 /* : */ ||
926
+ (name.charCodeAt(3) === 112 /* p */ && name.charCodeAt(4) === 58)) /* : */);
927
+ };
928
+ function jsxEventToHtmlAttribute(jsxEvent, isPassive = false) {
929
+ if (jsxEvent.endsWith(EVENT_SUFFIX)) {
930
+ const [prefix, idx] = getEventScopeDataFromJsxEvent(jsxEvent, isPassive);
931
+ if (idx !== -1) {
932
+ return prefix + normalizeJsxEventName(jsxEvent.slice(idx, -1));
933
+ }
934
+ }
935
+ return null; // Return null if not matching expected format
936
+ }
937
+ function createEventName(event, prefix = '') {
938
+ const eventName = fromCamelToKebabCase(event);
939
+ return prefix + eventName;
940
+ }
941
+ function getEventScopeDataFromJsxEvent(eventName, isPassive = false) {
942
+ let prefix;
943
+ let idx = -1;
944
+ // set prefix and idx based on the scope
945
+ if (eventName.startsWith("on" /* EventNameJSXScope.on */)) {
946
+ prefix = isPassive ? "q-ep:" /* EventNameHtmlScope.onPassive */ : "q-e:" /* EventNameHtmlScope.on */;
947
+ idx = 2;
948
+ }
949
+ else if (eventName.startsWith("window:on" /* EventNameJSXScope.window */)) {
950
+ prefix = isPassive ? "q-wp:" /* EventNameHtmlScope.windowPassive */ : "q-w:" /* EventNameHtmlScope.window */;
951
+ idx = 9;
952
+ }
953
+ else if (eventName.startsWith("document:on" /* EventNameJSXScope.document */)) {
954
+ prefix = isPassive ? "q-dp:" /* EventNameHtmlScope.documentPassive */ : "q-d:" /* EventNameHtmlScope.document */;
955
+ idx = 11;
956
+ }
957
+ return [prefix, idx];
958
+ }
959
+ const normalizeJsxEventName = (name) => {
960
+ return name === DOM_CONTENT_LOADED_EVENT
961
+ ? '-d-o-m-content-loaded'
962
+ : createEventName(name.charAt(0) === '-'
963
+ ? // marker for case sensitive event name
964
+ name.slice(1)
965
+ : name.toLowerCase());
966
+ };
967
+ function isPreventDefault(key) {
968
+ return key.startsWith('preventdefault:');
969
+ }
970
+ /** Converts a camelCase string to kebab-case. This is used for event names. */
971
+ const fromCamelToKebabCase = (text) => {
972
+ return text.replace(/([A-Z-])/g, (a) => '-' + a.toLowerCase());
973
+ };
974
+ /** E.g. `"q-e:click"` => `['e', 'click']`, `"q-ep:click"` => `['ep', 'click']` */
975
+ const getEventDataFromHtmlAttribute = (htmlKey) => {
976
+ const separatorIndex = htmlKey.indexOf(':');
977
+ return [htmlKey.slice(2, separatorIndex), htmlKey.slice(separatorIndex + 1)];
1537
978
  };
979
+ /** E.g. `"e:click"`, `"w:load"` */
980
+ const getScopedEventName = (scope, eventName) => scope + ':' + eventName;
1538
981
 
1539
982
  /** @internal */
1540
983
  class VNode {
@@ -1722,6 +1165,24 @@ const NODE_DIFF_DATA_KEY = ':nodeDiff';
1722
1165
  const ERROR_DATA_KEY = ':errorData';
1723
1166
  const HOST_SIGNAL = ':signal';
1724
1167
  const INLINE_COMPONENT_DATA_KEY = ':inlineComponentData';
1168
+ /** Qwik loader events to (re)register once the cursor's journal is flushed to the DOM. */
1169
+ const pendingQwikLoaderEvents = new WeakMap();
1170
+ function queueQwikLoaderEvent(cursorData, eventName) {
1171
+ let loaderEvents = pendingQwikLoaderEvents.get(cursorData);
1172
+ if (!loaderEvents) {
1173
+ pendingQwikLoaderEvents.set(cursorData, (loaderEvents = []));
1174
+ }
1175
+ if (!loaderEvents.includes(eventName)) {
1176
+ loaderEvents.push(eventName);
1177
+ }
1178
+ }
1179
+ function getPendingQwikLoaderEvents(cursorData) {
1180
+ const loaderEvents = pendingQwikLoaderEvents.get(cursorData);
1181
+ if (loaderEvents) {
1182
+ pendingQwikLoaderEvents.delete(cursorData);
1183
+ }
1184
+ return loaderEvents;
1185
+ }
1725
1186
  /**
1726
1187
  * Sets the cursor position in a cursor vNode.
1727
1188
  *
@@ -1759,6 +1220,13 @@ function mergeCursorData(newCursorData, oldCursorData) {
1759
1220
  newCursorData.afterFlushTasks = oldAfterFlushTasks;
1760
1221
  }
1761
1222
  }
1223
+ // merge qwik loader event notifications
1224
+ const oldLoaderEvents = getPendingQwikLoaderEvents(oldCursorData);
1225
+ if (oldLoaderEvents) {
1226
+ for (let i = 0; i < oldLoaderEvents.length; i++) {
1227
+ queueQwikLoaderEvent(newCursorData, oldLoaderEvents[i]);
1228
+ }
1229
+ }
1762
1230
  // merge extra promises
1763
1231
  const oldExtraPromises = oldCursorData.extraPromises;
1764
1232
  if (oldExtraPromises && oldExtraPromises.length > 0) {
@@ -2321,10 +1789,23 @@ class Job {
2321
1789
  }
2322
1790
  }
2323
1791
  get track() {
2324
- return (this.$track$ ||= trackFn(this.$signal$, this.$signal$.$container$));
1792
+ if (!this.$track$) {
1793
+ const track = trackFn(this.$signal$, this.$signal$.$container$);
1794
+ this.$track$ = (obj, prop) => {
1795
+ if (this.$signal$.$disposed$) {
1796
+ throw qError(39 /* QError.computedSignalDisposed */);
1797
+ }
1798
+ return track(obj, prop);
1799
+ };
1800
+ }
1801
+ return this.$track$;
2325
1802
  }
2326
1803
  get abortSignal() {
2327
- return (this.$abortController$ ||= new AbortController()).signal;
1804
+ const controller = (this.$abortController$ ||= new AbortController());
1805
+ if (this.$cleanupRequested$) {
1806
+ controller.abort();
1807
+ }
1808
+ return controller.signal;
2328
1809
  }
2329
1810
  /** Backward compatible cache method for resource */
2330
1811
  cache() {
@@ -2337,11 +1818,12 @@ class Job {
2337
1818
  return val;
2338
1819
  }
2339
1820
  }
2340
- cleanup(callback) {
1821
+ // Arrow property so the compute function can destructure `cleanup` from the context.
1822
+ cleanup = (callback) => {
2341
1823
  if (typeof callback === 'function') {
2342
1824
  (this.$cleanups$ ||= []).push(callback);
2343
1825
  }
2344
- }
1826
+ };
2345
1827
  }
2346
1828
  /**
2347
1829
  * A signal which is computed from other signals.
@@ -2403,6 +1885,9 @@ class ComputedSignalImpl extends SignalImpl {
2403
1885
  this.invalidate();
2404
1886
  }
2405
1887
  invalidate(info) {
1888
+ if (this.$disposed$) {
1889
+ return;
1890
+ }
2406
1891
  if (arguments.length > 0) {
2407
1892
  this.$info$ = info;
2408
1893
  this.$infoVersion$ = this.$infoVersion$ === undefined ? 1 : this.$infoVersion$ + 1;
@@ -2577,6 +2062,9 @@ class ComputedSignalImpl extends SignalImpl {
2577
2062
  return this.$untrackedError$;
2578
2063
  }
2579
2064
  $setInvalid$(allowRecalc) {
2065
+ if (this.$disposed$) {
2066
+ return;
2067
+ }
2580
2068
  this.$flags$ |= 1 /* ComputedSignalFlags.INVALID */;
2581
2069
  if (allowRecalc &&
2582
2070
  (this.$effects$?.size || this.$loadingEffects$?.size || this.$errorEffects$?.size)) {
@@ -2595,7 +2083,7 @@ class ComputedSignalImpl extends SignalImpl {
2595
2083
  if (!(this.$flags$ & 32 /* AsyncSignalFlags.EAGER_CLEANUP */) || this.$hasSubscribers$()) {
2596
2084
  return;
2597
2085
  }
2598
- if (!(qTest ? !isServerPlatform() : isBrowser$1)) {
2086
+ if (!(qTest ? !isServerPlatform() : isBrowser)) {
2599
2087
  return;
2600
2088
  }
2601
2089
  setTimeout(() => {
@@ -2606,7 +2094,7 @@ class ComputedSignalImpl extends SignalImpl {
2606
2094
  }
2607
2095
  /** Returns a promise resolves when the signal finished computing. */
2608
2096
  async promise() {
2609
- this.$computeIfNeeded$();
2097
+ await retryOnPromise(() => this.$computeIfNeeded$());
2610
2098
  // Wait for the current computation to finish, but if we became invalid while running, we need to wait for the new computation instead. So we loop until we are no longer invalid
2611
2099
  while (this.$current$?.$promise$) {
2612
2100
  await this.$current$?.$promise$;
@@ -2614,7 +2102,7 @@ class ComputedSignalImpl extends SignalImpl {
2614
2102
  }
2615
2103
  /** Run the computation if needed */
2616
2104
  $computeIfNeeded$() {
2617
- if (!(this.$flags$ & 1 /* ComputedSignalFlags.INVALID */)) {
2105
+ if (this.$disposed$ || !(this.$flags$ & 1 /* ComputedSignalFlags.INVALID */)) {
2618
2106
  return;
2619
2107
  }
2620
2108
  if (this.$flags$ & 512 /* AsyncSignalFlags.ASYNC_MODE */) {
@@ -2674,6 +2162,9 @@ class ComputedSignalImpl extends SignalImpl {
2674
2162
  * instead; after the first await they must use the explicit track() too.
2675
2163
  */
2676
2164
  $invokeComputeFn$(fn, job) {
2165
+ if (this.$disposed$) {
2166
+ throw qError(39 /* QError.computedSignalDisposed */);
2167
+ }
2677
2168
  const computeFn = fn;
2678
2169
  if (this.$flags$ & 1024 /* AsyncSignalFlags.CTX_ARG */) {
2679
2170
  // Strip the ambient effect subscriber: these compute fns track only via their track()
@@ -2732,7 +2223,7 @@ class ComputedSignalImpl extends SignalImpl {
2732
2223
  // subscribers know the value isn't ready yet.
2733
2224
  this.untrackedPending = true;
2734
2225
  fn = await this.$computeQrl$.resolve();
2735
- if (running.$abortController$?.signal.aborted) {
2226
+ if (this.$disposed$ || running.$abortController$?.signal.aborted) {
2736
2227
  running.$promise$ = null;
2737
2228
  return;
2738
2229
  }
@@ -2793,7 +2284,7 @@ class ComputedSignalImpl extends SignalImpl {
2793
2284
  running.$promise$ = null;
2794
2285
  this.$setError$(running, err);
2795
2286
  }
2796
- if (isCurrent()) {
2287
+ if (isCurrent() && !this.$disposed$) {
2797
2288
  clearTimeout(this.$computationTimeoutId$);
2798
2289
  if (running.$infoVersion$ === this.$infoVersion$) {
2799
2290
  this.$info$ = undefined;
@@ -2824,7 +2315,27 @@ class ComputedSignalImpl extends SignalImpl {
2824
2315
  // Job failures should be rare and require retrying
2825
2316
  this.untrackedValue = NEEDS_COMPUTATION;
2826
2317
  }
2827
- /** Called after SSR/unmount */
2318
+ /** Permanently stop computations; keep this cross-package name stable. */
2319
+ $dispose() {
2320
+ if (this.$disposed$) {
2321
+ return;
2322
+ }
2323
+ this.$disposed$ = true;
2324
+ this.$flags$ &= -2 /* ComputedSignalFlags.INVALID */;
2325
+ clearTimeout(this.$computationTimeoutId$);
2326
+ if (this.$container$) {
2327
+ clearAllEffects(this.$container$, this);
2328
+ }
2329
+ const jobs = new Set(this.$jobs$);
2330
+ if (this.$current$) {
2331
+ jobs.add(this.$current$);
2332
+ }
2333
+ for (const job of jobs) {
2334
+ job.$canWrite$ = false;
2335
+ this.$requestCleanups$(job);
2336
+ }
2337
+ }
2338
+ /** Clean computations after SSR while preserving dependencies for serialization. */
2828
2339
  async $destroy$() {
2829
2340
  clearTimeout(this.$computationTimeoutId$);
2830
2341
  const current = this.$current$;
@@ -3049,9 +2560,9 @@ const createSignal = createSignal$1;
3049
2560
  *
3050
2561
  * The QRL must be a function which returns the value of the signal. The function must not have side
3051
2562
  * effects. Every synchronous signal or store read is tracked automatically; reads after the first
3052
- * `await` must use the `track()` provided on the context argument. When the function is async, the
3053
- * returned signal exposes the async API (`.pending`, `.error`, `.promise()`), and reading an
3054
- * unresolved `.value` throws the computation promise.
2563
+ * `await` must use the `track()` provided on the context argument. When the function is async,
2564
+ * reading an unresolved `.value` throws the computation promise, and reading a failed `.value`
2565
+ * throws the error.
3055
2566
  *
3056
2567
  * @public
3057
2568
  */
@@ -3229,6 +2740,15 @@ class SubscriptionData {
3229
2740
  }
3230
2741
  }
3231
2742
 
2743
+ const isObjectEmpty = (obj) => {
2744
+ for (const key in obj) {
2745
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
2746
+ return false;
2747
+ }
2748
+ }
2749
+ return true;
2750
+ };
2751
+
3232
2752
  const _hasOwnProperty$3 = Object.prototype.hasOwnProperty;
3233
2753
  // TODO store props as the arrays the vnodes also use?
3234
2754
  class JSXNodeImpl {
@@ -3777,6 +3297,58 @@ function directSetAttribute(element, attrName, attrValue, isSvg) {
3777
3297
  }
3778
3298
  }
3779
3299
 
3300
+ function escapeHTML(html) {
3301
+ let escapedHTML = '';
3302
+ const length = html.length;
3303
+ let idx = 0;
3304
+ let lastIdx = idx;
3305
+ for (; idx < length; idx++) {
3306
+ // We get the charCode NOT string. String would allocate memory.
3307
+ const ch = html.charCodeAt(idx);
3308
+ // Every time we concat a string we allocate memory. We want to minimize that.
3309
+ if (ch === 60 /* < */) {
3310
+ escapedHTML += html.substring(lastIdx, idx) + '&lt;';
3311
+ }
3312
+ else if (ch === 62 /* > */) {
3313
+ escapedHTML += html.substring(lastIdx, idx) + '&gt;';
3314
+ }
3315
+ else if (ch === 38 /* & */) {
3316
+ escapedHTML += html.substring(lastIdx, idx) + '&amp;';
3317
+ }
3318
+ else if (ch === 34 /* " */) {
3319
+ escapedHTML += html.substring(lastIdx, idx) + '&quot;';
3320
+ }
3321
+ else if (ch === 39 /* ' */) {
3322
+ escapedHTML += html.substring(lastIdx, idx) + '&#39;';
3323
+ }
3324
+ else {
3325
+ continue;
3326
+ }
3327
+ lastIdx = idx + 1;
3328
+ }
3329
+ if (lastIdx === 0) {
3330
+ // This is most common case, just return previous string no memory allocation.
3331
+ return html;
3332
+ }
3333
+ else {
3334
+ // Add the tail of replacement.
3335
+ return escapedHTML + html.substring(lastIdx);
3336
+ }
3337
+ }
3338
+ function decodeVNodeDataString(str) {
3339
+ let result = '';
3340
+ for (let i = 0; i < str.length; i++) {
3341
+ if (str.charAt(i) === '\\' && i + 1 < str.length) {
3342
+ result += str.charAt(i + 1);
3343
+ i++;
3344
+ }
3345
+ else {
3346
+ result += str.charAt(i);
3347
+ }
3348
+ }
3349
+ return result;
3350
+ }
3351
+
3780
3352
  function getFileLocationFromJsx(jsxDev) {
3781
3353
  if (!jsxDev) {
3782
3354
  return null;
@@ -3801,65 +3373,247 @@ function hasSlotProps(props) {
3801
3373
  }
3802
3374
  }
3803
3375
  }
3804
- return false;
3805
- }
3806
- /** @internal */
3807
- const _restProps = (props, omit = [], target = {}) => {
3808
- // The optimizer can apply this transform to plain, non-component objects and
3809
- // even primitives (e.g. destructuring a string). Guard `isPropsProxy`, whose
3810
- // `in` check throws on primitives, then fall back to native object-rest
3811
- // copying so the transform cannot silently lose data.
3812
- if (!isObject(props) || !isPropsProxy(props)) {
3813
- // Match native rest-destructuring: `({ ...rest }) => …` throws on nullish.
3814
- if (props == null) {
3815
- throw new TypeError(`Cannot destructure '${props}' as it is ${props}.`);
3816
- }
3817
- // Box primitives so they get native ToObject rest semantics (e.g. 'ab' -> {0:'a',1:'b'}).
3818
- const source = Object(props);
3819
- const keys = Reflect.ownKeys(source);
3820
- for (let i = 0; i < keys.length; i++) {
3821
- const key = keys[i];
3822
- if (_propertyIsEnumerable.call(source, key) &&
3823
- (typeof key === 'symbol' || !omit.includes(key))) {
3824
- Object.defineProperty(target, key, {
3825
- value: source[key],
3826
- enumerable: true,
3827
- configurable: true,
3828
- writable: true,
3829
- });
3376
+ return false;
3377
+ }
3378
+ /** @internal */
3379
+ const _restProps = (props, omit = [], target = {}) => {
3380
+ // The optimizer can apply this transform to plain, non-component objects and
3381
+ // even primitives (e.g. destructuring a string). Guard `isPropsProxy`, whose
3382
+ // `in` check throws on primitives, then fall back to native object-rest
3383
+ // copying so the transform cannot silently lose data.
3384
+ if (!isObject(props) || !isPropsProxy(props)) {
3385
+ // Match native rest-destructuring: `({ ...rest }) => …` throws on nullish.
3386
+ if (props == null) {
3387
+ throw new TypeError(`Cannot destructure '${props}' as it is ${props}.`);
3388
+ }
3389
+ // Box primitives so they get native ToObject rest semantics (e.g. 'ab' -> {0:'a',1:'b'}).
3390
+ const source = Object(props);
3391
+ const keys = Reflect.ownKeys(source);
3392
+ for (let i = 0; i < keys.length; i++) {
3393
+ const key = keys[i];
3394
+ if (_propertyIsEnumerable.call(source, key) &&
3395
+ (typeof key === 'symbol' || !omit.includes(key))) {
3396
+ Object.defineProperty(target, key, {
3397
+ value: source[key],
3398
+ enumerable: true,
3399
+ configurable: true,
3400
+ writable: true,
3401
+ });
3402
+ }
3403
+ }
3404
+ return target;
3405
+ }
3406
+ let constPropsTarget = null;
3407
+ const constProps = props[_CONST_PROPS];
3408
+ if (constProps) {
3409
+ for (const key in constProps) {
3410
+ if (!omit.includes(key)) {
3411
+ constPropsTarget ||= {};
3412
+ constPropsTarget[key] = constProps[key];
3413
+ }
3414
+ }
3415
+ }
3416
+ const varPropsTarget = target;
3417
+ const varProps = props[_VAR_PROPS];
3418
+ for (const key in varProps) {
3419
+ if (!omit.includes(key)) {
3420
+ varPropsTarget[key] = varProps[key];
3421
+ }
3422
+ }
3423
+ return createPropsProxy(new JSXNodeImpl(null, varPropsTarget, constPropsTarget, null, 0, null));
3424
+ };
3425
+ function resolveSlotName(host, jsx, container) {
3426
+ const constProps = jsx.constProps;
3427
+ if (constProps && typeof constProps == 'object' && _hasOwnProperty$1.call(constProps, 'name')) {
3428
+ const constValue = constProps.name;
3429
+ if (host && constValue instanceof WrappedSignalImpl) {
3430
+ return trackSignalAndAssignHost(constValue, host, ":" /* EffectProperty.COMPONENT */, container);
3431
+ }
3432
+ }
3433
+ return directGetPropsProxyProp(jsx, 'name') || QDefaultSlot;
3434
+ }
3435
+
3436
+ const styleContent = (styleId) => {
3437
+ return ComponentStylesPrefixContent + styleId;
3438
+ };
3439
+ function isClassAttr(key) {
3440
+ return key === 'class';
3441
+ }
3442
+ function convertScopedStyleIdsToArray(scopedStyleIds) {
3443
+ return scopedStyleIds?.split(' ') ?? null;
3444
+ }
3445
+ function convertStyleIdsToString(scopedStyleIds) {
3446
+ return Array.from(scopedStyleIds).join(' ');
3447
+ }
3448
+ const addComponentStylePrefix = (styleId) => {
3449
+ if (styleId) {
3450
+ let idx = 0;
3451
+ do {
3452
+ styleId = styleId.substring(0, idx) + styleContent(styleId.substring(idx));
3453
+ } while ((idx = styleId.indexOf(' ', idx) + 1) !== 0);
3454
+ }
3455
+ return styleId || null;
3456
+ };
3457
+
3458
+ /** CSS properties which accept numbers but are not in units of "px". */
3459
+ const unitlessNumbers = new Set([
3460
+ 'animationIterationCount',
3461
+ 'aspectRatio',
3462
+ 'borderImageOutset',
3463
+ 'borderImageSlice',
3464
+ 'borderImageWidth',
3465
+ 'boxFlex',
3466
+ 'boxFlexGroup',
3467
+ 'boxOrdinalGroup',
3468
+ 'columnCount',
3469
+ 'columns',
3470
+ 'flex',
3471
+ 'flexGrow',
3472
+ 'flexShrink',
3473
+ 'gridArea',
3474
+ 'gridRow',
3475
+ 'gridRowEnd',
3476
+ 'gridRowStart',
3477
+ 'gridColumn',
3478
+ 'gridColumnEnd',
3479
+ 'gridColumnStart',
3480
+ 'fontWeight',
3481
+ 'lineClamp',
3482
+ 'lineHeight',
3483
+ 'opacity',
3484
+ 'order',
3485
+ 'orphans',
3486
+ 'scale',
3487
+ 'tabSize',
3488
+ 'widows',
3489
+ 'zIndex',
3490
+ 'zoom',
3491
+ 'MozAnimationIterationCount', // Known Prefixed Properties
3492
+ 'MozBoxFlex', // TODO: Remove these since they shouldn't be used in modern code
3493
+ 'msFlex',
3494
+ 'msFlexPositive',
3495
+ 'WebkitAnimationIterationCount',
3496
+ 'WebkitBoxFlex',
3497
+ 'WebkitBoxOrdinalGroup',
3498
+ 'WebkitColumnCount',
3499
+ 'WebkitColumns',
3500
+ 'WebkitFlex',
3501
+ 'WebkitFlexGrow',
3502
+ 'WebkitFlexShrink',
3503
+ 'WebkitLineClamp',
3504
+ ]);
3505
+ const isUnitlessNumber = (name) => {
3506
+ return unitlessNumbers.has(name);
3507
+ };
3508
+
3509
+ const hashCode = (text, hash = 0) => {
3510
+ for (let i = 0; i < text.length; i++) {
3511
+ const chr = text.charCodeAt(i);
3512
+ hash = (hash << 5) - hash + chr;
3513
+ hash |= 0; // Convert to 32bit integer
3514
+ }
3515
+ return Number(Math.abs(hash)).toString(36);
3516
+ };
3517
+
3518
+ const serializeClass = (obj) => {
3519
+ if (!obj) {
3520
+ return '';
3521
+ }
3522
+ if (isString(obj)) {
3523
+ return obj.trim();
3524
+ }
3525
+ const classes = [];
3526
+ if (isArray(obj)) {
3527
+ for (let i = 0; i < obj.length; i++) {
3528
+ const o = obj[i];
3529
+ const classList = serializeClass(o);
3530
+ if (classList) {
3531
+ classes.push(classList);
3830
3532
  }
3831
3533
  }
3832
- return target;
3833
3534
  }
3834
- let constPropsTarget = null;
3835
- const constProps = props[_CONST_PROPS];
3836
- if (constProps) {
3837
- for (const key in constProps) {
3838
- if (!omit.includes(key)) {
3839
- constPropsTarget ||= {};
3840
- constPropsTarget[key] = constProps[key];
3535
+ else {
3536
+ for (const [key, value] of Object.entries(obj)) {
3537
+ if (value) {
3538
+ classes.push(key.trim());
3841
3539
  }
3842
3540
  }
3843
3541
  }
3844
- const varPropsTarget = target;
3845
- const varProps = props[_VAR_PROPS];
3846
- for (const key in varProps) {
3847
- if (!omit.includes(key)) {
3848
- varPropsTarget[key] = varProps[key];
3542
+ return classes.join(' ');
3543
+ };
3544
+ // Unlike fromCamelToKebabCase, this leaves `-` so that `background-color` stays `background-color`
3545
+ const fromCamelToKebabCaseWithDash = (text) => {
3546
+ return text.replace(/([A-Z])/g, '-$1').toLowerCase();
3547
+ };
3548
+ const stringifyStyle = (obj) => {
3549
+ if (obj == null) {
3550
+ return '';
3551
+ }
3552
+ if (typeof obj == 'object') {
3553
+ if (isArray(obj)) {
3554
+ throw qError(0 /* QError.stringifyClassOrStyle */, [obj, 'style']);
3555
+ }
3556
+ else {
3557
+ const chunks = [];
3558
+ for (const key in obj) {
3559
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
3560
+ const value = obj[key];
3561
+ if (value != null && typeof value !== 'function') {
3562
+ if (key.startsWith('--')) {
3563
+ chunks.push(key + ':' + value);
3564
+ }
3565
+ else {
3566
+ chunks.push(fromCamelToKebabCaseWithDash(key) + ':' + setValueForStyle(key, value));
3567
+ }
3568
+ }
3569
+ }
3570
+ }
3571
+ return chunks.join(';');
3849
3572
  }
3850
3573
  }
3851
- return createPropsProxy(new JSXNodeImpl(null, varPropsTarget, constPropsTarget, null, 0, null));
3574
+ return String(obj);
3852
3575
  };
3853
- function resolveSlotName(host, jsx, container) {
3854
- const constProps = jsx.constProps;
3855
- if (constProps && typeof constProps == 'object' && _hasOwnProperty$1.call(constProps, 'name')) {
3856
- const constValue = constProps.name;
3857
- if (host && constValue instanceof WrappedSignalImpl) {
3858
- return trackSignalAndAssignHost(constValue, host, ":" /* EffectProperty.COMPONENT */, container);
3859
- }
3576
+ const serializeBooleanOrNumberAttribute = (value) => {
3577
+ return value != null ? String(value) : null;
3578
+ };
3579
+ function serializeAttribute(key, value, styleScopedId) {
3580
+ if (isClassAttr(key)) {
3581
+ const serializedClass = serializeClass(value);
3582
+ value = styleScopedId
3583
+ ? styleScopedId + (serializedClass.length ? ' ' + serializedClass : serializedClass)
3584
+ : serializedClass;
3860
3585
  }
3861
- return directGetPropsProxyProp(jsx, 'name') || QDefaultSlot;
3586
+ else if (key === 'style') {
3587
+ value = stringifyStyle(value);
3588
+ }
3589
+ else if (isEnumeratedBooleanAttribute(key) || typeof value === 'number') {
3590
+ // aria attrs, tabindex etc.
3591
+ value = serializeBooleanOrNumberAttribute(value);
3592
+ }
3593
+ else if (value === false || value == null) {
3594
+ value = null;
3595
+ }
3596
+ else if (value === true && isPreventDefault(key)) {
3597
+ value = '';
3598
+ }
3599
+ return value;
3600
+ }
3601
+ function isEnumeratedBooleanAttribute(key) {
3602
+ return isAriaAttribute(key) || ['spellcheck', 'draggable', 'contenteditable'].includes(key);
3603
+ }
3604
+ const setValueForStyle = (styleName, value) => {
3605
+ if (typeof value === 'number' && value !== 0 && !isUnitlessNumber(styleName)) {
3606
+ return value + 'px';
3607
+ }
3608
+ return value;
3609
+ };
3610
+ function isAriaAttribute(prop) {
3611
+ return prop.startsWith('aria-');
3862
3612
  }
3613
+ const styleKey = (qStyles, index) => {
3614
+ assertQrl(qStyles);
3615
+ return `${hashCode(qStyles.$hash$)}-${index}`;
3616
+ };
3863
3617
 
3864
3618
  class DeleteOperation {
3865
3619
  target;
@@ -4889,12 +4643,21 @@ function registerEventHandlers(key, value, element, vnode, diffContext) {
4889
4643
  else if (value) {
4890
4644
  (element._qDispatch ||= {})[scopedKebabName] = runEventHandlerQRL.bind(null, value);
4891
4645
  }
4892
- // window and document events need attrs so qwik loader can find them
4646
+ const isQVisible = scopedKebabName === "e:qvisible" /* QwikLoaderScanEvent.qvisible */;
4647
+ // window, document and qvisible events need attrs so qwik loader can find them
4893
4648
  // TODO only do these when not already present
4894
- if (key.charAt(2) !== 'e') {
4649
+ if (key.charAt(2) !== 'e' || isQVisible) {
4895
4650
  vnode_setAttr(diffContext.$journal$, vnode, key, '');
4896
4651
  }
4897
- registerQwikLoaderEvent(diffContext, scopedKebabName);
4652
+ if (isQVisible ||
4653
+ scopedKebabName === "d:qinit" /* QwikLoaderScanEvent.qinit */ ||
4654
+ scopedKebabName === "d:qidle" /* QwikLoaderScanEvent.qidle */) {
4655
+ // the loader scans the DOM for these, so notify it only after the flush
4656
+ queueQwikLoaderEvent(getCursorData(diffContext.$cursor$), scopedKebabName);
4657
+ }
4658
+ else {
4659
+ registerQwikLoaderEvent(diffContext.$container$, scopedKebabName);
4660
+ }
4898
4661
  }
4899
4662
  function createElementWithNamespace(diffContext, elementName) {
4900
4663
  const domParentVNode = vnode_getDomParentVNode(diffContext.$vParent$, true);
@@ -5025,14 +4788,6 @@ const patchProperty = (diffContext, vnode, key, value, currentFile) => {
5025
4788
  }
5026
4789
  setAttribute(diffContext.$journal$, vnode, key, value, diffContext.$scopedStyleIdPrefix$, originalValue);
5027
4790
  };
5028
- function registerQwikLoaderEvent(diffContext, eventName) {
5029
- const qWindow = qTest
5030
- ? diffContext.$container$.document.defaultView
5031
- : window;
5032
- if (qWindow) {
5033
- (qWindow._qwikEv ||= []).push(eventName);
5034
- }
5035
- }
5036
4791
  function retrieveChildWithKey(diffContext, nodeName, key) {
5037
4792
  let vNodeWithKey = null;
5038
4793
  if (diffContext.$vSiblings$ === null) {
@@ -5428,6 +5183,12 @@ function handleChangedProps(src, dst, propsHandler, container, triggerEffects =
5428
5183
  }
5429
5184
  const newValue = src[key];
5430
5185
  const oldValue = dst?.[key];
5186
+ // Every parent render creates an equivalent wrapper, but only the old one has subscribers.
5187
+ // handleProps() swaps the props owner, so keep the subscribed instance or they are orphaned.
5188
+ if (dst && newValue !== oldValue && areDiffValuesEqual(newValue, oldValue)) {
5189
+ src[key] = oldValue;
5190
+ continue;
5191
+ }
5431
5192
  if (!dst ||
5432
5193
  !(areDiffValuesEqual(newValue, oldValue) || areSignalValuesEqual(newValue, oldValue))) {
5433
5194
  if (key === 'class') {
@@ -5534,19 +5295,21 @@ function cleanup(container, journal, vNode, cursorRoot = null) {
5534
5295
  // don't call cleanupDestroyable yet, do it by the scheduler
5535
5296
  continue;
5536
5297
  }
5298
+ cleanupDestroyable(obj);
5537
5299
  }
5538
5300
  // Stores and plain signals are only producers; their subscriptions are removed
5539
5301
  // when cleaning the consumers that read them. They don't own reactive backrefs.
5540
5302
  else if (obj instanceof ComputedSignalImpl || obj instanceof WrappedSignalImpl) {
5541
- if (!(obj.$flags$ & 4 /* ComputedSignalFlags.PRESERVE_ON_SEQ_CLEANUP */)) {
5303
+ if (obj.$flags$ & 4 /* ComputedSignalFlags.PRESERVE_ON_SEQ_CLEANUP */) {
5304
+ continue;
5305
+ }
5306
+ if (obj instanceof ComputedSignalImpl) {
5307
+ obj.$dispose();
5308
+ }
5309
+ else {
5542
5310
  clearAllEffects(container, obj);
5543
5311
  }
5544
5312
  }
5545
- if (objIsTask ||
5546
- (obj instanceof ComputedSignalImpl &&
5547
- (obj.$flags$ & 512 /* AsyncSignalFlags.ASYNC_MODE */ || obj.$current$))) {
5548
- cleanupDestroyable(obj);
5549
- }
5550
5313
  }
5551
5314
  }
5552
5315
  }
@@ -5830,7 +5593,6 @@ const executeComponent = (container, renderHost, subscriptionHost, componentQRL,
5830
5593
  function addUseOnEvents(container, jsx, useOnEvents) {
5831
5594
  const jsxElement = findFirstElementNode(jsx);
5832
5595
  let jsxResult = jsx;
5833
- const qVisibleEvent = 'q-e:qvisible';
5834
5596
  return maybeThen(jsxElement, (jsxElement) => {
5835
5597
  // headless components are components that don't render a real DOM element
5836
5598
  const isHeadless = !jsxElement;
@@ -5842,7 +5604,7 @@ function addUseOnEvents(container, jsx, useOnEvents) {
5842
5604
  let eventKey = key;
5843
5605
  if (isHeadless) {
5844
5606
  // if the component is headless, we need to add the event to the placeholder element
5845
- if (key === qVisibleEvent ||
5607
+ if (key === QVisibleAttr ||
5846
5608
  key.startsWith("q-d:" /* EventNameHtmlScope.document */) ||
5847
5609
  key.startsWith("q-w:" /* EventNameHtmlScope.window */)) {
5848
5610
  if (!placeholderElement) {
@@ -5871,7 +5633,7 @@ function addUseOnEvents(container, jsx, useOnEvents) {
5871
5633
  }
5872
5634
  }
5873
5635
  if (targetElement) {
5874
- if (targetElement.type === 'script' && key === qVisibleEvent) {
5636
+ if (targetElement.type === 'script' && key === QVisibleAttr) {
5875
5637
  eventKey = 'q-d:qinit';
5876
5638
  if (isDev) {
5877
5639
  const sourceLocation = getUseOnSourceLocation(useOnEvents[key].qrls);
@@ -6362,7 +6124,10 @@ function executeComponentChore(vNode, container, journal, cursor) {
6362
6124
  * it. We just return the promise and we'll be called again, possibly with updated props, which
6363
6125
  * is why we don't clear the dirty bit yet.
6364
6126
  */
6365
- return componentQRL.resolve();
6127
+ return componentQRL.resolve().catch((error) => {
6128
+ vNode.dirty &= -5 /* ChoreBits.COMPONENT */;
6129
+ throw error;
6130
+ });
6366
6131
  }
6367
6132
  vNode.dirty &= -5 /* ChoreBits.COMPONENT */;
6368
6133
  if (!componentQRL) {
@@ -6532,6 +6297,9 @@ function executeCompute(vNode, container) {
6532
6297
  */
6533
6298
  function executeReconcile(vNode, container, journal, cursor) {
6534
6299
  vNode.dirty &= -257 /* ChoreBits.RECONCILE */;
6300
+ if (!__EXPERIMENTAL__.each) {
6301
+ return;
6302
+ }
6535
6303
  const host = vNode;
6536
6304
  const props = container.getHostProp(host, ELEMENT_PROPS) || null;
6537
6305
  if (!props) {
@@ -6564,6 +6332,12 @@ function executeFlushPhase(cursor, container) {
6564
6332
  _flushJournal(journal);
6565
6333
  cursorData.journal = null;
6566
6334
  }
6335
+ const loaderEvents = getPendingQwikLoaderEvents(cursorData);
6336
+ if (loaderEvents) {
6337
+ for (let i = 0; i < loaderEvents.length; i++) {
6338
+ registerQwikLoaderEvent(container, loaderEvents[i]);
6339
+ }
6340
+ }
6567
6341
  executeAfterFlush(container, cursorData);
6568
6342
  }
6569
6343
  let _insertBefore = null;
@@ -6745,6 +6519,43 @@ const parseBoolean = (value) => {
6745
6519
  return Boolean(value);
6746
6520
  };
6747
6521
 
6522
+ /**
6523
+ * Creates a function that schedules `fn` to run as a microtask. Microtasks run before browser
6524
+ * paint, preventing flickering.
6525
+ */
6526
+ const createMicroTask = (fn) => {
6527
+ return () => queueMicrotask(fn);
6528
+ };
6529
+ /**
6530
+ * Creates a function that schedules `fn` to run as a macrotask. Macrotasks yield to the browser,
6531
+ * allowing paint and user input. Used for time-slicing to avoid blocking the main thread.
6532
+ */
6533
+ const createMacroTask = (fn) => {
6534
+ let macroTask;
6535
+ if (typeof MessageChannel !== 'undefined') {
6536
+ const channel = new MessageChannel();
6537
+ let active = true;
6538
+ channel.port1.onmessage = () => fn();
6539
+ macroTask = () => {
6540
+ if (active) {
6541
+ channel.port2.postMessage(null);
6542
+ }
6543
+ };
6544
+ macroTask.$destroy$ = () => {
6545
+ if (active) {
6546
+ active = false;
6547
+ channel.port1.onmessage = null;
6548
+ channel.port1.close();
6549
+ channel.port2.close();
6550
+ }
6551
+ };
6552
+ }
6553
+ else {
6554
+ macroTask = () => setTimeout(fn);
6555
+ }
6556
+ return macroTask;
6557
+ };
6558
+
6748
6559
  /**
6749
6560
  * @file Cursor walker implementation for cursor-based scheduling.
6750
6561
  *
@@ -7103,11 +6914,12 @@ function findCursor(vNode) {
7103
6914
  /** @internal */
7104
6915
  function _executeSsrChores(container, ssrNode) {
7105
6916
  if (!(ssrNode.flags & 1 /* SsrNodeFlags.Updatable */)) {
6917
+ let result = undefined;
7106
6918
  if (ssrNode.dirty & 16 /* ChoreBits.NODE_PROPS */) {
7107
6919
  executeNodePropChore(container, ssrNode);
7108
6920
  }
7109
6921
  if (ssrNode.dirty & 32 /* ChoreBits.COMPUTE */) {
7110
- executeCompute(ssrNode, container);
6922
+ result = executeCompute(ssrNode, container);
7111
6923
  }
7112
6924
  if (isDev &&
7113
6925
  ssrNode.dirty & 1023 /* ChoreBits.DIRTY_MASK */ &&
@@ -7129,7 +6941,7 @@ function _executeSsrChores(container, ssrNode) {
7129
6941
  logWarn(warningMessage);
7130
6942
  }
7131
6943
  ssrNode.dirty &= -1024 /* ChoreBits.DIRTY_MASK */;
7132
- return;
6944
+ return result;
7133
6945
  }
7134
6946
  let promise = null;
7135
6947
  if (ssrNode.dirty & 1 /* ChoreBits.TASKS */) {
@@ -7193,6 +7005,9 @@ function executeNodePropChore(container, ssrNode) {
7193
7005
  }
7194
7006
  async function executeReconcileChore(container, ssrNode) {
7195
7007
  ssrNode.dirty &= -257 /* ChoreBits.RECONCILE */;
7008
+ if (!__EXPERIMENTAL__.each) {
7009
+ return;
7010
+ }
7196
7011
  const host = ssrNode;
7197
7012
  const props = container.getHostProp(host, ELEMENT_PROPS) || null;
7198
7013
  if (!props) {
@@ -7681,6 +7496,14 @@ const vnode_setAttr = (journal, vNode, key, value, scopedStyleIdPrefix = null) =
7681
7496
  addVNodeOperation(journal, createSetAttributeOperation(vNode.node, key, value, scopedStyleIdPrefix, (vNode.flags & 512 /* VNodeFlags.NS_svg */) !== 0));
7682
7497
  }
7683
7498
  };
7499
+ const registerQwikLoaderEvent = (container, eventName) => {
7500
+ const win = qTest
7501
+ ? container.document.defaultView
7502
+ : window;
7503
+ if (win) {
7504
+ (win._qwikEv ||= []).push(eventName);
7505
+ }
7506
+ };
7684
7507
  const vnode_ensureElementKeyInflated = (vnode) => {
7685
7508
  if (vnode.key) {
7686
7509
  return;
@@ -9338,7 +9161,7 @@ const runTask = (task, container, host) => {
9338
9161
  if (pendingTask) {
9339
9162
  return pendingTask;
9340
9163
  }
9341
- task.$flags$ &= -5 /* TaskFlags.DIRTY */;
9164
+ task.$flags$ = (task.$flags$ & -5 /* TaskFlags.DIRTY */) | 64 /* TaskFlags.EXECUTED */;
9342
9165
  const handleError = (reason) => {
9343
9166
  tagErrorPhase(reason, "hook" /* ErrorBoundaryPhase.Hook */);
9344
9167
  container.handleError(reason, host, "hook" /* ErrorBoundaryPhase.Hook */);
@@ -9359,7 +9182,7 @@ const runTask = (task, container, host) => {
9359
9182
  task.$taskPromise$ = null;
9360
9183
  }
9361
9184
  return runTask(task, container, host);
9362
- });
9185
+ }, handleError);
9363
9186
  }
9364
9187
  else {
9365
9188
  handleError(err);
@@ -9416,6 +9239,10 @@ function scheduleTask(_event, element) {
9416
9239
  // An ErrorBoundary tore the host down; the task has nothing left to run against.
9417
9240
  return;
9418
9241
  }
9242
+ if (task.$flags$ & (4 /* TaskFlags.DIRTY */ | 64 /* TaskFlags.EXECUTED */)) {
9243
+ // the trigger event only performs the initial run
9244
+ return;
9245
+ }
9419
9246
  task.$flags$ |= 4 /* TaskFlags.DIRTY */;
9420
9247
  markVNodeDirty(container, task.$el$, 1 /* ChoreBits.TASKS */);
9421
9248
  });
@@ -9472,7 +9299,7 @@ const getEffectSerializationContainer = (renderContainer, ownerContainer) => {
9472
9299
  return ownerContainer;
9473
9300
  };
9474
9301
  const scheduleEffects = (container, signal, effects) => {
9475
- const isRunningOnBrowser = qTest ? !isServerPlatform() : isBrowser$1;
9302
+ const isRunningOnBrowser = qTest ? !isServerPlatform() : isBrowser;
9476
9303
  if (effects) {
9477
9304
  const scheduleEffect = (effectSubscription) => {
9478
9305
  const consumer = effectSubscription.consumer;
@@ -9925,6 +9752,42 @@ function getEffects(target, prop, storeEffects) {
9925
9752
  return effectsToTrigger;
9926
9753
  }
9927
9754
 
9755
+ /** @internal */
9756
+ const stringifyRootRefPath = (path) => {
9757
+ let text = String(path[0]);
9758
+ for (let i = 1; i < path.length; i++) {
9759
+ text += ' ' + path[i];
9760
+ }
9761
+ return text;
9762
+ };
9763
+ /** @internal */
9764
+ const writeStringRootRef = (writer, id) => writer.write(String(id));
9765
+ /** @internal */
9766
+ const writeStringRootRefPath = (writer, path) => writer.write(stringifyRootRefPath(path));
9767
+ /** @internal */
9768
+ const writeStringRootRefDelta = (writer, id, base) => writer.write(String(id - base));
9769
+ /** @internal */
9770
+ const createStringStreamWriter = (write) => ({
9771
+ write,
9772
+ writeRootRef(id) {
9773
+ return writeStringRootRef(this, id);
9774
+ },
9775
+ writeRootRefPath(path) {
9776
+ return writeStringRootRefPath(this, path);
9777
+ },
9778
+ writeRootRefDelta(id, base) {
9779
+ return writeStringRootRefDelta(this, id, base);
9780
+ },
9781
+ });
9782
+
9783
+ // Pre-allocated common strings to reduce allocation overhead
9784
+ const CLOSE_TAG = '</';
9785
+ const ESCAPED_CLOSE_TAG = '<\\/';
9786
+ const QUOTE = '"';
9787
+ const BRACKET_OPEN = '[';
9788
+ const BRACKET_CLOSE = ']';
9789
+ const COMMA = ',';
9790
+
9928
9791
  /** Used to represent an undefined value that must be serialized */
9929
9792
  const explicitUndefined = Symbol('undefined');
9930
9793
  const EMPTY_OBJECT_PAYLOAD = 0;
@@ -11993,12 +11856,6 @@ const _regSymbol = (symbol, hash) => {
11993
11856
  return symbol;
11994
11857
  };
11995
11858
 
11996
- /** @internal */
11997
- const getAsyncLocalStorage = () => {
11998
- const process = globalThis.process;
11999
- return process?.getBuiltinModule?.('node:async_hooks')?.AsyncLocalStorage;
12000
- };
12001
-
12002
11859
  /** @file Shared types */
12003
11860
  /** @internal */
12004
11861
  function isStringifiable(value) {
@@ -12043,7 +11900,10 @@ class _SharedContainer {
12043
11900
  return trackSignalAndAssignHost(signal, subscriber, property, this, data);
12044
11901
  }
12045
11902
  serializationCtxFactory(NodeConstructor, DomRefConstructor, symbolToChunkResolver, writer) {
12046
- return createSerializationContext(NodeConstructor, DomRefConstructor, symbolToChunkResolver, this.setHostProp.bind(this), this.$storeProxyMap$, writer);
11903
+ if (isServer) {
11904
+ return createSerializationContext(NodeConstructor, DomRefConstructor, symbolToChunkResolver, this.setHostProp.bind(this), this.$storeProxyMap$, writer);
11905
+ }
11906
+ throw new Error('Serialization context is only available on the server');
12047
11907
  }
12048
11908
  $checkPendingCount$() {
12049
11909
  if (this.$pendingCount$ === 0) {
@@ -12628,21 +12488,13 @@ const useResourceQrl = (qrl, opts) => {
12628
12488
  * return (
12629
12489
  * <div>
12630
12490
  * <input name="city" bind:value={city} />
12631
- * <div>
12632
- * Temperature:{' '}
12633
- * {weather.pending
12634
- * ? 'Loading...'
12635
- * : weather.error
12636
- * ? `Error: ${weather.error.message}`
12637
- * : weather.value.temp}
12638
- * </div>
12491
+ * <div>Temperature: {weather.value.temp}</div>
12639
12492
  * </div>
12640
12493
  * );
12641
12494
  * });
12642
12495
  * ```
12643
12496
  *
12644
- * @deprecated Use `useComputed$` instead. Read the `pending` and `error` properties from the
12645
- * returned signal to determine the status.
12497
+ * @deprecated Use `useComputed$` instead.
12646
12498
  * @public
12647
12499
  */
12648
12500
  const Resource = ({ value, onResolved, onPending, onRejected, }) => {
@@ -12650,7 +12502,7 @@ const Resource = ({ value, onResolved, onPending, onRejected, }) => {
12650
12502
  return value.then(onResolved, onRejected);
12651
12503
  }
12652
12504
  const isRes = isResourceReturn(value);
12653
- const signal = isRes ? value.signal : value;
12505
+ const signal = (isRes ? value.signal : value);
12654
12506
  if (onPending && signal.loading) {
12655
12507
  return onPending();
12656
12508
  }
@@ -15378,6 +15230,9 @@ function getLocale(defaultLocale) {
15378
15230
  /**
15379
15231
  * Override the `getLocale` with `lang` within the `fn` execution.
15380
15232
  *
15233
+ * `fn` may be async. The locale stays set until the returned promise settles, even when
15234
+ * AsyncLocalStorage is not available.
15235
+ *
15381
15236
  * @public
15382
15237
  */
15383
15238
  function withLocale(locale, fn) {
@@ -15385,13 +15240,17 @@ function withLocale(locale, fn) {
15385
15240
  return localAsyncStore.run(locale, fn);
15386
15241
  }
15387
15242
  const previousLang = _locale;
15388
- try {
15389
- _locale = locale;
15390
- return fn();
15391
- }
15392
- finally {
15243
+ const restore = () => {
15393
15244
  _locale = previousLang;
15394
- }
15245
+ };
15246
+ _locale = locale;
15247
+ return safeCall(fn, (value) => {
15248
+ restore();
15249
+ return value;
15250
+ }, (error) => {
15251
+ restore();
15252
+ throw error;
15253
+ });
15395
15254
  }
15396
15255
  /**
15397
15256
  * Globally set a lang.
@@ -15470,15 +15329,12 @@ function newRenderInvokeContext(locale, hostElement, container) {
15470
15329
  return ctx;
15471
15330
  }
15472
15331
  /** @internal */
15473
- // TODO how about putting url and locale (and event/custom?) in to a "static" object
15474
15332
  function newInvokeContext(locale, hostElement, event) {
15475
- // ServerRequestEvent has .locale, but it's not always defined.
15476
- const $locale$ = locale || (event && isObject(event) && 'locale' in event ? event.locale : undefined);
15477
15333
  const ctx = {
15478
15334
  $hostElement$: hostElement,
15479
15335
  $event$: event,
15480
15336
  $effectSubscriber$: undefined,
15481
- $locale$,
15337
+ $locale$: locale,
15482
15338
  $container$: undefined,
15483
15339
  };
15484
15340
  seal(ctx);
@@ -15603,7 +15459,7 @@ const initQrlClassDev = (lazy, captures, qrl) => {
15603
15459
  };
15604
15460
  /** Set up HMR support: cache LazyRefs and invalidate on file changes. */
15605
15461
  const setupHmr = (LazyRefClass, setGetLazyRef) => {
15606
- if (!(isBrowser$1 && import.meta.hot)) {
15462
+ if (!(isBrowser && import.meta.hot)) {
15607
15463
  return;
15608
15464
  }
15609
15465
  const allLazyRefs = new Map();
@@ -15713,7 +15569,7 @@ class LazyRef {
15713
15569
  }
15714
15570
  qDev && initLazyRefDev(this);
15715
15571
  /** Preload the chunk with somewhat lower probability when we create the QRL. */
15716
- if (isBrowser$1 && $chunk$) {
15572
+ if (isBrowser && $chunk$) {
15717
15573
  p($chunk$, 0.8);
15718
15574
  }
15719
15575
  }
@@ -15729,7 +15585,7 @@ class LazyRef {
15729
15585
  if (qTest ? isServerPlatform() : isServer) {
15730
15586
  console.error(errorMessage, err);
15731
15587
  }
15732
- else if (qTest ? !isServerPlatform() : isBrowser$1) {
15588
+ else if (qTest ? !isServerPlatform() : isBrowser) {
15733
15589
  const failureKey = this.$chunk$ === null ? `symbol:${this.$symbol$}` : `chunk:${this.$chunk$}`;
15734
15590
  const container = this.$container$;
15735
15591
  let containerFailures = container && reportedChunkFailures?.get(container);
@@ -15762,7 +15618,7 @@ class LazyRef {
15762
15618
  const qFuncs = getQFuncs(doc, hash);
15763
15619
  return (this.$ref$ = qFuncs[Number(this.$symbol$)]);
15764
15620
  }
15765
- if (isBrowser$1 && this.$chunk$) {
15621
+ if (isBrowser && this.$chunk$) {
15766
15622
  /** We will run the QRL, so now the probability of the chunk is 100% */
15767
15623
  p(this.$chunk$, 1);
15768
15624
  }
@@ -15774,7 +15630,8 @@ class LazyRef {
15774
15630
  return this.$ref$;
15775
15631
  }
15776
15632
  }
15777
- isBrowser$1 &&
15633
+ qDev &&
15634
+ isBrowser &&
15778
15635
  import.meta.hot &&
15779
15636
  setupHmr(LazyRef, (fn) => {
15780
15637
  getLazyRef = fn;
@@ -16993,9 +16850,8 @@ const useComputedQrl = (qrl, options) => {
16993
16850
  *
16994
16851
  * Every synchronous signal or store read is tracked automatically. Reads after an `await` are not:
16995
16852
  * the tracking context is lost, so track them explicitly with the `track()` provided on the context
16996
- * argument. When the function is async, the returned signal exposes the async API: reading an
16997
- * unresolved `.value` throws the computation promise, and `.pending` and `.error` expose the
16998
- * computation state.
16853
+ * argument. When the function is async, reading an unresolved `.value` throws the computation
16854
+ * promise, and reading a failed `.value` throws the error.
16999
16855
  *
17000
16856
  * The function must not have any side effects.
17001
16857
  *
@@ -17085,15 +16941,18 @@ const useVisibleTaskQrl = (qrl, opts) => {
17085
16941
  }
17086
16942
  assertQrl(qrl);
17087
16943
  let flags;
17088
- if (!isServerPlatform()) {
17089
- // In DOM we immediately execute
16944
+ if (!isServerPlatform() && eagerness !== 'intersection-observer') {
16945
+ // The document is already ready/idle in DOM, so execute immediately
17090
16946
  flags = 1 /* TaskFlags.VISIBLE_TASK */ | 4 /* TaskFlags.DIRTY */;
17091
16947
  qrl.resolve();
17092
16948
  markVNodeDirty(iCtx.$container$, iCtx.$hostElement$, 1 /* ChoreBits.TASKS */);
17093
16949
  }
17094
16950
  else {
17095
- // In SSR we defer execution until triggered in DOM
16951
+ // Defer execution until the trigger event fires
17096
16952
  flags = 1 /* TaskFlags.VISIBLE_TASK */;
16953
+ if (!isServerPlatform()) {
16954
+ qrl.resolve();
16955
+ }
17097
16956
  }
17098
16957
  const task = new Task(flags, i, iCtx.$hostElement$, qrl, null);
17099
16958
  set(task);
@@ -17272,7 +17131,7 @@ const errorBoundaryReset = () => {
17272
17131
  const [host] = _captures;
17273
17132
  // this is executed only on client
17274
17133
  const container = tryGetInvokeContext()?.$container$;
17275
- const isBrowserEnv = qTest ? !isServerPlatform() : isBrowser$1;
17134
+ const isBrowserEnv = qTest ? !isServerPlatform() : isBrowser;
17276
17135
  if (isBrowserEnv && host && container) {
17277
17136
  resetErrorBoundary(container, host);
17278
17137
  }
@@ -17365,7 +17224,7 @@ const errorBoundaryCmp = (props) => {
17365
17224
  if (container && (getStoreTarget(store) ?? store).boundaryId === undefined) {
17366
17225
  store.boundaryId = getNextUniqueIndex(container);
17367
17226
  }
17368
- const isServerEnv = qTest ? isServerPlatform() : !isBrowser$1;
17227
+ const isServerEnv = qTest ? isServerPlatform() : !isBrowser;
17369
17228
  if (!isServerEnv && store.error === undefined) {
17370
17229
  return /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 0, null);
17371
17230
  }
@@ -17530,7 +17389,7 @@ const revealCanReveal = () => {
17530
17389
  if (registration !== null && registration.reveal.version.value < 0) {
17531
17390
  return false;
17532
17391
  }
17533
- if (qTest ? isServerPlatform() : !isBrowser$1) {
17392
+ if (qTest ? isServerPlatform() : !isBrowser) {
17534
17393
  const ooos = registration?.reveal.ooos;
17535
17394
  if (ooos) {
17536
17395
  return ooos.canReveal(registration);
@@ -17543,7 +17402,7 @@ const revealCleanupTask = ({ cleanup }) => {
17543
17402
  const registration = _captures[0];
17544
17403
  cleanup(() => {
17545
17404
  // Keep the SSR registry intact so `reveal.items` serializes for resume.
17546
- if (qTest ? isServerPlatform() : !isBrowser$1) {
17405
+ if (qTest ? isServerPlatform() : !isBrowser) {
17547
17406
  return;
17548
17407
  }
17549
17408
  const items = registration.reveal.items;
@@ -17587,7 +17446,7 @@ const revealCmp = (props) => {
17587
17446
  }
17588
17447
  const reveal = useConstant(createRevealContext, props);
17589
17448
  useContextProvider(RevealContext, reveal);
17590
- const isServerEnv = qTest ? isServerPlatform() : !isBrowser$1;
17449
+ const isServerEnv = qTest ? isServerPlatform() : !isBrowser;
17591
17450
  if (__EXPERIMENTAL__.suspense && isServerEnv && isOutOfOrderStreaming()) {
17592
17451
  const coordinator = getOutOfOrderCoordinator(reveal);
17593
17452
  return /*#__PURE__*/ _jsxSorted(SSRRevealSlot, {
@@ -17631,7 +17490,7 @@ const _hf1_str = '{display:p0.value==="content"&&p1.value?"contents":"none"}';
17631
17490
  const suspenseTask = ({ track, cleanup }) => {
17632
17491
  const cursorBoundary = _captures[0], props = _captures[1], state = _captures[2], revealRegistration = _captures[3];
17633
17492
  const pendingCount = track(cursorBoundary);
17634
- const isBrowserEnv = qTest ? !isServerPlatform() : isBrowser$1;
17493
+ const isBrowserEnv = qTest ? !isServerPlatform() : isBrowser;
17635
17494
  if (revealRegistration !== null && isBrowserEnv) {
17636
17495
  revealRegistration.reveal.version.value++;
17637
17496
  }
@@ -17663,7 +17522,7 @@ const suspenseCmp = (props) => {
17663
17522
  state,
17664
17523
  revealRegistration,
17665
17524
  ]));
17666
- const isServerEnv = qTest ? isServerPlatform() : !isBrowser$1;
17525
+ const isServerEnv = qTest ? isServerPlatform() : !isBrowser;
17667
17526
  const isServerOutOfOrder = isServerEnv && isOutOfOrderStreaming();
17668
17527
  const outOfOrderBoundaryId = isServerOutOfOrder ? nextOutOfOrderSuspenseId() : 0;
17669
17528
  const outOfOrderRevealBoundary = isServerOutOfOrder
@@ -17891,11 +17750,11 @@ if (globalThis.__qwik) {
17891
17750
  qError(30 /* QError.duplicateQwik */, [globalThis.__qwik, version]);
17892
17751
  }
17893
17752
  globalThis.__qwik = version;
17894
- if (import.meta.hot) {
17753
+ if (isDev && import.meta.hot) {
17895
17754
  import.meta.hot.dispose(() => {
17896
17755
  globalThis.__qwik = undefined;
17897
17756
  });
17898
17757
  }
17899
17758
 
17900
- export { $, Each, ErrorBoundary, Fragment, NoSerializeSymbol, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, Reveal, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SerializerSymbol, Show, SkipRender, Slot, Suspense, _CONST_PROPS, DomContainer as _DomContainer, _EFFECT_BACK_REF, ELEMENT_SEQ as _ELEMENT_SEQ, EMPTY_ARRAY as _EMPTY_ARRAY, EMPTY_OBJ as _EMPTY_OBJ, _IMMUTABLE, _SharedContainer, SubscriptionData as _SubscriptionData, SubscriptionPatch as _SubscriptionPatch, Task as _Task, _UNINITIALIZED, _VAR_PROPS, _addProjection, _captures, _chk, _createDeserializeContainer, createQRL as _createQRL, createStore as _createStore, delay as _delay, _deserialize, _dumpState, eachCmp as _eaC, eachCmpTask as _eaT, errorBoundaryCmp as _ebC, errorBoundaryReset as _ebR, _executeSsrChores, _fnSignal, getAsyncLocalStorage as _getAsyncLocalStorage, _getConstProps, _getContextContainer, _getContextEvent, _getContextHostElement, getDomContainer as _getDomContainer, _getQContainerElement, getSubscriber as _getSubscriber, _getVarProps, handleSSRError as _handleSSRError, _hasStoreEffects, _hmr, _injectAsyncSignalValue, invoke as _invoke, isJSXNode as _isJSXNode, isStore as _isStore, isStringifiable as _isStringifiable, isTask as _isTask, _jsxBranch, _jsxC, _jsxQ, _jsxS, _jsxSorted, _jsxSplit, mapApp_findIndx as _mapApp_findIndx, mapArray_get as _mapArray_get, mapArray_set as _mapArray_set, _markSignalAsExternallyOwned, newInvokeContext as _newInvokeContext, _noopQrl, _noopQrlDEV, preprocessState as _preprocessState, _qrlSync, qrlToString as _qrlToString, _qrlWithChunk, _qrlWithChunkDEV, revealCmp as _reC, revealCanReveal as _reR, revealCleanupTask as _reT, _regSymbol, _removeProjection, _res, _resolveContextWithoutSequentialScope, _restProps, retryOnPromise as _retryOnPromise, _rsc, _run, _serialize, setEvent as _setEvent, _setProjectionTarget, showCmp as _shC, showCmpTask as _shT, suspenseCmp as _suC, suspenseTask as _suT, scheduleTask as _task, _updateProjectionProps, _useHmr, _val, verifySerializable as _verifySerializable, vnode_ensureElementInflated as _vnode_ensureElementInflated, vnode_getAttrKeys as _vnode_getAttrKeys, vnode_getElementName as _vnode_getElementName, vnode_getFirstChild as _vnode_getFirstChild, vnode_getProp as _vnode_getProp, vnode_getVNodeForChildNode as _vnode_getVNodeForChildNode, vnode_insertBefore as _vnode_insertBefore, vnode_isElementVNode as _vnode_isElementVNode, vnode_isMaterialized as _vnode_isMaterialized, vnode_isTextVNode as _vnode_isTextVNode, vnode_isVirtualVNode as _vnode_isVirtualVNode, vnode_newVirtual as _vnode_newVirtual, vnode_remove as _vnode_remove, vnode_setProp as _vnode_setProp, vnode_toString as _vnode_toString, _waitUntilRendered, _walkJSX, _wrapProp, _wrapSignal, component$, componentQrl, createAsyncSignal as createAsyncQrl, createComputed$, createComputedSignal as createComputedQrl, createContextId, h as createElement, createSerializer$, createSerializerSignal as createSerializerQrl, createSignal, event$, eventQrl, forceStoreEffects, getClientManifest, getDomContainer, getLocale, getPlatform, h, implicit$FirstArg, inlinedQrl, inlinedQrlDEV, isSignal, jsx, jsxDEV, jsxs, noSerialize, qrl, qrlDEV, render, setPlatform, sync$, untrack, unwrapStore, useComputed$, useComputedQrl, useConstant, useContext, useContextProvider, useId, useLexicalScope, useOn, useOnDocument, useOnWindow, useResource$, useResourceQrl, useSerializer$, useSerializerQrl, useServerData, useSignal, useStore, useStyles$, useStylesQrl, useStylesScoped$, useStylesScopedQrl, useTask$, useTaskQrl, useVisibleTask$, useVisibleTaskQrl, version, withLocale };
17759
+ export { $, Each, ErrorBoundary, Fragment, NoSerializeSymbol, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, Reveal, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SerializerSymbol, Show, SkipRender, Slot, Suspense, _CONST_PROPS, DomContainer as _DomContainer, _EFFECT_BACK_REF, ELEMENT_SEQ as _ELEMENT_SEQ, EMPTY_ARRAY as _EMPTY_ARRAY, EMPTY_OBJ as _EMPTY_OBJ, _IMMUTABLE, _SharedContainer, SubscriptionData as _SubscriptionData, SubscriptionPatch as _SubscriptionPatch, Task as _Task, _UNINITIALIZED, _VAR_PROPS, _addProjection, _captures, _chk, _createDeserializeContainer, createQRL as _createQRL, createStore as _createStore, delay as _delay, _deserialize, _dumpState, eachCmp as _eaC, eachCmpTask as _eaT, errorBoundaryCmp as _ebC, errorBoundaryReset as _ebR, _executeSsrChores, _fnSignal, _getConstProps, _getContextContainer, _getContextEvent, _getContextHostElement, getDomContainer as _getDomContainer, _getQContainerElement, getSubscriber as _getSubscriber, _getVarProps, handleSSRError as _handleSSRError, _hasStoreEffects, _hmr, _injectAsyncSignalValue, invoke as _invoke, isJSXNode as _isJSXNode, isStore as _isStore, isStringifiable as _isStringifiable, isTask as _isTask, _jsxBranch, _jsxC, _jsxQ, _jsxS, _jsxSorted, _jsxSplit, mapApp_findIndx as _mapApp_findIndx, mapArray_get as _mapArray_get, mapArray_set as _mapArray_set, _markSignalAsExternallyOwned, newInvokeContext as _newInvokeContext, _noopQrl, _noopQrlDEV, preprocessState as _preprocessState, _qrlSync, qrlToString as _qrlToString, _qrlWithChunk, _qrlWithChunkDEV, revealCmp as _reC, revealCanReveal as _reR, revealCleanupTask as _reT, _regSymbol, _removeProjection, _res, _resolveContextWithoutSequentialScope, _restProps, retryOnPromise as _retryOnPromise, _rsc, _run, _serialize, setEvent as _setEvent, _setProjectionTarget, showCmp as _shC, showCmpTask as _shT, suspenseCmp as _suC, suspenseTask as _suT, scheduleTask as _task, _updateProjectionProps, _useHmr, _val, verifySerializable as _verifySerializable, vnode_ensureElementInflated as _vnode_ensureElementInflated, vnode_getAttrKeys as _vnode_getAttrKeys, vnode_getElementName as _vnode_getElementName, vnode_getFirstChild as _vnode_getFirstChild, vnode_getProp as _vnode_getProp, vnode_getVNodeForChildNode as _vnode_getVNodeForChildNode, vnode_insertBefore as _vnode_insertBefore, vnode_isElementVNode as _vnode_isElementVNode, vnode_isMaterialized as _vnode_isMaterialized, vnode_isTextVNode as _vnode_isTextVNode, vnode_isVirtualVNode as _vnode_isVirtualVNode, vnode_newVirtual as _vnode_newVirtual, vnode_remove as _vnode_remove, vnode_setProp as _vnode_setProp, vnode_toString as _vnode_toString, _waitUntilRendered, _walkJSX, _wrapProp, _wrapSignal, component$, componentQrl, createAsyncSignal as createAsyncQrl, createComputed$, createComputedSignal as createComputedQrl, createContextId, h as createElement, createSerializer$, createSerializerSignal as createSerializerQrl, createSignal, event$, eventQrl, forceStoreEffects, getClientManifest, getDomContainer, getLocale, getPlatform, h, implicit$FirstArg, inlinedQrl, inlinedQrlDEV, isSignal, jsx, jsxDEV, jsxs, noSerialize, qrl, qrlDEV, render, setPlatform, sync$, untrack, unwrapStore, useComputed$, useComputedQrl, useConstant, useContext, useContextProvider, useId, useLexicalScope, useOn, useOnDocument, useOnWindow, useResource$, useResourceQrl, useSerializer$, useSerializerQrl, useServerData, useSignal, useStore, useStyles$, useStylesQrl, useStylesScoped$, useStylesScopedQrl, useTask$, useTaskQrl, useVisibleTask$, useVisibleTaskQrl, version, withLocale };
17901
17760
  //# sourceMappingURL=core.mjs.map