marko 6.3.55 → 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 (90) hide show
  1. package/cheatsheet.md +3 -2
  2. package/dist/common/accessor.d.ts +3 -0
  3. package/dist/common/accessor.debug.d.ts +3 -0
  4. package/dist/common/constants/accessor-prefix.d.ts +1 -0
  5. package/dist/common/constants/accessor-prefix.debug.d.ts +1 -0
  6. package/dist/common/constants/accessor-prop.d.ts +3 -0
  7. package/dist/common/constants/accessor-prop.debug.d.ts +3 -0
  8. package/dist/common/constants/closure-scopes-prop.d.ts +4 -0
  9. package/dist/common/constants/closure-scopes-prop.debug.d.ts +4 -0
  10. package/dist/common/types.d.ts +9 -3
  11. package/dist/debug/dom/catch.feat.js +12 -14
  12. package/dist/debug/dom/catch.feat.mjs +12 -14
  13. package/dist/debug/dom/controllable-input.feat.js +1 -1
  14. package/dist/debug/dom/controllable-input.feat.mjs +1 -1
  15. package/dist/debug/dom/controllable-open.feat.js +1 -1
  16. package/dist/debug/dom/controllable-open.feat.mjs +1 -1
  17. package/dist/debug/dom/controllable-select.feat.js +1 -1
  18. package/dist/debug/dom/controllable-select.feat.mjs +1 -1
  19. package/dist/debug/dom/controllable-textarea.feat.js +1 -1
  20. package/dist/debug/dom/controllable-textarea.feat.mjs +1 -1
  21. package/dist/debug/dom/controllable.feat.js +1 -1
  22. package/dist/debug/dom/controllable.feat.mjs +1 -1
  23. package/dist/debug/dom/dynamic-tag-script.feat.js +1 -1
  24. package/dist/debug/dom/dynamic-tag-script.feat.mjs +1 -1
  25. package/dist/debug/dom/dynamic-tag-var.feat.js +1 -1
  26. package/dist/debug/dom/dynamic-tag-var.feat.mjs +1 -1
  27. package/dist/debug/dom/lazy.feat.js +4 -0
  28. package/dist/debug/dom/lazy.feat.mjs +4 -0
  29. package/dist/debug/dom/placeholder.feat.js +1 -1
  30. package/dist/debug/dom/placeholder.feat.mjs +1 -1
  31. package/dist/debug/{dom-CI0Vojyk.js → dom-BRO5aArp.js} +248 -193
  32. package/dist/debug/{dom-tl43c2wO.mjs → dom-Btj2QJhk.mjs} +225 -176
  33. package/dist/debug/dom.js +15 -13
  34. package/dist/debug/dom.mjs +15 -13
  35. package/dist/debug/html.js +605 -523
  36. package/dist/debug/html.mjs +604 -524
  37. package/dist/dom/abort-signal.d.ts +2 -0
  38. package/dist/dom/catch.feat.js +6 -7
  39. package/dist/dom/catch.feat.mjs +5 -7
  40. package/dist/dom/control-flow.d.ts +3 -5
  41. package/dist/dom/controllable-input.feat.js +3 -2
  42. package/dist/dom/controllable-input.feat.mjs +1 -1
  43. package/dist/dom/controllable-open.feat.js +3 -2
  44. package/dist/dom/controllable-open.feat.mjs +1 -1
  45. package/dist/dom/controllable-select.feat.js +3 -2
  46. package/dist/dom/controllable-select.feat.mjs +1 -1
  47. package/dist/dom/controllable-textarea.feat.js +3 -2
  48. package/dist/dom/controllable-textarea.feat.mjs +1 -1
  49. package/dist/dom/controllable.feat.js +3 -2
  50. package/dist/dom/controllable.feat.mjs +1 -1
  51. package/dist/dom/dynamic-tag-script.feat.js +3 -2
  52. package/dist/dom/dynamic-tag-script.feat.mjs +1 -1
  53. package/dist/dom/dynamic-tag-var.feat.js +2 -1
  54. package/dist/dom/dynamic-tag-var.feat.mjs +1 -1
  55. package/dist/dom/lazy.feat.d.ts +1 -0
  56. package/dist/dom/lazy.feat.js +4 -0
  57. package/dist/dom/lazy.feat.mjs +4 -0
  58. package/dist/dom/load.d.ts +3 -3
  59. package/dist/dom/placeholder.feat.js +4 -3
  60. package/dist/dom/placeholder.feat.mjs +1 -1
  61. package/dist/dom/queue.d.ts +2 -4
  62. package/dist/dom/resume.d.ts +2 -2
  63. package/dist/dom/scope.d.ts +0 -1
  64. package/dist/dom/signals.d.ts +1 -1
  65. package/dist/{dom-4udEPZaj.mjs → dom-B-v8Gw6T.mjs} +122 -92
  66. package/dist/{dom-C1mr-TA7.js → dom-BSsI9OPC.js} +218 -187
  67. package/dist/dom.d.ts +1 -1
  68. package/dist/dom.js +59 -56
  69. package/dist/dom.mjs +35 -33
  70. package/dist/html/attrs.d.ts +2 -0
  71. package/dist/html/writer.d.ts +5 -11
  72. package/dist/html.d.ts +1 -1
  73. package/dist/html.js +367 -327
  74. package/dist/html.mjs +366 -327
  75. package/dist/translator/index.js +866 -748
  76. package/dist/translator/util/binding-has-prop.d.ts +2 -0
  77. package/dist/translator/util/entry-builder.d.ts +2 -0
  78. package/dist/translator/util/generate-uid.d.ts +5 -0
  79. package/dist/translator/util/optional.d.ts +1 -3
  80. package/dist/translator/util/references.d.ts +6 -2
  81. package/dist/translator/util/runtime.d.ts +3 -3
  82. package/dist/translator/util/sections.d.ts +8 -2
  83. package/dist/translator/util/serialize-reasons.d.ts +3 -1
  84. package/dist/translator/util/setup-work.d.ts +5 -0
  85. package/dist/translator/util/signals.d.ts +5 -7
  86. package/dist/translator/util/translate-attrs.d.ts +2 -1
  87. package/dist/translator/visitors/tag/native-tag.d.ts +1 -0
  88. package/package.json +3 -3
  89. package/tags-html.d.ts +4 -3
  90. 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;
@@ -216,7 +218,7 @@ function _hoist_read_error() {
216
218
  throw new Error("Hoisted values can only be read in scripts and event handlers.");
217
219
  }
218
220
  function _assert_hoist(value) {
219
- if (typeof value !== "function") throw new Error(`Hoisted values must be functions, received type "${typeof value}".`);
221
+ if (value !== void 0 && typeof value !== "function") throw new Error(`Hoisted values must be functions, received type "${typeof value}".`);
220
222
  }
