marko 6.3.54 → 6.3.56

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 (64) hide show
  1. package/cheatsheet.md +1 -0
  2. package/dist/common/accessor.d.ts +3 -0
  3. package/dist/common/accessor.debug.d.ts +3 -0
  4. package/dist/common/constants/closure-scopes-prop.d.ts +4 -0
  5. package/dist/common/constants/closure-scopes-prop.debug.d.ts +4 -0
  6. package/dist/common/types.d.ts +1 -1
  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-script.feat.js +1 -1
  20. package/dist/debug/dom/dynamic-tag-script.feat.mjs +1 -1
  21. package/dist/debug/dom/dynamic-tag-var.feat.js +1 -1
  22. package/dist/debug/dom/dynamic-tag-var.feat.mjs +1 -1
  23. package/dist/debug/dom/placeholder.feat.js +1 -1
  24. package/dist/debug/dom/placeholder.feat.mjs +1 -1
  25. package/dist/debug/{dom-tl43c2wO.mjs → dom-BeCNT5R5.mjs} +12 -11
  26. package/dist/debug/{dom-CI0Vojyk.js → dom-DcwejnYg.js} +17 -16
  27. package/dist/debug/dom.js +2 -2
  28. package/dist/debug/dom.mjs +2 -2
  29. package/dist/debug/html.js +7 -11
  30. package/dist/debug/html.mjs +7 -11
  31. package/dist/dom/catch.feat.js +1 -1
  32. package/dist/dom/catch.feat.mjs +1 -1
  33. package/dist/dom/controllable-input.feat.js +1 -1
  34. package/dist/dom/controllable-input.feat.mjs +1 -1
  35. package/dist/dom/controllable-open.feat.js +1 -1
  36. package/dist/dom/controllable-open.feat.mjs +1 -1
  37. package/dist/dom/controllable-select.feat.js +1 -1
  38. package/dist/dom/controllable-select.feat.mjs +1 -1
  39. package/dist/dom/controllable-textarea.feat.js +1 -1
  40. package/dist/dom/controllable-textarea.feat.mjs +1 -1
  41. package/dist/dom/controllable.feat.js +1 -1
  42. package/dist/dom/controllable.feat.mjs +1 -1
  43. package/dist/dom/dynamic-tag-script.feat.js +1 -1
  44. package/dist/dom/dynamic-tag-script.feat.mjs +1 -1
  45. package/dist/dom/dynamic-tag-var.feat.js +1 -1
  46. package/dist/dom/dynamic-tag-var.feat.mjs +1 -1
  47. package/dist/dom/placeholder.feat.js +1 -1
  48. package/dist/dom/placeholder.feat.mjs +1 -1
  49. package/dist/dom/resume.d.ts +1 -1
  50. package/dist/dom/signals.d.ts +1 -1
  51. package/dist/{dom-4udEPZaj.mjs → dom-BwNsIevR.mjs} +11 -8
  52. package/dist/{dom-C1mr-TA7.js → dom-QEF0csuC.js} +12 -9
  53. package/dist/dom.d.ts +1 -1
  54. package/dist/dom.js +2 -2
  55. package/dist/dom.mjs +2 -2
  56. package/dist/html.js +5 -10
  57. package/dist/html.mjs +5 -10
  58. package/dist/translator/index.js +102 -118
  59. package/dist/translator/util/optional.d.ts +1 -3
  60. package/dist/translator/util/references.d.ts +3 -0
  61. package/dist/translator/util/serialize-reasons.d.ts +2 -0
  62. package/dist/translator/util/translate-attrs.d.ts +2 -1
  63. package/package.json +4 -4
  64. package/tags-html.d.ts +4 -3
@@ -86,7 +86,7 @@ function assertNoBodyContent(tag) {
86
86
  //#endregion
87
87
  //#region src/translator/core/attrs.ts
88
88
  var attrs_default = {
89
- migrate: [(tag) => {
89
+ migrate: (tag) => {
90
90
  (0, _marko_compiler_babel_utils.assertNoArgs)(tag);
91
91
  (0, _marko_compiler_babel_utils.assertNoParams)(tag);
92
92
  (0, _marko_compiler_babel_utils.assertNoAttributes)(tag);
@@ -103,7 +103,7 @@ var attrs_default = {
103
103
  } else tag.remove();
104
104
  }
105
105
  });
106
- }],
106
+ },
107
107
  attributes: {},
