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

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.cjs 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.6-dev+d848ba5
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
@@ -152,7 +152,7 @@
152
152
  'SsrError(tag): {{0}}', // 29
153
153
  '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
154
154
  'QRLs can not be dynamically resolved, because it does not have a chunk path', // 31
155
- 'The JSX ref attribute must be a Signal', // 32
155
+ '{{0}}\nThe JSX ref attribute must be a Signal', // 32
156
156
  'Serialization Error: Deserialization of data type {{0}} is not implemented', // 33
157
157
  'Serialization Error: Expected vnode for ref prop, but got {{0}}', // 34
158
158
  'Serialization Error: Cannot allocate data type {{0}}', // 35
@@ -160,12 +160,11 @@
160
160
  'Serialization Error: Serialization of data type {{0}} is not implemented', // 37
161
161
  'Serialization Error: Unvisited {{0}}', // 38
162
162
  'Serialization Error: Missing QRL chunk for {{0}}', // 39
163
- 'The value of the textarea must be a string', // 40
163
+ '{{0}}\nThe value of the textarea must be a string found {{1}}', // 40
164
164
  'Unable to find q:container', // 41
165
165
  "Element must have 'q:container' attribute.", // 42
166
166
  'Unknown vnode type {{0}}.', // 43
167
167
  'Materialize error: missing element: {{0}} {{1}} {{2}}', // 44
168
- 'SsrError: {{0}}', // 45
169
168
  'Cannot coerce a Signal, use `.value` instead', // 46
170
169
  'useComputedSignal$ QRL {{0}} {{1}} returned a Promise', // 47
171
170
  'ComputedSignal is read-only', // 48
@@ -237,19 +236,130 @@
237
236
  QError[QError["elementWithoutContainer"] = 42] = "elementWithoutContainer";
238
237
  QError[QError["invalidVNodeType"] = 43] = "invalidVNodeType";
239
238
  QError[QError["materializeVNodeDataError"] = 44] = "materializeVNodeDataError";
240
- QError[QError["serverHostMismatch"] = 45] = "serverHostMismatch";
241
- QError[QError["cannotCoerceSignal"] = 46] = "cannotCoerceSignal";
242
- QError[QError["computedNotSync"] = 47] = "computedNotSync";
243
- QError[QError["computedReadOnly"] = 48] = "computedReadOnly";
244
- QError[QError["wrappedReadOnly"] = 49] = "wrappedReadOnly";
245
- QError[QError["promisesNotExpected"] = 50] = "promisesNotExpected";
246
- QError[QError["unsafeAttr"] = 51] = "unsafeAttr";
239
+ QError[QError["cannotCoerceSignal"] = 45] = "cannotCoerceSignal";
240
+ QError[QError["computedNotSync"] = 46] = "computedNotSync";
241
+ QError[QError["computedReadOnly"] = 47] = "computedReadOnly";
242
+ QError[QError["wrappedReadOnly"] = 48] = "wrappedReadOnly";
243
+ QError[QError["promisesNotExpected"] = 49] = "promisesNotExpected";
244
+ QError[QError["unsafeAttr"] = 50] = "unsafeAttr";
247
245
  })(QError || (QError = {}));
248
246
  const qError = (code, errorMessageArgs = []) => {
249
247
  const text = codeToText(code, ...errorMessageArgs);
250
248
  return logErrorAndStop(text, ...errorMessageArgs);
251
249
  };
252
250
 
251
+ /**
252
+ * A friendly name tag for a VirtualVNode.
253
+ *
254
+ * Theses are used to give a name to a VirtualVNode. This is useful for debugging and testing.
255
+ *
256
+ * The name is only added in development mode and is not included in production builds.
257
+ */
258
+ const DEBUG_TYPE = 'q:type';
259
+ var VirtualType;
260
+ (function (VirtualType) {
261
+ VirtualType["Virtual"] = "V";
262
+ VirtualType["Fragment"] = "F";
263
+ VirtualType["WrappedSignal"] = "S";
264
+ VirtualType["Awaited"] = "A";
265
+ VirtualType["Component"] = "C";
266
+ VirtualType["InlineComponent"] = "I";
267
+ VirtualType["Projection"] = "P";
268
+ })(VirtualType || (VirtualType = {}));
269
+ const START = '\x1b[34m';
270
+ const END = '\x1b[0m';
271
+ const VirtualTypeName = {
272
+ [VirtualType.Virtual]: /* ********* */ START + 'Virtual' + END, //
273
+ [VirtualType.Fragment]: /* ******** */ START + 'Fragment' + END, //
274
+ [VirtualType.WrappedSignal]: /* *** */ START + 'Signal' + END, //
275
+ [VirtualType.Awaited]: /* ********* */ START + 'Awaited' + END, //
276
+ [VirtualType.Component]: /* ******* */ START + 'Component' + END, //
277
+ [VirtualType.InlineComponent]: /* * */ START + 'InlineComponent' + END, //
278
+ [VirtualType.Projection]: /* ****** */ START + 'Projection' + END, //
279
+ };
280
+ var QContainerValue;
281
+ (function (QContainerValue) {
282
+ QContainerValue["PAUSED"] = "paused";
283
+ QContainerValue["RESUMED"] = "resumed";
284
+ // these values below are used in the qwik loader as a plain text for the q:container selector
285
+ // standard dangerouslySetInnerHTML
286
+ QContainerValue["HTML"] = "html";
287
+ // textarea
288
+ QContainerValue["TEXT"] = "text";
289
+ })(QContainerValue || (QContainerValue = {}));
290
+
291
+ /** State factory of the component. */
292
+ const OnRenderProp = 'q:renderFn';
293
+ /** Component style content prefix */
294
+ const ComponentStylesPrefixContent = '⭐️';
295
+ /** `<some-element q:slot="...">` */
296
+ const QSlot = 'q:slot';
297
+ const QSlotParent = ':';
298
+ const QSlotRef = 'q:sref';
299
+ const QSlotS = 'q:s';
300
+ const QStyle = 'q:style';
301
+ const QStyleSelector = 'style[q\\:style]';
302
+ const QStyleSSelector = 'style[q\\:sstyle]';
303
+ const QStylesAllSelector = QStyleSelector + ',' + QStyleSSelector;
304
+ const QScopedStyle = 'q:sstyle';
305
+ const QCtxAttr = 'q:ctx';
306
+ const QSubscribers = 'q:subs';
307
+ const QFuncsPrefix = 'qFuncs_';
308
+ const getQFuncs = (document, hash) => {
309
+ return document[QFuncsPrefix + hash] || [];
310
+ };
311
+ const QBaseAttr = 'q:base';
312
+ const QLocaleAttr = 'q:locale';
313
+ const QManifestHashAttr = 'q:manifest-hash';
314
+ const QInstanceAttr = 'q:instance';
315
+ const QContainerIsland = 'q:container-island';
316
+ const QContainerIslandEnd = '/' + QContainerIsland;
317
+ const QIgnore = 'q:ignore';
318
+ const QIgnoreEnd = '/' + QIgnore;
319
+ const QContainerAttr = 'q:container';
320
+ const QContainerAttrEnd = '/' + QContainerAttr;
321
+ const QTemplate = 'q:template';
322
+ // the same selector should be inside the qwik loader
323
+ // and the same selector should be inside the qwik router spa-shim and spa-init
324
+ const QContainerSelector = '[q\\:container]:not([q\\:container=' +
325
+ QContainerValue.HTML +
326
+ ']):not([q\\:container=' +
327
+ QContainerValue.TEXT +
328
+ '])';
329
+ const HTML_NS = 'http://www.w3.org/1999/xhtml';
330
+ const SVG_NS = 'http://www.w3.org/2000/svg';
331
+ const MATH_NS = 'http://www.w3.org/1998/Math/MathML';
332
+ const ResourceEvent = 'qResource';
333
+ const RenderEvent = 'qRender';
334
+ const TaskEvent = 'qTask';
335
+ const QDefaultSlot = '';
336
+ /**
337
+ * Attribute to mark that this VNode has a pointer to itself from the `qwik/json` state.
338
+ *
339
+ * As the VNode get materialized the vnode now becomes eligible for mutation. Once the vnode mutates
340
+ * the `VNode` references from the `qwik/json` may become invalid. For this reason, these references
341
+ * need to be eagerly resolved. `VNODE_REF` stores a pointer to "this" vnode. This allows the system
342
+ * to eagerly resolve these pointes as the vnodes are materialized.
343
+ */
344
+ const ELEMENT_ID = 'q:id';
345
+ const ELEMENT_KEY = 'q:key';
346
+ const ELEMENT_PROPS = 'q:props';
347
+ const ELEMENT_SEQ = 'q:seq';
348
+ const ELEMENT_SEQ_IDX = 'q:seqIdx';
349
+ const Q_PREFIX = 'q:';
350
+ /** Non serializable markers - always begins with `:` character */
351
+ const NON_SERIALIZABLE_MARKER_PREFIX = ':';
352
+ const USE_ON_LOCAL = NON_SERIALIZABLE_MARKER_PREFIX + 'on';
353
+ const USE_ON_LOCAL_SEQ_IDX = NON_SERIALIZABLE_MARKER_PREFIX + 'onIdx';
354
+ const USE_ON_LOCAL_FLAGS = NON_SERIALIZABLE_MARKER_PREFIX + 'onFlags';
355
+ // comment nodes
356
+ const FLUSH_COMMENT = 'qkssr-f';
357
+ const STREAM_BLOCK_START_COMMENT = 'qkssr-pu';
358
+ const STREAM_BLOCK_END_COMMENT = 'qkssr-po';
359
+ const Q_PROPS_SEPARATOR = ':';
360
+ const dangerouslySetInnerHTML = 'dangerouslySetInnerHTML';
361
+ const qwikInspectorAttr = 'data-qwik-inspector';
362
+
253
363
  // keep this import from core/build so the cjs build works