221
223
  function assertExclusiveAttrs(attrs, onError = throwErr) {
222
224
  if (attrs) {
@@ -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"],
@@ -557,7 +567,7 @@ var State$1 = class {
557
567
  strs = /* @__PURE__ */ new Map();
558
568
  refs = /* @__PURE__ */ new WeakMap();
559
569
  pendingAssignments = /* @__PURE__ */ new Set();
560
- boundary = void 0;
570
+ boundary;
561
571
  channel = void 0;
562
572
  channelDeps = null;
563
573
  mutated = [];
@@ -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);
@@ -1034,7 +1048,6 @@ function writeRegExp(state, val) {
1034
1048
  }
1035
1049
  function writePromise(state, val, ref) {
1036
1050
  const { boundary, channel } = state;
1037
- if (!boundary) return false;
1038
1051
  const pId = nextRefAccess(state);
1039
1052
  const handle = newAsyncHandle(state, ref, pId);
1040
1053
  state.buf.push("(p=>p=new Promise((f,r)=>" + pId + "={f,r(e){p.catch(_=>0);r(e)}}))()");
@@ -1181,16 +1194,16 @@ function writeArrayBuffer(state, val) {
1181
1194
  state.buf.push(result);
1182
1195
  return true;
1183
1196
  }
1184
- function writeTypedArray(state, val, ref) {
1197
+ function writeTypedArray(state, val, name, ref) {
1185
1198
  if (val.byteOffset || val.byteLength < val.buffer.byteLength || state.refs.has(val.buffer)) {
1186
1199
  if (!canWriteBuffer(state, val.buffer, ref)) return false;
1187
1200
  const needsLength = val.byteOffset + val.byteLength < val.buffer.byteLength;
1188
- state.buf.push("new " + val.constructor.name + "(");
1201
+ state.buf.push("new " + name + "(");
1189
1202
  writeProp(state, val.buffer, ref, "buffer");
1190
1203
  state.buf.push((val.byteOffset || needsLength ? "," + val.byteOffset + (needsLength ? "," + val.length : "") : "") + ")");
1191
1204
  } else {
1192
1205
  state.refs.set(val.buffer, new Reference(ref, "buffer", state.flushId, null));
1193
- 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)) + ")"));
1194
1207
  }
1195
1208
  return true;
1196
1209
  }
@@ -1202,8 +1215,8 @@ function writeWeakMap(state) {
1202
1215
  state.buf.push("new WeakMap");
1203
1216
  return true;
1204
1217
  }
1205
- function writeError(state, val, ref) {
1206
- 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);
1207
1220
  if (val.cause !== void 0) {
1208
1221
  const pos = state.buf.push(result + ",{cause:") - 1;
1209
1222
  if (writeProp(state, val.cause, ref, "cause")) state.buf.push("})");
@@ -1372,8 +1385,11 @@ function writeTemporal(state, val, name) {
1372
1385
  return true;
1373
1386
  }
1374
1387
  function writeReadableStream(state, val, ref) {
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
- if (!boundary || val.locked) return false;
1377
1393
  const reader = val.getReader();
1378
1394
  const iterId = nextRefAccess(state);
1379
1395
  const handle = newAsyncHandle(state, ref, iterId);
@@ -1444,7 +1460,6 @@ function writeAsyncGenerator(state, iter, ref) {
1444
1460
  return true;
1445
1461
  }
1446
1462
  const { boundary, channel } = state;
1447
- if (!boundary) return false;
1448
1463
  const iterId = nextRefAccess(state);
1449
1464
  const handle = newAsyncHandle(state, ref, iterId);
1450
1465
  const onFulfilled = ({ value, done }) => {
@@ -1506,8 +1521,8 @@ function writeAsyncCall(state, boundary, handle, method, value, channel, valueId
1506
1521
  });
1507
1522
  boundary.endAsync();
1508
1523
  }
1509
- function throwUnserializable(state, cause, ref = null, accessor = "") {
1510
- if (cause !== void 0 && state.boundary?.abort) {
1524
+ function throwUnserializable(state, cause, ref = null, accessor = "", hint = "Values referenced in the browser must be serializable.") {
1525
+ if (cause !== void 0) {
1511
1526
  let message = "Unable to serialize";
1512
1527
  let access = "";
1513
1528
  while (ref) {
@@ -1519,10 +1534,12 @@ function throwUnserializable(state, cause, ref = null, accessor = "") {
1519
1534
  const slotName = debug.slots?.[rawAccessor];
1520
1535
  let debugAccess = varLoc ? rawAccessor : void 0;
1521
1536
  let debugLoc = debug.loc;
1522
- if (varLoc) if (Array.isArray(varLoc)) {
1523
- debugAccess = varLoc[0];
1524
- if (varLoc[1]) debugLoc = varLoc[1];
1525
- } 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
+ }
1526
1543
  let display;
1527
1544
  if (debugAccess !== void 0) display = slotName && debugAccess.startsWith("...") ? `\`${slotName}\` from \`${debugAccess}\`` : JSON.stringify(debugAccess);
1528
1545
  else display = describeAccessor(rawAccessor, slotName) ?? JSON.stringify(rawAccessor);
@@ -1536,10 +1553,10 @@ function throwUnserializable(state, cause, ref = null, accessor = "") {
1536
1553
  if (accessor) access = toAccess(accessor) + access;
1537
1554
  if (access[0] === ".") access = access.slice(1);
1538
1555
  if (access) message += ` (reading ${access})`;
1539
- message += ". Values referenced in the browser must be serializable.";
1556
+ message += ". " + hint;
1540
1557
  const err = new TypeError(message, { cause });
1541
1558
  err.stack = void 0;
1542
- state.boundary.abort(err);
1559
+ abortRender(state.boundary, err);
1543
1560
  }
1544
1561
  }
1545
1562
  const accessorPrefixDescriptions = {
@@ -1557,7 +1574,8 @@ const accessorPrefixDescriptions = {
1557
1574
  KeyedScopes: "the keyed scopes",
1558
1575
  Lifecycle: "the lifecycle handlers",
1559
1576
  Promise: "the pending promise",
1560
- TagVariableChange: "the tag variable change handler"
1577
+ TagVariableChange: "the tag variable change handler",
1578
+ TryBranch: "the try branch"
1561
1579
  };
1562
1580
  function describeAccessor(accessor, slotName) {
1563
1581
  const sep = accessor.indexOf(":");
@@ -1590,11 +1608,13 @@ function trackChannel(state, ref) {
1590
1608
  return false;
1591
1609
  }
1592
1610
  function abortUnreachableChannel(state, val) {
1593
- if (state.boundary?.abort) {
1594
- 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 });
1595
- err.stack = void 0;
1596
- state.boundary.abort(err);
1597
- }
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 });
1612
+ err.stack = void 0;
1613
+ abortRender(state.boundary, err);
1614
+ }
1615
+ function abortRender(boundary, err) {
1616
+ while (boundary.parent) boundary = boundary.parent;
1617
+ boundary.abort(err);
1598
1618
  }
1599
1619
  function isCircular(parent, ref) {
1600
1620
  let cur = parent;
@@ -1609,16 +1629,17 @@ function toObjectKey(name) {
1609
1629
  if (name === "__proto__") return "[\"__proto__\"]";
1610
1630
  const len = name.length;
1611
1631
  const c0 = name.charCodeAt(0);
1612
- if (c0 >= 48 && c0 <= 57) if (c0 === 48) {
1613
- if (len !== 1) return quote(name, 1);
1614
- } else {
1615
- for (let i = 1; i < len; i++) {
1616
- const c = name.charCodeAt(i);
1617
- 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);
1618
1641
  }
1619
- if (len > 15 && "" + +name !== name) return quote(name, 0);
1620
- }
1621
- 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++) {
1622
1643
  const c = name.charCodeAt(i);
1623
1644
  if (!(c >= 97 && c <= 122 || c >= 65 && c <= 90 || c >= 48 && c <= 57 || c === 95 || c === 36)) return quote(name, i);
1624
1645
  }
@@ -1743,7 +1764,7 @@ function nextId(state) {
1743
1764
  let n = state.ids++;
1744
1765
  let r = c[n % 53];
1745
1766
  for (n = n / 53 | 0; n; n >>>= 6) r += c[n & 63];
1746
- return r;
1767
+ return r === "name" ? nextId(state) : r;
1747
1768
  }
1748
1769
  function hasSymbolIterator(value) {
1749
1770
  return Symbol.iterator in value;
@@ -1794,127 +1815,313 @@ function patchIteratorNext(proto) {
1794
1815
  proto.next[kTouchedIterator] = true;
1795
1816
  }
1796
1817
  //#endregion
1797
- //#region src/common/for.ts
1798
- function forIn(obj, cb) {
1799
- 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));
1800
1821
  }
1801
- function forOf(list, cb) {
1802
- assertValidList(list);
1803
- if (list) {
1804
- let i = 0;
1805
- 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";
1806
1834
  }
1835
+ return valueAttr;
1807
1836
  }
1808
- function forTo(to, from, step, cb) {
1809
- assertValidRangeBound("to", to);
1810
- assertValidRangeStart("from", from);
1811
- assertValidRangeStart("step", step);
1812
- const start = from || 0;
1813
- const delta = step || 1;
1814
- 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
+ }
1815
1849
  }
1816
- function forUntil(until, from, step, cb) {
1817
- assertValidRangeBound("until", until);
1818
- assertValidRangeStart("from", from);
1819
- assertValidRangeStart("step", step);
1820
- const start = from || 0;
1821
- const delta = step || 1;
1822
- 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();
1823
1853
  }
1824
- //#endregion
1825
- //#region src/common/opt.ts
1826
- function forEach(opt, cb) {
1827
- if (opt) if (Array.isArray(opt)) for (const item of opt) cb(item);
1828
- 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);
1829
1857
  }
