marko 6.3.34 → 6.3.36

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 (62) hide show
  1. package/cheatsheet.md +2 -2
  2. package/dist/common/constants/accessor-prefix.d.ts +1 -0
  3. package/dist/common/constants/accessor-prefix.debug.d.ts +1 -0
  4. package/dist/common/errors.d.ts +1 -0
  5. package/dist/common/meta.d.ts +1 -0
  6. package/dist/common/types.d.ts +10 -0
  7. package/dist/debug/dom/catch.feat.js +1 -1
  8. package/dist/debug/dom/catch.feat.mjs +1 -1
  9. package/dist/debug/dom/controllable-input.feat.js +1 -1
  10. package/dist/debug/dom/controllable-input.feat.mjs +1 -1
  11. package/dist/debug/dom/controllable-open.feat.js +1 -1
  12. package/dist/debug/dom/controllable-open.feat.mjs +1 -1
  13. package/dist/debug/dom/controllable-select.feat.js +1 -1
  14. package/dist/debug/dom/controllable-select.feat.mjs +1 -1
  15. package/dist/debug/dom/controllable-textarea.feat.js +1 -1
  16. package/dist/debug/dom/controllable-textarea.feat.mjs +1 -1
  17. package/dist/debug/dom/controllable.feat.js +1 -1
  18. package/dist/debug/dom/controllable.feat.mjs +1 -1
  19. package/dist/debug/dom/dynamic-tag-var.feat.js +7 -0
  20. package/dist/debug/dom/dynamic-tag-var.feat.mjs +6 -0
  21. package/dist/debug/{dom-Bj58jt8y.js → dom-BbFAdZEB.js} +54 -17
  22. package/dist/debug/{dom-klf8Ec_o.mjs → dom-ClMc0GK9.mjs} +43 -18
  23. package/dist/debug/dom.js +1 -1
  24. package/dist/debug/dom.mjs +1 -1
  25. package/dist/debug/html.js +94 -25
  26. package/dist/debug/html.mjs +94 -25
  27. package/dist/dom/catch.feat.js +4 -4
  28. package/dist/dom/catch.feat.mjs +1 -1
  29. package/dist/dom/control-flow.d.ts +3 -0
  30. package/dist/dom/controllable-input.feat.js +2 -2
  31. package/dist/dom/controllable-input.feat.mjs +1 -1
  32. package/dist/dom/controllable-open.feat.js +2 -2
  33. package/dist/dom/controllable-open.feat.mjs +1 -1
  34. package/dist/dom/controllable-select.feat.js +2 -2
  35. package/dist/dom/controllable-select.feat.mjs +1 -1
  36. package/dist/dom/controllable-textarea.feat.js +2 -2
  37. package/dist/dom/controllable-textarea.feat.mjs +1 -1
  38. package/dist/dom/controllable.feat.js +2 -2
  39. package/dist/dom/controllable.feat.mjs +1 -1
  40. package/dist/dom/dynamic-tag-var.feat.d.ts +1 -0
  41. package/dist/dom/dynamic-tag-var.feat.js +3 -0
  42. package/dist/dom/dynamic-tag-var.feat.mjs +4 -0
  43. package/dist/dom/signals.d.ts +3 -3
  44. package/dist/{dom-B-XpL2_H.js → dom-59H9kVUF.js} +133 -118
  45. package/dist/{dom-6hBvZW7X.mjs → dom-BKDjlXIl.mjs} +25 -15
  46. package/dist/dom.js +34 -34
  47. package/dist/dom.mjs +1 -1
  48. package/dist/html/dynamic-tag.d.ts +1 -1
  49. package/dist/html/serializer.d.ts +9 -1
  50. package/dist/html/template.d.ts +1 -0
  51. package/dist/html/writer.d.ts +1 -0
  52. package/dist/html.js +19 -13
  53. package/dist/html.mjs +19 -13
  54. package/dist/translator/index.js +287 -101
  55. package/dist/translator/util/references.d.ts +1 -0
  56. package/dist/translator/util/runtime.d.ts +1 -1
  57. package/dist/translator/util/signals.d.ts +2 -0
  58. package/dist/translator/util/translate-var.d.ts +1 -1
  59. package/dist/translator/util/traverse.d.ts +2 -0
  60. package/dist/translator/visitors/export-declaration.d.ts +8 -0
  61. package/package.json +4 -4
  62. package/tags/let.d.marko +3 -4
