marko 6.4.0 → 6.4.2

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 (130) hide show
  1. package/cheatsheet.md +2 -2
  2. package/dist/common/constants/accessor-prefix.d.ts +1 -0
  3. package/dist/common/constants/accessor-prefix.debug.d.ts +1 -0
  4. package/dist/common/constants/reserved-id.d.ts +5 -0
  5. package/dist/common/errors.d.ts +2 -1
  6. package/dist/common/opt.d.ts +1 -0
  7. package/dist/common/types.d.ts +3 -0
  8. package/dist/debug/dom/catch.feat.js +1 -1
  9. package/dist/debug/dom/catch.feat.mjs +1 -1
  10. package/dist/debug/dom/controllable-input.feat.js +1 -1
  11. package/dist/debug/dom/controllable-input.feat.mjs +1 -1
  12. package/dist/debug/dom/controllable-open.feat.js +1 -1
  13. package/dist/debug/dom/controllable-open.feat.mjs +1 -1
  14. package/dist/debug/dom/controllable-select.feat.js +1 -1
  15. package/dist/debug/dom/controllable-select.feat.mjs +1 -1
  16. package/dist/debug/dom/controllable-textarea.feat.js +1 -1
  17. package/dist/debug/dom/controllable-textarea.feat.mjs +1 -1
  18. package/dist/debug/dom/controllable.feat.js +1 -1
  19. package/dist/debug/dom/controllable.feat.mjs +1 -1
  20. package/dist/debug/dom/dynamic-tag-script.feat.js +1 -1
  21. package/dist/debug/dom/dynamic-tag-script.feat.mjs +1 -1
  22. package/dist/debug/dom/dynamic-tag-var.feat.js +1 -1
  23. package/dist/debug/dom/dynamic-tag-var.feat.mjs +1 -1
  24. package/dist/debug/dom/lazy.feat.js +1 -1
  25. package/dist/debug/dom/lazy.feat.mjs +1 -1
  26. package/dist/debug/dom/placeholder.feat.js +1 -1
  27. package/dist/debug/dom/placeholder.feat.mjs +1 -1
  28. package/dist/debug/{dom-BRO5aArp.js → dom-BLbR0hEx.js} +62 -16
  29. package/dist/debug/{dom-Btj2QJhk.mjs → dom-Cii0IA92.mjs} +51 -17
  30. package/dist/debug/dom.js +7 -4
  31. package/dist/debug/dom.mjs +6 -5
  32. package/dist/debug/html.js +551 -292
  33. package/dist/debug/html.mjs +548 -290
  34. package/dist/dom/catch.feat.js +3 -3
  35. package/dist/dom/catch.feat.mjs +1 -1
  36. package/dist/dom/controllable-input.feat.js +1 -1
  37. package/dist/dom/controllable-input.feat.mjs +1 -1
  38. package/dist/dom/controllable-open.feat.js +1 -1
  39. package/dist/dom/controllable-open.feat.mjs +1 -1
  40. package/dist/dom/controllable-select.feat.js +1 -1
  41. package/dist/dom/controllable-select.feat.mjs +1 -1
  42. package/dist/dom/controllable-textarea.feat.js +1 -1
  43. package/dist/dom/controllable-textarea.feat.mjs +1 -1
  44. package/dist/dom/controllable.feat.js +1 -1
  45. package/dist/dom/controllable.feat.mjs +1 -1
  46. package/dist/dom/dom.d.ts +1 -0
  47. package/dist/dom/dynamic-tag-script.feat.js +2 -2
  48. package/dist/dom/dynamic-tag-script.feat.mjs +1 -1
  49. package/dist/dom/dynamic-tag-var.feat.js +1 -1
  50. package/dist/dom/dynamic-tag-var.feat.mjs +1 -1
  51. package/dist/dom/lazy.feat.js +1 -1
  52. package/dist/dom/lazy.feat.mjs +1 -1
  53. package/dist/dom/placeholder.feat.js +3 -3
  54. package/dist/dom/placeholder.feat.mjs +1 -1
  55. package/dist/dom/signals.d.ts +3 -2
  56. package/dist/{dom-BSsI9OPC.js → dom-B8UEYzOz.js} +112 -84
  57. package/dist/{dom-B-v8Gw6T.mjs → dom-BPjLe6YU.mjs} +23 -5
  58. package/dist/dom.d.ts +2 -2
  59. package/dist/dom.js +34 -33
  60. package/dist/dom.mjs +6 -5
  61. package/dist/html/assets.d.ts +12 -6
  62. package/dist/html/attrs.d.ts +3 -2
  63. package/dist/html/compat.d.ts +10 -2
  64. package/dist/html/dynamic-tag.d.ts +1 -1
  65. package/dist/html/inlined-runtimes.d.ts +1 -1
  66. package/dist/html/inlined-runtimes.debug.d.ts +1 -1
  67. package/dist/html/serializer.d.ts +2 -1
  68. package/dist/html/writer.d.ts +42 -22
  69. package/dist/html.d.ts +2 -2
  70. package/dist/html.js +400 -208
  71. package/dist/html.mjs +399 -207
  72. package/dist/translator/core/html-comment.d.ts +0 -7
  73. package/dist/translator/core/let.d.ts +0 -5
  74. package/dist/translator/core/show.d.ts +2 -5
  75. package/dist/translator/core/style.d.ts +6 -8
  76. package/dist/translator/index.d.ts +9 -0
  77. package/dist/translator/index.js +8429 -8100
  78. package/dist/translator/util/binding-has-prop.d.ts +1 -1
  79. package/dist/translator/util/binding-prop-tree.d.ts +4 -4
  80. package/dist/translator/util/bindings.d.ts +135 -0
  81. package/dist/translator/util/body-to-text-literal.d.ts +1 -2
  82. package/dist/translator/util/branch-tag.d.ts +7 -7
  83. package/dist/translator/util/constants/binding-type.d.ts +5 -6
  84. package/dist/translator/util/constants/slot-kind.d.ts +14 -0
  85. package/dist/translator/util/constants/structure-kind.d.ts +2 -1
  86. package/dist/translator/util/evaluate.d.ts +11 -10
  87. package/dist/translator/util/finalize-references.d.ts +4 -0
  88. package/dist/translator/util/for-selector.d.ts +1 -1
  89. package/dist/translator/util/generate-uid.d.ts +3 -1
  90. package/dist/translator/util/get-declared-binding-expression.d.ts +2 -2
  91. package/dist/translator/util/is-core-tag.d.ts +0 -3
  92. package/dist/translator/util/is-only-child-in-parent.d.ts +2 -7
  93. package/dist/translator/util/known-tag.d.ts +10 -8
  94. package/dist/translator/util/module-read.d.ts +21 -0
  95. package/dist/translator/util/read-replacement.d.ts +3 -0
  96. package/dist/translator/util/reasons.d.ts +32 -0
  97. package/dist/translator/util/references.d.ts +68 -166
  98. package/dist/translator/util/runtime.d.ts +2 -0
  99. package/dist/translator/util/scope-accessor.d.ts +14 -0
  100. package/dist/translator/util/scope-read.d.ts +1 -1
  101. package/dist/translator/util/sections.d.ts +52 -48
  102. package/dist/translator/util/set-tag-derived-from.d.ts +7 -0
  103. package/dist/translator/util/setup-work.d.ts +1 -2
  104. package/dist/translator/util/signals.d.ts +3 -5
  105. package/dist/translator/util/slots.d.ts +50 -0
  106. package/dist/translator/util/solve-reasons.d.ts +10 -0
  107. package/dist/translator/util/sources.d.ts +21 -0
  108. package/dist/translator/util/structure.d.ts +6 -2
  109. package/dist/translator/util/tag-facts.d.ts +21 -0
  110. package/dist/translator/util/tag-name-type.d.ts +4 -1
  111. package/dist/translator/util/translate-attrs.d.ts +2 -0
  112. package/dist/translator/util/translate-var.d.ts +3 -0
  113. package/dist/translator/util/write-guard.d.ts +12 -0
  114. package/dist/translator/util/writer.d.ts +3 -3
  115. package/dist/translator/visitors/export-declaration.d.ts +9 -0
  116. package/dist/translator/visitors/function.d.ts +5 -4
  117. package/dist/translator/visitors/import-declaration.d.ts +2 -2
  118. package/dist/translator/visitors/placeholder.d.ts +0 -3
  119. package/dist/translator/visitors/program/index.d.ts +13 -3
  120. package/dist/translator/visitors/referenced-identifier.d.ts +2 -1
  121. package/dist/translator/visitors/tag/custom-tag.d.ts +1 -1
  122. package/dist/translator/visitors/tag/dynamic-tag.d.ts +0 -3
  123. package/dist/translator/visitors/tag/index.d.ts +2 -1
  124. package/dist/translator/visitors/tag/native-tag.d.ts +26 -12
  125. package/package.json +3 -3
  126. package/dist/translator/util/insertion-context.d.ts +0 -1
  127. package/dist/translator/util/is-non-html-text.d.ts +0 -3
  128. package/dist/translator/util/serialize-guard.d.ts +0 -11
  129. package/dist/translator/util/serialize-reasons.d.ts +0 -37
  130. package/dist/translator/util/set-tag-sections-downstream.d.ts +0 -6
@@ -164,6 +164,16 @@ function assertValidAttrValue(name, value) {
164
164
  const unrenderable = describeUnrenderable(value);
165
165
  if (unrenderable) throw new Error(`The \`${name}\` attribute cannot be ${unrenderable}.`);
166
166
  }
