Skip to content

Commit

Permalink
fix: issue with ooo stream with and io stream followed by ooo stream
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed May 10, 2024
1 parent 5c59829 commit 7691418
Show file tree
Hide file tree
Showing 21 changed files with 77 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/chilly-plums-happen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"marko": patch
---

Fix issue where an out of order await contained an in order await and then another out of order await. This previously caused a race condition where if the final out of order await resolved first, it'd try to send it's content without it's placeholder location being available.
1 change: 1 addition & 0 deletions packages/marko/src/core-tags/core/await/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ module.exports = function awaitTag(input, out) {
};

if (clientReorder) {
awaitInfo.parent = out;
awaitInfo.after = input.showAfter;

clientReorderContext =
Expand Down
37 changes: 29 additions & 8 deletions packages/marko/src/core-tags/core/await/reorderer-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,27 @@ module.exports = function (input, out) {
}

function handleAwait(awaitInfo) {
let flushedScript = false;
let flushedContent = false;
let flushedPlaceholder = false;
awaitInfo.parent.on("___toString", () => {
flushedPlaceholder = true;
if (!flushedScript && flushedContent) {
flushedScript = true;
asyncOut.script(
`$${reorderFunctionId}(` +
(typeof awaitInfo.id === "number"
? awaitInfo.id
: '"' + awaitInfo.id + '"') +
(awaitInfo.after ? ',"' + awaitInfo.after + '"' : "") +
")",
);
}
});
awaitInfo.out
.on("___toString", out.emit.bind(out, "___toString"))
.on("finish", function (result) {
flushedContent = true;
if (!global._afRuntime) {
// Minified version of ./client-reorder-runtime.js
asyncOut.script(
Expand Down Expand Up @@ -86,14 +104,17 @@ module.exports = function (input, out) {
);
}

asyncOut.script(
`$${reorderFunctionId}(` +
(typeof awaitInfo.id === "number"
? awaitInfo.id
: '"' + awaitInfo.id + '"') +
(awaitInfo.after ? ',"' + awaitInfo.after + '"' : "") +
")",
);
if (!flushedScript && flushedPlaceholder) {
flushedScript = true;
asyncOut.script(
`$${reorderFunctionId}(` +
(typeof awaitInfo.id === "number"
? awaitInfo.id
: '"' + awaitInfo.id + '"') +
(awaitInfo.after ? ',"' + awaitInfo.after + '"' : "") +
")",
);
}

awaitInfo.out.writer = asyncOut.writer;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ exports.checkEvents = function (events, snapshot, out) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ exports.checkEvents = function (events, snapshot, out) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ exports.checkEvents = function (events, snapshot, out) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ exports.checkEvents = function (events, snapshot, out) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ exports.checkEvents = function (events, snapshot) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ exports.checkEvents = function (events, snapshot, out) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
BEFORE-OUT-OF-ORDER <noscript id="afpha"></noscript> AFTER-OUT-OF-ORDER <div id="afc" style="display:none">NESTED-OUT-OF-ORDER</div><script>function $af(d,a,e,l,g,h,k,b,f,c){c=$af;if(a&&!c[a])(c[a+="$"]||(c[a]=[])).push(d);else{e=document;l=e.getElementById("af"+d);g=e.getElementById("afph"+d);h=e.createDocumentFragment();k=l.childNodes;b=0;for(f=k.length;b<f;b++)h.appendChild(k.item(0));g&&g.parentNode.replaceChild(h,g);c[d]=1;if(a=c[d+"$"])for(b=0,f=a.length;b<f;b++)c(a[b])}}</script><!--FLUSH--><div id="afa" style="display:none">BEFORE-IN-ORDER INSIDE-IN-ORDER<noscript id="afphc"></noscript> AFTER-IN-ORDER</div><script>$af("a");$af("c")</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
BEFORE-OUT-OF-ORDER
<await(new Promise(r => setTimeout(r))) name="a" client-reorder>
<@then>
BEFORE-IN-ORDER
<await(new Promise(r => setTimeout(r))) name="b">
<@then>INSIDE-IN-ORDER</>
</>
<await(Promise.resolve()) name="c" client-reorder>
<@then>NESTED-OUT-OF-ORDER</>
</>
AFTER-IN-ORDER
</>
</>
AFTER-OUT-OF-ORDER
<await-reorderer/>
---
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const { callbackProvider } = require("../../../__util__/async-helpers");

exports.templateData = {
testDataProvider: callbackProvider(1, { name: "Frank" }),
};

exports.skip_vdom = "client-reorder/placeholders are not supported in vdom";
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ exports.checkEvents = function (events, snapshot) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.parent; // Not serializable

delete arg.asyncValue; // Not serializable

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ exports.checkEvents = function (events, snapshot, out) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ exports.checkEvents = function (events, snapshot, out) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ exports.checkEvents = function (events, snapshot, out) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ exports.checkEvents = function (events, snapshot, out) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ exports.checkEvents = function (events, snapshot) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ exports.checkEvents = function (events, snapshot, out) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ exports.checkEvents = function (events, snapshot, out) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down
1 change: 1 addition & 0 deletions packages/marko/test/render/fixtures/await-timeout/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ exports.checkEvents = function (events, snapshot) {
expect(arg.out != null).to.equal(true);

delete arg.out; // Not serializable
delete arg.parent; // Not serializable
delete arg.asyncValue; // Not serializable

return {
Expand Down

0 comments on commit 7691418

Please sign in to comment.