Project Init

This commit is contained in:
Muluhabt
2026-05-29 15:23:46 +03:00
commit 2fbc557aac
67387 changed files with 6063341 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023-present zhouxiao(zhoushaw)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,19 @@
//#region \0rolldown/runtime.js
var __defProp = Object.defineProperty;
var __exportAll = (all, no_symbols) => {
let target = {};
for (var name in all) {
__defProp(target, name, {
get: all[name],
enumerable: true
});
}
if (!no_symbols) {
__defProp(target, Symbol.toStringTag, { value: "Module" });
}
return target;
};
//#endregion
exports.__exportAll = __exportAll;

View File

@@ -0,0 +1,18 @@
//#region \0rolldown/runtime.js
var __defProp = Object.defineProperty;
var __exportAll = (all, no_symbols) => {
let target = {};
for (var name in all) {
__defProp(target, name, {
get: all[name],
enumerable: true
});
}
if (!no_symbols) {
__defProp(target, Symbol.toStringTag, { value: "Module" });
}
return target;
};
//#endregion
export { __exportAll };

View File

@@ -0,0 +1,9 @@
//#region src/constant.ts
const DEFAULT_SCOPE = "default";
const DEFAULT_REMOTE_TYPE = "global";
//#endregion
exports.DEFAULT_REMOTE_TYPE = DEFAULT_REMOTE_TYPE;
exports.DEFAULT_SCOPE = DEFAULT_SCOPE;
//# sourceMappingURL=constant.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"constant.cjs","names":[],"sources":["../src/constant.ts"],"sourcesContent":["export const DEFAULT_SCOPE = 'default';\nexport const DEFAULT_REMOTE_TYPE = 'global';\n"],"mappings":";;AAAA,MAAa,gBAAgB;AAC7B,MAAa,sBAAsB"}

View File

@@ -0,0 +1,7 @@
//#region src/constant.ts
const DEFAULT_SCOPE = "default";
const DEFAULT_REMOTE_TYPE = "global";
//#endregion
export { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE };
//# sourceMappingURL=constant.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"constant.js","names":[],"sources":["../src/constant.ts"],"sourcesContent":["export const DEFAULT_SCOPE = 'default';\nexport const DEFAULT_REMOTE_TYPE = 'global';\n"],"mappings":";AAAA,MAAa,gBAAgB;AAC7B,MAAa,sBAAsB"}

View File

@@ -0,0 +1,161 @@
const require_logger = require('./utils/logger.cjs');
const require_constant = require('./constant.cjs');
const require_share = require('./utils/share.cjs');
const require_env = require('./utils/env.cjs');
const require_plugin = require('./utils/plugin.cjs');
const require_load = require('./utils/load.cjs');
require('./utils/index.cjs');
const require_index$1 = require('./module/index.cjs');
const require_syncHook = require('./utils/hooks/syncHook.cjs');
const require_asyncHook = require('./utils/hooks/asyncHook.cjs');
const require_syncWaterfallHook = require('./utils/hooks/syncWaterfallHook.cjs');
const require_asyncWaterfallHooks = require('./utils/hooks/asyncWaterfallHooks.cjs');
const require_pluginSystem = require('./utils/hooks/pluginSystem.cjs');
require('./utils/hooks/index.cjs');
const require_index$3 = require('./plugins/snapshot/index.cjs');
const require_generate_preload_assets = require('./plugins/generate-preload-assets.cjs');
const require_SnapshotHandler = require('./plugins/snapshot/SnapshotHandler.cjs');
const require_index$4 = require('./shared/index.cjs');
const require_index$5 = require('./remote/index.cjs');
let _module_federation_sdk = require("@module-federation/sdk");
let _module_federation_error_codes = require("@module-federation/error-codes");
//#region src/core.ts
const USE_SNAPSHOT = typeof FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === "boolean" ? !FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN : true;
var ModuleFederation = class {
constructor(userOptions) {
this.hooks = new require_pluginSystem.PluginSystem({
beforeInit: new require_syncWaterfallHook.SyncWaterfallHook("beforeInit"),
init: new require_syncHook.SyncHook(),
beforeInitContainer: new require_asyncWaterfallHooks.AsyncWaterfallHook("beforeInitContainer"),
initContainer: new require_asyncWaterfallHooks.AsyncWaterfallHook("initContainer")
});
this.version = "2.5.0";
this.moduleCache = /* @__PURE__ */ new Map();
this.loaderHook = new require_pluginSystem.PluginSystem({
getModuleInfo: new require_syncHook.SyncHook(),
createScript: new require_syncHook.SyncHook(),
createLink: new require_syncHook.SyncHook(),
fetch: new require_asyncHook.AsyncHook(),
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()
});
this.bridgeHook = new require_pluginSystem.PluginSystem({
beforeBridgeRender: new require_syncHook.SyncHook(),
afterBridgeRender: new require_syncHook.SyncHook(),
beforeBridgeDestroy: new require_syncHook.SyncHook(),
afterBridgeDestroy: new require_syncHook.SyncHook()
});
const plugins = USE_SNAPSHOT ? [require_index$3.snapshotPlugin(), require_generate_preload_assets.generatePreloadAssetsPlugin()] : [];
const defaultOptions = {
id: require_env.getBuilderId(),
name: userOptions.name,
plugins,
remotes: [],
shared: {},
inBrowser: _module_federation_sdk.isBrowserEnvValue
};
this.name = userOptions.name;
this.options = defaultOptions;
this.snapshotHandler = new require_SnapshotHandler.SnapshotHandler(this);
this.sharedHandler = new require_index$4.SharedHandler(this);
this.remoteHandler = new require_index$5.RemoteHandler(this);
this.shareScopeMap = this.sharedHandler.shareScopeMap;
this.registerPlugins([...defaultOptions.plugins, ...userOptions.plugins || []]);
this.options = this.formatOptions(defaultOptions, userOptions);
}
initOptions(userOptions) {
if (userOptions.name && userOptions.name !== this.options.name) require_logger.error((0, _module_federation_error_codes.getShortErrorMsg)(_module_federation_error_codes.RUNTIME_010, _module_federation_error_codes.runtimeDescMap));
this.registerPlugins(userOptions.plugins);
const options = this.formatOptions(this.options, userOptions);
this.options = options;
return options;
}
async loadShare(pkgName, extraOptions) {
return this.sharedHandler.loadShare(pkgName, extraOptions);
}
loadShareSync(pkgName, extraOptions) {
return this.sharedHandler.loadShareSync(pkgName, extraOptions);
}
initializeSharing(shareScopeName = require_constant.DEFAULT_SCOPE, extraOptions) {
return this.sharedHandler.initializeSharing(shareScopeName, extraOptions);
}
initRawContainer(name, url, container) {
const remoteInfo = require_load.getRemoteInfo({
name,
entry: url
});
const module = new require_index$1.Module({
host: this,
remoteInfo
});
module.remoteEntryExports = container;
this.moduleCache.set(name, module);
return module;
}
async loadRemote(id, options) {
return this.remoteHandler.loadRemote(id, options);
}
async preloadRemote(preloadOptions) {
return this.remoteHandler.preloadRemote(preloadOptions);
}
initShareScopeMap(scopeName, shareScope, extraOptions = {}) {
this.sharedHandler.initShareScopeMap(scopeName, shareScope, extraOptions);
}
formatOptions(globalOptions, userOptions) {
const { allShareInfos: shared } = require_share.formatShareConfigs(globalOptions, userOptions);
const { userOptions: userOptionsRes, options: globalOptionsRes } = this.hooks.lifecycle.beforeInit.emit({
origin: this,
userOptions,
options: globalOptions,
shareInfo: shared
});
const remotes = this.remoteHandler.formatAndRegisterRemote(globalOptionsRes, userOptionsRes);
const { allShareInfos } = this.sharedHandler.registerShared(globalOptionsRes, userOptionsRes);
const plugins = [...globalOptionsRes.plugins];
if (userOptionsRes.plugins) userOptionsRes.plugins.forEach((plugin) => {
if (!plugins.includes(plugin)) plugins.push(plugin);
});
const optionsRes = {
...globalOptions,
...userOptions,
plugins,
remotes,
shared: allShareInfos,
id: userOptionsRes.id || globalOptions.id
};
this.hooks.lifecycle.init.emit({
origin: this,
options: optionsRes
});
return optionsRes;
}
registerPlugins(plugins) {
const pluginRes = require_plugin.registerPlugins(plugins, this);
this.options.plugins = this.options.plugins.reduce((res, plugin) => {
if (!plugin) return res;
if (res && !res.find((item) => item.name === plugin.name)) res.push(plugin);
return res;
}, pluginRes || []);
}
registerRemotes(remotes, options) {
return this.remoteHandler.registerRemotes(remotes, options);
}
registerShared(shared) {
this.sharedHandler.registerShared(this.options, {
...this.options,
shared
});
}
};
//#endregion
exports.ModuleFederation = ModuleFederation;
//# sourceMappingURL=core.cjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,197 @@
import { Module as Module$1, RemoteModuleFactory } from "./module/index.js";
import { SyncHook } from "./utils/hooks/syncHook.js";
import { AsyncHook } from "./utils/hooks/asyncHook.js";
import { SyncWaterfallHook } from "./utils/hooks/syncWaterfallHook.js";
import { AsyncWaterfallHook } from "./utils/hooks/asyncWaterfallHooks.js";
import { PluginSystem } from "./utils/hooks/pluginSystem.js";
import { SnapshotHandler } from "./plugins/snapshot/SnapshotHandler.js";
import { RemoteHandler } from "./remote/index.js";
import { SharedHandler } from "./shared/index.js";
import { CallFrom, InitScope, Options, Remote, RemoteEntryExports, RemoteEntryInitOptions, RemoteInfo, ShareInfos, ShareScopeMap, Shared, UserOptions } from "./type/config.js";
import { PreloadRemoteArgs, ResourceLoadContext } from "./type/preload.js";
import { getRemoteEntry } from "./utils/load.js";
import { CreateLinkHookReturnDom, CreateScriptHookReturn, GlobalModuleInfo, ModuleInfo } from "@module-federation/sdk";
//#region src/core.d.ts
declare class ModuleFederation {
options: Options;
hooks: PluginSystem<{
beforeInit: SyncWaterfallHook<{
userOptions: UserOptions;
options: Options;
origin: ModuleFederation;
/**
* @deprecated shareInfo will be removed soon, please use userOptions directly!
*/
shareInfo: ShareInfos;
}>;
init: SyncHook<[{
options: Options;
origin: ModuleFederation;
}], void>;
beforeInitContainer: AsyncWaterfallHook<{
shareScope: ShareScopeMap[string];
initScope: InitScope;
remoteEntryInitOptions: RemoteEntryInitOptions;
remoteInfo: RemoteInfo;
origin: ModuleFederation;
}>;
initContainer: AsyncWaterfallHook<{
shareScope: ShareScopeMap[string];
initScope: InitScope;
remoteEntryInitOptions: RemoteEntryInitOptions;
remoteInfo: RemoteInfo;
remoteEntryExports: RemoteEntryExports;
origin: ModuleFederation;
id?: string;
remoteSnapshot?: ModuleInfo;
}>;
}>;
version: string;
name: string;
moduleCache: Map<string, Module$1>;
snapshotHandler: SnapshotHandler;
sharedHandler: SharedHandler;
remoteHandler: RemoteHandler;
shareScopeMap: ShareScopeMap;
loaderHook: PluginSystem<{
getModuleInfo: SyncHook<[{
target: Record<string, any>;
key: any;
}], void | {
value: any | undefined;
key: string;
}>;
createScript: SyncHook<[{
url: string;
attrs?: Record<string, any>;
/**
* The producer(remote) info bound to this resource.
* Only present when the loader is invoked in a remote-related context
* (e.g. preloadRemote / loading remoteEntry).
*/
remoteInfo?: RemoteInfo;
resourceContext?: ResourceLoadContext;
}], CreateScriptHookReturn>;
createLink: SyncHook<[{
url: string;
attrs?: Record<string, any>;
/**
* The producer(remote) info bound to this resource.
* Only present when the loader is invoked in a remote-related context
* (e.g. preloadRemote / loading remoteEntry).
*/
remoteInfo?: RemoteInfo;
resourceContext?: ResourceLoadContext;
}], CreateLinkHookReturnDom>;
fetch: AsyncHook<[string, RequestInit, (RemoteInfo | undefined)?, (ResourceLoadContext | undefined)?], false | void | Promise<Response>>;
loadEntryError: AsyncHook<[{
getRemoteEntry: typeof getRemoteEntry;
origin: ModuleFederation;
remoteInfo: RemoteInfo;
remoteEntryExports?: RemoteEntryExports | undefined;
globalLoading: Record<string, Promise<void | RemoteEntryExports> | undefined>;
uniqueKey: string;
}], 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<[{
remoteEntryExports: RemoteEntryExports;
expose: string;
moduleInfo: RemoteInfo;
}], RemoteModuleFactory | Promise<RemoteModuleFactory | undefined> | undefined>;
}>;
bridgeHook: PluginSystem<{
beforeBridgeRender: SyncHook<[Record<string, any>], void | Record<string, any>>;
afterBridgeRender: SyncHook<[Record<string, any>], void | Record<string, any>>;
beforeBridgeDestroy: SyncHook<[Record<string, any>], void | Record<string, any>>;
afterBridgeDestroy: SyncHook<[Record<string, any>], void | Record<string, any>>;
}>;
moduleInfo?: GlobalModuleInfo[string];
constructor(userOptions: UserOptions);
initOptions(userOptions: UserOptions): Options;
loadShare<T>(pkgName: string, extraOptions?: {
customShareInfo?: Partial<Shared>;
resolver?: (sharedOptions: ShareInfos[string]) => Shared;
}): Promise<false | (() => T | undefined)>;
loadShareSync<T>(pkgName: string, extraOptions?: {
customShareInfo?: Partial<Shared>;
from?: 'build' | 'runtime';
resolver?: (sharedOptions: ShareInfos[string]) => Shared;
}): () => T | never;
initializeSharing(shareScopeName?: string, extraOptions?: {
initScope?: InitScope;
from?: CallFrom;
strategy?: Shared['strategy'];
}): Array<Promise<void>>;
initRawContainer(name: string, url: string, container: RemoteEntryExports): Module$1;
loadRemote<T>(id: string, options?: {
loadFactory?: boolean;
from: CallFrom;
}): Promise<T | null>;
preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void>;
initShareScopeMap(scopeName: string, shareScope: ShareScopeMap[string], extraOptions?: {
hostShareScopeMap?: ShareScopeMap;
}): void;
formatOptions(globalOptions: Options, userOptions: UserOptions): Options;
registerPlugins(plugins: UserOptions['plugins']): void;
registerRemotes(remotes: Remote[], options?: {
force?: boolean;
}): void;
registerShared(shared: UserOptions['shared']): void;
}
//#endregion
export { ModuleFederation };
//# sourceMappingURL=core.d.ts.map

View File

@@ -0,0 +1,161 @@
import { error } from "./utils/logger.js";
import { DEFAULT_SCOPE } from "./constant.js";
import { formatShareConfigs } from "./utils/share.js";
import { getBuilderId } from "./utils/env.js";
import { registerPlugins } from "./utils/plugin.js";
import { getRemoteInfo } from "./utils/load.js";
import "./utils/index.js";
import { Module as Module$1 } from "./module/index.js";
import { SyncHook } from "./utils/hooks/syncHook.js";
import { AsyncHook } from "./utils/hooks/asyncHook.js";
import { SyncWaterfallHook } from "./utils/hooks/syncWaterfallHook.js";
import { AsyncWaterfallHook } from "./utils/hooks/asyncWaterfallHooks.js";
import { PluginSystem } from "./utils/hooks/pluginSystem.js";
import "./utils/hooks/index.js";
import { snapshotPlugin } from "./plugins/snapshot/index.js";
import { generatePreloadAssetsPlugin } from "./plugins/generate-preload-assets.js";
import { SnapshotHandler } from "./plugins/snapshot/SnapshotHandler.js";
import { SharedHandler } from "./shared/index.js";
import { RemoteHandler } from "./remote/index.js";
import { isBrowserEnvValue } from "@module-federation/sdk";
import { RUNTIME_010, getShortErrorMsg, runtimeDescMap } from "@module-federation/error-codes";
//#region src/core.ts
const USE_SNAPSHOT = typeof FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === "boolean" ? !FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN : true;
var ModuleFederation = class {
constructor(userOptions) {
this.hooks = new PluginSystem({
beforeInit: new SyncWaterfallHook("beforeInit"),
init: new SyncHook(),
beforeInitContainer: new AsyncWaterfallHook("beforeInitContainer"),
initContainer: new AsyncWaterfallHook("initContainer")
});
this.version = "2.5.0";
this.moduleCache = /* @__PURE__ */ new Map();
this.loaderHook = new PluginSystem({
getModuleInfo: new SyncHook(),
createScript: new SyncHook(),
createLink: new SyncHook(),
fetch: new AsyncHook(),
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()
});
this.bridgeHook = new PluginSystem({
beforeBridgeRender: new SyncHook(),
afterBridgeRender: new SyncHook(),
beforeBridgeDestroy: new SyncHook(),
afterBridgeDestroy: new SyncHook()
});
const plugins = USE_SNAPSHOT ? [snapshotPlugin(), generatePreloadAssetsPlugin()] : [];
const defaultOptions = {
id: getBuilderId(),
name: userOptions.name,
plugins,
remotes: [],
shared: {},
inBrowser: isBrowserEnvValue
};
this.name = userOptions.name;
this.options = defaultOptions;
this.snapshotHandler = new SnapshotHandler(this);
this.sharedHandler = new SharedHandler(this);
this.remoteHandler = new RemoteHandler(this);
this.shareScopeMap = this.sharedHandler.shareScopeMap;
this.registerPlugins([...defaultOptions.plugins, ...userOptions.plugins || []]);
this.options = this.formatOptions(defaultOptions, userOptions);
}
initOptions(userOptions) {
if (userOptions.name && userOptions.name !== this.options.name) error(getShortErrorMsg(RUNTIME_010, runtimeDescMap));
this.registerPlugins(userOptions.plugins);
const options = this.formatOptions(this.options, userOptions);
this.options = options;
return options;
}
async loadShare(pkgName, extraOptions) {
return this.sharedHandler.loadShare(pkgName, extraOptions);
}
loadShareSync(pkgName, extraOptions) {
return this.sharedHandler.loadShareSync(pkgName, extraOptions);
}
initializeSharing(shareScopeName = DEFAULT_SCOPE, extraOptions) {
return this.sharedHandler.initializeSharing(shareScopeName, extraOptions);
}
initRawContainer(name, url, container) {
const remoteInfo = getRemoteInfo({
name,
entry: url
});
const module = new Module$1({
host: this,
remoteInfo
});
module.remoteEntryExports = container;
this.moduleCache.set(name, module);
return module;
}
async loadRemote(id, options) {
return this.remoteHandler.loadRemote(id, options);
}
async preloadRemote(preloadOptions) {
return this.remoteHandler.preloadRemote(preloadOptions);
}
initShareScopeMap(scopeName, shareScope, extraOptions = {}) {
this.sharedHandler.initShareScopeMap(scopeName, shareScope, extraOptions);
}
formatOptions(globalOptions, userOptions) {
const { allShareInfos: shared } = formatShareConfigs(globalOptions, userOptions);
const { userOptions: userOptionsRes, options: globalOptionsRes } = this.hooks.lifecycle.beforeInit.emit({
origin: this,
userOptions,
options: globalOptions,
shareInfo: shared
});
const remotes = this.remoteHandler.formatAndRegisterRemote(globalOptionsRes, userOptionsRes);
const { allShareInfos } = this.sharedHandler.registerShared(globalOptionsRes, userOptionsRes);
const plugins = [...globalOptionsRes.plugins];
if (userOptionsRes.plugins) userOptionsRes.plugins.forEach((plugin) => {
if (!plugins.includes(plugin)) plugins.push(plugin);
});
const optionsRes = {
...globalOptions,
...userOptions,
plugins,
remotes,
shared: allShareInfos,
id: userOptionsRes.id || globalOptions.id
};
this.hooks.lifecycle.init.emit({
origin: this,
options: optionsRes
});
return optionsRes;
}
registerPlugins(plugins) {
const pluginRes = registerPlugins(plugins, this);
this.options.plugins = this.options.plugins.reduce((res, plugin) => {
if (!plugin) return res;
if (res && !res.find((item) => item.name === plugin.name)) res.push(plugin);
return res;
}, pluginRes || []);
}
registerRemotes(remotes, options) {
return this.remoteHandler.registerRemotes(remotes, options);
}
registerShared(shared) {
this.sharedHandler.registerShared(this.options, {
...this.options,
shared
});
}
};
//#endregion
export { ModuleFederation };
//# sourceMappingURL=core.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,160 @@
const require_logger = require('./utils/logger.cjs');
const require_tool = require('./utils/tool.cjs');
let _module_federation_sdk = require("@module-federation/sdk");
//#region src/global.ts
const CurrentGlobal = typeof globalThis === "object" ? globalThis : window;
const nativeGlobal = (() => {
try {
return document.defaultView;
} catch {
return CurrentGlobal;
}
})();
const Global = nativeGlobal;
function definePropertyGlobalVal(target, key, val) {
Object.defineProperty(target, key, {
value: val,
configurable: false,
writable: true
});
}
function includeOwnProperty(target, key) {
return Object.hasOwnProperty.call(target, key);
}
if (!includeOwnProperty(CurrentGlobal, "__GLOBAL_LOADING_REMOTE_ENTRY__")) definePropertyGlobalVal(CurrentGlobal, "__GLOBAL_LOADING_REMOTE_ENTRY__", {});
const globalLoading = CurrentGlobal.__GLOBAL_LOADING_REMOTE_ENTRY__;
function setGlobalDefaultVal(target) {
if (includeOwnProperty(target, "__VMOK__") && !includeOwnProperty(target, "__FEDERATION__")) definePropertyGlobalVal(target, "__FEDERATION__", target.__VMOK__);
if (!includeOwnProperty(target, "__FEDERATION__")) {
definePropertyGlobalVal(target, "__FEDERATION__", {
__GLOBAL_PLUGIN__: [],
__INSTANCES__: [],
moduleInfo: {},
__SHARE__: {},
__MANIFEST_LOADING__: {},
__PRELOADED_MAP__: /* @__PURE__ */ new Map()
});
definePropertyGlobalVal(target, "__VMOK__", target.__FEDERATION__);
}
target.__FEDERATION__.__GLOBAL_PLUGIN__ ??= [];
target.__FEDERATION__.__INSTANCES__ ??= [];
target.__FEDERATION__.moduleInfo ??= {};
target.__FEDERATION__.__SHARE__ ??= {};
target.__FEDERATION__.__MANIFEST_LOADING__ ??= {};
target.__FEDERATION__.__PRELOADED_MAP__ ??= /* @__PURE__ */ new Map();
}
setGlobalDefaultVal(CurrentGlobal);
setGlobalDefaultVal(nativeGlobal);
function resetFederationGlobalInfo() {
CurrentGlobal.__FEDERATION__.__GLOBAL_PLUGIN__ = [];
CurrentGlobal.__FEDERATION__.__INSTANCES__ = [];
CurrentGlobal.__FEDERATION__.moduleInfo = {};
CurrentGlobal.__FEDERATION__.__SHARE__ = {};
CurrentGlobal.__FEDERATION__.__MANIFEST_LOADING__ = {};
Object.keys(globalLoading).forEach((key) => {
delete globalLoading[key];
});
}
function setGlobalFederationInstance(FederationInstance) {
CurrentGlobal.__FEDERATION__.__INSTANCES__.push(FederationInstance);
}
function getGlobalFederationConstructor() {
return CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR__;
}
function setGlobalFederationConstructor(FederationConstructor, isDebug = (0, _module_federation_sdk.isDebugMode)()) {
if (isDebug) {
CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR__ = FederationConstructor;
CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "2.5.0";
}
}
function getInfoWithoutType(target, key) {
if (typeof key === "string") if (target[key]) return {
value: target[key],
key
};
else {
const targetKeys = Object.keys(target);
for (const targetKey of targetKeys) {
const [targetTypeOrName, _] = targetKey.split(":");
const nKey = `${targetTypeOrName}:${key}`;
const typeWithKeyRes = target[nKey];
if (typeWithKeyRes) return {
value: typeWithKeyRes,
key: nKey
};
}
return {
value: void 0,
key
};
}
else require_logger.error(`getInfoWithoutType: "key" must be a string, got ${typeof key} (${JSON.stringify(key)}).`);
}
const getGlobalSnapshot = () => nativeGlobal.__FEDERATION__.moduleInfo;
const getTargetSnapshotInfoByModuleInfo = (moduleInfo, snapshot) => {
const getModuleInfo = getInfoWithoutType(snapshot, require_tool.getFMId(moduleInfo)).value;
if (getModuleInfo && !getModuleInfo.version && "version" in moduleInfo && moduleInfo["version"]) getModuleInfo.version = moduleInfo["version"];
if (getModuleInfo) return getModuleInfo;
if ("version" in moduleInfo && moduleInfo["version"]) {
const { version, ...resModuleInfo } = moduleInfo;
const moduleKeyWithoutVersion = require_tool.getFMId(resModuleInfo);
const getModuleInfoWithoutVersion = getInfoWithoutType(nativeGlobal.__FEDERATION__.moduleInfo, moduleKeyWithoutVersion).value;
if (getModuleInfoWithoutVersion?.version === version) return getModuleInfoWithoutVersion;
}
};
const getGlobalSnapshotInfoByModuleInfo = (moduleInfo) => getTargetSnapshotInfoByModuleInfo(moduleInfo, nativeGlobal.__FEDERATION__.moduleInfo);
const setGlobalSnapshotInfoByModuleInfo = (remoteInfo, moduleDetailInfo) => {
const moduleKey = require_tool.getFMId(remoteInfo);
nativeGlobal.__FEDERATION__.moduleInfo[moduleKey] = moduleDetailInfo;
return nativeGlobal.__FEDERATION__.moduleInfo;
};
const addGlobalSnapshot = (moduleInfos) => {
nativeGlobal.__FEDERATION__.moduleInfo = {
...nativeGlobal.__FEDERATION__.moduleInfo,
...moduleInfos
};
return () => {
const keys = Object.keys(moduleInfos);
for (const key of keys) delete nativeGlobal.__FEDERATION__.moduleInfo[key];
};
};
const getRemoteEntryExports = (name, globalName) => {
const remoteEntryKey = globalName || `__FEDERATION_${name}:custom__`;
return {
remoteEntryKey,
entryExports: CurrentGlobal[remoteEntryKey]
};
};
const registerGlobalPlugins = (plugins) => {
const { __GLOBAL_PLUGIN__ } = nativeGlobal.__FEDERATION__;
plugins.forEach((plugin) => {
if (__GLOBAL_PLUGIN__.findIndex((p) => p.name === plugin.name) === -1) __GLOBAL_PLUGIN__.push(plugin);
else require_logger.warn(`The plugin ${plugin.name} has been registered.`);
});
};
const getGlobalHostPlugins = () => nativeGlobal.__FEDERATION__.__GLOBAL_PLUGIN__;
const getPreloaded = (id) => CurrentGlobal.__FEDERATION__.__PRELOADED_MAP__.get(id);
const setPreloaded = (id) => CurrentGlobal.__FEDERATION__.__PRELOADED_MAP__.set(id, true);
//#endregion
exports.CurrentGlobal = CurrentGlobal;
exports.Global = Global;
exports.addGlobalSnapshot = addGlobalSnapshot;
exports.getGlobalFederationConstructor = getGlobalFederationConstructor;
exports.getGlobalHostPlugins = getGlobalHostPlugins;
exports.getGlobalSnapshot = getGlobalSnapshot;
exports.getGlobalSnapshotInfoByModuleInfo = getGlobalSnapshotInfoByModuleInfo;
exports.getInfoWithoutType = getInfoWithoutType;
exports.getPreloaded = getPreloaded;
exports.getRemoteEntryExports = getRemoteEntryExports;
exports.getTargetSnapshotInfoByModuleInfo = getTargetSnapshotInfoByModuleInfo;
exports.globalLoading = globalLoading;
exports.nativeGlobal = nativeGlobal;
exports.registerGlobalPlugins = registerGlobalPlugins;
exports.resetFederationGlobalInfo = resetFederationGlobalInfo;
exports.setGlobalFederationConstructor = setGlobalFederationConstructor;
exports.setGlobalFederationInstance = setGlobalFederationInstance;
exports.setGlobalSnapshotInfoByModuleInfo = setGlobalSnapshotInfoByModuleInfo;
exports.setPreloaded = setPreloaded;
//# sourceMappingURL=global.cjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,45 @@
import { ModuleFederation } from "./core.js";
import { ModuleFederationRuntimePlugin } from "./type/plugin.js";
import { GlobalShareScopeMap, Optional, Remote, RemoteEntryExports } from "./type/config.js";
import { GlobalModuleInfo, ModuleInfo } from "@module-federation/sdk";
//#region src/global.d.ts
interface Federation {
__GLOBAL_PLUGIN__: Array<ModuleFederationRuntimePlugin>;
__DEBUG_CONSTRUCTOR_VERSION__?: string;
moduleInfo: GlobalModuleInfo;
__DEBUG_CONSTRUCTOR__?: typeof ModuleFederation;
__INSTANCES__: Array<ModuleFederation>;
__SHARE__: GlobalShareScopeMap;
__MANIFEST_LOADING__: Record<string, Promise<ModuleInfo>>;
__PRELOADED_MAP__: Map<string, boolean>;
}
declare const CurrentGlobal: typeof globalThis;
declare const Global: typeof globalThis;
declare global {
var __FEDERATION__: Federation, __VMOK__: Federation, __GLOBAL_LOADING_REMOTE_ENTRY__: Record<string, undefined | Promise<RemoteEntryExports | void>>;
}
declare function resetFederationGlobalInfo(): void;
declare function setGlobalFederationInstance(FederationInstance: ModuleFederation): void;
declare function getGlobalFederationConstructor(): typeof ModuleFederation | undefined;
declare function setGlobalFederationConstructor(FederationConstructor: typeof ModuleFederation | undefined, isDebug?: boolean): void;
declare function getInfoWithoutType<T extends object>(target: T, key: keyof T): {
value: T[keyof T] | undefined;
key: string;
};
declare const getGlobalSnapshot: () => GlobalModuleInfo;
declare const getTargetSnapshotInfoByModuleInfo: (moduleInfo: Optional<Remote, "alias">, snapshot: GlobalModuleInfo) => GlobalModuleInfo[string] | undefined;
declare const getGlobalSnapshotInfoByModuleInfo: (moduleInfo: Optional<Remote, "alias">) => GlobalModuleInfo[string] | undefined;
declare const setGlobalSnapshotInfoByModuleInfo: (remoteInfo: Remote, moduleDetailInfo: GlobalModuleInfo[string]) => GlobalModuleInfo;
declare const addGlobalSnapshot: (moduleInfos: GlobalModuleInfo) => (() => void);
declare const getRemoteEntryExports: (name: string, globalName: string | undefined) => {
remoteEntryKey: string;
entryExports: RemoteEntryExports | undefined;
};
declare const registerGlobalPlugins: (plugins: Array<ModuleFederationRuntimePlugin>) => void;
declare const getGlobalHostPlugins: () => Array<ModuleFederationRuntimePlugin>;
declare const getPreloaded: (id: string) => boolean | undefined;
declare const setPreloaded: (id: string) => Map<string, boolean>;
//#endregion
export { CurrentGlobal, Federation, Global, addGlobalSnapshot, getGlobalFederationConstructor, getGlobalHostPlugins, getGlobalSnapshot, getGlobalSnapshotInfoByModuleInfo, getInfoWithoutType, getPreloaded, getRemoteEntryExports, getTargetSnapshotInfoByModuleInfo, registerGlobalPlugins, resetFederationGlobalInfo, setGlobalFederationConstructor, setGlobalFederationInstance, setGlobalSnapshotInfoByModuleInfo, setPreloaded };
//# sourceMappingURL=global.d.ts.map

