### Initialize Runtime and Load Remote with Timeout Source: https://www.npmjs.com/package/mf-shield/v/0.1.0 Use `createFederationRuntime` to initialize the runtime and get a loader. Wrap promises with `withTimeout` to reject with `FederationTimeoutError` if an SLA is missed. ```typescript import * as React from "react"; import * as ReactDOM from "react-dom"; import { createSharedSingleton, withTimeout, FederationTimeoutError } from "mf-shield"; import { createFederationRuntime } from "mf-shield/federation"; const loadRemote = createFederationRuntime({ name: "pokedex_host", remoteEntries: { stable: { name: "stable", entry: "http://127.0.0.1:4174/mf-manifest.json" } }, shared: { react: createSharedSingleton("19.2.5", () => React), "react-dom": createSharedSingleton("19.2.5", () => ReactDOM) } }); async function loadWidgetWithSla() { try { const mod = await withTimeout(loadRemote("stable/Widget"), 800, "stable widget"); return mod; } catch (error) { if (error instanceof FederationTimeoutError) { // Degrade to a local fallback: the remote missed the SLA. return null; } throw error; } } ``` -------------------------------- ### Install mf-shield Source: https://www.npmjs.com/package/mf-shield/v/0.1.0?activeTab=versions Install the mf-shield package using pnpm. This command adds the library to your project's dependencies. ```bash pnpm add mf-shield ``` -------------------------------- ### RemoteSlot with Fallback and Retry Source: https://www.npmjs.com/package/mf-shield?activeTab=dependencies Demonstrates how to use RemoteSlot to load a remote component, with a fallback UI and a retry mechanism triggered by state changes. ```jsx import { useState } from "react"; import { RemoteSlot, type RemoteComponent, type RemoteSlotConfig } from "mf-shield/react"; const widgetSlot: RemoteSlotConfig = { label: "stable widget", timeoutMs: 800, // optional: cuts off slow remotes load: async () => (await loadRemote<{ RemoteWidget: RemoteComponent }>("stable/Widget")).RemoteWidget }; export function WidgetPanel() { const [attempt, setAttempt] = useState(0); return (
); } ``` -------------------------------- ### Generate SRI Hash Source: https://www.npmjs.com/package/mf-shield/v/0.1.0 Use the `openssl` command-line tool to generate the SHA384 hash for a given file, which can then be used with the `createSriPlugin`. ```bash openssl dgst -sha384 -binary remoteEntry.js | openssl base64 -A # => paste as "sha384-" ``` -------------------------------- ### RemoteSlot with Fallback and Retry Source: https://www.npmjs.com/package/mf-shield/v/0.1.0?activeTab=versions Demonstrates how to use RemoteSlot to load a remote component, with a fallback UI and a retry mechanism triggered by state changes. ```jsx import { useState } from "react"; import { RemoteSlot, type RemoteComponent, type RemoteSlotConfig } from "mf-shield/react"; const widgetSlot: RemoteSlotConfig = { label: "stable widget", timeoutMs: 800, // optional: cuts off slow remotes load: async () => (await loadRemote<{ RemoteWidget: RemoteComponent }>( ``` ```jsx stable/Widget")).RemoteWidget }; export function WidgetPanel() { const [attempt, setAttempt] = useState(0); return (
); } ``` -------------------------------- ### RemoteSlot with Fallback and Retry Source: https://www.npmjs.com/package/mf-shield/v/0.1.0 Demonstrates how to use RemoteSlot to mount a remote component, provide a fallback UI, and enable retries by changing a key. The load function asynchronously loads the remote component. ```jsx import { useState } from "react"; import { RemoteSlot, type RemoteComponent, type RemoteSlotConfig } from "mf-shield/react"; const widgetSlot: RemoteSlotConfig = { label: "stable widget", timeoutMs: 800, // optional: cuts off slow remotes load: async () => (await loadRemote<{ RemoteWidget: RemoteComponent }>( ``` ```jsx "stable/Widget"))).RemoteWidget }; export function WidgetPanel() { const [attempt, setAttempt] = useState(0); return (
); } ``` -------------------------------- ### Create Isolated Federation Runtime Source: https://www.npmjs.com/package/mf-shield/v/0.1.0 Use `createInstanceFederationRuntime` to create an independent Module Federation runtime instance, useful for applying different plugin sets without interfering with existing runtimes. ```javascript import { createInstanceFederationRuntime } from "mf-shield/federation"; const loadIsolated = createInstanceFederationRuntime({ name: "widgets_host", remoteEntries, plugins: [accessPlugin, fallbackPlugin] }); ``` -------------------------------- ### Custom Fallback UI for RemoteSlot Source: https://www.npmjs.com/package/mf-shield?activeTab=dependencies Illustrates how to provide a custom fallback UI component to RemoteSlot when a remote component fails to load or render. ```jsx import { RemoteSlot, type RemoteComponent, type RemoteFallbackRenderer, type RemoteSlotConfig } from "mf-shield/react"; const pokedexFallback: RemoteFallbackRenderer = ({ label, error }) => (
This Pokémon fainted

{label} could not be summoned.

{error instanceof Error ? error.message : String(error)}
); const cardsSlot: RemoteSlotConfig = { label: "pokemon cards", timeoutMs: 800, fallback: pokedexFallback, load: async () => (await loadRemote<{ RemoteCards: RemoteComponent }>("stable/Cards")).RemoteCards }; ``` -------------------------------- ### RemoteSlot with Fallback and Retry Source: https://www.npmjs.com/package/mf-shield/v/0.1.0?activeTab=dependents Demonstrates mounting a remote component with a fallback mechanism. Changing the retryKey remounts the slot to attempt a retry. The timeoutMs option can be used to cut off slow remotes. ```typescript import { useState } from "react"; import { RemoteSlot, type RemoteComponent, type RemoteSlotConfig } from "mf-shield/react"; const widgetSlot: RemoteSlotConfig = { label: "stable widget", timeoutMs: 800, // optional: cuts off slow remotes load: async () => (await loadRemote<{ RemoteWidget: RemoteComponent }>( ``` ```typescript stable/Widget")).RemoteWidget }; export function WidgetPanel() { const [attempt, setAttempt] = useState(0); return (
); } ``` -------------------------------- ### Validate shared singletons Source: https://www.npmjs.com/package/mf-shield/v/0.1.0?activeTab=code Detects `shared` config footguns without throwing. Returns readable warnings (`[]` when clean). `createFederationRuntime` runs it automatically and emits `console.warn("[mf-shield] …")` once per runtime creation; you can also run it standalone. ```APIDOC ## Validate shared singletons (`validateSharedSingletons`) ### Description Detects `shared` config footguns without throwing. Returns readable warnings (`[]` when clean). ### Usage ```javascript import { validateSharedSingletons } from "mf-shield"; const warnings = validateSharedSingletons({ shared: { react: { version: "19.2.5", shareConfig: { singleton: true } } }, shareStrategy: "version-first" }); // warnings: missing strictVersion, missing requiredVersion, and 'version-first' + singleton (MF #3209) ``` ### Rules - `singleton: true` without `strictVersion` - `singleton: true` without `requiredVersion` - `shareStrategy: 'version-first'` combined with any singleton (it can load multiple instances of the singleton and eager-loads all remote entries at init). ``` -------------------------------- ### Create Remote Access Plugin Source: https://www.npmjs.com/package/mf-shield/v/0.1.0 Use `createRemoteAccessPlugin` to define a policy for accessing remote modules before they are resolved. It can deny access by throwing `RemoteAccessDeniedError` or allow access. ```javascript import { denyRemoteAccess, allowRemoteAccess } from "mf-shield"; import { createFederationRuntime, createRemoteAccessPlugin } from "mf-shield/federation"; const accessPlugin = createRemoteAccessPlugin({ policy: remoteName => (remoteName === "legacy" ? denyRemoteAccess("legacy remote disabled") : allowRemoteAccess()), onDenied: info => console.warn(`[app] blocked ${info.remote}: ${info.reason}`) }); const loadRemote = createFederationRuntime({ name: "pokedex_host", remoteEntries, plugins: [accessPlugin] }); ``` -------------------------------- ### Create Remote Fallback Plugin Source: https://www.npmjs.com/package/mf-shield/v/0.1.0 Implement `createRemoteFallbackPlugin` to intercept load failures. It allows returning a module object to replace the failed module or `undefined` to propagate the error. ```javascript import { RemoteAccessDeniedError } from "mf-shield"; import { createFederationRuntime, createRemoteFallbackPlugin } from "mf-shield/federation"; import type { RemoteComponent } from "mf-shield/react"; const LocalFallback: RemoteComponent = () =>
Local fallback content
; const fallbackPlugin = createRemoteFallbackPlugin({ fallback: info => { // Defer to an access denial: let the guard win. if (info.error instanceof RemoteAccessDeniedError) return undefined; // Replace a real load failure (lifecycle "onLoad") with a local module. return { RemoteWidget: LocalFallback }; } }); const loadRemote = createFederationRuntime({ name: "pokedex_host", remoteEntries, plugins: [fallbackPlugin] }); ``` -------------------------------- ### RemoteSlot with Fallback and Retry Source: https://www.npmjs.com/package/mf-shield/v/0.1.0?activeTab=code Demonstrates using RemoteSlot to load a remote component with a configurable timeout and a retry mechanism. The slot will display a fallback UI if loading fails. ```jsx import { useState } from "react"; import { RemoteSlot, type RemoteComponent, type RemoteSlotConfig } from "mf-shield/react"; const widgetSlot: RemoteSlotConfig = { label: "stable widget", timeoutMs: 800, // optional: cuts off slow remotes load: async () => (await loadRemote<{ RemoteWidget: RemoteComponent }>( ``` ```jsx import { RemoteSlot, type RemoteComponent, type RemoteFallbackRenderer, type RemoteSlotConfig } from "mf-shield/react"; const pokedexFallback: RemoteFallbackRenderer = ({ label, error }) => (
This Pokémon fainted

{label} could not be summoned.

{error instanceof Error ? error.message : String(error)}
); const cardsSlot: RemoteSlotConfig = { label: "pokemon cards", timeoutMs: 800, fallback: pokedexFallback, load: async () => (await loadRemote<{ RemoteCards: RemoteComponent }>( ``` -------------------------------- ### Typed Remote Props and Failure Observability Source: https://www.npmjs.com/package/mf-shield?activeTab=dependencies Shows how to use RemoteSlotConfig with generic types for remote component props and how to observe status changes and errors. ```javascript const typedSlot: RemoteSlotConfig<{ userId: string }> = { label: "user card", props: { userId: "42" }, // flows into the remote onStatusChange: status => track("slot", status), // "loading" → "ready" | "failed" onError: ({ label, error }) => report(label, error), // deny, reject, timeout, render crash load: async () => (await loadRemote<{ UserCard: RemoteComponent<{ userId: string }> }>("stable/UserCard")).UserCard }; ``` -------------------------------- ### createSriPlugin Source: https://www.npmjs.com/package/mf-shield/v/0.1.0?activeTab=readme Applies Subresource Integrity (SRI) to federated assets, including remoteEntry, chunks, and optionally CSS/preload. It enhances security by ensuring the browser rejects scripts if their bytes do not match the registered hash. ```APIDOC ## createSriPlugin ### Description Applies Subresource Integrity to federated assets (remoteEntry, chunks, and optionally CSS/preload) via MF's official `createScript` / `createLink` hooks. ### Usage ```javascript import { createFederationRuntime, createSriPlugin } from "mf-shield/federation"; const loadRemote = createFederationRuntime({ name: "pokedex_host", remoteEntries: { app: { name: "app", entry: "https://cdn.pokedex.example/app/v1.2.3/mf-manifest.json" } }, plugins: [ createSriPlugin({ // exact asset url -> hash "sha384-..." integrity: { "https://cdn.pokedex.example/app/v1.2.3/remoteEntry.js": "sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8w" }, strict: true, // default: url with no registered hash -> FederationIntegrityError crossOrigin: "anonymous", // default; required for cross-origin SRI onViolation: info => console.warn(`[app] no SRI hash for ${info.url}`) }) ] }); ``` ### Parameters - `integrity` (object | function): A map of `url -> hash` or a function `(url) => hash | undefined` for flexible logic. - `strict` (boolean): If `true` (default), blocks assets without a registered hash with `FederationIntegrityError`. If `false`, allows them through without `integrity`. - `crossOrigin` (string): Specifies the `crossorigin` attribute for script/link elements. Defaults to `anonymous`. - `onViolation` (function): Callback function invoked with information about integrity violations. ### Notes - SRI pins the exact bytes; every remote deploy that changes the bundle must republish the hashes. - It fits versioned/pinned remotes, not mutable `latest` URLs. - If a `