Skip to content

Commit 9b2c837

Browse files
committed
fix: improve await client render pending scope timing
1 parent 35706d2 commit 9b2c837

427 files changed

Lines changed: 1151 additions & 965 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/stale-pillows-cross.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@marko/runtime-tags": patch
3+
---
4+
5+
Fix incorrect client rendering of `<await>` content that contains nested child scopes (such as a nested component). The eager, detached render of the await body removed only a single scope from the pending-scopes list, which cleared the `Creating` flag on the await branch (or one of its children). When the promise resolved, the affected scope's setup ran in update mode instead of create mode. For example an `<input value=resolvedValue>` inside the await body rendered empty. All eagerly-created scopes are now deferred together and committed when the await resolves.

.sizes.json

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
{
88
"name": "*",
99
"total": {
10-
"min": 23654,
11-
"brotli": 8738
10+
"min": 23767,
11+
"brotli": 8781
1212
}
1313
},
1414
{
@@ -18,11 +18,11 @@
1818
"brotli": 120
1919
},
2020
"runtime": {
21-
"min": 4031,
21+
"min": 4010,
2222
"brotli": 1774
2323
},
2424
"total": {
25-
"min": 4194,
25+
"min": 4173,
2626
"brotli": 1894
2727
}
2828
},
@@ -33,12 +33,12 @@
3333
"brotli": 79
3434
},
3535
"runtime": {
36-
"min": 2563,
37-
"brotli": 1279
36+
"min": 2543,
37+
"brotli": 1278
3838
},
3939
"total": {
40-
"min": 2652,
41-
"brotli": 1358
40+
"min": 2632,
41+
"brotli": 1357
4242
}
4343
},
4444
{
@@ -48,12 +48,12 @@
4848
"brotli": 393
4949
},
5050
"runtime": {
51-
"min": 6520,
52-
"brotli": 2837
51+
"min": 6514,
52+
"brotli": 2852
5353
},
5454
"total": {
55-
"min": 7202,
56-
"brotli": 3230
55+
"min": 7196,
56+
"brotli": 3245
5757
}
5858
},
5959
{
@@ -63,12 +63,12 @@
6363
"brotli": 104
6464
},
6565
"runtime": {
66-
"min": 2768,
67-
"brotli": 1352
66+
"min": 2748,
67+
"brotli": 1345
6868
},
6969
"total": {
70-
"min": 2890,
71-
"brotli": 1456
70+
"min": 2870,
71+
"brotli": 1449
7272
}
7373
}
7474
]