View File

@@ -0,0 +1,142 @@
import { error, warn as warn$1 } from "./utils/logger.js";
import { getFMId } from "./utils/tool.js";
import { isDebugMode } from "@module-federation/sdk";
//#region src/global.ts
const CurrentGlobal = typeof globalThis === "object" ? globalThis : window;
const nativeGlobal = (() => {
try {
return document.defaultView;
} catch {
return CurrentGlobal;
}
})();
const Global = nativeGlobal;
function definePropertyGlobalVal(target, key, val) {
Object.defineProperty(target, key, {
value: val,
configurable: false,
writable: true
});
}
function includeOwnProperty(target, key) {
return Object.hasOwnProperty.call(target, key);
}
if (!includeOwnProperty(CurrentGlobal, "__GLOBAL_LOADING_REMOTE_ENTRY__")) definePropertyGlobalVal(CurrentGlobal, "__GLOBAL_LOADING_REMOTE_ENTRY__", {});
const globalLoading = CurrentGlobal.__GLOBAL_LOADING_REMOTE_ENTRY__;
function setGlobalDefaultVal(target) {
if (includeOwnProperty(target, "__VMOK__") && !includeOwnProperty(target, "__FEDERATION__")) definePropertyGlobalVal(target, "__FEDERATION__", target.__VMOK__);
if (!includeOwnProperty(target, "__FEDERATION__")) {
definePropertyGlobalVal(target, "__FEDERATION__", {
__GLOBAL_PLUGIN__: [],
__INSTANCES__: [],
moduleInfo: {},
__SHARE__: {},
__MANIFEST_LOADING__: {},
__PRELOADED_MAP__: /* @__PURE__ */ new Map()
});
definePropertyGlobalVal(target, "__VMOK__", target.__FEDERATION__);
}
target.__FEDERATION__.__GLOBAL_PLUGIN__ ??= [];
target.__FEDERATION__.__INSTANCES__ ??= [];
target.__FEDERATION__.moduleInfo ??= {};
target.__FEDERATION__.__SHARE__ ??= {};
target.__FEDERATION__.__MANIFEST_LOADING__ ??= {};
target.__FEDERATION__.__PRELOADED_MAP__ ??= /* @__PURE__ */ new Map();
}
setGlobalDefaultVal(CurrentGlobal);
setGlobalDefaultVal(nativeGlobal);
function resetFederationGlobalInfo() {
CurrentGlobal.__FEDERATION__.__GLOBAL_PLUGIN__ = [];
CurrentGlobal.__FEDERATION__.__INSTANCES__ = [];
CurrentGlobal.__FEDERATION__.moduleInfo = {};
CurrentGlobal.__FEDERATION__.__SHARE__ = {};
CurrentGlobal.__FEDERATION__.__MANIFEST_LOADING__ = {};
Object.keys(globalLoading).forEach((key) => {
delete globalLoading[key];
});
}
function setGlobalFederationInstance(FederationInstance) {
CurrentGlobal.__FEDERATION__.__INSTANCES__.push(FederationInstance);
}
function getGlobalFederationConstructor() {
return CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR__;
}
function setGlobalFederationConstructor(FederationConstructor, isDebug = isDebugMode()) {
if (isDebug) {
CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR__ = FederationConstructor;
CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "2.5.0";
}
}
function getInfoWithoutType(target, key) {
if (typeof key === "string") if (target[key]) return {
value: target[key],
key
};
else {
const targetKeys = Object.keys(target);
for (const targetKey of targetKeys) {
const [targetTypeOrName, _] = targetKey.split(":");
const nKey = `${targetTypeOrName}:${key}`;
const typeWithKeyRes = target[nKey];
if (typeWithKeyRes) return {
value: typeWithKeyRes,
key: nKey
};
}
return {
value: void 0,
key
};
}
else error(`getInfoWithoutType: "key" must be a string, got ${typeof key} (${JSON.stringify(key)}).`);
}
const getGlobalSnapshot = () => nativeGlobal.__FEDERATION__.moduleInfo;
const getTargetSnapshotInfoByModuleInfo = (moduleInfo, snapshot) => {
const getModuleInfo = getInfoWithoutType(snapshot, getFMId(moduleInfo)).value;
if (getModuleInfo && !getModuleInfo.version && "version" in moduleInfo && moduleInfo["version"]) getModuleInfo.version = moduleInfo["version"];
if (getModuleInfo) return getModuleInfo;
if ("version" in moduleInfo && moduleInfo["version"]) {
const { version, ...resModuleInfo } = moduleInfo;
const moduleKeyWithoutVersion = getFMId(resModuleInfo);
const getModuleInfoWithoutVersion = getInfoWithoutType(nativeGlobal.__FEDERATION__.moduleInfo, moduleKeyWithoutVersion).value;
if (getModuleInfoWithoutVersion?.version === version) return getModuleInfoWithoutVersion;
}
};
const getGlobalSnapshotInfoByModuleInfo = (moduleInfo) => getTargetSnapshotInfoByModuleInfo(moduleInfo, nativeGlobal.__FEDERATION__.moduleInfo);
const setGlobalSnapshotInfoByModuleInfo = (remoteInfo, moduleDetailInfo) => {
const moduleKey = getFMId(remoteInfo);
nativeGlobal.__FEDERATION__.moduleInfo[moduleKey] = moduleDetailInfo;
return nativeGlobal.__FEDERATION__.moduleInfo;
};
const addGlobalSnapshot = (moduleInfos) => {
nativeGlobal.__FEDERATION__.moduleInfo = {
...nativeGlobal.__FEDERATION__.moduleInfo,
...moduleInfos
};
return () => {
const keys = Object.keys(moduleInfos);
for (const key of keys) delete nativeGlobal.__FEDERATION__.moduleInfo[key];
};
};
const getRemoteEntryExports = (name, globalName) => {
const remoteEntryKey = globalName || `__FEDERATION_${name}:custom__`;
return {
remoteEntryKey,
entryExports: CurrentGlobal[remoteEntryKey]
};
};
const registerGlobalPlugins = (plugins) => {
const { __GLOBAL_PLUGIN__ } = nativeGlobal.__FEDERATION__;
plugins.forEach((plugin) => {
if (__GLOBAL_PLUGIN__.findIndex((p) => p.name === plugin.name) === -1) __GLOBAL_PLUGIN__.push(plugin);
else warn$1(`The plugin ${plugin.name} has been registered.`);
});
};
const getGlobalHostPlugins = () => nativeGlobal.__FEDERATION__.__GLOBAL_PLUGIN__;
const getPreloaded = (id) => CurrentGlobal.__FEDERATION__.__PRELOADED_MAP__.get(id);
const setPreloaded = (id) => CurrentGlobal.__FEDERATION__.__PRELOADED_MAP__.set(id, true);
//#endregion
export { CurrentGlobal, Global, addGlobalSnapshot, getGlobalFederationConstructor, getGlobalHostPlugins, getGlobalSnapshot, getGlobalSnapshotInfoByModuleInfo, getInfoWithoutType, getPreloaded, getRemoteEntryExports, getTargetSnapshotInfoByModuleInfo, globalLoading, nativeGlobal, registerGlobalPlugins, resetFederationGlobalInfo, setGlobalFederationConstructor, setGlobalFederationInstance, setGlobalSnapshotInfoByModuleInfo, setPreloaded };
//# sourceMappingURL=global.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,44 @@
const require_global = require('./global.cjs');
const require_share = require('./utils/share.cjs');
const require_manifest = require('./utils/manifest.cjs');
const require_load = require('./utils/load.cjs');
require('./utils/index.cjs');
const require_preload = require('./utils/preload.cjs');
//#region src/helpers.ts
const ShareUtils = {
getRegisteredShare: require_share.getRegisteredShare,
getGlobalShareScope: require_share.getGlobalShareScope
};
const GlobalUtils = {
Global: require_global.Global,
nativeGlobal: require_global.nativeGlobal,
resetFederationGlobalInfo: require_global.resetFederationGlobalInfo,
setGlobalFederationInstance: require_global.setGlobalFederationInstance,
getGlobalFederationConstructor: require_global.getGlobalFederationConstructor,
setGlobalFederationConstructor: require_global.setGlobalFederationConstructor,
getInfoWithoutType: require_global.getInfoWithoutType,
getGlobalSnapshot: require_global.getGlobalSnapshot,
getTargetSnapshotInfoByModuleInfo: require_global.getTargetSnapshotInfoByModuleInfo,
getGlobalSnapshotInfoByModuleInfo: require_global.getGlobalSnapshotInfoByModuleInfo,
setGlobalSnapshotInfoByModuleInfo: require_global.setGlobalSnapshotInfoByModuleInfo,
addGlobalSnapshot: require_global.addGlobalSnapshot,
getRemoteEntryExports: require_global.getRemoteEntryExports,
registerGlobalPlugins: require_global.registerGlobalPlugins,
getGlobalHostPlugins: require_global.getGlobalHostPlugins,
getPreloaded: require_global.getPreloaded,
setPreloaded: require_global.setPreloaded
};
var helpers_default = {
global: GlobalUtils,
share: ShareUtils,
utils: {
matchRemoteWithNameAndExpose: require_manifest.matchRemoteWithNameAndExpose,
preloadAssets: require_preload.preloadAssets,
getRemoteInfo: require_load.getRemoteInfo
}
};
//#endregion
exports.default = helpers_default;
//# sourceMappingURL=helpers.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"helpers.cjs","names":[],"sources":["../src/helpers.ts"],"sourcesContent":["import {\n nativeGlobal,\n resetFederationGlobalInfo,\n setGlobalFederationInstance,\n getGlobalFederationConstructor,\n setGlobalFederationConstructor,\n getInfoWithoutType,\n getGlobalSnapshot,\n getTargetSnapshotInfoByModuleInfo,\n getGlobalSnapshotInfoByModuleInfo,\n setGlobalSnapshotInfoByModuleInfo,\n addGlobalSnapshot,\n getRemoteEntryExports,\n registerGlobalPlugins,\n getGlobalHostPlugins,\n getPreloaded,\n setPreloaded,\n Global,\n} from './global';\nimport { getRegisteredShare, getGlobalShareScope } from './utils/share';\nimport { getRemoteInfo, matchRemoteWithNameAndExpose } from './utils';\nimport { preloadAssets } from './utils/preload';\ninterface IShareUtils {\n getRegisteredShare: typeof getRegisteredShare;\n getGlobalShareScope: typeof getGlobalShareScope;\n}\nconst ShareUtils: IShareUtils = {\n getRegisteredShare,\n getGlobalShareScope,\n};\n\ninterface IGlobalUtils {\n Global: typeof Global;\n nativeGlobal: typeof global;\n resetFederationGlobalInfo: typeof resetFederationGlobalInfo;\n setGlobalFederationInstance: typeof setGlobalFederationInstance;\n getGlobalFederationConstructor: typeof getGlobalFederationConstructor;\n setGlobalFederationConstructor: typeof setGlobalFederationConstructor;\n getInfoWithoutType: typeof getInfoWithoutType;\n getGlobalSnapshot: typeof getGlobalSnapshot;\n getTargetSnapshotInfoByModuleInfo: typeof getTargetSnapshotInfoByModuleInfo;\n getGlobalSnapshotInfoByModuleInfo: typeof getGlobalSnapshotInfoByModuleInfo;\n setGlobalSnapshotInfoByModuleInfo: typeof setGlobalSnapshotInfoByModuleInfo;\n addGlobalSnapshot: typeof addGlobalSnapshot;\n getRemoteEntryExports: typeof getRemoteEntryExports;\n registerGlobalPlugins: typeof registerGlobalPlugins;\n getGlobalHostPlugins: typeof getGlobalHostPlugins;\n getPreloaded: typeof getPreloaded;\n setPreloaded: typeof setPreloaded;\n}\n\nconst GlobalUtils: IGlobalUtils = {\n Global,\n nativeGlobal,\n resetFederationGlobalInfo,\n setGlobalFederationInstance,\n getGlobalFederationConstructor,\n setGlobalFederationConstructor,\n getInfoWithoutType,\n getGlobalSnapshot,\n getTargetSnapshotInfoByModuleInfo,\n getGlobalSnapshotInfoByModuleInfo,\n setGlobalSnapshotInfoByModuleInfo,\n addGlobalSnapshot,\n getRemoteEntryExports,\n registerGlobalPlugins,\n getGlobalHostPlugins,\n getPreloaded,\n setPreloaded,\n};\n\nexport default {\n global: GlobalUtils,\n share: ShareUtils,\n utils: {\n matchRemoteWithNameAndExpose,\n preloadAssets,\n getRemoteInfo,\n },\n};\n\nexport type { IGlobalUtils, IShareUtils };\n"],"mappings":";;;;;;;;AA0BA,MAAM,aAA0B;CAC9B;CACA;CACD;AAsBD,MAAM,cAA4B;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,sBAAe;CACb,QAAQ;CACR,OAAO;CACP,OAAO;EACL;EACA;EACA;EACD;CACF"}

View File

@@ -0,0 +1,30 @@
import { Global, addGlobalSnapshot, getGlobalFederationConstructor, getGlobalHostPlugins, getGlobalSnapshot, getGlobalSnapshotInfoByModuleInfo, getInfoWithoutType, getPreloaded, getRemoteEntryExports, getTargetSnapshotInfoByModuleInfo, registerGlobalPlugins, resetFederationGlobalInfo, setGlobalFederationConstructor, setGlobalFederationInstance, setGlobalSnapshotInfoByModuleInfo, setPreloaded } from "./global.js";
import { getGlobalShareScope, getRegisteredShare } from "./utils/share.js";
//#region src/helpers.d.ts
interface IShareUtils {
getRegisteredShare: typeof getRegisteredShare;
getGlobalShareScope: typeof getGlobalShareScope;
}
interface IGlobalUtils {
Global: typeof Global;
nativeGlobal: typeof global;
resetFederationGlobalInfo: typeof resetFederationGlobalInfo;
setGlobalFederationInstance: typeof setGlobalFederationInstance;
getGlobalFederationConstructor: typeof getGlobalFederationConstructor;
setGlobalFederationConstructor: typeof setGlobalFederationConstructor;
getInfoWithoutType: typeof getInfoWithoutType;
getGlobalSnapshot: typeof getGlobalSnapshot;
getTargetSnapshotInfoByModuleInfo: typeof getTargetSnapshotInfoByModuleInfo;
getGlobalSnapshotInfoByModuleInfo: typeof getGlobalSnapshotInfoByModuleInfo;
setGlobalSnapshotInfoByModuleInfo: typeof setGlobalSnapshotInfoByModuleInfo;
addGlobalSnapshot: typeof addGlobalSnapshot;
getRemoteEntryExports: typeof getRemoteEntryExports;
registerGlobalPlugins: typeof registerGlobalPlugins;
getGlobalHostPlugins: typeof getGlobalHostPlugins;
getPreloaded: typeof getPreloaded;
setPreloaded: typeof setPreloaded;
}
//#endregion
export { type IGlobalUtils, type IShareUtils };
//# sourceMappingURL=helpers.d.ts.map

View File