167
+ function _assert_class_toggles(classes, toggles) {
168
+ {
169
+ const written = new Set(classes.split(" "));
170
+ for (const toggle of toggles) {
171
+ const names = new Set(toggle.split(" "));
172
+ for (const name of names) if (written.has(name)) throw new Error(`The toggled class \`${name}\` is also written by another part of the \`class\` value; a toggled class may appear only once.`);
173
+ for (const name of names) written.add(name);
174
+ }
175
+ }
176
+ }
167
177
  function assertValidTextValue(value) {
168
178
  const unrenderable = describeUnrenderable(value);
169
179
  if (unrenderable) throw new Error(`Text content cannot be ${unrenderable}.`);
@@ -220,18 +230,18 @@ function _hoist_read_error() {
220
230
  function _assert_hoist(value) {
221
231
  if (value !== void 0 && typeof value !== "function") throw new Error(`Hoisted values must be functions, received type "${typeof value}".`);
222
232
  }
223
- function assertExclusiveAttrs(attrs, onError = throwErr) {
233
+ function assertExclusiveAttrs(attrs, onError = throwErr, isSet = isTruthy) {
224
234
  if (attrs) {
225
235
  let exclusiveAttrs;
226
- if (attrs.checkedChange) (exclusiveAttrs ||= []).push("checkedChange");
236
+ if (isSet(attrs.checkedChange)) (exclusiveAttrs ||= []).push("checkedChange");
227
237
  if ("checkedValue" in attrs) {
228
238
  (exclusiveAttrs ||= []).push("checkedValue");
229
239
  if ("checked" in attrs) exclusiveAttrs.push("checked");
230
- } else if (attrs.checkedValueChange) {
240
+ } else if (isSet(attrs.checkedValueChange)) {
231
241
  (exclusiveAttrs ||= []).push("checkedValueChange");
232
242
  if ("checked" in attrs) exclusiveAttrs.push("checked");
233
243
  }
234
- if (attrs.valueChange) {
244
+ if (isSet(attrs.valueChange)) {
235
245
  (exclusiveAttrs ||= []).push("valueChange");
236
246
  if ("checked" in attrs && !exclusiveAttrs.includes("checked")) exclusiveAttrs.push("checked");
237
247
  }
@@ -247,6 +257,9 @@ function assertHandlerIsFunction(name, value) {
247
257
  function assertValidTagName(tagName) {
248
258
  if (!/^[a-z][a-z0-9._-]*$/i.test(tagName)) throw new Error(`Invalid tag name: "${tagName}". Tag names must start with a letter and contain only letters, numbers, periods, hyphens, and underscores.`);
249
259
  }
260
+ function isTruthy(value) {
261
+ return value;
262
+ }
250
263
  function throwErr(msg) {
251
264
  throw new Error(msg);
252
265
  }
@@ -293,11 +306,12 @@ function forUntil(until, from, step, cb) {
293
306
  }
294
307
  //#endregion
295
308
  //#region src/common/opt.ts
296
- function forEach(opt, cb) {
309
+ function reduce(opt, cb, acc) {
297
310
  if (opt) {
298
- if (Array.isArray(opt)) for (const item of opt) cb(item);
299
- else cb(opt);
311
+ if (Array.isArray(opt)) for (const item of opt) acc = cb(acc, item);
312
+ else acc = cb(acc, opt);
300
313
  }
314
+ return acc;
301
315
  }
302
316
  function push(opt, item) {
303
317
  return opt ? Array.isArray(opt) ? (opt.push(item), opt) : [opt, item] : item;
@@ -647,6 +661,17 @@ var Serializer = class {
647
661
  channel
648
662
  });
649
663
  }
664
+ dropCall(value, object, property) {
665
+ const { mutated } = this.#state;
666
+ for (let i = 0; i < mutated.length; i++) {
667
+ const mutation = mutated[i];
668
+ if (mutation.value === value && mutation.object === object && mutation.property === property) {
669
+ mutated.splice(i, 1);
670
+ return true;
671
+ }
672
+ }
673
+ return false;
674
+ }
650
675
  };
651
676
  function register(id, val, scope, locals) {
652
677
  REGISTRY.set(val, {
@@ -740,7 +765,7 @@ function writeAssigned(state) {
740
765
  if (writeProp(state, mutation.object, null, "")) {
741
766
  const objectRef = state.refs.get(mutation.object);
742
767
  if (objectRef && objectRef.scopeId === void 0) {
743
- if (!objectRef.id) {
768
+ if (!objectRef.id && !isAncestorChannelRef(state, objectRef)) {
744
769
  objectRef.id = nextRefAccess(state);
745
770
  state.buf[objectStartIndex] = "(" + objectRef.id + "=" + state.buf[objectStartIndex];
746
771
  state.buf.push(")");
@@ -753,7 +778,7 @@ function writeAssigned(state) {
753
778
  const valueStartIndex = state.buf.push(toAccess(toObjectKey(mutation.property)) + "(");
754
779
  if (mutation.value === void 0) {} else if (writeProp(state, mutation.value, null, "")) {
755
780
  const valueRef = typeof mutation.value === "string" ? state.strs.get(mutation.value) : state.refs.get(mutation.value);
756
- if (valueRef && !valueRef.id && valueRef.scopeId === void 0) {
781
+ if (valueRef && !valueRef.id && valueRef.scopeId === void 0 && !isAncestorChannelRef(state, valueRef)) {
757
782
  valueRef.id = mutation.valueId || nextRefAccess(state);
758
783
  state.buf[valueStartIndex] = valueRef.id + "=" + state.buf[valueStartIndex];
759
784
  }
@@ -770,7 +795,7 @@ function writeCallArg(state, val) {
770
795
  state.buf.push("$");
771
796
  } else if (writeProp(state, val, null, "")) {
772
797
  const ref = state.refs.get(val) || state.strs.get(val);
773
- if (ref && ref.id === null) assignId(state, ref);
798
+ if (ref) ensureId(state, ref);
774
799
  } else state.buf.push("void 0");
775
800
  }
776
801
  function hasChannelMutations(state) {
@@ -852,8 +877,7 @@ function writeRegistered(state, val, parent, accessor, registered) {
852
877
  state.buf.push(registered.access + "(_(" + scopeId + ")");
853
878
  for (const local of locals) {
854
879
  state.buf.push(",");
855
- if (local) writePlainObject(state, local, new Reference(ref, null, state.flushId, state.buf.length));
856
- else state.buf.push("0");
880
+ writePlainObject(state, local, newArgReference(state, ref, local));
857
881
  }
858
882
  } else state.buf.push("_(" + scopeId + "," + quoteRegisterId(registered.id));
859
883
  state.buf.push(")");
@@ -1162,6 +1186,17 @@ function writeArrayArg(state, ref, items, assignsPrefix, plainPrefix, needsId) {
1162
1186
  }
1163
1187
  state.buf.push(")");
1164
1188
  }
1189
+ function newArgReference(state, parent, val) {
1190
+ for (const key in val) {
1191
+ const member = val[key];
1192
+ if (isDedupedMember(member) && !(typeof member === "string" ? state.strs.has(member) : state.refs.has(member))) {
1193
+ const ref = new Reference(parent, null, state.flushId, null, nextRefAccess(state));
1194
+ state.buf.push(ref.id + "=");
1195
+ return ref;
1196
+ }
1197
+ }
1198
+ return new Reference(parent, null, state.flushId, state.buf.length);
1199
+ }
1165
1200
  function isDedupedMember(val) {
1166
1201
  switch (typeof val) {
1167
1202
  case "object": return val !== null && val[K_SCOPE_ID] === void 0;
@@ -1358,20 +1393,9 @@ function writeResponse(state, val, ref) {
1358
1393
  }
1359
1394
  function writeIntl(state, val, name, ref) {
1360
1395
  const { locale, ...options } = val.resolvedOptions();
1361
- let needsId = false;
1362
- for (const key in options) if (isDedupedMember(options[key])) {
1363
- needsId = true;
1364
- break;
1365
- }
1366
1396
  state.buf.push("new Intl." + name + "(" + quote(locale, 0) + ",");
1367
- let optionsRef;
1368
- if (needsId) {
1369
- optionsRef = new Reference(ref, null, state.flushId, null, nextRefAccess(state));
1370
- state.buf.push(optionsRef.id + "={");
1371
- } else {
1372
- optionsRef = new Reference(ref, null, state.flushId, state.buf.length);
1373
- state.buf.push("{");
1374
- }
1397
+ const optionsRef = newArgReference(state, ref, options);
1398
+ state.buf.push("{");
1375
1399
  writeObjectProps(state, options, optionsRef);
1376
1400
  state.buf.push("})");
1377
1401
  return true;
@@ -1395,7 +1419,7 @@ function writeReadableStream(state, val, ref) {
1395
1419
  const handle = newAsyncHandle(state, ref, iterId);
1396
1420
  const onFulfilled = ({ value, done }) => {
1397
1421
  if (done) writeAsyncCall(state, boundary, handle, "r", value, channel);
1398
- else if (!boundary.signal.aborted) {
1422
+ else if (!boundary.aborted) {
1399
1423
  reader.read().then(onFulfilled, onRejected);
1400
1424
  boundary.startAsync();
1401
1425
  writeAsyncCall(state, boundary, handle, "f", value, channel);
@@ -1442,13 +1466,10 @@ function writeGenerator(state, iter, ref) {
1442
1466
  state.buf.push("," + holder.id + "={}");
1443
1467
  writeProp(state, returnValue, holder, "v");
1444
1468
  } else if (returnValue !== void 0) {
1445
- const sepIndex = state.buf.push(",") - 1;
1469
+ state.buf.push(",");
1446
1470
  if (writeProp(state, returnValue, ref, "") && isDedupedMember(returnValue)) {
1447
1471
  const retRef = typeof returnValue === "string" ? state.strs.get(returnValue) : state.refs.get(returnValue);
1448
- if (retRef && !retRef.id && retRef.scopeId === void 0) {
1449
- retRef.id = nextRefAccess(state);
1450
- state.buf[sepIndex] = "," + retRef.id + "=";
1451
- }
1472
+ if (retRef) ensureId(state, retRef);
1452
1473
  }
1453
1474
  }
1454
1475
  state.buf.push(")");
@@ -1464,7 +1485,7 @@ function writeAsyncGenerator(state, iter, ref) {
1464
1485
  const handle = newAsyncHandle(state, ref, iterId);
1465
1486
  const onFulfilled = ({ value, done }) => {
1466
1487
  if (done) writeAsyncCall(state, boundary, handle, "r", value, channel);
1467
- else if (!boundary.signal.aborted) {
1488
+ else if (!boundary.aborted) {
1468
1489
  iter.next().then(onFulfilled, onRejected);
1469
1490
  boundary.startAsync();
1470
1491
  writeAsyncCall(state, boundary, handle, "f", value, channel);
@@ -1511,7 +1532,7 @@ function writeMaybeIterableProps(state, val, ref) {
1511
1532
  return sep;
1512
1533
  }
1513
1534
  function writeAsyncCall(state, boundary, handle, method, value, channel, valueId = null) {
1514
- if (boundary.signal.aborted) return;
1535
+ if (boundary.aborted) return;
1515
1536
  state.mutated.push({
1516
1537
  value,
1517
1538
  object: handle,
@@ -1569,6 +1590,7 @@ const accessorPrefixDescriptions = {
1569
1590
  ControlledType: "the controlled type",
1570
1591
  ControlledValue: "the controlled value",
1571
1592
  DynamicHTMLLastChild: "the dynamic html",
1593
+ DynamicHTMLValue: "the dynamic html value",
1572
1594
  EventAttributes: "the event handlers",
1573
1595
  IdFallback: "the generated id",
1574
1596
  KeyedScopes: "the keyed scopes",
@@ -1607,6 +1629,9 @@ function trackChannel(state, ref) {
1607
1629
  }
1608
1630
  return false;
1609
1631
  }
1632
+ function isAncestorChannelRef(state, ref) {
1633
+ return ref.channel?.readyId !== state.channel?.readyId;
1634
+ }
1610
1635
  function abortUnreachableChannel(state, val) {
1611
1636
  const err = new TypeError("Unable to serialize a value shared between independently lazy loaded content. Values shared this way must also be serialized by content that is not lazily loaded, or by a common parent.", { cause: val });
1612
1637
  err.stack = void 0;
@@ -1700,11 +1725,10 @@ function quote(str, startPos) {
1700
1725
  return "\"" + (lastPos === startPos ? str : result + str.slice(lastPos)) + "\"";
1701
1726
  }
1702
1727
  function writeRef(state, ref) {
1703
- if (ref.id === null && ref.scopeId === void 0 && ref.path === null && (ref.pos === null || ref.flushId !== state.flushId)) {
1728
+ if (ref.id === null && ref.scopeId === void 0 && ref.path === null && (ref.pos === null || ref.flushId !== state.flushId) && !isAncestorChannelRef(state, ref)) {
1704
1729
  ref.path = accessPath(state, ref);
1705
1730
  ref.pos = state.buf.length;
1706
1731
  ref.flushId = state.flushId;
1707
- ref.channel = state.channel;
1708
1732
  state.buf.push(ref.path);
1709
1733
  } else state.buf.push(ensureId(state, ref));
1710
1734
  }
@@ -1725,23 +1749,26 @@ function accessId(state, ref) {
1725
1749
  }
1726
1750
  function assignId(state, ref) {
1727
1751
  const { pos } = ref;
1728
- ref.id = nextRefAccess(state);
1729
1752
  if (pos !== null && ref.flushId === state.flushId) {
1753
+ ref.id = nextRefAccess(state);
1730
1754
  if (pos === 0) state.buf[0] = ref.id + "=" + state.buf[0];
1731
1755
  else state.buf[pos - 1] += ref.id + "=";
1732
1756
  return ref.id;
1733
1757
  }
1734
- ref.channel = state.channel;
1758
+ if (isAncestorChannelRef(state, ref)) return ref.path || accessPath(state, ref);
1759
+ ref.id = nextRefAccess(state);
1735
1760
  return ref.id + "=" + (ref.path || accessPath(state, ref));
1736
1761
  }
1737
1762
  function accessPath(state, ref) {
1738
1763
  let cur = ref;
1739
1764
  let accessPrevValue = "";
1740
1765
  do {
1766
+ if (cur.accessor === null) throw new Error("Unable to serialize a reused value: no access path reaches where it was first written, and it has no id.");
1741
1767
  accessPrevValue = toAccess(cur.accessor) + accessPrevValue;
1742
1768
  const parent = cur.parent;
1743
1769
  if (parent.id) {
1744
- if (trackChannel(state, parent) || !parent.parent) return parent.id + accessPrevValue;
1770
+ trackChannel(state, parent);
1771
+ return parent.id + accessPrevValue;
1745
1772
  }
1746
1773
  if (parent.flushId === state.flushId || parent.scopeId !== void 0) return accessId(state, parent) + accessPrevValue;
1747
1774
  cur = parent;
@@ -1969,9 +1996,9 @@ function _attrs(data, nodeAccessor, scopeId, tagName) {
1969
1996
  }
1970
1997
  return result;
1971
1998
  }
1972
- function _attrs_content(data, nodeAccessor, scopeId, tagName, serializeReason) {
1999
+ function _attrs_content(data, nodeAccessor, scopeId, tagName, markerGuard) {
1973
2000
  _html(`${_attrs(data, nodeAccessor, scopeId, tagName)}>`);
1974
- _attr_content(nodeAccessor, scopeId, data?.content, serializeReason);
2001
+ _attr_content(nodeAccessor, scopeId, data?.content, markerGuard);
1975
2002
  }
1976
2003
  function _attrs_partial(data, skip, nodeAccessor, scopeId, tagName) {
1977
2004
  const partial = {};
@@ -1985,9 +2012,9 @@ function _attrs_partial(data, skip, nodeAccessor, scopeId, tagName) {
1985
2012
  });
1986
2013
  return _attrs(partial, nodeAccessor, scopeId, tagName);
1987
2014
  }
1988
- function _attrs_partial_content(data, skip, nodeAccessor, scopeId, tagName, serializeReason) {
2015
+ function _attrs_partial_content(data, skip, nodeAccessor, scopeId, tagName, markerGuard) {
1989
2016
  _html(`${_attrs_partial(data, skip, nodeAccessor, scopeId, tagName)}>`);
1990
- _attr_content(nodeAccessor, scopeId, data?.content, serializeReason);
2017
+ _attr_content(nodeAccessor, scopeId, data?.content, markerGuard);
1991
2018
  }
1992
2019
  function writeControlledScope(type, scopeId, nodeAccessor, value, valueChange, serializeType) {
1993
2020
  var handlerName = [
@@ -2116,11 +2143,6 @@ const REORDER_RUNTIME_CODE = `((runtime) => {
2116
2143
 
2117
2144
  if (op == "#") {
2118
2145
  (placeholders[id] = placeholder).i++;
2119
- } else if (op == "!") {
2120
- if (runtime.l[id] && placeholders[id]) {
2121
- nextSibling = node.nextSibling;
2122
- onNextSibling = () => placeholders[id].c();
2123
- }
2124
2146
  } else if (node.tagName == "T" && (id = node.getAttribute(runtime.i))) {
2125
2147
  nextSibling = node.nextSibling;
2126
2148
  onNextSibling = () => {
@@ -2132,7 +2154,8 @@ const REORDER_RUNTIME_CODE = `((runtime) => {
2132
2154
  placeholders[id] ||
2133
2155
  (placeholderRoot = placeholders[id] =
2134
2156
  {
2135
- i: runtime.l[id] ? 1 : 2,
2157
+ // The writer streams a reorder only after its markers.
2158
+ i: 1,
2136
2159
  r: id,
2137
2160
  // Resume may still walk markers inside the dropped placeholder, so
2138
2161
  // park it in any detached parent (a bare <t> clone is the cheapest).
@@ -2240,8 +2263,17 @@ function _html(html) {
2240
2263
  function writeScript(script) {
2241
2264
  $chunk.writeScript(script);
2242
2265
  }
2243
- function _script(scopeId, registryId, serializeMarker) {
2244
- if (serializeMarker === 0 && ($chunk.serializeState.readyId || $chunk.context?.[kIsAsync])) _resume_branch(scopeId);
2266
+ function catchableBoundary() {
2267
+ const { boundary } = $chunk;
2268
+ return boundary.withinCatch ? boundary : null;
2269
+ }
2270
+ function mayDrop(written) {
2271
+ const { boundary } = $chunk;
2272
+ for (let cur = written; cur && !isWithin(boundary, cur); cur = cur.parent) if (cur.aborted || cur.count) return true;
2273
+ return false;
2274
+ }
2275
+ function _script(scopeId, registryId, markerGuard) {
2276
+ if (markerGuard === 0 && ($chunk.serializeState.readyId || $chunk.context?.[kIsAsync])) _resume_branch(scopeId);
2245
2277
  $chunk.boundary.state.needsMainRuntime = true;
2246
2278
  $chunk.writeEffect(scopeId, registryId);
2247
2279
  }
@@ -2289,8 +2321,8 @@ function _resume_branch(scopeId) {
2289
2321
  const branchId = $chunk.context?.[kBranchId];
2290
2322
  if (branchId !== void 0 && branchId !== scopeId) writeScope(scopeId, { [ClosestBranchId]: branchId });
2291
2323
  }
2292
- function _attr_content(nodeAccessor, scopeId, content, serializeReason) {
2293
- const shouldResume = serializeReason !== 0;
2324
+ function _attr_content(nodeAccessor, scopeId, content, markerGuard) {
2325
+ const shouldResume = markerGuard !== 0;
2294
2326
  const render = normalizeServerRender(content);
2295
2327
  const branchId = _peek_scope_id();
2296
2328
  if (render) {
@@ -2324,47 +2356,47 @@ function writeScopePassive(scopeId, partialScope) {
2324
2356
  passive[scopeId] = Object.assign(passive[scopeId] || {}, partialScope);
2325
2357
  return scope;
2326
2358
  }
2327
- function _show_start(display, mark) {
2359
+ function _show_start(display, markerGuard, branchExprGuard, parentEndTag) {
2328
2360
  if (display) {
2329
- if (mark) $chunk.writeHTML($chunk.boundary.state.mark("[", ""));
2361
+ if (resumesMarker(markerGuard, branchExprGuard, parentEndTag)) $chunk.writeHTML($chunk.boundary.state.mark("[", ""));
2330
2362
  } else $chunk.writeHTML("<t hidden>");
2331
2363
  }
2332
- function _show_end(scopeId, accessor, display, serializeMarker, serializeStateful, parentEndTag, singleNode) {
2364
+ function _show_end(scopeId, accessor, display, markerGuard, branchExprGuard, parentEndTag, singleNode) {
2333
2365
  const branchId = _scope_id();
2334
2366
  const wrap = !display;
2335
2367
  if (wrap) $chunk.writeHTML("</t>");
2336
- writeBranchEnd(scopeId, accessor, serializeStateful, serializeMarker, parentEndTag, wrap || singleNode ? 1 : void 0, " " + branchId);
2368
+ writeBranchEnd(scopeId, accessor, branchExprGuard, markerGuard, parentEndTag, wrap || singleNode ? 1 : void 0, " " + branchId);
2337
2369
  }
2338
- function _for_of(list, cb, by, scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode) {
2370
+ function _for_of(list, cb, by, scopeId, accessor, branchGuard, markerGuard, branchExprGuard, parentEndTag, singleNode) {
2339
2371
  forBranches(by, (each) => each ? forOf(list, (item, index) => {
2340
2372
  const itemKey = forOfBy(by, item, index);
2341
2373
  each(itemKey, itemKey === index, () => cb(item, index));
2342
- }) : forOf(list, cb), scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode);
2374
+ }) : forOf(list, cb), scopeId, accessor, branchGuard, markerGuard, branchExprGuard, parentEndTag, singleNode);
2343
2375
  }
2344
- function _for_in(obj, cb, by, scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode) {
2376
+ function _for_in(obj, cb, by, scopeId, accessor, branchGuard, markerGuard, branchExprGuard, parentEndTag, singleNode) {
2345
2377
  forBranches(by, (each) => each ? forIn(obj, (key, value) => {
2346
2378
  each(forInBy(by, key, value), false, () => cb(key, value));
2347
- }) : forIn(obj, cb), scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode);
2379
+ }) : forIn(obj, cb), scopeId, accessor, branchGuard, markerGuard, branchExprGuard, parentEndTag, singleNode);
2348
2380
  }
2349
- function _for_to(to, from, step, cb, by, scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode) {
2381
+ function _for_to(to, from, step, cb, by, scopeId, accessor, branchGuard, markerGuard, branchExprGuard, parentEndTag, singleNode) {
2350
2382
  forBranches(by, (each) => {
2351
2383
  let index = 0;
2352
2384
  return each ? forTo(to, from, step, (value) => {
2353
2385
  const itemKey = forStepBy(by, value);
2354
2386
  each(itemKey, itemKey === index++, () => cb(value));
2355
2387
  }) : forTo(to, from, step, cb);
2356
- }, scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode);
2388
+ }, scopeId, accessor, branchGuard, markerGuard, branchExprGuard, parentEndTag, singleNode);
2357
2389
  }
2358
- function _for_until(to, from, step, cb, by, scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode) {
2390
+ function _for_until(to, from, step, cb, by, scopeId, accessor, branchGuard, markerGuard, branchExprGuard, parentEndTag, singleNode) {
2359
2391
  forBranches(by, (each) => {
2360
2392
  let index = 0;
2361
2393
  return each ? forUntil(to, from, step, (value) => {
2362
2394
  const itemKey = forStepBy(by, value);
2363
2395
  each(itemKey, itemKey === index++, () => cb(value));
2364
2396
  }) : forUntil(to, from, step, cb);
2365
- }, scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode);
2397
+ }, scopeId, accessor, branchGuard, markerGuard, branchExprGuard, parentEndTag, singleNode);
2366
2398
  }
2367
- function forBranches(by, iterate, scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode) {
2399
+ function forBranches(by, iterate, scopeId, accessor, branchGuard, markerGuard, branchExprGuard, parentEndTag, singleNode) {
2368
2400
  if (by) {
2369
2401
  const run = iterate;
2370
2402
  const seenKeys = /* @__PURE__ */ new Set();
@@ -2374,14 +2406,14 @@ function forBranches(by, iterate, scopeId, accessor, serializeBranch, serializeM
2374
2406
  else render();
2375
2407
  });
2376
2408
  }
2377
- if (serializeBranch === 0) {
2409
+ if (branchGuard === 0) {
2378
2410
  iterate(0);
2379
- writeBranchEnd(scopeId, accessor, serializeStateful, serializeMarker, parentEndTag, singleNode, "");
2411
+ writeBranchEnd(scopeId, accessor, branchExprGuard, markerGuard, parentEndTag, singleNode, "");
2380
2412
  return;
2381
2413
  }
2382
2414
  const { state } = $chunk.boundary;
2383
- const resumeKeys = serializeMarker !== 0;
2384
- const resumeMarker = resumeKeys && (!parentEndTag || serializeStateful !== 0);
2415
+ const resumeKeys = markerGuard !== 0;
2416
+ const resumeMarker = resumesMarker(markerGuard, branchExprGuard, parentEndTag);
2385
2417
  let flushBranchIds = "";
2386
2418
  let loopScopes;
2387
2419
  iterate((itemKey, sameAsIndex, render) => {
@@ -2400,11 +2432,11 @@ function forBranches(by, iterate, scopeId, accessor, serializeBranch, serializeM
2400
2432
  });
2401
2433
  });
2402
2434
  if (loopScopes) writeScope(scopeId, { [BranchScopes + accessor]: loopScopes });
2403
- writeBranchEnd(scopeId, accessor, serializeStateful, serializeMarker, parentEndTag, singleNode, singleNode ? flushBranchIds : flushBranchIds ? " " + flushBranchIds : "");
2435
+ writeBranchEnd(scopeId, accessor, branchExprGuard, markerGuard, parentEndTag, singleNode, singleNode ? flushBranchIds : flushBranchIds ? " " + flushBranchIds : "");
2404
2436
  }
2405
- function _if(cb, scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode) {
2406
- const resumeBranch = serializeBranch !== 0;
2407
- const resumeMarker = serializeMarker !== 0 && (!parentEndTag || serializeStateful !== 0);
2437
+ function _if(cb, scopeId, accessor, branchGuard, markerGuard, branchExprGuard, parentEndTag, singleNode) {
2438
+ const resumeBranch = branchGuard !== 0;
2439
+ const resumeMarker = resumesMarker(markerGuard, branchExprGuard, parentEndTag);
2408
2440
  const branchId = _peek_scope_id();
2409
2441
  const chunk = $chunk;
2410
2442
  const beforeBranch = resumeMarker && resumeBranch && !singleNode ? deferBranchStart(chunk) : void 0;
@@ -2415,7 +2447,7 @@ function _if(cb, scopeId, accessor, serializeBranch, serializeMarker, serializeS
2415
2447
  [ConditionalRenderer + accessor]: branchIndex || void 0,
2416
2448
  [BranchScopes + accessor]: resumeMarker ? void 0 : writeScope(branchId, {})
2417
2449
  });
2418
- writeBranchEnd(scopeId, accessor, serializeStateful, serializeMarker, parentEndTag, singleNode, shouldWriteBranch ? " " + branchId : "");
2450
+ writeBranchEnd(scopeId, accessor, branchExprGuard, markerGuard, parentEndTag, singleNode, shouldWriteBranch ? " " + branchId : "");
2419
2451
  }
2420
2452
  function deferBranchStart(chunk) {
2421
2453
  const beforeBranch = chunk.html;
@@ -2425,15 +2457,17 @@ function deferBranchStart(chunk) {
2425
2457
  function applyBranchStart(chunk, beforeBranch, rendered) {
2426
2458
  chunk.html = beforeBranch + (rendered ? chunk.boundary.state.mark("[", "") : "") + chunk.html;
2427
2459
  }
2428
- function writeBranchEnd(scopeId, accessor, serializeStateful, serializeMarker, parentEndTag, singleNode, branchIds) {
2460
+ function resumesMarker(markerGuard, branchExprGuard, parentEndTag) {
2461
+ return markerGuard !== 0 && (!parentEndTag || branchExprGuard !== 0);
2462
+ }
2463
+ function writeBranchEnd(scopeId, accessor, branchExprGuard, markerGuard, parentEndTag, singleNode, branchIds) {
2429
2464
  const endTag = parentEndTag || "";
2430
- if (serializeMarker !== 0) {
2431
- if (!parentEndTag || serializeStateful !== 0) {
2432
- const { state } = $chunk.boundary;
2433
- const mark = singleNode ? state.mark(parentEndTag ? "}" : "|", scopeId + " " + accessor + (branchIds || "")) : state.mark(parentEndTag ? ")" : "]", scopeId + " " + accessor + (branchIds || ""));
2434
- $chunk.writeHTML(mark + endTag);
2435
- } else $chunk.writeHTML(endTag + _el_resume(scopeId, accessor));
2436
- } else $chunk.writeHTML(endTag);
2465
+ if (resumesMarker(markerGuard, branchExprGuard, parentEndTag)) {
2466
+ const { state } = $chunk.boundary;
2467
+ const mark = singleNode ? state.mark(parentEndTag ? "}" : "|", scopeId + " " + accessor + (branchIds || "")) : state.mark(parentEndTag ? ")" : "]", scopeId + " " + accessor + (branchIds || ""));
2468
+ $chunk.writeHTML(mark + endTag);
2469
+ } else if (markerGuard !== 0) $chunk.writeHTML(endTag + _el_resume(scopeId, accessor));
2470
+ else $chunk.writeHTML(endTag);
2437
2471
  }
2438
2472
  let writeScope = (scopeId, partialScope) => {
2439
2473
  const { state } = $chunk.boundary;
@@ -2465,12 +2499,14 @@ function scopeWithId(state, scopeId) {
2465
2499
  if (!scope) scopes.set(scopeId, scope = { [K_SCOPE_ID]: scopeId });
2466
2500
  return scope;
2467
2501
  }
2468
- function _subscribe(subscribers, scope, resumeId, serializeMarker) {
2502
+ function _subscribe(subscribers, scope, resumeId, markerGuard) {
2469
2503
  if (subscribers) {
2470
- const { serializer } = $chunk.boundary.state;
2471
- if (!$chunk.serializeState.readyId && !serializer.written(subscribers)) subscribers.add(scope);
2472
- else if (resumeId) _script(scope[K_SCOPE_ID], resumeId, serializeMarker);
2473
- else serializer.writeCall(scope, subscribers, "add", $chunk.serializeState);
2504
+ const { boundary, serializeState } = $chunk;
2505
+ const { serializer } = boundary.state;
2506
+ if (!serializeState.readyId && !serializer.written(subscribers)) subscribers.add(scope);
2507
+ else if (resumeId) _script(scope[K_SCOPE_ID], resumeId, markerGuard);
2508
+ else serializer.writeCall(scope, subscribers, "add", serializeState);
2509
+ if (boundary.withinCatch) (boundary.subscribed ||= []).push(subscribers, scope, serializeState);
2474
2510
  }
2475
2511
  return scope;
2476
2512
  }
@@ -2478,19 +2514,19 @@ const CLIENT_ALL = 715827883;
2478
2514
  function maskGroup(mask, group) {
2479
2515
  return mask === 715827883 ? 1 : typeof mask === "number" ? group < 15 ? mask >>> 1 + 2 * group & 3 : 0 : mask[group] ?? 0;
2480
2516
  }
2481
- function _set_serialize_reason(reason) {
2482
- $chunk.boundary.state.serializeReason = reason;
2517
+ function _set_scope_reason(reason) {
2518
+ $chunk.boundary.state.scopeReason = reason;
2483
2519
  }
2484
2520
  function _scope_reason() {
2485
- const reason = $chunk.boundary.state.serializeReason;
2486
- $chunk.boundary.state.serializeReason = void 0;
2521
+ const reason = $chunk.boundary.state.scopeReason;
2522
+ $chunk.boundary.state.scopeReason = void 0;
2487
2523
  return reason;
2488
2524
  }
2489
- function _serialize_if(condition, key) {
2525
+ function _write_if(condition, key) {
2490
2526
  return condition && maskGroup(condition, key) ? 1 : void 0;
2491
2527
  }
2492
- function _serialize_guard(condition, key) {
2493
- return _serialize_if(condition, key) || 0;
2528
+ function _write_guard(condition, key) {
2529
+ return _write_if(condition, key) || 0;
2494
2530
  }
2495
2531
  function writeWaitReady(readyId, renderer, input) {
2496
2532
  const chunk = $chunk;
@@ -2503,6 +2539,7 @@ function writeWaitReady(readyId, renderer, input) {
2503
2539
  flushScopes: false
2504
2540
  });
2505
2541
  const bodyEnd = body.render(renderer, input);
2542
+ if (boundary.aborted) throw boundary.reason;
2506
2543
  if (body === bodyEnd) {
2507
2544
  chunk.writeHTML(body.html);
2508
2545
  body.deferOwnReady();
@@ -2512,8 +2549,8 @@ function writeWaitReady(readyId, renderer, input) {
2512
2549
  chunk.next = body;
2513
2550
  }
2514
2551
  }
2515
- function _await(scopeId, accessor, promise, content, serializeMarker) {
2516
- const resumeMarker = serializeMarker !== 0;
2552
+ function _await(scopeId, accessor, promise, content, markerGuard) {
2553
+ const resumeMarker = markerGuard !== 0;
2517
2554
  if (!isPromise(promise)) {
2518
2555
  if (resumeMarker) {
2519
2556
  const branchId = _peek_scope_id();
@@ -2533,7 +2570,8 @@ function _await(scopeId, accessor, promise, content, serializeMarker) {
2533
2570
  promise.then((value) => {
2534
2571
  if (chunk.async) {
2535
2572
  chunk.async = false;
2536
- if (!boundary.signal.aborted) {
2573
+ if (!boundary.aborted) {
2574
+ const { state } = boundary;
2537
2575
  chunk.render(() => {
2538
2576
  if (resumeMarker) {
2539
2577
  const branchId = _peek_scope_id();
@@ -2549,6 +2587,7 @@ function _await(scopeId, accessor, promise, content, serializeMarker) {
2549
2587
  async.end = $chunk;
2550
2588
  }
2551
2589
  });
2590
+ if (!chunk.async && boundary.pendingReorders?.delete(chunk)) state.reorder(chunk);
2552
2591
  boundary.endAsync();
2553
2592
  }
2554
2593
  }
@@ -2595,12 +2634,13 @@ function tryBoundary(content, catchContent, branchId, renderers) {
2595
2634
  const chunk = $chunk;
2596
2635
  const { boundary } = chunk;
2597
2636
  const { state } = boundary;
2598
- const catchBoundary = new Boundary(state, boundary.signal, boundary);
2637
+ const catchBoundary = new Boundary(state, void 0, boundary);
2638
+ if (catchContent) catchBoundary.withinCatch = true;
2599
2639
  const body = chunk.fork(catchBoundary, null);
2600
2640
  const bodyEnd = body.render(() => withBranchId(branchId, content));
2601
- if (catchBoundary.signal.aborted) {
2602
- if (catchContent) catchContent(catchBoundary.signal.reason);
2603
- else boundary.abort(catchBoundary.signal.reason);
2641
+ if (catchBoundary.aborted) {
2642
+ if (!catchContent) throw catchBoundary.reason;
2643
+ catchContent(catchBoundary.reason);
2604
2644
  return true;
2605
2645
  }
2606
2646
  if (body === bodyEnd) {
@@ -2612,49 +2652,69 @@ function tryBoundary(content, catchContent, branchId, renderers) {
2612
2652
  chunk.next = body;
2613
2653
  boundary.startAsync();
2614
2654
  const reorderId = catchContent ? state.nextReorderId() : "";
2615
- const endMarker = reorderId && state.mark("!", reorderId);
2616
2655
  if (reorderId) {
2617
- chunk.writeHTML(state.mark("!^", reorderId));
2618
- bodyEnd.writeHTML(endMarker);
2656
+ chunk.catchRange = {
2657
+ id: reorderId,
2658
+ end: bodyEnd
2659
+ };
2619
2660
  captureContext(chunk);
2620
2661
  }
2621
2662
  catchBoundary.onNext = () => {
2622
- if (boundary.signal.aborted) return;
2623
- if (catchBoundary.signal.aborted) {
2663
+ if (boundary.aborted) return;
2664
+ if (catchBoundary.aborted) {
2624
2665
  if (!reorderId) {
2625
- boundary.abort(catchBoundary.signal.reason);
2666
+ boundary.abort(catchBoundary.reason);
2626
2667
  return;
2627
2668
  }
2628
- if (!bodyEnd.consumed) {
2629
- let cur = body;
2630
- let writeMarker = true;
2631
- do {
2632
- const next = cur.next;
2633
- if (cur.boundary !== catchBoundary) cur.boundary.abort(catchBoundary.signal.reason);
2634
- if (writeMarker && !cur.consumed) {
2635
- writeMarker = false;
2636
- cur.async = false;
2637
- cur.next = bodyNext;
2638
- cur.needsWalk = true;
2639
- cur.html = endMarker;
2640
- cur.scripts = cur.effects = cur.lastEffect = "";
2641
- cur.placeholder = cur.reorderId = cur.deferredReady = null;
2642
- }
2643
- cur = next;
2644
- } while (cur !== bodyNext);
2645
- }
2669
+ const streamed = !chunk.catchRange;
2646
2670
  const catchChunk = chunk.fork(boundary, null);
2647
- catchChunk.reorderId = reorderId;
2648
- catchChunk.render(catchContent, catchBoundary.signal.reason);
2649
- state.reorder(catchChunk);
2671
+ chunk.catchRange = null;
2672
+ if (!renderersAtSettle) catchChunk.render(clearTryRenderers, branchId);
2673
+ const inOrder = catchChunk === catchChunk.render(catchContent, catchBoundary.reason);
2674
+ if (boundary.aborted) return;
2675
+ if (bodyEnd.consumed || !inOrder) catchChunk.reorderStart = state.mark("*", branchId + "");
2676
+ if (bodyEnd.consumed) {
2677
+ catchChunk.reorderId = reorderId;
2678
+ state.reorder(catchChunk);
2679
+ } else {
2680
+ let reorder = null;
2681
+ if (!inOrder) reorder = catchChunk;
2682
+ else if (streamed) reorder = chunk.fork(boundary, null);
2683
+ if (reorder) reorder.reorderId = reorderId;
2684
+ const endMarker = state.mark("!", reorderId);
2685
+ let cut = body;
2686
+ while (cut.consumed) cut = cut.next;
2687
+ cut.async = false;
2688
+ cut.next = inOrder ? catchChunk : bodyNext;
2689
+ cut.html = streamed ? endMarker : inOrder ? "" : state.mark("!^", reorderId) + endMarker;
2690
+ cut.scripts = cut.effects = cut.lastEffect = "";
2691
+ cut.placeholder = cut.reorderId = cut.catchRange = null;
2692
+ cut.deferredReorder = reorder;
2693
+ if (inOrder) catchChunk.next = bodyNext;
2694
+ }
2650
2695
  boundary.endAsync();
2651
2696
  } else if (!catchBoundary.count) {
2652
2697
  if (renderersAtSettle && catchBoundary.resumeWrites) bodyEnd.render(renderers);
2698
+ chunk.catchRange = null;
2653
2699
  boundary.endAsync();
2654
2700
  } else boundary.onNext();
2655
2701
  };
2656
2702
  return renderersAtSettle;
2657
2703
  }
2704
+ function unsubscribe(subscribed, serializer) {
2705
+ for (let i = 0; i < subscribed.length; i += 3) {
2706
+ const subscribers = subscribed[i];
2707
+ const scope = subscribed[i + 1];
2708
+ if (!serializer.written(subscribers)) subscribers.delete(scope);
2709
+ else if (!serializer.dropCall(scope, subscribers, "add")) serializer.writeCall(scope, subscribers, "delete", subscribed[i + 2]);
2710
+ }
2711
+ }
2712
+ function clearTryRenderers(branchId) {
2713
+ writeScope(branchId, {
2714
+ [CatchContent]: 0,
2715
+ [PlaceholderContent]: _scope_with_id(branchId)["#PlaceholderContent"] && 0
2716
+ });
2717
+ }
2658
2718
  function writeTryRenderers(branchId, catchContent, placeholderContent) {
2659
2719
  writeScope(branchId, {
2660
2720
  [CatchContent]: catchContent,
@@ -2694,7 +2754,7 @@ var State = class {
2694
2754
  flushScopes = false;
2695
2755
  writeScopes = {};
2696
2756
  readyIds = null;
2697
- serializeReason;
2757
+ scopeReason;
2698
2758
  $global;
2699
2759
  constructor($global) {
2700
2760
  this.$global = $global;
@@ -2755,38 +2815,57 @@ var State = class {
2755
2815
  return "<!--" + this.commentPrefix + code + str + "-->";
2756
2816
  }
2757
2817
  };
2758
- var Boundary = class extends AbortController {
2818
+ var Boundary = class {
2759
2819
  onNext = NOOP$2;
2760
2820
  count = 0;
2761
2821
  resumeWrites = 0;
2762
2822
  state;
2763
2823
  parent;
2824
+ aborted = false;
2825
+ reason;
2826
+ subscribed;
2827
+ pendingReorders;
2828
+ children;
2829
+ withinCatch = false;
2764
2830
  constructor(state, signal, parent) {
2765
- super();
2766
2831
  this.state = state;
2767
2832
  this.parent = parent;
2768
- this.signal.addEventListener("abort", () => {
2769
- this.count = 0;
2770
- this.state = new State(this.state.$global);
2771
- this.onNext();
2772
- });
2773
- if (signal) {
2833
+ if (parent) {
2834
+ this.withinCatch = parent.withinCatch;
2835
+ if (parent.aborted) this.abort(parent.reason);
2836
+ else (parent.children ||= []).push(this);
2837
+ } else if (signal) {
2774
2838
  if (signal.aborted) this.abort(signal.reason);
2775
2839
  else signal.addEventListener("abort", this);
2776
2840
  }
2777
2841
  }
2842
+ abort(reason) {
2843
+ if (this.aborted) return;
2844
+ const { state } = this;
2845
+ this.aborted = true;
2846
+ this.reason = reason;
2847
+ if (this.subscribed) unsubscribe(this.subscribed, state.serializer);
2848
+ if (this.pendingReorders) {
2849
+ for (const reorder of this.pendingReorders) state.reorder(reorder);
2850
+ this.pendingReorders = void 0;
2851
+ }
2852
+ this.count = 0;
2853
+ this.state = new State(state.$global);
2854
+ if (this.children) for (const child of this.children) child.abort(reason);
2855
+ this.onNext();
2856
+ }
2778
2857
  handleEvent(event) {
2779
2858
  this.abort(event.target.reason);
2780
2859
  }
2781
2860
  flush() {
2782
- if (!this.signal.aborted) flushSerializer(this, this.state);
2783
- return this.count ? 1 : this.signal.aborted ? 2 : 0;
2861
+ if (!this.aborted) flushSerializer(this, this.state);
2862
+ return this.count ? 1 : this.aborted ? 2 : 0;
2784
2863
  }
2785
2864
  startAsync() {
2786
- if (!this.signal.aborted) this.count++;
2865
+ if (!this.aborted) this.count++;
2787
2866
  }
2788
2867
  endAsync() {
2789
- if (!this.signal.aborted) {
2868
+ if (!this.aborted) {
2790
2869
  if (!this.count) throw new Error("A boundary ended more async work than it started.");
2791
2870
  this.count--;
2792
2871
  this.onNext();
@@ -2800,9 +2879,12 @@ var Chunk = class Chunk {
2800
2879
  lastEffect = "";
2801
2880
  async = false;
2802
2881
  consumed = false;
2803
- needsWalk = false;
2804
2882
  reorderId = null;
2883
+ reorderStart = "";
2805
2884
  deferredReady = null;
2885
+ heldEffects = null;
2886
+ deferredReorder = null;
2887
+ catchRange = null;
2806
2888
  placeholder = null;
2807
2889
  boundary;
2808
2890
  next;
@@ -2822,7 +2904,7 @@ var Chunk = class Chunk {
2822
2904
  }
2823
2905
  writeEffect(scopeId, registryId) {
2824
2906
  countResumeWrite(this);
2825
- if (this.lastEffect === registryId) this.effects += " " + scopeId;
2907
+ if (this.lastEffect === registryId) this.effects = concatEffects(this.effects, scopeId + "");
2826
2908
  else {
2827
2909
  this.lastEffect = registryId;
2828
2910
  this.effects = concatEffects(this.effects, registryId + " " + scopeId);
@@ -2833,12 +2915,16 @@ var Chunk = class Chunk {
2833
2915
  }
2834
2916
  append(chunk) {
2835
2917
  this.html += chunk.html;
2836
- this.needsWalk ||= chunk.needsWalk;
2837
2918
  this.effects = concatEffects(this.effects, chunk.effects);
2838
2919
  this.scripts = concatScripts(this.scripts, chunk.scripts);
2839
2920
  this.lastEffect = chunk.lastEffect || this.lastEffect;
2840
2921
  this.deferredReady = concat(this.deferredReady, chunk.takeDeferredReady());
2841
2922
  }
2923
+ takeHeldEffects() {
2924
+ const { heldEffects } = this;
2925
+ this.heldEffects = null;
2926
+ return heldEffects;
2927
+ }
2842
2928
  takeDeferredReady() {
2843
2929
  const { deferredReady } = this;
2844
2930
  this.deferredReady = null;
@@ -2853,64 +2939,123 @@ var Chunk = class Chunk {
2853
2939
  this.deferredReady = concat(deferred, this.deferredReady);
2854
2940
  }
2855
2941
  }
2856
- flushPlaceholder() {
2857
- const { placeholder } = this;
2858
- if (placeholder) {
2859
- this.placeholder = null;
2860
- const body = placeholder.body.consume();
2861
- if (body.async) {
2862
- const { state } = this.boundary;
2863
- const { branchId, scopeId, placeholderBranchId } = placeholder;
2864
- const reorderId = body.reorderId = branchId ? branchId + "" : state.nextReorderId();
2865
- this.writeHTML(state.mark("!^", reorderId));
2866
- const { effects } = this;
2867
- const beforeBranch = deferBranchStart(this);
2868
- if (this.render(() => withBranchId(placeholderBranchId, placeholder.render)) !== this) this.boundary.abort(/* @__PURE__ */ new Error("An @placeholder cannot contain async content."));
2869
- if (this.boundary.signal.aborted) return;
2870
- const stateful = this.effects !== effects;
2871
- applyBranchStart(this, beforeBranch, stateful);
2872
- if (stateful) {
2873
- this.render(() => writeScope(branchId, { [PlaceholderBranch]: scopeWithId(state, placeholderBranchId) }));
2874
- this.writeHTML(state.mark("]", scopeId + " " + (PlaceholderBranch + branchId) + " " + placeholderBranchId));
2875
- body.writeEffect(branchId, PLACEHOLDER_DISMISS_REGISTER_ID);
2942
+ renderPlaceholders(boundary) {
2943
+ const { state } = boundary;
2944
+ restart: for (;;) {
2945
+ let reorders = null;
2946
+ for (let cur = this; cur.next && !cur.async; cur = cur.next) {
2947
+ if (cur.renderPlaceholder(state)) {
2948
+ if (boundary.aborted) return;
2949
+ continue restart;
2876
2950
  }
2877
- this.writeHTML(state.mark("!", reorderId));
2878
- state.reorder(body);
2879
- } else {
2880
- body.next = this.next;
2881
- this.next = body;
2951
+ if (cur.deferredReorder) (reorders ||= []).push(cur.deferredReorder);
2882
2952
  }
2953
+ if (state.writeReorders) {
2954
+ for (const reorder of state.writeReorders) if ((reorders = renderReorderPlaceholders(reorder, reorders)) === false) {
2955
+ if (boundary.aborted) return;
2956
+ continue restart;
2957
+ }
2958
+ }
2959
+ for (let i = 0; reorders && i < reorders.length; i++) if ((reorders = renderReorderPlaceholders(reorders[i], reorders)) === false) {
2960
+ if (boundary.aborted) return;
2961
+ continue restart;
2962
+ }
2963
+ return;
2883
2964
  }
2884
2965
  }
2885
- consume() {
2966
+ renderPlaceholder(state) {
2967
+ const { placeholder } = this;
2968
+ if (!placeholder) return false;
2969
+ this.placeholder = null;
2970
+ if (this.boundary.aborted) return false;
2971
+ const { body } = placeholder;
2972
+ let end = body;
2973
+ while (end.next && !end.async) end = end.next;
2974
+ if (!end.async) {
2975
+ end.next = this.next;
2976
+ this.next = body;
2977
+ return false;
2978
+ }
2979
+ const { branchId, scopeId, placeholderBranchId } = placeholder;
2980
+ const reorderId = body.reorderId = branchId + "";
2981
+ this.writeHTML(state.mark("!^", reorderId));
2982
+ const { effects } = this;
2983
+ const beforeBranch = deferBranchStart(this);
2984
+ if (this.render(() => withBranchId(placeholderBranchId, placeholder.render)) !== this) this.boundary.abort(/* @__PURE__ */ new Error("An @placeholder cannot contain async content."));
2985
+ if (this.boundary.aborted) return true;
2986
+ const stateful = this.effects !== effects;
2987
+ applyBranchStart(this, beforeBranch, stateful);
2988
+ if (stateful) {
2989
+ this.render(() => writeScope(branchId, { [PlaceholderBranch]: scopeWithId(state, placeholderBranchId) }));
2990
+ this.writeHTML(state.mark("]", scopeId + " " + (PlaceholderBranch + branchId) + " " + placeholderBranchId));
2991
+ dismissChunk(end, body).writeEffect(branchId, PLACEHOLDER_DISMISS_REGISTER_ID);
2992
+ }
2993
+ this.writeHTML(state.mark("!", reorderId));
2994
+ this.deferredReorder = body;
2995
+ return false;
2996
+ }
2997
+ markCatchRange() {
2998
+ const { catchRange } = this;
2999
+ if (catchRange) {
3000
+ const { state } = this.boundary;
3001
+ this.catchRange = null;
3002
+ this.writeHTML(state.mark("!^", catchRange.id));
3003
+ catchRange.end.writeHTML(state.mark("!", catchRange.id));
3004
+ }
3005
+ }
3006
+ queueDeferredReorder() {
3007
+ const { deferredReorder } = this;
3008
+ if (deferredReorder) {
3009
+ this.deferredReorder = null;
3010
+ deferredReorder.boundary.state.reorder(deferredReorder);
3011
+ }
3012
+ }
3013
+ consume(boundary) {
3014
+ this.renderPlaceholders(boundary);
2886
3015
  let cur = this;
2887
3016
  let html = "";
2888
3017
  let effects = "";
2889
3018
  let scripts = "";
2890
- let lastEffect = "";
2891
- let needsWalk = false;
3019
+ let effectsEnd;
3020
+ let heldEffects = this.heldEffects;
2892
3021
  let deferredReady;
3022
+ this.heldEffects = null;
3023
+ if (this.serializeState.readyId && this.effects) followHeldEffects(this);
2893
3024
  while (cur.next && !cur.async) {
2894
- cur.flushPlaceholder();
2895
- needsWalk ||= cur.needsWalk;
3025
+ cur.markCatchRange();
3026
+ cur.queueDeferredReorder();
2896
3027
  html += cur.html;
2897
3028
  if (cur.serializeState.readyId) deferredReady = push(deferredReady, cur);
2898
3029
  else {
2899
- effects = concatEffects(effects, cur.effects);
3030
+ if (cur.effects) {
3031
+ if (effectsEnd && effectsEnd.boundary !== cur.boundary) {
3032
+ heldEffects = holdEffectsOn(heldEffects, effectsEnd, effects);
3033
+ effects = "";
3034
+ }
3035
+ effectsEnd = cur;
3036
+ effects = concatEffects(effects, cur.effects);
3037
+ }
2900
3038
  scripts = concatScripts(scripts, cur.scripts);
2901
- lastEffect = cur.lastEffect || lastEffect;
2902
3039
  }
2903
3040
  deferredReady = concat(deferredReady, cur.takeDeferredReady());
2904
3041
  cur.consumed = true;
2905
3042
  cur = cur.next;
2906
3043
  }
2907
3044
  cur.deferOwnReady();
3045
+ if (effects) {
3046
+ if (cur.serializeState.readyId) heldEffects = holdEffectsOn(heldEffects, effectsEnd, effects);
3047
+ else if (effectsEnd.boundary !== cur.boundary) {
3048
+ heldEffects = holdEffectsOn(heldEffects, effectsEnd, effects);
3049
+ if (isWithin(cur.boundary, effectsEnd.boundary)) cur.lastEffect ||= effectsEnd.lastEffect;
3050
+ } else {
3051
+ cur.effects = concatEffects(effects, cur.effects);
3052
+ cur.lastEffect ||= effectsEnd.lastEffect;
3053
+ }
3054
+ }
3055
+ cur.heldEffects = heldEffects;
2908
3056
  cur.deferredReady = concat(deferredReady, cur.deferredReady);
2909
- cur.needsWalk ||= needsWalk;
2910
3057
  cur.html = html + cur.html;
2911
- cur.effects = concatEffects(effects, cur.effects);
2912
3058
  cur.scripts = concatScripts(scripts, cur.scripts);
2913
- cur.lastEffect ||= lastEffect;
2914
3059
  return cur;
2915
3060
  }
2916
3061
  render(content, val) {
@@ -2930,10 +3075,12 @@ var Chunk = class Chunk {
2930
3075
  const { serializeState } = this;
2931
3076
  const { readyId } = serializeState;
2932
3077
  let scripts = "";
2933
- forEach(this.takeDeferredReady(), (chunk) => {
3078
+ const held = this.takeDeferredReady();
3079
+ if (held) for (const chunk of Array.isArray(held) ? held : [held]) {
3080
+ if (chunk.boundary.aborted) continue;
2934
3081
  scripts = concatScripts(scripts, chunk.flushReadyScripts(boundary, reservations, holdEffects));
2935
3082
  if (chunk.effects || chunk.deferredReady) this.deferredReady = push(this.deferredReady, chunk);
2936
- });
3083
+ }
2937
3084
  if (readyId && !this.async) {
2938
3085
  const { state } = boundary;
2939
3086
  flushSerializer(boundary, serializeState);
@@ -2961,16 +3108,18 @@ var Chunk = class Chunk {
2961
3108
  const { $global, runtimePrefix } = state;
2962
3109
  let needsWalk = state.walkOnNextFlush;
2963
3110
  if (needsWalk) state.walkOnNextFlush = false;
3111
+ flushSerializer(boundary, state);
2964
3112
  let readyResumeScripts = this.flushReadyScripts(boundary, void 0, this.async);
2965
- for (let channel; !boundary.signal.aborted && (channel = state.serializer.pendingReadyChannel());) {
3113
+ for (let channel; !boundary.aborted && (channel = state.serializer.pendingReadyChannel());) {
2966
3114
  const resumes = state.serializer.stringifyScopes([], boundary, channel);
2967
3115
  const deps = state.serializer.takeChannelDeps();
2968
3116
  state.needsMainRuntime = true;
2969
3117
  readyResumeScripts = concatScripts(readyResumeScripts, state.writeReady(channel.readyId, concatSequence(depsMarker(deps), resumes)));
2970
3118
  }
2971
3119
  if (readyResumeScripts) needsWalk = true;
2972
- const effects = this.async ? "" : this.effects;
3120
+ const effects = this.async ? "" : joinHeldEffects(this.takeHeldEffects(), this.effects);
2973
3121
  let { html, scripts } = this;
3122
+ if (html && state.hasReorderRuntime) html = state.mark("*", "") + html;
2974
3123
  if (state.needsMainRuntime && !state.hasMainRuntime) {
2975
3124
  state.hasMainRuntime = true;
2976
3125
  scripts = concatScripts(scripts, WALKER_RUNTIME_CODE + "(\"" + $global.runtimeId + "\")(\"" + $global.renderId + "\")");
@@ -2983,64 +3132,60 @@ var Chunk = class Chunk {
2983
3132
  let reordered = "";
2984
3133
  let needsResumeArray = false;
2985
3134
  if (state.writeReorders) {
2986
- let carried = null;
2987
3135
  for (const reorderedChunk of state.writeReorders) {
2988
- if (reorderedChunk.async && reorderedChunk.consumed) {
2989
- let aborted = reorderedChunk.boundary;
2990
- while (aborted && !aborted.signal.aborted) aborted = aborted.parent;
2991
- if (!aborted) {
2992
- (carried ||= []).push(reorderedChunk);
2993
- continue;
2994
- }
2995
- reorderedChunk.async = false;
2996
- }
2997
3136
  needsWalk = true;
2998
3137
  if (!state.hasReorderRuntime) {
2999
3138
  state.hasReorderRuntime = true;
3000
3139
  scripts = concatScripts(scripts, REORDER_RUNTIME_CODE + "(" + runtimePrefix + ")");
3001
3140
  }
3002
- const { reorderId } = reorderedChunk;
3141
+ const { reorderId, reorderStart } = reorderedChunk;
3003
3142
  const readyReservations = [];
3004
3143
  let reorderHTML = "";
3005
3144
  let reorderEffects = "";
3145
+ let effectsBoundary = reorderedChunk.boundary;
3006
3146
  let reorderScripts = "";
3007
- let cur = reorderedChunk;
3147
+ let cur = reorderedChunk.boundary.aborted ? null : reorderedChunk;
3008
3148
  reorderedChunk.reorderId = null;
3009
- for (;;) {
3010
- cur.flushPlaceholder();
3149
+ while (cur) {
3150
+ cur.markCatchRange();
3151
+ cur.queueDeferredReorder();
3011
3152
  cur.deferOwnReady();
3012
3153
  const { next } = cur;
3013
3154
  const readyResumeScripts = cur.flushReadyScripts(boundary, readyReservations, this.async);
3014
3155
  this.deferredReady = concat(this.deferredReady, cur.takeDeferredReady());
3015
3156
  cur.consumed = true;
3016
3157
  reorderHTML += cur.html;
3158
+ if (this.async && cur.effects && cur.boundary !== effectsBoundary) {
3159
+ if (reorderEffects) {
3160
+ holdReorderEffects(this, effectsBoundary, reorderEffects);
3161
+ reorderEffects = "";
3162
+ }
3163
+ effectsBoundary = cur.boundary;
3164
+ }
3017
3165
  reorderEffects = concatEffects(reorderEffects, cur.effects);
3018
3166
  reorderScripts = concatScripts(reorderScripts, concatScripts(readyResumeScripts, cur.scripts));
3019
3167
  if (cur.async) {
3020
3168
  reorderHTML += state.mark("#", cur.reorderId = state.nextReorderId());
3021
- state.reorder(cur);
3169
+ cur.reorderStart = reorderStart;
3170
+ (cur.boundary.pendingReorders ||= /* @__PURE__ */ new Set()).add(cur);
3022
3171
  cur.html = cur.effects = cur.scripts = cur.lastEffect = "";
3023
3172
  cur.next = null;
3024
3173
  }
3025
- if (next) cur = next;
3026
- else break;
3174
+ cur = next;
3027
3175
  }
3028
3176
  if (reorderEffects) {
3029
- if (this.async) {
3030
- this.effects = concatEffects(this.effects, reorderEffects);
3031
- this.lastEffect = "";
3032
- } else {
3177
+ if (this.async) holdReorderEffects(this, effectsBoundary, reorderEffects);
3178
+ else {
3033
3179
  needsResumeArray = true;
3034
3180
  reorderScripts = concatScripts(reorderScripts, "_.push(\"" + reorderEffects + "\")");
3035
3181
  }
3036
3182
  }
3037
3183
  for (const reservation of readyReservations) reordered = concatScripts(reordered, reservation);
3038
3184
  reordered = concatScripts(reordered, reorderScripts && runtimePrefix + ".j" + toAccess(reorderId) + "=_=>{" + reorderScripts + "}");
3039
- html += "<t hidden " + state.commentPrefix + "=" + reorderId + ">" + reorderHTML + "</t>";
3185
+ html += "<t hidden " + state.commentPrefix + "=" + reorderId + ">" + reorderStart + reorderHTML + "</t>";
3040
3186
  }
3041
- state.writeReorders = carried;
3187
+ state.writeReorders = null;
3042
3188
  }
3043
- flushSerializer(boundary, state);
3044
3189
  if (state.resumes || needsResumeArray && !state.hasWrittenResume) scripts = concatScripts(scripts, state.resumeScript(state.resumes));
3045
3190
  scripts = concatScripts(scripts, reordered);
3046
3191
  if (needsWalk) scripts = concatScripts(scripts, state.walkScript());
@@ -3052,16 +3197,54 @@ var Chunk = class Chunk {
3052
3197
  }
3053
3198
  flushHTML(boundary) {
3054
3199
  const { state } = boundary;
3055
- if (this.needsWalk) {
3056
- this.needsWalk = false;
3057
- state.walkOnNextFlush = true;
3058
- }
3059
3200
  this.flushScript(boundary);
3060
3201
  const { html, scripts } = this;
3061
3202
  this.html = this.scripts = "";
3062
3203
  return state.flushChunk(html, scripts, boundary.count);
3063
3204
  }
3064
3205
  };
3206
+ function renderReorderPlaceholders(reorder, reorders) {
3207
+ if (!reorder.boundary.aborted) for (let cur = reorder; cur; cur = cur.next) {
3208
+ if (cur.renderPlaceholder(reorder.boundary.state)) return false;
3209
+ if (cur.deferredReorder) (reorders ||= []).push(cur.deferredReorder);
3210
+ }
3211
+ return reorders;
3212
+ }
3213
+ function dismissChunk(end, body) {
3214
+ if (end.boundary !== body.boundary) while (end.next) end = end.next;
3215
+ return end;
3216
+ }
3217
+ function followHeldEffects(chunk) {
3218
+ const held = reduce(chunk.deferredReady, lastHeldOf, chunk);
3219
+ if (held !== chunk) {
3220
+ held.effects = concatEffects(held.effects, chunk.effects);
3221
+ chunk.effects = "";
3222
+ }
3223
+ }
3224
+ function lastHeldOf(held, cur) {
3225
+ return cur.serializeState === held.serializeState && cur.boundary === held.boundary ? cur : held;
3226
+ }
3227
+ function holdEffectsOn(heldEffects, chunk, effects) {
3228
+ chunk.effects = effects;
3229
+ return push(heldEffects, chunk);
3230
+ }
3231
+ function isWithin(boundary, outer) {
3232
+ while (boundary && boundary !== outer) boundary = boundary.parent;
3233
+ return !!boundary;
3234
+ }
3235
+ function holdReorderEffects(head, boundary, effects) {
3236
+ if (!head.serializeState.readyId) {
3237
+ if (head.effects) head.heldEffects = holdEffectsOn(head.heldEffects, head.fork(head.boundary, null), head.effects);
3238
+ head.effects = head.lastEffect = "";
3239
+ }
3240
+ head.heldEffects = holdEffectsOn(head.heldEffects, head.fork(boundary, null), effects);
3241
+ }
3242
+ function joinHeldEffects(heldEffects, effects) {
3243
+ return concatEffects(reduce(heldEffects, joinUncaught, ""), effects);
3244
+ }
3245
+ function joinUncaught(joined, held) {
3246
+ return held.boundary.aborted ? joined : concatEffects(joined, held.effects);
3247
+ }
3065
3248
  function flushSerializer(boundary, serializeState) {
3066
3249
  const { state } = boundary;
3067
3250
  const { serializer } = state;
@@ -3223,8 +3406,8 @@ function _escape_comment(val) {
3223
3406
  //#endregion
3224
3407
  //#region src/html/dynamic-tag.ts
3225
3408
  const voidElementsReg = /^(?:area|b(?:ase|r)|col|embed|hr|i(?:mg|nput)|link|meta|param|source|track|wbr)$/;
3226
- let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, serializeReason) => {
3227
- const shouldResume = serializeReason !== 0;
3409
+ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, markerGuard) => {
3410
+ const shouldResume = markerGuard !== 0;
3228
3411
  const renderer = normalizeDynamicRenderer(tag);
3229
3412
  const state = getState();
3230
3413
  const branchId = _peek_scope_id();
@@ -3244,8 +3427,8 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, s
3244
3427
  _html(_attrs_textarea_value(branchId, `#${renderer.toLowerCase()}/0`, input));
3245
3428
  } else {
3246
3429
  if (renderContent && typeof renderContent !== "function") throw new Error(`Body content is not supported for the \`<${renderer}>\` tag.`);
3247
- if (renderer === "select" && ("value" in input || "valueChange" in input)) _attr_select_value(branchId, `#${renderer.toLowerCase()}/0`, input.value, input.valueChange, renderContent ? () => _dynamic_tag(branchId, `#${renderer.toLowerCase()}/0`, renderContent, void 0, 0, void 0, serializeReason) : void 0, 1);
3248
- else if (renderContent) _dynamic_tag(branchId, `#${renderer.toLowerCase()}/0`, renderContent, void 0, 0, void 0, serializeReason);
3430
+ if (renderer === "select" && ("value" in input || "valueChange" in input)) _attr_select_value(branchId, `#${renderer.toLowerCase()}/0`, input.value, input.valueChange, renderContent ? () => _dynamic_tag(branchId, `#${renderer.toLowerCase()}/0`, renderContent, void 0, 0, void 0, markerGuard) : void 0, 1);
3431
+ else if (renderContent) _dynamic_tag(branchId, `#${renderer.toLowerCase()}/0`, renderContent, void 0, 0, void 0, markerGuard);
3249
3432
  }
3250
3433
  _html(`</${renderer}>`);
3251
3434
  } else if (content) throw new Error(`Body content is not supported for the \`<${renderer}>\` tag.`);
@@ -3264,13 +3447,13 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, s
3264
3447
  const beforeBranch = shouldResume ? deferBranchStart(chunk) : void 0;
3265
3448
  const render = () => {
3266
3449
  if (renderer) try {
3267
- _set_serialize_reason(shouldResume && inputOrArgs !== void 0 ? CLIENT_ALL : 0);
3450
+ _set_scope_reason(shouldResume && inputOrArgs !== void 0 ? CLIENT_ALL : 0);
3268
3451
  return inputIsArgs ? renderer(...inputOrArgs) : renderer(content ? {
3269
3452
  ...inputOrArgs,
3270
3453
  content
3271
3454
  } : inputOrArgs);
3272
3455
  } finally {
3273
- _set_serialize_reason(void 0);
3456
+ _set_scope_reason(void 0);
3274
3457
  }
3275
3458
  else if (content) return content();
3276
3459
  };
@@ -3486,13 +3669,13 @@ var ServerRendered = class {
3486
3669
  switch (!boundary.count && boundary.flush()) {
3487
3670
  case 2:
3488
3671
  settle(boundary);
3489
- reject(boundary.signal.reason);
3672
+ reject(boundary.reason);
3490
3673
  break;
3491
3674
  case 0:
3492
- head = head.consume();
3493
- if (boundary.signal.aborted) break;
3675
+ head = head.consume(boundary);
3676
+ if (boundary.aborted) break;
3494
3677
  html += head.flushHTML(boundary);
3495
- if (!(boundary.count || boundary.signal.aborted)) {
3678
+ if (!(boundary.count || boundary.aborted)) {
3496
3679
  settle(boundary);
3497
3680
  resolve(html);
3498
3681
  }
@@ -3523,14 +3706,14 @@ var ServerRendered = class {
3523
3706
  if (status === 2) {
3524
3707
  if (!tick) offTick(onNext);
3525
3708
  settle(boundary);
3526
- onAbort(boundary.signal.reason);
3709
+ onAbort(boundary.reason);
3527
3710
  return;
3528
3711
  }
3529
3712
  if (write || status === 0) {
3530
- head = head.consume();
3531
- if (boundary.signal.aborted) continue;
3713
+ head = head.consume(boundary);
3714
+ if (boundary.aborted) continue;
3532
3715
  const html = head.flushHTML(boundary);
3533
- if (boundary.signal.aborted) continue;
3716
+ if (boundary.aborted) continue;
3534
3717
  if (html) onWrite(html);
3535
3718
  if (!boundary.count) {
3536
3719
  if (!tick) offTick(onNext);
@@ -3554,10 +3737,10 @@ var ServerRendered = class {
3554
3737
  this.#head = null;
3555
3738
  if (!head) throw new Error(CONSUMED_RESULT_MESSAGE);
3556
3739
  const { boundary } = head;
3557
- const html = boundary.flush() === 0 ? head.consume().flushHTML(boundary) : "";
3740
+ const html = boundary.flush() === 0 ? head.consume(boundary).flushHTML(boundary) : "";
3558
3741
  if (boundary.count) boundary.abort(/* @__PURE__ */ new Error("Cannot consume asynchronous render with 'toString'"));
3559
3742
  settle(boundary);
3560
- if (boundary.signal.aborted) throw boundary.signal.reason;
3743
+ if (boundary.aborted) throw boundary.reason;
3561
3744
  return html;
3562
3745
  }
3563
3746
  };
@@ -3569,19 +3752,18 @@ function NOOP$1() {}
3569
3752
  //#endregion
3570
3753
  //#region src/html/assets.ts
3571
3754
  const kAssets = Symbol();
3572
- const kBlockIndex = Symbol();
3573
- const kDeferIndex = Symbol();
3574
- let assetFlush;
3575
- function withLoadAssets(renderer, assetId, triggers) {
3755
+ const kHead = Symbol();
3756
+ function withLoadAssets(renderer, flush, assetId, triggers) {
3576
3757
  return Object.assign((input) => {
3577
- const g = $global();
3578
- addAsset(g, assetId, triggers);
3579
- _html(flush(g, ""));
3758
+ writeLoadAsset(assetId, flush, triggers);
3580
3759
  return writeWaitReady(assetId, renderer, input);
3581
3760
  }, renderer);
3582
3761
  }
3762
+ function writeLoadAsset(assetId, flush, triggers) {
3763
+ const g = $global();
3764
+ writeAsset(g, addAsset(g, assetId, flush, triggers));
3765
+ }
3583
3766
  function withPageAssets(template, runtime, assetId, runtimeId) {
3584
- assetFlush = runtime;
3585
3767
  return Object.assign((input) => {
3586
3768
  const g = $global();
3587
3769
  if (runtimeId) {
@@ -3590,57 +3772,78 @@ function withPageAssets(template, runtime, assetId, runtimeId) {
3590
3772
  g.runtimeId = runtimeId;
3591
3773
  } else if (g.runtimeId !== runtimeId) console.error(`A page entry compiled with runtimeId "${runtimeId}" is nested in a render using runtimeId "${g.runtimeId}", so its content cannot resume.`);
3592
3774
  }
3593
- addAsset(g, assetId);
3775
+ const asset = addAsset(g, assetId, runtime);
3594
3776
  if (g.__flush__) {
3595
- _html(flush(g, ""));
3777
+ writeAsset(g, asset);
3596
3778
  return writeWaitReady(assetId, template, input);
3597
3779
  }
3598
- g.__flush__ = flush;
3780
+ g.__flush__ = flushPage;
3599
3781
  return template(input);
3600
3782
  }, template);
3601
3783
  }
3602
3784
  function _flush_head() {
3603
3785
  const g = $global();
3604
- return g[kAssets] ? flush(g, "") : "";
3786
+ if (!g[kAssets]) return "";
3787
+ g[kHead] = true;
3788
+ return takeAssets(g, catchableBoundary());
3789
+ }
3790
+ function flushPage(g, html) {
3791
+ return takeAssets(g, null) + html;
3792
+ }
3793
+ function takeAssets(g, at) {
3794
+ let block = "";
3795
+ let defer = "";
3796
+ for (const asset of g[kAssets]) if (asset.htmlAt === void 0) {
3797
+ asset.htmlAt = at;
3798
+ block += blockHTML(g, asset);
3799
+ if (!asset.triggers) defer += deferHTML(g, asset);
3800
+ }
3801
+ return block + defer;
3802
+ }
3803
+ function writeAsset(g, asset) {
3804
+ if (needsWrite(asset.htmlAt)) {
3805
+ asset.htmlAt = void 0;
3806
+ if (g[kHead] || g.__flush__ !== flushPage) {
3807
+ const block = blockHTML(g, asset);
3808
+ _html(block + (asset.triggers ? "" : deferHTML(g, asset)));
3809
+ if (block && isInResumedBranch()) writeScript(`document.head.insertAdjacentHTML("beforeend",${_escape_script(JSON.stringify(block))})`);
3810
+ asset.htmlAt = catchableBoundary();
3811
+ }
3812
+ }
3813
+ if (asset.triggers && needsWrite(asset.scriptAt)) {
3814
+ const defer = deferHTML(g, asset);
3815
+ if (defer) writeScript(asset.script ||= triggerScript(asset.id, defer, asset.triggers));
3816
+ asset.scriptAt = catchableBoundary();
3817
+ }
3605
3818
  }
3606
- function flush(g, html) {
3607
- let result = "";
3608
- const assets = g[kAssets];
3609
- const { length } = assets;
3610
- let bi = g[kBlockIndex];
3611
- let di = g[kDeferIndex];
3612
- for (; bi < length; bi++) result += assetFlush(g, "block", assets[bi].id);
3613
- for (; di < length; di++) {
3614
- const { id, triggers } = assets[di];
3615
- const deferHTML = assetFlush(g, "defer", id);
3616
- if (triggers) {
3617
- if (deferHTML) writeTriggerScript(id, deferHTML, triggers);
3618
- } else result += deferHTML;
3619
- }
3620
- g[kBlockIndex] = bi;
3621
- g[kDeferIndex] = di;
3622
- return result + html;
3623
- }
3624
- function addAsset(g, id, triggers) {
3625
- const assets = g[kAssets];
3626
- if (!assets) {
3627
- g[kAssets] = [{
3628
- id,
3629
- triggers
3630
- }];
3631
- g[kBlockIndex] = g[kDeferIndex] = 0;
3632
- } else if (!assets.find((a) => a.id === id)) assets.push({
3819
+ function needsWrite(at) {
3820
+ return at === void 0 || at !== null && mayDrop(at);
3821
+ }
3822
+ function blockHTML(g, asset) {
3823
+ return asset.block ??= asset.flush(g, "block", asset.id);
3824
+ }
3825
+ function deferHTML(g, asset) {
3826
+ return asset.defer ??= asset.flush(g, "defer", asset.id);
3827
+ }
3828
+ function addAsset(g, id, flush, triggers) {
3829
+ const assets = g[kAssets] ||= [];
3830
+ let asset = assets.find((a) => a.id === id);
3831
+ if (!asset) assets.push(asset = {
3633
3832
  id,
3634
- triggers
3833
+ flush,
3834
+ triggers,
3835
+ block: void 0,
3836
+ defer: void 0,
3837
+ script: void 0,
3838
+ htmlAt: void 0,
3839
+ scriptAt: void 0
3635
3840
  });
3636
- else {
3637
- const existing = assets.find((a) => a.id === id);
3638
- if (JSON.stringify(existing.triggers) !== JSON.stringify(triggers)) console.error(`The lazy asset "${id}" is imported with different \`load\` triggers; an asset must use one consistent trigger.`);
3639
- }
3841
+ else if (JSON.stringify(asset.triggers) !== JSON.stringify(triggers)) console.error(`The lazy asset "${id}" is imported with different \`load\` triggers; an asset must use one consistent trigger.`);
3842
+ return asset;
3640
3843
  }
3641
- function writeTriggerScript(id, html, triggers) {
3844
+ function triggerScript(id, html, triggers) {
3642
3845
  const htmlStr = _escape_script(JSON.stringify(html));
3643
- const insert = `(d=new Range().createContextualFragment(h),d.querySelectorAll("script").forEach(s=>s.onerror=()=>console.error(${_escape_script(JSON.stringify(`The lazy module for "${id}" failed to load; its server-rendered content cannot become interactive.`))})),p.after(d))`;
3846
+ const insert = `(d=new Range().createContextualFragment(h),d.querySelectorAll("script").forEach(s=>s.onerror=()=>console.error(${_escape_script(JSON.stringify(`The lazy module for "${id}" failed to load; its server-rendered content cannot become interactive.`))})),document.head.append(d))`;
3644
3847
  const exprs = triggers.map((trigger) => {
3645
3848
  const options = trigger.options && toObjectExpression(trigger.options);
3646
3849
  switch (trigger.type) {
@@ -3650,7 +3853,7 @@ function writeTriggerScript(id, html, triggers) {
3650
3853
  default: return `(e=>e?.addEventListener("${trigger.type.slice(3)}",l,{once:1}))(${querySelectorOrLoad(trigger.selector)})`;
3651
3854
  }
3652
3855
  });
3653
- writeScript(`((p,h,d,l=$=>{d||${insert}})=>${exprs.length > 1 ? `{${exprs.join(";")}}` : exprs[0]})(document.currentScript,${htmlStr})`);
3856
+ return `((h,d,l=$=>{d||${insert}})=>${exprs.length > 1 ? `{${exprs.join(";")}}` : exprs[0]})(${htmlStr})`;
3654
3857
  }
3655
3858
  function querySelectorOrLoad(selector) {
3656
3859
  return `document.querySelector(${JSON.stringify(selector)})||${`(console.warn(${JSON.stringify(`A lazy load trigger could not find an element matching "${selector}". The module was loaded immediately.`)}),l())`}`;
@@ -3674,6 +3877,7 @@ const K_TAGS_API_STATE = Symbol();
3674
3877
  const COMPAT_REGISTRY = /* @__PURE__ */ new WeakMap();
3675
3878
  const compat = {
3676
3879
  $global,
3880
+ writeLoadAsset,
3677
3881
  fork: _await,
3678
3882
  write: _html,
3679
3883
  writeScript,
@@ -3697,7 +3901,10 @@ const compat = {
3697
3901
  onFlush(fn) {
3698
3902
  const { flushHTML } = Chunk.prototype;
3699
3903
  Chunk.prototype.flushHTML = function(boundary) {
3904
+ const { state } = boundary;
3905
+ const reorders = swapReorders(state, null);
3700
3906
  fn(this);
3907
+ swapReorders(state, reorders);
3701
3908
  return flushHTML.call(this, boundary);
3702
3909
  };
3703
3910
  },
@@ -3723,21 +3930,52 @@ const compat = {
3723
3930
  return compatRegistered;
3724
3931
  };
3725
3932
  },
3933
+ joinChunks(chunks) {
3934
+ let joined;
3935
+ for (const chunk of chunks) {
3936
+ if (chunk.boundary.aborted) continue;
3937
+ if (joined) joined.append(chunk);
3938
+ else joined = chunk;
3939
+ }
3940
+ return joined;
3941
+ },
3942
+ appendChunks(chunks) {
3943
+ const chunk = getChunk();
3944
+ for (const part of chunks) {
3945
+ chunk.append(part);
3946
+ if (part.effects) chunk.lastEffect = part.lastEffect;
3947
+ }
3948
+ },
3949
+ deferReorders(reorders) {
3950
+ const chunk = getChunk();
3951
+ for (let i = reorders.length; i--;) {
3952
+ const carrier = chunk.fork(chunk.boundary, chunk.next);
3953
+ carrier.deferredReorder = reorders[i];
3954
+ chunk.next = carrier;
3955
+ }
3956
+ },
3726
3957
  createChunk($global) {
3727
3958
  const state = this.ensureState($global);
3728
3959
  return new Chunk(new Boundary(state), null, null, state);
3729
3960
  },
3730
- flushScript($global, chunk) {
3731
- chunk ||= this.createChunk($global);
3961
+ flushScript(chunk, reorders) {
3732
3962
  const { boundary } = chunk;
3733
- const scripts = boundary.flush() === 0 ? chunk.flushScript(boundary).scripts : "";
3734
- if (boundary.signal.aborted) throw boundary.signal.reason;
3963
+ const { state } = boundary;
3964
+ let html = "";
3965
+ let scripts = "";
3966
+ if (reorders) for (const reorder of reorders) state.reorder(reorder);
3967
+ if (boundary.flush() === 0) ({html, scripts} = chunk.flushScript(boundary));
3968
+ if (boundary.aborted) throw boundary.reason;
3735
3969
  if (boundary.count) throw new Error("Cannot serialize promise across tags/class compat layer.");
3736
- return scripts;
3970
+ return {
3971
+ html,
3972
+ scripts
3973
+ };
3737
3974
  },
3738
- render(renderer, willRerender, classAPIOut, component, input, completeChunks, registerChildScope) {
3975
+ render(renderer, willRerender, classAPIOut, component, input, componentScopes, registerChildScope, parentChunk) {
3976
+ if (parentChunk?.boundary.aborted) return;
3739
3977
  const state = this.ensureState(classAPIOut.global);
3740
- const boundary = new Boundary(state);
3978
+ const boundary = new Boundary(state, void 0, parentChunk?.boundary);
3741
3979
  const context = getChunk()?.context ?? null;
3742
3980
  let head = new Chunk(boundary, new Chunk(boundary, null, context, state), context, state);
3743
3981
  let normalizedInput = input;
@@ -3745,7 +3983,8 @@ const compat = {
3745
3983
  normalizedInput = {};
3746
3984
  for (const key in input) normalizedInput[key === "renderBody" ? "content" : key] = input[key];
3747
3985
  }
3748
- head.render(() => {
3986
+ const componentScope = new Chunk(boundary, null, context, state);
3987
+ componentScope.render(() => {
3749
3988
  if (this.hasPendingClassFunctions(classAPIOut.global)) drainClassFunctions(classAPIOut.global, (hostId) => {
3750
3989
  const fnScopeId = _scope_id();
3751
3990
  const scope = writeScope(fnScopeId, {
@@ -3760,11 +3999,13 @@ const compat = {
3760
3999
  writeScope(scopeId, { m5c: component.id });
3761
4000
  _script(scopeId, SET_SCOPE_REGISTER_ID);
3762
4001
  }
3763
- _set_serialize_reason(willRerender ? CLIENT_ALL : 0);
4002
+ });
4003
+ head.render(() => {
4004
+ _set_scope_reason(willRerender ? CLIENT_ALL : 0);
3764
4005
  try {
3765
4006
  renderer(normalizedInput);
3766
4007
  } finally {
3767
- _set_serialize_reason(void 0);
4008
+ _set_scope_reason(void 0);
3768
4009
  }
3769
4010
  const asyncOut = classAPIOut.beginAsync({
3770
4011
  last: true,
@@ -3772,17 +4013,29 @@ const compat = {
3772
4013
  });
3773
4014
  classAPIOut.onLast((next) => {
3774
4015
  (boundary.onNext = () => {
3775
- if (boundary.signal.aborted) {
3776
- asyncOut.error(boundary.signal.reason);
4016
+ if (boundary.aborted) {
3777
4017
  boundary.onNext = NOOP;
4018
+ if (parentChunk?.boundary.aborted) {
4019
+ asyncOut.end();
4020
+ next();
4021
+ } else asyncOut.error(boundary.reason);
3778
4022
  } else if (!boundary.count) {
3779
4023
  boundary.onNext = NOOP;
3780
- head = head.consume();
4024
+ const queued = swapReorders(state, null);
4025
+ head = head.consume(boundary);
4026
+ const reorders = swapReorders(state, queued);
4027
+ if (reorders) asyncOut.writer.get("reorders").push(...reorders);
4028
+ const heldEffects = head.takeHeldEffects();
4029
+ if (heldEffects) {
4030
+ head.effects = joinHeldEffects(heldEffects, head.effects);
4031
+ head.lastEffect = "";
4032
+ }
3781
4033
  asyncOut.write(head.html);
3782
4034
  asyncOut.script(head.scripts);
3783
- asyncOut.end();
3784
4035
  head.html = head.scripts = "";
3785
- completeChunks.push(head);
4036
+ asyncOut.writer.get("chunks").push(head);
4037
+ asyncOut.end();
4038
+ componentScopes.push(componentScope);
3786
4039
  next();
3787
4040
  }
3788
4041
  })();
@@ -3820,9 +4073,15 @@ function drainClassFunctions($global, writeScope) {
3820
4073
  for (const [id, fn, hostId] of pending) register(id, fn, scopeByHost[hostId] ||= writeScope(hostId));
3821
4074
  pending.length = 0;
3822
4075
  }
4076
+ function swapReorders(state, reorders) {
4077
+ const { writeReorders } = state;
4078
+ state.writeReorders = reorders;
4079
+ return writeReorders;
4080
+ }
3823
4081
  function NOOP() {}
3824
4082
  //#endregion
3825
4083
  exports.$global = $global;
4084
+ exports._assert_class_toggles = _assert_class_toggles;
3826
4085
  exports._assert_hoist = _assert_hoist;
3827
4086
  exports._attr = _attr;
3828
4087
  exports._attr_and = _attr_and;
@@ -3889,9 +4148,7 @@ exports._scope_id = _scope_id;
3889
4148
  exports._scope_reason = _scope_reason;
3890
4149
  exports._scope_with_id = _scope_with_id;
3891
4150
  exports._script = _script;
3892
- exports._serialize_guard = _serialize_guard;
3893
- exports._serialize_if = _serialize_if;
3894
- exports._set_serialize_reason = _set_serialize_reason;
4151
+ exports._set_scope_reason = _set_scope_reason;
3895
4152
  exports._show_end = _show_end;
3896
4153
  exports._show_start = _show_start;
3897
4154
  exports._style_html = _style_html;
@@ -3904,6 +4161,8 @@ exports._trailers = _trailers;
3904
4161
  exports._try = _try;
3905
4162
  exports._unescaped = _unescaped;
3906
4163
  exports._var = _var;
4164
+ exports._write_guard = _write_guard;
4165
+ exports._write_if = _write_if;
3907
4166
  exports.attrTag = attrTag;
3908
4167
  exports.attrTags = attrTags;
3909
4168
  exports.compat = compat;