@module-federation/runtime 0.0.0-next-20240919100820 → 0.0.0-next-20240920074009

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.
@@ -1,17 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var share = require('./share.cjs.js');
4
- require('@module-federation/sdk');
5
4
  require('./polyfills.cjs.js');
6
-
7
- var pluginHelper = /*#__PURE__*/Object.freeze({
8
- __proto__: null,
9
- SyncHook: share.SyncHook,
10
- AsyncHook: share.AsyncHook,
11
- SyncWaterfallHook: share.SyncWaterfallHook,
12
- AsyncWaterfallHook: share.AsyncWaterfallHook,
13
- PluginSystem: share.PluginSystem
14
- });
5
+ require('@module-federation/sdk');
15
6
 
16
7
  const ShareUtils = {
17
8
  getRegisteredShare: share.getRegisteredShare,
@@ -35,9 +26,7 @@ const GlobalUtils = {
35
26
  registerGlobalPlugins: share.registerGlobalPlugins,
36
27
  getGlobalHostPlugins: share.getGlobalHostPlugins,
37
28
  getPreloaded: share.getPreloaded,
38
- setPreloaded: share.setPreloaded,
39
- registerPlugins: share.registerPlugins,
40
- pluginHelper
29
+ setPreloaded: share.setPreloaded
41
30
  };
42
31
  var helpers = {
43
32
  global: GlobalUtils,
@@ -1,15 +1,6 @@
1
- import { y as SyncHook, A as AsyncHook, S as SyncWaterfallHook, r as AsyncWaterfallHook, P as PluginSystem, l as getRegisteredShare, w as getGlobalShareScope, G as Global, J as nativeGlobal, K as resetFederationGlobalInfo, E as getGlobalFederationInstance, H as setGlobalFederationInstance, F as getGlobalFederationConstructor, C as setGlobalFederationConstructor, j as getInfoWithoutType, t as getGlobalSnapshot, L as getTargetSnapshotInfoByModuleInfo, n as getGlobalSnapshotInfoByModuleInfo, q as setGlobalSnapshotInfoByModuleInfo, o as addGlobalSnapshot, b as getRemoteEntryExports, I as registerGlobalPlugins, M as getGlobalHostPlugins, k as getPreloaded, s as setPreloaded, z as registerPlugins } from './share.esm.js';
2
- import '@module-federation/sdk';
1
+ import { o as getRegisteredShare, y as getGlobalShareScope, G as Global, I as nativeGlobal, J as resetFederationGlobalInfo, C as getGlobalFederationInstance, F as setGlobalFederationInstance, E as getGlobalFederationConstructor, B as setGlobalFederationConstructor, m as getInfoWithoutType, u as getGlobalSnapshot, K as getTargetSnapshotInfoByModuleInfo, q as getGlobalSnapshotInfoByModuleInfo, t as setGlobalSnapshotInfoByModuleInfo, r as addGlobalSnapshot, c as getRemoteEntryExports, H as registerGlobalPlugins, g as getGlobalHostPlugins, n as getPreloaded, s as setPreloaded } from './share.esm.js';
3
2
  import './polyfills.esm.js';
4
-
5
- var pluginHelper = /*#__PURE__*/Object.freeze({
6
- __proto__: null,
7
- SyncHook: SyncHook,
8
- AsyncHook: AsyncHook,
9
- SyncWaterfallHook: SyncWaterfallHook,
10
- AsyncWaterfallHook: AsyncWaterfallHook,
11
- PluginSystem: PluginSystem
12
- });
3
+ import '@module-federation/sdk';
13
4
 
14
5
  const ShareUtils = {
15
6
  getRegisteredShare,
@@ -33,9 +24,7 @@ const GlobalUtils = {
33
24
  registerGlobalPlugins,
34
25
  getGlobalHostPlugins,
35
26
  getPreloaded,
36
- setPreloaded,
37
- registerPlugins,
38
- pluginHelper
27
+ setPreloaded
39
28
  };
40
29
  var helpers = {
41
30
  global: GlobalUtils,
package/dist/index.cjs.js CHANGED
@@ -70,6 +70,26 @@ function matchRemote(remotes, nameOrAlias) {
70
70
  return;
71
71
  }
72
72
 
73
+ function registerPlugins$1(plugins, hookInstances) {
74
+ const globalPlugins = share.getGlobalHostPlugins();
75
+ // Incorporate global plugins
76
+ if (globalPlugins.length > 0) {
77
+ globalPlugins.forEach((plugin)=>{
78
+ if (plugins == null ? void 0 : plugins.find((item)=>item.name !== plugin.name)) {
79
+ plugins.push(plugin);
80
+ }
81
+ });
82
+ }
83
+ if (plugins && plugins.length > 0) {
84
+ plugins.forEach((plugin)=>{
85
+ hookInstances.forEach((hookInstance)=>{
86
+ hookInstance.applyPlugin(plugin);
87
+ });
88
+ });
89
+ }
90
+ return plugins;
91
+ }
92
+
73
93
  async function loadEsmEntry({ entry, remoteEntryExports }) {
74
94
  return new Promise((resolve, reject)=>{
75
95
  try {
@@ -256,7 +276,7 @@ let Module = class Module {
256
276
  return this.remoteEntryExports;
257
277
  }
258
278
  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
259
- async get(id, expose, options) {
279
+ async get(id, expose, options, remoteSnapshot) {
260
280
  const { loadFactory = true } = options || {
261
281
  loadFactory: true
262
282
  };
@@ -292,6 +312,8 @@ let Module = class Module {
292
312
  }
293
313
  await remoteEntryExports.init(initContainerOptions.shareScope, initContainerOptions.initScope, initContainerOptions.remoteEntryInitOptions);
294
314
  await this.host.hooks.lifecycle.initContainer.emit(polyfills._extends({}, initContainerOptions, {
315
+ id,
316
+ remoteSnapshot,
295
317
  remoteEntryExports
296
318
  }));
297
319
  }
@@ -300,9 +322,7 @@ let Module = class Module {
300
322
  // get exposeGetter
301
323
  const moduleFactory = await remoteEntryExports.get(expose);
302
324
  share.assert(moduleFactory, `${share.getFMId(this.remoteInfo)} remote don't export ${expose}.`);
303
- // keep symbol for module name always one format
304
- const symbolName = share.processModuleAlias(this.remoteInfo.name, expose);
305
- const wrapModuleFactory = this.wraperFactory(moduleFactory, symbolName);
325
+ const wrapModuleFactory = this.wraperFactory(moduleFactory, id);
306
326
  if (!loadFactory) {
307
327
  return wrapModuleFactory;
308
328
  }
@@ -342,6 +362,193 @@ let Module = class Module {
342
362
  }
343
363
  };
344
364
 
365
+ class SyncHook {
366
+ on(fn) {
367
+ if (typeof fn === 'function') {
368
+ this.listeners.add(fn);
369
+ }
370
+ }
371
+ once(fn) {
372
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
373
+ const self = this;
374
+ this.on(function wrapper(...args) {
375
+ self.remove(wrapper);
376
+ // eslint-disable-next-line prefer-spread
377
+ return fn.apply(null, args);
378
+ });
379
+ }
380
+ emit(...data) {
381
+ let result;
382
+ if (this.listeners.size > 0) {
383
+ // eslint-disable-next-line prefer-spread
384
+ this.listeners.forEach((fn)=>{
385
+ result = fn(...data);
386
+ });
387
+ }
388
+ return result;
389
+ }
390
+ remove(fn) {
391
+ this.listeners.delete(fn);
392
+ }
393
+ removeAll() {
394
+ this.listeners.clear();
395
+ }
396
+ constructor(type){
397
+ this.type = '';
398
+ this.listeners = new Set();
399
+ if (type) {
400
+ this.type = type;
401
+ }
402
+ }
403
+ }
404
+
405
+ class AsyncHook extends SyncHook {
406
+ emit(...data) {
407
+ let result;
408
+ const ls = Array.from(this.listeners);
409
+ if (ls.length > 0) {
410
+ let i = 0;
411
+ const call = (prev)=>{
412
+ if (prev === false) {
413
+ return false; // Abort process
414
+ } else if (i < ls.length) {
415
+ return Promise.resolve(ls[i++].apply(null, data)).then(call);
416
+ } else {
417
+ return prev;
418
+ }
419
+ };
420
+ result = call();
421
+ }
422
+ return Promise.resolve(result);
423
+ }
424
+ }
425
+
426
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
427
+ function checkReturnData(originalData, returnedData) {
428
+ if (!share.isObject(returnedData)) {
429
+ return false;
430
+ }
431
+ if (originalData !== returnedData) {
432
+ // eslint-disable-next-line no-restricted-syntax
433
+ for(const key in originalData){
434
+ if (!(key in returnedData)) {
435
+ return false;
436
+ }
437
+ }
438
+ }
439
+ return true;
440
+ }
441
+ class SyncWaterfallHook extends SyncHook {
442
+ emit(data) {
443
+ if (!share.isObject(data)) {
444
+ share.error(`The data for the "${this.type}" hook should be an object.`);
445
+ }
446
+ for (const fn of this.listeners){
447
+ try {
448
+ const tempData = fn(data);
449
+ if (checkReturnData(data, tempData)) {
450
+ data = tempData;
451
+ } else {
452
+ this.onerror(`A plugin returned an unacceptable value for the "${this.type}" type.`);
453
+ break;
454
+ }
455
+ } catch (e) {
456
+ share.warn(e);
457
+ this.onerror(e);
458
+ }
459
+ }
460
+ return data;
461
+ }
462
+ constructor(type){
463
+ super();
464
+ this.onerror = share.error;
465
+ this.type = type;
466
+ }
467
+ }
468
+
469
+ class AsyncWaterfallHook extends SyncHook {
470
+ emit(data) {
471
+ if (!share.isObject(data)) {
472
+ share.error(`The response data for the "${this.type}" hook must be an object.`);
473
+ }
474
+ const ls = Array.from(this.listeners);
475
+ if (ls.length > 0) {
476
+ let i = 0;
477
+ const processError = (e)=>{
478
+ share.warn(e);
479
+ this.onerror(e);
480
+ return data;
481
+ };
482
+ const call = (prevData)=>{
483
+ if (checkReturnData(data, prevData)) {
484
+ data = prevData;
485
+ if (i < ls.length) {
486
+ try {
487
+ return Promise.resolve(ls[i++](data)).then(call, processError);
488
+ } catch (e) {
489
+ return processError(e);
490
+ }
491
+ }
492
+ } else {
493
+ this.onerror(`A plugin returned an incorrect value for the "${this.type}" type.`);
494
+ }
495
+ return data;
496
+ };
497
+ return Promise.resolve(call(data));
498
+ }
499
+ return Promise.resolve(data);
500
+ }
501
+ constructor(type){
502
+ super();
503
+ this.onerror = share.error;
504
+ this.type = type;
505
+ }
506
+ }
507
+
508
+ class PluginSystem {
509
+ applyPlugin(plugin) {
510
+ share.assert(share.isPlainObject(plugin), 'Plugin configuration is invalid.');
511
+ // The plugin's name is mandatory and must be unique
512
+ const pluginName = plugin.name;
513
+ share.assert(pluginName, 'A name must be provided by the plugin.');
514
+ if (!this.registerPlugins[pluginName]) {
515
+ this.registerPlugins[pluginName] = plugin;
516
+ Object.keys(this.lifecycle).forEach((key)=>{
517
+ const pluginLife = plugin[key];
518
+ if (pluginLife) {
519
+ this.lifecycle[key].on(pluginLife);
520
+ }
521
+ });
522
+ }
523
+ }
524
+ removePlugin(pluginName) {
525
+ share.assert(pluginName, 'A name is required.');
526
+ const plugin = this.registerPlugins[pluginName];
527
+ share.assert(plugin, `The plugin "${pluginName}" is not registered.`);
528
+ Object.keys(plugin).forEach((key)=>{
529
+ if (key !== 'name') {
530
+ this.lifecycle[key].remove(plugin[key]);
531
+ }
532
+ });
533
+ }
534
+ // eslint-disable-next-line @typescript-eslint/no-shadow
535
+ inherit({ lifecycle, registerPlugins }) {
536
+ Object.keys(lifecycle).forEach((hookName)=>{
537
+ share.assert(!this.lifecycle[hookName], `The hook "${hookName}" has a conflict and cannot be inherited.`);
538
+ this.lifecycle[hookName] = lifecycle[hookName];
539
+ });
540
+ Object.keys(registerPlugins).forEach((pluginName)=>{
541
+ share.assert(!this.registerPlugins[pluginName], `The plugin "${pluginName}" has a conflict and cannot be inherited.`);
542
+ this.applyPlugin(registerPlugins[pluginName]);
543
+ });
544
+ }
545
+ constructor(lifecycle){
546
+ this.registerPlugins = {};
547
+ this.lifecycle = lifecycle;
548
+ this.lifecycleKeys = Object.keys(lifecycle);
549
+ }
550
+ }
551
+
345
552
  function defaultPreloadArgs(preloadConfig) {
346
553
  return polyfills._extends({
347
554
  resourceCategory: 'sync',
@@ -849,8 +1056,6 @@ class SnapshotHandler {
849
1056
  remoteSnapshot,
850
1057
  globalSnapshot
851
1058
  });
852
- let mSnapshot;
853
- let gSnapshot;
854
1059
  // global snapshot includes manifest or module info includes manifest
855
1060
  if (globalRemoteSnapshot) {
856
1061
  if (sdk.isManifestProvider(globalRemoteSnapshot)) {
@@ -862,8 +1067,10 @@ class SnapshotHandler {
862
1067
  // Therefore, set the snapshot key to the global address of the actual request
863
1068
  entry: remoteEntry
864
1069
  }), moduleSnapshot);
865
- mSnapshot = moduleSnapshot;
866
- gSnapshot = globalSnapshotRes;
1070
+ return {
1071
+ remoteSnapshot: moduleSnapshot,
1072
+ globalSnapshot: globalSnapshotRes
1073
+ };
867
1074
  } else {
868
1075
  const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
869
1076
  options: this.HostInstance.options,
@@ -871,8 +1078,10 @@ class SnapshotHandler {
871
1078
  remoteSnapshot: globalRemoteSnapshot,
872
1079
  from: 'global'
873
1080
  });
874
- mSnapshot = remoteSnapshotRes;
875
- gSnapshot = globalSnapshotRes;
1081
+ return {
1082
+ remoteSnapshot: remoteSnapshotRes,
1083
+ globalSnapshot: globalSnapshotRes
1084
+ };
876
1085
  }
877
1086
  } else {
878
1087
  if (share.isRemoteInfoWithEntry(moduleInfo)) {
@@ -886,8 +1095,10 @@ class SnapshotHandler {
886
1095
  remoteSnapshot: moduleSnapshot,
887
1096
  from: 'global'
888
1097
  });
889
- mSnapshot = remoteSnapshotRes;
890
- gSnapshot = globalSnapshotRes;
1098
+ return {
1099
+ remoteSnapshot: remoteSnapshotRes,
1100
+ globalSnapshot: globalSnapshotRes
1101
+ };
891
1102
  } else {
892
1103
  share.error(`
893
1104
  Cannot get remoteSnapshot with the name: '${moduleInfo.name}', version: '${moduleInfo.version}' from __FEDERATION__.moduleInfo. The following reasons may be causing the problem:\n
@@ -897,15 +1108,6 @@ class SnapshotHandler {
897
1108
  `);
898
1109
  }
899
1110
  }
900
- await this.hooks.lifecycle.afterLoadSnapshot.emit({
901
- options,
902
- moduleInfo,
903
- remoteSnapshot: mSnapshot
904
- });
905
- return {
906
- remoteSnapshot: mSnapshot,
907
- globalSnapshot: gSnapshot
908
- };
909
1111
  }
910
1112
  getGlobalRemoteInfo(moduleInfo) {
911
1113
  return getGlobalRemoteInfo(moduleInfo, this.HostInstance);
@@ -955,11 +1157,10 @@ class SnapshotHandler {
955
1157
  constructor(HostInstance){
956
1158
  this.loadingHostSnapshot = null;
957
1159
  this.manifestCache = new Map();
958
- this.hooks = new share.PluginSystem({
959
- beforeLoadRemoteSnapshot: new share.AsyncHook('beforeLoadRemoteSnapshot'),
960
- loadSnapshot: new share.AsyncWaterfallHook('loadGlobalSnapshot'),
961
- loadRemoteSnapshot: new share.AsyncWaterfallHook('loadRemoteSnapshot'),
962
- afterLoadSnapshot: new share.AsyncWaterfallHook('afterLoadSnapshot')
1160
+ this.hooks = new PluginSystem({
1161
+ beforeLoadRemoteSnapshot: new AsyncHook('beforeLoadRemoteSnapshot'),
1162
+ loadSnapshot: new AsyncWaterfallHook('loadGlobalSnapshot'),
1163
+ loadRemoteSnapshot: new AsyncWaterfallHook('loadRemoteSnapshot')
963
1164
  });
964
1165
  this.manifestLoading = share.Global.__FEDERATION__.__MANIFEST_LOADING__;
965
1166
  this.HostInstance = HostInstance;
@@ -1302,14 +1503,14 @@ class SharedHandler {
1302
1503
  }
1303
1504
  }
1304
1505
  constructor(host){
1305
- this.hooks = new share.PluginSystem({
1306
- afterResolve: new share.AsyncWaterfallHook('afterResolve'),
1307
- beforeLoadShare: new share.AsyncWaterfallHook('beforeLoadShare'),
1506
+ this.hooks = new PluginSystem({
1507
+ afterResolve: new AsyncWaterfallHook('afterResolve'),
1508
+ beforeLoadShare: new AsyncWaterfallHook('beforeLoadShare'),
1308
1509
  // not used yet
1309
- loadShare: new share.AsyncHook(),
1310
- resolveShare: new share.SyncWaterfallHook('resolveShare'),
1510
+ loadShare: new AsyncHook(),
1511
+ resolveShare: new SyncWaterfallHook('resolveShare'),
1311
1512
  // maybe will change, temporarily for internal use only
1312
- initContainerShareScopeMap: new share.SyncWaterfallHook('initContainerShareScopeMap')
1513
+ initContainerShareScopeMap: new SyncWaterfallHook('initContainerShareScopeMap')
1313
1514
  });
1314
1515
  this.host = host;
1315
1516
  this.shareScopeMap = {};
@@ -1369,8 +1570,8 @@ class RemoteHandler {
1369
1570
  const { module, moduleOptions, remoteMatchInfo } = await this.getRemoteModuleAndOptions({
1370
1571
  id
1371
1572
  });
1372
- const { pkgNameOrAlias, remote, expose, id: idRes } = remoteMatchInfo;
1373
- const moduleOrFactory = await module.get(idRes, expose, options);
1573
+ const { pkgNameOrAlias, remote, expose, id: idRes, remoteSnapshot } = remoteMatchInfo;
1574
+ const moduleOrFactory = await module.get(idRes, expose, options, remoteSnapshot);
1374
1575
  const moduleWrapper = await this.hooks.lifecycle.onLoad.emit({
1375
1576
  id: idRes,
1376
1577
  pkgNameOrAlias,
@@ -1656,18 +1857,18 @@ class RemoteHandler {
1656
1857
  }
1657
1858
  }
1658
1859
  constructor(host){
1659
- this.hooks = new share.PluginSystem({
1660
- beforeRegisterRemote: new share.SyncWaterfallHook('beforeRegisterRemote'),
1661
- registerRemote: new share.SyncWaterfallHook('registerRemote'),
1662
- beforeRequest: new share.AsyncWaterfallHook('beforeRequest'),
1663
- onLoad: new share.AsyncHook('onLoad'),
1664
- handlePreloadModule: new share.SyncHook('handlePreloadModule'),
1665
- errorLoadRemote: new share.AsyncHook('errorLoadRemote'),
1666
- beforePreloadRemote: new share.AsyncHook('beforePreloadRemote'),
1667
- generatePreloadAssets: new share.AsyncHook('generatePreloadAssets'),
1860
+ this.hooks = new PluginSystem({
1861
+ beforeRegisterRemote: new SyncWaterfallHook('beforeRegisterRemote'),
1862
+ registerRemote: new SyncWaterfallHook('registerRemote'),
1863
+ beforeRequest: new AsyncWaterfallHook('beforeRequest'),
1864
+ onLoad: new AsyncHook('onLoad'),
1865
+ handlePreloadModule: new SyncHook('handlePreloadModule'),
1866
+ errorLoadRemote: new AsyncHook('errorLoadRemote'),
1867
+ beforePreloadRemote: new AsyncHook('beforePreloadRemote'),
1868
+ generatePreloadAssets: new AsyncHook('generatePreloadAssets'),
1668
1869
  // not used yet
1669
- afterPreloadRemote: new share.AsyncHook(),
1670
- loadEntry: new share.AsyncHook()
1870
+ afterPreloadRemote: new AsyncHook(),
1871
+ loadEntry: new AsyncHook()
1671
1872
  });
1672
1873
  this.host = host;
1673
1874
  this.idToRemoteMap = {};
@@ -1751,7 +1952,7 @@ class FederationHost {
1751
1952
  return optionsRes;
1752
1953
  }
1753
1954
  registerPlugins(plugins) {
1754
- const pluginRes = share.registerPlugins(plugins, [
1955
+ const pluginRes = registerPlugins$1(plugins, [
1755
1956
  this.hooks,
1756
1957
  this.remoteHandler.hooks,
1757
1958
  this.sharedHandler.hooks,
@@ -1771,23 +1972,23 @@ class FederationHost {
1771
1972
  return this.remoteHandler.registerRemotes(remotes, options);
1772
1973
  }
1773
1974
  constructor(userOptions){
1774
- this.hooks = new share.PluginSystem({
1775
- beforeInit: new share.SyncWaterfallHook('beforeInit'),
1776
- init: new share.SyncHook(),
1975
+ this.hooks = new PluginSystem({
1976
+ beforeInit: new SyncWaterfallHook('beforeInit'),
1977
+ init: new SyncHook(),
1777
1978
  // maybe will change, temporarily for internal use only
1778
- beforeInitContainer: new share.AsyncWaterfallHook('beforeInitContainer'),
1979
+ beforeInitContainer: new AsyncWaterfallHook('beforeInitContainer'),
1779
1980
  // maybe will change, temporarily for internal use only
1780
- initContainer: new share.AsyncWaterfallHook('initContainer')
1981
+ initContainer: new AsyncWaterfallHook('initContainer')
1781
1982
  });
1782
- this.version = "0.6.4";
1983
+ this.version = "0.6.5";
1783
1984
  this.moduleCache = new Map();
1784
- this.loaderHook = new share.PluginSystem({
1985
+ this.loaderHook = new PluginSystem({
1785
1986
  // FIXME: may not be suitable , not open to the public yet
1786
- getModuleInfo: new share.SyncHook(),
1787
- createScript: new share.SyncHook(),
1788
- createLink: new share.SyncHook(),
1987
+ getModuleInfo: new SyncHook(),
1988
+ createScript: new SyncHook(),
1989
+ createLink: new SyncHook(),
1789
1990
  // only work for manifest , so not open to the public yet
1790
- fetch: new share.AsyncHook()
1991
+ fetch: new AsyncHook()
1791
1992
  });
1792
1993
  // TODO: Validate the details of the options
1793
1994
  // Initialize options with default values
@@ -1884,6 +2085,7 @@ Object.defineProperty(exports, 'loadScriptNode', {
1884
2085
  });
1885
2086
  exports.registerGlobalPlugins = share.registerGlobalPlugins;
1886
2087
  exports.FederationHost = FederationHost;
2088
+ exports.Module = Module;
1887
2089
  exports.getInstance = getInstance;
1888
2090
  exports.getRemoteEntry = getRemoteEntry;
1889
2091
  exports.getRemoteInfo = getRemoteInfo;