@@ -0,0 +1,44 @@
import { Global, addGlobalSnapshot, getGlobalFederationConstructor, getGlobalHostPlugins, getGlobalSnapshot, getGlobalSnapshotInfoByModuleInfo, getInfoWithoutType, getPreloaded, getRemoteEntryExports, getTargetSnapshotInfoByModuleInfo, nativeGlobal, registerGlobalPlugins, resetFederationGlobalInfo, setGlobalFederationConstructor, setGlobalFederationInstance, setGlobalSnapshotInfoByModuleInfo, setPreloaded } from "./global.js";
import { getGlobalShareScope, getRegisteredShare } from "./utils/share.js";
import { matchRemoteWithNameAndExpose } from "./utils/manifest.js";
import { getRemoteInfo } from "./utils/load.js";
import "./utils/index.js";
import { preloadAssets } from "./utils/preload.js";
//#region src/helpers.ts
const ShareUtils = {
getRegisteredShare,
getGlobalShareScope
};
const GlobalUtils = {
Global,
nativeGlobal,
resetFederationGlobalInfo,
setGlobalFederationInstance,
getGlobalFederationConstructor,
setGlobalFederationConstructor,
getInfoWithoutType,
getGlobalSnapshot,
getTargetSnapshotInfoByModuleInfo,
getGlobalSnapshotInfoByModuleInfo,
setGlobalSnapshotInfoByModuleInfo,
addGlobalSnapshot,
getRemoteEntryExports,
registerGlobalPlugins,
getGlobalHostPlugins,
getPreloaded,
setPreloaded
};
var helpers_default = {
global: GlobalUtils,
share: ShareUtils,
utils: {
matchRemoteWithNameAndExpose,
preloadAssets,
getRemoteInfo
}
};
//#endregion
export { helpers_default as default };
//# sourceMappingURL=helpers.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"helpers.js","names":[],"sources":["../src/helpers.ts"],"sourcesContent":["import {\n nativeGlobal,\n resetFederationGlobalInfo,\n setGlobalFederationInstance,\n getGlobalFederationConstructor,\n setGlobalFederationConstructor,\n getInfoWithoutType,\n getGlobalSnapshot,\n getTargetSnapshotInfoByModuleInfo,\n getGlobalSnapshotInfoByModuleInfo,\n setGlobalSnapshotInfoByModuleInfo,\n addGlobalSnapshot,\n getRemoteEntryExports,\n registerGlobalPlugins,\n getGlobalHostPlugins,\n getPreloaded,\n setPreloaded,\n Global,\n} from './global';\nimport { getRegisteredShare, getGlobalShareScope } from './utils/share';\nimport { getRemoteInfo, matchRemoteWithNameAndExpose } from './utils';\nimport { preloadAssets } from './utils/preload';\ninterface IShareUtils {\n getRegisteredShare: typeof getRegisteredShare;\n getGlobalShareScope: typeof getGlobalShareScope;\n}\nconst ShareUtils: IShareUtils = {\n getRegisteredShare,\n getGlobalShareScope,\n};\n\ninterface IGlobalUtils {\n Global: typeof Global;\n nativeGlobal: typeof global;\n resetFederationGlobalInfo: typeof resetFederationGlobalInfo;\n setGlobalFederationInstance: typeof setGlobalFederationInstance;\n getGlobalFederationConstructor: typeof getGlobalFederationConstructor;\n setGlobalFederationConstructor: typeof setGlobalFederationConstructor;\n getInfoWithoutType: typeof getInfoWithoutType;\n getGlobalSnapshot: typeof getGlobalSnapshot;\n getTargetSnapshotInfoByModuleInfo: typeof getTargetSnapshotInfoByModuleInfo;\n getGlobalSnapshotInfoByModuleInfo: typeof getGlobalSnapshotInfoByModuleInfo;\n setGlobalSnapshotInfoByModuleInfo: typeof setGlobalSnapshotInfoByModuleInfo;\n addGlobalSnapshot: typeof addGlobalSnapshot;\n getRemoteEntryExports: typeof getRemoteEntryExports;\n registerGlobalPlugins: typeof registerGlobalPlugins;\n getGlobalHostPlugins: typeof getGlobalHostPlugins;\n getPreloaded: typeof getPreloaded;\n setPreloaded: typeof setPreloaded;\n}\n\nconst GlobalUtils: IGlobalUtils = {\n Global,\n nativeGlobal,\n resetFederationGlobalInfo,\n setGlobalFederationInstance,\n getGlobalFederationConstructor,\n setGlobalFederationConstructor,\n getInfoWithoutType,\n getGlobalSnapshot,\n getTargetSnapshotInfoByModuleInfo,\n getGlobalSnapshotInfoByModuleInfo,\n setGlobalSnapshotInfoByModuleInfo,\n addGlobalSnapshot,\n getRemoteEntryExports,\n registerGlobalPlugins,\n getGlobalHostPlugins,\n getPreloaded,\n setPreloaded,\n};\n\nexport default {\n global: GlobalUtils,\n share: ShareUtils,\n utils: {\n matchRemoteWithNameAndExpose,\n preloadAssets,\n getRemoteInfo,\n },\n};\n\nexport type { IGlobalUtils, IShareUtils };\n"],"mappings":";;;;;;;;AA0BA,MAAM,aAA0B;CAC9B;CACA;CACD;AAsBD,MAAM,cAA4B;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,sBAAe;CACb,QAAQ;CACR,OAAO;CACP,OAAO;EACL;EACA;EACA;EACD;CACF"}

View File

@@ -0,0 +1,60 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_logger = require('./utils/logger.cjs');
const require_tool = require('./utils/tool.cjs');
const require_global = require('./global.cjs');
const require_index = require('./utils/semver/index.cjs');
const require_share = require('./utils/share.cjs');
const require_manifest = require('./utils/manifest.cjs');
const require_load = require('./utils/load.cjs');
require('./utils/index.cjs');
const require_helpers = require('./helpers.cjs');
const require_index$2 = require('./module/index.cjs');
const require_core = require('./core.cjs');
const require_index$3 = require('./type/index.cjs');
let _module_federation_sdk = require("@module-federation/sdk");
//#region src/index.ts
const helpers = require_helpers.default;
//#endregion
exports.CurrentGlobal = require_global.CurrentGlobal;
exports.Global = require_global.Global;
exports.Module = require_index$2.Module;
exports.ModuleFederation = require_core.ModuleFederation;
exports.addGlobalSnapshot = require_global.addGlobalSnapshot;
exports.assert = require_logger.assert;
exports.error = require_logger.error;
exports.getGlobalFederationConstructor = require_global.getGlobalFederationConstructor;
exports.getGlobalSnapshot = require_global.getGlobalSnapshot;
exports.getInfoWithoutType = require_global.getInfoWithoutType;
exports.getRegisteredShare = require_share.getRegisteredShare;
exports.getRemoteEntry = require_load.getRemoteEntry;
exports.getRemoteInfo = require_load.getRemoteInfo;
exports.helpers = helpers;
exports.isStaticResourcesEqual = require_tool.isStaticResourcesEqual;
Object.defineProperty(exports, 'loadScript', {
enumerable: true,
get: function () {
return _module_federation_sdk.loadScript;
}
});
Object.defineProperty(exports, 'loadScriptNode', {
enumerable: true,
get: function () {
return _module_federation_sdk.loadScriptNode;
}
});
exports.matchRemoteWithNameAndExpose = require_manifest.matchRemoteWithNameAndExpose;
exports.registerGlobalPlugins = require_global.registerGlobalPlugins;
exports.resetFederationGlobalInfo = require_global.resetFederationGlobalInfo;
exports.safeWrapper = require_tool.safeWrapper;
exports.satisfy = require_index.satisfy;
exports.setGlobalFederationConstructor = require_global.setGlobalFederationConstructor;
exports.setGlobalFederationInstance = require_global.setGlobalFederationInstance;
Object.defineProperty(exports, 'types', {
enumerable: true,
get: function () {
return require_index$3.type_exports;
}
});
//# sourceMappingURL=index.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.cjs","names":["helpersDefault"],"sources":["../src/index.ts"],"sourcesContent":["import helpersDefault, { type IGlobalUtils, type IShareUtils } from './helpers';\n\nconst helpers = helpersDefault;\n\nexport { ModuleFederation } from './core';\nexport {\n type Federation,\n CurrentGlobal,\n Global,\n getGlobalFederationConstructor,\n setGlobalFederationInstance,\n setGlobalFederationConstructor,\n resetFederationGlobalInfo,\n addGlobalSnapshot,\n getGlobalSnapshot,\n getInfoWithoutType,\n} from './global';\nexport type { UserOptions, ModuleFederationRuntimePlugin } from './type';\nexport { assert, error } from './utils/logger';\nexport { registerGlobalPlugins } from './global';\nexport {\n getRemoteEntry,\n getRemoteInfo,\n isStaticResourcesEqual,\n matchRemoteWithNameAndExpose,\n safeWrapper,\n} from './utils';\nexport { getRegisteredShare } from '../src/utils/share';\nexport { loadScript, loadScriptNode } from '@module-federation/sdk';\nexport { Module } from './module';\nexport * as types from './type';\nexport { helpers };\nexport { satisfy } from '../src/utils/semver';\nexport type { IGlobalUtils, IShareUtils };\n"],"mappings":";;;;;;;;;;;;;;;;AAEA,MAAM,UAAUA"}

View File

@@ -0,0 +1,29 @@
import { Module } from "./module/index.js";
import { CurrentGlobal, Federation, Global, addGlobalSnapshot, getGlobalFederationConstructor, getGlobalSnapshot, getInfoWithoutType, registerGlobalPlugins, resetFederationGlobalInfo, setGlobalFederationConstructor, setGlobalFederationInstance } from "./global.js";
import { ModuleFederation } from "./core.js";
import { ModuleFederationRuntimePlugin } from "./type/plugin.js";
import { UserOptions } from "./type/config.js";
import { index_d_exports } from "./type/index.js";
import { isStaticResourcesEqual, safeWrapper } from "./utils/tool.js";
import { matchRemoteWithNameAndExpose } from "./utils/manifest.js";
import { assert, error } from "./utils/logger.js";
import { getRemoteEntry, getRemoteInfo } from "./utils/load.js";
import { preloadAssets } from "./utils/preload.js";
import { getRegisteredShare } from "./utils/share.js";
import { IGlobalUtils, IShareUtils } from "./helpers.js";
import { satisfy } from "./utils/semver/index.js";
import { loadScript, loadScriptNode } from "@module-federation/sdk";
//#region src/index.d.ts
declare const helpers: {
global: IGlobalUtils;
share: IShareUtils;
utils: {
matchRemoteWithNameAndExpose: typeof matchRemoteWithNameAndExpose;
preloadAssets: typeof preloadAssets;
getRemoteInfo: typeof getRemoteInfo;
};
};
//#endregion
export { CurrentGlobal, type Federation, Global, type IGlobalUtils, type IShareUtils, Module, ModuleFederation, type ModuleFederationRuntimePlugin, type UserOptions, addGlobalSnapshot, assert, error, getGlobalFederationConstructor, getGlobalSnapshot, getInfoWithoutType, getRegisteredShare, getRemoteEntry, getRemoteInfo, helpers, isStaticResourcesEqual, loadScript, loadScriptNode, matchRemoteWithNameAndExpose, registerGlobalPlugins, resetFederationGlobalInfo, safeWrapper, satisfy, setGlobalFederationConstructor, setGlobalFederationInstance, index_d_exports as types };
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,20 @@
import { assert, error } from "./utils/logger.js";
import { isStaticResourcesEqual, safeWrapper } from "./utils/tool.js";
import { CurrentGlobal, Global, addGlobalSnapshot, getGlobalFederationConstructor, getGlobalSnapshot, getInfoWithoutType, registerGlobalPlugins, resetFederationGlobalInfo, setGlobalFederationConstructor, setGlobalFederationInstance } from "./global.js";
import { satisfy } from "./utils/semver/index.js";
import { getRegisteredShare } from "./utils/share.js";
import { matchRemoteWithNameAndExpose } from "./utils/manifest.js";
import { getRemoteEntry, getRemoteInfo } from "./utils/load.js";
import "./utils/index.js";
import helpers_default from "./helpers.js";
import { Module } from "./module/index.js";
import { ModuleFederation } from "./core.js";
import { type_exports } from "./type/index.js";
import { loadScript, loadScriptNode } from "@module-federation/sdk";
//#region src/index.ts
const helpers = helpers_default;
//#endregion
export { CurrentGlobal, Global, Module, ModuleFederation, addGlobalSnapshot, assert, error, getGlobalFederationConstructor, getGlobalSnapshot, getInfoWithoutType, getRegisteredShare, getRemoteEntry, getRemoteInfo, helpers, isStaticResourcesEqual, loadScript, loadScriptNode, matchRemoteWithNameAndExpose, registerGlobalPlugins, resetFederationGlobalInfo, safeWrapper, satisfy, setGlobalFederationConstructor, setGlobalFederationInstance, type_exports as types };
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","names":["helpersDefault"],"sources":["../src/index.ts"],"sourcesContent":["import helpersDefault, { type IGlobalUtils, type IShareUtils } from './helpers';\n\nconst helpers = helpersDefault;\n\nexport { ModuleFederation } from './core';\nexport {\n type Federation,\n CurrentGlobal,\n Global,\n getGlobalFederationConstructor,\n setGlobalFederationInstance,\n setGlobalFederationConstructor,\n resetFederationGlobalInfo,\n addGlobalSnapshot,\n getGlobalSnapshot,\n getInfoWithoutType,\n} from './global';\nexport type { UserOptions, ModuleFederationRuntimePlugin } from './type';\nexport { assert, error } from './utils/logger';\nexport { registerGlobalPlugins } from './global';\nexport {\n getRemoteEntry,\n getRemoteInfo,\n isStaticResourcesEqual,\n matchRemoteWithNameAndExpose,\n safeWrapper,\n} from './utils';\nexport { getRegisteredShare } from '../src/utils/share';\nexport { loadScript, loadScriptNode } from '@module-federation/sdk';\nexport { Module } from './module';\nexport * as types from './type';\nexport { helpers };\nexport { satisfy } from '../src/utils/semver';\nexport type { IGlobalUtils, IShareUtils };\n"],"mappings":";;;;;;;;;;;;;;;AAEA,MAAM,UAAUA"}

View File

