Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6da2937
STRIPES-861: Setup federation
mkuklis Apr 25, 2023
eac40b8
Cleanup
mkuklis Apr 26, 2023
b6aa8f9
Cache remote components
mkuklis Apr 26, 2023
ff5e9a3
Prefetch handlers
mkuklis Apr 26, 2023
5ab4837
Align stripes-shared-context correctly
mkuklis Apr 27, 2023
9fd0420
Update @folio/stripes-shared-context version
mkuklis Apr 27, 2023
3b4fca0
wrap Pluggable's rendered Child in suspense to isolate react-dom's hi…
JohnC-80 May 25, 2023
86b3273
STCOR-718 load remote translations (#1309)
zburke Jun 8, 2023
72cb6e6
STCOR-725 load remote icons (#1317)
zburke Jun 9, 2023
d67c351
STCOR-718 correctly set apps' localized displayName
zburke Aug 4, 2023
f66ad62
STCOR-725 correctly load multiple icons per app
zburke Aug 4, 2023
44bd6dd
refactor catch up
zburke Dec 4, 2024
98a6b0e
resolve conflicts
JohnC-80 Nov 3, 2025
72a3f54
add registry to token util's set of paths for creds
JohnC-80 Nov 14, 2025
3cf47fd
ship context out to stripes-shared-context
JohnC-80 Nov 14, 2025
21dd6ad
preload all the things
JohnC-80 Nov 14, 2025
3deb33c
go back to memo'd version
JohnC-80 Nov 14, 2025
c756333
clean up
JohnC-80 Nov 14, 2025
7dc0e1d
only import/re-export context/initial values from shared-context
JohnC-80 Nov 19, 2025
196c37a
switch away from shared context
JohnC-80 Dec 1, 2025
5724025
use external ModuleFederation plugin
JohnC-80 Feb 5, 2026
03ac478
remove pre-preloading modules code
JohnC-80 Feb 6, 2026
f39a471
remove registryLoader
JohnC-80 Feb 6, 2026
a2bf44f
restore Root.js from main
JohnC-80 Feb 6, 2026
04094b3
add debug info to EntitlementLoader
JohnC-80 Feb 9, 2026
f9a47cf
remove mod-fed debug code
JohnC-80 Feb 10, 2026
839ef87
remove loadRemoteComponent and tests, replace with mod-fed runtime pa…
JohnC-80 Feb 10, 2026
da09382
use single instance of mf runtime
JohnC-80 Feb 11, 2026
6e1e3fa
use latest version of mod-fed
JohnC-80 Feb 13, 2026
48389de
load remote by the exposed name
JohnC-80 Feb 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
},
"dependencies": {
"@apollo/client": "^3.2.1",
"@module-federation/runtime": "^2.0.0",
"classnames": "^2.2.5",
"core-js": "^3.26.1",
"final-form": "^4.18.2",
Expand Down Expand Up @@ -148,4 +149,4 @@
"redux-observable": "^1.2.0",
"rxjs": "^6.6.3"
}
}
}
21 changes: 17 additions & 4 deletions src/components/EntitlementLoader.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useEffect, useState, useMemo } from 'react';
import PropTypes from 'prop-types';
import { getInstance } from '@module-federation/runtime';
import { useStripes } from '../StripesContext';
import { ModulesContext, useModules, modulesInitialState } from '../ModulesContext';
import loadRemoteComponent from '../loadRemoteComponent';
import { loadEntitlement } from './loadEntitlement';


/**
* preloadModules
* Loads each module code and sets up its getModule function.
Expand All @@ -16,14 +17,15 @@ import { loadEntitlement } from './loadEntitlement';
* @param {array} remotes
* @returns {app: [], plugin: [], settings: [], handler: []}
*/

