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