@@ -0,0 +1,266 @@
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');
const require_context = require('../utils/context.cjs');
require('../utils/index.cjs');
let _module_federation_sdk = require("@module-federation/sdk");
let _module_federation_error_codes = require("@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) {
const localShareScopeMap = hostShareScopeMap;
const shareScopeKeys = Array.isArray(remoteInfo.shareScope) ? remoteInfo.shareScope : [remoteInfo.shareScope];
if (!shareScopeKeys.length) shareScopeKeys.push("default");
shareScopeKeys.forEach((shareScopeKey) => {
if (!localShareScopeMap[shareScopeKey]) localShareScopeMap[shareScopeKey] = {};
});
const remoteEntryInitOptions = {
version: remoteInfo.version || "",
shareScopeKeys: Array.isArray(remoteInfo.shareScope) ? shareScopeKeys : remoteInfo.shareScope || "default"
};
Object.defineProperty(remoteEntryInitOptions, "shareScopeMap", {
value: localShareScopeMap,
enumerable: false
});
return {
remoteEntryInitOptions,
shareScope: localShareScopeMap[shareScopeKeys[0]],
initScope: rawInitScope ?? []
};
}
var Module = class {
constructor({ remoteInfo, host }) {
this.inited = false;
this.initing = false;
this.lib = void 0;
this.remoteInfo = remoteInfo;
this.host = host;
}
async getEntry(expose) {
if (this.remoteEntryExports) return this.remoteEntryExports;
const remoteEntryExports = await require_load.getRemoteEntry({
origin: this.host,
remoteInfo: this.remoteInfo,
remoteEntryExports: this.remoteEntryExports,
resourceContext: {
initiator: "loadRemote",
id: require_manifest.composeRemoteRequestId(this.remoteInfo.name, expose),
resourceType: "remoteEntry"
}
});
require_logger.assert(remoteEntryExports, `remoteEntryExports is undefined \n ${(0, _module_federation_sdk.safeToString)(this.remoteInfo)}`);
this.remoteEntryExports = remoteEntryExports;
return this.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) {
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;
}
this.initing = true;
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);
const initContainerOptions = await this.host.hooks.lifecycle.beforeInitContainer.emit({
shareScope,
remoteEntryInitOptions,
initScope,
remoteInfo: this.remoteInfo,
origin: this.host
});
if (typeof remoteEntryExports?.init === "undefined") require_logger.error(_module_federation_error_codes.RUNTIME_002, _module_federation_error_codes.runtimeDescMap, {
hostName: this.host.name,
remoteName: this.remoteInfo.name,
remoteEntryUrl: this.remoteInfo.entry,
remoteEntryKey: this.remoteInfo.entryGlobalName
}, void 0, require_context.optionsToMFContext(this.host.options));
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({
...initContainerOptions,
id,
remoteSnapshot,
remoteEntryExports
});
this.inited = true;
})();
try {
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 {
this.initing = false;
this.initPromise = void 0;
}
return remoteEntryExports;
}
async get(id, expose, options, remoteSnapshot) {
const { loadFactory = true } = options || { loadFactory: true };
const remoteEntryExports = await this.init(id, remoteSnapshot, void 0, expose);
this.lib = remoteEntryExports;
await this.host.loaderHook.lifecycle.beforeGetExpose.emit({
id,
expose,
moduleInfo: this.remoteInfo,
remoteEntryExports,
origin: this.host
});
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;
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;
}
}
wraperFactory(moduleFactory, id) {
function defineModuleId(res, id) {
if (res && typeof res === "object" && Object.isExtensible(res) && !Object.getOwnPropertyDescriptor(res, Symbol.for("mf_module_id"))) Object.defineProperty(res, Symbol.for("mf_module_id"), {
value: id,
enumerable: false
});
}
return () => {
const res = moduleFactory();
if (res instanceof Promise) return res.then((asyncRes) => {
defineModuleId(asyncRes, id);
return asyncRes;
});
defineModuleId(res, id);
return res;
};
}
};
//#endregion
exports.Module = Module;
//# sourceMappingURL=index.cjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,32 @@
import { ModuleFederation } from "../core.js";
import { InitScope, RemoteEntryExports, RemoteInfo } from "../type/config.js";
import { ModuleInfo } from "@module-federation/sdk";
//#region src/module/index.d.ts
type ModuleOptions = ConstructorParameters<typeof Module$1>[0];
type RemoteModuleFactory = () => unknown | Promise<unknown>;
declare class Module$1 {
remoteInfo: RemoteInfo;
inited: boolean;
initing: boolean;
initPromise?: Promise<void>;
remoteEntryExports?: RemoteEntryExports;
lib: RemoteEntryExports | undefined;
host: ModuleFederation;
constructor({
remoteInfo,
host
}: {
remoteInfo: RemoteInfo;
host: ModuleFederation;
});
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<unknown>;
private wraperFactory;
}
//#endregion
export { Module$1 as Module, ModuleOptions, RemoteModuleFactory };
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,266 @@
import { assert, error } from "../utils/logger.js";
import { processModuleAlias } from "../utils/tool.js";
import { composeRemoteRequestId } from "../utils/manifest.js";
import { getRemoteEntry } from "../utils/load.js";
import { optionsToMFContext } from "../utils/context.js";
import "../utils/index.js";
import { safeToString } from "@module-federation/sdk";
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) {
const localShareScopeMap = hostShareScopeMap;
const shareScopeKeys = Array.isArray(remoteInfo.shareScope) ? remoteInfo.shareScope : [remoteInfo.shareScope];
if (!shareScopeKeys.length) shareScopeKeys.push("default");
shareScopeKeys.forEach((shareScopeKey) => {
if (!localShareScopeMap[shareScopeKey]) localShareScopeMap[shareScopeKey] = {};
});
const remoteEntryInitOptions = {
version: remoteInfo.version || "",
shareScopeKeys: Array.isArray(remoteInfo.shareScope) ? shareScopeKeys : remoteInfo.shareScope || "default"
};
Object.defineProperty(remoteEntryInitOptions, "shareScopeMap", {
value: localShareScopeMap,
enumerable: false
});
return {
remoteEntryInitOptions,
shareScope: localShareScopeMap[shareScopeKeys[0]],
initScope: rawInitScope ?? []
};
}
var Module$1 = class {
constructor({ remoteInfo, host }) {
this.inited = false;
this.initing = false;
this.lib = void 0;
this.remoteInfo = remoteInfo;
this.host = host;
}
async getEntry(expose) {
if (this.remoteEntryExports) return this.remoteEntryExports;
const remoteEntryExports = await getRemoteEntry({
origin: this.host,
remoteInfo: this.remoteInfo,
remoteEntryExports: this.remoteEntryExports,
resourceContext: {
initiator: "loadRemote",
id: composeRemoteRequestId(this.remoteInfo.name, expose),
resourceType: "remoteEntry"
}
});
assert(remoteEntryExports, `remoteEntryExports is undefined \n ${safeToString(this.remoteInfo)}`);
this.remoteEntryExports = remoteEntryExports;
return this.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) {
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;
}
this.initing = true;
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);
const initContainerOptions = await this.host.hooks.lifecycle.beforeInitContainer.emit({
shareScope,
remoteEntryInitOptions,
initScope,
remoteInfo: this.remoteInfo,
origin: this.host
});
if (typeof remoteEntryExports?.init === "undefined") error(RUNTIME_002, runtimeDescMap, {
hostName: this.host.name,
remoteName: this.remoteInfo.name,
remoteEntryUrl: this.remoteInfo.entry,
remoteEntryKey: this.remoteInfo.entryGlobalName
}, void 0, optionsToMFContext(this.host.options));
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({
...initContainerOptions,
id,
remoteSnapshot,
remoteEntryExports
});
this.inited = true;
})();
try {
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 {
this.initing = false;
this.initPromise = void 0;
}
return remoteEntryExports;
}
async get(id, expose, options, remoteSnapshot) {
const { loadFactory = true } = options || { loadFactory: true };
const remoteEntryExports = await this.init(id, remoteSnapshot, void 0, expose);
this.lib = remoteEntryExports;
await this.host.loaderHook.lifecycle.beforeGetExpose.emit({
id,
expose,
moduleInfo: this.remoteInfo,
remoteEntryExports,
origin: this.host
});
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;
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;
}
}
wraperFactory(moduleFactory, id) {
function defineModuleId(res, id) {
if (res && typeof res === "object" && Object.isExtensible(res) && !Object.getOwnPropertyDescriptor(res, Symbol.for("mf_module_id"))) Object.defineProperty(res, Symbol.for("mf_module_id"), {
value: id,
enumerable: false
});
}
return () => {
const res = moduleFactory();
if (res instanceof Promise) return res.then((asyncRes) => {
defineModuleId(asyncRes, id);
return asyncRes;
});
defineModuleId(res, id);
return res;
};
}
};
//#endregion
export { Module$1 as Module };
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,182 @@
const require_tool = require('../utils/tool.cjs');
const require_global = require('../global.cjs');
const require_share = require('../utils/share.cjs');
require('../utils/index.cjs');
const require_preload = require('../utils/preload.cjs');
const require_index$1 = require('./snapshot/index.cjs');
let _module_federation_sdk = require("@module-federation/sdk");
//#region src/plugins/generate-preload-assets.ts
function splitId(id) {
const splitInfo = id.split(":");
if (splitInfo.length === 1) return {
name: splitInfo[0],
version: void 0
};
else if (splitInfo.length === 2) return {
name: splitInfo[0],
version: splitInfo[1]
};
else return {
name: splitInfo[1],
version: splitInfo[2]
};
}
function traverseModuleInfo(globalSnapshot, remoteInfo, traverse, isRoot, memo = {}, remoteSnapshot) {
const { value: snapshotValue } = require_global.getInfoWithoutType(globalSnapshot, require_tool.getFMId(remoteInfo));
const effectiveRemoteSnapshot = remoteSnapshot || snapshotValue;
if (effectiveRemoteSnapshot && !(0, _module_federation_sdk.isManifestProvider)(effectiveRemoteSnapshot)) {
traverse(effectiveRemoteSnapshot, remoteInfo, isRoot);
if (effectiveRemoteSnapshot.remotesInfo) {
const remoteKeys = Object.keys(effectiveRemoteSnapshot.remotesInfo);
for (const key of remoteKeys) {
if (memo[key]) continue;
memo[key] = true;
const subRemoteInfo = splitId(key);
const remoteValue = effectiveRemoteSnapshot.remotesInfo[key];
traverseModuleInfo(globalSnapshot, {
name: subRemoteInfo.name,
version: remoteValue.matchedVersion
}, traverse, false, memo, void 0);
}
}
}
}
const isExisted = (type, url) => {
return document.querySelector(`${type}[${type === "link" ? "href" : "src"}="${url}"]`);
};
function generatePreloadAssets(origin, preloadOptions, remote, globalSnapshot, remoteSnapshot) {
const cssAssets = [];
const jsAssets = [];
const entryAssets = [];
const loadedSharedJsAssets = /* @__PURE__ */ new Set();
const loadedSharedCssAssets = /* @__PURE__ */ new Set();
const { options } = origin;
const { preloadConfig: rootPreloadConfig } = preloadOptions;
const { depsRemote } = rootPreloadConfig;
traverseModuleInfo(globalSnapshot, remote, (moduleInfoSnapshot, remoteInfo, isRoot) => {
let preloadConfig;
if (isRoot) preloadConfig = rootPreloadConfig;
else if (Array.isArray(depsRemote)) {
const findPreloadConfig = depsRemote.find((remoteConfig) => {
if (remoteConfig.nameOrAlias === remoteInfo.name || remoteConfig.nameOrAlias === remoteInfo.alias) return true;
return false;
});
if (!findPreloadConfig) return;
preloadConfig = require_preload.defaultPreloadArgs(findPreloadConfig);
} else if (depsRemote === true) preloadConfig = rootPreloadConfig;
else return;
const remoteEntryUrl = (0, _module_federation_sdk.getResourceUrl)(moduleInfoSnapshot, require_tool.getRemoteEntryInfoFromSnapshot(moduleInfoSnapshot).url);
if (remoteEntryUrl) entryAssets.push({
name: remoteInfo.name,
moduleInfo: {
name: remoteInfo.name,
entry: remoteEntryUrl,
type: "remoteEntryType" in moduleInfoSnapshot ? moduleInfoSnapshot.remoteEntryType : "global",
entryGlobalName: "globalName" in moduleInfoSnapshot ? moduleInfoSnapshot.globalName : remoteInfo.name,
shareScope: "",
version: "version" in moduleInfoSnapshot ? moduleInfoSnapshot.version : void 0
},
url: remoteEntryUrl
});
let moduleAssetsInfo = "modules" in moduleInfoSnapshot ? moduleInfoSnapshot.modules : [];
const normalizedPreloadExposes = require_preload.normalizePreloadExposes(preloadConfig.exposes);
if (normalizedPreloadExposes.length && "modules" in moduleInfoSnapshot) moduleAssetsInfo = moduleInfoSnapshot?.modules?.reduce((assets, moduleAssetInfo) => {
if (normalizedPreloadExposes?.indexOf(moduleAssetInfo.moduleName) !== -1) assets.push(moduleAssetInfo);
return assets;
}, []);
function handleAssets(assets) {
const assetsRes = assets.map((asset) => (0, _module_federation_sdk.getResourceUrl)(moduleInfoSnapshot, asset));
if (preloadConfig.filter) return assetsRes.filter(preloadConfig.filter);
return assetsRes;
}
if (moduleAssetsInfo) {
const assetsLength = moduleAssetsInfo.length;
for (let index = 0; index < assetsLength; index++) {
const assetsInfo = moduleAssetsInfo[index];
const exposeFullPath = `${remoteInfo.name}/${assetsInfo.moduleName}`;
origin.remoteHandler.hooks.lifecycle.handlePreloadModule.emit({
id: assetsInfo.moduleName === "." ? remoteInfo.name : exposeFullPath,
name: remoteInfo.name,
remoteSnapshot: moduleInfoSnapshot,
preloadConfig,
remote: remoteInfo,
origin
});
if (require_global.getPreloaded(exposeFullPath)) continue;
if (preloadConfig.resourceCategory === "all") {
cssAssets.push(...handleAssets(assetsInfo.assets.css.async));
cssAssets.push(...handleAssets(assetsInfo.assets.css.sync));
jsAssets.push(...handleAssets(assetsInfo.assets.js.async));
jsAssets.push(...handleAssets(assetsInfo.assets.js.sync));
} else if (preloadConfig.resourceCategory === "sync") {
cssAssets.push(...handleAssets(assetsInfo.assets.css.sync));
jsAssets.push(...handleAssets(assetsInfo.assets.js.sync));
}
require_global.setPreloaded(exposeFullPath);
}
}
}, true, {}, remoteSnapshot);
if (remoteSnapshot.shared && remoteSnapshot.shared.length > 0) {
const collectSharedAssets = (shareInfo, snapshotShared) => {
const { shared: registeredShared } = require_share.getRegisteredShare(origin.shareScopeMap, snapshotShared.sharedName, shareInfo, origin.sharedHandler.hooks.lifecycle.resolveShare) || {};
if (registeredShared && typeof registeredShared.lib === "function") {
snapshotShared.assets.js.sync.forEach((asset) => {
loadedSharedJsAssets.add(asset);
});
snapshotShared.assets.css.sync.forEach((asset) => {
loadedSharedCssAssets.add(asset);
});
}
};
remoteSnapshot.shared.forEach((shared) => {
const shareInfos = options.shared?.[shared.sharedName];
if (!shareInfos) return;
const sharedOptions = shared.version ? shareInfos.find((s) => s.version === shared.version) : shareInfos;
if (!sharedOptions) return;
require_tool.arrayOptions(sharedOptions).forEach((s) => {
collectSharedAssets(s, shared);
});
});
}
const needPreloadJsAssets = jsAssets.filter((asset) => !loadedSharedJsAssets.has(asset) && !isExisted("script", asset));
return {
cssAssets: cssAssets.filter((asset) => !loadedSharedCssAssets.has(asset) && !isExisted("link", asset)),
jsAssetsWithoutEntry: needPreloadJsAssets,
entryAssets: entryAssets.filter((entry) => !isExisted("script", entry.url))
};
}
const generatePreloadAssetsPlugin = function() {
return {
name: "generate-preload-assets-plugin",
async generatePreloadAssets(args) {
const { origin, preloadOptions, remoteInfo, remote, globalSnapshot, remoteSnapshot } = args;
if (!_module_federation_sdk.isBrowserEnvValue) return {
cssAssets: [],
jsAssetsWithoutEntry: [],
entryAssets: []
};
if (require_tool.isRemoteInfoWithEntry(remote) && require_tool.isPureRemoteEntry(remote)) return {
cssAssets: [],
jsAssetsWithoutEntry: [],
entryAssets: [{
name: remote.name,
url: remote.entry,
moduleInfo: {
name: remoteInfo.name,
entry: remote.entry,
type: remoteInfo.type || "global",
entryGlobalName: "",
shareScope: ""
}
}]
};
require_index$1.assignRemoteInfo(remoteInfo, remoteSnapshot);
return generatePreloadAssets(origin, preloadOptions, remoteInfo, globalSnapshot, remoteSnapshot);
}
};
};
//#endregion
exports.generatePreloadAssetsPlugin = generatePreloadAssetsPlugin;
//# sourceMappingURL=generate-preload-assets.cjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,182 @@
import { arrayOptions, getFMId, getRemoteEntryInfoFromSnapshot, isPureRemoteEntry, isRemoteInfoWithEntry } from "../utils/tool.js";
import { getInfoWithoutType, getPreloaded, setPreloaded } from "../global.js";
import { getRegisteredShare } from "../utils/share.js";
import "../utils/index.js";
import { defaultPreloadArgs, normalizePreloadExposes } from "../utils/preload.js";
import { assignRemoteInfo } from "./snapshot/index.js";
import { getResourceUrl, isBrowserEnvValue, isManifestProvider } from "@module-federation/sdk";
//#region src/plugins/generate-preload-assets.ts
function splitId(id) {
const splitInfo = id.split(":");
if (splitInfo.length === 1) return {
name: splitInfo[0],
version: void 0
};
else if (splitInfo.length === 2) return {
name: splitInfo[0],
version: splitInfo[1]
};
else return {
name: splitInfo[1],
version: splitInfo[2]
};
}
function traverseModuleInfo(globalSnapshot, remoteInfo, traverse, isRoot, memo = {}, remoteSnapshot) {
const { value: snapshotValue } = getInfoWithoutType(globalSnapshot, getFMId(remoteInfo));
const effectiveRemoteSnapshot = remoteSnapshot || snapshotValue;
if (effectiveRemoteSnapshot && !isManifestProvider(effectiveRemoteSnapshot)) {
traverse(effectiveRemoteSnapshot, remoteInfo, isRoot);
if (effectiveRemoteSnapshot.remotesInfo) {
const remoteKeys = Object.keys(effectiveRemoteSnapshot.remotesInfo);
for (const key of remoteKeys) {
if (memo[key]) continue;
memo[key] = true;
const subRemoteInfo = splitId(key);
const remoteValue = effectiveRemoteSnapshot.remotesInfo[key];
traverseModuleInfo(globalSnapshot, {
name: subRemoteInfo.name,
version: remoteValue.matchedVersion
}, traverse, false, memo, void 0);
}
}
}
}
const isExisted = (type, url) => {
return document.querySelector(`${type}[${type === "link" ? "href" : "src"}="${url}"]`);
};
function generatePreloadAssets(origin, preloadOptions, remote, globalSnapshot, remoteSnapshot) {
const cssAssets = [];
const jsAssets = [];
const entryAssets = [];
const loadedSharedJsAssets = /* @__PURE__ */ new Set();
const loadedSharedCssAssets = /* @__PURE__ */ new Set();
const { options } = origin;
const { preloadConfig: rootPreloadConfig } = preloadOptions;
const { depsRemote } = rootPreloadConfig;
traverseModuleInfo(globalSnapshot, remote, (moduleInfoSnapshot, remoteInfo, isRoot) => {
let preloadConfig;
if (isRoot) preloadConfig = rootPreloadConfig;
else if (Array.isArray(depsRemote)) {
const findPreloadConfig = depsRemote.find((remoteConfig) => {
if (remoteConfig.nameOrAlias === remoteInfo.name || remoteConfig.nameOrAlias === remoteInfo.alias) return true;
return false;
});
if (!findPreloadConfig) return;
preloadConfig = defaultPreloadArgs(findPreloadConfig);
} else if (depsRemote === true) preloadConfig = rootPreloadConfig;
else return;
const remoteEntryUrl = getResourceUrl(moduleInfoSnapshot, getRemoteEntryInfoFromSnapshot(moduleInfoSnapshot).url);
if (remoteEntryUrl) entryAssets.push({
name: remoteInfo.name,
moduleInfo: {
name: remoteInfo.name,
entry: remoteEntryUrl,
type: "remoteEntryType" in moduleInfoSnapshot ? moduleInfoSnapshot.remoteEntryType : "global",
entryGlobalName: "globalName" in moduleInfoSnapshot ? moduleInfoSnapshot.globalName : remoteInfo.name,
shareScope: "",
version: "version" in moduleInfoSnapshot ? moduleInfoSnapshot.version : void 0
},
url: remoteEntryUrl
});
let moduleAssetsInfo = "modules" in moduleInfoSnapshot ? moduleInfoSnapshot.modules : [];
const normalizedPreloadExposes = normalizePreloadExposes(preloadConfig.exposes);
if (normalizedPreloadExposes.length && "modules" in moduleInfoSnapshot) moduleAssetsInfo = moduleInfoSnapshot?.modules?.reduce((assets, moduleAssetInfo) => {
if (normalizedPreloadExposes?.indexOf(moduleAssetInfo.moduleName) !== -1) assets.push(moduleAssetInfo);
return assets;
}, []);
function handleAssets(assets) {
const assetsRes = assets.map((asset) => getResourceUrl(moduleInfoSnapshot, asset));
if (preloadConfig.filter) return assetsRes.filter(preloadConfig.filter);
return assetsRes;
}
if (moduleAssetsInfo) {
const assetsLength = moduleAssetsInfo.length;
for (let index = 0; index < assetsLength; index++) {
const assetsInfo = moduleAssetsInfo[index];
const exposeFullPath = `${remoteInfo.name}/${assetsInfo.moduleName}`;
origin.remoteHandler.hooks.lifecycle.handlePreloadModule.emit({
id: assetsInfo.moduleName === "." ? remoteInfo.name : exposeFullPath,
name: remoteInfo.name,
remoteSnapshot: moduleInfoSnapshot,
preloadConfig,
remote: remoteInfo,
origin
});
if (getPreloaded(exposeFullPath)) continue;
if (preloadConfig.resourceCategory === "all") {
cssAssets.push(...handleAssets(assetsInfo.assets.css.async));
cssAssets.push(...handleAssets(assetsInfo.assets.css.sync));
jsAssets.push(...handleAssets(assetsInfo.assets.js.async));
jsAssets.push(...handleAssets(assetsInfo.assets.js.sync));
} else if (preloadConfig.resourceCategory === "sync") {
cssAssets.push(...handleAssets(assetsInfo.assets.css.sync));
jsAssets.push(...handleAssets(assetsInfo.assets.js.sync));
}
setPreloaded(exposeFullPath);
}
}
}, true, {}, remoteSnapshot);
if (remoteSnapshot.shared && remoteSnapshot.shared.length > 0) {
const collectSharedAssets = (shareInfo, snapshotShared) => {
const { shared: registeredShared } = getRegisteredShare(origin.shareScopeMap, snapshotShared.sharedName, shareInfo, origin.sharedHandler.hooks.lifecycle.resolveShare) || {};
if (registeredShared && typeof registeredShared.lib === "function") {
snapshotShared.assets.js.sync.forEach((asset) => {
loadedSharedJsAssets.add(asset);
});
snapshotShared.assets.css.sync.forEach((asset) => {
loadedSharedCssAssets.add(asset);
});
}
};
remoteSnapshot.shared.forEach((shared) => {
const shareInfos = options.shared?.[shared.sharedName];
if (!shareInfos) return;
const sharedOptions = shared.version ? shareInfos.find((s) => s.version === shared.version) : shareInfos;
if (!sharedOptions) return;
arrayOptions(sharedOptions).forEach((s) => {
collectSharedAssets(s, shared);
});
});
}
const needPreloadJsAssets = jsAssets.filter((asset) => !loadedSharedJsAssets.has(asset) && !isExisted("script", asset));
return {
cssAssets: cssAssets.filter((asset) => !loadedSharedCssAssets.has(asset) && !isExisted("link", asset)),
jsAssetsWithoutEntry: needPreloadJsAssets,
entryAssets: entryAssets.filter((entry) => !isExisted("script", entry.url))
};
}
const generatePreloadAssetsPlugin = function() {
return {
name: "generate-preload-assets-plugin",
async generatePreloadAssets(args) {
const { origin, preloadOptions, remoteInfo, remote, globalSnapshot, remoteSnapshot } = args;
if (!isBrowserEnvValue) return {
cssAssets: [],
jsAssetsWithoutEntry: [],
entryAssets: []
};
if (isRemoteInfoWithEntry(remote) && isPureRemoteEntry(remote)) return {
cssAssets: [],
jsAssetsWithoutEntry: [],
entryAssets: [{
name: remote.name,
url: remote.entry,
moduleInfo: {
name: remoteInfo.name,
entry: remote.entry,
type: remoteInfo.type || "global",
entryGlobalName: "",
shareScope: ""
}
}]
};
assignRemoteInfo(remoteInfo, remoteSnapshot);
return generatePreloadAssets(origin, preloadOptions, remoteInfo, globalSnapshot, remoteSnapshot);
}
};
};
//#endregion
export { generatePreloadAssetsPlugin };
//# sourceMappingURL=generate-preload-assets.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,215 @@
const require_logger = require('../../utils/logger.cjs');
const require_tool = require('../../utils/tool.cjs');
const require_global = require('../../global.cjs');
const require_load = require('../../utils/load.cjs');
const require_context = require('../../utils/context.cjs');
require('../../utils/index.cjs');
const require_asyncHook = require('../../utils/hooks/asyncHook.cjs');
const require_asyncWaterfallHooks = require('../../utils/hooks/asyncWaterfallHooks.cjs');
const require_pluginSystem = require('../../utils/hooks/pluginSystem.cjs');
require('../../utils/hooks/index.cjs');
let _module_federation_sdk = require("@module-federation/sdk");
let _module_federation_error_codes = require("@module-federation/error-codes");
//#region src/plugins/snapshot/SnapshotHandler.ts
function getGlobalRemoteInfo(moduleInfo, origin) {
const hostGlobalSnapshot = require_global.getGlobalSnapshotInfoByModuleInfo({
name: origin.name,
version: origin.options.version
});
const globalRemoteInfo = hostGlobalSnapshot && "remotesInfo" in hostGlobalSnapshot && hostGlobalSnapshot.remotesInfo && require_global.getInfoWithoutType(hostGlobalSnapshot.remotesInfo, moduleInfo.name).value;
if (globalRemoteInfo && globalRemoteInfo.matchedVersion) return {
hostGlobalSnapshot,
globalSnapshot: require_global.getGlobalSnapshot(),
remoteSnapshot: require_global.getGlobalSnapshotInfoByModuleInfo({
name: moduleInfo.name,
version: globalRemoteInfo.matchedVersion
})
};
return {
hostGlobalSnapshot: void 0,
globalSnapshot: require_global.getGlobalSnapshot(),
remoteSnapshot: require_global.getGlobalSnapshotInfoByModuleInfo({
name: moduleInfo.name,
version: "version" in moduleInfo ? moduleInfo.version : void 0
})
};
}
var SnapshotHandler = class {
constructor(HostInstance) {
this.loadingHostSnapshot = null;
this.manifestCache = /* @__PURE__ */ new Map();
this.hooks = new require_pluginSystem.PluginSystem({
beforeLoadRemoteSnapshot: new require_asyncHook.AsyncHook("beforeLoadRemoteSnapshot"),
loadSnapshot: new require_asyncWaterfallHooks.AsyncWaterfallHook("loadGlobalSnapshot"),
loadRemoteSnapshot: new require_asyncWaterfallHooks.AsyncWaterfallHook("loadRemoteSnapshot"),
afterLoadSnapshot: new require_asyncWaterfallHooks.AsyncWaterfallHook("afterLoadSnapshot")
});
this.manifestLoading = require_global.Global.__FEDERATION__.__MANIFEST_LOADING__;
this.HostInstance = HostInstance;
this.loaderHook = HostInstance.loaderHook;
}
async loadRemoteSnapshotInfo({ moduleInfo, id, initiator = "loadRemote" }) {
const { options } = this.HostInstance;
await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({
options,
moduleInfo,
origin: this.HostInstance
});
let hostSnapshot = require_global.getGlobalSnapshotInfoByModuleInfo({
name: this.HostInstance.options.name,
version: this.HostInstance.options.version
});
if (!hostSnapshot) {
hostSnapshot = {
version: this.HostInstance.options.version || "",
remoteEntry: "",
remotesInfo: {}
};
require_global.addGlobalSnapshot({ [this.HostInstance.options.name]: hostSnapshot });
}
if (hostSnapshot && "remotesInfo" in hostSnapshot && !require_global.getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name).value) {
if ("version" in moduleInfo || "entry" in moduleInfo) hostSnapshot.remotesInfo = {
...hostSnapshot?.remotesInfo,
[moduleInfo.name]: { matchedVersion: "version" in moduleInfo ? moduleInfo.version : moduleInfo.entry }
};
}
const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } = this.getGlobalRemoteInfo(moduleInfo);
const { remoteSnapshot: globalRemoteSnapshot, globalSnapshot: globalSnapshotRes } = await this.hooks.lifecycle.loadSnapshot.emit({
options,
moduleInfo,
hostGlobalSnapshot,
remoteSnapshot,
globalSnapshot
});
let mSnapshot;
let gSnapshot;
if (globalRemoteSnapshot) if ((0, _module_federation_sdk.isManifestProvider)(globalRemoteSnapshot)) {
const remoteEntry = _module_federation_sdk.isBrowserEnvValue ? globalRemoteSnapshot.remoteEntry : globalRemoteSnapshot.ssrRemoteEntry || globalRemoteSnapshot.remoteEntry || "";
const moduleSnapshot = await this.loadManifestSnapshot(remoteEntry, moduleInfo, {}, {
initiator,
id: id || moduleInfo.name
});
const globalSnapshotRes = require_global.setGlobalSnapshotInfoByModuleInfo({
...moduleInfo,
entry: remoteEntry
}, moduleSnapshot);
mSnapshot = moduleSnapshot;
gSnapshot = globalSnapshotRes;
} else {
const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
options: this.HostInstance.options,
moduleInfo,
remoteSnapshot: globalRemoteSnapshot,
from: "global"
});
mSnapshot = remoteSnapshotRes;
gSnapshot = globalSnapshotRes;
}
else if (require_tool.isRemoteInfoWithEntry(moduleInfo)) {
const moduleSnapshot = await this.loadManifestSnapshot(moduleInfo.entry, moduleInfo, {}, {
initiator,
id: id || moduleInfo.name
});
const globalSnapshotRes = require_global.setGlobalSnapshotInfoByModuleInfo(moduleInfo, moduleSnapshot);
mSnapshot = moduleSnapshot;
gSnapshot = globalSnapshotRes;
} else require_logger.error(_module_federation_error_codes.RUNTIME_007, _module_federation_error_codes.runtimeDescMap, {
remoteName: moduleInfo.name,
remoteVersion: moduleInfo.version,
hostName: this.HostInstance.options.name,
globalSnapshot: JSON.stringify(globalSnapshotRes)
}, void 0, require_context.optionsToMFContext(this.HostInstance.options));
await this.hooks.lifecycle.afterLoadSnapshot.emit({
id,
host: this.HostInstance,
options,
moduleInfo,
remoteSnapshot: mSnapshot
});
return {
remoteSnapshot: mSnapshot,
globalSnapshot: gSnapshot
};
}
getGlobalRemoteInfo(moduleInfo) {
return getGlobalRemoteInfo(moduleInfo, this.HostInstance);
}
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, {}, remoteInfo, resourceOptions ? {
...resourceOptions,
url: manifestUrl,
resourceType: "manifest"
} : void 0);
if (!res || !(res instanceof Response)) res = await fetch(manifestUrl, {});
manifestJson = await res.json();
} catch (err) {
manifestJson = await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit({
id: manifestUrl,
error: err,
from: "runtime",
lifecycle: "afterResolve",
remote: remoteInfo,
origin: this.HostInstance
});
if (!manifestJson) {
delete this.manifestLoading[manifestUrl];
require_logger.error(_module_federation_error_codes.RUNTIME_003, _module_federation_error_codes.runtimeDescMap, {
manifestUrl,
moduleName: moduleInfo.name,
hostName: this.HostInstance.options.name
}, `${err}`, require_context.optionsToMFContext(this.HostInstance.options));
}
}
const missingRequiredFields = [
!manifestJson.metaData && "metaData",
!manifestJson.exposes && "exposes",
!manifestJson.shared && "shared"
].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 this.getManifestJson(manifestUrl, moduleInfo, extraOptions, resourceOptions);
const remoteSnapshot = (0, _module_federation_sdk.generateSnapshotFromManifest)(manifestJson, { version: manifestUrl });
const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
options: this.HostInstance.options,
moduleInfo,
manifestJson,
remoteSnapshot,
manifestUrl,
from: "manifest"
});
return remoteSnapshotRes;
};
if (!this.manifestLoading[manifestUrl]) this.manifestLoading[manifestUrl] = asyncLoadProcess().then((res) => res);
return this.manifestLoading[manifestUrl];
}
};
//#endregion
exports.SnapshotHandler = SnapshotHandler;
exports.getGlobalRemoteInfo = getGlobalRemoteInfo;
//# sourceMappingURL=SnapshotHandler.cjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,69 @@
import { AsyncHook } from "../../utils/hooks/asyncHook.js";
import { AsyncWaterfallHook } from "../../utils/hooks/asyncWaterfallHooks.js";
import { PluginSystem } from "../../utils/hooks/pluginSystem.js";
import { getGlobalSnapshot } from "../../global.js";
import { ModuleFederation } from "../../core.js";
import { Options, Remote } from "../../type/config.js";
import { ResourceLoadInitiator } from "../../type/preload.js";
import { GlobalModuleInfo, Manifest, ModuleInfo } from "@module-federation/sdk";
//#region src/plugins/snapshot/SnapshotHandler.d.ts
declare class SnapshotHandler {
loadingHostSnapshot: Promise<GlobalModuleInfo | void> | null;
HostInstance: ModuleFederation;
manifestCache: Map<string, Manifest>;
hooks: PluginSystem<{
beforeLoadRemoteSnapshot: AsyncHook<[{
options: Options;
moduleInfo: Remote;
origin: ModuleFederation;
}], void>;
loadSnapshot: AsyncWaterfallHook<{
options: Options;
moduleInfo: Remote;
hostGlobalSnapshot: GlobalModuleInfo[string] | undefined;
globalSnapshot: ReturnType<typeof getGlobalSnapshot>;
remoteSnapshot?: GlobalModuleInfo[string] | undefined;
}>;
loadRemoteSnapshot: AsyncWaterfallHook<{
options: Options;
moduleInfo: Remote;
manifestJson?: Manifest;
manifestUrl?: string;
remoteSnapshot: ModuleInfo;
from: "global" | "manifest";
}>;
afterLoadSnapshot: AsyncWaterfallHook<{
id?: string;
host: ModuleFederation;
options: Options;
moduleInfo: Remote;
remoteSnapshot: ModuleInfo;
}>;
}>;
loaderHook: ModuleFederation['loaderHook'];
manifestLoading: Record<string, Promise<ModuleInfo>>;
constructor(HostInstance: ModuleFederation);
loadRemoteSnapshotInfo({
moduleInfo,
id,
initiator
}: {
moduleInfo: Remote;
id?: string;
initiator?: ResourceLoadInitiator;
}): Promise<{
remoteSnapshot: ModuleInfo;
globalSnapshot: GlobalModuleInfo;
}> | never;
getGlobalRemoteInfo(moduleInfo: Remote): {
hostGlobalSnapshot: ModuleInfo | undefined;
globalSnapshot: ReturnType<typeof getGlobalSnapshot>;
remoteSnapshot: GlobalModuleInfo[string] | undefined;
};
private getManifestJson;
private loadManifestSnapshot;
}
//#endregion
export { SnapshotHandler };
//# sourceMappingURL=SnapshotHandler.d.ts.map

View File