1830
- function push(opt, item) {
1831
- 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);
1832
1860
  }
1833
- function concat(opt, other) {
1834
- if (!opt) return other;
1835
- if (!other) return opt;
1836
- if (Array.isArray(opt)) {
1837
- if (Array.isArray(other)) for (const item of other) opt.push(item);
1838
- else opt.push(other);
1839
- 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;
1840
1887
  }
1841
- return Array.isArray(other) ? [opt, ...other] : [opt, other];
1842
1888
  }
1843
- //#endregion
1844
- //#region src/html/for.ts
1845
- function forOfBy(by, item, index) {
1846
- 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" : "";
1847
1893
  }
1848
- function forInBy(by, name, value) {
1849
- return by ? by(name, value) : name;
1894
+ function _attr_nonce() {
1895
+ return getChunk().boundary.state.nonceAttr;
1850
1896
  }
1851
- function forStepBy(by, index) {
1852
- return by ? by(index) : index;
1897
+ function _style_html(decls) {
1898
+ const id = _id();
1899
+ return `<style${_attr_nonce()} class=${id}>.${id}~*{${decls}}</style>`;
1853
1900
  }
1854
- //#endregion
1855
- //#region src/html/inlined-runtimes.debug.ts
1856
- const WALKER_RUNTIME_CODE = `((runtimeId) => (self[runtimeId] ||= (
1857
- renderId,
1858
- prefix = runtimeId + renderId,
1859
- prefixLen = prefix.length,
1860
- lookup = {},
1861
- visits = [],
1862
- doc = document,
1863
- walker = doc.createTreeWalker(
1864
- doc,
1865
- 129 /* NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_ELEMENT */,
1866
- ),
1867
- ) =>
1868
- doc = (self[runtimeId][renderId] = {
1869
- i: prefix,
1870
- d: doc,
1871
- l: lookup,
1872
- v: visits,
1873
- x() {},
1874
- w(node, op, id) {
1875
- while ((node = walker.nextNode())) {
1876
- // Only reorder markers ("#", "!") are ever looked up, so only they are
1877
- // kept: the lookup lives as long as the page, and every node marker
1878
- // would otherwise stay referenced in it after resume consumed it.
1879
- doc.x(
1880
- (op =
1881
- (op = node.data) &&
1882
- !op.indexOf(prefix) &&
1883
- ((id = op.slice(prefixLen + 1)),
1884
- (op = op[prefixLen]) > "#" || (lookup[id] = node),
1885
- op)),
1886
- id,
1887
- node,
1888
- );
1889
-
1890
- if (op > "#") {
1891
- visits.push(node);
1892
- }
1893
- }
1894
- },
1895
- })
1896
- , self[runtimeId]))`;
1897
- const REORDER_RUNTIME_CODE = `((runtime) => {
1898
- if (runtime.j) return;
1899
- let onNextSibling,
1900
- placeholder,
1901
- nextSibling,
1902
- placeholders = runtime.p = {},
1903
- replace = (id, container) => runtime.l[id].replaceWith(...container.childNodes);
1904
- runtime.j = {};
1905
- runtime.x = (op, id, node, placeholderRoot, placeholderCb) => {
1906
- if (node == nextSibling) {
1907
- onNextSibling();
1908
- }
1909
-
1910
- if (op == "#") {
1911
- (placeholders[id] = placeholder).i++;
1912
- } else if (op == "!") {
1913
- if (runtime.l[id] && placeholders[id]) {
1914
- nextSibling = node.nextSibling;
1915
- onNextSibling = () => placeholders[id].c();
1916
- }
1917
- } else if (node.tagName == "T" && (id = node.getAttribute(runtime.i))) {
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))) {
1918
2125
  nextSibling = node.nextSibling;
1919
2126
  onNextSibling = () => {
1920
2127
  node.remove();
@@ -2010,6 +2217,12 @@ function withContext(key, value, cb, cbValue) {
2010
2217
  ctx[key] = prev;
2011
2218
  }
2012
2219
  }
2220
+ function captureContext(chunk) {
2221
+ if (chunk.context?.[kPendingContexts]) chunk.context = {
2222
+ ...chunk.context,
2223
+ [kPendingContexts]: 0
2224
+ };
2225
+ }
2013
2226
  const kBranchId = Symbol("Branch Id");
2014
2227
  const kIsAsync = Symbol("Is Async");
2015
2228
  function isInResumedBranch() {
@@ -2018,8 +2231,8 @@ function isInResumedBranch() {
2018
2231
  function withBranchId(branchId, cb, cbValue) {
2019
2232
  return withContext(kBranchId, branchId, cb, cbValue);
2020
2233
  }
2021
- function withIsAsync(cb, value) {
2022
- return withContext(kIsAsync, true, cb, value);
2234
+ function withIsAsync(async, cb, value) {
2235
+ return withContext(kIsAsync, async, cb, value);
2023
2236
  }
2024
2237
  function _html(html) {
2025
2238
  $chunk.writeHTML(html);
@@ -2080,8 +2293,10 @@ function _attr_content(nodeAccessor, scopeId, content, serializeReason) {
2080
2293
  const shouldResume = serializeReason !== 0;
2081
2294
  const render = normalizeServerRender(content);
2082
2295
  const branchId = _peek_scope_id();
2083
- if (render) if (shouldResume) withBranchId(branchId, render);
2084
- else render();
2296
+ if (render) {
2297
+ if (shouldResume) withBranchId(branchId, render);
2298
+ else render();
2299
+ }
2085
2300
  if (_peek_scope_id() !== branchId) {
2086
2301
  if (shouldResume) writeScope(scopeId, {
2087
2302
  [BranchScopes + nodeAccessor]: writeScope(branchId, {}),
@@ -2091,8 +2306,10 @@ function _attr_content(nodeAccessor, scopeId, content, serializeReason) {
2091
2306
  }
2092
2307
  function normalizeServerRender(value) {
2093
2308
  const renderer = normalizeDynamicRenderer(value);
2094
- if (renderer) if (typeof renderer === "function") return renderer;
2095
- 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
+ }
2096
2313
  }
2097
2314
  function _var(parentScopeId, scopeOffsetAccessor, childScopeId, registryId, nodeAccessor) {
2098
2315
  writeScopePassive(parentScopeId, { [scopeOffsetAccessor]: _scope_id() });
@@ -2169,10 +2386,12 @@ function forBranches(by, iterate, scopeId, accessor, serializeBranch, serializeM
2169
2386
  let loopScopes;
2170
2387
  iterate((itemKey, sameAsIndex, render) => {
2171
2388
  const branchId = _peek_scope_id();
2172
- if (resumeMarker) if (singleNode) flushBranchIds = " " + branchId + flushBranchIds;
2173
- else {
2174
- $chunk.writeHTML(state.mark("[", flushBranchIds));
2175
- flushBranchIds = branchId + "";
2389
+ if (resumeMarker) {
2390
+ if (singleNode) flushBranchIds = " " + branchId + flushBranchIds;
2391
+ else {
2392
+ $chunk.writeHTML(state.mark("[", flushBranchIds));
2393
+ flushBranchIds = branchId + "";
2394
+ }
2176
2395
  }
2177
2396
  withBranchId(branchId, () => {
2178
2397
  render();
@@ -2208,12 +2427,13 @@ function applyBranchStart(chunk, beforeBranch, rendered) {
2208
2427
  }
2209
2428
  function writeBranchEnd(scopeId, accessor, serializeStateful, serializeMarker, parentEndTag, singleNode, branchIds) {
2210
2429
  const endTag = parentEndTag || "";
2211
- if (serializeMarker !== 0) if (!parentEndTag || serializeStateful !== 0) {
2212
- const { state } = $chunk.boundary;
2213
- const mark = singleNode ? state.mark(parentEndTag ? "}" : "|", scopeId + " " + accessor + (branchIds || "")) : state.mark(parentEndTag ? ")" : "]", scopeId + " " + accessor + (branchIds || ""));
2214
- $chunk.writeHTML(mark + endTag);
2215
- } else $chunk.writeHTML(endTag + _el_resume(scopeId, accessor));
2216
- 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);
2217
2437
  }
2218
2438
  let writeScope = (scopeId, partialScope) => {
2219
2439
  const { state } = $chunk.boundary;
@@ -2221,7 +2441,7 @@ let writeScope = (scopeId, partialScope) => {
2221
2441
  const scope = scopeWithId(state, scopeId);
2222
2442
  const pending = target.writeScopes[scopeId];
2223
2443
  state.needsMainRuntime = true;
2224
- countResumeWrite($chunk.boundary);
2444
+ countResumeWrite($chunk);
2225
2445
  Object.assign(scope, partialScope);
2226
2446
  if (pending && pending !== partialScope) Object.assign(pending, partialScope);
2227
2447
  else target.writeScopes[scopeId] = partialScope;
@@ -2305,12 +2525,10 @@ function _await(scopeId, accessor, promise, content, serializeMarker) {
2305
2525
  }
2306
2526
  const chunk = $chunk;
2307
2527
  const { boundary } = chunk;
2308
- 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);
2309
2530
  chunk.async = true;
2310
- if (chunk.context?.[kPendingContexts]) chunk.context = {
2311
- ...chunk.context,
2312
- [kPendingContexts]: 0
2313
- };
2531
+ captureContext(chunk);
2314
2532
  boundary.startAsync();
2315
2533
  promise.then((value) => {
2316
2534
  if (chunk.async) {
@@ -2320,9 +2538,16 @@ function _await(scopeId, accessor, promise, content, serializeMarker) {
2320
2538
  if (resumeMarker) {
2321
2539
  const branchId = _peek_scope_id();
2322
2540
  $chunk.writeHTML($chunk.boundary.state.mark("[", ""));
2323
- withBranchId(branchId, () => withIsAsync(content, value));
2541
+ withBranchId(branchId, () => withIsAsync({ parent: getAsyncContent(chunk) }, content, value));
2324
2542
  $chunk.writeHTML($chunk.boundary.state.mark("]", scopeId + " " + accessor + " " + branchId));
2325
- } 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
+ }
2326
2551
  });
2327
2552
  boundary.endAsync();
2328
2553
  }
@@ -2332,9 +2557,7 @@ function _await(scopeId, accessor, promise, content, serializeMarker) {
2332
2557
  boundary.abort(err);
2333
2558
  });
2334
2559
  }
2335
- function _try(scopeId, accessor, content, input) {
2336
- const catchContent = input.catch ? normalizeDynamicRenderer(input.catch) || 0 : void 0;
2337
- const placeholderContent = normalizeDynamicRenderer(input.placeholder);
2560
+ function _try(scopeId, accessor, content, placeholderContent, catchContent, placeholderId, catchId) {
2338
2561
  const placeholderBranchId = placeholderContent ? _scope_id() : 0;
2339
2562
  const branchId = _peek_scope_id();
2340
2563
  const chunk = $chunk;
@@ -2342,13 +2565,12 @@ function _try(scopeId, accessor, content, input) {
2342
2565
  const { state } = boundary;
2343
2566
  const { resumeWrites } = boundary;
2344
2567
  const beforeBranch = deferBranchStart(chunk);
2345
- let renderersAtSettle = false;
2346
- if (catchContent !== void 0 || placeholderContent) renderersAtSettle = tryBoundary(placeholderContent ? () => tryPlaceholder(content, placeholderContent, branchId, scopeId, placeholderBranchId) : content, catchContent, placeholderContent, branchId);
2347
- 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);
2348
2570
  const rendered = chunk !== $chunk || boundary.resumeWrites !== resumeWrites;
2349
2571
  applyBranchStart(chunk, beforeBranch, rendered);
2350
2572
  if (!rendered) return;
2351
- if (!renderersAtSettle) writeTryRenderers(branchId, catchContent, placeholderContent);
2573
+ if (!renderersWritten) renderers();
2352
2574
  $chunk.writeHTML(state.mark("]", scopeId + " " + accessor + " " + branchId));
2353
2575
  }
2354
2576
  function tryPlaceholder(content, placeholder, branchId, scopeId, placeholderBranchId) {
@@ -2360,6 +2582,7 @@ function tryPlaceholder(content, placeholder, branchId, scopeId, placeholderBran
2360
2582
  return;
2361
2583
  }
2362
2584
  chunk.next = $chunk = chunk.fork(boundary, chunk.next);
2585
+ captureContext(chunk);
2363
2586
  chunk.placeholder = {
2364
2587
  body,
2365
2588
  render: placeholder,
@@ -2368,17 +2591,17 @@ function tryPlaceholder(content, placeholder, branchId, scopeId, placeholderBran
2368
2591
  placeholderBranchId
2369
2592
  };
2370
2593
  }
2371
- function tryBoundary(content, catchContent, placeholderContent, branchId) {
2594
+ function tryBoundary(content, catchContent, branchId, renderers) {
2372
2595
  const chunk = $chunk;
2373
2596
  const { boundary } = chunk;
2374
2597
  const { state } = boundary;
2375
2598
  const catchBoundary = new Boundary(state, boundary.signal, boundary);
2376
2599
  const body = chunk.fork(catchBoundary, null);
2377
- const bodyEnd = withBranchId(branchId, () => body.render(content));
2600
+ const bodyEnd = body.render(() => withBranchId(branchId, content));
2378
2601
  if (catchBoundary.signal.aborted) {
2379
- if (catchContent === void 0) boundary.abort(catchBoundary.signal.reason);
2380
- else if (catchContent) catchContent(catchBoundary.signal.reason);
2381
- return false;
2602
+ if (catchContent) catchContent(catchBoundary.signal.reason);
2603
+ else boundary.abort(catchBoundary.signal.reason);
2604
+ return true;
2382
2605
  }
2383
2606
  if (body === bodyEnd) {
2384
2607
  chunk.append(body);
@@ -2388,11 +2611,12 @@ function tryBoundary(content, catchContent, placeholderContent, branchId) {
2388
2611
  const bodyNext = bodyEnd.next = $chunk = chunk.fork(boundary, chunk.next);
2389
2612
  chunk.next = body;
2390
2613
  boundary.startAsync();
2391
- const reorderId = catchContent === void 0 ? "" : state.nextReorderId();
2614
+ const reorderId = catchContent ? state.nextReorderId() : "";
2392
2615
  const endMarker = reorderId && state.mark("!", reorderId);
2393
2616
  if (reorderId) {
2394
2617
  chunk.writeHTML(state.mark("!^", reorderId));
2395
2618
  bodyEnd.writeHTML(endMarker);
2619
+ captureContext(chunk);
2396
2620
  }
2397
2621
  catchBoundary.onNext = () => {
2398
2622
  if (boundary.signal.aborted) return;
@@ -2420,13 +2644,12 @@ function tryBoundary(content, catchContent, placeholderContent, branchId) {
2420
2644
  } while (cur !== bodyNext);
2421
2645
  }
2422
2646
  const catchChunk = chunk.fork(boundary, null);
2423
- const { resumeWrites } = boundary;
2424
2647
  catchChunk.reorderId = reorderId;
2425
- 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);
2426
2649
  state.reorder(catchChunk);
2427
2650
  boundary.endAsync();
2428
2651
  } else if (!catchBoundary.count) {
2429
- if (renderersAtSettle && catchBoundary.resumeWrites) bodyEnd.render(() => writeTryRenderers(branchId, catchContent, placeholderContent));
2652
+ if (renderersAtSettle && catchBoundary.resumeWrites) bodyEnd.render(renderers);
2430
2653
  boundary.endAsync();
2431
2654
  } else boundary.onNext();
2432
2655
  };
@@ -2439,8 +2662,15 @@ function writeTryRenderers(branchId, catchContent, placeholderContent) {
2439
2662
  });
2440
2663
  }
2441
2664
  const NOOP$2 = () => {};
2442
- function countResumeWrite(boundary) {
2443
- 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];
2444
2674
  }
2445
2675
  var State = class {
2446
2676
  tagId = 1;
@@ -2540,10 +2770,13 @@ var Boundary = class extends AbortController {
2540
2770
  this.state = new State(this.state.$global);
2541
2771
  this.onNext();
2542
2772
  });
2543
- if (signal) if (signal.aborted) this.abort(signal.reason);
2544
- else signal.addEventListener("abort", () => {
2545
- this.abort(signal.reason);
2546
- });
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);
2547
2780
  }
2548
2781
  flush() {
2549
2782
  if (!this.signal.aborted) flushSerializer(this, this.state);
@@ -2553,7 +2786,8 @@ var Boundary = class extends AbortController {
2553
2786
  if (!this.signal.aborted) this.count++;
2554
2787
  }
2555
2788
  endAsync() {
2556
- 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.");
2557
2791
  this.count--;
2558
2792
  this.onNext();
2559
2793
  }
@@ -2587,7 +2821,7 @@ var Chunk = class Chunk {
2587
2821
  this.html += html;
2588
2822
  }
2589
2823
  writeEffect(scopeId, registryId) {
2590
- countResumeWrite(this.boundary);
2824
+ countResumeWrite(this);
2591
2825
  if (this.lastEffect === registryId) this.effects += " " + scopeId;
2592
2826
  else {
2593
2827
  this.lastEffect = registryId;
@@ -2622,6 +2856,7 @@ var Chunk = class Chunk {
2622
2856
  flushPlaceholder() {
2623
2857
  const { placeholder } = this;
2624
2858
  if (placeholder) {
2859
+ this.placeholder = null;
2625
2860
  const body = placeholder.body.consume();
2626
2861
  if (body.async) {
2627
2862
  const { state } = this.boundary;
@@ -2630,11 +2865,11 @@ var Chunk = class Chunk {
2630
2865
  this.writeHTML(state.mark("!^", reorderId));
2631
2866
  const { effects } = this;
2632
2867
  const beforeBranch = deferBranchStart(this);
2633
- const after = this.render(() => withBranchId(placeholderBranchId, placeholder.render));
2634
- 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;
2635
2871
  applyBranchStart(this, beforeBranch, stateful);
2636
- if (after !== this) this.boundary.abort(/* @__PURE__ */ new Error("An @placeholder cannot contain async content."));
2637
- else if (stateful) {
2872
+ if (stateful) {
2638
2873
  this.render(() => writeScope(branchId, { [PlaceholderBranch]: scopeWithId(state, placeholderBranchId) }));
2639
2874
  this.writeHTML(state.mark("]", scopeId + " " + (PlaceholderBranch + branchId) + " " + placeholderBranchId));
2640
2875
  body.writeEffect(branchId, PLACEHOLDER_DISMISS_REGISTER_ID);
@@ -2645,7 +2880,6 @@ var Chunk = class Chunk {
2645
2880
  body.next = this.next;
2646
2881
  this.next = body;
2647
2882
  }
2648
- this.placeholder = null;
2649
2883
  }
2650
2884
  }
2651
2885
  consume() {
@@ -2692,12 +2926,12 @@ var Chunk = class Chunk {
2692
2926
  $chunk = prev;
2693
2927
  }
2694
2928
  }
2695
- flushReadyScripts(reservations, holdEffects) {
2696
- const { boundary, serializeState } = this;
2929
+ flushReadyScripts(boundary, reservations, holdEffects) {
2930
+ const { serializeState } = this;
2697
2931
  const { readyId } = serializeState;
2698
2932
  let scripts = "";
2699
2933
  forEach(this.takeDeferredReady(), (chunk) => {
2700
- scripts = concatScripts(scripts, chunk.flushReadyScripts(reservations, holdEffects));
2934
+ scripts = concatScripts(scripts, chunk.flushReadyScripts(boundary, reservations, holdEffects));
2701
2935
  if (chunk.effects || chunk.deferredReady) this.deferredReady = push(this.deferredReady, chunk);
2702
2936
  });
2703
2937
  if (readyId && !this.async) {
@@ -2722,14 +2956,13 @@ var Chunk = class Chunk {
2722
2956
  }
2723
2957
  return scripts;
2724
2958
  }
2725
- flushScript() {
2726
- const { boundary } = this;
2959
+ flushScript(boundary) {
2727
2960
  const { state } = boundary;
2728
2961
  const { $global, runtimePrefix } = state;
2729
2962
  let needsWalk = state.walkOnNextFlush;
2730
2963
  if (needsWalk) state.walkOnNextFlush = false;
2731
- let readyResumeScripts = this.flushReadyScripts(void 0, this.async);
2732
- 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());) {
2733
2966
  const resumes = state.serializer.stringifyScopes([], boundary, channel);
2734
2967
  const deps = state.serializer.takeChannelDeps();
2735
2968
  state.needsMainRuntime = true;
@@ -2777,7 +3010,7 @@ var Chunk = class Chunk {
2777
3010
  cur.flushPlaceholder();
2778
3011
  cur.deferOwnReady();
2779
3012
  const { next } = cur;
2780
- const readyResumeScripts = cur.flushReadyScripts(readyReservations, this.async);
3013
+ const readyResumeScripts = cur.flushReadyScripts(boundary, readyReservations, this.async);
2781
3014
  this.deferredReady = concat(this.deferredReady, cur.takeDeferredReady());
2782
3015
  cur.consumed = true;
2783
3016
  reorderHTML += cur.html;
@@ -2792,12 +3025,14 @@ var Chunk = class Chunk {
2792
3025
  if (next) cur = next;
2793
3026
  else break;
2794
3027
  }
2795
- if (reorderEffects) if (this.async) {
2796
- this.effects = concatEffects(this.effects, reorderEffects);
2797
- this.lastEffect = "";
2798
- } else {
2799
- needsResumeArray = true;
2800
- 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
+ }
2801
3036
  }
2802
3037
  for (const reservation of readyReservations) reordered = concatScripts(reordered, reservation);
2803
3038
  reordered = concatScripts(reordered, reorderScripts && runtimePrefix + ".j" + toAccess(reorderId) + "=_=>{" + reorderScripts + "}");
@@ -2815,14 +3050,13 @@ var Chunk = class Chunk {
2815
3050
  state.resumes = "";
2816
3051
  return this;
2817
3052
  }
2818
- flushHTML() {
2819
- const { boundary } = this;
3053
+ flushHTML(boundary) {
2820
3054
  const { state } = boundary;
2821
3055
  if (this.needsWalk) {
2822
3056
  this.needsWalk = false;
2823
3057
  state.walkOnNextFlush = true;
2824
3058
  }
2825
- this.flushScript();
3059
+ this.flushScript(boundary);
2826
3060
  const { html, scripts } = this;
2827
3061
  this.html = this.scripts = "";
2828
3062
  return state.flushChunk(html, scripts, boundary.count);
@@ -2898,13 +3132,17 @@ function getFilteredGlobals($global) {
2898
3132
  let filtered = 0;
2899
3133
  if (Array.isArray(serializedGlobals)) for (const key of serializedGlobals) {
2900
3134
  const value = $global[key];
2901
- if (value !== void 0) if (filtered) filtered[key] = value;
2902
- else filtered = { [key]: value };
3135
+ if (value !== void 0) {
3136
+ if (filtered) filtered[key] = value;
3137
+ else filtered = { [key]: value };
3138
+ }
2903
3139
  }
2904
3140
  else for (const key in serializedGlobals) if (serializedGlobals[key]) {
2905
3141
  const value = $global[key];
2906
- if (value !== void 0) if (filtered) filtered[key] = value;
2907
- else filtered = { [key]: value };
3142
+ if (value !== void 0) {
3143
+ if (filtered) filtered[key] = value;
3144
+ else filtered = { [key]: value };
3145
+ }
2908
3146
  }
2909
3147
  return filtered;
2910
3148
  }
@@ -2941,231 +3179,46 @@ function flushTickQueue() {
2941
3179
  }
2942
3180
  }
2943
3181
  //#endregion
2944
- //#region src/html/attrs.ts
2945
- function _attr_class(value) {
2946
- return stringAttr("class", toDelimitedString(value, " ", stringifyClassObject));
2947
- }
2948
- function _attr_style(value) {
2949
- return stringAttr("style", toDelimitedString(value, ";", stringifyStyleObject));
2950
- }
2951
- function _attr_option_value(value) {
2952
- const valueAttr = _attr("value", value);
2953
- const selectedValue = getContext(kSelectedValue);
2954
- if (selectedValue !== void 0 && normalizedValueMatches(selectedValue, value)) {
2955
- {
2956
- const matched = getContext(kSelectedValueMatched);
2957
- if (matched) matched.value = true;
2958
- }
2959
- return valueAttr + " selected";
2960
- }
2961
- return valueAttr;
2962
- }
2963
- const kSelectedValue = Symbol("selectedValue");
2964
- const kSelectedValueMatched = Symbol("selectedValueMatched");
2965
- function _attr_select_value(scopeId, nodeAccessor, value, valueChange, content, serializeType) {
2966
- if (valueChange) writeControlledScope(3, scopeId, nodeAccessor, void 0, valueChange, serializeType);
2967
- if (content) {
2968
- const selectedValue = value ?? "";
2969
- if (valueChange) {
2970
- const matched = { value: false };
2971
- withContext(kSelectedValue, selectedValue, () => withContext(kSelectedValueMatched, matched, content));
2972
- 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);
2973
- } else withContext(kSelectedValue, selectedValue, content);
2974
- }
2975
- }
2976
- function _attr_textarea_value(scopeId, nodeAccessor, value, valueChange, serializeType) {
2977
- if (valueChange) writeControlledScope(2, scopeId, nodeAccessor, void 0, valueChange, serializeType);
2978
- return _textarea_value(value);
2979
- }
2980
- function _textarea_value(value) {
2981
- const escaped = _escape(normalizeStrAttrValue(value));
2982
- return escaped[0] === "\n" ? "\n" + escaped : escaped;
2983
- }
2984
- function _attr_input_value(scopeId, nodeAccessor, value, valueChange, serializeType) {
2985
- if (valueChange) writeControlledScope(2, scopeId, nodeAccessor, void 0, valueChange, serializeType);
2986
- return _attr("value", value);
2987
- }
2988
- function _attr_input_checked(scopeId, nodeAccessor, checked, checkedChange, serializeType) {
2989
- if (checkedChange) writeControlledScope(0, scopeId, nodeAccessor, void 0, checkedChange, serializeType);
2990
- return isNotVoid(checked) ? " checked" : "";
2991
- }
2992
- function _attr_input_checkedValue(scopeId, nodeAccessor, checkedValue, checkedValueChange, value, serializeType) {
2993
- const valueAttr = _attr("value", value);
2994
- if (checkedValueChange) writeControlledScope(1, scopeId, nodeAccessor, getCheckedValueRef(checkedValue), checkedValueChange, serializeType);
2995
- return normalizedValueMatches(checkedValue, value) ? valueAttr + " checked" : valueAttr;
2996
- }
2997
- const checkedValuesRefs = /* @__PURE__ */ new WeakMap();
2998
- function getCheckedValueRef(checkedValue) {
2999
- if (Array.isArray(checkedValue)) {
3000
- let ref = checkedValuesRefs.get(checkedValue);
3001
- if (!ref) {
3002
- ref = [];
3003
- checkedValuesRefs.set(checkedValue, ref);
3004
- }
3005
- return ref;
3006
- }
3007
- }
3008
- function _attr_details_or_dialog_open(scopeId, nodeAccessor, open, openChange, serializeType) {
3009
- const normalizedOpen = isNotVoid(open);
3010
- if (openChange) writeControlledScope(4, scopeId, nodeAccessor, normalizedOpen || void 0, openChange, serializeType);
3011
- return normalizedOpen ? " open" : "";
3012
- }
3013
- function _attr_nonce() {
3014
- return getChunk().boundary.state.nonceAttr;
3015
- }
3016
- function _style_html(decls) {
3017
- const id = _id();
3018
- return `<style${_attr_nonce()} class=${id}>.${id}~*{${decls}}</style>`;
3019
- }
3020
- function _attr(name, value) {
3021
- return isVoid(value) ? "" : nonVoidAttr(name, value);
3022
- }
3023
- function _attr_and(name, value, attr) {
3024
- return value ? attr : _attr(name, value);
3025
- }
3026
- function _attr_or(name, value, attr) {
3027
- return value ? _attr(name, value) : attr;
3028
- }
3029
- function _attr_nullish(name, value, attr) {
3030
- return value == null ? attr : _attr(name, value);
3031
- }
3032
- function _attrs(data, nodeAccessor, scopeId, tagName) {
3033
- let result = "";
3034
- let skip = /[\s/>"'=]/;
3035
- let events;
3036
- switch (data && tagName) {
3037
- case "input":
3038
- assertExclusiveAttrs(data);
3039
- if (data.checkedChange) {
3040
- result += _attr_input_checked(scopeId, nodeAccessor, data.checked, data.checkedChange, 1);
3041
- skip = /^checked(?:Value)?(?:Change)?$|[\s/>"'=]/;
3042
- } else if ("checkedValue" in data || data.checkedValueChange) {
3043
- result += _attr_input_checkedValue(scopeId, nodeAccessor, data.checkedValue, data.checkedValueChange, data.value, 1);
3044
- skip = /^(?:value|checked(?:Value)?)(?:Change)?$|[\s/>"'=]/;
3045
- } else if (data.valueChange) {
3046
- assertNoValueBindingOnCheckable(data.type, data.valueChange);
3047
- result += _attr_input_value(scopeId, nodeAccessor, data.value, data.valueChange, 1);
3048
- skip = /^value(?:Change)?$|[\s/>"'=]/;
3049
- }
3050
- break;
3051
- case "select":
3052
- case "textarea":
3053
- if ("value" in data || data.valueChange) skip = /^value(?:Change)?$|[\s/>"'=]/;
3054
- break;
3055
- case "option":
3056
- if ("value" in data) {
3057
- result += _attr_option_value(data.value);
3058
- skip = /^value$|[\s/>"'=]/;
3059
- }
3060
- break;
3061
- case "details":
3062
- case "dialog":
3063
- if (data.openChange) {
3064
- result += _attr_details_or_dialog_open(scopeId, nodeAccessor, data.open, data.openChange, 1);
3065
- skip = /^open(?:Change)?$|[\s/>"'=]/;
3066
- }
3067
- break;
3068
- }
3069
- for (const name in data) {
3070
- const value = data[name];
3071
- switch (name) {
3072
- case "class":
3073
- result += _attr_class(value);
3074
- break;
3075
- case "style":
3076
- result += _attr_style(value);
3077
- break;
3078
- default:
3079
- if (name) assertValidAttrName(name);
3080
- if (name && !(isVoid(value) || skip.test(name) || name === "content" && tagName !== "meta")) if (isEventHandler(name)) {
3081
- if (!events) {
3082
- events = {};
3083
- writeScope(scopeId, { [EventAttributes + nodeAccessor]: events });
3084
- }
3085
- events[getEventHandlerName(name)] = value;
3086
- } else result += nonVoidAttr(name, value);
3087
- break;
3088
- }
3089
- }
3090
- return result;
3091
- }
3092
- function _attrs_content(data, nodeAccessor, scopeId, tagName, serializeReason) {
3093
- _html(`${_attrs(data, nodeAccessor, scopeId, tagName)}>`);
3094
- _attr_content(nodeAccessor, scopeId, data?.content, serializeReason);
3095
- }
3096
- function _attrs_partial(data, skip, nodeAccessor, scopeId, tagName) {
3097
- const partial = {};
3098
- for (const name in data) {
3099
- const key = isEventHandler(name) ? `on-${getEventHandlerName(name)}` : name;
3100
- if (!skip[key]) partial[key] = data[name];
3101
- }
3102
- assertExclusiveAttrs({
3103
- ...data,
3104
- ...skip
3105
- });
3106
- return _attrs(partial, nodeAccessor, scopeId, tagName);
3107
- }
3108
- function _attrs_partial_content(data, skip, nodeAccessor, scopeId, tagName, serializeReason) {
3109
- _html(`${_attrs_partial(data, skip, nodeAccessor, scopeId, tagName)}>`);
3110
- _attr_content(nodeAccessor, scopeId, data?.content, serializeReason);
3111
- }
3112
- function writeControlledScope(type, scopeId, nodeAccessor, value, valueChange, serializeType) {
3113
- var handlerName = [
3114
- "checkedChange",
3115
- "checkedValueChange",
3116
- "valueChange",
3117
- "valueChange",
3118
- "openChange"
3119
- ][type];
3120
- assertHandlerIsFunction(handlerName, valueChange);
3121
- setDebugSlotName(writeScope(scopeId, serializeType ? {
3122
- [ControlledType + nodeAccessor]: type,
3123
- [ControlledValue + nodeAccessor]: value,
3124
- [ControlledHandler + nodeAccessor]: valueChange
3125
- } : {
3126
- [ControlledValue + nodeAccessor]: value,
3127
- [ControlledHandler + nodeAccessor]: valueChange
3128
- }), ControlledHandler + nodeAccessor, handlerName);
3129
- }
3130
- function stringAttr(name, value) {
3131
- return value && " " + name + attrAssignment(value);
3132
- }
3133
- function nonVoidAttr(name, value) {
3134
- assertValidAttrValue(name, value);
3135
- switch (typeof value) {
3136
- case "string": return " " + name + attrAssignment(value);
3137
- case "boolean": return " " + name;
3138
- case "number": return " " + name + "=" + value;
3139
- }
3140
- return " " + name + attrAssignment(value + "");
3182
+ //#region src/html/content.ts
3183
+ function _to_text(val) {
3184
+ assertValidTextValue(val);
3185
+ return val || val === 0 ? val + "" : "";
3141
3186
  }
3142
- const singleQuoteAttrReplacements = /['\r]|&(?=[#a-zA-Z])/g;
3143
- const doubleQuoteAttrReplacements = /["\r]|&(?=[#a-zA-Z])/g;
3144
- const needsQuotedAttr = /["'>\s]|&[#a-zA-Z]|\/$/g;
3145
- function attrAssignment(value) {
3146
- 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" : "";
3147
3190
  }
3148
- function escapeSingleQuotedAttrValue(value) {
3149
- 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" : "";
3150
3197
  }
3151
- function replaceUnsafeSingleQuoteAttrChar(match) {
3152
- 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" : "";
3153
3203
  }
3154
- function escapeDoubleQuotedAttrValue(value) {
3155
- 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" : "";
3156
3209
  }
3157
- function replaceUnsafeDoubleQuoteAttrChar(match) {
3158
- return match === "\"" ? "&#34;" : match === "\r" ? "&#13;" : "&amp;";
3210
+ function _escape_style_value(val) {
3211
+ assertValidTextValue(val);
3212
+ return val || val === 0 ? escapeStyleValue(val + "") : "";
3159
3213
  }
3160
- function normalizedValueMatches(a, b) {
3161
- const value = normalizeStrAttrValue(b);
3162
- if (Array.isArray(a)) {
3163
- for (const item of a) if (normalizeStrAttrValue(item) === value) return true;
3164
- } else if (normalizeStrAttrValue(a) === value) return true;
3165
- 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;
3166
3218
  }
3167
- function normalizeStrAttrValue(value) {
3168
- return isNotVoid(value) && value !== true ? value + "" : "";
3219
+ function _escape_comment(val) {
3220
+ assertValidTextValue(val);
3221
+ return val ? escapeCommentStr(val + "") : val === 0 ? "0" : "";
3169
3222
  }
3170
3223
  //#endregion
3171
3224
  //#region src/html/dynamic-tag.ts
@@ -3188,7 +3241,7 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, s
3188
3241
  const renderContent = content || normalizeDynamicRenderer(input.content);
3189
3242
  if (renderer === "textarea") {
3190
3243
  if (renderContent) throw new Error("A dynamic tag rendering a `<textarea>` cannot have `content` and must use the `value` attribute instead.");
3191
- _html(_attr_textarea_value(branchId, `#${renderer.toLowerCase()}/0`, input.value, input.valueChange, 1));
3244
+ _html(_attrs_textarea_value(branchId, `#${renderer.toLowerCase()}/0`, input));
3192
3245
  } else {
3193
3246
  if (renderContent && typeof renderContent !== "function") throw new Error(`Body content is not supported for the \`<${renderer}>\` tag.`);
3194
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);
@@ -3424,27 +3477,33 @@ var ServerRendered = class {
3424
3477
  }
3425
3478
  #promise() {
3426
3479
  return this.#cachedPromise ||= new Promise((resolve, reject) => {
3427
- const head = this.#head;
3480
+ let head = this.#head;
3428
3481
  this.#head = null;
3429
3482
  if (!head) return reject(/* @__PURE__ */ new Error(CONSUMED_RESULT_MESSAGE));
3430
3483
  const { boundary } = head;
3484
+ let html = "";
3431
3485
  (boundary.onNext = () => {
3432
3486
  switch (!boundary.count && boundary.flush()) {
3433
3487
  case 2:
3434
- boundary.onNext = NOOP$1;
3488
+ settle(boundary);
3435
3489
  reject(boundary.signal.reason);
3436
3490
  break;
3437
- case 0: {
3438
- const consumed = head.consume();
3439
- if (!boundary.signal.aborted) resolve(consumed.flushHTML());
3440
- break;
3441
- }
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
+ }
3442
3499
  }
3443
3500
  })();