254
364
  const createPlatform = () => {
255
365
  return {
@@ -310,7 +420,7 @@
310
420
  */
311
421
  const toUrl = (doc, containerEl, url) => {
312
422
  const baseURI = doc.baseURI;
313
- const base = new URL(containerEl.getAttribute('q:base') ?? baseURI, baseURI);
423
+ const base = new URL(containerEl.getAttribute(QBaseAttr) ?? baseURI, baseURI);
314
424
  return new URL(url, base);
315
425
  };
316
426
  let _platform = /*#__PURE__ */ createPlatform();
@@ -402,15 +512,24 @@
402
512
  setTimeout(resolve, timeout);
403
513
  });
404
514
  };
515
+ // Retries a function that throws a promise.
405
516
  function retryOnPromise(fn, retryCount = 0) {
406
- try {
407
- return fn();
408
- }
409
- catch (e) {
517
+ const retryOrThrow = (e) => {
410
518
  if (isPromise(e) && retryCount < MAX_RETRY_ON_PROMISE_COUNT) {
411
519
  return e.then(retryOnPromise.bind(null, fn, retryCount++));
412
520
  }
413
521
  throw e;
522
+ };
523
+ try {
524
+ const result = fn();
525
+ if (isPromise(result)) {
526
+ // not awaited promise is not caught by try/catch block
527
+ return result.catch((e) => retryOrThrow(e));
528
+ }
529
+ return result;
530
+ }
531
+ catch (e) {
532
+ return retryOrThrow(e);
414
533
  }
415
534
  }
416
535
 
@@ -453,118 +572,6 @@
453
572
  VNodeDataFlag[VNodeDataFlag["SERIALIZE"] = 16] = "SERIALIZE";
454
573
  })(VNodeDataFlag || (VNodeDataFlag = {}));
455
574
 
