marko 6.0.0-next.3.31 → 6.0.0-next.3.33

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.
@@ -68,6 +68,7 @@ __export(html_exports, {
68
68
  resumeSingleNodeForIn: () => resumeSingleNodeForIn,
69
69
  resumeSingleNodeForOf: () => resumeSingleNodeForOf,
70
70
  resumeSingleNodeForTo: () => resumeSingleNodeForTo,
71
+ setTagVar: () => setTagVar,
71
72
  styleAttr: () => styleAttr,
72
73
  toString: () => toString,
73
74
  tryContent: () => tryContent,
@@ -741,20 +742,27 @@ function writeRegistered(state, val, parent, accessor, { access, scope }) {
741
742
  );
742
743
  state.refs.set(val, fnRef);
743
744
  if (scopeRef) {
744
- const scopeId = ensureId(state, scopeRef);
745
745
  if (isCircular(parent, scopeRef)) {
746
746
  state.assigned.add(fnRef);
747
- fnRef.init = access + "(" + scopeId + ")";
747
+ fnRef.init = access + "(" + ensureId(state, scopeRef) + ")";
748
748
  fnRef.assigns += ensureId(state, parent) + toAccess(accessor) + "=";
749
749
  return false;
750
750
  }
751
- state.buf.push(access + "(" + scopeId + ")");
751
+ state.buf.push(access + "(" + ensureId(state, scopeRef) + ")");
752
752
  } else {
753
- state.buf.push(access + "(");
753
+ const pos = state.buf.push("");
754
+ const assigns = state.assigned.size;
754
755
  writeProp(state, scope, parent, "");
755
- const scopeRef2 = state.refs.get(scope);
756
- if (scopeRef2) ensureId(state, scopeRef2);
757
- state.buf.push(")");
756
+ const scopeRef2 = parent && state.refs.get(scope);
757
+ const scopeId = scopeRef2 && ensureId(state, scopeRef2);
758
+ if (scopeId && assigns !== state.assigned.size) {
759
+ state.assigned.add(fnRef);
760
+ fnRef.init = access + "(" + scopeId + ")";
761
+ fnRef.assigns += ensureId(state, parent) + toAccess(accessor) + "=";
762
+ } else {
763
+ state.buf[pos - 2] += access + "(";
764
+ state.buf.push(")");
765
+ }
758
766
  }
759
767
  } else {
760
768
  state.buf.push(access);
@@ -1537,6 +1545,13 @@ function withContext(key, value, cb) {
1537
1545
  ctx[key] = prev;
1538
1546
  }
1539
1547
  }
1548
+ function setTagVar(parentScopeId, childScope, registryId) {
1549
+ childScope["/" /* TagVariable */] = register2(
1550
+ {},
1551
+ registryId,
1552
+ parentScopeId
1553
+ );
1554
+ }
1540
1555
  function register2(val, id, scopeId) {
1541
1556
  return scopeId === void 0 ? register(id, val) : register(id, val, ensureScopeWithId(scopeId));
1542
1557
  }
@@ -2481,7 +2496,7 @@ var DEFAULT_RENDER_ID = "_";
2481
2496
 
2482
2497
  // src/html/dynamic-tag.ts
2483
2498
  var voidElementsReg = /^(?:area|b(?:ase|r)|col|embed|hr|i(?:mg|nput)|link|meta|param|source|track|wbr)$/;
2484
- function dynamicTagInput(scopeId, accessor, tag, input, content, tagVar) {
2499
+ function dynamicTagInput(scopeId, accessor, tag, input, content) {
2485
2500
  if (!tag && !content) {
2486
2501
  nextScopeId();
2487
2502
  return;
@@ -2542,7 +2557,7 @@ function dynamicTagInput(scopeId, accessor, tag, input, content, tagVar) {
2542
2557
  let result;
2543
2558
  resumeConditional(
2544
2559
  () => {
2545
- result = renderer(content ? { ...input, content } : input, tagVar);
2560
+ result = renderer(content ? { ...input, content } : input);
2546
2561
  },
2547
2562
  scopeId,
2548
2563
  accessor
@@ -2981,6 +2996,7 @@ function NOOP2() {
2981
2996
  resumeSingleNodeForIn,
2982
2997
  resumeSingleNodeForOf,
2983
2998
  resumeSingleNodeForTo,
2999
+ setTagVar,
2984
3000
  styleAttr,
2985
3001
  toString,
2986
3002
  tryContent,
@@ -660,20 +660,27 @@ function writeRegistered(state, val, parent, accessor, { access, scope }) {
660
660
  );
661
661
  state.refs.set(val, fnRef);
662
662
  if (scopeRef) {
663
- const scopeId = ensureId(state, scopeRef);
664
663
  if (isCircular(parent, scopeRef)) {
665
664
  state.assigned.add(fnRef);
666
- fnRef.init = access + "(" + scopeId + ")";
665
+ fnRef.init = access + "(" + ensureId(state, scopeRef) + ")";
667
666
  fnRef.assigns += ensureId(state, parent) + toAccess(accessor) + "=";
668
667
  return false;
669
668
  }
670
- state.buf.push(access + "(" + scopeId + ")");
669
+ state.buf.push(access + "(" + ensureId(state, scopeRef) + ")");
671
670
  } else {
672
- state.buf.push(access + "(");
671
+ const pos = state.buf.push("");
672
+ const assigns = state.assigned.size;
673
673
  writeProp(state, scope, parent, "");
674
- const scopeRef2 = state.refs.get(scope);
675
- if (scopeRef2) ensureId(state, scopeRef2);
676
- state.buf.push(")");
674
+ const scopeRef2 = parent && state.refs.get(scope);
675
+ const scopeId = scopeRef2 && ensureId(state, scopeRef2);
676
+ if (scopeId && assigns !== state.assigned.size) {
677
+ state.assigned.add(fnRef);
678
+ fnRef.init = access + "(" + scopeId + ")";
679
+ fnRef.assigns += ensureId(state, parent) + toAccess(accessor) + "=";
680
+ } else {
681
+ state.buf[pos - 2] += access + "(";
682
+ state.buf.push(")");
683
+ }
677
684
  }
678
685
  } else {
679
686
  state.buf.push(access);
@@ -1456,6 +1463,13 @@ function withContext(key, value, cb) {
1456
1463
  ctx[key] = prev;
1457
1464
  }
1458
1465
  }
1466
+ function setTagVar(parentScopeId, childScope, registryId) {
1467
+ childScope["/" /* TagVariable */] = register2(
1468
+ {},
1469
+ registryId,
1470
+ parentScopeId
1471
+ );
1472
+ }
1459
1473
  function register2(val, id, scopeId) {
1460
1474
  return scopeId === void 0 ? register(id, val) : register(id, val, ensureScopeWithId(scopeId));
1461
1475
  }
@@ -2400,7 +2414,7 @@ var DEFAULT_RENDER_ID = "_";
2400
2414
 
2401
2415
  // src/html/dynamic-tag.ts
2402
2416
  var voidElementsReg = /^(?:area|b(?:ase|r)|col|embed|hr|i(?:mg|nput)|link|meta|param|source|track|wbr)$/;
2403
- function dynamicTagInput(scopeId, accessor, tag, input, content, tagVar) {
2417
+ function dynamicTagInput(scopeId, accessor, tag, input, content) {
2404
2418
  if (!tag && !content) {
2405
2419
  nextScopeId();
2406
2420
  return;
@@ -2461,7 +2475,7 @@ function dynamicTagInput(scopeId, accessor, tag, input, content, tagVar) {
2461
2475
  let result;
2462
2476
  resumeConditional(
2463
2477
  () => {
2464
- result = renderer(content ? { ...input, content } : input, tagVar);
2478
+ result = renderer(content ? { ...input, content } : input);
2465
2479
  },
2466
2480
  scopeId,
2467
2481
  accessor
@@ -2899,6 +2913,7 @@ export {
2899
2913
  resumeSingleNodeForIn,
2900
2914
  resumeSingleNodeForOf,
2901
2915
  resumeSingleNodeForTo,
2916
+ setTagVar,
2902
2917
  styleAttr,
2903
2918
  toString,
2904
2919
  tryContent,
@@ -4,7 +4,7 @@ interface BodyContentObject {
4
4
  [x: PropertyKey]: unknown;
5
5
  content: ServerRenderer;
6
6
  }
7
- export declare function dynamicTagInput(scopeId: number, accessor: Accessor, tag: unknown | string | ServerRenderer | BodyContentObject, input: Record<string, unknown>, content?: () => void, tagVar?: unknown): undefined;
7
+ export declare function dynamicTagInput(scopeId: number, accessor: Accessor, tag: unknown | string | ServerRenderer | BodyContentObject, input: Record<string, unknown>, content?: () => void): undefined;
8
8
  export declare function dynamicTagArgs(scopeId: number, accessor: Accessor, tag: unknown | string | ServerRenderer | BodyContentObject, args: unknown[]): undefined;
9
9
  declare let getDynamicRenderer: (value: any) => string | ServerRenderer | undefined;
10
10
  export declare let createRenderer: (fn: ServerRenderer) => ServerRenderer;
@@ -16,6 +16,7 @@ export declare function write(html: string): void;
16
16
  export declare function writeScript(script: string): void;
17
17
  export declare function writeEffect(scopeId: number, registryId: string): void;
18
18
  export declare function withContext(key: PropertyKey, value: unknown, cb: () => void): void;
19
+ export declare function setTagVar(parentScopeId: number, childScope: PartialScope, registryId: string): void;
19
20
  export declare function register<T extends WeakKey>(val: T, id: string, scopeId?: number): T;
20
21
  export declare function nextTagId(): string;
21
22
  export declare function nextScopeId(): number;
package/dist/html.d.ts CHANGED
@@ -7,4 +7,4 @@ export { createRenderer, dynamicTagArgs, dynamicTagInput, } from "./html/dynamic
7
7
  export { forIn, forInBy, forOf, forOfBy, forTo, forToBy } from "./html/for";
8
8
  export { debug } from "./html/serializer";
9
9
  export { createTemplate } from "./html/template";
10
- export { $global, ensureScopeWithId, fork, getScopeById, markResumeNode, nextScopeId, nextTagId, nodeRef, peekNextScope, register, resumeClosestBranch, resumeConditional, resumeForIn, resumeForOf, resumeForTo, resumeSingleNodeConditional, resumeSingleNodeForIn, resumeSingleNodeForOf, resumeSingleNodeForTo, tryContent, write, writeEffect, writeExistingScope, writeScope, writeTrailers, } from "./html/writer";
10
+ export { $global, ensureScopeWithId, fork, getScopeById, markResumeNode, nextScopeId, nextTagId, nodeRef, peekNextScope, register, resumeClosestBranch, resumeConditional, resumeForIn, resumeForOf, resumeForTo, resumeSingleNodeConditional, resumeSingleNodeForIn, resumeSingleNodeForOf, resumeSingleNodeForTo, setTagVar, tryContent, write, writeEffect, writeExistingScope, writeScope, writeTrailers, } from "./html/writer";
package/dist/html.js CHANGED
@@ -65,6 +65,7 @@ __export(html_exports, {
65
65
  resumeSingleNodeForIn: () => resumeSingleNodeForIn,
66
66
  resumeSingleNodeForOf: () => resumeSingleNodeForOf,
67
67
  resumeSingleNodeForTo: () => resumeSingleNodeForTo,
68
+ setTagVar: () => setTagVar,
68
69
  styleAttr: () => styleAttr,
69
70
  toString: () => toString,
70
71
  tryContent: () => tryContent,
@@ -528,14 +529,14 @@ function writeRegistered(state, val, parent, accessor, { access, scope }) {
528
529
  state.buf.length
529
530
  );
530
531
  if (state.refs.set(val, fnRef), scopeRef) {
531
- let scopeId = ensureId(state, scopeRef);
532
532
  if (isCircular(parent, scopeRef))
533
- return state.assigned.add(fnRef), fnRef.init = access + "(" + scopeId + ")", fnRef.assigns += ensureId(state, parent) + toAccess(accessor) + "=", !1;
534
- state.buf.push(access + "(" + scopeId + ")");
533
+ return state.assigned.add(fnRef), fnRef.init = access + "(" + ensureId(state, scopeRef) + ")", fnRef.assigns += ensureId(state, parent) + toAccess(accessor) + "=", !1;
534
+ state.buf.push(access + "(" + ensureId(state, scopeRef) + ")");
535
535
  } else {
536
- state.buf.push(access + "("), writeProp(state, scope, parent, "");
537
- let scopeRef2 = state.refs.get(scope);
538
- scopeRef2 && ensureId(state, scopeRef2), state.buf.push(")");
536
+ let pos = state.buf.push(""), assigns = state.assigned.size;
537
+ writeProp(state, scope, parent, "");
538
+ let scopeRef2 = parent && state.refs.get(scope), scopeId = scopeRef2 && ensureId(state, scopeRef2);
539
+ scopeId && assigns !== state.assigned.size ? (state.assigned.add(fnRef), fnRef.init = access + "(" + scopeId + ")", fnRef.assigns += ensureId(state, parent) + toAccess(accessor) + "=") : (state.buf[pos - 2] += access + "(", state.buf.push(")"));
539
540
  }
540
541
  } else
541
542
  state.buf.push(access);
@@ -1006,6 +1007,13 @@ function withContext(key, value, cb) {
1006
1007
  ctx[kPendingContexts]--, ctx[key] = prev;
1007
1008
  }
1008
1009
  }
1010
+ function setTagVar(parentScopeId, childScope, registryId) {
1011
+ childScope["/" /* TagVariable */] = register2(
1012
+ {},
1013
+ registryId,
1014
+ parentScopeId
1015
+ );
1016
+ }
1009
1017
  function register2(val, id, scopeId) {
1010
1018
  return scopeId === void 0 ? register(id, val) : register(id, val, ensureScopeWithId(scopeId));
1011
1019
  }
@@ -1630,7 +1638,7 @@ var DEFAULT_RUNTIME_ID = "M", DEFAULT_RENDER_ID = "_";
1630
1638
 
1631
1639
  // src/html/dynamic-tag.ts
1632
1640
  var voidElementsReg = /^(?:area|b(?:ase|r)|col|embed|hr|i(?:mg|nput)|link|meta|param|source|track|wbr)$/;
1633
- function dynamicTagInput(scopeId, accessor, tag, input, content, tagVar) {
1641
+ function dynamicTagInput(scopeId, accessor, tag, input, content) {
1634
1642
  if (!tag && !content) {
1635
1643
  nextScopeId();
1636
1644
  return;
@@ -1665,7 +1673,7 @@ function dynamicTagInput(scopeId, accessor, tag, input, content, tagVar) {
1665
1673
  let renderer = getDynamicRenderer(tag), result;
1666
1674
  return resumeConditional(
1667
1675
  () => {
1668
- result = renderer(content ? { ...input, content } : input, tagVar);
1676
+ result = renderer(content ? { ...input, content } : input);
1669
1677
  },
1670
1678
  scopeId,
1671
1679
  accessor
@@ -1971,6 +1979,7 @@ function NOOP2() {
1971
1979
  resumeSingleNodeForIn,
1972
1980
  resumeSingleNodeForOf,
1973
1981
  resumeSingleNodeForTo,
1982
+ setTagVar,
1974
1983
  styleAttr,
1975
1984
  toString,
1976
1985
  tryContent,
package/dist/html.mjs CHANGED
@@ -450,14 +450,14 @@ function writeRegistered(state, val, parent, accessor, { access, scope }) {
450
450
  state.buf.length
451
451
  );
452
452
  if (state.refs.set(val, fnRef), scopeRef) {
453
- let scopeId = ensureId(state, scopeRef);
454
453
  if (isCircular(parent, scopeRef))
455
- return state.assigned.add(fnRef), fnRef.init = access + "(" + scopeId + ")", fnRef.assigns += ensureId(state, parent) + toAccess(accessor) + "=", !1;
456
- state.buf.push(access + "(" + scopeId + ")");
454
+ return state.assigned.add(fnRef), fnRef.init = access + "(" + ensureId(state, scopeRef) + ")", fnRef.assigns += ensureId(state, parent) + toAccess(accessor) + "=", !1;
455
+ state.buf.push(access + "(" + ensureId(state, scopeRef) + ")");
457
456
  } else {
458
- state.buf.push(access + "("), writeProp(state, scope, parent, "");
459
- let scopeRef2 = state.refs.get(scope);
460
- scopeRef2 && ensureId(state, scopeRef2), state.buf.push(")");
457
+ let pos = state.buf.push(""), assigns = state.assigned.size;
458
+ writeProp(state, scope, parent, "");
459
+ let scopeRef2 = parent && state.refs.get(scope), scopeId = scopeRef2 && ensureId(state, scopeRef2);
460
+ scopeId && assigns !== state.assigned.size ? (state.assigned.add(fnRef), fnRef.init = access + "(" + scopeId + ")", fnRef.assigns += ensureId(state, parent) + toAccess(accessor) + "=") : (state.buf[pos - 2] += access + "(", state.buf.push(")"));
461
461
  }
462
462
  } else
463
463
  state.buf.push(access);
@@ -928,6 +928,13 @@ function withContext(key, value, cb) {
928
928
  ctx[kPendingContexts]--, ctx[key] = prev;
929
929
  }
930
930
  }
931
+ function setTagVar(parentScopeId, childScope, registryId) {
932
+ childScope["/" /* TagVariable */] = register2(
933
+ {},
934
+ registryId,
935
+ parentScopeId
936
+ );
937
+ }
931
938
  function register2(val, id, scopeId) {
932
939
  return scopeId === void 0 ? register(id, val) : register(id, val, ensureScopeWithId(scopeId));
933
940
  }
@@ -1552,7 +1559,7 @@ var DEFAULT_RUNTIME_ID = "M", DEFAULT_RENDER_ID = "_";
1552
1559
 
1553
1560
  // src/html/dynamic-tag.ts
1554
1561
  var voidElementsReg = /^(?:area|b(?:ase|r)|col|embed|hr|i(?:mg|nput)|link|meta|param|source|track|wbr)$/;
1555
- function dynamicTagInput(scopeId, accessor, tag, input, content, tagVar) {
1562
+ function dynamicTagInput(scopeId, accessor, tag, input, content) {
1556
1563
  if (!tag && !content) {
1557
1564
  nextScopeId();
1558
1565
  return;
@@ -1587,7 +1594,7 @@ function dynamicTagInput(scopeId, accessor, tag, input, content, tagVar) {
1587
1594
  let renderer = getDynamicRenderer(tag), result;
1588
1595
  return resumeConditional(
1589
1596
  () => {
1590
- result = renderer(content ? { ...input, content } : input, tagVar);
1597
+ result = renderer(content ? { ...input, content } : input);
1591
1598
  },
1592
1599
  scopeId,
1593
1600
  accessor
@@ -1892,6 +1899,7 @@ export {
1892
1899
  resumeSingleNodeForIn,
1893
1900
  resumeSingleNodeForOf,
1894
1901
  resumeSingleNodeForTo,
1902
+ setTagVar,
1895
1903
  styleAttr,
1896
1904
  toString,
1897
1905
  tryContent,
@@ -1,6 +1,6 @@
1
1
  import { types as t } from "@marko/compiler";
2
2
  import { type Tag } from "@marko/compiler/babel-utils";
3
- declare const returnId: (section: import("../util/sections").Section) => t.Identifier | undefined;
4
- export { returnId };
3
+ declare const getSectionReturnValueIdentifier: (section: import("../util/sections").Section) => t.Identifier | undefined;
4
+ export { getSectionReturnValueIdentifier };
5
5
  declare const _default: Tag;
6
6
  export default _default;
@@ -742,6 +742,20 @@ function isConditionTag(tag) {
742
742
  }
743
743
  return false;
744
744
  }
745
+ function isControlFlowTag(tag) {
746
+ if (isCoreTag(tag)) {
747
+ switch (getTagName(tag)) {
748
+ case "if":
749
+ case "else-if":
750
+ case "else":
751
+ case "for":
752
+ case "await":
753
+ case "try":
754
+ return true;
755
+ }
756
+ }
757
+ return false;
758
+ }
745
759
 
746
760
  // src/translator/util/optional.ts
747
761
  var Sorted = class {
@@ -1102,6 +1116,7 @@ function startSection(path5) {
1102
1116
  params: void 0,
1103
1117
  closures: void 0,
1104
1118
  bindings: void 0,
1119
+ assignments: void 0,
1105
1120
  content: getContentInfo(path5),
1106
1121
  upstreamExpression: void 0,
1107
1122
  hasAbortSignal: false,
@@ -1303,6 +1318,14 @@ function getKnownAttrValues(tag) {
1303
1318
  return attrs2;
1304
1319
  }
1305
1320
 
1321
+ // src/translator/util/get-parent-tag.ts
1322
+ function getParentTag(tag) {
1323
+ const parent = tag.parent.type === "MarkoTagBody" ? tag.parentPath.parentPath : tag.parentPath;
1324
+ if (parent.type === "MarkoTag") {
1325
+ return parent;
1326
+ }
1327
+ }
1328
+
1306
1329
  // src/translator/util/plugin-hooks.ts
1307
1330
  var import_compiler7 = require("@marko/compiler");
1308
1331
  function enter(modulePlugin, path5) {
@@ -1648,10 +1671,8 @@ function markNode(path5, binding) {
1648
1671
  }
1649
1672
 
1650
1673
  // src/translator/core/return.ts
1651
- var [returnId, _setReturnId] = createSectionState(
1652
- "returnId"
1653
- );
1654
- var usedTag = /* @__PURE__ */ new WeakSet();
1674
+ var tagsWithReturn = /* @__PURE__ */ new WeakSet();
1675
+ var [getSectionReturnValueIdentifier, setReturnValueIdentifier] = createSectionState("returnValue");
1655
1676
  var return_default = {
1656
1677
  analyze(tag) {
1657
1678
  (0, import_babel_utils8.assertNoArgs)(tag);
@@ -1659,12 +1680,25 @@ var return_default = {
1659
1680
  (0, import_babel_utils8.assertNoParams)(tag);
1660
1681
  assertNoBodyContent(tag);
1661
1682
  (0, import_babel_utils8.assertAllowedAttributes)(tag, ["value", "valueChange"]);
1662
- if (usedTag.has(tag.hub)) {
1683
+ const parentTag = getParentTag(tag);
1684
+ if (parentTag) {
1685
+ if ((0, import_babel_utils8.isNativeTag)(parentTag)) {
1686
+ throw tag.get("name").buildCodeFrameError(
1687
+ "The `return` tag can not be used in a native tag."
1688
+ );
1689
+ } else if (isControlFlowTag(parentTag)) {
1690
+ throw tag.get("name").buildCodeFrameError(
1691
+ `The \`return\` tag can not be used under an \`${parentTag.get("name").toString()}\` tag.`
1692
+ );
1693
+ }
1694
+ }
1695
+ if (tagsWithReturn.has(tag.parentPath)) {
1663
1696
  throw tag.get("name").buildCodeFrameError(
1664
- "The `return` tag can only be used once per template."
1697
+ `Cannot have multiple \`return\` tags ${tag.parent.type === "Program" ? "for the template" : "within a tag's body content"}.`
1665
1698
  );
1699
+ } else {
1700
+ tagsWithReturn.add(tag.parentPath);
1666
1701
  }
1667
- usedTag.add(tag.hub);
1668
1702
  if (!getKnownAttrValues(tag.node).value) {
1669
1703
  throw tag.get("name").buildCodeFrameError("The `return` tag requires a value.");
1670
1704
  }
@@ -1682,11 +1716,11 @@ var return_default = {
1682
1716
  );
1683
1717
  }
1684
1718
  if (attrs2.value) {
1685
- const returnId2 = currentProgramPath.scope.generateUidIdentifier("return");
1686
- _setReturnId(section, returnId2);
1719
+ const returnId = tag.scope.generateUidIdentifier("return");
1720
+ setReturnValueIdentifier(section, returnId);
1687
1721
  tag.replaceWith(
1688
1722
  import_compiler11.types.variableDeclaration("const", [
1689
- import_compiler11.types.variableDeclarator(returnId2, attrs2.value)
1723
+ import_compiler11.types.variableDeclarator(returnId, attrs2.value)
1690
1724
  ])
1691
1725
  )[0].skip();
1692
1726
  }
@@ -2507,11 +2541,23 @@ function getMappedId(reference) {
2507
2541
  function addHTMLEffectCall(section, referencedBindings) {
2508
2542
  addStatement("effect", section, referencedBindings, void 0, false);
2509
2543
  }
2510
- function writeHTMLResumeStatements(path5, tagVarIdentifier) {
2544
+ function writeHTMLResumeStatements(path5) {
2511
2545
  const section = getSectionForBody(path5);
2512
2546
  if (!section) return;
2513
2547
  const allSignals = Array.from(getSignals(section).values());
2514
2548
  const scopeIdIdentifier = getScopeIdIdentifier(section);
2549
+ forEach(section.assignments, (assignment) => {
2550
+ let currentSection = section;
2551
+ while (currentSection !== assignment.section) {
2552
+ getSerializedScopeProperties(currentSection).set(
2553
+ import_compiler17.types.stringLiteral("_"),
2554
+ callRuntime(
2555
+ "ensureScopeWithId",
2556
+ getScopeIdIdentifier(currentSection = currentSection.parent)
2557
+ )
2558
+ );
2559
+ }
2560
+ });
2515
2561
  forEach(section.closures, (closure) => {
2516
2562
  if (isStatefulReferences(closure)) {
2517
2563
  let currentSection = section;
@@ -2570,14 +2616,6 @@ function writeHTMLResumeStatements(path5, tagVarIdentifier) {
2570
2616
  accessors.add(accessor.value);
2571
2617
  }
2572
2618
  });
2573
- if (tagVarIdentifier && returnId(section) !== void 0) {
2574
- serializedProperties.push(
2575
- import_compiler17.types.objectProperty(
2576
- import_compiler17.types.stringLiteral("/" /* TagVariable */),
2577
- tagVarIdentifier
2578
- )
2579
- );
2580
- }
2581
2619
  for (const [key, value] of additionalProperties) {
2582
2620
  if (!accessors.has(key.value)) {
2583
2621
  serializedProperties.push(
@@ -2647,6 +2685,10 @@ function writeHTMLResumeStatements(path5, tagVarIdentifier) {
2647
2685
  ])
2648
2686
  );
2649
2687
  }
2688
+ const returnIdentifier = getSectionReturnValueIdentifier(section);
2689
+ if (returnIdentifier !== void 0) {
2690
+ path5.pushContainer("body", import_compiler17.types.returnStatement(returnIdentifier));
2691
+ }
2650
2692
  }
2651
2693
  function getSetup(section) {
2652
2694
  return getSignals(section).get(void 0)?.identifier;
@@ -2919,15 +2961,9 @@ function isStatic(path5) {
2919
2961
  var html_default = {
2920
2962
  translate: {
2921
2963
  exit(program) {
2922
- const section = getSectionForBody(program);
2923
- const tagVarIdentifier = program.scope.generateUidIdentifier("tagVar");
2924
2964
  flushInto(program);
2925
- writeHTMLResumeStatements(program, tagVarIdentifier);
2965
+ writeHTMLResumeStatements(program);
2926
2966
  traverseReplace(program.node, "body", replaceNode);
2927
- const returnIdentifier = returnId(section);
2928
- if (returnIdentifier !== void 0) {
2929
- program.pushContainer("body", import_compiler19.types.returnStatement(returnIdentifier));
2930
- }
2931
2967
  const renderContent = [];
2932
2968
  for (const child of program.get("body")) {
2933
2969
  if (!isStatic(child)) {
@@ -2948,7 +2984,7 @@ var html_default = {
2948
2984
  callRuntime(
2949
2985
  "createRenderer",
2950
2986
  import_compiler19.types.arrowFunctionExpression(
2951
- [import_compiler19.types.identifier("input"), tagVarIdentifier],
2987
+ [import_compiler19.types.identifier("input")],
2952
2988
  import_compiler19.types.blockStatement(renderContent)
2953
2989
  )
2954
2990
  )
@@ -3350,6 +3386,7 @@ function trackAssignment(assignment, binding) {
3350
3386
  forEachIdentifier(assignment.node, (id) => {
3351
3387
  if (id.name === binding.name) {
3352
3388
  const extra = id.extra ??= {};
3389
+ section.assignments = bindingUtil.add(section.assignments, binding);
3353
3390
  extra.assignment = binding;
3354
3391
  extra.section = section;
3355
3392
  }
@@ -4170,16 +4207,6 @@ var import_babel_utils20 = require("@marko/compiler/babel-utils");
4170
4207
  // src/translator/util/nested-attribute-tags.ts
4171
4208
  var import_compiler27 = require("@marko/compiler");
4172
4209
  var import_babel_utils16 = require("@marko/compiler/babel-utils");
4173
-
4174
- // src/translator/util/get-parent-tag.ts
4175
- function getParentTag(tag) {
4176
- const parent = tag.parent.type === "MarkoTagBody" ? tag.parentPath.parentPath : tag.parentPath;
4177
- if (parent.type === "MarkoTag") {
4178
- return parent;
4179
- }
4180
- }
4181
-
4182
- // src/translator/util/nested-attribute-tags.ts
4183
4210
  var attrTagToIdentifierLookup = /* @__PURE__ */ new WeakMap();
4184
4211
  function getAttrTagIdentifier(meta) {
4185
4212
  let name2 = attrTagToIdentifierLookup.get(meta);
@@ -8431,6 +8458,25 @@ function translateHTML(tag) {
8431
8458
  properties: [],
8432
8459
  statements: []
8433
8460
  };
8461
+ if (tagVar) {
8462
+ statements.push(
8463
+ import_compiler51.types.expressionStatement(
8464
+ callRuntime(
8465
+ "setTagVar",
8466
+ getScopeIdIdentifier(section),
8467
+ peekScopeId,
8468
+ import_compiler51.types.stringLiteral(
8469
+ getResumeRegisterId(
8470
+ section,
8471
+ node.var.extra?.binding,
8472
+ // TODO: node.var is not always an identifier.
8473
+ "var"
8474
+ )
8475
+ )
8476
+ )
8477
+ )
8478
+ );
8479
+ }
8434
8480
  if (node.extra.tagNameNullable) {
8435
8481
  const contentProp = getTranslatedBodyContentProperty(properties);
8436
8482
  let contentId = void 0;
@@ -8466,23 +8512,7 @@ function translateHTML(tag) {
8466
8512
  } else if (tagVar) {
8467
8513
  translateVar(
8468
8514
  tag,
8469
- callExpression(
8470
- tagIdentifier,
8471
- propsToExpression(properties),
8472
- callRuntime(
8473
- "register",
8474
- import_compiler51.types.arrowFunctionExpression([], import_compiler51.types.blockStatement([])),
8475
- import_compiler51.types.stringLiteral(
8476
- getResumeRegisterId(
8477
- section,
8478
- node.var.extra?.binding,
8479
- // TODO: node.var is not always an identifier.
8480
- "var"
8481
- )
8482
- ),
8483
- getScopeIdIdentifier(section)
8484
- )
8485
- )
8515
+ callExpression(tagIdentifier, propsToExpression(properties))
8486
8516
  );
8487
8517
  setForceResumeScope(section);
8488
8518
  } else {
@@ -9090,21 +9120,6 @@ var dynamic_tag_default = {
9090
9120
  if (!hasMultipleArgs && args.length === 1) {
9091
9121
  args.push(import_compiler52.types.unaryExpression("void", import_compiler52.types.numericLiteral(0)));
9092
9122
  }
9093
- args.push(
9094
- callRuntime(
9095
- "register",
9096
- import_compiler52.types.arrowFunctionExpression([], import_compiler52.types.blockStatement([])),
9097
- import_compiler52.types.stringLiteral(
9098
- getResumeRegisterId(
9099
- section,
9100
- node.var.extra?.binding,
9101
- // TODO: node.var is not always an identifier.
9102
- "var"
9103
- )
9104
- ),
9105
- getScopeIdIdentifier(section)
9106
- )
9107
- );
9108
9123
  }
9109
9124
  const dynamicScopeIdentifier = currentProgramPath.scope.generateUidIdentifier("dynamicScope");
9110
9125
  const dynamicTagExpr = hasMultipleArgs ? callRuntime(
@@ -9128,11 +9143,30 @@ var dynamic_tag_default = {
9128
9143
  )
9129
9144
  ])
9130
9145
  );
9131
- statements.push(
9132
- node.var ? import_compiler52.types.variableDeclaration("const", [
9133
- import_compiler52.types.variableDeclarator(node.var, dynamicTagExpr)
9134
- ]) : import_compiler52.types.expressionStatement(dynamicTagExpr)
9135
- );
9146
+ if (node.var) {
9147
+ statements.push(
9148
+ import_compiler52.types.expressionStatement(
9149
+ callRuntime(
9150
+ "setTagVar",
9151
+ getScopeIdIdentifier(section),
9152
+ dynamicScopeIdentifier,
9153
+ import_compiler52.types.stringLiteral(
9154
+ getResumeRegisterId(
9155
+ section,
9156
+ node.var.extra?.binding,
9157
+ // TODO: node.var is not always an identifier.
9158
+ "var"
9159
+ )
9160
+ )
9161
+ )
9162
+ ),
9163
+ import_compiler52.types.variableDeclaration("const", [
9164
+ import_compiler52.types.variableDeclarator(node.var, dynamicTagExpr)
9165
+ ])
9166
+ );
9167
+ } else {
9168
+ statements.push(import_compiler52.types.expressionStatement(dynamicTagExpr));
9169
+ }
9136
9170
  getSerializedScopeProperties(section).set(
9137
9171
  import_compiler52.types.stringLiteral(
9138
9172
  getScopeAccessorLiteral(nodeRef2).value + "!" /* ConditionalScope */
@@ -8,3 +8,6 @@ export declare function isCoreTagName(tag: t.NodePath, name: string): tag is t.N
8
8
  export declare function isConditionTag(tag: t.NodePath): tag is t.NodePath<t.MarkoTag & {
9
9
  name: t.StringLiteral;
10
10
  }>;
11
+ export declare function isControlFlowTag(tag: t.NodePath): tag is t.NodePath<t.MarkoTag & {
12
+ name: t.StringLiteral;
13
+ }>;
@@ -16,6 +16,7 @@ export interface Section {
16
16
  params: undefined | Binding;
17
17
  closures: ReferencedBindings;
18
18
  bindings: ReferencedBindings;
19
+ assignments: ReferencedBindings;
19
20
  upstreamExpression: t.NodeExtra | undefined;
20
21
  hasAbortSignal: boolean;
21
22
  isBranch: boolean;
@@ -29,10 +30,6 @@ declare module "@marko/compiler/dist/types" {
29
30
  interface ProgramExtra {
30
31
  section?: Section;
31
32
  sections?: Section[];
32
- assignments?: [
33
- valueSection: Section,
34
- assignment: t.NodePath<t.UpdateExpression> | t.NodePath<t.AssignmentExpression>
35
- ][];
36
33
  }
37
34
  interface MarkoTagBodyExtra {
38
35
  section?: Section;
@@ -56,6 +56,6 @@ export declare function getRegisterUID(section: Section, name: string): string;
56
56
  export declare function writeSignals(section: Section): void;
57
57
  export declare function writeRegisteredFns(): void;
58
58
  export declare function addHTMLEffectCall(section: Section, referencedBindings?: ReferencedBindings): void;
59
- export declare function writeHTMLResumeStatements(path: t.NodePath<t.MarkoTagBody | t.Program>, tagVarIdentifier?: t.Identifier): void;
59
+ export declare function writeHTMLResumeStatements(path: t.NodePath<t.MarkoTagBody | t.Program>): void;
60
60
  export declare function getSetup(section: Section): t.Identifier | undefined;
61
61
  export declare function replaceRegisteredFunctionNode(node: t.Node): t.CallExpression | t.ClassPrivateProperty | t.ClassProperty | t.VariableDeclaration | t.Identifier | t.ObjectProperty | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "6.0.0-next.3.31",
3
+ "version": "6.0.0-next.3.33",
4
4
  "description": "Optimized runtime for Marko templates.",
5
5
  "keywords": [
6
6
  "api",