Skip to content

Commit 8788ed7

Browse files
committed
add routehandler and api route
1 parent a01164e commit 8788ed7

File tree

2 files changed

+93
-0
lines changed
  • examples

2 files changed

+93
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// https://developer.mozilla.org/docs/Web/API/ReadableStream#convert_async_iterator_to_stream
2+
function iteratorToStream(iterator: any) {
3+
return new ReadableStream({
4+
async pull(controller) {
5+
const { value, done } = await iterator.next();
6+
7+
if (done) {
8+
controller.close();
9+
} else {
10+
controller.enqueue(value);
11+
}
12+
},
13+
});
14+
}
15+
16+
function sleep(time: number) {
17+
return new Promise((resolve) => {
18+
setTimeout(resolve, time);
19+
});
20+
}
21+
22+
const encoder = new TextEncoder();
23+
24+
async function* makeIterator() {
25+
for (let i = 1; i <= 10; i++) {
26+
yield encoder.encode(`<p data-testid="iteratorCount">${i}</p>`);
27+
await sleep(1000);
28+
}
29+
}
30+
31+
export async function GET() {
32+
const iterator = makeIterator();
33+
const stream = iteratorToStream(iterator);
34+
35+
return new Response(stream, {
36+
headers: {
37+
"Content-Type": "text/html; charset=utf-8",
38+
Connection: "keep-alive",
39+
"Cache-Control": "no-cache, no-transform",
40+
},
41+
});
42+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { Readable } from "node:stream";
2+
import type { NextApiRequest, NextApiResponse } from "next";
3+
4+
function iteratorToStream(iterator: AsyncIterator<Uint8Array>) {
5+
return new ReadableStream({
6+
async pull(controller) {
7+
const { value, done } = await iterator.next();
8+
9+
if (done) {
10+
controller.close();
11+
} else {
12+
controller.enqueue(value);
13+
}
14+
},
15+
});
16+
}
17+
18+
function sleep(time: number) {
19+
return new Promise((resolve) => {
20+
setTimeout(resolve, time);
21+
});
22+
}
23+
24+
const encoder = new TextEncoder();
25+
26+
async function* makeIterator() {
27+
for (let i = 1; i <= 10; i++) {
28+
yield encoder.encode(`<p data-testid="iteratorCount">${i}</p>`);
29+
await sleep(1000);
30+
}
31+
}
32+
33+
export default async function handler(
34+
req: NextApiRequest,
35+
res: NextApiResponse,
36+
) {
37+
if (req.method !== "GET") {
38+
return res.status(405).json({ message: "Method not allowed" });
39+
}
40+
41+
res.setHeader("Content-Type", "text/html; charset=utf-8");
42+
res.setHeader("Connection", "keep-alive");
43+
res.setHeader("Cache-Control", "no-cache, no-transform");
44+
45+
// create and pipe the stream
46+
const iterator = makeIterator();
47+
const stream = iteratorToStream(iterator);
48+
49+
// @ts-ignore - not sure how to make typescript happy here
50+
return Readable.fromWeb(stream).pipe(res);
51+
}

0 commit comments

Comments
 (0)