456
- /**
457
- * A friendly name tag for a VirtualVNode.
458
- *
459
- * Theses are used to give a name to a VirtualVNode. This is useful for debugging and testing.
460
- *
461
- * The name is only added in development mode and is not included in production builds.
462
- */
463
- const DEBUG_TYPE = 'q:type';
464
- var VirtualType;
465
- (function (VirtualType) {
466
- VirtualType["Virtual"] = "V";
467
- VirtualType["Fragment"] = "F";
468
- VirtualType["WrappedSignal"] = "S";
469
- VirtualType["Awaited"] = "A";
470
- VirtualType["Component"] = "C";
471
- VirtualType["InlineComponent"] = "I";
472
- VirtualType["Projection"] = "P";
473
- })(VirtualType || (VirtualType = {}));
474
- const START = '\x1b[34m';
475
- const END = '\x1b[0m';
476
- const VirtualTypeName = {
477
- [VirtualType.Virtual]: /* ********* */ START + 'Virtual' + END, //
478
- [VirtualType.Fragment]: /* ******** */ START + 'Fragment' + END, //
479
- [VirtualType.WrappedSignal]: /* *** */ START + 'Signal' + END, //
480
- [VirtualType.Awaited]: /* ********* */ START + 'Awaited' + END, //
481
- [VirtualType.Component]: /* ******* */ START + 'Component' + END, //
482
- [VirtualType.InlineComponent]: /* * */ START + 'InlineComponent' + END, //
483
- [VirtualType.Projection]: /* ****** */ START + 'Projection' + END, //
484
- };
485
- var QContainerValue;
486
- (function (QContainerValue) {
487
- QContainerValue["PAUSED"] = "paused";
488
- QContainerValue["RESUMED"] = "resumed";
489
- // these values below are used in the qwik loader as a plain text for the q:container selector
490
- // standard dangerouslySetInnerHTML
491
- QContainerValue["HTML"] = "html";
492
- // textarea
493
- QContainerValue["TEXT"] = "text";
494
- })(QContainerValue || (QContainerValue = {}));
495
-
496
- /** State factory of the component. */
497
- const OnRenderProp = 'q:renderFn';
498
- /** Component style content prefix */
499
- const ComponentStylesPrefixContent = '⭐️';
500
- /** `<some-element q:slot="...">` */
501
- const QSlot = 'q:slot';
502
- const QSlotParent = ':';
503
- const QSlotRef = 'q:sref';
504
- const QSlotS = 'q:s';
505
- const QStyle = 'q:style';
506
- const QStyleSelector = 'style[q\\:style]';
507
- const QStyleSSelector = 'style[q\\:sstyle]';
508
- const QStylesAllSelector = QStyleSelector + ',' + QStyleSSelector;
509
- const QScopedStyle = 'q:sstyle';
510
- const QCtxAttr = 'q:ctx';
511
- const QSubscribers = 'q:subs';
512
- const QFuncsPrefix = 'qFuncs_';
513
- const getQFuncs = (document, hash) => {
514
- return document[QFuncsPrefix + hash] || [];
515
- };
516
- const QBaseAttr = 'q:base';
517
- const QLocaleAttr = 'q:locale';
518
- const QManifestHashAttr = 'q:manifest-hash';
519
- const QInstanceAttr = 'q:instance';
520
- const QContainerIsland = 'q:container-island';
521
- const QContainerIslandEnd = '/' + QContainerIsland;
522
- const QIgnore = 'q:ignore';
523
- const QIgnoreEnd = '/' + QIgnore;
524
- const QContainerAttr = 'q:container';
525
- const QContainerAttrEnd = '/' + QContainerAttr;
526
- const QTemplate = 'q:template';
527
- // the same selector should be inside the qwik loader
528
- // and the same selector should be inside the qwik router spa-shim and spa-init
529
- const QContainerSelector = '[q\\:container]:not([q\\:container=' +
530
- QContainerValue.HTML +
531
- ']):not([q\\:container=' +
532
- QContainerValue.TEXT +
533
- '])';
534
- const HTML_NS = 'http://www.w3.org/1999/xhtml';
535
- const SVG_NS = 'http://www.w3.org/2000/svg';
536
- const MATH_NS = 'http://www.w3.org/1998/Math/MathML';
537
- const ResourceEvent = 'qResource';
538
- const RenderEvent = 'qRender';
539
- const TaskEvent = 'qTask';
540
- const QDefaultSlot = '';
541
- /**
542
- * Attribute to mark that this VNode has a pointer to itself from the `qwik/json` state.
543
- *
544
- * As the VNode get materialized the vnode now becomes eligible for mutation. Once the vnode mutates
545
- * the `VNode` references from the `qwik/json` may become invalid. For this reason, these references
546
- * need to be eagerly resolved. `VNODE_REF` stores a pointer to "this" vnode. This allows the system
547
- * to eagerly resolve these pointes as the vnodes are materialized.
548
- */
549
- const ELEMENT_ID = 'q:id';
550
- const ELEMENT_KEY = 'q:key';
551
- const ELEMENT_PROPS = 'q:props';
552
- const ELEMENT_SEQ = 'q:seq';
553
- const ELEMENT_SEQ_IDX = 'q:seqIdx';
554
- const Q_PREFIX = 'q:';
555
- /** Non serializable markers - always begins with `:` character */
556
- const NON_SERIALIZABLE_MARKER_PREFIX = ':';
557
- const USE_ON_LOCAL = NON_SERIALIZABLE_MARKER_PREFIX + 'on';
558
- const USE_ON_LOCAL_SEQ_IDX = NON_SERIALIZABLE_MARKER_PREFIX + 'onIdx';
559
- const USE_ON_LOCAL_FLAGS = NON_SERIALIZABLE_MARKER_PREFIX + 'onFlags';
560
- // comment nodes
561
- const FLUSH_COMMENT = 'qkssr-f';
562
- const STREAM_BLOCK_START_COMMENT = 'qkssr-pu';
563
- const STREAM_BLOCK_END_COMMENT = 'qkssr-po';
564
- const Q_PROPS_SEPARATOR = ':';
565
- const dangerouslySetInnerHTML = 'dangerouslySetInnerHTML';
566
- const qwikInspectorAttr = 'data-qwik-inspector';
567
-
568
575
  let _locale = undefined;
569
576
  /**
570
577
  * Retrieve the current locale.
@@ -1138,7 +1145,6 @@
1138
1145
  }
1139
1146
  /** In the case of oldValue and value are the same, the effects are not triggered. */
1140
1147
  set(target, prop, value) {
1141
- target = unwrapDeserializerProxy(target);
1142
1148
  if (typeof prop === 'symbol') {
1143
1149
  target[prop] = value;
1144
1150
  return true;
@@ -1207,6 +1213,8 @@
1207
1213
  // to unsubscribe from. So we need to store the reference from the effect back
1208
1214
  // to this signal.
1209
1215
  ensureContains(effectSubscriber, target);
1216
+ // We need to add the subscriber to the effect so that we can clean it up later
1217
+ ensureEffectContainsSubscriber(effectSubscriber[EffectSubscriptionsProp.EFFECT], target, store.$container$);
1210
1218
  }
1211
1219
  function setNewValueAndTriggerEffects(prop, value, target, currentStore) {
1212
1220
  target[prop] = value;
@@ -1277,32 +1285,40 @@
1277
1285
  }
1278
1286
  for (let i = effects.length - 1; i >= 0; i--) {
1279
1287
  const subscriber = effects[i];
1280
- const subscriptionRemoved = clearEffects(subscriber, value);
1281
- if (subscriptionRemoved) {
1282
- effects.splice(i, 1);
1283
- }
1288
+ clearEffects(subscriber, value, effects, i, container);
1289
+ }
1290
+ if (effects.length === 0) {
1291
+ vnode_setProp(value, QSubscribers, null);
1284
1292
  }
1285
1293
  }
