@module-federation/runtime 1.0.0-canary.1

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.
Files changed (47) hide show
  1. package/helpers.cjs.d.ts +2 -0
  2. package/helpers.cjs.js +33 -0
  3. package/helpers.esm.js +31 -0
  4. package/index.cjs.d.ts +1 -0
  5. package/index.cjs.js +1927 -0
  6. package/index.esm.js +1917 -0
  7. package/package.json +40 -0
  8. package/share.cjs.js +782 -0
  9. package/share.esm.js +741 -0
  10. package/src/constant.d.ts +2 -0
  11. package/src/core.d.ts +113 -0
  12. package/src/global.d.ts +57 -0
  13. package/src/helpers.d.ts +32 -0
  14. package/src/index.d.ts +10 -0
  15. package/src/module/index.d.ts +25 -0
  16. package/src/plugins/generate-preload-assets.d.ts +8 -0
  17. package/src/plugins/snapshot/SnapshotHandler.d.ts +43 -0
  18. package/src/plugins/snapshot/index.d.ts +5 -0
  19. package/src/type/config.d.ts +94 -0
  20. package/src/type/index.d.ts +3 -0
  21. package/src/type/plugin.d.ts +20 -0
  22. package/src/type/preload.d.ts +25 -0
  23. package/src/types.d.ts +1 -0
  24. package/src/utils/dom.d.ts +8 -0
  25. package/src/utils/env.d.ts +4 -0
  26. package/src/utils/hooks/asyncHook.d.ts +6 -0
  27. package/src/utils/hooks/asyncWaterfallHooks.d.ts +10 -0
  28. package/src/utils/hooks/index.d.ts +6 -0
  29. package/src/utils/hooks/pluginSystem.d.ts +15 -0
  30. package/src/utils/hooks/syncHook.d.ts +12 -0
  31. package/src/utils/hooks/syncWaterfallHook.d.ts +9 -0
  32. package/src/utils/index.d.ts +6 -0
  33. package/src/utils/load.d.ts +17 -0
  34. package/src/utils/logger.d.ts +3 -0
  35. package/src/utils/manifest.d.ts +9 -0
  36. package/src/utils/plugin.d.ts +4 -0
  37. package/src/utils/preload.d.ts +6 -0
  38. package/src/utils/semver/compare.d.ts +9 -0
  39. package/src/utils/semver/constants.d.ts +10 -0
  40. package/src/utils/semver/index.d.ts +2 -0
  41. package/src/utils/semver/parser.d.ts +9 -0
  42. package/src/utils/semver/utils.d.ts +11 -0
  43. package/src/utils/share.d.ts +7 -0
  44. package/src/utils/tool.d.ts +12 -0
  45. package/type.cjs.d.ts +1 -0
  46. package/type.cjs.js +2 -0
  47. package/type.esm.js +1 -0
