import type { ModuleFederationRuntimePlugin } from "@module-federation/enhanced/runtime";
import type { ComponentType } from "react";
interface OfflineFallbackConfig {
enableLogging?: boolean;
fallbackTimeout?: number;
retryAttempts?: number;
retryDelay?: number;
enableCircuitBreaker?: boolean;
circuitBreakerThreshold?: number;
circuitBreakerResetTimeout?: number;
fallbackComponents?: Record<string, ComponentType>;
}
const enhancedOfflineFallbackPlugin = (
config: OfflineFallbackConfig = {}
): ModuleFederationRuntimePlugin => {
const {
enableLogging = true,
fallbackTimeout = 5000,
retryAttempts = 2,
retryDelay = 1000,
enableCircuitBreaker = true,
circuitBreakerThreshold = 3,
circuitBreakerResetTimeout = 60000,
fallbackComponents = {},
} = config;
const remoteStates = new Map<string, any>();
const fallbackCache = new Map<string, ComponentType>();
const log = (message: string, ...args: any[]) => {
if (enableLogging) {
console.warn(`[OfflineFallbackPlugin] ${message}`, ...args);
}
};
const createFallbackComponent = (remoteId: string, error?: Error) => {
if (fallbackComponents[remoteId]) {
return fallbackComponents[remoteId];
}
const FallbackComponent = async () => {
// Dynamically import React to avoid eager loading issues
const React = await import('react');
return React.createElement("div", {
style: {
padding: "16px",
border: "2px dashed #ffa39e",
borderRadius: "8px",
backgroundColor: "#fff2f0",
color: "#cf1322",
textAlign: "center",
},
}, [
React.createElement("h3", { key: "title" }, "Remote Module Unavailable"),
React.createElement("p", { key: "description" },
`The remote module "${remoteId}" is currently offline.`),
]);
};
return FallbackComponent;
};
return {
name: "enhanced-offline-fallback-plugin",
async errorLoadRemote(args) {
const { id, error, lifecycle } = args;
log(`Remote loading failed: ${id}`, { lifecycle, error: error?.message });
switch (lifecycle) {
case 'afterResolve':
// Manifest loading failed
return {
id: 'fallback',
name: 'fallback',
metaData: {},
shared: [],
remotes: [],
exposes: []
};
case 'onLoad':
// Module loading failed
return () => ({
__esModule: true,
default: createFallbackComponent(id, error),
});
default:
return createFallbackComponent(id, error);
}
},
onLoad(args) {
log(`Successfully loaded remote: ${args.id}`);
return args;
},
};
};
export default enhancedOfflineFallbackPlugin;