mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 10:58:56 +00:00
### What does this PR do?
Fixes a crash related to the dev server overwriting the uws user context
pointer when setting abort callback.
Adds support for `return new Response(<jsx />, { ... })` and `return
Response.render(...)` and `return Response.redirect(...)`:
- Created a `SSRResponse` class to handle this (see
`JSBakeResponse.{h,cpp}`)
- `SSRResponse` is designed to "fake" being a React component
- This is done in JSBakeResponse::create inside of
src/bun.js/bindings/JSBakeResponse.cpp
- And `src/js/builtins/BakeSSRResponse.ts` defines a `wrapComponent`
function which wraps
the passed in component (when doing `new Response(<jsx />, ...)`). It
does
this to throw an error (in redirect()/render() case) or return the
component.
- Created a `BakeAdditionsToGlobal` struct which contains some
properties
needed for this
- Added some of the properties we need to fake to BunBuiltinNames.h
(e.g.
`$$typeof`), the rationale behind this is that we couldn't use
`structure->addPropertyTransition` because JSBakeResponse is not a final
JSObject.
- When bake and server-side, bundler rewrites `Response ->
Bun.SSRResponse` (see `src/ast/P.zig` and `src/ast/visitExpr.zig`)
- Created a new WebCore body variant (`Render: struct { path: []const u8
}`)
- Created when `return Response.render(...)`
- When handled, it re-invokes dev server to render the new path
Enables server-side sourcemaps for the dev server:
- New source providers for server-side:
(`DevServerSourceProvider.{h,cpp}`)
- IncrementalGraph and SourceMapStore are updated to support this
There are numerous other stuff:
- allow `app` configuration from Bun.serve(...)
- fix errors stopping dev server
- fix use after free related to in
RequestContext.finishRunningErrorHandler
- Request.cookies
- Make `"use client";` components work
- Fix some bugs using `require(...)` in dev server
- Fix catch-all routes not working in the dev server
- Updates `findSourceMappingURL(...)` to use `std.mem.lastIndexOf(...)`
because
the sourcemap that should be used is the last one anyway
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Alistair Smith <hi@alistair.sh>
69 lines
1.8 KiB
TypeScript
69 lines
1.8 KiB
TypeScript
import { expect } from "bun:test";
|
|
import { devTest } from "../bake-harness";
|
|
|
|
// Basic test to verify request.cookies functionality
|
|
devTest("request.cookies.get() basic functionality", {
|
|
framework: "react",
|
|
files: {
|
|
"pages/index.tsx": `
|
|
export const mode = "ssr";
|
|
export const streaming = false;
|
|
|
|
export default async function IndexPage({ request }) {
|
|
// Try to access cookies
|
|
const userName = request.cookies?.get?.("userName") || "not-found";
|
|
|
|
return (
|
|
<div>
|
|
<p data-testid="cookie-value">{userName}</p>
|
|
</div>
|
|
);
|
|
}
|
|
`,
|
|
},
|
|
async test(dev) {
|
|
const response = await dev.fetch("/", {
|
|
headers: {
|
|
Cookie: "userName=TestUser",
|
|
},
|
|
});
|
|
|
|
const html = await response.text();
|
|
// Check if the cookie value appears in the rendered HTML
|
|
// The values appear with HTML comments (<!-- -->) in the output
|
|
expect(html).toContain("TestUser");
|
|
},
|
|
});
|
|
|
|
// Test that request object is passed to the component
|
|
devTest("request object is passed to SSR component", {
|
|
framework: "react",
|
|
files: {
|
|
"pages/index.tsx": `
|
|
export const mode = "ssr";
|
|
export const streaming = false;
|
|
|
|
export default async function IndexPage({ request }) {
|
|
// Check if request exists
|
|
const hasRequest = request !== undefined;
|
|
const requestType = typeof request;
|
|
|
|
return (
|
|
<div>
|
|
<p>Has request: {hasRequest ? "yes" : "no"}</p>
|
|
<p>Request type: {requestType}</p>
|
|
</div>
|
|
);
|
|
}
|
|
`,
|
|
},
|
|
async test(dev) {
|
|
const response = await dev.fetch("/");
|
|
const html = await response.text();
|
|
|
|
// The values appear with HTML comments in the rendered output
|
|
expect(html).toContain("yes");
|
|
expect(html).toContain("object");
|
|
},
|
|
});
|