Skip to content

Commit 9b8c34b

Browse files
authored
Merge pull request #153 from scalprum/manifest-cache
fix(core): do not process manifest for intialized scopes
2 parents 33dd6a7 + dcd4bed commit 9b8c34b

File tree

6 files changed

+101
-7
lines changed

6 files changed

+101
-7
lines changed

examples/test-app-e2e/src/e2e/test-app/sdk-plugin-loading.cy.ts

+7
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,11 @@ describe('SDK module loading', () => {
1818
cy.get(`[aria-label="Checked"]`).should('exist');
1919
cy.get('#plugin-manifest').should('exist');
2020
});
21+
22+
it('should render delayed module without processing entire manifest', () => {
23+
cy.visit('http://localhost:4200/sdk');
24+
// Delayed module is fetched after 5 seconds
25+
cy.wait(5001);
26+
cy.get('#delayed-module').should('exist');
27+
});
2128
});

examples/test-app/src/routes/SDKModules.tsx

+29-3
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,48 @@
1-
import React from 'react';
1+
import { useEffect, useState } from 'react';
22
import { ScalprumComponent } from '@scalprum/react-core';
3-
import { Grid } from '@mui/material';
3+
import { Grid, Typography } from '@mui/material';
44

55
const SDKModules = () => {
6+
const [delayed, setDelayed] = useState(false);
7+
const [seconds, setSeconds] = useState(0);
8+
useEffect(() => {
9+
const timeout = setTimeout(() => {
10+
setDelayed(true);
11+
}, 5000);
12+
const interval = setInterval(() => {
13+
if (seconds >= 6) {
14+
clearInterval(interval);
15+
return;
16+
}
17+
setSeconds((prevSeconds) => prevSeconds + 1);
18+
}, 1000);
19+
return () => {
20+
clearTimeout(timeout);
21+
clearInterval(interval);
22+
};
23+
}, []);
624
const props = {
725
name: 'plugin-manifest',
826
};
927
return (
1028
<Grid container spacing={4}>
1129
<Grid xs={12} md={6} item>
12-
<ScalprumComponent scope="sdk-plugin" module="./SDKComponent" />;
30+
<ScalprumComponent scope="sdk-plugin" module="./SDKComponent" />
1331
</Grid>
1432
<Grid xs={12} md={6} item>
1533
<ScalprumComponent scope="sdk-plugin" module="./SDKComponent" importName="NamedSDKComponent" />
1634
</Grid>
1735
<Grid xs={12} md={6} item>
1836
<ScalprumComponent scope="full-manifest" module="./SDKComponent" importName="PluginSDKComponent" {...props} />
1937
</Grid>
38+
39+
<Grid xs={12} md={6} item>
40+
{delayed ? (
41+
<ScalprumComponent scope="sdk-plugin" module="./DelayedModule" />
42+
) : (
43+
<Typography>Loading delayed module in {5 - seconds} seconds</Typography>
44+
)}
45+
</Grid>
2046
</Grid>
2147
);
2248
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import * as React from 'react';
2+
import FormatAlignLeftIcon from '@mui/icons-material/FormatAlignLeft';
3+
import FormatAlignCenterIcon from '@mui/icons-material/FormatAlignCenter';
4+
import FormatAlignRightIcon from '@mui/icons-material/FormatAlignRight';
5+
import FormatAlignJustifyIcon from '@mui/icons-material/FormatAlignJustify';
6+
import ToggleButton from '@mui/material/ToggleButton';
7+
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
8+
9+
export default function ToggleButtons() {
10+
const [alignment, setAlignment] = React.useState<string | null>('left');
11+
12+
const handleAlignment = (
13+
event: React.MouseEvent<HTMLElement>,
14+
newAlignment: string | null,
15+
) => {
16+
setAlignment(newAlignment);
17+
};
18+
19+
return (
20+
<ToggleButtonGroup
21+
value={alignment}
22+
exclusive
23+
onChange={handleAlignment}
24+
aria-label="text alignment"
25+
id="delayed-module"
26+
>
27+
<ToggleButton value="left" aria-label="left aligned">
28+
<FormatAlignLeftIcon />
29+
</ToggleButton>
30+
<ToggleButton value="center" aria-label="centered">
31+
<FormatAlignCenterIcon />
32+
</ToggleButton>
33+
<ToggleButton value="right" aria-label="right aligned">
34+
<FormatAlignRightIcon />
35+
</ToggleButton>
36+
<ToggleButton value="justify" aria-label="justified" disabled>
37+
<FormatAlignJustifyIcon />
38+
</ToggleButton>
39+
</ToggleButtonGroup>
40+
);
41+
}

federation-cdn-mock/webpack.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const TestSDKPlugin = new DynamicRemotePlugin({
5050
'./ModuleFour': resolve(__dirname, './src/modules/moduleFour.tsx'),
5151
'./SDKComponent': resolve(__dirname, './src/modules/SDKComponent.tsx'),
5252
'./ApiModule': resolve(__dirname, './src/modules/apiModule.tsx'),
53+
'./DelayedModule': resolve(__dirname, './src/modules/delayedModule.tsx'),
5354
},
5455
},
5556
});

