Skip to content

Commit 9203621

Browse files
refactor(rsc): remove diff-added globalThis resolver state
1 parent bae4e62 commit 9203621

2 files changed

Lines changed: 38 additions & 62 deletions

File tree

packages/runtime/render/src/client/callServer.ts

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,21 @@ type ReactServerValue = unknown;
88
export type ActionIdResolver = (id: string) => string | Promise<string>;
99
export type ActionRequestUrlResolver = (entryName?: string) => string;
1010

11-
const ACTION_RESOLVER_KEY = '__MODERN_RSC_ACTION_RESOLVER__';
12-
const ACTION_URL_RESOLVER_KEY = '__MODERN_RSC_ACTION_URL_RESOLVER__';
11+
let actionIdResolver: ActionIdResolver | undefined;
12+
let actionRequestUrlResolver: ActionRequestUrlResolver | undefined;
1313

1414
/**
1515
* Register a custom action ID resolver. Plugins (e.g. Module Federation)
1616
* use this to remap raw action IDs before they are sent to the server.
1717
*/
18-
export const setResolveActionId = (resolver: ActionIdResolver): void => {
19-
(
20-
globalThis as typeof globalThis & {
21-
[ACTION_RESOLVER_KEY]?: ActionIdResolver;
22-
}
23-
)[ACTION_RESOLVER_KEY] = resolver;
18+
export const setResolveActionId = (resolver?: ActionIdResolver): void => {
19+
actionIdResolver = resolver;
2420
};
2521

2622
export const setActionIdResolver = setResolveActionId;
2723

2824
const resolveActionId = (id: string): string | Promise<string> => {
29-
const resolver = (
30-
globalThis as typeof globalThis & {
31-
[ACTION_RESOLVER_KEY]?: ActionIdResolver;
32-
}
33-
)[ACTION_RESOLVER_KEY];
25+
const resolver = actionIdResolver;
3426
if (typeof resolver === 'function') {
3527
return resolver(id);
3628
}
@@ -42,13 +34,9 @@ const resolveActionId = (id: string): string | Promise<string> => {
4234
* to align request URLs with customized route/base configurations.
4335
*/
4436
export const setResolveActionRequestUrl = (
45-
resolver: ActionRequestUrlResolver,
37+
resolver?: ActionRequestUrlResolver,
4638
): void => {
47-
(
48-
globalThis as typeof globalThis & {
49-
[ACTION_URL_RESOLVER_KEY]?: ActionRequestUrlResolver;
50-
}
51-
)[ACTION_URL_RESOLVER_KEY] = resolver;
39+
actionRequestUrlResolver = resolver;
5240
};
5341

5442
export const setActionRequestUrlResolver = setResolveActionRequestUrl;
@@ -57,11 +45,7 @@ const resolveActionRequestUrl = (): string => {
5745
const entryName =
5846
typeof window !== 'undefined' ? window.__MODERN_JS_ENTRY_NAME : undefined;
5947

60-
const resolver = (
61-
globalThis as typeof globalThis & {
62-
[ACTION_URL_RESOLVER_KEY]?: ActionRequestUrlResolver;
63-
}
64-
)[ACTION_URL_RESOLVER_KEY];
48+
const resolver = actionRequestUrlResolver;
6549
if (typeof resolver === 'function') {
6650
return resolver(entryName);
6751
}

packages/runtime/render/tests/callServer.test.ts

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,43 @@
1-
const ACTION_RESOLVER_KEY = '__MODERN_RSC_ACTION_RESOLVER__';
2-
const ACTION_URL_RESOLVER_KEY = '__MODERN_RSC_ACTION_URL_RESOLVER__';
3-
4-
type GlobalWithResolvers = typeof globalThis & {
5-
[ACTION_RESOLVER_KEY]?: (id: string) => string | Promise<string>;
6-
[ACTION_URL_RESOLVER_KEY]?: (entryName?: string) => string;
7-
};
8-
91
const WEBPACK_REQUIRE_SHIM = {
102
u: (chunkId: string | number) => String(chunkId),
113
};
124

135
describe('requestCallServer pluggable action id resolver', () => {
14-
const originalFetch = globalThis.fetch;
15-
const originalWindow = (globalThis as { window?: unknown }).window;
6+
const runtimeGlobal = global as typeof global & {
7+
fetch?: typeof fetch;
8+
window?: { __MODERN_JS_ENTRY_NAME: string };
9+
};
10+
const originalFetch = runtimeGlobal.fetch;
11+
const originalWindow = runtimeGlobal.window;
1612
let requestCallServer: typeof import(
1713
'../src/client/callServer',
1814
).requestCallServer;
1915
let setResolveActionId: typeof import(
2016
'../src/client/callServer',
2117
).setResolveActionId;
18+
let setActionIdResolver: typeof import(
19+
'../src/client/callServer',
20+
).setActionIdResolver;
2221
let setResolveActionRequestUrl: typeof import(
2322
'../src/client/callServer',
2423
).setResolveActionRequestUrl;
24+
let setActionRequestUrlResolver: typeof import(
25+
'../src/client/callServer',
26+
).setActionRequestUrlResolver;
2527
let fetchMock: ReturnType<typeof rstest.fn>;
2628

2729
beforeAll(async () => {
2830
rstest.stubGlobal('__webpack_require__', WEBPACK_REQUIRE_SHIM);
2931
const mod = await import('../src/client/callServer');
3032
requestCallServer = mod.requestCallServer;
3133
setResolveActionId = mod.setResolveActionId;
34+
setActionIdResolver = mod.setActionIdResolver;
3235
setResolveActionRequestUrl = mod.setResolveActionRequestUrl;
36+
setActionRequestUrlResolver = mod.setActionRequestUrlResolver;
3337
});
3438

3539
beforeEach(() => {
36-
(
37-
globalThis as unknown as { window?: { __MODERN_JS_ENTRY_NAME: string } }
38-
).window = {
40+
runtimeGlobal.window = {
3941
__MODERN_JS_ENTRY_NAME: 'main',
4042
};
4143

@@ -46,22 +48,20 @@ describe('requestCallServer pluggable action id resolver', () => {
4648
statusText: 'OK',
4749
} as Response;
4850
});
49-
globalThis.fetch = fetchMock as typeof globalThis.fetch;
51+
runtimeGlobal.fetch = fetchMock as typeof fetch;
5052
});
5153

5254
afterEach(() => {
53-
delete (globalThis as GlobalWithResolvers)[ACTION_RESOLVER_KEY];
54-
delete (globalThis as GlobalWithResolvers)[ACTION_URL_RESOLVER_KEY];
55-
(
56-
globalThis as unknown as { window?: { __MODERN_JS_ENTRY_NAME: string } }
57-
).window = {
55+
setResolveActionId(undefined);
56+
setResolveActionRequestUrl(undefined);
57+
runtimeGlobal.window = {
5858
__MODERN_JS_ENTRY_NAME: 'main',
5959
};
6060
});
6161

6262
afterAll(() => {
63-
globalThis.fetch = originalFetch;
64-
(globalThis as { window?: unknown }).window = originalWindow;
63+
runtimeGlobal.fetch = originalFetch;
64+
runtimeGlobal.window = originalWindow;
6565
rstest.unstubAllGlobals();
6666
});
6767

@@ -131,22 +131,19 @@ describe('requestCallServer pluggable action id resolver', () => {
131131
});
132132
});
133133

134-
test('resolver set via global key is picked up', async () => {
135-
(globalThis as GlobalWithResolvers)[ACTION_RESOLVER_KEY] = id =>
136-
`global:${id}`;
134+
test('alias setter remaps action ids', async () => {
135+
setActionIdResolver(id => `alias:${id}`);
137136

138137
await requestCallServer('action123', []);
139138

140-
expectActionHeader('global:action123');
139+
expectActionHeader('alias:action123');
141140
});
142141

143142
test('uses custom request url resolver when registered', async () => {
144143
setResolveActionRequestUrl(entryName =>
145144
entryName ? `/custom/${entryName}` : '/custom',
146145
);
147-
(
148-
globalThis as unknown as { window?: { __MODERN_JS_ENTRY_NAME: string } }
149-
).window = {
146+
runtimeGlobal.window = {
150147
__MODERN_JS_ENTRY_NAME: 'server-component-root',
151148
};
152149

@@ -155,13 +152,12 @@ describe('requestCallServer pluggable action id resolver', () => {
155152
expectActionHeader('entry-action', '/custom/server-component-root');
156153
});
157154

158-
test('request url resolver set via global key is picked up', async () => {
159-
(globalThis as GlobalWithResolvers)[ACTION_URL_RESOLVER_KEY] = () =>
160-
'/global/custom';
155+
test('alias request url resolver is used', async () => {
156+
setActionRequestUrlResolver(() => '/alias/custom');
161157

162158
await requestCallServer('action123', []);
163159

164-
expectActionHeader('action123', '/global/custom');
160+
expectActionHeader('action123', '/alias/custom');
165161
});
166162

167163
test('wraps request url resolver errors with CallServerError', async () => {
@@ -177,9 +173,7 @@ describe('requestCallServer pluggable action id resolver', () => {
177173
});
178174

179175
test('uses entry specific action endpoint when entry name is not main/index', async () => {
180-
(
181-
globalThis as unknown as { window?: { __MODERN_JS_ENTRY_NAME: string } }
182-
).window = {
176+
runtimeGlobal.window = {
183177
__MODERN_JS_ENTRY_NAME: 'server-component-root',
184178
};
185179

@@ -189,9 +183,7 @@ describe('requestCallServer pluggable action id resolver', () => {
189183
});
190184

191185
test('falls back to root endpoint when window is unavailable', async () => {
192-
(
193-
globalThis as unknown as { window?: { __MODERN_JS_ENTRY_NAME: string } }
194-
).window = undefined;
186+
runtimeGlobal.window = undefined;
195187

196188
await requestCallServer('no-window-action', []);
197189

0 commit comments

Comments
 (0)