108
108
  autocomplete: [{
109
109
  displayText: "attrs/{ ... }",
@@ -861,13 +861,6 @@ function fromIter(data) {
861
861
  else one = item;
862
862
  return many || one;
863
863
  }
864
- function* toIter(data) {
865
- if (data !== void 0) if (Array.isArray(data)) yield* data;
866
- else yield data;
867
- }
868
- function includes(data, item) {
869
- return data !== void 0 ? Array.isArray(data) ? data.includes(item) : data === item : false;
870
- }
871
864
  function find(data, cb) {
872
865
  if (data !== void 0) {
873
866
  if (Array.isArray(data)) return data.find(cb);
@@ -886,6 +879,9 @@ function reduce(data, cb, initial) {
886
879
  function toArray(data, cb) {
887
880
  return data !== void 0 ? Array.isArray(data) ? data.map(cb) : [cb(data, 0)] : [];
888
881
  }
882
+ function toSet(data) {
883
+ return data !== void 0 ? Array.isArray(data) ? new Set(data) : (/* @__PURE__ */ new Set()).add(data) : /* @__PURE__ */ new Set();
884
+ }
889
885
  function mapToString(data, sep, cb) {
890
886
  if (data !== void 0) {
891
887
  if (Array.isArray(data)) {
@@ -981,9 +977,6 @@ function joinRepeatable(compare, a, b) {
981
977
  const compareResult = compare(a, b);
982
978
  return compareResult === 0 ? a : compareResult < 0 ? [a, b] : [b, a];
983
979
  }
984
- function addUnique(data, item) {
985
- return includes(data, item) ? data : push(data, item);
986
- }
987
980
  function at(data, index) {
988
981
  return Array.isArray(data) ? data[index] : index ? void 0 : data;
989
982
  }
@@ -1194,6 +1187,14 @@ function mergeRemappedSources(reason, params, mapped) {
1194
1187
  function mergeSerializeReasons(a, b) {
1195
1188
  return mergeSources(a, b);
1196
1189
  }
1190
+ function isOwnResumeReason(reason) {
1191
+ return !!reason && !!(reason.state || reason.forced);
1192
+ }
1193
+ function hasOwnResumeReason(section) {
1194
+ if (isOwnResumeReason(section.serializeReason)) return true;
1195
+ for (const reason of section.serializeReasons.values()) if (isOwnResumeReason(reason)) return true;
1196
+ return false;
1197
+ }
1197
1198
  function applySerializeExprs(section) {
1198
1199
  const propExprs = section.propSerializeExprs;
1199
1200
  if (propExprs) {
@@ -2731,47 +2732,33 @@ function getExprIfSerialized(section, reason, expr) {
2731
2732
  return guard ? _marko_compiler.types.logicalExpression("&&", guard, expr) : expr;
2732
2733
  }
2733
2734
  function getOrHoist(reason, isGuard) {
2734
- const onlySection = getOnlySection(reason.param);
2735
- if (onlySection) {
2736
- const state = getSectionReasonState(onlySection);
2737
- const tracking = isGuard ? state.guard : state.if;
2738
- const existingFound = sourcesUtil.find(tracking.hoistedReasons, reason);
2739
- if (existingFound) return _marko_compiler.types.identifier(tracking.names.get(existingFound));
2740
- const guard = buildGuardExpr(onlySection, reason.param, isGuard);
2741
- const seenFound = sourcesUtil.find(tracking.seenReasons, reason);
2742
- if (!seenFound) {
2743
- const expr = _marko_compiler.types.parenthesizedExpression(guard);
2744
- tracking.pending.set(reason, expr);
2745
- tracking.seenReasons = sourcesUtil.add(tracking.seenReasons, reason);
2746
- return expr;
2747
- }
2748
- const name = generateUid(`${isGuard ? "sg" : "si"}__${getDebugNamesAsIdentifier(reason.param)}`);
2749
- tracking.hoistedReasons = sourcesUtil.add(tracking.hoistedReasons, reason);
2750
- tracking.names.set(reason, name);
2751
- state.declarators.push(_marko_compiler.types.variableDeclarator(_marko_compiler.types.identifier(name), guard));
2752
- const pendingParen = tracking.pending.get(seenFound);
2753
- if (pendingParen) {
2754
- pendingParen.expression = _marko_compiler.types.identifier(name);
2755
- tracking.pending.delete(seenFound);
2756
- }
2757
- return _marko_compiler.types.parenthesizedExpression(_marko_compiler.types.identifier(name));
2758
- }
2759
- let orExpr;
2760
- for (const [paramsSection, params] of groupParamsBySection(reason.param)) {
2761
- const expr = buildGuardExpr(paramsSection, params, isGuard);
2762
- orExpr = orExpr ? _marko_compiler.types.logicalExpression("||", orExpr, expr) : expr;
2763
- }
2764
- return orExpr;
2765
- }
2766
- function buildGuardExpr(paramsSection, params, isGuard) {
2767
- const serializeIdentifier = scopeReasonIdentifier(paramsSection);
2768
- return paramsSection.paramReasonGroups ? callRuntime(isGuard ? "_serialize_guard" : "_serialize_if", serializeIdentifier, withLeadingComment(_marko_compiler.types.numericLiteral(getParamReasonGroupIndex(paramsSection, params)), getDebugNames(params))) : serializeIdentifier;
2769
- }
2770
- function getOnlySection(params) {
2771
- if (params === void 0) return void 0;
2772
- if (!Array.isArray(params)) return params.section;
2773
- const { section } = params[0];
2774
- return section === params[params.length - 1].section ? section : void 0;
2735
+ let expr;
2736
+ for (const [section, params] of groupParamsBySection(reason.param)) {
2737
+ const part = getOrHoistSectionGuard(section, params, isGuard);
2738
+ expr = expr ? _marko_compiler.types.logicalExpression("||", expr, part) : part;
2739
+ }
2740
+ return expr;
2741
+ }
2742
+ function getOrHoistSectionGuard(section, params, isGuard) {
2743
+ if (!section.paramReasonGroups) return scopeReasonIdentifier(section);
2744
+ const state = getSectionReasonState(section);
2745
+ const tracking = isGuard ? state.guard : state.if;
2746
+ const index = getParamReasonGroupIndex(section, params);
2747
+ const name = tracking.names.get(index);
2748
+ if (name) return _marko_compiler.types.identifier(name);
2749
+ const guard = callRuntime(isGuard ? "_serialize_guard" : "_serialize_if", scopeReasonIdentifier(section), withLeadingComment(_marko_compiler.types.numericLiteral(index), getDebugNames(params)));
2750
+ const pending = tracking.pending.get(index);
2751
+ if (!pending) {
2752
+ const expr = _marko_compiler.types.parenthesizedExpression(guard);
2753
+ tracking.pending.set(index, expr);
2754
+ return expr;
2755
+ }
2756
+ const hoisted = generateUid(`${isGuard ? "sg" : "si"}__${getDebugNamesAsIdentifier(params)}`);
2757
+ tracking.names.set(index, hoisted);
2758
+ tracking.pending.delete(index);
2759
+ state.declarators.push(_marko_compiler.types.variableDeclarator(_marko_compiler.types.identifier(hoisted), guard));
2760
+ pending.expression = _marko_compiler.types.identifier(hoisted);
2761
+ return _marko_compiler.types.parenthesizedExpression(_marko_compiler.types.identifier(hoisted));
2775
2762
  }
2776
2763
  function isDynamicSerializeGuard(section, reason) {
2777
2764
  return isReasonDynamic(reason) && !isCrossSection(section, reason);
@@ -2782,9 +2769,7 @@ function isCrossSection(section, reason) {
2782
2769
  function createTypeState() {
2783
2770
  return {
2784
2771
  names: /* @__PURE__ */ new Map(),
2785
- pending: /* @__PURE__ */ new Map(),
2786
- seenReasons: void 0,
2787
- hoistedReasons: void 0
2772
+ pending: /* @__PURE__ */ new Map()
2788
2773
  };
2789
2774
  }
2790
2775
  function hasDynamicSerializeReason(section) {
@@ -3212,8 +3197,7 @@ function getSignal(section, referencedBindings, name) {
3212
3197
  const render = getSignalFn(signal);
3213
3198
  const closureSignalBuilder = getClosureSignalBuilder(section);
3214
3199
  if (closureSignalBuilder && !isDynamicClosure(section, closure)) return closureSignalBuilder(closure, render);
3215
- const changeable = isChangeableDynamicClosure(section, closure);
3216
- return callRuntime("_closure_get", isOptimize() ? _marko_compiler.types.numericLiteral(getClosureAccessorId(closure)) : getScopeAccessorLiteral(closure, true), render, isImmediateOwner(section, closure) ? void 0 : _marko_compiler.types.arrowFunctionExpression([scopeIdentifier], getScopeExpression(section, closure.section)), changeable ? _marko_compiler.types.stringLiteral(getResumeRegisterId(section, closure, "subscribe")) : void 0, changeable && isOptimize() ? getScopeAccessorLiteral(closure, true) : void 0);
3200
+ return callRuntime("_closure_get", isOptimize() ? _marko_compiler.types.numericLiteral(getClosureAccessorId(closure)) : getScopeAccessorLiteral(closure, true), render, isImmediateOwner(section, closure) ? void 0 : _marko_compiler.types.arrowFunctionExpression([scopeIdentifier], getScopeExpression(section, closure.section)), isChangeableDynamicClosure(section, closure) ? _marko_compiler.types.stringLiteral(getResumeRegisterId(section, closure, "subscribe")) : void 0);
3217
3201
  };
3218
3202
  }
3219
3203
  return signal;
@@ -4765,7 +4749,7 @@ const contentProps = /* @__PURE__ */ new WeakSet();
4765
4749
  function translateAttrs(tag, propTree = true, skip, statements = [], contentKey = "content") {
4766
4750
  const contentProperties = [];
4767
4751
  const attrTagLookup = tag.node.extra?.attributeTags;
4768
- const seen = new Set(skip);
4752
+ const seen = toSet(skip);
4769
4753
  if (attrTagLookup) {
4770
4754
  for (const name in attrTagLookup) {
4771
4755
  const attrTagMeta = attrTagLookup[name];
@@ -4782,7 +4766,7 @@ function translateAttrs(tag, propTree = true, skip, statements = [], contentKey
4782
4766
  const child = attrTags[i];
4783
4767
  if (child.isMarkoTag()) if ((0, _marko_compiler_babel_utils.isAttributeTag)(child)) {
4784
4768
  const attrTagMeta = attrTagLookup[getTagName(child)];
4785
- if (skip?.has(attrTagMeta.name)) continue;
4769
+ if (propsUtil.has(skip, attrTagMeta.name)) continue;
4786
4770
  if (attrTagMeta.dynamic) i = addDynamicAttrTagStatements(attrTags, i, attrTagLookup, statements, propTree, contentKey);
4787
4771
  else {
4788
4772
  const translatedAttrTag = translateAttrs(child, getKnownFromPropTree(propTree, attrTagMeta.name), void 0, statements, contentKey);
@@ -5038,7 +5022,7 @@ var native_tag_default = {
5038
5022
  const attr = seen[name];
5039
5023
  if (isEventHandler(name) || name === "content" || !evaluate(attr.value).confident) addSetupExpr(tagSection, attr.value);
5040
5024
  }
5041
- if (node.var || hasEventHandlers) addSerializeReason(tagSection, FORCED, nodeBinding);
5025
+ if (hasEventHandlers || isTagVarRead(tag)) addSerializeReason(tagSection, FORCED, nodeBinding);
5042
5026
  trackDomVarReferences(tag, nodeBinding);
5043
5027
  addSerializeExpr(tagSection, push(exprExtras, tagExtra), nodeBinding);
5044
5028
  }
@@ -6126,14 +6110,16 @@ function translateVar(tag, initialValue, kind = "const", statements) {
6126
6110
  const restPath = id.parentPath;
6127
6111
  if (restPath.type !== "RestElement") throw restPath.buildCodeFrameError("Invalid compiler state, found a rest binding outside of a rest element.");
6128
6112
  let curPath = tag.parentPath;
6113
+ let prevPath = tag;
6129
6114
  while (curPath) {
6130
6115
  if (curPath.node.extra?.section === binding.section) {
6131
6116
  const canonicalUpstreamAlias = getCanonicalBinding(binding.upstreamAlias);
6132
6117
  const props = toArray(binding.excludeProperties, (name) => _marko_compiler.types.objectProperty(toPropertyName(name), generateUidIdentifier(name)));
6133
6118
  props.push(restPath.node);
6134
- curPath.insertBefore(_marko_compiler.types.variableDeclaration(kind, [_marko_compiler.types.variableDeclarator(_marko_compiler.types.objectPattern(props), canonicalUpstreamAlias.nullable ? _marko_compiler.types.logicalExpression("||", getDeclaredBindingExpression(canonicalUpstreamAlias), _marko_compiler.types.objectExpression([])) : getDeclaredBindingExpression(canonicalUpstreamAlias))]));
6119
+ (curPath.parentPath ? curPath : prevPath).insertBefore(_marko_compiler.types.variableDeclaration(kind, [_marko_compiler.types.variableDeclarator(_marko_compiler.types.objectPattern(props), canonicalUpstreamAlias.nullable ? _marko_compiler.types.logicalExpression("||", getDeclaredBindingExpression(canonicalUpstreamAlias), _marko_compiler.types.objectExpression([])) : getDeclaredBindingExpression(canonicalUpstreamAlias))]));
6135
6120
  break;
6136
6121
  }
6122
+ prevPath = curPath;
6137
6123
  curPath = curPath.parentPath;
6138
6124
  }
6139
6125
  restPath.remove();
@@ -6493,7 +6479,7 @@ function writeParamsToSignals(tag, propTree, importAlias, info) {
6493
6479
  }
6494
6480
  function applyAttrObject(tag, propTree, tagInputIdentifier, info) {
6495
6481
  const referencedBindings = tag.node.extra?.referencedBindings;
6496
- const translatedAttrs = translateAttrs(tag, true, propTree.rest && new Set(toIter(propTree.rest.binding.excludeProperties)));
6482
+ const translatedAttrs = translateAttrs(tag, true, propTree.rest?.binding.excludeProperties);
6497
6483
  let translatedProps = propsToExpression(translatedAttrs.properties);
6498
6484
  if (translatedAttrs.statements.length) addStatement("render", info.tagSection, referencedBindings, translatedAttrs.statements);
6499
6485
  if ((0, _marko_compiler_babel_utils.isAttributeTag)(tag)) {
@@ -7196,7 +7182,7 @@ var program_default = {
7196
7182
  if (paramsBinding && !paramsBinding.pruned) programExtra.domExports.params = getBindingPropTree(paramsBinding);
7197
7183
  const section = programExtra.section;
7198
7184
  forEachSection((childSection) => {
7199
- programExtra.hasResumes ||= !!(childSection.serializeReason || childSection.serializeReasons.size || childSection !== section && !isSectionRendererElided(childSection) && getSectionRegisterReasons(childSection));
7185
+ programExtra.hasResumes ||= !!(hasOwnResumeReason(childSection) || childSection !== section && !isSectionRendererElided(childSection) && getSectionRegisterReasons(childSection));
7200
7186
  });
7201
7187
  if (!section.hoistedTo && !sectionHasSetupStatements(section)) programExtra.domExports.setupEmpty = true;
7202
7188
  }
@@ -7409,6 +7395,10 @@ function getExistingPropertyAlias(binding, property) {
7409
7395
  binding = binding.upstreamAlias;
7410
7396
  }
7411
7397
  }
7398
+ function isTagVarRead(tag) {
7399
+ const tagVar = tag.node.var;
7400
+ return !!tagVar && !!tag.scope.getBinding(tagVar.name)?.referencePaths.length;
7401
+ }
7412
7402
  function trackDomVarReferences(tag, binding) {
7413
7403
  const tagVar = tag.node.var;
7414
7404
  if (!tagVar) return;
@@ -8231,6 +8221,7 @@ function addReadToExpression(root, binding, getter) {
8231
8221
  const section = getOrCreateSection(exprRoot);
8232
8222
  const rootExtra = exprRoot.node.extra ??= { section };
8233
8223
  const exprExtra = getCanonicalExtra(rootExtra);
8224
+ if (exprExtra.pruned) return;
8234
8225
  const extra = node.extra ??= {};
8235
8226
  extra.exprRoot = rootExtra;
8236
8227
  const read = addRead(exprExtra, extra, binding, section, getter);
@@ -8690,15 +8681,15 @@ function getAllSerializeReasonsForBinding(binding, properties) {
8690
8681
  function getRegisterReasonForExtra(extra) {
8691
8682
  if (extra.forceRegister) return FORCED;
8692
8683
  const { reason, reads } = serializationForExtra(extra);
8693
- return some(reads, isForceRegisterRead) ? FORCED : reason;
8694
- }
8695
- function isForceRegisterRead(read) {
8696
- return !!read.forceRegister;
8684
+ if (reads) {
8685
+ for (const read of reads) if (read.forceRegister) return FORCED;
8686
+ }
8687
+ return reason;
8697
8688
  }
8698
8689
  function serializationForExtra(extra) {
8699
8690
  if (extra.isEffect) return FORCED_SERIALIZATION;
8700
8691
  const serialization = extraSerialization(extra);
8701
- const reads = isReferencedExtra(extra) ? addUnique(serialization.reads, extra) : serialization.reads;
8692
+ const reads = isReferencedExtra(extra) ? addSerializationRead(serialization.reads, extra) : serialization.reads;
8702
8693
  return reads === serialization.reads ? serialization : {
8703
8694
  reason: serialization.reason,
8704
8695
  reads
@@ -8766,7 +8757,7 @@ function computeBindingSerialization(binding, properties) {
8766
8757
  if (!(head === "content" && expr.nativeTagSpread && bindingUtil.has(expr.spreadFrom, binding))) serialization = mergeSerialization(serialization, FORCED_SERIALIZATION);
8767
8758
  continue;
8768
8759
  }
8769
- const reads = addUnique(serialization.reads, expr);
8760
+ const reads = addSerializationRead(serialization.reads, expr);
8770
8761
  if (reads !== serialization.reads) serialization = {
8771
8762
  reason: serialization.reason,
8772
8763
  reads
@@ -8793,10 +8784,7 @@ function mergeSerialization(a, b) {
8793
8784
  if (a === UNSERIALIZED) return b;
8794
8785
  if (b === UNSERIALIZED) return a;
8795
8786
  const reason = mergeSources(a.reason, b.reason);
8796
- let reads = a.reads;
8797
- forEach(b.reads, (read) => {
8798
- reads = addUnique(reads, read);
8799
- });
8787
+ const reads = unionSerializationReads(a.reads, b.reads);
8800
8788
  if (reason === a.reason && reads === a.reads) return a;
8801
8789
  if (reason === b.reason && reads === b.reads) return b;
8802
8790
  return {
@@ -8804,6 +8792,15 @@ function mergeSerialization(a, b) {
8804
8792
  reads
8805
8793
  };
8806
8794
  }
8795
+ function addSerializationRead(reads, read) {
8796
+ return reads?.has(read) ? reads : new Set(reads).add(read);
8797
+ }
8798
+ function unionSerializationReads(a, b) {
8799
+ if (!a || !b || a === b) return a || b;
8800
+ let result;
8801
+ for (const read of b) if (!a.has(read)) (result ??= new Set(a)).add(read);
8802
+ return result || a;
8803
+ }
8807
8804
  function addNumericPropertiesUntil(props, len) {
8808
8805
  let result = props;
8809
8806
  for (let i = len; i--;) result = propsUtil.add(result, i + "");
@@ -8957,9 +8954,11 @@ function createStatementTag(keyword) {
8957
8954
  const rawValue = node.rawValue;
8958
8955
  const code = rawValue.replace(keywordReg, "");
8959
8956
  const start = node.start + (rawValue.length - code.length);
8960
- let body = (0, _marko_compiler_babel_utils.parseStatements)(file, code, start, start + code.length);
8961
- if (body.length === 1 && _marko_compiler.types.isBlockStatement(body[0])) body = body[0].body;
8962
- tag.replaceWith(_marko_compiler.types.markoScriptlet(body, true, target));
8957
+ let block = (0, _marko_compiler_babel_utils.parseBlock)(file, code, start, start + code.length);
8958
+ if (block.body.length === 1 && _marko_compiler.types.isBlockStatement(block.body[0])) block = block.body[0];
8959
+ const scriptlet = _marko_compiler.types.markoScriptlet(block.body, true, target);
8960
+ scriptlet.innerComments = block.innerComments;
8961
+ tag.replaceWith(scriptlet);
8963
8962
  },
8964
8963
  parseOptions: {
8965
8964
  statement: true,
@@ -9150,7 +9149,7 @@ var define_default = {
9150
9149
  //#endregion
9151
9150
  //#region src/translator/core/effect.ts
9152
9151
  var effect_default = {
9153
- migrate: [(tag) => {
9152
+ migrate: (tag) => {
9154
9153
  if (tag.node.body.body.length) throw tag.get("name").buildCodeFrameError("The `<effect>` tag has been replaced by [`<script>`](https://markojs.com/docs/reference/core-tag#script), which runs its body as code. Rename it to `<script>`.");
9155
9154
  (0, _marko_compiler_babel_utils.assertNoArgs)(tag);
9156
9155
  (0, _marko_compiler_babel_utils.assertNoParams)(tag);
@@ -9164,7 +9163,7 @@ var effect_default = {
9164
9163
  tag.replaceWith(_marko_compiler.types.markoTag(withPreviousLocation(_marko_compiler.types.stringLiteral("script"), node.name), node.attributes, node.body, node.arguments, node.var, node.attributeTags));
9165
9164
  }
9166
9165
  });
9167
- }],
9166
+ },
9168
9167
  attributes: {},
9169
9168
  types: runtime_info_default.name + "/tags/effect.d.marko"
9170
9169
  };
@@ -9219,7 +9218,7 @@ var html_comment_default = {
9219
9218
  const tagExtra = mergeReferences(tagSection, tag.node, referenceNodes);
9220
9219
  nodeBinding = tagExtra[kNodeBinding$1] = createBinding("#comment", 0, tagSection, void 0, void 0, void 0, void 0, !!tagVar);
9221
9220
  trackDomVarReferences(tag, nodeBinding);
9222
- if (tagVar) addSerializeReason(tagSection, FORCED, nodeBinding);
9221
+ if (isTagVarRead(tag)) addSerializeReason(tagSection, FORCED, nodeBinding);
9223
9222
  addSerializeExpr(tagSection, tagExtra, nodeBinding);
9224
9223
  }
9225
9224
  const write = writeTo(tag);
@@ -9535,9 +9534,9 @@ var script_default = {
9535
9534
  }
9536
9535
  const start = body[0]?.start;
9537
9536
  const end = body[body.length - 1]?.end;
9538
- const bodyStatements = (0, _marko_compiler_babel_utils.parseStatements)((0, _marko_compiler_babel_utils.getFile)(), code, start, end);
9539
- if (bodyStatements.length) {
9540
- const valueFn = _marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement(bodyStatements), !!traverseFindAwait(bodyStatements));
9537
+ const block = (0, _marko_compiler_babel_utils.parseBlock)((0, _marko_compiler_babel_utils.getFile)(), code, start, end);
9538
+ if (block.body.length || block.innerComments) {
9539
+ const valueFn = _marko_compiler.types.arrowFunctionExpression([], block, !!traverseFindAwait(block));
9541
9540
  node.attributes.push(_marko_compiler.types.markoAttribute("value", valueFn));
9542
9541
  }
9543
9542
  node.body.body = [];
@@ -9554,16 +9553,18 @@ var script_default = {
9554
9553
  for (const attr of node.attributes) if (attr.type === "MarkoAttribute" && attr.name === "value") {
9555
9554
  if (seenValueAttr) throw tag.hub.buildError(attr, "Invalid duplicate value attribute.");
9556
9555
  seenValueAttr = true;
9557
- (attr.value.extra ??= {}).isEffect = true;
9558
- addSetupExpr(getOrCreateSection(tag), attr.value);
9559
- (0, _marko_compiler_babel_utils.getProgram)().node.extra.isInteractive = true;
9556
+ if (!isEmptyFunction(attr.value)) {
9557
+ (attr.value.extra ??= {}).isEffect = true;
9558
+ addSetupExpr(getOrCreateSection(tag), attr.value);
9559
+ (0, _marko_compiler_babel_utils.getProgram)().node.extra.isInteractive = true;
9560
+ }
9560
9561
  } else throw tag.hub.buildError(attr, "The [`<script>` tag](https://markojs.com/docs/reference/core-tag#script) does not support html attributes. For a native html [`<script>` tag](https://markojs.com/docs/reference/core-tag#script) use the `html-script` core tag instead.");
9561
9562
  if (!seenValueAttr) dropNodes(getAllTagReferenceNodes(node));
9562
9563
  },
9563
9564
  translate: { exit(tag) {
9564
9565
  const { node } = tag;
9565
9566
  const [valueAttr] = node.attributes;
9566
- if (!valueAttr) {
9567
+ if (!valueAttr?.value.extra?.isEffect) {
9567
9568
  tag.remove();
9568
9569
  return;
9569
9570
  }
@@ -9598,6 +9599,9 @@ var script_default = {
9598
9599
  }],
9599
9600
  types: runtime_info_default.name + "/tags/script.d.marko"
9600
9601
  };
9602
+ function isEmptyFunction(node) {
9603
+ return (_marko_compiler.types.isFunctionExpression(node) || _marko_compiler.types.isArrowFunctionExpression(node)) && _marko_compiler.types.isBlockStatement(node.body) && !node.body.body.length;
9604
+ }
9601
9605
  function isReturnedFunction(node) {
9602
9606
  switch (node.type) {
9603
9607
  case "FunctionDeclaration":
@@ -10454,13 +10458,14 @@ var referenced_identifier_default = {
10454
10458
  const globalRead = _marko_compiler.types.memberExpression(scopeIdentifier, _marko_compiler.types.identifier(getAccessorProp().Global));
10455
10459
  const key = !isOptimize() && getSignalGlobalKey(identifier);
10456
10460
  if (key) identifier.parentPath.replaceWith(callRuntime("_global_read", globalRead, _marko_compiler.types.stringLiteral(key)));
10457
- else identifier.replaceWith(globalRead);
10461
+ else replaceWithExtra(identifier, globalRead);
10458
10462
  break;
10459
10463
  }
10460
- case "$signal": if (isOutputHTML()) identifier.replaceWith(_marko_compiler.types.callExpression(_marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement([_marko_compiler.types.throwStatement(_marko_compiler.types.newExpression(_marko_compiler.types.identifier("Error"), [_marko_compiler.types.stringLiteral("Cannot use $signal in a server render.")]))])), []));
10464
+ case "$signal": if (isOutputHTML()) replaceWithExtra(identifier, _marko_compiler.types.callExpression(_marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement([_marko_compiler.types.throwStatement(_marko_compiler.types.newExpression(_marko_compiler.types.identifier("Error"), [_marko_compiler.types.stringLiteral("Cannot use $signal in a server render.")]))])), []));
10461
10465
  else {
10462
- const section = getSection(identifier);
10463
10466
  const exprRoot = identifier.node.extra.exprRoot;
10467
+ if (getCanonicalExtra(exprRoot).pruned) break;
10468
+ const section = getSection(identifier);
10464
10469
  const exprId = exprRoot.abortId;
10465
10470
  const resetEmitted = getAbortResetEmitted(section);
10466
10471
  if (!resetEmitted.has(exprRoot)) {
@@ -10472,6 +10477,10 @@ var referenced_identifier_default = {
10472
10477
  }
10473
10478
  }
10474
10479
  };
10480
+ function replaceWithExtra(path, replacement) {
10481
+ replacement.extra = path.node.extra;
10482
+ path.replaceWith(replacement);
10483
+ }
10475
10484
  function getSignalGlobalKey(identifier) {
10476
10485
  const { parent } = identifier;
10477
10486
  if (!_marko_compiler.types.isMemberExpression(parent) || parent.computed || !_marko_compiler.types.isIdentifier(parent.property) || parent.object !== identifier.node) return;
@@ -10729,7 +10738,7 @@ function enableDynamicTagVar(tag) {
10729
10738
  importRuntimeFeature("dynamic-tag-var");
10730
10739
  if (!tag.node.var.extra.binding.pruned) {
10731
10740
  const accessor = getScopeAccessorLiteral(tag.node.extra.nodeBinding, true);
10732
- if (addRuntimeOnce(`_resume_dynamic_tag_var ${accessor.value}`)) (0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.expressionStatement(callRuntime("_resume_dynamic_tag_var", accessor)));
10741
+ if (addRuntimeOnce(`_dynamic_tag_var_resume ${accessor.value}`)) (0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.expressionStatement(callRuntime("_dynamic_tag_var_resume", accessor)));
10733
10742
  }
10734
10743
  }
10735
10744
  function enableDynamicTagResume(tag) {
@@ -10883,7 +10892,7 @@ var text_default = {
10883
10892
  function buildAggregateError(file, rootMsg, ...paths) {
10884
10893
  const err = /* @__PURE__ */ new SyntaxError();
10885
10894
  const fileName = path.default.relative(_marko_compiler_modules.cwd, file.opts.filename);
10886
- const finalMsg = `${rootMsg}:\n\n${paths.map(([msg, path$13]) => `\x1b[90m${msg} at ${getFileNameWithLoc(fileName, path$13)}:\x1b[0m\n${getFrame(file, path$13)}`).join("\n\n")}`;
10895
+ const finalMsg = `${rootMsg}:\n\n${paths.map(([msg, path$11]) => `\x1b[90m${msg} at ${getFileNameWithLoc(fileName, path$11)}:\x1b[0m\n${getFrame(file, path$11)}`).join("\n\n")}`;
10887
10896
  if (!("MARKO_DEBUG" in process.env)) err.stack = finalMsg;
10888
10897
  Object.defineProperty(err, "message", {
10889
10898
  get() {
@@ -11183,34 +11192,9 @@ function normalizeVisitor(visitor) {
11183
11192
  return visitor?.default ?? visitor;
11184
11193
  }
11185
11194
  function normalizeVisit(visitor) {
11186
- if (Array.isArray(visitor)) {
11187
- let merged;
11188
- for (const entry of visitor) merged = sequenceVisit(merged, normalizeVisit(entry));
11189
- return merged;
11190
- }
11195
+ if (Array.isArray(visitor)) throw new Error("A core tag's hook must be a single visitor for the interop merge, not a list.");
11191
11196
  return typeof visitor === "function" ? visitor : normalizeVisitor(visitor);
11192
11197
  }
11193
- function sequenceVisit(first, second) {
11194
- if (!first || !second) return first || second;
11195
- const enterFirst = getVisitorEnter(first);
11196
- const enterSecond = getVisitorEnter(second);
11197
- const enter = (enterFirst || enterSecond) && function enter(path$11, state) {
11198
- const { node } = path$11;
11199
- enterFirst?.call(this, path$11, state);
11200
- if (path$11.node === node) enterSecond?.call(this, path$11, state);
11201
- };
11202
- const exitFirst = getVisitorExit(first);
11203
- const exitSecond = getVisitorExit(second);
11204
- const exit = (exitFirst || exitSecond) && function exit(path$12, state) {
11205
- const { node } = path$12;
11206
- exitFirst?.call(this, path$12, state);
11207
- if (path$12.node === node) exitSecond?.call(this, path$12, state);
11208
- };
11209
- return exit ? enter ? {
11210
- enter,
11211
- exit
11212
- } : { exit } : enter;
11213
- }
11214
11198
  function getVisitorEnter(visit) {
11215
11199
  return typeof visit === "function" ? visit : visit?.enter;
11216
11200
  }
@@ -28,19 +28,17 @@ export declare function size<T>(data: Opt<T>): number;
28
28
  export declare function filter<T>(data: Opt<T>, cb: (item: T) => boolean): Opt<T>;
29
29
  export declare function forEach<T>(data: Opt<T>, cb: (item: T, index: number) => void): void;
30
30
  export declare function fromIter<T>(data: Iterable<T>): T | Many<T> | undefined;
31
- export declare function toIter<T>(data: Opt<T>): Iterable<T>;
32
- export declare function includes<T>(data: Opt<T>, item: T): boolean;
33
31
  export declare function find<T>(data: Opt<T>, cb: (item: T, index: number) => boolean): Opt<T>;
34
32
  export declare function some<T>(data: Opt<T>, cb: (item: T, index: number) => boolean): boolean;
35
33
  export declare function every<T>(data: Opt<T>, cb: (item: T, index: number) => boolean): boolean;
36
34
  export declare function reduce<T, R>(data: Opt<T>, cb: (acc: R | undefined, item: T, index: number) => R | undefined): R | undefined;
37
35
  export declare function reduce<T, R>(data: Opt<T>, cb: (acc: R, item: T, index: number) => R, initial: R): R;
38
36
  export declare function toArray<T, R>(data: Opt<T>, cb: (item: T, index: number) => R): R[];
37
+ export declare function toSet<T>(data: Opt<T>): Set<T>;
39
38
  export declare function mapToString<T>(data: Opt<T>, sep: string, cb: (item: T, index: number) => string): string;
40
39
  export declare function findSorted<T>(compare: Compare<T>, data: T[], item: T): T | undefined;
41
40
  export declare function findIndexSorted<T>(compare: Compare<T>, data: T[], item: T): number;
42
41
  export declare function addSorted<T, U extends T[]>(compare: Compare<T>, data: U, item: T): U;
43
- export declare function addUnique<T>(data: Opt<T>, item: T): OneMany<T>;
44
42
  export declare function at<T>(data: Opt<T>, index: number): T | undefined;
45
43
  export declare function first<T>(data: OneMany<T>): T;
46
44
  export declare function rest<T>(data: OneMany<T>): Opt<T>;
@@ -36,6 +36,7 @@ export interface Binding {
36
36
  sources: undefined | Sources;
37
37
  /** The intersection whose work computes it, or the nearest one upstream. Set on alias roots only. */
38
38
  upstreamIntersection: Intersection | undefined;
39
+ /** Complete only once `finalizeReferences` runs at program analyze exit. */
39
40
  reads: Set<ReferencedExtra>;
40
41
  aliases: Set<Binding>;
41
42
  hoists: SortedOpt<Section>;
@@ -64,6 +65,7 @@ export interface Binding {
64
65
  localClosures: Map<Section, Binding> | undefined;
65
66
  declared: boolean;
66
67
  nullable: boolean;
68
+ /** Settled only once `finalizeReferences` runs at program analyze exit. */
67
69
  pruned: boolean | undefined;
68
70
  exposed: boolean;
69
71
  forcePersist: boolean;
@@ -163,6 +165,7 @@ declare module "@marko/compiler/dist/types" {
163
165
  export declare function createBinding(name: string, type: Binding["type"], refSection: Section, upstreamAlias?: Binding["upstreamAlias"], property?: string, excludeProperties?: SortedOpt<string>, loc?: t.SourceLocation | null, refDeclared?: boolean): Binding;
164
166
  export declare function getOrCreatePropertyAlias(binding: Binding, property: string): Binding;
165
167
  export declare function getPropertyAlias(binding: Binding | undefined, properties: Opt<string>): Binding | undefined;
168
+ export declare function isTagVarRead(tag: t.NodePath<t.MarkoTag>): boolean;
166
169
  export declare function trackDomVarReferences(tag: t.NodePath<t.MarkoTag>, binding: Binding): Binding | undefined;
167
170
  export declare function trackVarReferences(tag: t.NodePath<t.MarkoTag>, type: BindingType, upstreamAlias?: Binding["upstreamAlias"]): Binding | undefined;
168
171
  export declare function trackParamsReferences(body: t.NodePath<t.MarkoTagBody | t.Program>, type: BindingType): Binding | undefined;
@@ -30,6 +30,8 @@ export declare function mapParamReason(program: Section, reason: Sources, exprs:
30
30
  export declare function mergeSerializeReasons(a: SerializeReason, b: undefined | SerializeReason): SerializeReason;
31
31
  export declare function mergeSerializeReasons(a: undefined | SerializeReason, b: SerializeReason): SerializeReason;
32
32
  export declare function mergeSerializeReasons(a: undefined | SerializeReason, b: undefined | SerializeReason): SerializeReason | undefined;
33
+ export declare function isOwnResumeReason(reason: SerializeReason | undefined): boolean;
34
+ export declare function hasOwnResumeReason(section: Section): boolean;
33
35
  export declare function applySerializeExprs(section: Section): void;
34
36
  export declare function finalizeSerializeReason(section: Section): void;
35
37
  export declare function getSerializeReasonsVersion(): number;
@@ -1,8 +1,9 @@
1
1
  import { types as t } from "@marko/compiler";
2
2
  import { type BindingPropTree } from "./binding-prop-tree";
3
3
  import { type AttrTagLookup } from "./nested-attribute-tags";
4
+ import { type SortedOpt } from "./optional";
4
5
  type ContentKey = "renderBody" | "content";
5
- export declare function translateAttrs(tag: t.NodePath<t.MarkoTag>, propTree?: BindingPropTree | true, skip?: Set<string>, statements?: t.Statement[], contentKey?: ContentKey): {
6
+ export declare function translateAttrs(tag: t.NodePath<t.MarkoTag>, propTree?: BindingPropTree | true, skip?: SortedOpt<string>, statements?: t.Statement[], contentKey?: ContentKey): {
6
7
  properties: (t.ObjectMethod | t.ObjectProperty | t.SpreadElement)[];
7
8
  statements: t.Statement[];
8
9
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "6.3.54",
3
+ "version": "6.3.56",
4
4
  "description": "Optimized runtime for Marko templates.",
5
5
  "keywords": [
6
6
  "api",
@@ -51,14 +51,14 @@
51
51
  }
52
52
  },
53
53
  "dependencies": {
54
- "@marko/compiler": "^5.42.7",
54
+ "@marko/compiler": "^5.42.9",
55
55
  "csstype": "^3.2.3",
56
56
  "fastest-levenshtein": "^1.0.16",
57
57
  "magic-string": "^0.30.21"
58
58
  },
59
59
  "devDependencies": {
60
- "@marko/runtime-tags": "npm:marko@6.3.54",
61
- "marko": "5.39.43"
60
+ "@marko/runtime-tags": "npm:marko@6.3.56",
61
+ "marko": "5.39.44"
62
62
  },
63
63
  "engines": {
64
64
  "node": ">=22"
package/tags-html.d.ts CHANGED
@@ -1662,7 +1662,8 @@ declare global {
1662
1662
  */
1663
1663
  type?: AttrMissing | "context" | "toolbar";
1664
1664
  }
1665
- interface Meta extends HTMLAttributes<HTMLMetaElement> {
1665
+ // The one tag whose `content` is its HTML attribute instead of its body.
1666
+ interface Meta extends Omit<HTMLAttributes<HTMLMetaElement>, "content"> {
1666
1667
  /**
1667
1668
  * Specifies the character encoding for the HTML document.
1668
1669
  * @see https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-charset
@@ -4413,7 +4414,7 @@ declare global {
4413
4414
  * @see Marko.Body
4414
4415
  */
4415
4416
  content?:
4416
- | AttrString
4417
+ | AttrMissing
4417
4418
  | Marko.Body<[], void>
4418
4419
  | Marko.Template<Record<any, never>, void>;
4419
4420
 
@@ -4466,7 +4467,7 @@ declare global {
4466
4467
  * @see Marko.Body
4467
4468
  */
4468
4469
  content?:
4469
- | AttrString
4470
+ | AttrMissing
4470
4471
  | Marko.Body<[], void>
4471
4472
  | Marko.Template<Record<any, never>, void>;
4472
4473