marko 6.0.56 → 6.0.58

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.
@@ -56,16 +56,19 @@ var import_babel_utils = require("@marko/compiler/babel-utils");
56
56
  function assertNoSpreadAttrs(tag) {
57
57
  for (const attr2 of tag.get("attributes")) {
58
58
  if (attr2.isMarkoSpreadAttribute()) {
59
+ const tagName = tag.get("name").node.value;
59
60
  throw attr2.buildCodeFrameError(
60
- `The \`${tag.get("name").node.value}\` tag does not support \`...spread\` attributes.`
61
+ `The [\`<${tagName}>\`](https://next.markojs.com/docs/reference/core-tag#${tagName}) tag does not support \`...spread\` attributes.`
61
62
  );
62
63
  }
63
64
  }
64
65
  }
65
66
  function assertNoBodyContent(tag) {
66
67
  if (tag.node.body.body.length) {
67
- throw tag.get("name").buildCodeFrameError(
68
- `The \`${tag.get("name").node.value}\` tag does not support body content.`
68
+ const tagName = tag.get("name");
69
+ const tagNameLiteral = tagName.node.value;
70
+ throw tagName.buildCodeFrameError(
71
+ `The [\`<${tagNameLiteral}>\`](https://next.markojs.com/docs/reference/core-tag#${tagNameLiteral}) tag does not support body content.`
69
72
  );
70
73
  }
71
74
  }
@@ -1880,13 +1883,9 @@ var function_default = {
1880
1883
  };
1881
1884
  function finalizeFunctionRegistry() {
1882
1885
  for (const [fnExtra, exprExtras] of getReferencesByFn()) {
1883
- const seenExtras = /* @__PURE__ */ new Set();
1884
1886
  let shouldRegister = false;
1885
1887
  for (const exprExtra of exprExtras) {
1886
- const refExtra = getCanonicalExtra(exprExtra);
1887
- if (seenExtras.has(refExtra)) continue;
1888
- seenExtras.add(refExtra);
1889
- if (couldSerializeDownstream(refExtra.downstream)) {
1888
+ if (couldSerializeExtra(getCanonicalExtra(exprExtra))) {
1890
1889
  shouldRegister = true;
1891
1890
  break;
1892
1891
  }
@@ -1896,36 +1895,6 @@ function finalizeFunctionRegistry() {
1896
1895
  }
1897
1896
  }
1898
1897
  }
1899
- function couldSerializeDownstream(downstream) {
1900
- if (downstream) {
1901
- return Array.isArray(downstream.bindings) ? downstream.bindings.some((binding) => couldSerializeBinding(binding)) : couldSerializeBinding(
1902
- downstream.bindings,
1903
- downstream.excludeProperties
1904
- );
1905
- }
1906
- return false;
1907
- }
1908
- function couldSerializeBinding(binding, excludeProperties) {
1909
- if (getBindingSerializeReason(binding.section, binding)) {
1910
- return true;
1911
- }
1912
- for (const expr of binding.downstreamExpressions) {
1913
- if (expr.isEffect || couldSerializeDownstream(expr.downstream)) {
1914
- return true;
1915
- }
1916
- }
1917
- for (const alias of binding.aliases) {
1918
- if (couldSerializeBinding(alias)) {
1919
- return true;
1920
- }
1921
- }
1922
- for (const [name2, propBinding] of binding.propertyAliases) {
1923
- if (!excludeProperties?.has(name2) && couldSerializeBinding(propBinding)) {
1924
- return true;
1925
- }
1926
- }
1927
- return false;
1928
- }
1929
1898
  function canIgnoreRegister(markoRoot, exprRoot) {
1930
1899
  return (
1931
1900
  // bail within a placeholder
@@ -3101,7 +3070,7 @@ function getSectionMeta(section) {
3101
3070
  function markNode(path5, nodeBinding, reason) {
3102
3071
  if (nodeBinding.type !== 0 /* dom */) {
3103
3072
  throw path5.buildCodeFrameError(
3104
- "Tried to mark a node that was not determined to need a mark during analyze."
3073
+ "POTENTIAL MARKO BUG: Tried to mark a node that was not determined to need a mark during analyze."
3105
3074
  );
3106
3075
  }
3107
3076
  if (isOutputHTML()) {
@@ -3131,26 +3100,29 @@ var return_default = {
3131
3100
  if (parentTag) {
3132
3101
  if ((0, import_babel_utils15.isNativeTag)(parentTag)) {
3133
3102
  throw tag.get("name").buildCodeFrameError(
3134
- "The `return` tag can not be used in a native tag."
3103
+ "The [`<return>` tag](https://next.markojs.com/docs/reference/core-tag#return) can not be used in a [native tag](https://next.markojs.com/docs/reference/native-tag)."
3135
3104
  );
3136
3105
  } else if (isControlFlowTag(parentTag)) {
3137
3106
  throw tag.get("name").buildCodeFrameError(
3138
- `The \`return\` tag can not be used under an \`${parentTag.get("name").toString()}\` tag.`
3107
+ `The [\`<return>\` tag](https://next.markojs.com/docs/reference/core-tag#return) can not be used under the \`<${parentTag.get("name").toString()}>\` tag.`
3139
3108
  );
3140
3109
  }
3141
3110
  }
3142
3111
  if (tagsWithReturn.has(tag.parentPath)) {
3143
3112
  throw tag.get("name").buildCodeFrameError(
3144
- `Cannot have multiple \`return\` tags ${tag.parent.type === "Program" ? "for the template" : "within a tag's body content"}.`
3113
+ `Cannot have multiple [\`<return>\` tags](https://next.markojs.com/docs/reference/core-tag#return) ${tag.parent.type === "Program" ? "for the template" : "within a tag's body content"}.`
3145
3114
  );
3146
3115
  } else {
3147
3116
  tagsWithReturn.add(tag.parentPath);
3148
3117
  }
3149
3118
  const attrs2 = getKnownAttrValues(tag.node);
3150
3119
  if (!attrs2.value) {
3151
- throw tag.get("name").buildCodeFrameError("The `return` tag requires a value.");
3120
+ throw tag.get("name").buildCodeFrameError(
3121
+ "The [`<return>` tag](https://next.markojs.com/docs/reference/core-tag#return) requires a [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
3122
+ );
3152
3123
  }
3153
3124
  if (attrs2.valueChange) {
3125
+ (attrs2.valueChange.extra ??= {}).isEffect = true;
3154
3126
  forceSectionSerialize(
3155
3127
  getOrCreateSection(tag),
3156
3128
  getAccessorProp().TagVariableChange
@@ -3221,7 +3193,7 @@ var return_default = {
3221
3193
  displayText: "return=<value>",
3222
3194
  description: "Provides a value for use in a parent template.",
3223
3195
  snippet: "return=${1:value}",
3224
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#return"
3196
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#return"
3225
3197
  }
3226
3198
  ]
3227
3199
  };
@@ -3569,7 +3541,7 @@ function getSignalFn(signal) {
3569
3541
  }
3570
3542
  if (isIntersection && signal.renderReferencedBindings) {
3571
3543
  signal.render.unshift(
3572
- import_compiler21.types.variableDeclaration("const", [
3544
+ import_compiler21.types.variableDeclaration("let", [
3573
3545
  import_compiler21.types.variableDeclarator(
3574
3546
  createScopeReadPattern(section, signal.renderReferencedBindings),
3575
3547
  scopeIdentifier
@@ -4893,7 +4865,7 @@ function trackAssignment(assignment, binding) {
4893
4865
  const changePropName = binding.property + "Change";
4894
4866
  const changeBinding = binding.upstreamAlias.propertyAliases.get(changePropName) || createBinding(
4895
4867
  generateUid(changePropName),
4896
- 5 /* derived */,
4868
+ binding.type === 2 /* input */ ? binding.type : 5 /* derived */,
4897
4869
  binding.section,
4898
4870
  binding.upstreamAlias,
4899
4871
  changePropName,
@@ -5040,10 +5012,10 @@ function createBindingsAndTrackReferences(lVal, type, scope, section, upstreamAl
5040
5012
  void 0
5041
5013
  );
5042
5014
  if (lVal.left.extra?.binding) {
5043
- (lVal.right.extra ??= {}).downstream = {
5044
- bindings: lVal.left.extra.binding,
5045
- excludeProperties: void 0
5046
- };
5015
+ setBindingDownstream(
5016
+ lVal.left.extra.binding,
5017
+ lVal.right.extra ??= {}
5018
+ );
5047
5019
  }
5048
5020
  break;
5049
5021
  }
@@ -5147,17 +5119,6 @@ function finalizeReferences() {
5147
5119
  });
5148
5120
  }
5149
5121
  }
5150
- for (const [fn, reads] of readsByFn) {
5151
- fn.referencedBindingsInFunction = resolveReferencedBindings(
5152
- fn,
5153
- reads,
5154
- intersectionsBySection
5155
- );
5156
- forEach(
5157
- fn.referencedBindingsInFunction,
5158
- (binding) => forceBindingSerialize(binding.section, binding)
5159
- );
5160
- }
5161
5122
  for (const binding of bindings) {
5162
5123
  if (binding.type !== 0 /* dom */ && !binding.upstreamAlias) {
5163
5124
  pruneBinding(bindings, binding);
@@ -5417,6 +5378,19 @@ function finalizeReferences() {
5417
5378
  }
5418
5379
  });
5419
5380
  finalizeFunctionRegistry();
5381
+ for (const [fn, reads] of readsByFn) {
5382
+ fn.referencedBindingsInFunction = resolveReferencedBindings(
5383
+ fn,
5384
+ reads,
5385
+ intersectionsBySection
5386
+ );
5387
+ if (fn.registerId) {
5388
+ forEach(
5389
+ fn.referencedBindingsInFunction,
5390
+ (binding) => forceBindingSerialize(binding.section, binding)
5391
+ );
5392
+ }
5393
+ }
5420
5394
  mergedReferences.clear();
5421
5395
  readsByExpression.clear();
5422
5396
  readsByFn.clear();
@@ -5437,8 +5411,13 @@ function getMaxOwnSourceOffset(intersection, section) {
5437
5411
  return scopeOffset;
5438
5412
  }
5439
5413
  var intersectionMeta = /* @__PURE__ */ new WeakMap();
5440
- function setBindingValueExpr(binding, valueExpr) {
5441
- bindingValueExprs.set(binding, valueExpr || false);
5414
+ function setBindingDownstream(binding, expr) {
5415
+ bindingValueExprs.set(binding, expr || false);
5416
+ if (expr && expr !== true) {
5417
+ forEach(expr, (expr2) => {
5418
+ expr2.downstream = bindingUtil.add(expr2.downstream, binding);
5419
+ });
5420
+ }
5442
5421
  }
5443
5422
  var resolvedSources = /* @__PURE__ */ new WeakSet();
5444
5423
  var bindingValueExprs = /* @__PURE__ */ new WeakMap();
@@ -5805,6 +5784,50 @@ function getCanonicalExtra(extra) {
5805
5784
  }
5806
5785
  return extra;
5807
5786
  }
5787
+ var couldSerializeLookup = /* @__PURE__ */ new WeakMap();
5788
+ function couldSerializeExtra(extra) {
5789
+ let couldSerialize = couldSerializeLookup.get(extra);
5790
+ if (couldSerialize === void 0) {
5791
+ couldSerializeLookup.set(
5792
+ extra,
5793
+ couldSerialize = extra === (0, import_babel_utils19.getProgram)().node.extra?.returnValueExpr || !!find(extra.downstream, couldSerializeBinding)
5794
+ );
5795
+ }
5796
+ return couldSerialize;
5797
+ }
5798
+ function couldSerializeBinding(binding) {
5799
+ let couldSerialize = couldSerializeLookup.get(binding);
5800
+ if (couldSerialize === void 0) {
5801
+ if (getBindingSerializeReason(binding.section, binding)) {
5802
+ couldSerialize = true;
5803
+ } else {
5804
+ for (const expr of binding.downstreamExpressions) {
5805
+ if (expr.isEffect || couldSerializeExtra(expr)) {
5806
+ couldSerialize = true;
5807
+ break;
5808
+ }
5809
+ }
5810
+ if (!couldSerialize) {
5811
+ for (const alias of binding.aliases) {
5812
+ if (couldSerializeBinding(alias)) {
5813
+ couldSerialize = true;
5814
+ break;
5815
+ }
5816
+ }
5817
+ if (!couldSerialize) {
5818
+ for (const [, propBinding] of binding.propertyAliases) {
5819
+ if (couldSerializeBinding(propBinding)) {
5820
+ couldSerialize = true;
5821
+ break;
5822
+ }
5823
+ }
5824
+ }
5825
+ }
5826
+ }
5827
+ couldSerializeLookup.set(binding, couldSerialize ??= false);
5828
+ }
5829
+ return couldSerialize;
5830
+ }
5808
5831
  function setCanonicalExtra(extra, merged) {
5809
5832
  extra.merged = merged;
5810
5833
  }
@@ -5831,19 +5854,23 @@ var await_default = {
5831
5854
  const tagExtra = tag.node.extra ??= {};
5832
5855
  tagExtra[kDOMBinding] = createBinding("#text", 0 /* dom */, section);
5833
5856
  if (!valueAttr) {
5834
- throw tag.get("name").buildCodeFrameError("The `await` tag requires a value.");
5857
+ throw tag.get("name").buildCodeFrameError(
5858
+ "The [`<await>` tag](https://next.markojs.com/docs/reference/core-tag#await) requires a [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
5859
+ );
5835
5860
  }
5836
5861
  if (node.attributes.length > 1 || !import_compiler26.types.isMarkoAttribute(valueAttr) || valueAttr.name !== "value") {
5837
5862
  throw tag.get("name").buildCodeFrameError(
5838
- "The `await` tag only supports the `value` attribute."
5863
+ "The [`<await>` tag](https://next.markojs.com/docs/reference/core-tag#await) only supports the [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
5839
5864
  );
5840
5865
  }
5841
5866
  if (!node.body.body.length) {
5842
- throw tag.get("name").buildCodeFrameError("The `await` tag requires body content.");
5867
+ throw tag.get("name").buildCodeFrameError(
5868
+ "The [`<await>` tag](https://next.markojs.com/docs/reference/core-tag#await) requires [content](https://next.markojs.com/docs/reference/language#tag-content)."
5869
+ );
5843
5870
  }
5844
5871
  if (node.body.params.length && (node.body.params.length > 1 || import_compiler26.types.isSpreadElement(node.body.params[0]))) {
5845
5872
  throw tag.get("name").buildCodeFrameError(
5846
- "The `await` tag only supports a single parameter."
5873
+ "The [`<await>` tag](https://next.markojs.com/docs/reference/core-tag#await) only supports a single parameter."
5847
5874
  );
5848
5875
  }
5849
5876
  const bodySection = startSection(tagBody);
@@ -5851,7 +5878,7 @@ var await_default = {
5851
5878
  getOrCreateSection(tag);
5852
5879
  const paramsBinding = trackParamsReferences(tagBody, 3 /* param */);
5853
5880
  if (paramsBinding) {
5854
- setBindingValueExpr(paramsBinding, valueExtra);
5881
+ setBindingDownstream(paramsBinding, valueExtra);
5855
5882
  }
5856
5883
  bodySection.upstreamExpression = valueAttr.value.extra;
5857
5884
  },
@@ -5937,7 +5964,7 @@ var await_default = {
5937
5964
  autocomplete: [
5938
5965
  {
5939
5966
  description: "Use to consume asynchronous an data.",
5940
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#await"
5967
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#await"
5941
5968
  }
5942
5969
  ],
5943
5970
  types: runtime_info_default.name + "/tags/await.d.marko"
@@ -6027,14 +6054,18 @@ var const_default = {
6027
6054
  const { node } = tag;
6028
6055
  const [valueAttr] = node.attributes;
6029
6056
  if (!node.var) {
6030
- throw tag.get("name").buildCodeFrameError("The `const` tag requires a tag variable.");
6057
+ throw tag.get("name").buildCodeFrameError(
6058
+ "The [`<const>` tag](https://next.markojs.com/docs/reference/core-tag#const) requires a [tag variable](https://next.markojs.com/docs/reference/language#tag-variables)."
6059
+ );
6031
6060
  }
6032
6061
  if (!valueAttr) {
6033
- throw tag.get("name").buildCodeFrameError("The `const` tag requires a value.");
6062
+ throw tag.get("name").buildCodeFrameError(
6063
+ "The [`<const>` tag](https://next.markojs.com/docs/reference/core-tag#const) requires a [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
6064
+ );
6034
6065
  }
6035
6066
  if (node.attributes.length > 1 || !import_compiler29.types.isMarkoAttribute(valueAttr) || !valueAttr.default && valueAttr.name !== "value") {
6036
6067
  throw tag.get("name").buildCodeFrameError(
6037
- "The `const` tag only supports the `value` attribute."
6068
+ "The [`<const>` tag](https://next.markojs.com/docs/reference/core-tag#const) only supports the [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
6038
6069
  );
6039
6070
  }
6040
6071
  const valueExtra = evaluate(valueAttr.value);
@@ -6045,11 +6076,7 @@ var const_default = {
6045
6076
  const binding = trackVarReferences(tag, 5 /* derived */, upstreamAlias);
6046
6077
  if (binding) {
6047
6078
  if (!valueExtra.nullable) binding.nullable = false;
6048
- setBindingValueExpr(binding, valueExtra);
6049
- valueExtra.downstream = {
6050
- bindings: binding,
6051
- excludeProperties: void 0
6052
- };
6079
+ setBindingDownstream(binding, valueExtra);
6053
6080
  }
6054
6081
  },
6055
6082
  translate: {
@@ -6077,7 +6104,7 @@ var const_default = {
6077
6104
  autocomplete: [
6078
6105
  {
6079
6106
  description: "Use to create an constant binding.",
6080
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#const"
6107
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#const"
6081
6108
  }
6082
6109
  ],
6083
6110
  types: runtime_info_default.name + "/tags/const.d.marko"
@@ -6095,7 +6122,7 @@ var debug_default = {
6095
6122
  assertNoBodyContent(tag);
6096
6123
  if (tag.node.attributes.length > 1 || tag.node.attributes.length === 1 && (!import_compiler30.types.isMarkoAttribute(valueAttr) || !valueAttr.default && valueAttr.name !== "value")) {
6097
6124
  throw tag.get("name").buildCodeFrameError(
6098
- "The `debug` tag only supports the `value` attribute."
6125
+ "The [`<debug>` tag](https://next.markojs.com/docs/reference/core-tag#debug) only supports the [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
6099
6126
  );
6100
6127
  }
6101
6128
  },
@@ -6120,7 +6147,7 @@ var debug_default = {
6120
6147
  autocomplete: [
6121
6148
  {
6122
6149
  description: "Debug on value change.",
6123
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#debug"
6150
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#debug"
6124
6151
  }
6125
6152
  ],
6126
6153
  types: runtime_info_default.name + "/tags/debug.d.marko"
@@ -6307,7 +6334,7 @@ var native_tag_default = {
6307
6334
  const { node } = tag;
6308
6335
  if (node.var && !import_compiler32.types.isIdentifier(node.var)) {
6309
6336
  throw tag.get("var").buildCodeFrameError(
6310
- "Tag variables on native elements cannot be destructured."
6337
+ "Tag variables on [native tags](https://next.markojs.com/docs/reference/native-tag) cannot be destructured."
6311
6338
  );
6312
6339
  }
6313
6340
  const tagName = getTagName(tag);
@@ -7241,7 +7268,7 @@ var for_default = {
7241
7268
  break;
7242
7269
  default:
7243
7270
  throw tag.buildCodeFrameError(
7244
- "Invalid `for` tag, missing an `of=`, `in=`, `to=` attribute."
7271
+ "The [`<for>` tag](https://next.markojs.com/docs/reference/core-tag#for) requires an `of=`, `in=`, or `to=` attribute."
7245
7272
  );
7246
7273
  }
7247
7274
  if (!isAttrTag) {
@@ -7261,7 +7288,7 @@ var for_default = {
7261
7288
  getAllTagReferenceNodes(tag.node)
7262
7289
  );
7263
7290
  if (paramsBinding) {
7264
- setBindingValueExpr(paramsBinding, tagExtra);
7291
+ setBindingDownstream(paramsBinding, tagExtra);
7265
7292
  }
7266
7293
  bodySection.sectionAccessor = {
7267
7294
  binding: nodeBinding,
@@ -7451,15 +7478,15 @@ var for_default = {
7451
7478
  {
7452
7479
  snippet: "for|${1:value, index}| of=${3:array}",
7453
7480
  description: "Use to iterate over lists, object properties, or between ranges.",
7454
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#iterating-over-a-list"
7481
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#for"
7455
7482
  },
7456
7483
  {
7457
7484
  snippet: "for|${1:name, value}| in=${3:object}",
7458
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#iterating-over-an-objects-properties"
7485
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#for"
7459
7486
  },
7460
7487
  {
7461
7488
  snippet: "for|${1:index}| to=${2:number}",
7462
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#iterating-between-a-range-of-numbers"
7489
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#for"
7463
7490
  }
7464
7491
  ]
7465
7492
  };
@@ -7881,7 +7908,9 @@ var define_default = {
7881
7908
  analyze(tag) {
7882
7909
  (0, import_babel_utils29.assertNoArgs)(tag);
7883
7910
  if (!tag.node.var) {
7884
- throw tag.get("name").buildCodeFrameError("The `define` tag requires a tag variable.");
7911
+ throw tag.get("name").buildCodeFrameError(
7912
+ "The [`<define>` tag](https://next.markojs.com/docs/reference/core-tag#define) requires a [tag variable](https://next.markojs.com/docs/reference/language#tag-variables)."
7913
+ );
7885
7914
  }
7886
7915
  const tagBody = tag.get("body");
7887
7916
  const bodySection = startSection(tagBody);
@@ -7899,11 +7928,7 @@ var define_default = {
7899
7928
  getAllTagReferenceNodes(tag.node)
7900
7929
  );
7901
7930
  if (varBinding) {
7902
- setBindingValueExpr(varBinding, tagExtra);
7903
- tagExtra.downstream = {
7904
- bindings: varBinding,
7905
- excludeProperties: void 0
7906
- };
7931
+ setBindingDownstream(varBinding, tagExtra);
7907
7932
  }
7908
7933
  },
7909
7934
  translate: {
@@ -7946,7 +7971,7 @@ var define_default = {
7946
7971
  autocomplete: [
7947
7972
  {
7948
7973
  description: "Use to create a constant object binding that can be rendered.",
7949
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#define"
7974
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#define"
7950
7975
  }
7951
7976
  ],
7952
7977
  types: runtime_info_default.name + "/tags/define.d.marko"
@@ -8022,7 +8047,7 @@ var html_comment_default = {
8022
8047
  if (tagVar) {
8023
8048
  if (!import_compiler38.types.isIdentifier(tagVar)) {
8024
8049
  throw tag.get("var").buildCodeFrameError(
8025
- "The `html-comment` tag variable cannot be destructured."
8050
+ "The [`<html-comment>` tag](https://next.markojs.com/docs/reference/core-tag#html-comment) tag variable cannot be destructured."
8026
8051
  );
8027
8052
  }
8028
8053
  needsBinding = true;
@@ -8189,7 +8214,7 @@ var html_comment_default = {
8189
8214
  autocomplete: [
8190
8215
  {
8191
8216
  description: "Use to create an html comment that is not stripped from the output.",
8192
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#html-comment"
8217
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#html-comment"
8193
8218
  }
8194
8219
  ]
8195
8220
  };
@@ -8567,7 +8592,13 @@ var html_script_default = {
8567
8592
  parseOptions: {
8568
8593
  text: true,
8569
8594
  preserveWhitespace: true
8570
- }
8595
+ },
8596
+ autocomplete: [
8597
+ {
8598
+ description: "Use instead of `<script>` to render a native tag directly, without processing by Marko.",
8599
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#html-script--html-style"
8600
+ }
8601
+ ]
8571
8602
  };
8572
8603
  function getUsedAttrs2(tag) {
8573
8604
  const seen = {};
@@ -8980,7 +9011,13 @@ var html_style_default = {
8980
9011
  parseOptions: {
8981
9012
  text: true,
8982
9013
  preserveWhitespace: true
8983
- }
9014
+ },
9015
+ autocomplete: [
9016
+ {
9017
+ description: "Use instead of `<style>` to render a native tag directly, without processing by Marko.",
9018
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#html-script--html-style"
9019
+ }
9020
+ ]
8984
9021
  };
8985
9022
  function getUsedAttrs3(tag) {
8986
9023
  const seen = {};
@@ -9037,14 +9074,18 @@ var id_default = {
9037
9074
  (0, import_babel_utils35.assertNoAttributeTags)(tag);
9038
9075
  const { node } = tag;
9039
9076
  if (!node.var) {
9040
- throw tag.get("name").buildCodeFrameError("The `id` tag requires a tag variable.");
9077
+ throw tag.get("name").buildCodeFrameError(
9078
+ "The [`<id>` tag](https://next.markojs.com/docs/reference/core-tag#id) requires a [tag variable](https://next.markojs.com/docs/reference/language#tag-variables)."
9079
+ );
9041
9080
  }
9042
9081
  if (!import_compiler41.types.isIdentifier(node.var)) {
9043
- throw tag.get("var").buildCodeFrameError("The `id` tag cannot be destructured");
9082
+ throw tag.get("var").buildCodeFrameError(
9083
+ "The [`<id>` tag](https://next.markojs.com/docs/reference/core-tag#id) cannot be destructured."
9084
+ );
9044
9085
  }
9045
9086
  const binding = trackVarReferences(tag, 5 /* derived */);
9046
9087
  if (binding) {
9047
- setBindingValueExpr(binding, false);
9088
+ setBindingDownstream(binding, false);
9048
9089
  }
9049
9090
  },
9050
9091
  translate: {
@@ -9071,7 +9112,7 @@ var id_default = {
9071
9112
  displayText: "id/<name>",
9072
9113
  description: "Use to create a unique identifier.",
9073
9114
  snippet: "id/${1:name}",
9074
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#id"
9115
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#id"
9075
9116
  }
9076
9117
  ],
9077
9118
  types: runtime_info_default.name + "/tags/id.d.marko"
@@ -9304,7 +9345,7 @@ var IfTag = {
9304
9345
  {
9305
9346
  snippet: "if=${1:condition}",
9306
9347
  description: "Use to display content only if the condition is met.",
9307
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#if-else-if-else"
9348
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#if--else"
9308
9349
  }
9309
9350
  ]
9310
9351
  };
@@ -9314,7 +9355,7 @@ var ElseIfTag = {
9314
9355
  {
9315
9356
  snippet: "else-if=${1:condition}",
9316
9357
  description: "Use after an <if> or <else-if> tag to display content if those conditions do not match and this one does.",
9317
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#if-else-if-else"
9358
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#if--else"
9318
9359
  }
9319
9360
  ]
9320
9361
  };
@@ -9323,7 +9364,7 @@ var ElseTag = {
9323
9364
  autocomplete: [
9324
9365
  {
9325
9366
  description: "Use after an <if> or <else-if> tag to display content if those conditions do not match.",
9326
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#if-else-if-else"
9367
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#if--else"
9327
9368
  }
9328
9369
  ]
9329
9370
  };
@@ -9352,14 +9393,14 @@ function assertHasPrecedingCondition(tag) {
9352
9393
  while (prev.node && prev.isMarkoComment()) prev = prev.getPrevSibling();
9353
9394
  if (!isConditionTag(prev) || getTagName(prev) !== "else" && !prev.node.attributes.length) {
9354
9395
  throw tag.buildCodeFrameError(
9355
- `The \`<${getTagName(tag)}>\` must have a preceding \`<if=cond>\`, \`<else-if=cond>\`, or \`<else if=cond>\`.`
9396
+ `The [\`<${getTagName(tag)}>\` tag](https://next.markojs.com/docs/reference/core-tag#if--else) must have a preceding \`<if=cond>\` or \`<else if=cond>\`.`
9356
9397
  );
9357
9398
  }
9358
9399
  }
9359
9400
  function assertHasBody(tag) {
9360
9401
  if (!(tag.node.body.body.length || tag.node.attributeTags.length)) {
9361
9402
  throw tag.get("name").buildCodeFrameError(
9362
- `The \`${getTagName(tag)}\` tag requires body content.`
9403
+ `The [\`${getTagName(tag)}\` tag](https://next.markojs.com/docs/reference/core-tag#if--else) requires [body content](https://next.markojs.com/docs/reference/language#tag-content).`
9363
9404
  );
9364
9405
  }
9365
9406
  }
@@ -9367,12 +9408,14 @@ function assertHasValueAttribute(tag) {
9367
9408
  const { node } = tag;
9368
9409
  const [valueAttr] = node.attributes;
9369
9410
  if (!import_compiler43.types.isMarkoAttribute(valueAttr) || !valueAttr.default) {
9370
- throw tag.get("name").buildCodeFrameError(`The \`${getTagName(tag)}\` tag requires a value.`);
9411
+ throw tag.get("name").buildCodeFrameError(
9412
+ `The [\`${getTagName(tag)}\` tag](https://next.markojs.com/docs/reference/core-tag#if--else) requires a [\`value=\` attribute](https://next.markojs.com/docs/reference/language#shorthand-value).`
9413
+ );
9371
9414
  }
9372
9415
  if (node.attributes.length > 1) {
9373
9416
  const start = node.attributes[1].loc?.start;
9374
9417
  const end = node.attributes[node.attributes.length - 1].loc?.end;
9375
- const msg = `The \`${getTagName(tag)}\` tag only supports the \`value\` attribute.`;
9418
+ const msg = `The [\`${getTagName(tag)}\` tag](https://next.markojs.com/docs/reference/core-tag#if--else) only supports the [\`value=\` attribute](https://next.markojs.com/docs/reference/language#shorthand-value).`;
9376
9419
  if (start == null || end == null) {
9377
9420
  throw tag.get("name").buildCodeFrameError(msg);
9378
9421
  } else {
@@ -9390,7 +9433,7 @@ function assertOptionalIfAttribute(tag) {
9390
9433
  if (node.attributes.length > 1 || ifAttr && ifAttr.name !== "if") {
9391
9434
  const start = node.attributes[1].loc?.start;
9392
9435
  const end = node.attributes[node.attributes.length - 1].loc?.end;
9393
- const msg = `The \`${getTagName(tag)}\` tag only supports an \`if=\` attribute.`;
9436
+ const msg = `The [\`${getTagName(tag)}\` tag](https://next.markojs.com/docs/reference/core-tag#if--else) only supports an \`if=\` attribute.`;
9394
9437
  if (start == null || end == null) {
9395
9438
  throw tag.get("name").buildCodeFrameError(msg);
9396
9439
  } else {
@@ -9467,7 +9510,7 @@ var let_default = {
9467
9510
  } else {
9468
9511
  const start = attr2.loc?.start;
9469
9512
  const end = attr2.loc?.end;
9470
- const msg = "The `let` tag only supports the `value` attribute and its change handler.";
9513
+ const msg = "The [`<let>` tag](https://next.markojs.com/docs/reference/core-tag#let) only supports the [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value) and its change handler.";
9471
9514
  if (start == null || end == null) {
9472
9515
  throw tag.get("name").buildCodeFrameError(msg);
9473
9516
  } else {
@@ -9485,19 +9528,23 @@ var let_default = {
9485
9528
  assertNoBodyContent(tag);
9486
9529
  assertNoSpreadAttrs(tag);
9487
9530
  if (!tagVar) {
9488
- throw tag.get("name").buildCodeFrameError("The `let` tag requires a tag variable.");
9531
+ throw tag.get("name").buildCodeFrameError(
9532
+ "The [`<let>` tag](https://next.markojs.com/docs/reference/core-tag#let) requires a [tag variable](https://next.markojs.com/docs/reference/language#tag-variables)."
9533
+ );
9489
9534
  }
9490
9535
  if (!import_compiler44.types.isIdentifier(tagVar)) {
9491
- throw tag.get("var").buildCodeFrameError("The `let` tag variable cannot be destructured.");
9536
+ throw tag.get("var").buildCodeFrameError(
9537
+ "The [`<let>` tag](https://next.markojs.com/docs/reference/core-tag#let) variable cannot be destructured."
9538
+ );
9492
9539
  }
9493
9540
  if (valueChangeAttr && (0, import_babel_utils38.computeNode)(valueChangeAttr.value)) {
9494
9541
  throw tag.get("attributes").find((attr2) => attr2.node === valueChangeAttr).get("value").buildCodeFrameError(
9495
- "The `let` tag `valueChange` attribute must be a function."
9542
+ "The [`<let>` tag](https://next.markojs.com/docs/reference/core-tag#let) [`valueChange=` attribute](https://next.markojs.com/docs/reference/core-tag#controllable-let) must be a function."
9496
9543
  );
9497
9544
  }
9498
9545
  const tagSection = getOrCreateSection(tag);
9499
9546
  const binding = trackVarReferences(tag, 1 /* let */);
9500
- setBindingValueExpr(
9547
+ setBindingDownstream(
9501
9548
  binding,
9502
9549
  mergeReferences(tagSection, tag.node, [
9503
9550
  valueAttr?.value,
@@ -9556,7 +9603,7 @@ var let_default = {
9556
9603
  autocomplete: [
9557
9604
  {
9558
9605
  description: "Use to create a mutable binding.",
9559
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#let"
9606
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#let"
9560
9607
  }
9561
9608
  ],
9562
9609
  types: runtime_info_default.name + "/tags/let.d.marko"
@@ -9587,13 +9634,13 @@ var lifecycle_default = {
9587
9634
  binding.downstreamExpressions.add(tagExtra);
9588
9635
  if (node.attributes.length === 0) {
9589
9636
  throw tag.get("name").buildCodeFrameError(
9590
- "The `lifecycle` tag requires at least one attribute."
9637
+ "The [`<lifecycle>` tag](https://next.markojs.com/docs/reference/core-tag#lifecycle) requires at least one attribute."
9591
9638
  );
9592
9639
  }
9593
9640
  for (const attr2 of node.attributes) {
9594
9641
  if (import_compiler45.types.isMarkoSpreadAttribute(attr2)) {
9595
9642
  throw tag.get("name").buildCodeFrameError(
9596
- "The `lifecycle` tag does not support `...spread` attributes."
9643
+ "The [`<lifecycle>` tag](https://next.markojs.com/docs/reference/core-tag#lifecycle) does not support [`...spread` attributes](https://next.markojs.com/docs/reference/language#spread-attributes)."
9597
9644
  );
9598
9645
  }
9599
9646
  (attr2.value.extra ??= {}).isEffect = true;
@@ -9638,7 +9685,7 @@ var lifecycle_default = {
9638
9685
  autocomplete: [
9639
9686
  {
9640
9687
  description: "Use to create a side effects.",
9641
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#effect"
9688
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#lifecycle"
9642
9689
  }
9643
9690
  ],
9644
9691
  types: runtime_info_default.name + "/tags/lifecycle.d.marko"
@@ -9655,11 +9702,13 @@ var log_default = {
9655
9702
  (0, import_babel_utils40.assertNoParams)(tag);
9656
9703
  assertNoBodyContent(tag);
9657
9704
  if (!valueAttr) {
9658
- throw tag.get("name").buildCodeFrameError("The `log` tag requires a value.");
9705
+ throw tag.get("name").buildCodeFrameError(
9706
+ "The [`<log>` tag](https://next.markojs.com/docs/reference/core-tag#log) requires a [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
9707
+ );
9659
9708
  }
9660
9709
  if (tag.node.attributes.length > 1 || !import_compiler46.types.isMarkoAttribute(valueAttr) || !valueAttr.default && valueAttr.name !== "value") {
9661
9710
  throw tag.get("name").buildCodeFrameError(
9662
- "The `log` tag only supports the `value` attribute."
9711
+ "The [`<log>` tag](https://next.markojs.com/docs/reference/core-tag#log) only supports the [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
9663
9712
  );
9664
9713
  }
9665
9714
  },
@@ -9690,7 +9739,7 @@ var log_default = {
9690
9739
  autocomplete: [
9691
9740
  {
9692
9741
  description: "Use to log a value to the console.",
9693
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#log"
9742
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#log"
9694
9743
  }
9695
9744
  ],
9696
9745
  types: runtime_info_default.name + "/tags/log.d.marko"
@@ -9699,7 +9748,7 @@ var log_default = {
9699
9748
  // src/translator/core/script.ts
9700
9749
  var import_compiler47 = require("@marko/compiler");
9701
9750
  var import_babel_utils41 = require("@marko/compiler/babel-utils");
9702
- var htmlScriptTagAlternateMsg = " For a native html `script` tag use the `html-script` core tag instead.";
9751
+ var htmlScriptTagAlternateMsg = " For a native html [`<script>` tag](https://next.markojs.com/docs/reference/core-tag#script) use the `html-script` core tag instead.";
9703
9752
  var script_default = {
9704
9753
  parse(tag) {
9705
9754
  const { node } = tag;
@@ -9710,7 +9759,7 @@ var script_default = {
9710
9759
  if (child.type !== "MarkoText") {
9711
9760
  throw tag.hub.file.hub.buildError(
9712
9761
  child,
9713
- "Unexpected content in `script` tag. Only javascript and typescript is supported." + htmlScriptTagAlternateMsg,
9762
+ "Unexpected content in [`<script>` tag](https://next.markojs.com/docs/reference/core-tag#script). Only javascript and typescript is supported." + htmlScriptTagAlternateMsg,
9714
9763
  SyntaxError
9715
9764
  );
9716
9765
  }
@@ -9737,7 +9786,7 @@ var script_default = {
9737
9786
  if (node.var) {
9738
9787
  throw tag.hub.buildError(
9739
9788
  node.var,
9740
- "The `script` tag does not support a tag variable reference." + htmlScriptTagAlternateMsg
9789
+ "The [`<script>` tag](https://next.markojs.com/docs/reference/core-tag#script) does not support a tag variable reference." + htmlScriptTagAlternateMsg
9741
9790
  );
9742
9791
  }
9743
9792
  let seenValueAttr = false;
@@ -9752,7 +9801,7 @@ var script_default = {
9752
9801
  } else {
9753
9802
  throw tag.hub.buildError(
9754
9803
  attr2,
9755
- "The `script` tag does not support html attributes." + htmlScriptTagAlternateMsg
9804
+ "The [`<script>` tag](https://next.markojs.com/docs/reference/core-tag#script) does not support html attributes." + htmlScriptTagAlternateMsg
9756
9805
  );
9757
9806
  }
9758
9807
  }
@@ -9902,7 +9951,7 @@ var import_babel_utils44 = require("@marko/compiler/babel-utils");
9902
9951
  var import_magic_string = __toESM(require("magic-string"));
9903
9952
  var import_path3 = __toESM(require("path"));
9904
9953
  var STYLE_EXT_REG = /^style((?:\.[a-zA-Z0-9$_-]+)+)?/;
9905
- var htmlStyleTagAlternateMsg = " For a native html `style` tag use the `html-style` core tag instead.";
9954
+ var htmlStyleTagAlternateMsg = " For a native html [`<style>` tag](https://next.markojs.com/docs/reference/core-tag#style) use the `html-style` core tag instead.";
9906
9955
  var style_default = {
9907
9956
  analyze(tag) {
9908
9957
  (0, import_babel_utils44.assertNoArgs)(tag);
@@ -9923,14 +9972,14 @@ var style_default = {
9923
9972
  if (child.type !== "MarkoText") {
9924
9973
  throw tag.hub.buildError(
9925
9974
  child,
9926
- "The `style` tag currently only supports static content." + htmlStyleTagAlternateMsg
9975
+ "The [`<style>` tag](https://next.markojs.com/docs/reference/core-tag#style) currently only supports static content." + htmlStyleTagAlternateMsg
9927
9976
  );
9928
9977
  }
9929
9978
  }
9930
9979
  if (node.body.body.length > 1) {
9931
9980
  throw tag.hub.buildError(
9932
9981
  node.name,
9933
- "The `style` tag currently only supports static content." + htmlStyleTagAlternateMsg
9982
+ "The [`<style>` tag](https://next.markojs.com/docs/reference/core-tag#style) currently only supports static content." + htmlStyleTagAlternateMsg
9934
9983
  );
9935
9984
  }
9936
9985
  },
@@ -10025,7 +10074,9 @@ var try_default = {
10025
10074
  );
10026
10075
  tagExtra[kDOMBinding2] = createBinding("#text", 0 /* dom */, section);
10027
10076
  if (!tag.node.body.body.length) {
10028
- throw tag.get("name").buildCodeFrameError("The `try` tag requires body content.");
10077
+ throw tag.get("name").buildCodeFrameError(
10078
+ "The [`<try>` tag](https://next.markojs.com/docs/reference/core-tag#try) requires [body content](https://next.markojs.com/docs/reference/language#tag-content)."
10079
+ );
10029
10080
  }
10030
10081
  startSection(tag.get("body"));
10031
10082
  },
@@ -10131,7 +10182,7 @@ var try_default = {
10131
10182
  autocomplete: [
10132
10183
  {
10133
10184
  description: "Used to capture errors and display placeholders for nested content.",
10134
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#try"
10185
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#try"
10135
10186
  }
10136
10187
  ],
10137
10188
  types: runtime_info_default.name + "/tags/try.d.marko"
@@ -10578,7 +10629,9 @@ var attribute_tag_default = {
10578
10629
  startSection(body);
10579
10630
  trackParamsReferences(body, 3 /* param */);
10580
10631
  if (!(0, import_babel_utils48.findParentTag)(tag)) {
10581
- throw tag.get("name").buildCodeFrameError("@tags must be nested within another tag.");
10632
+ throw tag.get("name").buildCodeFrameError(
10633
+ "[Attribute tags](https://next.markojs.com/docs/reference/language#attribute-tags) must be nested within another tag."
10634
+ );
10582
10635
  }
10583
10636
  }
10584
10637
  },
@@ -10616,11 +10669,11 @@ var custom_tag_default = {
10616
10669
  const tagName = getTagName(tag);
10617
10670
  if (tagName && tag.scope.hasBinding(tagName)) {
10618
10671
  throw tag.get("name").buildCodeFrameError(
10619
- `Local variables must be in a dynamic tag unless they are PascalCase. Use \`<\${${tagName}}/>\` or rename to \`${tagName.charAt(0).toUpperCase() + tagName.slice(1)}\`.`
10672
+ `Local variables must be in a [dynamic tag](https://next.markojs.com/docs/reference/language#dynamic-tags) unless they are PascalCase. Use \`<\${${tagName}}/>\` or rename to \`${tagName.charAt(0).toUpperCase() + tagName.slice(1)}\`.`
10620
10673
  );
10621
10674
  }
10622
10675
  throw tag.get("name").buildCodeFrameError(
10623
- `Unable to find entry point for custom tag \`<${tagName}>\`.`
10676
+ `Unable to find entry point for [custom tag](https://next.markojs.com/docs/reference/custom-tag#relative-custom-tags) \`<${tagName}>\`.`
10624
10677
  );
10625
10678
  }
10626
10679
  const section = getOrCreateSection(tag);
@@ -10646,7 +10699,7 @@ var custom_tag_default = {
10646
10699
  mergeReferences(section, tag.node, getAllTagReferenceNodes(tag.node));
10647
10700
  if (varBinding) {
10648
10701
  const varSerializeReason = (0, import_babel_utils49.getProgram)().node.extra.returnValueExpr;
10649
- setBindingValueExpr(varBinding, varSerializeReason);
10702
+ setBindingDownstream(varBinding, varSerializeReason);
10650
10703
  addBindingSerializeReasonExpr(
10651
10704
  section,
10652
10705
  childScopeBinding,
@@ -10672,7 +10725,7 @@ var custom_tag_default = {
10672
10725
  childInputBinding,
10673
10726
  inputExpr
10674
10727
  );
10675
- setBindingValueExpr(varBinding, varSerializeReason);
10728
+ setBindingDownstream(varBinding, varSerializeReason);
10676
10729
  addBindingSerializeReasonExpr(
10677
10730
  section,
10678
10731
  childScopeBinding,
@@ -10959,11 +11012,11 @@ function getTagRelativePath(tag) {
10959
11012
  const tagName = getTagName(tag);
10960
11013
  if (tagName && tag.scope.hasBinding(tagName)) {
10961
11014
  throw tag.get("name").buildCodeFrameError(
10962
- `Local variables must be in a dynamic tag unless they are PascalCase. Use \`<\${${tagName}}/>\` or rename to \`${tagName.charAt(0).toUpperCase() + tagName.slice(1)}\`.`
11015
+ `Local variables must be in a [dynamic tag](https://next.markojs.com/docs/reference/language#dynamic-tags) unless they are PascalCase. Use \`<\${${tagName}}/>\` or rename to \`${tagName.charAt(0).toUpperCase() + tagName.slice(1)}\`.`
10963
11016
  );
10964
11017
  }
10965
11018
  throw tag.get("name").buildCodeFrameError(
10966
- `Unable to find entry point for custom tag \`<${tagName}>\`.`
11019
+ `Unable to find entry point for [custom tag](https://next.markojs.com/docs/reference/custom-tag#relative-custom-tags) \`<${tagName}>\`.`
10967
11020
  );
10968
11021
  }
10969
11022
  return relativePath;
@@ -10979,10 +11032,7 @@ function analyzeAttrs(rootTagExtra, section, tag, templateExport, rootAttrExprs,
10979
11032
  tag.node,
10980
11033
  getAllTagReferenceNodes(tag.node)
10981
11034
  );
10982
- extra.downstream = {
10983
- bindings: templateExport.binding,
10984
- excludeProperties: void 0
10985
- };
11035
+ setBindingDownstream(templateExport.binding, extra);
10986
11036
  return;
10987
11037
  }
10988
11038
  const known = inputExpr.known = {};
@@ -11065,10 +11115,9 @@ function analyzeAttrs(rootTagExtra, section, tag, templateExport, rootAttrExprs,
11065
11115
  bindings = bindingUtil.add(bindings, templateExportAttr.binding);
11066
11116
  }
11067
11117
  if (bindings) {
11068
- groupExtra.downstream = {
11069
- bindings,
11070
- excludeProperties: void 0
11071
- };
11118
+ forEach(bindings, (binding) => {
11119
+ setBindingDownstream(binding, groupExtra);
11120
+ });
11072
11121
  }
11073
11122
  for (const name2 of group) {
11074
11123
  known[attrTagLookup[name2].name] = groupKnownValue;
@@ -11094,10 +11143,10 @@ function analyzeAttrs(rootTagExtra, section, tag, templateExport, rootAttrExprs,
11094
11143
  continue;
11095
11144
  }
11096
11145
  seen.add(attr2.name);
11097
- (attr2.value.extra ??= {}).downstream = {
11098
- bindings: templateExportAttr.binding,
11099
- excludeProperties: void 0
11100
- };
11146
+ setBindingDownstream(
11147
+ templateExportAttr.binding,
11148
+ attr2.value.extra ??= {}
11149
+ );
11101
11150
  }
11102
11151
  if (spreadReferenceNodes) {
11103
11152
  spreadReferenceNodes.push(attr2.value);
@@ -11115,10 +11164,20 @@ function analyzeAttrs(rootTagExtra, section, tag, templateExport, rootAttrExprs,
11115
11164
  tag.node,
11116
11165
  spreadReferenceNodes
11117
11166
  );
11118
- extra.downstream = {
11119
- bindings: templateExport.binding,
11120
- excludeProperties: seen
11121
- };
11167
+ let spreadBinding = templateExport.binding;
11168
+ if (seen.size) {
11169
+ spreadBinding = createBinding(
11170
+ generateUid(`${getTagName(tag)}_attrs`),
11171
+ spreadBinding.type,
11172
+ spreadBinding.section,
11173
+ spreadBinding,
11174
+ void 0,
11175
+ fromIter(seen),
11176
+ spreadReferenceNodes[0].loc,
11177
+ true
11178
+ );
11179
+ }
11180
+ setBindingDownstream(spreadBinding, extra);
11122
11181
  }
11123
11182
  }
11124
11183
  function writeAttrsToExports(tag, templateExport, importAlias, info) {
@@ -11606,7 +11665,7 @@ var dynamic_tag_default = {
11606
11665
  ])
11607
11666
  );
11608
11667
  statements.push(
11609
- import_compiler57.types.variableDeclaration("const", [
11668
+ import_compiler57.types.variableDeclaration("let", [
11610
11669
  import_compiler57.types.variableDeclarator(node.var, dynamicTagExpr)
11611
11670
  ]),
11612
11671
  import_compiler57.types.expressionStatement(
@@ -11838,9 +11897,16 @@ function getChangeHandler(tag, attr2) {
11838
11897
  );
11839
11898
  const existingChangedAttr = BINDING_CHANGE_HANDLER.get(binding.identifier);
11840
11899
  if (!existingChangedAttr) {
11900
+ const bindingIdentifierPath = binding.path.getOuterBindingIdentifierPaths()[binding.identifier.name];
11901
+ const changeAttrExpr = bindingIdentifierPath ? bindingIdentifierPath.parentPath === binding.path ? buildChangeHandlerFunction(attr2.value) : bindingIdentifierPath.parentPath.isObjectProperty() ? getChangeHandlerFromObjectPattern(
11902
+ bindingIdentifierPath.parentPath
11903
+ ) : void 0 : void 0;
11904
+ if (!changeAttrExpr) {
11905
+ throw tag.hub.buildError(attr2.value, "Unable to bind to value.");
11906
+ }
11841
11907
  const changeHandlerAttr = import_compiler58.types.markoAttribute(
11842
11908
  changeAttrName,
11843
- buildChangeHandlerFunction(attr2.value)
11909
+ changeAttrExpr
11844
11910
  );
11845
11911
  BINDING_CHANGE_HANDLER.set(binding.identifier, changeHandlerAttr);
11846
11912
  return changeHandlerAttr;
@@ -11916,6 +11982,51 @@ function buildChangeHandlerFunction(id) {
11916
11982
  ])
11917
11983
  );
11918
11984
  }
11985
+ function getChangeHandlerFromObjectPattern(parent) {
11986
+ let changeKey;
11987
+ const pattern = parent.parentPath;
11988
+ if (parent.node.computed) {
11989
+ changeKey = generateUidIdentifier(`dynamicChange`);
11990
+ pattern.pushContainer(
11991
+ "properties",
11992
+ import_compiler58.types.objectProperty(
11993
+ import_compiler58.types.binaryExpression(
11994
+ "+",
11995
+ parent.get("key").node,
11996
+ import_compiler58.types.stringLiteral("Change")
11997
+ ),
11998
+ changeKey,
11999
+ true
12000
+ )
12001
+ );
12002
+ } else {
12003
+ const key = parent.get("key");
12004
+ const searchKey = `${getStringOrIdentifierValue(key)}Change`;
12005
+ for (const prop of pattern.get("properties")) {
12006
+ if (prop.isObjectProperty()) {
12007
+ const propKey = prop.get("key");
12008
+ const propValue = prop.get("value");
12009
+ if (!prop.node.computed && getStringOrIdentifierValue(propKey) === searchKey && propValue.isIdentifier()) {
12010
+ changeKey = propValue.node;
12011
+ break;
12012
+ }
12013
+ }
12014
+ }
12015
+ if (!changeKey) {
12016
+ pattern.unshiftContainer(
12017
+ "properties",
12018
+ import_compiler58.types.objectProperty(
12019
+ import_compiler58.types.stringLiteral(searchKey),
12020
+ changeKey = generateUidIdentifier(searchKey)
12021
+ )
12022
+ );
12023
+ }
12024
+ }
12025
+ return changeKey;
12026
+ }
12027
+ function getStringOrIdentifierValue(path5) {
12028
+ return path5.isStringLiteral() ? path5.node.value : path5.node.name;
12029
+ }
11919
12030
 
11920
12031
  // src/translator/visitors/text.ts
11921
12032
  var import_compiler59 = require("@marko/compiler");
@@ -1,5 +1,5 @@
1
1
  import { types as t } from "@marko/compiler";
2
- import { type Many, type OneMany, type Opt, Sorted } from "./optional";
2
+ import { type Many, type Opt, Sorted } from "./optional";
3
3
  import { type Section } from "./sections";
4
4
  declare const kIsInvoked: unique symbol;
5
5
  export declare const kBranchSerializeReason: unique symbol;
@@ -52,10 +52,7 @@ declare module "@marko/compiler/dist/types" {
52
52
  interface NodeExtra {
53
53
  section?: Section;
54
54
  referencedBindings?: ReferencedBindings;
55
- downstream?: {
56
- bindings: OneMany<Binding>;
57
- excludeProperties: undefined | Set<string>;
58
- };
55
+ downstream?: Opt<Binding>;
59
56
  binding?: Binding;
60
57
  assignment?: Binding;
61
58
  assignmentTo?: Binding;
@@ -89,7 +86,7 @@ export declare const intersectionMeta: WeakMap<Intersection, {
89
86
  id: number;
90
87
  scopeOffset: Binding | undefined;
91
88
  }>;
92
- export declare function setBindingValueExpr(binding: Binding, valueExpr: boolean | Opt<t.NodeExtra>): void;
89
+ export declare function setBindingDownstream(binding: Binding, expr: boolean | Opt<t.NodeExtra>): void;
93
90
  export declare function createSources(state: Sources["state"], input: Sources["input"]): Sources;
94
91
  export declare function compareSources(a: Sources, b: Sources): number;
95
92
  export declare function mergeSources(a: undefined | Sources, b: undefined | Sources): Sources | undefined;
@@ -125,4 +122,6 @@ export interface RegisteredFnExtra extends ReferencedExtra {
125
122
  }
126
123
  export declare function isRegisteredFnExtra(extra: t.NodeExtra | undefined): extra is RegisteredFnExtra;
127
124
  export declare function getCanonicalExtra<T extends t.NodeExtra>(extra: T): T;
125
+ export declare function couldSerializeExtra(extra: t.NodeExtra): boolean;
126
+ export declare function couldSerializeBinding(binding: Binding): boolean;
128
127
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "6.0.56",
3
+ "version": "6.0.58",
4
4
  "description": "Optimized runtime for Marko templates.",
5
5
  "keywords": [
6
6
  "api",