@qwik.dev/core 2.0.0-beta.13 → 2.0.0-beta.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/backpatch/package.json +1 -1
  2. package/dist/build/package.json +1 -1
  3. package/dist/cli.mjs +5633 -0
  4. package/dist/core-internal.d.ts +76 -50
  5. package/dist/core.min.mjs +1 -1
  6. package/dist/core.mjs +179 -82
  7. package/dist/core.mjs.map +1 -1
  8. package/dist/core.prod.mjs +125 -71
  9. package/dist/loader/index.mjs +2 -2
  10. package/dist/loader/package.json +1 -1
  11. package/dist/optimizer.mjs +1283 -1280
  12. package/dist/qwikloader.debug.js +5 -0
  13. package/dist/qwikloader.js +1 -1
  14. package/dist/server.mjs +4 -4
  15. package/dist/starters/adapters/aws-lambda/package.json +2 -1
  16. package/dist/starters/adapters/azure-swa/package.json +2 -1
  17. package/dist/starters/adapters/bun/package.json +2 -1
  18. package/dist/starters/adapters/cloud-run/package.json +2 -1
  19. package/dist/starters/adapters/cloudflare-pages/package.json +2 -1
  20. package/dist/starters/adapters/deno/package.json +2 -1
  21. package/dist/starters/adapters/express/package.json +2 -1
  22. package/dist/starters/adapters/fastify/package.json +2 -1
  23. package/dist/starters/adapters/firebase/package.json +2 -1
  24. package/dist/starters/adapters/netlify-edge/package.json +2 -1
  25. package/dist/starters/adapters/node-server/package.json +2 -1
  26. package/dist/starters/adapters/ssg/package.json +2 -1
  27. package/dist/starters/adapters/vercel-edge/package.json +2 -1
  28. package/dist/starters/features/storybook/.storybook/tsconfig.json +0 -1
  29. package/dist/starters/features/styled-vanilla-extract/package.json +2 -1
  30. package/dist/testing/index.d.ts +2 -3
  31. package/dist/testing/index.mjs +188 -82
  32. package/dist/testing/package.json +1 -1
  33. package/package.json +14 -48
  34. package/{qwik-cli.cjs → qwik-cli.mjs} +1 -1
  35. package/dist/backpatch/index.cjs +0 -6
  36. package/dist/build/index.cjs +0 -35
  37. package/dist/build/index.cjs.map +0 -7
  38. package/dist/build/index.dev.cjs +0 -37
  39. package/dist/build/index.dev.cjs.map +0 -7
  40. package/dist/build/index.prod.cjs +0 -37
  41. package/dist/build/index.prod.cjs.map +0 -7
  42. package/dist/cli.cjs +0 -12956
  43. package/dist/core.cjs +0 -13036
  44. package/dist/core.cjs.map +0 -1
  45. package/dist/core.prod.cjs +0 -6377
  46. package/dist/insights/index.qwik.cjs +0 -1
  47. package/dist/insights/vite/index.cjs +0 -1
  48. package/dist/loader/index.cjs +0 -4
  49. package/dist/optimizer.cjs +0 -217
  50. package/dist/preloader.cjs +0 -266
  51. package/dist/server.cjs +0 -3294
  52. package/dist/testing/index.cjs +0 -36225
package/dist/core.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * @qwik.dev/core 2.0.0-beta.13-dev+cb19ff7
3
+ * @qwik.dev/core 2.0.0-beta.14-dev+1e7496d
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.13-dev+cb19ff7";
17
+ const version = "2.0.0-beta.14-dev+1e7496d";
18
18
 
19
19
  // same as isDev but separate so we can test
20
20
  const qDev = globalThis.qDev !== false;
@@ -1141,23 +1141,16 @@ class PropsProxyHandler {
1141
1141
  }
1142
1142
  }
