@module-federation/runtime 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
- import { g as getGlobalHostPlugins, a as globalLoading, D as DEFAULT_REMOTE_TYPE, b as DEFAULT_SCOPE, c as getRemoteEntryExports, d as assert, s as safeToString, e as getFMId, i as isObject, f as error, w as warn, h as isPlainObject, j as isRemoteInfoWithEntry, k as isPureRemoteEntry, l as getInfoWithoutType, m as getPreloaded, n as setPreloaded, o as getRegisteredShare, p as arrayOptions, q as getGlobalSnapshotInfoByModuleInfo, r as addGlobalSnapshot, t as setGlobalSnapshotInfoByModuleInfo, u as getGlobalSnapshot, G as Global, v as getGlobalShareScope, x as getTargetSharedOptions, y as formatShareConfigs, z as getBuilderId, A as isBrowserEnv, B as addUniqueItem, C as setGlobalFederationConstructor, E as getGlobalFederationInstance, F as getGlobalFederationConstructor, H as setGlobalFederationInstance } from './share.esm.js';
1
+ import { g as getGlobalHostPlugins, a as globalLoading, D as DEFAULT_REMOTE_TYPE, b as DEFAULT_SCOPE, c as getRemoteEntryExports, d as assert, s as safeToString, e as getFMId, i as isObject, f as error, w as warn, h as isPlainObject, j as isRemoteInfoWithEntry, k as isPureRemoteEntry, l as getInfoWithoutType, m as getPreloaded, n as setPreloaded, o as getRegisteredShare, p as arrayOptions, q as getGlobalSnapshotInfoByModuleInfo, r as addGlobalSnapshot, t as setGlobalSnapshotInfoByModuleInfo, u as getGlobalSnapshot, G as Global, v as formatShareConfigs, x as getTargetSharedOptions, y as getGlobalShareScope, z as addUniqueItem, A as getBuilderId, B as isBrowserEnv$1, C as setGlobalFederationConstructor, E as getGlobalFederationInstance, F as getGlobalFederationConstructor, H as setGlobalFederationInstance } from './share.esm.js';
2
2
  export { I as registerGlobalPlugins } from './share.esm.js';
3
- import { loadScriptNode, loadScript, composeKeyWithSeparator, createLink, getResourceUrl, isManifestProvider, generateSnapshotFromManifest } from '@module-federation/sdk';
3
+ import { loadScriptNode, loadScript, composeKeyWithSeparator, createLink, getResourceUrl, isManifestProvider, generateSnapshotFromManifest, warn as warn$1, isBrowserEnv } from '@module-federation/sdk';
4
4
  export { loadScript, loadScriptNode } from '@module-federation/sdk';
5
5
 
6
6
  // Function to match a remote with its name and expose
@@ -87,8 +87,8 @@ function registerPlugins$1(plugins, hookInstances) {
87
87
  return plugins;
88
88
  }
89
89
 
