diff --git a/.changeset/gentle-eyes-vanish.md b/.changeset/gentle-eyes-vanish.md new file mode 100644 index 000000000..4267d75da --- /dev/null +++ b/.changeset/gentle-eyes-vanish.md @@ -0,0 +1,6 @@ +--- +"@marko/translator-interop-class-tags": patch +"@marko/translator-tags": patch +--- + +State based registration & serialization diff --git a/packages/translator-interop/src/__tests__/fixtures/interop-nested-tags-to-class/__snapshots__/html.expected/template.js b/packages/translator-interop/src/__tests__/fixtures/interop-nested-tags-to-class/__snapshots__/html.expected/template.js index d6e77f764..dd1004f5a 100644 --- a/packages/translator-interop/src/__tests__/fixtures/interop-nested-tags-to-class/__snapshots__/html.expected/template.js +++ b/packages/translator-interop/src/__tests__/fixtures/interop-nested-tags-to-class/__snapshots__/html.expected/template.js @@ -7,8 +7,8 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { const _dynamicScope = _dynamicTagInput(_classLayout, {}, _register( /* @__PURE__ */_createRenderer(() => { const _scope1_id = _nextScopeId(); _write(`${_markResumeNode(_scope1_id, "#button/0")}`); - _writeEffect(_scope1_id, "packages/translator-interop/src/__tests__/fixtures/interop-nested-tags-to-class/template.marko_1_count"); _writeEffect(_scope1_id, "packages/translator-interop/src/__tests__/fixtures/interop-nested-tags-to-class/template.marko_1_count/subscriber"); + _writeEffect(_scope1_id, "packages/translator-interop/src/__tests__/fixtures/interop-nested-tags-to-class/template.marko_1_count"); _writeScope(_scope1_id, { "_": _serializedScope(_scope0_id) }); diff --git a/packages/translator-interop/src/__tests__/fixtures/interop-nested-tags-to-class/__snapshots__/resume.expected.md b/packages/translator-interop/src/__tests__/fixtures/interop-nested-tags-to-class/__snapshots__/resume.expected.md index c2c832d34..e5dda3e10 100644 --- a/packages/translator-interop/src/__tests__/fixtures/interop-nested-tags-to-class/__snapshots__/resume.expected.md +++ b/packages/translator-interop/src/__tests__/fixtures/interop-nested-tags-to-class/__snapshots__/resume.expected.md @@ -21,7 +21,7 @@ +
# Render "End" @@ -31,7 +31,7 @@ diff --git a/packages/translator-interop/src/__tests__/fixtures/interop-tag-params-tags-to-class/__snapshots__/html.expected/template.js b/packages/translator-interop/src/__tests__/fixtures/interop-tag-params-tags-to-class/__snapshots__/html.expected/template.js index 8b37ad2cf..919d5b1f1 100644 --- a/packages/translator-interop/src/__tests__/fixtures/interop-tag-params-tags-to-class/__snapshots__/html.expected/template.js +++ b/packages/translator-interop/src/__tests__/fixtures/interop-tag-params-tags-to-class/__snapshots__/html.expected/template.js @@ -7,8 +7,8 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { const _dynamicScope = _dynamicTagInput(_classLayout, {}, _register( /* @__PURE__ */_createRenderer((baseCount, message) => { const _scope1_id = _nextScopeId(); _write(`

${_escapeXML(message)}${_markResumeNode(_scope1_id, "#text/0")}

${_markResumeNode(_scope1_id, "#button/1")}`); - _writeEffect(_scope1_id, "packages/translator-interop/src/__tests__/fixtures/interop-tag-params-tags-to-class/template.marko_1_multiplier"); _writeEffect(_scope1_id, "packages/translator-interop/src/__tests__/fixtures/interop-tag-params-tags-to-class/template.marko_1_multiplier/subscriber"); + _writeEffect(_scope1_id, "packages/translator-interop/src/__tests__/fixtures/interop-tag-params-tags-to-class/template.marko_1_multiplier"); _writeScope(_scope1_id, { "baseCount": baseCount, "_": _serializedScope(_scope0_id) diff --git a/packages/translator-interop/src/__tests__/fixtures/interop-tag-params-tags-to-class/__snapshots__/resume.expected.md b/packages/translator-interop/src/__tests__/fixtures/interop-tag-params-tags-to-class/__snapshots__/resume.expected.md index 8d466f5e3..91d39ada5 100644 --- a/packages/translator-interop/src/__tests__/fixtures/interop-tag-params-tags-to-class/__snapshots__/resume.expected.md +++ b/packages/translator-interop/src/__tests__/fixtures/interop-tag-params-tags-to-class/__snapshots__/resume.expected.md @@ -33,7 +33,7 @@ +

hello

# Render "End" @@ -43,7 +43,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/at-tag-inside-if-tag/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/at-tag-inside-if-tag/__snapshots__/html.expected/template.js index 53a9c29ab..44d1e2d4c 100644 --- a/packages/translator-tags/src/__tests__/fixtures/at-tag-inside-if-tag/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/at-tag-inside-if-tag/__snapshots__/html.expected/template.js @@ -1,4 +1,4 @@ -import { write as _write, createRenderer as _createRenderer, writeScope as _writeScope, nextScopeId as _nextScopeId, register as _register, markResumeControlSingleNodeEnd as _markResumeControlSingleNodeEnd, serializedScope as _serializedScope, peekSerializedScope as _peekSerializedScope, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; +import { write as _write, createRenderer as _createRenderer, writeScope as _writeScope, nextScopeId as _nextScopeId, register as _register, markResumeControlSingleNodeEnd as _markResumeControlSingleNodeEnd, serializedScope as _serializedScope, writeEffect as _writeEffect, peekSerializedScope as _peekSerializedScope, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; import _customTag from "./components/custom-tag/index.marko"; const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { const _scope0_id = _nextScopeId(); @@ -21,9 +21,10 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _ifScopeId = _scope2_id; } _write(`${_markResumeControlSingleNodeEnd(_scope1_id, "#text/0", _ifScopeId)}`); + _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/at-tag-inside-if-tag/template.marko_1_x/subscriber"); _writeScope(_scope1_id, { - "#text/0!": _scope2_, "#text/0(": _ifRenderer, + "#text/0!": _scope2_, "_": _serializedScope(_scope0_id) }); const _childScope = _peekSerializedScope(); @@ -31,6 +32,7 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { thing: _thing }); _writeScope(_scope0_id, { + "x": x, "#childScope/0": _childScope }); }); diff --git a/packages/translator-tags/src/__tests__/fixtures/at-tags-dynamic-with-params/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/at-tags-dynamic-with-params/__snapshots__/html.expected/template.js index eb83ad7a6..95ea13aae 100644 --- a/packages/translator-tags/src/__tests__/fixtures/at-tags-dynamic-with-params/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/at-tags-dynamic-with-params/__snapshots__/html.expected/template.js @@ -1,4 +1,4 @@ -import { escapeXML as _escapeXML, write as _write, createRenderer as _createRenderer, writeScope as _writeScope, nextScopeId as _nextScopeId, register as _register, markResumeControlSingleNodeEnd as _markResumeControlSingleNodeEnd, serializedScope as _serializedScope, peekSerializedScope as _peekSerializedScope, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; +import { escapeXML as _escapeXML, write as _write, createRenderer as _createRenderer, writeScope as _writeScope, nextScopeId as _nextScopeId, register as _register, markResumeControlSingleNodeEnd as _markResumeControlSingleNodeEnd, serializedScope as _serializedScope, writeEffect as _writeEffect, peekSerializedScope as _peekSerializedScope, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; import _hello from "./components/hello/index.marko"; const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { const _scope0_id = _nextScopeId(); @@ -20,9 +20,10 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _ifScopeId = _scope2_id; } _write(`${_markResumeControlSingleNodeEnd(_scope1_id, "#text/0", _ifScopeId)}`); + _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/at-tags-dynamic-with-params/template.marko_1_x/subscriber"); _writeScope(_scope1_id, { - "#text/0!": _scope2_, "#text/0(": _ifRenderer, + "#text/0!": _scope2_, "_": _serializedScope(_scope0_id) }); const _childScope = _peekSerializedScope(); @@ -30,6 +31,7 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { item: _item }); _writeScope(_scope0_id, { + "x": x, "#childScope/0": _childScope }); }); diff --git a/packages/translator-tags/src/__tests__/fixtures/at-tags-dynamic/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/at-tags-dynamic/__snapshots__/html.expected/template.js index 20aeaae1b..6f8bae2a3 100644 --- a/packages/translator-tags/src/__tests__/fixtures/at-tags-dynamic/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/at-tags-dynamic/__snapshots__/html.expected/template.js @@ -1,4 +1,4 @@ -import { write as _write, createRenderer as _createRenderer, serializedScope as _serializedScope, writeScope as _writeScope, nextScopeId as _nextScopeId, maybeFlush as _maybeFlush, escapeXML as _escapeXML, peekSerializedScope as _peekSerializedScope, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; +import { write as _write, createRenderer as _createRenderer, nextScopeId as _nextScopeId, maybeFlush as _maybeFlush, escapeXML as _escapeXML, writeScope as _writeScope, peekSerializedScope as _peekSerializedScope, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; import _hello from "./components/hello/index.marko"; const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { const _scope0_id = _nextScopeId(); @@ -17,9 +17,6 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _write("foo"); }) }); - _writeScope(_scope4_id, { - "_": _serializedScope(_scope3_id) - }); } else { const _scope5_id = _nextScopeId(); _item.push({ @@ -30,9 +27,6 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _write("bar"); }) }); - _writeScope(_scope5_id, { - "_": _serializedScope(_scope3_id) - }); } _maybeFlush(); } @@ -49,12 +43,18 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _write(`${_escapeXML(row)}`); }) }); + _writeScope(_scope10_id, { + "row": row + }); _maybeFlush(); } _col.push({ x: i, row: _row }); + _writeScope(_scope8_id, { + "col": col + }); _maybeFlush(); } _col.push({ diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/dom.expected/template.hydrate.js b/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/dom.expected/template.hydrate.js new file mode 100644 index 000000000..5ef5a064f --- /dev/null +++ b/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/dom.expected/template.hydrate.js @@ -0,0 +1,4 @@ +import { init } from "@marko/runtime-tags/debug/dom"; +import "./template.marko"; +import "./components/my-button.marko"; +init(); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/html.expected/template.js index d1b9c654c..5925b1168 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/html.expected/template.js @@ -1,4 +1,4 @@ -import { escapeXML as _escapeXML, markResumeNode as _markResumeNode, write as _write, serializedScope as _serializedScope, writeScope as _writeScope, nextScopeId as _nextScopeId, register as _register, createRenderer as _createRenderer, peekSerializedScope as _peekSerializedScope, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; +import { escapeXML as _escapeXML, markResumeNode as _markResumeNode, write as _write, serializedScope as _serializedScope, writeEffect as _writeEffect, writeScope as _writeScope, nextScopeId as _nextScopeId, register as _register, createRenderer as _createRenderer, peekSerializedScope as _peekSerializedScope, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; import _myButton from "./components/my-button.marko"; const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { const _scope0_id = _nextScopeId(); @@ -11,6 +11,7 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { renderBody: /* @__PURE__ */_createRenderer(() => { const _scope1_id = _nextScopeId(); _write(`${_escapeXML(clickCount)}${_markResumeNode(_scope1_id, "#text/0")}`); + _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/template.marko_1_clickCount/subscriber"); _writeScope(_scope1_id, { "_": _serializedScope(_scope0_id) }); diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/resume-sanitized.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/resume-sanitized.expected.md new file mode 100644 index 000000000..cf47116d6 --- /dev/null +++ b/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/resume-sanitized.expected.md @@ -0,0 +1,36 @@ +# Render {} +```html + +``` + + +# Render +container.querySelector("button").click() + +```html + +``` + + +# Render +container.querySelector("button").click() + +```html + +``` + + +# Render +container.querySelector("button").click() + +```html + +``` \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/resume.expected.md new file mode 100644 index 000000000..3176ba0fe --- /dev/null +++ b/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/resume.expected.md @@ -0,0 +1,102 @@ +# Render {} +```html + + + + + + + + +``` + +# Mutations +``` + +``` + + +# Render +container.querySelector("button").click() + +```html + + + + + + + + +``` + +# Mutations +``` +inserted #document/html0/body1/button0/#text0 +removed #comment after #document/html0/body1/button0/#text0 +removed #text after #document/html0/body1/button0/#text0 +removed #comment after #document/html0/body1/button0/#text0 +#document/html0/body1/button0/#text0: " " => "1" +``` + + +# Render +container.querySelector("button").click() + +```html + + + + + + + + +``` + +# Mutations +``` +#document/html0/body1/button0/#text0: "1" => "2" +``` + + +# Render +container.querySelector("button").click() + +```html + + + + + + + + +``` + +# Mutations +``` +#document/html0/body1/button0/#text0: "2" => "3" +``` \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/ssr.expected.md index 6647399b1..9bb1f1b79 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write - + # Render "End" @@ -15,7 +15,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/test.ts b/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/test.ts index b27e78c52..692774ba7 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/test.ts +++ b/packages/translator-tags/src/__tests__/fixtures/basic-component-renderBody/test.ts @@ -2,6 +2,4 @@ export const steps = [{}, click, click, click]; function click(container: Element) { container.querySelector("button")!.click(); -} - -export const skip_resume = true; +} \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter-multiple-nodes/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter-multiple-nodes/__snapshots__/html.expected/template.js index f49476eae..fbd8bdcd1 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter-multiple-nodes/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter-multiple-nodes/__snapshots__/html.expected/template.js @@ -19,8 +19,8 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _writeScope(_scope0_id, { "show": show, "count": count, - "#text/2!": _scope1_, - "#text/2(": _ifRenderer + "#text/2(": _ifRenderer, + "#text/2!": _scope1_ }); }); export default /* @__PURE__ */_createTemplate(_renderer, "packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter-multiple-nodes/template.marko"); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter-multiple-nodes/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter-multiple-nodes/__snapshots__/resume.expected.md index d074c949d..6b9dec386 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter-multiple-nodes/__snapshots__/resume.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter-multiple-nodes/__snapshots__/resume.expected.md @@ -18,7 +18,7 @@ @@ -52,7 +52,7 @@ container.querySelector("button.inc").click() @@ -81,7 +81,7 @@ container.querySelector("button.toggle").click() @@ -116,7 +116,7 @@ container.querySelector("button.inc").click() @@ -145,7 +145,7 @@ container.querySelector("button.toggle").click() The count is 2 @@ -177,7 +177,7 @@ container.querySelector("button.inc").click() The count is 3 diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter-multiple-nodes/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter-multiple-nodes/__snapshots__/ssr.expected.md index 72818e696..312b726c5 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter-multiple-nodes/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter-multiple-nodes/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write - The count is 0 + The count is 0 # Render "End" @@ -22,7 +22,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter/__snapshots__/html.expected/template.js index 4bca4a5c2..bd52fb88b 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter/__snapshots__/html.expected/template.js @@ -20,8 +20,8 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _writeScope(_scope0_id, { "show": show, "count": count, - "#text/2!": _scope1_, - "#text/2(": _ifRenderer + "#text/2(": _ifRenderer, + "#text/2!": _scope1_ }); }); export default /* @__PURE__ */_createTemplate(_renderer, "packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter/template.marko"); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter/__snapshots__/resume.expected.md index a3d2acda7..5751cad0d 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter/__snapshots__/resume.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter/__snapshots__/resume.expected.md @@ -17,7 +17,7 @@ @@ -50,7 +50,7 @@ container.querySelector("button.inc").click() @@ -79,7 +79,7 @@ container.querySelector("button.toggle").click() @@ -110,7 +110,7 @@ container.querySelector("button.inc").click() @@ -141,7 +141,7 @@ container.querySelector("button.toggle").click() 2 @@ -174,7 +174,7 @@ container.querySelector("button.inc").click() 3 diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter/__snapshots__/ssr.expected.md index bfe4928c8..322e473fb 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-conditional-counter/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write - 0 + 0 # Render "End" @@ -21,7 +21,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/dom.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/dom.expected/template.js index 5d0f56aab..0cfce328c 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/dom.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/dom.expected/template.js @@ -1,4 +1,4 @@ -import { data as _data, intersection as _intersection, closure as _closure, createRenderer as _createRenderer, register as _register, conditional as _conditional, inConditionalScope as _inConditionalScope, value as _value, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/dom"; +import { data as _data, intersection as _intersection, closure as _closure, createRenderer as _createRenderer, conditional as _conditional, inConditionalScope as _inConditionalScope, value as _value, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/dom"; const _expr_a_b$ifBody = /* @__PURE__ */_intersection(2, _scope => { const { _: { @@ -10,7 +10,7 @@ const _expr_a_b$ifBody = /* @__PURE__ */_intersection(2, _scope => { }); const _b$ifBody = /* @__PURE__ */_closure("b", null, void 0, _expr_a_b$ifBody); const _a$ifBody = /* @__PURE__ */_closure("a", null, void 0, _expr_a_b$ifBody); -const _ifBody = _register("packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/template.marko_1_renderer", /* @__PURE__ */_createRenderer(" ", /* get */" ", void 0, [_a$ifBody, _b$ifBody])); +const _ifBody = /* @__PURE__ */_createRenderer(" ", /* get */" ", void 0, [_a$ifBody, _b$ifBody]); const _if = /* @__PURE__ */_conditional("#text/0"); const _b = /* @__PURE__ */_value("b", null, _inConditionalScope(_b$ifBody, "#text/0")); const _a = /* @__PURE__ */_value("a", null, _inConditionalScope(_a$ifBody, "#text/0")); diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/html.expected/template.js index 83d81e2c7..28d5eb217 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/html.expected/template.js @@ -3,16 +3,19 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { const _scope0_id = _nextScopeId(); const a = 0; const b = 0; + let _ifScopeId, _scope1_; if (true) { const _scope1_id = _nextScopeId(); _write(`${_escapeXML(a + b)}${_markResumeNode(_scope1_id, "#text/0")}`); - _writeScope(_scope1_id, { + _writeScope(_scope1_id, _scope1_ = { "_": _serializedScope(_scope0_id) }); + _ifScopeId = _scope1_id; } _writeScope(_scope0_id, { "a": a, - "b": b + "b": b, + "#text/0!": _scope1_ }); }); export default /* @__PURE__ */_createTemplate(_renderer, "packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/template.marko"); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/resume.expected.md index bf8c721ee..797e41dbf 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/resume.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/resume.expected.md @@ -6,7 +6,7 @@ 0 diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/ssr.expected.md index 69826ed27..7f0beca8e 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-converge-in-if/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write - 0 + 0 # Render "End" @@ -10,7 +10,7 @@ 0 diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-execution-order/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/basic-execution-order/__snapshots__/html.expected/template.js index e802a6628..0c95e50d7 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-execution-order/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-execution-order/__snapshots__/html.expected/template.js @@ -19,8 +19,9 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _write(`${_markResumeControlSingleNodeEnd(_scope0_id, "#text/1", _ifScopeId)}`); _writeEffect(_scope0_id, "packages/translator-tags/src/__tests__/fixtures/basic-execution-order/template.marko_0"); _writeScope(_scope0_id, { - "#text/1!": _scope1_, - "#text/1(": _ifRenderer + "message": message, + "#text/1(": _ifRenderer, + "#text/1!": _scope1_ }); }); export default /* @__PURE__ */_createTemplate(_renderer, "packages/translator-tags/src/__tests__/fixtures/basic-execution-order/template.marko"); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-execution-order/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-execution-order/__snapshots__/resume.expected.md index 75dc2a10b..a5ae08e4e 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-execution-order/__snapshots__/resume.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-execution-order/__snapshots__/resume.expected.md @@ -11,7 +11,7 @@ @@ -37,7 +37,7 @@ container.querySelector("button").click() diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-execution-order/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-execution-order/__snapshots__/ssr.expected.md index ec4244c6e..dad856b1a 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-execution-order/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-execution-order/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write - hi + hi # Render "End" @@ -15,7 +15,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/html.expected/components/comments.js b/packages/translator-tags/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/html.expected/components/comments.js index ee80f9c83..d54d50426 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/html.expected/components/comments.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/html.expected/components/comments.js @@ -29,15 +29,18 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _write(`${_markResumeControlSingleNodeEnd(_scope1_id, "#text/4", _ifScopeId)}${_markResumeNode(_scope1_id, "#li/0")}`); _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/basic-inert-collapsible-tree/components/comments.marko_1_open"); _writeScope(_scope1_id, (_s => (_scope1_.set(i, _s), _s))({ + "comment": comment, + "id": id, "open": open, - "#text/4!": _scope2_, "#text/4(": _ifRenderer, + "#text/4!": _scope2_, "_": _serializedScope(_scope0_id) })); _maybeFlush(); } _write(`${_markResumeControlEnd(_scope0_id, "#ul/0")}${_markResumeNode(_scope0_id, "#ul/0")}`); _writeScope(_scope0_id, { + "input": input, "#ul/0(": _scope1_.size ? _scope1_ : undefined }); }); diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/ssr.expected.md index 1d28b4e29..8e1c493de 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write - + # Render "End" @@ -64,7 +64,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-layout/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/basic-layout/__snapshots__/html.expected/template.js index 014f3033f..f396e0a4c 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-layout/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-layout/__snapshots__/html.expected/template.js @@ -1,4 +1,4 @@ -import { escapeXML as _escapeXML, markResumeNode as _markResumeNode, write as _write, serializedScope as _serializedScope, writeScope as _writeScope, nextScopeId as _nextScopeId, createRenderer as _createRenderer, peekSerializedScope as _peekSerializedScope, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; +import { escapeXML as _escapeXML, markResumeNode as _markResumeNode, write as _write, serializedScope as _serializedScope, writeEffect as _writeEffect, writeScope as _writeScope, nextScopeId as _nextScopeId, createRenderer as _createRenderer, peekSerializedScope as _peekSerializedScope, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; import _layout from "./components/layout.marko"; const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { const _scope0_id = _nextScopeId(); @@ -10,12 +10,14 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { renderBody: /* @__PURE__ */_createRenderer(() => { const _scope1_id = _nextScopeId(); _write(`

Hello ${_escapeXML(name)}${_markResumeNode(_scope1_id, "#text/0")}

`); + _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/basic-layout/template.marko_1_name/subscriber"); _writeScope(_scope1_id, { "_": _serializedScope(_scope0_id) }); }) }); _writeScope(_scope0_id, { + "name": name, "#childScope/0": _childScope }); }); diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-layout/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-layout/__snapshots__/resume.expected.md index 59779346b..651855831 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-layout/__snapshots__/resume.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-layout/__snapshots__/resume.expected.md @@ -12,7 +12,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-layout/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-layout/__snapshots__/ssr.expected.md index 58b58da02..0e0e814da 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-layout/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-layout/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write -

Hello World

+

Hello World

# Render "End" @@ -16,7 +16,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/__snapshots__/html.expected/template.js index b180f121a..5d6cec72d 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/__snapshots__/html.expected/template.js @@ -8,8 +8,8 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { renderBody: /* @__PURE__ */_createRenderer(() => { const _scope1_id = _nextScopeId(); _write(`${_markResumeNode(_scope1_id, "#button/0")}`); - _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/template.marko_1_count"); _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/template.marko_1_count/subscriber"); + _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/template.marko_1_count"); _writeScope(_scope1_id, { "_": _serializedScope(_scope0_id) }); diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/__snapshots__/resume.expected.md index a4e3bfc7b..61f7efb9a 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/__snapshots__/resume.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/__snapshots__/resume.expected.md @@ -11,7 +11,7 @@ @@ -39,7 +39,7 @@ container.querySelector("button").click() @@ -66,7 +66,7 @@ container.querySelector("button").click() @@ -93,7 +93,7 @@ container.querySelector("button").click() diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/__snapshots__/ssr.expected.md index 98de5796a..7984d273e 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-custom-tag/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write - + # Render "End" @@ -15,7 +15,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/__snapshots__/html.expected/template.js index c1a0f77fb..cec968ebe 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/__snapshots__/html.expected/template.js @@ -6,8 +6,8 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { const _dynamicScope = _dynamicTagInput(false || Child, {}, _register( /* @__PURE__ */_createRenderer(() => { const _scope1_id = _nextScopeId(); _write(`${_markResumeNode(_scope1_id, "#button/0")}`); - _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/template.marko_1_count"); _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/template.marko_1_count/subscriber"); + _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/template.marko_1_count"); _writeScope(_scope1_id, { "_": _serializedScope(_scope0_id) }); diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/__snapshots__/resume.expected.md index de6872528..9942ca03e 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/__snapshots__/resume.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/__snapshots__/resume.expected.md @@ -13,7 +13,7 @@ @@ -45,7 +45,7 @@ container.querySelector("button").click() @@ -74,7 +74,7 @@ container.querySelector("button").click() @@ -103,7 +103,7 @@ container.querySelector("button").click() diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/__snapshots__/ssr.expected.md index 9e6b2af69..2f41d7e2f 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-dynamic-tag/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write - + # Render "End" @@ -17,7 +17,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/dom.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/dom.expected/template.js index 7c2e9193d..6c23a694d 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/dom.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/dom.expected/template.js @@ -20,11 +20,11 @@ const _num$forBody = /* @__PURE__ */_value("num", (_scope, num) => { _queueEffect(_scope, _num$forBody_effect); }, _expr_selected_num$forBody); const _selected$forBody = /* @__PURE__ */_closure("selected", null, void 0, _expr_selected_num$forBody); -const _forBody = _register("packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/template.marko_1_renderer", /* @__PURE__ */_createRenderer("", /* get, next(1), get */" D ", void 0, [_selected$forBody], void 0, (_scope, _destructure, _clean) => { +const _forBody = /* @__PURE__ */_createRenderer("", /* get, next(1), get */" D ", void 0, [_selected$forBody], void 0, (_scope, _destructure, _clean) => { let num; if (!_clean) [num] = _destructure; _num$forBody(_scope, num, _clean); -})); +}); const _for = /* @__PURE__ */_loopOf("#text/0", _forBody); const _selected = /* @__PURE__ */_value("selected", null, _inLoopScope(_selected$forBody, "#text/0")); const _setup = _scope => { diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/html.expected/template.js index de6a28c72..a888bdbc7 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/html.expected/template.js @@ -1,14 +1,12 @@ -import { attr as _attr, escapeXML as _escapeXML, markResumeNode as _markResumeNode, markResumeControlSingleNodeEnd as _markResumeControlSingleNodeEnd, write as _write, serializedScope as _serializedScope, writeEffect as _writeEffect, writeScope as _writeScope, nextScopeId as _nextScopeId, maybeFlush as _maybeFlush, createRenderer as _createRenderer, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; +import { attr as _attr, escapeXML as _escapeXML, markResumeNode as _markResumeNode, write as _write, serializedScope as _serializedScope, writeEffect as _writeEffect, writeScope as _writeScope, nextScopeId as _nextScopeId, maybeFlush as _maybeFlush, createRenderer as _createRenderer, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { const _scope0_id = _nextScopeId(); const selected = 0; - const _forScopeIds = [], - _scope1_ = new Map(); + const _scope1_ = new Map(); let _i2 = 0; for (const num of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) { const _scope1_id = _nextScopeId(); let _i = _i2++; - _forScopeIds.push(_scope1_id); _write(`${_escapeXML(num)}${_markResumeNode(_scope1_id, "#button/0")}`); _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/template.marko_1_num"); _writeScope(_scope1_id, (_s => (_scope1_.set(_i, _s), _s))({ @@ -17,7 +15,6 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { })); _maybeFlush(); } - _write(`${_markResumeControlSingleNodeEnd(_scope0_id, "#text/0", _forScopeIds)}`); _writeScope(_scope0_id, { "#text/0(": _scope1_.size ? _scope1_ : undefined }); diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/resume.expected.md index 74d1b18c8..bb5cf3e2e 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/resume.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/resume.expected.md @@ -51,7 +51,6 @@ 12 - @@ -133,7 +132,6 @@ c => click(c, 2) 12 - @@ -217,7 +215,6 @@ c => click(c, 3) 12 - @@ -300,7 +297,6 @@ c => click(c, 5) 12 - diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/ssr.expected.md index 18fd4ab8d..622110169 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write - + # Render "End" @@ -55,7 +55,6 @@ 12 - @@ -104,7 +103,6 @@ inserted #document/html0/body1/#comment21 inserted #document/html0/body1/button22 inserted #document/html0/body1/button22/#text0 inserted #document/html0/body1/#comment23 -inserted #document/html0/body1/#comment24 -inserted #document/html0/body1/script25 -inserted #document/html0/body1/script25/#text0 +inserted #document/html0/body1/script24 +inserted #document/html0/body1/script24/#text0 ``` \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/html.expected/template.js index c81332fa5..018d5b604 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/html.expected/template.js @@ -25,8 +25,8 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _write(`${_markResumeControlSingleNodeEnd(_scope0_id, "#text/0", _ifScopeId)}`); _writeScope(_scope0_id, { "clickCount": clickCount, - "#text/0!": _scope1_, - "#text/0(": _ifRenderer + "#text/0(": _ifRenderer, + "#text/0!": _scope1_ }); }); export default /* @__PURE__ */_createTemplate(_renderer, "packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-if/template.marko"); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/resume.expected.md index 9b14369d0..48a25797f 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/resume.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/resume.expected.md @@ -12,7 +12,7 @@ @@ -40,7 +40,7 @@ container.querySelector("button").click() @@ -68,7 +68,7 @@ container.querySelector("button").click() @@ -95,7 +95,7 @@ container.querySelector("button").click() diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/ssr.expected.md index 1c5a4486e..63920a8e6 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write -
+
# Render "End" @@ -16,7 +16,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/__snapshots__/html.expected/template.js index aa8ac415b..1404e8efa 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/__snapshots__/html.expected/template.js @@ -15,8 +15,8 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _writeEffect(_scope0_id, "packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/template.marko_0_show"); _writeScope(_scope0_id, { "show": show, - "#text/0!": _scope1_, - "#text/0(": _ifRenderer + "#text/0(": _ifRenderer, + "#text/0!": _scope1_ }); }); export default /* @__PURE__ */_createTemplate(_renderer, "packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/template.marko"); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/__snapshots__/resume.expected.md index fb656d668..c7bab8368 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/__snapshots__/resume.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/__snapshots__/resume.expected.md @@ -12,7 +12,7 @@ @@ -39,7 +39,7 @@ container.querySelector("button").click() @@ -68,7 +68,7 @@ container.querySelector("button").click() @@ -96,7 +96,7 @@ container.querySelector("button").click() diff --git a/packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/__snapshots__/ssr.expected.md index d0a543653..ee62b20d8 100644 --- a/packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/basic-toggle-show/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write -
Hello!
+
Hello!
# Render "End" @@ -16,7 +16,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/__snapshots__/html.expected/template.js index 65dfeba3a..4d2922ac4 100644 --- a/packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/__snapshots__/html.expected/template.js @@ -18,8 +18,9 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _writeEffect(_scope0_id, "packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/template.marko_0_show"); _writeScope(_scope0_id, { "show": show, - "#text/1!": _scope1_, - "#text/1(": _ifRenderer + "message": message, + "#text/1(": _ifRenderer, + "#text/1!": _scope1_ }); }); export default /* @__PURE__ */_createTemplate(_renderer, "packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/template.marko"); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/__snapshots__/resume.expected.md index fe534b852..ec47053b4 100644 --- a/packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/__snapshots__/resume.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/__snapshots__/resume.expected.md @@ -11,7 +11,7 @@ @@ -34,7 +34,7 @@ container.querySelector("button").click() diff --git a/packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/__snapshots__/ssr.expected.md index f829f025a..17d64095d 100644 --- a/packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/batched-updates-cleanup/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write - hi + hi # Render "End" @@ -15,7 +15,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/component-attrs-intersection/__snapshots__/dom.expected/template.hydrate.js b/packages/translator-tags/src/__tests__/fixtures/component-attrs-intersection/__snapshots__/dom.expected/template.hydrate.js new file mode 100644 index 000000000..a9b05d4b8 --- /dev/null +++ b/packages/translator-tags/src/__tests__/fixtures/component-attrs-intersection/__snapshots__/dom.expected/template.hydrate.js @@ -0,0 +1,4 @@ +import { init } from "@marko/runtime-tags/debug/dom"; +import "./template.marko"; +import "./components/display-intersection.marko"; +init(); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/component-attrs-intersection/__snapshots__/resume-sanitized.expected.md b/packages/translator-tags/src/__tests__/fixtures/component-attrs-intersection/__snapshots__/resume-sanitized.expected.md new file mode 100644 index 000000000..4a89f29a4 --- /dev/null +++ b/packages/translator-tags/src/__tests__/fixtures/component-attrs-intersection/__snapshots__/resume-sanitized.expected.md @@ -0,0 +1,18 @@ +# Render {} +```html +
+ 0 +
+${_customTag_template}
`; +export const walks = /* get, over(1), beginChild, _customTag_walks, endChild, next(1), replace, out(1) */` b/${_customTag_walks}&D%l`; +export const setup = _setup; +export default /* @__PURE__ */_createTemplate( /* @__PURE__ */_createRenderer(template, walks, setup), "packages/translator-tags/src/__tests__/fixtures/dynamic-closures/template.marko"); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/dynamic-closures/__snapshots__/html.expected/components/custom-tag.js b/packages/translator-tags/src/__tests__/fixtures/dynamic-closures/__snapshots__/html.expected/components/custom-tag.js new file mode 100644 index 000000000..7c7ee5494 --- /dev/null +++ b/packages/translator-tags/src/__tests__/fixtures/dynamic-closures/__snapshots__/html.expected/components/custom-tag.js @@ -0,0 +1,12 @@ +import { write as _write, dynamicTagInput as _dynamicTagInput, markResumeControlEnd as _markResumeControlEnd, writeScope as _writeScope, nextScopeId as _nextScopeId, createRenderer as _createRenderer, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; +const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { + const _scope0_id = _nextScopeId(); + _write("
"); + const _dynamicScope = _dynamicTagInput(input.renderBody, {}); + _write(`${_markResumeControlEnd(_scope0_id, "#text/0")}
`); + _writeScope(_scope0_id, { + "#text/0!": _dynamicScope, + "#text/0(": input.renderBody + }); +}); +export default /* @__PURE__ */_createTemplate(_renderer, "packages/translator-tags/src/__tests__/fixtures/dynamic-closures/components/custom-tag.marko"); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/dynamic-closures/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/dynamic-closures/__snapshots__/html.expected/template.js new file mode 100644 index 000000000..90330176e --- /dev/null +++ b/packages/translator-tags/src/__tests__/fixtures/dynamic-closures/__snapshots__/html.expected/template.js @@ -0,0 +1,43 @@ +const a = 1; +import { markResumeNode as _markResumeNode, write as _write, escapeXML as _escapeXML, serializedScope as _serializedScope, writeEffect as _writeEffect, writeScope as _writeScope, nextScopeId as _nextScopeId, createRenderer as _createRenderer, peekSerializedScope as _peekSerializedScope, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; +import _customTag from "./components/custom-tag.marko"; +const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { + const _scope0_id = _nextScopeId(); + const b = 2; + const c = 3; + _write(`${_markResumeNode(_scope0_id, "#button/0")}`); + const _childScope = _peekSerializedScope(); + _customTag._({ + renderBody: /* @__PURE__ */_createRenderer(() => { + const _scope1_id = _nextScopeId(); + _write(`${_escapeXML(a)} ${_escapeXML(b)} ${_escapeXML(c)}${_markResumeNode(_scope1_id, "#text/2")}`); + _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/dynamic-closures/template.marko_1_c/subscriber"); + _writeScope(_scope1_id, { + "_": _serializedScope(_scope0_id) + }); + }) + }); + _write("
"); + if (Math.random()) { + const _scope2_id = _nextScopeId(); + if (Math.random()) { + const _scope3_id = _nextScopeId(); + _write(`${_escapeXML(a)} ${_escapeXML(b)} ${_escapeXML(c)}${_markResumeNode(_scope3_id, "#text/2")}`); + _writeEffect(_scope3_id, "packages/translator-tags/src/__tests__/fixtures/dynamic-closures/template.marko_3_c/subscriber"); + _writeScope(_scope3_id, { + "_": _serializedScope(_scope2_id) + }); + } + _writeScope(_scope2_id, { + "_": _serializedScope(_scope0_id) + }); + } + _write("
"); + _writeEffect(_scope0_id, "packages/translator-tags/src/__tests__/fixtures/dynamic-closures/template.marko_0"); + _writeScope(_scope0_id, { + "b": b, + "c": c, + "#childScope/1": _childScope + }); +}); +export default /* @__PURE__ */_createTemplate(_renderer, "packages/translator-tags/src/__tests__/fixtures/dynamic-closures/template.marko"); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/dynamic-closures/__snapshots__/resume-sanitized.expected.md b/packages/translator-tags/src/__tests__/fixtures/dynamic-closures/__snapshots__/resume-sanitized.expected.md new file mode 100644 index 000000000..620b728a5 --- /dev/null +++ b/packages/translator-tags/src/__tests__/fixtures/dynamic-closures/__snapshots__/resume-sanitized.expected.md @@ -0,0 +1,24 @@ +# Render {} +```html +
1 2 3
1 2 3
+ + +# Render "End" +```html + + + + ${_markResumeNode(_scope2_id, "#button/0")}`); - _writeEffect(_scope2_id, "packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/template.marko_2_count"); _writeEffect(_scope2_id, "packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/template.marko_2_count/subscriber"); + _writeEffect(_scope2_id, "packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/template.marko_2_count"); _writeScope(_scope2_id, _scope2_ = { "_": _serializedScope(_scope1_id) }); @@ -25,8 +25,8 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _writeEffect(_scope1_id, "packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/template.marko_1_inner"); _writeScope(_scope1_id, _scope1_ = { "_": _serializedScope(_scope0_id), - "#text/1!": _scope2_, - "#text/1(": _ifRenderer + "#text/1(": _ifRenderer, + "#text/1!": _scope2_ }); _register(_ifRenderer2 = /* @__PURE__ */_createRenderer(() => {}), "packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/template.marko_1_renderer"); } @@ -36,8 +36,8 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { "outer": outer, "inner": inner, "count": count, - "#text/1!": _scope1_, - "#text/1(": _ifRenderer2 + "#text/1(": _ifRenderer2, + "#text/1!": _scope1_ }); }); export default /* @__PURE__ */_createTemplate(_renderer, "packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/template.marko"); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/__snapshots__/resume.expected.md index bda6374b9..c537688fa 100644 --- a/packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/__snapshots__/resume.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/__snapshots__/resume.expected.md @@ -24,7 +24,7 @@ @@ -64,7 +64,7 @@ container.querySelector("#count").click() @@ -104,7 +104,7 @@ container.querySelector("#count").click() @@ -138,7 +138,7 @@ container.querySelector("#inner").click() @@ -178,7 +178,7 @@ container.querySelector("#inner").click() @@ -218,7 +218,7 @@ container.querySelector("#count").click() @@ -245,7 +245,7 @@ container.querySelector("#outer").click() @@ -286,7 +286,7 @@ container.querySelector("#outer").click() @@ -327,7 +327,7 @@ container.querySelector("#count").click() diff --git a/packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/__snapshots__/ssr.expected.md index 83f9bf4aa..f5fe06e60 100644 --- a/packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/toggle-nested-2/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write -
+
# Render "End" @@ -28,7 +28,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/toggle-nested/__snapshots__/html.expected/template.js b/packages/translator-tags/src/__tests__/fixtures/toggle-nested/__snapshots__/html.expected/template.js index 9277ce5bc..c8ddf5da3 100644 --- a/packages/translator-tags/src/__tests__/fixtures/toggle-nested/__snapshots__/html.expected/template.js +++ b/packages/translator-tags/src/__tests__/fixtures/toggle-nested/__snapshots__/html.expected/template.js @@ -1,4 +1,4 @@ -import { write as _write, markResumeScopeStart as _markResumeScopeStart, escapeXML as _escapeXML, markResumeNode as _markResumeNode, serializedScope as _serializedScope, writeScope as _writeScope, nextScopeId as _nextScopeId, createRenderer as _createRenderer, register as _register, markResumeControlSingleNodeEnd as _markResumeControlSingleNodeEnd, markResumeControlEnd as _markResumeControlEnd, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; +import { write as _write, markResumeScopeStart as _markResumeScopeStart, escapeXML as _escapeXML, markResumeNode as _markResumeNode, serializedScope as _serializedScope, writeEffect as _writeEffect, writeScope as _writeScope, nextScopeId as _nextScopeId, createRenderer as _createRenderer, register as _register, markResumeControlSingleNodeEnd as _markResumeControlSingleNodeEnd, markResumeControlEnd as _markResumeControlEnd, createTemplate as _createTemplate } from "@marko/runtime-tags/debug/html"; const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { const _scope0_id = _nextScopeId(); const { @@ -15,6 +15,7 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { if (value1) { const _scope2_id = _nextScopeId(); _write(`${_escapeXML(value1)}${_markResumeNode(_scope2_id, "#text/0")}`); + _writeEffect(_scope2_id, "packages/translator-tags/src/__tests__/fixtures/toggle-nested/template.marko_2_value1/subscriber"); _writeScope(_scope2_id, _scope2_ = { "_": _serializedScope(_scope1_id) }); @@ -26,6 +27,7 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { if (value2) { const _scope3_id = _nextScopeId(); _write(`${_escapeXML(value2)}${_markResumeNode(_scope3_id, "#text/0")}`); + _writeEffect(_scope3_id, "packages/translator-tags/src/__tests__/fixtures/toggle-nested/template.marko_3_value2/subscriber"); _writeScope(_scope3_id, _scope3_ = { "_": _serializedScope(_scope1_id) }); @@ -35,17 +37,19 @@ const _renderer = /* @__PURE__ */_createRenderer((input, _tagVar) => { _write(`${_markResumeControlSingleNodeEnd(_scope1_id, "#text/1", _ifScopeId2)}`); _writeScope(_scope1_id, _scope1_ = { "_": _serializedScope(_scope0_id), - "#text/0!": _scope2_, "#text/0(": _ifRenderer, - "#text/1!": _scope3_, - "#text/1(": _ifRenderer2 + "#text/0!": _scope2_, + "#text/1(": _ifRenderer2, + "#text/1!": _scope3_ }); _register(_ifRenderer3 = /* @__PURE__ */_createRenderer(() => {}), "packages/translator-tags/src/__tests__/fixtures/toggle-nested/template.marko_1_renderer"); } _write(`${_markResumeControlEnd(_scope0_id, "#text/0")}`); _writeScope(_scope0_id, { - "#text/0!": _scope1_, - "#text/0(": _ifRenderer3 + "value1": value1, + "value2": value2, + "#text/0(": _ifRenderer3, + "#text/0!": _scope1_ }); }); export default /* @__PURE__ */_createTemplate(_renderer, "packages/translator-tags/src/__tests__/fixtures/toggle-nested/template.marko"); \ No newline at end of file diff --git a/packages/translator-tags/src/__tests__/fixtures/toggle-nested/__snapshots__/resume.expected.md b/packages/translator-tags/src/__tests__/fixtures/toggle-nested/__snapshots__/resume.expected.md index 39ce64504..92c568a3e 100644 --- a/packages/translator-tags/src/__tests__/fixtures/toggle-nested/__snapshots__/resume.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/toggle-nested/__snapshots__/resume.expected.md @@ -7,7 +7,7 @@ diff --git a/packages/translator-tags/src/__tests__/fixtures/toggle-nested/__snapshots__/ssr.expected.md b/packages/translator-tags/src/__tests__/fixtures/toggle-nested/__snapshots__/ssr.expected.md index 2010012ff..0ed69b8ca 100644 --- a/packages/translator-tags/src/__tests__/fixtures/toggle-nested/__snapshots__/ssr.expected.md +++ b/packages/translator-tags/src/__tests__/fixtures/toggle-nested/__snapshots__/ssr.expected.md @@ -1,5 +1,5 @@ # Write -
+
# Render "End" @@ -11,7 +11,7 @@ diff --git a/packages/translator-tags/src/core/condition/if.ts b/packages/translator-tags/src/core/condition/if.ts index 9a8577319..7b4bb7001 100644 --- a/packages/translator-tags/src/core/condition/if.ts +++ b/packages/translator-tags/src/core/condition/if.ts @@ -20,6 +20,7 @@ import { getScopeIdentifier, getSection, startSection, + checkStatefulClosures, } from "../../util/sections"; import { addValue, @@ -167,6 +168,9 @@ export function exitBranchAnalyze(tag: t.NodePath) { rootExtra.singleNodeOptimization = branches.every(({ tag }) => { return tag.node.body.body.length === 1; }); + branches.forEach(({ section }) => { + section.upstreamExpression = rootExtra; + }); } } @@ -194,9 +198,10 @@ export function exitBranchTranslate(tag: t.NodePath) { const nodeRef = rootExtra[kBinding]!; const isStateful = isStatefulReferences(rootExtra.referencedBindings); const singleNodeOptimization = rootExtra.singleNodeOptimization; + const hasStatefulClosures = checkStatefulClosures(bodySection, true); if (isOutputHTML()) { - if (isStateful) { + if (isStateful || hasStatefulClosures) { setRegisterScopeBuilder(tag, (scope: t.Expression) => { return t.assignmentExpression( "=", @@ -232,10 +237,6 @@ export function exitBranchTranslate(tag: t.NodePath) { ); }); - if (isStateful) { - writer.setRegisterRenderer(section, true); - } - tag.remove(); if (testAttr) { @@ -268,6 +269,7 @@ export function exitBranchTranslate(tag: t.NodePath) { for (let i = branches.length; i--; ) { const { tag, section } = branches[i]; const branchScopeIdentifier = getScopeIdentifier(section, true); + const branchHasStatefulClosures = checkStatefulClosures(section, true); branchScopeIdentifier.name = ifScopeIdentifier.name; if (isStateful) { @@ -287,7 +289,8 @@ export function exitBranchTranslate(tag: t.NodePath) { ), ) as any, ); - + } + if (isStateful || branchHasStatefulClosures) { if (singleNodeOptimization) { tag.node.body.body.push( t.expressionStatement( @@ -313,7 +316,7 @@ export function exitBranchTranslate(tag: t.NodePath) { tag.remove(); } - if (!isStateful) { + if (!isStateful && !hasStatefulClosures) { nextTag.insertBefore(statement!); } else { nextTag.insertBefore([ @@ -323,24 +326,33 @@ export function exitBranchTranslate(tag: t.NodePath) { singleNodeOptimization && t.variableDeclarator(ifScopeIdIdentifier), t.variableDeclarator(ifScopeIdentifier), - t.variableDeclarator(ifRendererIdentifier), + isStateful && t.variableDeclarator(ifRendererIdentifier), ].filter(Boolean) as t.VariableDeclarator[], ), statement!, ]); - if (singleNodeOptimization) { - write`${callRuntime( - "markResumeControlSingleNodeEnd", - getScopeIdIdentifier(section), - getScopeAccessorLiteral(nodeRef), - ifScopeIdIdentifier, - )}`; - } else { - write`${callRuntime( - "markResumeControlEnd", - getScopeIdIdentifier(section), - getScopeAccessorLiteral(nodeRef), - )}`; + if (isStateful) { + if (singleNodeOptimization) { + write`${callRuntime( + "markResumeControlSingleNodeEnd", + getScopeIdIdentifier(section), + getScopeAccessorLiteral(nodeRef), + ifScopeIdIdentifier, + )}`; + } else { + write`${callRuntime( + "markResumeControlEnd", + getScopeIdIdentifier(section), + getScopeAccessorLiteral(nodeRef), + )}`; + } + getSerializedScopeProperties(section).set( + t.stringLiteral( + getScopeAccessorLiteral(nodeRef).value + + AccessorChar.ConditionalRenderer, + ), + ifRendererIdentifier, + ); } getSerializedScopeProperties(section).set( t.stringLiteral( @@ -349,13 +361,6 @@ export function exitBranchTranslate(tag: t.NodePath) { ), ifScopeIdentifier, ); - getSerializedScopeProperties(section).set( - t.stringLiteral( - getScopeAccessorLiteral(nodeRef).value + - AccessorChar.ConditionalRenderer, - ), - ifRendererIdentifier, - ); } } } diff --git a/packages/translator-tags/src/core/for.ts b/packages/translator-tags/src/core/for.ts index bbceeb7f6..b31d5ad0b 100644 --- a/packages/translator-tags/src/core/for.ts +++ b/packages/translator-tags/src/core/for.ts @@ -23,6 +23,7 @@ import { getScopeIdIdentifier, getScopeIdentifier, getSection, + checkStatefulClosures, startSection, } from "../util/sections"; import { @@ -78,6 +79,7 @@ export default { trackParamsReferences(tagBody, BindingType.param, undefined, tagExtra); }, exit(tag) { + const bodySection = getSection(tag.get("body")); const extra = tag.node.extra!; analyzeAttributeTags(tag); @@ -86,6 +88,8 @@ export default { tag.node.attributes.map((attr) => attr.value), ); + bodySection.upstreamExpression = extra; + extra.singleNodeOptimization = tag.node.body.body.length === 1; }, }, @@ -316,6 +320,7 @@ const translateHTML = { const block = t.blockStatement(body); const write = writer.writeTo(tag); const replacement: t.Node[] = []; + const hasStatefulClosures = checkStatefulClosures(bodySection, true); let byParams: t.Expression[]; let keyExpression: t.Expression | undefined = t.identifier("NOO"); @@ -323,7 +328,7 @@ const translateHTML = { tag.parentPath.parent.extra![kSerializeMarker] = true; } - if (isStateful || bodySection.closures) { + if (isStateful || hasStatefulClosures) { setRegisterScopeBuilder(tag, (scope: t.Expression) => { const tempScopeIdentifier = currentProgramPath.scope.generateUidIdentifier("s"); @@ -404,7 +409,7 @@ const translateHTML = { valParam = tempValParam; } - if (indexParam || isStateful || bodySection.closures) { + if (indexParam || isStateful || hasStatefulClosures) { indexParam ??= currentProgramPath.scope.generateUidIdentifier("i"); const indexName = tag.scope.generateUidIdentifierBasedOnNode( indexParam, @@ -462,7 +467,7 @@ const translateHTML = { const stepName = tag.scope.generateUidIdentifier("step"); const fromName = tag.scope.generateUidIdentifier("from"); - if (indexParam || isStateful || bodySection.closures) { + if (indexParam || isStateful || hasStatefulClosures) { indexParam ??= currentProgramPath.scope.generateUidIdentifier("i"); keyExpression = indexParam as t.Identifier; block.body.unshift( @@ -507,7 +512,7 @@ const translateHTML = { ); } - if ((isStateful || bodySection.closures) && !hasNestedAttributeTags) { + if ((isStateful || hasStatefulClosures) && !hasNestedAttributeTags) { const forScopeIdsIdentifier = tag.scope.generateUidIdentifier("forScopeIds"); const forScopesIdentifier = getScopeIdentifier(bodySection); @@ -516,7 +521,8 @@ const translateHTML = { t.variableDeclaration( "const", [ - singleNodeOptimization && + isStateful && + singleNodeOptimization && t.variableDeclarator( forScopeIdsIdentifier, t.arrayExpression([]), @@ -529,27 +535,29 @@ const translateHTML = { ), ); - if (singleNodeOptimization) { - block.body.push( - t.expressionStatement( - t.callExpression( - t.memberExpression(forScopeIdsIdentifier, t.identifier("push")), - [getScopeIdIdentifier(bodySection)], + if (isStateful) { + if (singleNodeOptimization) { + block.body.push( + t.expressionStatement( + t.callExpression( + t.memberExpression(forScopeIdsIdentifier, t.identifier("push")), + [getScopeIdIdentifier(bodySection)], + ), ), - ), - ); - write`${callRuntime( - "markResumeControlSingleNodeEnd", - getScopeIdIdentifier(tagSection), - getScopeAccessorLiteral(nodeRef), - forScopeIdsIdentifier, - )}`; - } else { - write`${callRuntime( - "markResumeControlEnd", - getScopeIdIdentifier(tagSection), - getScopeAccessorLiteral(nodeRef), - )}`; + ); + write`${callRuntime( + "markResumeControlSingleNodeEnd", + getScopeIdIdentifier(tagSection), + getScopeAccessorLiteral(nodeRef), + forScopeIdsIdentifier, + )}`; + } else { + write`${callRuntime( + "markResumeControlEnd", + getScopeIdIdentifier(tagSection), + getScopeAccessorLiteral(nodeRef), + )}`; + } } getSerializedScopeProperties(tagSection).set( t.stringLiteral( diff --git a/packages/translator-tags/src/util/references.ts b/packages/translator-tags/src/util/references.ts index ddd46fd08..3f89c6394 100644 --- a/packages/translator-tags/src/util/references.ts +++ b/packages/translator-tags/src/util/references.ts @@ -1,5 +1,6 @@ import { types as t } from "@marko/compiler"; import { getExprRoot, getFnRoot, getMarkoRoot } from "./get-root"; +import { isStatefulReferences } from "./is-stateful"; import { isOptimize } from "./marko-config"; import { addSorted, @@ -253,13 +254,6 @@ function trackReference( const exprExtra = (exprRoot.node.extra ??= {}); addReferenceToExpression(exprRoot, binding); - // TODO: this should be in finalizeReferences - // probably should be a set - if (section !== binding.section) { - section.closures ??= []; - section.closures.push(binding); - } - // TODO: remove if (fnRoot) { const name = (fnRoot.node as t.FunctionExpression).id?.name; @@ -381,12 +375,12 @@ export function finalizeReferences() { forEach(referencedBindings, (bindingReference) => { if (isEffect) { bindingReference.serialize = true; - section.bindings.add(bindingReference); } }); } } + // mark bindings that need to be serialized due to being in an intersection with state for (const intersection of intersections) { const numReferences = intersection.length; // TODO: in some cases we should be able to short circuit this @@ -407,6 +401,28 @@ export function finalizeReferences() { } } + // mark bindings that need to be serialized due to being closed over by stateful sections + forEachSection((section) => { + for (const binding of section.closures) { + if (!binding.serialize) { + let serialize = false; + const sourceSection = binding.section; + let currentSection = section; + while ( + currentSection !== sourceSection && + !(serialize = + !currentSection.upstreamExpression || + isStatefulReferences( + currentSection.upstreamExpression.referencedBindings, + )) + ) { + currentSection = currentSection.parent!; + } + binding.serialize = serialize; + } + } + }); + forEachSection(({ id, bindings }) => { const sortedBindings = [...bindings] .filter((b) => b.section.id === id) @@ -488,7 +504,9 @@ function addReference( referencedBindings: ReferencedBindings, binding: Binding, ) { - section.bindings.add(binding); + if (section !== binding.section) { + section.closures.add(binding); + } const newIntersection = bindingUtil.add(referencedBindings, binding); return findReferences(section, newIntersection); } diff --git a/packages/translator-tags/src/util/sections.ts b/packages/translator-tags/src/util/sections.ts index 0de374f92..d512e9ec7 100644 --- a/packages/translator-tags/src/util/sections.ts +++ b/packages/translator-tags/src/util/sections.ts @@ -5,6 +5,7 @@ import { } from "@marko/babel-utils"; import { types as t } from "@marko/compiler"; import { currentProgramPath } from "../visitors/program"; +import { isStatefulReferences } from "./is-stateful"; import type { Binding } from "./references"; import { createSectionState } from "./state"; import analyzeTagNameType, { TagNameType } from "./tag-name-type"; @@ -20,10 +21,11 @@ export type Section = { name: string; depth: number; parent?: Section; - closures?: Binding[]; + closures: Set; bindings: Set; startNodeContentType: ContentType; endNodeContentType: ContentType; + upstreamExpression: t.NodeExtra | undefined; }; declare module "@marko/compiler/dist/types" { @@ -62,9 +64,11 @@ export function startSection( name: sectionName, depth: parentSection ? parentSection.depth + 1 : 0, parent: parentSection, + closures: new Set(), bindings: new Set(), startNodeContentType: getStartNodeContentType(path), endNodeContentType: getEndNodeContentType(path), + upstreamExpression: undefined, }; sections.push(section); } @@ -217,3 +221,25 @@ function getNodeContentType( } return ContentType.Dynamic; } + +export const isStatefulSection = (section: Section) => { + const upstreamExpression = section.upstreamExpression; + return ( + !upstreamExpression || + isStatefulReferences(upstreamExpression.referencedBindings) + ); +}; + +export const checkStatefulClosures = ( + section: Section, + immediateOnly: boolean, +) => { + for (const binding of section.closures) { + if ( + (!immediateOnly || section.parent === binding.section) && + isStatefulReferences(binding) + ) { + return true; + } + } +}; diff --git a/packages/translator-tags/src/util/signals.ts b/packages/translator-tags/src/util/signals.ts index 8b91757e8..714c2b728 100644 --- a/packages/translator-tags/src/util/signals.ts +++ b/packages/translator-tags/src/util/signals.ts @@ -7,6 +7,7 @@ import { currentProgramPath, scopeIdentifier, } from "../visitors/program"; +import { isStatefulReferences } from "./is-stateful"; import { isOutputHTML } from "./marko-config"; import { type Opt, push } from "./optional"; import { @@ -642,7 +643,10 @@ export function writeSignals(section: Section) { ); } - if (signal.isDynamicClosure) { + if ( + signal.isDynamicClosure && + isStatefulReferences(signal.referencedBindings) + ) { value = callRuntime( "registerSubscriber", t.stringLiteral( @@ -719,10 +723,9 @@ export function writeHTMLResumeStatements( const section = getSection(path); const allSignals = Array.from(getSignals(section).values()); const scopeIdIdentifier = getScopeIdIdentifier(section); - const closures = section.closures; - if (closures) { - for (const closure of closures) { + for (const closure of section.closures) { + if (isStatefulReferences(closure)) { let currentSection = section; while (currentSection !== closure.section) { getSerializedScopeProperties(currentSection).set( @@ -733,6 +736,27 @@ export function writeHTMLResumeStatements( ), ); } + setForceResumeScope(closure.section); + const isImmediateOwner = section.parent?.id === closure.section.id; + // TODO: getSubscribeBuilder is not the right check + // the builder shouldn't get set for the HTML output + // we're setting it to an empty builder from if/for purely for this check + const isDynamicClosure = + !getSubscribeBuilder(section) || !isImmediateOwner; + if (isDynamicClosure) { + path.pushContainer( + "body", + t.expressionStatement( + callRuntime( + "writeEffect", + scopeIdIdentifier, + t.stringLiteral( + getResumeRegisterId(section, closure, "subscriber"), + ), + ), + ), + ); + } } } @@ -758,37 +782,10 @@ export function writeHTMLResumeStatements( section.bindings.forEach((binding) => { if (binding.serialize && binding.type !== BindingType.dom) { const accessor = getScopeAccessorLiteral(binding); - if (binding.section.id === section.id) { - serializedProperties.push( - t.objectProperty(accessor, t.identifier(binding.name)), - ); - accessors.add(accessor.value); - } else { - const isImmediateOwner = section.parent?.id === binding.section.id; - // TODO: getSubscribeBuilder is not the right check - // the builder shouldn't get set for the HTML output - // we're setting it to an empty builder from if/for purely for this check - const isDynamicClosure = - !getSubscribeBuilder(section) || !isImmediateOwner; - if (isDynamicClosure) { - path.pushContainer( - "body", - t.expressionStatement( - callRuntime( - "writeEffect", - scopeIdIdentifier, - t.stringLiteral( - getResumeRegisterId(section, binding, "subscriber"), - ), - ), - ), - ); - } - getSerializedScopeProperties(binding.section).set( - accessor, - t.identifier(binding.name), - ); - } + serializedProperties.push( + t.objectProperty(accessor, t.identifier(binding.name)), + ); + accessors.add(accessor.value); } }); diff --git a/packages/translator-tags/src/util/writer.ts b/packages/translator-tags/src/util/writer.ts index ca40516c5..cf7eb5707 100644 --- a/packages/translator-tags/src/util/writer.ts +++ b/packages/translator-tags/src/util/writer.ts @@ -31,13 +31,6 @@ const [getWrites] = createSectionState<(string | t.Expression)[]>( () => [""], ); -const [getRegisterRenderer, setRegisterRenderer] = createSectionState( - "registerRenderer", - () => false, -); - -export { setRegisterRenderer }; - export function writeTo(path: t.NodePath) { const section = getSection(path); return ( @@ -104,7 +97,6 @@ export function getSectionMeta(section: Section) { writes: toTemplateOrStringLiteral([writePrefix, ...writes, writePostfix]) || t.stringLiteral(""), - register: getRegisterRenderer(section), }; } diff --git a/packages/translator-tags/src/visitors/program/dom.ts b/packages/translator-tags/src/visitors/program/dom.ts index ddfc09c18..f5b7f032d 100644 --- a/packages/translator-tags/src/visitors/program/dom.ts +++ b/packages/translator-tags/src/visitors/program/dom.ts @@ -5,6 +5,7 @@ import { forEachSectionReverse, getSection, getSectionPath, + isStatefulSection, } from "../../util/sections"; import { getClosures, @@ -38,8 +39,7 @@ export default { writeSignals(childSection); if (childSection !== section) { - const { walks, writes, setup, register } = - writer.getSectionMeta(childSection); + const { walks, writes, setup } = writer.getSectionMeta(childSection); const closures = getClosures(childSection); const identifier = writer.getRenderer(childSection); const renderer = callRuntime( @@ -55,8 +55,7 @@ export default { t.variableDeclaration("const", [ t.variableDeclarator( identifier, - //eslint-disable-next-line no-constant-condition - register || true + isStatefulSection(childSection) ? callRuntime( "register", t.stringLiteral(