Skip to content

Commit 03b1c97

Browse files
committed
refactor(rsc-mf): make callback bootstrap injection source-driven
1 parent b52276d commit 03b1c97

2 files changed

Lines changed: 15 additions & 23 deletions

File tree

tests/integration/rsc-mf/remote/src/runtime/createRscExposeDefinitions.ts

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ const CALLBACK_BOOTSTRAP_PREFIX = './src/runtime/';
66
const USERLAND_EXPOSE_PREFIX = './';
77
const SOURCE_ENTRY_EXTENSION_PATTERN = /\.[cm]?[jt]sx?$/i;
88
const RSC_LAYER = 'react-server-components';
9-
const CALLBACK_BOOTSTRAP_EXPOSE_KEY_PATTERN =
10-
/^\.\/(?:RemoteClient[\w-]*|actions|nestedActions|defaultAction|actionBundle)$/;
11-
const CALLBACK_BOOTSTRAP_IMPORT_PATH_PATTERN =
12-
/\/(?:RemoteClient[\w-]*|actions|nestedActions|defaultAction|actionBundle)\.[cm]?[jt]sx?$/;
139
const LOCAL_MODULE_SPECIFIER_PATTERN = /^\.{1,2}\//;
1410
const SOURCE_DIRECTIVE_PATTERN = /^\s*['"]use (?:client|server)['"]\s*;?/m;
1511
const EXPORT_FROM_SPECIFIER_PATTERN =
@@ -25,6 +21,7 @@ const SOURCE_ENTRY_EXTENSIONS = [
2521
'.cjs',
2622
] as const;
2723
const REMOTE_PROJECT_ROOT = path.resolve(__dirname, '../..');
24+
const callbackDirectiveBySourceFile = new Map<string, boolean>();
2825

2926
type ExposeImportInput = string | string[];
3027
export type ExposeDefinitionInput =
@@ -134,15 +131,9 @@ const createRscExpose = (
134131
layer: RSC_LAYER,
135132
}) as const;
136133

137-
const shouldInjectCallbackBootstrap = (
138-
exposeKey: string,
139-
importPaths: string[],
140-
) =>
141-
CALLBACK_BOOTSTRAP_EXPOSE_KEY_PATTERN.test(exposeKey) ||
142-
importPaths.some(
143-
importPath =>
144-
CALLBACK_BOOTSTRAP_IMPORT_PATH_PATTERN.test(importPath) ||
145-
referencesCallbackCapableSourceModule(importPath),
134+
const shouldInjectCallbackBootstrap = (importPaths: string[]) =>
135+
importPaths.some(importPath =>
136+
referencesCallbackCapableSourceModule(importPath),
146137
);
147138

148139
const readSourceFile = (filePath: string) => {
@@ -186,15 +177,21 @@ const referencesCallbackCapableSourceModule = (importPath: string) => {
186177

187178
const visitedFiles = new Set<string>();
188179
const hasCallbackDirective = (filePath: string): boolean => {
180+
const cachedResult = callbackDirectiveBySourceFile.get(filePath);
181+
if (typeof cachedResult !== 'undefined') {
182+
return cachedResult;
183+
}
189184
if (visitedFiles.has(filePath)) {
190185
return false;
191186
}
192187
visitedFiles.add(filePath);
193188
const sourceText = readSourceFile(filePath);
194189
if (!sourceText) {
190+
callbackDirectiveBySourceFile.set(filePath, false);
195191
return false;
196192
}
197193
if (SOURCE_DIRECTIVE_PATTERN.test(sourceText)) {
194+
callbackDirectiveBySourceFile.set(filePath, true);
198195
return true;
199196
}
200197

@@ -211,10 +208,12 @@ const referencesCallbackCapableSourceModule = (importPath: string) => {
211208
filePath,
212209
);
213210
if (childModuleFilePath && hasCallbackDirective(childModuleFilePath)) {
211+
callbackDirectiveBySourceFile.set(filePath, true);
214212
return true;
215213
}
216214
}
217215

216+
callbackDirectiveBySourceFile.set(filePath, false);
218217
return false;
219218
};
220219

@@ -343,10 +342,7 @@ export const createRscExposeDefinitions = (
343342
createRscExpose(
344343
normalizedDefinition.importPaths,
345344
normalizedDefinition.exposeOverrides,
346-
shouldInjectCallbackBootstrap(
347-
exposeKey,
348-
normalizedDefinition.importPaths,
349-
),
345+
shouldInjectCallbackBootstrap(normalizedDefinition.importPaths),
350346
),
351347
]),
352348
);

tests/integration/rsc-mf/tests/createRscExposeDefinitions.test.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,14 @@ describe('createRscExposeDefinitions', () => {
5353
});
5454

5555
it('allows expose imports outside src root when path is relative', () => {
56-
const { createRscExposeDefinitions, CALLBACK_BOOTSTRAP_MODULE } =
57-
loadCreateRscExposeDefinitions();
56+
const { createRscExposeDefinitions } = loadCreateRscExposeDefinitions();
5857
expect(
5958
createRscExposeDefinitions({
6059
'./RemoteClientCounter': './app/components/RemoteClientCounter.tsx',
6160
}),
6261
).toEqual({
6362
'./RemoteClientCounter': {
64-
import: [
65-
CALLBACK_BOOTSTRAP_MODULE,
66-
'./app/components/RemoteClientCounter.tsx',
67-
],
63+
import: ['./app/components/RemoteClientCounter.tsx'],
6864
layer: 'react-server-components',
6965
},
7066
});

0 commit comments

Comments
 (0)