@@ -0,0 +1,214 @@
import { error } from "../../utils/logger.js";
import { isRemoteInfoWithEntry } from "../../utils/tool.js";
import { Global, addGlobalSnapshot, getGlobalSnapshot, getGlobalSnapshotInfoByModuleInfo, getInfoWithoutType, setGlobalSnapshotInfoByModuleInfo } from "../../global.js";
import { getRemoteInfo } from "../../utils/load.js";
import { optionsToMFContext } from "../../utils/context.js";
import "../../utils/index.js";
import { AsyncHook } from "../../utils/hooks/asyncHook.js";
import { AsyncWaterfallHook } from "../../utils/hooks/asyncWaterfallHooks.js";
import { PluginSystem } from "../../utils/hooks/pluginSystem.js";
import "../../utils/hooks/index.js";
import { generateSnapshotFromManifest, isBrowserEnvValue, isManifestProvider } from "@module-federation/sdk";
import { RUNTIME_003, RUNTIME_007, RUNTIME_013, runtimeDescMap } from "@module-federation/error-codes";
//#region src/plugins/snapshot/SnapshotHandler.ts
function getGlobalRemoteInfo(moduleInfo, origin) {
const hostGlobalSnapshot = getGlobalSnapshotInfoByModuleInfo({
name: origin.name,
version: origin.options.version
});
const globalRemoteInfo = hostGlobalSnapshot && "remotesInfo" in hostGlobalSnapshot && hostGlobalSnapshot.remotesInfo && getInfoWithoutType(hostGlobalSnapshot.remotesInfo, moduleInfo.name).value;
if (globalRemoteInfo && globalRemoteInfo.matchedVersion) return {
hostGlobalSnapshot,
globalSnapshot: getGlobalSnapshot(),
remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({
name: moduleInfo.name,
version: globalRemoteInfo.matchedVersion
})
};
return {
hostGlobalSnapshot: void 0,
globalSnapshot: getGlobalSnapshot(),
remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({
name: moduleInfo.name,
version: "version" in moduleInfo ? moduleInfo.version : void 0
})
};
}
var SnapshotHandler = class {
constructor(HostInstance) {
this.loadingHostSnapshot = null;
this.manifestCache = /* @__PURE__ */ new Map();
this.hooks = new PluginSystem({
beforeLoadRemoteSnapshot: new AsyncHook("beforeLoadRemoteSnapshot"),
loadSnapshot: new AsyncWaterfallHook("loadGlobalSnapshot"),
loadRemoteSnapshot: new AsyncWaterfallHook("loadRemoteSnapshot"),
afterLoadSnapshot: new AsyncWaterfallHook("afterLoadSnapshot")
});
this.manifestLoading = Global.__FEDERATION__.__MANIFEST_LOADING__;
this.HostInstance = HostInstance;
this.loaderHook = HostInstance.loaderHook;
}
async loadRemoteSnapshotInfo({ moduleInfo, id, initiator = "loadRemote" }) {
const { options } = this.HostInstance;
await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({
options,
moduleInfo,
origin: this.HostInstance
});
let hostSnapshot = getGlobalSnapshotInfoByModuleInfo({
name: this.HostInstance.options.name,
version: this.HostInstance.options.version
});
if (!hostSnapshot) {
hostSnapshot = {
version: this.HostInstance.options.version || "",
remoteEntry: "",
remotesInfo: {}
};
addGlobalSnapshot({ [this.HostInstance.options.name]: hostSnapshot });
}
if (hostSnapshot && "remotesInfo" in hostSnapshot && !getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name).value) {
if ("version" in moduleInfo || "entry" in moduleInfo) hostSnapshot.remotesInfo = {
...hostSnapshot?.remotesInfo,
[moduleInfo.name]: { matchedVersion: "version" in moduleInfo ? moduleInfo.version : moduleInfo.entry }
};
}
const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } = this.getGlobalRemoteInfo(moduleInfo);
const { remoteSnapshot: globalRemoteSnapshot, globalSnapshot: globalSnapshotRes } = await this.hooks.lifecycle.loadSnapshot.emit({
options,
moduleInfo,
hostGlobalSnapshot,
remoteSnapshot,
globalSnapshot
});
let mSnapshot;
let gSnapshot;
if (globalRemoteSnapshot) if (isManifestProvider(globalRemoteSnapshot)) {
const remoteEntry = isBrowserEnvValue ? globalRemoteSnapshot.remoteEntry : globalRemoteSnapshot.ssrRemoteEntry || globalRemoteSnapshot.remoteEntry || "";
const moduleSnapshot = await this.loadManifestSnapshot(remoteEntry, moduleInfo, {}, {
initiator,
id: id || moduleInfo.name
});
const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo({
...moduleInfo,
entry: remoteEntry
}, moduleSnapshot);
mSnapshot = moduleSnapshot;
gSnapshot = globalSnapshotRes;
} else {
const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
options: this.HostInstance.options,
moduleInfo,
remoteSnapshot: globalRemoteSnapshot,
from: "global"
});
mSnapshot = remoteSnapshotRes;
gSnapshot = globalSnapshotRes;
}
else if (isRemoteInfoWithEntry(moduleInfo)) {
const moduleSnapshot = await this.loadManifestSnapshot(moduleInfo.entry, moduleInfo, {}, {
initiator,
id: id || moduleInfo.name
});
const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(moduleInfo, moduleSnapshot);
mSnapshot = moduleSnapshot;
gSnapshot = globalSnapshotRes;
} else error(RUNTIME_007, runtimeDescMap, {
remoteName: moduleInfo.name,
remoteVersion: moduleInfo.version,
hostName: this.HostInstance.options.name,
globalSnapshot: JSON.stringify(globalSnapshotRes)
}, void 0, optionsToMFContext(this.HostInstance.options));
await this.hooks.lifecycle.afterLoadSnapshot.emit({
id,
host: this.HostInstance,
options,
moduleInfo,
remoteSnapshot: mSnapshot
});
return {
remoteSnapshot: mSnapshot,
globalSnapshot: gSnapshot
};
}
getGlobalRemoteInfo(moduleInfo) {
return getGlobalRemoteInfo(moduleInfo, this.HostInstance);
}
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, {}, remoteInfo, resourceOptions ? {
...resourceOptions,
url: manifestUrl,
resourceType: "manifest"
} : void 0);
if (!res || !(res instanceof Response)) res = await fetch(manifestUrl, {});
manifestJson = await res.json();
} catch (err) {
manifestJson = await this.HostInstance.remoteHandler.hooks.lifecycle.errorLoadRemote.emit({
id: manifestUrl,
error: err,
from: "runtime",
lifecycle: "afterResolve",
remote: remoteInfo,
origin: this.HostInstance
});
if (!manifestJson) {
delete this.manifestLoading[manifestUrl];
error(RUNTIME_003, runtimeDescMap, {
manifestUrl,
moduleName: moduleInfo.name,
hostName: this.HostInstance.options.name
}, `${err}`, optionsToMFContext(this.HostInstance.options));
}
}
const missingRequiredFields = [
!manifestJson.metaData && "metaData",
!manifestJson.exposes && "exposes",
!manifestJson.shared && "shared"
].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 this.getManifestJson(manifestUrl, moduleInfo, extraOptions, resourceOptions);
const remoteSnapshot = generateSnapshotFromManifest(manifestJson, { version: manifestUrl });
const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
options: this.HostInstance.options,
moduleInfo,
manifestJson,
remoteSnapshot,
manifestUrl,
from: "manifest"
});
return remoteSnapshotRes;
};
if (!this.manifestLoading[manifestUrl]) this.manifestLoading[manifestUrl] = asyncLoadProcess().then((res) => res);
return this.manifestLoading[manifestUrl];
}
};
//#endregion
export { SnapshotHandler, getGlobalRemoteInfo };
//# sourceMappingURL=SnapshotHandler.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,67 @@
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');
const require_preload = require('../../utils/preload.cjs');
let _module_federation_sdk = require("@module-federation/sdk");
let _module_federation_error_codes = require("@module-federation/error-codes");
//#region src/plugins/snapshot/index.ts
function assignRemoteInfo(remoteInfo, remoteSnapshot) {
const remoteEntryInfo = require_tool.getRemoteEntryInfoFromSnapshot(remoteSnapshot);
if (!remoteEntryInfo.url) require_logger.error(_module_federation_error_codes.RUNTIME_011, _module_federation_error_codes.runtimeDescMap, { remoteName: remoteInfo.name });
let entryUrl = (0, _module_federation_sdk.getResourceUrl)(remoteSnapshot, remoteEntryInfo.url);
if (!_module_federation_sdk.isBrowserEnvValue && !entryUrl.startsWith("http")) entryUrl = `https:${entryUrl}`;
remoteInfo.type = remoteEntryInfo.type;
remoteInfo.entryGlobalName = remoteEntryInfo.globalName;
remoteInfo.entry = entryUrl;
remoteInfo.version = remoteSnapshot.version;
remoteInfo.buildVersion = remoteSnapshot.buildVersion;
}
function snapshotPlugin() {
return {
name: "snapshot-plugin",
async afterResolve(args) {
const { remote, pkgNameOrAlias, expose, origin, remoteInfo, id } = args;
if (!require_tool.isRemoteInfoWithEntry(remote) || !require_tool.isPureRemoteEntry(remote)) {
const { remoteSnapshot, globalSnapshot } = await origin.snapshotHandler.loadRemoteSnapshotInfo({
moduleInfo: remote,
id: require_manifest.composeRemoteRequestId(remote.name, expose)
});
assignRemoteInfo(remoteInfo, remoteSnapshot);
const preloadOptions = {
remote,
preloadConfig: {
nameOrAlias: pkgNameOrAlias,
exposes: [expose],
resourceCategory: "sync",
share: false,
depsRemote: false
}
};
const assets = await origin.remoteHandler.hooks.lifecycle.generatePreloadAssets.emit({
origin,
preloadOptions,
remoteInfo,
remote,
remoteSnapshot,
globalSnapshot
});
if (assets) require_preload.preloadAssets(remoteInfo, origin, assets, false, {
initiator: "loadRemote",
id
}).catch(() => void 0);
return {
...args,
remoteSnapshot
};
}
return args;
}
};
}
//#endregion
exports.assignRemoteInfo = assignRemoteInfo;
exports.snapshotPlugin = snapshotPlugin;
//# sourceMappingURL=index.cjs.map

View File

@@ -0,0 +1 @@
{"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"}

View File

@@ -0,0 +1,66 @@
import { error } from "../../utils/logger.js";
import { getRemoteEntryInfoFromSnapshot, isPureRemoteEntry, isRemoteInfoWithEntry } from "../../utils/tool.js";
import { composeRemoteRequestId } from "../../utils/manifest.js";
import "../../utils/index.js";
import { preloadAssets } from "../../utils/preload.js";
import { getResourceUrl, isBrowserEnvValue } from "@module-federation/sdk";
import { RUNTIME_011, runtimeDescMap } from "@module-federation/error-codes";
//#region src/plugins/snapshot/index.ts
function assignRemoteInfo(remoteInfo, remoteSnapshot) {
const remoteEntryInfo = getRemoteEntryInfoFromSnapshot(remoteSnapshot);
if (!remoteEntryInfo.url) error(RUNTIME_011, runtimeDescMap, { remoteName: remoteInfo.name });
let entryUrl = getResourceUrl(remoteSnapshot, remoteEntryInfo.url);
if (!isBrowserEnvValue && !entryUrl.startsWith("http")) entryUrl = `https:${entryUrl}`;
remoteInfo.type = remoteEntryInfo.type;
remoteInfo.entryGlobalName = remoteEntryInfo.globalName;
remoteInfo.entry = entryUrl;
remoteInfo.version = remoteSnapshot.version;
remoteInfo.buildVersion = remoteSnapshot.buildVersion;
}
function snapshotPlugin() {
return {
name: "snapshot-plugin",
async afterResolve(args) {
const { remote, pkgNameOrAlias, expose, origin, remoteInfo, id } = args;
if (!isRemoteInfoWithEntry(remote) || !isPureRemoteEntry(remote)) {
const { remoteSnapshot, globalSnapshot } = await origin.snapshotHandler.loadRemoteSnapshotInfo({
moduleInfo: remote,
id: composeRemoteRequestId(remote.name, expose)
});
assignRemoteInfo(remoteInfo, remoteSnapshot);
const preloadOptions = {
remote,
preloadConfig: {
nameOrAlias: pkgNameOrAlias,
exposes: [expose],
resourceCategory: "sync",
share: false,
depsRemote: false
}
};
const assets = await origin.remoteHandler.hooks.lifecycle.generatePreloadAssets.emit({
origin,
preloadOptions,
remoteInfo,
remote,
remoteSnapshot,
globalSnapshot
});
if (assets) preloadAssets(remoteInfo, origin, assets, false, {
initiator: "loadRemote",
id
}).catch(() => void 0);
return {
...args,
remoteSnapshot
};
}
return args;
}
};
}
//#endregion
export { assignRemoteInfo, snapshotPlugin };
//# sourceMappingURL=index.js.map

View File

@@ -0,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 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"}

View File

