Skip to content

Commit

Permalink
fix: deal with fast consecutive promise resolutions when streaming (#…
Browse files Browse the repository at this point in the history
…9332)

* fix: deal with fast consecutive promise resolutions when streaming

fixes #9330

* Update packages/kit/src/utils/streaming.js
  • Loading branch information
dummdidumm committed Mar 6, 2023
1 parent 620f560 commit 18d330b
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/strange-garlics-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

fix: deal with fast consecutive promise resolutions when streaming
17 changes: 12 additions & 5 deletions packages/kit/src/utils/streaming.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,29 @@ function defer() {
* }}
*/
export function create_async_iterator() {
let deferred = defer();
let deferred = [defer()];

return {
iterator: {
[Symbol.asyncIterator]() {
return {
next: () => deferred.promise
next: async () => {
const next = await deferred[0].promise;
if (!next.done) deferred.shift();
return next;
}
};
}
},
push: (value) => {
deferred.fulfil({ value, done: false });
deferred = defer();
deferred[deferred.length - 1].fulfil({
value,
done: false
});
deferred.push(defer());
},
done: () => {
deferred.fulfil({ done: true });
deferred[deferred.length - 1].fulfil({ done: true });
}
};
}
20 changes: 20 additions & 0 deletions packages/kit/src/utils/streaming.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { test } from 'uvu';
import * as assert from 'uvu/assert';
import { create_async_iterator } from './streaming.js';

test(`works with fast consecutive promise resolutions`, async () => {
const iterator = create_async_iterator();

Promise.resolve(1).then((n) => iterator.push(n));
Promise.resolve(2).then((n) => iterator.push(n));
Promise.resolve().then(() => iterator.done());

const actual = [];
for await (const value of iterator.iterator) {
actual.push(value);
}

assert.equal(actual, [1, 2]);
});

test.run();

0 comments on commit 18d330b

Please sign in to comment.