{"version":3,"file":"mf.mjs","names":[],"sources":["../src/mf.ts"],"sourcesContent":["import { createInstance, getInstance } from \"@module-federation/enhanced/runtime\";\nimport { setGlobalFederationInstance } from \"@module-federation/runtime-core\";\nimport { computeSriHash, type IntegrityRegistry } from \"./integrity\";\n\ntype FederationInstance = ReturnType<typeof createInstance>;\n\nlet mfInstance: FederationInstance | null = null;\n\nfunction fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number): Promise<Response> {\n  const controller = new AbortController();\n  const timer = setTimeout(() => controller.abort(), timeoutMs);\n  return fetch(url, { ...init, signal: controller.signal }).finally(() => clearTimeout(timer));\n}\n\nexport function patchManifestFetchForSsrPublicPath(mf: FederationInstance): void {\n  if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) return;\n  if ((mf as any).__everythingDevPatchedManifestFetch === true) return;\n  (mf as any).__everythingDevPatchedManifestFetch = true;\n\n  (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n    if (typeof url !== \"string\" || !url.endsWith(\"/mf-manifest.json\")) {\n      return;\n    }\n    return fetchWithTimeout(url as string, init as RequestInit, 15_000)\n      .then((res) => res.json())\n      .then((json: any) => {\n        json.metaData = json.metaData ?? {};\n        json.metaData.ssrPublicPath =\n          json.metaData.ssrPublicPath ?? url.replace(/\\/mf-manifest\\.json$/, \"/\");\n        if (json.metaData.publicPath === \"auto\" || json.metaData.publicPath === \"\") {\n          json.metaData.publicPath = \"/\";\n        }\n        return new Response(JSON.stringify(json), {\n          headers: { \"content-type\": \"application/json\" },\n        });\n      });\n  });\n}\n\nexport function installIntegrityFetchHook(\n  mf: FederationInstance,\n  registry: IntegrityRegistry,\n): void {\n  if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) {\n    console.warn(\"[SRI] MF lifecycle fetch hook not available, skipping integrity-in-pipeline\");\n    return;\n  }\n  if ((mf as any).__everythingDevIntegrityHook === true) return;\n  (mf as any).__everythingDevIntegrityHook = true;\n\n  (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n    if (typeof url !== \"string\") return;\n\n    const expectedHash = registry.get(url);\n    if (!expectedHash) return;\n\n    return fetchWithTimeout(url as string, init as RequestInit, 15_000).then(async (res) => {\n      const buffer = Buffer.from(await res.arrayBuffer());\n      const computed = computeSriHash(buffer);\n\n      if (computed !== expectedHash) {\n        console.error(\n          `[SRI] Integrity check failed in MF fetch pipeline for ${url}\\n  Expected: ${expectedHash}\\n  Computed: ${computed}`,\n        );\n        return new Response(`Integrity check failed for ${url}`, {\n          status: 500,\n          statusText: \"Integrity Check Failed\",\n        });\n      }\n\n      console.log(`[SRI] Integrity verified in pipeline for ${url}`);\n      return new Response(buffer, {\n        status: res.status,\n        statusText: res.statusText,\n        headers: res.headers,\n      });\n    });\n  });\n}\n\nexport function getFederationInstance(): FederationInstance {\n  if (mfInstance) return mfInstance;\n\n  const existing = getInstance();\n  if (existing) {\n    mfInstance = existing as FederationInstance;\n    setGlobalFederationInstance(mfInstance as any);\n    patchManifestFetchForSsrPublicPath(mfInstance);\n    return mfInstance;\n  }\n\n  mfInstance = createInstance({\n    name: \"host\",\n    remotes: [],\n  }) as FederationInstance;\n  setGlobalFederationInstance(mfInstance as any);\n  patchManifestFetchForSsrPublicPath(mfInstance);\n  return mfInstance;\n}\n\nexport async function registerRemote(opts: {\n  name: string;\n  entry: string;\n  type?: \"manifest\" | \"script\";\n}): Promise<void> {\n  const instance = getFederationInstance();\n\n  const inferType = (): \"manifest\" | \"script\" => {\n    if (opts.type) return opts.type;\n    if (opts.entry.endsWith(\"/mf-manifest.json\")) return \"manifest\";\n    if (opts.entry.endsWith(\"/remoteEntry.js\")) return \"script\";\n    return typeof window === \"undefined\" ? \"script\" : \"manifest\";\n  };\n\n  const remoteType = inferType();\n\n  instance.registerRemotes([\n    {\n      name: opts.name,\n      entry: opts.entry,\n      type: remoteType,\n    },\n  ]);\n}\n\nexport async function loadRemoteModule<T>(\n  specifier: string,\n  options?: { loadFactory?: boolean; from?: \"build\" | \"runtime\" },\n): Promise<T> {\n  const instance = getFederationInstance();\n\n  const isServer = typeof window === \"undefined\";\n  if (isServer) {\n    await (instance as any).initializeSharing?.(\"default\");\n  }\n\n  const mod = await instance.loadRemote<T>(specifier, options as any);\n  if (!mod) {\n    throw new Error(`Failed to load remote module: ${specifier}`);\n  }\n  return mod;\n}\n\nexport async function ensureNodeRuntimePlugin(): Promise<void> {\n  const instance = getFederationInstance();\n  if (typeof window !== \"undefined\") return;\n  if ((instance as any).__nodeRuntimePluginLoaded) return;\n\n  const mod: any = await import(\"@module-federation/node/runtimePlugin\");\n  const factory = mod?.default ?? mod;\n  const plugin = typeof factory === \"function\" ? factory() : null;\n  if (plugin) {\n    instance.registerPlugins([plugin]);\n  }\n  (instance as any).__nodeRuntimePluginLoaded = true;\n}\n"],"mappings":"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"}