@@ -0,0 +1,442 @@
const require_logger = require('../utils/logger.cjs');
const require_global = require('../global.cjs');
const require_constant = require('../constant.cjs');
const require_share = require('../utils/share.cjs');
const require_manifest = require('../utils/manifest.cjs');
const require_load = require('../utils/load.cjs');
const require_context = require('../utils/context.cjs');
require('../utils/index.cjs');
const require_preload = require('../utils/preload.cjs');
const require_index$1 = require('../module/index.cjs');
const require_syncHook = require('../utils/hooks/syncHook.cjs');
const require_asyncHook = require('../utils/hooks/asyncHook.cjs');
const require_syncWaterfallHook = require('../utils/hooks/syncWaterfallHook.cjs');
const require_asyncWaterfallHooks = require('../utils/hooks/asyncWaterfallHooks.cjs');
const require_pluginSystem = require('../utils/hooks/pluginSystem.cjs');
require('../utils/hooks/index.cjs');
const require_SnapshotHandler = require('../plugins/snapshot/SnapshotHandler.cjs');
let _module_federation_sdk = require("@module-federation/sdk");
let _module_federation_error_codes = require("@module-federation/error-codes");
//#region src/remote/index.ts
var RemoteHandler = class {
constructor(host) {
this.hooks = new require_pluginSystem.PluginSystem({
beforeRegisterRemote: new require_syncWaterfallHook.SyncWaterfallHook("beforeRegisterRemote"),
registerRemote: new require_syncWaterfallHook.SyncWaterfallHook("registerRemote"),
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"),
errorLoadRemote: new require_asyncHook.AsyncHook("errorLoadRemote"),
beforePreloadRemote: new require_asyncHook.AsyncHook("beforePreloadRemote"),
generatePreloadAssets: new require_asyncHook.AsyncHook("generatePreloadAssets"),
afterPreloadRemote: new require_asyncHook.AsyncHook("afterPreloadRemote"),
loadEntry: new require_asyncHook.AsyncHook()
});
this.host = host;
this.idToRemoteMap = {};
}
formatAndRegisterRemote(globalOptions, userOptions) {
return (userOptions.remotes || []).reduce((res, remote) => {
this.registerRemote(remote, res, { force: false });
return res;
}, globalOptions.remotes);
}
setIdToRemoteMap(id, remoteMatchInfo) {
const { remote, expose } = remoteMatchInfo;
const { name, alias } = remote;
this.idToRemoteMap[id] = {
name: remote.name,
expose
};
if (alias && id.startsWith(name)) {
const idWithAlias = id.replace(name, alias);
this.idToRemoteMap[idWithAlias] = {
name: remote.name,
expose
};
return;
}
if (alias && id.startsWith(alias)) {
const idWithName = id.replace(alias, name);
this.idToRemoteMap[idWithName] = {
name: remote.name,
expose
};
}
}
async loadRemote(id, options) {
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 {
const { loadFactory = true } = options || { loadFactory: true };
const { module, moduleOptions, remoteMatchInfo } = await this.getRemoteModuleAndOptions({ id });
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);
const moduleWrapper = await this.hooks.lifecycle.onLoad.emit({
id: idRes,
pkgNameOrAlias,
expose,
exposeModule: loadFactory ? moduleOrFactory : void 0,
exposeModuleFactory: loadFactory ? void 0 : moduleOrFactory,
remote,
options: moduleOptions,
moduleInstance: module,
origin: host
});
this.setIdToRemoteMap(id, remoteMatchInfo);
afterLoadRemoteArgs = {
id: completeRequestId,
expose: completeExpose,
remote: completeRemote,
options,
origin: host
};
if (typeof moduleWrapper === "function") return moduleWrapper;
return moduleOrFactory;
} catch (error) {
const { from = "runtime" } = options || { from: "runtime" };
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,
origin: host,
recovered: true
};
return failOver;
} finally {
if (afterLoadRemoteArgs) await this.hooks.lifecycle.afterLoadRemote.emit(afterLoadRemoteArgs);
}
}
async preloadRemote(preloadOptions) {
const { host } = this;
const preloadResults = [];
await this.hooks.lifecycle.beforePreloadRemote.emit({
preloadOps: preloadOptions,
options: host.options,
origin: host
});
const preloadOps = require_preload.formatPreloadArgs(host.options.remotes, preloadOptions);
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);
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
});
}
await this.hooks.lifecycle.afterPreloadRemote.emit({
preloadOps: preloadOptions,
options: host.options,
origin: host,
results: preloadResults,
error: preloadError
});
if (preloadError) throw preloadError;
}
registerRemotes(remotes, options) {
const { host } = this;
remotes.forEach((remote) => {
this.registerRemote(remote, host.options.remotes, { force: options?.force });
});
}
async getRemoteModuleAndOptions(options) {
const { host } = this;
const { id } = options;
let loadRemoteArgs;
try {
loadRemoteArgs = await this.hooks.lifecycle.beforeRequest.emit({
id,
options: host.options,
origin: host
});
} catch (error) {
loadRemoteArgs = await this.hooks.lifecycle.errorLoadRemote.emit({
id,
options: host.options,
origin: host,
from: "runtime",
error,
lifecycle: "beforeRequest"
});
if (!loadRemoteArgs) throw error;
}
const { id: idRes } = loadRemoteArgs;
const remoteSplitInfo = require_manifest.matchRemoteWithNameAndExpose(host.options.remotes, idRes);
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({
id: idRes,
...remoteSplitInfo,
options: host.options,
origin: host,
remoteInfo
});
const { remote, expose } = matchInfo;
require_logger.assert(remote && expose, `The 'beforeRequest' hook was executed, but it failed to return the correct 'remote' and 'expose' values while loading ${idRes}.`);
let module = host.moduleCache.get(remote.name);
const moduleOptions = {
host,
remoteInfo
};
if (!module) {
module = new require_index$1.Module(moduleOptions);
host.moduleCache.set(remote.name, module);
}
return {
module,
moduleOptions,
remoteMatchInfo: matchInfo
};
}
registerRemote(remote, targetRemotes, options) {
const { host } = this;
const normalizeRemote = () => {
if (remote.alias) {
const findEqual = targetRemotes.find((item) => remote.alias && (item.name.startsWith(remote.alias) || item.alias?.startsWith(remote.alias)));
require_logger.assert(!findEqual, `The alias ${remote.alias} of remote ${remote.name} is not allowed to be the prefix of ${findEqual && findEqual.name} name or alias`);
}
if ("entry" in remote) {
if (_module_federation_sdk.isBrowserEnvValue && typeof window !== "undefined" && !remote.entry.startsWith("http")) remote.entry = new URL(remote.entry, window.location.origin).href;
}
if (!remote.shareScope) remote.shareScope = require_constant.DEFAULT_SCOPE;
if (!remote.type) remote.type = require_constant.DEFAULT_REMOTE_TYPE;
};
this.hooks.lifecycle.beforeRegisterRemote.emit({
remote,
origin: host
});
const registeredRemote = targetRemotes.find((item) => item.name === remote.name);
if (!registeredRemote) {
normalizeRemote();
targetRemotes.push(remote);
this.hooks.lifecycle.registerRemote.emit({
remote,
origin: host
});
} else {
const messages = [`The remote "${remote.name}" is already registered.`, "Please note that overriding it may cause unexpected errors."];
if (options?.force) {
this.removeRemote(registeredRemote);
normalizeRemote();
targetRemotes.push(remote);
this.hooks.lifecycle.registerRemote.emit({
remote,
origin: host
});
(0, _module_federation_sdk.warn)(messages.join(" "));
}
}
}
removeRemote(remote) {
try {
const { host } = this;
const { name } = remote;
const remoteIndex = host.options.remotes.findIndex((item) => item.name === name);
if (remoteIndex !== -1) host.options.remotes.splice(remoteIndex, 1);
const loadedModule = host.moduleCache.get(remote.name);
if (loadedModule) {
const remoteInfo = loadedModule.remoteInfo;
const key = remoteInfo.entryGlobalName;
if (require_global.CurrentGlobal[key]) if (Object.getOwnPropertyDescriptor(require_global.CurrentGlobal, key)?.configurable) delete require_global.CurrentGlobal[key];
else require_global.CurrentGlobal[key] = void 0;
const remoteEntryUniqueKey = require_load.getRemoteEntryUniqueKey(loadedModule.remoteInfo);
if (require_global.globalLoading[remoteEntryUniqueKey]) delete require_global.globalLoading[remoteEntryUniqueKey];
host.snapshotHandler.manifestCache.delete(remoteInfo.entry);
let remoteInsId = remoteInfo.buildVersion ? (0, _module_federation_sdk.composeKeyWithSeparator)(remoteInfo.name, remoteInfo.buildVersion) : remoteInfo.name;
const remoteInsIndex = require_global.CurrentGlobal.__FEDERATION__.__INSTANCES__.findIndex((ins) => {
if (remoteInfo.buildVersion) return ins.options.id === remoteInsId;
else return ins.name === remoteInsId;
});
if (remoteInsIndex !== -1) {
const remoteIns = require_global.CurrentGlobal.__FEDERATION__.__INSTANCES__[remoteInsIndex];
remoteInsId = remoteIns.options.id || remoteInsId;
const globalShareScopeMap = require_share.getGlobalShareScope();
let isAllSharedNotUsed = true;
const needDeleteKeys = [];
Object.keys(globalShareScopeMap).forEach((instId) => {
const shareScopeMap = globalShareScopeMap[instId];
shareScopeMap && Object.keys(shareScopeMap).forEach((shareScope) => {
const shareScopeVal = shareScopeMap[shareScope];
shareScopeVal && Object.keys(shareScopeVal).forEach((shareName) => {
const sharedPkgs = shareScopeVal[shareName];
sharedPkgs && Object.keys(sharedPkgs).forEach((shareVersion) => {
const shared = sharedPkgs[shareVersion];
if (shared && typeof shared === "object" && shared.from === remoteInfo.name) if (shared.loaded || shared.loading) {
shared.useIn = shared.useIn.filter((usedHostName) => usedHostName !== remoteInfo.name);
if (shared.useIn.length) isAllSharedNotUsed = false;
else needDeleteKeys.push([
instId,
shareScope,
shareName,
shareVersion
]);
} else needDeleteKeys.push([
instId,
shareScope,
shareName,
shareVersion
]);
});
});
});
});
if (isAllSharedNotUsed) {
remoteIns.shareScopeMap = {};
delete globalShareScopeMap[remoteInsId];
}
needDeleteKeys.forEach(([insId, shareScope, shareName, shareVersion]) => {
delete globalShareScopeMap[insId]?.[shareScope]?.[shareName]?.[shareVersion];
});
require_global.CurrentGlobal.__FEDERATION__.__INSTANCES__.splice(remoteInsIndex, 1);
}
const { hostGlobalSnapshot } = require_SnapshotHandler.getGlobalRemoteInfo(remote, host);
if (hostGlobalSnapshot) {
const remoteKey = hostGlobalSnapshot && "remotesInfo" in hostGlobalSnapshot && hostGlobalSnapshot.remotesInfo && require_global.getInfoWithoutType(hostGlobalSnapshot.remotesInfo, remote.name).key;
if (remoteKey) {
delete hostGlobalSnapshot.remotesInfo[remoteKey];
if (Boolean(require_global.Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey])) delete require_global.Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey];
}
}
host.moduleCache.delete(remote.name);
}
} catch (err) {
require_logger.logger.error(`removeRemote failed: ${err instanceof Error ? err.message : String(err)}`);
}
}
};
//#endregion
exports.RemoteHandler = RemoteHandler;
//# sourceMappingURL=index.cjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,145 @@
import { Module as Module$1, ModuleOptions } from "../module/index.js";
import { SyncHook } from "../utils/hooks/syncHook.js";
import { AsyncHook } from "../utils/hooks/asyncHook.js";
import { SyncWaterfallHook } from "../utils/hooks/syncWaterfallHook.js";
import { AsyncWaterfallHook } from "../utils/hooks/asyncWaterfallHooks.js";
import { PluginSystem } from "../utils/hooks/pluginSystem.js";
import { ModuleFederation } from "../core.js";
import { CallFrom, Options, Remote, RemoteEntryExports, RemoteInfo, UserOptions } from "../type/config.js";
import { PreloadAssets, PreloadOptions, PreloadRemoteArgs, PreloadRemoteResult } from "../type/preload.js";
import { GlobalModuleInfo, ModuleInfo } from "@module-federation/sdk";
//#region src/remote/index.d.ts
interface LoadRemoteMatch {
id: string;
pkgNameOrAlias: string;
expose: string;
remote: Remote;
options: Options;
origin: ModuleFederation;
remoteInfo: RemoteInfo;
remoteSnapshot?: ModuleInfo;
}
declare class RemoteHandler {
host: ModuleFederation;
idToRemoteMap: Record<string, {
name: string;
expose: string;
}>;
hooks: PluginSystem<{
beforeRegisterRemote: SyncWaterfallHook<{
remote: Remote;
origin: ModuleFederation;
}>;
registerRemote: SyncWaterfallHook<{
remote: Remote;
origin: ModuleFederation;
}>;
beforeRequest: AsyncWaterfallHook<{
id: string;
options: Options;
origin: ModuleFederation;
}>;
afterMatchRemote: AsyncHook<[{
id: string;
options: Options;
remote?: Remote;
expose?: string;
remoteInfo?: RemoteInfo;
error?: unknown;
origin: ModuleFederation;
}], void>;
onLoad: AsyncHook<[{
id: string;
expose: string;
pkgNameOrAlias: string;
remote: Remote;
options: ModuleOptions;
origin: ModuleFederation;
exposeModule: any;
exposeModuleFactory: any;
moduleInstance: Module$1;
}], unknown>;
afterLoadRemote: AsyncHook<[{
id: string;
expose?: string;
remote?: RemoteInfo;
options?: {
loadFactory?: boolean;
from?: CallFrom;
};
error?: unknown;
recovered?: boolean;
origin: ModuleFederation;
}], void>;
handlePreloadModule: SyncHook<[{
id: string;
name: string;
remote: Remote;
remoteSnapshot: ModuleInfo;
preloadConfig: PreloadRemoteArgs;
origin: ModuleFederation;
}], void>;
errorLoadRemote: AsyncHook<[{
id: string;
error: unknown;
options?: any;
from: CallFrom;
lifecycle: "beforeRequest" | "beforeLoadShare" | "afterResolve" | "onLoad";
remote?: RemoteInfo;
expose?: string;
origin: ModuleFederation;
}], unknown>;
beforePreloadRemote: AsyncHook<[{
preloadOps: Array<PreloadRemoteArgs>;
options: Options;
origin: ModuleFederation;
}], false | void | Promise<false | void>>;
generatePreloadAssets: AsyncHook<[{
origin: ModuleFederation;
preloadOptions: PreloadOptions[number];
remote: Remote;
remoteInfo: RemoteInfo;
remoteSnapshot: ModuleInfo;
globalSnapshot: GlobalModuleInfo;
}], Promise<PreloadAssets>>;
afterPreloadRemote: AsyncHook<[{
preloadOps: Array<PreloadRemoteArgs>;
options: Options;
origin: ModuleFederation;
results: PreloadRemoteResult[];
error?: unknown;
}], false | void | Promise<false | void>>;
loadEntry: AsyncHook<[{
origin: ModuleFederation;
loaderHook: ModuleFederation["loaderHook"];
remoteInfo: RemoteInfo;
remoteEntryExports?: RemoteEntryExports;
}], void | RemoteEntryExports | Promise<void | RemoteEntryExports>>;
}>;
constructor(host: ModuleFederation);
formatAndRegisterRemote(globalOptions: Options, userOptions: UserOptions): Remote[];
setIdToRemoteMap(id: string, remoteMatchInfo: LoadRemoteMatch): void;
loadRemote<T>(id: string, options?: {
loadFactory?: boolean;
from: CallFrom;
}): Promise<T | null>;
preloadRemote(preloadOptions: Array<PreloadRemoteArgs>): Promise<void>;
registerRemotes(remotes: Remote[], options?: {
force?: boolean;
}): void;
getRemoteModuleAndOptions(options: {
id: string;
}): Promise<{
module: Module$1;
moduleOptions: ModuleOptions;
remoteMatchInfo: LoadRemoteMatch;
}>;
registerRemote(remote: Remote, targetRemotes: Remote[], options?: {
force?: boolean;
}): void;
private removeRemote;
}
//#endregion
export { LoadRemoteMatch, RemoteHandler };
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,442 @@
import { assert, error, logger } from "../utils/logger.js";
import { CurrentGlobal, Global, getInfoWithoutType, globalLoading } from "../global.js";
import { DEFAULT_REMOTE_TYPE, DEFAULT_SCOPE } from "../constant.js";
import { getGlobalShareScope } from "../utils/share.js";
import { composeRemoteRequestId, matchRemoteWithNameAndExpose } from "../utils/manifest.js";
import { getRemoteEntryUniqueKey, getRemoteInfo } from "../utils/load.js";
import { optionsToMFContext } from "../utils/context.js";
import "../utils/index.js";
import { formatPreloadArgs, preloadAssets } from "../utils/preload.js";
import { Module as Module$1 } from "../module/index.js";
import { SyncHook } from "../utils/hooks/syncHook.js";
import { AsyncHook } from "../utils/hooks/asyncHook.js";
import { SyncWaterfallHook } from "../utils/hooks/syncWaterfallHook.js";
import { AsyncWaterfallHook } from "../utils/hooks/asyncWaterfallHooks.js";
import { PluginSystem } from "../utils/hooks/pluginSystem.js";
import "../utils/hooks/index.js";
import { getGlobalRemoteInfo } from "../plugins/snapshot/SnapshotHandler.js";
import { composeKeyWithSeparator, isBrowserEnvValue, warn } from "@module-federation/sdk";
import { RUNTIME_004, runtimeDescMap } from "@module-federation/error-codes";
//#region src/remote/index.ts
var RemoteHandler = class {
constructor(host) {
this.hooks = new PluginSystem({
beforeRegisterRemote: new SyncWaterfallHook("beforeRegisterRemote"),
registerRemote: new SyncWaterfallHook("registerRemote"),
beforeRequest: new AsyncWaterfallHook("beforeRequest"),
afterMatchRemote: new AsyncHook("afterMatchRemote"),
onLoad: new AsyncHook("onLoad"),
afterLoadRemote: new AsyncHook("afterLoadRemote"),
handlePreloadModule: new SyncHook("handlePreloadModule"),
errorLoadRemote: new AsyncHook("errorLoadRemote"),
beforePreloadRemote: new AsyncHook("beforePreloadRemote"),
generatePreloadAssets: new AsyncHook("generatePreloadAssets"),
afterPreloadRemote: new AsyncHook("afterPreloadRemote"),
loadEntry: new AsyncHook()
});
this.host = host;
this.idToRemoteMap = {};
}
formatAndRegisterRemote(globalOptions, userOptions) {
return (userOptions.remotes || []).reduce((res, remote) => {
this.registerRemote(remote, res, { force: false });
return res;
}, globalOptions.remotes);
}
setIdToRemoteMap(id, remoteMatchInfo) {
const { remote, expose } = remoteMatchInfo;
const { name, alias } = remote;
this.idToRemoteMap[id] = {
name: remote.name,
expose
};
if (alias && id.startsWith(name)) {
const idWithAlias = id.replace(name, alias);
this.idToRemoteMap[idWithAlias] = {
name: remote.name,
expose
};
return;
}
if (alias && id.startsWith(alias)) {
const idWithName = id.replace(alias, name);
this.idToRemoteMap[idWithName] = {
name: remote.name,
expose
};
}
}
async loadRemote(id, options) {
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 {
const { loadFactory = true } = options || { loadFactory: true };
const { module, moduleOptions, remoteMatchInfo } = await this.getRemoteModuleAndOptions({ id });
const { pkgNameOrAlias, remote, expose, id: idRes, remoteSnapshot } = remoteMatchInfo;
completeRequestId = idRes;
completeExpose = expose;
completeRemote = getRemoteInfo(remote);
const moduleOrFactory = await module.get(idRes, expose, options, remoteSnapshot);
const moduleWrapper = await this.hooks.lifecycle.onLoad.emit({
id: idRes,
pkgNameOrAlias,
expose,
exposeModule: loadFactory ? moduleOrFactory : void 0,
exposeModuleFactory: loadFactory ? void 0 : moduleOrFactory,
remote,
options: moduleOptions,
moduleInstance: module,
origin: host
});
this.setIdToRemoteMap(id, remoteMatchInfo);
afterLoadRemoteArgs = {
id: completeRequestId,
expose: completeExpose,
remote: completeRemote,
options,
origin: host
};
if (typeof moduleWrapper === "function") return moduleWrapper;
return moduleOrFactory;
} catch (error) {
const { from = "runtime" } = options || { from: "runtime" };
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,
origin: host,
recovered: true
};
return failOver;
} finally {
if (afterLoadRemoteArgs) await this.hooks.lifecycle.afterLoadRemote.emit(afterLoadRemoteArgs);
}
}
async preloadRemote(preloadOptions) {
const { host } = this;
const preloadResults = [];
await this.hooks.lifecycle.beforePreloadRemote.emit({
preloadOps: preloadOptions,
options: host.options,
origin: host
});
const preloadOps = formatPreloadArgs(host.options.remotes, preloadOptions);
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);
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
});
}
await this.hooks.lifecycle.afterPreloadRemote.emit({
preloadOps: preloadOptions,
options: host.options,
origin: host,
results: preloadResults,
error: preloadError
});
if (preloadError) throw preloadError;
}
registerRemotes(remotes, options) {
const { host } = this;
remotes.forEach((remote) => {
this.registerRemote(remote, host.options.remotes, { force: options?.force });
});
}
async getRemoteModuleAndOptions(options) {
const { host } = this;
const { id } = options;
let loadRemoteArgs;
try {
loadRemoteArgs = await this.hooks.lifecycle.beforeRequest.emit({
id,
options: host.options,
origin: host
});
} catch (error) {
loadRemoteArgs = await this.hooks.lifecycle.errorLoadRemote.emit({
id,
options: host.options,
origin: host,
from: "runtime",
error,
lifecycle: "beforeRequest"
});
if (!loadRemoteArgs) throw error;
}
const { id: idRes } = loadRemoteArgs;
const remoteSplitInfo = matchRemoteWithNameAndExpose(host.options.remotes, idRes);
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({
id: idRes,
...remoteSplitInfo,
options: host.options,
origin: host,
remoteInfo
});
const { remote, expose } = matchInfo;
assert(remote && expose, `The 'beforeRequest' hook was executed, but it failed to return the correct 'remote' and 'expose' values while loading ${idRes}.`);
let module = host.moduleCache.get(remote.name);
const moduleOptions = {
host,
remoteInfo
};
if (!module) {
module = new Module$1(moduleOptions);
host.moduleCache.set(remote.name, module);
}
return {
module,
moduleOptions,
remoteMatchInfo: matchInfo
};
}
registerRemote(remote, targetRemotes, options) {
const { host } = this;
const normalizeRemote = () => {
if (remote.alias) {
const findEqual = targetRemotes.find((item) => remote.alias && (item.name.startsWith(remote.alias) || item.alias?.startsWith(remote.alias)));
assert(!findEqual, `The alias ${remote.alias} of remote ${remote.name} is not allowed to be the prefix of ${findEqual && findEqual.name} name or alias`);
}
if ("entry" in remote) {
if (isBrowserEnvValue && typeof window !== "undefined" && !remote.entry.startsWith("http")) remote.entry = new URL(remote.entry, window.location.origin).href;
}
if (!remote.shareScope) remote.shareScope = DEFAULT_SCOPE;
if (!remote.type) remote.type = DEFAULT_REMOTE_TYPE;
};
this.hooks.lifecycle.beforeRegisterRemote.emit({
remote,
origin: host
});
const registeredRemote = targetRemotes.find((item) => item.name === remote.name);
if (!registeredRemote) {
normalizeRemote();
targetRemotes.push(remote);
this.hooks.lifecycle.registerRemote.emit({
remote,
origin: host
});
} else {
const messages = [`The remote "${remote.name}" is already registered.`, "Please note that overriding it may cause unexpected errors."];
if (options?.force) {
this.removeRemote(registeredRemote);
normalizeRemote();
targetRemotes.push(remote);
this.hooks.lifecycle.registerRemote.emit({
remote,
origin: host
});
warn(messages.join(" "));
}
}
}
removeRemote(remote) {
try {
const { host } = this;
const { name } = remote;
const remoteIndex = host.options.remotes.findIndex((item) => item.name === name);
if (remoteIndex !== -1) host.options.remotes.splice(remoteIndex, 1);
const loadedModule = host.moduleCache.get(remote.name);
if (loadedModule) {
const remoteInfo = loadedModule.remoteInfo;
const key = remoteInfo.entryGlobalName;
if (CurrentGlobal[key]) if (Object.getOwnPropertyDescriptor(CurrentGlobal, key)?.configurable) delete CurrentGlobal[key];
else CurrentGlobal[key] = void 0;
const remoteEntryUniqueKey = getRemoteEntryUniqueKey(loadedModule.remoteInfo);
if (globalLoading[remoteEntryUniqueKey]) delete globalLoading[remoteEntryUniqueKey];
host.snapshotHandler.manifestCache.delete(remoteInfo.entry);
let remoteInsId = remoteInfo.buildVersion ? composeKeyWithSeparator(remoteInfo.name, remoteInfo.buildVersion) : remoteInfo.name;
const remoteInsIndex = CurrentGlobal.__FEDERATION__.__INSTANCES__.findIndex((ins) => {
if (remoteInfo.buildVersion) return ins.options.id === remoteInsId;
else return ins.name === remoteInsId;
});
if (remoteInsIndex !== -1) {
const remoteIns = CurrentGlobal.__FEDERATION__.__INSTANCES__[remoteInsIndex];
remoteInsId = remoteIns.options.id || remoteInsId;
const globalShareScopeMap = getGlobalShareScope();
let isAllSharedNotUsed = true;
const needDeleteKeys = [];
Object.keys(globalShareScopeMap).forEach((instId) => {
const shareScopeMap = globalShareScopeMap[instId];
shareScopeMap && Object.keys(shareScopeMap).forEach((shareScope) => {
const shareScopeVal = shareScopeMap[shareScope];
shareScopeVal && Object.keys(shareScopeVal).forEach((shareName) => {
const sharedPkgs = shareScopeVal[shareName];
sharedPkgs && Object.keys(sharedPkgs).forEach((shareVersion) => {
const shared = sharedPkgs[shareVersion];
if (shared && typeof shared === "object" && shared.from === remoteInfo.name) if (shared.loaded || shared.loading) {
shared.useIn = shared.useIn.filter((usedHostName) => usedHostName !== remoteInfo.name);
if (shared.useIn.length) isAllSharedNotUsed = false;
else needDeleteKeys.push([
instId,
shareScope,
shareName,
shareVersion
]);
} else needDeleteKeys.push([
instId,
shareScope,
shareName,
shareVersion
]);
});
});
});
});
if (isAllSharedNotUsed) {
remoteIns.shareScopeMap = {};
delete globalShareScopeMap[remoteInsId];
}
needDeleteKeys.forEach(([insId, shareScope, shareName, shareVersion]) => {
delete globalShareScopeMap[insId]?.[shareScope]?.[shareName]?.[shareVersion];
});
CurrentGlobal.__FEDERATION__.__INSTANCES__.splice(remoteInsIndex, 1);
}
const { hostGlobalSnapshot } = getGlobalRemoteInfo(remote, host);
if (hostGlobalSnapshot) {
const remoteKey = hostGlobalSnapshot && "remotesInfo" in hostGlobalSnapshot && hostGlobalSnapshot.remotesInfo && getInfoWithoutType(hostGlobalSnapshot.remotesInfo, remote.name).key;
if (remoteKey) {
delete hostGlobalSnapshot.remotesInfo[remoteKey];
if (Boolean(Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey])) delete Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey];
}
}
host.moduleCache.delete(remote.name);
}
} catch (err) {
logger.error(`removeRemote failed: ${err instanceof Error ? err.message : String(err)}`);
}
}
};
//#endregion
export { RemoteHandler };
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,418 @@
const require_logger = require('../utils/logger.cjs');
const require_constant = require('../constant.cjs');
const require_share = require('../utils/share.cjs');
const require_context = require('../utils/context.cjs');
require('../utils/index.cjs');
const require_syncHook = require('../utils/hooks/syncHook.cjs');
const require_asyncHook = require('../utils/hooks/asyncHook.cjs');
const require_syncWaterfallHook = require('../utils/hooks/syncWaterfallHook.cjs');
const require_asyncWaterfallHooks = require('../utils/hooks/asyncWaterfallHooks.cjs');
const require_pluginSystem = require('../utils/hooks/pluginSystem.cjs');
require('../utils/hooks/index.cjs');
let _module_federation_error_codes = require("@module-federation/error-codes");
//#region src/shared/index.ts
var SharedHandler = class {
constructor(host) {
this.hooks = new require_pluginSystem.PluginSystem({
beforeRegisterShare: new require_syncWaterfallHook.SyncWaterfallHook("beforeRegisterShare"),
afterResolve: new require_asyncWaterfallHooks.AsyncWaterfallHook("afterResolve"),
beforeLoadShare: new require_asyncWaterfallHooks.AsyncWaterfallHook("beforeLoadShare"),
loadShare: new require_asyncHook.AsyncHook(),
afterLoadShare: new require_syncHook.SyncHook("afterLoadShare"),
errorLoadShare: new require_syncHook.SyncHook("errorLoadShare"),
resolveShare: new require_syncWaterfallHook.SyncWaterfallHook("resolveShare"),
initContainerShareScopeMap: new require_syncWaterfallHook.SyncWaterfallHook("initContainerShareScopeMap")
});
this.host = host;
this.shareScopeMap = {};
this.initTokens = {};
this._setGlobalShareScopeMap(host.options);
}
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) {
const { newShareInfos, allShareInfos } = require_share.formatShareConfigs(globalOptions, userOptions);
Object.keys(newShareInfos).forEach((sharedKey) => {
newShareInfos[sharedKey].forEach((sharedVal) => {
sharedVal.scope.forEach((sc) => {
this.hooks.lifecycle.beforeRegisterShare.emit({
origin: this.host,
pkgName: sharedKey,
shared: sharedVal
});
if (!this.shareScopeMap[sc]?.[sharedKey]) this.setShared({
pkgName: sharedKey,
lib: sharedVal.lib,
get: sharedVal.get,
loaded: sharedVal.loaded || Boolean(sharedVal.lib),
shared: sharedVal,
from: userOptions.name
});
});
});
});
return {
newShareInfos,
allShareInfos
};
}
async loadShare(pkgName, extraOptions) {
const { host } = this;
const shareOptions = require_share.getTargetSharedOptions({
pkgName,
extraOptions,
shareInfos: host.options.shared
});
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);
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;
};
const loading = asyncLoadProcess();
this.setShared({
pkgName,
loaded: false,
shared: resolvedShareOptions,
from: host.options.name,
lib: null,
loading,
treeShaking: _useTreeShaking ? targetShared : void 0
});
const factory = await loading;
this.emitAfterLoadShare({
lifecycle: "loadShare",
pkgName,
shareInfo: resolvedShareOptions,
selectedShared: resolvedShareOptions
});
return factory;
}
} catch (shareError) {
this.emitErrorLoadShare({
lifecycle: "loadShare",
pkgName,
shareInfo: shareOptionsRes,
error: shareError
});
throw shareError;
}
}
/**
* This function initializes the sharing sequence (executed only once per share scope).
* It accepts one argument, the name of the share scope.
* If the share scope does not exist, it creates one.
*/
initializeSharing(shareScopeName = require_constant.DEFAULT_SCOPE, extraOptions) {
const { host } = this;
const from = extraOptions?.from;
const strategy = extraOptions?.strategy;
let initScope = extraOptions?.initScope;
const promises = [];
if (from !== "build") {
const { initTokens } = this;
if (!initScope) initScope = [];
let initToken = initTokens[shareScopeName];
if (!initToken) initToken = initTokens[shareScopeName] = { from: this.host.name };
if (initScope.indexOf(initToken) >= 0) return promises;
initScope.push(initToken);
}
const shareScope = this.shareScopeMap;
const hostName = host.options.name;
if (!shareScope[shareScopeName]) shareScope[shareScopeName] = {};
const scope = shareScope[shareScopeName];
const register = (name, shared) => {
const { version, eager } = shared;
scope[name] = scope[name] || {};
const versions = scope[name];
const activeVersion = versions[version] && require_share.directShare(versions[version]);
const activeVersionEager = Boolean(activeVersion && ("eager" in activeVersion && activeVersion.eager || "shareConfig" in activeVersion && activeVersion.shareConfig?.eager));
if (!activeVersion || activeVersion.strategy !== "loaded-first" && !activeVersion.loaded && (Boolean(!eager) !== !activeVersionEager ? eager : hostName > versions[version].from)) versions[version] = shared;
};
const initRemoteModule = async (key) => {
const { module } = await host.remoteHandler.getRemoteModuleAndOptions({ id: key });
let remoteEntryExports = void 0;
try {
remoteEntryExports = await module.getEntry();
} catch (error) {
remoteEntryExports = await host.remoteHandler.hooks.lifecycle.errorLoadRemote.emit({
id: key,
error,
from: "runtime",
lifecycle: "beforeLoadShare",
remote: module.remoteInfo,
origin: host
});
if (!remoteEntryExports) return;
} finally {
if (remoteEntryExports?.init && !module.initing) {
module.remoteEntryExports = remoteEntryExports;
await module.init(void 0, void 0, initScope);
}
}
};
Object.keys(host.options.shared).forEach((shareName) => {
host.options.shared[shareName].forEach((shared) => {
if (shared.scope.includes(shareScopeName)) register(shareName, shared);
});
});
if (host.options.shareStrategy === "version-first" || strategy === "version-first") host.options.remotes.forEach((remote) => {
if (remote.shareScope === shareScopeName) promises.push(initRemoteModule(remote.name));
});
return promises;
}
loadShareSync(pkgName, extraOptions) {
const { host } = this;
const shareOptions = require_share.getTargetSharedOptions({
pkgName,
extraOptions,
shareInfos: host.options.shared
});
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);
if (!registeredShared.loaded) {
registeredShared.loaded = true;
if (registeredShared.from === host.options.name) shareOptions.loaded = true;
}
this.emitAfterLoadShare({
lifecycle: "loadShareSync",
pkgName,
shareInfo: shareOptions,
selectedShared: registeredShared
});
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;
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));
} catch (shareError) {
this.emitErrorLoadShare({
lifecycle: "loadShareSync",
pkgName,
shareInfo: shareOptions,
error: shareError
});
throw shareError;
}
}
initShareScopeMap(scopeName, shareScope, extraOptions = {}) {
const { host } = this;
this.shareScopeMap[scopeName] = shareScope;
this.hooks.lifecycle.initContainerShareScopeMap.emit({
shareScope,
options: host.options,
origin: host,
scopeName,
hostShareScopeMap: extraOptions.hostShareScopeMap
});
}
setShared({ pkgName, shared, from, lib, loading, loaded, get, treeShaking }) {
const { version, scope = "default", ...shareInfo } = shared;
const scopes = Array.isArray(scope) ? scope : [scope];
const mergeAttrs = (shared) => {
const merge = (s, key, val) => {
if (val && !s[key]) s[key] = val;
};
const targetShared = treeShaking ? shared.treeShaking : shared;
merge(targetShared, "loaded", loaded);
merge(targetShared, "loading", loading);
merge(targetShared, "get", get);
};
scopes.forEach((sc) => {
if (!this.shareScopeMap[sc]) this.shareScopeMap[sc] = {};
if (!this.shareScopeMap[sc][pkgName]) this.shareScopeMap[sc][pkgName] = {};
if (!this.shareScopeMap[sc][pkgName][version]) this.shareScopeMap[sc][pkgName][version] = {
version,
scope: [sc],
...shareInfo,
lib
};
const registeredShared = this.shareScopeMap[sc][pkgName][version];
mergeAttrs(registeredShared);
if (from && registeredShared.from !== from) registeredShared.from = from;
});
}
_setGlobalShareScopeMap(hostOptions) {
const globalShareScopeMap = require_share.getGlobalShareScope();
const identifier = hostOptions.id || hostOptions.name;
if (identifier && !globalShareScopeMap[identifier]) globalShareScopeMap[identifier] = this.shareScopeMap;
}
};
//#endregion
exports.SharedHandler = SharedHandler;
//# sourceMappingURL=index.cjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,104 @@
import { SyncHook } from "../utils/hooks/syncHook.js";
import { AsyncHook } from "../utils/hooks/asyncHook.js";
import { SyncWaterfallHook } from "../utils/hooks/syncWaterfallHook.js";
import { AsyncWaterfallHook } from "../utils/hooks/asyncWaterfallHooks.js";
import { PluginSystem } from "../utils/hooks/pluginSystem.js";
import { Federation } from "../global.js";
import { LoadRemoteMatch } from "../remote/index.js";
import { ModuleFederation } from "../core.js";
import { CallFrom, InitScope, InitTokens, Options, ShareInfos, ShareScopeMap, ShareStrategy, Shared, UserOptions } from "../type/config.js";
//#region src/shared/index.d.ts
declare class SharedHandler {
host: ModuleFederation;
shareScopeMap: ShareScopeMap;
hooks: PluginSystem<{
beforeRegisterShare: SyncWaterfallHook<{
pkgName: string;
shared: Shared;
origin: ModuleFederation;
}>;
afterResolve: AsyncWaterfallHook<LoadRemoteMatch>;
beforeLoadShare: AsyncWaterfallHook<{
pkgName: string;
shareInfo?: Shared;
shared: Options["shared"];
origin: ModuleFederation;
}>;
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<{
shareScopeMap: ShareScopeMap;
scope: string;
pkgName: string;
version: string;
shareInfo: Shared;
GlobalFederation: Federation;
resolver: () => {
shared: Shared;
useTreesShaking: boolean;
} | undefined;
}>;
initContainerShareScopeMap: SyncWaterfallHook<{
shareScope: ShareScopeMap[string];
options: Options;
origin: ModuleFederation;
scopeName: string;
hostShareScopeMap?: ShareScopeMap;
}>;
}>;
initTokens: InitTokens;
constructor(host: ModuleFederation);
private emitAfterLoadShare;
private emitErrorLoadShare;
registerShared(globalOptions: Options, userOptions: UserOptions): {
newShareInfos: ShareInfos;
allShareInfos: {
[pkgName: string]: Shared[];
};
};
loadShare<T>(pkgName: string, extraOptions?: {
customShareInfo?: Partial<Shared>;
resolver?: (sharedOptions: ShareInfos[string]) => Shared;
}): Promise<false | (() => T | undefined)>;
/**
* This function initializes the sharing sequence (executed only once per share scope).
* It accepts one argument, the name of the share scope.
* If the share scope does not exist, it creates one.
*/
initializeSharing(shareScopeName?: string, extraOptions?: {
initScope?: InitScope;
from?: CallFrom;
strategy?: ShareStrategy;
}): Array<Promise<void>>;
loadShareSync<T>(pkgName: string, extraOptions?: {
from?: 'build' | 'runtime';
customShareInfo?: Partial<Shared>;
resolver?: (sharedOptions: ShareInfos[string]) => Shared;
}): () => T | never;
initShareScopeMap(scopeName: string, shareScope: ShareScopeMap[string], extraOptions?: {
hostShareScopeMap?: ShareScopeMap;
}): void;
private setShared;
private _setGlobalShareScopeMap;
}
//#endregion
export { SharedHandler };
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,418 @@
import { assert, error, warn } from "../utils/logger.js";
import { DEFAULT_SCOPE } from "../constant.js";
import { addUseIn, directShare, formatShareConfigs, getGlobalShareScope, getRegisteredShare, getTargetSharedOptions, shouldUseTreeShaking } from "../utils/share.js";
import { optionsToMFContext } from "../utils/context.js";
import "../utils/index.js";
import { SyncHook } from "../utils/hooks/syncHook.js";
import { AsyncHook } from "../utils/hooks/asyncHook.js";
import { SyncWaterfallHook } from "../utils/hooks/syncWaterfallHook.js";
import { AsyncWaterfallHook } from "../utils/hooks/asyncWaterfallHooks.js";
import { PluginSystem } from "../utils/hooks/pluginSystem.js";
import "../utils/hooks/index.js";
import { RUNTIME_005, RUNTIME_006, runtimeDescMap } from "@module-federation/error-codes";
//#region src/shared/index.ts
var SharedHandler = class {
constructor(host) {
this.hooks = new PluginSystem({
beforeRegisterShare: new SyncWaterfallHook("beforeRegisterShare"),
afterResolve: new AsyncWaterfallHook("afterResolve"),
beforeLoadShare: new AsyncWaterfallHook("beforeLoadShare"),
loadShare: new AsyncHook(),
afterLoadShare: new SyncHook("afterLoadShare"),
errorLoadShare: new SyncHook("errorLoadShare"),
resolveShare: new SyncWaterfallHook("resolveShare"),
initContainerShareScopeMap: new SyncWaterfallHook("initContainerShareScopeMap")
});
this.host = host;
this.shareScopeMap = {};
this.initTokens = {};
this._setGlobalShareScopeMap(host.options);
}
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) {
const { newShareInfos, allShareInfos } = formatShareConfigs(globalOptions, userOptions);
Object.keys(newShareInfos).forEach((sharedKey) => {
newShareInfos[sharedKey].forEach((sharedVal) => {
sharedVal.scope.forEach((sc) => {
this.hooks.lifecycle.beforeRegisterShare.emit({
origin: this.host,
pkgName: sharedKey,
shared: sharedVal
});
if (!this.shareScopeMap[sc]?.[sharedKey]) this.setShared({
pkgName: sharedKey,
lib: sharedVal.lib,
get: sharedVal.get,
loaded: sharedVal.loaded || Boolean(sharedVal.lib),
shared: sharedVal,
from: userOptions.name
});
});
});
});
return {
newShareInfos,
allShareInfos
};
}
async loadShare(pkgName, extraOptions) {
const { host } = this;
const shareOptions = getTargetSharedOptions({
pkgName,
extraOptions,
shareInfos: host.options.shared
});
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);
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;
};
const loading = asyncLoadProcess();
this.setShared({
pkgName,
loaded: false,
shared: resolvedShareOptions,
from: host.options.name,
lib: null,
loading,
treeShaking: _useTreeShaking ? targetShared : void 0
});
const factory = await loading;
this.emitAfterLoadShare({
lifecycle: "loadShare",
pkgName,
shareInfo: resolvedShareOptions,
selectedShared: resolvedShareOptions
});
return factory;
}
} catch (shareError) {
this.emitErrorLoadShare({
lifecycle: "loadShare",
pkgName,
shareInfo: shareOptionsRes,
error: shareError
});
throw shareError;
}
}
/**
* This function initializes the sharing sequence (executed only once per share scope).
* It accepts one argument, the name of the share scope.
* If the share scope does not exist, it creates one.
*/
initializeSharing(shareScopeName = DEFAULT_SCOPE, extraOptions) {
const { host } = this;
const from = extraOptions?.from;
const strategy = extraOptions?.strategy;
let initScope = extraOptions?.initScope;
const promises = [];
if (from !== "build") {
const { initTokens } = this;
if (!initScope) initScope = [];
let initToken = initTokens[shareScopeName];
if (!initToken) initToken = initTokens[shareScopeName] = { from: this.host.name };
if (initScope.indexOf(initToken) >= 0) return promises;
initScope.push(initToken);
}
const shareScope = this.shareScopeMap;
const hostName = host.options.name;
if (!shareScope[shareScopeName]) shareScope[shareScopeName] = {};
const scope = shareScope[shareScopeName];
const register = (name, shared) => {
const { version, eager } = shared;
scope[name] = scope[name] || {};
const versions = scope[name];
const activeVersion = versions[version] && directShare(versions[version]);
const activeVersionEager = Boolean(activeVersion && ("eager" in activeVersion && activeVersion.eager || "shareConfig" in activeVersion && activeVersion.shareConfig?.eager));
if (!activeVersion || activeVersion.strategy !== "loaded-first" && !activeVersion.loaded && (Boolean(!eager) !== !activeVersionEager ? eager : hostName > versions[version].from)) versions[version] = shared;
};
const initRemoteModule = async (key) => {
const { module } = await host.remoteHandler.getRemoteModuleAndOptions({ id: key });
let remoteEntryExports = void 0;
try {
remoteEntryExports = await module.getEntry();
} catch (error) {
remoteEntryExports = await host.remoteHandler.hooks.lifecycle.errorLoadRemote.emit({
id: key,
error,
from: "runtime",
lifecycle: "beforeLoadShare",
remote: module.remoteInfo,
origin: host
});
if (!remoteEntryExports) return;
} finally {
if (remoteEntryExports?.init && !module.initing) {
module.remoteEntryExports = remoteEntryExports;
await module.init(void 0, void 0, initScope);
}
}
};
Object.keys(host.options.shared).forEach((shareName) => {
host.options.shared[shareName].forEach((shared) => {
if (shared.scope.includes(shareScopeName)) register(shareName, shared);
});
});
if (host.options.shareStrategy === "version-first" || strategy === "version-first") host.options.remotes.forEach((remote) => {
if (remote.shareScope === shareScopeName) promises.push(initRemoteModule(remote.name));
});
return promises;
}
loadShareSync(pkgName, extraOptions) {
const { host } = this;
const shareOptions = getTargetSharedOptions({
pkgName,
extraOptions,
shareInfos: host.options.shared
});
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);
if (!registeredShared.loaded) {
registeredShared.loaded = true;
if (registeredShared.from === host.options.name) shareOptions.loaded = true;
}
this.emitAfterLoadShare({
lifecycle: "loadShareSync",
pkgName,
shareInfo: shareOptions,
selectedShared: registeredShared
});
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;
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));
} catch (shareError) {
this.emitErrorLoadShare({
lifecycle: "loadShareSync",
pkgName,
shareInfo: shareOptions,
error: shareError
});
throw shareError;
}
}
initShareScopeMap(scopeName, shareScope, extraOptions = {}) {
const { host } = this;
this.shareScopeMap[scopeName] = shareScope;
this.hooks.lifecycle.initContainerShareScopeMap.emit({
shareScope,
options: host.options,
origin: host,
scopeName,
hostShareScopeMap: extraOptions.hostShareScopeMap
});
}
setShared({ pkgName, shared, from, lib, loading, loaded, get, treeShaking }) {
const { version, scope = "default", ...shareInfo } = shared;
const scopes = Array.isArray(scope) ? scope : [scope];
const mergeAttrs = (shared) => {
const merge = (s, key, val) => {
if (val && !s[key]) s[key] = val;
};
const targetShared = treeShaking ? shared.treeShaking : shared;
merge(targetShared, "loaded", loaded);
merge(targetShared, "loading", loading);
merge(targetShared, "get", get);
};
scopes.forEach((sc) => {
if (!this.shareScopeMap[sc]) this.shareScopeMap[sc] = {};
if (!this.shareScopeMap[sc][pkgName]) this.shareScopeMap[sc][pkgName] = {};
if (!this.shareScopeMap[sc][pkgName][version]) this.shareScopeMap[sc][pkgName][version] = {
version,
scope: [sc],
...shareInfo,
lib
};
const registeredShared = this.shareScopeMap[sc][pkgName][version];
mergeAttrs(registeredShared);
if (from && registeredShared.from !== from) registeredShared.from = from;
});
}
_setGlobalShareScopeMap(hostOptions) {
const globalShareScopeMap = getGlobalShareScope();
const identifier = hostOptions.id || hostOptions.name;
if (identifier && !globalShareScopeMap[identifier]) globalShareScopeMap[identifier] = this.shareScopeMap;
}
};
//#endregion
export { SharedHandler };
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,130 @@
import { ModuleFederationRuntimePlugin } from "./plugin.js";
import { Module, RemoteEntryType, RemoteWithEntry, RemoteWithVersion, TreeShakingStatus } from "@module-federation/sdk";
//#region src/type/config.d.ts
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<T>;
type PartialOptional<T, K extends keyof T> = Omit<T, K> & { [P in K]-?: T[P] };
interface RemoteInfoCommon {
alias?: string;
shareScope?: string | string[];
type?: RemoteEntryType;
entryGlobalName?: string;
}
type RemoteInfoOptionalVersion = {
name: string;
version?: string;
} & RemoteInfoCommon;
type Remote = (RemoteWithEntry | RemoteWithVersion) & RemoteInfoCommon;
type LoadShareExtraOptions = {
customShareInfo?: Partial<Shared>;
resolver?: (sharedOptions: ShareInfos[string]) => Shared;
};
interface RemoteInfo {
alias?: string;
name: string;
version?: string;
buildVersion?: string;
entry: string;
type: RemoteEntryType;
entryGlobalName: string;
shareScope: string | string[];
}
type HostInfo = Pick<Options, 'name' | 'version' | 'remotes' | 'version'>;
interface SharedConfig {
singleton?: boolean;
requiredVersion: false | string;
eager?: boolean;
strictVersion?: boolean;
layer?: string | null;
}
type TreeShakingArgs = {
usedExports?: string[];
get?: SharedGetter;
lib?: () => Module;
status?: TreeShakingStatus;
mode?: 'server-calc' | 'runtime-infer';
loading?: null | Promise<any>;
loaded?: boolean;
useIn?: Array<string>;
};
type SharedBaseArgs = {
version?: string;
shareConfig?: SharedConfig;
scope?: string | Array<string>;
deps?: Array<string>;
strategy?: 'version-first' | 'loaded-first';
loaded?: boolean;
treeShaking?: TreeShakingArgs;
};
type SharedGetter = (() => () => Module) | (() => Promise<() => Module>);
type ShareArgs = (SharedBaseArgs & {
get: SharedGetter;
}) | (SharedBaseArgs & {
lib: () => Module;
}) | SharedBaseArgs;
type ShareStrategy = 'version-first' | 'loaded-first';
type NoMatchedUsedExportsItem = [from: string, usedExports?: string[]];
type Shared = {
version: string;
get: SharedGetter;
shareConfig: SharedConfig;
scope: Array<string>;
useIn: Array<string>;
from: string;
deps: Array<string>;
lib?: () => Module;
loaded?: boolean;
loading?: null | Promise<any>;
eager?: boolean;
/**
* @deprecated set in initOptions.shareStrategy instead
*/
strategy: ShareStrategy;
treeShaking?: TreeShakingArgs;
};
type ShareScopeMap = {
[scope: string]: {
[pkgName: string]: {
[sharedVersion: string]: Shared;
};
};
};
type GlobalShareScopeMap = {
[instanceName: string]: ShareScopeMap;
};
type ShareInfos = {
[pkgName: string]: Shared[];
};
interface Options {
id?: string;
name: string;
version?: string;
remotes: Array<Remote>;
shared: ShareInfos;
plugins: Array<ModuleFederationRuntimePlugin>;
inBrowser: boolean;
shareStrategy?: ShareStrategy;
}
type UserOptions = Omit<Optional<Options, 'plugins'>, 'shared' | 'inBrowser'> & {
shared?: {
[pkgName: string]: ShareArgs | ShareArgs[];
};
};
type LoadModuleOptions = {
version?: string;
};
type RemoteEntryInitOptions = {
version: string;
shareScopeMap?: ShareScopeMap;
shareScopeKeys: string | string[];
};
type InitTokens = Record<string, Record<string, any>>;
type InitScope = InitTokens[];
type CallFrom = 'build' | 'runtime';
type RemoteEntryExports = {
get: (id: string) => () => Promise<Module>;
init: (shareScope: ShareScopeMap[string], initScope?: InitScope, remoteEntryInitOPtions?: RemoteEntryInitOptions) => void | Promise<void>;
};
//#endregion
export { 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 };
//# sourceMappingURL=config.d.ts.map

