Skip to content

Commit 190fa9b

Browse files
committed
fix(runtime-class): serialize hydration state for partial-document page entries
Page entries that render a partial document (no `<body>`) never triggered the `<init-components>`/`<await-reorderer>` tags a `<body>` injects, so no hydration payload was emitted and components could not resume. `withPageAssets` now emits them for the top-level entry; both are guarded, so full-page entries are unchanged.
1 parent dfa08ea commit 190fa9b

16 files changed

Lines changed: 246 additions & 2 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"marko": patch
3+
---
4+
5+
Fix client hydration for page entries that render a partial document (no `<body>`). Such entries never triggered the `<init-components>` tag a `<body>` injects, so no hydration payload was serialized and components could not resume. `withPageAssets` now emits it for the top-level entry.

packages/runtime-class/src/runtime/helpers/load-tag.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"use strict";
22

33
var flushHereAndAfter = require("../../core-tags/core/__flush_here_and_after__");
4+
var initComponents = require("../../core-tags/components/init-components-tag");
5+
var awaitReorderer = require("../../core-tags/core/await/reorderer-renderer");
46
var escapeScript = require("../html/helpers/escape-script-placeholder");
57
var FLAG_WILL_RERENDER_IN_BROWSER = 1;
68
var DEFAULT_RUNTIME_ID = "M";
@@ -57,6 +59,13 @@ exports.withPageAssets = function withPageAssets(
5759
}
5860

5961
template._(input, out);
62+
63+
if (!hasAssets) {
64+
// A partial-document page (no `<body>`) misses the tags `<body>` injects,
65+
// so emit them here for hydration state + `<await>` reorder (no-op if present).
66+
initComponents(input, out);
67+
awaitReorderer(input, out);
68+
}
6069
});
6170
};
6271

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// template.marko
2+
var import_vdom = require_vdom();
3+
var import_renderer = /* @__PURE__ */ __toESM(require_renderer());
4+
var import_registry = require_registry();
5+
var import_defineComponent = /* @__PURE__ */ __toESM(require_defineComponent());
6+
const _marko_componentType = "__tests__/template.marko", _marko_template = (0, import_vdom.t)(_marko_componentType);
7+
(0, import_registry.r)(_marko_componentType, () => _marko_template);
8+
const _marko_component = {
9+
onCreate() {
10+
this.state = { count: 0 };
11+
},
12+
increment() {
13+
this.state.count++;
14+
}
15+
};
16+
_marko_template._ = (0, import_renderer.default)(function(input, out, _componentDef, _component, state, $global) {
17+
out.be("button", null, "0", _component, null, 0, { "onclick": _componentDef.d("click", "increment", false) });
18+
out.t(state.count, _component);
19+
out.ee();
20+
}, {
21+
t: _marko_componentType,
22+
d: true
23+
}, _marko_component);
24+
_marko_template.Component = (0, import_defineComponent.default)(_marko_component, _marko_template._);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// template.marko
2+
var import_components = require_components();
3+
var import_vdom = require_vdom();
4+
var import_renderer = /* @__PURE__ */ __toESM(require_renderer());
5+
var import_registry = require_registry();
6+
var import_defineComponent = /* @__PURE__ */ __toESM(require_defineComponent());
7+
const _marko_componentType = "a", _marko_template = (0, import_vdom.t)(_marko_componentType);
8+
(0, import_registry.r)(_marko_componentType, () => _marko_template);
9+
const _marko_component = {
10+
onCreate() {
11+
this.state = { count: 0 };
12+
},
13+
increment() {
14+
this.state.count++;
15+
}
16+
};
17+
_marko_template._ = (0, import_renderer.default)(function(input, out, _componentDef, _component, state, $global) {
18+
out.be("button", null, "0", _component, null, 0, { "onclick": _componentDef.d("click", "increment", false) });
19+
out.t(state.count, _component);
20+
out.ee();
21+
}, { t: _marko_componentType }, _marko_component);
22+
_marko_template.Component = (0, import_defineComponent.default)(_marko_component, _marko_template._);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// template.marko
2+
var import_html = require_html();
3+
var import_escape_xml = require_escape_xml();
4+
var import_renderer = /* @__PURE__ */ __toESM(require_renderer());
5+
const _marko_componentType = "__tests__/template.marko", _marko_template = (0, import_html.t)(_marko_componentType);
6+
const _marko_component = {
7+
onCreate() {
8+
this.state = { count: 0 };
9+
},
10+
increment() {
11+
this.state.count++;
12+
}
13+
};
14+
_marko_template._ = (0, import_renderer.default)(function(input, out, _componentDef, _component, state, $global) {
15+
out.w("<button>");
16+
out.w((0, import_escape_xml.x)(state.count));
17+
out.w("</button>");
18+
}, {
19+
t: _marko_componentType,
20+
d: true
21+
}, _marko_component);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// template.marko
2+
var import_html = require_html();
3+
var import_escape_xml = require_escape_xml();
4+
var import_renderer = /* @__PURE__ */ __toESM(require_renderer());
5+
const _marko_componentType = "a", _marko_template = (0, import_html.t)(_marko_componentType);
6+
_marko_template._ = (0, import_renderer.default)(function(input, out, _componentDef, _component, state, $global) {
7+
out.w(`<button>${(0, import_escape_xml.x)(state.count)}</button>`);
8+
}, { t: _marko_componentType }, {
9+
onCreate() {
10+
this.state = { count: 0 };
11+
},
12+
increment() {
13+
this.state.count++;
14+
}
15+
});
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Render
2+
```html
3+
<button>
4+
0
5+
</button>
6+
```
7+
8+
# Update
9+
```js
10+
container.querySelector("button").click();
11+
```
12+
```html
13+
<button>
14+
1
15+
</button>
16+
```
17+
## Change
18+
```
19+
UPDATE: button::text "0" => "1"
20+
```
21+
22+
# Update
23+
```js
24+
container.querySelector("button").click();
25+
```
26+
```html
27+
<button>
28+
2
29+
</button>
30+
```
31+
## Change
32+
```
33+
UPDATE: button::text "1" => "2"
34+
```
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Render
2+
```html
3+
<button>
4+
0
5+
</button>
6+
```
7+
8+
# Update
9+
```js
10+
container.querySelector("button").click();
11+
```
12+
```html
13+
<button>
14+
1
15+
</button>
16+
```
17+
## Change
18+
```
19+
UPDATE: button::text "0" => "1"
20+
```
21+
22+
# Update
23+
```js
24+
container.querySelector("button").click();
25+
```
26+
```html
27+
<button>
28+
2
29+
</button>
30+
```
31+
## Change
32+
```
33+
UPDATE: button::text "1" => "2"
34+
```
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!--M#s0--><button>0</button><!--M/-->
2+
<script>
3+
$MC = (window.$MC || []).concat({
4+
"w": [
5+
["s0", 0, {}, {
6+
"f": 1
7+
}]
8+
],
9+
"t": [
10+
"packages/runtime-tags/src/__tests__/fixtures-interop/class-partial-document/template.marko"
11+
]
12+
})
13+
</script>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!--M#s0--><button>0</button><!--M/-->
2+
<script>
3+
$MC = (window.$MC || []).concat({
4+
"w": [
5+
["s0", 0, {}, {
6+
"f": 1
7+
}]
8+
],
9+
"t": ["a"]
10+
})
11+
</script>

0 commit comments

Comments
 (0)