marko 6.3.56 → 6.4.0

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 (81) 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/accessor-prop.d.ts +3 -0
  5. package/dist/common/constants/accessor-prop.debug.d.ts +3 -0
  6. package/dist/common/types.d.ts +8 -2
  7. package/dist/debug/dom/catch.feat.js +12 -14
  8. package/dist/debug/dom/catch.feat.mjs +12 -14
  9. package/dist/debug/dom/controllable-input.feat.js +1 -1
  10. package/dist/debug/dom/controllable-input.feat.mjs +1 -1
  11. package/dist/debug/dom/controllable-open.feat.js +1 -1
  12. package/dist/debug/dom/controllable-open.feat.mjs +1 -1
  13. package/dist/debug/dom/controllable-select.feat.js +1 -1
  14. package/dist/debug/dom/controllable-select.feat.mjs +1 -1
  15. package/dist/debug/dom/controllable-textarea.feat.js +1 -1
  16. package/dist/debug/dom/controllable-textarea.feat.mjs +1 -1
  17. package/dist/debug/dom/controllable.feat.js +1 -1
  18. package/dist/debug/dom/controllable.feat.mjs +1 -1
  19. package/dist/debug/dom/dynamic-tag-script.feat.js +1 -1
  20. package/dist/debug/dom/dynamic-tag-script.feat.mjs +1 -1
  21. package/dist/debug/dom/dynamic-tag-var.feat.js +1 -1
  22. package/dist/debug/dom/dynamic-tag-var.feat.mjs +1 -1
  23. package/dist/debug/dom/lazy.feat.js +4 -0
  24. package/dist/debug/dom/lazy.feat.mjs +4 -0
  25. package/dist/debug/dom/placeholder.feat.js +1 -1
  26. package/dist/debug/dom/placeholder.feat.mjs +1 -1
  27. package/dist/debug/{dom-DcwejnYg.js → dom-BRO5aArp.js} +232 -178
  28. package/dist/debug/{dom-BeCNT5R5.mjs → dom-Btj2QJhk.mjs} +215 -167
  29. package/dist/debug/dom.js +14 -12
  30. package/dist/debug/dom.mjs +14 -12
  31. package/dist/debug/html.js +603 -517
  32. package/dist/debug/html.mjs +602 -518
  33. package/dist/dom/abort-signal.d.ts +2 -0
  34. package/dist/dom/catch.feat.js +6 -7
  35. package/dist/dom/catch.feat.mjs +5 -7
  36. package/dist/dom/control-flow.d.ts +3 -5
  37. package/dist/dom/controllable-input.feat.js +3 -2
  38. package/dist/dom/controllable-input.feat.mjs +1 -1
  39. package/dist/dom/controllable-open.feat.js +3 -2
  40. package/dist/dom/controllable-open.feat.mjs +1 -1
  41. package/dist/dom/controllable-select.feat.js +3 -2
  42. package/dist/dom/controllable-select.feat.mjs +1 -1
  43. package/dist/dom/controllable-textarea.feat.js +3 -2
  44. package/dist/dom/controllable-textarea.feat.mjs +1 -1
  45. package/dist/dom/controllable.feat.js +3 -2
  46. package/dist/dom/controllable.feat.mjs +1 -1
  47. package/dist/dom/dynamic-tag-script.feat.js +3 -2
  48. package/dist/dom/dynamic-tag-script.feat.mjs +1 -1
  49. package/dist/dom/dynamic-tag-var.feat.js +2 -1
  50. package/dist/dom/dynamic-tag-var.feat.mjs +1 -1
  51. package/dist/dom/lazy.feat.d.ts +1 -0
  52. package/dist/dom/lazy.feat.js +4 -0
  53. package/dist/dom/lazy.feat.mjs +4 -0
  54. package/dist/dom/load.d.ts +3 -3
  55. package/dist/dom/placeholder.feat.js +4 -3
  56. package/dist/dom/placeholder.feat.mjs +1 -1
  57. package/dist/dom/queue.d.ts +2 -4
  58. package/dist/dom/resume.d.ts +1 -1
  59. package/dist/dom/scope.d.ts +0 -1
  60. package/dist/{dom-BwNsIevR.mjs → dom-B-v8Gw6T.mjs} +114 -87
  61. package/dist/{dom-QEF0csuC.js → dom-BSsI9OPC.js} +210 -182
  62. package/dist/dom.js +59 -56
  63. package/dist/dom.mjs +34 -32
  64. package/dist/html/attrs.d.ts +2 -0
  65. package/dist/html/writer.d.ts +5 -11
  66. package/dist/html.d.ts +1 -1
  67. package/dist/html.js +362 -317
  68. package/dist/html.mjs +361 -317
  69. package/dist/translator/index.js +791 -650
  70. package/dist/translator/util/binding-has-prop.d.ts +2 -0
  71. package/dist/translator/util/entry-builder.d.ts +2 -0
  72. package/dist/translator/util/generate-uid.d.ts +5 -0
  73. package/dist/translator/util/references.d.ts +3 -2
  74. package/dist/translator/util/runtime.d.ts +3 -3
  75. package/dist/translator/util/sections.d.ts +8 -2
  76. package/dist/translator/util/serialize-reasons.d.ts +2 -2
  77. package/dist/translator/util/setup-work.d.ts +5 -0
  78. package/dist/translator/util/signals.d.ts +5 -7
  79. package/dist/translator/visitors/tag/native-tag.d.ts +1 -0
  80. package/package.json +3 -3
  81. package/dist/translator/util/setup-statements.d.ts +0 -5
@@ -104,19 +104,21 @@ const toDelimitedString = function toDelimitedString(val, delimiter, stringify)
104
104
  let str = "";
105
105
  let sep = "";
106
106
  let part;