View File

@@ -0,0 +1,13 @@
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
//#region src/type/index.ts
var type_exports = /* @__PURE__ */ require_runtime.__exportAll({});
//#endregion
Object.defineProperty(exports, 'type_exports', {
enumerable: true,
get: function () {
return type_exports;
}
});
//# sourceMappingURL=index.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.cjs","names":[],"sources":["../../src/type/index.ts"],"sourcesContent":["export * from './config';\nexport * from './plugin';\nexport * from './preload';\n"],"mappings":""}

View File

@@ -0,0 +1,11 @@
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, 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, 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 };
}
//#endregion
export { index_d_exports };
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,8 @@
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
//#region src/type/index.ts
var type_exports = /* @__PURE__ */ __exportAll({});
//#endregion
export { type_exports };
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","names":[],"sources":["../../src/type/index.ts"],"sourcesContent":["export * from './config';\nexport * from './plugin';\nexport * from './preload';\n"],"mappings":""}

View File

@@ -0,0 +1,27 @@
import { Module } from "../module/index.js";
import { SnapshotHandler } from "../plugins/snapshot/SnapshotHandler.js";
import { RemoteHandler } from "../remote/index.js";
import { SharedHandler } from "../shared/index.js";
import { ModuleFederation } from "../core.js";
//#region src/type/plugin.d.ts
type CoreLifeCycle = ModuleFederation['hooks']['lifecycle'];
type CoreLifeCyclePartial = Partial<{ [k in keyof CoreLifeCycle]: Parameters<CoreLifeCycle[k]['on']>[0] }>;
type SnapshotLifeCycle = SnapshotHandler['hooks']['lifecycle'];
type SnapshotLifeCycleCyclePartial = Partial<{ [k in keyof SnapshotLifeCycle]: Parameters<SnapshotLifeCycle[k]['on']>[0] }>;
type ModuleLifeCycle = Module['host']['loaderHook']['lifecycle'];
type ModuleLifeCycleCyclePartial = Partial<{ [k in keyof ModuleLifeCycle]: Parameters<ModuleLifeCycle[k]['on']>[0] }>;
type ModuleBridgeLifeCycle = Module['host']['bridgeHook']['lifecycle'];
type ModuleBridgeLifeCycleCyclePartial = Partial<{ [k in keyof ModuleBridgeLifeCycle]: Parameters<ModuleBridgeLifeCycle[k]['on']>[0] }>;
type SharedLifeCycle = SharedHandler['hooks']['lifecycle'];
type SharedLifeCycleCyclePartial = Partial<{ [k in keyof SharedLifeCycle]: Parameters<SharedLifeCycle[k]['on']>[0] }>;
type RemoteLifeCycle = RemoteHandler['hooks']['lifecycle'];
type RemoteLifeCycleCyclePartial = Partial<{ [k in keyof RemoteLifeCycle]: Parameters<RemoteLifeCycle[k]['on']>[0] }>;
type ModuleFederationRuntimePlugin = CoreLifeCyclePartial & SnapshotLifeCycleCyclePartial & SharedLifeCycleCyclePartial & RemoteLifeCycleCyclePartial & ModuleLifeCycleCyclePartial & ModuleBridgeLifeCycleCyclePartial & {
name: string;
version?: string;
apply?: (instance: ModuleFederation) => void;
};
//#endregion
export { ModuleFederationRuntimePlugin };
//# sourceMappingURL=plugin.d.ts.map

View File

@@ -0,0 +1,54 @@
import { Remote, RemoteInfo } from "./config.js";
//#region src/type/preload.d.ts
type depsPreloadArg = Omit<PreloadRemoteArgs, 'depsRemote'>;
interface PreloadRemoteArgs {
nameOrAlias: string;
exposes?: Array<string>;
resourceCategory?: 'all' | 'sync';
share?: boolean;
depsRemote?: boolean | Array<depsPreloadArg>;
filter?: (assetUrl: string) => boolean;
}
type PreloadConfig = PreloadRemoteArgs;
type PreloadOptions = Array<{
remote: Remote;
preloadConfig: PreloadConfig;
}>;
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 = {
name: string;
url: string;
moduleInfo: RemoteInfo;
};
interface PreloadAssets {
cssAssets: Array<string>;
jsAssetsWithoutEntry: Array<string>;
entryAssets: Array<EntryAssets>;
}
//#endregion
export { EntryAssets, PreloadAssetResult, PreloadAssetStatus, PreloadAssets, PreloadConfig, PreloadOptions, PreloadRemoteArgs, PreloadRemoteResult, ResourceLoadContext, ResourceLoadInitiator, ResourceLoadType, depsPreloadArg };
//# sourceMappingURL=preload.d.ts.map

View File

View File

@@ -0,0 +1,4 @@
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, 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 };

View File

@@ -0,0 +1 @@
export { };

View File

@@ -0,0 +1,45 @@
//#region src/utils/context.ts
function remoteToEntry(r) {
return {
name: r.name,
alias: r.alias,
entry: "entry" in r ? r.entry : void 0,
version: "version" in r ? r.version : void 0,
type: r.type,
entryGlobalName: r.entryGlobalName,
shareScope: r.shareScope
};
}
/**
* Build a partial MFContext from runtime Options.
* Used to enrich diagnostic entries with host context at error sites.
*/
function optionsToMFContext(options) {
const shared = {};
for (const [pkgName, versions] of Object.entries(options.shared)) {
const first = versions[0];
if (first) shared[pkgName] = {
version: first.version,
singleton: first.shareConfig?.singleton,
requiredVersion: first.shareConfig?.requiredVersion === false ? false : first.shareConfig?.requiredVersion,
eager: first.eager,
strictVersion: first.shareConfig?.strictVersion
};
}
return {
project: {
name: options.name,
mfRole: options.remotes?.length > 0 ? "host" : "unknown"
},
mfConfig: {
name: options.name,
remotes: options.remotes?.map(remoteToEntry) ?? [],
shared
}
};
}
//#endregion
exports.optionsToMFContext = optionsToMFContext;
//# sourceMappingURL=context.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"context.cjs","names":[],"sources":["../../src/utils/context.ts"],"sourcesContent":["import type { MFContext } from '@module-federation/error-codes';\nimport type { Options, Remote } from '../type';\n\nfunction remoteToEntry(\n r: Remote,\n): import('@module-federation/error-codes').MFRemoteEntry {\n return {\n name: r.name,\n alias: r.alias,\n entry: 'entry' in r ? (r as { entry: string }).entry : undefined,\n version: 'version' in r ? (r as { version: string }).version : undefined,\n type: r.type,\n entryGlobalName: r.entryGlobalName,\n shareScope: r.shareScope,\n };\n}\n\n/**\n * Build a partial MFContext from runtime Options.\n * Used to enrich diagnostic entries with host context at error sites.\n */\nexport function optionsToMFContext(options: Options): Partial<MFContext> {\n const shared: MFContext['mfConfig'] extends undefined\n ? never\n : NonNullable<MFContext['mfConfig']>['shared'] = {};\n\n for (const [pkgName, versions] of Object.entries(options.shared)) {\n const first = versions[0];\n if (first) {\n shared[pkgName] = {\n version: first.version,\n singleton: first.shareConfig?.singleton,\n requiredVersion:\n first.shareConfig?.requiredVersion === false\n ? false\n : first.shareConfig?.requiredVersion,\n eager: first.eager,\n strictVersion: first.shareConfig?.strictVersion,\n };\n }\n }\n\n return {\n project: {\n name: options.name,\n mfRole: options.remotes?.length > 0 ? 'host' : 'unknown',\n },\n mfConfig: {\n name: options.name,\n remotes: options.remotes?.map(remoteToEntry) ?? [],\n shared,\n },\n };\n}\n"],"mappings":";;AAGA,SAAS,cACP,GACwD;AACxD,QAAO;EACL,MAAM,EAAE;EACR,OAAO,EAAE;EACT,OAAO,WAAW,IAAK,EAAwB,QAAQ;EACvD,SAAS,aAAa,IAAK,EAA0B,UAAU;EAC/D,MAAM,EAAE;EACR,iBAAiB,EAAE;EACnB,YAAY,EAAE;EACf;;;;;;AAOH,SAAgB,mBAAmB,SAAsC;CACvE,MAAM,SAE6C,EAAE;AAErD,MAAK,MAAM,CAAC,SAAS,aAAa,OAAO,QAAQ,QAAQ,OAAO,EAAE;EAChE,MAAM,QAAQ,SAAS;AACvB,MAAI,MACF,QAAO,WAAW;GAChB,SAAS,MAAM;GACf,WAAW,MAAM,aAAa;GAC9B,iBACE,MAAM,aAAa,oBAAoB,QACnC,QACA,MAAM,aAAa;GACzB,OAAO,MAAM;GACb,eAAe,MAAM,aAAa;GACnC;;AAIL,QAAO;EACL,SAAS;GACP,MAAM,QAAQ;GACd,QAAQ,QAAQ,SAAS,SAAS,IAAI,SAAS;GAChD;EACD,UAAU;GACR,MAAM,QAAQ;GACd,SAAS,QAAQ,SAAS,IAAI,cAAc,IAAI,EAAE;GAClD;GACD;EACF"}

View File

@@ -0,0 +1 @@
import { MFContext } from "@module-federation/error-codes";

View File

