Skip to content

Commit c358330

Browse files
conico974khuezy
andauthored
feat: support for streaming (#213)
* feat: support for streaming * fix streaming not working after a while * fix page static props and streaming not always starting * fix ISR not working reliably * better handling of errors * fix for node runtime v12 * cleanup * fix headers and middleware response headers being overwritten * add padding to guarantee flush * wip * Add nextTick to flush buffer * change version to experimental streaming * enable brotli compression * wip * fix set-cookie being overwritten by multiple set-cookie * fix end not draining before ending stream * remove extra write in end * return writableNeedDrain; support for warmer * add drain to internal write * override removeHeader to remove set-cookie * revert removal of drain in internal write * fixed OPEN_NEXT_URL * reset version * fix lint * revert fixDataPage * revert fixISRHeaders change * fix 404 on fallback:false * refactor move config to a single location * fix cookies set in middleware --------- Co-authored-by: Khue Nguyen <[email protected]>
1 parent 2512093 commit c358330

Some content is hidden

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

68 files changed

+2597
-945
lines changed

examples/app-pages-router/app/isr/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ async function getTime() {
55
export const revalidate = 10;
66
export default async function ISR() {
77
const time = getTime();
8-
return <div>ISR: {time}</div>;
8+
return <div>Time: {time}</div>;
99
}

examples/app-pages-router/app/layout.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ export default function RootLayout({
1717
}) {
1818
return (
1919
<html lang="en">
20-
<body className={inter.className}>{children}</body>
20+
<body className={inter.className}>
21+
<header>Header</header>
22+
{children}
23+
</body>
2124
</html>
2225
);
2326
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { PropsWithChildren } from "react";
2+
3+
export default function Layout({ children }: PropsWithChildren) {
4+
return (
5+
<div>
6+
<h1>SSR</h1>
7+
{children}
8+
</div>
9+
);
10+
}
Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
1-
import { wait } from "@open-next/utils";
1+
import React from "react";
2+
3+
import { headers } from "next/headers";
4+
5+
async function getTime() {
6+
const res = await new Promise<string>((resolve) => {
7+
setTimeout(() => {
8+
resolve(new Date().toISOString());
9+
}, 1500);
10+
});
11+
return res;
12+
}
213

3-
export const revalidate = 0;
414
export default async function SSR() {
5-
await wait(2000);
6-
const time = new Date().toISOString();
15+
const time = await getTime();
16+
const headerList = headers();
717
return (
818
<div>
9-
<h1>SSR {time}</h1>
19+
<h1>Time: {time}</h1>
20+
<div> {headerList.get("host")}</div>
1021
</div>
1122
);
1223
}

examples/app-pages-router/next.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/** @type {import('next').NextConfig} */
22
const nextConfig = {
33
poweredByHeader: false,
4+
cleanDistDir: true,
45
transpilePackages: ["@example/shared"],
56
output: "standalone",
67
outputFileTracing: "../sst",

examples/app-pages-router/pages/pages_isr/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ export async function getStaticProps() {
1212
export default function Page({
1313
time,
1414
}: InferGetStaticPropsType<typeof getStaticProps>) {
15-
return <div className="flex">ISR: {time}</div>;
15+
return <div className="flex">Time: {time}</div>;
1616
}

examples/app-pages-router/pages/pages_ssr/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ export async function getServerSideProps() {
1111
export default function Page({
1212
time,
1313
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
14-
return <div className="flex">SSR: {time}</div>;
14+
return <div className="flex">Time: {time}</div>;
1515
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { wait } from "@open-next/utils";
2+
import { NextRequest } from "next/server";
3+
4+
export const dynamic = "force-dynamic";
5+
6+
export async function GET(request: NextRequest) {
7+
const resStream = new TransformStream();
8+
const writer = resStream.writable.getWriter();
9+
10+
const res = new Response(resStream.readable, {
11+
headers: {
12+
"Content-Type": "text/event-stream",
13+
Connection: "keep-alive",
14+
"Cache-Control": "no-cache, no-transform",
15+
},
16+
});
17+
18+
setTimeout(async () => {
19+
writer.write(
20+
`data: ${JSON.stringify({
21+
message: "open",
22+
time: new Date().toISOString(),
23+
})}\n\n`,
24+
);
25+
for (let i = 1; i <= 4; i++) {
26+
await wait(2000);
27+
writer.write(
28+
`data: ${JSON.stringify({
29+
message: "hello:" + i,
30+
time: new Date().toISOString(),
31+
})}\n\n`,
32+
);
33+
}
34+
35+
await wait(2000); // Wait for 4 seconds
36+
writer.write(
37+
`data: ${JSON.stringify({
38+
message: "close",
39+
time: new Date().toISOString(),
40+
})}\n\n`,
41+
);
42+
await wait(5000);
43+
await writer.close();
44+
}, 100);
45+
46+
return res;
47+
}

examples/app-router/app/isr/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ async function getTime() {
55
export const revalidate = 10;
66
export default async function ISR() {
77
const time = getTime();
8-
return <div>ISR: {time}</div>;
8+
return <div>Time: {time}</div>;
99
}

examples/app-router/app/page.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ export default function Home() {
2626
new timestamp
2727
</Nav>
2828
<Nav href={"/ssr"} title="SSR">
29-
Server Side Render should generate a new timestamp on each load
29+
Server Side Render should generate a new timestamp on each load.
30+
Streaming support for loading...
3031
</Nav>
3132
<Nav href={"/api"} title="API">
3233
Calls an API endpoint defined in app/api/hello/route and middleware
@@ -40,6 +41,9 @@ export default function Home() {
4041
<Nav href={"/search-query"} title="Search Query">
4142
Search Query Params should be available in middleware
4243
</Nav>
44+
<Nav href={"/sse"} title="Server Sent Events">
45+
Server Sent Events via Streaming
46+
</Nav>
4347
</main>
4448
</>
4549
);

0 commit comments

Comments
 (0)