packages/core/src/index.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ describe('scalprum', () => {
113113
pendingInjections: {},
114114
pendingLoading: {},
115115
pendingPrefetch: {},
116+
existingScopes: new Set(),
116117
api: {},
117118
scalprumOptions: {
118119
cacheTimeout: 120,

packages/core/src/index.ts

+22-4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export type Scalprum<T extends Record<string, any> = Record<string, any>> = {
4545
pendingPrefetch: {
4646
[key: string]: Promise<unknown>;
4747
};
48+
existingScopes: Set<string>;
4849
exposedModules: {
4950
[moduleId: string]: ExposedScalprumModule;
5051
};
@@ -248,6 +249,7 @@ export const initialize = <T extends Record<string, any> = Record<string, any>>(
248249
pendingInjections: {},
249250
pendingLoading: {},
250251
pendingPrefetch: {},
252+
existingScopes: new Set<string>(),
251253
exposedModules: {},
252254
scalprumOptions: defaultOptions,
253255
api: api || {},
@@ -263,7 +265,11 @@ export const removeScalprum = () => {
263265

264266
export const getAppData = (name: string): AppMetadata => getScalprum().appsConfig[name];
265267

266-
const setExposedModule = (moduleId: string, exposedModule: ExposedScalprumModule) => {
268+
const setExposedModule = (scope: string, module: string, exposedModule: ExposedScalprumModule) => {
269+
if (!getScalprum().existingScopes.has(scope)) {
270+
getScalprum().existingScopes.add(scope);
271+
}
272+
const moduleId = getModuleIdentifier(scope, module);
267273
getScalprum().exposedModules[moduleId] = exposedModule;
268274
};
269275

@@ -302,11 +308,23 @@ export async function processManifest(
302308
processor?: (manifest: any) => string[],
303309
): Promise<void> {
304310
let pendingInjection = getPendingInjection(scope);
305-
const { pluginStore } = getScalprum();
311+
const { pluginStore, existingScopes } = getScalprum();
312+
313+
if (existingScopes.has(scope)) {
314+
try {
315+
const exposedModule = await pluginStore.getExposedModule<ExposedScalprumModule>(scope, module);
316+
setExposedModule(scope, module, exposedModule);
317+
return;
318+
} catch (error) {
319+
console.warn('Unable to load module from existing container', error);
320+
console.warn('Scalprum will try to process manifest from scratch.');
321+
}
322+
}
323+
306324
if (pendingInjection) {
307325
await pendingInjection;
308326
const exposedModule = await pluginStore.getExposedModule<ExposedScalprumModule>(scope, module);
309-
setExposedModule(getModuleIdentifier(scope, module), exposedModule);
327+
setExposedModule(scope, module, exposedModule);
310328
return;
311329
}
312330

@@ -361,7 +379,7 @@ export async function processManifest(
361379
await pluginStore.loadPlugin(sdkManifest);
362380
try {
363381
const exposedModule = await pluginStore.getExposedModule<ExposedScalprumModule>(scope, module);
364-
setExposedModule(getModuleIdentifier(scope, module), exposedModule);
382+
setExposedModule(scope, module, exposedModule);
365383
return;
366384
} catch (error) {
367385
clearPendingInjection(scope);

0 commit comments

Comments
 (0)