mirror of
https://github.com/marko-js/marko.git
synced 2026-02-01 16:07:13 +00:00
fix: multiple dynamic closures server render
This commit is contained in:
parent
694fcd84c3
commit
907c87ca06
5
.changeset/hot-jeans-tap.md
Normal file
5
.changeset/hot-jeans-tap.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@marko/runtime-tags": patch
|
||||
---
|
||||
|
||||
Fix multiple dynamic closures losing scope in server render
|
||||
@ -0,0 +1,28 @@
|
||||
{
|
||||
"vars": {
|
||||
"props": {
|
||||
"$_": "t",
|
||||
"$init": "o",
|
||||
"$resolveAfter": "r",
|
||||
"$$await_content__value": "_",
|
||||
"$$await_content__$params": "c",
|
||||
"$$await_content": "e",
|
||||
"$$try_content__await": "n",
|
||||
"$$try_content__clickCount": "m",
|
||||
"$$clickCount_closure": "s",
|
||||
"$$clickCount__script": "a",
|
||||
"$$clickCount": "i",
|
||||
"$$clickCount__closure": "l",
|
||||
"$$try_content__await_promise": "u",
|
||||
"$resolveAfterNext": "p",
|
||||
"$$if_content__a": "d",
|
||||
"$$if_content__b": "g",
|
||||
"$$a__OR__b__script": "f",
|
||||
"$$a__OR__b": "k",
|
||||
"$$a__closure": "b",
|
||||
"$$a": "x",
|
||||
"$$b__closure": "h",
|
||||
"$$b": "j"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
# Render
|
||||
```html
|
||||
<button />
|
||||
<div>
|
||||
0
|
||||
</div>
|
||||
<div>
|
||||
0
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button />
|
||||
<div>
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
1
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button />
|
||||
<div>
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
2
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button />
|
||||
<div>
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
3
|
||||
</div>
|
||||
```
|
||||
@ -0,0 +1,87 @@
|
||||
# Render
|
||||
```html
|
||||
<button />
|
||||
<!---->
|
||||
<div>
|
||||
0
|
||||
</div>
|
||||
<div>
|
||||
0
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
INSERT button, #comment0, div0, div1, #comment1, #comment2
|
||||
```
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button />
|
||||
<!---->
|
||||
<div>
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
1
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
UPDATE div1/#text "0" => "1"
|
||||
UPDATE div0/#text "0" => "1"
|
||||
```
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button />
|
||||
<!---->
|
||||
<div>
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
2
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
UPDATE div1/#text "1" => "2"
|
||||
UPDATE div0/#text "1" => "2"
|
||||
```
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button />
|
||||
<!---->
|
||||
<div>
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
3
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
UPDATE div1/#text "2" => "3"
|
||||
UPDATE div0/#text "2" => "3"
|
||||
```
|
||||
@ -0,0 +1,27 @@
|
||||
// size: 307 (min) 164 (brotli)
|
||||
_._enable_catch();
|
||||
const $if_content__a = _._closure_get(
|
||||
2,
|
||||
($scope) => _._text($scope.a, $scope._._.c),
|
||||
($scope) => $scope._._,
|
||||
),
|
||||
$if_content__b = _._closure_get(
|
||||
3,
|
||||
($scope) => _._text($scope.b, $scope._._.d),
|
||||
($scope) => $scope._._,
|
||||
),
|
||||
$a__OR__b__script = _._script("a0", ($scope) =>
|
||||
_._on($scope.a, "click", function () {
|
||||
($a($scope, $scope.c + 1), $b($scope, $scope.d + 1));
|
||||
}),
|
||||
),
|
||||
$a__OR__b = _._or(4, $a__OR__b__script),
|
||||
$a__closure = _._closure($if_content__a),
|
||||
$a = _._let(2, ($scope) => {
|
||||
($a__OR__b($scope), $a__closure($scope));
|
||||
}),
|
||||
$b__closure = _._closure($if_content__b),
|
||||
$b = _._let(3, ($scope) => {
|
||||
($a__OR__b($scope), $b__closure($scope));
|
||||
});
|
||||
init();
|
||||
@ -0,0 +1,34 @@
|
||||
export const $template = "<button></button><!><!>";
|
||||
export const $walks = /* get, over(1), replace, over(2) */" b%c";
|
||||
import * as _ from "@marko/runtime-tags/debug/dom";
|
||||
_._enable_catch();
|
||||
const $if_content__a = /* @__PURE__ */_._closure_get("a", $scope => _._text($scope["#text/0"], $scope._._.a), $scope => $scope._._);
|
||||
const $if_content__b = /* @__PURE__ */_._closure_get("b", $scope => _._text($scope["#text/1"], $scope._._.b), $scope => $scope._._);
|
||||
const $if_content__setup = $scope => {
|
||||
$if_content__a($scope);
|
||||
$if_content__b($scope);
|
||||
};
|
||||
const $try_content__if = /* @__PURE__ */_._if("#text/0", "<div> </div><div> </div>", /* next(1), get, out(1), next(1), get, out(1) */"D lD l", $if_content__setup);
|
||||
const $try_content__setup = $scope => $try_content__if($scope, true ? 0 : 1);
|
||||
const $a__OR__b__script = _._script("__tests__/template.marko_0_a_b", $scope => _._on($scope["#button/0"], "click", function () {
|
||||
$a($scope, $scope.a + 1);
|
||||
$b($scope, $scope.b + 1);
|
||||
}));
|
||||
const $a__OR__b = /* @__PURE__ */_._or(4, $a__OR__b__script);
|
||||
const $a__closure = /* @__PURE__ */_._closure($if_content__a);
|
||||
const $a = /* @__PURE__ */_._let("a/2", $scope => {
|
||||
$a__OR__b($scope);
|
||||
$a__closure($scope);
|
||||
});
|
||||
const $b__closure = /* @__PURE__ */_._closure($if_content__b);
|
||||
const $b = /* @__PURE__ */_._let("b/3", $scope => {
|
||||
$a__OR__b($scope);
|
||||
$b__closure($scope);
|
||||
});
|
||||
const $try = /* @__PURE__ */_._try("#text/1", "<!><!><!>", /* over(1), replace, over(2) */"b%c", $try_content__setup);
|
||||
export function $setup($scope) {
|
||||
$a($scope, 0);
|
||||
$b($scope, 0);
|
||||
$try($scope, {});
|
||||
}
|
||||
export default /* @__PURE__ */_._template("__tests__/template.marko", $template, $walks, $setup);
|
||||
@ -0,0 +1,35 @@
|
||||
import * as _ from "@marko/runtime-tags/debug/html";
|
||||
export default _._template("__tests__/template.marko", input => {
|
||||
const $scope0_id = _._scope_id();
|
||||
const $a__closures = new Set();
|
||||
const $b__closures = new Set();
|
||||
let a = 0;
|
||||
let b = 0;
|
||||
_._html(`<button></button>${_._el_resume($scope0_id, "#button/0")}`);
|
||||
_._try($scope0_id, "#text/1", _._content_resume("__tests__/template.marko_1_content", () => {
|
||||
const $scope1_id = _._scope_id();
|
||||
if (true) {
|
||||
const $scope2_id = _._scope_id();
|
||||
_._html(`<div>${_._escape(a)}${_._el_resume($scope2_id, "#text/0")}</div><div>${_._escape(b)}${_._el_resume($scope2_id, "#text/1")}</div>`);
|
||||
_._subscribe($b__closures, _._subscribe($a__closures, _._scope($scope2_id, {
|
||||
_: _._scope_with_id($scope1_id),
|
||||
"ClosureSignalIndex:a": 0,
|
||||
"ClosureSignalIndex:b": 0
|
||||
}, "__tests__/template.marko", "8:4")));
|
||||
}
|
||||
_._scope($scope1_id, {
|
||||
_: _._scope_with_id($scope0_id)
|
||||
}, "__tests__/template.marko", "7:2");
|
||||
}, $scope0_id), {});
|
||||
_._script($scope0_id, "__tests__/template.marko_0_a_b");
|
||||
_._scope($scope0_id, {
|
||||
a,
|
||||
b,
|
||||
"ClosureScopes:a": $a__closures,
|
||||
"ClosureScopes:b": $b__closures
|
||||
}, "__tests__/template.marko", 0, {
|
||||
a: "1:6",
|
||||
b: "2:6"
|
||||
});
|
||||
_._resume_branch($scope0_id);
|
||||
});
|
||||
@ -0,0 +1,55 @@
|
||||
# Render
|
||||
```html
|
||||
<button />
|
||||
<div>
|
||||
0
|
||||
</div>
|
||||
<div>
|
||||
0
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button />
|
||||
<div>
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
1
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button />
|
||||
<div>
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
2
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button />
|
||||
<div>
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
3
|
||||
</div>
|
||||
```
|
||||
@ -0,0 +1,191 @@
|
||||
# Render
|
||||
```html
|
||||
<html>
|
||||
<head />
|
||||
<body>
|
||||
<button />
|
||||
<!--M_*1 #button/0-->
|
||||
<!--M_[-->
|
||||
<div>
|
||||
0
|
||||
<!--M_*3 #text/0-->
|
||||
</div>
|
||||
<div>
|
||||
0
|
||||
<!--M_*3 #text/1-->
|
||||
</div>
|
||||
<!--M_]1 #text/1 2-->
|
||||
<script>
|
||||
WALKER_RUNTIME("M")("_");
|
||||
M._.r = [_ => (_.c = [0, _.a = {
|
||||
a: 0,
|
||||
b: 0,
|
||||
"ClosureScopes:a": _.d = new Set,
|
||||
"ClosureScopes:b": _.f = new Set
|
||||
}, _.b = {
|
||||
_: _.a,
|
||||
"#BranchAccessor": "#text/1"
|
||||
}, _.e = {
|
||||
_: _.b,
|
||||
"ClosureSignalIndex:a": 0,
|
||||
"ClosureSignalIndex:b": 0
|
||||
}], (_.d).add(_.e), (_.f).add(_.e), _.c),
|
||||
"__tests__/template.marko_0_a_b 1"
|
||||
];
|
||||
M._.w()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
INSERT html/body/#text
|
||||
```
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<html>
|
||||
<head />
|
||||
<body>
|
||||
<button />
|
||||
<!--M_*1 #button/0-->
|
||||
<!--M_[-->
|
||||
<div>
|
||||
1
|
||||
<!--M_*3 #text/0-->
|
||||
</div>
|
||||
<div>
|
||||
1
|
||||
<!--M_*3 #text/1-->
|
||||
</div>
|
||||
<!--M_]1 #text/1 2-->
|
||||
<script>
|
||||
WALKER_RUNTIME("M")("_");
|
||||
M._.r = [_ => (_.c = [0, _.a = {
|
||||
a: 0,
|
||||
b: 0,
|
||||
"ClosureScopes:a": _.d = new Set,
|
||||
"ClosureScopes:b": _.f = new Set
|
||||
}, _.b = {
|
||||
_: _.a,
|
||||
"#BranchAccessor": "#text/1"
|
||||
}, _.e = {
|
||||
_: _.b,
|
||||
"ClosureSignalIndex:a": 0,
|
||||
"ClosureSignalIndex:b": 0
|
||||
}], (_.d).add(_.e), (_.f).add(_.e), _.c),
|
||||
"__tests__/template.marko_0_a_b 1"
|
||||
];
|
||||
M._.w()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
UPDATE html/body/div1/#text "0" => "1"
|
||||
UPDATE html/body/div0/#text "0" => "1"
|
||||
```
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<html>
|
||||
<head />
|
||||
<body>
|
||||
<button />
|
||||
<!--M_*1 #button/0-->
|
||||
<!--M_[-->
|
||||
<div>
|
||||
2
|
||||
<!--M_*3 #text/0-->
|
||||
</div>
|
||||
<div>
|
||||
2
|
||||
<!--M_*3 #text/1-->
|
||||
</div>
|
||||
<!--M_]1 #text/1 2-->
|
||||
<script>
|
||||
WALKER_RUNTIME("M")("_");
|
||||
M._.r = [_ => (_.c = [0, _.a = {
|
||||
a: 0,
|
||||
b: 0,
|
||||
"ClosureScopes:a": _.d = new Set,
|
||||
"ClosureScopes:b": _.f = new Set
|
||||
}, _.b = {
|
||||
_: _.a,
|
||||
"#BranchAccessor": "#text/1"
|
||||
}, _.e = {
|
||||
_: _.b,
|
||||
"ClosureSignalIndex:a": 0,
|
||||
"ClosureSignalIndex:b": 0
|
||||
}], (_.d).add(_.e), (_.f).add(_.e), _.c),
|
||||
"__tests__/template.marko_0_a_b 1"
|
||||
];
|
||||
M._.w()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
UPDATE html/body/div1/#text "1" => "2"
|
||||
UPDATE html/body/div0/#text "1" => "2"
|
||||
```
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<html>
|
||||
<head />
|
||||
<body>
|
||||
<button />
|
||||
<!--M_*1 #button/0-->
|
||||
<!--M_[-->
|
||||
<div>
|
||||
3
|
||||
<!--M_*3 #text/0-->
|
||||
</div>
|
||||
<div>
|
||||
3
|
||||
<!--M_*3 #text/1-->
|
||||
</div>
|
||||
<!--M_]1 #text/1 2-->
|
||||
<script>
|
||||
WALKER_RUNTIME("M")("_");
|
||||
M._.r = [_ => (_.c = [0, _.a = {
|
||||
a: 0,
|
||||
b: 0,
|
||||
"ClosureScopes:a": _.d = new Set,
|
||||
"ClosureScopes:b": _.f = new Set
|
||||
}, _.b = {
|
||||
_: _.a,
|
||||
"#BranchAccessor": "#text/1"
|
||||
}, _.e = {
|
||||
_: _.b,
|
||||
"ClosureSignalIndex:a": 0,
|
||||
"ClosureSignalIndex:b": 0
|
||||
}], (_.d).add(_.e), (_.f).add(_.e), _.c),
|
||||
"__tests__/template.marko_0_a_b 1"
|
||||
];
|
||||
M._.w()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
UPDATE html/body/div1/#text "2" => "3"
|
||||
UPDATE html/body/div0/#text "2" => "3"
|
||||
```
|
||||
@ -0,0 +1,10 @@
|
||||
# Render End
|
||||
```html
|
||||
<button />
|
||||
<div>
|
||||
0
|
||||
</div>
|
||||
<div>
|
||||
0
|
||||
</div>
|
||||
```
|
||||
@ -0,0 +1,63 @@
|
||||
# Write
|
||||
```html
|
||||
<button></button><!--M_*1 #button/0--><!--M_[--><div>0<!--M_*3 #text/0--></div><div>0<!--M_*3 #text/1--></div><!--M_]1 #text/1 2--><script>WALKER_RUNTIME("M")("_");M._.r=[_=>(_.c=[0,_.a={a:0,b:0,"ClosureScopes:a":_.d=new Set,"ClosureScopes:b":_.f=new Set},_.b={_:_.a,"#BranchAccessor":"#text/1"},_.e={_:_.b,"ClosureSignalIndex:a":0,"ClosureSignalIndex:b":0}],(_.d).add(_.e),(_.f).add(_.e),_.c),"__tests__/template.marko_0_a_b 1"];M._.w()</script>
|
||||
```
|
||||
|
||||
# Render End
|
||||
```html
|
||||
<html>
|
||||
<head />
|
||||
<body>
|
||||
<button />
|
||||
<!--M_*1 #button/0-->
|
||||
<!--M_[-->
|
||||
<div>
|
||||
0
|
||||
<!--M_*3 #text/0-->
|
||||
</div>
|
||||
<div>
|
||||
0
|
||||
<!--M_*3 #text/1-->
|
||||
</div>
|
||||
<!--M_]1 #text/1 2-->
|
||||
<script>
|
||||
WALKER_RUNTIME("M")("_");
|
||||
M._.r = [_ => (_.c = [0, _.a = {
|
||||
a: 0,
|
||||
b: 0,
|
||||
"ClosureScopes:a": _.d = new Set,
|
||||
"ClosureScopes:b": _.f = new Set
|
||||
}, _.b = {
|
||||
_: _.a,
|
||||
"#BranchAccessor": "#text/1"
|
||||
}, _.e = {
|
||||
_: _.b,
|
||||
"ClosureSignalIndex:a": 0,
|
||||
"ClosureSignalIndex:b": 0
|
||||
}], (_.d).add(_.e), (_.f).add(_.e), _.c),
|
||||
"__tests__/template.marko_0_a_b 1"
|
||||
];
|
||||
M._.w()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
INSERT html
|
||||
INSERT html/head
|
||||
INSERT html/body
|
||||
INSERT html/body/button
|
||||
INSERT html/body/#comment0
|
||||
INSERT html/body/#comment1
|
||||
INSERT html/body/div0
|
||||
INSERT html/body/div0/#text
|
||||
INSERT html/body/div0/#comment
|
||||
INSERT html/body/div1
|
||||
INSERT html/body/div1/#text
|
||||
INSERT html/body/div1/#comment
|
||||
INSERT html/body/#comment2
|
||||
INSERT html/body/script
|
||||
INSERT html/body/script/#text
|
||||
```
|
||||
@ -0,0 +1,12 @@
|
||||
<let/a = 0/>
|
||||
<let/b = 0/>
|
||||
<button onClick() {
|
||||
a++;
|
||||
b++;
|
||||
}/>
|
||||
<try>
|
||||
<if=true>
|
||||
<div>${a}</div>
|
||||
<div>${b}</div>
|
||||
</if>
|
||||
</try>
|
||||
@ -0,0 +1,5 @@
|
||||
export const steps = [{}, click, click, click];
|
||||
|
||||
function click(container: Element) {
|
||||
container.querySelector("button")!.click();
|
||||
}
|
||||
@ -1532,5 +1532,5 @@ export function _subscribe(
|
||||
scope: ScopeInternals,
|
||||
) {
|
||||
$chunk.boundary.state.serializer.writeCall(scope, subscribers, "add");
|
||||
referenceScope(scope);
|
||||
return referenceScope(scope);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user