@qwik.dev/core 2.0.0-alpha.4 → 2.0.0-alpha.5

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-alpha.4-dev+374e0d6
3
+ * @qwik.dev/core 2.0.0-alpha.5-dev+cb53bbd
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
@@ -149,7 +149,7 @@ const codeToText = (code, ...parts) => {
149
149
  'SsrError(tag): {{0}}', // 29
150
150
  'QRLs can not be resolved because it does not have an attached container. This means that the QRL does not know where it belongs inside the DOM, so it cant dynamically import() from a relative path.', // 30
151
151
  'QRLs can not be dynamically resolved, because it does not have a chunk path', // 31
152
- 'The JSX ref attribute must be a Signal', // 32
152
+ '{{0}}\nThe JSX ref attribute must be a Signal', // 32
153
153
  'Serialization Error: Deserialization of data type {{0}} is not implemented', // 33
154
154
  'Serialization Error: Expected vnode for ref prop, but got {{0}}', // 34
155
155
  'Serialization Error: Cannot allocate data type {{0}}', // 35
@@ -157,7 +157,7 @@ const codeToText = (code, ...parts) => {
157
157
  'Serialization Error: Serialization of data type {{0}} is not implemented', // 37
158
158
  'Serialization Error: Unvisited {{0}}', // 38
159
159
  'Serialization Error: Missing QRL chunk for {{0}}', // 39
160
- 'The value of the textarea must be a string', // 40
160
+ '{{0}}\nThe value of the textarea must be a string found {{1}}', // 40
161
161
  'Unable to find q:container', // 41
162
162
  "Element must have 'q:container' attribute.", // 42
163
163
  'Unknown vnode type {{0}}.', // 43
@@ -1135,7 +1135,6 @@ class StoreHandler {
1135
1135
  }
1136
1136
  /** In the case of oldValue and value are the same, the effects are not triggered. */
1137
1137
  set(target, prop, value) {
1138
- target = unwrapDeserializerProxy(target);
1139
1138
  if (typeof prop === 'symbol') {
1140
1139
  target[prop] = value;
1141
1140
  return true;
@@ -1204,6 +1203,8 @@ function addEffect(target, prop, store, effectSubscriber) {
1204
1203
  // to unsubscribe from. So we need to store the reference from the effect back
1205
1204
  // to this signal.
1206
1205
  ensureContains(effectSubscriber, target);
1206
+ // We need to add the subscriber to the effect so that we can clean it up later
1207
+ ensureEffectContainsSubscriber(effectSubscriber[EffectSubscriptionsProp.EFFECT], target, store.$container$);
1207
1208
  }
1208
1209
  function setNewValueAndTriggerEffects(prop, value, target, currentStore) {
1209
1210
  target[prop] = value;
@@ -1274,32 +1275,40 @@ function clearVNodeEffectDependencies(container, value) {
1274
1275
  }
1275
1276
  for (let i = effects.length - 1; i >= 0; i--) {
1276
1277
  const subscriber = effects[i];
1277
- const subscriptionRemoved = clearEffects(subscriber, value);
1278
- if (subscriptionRemoved) {
1279
- effects.splice(i, 1);
1280
- }
1278
+ clearEffects(subscriber, value, effects, i, container);
1279
+ }
1280
+ if (effects.length === 0) {
1281
+ vnode_setProp(value, QSubscribers, null);
1281
1282
  }
1282
1283
  }
1283
- function clearSubscriberEffectDependencies(value) {
1284
+ function clearSubscriberEffectDependencies(container, value) {
1284
1285
  if (value.$effectDependencies$) {
1285
1286
  for (let i = value.$effectDependencies$.length - 1; i >= 0; i--) {
1286
1287
  const subscriber = value.$effectDependencies$[i];
1287
- const subscriptionRemoved = clearEffects(subscriber, value);
1288
- if (subscriptionRemoved) {
1289
- value.$effectDependencies$.splice(i, 1);
1290
- }
1288
+ clearEffects(subscriber, value, value.$effectDependencies$, i, container);
1289
+ }
1290
+ if (value.$effectDependencies$.length === 0) {
1291
+ value.$effectDependencies$ = null;
1291
1292
  }
1292
1293
  }
1293
1294
  }
1294
- function clearEffects(subscriber, value) {
1295
- if (!isSignal(subscriber)) {
1296
- return false;
1295
+ function clearEffects(subscriber, value, effectArray, indexToRemove, container) {
1296
+ let subscriptionRemoved = false;
1297
+ const seenSet = new Set();
1298
+ if (subscriber instanceof WrappedSignal) {
1299
+ subscriptionRemoved = clearSignalEffects(subscriber, value, seenSet);
1297
1300
  }
1298
- const effectSubscriptions = subscriber.$effects$;
1299
- const hostElement = subscriber.$hostElement$;
1300
- if (hostElement && hostElement === value) {
1301
- subscriber.$hostElement$ = null;
1301
+ else if (container.$storeProxyMap$.has(subscriber)) {
1302
+ const store = container.$storeProxyMap$.get(subscriber);
1303
+ const handler = getStoreHandler(store);
1304
+ subscriptionRemoved = clearStoreEffects(handler, value);
1305
+ }
1306
+ if (subscriptionRemoved) {
1307
+ effectArray.splice(indexToRemove, 1);
1302
1308
  }
1309
+ }
1310
+ function clearSignalEffects(subscriber, value, seenSet) {
1311
+ const effectSubscriptions = subscriber.$effects$;
1303
1312
  let subscriptionRemoved = false;
1304
1313
  if (effectSubscriptions) {
1305
1314
  for (let i = effectSubscriptions.length - 1; i >= 0; i--) {
@@ -1310,15 +1319,69 @@ function clearEffects(subscriber, value) {
1310
1319
  }
1311
1320
  }
1312
1321
  }
1313
- // clear the effects of the arguments
1314
- const args = subscriber.$args$;
1315
- if (args) {
1316
- for (let i = args.length - 1; i >= 0; i--) {
1317
- clearEffects(args[i], subscriber);
1322
+ if (subscriber instanceof WrappedSignal) {
1323
+ const hostElement = subscriber.$hostElement$;
1324
+ if (hostElement && hostElement === value) {
1325
+ subscriber.$hostElement$ = null;
1326
+ }
1327
+ // clear the effects of the arguments
1328
+ const args = subscriber.$args$;
1329
+ if (args) {
1330
+ clearArgsEffects(args, subscriber, seenSet);
1318
1331
  }
1319
1332
  }
1320
1333
  return subscriptionRemoved;
1321
1334
  }
1335
+ function clearStoreEffects(storeHandler, value) {
1336
+ const effectSubscriptions = storeHandler.$effects$;
1337
+ if (!effectSubscriptions) {
1338
+ return false;
1339
+ }
1340
+ let subscriptionRemoved = false;
1341
+ for (const key in effectSubscriptions) {
1342
+ const effects = effectSubscriptions[key];
1343
+ for (let i = effects.length - 1; i >= 0; i--) {
1344
+ const effect = effects[i];
1345
+ if (effect[EffectSubscriptionsProp.EFFECT] === value) {
1346
+ effects.splice(i, 1);
1347
+ subscriptionRemoved = true;
1348
+ }
1349
+ }
1350
+ if (effects.length === 0) {
1351
+ delete effectSubscriptions[key];
1352
+ }
1353
+ }
1354
+ return subscriptionRemoved;
1355
+ }
1356
+ function clearArgsEffects(args, subscriber, seenSet) {
1357
+ for (let i = args.length - 1; i >= 0; i--) {
1358
+ const arg = args[i];
1359
+ clearArgEffect(arg, subscriber, seenSet);
1360
+ }
1361
+ }
1362
+ function clearArgEffect(arg, subscriber, seenSet) {
1363
+ if (seenSet.has(arg)) {
1364
+ return;
1365
+ }
1366
+ seenSet.add(arg);
1367
+ if (isSignal(arg)) {
1368
+ clearSignalEffects(arg, subscriber, seenSet);
1369
+ }
1370
+ else if (typeof arg === 'object' && arg !== null) {
1371
+ if (isStore(arg)) {
1372
+ clearStoreEffects(getStoreHandler(arg), subscriber);
1373
+ }
1374
+ else {
1375
+ for (const key in arg) {
1376
+ clearArgEffect(arg[key], subscriber, seenSet);
1377
+ }
1378
+ }
1379
+ }
1380
+ else if (Array.isArray(arg)) {
1381
+ clearArgsEffects(arg, subscriber, seenSet);
1382
+ }
1383
+ else ;
1384
+ }
1322
1385
 
1323
1386
  /** @internal */
1324
1387
  const useResourceQrl = (qrl, opts) => {
@@ -1405,14 +1468,17 @@ function getResourceValueAsPromise(props) {
1405
1468
  // create a subscription for the resource._state changes
1406
1469
  const state = resource._state;
1407
1470
  if (state === 'pending' && props.onPending) {
1408
- return Promise.resolve(props.onPending());
1471
+ return Promise.resolve().then(useBindInvokeContext(props.onPending));
1409
1472
  }
1410
1473
  else if (state === 'rejected' && props.onRejected) {
1411
- return Promise.resolve(resource._error).then(props.onRejected);
1474
+ return Promise.resolve(resource._error).then(useBindInvokeContext(props.onRejected));
1412
1475
  }
1413
1476
  else {
1414
- // resolved, pending without onPending prop or rejected with onRejected prop
1415
- return Promise.resolve(untrack(() => resource._resolved)).then(props.onResolved);
1477
+ const resolvedValue = untrack(() => resource._resolved);
1478
+ if (resolvedValue !== undefined) {
1479
+ // resolved, pending without onPending prop or rejected without onRejected prop
1480
+ return Promise.resolve(resolvedValue).then(useBindInvokeContext(props.onResolved));
1481
+ }
1416
1482
  }
1417
1483
  }
1418
1484
  return resource.value.then(useBindInvokeContext(props.onResolved), useBindInvokeContext(props.onRejected));
@@ -1453,7 +1519,7 @@ const runResource = (task, container, host) => {
1453
1519
  cleanupTask(task);
1454
1520
  const iCtx = newInvokeContext(container.$locale$, host, undefined, ResourceEvent);
1455
1521
  iCtx.$container$ = container;
1456
- const taskFn = task.$qrl$.getFn(iCtx, () => clearSubscriberEffectDependencies(task));
1522
+ const taskFn = task.$qrl$.getFn(iCtx, () => clearSubscriberEffectDependencies(container, task));
1457
1523
  const resource = task.$state$;
1458
1524
  assertDefined(resource, 'useResource: when running a resource, "task.resource" must be a defined.', task);
1459
1525
  const track = (obj, prop) => {
@@ -2254,6 +2320,17 @@ function escapeHTML(html) {
2254
2320
  }
2255
2321
  }
2256
2322
 
2323
+ function getFileLocationFromJsx(jsxDev) {
2324
+ if (!jsxDev) {
2325
+ return null;
2326
+ }
2327
+ const sanitizedFileName = jsxDev.fileName?.replace(/\\/g, '/');
2328
+ if (sanitizedFileName) {
2329
+ return `${sanitizedFileName}:${jsxDev.lineNumber}:${jsxDev.columnNumber}`;
2330
+ }
2331
+ return null;
2332
+ }
2333
+
2257
2334
  const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
2258
2335
  let journal = container.$journal$;
2259
2336
  /**
@@ -2697,7 +2774,7 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
2697
2774
  *
2698
2775
  * @returns {boolean}
2699
2776
  */
2700
- function createNewElement(jsx, elementName) {
2777
+ function createNewElement(jsx, elementName, currentFile) {
2701
2778
  const element = createElementWithNamespace(elementName);
2702
2779
  const { constProps } = jsx;
2703
2780
  let needsQDispatchEventPatch = false;
@@ -2728,6 +2805,9 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
2728
2805
  value(element);
2729
2806
  continue;
2730
2807
  }
2808
+ else {
2809
+ throw qError(QError.invalidRefValue, [currentFile]);
2810
+ }
2731
2811
  }
2732
2812
  if (isSignal(value)) {
2733
2813
  const signalData = new EffectPropData({
@@ -2742,13 +2822,13 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
2742
2822
  continue;
2743
2823
  }
2744
2824
  if (elementName === 'textarea' && key === 'value') {
2745
- if (typeof value !== 'string') {
2825
+ if (value && typeof value !== 'string') {
2746
2826
  if (isDev) {
2747
- throw qError(QError.wrongTextareaValue);
2827
+ throw qError(QError.wrongTextareaValue, [currentFile, value]);
2748
2828
  }
2749
2829
  continue;
2750
2830
  }
2751
- element.value = escapeHTML(value);
2831
+ element.value = escapeHTML(value || '');
2752
2832
  continue;
2753
2833
  }
2754
2834
  value = serializeAttribute(key, value, scopedStyleIdPrefix);
@@ -2782,6 +2862,7 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
2782
2862
  const isSameElementName = vCurrent && vnode_isElementVNode(vCurrent) && elementName === vnode_getElementName(vCurrent);
2783
2863
  const jsxKey = jsx.key;
2784
2864
  let needsQDispatchEventPatch = false;
2865
+ const currentFile = getFileLocationFromJsx(jsx.dev);
2785
2866
  if (!isSameElementName || jsxKey !== getKey(vCurrent)) {
2786
2867
  // So we have a key and it does not match the current node.
2787
2868
  // We need to do a forward search to find it.
@@ -2794,14 +2875,21 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
2794
2875
  else {
2795
2876
  // Existing keyed node
2796
2877
  vnode_insertBefore(journal, vParent, vNewNode, vCurrent);
2878
+ // We are here, so jsx is different from the vCurrent, so now we want to point to the moved node.
2879
+ vCurrent = vNewNode;
2880
+ // We need to clean up the vNewNode, because we don't want to skip advance to next sibling (see `advance` function).
2881
+ vNewNode = null;
2882
+ // We need also to go back to the previous sibling, because we assigned previous sibling to the vCurrent.
2883
+ if (vSiblings !== null) {
2884
+ vSiblingsIdx -= SiblingsArray.Size;
2885
+ }
2797
2886
  }
2798
2887
  }
2799
2888
  // reconcile attributes
2800
2889
  const jsxAttrs = [];
2801
2890
  const props = jsx.varProps;
2802
2891
  for (const key in props) {
2803
- let value = props[key];
2804
- value = serializeAttribute(key, value, scopedStyleIdPrefix);
2892
+ const value = props[key];
2805
2893
  if (value != null) {
2806
2894
  mapArray_set(jsxAttrs, key, value, 0);
2807
2895
  }
@@ -2810,7 +2898,8 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
2810
2898
  mapArray_set(jsxAttrs, ELEMENT_KEY, jsxKey, 0);
2811
2899
  }
2812
2900
  const vNode = (vNewNode || vCurrent);
2813
- needsQDispatchEventPatch = setBulkProps(vNode, jsxAttrs) || needsQDispatchEventPatch;
2901
+ needsQDispatchEventPatch =
2902
+ setBulkProps(vNode, jsxAttrs, currentFile) || needsQDispatchEventPatch;
2814
2903
  if (needsQDispatchEventPatch) {
2815
2904
  // Event handler needs to be patched onto the element.
2816
2905
  const element = vnode_getNode(vNode);
@@ -2835,7 +2924,7 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
2835
2924
  }
2836
2925
  }
2837
2926
  /** @param tag Returns true if `qDispatchEvent` needs patching */
2838
- function setBulkProps(vnode, srcAttrs) {
2927
+ function setBulkProps(vnode, srcAttrs, currentFile) {
2839
2928
  vnode_ensureElementInflated(vnode);
2840
2929
  const dstAttrs = vnode;
2841
2930
  let srcIdx = 0;
@@ -2860,11 +2949,18 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
2860
2949
  value(element);
2861
2950
  return;
2862
2951
  }
2952
+ else {
2953
+ throw qError(QError.invalidRefValue, [currentFile]);
2954
+ }
2863
2955
  }
2864
2956
  if (isSignal(value)) {
2865
- value = untrack(() => value.value);
2957
+ const signalData = new EffectPropData({
2958
+ $scopedStyleIdPrefix$: scopedStyleIdPrefix,
2959
+ $isConst$: false,
2960
+ });
2961
+ value = trackSignalAndAssignHost(value, vnode, key, container, signalData);
2866
2962
  }
2867
- vnode_setAttr(journal, vnode, key, value);
2963
+ vnode_setAttr(journal, vnode, key, serializeAttribute(key, value, scopedStyleIdPrefix));
2868
2964
  if (value === null) {
2869
2965
  // if we set `null` than attribute was removed and we need to shorten the dstLength
2870
2966
  dstLength = dstAttrs.length;
@@ -2920,6 +3016,10 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
2920
3016
  }
2921
3017
  srcIdx++;
2922
3018
  srcKey = srcIdx < srcLength ? srcAttrs[srcIdx++] : null;
3019
+ // we need to increment dstIdx too, because we added destination key and value to the VNode
3020
+ // and dstAttrs is a reference to the VNode
3021
+ dstIdx++;
3022
+ dstKey = dstIdx < dstLength ? dstAttrs[dstIdx++] : null;
2923
3023
  }
2924
3024
  else if (srcKey == dstKey) {
2925
3025
  const srcValue = srcAttrs[srcIdx++];
@@ -3037,7 +3137,7 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
3037
3137
  vNewNode = retrieveChildWithKey(null, jsxKey);
3038
3138
  if (vNewNode != null) {
3039
3139
  // We found it, move it up.
3040
- vnode_insertBefore(journal, vParent, (vNewNode = vnode_newVirtual()), vCurrent && getInsertBefore());
3140
+ vnode_insertBefore(journal, vParent, vNewNode, vCurrent && getInsertBefore());
3041
3141
  return;
3042
3142
  }
3043
3143
  }
@@ -3279,7 +3379,7 @@ function cleanup(container, vNode) {
3279
3379
  const obj = seq[i];
3280
3380
  if (isTask(obj)) {
3281
3381
  const task = obj;
3282
- clearSubscriberEffectDependencies(task);
3382
+ clearSubscriberEffectDependencies(container, task);
3283
3383
  if (task.$flags$ & TaskFlags.VISIBLE_TASK) {
3284
3384
  container.$scheduler$(ChoreType.CLEANUP_VISIBLE, task);
3285
3385
  }
@@ -3612,7 +3712,7 @@ const createScheduler = (container, scheduleDrain, journalFlush) => {
3612
3712
  $executed$: false,
3613
3713
  };
3614
3714
  chore.$promise$ = new Promise((resolve) => (chore.$resolve$ = resolve));
3615
- chore = sortedInsert(choreQueue, chore);
3715
+ chore = sortedInsert(choreQueue, chore, container.rootVNode || null);
3616
3716
  if (!journalFlushScheduled && runLater) {
3617
3717
  // If we are not currently draining, we need to schedule a drain.
3618
3718
  journalFlushScheduled = true;
@@ -3623,7 +3723,7 @@ const createScheduler = (container, scheduleDrain, journalFlush) => {
3623
3723
  return chore.$promise$;
3624
3724
  }
3625
3725
  else {
3626
- return drainUpTo(chore);
3726
+ return drainUpTo(chore, container.rootVNode || null);
3627
3727
  }
3628
3728
  }
3629
3729
  /**
@@ -3631,7 +3731,7 @@ const createScheduler = (container, scheduleDrain, journalFlush) => {
3631
3731
  *
3632
3732
  * @param runUptoChore
3633
3733
  */
3634
- function drainUpTo(runUptoChore) {
3734
+ function drainUpTo(runUptoChore, rootVNode) {
3635
3735
  // If it already ran, it's not in the queue
3636
3736
  if (runUptoChore.$executed$) {
3637
3737
  return runUptoChore.$returnValue$;
@@ -3642,7 +3742,7 @@ const createScheduler = (container, scheduleDrain, journalFlush) => {
3642
3742
  }
3643
3743
  while (choreQueue.length) {
3644
3744
  const nextChore = choreQueue.shift();
3645
- const order = choreComparator(nextChore, runUptoChore, false);
3745
+ const order = choreComparator(nextChore, runUptoChore, rootVNode, false);
3646
3746
  if (order === null) {
3647
3747
  continue;
3648
3748
  }
@@ -3658,7 +3758,7 @@ const createScheduler = (container, scheduleDrain, journalFlush) => {
3658
3758
  }
3659
3759
  const returnValue = executeChore(nextChore);
3660
3760
  if (isPromise(returnValue)) {
3661
- const promise = returnValue.then(() => drainUpTo(runUptoChore));
3761
+ const promise = returnValue.then(() => drainUpTo(runUptoChore, rootVNode));
3662
3762
  return promise;
3663
3763
  }
3664
3764
  }
@@ -3779,7 +3879,7 @@ function vNodeAlreadyDeleted(chore) {
3779
3879
  vnode_isVNode(chore.$host$) &&
3780
3880
  chore.$host$[VNodeProps.flags] & VNodeFlags.Deleted);
3781
3881
  }
3782
- function choreComparator(a, b, shouldThrowOnHostMismatch) {
3882
+ function choreComparator(a, b, rootVNode, shouldThrowOnHostMismatch) {
3783
3883
  const macroTypeDiff = (a.$type$ & ChoreType.MACRO) - (b.$type$ & ChoreType.MACRO);
3784
3884
  if (macroTypeDiff !== 0) {
3785
3885
  return macroTypeDiff;
@@ -3792,7 +3892,7 @@ function choreComparator(a, b, shouldThrowOnHostMismatch) {
3792
3892
  if (aHost !== bHost && aHost !== null && bHost !== null) {
3793
3893
  if (vnode_isVNode(aHost) && vnode_isVNode(bHost)) {
3794
3894
  // we are running on the client.
3795
- const hostDiff = vnode_documentPosition(aHost, bHost);
3895
+ const hostDiff = vnode_documentPosition(aHost, bHost, rootVNode);
3796
3896
  if (hostDiff !== 0) {
3797
3897
  return hostDiff;
3798
3898
  }
@@ -3833,7 +3933,7 @@ function choreComparator(a, b, shouldThrowOnHostMismatch) {
3833
3933
  }
3834
3934
  return 0;
3835
3935
  }
3836
- function sortedFindIndex(sortedArray, value) {
3936
+ function sortedFindIndex(sortedArray, value, rootVNode) {
3837
3937
  /// We need to ensure that the `queue` is sorted by priority.
3838
3938
  /// 1. Find a place where to insert into.
3839
3939
  let bottom = 0;
@@ -3841,7 +3941,7 @@ function sortedFindIndex(sortedArray, value) {
3841
3941
  while (bottom < top) {
3842
3942
  const middle = bottom + ((top - bottom) >> 1);
3843
3943
  const midChore = sortedArray[middle];
3844
- const comp = choreComparator(value, midChore, true);
3944
+ const comp = choreComparator(value, midChore, rootVNode, true);
3845
3945
  if (comp < 0) {
3846
3946
  top = middle;
3847
3947
  }
@@ -3855,10 +3955,10 @@ function sortedFindIndex(sortedArray, value) {
3855
3955
  }
3856
3956
  return ~bottom;
3857
3957
  }
3858
- function sortedInsert(sortedArray, value) {
3958
+ function sortedInsert(sortedArray, value, rootVNode) {
3859
3959
  /// We need to ensure that the `queue` is sorted by priority.
3860
3960
  /// 1. Find a place where to insert into.
3861
- const idx = sortedFindIndex(sortedArray, value);
3961
+ const idx = sortedFindIndex(sortedArray, value, rootVNode);
3862
3962
  if (idx < 0) {
3863
3963
  /// 2. Insert the chore into the queue.
3864
3964
  sortedArray.splice(~idx, 0, value);
@@ -3936,7 +4036,7 @@ const runTask = (task, container, host) => {
3936
4036
  cleanupTask(task);
3937
4037
  const iCtx = newInvokeContext(container.$locale$, host, undefined, TaskEvent);
3938
4038
  iCtx.$container$ = container;
3939
- const taskFn = task.$qrl$.getFn(iCtx, () => clearSubscriberEffectDependencies(task));
4039
+ const taskFn = task.$qrl$.getFn(iCtx, () => clearSubscriberEffectDependencies(container, task));
3940
4040
  const track = (obj, prop) => {
3941
4041
  const ctx = newInvokeContext();
3942
4042
  ctx.$effectSubscriber$ = [task, EffectProperty.COMPONENT];
@@ -4568,7 +4668,7 @@ function processJSXNode(ssr, enqueue, value, options) {
4568
4668
  appendClassIfScopedStyleExists(jsx, options.styleScoped);
4569
4669
  let qwikInspectorAttrValue = null;
4570
4670
  if (isDev && jsx.dev && jsx.type !== 'head') {
4571
- qwikInspectorAttrValue = getQwikInspectorAttributeValue(jsx.dev);
4671
+ qwikInspectorAttrValue = getFileLocationFromJsx(jsx.dev);
4572
4672
  if (qInspector) {
4573
4673
  appendQwikInspectorAttribute(jsx, qwikInspectorAttrValue);
4574
4674
  }
@@ -4842,13 +4942,6 @@ function getSlotName(host, jsx, ssr) {
4842
4942
  }
4843
4943
  return directGetPropsProxyProp(jsx, 'name') || QDefaultSlot;
4844
4944
  }
4845
- function getQwikInspectorAttributeValue(jsxDev) {
4846
- const sanitizedFileName = jsxDev.fileName?.replace(/\\/g, '/');
4847
- if (sanitizedFileName) {
4848
- return `${sanitizedFileName}:${jsxDev.lineNumber}:${jsxDev.columnNumber}`;
4849
- }
4850
- return null;
4851
- }
4852
4945
  function appendQwikInspectorAttribute(jsx, qwikInspectorAttrValue) {
4853
4946
  if (qwikInspectorAttrValue && (!jsx.constProps || !(qwikInspectorAttr in jsx.constProps))) {
4854
4947
  (jsx.constProps ||= {})[qwikInspectorAttr] = qwikInspectorAttrValue;
@@ -4870,7 +4963,7 @@ function appendClassIfScopedStyleExists(jsx, styleScoped) {
4870
4963
  *
4871
4964
  * @public
4872
4965
  */
4873
- const version = "2.0.0-alpha.4-dev+374e0d6";
4966
+ const version = "2.0.0-alpha.5-dev+cb53bbd";
4874
4967
 
4875
4968
  /** @internal */
4876
4969
  class _SharedContainer {
@@ -6761,7 +6854,7 @@ const vnode_getNode = (vnode) => {
6761
6854
  assertTrue(vnode_isTextVNode(vnode), 'Expecting Text Node.');
6762
6855
  return vnode[TextVNodeProps.node];
6763
6856
  };
6764
- function vnode_toString(depth = 10, offset = '', materialize = false, siblings = false) {
6857
+ function vnode_toString(depth = 20, offset = '', materialize = false, siblings = false) {
6765
6858
  let vnode = this;
6766
6859
  if (depth === 0) {
6767
6860
  return '...';
@@ -6978,20 +7071,24 @@ const vnode_getType = (vnode) => {
6978
7071
  throw qError(QError.invalidVNodeType, [type]);
6979
7072
  };
6980
7073
  const isElement = (node) => node && typeof node == 'object' && fastNodeType(node) === /** Node.ELEMENT_NODE* */ 1;
6981
- /// These global variables are used to avoid creating new arrays for each call to `vnode_getPathToClosestDomNode`.
7074
+ /// These global variables are used to avoid creating new arrays for each call to `vnode_documentPosition`.
6982
7075
  const aPath = [];
6983
7076
  const bPath = [];
6984
- const vnode_documentPosition = (a, b) => {
7077
+ const vnode_documentPosition = (a, b, rootVNode) => {
6985
7078
  if (a === b) {
6986
7079
  return 0;
6987
7080
  }
6988
7081
  let aDepth = -1;
6989
7082
  let bDepth = -1;
6990
7083
  while (a) {
6991
- a = (aPath[++aDepth] = a)[VNodeProps.parent];
7084
+ const vNode = (aPath[++aDepth] = a);
7085
+ a = (vNode[VNodeProps.parent] ||
7086
+ (rootVNode && vnode_getProp(a, QSlotParent, (id) => vnode_locate(rootVNode, id))));
6992
7087
  }
6993
7088
  while (b) {
6994
- b = (bPath[++bDepth] = b)[VNodeProps.parent];
7089
+ const vNode = (bPath[++bDepth] = b);
7090
+ b = (vNode[VNodeProps.parent] ||
7091
+ (rootVNode && vnode_getProp(b, QSlotParent, (id) => vnode_locate(rootVNode, id))));
6995
7092
  }
6996
7093
  while (aDepth >= 0 && bDepth >= 0) {
6997
7094
  a = aPath[aDepth];
@@ -7017,6 +7114,11 @@ const vnode_documentPosition = (a, b) => {
7017
7114
  return -1;
7018
7115
  }
7019
7116
  } while (cursor);
7117
+ if (rootVNode && vnode_getProp(b, QSlotParent, (id) => vnode_locate(rootVNode, id))) {
7118
+ // The "b" node is a projection, so we need to set it after "a" node,
7119
+ // because the "a" node could be a context provider.
7120
+ return -1;
7121
+ }
7020
7122
  // The node is not in the list of siblings, that means it must be disconnected.
7021
7123
  return 1;
7022
7124
  }
@@ -7049,11 +7151,7 @@ const vnode_getProjectionParentComponent = (vHost, rootVNode) => {
7049
7151
  while (projectionDepth--) {
7050
7152
  while (vHost &&
7051
7153
  (vnode_isVirtualVNode(vHost) ? vnode_getProp(vHost, OnRenderProp, null) === null : true)) {
7052
- const qSlotParentProp = vnode_getProp(vHost, QSlotParent, null);
7053
- const qSlotParent = qSlotParentProp &&
7054
- (typeof qSlotParentProp === 'string'
7055
- ? vnode_locate(rootVNode, qSlotParentProp)
7056
- : qSlotParentProp);
7154
+ const qSlotParent = vnode_getProp(vHost, QSlotParent, (id) => vnode_locate(rootVNode, id));
7057
7155
  const vProjectionParent = vnode_isVirtualVNode(vHost) && qSlotParent;
7058
7156
  if (vProjectionParent) {
7059
7157
  // We found a projection, so we need to go up one more level.
@@ -7962,14 +8060,14 @@ class DomContainer extends _SharedContainer {
7962
8060
  if (vnode_getProp(vNode, OnRenderProp, null) !== null) {
7963
8061
  return vNode;
7964
8062
  }
7965
- // If virtual node, than it could be a slot so we need to read its parent.
7966
- const parent = vnode_getProp(vNode, QSlotParent, this.$vnodeLocate$);
7967
- if (parent) {
7968
- vNode = parent;
7969
- continue;
7970
- }
8063
+ vNode =
8064
+ vnode_getParent(vNode) ||
8065
+ // If virtual node, than it could be a slot so we need to read its parent.
8066
+ vnode_getProp(vNode, QSlotParent, this.$vnodeLocate$);
8067
+ }
8068
+ else {
8069
+ vNode = vnode_getParent(vNode);
7971
8070
  }
7972
- vNode = vnode_getParent(vNode);
7973
8071
  }
7974
8072
  return null;
7975
8073
  }
@@ -8069,12 +8167,6 @@ class DomContainer extends _SharedContainer {
8069
8167
 
8070
8168
  /** There's [documentation](./serialization.md) */
8071
8169
  const deserializedProxyMap = new WeakMap();
8072
- const unwrapDeserializerProxy = (value) => {
8073
- const unwrapped = typeof value === 'object' &&
8074
- value !== null &&
8075
- value[SERIALIZER_PROXY_UNWRAP];
8076
- return unwrapped ? unwrapped : value;
8077
- };
8078
8170
  const isDeserializerProxy = (value) => {
8079
8171
  return typeof value === 'object' && value !== null && SERIALIZER_PROXY_UNWRAP in value;
8080
8172
  };
@@ -8127,14 +8219,14 @@ class DeserializationHandler {
8127
8219
  return value;
8128
8220
  }
8129
8221
  const container = this.$container$;
8130
- const propValue = allocate(container, typeId, value);
8131
- Reflect.set(target, property, propValue);
8132
- this.$data$[idx] = undefined;
8133
- this.$data$[idx + 1] = propValue;
8222
+ let propValue = allocate(container, typeId, value);
8134
8223
  /** We stored the reference, so now we can inflate, allowing cycles. */
8135
8224
  if (typeId >= TypeIds.Error) {
8136
- inflate(container, propValue, typeId, value);
8225
+ propValue = inflate(container, propValue, typeId, value);
8137
8226
  }
8227
+ Reflect.set(target, property, propValue);
8228
+ this.$data$[idx] = undefined;
8229
+ this.$data$[idx + 1] = propValue;
8138
8230
  return propValue;
8139
8231
  }
8140
8232
  has(target, property) {
@@ -8173,7 +8265,7 @@ const resolvers = new WeakMap();
8173
8265
  const inflate = (container, target, typeId, data) => {
8174
8266
  if (typeId === undefined) {
8175
8267
  // Already processed
8176
- return;
8268
+ return target;
8177
8269
  }
8178
8270
  // restore the complex data, except for plain objects
8179
8271
  if (typeId !== TypeIds.Object && Array.isArray(data)) {
@@ -8245,16 +8337,13 @@ const inflate = (container, target, typeId, data) => {
8245
8337
  case TypeIds.Store:
8246
8338
  case TypeIds.StoreArray: {
8247
8339
  const [value, flags, effects, storeEffect] = data;
8248
- const handler = getStoreHandler(target);
8249
- handler.$flags$ = flags;
8250
- // First assign so it sets up the deep stores
8251
- Object.assign(getStoreTarget(target), value);
8252
- // Afterwards restore the effects so they don't get triggered
8340
+ const store = getOrCreateStore(value, flags, container);
8341
+ const storeHandler = getStoreHandler(store);
8253
8342
  if (storeEffect) {
8254
8343
  effects[STORE_ARRAY_PROP] = storeEffect;
8255
8344
  }
8256
- handler.$effects$ = effects;
8257
- container.$storeProxyMap$.set(value, target);
8345
+ storeHandler.$effects$ = effects;
8346
+ target = store;
8258
8347
  break;
8259
8348
  }
8260
8349
  case TypeIds.Signal: {
@@ -8381,6 +8470,7 @@ const inflate = (container, target, typeId, data) => {
8381
8470
  default:
8382
8471
  throw qError(QError.serializeErrorNotImplemented, [typeId]);
8383
8472
  }
8473
+ return target;
8384
8474
  };
8385
8475
  const _constants = [
8386
8476
  undefined,
@@ -8446,9 +8536,9 @@ const allocate = (container, typeId, value) => {
8446
8536
  case TypeIds.ComputedSignal:
8447
8537
  return new ComputedSignal(container, null);
8448
8538
  case TypeIds.Store:
8449
- return createStore(container, {}, 0);
8450
8539
  case TypeIds.StoreArray:
8451
- return createStore(container, [], 0);
8540
+ // ignore allocate, we need to assign target while creating store
8541
+ return null;
8452
8542
  case TypeIds.URLSearchParams:
8453
8543
  return new URLSearchParams(value);
8454
8544
  case TypeIds.FormData:
@@ -9310,15 +9400,15 @@ function _deserialize(rawStateData, element) {
9310
9400
  }
9311
9401
  return output;
9312
9402
  }
9313
- function deserializeData(container, typeId, propValue) {
9403
+ function deserializeData(container, typeId, value) {
9314
9404
  if (typeId === undefined) {
9315
- return propValue;
9405
+ return value;
9316
9406
  }
9317
- const value = allocate(container, typeId, propValue);
9407
+ let propValue = allocate(container, typeId, value);
9318
9408
  if (typeId >= TypeIds.Error) {
9319
- inflate(container, value, typeId, propValue);
9409
+ propValue = inflate(container, propValue, typeId, value);
9320
9410
  }
9321
- return value;
9411
+ return propValue;
9322
9412
  }
9323
9413
  function getObjectById(id, stateData) {
9324
9414
  if (typeof id === 'string') {