1143
1143
  if (this.owner.constProps && prop in this.owner.constProps) {
1144
- this.owner.constProps[prop] = undefined;
1145
- if (!(prop in this.owner.varProps)) {
1146
- this.owner.toSort = true;
1147
- }
1148
- this.owner.varProps[prop] = value;
1144
+ // delete the prop from the const props first
1145
+ delete this.owner.constProps[prop];
1149
1146
  }
1150
- else {
1151
- if (this.owner.varProps === EMPTY_OBJ) {
1152
- this.owner.varProps = {};
1153
- }
1154
- else {
1155
- if (!(prop in this.owner.varProps)) {
1156
- this.owner.toSort = true;
1157
- }
1158
- }
1159
- this.owner.varProps[prop] = value;
1147
+ if (this.owner.varProps === EMPTY_OBJ) {
1148
+ this.owner.varProps = {};
1160
1149
  }
1150
+ else if (!(prop in this.owner.varProps)) {
1151
+ this.owner.toSort = true;
1152
+ }
1153
+ this.owner.varProps[prop] = value;
1161
1154
  }
1162
1155
  return true;
1163
1156
  }
@@ -1245,6 +1238,19 @@ const isPropsProxy = (obj) => {
1245
1238
  return obj && _VAR_PROPS in obj;
1246
1239
  };
1247
1240
 