90
- function _extends$5() {
91
- _extends$5 = Object.assign || function(target) {
90
+ function _extends$7() {
91
+ _extends$7 = Object.assign || function(target) {
92
92
  for(var i = 1; i < arguments.length; i++){
93
93
  var source = arguments[i];
94
94
  for(var key in source){
@@ -99,7 +99,7 @@ function _extends$5() {
99
99
  }
100
100
  return target;
101
101
  };
102
- return _extends$5.apply(this, arguments);
102
+ return _extends$7.apply(this, arguments);
103
103
  }
104
104
  async function loadEsmEntry({ entry, remoteEntryExports }) {
105
105
  return new Promise((resolve, reject)=>{
@@ -187,7 +187,7 @@ async function getRemoteEntry({ remoteEntryExports, remoteInfo, createScriptHook
187
187
  return globalLoading[uniqueKey];
188
188
  }
189
189
  function getRemoteInfo(remote) {
190
- return _extends$5({}, remote, {
190
+ return _extends$7({}, remote, {
191
191
  entry: 'entry' in remote ? remote.entry : '',
192
192
  type: remote.type || DEFAULT_REMOTE_TYPE,
193
193
  entryGlobalName: remote.entryGlobalName || remote.name,
@@ -195,8 +195,8 @@ function getRemoteInfo(remote) {
195
195
  });
196
196
  }
197
197
 
198
- function _extends$4() {
199
- _extends$4 = Object.assign || function(target) {
198
+ function _extends$6() {
199
+ _extends$6 = Object.assign || function(target) {
200
200
  for(var i = 1; i < arguments.length; i++){
201
201
  var source = arguments[i];
202
202
  for(var key in source){
@@ -207,7 +207,7 @@ function _extends$4() {
207
207
  }
208
208
  return target;
209
209
  };
210
- return _extends$4.apply(this, arguments);
210
+ return _extends$6.apply(this, arguments);
211
211
  }
212
212
  let Module = class Module {
213
213
  async getEntry() {
@@ -269,7 +269,7 @@ let Module = class Module {
269
269
  origin: this.host
270
270
  });
271
271
  await remoteEntryExports.init(initContainerOptions.shareScope, initContainerOptions.initScope, initContainerOptions.remoteEntryInitOptions);
272
- await this.host.hooks.lifecycle.initContainer.emit(_extends$4({}, initContainerOptions, {
272
+ await this.host.hooks.lifecycle.initContainer.emit(_extends$6({}, initContainerOptions, {
273
273
  remoteEntryExports
274
274
  }));
275
275
  }
@@ -479,8 +479,8 @@ class PluginSystem {
479
479
  }
480
480
  }
481
481
 
482
- function _extends$3() {
483
- _extends$3 = Object.assign || function(target) {
482
+ function _extends$5() {
483
+ _extends$5 = Object.assign || function(target) {
484
484
  for(var i = 1; i < arguments.length; i++){
485
485
  var source = arguments[i];
486
486
  for(var key in source){
@@ -491,10 +491,10 @@ function _extends$3() {
491
491
  }
492
492
  return target;
493
493
  };
494
- return _extends$3.apply(this, arguments);
494
+ return _extends$5.apply(this, arguments);
495
495
  }
496
496
  function defaultPreloadArgs(preloadConfig) {
497
- return _extends$3({
497
+ return _extends$5({
498
498
  resourceCategory: 'sync',
499
499
  share: true,
500
500
  depsRemote: true,
@@ -601,8 +601,8 @@ function preloadAssets(remoteInfo, host, assets) {
601
601
  }
602
602
  }
603
603
 
604
- function _extends$2() {
605
- _extends$2 = Object.assign || function(target) {
604
+ function _extends$4() {
605
+ _extends$4 = Object.assign || function(target) {
606
606
  for(var i = 1; i < arguments.length; i++){
607
607
  var source = arguments[i];
608
608
  for(var key in source){
@@ -613,7 +613,7 @@ function _extends$2() {
613
613
  }
614
614
  return target;
615
615
  };
616
- return _extends$2.apply(this, arguments);
616
+ return _extends$4.apply(this, arguments);
617
617
  }
618
618
  function assignRemoteInfo(remoteInfo, remoteSnapshot) {
619
619
  if (!('remoteEntry' in remoteSnapshot) || !remoteSnapshot.remoteEntry) {
@@ -648,7 +648,7 @@ function snapshotPlugin() {
648
648
  depsRemote: false
649
649
  }
650
650
  };
651
- const assets = await origin.hooks.lifecycle.generatePreloadAssets.emit({
651
+ const assets = await origin.remoteHandler.hooks.lifecycle.generatePreloadAssets.emit({
652
652
  origin,
653
653
  preloadOptions,
654
654
  remoteInfo,
@@ -659,7 +659,7 @@ function snapshotPlugin() {
659
659
  if (assets) {
660
660
  preloadAssets(remoteInfo, origin, assets);
661
661
  }
662
- return _extends$2({}, args, {
662
+ return _extends$4({}, args, {
663
663
  remoteSnapshot
664
664
  });
665
665
  }
@@ -785,7 +785,7 @@ function generatePreloadAssets(origin, preloadOptions, remote, globalSnapshot, r
785
785
  for(let index = 0; index < assetsLength; index++){
786
786
  const assetsInfo = moduleAssetsInfo[index];
787
787
  const exposeFullPath = `${remoteInfo.name}/${assetsInfo.moduleName}`;
788
- origin.hooks.lifecycle.handlePreloadModule.emit({
788
+ origin.remoteHandler.hooks.lifecycle.handlePreloadModule.emit({
789
789
  id: assetsInfo.moduleName === '.' ? remoteInfo.name : exposeFullPath,
790
790
  name: remoteInfo.name,
791
791
  remoteSnapshot: moduleInfoSnapshot,
@@ -813,7 +813,7 @@ function generatePreloadAssets(origin, preloadOptions, remote, globalSnapshot, r
813
813
  }, true, memo, remoteSnapshot);
814
814
  if (remoteSnapshot.shared) {
815
815
  const collectSharedAssets = (shareInfo, snapshotShared)=>{
816
- const registeredShared = getRegisteredShare(origin.shareScopeMap, snapshotShared.sharedName, shareInfo, origin.hooks.lifecycle.resolveShare);
816
+ const registeredShared = getRegisteredShare(origin.shareScopeMap, snapshotShared.sharedName, shareInfo, origin.sharedHandler.hooks.lifecycle.resolveShare);
817
817
  // If the global share does not exist, or the lib function does not exist, it means that the shared has not been loaded yet and can be preloaded.
818
818
  if (registeredShared && typeof registeredShared.lib === 'function') {
819
819
  snapshotShared.assets.js.sync.forEach((asset)=>{
@@ -880,8 +880,8 @@ const generatePreloadAssetsPlugin = function() {
880
880
  };
881
881
  };
882
882
 
883
- function _extends$1() {
884
- _extends$1 = Object.assign || function(target) {
883
+ function _extends$3() {
884
+ _extends$3 = Object.assign || function(target) {
885
885
  for(var i = 1; i < arguments.length; i++){
886
886
  var source = arguments[i];
887
887
  for(var key in source){
@@ -892,7 +892,7 @@ function _extends$1() {
892
892
  }
893
893
  return target;
894
894
  };
895
- return _extends$1.apply(this, arguments);
895
+ return _extends$3.apply(this, arguments);
896
896
  }
897
897
  class SnapshotHandler {
898
898
  async loadSnapshot(moduleInfo) {
@@ -935,7 +935,7 @@ class SnapshotHandler {
935
935
  // This ensures the snapshot's integrity and helps the chrome plugin correctly identify all producer modules, ensuring that proxyable producer modules will not be missing.
936
936
  if (hostSnapshot && 'remotesInfo' in hostSnapshot && !getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name).value) {
937
937
  if ('version' in moduleInfo || 'entry' in moduleInfo) {
938
- hostSnapshot.remotesInfo = _extends$1({}, hostSnapshot == null ? void 0 : hostSnapshot.remotesInfo, {
938
+ hostSnapshot.remotesInfo = _extends$3({}, hostSnapshot == null ? void 0 : hostSnapshot.remotesInfo, {
939
939
  [moduleInfo.name]: {
940
940
  matchedVersion: 'version' in moduleInfo ? moduleInfo.version : moduleInfo.entry
941
941
  }
@@ -955,7 +955,7 @@ class SnapshotHandler {
955
955
  if (isManifestProvider(globalRemoteSnapshot)) {
956
956
  const moduleSnapshot = await this.getManifestJson(globalRemoteSnapshot.remoteEntry, moduleInfo, {});
957
957
  // eslint-disable-next-line @typescript-eslint/no-shadow
958
- const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(_extends$1({}, moduleInfo, {
958
+ const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(_extends$3({}, moduleInfo, {
959
959
  // The global remote may be overridden
960
960
  // Therefore, set the snapshot key to the global address of the actual request
961
961
  entry: globalRemoteSnapshot.remoteEntry
@@ -1083,8 +1083,8 @@ class SnapshotHandler {
1083
1083
  }
1084
1084
  }
1085
1085
 
1086
- function _extends() {
1087
- _extends = Object.assign || function(target) {
1086
+ function _extends$2() {
1087
+ _extends$2 = Object.assign || function(target) {
1088
1088
  for(var i = 1; i < arguments.length; i++){
1089
1089
  var source = arguments[i];
1090
1090
  for(var key in source){
@@ -1095,7 +1095,7 @@ function _extends() {
1095
1095
  }
1096
1096
  return target;
1097
1097
  };
1098
- return _extends.apply(this, arguments);
1098
+ return _extends$2.apply(this, arguments);
1099
1099
  }
1100
1100
  function _object_without_properties_loose(source, excluded) {
1101
1101
  if (source == null) return {};
@@ -1109,21 +1109,34 @@ function _object_without_properties_loose(source, excluded) {
1109
1109
  }
1110
1110
  return target;
1111
1111
  }
1112
- class FederationHost {
1113
- _setGlobalShareScopeMap() {
1114
- const globalShareScopeMap = getGlobalShareScope();
1115
- const identifier = this.options.id || this.options.name;
1116
- if (identifier && !globalShareScopeMap[identifier]) {
1117
- globalShareScopeMap[identifier] = this.shareScopeMap;
1118
- }
1119
- }
1120
- initOptions(userOptions) {
1121
- this.registerPlugins(userOptions.plugins);
1122
- const options = this.formatOptions(this.options, userOptions);
1123
- this.options = options;
1124
- return options;
1112
+ class SharedHandler {
1113
+ // register shared in shareScopeMap
1114
+ registerShared(globalOptions, userOptions) {
1115
+ const { shareInfos, shared } = formatShareConfigs(globalOptions, userOptions);
1116
+ const sharedKeys = Object.keys(shareInfos);
1117
+ sharedKeys.forEach((sharedKey)=>{
1118
+ const sharedVals = shareInfos[sharedKey];
1119
+ sharedVals.forEach((sharedVal)=>{
1120
+ const registeredShared = getRegisteredShare(this.shareScopeMap, sharedKey, sharedVal, this.hooks.lifecycle.resolveShare);
1121
+ if (!registeredShared && sharedVal && sharedVal.lib) {
1122
+ this.setShared({
1123
+ pkgName: sharedKey,
1124
+ lib: sharedVal.lib,
1125
+ get: sharedVal.get,
1126
+ loaded: true,
1127
+ shared: sharedVal,
1128
+ from: userOptions.name
1129
+ });
1130
+ }
1131
+ });
1132
+ });
1133
+ return {
1134
+ shareInfos,
1135
+ shared
1136
+ };
1125
1137
  }
1126
1138
  async loadShare(pkgName, extraOptions) {
1139
+ const { host } = this;
1127
1140
  // This function performs the following steps:
1128
1141
  // 1. Checks if the currently loaded share already exists, if not, it throws an error
1129
1142
  // 2. Searches globally for a matching share, if found, it uses it directly
@@ -1131,7 +1144,7 @@ class FederationHost {
1131
1144
  const shareInfo = getTargetSharedOptions({
1132
1145
  pkgName,
1133
1146
  extraOptions,
1134
- shareInfos: this.options.shared
1147
+ shareInfos: host.options.shared
1135
1148
  });
1136
1149
  if (shareInfo == null ? void 0 : shareInfo.scope) {
1137
1150
  await Promise.all(shareInfo.scope.map(async (shareScope)=>{
@@ -1142,19 +1155,19 @@ class FederationHost {
1142
1155
  const loadShareRes = await this.hooks.lifecycle.beforeLoadShare.emit({
1143
1156
  pkgName,
1144
1157
  shareInfo,
1145
- shared: this.options.shared,
1146
- origin: this
1158
+ shared: host.options.shared,
1159
+ origin: host
1147
1160
  });
1148
1161
  const { shareInfo: shareInfoRes } = loadShareRes;
1149
1162
  // Assert that shareInfoRes exists, if not, throw an error
1150
- assert(shareInfoRes, `Cannot find ${pkgName} Share in the ${this.options.name}. Please ensure that the ${pkgName} Share parameters have been injected`);
1163
+ assert(shareInfoRes, `Cannot find ${pkgName} Share in the ${host.options.name}. Please ensure that the ${pkgName} Share parameters have been injected`);
1151
1164
  // Retrieve from cache
1152
1165
  const registeredShared = getRegisteredShare(this.shareScopeMap, pkgName, shareInfoRes, this.hooks.lifecycle.resolveShare);
1153
1166
  const addUseIn = (shared)=>{
1154
1167
  if (!shared.useIn) {
1155
1168
  shared.useIn = [];
1156
1169
  }
1157
- addUniqueItem(shared.useIn, this.options.name);
1170
+ addUniqueItem(shared.useIn, host.options.name);
1158
1171
  };
1159
1172
  if (registeredShared && registeredShared.lib) {
1160
1173
  addUseIn(registeredShared);
@@ -1185,7 +1198,7 @@ class FederationHost {
1185
1198
  pkgName,
1186
1199
  loaded: false,
1187
1200
  shared: registeredShared,
1188
- from: this.options.name,
1201
+ from: host.options.name,
1189
1202
  lib: null,
1190
1203
  loading
1191
1204
  });
@@ -1211,22 +1224,80 @@ class FederationHost {
1211
1224
  pkgName,
1212
1225
  loaded: false,
1213
1226
  shared: shareInfoRes,
1214
- from: this.options.name,
1227
+ from: host.options.name,
1215
1228
  lib: null,
1216
1229
  loading
1217
1230
  });
1218
1231
  return loading;
1219
1232
  }
1220
1233
  }
1234
+ /**
1235
+ * This function initializes the sharing sequence (executed only once per share scope).
1236
+ * It accepts one argument, the name of the share scope.
1237
+ * If the share scope does not exist, it creates one.
1238
+ */ // eslint-disable-next-line @typescript-eslint/member-ordering
1239
+ initializeSharing(shareScopeName = DEFAULT_SCOPE, strategy) {
1240
+ const { host } = this;
1241
+ const shareScope = this.shareScopeMap;
1242
+ const hostName = host.options.name;
1243
+ // Creates a new share scope if necessary
1244
+ if (!shareScope[shareScopeName]) {
1245
+ shareScope[shareScopeName] = {};
1246
+ }
1247
+ // Executes all initialization snippets from all accessible modules
1248
+ const scope = shareScope[shareScopeName];
1249
+ const register = (name, shared)=>{
1250
+ var _activeVersion_shareConfig;
1251
+ const { version, eager } = shared;
1252
+ scope[name] = scope[name] || {};
1253
+ const versions = scope[name];
1254
+ const activeVersion = versions[version];
1255
+ const activeVersionEager = Boolean(activeVersion && (activeVersion.eager || ((_activeVersion_shareConfig = activeVersion.shareConfig) == null ? void 0 : _activeVersion_shareConfig.eager)));
1256
+ if (!activeVersion || activeVersion.strategy !== 'loaded-first' && !activeVersion.loaded && (Boolean(!eager) !== !activeVersionEager ? eager : hostName > activeVersion.from)) {
1257
+ versions[version] = shared;
1258
+ }
1259
+ };
1260
+ const promises = [];
1261
+ const initFn = (mod)=>mod && mod.init && mod.init(shareScope[shareScopeName]);
1262
+ const initRemoteModule = async (key)=>{
1263
+ const { module } = await host.remoteHandler.getRemoteModuleAndOptions({
1264
+ id: key
1265
+ });
1266
+ if (module.getEntry) {
1267
+ const entry = await module.getEntry();
1268
+ if (!module.inited) {
1269
+ initFn(entry);
1270
+ module.inited = true;
1271
+ }
1272
+ }
1273
+ };
1274
+ Object.keys(host.options.shared).forEach((shareName)=>{
1275
+ const sharedArr = host.options.shared[shareName];
1276
+ sharedArr.forEach((shared)=>{
1277
+ if (shared.scope.includes(shareScopeName)) {
1278
+ register(shareName, shared);
1279
+ }
1280
+ });
1281
+ });
1282
+ if (strategy === 'version-first') {
1283
+ host.options.remotes.forEach((remote)=>{
1284
+ if (remote.shareScope === shareScopeName) {
1285
+ promises.push(initRemoteModule(remote.name));
1286
+ }
1287
+ });
1288
+ }
1289
+ return promises;
1290
+ }
1221
1291
  // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.
1222
1292
  // 1. If the loaded shared already exists globally, then it will be reused
1223
1293
  // 2. If lib exists in local shared, it will be used directly
1224
1294
  // 3. If the local get returns something other than Promise, then it will be used directly
1225
1295
  loadShareSync(pkgName, extraOptions) {
1296
+ const { host } = this;
1226
1297
  const shareInfo = getTargetSharedOptions({
1227
1298
  pkgName,
1228
1299
  extraOptions,
1229
- shareInfos: this.options.shared
1300
+ shareInfos: host.options.shared
1230
1301
  });
1231
1302
  if (shareInfo == null ? void 0 : shareInfo.scope) {
1232
1303
  shareInfo.scope.forEach((shareScope)=>{
@@ -1238,14 +1309,14 @@ class FederationHost {
1238
1309
  if (!shared.useIn) {
1239
1310
  shared.useIn = [];
1240
1311
  }
1241
- addUniqueItem(shared.useIn, this.options.name);
1312
+ addUniqueItem(shared.useIn, host.options.name);
1242
1313
  };
1243
1314
  if (registeredShared) {
1244
1315
  if (typeof registeredShared.lib === 'function') {
1245
1316
  addUseIn(registeredShared);
1246
1317
  if (!registeredShared.loaded) {
1247
1318
  registeredShared.loaded = true;
1248
- if (registeredShared.from === this.options.name) {
1319
+ if (registeredShared.from === host.options.name) {
1249
1320
  shareInfo.loaded = true;
1250
1321
  }
1251
1322
  }
@@ -1258,7 +1329,7 @@ class FederationHost {
1258
1329
  this.setShared({
1259
1330
  pkgName,
1260
1331
  loaded: true,
1261
- from: this.options.name,
1332
+ from: host.options.name,
1262
1333
  lib: module,
1263
1334
  shared: registeredShared
1264
1335
  });
@@ -1276,7 +1347,7 @@ class FederationHost {
1276
1347
  const module = shareInfo.get();
1277
1348
  if (module instanceof Promise) {
1278
1349
  throw new Error(`
1279
- The loadShareSync function was unable to load ${pkgName}. The ${pkgName} could not be found in ${this.options.name}.
1350
+ The loadShareSync function was unable to load ${pkgName}. The ${pkgName} could not be found in ${host.options.name}.
1280
1351
  Possible reasons for failure: \n
1281
1352
  1. The ${pkgName} share was registered with the 'get' attribute, but loadShare was not used beforehand.\n
1282
1353
  2. The ${pkgName} share was not registered with the 'lib' attribute.\n
@@ -1286,92 +1357,112 @@ class FederationHost {
1286
1357
  this.setShared({
1287
1358
  pkgName,
1288
1359
  loaded: true,
1289
- from: this.options.name,
1360
+ from: host.options.name,
1290
1361
  lib: shareInfo.lib,
1291
1362
  shared: shareInfo
1292
1363
  });
1293
1364
  return shareInfo.lib;
1294
1365
  }
1295
1366
  throw new Error(`
1296
- The loadShareSync function was unable to load ${pkgName}. The ${pkgName} could not be found in ${this.options.name}.
1367
+ The loadShareSync function was unable to load ${pkgName}. The ${pkgName} could not be found in ${host.options.name}.
1297
1368
  Possible reasons for failure: \n
1298
1369
  1. The ${pkgName} share was registered with the 'get' attribute, but loadShare was not used beforehand.\n
1299
1370
  2. The ${pkgName} share was not registered with the 'lib' attribute.\n
1300
1371
  `);
1301
1372
  }
1302
- initRawContainer(name, url, container) {
1303
- const remoteInfo = getRemoteInfo({
1304
- name,
1305
- entry: url
1306
- });
1307
- const module = new Module({
1308
- host: this,
1309
- remoteInfo
1373
+ initShareScopeMap(scopeName, shareScope) {
1374
+ const { host } = this;
1375
+ this.shareScopeMap[scopeName] = shareScope;
1376
+ this.hooks.lifecycle.initContainerShareScopeMap.emit({
1377
+ shareScope,
1378
+ options: host.options,
1379
+ origin: host
1310
1380
  });
1311
- module.remoteEntryExports = container;
1312
- this.moduleCache.set(name, module);
1313
- return module;
1314
1381
  }
1315
- async _getRemoteModuleAndOptions(id) {
1316
- let loadRemoteArgs;
1317
- try {
1318
- loadRemoteArgs = await this.hooks.lifecycle.beforeRequest.emit({
1319
- id,
1320
- options: this.options,
1321
- origin: this
1322
- });
1323
- } catch (error) {
1324
- loadRemoteArgs = await this.hooks.lifecycle.errorLoadRemote.emit({
1325
- id,
1326
- options: this.options,
1327
- origin: this,
1328
- from: 'runtime',
1329
- error,
1330
- lifecycle: 'beforeRequest'
1382
+ setShared({ pkgName, shared, from, lib, loading, loaded, get }) {
1383
+ const { version, scope = 'default' } = shared, shareInfo = _object_without_properties_loose(shared, [
1384
+ "version",
1385
+ "scope"
1386
+ ]);
1387
+ const scopes = Array.isArray(scope) ? scope : [
1388
+ scope
1389
+ ];
1390
+ scopes.forEach((sc)=>{
1391
+ if (!this.shareScopeMap[sc]) {
1392
+ this.shareScopeMap[sc] = {};
1393
+ }
1394
+ if (!this.shareScopeMap[sc][pkgName]) {
1395
+ this.shareScopeMap[sc][pkgName] = {};
1396
+ }
1397
+ if (this.shareScopeMap[sc][pkgName][version]) {
1398
+ return;
1399
+ }
1400
+ this.shareScopeMap[sc][pkgName][version] = _extends$2({
1401
+ version,
1402
+ scope: [
1403
+ 'default'
1404
+ ]
1405
+ }, shareInfo, {
1406
+ lib,
1407
+ loaded,
1408
+ loading
1331
1409
  });
1332
- if (!loadRemoteArgs) {
1333
- throw error;
1410
+ if (get) {
1411
+ this.shareScopeMap[sc][pkgName][version].get = get;
1334
1412
  }
1413
+ });
1414
+ }
1415
+ _setGlobalShareScopeMap(hostOptions) {
1416
+ const globalShareScopeMap = getGlobalShareScope();
1417
+ const identifier = hostOptions.id || hostOptions.name;
1418
+ if (identifier && !globalShareScopeMap[identifier]) {
1419
+ globalShareScopeMap[identifier] = this.shareScopeMap;
1335
1420
  }
1336
- const { id: idRes } = loadRemoteArgs;
1337
- const remoteSplitInfo = matchRemoteWithNameAndExpose(this.options.remotes, idRes);
1338
- assert(remoteSplitInfo, `
1339
- Unable to locate ${idRes} in ${this.options.name}. Potential reasons for failure include:\n
1340
- 1. ${idRes} was not included in the 'remotes' parameter of ${this.options.name || 'the host'}.\n
1341
- 2. ${idRes} could not be found in the 'remotes' of ${this.options.name} with either 'name' or 'alias' attributes.
1342
- 3. ${idRes} is not online, injected, or loaded.
1343
- 4. ${idRes} cannot be accessed on the expected.
1344
- 5. The 'beforeRequest' hook was provided but did not return the correct 'remoteInfo' when attempting to load ${idRes}.
1345
- `);
1346
- const { remote: rawRemote } = remoteSplitInfo;
1347
- const remoteInfo = getRemoteInfo(rawRemote);
1348
- const matchInfo = await this.hooks.lifecycle.afterResolve.emit(_extends({
1349
- id: idRes
1350
- }, remoteSplitInfo, {
1351
- options: this.options,
1352
- origin: this,
1353
- remoteInfo
1354
- }));
1355
- const { remote, expose } = matchInfo;
1356
- assert(remote && expose, `The 'beforeRequest' hook was executed, but it failed to return the correct 'remote' and 'expose' values while loading ${idRes}.`);
1357
- let module = this.moduleCache.get(remote.name);
1358
- const moduleOptions = {
1359
- host: this,
1360
- remoteInfo
1361
- };
1362
- if (!module) {
1363
- module = new Module(moduleOptions);
1364
- this.moduleCache.set(remote.name, module);
1421
+ }
1422
+ constructor(host){
1423
+ this.hooks = new PluginSystem({
1424
+ afterResolve: new AsyncWaterfallHook('afterResolve'),
1425
+ beforeLoadShare: new AsyncWaterfallHook('beforeLoadShare'),
1426
+ // not used yet
1427
+ loadShare: new AsyncHook(),
1428
+ resolveShare: new SyncWaterfallHook('resolveShare'),
1429
+ // maybe will change, temporarily for internal use only
1430
+ initContainerShareScopeMap: new AsyncWaterfallHook('initContainer')
1431
+ });
1432
+ this.host = host;
1433
+ this.shareScopeMap = {};
1434
+ this._setGlobalShareScopeMap(host.options);
1435
+ }
1436
+ }
1437
+
1438
+ function _extends$1() {
1439
+ _extends$1 = Object.assign || function(target) {
1440
+ for(var i = 1; i < arguments.length; i++){
1441
+ var source = arguments[i];
1442
+ for(var key in source){
1443
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1444
+ target[key] = source[key];
1445
+ }
1446
+ }
1365
1447
  }
1366
- return {
1367
- module,
1368
- moduleOptions,
1369
- remoteMatchInfo: matchInfo
1370
- };
1448
+ return target;
1449
+ };
1450
+ return _extends$1.apply(this, arguments);
1451
+ }
1452
+ class RemoteHandler {
1453
+ formatAndRegisterRemote(globalOptions, userOptions) {
1454
+ const userRemotes = userOptions.remotes || [];
1455
+ return userRemotes.reduce((res, remote)=>{
1456
+ this.registerRemote(remote, res, {
1457
+ force: false
1458
+ });
1459
+ return res;
1460
+ }, globalOptions.remotes);
1371
1461
  }
1372
1462
  // eslint-disable-next-line max-lines-per-function
1373
1463
  // eslint-disable-next-line @typescript-eslint/member-ordering
1374
1464
  async loadRemote(id, options) {
1465
+ const { host } = this;
1375
1466
  try {
1376
1467
  const { loadFactory = true } = options || {
1377
1468
  loadFactory: true
@@ -1383,7 +1474,9 @@ class FederationHost {
1383
1474
  // id: pkgName(@federation/app1) + expose(button) = @federation/app1/button
1384
1475
  // id: alias(app1) + expose(button) = app1/button
1385
1476
  // id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort
1386
- const { module, moduleOptions, remoteMatchInfo } = await this._getRemoteModuleAndOptions(id);
1477
+ const { module, moduleOptions, remoteMatchInfo } = await this.getRemoteModuleAndOptions({
1478
+ id
1479
+ });
1387
1480
  const { pkgNameOrAlias, remote, expose, id: idRes } = remoteMatchInfo;
1388
1481
  const moduleOrFactory = await module.get(expose, options);
1389
1482
  const moduleWrapper = await this.hooks.lifecycle.onLoad.emit({
@@ -1395,7 +1488,7 @@ class FederationHost {
1395
1488
  remote,
1396
1489
  options: moduleOptions,
1397
1490
  moduleInstance: module,
1398
- origin: this
1491
+ origin: host
1399
1492
  });
1400
1493
  if (typeof moduleWrapper === 'function') {
1401
1494
  return moduleWrapper;
@@ -1410,7 +1503,7 @@ class FederationHost {
1410
1503
  error,
1411
1504
  from,
1412
1505
  lifecycle: 'onLoad',
1413
- origin: this
1506
+ origin: host
1414
1507
  });
1415
1508
  if (!failOver) {
1416
1509
  throw error;
@@ -1420,18 +1513,19 @@ class FederationHost {
1420
1513
  }
1421
1514
  // eslint-disable-next-line @typescript-eslint/member-ordering
1422
1515
  async preloadRemote(preloadOptions) {
1516
+ const { host } = this;
1423
1517
  await this.hooks.lifecycle.beforePreloadRemote.emit({
1424
1518
  preloadOptions,
1425
- options: this.options,
1426
- origin: this
1519
+ options: host.options,
1520
+ origin: host
1427
1521
  });
1428
- const preloadOps = formatPreloadArgs(this.options.remotes, preloadOptions);
1522
+ const preloadOps = formatPreloadArgs(host.options.remotes, preloadOptions);
1429
1523
  await Promise.all(preloadOps.map(async (ops)=>{
1430
1524
  const { remote } = ops;
1431
1525
  const remoteInfo = getRemoteInfo(remote);
1432
- const { globalSnapshot, remoteSnapshot } = await this.snapshotHandler.loadRemoteSnapshotInfo(remote);
1526
+ const { globalSnapshot, remoteSnapshot } = await host.snapshotHandler.loadRemoteSnapshotInfo(remote);
1433
1527
  const assets = await this.hooks.lifecycle.generatePreloadAssets.emit({
1434
- origin: this,
1528
+ origin: host,
1435
1529
  preloadOptions: ops,
1436
1530
  remote,
1437
1531
  remoteInfo,
@@ -1441,117 +1535,279 @@ class FederationHost {
1441
1535
  if (!assets) {
1442
1536
  return;
1443
1537
  }
1444
- preloadAssets(remoteInfo, this, assets);
1538
+ preloadAssets(remoteInfo, host, assets);
1445
1539
  }));
1446
1540
  }
1447
- /**
1448
- * This function initializes the sharing sequence (executed only once per share scope).
1449
- * It accepts one argument, the name of the share scope.
1450
- * If the share scope does not exist, it creates one.
1451
- */ // eslint-disable-next-line @typescript-eslint/member-ordering
1452
- initializeSharing(shareScopeName = DEFAULT_SCOPE, strategy) {
1453
- const shareScope = this.shareScopeMap;
1454
- const hostName = this.options.name;
1455
- // Creates a new share scope if necessary
1456
- if (!shareScope[shareScopeName]) {
1457
- shareScope[shareScopeName] = {};
1458
- }
1459
- // Executes all initialization snippets from all accessible modules
1460
- const scope = shareScope[shareScopeName];
1461
- const register = (name, shared)=>{
1462
- var _activeVersion_shareConfig;
1463
- const { version, eager } = shared;
1464
- scope[name] = scope[name] || {};
1465
- const versions = scope[name];
1466
- const activeVersion = versions[version];
1467
- const activeVersionEager = Boolean(activeVersion && (activeVersion.eager || ((_activeVersion_shareConfig = activeVersion.shareConfig) == null ? void 0 : _activeVersion_shareConfig.eager)));
1468
- if (!activeVersion || activeVersion.strategy !== 'loaded-first' && !activeVersion.loaded && (Boolean(!eager) !== !activeVersionEager ? eager : hostName > activeVersion.from)) {
1469
- versions[version] = shared;
1470
- }
1471
- };
1472
- const promises = [];
1473
- const initFn = (mod)=>mod && mod.init && mod.init(shareScope[shareScopeName]);
1474
- const initRemoteModule = async (key)=>{
1475
- const { module } = await this._getRemoteModuleAndOptions(key);
1476
- if (module.getEntry) {
1477
- const entry = await module.getEntry();
1478
- if (!module.inited) {
1479
- initFn(entry);
1480
- module.inited = true;
1541
+ registerRemotes(remotes, options) {
1542
+ const { host } = this;
1543
+ remotes.forEach((remote)=>{
1544
+ this.registerRemote(remote, host.options.remotes, {
1545
+ force: options == null ? void 0 : options.force
1546
+ });
1547
+ });
1548
+ }
1549
+ async getRemoteModuleAndOptions(options) {
1550
+ const { host } = this;
1551
+ const { id } = options;
1552
+ let loadRemoteArgs;
1553
+ try {
1554
+ loadRemoteArgs = await this.hooks.lifecycle.beforeRequest.emit({
1555
+ id,
1556
+ options: host.options,
1557
+ origin: host
1558
+ });
1559
+ } catch (error) {
1560
+ loadRemoteArgs = await this.hooks.lifecycle.errorLoadRemote.emit({
1561
+ id,
1562
+ options: host.options,
1563
+ origin: host,
1564
+ from: 'runtime',
1565
+ error,
1566
+ lifecycle: 'beforeRequest'
1567
+ });
1568
+ if (!loadRemoteArgs) {
1569
+ throw error;
1570
+ }
1571
+ }
1572
+ const { id: idRes } = loadRemoteArgs;
1573
+ const remoteSplitInfo = matchRemoteWithNameAndExpose(host.options.remotes, idRes);
1574
+ assert(remoteSplitInfo, `
1575
+ Unable to locate ${idRes} in ${host.options.name}. Potential reasons for failure include:\n
1576
+ 1. ${idRes} was not included in the 'remotes' parameter of ${host.options.name || 'the host'}.\n
1577
+ 2. ${idRes} could not be found in the 'remotes' of ${host.options.name} with either 'name' or 'alias' attributes.
1578
+ 3. ${idRes} is not online, injected, or loaded.
1579
+ 4. ${idRes} cannot be accessed on the expected.
1580
+ 5. The 'beforeRequest' hook was provided but did not return the correct 'remoteInfo' when attempting to load ${idRes}.
1581
+ `);
1582
+ const { remote: rawRemote } = remoteSplitInfo;
1583
+ const remoteInfo = getRemoteInfo(rawRemote);
1584
+ const matchInfo = await host.sharedHandler.hooks.lifecycle.afterResolve.emit(_extends$1({
1585
+ id: idRes
1586
+ }, remoteSplitInfo, {
1587
+ options: host.options,
1588
+ origin: host,
1589
+ remoteInfo
1590
+ }));
1591
+ const { remote, expose } = matchInfo;
1592
+ assert(remote && expose, `The 'beforeRequest' hook was executed, but it failed to return the correct 'remote' and 'expose' values while loading ${idRes}.`);
1593
+ let module = host.moduleCache.get(remote.name);
1594
+ const moduleOptions = {
1595
+ host: host,
1596
+ remoteInfo
1597
+ };
1598
+ if (!module) {
1599
+ module = new Module(moduleOptions);
1600
+ host.moduleCache.set(remote.name, module);
1601
+ }
1602
+ return {
1603
+ module,
1604
+ moduleOptions,
1605
+ remoteMatchInfo: matchInfo
1606
+ };
1607
+ }
1608
+ registerRemote(remote, targetRemotes, options) {
1609
+ const normalizeRemote = ()=>{
1610
+ if (remote.alias) {
1611
+ // Validate if alias equals the prefix of remote.name and remote.alias, if so, throw an error
1612
+ // As multi-level path references cannot guarantee unique names, alias being a prefix of remote.name is not supported
1613
+ const findEqual = targetRemotes.find((item)=>{
1614
+ var _item_alias;
1615
+ return remote.alias && (item.name.startsWith(remote.alias) || ((_item_alias = item.alias) == null ? void 0 : _item_alias.startsWith(remote.alias)));
1616
+ });
1617
+ assert(!findEqual, `The alias ${remote.alias} of remote ${remote.name} is not allowed to be the prefix of ${findEqual && findEqual.name} name or alias`);
1618
+ }
1619
+ // Set the remote entry to a complete path
1620
+ if ('entry' in remote) {
1621
+ if (isBrowserEnv() && !remote.entry.startsWith('http')) {
1622
+ remote.entry = new URL(remote.entry, window.location.origin).href;
1481
1623
  }
1482
1624
  }
1625
+ if (!remote.shareScope) {
1626
+ remote.shareScope = DEFAULT_SCOPE;
1627
+ }
1628
+ if (!remote.type) {
1629
+ remote.type = DEFAULT_REMOTE_TYPE;
1630
+ }
1483
1631
  };
1484
- Object.keys(this.options.shared).forEach((shareName)=>{
1485
- const sharedArr = this.options.shared[shareName];
1486
- sharedArr.forEach((shared)=>{
1487
- if (shared.scope.includes(shareScopeName)) {
1488
- register(shareName, shared);
1632
+ const registeredRemote = targetRemotes.find((item)=>item.name === remote.name);
1633
+ if (!registeredRemote) {
1634
+ normalizeRemote();
1635
+ targetRemotes.push(remote);
1636
+ } else {
1637
+ const messages = [
1638
+ `The remote "${remote.name}" is already registered.`,
1639
+ (options == null ? void 0 : options.force) ? 'Hope you have known that OVERRIDE it may have some unexpected errors' : 'If you want to merge the remote, you can set "force: true".'
1640
+ ];
1641
+ if (options == null ? void 0 : options.force) {
1642
+ // remove registered remote
1643
+ this.removeRemote(registeredRemote);
1644
+ normalizeRemote();
1645
+ targetRemotes.push(remote);
1646
+ }
1647
+ warn$1(messages.join(' '));
1648
+ }
1649
+ }
1650
+ removeRemote(remote) {
1651
+ const { host } = this;
1652
+ const { name } = remote;
1653
+ const remoteIndex = host.options.remotes.findIndex((item)=>item.name === name);
1654
+ if (remoteIndex !== -1) {
1655
+ host.options.remotes.splice(remoteIndex, 1);
1656
+ }
1657
+ const loadedModule = host.moduleCache.get(remote.name);
1658
+ if (loadedModule) {
1659
+ const remoteInfo = loadedModule.remoteInfo;
1660
+ const key = remoteInfo.entryGlobalName;
1661
+ if (globalThis[key]) {
1662
+ delete globalThis[key];
1663
+ }
1664
+ const remoteEntryUniqueKey = getRemoteEntryUniqueKey(loadedModule.remoteInfo);
1665
+ if (globalLoading[remoteEntryUniqueKey]) {
1666
+ delete globalLoading[remoteEntryUniqueKey];
1667
+ }
1668
+ // delete un loaded shared and instance
1669
+ let remoteInsId = remoteInfo.buildVersion ? composeKeyWithSeparator(remoteInfo.name, remoteInfo.buildVersion) : remoteInfo.name;
1670
+ const remoteInsIndex = globalThis.__FEDERATION__.__INSTANCES__.findIndex((ins)=>{
1671
+ if (remoteInfo.buildVersion) {
1672
+ return ins.options.id === remoteInsId;
1673
+ } else {
1674
+ return ins.name === remoteInsId;
1489
1675
  }
1490
1676
  });
1491
- });
1492
- if (strategy === 'version-first') {
1493
- this.options.remotes.forEach((remote)=>{
1494
- if (remote.shareScope === shareScopeName) {
1495
- promises.push(initRemoteModule(remote.name));
1677
+ if (remoteInsIndex !== -1) {
1678
+ const remoteIns = globalThis.__FEDERATION__.__INSTANCES__[remoteInsIndex];
1679
+ remoteInsId = remoteIns.options.id || remoteInsId;
1680
+ const globalShareScopeMap = getGlobalShareScope();
1681
+ let isAllSharedNotUsed = true;
1682
+ const needDeleteKeys = [];
1683
+ Object.keys(globalShareScopeMap).forEach((instId)=>{
1684
+ Object.keys(globalShareScopeMap[instId]).forEach((shareScope)=>{
1685
+ Object.keys(globalShareScopeMap[instId][shareScope]).forEach((shareName)=>{
1686
+ Object.keys(globalShareScopeMap[instId][shareScope][shareName]).forEach((shareVersion)=>{
1687
+ const shared = globalShareScopeMap[instId][shareScope][shareName][shareVersion];
1688
+ if (shared.from === remoteInfo.name) {
1689
+ if (shared.loaded || shared.loading) {
1690
+ shared.useIn = shared.useIn.filter((usedHostName)=>usedHostName !== remoteInfo.name);
1691
+ if (shared.useIn.length) {
1692
+ isAllSharedNotUsed = false;
1693
+ } else {
1694
+ needDeleteKeys.push([
1695
+ instId,
1696
+ shareScope,
1697
+ shareName,
1698
+ shareVersion
1699
+ ]);
1700
+ }
1701
+ } else {
1702
+ needDeleteKeys.push([
1703
+ instId,
1704
+ shareScope,
1705
+ shareName,
1706
+ shareVersion
1707
+ ]);
1708
+ }
1709
+ }
1710
+ });
1711
+ });
1712
+ });
1713
+ });
1714
+ if (isAllSharedNotUsed) {
1715
+ remoteIns.shareScopeMap = {};
1716
+ delete globalShareScopeMap[remoteInsId];
1496
1717
  }
1497
- });
1718
+ needDeleteKeys.forEach(([insId, shareScope, shareName, shareVersion])=>{
1719
+ var _globalShareScopeMap_insId_shareScope_shareName, _globalShareScopeMap_insId_shareScope, _globalShareScopeMap_insId;
1720
+ (_globalShareScopeMap_insId = globalShareScopeMap[insId]) == null ? true : (_globalShareScopeMap_insId_shareScope = _globalShareScopeMap_insId[shareScope]) == null ? true : (_globalShareScopeMap_insId_shareScope_shareName = _globalShareScopeMap_insId_shareScope[shareName]) == null ? true : delete _globalShareScopeMap_insId_shareScope_shareName[shareVersion];
1721
+ });
1722
+ globalThis.__FEDERATION__.__INSTANCES__.splice(remoteInsIndex, 1);
1723
+ }
1724
+ host.moduleCache.delete(remote.name);
1498
1725
  }
1499
- return promises;
1500
1726
  }
1501
- initShareScopeMap(scopeName, shareScope) {
1502
- this.shareScopeMap[scopeName] = shareScope;
1503
- this.hooks.lifecycle.initContainerShareScopeMap.emit({
1504
- shareScope,
1505
- options: this.options,
1506
- origin: this
1727
+ constructor(host){
1728
+ this.hooks = new PluginSystem({
1729
+ beforeRequest: new AsyncWaterfallHook('beforeRequest'),
1730
+ onLoad: new AsyncHook('onLoad'),
1731
+ handlePreloadModule: new SyncHook('handlePreloadModule'),
1732
+ errorLoadRemote: new AsyncHook('errorLoadRemote'),
1733
+ beforePreloadRemote: new AsyncHook(),
1734
+ generatePreloadAssets: new AsyncHook('generatePreloadAssets'),
1735
+ // not used yet
1736
+ afterPreloadRemote: new AsyncHook()
1507
1737
  });
1738
+ this.host = host;
1508
1739
  }
1509
- formatOptions(globalOptions, userOptions) {
1510
- const formatShareOptions = formatShareConfigs(userOptions.shared || {}, userOptions.name);
1511
- const shared = _extends({}, globalOptions.shared);
1512
- Object.keys(formatShareOptions).forEach((shareKey)=>{
1513
- if (!shared[shareKey]) {
1514
- shared[shareKey] = formatShareOptions[shareKey];
1515
- } else {
1516
- formatShareOptions[shareKey].forEach((newUserSharedOptions)=>{
1517
- const isSameVersion = shared[shareKey].find((sharedVal)=>sharedVal.version === newUserSharedOptions.version);
1518
- if (!isSameVersion) {
1519
- shared[shareKey].push(newUserSharedOptions);
1520
- }
1521
- });
1740
+ }
1741
+
1742
+ function _extends() {
1743
+ _extends = Object.assign || function(target) {
1744
+ for(var i = 1; i < arguments.length; i++){
1745
+ var source = arguments[i];
1746
+ for(var key in source){
1747
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1748
+ target[key] = source[key];
1749
+ }
1522
1750
  }
1751
+ }
1752
+ return target;
1753
+ };
1754
+ return _extends.apply(this, arguments);
1755
+ }
1756
+ class FederationHost {
1757
+ initOptions(userOptions) {
1758
+ this.registerPlugins(userOptions.plugins);
1759
+ const options = this.formatOptions(this.options, userOptions);
1760
+ this.options = options;
1761
+ return options;
1762
+ }
1763
+ async loadShare(pkgName, extraOptions) {
1764
+ return this.sharedHandler.loadShare(pkgName, extraOptions);
1765
+ }
1766
+ // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.
1767
+ // 1. If the loaded shared already exists globally, then it will be reused
1768
+ // 2. If lib exists in local shared, it will be used directly
1769
+ // 3. If the local get returns something other than Promise, then it will be used directly
1770
+ loadShareSync(pkgName, extraOptions) {
1771
+ return this.sharedHandler.loadShareSync(pkgName, extraOptions);
1772
+ }
1773
+ initializeSharing(shareScopeName = DEFAULT_SCOPE, strategy) {
1774
+ return this.sharedHandler.initializeSharing(shareScopeName, strategy);
1775
+ }
1776
+ initRawContainer(name, url, container) {
1777
+ const remoteInfo = getRemoteInfo({
1778
+ name,
1779
+ entry: url
1780
+ });
1781
+ const module = new Module({
1782
+ host: this,
1783
+ remoteInfo
1523
1784
  });
1785
+ module.remoteEntryExports = container;
1786
+ this.moduleCache.set(name, module);
1787
+ return module;
1788
+ }
1789
+ // eslint-disable-next-line max-lines-per-function
1790
+ // eslint-disable-next-line @typescript-eslint/member-ordering
1791
+ async loadRemote(id, options) {
1792
+ return this.remoteHandler.loadRemote(id, options);
1793
+ }
1794
+ // eslint-disable-next-line @typescript-eslint/member-ordering
1795
+ async preloadRemote(preloadOptions) {
1796
+ return this.remoteHandler.preloadRemote(preloadOptions);
1797
+ }
1798
+ initShareScopeMap(scopeName, shareScope) {
1799
+ this.sharedHandler.initShareScopeMap(scopeName, shareScope);
1800
+ }
1801
+ formatOptions(globalOptions, userOptions) {
1802
+ const { shared } = formatShareConfigs(globalOptions, userOptions);
1524
1803
  const { userOptions: userOptionsRes, options: globalOptionsRes } = this.hooks.lifecycle.beforeInit.emit({
1525
1804
  origin: this,
1526
1805
  userOptions,
1527
1806
  options: globalOptions,
1528
1807
  shareInfo: shared
1529
1808
  });
1530
- const userRemotes = userOptionsRes.remotes || [];
1531
- const remotes = userRemotes.reduce((res, remote)=>{
1532
- this.registerRemote(remote, res, {
1533
- force: false
1534
- });
1535
- return res;
1536
- }, globalOptionsRes.remotes);
1537
- // register shared in shareScopeMap
1538
- const sharedKeys = Object.keys(formatShareOptions);
1539
- sharedKeys.forEach((sharedKey)=>{
1540
- const sharedVals = formatShareOptions[sharedKey];
1541
- sharedVals.forEach((sharedVal)=>{
1542
- const registeredShared = getRegisteredShare(this.shareScopeMap, sharedKey, sharedVal, this.hooks.lifecycle.resolveShare);
1543
- if (!registeredShared && sharedVal && sharedVal.lib) {
1544
- this.setShared({
1545
- pkgName: sharedKey,
1546
- lib: sharedVal.lib,
1547
- get: sharedVal.get,
1548
- loaded: true,
1549
- shared: sharedVal,
1550
- from: userOptions.name
1551
- });
1552
- }
1553
- });
1554
- });
1809
+ const remotes = this.remoteHandler.formatAndRegisterRemote(globalOptionsRes, userOptionsRes);
1810
+ const { shared: handledShared } = this.sharedHandler.registerShared(globalOptionsRes, userOptionsRes);
1555
1811
  const plugins = [
1556
1812
  ...globalOptionsRes.plugins
1557
1813
  ];
@@ -1565,7 +1821,7 @@ class FederationHost {
1565
1821
  const optionsRes = _extends({}, globalOptions, userOptions, {
1566
1822
  plugins,
1567
1823
  remotes,
1568
- shared
1824
+ shared: handledShared
1569
1825
  });
1570
1826
  this.hooks.lifecycle.init.emit({
1571
1827
  origin: this,
@@ -1576,6 +1832,8 @@ class FederationHost {
1576
1832
  registerPlugins(plugins) {
1577
1833
  const pluginRes = registerPlugins$1(plugins, [
1578
1834
  this.hooks,
1835
+ this.remoteHandler.hooks,
1836
+ this.sharedHandler.hooks,
1579
1837
  this.snapshotHandler.hooks,
1580
1838
  this.loaderHook
1581
1839
  ]);
@@ -1588,132 +1846,19 @@ class FederationHost {
1588
1846
  return res;
1589
1847
  }, pluginRes || []);
1590
1848
  }
1591
- setShared({ pkgName, shared, from, lib, loading, loaded, get }) {
1592
- const { version, scope = 'default' } = shared, shareInfo = _object_without_properties_loose(shared, [
1593
- "version",
1594
- "scope"
1595
- ]);
1596
- const scopes = Array.isArray(scope) ? scope : [
1597
- scope
1598
- ];
1599
- scopes.forEach((sc)=>{
1600
- if (!this.shareScopeMap[sc]) {
1601
- this.shareScopeMap[sc] = {};
1602
- }
1603
- if (!this.shareScopeMap[sc][pkgName]) {
1604
- this.shareScopeMap[sc][pkgName] = {};
1605
- }
1606
- if (this.shareScopeMap[sc][pkgName][version]) {
1607
- return;
1608
- }
1609
- this.shareScopeMap[sc][pkgName][version] = _extends({
1610
- version,
1611
- scope: [
1612
- 'default'
1613
- ]
1614
- }, shareInfo, {
1615
- lib,
1616
- loaded,
1617
- loading
1618
- });
1619
- if (get) {
1620
- this.shareScopeMap[sc][pkgName][version].get = get;
1621
- }
1622
- });
1623
- }
1624
- removeRemote(remote) {
1625
- const { name } = remote;
1626
- const remoteIndex = this.options.remotes.findIndex((item)=>item.name === name);
1627
- if (remoteIndex !== -1) {
1628
- this.options.remotes.splice(remoteIndex, 1);
1629
- }
1630
- const loadedModule = this.moduleCache.get(remote.name);
1631
- if (loadedModule) {
1632
- const key = loadedModule.remoteInfo.entryGlobalName;
1633
- if (globalThis[key]) {
1634
- delete globalThis[key];
1635
- }
1636
- const remoteEntryUniqueKey = getRemoteEntryUniqueKey(loadedModule.remoteInfo);
1637
- if (globalLoading[remoteEntryUniqueKey]) {
1638
- delete globalLoading[remoteEntryUniqueKey];
1639
- }
1640
- this.moduleCache.delete(remote.name);
1641
- }
1642
- }
1643
- registerRemote(remote, targetRemotes, options) {
1644
- const normalizeRemote = ()=>{
1645
- if (remote.alias) {
1646
- // Validate if alias equals the prefix of remote.name and remote.alias, if so, throw an error
1647
- // As multi-level path references cannot guarantee unique names, alias being a prefix of remote.name is not supported
1648
- const findEqual = targetRemotes.find((item)=>{
1649
- var _item_alias;
1650
- return remote.alias && (item.name.startsWith(remote.alias) || ((_item_alias = item.alias) == null ? void 0 : _item_alias.startsWith(remote.alias)));
1651
- });
1652
- assert(!findEqual, `The alias ${remote.alias} of remote ${remote.name} is not allowed to be the prefix of ${findEqual && findEqual.name} name or alias`);
1653
- }
1654
- // Set the remote entry to a complete path
1655
- if ('entry' in remote) {
1656
- if (isBrowserEnv() && !remote.entry.startsWith('http')) {
1657
- remote.entry = new URL(remote.entry, window.location.origin).href;
1658
- }
1659
- }
1660
- if (!remote.shareScope) {
1661
- remote.shareScope = DEFAULT_SCOPE;
1662
- }
1663
- if (!remote.type) {
1664
- remote.type = DEFAULT_REMOTE_TYPE;
1665
- }
1666
- };
1667
- const registeredRemote = targetRemotes.find((item)=>item.name === remote.name);
1668
- if (!registeredRemote) {
1669
- normalizeRemote();
1670
- targetRemotes.push(remote);
1671
- } else {
1672
- const messages = [
1673
- `The remote "${remote.name}" is already registered.`,
1674
- (options == null ? void 0 : options.force) ? 'Hope you have known that OVERRIDE it may have some unexpected errors' : 'If you want to merge the remote, you can set "force: true".'
1675
- ];
1676
- if (options == null ? void 0 : options.force) {
1677
- // remove registered remote
1678
- this.removeRemote(registeredRemote);
1679
- normalizeRemote();
1680
- targetRemotes.push(remote);
1681
- }
1682
- warn(messages.join(' '));
1683
- }
1684
- }
1685
1849
  registerRemotes(remotes, options) {
1686
- remotes.forEach((remote)=>{
1687
- this.registerRemote(remote, this.options.remotes, {
1688
- force: options == null ? void 0 : options.force
1689
- });
1690
- });
1850
+ return this.remoteHandler.registerRemotes(remotes, options);
1691
1851
  }
1692
1852
  constructor(userOptions){
1693
1853
  this.hooks = new PluginSystem({
1694
1854
  beforeInit: new SyncWaterfallHook('beforeInit'),
1695
1855
  init: new SyncHook(),
1696
- beforeRequest: new AsyncWaterfallHook('beforeRequest'),
1697
- afterResolve: new AsyncWaterfallHook('afterResolve'),
1698
1856
  // maybe will change, temporarily for internal use only
1699
1857
  beforeInitContainer: new AsyncWaterfallHook('beforeInitContainer'),
1700
1858
  // maybe will change, temporarily for internal use only
1701
- initContainerShareScopeMap: new AsyncWaterfallHook('initContainer'),
1702
- // maybe will change, temporarily for internal use only
1703
- initContainer: new AsyncWaterfallHook('initContainer'),
1704
- onLoad: new AsyncHook('onLoad'),
1705
- handlePreloadModule: new SyncHook('handlePreloadModule'),
1706
- errorLoadRemote: new AsyncHook('errorLoadRemote'),
1707
- beforeLoadShare: new AsyncWaterfallHook('beforeLoadShare'),
1708
- // not used yet
1709
- loadShare: new AsyncHook(),
1710
- resolveShare: new SyncWaterfallHook('resolveShare'),
1711
- beforePreloadRemote: new AsyncHook(),
1712
- generatePreloadAssets: new AsyncHook('generatePreloadAssets'),
1713
- // not used yet
1714
- afterPreloadRemote: new AsyncHook()
1859
+ initContainer: new AsyncWaterfallHook('initContainer')
1715
1860
  });
1716
- this.version = "0.1.12";
1861
+ this.version = "0.1.13";
1717
1862
  this.moduleCache = new Map();
1718
1863
  this.loaderHook = new PluginSystem({
1719
1864
  // FIXME: may not be suitable , not open to the public yet
@@ -1734,13 +1879,14 @@ class FederationHost {
1734
1879
  ],
1735
1880
  remotes: [],
1736
1881
  shared: {},
1737
- inBrowser: isBrowserEnv()
1882
+ inBrowser: isBrowserEnv$1()
1738
1883
  };
1739
1884
  this.name = userOptions.name;
1740
1885
  this.options = defaultOptions;
1741
- this.shareScopeMap = {};
1742
- this._setGlobalShareScopeMap();
1743
1886
  this.snapshotHandler = new SnapshotHandler(this);
1887
+ this.sharedHandler = new SharedHandler(this);
1888
+ this.remoteHandler = new RemoteHandler(this);
1889
+ this.shareScopeMap = this.sharedHandler.shareScopeMap;
1744
1890
  this.registerPlugins([
1745
1891
  ...defaultOptions.plugins,
1746
1892
  ...userOptions.plugins || []