107
- if (val) if (typeof val !== "object") str += val;
108
- else if (Array.isArray(val)) for (const v of val) {
109
- part = toDelimitedString(v, delimiter, stringify);
110
- if (part) {
111
- str += sep + part;
112
- sep = delimiter;
107
+ if (val) {
108
+ if (typeof val !== "object") str += val;
109
+ else if (Array.isArray(val)) for (const v of val) {
110
+ part = toDelimitedString(v, delimiter, stringify);
111
+ if (part) {
112
+ str += sep + part;
113
+ sep = delimiter;
114
+ }
113
115
  }
114
- }
115
- else for (const name in val) {
116
- part = stringify(name, val[name]);
117
- if (part) {
118
- str += sep + part;
119
- sep = delimiter;
116
+ else for (const name in val) {
117
+ part = stringify(name, val[name]);
118
+ if (part) {
119
+ str += sep + part;
120
+ sep = delimiter;
121
+ }
120
122
  }
121
123
  }
122
124
  return str;
@@ -260,43 +262,53 @@ const DYNAMIC_TAG_SCRIPT_REGISTER_ID = "_dynamicTagScript";
260
262
  const DYNAMIC_TAG_VAR_REGISTER_ID = "_dynamicTagVar";
261
263
  const PLACEHOLDER_DISMISS_REGISTER_ID = "_placeholderDismiss";
262
264
  //#endregion
263
- //#region src/html/content.ts
264
- function _to_text(val) {
265
- assertValidTextValue(val);
266
- return val || val === 0 ? val + "" : "";
265
+ //#region src/common/for.ts
266
+ function forIn(obj, cb) {
267
+ for (const key in obj) cb(key, obj[key]);
267
268
  }
268
- function _unescaped(val) {
269
- assertValidTextValue(val);
270
- return val ? val + "" : val === 0 ? "0" : "";
269
+ function forOf(list, cb) {
270
+ assertValidList(list);
271
+ if (list) {
272
+ let i = 0;
273
+ for (const item of list) cb(item, i++);
274
+ }
271
275
  }
272
- const unsafeXMLReg = /[<&\r]/g;
273
- const replaceUnsafeXML = (c) => c === "&" ? "&amp;" : c === "<" ? "&lt;" : "&#13;";
274
- const escapeXMLStr = (str) => unsafeXMLReg.test(str) ? str.replace(unsafeXMLReg, replaceUnsafeXML) : str;
275
- function _escape(val) {
276
- assertValidTextValue(val);
277
- return val ? escapeXMLStr(val + "") : val === 0 ? "0" : "";
276
+ function forTo(to, from, step, cb) {
277
+ assertValidRangeBound("to", to);
278
+ assertValidRangeStart("from", from);
279
+ assertValidRangeStart("step", step);
280
+ const start = from || 0;
281
+ const delta = step || 1;
282
+ for (let steps = (to - start) / delta, i = 0; i <= steps; i++) cb(start + i * delta);
278
283
  }
279
- const unsafeScriptReg = /<(\/?script|!--)/gi;
280
- const escapeScriptStr = (str) => unsafeScriptReg.test(str) ? str.replace(unsafeScriptReg, "\\x3C$1") : str;
281
- function _escape_script(val) {
282
- assertValidTextValue(val);
283
- return val ? escapeScriptStr(val + "") : val === 0 ? "0" : "";
284
+ function forUntil(until, from, step, cb) {
285
+ assertValidRangeBound("until", until);
286
+ assertValidRangeStart("from", from);
287
+ assertValidRangeStart("step", step);
288
+ const start = from || 0;
289
+ const delta = step || 1;
290
+ for (let steps = (until - start) / delta, i = 0; i < steps; i++) cb(start + i * delta);
284
291
  }
285
- const unsafeStyleReg = /<(\/style)/gi;
286
- const escapeStyleStr = (str) => unsafeStyleReg.test(str) ? str.replace(unsafeStyleReg, "\\3C$1") : str;
287
- function _escape_style(val) {
288
- assertValidTextValue(val);
289
- return val ? escapeStyleStr(val + "") : val === 0 ? "0" : "";
292
+ //#endregion
293
+ //#region src/common/opt.ts
294
+ function forEach(opt, cb) {
295
+ if (opt) {
296
+ if (Array.isArray(opt)) for (const item of opt) cb(item);
297
+ else cb(opt);
298
+ }
290
299
  }
291
- function _escape_style_value(val) {
292
- assertValidTextValue(val);
293
- return val || val === 0 ? escapeStyleValue(val + "") : "";
300
+ function push(opt, item) {
301
+ return opt ? Array.isArray(opt) ? (opt.push(item), opt) : [opt, item] : item;
294
302
  }
295
- const unsafeCommentReg = />/g;
296
- const escapeCommentStr = (str) => unsafeCommentReg.test(str) ? str.replace(unsafeCommentReg, "&gt;") : str;
297
- function _escape_comment(val) {
298
- assertValidTextValue(val);
299
- return val ? escapeCommentStr(val + "") : val === 0 ? "0" : "";
303
+ function concat(opt, other) {
304
+ if (!opt) return other;
305
+ if (!other) return opt;
306
+ if (Array.isArray(opt)) {
307
+ if (Array.isArray(other)) for (const item of other) opt.push(item);
308
+ else opt.push(other);
309
+ return opt;
310
+ }
311
+ return Array.isArray(other) ? [opt, ...other] : [opt, other];
300
312
  }
301
313
  //#endregion
302
314
  //#region src/html/serializer.ts
@@ -387,7 +399,6 @@ const KNOWN_FUNCTIONS = /* @__PURE__ */ (() => /* @__PURE__ */ new Map([
387
399
  [Function, "Function"],
388
400
  [globalThis.atob, "atob"],
389
401
  [globalThis.btoa, "btoa"],
390
- [globalThis.clearImmediate, "clearImmediate"],
391
402
  [globalThis.clearInterval, "clearInterval"],
392
403
  [globalThis.clearTimeout, "clearTimeout"],
393
404
  [globalThis.crypto?.getRandomValues, "crypto.getRandomValues"],
@@ -395,7 +406,6 @@ const KNOWN_FUNCTIONS = /* @__PURE__ */ (() => /* @__PURE__ */ new Map([
395
406
  [globalThis.fetch, "fetch"],
396
407
  [globalThis.performance?.now, "performance.now"],
397
408
  [globalThis.queueMicrotask, "queueMicrotask"],
398
- [globalThis.setImmediate, "setImmediate"],
399
409
  [globalThis.setInterval, "setInterval"],
400
410
  [globalThis.setTimeout, "setTimeout"],
401
411
  [globalThis.structuredClone, "structuredClone"],
@@ -611,6 +621,9 @@ var Serializer = class {
611
621
  this.#state.boundary = boundary;
612
622
  this.#state.channel = channel;
613
623
  return writeScopesRoot(this.#state, flushes);
624
+ } catch (err) {
625
+ abortRender(boundary, err);
626
+ return "";
614
627
  } finally {
615
628
  this.#state.flushId++;
616
629
  this.#state.buf = [];
@@ -927,7 +940,8 @@ function writeUnknownObject(state, val, ref) {
927
940
  const proto = Object.getPrototypeOf(val);
928
941
  if (proto === objectProto) return writePlainObject(state, val, ref);
929
942
  if (proto === arrayProto) return writeArray(state, val, ref);
930
- switch (proto?.constructor) {
943
+ const constructor = proto?.constructor;
944
+ switch (constructor) {
931
945
  case void 0: return writeNullObject(state, val, ref);
932
946
  case Object: return writePlainObject(state, val, ref);
933
947
  case Array: return writeArray(state, val, ref);
@@ -944,7 +958,7 @@ function writeUnknownObject(state, val, ref) {
944
958
  case ReferenceError:
945
959
  case SyntaxError:
946
960
  case TypeError:
947
- case URIError: return writeError(state, val, ref);
961
+ case URIError: return writeError(state, val, constructor.name, ref);
948
962
  case AggregateError: return writeAggregateError(state, val, ref);
949
963
  case ArrayBuffer: return writeArrayBuffer(state, val);
950
964
  case Int8Array:
@@ -957,7 +971,7 @@ function writeUnknownObject(state, val, ref) {
957
971
  case Float32Array:
958
972
  case Float64Array:
959
973
  case BigInt64Array:
960
- case BigUint64Array: return writeTypedArray(state, val, ref);
974
+ case BigUint64Array: return writeTypedArray(state, val, constructor.name, ref);
961
975
  case DataView: return writeDataView(state, val, ref);
962
976
  case WeakSet: return writeWeakSet(state);
963
977
  case WeakMap: return writeWeakMap(state);
@@ -1178,16 +1192,16 @@ function writeArrayBuffer(state, val) {
1178
1192
  state.buf.push(result);
1179
1193
  return true;
1180
1194
  }
1181
- function writeTypedArray(state, val, ref) {
1195
+ function writeTypedArray(state, val, name, ref) {
1182
1196
  if (val.byteOffset || val.byteLength < val.buffer.byteLength || state.refs.has(val.buffer)) {
1183
1197
  if (!canWriteBuffer(state, val.buffer, ref)) return false;
1184
1198
  const needsLength = val.byteOffset + val.byteLength < val.buffer.byteLength;
1185
- state.buf.push("new " + val.constructor.name + "(");
1199
+ state.buf.push("new " + name + "(");
1186
1200
  writeProp(state, val.buffer, ref, "buffer");
1187
1201
  state.buf.push((val.byteOffset || needsLength ? "," + val.byteOffset + (needsLength ? "," + val.length : "") : "") + ")");
1188
1202
  } else {
1189
1203
  state.refs.set(val.buffer, new Reference(ref, "buffer", state.flushId, null));
1190
- state.buf.push("new " + val.constructor.name + (val.length === 0 ? "" : "(" + (hasOnlyZeros(val) ? val.length : typedArrayToInitString(val)) + ")"));
1204
+ state.buf.push("new " + name + (val.length === 0 ? "" : "(" + (hasOnlyZeros(val) ? val.length : typedArrayToInitString(val)) + ")"));
1191
1205
  }
1192
1206
  return true;
1193
1207
  }
@@ -1199,8 +1213,8 @@ function writeWeakMap(state) {
1199
1213
  state.buf.push("new WeakMap");
1200
1214
  return true;
1201
1215
  }
1202
- function writeError(state, val, ref) {
1203
- const result = "new " + val.constructor.name + "(" + quote(val.message + "", 0);
1216
+ function writeError(state, val, name, ref) {
1217
+ const result = "new " + name + "(" + quote(val.message + "", 0);
1204
1218
  if (val.cause !== void 0) {
1205
1219
  const pos = state.buf.push(result + ",{cause:") - 1;
1206
1220
  if (writeProp(state, val.cause, ref, "cause")) state.buf.push("})");
@@ -1369,7 +1383,10 @@ function writeTemporal(state, val, name) {
1369
1383
  return true;
1370
1384
  }
1371
1385
  function writeReadableStream(state, val, ref) {
1372
- if (val.locked) return false;
1386
+ if (val.locked) {
1387
+ throwUnserializable(state, val, ref, "", "The ReadableStream is locked by a reader on the server; to also send it to the browser, `tee()` it (or `clone()` its `Request`/`Response`) before reading.");
1388
+ return false;
1389
+ }
1373
1390
  const { boundary, channel } = state;
1374
1391
  const reader = val.getReader();
1375
1392
  const iterId = nextRefAccess(state);
@@ -1502,7 +1519,7 @@ function writeAsyncCall(state, boundary, handle, method, value, channel, valueId
1502
1519
  });
1503
1520
  boundary.endAsync();
1504
1521
  }
1505
- function throwUnserializable(state, cause, ref = null, accessor = "") {
1522
+ function throwUnserializable(state, cause, ref = null, accessor = "", hint = "Values referenced in the browser must be serializable.") {
1506
1523
  if (cause !== void 0) {
1507
1524
  let message = "Unable to serialize";
1508
1525
  let access = "";
@@ -1515,10 +1532,12 @@ function throwUnserializable(state, cause, ref = null, accessor = "") {
1515
1532
  const slotName = debug.slots?.[rawAccessor];
1516
1533
  let debugAccess = varLoc ? rawAccessor : void 0;
1517
1534
  let debugLoc = debug.loc;
1518
- if (varLoc) if (Array.isArray(varLoc)) {
1519
- debugAccess = varLoc[0];
1520
- if (varLoc[1]) debugLoc = varLoc[1];
1521
- } else debugLoc = varLoc;
1535
+ if (varLoc) {
1536
+ if (Array.isArray(varLoc)) {
1537
+ debugAccess = varLoc[0];
1538
+ if (varLoc[1]) debugLoc = varLoc[1];
1539
+ } else debugLoc = varLoc;
1540
+ }
1522
1541
  let display;
1523
1542
  if (debugAccess !== void 0) display = slotName && debugAccess.startsWith("...") ? `\`${slotName}\` from \`${debugAccess}\`` : JSON.stringify(debugAccess);
1524
1543
  else display = describeAccessor(rawAccessor, slotName) ?? JSON.stringify(rawAccessor);
@@ -1532,10 +1551,10 @@ function throwUnserializable(state, cause, ref = null, accessor = "") {
1532
1551
  if (accessor) access = toAccess(accessor) + access;
1533
1552
  if (access[0] === ".") access = access.slice(1);
1534
1553
  if (access) message += ` (reading ${access})`;
1535
- message += ". Values referenced in the browser must be serializable.";
1554
+ message += ". " + hint;
1536
1555
  const err = new TypeError(message, { cause });
1537
1556
  err.stack = void 0;
1538
- state.boundary.abort(err);
1557
+ abortRender(state.boundary, err);
1539
1558
  }
1540
1559
  }
1541
1560
  const accessorPrefixDescriptions = {
@@ -1553,7 +1572,8 @@ const accessorPrefixDescriptions = {
1553
1572
  KeyedScopes: "the keyed scopes",
1554
1573
  Lifecycle: "the lifecycle handlers",
1555
1574
  Promise: "the pending promise",
1556
- TagVariableChange: "the tag variable change handler"
1575
+ TagVariableChange: "the tag variable change handler",
1576
+ TryBranch: "the try branch"
1557
1577
  };
1558
1578
  function describeAccessor(accessor, slotName) {
1559
1579
  const sep = accessor.indexOf(":");
@@ -1588,7 +1608,11 @@ function trackChannel(state, ref) {
1588
1608
  function abortUnreachableChannel(state, val) {
1589
1609
  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 });
1590
1610
  err.stack = void 0;
1591
- state.boundary.abort(err);
1611
+ abortRender(state.boundary, err);
1612
+ }
1613
+ function abortRender(boundary, err) {
1614
+ while (boundary.parent) boundary = boundary.parent;
1615
+ boundary.abort(err);
1592
1616
  }
1593
1617
  function isCircular(parent, ref) {
1594
1618
  let cur = parent;
@@ -1603,16 +1627,17 @@ function toObjectKey(name) {
1603
1627
  if (name === "__proto__") return "[\"__proto__\"]";
1604
1628
  const len = name.length;
1605
1629
  const c0 = name.charCodeAt(0);
1606
- if (c0 >= 48 && c0 <= 57) if (c0 === 48) {
1607
- if (len !== 1) return quote(name, 1);
1608
- } else {
1609
- for (let i = 1; i < len; i++) {
1610
- const c = name.charCodeAt(i);
1611
- if (c < 48 || c > 57) return quote(name, i);
1630
+ if (c0 >= 48 && c0 <= 57) {
1631
+ if (c0 === 48) {
1632
+ if (len !== 1) return quote(name, 1);
1633
+ } else {
1634
+ for (let i = 1; i < len; i++) {
1635
+ const c = name.charCodeAt(i);
1636
+ if (c < 48 || c > 57) return quote(name, i);
1637
+ }
1638
+ if (len > 15 && "" + +name !== name) return quote(name, 0);
1612
1639
  }
1613
- if (len > 15 && "" + +name !== name) return quote(name, 0);
1614
- }
1615
- else if (c0 >= 97 && c0 <= 122 || c0 >= 65 && c0 <= 90 || c0 === 95 || c0 === 36) for (let i = 1; i < len; i++) {
1640
+ } else if (c0 >= 97 && c0 <= 122 || c0 >= 65 && c0 <= 90 || c0 === 95 || c0 === 36) for (let i = 1; i < len; i++) {
1616
1641
  const c = name.charCodeAt(i);
1617
1642
  if (!(c >= 97 && c <= 122 || c >= 65 && c <= 90 || c >= 48 && c <= 57 || c === 95 || c === 36)) return quote(name, i);
1618
1643
  }
@@ -1737,7 +1762,7 @@ function nextId(state) {
1737
1762
  let n = state.ids++;
1738
1763
  let r = c[n % 53];
1739
1764
  for (n = n / 53 | 0; n; n >>>= 6) r += c[n & 63];
1740
- return r;
1765
+ return r === "name" ? nextId(state) : r;
1741
1766
  }
1742
1767
  function hasSymbolIterator(value) {
1743
1768
  return Symbol.iterator in value;
@@ -1788,130 +1813,316 @@ function patchIteratorNext(proto) {
1788
1813
  proto.next[kTouchedIterator] = true;
1789
1814
  }
1790
1815
  //#endregion
1791
- //#region src/common/for.ts
1792
- function forIn(obj, cb) {
1793
- for (const key in obj) cb(key, obj[key]);
1816
+ //#region src/html/attrs.ts
1817
+ function _attr_class(value) {
1818
+ return stringAttr("class", toDelimitedString(value, " ", stringifyClassObject));
1794
1819
  }
1795
- function forOf(list, cb) {
1796
- assertValidList(list);
1797
- if (list) {
1798
- let i = 0;
1799
- for (const item of list) cb(item, i++);
1820
+ function _attr_style(value) {
1821
+ return stringAttr("style", toDelimitedString(value, ";", stringifyStyleObject));
1822
+ }
1823
+ function _attr_option_value(value) {
1824
+ const valueAttr = _attr("value", value);
1825
+ const selectedValue = getContext(kSelectedValue);
1826
+ if (selectedValue !== void 0 && normalizedValueMatches(selectedValue, value)) {
1827
+ {
1828
+ const matched = getContext(kSelectedValueMatched);
1829
+ if (matched) matched.value = true;
1830
+ }
1831
+ return valueAttr + " selected";
1800
1832
  }
1833
+ return valueAttr;
1801
1834
  }
1802
- function forTo(to, from, step, cb) {
1803
- assertValidRangeBound("to", to);
1804
- assertValidRangeStart("from", from);
1805
- assertValidRangeStart("step", step);
1806
- const start = from || 0;
1807
- const delta = step || 1;
1808
- for (let steps = (to - start) / delta, i = 0; i <= steps; i++) cb(start + i * delta);
1835
+ const kSelectedValue = Symbol("selectedValue");
1836
+ const kSelectedValueMatched = Symbol("selectedValueMatched");
1837
+ function _attr_select_value(scopeId, nodeAccessor, value, valueChange, content, serializeType) {
1838
+ if (valueChange) writeControlledScope(3, scopeId, nodeAccessor, void 0, valueChange, serializeType);
1839
+ if (content) {
1840
+ const selectedValue = value ?? "";
1841
+ if (valueChange) {
1842
+ const matched = { value: false };
1843
+ withContext(kSelectedValue, selectedValue, () => withContext(kSelectedValueMatched, matched, content));
1844
+ if (!matched.value && (Array.isArray(value) ? value.some((v) => normalizeStrAttrValue(v) !== "") : normalizeStrAttrValue(value) !== "")) console.error("A controlled `<select>`'s `value` has no matching `<option>`:", value);
1845
+ } else withContext(kSelectedValue, selectedValue, content);
1846
+ }
1809
1847
  }
1810
- function forUntil(until, from, step, cb) {
1811
- assertValidRangeBound("until", until);
1812
- assertValidRangeStart("from", from);
1813
- assertValidRangeStart("step", step);
1814
- const start = from || 0;
1815
- const delta = step || 1;
1816
- for (let steps = (until - start) / delta, i = 0; i < steps; i++) cb(start + i * delta);
1848
+ function _attrs_select_value(scopeId, nodeAccessor, data, content) {
1849
+ if (data && ("value" in data || data.valueChange)) _attr_select_value(scopeId, nodeAccessor, data.value, data.valueChange, content, 1);
1850
+ else content();
1817
1851
  }
1818
- //#endregion
1819
- //#region src/common/opt.ts
1820
- function forEach(opt, cb) {
1821
- if (opt) if (Array.isArray(opt)) for (const item of opt) cb(item);
1822
- else cb(opt);
1852
+ function _attr_textarea_value(scopeId, nodeAccessor, value, valueChange, serializeType) {
1853
+ if (valueChange) writeControlledScope(2, scopeId, nodeAccessor, void 0, valueChange, serializeType);
1854
+ return _textarea_value(value);
1823
1855
  }
1824
- function push(opt, item) {
1825
- return opt ? Array.isArray(opt) ? (opt.push(item), opt) : [opt, item] : item;
1856
+ function _attrs_textarea_value(scopeId, nodeAccessor, data) {
1857
+ return _attr_textarea_value(scopeId, nodeAccessor, data?.value, data?.valueChange, 1);
1826
1858
  }
1827
- function concat(opt, other) {
1828
- if (!opt) return other;
1829
- if (!other) return opt;
1830
- if (Array.isArray(opt)) {
1831
- if (Array.isArray(other)) for (const item of other) opt.push(item);
1832
- else opt.push(other);
1833
- return opt;
1859
+ function _textarea_value(value) {
1860
+ const escaped = _escape(normalizeStrAttrValue(value));
1861
+ return escaped[0] === "\n" ? "\n" + escaped : escaped;
1862
+ }
1863
+ function _attr_input_value(scopeId, nodeAccessor, value, valueChange, serializeType) {
1864
+ if (valueChange) writeControlledScope(2, scopeId, nodeAccessor, void 0, valueChange, serializeType);
1865
+ return _attr("value", value);
1866
+ }
1867
+ function _attr_input_checked(scopeId, nodeAccessor, checked, checkedChange, serializeType) {
1868
+ if (checkedChange) writeControlledScope(0, scopeId, nodeAccessor, void 0, checkedChange, serializeType);
1869
+ return isNotVoid(checked) ? " checked" : "";
1870
+ }
1871
+ function _attr_input_checkedValue(scopeId, nodeAccessor, checkedValue, checkedValueChange, value, serializeType) {
1872
+ const valueAttr = _attr("value", value);
1873
+ if (checkedValueChange) writeControlledScope(1, scopeId, nodeAccessor, getCheckedValueRef(checkedValue), checkedValueChange, serializeType);
1874
+ return normalizedValueMatches(checkedValue, value) ? valueAttr + " checked" : valueAttr;
1875
+ }
1876
+ const checkedValuesRefs = /* @__PURE__ */ new WeakMap();
1877
+ function getCheckedValueRef(checkedValue) {
1878
+ if (Array.isArray(checkedValue)) {
1879
+ let ref = checkedValuesRefs.get(checkedValue);
1880
+ if (!ref) {
1881
+ ref = [];
1882
+ checkedValuesRefs.set(checkedValue, ref);
1883
+ }
1884
+ return ref;
1834
1885
  }
1835
- return Array.isArray(other) ? [opt, ...other] : [opt, other];
1836
1886
  }
1837
- //#endregion
1838
- //#region src/html/for.ts
1839
- function forOfBy(by, item, index) {
1840
- return by ? typeof by === "string" ? item[by] : by(item, index) : index;
1887
+ function _attr_details_or_dialog_open(scopeId, nodeAccessor, open, openChange, serializeType) {
1888
+ const normalizedOpen = isNotVoid(open);
1889
+ if (openChange) writeControlledScope(4, scopeId, nodeAccessor, normalizedOpen || void 0, openChange, serializeType);
1890
+ return normalizedOpen ? " open" : "";
1841
1891
  }
1842
- function forInBy(by, name, value) {
1843
- return by ? by(name, value) : name;
1892
+ function _attr_nonce() {
1893
+ return getChunk().boundary.state.nonceAttr;
1844
1894
  }
1845
- function forStepBy(by, index) {
1846
- return by ? by(index) : index;
1895
+ function _style_html(decls) {
1896
+ const id = _id();
1897
+ return `<style${_attr_nonce()} class=${id}>.${id}~*{${decls}}</style>`;
1847
1898
  }
1848
- //#endregion
1849
- //#region src/html/inlined-runtimes.debug.ts
1850
- const WALKER_RUNTIME_CODE = `((runtimeId) => (self[runtimeId] ||= (
1851
- renderId,
1852
- prefix = runtimeId + renderId,
1853
- prefixLen = prefix.length,
1854
- lookup = {},
1855
- visits = [],
1856
- doc = document,
1857
- walker = doc.createTreeWalker(
1858
- doc,
1859
- 129 /* NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_ELEMENT */,
1860
- ),
1861
- ) =>
1862
- doc = (self[runtimeId][renderId] = {
1863
- i: prefix,
1864
- d: doc,
1865
- l: lookup,
1866
- v: visits,
1867
- x() {},
1868
- w(node, op, id) {
1869
- while ((node = walker.nextNode())) {
1870
- // Only reorder markers ("#", "!") are ever looked up, so only they are
1871
- // kept: the lookup lives as long as the page, and every node marker
1872
- // would otherwise stay referenced in it after resume consumed it.
1873
- doc.x(
1874
- (op =
1875
- (op = node.data) &&
1876
- !op.indexOf(prefix) &&
1877
- ((id = op.slice(prefixLen + 1)),
1878
- (op = op[prefixLen]) > "#" || (lookup[id] = node),
1879
- op)),
1880
- id,
1881
- node,
1882
- );
1883
-
1884
- if (op > "#") {
1885
- visits.push(node);
1886
- }
1887
- }
1888
- },
1889
- })
1890
- , self[runtimeId]))`;
1891
- const REORDER_RUNTIME_CODE = `((runtime) => {
1892
- if (runtime.j) return;
1893
- let onNextSibling,
1894
- placeholder,
1895
- nextSibling,
1896
- placeholders = runtime.p = {},
1897
- replace = (id, container) => runtime.l[id].replaceWith(...container.childNodes);
1898
- runtime.j = {};
1899
- runtime.x = (op, id, node, placeholderRoot, placeholderCb) => {
1900
- if (node == nextSibling) {
1901
- onNextSibling();
1902
- }
1903
-
1904
- if (op == "#") {
1905
- (placeholders[id] = placeholder).i++;
1906
- } else if (op == "!") {
1907
- if (runtime.l[id] && placeholders[id]) {
1908
- nextSibling = node.nextSibling;
1909
- onNextSibling = () => placeholders[id].c();
1910
- }
1911
- } else if (node.tagName == "T" && (id = node.getAttribute(runtime.i))) {
1912
- nextSibling = node.nextSibling;
1913
- onNextSibling = () => {
1914
- node.remove();
1899
+ function _attr(name, value) {
1900
+ return isVoid(value) ? "" : nonVoidAttr(name, value);
1901
+ }
1902
+ function _attr_and(name, value, attr) {
1903
+ return value ? attr : _attr(name, value);
1904
+ }
1905
+ function _attr_or(name, value, attr) {
1906
+ return value ? _attr(name, value) : attr;
1907
+ }
1908
+ function _attr_nullish(name, value, attr) {
1909
+ return value == null ? attr : _attr(name, value);
1910
+ }
1911
+ function _attrs(data, nodeAccessor, scopeId, tagName) {
1912
+ let result = "";
1913
+ let skip = /[\s/>"'=]/;
1914
+ let events;
1915
+ switch (data && tagName) {
1916
+ case "input":
1917
+ assertExclusiveAttrs(data);
1918
+ if (data.checkedChange) {
1919
+ result += _attr_input_checked(scopeId, nodeAccessor, data.checked, data.checkedChange, 1);
1920
+ skip = /^checked(?:Value)?(?:Change)?$|[\s/>"'=]/;
1921
+ } else if ("checkedValue" in data || data.checkedValueChange) {
1922
+ result += _attr_input_checkedValue(scopeId, nodeAccessor, data.checkedValue, data.checkedValueChange, data.value, 1);
1923
+ skip = /^(?:value|checked(?:Value)?)(?:Change)?$|[\s/>"'=]/;
1924
+ } else if (data.valueChange) {
1925
+ assertNoValueBindingOnCheckable(data.type, data.valueChange);
1926
+ result += _attr_input_value(scopeId, nodeAccessor, data.value, data.valueChange, 1);
1927
+ skip = /^value(?:Change)?$|[\s/>"'=]/;
1928
+ }
1929
+ break;
1930
+ case "select":
1931
+ case "textarea":
1932
+ if ("value" in data || data.valueChange) skip = /^value(?:Change)?$|[\s/>"'=]/;
1933
+ break;
1934
+ case "option":
1935
+ if ("value" in data) {
1936
+ result += _attr_option_value(data.value);
1937
+ skip = /^value$|[\s/>"'=]/;
1938
+ }
1939
+ break;
1940
+ case "details":
1941
+ case "dialog": if (data.openChange) {
1942
+ result += _attr_details_or_dialog_open(scopeId, nodeAccessor, data.open, data.openChange, 1);
1943
+ skip = /^open(?:Change)?$|[\s/>"'=]/;
1944
+ }
1945
+ }
1946
+ for (const name in data) {
1947
+ const value = data[name];
1948
+ switch (name) {
1949
+ case "class":
1950
+ result += _attr_class(value);
1951
+ break;
1952
+ case "style":
1953
+ result += _attr_style(value);
1954
+ break;
1955
+ default:
1956
+ if (name) assertValidAttrName(name);
1957
+ if (name && !(isVoid(value) || skip.test(name) || name === "content" && tagName !== "meta")) {
1958
+ if (isEventHandler(name)) {
1959
+ if (!events) {
1960
+ events = {};
1961
+ writeScope(scopeId, { [EventAttributes + nodeAccessor]: events });
1962
+ }
1963
+ events[getEventHandlerName(name)] = value;
1964
+ } else result += nonVoidAttr(name, value);
1965
+ }
1966
+ }
1967
+ }
1968
+ return result;
1969
+ }
1970
+ function _attrs_content(data, nodeAccessor, scopeId, tagName, serializeReason) {
1971
+ _html(`${_attrs(data, nodeAccessor, scopeId, tagName)}>`);
1972
+ _attr_content(nodeAccessor, scopeId, data?.content, serializeReason);
1973
+ }
1974
+ function _attrs_partial(data, skip, nodeAccessor, scopeId, tagName) {
1975
+ const partial = {};
1976
+ for (const name in data) {
1977
+ const key = isEventHandler(name) ? `on-${getEventHandlerName(name)}` : name;
1978
+ if (!skip[key]) partial[key] = data[name];
1979
+ }
1980
+ assertExclusiveAttrs({
1981
+ ...data,
1982
+ ...skip
1983
+ });
1984
+ return _attrs(partial, nodeAccessor, scopeId, tagName);
1985
+ }
1986
+ function _attrs_partial_content(data, skip, nodeAccessor, scopeId, tagName, serializeReason) {
1987
+ _html(`${_attrs_partial(data, skip, nodeAccessor, scopeId, tagName)}>`);
1988
+ _attr_content(nodeAccessor, scopeId, data?.content, serializeReason);
1989
+ }
1990
+ function writeControlledScope(type, scopeId, nodeAccessor, value, valueChange, serializeType) {
1991
+ var handlerName = [
1992
+ "checkedChange",
1993
+ "checkedValueChange",
1994
+ "valueChange",
1995
+ "valueChange",
1996
+ "openChange"
1997
+ ][type];
1998
+ assertHandlerIsFunction(handlerName, valueChange);
1999
+ setDebugSlotName(writeScope(scopeId, serializeType ? {
2000
+ [ControlledType + nodeAccessor]: type,
2001
+ [ControlledValue + nodeAccessor]: value,
2002
+ [ControlledHandler + nodeAccessor]: valueChange
2003
+ } : {
2004
+ [ControlledValue + nodeAccessor]: value,
2005
+ [ControlledHandler + nodeAccessor]: valueChange
2006
+ }), ControlledHandler + nodeAccessor, handlerName);
2007
+ }
2008
+ function stringAttr(name, value) {
2009
+ return value && " " + name + attrAssignment(value);
2010
+ }
2011
+ function nonVoidAttr(name, value) {
2012
+ assertValidAttrValue(name, value);
2013
+ switch (typeof value) {
2014
+ case "string": return " " + name + attrAssignment(value);
2015
+ case "boolean": return " " + name;
2016
+ case "number": return " " + name + "=" + value;
2017
+ }
2018
+ return " " + name + attrAssignment(value + "");
2019
+ }
2020
+ const singleQuoteAttrReplacements = /['\r]|&(?=[#a-zA-Z])/g;
2021
+ const doubleQuoteAttrReplacements = /["\r]|&(?=[#a-zA-Z])/g;
2022
+ const needsQuotedAttr = /["'>\s]|&[#a-zA-Z]|\/$/g;
2023
+ function attrAssignment(value) {
2024
+ return value ? needsQuotedAttr.test(value) ? value[needsQuotedAttr.lastIndex - 1] === (needsQuotedAttr.lastIndex = 0, "\"") ? "='" + escapeSingleQuotedAttrValue(value) + "'" : "=\"" + escapeDoubleQuotedAttrValue(value) + "\"" : "=" + value : "";
2025
+ }
2026
+ function escapeSingleQuotedAttrValue(value) {
2027
+ return singleQuoteAttrReplacements.test(value) ? value.replace(singleQuoteAttrReplacements, replaceUnsafeSingleQuoteAttrChar) : value;
2028
+ }
2029
+ function replaceUnsafeSingleQuoteAttrChar(match) {
2030
+ return match === "'" ? "&#39;" : match === "\r" ? "&#13;" : "&amp;";
2031
+ }
2032
+ function escapeDoubleQuotedAttrValue(value) {
2033
+ return doubleQuoteAttrReplacements.test(value) ? value.replace(doubleQuoteAttrReplacements, replaceUnsafeDoubleQuoteAttrChar) : value;
2034
+ }
2035
+ function replaceUnsafeDoubleQuoteAttrChar(match) {
2036
+ return match === "\"" ? "&#34;" : match === "\r" ? "&#13;" : "&amp;";
2037
+ }
2038
+ function normalizedValueMatches(a, b) {
2039
+ const value = normalizeStrAttrValue(b);
2040
+ if (Array.isArray(a)) {
2041
+ for (const item of a) if (normalizeStrAttrValue(item) === value) return true;
2042
+ } else if (normalizeStrAttrValue(a) === value) return true;
2043
+ return false;
2044
+ }
2045
+ function normalizeStrAttrValue(value) {
2046
+ return isNotVoid(value) && value !== true ? value + "" : "";
2047
+ }
2048
+ //#endregion
2049
+ //#region src/html/for.ts
2050
+ function forOfBy(by, item, index) {
2051
+ return by ? typeof by === "string" ? item[by] : by(item, index) : index;
2052
+ }
2053
+ function forInBy(by, name, value) {
2054
+ return by ? by(name, value) : name;
2055
+ }
2056
+ function forStepBy(by, index) {
2057
+ return by ? by(index) : index;
2058
+ }
2059
+ //#endregion
2060
+ //#region src/html/inlined-runtimes.debug.ts
2061
+ const WALKER_RUNTIME_CODE = `((runtimeId) => (self[runtimeId] ||= (
2062
+ renderId,
2063
+ prefix = runtimeId + renderId,
2064
+ prefixLen = prefix.length,
2065
+ lookup = {},
2066
+ visits = [],
2067
+ doc = document,
2068
+ walker = doc.createTreeWalker(
2069
+ doc,
2070
+ 129 /* NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_ELEMENT */,
2071
+ ),
2072
+ ) =>
2073
+ doc = (self[runtimeId][renderId] = {
2074
+ i: prefix,
2075
+ d: doc,
2076
+ l: lookup,
2077
+ v: visits,
2078
+ x() {},
2079
+ w(node, op, id) {
2080
+ while ((node = walker.nextNode())) {
2081
+ // Only reorder markers ("#", "!") are ever looked up, so only they are
2082
+ // kept: the lookup lives as long as the page, and every node marker
2083
+ // would otherwise stay referenced in it after resume consumed it.
2084
+ doc.x(
2085
+ (op =
2086
+ (op = node.data) &&
2087
+ !op.indexOf(prefix) &&
2088
+ ((id = op.slice(prefixLen + 1)),
2089
+ (op = op[prefixLen]) > "#" || (lookup[id] = node),
2090
+ op)),
2091
+ id,
2092
+ node,
2093
+ );
2094
+
2095
+ if (op > "#") {
2096
+ visits.push(node);
2097
+ }
2098
+ }
2099
+ },
2100
+ })
2101
+ , self[runtimeId]))`;
2102
+ const REORDER_RUNTIME_CODE = `((runtime) => {
2103
+ if (runtime.j) return;
2104
+ let onNextSibling,
2105
+ placeholder,
2106
+ nextSibling,
2107
+ placeholders = runtime.p = {},
2108
+ replace = (id, container) => runtime.l[id].replaceWith(...container.childNodes);
2109
+ runtime.j = {};
2110
+ runtime.x = (op, id, node, placeholderRoot, placeholderCb) => {
2111
+ if (node == nextSibling) {
2112
+ onNextSibling();
2113
+ }
2114
+
2115
+ if (op == "#") {
2116
+ (placeholders[id] = placeholder).i++;
2117
+ } else if (op == "!") {
2118
+ if (runtime.l[id] && placeholders[id]) {
2119
+ nextSibling = node.nextSibling;
2120
+ onNextSibling = () => placeholders[id].c();
2121
+ }
2122
+ } else if (node.tagName == "T" && (id = node.getAttribute(runtime.i))) {
2123
+ nextSibling = node.nextSibling;
2124
+ onNextSibling = () => {
2125
+ node.remove();
1915
2126
  placeholderRoot || replace(id, node);
1916
2127
  placeholder.c();
1917
2128
  };
@@ -2004,6 +2215,12 @@ function withContext(key, value, cb, cbValue) {
2004
2215
  ctx[key] = prev;
2005
2216
  }
2006
2217
  }
2218
+ function captureContext(chunk) {
2219
+ if (chunk.context?.[kPendingContexts]) chunk.context = {
2220
+ ...chunk.context,
2221
+ [kPendingContexts]: 0
2222
+ };
2223
+ }
2007
2224
  const kBranchId = Symbol("Branch Id");
2008
2225
  const kIsAsync = Symbol("Is Async");
2009
2226
  function isInResumedBranch() {
@@ -2012,8 +2229,8 @@ function isInResumedBranch() {
2012
2229
  function withBranchId(branchId, cb, cbValue) {
2013
2230
  return withContext(kBranchId, branchId, cb, cbValue);
2014
2231
  }
2015
- function withIsAsync(cb, value) {
2016
- return withContext(kIsAsync, true, cb, value);
2232
+ function withIsAsync(async, cb, value) {
2233
+ return withContext(kIsAsync, async, cb, value);
2017
2234
  }
2018
2235
  function _html(html) {
2019
2236
  $chunk.writeHTML(html);
@@ -2074,8 +2291,10 @@ function _attr_content(nodeAccessor, scopeId, content, serializeReason) {
2074
2291
  const shouldResume = serializeReason !== 0;
2075
2292
  const render = normalizeServerRender(content);
2076
2293
  const branchId = _peek_scope_id();
2077
- if (render) if (shouldResume) withBranchId(branchId, render);
2078
- else render();
2294
+ if (render) {
2295
+ if (shouldResume) withBranchId(branchId, render);
2296
+ else render();
2297
+ }
2079
2298
  if (_peek_scope_id() !== branchId) {
2080
2299
  if (shouldResume) writeScope(scopeId, {
2081
2300
  [BranchScopes + nodeAccessor]: writeScope(branchId, {}),
@@ -2085,8 +2304,10 @@ function _attr_content(nodeAccessor, scopeId, content, serializeReason) {
2085
2304
  }
2086
2305
  function normalizeServerRender(value) {
2087
2306
  const renderer = normalizeDynamicRenderer(value);
2088
- if (renderer) if (typeof renderer === "function") return renderer;
2089
- else throw new Error(`Invalid \`content\` attribute. Received ${typeof value}`);
2307
+ if (renderer) {
2308
+ if (typeof renderer === "function") return renderer;
2309
+ else throw new Error(`Invalid \`content\` attribute. Received ${typeof value}`);
2310
+ }
2090
2311
  }
2091
2312
  function _var(parentScopeId, scopeOffsetAccessor, childScopeId, registryId, nodeAccessor) {
2092
2313
  writeScopePassive(parentScopeId, { [scopeOffsetAccessor]: _scope_id() });
@@ -2163,10 +2384,12 @@ function forBranches(by, iterate, scopeId, accessor, serializeBranch, serializeM
2163
2384
  let loopScopes;
2164
2385
  iterate((itemKey, sameAsIndex, render) => {
2165
2386
  const branchId = _peek_scope_id();
2166
- if (resumeMarker) if (singleNode) flushBranchIds = " " + branchId + flushBranchIds;
2167
- else {
2168
- $chunk.writeHTML(state.mark("[", flushBranchIds));
2169
- flushBranchIds = branchId + "";
2387
+ if (resumeMarker) {
2388
+ if (singleNode) flushBranchIds = " " + branchId + flushBranchIds;
2389
+ else {
2390
+ $chunk.writeHTML(state.mark("[", flushBranchIds));
2391
+ flushBranchIds = branchId + "";
2392
+ }
2170
2393
  }
2171
2394
  withBranchId(branchId, () => {
2172
2395
  render();
@@ -2202,12 +2425,13 @@ function applyBranchStart(chunk, beforeBranch, rendered) {
2202
2425
  }
2203
2426
  function writeBranchEnd(scopeId, accessor, serializeStateful, serializeMarker, parentEndTag, singleNode, branchIds) {
2204
2427
  const endTag = parentEndTag || "";
2205
- if (serializeMarker !== 0) if (!parentEndTag || serializeStateful !== 0) {
2206
- const { state } = $chunk.boundary;
2207
- const mark = singleNode ? state.mark(parentEndTag ? "}" : "|", scopeId + " " + accessor + (branchIds || "")) : state.mark(parentEndTag ? ")" : "]", scopeId + " " + accessor + (branchIds || ""));
2208
- $chunk.writeHTML(mark + endTag);
2209
- } else $chunk.writeHTML(endTag + _el_resume(scopeId, accessor));
2210
- else $chunk.writeHTML(endTag);
2428
+ if (serializeMarker !== 0) {
2429
+ if (!parentEndTag || serializeStateful !== 0) {
2430
+ const { state } = $chunk.boundary;
2431
+ const mark = singleNode ? state.mark(parentEndTag ? "}" : "|", scopeId + " " + accessor + (branchIds || "")) : state.mark(parentEndTag ? ")" : "]", scopeId + " " + accessor + (branchIds || ""));
2432
+ $chunk.writeHTML(mark + endTag);
2433
+ } else $chunk.writeHTML(endTag + _el_resume(scopeId, accessor));
2434
+ } else $chunk.writeHTML(endTag);
2211
2435
  }
2212
2436
  let writeScope = (scopeId, partialScope) => {
2213
2437
  const { state } = $chunk.boundary;
@@ -2215,7 +2439,7 @@ let writeScope = (scopeId, partialScope) => {
2215
2439
  const scope = scopeWithId(state, scopeId);
2216
2440
  const pending = target.writeScopes[scopeId];
2217
2441
  state.needsMainRuntime = true;
2218
- countResumeWrite($chunk.boundary);
2442
+ countResumeWrite($chunk);
2219
2443
  Object.assign(scope, partialScope);
2220
2444
  if (pending && pending !== partialScope) Object.assign(pending, partialScope);
2221
2445
  else target.writeScopes[scopeId] = partialScope;
@@ -2299,12 +2523,10 @@ function _await(scopeId, accessor, promise, content, serializeMarker) {
2299
2523
  }
2300
2524
  const chunk = $chunk;
2301
2525
  const { boundary } = chunk;
2302
- chunk.next = $chunk = chunk.fork(boundary, chunk.next);
2526
+ const startId = _peek_scope_id();
2527
+ const after = chunk.next = $chunk = chunk.fork(boundary, chunk.next);
2303
2528
  chunk.async = true;
2304
- if (chunk.context?.[kPendingContexts]) chunk.context = {
2305
- ...chunk.context,
2306
- [kPendingContexts]: 0
2307
- };
2529
+ captureContext(chunk);
2308
2530
  boundary.startAsync();
2309
2531
  promise.then((value) => {
2310
2532
  if (chunk.async) {
@@ -2314,9 +2536,16 @@ function _await(scopeId, accessor, promise, content, serializeMarker) {
2314
2536
  if (resumeMarker) {
2315
2537
  const branchId = _peek_scope_id();
2316
2538
  $chunk.writeHTML($chunk.boundary.state.mark("[", ""));
2317
- withBranchId(branchId, () => withIsAsync(content, value));
2539
+ withBranchId(branchId, () => withIsAsync({ parent: getAsyncContent(chunk) }, content, value));
2318
2540
  $chunk.writeHTML($chunk.boundary.state.mark("]", scopeId + " " + accessor + " " + branchId));
2319
- } else withIsAsync(content, value);
2541
+ } else {
2542
+ const renderedSince = _peek_scope_id() !== startId;
2543
+ const async = { parent: getAsyncContent(chunk) };
2544
+ withIsAsync(async, content, value);
2545
+ async.visit = renderedSince && (after.html || after.next) ? $chunk.boundary.state.mark("]", scopeId + " " + accessor) : "";
2546
+ if (async.resumed) $chunk.writeHTML(async.visit);
2547
+ async.end = $chunk;
2548
+ }
2320
2549
  });
2321
2550
  boundary.endAsync();
2322
2551
  }
@@ -2326,9 +2555,7 @@ function _await(scopeId, accessor, promise, content, serializeMarker) {
2326
2555
  boundary.abort(err);
2327
2556
  });
2328
2557
  }
2329
- function _try(scopeId, accessor, content, input) {
2330
- const catchContent = input.catch ? normalizeDynamicRenderer(input.catch) || 0 : void 0;
2331
- const placeholderContent = normalizeDynamicRenderer(input.placeholder);
2558
+ function _try(scopeId, accessor, content, placeholderContent, catchContent, placeholderId, catchId) {
2332
2559
  const placeholderBranchId = placeholderContent ? _scope_id() : 0;
2333
2560
  const branchId = _peek_scope_id();
2334
2561
  const chunk = $chunk;
@@ -2336,13 +2563,12 @@ function _try(scopeId, accessor, content, input) {
2336
2563
  const { state } = boundary;
2337
2564
  const { resumeWrites } = boundary;
2338
2565
  const beforeBranch = deferBranchStart(chunk);
2339
- let renderersAtSettle = false;
2340
- if (catchContent !== void 0 || placeholderContent) renderersAtSettle = tryBoundary(placeholderContent ? () => tryPlaceholder(content, placeholderContent, branchId, scopeId, placeholderBranchId) : content, catchContent, placeholderContent, branchId);
2341
- else withBranchId(branchId, content);
2566
+ const renderers = () => writeTryRenderers(branchId, catchContent && _resume(catchContent, catchId), placeholderContent && _resume(placeholderContent, placeholderId));
2567
+ const renderersWritten = tryBoundary(placeholderContent ? () => tryPlaceholder(content, placeholderContent, branchId, scopeId, placeholderBranchId) : content, catchContent, branchId, renderers);
2342
2568
  const rendered = chunk !== $chunk || boundary.resumeWrites !== resumeWrites;
2343
2569
  applyBranchStart(chunk, beforeBranch, rendered);
2344
2570
  if (!rendered) return;
2345
- if (!renderersAtSettle) writeTryRenderers(branchId, catchContent, placeholderContent);
2571
+ if (!renderersWritten) renderers();
2346
2572
  $chunk.writeHTML(state.mark("]", scopeId + " " + accessor + " " + branchId));
2347
2573
  }
2348
2574
  function tryPlaceholder(content, placeholder, branchId, scopeId, placeholderBranchId) {
@@ -2354,6 +2580,7 @@ function tryPlaceholder(content, placeholder, branchId, scopeId, placeholderBran
2354
2580
  return;
2355
2581
  }
2356
2582
  chunk.next = $chunk = chunk.fork(boundary, chunk.next);
2583
+ captureContext(chunk);
2357
2584
  chunk.placeholder = {
2358
2585
  body,
2359
2586
  render: placeholder,
@@ -2362,17 +2589,17 @@ function tryPlaceholder(content, placeholder, branchId, scopeId, placeholderBran
2362
2589
  placeholderBranchId
2363
2590
  };
2364
2591
  }
2365
- function tryBoundary(content, catchContent, placeholderContent, branchId) {
2592
+ function tryBoundary(content, catchContent, branchId, renderers) {
2366
2593
  const chunk = $chunk;
2367
2594
  const { boundary } = chunk;
2368
2595
  const { state } = boundary;
2369
2596
  const catchBoundary = new Boundary(state, boundary.signal, boundary);
2370
2597
  const body = chunk.fork(catchBoundary, null);
2371
- const bodyEnd = withBranchId(branchId, () => body.render(content));
2598
+ const bodyEnd = body.render(() => withBranchId(branchId, content));
2372
2599
  if (catchBoundary.signal.aborted) {
2373
- if (catchContent === void 0) boundary.abort(catchBoundary.signal.reason);
2374
- else if (catchContent) catchContent(catchBoundary.signal.reason);
2375
- return false;
2600
+ if (catchContent) catchContent(catchBoundary.signal.reason);
2601
+ else boundary.abort(catchBoundary.signal.reason);
2602
+ return true;
2376
2603
  }
2377
2604
  if (body === bodyEnd) {
2378
2605
  chunk.append(body);
@@ -2382,11 +2609,12 @@ function tryBoundary(content, catchContent, placeholderContent, branchId) {
2382
2609
  const bodyNext = bodyEnd.next = $chunk = chunk.fork(boundary, chunk.next);
2383
2610
  chunk.next = body;
2384
2611
  boundary.startAsync();
2385
- const reorderId = catchContent === void 0 ? "" : state.nextReorderId();
2612
+ const reorderId = catchContent ? state.nextReorderId() : "";
2386
2613
  const endMarker = reorderId && state.mark("!", reorderId);
2387
2614
  if (reorderId) {
2388
2615
  chunk.writeHTML(state.mark("!^", reorderId));
2389
2616
  bodyEnd.writeHTML(endMarker);
2617
+ captureContext(chunk);
2390
2618
  }
2391
2619
  catchBoundary.onNext = () => {
2392
2620
  if (boundary.signal.aborted) return;
@@ -2414,13 +2642,12 @@ function tryBoundary(content, catchContent, placeholderContent, branchId) {
2414
2642
  } while (cur !== bodyNext);
2415
2643
  }
2416
2644
  const catchChunk = chunk.fork(boundary, null);
2417
- const { resumeWrites } = boundary;
2418
2645
  catchChunk.reorderId = reorderId;
2419
- if ((catchChunk.render(catchContent || NOOP$2, catchBoundary.signal.reason) !== catchChunk || boundary.resumeWrites !== resumeWrites) && renderersAtSettle) catchChunk.render(() => writeTryRenderers(branchId, catchContent, placeholderContent));
2646
+ catchChunk.render(catchContent, catchBoundary.signal.reason);
2420
2647
  state.reorder(catchChunk);
2421
2648
  boundary.endAsync();
2422
2649
  } else if (!catchBoundary.count) {
2423
- if (renderersAtSettle && catchBoundary.resumeWrites) bodyEnd.render(() => writeTryRenderers(branchId, catchContent, placeholderContent));
2650
+ if (renderersAtSettle && catchBoundary.resumeWrites) bodyEnd.render(renderers);
2424
2651
  boundary.endAsync();
2425
2652
  } else boundary.onNext();
2426
2653
  };
@@ -2433,8 +2660,15 @@ function writeTryRenderers(branchId, catchContent, placeholderContent) {
2433
2660
  });
2434
2661
  }
2435
2662
  const NOOP$2 = () => {};
2436
- function countResumeWrite(boundary) {
2437
- for (; boundary; boundary = boundary.parent) boundary.resumeWrites++;
2663
+ function countResumeWrite(chunk) {
2664
+ for (let boundary = chunk.boundary; boundary; boundary = boundary.parent) boundary.resumeWrites++;
2665
+ for (let async = getAsyncContent(chunk); async && !async.resumed; async = async.parent) {
2666
+ async.resumed = true;
2667
+ async.end?.writeHTML(async.visit);
2668
+ }
2669
+ }
2670
+ function getAsyncContent(chunk) {
2671
+ return chunk.context?.[kIsAsync];
2438
2672
  }
2439
2673
  var State = class {
2440
2674
  tagId = 1;
@@ -2534,10 +2768,13 @@ var Boundary = class extends AbortController {
2534
2768
  this.state = new State(this.state.$global);
2535
2769
  this.onNext();
2536
2770
  });
2537
- if (signal) if (signal.aborted) this.abort(signal.reason);
2538
- else signal.addEventListener("abort", () => {
2539
- this.abort(signal.reason);
2540
- });
2771
+ if (signal) {
2772
+ if (signal.aborted) this.abort(signal.reason);
2773
+ else signal.addEventListener("abort", this);
2774
+ }
2775
+ }
2776
+ handleEvent(event) {
2777
+ this.abort(event.target.reason);
2541
2778
  }
2542
2779
  flush() {
2543
2780
  if (!this.signal.aborted) flushSerializer(this, this.state);
@@ -2547,7 +2784,8 @@ var Boundary = class extends AbortController {
2547
2784
  if (!this.signal.aborted) this.count++;
2548
2785
  }
2549
2786
  endAsync() {
2550
- if (!this.signal.aborted && this.count) {
2787
+ if (!this.signal.aborted) {
2788
+ if (!this.count) throw new Error("A boundary ended more async work than it started.");
2551
2789
  this.count--;
2552
2790
  this.onNext();
2553
2791
  }
@@ -2581,7 +2819,7 @@ var Chunk = class Chunk {
2581
2819
  this.html += html;
2582
2820
  }
2583
2821
  writeEffect(scopeId, registryId) {
2584
- countResumeWrite(this.boundary);
2822
+ countResumeWrite(this);
2585
2823
  if (this.lastEffect === registryId) this.effects += " " + scopeId;
2586
2824
  else {
2587
2825
  this.lastEffect = registryId;
@@ -2616,6 +2854,7 @@ var Chunk = class Chunk {
2616
2854
  flushPlaceholder() {
2617
2855
  const { placeholder } = this;
2618
2856
  if (placeholder) {
2857
+ this.placeholder = null;
2619
2858
  const body = placeholder.body.consume();
2620
2859
  if (body.async) {
2621
2860
  const { state } = this.boundary;
@@ -2624,11 +2863,11 @@ var Chunk = class Chunk {
2624
2863
  this.writeHTML(state.mark("!^", reorderId));
2625
2864
  const { effects } = this;
2626
2865
  const beforeBranch = deferBranchStart(this);
2627
- const after = this.render(() => withBranchId(placeholderBranchId, placeholder.render));
2628
- const stateful = after === this && this.effects !== effects;
2866
+ if (this.render(() => withBranchId(placeholderBranchId, placeholder.render)) !== this) this.boundary.abort(/* @__PURE__ */ new Error("An @placeholder cannot contain async content."));
2867
+ if (this.boundary.signal.aborted) return;
2868
+ const stateful = this.effects !== effects;
2629
2869
  applyBranchStart(this, beforeBranch, stateful);
2630
- if (after !== this) this.boundary.abort(/* @__PURE__ */ new Error("An @placeholder cannot contain async content."));
2631
- else if (stateful) {
2870
+ if (stateful) {
2632
2871
  this.render(() => writeScope(branchId, { [PlaceholderBranch]: scopeWithId(state, placeholderBranchId) }));
2633
2872
  this.writeHTML(state.mark("]", scopeId + " " + (PlaceholderBranch + branchId) + " " + placeholderBranchId));
2634
2873
  body.writeEffect(branchId, PLACEHOLDER_DISMISS_REGISTER_ID);
@@ -2639,7 +2878,6 @@ var Chunk = class Chunk {
2639
2878
  body.next = this.next;
2640
2879
  this.next = body;
2641
2880
  }
2642
- this.placeholder = null;
2643
2881
  }
2644
2882
  }
2645
2883
  consume() {
@@ -2686,12 +2924,12 @@ var Chunk = class Chunk {
2686
2924
  $chunk = prev;
2687
2925
  }
2688
2926
  }
2689
- flushReadyScripts(reservations, holdEffects) {
2690
- const { boundary, serializeState } = this;
2927
+ flushReadyScripts(boundary, reservations, holdEffects) {
2928
+ const { serializeState } = this;
2691
2929
  const { readyId } = serializeState;
2692
2930
  let scripts = "";
2693
2931
  forEach(this.takeDeferredReady(), (chunk) => {
2694
- scripts = concatScripts(scripts, chunk.flushReadyScripts(reservations, holdEffects));
2932
+ scripts = concatScripts(scripts, chunk.flushReadyScripts(boundary, reservations, holdEffects));
2695
2933
  if (chunk.effects || chunk.deferredReady) this.deferredReady = push(this.deferredReady, chunk);
2696
2934
  });
2697
2935
  if (readyId && !this.async) {
@@ -2716,14 +2954,13 @@ var Chunk = class Chunk {
2716
2954
  }
2717
2955
  return scripts;
2718
2956
  }
2719
- flushScript() {
2720
- const { boundary } = this;
2957
+ flushScript(boundary) {
2721
2958
  const { state } = boundary;
2722
2959
  const { $global, runtimePrefix } = state;
2723
2960
  let needsWalk = state.walkOnNextFlush;
2724
2961
  if (needsWalk) state.walkOnNextFlush = false;
2725
- let readyResumeScripts = this.flushReadyScripts(void 0, this.async);
2726
- for (let channel; channel = state.serializer.pendingReadyChannel();) {
2962
+ let readyResumeScripts = this.flushReadyScripts(boundary, void 0, this.async);
2963
+ for (let channel; !boundary.signal.aborted && (channel = state.serializer.pendingReadyChannel());) {
2727
2964
  const resumes = state.serializer.stringifyScopes([], boundary, channel);
2728
2965
  const deps = state.serializer.takeChannelDeps();
2729
2966
  state.needsMainRuntime = true;
@@ -2771,7 +3008,7 @@ var Chunk = class Chunk {
2771
3008
  cur.flushPlaceholder();
2772
3009
  cur.deferOwnReady();
2773
3010
  const { next } = cur;
2774
- const readyResumeScripts = cur.flushReadyScripts(readyReservations, this.async);
3011
+ const readyResumeScripts = cur.flushReadyScripts(boundary, readyReservations, this.async);
2775
3012
  this.deferredReady = concat(this.deferredReady, cur.takeDeferredReady());
2776
3013
  cur.consumed = true;
2777
3014
  reorderHTML += cur.html;
@@ -2786,12 +3023,14 @@ var Chunk = class Chunk {
2786
3023
  if (next) cur = next;
2787
3024
  else break;
2788
3025
  }
2789
- if (reorderEffects) if (this.async) {
2790
- this.effects = concatEffects(this.effects, reorderEffects);
2791
- this.lastEffect = "";
2792
- } else {
2793
- needsResumeArray = true;
2794
- reorderScripts = concatScripts(reorderScripts, "_.push(\"" + reorderEffects + "\")");
3026
+ if (reorderEffects) {
3027
+ if (this.async) {
3028
+ this.effects = concatEffects(this.effects, reorderEffects);
3029
+ this.lastEffect = "";
3030
+ } else {
3031
+ needsResumeArray = true;
3032
+ reorderScripts = concatScripts(reorderScripts, "_.push(\"" + reorderEffects + "\")");
3033
+ }
2795
3034
  }
2796
3035
  for (const reservation of readyReservations) reordered = concatScripts(reordered, reservation);
2797
3036
  reordered = concatScripts(reordered, reorderScripts && runtimePrefix + ".j" + toAccess(reorderId) + "=_=>{" + reorderScripts + "}");
@@ -2809,14 +3048,13 @@ var Chunk = class Chunk {
2809
3048
  state.resumes = "";
2810
3049
  return this;
2811
3050
  }
2812
- flushHTML() {
2813
- const { boundary } = this;
3051
+ flushHTML(boundary) {
2814
3052
  const { state } = boundary;
2815
3053
  if (this.needsWalk) {
2816
3054
  this.needsWalk = false;
2817
3055
  state.walkOnNextFlush = true;
2818
3056
  }
2819
- this.flushScript();
3057
+ this.flushScript(boundary);
2820
3058
  const { html, scripts } = this;
2821
3059
  this.html = this.scripts = "";
2822
3060
  return state.flushChunk(html, scripts, boundary.count);
@@ -2892,13 +3130,17 @@ function getFilteredGlobals($global) {
2892
3130
  let filtered = 0;
2893
3131
  if (Array.isArray(serializedGlobals)) for (const key of serializedGlobals) {
2894
3132
  const value = $global[key];
2895
- if (value !== void 0) if (filtered) filtered[key] = value;
2896
- else filtered = { [key]: value };
3133
+ if (value !== void 0) {
3134
+ if (filtered) filtered[key] = value;
3135
+ else filtered = { [key]: value };
3136
+ }
2897
3137
  }
2898
3138
  else for (const key in serializedGlobals) if (serializedGlobals[key]) {
2899
3139
  const value = $global[key];
2900
- if (value !== void 0) if (filtered) filtered[key] = value;
2901
- else filtered = { [key]: value };
3140
+ if (value !== void 0) {
3141
+ if (filtered) filtered[key] = value;
3142
+ else filtered = { [key]: value };
3143
+ }
2902
3144
  }
2903
3145
  return filtered;
2904
3146
  }
@@ -2935,231 +3177,46 @@ function flushTickQueue() {
2935
3177
  }
2936
3178
  }
2937
3179
  //#endregion
2938
- //#region src/html/attrs.ts
2939
- function _attr_class(value) {
2940
- return stringAttr("class", toDelimitedString(value, " ", stringifyClassObject));
2941
- }
2942
- function _attr_style(value) {
2943
- return stringAttr("style", toDelimitedString(value, ";", stringifyStyleObject));
2944
- }
2945
- function _attr_option_value(value) {
2946
- const valueAttr = _attr("value", value);
2947
- const selectedValue = getContext(kSelectedValue);
2948
- if (selectedValue !== void 0 && normalizedValueMatches(selectedValue, value)) {
2949
- {
2950
- const matched = getContext(kSelectedValueMatched);
2951
- if (matched) matched.value = true;
2952
- }
2953
- return valueAttr + " selected";
2954
- }
2955
- return valueAttr;
2956
- }
2957
- const kSelectedValue = Symbol("selectedValue");
2958
- const kSelectedValueMatched = Symbol("selectedValueMatched");
2959
- function _attr_select_value(scopeId, nodeAccessor, value, valueChange, content, serializeType) {
2960
- if (valueChange) writeControlledScope(3, scopeId, nodeAccessor, void 0, valueChange, serializeType);
2961
- if (content) {
2962
- const selectedValue = value ?? "";
2963
- if (valueChange) {
2964
- const matched = { value: false };
2965
- withContext(kSelectedValue, selectedValue, () => withContext(kSelectedValueMatched, matched, content));
2966
- if (!matched.value && (Array.isArray(value) ? value.some((v) => normalizeStrAttrValue(v) !== "") : normalizeStrAttrValue(value) !== "")) console.error("A controlled `<select>`'s `value` has no matching `<option>`:", value);
2967
- } else withContext(kSelectedValue, selectedValue, content);
2968
- }
2969
- }
2970
- function _attr_textarea_value(scopeId, nodeAccessor, value, valueChange, serializeType) {
2971
- if (valueChange) writeControlledScope(2, scopeId, nodeAccessor, void 0, valueChange, serializeType);
2972
- return _textarea_value(value);
2973
- }
2974
- function _textarea_value(value) {
2975
- const escaped = _escape(normalizeStrAttrValue(value));
2976
- return escaped[0] === "\n" ? "\n" + escaped : escaped;
2977
- }
2978
- function _attr_input_value(scopeId, nodeAccessor, value, valueChange, serializeType) {
2979
- if (valueChange) writeControlledScope(2, scopeId, nodeAccessor, void 0, valueChange, serializeType);
2980
- return _attr("value", value);
2981
- }
2982
- function _attr_input_checked(scopeId, nodeAccessor, checked, checkedChange, serializeType) {
2983
- if (checkedChange) writeControlledScope(0, scopeId, nodeAccessor, void 0, checkedChange, serializeType);
2984
- return isNotVoid(checked) ? " checked" : "";
2985
- }
2986
- function _attr_input_checkedValue(scopeId, nodeAccessor, checkedValue, checkedValueChange, value, serializeType) {
2987
- const valueAttr = _attr("value", value);
2988
- if (checkedValueChange) writeControlledScope(1, scopeId, nodeAccessor, getCheckedValueRef(checkedValue), checkedValueChange, serializeType);
2989
- return normalizedValueMatches(checkedValue, value) ? valueAttr + " checked" : valueAttr;
2990
- }
2991
- const checkedValuesRefs = /* @__PURE__ */ new WeakMap();
2992
- function getCheckedValueRef(checkedValue) {
2993
- if (Array.isArray(checkedValue)) {
2994
- let ref = checkedValuesRefs.get(checkedValue);
2995
- if (!ref) {
2996
- ref = [];
2997
- checkedValuesRefs.set(checkedValue, ref);
2998
- }
2999
- return ref;
3000
- }
3001
- }
3002
- function _attr_details_or_dialog_open(scopeId, nodeAccessor, open, openChange, serializeType) {
3003
- const normalizedOpen = isNotVoid(open);
3004
- if (openChange) writeControlledScope(4, scopeId, nodeAccessor, normalizedOpen || void 0, openChange, serializeType);
3005
- return normalizedOpen ? " open" : "";
3006
- }
3007
- function _attr_nonce() {
3008
- return getChunk().boundary.state.nonceAttr;
3009
- }
3010
- function _style_html(decls) {
3011
- const id = _id();
3012
- return `<style${_attr_nonce()} class=${id}>.${id}~*{${decls}}</style>`;
3013
- }
3014
- function _attr(name, value) {
3015
- return isVoid(value) ? "" : nonVoidAttr(name, value);
3016
- }
3017
- function _attr_and(name, value, attr) {
3018
- return value ? attr : _attr(name, value);
3019
- }
3020
- function _attr_or(name, value, attr) {
3021
- return value ? _attr(name, value) : attr;
3022
- }
3023
- function _attr_nullish(name, value, attr) {
3024
- return value == null ? attr : _attr(name, value);
3025
- }
3026
- function _attrs(data, nodeAccessor, scopeId, tagName) {
3027
- let result = "";
3028
- let skip = /[\s/>"'=]/;
3029
- let events;
3030
- switch (data && tagName) {
3031
- case "input":
3032
- assertExclusiveAttrs(data);
3033
- if (data.checkedChange) {
3034
- result += _attr_input_checked(scopeId, nodeAccessor, data.checked, data.checkedChange, 1);
3035
- skip = /^checked(?:Value)?(?:Change)?$|[\s/>"'=]/;
3036
- } else if ("checkedValue" in data || data.checkedValueChange) {
3037
- result += _attr_input_checkedValue(scopeId, nodeAccessor, data.checkedValue, data.checkedValueChange, data.value, 1);
3038
- skip = /^(?:value|checked(?:Value)?)(?:Change)?$|[\s/>"'=]/;
3039
- } else if (data.valueChange) {
3040
- assertNoValueBindingOnCheckable(data.type, data.valueChange);
3041
- result += _attr_input_value(scopeId, nodeAccessor, data.value, data.valueChange, 1);
3042
- skip = /^value(?:Change)?$|[\s/>"'=]/;
3043
- }
3044
- break;
3045
- case "select":
3046
- case "textarea":
3047
- if ("value" in data || data.valueChange) skip = /^value(?:Change)?$|[\s/>"'=]/;
3048
- break;
3049
- case "option":
3050
- if ("value" in data) {
3051
- result += _attr_option_value(data.value);
3052
- skip = /^value$|[\s/>"'=]/;
3053
- }
3054
- break;
3055
- case "details":
3056
- case "dialog":
3057
- if (data.openChange) {
3058
- result += _attr_details_or_dialog_open(scopeId, nodeAccessor, data.open, data.openChange, 1);
3059
- skip = /^open(?:Change)?$|[\s/>"'=]/;
3060
- }
3061
- break;
3062
- }
3063
- for (const name in data) {
3064
- const value = data[name];
3065
- switch (name) {
3066
- case "class":
3067
- result += _attr_class(value);
3068
- break;
3069
- case "style":
3070
- result += _attr_style(value);
3071
- break;
3072
- default:
3073
- if (name) assertValidAttrName(name);
3074
- if (name && !(isVoid(value) || skip.test(name) || name === "content" && tagName !== "meta")) if (isEventHandler(name)) {
3075
- if (!events) {
3076
- events = {};
3077
- writeScope(scopeId, { [EventAttributes + nodeAccessor]: events });
3078
- }
3079
- events[getEventHandlerName(name)] = value;
3080
- } else result += nonVoidAttr(name, value);
3081
- break;
3082
- }
3083
- }
3084
- return result;
3085
- }
3086
- function _attrs_content(data, nodeAccessor, scopeId, tagName, serializeReason) {
3087
- _html(`${_attrs(data, nodeAccessor, scopeId, tagName)}>`);
3088
- _attr_content(nodeAccessor, scopeId, data?.content, serializeReason);
3089
- }
3090
- function _attrs_partial(data, skip, nodeAccessor, scopeId, tagName) {
3091
- const partial = {};
3092
- for (const name in data) {
3093
- const key = isEventHandler(name) ? `on-${getEventHandlerName(name)}` : name;
3094
- if (!skip[key]) partial[key] = data[name];
3095
- }
3096
- assertExclusiveAttrs({
3097
- ...data,
3098
- ...skip
3099
- });
3100
- return _attrs(partial, nodeAccessor, scopeId, tagName);
3101
- }
3102
- function _attrs_partial_content(data, skip, nodeAccessor, scopeId, tagName, serializeReason) {
3103
- _html(`${_attrs_partial(data, skip, nodeAccessor, scopeId, tagName)}>`);
3104
- _attr_content(nodeAccessor, scopeId, data?.content, serializeReason);
3105
- }
3106
- function writeControlledScope(type, scopeId, nodeAccessor, value, valueChange, serializeType) {
3107
- var handlerName = [
3108
- "checkedChange",
3109
- "checkedValueChange",
3110
- "valueChange",
3111
- "valueChange",
3112
- "openChange"
3113
- ][type];
3114
- assertHandlerIsFunction(handlerName, valueChange);
3115
- setDebugSlotName(writeScope(scopeId, serializeType ? {
3116
- [ControlledType + nodeAccessor]: type,
3117
- [ControlledValue + nodeAccessor]: value,
3118
- [ControlledHandler + nodeAccessor]: valueChange
3119
- } : {
3120
- [ControlledValue + nodeAccessor]: value,
3121
- [ControlledHandler + nodeAccessor]: valueChange
3122
- }), ControlledHandler + nodeAccessor, handlerName);
3123
- }
3124
- function stringAttr(name, value) {
3125
- return value && " " + name + attrAssignment(value);
3126
- }
3127
- function nonVoidAttr(name, value) {
3128
- assertValidAttrValue(name, value);
3129
- switch (typeof value) {
3130
- case "string": return " " + name + attrAssignment(value);
3131
- case "boolean": return " " + name;
3132
- case "number": return " " + name + "=" + value;
3133
- }
3134
- return " " + name + attrAssignment(value + "");
3180
+ //#region src/html/content.ts
3181
+ function _to_text(val) {
3182
+ assertValidTextValue(val);
3183
+ return val || val === 0 ? val + "" : "";
3135
3184
  }
3136
- const singleQuoteAttrReplacements = /['\r]|&(?=[#a-zA-Z])/g;
3137
- const doubleQuoteAttrReplacements = /["\r]|&(?=[#a-zA-Z])/g;
3138
- const needsQuotedAttr = /["'>\s]|&[#a-zA-Z]|\/$/g;
3139
- function attrAssignment(value) {
3140
- return value ? needsQuotedAttr.test(value) ? value[needsQuotedAttr.lastIndex - 1] === (needsQuotedAttr.lastIndex = 0, "\"") ? "='" + escapeSingleQuotedAttrValue(value) + "'" : "=\"" + escapeDoubleQuotedAttrValue(value) + "\"" : "=" + value : "";
3185
+ function _unescaped(val) {
3186
+ assertValidTextValue(val);
3187
+ return val ? val + "" : val === 0 ? "0" : "";
3141
3188
  }
3142
- function escapeSingleQuotedAttrValue(value) {
3143
- return singleQuoteAttrReplacements.test(value) ? value.replace(singleQuoteAttrReplacements, replaceUnsafeSingleQuoteAttrChar) : value;
3189
+ const unsafeXMLReg = /[<&\r]/g;
3190
+ const replaceUnsafeXML = (c) => c === "&" ? "&amp;" : c === "<" ? "&lt;" : "&#13;";
3191
+ const escapeXMLStr = (str) => unsafeXMLReg.test(str) ? str.replace(unsafeXMLReg, replaceUnsafeXML) : str;
3192
+ function _escape(val) {
3193
+ assertValidTextValue(val);
3194
+ return val ? escapeXMLStr(val + "") : val === 0 ? "0" : "";
3144
3195
  }
3145
- function replaceUnsafeSingleQuoteAttrChar(match) {
3146
- return match === "'" ? "&#39;" : match === "\r" ? "&#13;" : "&amp;";
3196
+ const unsafeScriptReg = /<(\/?script|!--)/gi;
3197
+ const escapeScriptStr = (str) => unsafeScriptReg.test(str) ? str.replace(unsafeScriptReg, "\\x3C$1") : str;
3198
+ function _escape_script(val) {
3199
+ assertValidTextValue(val);
3200
+ return val ? escapeScriptStr(val + "") : val === 0 ? "0" : "";
3147
3201
  }
3148
- function escapeDoubleQuotedAttrValue(value) {
3149
- return doubleQuoteAttrReplacements.test(value) ? value.replace(doubleQuoteAttrReplacements, replaceUnsafeDoubleQuoteAttrChar) : value;
3202
+ const unsafeStyleReg = /<(\/style)/gi;
3203
+ const escapeStyleStr = (str) => unsafeStyleReg.test(str) ? str.replace(unsafeStyleReg, "\\3C$1") : str;
3204
+ function _escape_style(val) {
3205
+ assertValidTextValue(val);
3206
+ return val ? escapeStyleStr(val + "") : val === 0 ? "0" : "";
3150
3207
  }
3151
- function replaceUnsafeDoubleQuoteAttrChar(match) {
3152
- return match === "\"" ? "&#34;" : match === "\r" ? "&#13;" : "&amp;";
3208
+ function _escape_style_value(val) {
3209
+ assertValidTextValue(val);
3210
+ return val || val === 0 ? escapeStyleValue(val + "") : "";
3153
3211
  }
3154
- function normalizedValueMatches(a, b) {
3155
- const value = normalizeStrAttrValue(b);
3156
- if (Array.isArray(a)) {
3157
- for (const item of a) if (normalizeStrAttrValue(item) === value) return true;
3158
- } else if (normalizeStrAttrValue(a) === value) return true;
3159
- return false;
3212
+ const unsafeCommentReg = />/g;
3213
+ function escapeCommentStr(str) {
3214
+ if (unsafeCommentReg.test(str)) str = str.replace(unsafeCommentReg, "&gt;");
3215
+ return str.startsWith(getState().commentPrefix) ? "&#" + str.charCodeAt(0) + ";" + str.slice(1) : str;
3160
3216
  }
3161
- function normalizeStrAttrValue(value) {
3162
- return isNotVoid(value) && value !== true ? value + "" : "";
3217
+ function _escape_comment(val) {
3218
+ assertValidTextValue(val);
3219
+ return val ? escapeCommentStr(val + "") : val === 0 ? "0" : "";
3163
3220
  }
3164
3221
  //#endregion
3165
3222
  //#region src/html/dynamic-tag.ts
@@ -3182,7 +3239,7 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, s
3182
3239
  const renderContent = content || normalizeDynamicRenderer(input.content);
3183
3240
  if (renderer === "textarea") {
3184
3241
  if (renderContent) throw new Error("A dynamic tag rendering a `<textarea>` cannot have `content` and must use the `value` attribute instead.");
3185
- _html(_attr_textarea_value(branchId, `#${renderer.toLowerCase()}/0`, input.value, input.valueChange, 1));
3242
+ _html(_attrs_textarea_value(branchId, `#${renderer.toLowerCase()}/0`, input));
3186
3243
  } else {
3187
3244
  if (renderContent && typeof renderContent !== "function") throw new Error(`Body content is not supported for the \`<${renderer}>\` tag.`);
3188
3245
  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);
@@ -3418,27 +3475,33 @@ var ServerRendered = class {
3418
3475
  }
3419
3476
  #promise() {
3420
3477
  return this.#cachedPromise ||= new Promise((resolve, reject) => {
3421
- const head = this.#head;
3478
+ let head = this.#head;
3422
3479
  this.#head = null;
3423
3480
  if (!head) return reject(/* @__PURE__ */ new Error(CONSUMED_RESULT_MESSAGE));
3424
3481
  const { boundary } = head;
3482
+ let html = "";
3425
3483
  (boundary.onNext = () => {
3426
3484
  switch (!boundary.count && boundary.flush()) {
3427
3485
  case 2:
3428
- boundary.onNext = NOOP$1;
3486
+ settle(boundary);
3429
3487
  reject(boundary.signal.reason);
3430
3488
  break;
3431
- case 0: {
3432
- const consumed = head.consume();
3433
- if (!boundary.signal.aborted) resolve(consumed.flushHTML());
3434
- break;
3435
- }
3489
+ case 0:
3490
+ head = head.consume();
3491
+ if (boundary.signal.aborted) break;
3492
+ html += head.flushHTML(boundary);
3493
+ if (!(boundary.count || boundary.signal.aborted)) {
3494
+ settle(boundary);
3495
+ resolve(html);
3496
+ }
3436
3497
  }
3437
3498
  })();
3438
3499
  });
3439
3500
  }
3440
3501
  #read(onWrite, onAbort, onClose) {
3441
3502
  let tick = true;
3503
+ let flushing = false;
3504
+ let again = false;
3442
3505
  let head = this.#head;
3443
3506
  this.#head = null;
3444
3507
  if (!head) {
@@ -3447,24 +3510,39 @@ var ServerRendered = class {
3447
3510
  }
3448
3511
  const { boundary } = head;
3449
3512
  const onNext = boundary.onNext = (write) => {
3450
- const status = boundary.flush();
3451
- if (status === 2) {
3452
- if (!tick) offTick(onNext);
3453
- boundary.onNext = NOOP$1;
3454
- onAbort(boundary.signal.reason);
3455
- } else if (write || status === 0) {
3456
- head = head.consume();
3457
- if (boundary.signal.aborted) return;
3458
- const html = head.flushHTML();
3459
- if (html) onWrite(html);
3460
- if (status === 0) {
3461
- if (!tick) offTick(onNext);
3462
- onClose();
3463
- } else tick = true;
3464
- } else if (tick) {
3465
- tick = false;
3466
- queueTick(onNext);
3513
+ if (flushing) {
3514
+ again = true;
3515
+ return;
3467
3516
  }
3517
+ flushing = true;
3518
+ do {
3519
+ again = false;
3520
+ const status = boundary.flush();
3521
+ if (status === 2) {
3522
+ if (!tick) offTick(onNext);
3523
+ settle(boundary);
3524
+ onAbort(boundary.signal.reason);
3525
+ return;
3526
+ }
3527
+ if (write || status === 0) {
3528
+ head = head.consume();
3529
+ if (boundary.signal.aborted) continue;
3530
+ const html = head.flushHTML(boundary);
3531
+ if (boundary.signal.aborted) continue;
3532
+ if (html) onWrite(html);
3533
+ if (!boundary.count) {
3534
+ if (!tick) offTick(onNext);
3535
+ settle(boundary);
3536
+ onClose();
3537
+ return;
3538
+ }
3539
+ if (write) tick = true;
3540
+ } else if (tick) {
3541
+ tick = false;
3542
+ queueTick(onNext);
3543
+ }
3544
+ } while (again);
3545
+ flushing = false;
3468
3546
  };
3469
3547
  onNext();
3470
3548
  return boundary;
@@ -3474,13 +3552,17 @@ var ServerRendered = class {
3474
3552
  this.#head = null;
3475
3553
  if (!head) throw new Error(CONSUMED_RESULT_MESSAGE);
3476
3554
  const { boundary } = head;
3477
- switch (boundary.flush()) {
3478
- case 2: throw boundary.signal.reason;
3479
- case 1: throw new Error("Cannot consume asynchronous render with 'toString'");
3480
- }
3481
- return head.consume().flushHTML();
3555
+ const html = boundary.flush() === 0 ? head.consume().flushHTML(boundary) : "";
3556
+ if (boundary.count) boundary.abort(/* @__PURE__ */ new Error("Cannot consume asynchronous render with 'toString'"));
3557
+ settle(boundary);
3558
+ if (boundary.signal.aborted) throw boundary.signal.reason;
3559
+ return html;
3482
3560
  }
3483
3561
  };
3562
+ function settle(boundary) {
3563
+ boundary.onNext = NOOP$1;
3564
+ boundary.state.$global.signal?.removeEventListener("abort", boundary);
3565
+ }
3484
3566
  function NOOP$1() {}
3485
3567
  //#endregion
3486
3568
  //#region src/html/assets.ts
@@ -3501,8 +3583,10 @@ function withPageAssets(template, runtime, assetId, runtimeId) {
3501
3583
  return Object.assign((input) => {
3502
3584
  const g = $global();
3503
3585
  if (runtimeId) {
3504
- if (g.runtimeId !== "M" && g.runtimeId !== runtimeId) throw new Error(`$global.runtimeId ("${g.runtimeId}") conflicts with the runtimeId this entry was compiled with ("${runtimeId}").`);
3505
- g.runtimeId = runtimeId;
3586
+ if (!g[kAssets]) {
3587
+ if (g.runtimeId !== "M" && g.runtimeId !== runtimeId) throw new Error(`$global.runtimeId ("${g.runtimeId}") conflicts with the runtimeId this entry was compiled with ("${runtimeId}").`);
3588
+ g.runtimeId = runtimeId;
3589
+ } 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.`);
3506
3590
  }
3507
3591
  addAsset(g, assetId);
3508
3592
  if (g.__flush__) {
@@ -3610,9 +3694,9 @@ const compat = {
3610
3694
  },
3611
3695
  onFlush(fn) {
3612
3696
  const { flushHTML } = Chunk.prototype;
3613
- Chunk.prototype.flushHTML = function() {
3697
+ Chunk.prototype.flushHTML = function(boundary) {
3614
3698
  fn(this);
3615
- return flushHTML.call(this);
3699
+ return flushHTML.call(this, boundary);
3616
3700
  };
3617
3701
  },
3618
3702
  patchDynamicTag,
@@ -3644,16 +3728,16 @@ const compat = {
3644
3728
  flushScript($global, chunk) {
3645
3729
  chunk ||= this.createChunk($global);
3646
3730
  const { boundary } = chunk;
3647
- switch (boundary.flush()) {
3648
- case 2: throw boundary.signal.reason;
3649
- case 1: throw new Error("Cannot serialize promise across tags/class compat layer.");
3650
- }
3651
- return chunk.flushScript().scripts;
3731
+ const scripts = boundary.flush() === 0 ? chunk.flushScript(boundary).scripts : "";
3732
+ if (boundary.signal.aborted) throw boundary.signal.reason;
3733
+ if (boundary.count) throw new Error("Cannot serialize promise across tags/class compat layer.");
3734
+ return scripts;
3652
3735
  },
3653
3736
  render(renderer, willRerender, classAPIOut, component, input, completeChunks, registerChildScope) {
3654
3737
  const state = this.ensureState(classAPIOut.global);
3655
3738
  const boundary = new Boundary(state);
3656
- let head = new Chunk(boundary, null, getChunk()?.context ?? null, state);
3739
+ const context = getChunk()?.context ?? null;
3740
+ let head = new Chunk(boundary, new Chunk(boundary, null, context, state), context, state);
3657
3741
  let normalizedInput = input;
3658
3742
  if ("renderBody" in input) {
3659
3743
  normalizedInput = {};
@@ -3736,4 +3820,4 @@ function drainClassFunctions($global, writeScope) {
3736
3820
  }
3737
3821
  function NOOP() {}
3738
3822
  //#endregion
3739
- export { $global, _assert_hoist, _attr, _attr_and, _attr_class, _attr_content, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_input_checked, _attr_input_checkedValue, _attr_input_value, _attr_nonce, _attr_nullish, _attr_option_value, _attr_or, _attr_select_value, _attr_style, _attr_textarea_value, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, _await, _content, _content_resume, _dynamic_tag, _el, _el_read_error, _el_resume, _escape, _escape_comment, _escape_script, _escape_style, _escape_style_value, _existing_scope, _flush_head, _for_in, _for_of, _for_to, _for_until, _hoist, _hoist_read_error, _html, _html_resume, _id, _if, _peek_scope_id, _resume, _resume_branch, _resume_locals, writeScope as _scope, _scope_id, _scope_reason, _scope_with_id, _script, _serialize_guard, _serialize_if, _set_serialize_reason, _show_end, _show_start, _style_html, _subscribe, _template, _text_resume, _textarea_value, _to_text, _trailers, _try, _unescaped, _var, attrTag, attrTags, compat, forIn, forOf, forTo, forUntil, withLoadAssets, withPageAssets };
3823
+ export { $global, _assert_hoist, _attr, _attr_and, _attr_class, _attr_content, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_input_checked, _attr_input_checkedValue, _attr_input_value, _attr_nonce, _attr_nullish, _attr_option_value, _attr_or, _attr_select_value, _attr_style, _attr_textarea_value, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, _attrs_select_value, _attrs_textarea_value, _await, _content, _content_resume, _dynamic_tag, _el, _el_read_error, _el_resume, _escape, _escape_comment, _escape_script, _escape_style, _escape_style_value, _existing_scope, _flush_head, _for_in, _for_of, _for_to, _for_until, _hoist, _hoist_read_error, _html, _html_resume, _id, _if, _peek_scope_id, _resume, _resume_branch, _resume_locals, writeScope as _scope, _scope_id, _scope_reason, _scope_with_id, _script, _serialize_guard, _serialize_if, _set_serialize_reason, _show_end, _show_start, _style_html, _subscribe, _template, _text_resume, _textarea_value, _to_text, _trailers, _try, _unescaped, _var, attrTag, attrTags, compat, forIn, forOf, forTo, forUntil, withLoadAssets, withPageAssets };