.sizes/comments.csr/runtime.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
// size: 6520 (min) 2837 (brotli)
1+
// size: 6514 (min) 2852 (brotli)
22
//#region packages/runtime-tags/dist/dom.mjs
33
let decodeAccessor = (num) =>
44
(num + (num < 26 ? 10 : num < 962 ? 334 : 11998)).toString(36),
55
defaultDelegator = /* @__PURE__ */ createDelegator(),
66
parsers = {},
77
nextScopeId = 1e6,
8+
collectingScopes,
89
destroyNestedScopes = function destroyNestedScopes(scope) {
9-
((scope.I = 1),
10+
((scope.H = 0),
1011
scope.D?.forEach(destroyNestedScopes),
1112
scope.B?.forEach(resetControllers));
1213
},
@@ -67,11 +68,10 @@ let decodeAccessor = (num) =>
6768
? forOf(all, (item, i) => cb(item[by], [item, i]))
6869
: forOf(all, (item, i) => cb(by(item, i), [item, i]));
6970
}),
70-
runId = 1,
71-
pendingRenders = [],
72-
pendingEffects = [],
73-
pendingScopes = [],
7471
rendering,
72+
runId = 2,
73+
pendingEffects = [],
74+
pendingRenders = [],
7575
scopeKeyOffset = 1e3,
7676
runEffects = (effects) => {
7777
for (let i = 0; i < effects.length; ) effects[i++](effects[i++]);
@@ -124,11 +124,11 @@ function parseHTML(html, ns) {
124124
function createScope($global, closestBranch) {
125125
let scope = {
126126
L: nextScopeId++,
127-
H: 1,
127+
H: runId,
128128
F: closestBranch,
129129
$: $global,
130130
};
131-
return (pendingScopes.push(scope), scope);
131+
return (collectingScopes?.push(scope), scope);
132132
}
133133
function skipScope() {
134134
return nextScopeId++;
@@ -163,7 +163,7 @@ function _let(id, fn) {
163163
let valueAccessor = decodeAccessor(id);
164164
return (scope, value) => (
165165
rendering
166-
? scope.H && ((scope[valueAccessor] = value), fn?.(scope))
166+
? scope.H === runId && ((scope[valueAccessor] = value), fn?.(scope))
167167
: (scope[valueAccessor] !== value || !(valueAccessor in scope)) &&
168168
((scope[valueAccessor] = value), fn) &&
169169
(schedule(), queueRender(scope, fn, id)),
@@ -188,7 +188,8 @@ function _for_closure(ownerLoopNodeAccessor, fn) {
188188
queueRender(
189189
ownerScope,
190190
() => {
191-
for (let scope of scopes) !scope.H && !scope.I && fn(scope);
191+
for (let scope of scopes)
192+
scope.H > 0 && scope.H < runId && fn(scope);
192193
},
193194
-1,
194195
0,
@@ -204,7 +205,8 @@ function _if_closure(ownerConditionalNodeAccessor, branch, fn) {
204205
ownerSignal = (scope) => {
205206
let ifScope = scope[scopeAccessor];
206207
ifScope &&
207-
!ifScope.H &&
208+
ifScope.H > 0 &&
209+
ifScope.H < runId &&
208210
(scope[branchAccessor] || 0) === branch &&
209211
queueRender(ifScope, fn, -1);
210212
};
@@ -588,12 +590,10 @@ function runRenders() {
588590
}
589591
runRender(render);
590592
}
591-
for (let scope of pendingScopes) scope.H = 0;
592-
pendingScopes = [];
593593
}
594594
function skipDestroyedRenders() {
595595
runRender = ((runRender) => (render) => {
596-
render.b.F?.I || runRender(render);
596+
render.b.F?.H !== 0 && runRender(render);
597597
})(runRender);
598598
}
599599
function $signalReset(scope, id) {

.sizes/comments.ssr/runtime.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// size: 2768 (min) 1352 (brotli)
1+
// size: 2748 (min) 1345 (brotli)
22
//#region packages/runtime-tags/dist/dom.mjs
33
let decodeAccessor = (num) =>
44
(num + (num < 26 ? 10 : num < 962 ? 334 : 11998)).toString(36),
@@ -8,11 +8,10 @@ let decodeAccessor = (num) =>
88
registeredValues = {},
99
curRenders,
1010
readyIds,
11-
runId = 1,
12-
pendingRenders = [],
13-
pendingEffects = [],
14-
pendingScopes = [],
1511
rendering,
12+
runId = 2,
13+
pendingEffects = [],
14+
pendingRenders = [],
1615
scopeKeyOffset = 1e3,
1716
runEffects = (effects) => {
1817
for (let i = 0; i < effects.length; ) effects[i++](effects[i++]);
@@ -59,7 +58,7 @@ function _let(id, fn) {
5958
let valueAccessor = decodeAccessor(id);
6059
return (scope, value) => (
6160
rendering
62-
? scope.H && ((scope[valueAccessor] = value), fn?.(scope))
61+
? scope.H === runId && ((scope[valueAccessor] = value), fn?.(scope))
6362
: (scope[valueAccessor] !== value || !(valueAccessor in scope)) &&
6463
((scope[valueAccessor] = value), fn) &&
6564
(schedule(), queueRender(scope, fn, id)),
@@ -93,7 +92,11 @@ function init(runtimeId = "M") {
9392
runtimeId,
9493
renderId,
9594
}),
96-
initScope = (scope) => ((scope.$ = initGlobal()), scope),
95+
initScope = (scope) => (
96+
(scope.H = 1),
97+
(scope.$ = initGlobal()),
98+
scope
99+
),
97100
applyScopes = (partials) => {
98101
let scopeId = partials[0];
99102
for (let i = 1; i < partials.length; i++) {
@@ -281,7 +284,5 @@ function runRenders() {
281284
}
282285
runRender(render);
283286
}
284-
for (let scope of pendingScopes) scope.H = 0;
285-
pendingScopes = [];
286287
}
287288
//#endregion

.sizes/counter.csr/runtime.js

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
// size: 4031 (min) 1774 (brotli)
1+
// size: 4010 (min) 1774 (brotli)
22
//#region packages/runtime-tags/dist/dom.mjs
33
let decodeAccessor = (num) =>
44
(num + (num < 26 ? 10 : num < 962 ? 334 : 11998)).toString(36),
55
defaultDelegator = /* @__PURE__ */ createDelegator(),
66
parsers = {},
77
nextScopeId = 1e6,
8+
collectingScopes,
89
destroyNestedScopes = function destroyNestedScopes(scope) {
9-
((scope.I = 1),
10+
((scope.H = 0),
1011
scope.D?.forEach(destroyNestedScopes),
1112
scope.B?.forEach(resetControllers));
1213
},
@@ -61,11 +62,10 @@ let decodeAccessor = (num) =>
6162
},
6263
cloneCache = {},
6364
registeredValues = {},
64-
runId = 1,
65-
pendingRenders = [],
66-
pendingEffects = [],
67-
pendingScopes = [],
6865
rendering,
66+
runId = 2,
67+
pendingEffects = [],
68+
pendingRenders = [],
6969
scopeKeyOffset = 1e3,
7070
runEffects = (effects) => {
7171
for (let i = 0; i < effects.length; ) effects[i++](effects[i++]);
@@ -106,11 +106,11 @@ function parseHTML(html, ns) {
106106
function createScope($global, closestBranch) {
107107
let scope = {
108108
L: nextScopeId++,
109-
H: 1,
109+
H: runId,
110110
F: closestBranch,
111111
$: $global,
112112
};
113-
return (pendingScopes.push(scope), scope);
113+
return (collectingScopes?.push(scope), scope);
114114
}
115115
function skipScope() {
116116
return nextScopeId++;
@@ -142,7 +142,7 @@ function _let(id, fn) {
142142
let valueAccessor = decodeAccessor(id);
143143
return (scope, value) => (
144144
rendering
145-
? scope.H && ((scope[valueAccessor] = value), fn?.(scope))
145+
? scope.H === runId && ((scope[valueAccessor] = value), fn?.(scope))
146146
: (scope[valueAccessor] !== value || !(valueAccessor in scope)) &&
147147
((scope[valueAccessor] = value), fn) &&
148148
(schedule(), queueRender(scope, fn, id)),
@@ -322,8 +322,6 @@ function runRenders() {
322322
}
323323
runRender(render);
324324
}
325-
for (let scope of pendingScopes) scope.H = 0;
326-
pendingScopes = [];
327325
}
328326
function $signalReset(scope, id) {
329327
let ctrl = scope.A?.[id];

.sizes/counter.ssr/runtime.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// size: 2563 (min) 1279 (brotli)
1+
// size: 2543 (min) 1278 (brotli)
22
//#region packages/runtime-tags/dist/dom.mjs
33
let decodeAccessor = (num) =>
44
(num + (num < 26 ? 10 : num < 962 ? 334 : 11998)).toString(36),
@@ -8,11 +8,10 @@ let decodeAccessor = (num) =>
88
registeredValues = {},
99
curRenders,
1010
readyIds,
11-
runId = 1,
12-
pendingRenders = [],
13-
pendingEffects = [],
14-
pendingScopes = [],
1511
rendering,
12+
runId = 2,
13+
pendingEffects = [],
14+
pendingRenders = [],
1615
scopeKeyOffset = 1e3,
1716
runEffects = (effects) => {
1817
for (let i = 0; i < effects.length; ) effects[i++](effects[i++]);
@@ -56,7 +55,7 @@ function _let(id, fn) {
5655
let valueAccessor = decodeAccessor(id);
5756
return (scope, value) => (
5857
rendering
59-
? scope.H && ((scope[valueAccessor] = value), fn?.(scope))
58+
? scope.H === runId && ((scope[valueAccessor] = value), fn?.(scope))
6059
: (scope[valueAccessor] !== value || !(valueAccessor in scope)) &&
6160
((scope[valueAccessor] = value), fn) &&
6261
(schedule(), queueRender(scope, fn, id)),
@@ -90,7 +89,11 @@ function init(runtimeId = "M") {
9089
runtimeId,
9190
renderId,
9291
}),
93-
initScope = (scope) => ((scope.$ = initGlobal()), scope),
92+
initScope = (scope) => (
93+
(scope.H = 1),
94+
(scope.$ = initGlobal()),
95+
scope
96+
),
9497
applyScopes = (partials) => {
9598
let scopeId = partials[0];
9699
for (let i = 1; i < partials.length; i++) {
@@ -266,7 +269,5 @@ function runRenders() {
266269
}
267270
runRender(render);
268271
}
269-
for (let scope of pendingScopes) scope.H = 0;
270-
pendingScopes = [];
271272
}
272273
//#endregion

0 commit comments

Comments
 (0)