@@ -126,6 +126,7 @@ var accessor_prefix_debug_exports = /* @__PURE__ */ __exportAll({
126
126
  ControlledValue: () => ControlledValue$1,
127
127
  DynamicHTMLLastChild: () => DynamicHTMLLastChild$1,
128
128
  EventAttributes: () => EventAttributes$1,
129
+ IdFallback: () => IdFallback$1,
129
130
  KeyedScopes: () => KeyedScopes$1,
130
131
  Lifecycle: () => Lifecycle$1,
131
132
  Promise: () => Promise$2,
@@ -141,6 +142,7 @@ const ControlledType$1 = "ControlledType:";
141
142
  const ControlledValue$1 = "ControlledValue:";
142
143
  const DynamicHTMLLastChild$1 = "DynamicHTMLLastChild:";
143
144
  const EventAttributes$1 = "EventAttributes:";
145
+ const IdFallback$1 = "IdFallback:";
144
146
  const KeyedScopes$1 = "KeyedScopes:";
145
147
  const Lifecycle$1 = "Lifecycle:";
146
148
  const Promise$2 = "Promise:";
@@ -203,6 +205,7 @@ const StartNode$1 = "#StartNode";
203
205
  const Subscriptions$1 = "#Subscriptions";
204
206
  const TagVariable$1 = "#TagVariable";
205
207
  const TagVariableChange$2 = "#TagVariableChange";
208
+ const Owner$1 = "owner";
206
209
  //#endregion
207
210
  //#region src/translator/util/evaluate.ts
208
211
  function evaluate(value) {
@@ -374,6 +377,7 @@ const Generator = (function* () {})().constructor;
374
377
  const AsyncGenerator = (async function* () {})().constructor;
375
378
  patchIteratorNext(Generator.prototype);
376
379
  patchIteratorNext(AsyncGenerator.prototype);
380
+ const REGISTRY = /* @__PURE__ */ new WeakMap();
377
381
  (() => {
378
382
  const KNOWN_SYMBOLS = /* @__PURE__ */ new Map();
379
383
  for (const name of Object.getOwnPropertyNames(Symbol)) {
@@ -384,10 +388,88 @@ patchIteratorNext(AsyncGenerator.prototype);
384
388
  })();
385
389
  Array.from, Array.isArray, Array.of, ArrayBuffer.isView, Atomics.add, Atomics.and, Atomics.compareExchange, Atomics.exchange, Atomics.isLockFree, Atomics.load, Atomics.notify, Atomics.or, Atomics.store, Atomics.sub, Atomics.wait, BigInt.asIntN, BigInt.asUintN, BigInt64Array, BigInt64Array.from, BigInt64Array.of, BigUint64Array, BigUint64Array.from, BigUint64Array.of, console.timeStamp, Date.now, Date.parse, Date.UTC, Float32Array.from, Float32Array.of, Float64Array.from, Float64Array.of, globalThis.atob, globalThis.btoa, globalThis.clearImmediate, globalThis.clearInterval, globalThis.clearTimeout, globalThis.crypto?.getRandomValues, globalThis.crypto?.randomUUID, globalThis.fetch, globalThis.performance?.now, globalThis.queueMicrotask, globalThis.setImmediate, globalThis.setInterval, globalThis.setTimeout, globalThis.structuredClone, globalThis.URL, globalThis.URLSearchParams, globalThis.WritableStream, Int16Array.from, Int16Array.of, Int32Array.from, Int32Array.of, Int8Array.from, Int8Array.of, Intl.Collator, Intl.DateTimeFormat, Intl.DisplayNames, Intl.getCanonicalLocales, Intl.ListFormat, Intl.Locale, Intl.NumberFormat, Intl.PluralRules, Intl.RelativeTimeFormat, Intl.Segmenter, Intl.supportedValuesOf, Map.groupBy, Number.isFinite, Number.isInteger, Number.isNaN, Number.isSafeInteger, Number.parseFloat, Number.parseInt, String.fromCharCode, String.fromCodePoint, String.raw, Symbol.for, Uint16Array.from, Uint16Array.of, Uint32Array.from, Uint32Array.of, Uint8Array.from, Uint8Array.of, Uint8ClampedArray.from, Uint8ClampedArray.of;
386
390
  Atomics, globalThis.crypto;
391
+ function register(id, val, scope) {
392
+ REGISTRY.set(val, {
393
+ id,
394
+ scope,
395
+ access: "_._" + toAccess(toObjectKey(id))
396
+ });
397
+ return val;
398
+ }
399
+ function toObjectKey(name) {
400
+ if (name === "") return "\"\"";
401
+ if (name === "__proto__") return "[\"__proto__\"]";
402
+ const len = name.length;
403
+ const c0 = name.charCodeAt(0);
404
+ if (c0 >= 48 && c0 <= 57) if (c0 === 48) {
405
+ if (len !== 1) return quote(name, 1);
406
+ } else {
407
+ for (let i = 1; i < len; i++) {
408
+ const c = name.charCodeAt(i);
409
+ if (c < 48 || c > 57) return quote(name, i);
410
+ }
411
+ if (len > 15 && "" + +name !== name) return quote(name, 0);
412
+ }
413
+ else if (c0 >= 97 && c0 <= 122 || c0 >= 65 && c0 <= 90 || c0 === 95 || c0 === 36) for (let i = 1; i < len; i++) {
414
+ const c = name.charCodeAt(i);
415
+ if (!(c >= 97 && c <= 122 || c >= 65 && c <= 90 || c >= 48 && c <= 57 || c === 95 || c === 36)) return quote(name, i);
416
+ }
417
+ else return quote(name, 0);
418
+ return name;
419
+ }
387
420
  function toAccess(accessor) {
388
421
  const start = accessor[0];
389
422
  return start === "[" ? accessor : start === "\"" || start >= "0" && start <= "9" ? "[" + accessor + "]" : "." + accessor;
390
423
  }
424
+ const unsafeQuoteReg = /["\\<\n\r\u2028\u2029\0\ud800-\udfff]/u;
425
+ function quote(str, startPos) {
426
+ if (!unsafeQuoteReg.test(str)) return "\"" + str + "\"";
427
+ let result = "";
428
+ let lastPos = 0;
429
+ for (let i = startPos; i < str.length; i++) {
430
+ let replacement;
431
+ const code = str.charCodeAt(i);
432
+ switch (code) {
433
+ case 34:
434
+ replacement = "\\\"";
435
+ break;
436
+ case 92:
437
+ replacement = "\\\\";
438
+ break;
439
+ case 60:
440
+ replacement = "\\x3C";
441
+ break;
442
+ case 10:
443
+ replacement = "\\n";
444
+ break;
445
+ case 13:
446
+ replacement = "\\r";
447
+ break;
448
+ case 8232:
449
+ replacement = "\\u2028";
450
+ break;
451
+ case 8233:
452
+ replacement = "\\u2029";
453
+ break;
454
+ case 0:
455
+ replacement = "\\x00";
456
+ break;
457
+ default:
458
+ if (code < 55296 || code > 57343) continue;
459
+ if (code < 56320) {
460
+ const next = str.charCodeAt(i + 1);
461
+ if (next >= 56320 && next <= 57343) {
462
+ i++;
463
+ continue;
464
+ }
465
+ }
466
+ replacement = "\\u" + code.toString(16);
467
+ }
468
+ result += str.slice(lastPos, i) + replacement;
469
+ lastPos = i + 1;
470
+ }
471
+ return "\"" + (lastPos === startPos ? str : result + str.slice(lastPos)) + "\"";
472
+ }
391
473
  function patchIteratorNext(proto) {
392
474
  if (proto.next[kTouchedIterator]) return;
393
475
  const { next } = proto;
@@ -422,16 +504,37 @@ function traverseReplace(container, key, enter, state) {
422
504
  }
423
505
  }
424
506
  function traverseContains(node, check) {
425
- if (node) if (Array.isArray(node)) {
426
- for (const item of node) if (traverseContains(item, check)) return true;
427
- } else {
507
+ return !!traverseFind(node, check);
508
+ }
509
+ function traverseFind(node, check) {
510
+ if (node) if (Array.isArray(node)) for (const item of node) {
511
+ const found = traverseFind(item, check);
512
+ if (found) return found;
513
+ }
514
+ else {
428
515
  switch (check(node)) {
429
- case true: return true;
430
- case skip: return false;
516
+ case true: return node;
517
+ case skip: return;
518
+ }
519
+ for (const key of _marko_compiler.types.VISITOR_KEYS[node.type]) {
520
+ const found = traverseFind(node[key], check);
521
+ if (found) return found;
431
522
  }
432
- for (const key of _marko_compiler.types.VISITOR_KEYS[node.type]) if (traverseContains(node[key], check)) return true;
433
523
  }
434
- return false;
524
+ }
525
+ function traverseFindAwait(node) {
526
+ return traverseFind(node, (child) => {
527
+ switch (child.type) {
528
+ case "ForOfStatement": return child.await;
529
+ case "FunctionDeclaration":
530
+ case "FunctionExpression":
531
+ case "ArrowFunctionExpression":
532
+ case "ClassMethod":
533
+ case "ObjectMethod":
534
+ case "ClassPrivateMethod": return skip;
535
+ case "AwaitExpression": return true;
536
+ }
537
+ });
435
538
  }
436
539
  function traverse(visit, node, parent, grandParent) {
437
540
  if (node) {
@@ -933,6 +1036,7 @@ var accessor_prefix_exports = /* @__PURE__ */ __exportAll({
933
1036
  ControlledValue: () => "G",
934
1037
  DynamicHTMLLastChild: () => "H",
935
1038
  EventAttributes: () => "I",
1039
+ IdFallback: () => "J",
936
1040
  KeyedScopes: () => "O",
937
1041
  Lifecycle: () => "K",
938
1042
  Promise: () => "L",
@@ -1439,7 +1543,7 @@ function getNodeContentType(path, extraMember, contentInfo) {
1439
1543
  case "for":
1440
1544
  case "if":
1441
1545
  case "await":
1442
- case "try":
1546
+ case "try": return 1;
1443
1547
  case "show": return 1;
1444
1548
  default: return null;
1445
1549
  }
@@ -1561,6 +1665,13 @@ function isNativeNode(tag) {
1561
1665
  const [getReferencesByFn] = createProgramState(() => /* @__PURE__ */ new Map());
1562
1666
  const [getReferencesByImportedFn] = createProgramState(() => /* @__PURE__ */ new Map());
1563
1667
  var function_default = { analyze(fn) {
1668
+ const awaitNode = isMarkoAttribute(fn.parentPath) && _marko_compiler.types.isFunctionExpression(fn.node) && !fn.node.async && traverseFindAwait(fn.node.body);
1669
+ if (awaitNode) {
1670
+ const file = (0, _marko_compiler_babel_utils.getFile)();
1671
+ const start = file.code.indexOf("await", awaitNode.start ?? 0);
1672
+ const highlight = start >= 0 && (awaitNode.end == null || start < awaitNode.end) ? (0, _marko_compiler_babel_utils.withLoc)(file, _marko_compiler.types.cloneNode(awaitNode), start, start + 5) : awaitNode;
1673
+ throw fn.hub.buildError(highlight, "Attribute methods containing `await` must be `async`. Add `async` before the method name.");
1674
+ }
1564
1675
  if (fn !== getFnRoot(fn)) return;
1565
1676
  const exprRoot = getExprRoot(fn);
1566
1677
  const markoRoot = getMarkoRoot(exprRoot);
@@ -1924,8 +2035,6 @@ const regexpCharsReg = /[\\^$.*+?()[\]{}|]/g;
1924
2035
  function escapeRegExp(str) {
1925
2036
  return str.replace(regexpCharsReg, "\\$&");
1926
2037
  }
1927
- //#endregion
1928
- //#region src/common/errors.ts
1929
2038
  function assertExclusiveAttrs(attrs, onError = throwErr) {
1930
2039
  if (attrs) {
1931
2040
  let exclusiveAttrs;
@@ -1937,7 +2046,10 @@ function assertExclusiveAttrs(attrs, onError = throwErr) {
1937
2046
  (exclusiveAttrs ||= []).push("checkedValueChange");
1938
2047
  if ("checked" in attrs) exclusiveAttrs.push("checked");
1939
2048
  }
1940
- if (attrs.valueChange) (exclusiveAttrs ||= []).push("valueChange");
2049
+ if (attrs.valueChange) {
2050
+ (exclusiveAttrs ||= []).push("valueChange");
2051
+ if ("checked" in attrs && !exclusiveAttrs.includes("checked")) exclusiveAttrs.push("checked");
2052
+ }
1941
2053
  if (exclusiveAttrs && exclusiveAttrs.length > 1) onError(`The attributes ${joinWithAnd(exclusiveAttrs)} are mutually exclusive.`);
1942
2054
  }
1943
2055
  }
@@ -1957,8 +2069,8 @@ function joinWithAnd(a) {
1957
2069
  function _unescaped(val) {
1958
2070
  return val ? val + "" : val === 0 ? "0" : "";
1959
2071
  }
1960
- const unsafeXMLReg = /[<&]/g;
1961
- const replaceUnsafeXML = (c) => c === "&" ? "&amp;" : "&lt;";
2072
+ const unsafeXMLReg = /[<&\r]/g;
2073
+ const replaceUnsafeXML = (c) => c === "&" ? "&amp;" : c === "<" ? "&lt;" : "&#13;";
1962
2074
  const escapeXMLStr = (str) => unsafeXMLReg.test(str) ? str.replace(unsafeXMLReg, replaceUnsafeXML) : str;
1963
2075
  function _escape(val) {
1964
2076
  return val ? escapeXMLStr(val + "") : val === 0 ? "0" : "";
@@ -1987,6 +2099,9 @@ function getContext(key) {
1987
2099
  function getState() {
1988
2100
  return $chunk.boundary.state;
1989
2101
  }
2102
+ function rendererKey(renderer) {
2103
+ return renderer?.["owner"] === void 0 ? renderer?.["id"] || renderer : renderer["id"] + " " + renderer[Owner$1];
2104
+ }
1990
2105
  function getScopeById(scopeId) {
1991
2106
  if (scopeId !== void 0) return $chunk.boundary.state.scopes.get(scopeId);
1992
2107
  }
@@ -2022,6 +2137,12 @@ function _script(scopeId, registryId) {
2022
2137
  $chunk.boundary.state.needsMainRuntime = true;
2023
2138
  $chunk.writeEffect(scopeId, registryId);
2024
2139
  }
2140
+ function _resume(val, id, scopeId) {
2141
+ return register(id, val, scopeId === void 0 ? void 0 : _scope_with_id(scopeId));
2142
+ }
2143
+ function _el(scopeId, id) {
2144
+ return _resume(() => void 0, id, scopeId);
2145
+ }
2025
2146
  function _resume_branch(scopeId) {
2026
2147
  const branchId = $chunk.context?.[kBranchId];
2027
2148
  if (branchId !== void 0 && branchId !== scopeId) writeScope(scopeId, { [ClosestBranchId$1]: branchId });
@@ -2046,6 +2167,9 @@ let writeScope = (scopeId, partialScope) => {
2046
2167
  target.flushScopes = true;
2047
2168
  return scope;
2048
2169
  };
2170
+ function _scope_with_id(scopeId) {
2171
+ return scopeWithId($chunk.boundary.state, scopeId);
2172
+ }
2049
2173
  function scopeWithId(state, scopeId) {
2050
2174
  const { scopes } = state;
2051
2175
  let scope = scopes.get(scopeId);
@@ -2081,7 +2205,7 @@ function _attr_textarea_value(scopeId, nodeAccessor, value, valueChange, seriali
2081
2205
  }
2082
2206
  function _textarea_value(value) {
2083
2207
  const escaped = _escape(normalizeStrAttrValue(value));
2084
- return escaped[0] === "\n" || escaped[0] === "\r" ? "\n" + escaped : escaped;
2208
+ return escaped[0] === "\n" ? "\n" + escaped : escaped;
2085
2209
  }
2086
2210
  function _attr_input_value(scopeId, nodeAccessor, value, valueChange, serializeType) {
2087
2211
  if (valueChange) writeControlledScope(2, scopeId, nodeAccessor, void 0, valueChange, serializeType);
@@ -2240,10 +2364,10 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, s
2240
2364
  if (!voidElementsReg.test(renderer)) {
2241
2365
  const renderContent = content || normalizeDynamicRenderer(input.content);
2242
2366
  if (renderer === "textarea") _html(_attr_textarea_value(branchId, "a", input.value, input.valueChange, 1));
2243
- else if (renderContent) {
2244
- if (typeof renderContent !== "function") throw new Error(`Body content is not supported for the \`<${renderer}>\` tag.`);
2245
- if (renderer === "select" && ("value" in input || "valueChange" in input)) _attr_select_value(branchId, "a", input.value, input.valueChange, renderContent, 1);
2246
- else _dynamic_tag(branchId, "a", renderContent, void 0, 0, void 0, serializeReason);
2367
+ else {
2368
+ if (renderContent && typeof renderContent !== "function") throw new Error(`Body content is not supported for the \`<${renderer}>\` tag.`);
2369
+ if (renderer === "select" && ("value" in input || "valueChange" in input)) _attr_select_value(branchId, "a", input.value, input.valueChange, renderContent ? () => _dynamic_tag(branchId, "a", renderContent, void 0, 0, void 0, serializeReason) : void 0, 1);
2370
+ else if (renderContent) _dynamic_tag(branchId, "a", renderContent, void 0, 0, void 0, serializeReason);
2247
2371
  }
2248
2372
  _html(`</${renderer}>`);
2249
2373
  }
@@ -2253,6 +2377,7 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, s
2253
2377
  if (shouldResume || needsScript) _html(state.mark("'", scopeId + " " + accessor + " " + branchId));
2254
2378
  };
2255
2379
  renderNative();
2380
+ result = _el(branchId, "e");
2256
2381
  } else {
2257
2382
  const chunk = void 0;
2258
2383
  const beforeBranch = shouldResume ? deferBranchStart(chunk) : void 0;
@@ -2276,7 +2401,7 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, s
2276
2401
  }
2277
2402
  }
2278
2403
  if (rendered) {
2279
- if (shouldResume) writeScope(scopeId, { [ConditionalRenderer$1 + accessor]: renderer?.["id"] || renderer });
2404
+ if (shouldResume) writeScope(scopeId, { [ConditionalRenderer$1 + accessor]: rendererKey(renderer) });
2280
2405
  } else _scope_id();
2281
2406
  return result;
2282
2407
  };
@@ -2324,10 +2449,17 @@ const pureDOMFunctions = /* @__PURE__ */ new Set([
2324
2449
  "_load_media_trigger",
2325
2450
  "_load_race_trigger"
2326
2451
  ]);
2452
+ const [getRuntimeImports] = createProgramState(() => /* @__PURE__ */ new Map());
2327
2453
  function importRuntime(name) {
2328
2454
  if (!isTranslate()) throw new Error(`\`importRuntime(${JSON.stringify(name)})\` may only be called during the translate stage.`);
2329
2455
  const { output } = getMarkoOpts();
2330
- return (0, _marko_compiler_babel_utils.importNamed)((0, _marko_compiler_babel_utils.getFile)(), getRuntimePath(output), name);
2456
+ const imports = getRuntimeImports();
2457
+ let localName = imports.get(name);
2458
+ if (!localName) {
2459
+ localName = (0, _marko_compiler_babel_utils.importNamed)((0, _marko_compiler_babel_utils.getFile)(), getRuntimePath(output), name).name;
2460
+ imports.set(name, localName);
2461
+ }
2462
+ return _marko_compiler.types.identifier(localName);
2331
2463
  }
2332
2464
  function callRuntime(name, ...args) {
2333
2465
  const callExpression = _marko_compiler.types.callExpression(importRuntime(name), filterArguments(args));
@@ -3012,10 +3144,25 @@ function setSectionSerializedValue(section, prop, expression) {
3012
3144
  }
3013
3145
  function setBindingSerializedValue(section, binding, expression, prefix) {
3014
3146
  const reason = getSerializeReason(section, binding, prefix);
3015
- if (reason) getSerializedAccessors(section).set(prefix === void 0 ? getScopeAccessor(binding) : getPrefixedScopeAccessor(binding, prefix), {
3147
+ if (reason) if (prefix === void 0) getSerializedAccessors(section).set(getScopeAccessor(binding), {
3016
3148
  expression,
3017
3149
  reason
3018
3150
  });
3151
+ else {
3152
+ const accessor = getPrefixedScopeAccessor(binding, prefix);
3153
+ getSerializedAccessors(section).set(accessor, {
3154
+ expression,
3155
+ reason
3156
+ });
3157
+ if (!isOptimize() && prefix === getAccessorPrefix().TagVariableChange) {
3158
+ const { root, access } = getDebugScopeAccess(binding);
3159
+ setSectionDebugVar(section, accessor, `${root.name + access}Change`, root.loc);
3160
+ }
3161
+ }
3162
+ }
3163
+ const [getSectionDebugVars] = createSectionState("sectionDebugVars", () => /* @__PURE__ */ new Map());
3164
+ function setSectionDebugVar(section, accessor, name, loc) {
3165
+ if (!isOptimize()) getSectionDebugVars(section).set(accessor, loc ? [name, `${loc.start.line}:${loc.start.column + 1}`] : [name]);
3019
3166
  }
3020
3167
  const nonAnalyzedForceSerializedSection = /* @__PURE__ */ new WeakSet();
3021
3168
  function setSerializedValue(section, key, expression) {
@@ -3354,7 +3501,7 @@ function writeSignals(section) {
3354
3501
  if (signal.build) {
3355
3502
  let value = signal.build();
3356
3503
  const buildsEagerForward = _marko_compiler.types.isIdentifier(value);
3357
- if (!value || !signal.register && _marko_compiler.types.isFunction(value) && _marko_compiler.types.isBlockStatement(value.body) && !value.body.body.length) return;
3504
+ if (!value || !signal.register && !signal.referenced && _marko_compiler.types.isFunction(value) && _marko_compiler.types.isBlockStatement(value.body) && !value.body.body.length) return;
3358
3505
  if (_marko_compiler.types.isCallExpression(value)) replaceNullishAndEmptyFunctionsWith0(value.arguments);
3359
3506
  if (signal.register) value = callRuntime("_var_resume", _marko_compiler.types.stringLiteral(getResumeRegisterId(section, signal.referencedBindings, "var")), value);
3360
3507
  if (buildsEagerForward) forEach(signal.forwards, writeSignal);
@@ -3401,7 +3548,8 @@ function writeRegisteredFns() {
3401
3548
  params = [localsIdentifier];
3402
3549
  if (registeredFn.referencedBindings || registeredFn.referencesScope) prologue = [_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(scopeIdentifier, _marko_compiler.types.memberExpression(localsIdentifier, _marko_compiler.types.identifier(getAccessorProp().Owner)))])];
3403
3550
  } else params = [scopeIdentifier];
3404
- fn = _marko_compiler.types.functionDeclaration(_marko_compiler.types.identifier(registeredFn.id), params, _marko_compiler.types.blockStatement(toReturnedFunction(registeredFn.node, prologue)));
3551
+ const body = toReturnedFunction(registeredFn.node, prologue);
3552
+ fn = _marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(_marko_compiler.types.identifier(registeredFn.id), _marko_compiler.types.arrowFunctionExpression(params, body.length === 1 && body[0].type === "ReturnStatement" ? body[0].argument : _marko_compiler.types.blockStatement(body)))]);
3405
3553
  } else if (registeredFn.node.type === "FunctionDeclaration" && registeredFn.node.id?.name === registeredFn.id) fn = registeredFn.node;
3406
3554
  else fn = _marko_compiler.types.functionDeclaration(_marko_compiler.types.identifier(registeredFn.id), registeredFn.node.params, registeredFn.node.body.type === "BlockStatement" ? registeredFn.node.body : _marko_compiler.types.blockStatement([_marko_compiler.types.returnStatement(registeredFn.node.body)]), registeredFn.node.generator, registeredFn.node.async);
3407
3555
  statements.push(fn);
@@ -3507,6 +3655,7 @@ function writeHTMLResumeStatements(path) {
3507
3655
  const writeScopeArgs = [scopeIdIdentifier, _marko_compiler.types.objectExpression(serializedProperties)];
3508
3656
  if (debug) {
3509
3657
  writeScopeArgs.push(_marko_compiler.types.stringLiteral(path.hub.file.opts.filenameRelative), section.loc && section.loc.start.line != null ? _marko_compiler.types.stringLiteral(`${section.loc.start.line}:${section.loc.start.column + 1}`) : _marko_compiler.types.numericLiteral(0));
3658
+ for (const [accessor, varLoc] of getSectionDebugVars(section)) (debugVars ||= []).push(toObjectProperty(accessor, _marko_compiler.types.valueToNode(varLoc)));
3510
3659
  if (debugVars) writeScopeArgs.push(_marko_compiler.types.objectExpression(debugVars));
3511
3660
  }
3512
3661
  body.push(_marko_compiler.types.expressionStatement(getExprIfSerialized(section, sectionSerializeReason, writeScopeBuilder ? writeScopeBuilder(callRuntime("_scope", ...writeScopeArgs)) : callRuntime("_scope", ...writeScopeArgs))));
@@ -3560,7 +3709,7 @@ function replaceAssignedNode(node) {
3560
3709
  case "UpdateExpression": {
3561
3710
  const { extra } = node.argument;
3562
3711
  if (isAssignedBindingExtra(extra)) {
3563
- let builtAssignment = getBuildAssignment(extra)?.(extra.section, _marko_compiler.types.binaryExpression(node.operator === "++" ? "+" : "-", createScopeReadExpression(extra.assignment, extra.section), _marko_compiler.types.numericLiteral(1)));
3712
+ let builtAssignment = getBuildAssignment(extra)?.(extra.section, _marko_compiler.types.binaryExpression(node.operator === "++" ? "+" : "-", _marko_compiler.types.unaryExpression("+", createScopeReadExpression(extra.assignment, extra.section)), _marko_compiler.types.numericLiteral(1)));
3564
3713
  if (builtAssignment) {
3565
3714
  if (!node.prefix) {
3566
3715
  builtAssignment = _marko_compiler.types.binaryExpression(node.operator === "++" ? "-" : "+", builtAssignment, _marko_compiler.types.numericLiteral(1));
@@ -4753,7 +4902,7 @@ function buildContent(body) {
4753
4902
  }
4754
4903
  if (dynamicSerializeReason) body.node.body.unshift(getScopeReasonDeclaration(bodySection));
4755
4904
  else body.node.body.unshift(_marko_compiler.types.expressionStatement(callRuntime("_scope_reason")));
4756
- return callRuntime(serialized ? "_content_resume" : "_content", _marko_compiler.types.stringLiteral(getResumeRegisterId(bodySection, "content")), _marko_compiler.types.arrowFunctionExpression(body.node.params, _marko_compiler.types.blockStatement(body.node.body)), serialized ? getScopeIdIdentifier(getSection(getAttributeTagParent(body.parentPath))) : void 0);
4905
+ return callRuntime(serialized ? "_content_resume" : "_content", _marko_compiler.types.stringLiteral(getResumeRegisterId(bodySection, "content")), _marko_compiler.types.arrowFunctionExpression(body.node.params, _marko_compiler.types.blockStatement(body.node.body)), getScopeIdIdentifier(getSection(getAttributeTagParent(body.parentPath))));
4757
4906
  } else {
4758
4907
  if (isSectionRendererElided(bodySection)) return;
4759
4908
  return _marko_compiler.types.callExpression(_marko_compiler.types.identifier(bodySection.name), bodySection.referencedLocalClosures ? [scopeIdentifier, _marko_compiler.types.objectExpression(toArray(bodySection.referencedLocalClosures, (ref) => {
@@ -4849,6 +4998,11 @@ var native_tag_default = {
4849
4998
  else if (!_marko_compiler.types.isMarkoText(child)) throw tag.hub.buildError(child, `Only text is allowed inside a \`<${tagName}>\`.`);
4850
4999
  }
4851
5000
  relatedControllable ||= getRelatedControllable(tagName, seen);
5001
+ const valueChangeEval = tagName === "input" && seen.valueChange ? evaluate(seen.valueChange.value) : void 0;
5002
+ if (valueChangeEval && !(valueChangeEval.confident && valueChangeEval.computed == null) && getInputValueMode(seen.type) === "attribute") {
5003
+ const type = evaluate(seen.type.value).computed;
5004
+ throw tag.hub.buildError(seen.valueChange, `\`valueChange\` cannot be used on a \`type="${type}"\` \`<input>\` — user interaction can never change its \`value\`.` + (/^[cr]/i.test(type) ? " Bind `checked` or `checkedValue` instead." : ""));
5005
+ }
4852
5006
  if (relatedControllable && relatedControllable.attrs[1]) hasEventHandlers = true;
4853
5007
  if (node.var || hasDynamicAttributes || hasEventHandlers || textPlaceholders || injectNonce || seen.content && tagName !== "meta" && !node.body.body.length || isDynamicControllable(relatedControllable)) {
4854
5008
  const tagExtra = node.extra ??= {};
@@ -4952,6 +5106,20 @@ var native_tag_default = {
4952
5106
  const usedAttrs = getUsedAttrs(tagName, tag.node);
4953
5107
  const { staticAttrs, staticControllable, staticContentAttr, skipExpression, injectNonce } = usedAttrs;
4954
5108
  let { spreadExpression } = usedAttrs;
5109
+ if (!isOptimize() && nodeBinding) {
5110
+ const changeAttr = staticControllable?.attrs[1];
5111
+ if (changeAttr) {
5112
+ const handler = evaluate(changeAttr.value);
5113
+ if (!(handler.confident && handler.computed == null)) setSectionDebugVar(tagSection, getPrefixedScopeAccessor(nodeBinding, getAccessorPrefix().ControlledHandler), changeAttr.name, changeAttr.loc);
5114
+ } else if (spreadExpression) {
5115
+ const spreads = tag.node.attributes.filter((attr) => _marko_compiler.types.isMarkoSpreadAttribute(attr));
5116
+ const spreadLoc = spreads.length === 1 && spreads[0].value.loc;
5117
+ if (spreadLoc && spreadLoc.start.index != null) {
5118
+ const name = "..." + tag.hub.file.code.slice(spreadLoc.start.index, spreadLoc.end.index);
5119
+ for (const prefix of [getAccessorPrefix().ControlledHandler, getAccessorPrefix().EventAttributes]) if (prefix !== getAccessorPrefix().ControlledHandler || getSpreadControllableValueProps(tagName)) setSectionDebugVar(tagSection, getPrefixedScopeAccessor(nodeBinding, prefix), name, spreadLoc);
5120
+ }
5121
+ }
5122
+ }
4955
5123
  if (tagName === "select" && (staticControllable || spreadExpression)) flushBefore(tag);
4956
5124
  write`<${tagName}`;
4957
5125
  if (injectNonce) write`${callRuntime("_attr_nonce")}`;
@@ -5128,7 +5296,7 @@ var native_tag_default = {
5128
5296
  stmt = _marko_compiler.types.expressionStatement(callRuntime(`_attr_${name}_items`, nodeExpr, _marko_compiler.types.objectExpression(props)));
5129
5297
  }
5130
5298
  }
5131
- if (stmt) addStatement("render", tagSection, valueReferences, stmt, !!meta.dynamicItems);
5299
+ if (stmt) addStatement("render", tagSection, valueReferences, stmt, true);
5132
5300
  }
5133
5301
  break;
5134
5302
  }
@@ -6019,7 +6187,7 @@ function getChangeHandler(tag, attr) {
6019
6187
  if (!existingChangedAttr) {
6020
6188
  const bindingIdentifierPath = binding.path.getOuterBindingIdentifierPaths()[binding.identifier.name];
6021
6189
  let changeAttrExpr = bindingIdentifierPath ? bindingIdentifierPath.parentPath === binding.path ? buildChangeHandlerFunction(attr.value, modifier) : bindingIdentifierPath.parentPath.isObjectProperty() ? getChangeHandlerFromObjectPattern(bindingIdentifierPath.parentPath) : void 0 : void 0;
6022
- if (!changeAttrExpr) throw tag.hub.buildError(attr.value, bindingIdentifierPath?.parentPath?.isArrayPattern() ? `Cannot two-way bind to \`${attr.value.name}\` because it comes from array destructuring, which has no change handler. Use object destructuring or pass an explicit \`${changeAttrName}\` attribute.` : "Unable to bind to value.");
6190
+ if (!changeAttrExpr) throw tag.hub.buildError(attr.value, bindingIdentifierPath?.parentPath?.isArrayPattern() ? `Cannot two-way bind to \`${attr.value.name}\` because it comes from array destructuring, which has no change handler. Use object destructuring or pass an explicit \`${changeAttrName}\` attribute.` : bindingIdentifierPath?.parentPath?.isObjectProperty({ computed: true }) ? `Cannot two-way bind to \`${attr.value.name}\` because it is destructured with a dynamically computed key, so its change handler cannot be derived. Use a static key or pass an explicit \`${changeAttrName}\` attribute.` : "Unable to bind to value.");
6023
6191
  if (modifier && _marko_compiler.types.isIdentifier(changeAttrExpr)) changeAttrExpr = _marko_compiler.types.logicalExpression("&&", changeAttrExpr, buildModifierForwarder(_marko_compiler.types.cloneNode(changeAttrExpr), modifier));
6024
6192
  const changeHandlerAttr = _marko_compiler.types.markoAttribute(changeAttrName, changeAttrExpr);
6025
6193
  handlerByModifier.set(modifierKey, changeHandlerAttr);
@@ -6060,25 +6228,21 @@ function buildChangeHandlerFunction(id, modifier) {
6060
6228
  function getChangeHandlerFromObjectPattern(parent) {
6061
6229
  let changeKey;
6062
6230
  const pattern = parent.parentPath;
6063
- if (parent.node.computed) {
6064
- changeKey = generateUidIdentifier("dynamicChange");
6065
- pattern.pushContainer("properties", _marko_compiler.types.objectProperty(_marko_compiler.types.binaryExpression("+", parent.get("key").node, _marko_compiler.types.stringLiteral("Change")), changeKey, true));
6066
- } else {
6067
- const searchKey = `${getStringOrIdentifierValue(parent.get("key"))}Change`;
6068
- for (const prop of pattern.get("properties")) if (prop.isObjectProperty()) {
6069
- const propKey = prop.get("key");
6070
- const propValue = prop.get("value");
6071
- if (!prop.node.computed && getStringOrIdentifierValue(propKey) === searchKey && propValue.isIdentifier()) {
6072
- changeKey = propValue.node;
6073
- break;
6074
- }
6231
+ const keyName = getStaticKeyName(parent.node);
6232
+ if (keyName === void 0) return;
6233
+ const searchKey = `${keyName}Change`;
6234
+ for (const prop of pattern.get("properties")) if (prop.isObjectProperty()) {
6235
+ const propValue = prop.get("value");
6236
+ if (getStaticKeyName(prop.node) === searchKey && propValue.isIdentifier()) {
6237
+ changeKey = propValue.node;
6238
+ break;
6075
6239
  }
6076
- if (!changeKey) pattern.unshiftContainer("properties", _marko_compiler.types.objectProperty(_marko_compiler.types.stringLiteral(searchKey), changeKey = generateUidIdentifier(searchKey)));
6077
6240
  }
6241
+ if (!changeKey) pattern.unshiftContainer("properties", _marko_compiler.types.objectProperty(_marko_compiler.types.stringLiteral(searchKey), changeKey = generateUidIdentifier(searchKey)));
6078
6242
  return changeKey;
6079
6243
  }
6080
- function getStringOrIdentifierValue(path) {
6081
- return getLiteralName(path.node);
6244
+ function getStaticKeyName(prop) {
6245
+ return prop.computed && !_marko_compiler.types.isStringLiteral(prop.key) ? void 0 : getLiteralName(prop.key);
6082
6246
  }
6083
6247
  function getLiteralName(node) {
6084
6248
  switch (node.type) {
@@ -6272,7 +6436,7 @@ function crawlSectionsAndSetBinding(tag, binding, properties, skip) {
6272
6436
  }
6273
6437
  //#endregion
6274
6438
  //#region src/translator/util/translate-var.ts
6275
- function translateVar(tag, initialValue, kind = "const") {
6439
+ function translateVar(tag, initialValue, kind = "const", statements) {
6276
6440
  const { node: { var: tagVar } } = tag;
6277
6441
  if (!tagVar) return;
6278
6442
  const tagSection = getOrCreateSection(tag);
@@ -6307,7 +6471,9 @@ function translateVar(tag, initialValue, kind = "const") {
6307
6471
  restPath.remove();
6308
6472
  }
6309
6473
  });
6310
- tag.insertBefore(_marko_compiler.types.variableDeclaration(kind, [_marko_compiler.types.variableDeclarator(tagVar, initialValue)]));
6474
+ const declaration = _marko_compiler.types.variableDeclaration(kind, [_marko_compiler.types.variableDeclarator(tagVar, initialValue)]);
6475
+ if (statements) statements.push(declaration);
6476
+ else tag.insertBefore(declaration);
6311
6477
  }
6312
6478
  function getDestructurePattern(id) {
6313
6479
  let cur = id;
@@ -6362,13 +6528,13 @@ function knownTagTranslateHTML(tag, tagIdentifier, contentSection, propTree) {
6362
6528
  statements: []
6363
6529
  };
6364
6530
  const childScopeBinding = tagExtra[kChildScopeBinding];
6365
- if (getSerializeReason(section, childScopeBinding)) {
6531
+ const childScopeSerializeReason = getSerializeReason(section, childScopeBinding);
6532
+ let varStatement;
6533
+ if (childScopeSerializeReason) {
6366
6534
  const peekScopeId = generateUidIdentifier(childScopeBinding?.name);
6367
- const peekScopeDeclaration = _marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(peekScopeId, callRuntime("_peek_scope_id"))]);
6368
- if (tagVar) tag.insertBefore(peekScopeDeclaration);
6369
- else statements.push(peekScopeDeclaration);
6535
+ statements.push(_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(peekScopeId, callRuntime("_peek_scope_id"))]));
6370
6536
  setBindingSerializedValue(section, childScopeBinding, callRuntime("_existing_scope", peekScopeId));
6371
- if (tagVar) statements.push(_marko_compiler.types.expressionStatement(callRuntime("_var", getScopeIdIdentifier(section), getScopeAccessorLiteral(tag.node.extra[kChildOffsetScopeBinding$1]), peekScopeId, _marko_compiler.types.stringLiteral(getResumeRegisterId(section, tagVar.extra?.binding, "var")))));
6537
+ if (tagVar) varStatement = _marko_compiler.types.expressionStatement(callRuntime("_var", getScopeIdIdentifier(section), getScopeAccessorLiteral(tag.node.extra[kChildOffsetScopeBinding$1]), peekScopeId, _marko_compiler.types.stringLiteral(getResumeRegisterId(section, tagVar.extra?.binding, "var"))));
6372
6538
  }
6373
6539
  if (contentSection.paramReasonGroups) {
6374
6540
  let childSerializeReasonExpr;
@@ -6406,8 +6572,10 @@ function knownTagTranslateHTML(tag, tagIdentifier, contentSection, propTree) {
6406
6572
  if (!tag.node.arguments?.length || properties.length) renderArgs.push(propsToExpression(properties));
6407
6573
  return renderArgs;
6408
6574
  };
6409
- if (tagVar) translateVar(tag, callExpression(tagIdentifier, ...getArgs()), "let");
6410
- else statements.push(callStatement(tagIdentifier, ...getArgs()));
6575
+ if (tagVar) {
6576
+ translateVar(tag, callExpression(tagIdentifier, ...getArgs()), "let", statements);
6577
+ if (varStatement) statements.push(varStatement);
6578
+ } else statements.push(callStatement(tagIdentifier, ...getArgs()));
6411
6579
  for (const replacement of tag.replaceWithMultiple(statements)) replacement.skip();
6412
6580
  }
6413
6581
  function knownTagTranslateDOM(tag, propTree, getBindingIdentifier, callSetup) {
@@ -6417,7 +6585,8 @@ function knownTagTranslateDOM(tag, propTree, getBindingIdentifier, callSetup) {
6417
6585
  if (node.var) {
6418
6586
  const varBinding = node.var.extra.binding;
6419
6587
  const source = initValue(varBinding);
6420
- source.register = !!getSerializeReason(tagSection, childScopeBinding) || !signalHasStatements(source);
6588
+ source.register = !!getSerializeReason(tagSection, childScopeBinding);
6589
+ source.referenced = true;
6421
6590
  source.buildAssignment = (valueSection, value) => {
6422
6591
  const changeArgs = [createScopeReadExpression(childScopeBinding, valueSection), value];
6423
6592
  if (!isOptimize()) changeArgs.push(_marko_compiler.types.stringLiteral(varBinding.name));
@@ -6919,6 +7088,7 @@ function createBinding(name, type, refSection, upstreamAlias, property, excludeP
6919
7088
  const declared = sameSection && refDeclared;
6920
7089
  const binding = {
6921
7090
  id,
7091
+ uid: id,
6922
7092
  name,
6923
7093
  originalName: void 0,
6924
7094
  type,
@@ -6994,9 +7164,9 @@ function trackVarReferences(tag, type, upstreamAlias) {
6994
7164
  const section = getOrCreateSection(tag);
6995
7165
  let canonicalUpstreamAlias = upstreamAlias && getCanonicalBinding(upstreamAlias);
6996
7166
  if (canonicalUpstreamAlias) {
6997
- const { excludeProperties } = canonicalUpstreamAlias;
7167
+ const { excludeProperties, restOffset } = canonicalUpstreamAlias;
6998
7168
  if (excludeProperties !== void 0) canonicalUpstreamAlias = canonicalUpstreamAlias.upstreamAlias;
6999
- createBindingsAndTrackReferences(tagVar, canonicalUpstreamAlias.type, tag.scope, section, canonicalUpstreamAlias, void 0, excludeProperties);
7169
+ createBindingsAndTrackReferences(tagVar, canonicalUpstreamAlias.type, tag.scope, section, canonicalUpstreamAlias, void 0, excludeProperties, restOffset);
7000
7170
  return canonicalUpstreamAlias;
7001
7171
  }
7002
7172
  createBindingsAndTrackReferences(tagVar, type, tag.scope, section, void 0, void 0, void 0);
@@ -7049,7 +7219,7 @@ function trackReferencesForBinding(babelBinding, binding) {
7049
7219
  for (const ref of referencePaths) {
7050
7220
  const refSection = getOrCreateSection(ref);
7051
7221
  const markoRoot = getMarkoRoot(ref);
7052
- if (markoRoot?.type === "MarkoAttribute" && markoRoot.parentPath === babelBinding.path) throw ref.buildCodeFrameError(`\`${ref.node.name}\` is the [tag variable](https://markojs.com/docs/reference/language#tag-variables) this tag declares, so its own attributes cannot read it.`);
7222
+ if (markoRoot?.type === "MarkoAttribute" && markoRoot.parentPath === babelBinding.path && !getFnRoot(ref)) throw ref.buildCodeFrameError(`\`${ref.node.name}\` is the [tag variable](https://markojs.com/docs/reference/language#tag-variables) this tag declares, so its own attributes cannot read it.`);
7053
7223
  else if (isReferenceHoisted(babelBinding.path, ref)) {
7054
7224
  const invoked = isInvokedFunction(ref);
7055
7225
  if (invoked) setReferencesScope(ref);
@@ -7080,12 +7250,13 @@ function trackReferencesForBinding(babelBinding, binding) {
7080
7250
  const left = ref.get("left");
7081
7251
  if (left.isIdentifier()) trackReference(left, binding);
7082
7252
  }
7083
- }
7253
+ } else if (ref.isForXStatement()) throw ref.get("left").buildCodeFrameError(`\`${binding.name}\` is a [tag variable](https://markojs.com/docs/reference/language#tag-variables), so a \`for...${ref.isForOfStatement() ? "of" : "in"}\` cannot assign to it. Loop into a local variable and assign \`${binding.name}\` from it instead.`);
7084
7254
  }
7085
7255
  }
7086
7256
  function trackAssignment(assignment, binding) {
7087
7257
  const fnParent = getFnParent(assignment);
7088
7258
  if (!fnParent) throw assignment.buildCodeFrameError(`\`${binding.name}\` is a tag ${binding.type === 3 ? "parameter" : "variable"} and can only be assigned within a script or function.`);
7259
+ if (binding.type === 4) throw assignment.buildCodeFrameError(`\`${binding.name}\` is a tag parameter and cannot be assigned to.`);
7089
7260
  const fnRoot = getFnRoot(fnParent);
7090
7261
  const fnExtra = fnRoot && (fnRoot.node.extra ??= {});
7091
7262
  const section = getOrCreateSection(assignment);
@@ -7145,14 +7316,14 @@ function createBindingsAndTrackReferences(lVal, type, scope, section, upstreamAl
7145
7316
  }
7146
7317
  case "ArrayPattern": {
7147
7318
  const patternBinding = (property ? upstreamAlias.propertyAliases.get(property) : upstreamAlias) || ((lVal.extra ??= {}).binding = createBinding(generateUid(property || "pattern"), type, section, upstreamAlias, property, excludeProperties, lVal.loc));
7148
- let i = -1;
7319
+ let index = (restOffset || 0) - 1;
7149
7320
  for (const element of lVal.elements) {
7150
- i++;
7321
+ index++;
7151
7322
  if (element) {
7152
7323
  if (element.type === "RestElement") {
7153
- excludeProperties = i > 0 ? addNumericPropertiesUntil(excludeProperties, i) : void 0;
7154
- createBindingsAndTrackReferences(element.argument, type, scope, section, patternBinding, void 0, excludeProperties, i);
7155
- } else if (_marko_compiler.types.isLVal(element)) createBindingsAndTrackReferences(element, type, scope, section, patternBinding, `${i}`, void 0);
7324
+ excludeProperties = index > 0 ? addNumericPropertiesUntil(excludeProperties, index) : void 0;
7325
+ createBindingsAndTrackReferences(element.argument, type, scope, section, patternBinding, void 0, excludeProperties, index);
7326
+ } else if (_marko_compiler.types.isLVal(element)) createBindingsAndTrackReferences(element, type, scope, section, patternBinding, `${index}`, void 0);
7156
7327
  }
7157
7328
  }
7158
7329
  break;
@@ -7610,7 +7781,7 @@ function unionParamSources(a, b) {
7610
7781
  return merged;
7611
7782
  }
7612
7783
  const bindingUtil = new Sorted(function compareBindings(a, b) {
7613
- return a === b ? 0 : a.section.id - b.section.id || (a.type !== b.type && (a.type === 0 || b.type === 0) ? a.type - b.type || a.id - b.id : a.id - b.id);
7784
+ return a === b ? 0 : a.section.id - b.section.id || (a.type !== b.type && (a.type === 0 || b.type === 0) ? a.type - b.type || a.id - b.id : a.id - b.id) || a.uid - b.uid;
7614
7785
  });
7615
7786
  const propsUtil = new Sorted(function compareProps(a, b) {
7616
7787
  return a < b ? -1 : a > b ? 1 : 0;
@@ -8419,8 +8590,8 @@ var define_default = {
8419
8590
  if (isOutputHTML()) {
8420
8591
  flushInto(tag);
8421
8592
  writeHTMLResumeStatements(tag.get("body"));
8593
+ translateVar(tag, propsToExpression(translatedAttrs.properties), "const", translatedAttrs.statements);
8422
8594
  tag.insertBefore(translatedAttrs.statements);
8423
- translateVar(tag, propsToExpression(translatedAttrs.properties));
8424
8595
  } else {
8425
8596
  if (_marko_compiler.types.isIdentifier(node.var)) {
8426
8597
  const babelBinding = tag.scope.getBinding(node.var.name);
@@ -8642,7 +8813,7 @@ var id_default = {
8642
8813
  const source = initValue(node.var.extra.binding);
8643
8814
  if (valueAttr) {
8644
8815
  const { value } = valueAttr;
8645
- addValue(section, value.extra?.referencedBindings, source, _marko_compiler.types.logicalExpression("||", value, id));
8816
+ addValue(section, value.extra?.referencedBindings, source, _marko_compiler.types.logicalExpression("||", value, evaluate(value).confident ? id : callRuntime("_id", scopeIdentifier, _marko_compiler.types.stringLiteral(getPrefixedScopeAccessor(node.var.extra.binding, getAccessorPrefix().IdFallback)))));
8646
8817
  } else addValue(section, void 0, source, id);
8647
8818
  tag.remove();
8648
8819
  }
@@ -8833,7 +9004,7 @@ var script_default = {
8833
9004
  const end = body[body.length - 1]?.end;
8834
9005
  const bodyStatements = (0, _marko_compiler_babel_utils.parseStatements)(tag.hub.file, code, start, end);
8835
9006
  if (bodyStatements.length) {
8836
- const valueFn = _marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement(bodyStatements), traverseContains(bodyStatements, isAwaitExpression));
9007
+ const valueFn = _marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement(bodyStatements), !!traverseFindAwait(bodyStatements));
8837
9008
  node.attributes.push(_marko_compiler.types.markoAttribute("value", valueFn));
8838
9009
  }
8839
9010
  node.body.body = [];
@@ -8894,19 +9065,6 @@ var script_default = {
8894
9065
  }],
8895
9066
  types: runtime_info_default.name + "/tags/script.d.marko"
8896
9067
  };
8897
- function isAwaitExpression(node) {
8898
- switch (node.type) {
8899
- case "ForOfStatement": return node.await;
8900
- case "FunctionDeclaration":
8901
- case "FunctionExpression":
8902
- case "ArrowFunctionExpression":
8903
- case "ClassMethod":
8904
- case "ObjectMethod":
8905
- case "ClassPrivateMethod": return skip;
8906
- case "AwaitExpression": return true;
8907
- default: return false;
8908
- }
8909
- }
8910
9068
  function isReturnedFunction(node) {
8911
9069
  switch (node.type) {
8912
9070
  case "FunctionDeclaration":
@@ -9114,6 +9272,7 @@ function checkStyleInterpolations(tag) {
9114
9272
  let stringQuote = "";
9115
9273
  let inComment = false;
9116
9274
  let groupDepth = 0;
9275
+ let urlDepth = 0;
9117
9276
  let blockDepth = 0;
9118
9277
  let valueColon = false;
9119
9278
  let runPlaceholder;
@@ -9128,6 +9287,7 @@ function checkStyleInterpolations(tag) {
9128
9287
  const child = body[i];
9129
9288
  if (_marko_compiler.types.isMarkoPlaceholder(child)) {
9130
9289
  if (stringQuote) throw tag.hub.buildError(child, styleStringMsg);
9290
+ if (urlDepth) throw tag.hub.buildError(child, styleUrlMsg);
9131
9291
  if (!runPlaceholder) {
9132
9292
  runPlaceholder = child;
9133
9293
  runAfterColon = valueColon;
@@ -9155,9 +9315,14 @@ function checkStyleInterpolations(tag) {
9155
9315
  inComment = true;
9156
9316
  j++;
9157
9317
  } else if (c === "\"" || c === "'") stringQuote = c;
9158
- else if (c === "(" || c === "[") groupDepth++;
9159
- else if (c === ")" || c === "]") {
9160
- if (groupDepth) groupDepth--;
9318
+ else if (c === "(" || c === "[") {
9319
+ groupDepth++;
9320
+ if (!urlDepth && cssUrlBefore.test(text.slice(0, j + 1)) && !cssQuotedArg.test(text.slice(j + 1))) urlDepth = groupDepth;
9321
+ } else if (c === ")" || c === "]") {
9322
+ if (groupDepth) {
9323
+ if (urlDepth === groupDepth) urlDepth = 0;
9324
+ groupDepth--;
9325
+ }
9161
9326
  } else if (!groupDepth) switch (c) {
9162
9327
  case ":":
9163
9328
  if (blockDepth) valueColon = true;
@@ -9182,10 +9347,13 @@ const styleInterpolationMsg = "A `${...}` interpolation in a [`<style>` tag](htt
9182
9347
  const styleSelectorMsg = `${styleInterpolationMsg} only resolves in a declaration value, not in a selector or at-rule prelude. For a native html [\`<style>\` tag](https://markojs.com/docs/reference/core-tag#style) use the \`html-style\` core tag instead.`;
9183
9348
  const stylePropertyMsg = `${styleInterpolationMsg} cannot be used as a property name. For a native html [\`<style>\` tag](https://markojs.com/docs/reference/core-tag#style) use the \`html-style\` core tag instead.`;
9184
9349
  const styleStringMsg = `${styleInterpolationMsg} is not substituted inside a quoted CSS string — the literal text \`var(--…)\` would be rendered instead of the value. For a native html [\`<style>\` tag](https://markojs.com/docs/reference/core-tag#style) use the \`html-style\` core tag instead.`;
9350
+ const styleUrlMsg = `${styleInterpolationMsg} is not substituted inside an unquoted \`url()\` — the raw url token consumes the \`var(--…)\` text literally, invalidating the declaration. Move the whole \`url(...)\` into the interpolated value. For a native html [\`<style>\` tag](https://markojs.com/docs/reference/core-tag#style) use the \`html-style\` core tag instead.`;
9185
9351
  const styleGluedMsg = `${styleInterpolationMsg} CSS does not re-tokenize, so a unit written directly after it (eg \`\${x}px\`) becomes the invalid \`var(--…)px\`. Move the unit into the interpolated value (so it resolves to eg \`"10px"\`) or use \`calc(var(--…) * 1px)\`.`;
9186
9352
  const styleGluedBeforeMsg = `${styleInterpolationMsg} CSS does not re-tokenize, so text written directly before it (eg \`10\${x}\`) merges with the \`var(--…)\` into a single invalid token. Add whitespace before the interpolation or move the text into the interpolated value.`;
9187
9353
  const cssGluedValue = /^(?:[%.\d]|(?:p[xtc]|in|[cm]m|q|r?em|ex|ch|r?lh|v[whib]|vmin|vmax|fr|deg|g?rad|turn|m?s|k?hz|dp(?:i|cm|px)|cq[whib]|cqmin|cqmax)(?![\w-]))/i;
9188
9354
  const cssGluedBefore = /[\w%]$/;
9355
+ const cssUrlBefore = /(?:^|[^\w-])url\($/i;
9356
+ const cssQuotedArg = /^\s*["']/;
9189
9357
  //#endregion
9190
9358
  //#region src/translator/core/style.ts
9191
9359
  const STYLE_EXT_REG = /^style((?:\.[a-zA-Z0-9$_-]+)+)?/;
@@ -9534,6 +9702,27 @@ function isBeforeHtmlOrHead(documentType) {
9534
9702
  return false;
9535
9703
  }
9536
9704
  //#endregion
9705
+ //#region src/translator/visitors/export-declaration.ts
9706
+ var export_declaration_default = {
9707
+ analyze(exportDecl) {
9708
+ const { node } = exportDecl;
9709
+ const { source } = node;
9710
+ if (source) {
9711
+ const tagImport = (0, _marko_compiler_babel_utils.resolveTagImport)(exportDecl, source.value);
9712
+ if (tagImport) {
9713
+ (node.extra ??= {}).tagImport = tagImport;
9714
+ const tags = exportDecl.hub.file.metadata.marko.tags;
9715
+ if (!tags.includes(tagImport)) tags.push(tagImport);
9716
+ }
9717
+ }
9718
+ },
9719
+ translate: { exit(exportDecl) {
9720
+ const { node } = exportDecl;
9721
+ const tagImport = node.extra?.tagImport;
9722
+ if (tagImport) node.source.value = tagImport;
9723
+ } }
9724
+ };
9725
+ //#endregion
9537
9726
  //#region src/translator/visitors/import-declaration.ts
9538
9727
  const triggerRegExp = /\s*([\w-]+)\s*([^?|]+?)?\s*(?:\?([^|]*?))?\s*(?:\||$)/g;
9539
9728
  const [getHtmlLoadWrapped] = createProgramState(() => /* @__PURE__ */ new Map());
@@ -10149,6 +10338,7 @@ function optionalValueToNode(value) {
10149
10338
  const kDOMBinding = Symbol("dynamic tag dom binding");
10150
10339
  const kChildOffsetScopeBinding = Symbol("custom tag scope offset");
10151
10340
  const importedDynamicTagResume = /* @__PURE__ */ new WeakSet();
10341
+ const importedDynamicTagVarResume = /* @__PURE__ */ new WeakSet();
10152
10342
  const [getCompatRegistrations] = createProgramState(() => /* @__PURE__ */ new Set());
10153
10343
  const [getCompatBoundaryCalls] = createProgramState(() => /* @__PURE__ */ new Map());
10154
10344
  function pushCompatRegistration(key, statement) {
@@ -10287,7 +10477,7 @@ var dynamic_tag_default = {
10287
10477
  if (tag.node.var) {
10288
10478
  const varBinding = tag.node.var.extra.binding;
10289
10479
  tagVarSignal = initValue(varBinding);
10290
- tagVarSignal.register = true;
10480
+ tagVarSignal.register = tagVarSignal.referenced = true;
10291
10481
  tagVarSignal.buildAssignment = (valueSection, value) => {
10292
10482
  const changeArgs = [_marko_compiler.types.memberExpression(getScopeExpression(tagVarSignal.section, valueSection), _marko_compiler.types.stringLiteral(getAccessorPrefix().BranchScopes + getScopeAccessor(nodeBinding)), true), value];
10293
10483
  if (!isOptimize()) changeArgs.push(_marko_compiler.types.stringLiteral(varBinding.name));
@@ -10305,6 +10495,7 @@ var dynamic_tag_default = {
10305
10495
  }
10306
10496
  if (!isClassAPI) {
10307
10497
  enableDynamicTagResume(tag);
10498
+ enableDynamicTagVarResume(tag);
10308
10499
  enableDynamicTagControllables(tag);
10309
10500
  }
10310
10501
  addValue(section, tagExtra.referencedBindings, signal, tagExpression);
@@ -10322,6 +10513,13 @@ function enableDynamicTagControllables(tag) {
10322
10513
  return;
10323
10514
  }
10324
10515
  }
10516
+ function enableDynamicTagVarResume(tag) {
10517
+ const program = (0, _marko_compiler_babel_utils.getProgram)().node;
10518
+ if (tag.node.var && !importedDynamicTagVarResume.has(program) && analyzeTagNameType(tag, true) !== 1) {
10519
+ importedDynamicTagVarResume.add(program);
10520
+ importRuntimeFeature("dynamic-tag-var");
10521
+ }
10522
+ }
10325
10523
  function enableDynamicTagResume(tag) {
10326
10524
  const program = (0, _marko_compiler_babel_utils.getProgram)().node;
10327
10525
  if (!importedDynamicTagResume.has(program) && analyzeTagNameType(tag, true) !== 1) {
@@ -10488,7 +10686,7 @@ function isTagsAPI(file = (0, _marko_compiler_babel_utils.getFile)()) {
10488
10686
  let { featureType } = programExtra;
10489
10687
  if (!featureType) {
10490
10688
  const lookup = (0, _marko_compiler_babel_utils.getTaglibLookup)(file);
10491
- const tagsDir = getTagsDir(file.opts.filename);
10689
+ const tagsDir = getTagsDir(lookup, file.opts.filename);
10492
10690
  const state = {};
10493
10691
  if (tagsDir && !lookup.manualTagsDirs?.has(tagsDir)) addFeature(state, Tags, "Template file within a tags directory", program);
10494
10692
  scanBody(state, program.get("body"));
@@ -10496,24 +10694,10 @@ function isTagsAPI(file = (0, _marko_compiler_babel_utils.getFile)()) {
10496
10694
  }
10497
10695
  return featureType === Tags;
10498
10696
  }
10499
- function getTagsDir(filename) {
10500
- const pathSeparator = /\/|\\/.exec(filename)?.[0];
10501
- if (pathSeparator) {
10502
- let previousIndex = filename.length - 1;
10503
- while (previousIndex > 0) {
10504
- const index = filename.lastIndexOf(pathSeparator, previousIndex);
10505
- switch (previousIndex - index) {
10506
- case 4:
10507
- if (filename.startsWith("tags", index + 1)) return filename.slice(0, index + 5);
10508
- break;
10509
- case 10:
10510
- if (filename.startsWith("components", index + 1)) return false;
10511
- break;
10512
- }
10513
- previousIndex = index - 1;
10514
- }
10515
- }
10516
- return false;
10697
+ function getTagsDir(lookup, filename) {
10698
+ let nearest;
10699
+ for (const dir of lookup.discoveryDirs || []) if (filename.startsWith(dir) && (filename[dir.length] === "/" || filename[dir.length] === "\\") && (!nearest || dir.length > nearest.length)) nearest = dir;
10700
+ return !!nearest && /[/\\]tags$/.test(nearest) && nearest;
10517
10701
  }
10518
10702
  function scanBody(state, body) {
10519
10703
  if (body?.length) for (const child of body) switch (child.type) {
@@ -10801,6 +10985,8 @@ const visitors = extractVisitors({
10801
10985
  Function: function_default,
10802
10986
  ReferencedIdentifier: referenced_identifier_default,
10803
10987
  ImportDeclaration: import_declaration_default,
10988
+ ExportNamedDeclaration: export_declaration_default,
10989
+ ExportAllDeclaration: export_declaration_default,
10804
10990
  MarkoDocumentType: document_type_default,
10805
10991
  MarkoDeclaration: declaration_default,
10806
10992
  MarkoCDATA: cdata_default,