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