@@ -43,22 +43,21 @@ export function createTanStackServerFnPlugin(opts: ServerFnPluginOpts): {
43
43
const directiveFnsById : Record < string , DirectiveFn > = { }
44
44
let viteDevServer : ViteDevServer | undefined
45
45
46
- const onDirectiveFnsById = ( d : Record < string , DirectiveFn > ) => {
47
- // When directives are compiled, save them to the plugin's state
48
- // This state will be used both during development to incrementally
49
- // look up server functions and during build/production to produce a
50
- // static manifest that can be read by the server build
51
- Object . assign ( directiveFnsById , d )
52
-
53
- if ( viteDevServer ) {
54
- const mod = viteDevServer . moduleGraph . getModuleById (
55
- resolveViteId ( opts . manifestVirtualImportId ) ,
56
- )
57
- if ( mod ) {
58
- viteDevServer . moduleGraph . invalidateModule ( mod )
46
+ const onDirectiveFnsById = buildOnDirectiveFnsByIdCallback ( {
47
+ directiveFnsById,
48
+ manifestVirtualImportId : opts . manifestVirtualImportId ,
49
+ invalidateModule : ( id ) => {
50
+ if ( viteDevServer ) {
51
+ const mod = viteDevServer . moduleGraph . getModuleById ( id )
52
+ if ( mod ) {
53
+ if ( debug ) {
54
+ console . info ( `invalidating module ${ JSON . stringify ( mod . id ) } ` )
55
+ }
56
+ viteDevServer . moduleGraph . invalidateModule ( mod )
57
+ }
59
58
}
60
- }
61
- }
59
+ } ,
60
+ } )
62
61
63
62
const directive = 'use server'
64
63
const directiveLabel = 'Server Function'
@@ -176,30 +175,23 @@ export function TanStackServerFnPluginEnv(
176
175
const directiveFnsById : Record < string , DirectiveFn > = { }
177
176
let serverDevEnv : DevEnvironment | undefined
178
177
179
- const onDirectiveFnsById = ( d : Record < string , DirectiveFn > ) => {
180
- if ( debug ) console . info ( `onDirectiveFnsById received: ` , d )
181
-
182
- // When directives are compiled, save them to the plugin's state
183
- // This state will be used both during development to incrementally
184
- // look up server functions and during build/production to produce a
185
- // static manifest that can be read by the server build
186
- Object . assign ( directiveFnsById , d )
187
- if ( debug ) console . info ( `directiveFnsById after update: ` , directiveFnsById )
188
-
189
- // during dev, invalidate the module in the server environment
190
- if ( serverDevEnv ) {
191
- const mod = serverDevEnv . moduleGraph . getModuleById (
192
- resolveViteId ( opts . manifestVirtualImportId ) ,
193
- )
194
- if ( mod ) {
195
- if ( debug )
196
- console . info (
197
- `invalidating module ${ JSON . stringify ( mod . id ) } in server environment` ,
198
- )
199
- serverDevEnv . moduleGraph . invalidateModule ( mod )
178
+ const onDirectiveFnsById = buildOnDirectiveFnsByIdCallback ( {
179
+ directiveFnsById,
180
+ manifestVirtualImportId : opts . manifestVirtualImportId ,
181
+ invalidateModule : ( id ) => {
182
+ if ( serverDevEnv ) {
183
+ const mod = serverDevEnv . moduleGraph . getModuleById ( id )
184
+ if ( mod ) {
185
+ if ( debug ) {
186
+ console . info (
187
+ `invalidating module ${ JSON . stringify ( mod . id ) } in server environment` ,
188
+ )
189
+ }
190
+ serverDevEnv . moduleGraph . invalidateModule ( mod )
191
+ }
200
192
}
201
- }
202
- }
193
+ } ,
194
+ } )
203
195
204
196
const directive = 'use server'
205
197
const directiveLabel = 'Server Function'
@@ -273,3 +265,35 @@ export function TanStackServerFnPluginEnv(
273
265
function resolveViteId ( id : string ) {
274
266
return `\0${ id } `
275
267
}
268
+
269
+ function buildOnDirectiveFnsByIdCallback ( opts : {
270
+ invalidateModule : ( resolvedId : string ) => void
271
+ directiveFnsById : Record < string , DirectiveFn >
272
+ manifestVirtualImportId : string
273
+ } ) {
274
+ const onDirectiveFnsById = ( d : Record < string , DirectiveFn > ) => {
275
+ if ( debug ) {
276
+ console . info ( `onDirectiveFnsById received: ` , d )
277
+ }
278
+
279
+ // When directives are compiled, save them to `directiveFnsById`
280
+ // This state will be used both during development to incrementally
281
+ // look up server functions and during build/production to produce a
282
+ // static manifest that can be read by the server build
283
+ Object . assign ( opts . directiveFnsById , d )
284
+ if ( debug ) {
285
+ console . info ( `directiveFnsById after update: ` , opts . directiveFnsById )
286
+ }
287
+
288
+ opts . invalidateModule ( resolveViteId ( opts . manifestVirtualImportId ) )
289
+
290
+ // a single module can contain multiple server functions, only invalidate the module once
291
+ const uniqueFilenames = new Set (
292
+ Object . values ( d ) . map ( ( fn ) => fn . extractedFilename ) ,
293
+ )
294
+ uniqueFilenames . forEach ( ( filename ) => {
295
+ opts . invalidateModule ( filename )
296
+ } )
297
+ }
298
+ return onDirectiveFnsById
299
+ }
0 commit comments