-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
fix: no invalidation for server functions in dev #5513
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 all 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 |
|---|---|---|
|
|
@@ -26,6 +26,7 @@ export type SupportedFunctionPath = | |
| export type GenerateFunctionIdFn = (opts: { | ||
| filename: string | ||
| functionName: string | ||
| extractedFilename: string | ||
| }) => string | ||
|
|
||
|
Comment on lines
26
to
31
Contributor
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. 🧩 Analysis chainThreading extractedFilename into ID generation looks good; verify call sites updated. The new GenerateFunctionIdFn signature adds extractedFilename. Ensure all implementations and usages across the repo are updated to avoid type drift. Run to locate and validate implementors: 🏁 Script executed: #!/bin/bash
# Find typedef and implementors/usages
rg -nP --type=ts 'type\s+GenerateFunctionIdFn\b|interface\s+GenerateFunctionIdFn\b'
rg -nP --type=ts '\bgenerateFunctionId\s*:\s*\(' -C3
rg -nP --type=ts '\bgenerateFunctionId\(\s*\{[^}]*\}\s*\)' -C2Length of output: 712 🏁 Script executed: #!/bin/bash
# Find all generateFunctionId call sites and implementations more broadly
echo "=== All generateFunctionId property definitions ==="
rg -nP --type=ts 'generateFunctionId\s*[:=]' -C5
echo ""
echo "=== All places where generateFunctionId is called ==="
rg -nP --type=ts 'generateFunctionId\s*\(' -C3
echo ""
echo "=== Files containing generateFunctionId ==="
fd --type f -e ts -e tsx | xargs rg -l 'generateFunctionId'Length of output: 9970 🏁 Script executed: #!/bin/bash
# Check the schema definition for generateFunctionId
echo "=== Schema definition for generateFunctionId ==="
sed -n '162,175p' packages/start-plugin-core/src/schema.ts
echo ""
echo "=== Full call site in server-functions-plugin ==="
sed -n '90,102p' packages/server-functions-plugin/src/index.ts
echo ""
echo "=== Full call site in directive-functions-plugin ==="
sed -n '490,500p' packages/directive-functions-plugin/src/compilers.tsLength of output: 1387 Type signature mismatch: GenerateFunctionIdFn requires extractedFilename but not all call sites provide it. The reviewed change adds
In strict TypeScript mode, the server-functions-plugin call will fail type checking. Either:
🤖 Prompt for AI Agents |
||
| export type ReplacerFn = (opts: { | ||
|
|
@@ -46,7 +47,6 @@ export type CompileDirectivesOpts = ParseAstOptions & { | |
| }) => string | ||
| generateFunctionId: GenerateFunctionIdFn | ||
| replacer: ReplacerFn | ||
| // devSplitImporter: string | ||
| filename: string | ||
| root: string | ||
| } | ||
|
|
@@ -493,7 +493,8 @@ export function findDirectives( | |
| const relativeFilename = path.relative(opts.root, baseFilename) | ||
| const functionId = opts.generateFunctionId({ | ||
| filename: relativeFilename, | ||
| functionName: functionName, | ||
| functionName, | ||
| extractedFilename, | ||
| }) | ||
| // If a replacer is provided, replace the function with the replacer | ||
| if (opts.replacer) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,40 +7,29 @@ | |
| Create a new instance of the plugin with the following options: | ||
|
|
||
| ```ts | ||
| const TanStackServerFnsPlugin = createTanStackServerFnPlugin({ | ||
| // This is the ID (virtual module) that will be made available to look up | ||
| // and import our server function manifest and resolve its modules. | ||
| TanStackServerFnPlugin({ | ||
| // This is the ID that will be available to look up and import | ||
| // our server function manifest and resolve its module | ||
| manifestVirtualImportId: 'tanstack:server-fn-manifest', | ||
| generateFunctionId: startPluginOpts?.serverFns?.generateFunctionId, | ||
| client: { | ||
| getRuntimeCode: () => | ||
| `import { createClientRpc } from '@tanstack/react-start/client-runtime'`, | ||
| replacer: (opts) => `createClientRpc(${JSON.stringify(opts.functionId)})`, | ||
| }, | ||
| ssr: { | ||
| getRuntimeCode: () => | ||
| `import { createSsrRpc } from '@tanstack/react-start/ssr-runtime'`, | ||
| replacer: (opts) => `createSsrRpc(${JSON.stringify(opts.functionId)})`, | ||
| `import { createClientRpc } from '@tanstack/${corePluginOpts.framework}-start/client-rpc'`, | ||
| replacer: (d) => `createClientRpc('${d.functionId}')`, | ||
| envName: 'client', | ||
| }, | ||
| server: { | ||
| getRuntimeCode: () => | ||
| `import { createServerRpc } from '@tanstack/react-start/server-runtime'`, | ||
| replacer: (opts) => | ||
| `createServerRpc(${JSON.stringify(opts.functionId)}, ${opts.fn})`, | ||
| `import { createServerRpc } from '@tanstack/${corePluginOpts.framework}-start/server-rpc'`, | ||
| replacer: (d) => `createServerRpc('${d.functionId}', ${d.fn})`, | ||
| envName: 'ssr', | ||
| }, | ||
|
Comment on lines
21
to
26
Contributor
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. 🧩 Analysis chainVerify envName value for server configuration. The server configuration has 🏁 Script executed: #!/bin/bash
# Search for envName usage patterns in server-functions-plugin and related packages
rg -nP --type=ts "envName:\s*['\"]" -A2 -B2Length of output: 665 I found that 🏁 Script executed: #!/bin/bash
# Search for envName in server-functions-plugin source code (not README)
rg -n "envName" packages/server-functions-plugin/src --type=tsLength of output: 816 🏁 Script executed: #!/bin/bash
# Also check the actual server-functions-plugin README to see full context
head -30 packages/server-functions-plugin/README.mdLength of output: 990 Update README.md to use correct envName value for server configuration. The README documentation incorrectly shows Update line 25 from: to: 🤖 Prompt for AI Agents |
||
| }) | ||
| ``` | ||
|
|
||
| Then you can inject the plugin into the appropriate vite config plugin arrays: | ||
|
|
||
| ```ts | ||
| clientVitePlugins: [TanStackServerFnsPlugin.client] | ||
| ssrVitePlugins: [TanStackServerFnsPlugin.ssr] | ||
| serverVitePlugins: [TanStackServerFnsPlugin.server] | ||
| }), | ||
| ``` | ||
|
|
||
| ## Providing the wrapper implementations | ||
|
|
||
| Each runtime replacement should be implemented by your framework. Generally, on the client and SSR runtimes, you'll end up using a `fetch` call to call the server function your desired endpoint, like this: | ||
| Each runtime replacement should be implemented by your framework. Generally, on the client runtime, you'll end up using a `fetch` call to call the server function your desired endpoint, like this: | ||
|
|
||
| ```ts | ||
| function createClientRpc(functionId: string) { | ||
|
|
@@ -71,20 +60,16 @@ function createClientRpc(functionId: string) { | |
| In your server handler, you can import the manifest and use it to look up and dynamically import the server function you want to call. | ||
|
|
||
| ```ts | ||
| import serverFnManifest from 'tanstack:server-fn-manifest' | ||
| import { getServerFnById } from 'tanstack:server-fn-manifest' | ||
|
|
||
| export const handler = async (req: Request) => { | ||
| const functionId = req.url.split('/').pop() | ||
| invariant(functionId, 'No function ID provided') | ||
|
|
||
| const fnInfo = serverFnManifest[functionId] | ||
| invariant(fn, `Server function ${functionId} not found`) | ||
|
|
||
| const fnModule = await fnInfo.importer() | ||
| invariant(fnModule, `Server function ${functionId} could not be imported`) | ||
| const serverFn = await getServerFnById(functionId) | ||
|
|
||
| const args = await req.json() | ||
|
|
||
| return await fnModule(...args) | ||
| return await serverFn(...args) | ||
| } | ||
| ``` | ||
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.
Fix unreachable code and hash algorithm inconsistency.
Two issues:
return undefinedafter line 263 already returns the hash, making it unreachable.sha1(line 261).Apply this diff:
generateFunctionId: ({ filename, functionName }) => { // Return a custom ID string. If you return undefined, the default is used. - return crypto - .createHash('sha1') + return crypto + .createHash('sha256') .update(`${filename}--${functionName}`) .digest('hex') - return undefined },📝 Committable suggestion
🤖 Prompt for AI Agents