From 0ca372cc265c02ecebc566eec0e134a7cffa00db Mon Sep 17 00:00:00 2001
From: Michael Rawlings
Date: Tue, 5 Apr 2022 15:18:35 -0400
Subject: [PATCH] feat: basic nested hydration
---
.sizes.json | 22 +-
packages/runtime/package.json | 2 +-
packages/runtime/src/dom/hydrate.ts | 4 +-
.../__snapshots__/html.expected.js | 20 +-
.../__snapshots__/html.expected.js | 2 +
.../__snapshots__/html.expected.js | 4 +-
.../__snapshots__/html.expected.js | 18 +-
.../__snapshots__/html.expected.js | 47 +-
.../attr-style/__snapshots__/html.expected.js | 5 +-
.../__snapshots__/html.expected.js | 4 +-
.../html.expected/components/my-button.js | 5 +-
.../__snapshots__/html.expected.js | 6 +-
.../__snapshots__/dom.expected.js | 21 +
.../dom.expected/components/comments.js | 124 +++++
.../__snapshots__/html.expected.js | 17 +
.../html.expected/components/comments.js | 49 ++
.../__snapshots__/ssr.expected.md | 470 ++++++++++++++++++
.../components/comments.marko | 16 +
.../template.marko | 2 +
.../basic-inert-collapsible-tree/test.ts | 29 ++
.../__snapshots__/html.expected.js | 8 +-
.../__snapshots__/html.expected.js | 12 +-
.../__snapshots__/html.expected.js | 2 +
.../__snapshots__/html.expected.js | 6 +-
.../__snapshots__/html.expected.js | 11 +-
.../__snapshots__/html.expected.js | 5 +-
.../__snapshots__/html.expected.js | 4 +
.../for-tag/__snapshots__/html.expected.js | 24 +-
.../__snapshots__/html.expected.js | 5 +-
.../if-tag/__snapshots__/html.expected.js | 33 +-
.../__snapshots__/html.expected.js | 4 +-
.../yield-tag/__snapshots__/html.expected.js | 15 +-
packages/translator/src/core/condition/if.ts | 10 +-
packages/translator/src/core/for.ts | 3 +
.../translator/src/visitors/program/html.ts | 3 +-
35 files changed, 947 insertions(+), 65 deletions(-)
create mode 100644 packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/dom.expected.js
create mode 100644 packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/dom.expected/components/comments.js
create mode 100644 packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/html.expected.js
create mode 100644 packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/html.expected/components/comments.js
create mode 100644 packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/ssr.expected.md
create mode 100644 packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/components/comments.marko
create mode 100644 packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/template.marko
create mode 100644 packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/test.ts
diff --git a/.sizes.json b/.sizes.json
index f0287eb3c..01d2825b1 100644
--- a/.sizes.json
+++ b/.sizes.json
@@ -6,9 +6,9 @@
{
"name": "*",
"total": {
- "min": 9174,
- "gzip": 4102,
- "brotli": 3749
+ "min": 9194,
+ "gzip": 4113,
+ "brotli": 3759
}
},
{
@@ -33,18 +33,18 @@
"name": "counter 💧",
"user": {
"min": 249,
- "gzip": 196,
- "brotli": 176
+ "gzip": 195,
+ "brotli": 194
},
"runtime": {
- "min": 2149,
- "gzip": 1168,
- "brotli": 1043
+ "min": 2169,
+ "gzip": 1180,
+ "brotli": 1061
},
"total": {
- "min": 2398,
- "gzip": 1364,
- "brotli": 1219
+ "min": 2418,
+ "gzip": 1375,
+ "brotli": 1255
}
}
]
diff --git a/packages/runtime/package.json b/packages/runtime/package.json
index f0c0f3b6a..53e305b68 100644
--- a/packages/runtime/package.json
+++ b/packages/runtime/package.json
@@ -22,7 +22,7 @@
"scripts": {
"build": "npm run build:types && npm run build:js",
"build:js": "node -r esbuild-register esbuild.ts",
- "build:types": "tsc -b",
+ "build:types": "tsc -d",
"prepublishOnly": "npm run build"
}
}
diff --git a/packages/runtime/src/dom/hydrate.ts b/packages/runtime/src/dom/hydrate.ts
index a65f2916d..a435c5256 100644
--- a/packages/runtime/src/dom/hydrate.ts
+++ b/packages/runtime/src/dom/hydrate.ts
@@ -93,7 +93,9 @@ export function init(runtimeId = "M" /* [a-zA-Z0-9]+ */) {
const scopeId = parseInt(
nodeValue.slice(nodeValue.lastIndexOf(" ") + 1)
);
- const scope = scopeLookup[scopeId];
+ const scope = (scopeLookup[scopeId] = scopeLookup[scopeId] || {
+ ___id: scopeId * SCOPE_ID_MULTIPLIER,
+ });
scope[data] = node;
} else if (token === HydrateSymbols.SECTION_START) {
if (currentScope) {
diff --git a/packages/translator/src/__tests__/fixtures/at-tag-inside-if-tag/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/at-tag-inside-if-tag/__snapshots__/html.expected.js
index 83bbf41fa..f3bc51730 100644
--- a/packages/translator/src/__tests__/fixtures/at-tag-inside-if-tag/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/at-tag-inside-if-tag/__snapshots__/html.expected.js
@@ -1,7 +1,9 @@
import { markHydrateNode as _markHydrateNode, write as _write, nextScopeId as _nextScopeId, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
import _customTag from "./components/custom-tag/index.marko";
-const _renderer = input => {
+const _renderer = ({
+ x
+}) => {
const _scope = _nextScopeId();
let _thing;
@@ -10,14 +12,18 @@ const _renderer = input => {
_write(`${_markHydrateNode(_scope, 0)}`);
- if (x) _thing = {
- x: 1,
+ if (x) {
+ const _scope = _nextScopeId();
- renderBody() {
- _write("Hello");
- }
+ _thing = {
+ x: 1,
- };
+ renderBody() {
+ _write("Hello");
+ }
+
+ };
+ }
_customTag({
thing: _thing
diff --git a/packages/translator/src/__tests__/fixtures/at-tags-dynamic-and-static/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/at-tags-dynamic-and-static/__snapshots__/html.expected.js
index 7e4eb1dce..95a4afc0d 100644
--- a/packages/translator/src/__tests__/fixtures/at-tags-dynamic-and-static/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/at-tags-dynamic-and-static/__snapshots__/html.expected.js
@@ -14,6 +14,8 @@ const _renderer = input => {
a: 1,
b: 2
}) {
+ const _scope = _nextScopeId();
+
_item.push({});
}
diff --git a/packages/translator/src/__tests__/fixtures/at-tags-dynamic-tag-parent/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/at-tags-dynamic-tag-parent/__snapshots__/html.expected.js
index 79782d3eb..49a4a3090 100644
--- a/packages/translator/src/__tests__/fixtures/at-tags-dynamic-tag-parent/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/at-tags-dynamic-tag-parent/__snapshots__/html.expected.js
@@ -1,6 +1,8 @@
import { write as _write, nextScopeId as _nextScopeId, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
-const _renderer = input => {
+const _renderer = ({
+ x
+}) => {
const _scope = _nextScopeId();
<${x} header={
diff --git a/packages/translator/src/__tests__/fixtures/at-tags-dynamic-with-params/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/at-tags-dynamic-with-params/__snapshots__/html.expected.js
index fc5d4c777..c36780fd3 100644
--- a/packages/translator/src/__tests__/fixtures/at-tags-dynamic-with-params/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/at-tags-dynamic-with-params/__snapshots__/html.expected.js
@@ -1,7 +1,9 @@
import { markHydrateNode as _markHydrateNode, write as _write, escapeXML as _escapeXML, nextScopeId as _nextScopeId, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
import _hello from "./components/hello/index.marko";
-const _renderer = input => {
+const _renderer = ({
+ x
+}) => {
const _scope = _nextScopeId();
let _item;
@@ -10,12 +12,16 @@ const _renderer = input => {
_write(`${_markHydrateNode(_scope, 0)}`);
- if (x) _item = {
- renderBody(y) {
- _write(`${_markHydrateNode(_scope, 0)}${_escapeXML(y)}`);
- }
+ if (x) {
+ const _scope = _nextScopeId();
- };
+ _item = {
+ renderBody(y) {
+ _write(`${_markHydrateNode(_scope, 0)}${_escapeXML(y)}`);
+ }
+
+ };
+ }
_hello({
item: _item
diff --git a/packages/translator/src/__tests__/fixtures/at-tags-dynamic/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/at-tags-dynamic/__snapshots__/html.expected.js
index b2a7579fb..acabd8f17 100644
--- a/packages/translator/src/__tests__/fixtures/at-tags-dynamic/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/at-tags-dynamic/__snapshots__/html.expected.js
@@ -1,4 +1,4 @@
-import { markHydrateNode as _markHydrateNode, write as _write, escapeXML as _escapeXML, nextScopeId as _nextScopeId, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
+import { markHydrateNode as _markHydrateNode, write as _write, nextScopeId as _nextScopeId, escapeXML as _escapeXML, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
import _hello from "./components/hello/index.marko";
const _renderer = input => {
@@ -13,27 +13,37 @@ const _renderer = input => {
_write(`${_markHydrateNode(_scope, 0)}`);
for (const color of ["red", "blue", "green"]) {
+ const _scope = _nextScopeId();
+
_write(`${_markHydrateNode(_scope, 0)}`);
- if (color === "red") _item.push({
- style: {
- color
- },
+ if (color === "red") {
+ const _scope = _nextScopeId();
- renderBody() {
- _write("foo");
- }
+ _item.push({
+ style: {
+ color
+ },
- });else _item.push({
- style: {
- color
- },
+ renderBody() {
+ _write("foo");
+ }
- renderBody() {
- _write("bar");
- }
+ });
+ } else {
+ const _scope = _nextScopeId();
- });
+ _item.push({
+ style: {
+ color
+ },
+
+ renderBody() {
+ _write("bar");
+ }
+
+ });
+ }
}
_write(`${_markHydrateNode(_scope, 0)}`);
@@ -42,11 +52,16 @@ const _renderer = input => {
for (const col of [["a", "b"], ["c", "d"]]) {
let i = _i++;
+
+ const _scope = _nextScopeId();
+
const _row = [];
_write(`${_markHydrateNode(_scope, 0)}`);
for (const row of col) {
+ const _scope = _nextScopeId();
+
_row.push({
row: row,
diff --git a/packages/translator/src/__tests__/fixtures/attr-style/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/attr-style/__snapshots__/html.expected.js
index 56284619d..1d16d16db 100644
--- a/packages/translator/src/__tests__/fixtures/attr-style/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/attr-style/__snapshots__/html.expected.js
@@ -1,7 +1,10 @@
import { markHydrateNode as _markHydrateNode, styleAttr as _styleAttr, write as _write, nextScopeId as _nextScopeId, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
import _customTag from "./components/custom-tag.marko";
-const _renderer = input => {
+const _renderer = ({
+ color,
+ test
+}) => {
const _scope = _nextScopeId();
_write(`${_markHydrateNode(_scope, 0)} {
+const _renderer = ({
+ name
+}) => {
const _scope = _nextScopeId();
_write(`${_markHydrateNode(_scope, 0)}
`);
diff --git a/packages/translator/src/__tests__/fixtures/basic-component-attrs/__snapshots__/html.expected/components/my-button.js b/packages/translator/src/__tests__/fixtures/basic-component-attrs/__snapshots__/html.expected/components/my-button.js
index 221e7c648..5a523c048 100644
--- a/packages/translator/src/__tests__/fixtures/basic-component-attrs/__snapshots__/html.expected/components/my-button.js
+++ b/packages/translator/src/__tests__/fixtures/basic-component-attrs/__snapshots__/html.expected/components/my-button.js
@@ -1,6 +1,9 @@
import { markHydrateNode as _markHydrateNode, escapeXML as _escapeXML, write as _write, nextScopeId as _nextScopeId, writeHydrateCall as _writeHydrateCall, writeHydrateScope as _writeHydrateScope, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
-const _renderer = input => {
+const _renderer = ({
+ onclick,
+ text
+}) => {
const _scope = _nextScopeId();
_write(`${_markHydrateNode(_scope, 0)}
`);
diff --git a/packages/translator/src/__tests__/fixtures/basic-execution-order/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/basic-execution-order/__snapshots__/html.expected.js
index 0eb6d50e6..c79126e9e 100644
--- a/packages/translator/src/__tests__/fixtures/basic-execution-order/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/basic-execution-order/__snapshots__/html.expected.js
@@ -10,7 +10,11 @@ const _renderer = input => {
_write(`${_markHydrateNode(_scope, 0)}
${_markHydrateNode(_scope, 1)}`);
- if (show) _write(`${_markHydrateNode(_scope, 0)}${_escapeXML(message.text)}`);
+ if (show) {
+ const _scope = _nextScopeId();
+
+ _write(`${_markHydrateNode(_scope, 0)}${_escapeXML(message.text)}`);
+ }
_writeHydrateCall(_scope, "packages/translator/src/__tests__/fixtures/basic-execution-order/template.marko_0_0");
diff --git a/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/dom.expected.js b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/dom.expected.js
new file mode 100644
index 000000000..802aed828
--- /dev/null
+++ b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/dom.expected.js
@@ -0,0 +1,21 @@
+import { apply as _comments, applyAttrs as _comments_attrs, template as _comments_template, walks as _comments_walks } from "./components/comments.marko";
+import { write as _write, createRenderFn as _createRenderFn } from "@marko/runtime-fluurt/src/dom";
+
+function _apply_input(_scope, input) {
+ if (_write(_scope, 1, input)) _comments_attrs(_scope[0], input);
+}
+
+function _apply(_scope) {
+ _comments(_scope[0]);
+}
+
+export const applyAttrs = function (_scope, input) {
+ _apply_input(_scope, input);
+};
+export { _apply_input };
+export const template = `${_comments_template}`;
+export const walks =
+/* beginChild(0), _comments_walks, endChild */
+`/${_comments_walks}&`;
+export const apply = _apply;
+export default _createRenderFn(template, walks, apply, applyAttrs);
\ No newline at end of file
diff --git a/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/dom.expected/components/comments.js b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/dom.expected/components/comments.js
new file mode 100644
index 000000000..606e9dc69
--- /dev/null
+++ b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/dom.expected/components/comments.js
@@ -0,0 +1,124 @@
+import { queue as _queue, attr as _attr, data as _data, on as _on, setConditionalRenderer as _setConditionalRenderer, setLoopOf as _setLoopOf, queueInBranch as _queueInBranch, register as _register, bind as _bind, queueHydrate as _queueHydrate, write as _write, queueForEach as _queueForEach, createRenderer as _createRenderer, createRenderFn as _createRenderFn } from "@marko/runtime-fluurt/src/dom";
+import { apply as _comments, applyAttrs as _comments_attrs, template as _comments_template, walks as _comments_walks } from "./comments.marko";
+
+function _applyWith_comment_id(_scope, comment = _scope._[8], id = _scope._[10]) {
+ _comments_attrs(_scope[0], {
+ comments: comment.comments,
+ path: id
+ });
+}
+
+function _apply_id2(_scope, id = _scope._[10]) {
+ _queue(_scope, _applyWith_comment_id, 2);
+}
+
+function _apply_comment2(_scope, comment = _scope._[8]) {
+ _queue(_scope, _applyWith_comment_id, 2);
+}
+
+function _apply2(_scope) {
+ _comments(_scope[0]);
+
+ _queue(_scope, _apply_id2, 1);
+
+ _queue(_scope, _apply_comment2, 0);
+}
+
+const _onclick = function (_scope) {
+ const open = _scope[11];
+
+ _queue(_scope, _apply_open, 4, !open);
+};
+
+function _hydrate_open(_scope, open = _scope[11]) {
+ _on(_scope, 2, "click", _bind(_scope, _onclick));
+}
+
+_register("packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/components/comments.marko_1_0", _hydrate_open);
+
+function _applyWith_path_i(_scope, path = _scope._[5], i = _scope[9]) {
+ _apply_id(`${path}-${i}`);
+}
+
+function _apply_open(_scope, open) {
+ if (_write(_scope, 11, open)) {
+ _attr(_scope, 0, "hidden", !open);
+
+ _data(_scope, 3, open ? "[-]" : "[+]");
+
+ _queueHydrate(_scope, _hydrate_open);
+ }
+}
+
+function _apply_id(_scope, id) {
+ if (_write(_scope, 10, id)) {
+ _attr(_scope, 0, "id", id);
+
+ _queueInBranch(_scope, 4, _if, _apply_id2, 1, 3);
+ }
+}
+
+function _apply_i(_scope, i) {
+ if (_write(_scope, 9, i)) _queue(_scope, _applyWith_path_i, 5);
+}
+
+function _apply_comment(_scope, comment) {
+ if (_write(_scope, 8, comment)) {
+ _data(_scope, 1, comment.text);
+
+ _setConditionalRenderer(_scope, 4, comment.comments ? _if : null);
+
+ _queueInBranch(_scope, 4, _if, _apply_comment2, 0, 4);
+ }
+}
+
+function _apply_path(_scope, path = _scope._[5]) {
+ _queue(_scope, _applyWith_path_i, 5);
+}
+
+function _apply_path(_scope, path = _scope._[5]) {
+ _queue(_scope, _applyWith_path_i, 5);
+}
+
+function _apply(_scope) {
+ _apply_open(_scope, true);
+
+ _queue(_scope, _apply_path, 0);
+
+ _queue(_scope, _apply_path, 0);
+}
+
+function _apply_path2(_scope, path) {
+ if (_write(_scope, 5, path)) {
+ _queueForEach(_scope, 0, _apply_path, 0, 6);
+
+ _queueForEach(_scope, 0, _apply_path, 0, 7);
+ }
+}
+
+function _apply_comments(_scope, comments) {
+ if (_write(_scope, 4, comments)) _setLoopOf(_scope, 0, comments, _for, null, _apply_comment);
+}
+
+const _for = _createRenderer("
",
+/* get, next(2), replace, out(1), get, next(1), replace, out(1), replace, skip(3) */
+" E%l D%l%+", _apply),
+ _if = _createRenderer(`${_comments_template}`,
+/* beginChild(0), _comments_walks, endChild */
+`/${_comments_walks}&`, _apply2);
+
+export const applyAttrs = function (_scope, {
+ comments,
+ path = "c"
+}) {
+ _apply_comments(_scope, comments);
+
+ _apply_path2(_scope, path);
+};
+export { _apply_comments, _apply_path2 as _apply_path };
+export const template = "
";
+export const walks =
+/* next(1), replace, skip(3), out(1) */
+"D%+l";
+export const apply = function () {};
+export default _createRenderFn(template, walks, apply, applyAttrs);
\ No newline at end of file
diff --git a/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/html.expected.js
new file mode 100644
index 000000000..a5227996f
--- /dev/null
+++ b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/html.expected.js
@@ -0,0 +1,17 @@
+import { nextScopeId as _nextScopeId, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
+import _comments from "./components/comments.marko";
+
+const _renderer = input => {
+ const _scope = _nextScopeId();
+
+ _comments({ ...input,
+
+ renderBody() {
+ const _scope = _nextScopeId();
+ }
+
+ });
+};
+
+export default _renderer;
+export const render = _createRenderer(_renderer);
\ No newline at end of file
diff --git a/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/html.expected/components/comments.js b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/html.expected/components/comments.js
new file mode 100644
index 000000000..a8901ec43
--- /dev/null
+++ b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/html.expected/components/comments.js
@@ -0,0 +1,49 @@
+import { markHydrateNode as _markHydrateNode, write as _write, attr as _attr, escapeXML as _escapeXML, nextScopeId as _nextScopeId, writeHydrateCall as _writeHydrateCall, writeHydrateScope as _writeHydrateScope, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
+import _comments from "./comments.marko";
+
+const _renderer = ({
+ comments,
+ path = "c"
+}) => {
+ const _scope = _nextScopeId();
+
+ _write(`
${_markHydrateNode(_scope, 0)}`);
+
+ let _i = 0;
+
+ for (const comment of comments) {
+ let i = _i++;
+
+ const _scope = _nextScopeId();
+
+ const id = `${path}-${i}`;
+ const open = true;
+
+ _write(`${_markHydrateNode(_scope, 0)}- ${_markHydrateNode(_scope, 1)}${_escapeXML(comment.text)}${_markHydrateNode(_scope, 2)}${_markHydrateNode(_scope, 4)}`);
+
+ if (comment.comments) {
+ const _scope = _nextScopeId();
+
+ _comments({
+ comments: comment.comments,
+ path: id,
+
+ renderBody() {
+ const _scope = _nextScopeId();
+ }
+
+ });
+ }
+
+ _write("
");
+
+ _writeHydrateCall(_scope, "packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/components/comments.marko_1_0");
+
+ _writeHydrateScope(_scope, [,,,,,,,,,,, open]);
+ }
+
+ _write("
");
+};
+
+export default _renderer;
+export const render = _createRenderer(_renderer);
\ No newline at end of file
diff --git a/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/ssr.expected.md b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/ssr.expected.md
new file mode 100644
index 000000000..0b86908e7
--- /dev/null
+++ b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/__snapshots__/ssr.expected.md
@@ -0,0 +1,470 @@
+# Write
+
- Hello World
- Goodbye World
+
+
+# Render "End"
+```html
+
+
+
+
+
+
+ -
+
+
+ Hello World
+
+
+
+
+
+
+
+ -
+
+
+ testing 123
+
+
+
+
+
+
+
+
+ -
+
+
+ Goodbye World
+
+
+
+
+
+
+
+
+
+```
+
+# Mutations
+```
+inserted html0
+inserted html0/head0
+inserted html0/body1
+inserted html0/body1/ul0
+inserted html0/body1/ul0/#comment0
+inserted html0/body1/ul0/#comment1
+inserted html0/body1/ul0/li2
+inserted html0/body1/ul0/li2/span0
+inserted html0/body1/ul0/li2/span0/#comment0
+inserted html0/body1/ul0/li2/span0/#text1
+inserted html0/body1/ul0/li2/#comment1
+inserted html0/body1/ul0/li2/button2
+inserted html0/body1/ul0/li2/button2/#comment0
+inserted html0/body1/ul0/li2/button2/#text1
+inserted html0/body1/ul0/li2/#comment3
+inserted html0/body1/ul0/li2/ul4
+inserted html0/body1/ul0/li2/ul4/#comment0
+inserted html0/body1/ul0/li2/ul4/#comment1
+inserted html0/body1/ul0/li2/ul4/li2
+inserted html0/body1/ul0/li2/ul4/li2/span0
+inserted html0/body1/ul0/li2/ul4/li2/span0/#comment0
+inserted html0/body1/ul0/li2/ul4/li2/span0/#text1
+inserted html0/body1/ul0/li2/ul4/li2/#comment1
+inserted html0/body1/ul0/li2/ul4/li2/button2
+inserted html0/body1/ul0/li2/ul4/li2/button2/#comment0
+inserted html0/body1/ul0/li2/ul4/li2/button2/#text1
+inserted html0/body1/ul0/li2/ul4/li2/#comment3
+inserted html0/body1/ul0/#comment3
+inserted html0/body1/ul0/li4
+inserted html0/body1/ul0/li4/span0
+inserted html0/body1/ul0/li4/span0/#comment0
+inserted html0/body1/ul0/li4/span0/#text1
+inserted html0/body1/ul0/li4/#comment1
+inserted html0/body1/ul0/li4/button2
+inserted html0/body1/ul0/li4/button2/#comment0
+inserted html0/body1/ul0/li4/button2/#text1
+inserted html0/body1/ul0/li4/#comment3
+inserted html0/body1/script1
+inserted html0/body1/script1/#text0
+```
+
+
+# Render "Hydrate"
+```html
+
+
+
+
+
+
+ -
+
+
+ Hello World
+
+
+
+
+
+
+
+ -
+
+
+ testing 123
+
+
+
+
+
+
+
+
+ -
+
+
+ Goodbye World
+
+
+
+
+
+
+
+
+
+```
+
+# Mutations
+```
+
+```
+
+
+# Render
+container.querySelector(`#c-${id} > button`).click();
+
+```html
+
+
+
+
+
+ -
+
+
+ Hello World
+
+
+
+
+
+
+
+ -
+
+
+ testing 123
+
+
+
+
+
+
+
+
+ -
+
+
+ Goodbye World
+
+
+
+
+
+
+
+
+
+```
+
+# Mutations
+```
+html0/body1/ul0/li2: attr(hidden) null => "true"
+html0/body1/ul0/li2/button2/#text1: "[-]" => "[+]"
+```
+
+
+# Render
+container.querySelector(`#c-${id} > button`).click();
+
+```html
+
+
+
+
+
+ -
+
+
+ Hello World
+
+
+
+
+
+
+
+ -
+
+
+ testing 123
+
+
+
+
+
+
+
+
+ -
+
+
+ Goodbye World
+
+
+
+
+
+
+
+
+
+```
+
+# Mutations
+```
+html0/body1/ul0/li2: attr(hidden) "true" => null
+html0/body1/ul0/li2/button2/#text1: "[+]" => "[-]"
+```
+
+
+# Render
+container.querySelector(`#c-${id} > button`).click();
+
+```html
+
+
+
+
+
+ -
+
+
+ Hello World
+
+
+
+
+
+
+
+ -
+
+
+ testing 123
+
+
+
+
+
+
+
+
+ -
+
+
+ Goodbye World
+
+
+
+
+
+
+
+
+
+```
+
+# Mutations
+```
+html0/body1/ul0/li2/ul4/li2: attr(hidden) null => "true"
+html0/body1/ul0/li2/ul4/li2/button2/#text1: "[-]" => "[+]"
+```
+
+
+# Render
+container.querySelector(`#c-${id} > button`).click();
+
+```html
+
+
+
+
+
+ -
+
+
+ Hello World
+
+
+
+
+
+
+
+ -
+
+
+ testing 123
+
+
+
+
+
+
+
+
+ -
+
+
+ Goodbye World
+
+
+
+
+
+
+
+
+
+```
+
+# Mutations
+```
+html0/body1/ul0/li4: attr(hidden) null => "true"
+html0/body1/ul0/li4/button2/#text1: "[-]" => "[+]"
+```
\ No newline at end of file
diff --git a/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/components/comments.marko b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/components/comments.marko
new file mode 100644
index 000000000..98e4d11f2
--- /dev/null
+++ b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/components/comments.marko
@@ -0,0 +1,16 @@
+
+
+
+
+
+ -
+ ${comment.text}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/template.marko b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/template.marko
new file mode 100644
index 000000000..f056c045a
--- /dev/null
+++ b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/template.marko
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/test.ts b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/test.ts
new file mode 100644
index 000000000..6b43b8e51
--- /dev/null
+++ b/packages/translator/src/__tests__/fixtures/basic-inert-collapsible-tree/test.ts
@@ -0,0 +1,29 @@
+export const steps = [
+ {
+ comments: [
+ {
+ text: "Hello World",
+ comments: [
+ {
+ text: "testing 123",
+ },
+ ],
+ },
+ {
+ text: "Goodbye World",
+ },
+ ],
+ },
+ toggle("0"),
+ toggle("0"),
+ toggle("0-0"),
+ toggle("1"),
+];
+
+function toggle(id: string) {
+ return (container: Element) => {
+ (container.querySelector(`#c-${id} > button`) as HTMLButtonElement).click();
+ };
+}
+
+export const skip_csr = true;
diff --git a/packages/translator/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/html.expected.js
index 7efb6a67b..2d3109e2b 100644
--- a/packages/translator/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/basic-nested-scope-for/__snapshots__/html.expected.js
@@ -1,4 +1,4 @@
-import { markHydrateNode as _markHydrateNode, write as _write, attr as _attr, escapeXML as _escapeXML, nextScopeId as _nextScopeId, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
+import { markHydrateNode as _markHydrateNode, write as _write, attr as _attr, escapeXML as _escapeXML, nextScopeId as _nextScopeId, writeHydrateCall as _writeHydrateCall, writeHydrateScope as _writeHydrateScope, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
const _renderer = input => {
const _scope = _nextScopeId();
@@ -8,7 +8,13 @@ const _renderer = input => {
_write(`${_markHydrateNode(_scope, 0)}`);
for (const num of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) {
+ const _scope = _nextScopeId();
+
_write(`${_markHydrateNode(_scope, 0)}`);
+
+ _writeHydrateCall(_scope, "packages/translator/src/__tests__/fixtures/basic-nested-scope-for/template.marko_1_0");
+
+ _writeHydrateScope(_scope, [,, num]);
}
};
diff --git a/packages/translator/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/html.expected.js
index 8dc80ce7c..079de6e42 100644
--- a/packages/translator/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/basic-nested-scope-if/__snapshots__/html.expected.js
@@ -1,4 +1,4 @@
-import { markHydrateNode as _markHydrateNode, write as _write, escapeXML as _escapeXML, nextScopeId as _nextScopeId, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
+import { markHydrateNode as _markHydrateNode, write as _write, escapeXML as _escapeXML, nextScopeId as _nextScopeId, writeHydrateCall as _writeHydrateCall, writeHydrateScope as _writeHydrateScope, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
const _renderer = input => {
const _scope = _nextScopeId();
@@ -7,7 +7,15 @@ const _renderer = input => {
_write(`${_markHydrateNode(_scope, 0)}`);
- if (clickCount < 3) _write(`${_markHydrateNode(_scope, 0)}`);
+ if (clickCount < 3) {
+ const _scope = _nextScopeId();
+
+ _write(`${_markHydrateNode(_scope, 0)}`);
+
+ _writeHydrateCall(_scope, "packages/translator/src/__tests__/fixtures/basic-nested-scope-if/template.marko_1_0");
+
+ _writeHydrateScope(_scope, [,,,, clickCount]);
+ }
_write("
");
};
diff --git a/packages/translator/src/__tests__/fixtures/basic-push-pop-list/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/basic-push-pop-list/__snapshots__/html.expected.js
index 01d4c36ff..ba3b805fc 100644
--- a/packages/translator/src/__tests__/fixtures/basic-push-pop-list/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/basic-push-pop-list/__snapshots__/html.expected.js
@@ -9,6 +9,8 @@ const _renderer = input => {
_write(`${_markHydrateNode(_scope, 0)}`);
for (const item of items) {
+ const _scope = _nextScopeId();
+
_write(`${_markHydrateNode(_scope, 0)}${_escapeXML(item)}`);
}
diff --git a/packages/translator/src/__tests__/fixtures/basic-toggle-show/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/basic-toggle-show/__snapshots__/html.expected.js
index dd1d81db7..7329a7aee 100644
--- a/packages/translator/src/__tests__/fixtures/basic-toggle-show/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/basic-toggle-show/__snapshots__/html.expected.js
@@ -7,7 +7,11 @@ const _renderer = input => {
_write(`
${_markHydrateNode(_scope, 0)}`);
- if (show) _write("Hello!");
+ if (show) {
+ const _scope = _nextScopeId();
+
+ _write("Hello!");
+ }
_write(`${_markHydrateNode(_scope, 4)}
`);
diff --git a/packages/translator/src/__tests__/fixtures/dynamic-tag-name/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/dynamic-tag-name/__snapshots__/html.expected.js
index 5f2dac40c..2b881718e 100644
--- a/packages/translator/src/__tests__/fixtures/dynamic-tag-name/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/dynamic-tag-name/__snapshots__/html.expected.js
@@ -2,7 +2,16 @@ import tagA from "./components/tag-a/index.marko";
import tagB from "./components/tag-b/index.marko";
import { markHydrateNode as _markHydrateNode, attr as _attr, write as _write, nextScopeId as _nextScopeId, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
-const _renderer = input => {
+const _renderer = ({
+ renderBody,
+ x,
+ show,
+ showTagA,
+ isLarge,
+ tag,
+ level,
+ other
+}) => {
const _scope = _nextScopeId();
<${renderBody} class=["a", "b"] other=other/>
diff --git a/packages/translator/src/__tests__/fixtures/dynamic-tag-var/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/dynamic-tag-var/__snapshots__/html.expected.js
index 6b0cc7c26..b3cee906f 100644
--- a/packages/translator/src/__tests__/fixtures/dynamic-tag-var/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/dynamic-tag-var/__snapshots__/html.expected.js
@@ -1,7 +1,10 @@
import child from "./components/child/index.marko";
import { nextScopeId as _nextScopeId, markHydrateNode as _markHydrateNode, write as _write, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
-const _renderer = input => {
+const _renderer = ({
+ show,
+ dynamic
+}) => {
const _scope = _nextScopeId();
const data1 = child({
diff --git a/packages/translator/src/__tests__/fixtures/for-tag-with-state/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/for-tag-with-state/__snapshots__/html.expected.js
index dd5dea9e0..2f522b994 100644
--- a/packages/translator/src/__tests__/fixtures/for-tag-with-state/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/for-tag-with-state/__snapshots__/html.expected.js
@@ -12,6 +12,8 @@ const _renderer = input => {
for (const val of arrA) {
let i = _i++;
+ const _scope = _nextScopeId();
+
_write(`
${_markHydrateNode(_scope, 0)}${_escapeXML(i)}: ${_markHydrateNode(_scope, 1)}${_escapeXML(val)}
`);
}
@@ -24,6 +26,8 @@ const _renderer = input => {
for (const val of arrB) {
let i = _i2++;
+ const _scope = _nextScopeId();
+
_write(`
${_markHydrateNode(_scope, 0)}${_escapeXML(i)}: ${_markHydrateNode(_scope, 1)}${_escapeXML(val)}
`);
}
};
diff --git a/packages/translator/src/__tests__/fixtures/for-tag/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/for-tag/__snapshots__/html.expected.js
index ad9c1bbff..d1cac307a 100644
--- a/packages/translator/src/__tests__/fixtures/for-tag/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/for-tag/__snapshots__/html.expected.js
@@ -1,4 +1,4 @@
-import { markHydrateNode as _markHydrateNode, write as _write, escapeXML as _escapeXML, attr as _attr, nextScopeId as _nextScopeId, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
+import { markHydrateNode as _markHydrateNode, write as _write, escapeXML as _escapeXML, nextScopeId as _nextScopeId, attr as _attr, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
const _renderer = input => {
const _scope = _nextScopeId();
@@ -17,6 +17,8 @@ const _renderer = input => {
for (const val of arr) {
let i = _i++;
+ const _scope = _nextScopeId();
+
_write(`
${_markHydrateNode(_scope, 0)}${_escapeXML(i)}: ${_markHydrateNode(_scope, 1)}${_escapeXML(val)}
`);
}
@@ -25,6 +27,8 @@ const _renderer = input => {
for (const key in obj) {
const val = obj[key];
+ const _scope = _nextScopeId();
+
_write(`
${_markHydrateNode(_scope, 0)}${_escapeXML(key)}: ${_markHydrateNode(_scope, 1)}${_escapeXML(val)}
`);
}
@@ -33,6 +37,8 @@ const _renderer = input => {
for (let _steps = (10 - 0) / 2, _step = 0; _step <= _steps; _step++) {
const i = 0 + _step * 2;
+ const _scope = _nextScopeId();
+
_write(`
${_markHydrateNode(_scope, 0)}${_escapeXML(i)}
`);
}
@@ -43,6 +49,8 @@ const _renderer = input => {
for (const val of arr) {
let i = _i2++;
+ const _scope = _nextScopeId();
+
_write(`${_markHydrateNode(_scope, 0)}
${_markHydrateNode(_scope, 1)}${_escapeXML(i)}: ${_markHydrateNode(_scope, 2)}${_escapeXML(val)}
${_markHydrateNode(_scope, 3)}
`);
}
@@ -54,6 +62,8 @@ const _renderer = input => {
for (const val of list) {
let i = _i3++;
+ const _scope = _nextScopeId();
+
_write(`${_markHydrateNode(_scope, 0)}
${_markHydrateNode(_scope, 1)}${_escapeXML(list.length)}: ${_markHydrateNode(_scope, 2)}${_escapeXML(val)}
`);
}
@@ -62,6 +72,8 @@ const _renderer = input => {
for (const key in obj) {
const val = obj[key];
+ const _scope = _nextScopeId();
+
_write(`${_markHydrateNode(_scope, 0)}
${_markHydrateNode(_scope, 1)}${_escapeXML(key)}: ${_markHydrateNode(_scope, 2)}${_escapeXML(val)}
${_markHydrateNode(_scope, 3)}
`);
}
@@ -70,11 +82,15 @@ const _renderer = input => {
for (let _steps3 = (10 - 0) / 2, _step3 = 0; _step3 <= _steps3; _step3++) {
const i = 0 + _step3 * 2;
+ const _scope = _nextScopeId();
+
_write(`${_markHydrateNode(_scope, 0)}
${_markHydrateNode(_scope, 1)}${_escapeXML(i)}
${_markHydrateNode(_scope, 2)}
${_markHydrateNode(_scope, 3)}`);
for (let _steps2 = (10 - 0) / 2, _step2 = 0; _step2 <= _steps2; _step2++) {
const i = 0 + _step2 * 2;
+ const _scope = _nextScopeId();
+
_write(`${_markHydrateNode(_scope, 0)}
${_markHydrateNode(_scope, 1)}${_escapeXML(i)}
${_markHydrateNode(_scope, 2)}
`);
}
}
@@ -84,18 +100,24 @@ const _renderer = input => {
for (let _steps4 = (0 - 10) / -2, _step4 = 0; _step4 <= _steps4; _step4++) {
const i = 10 + _step4 * -2;
+ const _scope = _nextScopeId();
+
_write(`${_markHydrateNode(_scope, 0)}
${_markHydrateNode(_scope, 1)}${_escapeXML(i)}
${_markHydrateNode(_scope, 2)}
`);
}
_write(`${_markHydrateNode(_scope, 32)}`);
for (let _steps5 = (10 - 0) / 1, _step5 = 0; _step5 <= _steps5; _step5++) {
+ const _scope = _nextScopeId();
+
_write("Hello");
}
_write(`${_markHydrateNode(_scope, 36)}`);
for (let _steps6 = (10 - 0) / 1, _step6 = 0; _step6 <= _steps6; _step6++) {
+ const _scope = _nextScopeId();
+
_write("Hello");
}
};
diff --git a/packages/translator/src/__tests__/fixtures/hello-dynamic/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/hello-dynamic/__snapshots__/html.expected.js
index 634a63006..2420df705 100644
--- a/packages/translator/src/__tests__/fixtures/hello-dynamic/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/hello-dynamic/__snapshots__/html.expected.js
@@ -1,6 +1,9 @@
import { markHydrateNode as _markHydrateNode, escapeXML as _escapeXML, toString as _toString, write as _write, nextScopeId as _nextScopeId, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
-const _renderer = input => {
+const _renderer = ({
+ name,
+ missing
+}) => {
const _scope = _nextScopeId();
_write(`Hello ${_markHydrateNode(_scope, 0)}${_escapeXML(name)}! Hello ${_markHydrateNode(_scope, 1)}${_toString(name)}! Hello ${_markHydrateNode(_scope, 2)}${_toString(missing)}!`);
diff --git a/packages/translator/src/__tests__/fixtures/if-tag/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/if-tag/__snapshots__/html.expected.js
index 1fc9aaef9..e3777c624 100644
--- a/packages/translator/src/__tests__/fixtures/if-tag/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/if-tag/__snapshots__/html.expected.js
@@ -1,19 +1,44 @@
import { markHydrateNode as _markHydrateNode, write as _write, nextScopeId as _nextScopeId, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
-const _renderer = input => {
+const _renderer = ({
+ a,
+ b,
+ x,
+ y
+}) => {
const _scope = _nextScopeId();
_write(`${_markHydrateNode(_scope, 0)}`);
- if (a + b) _write("Hello");
+ if (a + b) {
+ const _scope = _nextScopeId();
+
+ _write("Hello");
+ }
_write(`${_markHydrateNode(_scope, 4)}`);
- if (a, b) _write("World");
+ if (a, b) {
+ const _scope = _nextScopeId();
+
+ _write("World");
+ }
_write(`
${_markHydrateNode(_scope, 8)}`);
- if (x) _write("A");else if (y) _write("B");else _write("C");
+ if (x) {
+ const _scope = _nextScopeId();
+
+ _write("A");
+ } else if (y) {
+ const _scope = _nextScopeId();
+
+ _write("B");
+ } else {
+ const _scope = _nextScopeId();
+
+ _write("C");
+ }
_write("
");
};
diff --git a/packages/translator/src/__tests__/fixtures/placeholders/__snapshots__/html.expected.js b/packages/translator/src/__tests__/fixtures/placeholders/__snapshots__/html.expected.js
index 175029732..f4c4f5141 100644
--- a/packages/translator/src/__tests__/fixtures/placeholders/__snapshots__/html.expected.js
+++ b/packages/translator/src/__tests__/fixtures/placeholders/__snapshots__/html.expected.js
@@ -1,6 +1,8 @@
import { markHydrateNode as _markHydrateNode, escapeXML as _escapeXML, toString as _toString, write as _write, nextScopeId as _nextScopeId, createRenderer as _createRenderer } from "@marko/runtime-fluurt/src/html";
-const _renderer = input => {
+const _renderer = ({
+ x
+}) => {
const _scope = _nextScopeId();
_write(`
a
${_markHydrateNode(_scope, 0)}${_escapeXML(x)}Hello Text <a/>${_markHydrateNode(_scope, 1)}${_toString(x)}Hello HTML