1241
+ const cleanupDestroyable = (destroyable) => {
1242
+ const destroy = destroyable.$destroy$;
1243
+ if (destroy) {
1244
+ destroyable.$destroy$ = null;
1245
+ try {
1246
+ destroy();
1247
+ }
1248
+ catch (err) {
1249
+ logError(err);
1250
+ }
1251
+ }
1252
+ };
1253
+
1248
1254
  function getSubscriber(effect, prop, data) {
1249
1255
  if (!effect[_EFFECT_BACK_REF]) {
1250
1256
  if (isServer && isSsrNode(effect)) {
@@ -1301,14 +1307,14 @@ const cleanupFn = (target, handleError) => {
1301
1307
  cleanupFns = [];
1302
1308
  target.$destroy$ = noSerialize(() => {
1303
1309
  target.$destroy$ = null;
1304
- cleanupFns.forEach((fn) => {
1310
+ for (const fn of cleanupFns) {
1305
1311
  try {
1306
1312
  fn();
1307
1313
  }
1308
1314
  catch (err) {
1309
1315
  handleError(err);
1310
1316
  }
1311
- });
1317
+ }
1312
1318
  });
1313
1319
  }
1314
1320
  cleanupFns.push(fn);
@@ -1421,6 +1427,7 @@ class AsyncComputedSignalImpl extends ComputedSignalImpl {
1421
1427
  $errorEffects$ = null;
1422
1428
  $destroy$;
1423
1429
  $promiseValue$ = NEEDS_COMPUTATION;
1430
+ $promise$ = null;
1424
1431
  [_EFFECT_BACK_REF] = null;
1425
1432
  constructor(container, fn, flags = 1 /* SignalFlags.INVALID */) {
1426
1433
  super(container, fn, flags);
@@ -1456,9 +1463,12 @@ class AsyncComputedSignalImpl extends ComputedSignalImpl {
1456
1463
  }
1457
1464
  invalidate() {
1458
1465
  super.invalidate();
1459
- this.$promiseValue$ = NEEDS_COMPUTATION;
1466
+ // clear the promise, we need to get function again
1467
+ this.$promise$ = null;
1460
1468
  }
1461
- async resolve() {
1469
+ async promise() {
1470
+ // make sure we get a new promise during the next computation
1471
+ this.$promise$ = null;
1462
1472
  await retryOnPromise(() => this.$computeIfNeeded$());
1463
1473
  return this.$untrackedValue$;
1464
1474
  }
@@ -1466,34 +1476,69 @@ class AsyncComputedSignalImpl extends ComputedSignalImpl {
1466
1476
  if (!(this.$flags$ & 1 /* SignalFlags.INVALID */)) {
1467
1477
  return;
1468
1478
  }
1469
- const [cleanup] = cleanupFn(this, (err) => this.$container$?.handleError(err, null));
1470
- const untrackedValue = this.$promiseValue$ === NEEDS_COMPUTATION
1471
- ? this.$computeQrl$.getFn()({
1472
- track: trackFn(this, this.$container$),
1473
- cleanup,
1474
- })
1479
+ const untrackedValue =
1480
+ // first time
1481
+ this.$promiseValue$ === NEEDS_COMPUTATION ||
1482
+ // or after invalidation
1483
+ this.$promise$ === null
1484
+ ? this.$promiseComputation$()
1475
1485
  : this.$promiseValue$;
1476
1486
  if (isPromise(untrackedValue)) {
1487
+ const isFirstComputation = this.$promiseValue$ === NEEDS_COMPUTATION;
1477
1488
  this.untrackedLoading = true;
1478
1489
  this.untrackedError = null;
1479
- throw untrackedValue
1490
+ if (this.$promiseValue$ !== NEEDS_COMPUTATION) {
1491
+ // skip cleanup after resuming
1492
+ cleanupDestroyable(this);
1493
+ }
1494
+ const promise = untrackedValue
1480
1495
  .then((promiseValue) => {
1481
1496
  this.$promiseValue$ = promiseValue;
1482
1497
  this.untrackedLoading = false;
1483
1498
  this.untrackedError = null;
1499
+ if (this.setValue(promiseValue)) {
1500
+ scheduleEffects(this.$container$, this, this.$effects$);
1501
+ }
1484
1502
  })
1485
1503
  .catch((err) => {
1504
+ if (isPromise(err)) {
1505
+ // ignore promise errors, they will be handled
1506
+ return;
1507
+ }
1486
1508
  this.$promiseValue$ = err;
1487
1509
  this.untrackedLoading = false;
1488
1510
  this.untrackedError = err;
1489
1511
  });
1512
+ if (isFirstComputation) {
1513
+ // we want to throw only the first time
1514
+ // the next time we will return stale value
1515
+ throw promise;
1516
+ }
1517
+ else {
1518
+ // Return the promise so the scheduler can track it as a running chore
1519
+ return promise;
1520
+ }
1521
+ }
1522
+ else {
1523
+ this.setValue(untrackedValue);
1524
+ }
1525
+ }
1526
+ async $promiseComputation$() {
1527
+ if (!this.$promise$) {
1528
+ const [cleanup] = cleanupFn(this, (err) => this.$container$?.handleError(err, null));
1529
+ this.$promise$ = this.$computeQrl$.getFn()({
1530
+ track: trackFn(this, this.$container$),
1531
+ cleanup,
1532
+ });
1490
1533
  }
1491
- this.$promiseValue$ = NEEDS_COMPUTATION;
1534
+ return this.$promise$;
1535
+ }
1536
+ setValue(value) {
1492
1537
  this.$flags$ &= -2 /* SignalFlags.INVALID */;
1493
- const didChange = untrackedValue !== this.$untrackedValue$;
1538
+ const didChange = value !== this.$untrackedValue$;
1494
1539
  if (didChange) {
1540
+ this.$untrackedValue$ = value;
1495
1541
  this.$flags$ |= 2 /* SignalFlags.RUN_EFFECTS */;
1496
- this.$untrackedValue$ = untrackedValue;
1497
1542
  }
1498
1543
  return didChange;
1499
1544
  }
@@ -1849,9 +1894,12 @@ function clearAsyncComputedSignal(producer, effect) {
1849
1894
  function clearStore(producer, effect) {
1850
1895
  const effects = producer?.$effects$;
1851
1896
  if (effects) {
1852
- for (const propEffects of effects.values()) {
1897
+ for (const [propKey, propEffects] of effects.entries()) {
1853
1898
  if (propEffects.has(effect)) {
1854
1899
  propEffects.delete(effect);
1900
+ if (propEffects.size === 0) {
1901
+ effects.delete(propKey);
1902
+ }
1855
1903
  }
1856
1904
  }
1857
1905
  }
@@ -4370,14 +4418,17 @@ const RenderOnce = (props, key) => {
4370
4418
  };
4371
4419
 
4372
4420
  /** @internal */
4373
- const useTaskQrl = (qrl) => {
4421
+ const useTaskQrl = (qrl, opts) => {
4374
4422
  const { val, set, iCtx, i } = useSequentialScope();
4375
4423
  if (val) {
4376
4424
  return;
4377
4425
  }
4378
4426
  assertQrl(qrl);
4379
4427
  set(1);
4380
- const task = new Task(8 /* TaskFlags.DIRTY */ | 2 /* TaskFlags.TASK */, i, iCtx.$hostElement$, qrl, undefined, null);
4428
+ const taskFlags =
4429
+ // enabled by default
4430
+ opts?.deferUpdates === false ? 0 : 16 /* TaskFlags.RENDER_BLOCKING */;
4431
+ const task = new Task(8 /* TaskFlags.DIRTY */ | 2 /* TaskFlags.TASK */ | taskFlags, i, iCtx.$hostElement$, qrl, undefined, null);
4381
4432
  // In V2 we add the task to the sequential scope. We need to do this
4382
4433
  // in order to be able to retrieve it later when the parent element is
4383
4434
  // deleted and we need to be able to release the task subscriptions.
@@ -4390,7 +4441,7 @@ const useTaskQrl = (qrl) => {
4390
4441
  };
4391
4442
  const runTask = (task, container, host) => {
4392
4443
  task.$flags$ &= -9 /* TaskFlags.DIRTY */;
4393
- cleanupTask(task);
4444
+ cleanupDestroyable(task);
4394
4445
  const iCtx = newInvokeContext(container.$locale$, host, undefined, TaskEvent);
4395
4446
  iCtx.$container$ = container;
4396
4447
  const taskFn = task.$qrl$.getFn(iCtx, () => clearAllEffects(container, task));
@@ -4407,18 +4458,6 @@ const runTask = (task, container, host) => {
4407
4458
  }
4408
4459
  });
4409
4460
  };
4410
- const cleanupTask = (task) => {
4411
- const destroy = task.$destroy$;
4412
- if (destroy) {
4413
- task.$destroy$ = null;
4414
- try {
4415
- destroy();
4416
- }
4417
- catch (err) {
4418
- logError(err);
4419
- }
4420
- }
4421
- };
4422
4461
  class Task extends BackRef$1 {
4423
4462
  $flags$;
4424
4463
  $index$;
@@ -4587,7 +4626,7 @@ const isResourceReturn = (obj) => {
4587
4626
  };
4588
4627
  const runResource = (task, container, host) => {
4589
4628
  task.$flags$ &= -9 /* TaskFlags.DIRTY */;
4590
- cleanupTask(task);
4629
+ cleanupDestroyable(task);
4591
4630
  const iCtx = newInvokeContext(container.$locale$, host, undefined, ResourceEvent);
4592
4631
  iCtx.$container$ = container;
4593
4632
  const taskFn = task.$qrl$.getFn(iCtx, () => clearAllEffects(container, task));
@@ -4676,7 +4715,7 @@ const runResource = (task, container, host) => {
4676
4715
  promise,
4677
4716
  delay(timeout).then(() => {
4678
4717
  if (setState(false, new Error('timeout'))) {
4679
- cleanupTask(task);
4718
+ cleanupDestroyable(task);
4680
4719
  }
4681
4720
  }),
4682
4721
  ]);
@@ -4814,16 +4853,17 @@ function qrlToString(serializationContext, value, raw) {
4814
4853
  // TODO test that provided stringified fn is used
4815
4854
  symbol = String(serializationContext.$addSyncFn$(null, 0, fn));
4816
4855
  }
4817
- if (!value.$capture$ && Array.isArray(value.$captureRef$) && value.$captureRef$.length > 0) {
4856
+ let capturedIds = null;
4857
+ if (Array.isArray(value.$captureRef$) && value.$captureRef$.length > 0) {
4818
4858
  // We refer by id so every capture needs to be a root
4819
- value.$capture$ = value.$captureRef$.map((ref) => `${serializationContext.$addRoot$(ref)}`);
4859
+ capturedIds = value.$captureRef$.map((ref) => `${serializationContext.$addRoot$(ref)}`);
4820
4860
  }
4821
4861
  if (raw) {
4822
- return [chunk, symbol, value.$capture$];
4862
+ return [chunk, symbol, capturedIds];
4823
4863
  }
4824
4864
  let qrlStringInline = `${chunk}#${symbol}`;
4825
- if (value.$capture$ && value.$capture$.length > 0) {
4826
- qrlStringInline += `[${value.$capture$.join(' ')}]`;
4865
+ if (capturedIds && capturedIds.length > 0) {
4866
+ qrlStringInline += `[${capturedIds.join(' ')}]`;
4827
4867
  }
4828
4868
  return qrlStringInline;
4829
4869
  }
@@ -5664,6 +5704,7 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
5664
5704
  */
5665
5705
  const stack = [];
5666
5706
  const asyncQueue = [];
5707
+ const asyncAttributePromises = [];
5667
5708
  ////////////////////////////////
5668
5709
  //// Traverse state variables
5669
5710
  ////////////////////////////////
@@ -6077,6 +6118,14 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
6077
6118
  diff(jsxNode, vHostNode);
6078
6119
  }
6079
6120
  }
6121
+ // Wait for all async attribute promises to complete, then check for more work
6122
+ if (asyncAttributePromises.length) {
6123
+ const promises = asyncAttributePromises.splice(0);
6124
+ return Promise.all(promises).then(() => {
6125
+ // After attributes are set, check if there's more work in the queue
6126
+ return drainAsyncQueue();
6127
+ });
6128
+ }
6080
6129
  }
6081
6130
  function expectNoChildren() {
6082
6131
  const vFirstChild = vCurrent && vnode_getFirstChild(vCurrent);
@@ -6128,11 +6177,11 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
6128
6177
  // only svg elements can have namespace attributes
6129
6178
  const namespace = getAttributeNamespace(key);
6130
6179
  if (namespace) {
6131
- element.setAttributeNS(namespace, key, String(value));
6180
+ element.setAttributeNS(namespace, key, value);
6132
6181
  return;
6133
6182
  }
6134
6183
  }
6135
- element.setAttribute(key, String(value));
6184
+ element.setAttribute(key, value);
6136
6185
  }
6137
6186
  }
6138
6187
  const { constProps } = jsx;
@@ -6183,7 +6232,8 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
6183
6232
  }
6184
6233
  if (isPromise(value)) {
6185
6234
  const vHost = vNewNode;
6186
- value.then((resolvedValue) => setAttribute(key, resolvedValue, vHost));
6235
+ const attributePromise = value.then((resolvedValue) => setAttribute(key, resolvedValue, vHost));
6236
+ asyncAttributePromises.push(attributePromise);
6187
6237
  continue;
6188
6238
  }
6189
6239
  if (key === dangerouslySetInnerHTML) {
@@ -6355,7 +6405,8 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
6355
6405
  }
6356
6406
  if (isPromise(value)) {
6357
6407
  const vHost = vnode;
6358
- value.then((resolvedValue) => setAttribute(key, resolvedValue, vHost));
6408
+ const attributePromise = value.then((resolvedValue) => setAttribute(key, resolvedValue, vHost));
6409
+ asyncAttributePromises.push(attributePromise);
6359
6410
  return;
6360
6411
  }
6361
6412
  setAttribute(key, value, vnode);
@@ -6877,28 +6928,30 @@ function cleanup(container, vNode) {
6877
6928
  if (type & 3 /* VNodeFlags.ELEMENT_OR_VIRTUAL_MASK */) {
6878
6929
  clearAllEffects(container, vCursor);
6879
6930
  markVNodeAsDeleted(vCursor);
6880
- // Only elements and virtual nodes need to be traversed for children
6881
- if (type & 2 /* VNodeFlags.Virtual */) {
6931
+ const isComponent = type & 2 /* VNodeFlags.Virtual */ &&
6932
+ vCursor.getProp(OnRenderProp, null) !== null;
6933
+ if (isComponent) {
6934
+ // cleanup q:seq content
6882
6935
  const seq = container.getHostProp(vCursor, ELEMENT_SEQ);
6883
6936
  if (seq) {
6884
6937
  for (let i = 0; i < seq.length; i++) {
6885
6938
  const obj = seq[i];
6886
- if (isTask(obj)) {
6887
- const task = obj;
6888
- clearAllEffects(container, task);
6889
- if (task.$flags$ & 1 /* TaskFlags.VISIBLE_TASK */) {
6890
- container.$scheduler$(32 /* ChoreType.CLEANUP_VISIBLE */, task);
6939
+ if (isObject(obj)) {
6940
+ const objIsTask = isTask(obj);
6941
+ if (objIsTask && obj.$flags$ & 1 /* TaskFlags.VISIBLE_TASK */) {
6942
+ container.$scheduler$(32 /* ChoreType.CLEANUP_VISIBLE */, obj);
6943
+ // don't call cleanupDestroyable yet, do it by the scheduler
6944
+ continue;
6891
6945
  }
6892
- else {
6893
- cleanupTask(task);
6946
+ else if (obj instanceof SignalImpl || isStore(obj)) {
6947
+ clearAllEffects(container, obj);
6948
+ }
6949
+ if (objIsTask || obj instanceof AsyncComputedSignalImpl) {
6950
+ cleanupDestroyable(obj);
6894
6951
  }
6895
6952
  }
6896
6953
  }
6897
6954
  }
6898
- }
6899
- const isComponent = type & 2 /* VNodeFlags.Virtual */ &&
6900
- vCursor.getProp(OnRenderProp, null) !== null;
6901
- if (isComponent) {
6902
6955
  // SPECIAL CASE: If we are a component, we need to descend into the projected content and release the content.
6903
6956
  const attrs = vnode_getProps(vCursor);
6904
6957
  for (let i = 0; i < attrs.length; i = i + 2) {
@@ -7547,6 +7600,8 @@ const createScheduler = (container, journalFlush, choreQueue, blockedChores, run
7547
7600
  let currentTime = performance.now();
7548
7601
  const nextTick = createNextTick(drainChoreQueue);
7549
7602
  let flushTimerId = null;
7603
+ let blockingChoresCount = 0;
7604
+ let currentChore = null;
7550
7605
  function drainInNextTick() {
7551
7606
  if (!drainScheduled) {
7552
7607
  drainScheduled = true;
@@ -7620,6 +7675,10 @@ Problematic chore:
7620
7675
 
7621
7676
  This is often caused by modifying a signal in an already rendered component during SSR.`;
7622
7677
  logWarn(warningMessage);
7678
+ // Decrement counter if this was a blocking chore that we're skipping
7679
+ if (isRenderBlocking(type)) {
7680
+ blockingChoresCount--;
7681
+ }
7623
7682
  return chore;
7624
7683
  }
7625
7684
  }
@@ -7637,7 +7696,7 @@ This is often caused by modifying a signal in an already rendered component duri
7637
7696
  return chore;
7638
7697
  }
7639
7698
  }
7640
- addChore(chore, choreQueue);
7699
+ addChoreAndIncrementBlockingCounter(chore, choreQueue);
7641
7700
  const runImmediately = (isServer && type === 6 /* ChoreType.COMPONENT */) || type === 2 /* ChoreType.RUN_QRL */;
7642
7701
  if (runImmediately && !isDraining) {
7643
7702
  immediateDrain();
@@ -7686,6 +7745,9 @@ This is often caused by modifying a signal in an already rendered component duri
7686
7745
  }, delay);
7687
7746
  }
7688
7747
  function applyJournalFlush() {
7748
+ if (blockingChoresCount > 0) {
7749
+ return;
7750
+ }
7689
7751
  if (!isJournalFlushRunning) {
7690
7752
  // prevent multiple journal flushes from running at the same time
7691
7753
  isJournalFlushRunning = true;
@@ -7752,7 +7814,7 @@ This is often caused by modifying a signal in an already rendered component duri
7752
7814
  if (vnode_isVNode(blockedChore.$host$)) {
7753
7815
  blockedChore.$host$.blockedChores?.delete(blockedChore);
7754
7816
  }
7755
- addChore(blockedChore, choreQueue);
7817
+ addChoreAndIncrementBlockingCounter(blockedChore, choreQueue);
7756
7818
  blockedChoresScheduled = true;
7757
7819
  }
7758
7820
  }
@@ -7762,12 +7824,12 @@ This is often caused by modifying a signal in an already rendered component duri
7762
7824
  drainInNextTick();
7763
7825
  }
7764
7826
  };
7765
- let currentChore = null;
7766
7827
  try {
7767
7828
  while (choreQueue.length) {
7768
7829
  currentTime = performance.now();
7769
7830
  const chore = (currentChore = choreQueue.shift());
7770
7831
  if (chore.$state$ !== ChoreState.NONE) {
7832
+ // Chore was already processed, counter already decremented in finishChore/handleError
7771
7833
  continue;
7772
7834
  }
7773
7835
  if (vNodeAlreadyDeleted(chore) &&
@@ -7778,6 +7840,10 @@ This is often caused by modifying a signal in an already rendered component duri
7778
7840
  if (vnode_isVNode(chore.$host$)) {
7779
7841
  chore.$host$.chores?.delete(chore);
7780
7842
  }
7843
+ // Decrement counter if this was a blocking chore that we're skipping
7844
+ if (isRenderBlocking(chore.$type$)) {
7845
+ blockingChoresCount--;
7846
+ }
7781
7847
  continue;
7782
7848
  }
7783
7849
  if (chore.$type$ === 16 /* ChoreType.VISIBLE */) {
@@ -7853,10 +7919,18 @@ This is often caused by modifying a signal in an already rendered component duri
7853
7919
  if (vnode_isVNode(chore.$host$)) {
7854
7920
  chore.$host$.chores?.delete(chore);
7855
7921
  }
7922
+ // Decrement blocking counter if this chore was blocking journal flush
7923
+ if (isRenderBlocking(chore.$type$)) {
7924
+ blockingChoresCount--;
7925
+ }
7856
7926
  }
7857
7927
  function handleError(chore, e) {
7858
7928
  chore.$endTime$ = performance.now();
7859
7929
  chore.$state$ = ChoreState.FAILED;
7930
+ // Decrement blocking counter if this chore was blocking journal flush
7931
+ if (isRenderBlocking(chore.$type$)) {
7932
+ blockingChoresCount--;
7933
+ }
7860
7934
  // If we used the result as promise, this won't exist
7861
7935
  chore.$reject$?.(e);
7862
7936
  container.handleError(e, chore.$host$);
@@ -7894,14 +7968,21 @@ This is often caused by modifying a signal in an already rendered component duri
7894
7968
  returnValue = runResource(payload, container, host);
7895
7969
  }
7896
7970
  else {
7897
- returnValue = runTask(payload, container, host);
7971
+ const task = payload;
7972
+ returnValue = runTask(task, container, host);
7973
+ if (task.$flags$ & 16 /* TaskFlags.RENDER_BLOCKING */) {
7974
+ blockingChoresCount++;
7975
+ returnValue = maybeThen(returnValue, () => {
7976
+ blockingChoresCount--;
7977
+ });
7978
+ }
7898
7979
  }
7899
7980
  }
7900
7981
  break;
7901
7982
  case 32 /* ChoreType.CLEANUP_VISIBLE */:
7902
7983
  {
7903
7984
  const task = chore.$payload$;
7904
- cleanupTask(task);
7985
+ cleanupDestroyable(task);
7905
7986
  }
7906
7987
  break;
7907
7988
  case 4 /* ChoreType.NODE_DIFF */:
@@ -7995,7 +8076,22 @@ This is often caused by modifying a signal in an already rendered component duri
7995
8076
  }
7996
8077
  return null;
7997
8078
  }
8079
+ function addChoreAndIncrementBlockingCounter(chore, choreArray) {
8080
+ if (addChore(chore, choreArray)) {
8081
+ blockingChoresCount++;
8082
+ }
8083
+ }
7998
8084
  };
8085
+ function addChore(chore, choreArray) {
8086
+ const idx = choreArray.add(chore);
8087
+ if (idx < 0) {
8088
+ if (vnode_isVNode(chore.$host$)) {
8089
+ (chore.$host$.chores ||= new ChoreArray()).add(chore);
8090
+ }
8091
+ return isRenderBlocking(chore.$type$);
8092
+ }
8093
+ return false;
8094
+ }
7999
8095
  function vNodeAlreadyDeleted(chore) {
8000
8096
  return !!(chore.$host$ && vnode_isVNode(chore.$host$) && chore.$host$.flags & 32 /* VNodeFlags.Deleted */);
8001
8097
  }
@@ -8006,11 +8102,8 @@ function addBlockedChore(blockedChore, blockingChore, blockedChores) {
8006
8102
  (blockedChore.$host$.blockedChores ||= new ChoreArray()).add(blockedChore);
8007
8103
  }
8008
8104
  }
8009
- function addChore(chore, choreArray) {
8010
- const idx = choreArray.add(chore);
8011
- if (idx < 0 && vnode_isVNode(chore.$host$)) {
8012
- (chore.$host$.chores ||= new ChoreArray()).add(chore);
8013
- }
8105
+ function isRenderBlocking(type) {
8106
+ return type === 4 /* ChoreType.NODE_DIFF */ || type === 6 /* ChoreType.COMPONENT */;
8014
8107
  }
8015
8108
  function choreTypeToName(type) {
8016
8109
  return ({
@@ -9344,7 +9437,7 @@ function setEvent(serializationCtx, key, rawValue) {
9344
9437
  *
9345
9438
  * For internal qrls (starting with `_`) we assume that they do the right thing.
9346
9439
  */
9347
- if (!qrl.$symbol$.startsWith('_') && (qrl.$captureRef$ || qrl.$capture$)) {
9440
+ if (!qrl.$symbol$.startsWith('_') && qrl.$captureRef$?.length) {
9348
9441
  qrl = createQRL(null, '_run', _run, null, null, [qrl]);
9349
9442
  }
9350
9443
  return qrlToString(serializationCtx, qrl);
@@ -9524,6 +9617,7 @@ const inflate = (container, target, typeId, data) => {
9524
9617
  const hasValue = d.length > 6;
9525
9618
  if (hasValue) {
9526
9619
  asyncComputed.$untrackedValue$ = d[6];
9620
+ asyncComputed.$promiseValue$ = d[6];
9527
9621
  }
9528
9622
  asyncComputed.$flags$ |= 1 /* SignalFlags.INVALID */;
9529
9623
  break;
@@ -10178,6 +10272,9 @@ class DomContainer extends _SharedContainer {
10178
10272
  this.$setServerData$();
10179
10273
  element.setAttribute(QContainerAttr, "resumed" /* QContainerValue.RESUMED */);
10180
10274
  element.qContainer = this;
10275
+ if (!qTest && element.isConnected) {
10276
+ element.dispatchEvent(new CustomEvent('qresume', { bubbles: true }));
10277
+ }
10181
10278
  const qwikStates = element.querySelectorAll('script[type="qwik/state"]');
10182
10279
  if (qwikStates.length !== 0) {
10183
10280
  const lastState = qwikStates[qwikStates.length - 1];