-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(vercel): streaming #8879
feat(vercel): streaming #8879
Changes from 6 commits
8e49b35
fbc595b
441ae06
3a03091
463f157
fe28750
d23967a
b05a2ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
'@astrojs/vercel': minor | ||
--- | ||
|
||
The Vercel adapter now allows you to enable streaming! | ||
|
||
Bring better performance to your visitors by showing them content as it is rendered. The browser can also start loading the required stylesheets and scripts much sooner, which ultimately results in faster full page loads. | ||
|
||
|
||
```diff | ||
export default defineConfig({ | ||
output: "server", | ||
adapter: vercel({ | ||
+ streaming: true | ||
}), | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -105,6 +105,9 @@ export interface VercelServerlessConfig { | |
|
||
/** The maximum duration (in seconds) that Serverless Functions can run before timing out. See the [Vercel documentation](https://vercel.com/docs/functions/serverless-functions/runtimes#maxduration) for the default and maximum limit for your account plan. */ | ||
maxDuration?: number; | ||
|
||
/** Whether to allow the serverless function to stream the response to the browser. */ | ||
streaming?: boolean; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like @sarah11918 might have thoughts on the wording here! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm hoping lol There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want to see which direction the README takes before bringing that over here! Don't let me forget about this, though! |
||
} | ||
|
||
export default function vercelServerless({ | ||
|
@@ -119,6 +122,7 @@ export default function vercelServerless({ | |
functionPerRoute = false, | ||
edgeMiddleware = false, | ||
maxDuration, | ||
streaming, | ||
}: VercelServerlessConfig = {}): AstroIntegration { | ||
if (maxDuration) { | ||
if (typeof maxDuration !== 'number') { | ||
|
@@ -276,6 +280,7 @@ You can set functionPerRoute: false to prevent surpassing the limit.` | |
includeFiles: filesToInclude, | ||
excludeFiles, | ||
maxDuration, | ||
streaming, | ||
}); | ||
routeDefinitions.push({ | ||
src: route.pattern.source, | ||
|
@@ -292,6 +297,7 @@ You can set functionPerRoute: false to prevent surpassing the limit.` | |
includeFiles: filesToInclude, | ||
excludeFiles, | ||
maxDuration, | ||
streaming, | ||
}); | ||
routeDefinitions.push({ src: '/.*', dest: 'render' }); | ||
} | ||
|
@@ -341,7 +347,8 @@ interface CreateFunctionFolderArgs { | |
NTF_CACHE: any; | ||
includeFiles: URL[]; | ||
excludeFiles?: string[]; | ||
maxDuration?: number; | ||
maxDuration: number | undefined; | ||
streaming: boolean | undefined; | ||
} | ||
|
||
async function createFunctionFolder({ | ||
|
@@ -353,6 +360,7 @@ async function createFunctionFolder({ | |
includeFiles, | ||
excludeFiles, | ||
maxDuration, | ||
streaming, | ||
}: CreateFunctionFolderArgs) { | ||
const functionFolder = new URL(`./functions/${functionName}.func/`, config.outDir); | ||
|
||
|
@@ -381,6 +389,7 @@ async function createFunctionFolder({ | |
handler, | ||
launcherType: 'Nodejs', | ||
maxDuration, | ||
supportsResponseStreaming: streaming, | ||
}); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { defineConfig } from 'astro/config'; | ||
import vercel from '@astrojs/vercel/serverless'; | ||
|
||
export default defineConfig({ | ||
output: "server", | ||
adapter: vercel({ | ||
streaming: true | ||
}) | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"name": "@test/vercel-streaming", | ||
"version": "0.0.0", | ||
"private": true, | ||
"dependencies": { | ||
"@astrojs/vercel": "workspace:*", | ||
"astro": "workspace:*" | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<html> | ||
<head> | ||
<title>One</title> | ||
</head> | ||
<body> | ||
<h1>One</h1> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<html> | ||
<head> | ||
<title>Two</title> | ||
</head> | ||
<body> | ||
<h1>Two</h1> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { loadFixture } from './test-utils.js'; | ||
import { expect } from 'chai'; | ||
|
||
describe('maxDuration', () => { | ||
/** @type {import('./test-utils.js').Fixture} */ | ||
let fixture; | ||
|
||
before(async () => { | ||
fixture = await loadFixture({ | ||
root: './fixtures/streaming/', | ||
}); | ||
await fixture.build(); | ||
}); | ||
|
||
it('makes it to vercel function configuration', async () => { | ||
const vcConfig = JSON.parse( | ||
await fixture.readFile('../.vercel/output/functions/render.func/.vc-config.json') | ||
); | ||
expect(vcConfig).to.deep.include({ supportsResponseStreaming: true }); | ||
}); | ||
}); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kind of want something like this now, because the docs really do imply this happens by default. (And yes, this seems to be more consistent with the others.)
What do you think about something like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm it won't be limited to HTML. Although the non-HTML cases would be where the user is creating their own streaming responses from scratch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so I'll tell you where my little stumbling blocks are and YOU propose what works! 😄
Grammatically:
Philosophically:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, the serverless function is the particular one created when you deploy to Vercel, at least intended to be that one.
I agree, it's a documented feature. We could probably make a major release to change the default very soon (but not right away), so that streaming is always the case. And I think it is a good idea for another major release after to remove the option altogether.
Netlify never streams either 😶
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is now built that way. Streaming with no configuration to opt-out, just the way it should be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What even is happening?? The cake is a lie! 😅
So, I don't want anyone's project to break with this change, of course! Aligning this with docs is helpful for me, since that's the story we tell pretty clearly, but if we've been misinformed then we can change on our end, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Breaking is not a concern, just that the change is going to be more visible than what someone might expect from a minor or patch release. So a major release is important more because the user needs to be given notice about what's happening.