@module-federation/runtime-core
Advanced tools
+8
-1
@@ -33,3 +33,3 @@ const require_logger = require('./utils/logger.cjs'); | ||
| }); | ||
| this.version = "2.4.0"; | ||
| this.version = "2.5.0"; | ||
| this.moduleCache = /* @__PURE__ */ new Map(); | ||
@@ -42,2 +42,9 @@ this.loaderHook = new require_pluginSystem.PluginSystem({ | ||
| loadEntryError: new require_asyncHook.AsyncHook(), | ||
| afterLoadEntry: new require_asyncHook.AsyncHook("afterLoadEntry"), | ||
| beforeInitRemote: new require_asyncHook.AsyncHook("beforeInitRemote"), | ||
| afterInitRemote: new require_asyncHook.AsyncHook("afterInitRemote"), | ||
| beforeGetExpose: new require_asyncHook.AsyncHook("beforeGetExpose"), | ||
| afterGetExpose: new require_asyncHook.AsyncHook("afterGetExpose"), | ||
| beforeExecuteFactory: new require_asyncHook.AsyncHook("beforeExecuteFactory"), | ||
| afterExecuteFactory: new require_asyncHook.AsyncHook("afterExecuteFactory"), | ||
| getModuleFactory: new require_asyncHook.AsyncHook() | ||
@@ -44,0 +51,0 @@ }); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"core.cjs","names":["PluginSystem","SyncWaterfallHook","SyncHook","AsyncWaterfallHook","AsyncHook","snapshotPlugin","generatePreloadAssetsPlugin","getBuilderId","isBrowserEnvValue","SnapshotHandler","SharedHandler","RemoteHandler","RUNTIME_010","runtimeDescMap","DEFAULT_SCOPE","getRemoteInfo","Module","formatShareConfigs","registerPlugins"],"sources":["../src/core.ts"],"sourcesContent":["import { isBrowserEnvValue } from '@module-federation/sdk';\nimport type {\n CreateScriptHookReturn,\n GlobalModuleInfo,\n ModuleInfo,\n} from '@module-federation/sdk';\nimport {\n Options,\n PreloadRemoteArgs,\n RemoteEntryExports,\n Remote,\n Shared,\n ShareInfos,\n UserOptions,\n RemoteInfo,\n ShareScopeMap,\n InitScope,\n RemoteEntryInitOptions,\n CallFrom,\n} from './type';\nimport { getBuilderId, registerPlugins, getRemoteEntry, error } from './utils';\nimport {\n getShortErrorMsg,\n RUNTIME_010,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Module } from './module';\nimport {\n AsyncHook,\n AsyncWaterfallHook,\n PluginSystem,\n SyncHook,\n SyncWaterfallHook,\n} from './utils/hooks';\nimport { generatePreloadAssetsPlugin } from './plugins/generate-preload-assets';\nimport { snapshotPlugin } from './plugins/snapshot';\nimport { getRemoteInfo } from './utils/load';\nimport { DEFAULT_SCOPE } from './constant';\nimport { SnapshotHandler } from './plugins/snapshot/SnapshotHandler';\nimport { SharedHandler } from './shared';\nimport { RemoteHandler } from './remote';\nimport { formatShareConfigs } from './utils/share';\n\n// Declare the global constant that will be defined by DefinePlugin\n// Default to true if not defined (e.g., when runtime-core is used outside of webpack)\n// so that snapshot functionality is included by default.\ndeclare const FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: boolean;\nconst USE_SNAPSHOT =\n typeof FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'boolean'\n ? !FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN\n : true; // Default to true (use snapshot) when not explicitly defined\n\nexport class ModuleFederation {\n options: Options;\n hooks = new PluginSystem({\n beforeInit: new SyncWaterfallHook<{\n userOptions: UserOptions;\n options: Options;\n origin: ModuleFederation;\n /**\n * @deprecated shareInfo will be removed soon, please use userOptions directly!\n */\n shareInfo: ShareInfos;\n }>('beforeInit'),\n init: new SyncHook<\n [\n {\n options: Options;\n origin: ModuleFederation;\n },\n ],\n void\n >(),\n // maybe will change, temporarily for internal use only\n beforeInitContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n origin: ModuleFederation;\n }>('beforeInitContainer'),\n // maybe will change, temporarily for internal use only\n initContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n remoteEntryExports: RemoteEntryExports;\n origin: ModuleFederation;\n id?: string;\n remoteSnapshot?: ModuleInfo;\n }>('initContainer'),\n });\n version: string = __VERSION__;\n name: string;\n moduleCache: Map<string, Module> = new Map();\n snapshotHandler: SnapshotHandler;\n sharedHandler: SharedHandler;\n remoteHandler: RemoteHandler;\n shareScopeMap: ShareScopeMap;\n loaderHook = new PluginSystem({\n // FIXME: may not be suitable , not open to the public yet\n getModuleInfo: new SyncHook<\n [\n {\n target: Record<string, any>;\n key: any;\n },\n ],\n { value: any | undefined; key: string } | void\n >(),\n createScript: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n /**\n * The producer(remote) info bound to this resource.\n * Only present when the loader is invoked in a remote-related context\n * (e.g. preloadRemote / loading remoteEntry).\n */\n remoteInfo?: RemoteInfo;\n },\n ],\n CreateScriptHookReturn\n >(),\n createLink: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n /**\n * The producer(remote) info bound to this resource.\n * Only present when the loader is invoked in a remote-related context\n * (e.g. preloadRemote / loading remoteEntry).\n */\n remoteInfo?: RemoteInfo;\n },\n ],\n HTMLLinkElement | void\n >(),\n fetch: new AsyncHook<\n [string, RequestInit, RemoteInfo?],\n Promise<Response> | void | false\n >(),\n loadEntryError: new AsyncHook<\n [\n {\n getRemoteEntry: typeof getRemoteEntry;\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n globalLoading: Record<\n string,\n Promise<void | RemoteEntryExports> | undefined\n >;\n uniqueKey: string;\n },\n ],\n Promise<Promise<RemoteEntryExports | undefined> | undefined>\n >(),\n getModuleFactory: new AsyncHook<\n [\n {\n remoteEntryExports: RemoteEntryExports;\n expose: string;\n moduleInfo: RemoteInfo;\n },\n ],\n Promise<(() => Promise<Module>) | undefined>\n >(),\n });\n bridgeHook = new PluginSystem({\n beforeBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n beforeBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n });\n moduleInfo?: GlobalModuleInfo[string];\n\n constructor(userOptions: UserOptions) {\n const plugins = USE_SNAPSHOT\n ? [snapshotPlugin(), generatePreloadAssetsPlugin()]\n : [];\n // TODO: Validate the details of the options\n // Initialize options with default values\n const defaultOptions: Options = {\n id: getBuilderId(),\n name: userOptions.name,\n plugins,\n remotes: [],\n shared: {},\n inBrowser: isBrowserEnvValue,\n };\n\n this.name = userOptions.name;\n this.options = defaultOptions;\n this.snapshotHandler = new SnapshotHandler(this);\n this.sharedHandler = new SharedHandler(this);\n this.remoteHandler = new RemoteHandler(this);\n this.shareScopeMap = this.sharedHandler.shareScopeMap;\n this.registerPlugins([\n ...defaultOptions.plugins,\n ...(userOptions.plugins || []),\n ]);\n this.options = this.formatOptions(defaultOptions, userOptions);\n }\n\n initOptions(userOptions: UserOptions): Options {\n if (userOptions.name && userOptions.name !== this.options.name) {\n error(getShortErrorMsg(RUNTIME_010, runtimeDescMap));\n }\n this.registerPlugins(userOptions.plugins);\n const options = this.formatOptions(this.options, userOptions);\n\n this.options = options;\n\n return options;\n }\n\n async loadShare<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): Promise<false | (() => T | undefined)> {\n return this.sharedHandler.loadShare(pkgName, extraOptions);\n }\n\n // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.\n // 1. If the loaded shared already exists globally, then it will be reused\n // 2. If lib exists in local shared, it will be used directly\n // 3. If the local get returns something other than Promise, then it will be used directly\n loadShareSync<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n from?: 'build' | 'runtime';\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): () => T | never {\n return this.sharedHandler.loadShareSync(pkgName, extraOptions);\n }\n\n initializeSharing(\n shareScopeName = DEFAULT_SCOPE,\n extraOptions?: {\n initScope?: InitScope;\n from?: CallFrom;\n strategy?: Shared['strategy'];\n },\n ): Array<Promise<void>> {\n return this.sharedHandler.initializeSharing(shareScopeName, extraOptions);\n }\n\n initRawContainer(\n name: string,\n url: string,\n container: RemoteEntryExports,\n ): Module {\n const remoteInfo = getRemoteInfo({ name, entry: url });\n const module = new Module({ host: this, remoteInfo });\n\n module.remoteEntryExports = container;\n this.moduleCache.set(name, module);\n\n return module;\n }\n\n // eslint-disable-next-line max-lines-per-function\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async loadRemote<T>(\n id: string,\n options?: { loadFactory?: boolean; from: CallFrom },\n ): Promise<T | null> {\n return this.remoteHandler.loadRemote(id, options);\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void> {\n return this.remoteHandler.preloadRemote(preloadOptions);\n }\n\n initShareScopeMap(\n scopeName: string,\n shareScope: ShareScopeMap[string],\n extraOptions: { hostShareScopeMap?: ShareScopeMap } = {},\n ): void {\n this.sharedHandler.initShareScopeMap(scopeName, shareScope, extraOptions);\n }\n\n formatOptions(globalOptions: Options, userOptions: UserOptions): Options {\n const { allShareInfos: shared } = formatShareConfigs(\n globalOptions,\n userOptions,\n );\n const { userOptions: userOptionsRes, options: globalOptionsRes } =\n this.hooks.lifecycle.beforeInit.emit({\n origin: this,\n userOptions,\n options: globalOptions,\n shareInfo: shared,\n });\n\n const remotes = this.remoteHandler.formatAndRegisterRemote(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const { allShareInfos } = this.sharedHandler.registerShared(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const plugins = [...globalOptionsRes.plugins];\n\n if (userOptionsRes.plugins) {\n userOptionsRes.plugins.forEach((plugin) => {\n if (!plugins.includes(plugin)) {\n plugins.push(plugin);\n }\n });\n }\n\n const optionsRes: Options = {\n ...globalOptions,\n ...userOptions,\n plugins,\n remotes,\n shared: allShareInfos,\n id: userOptionsRes.id || globalOptions.id,\n };\n\n this.hooks.lifecycle.init.emit({\n origin: this,\n options: optionsRes,\n });\n return optionsRes;\n }\n\n registerPlugins(plugins: UserOptions['plugins']) {\n const pluginRes = registerPlugins(plugins, this);\n // Merge plugin\n this.options.plugins = this.options.plugins.reduce((res, plugin) => {\n if (!plugin) return res;\n if (res && !res.find((item) => item.name === plugin.name)) {\n res.push(plugin);\n }\n return res;\n }, pluginRes || []);\n }\n registerRemotes(remotes: Remote[], options?: { force?: boolean }): void {\n return this.remoteHandler.registerRemotes(remotes, options);\n }\n\n registerShared(shared: UserOptions['shared']) {\n this.sharedHandler.registerShared(this.options, {\n ...this.options,\n shared,\n });\n }\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"core.cjs","names":["PluginSystem","SyncWaterfallHook","SyncHook","AsyncWaterfallHook","AsyncHook","snapshotPlugin","generatePreloadAssetsPlugin","getBuilderId","isBrowserEnvValue","SnapshotHandler","SharedHandler","RemoteHandler","RUNTIME_010","runtimeDescMap","DEFAULT_SCOPE","getRemoteInfo","Module","formatShareConfigs","registerPlugins"],"sources":["../src/core.ts"],"sourcesContent":["import { isBrowserEnvValue } from '@module-federation/sdk';\nimport type {\n CreateLinkHookReturnDom,\n CreateScriptHookReturn,\n GlobalModuleInfo,\n ModuleInfo,\n} from '@module-federation/sdk';\nimport {\n Options,\n PreloadRemoteArgs,\n RemoteEntryExports,\n Remote,\n Shared,\n ShareInfos,\n UserOptions,\n RemoteInfo,\n ShareScopeMap,\n InitScope,\n RemoteEntryInitOptions,\n CallFrom,\n ResourceLoadContext,\n} from './type';\nimport { getBuilderId, registerPlugins, getRemoteEntry, error } from './utils';\nimport {\n getShortErrorMsg,\n RUNTIME_010,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Module, type RemoteModuleFactory } from './module';\nimport {\n AsyncHook,\n AsyncWaterfallHook,\n PluginSystem,\n SyncHook,\n SyncWaterfallHook,\n} from './utils/hooks';\nimport { generatePreloadAssetsPlugin } from './plugins/generate-preload-assets';\nimport { snapshotPlugin } from './plugins/snapshot';\nimport { getRemoteInfo } from './utils/load';\nimport { DEFAULT_SCOPE } from './constant';\nimport { SnapshotHandler } from './plugins/snapshot/SnapshotHandler';\nimport { SharedHandler } from './shared';\nimport { RemoteHandler } from './remote';\nimport { formatShareConfigs } from './utils/share';\n\n// Declare the global constant that will be defined by DefinePlugin\n// Default to true if not defined (e.g., when runtime-core is used outside of webpack)\n// so that snapshot functionality is included by default.\ndeclare const FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: boolean;\nconst USE_SNAPSHOT =\n typeof FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'boolean'\n ? !FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN\n : true; // Default to true (use snapshot) when not explicitly defined\n\nexport class ModuleFederation {\n options: Options;\n hooks = new PluginSystem({\n beforeInit: new SyncWaterfallHook<{\n userOptions: UserOptions;\n options: Options;\n origin: ModuleFederation;\n /**\n * @deprecated shareInfo will be removed soon, please use userOptions directly!\n */\n shareInfo: ShareInfos;\n }>('beforeInit'),\n init: new SyncHook<\n [\n {\n options: Options;\n origin: ModuleFederation;\n },\n ],\n void\n >(),\n // maybe will change, temporarily for internal use only\n beforeInitContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n origin: ModuleFederation;\n }>('beforeInitContainer'),\n // maybe will change, temporarily for internal use only\n initContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n remoteEntryExports: RemoteEntryExports;\n origin: ModuleFederation;\n id?: string;\n remoteSnapshot?: ModuleInfo;\n }>('initContainer'),\n });\n version: string = __VERSION__;\n name: string;\n moduleCache: Map<string, Module> = new Map();\n snapshotHandler: SnapshotHandler;\n sharedHandler: SharedHandler;\n remoteHandler: RemoteHandler;\n shareScopeMap: ShareScopeMap;\n loaderHook = new PluginSystem({\n // FIXME: may not be suitable , not open to the public yet\n getModuleInfo: new SyncHook<\n [\n {\n target: Record<string, any>;\n key: any;\n },\n ],\n { value: any | undefined; key: string } | void\n >(),\n createScript: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n /**\n * The producer(remote) info bound to this resource.\n * Only present when the loader is invoked in a remote-related context\n * (e.g. preloadRemote / loading remoteEntry).\n */\n remoteInfo?: RemoteInfo;\n resourceContext?: ResourceLoadContext;\n },\n ],\n CreateScriptHookReturn\n >(),\n createLink: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n /**\n * The producer(remote) info bound to this resource.\n * Only present when the loader is invoked in a remote-related context\n * (e.g. preloadRemote / loading remoteEntry).\n */\n remoteInfo?: RemoteInfo;\n resourceContext?: ResourceLoadContext;\n },\n ],\n CreateLinkHookReturnDom\n >(),\n fetch: new AsyncHook<\n [string, RequestInit, RemoteInfo?, ResourceLoadContext?],\n Promise<Response> | void | false\n >(),\n loadEntryError: new AsyncHook<\n [\n {\n getRemoteEntry: typeof getRemoteEntry;\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n globalLoading: Record<\n string,\n Promise<void | RemoteEntryExports> | undefined\n >;\n uniqueKey: string;\n },\n ],\n Promise<Promise<RemoteEntryExports | undefined> | undefined>\n >(),\n afterLoadEntry: new AsyncHook<\n [\n {\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | false | void;\n error?: unknown;\n recovered?: boolean;\n },\n ],\n void\n >('afterLoadEntry'),\n beforeInitRemote: new AsyncHook<\n [\n {\n id?: string;\n remoteInfo: RemoteInfo;\n remoteSnapshot?: ModuleInfo;\n origin: ModuleFederation;\n },\n ],\n void\n >('beforeInitRemote'),\n afterInitRemote: new AsyncHook<\n [\n {\n id?: string;\n remoteInfo: RemoteInfo;\n remoteSnapshot?: ModuleInfo;\n remoteEntryExports?: RemoteEntryExports;\n error?: unknown;\n cached?: boolean;\n origin: ModuleFederation;\n },\n ],\n void\n >('afterInitRemote'),\n beforeGetExpose: new AsyncHook<\n [\n {\n id: string;\n expose: string;\n moduleInfo: RemoteInfo;\n remoteEntryExports: RemoteEntryExports;\n origin: ModuleFederation;\n },\n ],\n void\n >('beforeGetExpose'),\n afterGetExpose: new AsyncHook<\n [\n {\n id: string;\n expose: string;\n moduleInfo: RemoteInfo;\n remoteEntryExports: RemoteEntryExports;\n moduleFactory?: RemoteModuleFactory;\n error?: unknown;\n origin: ModuleFederation;\n },\n ],\n void\n >('afterGetExpose'),\n beforeExecuteFactory: new AsyncHook<\n [\n {\n id: string;\n expose: string;\n moduleInfo: RemoteInfo;\n loadFactory: boolean;\n origin: ModuleFederation;\n },\n ],\n void\n >('beforeExecuteFactory'),\n afterExecuteFactory: new AsyncHook<\n [\n {\n id: string;\n expose: string;\n moduleInfo: RemoteInfo;\n loadFactory: boolean;\n exposeModule?: unknown;\n error?: unknown;\n origin: ModuleFederation;\n },\n ],\n void\n >('afterExecuteFactory'),\n getModuleFactory: new AsyncHook<\n [\n {\n remoteEntryExports: RemoteEntryExports;\n expose: string;\n moduleInfo: RemoteInfo;\n },\n ],\n RemoteModuleFactory | Promise<RemoteModuleFactory | undefined> | undefined\n >(),\n });\n bridgeHook = new PluginSystem({\n beforeBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n beforeBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n });\n moduleInfo?: GlobalModuleInfo[string];\n\n constructor(userOptions: UserOptions) {\n const plugins = USE_SNAPSHOT\n ? [snapshotPlugin(), generatePreloadAssetsPlugin()]\n : [];\n // TODO: Validate the details of the options\n // Initialize options with default values\n const defaultOptions: Options = {\n id: getBuilderId(),\n name: userOptions.name,\n plugins,\n remotes: [],\n shared: {},\n inBrowser: isBrowserEnvValue,\n };\n\n this.name = userOptions.name;\n this.options = defaultOptions;\n this.snapshotHandler = new SnapshotHandler(this);\n this.sharedHandler = new SharedHandler(this);\n this.remoteHandler = new RemoteHandler(this);\n this.shareScopeMap = this.sharedHandler.shareScopeMap;\n this.registerPlugins([\n ...defaultOptions.plugins,\n ...(userOptions.plugins || []),\n ]);\n this.options = this.formatOptions(defaultOptions, userOptions);\n }\n\n initOptions(userOptions: UserOptions): Options {\n if (userOptions.name && userOptions.name !== this.options.name) {\n error(getShortErrorMsg(RUNTIME_010, runtimeDescMap));\n }\n this.registerPlugins(userOptions.plugins);\n const options = this.formatOptions(this.options, userOptions);\n\n this.options = options;\n\n return options;\n }\n\n async loadShare<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): Promise<false | (() => T | undefined)> {\n return this.sharedHandler.loadShare(pkgName, extraOptions);\n }\n\n // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.\n // 1. If the loaded shared already exists globally, then it will be reused\n // 2. If lib exists in local shared, it will be used directly\n // 3. If the local get returns something other than Promise, then it will be used directly\n loadShareSync<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n from?: 'build' | 'runtime';\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): () => T | never {\n return this.sharedHandler.loadShareSync(pkgName, extraOptions);\n }\n\n initializeSharing(\n shareScopeName = DEFAULT_SCOPE,\n extraOptions?: {\n initScope?: InitScope;\n from?: CallFrom;\n strategy?: Shared['strategy'];\n },\n ): Array<Promise<void>> {\n return this.sharedHandler.initializeSharing(shareScopeName, extraOptions);\n }\n\n initRawContainer(\n name: string,\n url: string,\n container: RemoteEntryExports,\n ): Module {\n const remoteInfo = getRemoteInfo({ name, entry: url });\n const module = new Module({ host: this, remoteInfo });\n\n module.remoteEntryExports = container;\n this.moduleCache.set(name, module);\n\n return module;\n }\n\n // eslint-disable-next-line max-lines-per-function\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async loadRemote<T>(\n id: string,\n options?: { loadFactory?: boolean; from: CallFrom },\n ): Promise<T | null> {\n return this.remoteHandler.loadRemote(id, options);\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void> {\n return this.remoteHandler.preloadRemote(preloadOptions);\n }\n\n initShareScopeMap(\n scopeName: string,\n shareScope: ShareScopeMap[string],\n extraOptions: { hostShareScopeMap?: ShareScopeMap } = {},\n ): void {\n this.sharedHandler.initShareScopeMap(scopeName, shareScope, extraOptions);\n }\n\n formatOptions(globalOptions: Options, userOptions: UserOptions): Options {\n const { allShareInfos: shared } = formatShareConfigs(\n globalOptions,\n userOptions,\n );\n const { userOptions: userOptionsRes, options: globalOptionsRes } =\n this.hooks.lifecycle.beforeInit.emit({\n origin: this,\n userOptions,\n options: globalOptions,\n shareInfo: shared,\n });\n\n const remotes = this.remoteHandler.formatAndRegisterRemote(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const { allShareInfos } = this.sharedHandler.registerShared(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const plugins = [...globalOptionsRes.plugins];\n\n if (userOptionsRes.plugins) {\n userOptionsRes.plugins.forEach((plugin) => {\n if (!plugins.includes(plugin)) {\n plugins.push(plugin);\n }\n });\n }\n\n const optionsRes: Options = {\n ...globalOptions,\n ...userOptions,\n plugins,\n remotes,\n shared: allShareInfos,\n id: userOptionsRes.id || globalOptions.id,\n };\n\n this.hooks.lifecycle.init.emit({\n origin: this,\n options: optionsRes,\n });\n return optionsRes;\n }\n\n registerPlugins(plugins: UserOptions['plugins']) {\n const pluginRes = registerPlugins(plugins, this);\n // Merge plugin\n this.options.plugins = this.options.plugins.reduce((res, plugin) => {\n if (!plugin) return res;\n if (res && !res.find((item) => item.name === plugin.name)) {\n res.push(plugin);\n }\n return res;\n }, pluginRes || []);\n }\n registerRemotes(remotes: Remote[], options?: { force?: boolean }): void {\n return this.remoteHandler.registerRemotes(remotes, options);\n }\n\n registerShared(shared: UserOptions['shared']) {\n this.sharedHandler.registerShared(this.options, {\n ...this.options,\n shared,\n });\n }\n}\n"],"mappings":"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"} |
+62
-6
@@ -1,2 +0,2 @@ | ||
| import { Module as Module$1 } from "./module/index.js"; | ||
| import { Module as Module$1, RemoteModuleFactory } from "./module/index.js"; | ||
| import { SyncHook } from "./utils/hooks/syncHook.js"; | ||
@@ -11,5 +11,5 @@ import { AsyncHook } from "./utils/hooks/asyncHook.js"; | ||
| import { CallFrom, InitScope, Options, Remote, RemoteEntryExports, RemoteEntryInitOptions, RemoteInfo, ShareInfos, ShareScopeMap, Shared, UserOptions } from "./type/config.js"; | ||
| import { PreloadRemoteArgs } from "./type/preload.js"; | ||
| import { PreloadRemoteArgs, ResourceLoadContext } from "./type/preload.js"; | ||
| import { getRemoteEntry } from "./utils/load.js"; | ||
| import { CreateScriptHookReturn, GlobalModuleInfo, ModuleInfo } from "@module-federation/sdk"; | ||
| import { CreateLinkHookReturnDom, CreateScriptHookReturn, GlobalModuleInfo, ModuleInfo } from "@module-federation/sdk"; | ||
@@ -75,2 +75,3 @@ //#region src/core.d.ts | ||
| remoteInfo?: RemoteInfo; | ||
| resourceContext?: ResourceLoadContext; | ||
| }], CreateScriptHookReturn>; | ||
@@ -86,4 +87,5 @@ createLink: SyncHook<[{ | ||
| remoteInfo?: RemoteInfo; | ||
| }], void | HTMLLinkElement>; | ||
| fetch: AsyncHook<[string, RequestInit, (RemoteInfo | undefined)?], false | void | Promise<Response>>; | ||
| resourceContext?: ResourceLoadContext; | ||
| }], CreateLinkHookReturnDom>; | ||
| fetch: AsyncHook<[string, RequestInit, (RemoteInfo | undefined)?, (ResourceLoadContext | undefined)?], false | void | Promise<Response>>; | ||
| loadEntryError: AsyncHook<[{ | ||
@@ -97,2 +99,56 @@ getRemoteEntry: typeof getRemoteEntry; | ||
| }], Promise<Promise<RemoteEntryExports | undefined> | undefined>>; | ||
| afterLoadEntry: AsyncHook<[{ | ||
| origin: ModuleFederation; | ||
| remoteInfo: RemoteInfo; | ||
| remoteEntryExports?: false | void | RemoteEntryExports | undefined; | ||
| error?: unknown; | ||
| recovered?: boolean; | ||
| }], void>; | ||
| beforeInitRemote: AsyncHook<[{ | ||
| id?: string; | ||
| remoteInfo: RemoteInfo; | ||
| remoteSnapshot?: ModuleInfo; | ||
| origin: ModuleFederation; | ||
| }], void>; | ||
| afterInitRemote: AsyncHook<[{ | ||
| id?: string; | ||
| remoteInfo: RemoteInfo; | ||
| remoteSnapshot?: ModuleInfo; | ||
| remoteEntryExports?: RemoteEntryExports; | ||
| error?: unknown; | ||
| cached?: boolean; | ||
| origin: ModuleFederation; | ||
| }], void>; | ||
| beforeGetExpose: AsyncHook<[{ | ||
| id: string; | ||
| expose: string; | ||
| moduleInfo: RemoteInfo; | ||
| remoteEntryExports: RemoteEntryExports; | ||
| origin: ModuleFederation; | ||
| }], void>; | ||
| afterGetExpose: AsyncHook<[{ | ||
| id: string; | ||
| expose: string; | ||
| moduleInfo: RemoteInfo; | ||
| remoteEntryExports: RemoteEntryExports; | ||
| moduleFactory?: RemoteModuleFactory; | ||
| error?: unknown; | ||
| origin: ModuleFederation; | ||
| }], void>; | ||
| beforeExecuteFactory: AsyncHook<[{ | ||
| id: string; | ||
| expose: string; | ||
| moduleInfo: RemoteInfo; | ||
| loadFactory: boolean; | ||
| origin: ModuleFederation; | ||
| }], void>; | ||
| afterExecuteFactory: AsyncHook<[{ | ||
| id: string; | ||
| expose: string; | ||
| moduleInfo: RemoteInfo; | ||
| loadFactory: boolean; | ||
| exposeModule?: unknown; | ||
| error?: unknown; | ||
| origin: ModuleFederation; | ||
| }], void>; | ||
| getModuleFactory: AsyncHook<[{ | ||
@@ -102,3 +158,3 @@ remoteEntryExports: RemoteEntryExports; | ||
| moduleInfo: RemoteInfo; | ||
| }], Promise<(() => Promise<Module$1>) | undefined>>; | ||
| }], RemoteModuleFactory | Promise<RemoteModuleFactory | undefined> | undefined>; | ||
| }>; | ||
@@ -105,0 +161,0 @@ bridgeHook: PluginSystem<{ |
+8
-1
@@ -33,3 +33,3 @@ import { error } from "./utils/logger.js"; | ||
| }); | ||
| this.version = "2.4.0"; | ||
| this.version = "2.5.0"; | ||
| this.moduleCache = /* @__PURE__ */ new Map(); | ||
@@ -42,2 +42,9 @@ this.loaderHook = new PluginSystem({ | ||
| loadEntryError: new AsyncHook(), | ||
| afterLoadEntry: new AsyncHook("afterLoadEntry"), | ||
| beforeInitRemote: new AsyncHook("beforeInitRemote"), | ||
| afterInitRemote: new AsyncHook("afterInitRemote"), | ||
| beforeGetExpose: new AsyncHook("beforeGetExpose"), | ||
| afterGetExpose: new AsyncHook("afterGetExpose"), | ||
| beforeExecuteFactory: new AsyncHook("beforeExecuteFactory"), | ||
| afterExecuteFactory: new AsyncHook("afterExecuteFactory"), | ||
| getModuleFactory: new AsyncHook() | ||
@@ -44,0 +51,0 @@ }); |
+1
-1
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"core.js","names":["Module"],"sources":["../src/core.ts"],"sourcesContent":["import { isBrowserEnvValue } from '@module-federation/sdk';\nimport type {\n CreateScriptHookReturn,\n GlobalModuleInfo,\n ModuleInfo,\n} from '@module-federation/sdk';\nimport {\n Options,\n PreloadRemoteArgs,\n RemoteEntryExports,\n Remote,\n Shared,\n ShareInfos,\n UserOptions,\n RemoteInfo,\n ShareScopeMap,\n InitScope,\n RemoteEntryInitOptions,\n CallFrom,\n} from './type';\nimport { getBuilderId, registerPlugins, getRemoteEntry, error } from './utils';\nimport {\n getShortErrorMsg,\n RUNTIME_010,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Module } from './module';\nimport {\n AsyncHook,\n AsyncWaterfallHook,\n PluginSystem,\n SyncHook,\n SyncWaterfallHook,\n} from './utils/hooks';\nimport { generatePreloadAssetsPlugin } from './plugins/generate-preload-assets';\nimport { snapshotPlugin } from './plugins/snapshot';\nimport { getRemoteInfo } from './utils/load';\nimport { DEFAULT_SCOPE } from './constant';\nimport { SnapshotHandler } from './plugins/snapshot/SnapshotHandler';\nimport { SharedHandler } from './shared';\nimport { RemoteHandler } from './remote';\nimport { formatShareConfigs } from './utils/share';\n\n// Declare the global constant that will be defined by DefinePlugin\n// Default to true if not defined (e.g., when runtime-core is used outside of webpack)\n// so that snapshot functionality is included by default.\ndeclare const FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: boolean;\nconst USE_SNAPSHOT =\n typeof FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'boolean'\n ? !FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN\n : true; // Default to true (use snapshot) when not explicitly defined\n\nexport class ModuleFederation {\n options: Options;\n hooks = new PluginSystem({\n beforeInit: new SyncWaterfallHook<{\n userOptions: UserOptions;\n options: Options;\n origin: ModuleFederation;\n /**\n * @deprecated shareInfo will be removed soon, please use userOptions directly!\n */\n shareInfo: ShareInfos;\n }>('beforeInit'),\n init: new SyncHook<\n [\n {\n options: Options;\n origin: ModuleFederation;\n },\n ],\n void\n >(),\n // maybe will change, temporarily for internal use only\n beforeInitContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n origin: ModuleFederation;\n }>('beforeInitContainer'),\n // maybe will change, temporarily for internal use only\n initContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n remoteEntryExports: RemoteEntryExports;\n origin: ModuleFederation;\n id?: string;\n remoteSnapshot?: ModuleInfo;\n }>('initContainer'),\n });\n version: string = __VERSION__;\n name: string;\n moduleCache: Map<string, Module> = new Map();\n snapshotHandler: SnapshotHandler;\n sharedHandler: SharedHandler;\n remoteHandler: RemoteHandler;\n shareScopeMap: ShareScopeMap;\n loaderHook = new PluginSystem({\n // FIXME: may not be suitable , not open to the public yet\n getModuleInfo: new SyncHook<\n [\n {\n target: Record<string, any>;\n key: any;\n },\n ],\n { value: any | undefined; key: string } | void\n >(),\n createScript: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n /**\n * The producer(remote) info bound to this resource.\n * Only present when the loader is invoked in a remote-related context\n * (e.g. preloadRemote / loading remoteEntry).\n */\n remoteInfo?: RemoteInfo;\n },\n ],\n CreateScriptHookReturn\n >(),\n createLink: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n /**\n * The producer(remote) info bound to this resource.\n * Only present when the loader is invoked in a remote-related context\n * (e.g. preloadRemote / loading remoteEntry).\n */\n remoteInfo?: RemoteInfo;\n },\n ],\n HTMLLinkElement | void\n >(),\n fetch: new AsyncHook<\n [string, RequestInit, RemoteInfo?],\n Promise<Response> | void | false\n >(),\n loadEntryError: new AsyncHook<\n [\n {\n getRemoteEntry: typeof getRemoteEntry;\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n globalLoading: Record<\n string,\n Promise<void | RemoteEntryExports> | undefined\n >;\n uniqueKey: string;\n },\n ],\n Promise<Promise<RemoteEntryExports | undefined> | undefined>\n >(),\n getModuleFactory: new AsyncHook<\n [\n {\n remoteEntryExports: RemoteEntryExports;\n expose: string;\n moduleInfo: RemoteInfo;\n },\n ],\n Promise<(() => Promise<Module>) | undefined>\n >(),\n });\n bridgeHook = new PluginSystem({\n beforeBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n beforeBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n });\n moduleInfo?: GlobalModuleInfo[string];\n\n constructor(userOptions: UserOptions) {\n const plugins = USE_SNAPSHOT\n ? [snapshotPlugin(), generatePreloadAssetsPlugin()]\n : [];\n // TODO: Validate the details of the options\n // Initialize options with default values\n const defaultOptions: Options = {\n id: getBuilderId(),\n name: userOptions.name,\n plugins,\n remotes: [],\n shared: {},\n inBrowser: isBrowserEnvValue,\n };\n\n this.name = userOptions.name;\n this.options = defaultOptions;\n this.snapshotHandler = new SnapshotHandler(this);\n this.sharedHandler = new SharedHandler(this);\n this.remoteHandler = new RemoteHandler(this);\n this.shareScopeMap = this.sharedHandler.shareScopeMap;\n this.registerPlugins([\n ...defaultOptions.plugins,\n ...(userOptions.plugins || []),\n ]);\n this.options = this.formatOptions(defaultOptions, userOptions);\n }\n\n initOptions(userOptions: UserOptions): Options {\n if (userOptions.name && userOptions.name !== this.options.name) {\n error(getShortErrorMsg(RUNTIME_010, runtimeDescMap));\n }\n this.registerPlugins(userOptions.plugins);\n const options = this.formatOptions(this.options, userOptions);\n\n this.options = options;\n\n return options;\n }\n\n async loadShare<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): Promise<false | (() => T | undefined)> {\n return this.sharedHandler.loadShare(pkgName, extraOptions);\n }\n\n // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.\n // 1. If the loaded shared already exists globally, then it will be reused\n // 2. If lib exists in local shared, it will be used directly\n // 3. If the local get returns something other than Promise, then it will be used directly\n loadShareSync<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n from?: 'build' | 'runtime';\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): () => T | never {\n return this.sharedHandler.loadShareSync(pkgName, extraOptions);\n }\n\n initializeSharing(\n shareScopeName = DEFAULT_SCOPE,\n extraOptions?: {\n initScope?: InitScope;\n from?: CallFrom;\n strategy?: Shared['strategy'];\n },\n ): Array<Promise<void>> {\n return this.sharedHandler.initializeSharing(shareScopeName, extraOptions);\n }\n\n initRawContainer(\n name: string,\n url: string,\n container: RemoteEntryExports,\n ): Module {\n const remoteInfo = getRemoteInfo({ name, entry: url });\n const module = new Module({ host: this, remoteInfo });\n\n module.remoteEntryExports = container;\n this.moduleCache.set(name, module);\n\n return module;\n }\n\n // eslint-disable-next-line max-lines-per-function\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async loadRemote<T>(\n id: string,\n options?: { loadFactory?: boolean; from: CallFrom },\n ): Promise<T | null> {\n return this.remoteHandler.loadRemote(id, options);\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void> {\n return this.remoteHandler.preloadRemote(preloadOptions);\n }\n\n initShareScopeMap(\n scopeName: string,\n shareScope: ShareScopeMap[string],\n extraOptions: { hostShareScopeMap?: ShareScopeMap } = {},\n ): void {\n this.sharedHandler.initShareScopeMap(scopeName, shareScope, extraOptions);\n }\n\n formatOptions(globalOptions: Options, userOptions: UserOptions): Options {\n const { allShareInfos: shared } = formatShareConfigs(\n globalOptions,\n userOptions,\n );\n const { userOptions: userOptionsRes, options: globalOptionsRes } =\n this.hooks.lifecycle.beforeInit.emit({\n origin: this,\n userOptions,\n options: globalOptions,\n shareInfo: shared,\n });\n\n const remotes = this.remoteHandler.formatAndRegisterRemote(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const { allShareInfos } = this.sharedHandler.registerShared(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const plugins = [...globalOptionsRes.plugins];\n\n if (userOptionsRes.plugins) {\n userOptionsRes.plugins.forEach((plugin) => {\n if (!plugins.includes(plugin)) {\n plugins.push(plugin);\n }\n });\n }\n\n const optionsRes: Options = {\n ...globalOptions,\n ...userOptions,\n plugins,\n remotes,\n shared: allShareInfos,\n id: userOptionsRes.id || globalOptions.id,\n };\n\n this.hooks.lifecycle.init.emit({\n origin: this,\n options: optionsRes,\n });\n return optionsRes;\n }\n\n registerPlugins(plugins: UserOptions['plugins']) {\n const pluginRes = registerPlugins(plugins, this);\n // Merge plugin\n this.options.plugins = this.options.plugins.reduce((res, plugin) => {\n if (!plugin) return res;\n if (res && !res.find((item) => item.name === plugin.name)) {\n res.push(plugin);\n }\n return res;\n }, pluginRes || []);\n }\n registerRemotes(remotes: Remote[], options?: { force?: boolean }): void {\n return this.remoteHandler.registerRemotes(remotes, options);\n }\n\n registerShared(shared: UserOptions['shared']) {\n this.sharedHandler.registerShared(this.options, {\n ...this.options,\n shared,\n });\n }\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"core.js","names":["Module"],"sources":["../src/core.ts"],"sourcesContent":["import { isBrowserEnvValue } from '@module-federation/sdk';\nimport type {\n CreateLinkHookReturnDom,\n CreateScriptHookReturn,\n GlobalModuleInfo,\n ModuleInfo,\n} from '@module-federation/sdk';\nimport {\n Options,\n PreloadRemoteArgs,\n RemoteEntryExports,\n Remote,\n Shared,\n ShareInfos,\n UserOptions,\n RemoteInfo,\n ShareScopeMap,\n InitScope,\n RemoteEntryInitOptions,\n CallFrom,\n ResourceLoadContext,\n} from './type';\nimport { getBuilderId, registerPlugins, getRemoteEntry, error } from './utils';\nimport {\n getShortErrorMsg,\n RUNTIME_010,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Module, type RemoteModuleFactory } from './module';\nimport {\n AsyncHook,\n AsyncWaterfallHook,\n PluginSystem,\n SyncHook,\n SyncWaterfallHook,\n} from './utils/hooks';\nimport { generatePreloadAssetsPlugin } from './plugins/generate-preload-assets';\nimport { snapshotPlugin } from './plugins/snapshot';\nimport { getRemoteInfo } from './utils/load';\nimport { DEFAULT_SCOPE } from './constant';\nimport { SnapshotHandler } from './plugins/snapshot/SnapshotHandler';\nimport { SharedHandler } from './shared';\nimport { RemoteHandler } from './remote';\nimport { formatShareConfigs } from './utils/share';\n\n// Declare the global constant that will be defined by DefinePlugin\n// Default to true if not defined (e.g., when runtime-core is used outside of webpack)\n// so that snapshot functionality is included by default.\ndeclare const FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: boolean;\nconst USE_SNAPSHOT =\n typeof FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'boolean'\n ? !FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN\n : true; // Default to true (use snapshot) when not explicitly defined\n\nexport class ModuleFederation {\n options: Options;\n hooks = new PluginSystem({\n beforeInit: new SyncWaterfallHook<{\n userOptions: UserOptions;\n options: Options;\n origin: ModuleFederation;\n /**\n * @deprecated shareInfo will be removed soon, please use userOptions directly!\n */\n shareInfo: ShareInfos;\n }>('beforeInit'),\n init: new SyncHook<\n [\n {\n options: Options;\n origin: ModuleFederation;\n },\n ],\n void\n >(),\n // maybe will change, temporarily for internal use only\n beforeInitContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n origin: ModuleFederation;\n }>('beforeInitContainer'),\n // maybe will change, temporarily for internal use only\n initContainer: new AsyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n initScope: InitScope;\n remoteEntryInitOptions: RemoteEntryInitOptions;\n remoteInfo: RemoteInfo;\n remoteEntryExports: RemoteEntryExports;\n origin: ModuleFederation;\n id?: string;\n remoteSnapshot?: ModuleInfo;\n }>('initContainer'),\n });\n version: string = __VERSION__;\n name: string;\n moduleCache: Map<string, Module> = new Map();\n snapshotHandler: SnapshotHandler;\n sharedHandler: SharedHandler;\n remoteHandler: RemoteHandler;\n shareScopeMap: ShareScopeMap;\n loaderHook = new PluginSystem({\n // FIXME: may not be suitable , not open to the public yet\n getModuleInfo: new SyncHook<\n [\n {\n target: Record<string, any>;\n key: any;\n },\n ],\n { value: any | undefined; key: string } | void\n >(),\n createScript: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n /**\n * The producer(remote) info bound to this resource.\n * Only present when the loader is invoked in a remote-related context\n * (e.g. preloadRemote / loading remoteEntry).\n */\n remoteInfo?: RemoteInfo;\n resourceContext?: ResourceLoadContext;\n },\n ],\n CreateScriptHookReturn\n >(),\n createLink: new SyncHook<\n [\n {\n url: string;\n attrs?: Record<string, any>;\n /**\n * The producer(remote) info bound to this resource.\n * Only present when the loader is invoked in a remote-related context\n * (e.g. preloadRemote / loading remoteEntry).\n */\n remoteInfo?: RemoteInfo;\n resourceContext?: ResourceLoadContext;\n },\n ],\n CreateLinkHookReturnDom\n >(),\n fetch: new AsyncHook<\n [string, RequestInit, RemoteInfo?, ResourceLoadContext?],\n Promise<Response> | void | false\n >(),\n loadEntryError: new AsyncHook<\n [\n {\n getRemoteEntry: typeof getRemoteEntry;\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n globalLoading: Record<\n string,\n Promise<void | RemoteEntryExports> | undefined\n >;\n uniqueKey: string;\n },\n ],\n Promise<Promise<RemoteEntryExports | undefined> | undefined>\n >(),\n afterLoadEntry: new AsyncHook<\n [\n {\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | false | void;\n error?: unknown;\n recovered?: boolean;\n },\n ],\n void\n >('afterLoadEntry'),\n beforeInitRemote: new AsyncHook<\n [\n {\n id?: string;\n remoteInfo: RemoteInfo;\n remoteSnapshot?: ModuleInfo;\n origin: ModuleFederation;\n },\n ],\n void\n >('beforeInitRemote'),\n afterInitRemote: new AsyncHook<\n [\n {\n id?: string;\n remoteInfo: RemoteInfo;\n remoteSnapshot?: ModuleInfo;\n remoteEntryExports?: RemoteEntryExports;\n error?: unknown;\n cached?: boolean;\n origin: ModuleFederation;\n },\n ],\n void\n >('afterInitRemote'),\n beforeGetExpose: new AsyncHook<\n [\n {\n id: string;\n expose: string;\n moduleInfo: RemoteInfo;\n remoteEntryExports: RemoteEntryExports;\n origin: ModuleFederation;\n },\n ],\n void\n >('beforeGetExpose'),\n afterGetExpose: new AsyncHook<\n [\n {\n id: string;\n expose: string;\n moduleInfo: RemoteInfo;\n remoteEntryExports: RemoteEntryExports;\n moduleFactory?: RemoteModuleFactory;\n error?: unknown;\n origin: ModuleFederation;\n },\n ],\n void\n >('afterGetExpose'),\n beforeExecuteFactory: new AsyncHook<\n [\n {\n id: string;\n expose: string;\n moduleInfo: RemoteInfo;\n loadFactory: boolean;\n origin: ModuleFederation;\n },\n ],\n void\n >('beforeExecuteFactory'),\n afterExecuteFactory: new AsyncHook<\n [\n {\n id: string;\n expose: string;\n moduleInfo: RemoteInfo;\n loadFactory: boolean;\n exposeModule?: unknown;\n error?: unknown;\n origin: ModuleFederation;\n },\n ],\n void\n >('afterExecuteFactory'),\n getModuleFactory: new AsyncHook<\n [\n {\n remoteEntryExports: RemoteEntryExports;\n expose: string;\n moduleInfo: RemoteInfo;\n },\n ],\n RemoteModuleFactory | Promise<RemoteModuleFactory | undefined> | undefined\n >(),\n });\n bridgeHook = new PluginSystem({\n beforeBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeRender: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n beforeBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n afterBridgeDestroy: new SyncHook<\n [Record<string, any>],\n void | Record<string, any>\n >(),\n });\n moduleInfo?: GlobalModuleInfo[string];\n\n constructor(userOptions: UserOptions) {\n const plugins = USE_SNAPSHOT\n ? [snapshotPlugin(), generatePreloadAssetsPlugin()]\n : [];\n // TODO: Validate the details of the options\n // Initialize options with default values\n const defaultOptions: Options = {\n id: getBuilderId(),\n name: userOptions.name,\n plugins,\n remotes: [],\n shared: {},\n inBrowser: isBrowserEnvValue,\n };\n\n this.name = userOptions.name;\n this.options = defaultOptions;\n this.snapshotHandler = new SnapshotHandler(this);\n this.sharedHandler = new SharedHandler(this);\n this.remoteHandler = new RemoteHandler(this);\n this.shareScopeMap = this.sharedHandler.shareScopeMap;\n this.registerPlugins([\n ...defaultOptions.plugins,\n ...(userOptions.plugins || []),\n ]);\n this.options = this.formatOptions(defaultOptions, userOptions);\n }\n\n initOptions(userOptions: UserOptions): Options {\n if (userOptions.name && userOptions.name !== this.options.name) {\n error(getShortErrorMsg(RUNTIME_010, runtimeDescMap));\n }\n this.registerPlugins(userOptions.plugins);\n const options = this.formatOptions(this.options, userOptions);\n\n this.options = options;\n\n return options;\n }\n\n async loadShare<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): Promise<false | (() => T | undefined)> {\n return this.sharedHandler.loadShare(pkgName, extraOptions);\n }\n\n // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.\n // 1. If the loaded shared already exists globally, then it will be reused\n // 2. If lib exists in local shared, it will be used directly\n // 3. If the local get returns something other than Promise, then it will be used directly\n loadShareSync<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n from?: 'build' | 'runtime';\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): () => T | never {\n return this.sharedHandler.loadShareSync(pkgName, extraOptions);\n }\n\n initializeSharing(\n shareScopeName = DEFAULT_SCOPE,\n extraOptions?: {\n initScope?: InitScope;\n from?: CallFrom;\n strategy?: Shared['strategy'];\n },\n ): Array<Promise<void>> {\n return this.sharedHandler.initializeSharing(shareScopeName, extraOptions);\n }\n\n initRawContainer(\n name: string,\n url: string,\n container: RemoteEntryExports,\n ): Module {\n const remoteInfo = getRemoteInfo({ name, entry: url });\n const module = new Module({ host: this, remoteInfo });\n\n module.remoteEntryExports = container;\n this.moduleCache.set(name, module);\n\n return module;\n }\n\n // eslint-disable-next-line max-lines-per-function\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async loadRemote<T>(\n id: string,\n options?: { loadFactory?: boolean; from: CallFrom },\n ): Promise<T | null> {\n return this.remoteHandler.loadRemote(id, options);\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void> {\n return this.remoteHandler.preloadRemote(preloadOptions);\n }\n\n initShareScopeMap(\n scopeName: string,\n shareScope: ShareScopeMap[string],\n extraOptions: { hostShareScopeMap?: ShareScopeMap } = {},\n ): void {\n this.sharedHandler.initShareScopeMap(scopeName, shareScope, extraOptions);\n }\n\n formatOptions(globalOptions: Options, userOptions: UserOptions): Options {\n const { allShareInfos: shared } = formatShareConfigs(\n globalOptions,\n userOptions,\n );\n const { userOptions: userOptionsRes, options: globalOptionsRes } =\n this.hooks.lifecycle.beforeInit.emit({\n origin: this,\n userOptions,\n options: globalOptions,\n shareInfo: shared,\n });\n\n const remotes = this.remoteHandler.formatAndRegisterRemote(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const { allShareInfos } = this.sharedHandler.registerShared(\n globalOptionsRes,\n userOptionsRes,\n );\n\n const plugins = [...globalOptionsRes.plugins];\n\n if (userOptionsRes.plugins) {\n userOptionsRes.plugins.forEach((plugin) => {\n if (!plugins.includes(plugin)) {\n plugins.push(plugin);\n }\n });\n }\n\n const optionsRes: Options = {\n ...globalOptions,\n ...userOptions,\n plugins,\n remotes,\n shared: allShareInfos,\n id: userOptionsRes.id || globalOptions.id,\n };\n\n this.hooks.lifecycle.init.emit({\n origin: this,\n options: optionsRes,\n });\n return optionsRes;\n }\n\n registerPlugins(plugins: UserOptions['plugins']) {\n const pluginRes = registerPlugins(plugins, this);\n // Merge plugin\n this.options.plugins = this.options.plugins.reduce((res, plugin) => {\n if (!plugin) return res;\n if (res && !res.find((item) => item.name === plugin.name)) {\n res.push(plugin);\n }\n return res;\n }, pluginRes || []);\n }\n registerRemotes(remotes: Remote[], options?: { force?: boolean }): void {\n return this.remoteHandler.registerRemotes(remotes, options);\n }\n\n registerShared(shared: UserOptions['shared']) {\n this.sharedHandler.registerShared(this.options, {\n ...this.options,\n shared,\n });\n }\n}\n"],"mappings":"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"} |
+1
-1
@@ -68,3 +68,3 @@ const require_logger = require('./utils/logger.cjs'); | ||
| CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR__ = FederationConstructor; | ||
| CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "2.4.0"; | ||
| CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "2.5.0"; | ||
| } | ||
@@ -71,0 +71,0 @@ } |
+1
-1
@@ -68,3 +68,3 @@ import { error, warn as warn$1 } from "./utils/logger.js"; | ||
| CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR__ = FederationConstructor; | ||
| CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "2.4.0"; | ||
| CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "2.5.0"; | ||
| } | ||
@@ -71,0 +71,0 @@ } |
+158
-21
| const require_logger = require('../utils/logger.cjs'); | ||
| const require_tool = require('../utils/tool.cjs'); | ||
| const require_manifest = require('../utils/manifest.cjs'); | ||
| const require_load = require('../utils/load.cjs'); | ||
@@ -10,2 +11,7 @@ const require_context = require('../utils/context.cjs'); | ||
| //#region src/module/index.ts | ||
| function getAvailableExposeNames(remoteSnapshot) { | ||
| if (!remoteSnapshot || !("modules" in remoteSnapshot) || !Array.isArray(remoteSnapshot.modules)) return; | ||
| const exposes = remoteSnapshot.modules.map((module) => module.moduleName).filter(Boolean); | ||
| return exposes.length ? exposes.join(",") : void 0; | ||
| } | ||
| function createRemoteEntryInitOptions(remoteInfo, hostShareScopeMap, rawInitScope) { | ||
@@ -40,3 +46,3 @@ const localShareScopeMap = hostShareScopeMap; | ||
| } | ||
| async getEntry() { | ||
| async getEntry(expose) { | ||
| if (this.remoteEntryExports) return this.remoteEntryExports; | ||
@@ -46,3 +52,8 @@ const remoteEntryExports = await require_load.getRemoteEntry({ | ||
| remoteInfo: this.remoteInfo, | ||
| remoteEntryExports: this.remoteEntryExports | ||
| remoteEntryExports: this.remoteEntryExports, | ||
| resourceContext: { | ||
| initiator: "loadRemote", | ||
| id: require_manifest.composeRemoteRequestId(this.remoteInfo.name, expose), | ||
| resourceType: "remoteEntry" | ||
| } | ||
| }); | ||
@@ -53,7 +64,38 @@ require_logger.assert(remoteEntryExports, `remoteEntryExports is undefined \n ${(0, _module_federation_sdk.safeToString)(this.remoteInfo)}`); | ||
| } | ||
| async init(id, remoteSnapshot, rawInitScope) { | ||
| const remoteEntryExports = await this.getEntry(); | ||
| if (this.inited) return remoteEntryExports; | ||
| async init(id, remoteSnapshot, rawInitScope, expose) { | ||
| const remoteEntryExports = await this.getEntry(expose); | ||
| if (this.inited) { | ||
| await this.host.loaderHook.lifecycle.afterInitRemote.emit({ | ||
| id, | ||
| remoteInfo: this.remoteInfo, | ||
| remoteSnapshot, | ||
| remoteEntryExports, | ||
| cached: true, | ||
| origin: this.host | ||
| }); | ||
| return remoteEntryExports; | ||
| } | ||
| if (this.initPromise) { | ||
| await this.initPromise; | ||
| try { | ||
| await this.initPromise; | ||
| await this.host.loaderHook.lifecycle.afterInitRemote.emit({ | ||
| id, | ||
| remoteInfo: this.remoteInfo, | ||
| remoteSnapshot, | ||
| remoteEntryExports, | ||
| cached: true, | ||
| origin: this.host | ||
| }); | ||
| } catch (initError) { | ||
| await this.host.loaderHook.lifecycle.afterInitRemote.emit({ | ||
| id, | ||
| remoteInfo: this.remoteInfo, | ||
| remoteSnapshot, | ||
| remoteEntryExports, | ||
| error: initError, | ||
| cached: true, | ||
| origin: this.host | ||
| }); | ||
| throw initError; | ||
| } | ||
| return remoteEntryExports; | ||
@@ -63,2 +105,8 @@ } | ||
| this.initPromise = (async () => { | ||
| await this.host.loaderHook.lifecycle.beforeInitRemote.emit({ | ||
| id, | ||
| remoteInfo: this.remoteInfo, | ||
| remoteSnapshot, | ||
| origin: this.host | ||
| }); | ||
| const { remoteEntryInitOptions, shareScope, initScope } = createRemoteEntryInitOptions(this.remoteInfo, this.host.shareScopeMap, rawInitScope); | ||
@@ -78,3 +126,13 @@ const initContainerOptions = await this.host.hooks.lifecycle.beforeInitContainer.emit({ | ||
| }, void 0, require_context.optionsToMFContext(this.host.options)); | ||
| await remoteEntryExports.init(initContainerOptions.shareScope, initContainerOptions.initScope, initContainerOptions.remoteEntryInitOptions); | ||
| try { | ||
| await remoteEntryExports.init(initContainerOptions.shareScope, initContainerOptions.initScope, initContainerOptions.remoteEntryInitOptions); | ||
| } catch (initError) { | ||
| require_logger.error(_module_federation_error_codes.RUNTIME_015, _module_federation_error_codes.runtimeDescMap, { | ||
| hostName: this.host.name, | ||
| remoteName: this.remoteInfo.name, | ||
| remoteEntryUrl: this.remoteInfo.entry, | ||
| remoteEntryKey: this.remoteInfo.entryGlobalName, | ||
| shareScope: this.remoteInfo.shareScope | ||
| }, `${initError}`, require_context.optionsToMFContext(this.host.options)); | ||
| } | ||
| await this.host.hooks.lifecycle.initContainer.emit({ | ||
@@ -90,2 +148,19 @@ ...initContainerOptions, | ||
| await this.initPromise; | ||
| await this.host.loaderHook.lifecycle.afterInitRemote.emit({ | ||
| id, | ||
| remoteInfo: this.remoteInfo, | ||
| remoteSnapshot, | ||
| remoteEntryExports, | ||
| origin: this.host | ||
| }); | ||
| } catch (initError) { | ||
| await this.host.loaderHook.lifecycle.afterInitRemote.emit({ | ||
| id, | ||
| remoteInfo: this.remoteInfo, | ||
| remoteSnapshot, | ||
| remoteEntryExports, | ||
| error: initError, | ||
| origin: this.host | ||
| }); | ||
| throw initError; | ||
| } finally { | ||
@@ -99,16 +174,79 @@ this.initing = false; | ||
| const { loadFactory = true } = options || { loadFactory: true }; | ||
| const remoteEntryExports = await this.init(id, remoteSnapshot); | ||
| const remoteEntryExports = await this.init(id, remoteSnapshot, void 0, expose); | ||
| this.lib = remoteEntryExports; | ||
| let moduleFactory; | ||
| moduleFactory = await this.host.loaderHook.lifecycle.getModuleFactory.emit({ | ||
| await this.host.loaderHook.lifecycle.beforeGetExpose.emit({ | ||
| id, | ||
| expose, | ||
| moduleInfo: this.remoteInfo, | ||
| remoteEntryExports, | ||
| expose, | ||
| moduleInfo: this.remoteInfo | ||
| origin: this.host | ||
| }); | ||
| if (!moduleFactory) moduleFactory = await remoteEntryExports.get(expose); | ||
| require_logger.assert(moduleFactory, `${require_tool.getFMId(this.remoteInfo)} remote don't export ${expose}.`); | ||
| let moduleFactory; | ||
| try { | ||
| const hookModuleFactory = await this.host.loaderHook.lifecycle.getModuleFactory.emit({ | ||
| remoteEntryExports, | ||
| expose, | ||
| moduleInfo: this.remoteInfo | ||
| }); | ||
| moduleFactory = typeof hookModuleFactory === "function" ? hookModuleFactory : void 0; | ||
| if (!moduleFactory) moduleFactory = await remoteEntryExports.get(expose); | ||
| if (!moduleFactory) require_logger.error(_module_federation_error_codes.RUNTIME_014, _module_federation_error_codes.runtimeDescMap, { | ||
| hostName: this.host.name, | ||
| remoteName: this.remoteInfo.name, | ||
| remoteEntryUrl: this.remoteInfo.entry, | ||
| expose, | ||
| requestId: id, | ||
| availableExposes: getAvailableExposeNames(remoteSnapshot) | ||
| }, void 0, require_context.optionsToMFContext(this.host.options)); | ||
| await this.host.loaderHook.lifecycle.afterGetExpose.emit({ | ||
| id, | ||
| expose, | ||
| moduleInfo: this.remoteInfo, | ||
| remoteEntryExports, | ||
| moduleFactory, | ||
| origin: this.host | ||
| }); | ||
| } catch (getExposeError) { | ||
| await this.host.loaderHook.lifecycle.afterGetExpose.emit({ | ||
| id, | ||
| expose, | ||
| moduleInfo: this.remoteInfo, | ||
| remoteEntryExports, | ||
| error: getExposeError, | ||
| origin: this.host | ||
| }); | ||
| throw getExposeError; | ||
| } | ||
| const symbolName = require_tool.processModuleAlias(this.remoteInfo.name, expose); | ||
| const wrapModuleFactory = this.wraperFactory(moduleFactory, symbolName); | ||
| if (!loadFactory) return wrapModuleFactory; | ||
| return await wrapModuleFactory(); | ||
| await this.host.loaderHook.lifecycle.beforeExecuteFactory.emit({ | ||
| id, | ||
| expose, | ||
| moduleInfo: this.remoteInfo, | ||
| loadFactory, | ||
| origin: this.host | ||
| }); | ||
| try { | ||
| const exposeContent = await wrapModuleFactory(); | ||
| await this.host.loaderHook.lifecycle.afterExecuteFactory.emit({ | ||
| id, | ||
| expose, | ||
| moduleInfo: this.remoteInfo, | ||
| loadFactory, | ||
| exposeModule: exposeContent, | ||
| origin: this.host | ||
| }); | ||
| return exposeContent; | ||
| } catch (executeFactoryError) { | ||
| await this.host.loaderHook.lifecycle.afterExecuteFactory.emit({ | ||
| id, | ||
| expose, | ||
| moduleInfo: this.remoteInfo, | ||
| loadFactory, | ||
| error: executeFactoryError, | ||
| origin: this.host | ||
| }); | ||
| throw executeFactoryError; | ||
| } | ||
| } | ||
@@ -122,9 +260,8 @@ wraperFactory(moduleFactory, id) { | ||
| } | ||
| if (moduleFactory instanceof Promise) return async () => { | ||
| const res = await moduleFactory(); | ||
| defineModuleId(res, id); | ||
| return res; | ||
| }; | ||
| else return () => { | ||
| return () => { | ||
| const res = moduleFactory(); | ||
| if (res instanceof Promise) return res.then((asyncRes) => { | ||
| defineModuleId(asyncRes, id); | ||
| return asyncRes; | ||
| }); | ||
| defineModuleId(res, id); | ||
@@ -131,0 +268,0 @@ return res; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.cjs","names":["getRemoteEntry","RUNTIME_002","runtimeDescMap","optionsToMFContext","getFMId","processModuleAlias"],"sources":["../../src/module/index.ts"],"sourcesContent":["import {\n getFMId,\n assert,\n error,\n processModuleAlias,\n optionsToMFContext,\n} from '../utils';\nimport { safeToString, ModuleInfo } from '@module-federation/sdk';\nimport {\n RUNTIME_002,\n RUNTIME_008,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { getRemoteEntry } from '../utils/load';\nimport { ModuleFederation } from '../core';\nimport {\n RemoteEntryExports,\n RemoteInfo,\n InitScope,\n ShareScopeMap,\n} from '../type';\n\nexport type ModuleOptions = ConstructorParameters<typeof Module>[0];\n\nexport function createRemoteEntryInitOptions(\n remoteInfo: RemoteInfo,\n hostShareScopeMap: ShareScopeMap,\n rawInitScope?: InitScope,\n): Record<string, any> {\n const localShareScopeMap = hostShareScopeMap;\n\n const shareScopeKeys = Array.isArray(remoteInfo.shareScope)\n ? remoteInfo.shareScope\n : [remoteInfo.shareScope];\n\n if (!shareScopeKeys.length) {\n shareScopeKeys.push('default');\n }\n shareScopeKeys.forEach((shareScopeKey) => {\n if (!localShareScopeMap[shareScopeKey]) {\n localShareScopeMap[shareScopeKey] = {};\n }\n });\n\n const remoteEntryInitOptions = {\n version: remoteInfo.version || '',\n shareScopeKeys: Array.isArray(remoteInfo.shareScope)\n ? shareScopeKeys\n : remoteInfo.shareScope || 'default',\n };\n\n // Help to find host instance\n Object.defineProperty(remoteEntryInitOptions, 'shareScopeMap', {\n value: localShareScopeMap,\n // remoteEntryInitOptions will be traversed and assigned during container init, ,so this attribute is not allowed to be traversed\n enumerable: false,\n });\n\n // TODO: compate legacy init params, should use shareScopeMap if exist\n const shareScope = localShareScopeMap[shareScopeKeys[0]];\n const initScope: InitScope = rawInitScope ?? [];\n\n return {\n remoteEntryInitOptions,\n shareScope,\n initScope,\n };\n}\n\nclass Module {\n remoteInfo: RemoteInfo;\n inited = false;\n initing = false;\n initPromise?: Promise<void>;\n remoteEntryExports?: RemoteEntryExports;\n lib: RemoteEntryExports | undefined = undefined;\n host: ModuleFederation;\n\n constructor({\n remoteInfo,\n host,\n }: {\n remoteInfo: RemoteInfo;\n host: ModuleFederation;\n }) {\n this.remoteInfo = remoteInfo;\n this.host = host;\n }\n\n async getEntry(): Promise<RemoteEntryExports> {\n if (this.remoteEntryExports) {\n return this.remoteEntryExports;\n }\n\n const remoteEntryExports = await getRemoteEntry({\n origin: this.host,\n remoteInfo: this.remoteInfo,\n remoteEntryExports: this.remoteEntryExports,\n });\n\n assert(\n remoteEntryExports,\n `remoteEntryExports is undefined \\n ${safeToString(this.remoteInfo)}`,\n );\n\n this.remoteEntryExports = remoteEntryExports;\n return this.remoteEntryExports;\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n\n async init(\n id?: string,\n remoteSnapshot?: ModuleInfo,\n rawInitScope?: InitScope,\n ) {\n // Get remoteEntry.js\n const remoteEntryExports = await this.getEntry();\n\n if (this.inited) {\n return remoteEntryExports;\n }\n\n if (this.initPromise) {\n await this.initPromise;\n return remoteEntryExports;\n }\n\n this.initing = true;\n this.initPromise = (async () => {\n const { remoteEntryInitOptions, shareScope, initScope } =\n createRemoteEntryInitOptions(\n this.remoteInfo,\n this.host.shareScopeMap,\n rawInitScope,\n );\n\n const initContainerOptions =\n await this.host.hooks.lifecycle.beforeInitContainer.emit({\n shareScope,\n // @ts-ignore shareScopeMap will be set by Object.defineProperty\n remoteEntryInitOptions,\n initScope,\n remoteInfo: this.remoteInfo,\n origin: this.host,\n });\n\n if (typeof remoteEntryExports?.init === 'undefined') {\n error(\n RUNTIME_002,\n runtimeDescMap,\n {\n hostName: this.host.name,\n remoteName: this.remoteInfo.name,\n remoteEntryUrl: this.remoteInfo.entry,\n remoteEntryKey: this.remoteInfo.entryGlobalName,\n },\n undefined,\n optionsToMFContext(this.host.options),\n );\n }\n\n await remoteEntryExports.init(\n initContainerOptions.shareScope,\n initContainerOptions.initScope,\n initContainerOptions.remoteEntryInitOptions,\n );\n\n await this.host.hooks.lifecycle.initContainer.emit({\n ...initContainerOptions,\n id,\n remoteSnapshot,\n remoteEntryExports,\n });\n this.inited = true;\n })();\n\n try {\n await this.initPromise;\n } finally {\n this.initing = false;\n this.initPromise = undefined;\n }\n\n return remoteEntryExports;\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n async get(\n id: string,\n expose: string,\n options?: { loadFactory?: boolean },\n remoteSnapshot?: ModuleInfo,\n ) {\n const { loadFactory = true } = options || { loadFactory: true };\n\n const remoteEntryExports = await this.init(id, remoteSnapshot);\n this.lib = remoteEntryExports;\n\n let moduleFactory;\n moduleFactory = await this.host.loaderHook.lifecycle.getModuleFactory.emit({\n remoteEntryExports,\n expose,\n moduleInfo: this.remoteInfo,\n });\n\n // get exposeGetter\n if (!moduleFactory) {\n moduleFactory = await remoteEntryExports.get(expose);\n }\n\n assert(\n moduleFactory,\n `${getFMId(this.remoteInfo)} remote don't export ${expose}.`,\n );\n\n // keep symbol for module name always one format\n const symbolName = processModuleAlias(this.remoteInfo.name, expose);\n const wrapModuleFactory = this.wraperFactory(moduleFactory, symbolName);\n\n if (!loadFactory) {\n return wrapModuleFactory;\n }\n const exposeContent = await wrapModuleFactory();\n\n return exposeContent;\n }\n\n private wraperFactory(\n moduleFactory: () => any | (() => Promise<any>),\n id: string,\n ) {\n function defineModuleId(res: any, id: string) {\n if (\n res &&\n typeof res === 'object' &&\n Object.isExtensible(res) &&\n !Object.getOwnPropertyDescriptor(res, Symbol.for('mf_module_id'))\n ) {\n Object.defineProperty(res, Symbol.for('mf_module_id'), {\n value: id,\n enumerable: false,\n });\n }\n }\n\n if (moduleFactory instanceof Promise) {\n return async () => {\n const res = await moduleFactory();\n // This parameter is used for bridge debugging\n defineModuleId(res, id);\n return res;\n };\n } else {\n return () => {\n const res = moduleFactory();\n // This parameter is used for bridge debugging\n defineModuleId(res, id);\n return res;\n };\n }\n }\n}\n\nexport { Module };\n"],"mappings":"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"} | ||
| {"version":3,"file":"index.cjs","names":["getRemoteEntry","composeRemoteRequestId","RUNTIME_002","runtimeDescMap","optionsToMFContext","RUNTIME_015","RUNTIME_014","processModuleAlias"],"sources":["../../src/module/index.ts"],"sourcesContent":["import {\n assert,\n error,\n processModuleAlias,\n optionsToMFContext,\n composeRemoteRequestId,\n} from '../utils';\nimport { safeToString, ModuleInfo } from '@module-federation/sdk';\nimport {\n RUNTIME_002,\n RUNTIME_014,\n RUNTIME_015,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { getRemoteEntry } from '../utils/load';\nimport { ModuleFederation } from '../core';\nimport {\n RemoteEntryExports,\n RemoteInfo,\n InitScope,\n ShareScopeMap,\n} from '../type';\n\nexport type ModuleOptions = ConstructorParameters<typeof Module>[0];\nexport type RemoteModuleFactory = () => unknown | Promise<unknown>;\n\nfunction getAvailableExposeNames(\n remoteSnapshot?: ModuleInfo,\n): string | undefined {\n if (\n !remoteSnapshot ||\n !('modules' in remoteSnapshot) ||\n !Array.isArray(remoteSnapshot.modules)\n ) {\n return undefined;\n }\n\n const exposes = remoteSnapshot.modules\n .map((module) => module.moduleName)\n .filter(Boolean);\n\n return exposes.length ? exposes.join(',') : undefined;\n}\n\nexport function createRemoteEntryInitOptions(\n remoteInfo: RemoteInfo,\n hostShareScopeMap: ShareScopeMap,\n rawInitScope?: InitScope,\n): Record<string, any> {\n const localShareScopeMap = hostShareScopeMap;\n\n const shareScopeKeys = Array.isArray(remoteInfo.shareScope)\n ? remoteInfo.shareScope\n : [remoteInfo.shareScope];\n\n if (!shareScopeKeys.length) {\n shareScopeKeys.push('default');\n }\n shareScopeKeys.forEach((shareScopeKey) => {\n if (!localShareScopeMap[shareScopeKey]) {\n localShareScopeMap[shareScopeKey] = {};\n }\n });\n\n const remoteEntryInitOptions = {\n version: remoteInfo.version || '',\n shareScopeKeys: Array.isArray(remoteInfo.shareScope)\n ? shareScopeKeys\n : remoteInfo.shareScope || 'default',\n };\n\n // Help to find host instance\n Object.defineProperty(remoteEntryInitOptions, 'shareScopeMap', {\n value: localShareScopeMap,\n // remoteEntryInitOptions will be traversed and assigned during container init, ,so this attribute is not allowed to be traversed\n enumerable: false,\n });\n\n // TODO: compate legacy init params, should use shareScopeMap if exist\n const shareScope = localShareScopeMap[shareScopeKeys[0]];\n const initScope: InitScope = rawInitScope ?? [];\n\n return {\n remoteEntryInitOptions,\n shareScope,\n initScope,\n };\n}\n\nclass Module {\n remoteInfo: RemoteInfo;\n inited = false;\n initing = false;\n initPromise?: Promise<void>;\n remoteEntryExports?: RemoteEntryExports;\n lib: RemoteEntryExports | undefined = undefined;\n host: ModuleFederation;\n\n constructor({\n remoteInfo,\n host,\n }: {\n remoteInfo: RemoteInfo;\n host: ModuleFederation;\n }) {\n this.remoteInfo = remoteInfo;\n this.host = host;\n }\n\n async getEntry(expose?: string): Promise<RemoteEntryExports> {\n if (this.remoteEntryExports) {\n return this.remoteEntryExports;\n }\n\n const remoteEntryExports = await getRemoteEntry({\n origin: this.host,\n remoteInfo: this.remoteInfo,\n remoteEntryExports: this.remoteEntryExports,\n resourceContext: {\n initiator: 'loadRemote',\n id: composeRemoteRequestId(this.remoteInfo.name, expose),\n resourceType: 'remoteEntry',\n },\n });\n\n assert(\n remoteEntryExports,\n `remoteEntryExports is undefined \\n ${safeToString(this.remoteInfo)}`,\n );\n\n this.remoteEntryExports = remoteEntryExports;\n return this.remoteEntryExports;\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n\n async init(\n id?: string,\n remoteSnapshot?: ModuleInfo,\n rawInitScope?: InitScope,\n expose?: string,\n ) {\n // Get remoteEntry.js\n const remoteEntryExports = await this.getEntry(expose);\n\n if (this.inited) {\n await this.host.loaderHook.lifecycle.afterInitRemote.emit({\n id,\n remoteInfo: this.remoteInfo,\n remoteSnapshot,\n remoteEntryExports,\n cached: true,\n origin: this.host,\n });\n return remoteEntryExports;\n }\n\n if (this.initPromise) {\n try {\n await this.initPromise;\n await this.host.loaderHook.lifecycle.afterInitRemote.emit({\n id,\n remoteInfo: this.remoteInfo,\n remoteSnapshot,\n remoteEntryExports,\n cached: true,\n origin: this.host,\n });\n } catch (initError) {\n await this.host.loaderHook.lifecycle.afterInitRemote.emit({\n id,\n remoteInfo: this.remoteInfo,\n remoteSnapshot,\n remoteEntryExports,\n error: initError,\n cached: true,\n origin: this.host,\n });\n throw initError;\n }\n return remoteEntryExports;\n }\n\n this.initing = true;\n this.initPromise = (async () => {\n await this.host.loaderHook.lifecycle.beforeInitRemote.emit({\n id,\n remoteInfo: this.remoteInfo,\n remoteSnapshot,\n origin: this.host,\n });\n\n const { remoteEntryInitOptions, shareScope, initScope } =\n createRemoteEntryInitOptions(\n this.remoteInfo,\n this.host.shareScopeMap,\n rawInitScope,\n );\n\n const initContainerOptions =\n await this.host.hooks.lifecycle.beforeInitContainer.emit({\n shareScope,\n // @ts-ignore shareScopeMap will be set by Object.defineProperty\n remoteEntryInitOptions,\n initScope,\n remoteInfo: this.remoteInfo,\n origin: this.host,\n });\n\n if (typeof remoteEntryExports?.init === 'undefined') {\n error(\n RUNTIME_002,\n runtimeDescMap,\n {\n hostName: this.host.name,\n remoteName: this.remoteInfo.name,\n remoteEntryUrl: this.remoteInfo.entry,\n remoteEntryKey: this.remoteInfo.entryGlobalName,\n },\n undefined,\n optionsToMFContext(this.host.options),\n );\n }\n\n try {\n await remoteEntryExports.init(\n initContainerOptions.shareScope,\n initContainerOptions.initScope,\n initContainerOptions.remoteEntryInitOptions,\n );\n } catch (initError) {\n error(\n RUNTIME_015,\n runtimeDescMap,\n {\n hostName: this.host.name,\n remoteName: this.remoteInfo.name,\n remoteEntryUrl: this.remoteInfo.entry,\n remoteEntryKey: this.remoteInfo.entryGlobalName,\n shareScope: this.remoteInfo.shareScope,\n },\n `${initError}`,\n optionsToMFContext(this.host.options),\n );\n }\n\n await this.host.hooks.lifecycle.initContainer.emit({\n ...initContainerOptions,\n id,\n remoteSnapshot,\n remoteEntryExports,\n });\n this.inited = true;\n })();\n\n try {\n await this.initPromise;\n await this.host.loaderHook.lifecycle.afterInitRemote.emit({\n id,\n remoteInfo: this.remoteInfo,\n remoteSnapshot,\n remoteEntryExports,\n origin: this.host,\n });\n } catch (initError) {\n await this.host.loaderHook.lifecycle.afterInitRemote.emit({\n id,\n remoteInfo: this.remoteInfo,\n remoteSnapshot,\n remoteEntryExports,\n error: initError,\n origin: this.host,\n });\n throw initError;\n } finally {\n this.initing = false;\n this.initPromise = undefined;\n }\n\n return remoteEntryExports;\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n async get(\n id: string,\n expose: string,\n options?: { loadFactory?: boolean },\n remoteSnapshot?: ModuleInfo,\n ) {\n const { loadFactory = true } = options || { loadFactory: true };\n\n const remoteEntryExports = await this.init(\n id,\n remoteSnapshot,\n undefined,\n expose,\n );\n this.lib = remoteEntryExports;\n\n await this.host.loaderHook.lifecycle.beforeGetExpose.emit({\n id,\n expose,\n moduleInfo: this.remoteInfo,\n remoteEntryExports,\n origin: this.host,\n });\n\n let moduleFactory: RemoteModuleFactory | undefined;\n try {\n const hookModuleFactory =\n await this.host.loaderHook.lifecycle.getModuleFactory.emit({\n remoteEntryExports,\n expose,\n moduleInfo: this.remoteInfo,\n });\n moduleFactory =\n typeof hookModuleFactory === 'function' ? hookModuleFactory : undefined;\n\n // get exposeGetter\n if (!moduleFactory) {\n moduleFactory = await remoteEntryExports.get(expose);\n }\n\n if (!moduleFactory) {\n error(\n RUNTIME_014,\n runtimeDescMap,\n {\n hostName: this.host.name,\n remoteName: this.remoteInfo.name,\n remoteEntryUrl: this.remoteInfo.entry,\n expose,\n requestId: id,\n availableExposes: getAvailableExposeNames(remoteSnapshot),\n },\n undefined,\n optionsToMFContext(this.host.options),\n );\n }\n\n await this.host.loaderHook.lifecycle.afterGetExpose.emit({\n id,\n expose,\n moduleInfo: this.remoteInfo,\n remoteEntryExports,\n moduleFactory,\n origin: this.host,\n });\n } catch (getExposeError) {\n await this.host.loaderHook.lifecycle.afterGetExpose.emit({\n id,\n expose,\n moduleInfo: this.remoteInfo,\n remoteEntryExports,\n error: getExposeError,\n origin: this.host,\n });\n throw getExposeError;\n }\n\n // keep symbol for module name always one format\n const symbolName = processModuleAlias(this.remoteInfo.name, expose);\n const wrapModuleFactory = this.wraperFactory(moduleFactory, symbolName);\n\n if (!loadFactory) {\n return wrapModuleFactory;\n }\n\n await this.host.loaderHook.lifecycle.beforeExecuteFactory.emit({\n id,\n expose,\n moduleInfo: this.remoteInfo,\n loadFactory,\n origin: this.host,\n });\n\n try {\n const exposeContent = await wrapModuleFactory();\n\n await this.host.loaderHook.lifecycle.afterExecuteFactory.emit({\n id,\n expose,\n moduleInfo: this.remoteInfo,\n loadFactory,\n exposeModule: exposeContent,\n origin: this.host,\n });\n\n return exposeContent;\n } catch (executeFactoryError) {\n await this.host.loaderHook.lifecycle.afterExecuteFactory.emit({\n id,\n expose,\n moduleInfo: this.remoteInfo,\n loadFactory,\n error: executeFactoryError,\n origin: this.host,\n });\n throw executeFactoryError;\n }\n }\n\n private wraperFactory(moduleFactory: RemoteModuleFactory, id: string) {\n function defineModuleId(res: unknown, id: string) {\n if (\n res &&\n typeof res === 'object' &&\n Object.isExtensible(res) &&\n !Object.getOwnPropertyDescriptor(res, Symbol.for('mf_module_id'))\n ) {\n Object.defineProperty(res, Symbol.for('mf_module_id'), {\n value: id,\n enumerable: false,\n });\n }\n }\n\n return () => {\n const res = moduleFactory();\n\n if (res instanceof Promise) {\n return res.then((asyncRes) => {\n // This parameter is used for bridge debugging\n defineModuleId(asyncRes, id);\n return asyncRes;\n });\n }\n\n // This parameter is used for bridge debugging\n defineModuleId(res, id);\n return res;\n };\n }\n}\n\nexport { Module };\n"],"mappings":"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"} |
@@ -7,2 +7,3 @@ import { ModuleFederation } from "../core.js"; | ||
| type ModuleOptions = ConstructorParameters<typeof Module$1>[0]; | ||
| type RemoteModuleFactory = () => unknown | Promise<unknown>; | ||
| declare class Module$1 { | ||
@@ -23,11 +24,11 @@ remoteInfo: RemoteInfo; | ||
| }); | ||
| getEntry(): Promise<RemoteEntryExports>; | ||
| init(id?: string, remoteSnapshot?: ModuleInfo, rawInitScope?: InitScope): Promise<RemoteEntryExports>; | ||
| getEntry(expose?: string): Promise<RemoteEntryExports>; | ||
| init(id?: string, remoteSnapshot?: ModuleInfo, rawInitScope?: InitScope, expose?: string): Promise<RemoteEntryExports>; | ||
| get(id: string, expose: string, options?: { | ||
| loadFactory?: boolean; | ||
| }, remoteSnapshot?: ModuleInfo): Promise<any>; | ||
| }, remoteSnapshot?: ModuleInfo): Promise<unknown>; | ||
| private wraperFactory; | ||
| } | ||
| //#endregion | ||
| export { Module$1 as Module, ModuleOptions }; | ||
| export { Module$1 as Module, ModuleOptions, RemoteModuleFactory }; | ||
| //# sourceMappingURL=index.d.ts.map |
+160
-23
| import { assert, error } from "../utils/logger.js"; | ||
| import { getFMId, processModuleAlias } from "../utils/tool.js"; | ||
| import { processModuleAlias } from "../utils/tool.js"; | ||
| import { composeRemoteRequestId } from "../utils/manifest.js"; | ||
| import { getRemoteEntry } from "../utils/load.js"; | ||
@@ -7,5 +8,10 @@ import { optionsToMFContext } from "../utils/context.js"; | ||
| import { safeToString } from "@module-federation/sdk"; | ||
| import { RUNTIME_002, runtimeDescMap } from "@module-federation/error-codes"; | ||
| import { RUNTIME_002, RUNTIME_014, RUNTIME_015, runtimeDescMap } from "@module-federation/error-codes"; | ||
| //#region src/module/index.ts | ||
| function getAvailableExposeNames(remoteSnapshot) { | ||
| if (!remoteSnapshot || !("modules" in remoteSnapshot) || !Array.isArray(remoteSnapshot.modules)) return; | ||
| const exposes = remoteSnapshot.modules.map((module) => module.moduleName).filter(Boolean); | ||
| return exposes.length ? exposes.join(",") : void 0; | ||
| } | ||
| function createRemoteEntryInitOptions(remoteInfo, hostShareScopeMap, rawInitScope) { | ||
@@ -40,3 +46,3 @@ const localShareScopeMap = hostShareScopeMap; | ||
| } | ||
| async getEntry() { | ||
| async getEntry(expose) { | ||
| if (this.remoteEntryExports) return this.remoteEntryExports; | ||
@@ -46,3 +52,8 @@ const remoteEntryExports = await getRemoteEntry({ | ||
| remoteInfo: this.remoteInfo, | ||
| remoteEntryExports: this.remoteEntryExports | ||
| remoteEntryExports: this.remoteEntryExports, | ||
| resourceContext: { | ||
| initiator: "loadRemote", | ||
| id: composeRemoteRequestId(this.remoteInfo.name, expose), | ||
| resourceType: "remoteEntry" | ||
| } | ||
| }); | ||
@@ -53,7 +64,38 @@ assert(remoteEntryExports, `remoteEntryExports is undefined \n ${safeToString(this.remoteInfo)}`); | ||
| } | ||
| async init(id, remoteSnapshot, rawInitScope) { | ||
| const remoteEntryExports = await this.getEntry(); | ||
| if (this.inited) return remoteEntryExports; | ||
| async init(id, remoteSnapshot, rawInitScope, expose) { | ||
| const remoteEntryExports = await this.getEntry(expose); | ||
| if (this.inited) { | ||
| await this.host.loaderHook.lifecycle.afterInitRemote.emit({ | ||
| id, | ||
| remoteInfo: this.remoteInfo, | ||
| remoteSnapshot, | ||
| remoteEntryExports, | ||
| cached: true, | ||
| origin: this.host | ||
| }); | ||
| return remoteEntryExports; | ||
| } | ||
| if (this.initPromise) { | ||
| await this.initPromise; | ||
| try { | ||
| await this.initPromise; | ||
| await this.host.loaderHook.lifecycle.afterInitRemote.emit({ | ||
| id, | ||
| remoteInfo: this.remoteInfo, | ||
| remoteSnapshot, | ||
| remoteEntryExports, | ||
| cached: true, | ||
| origin: this.host | ||
| }); | ||
| } catch (initError) { | ||
| await this.host.loaderHook.lifecycle.afterInitRemote.emit({ | ||
| id, | ||
| remoteInfo: this.remoteInfo, | ||
| remoteSnapshot, | ||
| remoteEntryExports, | ||
| error: initError, | ||
| cached: true, | ||
| origin: this.host | ||
| }); | ||
| throw initError; | ||
| } | ||
| return remoteEntryExports; | ||
@@ -63,2 +105,8 @@ } | ||
| this.initPromise = (async () => { | ||
| await this.host.loaderHook.lifecycle.beforeInitRemote.emit({ | ||
| id, | ||
| remoteInfo: this.remoteInfo, | ||
| remoteSnapshot, | ||
| origin: this.host | ||
| }); | ||
| const { remoteEntryInitOptions, shareScope, initScope } = createRemoteEntryInitOptions(this.remoteInfo, this.host.shareScopeMap, rawInitScope); | ||
@@ -78,3 +126,13 @@ const initContainerOptions = await this.host.hooks.lifecycle.beforeInitContainer.emit({ | ||
| }, void 0, optionsToMFContext(this.host.options)); | ||
| await remoteEntryExports.init(initContainerOptions.shareScope, initContainerOptions.initScope, initContainerOptions.remoteEntryInitOptions); | ||
| try { | ||
| await remoteEntryExports.init(initContainerOptions.shareScope, initContainerOptions.initScope, initContainerOptions.remoteEntryInitOptions); | ||
| } catch (initError) { | ||
| error(RUNTIME_015, runtimeDescMap, { | ||
| hostName: this.host.name, | ||
| remoteName: this.remoteInfo.name, | ||
| remoteEntryUrl: this.remoteInfo.entry, | ||
| remoteEntryKey: this.remoteInfo.entryGlobalName, | ||
| shareScope: this.remoteInfo.shareScope | ||
| }, `${initError}`, optionsToMFContext(this.host.options)); | ||
| } | ||
| await this.host.hooks.lifecycle.initContainer.emit({ | ||
@@ -90,2 +148,19 @@ ...initContainerOptions, | ||
| await this.initPromise; | ||
| await this.host.loaderHook.lifecycle.afterInitRemote.emit({ | ||
| id, | ||
| remoteInfo: this.remoteInfo, | ||
| remoteSnapshot, | ||
| remoteEntryExports, | ||
| origin: this.host | ||
| }); | ||
| } catch (initError) { | ||
| await this.host.loaderHook.lifecycle.afterInitRemote.emit({ | ||
| id, | ||
| remoteInfo: this.remoteInfo, | ||
| remoteSnapshot, | ||
| remoteEntryExports, | ||
| error: initError, | ||
| origin: this.host | ||
| }); | ||
| throw initError; | ||
| } finally { | ||
@@ -99,16 +174,79 @@ this.initing = false; | ||
| const { loadFactory = true } = options || { loadFactory: true }; | ||
| const remoteEntryExports = await this.init(id, remoteSnapshot); | ||
| const remoteEntryExports = await this.init(id, remoteSnapshot, void 0, expose); | ||
| this.lib = remoteEntryExports; | ||
| let moduleFactory; | ||
| moduleFactory = await this.host.loaderHook.lifecycle.getModuleFactory.emit({ | ||
| await this.host.loaderHook.lifecycle.beforeGetExpose.emit({ | ||
| id, | ||
| expose, | ||
| moduleInfo: this.remoteInfo, | ||
| remoteEntryExports, | ||
| expose, | ||
| moduleInfo: this.remoteInfo | ||
| origin: this.host | ||
| }); | ||
| if (!moduleFactory) moduleFactory = await remoteEntryExports.get(expose); | ||
| assert(moduleFactory, `${getFMId(this.remoteInfo)} remote don't export ${expose}.`); | ||
| let moduleFactory; | ||
| try { | ||
| const hookModuleFactory = await this.host.loaderHook.lifecycle.getModuleFactory.emit({ | ||
| remoteEntryExports, | ||
| expose, | ||
| moduleInfo: this.remoteInfo | ||
| }); | ||
| moduleFactory = typeof hookModuleFactory === "function" ? hookModuleFactory : void 0; | ||
| if (!moduleFactory) moduleFactory = await remoteEntryExports.get(expose); | ||
| if (!moduleFactory) error(RUNTIME_014, runtimeDescMap, { | ||
| hostName: this.host.name, | ||
| remoteName: this.remoteInfo.name, | ||
| remoteEntryUrl: this.remoteInfo.entry, | ||
| expose, | ||
| requestId: id, | ||
| availableExposes: getAvailableExposeNames(remoteSnapshot) | ||
| }, void 0, optionsToMFContext(this.host.options)); | ||
| await this.host.loaderHook.lifecycle.afterGetExpose.emit({ | ||
| id, | ||
| expose, | ||
| moduleInfo: this.remoteInfo, | ||
| remoteEntryExports, | ||
| moduleFactory, | ||
| origin: this.host | ||
| }); | ||
| } catch (getExposeError) { | ||
| await this.host.loaderHook.lifecycle.afterGetExpose.emit({ | ||
| id, | ||
| expose, | ||
| moduleInfo: this.remoteInfo, | ||
| remoteEntryExports, | ||
| error: getExposeError, | ||
| origin: this.host | ||
| }); | ||
| throw getExposeError; | ||
| } | ||
| const symbolName = processModuleAlias(this.remoteInfo.name, expose); | ||
| const wrapModuleFactory = this.wraperFactory(moduleFactory, symbolName); | ||
| if (!loadFactory) return wrapModuleFactory; | ||
| return await wrapModuleFactory(); | ||
| await this.host.loaderHook.lifecycle.beforeExecuteFactory.emit({ | ||
| id, | ||
| expose, | ||
| moduleInfo: this.remoteInfo, | ||
| loadFactory, | ||
| origin: this.host | ||
| }); | ||
| try { | ||
| const exposeContent = await wrapModuleFactory(); | ||
| await this.host.loaderHook.lifecycle.afterExecuteFactory.emit({ | ||
| id, | ||
| expose, | ||
| moduleInfo: this.remoteInfo, | ||
| loadFactory, | ||
| exposeModule: exposeContent, | ||
| origin: this.host | ||
| }); | ||
| return exposeContent; | ||
| } catch (executeFactoryError) { | ||
| await this.host.loaderHook.lifecycle.afterExecuteFactory.emit({ | ||
| id, | ||
| expose, | ||
| moduleInfo: this.remoteInfo, | ||
| loadFactory, | ||
| error: executeFactoryError, | ||
| origin: this.host | ||
| }); | ||
| throw executeFactoryError; | ||
| } | ||
| } | ||
@@ -122,9 +260,8 @@ wraperFactory(moduleFactory, id) { | ||
| } | ||
| if (moduleFactory instanceof Promise) return async () => { | ||
| const res = await moduleFactory(); | ||
| defineModuleId(res, id); | ||
| return res; | ||
| }; | ||
| else return () => { | ||
| return () => { | ||
| const res = moduleFactory(); | ||
| if (res instanceof Promise) return res.then((asyncRes) => { | ||
| defineModuleId(asyncRes, id); | ||
| return asyncRes; | ||
| }); | ||
| defineModuleId(res, id); | ||
@@ -131,0 +268,0 @@ return res; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","names":["Module"],"sources":["../../src/module/index.ts"],"sourcesContent":["import {\n getFMId,\n assert,\n error,\n processModuleAlias,\n optionsToMFContext,\n} from '../utils';\nimport { safeToString, ModuleInfo } from '@module-federation/sdk';\nimport {\n RUNTIME_002,\n RUNTIME_008,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { getRemoteEntry } from '../utils/load';\nimport { ModuleFederation } from '../core';\nimport {\n RemoteEntryExports,\n RemoteInfo,\n InitScope,\n ShareScopeMap,\n} from '../type';\n\nexport type ModuleOptions = ConstructorParameters<typeof Module>[0];\n\nexport function createRemoteEntryInitOptions(\n remoteInfo: RemoteInfo,\n hostShareScopeMap: ShareScopeMap,\n rawInitScope?: InitScope,\n): Record<string, any> {\n const localShareScopeMap = hostShareScopeMap;\n\n const shareScopeKeys = Array.isArray(remoteInfo.shareScope)\n ? remoteInfo.shareScope\n : [remoteInfo.shareScope];\n\n if (!shareScopeKeys.length) {\n shareScopeKeys.push('default');\n }\n shareScopeKeys.forEach((shareScopeKey) => {\n if (!localShareScopeMap[shareScopeKey]) {\n localShareScopeMap[shareScopeKey] = {};\n }\n });\n\n const remoteEntryInitOptions = {\n version: remoteInfo.version || '',\n shareScopeKeys: Array.isArray(remoteInfo.shareScope)\n ? shareScopeKeys\n : remoteInfo.shareScope || 'default',\n };\n\n // Help to find host instance\n Object.defineProperty(remoteEntryInitOptions, 'shareScopeMap', {\n value: localShareScopeMap,\n // remoteEntryInitOptions will be traversed and assigned during container init, ,so this attribute is not allowed to be traversed\n enumerable: false,\n });\n\n // TODO: compate legacy init params, should use shareScopeMap if exist\n const shareScope = localShareScopeMap[shareScopeKeys[0]];\n const initScope: InitScope = rawInitScope ?? [];\n\n return {\n remoteEntryInitOptions,\n shareScope,\n initScope,\n };\n}\n\nclass Module {\n remoteInfo: RemoteInfo;\n inited = false;\n initing = false;\n initPromise?: Promise<void>;\n remoteEntryExports?: RemoteEntryExports;\n lib: RemoteEntryExports | undefined = undefined;\n host: ModuleFederation;\n\n constructor({\n remoteInfo,\n host,\n }: {\n remoteInfo: RemoteInfo;\n host: ModuleFederation;\n }) {\n this.remoteInfo = remoteInfo;\n this.host = host;\n }\n\n async getEntry(): Promise<RemoteEntryExports> {\n if (this.remoteEntryExports) {\n return this.remoteEntryExports;\n }\n\n const remoteEntryExports = await getRemoteEntry({\n origin: this.host,\n remoteInfo: this.remoteInfo,\n remoteEntryExports: this.remoteEntryExports,\n });\n\n assert(\n remoteEntryExports,\n `remoteEntryExports is undefined \\n ${safeToString(this.remoteInfo)}`,\n );\n\n this.remoteEntryExports = remoteEntryExports;\n return this.remoteEntryExports;\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n\n async init(\n id?: string,\n remoteSnapshot?: ModuleInfo,\n rawInitScope?: InitScope,\n ) {\n // Get remoteEntry.js\n const remoteEntryExports = await this.getEntry();\n\n if (this.inited) {\n return remoteEntryExports;\n }\n\n if (this.initPromise) {\n await this.initPromise;\n return remoteEntryExports;\n }\n\n this.initing = true;\n this.initPromise = (async () => {\n const { remoteEntryInitOptions, shareScope, initScope } =\n createRemoteEntryInitOptions(\n this.remoteInfo,\n this.host.shareScopeMap,\n rawInitScope,\n );\n\n const initContainerOptions =\n await this.host.hooks.lifecycle.beforeInitContainer.emit({\n shareScope,\n // @ts-ignore shareScopeMap will be set by Object.defineProperty\n remoteEntryInitOptions,\n initScope,\n remoteInfo: this.remoteInfo,\n origin: this.host,\n });\n\n if (typeof remoteEntryExports?.init === 'undefined') {\n error(\n RUNTIME_002,\n runtimeDescMap,\n {\n hostName: this.host.name,\n remoteName: this.remoteInfo.name,\n remoteEntryUrl: this.remoteInfo.entry,\n remoteEntryKey: this.remoteInfo.entryGlobalName,\n },\n undefined,\n optionsToMFContext(this.host.options),\n );\n }\n\n await remoteEntryExports.init(\n initContainerOptions.shareScope,\n initContainerOptions.initScope,\n initContainerOptions.remoteEntryInitOptions,\n );\n\n await this.host.hooks.lifecycle.initContainer.emit({\n ...initContainerOptions,\n id,\n remoteSnapshot,\n remoteEntryExports,\n });\n this.inited = true;\n })();\n\n try {\n await this.initPromise;\n } finally {\n this.initing = false;\n this.initPromise = undefined;\n }\n\n return remoteEntryExports;\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n async get(\n id: string,\n expose: string,\n options?: { loadFactory?: boolean },\n remoteSnapshot?: ModuleInfo,\n ) {\n const { loadFactory = true } = options || { loadFactory: true };\n\n const remoteEntryExports = await this.init(id, remoteSnapshot);\n this.lib = remoteEntryExports;\n\n let moduleFactory;\n moduleFactory = await this.host.loaderHook.lifecycle.getModuleFactory.emit({\n remoteEntryExports,\n expose,\n moduleInfo: this.remoteInfo,\n });\n\n // get exposeGetter\n if (!moduleFactory) {\n moduleFactory = await remoteEntryExports.get(expose);\n }\n\n assert(\n moduleFactory,\n `${getFMId(this.remoteInfo)} remote don't export ${expose}.`,\n );\n\n // keep symbol for module name always one format\n const symbolName = processModuleAlias(this.remoteInfo.name, expose);\n const wrapModuleFactory = this.wraperFactory(moduleFactory, symbolName);\n\n if (!loadFactory) {\n return wrapModuleFactory;\n }\n const exposeContent = await wrapModuleFactory();\n\n return exposeContent;\n }\n\n private wraperFactory(\n moduleFactory: () => any | (() => Promise<any>),\n id: string,\n ) {\n function defineModuleId(res: any, id: string) {\n if (\n res &&\n typeof res === 'object' &&\n Object.isExtensible(res) &&\n !Object.getOwnPropertyDescriptor(res, Symbol.for('mf_module_id'))\n ) {\n Object.defineProperty(res, Symbol.for('mf_module_id'), {\n value: id,\n enumerable: false,\n });\n }\n }\n\n if (moduleFactory instanceof Promise) {\n return async () => {\n const res = await moduleFactory();\n // This parameter is used for bridge debugging\n defineModuleId(res, id);\n return res;\n };\n } else {\n return () => {\n const res = moduleFactory();\n // This parameter is used for bridge debugging\n defineModuleId(res, id);\n return res;\n };\n }\n }\n}\n\nexport { Module };\n"],"mappings":"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"} | ||
| {"version":3,"file":"index.js","names":["Module"],"sources":["../../src/module/index.ts"],"sourcesContent":["import {\n assert,\n error,\n processModuleAlias,\n optionsToMFContext,\n composeRemoteRequestId,\n} from '../utils';\nimport { safeToString, ModuleInfo } from '@module-federation/sdk';\nimport {\n RUNTIME_002,\n RUNTIME_014,\n RUNTIME_015,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { getRemoteEntry } from '../utils/load';\nimport { ModuleFederation } from '../core';\nimport {\n RemoteEntryExports,\n RemoteInfo,\n InitScope,\n ShareScopeMap,\n} from '../type';\n\nexport type ModuleOptions = ConstructorParameters<typeof Module>[0];\nexport type RemoteModuleFactory = () => unknown | Promise<unknown>;\n\nfunction getAvailableExposeNames(\n remoteSnapshot?: ModuleInfo,\n): string | undefined {\n if (\n !remoteSnapshot ||\n !('modules' in remoteSnapshot) ||\n !Array.isArray(remoteSnapshot.modules)\n ) {\n return undefined;\n }\n\n const exposes = remoteSnapshot.modules\n .map((module) => module.moduleName)\n .filter(Boolean);\n\n return exposes.length ? exposes.join(',') : undefined;\n}\n\nexport function createRemoteEntryInitOptions(\n remoteInfo: RemoteInfo,\n hostShareScopeMap: ShareScopeMap,\n rawInitScope?: InitScope,\n): Record<string, any> {\n const localShareScopeMap = hostShareScopeMap;\n\n const shareScopeKeys = Array.isArray(remoteInfo.shareScope)\n ? remoteInfo.shareScope\n : [remoteInfo.shareScope];\n\n if (!shareScopeKeys.length) {\n shareScopeKeys.push('default');\n }\n shareScopeKeys.forEach((shareScopeKey) => {\n if (!localShareScopeMap[shareScopeKey]) {\n localShareScopeMap[shareScopeKey] = {};\n }\n });\n\n const remoteEntryInitOptions = {\n version: remoteInfo.version || '',\n shareScopeKeys: Array.isArray(remoteInfo.shareScope)\n ? shareScopeKeys\n : remoteInfo.shareScope || 'default',\n };\n\n // Help to find host instance\n Object.defineProperty(remoteEntryInitOptions, 'shareScopeMap', {\n value: localShareScopeMap,\n // remoteEntryInitOptions will be traversed and assigned during container init, ,so this attribute is not allowed to be traversed\n enumerable: false,\n });\n\n // TODO: compate legacy init params, should use shareScopeMap if exist\n const shareScope = localShareScopeMap[shareScopeKeys[0]];\n const initScope: InitScope = rawInitScope ?? [];\n\n return {\n remoteEntryInitOptions,\n shareScope,\n initScope,\n };\n}\n\nclass Module {\n remoteInfo: RemoteInfo;\n inited = false;\n initing = false;\n initPromise?: Promise<void>;\n remoteEntryExports?: RemoteEntryExports;\n lib: RemoteEntryExports | undefined = undefined;\n host: ModuleFederation;\n\n constructor({\n remoteInfo,\n host,\n }: {\n remoteInfo: RemoteInfo;\n host: ModuleFederation;\n }) {\n this.remoteInfo = remoteInfo;\n this.host = host;\n }\n\n async getEntry(expose?: string): Promise<RemoteEntryExports> {\n if (this.remoteEntryExports) {\n return this.remoteEntryExports;\n }\n\n const remoteEntryExports = await getRemoteEntry({\n origin: this.host,\n remoteInfo: this.remoteInfo,\n remoteEntryExports: this.remoteEntryExports,\n resourceContext: {\n initiator: 'loadRemote',\n id: composeRemoteRequestId(this.remoteInfo.name, expose),\n resourceType: 'remoteEntry',\n },\n });\n\n assert(\n remoteEntryExports,\n `remoteEntryExports is undefined \\n ${safeToString(this.remoteInfo)}`,\n );\n\n this.remoteEntryExports = remoteEntryExports;\n return this.remoteEntryExports;\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n\n async init(\n id?: string,\n remoteSnapshot?: ModuleInfo,\n rawInitScope?: InitScope,\n expose?: string,\n ) {\n // Get remoteEntry.js\n const remoteEntryExports = await this.getEntry(expose);\n\n if (this.inited) {\n await this.host.loaderHook.lifecycle.afterInitRemote.emit({\n id,\n remoteInfo: this.remoteInfo,\n remoteSnapshot,\n remoteEntryExports,\n cached: true,\n origin: this.host,\n });\n return remoteEntryExports;\n }\n\n if (this.initPromise) {\n try {\n await this.initPromise;\n await this.host.loaderHook.lifecycle.afterInitRemote.emit({\n id,\n remoteInfo: this.remoteInfo,\n remoteSnapshot,\n remoteEntryExports,\n cached: true,\n origin: this.host,\n });\n } catch (initError) {\n await this.host.loaderHook.lifecycle.afterInitRemote.emit({\n id,\n remoteInfo: this.remoteInfo,\n remoteSnapshot,\n remoteEntryExports,\n error: initError,\n cached: true,\n origin: this.host,\n });\n throw initError;\n }\n return remoteEntryExports;\n }\n\n this.initing = true;\n this.initPromise = (async () => {\n await this.host.loaderHook.lifecycle.beforeInitRemote.emit({\n id,\n remoteInfo: this.remoteInfo,\n remoteSnapshot,\n origin: this.host,\n });\n\n const { remoteEntryInitOptions, shareScope, initScope } =\n createRemoteEntryInitOptions(\n this.remoteInfo,\n this.host.shareScopeMap,\n rawInitScope,\n );\n\n const initContainerOptions =\n await this.host.hooks.lifecycle.beforeInitContainer.emit({\n shareScope,\n // @ts-ignore shareScopeMap will be set by Object.defineProperty\n remoteEntryInitOptions,\n initScope,\n remoteInfo: this.remoteInfo,\n origin: this.host,\n });\n\n if (typeof remoteEntryExports?.init === 'undefined') {\n error(\n RUNTIME_002,\n runtimeDescMap,\n {\n hostName: this.host.name,\n remoteName: this.remoteInfo.name,\n remoteEntryUrl: this.remoteInfo.entry,\n remoteEntryKey: this.remoteInfo.entryGlobalName,\n },\n undefined,\n optionsToMFContext(this.host.options),\n );\n }\n\n try {\n await remoteEntryExports.init(\n initContainerOptions.shareScope,\n initContainerOptions.initScope,\n initContainerOptions.remoteEntryInitOptions,\n );\n } catch (initError) {\n error(\n RUNTIME_015,\n runtimeDescMap,\n {\n hostName: this.host.name,\n remoteName: this.remoteInfo.name,\n remoteEntryUrl: this.remoteInfo.entry,\n remoteEntryKey: this.remoteInfo.entryGlobalName,\n shareScope: this.remoteInfo.shareScope,\n },\n `${initError}`,\n optionsToMFContext(this.host.options),\n );\n }\n\n await this.host.hooks.lifecycle.initContainer.emit({\n ...initContainerOptions,\n id,\n remoteSnapshot,\n remoteEntryExports,\n });\n this.inited = true;\n })();\n\n try {\n await this.initPromise;\n await this.host.loaderHook.lifecycle.afterInitRemote.emit({\n id,\n remoteInfo: this.remoteInfo,\n remoteSnapshot,\n remoteEntryExports,\n origin: this.host,\n });\n } catch (initError) {\n await this.host.loaderHook.lifecycle.afterInitRemote.emit({\n id,\n remoteInfo: this.remoteInfo,\n remoteSnapshot,\n remoteEntryExports,\n error: initError,\n origin: this.host,\n });\n throw initError;\n } finally {\n this.initing = false;\n this.initPromise = undefined;\n }\n\n return remoteEntryExports;\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n async get(\n id: string,\n expose: string,\n options?: { loadFactory?: boolean },\n remoteSnapshot?: ModuleInfo,\n ) {\n const { loadFactory = true } = options || { loadFactory: true };\n\n const remoteEntryExports = await this.init(\n id,\n remoteSnapshot,\n undefined,\n expose,\n );\n this.lib = remoteEntryExports;\n\n await this.host.loaderHook.lifecycle.beforeGetExpose.emit({\n id,\n expose,\n moduleInfo: this.remoteInfo,\n remoteEntryExports,\n origin: this.host,\n });\n\n let moduleFactory: RemoteModuleFactory | undefined;\n try {\n const hookModuleFactory =\n await this.host.loaderHook.lifecycle.getModuleFactory.emit({\n remoteEntryExports,\n expose,\n moduleInfo: this.remoteInfo,\n });\n moduleFactory =\n typeof hookModuleFactory === 'function' ? hookModuleFactory : undefined;\n\n // get exposeGetter\n if (!moduleFactory) {\n moduleFactory = await remoteEntryExports.get(expose);\n }\n\n if (!moduleFactory) {\n error(\n RUNTIME_014,\n runtimeDescMap,\n {\n hostName: this.host.name,\n remoteName: this.remoteInfo.name,\n remoteEntryUrl: this.remoteInfo.entry,\n expose,\n requestId: id,\n availableExposes: getAvailableExposeNames(remoteSnapshot),\n },\n undefined,\n optionsToMFContext(this.host.options),\n );\n }\n\n await this.host.loaderHook.lifecycle.afterGetExpose.emit({\n id,\n expose,\n moduleInfo: this.remoteInfo,\n remoteEntryExports,\n moduleFactory,\n origin: this.host,\n });\n } catch (getExposeError) {\n await this.host.loaderHook.lifecycle.afterGetExpose.emit({\n id,\n expose,\n moduleInfo: this.remoteInfo,\n remoteEntryExports,\n error: getExposeError,\n origin: this.host,\n });\n throw getExposeError;\n }\n\n // keep symbol for module name always one format\n const symbolName = processModuleAlias(this.remoteInfo.name, expose);\n const wrapModuleFactory = this.wraperFactory(moduleFactory, symbolName);\n\n if (!loadFactory) {\n return wrapModuleFactory;\n }\n\n await this.host.loaderHook.lifecycle.beforeExecuteFactory.emit({\n id,\n expose,\n moduleInfo: this.remoteInfo,\n loadFactory,\n origin: this.host,\n });\n\n try {\n const exposeContent = await wrapModuleFactory();\n\n await this.host.loaderHook.lifecycle.afterExecuteFactory.emit({\n id,\n expose,\n moduleInfo: this.remoteInfo,\n loadFactory,\n exposeModule: exposeContent,\n origin: this.host,\n });\n\n return exposeContent;\n } catch (executeFactoryError) {\n await this.host.loaderHook.lifecycle.afterExecuteFactory.emit({\n id,\n expose,\n moduleInfo: this.remoteInfo,\n loadFactory,\n error: executeFactoryError,\n origin: this.host,\n });\n throw executeFactoryError;\n }\n }\n\n private wraperFactory(moduleFactory: RemoteModuleFactory, id: string) {\n function defineModuleId(res: unknown, id: string) {\n if (\n res &&\n typeof res === 'object' &&\n Object.isExtensible(res) &&\n !Object.getOwnPropertyDescriptor(res, Symbol.for('mf_module_id'))\n ) {\n Object.defineProperty(res, Symbol.for('mf_module_id'), {\n value: id,\n enumerable: false,\n });\n }\n }\n\n return () => {\n const res = moduleFactory();\n\n if (res instanceof Promise) {\n return res.then((asyncRes) => {\n // This parameter is used for bridge debugging\n defineModuleId(asyncRes, id);\n return asyncRes;\n });\n }\n\n // This parameter is used for bridge debugging\n defineModuleId(res, id);\n return res;\n };\n }\n}\n\nexport { Module };\n"],"mappings":"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"} |
| const require_logger = require('../../utils/logger.cjs'); | ||
| const require_tool = require('../../utils/tool.cjs'); | ||
| const require_manifest = require('../../utils/manifest.cjs'); | ||
| require('../../utils/index.cjs'); | ||
@@ -28,3 +29,3 @@ const require_preload = require('../../utils/preload.cjs'); | ||
| moduleInfo: remote, | ||
| id | ||
| id: require_manifest.composeRemoteRequestId(remote.name, expose) | ||
| }); | ||
@@ -50,3 +51,6 @@ assignRemoteInfo(remoteInfo, remoteSnapshot); | ||
| }); | ||
| if (assets) require_preload.preloadAssets(remoteInfo, origin, assets, false); | ||
| if (assets) require_preload.preloadAssets(remoteInfo, origin, assets, false, { | ||
| initiator: "loadRemote", | ||
| id | ||
| }).catch(() => void 0); | ||
| return { | ||
@@ -53,0 +57,0 @@ ...args, |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.cjs","names":["getRemoteEntryInfoFromSnapshot","RUNTIME_011","runtimeDescMap","isBrowserEnvValue","isRemoteInfoWithEntry","isPureRemoteEntry"],"sources":["../../../src/plugins/snapshot/index.ts"],"sourcesContent":["import {\n ModuleInfo,\n getResourceUrl,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport { ModuleFederationRuntimePlugin } from '../../type/plugin';\nimport { RUNTIME_011, runtimeDescMap } from '@module-federation/error-codes';\nimport {\n error,\n isPureRemoteEntry,\n isRemoteInfoWithEntry,\n getRemoteEntryInfoFromSnapshot,\n} from '../../utils';\nimport { PreloadOptions, RemoteInfo } from '../../type';\nimport { preloadAssets } from '../../utils/preload';\n\nexport function assignRemoteInfo(\n remoteInfo: RemoteInfo,\n remoteSnapshot: ModuleInfo,\n): void {\n const remoteEntryInfo = getRemoteEntryInfoFromSnapshot(remoteSnapshot);\n if (!remoteEntryInfo.url) {\n error(RUNTIME_011, runtimeDescMap, { remoteName: remoteInfo.name });\n }\n\n let entryUrl = getResourceUrl(remoteSnapshot, remoteEntryInfo.url);\n\n if (!isBrowserEnvValue && !entryUrl.startsWith('http')) {\n entryUrl = `https:${entryUrl}`;\n }\n\n remoteInfo.type = remoteEntryInfo.type;\n remoteInfo.entryGlobalName = remoteEntryInfo.globalName;\n remoteInfo.entry = entryUrl;\n remoteInfo.version = remoteSnapshot.version;\n remoteInfo.buildVersion = remoteSnapshot.buildVersion;\n}\n\nexport function snapshotPlugin(): ModuleFederationRuntimePlugin {\n return {\n name: 'snapshot-plugin',\n async afterResolve(args) {\n const { remote, pkgNameOrAlias, expose, origin, remoteInfo, id } = args;\n\n if (!isRemoteInfoWithEntry(remote) || !isPureRemoteEntry(remote)) {\n const { remoteSnapshot, globalSnapshot } =\n await origin.snapshotHandler.loadRemoteSnapshotInfo({\n moduleInfo: remote,\n id,\n });\n\n assignRemoteInfo(remoteInfo, remoteSnapshot);\n // preloading assets\n const preloadOptions: PreloadOptions[0] = {\n remote,\n preloadConfig: {\n nameOrAlias: pkgNameOrAlias,\n exposes: [expose],\n resourceCategory: 'sync',\n share: false,\n depsRemote: false,\n },\n };\n\n const assets =\n await origin.remoteHandler.hooks.lifecycle.generatePreloadAssets.emit(\n {\n origin,\n preloadOptions,\n remoteInfo,\n remote,\n remoteSnapshot,\n globalSnapshot,\n },\n );\n\n if (assets) {\n preloadAssets(remoteInfo, origin, assets, false);\n }\n\n return {\n ...args,\n remoteSnapshot,\n };\n }\n\n return args;\n },\n };\n}\n"],"mappings":";;;;;;;;AAgBA,SAAgB,iBACd,YACA,gBACM;CACN,MAAM,kBAAkBA,4CAA+B,eAAe;AACtE,KAAI,CAAC,gBAAgB,IACnB,sBAAMC,4CAAaC,+CAAgB,EAAE,YAAY,WAAW,MAAM,CAAC;CAGrE,IAAI,sDAA0B,gBAAgB,gBAAgB,IAAI;AAElE,KAAI,CAACC,4CAAqB,CAAC,SAAS,WAAW,OAAO,CACpD,YAAW,SAAS;AAGtB,YAAW,OAAO,gBAAgB;AAClC,YAAW,kBAAkB,gBAAgB;AAC7C,YAAW,QAAQ;AACnB,YAAW,UAAU,eAAe;AACpC,YAAW,eAAe,eAAe;;AAG3C,SAAgB,iBAAgD;AAC9D,QAAO;EACL,MAAM;EACN,MAAM,aAAa,MAAM;GACvB,MAAM,EAAE,QAAQ,gBAAgB,QAAQ,QAAQ,YAAY,OAAO;AAEnE,OAAI,CAACC,mCAAsB,OAAO,IAAI,CAACC,+BAAkB,OAAO,EAAE;IAChE,MAAM,EAAE,gBAAgB,mBACtB,MAAM,OAAO,gBAAgB,uBAAuB;KAClD,YAAY;KACZ;KACD,CAAC;AAEJ,qBAAiB,YAAY,eAAe;IAE5C,MAAM,iBAAoC;KACxC;KACA,eAAe;MACb,aAAa;MACb,SAAS,CAAC,OAAO;MACjB,kBAAkB;MAClB,OAAO;MACP,YAAY;MACb;KACF;IAED,MAAM,SACJ,MAAM,OAAO,cAAc,MAAM,UAAU,sBAAsB,KAC/D;KACE;KACA;KACA;KACA;KACA;KACA;KACD,CACF;AAEH,QAAI,OACF,+BAAc,YAAY,QAAQ,QAAQ,MAAM;AAGlD,WAAO;KACL,GAAG;KACH;KACD;;AAGH,UAAO;;EAEV"} | ||
| {"version":3,"file":"index.cjs","names":["getRemoteEntryInfoFromSnapshot","RUNTIME_011","runtimeDescMap","isBrowserEnvValue","isRemoteInfoWithEntry","isPureRemoteEntry","composeRemoteRequestId"],"sources":["../../../src/plugins/snapshot/index.ts"],"sourcesContent":["import {\n ModuleInfo,\n getResourceUrl,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport { ModuleFederationRuntimePlugin } from '../../type/plugin';\nimport { RUNTIME_011, runtimeDescMap } from '@module-federation/error-codes';\nimport {\n error,\n composeRemoteRequestId,\n isPureRemoteEntry,\n isRemoteInfoWithEntry,\n getRemoteEntryInfoFromSnapshot,\n} from '../../utils';\nimport { PreloadOptions, RemoteInfo } from '../../type';\nimport { preloadAssets } from '../../utils/preload';\n\nexport function assignRemoteInfo(\n remoteInfo: RemoteInfo,\n remoteSnapshot: ModuleInfo,\n): void {\n const remoteEntryInfo = getRemoteEntryInfoFromSnapshot(remoteSnapshot);\n if (!remoteEntryInfo.url) {\n error(RUNTIME_011, runtimeDescMap, { remoteName: remoteInfo.name });\n }\n\n let entryUrl = getResourceUrl(remoteSnapshot, remoteEntryInfo.url);\n\n if (!isBrowserEnvValue && !entryUrl.startsWith('http')) {\n entryUrl = `https:${entryUrl}`;\n }\n\n remoteInfo.type = remoteEntryInfo.type;\n remoteInfo.entryGlobalName = remoteEntryInfo.globalName;\n remoteInfo.entry = entryUrl;\n remoteInfo.version = remoteSnapshot.version;\n remoteInfo.buildVersion = remoteSnapshot.buildVersion;\n}\n\nexport function snapshotPlugin(): ModuleFederationRuntimePlugin {\n return {\n name: 'snapshot-plugin',\n async afterResolve(args) {\n const { remote, pkgNameOrAlias, expose, origin, remoteInfo, id } = args;\n\n if (!isRemoteInfoWithEntry(remote) || !isPureRemoteEntry(remote)) {\n const { remoteSnapshot, globalSnapshot } =\n await origin.snapshotHandler.loadRemoteSnapshotInfo({\n moduleInfo: remote,\n id: composeRemoteRequestId(remote.name, expose),\n });\n\n assignRemoteInfo(remoteInfo, remoteSnapshot);\n // preloading assets\n const preloadOptions: PreloadOptions[0] = {\n remote,\n preloadConfig: {\n nameOrAlias: pkgNameOrAlias,\n exposes: [expose],\n resourceCategory: 'sync',\n share: false,\n depsRemote: false,\n },\n };\n\n const assets =\n await origin.remoteHandler.hooks.lifecycle.generatePreloadAssets.emit(\n {\n origin,\n preloadOptions,\n remoteInfo,\n remote,\n remoteSnapshot,\n globalSnapshot,\n },\n );\n\n if (assets) {\n preloadAssets(remoteInfo, origin, assets, false, {\n initiator: 'loadRemote',\n id,\n }).catch(() => undefined);\n }\n\n return {\n ...args,\n remoteSnapshot,\n };\n }\n\n return args;\n },\n };\n}\n"],"mappings":";;;;;;;;;AAiBA,SAAgB,iBACd,YACA,gBACM;CACN,MAAM,kBAAkBA,4CAA+B,eAAe;AACtE,KAAI,CAAC,gBAAgB,IACnB,sBAAMC,4CAAaC,+CAAgB,EAAE,YAAY,WAAW,MAAM,CAAC;CAGrE,IAAI,sDAA0B,gBAAgB,gBAAgB,IAAI;AAElE,KAAI,CAACC,4CAAqB,CAAC,SAAS,WAAW,OAAO,CACpD,YAAW,SAAS;AAGtB,YAAW,OAAO,gBAAgB;AAClC,YAAW,kBAAkB,gBAAgB;AAC7C,YAAW,QAAQ;AACnB,YAAW,UAAU,eAAe;AACpC,YAAW,eAAe,eAAe;;AAG3C,SAAgB,iBAAgD;AAC9D,QAAO;EACL,MAAM;EACN,MAAM,aAAa,MAAM;GACvB,MAAM,EAAE,QAAQ,gBAAgB,QAAQ,QAAQ,YAAY,OAAO;AAEnE,OAAI,CAACC,mCAAsB,OAAO,IAAI,CAACC,+BAAkB,OAAO,EAAE;IAChE,MAAM,EAAE,gBAAgB,mBACtB,MAAM,OAAO,gBAAgB,uBAAuB;KAClD,YAAY;KACZ,IAAIC,wCAAuB,OAAO,MAAM,OAAO;KAChD,CAAC;AAEJ,qBAAiB,YAAY,eAAe;IAE5C,MAAM,iBAAoC;KACxC;KACA,eAAe;MACb,aAAa;MACb,SAAS,CAAC,OAAO;MACjB,kBAAkB;MAClB,OAAO;MACP,YAAY;MACb;KACF;IAED,MAAM,SACJ,MAAM,OAAO,cAAc,MAAM,UAAU,sBAAsB,KAC/D;KACE;KACA;KACA;KACA;KACA;KACA;KACD,CACF;AAEH,QAAI,OACF,+BAAc,YAAY,QAAQ,QAAQ,OAAO;KAC/C,WAAW;KACX;KACD,CAAC,CAAC,YAAY,OAAU;AAG3B,WAAO;KACL,GAAG;KACH;KACD;;AAGH,UAAO;;EAEV"} |
| import { error } from "../../utils/logger.js"; | ||
| import { getRemoteEntryInfoFromSnapshot, isPureRemoteEntry, isRemoteInfoWithEntry } from "../../utils/tool.js"; | ||
| import { composeRemoteRequestId } from "../../utils/manifest.js"; | ||
| import "../../utils/index.js"; | ||
@@ -28,3 +29,3 @@ import { preloadAssets } from "../../utils/preload.js"; | ||
| moduleInfo: remote, | ||
| id | ||
| id: composeRemoteRequestId(remote.name, expose) | ||
| }); | ||
@@ -50,3 +51,6 @@ assignRemoteInfo(remoteInfo, remoteSnapshot); | ||
| }); | ||
| if (assets) preloadAssets(remoteInfo, origin, assets, false); | ||
| if (assets) preloadAssets(remoteInfo, origin, assets, false, { | ||
| initiator: "loadRemote", | ||
| id | ||
| }).catch(() => void 0); | ||
| return { | ||
@@ -53,0 +57,0 @@ ...args, |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","names":[],"sources":["../../../src/plugins/snapshot/index.ts"],"sourcesContent":["import {\n ModuleInfo,\n getResourceUrl,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport { ModuleFederationRuntimePlugin } from '../../type/plugin';\nimport { RUNTIME_011, runtimeDescMap } from '@module-federation/error-codes';\nimport {\n error,\n isPureRemoteEntry,\n isRemoteInfoWithEntry,\n getRemoteEntryInfoFromSnapshot,\n} from '../../utils';\nimport { PreloadOptions, RemoteInfo } from '../../type';\nimport { preloadAssets } from '../../utils/preload';\n\nexport function assignRemoteInfo(\n remoteInfo: RemoteInfo,\n remoteSnapshot: ModuleInfo,\n): void {\n const remoteEntryInfo = getRemoteEntryInfoFromSnapshot(remoteSnapshot);\n if (!remoteEntryInfo.url) {\n error(RUNTIME_011, runtimeDescMap, { remoteName: remoteInfo.name });\n }\n\n let entryUrl = getResourceUrl(remoteSnapshot, remoteEntryInfo.url);\n\n if (!isBrowserEnvValue && !entryUrl.startsWith('http')) {\n entryUrl = `https:${entryUrl}`;\n }\n\n remoteInfo.type = remoteEntryInfo.type;\n remoteInfo.entryGlobalName = remoteEntryInfo.globalName;\n remoteInfo.entry = entryUrl;\n remoteInfo.version = remoteSnapshot.version;\n remoteInfo.buildVersion = remoteSnapshot.buildVersion;\n}\n\nexport function snapshotPlugin(): ModuleFederationRuntimePlugin {\n return {\n name: 'snapshot-plugin',\n async afterResolve(args) {\n const { remote, pkgNameOrAlias, expose, origin, remoteInfo, id } = args;\n\n if (!isRemoteInfoWithEntry(remote) || !isPureRemoteEntry(remote)) {\n const { remoteSnapshot, globalSnapshot } =\n await origin.snapshotHandler.loadRemoteSnapshotInfo({\n moduleInfo: remote,\n id,\n });\n\n assignRemoteInfo(remoteInfo, remoteSnapshot);\n // preloading assets\n const preloadOptions: PreloadOptions[0] = {\n remote,\n preloadConfig: {\n nameOrAlias: pkgNameOrAlias,\n exposes: [expose],\n resourceCategory: 'sync',\n share: false,\n depsRemote: false,\n },\n };\n\n const assets =\n await origin.remoteHandler.hooks.lifecycle.generatePreloadAssets.emit(\n {\n origin,\n preloadOptions,\n remoteInfo,\n remote,\n remoteSnapshot,\n globalSnapshot,\n },\n );\n\n if (assets) {\n preloadAssets(remoteInfo, origin, assets, false);\n }\n\n return {\n ...args,\n remoteSnapshot,\n };\n }\n\n return args;\n },\n };\n}\n"],"mappings":";;;;;;;;AAgBA,SAAgB,iBACd,YACA,gBACM;CACN,MAAM,kBAAkB,+BAA+B,eAAe;AACtE,KAAI,CAAC,gBAAgB,IACnB,OAAM,aAAa,gBAAgB,EAAE,YAAY,WAAW,MAAM,CAAC;CAGrE,IAAI,WAAW,eAAe,gBAAgB,gBAAgB,IAAI;AAElE,KAAI,CAAC,qBAAqB,CAAC,SAAS,WAAW,OAAO,CACpD,YAAW,SAAS;AAGtB,YAAW,OAAO,gBAAgB;AAClC,YAAW,kBAAkB,gBAAgB;AAC7C,YAAW,QAAQ;AACnB,YAAW,UAAU,eAAe;AACpC,YAAW,eAAe,eAAe;;AAG3C,SAAgB,iBAAgD;AAC9D,QAAO;EACL,MAAM;EACN,MAAM,aAAa,MAAM;GACvB,MAAM,EAAE,QAAQ,gBAAgB,QAAQ,QAAQ,YAAY,OAAO;AAEnE,OAAI,CAAC,sBAAsB,OAAO,IAAI,CAAC,kBAAkB,OAAO,EAAE;IAChE,MAAM,EAAE,gBAAgB,mBACtB,MAAM,OAAO,gBAAgB,uBAAuB;KAClD,YAAY;KACZ;KACD,CAAC;AAEJ,qBAAiB,YAAY,eAAe;IAE5C,MAAM,iBAAoC;KACxC;KACA,eAAe;MACb,aAAa;MACb,SAAS,CAAC,OAAO;MACjB,kBAAkB;MAClB,OAAO;MACP,YAAY;MACb;KACF;IAED,MAAM,SACJ,MAAM,OAAO,cAAc,MAAM,UAAU,sBAAsB,KAC/D;KACE;KACA;KACA;KACA;KACA;KACA;KACD,CACF;AAEH,QAAI,OACF,eAAc,YAAY,QAAQ,QAAQ,MAAM;AAGlD,WAAO;KACL,GAAG;KACH;KACD;;AAGH,UAAO;;EAEV"} | ||
| {"version":3,"file":"index.js","names":[],"sources":["../../../src/plugins/snapshot/index.ts"],"sourcesContent":["import {\n ModuleInfo,\n getResourceUrl,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport { ModuleFederationRuntimePlugin } from '../../type/plugin';\nimport { RUNTIME_011, runtimeDescMap } from '@module-federation/error-codes';\nimport {\n error,\n composeRemoteRequestId,\n isPureRemoteEntry,\n isRemoteInfoWithEntry,\n getRemoteEntryInfoFromSnapshot,\n} from '../../utils';\nimport { PreloadOptions, RemoteInfo } from '../../type';\nimport { preloadAssets } from '../../utils/preload';\n\nexport function assignRemoteInfo(\n remoteInfo: RemoteInfo,\n remoteSnapshot: ModuleInfo,\n): void {\n const remoteEntryInfo = getRemoteEntryInfoFromSnapshot(remoteSnapshot);\n if (!remoteEntryInfo.url) {\n error(RUNTIME_011, runtimeDescMap, { remoteName: remoteInfo.name });\n }\n\n let entryUrl = getResourceUrl(remoteSnapshot, remoteEntryInfo.url);\n\n if (!isBrowserEnvValue && !entryUrl.startsWith('http')) {\n entryUrl = `https:${entryUrl}`;\n }\n\n remoteInfo.type = remoteEntryInfo.type;\n remoteInfo.entryGlobalName = remoteEntryInfo.globalName;\n remoteInfo.entry = entryUrl;\n remoteInfo.version = remoteSnapshot.version;\n remoteInfo.buildVersion = remoteSnapshot.buildVersion;\n}\n\nexport function snapshotPlugin(): ModuleFederationRuntimePlugin {\n return {\n name: 'snapshot-plugin',\n async afterResolve(args) {\n const { remote, pkgNameOrAlias, expose, origin, remoteInfo, id } = args;\n\n if (!isRemoteInfoWithEntry(remote) || !isPureRemoteEntry(remote)) {\n const { remoteSnapshot, globalSnapshot } =\n await origin.snapshotHandler.loadRemoteSnapshotInfo({\n moduleInfo: remote,\n id: composeRemoteRequestId(remote.name, expose),\n });\n\n assignRemoteInfo(remoteInfo, remoteSnapshot);\n // preloading assets\n const preloadOptions: PreloadOptions[0] = {\n remote,\n preloadConfig: {\n nameOrAlias: pkgNameOrAlias,\n exposes: [expose],\n resourceCategory: 'sync',\n share: false,\n depsRemote: false,\n },\n };\n\n const assets =\n await origin.remoteHandler.hooks.lifecycle.generatePreloadAssets.emit(\n {\n origin,\n preloadOptions,\n remoteInfo,\n remote,\n remoteSnapshot,\n globalSnapshot,\n },\n );\n\n if (assets) {\n preloadAssets(remoteInfo, origin, assets, false, {\n initiator: 'loadRemote',\n id,\n }).catch(() => undefined);\n }\n\n return {\n ...args,\n remoteSnapshot,\n };\n }\n\n return args;\n },\n };\n}\n"],"mappings":";;;;;;;;;AAiBA,SAAgB,iBACd,YACA,gBACM;CACN,MAAM,kBAAkB,+BAA+B,eAAe;AACtE,KAAI,CAAC,gBAAgB,IACnB,OAAM,aAAa,gBAAgB,EAAE,YAAY,WAAW,MAAM,CAAC;CAGrE,IAAI,WAAW,eAAe,gBAAgB,gBAAgB,IAAI;AAElE,KAAI,CAAC,qBAAqB,CAAC,SAAS,WAAW,OAAO,CACpD,YAAW,SAAS;AAGtB,YAAW,OAAO,gBAAgB;AAClC,YAAW,kBAAkB,gBAAgB;AAC7C,YAAW,QAAQ;AACnB,YAAW,UAAU,eAAe;AACpC,YAAW,eAAe,eAAe;;AAG3C,SAAgB,iBAAgD;AAC9D,QAAO;EACL,MAAM;EACN,MAAM,aAAa,MAAM;GACvB,MAAM,EAAE,QAAQ,gBAAgB,QAAQ,QAAQ,YAAY,OAAO;AAEnE,OAAI,CAAC,sBAAsB,OAAO,IAAI,CAAC,kBAAkB,OAAO,EAAE;IAChE,MAAM,EAAE,gBAAgB,mBACtB,MAAM,OAAO,gBAAgB,uBAAuB;KAClD,YAAY;KACZ,IAAI,uBAAuB,OAAO,MAAM,OAAO;KAChD,CAAC;AAEJ,qBAAiB,YAAY,eAAe;IAE5C,MAAM,iBAAoC;KACxC;KACA,eAAe;MACb,aAAa;MACb,SAAS,CAAC,OAAO;MACjB,kBAAkB;MAClB,OAAO;MACP,YAAY;MACb;KACF;IAED,MAAM,SACJ,MAAM,OAAO,cAAc,MAAM,UAAU,sBAAsB,KAC/D;KACE;KACA;KACA;KACA;KACA;KACA;KACD,CACF;AAEH,QAAI,OACF,eAAc,YAAY,QAAQ,QAAQ,OAAO;KAC/C,WAAW;KACX;KACD,CAAC,CAAC,YAAY,OAAU;AAG3B,WAAO;KACL,GAAG;KACH;KACD;;AAGH,UAAO;;EAEV"} |
@@ -52,7 +52,8 @@ const require_logger = require('../../utils/logger.cjs'); | ||
| } | ||
| async loadRemoteSnapshotInfo({ moduleInfo, id, expose }) { | ||
| async loadRemoteSnapshotInfo({ moduleInfo, id, initiator = "loadRemote" }) { | ||
| const { options } = this.HostInstance; | ||
| await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({ | ||
| options, | ||
| moduleInfo | ||
| moduleInfo, | ||
| origin: this.HostInstance | ||
| }); | ||
@@ -89,3 +90,6 @@ let hostSnapshot = require_global.getGlobalSnapshotInfoByModuleInfo({ | ||
| const remoteEntry = _module_federation_sdk.isBrowserEnvValue ? globalRemoteSnapshot.remoteEntry : globalRemoteSnapshot.ssrRemoteEntry || globalRemoteSnapshot.remoteEntry || ""; | ||
| const moduleSnapshot = await this.getManifestJson(remoteEntry, moduleInfo, {}); | ||
| const moduleSnapshot = await this.loadManifestSnapshot(remoteEntry, moduleInfo, {}, { | ||
| initiator, | ||
| id: id || moduleInfo.name | ||
| }); | ||
| const globalSnapshotRes = require_global.setGlobalSnapshotInfoByModuleInfo({ | ||
@@ -108,11 +112,8 @@ ...moduleInfo, | ||
| else if (require_tool.isRemoteInfoWithEntry(moduleInfo)) { | ||
| const moduleSnapshot = await this.getManifestJson(moduleInfo.entry, moduleInfo, {}); | ||
| const moduleSnapshot = await this.loadManifestSnapshot(moduleInfo.entry, moduleInfo, {}, { | ||
| initiator, | ||
| id: id || moduleInfo.name | ||
| }); | ||
| const globalSnapshotRes = require_global.setGlobalSnapshotInfoByModuleInfo(moduleInfo, moduleSnapshot); | ||
| const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({ | ||
| options: this.HostInstance.options, | ||
| moduleInfo, | ||
| remoteSnapshot: moduleSnapshot, | ||
| from: "global" | ||
| }); | ||
| mSnapshot = remoteSnapshotRes; | ||
| mSnapshot = moduleSnapshot; | ||
| gSnapshot = globalSnapshotRes; | ||
@@ -140,8 +141,13 @@ } else require_logger.error(_module_federation_error_codes.RUNTIME_007, _module_federation_error_codes.runtimeDescMap, { | ||
| } | ||
| async getManifestJson(manifestUrl, moduleInfo, extraOptions) { | ||
| async getManifestJson(manifestUrl, moduleInfo, extraOptions, resourceOptions) { | ||
| const getManifest = async () => { | ||
| const remoteInfo = require_load.getRemoteInfo(moduleInfo); | ||
| let manifestJson = this.manifestCache.get(manifestUrl); | ||
| if (manifestJson) return manifestJson; | ||
| try { | ||
| let res = await this.loaderHook.lifecycle.fetch.emit(manifestUrl, {}, require_load.getRemoteInfo(moduleInfo)); | ||
| let res = await this.loaderHook.lifecycle.fetch.emit(manifestUrl, {}, remoteInfo, resourceOptions ? { | ||
| ...resourceOptions, | ||
| url: manifestUrl, | ||
| resourceType: "manifest" | ||
| } : void 0); | ||
| if (!res || !(res instanceof Response)) res = await fetch(manifestUrl, {}); | ||
@@ -155,2 +161,3 @@ manifestJson = await res.json(); | ||
| lifecycle: "afterResolve", | ||
| remote: remoteInfo, | ||
| origin: this.HostInstance | ||
@@ -167,12 +174,29 @@ }); | ||
| } | ||
| require_logger.assert(manifestJson.metaData && manifestJson.exposes && manifestJson.shared, `"${manifestUrl}" is not a valid federation manifest for remote "${moduleInfo.name}". Missing required fields: ${[ | ||
| const missingRequiredFields = [ | ||
| !manifestJson.metaData && "metaData", | ||
| !manifestJson.exposes && "exposes", | ||
| !manifestJson.shared && "shared" | ||
| ].filter(Boolean).join(", ")}.`); | ||
| ].filter(Boolean); | ||
| if (missingRequiredFields.length > 0) await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit({ | ||
| id: manifestUrl, | ||
| error: /* @__PURE__ */ new Error(`"${manifestUrl}" is not a valid federation manifest for remote "${moduleInfo.name}". Missing required fields: ${missingRequiredFields.join(", ")}.`), | ||
| from: "runtime", | ||
| lifecycle: "afterResolve", | ||
| remote: remoteInfo, | ||
| origin: this.HostInstance | ||
| }); | ||
| if (missingRequiredFields.length > 0) require_logger.error(_module_federation_error_codes.RUNTIME_013, _module_federation_error_codes.runtimeDescMap, { | ||
| manifestUrl, | ||
| moduleName: moduleInfo.name, | ||
| hostName: this.HostInstance.options.name, | ||
| missingFields: missingRequiredFields.join(",") | ||
| }, void 0, require_context.optionsToMFContext(this.HostInstance.options)); | ||
| this.manifestCache.set(manifestUrl, manifestJson); | ||
| return manifestJson; | ||
| }; | ||
| return getManifest(); | ||
| } | ||
| async loadManifestSnapshot(manifestUrl, moduleInfo, extraOptions, resourceOptions) { | ||
| const asyncLoadProcess = async () => { | ||
| const manifestJson = await getManifest(); | ||
| const manifestJson = await this.getManifestJson(manifestUrl, moduleInfo, extraOptions, resourceOptions); | ||
| const remoteSnapshot = (0, _module_federation_sdk.generateSnapshotFromManifest)(manifestJson, { version: manifestUrl }); | ||
@@ -179,0 +203,0 @@ const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({ |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"SnapshotHandler.cjs","names":["getGlobalSnapshotInfoByModuleInfo","getInfoWithoutType","getGlobalSnapshot","PluginSystem","AsyncHook","AsyncWaterfallHook","Global","isBrowserEnvValue","setGlobalSnapshotInfoByModuleInfo","isRemoteInfoWithEntry","RUNTIME_007","runtimeDescMap","optionsToMFContext","getRemoteInfo","RUNTIME_003"],"sources":["../../../src/plugins/snapshot/SnapshotHandler.ts"],"sourcesContent":["import {\n GlobalModuleInfo,\n Manifest,\n ModuleInfo,\n generateSnapshotFromManifest,\n isManifestProvider,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport {\n RUNTIME_003,\n RUNTIME_007,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Options, Remote } from '../../type';\nimport {\n isRemoteInfoWithEntry,\n error,\n optionsToMFContext,\n getRemoteInfo,\n} from '../../utils';\nimport {\n getGlobalSnapshot,\n setGlobalSnapshotInfoByModuleInfo,\n Global,\n addGlobalSnapshot,\n getGlobalSnapshotInfoByModuleInfo,\n getInfoWithoutType,\n} from '../../global';\nimport { PluginSystem, AsyncHook, AsyncWaterfallHook } from '../../utils/hooks';\nimport { ModuleFederation } from '../../core';\nimport { assert } from '../../utils/logger';\n\nexport function getGlobalRemoteInfo(\n moduleInfo: Remote,\n origin: ModuleFederation,\n): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n} {\n const hostGlobalSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: origin.name,\n version: origin.options.version,\n });\n\n // get remote detail info from global\n const globalRemoteInfo =\n hostGlobalSnapshot &&\n 'remotesInfo' in hostGlobalSnapshot &&\n hostGlobalSnapshot.remotesInfo &&\n getInfoWithoutType(hostGlobalSnapshot.remotesInfo, moduleInfo.name).value;\n\n if (globalRemoteInfo && globalRemoteInfo.matchedVersion) {\n return {\n hostGlobalSnapshot,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: globalRemoteInfo.matchedVersion,\n }),\n };\n }\n\n return {\n hostGlobalSnapshot: undefined,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: 'version' in moduleInfo ? moduleInfo.version : undefined,\n }),\n };\n}\n\nexport class SnapshotHandler {\n loadingHostSnapshot: Promise<GlobalModuleInfo | void> | null = null;\n HostInstance: ModuleFederation;\n manifestCache: Map<string, Manifest> = new Map();\n hooks = new PluginSystem({\n beforeLoadRemoteSnapshot: new AsyncHook<\n [\n {\n options: Options;\n moduleInfo: Remote;\n },\n ],\n void\n >('beforeLoadRemoteSnapshot'),\n loadSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n hostGlobalSnapshot: GlobalModuleInfo[string] | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot?: GlobalModuleInfo[string] | undefined;\n }>('loadGlobalSnapshot'),\n loadRemoteSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n manifestJson?: Manifest;\n manifestUrl?: string;\n remoteSnapshot: ModuleInfo;\n from: 'global' | 'manifest';\n }>('loadRemoteSnapshot'),\n afterLoadSnapshot: new AsyncWaterfallHook<{\n id?: string;\n host: ModuleFederation;\n options: Options;\n moduleInfo: Remote;\n remoteSnapshot: ModuleInfo;\n }>('afterLoadSnapshot'),\n });\n loaderHook: ModuleFederation['loaderHook'];\n manifestLoading: Record<string, Promise<ModuleInfo>> =\n Global.__FEDERATION__.__MANIFEST_LOADING__;\n\n constructor(HostInstance: ModuleFederation) {\n this.HostInstance = HostInstance;\n this.loaderHook = HostInstance.loaderHook;\n }\n\n // eslint-disable-next-line max-lines-per-function\n async loadRemoteSnapshotInfo({\n moduleInfo,\n id,\n expose,\n }: {\n moduleInfo: Remote;\n id?: string;\n expose?: string;\n }):\n | Promise<{\n remoteSnapshot: ModuleInfo;\n globalSnapshot: GlobalModuleInfo;\n }>\n | never {\n const { options } = this.HostInstance;\n\n await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({\n options,\n moduleInfo,\n });\n\n let hostSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: this.HostInstance.options.name,\n version: this.HostInstance.options.version,\n });\n\n if (!hostSnapshot) {\n hostSnapshot = {\n version: this.HostInstance.options.version || '',\n remoteEntry: '',\n remotesInfo: {},\n };\n addGlobalSnapshot({\n [this.HostInstance.options.name]: hostSnapshot,\n });\n }\n\n // In dynamic loadRemote scenarios, incomplete remotesInfo delivery may occur. In such cases, the remotesInfo in the host needs to be completed in the snapshot at runtime.\n // This ensures the snapshot's integrity and helps the chrome plugin correctly identify all producer modules, ensuring that proxyable producer modules will not be missing.\n if (\n hostSnapshot &&\n 'remotesInfo' in hostSnapshot &&\n !getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name).value\n ) {\n if ('version' in moduleInfo || 'entry' in moduleInfo) {\n hostSnapshot.remotesInfo = {\n ...hostSnapshot?.remotesInfo,\n [moduleInfo.name]: {\n matchedVersion:\n 'version' in moduleInfo ? moduleInfo.version : moduleInfo.entry,\n },\n };\n }\n }\n\n const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } =\n this.getGlobalRemoteInfo(moduleInfo);\n const {\n remoteSnapshot: globalRemoteSnapshot,\n globalSnapshot: globalSnapshotRes,\n } = await this.hooks.lifecycle.loadSnapshot.emit({\n options,\n moduleInfo,\n hostGlobalSnapshot,\n remoteSnapshot,\n globalSnapshot,\n });\n\n let mSnapshot;\n let gSnapshot;\n // global snapshot includes manifest or module info includes manifest\n if (globalRemoteSnapshot) {\n if (isManifestProvider(globalRemoteSnapshot)) {\n const remoteEntry = isBrowserEnvValue\n ? globalRemoteSnapshot.remoteEntry\n : globalRemoteSnapshot.ssrRemoteEntry ||\n globalRemoteSnapshot.remoteEntry ||\n '';\n const moduleSnapshot = await this.getManifestJson(\n remoteEntry,\n moduleInfo,\n {},\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n {\n ...moduleInfo,\n // The global remote may be overridden\n // Therefore, set the snapshot key to the global address of the actual request\n entry: remoteEntry,\n },\n moduleSnapshot,\n );\n mSnapshot = moduleSnapshot;\n gSnapshot = globalSnapshotRes;\n } else {\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: globalRemoteSnapshot,\n from: 'global',\n });\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n }\n } else {\n if (isRemoteInfoWithEntry(moduleInfo)) {\n // get from manifest.json and merge remote info from remote server\n const moduleSnapshot = await this.getManifestJson(\n moduleInfo.entry,\n moduleInfo,\n {},\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n moduleInfo,\n moduleSnapshot,\n );\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: moduleSnapshot,\n from: 'global',\n });\n\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n } else {\n error(\n RUNTIME_007,\n runtimeDescMap,\n {\n remoteName: moduleInfo.name,\n remoteVersion: moduleInfo.version,\n hostName: this.HostInstance.options.name,\n globalSnapshot: JSON.stringify(globalSnapshotRes),\n },\n undefined,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n await this.hooks.lifecycle.afterLoadSnapshot.emit({\n id,\n host: this.HostInstance,\n options,\n moduleInfo,\n remoteSnapshot: mSnapshot,\n });\n\n return {\n remoteSnapshot: mSnapshot,\n globalSnapshot: gSnapshot,\n };\n }\n\n getGlobalRemoteInfo(moduleInfo: Remote): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n } {\n return getGlobalRemoteInfo(moduleInfo, this.HostInstance);\n }\n\n private async getManifestJson(\n manifestUrl: string,\n moduleInfo: Remote,\n extraOptions: Record<string, any>,\n ): Promise<ModuleInfo> {\n const getManifest = async (): Promise<Manifest> => {\n let manifestJson: Manifest | undefined =\n this.manifestCache.get(manifestUrl);\n if (manifestJson) {\n return manifestJson;\n }\n try {\n let res = await this.loaderHook.lifecycle.fetch.emit(\n manifestUrl,\n {},\n getRemoteInfo(moduleInfo),\n );\n if (!res || !(res instanceof Response)) {\n res = await fetch(manifestUrl, {});\n }\n manifestJson = (await res.json()) as Manifest;\n } catch (err) {\n manifestJson =\n (await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit(\n {\n id: manifestUrl,\n error: err,\n from: 'runtime',\n lifecycle: 'afterResolve',\n origin: this.HostInstance,\n },\n )) as Manifest | undefined;\n\n if (!manifestJson) {\n delete this.manifestLoading[manifestUrl];\n error(\n RUNTIME_003,\n runtimeDescMap,\n {\n manifestUrl,\n moduleName: moduleInfo.name,\n hostName: this.HostInstance.options.name,\n },\n `${err}`,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n assert(\n manifestJson.metaData && manifestJson.exposes && manifestJson.shared,\n `\"${manifestUrl}\" is not a valid federation manifest for remote \"${moduleInfo.name}\". Missing required fields: ${[!manifestJson.metaData && 'metaData', !manifestJson.exposes && 'exposes', !manifestJson.shared && 'shared'].filter(Boolean).join(', ')}.`,\n );\n this.manifestCache.set(manifestUrl, manifestJson);\n return manifestJson;\n };\n\n const asyncLoadProcess = async () => {\n const manifestJson = await getManifest();\n const remoteSnapshot = generateSnapshotFromManifest(manifestJson, {\n version: manifestUrl,\n });\n\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n manifestJson,\n remoteSnapshot,\n manifestUrl,\n from: 'manifest',\n });\n return remoteSnapshotRes;\n };\n\n if (!this.manifestLoading[manifestUrl]) {\n this.manifestLoading[manifestUrl] = asyncLoadProcess().then((res) => res);\n }\n return this.manifestLoading[manifestUrl];\n }\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"SnapshotHandler.cjs","names":["getGlobalSnapshotInfoByModuleInfo","getInfoWithoutType","getGlobalSnapshot","PluginSystem","AsyncHook","AsyncWaterfallHook","Global","isBrowserEnvValue","setGlobalSnapshotInfoByModuleInfo","isRemoteInfoWithEntry","RUNTIME_007","runtimeDescMap","optionsToMFContext","getRemoteInfo","RUNTIME_003","RUNTIME_013"],"sources":["../../../src/plugins/snapshot/SnapshotHandler.ts"],"sourcesContent":["import {\n GlobalModuleInfo,\n Manifest,\n ModuleInfo,\n generateSnapshotFromManifest,\n isManifestProvider,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport {\n RUNTIME_003,\n RUNTIME_007,\n RUNTIME_013,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Options, Remote, ResourceLoadInitiator } from '../../type';\nimport {\n isRemoteInfoWithEntry,\n error,\n optionsToMFContext,\n getRemoteInfo,\n} from '../../utils';\nimport {\n getGlobalSnapshot,\n setGlobalSnapshotInfoByModuleInfo,\n Global,\n addGlobalSnapshot,\n getGlobalSnapshotInfoByModuleInfo,\n getInfoWithoutType,\n} from '../../global';\nimport { PluginSystem, AsyncHook, AsyncWaterfallHook } from '../../utils/hooks';\nimport { ModuleFederation } from '../../core';\n\nexport function getGlobalRemoteInfo(\n moduleInfo: Remote,\n origin: ModuleFederation,\n): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n} {\n const hostGlobalSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: origin.name,\n version: origin.options.version,\n });\n\n // get remote detail info from global\n const globalRemoteInfo =\n hostGlobalSnapshot &&\n 'remotesInfo' in hostGlobalSnapshot &&\n hostGlobalSnapshot.remotesInfo &&\n getInfoWithoutType(hostGlobalSnapshot.remotesInfo, moduleInfo.name).value;\n\n if (globalRemoteInfo && globalRemoteInfo.matchedVersion) {\n return {\n hostGlobalSnapshot,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: globalRemoteInfo.matchedVersion,\n }),\n };\n }\n\n return {\n hostGlobalSnapshot: undefined,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: 'version' in moduleInfo ? moduleInfo.version : undefined,\n }),\n };\n}\n\nexport class SnapshotHandler {\n loadingHostSnapshot: Promise<GlobalModuleInfo | void> | null = null;\n HostInstance: ModuleFederation;\n manifestCache: Map<string, Manifest> = new Map();\n hooks = new PluginSystem({\n beforeLoadRemoteSnapshot: new AsyncHook<\n [\n {\n options: Options;\n moduleInfo: Remote;\n origin: ModuleFederation;\n },\n ],\n void\n >('beforeLoadRemoteSnapshot'),\n loadSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n hostGlobalSnapshot: GlobalModuleInfo[string] | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot?: GlobalModuleInfo[string] | undefined;\n }>('loadGlobalSnapshot'),\n loadRemoteSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n manifestJson?: Manifest;\n manifestUrl?: string;\n remoteSnapshot: ModuleInfo;\n from: 'global' | 'manifest';\n }>('loadRemoteSnapshot'),\n afterLoadSnapshot: new AsyncWaterfallHook<{\n id?: string;\n host: ModuleFederation;\n options: Options;\n moduleInfo: Remote;\n remoteSnapshot: ModuleInfo;\n }>('afterLoadSnapshot'),\n });\n loaderHook: ModuleFederation['loaderHook'];\n manifestLoading: Record<string, Promise<ModuleInfo>> =\n Global.__FEDERATION__.__MANIFEST_LOADING__;\n\n constructor(HostInstance: ModuleFederation) {\n this.HostInstance = HostInstance;\n this.loaderHook = HostInstance.loaderHook;\n }\n\n // eslint-disable-next-line max-lines-per-function\n async loadRemoteSnapshotInfo({\n moduleInfo,\n id,\n initiator = 'loadRemote',\n }: {\n moduleInfo: Remote;\n id?: string;\n initiator?: ResourceLoadInitiator;\n }):\n | Promise<{\n remoteSnapshot: ModuleInfo;\n globalSnapshot: GlobalModuleInfo;\n }>\n | never {\n const { options } = this.HostInstance;\n\n await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({\n options,\n moduleInfo,\n origin: this.HostInstance,\n });\n\n let hostSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: this.HostInstance.options.name,\n version: this.HostInstance.options.version,\n });\n\n if (!hostSnapshot) {\n hostSnapshot = {\n version: this.HostInstance.options.version || '',\n remoteEntry: '',\n remotesInfo: {},\n };\n addGlobalSnapshot({\n [this.HostInstance.options.name]: hostSnapshot,\n });\n }\n\n // In dynamic loadRemote scenarios, incomplete remotesInfo delivery may occur. In such cases, the remotesInfo in the host needs to be completed in the snapshot at runtime.\n // This ensures the snapshot's integrity and helps the chrome plugin correctly identify all producer modules, ensuring that proxyable producer modules will not be missing.\n if (\n hostSnapshot &&\n 'remotesInfo' in hostSnapshot &&\n !getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name).value\n ) {\n if ('version' in moduleInfo || 'entry' in moduleInfo) {\n hostSnapshot.remotesInfo = {\n ...hostSnapshot?.remotesInfo,\n [moduleInfo.name]: {\n matchedVersion:\n 'version' in moduleInfo ? moduleInfo.version : moduleInfo.entry,\n },\n };\n }\n }\n\n const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } =\n this.getGlobalRemoteInfo(moduleInfo);\n const {\n remoteSnapshot: globalRemoteSnapshot,\n globalSnapshot: globalSnapshotRes,\n } = await this.hooks.lifecycle.loadSnapshot.emit({\n options,\n moduleInfo,\n hostGlobalSnapshot,\n remoteSnapshot,\n globalSnapshot,\n });\n\n let mSnapshot;\n let gSnapshot;\n // global snapshot includes manifest or module info includes manifest\n if (globalRemoteSnapshot) {\n if (isManifestProvider(globalRemoteSnapshot)) {\n const remoteEntry = isBrowserEnvValue\n ? globalRemoteSnapshot.remoteEntry\n : globalRemoteSnapshot.ssrRemoteEntry ||\n globalRemoteSnapshot.remoteEntry ||\n '';\n const moduleSnapshot = await this.loadManifestSnapshot(\n remoteEntry,\n moduleInfo,\n {},\n {\n initiator,\n id: id || moduleInfo.name,\n },\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n {\n ...moduleInfo,\n // The global remote may be overridden\n // Therefore, set the snapshot key to the global address of the actual request\n entry: remoteEntry,\n },\n moduleSnapshot,\n );\n mSnapshot = moduleSnapshot;\n gSnapshot = globalSnapshotRes;\n } else {\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: globalRemoteSnapshot,\n from: 'global',\n });\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n }\n } else {\n if (isRemoteInfoWithEntry(moduleInfo)) {\n // get from manifest.json and merge remote info from remote server\n const moduleSnapshot = await this.loadManifestSnapshot(\n moduleInfo.entry,\n moduleInfo,\n {},\n {\n initiator,\n id: id || moduleInfo.name,\n },\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n moduleInfo,\n moduleSnapshot,\n );\n mSnapshot = moduleSnapshot;\n gSnapshot = globalSnapshotRes;\n } else {\n error(\n RUNTIME_007,\n runtimeDescMap,\n {\n remoteName: moduleInfo.name,\n remoteVersion: moduleInfo.version,\n hostName: this.HostInstance.options.name,\n globalSnapshot: JSON.stringify(globalSnapshotRes),\n },\n undefined,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n await this.hooks.lifecycle.afterLoadSnapshot.emit({\n id,\n host: this.HostInstance,\n options,\n moduleInfo,\n remoteSnapshot: mSnapshot,\n });\n\n return {\n remoteSnapshot: mSnapshot,\n globalSnapshot: gSnapshot,\n };\n }\n\n getGlobalRemoteInfo(moduleInfo: Remote): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n } {\n return getGlobalRemoteInfo(moduleInfo, this.HostInstance);\n }\n\n private async getManifestJson(\n manifestUrl: string,\n moduleInfo: Remote,\n extraOptions: Record<string, any>,\n resourceOptions?: {\n initiator: ResourceLoadInitiator;\n id: string;\n },\n ): Promise<Manifest> {\n const getManifest = async (): Promise<Manifest> => {\n const remoteInfo = getRemoteInfo(moduleInfo);\n let manifestJson: Manifest | undefined =\n this.manifestCache.get(manifestUrl);\n if (manifestJson) {\n return manifestJson;\n }\n try {\n let res = await this.loaderHook.lifecycle.fetch.emit(\n manifestUrl,\n {},\n remoteInfo,\n resourceOptions\n ? {\n ...resourceOptions,\n url: manifestUrl,\n resourceType: 'manifest',\n }\n : undefined,\n );\n if (!res || !(res instanceof Response)) {\n res = await fetch(manifestUrl, {});\n }\n manifestJson = (await res.json()) as Manifest;\n } catch (err) {\n manifestJson =\n (await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit(\n {\n id: manifestUrl,\n error: err,\n from: 'runtime',\n lifecycle: 'afterResolve',\n remote: remoteInfo,\n origin: this.HostInstance,\n },\n )) as Manifest | undefined;\n\n if (!manifestJson) {\n delete this.manifestLoading[manifestUrl];\n error(\n RUNTIME_003,\n runtimeDescMap,\n {\n manifestUrl,\n moduleName: moduleInfo.name,\n hostName: this.HostInstance.options.name,\n },\n `${err}`,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n const missingRequiredFields = [\n !manifestJson.metaData && 'metaData',\n !manifestJson.exposes && 'exposes',\n !manifestJson.shared && 'shared',\n ].filter(Boolean);\n if (missingRequiredFields.length > 0) {\n await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit(\n {\n id: manifestUrl,\n error: new Error(\n `\"${manifestUrl}\" is not a valid federation manifest for remote \"${moduleInfo.name}\". Missing required fields: ${missingRequiredFields.join(', ')}.`,\n ),\n from: 'runtime',\n lifecycle: 'afterResolve',\n remote: remoteInfo,\n origin: this.HostInstance,\n },\n );\n }\n\n if (missingRequiredFields.length > 0) {\n error(\n RUNTIME_013,\n runtimeDescMap,\n {\n manifestUrl,\n moduleName: moduleInfo.name,\n hostName: this.HostInstance.options.name,\n missingFields: missingRequiredFields.join(','),\n },\n undefined,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n this.manifestCache.set(manifestUrl, manifestJson);\n return manifestJson;\n };\n\n return getManifest();\n }\n\n private async loadManifestSnapshot(\n manifestUrl: string,\n moduleInfo: Remote,\n extraOptions: Record<string, any>,\n resourceOptions?: {\n initiator: ResourceLoadInitiator;\n id: string;\n },\n ): Promise<ModuleInfo> {\n const asyncLoadProcess = async () => {\n const manifestJson = await this.getManifestJson(\n manifestUrl,\n moduleInfo,\n extraOptions,\n resourceOptions,\n );\n const remoteSnapshot = generateSnapshotFromManifest(manifestJson, {\n version: manifestUrl,\n });\n\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n manifestJson,\n remoteSnapshot,\n manifestUrl,\n from: 'manifest',\n });\n return remoteSnapshotRes;\n };\n\n if (!this.manifestLoading[manifestUrl]) {\n this.manifestLoading[manifestUrl] = asyncLoadProcess().then((res) => res);\n }\n return this.manifestLoading[manifestUrl];\n }\n}\n"],"mappings":"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"} |
@@ -7,2 +7,3 @@ import { AsyncHook } from "../../utils/hooks/asyncHook.js"; | ||
| import { Options, Remote } from "../../type/config.js"; | ||
| import { ResourceLoadInitiator } from "../../type/preload.js"; | ||
| import { GlobalModuleInfo, Manifest, ModuleInfo } from "@module-federation/sdk"; | ||
@@ -19,2 +20,3 @@ | ||
| moduleInfo: Remote; | ||
| origin: ModuleFederation; | ||
| }], void>; | ||
@@ -50,7 +52,7 @@ loadSnapshot: AsyncWaterfallHook<{ | ||
| id, | ||
| expose | ||
| initiator | ||
| }: { | ||
| moduleInfo: Remote; | ||
| id?: string; | ||
| expose?: string; | ||
| initiator?: ResourceLoadInitiator; | ||
| }): Promise<{ | ||
@@ -66,2 +68,3 @@ remoteSnapshot: ModuleInfo; | ||
| private getManifestJson; | ||
| private loadManifestSnapshot; | ||
| } | ||
@@ -68,0 +71,0 @@ //#endregion |
@@ -1,2 +0,2 @@ | ||
| import { assert, error } from "../../utils/logger.js"; | ||
| import { error } from "../../utils/logger.js"; | ||
| import { isRemoteInfoWithEntry } from "../../utils/tool.js"; | ||
@@ -12,3 +12,3 @@ import { Global, addGlobalSnapshot, getGlobalSnapshot, getGlobalSnapshotInfoByModuleInfo, getInfoWithoutType, setGlobalSnapshotInfoByModuleInfo } from "../../global.js"; | ||
| import { generateSnapshotFromManifest, isBrowserEnvValue, isManifestProvider } from "@module-federation/sdk"; | ||
| import { RUNTIME_003, RUNTIME_007, runtimeDescMap } from "@module-federation/error-codes"; | ||
| import { RUNTIME_003, RUNTIME_007, RUNTIME_013, runtimeDescMap } from "@module-federation/error-codes"; | ||
@@ -53,7 +53,8 @@ //#region src/plugins/snapshot/SnapshotHandler.ts | ||
| } | ||
| async loadRemoteSnapshotInfo({ moduleInfo, id, expose }) { | ||
| async loadRemoteSnapshotInfo({ moduleInfo, id, initiator = "loadRemote" }) { | ||
| const { options } = this.HostInstance; | ||
| await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({ | ||
| options, | ||
| moduleInfo | ||
| moduleInfo, | ||
| origin: this.HostInstance | ||
| }); | ||
@@ -90,3 +91,6 @@ let hostSnapshot = getGlobalSnapshotInfoByModuleInfo({ | ||
| const remoteEntry = isBrowserEnvValue ? globalRemoteSnapshot.remoteEntry : globalRemoteSnapshot.ssrRemoteEntry || globalRemoteSnapshot.remoteEntry || ""; | ||
| const moduleSnapshot = await this.getManifestJson(remoteEntry, moduleInfo, {}); | ||
| const moduleSnapshot = await this.loadManifestSnapshot(remoteEntry, moduleInfo, {}, { | ||
| initiator, | ||
| id: id || moduleInfo.name | ||
| }); | ||
| const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo({ | ||
@@ -109,11 +113,8 @@ ...moduleInfo, | ||
| else if (isRemoteInfoWithEntry(moduleInfo)) { | ||
| const moduleSnapshot = await this.getManifestJson(moduleInfo.entry, moduleInfo, {}); | ||
| const moduleSnapshot = await this.loadManifestSnapshot(moduleInfo.entry, moduleInfo, {}, { | ||
| initiator, | ||
| id: id || moduleInfo.name | ||
| }); | ||
| const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(moduleInfo, moduleSnapshot); | ||
| const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({ | ||
| options: this.HostInstance.options, | ||
| moduleInfo, | ||
| remoteSnapshot: moduleSnapshot, | ||
| from: "global" | ||
| }); | ||
| mSnapshot = remoteSnapshotRes; | ||
| mSnapshot = moduleSnapshot; | ||
| gSnapshot = globalSnapshotRes; | ||
@@ -141,8 +142,13 @@ } else error(RUNTIME_007, runtimeDescMap, { | ||
| } | ||
| async getManifestJson(manifestUrl, moduleInfo, extraOptions) { | ||
| async getManifestJson(manifestUrl, moduleInfo, extraOptions, resourceOptions) { | ||
| const getManifest = async () => { | ||
| const remoteInfo = getRemoteInfo(moduleInfo); | ||
| let manifestJson = this.manifestCache.get(manifestUrl); | ||
| if (manifestJson) return manifestJson; | ||
| try { | ||
| let res = await this.loaderHook.lifecycle.fetch.emit(manifestUrl, {}, getRemoteInfo(moduleInfo)); | ||
| let res = await this.loaderHook.lifecycle.fetch.emit(manifestUrl, {}, remoteInfo, resourceOptions ? { | ||
| ...resourceOptions, | ||
| url: manifestUrl, | ||
| resourceType: "manifest" | ||
| } : void 0); | ||
| if (!res || !(res instanceof Response)) res = await fetch(manifestUrl, {}); | ||
@@ -156,2 +162,3 @@ manifestJson = await res.json(); | ||
| lifecycle: "afterResolve", | ||
| remote: remoteInfo, | ||
| origin: this.HostInstance | ||
@@ -168,12 +175,29 @@ }); | ||
| } | ||
| assert(manifestJson.metaData && manifestJson.exposes && manifestJson.shared, `"${manifestUrl}" is not a valid federation manifest for remote "${moduleInfo.name}". Missing required fields: ${[ | ||
| const missingRequiredFields = [ | ||
| !manifestJson.metaData && "metaData", | ||
| !manifestJson.exposes && "exposes", | ||
| !manifestJson.shared && "shared" | ||
| ].filter(Boolean).join(", ")}.`); | ||
| ].filter(Boolean); | ||
| if (missingRequiredFields.length > 0) await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit({ | ||
| id: manifestUrl, | ||
| error: /* @__PURE__ */ new Error(`"${manifestUrl}" is not a valid federation manifest for remote "${moduleInfo.name}". Missing required fields: ${missingRequiredFields.join(", ")}.`), | ||
| from: "runtime", | ||
| lifecycle: "afterResolve", | ||
| remote: remoteInfo, | ||
| origin: this.HostInstance | ||
| }); | ||
| if (missingRequiredFields.length > 0) error(RUNTIME_013, runtimeDescMap, { | ||
| manifestUrl, | ||
| moduleName: moduleInfo.name, | ||
| hostName: this.HostInstance.options.name, | ||
| missingFields: missingRequiredFields.join(",") | ||
| }, void 0, optionsToMFContext(this.HostInstance.options)); | ||
| this.manifestCache.set(manifestUrl, manifestJson); | ||
| return manifestJson; | ||
| }; | ||
| return getManifest(); | ||
| } | ||
| async loadManifestSnapshot(manifestUrl, moduleInfo, extraOptions, resourceOptions) { | ||
| const asyncLoadProcess = async () => { | ||
| const manifestJson = await getManifest(); | ||
| const manifestJson = await this.getManifestJson(manifestUrl, moduleInfo, extraOptions, resourceOptions); | ||
| const remoteSnapshot = generateSnapshotFromManifest(manifestJson, { version: manifestUrl }); | ||
@@ -180,0 +204,0 @@ const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({ |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"SnapshotHandler.js","names":[],"sources":["../../../src/plugins/snapshot/SnapshotHandler.ts"],"sourcesContent":["import {\n GlobalModuleInfo,\n Manifest,\n ModuleInfo,\n generateSnapshotFromManifest,\n isManifestProvider,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport {\n RUNTIME_003,\n RUNTIME_007,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Options, Remote } from '../../type';\nimport {\n isRemoteInfoWithEntry,\n error,\n optionsToMFContext,\n getRemoteInfo,\n} from '../../utils';\nimport {\n getGlobalSnapshot,\n setGlobalSnapshotInfoByModuleInfo,\n Global,\n addGlobalSnapshot,\n getGlobalSnapshotInfoByModuleInfo,\n getInfoWithoutType,\n} from '../../global';\nimport { PluginSystem, AsyncHook, AsyncWaterfallHook } from '../../utils/hooks';\nimport { ModuleFederation } from '../../core';\nimport { assert } from '../../utils/logger';\n\nexport function getGlobalRemoteInfo(\n moduleInfo: Remote,\n origin: ModuleFederation,\n): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n} {\n const hostGlobalSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: origin.name,\n version: origin.options.version,\n });\n\n // get remote detail info from global\n const globalRemoteInfo =\n hostGlobalSnapshot &&\n 'remotesInfo' in hostGlobalSnapshot &&\n hostGlobalSnapshot.remotesInfo &&\n getInfoWithoutType(hostGlobalSnapshot.remotesInfo, moduleInfo.name).value;\n\n if (globalRemoteInfo && globalRemoteInfo.matchedVersion) {\n return {\n hostGlobalSnapshot,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: globalRemoteInfo.matchedVersion,\n }),\n };\n }\n\n return {\n hostGlobalSnapshot: undefined,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: 'version' in moduleInfo ? moduleInfo.version : undefined,\n }),\n };\n}\n\nexport class SnapshotHandler {\n loadingHostSnapshot: Promise<GlobalModuleInfo | void> | null = null;\n HostInstance: ModuleFederation;\n manifestCache: Map<string, Manifest> = new Map();\n hooks = new PluginSystem({\n beforeLoadRemoteSnapshot: new AsyncHook<\n [\n {\n options: Options;\n moduleInfo: Remote;\n },\n ],\n void\n >('beforeLoadRemoteSnapshot'),\n loadSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n hostGlobalSnapshot: GlobalModuleInfo[string] | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot?: GlobalModuleInfo[string] | undefined;\n }>('loadGlobalSnapshot'),\n loadRemoteSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n manifestJson?: Manifest;\n manifestUrl?: string;\n remoteSnapshot: ModuleInfo;\n from: 'global' | 'manifest';\n }>('loadRemoteSnapshot'),\n afterLoadSnapshot: new AsyncWaterfallHook<{\n id?: string;\n host: ModuleFederation;\n options: Options;\n moduleInfo: Remote;\n remoteSnapshot: ModuleInfo;\n }>('afterLoadSnapshot'),\n });\n loaderHook: ModuleFederation['loaderHook'];\n manifestLoading: Record<string, Promise<ModuleInfo>> =\n Global.__FEDERATION__.__MANIFEST_LOADING__;\n\n constructor(HostInstance: ModuleFederation) {\n this.HostInstance = HostInstance;\n this.loaderHook = HostInstance.loaderHook;\n }\n\n // eslint-disable-next-line max-lines-per-function\n async loadRemoteSnapshotInfo({\n moduleInfo,\n id,\n expose,\n }: {\n moduleInfo: Remote;\n id?: string;\n expose?: string;\n }):\n | Promise<{\n remoteSnapshot: ModuleInfo;\n globalSnapshot: GlobalModuleInfo;\n }>\n | never {\n const { options } = this.HostInstance;\n\n await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({\n options,\n moduleInfo,\n });\n\n let hostSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: this.HostInstance.options.name,\n version: this.HostInstance.options.version,\n });\n\n if (!hostSnapshot) {\n hostSnapshot = {\n version: this.HostInstance.options.version || '',\n remoteEntry: '',\n remotesInfo: {},\n };\n addGlobalSnapshot({\n [this.HostInstance.options.name]: hostSnapshot,\n });\n }\n\n // In dynamic loadRemote scenarios, incomplete remotesInfo delivery may occur. In such cases, the remotesInfo in the host needs to be completed in the snapshot at runtime.\n // This ensures the snapshot's integrity and helps the chrome plugin correctly identify all producer modules, ensuring that proxyable producer modules will not be missing.\n if (\n hostSnapshot &&\n 'remotesInfo' in hostSnapshot &&\n !getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name).value\n ) {\n if ('version' in moduleInfo || 'entry' in moduleInfo) {\n hostSnapshot.remotesInfo = {\n ...hostSnapshot?.remotesInfo,\n [moduleInfo.name]: {\n matchedVersion:\n 'version' in moduleInfo ? moduleInfo.version : moduleInfo.entry,\n },\n };\n }\n }\n\n const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } =\n this.getGlobalRemoteInfo(moduleInfo);\n const {\n remoteSnapshot: globalRemoteSnapshot,\n globalSnapshot: globalSnapshotRes,\n } = await this.hooks.lifecycle.loadSnapshot.emit({\n options,\n moduleInfo,\n hostGlobalSnapshot,\n remoteSnapshot,\n globalSnapshot,\n });\n\n let mSnapshot;\n let gSnapshot;\n // global snapshot includes manifest or module info includes manifest\n if (globalRemoteSnapshot) {\n if (isManifestProvider(globalRemoteSnapshot)) {\n const remoteEntry = isBrowserEnvValue\n ? globalRemoteSnapshot.remoteEntry\n : globalRemoteSnapshot.ssrRemoteEntry ||\n globalRemoteSnapshot.remoteEntry ||\n '';\n const moduleSnapshot = await this.getManifestJson(\n remoteEntry,\n moduleInfo,\n {},\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n {\n ...moduleInfo,\n // The global remote may be overridden\n // Therefore, set the snapshot key to the global address of the actual request\n entry: remoteEntry,\n },\n moduleSnapshot,\n );\n mSnapshot = moduleSnapshot;\n gSnapshot = globalSnapshotRes;\n } else {\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: globalRemoteSnapshot,\n from: 'global',\n });\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n }\n } else {\n if (isRemoteInfoWithEntry(moduleInfo)) {\n // get from manifest.json and merge remote info from remote server\n const moduleSnapshot = await this.getManifestJson(\n moduleInfo.entry,\n moduleInfo,\n {},\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n moduleInfo,\n moduleSnapshot,\n );\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: moduleSnapshot,\n from: 'global',\n });\n\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n } else {\n error(\n RUNTIME_007,\n runtimeDescMap,\n {\n remoteName: moduleInfo.name,\n remoteVersion: moduleInfo.version,\n hostName: this.HostInstance.options.name,\n globalSnapshot: JSON.stringify(globalSnapshotRes),\n },\n undefined,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n await this.hooks.lifecycle.afterLoadSnapshot.emit({\n id,\n host: this.HostInstance,\n options,\n moduleInfo,\n remoteSnapshot: mSnapshot,\n });\n\n return {\n remoteSnapshot: mSnapshot,\n globalSnapshot: gSnapshot,\n };\n }\n\n getGlobalRemoteInfo(moduleInfo: Remote): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n } {\n return getGlobalRemoteInfo(moduleInfo, this.HostInstance);\n }\n\n private async getManifestJson(\n manifestUrl: string,\n moduleInfo: Remote,\n extraOptions: Record<string, any>,\n ): Promise<ModuleInfo> {\n const getManifest = async (): Promise<Manifest> => {\n let manifestJson: Manifest | undefined =\n this.manifestCache.get(manifestUrl);\n if (manifestJson) {\n return manifestJson;\n }\n try {\n let res = await this.loaderHook.lifecycle.fetch.emit(\n manifestUrl,\n {},\n getRemoteInfo(moduleInfo),\n );\n if (!res || !(res instanceof Response)) {\n res = await fetch(manifestUrl, {});\n }\n manifestJson = (await res.json()) as Manifest;\n } catch (err) {\n manifestJson =\n (await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit(\n {\n id: manifestUrl,\n error: err,\n from: 'runtime',\n lifecycle: 'afterResolve',\n origin: this.HostInstance,\n },\n )) as Manifest | undefined;\n\n if (!manifestJson) {\n delete this.manifestLoading[manifestUrl];\n error(\n RUNTIME_003,\n runtimeDescMap,\n {\n manifestUrl,\n moduleName: moduleInfo.name,\n hostName: this.HostInstance.options.name,\n },\n `${err}`,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n assert(\n manifestJson.metaData && manifestJson.exposes && manifestJson.shared,\n `\"${manifestUrl}\" is not a valid federation manifest for remote \"${moduleInfo.name}\". Missing required fields: ${[!manifestJson.metaData && 'metaData', !manifestJson.exposes && 'exposes', !manifestJson.shared && 'shared'].filter(Boolean).join(', ')}.`,\n );\n this.manifestCache.set(manifestUrl, manifestJson);\n return manifestJson;\n };\n\n const asyncLoadProcess = async () => {\n const manifestJson = await getManifest();\n const remoteSnapshot = generateSnapshotFromManifest(manifestJson, {\n version: manifestUrl,\n });\n\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n manifestJson,\n remoteSnapshot,\n manifestUrl,\n from: 'manifest',\n });\n return remoteSnapshotRes;\n };\n\n if (!this.manifestLoading[manifestUrl]) {\n this.manifestLoading[manifestUrl] = asyncLoadProcess().then((res) => res);\n }\n return this.manifestLoading[manifestUrl];\n }\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"SnapshotHandler.js","names":[],"sources":["../../../src/plugins/snapshot/SnapshotHandler.ts"],"sourcesContent":["import {\n GlobalModuleInfo,\n Manifest,\n ModuleInfo,\n generateSnapshotFromManifest,\n isManifestProvider,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport {\n RUNTIME_003,\n RUNTIME_007,\n RUNTIME_013,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Options, Remote, ResourceLoadInitiator } from '../../type';\nimport {\n isRemoteInfoWithEntry,\n error,\n optionsToMFContext,\n getRemoteInfo,\n} from '../../utils';\nimport {\n getGlobalSnapshot,\n setGlobalSnapshotInfoByModuleInfo,\n Global,\n addGlobalSnapshot,\n getGlobalSnapshotInfoByModuleInfo,\n getInfoWithoutType,\n} from '../../global';\nimport { PluginSystem, AsyncHook, AsyncWaterfallHook } from '../../utils/hooks';\nimport { ModuleFederation } from '../../core';\n\nexport function getGlobalRemoteInfo(\n moduleInfo: Remote,\n origin: ModuleFederation,\n): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n} {\n const hostGlobalSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: origin.name,\n version: origin.options.version,\n });\n\n // get remote detail info from global\n const globalRemoteInfo =\n hostGlobalSnapshot &&\n 'remotesInfo' in hostGlobalSnapshot &&\n hostGlobalSnapshot.remotesInfo &&\n getInfoWithoutType(hostGlobalSnapshot.remotesInfo, moduleInfo.name).value;\n\n if (globalRemoteInfo && globalRemoteInfo.matchedVersion) {\n return {\n hostGlobalSnapshot,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: globalRemoteInfo.matchedVersion,\n }),\n };\n }\n\n return {\n hostGlobalSnapshot: undefined,\n globalSnapshot: getGlobalSnapshot(),\n remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({\n name: moduleInfo.name,\n version: 'version' in moduleInfo ? moduleInfo.version : undefined,\n }),\n };\n}\n\nexport class SnapshotHandler {\n loadingHostSnapshot: Promise<GlobalModuleInfo | void> | null = null;\n HostInstance: ModuleFederation;\n manifestCache: Map<string, Manifest> = new Map();\n hooks = new PluginSystem({\n beforeLoadRemoteSnapshot: new AsyncHook<\n [\n {\n options: Options;\n moduleInfo: Remote;\n origin: ModuleFederation;\n },\n ],\n void\n >('beforeLoadRemoteSnapshot'),\n loadSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n hostGlobalSnapshot: GlobalModuleInfo[string] | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot?: GlobalModuleInfo[string] | undefined;\n }>('loadGlobalSnapshot'),\n loadRemoteSnapshot: new AsyncWaterfallHook<{\n options: Options;\n moduleInfo: Remote;\n manifestJson?: Manifest;\n manifestUrl?: string;\n remoteSnapshot: ModuleInfo;\n from: 'global' | 'manifest';\n }>('loadRemoteSnapshot'),\n afterLoadSnapshot: new AsyncWaterfallHook<{\n id?: string;\n host: ModuleFederation;\n options: Options;\n moduleInfo: Remote;\n remoteSnapshot: ModuleInfo;\n }>('afterLoadSnapshot'),\n });\n loaderHook: ModuleFederation['loaderHook'];\n manifestLoading: Record<string, Promise<ModuleInfo>> =\n Global.__FEDERATION__.__MANIFEST_LOADING__;\n\n constructor(HostInstance: ModuleFederation) {\n this.HostInstance = HostInstance;\n this.loaderHook = HostInstance.loaderHook;\n }\n\n // eslint-disable-next-line max-lines-per-function\n async loadRemoteSnapshotInfo({\n moduleInfo,\n id,\n initiator = 'loadRemote',\n }: {\n moduleInfo: Remote;\n id?: string;\n initiator?: ResourceLoadInitiator;\n }):\n | Promise<{\n remoteSnapshot: ModuleInfo;\n globalSnapshot: GlobalModuleInfo;\n }>\n | never {\n const { options } = this.HostInstance;\n\n await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({\n options,\n moduleInfo,\n origin: this.HostInstance,\n });\n\n let hostSnapshot = getGlobalSnapshotInfoByModuleInfo({\n name: this.HostInstance.options.name,\n version: this.HostInstance.options.version,\n });\n\n if (!hostSnapshot) {\n hostSnapshot = {\n version: this.HostInstance.options.version || '',\n remoteEntry: '',\n remotesInfo: {},\n };\n addGlobalSnapshot({\n [this.HostInstance.options.name]: hostSnapshot,\n });\n }\n\n // In dynamic loadRemote scenarios, incomplete remotesInfo delivery may occur. In such cases, the remotesInfo in the host needs to be completed in the snapshot at runtime.\n // This ensures the snapshot's integrity and helps the chrome plugin correctly identify all producer modules, ensuring that proxyable producer modules will not be missing.\n if (\n hostSnapshot &&\n 'remotesInfo' in hostSnapshot &&\n !getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name).value\n ) {\n if ('version' in moduleInfo || 'entry' in moduleInfo) {\n hostSnapshot.remotesInfo = {\n ...hostSnapshot?.remotesInfo,\n [moduleInfo.name]: {\n matchedVersion:\n 'version' in moduleInfo ? moduleInfo.version : moduleInfo.entry,\n },\n };\n }\n }\n\n const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } =\n this.getGlobalRemoteInfo(moduleInfo);\n const {\n remoteSnapshot: globalRemoteSnapshot,\n globalSnapshot: globalSnapshotRes,\n } = await this.hooks.lifecycle.loadSnapshot.emit({\n options,\n moduleInfo,\n hostGlobalSnapshot,\n remoteSnapshot,\n globalSnapshot,\n });\n\n let mSnapshot;\n let gSnapshot;\n // global snapshot includes manifest or module info includes manifest\n if (globalRemoteSnapshot) {\n if (isManifestProvider(globalRemoteSnapshot)) {\n const remoteEntry = isBrowserEnvValue\n ? globalRemoteSnapshot.remoteEntry\n : globalRemoteSnapshot.ssrRemoteEntry ||\n globalRemoteSnapshot.remoteEntry ||\n '';\n const moduleSnapshot = await this.loadManifestSnapshot(\n remoteEntry,\n moduleInfo,\n {},\n {\n initiator,\n id: id || moduleInfo.name,\n },\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n {\n ...moduleInfo,\n // The global remote may be overridden\n // Therefore, set the snapshot key to the global address of the actual request\n entry: remoteEntry,\n },\n moduleSnapshot,\n );\n mSnapshot = moduleSnapshot;\n gSnapshot = globalSnapshotRes;\n } else {\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n remoteSnapshot: globalRemoteSnapshot,\n from: 'global',\n });\n mSnapshot = remoteSnapshotRes;\n gSnapshot = globalSnapshotRes;\n }\n } else {\n if (isRemoteInfoWithEntry(moduleInfo)) {\n // get from manifest.json and merge remote info from remote server\n const moduleSnapshot = await this.loadManifestSnapshot(\n moduleInfo.entry,\n moduleInfo,\n {},\n {\n initiator,\n id: id || moduleInfo.name,\n },\n );\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(\n moduleInfo,\n moduleSnapshot,\n );\n mSnapshot = moduleSnapshot;\n gSnapshot = globalSnapshotRes;\n } else {\n error(\n RUNTIME_007,\n runtimeDescMap,\n {\n remoteName: moduleInfo.name,\n remoteVersion: moduleInfo.version,\n hostName: this.HostInstance.options.name,\n globalSnapshot: JSON.stringify(globalSnapshotRes),\n },\n undefined,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n await this.hooks.lifecycle.afterLoadSnapshot.emit({\n id,\n host: this.HostInstance,\n options,\n moduleInfo,\n remoteSnapshot: mSnapshot,\n });\n\n return {\n remoteSnapshot: mSnapshot,\n globalSnapshot: gSnapshot,\n };\n }\n\n getGlobalRemoteInfo(moduleInfo: Remote): {\n hostGlobalSnapshot: ModuleInfo | undefined;\n globalSnapshot: ReturnType<typeof getGlobalSnapshot>;\n remoteSnapshot: GlobalModuleInfo[string] | undefined;\n } {\n return getGlobalRemoteInfo(moduleInfo, this.HostInstance);\n }\n\n private async getManifestJson(\n manifestUrl: string,\n moduleInfo: Remote,\n extraOptions: Record<string, any>,\n resourceOptions?: {\n initiator: ResourceLoadInitiator;\n id: string;\n },\n ): Promise<Manifest> {\n const getManifest = async (): Promise<Manifest> => {\n const remoteInfo = getRemoteInfo(moduleInfo);\n let manifestJson: Manifest | undefined =\n this.manifestCache.get(manifestUrl);\n if (manifestJson) {\n return manifestJson;\n }\n try {\n let res = await this.loaderHook.lifecycle.fetch.emit(\n manifestUrl,\n {},\n remoteInfo,\n resourceOptions\n ? {\n ...resourceOptions,\n url: manifestUrl,\n resourceType: 'manifest',\n }\n : undefined,\n );\n if (!res || !(res instanceof Response)) {\n res = await fetch(manifestUrl, {});\n }\n manifestJson = (await res.json()) as Manifest;\n } catch (err) {\n manifestJson =\n (await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit(\n {\n id: manifestUrl,\n error: err,\n from: 'runtime',\n lifecycle: 'afterResolve',\n remote: remoteInfo,\n origin: this.HostInstance,\n },\n )) as Manifest | undefined;\n\n if (!manifestJson) {\n delete this.manifestLoading[manifestUrl];\n error(\n RUNTIME_003,\n runtimeDescMap,\n {\n manifestUrl,\n moduleName: moduleInfo.name,\n hostName: this.HostInstance.options.name,\n },\n `${err}`,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n }\n\n const missingRequiredFields = [\n !manifestJson.metaData && 'metaData',\n !manifestJson.exposes && 'exposes',\n !manifestJson.shared && 'shared',\n ].filter(Boolean);\n if (missingRequiredFields.length > 0) {\n await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit(\n {\n id: manifestUrl,\n error: new Error(\n `\"${manifestUrl}\" is not a valid federation manifest for remote \"${moduleInfo.name}\". Missing required fields: ${missingRequiredFields.join(', ')}.`,\n ),\n from: 'runtime',\n lifecycle: 'afterResolve',\n remote: remoteInfo,\n origin: this.HostInstance,\n },\n );\n }\n\n if (missingRequiredFields.length > 0) {\n error(\n RUNTIME_013,\n runtimeDescMap,\n {\n manifestUrl,\n moduleName: moduleInfo.name,\n hostName: this.HostInstance.options.name,\n missingFields: missingRequiredFields.join(','),\n },\n undefined,\n optionsToMFContext(this.HostInstance.options),\n );\n }\n this.manifestCache.set(manifestUrl, manifestJson);\n return manifestJson;\n };\n\n return getManifest();\n }\n\n private async loadManifestSnapshot(\n manifestUrl: string,\n moduleInfo: Remote,\n extraOptions: Record<string, any>,\n resourceOptions?: {\n initiator: ResourceLoadInitiator;\n id: string;\n },\n ): Promise<ModuleInfo> {\n const asyncLoadProcess = async () => {\n const manifestJson = await this.getManifestJson(\n manifestUrl,\n moduleInfo,\n extraOptions,\n resourceOptions,\n );\n const remoteSnapshot = generateSnapshotFromManifest(manifestJson, {\n version: manifestUrl,\n });\n\n const { remoteSnapshot: remoteSnapshotRes } =\n await this.hooks.lifecycle.loadRemoteSnapshot.emit({\n options: this.HostInstance.options,\n moduleInfo,\n manifestJson,\n remoteSnapshot,\n manifestUrl,\n from: 'manifest',\n });\n return remoteSnapshotRes;\n };\n\n if (!this.manifestLoading[manifestUrl]) {\n this.manifestLoading[manifestUrl] = asyncLoadProcess().then((res) => res);\n }\n return this.manifestLoading[manifestUrl];\n }\n}\n"],"mappings":"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"} |
+163
-25
@@ -28,3 +28,5 @@ const require_logger = require('../utils/logger.cjs'); | ||
| beforeRequest: new require_asyncWaterfallHooks.AsyncWaterfallHook("beforeRequest"), | ||
| afterMatchRemote: new require_asyncHook.AsyncHook("afterMatchRemote"), | ||
| onLoad: new require_asyncHook.AsyncHook("onLoad"), | ||
| afterLoadRemote: new require_asyncHook.AsyncHook("afterLoadRemote"), | ||
| handlePreloadModule: new require_syncHook.SyncHook("handlePreloadModule"), | ||
@@ -34,3 +36,3 @@ errorLoadRemote: new require_asyncHook.AsyncHook("errorLoadRemote"), | ||
| generatePreloadAssets: new require_asyncHook.AsyncHook("generatePreloadAssets"), | ||
| afterPreloadRemote: new require_asyncHook.AsyncHook(), | ||
| afterPreloadRemote: new require_asyncHook.AsyncHook("afterPreloadRemote"), | ||
| loadEntry: new require_asyncHook.AsyncHook() | ||
@@ -72,2 +74,7 @@ }); | ||
| const { host } = this; | ||
| const startMatchInfo = require_manifest.matchRemoteWithNameAndExpose(host.options.remotes, id); | ||
| let completeRequestId = id; | ||
| let completeExpose = startMatchInfo?.expose; | ||
| let completeRemote = startMatchInfo ? require_load.getRemoteInfo(startMatchInfo.remote) : void 0; | ||
| let afterLoadRemoteArgs; | ||
| try { | ||
@@ -77,2 +84,5 @@ const { loadFactory = true } = options || { loadFactory: true }; | ||
| const { pkgNameOrAlias, remote, expose, id: idRes, remoteSnapshot } = remoteMatchInfo; | ||
| completeRequestId = idRes; | ||
| completeExpose = expose; | ||
| completeRemote = require_load.getRemoteInfo(remote); | ||
| const moduleOrFactory = await module.get(idRes, expose, options, remoteSnapshot); | ||
@@ -91,2 +101,9 @@ const moduleWrapper = await this.hooks.lifecycle.onLoad.emit({ | ||
| this.setIdToRemoteMap(id, remoteMatchInfo); | ||
| afterLoadRemoteArgs = { | ||
| id: completeRequestId, | ||
| expose: completeExpose, | ||
| remote: completeRemote, | ||
| options, | ||
| origin: host | ||
| }; | ||
| if (typeof moduleWrapper === "function") return moduleWrapper; | ||
@@ -96,11 +113,47 @@ return moduleOrFactory; | ||
| const { from = "runtime" } = options || { from: "runtime" }; | ||
| const failOver = await this.hooks.lifecycle.errorLoadRemote.emit({ | ||
| id, | ||
| let failOver; | ||
| try { | ||
| failOver = await this.hooks.lifecycle.errorLoadRemote.emit({ | ||
| id, | ||
| error, | ||
| from, | ||
| lifecycle: "onLoad", | ||
| expose: completeExpose, | ||
| remote: completeRemote, | ||
| origin: host | ||
| }); | ||
| } catch (hookError) { | ||
| afterLoadRemoteArgs = { | ||
| id: completeRequestId, | ||
| expose: completeExpose, | ||
| remote: completeRemote, | ||
| options, | ||
| error: hookError, | ||
| origin: host | ||
| }; | ||
| throw hookError; | ||
| } | ||
| if (!failOver) { | ||
| afterLoadRemoteArgs = { | ||
| id: completeRequestId, | ||
| expose: completeExpose, | ||
| remote: completeRemote, | ||
| options, | ||
| error, | ||
| origin: host | ||
| }; | ||
| throw error; | ||
| } | ||
| afterLoadRemoteArgs = { | ||
| id: completeRequestId, | ||
| expose: completeExpose, | ||
| remote: completeRemote, | ||
| options, | ||
| error, | ||
| from, | ||
| lifecycle: "onLoad", | ||
| origin: host | ||
| }); | ||
| if (!failOver) throw error; | ||
| origin: host, | ||
| recovered: true | ||
| }; | ||
| return failOver; | ||
| } finally { | ||
| if (afterLoadRemoteArgs) await this.hooks.lifecycle.afterLoadRemote.emit(afterLoadRemoteArgs); | ||
| } | ||
@@ -110,2 +163,3 @@ } | ||
| const { host } = this; | ||
| const preloadResults = []; | ||
| await this.hooks.lifecycle.beforePreloadRemote.emit({ | ||
@@ -117,17 +171,84 @@ preloadOps: preloadOptions, | ||
| const preloadOps = require_preload.formatPreloadArgs(host.options.remotes, preloadOptions); | ||
| await Promise.all(preloadOps.map(async (ops) => { | ||
| const { remote } = ops; | ||
| const createPreloadAssetOps = (ops) => { | ||
| const { preloadConfig, remote } = ops; | ||
| const exposes = preloadConfig.exposes || []; | ||
| if (!exposes.length) return [{ | ||
| ops, | ||
| id: `${remote.name}/*` | ||
| }]; | ||
| return exposes.map((expose) => ({ | ||
| ops: { | ||
| ...ops, | ||
| preloadConfig: { | ||
| ...preloadConfig, | ||
| exposes: [expose] | ||
| } | ||
| }, | ||
| id: require_manifest.composeRemoteRequestId(remote.name, expose) | ||
| })); | ||
| }; | ||
| let preloadError; | ||
| await Promise.all(preloadOps.flatMap(createPreloadAssetOps).map(async (assetOps) => { | ||
| const { ops, id: preloadId } = assetOps; | ||
| const { remote, preloadConfig } = ops; | ||
| const remoteInfo = require_load.getRemoteInfo(remote); | ||
| const { globalSnapshot, remoteSnapshot } = await host.snapshotHandler.loadRemoteSnapshotInfo({ moduleInfo: remote }); | ||
| const assets = await this.hooks.lifecycle.generatePreloadAssets.emit({ | ||
| origin: host, | ||
| preloadOptions: ops, | ||
| remote, | ||
| remoteInfo, | ||
| globalSnapshot, | ||
| remoteSnapshot | ||
| try { | ||
| const { globalSnapshot, remoteSnapshot } = await host.snapshotHandler.loadRemoteSnapshotInfo({ | ||
| moduleInfo: remote, | ||
| id: preloadId, | ||
| initiator: "preloadRemote" | ||
| }); | ||
| const assets = await this.hooks.lifecycle.generatePreloadAssets.emit({ | ||
| origin: host, | ||
| preloadOptions: ops, | ||
| remote, | ||
| remoteInfo, | ||
| globalSnapshot, | ||
| remoteSnapshot | ||
| }); | ||
| if (!assets) return; | ||
| const results = await require_preload.preloadAssets(remoteInfo, host, assets, true, { | ||
| initiator: "preloadRemote", | ||
| id: preloadId | ||
| }); | ||
| preloadResults.push({ | ||
| remote, | ||
| remoteInfo, | ||
| preloadConfig, | ||
| id: preloadId, | ||
| results | ||
| }); | ||
| } catch (error) { | ||
| preloadResults.push({ | ||
| remote, | ||
| remoteInfo, | ||
| preloadConfig, | ||
| id: preloadId, | ||
| results: [{ | ||
| url: remoteInfo.entry, | ||
| status: "error", | ||
| resourceType: /\.json(?:$|[?#])/i.test(remoteInfo.entry) ? "manifest" : "remoteEntry", | ||
| initiator: "preloadRemote", | ||
| id: preloadId, | ||
| error | ||
| }] | ||
| }); | ||
| } | ||
| })); | ||
| const failedResults = preloadResults.flatMap((preloadResult) => preloadResult.results.filter((result) => result.status === "error" || result.status === "timeout")); | ||
| if (failedResults.length > 0) { | ||
| preloadError = /* @__PURE__ */ new Error(`preloadRemote failed to load ${failedResults.length} resource(s).`); | ||
| Object.assign(preloadError, { | ||
| results: preloadResults, | ||
| failedResults | ||
| }); | ||
| if (!assets) return; | ||
| require_preload.preloadAssets(remoteInfo, host, assets); | ||
| })); | ||
| } | ||
| await this.hooks.lifecycle.afterPreloadRemote.emit({ | ||
| preloadOps: preloadOptions, | ||
| options: host.options, | ||
| origin: host, | ||
| results: preloadResults, | ||
| error: preloadError | ||
| }); | ||
| if (preloadError) throw preloadError; | ||
| } | ||
@@ -163,8 +284,25 @@ registerRemotes(remotes, options) { | ||
| const remoteSplitInfo = require_manifest.matchRemoteWithNameAndExpose(host.options.remotes, idRes); | ||
| if (!remoteSplitInfo) require_logger.error(_module_federation_error_codes.RUNTIME_004, _module_federation_error_codes.runtimeDescMap, { | ||
| hostName: host.options.name, | ||
| requestId: idRes | ||
| }, void 0, require_context.optionsToMFContext(host.options)); | ||
| if (!remoteSplitInfo) try { | ||
| require_logger.error(_module_federation_error_codes.RUNTIME_004, _module_federation_error_codes.runtimeDescMap, { | ||
| hostName: host.options.name, | ||
| requestId: idRes | ||
| }, void 0, require_context.optionsToMFContext(host.options)); | ||
| } catch (matchError) { | ||
| await this.hooks.lifecycle.afterMatchRemote.emit({ | ||
| id: idRes, | ||
| options: host.options, | ||
| error: matchError, | ||
| origin: host | ||
| }); | ||
| throw matchError; | ||
| } | ||
| const { remote: rawRemote } = remoteSplitInfo; | ||
| const remoteInfo = require_load.getRemoteInfo(rawRemote); | ||
| await this.hooks.lifecycle.afterMatchRemote.emit({ | ||
| id: idRes, | ||
| ...remoteSplitInfo, | ||
| options: host.options, | ||
| remoteInfo, | ||
| origin: host | ||
| }); | ||
| const matchInfo = await host.sharedHandler.hooks.lifecycle.afterResolve.emit({ | ||
@@ -171,0 +309,0 @@ id: idRes, |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.cjs","names":["PluginSystem","SyncWaterfallHook","AsyncWaterfallHook","AsyncHook","SyncHook","formatPreloadArgs","getRemoteInfo","matchRemoteWithNameAndExpose","RUNTIME_004","runtimeDescMap","optionsToMFContext","Module","isBrowserEnvValue","DEFAULT_SCOPE","DEFAULT_REMOTE_TYPE","CurrentGlobal","getRemoteEntryUniqueKey","globalLoading","getGlobalShareScope","getGlobalRemoteInfo","getInfoWithoutType","Global"],"sources":["../../src/remote/index.ts"],"sourcesContent":["import {\n isBrowserEnvValue,\n warn,\n composeKeyWithSeparator,\n ModuleInfo,\n GlobalModuleInfo,\n} from '@module-federation/sdk';\nimport { RUNTIME_004, runtimeDescMap } from '@module-federation/error-codes';\nimport {\n Global,\n getInfoWithoutType,\n globalLoading,\n CurrentGlobal,\n} from '../global';\nimport {\n Options,\n UserOptions,\n PreloadAssets,\n PreloadOptions,\n PreloadRemoteArgs,\n Remote,\n RemoteInfo,\n RemoteEntryExports,\n CallFrom,\n} from '../type';\nimport { ModuleFederation } from '../core';\nimport {\n PluginSystem,\n AsyncHook,\n AsyncWaterfallHook,\n SyncHook,\n SyncWaterfallHook,\n} from '../utils/hooks';\nimport {\n assert,\n error,\n getRemoteInfo,\n getRemoteEntryUniqueKey,\n matchRemoteWithNameAndExpose,\n optionsToMFContext,\n logger,\n} from '../utils';\nimport { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from '../constant';\nimport { Module, ModuleOptions } from '../module';\nimport { formatPreloadArgs, preloadAssets } from '../utils/preload';\nimport { getGlobalShareScope } from '../utils/share';\nimport { getGlobalRemoteInfo } from '../plugins/snapshot/SnapshotHandler';\n\nexport interface LoadRemoteMatch {\n id: string;\n pkgNameOrAlias: string;\n expose: string;\n remote: Remote;\n options: Options;\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteSnapshot?: ModuleInfo;\n}\n\nexport class RemoteHandler {\n host: ModuleFederation;\n idToRemoteMap: Record<string, { name: string; expose: string }>;\n\n hooks = new PluginSystem({\n beforeRegisterRemote: new SyncWaterfallHook<{\n remote: Remote;\n origin: ModuleFederation;\n }>('beforeRegisterRemote'),\n registerRemote: new SyncWaterfallHook<{\n remote: Remote;\n origin: ModuleFederation;\n }>('registerRemote'),\n beforeRequest: new AsyncWaterfallHook<{\n id: string;\n options: Options;\n origin: ModuleFederation;\n }>('beforeRequest'),\n onLoad: new AsyncHook<\n [\n {\n id: string;\n expose: string;\n pkgNameOrAlias: string;\n remote: Remote;\n options: ModuleOptions;\n origin: ModuleFederation;\n exposeModule: any;\n exposeModuleFactory: any;\n moduleInstance: Module;\n },\n ],\n void\n >('onLoad'),\n handlePreloadModule: new SyncHook<\n [\n {\n id: string;\n name: string;\n remote: Remote;\n remoteSnapshot: ModuleInfo;\n preloadConfig: PreloadRemoteArgs;\n origin: ModuleFederation;\n },\n ],\n void\n >('handlePreloadModule'),\n errorLoadRemote: new AsyncHook<\n [\n {\n id: string;\n error: unknown;\n options?: any;\n from: CallFrom;\n lifecycle:\n | 'beforeRequest'\n | 'beforeLoadShare'\n | 'afterResolve'\n | 'onLoad';\n origin: ModuleFederation;\n },\n ],\n void | unknown\n >('errorLoadRemote'),\n beforePreloadRemote: new AsyncHook<\n [\n {\n preloadOps: Array<PreloadRemoteArgs>;\n options: Options;\n origin: ModuleFederation;\n },\n ]\n >('beforePreloadRemote'),\n generatePreloadAssets: new AsyncHook<\n [\n {\n origin: ModuleFederation;\n preloadOptions: PreloadOptions[number];\n remote: Remote;\n remoteInfo: RemoteInfo;\n remoteSnapshot: ModuleInfo;\n globalSnapshot: GlobalModuleInfo;\n },\n ],\n Promise<PreloadAssets>\n >('generatePreloadAssets'),\n // not used yet\n afterPreloadRemote: new AsyncHook<{\n preloadOps: Array<PreloadRemoteArgs>;\n options: Options;\n origin: ModuleFederation;\n }>(),\n // TODO: Move to loaderHook\n loadEntry: new AsyncHook<\n [\n {\n loaderHook: ModuleFederation['loaderHook'];\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports;\n },\n ],\n Promise<RemoteEntryExports>\n >(),\n });\n\n constructor(host: ModuleFederation) {\n this.host = host;\n this.idToRemoteMap = {};\n }\n\n formatAndRegisterRemote(globalOptions: Options, userOptions: UserOptions) {\n const userRemotes = userOptions.remotes || [];\n\n return userRemotes.reduce((res, remote) => {\n this.registerRemote(remote, res, { force: false });\n return res;\n }, globalOptions.remotes);\n }\n\n setIdToRemoteMap(id: string, remoteMatchInfo: LoadRemoteMatch) {\n const { remote, expose } = remoteMatchInfo;\n const { name, alias } = remote;\n this.idToRemoteMap[id] = { name: remote.name, expose };\n if (alias && id.startsWith(name)) {\n const idWithAlias = id.replace(name, alias);\n this.idToRemoteMap[idWithAlias] = { name: remote.name, expose };\n return;\n }\n\n if (alias && id.startsWith(alias)) {\n const idWithName = id.replace(alias, name);\n this.idToRemoteMap[idWithName] = { name: remote.name, expose };\n }\n }\n\n // eslint-disable-next-line max-lines-per-function\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async loadRemote<T>(\n id: string,\n options?: { loadFactory?: boolean; from: CallFrom },\n ): Promise<T | null> {\n const { host } = this;\n try {\n const { loadFactory = true } = options || {\n loadFactory: true,\n };\n // 1. Validate the parameters of the retrieved module. There are two module request methods: pkgName + expose and alias + expose.\n // 2. Request the snapshot information of the current host and globally store the obtained snapshot information. The retrieved module information is partially offline and partially online. The online module information will retrieve the modules used online.\n // 3. Retrieve the detailed information of the current module from global (remoteEntry address, expose resource address)\n // 4. After retrieving remoteEntry, call the init of the module, and then retrieve the exported content of the module through get\n // id: pkgName(@federation/app1) + expose(button) = @federation/app1/button\n // id: alias(app1) + expose(button) = app1/button\n // id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort\n const { module, moduleOptions, remoteMatchInfo } =\n await this.getRemoteModuleAndOptions({\n id,\n });\n const {\n pkgNameOrAlias,\n remote,\n expose,\n id: idRes,\n remoteSnapshot,\n } = remoteMatchInfo;\n\n const moduleOrFactory = (await module.get(\n idRes,\n expose,\n options,\n remoteSnapshot,\n )) as T;\n\n const moduleWrapper = await this.hooks.lifecycle.onLoad.emit({\n id: idRes,\n pkgNameOrAlias,\n expose,\n exposeModule: loadFactory ? moduleOrFactory : undefined,\n exposeModuleFactory: loadFactory ? undefined : moduleOrFactory,\n remote,\n options: moduleOptions,\n moduleInstance: module,\n origin: host,\n });\n\n this.setIdToRemoteMap(id, remoteMatchInfo);\n if (typeof moduleWrapper === 'function') {\n return moduleWrapper as T;\n }\n\n return moduleOrFactory;\n } catch (error) {\n const { from = 'runtime' } = options || { from: 'runtime' };\n\n const failOver = await this.hooks.lifecycle.errorLoadRemote.emit({\n id,\n error,\n from,\n lifecycle: 'onLoad',\n origin: host,\n });\n\n if (!failOver) {\n throw error;\n }\n\n return failOver as T;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void> {\n const { host } = this;\n\n await this.hooks.lifecycle.beforePreloadRemote.emit({\n preloadOps: preloadOptions,\n options: host.options,\n origin: host,\n });\n\n const preloadOps: PreloadOptions = formatPreloadArgs(\n host.options.remotes,\n preloadOptions,\n );\n\n await Promise.all(\n preloadOps.map(async (ops) => {\n const { remote } = ops;\n const remoteInfo = getRemoteInfo(remote);\n const { globalSnapshot, remoteSnapshot } =\n await host.snapshotHandler.loadRemoteSnapshotInfo({\n moduleInfo: remote,\n });\n\n const assets = await this.hooks.lifecycle.generatePreloadAssets.emit({\n origin: host,\n preloadOptions: ops,\n remote,\n remoteInfo,\n globalSnapshot,\n remoteSnapshot,\n });\n if (!assets) {\n return;\n }\n preloadAssets(remoteInfo, host, assets);\n }),\n );\n }\n\n registerRemotes(remotes: Remote[], options?: { force?: boolean }): void {\n const { host } = this;\n remotes.forEach((remote) => {\n this.registerRemote(remote, host.options.remotes, {\n force: options?.force,\n });\n });\n }\n\n async getRemoteModuleAndOptions(options: { id: string }): Promise<{\n module: Module;\n moduleOptions: ModuleOptions;\n remoteMatchInfo: LoadRemoteMatch;\n }> {\n const { host } = this;\n const { id } = options;\n let loadRemoteArgs;\n\n try {\n loadRemoteArgs = await this.hooks.lifecycle.beforeRequest.emit({\n id,\n options: host.options,\n origin: host,\n });\n } catch (error) {\n loadRemoteArgs = (await this.hooks.lifecycle.errorLoadRemote.emit({\n id,\n options: host.options,\n origin: host,\n from: 'runtime',\n error,\n lifecycle: 'beforeRequest',\n })) as {\n id: string;\n options: Options;\n origin: ModuleFederation;\n };\n\n if (!loadRemoteArgs) {\n throw error;\n }\n }\n\n const { id: idRes } = loadRemoteArgs;\n\n const remoteSplitInfo = matchRemoteWithNameAndExpose(\n host.options.remotes,\n idRes,\n );\n if (!remoteSplitInfo) {\n error(\n RUNTIME_004,\n runtimeDescMap,\n {\n hostName: host.options.name,\n requestId: idRes,\n },\n undefined,\n optionsToMFContext(host.options),\n );\n }\n\n const { remote: rawRemote } = remoteSplitInfo;\n const remoteInfo = getRemoteInfo(rawRemote);\n const matchInfo =\n await host.sharedHandler.hooks.lifecycle.afterResolve.emit({\n id: idRes,\n ...remoteSplitInfo,\n options: host.options,\n origin: host,\n remoteInfo,\n });\n\n const { remote, expose } = matchInfo;\n assert(\n remote && expose,\n `The 'beforeRequest' hook was executed, but it failed to return the correct 'remote' and 'expose' values while loading ${idRes}.`,\n );\n let module: Module | undefined = host.moduleCache.get(remote.name);\n\n const moduleOptions: ModuleOptions = {\n host: host,\n remoteInfo,\n };\n\n if (!module) {\n module = new Module(moduleOptions);\n host.moduleCache.set(remote.name, module);\n }\n return {\n module,\n moduleOptions,\n remoteMatchInfo: matchInfo,\n };\n }\n\n registerRemote(\n remote: Remote,\n targetRemotes: Remote[],\n options?: { force?: boolean },\n ): void {\n const { host } = this;\n const normalizeRemote = () => {\n if (remote.alias) {\n // Validate if alias equals the prefix of remote.name and remote.alias, if so, throw an error\n // As multi-level path references cannot guarantee unique names, alias being a prefix of remote.name is not supported\n const findEqual = targetRemotes.find(\n (item) =>\n remote.alias &&\n (item.name.startsWith(remote.alias) ||\n item.alias?.startsWith(remote.alias)),\n );\n assert(\n !findEqual,\n `The alias ${remote.alias} of remote ${\n remote.name\n } is not allowed to be the prefix of ${\n findEqual && findEqual.name\n } name or alias`,\n );\n }\n // Set the remote entry to a complete path\n if ('entry' in remote) {\n if (\n isBrowserEnvValue &&\n typeof window !== 'undefined' &&\n !remote.entry.startsWith('http')\n ) {\n remote.entry = new URL(remote.entry, window.location.origin).href;\n }\n }\n if (!remote.shareScope) {\n remote.shareScope = DEFAULT_SCOPE;\n }\n if (!remote.type) {\n remote.type = DEFAULT_REMOTE_TYPE;\n }\n };\n this.hooks.lifecycle.beforeRegisterRemote.emit({ remote, origin: host });\n const registeredRemote = targetRemotes.find(\n (item) => item.name === remote.name,\n );\n if (!registeredRemote) {\n normalizeRemote();\n targetRemotes.push(remote);\n this.hooks.lifecycle.registerRemote.emit({ remote, origin: host });\n } else {\n const messages = [\n `The remote \"${remote.name}\" is already registered.`,\n 'Please note that overriding it may cause unexpected errors.',\n ];\n if (options?.force) {\n // remove registered remote\n this.removeRemote(registeredRemote);\n normalizeRemote();\n targetRemotes.push(remote);\n this.hooks.lifecycle.registerRemote.emit({ remote, origin: host });\n warn(messages.join(' '));\n }\n }\n }\n\n private removeRemote(remote: Remote): void {\n try {\n const { host } = this;\n const { name } = remote;\n const remoteIndex = host.options.remotes.findIndex(\n (item) => item.name === name,\n );\n if (remoteIndex !== -1) {\n host.options.remotes.splice(remoteIndex, 1);\n }\n const loadedModule = host.moduleCache.get(remote.name);\n if (loadedModule) {\n const remoteInfo = loadedModule.remoteInfo;\n const key = remoteInfo.entryGlobalName as keyof typeof CurrentGlobal;\n\n if (CurrentGlobal[key]) {\n if (\n Object.getOwnPropertyDescriptor(CurrentGlobal, key)?.configurable\n ) {\n delete CurrentGlobal[key];\n } else {\n // @ts-ignore\n CurrentGlobal[key] = undefined;\n }\n }\n const remoteEntryUniqueKey = getRemoteEntryUniqueKey(\n loadedModule.remoteInfo,\n );\n\n if (globalLoading[remoteEntryUniqueKey]) {\n delete globalLoading[remoteEntryUniqueKey];\n }\n\n host.snapshotHandler.manifestCache.delete(remoteInfo.entry);\n\n // delete unloaded shared and instance\n let remoteInsId = remoteInfo.buildVersion\n ? composeKeyWithSeparator(remoteInfo.name, remoteInfo.buildVersion)\n : remoteInfo.name;\n const remoteInsIndex =\n CurrentGlobal.__FEDERATION__.__INSTANCES__.findIndex((ins) => {\n if (remoteInfo.buildVersion) {\n return ins.options.id === remoteInsId;\n } else {\n return ins.name === remoteInsId;\n }\n });\n if (remoteInsIndex !== -1) {\n const remoteIns =\n CurrentGlobal.__FEDERATION__.__INSTANCES__[remoteInsIndex];\n remoteInsId = remoteIns.options.id || remoteInsId;\n const globalShareScopeMap = getGlobalShareScope();\n\n let isAllSharedNotUsed = true;\n const needDeleteKeys: Array<[string, string, string, string]> = [];\n Object.keys(globalShareScopeMap).forEach((instId) => {\n const shareScopeMap = globalShareScopeMap[instId];\n shareScopeMap &&\n Object.keys(shareScopeMap).forEach((shareScope) => {\n const shareScopeVal = shareScopeMap[shareScope];\n shareScopeVal &&\n Object.keys(shareScopeVal).forEach((shareName) => {\n const sharedPkgs = shareScopeVal[shareName];\n sharedPkgs &&\n Object.keys(sharedPkgs).forEach((shareVersion) => {\n const shared = sharedPkgs[shareVersion];\n if (\n shared &&\n typeof shared === 'object' &&\n shared.from === remoteInfo.name\n ) {\n if (shared.loaded || shared.loading) {\n shared.useIn = shared.useIn.filter(\n (usedHostName) =>\n usedHostName !== remoteInfo.name,\n );\n if (shared.useIn.length) {\n isAllSharedNotUsed = false;\n } else {\n needDeleteKeys.push([\n instId,\n shareScope,\n shareName,\n shareVersion,\n ]);\n }\n } else {\n needDeleteKeys.push([\n instId,\n shareScope,\n shareName,\n shareVersion,\n ]);\n }\n }\n });\n });\n });\n });\n\n if (isAllSharedNotUsed) {\n remoteIns.shareScopeMap = {};\n delete globalShareScopeMap[remoteInsId];\n }\n needDeleteKeys.forEach(\n ([insId, shareScope, shareName, shareVersion]) => {\n delete globalShareScopeMap[insId]?.[shareScope]?.[shareName]?.[\n shareVersion\n ];\n },\n );\n CurrentGlobal.__FEDERATION__.__INSTANCES__.splice(remoteInsIndex, 1);\n }\n\n const { hostGlobalSnapshot } = getGlobalRemoteInfo(remote, host);\n if (hostGlobalSnapshot) {\n const remoteKey =\n hostGlobalSnapshot &&\n 'remotesInfo' in hostGlobalSnapshot &&\n hostGlobalSnapshot.remotesInfo &&\n getInfoWithoutType(hostGlobalSnapshot.remotesInfo, remote.name).key;\n if (remoteKey) {\n delete hostGlobalSnapshot.remotesInfo[remoteKey];\n if (\n //eslint-disable-next-line no-extra-boolean-cast\n Boolean(Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey])\n ) {\n delete Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey];\n }\n }\n }\n\n host.moduleCache.delete(remote.name);\n }\n } catch (err) {\n logger.error(\n `removeRemote failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"index.cjs","names":["PluginSystem","SyncWaterfallHook","AsyncWaterfallHook","AsyncHook","SyncHook","matchRemoteWithNameAndExpose","getRemoteInfo","formatPreloadArgs","composeRemoteRequestId","preloadAssets","RUNTIME_004","runtimeDescMap","optionsToMFContext","Module","isBrowserEnvValue","DEFAULT_SCOPE","DEFAULT_REMOTE_TYPE","CurrentGlobal","getRemoteEntryUniqueKey","globalLoading","getGlobalShareScope","getGlobalRemoteInfo","getInfoWithoutType","Global"],"sources":["../../src/remote/index.ts"],"sourcesContent":["import {\n isBrowserEnvValue,\n warn,\n composeKeyWithSeparator,\n ModuleInfo,\n GlobalModuleInfo,\n} from '@module-federation/sdk';\nimport { RUNTIME_004, runtimeDescMap } from '@module-federation/error-codes';\nimport {\n Global,\n getInfoWithoutType,\n globalLoading,\n CurrentGlobal,\n} from '../global';\nimport {\n Options,\n UserOptions,\n PreloadAssets,\n PreloadOptions,\n PreloadRemoteArgs,\n PreloadRemoteResult,\n Remote,\n RemoteInfo,\n RemoteEntryExports,\n CallFrom,\n} from '../type';\nimport { ModuleFederation } from '../core';\nimport {\n PluginSystem,\n AsyncHook,\n AsyncWaterfallHook,\n SyncHook,\n SyncWaterfallHook,\n} from '../utils/hooks';\nimport {\n assert,\n error,\n getRemoteInfo,\n getRemoteEntryUniqueKey,\n composeRemoteRequestId,\n matchRemoteWithNameAndExpose,\n optionsToMFContext,\n logger,\n} from '../utils';\nimport { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from '../constant';\nimport { Module, ModuleOptions } from '../module';\nimport { formatPreloadArgs, preloadAssets } from '../utils/preload';\nimport { getGlobalShareScope } from '../utils/share';\nimport { getGlobalRemoteInfo } from '../plugins/snapshot/SnapshotHandler';\n\nexport interface LoadRemoteMatch {\n id: string;\n pkgNameOrAlias: string;\n expose: string;\n remote: Remote;\n options: Options;\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteSnapshot?: ModuleInfo;\n}\n\nexport class RemoteHandler {\n host: ModuleFederation;\n idToRemoteMap: Record<string, { name: string; expose: string }>;\n\n hooks = new PluginSystem({\n beforeRegisterRemote: new SyncWaterfallHook<{\n remote: Remote;\n origin: ModuleFederation;\n }>('beforeRegisterRemote'),\n registerRemote: new SyncWaterfallHook<{\n remote: Remote;\n origin: ModuleFederation;\n }>('registerRemote'),\n beforeRequest: new AsyncWaterfallHook<{\n id: string;\n options: Options;\n origin: ModuleFederation;\n }>('beforeRequest'),\n afterMatchRemote: new AsyncHook<\n [\n {\n id: string;\n options: Options;\n remote?: Remote;\n expose?: string;\n remoteInfo?: RemoteInfo;\n error?: unknown;\n origin: ModuleFederation;\n },\n ],\n void\n >('afterMatchRemote'),\n onLoad: new AsyncHook<\n [\n {\n id: string;\n expose: string;\n pkgNameOrAlias: string;\n remote: Remote;\n options: ModuleOptions;\n origin: ModuleFederation;\n exposeModule: any;\n exposeModuleFactory: any;\n moduleInstance: Module;\n },\n ],\n unknown\n >('onLoad'),\n afterLoadRemote: new AsyncHook<\n [\n {\n id: string;\n expose?: string;\n remote?: RemoteInfo;\n options?: {\n loadFactory?: boolean;\n from?: CallFrom;\n };\n error?: unknown;\n recovered?: boolean;\n origin: ModuleFederation;\n },\n ],\n void\n >('afterLoadRemote'),\n handlePreloadModule: new SyncHook<\n [\n {\n id: string;\n name: string;\n remote: Remote;\n remoteSnapshot: ModuleInfo;\n preloadConfig: PreloadRemoteArgs;\n origin: ModuleFederation;\n },\n ],\n void\n >('handlePreloadModule'),\n errorLoadRemote: new AsyncHook<\n [\n {\n id: string;\n error: unknown;\n options?: any;\n from: CallFrom;\n lifecycle:\n | 'beforeRequest'\n | 'beforeLoadShare'\n | 'afterResolve'\n | 'onLoad';\n remote?: RemoteInfo;\n expose?: string;\n origin: ModuleFederation;\n },\n ],\n void | unknown\n >('errorLoadRemote'),\n beforePreloadRemote: new AsyncHook<\n [\n {\n preloadOps: Array<PreloadRemoteArgs>;\n options: Options;\n origin: ModuleFederation;\n },\n ]\n >('beforePreloadRemote'),\n generatePreloadAssets: new AsyncHook<\n [\n {\n origin: ModuleFederation;\n preloadOptions: PreloadOptions[number];\n remote: Remote;\n remoteInfo: RemoteInfo;\n remoteSnapshot: ModuleInfo;\n globalSnapshot: GlobalModuleInfo;\n },\n ],\n Promise<PreloadAssets>\n >('generatePreloadAssets'),\n afterPreloadRemote: new AsyncHook<\n [\n {\n preloadOps: Array<PreloadRemoteArgs>;\n options: Options;\n origin: ModuleFederation;\n results: PreloadRemoteResult[];\n error?: unknown;\n },\n ]\n >('afterPreloadRemote'),\n // TODO: Move to loaderHook\n loadEntry: new AsyncHook<\n [\n {\n origin: ModuleFederation;\n loaderHook: ModuleFederation['loaderHook'];\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports;\n },\n ],\n Promise<RemoteEntryExports | void> | RemoteEntryExports | void\n >(),\n });\n\n constructor(host: ModuleFederation) {\n this.host = host;\n this.idToRemoteMap = {};\n }\n\n formatAndRegisterRemote(globalOptions: Options, userOptions: UserOptions) {\n const userRemotes = userOptions.remotes || [];\n\n return userRemotes.reduce((res, remote) => {\n this.registerRemote(remote, res, { force: false });\n return res;\n }, globalOptions.remotes);\n }\n\n setIdToRemoteMap(id: string, remoteMatchInfo: LoadRemoteMatch) {\n const { remote, expose } = remoteMatchInfo;\n const { name, alias } = remote;\n this.idToRemoteMap[id] = { name: remote.name, expose };\n if (alias && id.startsWith(name)) {\n const idWithAlias = id.replace(name, alias);\n this.idToRemoteMap[idWithAlias] = { name: remote.name, expose };\n return;\n }\n\n if (alias && id.startsWith(alias)) {\n const idWithName = id.replace(alias, name);\n this.idToRemoteMap[idWithName] = { name: remote.name, expose };\n }\n }\n\n // eslint-disable-next-line max-lines-per-function\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async loadRemote<T>(\n id: string,\n options?: { loadFactory?: boolean; from: CallFrom },\n ): Promise<T | null> {\n const { host } = this;\n const startMatchInfo = matchRemoteWithNameAndExpose(\n host.options.remotes,\n id,\n );\n let completeRequestId = id;\n let completeExpose = startMatchInfo?.expose;\n let completeRemote = startMatchInfo\n ? getRemoteInfo(startMatchInfo.remote)\n : undefined;\n let afterLoadRemoteArgs:\n | Parameters<\n RemoteHandler['hooks']['lifecycle']['afterLoadRemote']['emit']\n >[0]\n | undefined;\n\n try {\n const { loadFactory = true } = options || {\n loadFactory: true,\n };\n // 1. Validate the parameters of the retrieved module. There are two module request methods: pkgName + expose and alias + expose.\n // 2. Request the snapshot information of the current host and globally store the obtained snapshot information. The retrieved module information is partially offline and partially online. The online module information will retrieve the modules used online.\n // 3. Retrieve the detailed information of the current module from global (remoteEntry address, expose resource address)\n // 4. After retrieving remoteEntry, call the init of the module, and then retrieve the exported content of the module through get\n // id: pkgName(@federation/app1) + expose(button) = @federation/app1/button\n // id: alias(app1) + expose(button) = app1/button\n // id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort\n const { module, moduleOptions, remoteMatchInfo } =\n await this.getRemoteModuleAndOptions({\n id,\n });\n const {\n pkgNameOrAlias,\n remote,\n expose,\n id: idRes,\n remoteSnapshot,\n } = remoteMatchInfo;\n completeRequestId = idRes;\n completeExpose = expose;\n completeRemote = getRemoteInfo(remote);\n\n const moduleOrFactory = (await module.get(\n idRes,\n expose,\n options,\n remoteSnapshot,\n )) as T;\n\n const moduleWrapper = await this.hooks.lifecycle.onLoad.emit({\n id: idRes,\n pkgNameOrAlias,\n expose,\n exposeModule: loadFactory ? moduleOrFactory : undefined,\n exposeModuleFactory: loadFactory ? undefined : moduleOrFactory,\n remote,\n options: moduleOptions,\n moduleInstance: module,\n origin: host,\n });\n\n this.setIdToRemoteMap(id, remoteMatchInfo);\n afterLoadRemoteArgs = {\n id: completeRequestId,\n expose: completeExpose,\n remote: completeRemote,\n options,\n origin: host,\n };\n\n if (typeof moduleWrapper === 'function') {\n return moduleWrapper as T;\n }\n\n return moduleOrFactory;\n } catch (error) {\n const { from = 'runtime' } = options || { from: 'runtime' };\n\n let failOver;\n try {\n failOver = await this.hooks.lifecycle.errorLoadRemote.emit({\n id,\n error,\n from,\n lifecycle: 'onLoad',\n expose: completeExpose,\n remote: completeRemote,\n origin: host,\n });\n } catch (hookError) {\n afterLoadRemoteArgs = {\n id: completeRequestId,\n expose: completeExpose,\n remote: completeRemote,\n options,\n error: hookError,\n origin: host,\n };\n throw hookError;\n }\n\n if (!failOver) {\n afterLoadRemoteArgs = {\n id: completeRequestId,\n expose: completeExpose,\n remote: completeRemote,\n options,\n error,\n origin: host,\n };\n throw error;\n }\n\n afterLoadRemoteArgs = {\n id: completeRequestId,\n expose: completeExpose,\n remote: completeRemote,\n options,\n error,\n origin: host,\n recovered: true,\n };\n\n return failOver as T;\n } finally {\n if (afterLoadRemoteArgs) {\n await this.hooks.lifecycle.afterLoadRemote.emit(afterLoadRemoteArgs);\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void> {\n const { host } = this;\n const preloadResults: PreloadRemoteResult[] = [];\n\n await this.hooks.lifecycle.beforePreloadRemote.emit({\n preloadOps: preloadOptions,\n options: host.options,\n origin: host,\n });\n\n const preloadOps: PreloadOptions = formatPreloadArgs(\n host.options.remotes,\n preloadOptions,\n );\n\n const createPreloadAssetOps = (ops: PreloadOptions[number]) => {\n const { preloadConfig, remote } = ops;\n const exposes = preloadConfig.exposes || [];\n\n if (!exposes.length) {\n return [\n {\n ops,\n id: `${remote.name}/*`,\n },\n ];\n }\n\n return exposes.map((expose) => ({\n ops: {\n ...ops,\n preloadConfig: {\n ...preloadConfig,\n exposes: [expose],\n },\n },\n id: composeRemoteRequestId(remote.name, expose),\n }));\n };\n\n let preloadError: Error | undefined;\n\n await Promise.all(\n preloadOps.flatMap(createPreloadAssetOps).map(async (assetOps) => {\n const { ops, id: preloadId } = assetOps;\n const { remote, preloadConfig } = ops;\n const remoteInfo = getRemoteInfo(remote);\n try {\n const { globalSnapshot, remoteSnapshot } =\n await host.snapshotHandler.loadRemoteSnapshotInfo({\n moduleInfo: remote,\n id: preloadId,\n initiator: 'preloadRemote',\n });\n\n const assets = await this.hooks.lifecycle.generatePreloadAssets.emit({\n origin: host,\n preloadOptions: ops,\n remote,\n remoteInfo,\n globalSnapshot,\n remoteSnapshot,\n });\n if (!assets) {\n return;\n }\n const results = await preloadAssets(remoteInfo, host, assets, true, {\n initiator: 'preloadRemote',\n id: preloadId,\n });\n preloadResults.push({\n remote,\n remoteInfo,\n preloadConfig,\n id: preloadId,\n results,\n });\n } catch (error) {\n preloadResults.push({\n remote,\n remoteInfo,\n preloadConfig,\n id: preloadId,\n results: [\n {\n url: remoteInfo.entry,\n status: 'error',\n resourceType: /\\.json(?:$|[?#])/i.test(remoteInfo.entry)\n ? 'manifest'\n : 'remoteEntry',\n initiator: 'preloadRemote',\n id: preloadId,\n error,\n },\n ],\n });\n }\n }),\n );\n\n const failedResults = preloadResults.flatMap((preloadResult) =>\n preloadResult.results.filter(\n (result) => result.status === 'error' || result.status === 'timeout',\n ),\n );\n if (failedResults.length > 0) {\n preloadError = new Error(\n `preloadRemote failed to load ${failedResults.length} resource(s).`,\n );\n Object.assign(preloadError, {\n results: preloadResults,\n failedResults,\n });\n }\n\n await this.hooks.lifecycle.afterPreloadRemote.emit({\n preloadOps: preloadOptions,\n options: host.options,\n origin: host,\n results: preloadResults,\n error: preloadError,\n });\n\n if (preloadError) {\n throw preloadError;\n }\n }\n\n registerRemotes(remotes: Remote[], options?: { force?: boolean }): void {\n const { host } = this;\n remotes.forEach((remote) => {\n this.registerRemote(remote, host.options.remotes, {\n force: options?.force,\n });\n });\n }\n\n async getRemoteModuleAndOptions(options: { id: string }): Promise<{\n module: Module;\n moduleOptions: ModuleOptions;\n remoteMatchInfo: LoadRemoteMatch;\n }> {\n const { host } = this;\n const { id } = options;\n let loadRemoteArgs;\n\n try {\n loadRemoteArgs = await this.hooks.lifecycle.beforeRequest.emit({\n id,\n options: host.options,\n origin: host,\n });\n } catch (error) {\n loadRemoteArgs = (await this.hooks.lifecycle.errorLoadRemote.emit({\n id,\n options: host.options,\n origin: host,\n from: 'runtime',\n error,\n lifecycle: 'beforeRequest',\n })) as {\n id: string;\n options: Options;\n origin: ModuleFederation;\n };\n\n if (!loadRemoteArgs) {\n throw error;\n }\n }\n\n const { id: idRes } = loadRemoteArgs;\n\n const remoteSplitInfo = matchRemoteWithNameAndExpose(\n host.options.remotes,\n idRes,\n );\n if (!remoteSplitInfo) {\n try {\n error(\n RUNTIME_004,\n runtimeDescMap,\n {\n hostName: host.options.name,\n requestId: idRes,\n },\n undefined,\n optionsToMFContext(host.options),\n );\n } catch (matchError) {\n await this.hooks.lifecycle.afterMatchRemote.emit({\n id: idRes,\n options: host.options,\n error: matchError,\n origin: host,\n });\n throw matchError;\n }\n }\n\n const { remote: rawRemote } = remoteSplitInfo;\n const remoteInfo = getRemoteInfo(rawRemote);\n await this.hooks.lifecycle.afterMatchRemote.emit({\n id: idRes,\n ...remoteSplitInfo,\n options: host.options,\n remoteInfo,\n origin: host,\n });\n const matchInfo =\n await host.sharedHandler.hooks.lifecycle.afterResolve.emit({\n id: idRes,\n ...remoteSplitInfo,\n options: host.options,\n origin: host,\n remoteInfo,\n });\n\n const { remote, expose } = matchInfo;\n assert(\n remote && expose,\n `The 'beforeRequest' hook was executed, but it failed to return the correct 'remote' and 'expose' values while loading ${idRes}.`,\n );\n let module: Module | undefined = host.moduleCache.get(remote.name);\n\n const moduleOptions: ModuleOptions = {\n host: host,\n remoteInfo,\n };\n\n if (!module) {\n module = new Module(moduleOptions);\n host.moduleCache.set(remote.name, module);\n }\n return {\n module,\n moduleOptions,\n remoteMatchInfo: matchInfo,\n };\n }\n\n registerRemote(\n remote: Remote,\n targetRemotes: Remote[],\n options?: { force?: boolean },\n ): void {\n const { host } = this;\n const normalizeRemote = () => {\n if (remote.alias) {\n // Validate if alias equals the prefix of remote.name and remote.alias, if so, throw an error\n // As multi-level path references cannot guarantee unique names, alias being a prefix of remote.name is not supported\n const findEqual = targetRemotes.find(\n (item) =>\n remote.alias &&\n (item.name.startsWith(remote.alias) ||\n item.alias?.startsWith(remote.alias)),\n );\n assert(\n !findEqual,\n `The alias ${remote.alias} of remote ${\n remote.name\n } is not allowed to be the prefix of ${\n findEqual && findEqual.name\n } name or alias`,\n );\n }\n // Set the remote entry to a complete path\n if ('entry' in remote) {\n if (\n isBrowserEnvValue &&\n typeof window !== 'undefined' &&\n !remote.entry.startsWith('http')\n ) {\n remote.entry = new URL(remote.entry, window.location.origin).href;\n }\n }\n if (!remote.shareScope) {\n remote.shareScope = DEFAULT_SCOPE;\n }\n if (!remote.type) {\n remote.type = DEFAULT_REMOTE_TYPE;\n }\n };\n this.hooks.lifecycle.beforeRegisterRemote.emit({ remote, origin: host });\n const registeredRemote = targetRemotes.find(\n (item) => item.name === remote.name,\n );\n if (!registeredRemote) {\n normalizeRemote();\n targetRemotes.push(remote);\n this.hooks.lifecycle.registerRemote.emit({ remote, origin: host });\n } else {\n const messages = [\n `The remote \"${remote.name}\" is already registered.`,\n 'Please note that overriding it may cause unexpected errors.',\n ];\n if (options?.force) {\n // remove registered remote\n this.removeRemote(registeredRemote);\n normalizeRemote();\n targetRemotes.push(remote);\n this.hooks.lifecycle.registerRemote.emit({ remote, origin: host });\n warn(messages.join(' '));\n }\n }\n }\n\n private removeRemote(remote: Remote): void {\n try {\n const { host } = this;\n const { name } = remote;\n const remoteIndex = host.options.remotes.findIndex(\n (item) => item.name === name,\n );\n if (remoteIndex !== -1) {\n host.options.remotes.splice(remoteIndex, 1);\n }\n const loadedModule = host.moduleCache.get(remote.name);\n if (loadedModule) {\n const remoteInfo = loadedModule.remoteInfo;\n const key = remoteInfo.entryGlobalName as keyof typeof CurrentGlobal;\n\n if (CurrentGlobal[key]) {\n if (\n Object.getOwnPropertyDescriptor(CurrentGlobal, key)?.configurable\n ) {\n delete CurrentGlobal[key];\n } else {\n // @ts-ignore\n CurrentGlobal[key] = undefined;\n }\n }\n const remoteEntryUniqueKey = getRemoteEntryUniqueKey(\n loadedModule.remoteInfo,\n );\n\n if (globalLoading[remoteEntryUniqueKey]) {\n delete globalLoading[remoteEntryUniqueKey];\n }\n\n host.snapshotHandler.manifestCache.delete(remoteInfo.entry);\n\n // delete unloaded shared and instance\n let remoteInsId = remoteInfo.buildVersion\n ? composeKeyWithSeparator(remoteInfo.name, remoteInfo.buildVersion)\n : remoteInfo.name;\n const remoteInsIndex =\n CurrentGlobal.__FEDERATION__.__INSTANCES__.findIndex((ins) => {\n if (remoteInfo.buildVersion) {\n return ins.options.id === remoteInsId;\n } else {\n return ins.name === remoteInsId;\n }\n });\n if (remoteInsIndex !== -1) {\n const remoteIns =\n CurrentGlobal.__FEDERATION__.__INSTANCES__[remoteInsIndex];\n remoteInsId = remoteIns.options.id || remoteInsId;\n const globalShareScopeMap = getGlobalShareScope();\n\n let isAllSharedNotUsed = true;\n const needDeleteKeys: Array<[string, string, string, string]> = [];\n Object.keys(globalShareScopeMap).forEach((instId) => {\n const shareScopeMap = globalShareScopeMap[instId];\n shareScopeMap &&\n Object.keys(shareScopeMap).forEach((shareScope) => {\n const shareScopeVal = shareScopeMap[shareScope];\n shareScopeVal &&\n Object.keys(shareScopeVal).forEach((shareName) => {\n const sharedPkgs = shareScopeVal[shareName];\n sharedPkgs &&\n Object.keys(sharedPkgs).forEach((shareVersion) => {\n const shared = sharedPkgs[shareVersion];\n if (\n shared &&\n typeof shared === 'object' &&\n shared.from === remoteInfo.name\n ) {\n if (shared.loaded || shared.loading) {\n shared.useIn = shared.useIn.filter(\n (usedHostName) =>\n usedHostName !== remoteInfo.name,\n );\n if (shared.useIn.length) {\n isAllSharedNotUsed = false;\n } else {\n needDeleteKeys.push([\n instId,\n shareScope,\n shareName,\n shareVersion,\n ]);\n }\n } else {\n needDeleteKeys.push([\n instId,\n shareScope,\n shareName,\n shareVersion,\n ]);\n }\n }\n });\n });\n });\n });\n\n if (isAllSharedNotUsed) {\n remoteIns.shareScopeMap = {};\n delete globalShareScopeMap[remoteInsId];\n }\n needDeleteKeys.forEach(\n ([insId, shareScope, shareName, shareVersion]) => {\n delete globalShareScopeMap[insId]?.[shareScope]?.[shareName]?.[\n shareVersion\n ];\n },\n );\n CurrentGlobal.__FEDERATION__.__INSTANCES__.splice(remoteInsIndex, 1);\n }\n\n const { hostGlobalSnapshot } = getGlobalRemoteInfo(remote, host);\n if (hostGlobalSnapshot) {\n const remoteKey =\n hostGlobalSnapshot &&\n 'remotesInfo' in hostGlobalSnapshot &&\n hostGlobalSnapshot.remotesInfo &&\n getInfoWithoutType(hostGlobalSnapshot.remotesInfo, remote.name).key;\n if (remoteKey) {\n delete hostGlobalSnapshot.remotesInfo[remoteKey];\n if (\n //eslint-disable-next-line no-extra-boolean-cast\n Boolean(Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey])\n ) {\n delete Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey];\n }\n }\n }\n\n host.moduleCache.delete(remote.name);\n }\n } catch (err) {\n logger.error(\n `removeRemote failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n}\n"],"mappings":"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"} |
@@ -9,3 +9,3 @@ import { Module as Module$1, ModuleOptions } from "../module/index.js"; | ||
| import { CallFrom, Options, Remote, RemoteEntryExports, RemoteInfo, UserOptions } from "../type/config.js"; | ||
| import { PreloadAssets, PreloadOptions, PreloadRemoteArgs } from "../type/preload.js"; | ||
| import { PreloadAssets, PreloadOptions, PreloadRemoteArgs, PreloadRemoteResult } from "../type/preload.js"; | ||
| import { GlobalModuleInfo, ModuleInfo } from "@module-federation/sdk"; | ||
@@ -44,2 +44,11 @@ | ||
| }>; | ||
| afterMatchRemote: AsyncHook<[{ | ||
| id: string; | ||
| options: Options; | ||
| remote?: Remote; | ||
| expose?: string; | ||
| remoteInfo?: RemoteInfo; | ||
| error?: unknown; | ||
| origin: ModuleFederation; | ||
| }], void>; | ||
| onLoad: AsyncHook<[{ | ||
@@ -55,2 +64,14 @@ id: string; | ||
| moduleInstance: Module$1; | ||
| }], unknown>; | ||
| afterLoadRemote: AsyncHook<[{ | ||
| id: string; | ||
| expose?: string; | ||
| remote?: RemoteInfo; | ||
| options?: { | ||
| loadFactory?: boolean; | ||
| from?: CallFrom; | ||
| }; | ||
| error?: unknown; | ||
| recovered?: boolean; | ||
| origin: ModuleFederation; | ||
| }], void>; | ||
@@ -71,2 +92,4 @@ handlePreloadModule: SyncHook<[{ | ||
| lifecycle: "beforeRequest" | "beforeLoadShare" | "afterResolve" | "onLoad"; | ||
| remote?: RemoteInfo; | ||
| expose?: string; | ||
| origin: ModuleFederation; | ||
@@ -87,12 +110,15 @@ }], unknown>; | ||
| }], Promise<PreloadAssets>>; | ||
| afterPreloadRemote: AsyncHook<{ | ||
| afterPreloadRemote: AsyncHook<[{ | ||
| preloadOps: Array<PreloadRemoteArgs>; | ||
| options: Options; | ||
| origin: ModuleFederation; | ||
| }, false | void | Promise<false | void>>; | ||
| results: PreloadRemoteResult[]; | ||
| error?: unknown; | ||
| }], false | void | Promise<false | void>>; | ||
| loadEntry: AsyncHook<[{ | ||
| origin: ModuleFederation; | ||
| loaderHook: ModuleFederation["loaderHook"]; | ||
| remoteInfo: RemoteInfo; | ||
| remoteEntryExports?: RemoteEntryExports; | ||
| }], Promise<RemoteEntryExports>>; | ||
| }], void | RemoteEntryExports | Promise<void | RemoteEntryExports>>; | ||
| }>; | ||
@@ -99,0 +125,0 @@ constructor(host: ModuleFederation); |
+164
-26
@@ -5,3 +5,3 @@ import { assert, error, logger } from "../utils/logger.js"; | ||
| import { getGlobalShareScope } from "../utils/share.js"; | ||
| import { matchRemoteWithNameAndExpose } from "../utils/manifest.js"; | ||
| import { composeRemoteRequestId, matchRemoteWithNameAndExpose } from "../utils/manifest.js"; | ||
| import { getRemoteEntryUniqueKey, getRemoteInfo } from "../utils/load.js"; | ||
@@ -29,3 +29,5 @@ import { optionsToMFContext } from "../utils/context.js"; | ||
| beforeRequest: new AsyncWaterfallHook("beforeRequest"), | ||
| afterMatchRemote: new AsyncHook("afterMatchRemote"), | ||
| onLoad: new AsyncHook("onLoad"), | ||
| afterLoadRemote: new AsyncHook("afterLoadRemote"), | ||
| handlePreloadModule: new SyncHook("handlePreloadModule"), | ||
@@ -35,3 +37,3 @@ errorLoadRemote: new AsyncHook("errorLoadRemote"), | ||
| generatePreloadAssets: new AsyncHook("generatePreloadAssets"), | ||
| afterPreloadRemote: new AsyncHook(), | ||
| afterPreloadRemote: new AsyncHook("afterPreloadRemote"), | ||
| loadEntry: new AsyncHook() | ||
@@ -73,2 +75,7 @@ }); | ||
| const { host } = this; | ||
| const startMatchInfo = matchRemoteWithNameAndExpose(host.options.remotes, id); | ||
| let completeRequestId = id; | ||
| let completeExpose = startMatchInfo?.expose; | ||
| let completeRemote = startMatchInfo ? getRemoteInfo(startMatchInfo.remote) : void 0; | ||
| let afterLoadRemoteArgs; | ||
| try { | ||
@@ -78,2 +85,5 @@ const { loadFactory = true } = options || { loadFactory: true }; | ||
| const { pkgNameOrAlias, remote, expose, id: idRes, remoteSnapshot } = remoteMatchInfo; | ||
| completeRequestId = idRes; | ||
| completeExpose = expose; | ||
| completeRemote = getRemoteInfo(remote); | ||
| const moduleOrFactory = await module.get(idRes, expose, options, remoteSnapshot); | ||
@@ -92,2 +102,9 @@ const moduleWrapper = await this.hooks.lifecycle.onLoad.emit({ | ||
| this.setIdToRemoteMap(id, remoteMatchInfo); | ||
| afterLoadRemoteArgs = { | ||
| id: completeRequestId, | ||
| expose: completeExpose, | ||
| remote: completeRemote, | ||
| options, | ||
| origin: host | ||
| }; | ||
| if (typeof moduleWrapper === "function") return moduleWrapper; | ||
@@ -97,11 +114,47 @@ return moduleOrFactory; | ||
| const { from = "runtime" } = options || { from: "runtime" }; | ||
| const failOver = await this.hooks.lifecycle.errorLoadRemote.emit({ | ||
| id, | ||
| let failOver; | ||
| try { | ||
| failOver = await this.hooks.lifecycle.errorLoadRemote.emit({ | ||
| id, | ||
| error, | ||
| from, | ||
| lifecycle: "onLoad", | ||
| expose: completeExpose, | ||
| remote: completeRemote, | ||
| origin: host | ||
| }); | ||
| } catch (hookError) { | ||
| afterLoadRemoteArgs = { | ||
| id: completeRequestId, | ||
| expose: completeExpose, | ||
| remote: completeRemote, | ||
| options, | ||
| error: hookError, | ||
| origin: host | ||
| }; | ||
| throw hookError; | ||
| } | ||
| if (!failOver) { | ||
| afterLoadRemoteArgs = { | ||
| id: completeRequestId, | ||
| expose: completeExpose, | ||
| remote: completeRemote, | ||
| options, | ||
| error, | ||
| origin: host | ||
| }; | ||
| throw error; | ||
| } | ||
| afterLoadRemoteArgs = { | ||
| id: completeRequestId, | ||
| expose: completeExpose, | ||
| remote: completeRemote, | ||
| options, | ||
| error, | ||
| from, | ||
| lifecycle: "onLoad", | ||
| origin: host | ||
| }); | ||
| if (!failOver) throw error; | ||
| origin: host, | ||
| recovered: true | ||
| }; | ||
| return failOver; | ||
| } finally { | ||
| if (afterLoadRemoteArgs) await this.hooks.lifecycle.afterLoadRemote.emit(afterLoadRemoteArgs); | ||
| } | ||
@@ -111,2 +164,3 @@ } | ||
| const { host } = this; | ||
| const preloadResults = []; | ||
| await this.hooks.lifecycle.beforePreloadRemote.emit({ | ||
@@ -118,17 +172,84 @@ preloadOps: preloadOptions, | ||
| const preloadOps = formatPreloadArgs(host.options.remotes, preloadOptions); | ||
| await Promise.all(preloadOps.map(async (ops) => { | ||
| const { remote } = ops; | ||
| const createPreloadAssetOps = (ops) => { | ||
| const { preloadConfig, remote } = ops; | ||
| const exposes = preloadConfig.exposes || []; | ||
| if (!exposes.length) return [{ | ||
| ops, | ||
| id: `${remote.name}/*` | ||
| }]; | ||
| return exposes.map((expose) => ({ | ||
| ops: { | ||
| ...ops, | ||
| preloadConfig: { | ||
| ...preloadConfig, | ||
| exposes: [expose] | ||
| } | ||
| }, | ||
| id: composeRemoteRequestId(remote.name, expose) | ||
| })); | ||
| }; | ||
| let preloadError; | ||
| await Promise.all(preloadOps.flatMap(createPreloadAssetOps).map(async (assetOps) => { | ||
| const { ops, id: preloadId } = assetOps; | ||
| const { remote, preloadConfig } = ops; | ||
| const remoteInfo = getRemoteInfo(remote); | ||
| const { globalSnapshot, remoteSnapshot } = await host.snapshotHandler.loadRemoteSnapshotInfo({ moduleInfo: remote }); | ||
| const assets = await this.hooks.lifecycle.generatePreloadAssets.emit({ | ||
| origin: host, | ||
| preloadOptions: ops, | ||
| remote, | ||
| remoteInfo, | ||
| globalSnapshot, | ||
| remoteSnapshot | ||
| try { | ||
| const { globalSnapshot, remoteSnapshot } = await host.snapshotHandler.loadRemoteSnapshotInfo({ | ||
| moduleInfo: remote, | ||
| id: preloadId, | ||
| initiator: "preloadRemote" | ||
| }); | ||
| const assets = await this.hooks.lifecycle.generatePreloadAssets.emit({ | ||
| origin: host, | ||
| preloadOptions: ops, | ||
| remote, | ||
| remoteInfo, | ||
| globalSnapshot, | ||
| remoteSnapshot | ||
| }); | ||
| if (!assets) return; | ||
| const results = await preloadAssets(remoteInfo, host, assets, true, { | ||
| initiator: "preloadRemote", | ||
| id: preloadId | ||
| }); | ||
| preloadResults.push({ | ||
| remote, | ||
| remoteInfo, | ||
| preloadConfig, | ||
| id: preloadId, | ||
| results | ||
| }); | ||
| } catch (error) { | ||
| preloadResults.push({ | ||
| remote, | ||
| remoteInfo, | ||
| preloadConfig, | ||
| id: preloadId, | ||
| results: [{ | ||
| url: remoteInfo.entry, | ||
| status: "error", | ||
| resourceType: /\.json(?:$|[?#])/i.test(remoteInfo.entry) ? "manifest" : "remoteEntry", | ||
| initiator: "preloadRemote", | ||
| id: preloadId, | ||
| error | ||
| }] | ||
| }); | ||
| } | ||
| })); | ||
| const failedResults = preloadResults.flatMap((preloadResult) => preloadResult.results.filter((result) => result.status === "error" || result.status === "timeout")); | ||
| if (failedResults.length > 0) { | ||
| preloadError = /* @__PURE__ */ new Error(`preloadRemote failed to load ${failedResults.length} resource(s).`); | ||
| Object.assign(preloadError, { | ||
| results: preloadResults, | ||
| failedResults | ||
| }); | ||
| if (!assets) return; | ||
| preloadAssets(remoteInfo, host, assets); | ||
| })); | ||
| } | ||
| await this.hooks.lifecycle.afterPreloadRemote.emit({ | ||
| preloadOps: preloadOptions, | ||
| options: host.options, | ||
| origin: host, | ||
| results: preloadResults, | ||
| error: preloadError | ||
| }); | ||
| if (preloadError) throw preloadError; | ||
| } | ||
@@ -164,8 +285,25 @@ registerRemotes(remotes, options) { | ||
| const remoteSplitInfo = matchRemoteWithNameAndExpose(host.options.remotes, idRes); | ||
| if (!remoteSplitInfo) error(RUNTIME_004, runtimeDescMap, { | ||
| hostName: host.options.name, | ||
| requestId: idRes | ||
| }, void 0, optionsToMFContext(host.options)); | ||
| if (!remoteSplitInfo) try { | ||
| error(RUNTIME_004, runtimeDescMap, { | ||
| hostName: host.options.name, | ||
| requestId: idRes | ||
| }, void 0, optionsToMFContext(host.options)); | ||
| } catch (matchError) { | ||
| await this.hooks.lifecycle.afterMatchRemote.emit({ | ||
| id: idRes, | ||
| options: host.options, | ||
| error: matchError, | ||
| origin: host | ||
| }); | ||
| throw matchError; | ||
| } | ||
| const { remote: rawRemote } = remoteSplitInfo; | ||
| const remoteInfo = getRemoteInfo(rawRemote); | ||
| await this.hooks.lifecycle.afterMatchRemote.emit({ | ||
| id: idRes, | ||
| ...remoteSplitInfo, | ||
| options: host.options, | ||
| remoteInfo, | ||
| origin: host | ||
| }); | ||
| const matchInfo = await host.sharedHandler.hooks.lifecycle.afterResolve.emit({ | ||
@@ -172,0 +310,0 @@ id: idRes, |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","names":["Module"],"sources":["../../src/remote/index.ts"],"sourcesContent":["import {\n isBrowserEnvValue,\n warn,\n composeKeyWithSeparator,\n ModuleInfo,\n GlobalModuleInfo,\n} from '@module-federation/sdk';\nimport { RUNTIME_004, runtimeDescMap } from '@module-federation/error-codes';\nimport {\n Global,\n getInfoWithoutType,\n globalLoading,\n CurrentGlobal,\n} from '../global';\nimport {\n Options,\n UserOptions,\n PreloadAssets,\n PreloadOptions,\n PreloadRemoteArgs,\n Remote,\n RemoteInfo,\n RemoteEntryExports,\n CallFrom,\n} from '../type';\nimport { ModuleFederation } from '../core';\nimport {\n PluginSystem,\n AsyncHook,\n AsyncWaterfallHook,\n SyncHook,\n SyncWaterfallHook,\n} from '../utils/hooks';\nimport {\n assert,\n error,\n getRemoteInfo,\n getRemoteEntryUniqueKey,\n matchRemoteWithNameAndExpose,\n optionsToMFContext,\n logger,\n} from '../utils';\nimport { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from '../constant';\nimport { Module, ModuleOptions } from '../module';\nimport { formatPreloadArgs, preloadAssets } from '../utils/preload';\nimport { getGlobalShareScope } from '../utils/share';\nimport { getGlobalRemoteInfo } from '../plugins/snapshot/SnapshotHandler';\n\nexport interface LoadRemoteMatch {\n id: string;\n pkgNameOrAlias: string;\n expose: string;\n remote: Remote;\n options: Options;\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteSnapshot?: ModuleInfo;\n}\n\nexport class RemoteHandler {\n host: ModuleFederation;\n idToRemoteMap: Record<string, { name: string; expose: string }>;\n\n hooks = new PluginSystem({\n beforeRegisterRemote: new SyncWaterfallHook<{\n remote: Remote;\n origin: ModuleFederation;\n }>('beforeRegisterRemote'),\n registerRemote: new SyncWaterfallHook<{\n remote: Remote;\n origin: ModuleFederation;\n }>('registerRemote'),\n beforeRequest: new AsyncWaterfallHook<{\n id: string;\n options: Options;\n origin: ModuleFederation;\n }>('beforeRequest'),\n onLoad: new AsyncHook<\n [\n {\n id: string;\n expose: string;\n pkgNameOrAlias: string;\n remote: Remote;\n options: ModuleOptions;\n origin: ModuleFederation;\n exposeModule: any;\n exposeModuleFactory: any;\n moduleInstance: Module;\n },\n ],\n void\n >('onLoad'),\n handlePreloadModule: new SyncHook<\n [\n {\n id: string;\n name: string;\n remote: Remote;\n remoteSnapshot: ModuleInfo;\n preloadConfig: PreloadRemoteArgs;\n origin: ModuleFederation;\n },\n ],\n void\n >('handlePreloadModule'),\n errorLoadRemote: new AsyncHook<\n [\n {\n id: string;\n error: unknown;\n options?: any;\n from: CallFrom;\n lifecycle:\n | 'beforeRequest'\n | 'beforeLoadShare'\n | 'afterResolve'\n | 'onLoad';\n origin: ModuleFederation;\n },\n ],\n void | unknown\n >('errorLoadRemote'),\n beforePreloadRemote: new AsyncHook<\n [\n {\n preloadOps: Array<PreloadRemoteArgs>;\n options: Options;\n origin: ModuleFederation;\n },\n ]\n >('beforePreloadRemote'),\n generatePreloadAssets: new AsyncHook<\n [\n {\n origin: ModuleFederation;\n preloadOptions: PreloadOptions[number];\n remote: Remote;\n remoteInfo: RemoteInfo;\n remoteSnapshot: ModuleInfo;\n globalSnapshot: GlobalModuleInfo;\n },\n ],\n Promise<PreloadAssets>\n >('generatePreloadAssets'),\n // not used yet\n afterPreloadRemote: new AsyncHook<{\n preloadOps: Array<PreloadRemoteArgs>;\n options: Options;\n origin: ModuleFederation;\n }>(),\n // TODO: Move to loaderHook\n loadEntry: new AsyncHook<\n [\n {\n loaderHook: ModuleFederation['loaderHook'];\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports;\n },\n ],\n Promise<RemoteEntryExports>\n >(),\n });\n\n constructor(host: ModuleFederation) {\n this.host = host;\n this.idToRemoteMap = {};\n }\n\n formatAndRegisterRemote(globalOptions: Options, userOptions: UserOptions) {\n const userRemotes = userOptions.remotes || [];\n\n return userRemotes.reduce((res, remote) => {\n this.registerRemote(remote, res, { force: false });\n return res;\n }, globalOptions.remotes);\n }\n\n setIdToRemoteMap(id: string, remoteMatchInfo: LoadRemoteMatch) {\n const { remote, expose } = remoteMatchInfo;\n const { name, alias } = remote;\n this.idToRemoteMap[id] = { name: remote.name, expose };\n if (alias && id.startsWith(name)) {\n const idWithAlias = id.replace(name, alias);\n this.idToRemoteMap[idWithAlias] = { name: remote.name, expose };\n return;\n }\n\n if (alias && id.startsWith(alias)) {\n const idWithName = id.replace(alias, name);\n this.idToRemoteMap[idWithName] = { name: remote.name, expose };\n }\n }\n\n // eslint-disable-next-line max-lines-per-function\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async loadRemote<T>(\n id: string,\n options?: { loadFactory?: boolean; from: CallFrom },\n ): Promise<T | null> {\n const { host } = this;\n try {\n const { loadFactory = true } = options || {\n loadFactory: true,\n };\n // 1. Validate the parameters of the retrieved module. There are two module request methods: pkgName + expose and alias + expose.\n // 2. Request the snapshot information of the current host and globally store the obtained snapshot information. The retrieved module information is partially offline and partially online. The online module information will retrieve the modules used online.\n // 3. Retrieve the detailed information of the current module from global (remoteEntry address, expose resource address)\n // 4. After retrieving remoteEntry, call the init of the module, and then retrieve the exported content of the module through get\n // id: pkgName(@federation/app1) + expose(button) = @federation/app1/button\n // id: alias(app1) + expose(button) = app1/button\n // id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort\n const { module, moduleOptions, remoteMatchInfo } =\n await this.getRemoteModuleAndOptions({\n id,\n });\n const {\n pkgNameOrAlias,\n remote,\n expose,\n id: idRes,\n remoteSnapshot,\n } = remoteMatchInfo;\n\n const moduleOrFactory = (await module.get(\n idRes,\n expose,\n options,\n remoteSnapshot,\n )) as T;\n\n const moduleWrapper = await this.hooks.lifecycle.onLoad.emit({\n id: idRes,\n pkgNameOrAlias,\n expose,\n exposeModule: loadFactory ? moduleOrFactory : undefined,\n exposeModuleFactory: loadFactory ? undefined : moduleOrFactory,\n remote,\n options: moduleOptions,\n moduleInstance: module,\n origin: host,\n });\n\n this.setIdToRemoteMap(id, remoteMatchInfo);\n if (typeof moduleWrapper === 'function') {\n return moduleWrapper as T;\n }\n\n return moduleOrFactory;\n } catch (error) {\n const { from = 'runtime' } = options || { from: 'runtime' };\n\n const failOver = await this.hooks.lifecycle.errorLoadRemote.emit({\n id,\n error,\n from,\n lifecycle: 'onLoad',\n origin: host,\n });\n\n if (!failOver) {\n throw error;\n }\n\n return failOver as T;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void> {\n const { host } = this;\n\n await this.hooks.lifecycle.beforePreloadRemote.emit({\n preloadOps: preloadOptions,\n options: host.options,\n origin: host,\n });\n\n const preloadOps: PreloadOptions = formatPreloadArgs(\n host.options.remotes,\n preloadOptions,\n );\n\n await Promise.all(\n preloadOps.map(async (ops) => {\n const { remote } = ops;\n const remoteInfo = getRemoteInfo(remote);\n const { globalSnapshot, remoteSnapshot } =\n await host.snapshotHandler.loadRemoteSnapshotInfo({\n moduleInfo: remote,\n });\n\n const assets = await this.hooks.lifecycle.generatePreloadAssets.emit({\n origin: host,\n preloadOptions: ops,\n remote,\n remoteInfo,\n globalSnapshot,\n remoteSnapshot,\n });\n if (!assets) {\n return;\n }\n preloadAssets(remoteInfo, host, assets);\n }),\n );\n }\n\n registerRemotes(remotes: Remote[], options?: { force?: boolean }): void {\n const { host } = this;\n remotes.forEach((remote) => {\n this.registerRemote(remote, host.options.remotes, {\n force: options?.force,\n });\n });\n }\n\n async getRemoteModuleAndOptions(options: { id: string }): Promise<{\n module: Module;\n moduleOptions: ModuleOptions;\n remoteMatchInfo: LoadRemoteMatch;\n }> {\n const { host } = this;\n const { id } = options;\n let loadRemoteArgs;\n\n try {\n loadRemoteArgs = await this.hooks.lifecycle.beforeRequest.emit({\n id,\n options: host.options,\n origin: host,\n });\n } catch (error) {\n loadRemoteArgs = (await this.hooks.lifecycle.errorLoadRemote.emit({\n id,\n options: host.options,\n origin: host,\n from: 'runtime',\n error,\n lifecycle: 'beforeRequest',\n })) as {\n id: string;\n options: Options;\n origin: ModuleFederation;\n };\n\n if (!loadRemoteArgs) {\n throw error;\n }\n }\n\n const { id: idRes } = loadRemoteArgs;\n\n const remoteSplitInfo = matchRemoteWithNameAndExpose(\n host.options.remotes,\n idRes,\n );\n if (!remoteSplitInfo) {\n error(\n RUNTIME_004,\n runtimeDescMap,\n {\n hostName: host.options.name,\n requestId: idRes,\n },\n undefined,\n optionsToMFContext(host.options),\n );\n }\n\n const { remote: rawRemote } = remoteSplitInfo;\n const remoteInfo = getRemoteInfo(rawRemote);\n const matchInfo =\n await host.sharedHandler.hooks.lifecycle.afterResolve.emit({\n id: idRes,\n ...remoteSplitInfo,\n options: host.options,\n origin: host,\n remoteInfo,\n });\n\n const { remote, expose } = matchInfo;\n assert(\n remote && expose,\n `The 'beforeRequest' hook was executed, but it failed to return the correct 'remote' and 'expose' values while loading ${idRes}.`,\n );\n let module: Module | undefined = host.moduleCache.get(remote.name);\n\n const moduleOptions: ModuleOptions = {\n host: host,\n remoteInfo,\n };\n\n if (!module) {\n module = new Module(moduleOptions);\n host.moduleCache.set(remote.name, module);\n }\n return {\n module,\n moduleOptions,\n remoteMatchInfo: matchInfo,\n };\n }\n\n registerRemote(\n remote: Remote,\n targetRemotes: Remote[],\n options?: { force?: boolean },\n ): void {\n const { host } = this;\n const normalizeRemote = () => {\n if (remote.alias) {\n // Validate if alias equals the prefix of remote.name and remote.alias, if so, throw an error\n // As multi-level path references cannot guarantee unique names, alias being a prefix of remote.name is not supported\n const findEqual = targetRemotes.find(\n (item) =>\n remote.alias &&\n (item.name.startsWith(remote.alias) ||\n item.alias?.startsWith(remote.alias)),\n );\n assert(\n !findEqual,\n `The alias ${remote.alias} of remote ${\n remote.name\n } is not allowed to be the prefix of ${\n findEqual && findEqual.name\n } name or alias`,\n );\n }\n // Set the remote entry to a complete path\n if ('entry' in remote) {\n if (\n isBrowserEnvValue &&\n typeof window !== 'undefined' &&\n !remote.entry.startsWith('http')\n ) {\n remote.entry = new URL(remote.entry, window.location.origin).href;\n }\n }\n if (!remote.shareScope) {\n remote.shareScope = DEFAULT_SCOPE;\n }\n if (!remote.type) {\n remote.type = DEFAULT_REMOTE_TYPE;\n }\n };\n this.hooks.lifecycle.beforeRegisterRemote.emit({ remote, origin: host });\n const registeredRemote = targetRemotes.find(\n (item) => item.name === remote.name,\n );\n if (!registeredRemote) {\n normalizeRemote();\n targetRemotes.push(remote);\n this.hooks.lifecycle.registerRemote.emit({ remote, origin: host });\n } else {\n const messages = [\n `The remote \"${remote.name}\" is already registered.`,\n 'Please note that overriding it may cause unexpected errors.',\n ];\n if (options?.force) {\n // remove registered remote\n this.removeRemote(registeredRemote);\n normalizeRemote();\n targetRemotes.push(remote);\n this.hooks.lifecycle.registerRemote.emit({ remote, origin: host });\n warn(messages.join(' '));\n }\n }\n }\n\n private removeRemote(remote: Remote): void {\n try {\n const { host } = this;\n const { name } = remote;\n const remoteIndex = host.options.remotes.findIndex(\n (item) => item.name === name,\n );\n if (remoteIndex !== -1) {\n host.options.remotes.splice(remoteIndex, 1);\n }\n const loadedModule = host.moduleCache.get(remote.name);\n if (loadedModule) {\n const remoteInfo = loadedModule.remoteInfo;\n const key = remoteInfo.entryGlobalName as keyof typeof CurrentGlobal;\n\n if (CurrentGlobal[key]) {\n if (\n Object.getOwnPropertyDescriptor(CurrentGlobal, key)?.configurable\n ) {\n delete CurrentGlobal[key];\n } else {\n // @ts-ignore\n CurrentGlobal[key] = undefined;\n }\n }\n const remoteEntryUniqueKey = getRemoteEntryUniqueKey(\n loadedModule.remoteInfo,\n );\n\n if (globalLoading[remoteEntryUniqueKey]) {\n delete globalLoading[remoteEntryUniqueKey];\n }\n\n host.snapshotHandler.manifestCache.delete(remoteInfo.entry);\n\n // delete unloaded shared and instance\n let remoteInsId = remoteInfo.buildVersion\n ? composeKeyWithSeparator(remoteInfo.name, remoteInfo.buildVersion)\n : remoteInfo.name;\n const remoteInsIndex =\n CurrentGlobal.__FEDERATION__.__INSTANCES__.findIndex((ins) => {\n if (remoteInfo.buildVersion) {\n return ins.options.id === remoteInsId;\n } else {\n return ins.name === remoteInsId;\n }\n });\n if (remoteInsIndex !== -1) {\n const remoteIns =\n CurrentGlobal.__FEDERATION__.__INSTANCES__[remoteInsIndex];\n remoteInsId = remoteIns.options.id || remoteInsId;\n const globalShareScopeMap = getGlobalShareScope();\n\n let isAllSharedNotUsed = true;\n const needDeleteKeys: Array<[string, string, string, string]> = [];\n Object.keys(globalShareScopeMap).forEach((instId) => {\n const shareScopeMap = globalShareScopeMap[instId];\n shareScopeMap &&\n Object.keys(shareScopeMap).forEach((shareScope) => {\n const shareScopeVal = shareScopeMap[shareScope];\n shareScopeVal &&\n Object.keys(shareScopeVal).forEach((shareName) => {\n const sharedPkgs = shareScopeVal[shareName];\n sharedPkgs &&\n Object.keys(sharedPkgs).forEach((shareVersion) => {\n const shared = sharedPkgs[shareVersion];\n if (\n shared &&\n typeof shared === 'object' &&\n shared.from === remoteInfo.name\n ) {\n if (shared.loaded || shared.loading) {\n shared.useIn = shared.useIn.filter(\n (usedHostName) =>\n usedHostName !== remoteInfo.name,\n );\n if (shared.useIn.length) {\n isAllSharedNotUsed = false;\n } else {\n needDeleteKeys.push([\n instId,\n shareScope,\n shareName,\n shareVersion,\n ]);\n }\n } else {\n needDeleteKeys.push([\n instId,\n shareScope,\n shareName,\n shareVersion,\n ]);\n }\n }\n });\n });\n });\n });\n\n if (isAllSharedNotUsed) {\n remoteIns.shareScopeMap = {};\n delete globalShareScopeMap[remoteInsId];\n }\n needDeleteKeys.forEach(\n ([insId, shareScope, shareName, shareVersion]) => {\n delete globalShareScopeMap[insId]?.[shareScope]?.[shareName]?.[\n shareVersion\n ];\n },\n );\n CurrentGlobal.__FEDERATION__.__INSTANCES__.splice(remoteInsIndex, 1);\n }\n\n const { hostGlobalSnapshot } = getGlobalRemoteInfo(remote, host);\n if (hostGlobalSnapshot) {\n const remoteKey =\n hostGlobalSnapshot &&\n 'remotesInfo' in hostGlobalSnapshot &&\n hostGlobalSnapshot.remotesInfo &&\n getInfoWithoutType(hostGlobalSnapshot.remotesInfo, remote.name).key;\n if (remoteKey) {\n delete hostGlobalSnapshot.remotesInfo[remoteKey];\n if (\n //eslint-disable-next-line no-extra-boolean-cast\n Boolean(Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey])\n ) {\n delete Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey];\n }\n }\n }\n\n host.moduleCache.delete(remote.name);\n }\n } catch (err) {\n logger.error(\n `removeRemote failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"index.js","names":["Module"],"sources":["../../src/remote/index.ts"],"sourcesContent":["import {\n isBrowserEnvValue,\n warn,\n composeKeyWithSeparator,\n ModuleInfo,\n GlobalModuleInfo,\n} from '@module-federation/sdk';\nimport { RUNTIME_004, runtimeDescMap } from '@module-federation/error-codes';\nimport {\n Global,\n getInfoWithoutType,\n globalLoading,\n CurrentGlobal,\n} from '../global';\nimport {\n Options,\n UserOptions,\n PreloadAssets,\n PreloadOptions,\n PreloadRemoteArgs,\n PreloadRemoteResult,\n Remote,\n RemoteInfo,\n RemoteEntryExports,\n CallFrom,\n} from '../type';\nimport { ModuleFederation } from '../core';\nimport {\n PluginSystem,\n AsyncHook,\n AsyncWaterfallHook,\n SyncHook,\n SyncWaterfallHook,\n} from '../utils/hooks';\nimport {\n assert,\n error,\n getRemoteInfo,\n getRemoteEntryUniqueKey,\n composeRemoteRequestId,\n matchRemoteWithNameAndExpose,\n optionsToMFContext,\n logger,\n} from '../utils';\nimport { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from '../constant';\nimport { Module, ModuleOptions } from '../module';\nimport { formatPreloadArgs, preloadAssets } from '../utils/preload';\nimport { getGlobalShareScope } from '../utils/share';\nimport { getGlobalRemoteInfo } from '../plugins/snapshot/SnapshotHandler';\n\nexport interface LoadRemoteMatch {\n id: string;\n pkgNameOrAlias: string;\n expose: string;\n remote: Remote;\n options: Options;\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteSnapshot?: ModuleInfo;\n}\n\nexport class RemoteHandler {\n host: ModuleFederation;\n idToRemoteMap: Record<string, { name: string; expose: string }>;\n\n hooks = new PluginSystem({\n beforeRegisterRemote: new SyncWaterfallHook<{\n remote: Remote;\n origin: ModuleFederation;\n }>('beforeRegisterRemote'),\n registerRemote: new SyncWaterfallHook<{\n remote: Remote;\n origin: ModuleFederation;\n }>('registerRemote'),\n beforeRequest: new AsyncWaterfallHook<{\n id: string;\n options: Options;\n origin: ModuleFederation;\n }>('beforeRequest'),\n afterMatchRemote: new AsyncHook<\n [\n {\n id: string;\n options: Options;\n remote?: Remote;\n expose?: string;\n remoteInfo?: RemoteInfo;\n error?: unknown;\n origin: ModuleFederation;\n },\n ],\n void\n >('afterMatchRemote'),\n onLoad: new AsyncHook<\n [\n {\n id: string;\n expose: string;\n pkgNameOrAlias: string;\n remote: Remote;\n options: ModuleOptions;\n origin: ModuleFederation;\n exposeModule: any;\n exposeModuleFactory: any;\n moduleInstance: Module;\n },\n ],\n unknown\n >('onLoad'),\n afterLoadRemote: new AsyncHook<\n [\n {\n id: string;\n expose?: string;\n remote?: RemoteInfo;\n options?: {\n loadFactory?: boolean;\n from?: CallFrom;\n };\n error?: unknown;\n recovered?: boolean;\n origin: ModuleFederation;\n },\n ],\n void\n >('afterLoadRemote'),\n handlePreloadModule: new SyncHook<\n [\n {\n id: string;\n name: string;\n remote: Remote;\n remoteSnapshot: ModuleInfo;\n preloadConfig: PreloadRemoteArgs;\n origin: ModuleFederation;\n },\n ],\n void\n >('handlePreloadModule'),\n errorLoadRemote: new AsyncHook<\n [\n {\n id: string;\n error: unknown;\n options?: any;\n from: CallFrom;\n lifecycle:\n | 'beforeRequest'\n | 'beforeLoadShare'\n | 'afterResolve'\n | 'onLoad';\n remote?: RemoteInfo;\n expose?: string;\n origin: ModuleFederation;\n },\n ],\n void | unknown\n >('errorLoadRemote'),\n beforePreloadRemote: new AsyncHook<\n [\n {\n preloadOps: Array<PreloadRemoteArgs>;\n options: Options;\n origin: ModuleFederation;\n },\n ]\n >('beforePreloadRemote'),\n generatePreloadAssets: new AsyncHook<\n [\n {\n origin: ModuleFederation;\n preloadOptions: PreloadOptions[number];\n remote: Remote;\n remoteInfo: RemoteInfo;\n remoteSnapshot: ModuleInfo;\n globalSnapshot: GlobalModuleInfo;\n },\n ],\n Promise<PreloadAssets>\n >('generatePreloadAssets'),\n afterPreloadRemote: new AsyncHook<\n [\n {\n preloadOps: Array<PreloadRemoteArgs>;\n options: Options;\n origin: ModuleFederation;\n results: PreloadRemoteResult[];\n error?: unknown;\n },\n ]\n >('afterPreloadRemote'),\n // TODO: Move to loaderHook\n loadEntry: new AsyncHook<\n [\n {\n origin: ModuleFederation;\n loaderHook: ModuleFederation['loaderHook'];\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports;\n },\n ],\n Promise<RemoteEntryExports | void> | RemoteEntryExports | void\n >(),\n });\n\n constructor(host: ModuleFederation) {\n this.host = host;\n this.idToRemoteMap = {};\n }\n\n formatAndRegisterRemote(globalOptions: Options, userOptions: UserOptions) {\n const userRemotes = userOptions.remotes || [];\n\n return userRemotes.reduce((res, remote) => {\n this.registerRemote(remote, res, { force: false });\n return res;\n }, globalOptions.remotes);\n }\n\n setIdToRemoteMap(id: string, remoteMatchInfo: LoadRemoteMatch) {\n const { remote, expose } = remoteMatchInfo;\n const { name, alias } = remote;\n this.idToRemoteMap[id] = { name: remote.name, expose };\n if (alias && id.startsWith(name)) {\n const idWithAlias = id.replace(name, alias);\n this.idToRemoteMap[idWithAlias] = { name: remote.name, expose };\n return;\n }\n\n if (alias && id.startsWith(alias)) {\n const idWithName = id.replace(alias, name);\n this.idToRemoteMap[idWithName] = { name: remote.name, expose };\n }\n }\n\n // eslint-disable-next-line max-lines-per-function\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async loadRemote<T>(\n id: string,\n options?: { loadFactory?: boolean; from: CallFrom },\n ): Promise<T | null> {\n const { host } = this;\n const startMatchInfo = matchRemoteWithNameAndExpose(\n host.options.remotes,\n id,\n );\n let completeRequestId = id;\n let completeExpose = startMatchInfo?.expose;\n let completeRemote = startMatchInfo\n ? getRemoteInfo(startMatchInfo.remote)\n : undefined;\n let afterLoadRemoteArgs:\n | Parameters<\n RemoteHandler['hooks']['lifecycle']['afterLoadRemote']['emit']\n >[0]\n | undefined;\n\n try {\n const { loadFactory = true } = options || {\n loadFactory: true,\n };\n // 1. Validate the parameters of the retrieved module. There are two module request methods: pkgName + expose and alias + expose.\n // 2. Request the snapshot information of the current host and globally store the obtained snapshot information. The retrieved module information is partially offline and partially online. The online module information will retrieve the modules used online.\n // 3. Retrieve the detailed information of the current module from global (remoteEntry address, expose resource address)\n // 4. After retrieving remoteEntry, call the init of the module, and then retrieve the exported content of the module through get\n // id: pkgName(@federation/app1) + expose(button) = @federation/app1/button\n // id: alias(app1) + expose(button) = app1/button\n // id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort\n const { module, moduleOptions, remoteMatchInfo } =\n await this.getRemoteModuleAndOptions({\n id,\n });\n const {\n pkgNameOrAlias,\n remote,\n expose,\n id: idRes,\n remoteSnapshot,\n } = remoteMatchInfo;\n completeRequestId = idRes;\n completeExpose = expose;\n completeRemote = getRemoteInfo(remote);\n\n const moduleOrFactory = (await module.get(\n idRes,\n expose,\n options,\n remoteSnapshot,\n )) as T;\n\n const moduleWrapper = await this.hooks.lifecycle.onLoad.emit({\n id: idRes,\n pkgNameOrAlias,\n expose,\n exposeModule: loadFactory ? moduleOrFactory : undefined,\n exposeModuleFactory: loadFactory ? undefined : moduleOrFactory,\n remote,\n options: moduleOptions,\n moduleInstance: module,\n origin: host,\n });\n\n this.setIdToRemoteMap(id, remoteMatchInfo);\n afterLoadRemoteArgs = {\n id: completeRequestId,\n expose: completeExpose,\n remote: completeRemote,\n options,\n origin: host,\n };\n\n if (typeof moduleWrapper === 'function') {\n return moduleWrapper as T;\n }\n\n return moduleOrFactory;\n } catch (error) {\n const { from = 'runtime' } = options || { from: 'runtime' };\n\n let failOver;\n try {\n failOver = await this.hooks.lifecycle.errorLoadRemote.emit({\n id,\n error,\n from,\n lifecycle: 'onLoad',\n expose: completeExpose,\n remote: completeRemote,\n origin: host,\n });\n } catch (hookError) {\n afterLoadRemoteArgs = {\n id: completeRequestId,\n expose: completeExpose,\n remote: completeRemote,\n options,\n error: hookError,\n origin: host,\n };\n throw hookError;\n }\n\n if (!failOver) {\n afterLoadRemoteArgs = {\n id: completeRequestId,\n expose: completeExpose,\n remote: completeRemote,\n options,\n error,\n origin: host,\n };\n throw error;\n }\n\n afterLoadRemoteArgs = {\n id: completeRequestId,\n expose: completeExpose,\n remote: completeRemote,\n options,\n error,\n origin: host,\n recovered: true,\n };\n\n return failOver as T;\n } finally {\n if (afterLoadRemoteArgs) {\n await this.hooks.lifecycle.afterLoadRemote.emit(afterLoadRemoteArgs);\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n async preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void> {\n const { host } = this;\n const preloadResults: PreloadRemoteResult[] = [];\n\n await this.hooks.lifecycle.beforePreloadRemote.emit({\n preloadOps: preloadOptions,\n options: host.options,\n origin: host,\n });\n\n const preloadOps: PreloadOptions = formatPreloadArgs(\n host.options.remotes,\n preloadOptions,\n );\n\n const createPreloadAssetOps = (ops: PreloadOptions[number]) => {\n const { preloadConfig, remote } = ops;\n const exposes = preloadConfig.exposes || [];\n\n if (!exposes.length) {\n return [\n {\n ops,\n id: `${remote.name}/*`,\n },\n ];\n }\n\n return exposes.map((expose) => ({\n ops: {\n ...ops,\n preloadConfig: {\n ...preloadConfig,\n exposes: [expose],\n },\n },\n id: composeRemoteRequestId(remote.name, expose),\n }));\n };\n\n let preloadError: Error | undefined;\n\n await Promise.all(\n preloadOps.flatMap(createPreloadAssetOps).map(async (assetOps) => {\n const { ops, id: preloadId } = assetOps;\n const { remote, preloadConfig } = ops;\n const remoteInfo = getRemoteInfo(remote);\n try {\n const { globalSnapshot, remoteSnapshot } =\n await host.snapshotHandler.loadRemoteSnapshotInfo({\n moduleInfo: remote,\n id: preloadId,\n initiator: 'preloadRemote',\n });\n\n const assets = await this.hooks.lifecycle.generatePreloadAssets.emit({\n origin: host,\n preloadOptions: ops,\n remote,\n remoteInfo,\n globalSnapshot,\n remoteSnapshot,\n });\n if (!assets) {\n return;\n }\n const results = await preloadAssets(remoteInfo, host, assets, true, {\n initiator: 'preloadRemote',\n id: preloadId,\n });\n preloadResults.push({\n remote,\n remoteInfo,\n preloadConfig,\n id: preloadId,\n results,\n });\n } catch (error) {\n preloadResults.push({\n remote,\n remoteInfo,\n preloadConfig,\n id: preloadId,\n results: [\n {\n url: remoteInfo.entry,\n status: 'error',\n resourceType: /\\.json(?:$|[?#])/i.test(remoteInfo.entry)\n ? 'manifest'\n : 'remoteEntry',\n initiator: 'preloadRemote',\n id: preloadId,\n error,\n },\n ],\n });\n }\n }),\n );\n\n const failedResults = preloadResults.flatMap((preloadResult) =>\n preloadResult.results.filter(\n (result) => result.status === 'error' || result.status === 'timeout',\n ),\n );\n if (failedResults.length > 0) {\n preloadError = new Error(\n `preloadRemote failed to load ${failedResults.length} resource(s).`,\n );\n Object.assign(preloadError, {\n results: preloadResults,\n failedResults,\n });\n }\n\n await this.hooks.lifecycle.afterPreloadRemote.emit({\n preloadOps: preloadOptions,\n options: host.options,\n origin: host,\n results: preloadResults,\n error: preloadError,\n });\n\n if (preloadError) {\n throw preloadError;\n }\n }\n\n registerRemotes(remotes: Remote[], options?: { force?: boolean }): void {\n const { host } = this;\n remotes.forEach((remote) => {\n this.registerRemote(remote, host.options.remotes, {\n force: options?.force,\n });\n });\n }\n\n async getRemoteModuleAndOptions(options: { id: string }): Promise<{\n module: Module;\n moduleOptions: ModuleOptions;\n remoteMatchInfo: LoadRemoteMatch;\n }> {\n const { host } = this;\n const { id } = options;\n let loadRemoteArgs;\n\n try {\n loadRemoteArgs = await this.hooks.lifecycle.beforeRequest.emit({\n id,\n options: host.options,\n origin: host,\n });\n } catch (error) {\n loadRemoteArgs = (await this.hooks.lifecycle.errorLoadRemote.emit({\n id,\n options: host.options,\n origin: host,\n from: 'runtime',\n error,\n lifecycle: 'beforeRequest',\n })) as {\n id: string;\n options: Options;\n origin: ModuleFederation;\n };\n\n if (!loadRemoteArgs) {\n throw error;\n }\n }\n\n const { id: idRes } = loadRemoteArgs;\n\n const remoteSplitInfo = matchRemoteWithNameAndExpose(\n host.options.remotes,\n idRes,\n );\n if (!remoteSplitInfo) {\n try {\n error(\n RUNTIME_004,\n runtimeDescMap,\n {\n hostName: host.options.name,\n requestId: idRes,\n },\n undefined,\n optionsToMFContext(host.options),\n );\n } catch (matchError) {\n await this.hooks.lifecycle.afterMatchRemote.emit({\n id: idRes,\n options: host.options,\n error: matchError,\n origin: host,\n });\n throw matchError;\n }\n }\n\n const { remote: rawRemote } = remoteSplitInfo;\n const remoteInfo = getRemoteInfo(rawRemote);\n await this.hooks.lifecycle.afterMatchRemote.emit({\n id: idRes,\n ...remoteSplitInfo,\n options: host.options,\n remoteInfo,\n origin: host,\n });\n const matchInfo =\n await host.sharedHandler.hooks.lifecycle.afterResolve.emit({\n id: idRes,\n ...remoteSplitInfo,\n options: host.options,\n origin: host,\n remoteInfo,\n });\n\n const { remote, expose } = matchInfo;\n assert(\n remote && expose,\n `The 'beforeRequest' hook was executed, but it failed to return the correct 'remote' and 'expose' values while loading ${idRes}.`,\n );\n let module: Module | undefined = host.moduleCache.get(remote.name);\n\n const moduleOptions: ModuleOptions = {\n host: host,\n remoteInfo,\n };\n\n if (!module) {\n module = new Module(moduleOptions);\n host.moduleCache.set(remote.name, module);\n }\n return {\n module,\n moduleOptions,\n remoteMatchInfo: matchInfo,\n };\n }\n\n registerRemote(\n remote: Remote,\n targetRemotes: Remote[],\n options?: { force?: boolean },\n ): void {\n const { host } = this;\n const normalizeRemote = () => {\n if (remote.alias) {\n // Validate if alias equals the prefix of remote.name and remote.alias, if so, throw an error\n // As multi-level path references cannot guarantee unique names, alias being a prefix of remote.name is not supported\n const findEqual = targetRemotes.find(\n (item) =>\n remote.alias &&\n (item.name.startsWith(remote.alias) ||\n item.alias?.startsWith(remote.alias)),\n );\n assert(\n !findEqual,\n `The alias ${remote.alias} of remote ${\n remote.name\n } is not allowed to be the prefix of ${\n findEqual && findEqual.name\n } name or alias`,\n );\n }\n // Set the remote entry to a complete path\n if ('entry' in remote) {\n if (\n isBrowserEnvValue &&\n typeof window !== 'undefined' &&\n !remote.entry.startsWith('http')\n ) {\n remote.entry = new URL(remote.entry, window.location.origin).href;\n }\n }\n if (!remote.shareScope) {\n remote.shareScope = DEFAULT_SCOPE;\n }\n if (!remote.type) {\n remote.type = DEFAULT_REMOTE_TYPE;\n }\n };\n this.hooks.lifecycle.beforeRegisterRemote.emit({ remote, origin: host });\n const registeredRemote = targetRemotes.find(\n (item) => item.name === remote.name,\n );\n if (!registeredRemote) {\n normalizeRemote();\n targetRemotes.push(remote);\n this.hooks.lifecycle.registerRemote.emit({ remote, origin: host });\n } else {\n const messages = [\n `The remote \"${remote.name}\" is already registered.`,\n 'Please note that overriding it may cause unexpected errors.',\n ];\n if (options?.force) {\n // remove registered remote\n this.removeRemote(registeredRemote);\n normalizeRemote();\n targetRemotes.push(remote);\n this.hooks.lifecycle.registerRemote.emit({ remote, origin: host });\n warn(messages.join(' '));\n }\n }\n }\n\n private removeRemote(remote: Remote): void {\n try {\n const { host } = this;\n const { name } = remote;\n const remoteIndex = host.options.remotes.findIndex(\n (item) => item.name === name,\n );\n if (remoteIndex !== -1) {\n host.options.remotes.splice(remoteIndex, 1);\n }\n const loadedModule = host.moduleCache.get(remote.name);\n if (loadedModule) {\n const remoteInfo = loadedModule.remoteInfo;\n const key = remoteInfo.entryGlobalName as keyof typeof CurrentGlobal;\n\n if (CurrentGlobal[key]) {\n if (\n Object.getOwnPropertyDescriptor(CurrentGlobal, key)?.configurable\n ) {\n delete CurrentGlobal[key];\n } else {\n // @ts-ignore\n CurrentGlobal[key] = undefined;\n }\n }\n const remoteEntryUniqueKey = getRemoteEntryUniqueKey(\n loadedModule.remoteInfo,\n );\n\n if (globalLoading[remoteEntryUniqueKey]) {\n delete globalLoading[remoteEntryUniqueKey];\n }\n\n host.snapshotHandler.manifestCache.delete(remoteInfo.entry);\n\n // delete unloaded shared and instance\n let remoteInsId = remoteInfo.buildVersion\n ? composeKeyWithSeparator(remoteInfo.name, remoteInfo.buildVersion)\n : remoteInfo.name;\n const remoteInsIndex =\n CurrentGlobal.__FEDERATION__.__INSTANCES__.findIndex((ins) => {\n if (remoteInfo.buildVersion) {\n return ins.options.id === remoteInsId;\n } else {\n return ins.name === remoteInsId;\n }\n });\n if (remoteInsIndex !== -1) {\n const remoteIns =\n CurrentGlobal.__FEDERATION__.__INSTANCES__[remoteInsIndex];\n remoteInsId = remoteIns.options.id || remoteInsId;\n const globalShareScopeMap = getGlobalShareScope();\n\n let isAllSharedNotUsed = true;\n const needDeleteKeys: Array<[string, string, string, string]> = [];\n Object.keys(globalShareScopeMap).forEach((instId) => {\n const shareScopeMap = globalShareScopeMap[instId];\n shareScopeMap &&\n Object.keys(shareScopeMap).forEach((shareScope) => {\n const shareScopeVal = shareScopeMap[shareScope];\n shareScopeVal &&\n Object.keys(shareScopeVal).forEach((shareName) => {\n const sharedPkgs = shareScopeVal[shareName];\n sharedPkgs &&\n Object.keys(sharedPkgs).forEach((shareVersion) => {\n const shared = sharedPkgs[shareVersion];\n if (\n shared &&\n typeof shared === 'object' &&\n shared.from === remoteInfo.name\n ) {\n if (shared.loaded || shared.loading) {\n shared.useIn = shared.useIn.filter(\n (usedHostName) =>\n usedHostName !== remoteInfo.name,\n );\n if (shared.useIn.length) {\n isAllSharedNotUsed = false;\n } else {\n needDeleteKeys.push([\n instId,\n shareScope,\n shareName,\n shareVersion,\n ]);\n }\n } else {\n needDeleteKeys.push([\n instId,\n shareScope,\n shareName,\n shareVersion,\n ]);\n }\n }\n });\n });\n });\n });\n\n if (isAllSharedNotUsed) {\n remoteIns.shareScopeMap = {};\n delete globalShareScopeMap[remoteInsId];\n }\n needDeleteKeys.forEach(\n ([insId, shareScope, shareName, shareVersion]) => {\n delete globalShareScopeMap[insId]?.[shareScope]?.[shareName]?.[\n shareVersion\n ];\n },\n );\n CurrentGlobal.__FEDERATION__.__INSTANCES__.splice(remoteInsIndex, 1);\n }\n\n const { hostGlobalSnapshot } = getGlobalRemoteInfo(remote, host);\n if (hostGlobalSnapshot) {\n const remoteKey =\n hostGlobalSnapshot &&\n 'remotesInfo' in hostGlobalSnapshot &&\n hostGlobalSnapshot.remotesInfo &&\n getInfoWithoutType(hostGlobalSnapshot.remotesInfo, remote.name).key;\n if (remoteKey) {\n delete hostGlobalSnapshot.remotesInfo[remoteKey];\n if (\n //eslint-disable-next-line no-extra-boolean-cast\n Boolean(Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey])\n ) {\n delete Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey];\n }\n }\n }\n\n host.moduleCache.delete(remote.name);\n }\n } catch (err) {\n logger.error(\n `removeRemote failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n}\n"],"mappings":"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"} |
+210
-95
@@ -6,2 +6,3 @@ const require_logger = require('../utils/logger.cjs'); | ||
| require('../utils/index.cjs'); | ||
| const require_syncHook = require('../utils/hooks/syncHook.cjs'); | ||
| const require_asyncHook = require('../utils/hooks/asyncHook.cjs'); | ||
@@ -22,2 +23,4 @@ const require_syncWaterfallHook = require('../utils/hooks/syncWaterfallHook.cjs'); | ||
| loadShare: new require_asyncHook.AsyncHook(), | ||
| afterLoadShare: new require_syncHook.SyncHook("afterLoadShare"), | ||
| errorLoadShare: new require_syncHook.SyncHook("errorLoadShare"), | ||
| resolveShare: new require_syncWaterfallHook.SyncWaterfallHook("resolveShare"), | ||
@@ -31,2 +34,33 @@ initContainerShareScopeMap: new require_syncWaterfallHook.SyncWaterfallHook("initContainerShareScopeMap") | ||
| } | ||
| emitAfterLoadShare({ lifecycle, pkgName, shareInfo, selectedShared }) { | ||
| try { | ||
| this.hooks.lifecycle.afterLoadShare.emit({ | ||
| pkgName, | ||
| shareInfo, | ||
| selectedShared, | ||
| shared: this.host.options.shared, | ||
| shareScopeMap: this.shareScopeMap, | ||
| lifecycle, | ||
| origin: this.host | ||
| }); | ||
| } catch (error) { | ||
| require_logger.warn(error); | ||
| } | ||
| } | ||
| emitErrorLoadShare({ lifecycle, pkgName, shareInfo, error, recovered }) { | ||
| try { | ||
| this.hooks.lifecycle.errorLoadShare.emit({ | ||
| pkgName, | ||
| shareInfo, | ||
| shared: this.host.options.shared, | ||
| shareScopeMap: this.shareScopeMap, | ||
| lifecycle, | ||
| origin: this.host, | ||
| error, | ||
| recovered | ||
| }); | ||
| } catch (hookError) { | ||
| require_logger.warn(hookError); | ||
| } | ||
| } | ||
| registerShared(globalOptions, userOptions) { | ||
@@ -65,30 +99,90 @@ const { newShareInfos, allShareInfos } = require_share.formatShareConfigs(globalOptions, userOptions); | ||
| }); | ||
| if (shareOptions?.scope) await Promise.all(shareOptions.scope.map(async (shareScope) => { | ||
| await Promise.all(this.initializeSharing(shareScope, { strategy: shareOptions.strategy })); | ||
| })); | ||
| const { shareInfo: shareOptionsRes } = await this.hooks.lifecycle.beforeLoadShare.emit({ | ||
| pkgName, | ||
| shareInfo: shareOptions, | ||
| shared: host.options.shared, | ||
| origin: host | ||
| }); | ||
| require_logger.assert(shareOptionsRes, `Cannot find shared "${pkgName}" in host "${host.options.name}". Ensure the shared config for "${pkgName}" is declared in the federation plugin options and the host has been initialized before loading shares.`); | ||
| const { shared: registeredShared, useTreesShaking } = require_share.getRegisteredShare(this.shareScopeMap, pkgName, shareOptionsRes, this.hooks.lifecycle.resolveShare) || {}; | ||
| if (registeredShared) { | ||
| const targetShared = require_share.directShare(registeredShared, useTreesShaking); | ||
| if (targetShared.lib) { | ||
| require_share.addUseIn(targetShared, host.options.name); | ||
| return targetShared.lib; | ||
| } else if (targetShared.loading && !targetShared.loaded) { | ||
| const factory = await targetShared.loading; | ||
| targetShared.loaded = true; | ||
| if (!targetShared.lib) targetShared.lib = factory; | ||
| require_share.addUseIn(targetShared, host.options.name); | ||
| return factory; | ||
| let shareOptionsRes = shareOptions; | ||
| try { | ||
| if (shareOptions?.scope) await Promise.all(shareOptions.scope.map(async (shareScope) => { | ||
| await Promise.all(this.initializeSharing(shareScope, { strategy: shareOptions.strategy })); | ||
| })); | ||
| shareOptionsRes = (await this.hooks.lifecycle.beforeLoadShare.emit({ | ||
| pkgName, | ||
| shareInfo: shareOptions, | ||
| shared: host.options.shared, | ||
| origin: host | ||
| })).shareInfo; | ||
| require_logger.assert(shareOptionsRes, `Cannot find shared "${pkgName}" in host "${host.options.name}". Ensure the shared config for "${pkgName}" is declared in the federation plugin options and the host has been initialized before loading shares.`); | ||
| const resolvedShareOptions = shareOptionsRes; | ||
| const { shared: registeredShared, useTreesShaking } = require_share.getRegisteredShare(this.shareScopeMap, pkgName, shareOptionsRes, this.hooks.lifecycle.resolveShare) || {}; | ||
| if (registeredShared) { | ||
| const targetShared = require_share.directShare(registeredShared, useTreesShaking); | ||
| if (targetShared.lib) { | ||
| require_share.addUseIn(targetShared, host.options.name); | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShare", | ||
| pkgName, | ||
| shareInfo: resolvedShareOptions, | ||
| selectedShared: registeredShared | ||
| }); | ||
| return targetShared.lib; | ||
| } else if (targetShared.loading && !targetShared.loaded) { | ||
| const factory = await targetShared.loading; | ||
| targetShared.loaded = true; | ||
| if (!targetShared.lib) targetShared.lib = factory; | ||
| require_share.addUseIn(targetShared, host.options.name); | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShare", | ||
| pkgName, | ||
| shareInfo: resolvedShareOptions, | ||
| selectedShared: registeredShared | ||
| }); | ||
| return factory; | ||
| } else { | ||
| const asyncLoadProcess = async () => { | ||
| const factory = await targetShared.get(); | ||
| require_share.addUseIn(targetShared, host.options.name); | ||
| targetShared.loaded = true; | ||
| targetShared.lib = factory; | ||
| return factory; | ||
| }; | ||
| const loading = asyncLoadProcess(); | ||
| this.setShared({ | ||
| pkgName, | ||
| loaded: false, | ||
| shared: registeredShared, | ||
| from: host.options.name, | ||
| lib: null, | ||
| loading, | ||
| treeShaking: useTreesShaking ? targetShared : void 0 | ||
| }); | ||
| const factory = await loading; | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShare", | ||
| pkgName, | ||
| shareInfo: resolvedShareOptions, | ||
| selectedShared: registeredShared | ||
| }); | ||
| return factory; | ||
| } | ||
| } else { | ||
| if (extraOptions?.customShareInfo) { | ||
| this.emitErrorLoadShare({ | ||
| lifecycle: "loadShare", | ||
| pkgName, | ||
| shareInfo: resolvedShareOptions, | ||
| recovered: true | ||
| }); | ||
| return false; | ||
| } | ||
| const _useTreeShaking = require_share.shouldUseTreeShaking(resolvedShareOptions.treeShaking); | ||
| const targetShared = require_share.directShare(resolvedShareOptions, _useTreeShaking); | ||
| const asyncLoadProcess = async () => { | ||
| const factory = await targetShared.get(); | ||
| targetShared.lib = factory; | ||
| targetShared.loaded = true; | ||
| require_share.addUseIn(targetShared, host.options.name); | ||
| targetShared.loaded = true; | ||
| targetShared.lib = factory; | ||
| const { shared: gShared, useTreesShaking: gUseTreeShaking } = require_share.getRegisteredShare(this.shareScopeMap, pkgName, resolvedShareOptions, this.hooks.lifecycle.resolveShare) || {}; | ||
| if (gShared) { | ||
| const targetGShared = require_share.directShare(gShared, gUseTreeShaking); | ||
| targetGShared.lib = factory; | ||
| targetGShared.loaded = true; | ||
| gShared.from = resolvedShareOptions.from; | ||
| } | ||
| return factory; | ||
@@ -100,39 +194,25 @@ }; | ||
| loaded: false, | ||
| shared: registeredShared, | ||
| shared: resolvedShareOptions, | ||
| from: host.options.name, | ||
| lib: null, | ||
| loading, | ||
| treeShaking: useTreesShaking ? targetShared : void 0 | ||
| treeShaking: _useTreeShaking ? targetShared : void 0 | ||
| }); | ||
| return loading; | ||
| const factory = await loading; | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShare", | ||
| pkgName, | ||
| shareInfo: resolvedShareOptions, | ||
| selectedShared: resolvedShareOptions | ||
| }); | ||
| return factory; | ||
| } | ||
| } else { | ||
| if (extraOptions?.customShareInfo) return false; | ||
| const _useTreeShaking = require_share.shouldUseTreeShaking(shareOptionsRes.treeShaking); | ||
| const targetShared = require_share.directShare(shareOptionsRes, _useTreeShaking); | ||
| const asyncLoadProcess = async () => { | ||
| const factory = await targetShared.get(); | ||
| targetShared.lib = factory; | ||
| targetShared.loaded = true; | ||
| require_share.addUseIn(targetShared, host.options.name); | ||
| const { shared: gShared, useTreesShaking: gUseTreeShaking } = require_share.getRegisteredShare(this.shareScopeMap, pkgName, shareOptionsRes, this.hooks.lifecycle.resolveShare) || {}; | ||
| if (gShared) { | ||
| const targetGShared = require_share.directShare(gShared, gUseTreeShaking); | ||
| targetGShared.lib = factory; | ||
| targetGShared.loaded = true; | ||
| gShared.from = shareOptionsRes.from; | ||
| } | ||
| return factory; | ||
| }; | ||
| const loading = asyncLoadProcess(); | ||
| this.setShared({ | ||
| } catch (shareError) { | ||
| this.emitErrorLoadShare({ | ||
| lifecycle: "loadShare", | ||
| pkgName, | ||
| loaded: false, | ||
| shared: shareOptionsRes, | ||
| from: host.options.name, | ||
| lib: null, | ||
| loading, | ||
| treeShaking: _useTreeShaking ? targetShared : void 0 | ||
| shareInfo: shareOptionsRes, | ||
| error: shareError | ||
| }); | ||
| return loading; | ||
| throw shareError; | ||
| } | ||
@@ -182,2 +262,3 @@ } | ||
| lifecycle: "beforeLoadShare", | ||
| remote: module.remoteInfo, | ||
| origin: host | ||
@@ -210,54 +291,88 @@ }); | ||
| }); | ||
| if (shareOptions?.scope) shareOptions.scope.forEach((shareScope) => { | ||
| this.initializeSharing(shareScope, { strategy: shareOptions.strategy }); | ||
| }); | ||
| const { shared: registeredShared, useTreesShaking } = require_share.getRegisteredShare(this.shareScopeMap, pkgName, shareOptions, this.hooks.lifecycle.resolveShare) || {}; | ||
| if (registeredShared) { | ||
| if (typeof registeredShared.lib === "function") { | ||
| require_share.addUseIn(registeredShared, host.options.name); | ||
| if (!registeredShared.loaded) { | ||
| registeredShared.loaded = true; | ||
| if (registeredShared.from === host.options.name) shareOptions.loaded = true; | ||
| } | ||
| return registeredShared.lib; | ||
| } | ||
| if (typeof registeredShared.get === "function") { | ||
| const module = registeredShared.get(); | ||
| if (!(module instanceof Promise)) { | ||
| try { | ||
| if (shareOptions?.scope) shareOptions.scope.forEach((shareScope) => { | ||
| this.initializeSharing(shareScope, { strategy: shareOptions.strategy }); | ||
| }); | ||
| const { shared: registeredShared } = require_share.getRegisteredShare(this.shareScopeMap, pkgName, shareOptions, this.hooks.lifecycle.resolveShare) || {}; | ||
| if (registeredShared) { | ||
| if (typeof registeredShared.lib === "function") { | ||
| require_share.addUseIn(registeredShared, host.options.name); | ||
| this.setShared({ | ||
| if (!registeredShared.loaded) { | ||
| registeredShared.loaded = true; | ||
| if (registeredShared.from === host.options.name) shareOptions.loaded = true; | ||
| } | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShareSync", | ||
| pkgName, | ||
| loaded: true, | ||
| from: host.options.name, | ||
| lib: module, | ||
| shared: registeredShared | ||
| shareInfo: shareOptions, | ||
| selectedShared: registeredShared | ||
| }); | ||
| return module; | ||
| return registeredShared.lib; | ||
| } | ||
| if (typeof registeredShared.get === "function") { | ||
| const module = registeredShared.get(); | ||
| if (!(module instanceof Promise)) { | ||
| require_share.addUseIn(registeredShared, host.options.name); | ||
| this.setShared({ | ||
| pkgName, | ||
| loaded: true, | ||
| from: host.options.name, | ||
| lib: module, | ||
| shared: registeredShared | ||
| }); | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShareSync", | ||
| pkgName, | ||
| shareInfo: shareOptions, | ||
| selectedShared: registeredShared | ||
| }); | ||
| return module; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| if (shareOptions.lib) { | ||
| if (!shareOptions.loaded) shareOptions.loaded = true; | ||
| return shareOptions.lib; | ||
| } | ||
| if (shareOptions.get) { | ||
| const module = shareOptions.get(); | ||
| if (module instanceof Promise) require_logger.error(extraOptions?.from === "build" ? _module_federation_error_codes.RUNTIME_005 : _module_federation_error_codes.RUNTIME_006, _module_federation_error_codes.runtimeDescMap, { | ||
| if (shareOptions.lib) { | ||
| if (!shareOptions.loaded) shareOptions.loaded = true; | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShareSync", | ||
| pkgName, | ||
| shareInfo: shareOptions, | ||
| selectedShared: shareOptions | ||
| }); | ||
| return shareOptions.lib; | ||
| } | ||
| if (shareOptions.get) { | ||
| const module = shareOptions.get(); | ||
| if (module instanceof Promise) require_logger.error(extraOptions?.from === "build" ? _module_federation_error_codes.RUNTIME_005 : _module_federation_error_codes.RUNTIME_006, _module_federation_error_codes.runtimeDescMap, { | ||
| hostName: host.options.name, | ||
| sharedPkgName: pkgName | ||
| }, void 0, require_context.optionsToMFContext(host.options)); | ||
| shareOptions.lib = module; | ||
| this.setShared({ | ||
| pkgName, | ||
| loaded: true, | ||
| from: host.options.name, | ||
| lib: shareOptions.lib, | ||
| shared: shareOptions | ||
| }); | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShareSync", | ||
| pkgName, | ||
| shareInfo: shareOptions, | ||
| selectedShared: shareOptions | ||
| }); | ||
| return shareOptions.lib; | ||
| } | ||
| require_logger.error(_module_federation_error_codes.RUNTIME_006, _module_federation_error_codes.runtimeDescMap, { | ||
| hostName: host.options.name, | ||
| sharedPkgName: pkgName | ||
| }, void 0, require_context.optionsToMFContext(host.options)); | ||
| shareOptions.lib = module; | ||
| this.setShared({ | ||
| } catch (shareError) { | ||
| this.emitErrorLoadShare({ | ||
| lifecycle: "loadShareSync", | ||
| pkgName, | ||
| loaded: true, | ||
| from: host.options.name, | ||
| lib: shareOptions.lib, | ||
| shared: shareOptions | ||
| shareInfo: shareOptions, | ||
| error: shareError | ||
| }); | ||
| return shareOptions.lib; | ||
| throw shareError; | ||
| } | ||
| require_logger.error(_module_federation_error_codes.RUNTIME_006, _module_federation_error_codes.runtimeDescMap, { | ||
| hostName: host.options.name, | ||
| sharedPkgName: pkgName | ||
| }, void 0, require_context.optionsToMFContext(host.options)); | ||
| } | ||
@@ -264,0 +379,0 @@ initShareScopeMap(scopeName, shareScope, extraOptions = {}) { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.cjs","names":["PluginSystem","SyncWaterfallHook","AsyncWaterfallHook","AsyncHook","formatShareConfigs","getTargetSharedOptions","getRegisteredShare","directShare","shouldUseTreeShaking","DEFAULT_SCOPE","RUNTIME_005","RUNTIME_006","runtimeDescMap","optionsToMFContext","getGlobalShareScope"],"sources":["../../src/shared/index.ts"],"sourcesContent":["import {\n RUNTIME_005,\n RUNTIME_006,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Federation } from '../global';\nimport {\n Options,\n ShareScopeMap,\n ShareInfos,\n Shared,\n RemoteEntryExports,\n UserOptions,\n ShareStrategy,\n InitScope,\n InitTokens,\n CallFrom,\n TreeShakingArgs,\n} from '../type';\nimport { ModuleFederation } from '../core';\nimport {\n PluginSystem,\n AsyncHook,\n AsyncWaterfallHook,\n SyncWaterfallHook,\n} from '../utils/hooks';\nimport {\n formatShareConfigs,\n getRegisteredShare,\n getTargetSharedOptions,\n getGlobalShareScope,\n directShare,\n shouldUseTreeShaking,\n addUseIn,\n} from '../utils/share';\nimport { assert, error, addUniqueItem, optionsToMFContext } from '../utils';\nimport { DEFAULT_SCOPE } from '../constant';\nimport { LoadRemoteMatch } from '../remote';\nimport { createRemoteEntryInitOptions } from '../module';\n\nexport class SharedHandler {\n host: ModuleFederation;\n shareScopeMap: ShareScopeMap;\n hooks = new PluginSystem({\n beforeRegisterShare: new SyncWaterfallHook<{\n pkgName: string;\n shared: Shared;\n origin: ModuleFederation;\n }>('beforeRegisterShare'),\n afterResolve: new AsyncWaterfallHook<LoadRemoteMatch>('afterResolve'),\n beforeLoadShare: new AsyncWaterfallHook<{\n pkgName: string;\n shareInfo?: Shared;\n shared: Options['shared'];\n origin: ModuleFederation;\n }>('beforeLoadShare'),\n // not used yet\n loadShare: new AsyncHook<[ModuleFederation, string, ShareInfos]>(),\n resolveShare: new SyncWaterfallHook<{\n shareScopeMap: ShareScopeMap;\n scope: string;\n pkgName: string;\n version: string;\n shareInfo: Shared;\n GlobalFederation: Federation;\n resolver: () => { shared: Shared; useTreesShaking: boolean } | undefined;\n }>('resolveShare'),\n // maybe will change, temporarily for internal use only\n initContainerShareScopeMap: new SyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n options: Options;\n origin: ModuleFederation;\n scopeName: string;\n hostShareScopeMap?: ShareScopeMap;\n }>('initContainerShareScopeMap'),\n });\n initTokens: InitTokens;\n constructor(host: ModuleFederation) {\n this.host = host;\n this.shareScopeMap = {};\n this.initTokens = {};\n this._setGlobalShareScopeMap(host.options);\n }\n\n // register shared in shareScopeMap\n registerShared(globalOptions: Options, userOptions: UserOptions) {\n const { newShareInfos, allShareInfos } = formatShareConfigs(\n globalOptions,\n userOptions,\n );\n\n const sharedKeys = Object.keys(newShareInfos);\n sharedKeys.forEach((sharedKey) => {\n const sharedVals = newShareInfos[sharedKey];\n sharedVals.forEach((sharedVal) => {\n sharedVal.scope.forEach((sc) => {\n this.hooks.lifecycle.beforeRegisterShare.emit({\n origin: this.host,\n pkgName: sharedKey,\n shared: sharedVal,\n });\n const registeredShared = this.shareScopeMap[sc]?.[sharedKey];\n if (!registeredShared) {\n this.setShared({\n pkgName: sharedKey,\n lib: sharedVal.lib,\n get: sharedVal.get,\n loaded: sharedVal.loaded || Boolean(sharedVal.lib),\n shared: sharedVal,\n from: userOptions.name,\n });\n }\n });\n });\n });\n\n return {\n newShareInfos,\n allShareInfos,\n };\n }\n\n async loadShare<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): Promise<false | (() => T | undefined)> {\n const { host } = this;\n // This function performs the following steps:\n // 1. Checks if the currently loaded share already exists, if not, it throws an error\n // 2. Searches globally for a matching share, if found, it uses it directly\n // 3. If not found, it retrieves it from the current share and stores the obtained share globally.\n\n const shareOptions = getTargetSharedOptions({\n pkgName,\n extraOptions,\n shareInfos: host.options.shared,\n });\n\n if (shareOptions?.scope) {\n await Promise.all(\n shareOptions.scope.map(async (shareScope) => {\n await Promise.all(\n this.initializeSharing(shareScope, {\n strategy: shareOptions.strategy,\n }),\n );\n return;\n }),\n );\n }\n const loadShareRes = await this.hooks.lifecycle.beforeLoadShare.emit({\n pkgName,\n shareInfo: shareOptions,\n shared: host.options.shared,\n origin: host,\n });\n\n const { shareInfo: shareOptionsRes } = loadShareRes;\n\n // Assert that shareInfoRes exists, if not, throw an error\n assert(\n shareOptionsRes,\n `Cannot find shared \"${pkgName}\" in host \"${host.options.name}\". Ensure the shared config for \"${pkgName}\" is declared in the federation plugin options and the host has been initialized before loading shares.`,\n );\n\n const { shared: registeredShared, useTreesShaking } =\n getRegisteredShare(\n this.shareScopeMap,\n pkgName,\n shareOptionsRes,\n this.hooks.lifecycle.resolveShare,\n ) || {};\n\n if (registeredShared) {\n const targetShared = directShare(registeredShared, useTreesShaking);\n if (targetShared.lib) {\n addUseIn(targetShared, host.options.name);\n return targetShared.lib as () => T;\n } else if (targetShared.loading && !targetShared.loaded) {\n const factory = await targetShared.loading;\n targetShared.loaded = true;\n if (!targetShared.lib) {\n targetShared.lib = factory;\n }\n addUseIn(targetShared, host.options.name);\n return factory;\n } else {\n const asyncLoadProcess = async () => {\n const factory = await targetShared.get!();\n addUseIn(targetShared, host.options.name);\n targetShared.loaded = true;\n targetShared.lib = factory;\n return factory as () => T;\n };\n const loading = asyncLoadProcess();\n this.setShared({\n pkgName,\n loaded: false,\n shared: registeredShared,\n from: host.options.name,\n lib: null,\n loading,\n treeShaking: useTreesShaking\n ? (targetShared as TreeShakingArgs)\n : undefined,\n });\n return loading;\n }\n } else {\n if (extraOptions?.customShareInfo) {\n return false;\n }\n const _useTreeShaking = shouldUseTreeShaking(shareOptionsRes.treeShaking);\n const targetShared = directShare(shareOptionsRes, _useTreeShaking);\n\n const asyncLoadProcess = async () => {\n const factory = await targetShared.get!();\n targetShared.lib = factory;\n targetShared.loaded = true;\n addUseIn(targetShared, host.options.name);\n const { shared: gShared, useTreesShaking: gUseTreeShaking } =\n getRegisteredShare(\n this.shareScopeMap,\n pkgName,\n shareOptionsRes,\n this.hooks.lifecycle.resolveShare,\n ) || {};\n if (gShared) {\n const targetGShared = directShare(gShared, gUseTreeShaking);\n targetGShared.lib = factory;\n targetGShared.loaded = true;\n gShared.from = shareOptionsRes.from;\n }\n return factory as () => T;\n };\n const loading = asyncLoadProcess();\n this.setShared({\n pkgName,\n loaded: false,\n shared: shareOptionsRes,\n from: host.options.name,\n lib: null,\n loading,\n treeShaking: _useTreeShaking\n ? (targetShared as TreeShakingArgs)\n : undefined,\n });\n return loading;\n }\n }\n\n /**\n * This function initializes the sharing sequence (executed only once per share scope).\n * It accepts one argument, the name of the share scope.\n * If the share scope does not exist, it creates one.\n */\n // eslint-disable-next-line @typescript-eslint/member-ordering\n initializeSharing(\n shareScopeName = DEFAULT_SCOPE,\n extraOptions?: {\n initScope?: InitScope;\n from?: CallFrom;\n strategy?: ShareStrategy;\n },\n ): Array<Promise<void>> {\n const { host } = this;\n const from = extraOptions?.from;\n const strategy = extraOptions?.strategy;\n let initScope = extraOptions?.initScope;\n const promises: Promise<any>[] = [];\n if (from !== 'build') {\n const { initTokens } = this;\n if (!initScope) initScope = [];\n let initToken = initTokens[shareScopeName];\n if (!initToken)\n initToken = initTokens[shareScopeName] = { from: this.host.name };\n if (initScope.indexOf(initToken) >= 0) return promises;\n initScope.push(initToken);\n }\n\n const shareScope = this.shareScopeMap;\n const hostName = host.options.name;\n // Creates a new share scope if necessary\n if (!shareScope[shareScopeName]) {\n shareScope[shareScopeName] = {};\n }\n // Executes all initialization snippets from all accessible modules\n const scope = shareScope[shareScopeName];\n const register = (name: string, shared: Shared) => {\n const { version, eager } = shared;\n scope[name] = scope[name] || {};\n const versions = scope[name];\n const activeVersion: Shared =\n versions[version] && (directShare(versions[version]) as Shared);\n const activeVersionEager = Boolean(\n activeVersion &&\n (('eager' in activeVersion && activeVersion.eager) ||\n ('shareConfig' in activeVersion && activeVersion.shareConfig?.eager)),\n );\n if (\n !activeVersion ||\n (activeVersion.strategy !== 'loaded-first' &&\n !activeVersion.loaded &&\n (Boolean(!eager) !== !activeVersionEager\n ? eager\n : hostName > versions[version].from))\n ) {\n versions[version] = shared;\n }\n };\n\n const initRemoteModule = async (key: string): Promise<void> => {\n const { module } = await host.remoteHandler.getRemoteModuleAndOptions({\n id: key,\n });\n let remoteEntryExports: RemoteEntryExports | undefined = undefined;\n try {\n remoteEntryExports = await module.getEntry();\n } catch (error) {\n remoteEntryExports =\n (await host.remoteHandler.hooks.lifecycle.errorLoadRemote.emit({\n id: key,\n error,\n from: 'runtime',\n lifecycle: 'beforeLoadShare',\n origin: host,\n })) as RemoteEntryExports;\n if (!remoteEntryExports) {\n return;\n }\n } finally {\n // prevent self load loop: when host load self , the initTokens is not the same\n if (remoteEntryExports?.init && !module.initing) {\n module.remoteEntryExports = remoteEntryExports;\n await module.init(undefined, undefined, initScope);\n }\n }\n };\n Object.keys(host.options.shared).forEach((shareName) => {\n const sharedArr = host.options.shared[shareName];\n sharedArr.forEach((shared) => {\n if (shared.scope.includes(shareScopeName)) {\n register(shareName, shared);\n }\n });\n });\n // TODO: strategy==='version-first' need to be removed in the future\n if (\n host.options.shareStrategy === 'version-first' ||\n strategy === 'version-first'\n ) {\n host.options.remotes.forEach((remote) => {\n if (remote.shareScope === shareScopeName) {\n promises.push(initRemoteModule(remote.name));\n }\n });\n }\n\n return promises;\n }\n\n // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.\n // 1. If the loaded shared already exists globally, then it will be reused\n // 2. If lib exists in local shared, it will be used directly\n // 3. If the local get returns something other than Promise, then it will be used directly\n loadShareSync<T>(\n pkgName: string,\n extraOptions?: {\n from?: 'build' | 'runtime';\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): () => T | never {\n const { host } = this;\n const shareOptions = getTargetSharedOptions({\n pkgName,\n extraOptions,\n shareInfos: host.options.shared,\n });\n\n if (shareOptions?.scope) {\n shareOptions.scope.forEach((shareScope) => {\n this.initializeSharing(shareScope, { strategy: shareOptions.strategy });\n });\n }\n const { shared: registeredShared, useTreesShaking } =\n getRegisteredShare(\n this.shareScopeMap,\n pkgName,\n shareOptions,\n this.hooks.lifecycle.resolveShare,\n ) || {};\n\n if (registeredShared) {\n if (typeof registeredShared.lib === 'function') {\n addUseIn(registeredShared, host.options.name);\n if (!registeredShared.loaded) {\n registeredShared.loaded = true;\n if (registeredShared.from === host.options.name) {\n shareOptions.loaded = true;\n }\n }\n return registeredShared.lib as () => T;\n }\n if (typeof registeredShared.get === 'function') {\n const module = registeredShared.get();\n if (!(module instanceof Promise)) {\n addUseIn(registeredShared, host.options.name);\n this.setShared({\n pkgName,\n loaded: true,\n from: host.options.name,\n lib: module,\n shared: registeredShared,\n });\n return module;\n }\n }\n }\n\n if (shareOptions.lib) {\n if (!shareOptions.loaded) {\n shareOptions.loaded = true;\n }\n return shareOptions.lib as () => T;\n }\n\n if (shareOptions.get) {\n const module = shareOptions.get();\n\n if (module instanceof Promise) {\n const errorCode =\n extraOptions?.from === 'build' ? RUNTIME_005 : RUNTIME_006;\n error(\n errorCode,\n runtimeDescMap,\n {\n hostName: host.options.name,\n sharedPkgName: pkgName,\n },\n undefined,\n optionsToMFContext(host.options),\n );\n }\n\n shareOptions.lib = module;\n\n this.setShared({\n pkgName,\n loaded: true,\n from: host.options.name,\n lib: shareOptions.lib,\n shared: shareOptions,\n });\n return shareOptions.lib as () => T;\n }\n\n error(\n RUNTIME_006,\n runtimeDescMap,\n {\n hostName: host.options.name,\n sharedPkgName: pkgName,\n },\n undefined,\n optionsToMFContext(host.options),\n );\n }\n\n initShareScopeMap(\n scopeName: string,\n shareScope: ShareScopeMap[string],\n extraOptions: { hostShareScopeMap?: ShareScopeMap } = {},\n ): void {\n const { host } = this;\n this.shareScopeMap[scopeName] = shareScope;\n this.hooks.lifecycle.initContainerShareScopeMap.emit({\n shareScope,\n options: host.options,\n origin: host,\n scopeName,\n hostShareScopeMap: extraOptions.hostShareScopeMap,\n });\n }\n\n private setShared({\n pkgName,\n shared,\n from,\n lib,\n loading,\n loaded,\n get,\n treeShaking,\n }: {\n pkgName: string;\n shared: Shared;\n from: string;\n lib: any;\n loaded?: boolean;\n loading?: Shared['loading'];\n get?: Shared['get'];\n treeShaking?: TreeShakingArgs;\n }): void {\n const { version, scope = 'default', ...shareInfo } = shared;\n const scopes: string[] = Array.isArray(scope) ? scope : [scope];\n\n const mergeAttrs = (shared: Shared) => {\n const merge = <K extends keyof TreeShakingArgs>(\n s: TreeShakingArgs,\n key: K,\n val: TreeShakingArgs[K],\n ): void => {\n if (val && !s[key]) {\n s[key] = val;\n }\n };\n const targetShared = (\n treeShaking ? shared.treeShaking! : shared\n ) as TreeShakingArgs;\n merge(targetShared, 'loaded', loaded);\n merge(targetShared, 'loading', loading);\n merge(targetShared, 'get', get);\n };\n scopes.forEach((sc) => {\n if (!this.shareScopeMap[sc]) {\n this.shareScopeMap[sc] = {};\n }\n if (!this.shareScopeMap[sc][pkgName]) {\n this.shareScopeMap[sc][pkgName] = {};\n }\n\n if (!this.shareScopeMap[sc][pkgName][version]) {\n this.shareScopeMap[sc][pkgName][version] = {\n version,\n scope: [sc],\n ...shareInfo,\n lib,\n };\n }\n\n const registeredShared = this.shareScopeMap[sc][pkgName][version];\n mergeAttrs(registeredShared);\n if (from && registeredShared.from !== from) {\n registeredShared.from = from;\n }\n });\n }\n\n private _setGlobalShareScopeMap(hostOptions: Options): void {\n const globalShareScopeMap = getGlobalShareScope();\n const identifier = hostOptions.id || hostOptions.name;\n if (identifier && !globalShareScopeMap[identifier]) {\n globalShareScopeMap[identifier] = this.shareScopeMap;\n }\n }\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"index.cjs","names":["PluginSystem","SyncWaterfallHook","AsyncWaterfallHook","AsyncHook","SyncHook","formatShareConfigs","getTargetSharedOptions","getRegisteredShare","directShare","shouldUseTreeShaking","DEFAULT_SCOPE","RUNTIME_005","RUNTIME_006","runtimeDescMap","optionsToMFContext","getGlobalShareScope"],"sources":["../../src/shared/index.ts"],"sourcesContent":["import {\n RUNTIME_005,\n RUNTIME_006,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Federation } from '../global';\nimport {\n Options,\n ShareScopeMap,\n ShareInfos,\n Shared,\n RemoteEntryExports,\n UserOptions,\n ShareStrategy,\n InitScope,\n InitTokens,\n CallFrom,\n TreeShakingArgs,\n} from '../type';\nimport { ModuleFederation } from '../core';\nimport {\n PluginSystem,\n AsyncHook,\n AsyncWaterfallHook,\n SyncWaterfallHook,\n SyncHook,\n} from '../utils/hooks';\nimport {\n formatShareConfigs,\n getRegisteredShare,\n getTargetSharedOptions,\n getGlobalShareScope,\n directShare,\n shouldUseTreeShaking,\n addUseIn,\n} from '../utils/share';\nimport {\n assert,\n error,\n addUniqueItem,\n optionsToMFContext,\n warn,\n} from '../utils';\nimport { DEFAULT_SCOPE } from '../constant';\nimport { LoadRemoteMatch } from '../remote';\nimport { createRemoteEntryInitOptions } from '../module';\n\nexport class SharedHandler {\n host: ModuleFederation;\n shareScopeMap: ShareScopeMap;\n hooks = new PluginSystem({\n beforeRegisterShare: new SyncWaterfallHook<{\n pkgName: string;\n shared: Shared;\n origin: ModuleFederation;\n }>('beforeRegisterShare'),\n afterResolve: new AsyncWaterfallHook<LoadRemoteMatch>('afterResolve'),\n beforeLoadShare: new AsyncWaterfallHook<{\n pkgName: string;\n shareInfo?: Shared;\n shared: Options['shared'];\n origin: ModuleFederation;\n }>('beforeLoadShare'),\n // not used yet\n loadShare: new AsyncHook<[ModuleFederation, string, ShareInfos]>(),\n afterLoadShare: new SyncHook<\n [\n {\n pkgName: string;\n shareInfo?: Partial<Shared>;\n selectedShared?: Partial<Shared>;\n shared: Options['shared'];\n shareScopeMap: ShareScopeMap;\n lifecycle: 'loadShare' | 'loadShareSync';\n origin: ModuleFederation;\n },\n ],\n void\n >('afterLoadShare'),\n errorLoadShare: new SyncHook<\n [\n {\n pkgName: string;\n shareInfo?: Partial<Shared>;\n shared: Options['shared'];\n shareScopeMap: ShareScopeMap;\n lifecycle: 'loadShare' | 'loadShareSync';\n origin: ModuleFederation;\n error?: unknown;\n recovered?: boolean;\n },\n ],\n void\n >('errorLoadShare'),\n resolveShare: new SyncWaterfallHook<{\n shareScopeMap: ShareScopeMap;\n scope: string;\n pkgName: string;\n version: string;\n shareInfo: Shared;\n GlobalFederation: Federation;\n resolver: () => { shared: Shared; useTreesShaking: boolean } | undefined;\n }>('resolveShare'),\n // maybe will change, temporarily for internal use only\n initContainerShareScopeMap: new SyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n options: Options;\n origin: ModuleFederation;\n scopeName: string;\n hostShareScopeMap?: ShareScopeMap;\n }>('initContainerShareScopeMap'),\n });\n initTokens: InitTokens;\n constructor(host: ModuleFederation) {\n this.host = host;\n this.shareScopeMap = {};\n this.initTokens = {};\n this._setGlobalShareScopeMap(host.options);\n }\n\n private emitAfterLoadShare({\n lifecycle,\n pkgName,\n shareInfo,\n selectedShared,\n }: {\n lifecycle: 'loadShare' | 'loadShareSync';\n pkgName: string;\n shareInfo?: Partial<Shared>;\n selectedShared?: Partial<Shared>;\n }): void {\n try {\n this.hooks.lifecycle.afterLoadShare.emit({\n pkgName,\n shareInfo,\n selectedShared,\n shared: this.host.options.shared,\n shareScopeMap: this.shareScopeMap,\n lifecycle,\n origin: this.host,\n });\n } catch (error) {\n warn(error);\n }\n }\n\n private emitErrorLoadShare({\n lifecycle,\n pkgName,\n shareInfo,\n error,\n recovered,\n }: {\n lifecycle: 'loadShare' | 'loadShareSync';\n pkgName: string;\n shareInfo?: Partial<Shared>;\n error?: unknown;\n recovered?: boolean;\n }): void {\n try {\n this.hooks.lifecycle.errorLoadShare.emit({\n pkgName,\n shareInfo,\n shared: this.host.options.shared,\n shareScopeMap: this.shareScopeMap,\n lifecycle,\n origin: this.host,\n error,\n recovered,\n });\n } catch (hookError) {\n warn(hookError);\n }\n }\n\n // register shared in shareScopeMap\n registerShared(globalOptions: Options, userOptions: UserOptions) {\n const { newShareInfos, allShareInfos } = formatShareConfigs(\n globalOptions,\n userOptions,\n );\n\n const sharedKeys = Object.keys(newShareInfos);\n sharedKeys.forEach((sharedKey) => {\n const sharedVals = newShareInfos[sharedKey];\n sharedVals.forEach((sharedVal) => {\n sharedVal.scope.forEach((sc) => {\n this.hooks.lifecycle.beforeRegisterShare.emit({\n origin: this.host,\n pkgName: sharedKey,\n shared: sharedVal,\n });\n const registeredShared = this.shareScopeMap[sc]?.[sharedKey];\n if (!registeredShared) {\n this.setShared({\n pkgName: sharedKey,\n lib: sharedVal.lib,\n get: sharedVal.get,\n loaded: sharedVal.loaded || Boolean(sharedVal.lib),\n shared: sharedVal,\n from: userOptions.name,\n });\n }\n });\n });\n });\n\n return {\n newShareInfos,\n allShareInfos,\n };\n }\n\n async loadShare<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): Promise<false | (() => T | undefined)> {\n const { host } = this;\n // This function performs the following steps:\n // 1. Checks if the currently loaded share already exists, if not, it throws an error\n // 2. Searches globally for a matching share, if found, it uses it directly\n // 3. If not found, it retrieves it from the current share and stores the obtained share globally.\n\n const shareOptions = getTargetSharedOptions({\n pkgName,\n extraOptions,\n shareInfos: host.options.shared,\n });\n let shareOptionsRes: Shared | undefined = shareOptions;\n\n try {\n if (shareOptions?.scope) {\n await Promise.all(\n shareOptions.scope.map(async (shareScope) => {\n await Promise.all(\n this.initializeSharing(shareScope, {\n strategy: shareOptions.strategy,\n }),\n );\n return;\n }),\n );\n }\n const loadShareRes = await this.hooks.lifecycle.beforeLoadShare.emit({\n pkgName,\n shareInfo: shareOptions,\n shared: host.options.shared,\n origin: host,\n });\n\n shareOptionsRes = loadShareRes.shareInfo;\n\n // Assert that shareInfoRes exists, if not, throw an error\n assert(\n shareOptionsRes,\n `Cannot find shared \"${pkgName}\" in host \"${host.options.name}\". Ensure the shared config for \"${pkgName}\" is declared in the federation plugin options and the host has been initialized before loading shares.`,\n );\n const resolvedShareOptions = shareOptionsRes;\n\n const { shared: registeredShared, useTreesShaking } =\n getRegisteredShare(\n this.shareScopeMap,\n pkgName,\n shareOptionsRes,\n this.hooks.lifecycle.resolveShare,\n ) || {};\n\n if (registeredShared) {\n const targetShared = directShare(registeredShared, useTreesShaking);\n if (targetShared.lib) {\n addUseIn(targetShared, host.options.name);\n this.emitAfterLoadShare({\n lifecycle: 'loadShare',\n pkgName,\n shareInfo: resolvedShareOptions,\n selectedShared: registeredShared,\n });\n return targetShared.lib as () => T;\n } else if (targetShared.loading && !targetShared.loaded) {\n const factory = await targetShared.loading;\n targetShared.loaded = true;\n if (!targetShared.lib) {\n targetShared.lib = factory;\n }\n addUseIn(targetShared, host.options.name);\n this.emitAfterLoadShare({\n lifecycle: 'loadShare',\n pkgName,\n shareInfo: resolvedShareOptions,\n selectedShared: registeredShared,\n });\n return factory;\n } else {\n const asyncLoadProcess = async () => {\n const factory = await targetShared.get!();\n addUseIn(targetShared, host.options.name);\n targetShared.loaded = true;\n targetShared.lib = factory;\n return factory as () => T;\n };\n const loading = asyncLoadProcess();\n this.setShared({\n pkgName,\n loaded: false,\n shared: registeredShared,\n from: host.options.name,\n lib: null,\n loading,\n treeShaking: useTreesShaking\n ? (targetShared as TreeShakingArgs)\n : undefined,\n });\n const factory = await loading;\n this.emitAfterLoadShare({\n lifecycle: 'loadShare',\n pkgName,\n shareInfo: resolvedShareOptions,\n selectedShared: registeredShared,\n });\n return factory;\n }\n } else {\n if (extraOptions?.customShareInfo) {\n this.emitErrorLoadShare({\n lifecycle: 'loadShare',\n pkgName,\n shareInfo: resolvedShareOptions,\n recovered: true,\n });\n return false;\n }\n const _useTreeShaking = shouldUseTreeShaking(\n resolvedShareOptions.treeShaking,\n );\n const targetShared = directShare(resolvedShareOptions, _useTreeShaking);\n\n const asyncLoadProcess = async () => {\n const factory = await targetShared.get!();\n targetShared.lib = factory;\n targetShared.loaded = true;\n addUseIn(targetShared, host.options.name);\n const { shared: gShared, useTreesShaking: gUseTreeShaking } =\n getRegisteredShare(\n this.shareScopeMap,\n pkgName,\n resolvedShareOptions,\n this.hooks.lifecycle.resolveShare,\n ) || {};\n if (gShared) {\n const targetGShared = directShare(gShared, gUseTreeShaking);\n targetGShared.lib = factory;\n targetGShared.loaded = true;\n gShared.from = resolvedShareOptions.from;\n }\n return factory as () => T;\n };\n const loading = asyncLoadProcess();\n this.setShared({\n pkgName,\n loaded: false,\n shared: resolvedShareOptions,\n from: host.options.name,\n lib: null,\n loading,\n treeShaking: _useTreeShaking\n ? (targetShared as TreeShakingArgs)\n : undefined,\n });\n const factory = await loading;\n this.emitAfterLoadShare({\n lifecycle: 'loadShare',\n pkgName,\n shareInfo: resolvedShareOptions,\n selectedShared: resolvedShareOptions,\n });\n return factory;\n }\n } catch (shareError) {\n this.emitErrorLoadShare({\n lifecycle: 'loadShare',\n pkgName,\n shareInfo: shareOptionsRes,\n error: shareError,\n });\n throw shareError;\n }\n }\n\n /**\n * This function initializes the sharing sequence (executed only once per share scope).\n * It accepts one argument, the name of the share scope.\n * If the share scope does not exist, it creates one.\n */\n // eslint-disable-next-line @typescript-eslint/member-ordering\n initializeSharing(\n shareScopeName = DEFAULT_SCOPE,\n extraOptions?: {\n initScope?: InitScope;\n from?: CallFrom;\n strategy?: ShareStrategy;\n },\n ): Array<Promise<void>> {\n const { host } = this;\n const from = extraOptions?.from;\n const strategy = extraOptions?.strategy;\n let initScope = extraOptions?.initScope;\n const promises: Promise<any>[] = [];\n if (from !== 'build') {\n const { initTokens } = this;\n if (!initScope) initScope = [];\n let initToken = initTokens[shareScopeName];\n if (!initToken)\n initToken = initTokens[shareScopeName] = { from: this.host.name };\n if (initScope.indexOf(initToken) >= 0) return promises;\n initScope.push(initToken);\n }\n\n const shareScope = this.shareScopeMap;\n const hostName = host.options.name;\n // Creates a new share scope if necessary\n if (!shareScope[shareScopeName]) {\n shareScope[shareScopeName] = {};\n }\n // Executes all initialization snippets from all accessible modules\n const scope = shareScope[shareScopeName];\n const register = (name: string, shared: Shared) => {\n const { version, eager } = shared;\n scope[name] = scope[name] || {};\n const versions = scope[name];\n const activeVersion: Shared =\n versions[version] && (directShare(versions[version]) as Shared);\n const activeVersionEager = Boolean(\n activeVersion &&\n (('eager' in activeVersion && activeVersion.eager) ||\n ('shareConfig' in activeVersion && activeVersion.shareConfig?.eager)),\n );\n if (\n !activeVersion ||\n (activeVersion.strategy !== 'loaded-first' &&\n !activeVersion.loaded &&\n (Boolean(!eager) !== !activeVersionEager\n ? eager\n : hostName > versions[version].from))\n ) {\n versions[version] = shared;\n }\n };\n\n const initRemoteModule = async (key: string): Promise<void> => {\n const { module } = await host.remoteHandler.getRemoteModuleAndOptions({\n id: key,\n });\n let remoteEntryExports: RemoteEntryExports | undefined = undefined;\n try {\n remoteEntryExports = await module.getEntry();\n } catch (error) {\n remoteEntryExports =\n (await host.remoteHandler.hooks.lifecycle.errorLoadRemote.emit({\n id: key,\n error,\n from: 'runtime',\n lifecycle: 'beforeLoadShare',\n remote: module.remoteInfo,\n origin: host,\n })) as RemoteEntryExports;\n if (!remoteEntryExports) {\n return;\n }\n } finally {\n // prevent self load loop: when host load self , the initTokens is not the same\n if (remoteEntryExports?.init && !module.initing) {\n module.remoteEntryExports = remoteEntryExports;\n await module.init(undefined, undefined, initScope);\n }\n }\n };\n Object.keys(host.options.shared).forEach((shareName) => {\n const sharedArr = host.options.shared[shareName];\n sharedArr.forEach((shared) => {\n if (shared.scope.includes(shareScopeName)) {\n register(shareName, shared);\n }\n });\n });\n // TODO: strategy==='version-first' need to be removed in the future\n if (\n host.options.shareStrategy === 'version-first' ||\n strategy === 'version-first'\n ) {\n host.options.remotes.forEach((remote) => {\n if (remote.shareScope === shareScopeName) {\n promises.push(initRemoteModule(remote.name));\n }\n });\n }\n\n return promises;\n }\n\n // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.\n // 1. If the loaded shared already exists globally, then it will be reused\n // 2. If lib exists in local shared, it will be used directly\n // 3. If the local get returns something other than Promise, then it will be used directly\n loadShareSync<T>(\n pkgName: string,\n extraOptions?: {\n from?: 'build' | 'runtime';\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): () => T | never {\n const { host } = this;\n const shareOptions = getTargetSharedOptions({\n pkgName,\n extraOptions,\n shareInfos: host.options.shared,\n });\n\n try {\n if (shareOptions?.scope) {\n shareOptions.scope.forEach((shareScope) => {\n this.initializeSharing(shareScope, {\n strategy: shareOptions.strategy,\n });\n });\n }\n const { shared: registeredShared } =\n getRegisteredShare(\n this.shareScopeMap,\n pkgName,\n shareOptions,\n this.hooks.lifecycle.resolveShare,\n ) || {};\n\n if (registeredShared) {\n if (typeof registeredShared.lib === 'function') {\n addUseIn(registeredShared, host.options.name);\n if (!registeredShared.loaded) {\n registeredShared.loaded = true;\n if (registeredShared.from === host.options.name) {\n shareOptions.loaded = true;\n }\n }\n this.emitAfterLoadShare({\n lifecycle: 'loadShareSync',\n pkgName,\n shareInfo: shareOptions,\n selectedShared: registeredShared,\n });\n return registeredShared.lib as () => T;\n }\n if (typeof registeredShared.get === 'function') {\n const module = registeredShared.get();\n if (!(module instanceof Promise)) {\n addUseIn(registeredShared, host.options.name);\n this.setShared({\n pkgName,\n loaded: true,\n from: host.options.name,\n lib: module,\n shared: registeredShared,\n });\n this.emitAfterLoadShare({\n lifecycle: 'loadShareSync',\n pkgName,\n shareInfo: shareOptions,\n selectedShared: registeredShared,\n });\n return module;\n }\n }\n }\n\n if (shareOptions.lib) {\n if (!shareOptions.loaded) {\n shareOptions.loaded = true;\n }\n this.emitAfterLoadShare({\n lifecycle: 'loadShareSync',\n pkgName,\n shareInfo: shareOptions,\n selectedShared: shareOptions,\n });\n return shareOptions.lib as () => T;\n }\n\n if (shareOptions.get) {\n const module = shareOptions.get();\n\n if (module instanceof Promise) {\n const errorCode =\n extraOptions?.from === 'build' ? RUNTIME_005 : RUNTIME_006;\n error(\n errorCode,\n runtimeDescMap,\n {\n hostName: host.options.name,\n sharedPkgName: pkgName,\n },\n undefined,\n optionsToMFContext(host.options),\n );\n }\n\n shareOptions.lib = module;\n\n this.setShared({\n pkgName,\n loaded: true,\n from: host.options.name,\n lib: shareOptions.lib,\n shared: shareOptions,\n });\n this.emitAfterLoadShare({\n lifecycle: 'loadShareSync',\n pkgName,\n shareInfo: shareOptions,\n selectedShared: shareOptions,\n });\n return shareOptions.lib as () => T;\n }\n\n error(\n RUNTIME_006,\n runtimeDescMap,\n {\n hostName: host.options.name,\n sharedPkgName: pkgName,\n },\n undefined,\n optionsToMFContext(host.options),\n );\n } catch (shareError) {\n this.emitErrorLoadShare({\n lifecycle: 'loadShareSync',\n pkgName,\n shareInfo: shareOptions,\n error: shareError,\n });\n throw shareError;\n }\n }\n\n initShareScopeMap(\n scopeName: string,\n shareScope: ShareScopeMap[string],\n extraOptions: { hostShareScopeMap?: ShareScopeMap } = {},\n ): void {\n const { host } = this;\n this.shareScopeMap[scopeName] = shareScope;\n this.hooks.lifecycle.initContainerShareScopeMap.emit({\n shareScope,\n options: host.options,\n origin: host,\n scopeName,\n hostShareScopeMap: extraOptions.hostShareScopeMap,\n });\n }\n\n private setShared({\n pkgName,\n shared,\n from,\n lib,\n loading,\n loaded,\n get,\n treeShaking,\n }: {\n pkgName: string;\n shared: Shared;\n from: string;\n lib: any;\n loaded?: boolean;\n loading?: Shared['loading'];\n get?: Shared['get'];\n treeShaking?: TreeShakingArgs;\n }): void {\n const { version, scope = 'default', ...shareInfo } = shared;\n const scopes: string[] = Array.isArray(scope) ? scope : [scope];\n\n const mergeAttrs = (shared: Shared) => {\n const merge = <K extends keyof TreeShakingArgs>(\n s: TreeShakingArgs,\n key: K,\n val: TreeShakingArgs[K],\n ): void => {\n if (val && !s[key]) {\n s[key] = val;\n }\n };\n const targetShared = (\n treeShaking ? shared.treeShaking! : shared\n ) as TreeShakingArgs;\n merge(targetShared, 'loaded', loaded);\n merge(targetShared, 'loading', loading);\n merge(targetShared, 'get', get);\n };\n scopes.forEach((sc) => {\n if (!this.shareScopeMap[sc]) {\n this.shareScopeMap[sc] = {};\n }\n if (!this.shareScopeMap[sc][pkgName]) {\n this.shareScopeMap[sc][pkgName] = {};\n }\n\n if (!this.shareScopeMap[sc][pkgName][version]) {\n this.shareScopeMap[sc][pkgName][version] = {\n version,\n scope: [sc],\n ...shareInfo,\n lib,\n };\n }\n\n const registeredShared = this.shareScopeMap[sc][pkgName][version];\n mergeAttrs(registeredShared);\n if (from && registeredShared.from !== from) {\n registeredShared.from = from;\n }\n });\n }\n\n private _setGlobalShareScopeMap(hostOptions: Options): void {\n const globalShareScopeMap = getGlobalShareScope();\n const identifier = hostOptions.id || hostOptions.name;\n if (identifier && !globalShareScopeMap[identifier]) {\n globalShareScopeMap[identifier] = this.shareScopeMap;\n }\n }\n}\n"],"mappings":"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"} |
@@ -0,1 +1,2 @@ | ||
| import { SyncHook } from "../utils/hooks/syncHook.js"; | ||
| import { AsyncHook } from "../utils/hooks/asyncHook.js"; | ||
@@ -27,2 +28,21 @@ import { SyncWaterfallHook } from "../utils/hooks/syncWaterfallHook.js"; | ||
| loadShare: AsyncHook<[ModuleFederation, string, ShareInfos], false | void | Promise<false | void>>; | ||
| afterLoadShare: SyncHook<[{ | ||
| pkgName: string; | ||
| shareInfo?: Partial<Shared>; | ||
| selectedShared?: Partial<Shared>; | ||
| shared: Options["shared"]; | ||
| shareScopeMap: ShareScopeMap; | ||
| lifecycle: "loadShare" | "loadShareSync"; | ||
| origin: ModuleFederation; | ||
| }], void>; | ||
| errorLoadShare: SyncHook<[{ | ||
| pkgName: string; | ||
| shareInfo?: Partial<Shared>; | ||
| shared: Options["shared"]; | ||
| shareScopeMap: ShareScopeMap; | ||
| lifecycle: "loadShare" | "loadShareSync"; | ||
| origin: ModuleFederation; | ||
| error?: unknown; | ||
| recovered?: boolean; | ||
| }], void>; | ||
| resolveShare: SyncWaterfallHook<{ | ||
@@ -50,2 +70,4 @@ shareScopeMap: ShareScopeMap; | ||
| constructor(host: ModuleFederation); | ||
| private emitAfterLoadShare; | ||
| private emitErrorLoadShare; | ||
| registerShared(globalOptions: Options, userOptions: UserOptions): { | ||
@@ -52,0 +74,0 @@ newShareInfos: ShareInfos; |
+211
-96
@@ -1,2 +0,2 @@ | ||
| import { assert, error } from "../utils/logger.js"; | ||
| import { assert, error, warn } from "../utils/logger.js"; | ||
| import { DEFAULT_SCOPE } from "../constant.js"; | ||
@@ -6,2 +6,3 @@ import { addUseIn, directShare, formatShareConfigs, getGlobalShareScope, getRegisteredShare, getTargetSharedOptions, shouldUseTreeShaking } from "../utils/share.js"; | ||
| import "../utils/index.js"; | ||
| import { SyncHook } from "../utils/hooks/syncHook.js"; | ||
| import { AsyncHook } from "../utils/hooks/asyncHook.js"; | ||
@@ -22,2 +23,4 @@ import { SyncWaterfallHook } from "../utils/hooks/syncWaterfallHook.js"; | ||
| loadShare: new AsyncHook(), | ||
| afterLoadShare: new SyncHook("afterLoadShare"), | ||
| errorLoadShare: new SyncHook("errorLoadShare"), | ||
| resolveShare: new SyncWaterfallHook("resolveShare"), | ||
@@ -31,2 +34,33 @@ initContainerShareScopeMap: new SyncWaterfallHook("initContainerShareScopeMap") | ||
| } | ||
| emitAfterLoadShare({ lifecycle, pkgName, shareInfo, selectedShared }) { | ||
| try { | ||
| this.hooks.lifecycle.afterLoadShare.emit({ | ||
| pkgName, | ||
| shareInfo, | ||
| selectedShared, | ||
| shared: this.host.options.shared, | ||
| shareScopeMap: this.shareScopeMap, | ||
| lifecycle, | ||
| origin: this.host | ||
| }); | ||
| } catch (error) { | ||
| warn(error); | ||
| } | ||
| } | ||
| emitErrorLoadShare({ lifecycle, pkgName, shareInfo, error, recovered }) { | ||
| try { | ||
| this.hooks.lifecycle.errorLoadShare.emit({ | ||
| pkgName, | ||
| shareInfo, | ||
| shared: this.host.options.shared, | ||
| shareScopeMap: this.shareScopeMap, | ||
| lifecycle, | ||
| origin: this.host, | ||
| error, | ||
| recovered | ||
| }); | ||
| } catch (hookError) { | ||
| warn(hookError); | ||
| } | ||
| } | ||
| registerShared(globalOptions, userOptions) { | ||
@@ -65,30 +99,90 @@ const { newShareInfos, allShareInfos } = formatShareConfigs(globalOptions, userOptions); | ||
| }); | ||
| if (shareOptions?.scope) await Promise.all(shareOptions.scope.map(async (shareScope) => { | ||
| await Promise.all(this.initializeSharing(shareScope, { strategy: shareOptions.strategy })); | ||
| })); | ||
| const { shareInfo: shareOptionsRes } = await this.hooks.lifecycle.beforeLoadShare.emit({ | ||
| pkgName, | ||
| shareInfo: shareOptions, | ||
| shared: host.options.shared, | ||
| origin: host | ||
| }); | ||
| assert(shareOptionsRes, `Cannot find shared "${pkgName}" in host "${host.options.name}". Ensure the shared config for "${pkgName}" is declared in the federation plugin options and the host has been initialized before loading shares.`); | ||
| const { shared: registeredShared, useTreesShaking } = getRegisteredShare(this.shareScopeMap, pkgName, shareOptionsRes, this.hooks.lifecycle.resolveShare) || {}; | ||
| if (registeredShared) { | ||
| const targetShared = directShare(registeredShared, useTreesShaking); | ||
| if (targetShared.lib) { | ||
| addUseIn(targetShared, host.options.name); | ||
| return targetShared.lib; | ||
| } else if (targetShared.loading && !targetShared.loaded) { | ||
| const factory = await targetShared.loading; | ||
| targetShared.loaded = true; | ||
| if (!targetShared.lib) targetShared.lib = factory; | ||
| addUseIn(targetShared, host.options.name); | ||
| return factory; | ||
| let shareOptionsRes = shareOptions; | ||
| try { | ||
| if (shareOptions?.scope) await Promise.all(shareOptions.scope.map(async (shareScope) => { | ||
| await Promise.all(this.initializeSharing(shareScope, { strategy: shareOptions.strategy })); | ||
| })); | ||
| shareOptionsRes = (await this.hooks.lifecycle.beforeLoadShare.emit({ | ||
| pkgName, | ||
| shareInfo: shareOptions, | ||
| shared: host.options.shared, | ||
| origin: host | ||
| })).shareInfo; | ||
| assert(shareOptionsRes, `Cannot find shared "${pkgName}" in host "${host.options.name}". Ensure the shared config for "${pkgName}" is declared in the federation plugin options and the host has been initialized before loading shares.`); | ||
| const resolvedShareOptions = shareOptionsRes; | ||
| const { shared: registeredShared, useTreesShaking } = getRegisteredShare(this.shareScopeMap, pkgName, shareOptionsRes, this.hooks.lifecycle.resolveShare) || {}; | ||
| if (registeredShared) { | ||
| const targetShared = directShare(registeredShared, useTreesShaking); | ||
| if (targetShared.lib) { | ||
| addUseIn(targetShared, host.options.name); | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShare", | ||
| pkgName, | ||
| shareInfo: resolvedShareOptions, | ||
| selectedShared: registeredShared | ||
| }); | ||
| return targetShared.lib; | ||
| } else if (targetShared.loading && !targetShared.loaded) { | ||
| const factory = await targetShared.loading; | ||
| targetShared.loaded = true; | ||
| if (!targetShared.lib) targetShared.lib = factory; | ||
| addUseIn(targetShared, host.options.name); | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShare", | ||
| pkgName, | ||
| shareInfo: resolvedShareOptions, | ||
| selectedShared: registeredShared | ||
| }); | ||
| return factory; | ||
| } else { | ||
| const asyncLoadProcess = async () => { | ||
| const factory = await targetShared.get(); | ||
| addUseIn(targetShared, host.options.name); | ||
| targetShared.loaded = true; | ||
| targetShared.lib = factory; | ||
| return factory; | ||
| }; | ||
| const loading = asyncLoadProcess(); | ||
| this.setShared({ | ||
| pkgName, | ||
| loaded: false, | ||
| shared: registeredShared, | ||
| from: host.options.name, | ||
| lib: null, | ||
| loading, | ||
| treeShaking: useTreesShaking ? targetShared : void 0 | ||
| }); | ||
| const factory = await loading; | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShare", | ||
| pkgName, | ||
| shareInfo: resolvedShareOptions, | ||
| selectedShared: registeredShared | ||
| }); | ||
| return factory; | ||
| } | ||
| } else { | ||
| if (extraOptions?.customShareInfo) { | ||
| this.emitErrorLoadShare({ | ||
| lifecycle: "loadShare", | ||
| pkgName, | ||
| shareInfo: resolvedShareOptions, | ||
| recovered: true | ||
| }); | ||
| return false; | ||
| } | ||
| const _useTreeShaking = shouldUseTreeShaking(resolvedShareOptions.treeShaking); | ||
| const targetShared = directShare(resolvedShareOptions, _useTreeShaking); | ||
| const asyncLoadProcess = async () => { | ||
| const factory = await targetShared.get(); | ||
| targetShared.lib = factory; | ||
| targetShared.loaded = true; | ||
| addUseIn(targetShared, host.options.name); | ||
| targetShared.loaded = true; | ||
| targetShared.lib = factory; | ||
| const { shared: gShared, useTreesShaking: gUseTreeShaking } = getRegisteredShare(this.shareScopeMap, pkgName, resolvedShareOptions, this.hooks.lifecycle.resolveShare) || {}; | ||
| if (gShared) { | ||
| const targetGShared = directShare(gShared, gUseTreeShaking); | ||
| targetGShared.lib = factory; | ||
| targetGShared.loaded = true; | ||
| gShared.from = resolvedShareOptions.from; | ||
| } | ||
| return factory; | ||
@@ -100,39 +194,25 @@ }; | ||
| loaded: false, | ||
| shared: registeredShared, | ||
| shared: resolvedShareOptions, | ||
| from: host.options.name, | ||
| lib: null, | ||
| loading, | ||
| treeShaking: useTreesShaking ? targetShared : void 0 | ||
| treeShaking: _useTreeShaking ? targetShared : void 0 | ||
| }); | ||
| return loading; | ||
| const factory = await loading; | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShare", | ||
| pkgName, | ||
| shareInfo: resolvedShareOptions, | ||
| selectedShared: resolvedShareOptions | ||
| }); | ||
| return factory; | ||
| } | ||
| } else { | ||
| if (extraOptions?.customShareInfo) return false; | ||
| const _useTreeShaking = shouldUseTreeShaking(shareOptionsRes.treeShaking); | ||
| const targetShared = directShare(shareOptionsRes, _useTreeShaking); | ||
| const asyncLoadProcess = async () => { | ||
| const factory = await targetShared.get(); | ||
| targetShared.lib = factory; | ||
| targetShared.loaded = true; | ||
| addUseIn(targetShared, host.options.name); | ||
| const { shared: gShared, useTreesShaking: gUseTreeShaking } = getRegisteredShare(this.shareScopeMap, pkgName, shareOptionsRes, this.hooks.lifecycle.resolveShare) || {}; | ||
| if (gShared) { | ||
| const targetGShared = directShare(gShared, gUseTreeShaking); | ||
| targetGShared.lib = factory; | ||
| targetGShared.loaded = true; | ||
| gShared.from = shareOptionsRes.from; | ||
| } | ||
| return factory; | ||
| }; | ||
| const loading = asyncLoadProcess(); | ||
| this.setShared({ | ||
| } catch (shareError) { | ||
| this.emitErrorLoadShare({ | ||
| lifecycle: "loadShare", | ||
| pkgName, | ||
| loaded: false, | ||
| shared: shareOptionsRes, | ||
| from: host.options.name, | ||
| lib: null, | ||
| loading, | ||
| treeShaking: _useTreeShaking ? targetShared : void 0 | ||
| shareInfo: shareOptionsRes, | ||
| error: shareError | ||
| }); | ||
| return loading; | ||
| throw shareError; | ||
| } | ||
@@ -182,2 +262,3 @@ } | ||
| lifecycle: "beforeLoadShare", | ||
| remote: module.remoteInfo, | ||
| origin: host | ||
@@ -210,54 +291,88 @@ }); | ||
| }); | ||
| if (shareOptions?.scope) shareOptions.scope.forEach((shareScope) => { | ||
| this.initializeSharing(shareScope, { strategy: shareOptions.strategy }); | ||
| }); | ||
| const { shared: registeredShared, useTreesShaking } = getRegisteredShare(this.shareScopeMap, pkgName, shareOptions, this.hooks.lifecycle.resolveShare) || {}; | ||
| if (registeredShared) { | ||
| if (typeof registeredShared.lib === "function") { | ||
| addUseIn(registeredShared, host.options.name); | ||
| if (!registeredShared.loaded) { | ||
| registeredShared.loaded = true; | ||
| if (registeredShared.from === host.options.name) shareOptions.loaded = true; | ||
| } | ||
| return registeredShared.lib; | ||
| } | ||
| if (typeof registeredShared.get === "function") { | ||
| const module = registeredShared.get(); | ||
| if (!(module instanceof Promise)) { | ||
| try { | ||
| if (shareOptions?.scope) shareOptions.scope.forEach((shareScope) => { | ||
| this.initializeSharing(shareScope, { strategy: shareOptions.strategy }); | ||
| }); | ||
| const { shared: registeredShared } = getRegisteredShare(this.shareScopeMap, pkgName, shareOptions, this.hooks.lifecycle.resolveShare) || {}; | ||
| if (registeredShared) { | ||
| if (typeof registeredShared.lib === "function") { | ||
| addUseIn(registeredShared, host.options.name); | ||
| this.setShared({ | ||
| if (!registeredShared.loaded) { | ||
| registeredShared.loaded = true; | ||
| if (registeredShared.from === host.options.name) shareOptions.loaded = true; | ||
| } | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShareSync", | ||
| pkgName, | ||
| loaded: true, | ||
| from: host.options.name, | ||
| lib: module, | ||
| shared: registeredShared | ||
| shareInfo: shareOptions, | ||
| selectedShared: registeredShared | ||
| }); | ||
| return module; | ||
| return registeredShared.lib; | ||
| } | ||
| if (typeof registeredShared.get === "function") { | ||
| const module = registeredShared.get(); | ||
| if (!(module instanceof Promise)) { | ||
| addUseIn(registeredShared, host.options.name); | ||
| this.setShared({ | ||
| pkgName, | ||
| loaded: true, | ||
| from: host.options.name, | ||
| lib: module, | ||
| shared: registeredShared | ||
| }); | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShareSync", | ||
| pkgName, | ||
| shareInfo: shareOptions, | ||
| selectedShared: registeredShared | ||
| }); | ||
| return module; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| if (shareOptions.lib) { | ||
| if (!shareOptions.loaded) shareOptions.loaded = true; | ||
| return shareOptions.lib; | ||
| } | ||
| if (shareOptions.get) { | ||
| const module = shareOptions.get(); | ||
| if (module instanceof Promise) error(extraOptions?.from === "build" ? RUNTIME_005 : RUNTIME_006, runtimeDescMap, { | ||
| if (shareOptions.lib) { | ||
| if (!shareOptions.loaded) shareOptions.loaded = true; | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShareSync", | ||
| pkgName, | ||
| shareInfo: shareOptions, | ||
| selectedShared: shareOptions | ||
| }); | ||
| return shareOptions.lib; | ||
| } | ||
| if (shareOptions.get) { | ||
| const module = shareOptions.get(); | ||
| if (module instanceof Promise) error(extraOptions?.from === "build" ? RUNTIME_005 : RUNTIME_006, runtimeDescMap, { | ||
| hostName: host.options.name, | ||
| sharedPkgName: pkgName | ||
| }, void 0, optionsToMFContext(host.options)); | ||
| shareOptions.lib = module; | ||
| this.setShared({ | ||
| pkgName, | ||
| loaded: true, | ||
| from: host.options.name, | ||
| lib: shareOptions.lib, | ||
| shared: shareOptions | ||
| }); | ||
| this.emitAfterLoadShare({ | ||
| lifecycle: "loadShareSync", | ||
| pkgName, | ||
| shareInfo: shareOptions, | ||
| selectedShared: shareOptions | ||
| }); | ||
| return shareOptions.lib; | ||
| } | ||
| error(RUNTIME_006, runtimeDescMap, { | ||
| hostName: host.options.name, | ||
| sharedPkgName: pkgName | ||
| }, void 0, optionsToMFContext(host.options)); | ||
| shareOptions.lib = module; | ||
| this.setShared({ | ||
| } catch (shareError) { | ||
| this.emitErrorLoadShare({ | ||
| lifecycle: "loadShareSync", | ||
| pkgName, | ||
| loaded: true, | ||
| from: host.options.name, | ||
| lib: shareOptions.lib, | ||
| shared: shareOptions | ||
| shareInfo: shareOptions, | ||
| error: shareError | ||
| }); | ||
| return shareOptions.lib; | ||
| throw shareError; | ||
| } | ||
| error(RUNTIME_006, runtimeDescMap, { | ||
| hostName: host.options.name, | ||
| sharedPkgName: pkgName | ||
| }, void 0, optionsToMFContext(host.options)); | ||
| } | ||
@@ -264,0 +379,0 @@ initShareScopeMap(scopeName, shareScope, extraOptions = {}) { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","names":[],"sources":["../../src/shared/index.ts"],"sourcesContent":["import {\n RUNTIME_005,\n RUNTIME_006,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Federation } from '../global';\nimport {\n Options,\n ShareScopeMap,\n ShareInfos,\n Shared,\n RemoteEntryExports,\n UserOptions,\n ShareStrategy,\n InitScope,\n InitTokens,\n CallFrom,\n TreeShakingArgs,\n} from '../type';\nimport { ModuleFederation } from '../core';\nimport {\n PluginSystem,\n AsyncHook,\n AsyncWaterfallHook,\n SyncWaterfallHook,\n} from '../utils/hooks';\nimport {\n formatShareConfigs,\n getRegisteredShare,\n getTargetSharedOptions,\n getGlobalShareScope,\n directShare,\n shouldUseTreeShaking,\n addUseIn,\n} from '../utils/share';\nimport { assert, error, addUniqueItem, optionsToMFContext } from '../utils';\nimport { DEFAULT_SCOPE } from '../constant';\nimport { LoadRemoteMatch } from '../remote';\nimport { createRemoteEntryInitOptions } from '../module';\n\nexport class SharedHandler {\n host: ModuleFederation;\n shareScopeMap: ShareScopeMap;\n hooks = new PluginSystem({\n beforeRegisterShare: new SyncWaterfallHook<{\n pkgName: string;\n shared: Shared;\n origin: ModuleFederation;\n }>('beforeRegisterShare'),\n afterResolve: new AsyncWaterfallHook<LoadRemoteMatch>('afterResolve'),\n beforeLoadShare: new AsyncWaterfallHook<{\n pkgName: string;\n shareInfo?: Shared;\n shared: Options['shared'];\n origin: ModuleFederation;\n }>('beforeLoadShare'),\n // not used yet\n loadShare: new AsyncHook<[ModuleFederation, string, ShareInfos]>(),\n resolveShare: new SyncWaterfallHook<{\n shareScopeMap: ShareScopeMap;\n scope: string;\n pkgName: string;\n version: string;\n shareInfo: Shared;\n GlobalFederation: Federation;\n resolver: () => { shared: Shared; useTreesShaking: boolean } | undefined;\n }>('resolveShare'),\n // maybe will change, temporarily for internal use only\n initContainerShareScopeMap: new SyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n options: Options;\n origin: ModuleFederation;\n scopeName: string;\n hostShareScopeMap?: ShareScopeMap;\n }>('initContainerShareScopeMap'),\n });\n initTokens: InitTokens;\n constructor(host: ModuleFederation) {\n this.host = host;\n this.shareScopeMap = {};\n this.initTokens = {};\n this._setGlobalShareScopeMap(host.options);\n }\n\n // register shared in shareScopeMap\n registerShared(globalOptions: Options, userOptions: UserOptions) {\n const { newShareInfos, allShareInfos } = formatShareConfigs(\n globalOptions,\n userOptions,\n );\n\n const sharedKeys = Object.keys(newShareInfos);\n sharedKeys.forEach((sharedKey) => {\n const sharedVals = newShareInfos[sharedKey];\n sharedVals.forEach((sharedVal) => {\n sharedVal.scope.forEach((sc) => {\n this.hooks.lifecycle.beforeRegisterShare.emit({\n origin: this.host,\n pkgName: sharedKey,\n shared: sharedVal,\n });\n const registeredShared = this.shareScopeMap[sc]?.[sharedKey];\n if (!registeredShared) {\n this.setShared({\n pkgName: sharedKey,\n lib: sharedVal.lib,\n get: sharedVal.get,\n loaded: sharedVal.loaded || Boolean(sharedVal.lib),\n shared: sharedVal,\n from: userOptions.name,\n });\n }\n });\n });\n });\n\n return {\n newShareInfos,\n allShareInfos,\n };\n }\n\n async loadShare<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): Promise<false | (() => T | undefined)> {\n const { host } = this;\n // This function performs the following steps:\n // 1. Checks if the currently loaded share already exists, if not, it throws an error\n // 2. Searches globally for a matching share, if found, it uses it directly\n // 3. If not found, it retrieves it from the current share and stores the obtained share globally.\n\n const shareOptions = getTargetSharedOptions({\n pkgName,\n extraOptions,\n shareInfos: host.options.shared,\n });\n\n if (shareOptions?.scope) {\n await Promise.all(\n shareOptions.scope.map(async (shareScope) => {\n await Promise.all(\n this.initializeSharing(shareScope, {\n strategy: shareOptions.strategy,\n }),\n );\n return;\n }),\n );\n }\n const loadShareRes = await this.hooks.lifecycle.beforeLoadShare.emit({\n pkgName,\n shareInfo: shareOptions,\n shared: host.options.shared,\n origin: host,\n });\n\n const { shareInfo: shareOptionsRes } = loadShareRes;\n\n // Assert that shareInfoRes exists, if not, throw an error\n assert(\n shareOptionsRes,\n `Cannot find shared \"${pkgName}\" in host \"${host.options.name}\". Ensure the shared config for \"${pkgName}\" is declared in the federation plugin options and the host has been initialized before loading shares.`,\n );\n\n const { shared: registeredShared, useTreesShaking } =\n getRegisteredShare(\n this.shareScopeMap,\n pkgName,\n shareOptionsRes,\n this.hooks.lifecycle.resolveShare,\n ) || {};\n\n if (registeredShared) {\n const targetShared = directShare(registeredShared, useTreesShaking);\n if (targetShared.lib) {\n addUseIn(targetShared, host.options.name);\n return targetShared.lib as () => T;\n } else if (targetShared.loading && !targetShared.loaded) {\n const factory = await targetShared.loading;\n targetShared.loaded = true;\n if (!targetShared.lib) {\n targetShared.lib = factory;\n }\n addUseIn(targetShared, host.options.name);\n return factory;\n } else {\n const asyncLoadProcess = async () => {\n const factory = await targetShared.get!();\n addUseIn(targetShared, host.options.name);\n targetShared.loaded = true;\n targetShared.lib = factory;\n return factory as () => T;\n };\n const loading = asyncLoadProcess();\n this.setShared({\n pkgName,\n loaded: false,\n shared: registeredShared,\n from: host.options.name,\n lib: null,\n loading,\n treeShaking: useTreesShaking\n ? (targetShared as TreeShakingArgs)\n : undefined,\n });\n return loading;\n }\n } else {\n if (extraOptions?.customShareInfo) {\n return false;\n }\n const _useTreeShaking = shouldUseTreeShaking(shareOptionsRes.treeShaking);\n const targetShared = directShare(shareOptionsRes, _useTreeShaking);\n\n const asyncLoadProcess = async () => {\n const factory = await targetShared.get!();\n targetShared.lib = factory;\n targetShared.loaded = true;\n addUseIn(targetShared, host.options.name);\n const { shared: gShared, useTreesShaking: gUseTreeShaking } =\n getRegisteredShare(\n this.shareScopeMap,\n pkgName,\n shareOptionsRes,\n this.hooks.lifecycle.resolveShare,\n ) || {};\n if (gShared) {\n const targetGShared = directShare(gShared, gUseTreeShaking);\n targetGShared.lib = factory;\n targetGShared.loaded = true;\n gShared.from = shareOptionsRes.from;\n }\n return factory as () => T;\n };\n const loading = asyncLoadProcess();\n this.setShared({\n pkgName,\n loaded: false,\n shared: shareOptionsRes,\n from: host.options.name,\n lib: null,\n loading,\n treeShaking: _useTreeShaking\n ? (targetShared as TreeShakingArgs)\n : undefined,\n });\n return loading;\n }\n }\n\n /**\n * This function initializes the sharing sequence (executed only once per share scope).\n * It accepts one argument, the name of the share scope.\n * If the share scope does not exist, it creates one.\n */\n // eslint-disable-next-line @typescript-eslint/member-ordering\n initializeSharing(\n shareScopeName = DEFAULT_SCOPE,\n extraOptions?: {\n initScope?: InitScope;\n from?: CallFrom;\n strategy?: ShareStrategy;\n },\n ): Array<Promise<void>> {\n const { host } = this;\n const from = extraOptions?.from;\n const strategy = extraOptions?.strategy;\n let initScope = extraOptions?.initScope;\n const promises: Promise<any>[] = [];\n if (from !== 'build') {\n const { initTokens } = this;\n if (!initScope) initScope = [];\n let initToken = initTokens[shareScopeName];\n if (!initToken)\n initToken = initTokens[shareScopeName] = { from: this.host.name };\n if (initScope.indexOf(initToken) >= 0) return promises;\n initScope.push(initToken);\n }\n\n const shareScope = this.shareScopeMap;\n const hostName = host.options.name;\n // Creates a new share scope if necessary\n if (!shareScope[shareScopeName]) {\n shareScope[shareScopeName] = {};\n }\n // Executes all initialization snippets from all accessible modules\n const scope = shareScope[shareScopeName];\n const register = (name: string, shared: Shared) => {\n const { version, eager } = shared;\n scope[name] = scope[name] || {};\n const versions = scope[name];\n const activeVersion: Shared =\n versions[version] && (directShare(versions[version]) as Shared);\n const activeVersionEager = Boolean(\n activeVersion &&\n (('eager' in activeVersion && activeVersion.eager) ||\n ('shareConfig' in activeVersion && activeVersion.shareConfig?.eager)),\n );\n if (\n !activeVersion ||\n (activeVersion.strategy !== 'loaded-first' &&\n !activeVersion.loaded &&\n (Boolean(!eager) !== !activeVersionEager\n ? eager\n : hostName > versions[version].from))\n ) {\n versions[version] = shared;\n }\n };\n\n const initRemoteModule = async (key: string): Promise<void> => {\n const { module } = await host.remoteHandler.getRemoteModuleAndOptions({\n id: key,\n });\n let remoteEntryExports: RemoteEntryExports | undefined = undefined;\n try {\n remoteEntryExports = await module.getEntry();\n } catch (error) {\n remoteEntryExports =\n (await host.remoteHandler.hooks.lifecycle.errorLoadRemote.emit({\n id: key,\n error,\n from: 'runtime',\n lifecycle: 'beforeLoadShare',\n origin: host,\n })) as RemoteEntryExports;\n if (!remoteEntryExports) {\n return;\n }\n } finally {\n // prevent self load loop: when host load self , the initTokens is not the same\n if (remoteEntryExports?.init && !module.initing) {\n module.remoteEntryExports = remoteEntryExports;\n await module.init(undefined, undefined, initScope);\n }\n }\n };\n Object.keys(host.options.shared).forEach((shareName) => {\n const sharedArr = host.options.shared[shareName];\n sharedArr.forEach((shared) => {\n if (shared.scope.includes(shareScopeName)) {\n register(shareName, shared);\n }\n });\n });\n // TODO: strategy==='version-first' need to be removed in the future\n if (\n host.options.shareStrategy === 'version-first' ||\n strategy === 'version-first'\n ) {\n host.options.remotes.forEach((remote) => {\n if (remote.shareScope === shareScopeName) {\n promises.push(initRemoteModule(remote.name));\n }\n });\n }\n\n return promises;\n }\n\n // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.\n // 1. If the loaded shared already exists globally, then it will be reused\n // 2. If lib exists in local shared, it will be used directly\n // 3. If the local get returns something other than Promise, then it will be used directly\n loadShareSync<T>(\n pkgName: string,\n extraOptions?: {\n from?: 'build' | 'runtime';\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): () => T | never {\n const { host } = this;\n const shareOptions = getTargetSharedOptions({\n pkgName,\n extraOptions,\n shareInfos: host.options.shared,\n });\n\n if (shareOptions?.scope) {\n shareOptions.scope.forEach((shareScope) => {\n this.initializeSharing(shareScope, { strategy: shareOptions.strategy });\n });\n }\n const { shared: registeredShared, useTreesShaking } =\n getRegisteredShare(\n this.shareScopeMap,\n pkgName,\n shareOptions,\n this.hooks.lifecycle.resolveShare,\n ) || {};\n\n if (registeredShared) {\n if (typeof registeredShared.lib === 'function') {\n addUseIn(registeredShared, host.options.name);\n if (!registeredShared.loaded) {\n registeredShared.loaded = true;\n if (registeredShared.from === host.options.name) {\n shareOptions.loaded = true;\n }\n }\n return registeredShared.lib as () => T;\n }\n if (typeof registeredShared.get === 'function') {\n const module = registeredShared.get();\n if (!(module instanceof Promise)) {\n addUseIn(registeredShared, host.options.name);\n this.setShared({\n pkgName,\n loaded: true,\n from: host.options.name,\n lib: module,\n shared: registeredShared,\n });\n return module;\n }\n }\n }\n\n if (shareOptions.lib) {\n if (!shareOptions.loaded) {\n shareOptions.loaded = true;\n }\n return shareOptions.lib as () => T;\n }\n\n if (shareOptions.get) {\n const module = shareOptions.get();\n\n if (module instanceof Promise) {\n const errorCode =\n extraOptions?.from === 'build' ? RUNTIME_005 : RUNTIME_006;\n error(\n errorCode,\n runtimeDescMap,\n {\n hostName: host.options.name,\n sharedPkgName: pkgName,\n },\n undefined,\n optionsToMFContext(host.options),\n );\n }\n\n shareOptions.lib = module;\n\n this.setShared({\n pkgName,\n loaded: true,\n from: host.options.name,\n lib: shareOptions.lib,\n shared: shareOptions,\n });\n return shareOptions.lib as () => T;\n }\n\n error(\n RUNTIME_006,\n runtimeDescMap,\n {\n hostName: host.options.name,\n sharedPkgName: pkgName,\n },\n undefined,\n optionsToMFContext(host.options),\n );\n }\n\n initShareScopeMap(\n scopeName: string,\n shareScope: ShareScopeMap[string],\n extraOptions: { hostShareScopeMap?: ShareScopeMap } = {},\n ): void {\n const { host } = this;\n this.shareScopeMap[scopeName] = shareScope;\n this.hooks.lifecycle.initContainerShareScopeMap.emit({\n shareScope,\n options: host.options,\n origin: host,\n scopeName,\n hostShareScopeMap: extraOptions.hostShareScopeMap,\n });\n }\n\n private setShared({\n pkgName,\n shared,\n from,\n lib,\n loading,\n loaded,\n get,\n treeShaking,\n }: {\n pkgName: string;\n shared: Shared;\n from: string;\n lib: any;\n loaded?: boolean;\n loading?: Shared['loading'];\n get?: Shared['get'];\n treeShaking?: TreeShakingArgs;\n }): void {\n const { version, scope = 'default', ...shareInfo } = shared;\n const scopes: string[] = Array.isArray(scope) ? scope : [scope];\n\n const mergeAttrs = (shared: Shared) => {\n const merge = <K extends keyof TreeShakingArgs>(\n s: TreeShakingArgs,\n key: K,\n val: TreeShakingArgs[K],\n ): void => {\n if (val && !s[key]) {\n s[key] = val;\n }\n };\n const targetShared = (\n treeShaking ? shared.treeShaking! : shared\n ) as TreeShakingArgs;\n merge(targetShared, 'loaded', loaded);\n merge(targetShared, 'loading', loading);\n merge(targetShared, 'get', get);\n };\n scopes.forEach((sc) => {\n if (!this.shareScopeMap[sc]) {\n this.shareScopeMap[sc] = {};\n }\n if (!this.shareScopeMap[sc][pkgName]) {\n this.shareScopeMap[sc][pkgName] = {};\n }\n\n if (!this.shareScopeMap[sc][pkgName][version]) {\n this.shareScopeMap[sc][pkgName][version] = {\n version,\n scope: [sc],\n ...shareInfo,\n lib,\n };\n }\n\n const registeredShared = this.shareScopeMap[sc][pkgName][version];\n mergeAttrs(registeredShared);\n if (from && registeredShared.from !== from) {\n registeredShared.from = from;\n }\n });\n }\n\n private _setGlobalShareScopeMap(hostOptions: Options): void {\n const globalShareScopeMap = getGlobalShareScope();\n const identifier = hostOptions.id || hostOptions.name;\n if (identifier && !globalShareScopeMap[identifier]) {\n globalShareScopeMap[identifier] = this.shareScopeMap;\n }\n }\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"index.js","names":[],"sources":["../../src/shared/index.ts"],"sourcesContent":["import {\n RUNTIME_005,\n RUNTIME_006,\n runtimeDescMap,\n} from '@module-federation/error-codes';\nimport { Federation } from '../global';\nimport {\n Options,\n ShareScopeMap,\n ShareInfos,\n Shared,\n RemoteEntryExports,\n UserOptions,\n ShareStrategy,\n InitScope,\n InitTokens,\n CallFrom,\n TreeShakingArgs,\n} from '../type';\nimport { ModuleFederation } from '../core';\nimport {\n PluginSystem,\n AsyncHook,\n AsyncWaterfallHook,\n SyncWaterfallHook,\n SyncHook,\n} from '../utils/hooks';\nimport {\n formatShareConfigs,\n getRegisteredShare,\n getTargetSharedOptions,\n getGlobalShareScope,\n directShare,\n shouldUseTreeShaking,\n addUseIn,\n} from '../utils/share';\nimport {\n assert,\n error,\n addUniqueItem,\n optionsToMFContext,\n warn,\n} from '../utils';\nimport { DEFAULT_SCOPE } from '../constant';\nimport { LoadRemoteMatch } from '../remote';\nimport { createRemoteEntryInitOptions } from '../module';\n\nexport class SharedHandler {\n host: ModuleFederation;\n shareScopeMap: ShareScopeMap;\n hooks = new PluginSystem({\n beforeRegisterShare: new SyncWaterfallHook<{\n pkgName: string;\n shared: Shared;\n origin: ModuleFederation;\n }>('beforeRegisterShare'),\n afterResolve: new AsyncWaterfallHook<LoadRemoteMatch>('afterResolve'),\n beforeLoadShare: new AsyncWaterfallHook<{\n pkgName: string;\n shareInfo?: Shared;\n shared: Options['shared'];\n origin: ModuleFederation;\n }>('beforeLoadShare'),\n // not used yet\n loadShare: new AsyncHook<[ModuleFederation, string, ShareInfos]>(),\n afterLoadShare: new SyncHook<\n [\n {\n pkgName: string;\n shareInfo?: Partial<Shared>;\n selectedShared?: Partial<Shared>;\n shared: Options['shared'];\n shareScopeMap: ShareScopeMap;\n lifecycle: 'loadShare' | 'loadShareSync';\n origin: ModuleFederation;\n },\n ],\n void\n >('afterLoadShare'),\n errorLoadShare: new SyncHook<\n [\n {\n pkgName: string;\n shareInfo?: Partial<Shared>;\n shared: Options['shared'];\n shareScopeMap: ShareScopeMap;\n lifecycle: 'loadShare' | 'loadShareSync';\n origin: ModuleFederation;\n error?: unknown;\n recovered?: boolean;\n },\n ],\n void\n >('errorLoadShare'),\n resolveShare: new SyncWaterfallHook<{\n shareScopeMap: ShareScopeMap;\n scope: string;\n pkgName: string;\n version: string;\n shareInfo: Shared;\n GlobalFederation: Federation;\n resolver: () => { shared: Shared; useTreesShaking: boolean } | undefined;\n }>('resolveShare'),\n // maybe will change, temporarily for internal use only\n initContainerShareScopeMap: new SyncWaterfallHook<{\n shareScope: ShareScopeMap[string];\n options: Options;\n origin: ModuleFederation;\n scopeName: string;\n hostShareScopeMap?: ShareScopeMap;\n }>('initContainerShareScopeMap'),\n });\n initTokens: InitTokens;\n constructor(host: ModuleFederation) {\n this.host = host;\n this.shareScopeMap = {};\n this.initTokens = {};\n this._setGlobalShareScopeMap(host.options);\n }\n\n private emitAfterLoadShare({\n lifecycle,\n pkgName,\n shareInfo,\n selectedShared,\n }: {\n lifecycle: 'loadShare' | 'loadShareSync';\n pkgName: string;\n shareInfo?: Partial<Shared>;\n selectedShared?: Partial<Shared>;\n }): void {\n try {\n this.hooks.lifecycle.afterLoadShare.emit({\n pkgName,\n shareInfo,\n selectedShared,\n shared: this.host.options.shared,\n shareScopeMap: this.shareScopeMap,\n lifecycle,\n origin: this.host,\n });\n } catch (error) {\n warn(error);\n }\n }\n\n private emitErrorLoadShare({\n lifecycle,\n pkgName,\n shareInfo,\n error,\n recovered,\n }: {\n lifecycle: 'loadShare' | 'loadShareSync';\n pkgName: string;\n shareInfo?: Partial<Shared>;\n error?: unknown;\n recovered?: boolean;\n }): void {\n try {\n this.hooks.lifecycle.errorLoadShare.emit({\n pkgName,\n shareInfo,\n shared: this.host.options.shared,\n shareScopeMap: this.shareScopeMap,\n lifecycle,\n origin: this.host,\n error,\n recovered,\n });\n } catch (hookError) {\n warn(hookError);\n }\n }\n\n // register shared in shareScopeMap\n registerShared(globalOptions: Options, userOptions: UserOptions) {\n const { newShareInfos, allShareInfos } = formatShareConfigs(\n globalOptions,\n userOptions,\n );\n\n const sharedKeys = Object.keys(newShareInfos);\n sharedKeys.forEach((sharedKey) => {\n const sharedVals = newShareInfos[sharedKey];\n sharedVals.forEach((sharedVal) => {\n sharedVal.scope.forEach((sc) => {\n this.hooks.lifecycle.beforeRegisterShare.emit({\n origin: this.host,\n pkgName: sharedKey,\n shared: sharedVal,\n });\n const registeredShared = this.shareScopeMap[sc]?.[sharedKey];\n if (!registeredShared) {\n this.setShared({\n pkgName: sharedKey,\n lib: sharedVal.lib,\n get: sharedVal.get,\n loaded: sharedVal.loaded || Boolean(sharedVal.lib),\n shared: sharedVal,\n from: userOptions.name,\n });\n }\n });\n });\n });\n\n return {\n newShareInfos,\n allShareInfos,\n };\n }\n\n async loadShare<T>(\n pkgName: string,\n extraOptions?: {\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): Promise<false | (() => T | undefined)> {\n const { host } = this;\n // This function performs the following steps:\n // 1. Checks if the currently loaded share already exists, if not, it throws an error\n // 2. Searches globally for a matching share, if found, it uses it directly\n // 3. If not found, it retrieves it from the current share and stores the obtained share globally.\n\n const shareOptions = getTargetSharedOptions({\n pkgName,\n extraOptions,\n shareInfos: host.options.shared,\n });\n let shareOptionsRes: Shared | undefined = shareOptions;\n\n try {\n if (shareOptions?.scope) {\n await Promise.all(\n shareOptions.scope.map(async (shareScope) => {\n await Promise.all(\n this.initializeSharing(shareScope, {\n strategy: shareOptions.strategy,\n }),\n );\n return;\n }),\n );\n }\n const loadShareRes = await this.hooks.lifecycle.beforeLoadShare.emit({\n pkgName,\n shareInfo: shareOptions,\n shared: host.options.shared,\n origin: host,\n });\n\n shareOptionsRes = loadShareRes.shareInfo;\n\n // Assert that shareInfoRes exists, if not, throw an error\n assert(\n shareOptionsRes,\n `Cannot find shared \"${pkgName}\" in host \"${host.options.name}\". Ensure the shared config for \"${pkgName}\" is declared in the federation plugin options and the host has been initialized before loading shares.`,\n );\n const resolvedShareOptions = shareOptionsRes;\n\n const { shared: registeredShared, useTreesShaking } =\n getRegisteredShare(\n this.shareScopeMap,\n pkgName,\n shareOptionsRes,\n this.hooks.lifecycle.resolveShare,\n ) || {};\n\n if (registeredShared) {\n const targetShared = directShare(registeredShared, useTreesShaking);\n if (targetShared.lib) {\n addUseIn(targetShared, host.options.name);\n this.emitAfterLoadShare({\n lifecycle: 'loadShare',\n pkgName,\n shareInfo: resolvedShareOptions,\n selectedShared: registeredShared,\n });\n return targetShared.lib as () => T;\n } else if (targetShared.loading && !targetShared.loaded) {\n const factory = await targetShared.loading;\n targetShared.loaded = true;\n if (!targetShared.lib) {\n targetShared.lib = factory;\n }\n addUseIn(targetShared, host.options.name);\n this.emitAfterLoadShare({\n lifecycle: 'loadShare',\n pkgName,\n shareInfo: resolvedShareOptions,\n selectedShared: registeredShared,\n });\n return factory;\n } else {\n const asyncLoadProcess = async () => {\n const factory = await targetShared.get!();\n addUseIn(targetShared, host.options.name);\n targetShared.loaded = true;\n targetShared.lib = factory;\n return factory as () => T;\n };\n const loading = asyncLoadProcess();\n this.setShared({\n pkgName,\n loaded: false,\n shared: registeredShared,\n from: host.options.name,\n lib: null,\n loading,\n treeShaking: useTreesShaking\n ? (targetShared as TreeShakingArgs)\n : undefined,\n });\n const factory = await loading;\n this.emitAfterLoadShare({\n lifecycle: 'loadShare',\n pkgName,\n shareInfo: resolvedShareOptions,\n selectedShared: registeredShared,\n });\n return factory;\n }\n } else {\n if (extraOptions?.customShareInfo) {\n this.emitErrorLoadShare({\n lifecycle: 'loadShare',\n pkgName,\n shareInfo: resolvedShareOptions,\n recovered: true,\n });\n return false;\n }\n const _useTreeShaking = shouldUseTreeShaking(\n resolvedShareOptions.treeShaking,\n );\n const targetShared = directShare(resolvedShareOptions, _useTreeShaking);\n\n const asyncLoadProcess = async () => {\n const factory = await targetShared.get!();\n targetShared.lib = factory;\n targetShared.loaded = true;\n addUseIn(targetShared, host.options.name);\n const { shared: gShared, useTreesShaking: gUseTreeShaking } =\n getRegisteredShare(\n this.shareScopeMap,\n pkgName,\n resolvedShareOptions,\n this.hooks.lifecycle.resolveShare,\n ) || {};\n if (gShared) {\n const targetGShared = directShare(gShared, gUseTreeShaking);\n targetGShared.lib = factory;\n targetGShared.loaded = true;\n gShared.from = resolvedShareOptions.from;\n }\n return factory as () => T;\n };\n const loading = asyncLoadProcess();\n this.setShared({\n pkgName,\n loaded: false,\n shared: resolvedShareOptions,\n from: host.options.name,\n lib: null,\n loading,\n treeShaking: _useTreeShaking\n ? (targetShared as TreeShakingArgs)\n : undefined,\n });\n const factory = await loading;\n this.emitAfterLoadShare({\n lifecycle: 'loadShare',\n pkgName,\n shareInfo: resolvedShareOptions,\n selectedShared: resolvedShareOptions,\n });\n return factory;\n }\n } catch (shareError) {\n this.emitErrorLoadShare({\n lifecycle: 'loadShare',\n pkgName,\n shareInfo: shareOptionsRes,\n error: shareError,\n });\n throw shareError;\n }\n }\n\n /**\n * This function initializes the sharing sequence (executed only once per share scope).\n * It accepts one argument, the name of the share scope.\n * If the share scope does not exist, it creates one.\n */\n // eslint-disable-next-line @typescript-eslint/member-ordering\n initializeSharing(\n shareScopeName = DEFAULT_SCOPE,\n extraOptions?: {\n initScope?: InitScope;\n from?: CallFrom;\n strategy?: ShareStrategy;\n },\n ): Array<Promise<void>> {\n const { host } = this;\n const from = extraOptions?.from;\n const strategy = extraOptions?.strategy;\n let initScope = extraOptions?.initScope;\n const promises: Promise<any>[] = [];\n if (from !== 'build') {\n const { initTokens } = this;\n if (!initScope) initScope = [];\n let initToken = initTokens[shareScopeName];\n if (!initToken)\n initToken = initTokens[shareScopeName] = { from: this.host.name };\n if (initScope.indexOf(initToken) >= 0) return promises;\n initScope.push(initToken);\n }\n\n const shareScope = this.shareScopeMap;\n const hostName = host.options.name;\n // Creates a new share scope if necessary\n if (!shareScope[shareScopeName]) {\n shareScope[shareScopeName] = {};\n }\n // Executes all initialization snippets from all accessible modules\n const scope = shareScope[shareScopeName];\n const register = (name: string, shared: Shared) => {\n const { version, eager } = shared;\n scope[name] = scope[name] || {};\n const versions = scope[name];\n const activeVersion: Shared =\n versions[version] && (directShare(versions[version]) as Shared);\n const activeVersionEager = Boolean(\n activeVersion &&\n (('eager' in activeVersion && activeVersion.eager) ||\n ('shareConfig' in activeVersion && activeVersion.shareConfig?.eager)),\n );\n if (\n !activeVersion ||\n (activeVersion.strategy !== 'loaded-first' &&\n !activeVersion.loaded &&\n (Boolean(!eager) !== !activeVersionEager\n ? eager\n : hostName > versions[version].from))\n ) {\n versions[version] = shared;\n }\n };\n\n const initRemoteModule = async (key: string): Promise<void> => {\n const { module } = await host.remoteHandler.getRemoteModuleAndOptions({\n id: key,\n });\n let remoteEntryExports: RemoteEntryExports | undefined = undefined;\n try {\n remoteEntryExports = await module.getEntry();\n } catch (error) {\n remoteEntryExports =\n (await host.remoteHandler.hooks.lifecycle.errorLoadRemote.emit({\n id: key,\n error,\n from: 'runtime',\n lifecycle: 'beforeLoadShare',\n remote: module.remoteInfo,\n origin: host,\n })) as RemoteEntryExports;\n if (!remoteEntryExports) {\n return;\n }\n } finally {\n // prevent self load loop: when host load self , the initTokens is not the same\n if (remoteEntryExports?.init && !module.initing) {\n module.remoteEntryExports = remoteEntryExports;\n await module.init(undefined, undefined, initScope);\n }\n }\n };\n Object.keys(host.options.shared).forEach((shareName) => {\n const sharedArr = host.options.shared[shareName];\n sharedArr.forEach((shared) => {\n if (shared.scope.includes(shareScopeName)) {\n register(shareName, shared);\n }\n });\n });\n // TODO: strategy==='version-first' need to be removed in the future\n if (\n host.options.shareStrategy === 'version-first' ||\n strategy === 'version-first'\n ) {\n host.options.remotes.forEach((remote) => {\n if (remote.shareScope === shareScopeName) {\n promises.push(initRemoteModule(remote.name));\n }\n });\n }\n\n return promises;\n }\n\n // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.\n // 1. If the loaded shared already exists globally, then it will be reused\n // 2. If lib exists in local shared, it will be used directly\n // 3. If the local get returns something other than Promise, then it will be used directly\n loadShareSync<T>(\n pkgName: string,\n extraOptions?: {\n from?: 'build' | 'runtime';\n customShareInfo?: Partial<Shared>;\n resolver?: (sharedOptions: ShareInfos[string]) => Shared;\n },\n ): () => T | never {\n const { host } = this;\n const shareOptions = getTargetSharedOptions({\n pkgName,\n extraOptions,\n shareInfos: host.options.shared,\n });\n\n try {\n if (shareOptions?.scope) {\n shareOptions.scope.forEach((shareScope) => {\n this.initializeSharing(shareScope, {\n strategy: shareOptions.strategy,\n });\n });\n }\n const { shared: registeredShared } =\n getRegisteredShare(\n this.shareScopeMap,\n pkgName,\n shareOptions,\n this.hooks.lifecycle.resolveShare,\n ) || {};\n\n if (registeredShared) {\n if (typeof registeredShared.lib === 'function') {\n addUseIn(registeredShared, host.options.name);\n if (!registeredShared.loaded) {\n registeredShared.loaded = true;\n if (registeredShared.from === host.options.name) {\n shareOptions.loaded = true;\n }\n }\n this.emitAfterLoadShare({\n lifecycle: 'loadShareSync',\n pkgName,\n shareInfo: shareOptions,\n selectedShared: registeredShared,\n });\n return registeredShared.lib as () => T;\n }\n if (typeof registeredShared.get === 'function') {\n const module = registeredShared.get();\n if (!(module instanceof Promise)) {\n addUseIn(registeredShared, host.options.name);\n this.setShared({\n pkgName,\n loaded: true,\n from: host.options.name,\n lib: module,\n shared: registeredShared,\n });\n this.emitAfterLoadShare({\n lifecycle: 'loadShareSync',\n pkgName,\n shareInfo: shareOptions,\n selectedShared: registeredShared,\n });\n return module;\n }\n }\n }\n\n if (shareOptions.lib) {\n if (!shareOptions.loaded) {\n shareOptions.loaded = true;\n }\n this.emitAfterLoadShare({\n lifecycle: 'loadShareSync',\n pkgName,\n shareInfo: shareOptions,\n selectedShared: shareOptions,\n });\n return shareOptions.lib as () => T;\n }\n\n if (shareOptions.get) {\n const module = shareOptions.get();\n\n if (module instanceof Promise) {\n const errorCode =\n extraOptions?.from === 'build' ? RUNTIME_005 : RUNTIME_006;\n error(\n errorCode,\n runtimeDescMap,\n {\n hostName: host.options.name,\n sharedPkgName: pkgName,\n },\n undefined,\n optionsToMFContext(host.options),\n );\n }\n\n shareOptions.lib = module;\n\n this.setShared({\n pkgName,\n loaded: true,\n from: host.options.name,\n lib: shareOptions.lib,\n shared: shareOptions,\n });\n this.emitAfterLoadShare({\n lifecycle: 'loadShareSync',\n pkgName,\n shareInfo: shareOptions,\n selectedShared: shareOptions,\n });\n return shareOptions.lib as () => T;\n }\n\n error(\n RUNTIME_006,\n runtimeDescMap,\n {\n hostName: host.options.name,\n sharedPkgName: pkgName,\n },\n undefined,\n optionsToMFContext(host.options),\n );\n } catch (shareError) {\n this.emitErrorLoadShare({\n lifecycle: 'loadShareSync',\n pkgName,\n shareInfo: shareOptions,\n error: shareError,\n });\n throw shareError;\n }\n }\n\n initShareScopeMap(\n scopeName: string,\n shareScope: ShareScopeMap[string],\n extraOptions: { hostShareScopeMap?: ShareScopeMap } = {},\n ): void {\n const { host } = this;\n this.shareScopeMap[scopeName] = shareScope;\n this.hooks.lifecycle.initContainerShareScopeMap.emit({\n shareScope,\n options: host.options,\n origin: host,\n scopeName,\n hostShareScopeMap: extraOptions.hostShareScopeMap,\n });\n }\n\n private setShared({\n pkgName,\n shared,\n from,\n lib,\n loading,\n loaded,\n get,\n treeShaking,\n }: {\n pkgName: string;\n shared: Shared;\n from: string;\n lib: any;\n loaded?: boolean;\n loading?: Shared['loading'];\n get?: Shared['get'];\n treeShaking?: TreeShakingArgs;\n }): void {\n const { version, scope = 'default', ...shareInfo } = shared;\n const scopes: string[] = Array.isArray(scope) ? scope : [scope];\n\n const mergeAttrs = (shared: Shared) => {\n const merge = <K extends keyof TreeShakingArgs>(\n s: TreeShakingArgs,\n key: K,\n val: TreeShakingArgs[K],\n ): void => {\n if (val && !s[key]) {\n s[key] = val;\n }\n };\n const targetShared = (\n treeShaking ? shared.treeShaking! : shared\n ) as TreeShakingArgs;\n merge(targetShared, 'loaded', loaded);\n merge(targetShared, 'loading', loading);\n merge(targetShared, 'get', get);\n };\n scopes.forEach((sc) => {\n if (!this.shareScopeMap[sc]) {\n this.shareScopeMap[sc] = {};\n }\n if (!this.shareScopeMap[sc][pkgName]) {\n this.shareScopeMap[sc][pkgName] = {};\n }\n\n if (!this.shareScopeMap[sc][pkgName][version]) {\n this.shareScopeMap[sc][pkgName][version] = {\n version,\n scope: [sc],\n ...shareInfo,\n lib,\n };\n }\n\n const registeredShared = this.shareScopeMap[sc][pkgName][version];\n mergeAttrs(registeredShared);\n if (from && registeredShared.from !== from) {\n registeredShared.from = from;\n }\n });\n }\n\n private _setGlobalShareScopeMap(hostOptions: Options): void {\n const globalShareScopeMap = getGlobalShareScope();\n const identifier = hostOptions.id || hostOptions.name;\n if (identifier && !globalShareScopeMap[identifier]) {\n globalShareScopeMap[identifier] = this.shareScopeMap;\n }\n }\n}\n"],"mappings":"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"} |
| import { ModuleFederationRuntimePlugin } from "./plugin.js"; | ||
| import { CallFrom, GlobalShareScopeMap, HostInfo, InitScope, InitTokens, LoadModuleOptions, LoadShareExtraOptions, NoMatchedUsedExportsItem, Optional, Options, PartialOptional, Remote, RemoteEntryExports, RemoteEntryInitOptions, RemoteInfo, RemoteInfoCommon, RemoteInfoOptionalVersion, ShareArgs, ShareInfos, ShareScopeMap, ShareStrategy, Shared, SharedConfig, SharedGetter, TreeShakingArgs, UserOptions } from "./config.js"; | ||
| import { EntryAssets, PreloadAssets, PreloadConfig, PreloadOptions, PreloadRemoteArgs, depsPreloadArg } from "./preload.js"; | ||
| import { EntryAssets, PreloadAssetResult, PreloadAssetStatus, PreloadAssets, PreloadConfig, PreloadOptions, PreloadRemoteArgs, PreloadRemoteResult, ResourceLoadContext, ResourceLoadInitiator, ResourceLoadType, depsPreloadArg } from "./preload.js"; | ||
| //#region src/type/index.d.ts | ||
| declare namespace index_d_exports { | ||
| export { CallFrom, EntryAssets, GlobalShareScopeMap, HostInfo, InitScope, InitTokens, LoadModuleOptions, LoadShareExtraOptions, ModuleFederationRuntimePlugin, NoMatchedUsedExportsItem, Optional, Options, PartialOptional, PreloadAssets, PreloadConfig, PreloadOptions, PreloadRemoteArgs, Remote, RemoteEntryExports, RemoteEntryInitOptions, RemoteInfo, RemoteInfoCommon, RemoteInfoOptionalVersion, ShareArgs, ShareInfos, ShareScopeMap, ShareStrategy, Shared, SharedConfig, SharedGetter, TreeShakingArgs, UserOptions, depsPreloadArg }; | ||
| export { CallFrom, EntryAssets, GlobalShareScopeMap, HostInfo, InitScope, InitTokens, LoadModuleOptions, LoadShareExtraOptions, ModuleFederationRuntimePlugin, NoMatchedUsedExportsItem, Optional, Options, PartialOptional, PreloadAssetResult, PreloadAssetStatus, PreloadAssets, PreloadConfig, PreloadOptions, PreloadRemoteArgs, PreloadRemoteResult, Remote, RemoteEntryExports, RemoteEntryInitOptions, RemoteInfo, RemoteInfoCommon, RemoteInfoOptionalVersion, ResourceLoadContext, ResourceLoadInitiator, ResourceLoadType, ShareArgs, ShareInfos, ShareScopeMap, ShareStrategy, Shared, SharedConfig, SharedGetter, TreeShakingArgs, UserOptions, depsPreloadArg }; | ||
| } | ||
@@ -9,0 +9,0 @@ //#endregion |
@@ -18,2 +18,26 @@ import { Remote, RemoteInfo } from "./config.js"; | ||
| }>; | ||
| type ResourceLoadInitiator = 'loadRemote' | 'preloadRemote'; | ||
| type ResourceLoadType = 'manifest' | 'remoteEntry' | 'js' | 'css'; | ||
| interface ResourceLoadContext { | ||
| initiator: ResourceLoadInitiator; | ||
| id: string; | ||
| resourceType: ResourceLoadType; | ||
| url?: string; | ||
| } | ||
| type PreloadAssetStatus = 'success' | 'error' | 'timeout' | 'cached'; | ||
| interface PreloadAssetResult { | ||
| url: string; | ||
| status: PreloadAssetStatus; | ||
| resourceType: ResourceLoadType; | ||
| initiator: ResourceLoadInitiator; | ||
| id: string; | ||
| error?: unknown; | ||
| } | ||
| interface PreloadRemoteResult { | ||
| remote: Remote; | ||
| remoteInfo: RemoteInfo; | ||
| preloadConfig: PreloadConfig; | ||
| id: string; | ||
| results: PreloadAssetResult[]; | ||
| } | ||
| type EntryAssets = { | ||
@@ -30,3 +54,3 @@ name: string; | ||
| //#endregion | ||
| export { EntryAssets, PreloadAssets, PreloadConfig, PreloadOptions, PreloadRemoteArgs, depsPreloadArg }; | ||
| export { EntryAssets, PreloadAssetResult, PreloadAssetStatus, PreloadAssets, PreloadConfig, PreloadOptions, PreloadRemoteArgs, PreloadRemoteResult, ResourceLoadContext, ResourceLoadInitiator, ResourceLoadType, depsPreloadArg }; | ||
| //# sourceMappingURL=preload.d.ts.map |
+2
-2
| import { ModuleFederationRuntimePlugin } from "./type/plugin.js"; | ||
| import { CallFrom, GlobalShareScopeMap, HostInfo, InitScope, InitTokens, LoadModuleOptions, LoadShareExtraOptions, NoMatchedUsedExportsItem, Optional, Options, PartialOptional, Remote, RemoteEntryExports, RemoteEntryInitOptions, RemoteInfo, RemoteInfoCommon, RemoteInfoOptionalVersion, ShareArgs, ShareInfos, ShareScopeMap, ShareStrategy, Shared, SharedConfig, SharedGetter, TreeShakingArgs, UserOptions } from "./type/config.js"; | ||
| import { EntryAssets, PreloadAssets, PreloadConfig, PreloadOptions, PreloadRemoteArgs, depsPreloadArg } from "./type/preload.js"; | ||
| export { CallFrom, EntryAssets, GlobalShareScopeMap, HostInfo, InitScope, InitTokens, LoadModuleOptions, LoadShareExtraOptions, ModuleFederationRuntimePlugin, NoMatchedUsedExportsItem, Optional, Options, PartialOptional, PreloadAssets, PreloadConfig, PreloadOptions, PreloadRemoteArgs, Remote, RemoteEntryExports, RemoteEntryInitOptions, RemoteInfo, RemoteInfoCommon, RemoteInfoOptionalVersion, ShareArgs, ShareInfos, ShareScopeMap, ShareStrategy, Shared, SharedConfig, SharedGetter, TreeShakingArgs, UserOptions, depsPreloadArg }; | ||
| import { EntryAssets, PreloadAssetResult, PreloadAssetStatus, PreloadAssets, PreloadConfig, PreloadOptions, PreloadRemoteArgs, PreloadRemoteResult, ResourceLoadContext, ResourceLoadInitiator, ResourceLoadType, depsPreloadArg } from "./type/preload.js"; | ||
| export { CallFrom, EntryAssets, GlobalShareScopeMap, HostInfo, InitScope, InitTokens, LoadModuleOptions, LoadShareExtraOptions, ModuleFederationRuntimePlugin, NoMatchedUsedExportsItem, Optional, Options, PartialOptional, PreloadAssetResult, PreloadAssetStatus, PreloadAssets, PreloadConfig, PreloadOptions, PreloadRemoteArgs, PreloadRemoteResult, Remote, RemoteEntryExports, RemoteEntryInitOptions, RemoteInfo, RemoteInfoCommon, RemoteInfoOptionalVersion, ResourceLoadContext, ResourceLoadInitiator, ResourceLoadType, ShareArgs, ShareInfos, ShareScopeMap, ShareStrategy, Shared, SharedConfig, SharedGetter, TreeShakingArgs, UserOptions, depsPreloadArg }; |
@@ -12,3 +12,6 @@ const require_syncHook = require('./syncHook.cjs'); | ||
| if (prev === false) return false; | ||
| else if (i < ls.length) return Promise.resolve(ls[i++].apply(null, data)).then(call); | ||
| else if (i < ls.length) return Promise.resolve(ls[i++].apply(null, data)).then((result) => { | ||
| if (result === void 0 || data.length === 1 && result === data[0]) return call(prev); | ||
| return call(result); | ||
| }); | ||
| else return prev; | ||
@@ -15,0 +18,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"asyncHook.cjs","names":["SyncHook"],"sources":["../../../src/utils/hooks/asyncHook.ts"],"sourcesContent":["import { ArgsType, SyncHook } from './syncHook';\n\ntype CallbackReturnType = void | false | Promise<void | false>;\n\nexport class AsyncHook<\n T,\n ExternalEmitReturnType = CallbackReturnType,\n> extends SyncHook<T, ExternalEmitReturnType> {\n override emit(\n ...data: ArgsType<T>\n ): Promise<void | false | ExternalEmitReturnType> {\n let result;\n const ls = Array.from(this.listeners);\n if (ls.length > 0) {\n let i = 0;\n const call = (prev?: any): any => {\n if (prev === false) {\n return false; // Abort process\n } else if (i < ls.length) {\n return Promise.resolve(ls[i++].apply(null, data)).then(call);\n } else {\n return prev;\n }\n };\n result = call();\n }\n return Promise.resolve(result);\n }\n}\n"],"mappings":";;;AAIA,IAAa,YAAb,cAGUA,0BAAoC;CAC5C,AAAS,KACP,GAAG,MAC6C;EAChD,IAAI;EACJ,MAAM,KAAK,MAAM,KAAK,KAAK,UAAU;AACrC,MAAI,GAAG,SAAS,GAAG;GACjB,IAAI,IAAI;GACR,MAAM,QAAQ,SAAoB;AAChC,QAAI,SAAS,MACX,QAAO;aACE,IAAI,GAAG,OAChB,QAAO,QAAQ,QAAQ,GAAG,KAAK,MAAM,MAAM,KAAK,CAAC,CAAC,KAAK,KAAK;QAE5D,QAAO;;AAGX,YAAS,MAAM;;AAEjB,SAAO,QAAQ,QAAQ,OAAO"} | ||
| {"version":3,"file":"asyncHook.cjs","names":["SyncHook"],"sources":["../../../src/utils/hooks/asyncHook.ts"],"sourcesContent":["import { ArgsType, SyncHook } from './syncHook';\n\ntype CallbackReturnType = void | false | Promise<void | false>;\n\nexport class AsyncHook<\n T,\n ExternalEmitReturnType = CallbackReturnType,\n> extends SyncHook<T, ExternalEmitReturnType> {\n override emit(\n ...data: ArgsType<T>\n ): Promise<void | false | ExternalEmitReturnType> {\n let result;\n const ls = Array.from(this.listeners);\n if (ls.length > 0) {\n let i = 0;\n const call = (prev?: unknown): unknown => {\n if (prev === false) {\n return false; // Abort process\n } else if (i < ls.length) {\n return Promise.resolve(ls[i++].apply(null, data)).then((result) => {\n if (\n result === undefined ||\n (data.length === 1 && result === data[0])\n ) {\n return call(prev);\n }\n return call(result);\n });\n } else {\n return prev;\n }\n };\n result = call();\n }\n return Promise.resolve(result) as Promise<\n void | false | ExternalEmitReturnType\n >;\n }\n}\n"],"mappings":";;;AAIA,IAAa,YAAb,cAGUA,0BAAoC;CAC5C,AAAS,KACP,GAAG,MAC6C;EAChD,IAAI;EACJ,MAAM,KAAK,MAAM,KAAK,KAAK,UAAU;AACrC,MAAI,GAAG,SAAS,GAAG;GACjB,IAAI,IAAI;GACR,MAAM,QAAQ,SAA4B;AACxC,QAAI,SAAS,MACX,QAAO;aACE,IAAI,GAAG,OAChB,QAAO,QAAQ,QAAQ,GAAG,KAAK,MAAM,MAAM,KAAK,CAAC,CAAC,MAAM,WAAW;AACjE,SACE,WAAW,UACV,KAAK,WAAW,KAAK,WAAW,KAAK,GAEtC,QAAO,KAAK,KAAK;AAEnB,YAAO,KAAK,OAAO;MACnB;QAEF,QAAO;;AAGX,YAAS,MAAM;;AAEjB,SAAO,QAAQ,QAAQ,OAAO"} |
@@ -12,3 +12,6 @@ import { SyncHook } from "./syncHook.js"; | ||
| if (prev === false) return false; | ||
| else if (i < ls.length) return Promise.resolve(ls[i++].apply(null, data)).then(call); | ||
| else if (i < ls.length) return Promise.resolve(ls[i++].apply(null, data)).then((result) => { | ||
| if (result === void 0 || data.length === 1 && result === data[0]) return call(prev); | ||
| return call(result); | ||
| }); | ||
| else return prev; | ||
@@ -15,0 +18,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"asyncHook.js","names":[],"sources":["../../../src/utils/hooks/asyncHook.ts"],"sourcesContent":["import { ArgsType, SyncHook } from './syncHook';\n\ntype CallbackReturnType = void | false | Promise<void | false>;\n\nexport class AsyncHook<\n T,\n ExternalEmitReturnType = CallbackReturnType,\n> extends SyncHook<T, ExternalEmitReturnType> {\n override emit(\n ...data: ArgsType<T>\n ): Promise<void | false | ExternalEmitReturnType> {\n let result;\n const ls = Array.from(this.listeners);\n if (ls.length > 0) {\n let i = 0;\n const call = (prev?: any): any => {\n if (prev === false) {\n return false; // Abort process\n } else if (i < ls.length) {\n return Promise.resolve(ls[i++].apply(null, data)).then(call);\n } else {\n return prev;\n }\n };\n result = call();\n }\n return Promise.resolve(result);\n }\n}\n"],"mappings":";;;AAIA,IAAa,YAAb,cAGU,SAAoC;CAC5C,AAAS,KACP,GAAG,MAC6C;EAChD,IAAI;EACJ,MAAM,KAAK,MAAM,KAAK,KAAK,UAAU;AACrC,MAAI,GAAG,SAAS,GAAG;GACjB,IAAI,IAAI;GACR,MAAM,QAAQ,SAAoB;AAChC,QAAI,SAAS,MACX,QAAO;aACE,IAAI,GAAG,OAChB,QAAO,QAAQ,QAAQ,GAAG,KAAK,MAAM,MAAM,KAAK,CAAC,CAAC,KAAK,KAAK;QAE5D,QAAO;;AAGX,YAAS,MAAM;;AAEjB,SAAO,QAAQ,QAAQ,OAAO"} | ||
| {"version":3,"file":"asyncHook.js","names":[],"sources":["../../../src/utils/hooks/asyncHook.ts"],"sourcesContent":["import { ArgsType, SyncHook } from './syncHook';\n\ntype CallbackReturnType = void | false | Promise<void | false>;\n\nexport class AsyncHook<\n T,\n ExternalEmitReturnType = CallbackReturnType,\n> extends SyncHook<T, ExternalEmitReturnType> {\n override emit(\n ...data: ArgsType<T>\n ): Promise<void | false | ExternalEmitReturnType> {\n let result;\n const ls = Array.from(this.listeners);\n if (ls.length > 0) {\n let i = 0;\n const call = (prev?: unknown): unknown => {\n if (prev === false) {\n return false; // Abort process\n } else if (i < ls.length) {\n return Promise.resolve(ls[i++].apply(null, data)).then((result) => {\n if (\n result === undefined ||\n (data.length === 1 && result === data[0])\n ) {\n return call(prev);\n }\n return call(result);\n });\n } else {\n return prev;\n }\n };\n result = call();\n }\n return Promise.resolve(result) as Promise<\n void | false | ExternalEmitReturnType\n >;\n }\n}\n"],"mappings":";;;AAIA,IAAa,YAAb,cAGU,SAAoC;CAC5C,AAAS,KACP,GAAG,MAC6C;EAChD,IAAI;EACJ,MAAM,KAAK,MAAM,KAAK,KAAK,UAAU;AACrC,MAAI,GAAG,SAAS,GAAG;GACjB,IAAI,IAAI;GACR,MAAM,QAAQ,SAA4B;AACxC,QAAI,SAAS,MACX,QAAO;aACE,IAAI,GAAG,OAChB,QAAO,QAAQ,QAAQ,GAAG,KAAK,MAAM,MAAM,KAAK,CAAC,CAAC,MAAM,WAAW;AACjE,SACE,WAAW,UACV,KAAK,WAAW,KAAK,WAAW,KAAK,GAEtC,QAAO,KAAK,KAAK;AAEnB,YAAO,KAAK,OAAO;MACnB;QAEF,QAAO;;AAGX,YAAS,MAAM;;AAEjB,SAAO,QAAQ,QAAQ,OAAO"} |
@@ -24,10 +24,12 @@ const require_logger = require('../logger.cjs'); | ||
| const call = (prevData) => { | ||
| if (require_syncWaterfallHook.checkReturnData(data, prevData)) { | ||
| data = prevData; | ||
| if (i < ls.length) try { | ||
| return Promise.resolve(ls[i++](data)).then(call, processError); | ||
| } catch (e) { | ||
| return processError(e); | ||
| } | ||
| } else this.onerror(`A plugin returned an incorrect value for the "${this.type}" type.`); | ||
| if (prevData !== void 0 && require_syncWaterfallHook.checkReturnData(data, prevData)) data = prevData; | ||
| else if (prevData !== void 0) { | ||
| this.onerror(`A plugin returned an incorrect value for the "${this.type}" type.`); | ||
| return data; | ||
| } | ||
| if (i < ls.length) try { | ||
| return Promise.resolve(ls[i++](data)).then(call, processError); | ||
| } catch (e) { | ||
| return processError(e); | ||
| } | ||
| return data; | ||
@@ -34,0 +36,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"asyncWaterfallHooks.cjs","names":["SyncHook","error","isObject","checkReturnData"],"sources":["../../../src/utils/hooks/asyncWaterfallHooks.ts"],"sourcesContent":["import { error, warn } from '../logger';\nimport { isObject } from '../tool';\nimport { SyncHook } from './syncHook';\nimport { checkReturnData } from './syncWaterfallHook';\n\ntype CallbackReturnType<T> = T | Promise<T>;\n\nexport class AsyncWaterfallHook<T extends Record<string, any>> extends SyncHook<\n [T],\n CallbackReturnType<T>\n> {\n onerror: (errMsg: string | Error | unknown) => void = error;\n constructor(type: string) {\n super();\n this.type = type;\n }\n\n override emit(data: T): Promise<T> {\n if (!isObject(data)) {\n error(`The response data for the \"${this.type}\" hook must be an object.`);\n }\n const ls = Array.from(this.listeners);\n\n if (ls.length > 0) {\n let i = 0;\n const processError = (e: any) => {\n warn(e);\n this.onerror(e);\n return data;\n };\n\n const call = (prevData: T): any => {\n if (checkReturnData(data, prevData)) {\n data = prevData as T;\n if (i < ls.length) {\n try {\n return Promise.resolve(ls[i++](data)).then(call, processError);\n } catch (e) {\n return processError(e);\n }\n }\n } else {\n this.onerror(\n `A plugin returned an incorrect value for the \"${this.type}\" type.`,\n );\n }\n return data;\n };\n return Promise.resolve(call(data));\n }\n return Promise.resolve(data);\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,qBAAb,cAAuEA,0BAGrE;CAEA,YAAY,MAAc;AACxB,SAAO;iBAF6CC;AAGpD,OAAK,OAAO;;CAGd,AAAS,KAAK,MAAqB;AACjC,MAAI,CAACC,sBAAS,KAAK,CACjB,sBAAM,8BAA8B,KAAK,KAAK,2BAA2B;EAE3E,MAAM,KAAK,MAAM,KAAK,KAAK,UAAU;AAErC,MAAI,GAAG,SAAS,GAAG;GACjB,IAAI,IAAI;GACR,MAAM,gBAAgB,MAAW;AAC/B,wBAAK,EAAE;AACP,SAAK,QAAQ,EAAE;AACf,WAAO;;GAGT,MAAM,QAAQ,aAAqB;AACjC,QAAIC,0CAAgB,MAAM,SAAS,EAAE;AACnC,YAAO;AACP,SAAI,IAAI,GAAG,OACT,KAAI;AACF,aAAO,QAAQ,QAAQ,GAAG,KAAK,KAAK,CAAC,CAAC,KAAK,MAAM,aAAa;cACvD,GAAG;AACV,aAAO,aAAa,EAAE;;UAI1B,MAAK,QACH,iDAAiD,KAAK,KAAK,SAC5D;AAEH,WAAO;;AAET,UAAO,QAAQ,QAAQ,KAAK,KAAK,CAAC;;AAEpC,SAAO,QAAQ,QAAQ,KAAK"} | ||
| {"version":3,"file":"asyncWaterfallHooks.cjs","names":["SyncHook","error","isObject","checkReturnData"],"sources":["../../../src/utils/hooks/asyncWaterfallHooks.ts"],"sourcesContent":["import { error, warn } from '../logger';\nimport { isObject } from '../tool';\nimport { SyncHook } from './syncHook';\nimport { checkReturnData } from './syncWaterfallHook';\n\ntype CallbackReturnType<T> = T | void | Promise<T | void>;\n\nexport class AsyncWaterfallHook<T extends object> extends SyncHook<\n [T],\n CallbackReturnType<T>\n> {\n onerror: (errMsg: string | Error | unknown) => void = error;\n constructor(type: string) {\n super();\n this.type = type;\n }\n\n override emit(data: T): Promise<T> {\n if (!isObject(data)) {\n error(`The response data for the \"${this.type}\" hook must be an object.`);\n }\n const ls = Array.from(this.listeners);\n\n if (ls.length > 0) {\n let i = 0;\n const processError = (e: unknown): T => {\n warn(e);\n this.onerror(e);\n return data;\n };\n\n const call = (prevData?: T | Awaited<T> | void): T | Promise<T> => {\n if (prevData !== undefined && checkReturnData(data, prevData)) {\n data = prevData as T;\n } else if (prevData !== undefined) {\n this.onerror(\n `A plugin returned an incorrect value for the \"${this.type}\" type.`,\n );\n return data;\n }\n if (i < ls.length) {\n try {\n return Promise.resolve(ls[i++](data)).then(call, processError);\n } catch (e) {\n return processError(e);\n }\n }\n return data;\n };\n return Promise.resolve(call(data));\n }\n return Promise.resolve(data);\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,qBAAb,cAA0DA,0BAGxD;CAEA,YAAY,MAAc;AACxB,SAAO;iBAF6CC;AAGpD,OAAK,OAAO;;CAGd,AAAS,KAAK,MAAqB;AACjC,MAAI,CAACC,sBAAS,KAAK,CACjB,sBAAM,8BAA8B,KAAK,KAAK,2BAA2B;EAE3E,MAAM,KAAK,MAAM,KAAK,KAAK,UAAU;AAErC,MAAI,GAAG,SAAS,GAAG;GACjB,IAAI,IAAI;GACR,MAAM,gBAAgB,MAAkB;AACtC,wBAAK,EAAE;AACP,SAAK,QAAQ,EAAE;AACf,WAAO;;GAGT,MAAM,QAAQ,aAAqD;AACjE,QAAI,aAAa,UAAaC,0CAAgB,MAAM,SAAS,CAC3D,QAAO;aACE,aAAa,QAAW;AACjC,UAAK,QACH,iDAAiD,KAAK,KAAK,SAC5D;AACD,YAAO;;AAET,QAAI,IAAI,GAAG,OACT,KAAI;AACF,YAAO,QAAQ,QAAQ,GAAG,KAAK,KAAK,CAAC,CAAC,KAAK,MAAM,aAAa;aACvD,GAAG;AACV,YAAO,aAAa,EAAE;;AAG1B,WAAO;;AAET,UAAO,QAAQ,QAAQ,KAAK,KAAK,CAAC;;AAEpC,SAAO,QAAQ,QAAQ,KAAK"} |
| import { SyncHook } from "./syncHook.js"; | ||
| //#region src/utils/hooks/asyncWaterfallHooks.d.ts | ||
| type CallbackReturnType<T> = T | Promise<T>; | ||
| declare class AsyncWaterfallHook<T extends Record<string, any>> extends SyncHook<[T], CallbackReturnType<T>> { | ||
| type CallbackReturnType<T> = T | void | Promise<T | void>; | ||
| declare class AsyncWaterfallHook<T extends object> extends SyncHook<[T], CallbackReturnType<T>> { | ||
| onerror: (errMsg: string | Error | unknown) => void; | ||
@@ -7,0 +7,0 @@ constructor(type: string); |
@@ -24,10 +24,12 @@ import { error, warn } from "../logger.js"; | ||
| const call = (prevData) => { | ||
| if (checkReturnData(data, prevData)) { | ||
| data = prevData; | ||
| if (i < ls.length) try { | ||
| return Promise.resolve(ls[i++](data)).then(call, processError); | ||
| } catch (e) { | ||
| return processError(e); | ||
| } | ||
| } else this.onerror(`A plugin returned an incorrect value for the "${this.type}" type.`); | ||
| if (prevData !== void 0 && checkReturnData(data, prevData)) data = prevData; | ||
| else if (prevData !== void 0) { | ||
| this.onerror(`A plugin returned an incorrect value for the "${this.type}" type.`); | ||
| return data; | ||
| } | ||
| if (i < ls.length) try { | ||
| return Promise.resolve(ls[i++](data)).then(call, processError); | ||
| } catch (e) { | ||
| return processError(e); | ||
| } | ||
| return data; | ||
@@ -34,0 +36,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"asyncWaterfallHooks.js","names":[],"sources":["../../../src/utils/hooks/asyncWaterfallHooks.ts"],"sourcesContent":["import { error, warn } from '../logger';\nimport { isObject } from '../tool';\nimport { SyncHook } from './syncHook';\nimport { checkReturnData } from './syncWaterfallHook';\n\ntype CallbackReturnType<T> = T | Promise<T>;\n\nexport class AsyncWaterfallHook<T extends Record<string, any>> extends SyncHook<\n [T],\n CallbackReturnType<T>\n> {\n onerror: (errMsg: string | Error | unknown) => void = error;\n constructor(type: string) {\n super();\n this.type = type;\n }\n\n override emit(data: T): Promise<T> {\n if (!isObject(data)) {\n error(`The response data for the \"${this.type}\" hook must be an object.`);\n }\n const ls = Array.from(this.listeners);\n\n if (ls.length > 0) {\n let i = 0;\n const processError = (e: any) => {\n warn(e);\n this.onerror(e);\n return data;\n };\n\n const call = (prevData: T): any => {\n if (checkReturnData(data, prevData)) {\n data = prevData as T;\n if (i < ls.length) {\n try {\n return Promise.resolve(ls[i++](data)).then(call, processError);\n } catch (e) {\n return processError(e);\n }\n }\n } else {\n this.onerror(\n `A plugin returned an incorrect value for the \"${this.type}\" type.`,\n );\n }\n return data;\n };\n return Promise.resolve(call(data));\n }\n return Promise.resolve(data);\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,qBAAb,cAAuE,SAGrE;CAEA,YAAY,MAAc;AACxB,SAAO;iBAF6C;AAGpD,OAAK,OAAO;;CAGd,AAAS,KAAK,MAAqB;AACjC,MAAI,CAAC,SAAS,KAAK,CACjB,OAAM,8BAA8B,KAAK,KAAK,2BAA2B;EAE3E,MAAM,KAAK,MAAM,KAAK,KAAK,UAAU;AAErC,MAAI,GAAG,SAAS,GAAG;GACjB,IAAI,IAAI;GACR,MAAM,gBAAgB,MAAW;AAC/B,SAAK,EAAE;AACP,SAAK,QAAQ,EAAE;AACf,WAAO;;GAGT,MAAM,QAAQ,aAAqB;AACjC,QAAI,gBAAgB,MAAM,SAAS,EAAE;AACnC,YAAO;AACP,SAAI,IAAI,GAAG,OACT,KAAI;AACF,aAAO,QAAQ,QAAQ,GAAG,KAAK,KAAK,CAAC,CAAC,KAAK,MAAM,aAAa;cACvD,GAAG;AACV,aAAO,aAAa,EAAE;;UAI1B,MAAK,QACH,iDAAiD,KAAK,KAAK,SAC5D;AAEH,WAAO;;AAET,UAAO,QAAQ,QAAQ,KAAK,KAAK,CAAC;;AAEpC,SAAO,QAAQ,QAAQ,KAAK"} | ||
| {"version":3,"file":"asyncWaterfallHooks.js","names":[],"sources":["../../../src/utils/hooks/asyncWaterfallHooks.ts"],"sourcesContent":["import { error, warn } from '../logger';\nimport { isObject } from '../tool';\nimport { SyncHook } from './syncHook';\nimport { checkReturnData } from './syncWaterfallHook';\n\ntype CallbackReturnType<T> = T | void | Promise<T | void>;\n\nexport class AsyncWaterfallHook<T extends object> extends SyncHook<\n [T],\n CallbackReturnType<T>\n> {\n onerror: (errMsg: string | Error | unknown) => void = error;\n constructor(type: string) {\n super();\n this.type = type;\n }\n\n override emit(data: T): Promise<T> {\n if (!isObject(data)) {\n error(`The response data for the \"${this.type}\" hook must be an object.`);\n }\n const ls = Array.from(this.listeners);\n\n if (ls.length > 0) {\n let i = 0;\n const processError = (e: unknown): T => {\n warn(e);\n this.onerror(e);\n return data;\n };\n\n const call = (prevData?: T | Awaited<T> | void): T | Promise<T> => {\n if (prevData !== undefined && checkReturnData(data, prevData)) {\n data = prevData as T;\n } else if (prevData !== undefined) {\n this.onerror(\n `A plugin returned an incorrect value for the \"${this.type}\" type.`,\n );\n return data;\n }\n if (i < ls.length) {\n try {\n return Promise.resolve(ls[i++](data)).then(call, processError);\n } catch (e) {\n return processError(e);\n }\n }\n return data;\n };\n return Promise.resolve(call(data));\n }\n return Promise.resolve(data);\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,qBAAb,cAA0D,SAGxD;CAEA,YAAY,MAAc;AACxB,SAAO;iBAF6C;AAGpD,OAAK,OAAO;;CAGd,AAAS,KAAK,MAAqB;AACjC,MAAI,CAAC,SAAS,KAAK,CACjB,OAAM,8BAA8B,KAAK,KAAK,2BAA2B;EAE3E,MAAM,KAAK,MAAM,KAAK,KAAK,UAAU;AAErC,MAAI,GAAG,SAAS,GAAG;GACjB,IAAI,IAAI;GACR,MAAM,gBAAgB,MAAkB;AACtC,SAAK,EAAE;AACP,SAAK,QAAQ,EAAE;AACf,WAAO;;GAGT,MAAM,QAAQ,aAAqD;AACjE,QAAI,aAAa,UAAa,gBAAgB,MAAM,SAAS,CAC3D,QAAO;aACE,aAAa,QAAW;AACjC,UAAK,QACH,iDAAiD,KAAK,KAAK,SAC5D;AACD,YAAO;;AAET,QAAI,IAAI,GAAG,OACT,KAAI;AACF,YAAO,QAAQ,QAAQ,GAAG,KAAK,KAAK,CAAC,CAAC,KAAK,MAAM,aAAa;aACvD,GAAG;AACV,YAAO,aAAa,EAAE;;AAG1B,WAAO;;AAET,UAAO,QAAQ,QAAQ,KAAK,KAAK,CAAC;;AAEpC,SAAO,QAAQ,QAAQ,KAAK"} |
@@ -18,3 +18,3 @@ import { ModuleFederation } from "../../core.js"; | ||
| //#endregion | ||
| export { Plugin, PluginSystem }; | ||
| export { PluginSystem }; | ||
| //# sourceMappingURL=pluginSystem.d.ts.map |
@@ -22,3 +22,4 @@ | ||
| if (this.listeners.size > 0) this.listeners.forEach((fn) => { | ||
| result = fn(...data); | ||
| const nextResult = fn(...data); | ||
| if (nextResult !== void 0) result = nextResult; | ||
| }); | ||
@@ -25,0 +26,0 @@ return result; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"syncHook.cjs","names":[],"sources":["../../../src/utils/hooks/syncHook.ts"],"sourcesContent":["export type Callback<T, K> = (...args: ArgsType<T>) => K;\nexport type ArgsType<T> = T extends Array<any> ? T : Array<any>;\n\nexport class SyncHook<T, K> {\n type = '';\n listeners = new Set<Callback<T, K>>();\n\n constructor(type?: string) {\n if (type) {\n this.type = type;\n }\n }\n\n on(fn: Callback<T, K>): void {\n if (typeof fn === 'function') {\n this.listeners.add(fn);\n }\n }\n\n once(fn: Callback<T, K>): void {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n this.on(function wrapper(...args) {\n self.remove(wrapper);\n // eslint-disable-next-line prefer-spread\n return fn.apply(null, args);\n });\n }\n\n emit(...data: ArgsType<T>): void | K | Promise<any> {\n let result;\n if (this.listeners.size > 0) {\n // eslint-disable-next-line prefer-spread\n this.listeners.forEach((fn) => {\n result = fn(...data);\n });\n }\n return result;\n }\n\n remove(fn: Callback<T, K>): void {\n this.listeners.delete(fn);\n }\n\n removeAll(): void {\n this.listeners.clear();\n }\n}\n"],"mappings":";;AAGA,IAAa,WAAb,MAA4B;CAI1B,YAAY,MAAe;cAHpB;mCACK,IAAI,KAAqB;AAGnC,MAAI,KACF,MAAK,OAAO;;CAIhB,GAAG,IAA0B;AAC3B,MAAI,OAAO,OAAO,WAChB,MAAK,UAAU,IAAI,GAAG;;CAI1B,KAAK,IAA0B;EAE7B,MAAM,OAAO;AACb,OAAK,GAAG,SAAS,QAAQ,GAAG,MAAM;AAChC,QAAK,OAAO,QAAQ;AAEpB,UAAO,GAAG,MAAM,MAAM,KAAK;IAC3B;;CAGJ,KAAK,GAAG,MAA4C;EAClD,IAAI;AACJ,MAAI,KAAK,UAAU,OAAO,EAExB,MAAK,UAAU,SAAS,OAAO;AAC7B,YAAS,GAAG,GAAG,KAAK;IACpB;AAEJ,SAAO;;CAGT,OAAO,IAA0B;AAC/B,OAAK,UAAU,OAAO,GAAG;;CAG3B,YAAkB;AAChB,OAAK,UAAU,OAAO"} | ||
| {"version":3,"file":"syncHook.cjs","names":[],"sources":["../../../src/utils/hooks/syncHook.ts"],"sourcesContent":["export type Callback<T, K> = (...args: ArgsType<T>) => K;\nexport type ArgsType<T> = T extends Array<any> ? T : Array<any>;\n\nexport class SyncHook<T, K> {\n type = '';\n listeners = new Set<Callback<T, K>>();\n\n constructor(type?: string) {\n if (type) {\n this.type = type;\n }\n }\n\n on(fn: Callback<T, K>): void {\n if (typeof fn === 'function') {\n this.listeners.add(fn);\n }\n }\n\n once(fn: Callback<T, K>): void {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n this.on(function wrapper(...args) {\n self.remove(wrapper);\n // eslint-disable-next-line prefer-spread\n return fn.apply(null, args);\n });\n }\n\n emit(...data: ArgsType<T>): void | K | Promise<any> {\n let result;\n if (this.listeners.size > 0) {\n // eslint-disable-next-line prefer-spread\n this.listeners.forEach((fn) => {\n const nextResult = fn(...data);\n if (nextResult !== undefined) {\n result = nextResult;\n }\n });\n }\n return result;\n }\n\n remove(fn: Callback<T, K>): void {\n this.listeners.delete(fn);\n }\n\n removeAll(): void {\n this.listeners.clear();\n }\n}\n"],"mappings":";;AAGA,IAAa,WAAb,MAA4B;CAI1B,YAAY,MAAe;cAHpB;mCACK,IAAI,KAAqB;AAGnC,MAAI,KACF,MAAK,OAAO;;CAIhB,GAAG,IAA0B;AAC3B,MAAI,OAAO,OAAO,WAChB,MAAK,UAAU,IAAI,GAAG;;CAI1B,KAAK,IAA0B;EAE7B,MAAM,OAAO;AACb,OAAK,GAAG,SAAS,QAAQ,GAAG,MAAM;AAChC,QAAK,OAAO,QAAQ;AAEpB,UAAO,GAAG,MAAM,MAAM,KAAK;IAC3B;;CAGJ,KAAK,GAAG,MAA4C;EAClD,IAAI;AACJ,MAAI,KAAK,UAAU,OAAO,EAExB,MAAK,UAAU,SAAS,OAAO;GAC7B,MAAM,aAAa,GAAG,GAAG,KAAK;AAC9B,OAAI,eAAe,OACjB,UAAS;IAEX;AAEJ,SAAO;;CAGT,OAAO,IAA0B;AAC/B,OAAK,UAAU,OAAO,GAAG;;CAG3B,YAAkB;AAChB,OAAK,UAAU,OAAO"} |
@@ -21,3 +21,4 @@ //#region src/utils/hooks/syncHook.ts | ||
| if (this.listeners.size > 0) this.listeners.forEach((fn) => { | ||
| result = fn(...data); | ||
| const nextResult = fn(...data); | ||
| if (nextResult !== void 0) result = nextResult; | ||
| }); | ||
@@ -24,0 +25,0 @@ return result; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"syncHook.js","names":[],"sources":["../../../src/utils/hooks/syncHook.ts"],"sourcesContent":["export type Callback<T, K> = (...args: ArgsType<T>) => K;\nexport type ArgsType<T> = T extends Array<any> ? T : Array<any>;\n\nexport class SyncHook<T, K> {\n type = '';\n listeners = new Set<Callback<T, K>>();\n\n constructor(type?: string) {\n if (type) {\n this.type = type;\n }\n }\n\n on(fn: Callback<T, K>): void {\n if (typeof fn === 'function') {\n this.listeners.add(fn);\n }\n }\n\n once(fn: Callback<T, K>): void {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n this.on(function wrapper(...args) {\n self.remove(wrapper);\n // eslint-disable-next-line prefer-spread\n return fn.apply(null, args);\n });\n }\n\n emit(...data: ArgsType<T>): void | K | Promise<any> {\n let result;\n if (this.listeners.size > 0) {\n // eslint-disable-next-line prefer-spread\n this.listeners.forEach((fn) => {\n result = fn(...data);\n });\n }\n return result;\n }\n\n remove(fn: Callback<T, K>): void {\n this.listeners.delete(fn);\n }\n\n removeAll(): void {\n this.listeners.clear();\n }\n}\n"],"mappings":";AAGA,IAAa,WAAb,MAA4B;CAI1B,YAAY,MAAe;cAHpB;mCACK,IAAI,KAAqB;AAGnC,MAAI,KACF,MAAK,OAAO;;CAIhB,GAAG,IAA0B;AAC3B,MAAI,OAAO,OAAO,WAChB,MAAK,UAAU,IAAI,GAAG;;CAI1B,KAAK,IAA0B;EAE7B,MAAM,OAAO;AACb,OAAK,GAAG,SAAS,QAAQ,GAAG,MAAM;AAChC,QAAK,OAAO,QAAQ;AAEpB,UAAO,GAAG,MAAM,MAAM,KAAK;IAC3B;;CAGJ,KAAK,GAAG,MAA4C;EAClD,IAAI;AACJ,MAAI,KAAK,UAAU,OAAO,EAExB,MAAK,UAAU,SAAS,OAAO;AAC7B,YAAS,GAAG,GAAG,KAAK;IACpB;AAEJ,SAAO;;CAGT,OAAO,IAA0B;AAC/B,OAAK,UAAU,OAAO,GAAG;;CAG3B,YAAkB;AAChB,OAAK,UAAU,OAAO"} | ||
| {"version":3,"file":"syncHook.js","names":[],"sources":["../../../src/utils/hooks/syncHook.ts"],"sourcesContent":["export type Callback<T, K> = (...args: ArgsType<T>) => K;\nexport type ArgsType<T> = T extends Array<any> ? T : Array<any>;\n\nexport class SyncHook<T, K> {\n type = '';\n listeners = new Set<Callback<T, K>>();\n\n constructor(type?: string) {\n if (type) {\n this.type = type;\n }\n }\n\n on(fn: Callback<T, K>): void {\n if (typeof fn === 'function') {\n this.listeners.add(fn);\n }\n }\n\n once(fn: Callback<T, K>): void {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n this.on(function wrapper(...args) {\n self.remove(wrapper);\n // eslint-disable-next-line prefer-spread\n return fn.apply(null, args);\n });\n }\n\n emit(...data: ArgsType<T>): void | K | Promise<any> {\n let result;\n if (this.listeners.size > 0) {\n // eslint-disable-next-line prefer-spread\n this.listeners.forEach((fn) => {\n const nextResult = fn(...data);\n if (nextResult !== undefined) {\n result = nextResult;\n }\n });\n }\n return result;\n }\n\n remove(fn: Callback<T, K>): void {\n this.listeners.delete(fn);\n }\n\n removeAll(): void {\n this.listeners.clear();\n }\n}\n"],"mappings":";AAGA,IAAa,WAAb,MAA4B;CAI1B,YAAY,MAAe;cAHpB;mCACK,IAAI,KAAqB;AAGnC,MAAI,KACF,MAAK,OAAO;;CAIhB,GAAG,IAA0B;AAC3B,MAAI,OAAO,OAAO,WAChB,MAAK,UAAU,IAAI,GAAG;;CAI1B,KAAK,IAA0B;EAE7B,MAAM,OAAO;AACb,OAAK,GAAG,SAAS,QAAQ,GAAG,MAAM;AAChC,QAAK,OAAO,QAAQ;AAEpB,UAAO,GAAG,MAAM,MAAM,KAAK;IAC3B;;CAGJ,KAAK,GAAG,MAA4C;EAClD,IAAI;AACJ,MAAI,KAAK,UAAU,OAAO,EAExB,MAAK,UAAU,SAAS,OAAO;GAC7B,MAAM,aAAa,GAAG,GAAG,KAAK;AAC9B,OAAI,eAAe,OACjB,UAAS;IAEX;AAEJ,SAAO;;CAGT,OAAO,IAA0B;AAC/B,OAAK,UAAU,OAAO,GAAG;;CAG3B,YAAkB;AAChB,OAAK,UAAU,OAAO"} |
@@ -23,2 +23,3 @@ const require_logger = require('../logger.cjs'); | ||
| const tempData = fn(data); | ||
| if (tempData === void 0) continue; | ||
| if (checkReturnData(data, tempData)) data = tempData; | ||
@@ -25,0 +26,0 @@ else { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"syncWaterfallHook.cjs","names":["isObject","SyncHook","error"],"sources":["../../../src/utils/hooks/syncWaterfallHook.ts"],"sourcesContent":["import { error, warn } from '../logger';\nimport { isObject } from '../tool';\nimport { SyncHook } from './syncHook';\n\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nexport function checkReturnData(originalData: any, returnedData: any): boolean {\n if (!isObject(returnedData)) {\n return false;\n }\n if (originalData !== returnedData) {\n // eslint-disable-next-line no-restricted-syntax\n for (const key in originalData) {\n if (!(key in returnedData)) {\n return false;\n }\n }\n }\n return true;\n}\n\nexport class SyncWaterfallHook<T extends Record<string, any>> extends SyncHook<\n [T],\n T\n> {\n onerror: (errMsg: string | Error | unknown) => void = error;\n\n constructor(type: string) {\n super();\n this.type = type;\n }\n\n override emit(data: T): T {\n if (!isObject(data)) {\n error(`The data for the \"${this.type}\" hook should be an object.`);\n }\n for (const fn of this.listeners) {\n try {\n const tempData = fn(data);\n if (checkReturnData(data, tempData)) {\n data = tempData;\n } else {\n this.onerror(\n `A plugin returned an unacceptable value for the \"${this.type}\" type.`,\n );\n break;\n }\n } catch (e) {\n warn(e);\n this.onerror(e);\n }\n }\n return data;\n }\n}\n"],"mappings":";;;;;AAKA,SAAgB,gBAAgB,cAAmB,cAA4B;AAC7E,KAAI,CAACA,sBAAS,aAAa,CACzB,QAAO;AAET,KAAI,iBAAiB,cAEnB;OAAK,MAAM,OAAO,aAChB,KAAI,EAAE,OAAO,cACX,QAAO;;AAIb,QAAO;;AAGT,IAAa,oBAAb,cAAsEC,0BAGpE;CAGA,YAAY,MAAc;AACxB,SAAO;iBAH6CC;AAIpD,OAAK,OAAO;;CAGd,AAAS,KAAK,MAAY;AACxB,MAAI,CAACF,sBAAS,KAAK,CACjB,sBAAM,qBAAqB,KAAK,KAAK,6BAA6B;AAEpE,OAAK,MAAM,MAAM,KAAK,UACpB,KAAI;GACF,MAAM,WAAW,GAAG,KAAK;AACzB,OAAI,gBAAgB,MAAM,SAAS,CACjC,QAAO;QACF;AACL,SAAK,QACH,oDAAoD,KAAK,KAAK,SAC/D;AACD;;WAEK,GAAG;AACV,uBAAK,EAAE;AACP,QAAK,QAAQ,EAAE;;AAGnB,SAAO"} | ||
| {"version":3,"file":"syncWaterfallHook.cjs","names":["isObject","SyncHook","error"],"sources":["../../../src/utils/hooks/syncWaterfallHook.ts"],"sourcesContent":["import { error, warn } from '../logger';\nimport { isObject } from '../tool';\nimport { SyncHook } from './syncHook';\n\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nexport function checkReturnData(originalData: any, returnedData: any): boolean {\n if (!isObject(returnedData)) {\n return false;\n }\n if (originalData !== returnedData) {\n // eslint-disable-next-line no-restricted-syntax\n for (const key in originalData) {\n if (!(key in returnedData)) {\n return false;\n }\n }\n }\n return true;\n}\n\nexport class SyncWaterfallHook<T extends Record<string, any>> extends SyncHook<\n [T],\n T | void\n> {\n onerror: (errMsg: string | Error | unknown) => void = error;\n\n constructor(type: string) {\n super();\n this.type = type;\n }\n\n override emit(data: T): T {\n if (!isObject(data)) {\n error(`The data for the \"${this.type}\" hook should be an object.`);\n }\n for (const fn of this.listeners) {\n try {\n const tempData = fn(data);\n if (tempData === undefined) {\n continue;\n }\n if (checkReturnData(data, tempData)) {\n data = tempData;\n } else {\n this.onerror(\n `A plugin returned an unacceptable value for the \"${this.type}\" type.`,\n );\n break;\n }\n } catch (e) {\n warn(e);\n this.onerror(e);\n }\n }\n return data;\n }\n}\n"],"mappings":";;;;;AAKA,SAAgB,gBAAgB,cAAmB,cAA4B;AAC7E,KAAI,CAACA,sBAAS,aAAa,CACzB,QAAO;AAET,KAAI,iBAAiB,cAEnB;OAAK,MAAM,OAAO,aAChB,KAAI,EAAE,OAAO,cACX,QAAO;;AAIb,QAAO;;AAGT,IAAa,oBAAb,cAAsEC,0BAGpE;CAGA,YAAY,MAAc;AACxB,SAAO;iBAH6CC;AAIpD,OAAK,OAAO;;CAGd,AAAS,KAAK,MAAY;AACxB,MAAI,CAACF,sBAAS,KAAK,CACjB,sBAAM,qBAAqB,KAAK,KAAK,6BAA6B;AAEpE,OAAK,MAAM,MAAM,KAAK,UACpB,KAAI;GACF,MAAM,WAAW,GAAG,KAAK;AACzB,OAAI,aAAa,OACf;AAEF,OAAI,gBAAgB,MAAM,SAAS,CACjC,QAAO;QACF;AACL,SAAK,QACH,oDAAoD,KAAK,KAAK,SAC/D;AACD;;WAEK,GAAG;AACV,uBAAK,EAAE;AACP,QAAK,QAAQ,EAAE;;AAGnB,SAAO"} |
| import { SyncHook } from "./syncHook.js"; | ||
| //#region src/utils/hooks/syncWaterfallHook.d.ts | ||
| declare class SyncWaterfallHook<T extends Record<string, any>> extends SyncHook<[T], T> { | ||
| declare class SyncWaterfallHook<T extends Record<string, any>> extends SyncHook<[T], T | void> { | ||
| onerror: (errMsg: string | Error | unknown) => void; | ||
@@ -6,0 +6,0 @@ constructor(type: string); |
@@ -23,2 +23,3 @@ import { error, warn } from "../logger.js"; | ||
| const tempData = fn(data); | ||
| if (tempData === void 0) continue; | ||
| if (checkReturnData(data, tempData)) data = tempData; | ||
@@ -25,0 +26,0 @@ else { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"syncWaterfallHook.js","names":[],"sources":["../../../src/utils/hooks/syncWaterfallHook.ts"],"sourcesContent":["import { error, warn } from '../logger';\nimport { isObject } from '../tool';\nimport { SyncHook } from './syncHook';\n\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nexport function checkReturnData(originalData: any, returnedData: any): boolean {\n if (!isObject(returnedData)) {\n return false;\n }\n if (originalData !== returnedData) {\n // eslint-disable-next-line no-restricted-syntax\n for (const key in originalData) {\n if (!(key in returnedData)) {\n return false;\n }\n }\n }\n return true;\n}\n\nexport class SyncWaterfallHook<T extends Record<string, any>> extends SyncHook<\n [T],\n T\n> {\n onerror: (errMsg: string | Error | unknown) => void = error;\n\n constructor(type: string) {\n super();\n this.type = type;\n }\n\n override emit(data: T): T {\n if (!isObject(data)) {\n error(`The data for the \"${this.type}\" hook should be an object.`);\n }\n for (const fn of this.listeners) {\n try {\n const tempData = fn(data);\n if (checkReturnData(data, tempData)) {\n data = tempData;\n } else {\n this.onerror(\n `A plugin returned an unacceptable value for the \"${this.type}\" type.`,\n );\n break;\n }\n } catch (e) {\n warn(e);\n this.onerror(e);\n }\n }\n return data;\n }\n}\n"],"mappings":";;;;;AAKA,SAAgB,gBAAgB,cAAmB,cAA4B;AAC7E,KAAI,CAAC,SAAS,aAAa,CACzB,QAAO;AAET,KAAI,iBAAiB,cAEnB;OAAK,MAAM,OAAO,aAChB,KAAI,EAAE,OAAO,cACX,QAAO;;AAIb,QAAO;;AAGT,IAAa,oBAAb,cAAsE,SAGpE;CAGA,YAAY,MAAc;AACxB,SAAO;iBAH6C;AAIpD,OAAK,OAAO;;CAGd,AAAS,KAAK,MAAY;AACxB,MAAI,CAAC,SAAS,KAAK,CACjB,OAAM,qBAAqB,KAAK,KAAK,6BAA6B;AAEpE,OAAK,MAAM,MAAM,KAAK,UACpB,KAAI;GACF,MAAM,WAAW,GAAG,KAAK;AACzB,OAAI,gBAAgB,MAAM,SAAS,CACjC,QAAO;QACF;AACL,SAAK,QACH,oDAAoD,KAAK,KAAK,SAC/D;AACD;;WAEK,GAAG;AACV,QAAK,EAAE;AACP,QAAK,QAAQ,EAAE;;AAGnB,SAAO"} | ||
| {"version":3,"file":"syncWaterfallHook.js","names":[],"sources":["../../../src/utils/hooks/syncWaterfallHook.ts"],"sourcesContent":["import { error, warn } from '../logger';\nimport { isObject } from '../tool';\nimport { SyncHook } from './syncHook';\n\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nexport function checkReturnData(originalData: any, returnedData: any): boolean {\n if (!isObject(returnedData)) {\n return false;\n }\n if (originalData !== returnedData) {\n // eslint-disable-next-line no-restricted-syntax\n for (const key in originalData) {\n if (!(key in returnedData)) {\n return false;\n }\n }\n }\n return true;\n}\n\nexport class SyncWaterfallHook<T extends Record<string, any>> extends SyncHook<\n [T],\n T | void\n> {\n onerror: (errMsg: string | Error | unknown) => void = error;\n\n constructor(type: string) {\n super();\n this.type = type;\n }\n\n override emit(data: T): T {\n if (!isObject(data)) {\n error(`The data for the \"${this.type}\" hook should be an object.`);\n }\n for (const fn of this.listeners) {\n try {\n const tempData = fn(data);\n if (tempData === undefined) {\n continue;\n }\n if (checkReturnData(data, tempData)) {\n data = tempData;\n } else {\n this.onerror(\n `A plugin returned an unacceptable value for the \"${this.type}\" type.`,\n );\n break;\n }\n } catch (e) {\n warn(e);\n this.onerror(e);\n }\n }\n return data;\n }\n}\n"],"mappings":";;;;;AAKA,SAAgB,gBAAgB,cAAmB,cAA4B;AAC7E,KAAI,CAAC,SAAS,aAAa,CACzB,QAAO;AAET,KAAI,iBAAiB,cAEnB;OAAK,MAAM,OAAO,aAChB,KAAI,EAAE,OAAO,cACX,QAAO;;AAIb,QAAO;;AAGT,IAAa,oBAAb,cAAsE,SAGpE;CAGA,YAAY,MAAc;AACxB,SAAO;iBAH6C;AAIpD,OAAK,OAAO;;CAGd,AAAS,KAAK,MAAY;AACxB,MAAI,CAAC,SAAS,KAAK,CACjB,OAAM,qBAAqB,KAAK,KAAK,6BAA6B;AAEpE,OAAK,MAAM,MAAM,KAAK,UACpB,KAAI;GACF,MAAM,WAAW,GAAG,KAAK;AACzB,OAAI,aAAa,OACf;AAEF,OAAI,gBAAgB,MAAM,SAAS,CACjC,QAAO;QACF;AACL,SAAK,QACH,oDAAoD,KAAK,KAAK,SAC/D;AACD;;WAEK,GAAG;AACV,QAAK,EAAE;AACP,QAAK,QAAQ,EAAE;;AAGnB,SAAO"} |
| import { assert, error, logger, warn } from "./logger.js"; | ||
| import { addUniqueItem, arrayOptions, getFMId, getRemoteEntryInfoFromSnapshot, isObject, isPlainObject, isPureRemoteEntry, isRemoteInfoWithEntry, isStaticResourcesEqual, objectToString, processModuleAlias, safeWrapper } from "./tool.js"; | ||
| import { getBuilderId } from "./env.js"; | ||
| import { matchRemote, matchRemoteWithNameAndExpose } from "./manifest.js"; | ||
| import { composeRemoteRequestId, matchRemote, matchRemoteWithNameAndExpose } from "./manifest.js"; | ||
| import { registerPlugins } from "./plugin.js"; | ||
@@ -6,0 +6,0 @@ import { getRemoteEntry, getRemoteEntryUniqueKey, getRemoteInfo } from "./load.js"; |
+42
-10
@@ -44,3 +44,3 @@ const require_logger = require('./logger.cjs'); | ||
| } | ||
| async function loadEntryScript({ name, globalName, entry, remoteInfo, loaderHook, getEntryUrl }) { | ||
| async function loadEntryScript({ name, globalName, entry, remoteInfo, loaderHook, getEntryUrl, resourceContext }) { | ||
| const { entryExports: remoteEntryExports } = require_global.getRemoteEntryExports(name, globalName); | ||
@@ -55,3 +55,7 @@ if (remoteEntryExports) return remoteEntryExports; | ||
| attrs, | ||
| remoteInfo | ||
| remoteInfo, | ||
| resourceContext: resourceContext ? { | ||
| ...resourceContext, | ||
| url | ||
| } : void 0 | ||
| }); | ||
@@ -72,3 +76,3 @@ if (!res) return; | ||
| } | ||
| async function loadEntryDom({ remoteInfo, remoteEntryExports, loaderHook, getEntryUrl }) { | ||
| async function loadEntryDom({ remoteInfo, remoteEntryExports, loaderHook, getEntryUrl, resourceContext }) { | ||
| const { entry, entryGlobalName: globalName, name, type } = remoteInfo; | ||
@@ -91,7 +95,8 @@ switch (type) { | ||
| loaderHook, | ||
| getEntryUrl | ||
| getEntryUrl, | ||
| resourceContext | ||
| }); | ||
| } | ||
| } | ||
| async function loadEntryNode({ remoteInfo, loaderHook }) { | ||
| async function loadEntryNode({ remoteInfo, loaderHook, resourceContext }) { | ||
| const { entry, entryGlobalName: globalName, name, type } = remoteInfo; | ||
@@ -110,3 +115,7 @@ const { entryExports: remoteEntryExports } = require_global.getRemoteEntryExports(name, globalName); | ||
| attrs, | ||
| remoteInfo | ||
| remoteInfo, | ||
| resourceContext: resourceContext ? { | ||
| ...resourceContext, | ||
| url | ||
| } : void 0 | ||
| }); | ||
@@ -127,3 +136,3 @@ if (!res) return; | ||
| async function getRemoteEntry(params) { | ||
| const { origin, remoteEntryExports, remoteInfo, getEntryUrl, _inErrorHandling = false } = params; | ||
| const { origin, remoteEntryExports, remoteInfo, getEntryUrl, resourceContext, _inErrorHandling = false } = params; | ||
| const uniqueKey = getRemoteEntryUniqueKey(remoteInfo); | ||
@@ -135,2 +144,3 @@ if (remoteEntryExports) return remoteEntryExports; | ||
| require_global.globalLoading[uniqueKey] = loadEntryHook.emit({ | ||
| origin, | ||
| loaderHook, | ||
@@ -145,7 +155,16 @@ remoteInfo, | ||
| loaderHook, | ||
| getEntryUrl | ||
| getEntryUrl, | ||
| resourceContext | ||
| }) : loadEntryNode({ | ||
| remoteInfo, | ||
| loaderHook | ||
| loaderHook, | ||
| resourceContext | ||
| }); | ||
| }).then(async (res) => { | ||
| await origin.loaderHook.lifecycle.afterLoadEntry.emit({ | ||
| origin, | ||
| remoteInfo, | ||
| remoteEntryExports: res | ||
| }); | ||
| return res; | ||
| }).catch(async (err) => { | ||
@@ -169,4 +188,17 @@ const uniqueKey = getRemoteEntryUniqueKey(remoteInfo); | ||
| }); | ||
| if (RemoteEntryExports) return RemoteEntryExports; | ||
| if (RemoteEntryExports) { | ||
| await origin.loaderHook.lifecycle.afterLoadEntry.emit({ | ||
| origin, | ||
| remoteInfo, | ||
| remoteEntryExports: RemoteEntryExports, | ||
| recovered: true | ||
| }); | ||
| return RemoteEntryExports; | ||
| } | ||
| } | ||
| await origin.loaderHook.lifecycle.afterLoadEntry.emit({ | ||
| origin, | ||
| remoteInfo, | ||
| error: err | ||
| }); | ||
| throw err; | ||
@@ -173,0 +205,0 @@ }); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"load.cjs","names":["getRemoteEntryExports","RUNTIME_001","runtimeDescMap","RUNTIME_008","globalLoading","isBrowserEnvValue","DEFAULT_REMOTE_TYPE","DEFAULT_SCOPE"],"sources":["../../src/utils/load.ts"],"sourcesContent":["import {\n loadScript,\n loadScriptNode,\n composeKeyWithSeparator,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from '../constant';\nimport { ModuleFederation } from '../core';\nimport { globalLoading, getRemoteEntryExports } from '../global';\nimport { Remote, RemoteEntryExports, RemoteInfo } from '../type';\nimport { assert, error } from './logger';\nimport {\n RUNTIME_001,\n RUNTIME_008,\n runtimeDescMap,\n} from '@module-federation/error-codes';\n\n// Declare the ENV_TARGET constant that will be defined by DefinePlugin\ndeclare const ENV_TARGET: 'web' | 'node';\nconst importCallback = '.then(callbacks[0]).catch(callbacks[1])';\n\nasync function loadEsmEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n if (typeof FEDERATION_ALLOW_NEW_FUNCTION !== 'undefined') {\n new Function('callbacks', `import(\"${entry}\")${importCallback}`)([\n resolve,\n reject,\n ]);\n } else {\n import(/* webpackIgnore: true */ /* @vite-ignore */ entry)\n .then(resolve)\n .catch(reject);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load ESM entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nasync function loadSystemJsEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n //@ts-ignore\n if (typeof __system_context__ === 'undefined') {\n //@ts-ignore\n System.import(entry).then(resolve).catch(reject);\n } else {\n new Function(\n 'callbacks',\n `System.import(\"${entry}\")${importCallback}`,\n )([resolve, reject]);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load SystemJS entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nfunction handleRemoteEntryLoaded(\n name: string,\n globalName: string,\n entry: string,\n): RemoteEntryExports {\n const { remoteEntryKey, entryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (!entryExports) {\n error(RUNTIME_001, runtimeDescMap, {\n remoteName: name,\n remoteEntryUrl: entry,\n remoteEntryKey,\n });\n }\n\n return entryExports;\n}\n\nasync function loadEntryScript({\n name,\n globalName,\n entry,\n remoteInfo,\n loaderHook,\n getEntryUrl,\n}: {\n name: string;\n globalName: string;\n entry: string;\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n}): Promise<RemoteEntryExports> {\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n // if getEntryUrl is passed, use the getEntryUrl to get the entry url\n const url = getEntryUrl ? getEntryUrl(entry) : entry;\n return loadScript(url, {\n attrs: {},\n createScriptHook: (url, attrs) => {\n const res = loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n });\n\n if (!res) return;\n\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n\n if ('script' in res || 'timeout' in res) {\n return res;\n }\n\n return;\n },\n }).then(\n () => {\n // loadScript resolved: script was fetched, executed without throwing, and\n // did not trigger a ScriptExecutionError listener. Now verify the global was registered.\n return handleRemoteEntryLoaded(name, globalName, entry);\n },\n (loadError: unknown) => {\n // loadScript rejected — one of three causes, all with descriptive messages:\n // ScriptNetworkError — URL unreachable, 404, CORS, etc.\n // ScriptExecutionError — script fetched OK but IIFE threw during execution\n // timeout — script took too long to load\n // Errors thrown inside handleRemoteEntryLoaded above are NOT caught here.\n const originalMsg =\n loadError instanceof Error ? loadError.message : String(loadError);\n error(\n RUNTIME_008,\n runtimeDescMap,\n {\n remoteName: name,\n resourceUrl: url,\n },\n originalMsg,\n );\n },\n );\n}\nasync function loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n}: {\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n switch (type) {\n case 'esm':\n case 'module':\n return loadEsmEntry({ entry, remoteEntryExports });\n case 'system':\n return loadSystemJsEntry({ entry, remoteEntryExports });\n default:\n return loadEntryScript({\n entry,\n globalName,\n name,\n remoteInfo,\n loaderHook,\n getEntryUrl,\n });\n }\n}\n\nasync function loadEntryNode({\n remoteInfo,\n loaderHook,\n}: {\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n return loadScriptNode(entry, {\n attrs: { name, globalName, type },\n loaderHook: {\n createScriptHook: (url: string, attrs: Record<string, any> = {}) => {\n const res = loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n });\n\n if (!res) return;\n\n if ('url' in res) {\n return res;\n }\n\n return;\n },\n },\n })\n .then(() => {\n return handleRemoteEntryLoaded(name, globalName, entry);\n })\n .catch((e) => {\n const msg = e instanceof Error ? e.message : String(e);\n error(\n `Failed to load Node.js entry for remote \"${name}\" from \"${entry}\". ${msg}`,\n );\n });\n}\n\nexport function getRemoteEntryUniqueKey(remoteInfo: RemoteInfo): string {\n const { entry, name } = remoteInfo;\n return composeKeyWithSeparator(name, entry);\n}\n\nexport async function getRemoteEntry(params: {\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n getEntryUrl?: (url: string) => string;\n _inErrorHandling?: boolean; // Add flag to prevent recursion\n}): Promise<RemoteEntryExports | false | void> {\n const {\n origin,\n remoteEntryExports,\n remoteInfo,\n getEntryUrl,\n _inErrorHandling = false,\n } = params;\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n if (!globalLoading[uniqueKey]) {\n const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;\n const loaderHook = origin.loaderHook;\n\n globalLoading[uniqueKey] = loadEntryHook\n .emit({\n loaderHook,\n remoteInfo,\n remoteEntryExports,\n })\n .then((res) => {\n if (res) {\n return res;\n }\n // Use ENV_TARGET if defined, otherwise fallback to isBrowserEnvValue\n const isWebEnvironment =\n typeof ENV_TARGET !== 'undefined'\n ? ENV_TARGET === 'web'\n : isBrowserEnvValue;\n\n return isWebEnvironment\n ? loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n })\n : loadEntryNode({ remoteInfo, loaderHook });\n })\n .catch(async (err) => {\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n // ScriptExecutionError means the script downloaded fine but its IIFE\n // threw at runtime — retrying would reproduce the same error, so exclude it.\n const isScriptExecutionError =\n err instanceof Error && err.message.includes('ScriptExecutionError');\n const isScriptLoadError =\n err instanceof Error &&\n err.message.includes(RUNTIME_008) &&\n !isScriptExecutionError;\n\n if (isScriptLoadError && !_inErrorHandling) {\n const wrappedGetRemoteEntry = (\n params: Parameters<typeof getRemoteEntry>[0],\n ) => {\n return getRemoteEntry({ ...params, _inErrorHandling: true });\n };\n\n const RemoteEntryExports =\n await origin.loaderHook.lifecycle.loadEntryError.emit({\n getRemoteEntry: wrappedGetRemoteEntry,\n origin,\n remoteInfo: remoteInfo,\n remoteEntryExports,\n globalLoading,\n uniqueKey,\n });\n\n if (RemoteEntryExports) {\n return RemoteEntryExports;\n }\n }\n throw err;\n });\n }\n\n return globalLoading[uniqueKey];\n}\n\nexport function getRemoteInfo(remote: Remote): RemoteInfo {\n return {\n ...remote,\n entry: 'entry' in remote ? remote.entry : '',\n type: remote.type || DEFAULT_REMOTE_TYPE,\n entryGlobalName: remote.entryGlobalName || remote.name,\n shareScope: remote.shareScope || DEFAULT_SCOPE,\n };\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"load.cjs","names":["getRemoteEntryExports","RUNTIME_001","runtimeDescMap","RUNTIME_008","globalLoading","isBrowserEnvValue","DEFAULT_REMOTE_TYPE","DEFAULT_SCOPE"],"sources":["../../src/utils/load.ts"],"sourcesContent":["import {\n loadScript,\n loadScriptNode,\n composeKeyWithSeparator,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from '../constant';\nimport { ModuleFederation } from '../core';\nimport { globalLoading, getRemoteEntryExports } from '../global';\nimport {\n Remote,\n RemoteEntryExports,\n RemoteInfo,\n ResourceLoadContext,\n} from '../type';\nimport { assert, error } from './logger';\nimport {\n RUNTIME_001,\n RUNTIME_008,\n runtimeDescMap,\n} from '@module-federation/error-codes';\n\n// Declare the ENV_TARGET constant that will be defined by DefinePlugin\ndeclare const ENV_TARGET: 'web' | 'node';\nconst importCallback = '.then(callbacks[0]).catch(callbacks[1])';\n\nasync function loadEsmEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n if (typeof FEDERATION_ALLOW_NEW_FUNCTION !== 'undefined') {\n new Function('callbacks', `import(\"${entry}\")${importCallback}`)([\n resolve,\n reject,\n ]);\n } else {\n import(/* webpackIgnore: true */ /* @vite-ignore */ entry)\n .then(resolve)\n .catch(reject);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load ESM entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nasync function loadSystemJsEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n //@ts-ignore\n if (typeof __system_context__ === 'undefined') {\n //@ts-ignore\n System.import(entry).then(resolve).catch(reject);\n } else {\n new Function(\n 'callbacks',\n `System.import(\"${entry}\")${importCallback}`,\n )([resolve, reject]);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load SystemJS entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nfunction handleRemoteEntryLoaded(\n name: string,\n globalName: string,\n entry: string,\n): RemoteEntryExports {\n const { remoteEntryKey, entryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (!entryExports) {\n error(RUNTIME_001, runtimeDescMap, {\n remoteName: name,\n remoteEntryUrl: entry,\n remoteEntryKey,\n });\n }\n\n return entryExports;\n}\n\nasync function loadEntryScript({\n name,\n globalName,\n entry,\n remoteInfo,\n loaderHook,\n getEntryUrl,\n resourceContext,\n}: {\n name: string;\n globalName: string;\n entry: string;\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n resourceContext?: ResourceLoadContext;\n}): Promise<RemoteEntryExports> {\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n // if getEntryUrl is passed, use the getEntryUrl to get the entry url\n const url = getEntryUrl ? getEntryUrl(entry) : entry;\n return loadScript(url, {\n attrs: {},\n createScriptHook: (url, attrs) => {\n const res = loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n resourceContext: resourceContext\n ? {\n ...resourceContext,\n url,\n }\n : undefined,\n });\n\n if (!res) return;\n\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n\n if ('script' in res || 'timeout' in res) {\n return res;\n }\n\n return;\n },\n }).then(\n () => {\n // loadScript resolved: script was fetched, executed without throwing, and\n // did not trigger a ScriptExecutionError listener. Now verify the global was registered.\n return handleRemoteEntryLoaded(name, globalName, entry);\n },\n (loadError: unknown) => {\n // loadScript rejected — one of three causes, all with descriptive messages:\n // ScriptNetworkError — URL unreachable, 404, CORS, etc.\n // ScriptExecutionError — script fetched OK but IIFE threw during execution\n // timeout — script took too long to load\n // Errors thrown inside handleRemoteEntryLoaded above are NOT caught here.\n const originalMsg =\n loadError instanceof Error ? loadError.message : String(loadError);\n error(\n RUNTIME_008,\n runtimeDescMap,\n {\n remoteName: name,\n resourceUrl: url,\n },\n originalMsg,\n );\n },\n );\n}\nasync function loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n resourceContext,\n}: {\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n resourceContext?: ResourceLoadContext;\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n switch (type) {\n case 'esm':\n case 'module':\n return loadEsmEntry({ entry, remoteEntryExports });\n case 'system':\n return loadSystemJsEntry({ entry, remoteEntryExports });\n default:\n return loadEntryScript({\n entry,\n globalName,\n name,\n remoteInfo,\n loaderHook,\n getEntryUrl,\n resourceContext,\n });\n }\n}\n\nasync function loadEntryNode({\n remoteInfo,\n loaderHook,\n resourceContext,\n}: {\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n resourceContext?: ResourceLoadContext;\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n return loadScriptNode(entry, {\n attrs: { name, globalName, type },\n loaderHook: {\n createScriptHook: (url: string, attrs: Record<string, any> = {}) => {\n const res = loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n resourceContext: resourceContext\n ? {\n ...resourceContext,\n url,\n }\n : undefined,\n });\n\n if (!res) return;\n\n if ('url' in res) {\n return res;\n }\n\n return;\n },\n },\n })\n .then(() => {\n return handleRemoteEntryLoaded(name, globalName, entry);\n })\n .catch((e) => {\n const msg = e instanceof Error ? e.message : String(e);\n error(\n `Failed to load Node.js entry for remote \"${name}\" from \"${entry}\". ${msg}`,\n );\n });\n}\n\nexport function getRemoteEntryUniqueKey(remoteInfo: RemoteInfo): string {\n const { entry, name } = remoteInfo;\n return composeKeyWithSeparator(name, entry);\n}\n\nexport async function getRemoteEntry(params: {\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n getEntryUrl?: (url: string) => string;\n _inErrorHandling?: boolean; // Add flag to prevent recursion\n resourceContext?: ResourceLoadContext;\n}): Promise<RemoteEntryExports | false | void> {\n const {\n origin,\n remoteEntryExports,\n remoteInfo,\n getEntryUrl,\n resourceContext,\n _inErrorHandling = false,\n } = params;\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n if (!globalLoading[uniqueKey]) {\n const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;\n const loaderHook = origin.loaderHook;\n\n globalLoading[uniqueKey] = loadEntryHook\n .emit({\n origin,\n loaderHook,\n remoteInfo,\n remoteEntryExports,\n })\n .then((res) => {\n if (res) {\n return res;\n }\n // Use ENV_TARGET if defined, otherwise fallback to isBrowserEnvValue\n const isWebEnvironment =\n typeof ENV_TARGET !== 'undefined'\n ? ENV_TARGET === 'web'\n : isBrowserEnvValue;\n\n return isWebEnvironment\n ? loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n resourceContext,\n })\n : loadEntryNode({ remoteInfo, loaderHook, resourceContext });\n })\n .then(async (res) => {\n await origin.loaderHook.lifecycle.afterLoadEntry.emit({\n origin,\n remoteInfo,\n remoteEntryExports: res,\n });\n return res;\n })\n .catch(async (err) => {\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n // ScriptExecutionError means the script downloaded fine but its IIFE\n // threw at runtime — retrying would reproduce the same error, so exclude it.\n const isScriptExecutionError =\n err instanceof Error && err.message.includes('ScriptExecutionError');\n const isScriptLoadError =\n err instanceof Error &&\n err.message.includes(RUNTIME_008) &&\n !isScriptExecutionError;\n\n if (isScriptLoadError && !_inErrorHandling) {\n const wrappedGetRemoteEntry = (\n params: Parameters<typeof getRemoteEntry>[0],\n ) => {\n return getRemoteEntry({ ...params, _inErrorHandling: true });\n };\n\n const RemoteEntryExports =\n await origin.loaderHook.lifecycle.loadEntryError.emit({\n getRemoteEntry: wrappedGetRemoteEntry,\n origin,\n remoteInfo: remoteInfo,\n remoteEntryExports,\n globalLoading,\n uniqueKey,\n });\n\n if (RemoteEntryExports) {\n await origin.loaderHook.lifecycle.afterLoadEntry.emit({\n origin,\n remoteInfo,\n remoteEntryExports: RemoteEntryExports,\n recovered: true,\n });\n return RemoteEntryExports;\n }\n }\n await origin.loaderHook.lifecycle.afterLoadEntry.emit({\n origin,\n remoteInfo,\n error: err,\n });\n throw err;\n });\n }\n\n return globalLoading[uniqueKey];\n}\n\nexport function getRemoteInfo(remote: Remote): RemoteInfo {\n return {\n ...remote,\n entry: 'entry' in remote ? remote.entry : '',\n type: remote.type || DEFAULT_REMOTE_TYPE,\n entryGlobalName: remote.entryGlobalName || remote.name,\n shareScope: remote.shareScope || DEFAULT_SCOPE,\n };\n}\n"],"mappings":"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"} |
| import { ModuleFederation } from "../core.js"; | ||
| import { Remote, RemoteEntryExports, RemoteInfo } from "../type/config.js"; | ||
| import { ResourceLoadContext } from "../type/preload.js"; | ||
| //#region src/utils/load.d.ts | ||
@@ -10,2 +11,3 @@ declare function getRemoteEntry(params: { | ||
| _inErrorHandling?: boolean; | ||
| resourceContext?: ResourceLoadContext; | ||
| }): Promise<RemoteEntryExports | false | void>; | ||
@@ -12,0 +14,0 @@ declare function getRemoteInfo(remote: Remote): RemoteInfo; |
+42
-10
@@ -44,3 +44,3 @@ import { error } from "./logger.js"; | ||
| } | ||
| async function loadEntryScript({ name, globalName, entry, remoteInfo, loaderHook, getEntryUrl }) { | ||
| async function loadEntryScript({ name, globalName, entry, remoteInfo, loaderHook, getEntryUrl, resourceContext }) { | ||
| const { entryExports: remoteEntryExports } = getRemoteEntryExports(name, globalName); | ||
@@ -55,3 +55,7 @@ if (remoteEntryExports) return remoteEntryExports; | ||
| attrs, | ||
| remoteInfo | ||
| remoteInfo, | ||
| resourceContext: resourceContext ? { | ||
| ...resourceContext, | ||
| url | ||
| } : void 0 | ||
| }); | ||
@@ -72,3 +76,3 @@ if (!res) return; | ||
| } | ||
| async function loadEntryDom({ remoteInfo, remoteEntryExports, loaderHook, getEntryUrl }) { | ||
| async function loadEntryDom({ remoteInfo, remoteEntryExports, loaderHook, getEntryUrl, resourceContext }) { | ||
| const { entry, entryGlobalName: globalName, name, type } = remoteInfo; | ||
@@ -91,7 +95,8 @@ switch (type) { | ||
| loaderHook, | ||
| getEntryUrl | ||
| getEntryUrl, | ||
| resourceContext | ||
| }); | ||
| } | ||
| } | ||
| async function loadEntryNode({ remoteInfo, loaderHook }) { | ||
| async function loadEntryNode({ remoteInfo, loaderHook, resourceContext }) { | ||
| const { entry, entryGlobalName: globalName, name, type } = remoteInfo; | ||
@@ -110,3 +115,7 @@ const { entryExports: remoteEntryExports } = getRemoteEntryExports(name, globalName); | ||
| attrs, | ||
| remoteInfo | ||
| remoteInfo, | ||
| resourceContext: resourceContext ? { | ||
| ...resourceContext, | ||
| url | ||
| } : void 0 | ||
| }); | ||
@@ -127,3 +136,3 @@ if (!res) return; | ||
| async function getRemoteEntry(params) { | ||
| const { origin, remoteEntryExports, remoteInfo, getEntryUrl, _inErrorHandling = false } = params; | ||
| const { origin, remoteEntryExports, remoteInfo, getEntryUrl, resourceContext, _inErrorHandling = false } = params; | ||
| const uniqueKey = getRemoteEntryUniqueKey(remoteInfo); | ||
@@ -135,2 +144,3 @@ if (remoteEntryExports) return remoteEntryExports; | ||
| globalLoading[uniqueKey] = loadEntryHook.emit({ | ||
| origin, | ||
| loaderHook, | ||
@@ -145,7 +155,16 @@ remoteInfo, | ||
| loaderHook, | ||
| getEntryUrl | ||
| getEntryUrl, | ||
| resourceContext | ||
| }) : loadEntryNode({ | ||
| remoteInfo, | ||
| loaderHook | ||
| loaderHook, | ||
| resourceContext | ||
| }); | ||
| }).then(async (res) => { | ||
| await origin.loaderHook.lifecycle.afterLoadEntry.emit({ | ||
| origin, | ||
| remoteInfo, | ||
| remoteEntryExports: res | ||
| }); | ||
| return res; | ||
| }).catch(async (err) => { | ||
@@ -169,4 +188,17 @@ const uniqueKey = getRemoteEntryUniqueKey(remoteInfo); | ||
| }); | ||
| if (RemoteEntryExports) return RemoteEntryExports; | ||
| if (RemoteEntryExports) { | ||
| await origin.loaderHook.lifecycle.afterLoadEntry.emit({ | ||
| origin, | ||
| remoteInfo, | ||
| remoteEntryExports: RemoteEntryExports, | ||
| recovered: true | ||
| }); | ||
| return RemoteEntryExports; | ||
| } | ||
| } | ||
| await origin.loaderHook.lifecycle.afterLoadEntry.emit({ | ||
| origin, | ||
| remoteInfo, | ||
| error: err | ||
| }); | ||
| throw err; | ||
@@ -173,0 +205,0 @@ }); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"load.js","names":[],"sources":["../../src/utils/load.ts"],"sourcesContent":["import {\n loadScript,\n loadScriptNode,\n composeKeyWithSeparator,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from '../constant';\nimport { ModuleFederation } from '../core';\nimport { globalLoading, getRemoteEntryExports } from '../global';\nimport { Remote, RemoteEntryExports, RemoteInfo } from '../type';\nimport { assert, error } from './logger';\nimport {\n RUNTIME_001,\n RUNTIME_008,\n runtimeDescMap,\n} from '@module-federation/error-codes';\n\n// Declare the ENV_TARGET constant that will be defined by DefinePlugin\ndeclare const ENV_TARGET: 'web' | 'node';\nconst importCallback = '.then(callbacks[0]).catch(callbacks[1])';\n\nasync function loadEsmEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n if (typeof FEDERATION_ALLOW_NEW_FUNCTION !== 'undefined') {\n new Function('callbacks', `import(\"${entry}\")${importCallback}`)([\n resolve,\n reject,\n ]);\n } else {\n import(/* webpackIgnore: true */ /* @vite-ignore */ entry)\n .then(resolve)\n .catch(reject);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load ESM entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nasync function loadSystemJsEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n //@ts-ignore\n if (typeof __system_context__ === 'undefined') {\n //@ts-ignore\n System.import(entry).then(resolve).catch(reject);\n } else {\n new Function(\n 'callbacks',\n `System.import(\"${entry}\")${importCallback}`,\n )([resolve, reject]);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load SystemJS entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nfunction handleRemoteEntryLoaded(\n name: string,\n globalName: string,\n entry: string,\n): RemoteEntryExports {\n const { remoteEntryKey, entryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (!entryExports) {\n error(RUNTIME_001, runtimeDescMap, {\n remoteName: name,\n remoteEntryUrl: entry,\n remoteEntryKey,\n });\n }\n\n return entryExports;\n}\n\nasync function loadEntryScript({\n name,\n globalName,\n entry,\n remoteInfo,\n loaderHook,\n getEntryUrl,\n}: {\n name: string;\n globalName: string;\n entry: string;\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n}): Promise<RemoteEntryExports> {\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n // if getEntryUrl is passed, use the getEntryUrl to get the entry url\n const url = getEntryUrl ? getEntryUrl(entry) : entry;\n return loadScript(url, {\n attrs: {},\n createScriptHook: (url, attrs) => {\n const res = loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n });\n\n if (!res) return;\n\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n\n if ('script' in res || 'timeout' in res) {\n return res;\n }\n\n return;\n },\n }).then(\n () => {\n // loadScript resolved: script was fetched, executed without throwing, and\n // did not trigger a ScriptExecutionError listener. Now verify the global was registered.\n return handleRemoteEntryLoaded(name, globalName, entry);\n },\n (loadError: unknown) => {\n // loadScript rejected — one of three causes, all with descriptive messages:\n // ScriptNetworkError — URL unreachable, 404, CORS, etc.\n // ScriptExecutionError — script fetched OK but IIFE threw during execution\n // timeout — script took too long to load\n // Errors thrown inside handleRemoteEntryLoaded above are NOT caught here.\n const originalMsg =\n loadError instanceof Error ? loadError.message : String(loadError);\n error(\n RUNTIME_008,\n runtimeDescMap,\n {\n remoteName: name,\n resourceUrl: url,\n },\n originalMsg,\n );\n },\n );\n}\nasync function loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n}: {\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n switch (type) {\n case 'esm':\n case 'module':\n return loadEsmEntry({ entry, remoteEntryExports });\n case 'system':\n return loadSystemJsEntry({ entry, remoteEntryExports });\n default:\n return loadEntryScript({\n entry,\n globalName,\n name,\n remoteInfo,\n loaderHook,\n getEntryUrl,\n });\n }\n}\n\nasync function loadEntryNode({\n remoteInfo,\n loaderHook,\n}: {\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n return loadScriptNode(entry, {\n attrs: { name, globalName, type },\n loaderHook: {\n createScriptHook: (url: string, attrs: Record<string, any> = {}) => {\n const res = loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n });\n\n if (!res) return;\n\n if ('url' in res) {\n return res;\n }\n\n return;\n },\n },\n })\n .then(() => {\n return handleRemoteEntryLoaded(name, globalName, entry);\n })\n .catch((e) => {\n const msg = e instanceof Error ? e.message : String(e);\n error(\n `Failed to load Node.js entry for remote \"${name}\" from \"${entry}\". ${msg}`,\n );\n });\n}\n\nexport function getRemoteEntryUniqueKey(remoteInfo: RemoteInfo): string {\n const { entry, name } = remoteInfo;\n return composeKeyWithSeparator(name, entry);\n}\n\nexport async function getRemoteEntry(params: {\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n getEntryUrl?: (url: string) => string;\n _inErrorHandling?: boolean; // Add flag to prevent recursion\n}): Promise<RemoteEntryExports | false | void> {\n const {\n origin,\n remoteEntryExports,\n remoteInfo,\n getEntryUrl,\n _inErrorHandling = false,\n } = params;\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n if (!globalLoading[uniqueKey]) {\n const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;\n const loaderHook = origin.loaderHook;\n\n globalLoading[uniqueKey] = loadEntryHook\n .emit({\n loaderHook,\n remoteInfo,\n remoteEntryExports,\n })\n .then((res) => {\n if (res) {\n return res;\n }\n // Use ENV_TARGET if defined, otherwise fallback to isBrowserEnvValue\n const isWebEnvironment =\n typeof ENV_TARGET !== 'undefined'\n ? ENV_TARGET === 'web'\n : isBrowserEnvValue;\n\n return isWebEnvironment\n ? loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n })\n : loadEntryNode({ remoteInfo, loaderHook });\n })\n .catch(async (err) => {\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n // ScriptExecutionError means the script downloaded fine but its IIFE\n // threw at runtime — retrying would reproduce the same error, so exclude it.\n const isScriptExecutionError =\n err instanceof Error && err.message.includes('ScriptExecutionError');\n const isScriptLoadError =\n err instanceof Error &&\n err.message.includes(RUNTIME_008) &&\n !isScriptExecutionError;\n\n if (isScriptLoadError && !_inErrorHandling) {\n const wrappedGetRemoteEntry = (\n params: Parameters<typeof getRemoteEntry>[0],\n ) => {\n return getRemoteEntry({ ...params, _inErrorHandling: true });\n };\n\n const RemoteEntryExports =\n await origin.loaderHook.lifecycle.loadEntryError.emit({\n getRemoteEntry: wrappedGetRemoteEntry,\n origin,\n remoteInfo: remoteInfo,\n remoteEntryExports,\n globalLoading,\n uniqueKey,\n });\n\n if (RemoteEntryExports) {\n return RemoteEntryExports;\n }\n }\n throw err;\n });\n }\n\n return globalLoading[uniqueKey];\n}\n\nexport function getRemoteInfo(remote: Remote): RemoteInfo {\n return {\n ...remote,\n entry: 'entry' in remote ? remote.entry : '',\n type: remote.type || DEFAULT_REMOTE_TYPE,\n entryGlobalName: remote.entryGlobalName || remote.name,\n shareScope: remote.shareScope || DEFAULT_SCOPE,\n };\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"load.js","names":[],"sources":["../../src/utils/load.ts"],"sourcesContent":["import {\n loadScript,\n loadScriptNode,\n composeKeyWithSeparator,\n isBrowserEnvValue,\n} from '@module-federation/sdk';\nimport { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from '../constant';\nimport { ModuleFederation } from '../core';\nimport { globalLoading, getRemoteEntryExports } from '../global';\nimport {\n Remote,\n RemoteEntryExports,\n RemoteInfo,\n ResourceLoadContext,\n} from '../type';\nimport { assert, error } from './logger';\nimport {\n RUNTIME_001,\n RUNTIME_008,\n runtimeDescMap,\n} from '@module-federation/error-codes';\n\n// Declare the ENV_TARGET constant that will be defined by DefinePlugin\ndeclare const ENV_TARGET: 'web' | 'node';\nconst importCallback = '.then(callbacks[0]).catch(callbacks[1])';\n\nasync function loadEsmEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n if (typeof FEDERATION_ALLOW_NEW_FUNCTION !== 'undefined') {\n new Function('callbacks', `import(\"${entry}\")${importCallback}`)([\n resolve,\n reject,\n ]);\n } else {\n import(/* webpackIgnore: true */ /* @vite-ignore */ entry)\n .then(resolve)\n .catch(reject);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load ESM entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nasync function loadSystemJsEntry({\n entry,\n remoteEntryExports,\n}: {\n entry: string;\n remoteEntryExports: RemoteEntryExports | undefined;\n}): Promise<RemoteEntryExports> {\n return new Promise<RemoteEntryExports>((resolve, reject) => {\n try {\n if (!remoteEntryExports) {\n //@ts-ignore\n if (typeof __system_context__ === 'undefined') {\n //@ts-ignore\n System.import(entry).then(resolve).catch(reject);\n } else {\n new Function(\n 'callbacks',\n `System.import(\"${entry}\")${importCallback}`,\n )([resolve, reject]);\n }\n } else {\n resolve(remoteEntryExports);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n error(`Failed to load SystemJS entry from \"${entry}\". ${msg}`);\n }\n });\n}\n\nfunction handleRemoteEntryLoaded(\n name: string,\n globalName: string,\n entry: string,\n): RemoteEntryExports {\n const { remoteEntryKey, entryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (!entryExports) {\n error(RUNTIME_001, runtimeDescMap, {\n remoteName: name,\n remoteEntryUrl: entry,\n remoteEntryKey,\n });\n }\n\n return entryExports;\n}\n\nasync function loadEntryScript({\n name,\n globalName,\n entry,\n remoteInfo,\n loaderHook,\n getEntryUrl,\n resourceContext,\n}: {\n name: string;\n globalName: string;\n entry: string;\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n resourceContext?: ResourceLoadContext;\n}): Promise<RemoteEntryExports> {\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n // if getEntryUrl is passed, use the getEntryUrl to get the entry url\n const url = getEntryUrl ? getEntryUrl(entry) : entry;\n return loadScript(url, {\n attrs: {},\n createScriptHook: (url, attrs) => {\n const res = loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n resourceContext: resourceContext\n ? {\n ...resourceContext,\n url,\n }\n : undefined,\n });\n\n if (!res) return;\n\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n\n if ('script' in res || 'timeout' in res) {\n return res;\n }\n\n return;\n },\n }).then(\n () => {\n // loadScript resolved: script was fetched, executed without throwing, and\n // did not trigger a ScriptExecutionError listener. Now verify the global was registered.\n return handleRemoteEntryLoaded(name, globalName, entry);\n },\n (loadError: unknown) => {\n // loadScript rejected — one of three causes, all with descriptive messages:\n // ScriptNetworkError — URL unreachable, 404, CORS, etc.\n // ScriptExecutionError — script fetched OK but IIFE threw during execution\n // timeout — script took too long to load\n // Errors thrown inside handleRemoteEntryLoaded above are NOT caught here.\n const originalMsg =\n loadError instanceof Error ? loadError.message : String(loadError);\n error(\n RUNTIME_008,\n runtimeDescMap,\n {\n remoteName: name,\n resourceUrl: url,\n },\n originalMsg,\n );\n },\n );\n}\nasync function loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n resourceContext,\n}: {\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports;\n loaderHook: ModuleFederation['loaderHook'];\n getEntryUrl?: (url: string) => string;\n resourceContext?: ResourceLoadContext;\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n switch (type) {\n case 'esm':\n case 'module':\n return loadEsmEntry({ entry, remoteEntryExports });\n case 'system':\n return loadSystemJsEntry({ entry, remoteEntryExports });\n default:\n return loadEntryScript({\n entry,\n globalName,\n name,\n remoteInfo,\n loaderHook,\n getEntryUrl,\n resourceContext,\n });\n }\n}\n\nasync function loadEntryNode({\n remoteInfo,\n loaderHook,\n resourceContext,\n}: {\n remoteInfo: RemoteInfo;\n loaderHook: ModuleFederation['loaderHook'];\n resourceContext?: ResourceLoadContext;\n}) {\n const { entry, entryGlobalName: globalName, name, type } = remoteInfo;\n const { entryExports: remoteEntryExports } = getRemoteEntryExports(\n name,\n globalName,\n );\n\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n return loadScriptNode(entry, {\n attrs: { name, globalName, type },\n loaderHook: {\n createScriptHook: (url: string, attrs: Record<string, any> = {}) => {\n const res = loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n resourceContext: resourceContext\n ? {\n ...resourceContext,\n url,\n }\n : undefined,\n });\n\n if (!res) return;\n\n if ('url' in res) {\n return res;\n }\n\n return;\n },\n },\n })\n .then(() => {\n return handleRemoteEntryLoaded(name, globalName, entry);\n })\n .catch((e) => {\n const msg = e instanceof Error ? e.message : String(e);\n error(\n `Failed to load Node.js entry for remote \"${name}\" from \"${entry}\". ${msg}`,\n );\n });\n}\n\nexport function getRemoteEntryUniqueKey(remoteInfo: RemoteInfo): string {\n const { entry, name } = remoteInfo;\n return composeKeyWithSeparator(name, entry);\n}\n\nexport async function getRemoteEntry(params: {\n origin: ModuleFederation;\n remoteInfo: RemoteInfo;\n remoteEntryExports?: RemoteEntryExports | undefined;\n getEntryUrl?: (url: string) => string;\n _inErrorHandling?: boolean; // Add flag to prevent recursion\n resourceContext?: ResourceLoadContext;\n}): Promise<RemoteEntryExports | false | void> {\n const {\n origin,\n remoteEntryExports,\n remoteInfo,\n getEntryUrl,\n resourceContext,\n _inErrorHandling = false,\n } = params;\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n if (remoteEntryExports) {\n return remoteEntryExports;\n }\n\n if (!globalLoading[uniqueKey]) {\n const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;\n const loaderHook = origin.loaderHook;\n\n globalLoading[uniqueKey] = loadEntryHook\n .emit({\n origin,\n loaderHook,\n remoteInfo,\n remoteEntryExports,\n })\n .then((res) => {\n if (res) {\n return res;\n }\n // Use ENV_TARGET if defined, otherwise fallback to isBrowserEnvValue\n const isWebEnvironment =\n typeof ENV_TARGET !== 'undefined'\n ? ENV_TARGET === 'web'\n : isBrowserEnvValue;\n\n return isWebEnvironment\n ? loadEntryDom({\n remoteInfo,\n remoteEntryExports,\n loaderHook,\n getEntryUrl,\n resourceContext,\n })\n : loadEntryNode({ remoteInfo, loaderHook, resourceContext });\n })\n .then(async (res) => {\n await origin.loaderHook.lifecycle.afterLoadEntry.emit({\n origin,\n remoteInfo,\n remoteEntryExports: res,\n });\n return res;\n })\n .catch(async (err) => {\n const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);\n // ScriptExecutionError means the script downloaded fine but its IIFE\n // threw at runtime — retrying would reproduce the same error, so exclude it.\n const isScriptExecutionError =\n err instanceof Error && err.message.includes('ScriptExecutionError');\n const isScriptLoadError =\n err instanceof Error &&\n err.message.includes(RUNTIME_008) &&\n !isScriptExecutionError;\n\n if (isScriptLoadError && !_inErrorHandling) {\n const wrappedGetRemoteEntry = (\n params: Parameters<typeof getRemoteEntry>[0],\n ) => {\n return getRemoteEntry({ ...params, _inErrorHandling: true });\n };\n\n const RemoteEntryExports =\n await origin.loaderHook.lifecycle.loadEntryError.emit({\n getRemoteEntry: wrappedGetRemoteEntry,\n origin,\n remoteInfo: remoteInfo,\n remoteEntryExports,\n globalLoading,\n uniqueKey,\n });\n\n if (RemoteEntryExports) {\n await origin.loaderHook.lifecycle.afterLoadEntry.emit({\n origin,\n remoteInfo,\n remoteEntryExports: RemoteEntryExports,\n recovered: true,\n });\n return RemoteEntryExports;\n }\n }\n await origin.loaderHook.lifecycle.afterLoadEntry.emit({\n origin,\n remoteInfo,\n error: err,\n });\n throw err;\n });\n }\n\n return globalLoading[uniqueKey];\n}\n\nexport function getRemoteInfo(remote: Remote): RemoteInfo {\n return {\n ...remote,\n entry: 'entry' in remote ? remote.entry : '',\n type: remote.type || DEFAULT_REMOTE_TYPE,\n entryGlobalName: remote.entryGlobalName || remote.name,\n shareScope: remote.shareScope || DEFAULT_SCOPE,\n };\n}\n"],"mappings":";;;;;;;AAwBA,MAAM,iBAAiB;AAEvB,eAAe,aAAa,EAC1B,OACA,sBAI8B;AAC9B,QAAO,IAAI,SAA6B,SAAS,WAAW;AAC1D,MAAI;AACF,OAAI,CAAC,mBACH,KAAI,OAAO,kCAAkC,YAC3C,KAAI,SAAS,aAAa,WAAW,MAAM,IAAI,iBAAiB,CAAC,CAC/D,SACA,OACD,CAAC;OAEF;;;IAAoD;EACjD,KAAK,QAAQ,CACb,MAAM,OAAO;OAGlB,SAAQ,mBAAmB;WAEtB,GAAG;AAEV,SAAM,kCAAkC,MAAM,KADlC,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE,GACG;;GAE3D;;AAGJ,eAAe,kBAAkB,EAC/B,OACA,sBAI8B;AAC9B,QAAO,IAAI,SAA6B,SAAS,WAAW;AAC1D,MAAI;AACF,OAAI,CAAC,mBAEH,KAAI,OAAO,uBAAuB,YAEhC,QAAO,OAAO,MAAM,CAAC,KAAK,QAAQ,CAAC,MAAM,OAAO;OAEhD,KAAI,SACF,aACA,kBAAkB,MAAM,IAAI,iBAC7B,CAAC,CAAC,SAAS,OAAO,CAAC;OAGtB,SAAQ,mBAAmB;WAEtB,GAAG;AAEV,SAAM,uCAAuC,MAAM,KADvC,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE,GACQ;;GAEhE;;AAGJ,SAAS,wBACP,MACA,YACA,OACoB;CACpB,MAAM,EAAE,gBAAgB,iBAAiB,sBACvC,MACA,WACD;AAED,KAAI,CAAC,aACH,OAAM,aAAa,gBAAgB;EACjC,YAAY;EACZ,gBAAgB;EAChB;EACD,CAAC;AAGJ,QAAO;;AAGT,eAAe,gBAAgB,EAC7B,MACA,YACA,OACA,YACA,YACA,aACA,mBAS8B;CAC9B,MAAM,EAAE,cAAc,uBAAuB,sBAC3C,MACA,WACD;AAED,KAAI,mBACF,QAAO;CAIT,MAAM,MAAM,cAAc,YAAY,MAAM,GAAG;AAC/C,QAAO,WAAW,KAAK;EACrB,OAAO,EAAE;EACT,mBAAmB,KAAK,UAAU;GAChC,MAAM,MAAM,WAAW,UAAU,aAAa,KAAK;IACjD;IACA;IACA;IACA,iBAAiB,kBACb;KACE,GAAG;KACH;KACD,GACD;IACL,CAAC;AAEF,OAAI,CAAC,IAAK;AAEV,OAAI,eAAe,kBACjB,QAAO;AAGT,OAAI,YAAY,OAAO,aAAa,IAClC,QAAO;;EAKZ,CAAC,CAAC,WACK;AAGJ,SAAO,wBAAwB,MAAM,YAAY,MAAM;KAExD,cAAuB;EAMtB,MAAM,cACJ,qBAAqB,QAAQ,UAAU,UAAU,OAAO,UAAU;AACpE,QACE,aACA,gBACA;GACE,YAAY;GACZ,aAAa;GACd,EACD,YACD;GAEJ;;AAEH,eAAe,aAAa,EAC1B,YACA,oBACA,YACA,aACA,mBAOC;CACD,MAAM,EAAE,OAAO,iBAAiB,YAAY,MAAM,SAAS;AAC3D,SAAQ,MAAR;EACE,KAAK;EACL,KAAK,SACH,QAAO,aAAa;GAAE;GAAO;GAAoB,CAAC;EACpD,KAAK,SACH,QAAO,kBAAkB;GAAE;GAAO;GAAoB,CAAC;EACzD,QACE,QAAO,gBAAgB;GACrB;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;;;AAIR,eAAe,cAAc,EAC3B,YACA,YACA,mBAKC;CACD,MAAM,EAAE,OAAO,iBAAiB,YAAY,MAAM,SAAS;CAC3D,MAAM,EAAE,cAAc,uBAAuB,sBAC3C,MACA,WACD;AAED,KAAI,mBACF,QAAO;AAGT,QAAO,eAAe,OAAO;EAC3B,OAAO;GAAE;GAAM;GAAY;GAAM;EACjC,YAAY,EACV,mBAAmB,KAAa,QAA6B,EAAE,KAAK;GAClE,MAAM,MAAM,WAAW,UAAU,aAAa,KAAK;IACjD;IACA;IACA;IACA,iBAAiB,kBACb;KACE,GAAG;KACH;KACD,GACD;IACL,CAAC;AAEF,OAAI,CAAC,IAAK;AAEV,OAAI,SAAS,IACX,QAAO;KAKZ;EACF,CAAC,CACC,WAAW;AACV,SAAO,wBAAwB,MAAM,YAAY,MAAM;GACvD,CACD,OAAO,MAAM;AAEZ,QACE,4CAA4C,KAAK,UAAU,MAAM,KAFvD,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE,GAGrD;GACD;;AAGN,SAAgB,wBAAwB,YAAgC;CACtE,MAAM,EAAE,OAAO,SAAS;AACxB,QAAO,wBAAwB,MAAM,MAAM;;AAG7C,eAAsB,eAAe,QAOU;CAC7C,MAAM,EACJ,QACA,oBACA,YACA,aACA,iBACA,mBAAmB,UACjB;CACJ,MAAM,YAAY,wBAAwB,WAAW;AACrD,KAAI,mBACF,QAAO;AAGT,KAAI,CAAC,cAAc,YAAY;EAC7B,MAAM,gBAAgB,OAAO,cAAc,MAAM,UAAU;EAC3D,MAAM,aAAa,OAAO;AAE1B,gBAAc,aAAa,cACxB,KAAK;GACJ;GACA;GACA;GACA;GACD,CAAC,CACD,MAAM,QAAQ;AACb,OAAI,IACF,QAAO;AAQT,WAJE,OAAO,eAAe,cAClB,eAAe,QACf,qBAGF,aAAa;IACX;IACA;IACA;IACA;IACA;IACD,CAAC,GACF,cAAc;IAAE;IAAY;IAAY;IAAiB,CAAC;IAC9D,CACD,KAAK,OAAO,QAAQ;AACnB,SAAM,OAAO,WAAW,UAAU,eAAe,KAAK;IACpD;IACA;IACA,oBAAoB;IACrB,CAAC;AACF,UAAO;IACP,CACD,MAAM,OAAO,QAAQ;GACpB,MAAM,YAAY,wBAAwB,WAAW;GAGrD,MAAM,yBACJ,eAAe,SAAS,IAAI,QAAQ,SAAS,uBAAuB;AAMtE,OAJE,eAAe,SACf,IAAI,QAAQ,SAAS,YAAY,IACjC,CAAC,0BAEsB,CAAC,kBAAkB;IAC1C,MAAM,yBACJ,WACG;AACH,YAAO,eAAe;MAAE,GAAG;MAAQ,kBAAkB;MAAM,CAAC;;IAG9D,MAAM,qBACJ,MAAM,OAAO,WAAW,UAAU,eAAe,KAAK;KACpD,gBAAgB;KAChB;KACY;KACZ;KACA;KACA;KACD,CAAC;AAEJ,QAAI,oBAAoB;AACtB,WAAM,OAAO,WAAW,UAAU,eAAe,KAAK;MACpD;MACA;MACA,oBAAoB;MACpB,WAAW;MACZ,CAAC;AACF,YAAO;;;AAGX,SAAM,OAAO,WAAW,UAAU,eAAe,KAAK;IACpD;IACA;IACA,OAAO;IACR,CAAC;AACF,SAAM;IACN;;AAGN,QAAO,cAAc;;AAGvB,SAAgB,cAAc,QAA4B;AACxD,QAAO;EACL,GAAG;EACH,OAAO,WAAW,SAAS,OAAO,QAAQ;EAC1C,MAAM,OAAO,QAAQ;EACrB,iBAAiB,OAAO,mBAAmB,OAAO;EAClD,YAAY,OAAO,cAAc;EAClC"} |
| //#region src/utils/manifest.ts | ||
| function composeRemoteRequestId(remoteName, expose) { | ||
| if (!expose || expose === ".") return remoteName; | ||
| return `${remoteName}/${expose.replace(/^\.\//, "")}`; | ||
| } | ||
| function matchRemoteWithNameAndExpose(remotes, id) { | ||
@@ -49,4 +53,5 @@ for (const remote of remotes) { | ||
| //#endregion | ||
| exports.composeRemoteRequestId = composeRemoteRequestId; | ||
| exports.matchRemote = matchRemote; | ||
| exports.matchRemoteWithNameAndExpose = matchRemoteWithNameAndExpose; | ||
| //# sourceMappingURL=manifest.cjs.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"manifest.cjs","names":[],"sources":["../../src/utils/manifest.ts"],"sourcesContent":["import { Remote } from '../type';\n\n// Function to match a remote with its name and expose\n// id: pkgName(@federation/app1) + expose(button) = @federation/app1/button\n// id: alias(app1) + expose(button) = app1/button\n// id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort\nexport function matchRemoteWithNameAndExpose(\n remotes: Array<Remote>,\n id: string,\n):\n | {\n pkgNameOrAlias: string;\n expose: string;\n remote: Remote;\n }\n | undefined {\n for (const remote of remotes) {\n // match pkgName\n const isNameMatched = id.startsWith(remote.name);\n let expose = id.replace(remote.name, '');\n if (isNameMatched) {\n if (expose.startsWith('/')) {\n const pkgNameOrAlias = remote.name;\n expose = `.${expose}`;\n return {\n pkgNameOrAlias,\n expose,\n remote,\n };\n } else if (expose === '') {\n return {\n pkgNameOrAlias: remote.name,\n expose: '.',\n remote,\n };\n }\n }\n\n // match alias\n const isAliasMatched = remote.alias && id.startsWith(remote.alias);\n let exposeWithAlias = remote.alias && id.replace(remote.alias, '');\n if (remote.alias && isAliasMatched) {\n if (exposeWithAlias && exposeWithAlias.startsWith('/')) {\n const pkgNameOrAlias = remote.alias;\n exposeWithAlias = `.${exposeWithAlias}`;\n return {\n pkgNameOrAlias,\n expose: exposeWithAlias,\n remote,\n };\n } else if (exposeWithAlias === '') {\n return {\n pkgNameOrAlias: remote.alias,\n expose: '.',\n remote,\n };\n }\n }\n }\n\n return;\n}\n\n// Function to match a remote with its name or alias\nexport function matchRemote(\n remotes: Array<Remote>,\n nameOrAlias: string,\n): Remote | undefined {\n for (const remote of remotes) {\n const isNameMatched = nameOrAlias === remote.name;\n if (isNameMatched) {\n return remote;\n }\n\n const isAliasMatched = remote.alias && nameOrAlias === remote.alias;\n if (isAliasMatched) {\n return remote;\n }\n }\n return;\n}\n"],"mappings":";;AAMA,SAAgB,6BACd,SACA,IAOY;AACZ,MAAK,MAAM,UAAU,SAAS;EAE5B,MAAM,gBAAgB,GAAG,WAAW,OAAO,KAAK;EAChD,IAAI,SAAS,GAAG,QAAQ,OAAO,MAAM,GAAG;AACxC,MAAI,eACF;OAAI,OAAO,WAAW,IAAI,EAAE;IAC1B,MAAM,iBAAiB,OAAO;AAC9B,aAAS,IAAI;AACb,WAAO;KACL;KACA;KACA;KACD;cACQ,WAAW,GACpB,QAAO;IACL,gBAAgB,OAAO;IACvB,QAAQ;IACR;IACD;;EAKL,MAAM,iBAAiB,OAAO,SAAS,GAAG,WAAW,OAAO,MAAM;EAClE,IAAI,kBAAkB,OAAO,SAAS,GAAG,QAAQ,OAAO,OAAO,GAAG;AAClE,MAAI,OAAO,SAAS,gBAClB;OAAI,mBAAmB,gBAAgB,WAAW,IAAI,EAAE;IACtD,MAAM,iBAAiB,OAAO;AAC9B,sBAAkB,IAAI;AACtB,WAAO;KACL;KACA,QAAQ;KACR;KACD;cACQ,oBAAoB,GAC7B,QAAO;IACL,gBAAgB,OAAO;IACvB,QAAQ;IACR;IACD;;;;AAST,SAAgB,YACd,SACA,aACoB;AACpB,MAAK,MAAM,UAAU,SAAS;AAE5B,MADsB,gBAAgB,OAAO,KAE3C,QAAO;AAIT,MADuB,OAAO,SAAS,gBAAgB,OAAO,MAE5D,QAAO"} | ||
| {"version":3,"file":"manifest.cjs","names":[],"sources":["../../src/utils/manifest.ts"],"sourcesContent":["import { Remote } from '../type';\n\nexport function composeRemoteRequestId(\n remoteName: string,\n expose?: string,\n): string {\n if (!expose || expose === '.') {\n return remoteName;\n }\n\n return `${remoteName}/${expose.replace(/^\\.\\//, '')}`;\n}\n\n// Function to match a remote with its name and expose\n// id: pkgName(@federation/app1) + expose(button) = @federation/app1/button\n// id: alias(app1) + expose(button) = app1/button\n// id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort\nexport function matchRemoteWithNameAndExpose(\n remotes: Array<Remote>,\n id: string,\n):\n | {\n pkgNameOrAlias: string;\n expose: string;\n remote: Remote;\n }\n | undefined {\n for (const remote of remotes) {\n // match pkgName\n const isNameMatched = id.startsWith(remote.name);\n let expose = id.replace(remote.name, '');\n if (isNameMatched) {\n if (expose.startsWith('/')) {\n const pkgNameOrAlias = remote.name;\n expose = `.${expose}`;\n return {\n pkgNameOrAlias,\n expose,\n remote,\n };\n } else if (expose === '') {\n return {\n pkgNameOrAlias: remote.name,\n expose: '.',\n remote,\n };\n }\n }\n\n // match alias\n const isAliasMatched = remote.alias && id.startsWith(remote.alias);\n let exposeWithAlias = remote.alias && id.replace(remote.alias, '');\n if (remote.alias && isAliasMatched) {\n if (exposeWithAlias && exposeWithAlias.startsWith('/')) {\n const pkgNameOrAlias = remote.alias;\n exposeWithAlias = `.${exposeWithAlias}`;\n return {\n pkgNameOrAlias,\n expose: exposeWithAlias,\n remote,\n };\n } else if (exposeWithAlias === '') {\n return {\n pkgNameOrAlias: remote.alias,\n expose: '.',\n remote,\n };\n }\n }\n }\n\n return;\n}\n\n// Function to match a remote with its name or alias\nexport function matchRemote(\n remotes: Array<Remote>,\n nameOrAlias: string,\n): Remote | undefined {\n for (const remote of remotes) {\n const isNameMatched = nameOrAlias === remote.name;\n if (isNameMatched) {\n return remote;\n }\n\n const isAliasMatched = remote.alias && nameOrAlias === remote.alias;\n if (isAliasMatched) {\n return remote;\n }\n }\n return;\n}\n"],"mappings":";;AAEA,SAAgB,uBACd,YACA,QACQ;AACR,KAAI,CAAC,UAAU,WAAW,IACxB,QAAO;AAGT,QAAO,GAAG,WAAW,GAAG,OAAO,QAAQ,SAAS,GAAG;;AAOrD,SAAgB,6BACd,SACA,IAOY;AACZ,MAAK,MAAM,UAAU,SAAS;EAE5B,MAAM,gBAAgB,GAAG,WAAW,OAAO,KAAK;EAChD,IAAI,SAAS,GAAG,QAAQ,OAAO,MAAM,GAAG;AACxC,MAAI,eACF;OAAI,OAAO,WAAW,IAAI,EAAE;IAC1B,MAAM,iBAAiB,OAAO;AAC9B,aAAS,IAAI;AACb,WAAO;KACL;KACA;KACA;KACD;cACQ,WAAW,GACpB,QAAO;IACL,gBAAgB,OAAO;IACvB,QAAQ;IACR;IACD;;EAKL,MAAM,iBAAiB,OAAO,SAAS,GAAG,WAAW,OAAO,MAAM;EAClE,IAAI,kBAAkB,OAAO,SAAS,GAAG,QAAQ,OAAO,OAAO,GAAG;AAClE,MAAI,OAAO,SAAS,gBAClB;OAAI,mBAAmB,gBAAgB,WAAW,IAAI,EAAE;IACtD,MAAM,iBAAiB,OAAO;AAC9B,sBAAkB,IAAI;AACtB,WAAO;KACL;KACA,QAAQ;KACR;KACD;cACQ,oBAAoB,GAC7B,QAAO;IACL,gBAAgB,OAAO;IACvB,QAAQ;IACR;IACD;;;;AAST,SAAgB,YACd,SACA,aACoB;AACpB,MAAK,MAAM,UAAU,SAAS;AAE5B,MADsB,gBAAgB,OAAO,KAE3C,QAAO;AAIT,MADuB,OAAO,SAAS,gBAAgB,OAAO,MAE5D,QAAO"} |
| //#region src/utils/manifest.ts | ||
| function composeRemoteRequestId(remoteName, expose) { | ||
| if (!expose || expose === ".") return remoteName; | ||
| return `${remoteName}/${expose.replace(/^\.\//, "")}`; | ||
| } | ||
| function matchRemoteWithNameAndExpose(remotes, id) { | ||
@@ -48,3 +52,3 @@ for (const remote of remotes) { | ||
| //#endregion | ||
| export { matchRemote, matchRemoteWithNameAndExpose }; | ||
| export { composeRemoteRequestId, matchRemote, matchRemoteWithNameAndExpose }; | ||
| //# sourceMappingURL=manifest.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"manifest.js","names":[],"sources":["../../src/utils/manifest.ts"],"sourcesContent":["import { Remote } from '../type';\n\n// Function to match a remote with its name and expose\n// id: pkgName(@federation/app1) + expose(button) = @federation/app1/button\n// id: alias(app1) + expose(button) = app1/button\n// id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort\nexport function matchRemoteWithNameAndExpose(\n remotes: Array<Remote>,\n id: string,\n):\n | {\n pkgNameOrAlias: string;\n expose: string;\n remote: Remote;\n }\n | undefined {\n for (const remote of remotes) {\n // match pkgName\n const isNameMatched = id.startsWith(remote.name);\n let expose = id.replace(remote.name, '');\n if (isNameMatched) {\n if (expose.startsWith('/')) {\n const pkgNameOrAlias = remote.name;\n expose = `.${expose}`;\n return {\n pkgNameOrAlias,\n expose,\n remote,\n };\n } else if (expose === '') {\n return {\n pkgNameOrAlias: remote.name,\n expose: '.',\n remote,\n };\n }\n }\n\n // match alias\n const isAliasMatched = remote.alias && id.startsWith(remote.alias);\n let exposeWithAlias = remote.alias && id.replace(remote.alias, '');\n if (remote.alias && isAliasMatched) {\n if (exposeWithAlias && exposeWithAlias.startsWith('/')) {\n const pkgNameOrAlias = remote.alias;\n exposeWithAlias = `.${exposeWithAlias}`;\n return {\n pkgNameOrAlias,\n expose: exposeWithAlias,\n remote,\n };\n } else if (exposeWithAlias === '') {\n return {\n pkgNameOrAlias: remote.alias,\n expose: '.',\n remote,\n };\n }\n }\n }\n\n return;\n}\n\n// Function to match a remote with its name or alias\nexport function matchRemote(\n remotes: Array<Remote>,\n nameOrAlias: string,\n): Remote | undefined {\n for (const remote of remotes) {\n const isNameMatched = nameOrAlias === remote.name;\n if (isNameMatched) {\n return remote;\n }\n\n const isAliasMatched = remote.alias && nameOrAlias === remote.alias;\n if (isAliasMatched) {\n return remote;\n }\n }\n return;\n}\n"],"mappings":";AAMA,SAAgB,6BACd,SACA,IAOY;AACZ,MAAK,MAAM,UAAU,SAAS;EAE5B,MAAM,gBAAgB,GAAG,WAAW,OAAO,KAAK;EAChD,IAAI,SAAS,GAAG,QAAQ,OAAO,MAAM,GAAG;AACxC,MAAI,eACF;OAAI,OAAO,WAAW,IAAI,EAAE;IAC1B,MAAM,iBAAiB,OAAO;AAC9B,aAAS,IAAI;AACb,WAAO;KACL;KACA;KACA;KACD;cACQ,WAAW,GACpB,QAAO;IACL,gBAAgB,OAAO;IACvB,QAAQ;IACR;IACD;;EAKL,MAAM,iBAAiB,OAAO,SAAS,GAAG,WAAW,OAAO,MAAM;EAClE,IAAI,kBAAkB,OAAO,SAAS,GAAG,QAAQ,OAAO,OAAO,GAAG;AAClE,MAAI,OAAO,SAAS,gBAClB;OAAI,mBAAmB,gBAAgB,WAAW,IAAI,EAAE;IACtD,MAAM,iBAAiB,OAAO;AAC9B,sBAAkB,IAAI;AACtB,WAAO;KACL;KACA,QAAQ;KACR;KACD;cACQ,oBAAoB,GAC7B,QAAO;IACL,gBAAgB,OAAO;IACvB,QAAQ;IACR;IACD;;;;AAST,SAAgB,YACd,SACA,aACoB;AACpB,MAAK,MAAM,UAAU,SAAS;AAE5B,MADsB,gBAAgB,OAAO,KAE3C,QAAO;AAIT,MADuB,OAAO,SAAS,gBAAgB,OAAO,MAE5D,QAAO"} | ||
| {"version":3,"file":"manifest.js","names":[],"sources":["../../src/utils/manifest.ts"],"sourcesContent":["import { Remote } from '../type';\n\nexport function composeRemoteRequestId(\n remoteName: string,\n expose?: string,\n): string {\n if (!expose || expose === '.') {\n return remoteName;\n }\n\n return `${remoteName}/${expose.replace(/^\\.\\//, '')}`;\n}\n\n// Function to match a remote with its name and expose\n// id: pkgName(@federation/app1) + expose(button) = @federation/app1/button\n// id: alias(app1) + expose(button) = app1/button\n// id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort\nexport function matchRemoteWithNameAndExpose(\n remotes: Array<Remote>,\n id: string,\n):\n | {\n pkgNameOrAlias: string;\n expose: string;\n remote: Remote;\n }\n | undefined {\n for (const remote of remotes) {\n // match pkgName\n const isNameMatched = id.startsWith(remote.name);\n let expose = id.replace(remote.name, '');\n if (isNameMatched) {\n if (expose.startsWith('/')) {\n const pkgNameOrAlias = remote.name;\n expose = `.${expose}`;\n return {\n pkgNameOrAlias,\n expose,\n remote,\n };\n } else if (expose === '') {\n return {\n pkgNameOrAlias: remote.name,\n expose: '.',\n remote,\n };\n }\n }\n\n // match alias\n const isAliasMatched = remote.alias && id.startsWith(remote.alias);\n let exposeWithAlias = remote.alias && id.replace(remote.alias, '');\n if (remote.alias && isAliasMatched) {\n if (exposeWithAlias && exposeWithAlias.startsWith('/')) {\n const pkgNameOrAlias = remote.alias;\n exposeWithAlias = `.${exposeWithAlias}`;\n return {\n pkgNameOrAlias,\n expose: exposeWithAlias,\n remote,\n };\n } else if (exposeWithAlias === '') {\n return {\n pkgNameOrAlias: remote.alias,\n expose: '.',\n remote,\n };\n }\n }\n }\n\n return;\n}\n\n// Function to match a remote with its name or alias\nexport function matchRemote(\n remotes: Array<Remote>,\n nameOrAlias: string,\n): Remote | undefined {\n for (const remote of remotes) {\n const isNameMatched = nameOrAlias === remote.name;\n if (isNameMatched) {\n return remote;\n }\n\n const isAliasMatched = remote.alias && nameOrAlias === remote.alias;\n if (isAliasMatched) {\n return remote;\n }\n }\n return;\n}\n"],"mappings":";AAEA,SAAgB,uBACd,YACA,QACQ;AACR,KAAI,CAAC,UAAU,WAAW,IACxB,QAAO;AAGT,QAAO,GAAG,WAAW,GAAG,OAAO,QAAQ,SAAS,GAAG;;AAOrD,SAAgB,6BACd,SACA,IAOY;AACZ,MAAK,MAAM,UAAU,SAAS;EAE5B,MAAM,gBAAgB,GAAG,WAAW,OAAO,KAAK;EAChD,IAAI,SAAS,GAAG,QAAQ,OAAO,MAAM,GAAG;AACxC,MAAI,eACF;OAAI,OAAO,WAAW,IAAI,EAAE;IAC1B,MAAM,iBAAiB,OAAO;AAC9B,aAAS,IAAI;AACb,WAAO;KACL;KACA;KACA;KACD;cACQ,WAAW,GACpB,QAAO;IACL,gBAAgB,OAAO;IACvB,QAAQ;IACR;IACD;;EAKL,MAAM,iBAAiB,OAAO,SAAS,GAAG,WAAW,OAAO,MAAM;EAClE,IAAI,kBAAkB,OAAO,SAAS,GAAG,QAAQ,OAAO,OAAO,GAAG;AAClE,MAAI,OAAO,SAAS,gBAClB;OAAI,mBAAmB,gBAAgB,WAAW,IAAI,EAAE;IACtD,MAAM,iBAAiB,OAAO;AAC9B,sBAAkB,IAAI;AACtB,WAAO;KACL;KACA,QAAQ;KACR;KACD;cACQ,oBAAoB,GAC7B,QAAO;IACL,gBAAgB,OAAO;IACvB,QAAQ;IACR;IACD;;;;AAST,SAAgB,YACd,SACA,aACoB;AACpB,MAAK,MAAM,UAAU,SAAS;AAE5B,MADsB,gBAAgB,OAAO,KAE3C,QAAO;AAIT,MADuB,OAAO,SAAS,gBAAgB,OAAO,MAE5D,QAAO"} |
+126
-63
@@ -36,18 +36,109 @@ const require_logger = require('./logger.cjs'); | ||
| } | ||
| function preloadAssets(remoteInfo, host, assets, useLinkPreload = true) { | ||
| function isTimeoutError(error) { | ||
| if (!(error instanceof Error)) return false; | ||
| return error.message.includes("timed out") || error.name.includes("Timeout"); | ||
| } | ||
| function createAssetResult(context, url, status, error) { | ||
| return { | ||
| url, | ||
| status, | ||
| resourceType: context.resourceType, | ||
| initiator: context.initiator, | ||
| id: context.id, | ||
| error | ||
| }; | ||
| } | ||
| async function waitForRemoteEntryPreload(host, remoteInfo, entryRemoteInfo, context) { | ||
| const cachedRemote = host.moduleCache.get(entryRemoteInfo.name); | ||
| const url = entryRemoteInfo.entry; | ||
| if (cachedRemote?.remoteEntryExports) return createAssetResult(context, url, "cached"); | ||
| try { | ||
| if (!await require_load.getRemoteEntry({ | ||
| origin: host, | ||
| remoteInfo: entryRemoteInfo, | ||
| remoteEntryExports: cachedRemote?.remoteEntryExports, | ||
| resourceContext: { | ||
| ...context, | ||
| url | ||
| } | ||
| })) throw new Error(`Failed to load remoteEntry "${url}".`); | ||
| return createAssetResult(context, url, "success"); | ||
| } catch (error) { | ||
| return createAssetResult(context, url, isTimeoutError(error) ? "timeout" : "error", error); | ||
| } | ||
| } | ||
| function waitForLinkPreload({ host, remoteInfo, url, attrs, context, needDeleteLink }) { | ||
| return new Promise((resolve) => { | ||
| const { link, needAttach } = (0, _module_federation_sdk.createLink)({ | ||
| url, | ||
| cb: () => { | ||
| resolve(createAssetResult(context, url, needAttach ? "success" : "cached")); | ||
| }, | ||
| onErrorCallback: (error) => { | ||
| resolve(createAssetResult(context, url, isTimeoutError(error) ? "timeout" : "error", error)); | ||
| }, | ||
| attrs, | ||
| createLinkHook: (hookUrl, hookAttrs) => { | ||
| const res = host.loaderHook.lifecycle.createLink.emit({ | ||
| url: hookUrl, | ||
| attrs: hookAttrs, | ||
| remoteInfo, | ||
| resourceContext: { | ||
| ...context, | ||
| url: hookUrl | ||
| } | ||
| }); | ||
| if (res instanceof HTMLLinkElement) return res; | ||
| return res; | ||
| }, | ||
| needDeleteLink | ||
| }); | ||
| needAttach && document.head.appendChild(link); | ||
| }); | ||
| } | ||
| function waitForScriptPreload({ host, remoteInfo, url, attrs, context }) { | ||
| return new Promise((resolve) => { | ||
| const { script, needAttach } = (0, _module_federation_sdk.createScript)({ | ||
| url, | ||
| cb: () => { | ||
| resolve(createAssetResult(context, url, needAttach ? "success" : "cached")); | ||
| }, | ||
| onErrorCallback: (error) => { | ||
| resolve(createAssetResult(context, url, isTimeoutError(error) ? "timeout" : "error", error)); | ||
| }, | ||
| attrs, | ||
| createScriptHook: (hookUrl, hookAttrs) => { | ||
| const res = host.loaderHook.lifecycle.createScript.emit({ | ||
| url: hookUrl, | ||
| attrs: hookAttrs, | ||
| remoteInfo, | ||
| resourceContext: { | ||
| ...context, | ||
| url: hookUrl | ||
| } | ||
| }); | ||
| if (res instanceof HTMLScriptElement) return res; | ||
| return res; | ||
| }, | ||
| needDeleteScript: true | ||
| }); | ||
| needAttach && document.head.appendChild(script); | ||
| }); | ||
| } | ||
| function createResourceContext(baseContext, resourceType) { | ||
| return { | ||
| ...baseContext, | ||
| resourceType | ||
| }; | ||
| } | ||
| function preloadAssets(remoteInfo, host, assets, useLinkPreload = true, baseContext = { | ||
| initiator: "preloadRemote", | ||
| id: remoteInfo.name | ||
| }) { | ||
| const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets; | ||
| const results = []; | ||
| if (host.options.inBrowser) { | ||
| entryAssets.forEach((asset) => { | ||
| const { moduleInfo } = asset; | ||
| const module = host.moduleCache.get(remoteInfo.name); | ||
| if (module) require_load.getRemoteEntry({ | ||
| origin: host, | ||
| remoteInfo: moduleInfo, | ||
| remoteEntryExports: module.remoteEntryExports | ||
| }); | ||
| else require_load.getRemoteEntry({ | ||
| origin: host, | ||
| remoteInfo: moduleInfo, | ||
| remoteEntryExports: void 0 | ||
| }); | ||
| const { moduleInfo: entryRemoteInfo } = asset; | ||
| results.push(waitForRemoteEntryPreload(host, remoteInfo, entryRemoteInfo, createResourceContext(baseContext, "remoteEntry"))); | ||
| }); | ||
@@ -60,16 +151,9 @@ if (useLinkPreload) { | ||
| cssAssets.forEach((cssUrl) => { | ||
| const { link: cssEl, needAttach } = (0, _module_federation_sdk.createLink)({ | ||
| results.push(waitForLinkPreload({ | ||
| host, | ||
| remoteInfo, | ||
| url: cssUrl, | ||
| cb: () => {}, | ||
| attrs: defaultAttrs, | ||
| createLinkHook: (url, attrs) => { | ||
| const res = host.loaderHook.lifecycle.createLink.emit({ | ||
| url, | ||
| attrs, | ||
| remoteInfo | ||
| }); | ||
| if (res instanceof HTMLLinkElement) return res; | ||
| } | ||
| }); | ||
| needAttach && document.head.appendChild(cssEl); | ||
| context: createResourceContext(baseContext, "css") | ||
| })); | ||
| }); | ||
@@ -82,17 +166,10 @@ } else { | ||
| cssAssets.forEach((cssUrl) => { | ||
| const { link: cssEl, needAttach } = (0, _module_federation_sdk.createLink)({ | ||
| results.push(waitForLinkPreload({ | ||
| host, | ||
| remoteInfo, | ||
| url: cssUrl, | ||
| cb: () => {}, | ||
| attrs: defaultAttrs, | ||
| createLinkHook: (url, attrs) => { | ||
| const res = host.loaderHook.lifecycle.createLink.emit({ | ||
| url, | ||
| attrs, | ||
| remoteInfo | ||
| }); | ||
| if (res instanceof HTMLLinkElement) return res; | ||
| }, | ||
| needDeleteLink: false | ||
| }); | ||
| needAttach && document.head.appendChild(cssEl); | ||
| needDeleteLink: false, | ||
| context: createResourceContext(baseContext, "css") | ||
| })); | ||
| }); | ||
@@ -106,16 +183,9 @@ } | ||
| jsAssetsWithoutEntry.forEach((jsUrl) => { | ||
| const { link: linkEl, needAttach } = (0, _module_federation_sdk.createLink)({ | ||
| results.push(waitForLinkPreload({ | ||
| host, | ||
| remoteInfo, | ||
| url: jsUrl, | ||
| cb: () => {}, | ||
| attrs: defaultAttrs, | ||
| createLinkHook: (url, attrs) => { | ||
| const res = host.loaderHook.lifecycle.createLink.emit({ | ||
| url, | ||
| attrs, | ||
| remoteInfo | ||
| }); | ||
| if (res instanceof HTMLLinkElement) return res; | ||
| } | ||
| }); | ||
| needAttach && document.head.appendChild(linkEl); | ||
| context: createResourceContext(baseContext, "js") | ||
| })); | ||
| }); | ||
@@ -128,20 +198,13 @@ } else { | ||
| jsAssetsWithoutEntry.forEach((jsUrl) => { | ||
| const { script: scriptEl, needAttach } = (0, _module_federation_sdk.createScript)({ | ||
| results.push(waitForScriptPreload({ | ||
| host, | ||
| remoteInfo, | ||
| url: jsUrl, | ||
| cb: () => {}, | ||
| attrs: defaultAttrs, | ||
| createScriptHook: (url, attrs) => { | ||
| const res = host.loaderHook.lifecycle.createScript.emit({ | ||
| url, | ||
| attrs, | ||
| remoteInfo | ||
| }); | ||
| if (res instanceof HTMLScriptElement) return res; | ||
| }, | ||
| needDeleteScript: true | ||
| }); | ||
| needAttach && document.head.appendChild(scriptEl); | ||
| context: createResourceContext(baseContext, "js") | ||
| })); | ||
| }); | ||
| } | ||
| } | ||
| return Promise.all(results); | ||
| } | ||
@@ -148,0 +211,0 @@ |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"preload.cjs","names":["matchRemote"],"sources":["../../src/utils/preload.ts"],"sourcesContent":["import { createLink, createScript, safeToString } from '@module-federation/sdk';\nimport {\n PreloadAssets,\n PreloadConfig,\n PreloadOptions,\n PreloadRemoteArgs,\n Remote,\n RemoteInfo,\n depsPreloadArg,\n} from '../type';\nimport { matchRemote } from './manifest';\nimport { assert } from './logger';\nimport { ModuleFederation } from '../core';\nimport { getRemoteEntry } from './load';\n\nexport function defaultPreloadArgs(\n preloadConfig: PreloadRemoteArgs | depsPreloadArg,\n): PreloadConfig {\n return {\n resourceCategory: 'sync',\n share: true,\n depsRemote: true,\n ...preloadConfig,\n } as PreloadConfig;\n}\n\nexport function formatPreloadArgs(\n remotes: Array<Remote>,\n preloadArgs: Array<PreloadRemoteArgs>,\n): PreloadOptions {\n return preloadArgs.map((args) => {\n const remoteInfo = matchRemote(remotes, args.nameOrAlias);\n assert(\n remoteInfo,\n `Unable to preload ${args.nameOrAlias} as it is not included in ${\n !remoteInfo &&\n safeToString({\n remoteInfo,\n remotes,\n })\n }`,\n );\n return {\n remote: remoteInfo,\n preloadConfig: defaultPreloadArgs(args),\n };\n });\n}\n\nexport function normalizePreloadExposes(exposes?: string[]): string[] {\n if (!exposes) {\n return [];\n }\n\n return exposes.map((expose) => {\n if (expose === '.') {\n return expose;\n }\n if (expose.startsWith('./')) {\n return expose.replace('./', '');\n }\n return expose;\n });\n}\n\nexport function preloadAssets(\n remoteInfo: RemoteInfo,\n host: ModuleFederation,\n assets: PreloadAssets,\n // It is used to distinguish preload from load remote parallel loading\n useLinkPreload = true,\n): void {\n const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets;\n\n if (host.options.inBrowser) {\n entryAssets.forEach((asset) => {\n const { moduleInfo } = asset;\n const module = host.moduleCache.get(remoteInfo.name);\n if (module) {\n getRemoteEntry({\n origin: host,\n remoteInfo: moduleInfo,\n remoteEntryExports: module.remoteEntryExports,\n });\n } else {\n getRemoteEntry({\n origin: host,\n remoteInfo: moduleInfo,\n remoteEntryExports: undefined,\n });\n }\n });\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'style',\n };\n cssAssets.forEach((cssUrl) => {\n const { link: cssEl, needAttach } = createLink({\n url: cssUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n });\n\n needAttach && document.head.appendChild(cssEl);\n });\n } else {\n const defaultAttrs = {\n rel: 'stylesheet',\n type: 'text/css',\n };\n cssAssets.forEach((cssUrl) => {\n const { link: cssEl, needAttach } = createLink({\n url: cssUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n needDeleteLink: false,\n });\n\n needAttach && document.head.appendChild(cssEl);\n });\n }\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'script',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n const { link: linkEl, needAttach } = createLink({\n url: jsUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url: string, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n });\n needAttach && document.head.appendChild(linkEl);\n });\n } else {\n const defaultAttrs = {\n fetchpriority: 'high',\n type: remoteInfo?.type === 'module' ? 'module' : 'text/javascript',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n const { script: scriptEl, needAttach } = createScript({\n url: jsUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createScriptHook: (url: string, attrs: any) => {\n const res = host.loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n return;\n },\n needDeleteScript: true,\n });\n needAttach && document.head.appendChild(scriptEl);\n });\n }\n }\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"preload.cjs","names":["matchRemote","getRemoteEntry"],"sources":["../../src/utils/preload.ts"],"sourcesContent":["import { createLink, createScript, safeToString } from '@module-federation/sdk';\nimport {\n PreloadAssets,\n PreloadAssetResult,\n PreloadConfig,\n PreloadOptions,\n PreloadRemoteArgs,\n Remote,\n RemoteInfo,\n ResourceLoadContext,\n ResourceLoadType,\n depsPreloadArg,\n} from '../type';\nimport { matchRemote } from './manifest';\nimport { assert } from './logger';\nimport { ModuleFederation } from '../core';\nimport { getRemoteEntry } from './load';\n\nexport function defaultPreloadArgs(\n preloadConfig: PreloadRemoteArgs | depsPreloadArg,\n): PreloadConfig {\n return {\n resourceCategory: 'sync',\n share: true,\n depsRemote: true,\n ...preloadConfig,\n } as PreloadConfig;\n}\n\nexport function formatPreloadArgs(\n remotes: Array<Remote>,\n preloadArgs: Array<PreloadRemoteArgs>,\n): PreloadOptions {\n return preloadArgs.map((args) => {\n const remoteInfo = matchRemote(remotes, args.nameOrAlias);\n assert(\n remoteInfo,\n `Unable to preload ${args.nameOrAlias} as it is not included in ${\n !remoteInfo &&\n safeToString({\n remoteInfo,\n remotes,\n })\n }`,\n );\n return {\n remote: remoteInfo,\n preloadConfig: defaultPreloadArgs(args),\n };\n });\n}\n\nexport function normalizePreloadExposes(exposes?: string[]): string[] {\n if (!exposes) {\n return [];\n }\n\n return exposes.map((expose) => {\n if (expose === '.') {\n return expose;\n }\n if (expose.startsWith('./')) {\n return expose.replace('./', '');\n }\n return expose;\n });\n}\n\nfunction isTimeoutError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n return error.message.includes('timed out') || error.name.includes('Timeout');\n}\n\nfunction createAssetResult(\n context: ResourceLoadContext,\n url: string,\n status: PreloadAssetResult['status'],\n error?: unknown,\n): PreloadAssetResult {\n return {\n url,\n status,\n resourceType: context.resourceType,\n initiator: context.initiator,\n id: context.id,\n error,\n };\n}\n\nasync function waitForRemoteEntryPreload(\n host: ModuleFederation,\n remoteInfo: RemoteInfo,\n entryRemoteInfo: RemoteInfo,\n context: ResourceLoadContext,\n): Promise<PreloadAssetResult> {\n const cachedRemote = host.moduleCache.get(entryRemoteInfo.name);\n const url = entryRemoteInfo.entry;\n if (cachedRemote?.remoteEntryExports) {\n return createAssetResult(context, url, 'cached');\n }\n\n try {\n const remoteEntryExports = await getRemoteEntry({\n origin: host,\n remoteInfo: entryRemoteInfo,\n remoteEntryExports: cachedRemote?.remoteEntryExports,\n resourceContext: {\n ...context,\n url,\n },\n });\n if (!remoteEntryExports) {\n throw new Error(`Failed to load remoteEntry \"${url}\".`);\n }\n return createAssetResult(context, url, 'success');\n } catch (error) {\n return createAssetResult(\n context,\n url,\n isTimeoutError(error) ? 'timeout' : 'error',\n error,\n );\n }\n}\n\nfunction waitForLinkPreload({\n host,\n remoteInfo,\n url,\n attrs,\n context,\n needDeleteLink,\n}: {\n host: ModuleFederation;\n remoteInfo: RemoteInfo;\n url: string;\n attrs: Record<string, string>;\n context: ResourceLoadContext;\n needDeleteLink?: boolean;\n}): Promise<PreloadAssetResult> {\n return new Promise((resolve) => {\n const { link, needAttach } = createLink({\n url,\n cb: () => {\n resolve(\n createAssetResult(context, url, needAttach ? 'success' : 'cached'),\n );\n },\n onErrorCallback: (error) => {\n resolve(\n createAssetResult(\n context,\n url,\n isTimeoutError(error) ? 'timeout' : 'error',\n error,\n ),\n );\n },\n attrs,\n createLinkHook: (hookUrl, hookAttrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url: hookUrl,\n attrs: hookAttrs,\n remoteInfo,\n resourceContext: {\n ...context,\n url: hookUrl,\n },\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return res;\n },\n needDeleteLink,\n });\n\n needAttach && document.head.appendChild(link);\n });\n}\n\nfunction waitForScriptPreload({\n host,\n remoteInfo,\n url,\n attrs,\n context,\n}: {\n host: ModuleFederation;\n remoteInfo: RemoteInfo;\n url: string;\n attrs: Record<string, string>;\n context: ResourceLoadContext;\n}): Promise<PreloadAssetResult> {\n return new Promise((resolve) => {\n const { script, needAttach } = createScript({\n url,\n cb: () => {\n resolve(\n createAssetResult(context, url, needAttach ? 'success' : 'cached'),\n );\n },\n onErrorCallback: (error) => {\n resolve(\n createAssetResult(\n context,\n url,\n isTimeoutError(error) ? 'timeout' : 'error',\n error,\n ),\n );\n },\n attrs,\n createScriptHook: (hookUrl: string, hookAttrs: any) => {\n const res = host.loaderHook.lifecycle.createScript.emit({\n url: hookUrl,\n attrs: hookAttrs,\n remoteInfo,\n resourceContext: {\n ...context,\n url: hookUrl,\n },\n });\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n return res;\n },\n needDeleteScript: true,\n });\n\n needAttach && document.head.appendChild(script);\n });\n}\n\nfunction createResourceContext(\n baseContext: Omit<ResourceLoadContext, 'resourceType'>,\n resourceType: ResourceLoadType,\n): ResourceLoadContext {\n return {\n ...baseContext,\n resourceType,\n };\n}\n\nexport function preloadAssets(\n remoteInfo: RemoteInfo,\n host: ModuleFederation,\n assets: PreloadAssets,\n // It is used to distinguish preload from load remote parallel loading\n useLinkPreload = true,\n baseContext: Omit<ResourceLoadContext, 'resourceType'> = {\n initiator: 'preloadRemote',\n id: remoteInfo.name,\n },\n): Promise<PreloadAssetResult[]> {\n const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets;\n const results: Array<Promise<PreloadAssetResult>> = [];\n\n if (host.options.inBrowser) {\n entryAssets.forEach((asset) => {\n const { moduleInfo: entryRemoteInfo } = asset;\n results.push(\n waitForRemoteEntryPreload(\n host,\n remoteInfo,\n entryRemoteInfo,\n createResourceContext(baseContext, 'remoteEntry'),\n ),\n );\n });\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'style',\n };\n cssAssets.forEach((cssUrl) => {\n results.push(\n waitForLinkPreload({\n host,\n remoteInfo,\n url: cssUrl,\n attrs: defaultAttrs,\n context: createResourceContext(baseContext, 'css'),\n }),\n );\n });\n } else {\n const defaultAttrs = {\n rel: 'stylesheet',\n type: 'text/css',\n };\n cssAssets.forEach((cssUrl) => {\n results.push(\n waitForLinkPreload({\n host,\n remoteInfo,\n url: cssUrl,\n attrs: defaultAttrs,\n needDeleteLink: false,\n context: createResourceContext(baseContext, 'css'),\n }),\n );\n });\n }\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'script',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n results.push(\n waitForLinkPreload({\n host,\n remoteInfo,\n url: jsUrl,\n attrs: defaultAttrs,\n context: createResourceContext(baseContext, 'js'),\n }),\n );\n });\n } else {\n const defaultAttrs = {\n fetchpriority: 'high',\n type: remoteInfo?.type === 'module' ? 'module' : 'text/javascript',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n results.push(\n waitForScriptPreload({\n host,\n remoteInfo,\n url: jsUrl,\n attrs: defaultAttrs,\n context: createResourceContext(baseContext, 'js'),\n }),\n );\n });\n }\n }\n\n return Promise.all(results);\n}\n"],"mappings":"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"} |
| import { ModuleFederation } from "../core.js"; | ||
| import { RemoteInfo } from "../type/config.js"; | ||
| import { PreloadAssets } from "../type/preload.js"; | ||
| import { PreloadAssetResult, PreloadAssets, ResourceLoadContext } from "../type/preload.js"; | ||
| //#region src/utils/preload.d.ts | ||
| declare function preloadAssets(remoteInfo: RemoteInfo, host: ModuleFederation, assets: PreloadAssets, useLinkPreload?: boolean): void; | ||
| declare function preloadAssets(remoteInfo: RemoteInfo, host: ModuleFederation, assets: PreloadAssets, useLinkPreload?: boolean, baseContext?: Omit<ResourceLoadContext, 'resourceType'>): Promise<PreloadAssetResult[]>; | ||
| //#endregion | ||
| export { preloadAssets }; | ||
| //# sourceMappingURL=preload.d.ts.map |
+126
-63
@@ -36,18 +36,109 @@ import { assert } from "./logger.js"; | ||
| } | ||
| function preloadAssets(remoteInfo, host, assets, useLinkPreload = true) { | ||
| function isTimeoutError(error) { | ||
| if (!(error instanceof Error)) return false; | ||
| return error.message.includes("timed out") || error.name.includes("Timeout"); | ||
| } | ||
| function createAssetResult(context, url, status, error) { | ||
| return { | ||
| url, | ||
| status, | ||
| resourceType: context.resourceType, | ||
| initiator: context.initiator, | ||
| id: context.id, | ||
| error | ||
| }; | ||
| } | ||
| async function waitForRemoteEntryPreload(host, remoteInfo, entryRemoteInfo, context) { | ||
| const cachedRemote = host.moduleCache.get(entryRemoteInfo.name); | ||
| const url = entryRemoteInfo.entry; | ||
| if (cachedRemote?.remoteEntryExports) return createAssetResult(context, url, "cached"); | ||
| try { | ||
| if (!await getRemoteEntry({ | ||
| origin: host, | ||
| remoteInfo: entryRemoteInfo, | ||
| remoteEntryExports: cachedRemote?.remoteEntryExports, | ||
| resourceContext: { | ||
| ...context, | ||
| url | ||
| } | ||
| })) throw new Error(`Failed to load remoteEntry "${url}".`); | ||
| return createAssetResult(context, url, "success"); | ||
| } catch (error) { | ||
| return createAssetResult(context, url, isTimeoutError(error) ? "timeout" : "error", error); | ||
| } | ||
| } | ||
| function waitForLinkPreload({ host, remoteInfo, url, attrs, context, needDeleteLink }) { | ||
| return new Promise((resolve) => { | ||
| const { link, needAttach } = createLink({ | ||
| url, | ||
| cb: () => { | ||
| resolve(createAssetResult(context, url, needAttach ? "success" : "cached")); | ||
| }, | ||
| onErrorCallback: (error) => { | ||
| resolve(createAssetResult(context, url, isTimeoutError(error) ? "timeout" : "error", error)); | ||
| }, | ||
| attrs, | ||
| createLinkHook: (hookUrl, hookAttrs) => { | ||
| const res = host.loaderHook.lifecycle.createLink.emit({ | ||
| url: hookUrl, | ||
| attrs: hookAttrs, | ||
| remoteInfo, | ||
| resourceContext: { | ||
| ...context, | ||
| url: hookUrl | ||
| } | ||
| }); | ||
| if (res instanceof HTMLLinkElement) return res; | ||
| return res; | ||
| }, | ||
| needDeleteLink | ||
| }); | ||
| needAttach && document.head.appendChild(link); | ||
| }); | ||
| } | ||
| function waitForScriptPreload({ host, remoteInfo, url, attrs, context }) { | ||
| return new Promise((resolve) => { | ||
| const { script, needAttach } = createScript({ | ||
| url, | ||
| cb: () => { | ||
| resolve(createAssetResult(context, url, needAttach ? "success" : "cached")); | ||
| }, | ||
| onErrorCallback: (error) => { | ||
| resolve(createAssetResult(context, url, isTimeoutError(error) ? "timeout" : "error", error)); | ||
| }, | ||
| attrs, | ||
| createScriptHook: (hookUrl, hookAttrs) => { | ||
| const res = host.loaderHook.lifecycle.createScript.emit({ | ||
| url: hookUrl, | ||
| attrs: hookAttrs, | ||
| remoteInfo, | ||
| resourceContext: { | ||
| ...context, | ||
| url: hookUrl | ||
| } | ||
| }); | ||
| if (res instanceof HTMLScriptElement) return res; | ||
| return res; | ||
| }, | ||
| needDeleteScript: true | ||
| }); | ||
| needAttach && document.head.appendChild(script); | ||
| }); | ||
| } | ||
| function createResourceContext(baseContext, resourceType) { | ||
| return { | ||
| ...baseContext, | ||
| resourceType | ||
| }; | ||
| } | ||
| function preloadAssets(remoteInfo, host, assets, useLinkPreload = true, baseContext = { | ||
| initiator: "preloadRemote", | ||
| id: remoteInfo.name | ||
| }) { | ||
| const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets; | ||
| const results = []; | ||
| if (host.options.inBrowser) { | ||
| entryAssets.forEach((asset) => { | ||
| const { moduleInfo } = asset; | ||
| const module = host.moduleCache.get(remoteInfo.name); | ||
| if (module) getRemoteEntry({ | ||
| origin: host, | ||
| remoteInfo: moduleInfo, | ||
| remoteEntryExports: module.remoteEntryExports | ||
| }); | ||
| else getRemoteEntry({ | ||
| origin: host, | ||
| remoteInfo: moduleInfo, | ||
| remoteEntryExports: void 0 | ||
| }); | ||
| const { moduleInfo: entryRemoteInfo } = asset; | ||
| results.push(waitForRemoteEntryPreload(host, remoteInfo, entryRemoteInfo, createResourceContext(baseContext, "remoteEntry"))); | ||
| }); | ||
@@ -60,16 +151,9 @@ if (useLinkPreload) { | ||
| cssAssets.forEach((cssUrl) => { | ||
| const { link: cssEl, needAttach } = createLink({ | ||
| results.push(waitForLinkPreload({ | ||
| host, | ||
| remoteInfo, | ||
| url: cssUrl, | ||
| cb: () => {}, | ||
| attrs: defaultAttrs, | ||
| createLinkHook: (url, attrs) => { | ||
| const res = host.loaderHook.lifecycle.createLink.emit({ | ||
| url, | ||
| attrs, | ||
| remoteInfo | ||
| }); | ||
| if (res instanceof HTMLLinkElement) return res; | ||
| } | ||
| }); | ||
| needAttach && document.head.appendChild(cssEl); | ||
| context: createResourceContext(baseContext, "css") | ||
| })); | ||
| }); | ||
@@ -82,17 +166,10 @@ } else { | ||
| cssAssets.forEach((cssUrl) => { | ||
| const { link: cssEl, needAttach } = createLink({ | ||
| results.push(waitForLinkPreload({ | ||
| host, | ||
| remoteInfo, | ||
| url: cssUrl, | ||
| cb: () => {}, | ||
| attrs: defaultAttrs, | ||
| createLinkHook: (url, attrs) => { | ||
| const res = host.loaderHook.lifecycle.createLink.emit({ | ||
| url, | ||
| attrs, | ||
| remoteInfo | ||
| }); | ||
| if (res instanceof HTMLLinkElement) return res; | ||
| }, | ||
| needDeleteLink: false | ||
| }); | ||
| needAttach && document.head.appendChild(cssEl); | ||
| needDeleteLink: false, | ||
| context: createResourceContext(baseContext, "css") | ||
| })); | ||
| }); | ||
@@ -106,16 +183,9 @@ } | ||
| jsAssetsWithoutEntry.forEach((jsUrl) => { | ||
| const { link: linkEl, needAttach } = createLink({ | ||
| results.push(waitForLinkPreload({ | ||
| host, | ||
| remoteInfo, | ||
| url: jsUrl, | ||
| cb: () => {}, | ||
| attrs: defaultAttrs, | ||
| createLinkHook: (url, attrs) => { | ||
| const res = host.loaderHook.lifecycle.createLink.emit({ | ||
| url, | ||
| attrs, | ||
| remoteInfo | ||
| }); | ||
| if (res instanceof HTMLLinkElement) return res; | ||
| } | ||
| }); | ||
| needAttach && document.head.appendChild(linkEl); | ||
| context: createResourceContext(baseContext, "js") | ||
| })); | ||
| }); | ||
@@ -128,20 +198,13 @@ } else { | ||
| jsAssetsWithoutEntry.forEach((jsUrl) => { | ||
| const { script: scriptEl, needAttach } = createScript({ | ||
| results.push(waitForScriptPreload({ | ||
| host, | ||
| remoteInfo, | ||
| url: jsUrl, | ||
| cb: () => {}, | ||
| attrs: defaultAttrs, | ||
| createScriptHook: (url, attrs) => { | ||
| const res = host.loaderHook.lifecycle.createScript.emit({ | ||
| url, | ||
| attrs, | ||
| remoteInfo | ||
| }); | ||
| if (res instanceof HTMLScriptElement) return res; | ||
| }, | ||
| needDeleteScript: true | ||
| }); | ||
| needAttach && document.head.appendChild(scriptEl); | ||
| context: createResourceContext(baseContext, "js") | ||
| })); | ||
| }); | ||
| } | ||
| } | ||
| return Promise.all(results); | ||
| } | ||
@@ -148,0 +211,0 @@ |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"preload.js","names":[],"sources":["../../src/utils/preload.ts"],"sourcesContent":["import { createLink, createScript, safeToString } from '@module-federation/sdk';\nimport {\n PreloadAssets,\n PreloadConfig,\n PreloadOptions,\n PreloadRemoteArgs,\n Remote,\n RemoteInfo,\n depsPreloadArg,\n} from '../type';\nimport { matchRemote } from './manifest';\nimport { assert } from './logger';\nimport { ModuleFederation } from '../core';\nimport { getRemoteEntry } from './load';\n\nexport function defaultPreloadArgs(\n preloadConfig: PreloadRemoteArgs | depsPreloadArg,\n): PreloadConfig {\n return {\n resourceCategory: 'sync',\n share: true,\n depsRemote: true,\n ...preloadConfig,\n } as PreloadConfig;\n}\n\nexport function formatPreloadArgs(\n remotes: Array<Remote>,\n preloadArgs: Array<PreloadRemoteArgs>,\n): PreloadOptions {\n return preloadArgs.map((args) => {\n const remoteInfo = matchRemote(remotes, args.nameOrAlias);\n assert(\n remoteInfo,\n `Unable to preload ${args.nameOrAlias} as it is not included in ${\n !remoteInfo &&\n safeToString({\n remoteInfo,\n remotes,\n })\n }`,\n );\n return {\n remote: remoteInfo,\n preloadConfig: defaultPreloadArgs(args),\n };\n });\n}\n\nexport function normalizePreloadExposes(exposes?: string[]): string[] {\n if (!exposes) {\n return [];\n }\n\n return exposes.map((expose) => {\n if (expose === '.') {\n return expose;\n }\n if (expose.startsWith('./')) {\n return expose.replace('./', '');\n }\n return expose;\n });\n}\n\nexport function preloadAssets(\n remoteInfo: RemoteInfo,\n host: ModuleFederation,\n assets: PreloadAssets,\n // It is used to distinguish preload from load remote parallel loading\n useLinkPreload = true,\n): void {\n const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets;\n\n if (host.options.inBrowser) {\n entryAssets.forEach((asset) => {\n const { moduleInfo } = asset;\n const module = host.moduleCache.get(remoteInfo.name);\n if (module) {\n getRemoteEntry({\n origin: host,\n remoteInfo: moduleInfo,\n remoteEntryExports: module.remoteEntryExports,\n });\n } else {\n getRemoteEntry({\n origin: host,\n remoteInfo: moduleInfo,\n remoteEntryExports: undefined,\n });\n }\n });\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'style',\n };\n cssAssets.forEach((cssUrl) => {\n const { link: cssEl, needAttach } = createLink({\n url: cssUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n });\n\n needAttach && document.head.appendChild(cssEl);\n });\n } else {\n const defaultAttrs = {\n rel: 'stylesheet',\n type: 'text/css',\n };\n cssAssets.forEach((cssUrl) => {\n const { link: cssEl, needAttach } = createLink({\n url: cssUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n needDeleteLink: false,\n });\n\n needAttach && document.head.appendChild(cssEl);\n });\n }\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'script',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n const { link: linkEl, needAttach } = createLink({\n url: jsUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createLinkHook: (url: string, attrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return;\n },\n });\n needAttach && document.head.appendChild(linkEl);\n });\n } else {\n const defaultAttrs = {\n fetchpriority: 'high',\n type: remoteInfo?.type === 'module' ? 'module' : 'text/javascript',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n const { script: scriptEl, needAttach } = createScript({\n url: jsUrl,\n cb: () => {\n // noop\n },\n attrs: defaultAttrs,\n createScriptHook: (url: string, attrs: any) => {\n const res = host.loaderHook.lifecycle.createScript.emit({\n url,\n attrs,\n remoteInfo,\n });\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n return;\n },\n needDeleteScript: true,\n });\n needAttach && document.head.appendChild(scriptEl);\n });\n }\n }\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"preload.js","names":[],"sources":["../../src/utils/preload.ts"],"sourcesContent":["import { createLink, createScript, safeToString } from '@module-federation/sdk';\nimport {\n PreloadAssets,\n PreloadAssetResult,\n PreloadConfig,\n PreloadOptions,\n PreloadRemoteArgs,\n Remote,\n RemoteInfo,\n ResourceLoadContext,\n ResourceLoadType,\n depsPreloadArg,\n} from '../type';\nimport { matchRemote } from './manifest';\nimport { assert } from './logger';\nimport { ModuleFederation } from '../core';\nimport { getRemoteEntry } from './load';\n\nexport function defaultPreloadArgs(\n preloadConfig: PreloadRemoteArgs | depsPreloadArg,\n): PreloadConfig {\n return {\n resourceCategory: 'sync',\n share: true,\n depsRemote: true,\n ...preloadConfig,\n } as PreloadConfig;\n}\n\nexport function formatPreloadArgs(\n remotes: Array<Remote>,\n preloadArgs: Array<PreloadRemoteArgs>,\n): PreloadOptions {\n return preloadArgs.map((args) => {\n const remoteInfo = matchRemote(remotes, args.nameOrAlias);\n assert(\n remoteInfo,\n `Unable to preload ${args.nameOrAlias} as it is not included in ${\n !remoteInfo &&\n safeToString({\n remoteInfo,\n remotes,\n })\n }`,\n );\n return {\n remote: remoteInfo,\n preloadConfig: defaultPreloadArgs(args),\n };\n });\n}\n\nexport function normalizePreloadExposes(exposes?: string[]): string[] {\n if (!exposes) {\n return [];\n }\n\n return exposes.map((expose) => {\n if (expose === '.') {\n return expose;\n }\n if (expose.startsWith('./')) {\n return expose.replace('./', '');\n }\n return expose;\n });\n}\n\nfunction isTimeoutError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n return error.message.includes('timed out') || error.name.includes('Timeout');\n}\n\nfunction createAssetResult(\n context: ResourceLoadContext,\n url: string,\n status: PreloadAssetResult['status'],\n error?: unknown,\n): PreloadAssetResult {\n return {\n url,\n status,\n resourceType: context.resourceType,\n initiator: context.initiator,\n id: context.id,\n error,\n };\n}\n\nasync function waitForRemoteEntryPreload(\n host: ModuleFederation,\n remoteInfo: RemoteInfo,\n entryRemoteInfo: RemoteInfo,\n context: ResourceLoadContext,\n): Promise<PreloadAssetResult> {\n const cachedRemote = host.moduleCache.get(entryRemoteInfo.name);\n const url = entryRemoteInfo.entry;\n if (cachedRemote?.remoteEntryExports) {\n return createAssetResult(context, url, 'cached');\n }\n\n try {\n const remoteEntryExports = await getRemoteEntry({\n origin: host,\n remoteInfo: entryRemoteInfo,\n remoteEntryExports: cachedRemote?.remoteEntryExports,\n resourceContext: {\n ...context,\n url,\n },\n });\n if (!remoteEntryExports) {\n throw new Error(`Failed to load remoteEntry \"${url}\".`);\n }\n return createAssetResult(context, url, 'success');\n } catch (error) {\n return createAssetResult(\n context,\n url,\n isTimeoutError(error) ? 'timeout' : 'error',\n error,\n );\n }\n}\n\nfunction waitForLinkPreload({\n host,\n remoteInfo,\n url,\n attrs,\n context,\n needDeleteLink,\n}: {\n host: ModuleFederation;\n remoteInfo: RemoteInfo;\n url: string;\n attrs: Record<string, string>;\n context: ResourceLoadContext;\n needDeleteLink?: boolean;\n}): Promise<PreloadAssetResult> {\n return new Promise((resolve) => {\n const { link, needAttach } = createLink({\n url,\n cb: () => {\n resolve(\n createAssetResult(context, url, needAttach ? 'success' : 'cached'),\n );\n },\n onErrorCallback: (error) => {\n resolve(\n createAssetResult(\n context,\n url,\n isTimeoutError(error) ? 'timeout' : 'error',\n error,\n ),\n );\n },\n attrs,\n createLinkHook: (hookUrl, hookAttrs) => {\n const res = host.loaderHook.lifecycle.createLink.emit({\n url: hookUrl,\n attrs: hookAttrs,\n remoteInfo,\n resourceContext: {\n ...context,\n url: hookUrl,\n },\n });\n if (res instanceof HTMLLinkElement) {\n return res;\n }\n return res;\n },\n needDeleteLink,\n });\n\n needAttach && document.head.appendChild(link);\n });\n}\n\nfunction waitForScriptPreload({\n host,\n remoteInfo,\n url,\n attrs,\n context,\n}: {\n host: ModuleFederation;\n remoteInfo: RemoteInfo;\n url: string;\n attrs: Record<string, string>;\n context: ResourceLoadContext;\n}): Promise<PreloadAssetResult> {\n return new Promise((resolve) => {\n const { script, needAttach } = createScript({\n url,\n cb: () => {\n resolve(\n createAssetResult(context, url, needAttach ? 'success' : 'cached'),\n );\n },\n onErrorCallback: (error) => {\n resolve(\n createAssetResult(\n context,\n url,\n isTimeoutError(error) ? 'timeout' : 'error',\n error,\n ),\n );\n },\n attrs,\n createScriptHook: (hookUrl: string, hookAttrs: any) => {\n const res = host.loaderHook.lifecycle.createScript.emit({\n url: hookUrl,\n attrs: hookAttrs,\n remoteInfo,\n resourceContext: {\n ...context,\n url: hookUrl,\n },\n });\n if (res instanceof HTMLScriptElement) {\n return res;\n }\n return res;\n },\n needDeleteScript: true,\n });\n\n needAttach && document.head.appendChild(script);\n });\n}\n\nfunction createResourceContext(\n baseContext: Omit<ResourceLoadContext, 'resourceType'>,\n resourceType: ResourceLoadType,\n): ResourceLoadContext {\n return {\n ...baseContext,\n resourceType,\n };\n}\n\nexport function preloadAssets(\n remoteInfo: RemoteInfo,\n host: ModuleFederation,\n assets: PreloadAssets,\n // It is used to distinguish preload from load remote parallel loading\n useLinkPreload = true,\n baseContext: Omit<ResourceLoadContext, 'resourceType'> = {\n initiator: 'preloadRemote',\n id: remoteInfo.name,\n },\n): Promise<PreloadAssetResult[]> {\n const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets;\n const results: Array<Promise<PreloadAssetResult>> = [];\n\n if (host.options.inBrowser) {\n entryAssets.forEach((asset) => {\n const { moduleInfo: entryRemoteInfo } = asset;\n results.push(\n waitForRemoteEntryPreload(\n host,\n remoteInfo,\n entryRemoteInfo,\n createResourceContext(baseContext, 'remoteEntry'),\n ),\n );\n });\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'style',\n };\n cssAssets.forEach((cssUrl) => {\n results.push(\n waitForLinkPreload({\n host,\n remoteInfo,\n url: cssUrl,\n attrs: defaultAttrs,\n context: createResourceContext(baseContext, 'css'),\n }),\n );\n });\n } else {\n const defaultAttrs = {\n rel: 'stylesheet',\n type: 'text/css',\n };\n cssAssets.forEach((cssUrl) => {\n results.push(\n waitForLinkPreload({\n host,\n remoteInfo,\n url: cssUrl,\n attrs: defaultAttrs,\n needDeleteLink: false,\n context: createResourceContext(baseContext, 'css'),\n }),\n );\n });\n }\n\n if (useLinkPreload) {\n const defaultAttrs = {\n rel: 'preload',\n as: 'script',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n results.push(\n waitForLinkPreload({\n host,\n remoteInfo,\n url: jsUrl,\n attrs: defaultAttrs,\n context: createResourceContext(baseContext, 'js'),\n }),\n );\n });\n } else {\n const defaultAttrs = {\n fetchpriority: 'high',\n type: remoteInfo?.type === 'module' ? 'module' : 'text/javascript',\n };\n jsAssetsWithoutEntry.forEach((jsUrl) => {\n results.push(\n waitForScriptPreload({\n host,\n remoteInfo,\n url: jsUrl,\n attrs: defaultAttrs,\n context: createResourceContext(baseContext, 'js'),\n }),\n );\n });\n }\n }\n\n return Promise.all(results);\n}\n"],"mappings":"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"} |
+3
-3
| { | ||
| "name": "@module-federation/runtime-core", | ||
| "version": "2.4.0", | ||
| "version": "2.5.0", | ||
| "type": "module", | ||
@@ -55,4 +55,4 @@ "author": "zhouxiao <codingzx@gmail.com>", | ||
| "dependencies": { | ||
| "@module-federation/sdk": "2.4.0", | ||
| "@module-federation/error-codes": "2.4.0" | ||
| "@module-federation/sdk": "2.5.0", | ||
| "@module-federation/error-codes": "2.5.0" | ||
| }, | ||
@@ -59,0 +59,0 @@ "scripts": { |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 2 instances in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
810959
14.26%7706
18.41%2
100%+ Added
+ Added
- Removed
- Removed
Updated