export const preloadModules = async (stripes, remotes) => {
const modules = { app: [], plugin: [], settings: [], handler: [] };

try {
const loaderArray = [];
remotes.forEach(remote => {
const { name, location } = remote;
loaderArray.push(loadRemoteComponent(location, name)
const { name } = remote;
loaderArray.push(getInstance().loadRemote(`${name}/MainEntry`)
.then((module) => {
remote.getModule = () => module.default;
})
Expand Down Expand Up @@ -172,6 +174,10 @@ const EntitlementLoader = ({ children }) => {
const controller = new AbortController();
const signal = controller.signal;
if (okapi?.discoveryUrl) {
// ENABLE MOD FED DEBUGGING
localStorage.setItem('FEDERATION_DEBUG', 'true');


// fetches the list of registered apps/metadata,
// loads icons and translations, then module code,
// ultimately stores the result in the modules state to pass down into the modules context.
Expand All @@ -195,16 +201,23 @@ const EntitlementLoader = ({ children }) => {
handleRemoteModuleError(stripes, `Error loading remote module assets (icons, translations, sounds): ${e}`);
}

const remotesToRegister = remotes.map(remote => ({
name: remote.name, entry: remote.location
}));

getInstance().registerRemotes(remotesToRegister);

try {
// load module code - this loads each module only once and up `getModule` so that it can be used sychronously.
cachedModules = await preloadModules(stripes, remotesWithLoadedAssets);
cachedModules = await preloadModules(stripes, remotesWithLoadedAssets, remotesToRegister);
} catch (e) {
handleRemoteModuleError(stripes, `error loading remote modules: ${e}`);
}

setRemoteModules(cachedModules);
}
};

fetchRegistry();
}
return () => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/EntitlementLoader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { okapi } from 'stripes-config';
import EntitlementLoader, { preloadModules, loadModuleAssets } from './EntitlementLoader';
import { StripesContext } from '../StripesContext';
import { ModulesContext, useModules, modulesInitialState as mockModuleInitialState } from '../ModulesContext';
import loadRemoteComponent from '../loadRemoteComponent';
import { loadRemote, registerRemotes } from '@module-federation/runtime';
import { loadEntitlement } from './loadEntitlement';

jest.mock('stripes-config');
Expand Down
6 changes: 3 additions & 3 deletions src/components/loadEntitlement.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { stripesHubAPI } from '../constants';
export const loadEntitlement = async (discoveryUrl, signal) => {
let registry = {};
const discovery = await localforage.getItem(stripesHubAPI.REMOTE_LIST_KEY);
if (discovery) {
if (discovery && discovery.length !== 0) {
registry = { discovery };
} else if (discoveryUrl) {
try {
Expand All @@ -18,7 +18,7 @@ export const loadEntitlement = async (discoveryUrl, signal) => {
// it's present...)
registry.discovery = registryData?.discovery.filter((entry) => entry.name !== stripesHubAPI.HOST_APP_NAME);

await localforage.setItem(stripesHubAPI.REMOTE_LIST_KEY, registry.discovery);
// await localforage.setItem(stripesHubAPI.REMOTE_LIST_KEY, registry.discovery);
} catch (e) {
if (e.name !== 'AbortError') {
console.error('Discovery fetch error:', e); // eslint-disable-line no-console
Expand All @@ -39,7 +39,7 @@ export const loadEntitlement = async (discoveryUrl, signal) => {
remote.origin = url.origin;
const segments = url.href.split('/');
segments.pop();
const hrefWithoutFilename = segments.join('/')
const hrefWithoutFilename = segments.join('/');
remote.assetPath = hrefWithoutFilename;
});
return Promise.resolve(registry?.discovery);
Expand Down
39 changes: 0 additions & 39 deletions src/loadRemoteComponent.js

This file was deleted.

6 changes: 3 additions & 3 deletions src/loginServices.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,14 +317,14 @@ export async function loadTranslations(store, locale, defaultTranslations = {})
const res = await fetch(translationUrl.href)
.then((response) => {
if (response.ok) {
response.json().then((stripesTranslations) => {
return response.json().then((stripesTranslations) => {
store.dispatch(setTranslations(Object.assign(stripesTranslations, defaultTranslations)));
store.dispatch(setLocale(locale));
});
} else {
return Promise.reject(new Error(`Could not load translations from ${translationsUrl}`));
}
});

return res;
}

/**
Expand Down
51 changes: 0 additions & 51 deletions test/bigtest/tests/LoadRemoteComponent-test.js

This file was deleted.

Loading