-
Notifications
You must be signed in to change notification settings - Fork 3
feat: add configurable rscPayloadDir option
#75
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
Changes from 2 commits
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 |
|---|---|---|
|
|
@@ -31,6 +31,7 @@ interface RawComponent { | |
| export async function processRscComponents( | ||
| deferRegistryIterator: AsyncIterable<RawComponent>, | ||
| appRscStream: ReadableStream, | ||
| rscPayloadDir: string, | ||
| context?: { warn: (message: string) => void }, | ||
|
Comment on lines
24
to
36
|
||
| ): Promise<ProcessResult> { | ||
| // Step 1: Collect all components from deferRegistry | ||
|
|
@@ -95,7 +96,7 @@ export async function processRscComponents( | |
|
|
||
| // Compute content hash for this component | ||
| const contentHash = await computeContentHash(content); | ||
| const finalId = getPayloadIDFor(contentHash); | ||
| const finalId = getPayloadIDFor(contentHash, rscPayloadDir); | ||
|
|
||
| // Create mapping | ||
| idMapping.set(tempId, finalId); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ import type { Plugin } from "vite"; | |
| import rsc from "@vitejs/plugin-rsc"; | ||
| import { buildApp } from "../build/buildApp"; | ||
| import { serverPlugin } from "./server"; | ||
| import { defaultRscPayloadDir } from "../rsc/rscModule"; | ||
|
|
||
| interface FunstackStaticBaseOptions { | ||
| /** | ||
|
|
@@ -25,6 +26,16 @@ interface FunstackStaticBaseOptions { | |
| * The module is imported for its side effects only (no exports needed). | ||
| */ | ||
| clientInit?: string; | ||
| /** | ||
| * Directory name used for RSC payload files in the build output. | ||
| * The final path will be `/funstack__/{rscPayloadDir}/{hash}.txt`. | ||
| * | ||
| * Change this if your hosting platform has issues with the default | ||
| * directory name (e.g. Cloudflare Workers redirects URLs containing colons). | ||
| * | ||
| * @default "fun:rsc-payload" | ||
| */ | ||
| rscPayloadDir?: string; | ||
| } | ||
|
|
||
| interface SingleEntryOptions { | ||
|
|
@@ -58,7 +69,12 @@ export type FunstackStaticOptions = FunstackStaticBaseOptions & | |
| export default function funstackStatic( | ||
| options: FunstackStaticOptions, | ||
| ): (Plugin | Plugin[])[] { | ||
| const { publicOutDir = "dist/public", ssr = false, clientInit } = options; | ||
| const { | ||
| publicOutDir = "dist/public", | ||
| ssr = false, | ||
| clientInit, | ||
| rscPayloadDir = defaultRscPayloadDir, | ||
| } = options; | ||
|
Comment on lines
+76
to
+81
|
||
|
|
||
| let resolvedEntriesModule: string = "__uninitialized__"; | ||
| let resolvedClientInitEntry: string | undefined; | ||
|
|
@@ -166,7 +182,10 @@ export default function funstackStatic( | |
| ].join("\n"); | ||
| } | ||
| if (id === "\0virtual:funstack/config") { | ||
| return `export const ssr = ${JSON.stringify(ssr)};`; | ||
| return [ | ||
| `export const ssr = ${JSON.stringify(ssr)};`, | ||
| `export const rscPayloadDir = ${JSON.stringify(rscPayloadDir)};`, | ||
| ].join("\n"); | ||
| } | ||
| if (id === "\0virtual:funstack/client-init") { | ||
| if (resolvedClientInitEntry) { | ||
|
|
@@ -179,7 +198,7 @@ export default function funstackStatic( | |
| { | ||
| name: "@funstack/static:build", | ||
| async buildApp(builder) { | ||
| await buildApp(builder, this); | ||
| await buildApp(builder, this, { rscPayloadDir }); | ||
| }, | ||
| }, | ||
| ]; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,17 @@ | ||
| /** | ||
| * ID is prefixed with this string to form module path. | ||
| * Default directory name for RSC payload files. | ||
| */ | ||
| const rscPayloadIDPrefix = "fun:rsc-payload/"; | ||
| export const defaultRscPayloadDir = "fun:rsc-payload"; | ||
|
|
||
| /** | ||
| * Add prefix to raw ID to form payload ID so that the ID is | ||
| * distinguishable from other possible IDs. | ||
| */ | ||
| export function getPayloadIDFor(rawId: string): string { | ||
| return `${rscPayloadIDPrefix}${rawId}`; | ||
| export function getPayloadIDFor( | ||
| rawId: string, | ||
| rscPayloadDir: string = defaultRscPayloadDir, | ||
| ): string { | ||
| return `${rscPayloadDir}/${rawId}`; | ||
| } | ||
|
Comment on lines
6
to
15
|
||
|
|
||
| const rscModulePathPrefix = "/funstack__/"; | ||
|
|
||
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.
This request filter now matches any
.txtrequest underfunstack__/, which may overcount unrelated files and doesn’t actually prove the app fetched the main RSC payload path referenced by the HTML. To keep the test robust with configurablerscPayloadDir, consider extracting the expected payload URL from the document (preload link / manifest) and assert that exact path was requested.