3444
3501
  });
3445
3502
  }
3446
3503
  #read(onWrite, onAbort, onClose) {
3447
3504
  let tick = true;
3505
+ let flushing = false;
3506
+ let again = false;
3448
3507
  let head = this.#head;
3449
3508
  this.#head = null;
3450
3509
  if (!head) {
@@ -3453,24 +3512,39 @@ var ServerRendered = class {
3453
3512
  }
3454
3513
  const { boundary } = head;
3455
3514
  const onNext = boundary.onNext = (write) => {
3456
- const status = boundary.flush();
3457
- if (status === 2) {
3458
- if (!tick) offTick(onNext);
3459
- boundary.onNext = NOOP$1;
3460
- onAbort(boundary.signal.reason);
3461
- } else if (write || status === 0) {
3462
- head = head.consume();
3463
- if (boundary.signal.aborted) return;
3464
- const html = head.flushHTML();
3465
- if (html) onWrite(html);
3466
- if (status === 0) {
3467
- if (!tick) offTick(onNext);
3468
- onClose();
3469
- } else tick = true;
3470
- } else if (tick) {
3471
- tick = false;
3472
- queueTick(onNext);
3515
+ if (flushing) {
3516
+ again = true;
3517
+ return;
3473
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;
3474
3548
  };
3475
3549
  onNext();
3476
3550
  return boundary;
@@ -3480,13 +3554,17 @@ var ServerRendered = class {
3480
3554
  this.#head = null;
3481
3555
  if (!head) throw new Error(CONSUMED_RESULT_MESSAGE);
3482
3556
  const { boundary } = head;
3483
- switch (boundary.flush()) {
3484
- case 2: throw boundary.signal.reason;
3485
- case 1: throw new Error("Cannot consume asynchronous render with 'toString'");
3486
- }
3487
- 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;
3488
3562
  }
3489
3563
  };
3564
+ function settle(boundary) {
3565
+ boundary.onNext = NOOP$1;
3566
+ boundary.state.$global.signal?.removeEventListener("abort", boundary);
3567
+ }
3490
3568
  function NOOP$1() {}
3491
3569
  //#endregion
3492
3570
  //#region src/html/assets.ts
@@ -3507,8 +3585,10 @@ function withPageAssets(template, runtime, assetId, runtimeId) {
3507
3585
  return Object.assign((input) => {
3508
3586
  const g = $global();
3509
3587
  if (runtimeId) {
3510
- if (g.runtimeId !== "M" && g.runtimeId !== runtimeId) throw new Error(`$global.runtimeId ("${g.runtimeId}") conflicts with the runtimeId this entry was compiled with ("${runtimeId}").`);
3511
- 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.`);
3512
3592
  }
3513
3593
  addAsset(g, assetId);
3514
3594
  if (g.__flush__) {
@@ -3616,9 +3696,9 @@ const compat = {
3616
3696
  },
3617
3697
  onFlush(fn) {
3618
3698
  const { flushHTML } = Chunk.prototype;
3619
- Chunk.prototype.flushHTML = function() {
3699
+ Chunk.prototype.flushHTML = function(boundary) {
3620
3700
  fn(this);
3621
- return flushHTML.call(this);
3701
+ return flushHTML.call(this, boundary);
3622
3702
  };
3623
3703
  },
3624
3704
  patchDynamicTag,
@@ -3650,16 +3730,16 @@ const compat = {
3650
3730
  flushScript($global, chunk) {
3651
3731
  chunk ||= this.createChunk($global);
3652
3732
  const { boundary } = chunk;
3653
- switch (boundary.flush()) {
3654
- case 2: throw boundary.signal.reason;
3655
- case 1: throw new Error("Cannot serialize promise across tags/class compat layer.");
3656
- }
3657
- 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;
3658
3737
  },
3659
3738
  render(renderer, willRerender, classAPIOut, component, input, completeChunks, registerChildScope) {
3660
3739
  const state = this.ensureState(classAPIOut.global);
3661
3740
  const boundary = new Boundary(state);
3662
- 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);
3663
3743
  let normalizedInput = input;
3664
3744
  if ("renderBody" in input) {
3665
3745
  normalizedInput = {};
@@ -3764,6 +3844,8 @@ exports._attrs = _attrs;
3764
3844
  exports._attrs_content = _attrs_content;
3765
3845
  exports._attrs_partial = _attrs_partial;
3766
3846
  exports._attrs_partial_content = _attrs_partial_content;
3847
+ exports._attrs_select_value = _attrs_select_value;
3848
+ exports._attrs_textarea_value = _attrs_textarea_value;
3767
3849
  exports._await = _await;
3768
3850
  exports._content = _content;
3769
3851
  exports._content_resume = _content_resume;