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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * @qwik.dev/core 2.0.0-beta.19-dev+0d046fb
3
+ * @qwik.dev/core 2.0.0-beta.21-dev+c008e88
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
@@ -14,7 +14,7 @@ import { p } from '@qwik.dev/core/preloader';
14
14
  *
15
15
  * @public
16
16
  */
17
- const version = "2.0.0-beta.19-dev+0d046fb";
17
+ const version = "2.0.0-beta.21-dev+c008e88";
18
18
 
19
19
  // same as isDev but separate so we can test
20
20
  const qDev = globalThis.qDev !== false;
@@ -401,29 +401,64 @@ const delay = (timeout) => {
401
401
  setTimeout(resolve, timeout);
402
402
  });
403
403
  };
404
- /** Retries a function that throws a promise. */
405
- function retryOnPromise(fn, retryCount = 0) {
406
- const retryOrThrow = (e) => {
407
- if (isPromise(e) && retryCount < MAX_RETRY_ON_PROMISE_COUNT) {
408
- return e.then(retryOnPromise.bind(null, fn, retryCount++));
409
- }
410
- throw e;
411
- };
404
+ const checkError = (e) => {
405
+ if (isServer && e instanceof ReferenceError && e.message.includes('window')) {
406
+ e.message = 'It seems like you forgot to add "if (isBrowser) {...}" here:' + e.message;
407
+ }
408
+ };
409
+ const justThrow = (e) => {
410
+ throw e;
411
+ };
412
+ /**
413
+ * Retries a function that throws a promise. If you pass `onError`, you're responsible for handling
414
+ * errors.
415
+ */
416
+ function retryOnPromise(fn, onError = justThrow) {
417
+ let ok = false;
418
+ let result;
412
419
  try {
413
- const result = fn();
414
- if (isPromise(result)) {
415
- // not awaited promise is not caught by try/catch block
416
- return result.catch((e) => retryOrThrow(e));
417
- }
418
- return result;
420
+ result = fn();
421
+ ok = true;
419
422
  }
420
423
  catch (e) {
421
- if (isDev && isServer && e instanceof ReferenceError && e.message.includes('window')) {
422
- e.message = 'It seems like you forgot to add "if (isBrowser) {...}" here:' + e.message;
423
- throw e;
424
+ result = e;
425
+ }
426
+ if (!isPromise(result)) {
427
+ // Synchronous function or error, no need to retry
428
+ if (ok) {
429
+ return result;
424
430
  }
425
- return retryOrThrow(e);
431
+ isDev && checkError(result);
432
+ return onError(result);
426
433
  }
434
+ let retryCount = MAX_RETRY_ON_PROMISE_COUNT;
435
+ const retry = async (p) => {
436
+ while (isPromise(p)) {
437
+ try {
438
+ await p;
439
+ // We waited for the thrown promise, now try again
440
+ return await fn();
441
+ }
442
+ catch (err) {
443
+ if (isPromise(err)) {
444
+ if (!--retryCount) {
445
+ p = new Error('Exceeded max retry count in retryOnPromise');
446
+ break;
447
+ }
448
+ else {
449
+ p = err;
450
+ }
451
+ }
452
+ else {
453
+ p = err;
454
+ break;
455
+ }
456
+ }
457
+ }
458
+ isDev && checkError(p);
459
+ return onError(p);
460
+ };
461
+ return ok ? result.catch(retry) : retry(result);
427
462
  }
428
463
 
429
464
  const ASSERT_DISCLAIMER = 'Internal assert, this is likely caused by a bug in Qwik: ';
@@ -529,15 +564,15 @@ const isSvgElement = (elementName) => elementName === 'svg' || isForeignObjectEl
529
564
  const isMathElement = (elementName) => elementName === 'math';
530
565
  const vnode_isDefaultNamespace = (vnode) => {
531
566
  const flags = vnode.flags;
532
- return (flags & 384 /* VNodeFlags.NAMESPACE_MASK */) === 0;
567
+ return (flags & 1536 /* VNodeFlags.NAMESPACE_MASK */) === 0;
533
568
  };
534
569
  const vnode_getElementNamespaceFlags = (element) => {
535
570
  const namespace = fastNamespaceURI(element);
536
571
  switch (namespace) {
537
572
  case SVG_NS:
538
- return 128 /* VNodeFlags.NS_svg */;
573
+ return 512 /* VNodeFlags.NS_svg */;
539
574
  case MATH_NS:
540
- return 256 /* VNodeFlags.NS_math */;
575
+ return 1024 /* VNodeFlags.NS_math */;
541
576
  default:
542
577
  return 0 /* VNodeFlags.NS_html */;
543
578
  }
@@ -560,8 +595,8 @@ function vnode_getDomChildrenWithCorrectNamespacesToInsert(journal, domParentVNo
560
595
  domChildren.push(childVNode);
561
596
  continue;
562
597
  }
563
- if ((childVNode.flags & 384 /* VNodeFlags.NAMESPACE_MASK */) ===
564
- (domParentVNode.flags & 384 /* VNodeFlags.NAMESPACE_MASK */)) {
598
+ if ((childVNode.flags & 1536 /* VNodeFlags.NAMESPACE_MASK */) ===
599
+ (domParentVNode.flags & 1536 /* VNodeFlags.NAMESPACE_MASK */)) {
565
600
  // if the child and parent have the same namespace, we don't need to clone the element
566
601
  domChildren.push(childVNode);
567
602
  continue;
@@ -648,7 +683,7 @@ function vnode_cloneElementWithNamespace(elementVNode, parentVNode, namespace, n
648
683
  // This is because we need to materialize the children before we assign new element
649
684
  vCursor.node = newChildElement;
650
685
  // Set correct namespace flag
651
- vCursor.flags &= -385 /* VNodeFlags.NEGATED_NAMESPACE_MASK */;
686
+ vCursor.flags &= -1537 /* VNodeFlags.NEGATED_NAMESPACE_MASK */;
652
687
  vCursor.flags |= namespaceFlag;
653
688
  if (vFirstChild) {
654
689
  vCursor = vFirstChild;
@@ -717,17 +752,17 @@ function getNewElementNamespaceData(domParentVNode, tagOrVNode) {
717
752
  const isElementVNodeOrString = typeof tagOrVNode === 'string' || vnode_isElementVNode(tagOrVNode);
718
753
  if (isElementVNodeOrString && isSvg(tagOrVNode)) {
719
754
  elementNamespace = SVG_NS;
720
- elementNamespaceFlag = 128 /* VNodeFlags.NS_svg */;
755
+ elementNamespaceFlag = 512 /* VNodeFlags.NS_svg */;
721
756
  }
722
757
  else if (isElementVNodeOrString && isMath(tagOrVNode)) {
723
758
  elementNamespace = MATH_NS;
724
- elementNamespaceFlag = 256 /* VNodeFlags.NS_math */;
759
+ elementNamespaceFlag = 1024 /* VNodeFlags.NS_math */;
725
760
  }
726
761
  else if (domParentVNode && !parentIsForeignObject && !parentIsDefaultNamespace) {
727
- const isParentSvg = (domParentVNode.flags & 128 /* VNodeFlags.NS_svg */) !== 0;
728
- const isParentMath = (domParentVNode.flags & 256 /* VNodeFlags.NS_math */) !== 0;
762
+ const isParentSvg = (domParentVNode.flags & 512 /* VNodeFlags.NS_svg */) !== 0;
763
+ const isParentMath = (domParentVNode.flags & 1024 /* VNodeFlags.NS_math */) !== 0;
729
764
  elementNamespace = isParentSvg ? SVG_NS : isParentMath ? MATH_NS : HTML_NS;
730
- elementNamespaceFlag = domParentVNode.flags & 384 /* VNodeFlags.NAMESPACE_MASK */;
765
+ elementNamespaceFlag = domParentVNode.flags & 1536 /* VNodeFlags.NAMESPACE_MASK */;
731
766
  }
732
767
  NEW_NAMESPACE_DATA.elementNamespace = elementNamespace;
733
768
  NEW_NAMESPACE_DATA.elementNamespaceFlag = elementNamespaceFlag;
@@ -738,7 +773,7 @@ function isSvg(tagOrVNode) {
738
773
  return isSvgElement(tagOrVNode);
739
774
  }
740
775
  if (vnode_isElementVNode(tagOrVNode)) {
741
- return (isSvgElement(vnode_getElementName(tagOrVNode)) || (tagOrVNode.flags & 128 /* VNodeFlags.NS_svg */) !== 0);
776
+ return (isSvgElement(vnode_getElementName(tagOrVNode)) || (tagOrVNode.flags & 512 /* VNodeFlags.NS_svg */) !== 0);
742
777
  }
743
778
  return false;
744
779
  }
@@ -748,7 +783,7 @@ function isMath(tagOrVNode) {
748
783
  }
749
784
  if (vnode_isElementVNode(tagOrVNode)) {
750
785
  return (isMathElement(vnode_getElementName(tagOrVNode)) ||
751
- (tagOrVNode.flags & 256 /* VNodeFlags.NS_math */) !== 0);
786
+ (tagOrVNode.flags & 1024 /* VNodeFlags.NS_math */) !== 0);
752
787
  }
753
788
  return false;
754
789
  }
@@ -778,6 +813,75 @@ const mergeMaps = (map1, map2) => {
778
813
  return map1;
779
814
  };
780
815
 
816
+ /**
817
+ * Think of `-` as an escape character which makes the next character uppercase. `--` is just `-`.
818
+ *
819
+ * Rules for JSX property event names starting with `on`:
820
+ *
821
+ * - Are case insensitive: `onClick$` is same `onclick$`
822
+ * - A `--` is `-`: `dbl--click` => `dbl-click`
823
+ * - Become case sensitive if prefixed by `-`: `-Click` is `Click`
824
+ * - A `-` (not at the beginning) makes next character uppercase: `dbl-click` => `dblClick`
825
+ */
826
+ const EVENT_SUFFIX = '$';
827
+ const isHtmlAttributeAnEventName = (name) => {
828
+ return (name.charCodeAt(0) === 113 /* q */ &&
829
+ name.charCodeAt(1) === 45 /* - */ &&
830
+ name.charCodeAt(3) === 58 /* : */);
831
+ };
832
+ function jsxEventToHtmlAttribute(jsxEvent) {
833
+ if (jsxEvent.endsWith(EVENT_SUFFIX)) {
834
+ const [prefix, idx] = getEventScopeDataFromJsxEvent(jsxEvent);
835
+ if (idx !== -1) {
836
+ const name = jsxEvent.slice(idx, -1);
837
+ return name === 'DOMContentLoaded'
838
+ ? // The only DOM event that is not all lowercase
839
+ prefix + '-d-o-m-content-loaded'
840
+ : createEventName(name.charAt(0) === '-'
841
+ ? // marker for case sensitive event name
842
+ name.slice(1)
843
+ : name.toLowerCase(), prefix);
844
+ }
845
+ }
846
+ return null; // Return null if not matching expected format
847
+ }
848
+ function createEventName(event, prefix) {
849
+ const eventName = fromCamelToKebabCase(event);
850
+ return prefix + eventName;
851
+ }
852
+ function getEventScopeDataFromJsxEvent(eventName) {
853
+ let prefix;
854
+ let idx = -1;
855
+ // set prefix and idx based on the scope
856
+ if (eventName.startsWith("on" /* EventNameJSXScope.on */)) {
857
+ prefix = "q-e:" /* EventNameHtmlScope.on */;
858
+ idx = 2;
859
+ }
860
+ else if (eventName.startsWith("window:on" /* EventNameJSXScope.window */)) {
861
+ prefix = "q-w:" /* EventNameHtmlScope.window */;
862
+ idx = 9;
863
+ }
864
+ else if (eventName.startsWith("document:on" /* EventNameJSXScope.document */)) {
865
+ prefix = "q-d:" /* EventNameHtmlScope.document */;
866
+ idx = 11;
867
+ }
868
+ return [prefix, idx];
869
+ }
870
+ function isPreventDefault(key) {
871
+ return key.startsWith('preventdefault:');
872
+ }
873
+ /** Converts a camelCase string to kebab-case. This is used for event names. */
874
+ const fromCamelToKebabCase = (text) => {
875
+ return text.replace(/([A-Z-])/g, (a) => '-' + a.toLowerCase());
876
+ };
877
+ /** E.g. `"q-e:click"` => `['e', 'click']` */
878
+ const getEventDataFromHtmlAttribute = (htmlKey) => [
879
+ htmlKey.charAt(2),
880
+ htmlKey.substring(4),
881
+ ];
882
+ /** E.g. `"e:click"`, `"w:load"` */
883
+ const getScopedEventName = (scope, eventName) => scope + ':' + eventName;
884
+
781
885
  /** @internal */
782
886
  const _EFFECT_BACK_REF = Symbol('backRef');
783
887
  /** Class for back reference to the EffectSubscription */
@@ -924,7 +1028,7 @@ function resumeCursor(cursor, container) {
924
1028
  */
925
1029
  function removeCursorFromQueue(cursor, container, keepCursorFlag) {
926
1030
  if (!keepCursorFlag) {
927
- cursor.flags &= -65 /* VNodeFlags.Cursor */;
1031
+ cursor.flags &= -257 /* VNodeFlags.Cursor */;
928
1032
  }
929
1033
  const index = globalCursorQueue.indexOf(cursor);
930
1034
  if (index !== -1) {
@@ -1144,88 +1248,6 @@ const _IMMUTABLE = Symbol('IMMUTABLE');
1144
1248
  /** @internal */
1145
1249
  const _UNINITIALIZED = Symbol('UNINITIALIZED');
1146
1250
 
1147
- /**
1148
- * Think of `-` as an escape character which makes the next character uppercase. `--` is just `-`.
1149
- *
1150
- * Rules for JSX property event names starting with `on`:
1151
- *
1152
- * - Are case insensitive: `onClick$` is same `onclick$`
1153
- * - A `--` is `-`: `dbl--click` => `dbl-click`
1154
- * - Become case sensitive if prefixed by `-`: `-Click` is `Click`
1155
- * - A `-` (not at the beginning) makes next character uppercase: `dbl-click` => `dblClick`
1156
- */
1157
- const EVENT_SUFFIX = '$';
1158
- const isHtmlAttributeAnEventName = (name) => {
1159
- if (name.charCodeAt(0) !== 111 /* o */ || name.charCodeAt(1) !== 110 /* n */) {
1160
- return false;
1161
- }
1162
- if (name.charCodeAt(2) === 58 /* : */) {
1163
- return true; // on:
1164
- }
1165
- return name.startsWith("on-window:" /* EventNameHtmlScope.window */) || name.startsWith("on-document:" /* EventNameHtmlScope.document */);
1166
- };
1167
- function jsxEventToHtmlAttribute(jsxEvent) {
1168
- if (jsxEvent.endsWith(EVENT_SUFFIX)) {
1169
- const [prefix, idx] = getEventScopeDataFromJsxEvent(jsxEvent);
1170
- if (idx !== -1) {
1171
- const name = jsxEvent.slice(idx, -1);
1172
- return name === 'DOMContentLoaded'
1173
- ? // The only DOM event that is not all lowercase
1174
- prefix + '-d-o-m-content-loaded'
1175
- : createEventName(name.charAt(0) === '-'
1176
- ? // marker for case sensitive event name
1177
- name.slice(1)
1178
- : name.toLowerCase(), prefix);
1179
- }
1180
- }
1181
- return null; // Return null if not matching expected format
1182
- }
1183
- function createEventName(event, prefix) {
1184
- const eventName = fromCamelToKebabCase(event);
1185
- return prefix + eventName;
1186
- }
1187
- function getEventScopeDataFromJsxEvent(eventName) {
1188
- let prefix = "on:" /* EventNameHtmlScope.on */;
1189
- let idx = -1;
1190
- // set prefix and idx based on the scope
1191
- if (eventName.startsWith("on" /* EventNameJSXScope.on */)) {
1192
- prefix = "on:" /* EventNameHtmlScope.on */;
1193
- idx = 2;
1194
- }
1195
- else if (eventName.startsWith("window:on" /* EventNameJSXScope.window */)) {
1196
- prefix = "on-window:" /* EventNameHtmlScope.window */;
1197
- idx = 9;
1198
- }
1199
- else if (eventName.startsWith("document:on" /* EventNameJSXScope.document */)) {
1200
- prefix = "on-document:" /* EventNameHtmlScope.document */;
1201
- idx = 11;
1202
- }
1203
- return [prefix, idx];
1204
- }
1205
- function isPreventDefault(key) {
1206
- return key.startsWith('preventdefault:');
1207
- }
1208
- /** Converts a camelCase string to kebab-case. This is used for event names. */
1209
- const fromCamelToKebabCase = (text) => {
1210
- return text.replace(/([A-Z-])/g, (a) => '-' + a.toLowerCase());
1211
- };
1212
- const getEventDataFromHtmlAttribute = (htmlKey) => {
1213
- if (htmlKey.startsWith("on:" /* EventNameHtmlScope.on */)) {
1214
- return ['', htmlKey.substring(3)];
1215
- }
1216
- if (htmlKey.startsWith("on-window:" /* EventNameHtmlScope.window */)) {
1217
- return ['window', htmlKey.substring(10)];
1218
- }
1219
- return ['document', htmlKey.substring(12)];
1220
- };
1221
- const getScopedEventName = (scope, eventName) => {
1222
- const suffix = ':' + eventName;
1223
- return scope ? scope + suffix : suffix;
1224
- };
1225
- const getLoaderScopedEventName = (scope, scopedEvent) => {
1226
- return scope ? '-' + scopedEvent : scopedEvent;
1227
- };
1228
-
1229
1251
  /** @internal */
1230
1252
  const EMPTY_ARRAY = [];
1231
1253
  const EMPTY_OBJ = {};
@@ -1618,7 +1640,7 @@ class ComputedSignalImpl extends SignalImpl {
1618
1640
  // We need a separate flag to know when the computation needs running because
1619
1641
  // we need the old value to know if effects need running after computation
1620
1642
  flags = 1 /* SignalFlags.INVALID */ |
1621
- 32 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_ALWAYS */) {
1643
+ 16 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_ALWAYS */) {
1622
1644
  // The value is used for comparison when signals trigger, which can only happen
1623
1645
  // when it was calculated before. Therefore we can pass whatever we like.
1624
1646
  super(container, NEEDS_COMPUTATION);
@@ -1687,24 +1709,16 @@ class ComputedSignalImpl extends SignalImpl {
1687
1709
  }
1688
1710
  }
1689
1711
  }
1690
- // Make this signal read-only
1691
- set value(_) {
1692
- throw qError(30 /* QError.computedReadOnly */);
1693
- }
1694
- // Getters don't get inherited when overriding a setter
1695
- get value() {
1696
- return super.value;
1697
- }
1698
1712
  }
1699
1713
 
1700
1714
  /**
1701
1715
  * # ================================
1702
1716
  *
1703
- * AsyncComputedSignalImpl
1717
+ * AsyncSignalImpl
1704
1718
  *
1705
1719
  * # ================================
1706
1720
  */
1707
- class AsyncComputedSignalImpl extends ComputedSignalImpl {
1721
+ class AsyncSignalImpl extends ComputedSignalImpl {
1708
1722
  $untrackedLoading$ = false;
1709
1723
  $untrackedError$ = undefined;
1710
1724
  $loadingEffects$ = undefined;
@@ -1753,7 +1767,7 @@ class AsyncComputedSignalImpl extends ComputedSignalImpl {
1753
1767
  async promise() {
1754
1768
  // make sure we get a new promise during the next computation
1755
1769
  this.$promise$ = null;
1756
- await retryOnPromise(() => this.$computeIfNeeded$());
1770
+ await retryOnPromise(this.$computeIfNeeded$.bind(this));
1757
1771
  return this.$untrackedValue$;
1758
1772
  }
1759
1773
  $computeIfNeeded$() {
@@ -1815,6 +1829,42 @@ class AsyncComputedSignalImpl extends ComputedSignalImpl {
1815
1829
  track: trackFn(this, this.$container$),
1816
1830
  cleanup,
1817
1831
  });
1832
+ // TODO implement these
1833
+ // const arg: {
1834
+ // track: Tracker;
1835
+ // cleanup: ReturnType<typeof cleanupFn>[0];
1836
+ // poll: (ms: number) => void;
1837
+ // } = {
1838
+ // poll: (ms: number) => {
1839
+ // setTimeout(() => {
1840
+ // super.invalidate();
1841
+ // if (this.$effects$?.size) {
1842
+ // this.$computeIfNeeded$();
1843
+ // }
1844
+ // }, ms);
1845
+ // },
1846
+ // } as any;
1847
+ // Object.defineProperty(arg, 'track', {
1848
+ // get() {
1849
+ // const fn = trackFn(this, this.$container$);
1850
+ // arg.track = fn;
1851
+ // return fn;
1852
+ // },
1853
+ // configurable: true,
1854
+ // enumerable: true,
1855
+ // writable: true,
1856
+ // });
1857
+ // Object.defineProperty(arg, 'cleanup', {
1858
+ // get() {
1859
+ // const [fn] = cleanupFn(this, (err) => this.$container$?.handleError(err, null!));
1860
+ // arg.cleanup = fn;
1861
+ // return fn;
1862
+ // },
1863
+ // configurable: true,
1864
+ // enumerable: true,
1865
+ // writable: true,
1866
+ // });
1867
+ // this.$promise$ = this.$computeQrl$.getFn()(arg) as ValueOrPromise<T>;
1818
1868
  }
1819
1869
  return this.$promise$;
1820
1870
  }
@@ -1883,7 +1933,7 @@ const implicit$FirstArg = (fn) => {
1883
1933
  */
1884
1934
  class SerializerSignalImpl extends ComputedSignalImpl {
1885
1935
  constructor(container, argQrl) {
1886
- super(container, argQrl, 1 /* SignalFlags.INVALID */ | 32 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_ALWAYS */);
1936
+ super(container, argQrl, 1 /* SignalFlags.INVALID */ | 16 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_ALWAYS */);
1887
1937
  }
1888
1938
  $didInitialize$ = false;
1889
1939
  $computeIfNeeded$() {
@@ -1921,8 +1971,8 @@ const createComputedSignal = (qrl, options) => {
1921
1971
  return new ComputedSignalImpl(options?.container || null, qrl, getComputedSignalFlags(options?.serializationStrategy || 'always'));
1922
1972
  };
1923
1973
  /** @internal */
1924
- const createAsyncComputedSignal = (qrl, options) => {
1925
- return new AsyncComputedSignalImpl(options?.container || null, qrl, getComputedSignalFlags(options?.serializationStrategy || 'never'));
1974
+ const createAsyncSignal = (qrl, options) => {
1975
+ return new AsyncSignalImpl(options?.container || null, qrl, getComputedSignalFlags(options?.serializationStrategy || 'never'));
1926
1976
  };
1927
1977
  /** @internal */
1928
1978
  const createSerializerSignal = (arg) => {
@@ -1944,7 +1994,7 @@ const createSignal = createSignal$1;
1944
1994
  * The QRL must be a function which returns the value of the signal. The function must not have side
1945
1995
  * effects, and it must be synchronous.
1946
1996
  *
1947
- * If you need the function to be async, use `useAsyncComputed$` instead.
1997
+ * If you need the function to be async, use `useAsync$` instead.
1948
1998
  *
1949
1999
  * @public
1950
2000
  */
@@ -1959,7 +2009,8 @@ const createComputed$ = /*#__PURE__*/ implicit$FirstArg(createComputedSignal);
1959
2009
  *
1960
2010
  * @public
1961
2011
  */
1962
- const createAsyncComputed$ = /*#__PURE__*/ implicit$FirstArg(createAsyncComputedSignal);
2012
+ const createAsync$ =
2013
+ /*#__PURE__*/ implicit$FirstArg(createAsyncSignal);
1963
2014
  /**
1964
2015
  * Create a signal that holds a custom serializable value. See {@link useSerializer$} for more
1965
2016
  * details.
@@ -2003,7 +2054,7 @@ const _wrapProp = (...args) => {
2003
2054
  return obj[prop];
2004
2055
  }
2005
2056
  if (isSignal(obj)) {
2006
- if (!(obj instanceof AsyncComputedSignalImpl)) {
2057
+ if (!(obj instanceof AsyncSignalImpl)) {
2007
2058
  isDev && assertEqual(prop, 'value', 'Left side is a signal, prop must be value');
2008
2059
  }
2009
2060
  if (obj instanceof WrappedSignalImpl && obj.$flags$ & 4 /* WrappedSignalFlags.UNWRAP */) {
@@ -2153,9 +2204,9 @@ function clearEffectSubscription(container, effect) {
2153
2204
  return;
2154
2205
  }
2155
2206
  for (const producer of backRefs) {
2156
- // Check AsyncComputedSignalImpl before SignalImpl since it extends SignalImpl
2157
- if (producer instanceof AsyncComputedSignalImpl) {
2158
- clearAsyncComputedSignal(producer, effect);
2207
+ // Check AsyncSignalImpl before SignalImpl since it extends SignalImpl
2208
+ if (producer instanceof AsyncSignalImpl) {
2209
+ clearAsyncSignal(producer, effect);
2159
2210
  }
2160
2211
  else if (producer instanceof SignalImpl) {
2161
2212
  clearSignal(container, producer, effect);
@@ -2183,7 +2234,7 @@ function clearSignal(container, producer, effect) {
2183
2234
  clearAllEffects(container, producer);
2184
2235
  }
2185
2236
  }
2186
- function clearAsyncComputedSignal(producer, effect) {
2237
+ function clearAsyncSignal(producer, effect) {
2187
2238
  const effects = producer.$effects$;
2188
2239
  if (effects && effects.has(effect)) {
2189
2240
  effects.delete(effect);
@@ -2215,58 +2266,38 @@ class SubscriptionData {
2215
2266
  }
2216
2267
  }
2217
2268
 
2218
- // <docs markdown="../readme.md#useLexicalScope">
2219
- // !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
2220
- // (edit ../readme.md#useLexicalScope instead and run `pnpm docs.sync`)
2221
2269
  /**
2222
- * Used by the Qwik Optimizer to restore the lexically scoped variables.
2223
- *
2224
- * This method should not be present in the application source code.
2225
- *
2226
- * NOTE: `useLexicalScope` method can only be used in the synchronous portion of the callback
2227
- * (before any `await` statements.)
2228
- *
2229
- * @internal
2270
+ * Qwikloader provides the captures string of the QRL when calling a handler. In that case we must
2271
+ * load the QRL captured scope ourselves. Otherwise, we are being called as a QRL and the captures
2272
+ * are already set.
2230
2273
  */
2231
- // </docs>
2232
- const useLexicalScope = () => {
2233
- const context = getInvokeContext();
2234
- let qrl = context.$qrl$;
2235
- if (!qrl) {
2236
- const el = context.$hostElement$ instanceof ElementVNode ? context.$hostElement$.node : undefined;
2237
- isDev && assertDefined(el, 'invoke: element must be defined inside useLexicalScope()', context);
2238
- const containerElement = _getQContainerElement(el);
2239
- isDev && assertDefined(containerElement, `invoke: cant find parent q:container of`, el);
2240
- const container = getDomContainer(containerElement);
2241
- context.$container$ ||= container;
2242
- qrl = container.parseQRL(decodeURIComponent(String(context.$url$)));
2274
+ const maybeScopeFromQL = (captureIds, element) => {
2275
+ if (typeof captureIds === 'string') {
2276
+ const container = getDomContainer(element);
2277
+ setCaptures(deserializeCaptures(container, captureIds));
2243
2278
  }
2244
- else {
2245
- isDev && assertQrl(qrl);
2246
- isDev &&
2247
- assertDefined(qrl.$captureRef$, 'invoke: qrl $captureRef$ must be defined inside useLexicalScope()', qrl);
2248
- }
2249
- return qrl.$captureRef$;
2279
+ return null;
2250
2280
  };
2251
-
2252
2281
  /**
2253
2282
  * Handles events for bind:value
2254
2283
  *
2255
2284
  * @internal
2256
2285
  */
2257
- const _val = (_, element) => {
2258
- const [signal] = useLexicalScope();
2286
+ function _val(_, element) {
2287
+ maybeScopeFromQL(this, element);
2288
+ const signal = _captures[0];
2259
2289
  signal.value = element.type === 'number' ? element.valueAsNumber : element.value;
2260
- };
2290
+ }
2261
2291
  /**
2262
2292
  * Handles events for bind:checked
2263
2293
  *
2264
2294
  * @internal
2265
2295
  */
2266
- const _chk = (_, element) => {
2267
- const [signal] = useLexicalScope();
2296
+ function _chk(_, element) {
2297
+ maybeScopeFromQL(this, element);
2298
+ const signal = _captures[0];
2268
2299
  signal.value = element.checked;
2269
- };
2300
+ }
2270
2301
 
2271
2302
  const _hasOwnProperty$2 = Object.prototype.hasOwnProperty;
2272
2303
  // TODO store props as the arrays the vnodes also use?
@@ -2357,7 +2388,9 @@ const _hasOwnProperty$1 = Object.prototype.hasOwnProperty;
2357
2388
  * @param children - JSX children. Any `children` in the props objects are ignored.
2358
2389
  * @internal
2359
2390
  */
2360
- const _jsxSorted = (type, varProps, constProps, children, flags, key, dev) => {
2391
+ const _jsxSorted = (type, varProps, constProps, children,
2392
+ // TODO use this to know static parts of the tree
2393
+ flags, key, dev) => {
2361
2394
  return new JSXNodeImpl(type, varProps, constProps, children, key, false, dev);
2362
2395
  };
2363
2396
  /**
@@ -2384,7 +2417,7 @@ const _jsxSplit = (type, varProps, constProps, children, flags, key, dev) => {
2384
2417
  let bindCheckedSignal = null;
2385
2418
  // Apply transformations for native HTML elements only
2386
2419
  if (typeof type === 'string') {
2387
- // Transform event names (onClick$ -> on:click)
2420
+ // Transform event names (onClick$ -> q-e:click)
2388
2421
  if (constProps) {
2389
2422
  const processedKeys = new Set();
2390
2423
  for (const k in constProps) {
@@ -2437,34 +2470,34 @@ const _jsxSplit = (type, varProps, constProps, children, flags, key, dev) => {
2437
2470
  if (bindCheckedSignal) {
2438
2471
  delete varProps[BIND_CHECKED];
2439
2472
  varProps.checked = bindCheckedSignal;
2440
- const handler = createQRL(null, '_chk', _chk, null, null, [bindCheckedSignal]);
2441
- // Move on:input from constProps if it exists
2442
- if (constProps && _hasOwnProperty$1.call(constProps, 'on:input')) {
2473
+ const handler = createQRL(null, '_chk', _chk, null, [bindCheckedSignal]);
2474
+ // Move q-e:input from constProps if it exists
2475
+ if (constProps && _hasOwnProperty$1.call(constProps, 'q-e:input')) {
2443
2476
  if (!constPropsCopied) {
2444
2477
  constProps = { ...constProps };
2445
2478
  constPropsCopied = true;
2446
2479
  }
2447
- const existingHandler = constProps['on:input'];
2448
- delete constProps['on:input'];
2449
- toSort = mergeHandlers(varProps, 'on:input', existingHandler) || toSort;
2480
+ const existingHandler = constProps['q-e:input'];
2481
+ delete constProps['q-e:input'];
2482
+ toSort = mergeHandlers(varProps, 'q-e:input', existingHandler) || toSort;
2450
2483
  }
2451
- toSort = mergeHandlers(varProps, 'on:input', handler) || toSort;
2484
+ toSort = mergeHandlers(varProps, 'q-e:input', handler) || toSort;
2452
2485
  }
2453
2486
  else if (bindValueSignal) {
2454
2487
  delete varProps[BIND_VALUE];
2455
2488
  varProps.value = bindValueSignal;
2456
- const handler = createQRL(null, '_val', _val, null, null, [bindValueSignal]);
2457
- // Move on:input from constProps if it exists
2458
- if (constProps && _hasOwnProperty$1.call(constProps, 'on:input')) {
2489
+ const handler = createQRL(null, '_val', _val, null, [bindValueSignal]);
2490
+ // Move q-e:input from constProps if it exists
2491
+ if (constProps && _hasOwnProperty$1.call(constProps, 'q-e:input')) {
2459
2492
  if (!constPropsCopied) {
2460
2493
  constProps = { ...constProps };
2461
2494
  constPropsCopied = true;
2462
2495
  }
2463
- const existingHandler = constProps['on:input'];
2464
- delete constProps['on:input'];
2465
- toSort = mergeHandlers(varProps, 'on:input', existingHandler) || toSort;
2496
+ const existingHandler = constProps['q-e:input'];
2497
+ delete constProps['q-e:input'];
2498
+ toSort = mergeHandlers(varProps, 'q-e:input', existingHandler) || toSort;
2466
2499
  }
2467
- toSort = mergeHandlers(varProps, 'on:input', handler) || toSort;
2500
+ toSort = mergeHandlers(varProps, 'q-e:input', handler) || toSort;
2468
2501
  }
2469
2502
  }
2470
2503
  }
@@ -2695,7 +2728,7 @@ const executeComponent = (container, renderHost, subscriptionHost, componentQRL,
2695
2728
  function addUseOnEvents(jsx, useOnEvents) {
2696
2729
  const jsxElement = findFirstElementNode(jsx);
2697
2730
  let jsxResult = jsx;
2698
- const qVisibleEvent = 'on:qvisible';
2731
+ const qVisibleEvent = 'q-e:qvisible';
2699
2732
  return maybeThen(jsxElement, (jsxElement) => {
2700
2733
  // headless components are components that don't render a real DOM element
2701
2734
  const isHeadless = !jsxElement;
@@ -2708,8 +2741,8 @@ function addUseOnEvents(jsx, useOnEvents) {
2708
2741
  if (isHeadless) {
2709
2742
  // if the component is headless, we need to add the event to the placeholder element
2710
2743
  if (key === qVisibleEvent ||
2711
- key.startsWith("on-document:" /* EventNameHtmlScope.document */) ||
2712
- key.startsWith("on-window:" /* EventNameHtmlScope.window */)) {
2744
+ key.startsWith("q-d:" /* EventNameHtmlScope.document */) ||
2745
+ key.startsWith("q-w:" /* EventNameHtmlScope.window */)) {
2713
2746
  if (!placeholderElement) {
2714
2747
  const [createdElement, newJsx] = injectPlaceholderElement(jsxResult);
2715
2748
  jsxResult = newJsx;
@@ -2730,7 +2763,7 @@ function addUseOnEvents(jsx, useOnEvents) {
2730
2763
  }
2731
2764
  if (targetElement) {
2732
2765
  if (targetElement.type === 'script' && key === qVisibleEvent) {
2733
- eventKey = 'on-document:qinit';
2766
+ eventKey = 'q-d:qinit';
2734
2767
  if (isDev) {
2735
2768
  logWarn('You are trying to add an event "' +
2736
2769
  key +
@@ -2778,6 +2811,7 @@ function addUseOnEvent(jsxElement, key, value) {
2778
2811
  props[key] = undefined;
2779
2812
  }
2780
2813
  }
2814
+ const getValue$1 = (o) => o.value;
2781
2815
  /**
2782
2816
  * Finds the first element node in the JSX output.
2783
2817
  *
@@ -2801,7 +2835,7 @@ function findFirstElementNode(jsx) {
2801
2835
  return maybeThen(jsx, (jsx) => findFirstElementNode(jsx));
2802
2836
  }
2803
2837
  else if (isSignal(jsx)) {
2804
- return findFirstElementNode(untrack(() => jsx.value));
2838
+ return findFirstElementNode(untrack(getValue$1, jsx));
2805
2839
  }
2806
2840
  }
2807
2841
  return null;
@@ -2880,6 +2914,34 @@ const SSRStreamBlock = (props) => {
2880
2914
  const SSRStream = (props, key) => jsx(RenderOnce, { children: jsx(InternalSSRStream, props) }, key);
2881
2915
  const InternalSSRStream = () => null;
2882
2916
 
2917
+ let _setAttribute = null;
2918
+ const fastSetAttribute = (target, name, value) => {
2919
+ if (!_setAttribute) {
2920
+ _setAttribute = target.setAttribute;
2921
+ }
2922
+ _setAttribute.call(target, name, value);
2923
+ };
2924
+ let _setAttributeNS = null;
2925
+ const fastSetAttributeNS = (target, namespace, name, value) => {
2926
+ if (!_setAttributeNS) {
2927
+ _setAttributeNS = target.setAttributeNS;
2928
+ }
2929
+ _setAttributeNS.call(target, namespace, name, value);
2930
+ };
2931
+ function directSetAttribute(element, attrName, attrValue, isSvg) {
2932
+ if (attrValue != null) {
2933
+ if (isSvg) {
2934
+ // only svg elements can have namespace attributes
2935
+ const namespace = getAttributeNamespace(attrName);
2936
+ if (namespace) {
2937
+ fastSetAttributeNS(element, namespace, attrName, attrValue);
2938
+ return;
2939
+ }
2940
+ }
2941
+ fastSetAttribute(element, attrName, attrValue);
2942
+ }
2943
+ }
2944
+
2883
2945
  function escapeHTML(html) {
2884
2946
  let escapedHTML = '';
2885
2947
  const length = html.length;
@@ -3149,55 +3211,6 @@ const styleKey = (qStyles, index) => {
3149
3211
  return `${hashCode(qStyles.$hash$)}-${index}`;
3150
3212
  };
3151
3213
 
3152
- /** @internal */
3153
- const mapApp_findIndx = (array, key, start) => {
3154
- isDev && assertTrue(start % 2 === 0, 'Expecting even number.');
3155
- let bottom = start >> 1;
3156
- let top = (array.length - 2) >> 1;
3157
- while (bottom <= top) {
3158
- const mid = bottom + ((top - bottom) >> 1);
3159
- const midKey = array[mid << 1];
3160
- if (midKey === key) {
3161
- return mid << 1;
3162
- }
3163
- if (midKey < key) {
3164
- bottom = mid + 1;
3165
- }
3166
- else {
3167
- top = mid - 1;
3168
- }
3169
- }
3170
- return (bottom << 1) ^ -1;
3171
- };
3172
- /** @internal */
3173
- const mapArray_set = (array, key, value, start, allowNullValue = false) => {
3174
- const indx = mapApp_findIndx(array, key, start);
3175
- if (indx >= 0) {
3176
- if (value == null && !allowNullValue) {
3177
- array.splice(indx, 2);
3178
- }
3179
- else {
3180
- array[indx + 1] = value;
3181
- }
3182
- }
3183
- else if (value != null || allowNullValue) {
3184
- array.splice(indx ^ -1, 0, key, value);
3185
- }
3186
- };
3187
- /** @internal */
3188
- const mapArray_get = (array, key, start) => {
3189
- const indx = mapApp_findIndx(array, key, start);
3190
- if (indx >= 0) {
3191
- return array[indx + 1];
3192
- }
3193
- else {
3194
- return null;
3195
- }
3196
- };
3197
- const mapArray_has = (array, key, start) => {
3198
- return mapApp_findIndx(array, key, start) >= 0;
3199
- };
3200
-
3201
3214
  class DeleteOperation {
3202
3215
  target;
3203
3216
  constructor(target) {
@@ -3250,74 +3263,103 @@ const createSetTextOperation = (target, text) => new SetTextOperation(target, te
3250
3263
  const createInsertOrMoveOperation = (target, parent, beforeTarget) => new InsertOrMoveOperation(target, parent, beforeTarget);
3251
3264
  const createSetAttributeOperation = (target, attrName, attrValue, scopedStyleIdPrefix = null, isSvg = false) => new SetAttributeOperation(target, attrName, attrValue, scopedStyleIdPrefix, isSvg);
3252
3265
 
3253
- function callQrl(container, host, qrl, event, element, useGetObjectById) {
3254
- const getObjectById = useGetObjectById ? container?.$getObjectById$ || null : null;
3255
- const singleItem = vnode_getProp(host, ITERATION_ITEM_SINGLE, getObjectById);
3256
- if (singleItem !== null) {
3257
- return qrl(event, element, singleItem);
3258
- }
3259
- const multiItems = vnode_getProp(host, ITERATION_ITEM_MULTI, getObjectById);
3260
- if (multiItems !== null) {
3261
- return qrl(event, element, ...multiItems);
3266
+ /**
3267
+ * This safely calls an event handler, handling errors and retrying on thrown Promises, and
3268
+ * providing extra parameters defined on the elements as arguments (used for loop optimization)
3269
+ */
3270
+ function runEventHandlerQRL(handler, event, element, ctx = newInvokeContextFromDOM(event, element)) {
3271
+ const container = ctx.$container$;
3272
+ const hostElement = ctx.$hostElement$;
3273
+ vnode_ensureElementInflated(container, hostElement);
3274
+ let realHandler = handler;
3275
+ if (hostElement.flags & 64 /* VNodeFlags.HasIterationItems */) {
3276
+ let shouldInflate;
3277
+ if (!(hostElement.flags & 128 /* VNodeFlags.InflatedIterationItems */)) {
3278
+ shouldInflate = true;
3279
+ hostElement.flags |= 128 /* VNodeFlags.InflatedIterationItems */;
3280
+ }
3281
+ const getObj = shouldInflate ? container.$getObjectById$ : null;
3282
+ const singleItem = vnode_getProp(hostElement, ITERATION_ITEM_SINGLE, getObj);
3283
+ if (singleItem !== null) {
3284
+ realHandler = (() => handler(event, element, singleItem));
3285
+ }
3286
+ else {
3287
+ const multiItems = vnode_getProp(hostElement, ITERATION_ITEM_MULTI, getObj);
3288
+ if (multiItems !== null) {
3289
+ realHandler = (() => handler(event, element, ...multiItems));
3290
+ }
3291
+ }
3262
3292
  }
3263
- return qrl(event, element);
3293
+ return retryOnPromise(() => {
3294
+ // Check if the host element was deleted while waiting for the promise to resolve
3295
+ if (!(hostElement.flags & 32 /* VNodeFlags.Deleted */)) {
3296
+ return invokeApply(ctx, realHandler, [event, element]);
3297
+ }
3298
+ }, (err) => container.handleError(err, hostElement));
3264
3299
  }
3265
3300
  /**
3266
- * This is called by qwik-loader to run a QRL. It has to be synchronous.
3301
+ * This is called by qwik-loader to run a QRL. It has to be synchronous when possible.
3267
3302
  *
3268
3303
  * @internal
3269
3304
  */
3270
- const _run = (...args) => {
3271
- // This will already check container
3272
- const [qrl] = useLexicalScope();
3273
- const context = getInvokeContext();
3274
- const hostElement = context.$hostElement$;
3275
- if (hostElement) {
3276
- context.$container$ ||= getDomContainer(hostElement.node);
3277
- vnode_ensureElementInflated(hostElement);
3278
- return retryOnPromise(() => {
3279
- if (!(hostElement.flags & 32 /* VNodeFlags.Deleted */)) {
3280
- return callQrl(context.$container$, hostElement, qrl, args[0], args[1], true).catch((err) => {
3281
- const container = context.$container$;
3282
- if (container) {
3283
- container.handleError(err, hostElement);
3284
- }
3285
- else {
3286
- throw err;
3287
- }
3288
- });
3289
- }
3290
- });
3305
+ function _run(event, element) {
3306
+ const ctx = newInvokeContextFromDOM(event, element);
3307
+ if (typeof this === 'string') {
3308
+ setCaptures(deserializeCaptures(ctx.$container$, this));
3291
3309
  }
3292
- };
3310
+ const qrlToRun = _captures[0];
3311
+ isDev && assertQrl(qrlToRun);
3312
+ return runEventHandlerQRL(qrlToRun, event, element, ctx);
3313
+ }
3293
3314
 
3294
- let _setAttribute = null;
3295
- const fastSetAttribute = (target, name, value) => {
3296
- if (!_setAttribute) {
3297
- _setAttribute = target.setAttribute;
3315
+ /** @internal */
3316
+ const mapApp_findIndx = (array, key, start) => {
3317
+ isDev && assertTrue(start % 2 === 0, 'Expecting even number.');
3318
+ let bottom = start >> 1;
3319
+ let top = (array.length - 2) >> 1;
3320
+ while (bottom <= top) {
3321
+ const mid = bottom + ((top - bottom) >> 1);
3322
+ const midKey = array[mid << 1];
3323
+ if (midKey === key) {
3324
+ return mid << 1;
3325
+ }
3326
+ if (midKey < key) {
3327
+ bottom = mid + 1;
3328
+ }
3329
+ else {
3330
+ top = mid - 1;
3331
+ }
3298
3332
  }
3299
- _setAttribute.call(target, name, value);
3333
+ return (bottom << 1) ^ -1;
3300
3334
  };
3301
- let _setAttributeNS = null;
3302
- const fastSetAttributeNS = (target, namespace, name, value) => {
3303
- if (!_setAttributeNS) {
3304
- _setAttributeNS = target.setAttributeNS;
3335
+ /** @internal */
3336
+ const mapArray_set = (array, key, value, start, allowNullValue = false) => {
3337
+ const indx = mapApp_findIndx(array, key, start);
3338
+ if (indx >= 0) {
3339
+ if (value == null && !allowNullValue) {
3340
+ array.splice(indx, 2);
3341
+ }
3342
+ else {
3343
+ array[indx + 1] = value;
3344
+ }
3345
+ }
3346
+ else if (value != null || allowNullValue) {
3347
+ array.splice(indx ^ -1, 0, key, value);
3305
3348
  }
3306
- _setAttributeNS.call(target, namespace, name, value);
3307
3349
  };
3308
- function directSetAttribute(element, attrName, attrValue, isSvg) {
3309
- if (attrValue != null) {
3310
- if (isSvg) {
3311
- // only svg elements can have namespace attributes
3312
- const namespace = getAttributeNamespace(attrName);
3313
- if (namespace) {
3314
- fastSetAttributeNS(element, namespace, attrName, attrValue);
3315
- return;
3316
- }
3317
- }
3318
- fastSetAttribute(element, attrName, attrValue);
3350
+ /** @internal */
3351
+ const mapArray_get = (array, key, start) => {
3352
+ const indx = mapApp_findIndx(array, key, start);
3353
+ if (indx >= 0) {
3354
+ return array[indx + 1];
3319
3355
  }
3320
- }
3356
+ else {
3357
+ return null;
3358
+ }
3359
+ };
3360
+ const mapArray_has = (array, key, start) => {
3361
+ return mapApp_findIndx(array, key, start) >= 0;
3362
+ };
3321
3363
 
3322
3364
  /**
3323
3365
  * Helper to get the next sibling of a VNode. Extracted to module scope to help V8 inline it
@@ -3333,7 +3375,7 @@ function setAttribute(journal, vnode, key, value, scopedStyleIdPrefix, originalV
3333
3375
  scopedStyleIdPrefix &&
3334
3376
  vnode_setProp(vnode, debugStyleScopeIdPrefixAttr, scopedStyleIdPrefix);
3335
3377
  vnode_setProp(vnode, key, originalValue);
3336
- addVNodeOperation(journal, createSetAttributeOperation(vnode.node, key, value, scopedStyleIdPrefix, (vnode.flags & 128 /* VNodeFlags.NS_svg */) !== 0));
3378
+ addVNodeOperation(journal, createSetAttributeOperation(vnode.node, key, value, scopedStyleIdPrefix, (vnode.flags & 512 /* VNodeFlags.NS_svg */) !== 0));
3337
3379
  }
3338
3380
  const vnode_diff = (container, journal, jsxNode, vStartNode, cursor, scopedStyleIdPrefix) => {
3339
3381
  const diffContext = {
@@ -3828,16 +3870,9 @@ function expectNoMoreTextNodes(diffContext) {
3828
3870
  vnode_remove(diffContext.journal, diffContext.vParent, toRemove, true);
3829
3871
  }
3830
3872
  }
3831
- /**
3832
- * Returns whether `qDispatchEvent` needs patching. This is true when one of the `jsx` argument's
3833
- * const props has the name of an event.
3834
- *
3835
- * @returns {boolean}
3836
- */
3837
3873
  function createNewElement(diffContext, jsx, elementName, currentFile) {
3838
3874
  const element = createElementWithNamespace(diffContext, elementName);
3839
3875
  const { constProps } = jsx;
3840
- let needsQDispatchEventPatch = false;
3841
3876
  if (constProps) {
3842
3877
  // Const props are, well, constant, they will never change!
3843
3878
  // For this reason we can cheat and write them directly into the DOM.
@@ -3845,22 +3880,7 @@ function createNewElement(diffContext, jsx, elementName, currentFile) {
3845
3880
  for (const key in constProps) {
3846
3881
  let value = constProps[key];
3847
3882
  if (isHtmlAttributeAnEventName(key)) {
3848
- const data = getEventDataFromHtmlAttribute(key);
3849
- if (data) {
3850
- const [scope, eventName] = data;
3851
- const scopedEvent = getScopedEventName(scope, eventName);
3852
- const loaderScopedEvent = getLoaderScopedEventName(scope, scopedEvent);
3853
- if (eventName) {
3854
- vnode_setProp(diffContext.vNewNode, '::' + scopedEvent, value);
3855
- if (scope) {
3856
- // window and document need attrs so qwik loader can find them
3857
- vnode_setAttr(diffContext.journal, diffContext.vNewNode, key, '');
3858
- }
3859
- // register an event for qwik loader (window/document prefixed with '-')
3860
- registerQwikLoaderEvent(diffContext, loaderScopedEvent);
3861
- }
3862
- }
3863
- needsQDispatchEventPatch = true;
3883
+ registerEventHandlers(key, value, element, diffContext.vNewNode, diffContext);
3864
3884
  continue;
3865
3885
  }
3866
3886
  if (key === 'ref') {
@@ -3886,7 +3906,7 @@ function createNewElement(diffContext, jsx, elementName, currentFile) {
3886
3906
  }
3887
3907
  if (isPromise(value)) {
3888
3908
  const vHost = diffContext.vNewNode;
3889
- const attributePromise = value.then((resolvedValue) => directSetAttribute(element, key, serializeAttribute(key, resolvedValue, diffContext.scopedStyleIdPrefix), (vHost.flags & 128 /* VNodeFlags.NS_svg */) !== 0));
3909
+ const attributePromise = value.then((resolvedValue) => directSetAttribute(element, key, serializeAttribute(key, resolvedValue, diffContext.scopedStyleIdPrefix), (vHost.flags & 512 /* VNodeFlags.NS_svg */) !== 0));
3890
3910
  diffContext.asyncAttributePromises.push(attributePromise);
3891
3911
  continue;
3892
3912
  }
@@ -3907,7 +3927,7 @@ function createNewElement(diffContext, jsx, elementName, currentFile) {
3907
3927
  element.value = escapeHTML(value || '');
3908
3928
  continue;
3909
3929
  }
3910
- directSetAttribute(element, key, serializeAttribute(key, value, diffContext.scopedStyleIdPrefix), (diffContext.vNewNode.flags & 128 /* VNodeFlags.NS_svg */) !== 0);
3930
+ directSetAttribute(element, key, serializeAttribute(key, value, diffContext.scopedStyleIdPrefix), (diffContext.vNewNode.flags & 512 /* VNodeFlags.NS_svg */) !== 0);
3911
3931
  }
3912
3932
  }
3913
3933
  const key = jsx.key;
@@ -3923,7 +3943,25 @@ function createNewElement(diffContext, jsx, elementName, currentFile) {
3923
3943
  }
3924
3944
  }
3925
3945
  vnode_insertBefore(diffContext.journal, diffContext.vParent, diffContext.vNewNode, diffContext.vCurrent);
3926
- return needsQDispatchEventPatch;
3946
+ }
3947
+ function registerEventHandlers(key, value, element, vnode, diffContext) {
3948
+ const scopedKebabName = key.slice(2);
3949
+ if (!Array.isArray(value)) {
3950
+ value = [value];
3951
+ }
3952
+ const handlers = [];
3953
+ for (const handler of value.flat(2)) {
3954
+ if (handler) {
3955
+ handlers.push(runEventHandlerQRL.bind(null, handler));
3956
+ }
3957
+ }
3958
+ (element._qDispatch ||= {})[scopedKebabName] = handlers;
3959
+ // window and document events need attrs so qwik loader can find them
3960
+ // TODO only do these when not already present
3961
+ if (key.charAt(2) !== 'e') {
3962
+ vnode_setAttr(diffContext.journal, vnode, key, '');
3963
+ }
3964
+ registerQwikLoaderEvent(diffContext, scopedKebabName);
3927
3965
  }
3928
3966
  function createElementWithNamespace(diffContext, elementName) {
3929
3967
  const domParentVNode = vnode_getDomParentVNode(diffContext.vParent, true);
@@ -3937,9 +3975,8 @@ function createElementWithNamespace(diffContext, elementName) {
3937
3975
  return element;
3938
3976
  }
3939
3977
  function expectElement(diffContext, jsx, elementName) {
3940
- let needsQDispatchEventPatch = false;
3941
3978
  if (diffContext.isCreationMode) {
3942
- needsQDispatchEventPatch = createNewElement(diffContext, jsx, elementName, null);
3979
+ createNewElement(diffContext, jsx, elementName, null);
3943
3980
  }
3944
3981
  else {
3945
3982
  const isElementVNode = diffContext.vCurrent && vnode_isElementVNode(diffContext.vCurrent);
@@ -3949,7 +3986,7 @@ function expectElement(diffContext, jsx, elementName) {
3949
3986
  if (!isSameElementName || jsxKey !== currentKey) {
3950
3987
  const sideBufferKey = getSideBufferKey(elementName, jsxKey);
3951
3988
  if (moveOrCreateKeyedNode(diffContext, elementName, jsxKey, sideBufferKey, diffContext.vParent)) {
3952
- needsQDispatchEventPatch = createNewElement(diffContext, jsx, elementName, null);
3989
+ createNewElement(diffContext, jsx, elementName, null);
3953
3990
  }
3954
3991
  }
3955
3992
  else {
@@ -3960,48 +3997,20 @@ function expectElement(diffContext, jsx, elementName) {
3960
3997
  // reconcile attributes
3961
3998
  const jsxProps = jsx.varProps;
3962
3999
  const vNode = (diffContext.vNewNode || diffContext.vCurrent);
3963
- const element = vNode.node;
3964
- if (jsxProps) {
3965
- needsQDispatchEventPatch =
3966
- diffProps(diffContext, vNode, jsxProps, (isDev && getFileLocationFromJsx(jsx.dev)) || null) ||
3967
- needsQDispatchEventPatch;
3968
- }
3969
- if (needsQDispatchEventPatch) {
3970
- // Event handler needs to be patched onto the element.
3971
- if (!element.qDispatchEvent) {
3972
- element.qDispatchEvent = (event, scope) => {
3973
- if (vNode.flags & 32 /* VNodeFlags.Deleted */) {
3974
- return;
3975
- }
3976
- const eventName = fromCamelToKebabCase(event.type);
3977
- const eventProp = ':' + scope.substring(1) + ':' + eventName;
3978
- const qrls = [
3979
- vnode_getProp(vNode, eventProp, null),
3980
- vnode_getProp(vNode, HANDLER_PREFIX + eventProp, null),
3981
- ];
3982
- for (const qrl of qrls.flat(2)) {
3983
- if (qrl) {
3984
- callQrl(diffContext.container, vNode, qrl, event, vNode.node, false).catch((e) => {
3985
- diffContext.container.handleError(e, vNode);
3986
- });
3987
- }
3988
- }
3989
- };
3990
- }
4000
+ if (jsxProps) {
4001
+ diffProps(diffContext, vNode, jsxProps, (isDev && getFileLocationFromJsx(jsx.dev)) || null);
3991
4002
  }
3992
4003
  }
3993
4004
  function diffProps(diffContext, vnode, newAttrs, currentFile) {
3994
4005
  if (!diffContext.isCreationMode) {
3995
4006
  // inflate only resumed vnodes
3996
- vnode_ensureElementInflated(vnode);
4007
+ vnode_ensureElementInflated(diffContext.container, vnode);
3997
4008
  }
3998
4009
  const oldAttrs = vnode.props;
3999
- let patchEventDispatch = false;
4000
4010
  // Actual diffing logic
4001
4011
  // Apply all new attributes
4002
4012
  for (const key in newAttrs) {
4003
4013
  const newValue = newAttrs[key];
4004
- const isEvent = isHtmlAttributeAnEventName(key);
4005
4014
  if (oldAttrs && _hasOwnProperty.call(oldAttrs, key)) {
4006
4015
  const oldValue = oldAttrs[key];
4007
4016
  if (newValue !== oldValue) {
@@ -4010,46 +4019,40 @@ function diffProps(diffContext, vnode, newAttrs, currentFile) {
4010
4019
  areWrappedSignalsEqual(newValue, oldValue)) {
4011
4020
  continue;
4012
4021
  }
4013
- if (isEvent) {
4014
- const result = recordJsxEvent(diffContext, vnode, key, newValue, currentFile);
4015
- patchEventDispatch ||= result;
4016
- }
4017
- else {
4018
- patchProperty(diffContext, vnode, key, newValue, currentFile);
4019
- }
4022
+ patchProperty(diffContext, vnode, key, newValue, currentFile);
4020
4023
  }
4021
4024
  }
4022
4025
  else if (newValue != null) {
4023
- if (isEvent) {
4024
- const result = recordJsxEvent(diffContext, vnode, key, newValue, currentFile);
4025
- patchEventDispatch ||= result;
4026
- }
4027
- else {
4028
- patchProperty(diffContext, vnode, key, newValue, currentFile);
4029
- }
4026
+ patchProperty(diffContext, vnode, key, newValue, currentFile);
4030
4027
  }
4031
4028
  }
4032
4029
  if (oldAttrs) {
4033
4030
  // Remove attributes that no longer exist in new props
4034
4031
  for (const key in oldAttrs) {
4035
4032
  if (!_hasOwnProperty.call(newAttrs, key) &&
4036
- !key.startsWith(HANDLER_PREFIX) &&
4033
+ // do not remove special attributes
4034
+ key.charAt(0) !== ':' &&
4035
+ // we keep these handler props to indicate to qwikloader that these events are used
4037
4036
  !isHtmlAttributeAnEventName(key)) {
4038
4037
  patchProperty(diffContext, vnode, key, null, currentFile);
4039
4038
  }
4040
4039
  }
4041
4040
  }
4042
- return patchEventDispatch;
4043
4041
  }
4044
4042
  const patchProperty = (diffContext, vnode, key, value, currentFile) => {
4043
+ // During CSR we do handlers via qDispatch
4044
+ if (isHtmlAttributeAnEventName(key)) {
4045
+ registerEventHandlers(key, value, vnode.node, vnode, diffContext);
4046
+ return;
4047
+ }
4045
4048
  if (
4046
4049
  // set only property for iteration item, not an attribute
4047
4050
  key === ITERATION_ITEM_SINGLE ||
4048
- key === ITERATION_ITEM_MULTI ||
4049
- key.charAt(0) === HANDLER_PREFIX) {
4051
+ key === ITERATION_ITEM_MULTI) {
4050
4052
  // TODO: there is a potential deoptimization here, because we are setting different keys on props.
4051
4053
  // Eager bailout - Insufficient type feedback for generic keyed access
4052
4054
  vnode_setProp(vnode, key, value);
4055
+ vnode.flags |= 64 /* VNodeFlags.HasIterationItems */ | 128 /* VNodeFlags.InflatedIterationItems */;
4053
4056
  return;
4054
4057
  }
4055
4058
  const originalValue = value;
@@ -4094,29 +4097,12 @@ const patchProperty = (diffContext, vnode, key, value, currentFile) => {
4094
4097
  }
4095
4098
  setAttribute(diffContext.journal, vnode, key, value, diffContext.scopedStyleIdPrefix, originalValue);
4096
4099
  };
4097
- const recordJsxEvent = (diffContext, vnode, key, value, currentFile) => {
4098
- const data = getEventDataFromHtmlAttribute(key);
4099
- if (data) {
4100
- const props = vnode.props;
4101
- const [scope, eventName] = data;
4102
- const scopedEvent = getScopedEventName(scope, eventName);
4103
- const loaderScopedEvent = getLoaderScopedEventName(scope, scopedEvent);
4104
- const scopedEventKey = ':' + scopedEvent;
4105
- if (props && _hasOwnProperty.call(props, scopedEventKey)) {
4106
- return false;
4107
- }
4108
- patchProperty(diffContext, vnode, scopedEventKey, value, currentFile);
4109
- registerQwikLoaderEvent(diffContext, loaderScopedEvent);
4110
- return true;
4111
- }
4112
- return false;
4113
- };
4114
4100
  function registerQwikLoaderEvent(diffContext, eventName) {
4115
4101
  const qWindow = import.meta.env.TEST
4116
4102
  ? diffContext.container.document.defaultView
4117
4103
  : window;
4118
4104
  if (qWindow) {
4119
- (qWindow.qwikevents ||= []).push(eventName);
4105
+ (qWindow._qwikEv ||= []).push(eventName);
4120
4106
  }
4121
4107
  }
4122
4108
  function retrieveChildWithKey(diffContext, nodeName, key) {
@@ -4238,7 +4224,9 @@ function moveOrCreateKeyedNode(diffContext, nodeName, lookupKey, sideBufferKey,
4238
4224
  // 1) Try to find the node among upcoming siblings
4239
4225
  diffContext.vNewNode = retrieveChildWithKey(diffContext, nodeName, lookupKey);
4240
4226
  if (diffContext.vNewNode) {
4241
- vnode_insertBefore(diffContext.journal, parentForInsert, diffContext.vNewNode, diffContext.vCurrent);
4227
+ if (!sideBufferKey) {
4228
+ vnode_insertBefore(diffContext.journal, parentForInsert, diffContext.vNewNode, diffContext.vCurrent);
4229
+ }
4242
4230
  diffContext.vCurrent = diffContext.vNewNode;
4243
4231
  diffContext.vNewNode = null;
4244
4232
  return false;
@@ -4262,7 +4250,10 @@ function moveOrCreateKeyedNode(diffContext, nodeName, lookupKey, sideBufferKey,
4262
4250
  }
4263
4251
  }
4264
4252
  }
4265
- vnode_insertBefore(diffContext.journal, parentForInsert, buffered, diffContext.vCurrent);
4253
+ // Only move if the node is not already in the correct position
4254
+ if (buffered !== diffContext.vCurrent) {
4255
+ vnode_insertBefore(diffContext.journal, parentForInsert, buffered, diffContext.vCurrent);
4256
+ }
4266
4257
  diffContext.vCurrent = buffered;
4267
4258
  diffContext.vNewNode = null;
4268
4259
  return false;
@@ -4587,7 +4578,7 @@ function cleanup(container, journal, vNode, cursorRoot = null) {
4587
4578
  else if (obj instanceof SignalImpl || isStore(obj)) {
4588
4579
  clearAllEffects(container, obj);
4589
4580
  }
4590
- if (objIsTask || obj instanceof AsyncComputedSignalImpl) {
4581
+ if (objIsTask || obj instanceof AsyncSignalImpl) {
4591
4582
  cleanupDestroyable(obj);
4592
4583
  }
4593
4584
  }
@@ -4733,11 +4724,6 @@ function containsWrappedSignal(data, signal) {
4733
4724
  }
4734
4725
  return false;
4735
4726
  }
4736
- /**
4737
- * This marks the property as immutable. It is needed for the QRLs so that QwikLoader can get a hold
4738
- * of them. This character must be `:` so that the `vnode_getAttr` can ignore them.
4739
- */
4740
- const HANDLER_PREFIX = ':';
4741
4727
  let count = 0;
4742
4728
 
4743
4729
  /**
@@ -4852,6 +4838,9 @@ const Resource = (props) => {
4852
4838
  // Resource path
4853
4839
  return _jsxSorted(Fragment, null, null, getResourceValueAsPromise(props), 0, null);
4854
4840
  };
4841
+ const getResolved = (resource) => resource._resolved;
4842
+ const getValue = (resource) => resource.value;
4843
+ const getLoading = (resource) => resource.loading;
4855
4844
  function getResourceValueAsPromise(props) {
4856
4845
  const resource = props.value;
4857
4846
  if (isResourceReturn(resource)) {
@@ -4867,14 +4856,14 @@ function getResourceValueAsPromise(props) {
4867
4856
  return Promise.resolve(resource._error).then(useBindInvokeContext(props.onRejected));
4868
4857
  }
4869
4858
  else {
4870
- const resolvedValue = untrack(() => resource._resolved);
4859
+ const resolvedValue = untrack(getResolved, resource);
4871
4860
  if (resolvedValue !== undefined) {
4872
4861
  // resolved, pending without onPending prop or rejected without onRejected prop
4873
4862
  return Promise.resolve(resolvedValue).then(useBindInvokeContext(props.onResolved));
4874
4863
  }
4875
4864
  }
4876
4865
  }
4877
- return untrack(() => resource.value).then(useBindInvokeContext(props.onResolved), useBindInvokeContext(props.onRejected));
4866
+ return untrack(getValue, resource).then(useBindInvokeContext(props.onResolved), useBindInvokeContext(props.onRejected));
4878
4867
  }
4879
4868
  else if (isPromise(resource)) {
4880
4869
  return resource.then(useBindInvokeContext(props.onResolved), useBindInvokeContext(props.onRejected));
@@ -4971,8 +4960,8 @@ const runResource = (task, container, host) => {
4971
4960
  * previous one is not resolved yet. The next `runResource` run will call this cleanup
4972
4961
  */
4973
4962
  cleanups.push(() => {
4974
- if (untrack(() => resource.loading) === true) {
4975
- const value = untrack(() => resource._resolved);
4963
+ if (untrack(getLoading, resource) === true) {
4964
+ const value = untrack(getResolved, resource);
4976
4965
  setState(true, value);
4977
4966
  }
4978
4967
  });
@@ -5156,7 +5145,7 @@ function clearNodePropData(vNode) {
5156
5145
  delete props[NODE_PROPS_DATA_KEY];
5157
5146
  }
5158
5147
  function setNodeProp(domVNode, journal, property, value, isConst, scopedStyleIdPrefix = null) {
5159
- journal.push(createSetAttributeOperation(domVNode.node, property, value, scopedStyleIdPrefix, (domVNode.flags & 128 /* VNodeFlags.NS_svg */) !== 0));
5148
+ journal.push(createSetAttributeOperation(domVNode.node, property, value, scopedStyleIdPrefix, (domVNode.flags & 512 /* VNodeFlags.NS_svg */) !== 0));
5160
5149
  if (!isConst) {
5161
5150
  if (domVNode.props && value == null) {
5162
5151
  delete domVNode.props[property];
@@ -5549,15 +5538,6 @@ function walkCursor(cursor, options) {
5549
5538
  // Get starting position (resume from last position or start at root)
5550
5539
  let currentVNode = null;
5551
5540
  while ((currentVNode = cursorData.position)) {
5552
- // Check time budget (only for DOM, not SSR)
5553
- if (!isRunningOnServer && !import.meta.env.TEST) {
5554
- const elapsed = performance.now() - startTime;
5555
- if (elapsed >= timeBudget) {
5556
- // Schedule continuation as macrotask to actually yield to browser
5557
- scheduleYield();
5558
- return;
5559
- }
5560
- }
5561
5541
  if (cursorData.promise) {
5562
5542
  return;
5563
5543
  }
@@ -5632,6 +5612,15 @@ function walkCursor(cursor, options) {
5632
5612
  });
5633
5613
  return;
5634
5614
  }
5615
+ // Check time budget (only for DOM, not SSR)
5616
+ if (!isRunningOnServer && !import.meta.env.TEST) {
5617
+ const elapsed = performance.now() - startTime;
5618
+ if (elapsed >= timeBudget) {
5619
+ // Schedule continuation as macrotask to actually yield to browser
5620
+ scheduleYield();
5621
+ return;
5622
+ }
5623
+ }
5635
5624
  }
5636
5625
  isDev &&
5637
5626
  assertFalse(!!(cursor.dirty & 127 /* ChoreBits.DIRTY_MASK */ && !cursorData.position), 'Cursor is still dirty and position is not set after walking');
@@ -5743,7 +5732,7 @@ function addCursor(container, root, priority) {
5743
5732
  };
5744
5733
  setCursorData(root, cursorData);
5745
5734
  const cursor = root;
5746
- cursor.flags |= 64 /* VNodeFlags.Cursor */;
5735
+ cursor.flags |= 256 /* VNodeFlags.Cursor */;
5747
5736
  // Add cursor to global queue
5748
5737
  addCursorToQueue(container, cursor);
5749
5738
  triggerCursors();
@@ -5756,7 +5745,7 @@ function addCursor(container, root, priority) {
5756
5745
  * @returns True if the vNode has the CURSOR flag set
5757
5746
  */
5758
5747
  function isCursor(vNode) {
5759
- return (vNode.flags & 64 /* VNodeFlags.Cursor */) !== 0;
5748
+ return (vNode.flags & 256 /* VNodeFlags.Cursor */) !== 0;
5760
5749
  }
5761
5750
  /**
5762
5751
  * Finds the root cursor for the given vNode.
@@ -6140,14 +6129,14 @@ const fastGetter = (prototype, name) => {
6140
6129
  //////////////////////////////////////////////////////////////////////////////////////////////////////
6141
6130
  const vnode_newElement = (element, elementName, key = null) => {
6142
6131
  isDev && assertEqual(fastNodeType(element), 1 /* ELEMENT_NODE */, 'Expecting element node.');
6143
- const vnode = new ElementVNode(key, 1 /* VNodeFlags.Element */ | 8 /* VNodeFlags.Inflated */ | (-1 << 9 /* VNodeFlagsIndex.shift */), // Flag
6132
+ const vnode = new ElementVNode(key, 1 /* VNodeFlags.Element */ | 8 /* VNodeFlags.Inflated */ | (-1 << 11 /* VNodeFlagsIndex.shift */), // Flag
6144
6133
  null, null, null, null, null, null, element, elementName);
6145
6134
  element.vNode = vnode;
6146
6135
  return vnode;
6147
6136
  };
6148
6137
  const vnode_newUnMaterializedElement = (element) => {
6149
6138
  isDev && assertEqual(fastNodeType(element), 1 /* ELEMENT_NODE */, 'Expecting element node.');
6150
- const vnode = new ElementVNode(null, 1 /* VNodeFlags.Element */ | (-1 << 9 /* VNodeFlagsIndex.shift */), // Flag
6139
+ const vnode = new ElementVNode(null, 1 /* VNodeFlags.Element */ | (-1 << 11 /* VNodeFlagsIndex.shift */), // Flag
6151
6140
  null, null, null, null, undefined, undefined, element, undefined);
6152
6141
  element.vNode = vnode;
6153
6142
  return vnode;
@@ -6156,7 +6145,7 @@ const vnode_newSharedText = (previousTextNode, sharedTextNode, textContent) => {
6156
6145
  isDev &&
6157
6146
  sharedTextNode &&
6158
6147
  assertEqual(fastNodeType(sharedTextNode), 3 /* TEXT_NODE */, 'Expecting text node.');
6159
- const vnode = new TextVNode(4 /* VNodeFlags.Text */ | (-1 << 9 /* VNodeFlagsIndex.shift */), // Flag
6148
+ const vnode = new TextVNode(4 /* VNodeFlags.Text */ | (-1 << 11 /* VNodeFlagsIndex.shift */), // Flag
6160
6149
  null, // Parent
6161
6150
  previousTextNode, // Previous TextNode (usually first child)
6162
6151
  null, // Next sibling
@@ -6164,7 +6153,7 @@ const vnode_newSharedText = (previousTextNode, sharedTextNode, textContent) => {
6164
6153
  return vnode;
6165
6154
  };
6166
6155
  const vnode_newText = (textNode, textContent) => {
6167
- const vnode = new TextVNode(4 /* VNodeFlags.Text */ | 8 /* VNodeFlags.Inflated */ | (-1 << 9 /* VNodeFlagsIndex.shift */), // Flags
6156
+ const vnode = new TextVNode(4 /* VNodeFlags.Text */ | 8 /* VNodeFlags.Inflated */ | (-1 << 11 /* VNodeFlagsIndex.shift */), // Flags
6168
6157
  null, // Parent
6169
6158
  null, // No previous sibling
6170
6159
  null, // We may have a next sibling.
@@ -6178,7 +6167,7 @@ const vnode_newText = (textNode, textContent) => {
6178
6167
  return vnode;
6179
6168
  };
6180
6169
  const vnode_newVirtual = () => {
6181
- const vnode = new VirtualVNode(null, 2 /* VNodeFlags.Virtual */ | (-1 << 9 /* VNodeFlagsIndex.shift */), // Flags
6170
+ const vnode = new VirtualVNode(null, 2 /* VNodeFlags.Virtual */ | (-1 << 11 /* VNodeFlagsIndex.shift */), // Flags
6182
6171
  null, null, null, null, null, null);
6183
6172
  isDev && assertFalse(vnode_isElementVNode(vnode), 'Incorrect format of TextVNode.');
6184
6173
  isDev && assertFalse(vnode_isTextVNode(vnode), 'Incorrect format of TextVNode.');
@@ -6274,7 +6263,7 @@ const vnode_setAttr = (journal, vNode, key, value, scopedStyleIdPrefix = null) =
6274
6263
  scopedStyleIdPrefix &&
6275
6264
  vnode_setProp(vNode, debugStyleScopeIdPrefixAttr, scopedStyleIdPrefix);
6276
6265
  vnode_setProp(vNode, key, value);
6277
- addVNodeOperation(journal, createSetAttributeOperation(vNode.node, key, value, scopedStyleIdPrefix, (vNode.flags & 128 /* VNodeFlags.NS_svg */) !== 0));
6266
+ addVNodeOperation(journal, createSetAttributeOperation(vNode.node, key, value, scopedStyleIdPrefix, (vNode.flags & 512 /* VNodeFlags.NS_svg */) !== 0));
6278
6267
  }
6279
6268
  };
6280
6269
  const vnode_ensureElementKeyInflated = (vnode) => {
@@ -6287,16 +6276,23 @@ const vnode_ensureElementKeyInflated = (vnode) => {
6287
6276
  }
6288
6277
  };
6289
6278
  /** @internal */
6290
- const vnode_ensureElementInflated = (vnode) => {
6279
+ const vnode_ensureElementInflated = (container, vnode) => {
6291
6280
  if ((vnode.flags & 15 /* VNodeFlags.INFLATED_TYPE_MASK */) === 1 /* VNodeFlags.Element */) {
6292
6281
  const elementVNode = vnode;
6293
6282
  elementVNode.flags ^= 8 /* VNodeFlags.Inflated */;
6294
6283
  const element = elementVNode.node;
6295
6284
  const attributes = element.attributes;
6285
+ let isConst = false;
6296
6286
  for (let idx = 0; idx < attributes.length; idx++) {
6297
6287
  const attr = attributes[idx];
6298
6288
  const key = attr.name;
6299
- if (key === Q_PROPS_SEPARATOR || !key) {
6289
+ // We need to grab all handlers, even const ones, because as soon as qDispatch exists, qwikloader will use it
6290
+ if (isHtmlAttributeAnEventName(key)) {
6291
+ registerQrlHandlers(attr, key, container, element);
6292
+ continue;
6293
+ }
6294
+ if (isConst) ;
6295
+ else if (key === Q_PROPS_SEPARATOR || !key) {
6300
6296
  // SVG in Domino does not support ':' so it becomes an empty string.
6301
6297
  // all attributes after the ':' are considered immutable, and so we ignore them.
6302
6298
  const value = attr.value;
@@ -6304,7 +6300,7 @@ const vnode_ensureElementInflated = (vnode) => {
6304
6300
  // don't assign empty string as a key
6305
6301
  elementVNode.key = value;
6306
6302
  }
6307
- break;
6303
+ isConst = true;
6308
6304
  }
6309
6305
  else if (key.startsWith(QContainerAttr)) {
6310
6306
  const value = attr.value;
@@ -6315,13 +6311,29 @@ const vnode_ensureElementInflated = (vnode) => {
6315
6311
  vnode_setProp(elementVNode, 'value', element.value);
6316
6312
  }
6317
6313
  }
6318
- else if (!key.startsWith("on:" /* EventNameHtmlScope.on */)) {
6314
+ else {
6319
6315
  const value = attr.value;
6320
6316
  vnode_setProp(elementVNode, key, value);
6321
6317
  }
6322
6318
  }
6319
+ if (vnode_getProp(elementVNode, ITERATION_ITEM_SINGLE, null) !== null ||
6320
+ vnode_getProp(elementVNode, ITERATION_ITEM_MULTI, null) !== null) {
6321
+ vnode.flags |= 64 /* VNodeFlags.HasIterationItems */;
6322
+ }
6323
6323
  }
6324
6324
  };
6325
+ function registerQrlHandlers(attr, key, container, element) {
6326
+ const value = attr.value;
6327
+ const scopedKebabName = key.slice(2);
6328
+ const qrls = value.split('|');
6329
+ const handlers = qrls.map((qrl) => {
6330
+ const handler = parseQRL(qrl);
6331
+ handler.$container$ = container;
6332
+ // These QRLs are mostly _run and _task and don't need wrapping with retryOnPromise
6333
+ return handler;
6334
+ });
6335
+ (element._qDispatch ||= {})[scopedKebabName] = handlers;
6336
+ }
6325
6337
  /** Walks the VNode tree and materialize it using `vnode_getFirstChild`. */
6326
6338
  function vnode_walkVNode(vNode, callback) {
6327
6339
  let vCursor = vNode;
@@ -6407,6 +6419,21 @@ function vnode_getDOMChildNodes(journal, root, isVNode = false, childNodes = [])
6407
6419
  }
6408
6420
  return childNodes;
6409
6421
  }
6422
+ function vnode_getDOMContainer(vNode) {
6423
+ let cursor = vNode;
6424
+ while (cursor) {
6425
+ if (vnode_isElementVNode(cursor)) {
6426
+ try {
6427
+ return getDomContainer(cursor.node);
6428
+ }
6429
+ catch {
6430
+ return null;
6431
+ }
6432
+ }
6433
+ cursor = cursor.parent;
6434
+ }
6435
+ return null;
6436
+ }
6410
6437
  /**
6411
6438
  * Returns the previous/next sibling but from the point of view of the DOM.
6412
6439
  *
@@ -6620,7 +6647,7 @@ const vnode_locate = (rootVNode, id) => {
6620
6647
  const vnode_getChildWithIdx = (vNode, childIdx) => {
6621
6648
  let child = vnode_getFirstChild(vNode);
6622
6649
  isDev && assertDefined(child, 'Missing child.');
6623
- while (child.flags >>> 9 /* VNodeFlagsIndex.shift */ !== childIdx) {
6650
+ while (child.flags >>> 11 /* VNodeFlagsIndex.shift */ !== childIdx) {
6624
6651
  child = child.nextSibling;
6625
6652
  isDev && assertDefined(child, 'Missing child.');
6626
6653
  }
@@ -7250,10 +7277,10 @@ const processVNodeData$1 = (vData, callback) => {
7250
7277
  }
7251
7278
  };
7252
7279
  /** @internal */
7253
- const vnode_getAttrKeys = (vnode) => {
7280
+ const vnode_getAttrKeys = (container, vnode) => {
7254
7281
  const type = vnode.flags;
7255
7282
  if ((type & 3 /* VNodeFlags.ELEMENT_OR_VIRTUAL_MASK */) !== 0) {
7256
- vnode_ensureElementInflated(vnode);
7283
+ vnode_ensureElementInflated(container, vnode);
7257
7284
  const keys = [];
7258
7285
  const props = vnode.props;
7259
7286
  if (props) {
@@ -7287,7 +7314,7 @@ const vnode_getNode = (vnode) => {
7287
7314
  return vnode.node;
7288
7315
  };
7289
7316
  /** @internal */
7290
- function vnode_toString(depth = 20, offset = '', materialize = false, siblings = false, colorize = true) {
7317
+ function vnode_toString(depth = 20, offset = '', materialize = false, siblings = false, colorize = true, container = this && vnode_getDOMContainer(this)) {
7291
7318
  let vnode = this;
7292
7319
  if (depth === 0) {
7293
7320
  return '...';
@@ -7306,12 +7333,12 @@ function vnode_toString(depth = 20, offset = '', materialize = false, siblings =
7306
7333
  strings.push(qwikDebugToString(vnode_getText(vnode)));
7307
7334
  }
7308
7335
  else if (vnode_isVirtualVNode(vnode)) {
7309
- const idx = vnode.flags >>> 9 /* VNodeFlagsIndex.shift */;
7336
+ const idx = vnode.flags >>> 11 /* VNodeFlagsIndex.shift */;
7310
7337
  const attrs = ['[' + String(idx) + ']'];
7311
7338
  if (vnode.dirty) {
7312
7339
  attrs.push(` dirty:${vnode.dirty}`);
7313
7340
  }
7314
- vnode_getAttrKeys(vnode).forEach((key) => {
7341
+ vnode_getAttrKeys(container, vnode).forEach((key) => {
7315
7342
  if (key !== DEBUG_TYPE && key !== debugStyleScopeIdPrefixAttr) {
7316
7343
  const value = vnode_getProp(vnode, key, null);
7317
7344
  attrs.push(' ' + key + '=' + qwikDebugToString(value));
@@ -7339,7 +7366,7 @@ function vnode_toString(depth = 20, offset = '', materialize = false, siblings =
7339
7366
  if (vnode.dirtyChildren) {
7340
7367
  attrs.push(` dirtyChildren[${vnode.dirtyChildren.length}]`);
7341
7368
  }
7342
- const keys = vnode_getAttrKeys(vnode);
7369
+ const keys = vnode_getAttrKeys(container, vnode);
7343
7370
  for (const key of keys) {
7344
7371
  const value = vnode_getProp(vnode, key, null);
7345
7372
  attrs.push(' ' + key + '=' + qwikDebugToString(value));
@@ -7391,7 +7418,7 @@ function materializeFromVNodeData(vParent, vData, element, child) {
7391
7418
  let vLast = null;
7392
7419
  let previousTextNode = null;
7393
7420
  const addVNode = (node) => {
7394
- node.flags = (node.flags & 511 /* VNodeFlagsIndex.mask */) | (idx << 9 /* VNodeFlagsIndex.shift */);
7421
+ node.flags = (node.flags & 2047 /* VNodeFlagsIndex.mask */) | (idx << 11 /* VNodeFlagsIndex.shift */);
7395
7422
  idx++;
7396
7423
  vLast && (vLast.nextSibling = node);
7397
7424
  node.previousSibling = vLast;
@@ -7677,16 +7704,6 @@ function setLocale(locale) {
7677
7704
 
7678
7705
  let _context;
7679
7706
  const tryGetInvokeContext = () => {
7680
- if (!_context) {
7681
- const context = typeof document !== 'undefined' && document && document.__q_context__;
7682
- if (!context) {
7683
- return undefined;
7684
- }
7685
- if (isArray(context)) {
7686
- return (document.__q_context__ = newInvokeContextFromTuple(context));
7687
- }
7688
- return context;
7689
- }
7690
7707
  return _context;
7691
7708
  };
7692
7709
  const getInvokeContext = () => {
@@ -7722,29 +7739,27 @@ function invoke(context, fn, ...args) {
7722
7739
  /** Call a function with the given InvokeContext and array of arguments. */
7723
7740
  function invokeApply(context, fn, args) {
7724
7741
  const previousContext = _context;
7725
- let returnValue;
7726
7742
  try {
7727
7743
  _context = context;
7728
- returnValue = fn.apply(this, args);
7744
+ return fn.apply(this, args);
7729
7745
  }
7730
7746
  finally {
7731
7747
  _context = previousContext;
7732
7748
  }
7733
- return returnValue;
7734
7749
  }
7735
- const newInvokeContextFromTuple = ([element, event, url]) => {
7750
+ const newInvokeContextFromDOM = (event, element) => {
7736
7751
  const domContainer = getDomContainer(element);
7737
7752
  const hostElement = vnode_locate(domContainer.rootVNode, element);
7738
7753
  const locale = domContainer.$locale$;
7739
7754
  locale && setLocale(locale);
7740
- return newInvokeContext(locale, hostElement, event, url);
7755
+ const context = newInvokeContext(locale, hostElement, event);
7756
+ context.$container$ = domContainer;
7757
+ return context;
7741
7758
  };
7742
- function newRenderInvokeContext(locale, hostElement, container, url) {
7759
+ function newRenderInvokeContext(locale, hostElement, container) {
7743
7760
  const ctx = {
7744
- $url$: url,
7745
7761
  $hostElement$: hostElement,
7746
7762
  $event$: RenderEvent,
7747
- $qrl$: undefined,
7748
7763
  $effectSubscriber$: undefined,
7749
7764
  $locale$: locale,
7750
7765
  $container$: container,
@@ -7754,14 +7769,12 @@ function newRenderInvokeContext(locale, hostElement, container, url) {
7754
7769
  return ctx;
7755
7770
  }
7756
7771
  // TODO how about putting url and locale (and event/custom?) in to a "static" object
7757
- function newInvokeContext(locale, hostElement, event, url) {
7772
+ function newInvokeContext(locale, hostElement, event) {
7758
7773
  // ServerRequestEvent has .locale, but it's not always defined.
7759
7774
  const $locale$ = locale || (event && isObject(event) && 'locale' in event ? event.locale : undefined);
7760
7775
  const ctx = {
7761
- $url$: url,
7762
7776
  $hostElement$: hostElement,
7763
7777
  $event$: event,
7764
- $qrl$: undefined,
7765
7778
  $effectSubscriber$: undefined,
7766
7779
  $locale$,
7767
7780
  $container$: undefined,
@@ -7832,24 +7845,8 @@ const trackSignalAndAssignHost = (value, host, property, container, data) => {
7832
7845
  return trackSignal(() => value.value, host, property, container, data);
7833
7846
  };
7834
7847
  /** @internal */
7835
- const _getContextElement = () => {
7836
- const iCtx = tryGetInvokeContext();
7837
- if (iCtx) {
7838
- const hostElement = iCtx.$hostElement$;
7839
- let element = null;
7840
- if (hostElement != null) {
7841
- if (vnode_isVNode(hostElement)) {
7842
- if (vnode_isElementVNode(hostElement)) {
7843
- element = vnode_getNode(hostElement);
7844
- }
7845
- }
7846
- else {
7847
- // isSSRnode
7848
- element = hostElement;
7849
- }
7850
- }
7851
- return element ?? iCtx.$qrl$?.$setContainer$(undefined);
7852
- }
7848
+ const _getContextHostElement = () => {
7849
+ return tryGetInvokeContext()?.$hostElement$;
7853
7850
  };
7854
7851
  /** @internal */
7855
7852
  const _getContextEvent = () => {
@@ -7874,10 +7871,8 @@ const _jsxBranch = (input) => {
7874
7871
  return input;
7875
7872
  };
7876
7873
  /** @internal */
7877
- const _waitUntilRendered = (elm) => {
7878
- const container = getDomContainer(elm);
7879
- const promise = container?.$renderPromise$;
7880
- return promise || Promise.resolve();
7874
+ const _waitUntilRendered = (container) => {
7875
+ return container.$renderPromise$ || Promise.resolve();
7881
7876
  };
7882
7877
 
7883
7878
  // <docs markdown="../readme.md#createContextId">
@@ -8158,6 +8153,7 @@ const _typeIdNames = [
8158
8153
  'URL',
8159
8154
  'Date',
8160
8155
  'Regex',
8156
+ 'QRL',
8161
8157
  'VNode',
8162
8158
  'RefVNode',
8163
8159
  'BigInt',
@@ -8168,15 +8164,13 @@ const _typeIdNames = [
8168
8164
  'Set',
8169
8165
  'Map',
8170
8166
  'Uint8Array',
8171
- 'QRL',
8172
- 'PreloadQRL',
8173
8167
  'Task',
8174
8168
  'Resource',
8175
8169
  'Component',
8176
8170
  'Signal',
8177
8171
  'WrappedSignal',
8178
8172
  'ComputedSignal',
8179
- 'AsyncComputedSignal',
8173
+ 'AsyncSignal',
8180
8174
  'SerializerSignal',
8181
8175
  'Store',
8182
8176
  'FormData',
@@ -8186,61 +8180,64 @@ const _typeIdNames = [
8186
8180
  'EffectSubscription',
8187
8181
  ];
8188
8182
 
8189
- function qrlToString(serializationContext, value, raw) {
8190
- let symbol = value.$symbol$;
8191
- let chunk = value.$chunk$;
8183
+ function qrlToString(serializationContext, qrl, raw) {
8184
+ let symbol = qrl.$symbol$;
8185
+ let chunk = qrl.$chunk$;
8192
8186
  const platform = getPlatform();
8193
8187
  if (platform) {
8194
- const result = platform.chunkForSymbol(symbol, chunk, value.dev?.file);
8188
+ const result = isDev
8189
+ ? platform.chunkForSymbol(symbol, chunk, qrl.dev?.file)
8190
+ : platform.chunkForSymbol(symbol, chunk);
8195
8191
  if (result) {
8196
8192
  chunk = result[1];
8197
8193
  symbol = result[0];
8198
8194
  }
8199
8195
  }
8200
- const isSync = isSyncQrl(value);
8196
+ const isSync = isSyncQrl(qrl);
8201
8197
  if (!isSync) {
8202
8198
  // If we have a symbol we need to resolve the chunk.
8203
8199
  if (!chunk) {
8204
- chunk = serializationContext.$symbolToChunkResolver$(value.$hash$);
8200
+ chunk = serializationContext.$symbolToChunkResolver$(qrl.$hash$);
8205
8201
  }
8206
8202
  // in Dev mode we need to keep track of the symbols
8207
8203
  if (isDev) {
8208
8204
  const backChannel = (globalThis.__qrl_back_channel__ ||=
8209
8205
  new Map());
8210
8206
  // During tests the resolved value is always available
8211
- backChannel.set(value.$symbol$, value.resolved);
8207
+ backChannel.set(qrl.$symbol$, qrl.$symbolRef$);
8212
8208
  if (!chunk) {
8213
8209
  chunk = QRL_RUNTIME_CHUNK;
8214
8210
  }
8215
8211
  }
8216
8212
  if (!chunk) {
8217
- throw qError(14 /* QError.qrlMissingChunk */, [value.$symbol$]);
8213
+ throw qError(14 /* QError.qrlMissingChunk */, [qrl.$symbol$]);
8218
8214
  }
8219
8215
  if (chunk.startsWith('./')) {
8220
8216
  chunk = chunk.slice(2);
8221
8217
  }
8222
8218
  }
8223
8219
  else {
8224
- const fn = value.resolved;
8220
+ const fn = qrl.resolved;
8225
8221
  chunk = '';
8226
8222
  // TODO test that provided stringified fn is used
8227
8223
  symbol = String(serializationContext.$addSyncFn$(null, 0, fn));
8228
8224
  }
8229
- let capturedIds = null;
8230
- if (Array.isArray(value.$captureRef$) && value.$captureRef$.length > 0) {
8225
+ const captures = qrl.getCaptured();
8226
+ let captureIds = null;
8227
+ if (captures && captures.length > 0) {
8231
8228
  // We refer by id so every capture needs to be a root
8232
- capturedIds = value.$captureRef$.map((ref) => `${serializationContext.$addRoot$(ref)}`);
8229
+ captureIds = captures.map((ref) => `${serializationContext.$addRoot$(ref)}`).join(' ');
8233
8230
  }
8234
8231
  if (raw) {
8235
- return [chunk, symbol, capturedIds];
8232
+ return [chunk, symbol, captureIds];
8236
8233
  }
8237
8234
  let qrlStringInline = `${chunk}#${symbol}`;
8238
- if (capturedIds && capturedIds.length > 0) {
8239
- qrlStringInline += `[${capturedIds.join(' ')}]`;
8235
+ if (captureIds) {
8236
+ qrlStringInline += `#${captureIds}`;
8240
8237
  }
8241
8238
  return qrlStringInline;
8242
8239
  }
8243
- function createQRLWithBackChannel(chunk, symbol, captureIds) {
8240
+ function createQRLWithBackChannel(chunk, symbol, captures) {
8244
8241
  let qrlImporter = null;
8245
8242
  if (isDev && chunk === QRL_RUNTIME_CHUNK) {
8246
8243
  const backChannel = globalThis.__qrl_back_channel__;
@@ -8250,23 +8247,12 @@ function createQRLWithBackChannel(chunk, symbol, captureIds) {
8250
8247
  qrlImporter = () => Promise.resolve({ [symbol]: fn });
8251
8248
  }
8252
8249
  }
8253
- return createQRL(chunk, symbol, null, qrlImporter, captureIds, null);
8250
+ return createQRL(chunk, symbol, null, qrlImporter, captures);
8254
8251
  }
8255
- /** Parses "chunk#hash[...rootRef]" */
8252
+ /** Parses "chunk#hash#...rootRef" */
8256
8253
  function parseQRL(qrl) {
8257
- const hashIdx = qrl.indexOf('#');
8258
- const captureStart = qrl.indexOf('[', hashIdx);
8259
- const captureEnd = qrl.indexOf(']', captureStart);
8260
- const chunk = hashIdx > -1 ? qrl.slice(0, hashIdx) : qrl.slice(0, captureStart);
8261
- const symbol = captureStart > -1 ? qrl.slice(hashIdx + 1, captureStart) : qrl.slice(hashIdx + 1);
8262
- const captureIds = captureStart > -1 && captureEnd > -1
8263
- ? qrl
8264
- .slice(captureStart + 1, captureEnd)
8265
- .split(' ')
8266
- .filter((v) => v.length)
8267
- .map((s) => parseInt(s, 10))
8268
- : null;
8269
- return createQRLWithBackChannel(chunk, symbol, captureIds);
8254
+ const [chunk, symbol, captures] = qrl.split('#');
8255
+ return createQRLWithBackChannel(chunk, symbol, captures || null);
8270
8256
  }
8271
8257
  const QRL_RUNTIME_CHUNK = 'mock-chunk';
8272
8258
 
@@ -8289,7 +8275,7 @@ const allocate = (container, typeId, value) => {
8289
8275
  else {
8290
8276
  return container.$getObjectById$(rootRef);
8291
8277
  }
8292
- case 13 /* TypeIds.ForwardRefs */:
8278
+ case 14 /* TypeIds.ForwardRefs */:
8293
8279
  return value;
8294
8280
  case 3 /* TypeIds.Constant */:
8295
8281
  return _constants[value];
@@ -8297,22 +8283,24 @@ const allocate = (container, typeId, value) => {
8297
8283
  return Array(value.length / 2);
8298
8284
  case 5 /* TypeIds.Object */:
8299
8285
  return {};
8300
- case 19 /* TypeIds.QRL */:
8301
- case 20 /* TypeIds.PreloadQRL */: {
8286
+ case 9 /* TypeIds.QRL */: {
8287
+ let qrl;
8302
8288
  if (typeof value === 'string') {
8303
- const data = value.split(' ').map(Number);
8304
- const chunk = container.$getObjectById$(data[0]);
8305
- const symbol = container.$getObjectById$(data[1]);
8306
- const captureIds = data.length > 2 ? data.slice(2) : null;
8307
- return createQRLWithBackChannel(chunk, symbol, captureIds);
8289
+ const [chunkId, symbolId, captureIds] = value.split('#');
8290
+ const chunk = container.$getObjectById$(chunkId);
8291
+ const symbol = container.$getObjectById$(symbolId);
8292
+ qrl = createQRLWithBackChannel(chunk, symbol, captureIds || null);
8308
8293
  }
8309
8294
  else {
8310
- return createQRLWithBackChannel('', String(value));
8295
+ // Sync qrl
8296
+ qrl = createQRLWithBackChannel('', String(value), null);
8311
8297
  }
8298
+ qrl.$container$ = container;
8299
+ return qrl;
8312
8300
  }
8313
- case 21 /* TypeIds.Task */:
8301
+ case 20 /* TypeIds.Task */:
8314
8302
  return new Task(-1, -1, null, null, null, null);
8315
- case 22 /* TypeIds.Resource */: {
8303
+ case 21 /* TypeIds.Resource */: {
8316
8304
  const res = createResourceReturn(container,
8317
8305
  // we don't care about the timeout value
8318
8306
  undefined, undefined);
@@ -8326,21 +8314,21 @@ const allocate = (container, typeId, value) => {
8326
8314
  case 8 /* TypeIds.Regex */:
8327
8315
  const idx = value.lastIndexOf('/');
8328
8316
  return new RegExp(value.slice(1, idx), value.slice(idx + 1));
8329
- case 14 /* TypeIds.Error */:
8317
+ case 15 /* TypeIds.Error */:
8330
8318
  return new Error();
8331
- case 23 /* TypeIds.Component */:
8319
+ case 22 /* TypeIds.Component */:
8332
8320
  return componentQrl(null);
8333
- case 24 /* TypeIds.Signal */:
8321
+ case 23 /* TypeIds.Signal */:
8334
8322
  return new SignalImpl(container, 0);
8335
- case 25 /* TypeIds.WrappedSignal */:
8323
+ case 24 /* TypeIds.WrappedSignal */:
8336
8324
  return new WrappedSignalImpl(container, null, null, null);
8337
- case 26 /* TypeIds.ComputedSignal */:
8325
+ case 25 /* TypeIds.ComputedSignal */:
8338
8326
  return new ComputedSignalImpl(container, null);
8339
- case 27 /* TypeIds.AsyncComputedSignal */:
8340
- return new AsyncComputedSignalImpl(container, null);
8341
- case 28 /* TypeIds.SerializerSignal */:
8327
+ case 26 /* TypeIds.AsyncSignal */:
8328
+ return new AsyncSignalImpl(container, null);
8329
+ case 27 /* TypeIds.SerializerSignal */:
8342
8330
  return new SerializerSignalImpl(container, null);
8343
- case 29 /* TypeIds.Store */: {
8331
+ case 28 /* TypeIds.Store */: {
8344
8332
  const data = value;
8345
8333
  // We need to allocate the store first, before we inflate its data, because the data can
8346
8334
  // reference the store itself (circular)
@@ -8357,19 +8345,19 @@ const allocate = (container, typeId, value) => {
8357
8345
  data[1] = storeValue;
8358
8346
  return store;
8359
8347
  }
8360
- case 12 /* TypeIds.URLSearchParams */:
8348
+ case 13 /* TypeIds.URLSearchParams */:
8361
8349
  return new URLSearchParams(value);
8362
- case 30 /* TypeIds.FormData */:
8350
+ case 29 /* TypeIds.FormData */:
8363
8351
  return new FormData();
8364
- case 31 /* TypeIds.JSXNode */:
8352
+ case 30 /* TypeIds.JSXNode */:
8365
8353
  return new JSXNodeImpl(null, null, null, null, null);
8366
- case 11 /* TypeIds.BigInt */:
8354
+ case 12 /* TypeIds.BigInt */:
8367
8355
  return BigInt(value);
8368
- case 16 /* TypeIds.Set */:
8356
+ case 17 /* TypeIds.Set */:
8369
8357
  return new Set();
8370
- case 17 /* TypeIds.Map */:
8358
+ case 18 /* TypeIds.Map */:
8371
8359
  return new Map();
8372
- case 15 /* TypeIds.Promise */:
8360
+ case 16 /* TypeIds.Promise */:
8373
8361
  let resolve;
8374
8362
  let reject;
8375
8363
  const promise = new Promise((res, rej) => {
@@ -8380,17 +8368,17 @@ const allocate = (container, typeId, value) => {
8380
8368
  // Don't leave unhandled promise rejections
8381
8369
  promise.catch(() => { });
8382
8370
  return promise;
8383
- case 18 /* TypeIds.Uint8Array */:
8371
+ case 19 /* TypeIds.Uint8Array */:
8384
8372
  const encodedLength = value.length;
8385
8373
  const blocks = encodedLength >>> 2;
8386
8374
  const rest = encodedLength & 3;
8387
8375
  const decodedLength = blocks * 3 + (rest ? rest - 1 : 0);
8388
8376
  return new Uint8Array(decodedLength);
8389
- case 32 /* TypeIds.PropsProxy */:
8377
+ case 31 /* TypeIds.PropsProxy */:
8390
8378
  return createPropsProxy(null);
8391
- case 9 /* TypeIds.VNode */:
8379
+ case 10 /* TypeIds.VNode */:
8392
8380
  return retrieveVNodeOrDocument(container, value);
8393
- case 10 /* TypeIds.RefVNode */:
8381
+ case 11 /* TypeIds.RefVNode */:
8394
8382
  const vNode = retrieveVNodeOrDocument(container, value);
8395
8383
  if (vnode_isVNode(vNode)) {
8396
8384
  /**
@@ -8424,9 +8412,9 @@ const allocate = (container, typeId, value) => {
8424
8412
  else {
8425
8413
  throw qError(17 /* QError.serializeErrorExpectedVNode */, [typeof vNode]);
8426
8414
  }
8427
- case 33 /* TypeIds.SubscriptionData */:
8415
+ case 32 /* TypeIds.SubscriptionData */:
8428
8416
  return new SubscriptionData({});
8429
- case 34 /* TypeIds.EffectSubscription */:
8417
+ case 33 /* TypeIds.EffectSubscription */:
8430
8418
  return new EffectSubscription(null, null, null, null);
8431
8419
  default:
8432
8420
  throw qError(18 /* QError.serializeErrorCannotAllocate */, [typeId]);
@@ -8463,7 +8451,7 @@ const EXTRACT_FILE_NAME = /[\\/(]([\w\d.\-_]+\.(js|ts)x?):/;
8463
8451
  * @see `QRL`, `$(...)`
8464
8452
  */
8465
8453
  // </docs>
8466
- const qrl = (chunkOrFn, symbol, lexicalScopeCapture = EMPTY_ARRAY, stackOffset = 0) => {
8454
+ const qrl = (chunkOrFn, symbol, lexicalScopeCapture, stackOffset = 0) => {
8467
8455
  let chunk = null;
8468
8456
  let symbolFn = null;
8469
8457
  if (isFunction(chunkOrFn)) {
@@ -8499,7 +8487,7 @@ const qrl = (chunkOrFn, symbol, lexicalScopeCapture = EMPTY_ARRAY, stackOffset =
8499
8487
  throw qError(7 /* QError.unknownTypeArgument */, [chunkOrFn]);
8500
8488
  }
8501
8489
  // Unwrap subscribers
8502
- return createQRL(chunk, symbol, null, symbolFn, null, lexicalScopeCapture);
8490
+ return createQRL(chunk, symbol, null, symbolFn, lexicalScopeCapture);
8503
8491
  };
8504
8492
  /**
8505
8493
  * Create an inlined QRL. This is mostly useful on the server side for serialization.
@@ -8510,28 +8498,28 @@ const qrl = (chunkOrFn, symbol, lexicalScopeCapture = EMPTY_ARRAY, stackOffset =
8510
8498
  * @param lexicalScopeCapture - A set of lexically scoped variables to capture.
8511
8499
  * @public
8512
8500
  */
8513
- const inlinedQrl = (symbol, symbolName, lexicalScopeCapture = EMPTY_ARRAY) => {
8501
+ const inlinedQrl = (symbol, symbolName, lexicalScopeCapture) => {
8514
8502
  // Unwrap subscribers
8515
- return createQRL(null, symbolName, symbol, null, null, lexicalScopeCapture);
8503
+ return createQRL(null, symbolName, symbol, null, lexicalScopeCapture);
8516
8504
  };
8517
8505
  /** @internal */
8518
- const _noopQrl = (symbolName, lexicalScopeCapture = EMPTY_ARRAY) => {
8519
- return createQRL(null, symbolName, null, null, null, lexicalScopeCapture);
8506
+ const _noopQrl = (symbolName, lexicalScopeCapture) => {
8507
+ return createQRL(null, symbolName, null, null, lexicalScopeCapture);
8520
8508
  };
8521
8509
  /** @internal */
8522
- const _noopQrlDEV = (symbolName, opts, lexicalScopeCapture = EMPTY_ARRAY) => {
8510
+ const _noopQrlDEV = (symbolName, opts, lexicalScopeCapture) => {
8523
8511
  const newQrl = _noopQrl(symbolName, lexicalScopeCapture);
8524
8512
  newQrl.dev = opts;
8525
8513
  return newQrl;
8526
8514
  };
8527
8515
  /** @internal */
8528
- const qrlDEV = (chunkOrFn, symbol, opts, lexicalScopeCapture = EMPTY_ARRAY) => {
8516
+ const qrlDEV = (chunkOrFn, symbol, opts, lexicalScopeCapture) => {
8529
8517
  const newQrl = qrl(chunkOrFn, symbol, lexicalScopeCapture, 1);
8530
8518
  newQrl.dev = opts;
8531
8519
  return newQrl;
8532
8520
  };
8533
8521
  /** @internal */
8534
- const inlinedQrlDEV = (symbol, symbolName, opts, lexicalScopeCapture = EMPTY_ARRAY) => {
8522
+ const inlinedQrlDEV = (symbol, symbolName, opts, lexicalScopeCapture) => {
8535
8523
  const qrl = inlinedQrl(symbol, symbolName, lexicalScopeCapture);
8536
8524
  qrl.dev = opts;
8537
8525
  return qrl;
@@ -8579,7 +8567,6 @@ async function serialize(serializationContext) {
8579
8567
  const forwardRefs = [];
8580
8568
  let forwardRefsId = 0;
8581
8569
  const promises = new Set();
8582
- const preloadQrls = new Set();
8583
8570
  const s11nWeakRefs = new Map();
8584
8571
  let parent;
8585
8572
  const qrlMap = new Map();
@@ -8632,12 +8619,6 @@ async function serialize(serializationContext) {
8632
8619
  });
8633
8620
  }
8634
8621
  };
8635
- const addPreloadQrl = (qrl) => {
8636
- if (!isSyncQrl(qrl)) {
8637
- preloadQrls.add(qrl);
8638
- serializationContext.$addRoot$(qrl);
8639
- }
8640
- };
8641
8622
  const getSeenRefOrOutput = (value, index, keepWeak) => {
8642
8623
  let seen = getSeenRef(value);
8643
8624
  const forwardRefIdx = !keepWeak && s11nWeakRefs.get(value);
@@ -8728,7 +8709,7 @@ async function serialize(serializationContext) {
8728
8709
  break;
8729
8710
  case 'bigint':
8730
8711
  if ((value < 10000 && value > -1e3) || getSeenRefOrOutput(value, index)) {
8731
- output(11 /* TypeIds.BigInt */, value.toString());
8712
+ output(12 /* TypeIds.BigInt */, value.toString());
8732
8713
  }
8733
8714
  break;
8734
8715
  case 'symbol':
@@ -8751,12 +8732,11 @@ async function serialize(serializationContext) {
8751
8732
  }
8752
8733
  else if (isQrl(value)) {
8753
8734
  if (getSeenRefOrOutput(value, index)) {
8754
- const [chunk, symbol, captureIds] = qrlToString(serializationContext, value, true);
8735
+ const [chunk, symbol, captures] = qrlToString(serializationContext, value, true);
8755
8736
  let data;
8756
- let type;
8757
8737
  if (chunk !== '') {
8758
8738
  // not a sync QRL, replace all parts with string references
8759
- data = `${$addRoot$(chunk)} ${$addRoot$(symbol)}${captureIds ? ' ' + captureIds.join(' ') : ''}`;
8739
+ data = `${$addRoot$(chunk)}#${$addRoot$(symbol)}${captures ? '#' + captures : ''}`;
8760
8740
  // Since we map QRLs to strings, we need to keep track of this secondary mapping
8761
8741
  const existing = qrlMap.get(data);
8762
8742
  if (existing) {
@@ -8768,19 +8748,18 @@ async function serialize(serializationContext) {
8768
8748
  else {
8769
8749
  qrlMap.set(data, value);
8770
8750
  }
8771
- type = preloadQrls.has(value) ? 20 /* TypeIds.PreloadQRL */ : 19 /* TypeIds.QRL */;
8772
8751
  }
8773
8752
  else {
8753
+ // sync QRL
8774
8754
  data = Number(symbol);
8775
- type = 19 /* TypeIds.QRL */;
8776
8755
  }
8777
- output(type, data);
8756
+ output(9 /* TypeIds.QRL */, data);
8778
8757
  }
8779
8758
  }
8780
8759
  else if (isQwikComponent(value)) {
8781
8760
  const [qrl] = value[SERIALIZABLE_STATE];
8782
8761
  serializationContext.$renderSymbols$.add(qrl.$symbol$);
8783
- output(23 /* TypeIds.Component */, [qrl]);
8762
+ output(22 /* TypeIds.Component */, [qrl]);
8784
8763
  }
8785
8764
  else {
8786
8765
  throw qError(34 /* QError.serializeErrorCannotSerializeFunction */, [value.toString()]);
@@ -8818,7 +8797,7 @@ async function serialize(serializationContext) {
8818
8797
  const writeObjectValue = (value) => {
8819
8798
  if (isPropsProxy(value)) {
8820
8799
  const owner = value[_OWNER];
8821
- output(32 /* TypeIds.PropsProxy */, [
8800
+ output(31 /* TypeIds.PropsProxy */, [
8822
8801
  _serializationWeakRef(owner),
8823
8802
  owner.varProps,
8824
8803
  owner.constProps,
@@ -8826,10 +8805,10 @@ async function serialize(serializationContext) {
8826
8805
  ]);
8827
8806
  }
8828
8807
  else if (value instanceof SubscriptionData) {
8829
- output(33 /* TypeIds.SubscriptionData */, [value.data.$scopedStyleIdPrefix$, value.data.$isConst$]);
8808
+ output(32 /* TypeIds.SubscriptionData */, [value.data.$scopedStyleIdPrefix$, value.data.$isConst$]);
8830
8809
  }
8831
8810
  else if (value instanceof EffectSubscription) {
8832
- output(34 /* TypeIds.EffectSubscription */, [
8811
+ output(33 /* TypeIds.EffectSubscription */, [
8833
8812
  value.consumer,
8834
8813
  value.property,
8835
8814
  value.backRef,
@@ -8842,7 +8821,7 @@ async function serialize(serializationContext) {
8842
8821
  serializationContext.$resources$.add(value);
8843
8822
  // TODO the effects include the resource return which has duplicate data
8844
8823
  const forwardRefId = resolvePromise(value.value, $addRoot$, (resolved, resolvedValue) => {
8845
- return new PromiseResult(22 /* TypeIds.Resource */, resolved, resolvedValue, getStoreHandler(value).$effects$);
8824
+ return new PromiseResult(21 /* TypeIds.Resource */, resolved, resolvedValue, getStoreHandler(value).$effects$);
8846
8825
  });
8847
8826
  output(2 /* TypeIds.ForwardRef */, forwardRefId);
8848
8827
  }
@@ -8864,14 +8843,14 @@ async function serialize(serializationContext) {
8864
8843
  while (out[out.length - 1] === undefined) {
8865
8844
  out.pop();
8866
8845
  }
8867
- output(29 /* TypeIds.Store */, out);
8846
+ output(28 /* TypeIds.Store */, out);
8868
8847
  }
8869
8848
  }
8870
8849
  else if (isSerializerObj(value)) {
8871
8850
  const result = value[SerializerSymbol](value);
8872
8851
  if (isPromise(result)) {
8873
8852
  const forwardRef = resolvePromise(result, $addRoot$, (resolved, resolvedValue) => {
8874
- return new PromiseResult(28 /* TypeIds.SerializerSignal */, resolved, resolvedValue, undefined, undefined);
8853
+ return new PromiseResult(27 /* TypeIds.SerializerSignal */, resolved, resolvedValue, undefined, undefined);
8875
8854
  });
8876
8855
  output(2 /* TypeIds.ForwardRef */, forwardRef);
8877
8856
  }
@@ -8901,20 +8880,19 @@ async function serialize(serializationContext) {
8901
8880
  }
8902
8881
  else if ($isDomRef$(value)) {
8903
8882
  value.$ssrNode$.vnodeData[0] |= 16 /* VNodeDataFlag.SERIALIZE */;
8904
- output(10 /* TypeIds.RefVNode */, value.$ssrNode$.id);
8883
+ output(11 /* TypeIds.RefVNode */, value.$ssrNode$.id);
8905
8884
  }
8906
8885
  else if (value instanceof SignalImpl) {
8907
8886
  if (value instanceof SerializerSignalImpl) {
8908
- addPreloadQrl(value.$computeQrl$);
8909
8887
  const maybeValue = getCustomSerializerPromise(value, value.$untrackedValue$);
8910
8888
  if (isPromise(maybeValue)) {
8911
8889
  const forwardRefId = resolvePromise(maybeValue, $addRoot$, (resolved, resolvedValue) => {
8912
- return new PromiseResult(28 /* TypeIds.SerializerSignal */, resolved, resolvedValue, value.$effects$, value.$computeQrl$);
8890
+ return new PromiseResult(27 /* TypeIds.SerializerSignal */, resolved, resolvedValue, value.$effects$, value.$computeQrl$);
8913
8891
  });
8914
8892
  output(2 /* TypeIds.ForwardRef */, forwardRefId);
8915
8893
  }
8916
8894
  else {
8917
- output(28 /* TypeIds.SerializerSignal */, [
8895
+ output(27 /* TypeIds.SerializerSignal */, [
8918
8896
  value.$computeQrl$,
8919
8897
  filterEffectBackRefs(value[_EFFECT_BACK_REF]),
8920
8898
  value.$effects$,
@@ -8924,7 +8902,7 @@ async function serialize(serializationContext) {
8924
8902
  return;
8925
8903
  }
8926
8904
  if (value instanceof WrappedSignalImpl) {
8927
- output(25 /* TypeIds.WrappedSignal */, [
8905
+ output(24 /* TypeIds.WrappedSignal */, [
8928
8906
  ...serializeWrappingFn(serializationContext, value),
8929
8907
  filterEffectBackRefs(value[_EFFECT_BACK_REF]),
8930
8908
  value.$flags$,
@@ -8934,8 +8912,8 @@ async function serialize(serializationContext) {
8934
8912
  }
8935
8913
  else if (value instanceof ComputedSignalImpl) {
8936
8914
  let v = value.$untrackedValue$;
8937
- const shouldAlwaysSerialize = value.$flags$ & 32 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_ALWAYS */;
8938
- const shouldNeverSerialize = value.$flags$ & 16 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_NEVER */;
8915
+ const shouldAlwaysSerialize = value.$flags$ & 16 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_ALWAYS */;
8916
+ const shouldNeverSerialize = value.$flags$ & 8 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_NEVER */;
8939
8917
  const isInvalid = value.$flags$ & 1 /* SignalFlags.INVALID */;
8940
8918
  const isSkippable = fastSkipSerialize(value.$untrackedValue$);
8941
8919
  if (shouldAlwaysSerialize) {
@@ -8947,13 +8925,12 @@ async function serialize(serializationContext) {
8947
8925
  else if (isInvalid || isSkippable) {
8948
8926
  v = NEEDS_COMPUTATION;
8949
8927
  }
8950
- addPreloadQrl(value.$computeQrl$);
8951
8928
  const out = [
8952
8929
  value.$computeQrl$,
8953
8930
  filterEffectBackRefs(value[_EFFECT_BACK_REF]),
8954
8931
  value.$effects$,
8955
8932
  ];
8956
- const isAsync = value instanceof AsyncComputedSignalImpl;
8933
+ const isAsync = value instanceof AsyncSignalImpl;
8957
8934
  if (isAsync) {
8958
8935
  out.push(value.$loadingEffects$, value.$errorEffects$, value.$untrackedLoading$, value.$untrackedError$);
8959
8936
  }
@@ -8969,7 +8946,7 @@ async function serialize(serializationContext) {
8969
8946
  keepUndefined = true;
8970
8947
  }
8971
8948
  }
8972
- output(isAsync ? 27 /* TypeIds.AsyncComputedSignal */ : 26 /* TypeIds.ComputedSignal */, out, keepUndefined);
8949
+ output(isAsync ? 26 /* TypeIds.AsyncSignal */ : 25 /* TypeIds.ComputedSignal */, out, keepUndefined);
8973
8950
  }
8974
8951
  else {
8975
8952
  const v = value.$untrackedValue$;
@@ -8978,7 +8955,7 @@ async function serialize(serializationContext) {
8978
8955
  if (value.$effects$) {
8979
8956
  out.push(...value.$effects$);
8980
8957
  }
8981
- output(24 /* TypeIds.Signal */, out, keepUndefined);
8958
+ output(23 /* TypeIds.Signal */, out, keepUndefined);
8982
8959
  }
8983
8960
  }
8984
8961
  else if (value instanceof URL) {
@@ -8998,13 +8975,13 @@ async function serialize(serializationContext) {
8998
8975
  if (isDev) {
8999
8976
  out.push('stack', value.stack);
9000
8977
  }
9001
- output(14 /* TypeIds.Error */, out);
8978
+ output(15 /* TypeIds.Error */, out);
9002
8979
  }
9003
8980
  else if ($isSsrNode$(value)) {
9004
8981
  const rootIndex = $addRoot$(value);
9005
8982
  serializationContext.$setProp$(value, ELEMENT_ID, String(rootIndex));
9006
8983
  // we need to output before the vnode overwrites its values
9007
- output(9 /* TypeIds.VNode */, value.id);
8984
+ output(10 /* TypeIds.VNode */, value.id);
9008
8985
  const vNodeData = value.vnodeData;
9009
8986
  if (vNodeData) {
9010
8987
  discoverValuesForVNodeData(vNodeData, (vNodeDataValue) => $addRoot$(vNodeDataValue));
@@ -9040,20 +9017,20 @@ async function serialize(serializationContext) {
9040
9017
  array.push(key, value.name);
9041
9018
  }
9042
9019
  });
9043
- output(30 /* TypeIds.FormData */, array);
9020
+ output(29 /* TypeIds.FormData */, array);
9044
9021
  }
9045
9022
  else if (value instanceof URLSearchParams) {
9046
- output(12 /* TypeIds.URLSearchParams */, value.toString());
9023
+ output(13 /* TypeIds.URLSearchParams */, value.toString());
9047
9024
  }
9048
9025
  else if (value instanceof Set) {
9049
- output(16 /* TypeIds.Set */, [...value.values()]);
9026
+ output(17 /* TypeIds.Set */, [...value.values()]);
9050
9027
  }
9051
9028
  else if (value instanceof Map) {
9052
9029
  const combined = [];
9053
9030
  for (const [k, v] of value.entries()) {
9054
9031
  combined.push(k, v);
9055
9032
  }
9056
- output(17 /* TypeIds.Map */, combined);
9033
+ output(18 /* TypeIds.Map */, combined);
9057
9034
  }
9058
9035
  else if (isJSXNode(value)) {
9059
9036
  const out = [
@@ -9067,7 +9044,7 @@ async function serialize(serializationContext) {
9067
9044
  while (out[out.length - 1] === undefined) {
9068
9045
  out.pop();
9069
9046
  }
9070
- output(31 /* TypeIds.JSXNode */, out);
9047
+ output(30 /* TypeIds.JSXNode */, out);
9071
9048
  }
9072
9049
  else if (value instanceof Task) {
9073
9050
  const out = [
@@ -9081,21 +9058,21 @@ async function serialize(serializationContext) {
9081
9058
  while (out[out.length - 1] === undefined) {
9082
9059
  out.pop();
9083
9060
  }
9084
- output(21 /* TypeIds.Task */, out);
9061
+ output(20 /* TypeIds.Task */, out);
9085
9062
  }
9086
9063
  else if (isPromise(value)) {
9087
9064
  const forwardRefId = resolvePromise(value, $addRoot$, (resolved, resolvedValue) => {
9088
- return new PromiseResult(15 /* TypeIds.Promise */, resolved, resolvedValue);
9065
+ return new PromiseResult(16 /* TypeIds.Promise */, resolved, resolvedValue);
9089
9066
  });
9090
9067
  output(2 /* TypeIds.ForwardRef */, forwardRefId);
9091
9068
  }
9092
9069
  else if (value instanceof PromiseResult) {
9093
- if (value.$type$ === 22 /* TypeIds.Resource */) {
9094
- output(22 /* TypeIds.Resource */, [value.$resolved$, value.$value$, value.$effects$]);
9070
+ if (value.$type$ === 21 /* TypeIds.Resource */) {
9071
+ output(21 /* TypeIds.Resource */, [value.$resolved$, value.$value$, value.$effects$]);
9095
9072
  }
9096
- else if (value.$type$ === 28 /* TypeIds.SerializerSignal */) {
9073
+ else if (value.$type$ === 27 /* TypeIds.SerializerSignal */) {
9097
9074
  if (value.$qrl$) {
9098
- output(28 /* TypeIds.SerializerSignal */, [value.$qrl$, value.$effects$, value.$value$]);
9075
+ output(27 /* TypeIds.SerializerSignal */, [value.$qrl$, value.$effects$, value.$value$]);
9099
9076
  }
9100
9077
  else if (value.$resolved$) {
9101
9078
  // We replace ourselves with this value
@@ -9109,7 +9086,7 @@ async function serialize(serializationContext) {
9109
9086
  }
9110
9087
  }
9111
9088
  else {
9112
- output(15 /* TypeIds.Promise */, [value.$resolved$, value.$value$]);
9089
+ output(16 /* TypeIds.Promise */, [value.$resolved$, value.$value$]);
9113
9090
  }
9114
9091
  }
9115
9092
  else if (value instanceof Uint8Array) {
@@ -9118,7 +9095,7 @@ async function serialize(serializationContext) {
9118
9095
  buf += String.fromCharCode(c);
9119
9096
  }
9120
9097
  const out = btoa(buf).replace(/=+$/, '');
9121
- output(18 /* TypeIds.Uint8Array */, out);
9098
+ output(19 /* TypeIds.Uint8Array */, out);
9122
9099
  }
9123
9100
  else if (value instanceof SerializationWeakRef) {
9124
9101
  const obj = value.$obj$;
@@ -9187,7 +9164,7 @@ async function serialize(serializationContext) {
9187
9164
  }
9188
9165
  if (lastIdx >= 0) {
9189
9166
  $writer$.write(',');
9190
- $writer$.write(13 /* TypeIds.ForwardRefs */ + ',');
9167
+ $writer$.write(14 /* TypeIds.ForwardRefs */ + ',');
9191
9168
  const out = lastIdx === forwardRefs.length - 1 ? forwardRefs : forwardRefs.slice(0, lastIdx + 1);
9192
9169
  // We could also implement RLE of -1 values
9193
9170
  outputArray(out, true, (value) => {
@@ -9787,7 +9764,7 @@ function setEvent(serializationCtx, key, rawValue) {
9787
9764
  let value = null;
9788
9765
  const qrls = rawValue;
9789
9766
  const appendToValue = (valueToAppend) => {
9790
- value = (value == null ? '' : value + '\n') + valueToAppend;
9767
+ value = (value == null ? '' : value + '|') + valueToAppend;
9791
9768
  };
9792
9769
  const getQrlString = (qrl) => {
9793
9770
  /**
@@ -9796,8 +9773,8 @@ function setEvent(serializationCtx, key, rawValue) {
9796
9773
  *
9797
9774
  * For internal qrls (starting with `_`) we assume that they do the right thing.
9798
9775
  */
9799
- if (!qrl.$symbol$.startsWith('_') && qrl.$captureRef$?.length) {
9800
- qrl = createQRL(null, '_run', _run, null, null, [qrl]);
9776
+ if (!qrl.$symbol$.startsWith('_') && qrl.$captures$?.length) {
9777
+ qrl = createQRL(null, '_run', _run, null, [qrl]);
9801
9778
  }
9802
9779
  return qrlToString(serializationCtx, qrl);
9803
9780
  };
@@ -9824,19 +9801,17 @@ function setEvent(serializationCtx, key, rawValue) {
9824
9801
  return value;
9825
9802
  }
9826
9803
  function addQwikEventToSerializationContext(serializationCtx, key, qrl) {
9827
- // TODO extract window/document too so qwikloader can precisely listen
9828
9804
  const data = getEventDataFromHtmlAttribute(key);
9829
9805
  if (data) {
9830
9806
  const [scope, eventName] = data;
9831
9807
  const scopedEvent = getScopedEventName(scope, eventName);
9832
- const loaderScopedEvent = getLoaderScopedEventName(scope, scopedEvent);
9833
- serializationCtx.$eventNames$.add(loaderScopedEvent);
9808
+ serializationCtx.$eventNames$.add(scopedEvent);
9834
9809
  serializationCtx.$eventQrls$.add(qrl);
9835
9810
  }
9836
9811
  }
9837
9812
  function addPreventDefaultEventToSerializationContext(serializationCtx, key) {
9838
- // skip first 15 chars, this is length of the `preventdefault`, leave the ":"
9839
- const eventName = key.substring(14);
9813
+ // skip the `preventdefault`, leave the ':'
9814
+ const eventName = 'e' + key.substring(14);
9840
9815
  if (eventName) {
9841
9816
  serializationCtx.$eventNames$.add(eventName);
9842
9817
  }
@@ -9867,6 +9842,27 @@ function appendClassIfScopedStyleExists(jsx, styleScoped) {
9867
9842
  }
9868
9843
  }
9869
9844
 
9845
+ // <docs markdown="../readme.md#useLexicalScope">
9846
+ // !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
9847
+ // (edit ../readme.md#useLexicalScope instead and run `pnpm docs.sync`)
9848
+ /**
9849
+ * Used by the Qwik Optimizer to restore the lexically scoped variables.
9850
+ *
9851
+ * This method should not be present in the application source code.
9852
+ *
9853
+ * NOTE: `useLexicalScope` method can only be used in the synchronous portion of the callback
9854
+ * (before any `await` statements.)
9855
+ *
9856
+ * @deprecated Read from `_captures` directly instead.
9857
+ * @internal
9858
+ */
9859
+ // </docs>
9860
+ const useLexicalScope = () => {
9861
+ isDev && assertDefined(_captures, 'invoke: captures must be defined for useLexicalScope()');
9862
+ return _captures;
9863
+ };
9864
+
9865
+ let loading = Promise.resolve();
9870
9866
  const inflate = (container, target, typeId, data) => {
9871
9867
  if (typeId === 0 /* TypeIds.Plain */) {
9872
9868
  // Already processed
@@ -9892,14 +9888,7 @@ const inflate = (container, target, typeId, data) => {
9892
9888
  target[key] = value;
9893
9889
  }
9894
9890
  break;
9895
- case 19 /* TypeIds.QRL */:
9896
- case 20 /* TypeIds.PreloadQRL */:
9897
- _inflateQRL(container, target);
9898
- if (typeId === 20 /* TypeIds.PreloadQRL */) {
9899
- target.resolve();
9900
- }
9901
- break;
9902
- case 21 /* TypeIds.Task */:
9891
+ case 20 /* TypeIds.Task */:
9903
9892
  const task = target;
9904
9893
  const v = data;
9905
9894
  task.$qrl$ = v[0];
@@ -9909,7 +9898,7 @@ const inflate = (container, target, typeId, data) => {
9909
9898
  task[_EFFECT_BACK_REF] = v[4];
9910
9899
  task.$state$ = v[5];
9911
9900
  break;
9912
- case 22 /* TypeIds.Resource */:
9901
+ case 21 /* TypeIds.Resource */:
9913
9902
  const [resolved, result, effects] = data;
9914
9903
  const resource = target;
9915
9904
  if (resolved) {
@@ -9924,10 +9913,10 @@ const inflate = (container, target, typeId, data) => {
9924
9913
  }
9925
9914
  getStoreHandler(target).$effects$ = effects;
9926
9915
  break;
9927
- case 23 /* TypeIds.Component */:
9916
+ case 22 /* TypeIds.Component */:
9928
9917
  target[SERIALIZABLE_STATE][0] = data[0];
9929
9918
  break;
9930
- case 29 /* TypeIds.Store */: {
9919
+ case 28 /* TypeIds.Store */: {
9931
9920
  // Inflate the store target
9932
9921
  const store = unwrapStore(target);
9933
9922
  const storeTarget = pendingStoreTargets.get(store);
@@ -9945,14 +9934,14 @@ const inflate = (container, target, typeId, data) => {
9945
9934
  storeHandler.$effects$ = effects;
9946
9935
  break;
9947
9936
  }
9948
- case 24 /* TypeIds.Signal */: {
9937
+ case 23 /* TypeIds.Signal */: {
9949
9938
  const signal = target;
9950
9939
  const d = data;
9951
9940
  signal.$untrackedValue$ = d[0];
9952
9941
  signal.$effects$ = new Set(d.slice(1));
9953
9942
  break;
9954
9943
  }
9955
- case 25 /* TypeIds.WrappedSignal */: {
9944
+ case 24 /* TypeIds.WrappedSignal */: {
9956
9945
  const signal = target;
9957
9946
  const d = data;
9958
9947
  signal.$func$ = container.getSyncFn(d[0]);
@@ -9966,30 +9955,39 @@ const inflate = (container, target, typeId, data) => {
9966
9955
  inflateWrappedSignalValue(signal);
9967
9956
  break;
9968
9957
  }
9969
- case 27 /* TypeIds.AsyncComputedSignal */: {
9970
- const asyncComputed = target;
9958
+ case 26 /* TypeIds.AsyncSignal */: {
9959
+ const asyncSignal = target;
9971
9960
  const d = data;
9972
- asyncComputed.$computeQrl$ = d[0];
9973
- asyncComputed[_EFFECT_BACK_REF] = d[1];
9974
- asyncComputed.$effects$ = new Set(d[2]);
9975
- asyncComputed.$loadingEffects$ = new Set(d[3]);
9976
- asyncComputed.$errorEffects$ = new Set(d[4]);
9977
- asyncComputed.$untrackedLoading$ = d[5];
9978
- asyncComputed.$untrackedError$ = d[6];
9961
+ asyncSignal.$computeQrl$ = d[0];
9962
+ asyncSignal[_EFFECT_BACK_REF] = d[1];
9963
+ asyncSignal.$effects$ = new Set(d[2]);
9964
+ asyncSignal.$loadingEffects$ = new Set(d[3]);
9965
+ asyncSignal.$errorEffects$ = new Set(d[4]);
9966
+ asyncSignal.$untrackedLoading$ = d[5];
9967
+ asyncSignal.$untrackedError$ = d[6];
9979
9968
  const hasValue = d.length > 7;
9980
9969
  if (hasValue) {
9981
- asyncComputed.$untrackedValue$ = d[7];
9982
- asyncComputed.$promiseValue$ = d[7];
9970
+ asyncSignal.$untrackedValue$ = d[7];
9971
+ asyncSignal.$promiseValue$ = d[7];
9983
9972
  }
9984
- asyncComputed.$flags$ |= 1 /* SignalFlags.INVALID */;
9973
+ asyncSignal.$flags$ |= 1 /* SignalFlags.INVALID */;
9985
9974
  break;
9986
9975
  }
9987
9976
  // Inflating a SerializerSignal is the same as inflating a ComputedSignal
9988
- case 28 /* TypeIds.SerializerSignal */:
9989
- case 26 /* TypeIds.ComputedSignal */: {
9977
+ case 27 /* TypeIds.SerializerSignal */:
9978
+ case 25 /* TypeIds.ComputedSignal */: {
9990
9979
  const computed = target;
9991
9980
  const d = data;
9992
9981
  computed.$computeQrl$ = d[0];
9982
+ /**
9983
+ * If we try to compute value and the qrl is not resolved, then system throws an error with
9984
+ * the resolve promise. To prevent that we load it now and qrls wait for the loading to
9985
+ * finish.
9986
+ */
9987
+ const p = computed.$computeQrl$.resolve(container).catch(() => {
9988
+ // ignore preload errors
9989
+ });
9990
+ loading = loading.finally(() => p);
9993
9991
  computed[_EFFECT_BACK_REF] = d[1];
9994
9992
  if (d[2]) {
9995
9993
  computed.$effects$ = new Set(d[2]);
@@ -9998,24 +9996,16 @@ const inflate = (container, target, typeId, data) => {
9998
9996
  if (hasValue) {
9999
9997
  computed.$untrackedValue$ = d[3];
10000
9998
  // The serialized signal is always invalid so it can recreate the custom object
10001
- if (typeId === 28 /* TypeIds.SerializerSignal */) {
9999
+ if (typeId === 27 /* TypeIds.SerializerSignal */) {
10002
10000
  computed.$flags$ |= 1 /* SignalFlags.INVALID */;
10003
10001
  }
10004
10002
  }
10005
10003
  else {
10006
10004
  computed.$flags$ |= 1 /* SignalFlags.INVALID */;
10007
- /**
10008
- * If we try to compute value and the qrl is not resolved, then system throws an error with
10009
- * qrl promise. To prevent that we should early resolve computed qrl while computed
10010
- * deserialization. This also prevents anything from firing while computed qrls load,
10011
- * because of scheduler
10012
- */
10013
- // try to download qrl in this tick
10014
- computed.$computeQrl$.resolve();
10015
10005
  }
10016
10006
  break;
10017
10007
  }
10018
- case 14 /* TypeIds.Error */: {
10008
+ case 15 /* TypeIds.Error */: {
10019
10009
  const d = data;
10020
10010
  target.message = d[0];
10021
10011
  for (let i = 1; i < d.length; i += 2) {
@@ -10023,7 +10013,7 @@ const inflate = (container, target, typeId, data) => {
10023
10013
  }
10024
10014
  break;
10025
10015
  }
10026
- case 30 /* TypeIds.FormData */: {
10016
+ case 29 /* TypeIds.FormData */: {
10027
10017
  const formData = target;
10028
10018
  const d = data;
10029
10019
  for (let i = 0; i < d.length; i++) {
@@ -10031,7 +10021,7 @@ const inflate = (container, target, typeId, data) => {
10031
10021
  }
10032
10022
  break;
10033
10023
  }
10034
- case 31 /* TypeIds.JSXNode */: {
10024
+ case 30 /* TypeIds.JSXNode */: {
10035
10025
  const jsx = target;
10036
10026
  const [type, key, varProps, constProps, children, toSort] = data;
10037
10027
  jsx.type = type;
@@ -10042,7 +10032,7 @@ const inflate = (container, target, typeId, data) => {
10042
10032
  jsx.toSort = !!toSort;
10043
10033
  break;
10044
10034
  }
10045
- case 16 /* TypeIds.Set */: {
10035
+ case 17 /* TypeIds.Set */: {
10046
10036
  const set = target;
10047
10037
  const d = data;
10048
10038
  for (let i = 0; i < d.length; i++) {
@@ -10050,7 +10040,7 @@ const inflate = (container, target, typeId, data) => {
10050
10040
  }
10051
10041
  break;
10052
10042
  }
10053
- case 17 /* TypeIds.Map */: {
10043
+ case 18 /* TypeIds.Map */: {
10054
10044
  const map = target;
10055
10045
  const d = data;
10056
10046
  for (let i = 0; i < d.length; i++) {
@@ -10058,7 +10048,7 @@ const inflate = (container, target, typeId, data) => {
10058
10048
  }
10059
10049
  break;
10060
10050
  }
10061
- case 15 /* TypeIds.Promise */: {
10051
+ case 16 /* TypeIds.Promise */: {
10062
10052
  const promise = target;
10063
10053
  const [resolved, result] = data;
10064
10054
  const [resolve, reject] = resolvers.get(promise);
@@ -10070,7 +10060,7 @@ const inflate = (container, target, typeId, data) => {
10070
10060
  }
10071
10061
  break;
10072
10062
  }
10073
- case 18 /* TypeIds.Uint8Array */:
10063
+ case 19 /* TypeIds.Uint8Array */:
10074
10064
  const bytes = target;
10075
10065
  const buf = atob(data);
10076
10066
  let i = 0;
@@ -10078,7 +10068,7 @@ const inflate = (container, target, typeId, data) => {
10078
10068
  bytes[i++] = s.charCodeAt(0);
10079
10069
  }
10080
10070
  break;
10081
- case 32 /* TypeIds.PropsProxy */:
10071
+ case 31 /* TypeIds.PropsProxy */:
10082
10072
  const propsProxy = target;
10083
10073
  const d = data;
10084
10074
  let owner = d[0];
@@ -10089,13 +10079,13 @@ const inflate = (container, target, typeId, data) => {
10089
10079
  propsProxy[_OWNER] = owner;
10090
10080
  propsProxy[_PROPS_HANDLER].$effects$ = d[3];
10091
10081
  break;
10092
- case 33 /* TypeIds.SubscriptionData */: {
10082
+ case 32 /* TypeIds.SubscriptionData */: {
10093
10083
  const effectData = target;
10094
10084
  effectData.data.$scopedStyleIdPrefix$ = data[0];
10095
10085
  effectData.data.$isConst$ = data[1];
10096
10086
  break;
10097
10087
  }
10098
- case 34 /* TypeIds.EffectSubscription */: {
10088
+ case 33 /* TypeIds.EffectSubscription */: {
10099
10089
  const effectSub = target;
10100
10090
  const d = data;
10101
10091
  effectSub.consumer = d[0];
@@ -10117,20 +10107,6 @@ const _eagerDeserializeArray = (container, data, output = Array(data.length / 2)
10117
10107
  }
10118
10108
  return output;
10119
10109
  };
10120
- function _inflateQRL(container, qrl) {
10121
- if (qrl.$captureRef$) {
10122
- // early return if capture references are already set and qrl is already inflated
10123
- return qrl;
10124
- }
10125
- const captureIds = qrl.$capture$;
10126
- qrl.$captureRef$ = captureIds ? captureIds.map((id) => container.$getObjectById$(id)) : null;
10127
- // clear serialized capture references
10128
- qrl.$capture$ = null;
10129
- if (container.element) {
10130
- qrl.$setContainer$(container.element);
10131
- }
10132
- return qrl;
10133
- }
10134
10110
  function deserializeData(container, typeId, value) {
10135
10111
  if (typeId === 0 /* TypeIds.Plain */) {
10136
10112
  return value;
@@ -10174,7 +10150,7 @@ function inflateWrappedSignalValue(signal) {
10174
10150
  }
10175
10151
 
10176
10152
  /** Arrays/Objects are special-cased so their identifiers is a single digit. */
10177
- const needsInflation = (typeId) => typeId >= 14 /* TypeIds.Error */ || typeId === 4 /* TypeIds.Array */ || typeId === 5 /* TypeIds.Object */;
10153
+ const needsInflation = (typeId) => typeId >= 15 /* TypeIds.Error */ || typeId === 4 /* TypeIds.Array */ || typeId === 5 /* TypeIds.Object */;
10178
10154
  const deserializedProxyMap = new WeakMap();
10179
10155
  const isDeserializerProxy = (value) => {
10180
10156
  return isObject(value) && SERIALIZER_PROXY_UNWRAP in value;
@@ -10664,8 +10640,10 @@ class DomContainer extends _SharedContainer {
10664
10640
  $setRawState$(id, vParent) {
10665
10641
  this.$stateData$[id] = vParent;
10666
10642
  }
10667
- parseQRL(qrl) {
10668
- return _inflateQRL(this, parseQRL(qrl));
10643
+ parseQRL(qrlStr) {
10644
+ const qrl = parseQRL(qrlStr);
10645
+ qrl.$container$ = this;
10646
+ return qrl;
10669
10647
  }
10670
10648
  handleError(err, host) {
10671
10649
  if (qDev && host) {
@@ -10884,16 +10862,20 @@ const isTask = (value) => {
10884
10862
  return value instanceof Task;
10885
10863
  };
10886
10864
  /**
10887
- * Used internally as a qrl event handler to schedule a task.
10865
+ * Used internally as a qwikloader event handler to schedule a task. The `this` context is the
10866
+ * captures part of the QRL, provided by qwikloader.
10888
10867
  *
10889
10868
  * @internal
10890
10869
  */
10891
- const scheduleTask = (_event, element) => {
10892
- const [task] = useLexicalScope();
10870
+ function scheduleTask(_event, element) {
10893
10871
  const container = getDomContainer(element);
10872
+ if (typeof this === 'string') {
10873
+ setCaptures(deserializeCaptures(container, this));
10874
+ }
10875
+ const task = _captures[0];
10894
10876
  task.$flags$ |= 8 /* TaskFlags.DIRTY */;
10895
10877
  markVNodeDirty(container, task.$el$, 1 /* ChoreBits.TASKS */);
10896
- };
10878
+ }
10897
10879
 
10898
10880
  const throwIfQRLNotResolved = (qrl) => {
10899
10881
  const resolved = qrl.resolved;
@@ -11002,10 +10984,10 @@ const getComputedSignalFlags = (serializationStrategy) => {
11002
10984
  // flags |= ComputedSignalFlags.SERIALIZATION_STRATEGY_AUTO;
11003
10985
  // break;
11004
10986
  case 'never':
11005
- flags |= 16 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_NEVER */;
10987
+ flags |= 8 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_NEVER */;
11006
10988
  break;
11007
10989
  case 'always':
11008
- flags |= 32 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_ALWAYS */;
10990
+ flags |= 16 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_ALWAYS */;
11009
10991
  break;
11010
10992
  }
11011
10993
  return flags;
@@ -11356,6 +11338,7 @@ function getEffects(target, prop, storeEffects) {
11356
11338
  return effectsToTrigger;
11357
11339
  }
11358
11340
 
11341
+ const getKeyVal = (value, key) => value[key];
11359
11342
  const canSerialize = (value, seen = new WeakSet()) => {
11360
11343
  if (value == null ||
11361
11344
  typeof value === 'string' ||
@@ -11377,7 +11360,7 @@ const canSerialize = (value, seen = new WeakSet()) => {
11377
11360
  for (const key in value) {
11378
11361
  // if the value is a props proxy, then sometimes we could create a component-level subscription,
11379
11362
  // so we should call untrack here to avoid tracking the value
11380
- if (!canSerialize(untrack(() => value[key]), seen)) {
11363
+ if (!canSerialize(untrack(getKeyVal, value, key), seen)) {
11381
11364
  return false;
11382
11365
  }
11383
11366
  }
@@ -11504,7 +11487,7 @@ const _dumpState = (state, color = false, prefix = '', limit = 20) => {
11504
11487
  value = value.slice(0, 120) + '"...';
11505
11488
  }
11506
11489
  }
11507
- else if (key === 13 /* TypeIds.ForwardRefs */) {
11490
+ else if (key === 14 /* TypeIds.ForwardRefs */) {
11508
11491
  value = '[' + `\n${prefix} ${value.join(`\n${prefix} `)}\n${prefix}]`;
11509
11492
  }
11510
11493
  else if (Array.isArray(value)) {
@@ -11580,10 +11563,7 @@ function preprocessState(data, container) {
11580
11563
  return type === 1 /* TypeIds.RootRef */ && typeof value === 'string';
11581
11564
  };
11582
11565
  const isForwardRefsMap = (type) => {
11583
- return type === 13 /* TypeIds.ForwardRefs */;
11584
- };
11585
- const isPreloadQrlType = (type) => {
11586
- return type === 20 /* TypeIds.PreloadQRL */;
11566
+ return type === 14 /* TypeIds.ForwardRefs */;
11587
11567
  };
11588
11568
  const processRootRef = (index) => {
11589
11569
  const rootRefPath = data[index + 1].split(' ');
@@ -11612,7 +11592,6 @@ function preprocessState(data, container) {
11612
11592
  data[index] = objectType;
11613
11593
  data[index + 1] = object;
11614
11594
  };
11615
- const toPreload = isServer ? undefined : [];
11616
11595
  for (let i = 0; i < data.length; i += 2) {
11617
11596
  if (isRootDeepRef(data[i], data[i + 1])) {
11618
11597
  processRootRef(i);
@@ -11620,45 +11599,6 @@ function preprocessState(data, container) {
11620
11599
  else if (isForwardRefsMap(data[i])) {
11621
11600
  container.$forwardRefs$ = data[i + 1];
11622
11601
  }
11623
- else if (!isServer && isPreloadQrlType(data[i])) {
11624
- // preload QRLs are always serialized as strings with chunk and symbol ids
11625
- const qrl = data[i + 1];
11626
- const chunkIdx = Number(qrl.split(' ')[0]);
11627
- toPreload.push(chunkIdx);
11628
- }
11629
- }
11630
- /**
11631
- * Preloads QRLs that are defined in the state data as `PreloadQRL`.
11632
- *
11633
- * This is done because when computed and custom serializer QRLs are called they need QRL to work.
11634
- * If the QRL is not resolved at this point, it will be resolved by throwing a promise and
11635
- * rerunning the whole wrapping function again. We want to avoid that, because it means that the
11636
- * function can execute twice.
11637
- *
11638
- * ```ts
11639
- * useVisibleTask$(() => {
11640
- * runHeavyLogic(); // This will be called again if the QRL of `computedOrCustomSerializer` is not resolved.
11641
- * console.log(computedOrCustomSerializer.value); // Throw a promise if QRL not resolved and execute visible task again.
11642
- * });
11643
- * ```
11644
- */
11645
- if (!isServer) {
11646
- for (const idx of toPreload) {
11647
- // we preload the chunk instead of the symbol so it also works in dev
11648
- const chunkType = data[idx * 2];
11649
- let chunk;
11650
- if (chunkType === 0 /* TypeIds.Plain */) {
11651
- chunk = data[idx * 2 + 1];
11652
- }
11653
- else if (chunkType === 1 /* TypeIds.RootRef */) {
11654
- const refIdx = data[idx * 2 + 1];
11655
- chunk = data[refIdx * 2 + 1];
11656
- }
11657
- else {
11658
- continue;
11659
- }
11660
- p(chunk, 0.3);
11661
- }
11662
11602
  }
11663
11603
  }
11664
11604
 
@@ -11680,10 +11620,9 @@ async function _serialize(data) {
11680
11620
  * Deserialize data from string to an array of objects.
11681
11621
  *
11682
11622
  * @param rawStateData - Data to deserialize
11683
- * @param element - Container element
11684
11623
  * @internal
11685
11624
  */
11686
- function _deserialize(rawStateData, element) {
11625
+ function _deserialize(rawStateData) {
11687
11626
  if (rawStateData == null) {
11688
11627
  return [];
11689
11628
  }
@@ -11691,13 +11630,7 @@ function _deserialize(rawStateData, element) {
11691
11630
  if (!Array.isArray(stateData)) {
11692
11631
  return [];
11693
11632
  }
11694
- let container;
11695
- if (isNode(element) && isElement$1(element)) {
11696
- container = _createDeserializeContainer(stateData, element);
11697
- }
11698
- else {
11699
- container = _createDeserializeContainer(stateData);
11700
- }
11633
+ const container = _createDeserializeContainer(stateData);
11701
11634
  const output = [];
11702
11635
  for (let i = 0; i < stateData.length; i += 2) {
11703
11636
  output[i / 2] = deserializeData(container, stateData[i], stateData[i + 1]);
@@ -11707,11 +11640,13 @@ function _deserialize(rawStateData, element) {
11707
11640
  function getObjectById(id, stateData) {
11708
11641
  if (typeof id === 'string') {
11709
11642
  id = parseInt(id, 10);
11643
+ // This return statement is needed to prevent the function from turning megamorphic
11644
+ return stateData[id];
11710
11645
  }
11711
11646
  isDev && assertTrue(id < stateData.length, `Invalid reference ${id} >= ${stateData.length}`);
11712
11647
  return stateData[id];
11713
11648
  }
11714
- function _createDeserializeContainer(stateData, element) {
11649
+ function _createDeserializeContainer(stateData) {
11715
11650
  // eslint-disable-next-line prefer-const
11716
11651
  let state;
11717
11652
  const container = {
@@ -11727,16 +11662,13 @@ function _createDeserializeContainer(stateData, element) {
11727
11662
  preprocessState(stateData, container);
11728
11663
  state = wrapDeserializerProxy(container, stateData);
11729
11664
  container.$state$ = state;
11730
- if (element) {
11731
- container.element = element;
11732
- }
11733
11665
  return container;
11734
11666
  }
11735
11667
 
11736
11668
  /** @internal */
11737
11669
  const verifySerializable = (value, preMessage) => {
11738
11670
  const seen = new WeakSet();
11739
- return untrack(() => _verifySerializable(value, seen, '_', preMessage));
11671
+ return untrack(_verifySerializable, value, seen, '_', preMessage);
11740
11672
  };
11741
11673
  const _verifySerializable = (value, seen, ctx, preMessage) => {
11742
11674
  const unwrapped = unwrapStore(value);
@@ -11871,173 +11803,202 @@ const NoSerializeSymbol = Symbol('noSerialize');
11871
11803
  const SerializerSymbol = Symbol('serialize');
11872
11804
 
11873
11805
  // keep these imports above the rest to prevent circular dep issues
11874
- const resolvedSymbol = Symbol('resolved');
11875
- const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef) => {
11876
- if (qDev && qSerialize) {
11877
- if (captureRef) {
11878
- for (const item of captureRef) {
11879
- verifySerializable(item, 'Captured variable in the closure can not be serialized');
11880
- }
11806
+ /**
11807
+ * The current captured scope during QRL invocation. This is used to provide the lexical scope for
11808
+ * QRL functions. It is used one time per invocation, synchronously, so it is safe to store it in
11809
+ * module scope.
11810
+ *
11811
+ * @internal
11812
+ */
11813
+ let _captures = null;
11814
+ const setCaptures = (captures) => {
11815
+ _captures = captures;
11816
+ };
11817
+ const deserializeCaptures = (container, captures) => {
11818
+ const refs = [];
11819
+ for (const id of captures.split(' ')) {
11820
+ refs.push(container.$getObjectById$(id));
11821
+ }
11822
+ return refs;
11823
+ };
11824
+ /** Puts the qrl captures into `_captures`, and returns a Promise that should be awaited if possible */
11825
+ const ensureQrlCaptures = (qrl) => {
11826
+ // We read the captures once, synchronously, so no need to keep previous
11827
+ _captures = qrl.$captures$;
11828
+ if (typeof _captures === 'string') {
11829
+ if (!qrl.$container$) {
11830
+ throw qError(13 /* QError.qrlMissingContainer */);
11831
+ }
11832
+ const prevLoading = loading;
11833
+ _captures = qrl.$captures$ = deserializeCaptures(qrl.$container$, _captures);
11834
+ if (loading !== prevLoading) {
11835
+ // return the loading promise so callers can await it
11836
+ return loading;
11881
11837
  }
11882
11838
  }
11883
- let _containerEl;
11884
- const qrl = async function (...args) {
11885
- const boundedFn = bindFnToContext.call(this, tryGetInvokeContext());
11886
- const result = await boundedFn(...args);
11887
- return result;
11888
- };
11889
- const setContainer = (el) => {
11890
- if (!_containerEl) {
11891
- _containerEl = el;
11839
+ };
11840
+ function bindFnToContext(qrl, currentCtx, beforeFn) {
11841
+ // Note that we bind the current `this`
11842
+ const bound = (...args) => {
11843
+ if (!qrl.resolved) {
11844
+ return qrl.resolve().then((fn) => {
11845
+ if (!isFunction(fn)) {
11846
+ throw qError(5 /* QError.qrlIsNotFunction */);
11847
+ }
11848
+ return bound(...args);
11849
+ });
11892
11850
  }
11893
- return _containerEl;
11851
+ if (beforeFn && beforeFn() === false) {
11852
+ return;
11853
+ }
11854
+ return invokeApply.call(this, currentCtx, qrl.resolved, args);
11894
11855
  };
11895
- function bindFnToContext(currentCtx, beforeFn) {
11896
- // Note that we bind the current `this`
11897
- const bound = (...args) => {
11898
- if (!qrl.resolved) {
11899
- return qrl.resolve().then((fn) => {
11900
- if (!isFunction(fn)) {
11901
- throw qError(5 /* QError.qrlIsNotFunction */);
11902
- }
11903
- return bound(...args);
11904
- });
11905
- }
11906
- if (beforeFn && beforeFn() === false) {
11907
- return;
11908
- }
11909
- const context = createOrReuseInvocationContext(currentCtx);
11910
- const prevQrl = context.$qrl$;
11911
- const prevEvent = context.$event$;
11912
- // Note that we set the qrl here instead of in wrapFn because
11913
- // it is possible we're called on a copied qrl
11914
- context.$qrl$ = qrl;
11915
- context.$event$ ||= this;
11916
- try {
11917
- return invoke.call(this, context, symbolRef, ...args);
11918
- }
11919
- finally {
11920
- context.$qrl$ = prevQrl;
11921
- context.$event$ = prevEvent;
11922
- }
11923
- };
11924
- return bound;
11856
+ return bound;
11857
+ }
11858
+ // Wrap functions to provide their lexical scope
11859
+ const bindCaptures = (qrl, fn) => {
11860
+ if (typeof fn !== 'function' || !qrl.$captures$) {
11861
+ return fn;
11925
11862
  }
11926
- // Wrap functions to provide their lexical scope
11927
- const wrapFn = (fn) => {
11928
- if (typeof fn !== 'function' || (!capture?.length && !captureRef?.length)) {
11929
- return fn;
11930
- }
11931
- return function (...args) {
11932
- let context = tryGetInvokeContext();
11933
- // use the given qrl if it is the right one
11934
- if (context) {
11935
- // TODO check if this is necessary in production
11936
- if (context.$qrl$?.$symbol$ === qrl.$symbol$) {
11937
- return fn.apply(this, args);
11938
- }
11939
- const prevQrl = context.$qrl$;
11940
- context.$qrl$ = qrl;
11941
- try {
11942
- return fn.apply(this, args);
11943
- }
11944
- finally {
11945
- context.$qrl$ = prevQrl;
11946
- }
11947
- }
11948
- context = newInvokeContext();
11949
- context.$qrl$ = qrl;
11950
- context.$event$ = this;
11951
- return invoke.call(this, context, fn, ...args);
11952
- };
11863
+ return function withCaptures(...args) {
11864
+ ensureQrlCaptures(qrl);
11865
+ return fn.apply(this, args);
11953
11866
  };
11954
- // Retrieve memoized result from symbolFn
11955
- if (symbolFn && resolvedSymbol in symbolFn) {
11956
- symbolRef = symbolFn[resolvedSymbol];
11957
- }
11958
- const resolve = symbolRef
11959
- ? async () => symbolRef
11960
- : async (containerEl) => {
11961
- if (symbolRef !== null) {
11962
- // Resolving (Promise) or already resolved (value)
11963
- return symbolRef;
11964
- }
11965
- if (containerEl) {
11966
- setContainer(containerEl);
11967
- }
11968
- if (chunk === '') {
11969
- // Sync QRL
11970
- isDev && assertDefined(_containerEl, 'Sync QRL must have container element');
11971
- const hash = _containerEl.getAttribute(QInstanceAttr);
11972
- const doc = _containerEl.ownerDocument;
11973
- const qFuncs = getQFuncs(doc, hash);
11974
- // No need to wrap, syncQRLs can't have captured scope
11975
- return (qrl.resolved = symbolRef = qFuncs[Number(symbol)]);
11976
- }
11977
- if (isBrowser && chunk) {
11978
- /** We run the QRL, so now the probability of the chunk is 100% */
11979
- p(chunk, 1);
11980
- }
11981
- const start = now();
11982
- const ctx = tryGetInvokeContext();
11983
- if (symbolFn !== null) {
11984
- symbolRef = symbolFn().then((module) => {
11985
- const resolved = wrapFn((symbolRef = module[symbol]));
11986
- // We memoize the result on the symbolFn
11987
- symbolFn[resolvedSymbol] = resolved;
11988
- qrl.resolved = resolved;
11989
- return resolved;
11990
- });
11991
- }
11992
- else {
11993
- // TODO cache the imported symbol but watch out for dev mode
11994
- const imported = getPlatform().importSymbol(_containerEl, chunk, symbol);
11995
- symbolRef = maybeThen(imported, (ref) => (qrl.resolved = wrapFn((symbolRef = ref))));
11996
- }
11997
- if (isPromise(symbolRef)) {
11998
- symbolRef.then(() => emitUsedSymbol(symbol, ctx?.$hostElement$ instanceof ElementVNode ? ctx?.$hostElement$.node : undefined, start), (err) => {
11999
- console.error(`qrl ${symbol} failed to load`, err);
12000
- // We shouldn't cache rejections, we can try again later
12001
- symbolRef = null;
12002
- });
12003
- }
11867
+ };
11868
+ const makeResolveFunction = (qrl, symbolFn) => {
11869
+ let symbolRef;
11870
+ // Always return a promise, even for sync QRLs
11871
+ return async (container) => {
11872
+ if (symbolRef != null) {
11873
+ // Resolving (Promise) or already resolved (value)
12004
11874
  return symbolRef;
12005
- };
12006
- const createOrReuseInvocationContext = (invoke) => {
12007
- if (invoke == null) {
12008
- return newInvokeContext();
12009
11875
  }
12010
- else if (isArray(invoke)) {
12011
- return newInvokeContextFromTuple(invoke);
11876
+ if (container) {
11877
+ qrl.$container$ = container;
12012
11878
  }
12013
- else {
12014
- return invoke;
11879
+ else if (!qrl.$container$) {
11880
+ const ctx = tryGetInvokeContext();
11881
+ if (ctx?.$container$) {
11882
+ qrl.$container$ = ctx.$container$;
11883
+ }
11884
+ }
11885
+ if (qrl.$chunk$ === '') {
11886
+ // Sync QRL
11887
+ isDev && assertDefined(qrl.$container$, 'Sync QRL must have container element');
11888
+ const hash = qrl.$container$.$instanceHash$;
11889
+ const doc = qrl.$container$.element?.ownerDocument || document;
11890
+ const qFuncs = getQFuncs(doc, hash);
11891
+ // No need to wrap, syncQRLs can't have captured scope
11892
+ return (qrl.resolved = symbolRef = qFuncs[Number(qrl.$symbol$)]);
11893
+ }
11894
+ if (isBrowser && qrl.$chunk$) {
11895
+ /** We run the QRL, so now the probability of the chunk is 100% */
11896
+ p(qrl.$chunk$, 1);
11897
+ }
11898
+ const start = now();
11899
+ const symbol = qrl.$symbol$;
11900
+ const importP = symbolFn
11901
+ ? symbolFn().then((module) => module[symbol])
11902
+ : getPlatform().importSymbol(qrl.$container$?.element, qrl.$chunk$, symbol);
11903
+ symbolRef = maybeThen(importP, (resolved) => {
11904
+ // We memoize the result on the symbolFn
11905
+ // Make sure not to memoize the wrapped function!
11906
+ if (symbolFn) {
11907
+ symbolFn[symbol] = resolved;
11908
+ }
11909
+ return (symbolRef = qrl.resolved = bindCaptures(qrl, resolved));
11910
+ });
11911
+ if (isPromise(symbolRef)) {
11912
+ const ctx = tryGetInvokeContext();
11913
+ symbolRef.then(() => emitUsedSymbol(symbol, ctx?.$hostElement$ instanceof ElementVNode ? ctx?.$hostElement$.node : undefined, start), (err) => {
11914
+ console.error(`qrl ${symbol} failed to load`, err);
11915
+ // We shouldn't cache rejections, we can try again later
11916
+ symbolRef = null;
11917
+ });
11918
+ }
11919
+ // Try to deserialize captures if any
11920
+ if (qrl.$container$) {
11921
+ await ensureQrlCaptures(qrl);
11922
+ }
11923
+ return symbolRef;
11924
+ };
11925
+ };
11926
+ function getSymbol() {
11927
+ return this.$symbol$;
11928
+ }
11929
+ function getHash() {
11930
+ return this.$hash$;
11931
+ }
11932
+ function getCaptured() {
11933
+ ensureQrlCaptures(this);
11934
+ return this.$captures$;
11935
+ }
11936
+ /**
11937
+ * Creates a QRL instance to represent a lazily loaded value. Normally this is a function, but it
11938
+ * can be any value.
11939
+ *
11940
+ * When the value is a function, calling the returned qrl will load the underlying code when
11941
+ * invoked, and call it with the captured scope. This always returns a promise since the code may
11942
+ * not be loaded yet.
11943
+ *
11944
+ * To get the underlying function without invoking it, await `qrl.resolve()` and then `qrl.resolved`
11945
+ * holds the loaded function, wrapped with the captured scope.
11946
+ *
11947
+ * @internal
11948
+ */
11949
+ const createQRL = (chunk, symbol, symbolRef, symbolFn, captures) => {
11950
+ // In dev mode we need to preserve the original symbolRef without wrapping
11951
+ const origSymbolRef = symbolRef;
11952
+ if (qDev && qSerialize) {
11953
+ if (captures && typeof captures === 'object') {
11954
+ for (const item of captures) {
11955
+ verifySerializable(item, 'Captured variable in the closure can not be serialized');
11956
+ }
12015
11957
  }
11958
+ }
11959
+ const qrl = async function qrlFn(...args) {
11960
+ if (qrl.resolved) {
11961
+ return qrl.resolved.apply(this, args);
11962
+ }
11963
+ // grab the context while we are sync
11964
+ const ctx = tryGetInvokeContext();
11965
+ await qrl.resolve(ctx?.$container$);
11966
+ return invokeApply.call(this, ctx, qrl.resolved, args);
12016
11967
  };
11968
+ // Retrieve memoized result from symbolFn
11969
+ if (symbolFn && symbol in symbolFn) {
11970
+ symbolRef = symbolFn[symbol];
11971
+ }
11972
+ const resolve = symbolRef != null ? async () => symbolRef : makeResolveFunction(qrl, symbolFn);
12017
11973
  const hash = getSymbolHash(symbol);
12018
11974
  Object.assign(qrl, {
12019
- getSymbol: () => symbol,
12020
- getHash: () => hash,
12021
- // captureRef is replaced during deserialization
12022
- getCaptured: () => qrl.$captureRef$,
11975
+ getSymbol,
11976
+ getHash,
11977
+ getCaptured,
11978
+ // This can be called with other `this`
11979
+ getFn: function (currentCtx, beforeFn) {
11980
+ return bindFnToContext.call(this, qrl, currentCtx, beforeFn);
11981
+ },
12023
11982
  resolve,
12024
- $setContainer$: setContainer,
11983
+ resolved: undefined,
12025
11984
  $chunk$: chunk,
12026
11985
  $symbol$: symbol,
12027
11986
  $hash$: hash,
12028
- getFn: bindFnToContext,
12029
- $capture$: capture,
12030
- $captureRef$: captureRef,
12031
- dev: null,
12032
- resolved: undefined,
11987
+ $captures$: captures,
11988
+ $container$: null,
12033
11989
  });
12034
- if (symbolRef) {
12035
- // Unwrap any promises
12036
- symbolRef = maybeThen(symbolRef, (resolved) => (qrl.resolved = wrapFn((symbolRef = resolved))));
12037
- }
12038
11990
  if (qDev) {
11991
+ qrl.dev = null;
11992
+ qrl.$symbolRef$ = origSymbolRef;
12039
11993
  seal(qrl);
12040
11994
  }
11995
+ // Now that the qrl is fully constructed, we can resolve/wrap the symbolRef if we received it. If it is a plain value without computed captures, the qrl will be resolved immediately.
11996
+ if (symbolRef != null) {
11997
+ symbolRef = maybeThen(ensureQrlCaptures(qrl), () => maybeThen(symbolRef, (resolved) => {
11998
+ symbolRef = qrl.resolved = bindCaptures(qrl, resolved);
11999
+ return symbolRef;
12000
+ }));
12001
+ }
12041
12002
  if (isBrowser && symbol) {
12042
12003
  /**
12043
12004
  * Preloading the symbol instead of the chunk allows us to get probabilities for the bundle
@@ -12159,7 +12120,7 @@ const $ = (expression) => {
12159
12120
  if (!qRuntimeQrl && qDev) {
12160
12121
  throw new Error('Optimizer should replace all usages of $() with some special syntax. If you need to create a QRL manually, use inlinedQrl() instead.');
12161
12122
  }
12162
- return createQRL(null, 's' + runtimeSymbolId++, expression, null, null, null);
12123
+ return createQRL(null, 's' + runtimeSymbolId++, expression, null, null);
12163
12124
  };
12164
12125
  /** @private Use To avoid optimizer replacement */
12165
12126
  const dollar = $;
@@ -12185,7 +12146,7 @@ const sync$ = (fn) => {
12185
12146
  // eslint-disable-next-line no-new-func
12186
12147
  fn = new Function('return ' + fn.toString())();
12187
12148
  }
12188
- return createQRL('', SYNC_QRL, fn, null, null, null);
12149
+ return createQRL('', SYNC_QRL, fn, null, null);
12189
12150
  };
12190
12151
  /**
12191
12152
  * Extract function into a synchronously loadable QRL.
@@ -12202,7 +12163,7 @@ const _qrlSync = function (fn, serializedFn) {
12202
12163
  serializedFn = fn.toString();
12203
12164
  }
12204
12165
  fn.serialized = serializedFn;
12205
- return createQRL('', SYNC_QRL, fn, null, null, null);
12166
+ return createQRL('', SYNC_QRL, fn, null, null);
12206
12167
  };
12207
12168
 
12208
12169
  /** @internal */
@@ -12250,11 +12211,11 @@ const isQwikComponent = (component) => {
12250
12211
  * step?: number;
12251
12212
  * }
12252
12213
  * export const Counter = component$((props: CounterProps) => {
12253
- * const state = useStore({ count: props.initialValue || 0 });
12214
+ * const state = useSignal(props.initialValue || 0);
12254
12215
  * return (
12255
12216
  * <div>
12256
- * <span>{state.count}</span>
12257
- * <button onClick$={() => (state.count += props.step || 1)}>+</button>
12217
+ * <span>{state.value}</span>
12218
+ * <button onClick$={() => (state.value += props.step || 1)}>+</button>
12258
12219
  * </div>
12259
12220
  * );
12260
12221
  * });
@@ -12331,10 +12292,15 @@ const render = async (parent, jsxNode, opts = {}) => {
12331
12292
  // !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
12332
12293
  // (edit ../readme.md#useStore instead and run `pnpm docs.sync`)
12333
12294
  /**
12334
- * Creates an object that Qwik can track across serializations.
12295
+ * Creates a reactive object that Qwik can track across serialization.
12335
12296
  *
12336
- * Use `useStore` to create a state for your application. The returned object is a proxy that has a
12337
- * unique ID. The ID of the object is used in the `QRL`s to refer to the store.
12297
+ * Use it to create state for your application. The returned object is a Proxy that tracks reads and
12298
+ * writes. When any of the properties change, the functions that read those properties will re-run.
12299
+ *
12300
+ * `Store`s are deep by default, meaning that any objects assigned to properties will also become
12301
+ * `Store`s. This includes arrays.
12302
+ *
12303
+ * Prefer `useSignal` over `useStore` when possible, as it is more efficient.
12338
12304
  *
12339
12305
  * ### Example
12340
12306
  *
@@ -12886,7 +12852,7 @@ const _useStyles = (styleQrl, transform, scoped) => {
12886
12852
  */
12887
12853
  // </docs>
12888
12854
  const useOn = (event, eventQrl) => {
12889
- _useOn("on:" /* EventNameHtmlScope.on */, event, eventQrl);
12855
+ _useOn("q-e:" /* EventNameHtmlScope.on */, event, eventQrl);
12890
12856
  };
12891
12857
  // <docs markdown="../readme.md#useOnDocument">
12892
12858
  // !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
@@ -12920,7 +12886,7 @@ const useOn = (event, eventQrl) => {
12920
12886
  */
12921
12887
  // </docs>
12922
12888
  const useOnDocument = (event, eventQrl) => {
12923
- _useOn("on-document:" /* EventNameHtmlScope.document */, event, eventQrl);
12889
+ _useOn("q-d:" /* EventNameHtmlScope.document */, event, eventQrl);
12924
12890
  };
12925
12891
  // <docs markdown="../readme.md#useOnWindow">
12926
12892
  // !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
@@ -12955,7 +12921,7 @@ const useOnDocument = (event, eventQrl) => {
12955
12921
  */
12956
12922
  // </docs>
12957
12923
  const useOnWindow = (event, eventQrl) => {
12958
- _useOn("on-window:" /* EventNameHtmlScope.window */, event, eventQrl);
12924
+ _useOn("q-w:" /* EventNameHtmlScope.window */, event, eventQrl);
12959
12925
  };
12960
12926
  const _useOn = (prefix, eventName, eventQrl) => {
12961
12927
  const { isAdded, addEvent } = useOnEventsSequentialScope();
@@ -13020,50 +12986,99 @@ const useOnEventsSequentialScope = () => {
13020
12986
  };
13021
12987
  };
13022
12988
 
13023
- /** @public */
12989
+ const getSignal = (initialState) => {
12990
+ const value = isFunction(initialState) && !isQwikComponent(initialState)
12991
+ ? invoke(undefined, initialState)
12992
+ : initialState;
12993
+ return createSignal(value);
12994
+ };
12995
+ // <docs markdown="../readme.md#useSignal">
12996
+ // !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
12997
+ // (edit ../readme.md#useSignal instead and run `pnpm docs.sync`)
12998
+ /**
12999
+ * Creates an object with a single reactive `.value` property, that Qwik can track across
13000
+ * serializations.
13001
+ *
13002
+ * Use it to create state for your application. The object has a getter and setter to track reads
13003
+ * and writes of the `.value` property. When the value changes, any functions that read from it will
13004
+ * re-run.
13005
+ *
13006
+ * Prefer `useSignal` over `useStore` when possible, as it is more efficient.
13007
+ *
13008
+ * ### Example
13009
+ *
13010
+ * ```tsx
13011
+ * const Signals = component$(() => {
13012
+ * const counter = useSignal(1);
13013
+ * const text = useSignal('changeme');
13014
+ * const toggle = useSignal(false);
13015
+ *
13016
+ * // useSignal() can also accept a function to calculate the initial value
13017
+ * const state = useSignal(() => {
13018
+ * return expensiveInitialValue();
13019
+ * });
13020
+ *
13021
+ * return (
13022
+ * <div>
13023
+ * <button onClick$={() => counter.value++}>Counter: {counter.value}</button>
13024
+ * {
13025
+ * // pass signal values as the value, the optimizer will make it pass the signal
13026
+ * }
13027
+ * <Child state={state.value} />
13028
+ * {
13029
+ * // signals can be bound to inputs. A property named `bind:x` implies that the property
13030
+ * is a signal
13031
+ * }
13032
+ * <input type="text" bind:value={text} />
13033
+ * <input type="checkbox" bind:checked={toggle} />
13034
+ * </div>
13035
+ * );
13036
+ * });
13037
+ * ```
13038
+ *
13039
+ * @public
13040
+ */
13041
+ // </docs>
13024
13042
  const useSignal = (initialState) => {
13025
- return useConstant(() => {
13026
- const value = isFunction(initialState) && !isQwikComponent(initialState)
13027
- ? invoke(undefined, initialState)
13028
- : initialState;
13029
- return createSignal(value);
13030
- });
13043
+ return useConstant((getSignal), initialState);
13031
13044
  };
13032
13045
  /**
13033
13046
  * Stores a value which is retained for the lifetime of the component. Subsequent calls to
13034
13047
  * `useConstant` will always return the first value given.
13035
13048
  *
13036
- * If the value is a function, the function is invoked once to calculate the actual value.
13049
+ * If the value is a function, the function is invoked once to calculate the actual value. You can
13050
+ * then also pass arguments to call the function with, so that you don't need to create a new
13051
+ * function on every render.
13052
+ *
13053
+ * @example
13054
+ *
13055
+ * ```tsx
13056
+ * const fixedRandomValue = useConstant(() => Math.random);
13057
+ * const otherFixedRandomValue = useConstant(Math.random);
13058
+ *
13059
+ * const getConfig = (env: string) => { ... }
13060
+ * const config = useConstant(getConfig, environment);
13061
+ * ```
13037
13062
  *
13038
13063
  * @public
13039
13064
  */
13040
- const useConstant = (value) => {
13065
+ const useConstant = (value, ...args) => {
13041
13066
  const { val, set } = useSequentialScope();
13042
13067
  if (val != null) {
13043
13068
  return val;
13044
13069
  }
13045
13070
  // Note: We are not using `invoke` here because we don't want to clear the context
13046
- value = isFunction(value) && !isQwikComponent(value) ? value() : value;
13071
+ value = isFunction(value) && !isQwikComponent(value) ? untrack(value, ...args) : value;
13047
13072
  return set(value);
13048
13073
  };
13049
13074
 
13050
- const useComputedCommon = (qrl, createFn, options) => {
13051
- const { val, set } = useSequentialScope();
13052
- if (val) {
13053
- return val;
13054
- }
13055
- assertQrl(qrl);
13056
- const signal = createFn(qrl, options);
13057
- set(signal);
13058
- // Note that we first save the signal
13059
- // and then we throw to load the qrl
13060
- // This is why we can't use useConstant, we need to keep using the same qrl object
13061
- throwIfQRLNotResolved(qrl);
13062
- return signal;
13075
+ const creator$2 = (qrl, options) => {
13076
+ qrl.resolve();
13077
+ return createComputedSignal(qrl, options);
13063
13078
  };
13064
13079
  /** @internal */
13065
13080
  const useComputedQrl = (qrl, options) => {
13066
- return useComputedCommon(qrl, createComputedSignal, options);
13081
+ return useConstant((creator$2), qrl, options);
13067
13082
  };
13068
13083
  /**
13069
13084
  * Creates a computed signal which is calculated from the given function. A computed signal is a
@@ -13077,8 +13092,12 @@ const useComputedQrl = (qrl, options) => {
13077
13092
  */
13078
13093
  const useComputed$ = implicit$FirstArg(useComputedQrl);
13079
13094
 
13095
+ const creator$1 = (qrl) => {
13096
+ qrl.resolve();
13097
+ return createSerializerSignal(qrl);
13098
+ };
13080
13099
  /** @internal */
13081
- const useSerializerQrl = (qrl) => useComputedCommon(qrl, createSerializerSignal);
13100
+ const useSerializerQrl = (qrl) => useConstant((creator$1), qrl);
13082
13101
  /**
13083
13102
  * Creates a signal which holds a custom serializable value. It requires that the value implements
13084
13103
  * the `CustomSerializable` type, which means having a function under the `[SerializeSymbol]`
@@ -13181,7 +13200,7 @@ const useRegisterTaskEvents = (task, eagerness) => {
13181
13200
  }
13182
13201
  };
13183
13202
  const getTaskHandlerQrl = (task) => {
13184
- return createQRL(null, '_task', scheduleTask, null, null, [task]);
13203
+ return createQRL(null, '_task', scheduleTask, null, [task]);
13185
13204
  };
13186
13205
 
13187
13206
  // <docs markdown="../readme.md#useResource">
@@ -13340,21 +13359,36 @@ const useTask$ = /*#__PURE__*/ implicit$FirstArg(useTaskQrl);
13340
13359
  // We need to cast to help out the api extractor
13341
13360
  const useVisibleTask$ = /*#__PURE__*/ implicit$FirstArg(useVisibleTaskQrl);
13342
13361
 
13362
+ const creator = (qrl, options) => {
13363
+ qrl.resolve();
13364
+ return createAsyncSignal(qrl, options);
13365
+ };
13343
13366
  /** @internal */
13344
- const useAsyncComputedQrl = (qrl, options) => {
13345
- return useComputedCommon(qrl, createAsyncComputedSignal, options);
13367
+ const useAsyncQrl = (qrl, options) => {
13368
+ return useConstant((creator), qrl, options);
13346
13369
  };
13347
13370
  /**
13348
- * Creates a computed signal which is calculated from the given function. A computed signal is a
13349
- * signal which is calculated from other signals. When the signals change, the computed signal is
13350
- * recalculated, and if the result changed, all tasks which are tracking the signal will be re-run
13351
- * and all components that read the signal will be re-rendered.
13371
+ * Creates an AsyncSignal which holds the result of the given async function. If the function uses
13372
+ * `track()` to track reactive state, and that state changes, the AsyncSignal is recalculated, and
13373
+ * if the result changed, all tasks which are tracking the AsyncSignal will be re-run and all
13374
+ * subscribers (components, tasks etc) that read the AsyncSignal will be updated.
13352
13375
  *
13353
- * The function must be synchronous and must not have any side effects.
13376
+ * If the async function throws an error, the AsyncSignal will capture the error and set the `error`
13377
+ * property. The error can be cleared by re-running the async function successfully.
13378
+ *
13379
+ * While the async function is running, the `loading` property will be set to `true`. Once the
13380
+ * function completes, `loading` will be set to `false`.
13381
+ *
13382
+ * If the value has not yet been resolved, reading the AsyncSignal will throw a Promise, which will
13383
+ * retry the component or task once the value resolves.
13384
+ *
13385
+ * If the value has been resolved, but the async function is re-running, reading the AsyncSignal
13386
+ * will subscribe to it and return the last resolved value until the new value is ready. As soon as
13387
+ * the new value is ready, the subscribers will be updated.
13354
13388
  *
13355
13389
  * @public
13356
13390
  */
13357
- const useAsyncComputed$ = implicit$FirstArg(useAsyncComputedQrl);
13391
+ const useAsync$ = implicit$FirstArg(useAsyncQrl);
13358
13392
 
13359
13393
  /** @public */
13360
13394
  const useErrorBoundary = () => {
@@ -13461,5 +13495,5 @@ if (import.meta.hot) {
13461
13495
  });
13462
13496
  }
13463
13497
 
13464
- export { $, Fragment, NoSerializeSymbol, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SerializerSymbol, SkipRender, Slot, _CONST_PROPS, DomContainer as _DomContainer, _EFFECT_BACK_REF, EMPTY_ARRAY as _EMPTY_ARRAY, _IMMUTABLE, _SharedContainer, SubscriptionData as _SubscriptionData, _UNINITIALIZED, _VAR_PROPS, _chk, _deserialize, _dumpState, _executeSsrChores, _fnSignal, _getConstProps, _getContextContainer, _getContextElement, _getContextEvent, getDomContainer as _getDomContainer, _getQContainerElement, _getVarProps, _hasStoreEffects, 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, _noopQrl, _noopQrlDEV, preprocessState as _preprocessState, _qrlSync, _regSymbol, _resolveContextWithoutSequentialScope, _restProps, _run, _serialize, scheduleTask as _task, _val, verifySerializable as _verifySerializable, vnode_ensureElementInflated as _vnode_ensureElementInflated, vnode_getAttrKeys as _vnode_getAttrKeys, vnode_getFirstChild as _vnode_getFirstChild, vnode_isMaterialized as _vnode_isMaterialized, vnode_isTextVNode as _vnode_isTextVNode, vnode_isVirtualVNode as _vnode_isVirtualVNode, vnode_toString as _vnode_toString, _waitUntilRendered, _walkJSX, _wrapProp, _wrapSignal, component$, componentQrl, createAsyncComputed$, createAsyncComputedSignal as createAsyncComputedQrl, createComputed$, createComputedSignal as createComputedQrl, createContextId, h as createElement, createSerializer$, createSerializerSignal as createSerializerQrl, createSignal, event$, eventQrl, forceStoreEffects, getDomContainer, getLocale, getPlatform, h, implicit$FirstArg, inlinedQrl, inlinedQrlDEV, isSignal, jsx, jsxDEV, jsxs, noSerialize, qrl, qrlDEV, render, setPlatform, sync$, untrack, unwrapStore, useAsyncComputed$, useAsyncComputedQrl, useComputed$, useComputedQrl, useConstant, useContext, useContextProvider, useErrorBoundary, useId, useLexicalScope, useOn, useOnDocument, useOnWindow, useResource$, useResourceQrl, useSerializer$, useSerializerQrl, useServerData, useSignal, useStore, useStyles$, useStylesQrl, useStylesScoped$, useStylesScopedQrl, useTask$, useTaskQrl, useVisibleTask$, useVisibleTaskQrl, version, withLocale };
13498
+ export { $, Fragment, NoSerializeSymbol, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SerializerSymbol, SkipRender, Slot, _CONST_PROPS, DomContainer as _DomContainer, _EFFECT_BACK_REF, EMPTY_ARRAY as _EMPTY_ARRAY, _IMMUTABLE, _SharedContainer, SubscriptionData as _SubscriptionData, _UNINITIALIZED, _VAR_PROPS, _captures, _chk, _deserialize, _dumpState, _executeSsrChores, _fnSignal, _getConstProps, _getContextContainer, _getContextEvent, _getContextHostElement, getDomContainer as _getDomContainer, _getQContainerElement, _getVarProps, _hasStoreEffects, 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, _noopQrl, _noopQrlDEV, preprocessState as _preprocessState, _qrlSync, _regSymbol, _resolveContextWithoutSequentialScope, _restProps, _run, _serialize, scheduleTask as _task, _val, verifySerializable as _verifySerializable, vnode_ensureElementInflated as _vnode_ensureElementInflated, vnode_getAttrKeys as _vnode_getAttrKeys, vnode_getFirstChild as _vnode_getFirstChild, vnode_isMaterialized as _vnode_isMaterialized, vnode_isTextVNode as _vnode_isTextVNode, vnode_isVirtualVNode as _vnode_isVirtualVNode, vnode_toString as _vnode_toString, _waitUntilRendered, _walkJSX, _wrapProp, _wrapSignal, component$, componentQrl, createAsync$, createAsyncSignal as createAsyncQrl, createComputed$, createComputedSignal as createComputedQrl, createContextId, h as createElement, createSerializer$, createSerializerSignal as createSerializerQrl, createSignal, event$, eventQrl, forceStoreEffects, getDomContainer, getLocale, getPlatform, h, implicit$FirstArg, inlinedQrl, inlinedQrlDEV, isSignal, jsx, jsxDEV, jsxs, noSerialize, qrl, qrlDEV, render, setPlatform, sync$, untrack, unwrapStore, useAsync$, useAsyncQrl, useComputed$, useComputedQrl, useConstant, useContext, useContextProvider, useErrorBoundary, useId, useLexicalScope, useOn, useOnDocument, useOnWindow, useResource$, useResourceQrl, useSerializer$, useSerializerQrl, useServerData, useSignal, useStore, useStyles$, useStylesQrl, useStylesScoped$, useStylesScopedQrl, useTask$, useTaskQrl, useVisibleTask$, useVisibleTaskQrl, version, withLocale };
13465
13499
  //# sourceMappingURL=core.mjs.map