package/index.esm.js ADDED
@@ -0,0 +1,1917 @@
1
+ import { i as isStaticResourcesEqual, s as safeWrapper, g as getGlobalHostPlugins, _ as _extends, D as DEFAULT_REMOTE_TYPE, a as DEFAULT_SCOPE, b as globalLoading, c as getRemoteEntryExports, d as assert, e as safeToString$1, G as Global, f as getFMId, h as isObject, j as error, w as warn, k as isPlainObject, l as isRemoteInfoWithEntry, m as isPureRemoteEntry, n as getGlobalShare, o as getInfoWithoutType, p as getPreloaded, q as setPreloaded, r as getGlobalSnapshotInfoByModuleInfo, t as setGlobalSnapshotInfoByModuleInfo, u as getGlobalSnapshot, v as addUniqueItem, x as formatShareConfigs, y as isBrowserEnv$1, z as getGlobalShareScope, A as _object_without_properties_loose, B as getBuilderId, C as setGlobalFederationConstructor, E as getGlobalFederationInstance, F as getGlobalFederationConstructor, H as setGlobalFederationInstance } from './share.esm.js';
2
+ export { I as registerGlobalPlugins } from './share.esm.js';
3
+
4
+ function getResourceUrl(module, sourceUrl) {
5
+ if ('getPublicPath' in module) {
6
+ const publicPath = new Function(module.getPublicPath)();
7
+ return `${publicPath}${sourceUrl}`;
8
+ } else if ('publicPath' in module) {
9
+ return `${module.publicPath}${sourceUrl}`;
10
+ } else {
11
+ console.warn('Cannot get resource URL. If in debug mode, please ignore.', module, sourceUrl);
12
+ return '';
13
+ }
14
+ }
15
+ // id: pkgName(@federation/app1) + expose(button) = @federation/app1/button
16
+ // id: alias(app1) + expose(button) = app1/button
17
+ // id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort
18
+ function matchRemoteWithNameAndExpose(remotes, id) {
19
+ for (const remote of remotes){
20
+ // match pkgName
21
+ const matchNameSuccess = id.startsWith(remote.name);
22
+ let expose = id.replace(remote.name, '');
23
+ if (matchNameSuccess) {
24
+ if (expose.startsWith('/')) {
25
+ const pkgNameOrAlias = remote.name;
26
+ expose = `.${expose}`;
27
+ return {
28
+ pkgNameOrAlias,
29
+ expose,
30
+ remote
31
+ };
32
+ } else if (expose === '') {
33
+ return {
34
+ pkgNameOrAlias: remote.name,
35
+ expose: '.',
36
+ remote
37
+ };
38
+ }
39
+ }
40
+ // match alias
41
+ const matchAliasSuccess = remote.alias && id.startsWith(remote.alias);
42
+ let exposeWithAlias = remote.alias && id.replace(remote.alias, '');
43
+ if (remote.alias && matchAliasSuccess) {
44
+ if (exposeWithAlias && exposeWithAlias.startsWith('/')) {
45
+ const pkgNameOrAlias = remote.alias;
46
+ exposeWithAlias = `.${exposeWithAlias}`;
47
+ return {
48
+ pkgNameOrAlias,
49
+ expose: exposeWithAlias,
50
+ remote
51
+ };
52
+ } else if (exposeWithAlias === '') {
53
+ return {
54
+ pkgNameOrAlias: remote.alias,
55
+ expose: '.',
56
+ remote
57
+ };
58
+ }
59
+ }
60
+ }
61
+ return;
62
+ }
63
+ function matchRemote(remotes, nameOrAlias) {
64
+ for (const remote of remotes){
65
+ const matchNameSuccess = nameOrAlias === remote.name;
66
+ if (matchNameSuccess) {
67
+ return remote;
68
+ }
69
+ const matchAliasSuccess = remote.alias && nameOrAlias === remote.alias;
70
+ if (matchAliasSuccess) {
71
+ return remote;
72
+ }
73
+ }
74
+ return;
75
+ }
76
+
77
+ function createScript(url, cb, attrs, createScriptHook) {
78
+ // get the existing script element by src
79
+ let script = null;
80
+ let needAttach = true;
81
+ const scripts = document.getElementsByTagName('script');
82
+ for(let i = 0; i < scripts.length; i++){
83
+ const s = scripts[i];
84
+ const scriptSrc = s.getAttribute('src');
85
+ if (scriptSrc && isStaticResourcesEqual(scriptSrc, url)) {
86
+ script = s;
87
+ needAttach = false;
88
+ break;
89
+ }
90
+ }
91
+ if (!script) {
92
+ script = document.createElement('script');
93
+ script.type = 'text/javascript';
94
+ script.src = url;
95
+ if (createScriptHook) {
96
+ const createScriptRes = createScriptHook(url);
97
+ if (createScriptRes instanceof HTMLScriptElement) {
98
+ script = createScriptRes;
99
+ }
100
+ }
101
+ }
102
+ if (attrs) {
103
+ Object.keys(attrs).forEach((name)=>{
104
+ if (script) {
105
+ if (name === 'async' || name === 'defer') {
106
+ script[name] = attrs[name];
107
+ } else {
108
+ script.setAttribute(name, attrs[name]);
109
+ }
110
+ }
111
+ });
112
+ }
113
+ const onScriptComplete = (prev, // eslint-disable-next-line @typescript-eslint/no-explicit-any
114
+ event)=>{
115
+ // avoid memory leaks in IE.
116
+ if (script) {
117
+ script.onerror = null;
118
+ script.onload = null;
119
+ safeWrapper(()=>{
120
+ (script == null ? void 0 : script.parentNode) && script.parentNode.removeChild(script);
121
+ });
122
+ if (prev) {
123
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
124
+ const res = prev(event);
125
+ cb();
126
+ return res;
127
+ }
128
+ }
129
+ cb();
130
+ };
131
+ script.onerror = onScriptComplete.bind(null, script.onerror);
132
+ script.onload = onScriptComplete.bind(null, script.onload);
133
+ return {
134
+ script,
135
+ needAttach
136
+ };
137
+ }
138
+ function loadScript(url, info) {
139
+ const { attrs, createScriptHook } = info;
140
+ return new Promise((resolve, _reject)=>{
141
+ const { script, needAttach } = createScript(url, resolve, attrs, createScriptHook);
142
+ needAttach && document.getElementsByTagName('head')[0].appendChild(script);
143
+ });
144
+ }
145
+
146
+ function registerPlugins(plugins, hookInstances) {
147
+ const globalPlugins = getGlobalHostPlugins();
148
+ // Register global plugins
149
+ if (globalPlugins.length > 0) {
150
+ globalPlugins.forEach((plugin)=>{
151
+ if (plugins == null ? void 0 : plugins.find((item)=>item.name !== plugin.name)) {
152
+ plugins.push(plugin);
153
+ }
154
+ });
155
+ }
156
+ if (plugins && plugins.length > 0) {
157
+ plugins.forEach((plugin)=>{
158
+ hookInstances.forEach((hookInstance)=>{
159
+ hookInstance.usePlugin(plugin);
160
+ });
161
+ });
162
+ }
163
+ }
164
+
165
+ function _instanceof(left, right) {
166
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
167
+ return !!right[Symbol.hasInstance](left);
168
+ } else {
169
+ return left instanceof right;
170
+ }
171
+ }
172
+ function _define_property$2(obj, key, value) {
173
+ if (key in obj) {
174
+ Object.defineProperty(obj, key, {
175
+ value: value,
176
+ enumerable: true,
177
+ configurable: true,
178
+ writable: true
179
+ });
180
+ } else {
181
+ obj[key] = value;
182
+ }
183
+ return obj;
184
+ }
185
+ var MANIFEST_EXT = ".json";
186
+ var BROWSER_LOG_KEY = "''";
187
+ var BROWSER_LOG_VALUE = "1";
188
+ var NameTransformSymbol = {
189
+ AT: "@",
190
+ HYPHEN: "-",
191
+ SLASH: "/"
192
+ };
193
+ var _obj;
194
+ var NameTransformMap = (_obj = {}, _define_property$2(_obj, NameTransformSymbol.AT, "scope_"), _define_property$2(_obj, NameTransformSymbol.HYPHEN, "_"), _define_property$2(_obj, NameTransformSymbol.SLASH, "__"), _obj);
195
+ var _obj1;
196
+ (_obj1 = {}, _define_property$2(_obj1, NameTransformMap[NameTransformSymbol.AT], NameTransformSymbol.AT), _define_property$2(_obj1, NameTransformMap[NameTransformSymbol.HYPHEN], NameTransformSymbol.HYPHEN), _define_property$2(_obj1, NameTransformMap[NameTransformSymbol.SLASH], NameTransformSymbol.SLASH), _obj1);
197
+ var SEPARATOR = ":";
198
+ function isBrowserEnv() {
199
+ return typeof window !== "undefined";
200
+ }
201
+ function isDebugMode() {
202
+ if (typeof process !== "undefined" && process.env && process.env["''"]) {
203
+ return Boolean(process.env["''"]);
204
+ }
205
+ return Boolean('');
206
+ }
207
+ function _array_like_to_array$1(arr, len) {
208
+ if (len == null || len > arr.length) len = arr.length;
209
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
210
+ return arr2;
211
+ }
212
+ function _array_without_holes(arr) {
213
+ if (Array.isArray(arr)) return _array_like_to_array$1(arr);
214
+ }
215
+ function _class_call_check(instance, Constructor) {
216
+ if (!_instanceof(instance, Constructor)) {
217
+ throw new TypeError("Cannot call a class as a function");
218
+ }
219
+ }
220
+ function _defineProperties(target, props) {
221
+ for(var i = 0; i < props.length; i++){
222
+ var descriptor = props[i];
223
+ descriptor.enumerable = descriptor.enumerable || false;
224
+ descriptor.configurable = true;
225
+ if ("value" in descriptor) descriptor.writable = true;
226
+ Object.defineProperty(target, descriptor.key, descriptor);
227
+ }
228
+ }
229
+ function _create_class(Constructor, protoProps, staticProps) {
230
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
231
+ if (staticProps) _defineProperties(Constructor, staticProps);
232
+ return Constructor;
233
+ }
234
+ function _define_property$1(obj, key, value) {
235
+ if (key in obj) {
236
+ Object.defineProperty(obj, key, {
237
+ value: value,
238
+ enumerable: true,
239
+ configurable: true,
240
+ writable: true
241
+ });
242
+ } else {
243
+ obj[key] = value;
244
+ }
245
+ return obj;
246
+ }
247
+ function _iterable_to_array$1(iter) {
248
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
249
+ }
250
+ function _non_iterable_spread() {
251
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
252
+ }
253
+ function _to_consumable_array(arr) {
254
+ return _array_without_holes(arr) || _iterable_to_array$1(arr) || _unsupported_iterable_to_array$1(arr) || _non_iterable_spread();
255
+ }
256
+ function _unsupported_iterable_to_array$1(o, minLen) {
257
+ if (!o) return;
258
+ if (typeof o === "string") return _array_like_to_array$1(o, minLen);
259
+ var n = Object.prototype.toString.call(o).slice(8, -1);
260
+ if (n === "Object" && o.constructor) n = o.constructor.name;
261
+ if (n === "Map" || n === "Set") return Array.from(n);
262
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$1(o, minLen);
263
+ }
264
+ function safeToString(info) {
265
+ try {
266
+ return JSON.stringify(info, null, 2);
267
+ } catch (e) {
268
+ return "";
269
+ }
270
+ }
271
+ var DEBUG_LOG = "[ FEDERATION DEBUG ]";
272
+ var Logger = /*#__PURE__*/ function() {
273
+ function Logger(identifier) {
274
+ _class_call_check(this, Logger);
275
+ _define_property$1(this, "enable", false);
276
+ _define_property$1(this, "identifier", void 0);
277
+ this.identifier = identifier || DEBUG_LOG;
278
+ if (isBrowserEnv() && localStorage.getItem(BROWSER_LOG_KEY) === BROWSER_LOG_VALUE) {
279
+ this.enable = true;
280
+ } else if (isDebugMode()) {
281
+ this.enable = true;
282
+ }
283
+ }
284
+ _create_class(Logger, [
285
+ {
286
+ key: "info",
287
+ value: function info(msg, info) {
288
+ if (this.enable) {
289
+ var argsToString = safeToString(info) || "";
290
+ if (isBrowserEnv()) {
291
+ console.info("%c ".concat(this.identifier, ": ").concat(msg, " ").concat(argsToString), "color:#3300CC");
292
+ } else {
293
+ console.info("\x1b[34m%s", "".concat(this.identifier, ": ").concat(msg, " ").concat(argsToString ? "\n".concat(argsToString) : ""));
294
+ }
295
+ }
296
+ }
297
+ },
298
+ {
299
+ key: "logOriginalInfo",
300
+ value: function logOriginalInfo() {
301
+ for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
302
+ args[_key] = arguments[_key];
303
+ }
304
+ if (this.enable) {
305
+ if (isBrowserEnv()) {
306
+ var _console;
307
+ console.info("%c ".concat(this.identifier, ": OriginalInfo"), "color:#3300CC");
308
+ (_console = console).log.apply(_console, _to_consumable_array(args));
309
+ } else {
310
+ var _console1;
311
+ console.info("%c ".concat(this.identifier, ": OriginalInfo"), "color:#3300CC");
312
+ (_console1 = console).log.apply(_console1, _to_consumable_array(args));
313
+ }
314
+ }
315
+ }
316
+ }
317
+ ]);
318
+ return Logger;
319
+ }();
320
+ new Logger();
321
+ var composeKeyWithSeparator = function composeKeyWithSeparator() {
322
+ for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
323
+ args[_key] = arguments[_key];
324
+ }
325
+ if (!args.length) {
326
+ return "";
327
+ }
328
+ return args.reduce(function(sum, cur) {
329
+ if (!cur) {
330
+ return sum;
331
+ }
332
+ if (!sum) {
333
+ return cur;
334
+ }
335
+ return "".concat(sum).concat(SEPARATOR).concat(cur);
336
+ }, "");
337
+ };
338
+ function _define_property(obj, key, value) {
339
+ if (key in obj) {
340
+ Object.defineProperty(obj, key, {
341
+ value: value,
342
+ enumerable: true,
343
+ configurable: true,
344
+ writable: true
345
+ });
346
+ } else {
347
+ obj[key] = value;
348
+ }
349
+ return obj;
350
+ }
351
+ function _object_spread(target) {
352
+ for(var i = 1; i < arguments.length; i++){
353
+ var source = arguments[i] != null ? arguments[i] : {};
354
+ var ownKeys = Object.keys(source);
355
+ if (typeof Object.getOwnPropertySymbols === "function") {
356
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
357
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
358
+ }));
359
+ }
360
+ ownKeys.forEach(function(key) {
361
+ _define_property(target, key, source[key]);
362
+ });
363
+ }
364
+ return target;
365
+ }
366
+ function ownKeys(object, enumerableOnly) {
367
+ var keys = Object.keys(object);
368
+ if (Object.getOwnPropertySymbols) {
369
+ var symbols = Object.getOwnPropertySymbols(object);
370
+ if (enumerableOnly) {
371
+ symbols = symbols.filter(function(sym) {
372
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
373
+ });
374
+ }
375
+ keys.push.apply(keys, symbols);
376
+ }
377
+ return keys;
378
+ }
379
+ function _object_spread_props(target, source) {
380
+ source = source != null ? source : {};
381
+ if (Object.getOwnPropertyDescriptors) {
382
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
383
+ } else {
384
+ ownKeys(Object(source)).forEach(function(key) {
385
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
386
+ });
387
+ }
388
+ return target;
389
+ }
390
+ var simpleJoinRemoteEntry = function simpleJoinRemoteEntry(rPath, rName) {
391
+ if (!rPath) {
392
+ return rName;
393
+ }
394
+ var transformPath = function transformPath(str) {
395
+ if (str === ".") {
396
+ return "";
397
+ }
398
+ if (str.startsWith("./")) {
399
+ return str.replace("./", "");
400
+ }
401
+ if (str.startsWith("/")) {
402
+ var strWithoutSlash = str.slice(1);
403
+ if (strWithoutSlash.endsWith("/")) {
404
+ return strWithoutSlash.slice(0, -1);
405
+ }
406
+ return strWithoutSlash;
407
+ }
408
+ return str;
409
+ };
410
+ var transformedPath = transformPath(rPath);
411
+ if (!transformedPath) {
412
+ return rName;
413
+ }
414
+ if (transformedPath.endsWith("/")) {
415
+ return "".concat(transformedPath).concat(rName);
416
+ }
417
+ return "".concat(transformedPath, "/").concat(rName);
418
+ };
419
+ // 优先级:overrides > remotes
420
+ // eslint-disable-next-line max-lines-per-function
421
+ function generateSnapshotFromManifest(manifest) {
422
+ var options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
423
+ var _options_remotes = options.remotes, remotes = _options_remotes === void 0 ? {} : _options_remotes, _options_overrides = options.overrides, overrides = _options_overrides === void 0 ? {} : _options_overrides, version = options.version;
424
+ var remoteSnapshot;
425
+ var getPublicPath = function getPublicPath() {
426
+ if ("publicPath" in manifest.metaData) {
427
+ return manifest.metaData.publicPath;
428
+ } else {
429
+ return manifest.metaData.getPublicPath;
430
+ }
431
+ };
432
+ var overridesKeys = Object.keys(overrides);
433
+ var remotesInfo = {};
434
+ // If remotes are not passed, only the remotes in the manifest will be read
435
+ if (!Object.keys(remotes).length) {
436
+ var _manifest_remotes;
437
+ remotesInfo = ((_manifest_remotes = manifest.remotes) === null || _manifest_remotes === void 0 ? void 0 : _manifest_remotes.reduce(function(res, next) {
438
+ var matchedVersion;
439
+ var name = next.federationContainerName;
440
+ // overrides has hight priority
441
+ if (overridesKeys.includes(name)) {
442
+ matchedVersion = overrides[name];
443
+ } else {
444
+ if ("version" in next) {
445
+ matchedVersion = next.version;
446
+ } else {
447
+ matchedVersion = next.entry;
448
+ }
449
+ }
450
+ res[name] = {
451
+ matchedVersion: matchedVersion
452
+ };
453
+ return res;
454
+ }, {})) || {};
455
+ }
456
+ // If remotes (deploy scenario) are specified, you need to traverse it again
457
+ Object.keys(remotes).forEach(function(key) {
458
+ return remotesInfo[key] = {
459
+ // overrides will override dependencies
460
+ matchedVersion: overridesKeys.includes(key) ? overrides[key] : remotes[key]
461
+ };
462
+ });
463
+ var _manifest_metaData = manifest.metaData, _manifest_metaData_remoteEntry = _manifest_metaData.remoteEntry, remoteEntryPath = _manifest_metaData_remoteEntry.path, remoteEntryName = _manifest_metaData_remoteEntry.name, remoteEntryType = _manifest_metaData_remoteEntry.type, remoteTypes = _manifest_metaData.types, buildVersion = _manifest_metaData.buildInfo.buildVersion, globalName = _manifest_metaData.globalName;
464
+ var exposes = manifest.exposes;
465
+ var basicRemoteSnapshot = {
466
+ version: version ? version : "",
467
+ buildVersion: buildVersion,
468
+ globalName: globalName,
469
+ remoteEntry: simpleJoinRemoteEntry(remoteEntryPath, remoteEntryName),
470
+ remoteEntryType: remoteEntryType,
471
+ remoteTypes: simpleJoinRemoteEntry(remoteTypes.path, remoteTypes.name),
472
+ remotesInfo: remotesInfo,
473
+ shared: manifest === null || manifest === void 0 ? void 0 : manifest.shared.map(function(item) {
474
+ return {
475
+ assets: item.assets,
476
+ sharedName: item.name
477
+ };
478
+ }),
479
+ modules: exposes === null || exposes === void 0 ? void 0 : exposes.map(function(expose) {
480
+ return {
481
+ moduleName: expose.name,
482
+ modulePath: expose.path,
483
+ assets: expose.assets
484
+ };
485
+ })
486
+ };
487
+ if ("publicPath" in manifest.metaData) {
488
+ remoteSnapshot = _object_spread_props(_object_spread({}, basicRemoteSnapshot), {
489
+ publicPath: getPublicPath()
490
+ });
491
+ } else {
492
+ remoteSnapshot = _object_spread_props(_object_spread({}, basicRemoteSnapshot), {
493
+ getPublicPath: getPublicPath()
494
+ });
495
+ }
496
+ return remoteSnapshot;
497
+ }
498
+ function isManifestProvider(moduleInfo) {
499
+ if ("remoteEntry" in moduleInfo && moduleInfo.remoteEntry.endsWith(MANIFEST_EXT)) {
500
+ return true;
501
+ } else {
502
+ return false;
503
+ }
504
+ }
505
+
506
+ async function loadEsmEntry({ entry, remoteEntryExports }) {
507
+ return new Promise((resolve, reject)=>{
508
+ try {
509
+ if (!remoteEntryExports) {
510
+ // eslint-disable-next-line no-eval
511
+ new Function('resolve', `import("${entry}").then((res)=>{resolve(res);}, (error)=> reject(error))`)(resolve);
512
+ } else {
513
+ resolve(remoteEntryExports);
514
+ }
515
+ } catch (e) {
516
+ reject(e);
517
+ }
518
+ });
519
+ }
520
+ async function loadEntryScript({ name, globalName, entry, createScriptHook }) {
521
+ const { entryExports: remoteEntryExports } = getRemoteEntryExports(name, globalName);
522
+ if (remoteEntryExports) {
523
+ return remoteEntryExports;
524
+ }
525
+ return loadScript(entry, {
526
+ attrs: {},
527
+ createScriptHook
528
+ }).then(()=>{
529
+ const { remoteEntryKey, entryExports } = getRemoteEntryExports(name, globalName);
530
+ assert(entryExports, `
531
+ Cannot use the ${name}'s '${entry}' URL with ${remoteEntryKey}'s globalName to get remoteEntry exports.
532
+ The following reasons may be causing the problem:\n
533
+ 1. '${entry}' is not the correct URL, or the remoteEntry resource or name is incorrect.\n
534
+ 2. Unable to use ${remoteEntryKey} to get remoteEntry exports in the window object.
535
+ `);
536
+ return entryExports;
537
+ });
538
+ }
539
+ async function getRemoteEntry({ remoteEntryExports, remoteInfo, createScriptHook }) {
540
+ const { entry, name, type, entryGlobalName } = remoteInfo;
541
+ const uniqueKey = composeKeyWithSeparator(name, entry);
542
+ if (remoteEntryExports) {
543
+ return remoteEntryExports;
544
+ }
545
+ if (!globalLoading[uniqueKey]) {
546
+ if (type === 'esm') {
547
+ globalLoading[uniqueKey] = loadEsmEntry({
548
+ entry,
549
+ remoteEntryExports
550
+ });
551
+ } else {
552
+ globalLoading[uniqueKey] = loadEntryScript({
553
+ name,
554
+ globalName: entryGlobalName,
555
+ entry,
556
+ createScriptHook
557
+ });
558
+ }
559
+ }
560
+ return globalLoading[uniqueKey];
561
+ }
562
+ function getRemoteInfo(remote) {
563
+ return _extends({}, remote, {
564
+ entry: 'entry' in remote ? remote.entry : '',
565
+ type: remote.type || DEFAULT_REMOTE_TYPE,
566
+ entryGlobalName: remote.entryGlobalName || remote.name,
567
+ shareScope: remote.shareScope || DEFAULT_SCOPE
568
+ });
569
+ }
570
+
571
+ let Module = class Module {
572
+ async getEntry() {
573
+ if (this.remoteEntryExports) {
574
+ return this.remoteEntryExports;
575
+ }
576
+ // Get remoteEntry.js
577
+ const remoteEntryExports = await getRemoteEntry({
578
+ remoteInfo: this.remoteInfo,
579
+ remoteEntryExports: this.remoteEntryExports,
580
+ createScriptHook: (url)=>{
581
+ const res = this.loaderHook.lifecycle.createScript.emit({
582
+ url
583
+ });
584
+ if (res instanceof HTMLScriptElement) {
585
+ return res;
586
+ }
587
+ return;
588
+ }
589
+ });
590
+ assert(remoteEntryExports, `remoteEntryExports is undefined \n ${safeToString$1(this.remoteInfo)}`);
591
+ this.remoteEntryExports = remoteEntryExports;
592
+ return this.remoteEntryExports;
593
+ }
594
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
595
+ async get(expose, options) {
596
+ const { loadFactory = true } = options || {
597
+ loadFactory: true
598
+ };
599
+ // Get remoteEntry.js
600
+ const remoteEntryExports = await this.getEntry();
601
+ if (!this.inited) {
602
+ const globalShareScope = Global.__FEDERATION__.__SHARE__;
603
+ const remoteShareScope = this.remoteInfo.shareScope || 'default';
604
+ if (!globalShareScope[remoteShareScope]) {
605
+ globalShareScope[remoteShareScope] = {};
606
+ }
607
+ const shareScope = globalShareScope[remoteShareScope];
608
+ // TODO: compat logic , it could be moved after providing startup hooks
609
+ const remoteEntryInitOptions = {
610
+ version: this.remoteInfo.version || '',
611
+ // @ts-ignore it will be passed by startup hooks
612
+ region: this.hostInfo.region
613
+ };
614
+ remoteEntryExports.init(shareScope, [], remoteEntryInitOptions);
615
+ const federationInstance = Global.__FEDERATION__.__INSTANCES__.find((i)=>i.options.id === composeKeyWithSeparator(this.remoteInfo.name, this.remoteInfo.buildVersion));
616
+ if (federationInstance) {
617
+ federationInstance.initOptions(_extends({}, remoteEntryInitOptions, {
618
+ remotes: [],
619
+ name: this.remoteInfo.name
620
+ }));
621
+ }
622
+ }
623
+ this.lib = remoteEntryExports;
624
+ this.inited = true;
625
+ // get exposeGetter
626
+ const moduleFactory = await remoteEntryExports.get(expose);
627
+ assert(moduleFactory, `${getFMId(this.remoteInfo)} remote don't export ${expose}.`);
628
+ if (!loadFactory) {
629
+ return moduleFactory;
630
+ }
631
+ const exposeContent = await moduleFactory();
632
+ return exposeContent;
633
+ }
634
+ // loading: Record<string, undefined | Promise<RemoteEntryExports | void>> = {};
635
+ constructor({ hostInfo, remoteInfo, shared, loaderHook }){
636
+ this.inited = false;
637
+ this.shared = {};
638
+ this.lib = undefined;
639
+ this.hostInfo = hostInfo;
640
+ this.remoteInfo = remoteInfo;
641
+ this.shared = shared;
642
+ this.loaderHook = loaderHook;
643
+ }
644
+ };
645
+
646
+ class SyncHook {
647
+ on(fn) {
648
+ if (typeof fn === 'function') {
649
+ this.listeners.add(fn);
650
+ }
651
+ }
652
+ once(fn) {
653
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
654
+ const self = this;
655
+ this.on(function wrapper(...args) {
656
+ self.remove(wrapper);
657
+ // eslint-disable-next-line prefer-spread
658
+ return fn.apply(null, args);
659
+ });
660
+ }
661
+ emit(...data) {
662
+ let result;
663
+ if (this.listeners.size > 0) {
664
+ // eslint-disable-next-line prefer-spread
665
+ this.listeners.forEach((fn)=>{
666
+ result = fn(...data);
667
+ });
668
+ }
669
+ return result;
670
+ }
671
+ remove(fn) {
672
+ this.listeners.delete(fn);
673
+ }
674
+ removeAll() {
675
+ this.listeners.clear();
676
+ }
677
+ constructor(type){
678
+ this.type = '';
679
+ this.listeners = new Set();
680
+ if (type) {
681
+ this.type = type;
682
+ }
683
+ }
684
+ }
685
+
686
+ class AsyncHook extends SyncHook {
687
+ emit(...data) {
688
+ let result;
689
+ const ls = Array.from(this.listeners);
690
+ if (ls.length > 0) {
691
+ let i = 0;
692
+ const call = (prev)=>{
693
+ if (prev === false) {
694
+ return false; // Abort process
695
+ } else if (i < ls.length) {
696
+ return Promise.resolve(ls[i++].apply(null, data)).then(call);
697
+ } else {
698
+ return prev;
699
+ }
700
+ };
701
+ result = call();
702
+ }
703
+ return Promise.resolve(result);
704
+ }
705
+ }
706
+
707
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
708
+ function checkReturnData(originData, returnData) {
709
+ if (!isObject(returnData)) {
710
+ return false;
711
+ }
712
+ if (originData !== returnData) {
713
+ // eslint-disable-next-line no-restricted-syntax
714
+ for(const key in originData){
715
+ if (!(key in returnData)) {
716
+ return false;
717
+ }
718
+ }
719
+ }
720
+ return true;
721
+ }
722
+ class SyncWaterfallHook extends SyncHook {
723
+ emit(data) {
724
+ if (!isObject(data)) {
725
+ error(`"${this.type}" hook response data must be an object.`);
726
+ }
727
+ for (const fn of this.listeners){
728
+ try {
729
+ const tempData = fn(data);
730
+ if (checkReturnData(data, tempData)) {
731
+ data = tempData;
732
+ } else {
733
+ this.onerror(`The "${this.type}" type has a plugin return value error.`);
734
+ break;
735
+ }
736
+ } catch (e) {
737
+ warn(e);
738
+ this.onerror(e);
739
+ }
740
+ }
741
+ return data;
742
+ }
743
+ constructor(type){
744
+ super();
745
+ this.onerror = error;
746
+ this.type = type;
747
+ }
748
+ }
749
+
750
+ class AsyncWaterfallHook extends SyncHook {
751
+ emit(data) {
752
+ if (!isObject(data)) {
753
+ error(`"${this.type}" hook response data must be an object.`);
754
+ }
755
+ const ls = Array.from(this.listeners);
756
+ if (ls.length > 0) {
757
+ let i = 0;
758
+ const processError = (e)=>{
759
+ warn(e);
760
+ this.onerror(e);
761
+ return data;
762
+ };
763
+ const call = (prevData)=>{
764
+ if (checkReturnData(data, prevData)) {
765
+ data = prevData;
766
+ if (i < ls.length) {
767
+ try {
768
+ return Promise.resolve(ls[i++](data)).then(call, processError);
769
+ } catch (e) {
770
+ return processError(e);
771
+ }
772
+ }
773
+ } else {
774
+ this.onerror(`The "${this.type}" type has a plugin return value error.`);
775
+ }
776
+ return data;
777
+ };
778
+ return Promise.resolve(call(data));
779
+ }
780
+ return Promise.resolve(data);
781
+ }
782
+ constructor(type){
783
+ super();
784
+ this.onerror = error;
785
+ this.type = type;
786
+ }
787
+ }
788
+
789
+ class PluginSystem {
790
+ usePlugin(plugin) {
791
+ assert(isPlainObject(plugin), 'Invalid plugin configuration.');
792
+ // The plugin name is required and must be unique
793
+ const pluginName = plugin.name;
794
+ assert(pluginName, 'Plugin must provide a name.');
795
+ if (!this.registerPlugins[pluginName]) {
796
+ this.registerPlugins[pluginName] = plugin;
797
+ Object.keys(this.lifecycle).forEach((key)=>{
798
+ const pluginLife = plugin[key];
799
+ if (pluginLife) {
800
+ this.lifecycle[key].on(pluginLife);
801
+ }
802
+ });
803
+ }
804
+ }
805
+ removePlugin(pluginName) {
806
+ assert(pluginName, 'Must provide a name.');
807
+ const plugin = this.registerPlugins[pluginName];
808
+ assert(plugin, `plugin "${pluginName}" is not registered.`);
809
+ Object.keys(plugin).forEach((key)=>{
810
+ if (key !== 'name') {
811
+ this.lifecycle[key].remove(plugin[key]);
812
+ }
813
+ });
814
+ }
815
+ // eslint-disable-next-line @typescript-eslint/no-shadow
816
+ inherit({ lifecycle, registerPlugins }) {
817
+ Object.keys(lifecycle).forEach((hookName)=>{
818
+ assert(!this.lifecycle[hookName], `"${hookName}" hook has conflict and cannot be inherited.`);
819
+ this.lifecycle[hookName] = lifecycle[hookName];
820
+ });
821
+ Object.keys(registerPlugins).forEach((pluginName)=>{
822
+ assert(!this.registerPlugins[pluginName], `"${pluginName}" plugin has conflict and cannot be inherited.`);
823
+ this.usePlugin(registerPlugins[pluginName]);
824
+ });
825
+ }
826
+ constructor(lifecycle){
827
+ this.registerPlugins = {};
828
+ this.lifecycle = lifecycle;
829
+ this.lifecycleKeys = Object.keys(lifecycle);
830
+ }
831
+ }
832
+
833
+ function defaultPreloadArgs(preloadConfig) {
834
+ return _extends({
835
+ resourceCategory: 'sync',
836
+ share: true,
837
+ depsRemote: true
838
+ }, preloadConfig);
839
+ }
840
+ function formatPreloadArgs(remotes, preloadArgs) {
841
+ // let preloadOps: PreloadOptions;
842
+ return preloadArgs.map((args)=>{
843
+ const remoteInfo = matchRemote(remotes, args.nameOrAlias);
844
+ assert(remoteInfo, `can't preload ${args.nameOrAlias},it is no't include in ${!remoteInfo && safeToString$1({
845
+ remoteInfo,
846
+ remotes
847
+ })} `);
848
+ return {
849
+ remote: remoteInfo,
850
+ preloadConfig: defaultPreloadArgs(args)
851
+ };
852
+ });
853
+ }
854
+ function normalizePreloadExposes(exposes) {
855
+ if (!exposes) {
856
+ return [];
857
+ }
858
+ return exposes.map((expose)=>{
859
+ if (expose === '.') {
860
+ return expose;
861
+ }
862
+ if (expose.startsWith('./')) {
863
+ return expose.replace('./', '');
864
+ }
865
+ return expose;
866
+ });
867
+ }
868
+ function preloadAssets(remoteInfo, host, assets) {
869
+ const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets;
870
+ if (host.options.inBrowser) {
871
+ entryAssets.forEach((asset)=>{
872
+ const { moduleInfo } = asset;
873
+ const module = host.moduleCache.get(remoteInfo.name);
874
+ if (module) {
875
+ getRemoteEntry({
876
+ remoteInfo: moduleInfo,
877
+ remoteEntryExports: module.remoteEntryExports,
878
+ createScriptHook: (url)=>{
879
+ const res = host.loaderHook.lifecycle.createScript.emit({
880
+ url
881
+ });
882
+ if (res instanceof HTMLScriptElement) {
883
+ return res;
884
+ }
885
+ return;
886
+ }
887
+ });
888
+ } else {
889
+ getRemoteEntry({
890
+ remoteInfo: moduleInfo,
891
+ remoteEntryExports: undefined,
892
+ createScriptHook: (url)=>{
893
+ const res = host.loaderHook.lifecycle.createScript.emit({
894
+ url
895
+ });
896
+ if (res instanceof HTMLScriptElement) {
897
+ return res;
898
+ }
899
+ return;
900
+ }
901
+ });
902
+ }
903
+ });
904
+ const fragment = document.createDocumentFragment();
905
+ cssAssets.forEach((cssUrl)=>{
906
+ const cssEl = document.createElement('link');
907
+ cssEl.setAttribute('rel', 'preload');
908
+ cssEl.setAttribute('href', cssUrl);
909
+ cssEl.setAttribute('as', 'style');
910
+ cssEl.setAttribute('crossorigin', 'anonymous');
911
+ fragment.appendChild(cssEl);
912
+ });
913
+ document.head.appendChild(fragment);
914
+ jsAssetsWithoutEntry.forEach((jsUrl)=>{
915
+ const { script: scriptEl } = createScript(jsUrl, ()=>{
916
+ // noop
917
+ }, {}, (url)=>{
918
+ const res = host.loaderHook.lifecycle.createScript.emit({
919
+ url
920
+ });
921
+ if (res instanceof HTMLScriptElement) {
922
+ return res;
923
+ }
924
+ return;
925
+ });
926
+ document.head.appendChild(scriptEl);
927
+ });
928
+ }
929
+ }
930
+
931
+ function assignRemoteInfo(remoteInfo, remoteSnapshot) {
932
+ if (!('remoteEntry' in remoteSnapshot) || !remoteSnapshot.remoteEntry) {
933
+ error(`The remoteEntry attribute of ${name} cannot be undefined.`);
934
+ }
935
+ const { remoteEntry } = remoteSnapshot;
936
+ const entryUrl = getResourceUrl(remoteSnapshot, remoteEntry);
937
+ remoteInfo.type = remoteSnapshot.remoteEntryType;
938
+ remoteInfo.entryGlobalName = remoteSnapshot.globalName;
939
+ remoteInfo.entry = entryUrl;
940
+ remoteInfo.version = remoteSnapshot.version;
941
+ remoteInfo.buildVersion = remoteSnapshot.buildVersion;
942
+ }
943
+ function snapshotPlugin() {
944
+ return {
945
+ name: 'snapshot-plugin',
946
+ async loadRemoteMatch (args) {
947
+ const { remote, pkgNameOrAlias, expose, origin, remoteInfo } = args;
948
+ if (!isRemoteInfoWithEntry(remote) || !isPureRemoteEntry(remote)) {
949
+ const { remoteSnapshot, globalSnapshot } = await origin.snapshotHandler.loadRemoteSnapshotInfo(remote);
950
+ assignRemoteInfo(remoteInfo, remoteSnapshot);
951
+ // preload assets
952
+ const preloadOptions = {
953
+ remote,
954
+ preloadConfig: {
955
+ nameOrAlias: pkgNameOrAlias,
956
+ exposes: [
957
+ expose
958
+ ],
959
+ resourceCategory: 'sync',
960
+ share: false,
961
+ depsRemote: false
962
+ }
963
+ };
964
+ const assets = await origin.hooks.lifecycle.generatePreloadAssets.emit({
965
+ origin,
966
+ preloadOptions,
967
+ remoteInfo,
968
+ remote,
969
+ remoteSnapshot,
970
+ globalSnapshot
971
+ });
972
+ if (assets) {
973
+ preloadAssets(remoteInfo, origin, assets);
974
+ }
975
+ }
976
+ return args;
977
+ }
978
+ };
979
+ }
980
+
981
+ // name
982
+ // name:version
983
+ function splitId(id) {
984
+ const splitInfo = id.split(':');
985
+ if (splitInfo.length === 1) {
986
+ return {
987
+ name: splitInfo[0],
988
+ version: undefined
989
+ };
990
+ } else if (splitInfo.length === 2) {
991
+ return {
992
+ name: splitInfo[0],
993
+ version: splitInfo[1]
994
+ };
995
+ } else {
996
+ return {
997
+ name: splitInfo[1],
998
+ version: splitInfo[2]
999
+ };
1000
+ }
1001
+ }
1002
+ // Traverse all nodes through moduleInfo and traverse the entire snapshot
1003
+ function traverseModuleInfo(globalSnapshot, remoteInfo, traverse, isRoot, memo = {}, remoteSnapshot, getModuleInfoHook) {
1004
+ const id = getFMId(remoteInfo);
1005
+ const { value: snapshotValue } = getInfoWithoutType(globalSnapshot, id, getModuleInfoHook);
1006
+ const effectRemoteSnapshot = remoteSnapshot || snapshotValue;
1007
+ if (effectRemoteSnapshot && !isManifestProvider(effectRemoteSnapshot)) {
1008
+ traverse(effectRemoteSnapshot, remoteInfo, isRoot);
1009
+ if (effectRemoteSnapshot.remotesInfo) {
1010
+ const remoteKeys = Object.keys(effectRemoteSnapshot.remotesInfo);
1011
+ for (const key of remoteKeys){
1012
+ if (memo[key]) {
1013
+ continue;
1014
+ }
1015
+ memo[key] = true;
1016
+ const subRemoteInfo = splitId(key);
1017
+ const remoteValue = effectRemoteSnapshot.remotesInfo[key];
1018
+ traverseModuleInfo(globalSnapshot, {
1019
+ name: subRemoteInfo.name,
1020
+ version: remoteValue.matchedVersion
1021
+ }, traverse, false, memo, undefined, getModuleInfoHook);
1022
+ }
1023
+ }
1024
+ }
1025
+ }
1026
+ // eslint-disable-next-line max-lines-per-function
1027
+ function generatePreloadAssets(origin, preloadOptions, remote, globalSnapshot, remoteSnapshot) {
1028
+ const cssAssets = [];
1029
+ const jsAssets = [];
1030
+ const entryAssets = [];
1031
+ const loadedSharedJsAssets = new Set();
1032
+ const loadedSharedCssAssets = new Set();
1033
+ const { options } = origin;
1034
+ const { preloadConfig: rootPreloadConfig } = preloadOptions;
1035
+ const { depsRemote } = rootPreloadConfig;
1036
+ const memo = {};
1037
+ traverseModuleInfo(globalSnapshot, remote, (moduleInfoSnapshot, remoteInfo, isRoot)=>{
1038
+ let preloadConfig;
1039
+ if (isRoot) {
1040
+ preloadConfig = rootPreloadConfig;
1041
+ } else {
1042
+ if (Array.isArray(depsRemote)) {
1043
+ // eslint-disable-next-line array-callback-return
1044
+ const findPreloadConfig = depsRemote.find((remoteConfig)=>{
1045
+ if (remoteConfig.nameOrAlias === remoteInfo.name || remoteConfig.nameOrAlias === remoteInfo.alias) {
1046
+ return true;
1047
+ }
1048
+ return false;
1049
+ });
1050
+ if (!findPreloadConfig) {
1051
+ return;
1052
+ }
1053
+ preloadConfig = defaultPreloadArgs(findPreloadConfig);
1054
+ } else if (depsRemote === true) {
1055
+ preloadConfig = rootPreloadConfig;
1056
+ } else {
1057
+ return;
1058
+ }
1059
+ }
1060
+ const remoteEntryUrl = getResourceUrl(moduleInfoSnapshot, 'remoteEntry' in moduleInfoSnapshot ? moduleInfoSnapshot.remoteEntry : '');
1061
+ if (remoteEntryUrl) {
1062
+ entryAssets.push({
1063
+ name: remoteInfo.name,
1064
+ moduleInfo: {
1065
+ name: remoteInfo.name,
1066
+ entry: remoteEntryUrl,
1067
+ type: 'remoteEntryType' in moduleInfoSnapshot ? moduleInfoSnapshot.remoteEntryType : 'global',
1068
+ entryGlobalName: 'globalName' in moduleInfoSnapshot ? moduleInfoSnapshot.globalName : remoteInfo.name,
1069
+ shareScope: '',
1070
+ version: 'version' in moduleInfoSnapshot ? moduleInfoSnapshot.version : undefined
1071
+ },
1072
+ url: remoteEntryUrl
1073
+ });
1074
+ }
1075
+ let moduleAssetsInfo = 'modules' in moduleInfoSnapshot ? moduleInfoSnapshot.modules : [];
1076
+ const normalizedPreloadExposes = normalizePreloadExposes(preloadConfig.exposes);
1077
+ if (normalizedPreloadExposes.length && 'modules' in moduleInfoSnapshot) {
1078
+ var _moduleInfoSnapshot_modules;
1079
+ moduleAssetsInfo = moduleInfoSnapshot == null ? void 0 : (_moduleInfoSnapshot_modules = moduleInfoSnapshot.modules) == null ? void 0 : _moduleInfoSnapshot_modules.reduce((assets, moduleAssetInfo)=>{
1080
+ if ((normalizedPreloadExposes == null ? void 0 : normalizedPreloadExposes.indexOf(moduleAssetInfo.moduleName)) !== -1) {
1081
+ assets.push(moduleAssetInfo);
1082
+ }
1083
+ return assets;
1084
+ }, []);
1085
+ }
1086
+ function handlerAssets(assets) {
1087
+ const assetsRes = assets.map((asset)=>getResourceUrl(moduleInfoSnapshot, asset));
1088
+ if (preloadConfig.filter) {
1089
+ return assetsRes.filter(preloadConfig.filter);
1090
+ }
1091
+ return assetsRes;
1092
+ }
1093
+ if (moduleAssetsInfo) {
1094
+ const assetsLength = moduleAssetsInfo.length;
1095
+ for(let index = 0; index < assetsLength; index++){
1096
+ const assetsInfo = moduleAssetsInfo[index];
1097
+ // for (const assetsInfo of moduleAssetsInfo) {
1098
+ const exposeFullPath = `${remoteInfo.name}/${assetsInfo.moduleName}`;
1099
+ const preloaded = getPreloaded(exposeFullPath);
1100
+ if (preloaded) {
1101
+ continue;
1102
+ }
1103
+ if (preloadConfig.resourceCategory === 'all') {
1104
+ cssAssets.push(...handlerAssets(assetsInfo.assets.css.async));
1105
+ cssAssets.push(...handlerAssets(assetsInfo.assets.css.sync));
1106
+ jsAssets.push(...handlerAssets(assetsInfo.assets.js.async));
1107
+ jsAssets.push(...handlerAssets(assetsInfo.assets.js.sync));
1108
+ // eslint-disable-next-line no-constant-condition
1109
+ } else if (preloadConfig.resourceCategory = 'sync') {
1110
+ cssAssets.push(...handlerAssets(assetsInfo.assets.css.sync));
1111
+ jsAssets.push(...handlerAssets(assetsInfo.assets.js.sync));
1112
+ }
1113
+ setPreloaded(exposeFullPath);
1114
+ }
1115
+ }
1116
+ }, true, memo, remoteSnapshot, (target, key)=>{
1117
+ const res = origin.loaderHook.lifecycle.getModuleInfo.emit({
1118
+ target,
1119
+ key
1120
+ });
1121
+ if (res && !(res instanceof Promise)) {
1122
+ return res;
1123
+ }
1124
+ return;
1125
+ });
1126
+ if (remoteSnapshot.shared) {
1127
+ remoteSnapshot.shared.forEach((shared)=>{
1128
+ var _options_shared;
1129
+ const shareInfo = (_options_shared = options.shared) == null ? void 0 : _options_shared[shared.sharedName];
1130
+ // When data is downgraded, the shared configuration may be different.
1131
+ if (!shareInfo) {
1132
+ return;
1133
+ }
1134
+ const globalShare = getGlobalShare(shared.sharedName, shareInfo);
1135
+ // 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.
1136
+ if (globalShare && typeof globalShare.lib === 'function') {
1137
+ shared.assets.js.sync.forEach((asset)=>{
1138
+ loadedSharedJsAssets.add(asset);
1139
+ });
1140
+ shared.assets.css.sync.forEach((asset)=>{
1141
+ loadedSharedCssAssets.add(asset);
1142
+ });
1143
+ }
1144
+ });
1145
+ }
1146
+ const needPreloadJsAssets = jsAssets.filter((asset)=>!loadedSharedJsAssets.has(asset));
1147
+ const needPreloadCssAssets = cssAssets.filter((asset)=>!loadedSharedCssAssets.has(asset));
1148
+ return {
1149
+ cssAssets: needPreloadCssAssets,
1150
+ jsAssetsWithoutEntry: needPreloadJsAssets,
1151
+ entryAssets
1152
+ };
1153
+ }
1154
+ const generatePreloadAssetsPlugin = function() {
1155
+ return {
1156
+ name: 'generate-preload-assets-plugin',
1157
+ async generatePreloadAssets (args) {
1158
+ const { origin, preloadOptions, remoteInfo, remote, globalSnapshot, remoteSnapshot } = args;
1159
+ if (isRemoteInfoWithEntry(remote) && isPureRemoteEntry(remote)) {
1160
+ return {
1161
+ cssAssets: [],
1162
+ jsAssetsWithoutEntry: [],
1163
+ entryAssets: [
1164
+ {
1165
+ name: remote.name,
1166
+ url: remote.entry,
1167
+ moduleInfo: {
1168
+ name: remoteInfo.name,
1169
+ entry: remote.entry,
1170
+ type: 'global',
1171
+ entryGlobalName: '',
1172
+ shareScope: ''
1173
+ }
1174
+ }
1175
+ ]
1176
+ };
1177
+ }
1178
+ assignRemoteInfo(remoteInfo, remoteSnapshot);
1179
+ const assets = generatePreloadAssets(origin, preloadOptions, remoteInfo, globalSnapshot, remoteSnapshot);
1180
+ return assets;
1181
+ }
1182
+ };
1183
+ };
1184
+
1185
+ class SnapshotHandler {
1186
+ async loadSnapshot(moduleInfo) {
1187
+ const { options } = this.HostInstance;
1188
+ const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } = this.getGlobalRemoteInfo(moduleInfo);
1189
+ const { remoteSnapshot: globalRemoteSnapshot, globalSnapshot: globalSnapshotRes } = await this.hooks.lifecycle.loadSnapshot.emit({
1190
+ options,
1191
+ moduleInfo,
1192
+ hostGlobalSnapshot,
1193
+ remoteSnapshot,
1194
+ globalSnapshot
1195
+ });
1196
+ return {
1197
+ remoteSnapshot: globalRemoteSnapshot,
1198
+ globalSnapshot: globalSnapshotRes
1199
+ };
1200
+ }
1201
+ // eslint-disable-next-line max-lines-per-function
1202
+ async loadRemoteSnapshotInfo(moduleInfo) {
1203
+ const { options } = this.HostInstance;
1204
+ const hostSnapshot = getGlobalSnapshotInfoByModuleInfo({
1205
+ name: this.HostInstance.options.name,
1206
+ version: this.HostInstance.options.version
1207
+ }, {
1208
+ getModuleInfoHook: (target, key)=>{
1209
+ const res = this.HostInstance.loaderHook.lifecycle.getModuleInfo.emit({
1210
+ target,
1211
+ key
1212
+ });
1213
+ if (res && !(res instanceof Promise)) {
1214
+ return res;
1215
+ }
1216
+ return;
1217
+ }
1218
+ });
1219
+ await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({
1220
+ options,
1221
+ moduleInfo
1222
+ });
1223
+ // In the dynamic loadRemote scenario, incomplete remotesInfo delivery may occur. In this case, the remotesInfo in the host needs to be completed in the snapshot at runtime.
1224
+ // Ensure the integrity of the snapshot, and at the same time help the chrome plug-in correctly identify all producer modules, ensuring that proxyable producer modules will not be missing
1225
+ // In the dynamic loadRemote scenario, incomplete remotesInfo delivery may occur. In this case, the remotesInfo in the host needs to be completed in the snapshot at runtime.
1226
+ // Ensure the integrity of the snapshot, and at the same time help the chrome plug-in correctly identify all producer modules, ensuring that proxyable producer modules will not be missing
1227
+ if (hostSnapshot && 'remotesInfo' in hostSnapshot && !getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name, (target, key)=>{
1228
+ const res = this.HostInstance.loaderHook.lifecycle.getModuleInfo.emit({
1229
+ target,
1230
+ key
1231
+ });
1232
+ if (res && !(res instanceof Promise)) {
1233
+ return res;
1234
+ }
1235
+ return;
1236
+ }).value) {
1237
+ if ('version' in moduleInfo || 'entry' in moduleInfo) {
1238
+ hostSnapshot.remotesInfo = _extends({}, hostSnapshot == null ? void 0 : hostSnapshot.remotesInfo, {
1239
+ [moduleInfo.name]: {
1240
+ matchedVersion: 'version' in moduleInfo ? moduleInfo.version : moduleInfo.entry
1241
+ }
1242
+ });
1243
+ }
1244
+ }
1245
+ const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } = this.getGlobalRemoteInfo(moduleInfo);
1246
+ const { remoteSnapshot: globalRemoteSnapshot, globalSnapshot: globalSnapshotRes } = await this.hooks.lifecycle.loadSnapshot.emit({
1247
+ options,
1248
+ moduleInfo,
1249
+ hostGlobalSnapshot,
1250
+ remoteSnapshot,
1251
+ globalSnapshot
1252
+ });
1253
+ // global snapshot include manifest or module info include manifest
1254
+ if (globalRemoteSnapshot) {
1255
+ if (isManifestProvider(globalRemoteSnapshot)) {
1256
+ const moduleSnapshot = await this.getManifestJson(globalRemoteSnapshot.remoteEntry, moduleInfo, {});
1257
+ // eslint-disable-next-line @typescript-eslint/no-shadow
1258
+ const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(_extends({}, moduleInfo), moduleSnapshot);
1259
+ return {
1260
+ remoteSnapshot: moduleSnapshot,
1261
+ globalSnapshot: globalSnapshotRes
1262
+ };
1263
+ } else {
1264
+ const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
1265
+ options: this.HostInstance.options,
1266
+ moduleInfo,
1267
+ remoteSnapshot: globalRemoteSnapshot,
1268
+ from: 'global'
1269
+ });
1270
+ return {
1271
+ remoteSnapshot: remoteSnapshotRes,
1272
+ globalSnapshot: globalSnapshotRes
1273
+ };
1274
+ }
1275
+ } else {
1276
+ if (isRemoteInfoWithEntry(moduleInfo)) {
1277
+ // get from manifest.json and merge remote info from remote server
1278
+ const moduleSnapshot = await this.getManifestJson(moduleInfo.entry, moduleInfo, {});
1279
+ // eslint-disable-next-line @typescript-eslint/no-shadow
1280
+ const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(moduleInfo, moduleSnapshot);
1281
+ const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
1282
+ options: this.HostInstance.options,
1283
+ moduleInfo,
1284
+ remoteSnapshot: moduleSnapshot,
1285
+ from: 'global'
1286
+ });
1287
+ return {
1288
+ remoteSnapshot: remoteSnapshotRes,
1289
+ globalSnapshot: globalSnapshotRes
1290
+ };
1291
+ } else {
1292
+ error(`
1293
+ Cannot get remoteSnapshot with the name: '${moduleInfo.name}', version: '${moduleInfo.version}' from __FEDERATION__.moduleInfo. The following reasons may be causing the problem:\n
1294
+ 1. The Deploy platform did not deliver the correct data. You can use __FEDERATION__.moduleInfo to check the remoteInfo.\n
1295
+ 2. The remote '${moduleInfo.name}' version '${moduleInfo.version}' is not released.\n
1296
+ The transformed module info: ${JSON.stringify(globalSnapshotRes)}
1297
+ `);
1298
+ }
1299
+ }
1300
+ }
1301
+ getGlobalRemoteInfo(moduleInfo) {
1302
+ const hostGlobalSnapshot = getGlobalSnapshotInfoByModuleInfo({
1303
+ name: this.HostInstance.options.name,
1304
+ version: this.HostInstance.options.version
1305
+ }, {
1306
+ getModuleInfoHook: (target, key)=>{
1307
+ const res = this.HostInstance.loaderHook.lifecycle.getModuleInfo.emit({
1308
+ target,
1309
+ key
1310
+ });
1311
+ if (res && !(res instanceof Promise)) {
1312
+ return res;
1313
+ }
1314
+ return;
1315
+ }
1316
+ });
1317
+ // get remote detail info from global
1318
+ const globalRemoteInfo = hostGlobalSnapshot && 'remotesInfo' in hostGlobalSnapshot && hostGlobalSnapshot.remotesInfo && getInfoWithoutType(hostGlobalSnapshot.remotesInfo, moduleInfo.name, (target, key)=>{
1319
+ const res = this.HostInstance.loaderHook.lifecycle.getModuleInfo.emit({
1320
+ target,
1321
+ key
1322
+ });
1323
+ if (res && !(res instanceof Promise)) {
1324
+ return res;
1325
+ }
1326
+ return;
1327
+ }).value;
1328
+ if (globalRemoteInfo && globalRemoteInfo.matchedVersion) {
1329
+ return {
1330
+ hostGlobalSnapshot,
1331
+ globalSnapshot: getGlobalSnapshot(),
1332
+ remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({
1333
+ name: moduleInfo.name,
1334
+ version: globalRemoteInfo.matchedVersion
1335
+ }, {
1336
+ getModuleInfoHook: (target, key)=>{
1337
+ const res = this.HostInstance.loaderHook.lifecycle.getModuleInfo.emit({
1338
+ target,
1339
+ key
1340
+ });
1341
+ if (res && !(res instanceof Promise)) {
1342
+ return res;
1343
+ }
1344
+ return;
1345
+ }
1346
+ })
1347
+ };
1348
+ }
1349
+ return {
1350
+ hostGlobalSnapshot: undefined,
1351
+ globalSnapshot: getGlobalSnapshot(),
1352
+ remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({
1353
+ name: moduleInfo.name,
1354
+ version: 'version' in moduleInfo ? moduleInfo.version : undefined
1355
+ }, {
1356
+ getModuleInfoHook: (target, key)=>{
1357
+ const res = this.HostInstance.loaderHook.lifecycle.getModuleInfo.emit({
1358
+ target,
1359
+ key
1360
+ });
1361
+ if (res && !(res instanceof Promise)) {
1362
+ return res;
1363
+ }
1364
+ return;
1365
+ }
1366
+ })
1367
+ };
1368
+ }
1369
+ async getManifestJson(manifestUrl, moduleInfo, extraOptions) {
1370
+ const getManifest = async ()=>{
1371
+ let manifestJson = this.manifestCache.get(manifestUrl);
1372
+ if (manifestJson) {
1373
+ return manifestJson;
1374
+ }
1375
+ try {
1376
+ const res = await fetch(manifestUrl);
1377
+ manifestJson = await res.json();
1378
+ assert(manifestJson.metaData && manifestJson.exposes && manifestJson.shared, `${manifestUrl} is not federation manifest`);
1379
+ this.manifestCache.set(manifestUrl, manifestJson);
1380
+ return manifestJson;
1381
+ } catch (err) {
1382
+ error(`Failed to get manifestJson for ${moduleInfo.name}. The manifest URL is ${manifestUrl}. Please ensure that the manifestUrl is accessible.
1383
+ \n Error message:
1384
+ \n ${err}`);
1385
+ }
1386
+ };
1387
+ const asyncLoadProcess = async ()=>{
1388
+ const manifestJson = await getManifest();
1389
+ const remoteSnapshot = generateSnapshotFromManifest(manifestJson, {
1390
+ version: manifestUrl
1391
+ });
1392
+ const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
1393
+ options: this.HostInstance.options,
1394
+ moduleInfo,
1395
+ manifestJson,
1396
+ remoteSnapshot,
1397
+ manifestUrl,
1398
+ from: 'manifest'
1399
+ });
1400
+ return remoteSnapshotRes;
1401
+ };
1402
+ if (!this.manifestLoading[manifestUrl]) {
1403
+ this.manifestLoading[manifestUrl] = asyncLoadProcess().then((res)=>res);
1404
+ }
1405
+ return this.manifestLoading[manifestUrl];
1406
+ }
1407
+ constructor(HostInstance){
1408
+ this.loadingHostSnapshot = null;
1409
+ this.manifestCache = new Map();
1410
+ this.hooks = new PluginSystem({
1411
+ beforeLoadRemoteSnapshot: new AsyncHook('beforeLoadRemoteSnapshot'),
1412
+ loadSnapshot: new AsyncWaterfallHook('loadGlobalSnapshot'),
1413
+ loadRemoteSnapshot: new AsyncWaterfallHook('loadRemoteSnapshot')
1414
+ });
1415
+ this.manifestLoading = Global.__FEDERATION__.__MANIFEST_LOADING__;
1416
+ this.HostInstance = HostInstance;
1417
+ }
1418
+ }
1419
+
1420
+ class FederationHost {
1421
+ initOptions(userOptions) {
1422
+ this.registerPlugins(userOptions.plugins);
1423
+ const options = this.formatOptions(this.options, userOptions);
1424
+ this.options = options;
1425
+ return options;
1426
+ }
1427
+ // overrideSharedOptions(shareScope: GlobalShareScope[string]): void {}
1428
+ async loadShare(pkgName, customShareInfo) {
1429
+ var _this_options_shared;
1430
+ // 1. Verify whether the currently loaded share already exists, and report an error if it does not exist
1431
+ // 2. Search globally to see if there is a matching share, and if so, use it directly
1432
+ // 3. If not, get it from the current share and store the obtained share globally.
1433
+ const shareInfo = Object.assign({}, (_this_options_shared = this.options.shared) == null ? void 0 : _this_options_shared[pkgName], customShareInfo);
1434
+ const loadShareRes = await this.hooks.lifecycle.beforeLoadShare.emit({
1435
+ pkgName,
1436
+ shareInfo,
1437
+ shared: this.options.shared,
1438
+ origin: this
1439
+ });
1440
+ const { shareInfo: shareInfoRes } = loadShareRes;
1441
+ assert(shareInfoRes, `cannot find ${pkgName} Share in the ${this.options.name}. Perhaps you have not injected the ${pkgName} Share parameters`);
1442
+ // get from cache
1443
+ const globalShare = getGlobalShare(pkgName, shareInfoRes);
1444
+ if (globalShare && globalShare.lib) {
1445
+ addUniqueItem(globalShare.useIn, this.options.name);
1446
+ return globalShare.lib;
1447
+ } else if (globalShare && globalShare.loading) {
1448
+ const factory = await globalShare.loading;
1449
+ addUniqueItem(globalShare.useIn, this.options.name);
1450
+ return factory;
1451
+ } else if (globalShare) {
1452
+ const asyncLoadProcess = async ()=>{
1453
+ const factory = await globalShare.get();
1454
+ shareInfoRes.lib = factory;
1455
+ addUniqueItem(shareInfoRes.useIn, this.options.name);
1456
+ const gShared = getGlobalShare(pkgName, shareInfoRes);
1457
+ if (gShared) {
1458
+ gShared.lib = factory;
1459
+ }
1460
+ return factory;
1461
+ };
1462
+ const loading = asyncLoadProcess();
1463
+ this.setShared({
1464
+ pkgName,
1465
+ loaded: true,
1466
+ shared: shareInfoRes,
1467
+ from: this.options.name,
1468
+ lib: null,
1469
+ loading
1470
+ });
1471
+ return loading;
1472
+ } else {
1473
+ if (customShareInfo) {
1474
+ return false;
1475
+ }
1476
+ const asyncLoadProcess = async ()=>{
1477
+ const factory = await shareInfoRes.get();
1478
+ shareInfoRes.lib = factory;
1479
+ addUniqueItem(shareInfoRes.useIn, this.options.name);
1480
+ const gShared = getGlobalShare(pkgName, shareInfoRes);
1481
+ if (gShared) {
1482
+ gShared.lib = factory;
1483
+ }
1484
+ return factory;
1485
+ };
1486
+ const loading = asyncLoadProcess();
1487
+ this.setShared({
1488
+ pkgName,
1489
+ loaded: true,
1490
+ shared: shareInfoRes,
1491
+ from: this.options.name,
1492
+ lib: null,
1493
+ loading
1494
+ });
1495
+ return loading;
1496
+ }
1497
+ }
1498
+ // There will be a lib function only if the shared set by eager or runtime init is set or the shared is successfully loaded.
1499
+ // 1. If the loaded shared already exists globally, then reuse
1500
+ // 2. If lib exists in local shared, use it directly
1501
+ // 3. If the local get returns something other than Promise, then use it directly
1502
+ loadShareSync(pkgName) {
1503
+ var _this_options_shared;
1504
+ const shareInfo = (_this_options_shared = this.options.shared) == null ? void 0 : _this_options_shared[pkgName];
1505
+ const globalShare = getGlobalShare(pkgName, shareInfo);
1506
+ if (globalShare && typeof globalShare.lib === 'function') {
1507
+ addUniqueItem(globalShare.useIn, this.options.name);
1508
+ if (!globalShare.loaded) {
1509
+ globalShare.loaded = true;
1510
+ if (globalShare.from === this.options.name) {
1511
+ shareInfo.loaded = true;
1512
+ }
1513
+ }
1514
+ return globalShare.lib;
1515
+ }
1516
+ if (shareInfo.lib) {
1517
+ if (!shareInfo.loaded) {
1518
+ shareInfo.loaded = true;
1519
+ }
1520
+ return shareInfo.lib;
1521
+ }
1522
+ if (shareInfo.get) {
1523
+ const module = shareInfo.get();
1524
+ if (module instanceof Promise) {
1525
+ throw new Error(`
1526
+ The loadShareSync function failed to load ${pkgName}. Cannot find ${pkgName} in ${this.options.name}.
1527
+ Failure reason: \n
1528
+ 1. Registered ${pkgName} share with the 'get' attribute, but did not use loadShare before.\n
1529
+ 2. Did not register ${pkgName} share with the 'lib' attribute.\n
1530
+ `);
1531
+ }
1532
+ shareInfo.lib = module;
1533
+ this.setShared({
1534
+ pkgName,
1535
+ loaded: true,
1536
+ from: this.options.name,
1537
+ lib: shareInfo.lib,
1538
+ shared: shareInfo
1539
+ });
1540
+ return shareInfo.lib;
1541
+ }
1542
+ throw new Error(`
1543
+ The loadShareSync function failed to load ${pkgName}. Cannot find ${pkgName} in ${this.options.name}.
1544
+ Failure reason: \n
1545
+ 1. Registered ${pkgName} share with the 'get' attribute, but did not use loadShare before.\n
1546
+ 2. Did not register ${pkgName} share with the 'lib' attribute.\n
1547
+ `);
1548
+ }
1549
+ async _getRemoteModuleAndOptions(id) {
1550
+ const loadRemoteArgs = await this.hooks.lifecycle.beforeLoadRemote.emit({
1551
+ id,
1552
+ options: this.options,
1553
+ origin: this
1554
+ });
1555
+ const { id: idRes } = loadRemoteArgs;
1556
+ const remoteSplitInfo = matchRemoteWithNameAndExpose(this.options.remotes, idRes);
1557
+ assert(remoteSplitInfo, `
1558
+ Cannot find ${idRes} in ${this.options.name}. Possible cause of failure:\n
1559
+ 1. ${idRes} was not injected into ${this.options.name}'s 'remotes' parameter.\n
1560
+ 2. Cannot find ${idRes} in ${this.options.name}'s 'remotes' with attribute 'name' or 'alias'.
1561
+ 3. The 'beforeLoadRemote' hook was provided but did not return the correct 'remoteInfo' when loading ${idRes}.
1562
+ `);
1563
+ const { remote: rawRemote } = remoteSplitInfo;
1564
+ const remoteInfo = getRemoteInfo(rawRemote);
1565
+ const matchInfo = await this.hooks.lifecycle.loadRemoteMatch.emit(_extends({
1566
+ id: idRes
1567
+ }, remoteSplitInfo, {
1568
+ options: this.options,
1569
+ origin: this,
1570
+ remoteInfo
1571
+ }));
1572
+ const { remote, expose } = matchInfo;
1573
+ assert(remote && expose, `The 'beforeLoadRemote' hook was provided but did not return the correct 'remote' and 'expose' when loading ${idRes}.`);
1574
+ let module = this.moduleCache.get(remote.name);
1575
+ const moduleOptions = {
1576
+ hostInfo: {
1577
+ name: this.options.name,
1578
+ version: this.options.version || 'custom'
1579
+ },
1580
+ remoteInfo,
1581
+ shared: this.options.shared || {},
1582
+ plugins: this.options.plugins,
1583
+ loaderHook: this.loaderHook
1584
+ };
1585
+ if (!module) {
1586
+ module = new Module(moduleOptions);
1587
+ this.moduleCache.set(remote.name, module);
1588
+ }
1589
+ return {
1590
+ module,
1591
+ moduleOptions,
1592
+ remoteMatchInfo: matchInfo
1593
+ };
1594
+ }
1595
+ // eslint-disable-next-line max-lines-per-function
1596
+ // eslint-disable-next-line @typescript-eslint/member-ordering
1597
+ async loadRemote(id, options) {
1598
+ try {
1599
+ const { loadFactory = true } = options || {
1600
+ loadFactory: true
1601
+ };
1602
+ // 1. Verify whether the parameters of the obtained module are legal. There are two module request methods: pkgName + expose and alias + expose.
1603
+ // 2. Request the snapshot information of the current host and store the obtained snapshot information globally. The obtained module information is partly offline and partly online. The online module information will obtain the modules used online.
1604
+ // 3. Get the detailed information of the current module from global (remoteEntry address, expose resource address)
1605
+ // 4. After obtaining remoteEntry, call the init of the module, and then obtain the exported content of the module through get
1606
+ // id: pkgName(@federation/app1) + expose(button) = @federation/app1/button
1607
+ // id: alias(app1) + expose(button) = app1/button
1608
+ // id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort
1609
+ const { module, moduleOptions, remoteMatchInfo } = await this._getRemoteModuleAndOptions(id);
1610
+ const { pkgNameOrAlias, remote, expose, id: idRes } = remoteMatchInfo;
1611
+ const moduleOrFactory = await module.get(expose, options);
1612
+ await this.hooks.lifecycle.loadRemote.emit({
1613
+ id: idRes,
1614
+ pkgNameOrAlias,
1615
+ expose,
1616
+ exposeModule: loadFactory ? moduleOrFactory : undefined,
1617
+ exposeModuleFactory: loadFactory ? undefined : moduleOrFactory,
1618
+ remote,
1619
+ options: moduleOptions,
1620
+ moduleInstance: module,
1621
+ origin: this
1622
+ });
1623
+ return moduleOrFactory;
1624
+ } catch (error) {
1625
+ this.hooks.lifecycle.errorLoadRemote.emit({
1626
+ id,
1627
+ error
1628
+ });
1629
+ throw error;
1630
+ }
1631
+ }
1632
+ // eslint-disable-next-line @typescript-eslint/member-ordering
1633
+ async preloadRemote(preloadOptions) {
1634
+ await this.hooks.lifecycle.beforePreloadRemote.emit({
1635
+ preloadOptions,
1636
+ options: this.options,
1637
+ origin: this
1638
+ });
1639
+ const preloadOps = formatPreloadArgs(this.options.remotes, preloadOptions);
1640
+ await Promise.all(preloadOps.map(async (ops)=>{
1641
+ const { remote } = ops;
1642
+ const remoteInfo = getRemoteInfo(remote);
1643
+ const { globalSnapshot, remoteSnapshot } = await this.snapshotHandler.loadRemoteSnapshotInfo(remote);
1644
+ const assets = await this.hooks.lifecycle.generatePreloadAssets.emit({
1645
+ origin: this,
1646
+ preloadOptions: ops,
1647
+ remote,
1648
+ remoteInfo,
1649
+ globalSnapshot,
1650
+ remoteSnapshot
1651
+ });
1652
+ if (!assets) {
1653
+ return;
1654
+ }
1655
+ preloadAssets(remoteInfo, this, assets);
1656
+ }));
1657
+ }
1658
+ /**
1659
+ * The sharing init sequence function (only runs once per share scope).
1660
+ * Has one argument, the name of the share scope.
1661
+ * Creates a share scope if not existing
1662
+ */ // eslint-disable-next-line @typescript-eslint/member-ordering
1663
+ initializeSharing(shareScopeName = DEFAULT_SCOPE) {
1664
+ const shareScopeLoading = Global.__FEDERATION__.__SHARE_SCOPE_LOADING__;
1665
+ const shareScope = Global.__FEDERATION__.__SHARE__;
1666
+ const hostName = this.options.name;
1667
+ // only runs once
1668
+ if (shareScopeLoading[shareScopeName]) {
1669
+ return shareScopeLoading[shareScopeName];
1670
+ }
1671
+ // creates a new share scope if needed
1672
+ if (!shareScope[shareScopeName]) {
1673
+ shareScope[shareScopeName] = {};
1674
+ }
1675
+ // runs all init snippets from all modules reachable
1676
+ const scope = shareScope[shareScopeName];
1677
+ const register = (name, shared)=>{
1678
+ const { version, eager } = shared;
1679
+ scope[name] = scope[name] || {};
1680
+ const versions = scope[name];
1681
+ const activeVersion = versions[version];
1682
+ const activeVersionEager = Boolean(activeVersion && (activeVersion.eager || activeVersion.shareConfig.eager));
1683
+ if (!activeVersion || !activeVersion.loaded && (Boolean(!eager) !== !activeVersionEager ? eager : hostName > activeVersion.from)) {
1684
+ versions[version] = shared;
1685
+ }
1686
+ };
1687
+ const promises = [];
1688
+ const initRemoteModule = async (key)=>{
1689
+ const { module } = await this._getRemoteModuleAndOptions(key);
1690
+ const initFn = (mod)=>mod && mod.init && mod.init(shareScope[shareScopeName]);
1691
+ const entry = await module.getEntry();
1692
+ initFn(entry);
1693
+ };
1694
+ Object.keys(this.options.shared).forEach((shareName)=>{
1695
+ const shared = this.options.shared[shareName];
1696
+ if (shared.scope.includes(shareScopeName)) {
1697
+ register(shareName, shared);
1698
+ }
1699
+ });
1700
+ this.options.remotes.forEach((remote)=>{
1701
+ if (remote.shareScope === shareScopeName) {
1702
+ promises.push(initRemoteModule(remote.name));
1703
+ }
1704
+ });
1705
+ if (!promises.length) {
1706
+ return shareScopeLoading[shareScopeName] = true;
1707
+ }
1708
+ return shareScopeLoading[shareScopeName] = Promise.all(promises).then(()=>shareScopeLoading[shareScopeName] = true);
1709
+ }
1710
+ formatOptions(globalOptions, userOptions) {
1711
+ const formatShareOptions = formatShareConfigs(userOptions.shared || {}, userOptions.name);
1712
+ const shared = _extends({}, globalOptions.shared, formatShareOptions);
1713
+ const { userOptions: userOptionsRes, options: globalOptionsRes } = this.hooks.lifecycle.beforeInit.emit({
1714
+ origin: this,
1715
+ userOptions,
1716
+ options: globalOptions,
1717
+ shareInfo: shared
1718
+ });
1719
+ const userRemotes = userOptionsRes.remotes || [];
1720
+ const remotes = userRemotes.reduce((res, remote)=>{
1721
+ if (!res.find((item)=>item.name === remote.name)) {
1722
+ if (remote.alias) {
1723
+ // 校验 alias 是否等于 remote.name 和 remote.alias 的前缀,如果是则报错
1724
+ // 因为引用支持多级路径的引用时无法保证名称是否唯一,所以不支持 alias 为 remote.name 的前缀
1725
+ const findEqual = res.find((item)=>{
1726
+ var _item_alias;
1727
+ return remote.alias && (item.name.startsWith(remote.alias) || ((_item_alias = item.alias) == null ? void 0 : _item_alias.startsWith(remote.alias)));
1728
+ });
1729
+ assert(!findEqual, `The alias ${remote.alias} of remote ${remote.name} is not allowed to be the prefix of ${findEqual && findEqual.name} name or alias`);
1730
+ }
1731
+ // Set the remote entry to a complete path
1732
+ if ('entry' in remote) {
1733
+ if (isBrowserEnv$1()) {
1734
+ remote.entry = new URL(remote.entry, window.location.origin).href;
1735
+ }
1736
+ }
1737
+ if (!remote.shareScope) {
1738
+ remote.shareScope = DEFAULT_SCOPE;
1739
+ }
1740
+ if (!remote.type) {
1741
+ // FIXME: The build plugin need to support this field
1742
+ remote.type = DEFAULT_REMOTE_TYPE;
1743
+ }
1744
+ res.push(remote);
1745
+ }
1746
+ return res;
1747
+ }, globalOptionsRes.remotes);
1748
+ // register shared include lib
1749
+ const sharedKeys = Object.keys(formatShareOptions);
1750
+ sharedKeys.forEach((sharedKey)=>{
1751
+ const sharedVal = formatShareOptions[sharedKey];
1752
+ const globalShare = getGlobalShare(sharedKey, sharedVal);
1753
+ if (!globalShare && sharedVal && sharedVal.lib) {
1754
+ this.setShared({
1755
+ pkgName: sharedKey,
1756
+ lib: sharedVal.lib,
1757
+ get: sharedVal.get,
1758
+ shared: sharedVal,
1759
+ from: userOptions.name
1760
+ });
1761
+ }
1762
+ });
1763
+ const plugins = [
1764
+ ...globalOptionsRes.plugins
1765
+ ];
1766
+ if (userOptionsRes.plugins) {
1767
+ userOptionsRes.plugins.forEach((plugin)=>{
1768
+ if (!plugins.includes(plugin)) {
1769
+ plugins.push(plugin);
1770
+ }
1771
+ });
1772
+ }
1773
+ const optionsRes = _extends({}, globalOptions, userOptions, {
1774
+ plugins,
1775
+ remotes,
1776
+ shared
1777
+ });
1778
+ this.hooks.lifecycle.init.emit({
1779
+ origin: this,
1780
+ options: optionsRes
1781
+ });
1782
+ return optionsRes;
1783
+ }
1784
+ registerPlugins(plugins) {
1785
+ registerPlugins(plugins, [
1786
+ this.hooks,
1787
+ this.snapshotHandler.hooks,
1788
+ this.loaderHook
1789
+ ]);
1790
+ }
1791
+ setShared({ pkgName, shared, from, lib, loading, loaded, get }) {
1792
+ const target = getGlobalShareScope();
1793
+ const { version, scope = 'default' } = shared, shareInfo = _object_without_properties_loose(shared, [
1794
+ "version",
1795
+ "scope"
1796
+ ]);
1797
+ const scopes = Array.isArray(scope) ? scope : [
1798
+ scope
1799
+ ];
1800
+ scopes.forEach((sc)=>{
1801
+ if (!target[sc]) {
1802
+ target[sc] = {};
1803
+ }
1804
+ if (!target[sc][pkgName]) {
1805
+ target[sc][pkgName] = {};
1806
+ }
1807
+ if (target[sc][pkgName][version]) {
1808
+ warn(// eslint-disable-next-line max-len
1809
+ `The share \n ${safeToString$1({
1810
+ scope: sc,
1811
+ pkgName,
1812
+ version,
1813
+ from: target[sc][pkgName][version].from
1814
+ })} has been registered`);
1815
+ return;
1816
+ }
1817
+ target[sc][pkgName][version] = _extends({
1818
+ version,
1819
+ scope: [
1820
+ 'default'
1821
+ ]
1822
+ }, shareInfo, {
1823
+ lib,
1824
+ loaded,
1825
+ loading
1826
+ });
1827
+ if (get) {
1828
+ target[sc][pkgName][version].get = get;
1829
+ }
1830
+ });
1831
+ }
1832
+ constructor(userOptions){
1833
+ this.hooks = new PluginSystem({
1834
+ beforeInit: new SyncWaterfallHook('beforeInit'),
1835
+ init: new SyncHook(),
1836
+ beforeLoadRemote: new AsyncWaterfallHook('beforeLoadRemote'),
1837
+ loadRemoteMatch: new AsyncWaterfallHook('loadRemoteMatch'),
1838
+ loadRemote: new AsyncHook('loadRemote'),
1839
+ errorLoadRemote: new AsyncHook('errorLoadRemote'),
1840
+ beforeLoadShare: new AsyncWaterfallHook('beforeLoadShare'),
1841
+ loadShare: new AsyncHook(),
1842
+ beforePreloadRemote: new AsyncHook(),
1843
+ generatePreloadAssets: new AsyncHook('generatePreloadAssets'),
1844
+ afterPreloadRemote: new AsyncHook()
1845
+ });
1846
+ this.version = '0.0.1';
1847
+ this.moduleCache = new Map();
1848
+ this.loaderHook = new PluginSystem({
1849
+ // FIXME: may not be suitable
1850
+ getModuleInfo: new SyncHook(),
1851
+ createScript: new SyncHook()
1852
+ });
1853
+ this.loadingShare = {};
1854
+ // TODO: check options detail type
1855
+ // set options default value
1856
+ const defaultOptions = {
1857
+ id: getBuilderId(),
1858
+ name: userOptions.name,
1859
+ plugins: [
1860
+ snapshotPlugin(),
1861
+ generatePreloadAssetsPlugin()
1862
+ ],
1863
+ remotes: [],
1864
+ shared: {},
1865
+ inBrowser: isBrowserEnv$1()
1866
+ };
1867
+ this.name = userOptions.name;
1868
+ this.options = defaultOptions;
1869
+ this.snapshotHandler = new SnapshotHandler(this);
1870
+ this.registerPlugins([
1871
+ ...defaultOptions.plugins,
1872
+ ...userOptions.plugins || []
1873
+ ]);
1874
+ this.options = this.formatOptions(defaultOptions, userOptions);
1875
+ }
1876
+ }
1877
+
1878
+ let FederationInstance = null;
1879
+ function init(options) {
1880
+ // Retrieve the same instance with the same name
1881
+ const instance = getGlobalFederationInstance(options.name, options.version);
1882
+ if (!instance) {
1883
+ // Retrieve debug constructor
1884
+ const FederationConstructor = getGlobalFederationConstructor() || FederationHost;
1885
+ FederationInstance = new FederationConstructor(options);
1886
+ setGlobalFederationInstance(FederationInstance);
1887
+ return FederationInstance;
1888
+ } else {
1889
+ // Merge options
1890
+ instance.initOptions(options);
1891
+ return instance;
1892
+ }
1893
+ }
1894
+ function loadRemote(...args) {
1895
+ assert(FederationInstance, 'Please call init first');
1896
+ // eslint-disable-next-line prefer-spread
1897
+ return FederationInstance.loadRemote.apply(FederationInstance, args);
1898
+ }
1899
+ function loadShare(...args) {
1900
+ assert(FederationInstance, 'Please call init first');
1901
+ // eslint-disable-next-line prefer-spread
1902
+ return FederationInstance.loadShare.apply(FederationInstance, args);
1903
+ }
1904
+ function loadShareSync(...args) {
1905
+ assert(FederationInstance, 'Please call init first');
1906
+ // eslint-disable-next-line prefer-spread
1907
+ return FederationInstance.loadShareSync.apply(FederationInstance, args);
1908
+ }
1909
+ function preloadRemote(...args) {
1910
+ assert(FederationInstance, 'Please call init first');
1911
+ // eslint-disable-next-line prefer-spread
1912
+ return FederationInstance.preloadRemote.apply(FederationInstance, args);
1913
+ }
1914
+ // Inject for debug
1915
+ setGlobalFederationConstructor(FederationHost);
1916
+
1917
+ export { FederationHost, init, loadRemote, loadScript, loadShare, loadShareSync, preloadRemote };