marko 6.3.14 → 6.3.16

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.
@@ -1146,62 +1146,67 @@ function analyzeTagNameType(tag, allowDynamic) {
1146
1146
  }
1147
1147
  function analyzeExpressionTagName(name, extra) {
1148
1148
  const pending = [name];
1149
+ const seen = /* @__PURE__ */ new Set();
1149
1150
  let path;
1150
1151
  let type;
1151
1152
  let nullable = false;
1152
1153
  let tagNameImported;
1153
1154
  let tagNameLoad;
1154
- while ((path = pending.pop()) && type !== 2) if (path.isConditionalExpression()) {
1155
- pending.push(path.get("consequent"));
1156
- if (path.node.alternate) pending.push(path.get("alternate"));
1157
- } else if (path.isLogicalExpression()) {
1158
- if (path.node.operator === "&&") nullable = true;
1159
- else pending.push(path.get("left"));
1160
- pending.push(path.get("right"));
1161
- } else if (path.isAssignmentExpression()) pending.push(path.get("right"));
1162
- else if (path.isBinaryExpression()) type = path.node.operator !== "+" || type === void 0 || type === 0 ? 0 : 2;
1163
- else if (path.isStringLiteral() || path.isTemplateLiteral()) type = type === void 0 || type === 0 ? 0 : 2;
1164
- else if (path.isNullLiteral()) nullable = true;
1165
- else if (path.isIdentifier()) {
1166
- if (path.node.name === "undefined") {
1167
- nullable = true;
1168
- continue;
1169
- }
1170
- const binding = path.scope.getBinding(path.node.name);
1171
- if (!binding) {
1172
- type = 2;
1173
- continue;
1174
- }
1175
- if (binding.kind === "module") {
1176
- const decl = binding.path.parent;
1177
- if (MARKO_FILE_REG.test(decl.source.value) && decl.specifiers.some((it) => _marko_compiler.types.isImportDefaultSpecifier(it))) {
1178
- const resolvedImport = decl.extra?.tagImport || decl.source.value;
1179
- if (type === void 0) {
1180
- type = 1;
1181
- tagNameImported = resolvedImport;
1182
- tagNameLoad = decl.extra?.loadImport;
1183
- } else if (type === 0) {
1184
- type = 2;
1185
- tagNameImported = void 0;
1186
- } else if (tagNameImported !== resolvedImport) tagNameImported = void 0;
1187
- } else type = 2;
1188
- continue;
1189
- }
1190
- const bindingTag = binding.path;
1191
- if (bindingTag.isMarkoTag() && binding.kind === "local") {
1192
- const bindingTagName = bindingTag.get("name").node.value;
1193
- if (bindingTagName === "const") {
1194
- pending.push(bindingTag.get("attributes")[0].get("value"));
1155
+ while ((path = pending.pop()) && type !== 2) {
1156
+ if (seen.has(path.node)) continue;
1157
+ seen.add(path.node);
1158
+ if (path.isConditionalExpression()) {
1159
+ pending.push(path.get("consequent"));
1160
+ if (path.node.alternate) pending.push(path.get("alternate"));
1161
+ } else if (path.isLogicalExpression()) {
1162
+ if (path.node.operator === "&&") nullable = true;
1163
+ else pending.push(path.get("left"));
1164
+ pending.push(path.get("right"));
1165
+ } else if (path.isAssignmentExpression()) pending.push(path.get("right"));
1166
+ else if (path.isBinaryExpression()) type = path.node.operator !== "+" || type === void 0 || type === 0 ? 0 : 2;
1167
+ else if (path.isStringLiteral() || path.isTemplateLiteral()) type = type === void 0 || type === 0 ? 0 : 2;
1168
+ else if (path.isNullLiteral()) nullable = true;
1169
+ else if (path.isIdentifier()) {
1170
+ if (path.node.name === "undefined") {
1171
+ nullable = true;
1195
1172
  continue;
1196
1173
  }
1197
- if (bindingTagName === "let") {
1174
+ const binding = path.scope.getBinding(path.node.name);
1175
+ if (!binding) {
1198
1176
  type = 2;
1199
1177
  continue;
1200
1178
  }
1201
- continue;
1202
- }
1203
- type = 2;
1204
- } else type = 2;
1179
+ if (binding.kind === "module") {
1180
+ const decl = binding.path.parent;
1181
+ if (MARKO_FILE_REG.test(decl.source.value) && decl.specifiers.some((it) => _marko_compiler.types.isImportDefaultSpecifier(it))) {
1182
+ const resolvedImport = decl.extra?.tagImport || decl.source.value;
1183
+ if (type === void 0) {
1184
+ type = 1;
1185
+ tagNameImported = resolvedImport;
1186
+ tagNameLoad = decl.extra?.loadImport;
1187
+ } else if (type === 0) {
1188
+ type = 2;
1189
+ tagNameImported = void 0;
1190
+ } else if (tagNameImported !== resolvedImport) tagNameImported = void 0;
1191
+ } else type = 2;
1192
+ continue;
1193
+ }
1194
+ const bindingTag = binding.path;
1195
+ if (bindingTag.isMarkoTag() && binding.kind === "local") {
1196
+ const bindingTagName = bindingTag.get("name").node.value;
1197
+ if (bindingTagName === "const") {
1198
+ pending.push(bindingTag.get("attributes")[0].get("value"));
1199
+ continue;
1200
+ }
1201
+ if (bindingTagName === "let") {
1202
+ type = 2;
1203
+ continue;
1204
+ }
1205
+ continue;
1206
+ }
1207
+ type = 2;
1208
+ } else type = 2;
1209
+ }
1205
1210
  extra.tagNameType = type ?? 2;
1206
1211
  extra.tagNameNullable = nullable;
1207
1212
  if (type === 1 && tagNameImported) {
@@ -1475,9 +1480,10 @@ function finalizeFunctionRegistry() {
1475
1480
  function canIgnoreRegister(markoRoot, exprRoot) {
1476
1481
  return markoRoot.isMarkoPlaceholder() || markoRoot.isMarkoScriptlet() && (!markoRoot.node.static || markoRoot.node.target === "server") || markoRoot.isMarkoTag() && markoRoot.node.name == exprRoot.node || isMarkoAttribute(markoRoot) && (analyzeTagNameType(markoRoot.parentPath) === 0 && /^on[A-Z-]/.test(markoRoot.node.name) && !hasSpreadAttributeAfter(markoRoot) || isCoreTagName(markoRoot.parentPath, "script") || isCoreTagName(markoRoot.parentPath, "lifecycle") || isCoreTagName(markoRoot.parentPath, "for"));
1477
1482
  }
1478
- function getStaticDeclRefs(fnExtra, path, refs = /* @__PURE__ */ new Set()) {
1483
+ function getStaticDeclRefs(fnExtra, path, refs = /* @__PURE__ */ new Set(), seen = /* @__PURE__ */ new Set()) {
1479
1484
  const decl = getDeclarationRoot(path);
1480
- if (decl) {
1485
+ if (decl && !seen.has(decl.node)) {
1486
+ seen.add(decl.node);
1481
1487
  const ids = decl.getOuterBindingIdentifiers();
1482
1488
  if (ids) for (const name in ids) {
1483
1489
  const binding = decl.scope.getBinding(name);
@@ -1488,7 +1494,7 @@ function getStaticDeclRefs(fnExtra, path, refs = /* @__PURE__ */ new Set()) {
1488
1494
  const markoRoot = getMarkoRoot(exprRoot);
1489
1495
  if (!markoRoot || canIgnoreRegister(markoRoot, exprRoot)) continue;
1490
1496
  if (isStaticRoot(markoRoot)) {
1491
- if (getStaticDeclRefs(fnExtra, ref, refs) === true) return true;
1497
+ if (getStaticDeclRefs(fnExtra, ref, refs, seen) === true) return true;
1492
1498
  } else if (shouldAlwaysRegister(markoRoot)) return true;
1493
1499
  else refs.add(exprRoot.node.extra ??= {});
1494
1500
  }
@@ -1754,13 +1760,14 @@ function getContext(key) {
1754
1760
  function getState() {
1755
1761
  return $chunk.boundary.state;
1756
1762
  }
1757
- function _html(html) {
1758
- $chunk.writeHTML(html);
1763
+ function getScopeById(scopeId) {
1764
+ if (scopeId !== void 0) return $chunk.boundary.state.scopes.get(scopeId);
1759
1765
  }
1760
- function _script(scopeId, registryId) {
1761
- if ($chunk.serializeState.readyId || $chunk.context?.[kIsAsync]) _resume_branch(scopeId);
1762
- $chunk.boundary.state.needsMainRuntime = true;
1763
- $chunk.writeEffect(scopeId, registryId);
1766
+ function _scope_id() {
1767
+ return $chunk.boundary.state.scopeId++;
1768
+ }
1769
+ function _peek_scope_id() {
1770
+ return $chunk.boundary.state.scopeId;
1764
1771
  }
1765
1772
  const kPendingContexts = Symbol("Pending Contexts");
1766
1773
  function withContext(key, value, cb, cbValue) {
@@ -1775,27 +1782,23 @@ function withContext(key, value, cb, cbValue) {
1775
1782
  ctx[key] = prev;
1776
1783
  }
1777
1784
  }
1778
- function _scope_id() {
1779
- return $chunk.boundary.state.scopeId++;
1780
- }
1781
- function _peek_scope_id() {
1782
- return $chunk.boundary.state.scopeId;
1785
+ const kBranchId = Symbol("Branch Id");
1786
+ const kIsAsync = Symbol("Is Async");
1787
+ function withBranchId(branchId, cb) {
1788
+ return withContext(kBranchId, branchId, cb);
1783
1789
  }
1784
- function getScopeById(scopeId) {
1785
- if (scopeId !== void 0) return $chunk.boundary.state.scopes.get(scopeId);
1790
+ function _html(html) {
1791
+ $chunk.writeHTML(html);
1786
1792
  }
1787
- function _set_serialize_reason(reason) {
1788
- $chunk.boundary.state.serializeReason = reason;
1793
+ function _script(scopeId, registryId) {
1794
+ if ($chunk.serializeState.readyId || $chunk.context?.[kIsAsync]) _resume_branch(scopeId);
1795
+ $chunk.boundary.state.needsMainRuntime = true;
1796
+ $chunk.writeEffect(scopeId, registryId);
1789
1797
  }
1790
1798
  function _resume_branch(scopeId) {
1791
1799
  const branchId = $chunk.context?.[kBranchId];
1792
1800
  if (branchId !== void 0 && branchId !== scopeId) writeScope(scopeId, { ["#ClosestBranchId"]: branchId });
1793
1801
  }
1794
- const kBranchId = Symbol("Branch Id");
1795
- const kIsAsync = Symbol("Is Async");
1796
- function withBranchId(branchId, cb) {
1797
- return withContext(kBranchId, branchId, cb);
1798
- }
1799
1802
  let writeScope = (scopeId, partialScope) => {
1800
1803
  const { state } = $chunk.boundary;
1801
1804
  const target = $chunk.serializeState;
@@ -1814,6 +1817,9 @@ function scopeWithId(state, scopeId) {
1814
1817
  if (!scope) scopes.set(scopeId, scope = { [K_SCOPE_ID]: scopeId });
1815
1818
  return scope;
1816
1819
  }
1820
+ function _set_serialize_reason(reason) {
1821
+ $chunk.boundary.state.serializeReason = reason;
1822
+ }
1817
1823
  globalThis.setImmediate || globalThis.setTimeout || globalThis.queueMicrotask;
1818
1824
  //#endregion
1819
1825
  //#region src/html/attrs.ts
@@ -1974,7 +1980,7 @@ function normalizedValueMatches(a, b) {
1974
1980
  return false;
1975
1981
  }
1976
1982
  function normalizeStrAttrValue(value) {
1977
- return value && value !== true || value === 0 ? value + "" : "";
1983
+ return isNotVoid(value) && value !== true ? value + "" : "";
1978
1984
  }
1979
1985
  //#endregion
1980
1986
  //#region src/html/dynamic-tag.ts
@@ -1989,25 +1995,28 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, s
1989
1995
  if (typeof renderer === "string") {
1990
1996
  const input = (inputIsArgs ? inputOrArgs[0] : inputOrArgs) || {};
1991
1997
  rendered = true;
1992
- _scope_id();
1993
- _html(`<${renderer}${_attrs(input, "a", branchId, renderer)}>`);
1994
- if (!voidElementsReg.test(renderer)) {
1995
- const renderContent = content || normalizeDynamicRenderer(input.content);
1996
- if (renderer === "textarea") _html(_attr_textarea_value(branchId, "a", input.value, input.valueChange, 1));
1997
- else if (renderContent) {
1998
- if (typeof renderContent !== "function") throw new Error(`Body content is not supported for the \`<${renderer}>\` tag.`);
1999
- if (renderer === "select" && ("value" in input || "valueChange" in input)) _attr_select_value(branchId, "a", input.value, input.valueChange, renderContent, 1);
2000
- else _dynamic_tag(branchId, "a", renderContent, void 0, 0, void 0, serializeReason);
2001
- }
2002
- _html(`</${renderer}>`);
2003
- }
2004
- const childScope = getScopeById(branchId);
2005
- const needsScript = childScope && (childScope["EventAttributes:a"] || childScope["ControlledHandler:a"]);
2006
- if (needsScript) {
2007
- writeScope(branchId, { ["#Renderer"]: renderer });
2008
- _script(branchId, "d");
2009
- }
2010
- if (shouldResume || needsScript) _html(state.mark("'", scopeId + " " + accessor + " " + branchId));
1998
+ const renderNative = () => {
1999
+ _scope_id();
2000
+ _html(`<${renderer}${_attrs(input, "a", branchId, renderer)}>`);
2001
+ if (!voidElementsReg.test(renderer)) {
2002
+ const renderContent = content || normalizeDynamicRenderer(input.content);
2003
+ if (renderer === "textarea") _html(_attr_textarea_value(branchId, "a", input.value, input.valueChange, 1));
2004
+ else if (renderContent) {
2005
+ if (typeof renderContent !== "function") throw new Error(`Body content is not supported for the \`<${renderer}>\` tag.`);
2006
+ if (renderer === "select" && ("value" in input || "valueChange" in input)) _attr_select_value(branchId, "a", input.value, input.valueChange, renderContent, 1);
2007
+ else _dynamic_tag(branchId, "a", renderContent, void 0, 0, void 0, serializeReason);
2008
+ }
2009
+ _html(`</${renderer}>`);
2010
+ }
2011
+ const childScope = getScopeById(branchId);
2012
+ const needsScript = childScope && (childScope["EventAttributes:a"] || childScope["ControlledHandler:a"]);
2013
+ if (needsScript) {
2014
+ writeScope(branchId, { ["#Renderer"]: renderer });
2015
+ _script(branchId, "d");
2016
+ }
2017
+ if (shouldResume || needsScript) _html(state.mark("'", scopeId + " " + accessor + " " + branchId));
2018
+ };
2019
+ renderNative();
2011
2020
  } else {
2012
2021
  if (shouldResume) _html(state.mark("[", ""));
2013
2022
  const render = () => {
@@ -2116,16 +2125,8 @@ function getCompatRuntimeFile() {
2116
2125
  //#endregion
2117
2126
  //#region src/translator/util/setup-statements.ts
2118
2127
  /**
2119
- * Tracks, during analyze, whether translate will add statements to a
2120
- * section's setup signal (the signal keyed by no referenced bindings).
2121
- * Sites that key statements by an expression's resolved references register
2122
- * the expression with `addSetupExpr`; sites that always target the setup
2123
- * signal call `addSetupStatement`. Expressions that resolve references
2124
- * through `mergeReferences` are covered centrally by `finalizeReferences`.
2125
- *
2126
- * This lets a template's analyze phase prove its setup export is a noop so
2127
- * parent templates can skip importing and calling it. The proof is checked
2128
- * when the template itself is translated (see `visitors/program/dom.ts`).
2128
+ * Tracks during analyze whether translate will add setup-signal statements, so a
2129
+ * template can prove its setup export is a noop and parents can skip calling it.
2129
2130
  */
2130
2131
  const [getSetupInfo] = createSectionState("setupStatements", () => ({
2131
2132
  forced: false,
@@ -2298,7 +2299,10 @@ function getScopeReasonDeclaration(section) {
2298
2299
  return _marko_compiler.types.variableDeclaration("const", getSectionReasonState(section).declarators);
2299
2300
  }
2300
2301
  function getSerializeGuard(section, reason, optional) {
2301
- if (!isReasonDynamic(reason) || isCrossSection(section, reason)) return reason ? optional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason === true ? void 0 : reason.state)) : _marko_compiler.types.numericLiteral(0);
2302
+ if (!isReasonDynamic(reason) || isCrossSection(section, reason)) {
2303
+ if (!reason) return _marko_compiler.types.numericLiteral(0);
2304
+ return optional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason === true ? void 0 : reason.state));
2305
+ }
2302
2306
  return getOrHoist(reason, true);
2303
2307
  }
2304
2308
  function getSerializeGuardForAny(section, reasons, optional) {
@@ -2892,7 +2896,6 @@ function getSignal(section, referencedBindings, name) {
2892
2896
  build: void 0,
2893
2897
  export: !!exportName,
2894
2898
  hasSideEffect: !!(referencedBindings && (Array.isArray(referencedBindings) || referencedBindings.type === 0 || referencedBindings.type === 1 || referencedBindings.section !== section || referencedBindings.closureSections || referencedBindings.hoists)),
2895
- hasDynamicSubscribers: false,
2896
2899
  forcePersist: false,
2897
2900
  inline: void 0,
2898
2901
  extraArgs: void 0,
@@ -3013,12 +3016,14 @@ function getSignalFn(signal) {
3013
3016
  }
3014
3017
  for (const value of signal.values) {
3015
3018
  if (value.signal.inline) continue;
3016
- if (signalHasStatements(value.signal)) signal.render.push(_marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(value.signal.identifier, [
3017
- scopeIdentifier,
3018
- value.value,
3019
- ...getTranslatedExtraArgs(value.signal)
3020
- ])));
3021
- else signal.render.push(_marko_compiler.types.expressionStatement(withLeadingComment(value.value, getDebugNames(value.signal.referencedBindings))));
3019
+ if (signalHasStatements(value.signal)) {
3020
+ const invocation = _marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(value.signal.identifier, [
3021
+ scopeIdentifier,
3022
+ value.value,
3023
+ ...getTranslatedExtraArgs(value.signal)
3024
+ ]));
3025
+ signal.render.push(invocation);
3026
+ } else signal.render.push(_marko_compiler.types.expressionStatement(withLeadingComment(value.value, getDebugNames(value.signal.referencedBindings))));
3022
3027
  }
3023
3028
  forEach(signal.intersection, (intersection) => {
3024
3029
  signal.render.push(_marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(intersection.identifier, [scopeIdentifier])));
@@ -3150,13 +3155,16 @@ function addValue(targetSection, referencedBindings, signal, value) {
3150
3155
  });
3151
3156
  if (value.extra?.referencedBindingsInFunction) parentSignal.hasSideEffect = true;
3152
3157
  }
3153
- function getResumeRegisterId(section, referencedBindings, type) {
3154
- const { markoOpts, opts: { filename } } = (0, _marko_compiler_babel_utils.getFile)();
3158
+ function buildResumeRegisterKey(section, referencedBindings, type) {
3155
3159
  let name = "";
3156
3160
  if (referencedBindings) if (typeof referencedBindings === "string") name += `_${referencedBindings}`;
3157
3161
  else if (Array.isArray(referencedBindings)) for (const ref of referencedBindings) name += `_${ref.name}`;
3158
3162
  else name += `_${referencedBindings.name}`;
3159
- return (0, _marko_compiler_babel_utils.getTemplateId)(markoOpts, filename, `${section.id}${name}${type ? "/" + type : ""}`);
3163
+ return `${section.id}${name}${type ? "/" + type : ""}`;
3164
+ }
3165
+ function getResumeRegisterId(section, referencedBindings, type) {
3166
+ const { markoOpts, opts: { filename } } = (0, _marko_compiler_babel_utils.getFile)();
3167
+ return (0, _marko_compiler_babel_utils.getTemplateId)(markoOpts, filename, buildResumeRegisterKey(section, referencedBindings, type));
3160
3168
  }
3161
3169
  function writeSignals(section) {
3162
3170
  const seen = /* @__PURE__ */ new Set();
@@ -3175,7 +3183,8 @@ function writeSignals(section) {
3175
3183
  if (signal.effect.length) {
3176
3184
  traverseReplace(signal, "effect", replaceEffectNode);
3177
3185
  const effectIdentifier = _marko_compiler.types.identifier(`${signal.identifier.name}__script`);
3178
- effectDeclarator = _marko_compiler.types.variableDeclarator(effectIdentifier, callRuntime("_script", _marko_compiler.types.stringLiteral(getResumeRegisterId(section, signal.referencedBindings)), _marko_compiler.types.arrowFunctionExpression([scopeIdentifier], toFirstExpressionOrBlock(signal.effect))));
3186
+ const effectFn = _marko_compiler.types.arrowFunctionExpression([scopeIdentifier], toFirstExpressionOrBlock(signal.effect));
3187
+ effectDeclarator = _marko_compiler.types.variableDeclarator(effectIdentifier, callRuntime("_script", _marko_compiler.types.stringLiteral(getResumeRegisterId(section, signal.referencedBindings)), effectFn));
3179
3188
  }
3180
3189
  let signalDeclaration;
3181
3190
  if (signal.build) {
@@ -3791,7 +3800,7 @@ var for_default = {
3791
3800
  "step"
3792
3801
  ];
3793
3802
  break;
3794
- default: throw tag.buildCodeFrameError("The [`<for>` tag](https://markojs.com/docs/reference/core-tag#for) requires an `of=`, `in=`, or `to=` attribute.");
3803
+ default: throw tag.buildCodeFrameError("The [`<for>` tag](https://markojs.com/docs/reference/core-tag#for) requires an `of=`, `in=`, `to=`, or `until=` attribute.");
3795
3804
  }
3796
3805
  if (!isAttrTag) allowAttrs.push("by");
3797
3806
  const keyAttr = tag.node.attributes.find((attr) => attr.type === "MarkoAttribute" && attr.name === "key");
@@ -4344,6 +4353,10 @@ var native_tag_default = {
4344
4353
  const valueExtra = attr.value.extra ??= {};
4345
4354
  if (_marko_compiler.types.isMarkoAttribute(attr)) {
4346
4355
  if (seen[attr.name]) {
4356
+ (0, _marko_compiler_babel_utils.diagnosticWarn)(tag, {
4357
+ label: `The \`${attr.name}\` attribute is set more than once on \`<${tagName}>\`; only the last value is used.`,
4358
+ loc: attr.loc ?? void 0
4359
+ });
4347
4360
  dropNodes(attr.value);
4348
4361
  continue;
4349
4362
  }
@@ -4385,7 +4398,7 @@ var native_tag_default = {
4385
4398
  if (node.var || hasDynamicAttributes || hasEventHandlers || textPlaceholders || injectNonce || isDynamicControllable(relatedControllable)) {
4386
4399
  const tagExtra = node.extra ??= {};
4387
4400
  const tagSection = getOrCreateSection(tag);
4388
- const nodeBinding = tagExtra[kNativeTagBinding] = createBinding("#" + tagName, 0, tagSection, void 0, void 0, void 0, void 0, !!node.var);
4401
+ const nodeBinding = tagExtra[kNativeTagBinding] = createBinding("#" + tagName.toLowerCase(), 0, tagSection, void 0, void 0, void 0, void 0, !!node.var);
4389
4402
  if (hasEventHandlers) (0, _marko_compiler_babel_utils.getProgram)().node.extra.isInteractive = true;
4390
4403
  if (spreadReferenceNodes) {
4391
4404
  const isMergedSpread = !!relatedControllable;
@@ -5055,7 +5068,7 @@ function getOptimizedOnlyChildNodeBinding(tag, section, branchSize = 1) {
5055
5068
  if (getOnlyChildParentTagName(tag, branchSize)) {
5056
5069
  const parentTag = getParentTag(tag).node;
5057
5070
  const parentTagName = parentTag.name?.value;
5058
- return (parentTag.extra ??= {})[kNativeTagBinding] ??= createBinding("#" + parentTagName, 0, section);
5071
+ return (parentTag.extra ??= {})[kNativeTagBinding] ??= createBinding("#" + parentTagName.toLowerCase(), 0, section);
5059
5072
  } else return (tag.node.extra ??= {})[kNodeRef] ??= createBinding("#text", 0, section);
5060
5073
  }
5061
5074
  //#endregion
@@ -5350,6 +5363,8 @@ function isRoot(tag) {
5350
5363
  //#region src/translator/core/textarea.ts
5351
5364
  function preAnalyze$1(tag) {
5352
5365
  if (tag.node.body.body.length) {
5366
+ const [firstChild] = tag.node.body.body;
5367
+ if (firstChild.type === "MarkoText") firstChild.value = firstChild.value.replace(/^\r?\n/, "");
5353
5368
  const parts = [];
5354
5369
  for (const child of tag.node.body.body) if (child.type === "MarkoText" || child.type === "MarkoPlaceholder" && child.escape) parts.push(child.value);
5355
5370
  else throw tag.hub.file.hub.buildError(child, "Unexpected content in textarea, only text and placeholders are supported.", SyntaxError);
@@ -5590,9 +5605,6 @@ function buildUndefined() {
5590
5605
  //#endregion
5591
5606
  //#region src/translator/visitors/program/index.ts
5592
5607
  let scopeIdentifier;
5593
- function isScopeIdentifier(node) {
5594
- return node === scopeIdentifier;
5595
- }
5596
5608
  var program_default = {
5597
5609
  migrate: {
5598
5610
  enter(program) {
@@ -5910,7 +5922,7 @@ function analyzeParams(rootTagExtra, section, tag, propTree, rootAttrExprs) {
5910
5922
  dropNodes(getAllTagReferenceNodes(tag.node));
5911
5923
  return inputExpr;
5912
5924
  }
5913
- if (!propTree.props || tag.node.arguments?.some((node) => _marko_compiler.types.isSpreadElement(node))) {
5925
+ if (!propTree.props || propTree.rest || tag.node.arguments?.some((node) => _marko_compiler.types.isSpreadElement(node))) {
5914
5926
  const extra = inputExpr.value = mergeReferences(section, tag.node, getAllTagReferenceNodes(tag.node));
5915
5927
  setBindingDownstream(propTree.binding, extra);
5916
5928
  return inputExpr;
@@ -5918,14 +5930,13 @@ function analyzeParams(rootTagExtra, section, tag, propTree, rootAttrExprs) {
5918
5930
  const known = inputExpr.known = {};
5919
5931
  let i = 0;
5920
5932
  if (tag.node.arguments) for (const arg of tag.node.arguments) {
5921
- if (!propTree.props[i]) {
5922
- dropNodes(arg);
5923
- continue;
5924
- }
5925
- const argValueExtra = arg.extra ??= {};
5926
- known[i++] = { value: argValueExtra };
5927
- rootAttrExprs.add(argValueExtra);
5928
- addSetupExpr(section, arg);
5933
+ if (propTree.props[i]) {
5934
+ const argValueExtra = arg.extra ??= {};
5935
+ known[i] = { value: argValueExtra };
5936
+ rootAttrExprs.add(argValueExtra);
5937
+ addSetupExpr(section, arg);
5938
+ } else dropNodes(arg);
5939
+ i++;
5929
5940
  }
5930
5941
  const attrPropsTree = propTree.props[i];
5931
5942
  if (attrPropsTree) known[i] = analyzeAttrs(rootTagExtra, section, tag, attrPropsTree, rootAttrExprs);
@@ -6100,7 +6111,7 @@ function getSingleKnownSpread(attributes) {
6100
6111
  };
6101
6112
  }
6102
6113
  function writeParamsToSignals(tag, propTree, importAlias, info) {
6103
- if (!propTree.props || tag.node.arguments?.some((node) => _marko_compiler.types.isSpreadElement(node))) {
6114
+ if (!propTree.props || propTree.rest || tag.node.arguments?.some((node) => _marko_compiler.types.isSpreadElement(node))) {
6104
6115
  const referencedBindings = tag.node.extra?.referencedBindings;
6105
6116
  const tagInputIdentifier = info.getBindingIdentifier(propTree.binding, `${importAlias}_params`);
6106
6117
  const translatedAttrs = translateAttrs(tag);
@@ -7198,8 +7209,7 @@ function getSectionInstancesAccessor(section) {
7198
7209
  return section.sectionAccessor ? section.sectionAccessor.prefix + getScopeAccessor(section.sectionAccessor.binding) : getAccessorPrefix().ClosureScopes + section.id;
7199
7210
  }
7200
7211
  function getSectionInstancesAccessorLiteral(section) {
7201
- const accessor = getSectionInstancesAccessor(section);
7202
- return accessor ? typeof accessor === "number" ? _marko_compiler.types.numericLiteral(accessor) : _marko_compiler.types.stringLiteral(accessor) : void 0;
7212
+ return _marko_compiler.types.stringLiteral(getSectionInstancesAccessor(section));
7203
7213
  }
7204
7214
  function getReadReplacement(node, signal) {
7205
7215
  const { extra } = node;
@@ -7643,6 +7653,17 @@ var await_default = {
7643
7653
  types: runtime_info_default.name + "/tags/await.d.marko"
7644
7654
  };
7645
7655
  //#endregion
7656
+ //#region src/translator/core/class.ts
7657
+ var class_default = {
7658
+ parse(tag) {
7659
+ throw tag.hub.buildError(tag.node.name, "class {} component blocks are no longer supported. Use <let> and <const> tags for state.");
7660
+ },
7661
+ parseOptions: {
7662
+ statement: true,
7663
+ rawOpenTag: true
7664
+ }
7665
+ };
7666
+ //#endregion
7646
7667
  //#region src/translator/core/client.ts
7647
7668
  var client_default = {
7648
7669
  parse(tag) {
@@ -8234,9 +8255,7 @@ var script_default = {
8234
8255
  if (isOutputDOM()) {
8235
8256
  const isFunction = _marko_compiler.types.isFunctionExpression(value) || _marko_compiler.types.isArrowFunctionExpression(value);
8236
8257
  let inlineBody = null;
8237
- let referencesScope = false;
8238
- if (isFunction) if (value.async || value.generator) referencesScope = traverseContains(value, isScopeIdentifier);
8239
- else if (_marko_compiler.types.isBlockStatement(value.body)) {
8258
+ if (isFunction) if (value.async || value.generator) {} else if (_marko_compiler.types.isBlockStatement(value.body)) {
8240
8259
  if (!traverseContains(value.body, isReturnStatement)) {
8241
8260
  let hasDeclaration = false;
8242
8261
  for (const child of value.body.body) if (_marko_compiler.types.isDeclaration(child)) {
@@ -8246,7 +8265,7 @@ var script_default = {
8246
8265
  inlineBody = hasDeclaration ? value.body : value.body.body;
8247
8266
  }
8248
8267
  } else inlineBody = _marko_compiler.types.expressionStatement(value.body);
8249
- addStatement("effect", section, referencedBindings, inlineBody || _marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(value, referencesScope ? [scopeIdentifier] : [])));
8268
+ addStatement("effect", section, referencedBindings, inlineBody || _marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(value, [])));
8250
8269
  } else addHTMLEffectCall(section, referencedBindings);
8251
8270
  tag.remove();
8252
8271
  } },
@@ -8558,6 +8577,7 @@ const cssGluedBefore = /[\w%]$/;
8558
8577
  //#region src/translator/core/style.ts
8559
8578
  const STYLE_EXT_REG = /^style((?:\.[a-zA-Z0-9$_-]+)+)?/;
8560
8579
  const programStyleCounts = /* @__PURE__ */ new WeakMap();
8580
+ const programDynamicStyleNameCounts = /* @__PURE__ */ new WeakMap();
8561
8581
  var style_default = {
8562
8582
  analyze(tag) {
8563
8583
  (0, _marko_compiler_babel_utils.assertNoArgs)(tag);
@@ -8604,25 +8624,14 @@ function analyzeDynamicStyle(tag, names) {
8604
8624
  }
8605
8625
  function collectDynamicStyleNames(tag) {
8606
8626
  let names;
8607
- let index = 0;
8608
8627
  for (const child of tag.node.body.body) if (_marko_compiler.types.isMarkoPlaceholder(child)) {
8609
- if (!names) {
8610
- names = [];
8611
- index = dynamicStyleNameOffset(tag);
8612
- }
8613
- names.push(dynamicStyleName(tag, index++));
8628
+ const program = (0, _marko_compiler_babel_utils.getProgram)().node;
8629
+ const index = programDynamicStyleNameCounts.get(program) ?? 0;
8630
+ programDynamicStyleNameCounts.set(program, index + 1);
8631
+ (names ??= []).push(dynamicStyleName(tag, index));
8614
8632
  } else if (!_marko_compiler.types.isMarkoText(child)) throw tag.hub.buildError(child, "The [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) only supports text and `${...}` interpolations. For a native html [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) use the `html-style` core tag instead.");
8615
8633
  return names;
8616
8634
  }
8617
- function dynamicStyleNameOffset(tag) {
8618
- const { start } = tag.node;
8619
- let offset = 0;
8620
- if (start != null) _marko_compiler.types.traverseFast((0, _marko_compiler_babel_utils.getProgram)().node, (node) => {
8621
- const dynamicStyle = node.extra?.dynamicStyle;
8622
- if (dynamicStyle && node.start != null && node.start < start) offset += dynamicStyle.names.length;
8623
- });
8624
- return offset;
8625
- }
8626
8635
  const styleNameUnsafeReg = /[^a-zA-Z0-9_]/g;
8627
8636
  const encodeStyleNameChar = (c) => "-" + c.charCodeAt(0).toString(36);
8628
8637
  function dynamicStyleName(tag, index) {
@@ -8706,9 +8715,8 @@ function buildStyleDecls(node) {
8706
8715
  return normalizeStringExpression(parts);
8707
8716
  }
8708
8717
  /**
8709
- * Resolves a `<style>` block's text content to its client side import path
8710
- * (eg `./template.marko.css`) by handing the css off to the configured
8711
- * `resolveVirtualDependency` hook.
8718
+ * Resolves a `<style>` block's text to its client-side import path by handing
8719
+ * the css to the configured `resolveVirtualDependency` hook.
8712
8720
  */
8713
8721
  function getStyleImportPath(file, node, names) {
8714
8722
  const { resolveVirtualDependency, sourceMaps } = file.markoOpts;
@@ -8849,6 +8857,7 @@ var core_default = {
8849
8857
  taglibId: runtime_info_default.taglibId,
8850
8858
  "<attrs>": attrs_default,
8851
8859
  "<await>": await_default,
8860
+ "<class>": class_default,
8852
8861
  "<client>": client_default,
8853
8862
  "<const>": const_default,
8854
8863
  "<debug>": debug_default,
@@ -154,7 +154,7 @@ export declare function getDebugName(binding: Binding): string;
154
154
  export declare function getDebugNames(refs: ReferencedBindings): string;
155
155
  export declare function getDebugNamesAsIdentifier(refs: ReferencedBindings): string;
156
156
  export declare function getSectionInstancesAccessor(section: Section): string;
157
- export declare function getSectionInstancesAccessorLiteral(section: Section): t.NumericLiteral | t.StringLiteral | undefined;
157
+ export declare function getSectionInstancesAccessorLiteral(section: Section): t.StringLiteral;
158
158
  export declare function getReadReplacement(node: t.Identifier | t.MemberExpression | t.OptionalMemberExpression, signal?: Signal): t.Expression | undefined;
159
159
  export declare function isInvokeOnlyBinding(binding: Binding): boolean;
160
160
  export declare function hasNonConstantPropertyAlias(ref: Binding): boolean;
@@ -18,7 +18,6 @@ export interface Signal {
18
18
  renderReferencedBindings: ReferencedBindings;
19
19
  effect: t.Statement[];
20
20
  effectReferencedBindings: ReferencedBindings;
21
- hasDynamicSubscribers: boolean;
22
21
  hasSideEffect: boolean;
23
22
  forcePersist: boolean;
24
23
  inline: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "6.3.14",
3
+ "version": "6.3.16",
4
4
  "description": "Optimized runtime for Marko templates.",
5
5
  "keywords": [
6
6
  "api",