1286
- function clearSubscriberEffectDependencies(value) {
1294
+ function clearSubscriberEffectDependencies(container, value) {
1287
1295
  if (value.$effectDependencies$) {
1288
1296
  for (let i = value.$effectDependencies$.length - 1; i >= 0; i--) {
1289
1297
  const subscriber = value.$effectDependencies$[i];
1290
- const subscriptionRemoved = clearEffects(subscriber, value);
1291
- if (subscriptionRemoved) {
1292
- value.$effectDependencies$.splice(i, 1);
1293
- }
1298
+ clearEffects(subscriber, value, value.$effectDependencies$, i, container);
1299
+ }
1300
+ if (value.$effectDependencies$.length === 0) {
1301
+ value.$effectDependencies$ = null;
1294
1302
  }
1295
1303
  }
1296
1304
  }
1297
- function clearEffects(subscriber, value) {
1298
- if (!isSignal(subscriber)) {
1299
- return false;
1305
+ function clearEffects(subscriber, value, effectArray, indexToRemove, container) {
1306
+ let subscriptionRemoved = false;
1307
+ const seenSet = new Set();
1308
+ if (subscriber instanceof WrappedSignal) {
1309
+ subscriptionRemoved = clearSignalEffects(subscriber, value, seenSet);
1300
1310
  }
1301
- const effectSubscriptions = subscriber.$effects$;
1302
- const hostElement = subscriber.$hostElement$;
1303
- if (hostElement && hostElement === value) {
1304
- subscriber.$hostElement$ = null;
1311
+ else if (container.$storeProxyMap$.has(subscriber)) {
1312
+ const store = container.$storeProxyMap$.get(subscriber);
1313
+ const handler = getStoreHandler(store);
1314
+ subscriptionRemoved = clearStoreEffects(handler, value);
1305
1315
  }
1316
+ if (subscriptionRemoved) {
1317
+ effectArray.splice(indexToRemove, 1);
1318
+ }
1319
+ }
1320
+ function clearSignalEffects(subscriber, value, seenSet) {
1321
+ const effectSubscriptions = subscriber.$effects$;
1306
1322
  let subscriptionRemoved = false;
1307
1323
  if (effectSubscriptions) {
1308
1324
  for (let i = effectSubscriptions.length - 1; i >= 0; i--) {
@@ -1313,15 +1329,84 @@
1313
1329
  }
1314
1330
  }
1315
1331
  }
1316
- // clear the effects of the arguments
1317
- const args = subscriber.$args$;
1318
- if (args) {
1319
- for (let i = args.length - 1; i >= 0; i--) {
1320
- clearEffects(args[i], subscriber);
1332
+ if (subscriber instanceof WrappedSignal) {
1333
+ const hostElement = subscriber.$hostElement$;
1334
+ if (hostElement && hostElement === value) {
1335
+ subscriber.$hostElement$ = null;
1336
+ }
1337
+ // clear the effects of the arguments
1338
+ const args = subscriber.$args$;
1339
+ if (args) {
1340
+ clearArgsEffects(args, subscriber, seenSet);
1321
1341
  }
1322
1342
  }
1323
1343
  return subscriptionRemoved;
1324
1344
  }
1345
+ function clearStoreEffects(storeHandler, value) {
1346
+ const effectSubscriptions = storeHandler.$effects$;
1347
+ if (!effectSubscriptions) {
1348
+ return false;
1349
+ }
1350
+ let subscriptionRemoved = false;
1351
+ for (const key in effectSubscriptions) {
1352
+ const effects = effectSubscriptions[key];
1353
+ for (let i = effects.length - 1; i >= 0; i--) {
1354
+ const effect = effects[i];
1355
+ if (effect[EffectSubscriptionsProp.EFFECT] === value) {
1356
+ effects.splice(i, 1);
1357
+ subscriptionRemoved = true;
1358
+ }
1359
+ }
1360
+ if (effects.length === 0) {
1361
+ delete effectSubscriptions[key];
1362
+ }
1363
+ }
1364
+ return subscriptionRemoved;
1365
+ }
1366
+ function clearArgsEffects(args, subscriber, seenSet) {
1367
+ for (let i = args.length - 1; i >= 0; i--) {
1368
+ const arg = args[i];
1369
+ clearArgEffect(arg, subscriber, seenSet);
1370
+ }
1371
+ }
1372
+ function clearArgEffect(arg, subscriber, seenSet) {
1373
+ if (seenSet.has(arg)) {
1374
+ return;
1375
+ }
1376
+ seenSet.add(arg);
1377
+ if (isSignal(arg)) {
1378
+ clearSignalEffects(arg, subscriber, seenSet);
1379
+ }
1380
+ else if (typeof arg === 'object' && arg !== null) {
1381
+ if (isStore(arg)) {
1382
+ clearStoreEffects(getStoreHandler(arg), subscriber);
1383
+ }
1384
+ else if (isPropsProxy(arg)) {
1385
+ // Separate check for props proxy, because props proxy getter could call signal getter.
1386
+ // To avoid that we need to get the constProps and varProps directly
1387
+ // from the props proxy object and loop over them.
1388
+ const constProps = arg[_CONST_PROPS];
1389
+ const varProps = arg[_VAR_PROPS];
1390
+ if (constProps) {
1391
+ for (const key in constProps) {
1392
+ clearArgEffect(constProps[key], subscriber, seenSet);
1393
+ }
1394
+ }
1395
+ for (const key in varProps) {
1396
+ clearArgEffect(varProps[key], subscriber, seenSet);
1397
+ }
1398
+ }
1399
+ else {
1400
+ for (const key in arg) {
1401
+ clearArgEffect(arg[key], subscriber, seenSet);
1402
+ }
1403
+ }
1404
+ }
1405
+ else if (Array.isArray(arg)) {
1406
+ clearArgsEffects(arg, subscriber, seenSet);
1407
+ }
1408
+ else ;
1409
+ }
1325
1410
 
1326
1411
  /** @internal */
1327
1412
  const useResourceQrl = (qrl, opts) => {
@@ -1408,14 +1493,17 @@
1408
1493
  // create a subscription for the resource._state changes
1409
1494
  const state = resource._state;
1410
1495
  if (state === 'pending' && props.onPending) {
1411
- return Promise.resolve(props.onPending());
1496
+ return Promise.resolve().then(useBindInvokeContext(props.onPending));
1412
1497
  }
1413
1498
  else if (state === 'rejected' && props.onRejected) {
1414
- return Promise.resolve(resource._error).then(props.onRejected);
1499
+ return Promise.resolve(resource._error).then(useBindInvokeContext(props.onRejected));
1415
1500
  }
1416
1501
  else {
1417
- // resolved, pending without onPending prop or rejected with onRejected prop
1418
- return Promise.resolve(untrack(() => resource._resolved)).then(props.onResolved);
1502
+ const resolvedValue = untrack(() => resource._resolved);
1503
+ if (resolvedValue !== undefined) {
1504
+ // resolved, pending without onPending prop or rejected without onRejected prop
1505
+ return Promise.resolve(resolvedValue).then(useBindInvokeContext(props.onResolved));
1506
+ }
1419
1507
  }
1420
1508
  }
1421
1509
  return resource.value.then(useBindInvokeContext(props.onResolved), useBindInvokeContext(props.onRejected));
@@ -1456,7 +1544,7 @@
1456
1544
  cleanupTask(task);
1457
1545
  const iCtx = newInvokeContext(container.$locale$, host, undefined, ResourceEvent);
1458
1546
  iCtx.$container$ = container;
1459
- const taskFn = task.$qrl$.getFn(iCtx, () => clearSubscriberEffectDependencies(task));
1547
+ const taskFn = task.$qrl$.getFn(iCtx, () => clearSubscriberEffectDependencies(container, task));
1460
1548
  const resource = task.$state$;
1461
1549
  assertDefined(resource, 'useResource: when running a resource, "task.resource" must be a defined.', task);
1462
1550
  const track = (obj, prop) => {
@@ -2257,6 +2345,17 @@
2257
2345
  }
2258
2346
  }
2259
2347
 
2348
+ function getFileLocationFromJsx(jsxDev) {
2349
+ if (!jsxDev) {
2350
+ return null;
2351
+ }
2352
+ const sanitizedFileName = jsxDev.fileName?.replace(/\\/g, '/');
2353
+ if (sanitizedFileName) {
2354
+ return `${sanitizedFileName}:${jsxDev.lineNumber}:${jsxDev.columnNumber}`;
2355
+ }
2356
+ return null;
2357
+ }
2358
+
2260
2359
  const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
2261
2360
  let journal = container.$journal$;
2262
2361
  /**
@@ -2700,7 +2799,7 @@
2700
2799
  *
2701
2800
  * @returns {boolean}
2702
2801
  */
2703
- function createNewElement(jsx, elementName) {
2802
+ function createNewElement(jsx, elementName, currentFile) {
2704
2803
  const element = createElementWithNamespace(elementName);
2705
2804
  const { constProps } = jsx;
2706
2805
  let needsQDispatchEventPatch = false;
@@ -2731,6 +2830,9 @@
2731
2830
  value(element);
2732
2831
  continue;
2733
2832
  }
2833
+ else {
2834
+ throw qError(QError.invalidRefValue, [currentFile]);
2835
+ }
2734
2836
  }
2735
2837
  if (isSignal(value)) {
2736
2838
  const signalData = new EffectPropData({
@@ -2745,13 +2847,13 @@
2745
2847
  continue;
2746
2848
  }
2747
2849
  if (elementName === 'textarea' && key === 'value') {
2748
- if (typeof value !== 'string') {
2850
+ if (value && typeof value !== 'string') {
2749
2851
  if (build.isDev) {
2750
- throw qError(QError.wrongTextareaValue);
2852
+ throw qError(QError.wrongTextareaValue, [currentFile, value]);
2751
2853
  }
2752
2854
  continue;
2753
2855
  }
2754
- element.value = escapeHTML(value);
2856
+ element.value = escapeHTML(value || '');
2755
2857
  continue;
2756
2858
  }
2757
2859
  value = serializeAttribute(key, value, scopedStyleIdPrefix);
@@ -2785,6 +2887,7 @@
2785
2887
  const isSameElementName = vCurrent && vnode_isElementVNode(vCurrent) && elementName === vnode_getElementName(vCurrent);
2786
2888
  const jsxKey = jsx.key;
2787
2889
  let needsQDispatchEventPatch = false;
2890
+ const currentFile = getFileLocationFromJsx(jsx.dev);
2788
2891
  if (!isSameElementName || jsxKey !== getKey(vCurrent)) {
2789
2892
  // So we have a key and it does not match the current node.
2790
2893
  // We need to do a forward search to find it.
@@ -2797,14 +2900,21 @@
2797
2900
  else {
2798
2901
  // Existing keyed node
2799
2902
  vnode_insertBefore(journal, vParent, vNewNode, vCurrent);
2903
+ // We are here, so jsx is different from the vCurrent, so now we want to point to the moved node.
2904
+ vCurrent = vNewNode;
2905
+ // We need to clean up the vNewNode, because we don't want to skip advance to next sibling (see `advance` function).
2906
+ vNewNode = null;
2907
+ // We need also to go back to the previous sibling, because we assigned previous sibling to the vCurrent.
2908
+ if (vSiblings !== null) {
2909
+ vSiblingsIdx -= SiblingsArray.Size;
2910
+ }
2800
2911
  }
2801
2912
  }
2802
2913
  // reconcile attributes
2803
2914
  const jsxAttrs = [];
2804
2915
  const props = jsx.varProps;
2805
2916
  for (const key in props) {
2806
- let value = props[key];
2807
- value = serializeAttribute(key, value, scopedStyleIdPrefix);
2917
+ const value = props[key];
2808
2918
  if (value != null) {
2809
2919
  mapArray_set(jsxAttrs, key, value, 0);
2810
2920
  }
@@ -2813,7 +2923,8 @@
2813
2923
  mapArray_set(jsxAttrs, ELEMENT_KEY, jsxKey, 0);
2814
2924
  }
2815
2925
  const vNode = (vNewNode || vCurrent);
2816
- needsQDispatchEventPatch = setBulkProps(vNode, jsxAttrs) || needsQDispatchEventPatch;
2926
+ needsQDispatchEventPatch =
2927
+ setBulkProps(vNode, jsxAttrs, currentFile) || needsQDispatchEventPatch;
2817
2928
  if (needsQDispatchEventPatch) {
2818
2929
  // Event handler needs to be patched onto the element.
2819
2930
  const element = vnode_getNode(vNode);
@@ -2838,7 +2949,7 @@
2838
2949
  }
2839
2950
  }
2840
2951
  /** @param tag Returns true if `qDispatchEvent` needs patching */
2841
- function setBulkProps(vnode, srcAttrs) {
2952
+ function setBulkProps(vnode, srcAttrs, currentFile) {
2842
2953
  vnode_ensureElementInflated(vnode);
2843
2954
  const dstAttrs = vnode;
2844
2955
  let srcIdx = 0;
@@ -2863,11 +2974,18 @@
2863
2974
  value(element);
2864
2975
  return;
2865
2976
  }
2977
+ else {
2978
+ throw qError(QError.invalidRefValue, [currentFile]);
2979
+ }
2866
2980
  }
2867
2981
  if (isSignal(value)) {
2868
- value = untrack(() => value.value);
2982
+ const signalData = new EffectPropData({
2983
+ $scopedStyleIdPrefix$: scopedStyleIdPrefix,
2984
+ $isConst$: false,
2985
+ });
2986
+ value = trackSignalAndAssignHost(value, vnode, key, container, signalData);
2869
2987
  }
2870
- vnode_setAttr(journal, vnode, key, value);
2988
+ vnode_setAttr(journal, vnode, key, serializeAttribute(key, value, scopedStyleIdPrefix));
2871
2989
  if (value === null) {
2872
2990
  // if we set `null` than attribute was removed and we need to shorten the dstLength
2873
2991
  dstLength = dstAttrs.length;
@@ -2923,6 +3041,10 @@
2923
3041
  }
2924
3042
  srcIdx++;
2925
3043
  srcKey = srcIdx < srcLength ? srcAttrs[srcIdx++] : null;
3044
+ // we need to increment dstIdx too, because we added destination key and value to the VNode
3045
+ // and dstAttrs is a reference to the VNode
3046
+ dstIdx++;
3047
+ dstKey = dstIdx < dstLength ? dstAttrs[dstIdx++] : null;
2926
3048
  }
2927
3049
  else if (srcKey == dstKey) {
2928
3050
  const srcValue = srcAttrs[srcIdx++];
@@ -3040,7 +3162,7 @@
3040
3162
  vNewNode = retrieveChildWithKey(null, jsxKey);
3041
3163
  if (vNewNode != null) {
3042
3164
  // We found it, move it up.
3043
- vnode_insertBefore(journal, vParent, (vNewNode = vnode_newVirtual()), vCurrent && getInsertBefore());
3165
+ vnode_insertBefore(journal, vParent, vNewNode, vCurrent && getInsertBefore());
3044
3166
  return;
3045
3167
  }
3046
3168
  }
@@ -3282,7 +3404,7 @@
3282
3404
  const obj = seq[i];
3283
3405
  if (isTask(obj)) {
3284
3406
  const task = obj;
3285
- clearSubscriberEffectDependencies(task);
3407
+ clearSubscriberEffectDependencies(container, task);
3286
3408
  if (task.$flags$ & TaskFlags.VISIBLE_TASK) {
3287
3409
  container.$scheduler$(ChoreType.CLEANUP_VISIBLE, task);
3288
3410
  }
@@ -3483,6 +3605,108 @@
3483
3605
  */
3484
3606
  const createComputed$ = /*#__PURE__*/ implicit$FirstArg(createComputedQrl);
3485
3607
 
3608
+ /// These global variables are used to avoid creating new arrays for each call to `vnode_documentPosition`.
3609
+ const aVNodePath = [];
3610
+ const bVNodePath = [];
3611
+ /**
3612
+ * Compare two VNodes and determine their document position relative to each other.
3613
+ *
3614
+ * @param a VNode to compare
3615
+ * @param b VNode to compare
3616
+ * @param rootVNode - Root VNode of a container
3617
+ * @returns -1 if `a` is before `b`, 0 if `a` is the same as `b`, 1 if `a` is after `b`.
3618
+ */
3619
+ const vnode_documentPosition = (a, b, rootVNode) => {
3620
+ if (a === b) {
3621
+ return 0;
3622
+ }
3623
+ let aDepth = -1;
3624
+ let bDepth = -1;
3625
+ while (a) {
3626
+ const vNode = (aVNodePath[++aDepth] = a);
3627
+ a = (vNode[VNodeProps.parent] ||
3628
+ (rootVNode && vnode_getProp(a, QSlotParent, (id) => vnode_locate(rootVNode, id))));
3629
+ }
3630
+ while (b) {
3631
+ const vNode = (bVNodePath[++bDepth] = b);
3632
+ b = (vNode[VNodeProps.parent] ||
3633
+ (rootVNode && vnode_getProp(b, QSlotParent, (id) => vnode_locate(rootVNode, id))));
3634
+ }
3635
+ while (aDepth >= 0 && bDepth >= 0) {
3636
+ a = aVNodePath[aDepth];
3637
+ b = bVNodePath[bDepth];
3638
+ if (a === b) {
3639
+ // if the nodes are the same, we need to check the next level.
3640
+ aDepth--;
3641
+ bDepth--;
3642
+ }
3643
+ else {
3644
+ // We found a difference so we need to scan nodes at this level.
3645
+ let cursor = b;
3646
+ do {
3647
+ cursor = vnode_getNextSibling(cursor);
3648
+ if (cursor === a) {
3649
+ return 1;
3650
+ }
3651
+ } while (cursor);
3652
+ cursor = b;
3653
+ do {
3654
+ cursor = vnode_getPreviousSibling(cursor);
3655
+ if (cursor === a) {
3656
+ return -1;
3657
+ }
3658
+ } while (cursor);
3659
+ if (rootVNode && vnode_getProp(b, QSlotParent, (id) => vnode_locate(rootVNode, id))) {
3660
+ // The "b" node is a projection, so we need to set it after "a" node,
3661
+ // because the "a" node could be a context provider.
3662
+ return -1;
3663
+ }
3664
+ // The node is not in the list of siblings, that means it must be disconnected.
3665
+ return 1;
3666
+ }
3667
+ }
3668
+ return aDepth < bDepth ? -1 : 1;
3669
+ };
3670
+ /// These global variables are used to avoid creating new arrays for each call to `ssrNodeDocumentPosition`.
3671
+ const aSsrNodePath = [];
3672
+ const bSsrNodePath = [];
3673
+ /**
3674
+ * Compare two SSR nodes and determine their document position relative to each other. Compares only
3675
+ * position between parent and child.
3676
+ *
3677
+ * @param a SSR node to compare
3678
+ * @param b SSR node to compare
3679
+ * @returns -1 if `a` is before `b`, 0 if `a` is the same as `b`, 1 if `a` is after `b`.
3680
+ */
3681
+ const ssrNodeDocumentPosition = (a, b) => {
3682
+ if (a === b) {
3683
+ return 0;
3684
+ }
3685
+ let aDepth = -1;
3686
+ let bDepth = -1;
3687
+ while (a) {
3688
+ const ssrNode = (aSsrNodePath[++aDepth] = a);
3689
+ a = ssrNode.currentComponentNode;
3690
+ }
3691
+ while (b) {
3692
+ const ssrNode = (bSsrNodePath[++bDepth] = b);
3693
+ b = ssrNode.currentComponentNode;
3694
+ }
3695
+ while (aDepth >= 0 && bDepth >= 0) {
3696
+ a = aSsrNodePath[aDepth];
3697
+ b = bSsrNodePath[bDepth];
3698
+ if (a === b) {
3699
+ // if the nodes are the same, we need to check the next level.
3700
+ aDepth--;
3701
+ bDepth--;
3702
+ }
3703
+ else {
3704
+ return 1;
3705
+ }
3706
+ }
3707
+ return aDepth < bDepth ? -1 : 1;
3708
+ };
3709
+
3486
3710
  /**
3487
3711
  * Scheduler is responsible for running application code in predictable order.
3488
3712
  *
@@ -3615,7 +3839,7 @@
3615
3839
  $executed$: false,
3616
3840
  };
3617
3841
  chore.$promise$ = new Promise((resolve) => (chore.$resolve$ = resolve));
3618
- chore = sortedInsert(choreQueue, chore);
3842
+ chore = sortedInsert(choreQueue, chore, container.rootVNode || null);
3619
3843
  if (!journalFlushScheduled && runLater) {
3620
3844
  // If we are not currently draining, we need to schedule a drain.
3621
3845
  journalFlushScheduled = true;
@@ -3626,7 +3850,7 @@
3626
3850
  return chore.$promise$;
3627
3851
  }
3628
3852
  else {
3629
- return drainUpTo(chore);
3853
+ return drainUpTo(chore, container.rootVNode || null);
3630
3854
  }
3631
3855
  }
3632
3856
  /**
@@ -3634,7 +3858,7 @@
3634
3858
  *
3635
3859
  * @param runUptoChore
3636
3860
  */
3637
- function drainUpTo(runUptoChore) {
3861
+ function drainUpTo(runUptoChore, rootVNode) {
3638
3862
  // If it already ran, it's not in the queue
3639
3863
  if (runUptoChore.$executed$) {
3640
3864
  return runUptoChore.$returnValue$;
@@ -3645,7 +3869,7 @@
3645
3869
  }
3646
3870
  while (choreQueue.length) {
3647
3871
  const nextChore = choreQueue.shift();
3648
- const order = choreComparator(nextChore, runUptoChore, false);
3872
+ const order = choreComparator(nextChore, runUptoChore, rootVNode);
3649
3873
  if (order === null) {
3650
3874
  continue;
3651
3875
  }
@@ -3661,7 +3885,7 @@
3661
3885
  }
3662
3886
  const returnValue = executeChore(nextChore);
3663
3887
  if (isPromise(returnValue)) {
3664
- const promise = returnValue.then(() => drainUpTo(runUptoChore));
3888
+ const promise = returnValue.then(() => drainUpTo(runUptoChore, rootVNode));
3665
3889
  return promise;
3666
3890
  }
3667
3891
  }
@@ -3682,7 +3906,7 @@
3682
3906
  returnValue = safeCall(() => executeComponent(container, host, host, chore.$target$, chore.$payload$), (jsx) => {
3683
3907
  if (chore.$type$ === ChoreType.COMPONENT) {
3684
3908
  const styleScopedId = container.getHostProp(host, QScopedStyle);
3685
- return vnode_diff(container, jsx, host, addComponentStylePrefix(styleScopedId));
3909
+ return retryOnPromise(() => vnode_diff(container, jsx, host, addComponentStylePrefix(styleScopedId)));
3686
3910
  }
3687
3911
  else {
3688
3912
  return jsx;
@@ -3713,7 +3937,7 @@
3713
3937
  if (isSignal(jsx)) {
3714
3938
  jsx = jsx.value;
3715
3939
  }
3716
- returnValue = vnode_diff(container, jsx, parentVirtualNode, null);
3940
+ returnValue = retryOnPromise(() => vnode_diff(container, jsx, parentVirtualNode, null));
3717
3941
  break;
3718
3942
  case ChoreType.NODE_PROP:
3719
3943
  const virtualNode = chore.$host$;
@@ -3782,7 +4006,15 @@
3782
4006
  vnode_isVNode(chore.$host$) &&
3783
4007
  chore.$host$[VNodeProps.flags] & VNodeFlags.Deleted);
3784
4008
  }
3785
- function choreComparator(a, b, shouldThrowOnHostMismatch) {
4009
+ /**
4010
+ * Compares two chores to determine their execution order in the scheduler's queue.
4011
+ *
4012
+ * @param a - The first chore to compare
4013
+ * @param b - The second chore to compare
4014
+ * @returns A number indicating the relative order of the chores. A negative number means `a` runs
4015
+ * before `b`.
4016
+ */
4017
+ function choreComparator(a, b, rootVNode) {
3786
4018
  const macroTypeDiff = (a.$type$ & ChoreType.MACRO) - (b.$type$ & ChoreType.MACRO);
3787
4019
  if (macroTypeDiff !== 0) {
3788
4020
  return macroTypeDiff;
@@ -3795,7 +4027,7 @@
3795
4027
  if (aHost !== bHost && aHost !== null && bHost !== null) {
3796
4028
  if (vnode_isVNode(aHost) && vnode_isVNode(bHost)) {
3797
4029
  // we are running on the client.
3798
- const hostDiff = vnode_documentPosition(aHost, bHost);
4030
+ const hostDiff = vnode_documentPosition(aHost, bHost, rootVNode);
3799
4031
  if (hostDiff !== 0) {
3800
4032
  return hostDiff;
3801
4033
  }
@@ -3809,11 +4041,11 @@
3809
4041
  You are attempting to change a state that has already been streamed to the client.
3810
4042
  This can lead to inconsistencies between Server-Side Rendering (SSR) and Client-Side Rendering (CSR).
3811
4043
  Problematic Node: ${aHost.toString()}`;
3812
- if (shouldThrowOnHostMismatch) {
3813
- throw qError(QError.serverHostMismatch, [errorMessage]);
3814
- }
3815
4044
  logWarn(errorMessage);
3816
- return null;
4045
+ const hostDiff = ssrNodeDocumentPosition(aHost, bHost);
4046
+ if (hostDiff !== 0) {
4047
+ return hostDiff;
4048
+ }
3817
4049
  }
3818
4050
  }
3819
4051
  const microTypeDiff = (a.$type$ & ChoreType.MICRO) - (b.$type$ & ChoreType.MICRO);
@@ -3836,7 +4068,7 @@
3836
4068
  }
3837
4069
  return 0;
3838
4070
  }
3839
- function sortedFindIndex(sortedArray, value) {
4071
+ function sortedFindIndex(sortedArray, value, rootVNode) {
3840
4072
  /// We need to ensure that the `queue` is sorted by priority.
3841
4073
  /// 1. Find a place where to insert into.
3842
4074
  let bottom = 0;
@@ -3844,7 +4076,7 @@
3844
4076
  while (bottom < top) {
3845
4077
  const middle = bottom + ((top - bottom) >> 1);
3846
4078
  const midChore = sortedArray[middle];
3847
- const comp = choreComparator(value, midChore, true);
4079
+ const comp = choreComparator(value, midChore, rootVNode);
3848
4080
  if (comp < 0) {
3849
4081
  top = middle;
3850
4082
  }
@@ -3858,10 +4090,10 @@
3858
4090
  }
3859
4091
  return ~bottom;
3860
4092
  }
3861
- function sortedInsert(sortedArray, value) {
4093
+ function sortedInsert(sortedArray, value, rootVNode) {
3862
4094
  /// We need to ensure that the `queue` is sorted by priority.
3863
4095
  /// 1. Find a place where to insert into.
3864
- const idx = sortedFindIndex(sortedArray, value);
4096
+ const idx = sortedFindIndex(sortedArray, value, rootVNode);
3865
4097
  if (idx < 0) {
3866
4098
  /// 2. Insert the chore into the queue.
3867
4099
  sortedArray.splice(~idx, 0, value);
@@ -3939,7 +4171,7 @@
3939
4171
  cleanupTask(task);
3940
4172
  const iCtx = newInvokeContext(container.$locale$, host, undefined, TaskEvent);
3941
4173
  iCtx.$container$ = container;
3942
- const taskFn = task.$qrl$.getFn(iCtx, () => clearSubscriberEffectDependencies(task));
4174
+ const taskFn = task.$qrl$.getFn(iCtx, () => clearSubscriberEffectDependencies(container, task));
3943
4175
  const track = (obj, prop) => {
3944
4176
  const ctx = newInvokeContext();
3945
4177
  ctx.$effectSubscriber$ = [task, EffectProperty.COMPONENT];
@@ -4571,7 +4803,7 @@
4571
4803
  appendClassIfScopedStyleExists(jsx, options.styleScoped);
4572
4804
  let qwikInspectorAttrValue = null;
4573
4805
  if (build.isDev && jsx.dev && jsx.type !== 'head') {
4574
- qwikInspectorAttrValue = getQwikInspectorAttributeValue(jsx.dev);
4806
+ qwikInspectorAttrValue = getFileLocationFromJsx(jsx.dev);
4575
4807
  if (qInspector) {
4576
4808
  appendQwikInspectorAttribute(jsx, qwikInspectorAttrValue);
4577
4809
  }
@@ -4845,13 +5077,6 @@
4845
5077
  }
4846
5078
  return directGetPropsProxyProp(jsx, 'name') || QDefaultSlot;
4847
5079
  }
4848
- function getQwikInspectorAttributeValue(jsxDev) {
4849
- const sanitizedFileName = jsxDev.fileName?.replace(/\\/g, '/');
4850
- if (sanitizedFileName) {
4851
- return `${sanitizedFileName}:${jsxDev.lineNumber}:${jsxDev.columnNumber}`;
4852
- }
4853
- return null;
4854
- }
4855
5080
  function appendQwikInspectorAttribute(jsx, qwikInspectorAttrValue) {
4856
5081
  if (qwikInspectorAttrValue && (!jsx.constProps || !(qwikInspectorAttr in jsx.constProps))) {
4857
5082
  (jsx.constProps ||= {})[qwikInspectorAttr] = qwikInspectorAttrValue;
@@ -4873,7 +5098,7 @@
4873
5098
  *
4874
5099
  * @public
4875
5100
  */
4876
- const version = "2.0.0-alpha.4-dev+374e0d6";
5101
+ const version = "2.0.0-alpha.6-dev+d848ba5";
4877
5102
 
4878
5103
  /** @internal */
4879
5104
  class _SharedContainer {
@@ -6764,7 +6989,7 @@
6764
6989
  assertTrue(vnode_isTextVNode(vnode), 'Expecting Text Node.');
6765
6990
  return vnode[TextVNodeProps.node];
6766
6991
  };
6767
- function vnode_toString(depth = 10, offset = '', materialize = false, siblings = false) {
6992
+ function vnode_toString(depth = 20, offset = '', materialize = false, siblings = false) {
6768
6993
  let vnode = this;
6769
6994
  if (depth === 0) {
6770
6995
  return '...';
@@ -6981,51 +7206,6 @@
6981
7206
  throw qError(QError.invalidVNodeType, [type]);
6982
7207
  };
6983
7208
  const isElement = (node) => node && typeof node == 'object' && fastNodeType(node) === /** Node.ELEMENT_NODE* */ 1;
6984
- /// These global variables are used to avoid creating new arrays for each call to `vnode_getPathToClosestDomNode`.
6985
- const aPath = [];
6986
- const bPath = [];
6987
- const vnode_documentPosition = (a, b) => {
6988
- if (a === b) {
6989
- return 0;
6990
- }
6991
- let aDepth = -1;
6992
- let bDepth = -1;
6993
- while (a) {
6994
- a = (aPath[++aDepth] = a)[VNodeProps.parent];
6995
- }
6996
- while (b) {
6997
- b = (bPath[++bDepth] = b)[VNodeProps.parent];
6998
- }
6999
- while (aDepth >= 0 && bDepth >= 0) {
7000
- a = aPath[aDepth];
7001
- b = bPath[bDepth];
7002
- if (a === b) {
7003
- // if the nodes are the same, we need to check the next level.
7004
- aDepth--;
7005
- bDepth--;
7006
- }
7007
- else {
7008
- // We found a difference so we need to scan nodes at this level.
7009
- let cursor = b;
7010
- do {
7011
- cursor = vnode_getNextSibling(cursor);
7012
- if (cursor === a) {
7013
- return 1;
7014
- }
7015
- } while (cursor);
7016
- cursor = b;
7017
- do {
7018
- cursor = vnode_getPreviousSibling(cursor);
7019
- if (cursor === a) {
7020
- return -1;
7021
- }
7022
- } while (cursor);
7023
- // The node is not in the list of siblings, that means it must be disconnected.
7024
- return 1;
7025
- }
7026
- }
7027
- return aDepth < bDepth ? -1 : 1;
7028
- };
7029
7209
  /**
7030
7210
  * Use this method to find the parent component for projection.
7031
7211
  *
@@ -7052,11 +7232,7 @@
7052
7232
  while (projectionDepth--) {
7053
7233
  while (vHost &&
7054
7234
  (vnode_isVirtualVNode(vHost) ? vnode_getProp(vHost, OnRenderProp, null) === null : true)) {
7055
- const qSlotParentProp = vnode_getProp(vHost, QSlotParent, null);
7056
- const qSlotParent = qSlotParentProp &&
7057
- (typeof qSlotParentProp === 'string'
7058
- ? vnode_locate(rootVNode, qSlotParentProp)
7059
- : qSlotParentProp);
7235
+ const qSlotParent = vnode_getProp(vHost, QSlotParent, (id) => vnode_locate(rootVNode, id));
7060
7236
  const vProjectionParent = vnode_isVirtualVNode(vHost) && qSlotParent;
7061
7237
  if (vProjectionParent) {
7062
7238
  // We found a projection, so we need to go up one more level.
@@ -7965,14 +8141,14 @@
7965
8141
  if (vnode_getProp(vNode, OnRenderProp, null) !== null) {
7966
8142
  return vNode;
7967
8143
  }
7968
- // If virtual node, than it could be a slot so we need to read its parent.
7969
- const parent = vnode_getProp(vNode, QSlotParent, this.$vnodeLocate$);
7970
- if (parent) {
7971
- vNode = parent;
7972
- continue;
7973
- }
8144
+ vNode =
8145
+ vnode_getParent(vNode) ||
8146
+ // If virtual node, than it could be a slot so we need to read its parent.
8147
+ vnode_getProp(vNode, QSlotParent, this.$vnodeLocate$);
8148
+ }
8149
+ else {
8150
+ vNode = vnode_getParent(vNode);
7974
8151
  }
7975
- vNode = vnode_getParent(vNode);
7976
8152
  }
7977
8153
  return null;
7978
8154
  }
@@ -8072,12 +8248,6 @@
8072
8248
 
8073
8249
  /** There's [documentation](./serialization.md) */
8074
8250
  const deserializedProxyMap = new WeakMap();
8075
- const unwrapDeserializerProxy = (value) => {
8076
- const unwrapped = typeof value === 'object' &&
8077
- value !== null &&
8078
- value[SERIALIZER_PROXY_UNWRAP];
8079
- return unwrapped ? unwrapped : value;
8080
- };
8081
8251
  const isDeserializerProxy = (value) => {
8082
8252
  return typeof value === 'object' && value !== null && SERIALIZER_PROXY_UNWRAP in value;
8083
8253
  };
@@ -8130,14 +8300,14 @@
8130
8300
  return value;
8131
8301
  }
8132
8302
  const container = this.$container$;
8133
- const propValue = allocate(container, typeId, value);
8134
- Reflect.set(target, property, propValue);
8135
- this.$data$[idx] = undefined;
8136
- this.$data$[idx + 1] = propValue;
8303
+ let propValue = allocate(container, typeId, value);
8137
8304
  /** We stored the reference, so now we can inflate, allowing cycles. */
8138
8305
  if (typeId >= TypeIds.Error) {
8139
- inflate(container, propValue, typeId, value);
8306
+ propValue = inflate(container, propValue, typeId, value);
8140
8307
  }
8308
+ Reflect.set(target, property, propValue);
8309
+ this.$data$[idx] = undefined;
8310
+ this.$data$[idx + 1] = propValue;
8141
8311
  return propValue;
8142
8312
  }
8143
8313
  has(target, property) {
@@ -8176,7 +8346,7 @@
8176
8346
  const inflate = (container, target, typeId, data) => {
8177
8347
  if (typeId === undefined) {
8178
8348
  // Already processed
8179
- return;
8349
+ return target;
8180
8350
  }
8181
8351
  // restore the complex data, except for plain objects
8182
8352
  if (typeId !== TypeIds.Object && Array.isArray(data)) {
@@ -8248,16 +8418,13 @@
8248
8418
  case TypeIds.Store:
8249
8419
  case TypeIds.StoreArray: {
8250
8420
  const [value, flags, effects, storeEffect] = data;
8251
- const handler = getStoreHandler(target);
8252
- handler.$flags$ = flags;
8253
- // First assign so it sets up the deep stores
8254
- Object.assign(getStoreTarget(target), value);
8255
- // Afterwards restore the effects so they don't get triggered
8421
+ const store = getOrCreateStore(value, flags, container);
8422
+ const storeHandler = getStoreHandler(store);
8256
8423
  if (storeEffect) {
8257
8424
  effects[STORE_ARRAY_PROP] = storeEffect;
8258
8425
  }
8259
- handler.$effects$ = effects;
8260
- container.$storeProxyMap$.set(value, target);
8426
+ storeHandler.$effects$ = effects;
8427
+ target = store;
8261
8428
  break;
8262
8429
  }
8263
8430
  case TypeIds.Signal: {
@@ -8384,6 +8551,7 @@
8384
8551
  default:
8385
8552
  throw qError(QError.serializeErrorNotImplemented, [typeId]);
8386
8553
  }
8554
+ return target;
8387
8555
  };
8388
8556
  const _constants = [
8389
8557
  undefined,
@@ -8449,9 +8617,9 @@
8449
8617
  case TypeIds.ComputedSignal:
8450
8618
  return new ComputedSignal(container, null);
8451
8619
  case TypeIds.Store:
8452
- return createStore(container, {}, 0);
8453
8620
  case TypeIds.StoreArray:
8454
- return createStore(container, [], 0);
8621
+ // ignore allocate, we need to assign target while creating store
8622
+ return null;
8455
8623
  case TypeIds.URLSearchParams:
8456
8624
  return new URLSearchParams(value);
8457
8625
  case TypeIds.FormData:
@@ -9313,15 +9481,15 @@
9313
9481
  }
9314
9482
  return output;
9315
9483
  }
9316
- function deserializeData(container, typeId, propValue) {
9484
+ function deserializeData(container, typeId, value) {
9317
9485
  if (typeId === undefined) {
9318
- return propValue;
9486
+ return value;
9319
9487
  }
9320
- const value = allocate(container, typeId, propValue);
9488
+ let propValue = allocate(container, typeId, value);
9321
9489
  if (typeId >= TypeIds.Error) {
9322
- inflate(container, value, typeId, propValue);
9490
+ propValue = inflate(container, propValue, typeId, value);
9323
9491
  }
9324
- return value;
9492
+ return propValue;
9325
9493
  }
9326
9494
  function getObjectById(id, stateData) {
9327
9495
  if (typeof id === 'string') {