Skip to content

Commit 2def5b6

Browse files
committed
fix(url-loader): handle SSE ping event for Readable
1 parent 63a2936 commit 2def5b6

File tree

7 files changed

+75
-54
lines changed

7 files changed

+75
-54
lines changed

.changeset/plenty-nails-shave.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
"@graphql-tools/url-loader": patch
33
---
44

5-
[@graphql-tools/url-loader] Fix SSE ping event
5+
fix(url-loader): handle SSE ping event correctly

packages/loaders/url/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
"express-graphql": "0.12.0",
4444
"graphql-upload": "12.0.0",
4545
"puppeteer": "11.0.0",
46-
"web-streams-polyfill": "^3.1.1",
4746
"webpack": "5.61.0"
4847
},
4948
"dependencies": {

packages/loaders/url/src/event-stream/handleReadable.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ export async function* handleReadable(readable: Readable) {
88
if (part) {
99
const eventStr = part.split('event: ')[1];
1010
const dataStr = part.split('data: ')[1];
11-
const data = JSON.parse(dataStr);
1211
if (eventStr === 'complete') {
1312
break outer;
1413
}
15-
yield data.payload || data;
14+
if (dataStr) {
15+
const data = JSON.parse(dataStr);
16+
yield data.payload || data;
17+
}
1618
}
1719
}
1820
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { handleEventStreamResponse } from '../src/event-stream/handleEventStreamResponse';
2+
import { TextEncoder } from 'util';
3+
4+
describe('handleEventStreamResponse', () => {
5+
describe('ReadableStream', () => {
6+
if (parseInt(process.versions.node.split('.')[0]) < 16) {
7+
it('dummy', () => { });
8+
}
9+
const { TransformStream } = require('stream/web');
10+
it('should handle an event with data', async () => {
11+
const { readable, writable } = new TransformStream();
12+
const encoder = new TextEncoder();
13+
const stream = writable.getWriter();
14+
15+
const generator = await handleEventStreamResponse(readable);
16+
17+
// stream.write(encoder.encode(':\n\n'));
18+
stream.write(encoder.encode('event: complete\n'));
19+
stream.write(encoder.encode('data: { "foo": "bar" }\n'));
20+
stream.write(encoder.encode('\n'));
21+
22+
expect((await generator.next()).value).toMatchInlineSnapshot(`
23+
Object {
24+
"foo": "bar",
25+
}
26+
`);
27+
});
28+
29+
it('should ignore server pings', async () => {
30+
const { readable, writable } = new TransformStream();
31+
const encoder = new TextEncoder();
32+
const stream = writable.getWriter();
33+
34+
const readStream = async () => {
35+
const generator = await handleEventStreamResponse(readable);
36+
37+
stream.write(encoder.encode(':\n\n'));
38+
stream.write(encoder.encode('event: next\n'));
39+
stream.write(encoder.encode('data: { "foo": "bar" }\n\n'));
40+
41+
return generator.next();
42+
};
43+
44+
await expect(await readStream()).resolves.toMatchInlineSnapshot(`
45+
Object {
46+
"done": false,
47+
"value": Object {
48+
"foo": "bar",
49+
},
50+
}
51+
`);
52+
});
53+
});
54+
55+
})

packages/loaders/url/tests/handleReadableStream.test.ts

Lines changed: 0 additions & 49 deletions
This file was deleted.

packages/loaders/url/tests/url-loader-browser.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,12 +290,19 @@ describe('[url-loader] webpack bundle compat', () => {
290290

291291
responseClosed$ = new Promise(resolve => res.once('close', () => resolve(true)));
292292

293+
const ping = setInterval(() => {
294+
// Ping
295+
res.write(':\n\n');
296+
}, 100);
297+
293298
for (const data of sentDatas) {
294299
await new Promise(resolve => setTimeout(resolve, 300));
295300
res.write(`data: ${JSON.stringify(data)}\n\n`);
296301
await new Promise(resolve => setTimeout(resolve, 300));
297302
}
298303

304+
clearInterval(ping);
305+
299306
};
300307

301308
const document = parse(/* GraphQL */ `

packages/loaders/url/tests/url-loader.spec.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,8 +700,15 @@ input TestInput {
700700
"Cache-Control": "no-cache",
701701
});
702702

703+
const ping = setInterval(() => {
704+
// Ping
705+
res.write(':\n\n');
706+
}, 50);
703707
sentDatas.forEach(result => sleep(300).then(() => res.write(`data: ${JSON.stringify(result)}\n\n`)));
704-
serverResponseEnded$ = new Promise(resolve => res.once('close', () => resolve(true)));
708+
serverResponseEnded$ = new Promise(resolve => res.once('close', () => {
709+
resolve(true);
710+
clearInterval(ping);
711+
}));
705712
});
706713

707714
await new Promise<void>((resolve) => httpServer.listen(serverPort, () => resolve()));

0 commit comments

Comments
 (0)