@@ -0,0 +1,44 @@
//#region src/utils/context.ts
function remoteToEntry(r) {
return {
name: r.name,
alias: r.alias,
entry: "entry" in r ? r.entry : void 0,
version: "version" in r ? r.version : void 0,
type: r.type,
entryGlobalName: r.entryGlobalName,
shareScope: r.shareScope
};
}
/**
* Build a partial MFContext from runtime Options.
* Used to enrich diagnostic entries with host context at error sites.
*/
function optionsToMFContext(options) {
const shared = {};
for (const [pkgName, versions] of Object.entries(options.shared)) {
const first = versions[0];
if (first) shared[pkgName] = {
version: first.version,
singleton: first.shareConfig?.singleton,
requiredVersion: first.shareConfig?.requiredVersion === false ? false : first.shareConfig?.requiredVersion,
eager: first.eager,
strictVersion: first.shareConfig?.strictVersion
};
}
return {
project: {
name: options.name,
mfRole: options.remotes?.length > 0 ? "host" : "unknown"
},
mfConfig: {
name: options.name,
remotes: options.remotes?.map(remoteToEntry) ?? [],
shared
}
};
}
//#endregion
export { optionsToMFContext };
//# sourceMappingURL=context.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"context.js","names":[],"sources":["../../src/utils/context.ts"],"sourcesContent":["import type { MFContext } from '@module-federation/error-codes';\nimport type { Options, Remote } from '../type';\n\nfunction remoteToEntry(\n r: Remote,\n): import('@module-federation/error-codes').MFRemoteEntry {\n return {\n name: r.name,\n alias: r.alias,\n entry: 'entry' in r ? (r as { entry: string }).entry : undefined,\n version: 'version' in r ? (r as { version: string }).version : undefined,\n type: r.type,\n entryGlobalName: r.entryGlobalName,\n shareScope: r.shareScope,\n };\n}\n\n/**\n * Build a partial MFContext from runtime Options.\n * Used to enrich diagnostic entries with host context at error sites.\n */\nexport function optionsToMFContext(options: Options): Partial<MFContext> {\n const shared: MFContext['mfConfig'] extends undefined\n ? never\n : NonNullable<MFContext['mfConfig']>['shared'] = {};\n\n for (const [pkgName, versions] of Object.entries(options.shared)) {\n const first = versions[0];\n if (first) {\n shared[pkgName] = {\n version: first.version,\n singleton: first.shareConfig?.singleton,\n requiredVersion:\n first.shareConfig?.requiredVersion === false\n ? false\n : first.shareConfig?.requiredVersion,\n eager: first.eager,\n strictVersion: first.shareConfig?.strictVersion,\n };\n }\n }\n\n return {\n project: {\n name: options.name,\n mfRole: options.remotes?.length > 0 ? 'host' : 'unknown',\n },\n mfConfig: {\n name: options.name,\n remotes: options.remotes?.map(remoteToEntry) ?? [],\n shared,\n },\n };\n}\n"],"mappings":";AAGA,SAAS,cACP,GACwD;AACxD,QAAO;EACL,MAAM,EAAE;EACR,OAAO,EAAE;EACT,OAAO,WAAW,IAAK,EAAwB,QAAQ;EACvD,SAAS,aAAa,IAAK,EAA0B,UAAU;EAC/D,MAAM,EAAE;EACR,iBAAiB,EAAE;EACnB,YAAY,EAAE;EACf;;;;;;AAOH,SAAgB,mBAAmB,SAAsC;CACvE,MAAM,SAE6C,EAAE;AAErD,MAAK,MAAM,CAAC,SAAS,aAAa,OAAO,QAAQ,QAAQ,OAAO,EAAE;EAChE,MAAM,QAAQ,SAAS;AACvB,MAAI,MACF,QAAO,WAAW;GAChB,SAAS,MAAM;GACf,WAAW,MAAM,aAAa;GAC9B,iBACE,MAAM,aAAa,oBAAoB,QACnC,QACA,MAAM,aAAa;GACzB,OAAO,MAAM;GACb,eAAe,MAAM,aAAa;GACnC;;AAIL,QAAO;EACL,SAAS;GACP,MAAM,QAAQ;GACd,QAAQ,QAAQ,SAAS,SAAS,IAAI,SAAS;GAChD;EACD,UAAU;GACR,MAAM,QAAQ;GACd,SAAS,QAAQ,SAAS,IAAI,cAAc,IAAI,EAAE;GAClD;GACD;EACF"}

View File

@@ -0,0 +1,10 @@
let _module_federation_sdk = require("@module-federation/sdk");
//#region src/utils/env.ts
function getBuilderId() {
return typeof FEDERATION_BUILD_IDENTIFIER !== "undefined" ? FEDERATION_BUILD_IDENTIFIER : "";
}
//#endregion
exports.getBuilderId = getBuilderId;
//# sourceMappingURL=env.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"env.cjs","names":[],"sources":["../../src/utils/env.ts"],"sourcesContent":["export {\n isBrowserEnv,\n isBrowserEnvValue,\n isDebugMode,\n} from '@module-federation/sdk';\n\nexport function isDevelopmentMode(): boolean {\n return true;\n}\n\nexport function getBuilderId(): string {\n //@ts-ignore\n return typeof FEDERATION_BUILD_IDENTIFIER !== 'undefined'\n ? //@ts-ignore\n FEDERATION_BUILD_IDENTIFIER\n : '';\n}\n"],"mappings":";;;AAUA,SAAgB,eAAuB;AAErC,QAAO,OAAO,gCAAgC,cAE1C,8BACA"}

View File

@@ -0,0 +1 @@
export { };

View File

@@ -0,0 +1,10 @@
import "@module-federation/sdk";
//#region src/utils/env.ts
function getBuilderId() {
return typeof FEDERATION_BUILD_IDENTIFIER !== "undefined" ? FEDERATION_BUILD_IDENTIFIER : "";
}
//#endregion
export { getBuilderId };
//# sourceMappingURL=env.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"env.js","names":[],"sources":["../../src/utils/env.ts"],"sourcesContent":["export {\n isBrowserEnv,\n isBrowserEnvValue,\n isDebugMode,\n} from '@module-federation/sdk';\n\nexport function isDevelopmentMode(): boolean {\n return true;\n}\n\nexport function getBuilderId(): string {\n //@ts-ignore\n return typeof FEDERATION_BUILD_IDENTIFIER !== 'undefined'\n ? //@ts-ignore\n FEDERATION_BUILD_IDENTIFIER\n : '';\n}\n"],"mappings":";;;AAUA,SAAgB,eAAuB;AAErC,QAAO,OAAO,gCAAgC,cAE1C,8BACA"}

View File

@@ -0,0 +1,26 @@
const require_syncHook = require('./syncHook.cjs');
//#region src/utils/hooks/asyncHook.ts
var AsyncHook = class extends require_syncHook.SyncHook {
emit(...data) {
let result;
const ls = Array.from(this.listeners);
if (ls.length > 0) {
let i = 0;
const call = (prev) => {
if (prev === false) return false;
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;
};
result = call();
}
return Promise.resolve(result);
}
};
//#endregion
exports.AsyncHook = AsyncHook;
//# sourceMappingURL=asyncHook.cjs.map

View File

@@ -0,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?: 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"}

View File

@@ -0,0 +1,10 @@
import { ArgsType, SyncHook } from "./syncHook.js";
//#region src/utils/hooks/asyncHook.d.ts
type CallbackReturnType = void | false | Promise<void | false>;
declare class AsyncHook<T, ExternalEmitReturnType = CallbackReturnType> extends SyncHook<T, ExternalEmitReturnType> {
emit(...data: ArgsType<T>): Promise<void | false | ExternalEmitReturnType>;
}
//#endregion
export { AsyncHook };
//# sourceMappingURL=asyncHook.d.ts.map

View File

@@ -0,0 +1,26 @@
import { SyncHook } from "./syncHook.js";
//#region src/utils/hooks/asyncHook.ts
var AsyncHook = class extends SyncHook {
emit(...data) {
let result;
const ls = Array.from(this.listeners);
if (ls.length > 0) {
let i = 0;
const call = (prev) => {
if (prev === false) return false;
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;
};
result = call();
}
return Promise.resolve(result);
}
};
//#endregion
export { AsyncHook };
//# sourceMappingURL=asyncHook.js.map

View File

@@ -0,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?: 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"}

View File

@@ -0,0 +1,44 @@
const require_logger = require('../logger.cjs');
const require_tool = require('../tool.cjs');
const require_syncHook = require('./syncHook.cjs');
const require_syncWaterfallHook = require('./syncWaterfallHook.cjs');
//#region src/utils/hooks/asyncWaterfallHooks.ts
var AsyncWaterfallHook = class extends require_syncHook.SyncHook {
constructor(type) {
super();
this.onerror = require_logger.error;
this.type = type;
}
emit(data) {
if (!require_tool.isObject(data)) require_logger.error(`The response data for the "${this.type}" hook must be an object.`);
const ls = Array.from(this.listeners);
if (ls.length > 0) {
let i = 0;
const processError = (e) => {
require_logger.warn(e);
this.onerror(e);
return data;
};
const call = (prevData) => {
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;
};
return Promise.resolve(call(data));
}
return Promise.resolve(data);
}
};
//#endregion
exports.AsyncWaterfallHook = AsyncWaterfallHook;
//# sourceMappingURL=asyncWaterfallHooks.cjs.map

View File

@@ -0,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 | 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"}

View File

@@ -0,0 +1,12 @@
import { SyncHook } from "./syncHook.js";
//#region src/utils/hooks/asyncWaterfallHooks.d.ts
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;
constructor(type: string);
emit(data: T): Promise<T>;
}
//#endregion
export { AsyncWaterfallHook };
//# sourceMappingURL=asyncWaterfallHooks.d.ts.map

View File

@@ -0,0 +1,44 @@
import { error, warn } from "../logger.js";
import { isObject } from "../tool.js";
import { SyncHook } from "./syncHook.js";
import { checkReturnData } from "./syncWaterfallHook.js";
//#region src/utils/hooks/asyncWaterfallHooks.ts
var AsyncWaterfallHook = class extends SyncHook {
constructor(type) {
super();
this.onerror = error;
this.type = type;
}
emit(data) {
if (!isObject(data)) error(`The response data for the "${this.type}" hook must be an object.`);
const ls = Array.from(this.listeners);
if (ls.length > 0) {
let i = 0;
const processError = (e) => {
warn(e);
this.onerror(e);
return data;
};
const call = (prevData) => {
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;
};
return Promise.resolve(call(data));
}
return Promise.resolve(data);
}
};
//#endregion
export { AsyncWaterfallHook };
//# sourceMappingURL=asyncWaterfallHooks.js.map

View File

@@ -0,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 | 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"}

View File

@@ -0,0 +1,5 @@
const require_syncHook = require('./syncHook.cjs');
const require_asyncHook = require('./asyncHook.cjs');
const require_syncWaterfallHook = require('./syncWaterfallHook.cjs');
const require_asyncWaterfallHooks = require('./asyncWaterfallHooks.cjs');
const require_pluginSystem = require('./pluginSystem.cjs');

View File

@@ -0,0 +1,5 @@
import { SyncHook } from "./syncHook.js";
import { AsyncHook } from "./asyncHook.js";
import { SyncWaterfallHook } from "./syncWaterfallHook.js";
import { AsyncWaterfallHook } from "./asyncWaterfallHooks.js";
import { Plugin, PluginSystem } from "./pluginSystem.js";

View File

@@ -0,0 +1,7 @@
import { SyncHook } from "./syncHook.js";
import { AsyncHook } from "./asyncHook.js";
import { SyncWaterfallHook } from "./syncWaterfallHook.js";
import { AsyncWaterfallHook } from "./asyncWaterfallHooks.js";
import { PluginSystem } from "./pluginSystem.js";
export { };

View File

@@ -0,0 +1,37 @@
const require_logger = require('../logger.cjs');
const require_tool = require('../tool.cjs');
require('../index.cjs');
//#region src/utils/hooks/pluginSystem.ts
var PluginSystem = class {
constructor(lifecycle) {
this.registerPlugins = {};
this.lifecycle = lifecycle;
this.lifecycleKeys = Object.keys(lifecycle);
}
applyPlugin(plugin, instance) {
require_logger.assert(require_tool.isPlainObject(plugin), "Plugin configuration is invalid.");
const pluginName = plugin.name;
require_logger.assert(pluginName, "A name must be provided by the plugin.");
if (!this.registerPlugins[pluginName]) {
this.registerPlugins[pluginName] = plugin;
plugin.apply?.(instance);
Object.keys(this.lifecycle).forEach((key) => {
const pluginLife = plugin[key];
if (pluginLife) this.lifecycle[key].on(pluginLife);
});
}
}
removePlugin(pluginName) {
require_logger.assert(pluginName, "A name is required.");
const plugin = this.registerPlugins[pluginName];
require_logger.assert(plugin, `The plugin "${pluginName}" is not registered.`);
Object.keys(plugin).forEach((key) => {
if (key !== "name") this.lifecycle[key].remove(plugin[key]);
});
}
};
//#endregion
exports.PluginSystem = PluginSystem;
//# sourceMappingURL=pluginSystem.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"pluginSystem.cjs","names":["isPlainObject"],"sources":["../../../src/utils/hooks/pluginSystem.ts"],"sourcesContent":["import type { ModuleFederation } from '../../core';\nimport { assert, isPlainObject } from '../../utils';\n\nexport type Plugin<T extends Record<string, any>> = {\n [k in keyof T]?: Parameters<T[k]['on']>[0];\n} & {\n name: string;\n version?: string;\n apply?: (instance: ModuleFederation) => void;\n};\n\nexport class PluginSystem<T extends Record<string, any>> {\n lifecycle: T;\n lifecycleKeys: Array<keyof T>;\n registerPlugins: Record<string, Plugin<T>> = {};\n\n constructor(lifecycle: T) {\n this.lifecycle = lifecycle;\n this.lifecycleKeys = Object.keys(lifecycle);\n }\n\n applyPlugin(plugin: Plugin<T>, instance: ModuleFederation): void {\n assert(isPlainObject(plugin), 'Plugin configuration is invalid.');\n // The plugin's name is mandatory and must be unique\n const pluginName = plugin.name;\n assert(pluginName, 'A name must be provided by the plugin.');\n\n if (!this.registerPlugins[pluginName]) {\n this.registerPlugins[pluginName] = plugin;\n plugin.apply?.(instance);\n\n Object.keys(this.lifecycle).forEach((key) => {\n const pluginLife = plugin[key as string];\n if (pluginLife) {\n this.lifecycle[key].on(pluginLife);\n }\n });\n }\n }\n\n removePlugin(pluginName: string): void {\n assert(pluginName, 'A name is required.');\n const plugin = this.registerPlugins[pluginName];\n assert(plugin, `The plugin \"${pluginName}\" is not registered.`);\n\n Object.keys(plugin).forEach((key) => {\n if (key !== 'name') {\n this.lifecycle[key].remove(plugin[key as string]);\n }\n });\n }\n}\n"],"mappings":";;;;;AAWA,IAAa,eAAb,MAAyD;CAKvD,YAAY,WAAc;yBAFmB,EAAE;AAG7C,OAAK,YAAY;AACjB,OAAK,gBAAgB,OAAO,KAAK,UAAU;;CAG7C,YAAY,QAAmB,UAAkC;AAC/D,wBAAOA,2BAAc,OAAO,EAAE,mCAAmC;EAEjE,MAAM,aAAa,OAAO;AAC1B,wBAAO,YAAY,yCAAyC;AAE5D,MAAI,CAAC,KAAK,gBAAgB,aAAa;AACrC,QAAK,gBAAgB,cAAc;AACnC,UAAO,QAAQ,SAAS;AAExB,UAAO,KAAK,KAAK,UAAU,CAAC,SAAS,QAAQ;IAC3C,MAAM,aAAa,OAAO;AAC1B,QAAI,WACF,MAAK,UAAU,KAAK,GAAG,WAAW;KAEpC;;;CAIN,aAAa,YAA0B;AACrC,wBAAO,YAAY,sBAAsB;EACzC,MAAM,SAAS,KAAK,gBAAgB;AACpC,wBAAO,QAAQ,eAAe,WAAW,sBAAsB;AAE/D,SAAO,KAAK,OAAO,CAAC,SAAS,QAAQ;AACnC,OAAI,QAAQ,OACV,MAAK,UAAU,KAAK,OAAO,OAAO,KAAe;IAEnD"}

View File

@@ -0,0 +1,19 @@
import { ModuleFederation } from "../../core.js";
//#region src/utils/hooks/pluginSystem.d.ts
type Plugin<T extends Record<string, any>> = { [k in keyof T]?: Parameters<T[k]['on']>[0] } & {
name: string;
version?: string;
apply?: (instance: ModuleFederation) => void;
};
declare class PluginSystem<T extends Record<string, any>> {
lifecycle: T;
lifecycleKeys: Array<keyof T>;
registerPlugins: Record<string, Plugin<T>>;
constructor(lifecycle: T);
applyPlugin(plugin: Plugin<T>, instance: ModuleFederation): void;
removePlugin(pluginName: string): void;
}
//#endregion
export { PluginSystem };
//# sourceMappingURL=pluginSystem.d.ts.map

View File

@@ -0,0 +1,37 @@
import { assert } from "../logger.js";
import { isPlainObject } from "../tool.js";
import "../index.js";
//#region src/utils/hooks/pluginSystem.ts
var PluginSystem = class {
constructor(lifecycle) {
this.registerPlugins = {};
this.lifecycle = lifecycle;
this.lifecycleKeys = Object.keys(lifecycle);
}
applyPlugin(plugin, instance) {
assert(isPlainObject(plugin), "Plugin configuration is invalid.");
const pluginName = plugin.name;
assert(pluginName, "A name must be provided by the plugin.");
if (!this.registerPlugins[pluginName]) {
this.registerPlugins[pluginName] = plugin;
plugin.apply?.(instance);
Object.keys(this.lifecycle).forEach((key) => {
const pluginLife = plugin[key];
if (pluginLife) this.lifecycle[key].on(pluginLife);
});
}
}
removePlugin(pluginName) {
assert(pluginName, "A name is required.");
const plugin = this.registerPlugins[pluginName];
assert(plugin, `The plugin "${pluginName}" is not registered.`);
Object.keys(plugin).forEach((key) => {
if (key !== "name") this.lifecycle[key].remove(plugin[key]);
});
}
};
//#endregion
export { PluginSystem };
//# sourceMappingURL=pluginSystem.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"pluginSystem.js","names":[],"sources":["../../../src/utils/hooks/pluginSystem.ts"],"sourcesContent":["import type { ModuleFederation } from '../../core';\nimport { assert, isPlainObject } from '../../utils';\n\nexport type Plugin<T extends Record<string, any>> = {\n [k in keyof T]?: Parameters<T[k]['on']>[0];\n} & {\n name: string;\n version?: string;\n apply?: (instance: ModuleFederation) => void;\n};\n\nexport class PluginSystem<T extends Record<string, any>> {\n lifecycle: T;\n lifecycleKeys: Array<keyof T>;\n registerPlugins: Record<string, Plugin<T>> = {};\n\n constructor(lifecycle: T) {\n this.lifecycle = lifecycle;\n this.lifecycleKeys = Object.keys(lifecycle);\n }\n\n applyPlugin(plugin: Plugin<T>, instance: ModuleFederation): void {\n assert(isPlainObject(plugin), 'Plugin configuration is invalid.');\n // The plugin's name is mandatory and must be unique\n const pluginName = plugin.name;\n assert(pluginName, 'A name must be provided by the plugin.');\n\n if (!this.registerPlugins[pluginName]) {\n this.registerPlugins[pluginName] = plugin;\n plugin.apply?.(instance);\n\n Object.keys(this.lifecycle).forEach((key) => {\n const pluginLife = plugin[key as string];\n if (pluginLife) {\n this.lifecycle[key].on(pluginLife);\n }\n });\n }\n }\n\n removePlugin(pluginName: string): void {\n assert(pluginName, 'A name is required.');\n const plugin = this.registerPlugins[pluginName];\n assert(plugin, `The plugin \"${pluginName}\" is not registered.`);\n\n Object.keys(plugin).forEach((key) => {\n if (key !== 'name') {\n this.lifecycle[key].remove(plugin[key as string]);\n }\n });\n }\n}\n"],"mappings":";;;;;AAWA,IAAa,eAAb,MAAyD;CAKvD,YAAY,WAAc;yBAFmB,EAAE;AAG7C,OAAK,YAAY;AACjB,OAAK,gBAAgB,OAAO,KAAK,UAAU;;CAG7C,YAAY,QAAmB,UAAkC;AAC/D,SAAO,cAAc,OAAO,EAAE,mCAAmC;EAEjE,MAAM,aAAa,OAAO;AAC1B,SAAO,YAAY,yCAAyC;AAE5D,MAAI,CAAC,KAAK,gBAAgB,aAAa;AACrC,QAAK,gBAAgB,cAAc;AACnC,UAAO,QAAQ,SAAS;AAExB,UAAO,KAAK,KAAK,UAAU,CAAC,SAAS,QAAQ;IAC3C,MAAM,aAAa,OAAO;AAC1B,QAAI,WACF,MAAK,UAAU,KAAK,GAAG,WAAW;KAEpC;;;CAIN,aAAa,YAA0B;AACrC,SAAO,YAAY,sBAAsB;EACzC,MAAM,SAAS,KAAK,gBAAgB;AACpC,SAAO,QAAQ,eAAe,WAAW,sBAAsB;AAE/D,SAAO,KAAK,OAAO,CAAC,SAAS,QAAQ;AACnC,OAAI,QAAQ,OACV,MAAK,UAAU,KAAK,OAAO,OAAO,KAAe;IAEnD"}

View File

@@ -0,0 +1,37 @@
//#region src/utils/hooks/syncHook.ts
var SyncHook = class {
constructor(type) {
this.type = "";
this.listeners = /* @__PURE__ */ new Set();
if (type) this.type = type;
}
on(fn) {
if (typeof fn === "function") this.listeners.add(fn);
}
once(fn) {
const self = this;
this.on(function wrapper(...args) {
self.remove(wrapper);
return fn.apply(null, args);
});
}
emit(...data) {
let result;
if (this.listeners.size > 0) this.listeners.forEach((fn) => {
const nextResult = fn(...data);
if (nextResult !== void 0) result = nextResult;
});
return result;
}
remove(fn) {
this.listeners.delete(fn);
}
removeAll() {
this.listeners.clear();
}
};
//#endregion
exports.SyncHook = SyncHook;
//# sourceMappingURL=syncHook.cjs.map

View File

@@ -0,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 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"}

View File

@@ -0,0 +1,16 @@
//#region src/utils/hooks/syncHook.d.ts
type Callback<T, K> = (...args: ArgsType<T>) => K;
type ArgsType<T> = T extends Array<any> ? T : Array<any>;
declare class SyncHook<T, K> {
type: string;
listeners: Set<Callback<T, K>>;
constructor(type?: string);
on(fn: Callback<T, K>): void;
once(fn: Callback<T, K>): void;
emit(...data: ArgsType<T>): void | K | Promise<any>;
remove(fn: Callback<T, K>): void;
removeAll(): void;
}
//#endregion
export { ArgsType, SyncHook };
//# sourceMappingURL=syncHook.d.ts.map

View File

@@ -0,0 +1,36 @@
//#region src/utils/hooks/syncHook.ts
var SyncHook = class {
constructor(type) {
this.type = "";
this.listeners = /* @__PURE__ */ new Set();
if (type) this.type = type;
}
on(fn) {
if (typeof fn === "function") this.listeners.add(fn);
}
once(fn) {
const self = this;
this.on(function wrapper(...args) {
self.remove(wrapper);
return fn.apply(null, args);
});
}
emit(...data) {
let result;
if (this.listeners.size > 0) this.listeners.forEach((fn) => {
const nextResult = fn(...data);
if (nextResult !== void 0) result = nextResult;
});
return result;
}
remove(fn) {
this.listeners.delete(fn);
}
removeAll() {
this.listeners.clear();
}
};
//#endregion
export { SyncHook };
//# sourceMappingURL=syncHook.js.map

View File

@@ -0,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 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"}

View File

@@ -0,0 +1,40 @@
const require_logger = require('../logger.cjs');
const require_tool = require('../tool.cjs');
const require_syncHook = require('./syncHook.cjs');
//#region src/utils/hooks/syncWaterfallHook.ts
function checkReturnData(originalData, returnedData) {
if (!require_tool.isObject(returnedData)) return false;
if (originalData !== returnedData) {
for (const key in originalData) if (!(key in returnedData)) return false;
}
return true;
}
var SyncWaterfallHook = class extends require_syncHook.SyncHook {
constructor(type) {
super();
this.onerror = require_logger.error;
this.type = type;
}
emit(data) {
if (!require_tool.isObject(data)) require_logger.error(`The data for the "${this.type}" hook should be an object.`);
for (const fn of this.listeners) try {
const tempData = fn(data);
if (tempData === void 0) continue;
if (checkReturnData(data, tempData)) data = tempData;
else {
this.onerror(`A plugin returned an unacceptable value for the "${this.type}" type.`);
break;
}
} catch (e) {
require_logger.warn(e);
this.onerror(e);
}
return data;
}
};
//#endregion
exports.SyncWaterfallHook = SyncWaterfallHook;
exports.checkReturnData = checkReturnData;
//# sourceMappingURL=syncWaterfallHook.cjs.map

Some files were not shown because too many files have changed in this diff Show More