@module-federation/runtime-core 0.0.0-next-20241115035905

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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -0
  3. package/dist/LICENSE +21 -0
  4. package/dist/index.cjs.d.ts +1 -0
  5. package/dist/index.cjs.js +3010 -0
  6. package/dist/index.esm.d.ts +1 -0
  7. package/dist/index.esm.js +2980 -0
  8. package/dist/package.json +42 -0
  9. package/dist/polyfills.cjs.js +28 -0
  10. package/dist/polyfills.esm.js +25 -0
  11. package/dist/src/constant.d.ts +2 -0
  12. package/dist/src/core.d.ts +105 -0
  13. package/dist/src/global.d.ts +42 -0
  14. package/dist/src/helpers.d.ts +31 -0
  15. package/dist/src/index.d.ts +14 -0
  16. package/dist/src/module/index.d.ts +21 -0
  17. package/dist/src/plugins/generate-preload-assets.d.ts +8 -0
  18. package/dist/src/plugins/snapshot/SnapshotHandler.d.ts +58 -0
  19. package/dist/src/plugins/snapshot/index.d.ts +5 -0
  20. package/dist/src/remote/index.d.ts +109 -0
  21. package/dist/src/shared/index.d.ts +66 -0
  22. package/dist/src/type/config.d.ts +112 -0
  23. package/dist/src/type/index.d.ts +3 -0
  24. package/dist/src/type/plugin.d.ts +34 -0
  25. package/dist/src/type/preload.d.ts +26 -0
  26. package/dist/src/types.d.ts +1 -0
  27. package/dist/src/utils/env.d.ts +3 -0
  28. package/dist/src/utils/hooks/asyncHook.d.ts +6 -0
  29. package/dist/src/utils/hooks/asyncWaterfallHooks.d.ts +10 -0
  30. package/dist/src/utils/hooks/index.d.ts +6 -0
  31. package/dist/src/utils/hooks/pluginSystem.d.ts +15 -0
  32. package/dist/src/utils/hooks/syncHook.d.ts +12 -0
  33. package/dist/src/utils/hooks/syncWaterfallHook.d.ts +9 -0
  34. package/dist/src/utils/index.d.ts +6 -0
  35. package/dist/src/utils/load.d.ts +9 -0
  36. package/dist/src/utils/logger.d.ts +6 -0
  37. package/dist/src/utils/manifest.d.ts +7 -0
  38. package/dist/src/utils/plugin.d.ts +4 -0
  39. package/dist/src/utils/preload.d.ts +6 -0
  40. package/dist/src/utils/semver/compare.d.ts +9 -0
  41. package/dist/src/utils/semver/constants.d.ts +10 -0
  42. package/dist/src/utils/semver/index.d.ts +2 -0
  43. package/dist/src/utils/semver/parser.d.ts +9 -0
  44. package/dist/src/utils/semver/utils.d.ts +11 -0
  45. package/dist/src/utils/share.d.ts +27 -0
  46. package/dist/src/utils/tool.d.ts +18 -0
  47. package/dist/types.cjs.d.ts +1 -0
  48. package/dist/types.cjs.js +2 -0
  49. package/dist/types.esm.d.ts +1 -0
  50. package/dist/types.esm.js +1 -0
  51. package/package.json +42 -0
@@ -0,0 +1,2980 @@
1
+ import { _ as _extends, a as _object_without_properties_loose } from './polyfills.esm.js';
2
+ import { createLogger, isBrowserEnv, isDebugMode, loadScriptNode, composeKeyWithSeparator, loadScript, safeToString, createLink, createScript, getResourceUrl, isManifestProvider, generateSnapshotFromManifest, warn as warn$1 } from '@module-federation/sdk';
3
+ export { loadScript, loadScriptNode } from '@module-federation/sdk';
4
+ import { getShortErrorMsg, RUNTIME_001, runtimeDescMap, RUNTIME_002, RUNTIME_007, RUNTIME_003, RUNTIME_005, RUNTIME_006, RUNTIME_004 } from '@module-federation/error-codes';
5
+
6
+ const LOG_CATEGORY = '[ Federation Runtime ]';
7
+ // FIXME: pre-bundle ?
8
+ const logger = createLogger(LOG_CATEGORY);
9
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
10
+ function assert(condition, msg) {
11
+ if (!condition) {
12
+ error(msg);
13
+ }
14
+ }
15
+ function error(msg) {
16
+ if (msg instanceof Error) {
17
+ msg.message = `${LOG_CATEGORY}: ${msg.message}`;
18
+ throw msg;
19
+ }
20
+ throw new Error(`${LOG_CATEGORY}: ${msg}`);
21
+ }
22
+ function warn(msg) {
23
+ if (msg instanceof Error) {
24
+ msg.message = `${LOG_CATEGORY}: ${msg.message}`;
25
+ logger.warn(msg);
26
+ } else {
27
+ logger.warn(msg);
28
+ }
29
+ }
30
+
31
+ function addUniqueItem(arr, item) {
32
+ if (arr.findIndex((name)=>name === item) === -1) {
33
+ arr.push(item);
34
+ }
35
+ return arr;
36
+ }
37
+ function getFMId(remoteInfo) {
38
+ if ('version' in remoteInfo && remoteInfo.version) {
39
+ return `${remoteInfo.name}:${remoteInfo.version}`;
40
+ } else if ('entry' in remoteInfo && remoteInfo.entry) {
41
+ return `${remoteInfo.name}:${remoteInfo.entry}`;
42
+ } else {
43
+ return `${remoteInfo.name}`;
44
+ }
45
+ }
46
+ function isRemoteInfoWithEntry(remote) {
47
+ return typeof remote.entry !== 'undefined';
48
+ }
49
+ function isPureRemoteEntry(remote) {
50
+ return !remote.entry.includes('.json') && remote.entry.includes('.js');
51
+ }
52
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
53
+ async function safeWrapper(callback, disableWarn) {
54
+ try {
55
+ const res = await callback();
56
+ return res;
57
+ } catch (e) {
58
+ !disableWarn && warn(e);
59
+ return;
60
+ }
61
+ }
62
+ function isObject(val) {
63
+ return val && typeof val === 'object';
64
+ }
65
+ const objectToString = Object.prototype.toString;
66
+ // eslint-disable-next-line @typescript-eslint/ban-types
67
+ function isPlainObject(val) {
68
+ return objectToString.call(val) === '[object Object]';
69
+ }
70
+ function isStaticResourcesEqual(url1, url2) {
71
+ const REG_EXP = /^(https?:)?\/\//i;
72
+ // Transform url1 and url2 into relative paths
73
+ const relativeUrl1 = url1.replace(REG_EXP, '').replace(/\/$/, '');
74
+ const relativeUrl2 = url2.replace(REG_EXP, '').replace(/\/$/, '');
75
+ // Check if the relative paths are identical
76
+ return relativeUrl1 === relativeUrl2;
77
+ }
78
+ function arrayOptions(options) {
79
+ return Array.isArray(options) ? options : [
80
+ options
81
+ ];
82
+ }
83
+ function getRemoteEntryInfoFromSnapshot(snapshot) {
84
+ const defaultRemoteEntryInfo = {
85
+ url: '',
86
+ type: 'global',
87
+ globalName: ''
88
+ };
89
+ if (isBrowserEnv()) {
90
+ return 'remoteEntry' in snapshot ? {
91
+ url: snapshot.remoteEntry,
92
+ type: snapshot.remoteEntryType,
93
+ globalName: snapshot.globalName
94
+ } : defaultRemoteEntryInfo;
95
+ }
96
+ if ('ssrRemoteEntry' in snapshot) {
97
+ return {
98
+ url: snapshot.ssrRemoteEntry || defaultRemoteEntryInfo.url,
99
+ type: snapshot.ssrRemoteEntryType || defaultRemoteEntryInfo.type,
100
+ globalName: snapshot.globalName
101
+ };
102
+ }
103
+ return defaultRemoteEntryInfo;
104
+ }
105
+ const processModuleAlias = (name, subPath)=>{
106
+ // @host/ ./button -> @host/button
107
+ let moduleName;
108
+ if (name.endsWith('/')) {
109
+ moduleName = name.slice(0, -1);
110
+ } else {
111
+ moduleName = name;
112
+ }
113
+ if (subPath.startsWith('.')) {
114
+ subPath = subPath.slice(1);
115
+ }
116
+ moduleName = moduleName + subPath;
117
+ return moduleName;
118
+ };
119
+
120
+ const CurrentGlobal = typeof globalThis === 'object' ? globalThis : window;
121
+ const nativeGlobal = (()=>{
122
+ try {
123
+ // get real window (incase of sandbox)
124
+ return document.defaultView;
125
+ } catch (e) {
126
+ // node env
127
+ return CurrentGlobal;
128
+ }
129
+ })();
130
+ const Global = nativeGlobal;
131
+ function definePropertyGlobalVal(target, key, val) {
132
+ Object.defineProperty(target, key, {
133
+ value: val,
134
+ configurable: false,
135
+ writable: true
136
+ });
137
+ }
138
+ function includeOwnProperty(target, key) {
139
+ return Object.hasOwnProperty.call(target, key);
140
+ }
141
+ // This section is to prevent encapsulation by certain microfrontend frameworks. Due to reuse policies, sandbox escapes.
142
+ // The sandbox in the microfrontend does not replicate the value of 'configurable'.
143
+ // If there is no loading content on the global object, this section defines the loading object.
144
+ if (!includeOwnProperty(CurrentGlobal, '__GLOBAL_LOADING_REMOTE_ENTRY__')) {
145
+ definePropertyGlobalVal(CurrentGlobal, '__GLOBAL_LOADING_REMOTE_ENTRY__', {});
146
+ }
147
+ const globalLoading = CurrentGlobal.__GLOBAL_LOADING_REMOTE_ENTRY__;
148
+ function setGlobalDefaultVal(target) {
149
+ var _target___FEDERATION__, _target___FEDERATION__1, _target___FEDERATION__2, _target___FEDERATION__3, _target___FEDERATION__4, _target___FEDERATION__5;
150
+ if (includeOwnProperty(target, '__VMOK__') && !includeOwnProperty(target, '__FEDERATION__')) {
151
+ definePropertyGlobalVal(target, '__FEDERATION__', target.__VMOK__);
152
+ }
153
+ if (!includeOwnProperty(target, '__FEDERATION__')) {
154
+ definePropertyGlobalVal(target, '__FEDERATION__', {
155
+ __GLOBAL_PLUGIN__: [],
156
+ __INSTANCES__: [],
157
+ moduleInfo: {},
158
+ __SHARE__: {},
159
+ __MANIFEST_LOADING__: {},
160
+ __PRELOADED_MAP__: new Map()
161
+ });
162
+ definePropertyGlobalVal(target, '__VMOK__', target.__FEDERATION__);
163
+ }
164
+ var ___GLOBAL_PLUGIN__;
165
+ (___GLOBAL_PLUGIN__ = (_target___FEDERATION__ = target.__FEDERATION__).__GLOBAL_PLUGIN__) != null ? ___GLOBAL_PLUGIN__ : _target___FEDERATION__.__GLOBAL_PLUGIN__ = [];
166
+ var ___INSTANCES__;
167
+ (___INSTANCES__ = (_target___FEDERATION__1 = target.__FEDERATION__).__INSTANCES__) != null ? ___INSTANCES__ : _target___FEDERATION__1.__INSTANCES__ = [];
168
+ var _moduleInfo;
169
+ (_moduleInfo = (_target___FEDERATION__2 = target.__FEDERATION__).moduleInfo) != null ? _moduleInfo : _target___FEDERATION__2.moduleInfo = {};
170
+ var ___SHARE__;
171
+ (___SHARE__ = (_target___FEDERATION__3 = target.__FEDERATION__).__SHARE__) != null ? ___SHARE__ : _target___FEDERATION__3.__SHARE__ = {};
172
+ var ___MANIFEST_LOADING__;
173
+ (___MANIFEST_LOADING__ = (_target___FEDERATION__4 = target.__FEDERATION__).__MANIFEST_LOADING__) != null ? ___MANIFEST_LOADING__ : _target___FEDERATION__4.__MANIFEST_LOADING__ = {};
174
+ var ___PRELOADED_MAP__;
175
+ (___PRELOADED_MAP__ = (_target___FEDERATION__5 = target.__FEDERATION__).__PRELOADED_MAP__) != null ? ___PRELOADED_MAP__ : _target___FEDERATION__5.__PRELOADED_MAP__ = new Map();
176
+ }
177
+ setGlobalDefaultVal(CurrentGlobal);
178
+ setGlobalDefaultVal(nativeGlobal);
179
+ function resetFederationGlobalInfo() {
180
+ CurrentGlobal.__FEDERATION__.__GLOBAL_PLUGIN__ = [];
181
+ CurrentGlobal.__FEDERATION__.__INSTANCES__ = [];
182
+ CurrentGlobal.__FEDERATION__.moduleInfo = {};
183
+ CurrentGlobal.__FEDERATION__.__SHARE__ = {};
184
+ CurrentGlobal.__FEDERATION__.__MANIFEST_LOADING__ = {};
185
+ Object.keys(globalLoading).forEach((key)=>{
186
+ delete globalLoading[key];
187
+ });
188
+ }
189
+ function setGlobalFederationInstance(FederationInstance) {
190
+ CurrentGlobal.__FEDERATION__.__INSTANCES__.push(FederationInstance);
191
+ }
192
+ function getGlobalFederationConstructor() {
193
+ return CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR__;
194
+ }
195
+ function setGlobalFederationConstructor(FederationConstructor, isDebug = isDebugMode()) {
196
+ if (isDebug) {
197
+ CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR__ = FederationConstructor;
198
+ CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "0.6.14";
199
+ }
200
+ }
201
+ // eslint-disable-next-line @typescript-eslint/ban-types
202
+ function getInfoWithoutType(target, key) {
203
+ if (typeof key === 'string') {
204
+ const keyRes = target[key];
205
+ if (keyRes) {
206
+ return {
207
+ value: target[key],
208
+ key: key
209
+ };
210
+ } else {
211
+ const targetKeys = Object.keys(target);
212
+ for (const targetKey of targetKeys){
213
+ const [targetTypeOrName, _] = targetKey.split(':');
214
+ const nKey = `${targetTypeOrName}:${key}`;
215
+ const typeWithKeyRes = target[nKey];
216
+ if (typeWithKeyRes) {
217
+ return {
218
+ value: typeWithKeyRes,
219
+ key: nKey
220
+ };
221
+ }
222
+ }
223
+ return {
224
+ value: undefined,
225
+ key: key
226
+ };
227
+ }
228
+ } else {
229
+ throw new Error('key must be string');
230
+ }
231
+ }
232
+ const getGlobalSnapshot = ()=>nativeGlobal.__FEDERATION__.moduleInfo;
233
+ const getTargetSnapshotInfoByModuleInfo = (moduleInfo, snapshot)=>{
234
+ // Check if the remote is included in the hostSnapshot
235
+ const moduleKey = getFMId(moduleInfo);
236
+ const getModuleInfo = getInfoWithoutType(snapshot, moduleKey).value;
237
+ // The remoteSnapshot might not include a version
238
+ if (getModuleInfo && !getModuleInfo.version && 'version' in moduleInfo && moduleInfo['version']) {
239
+ getModuleInfo.version = moduleInfo['version'];
240
+ }
241
+ if (getModuleInfo) {
242
+ return getModuleInfo;
243
+ }
244
+ // If the remote is not included in the hostSnapshot, deploy a micro app snapshot
245
+ if ('version' in moduleInfo && moduleInfo['version']) {
246
+ const { version } = moduleInfo, resModuleInfo = _object_without_properties_loose(moduleInfo, [
247
+ "version"
248
+ ]);
249
+ const moduleKeyWithoutVersion = getFMId(resModuleInfo);
250
+ const getModuleInfoWithoutVersion = getInfoWithoutType(nativeGlobal.__FEDERATION__.moduleInfo, moduleKeyWithoutVersion).value;
251
+ if ((getModuleInfoWithoutVersion == null ? void 0 : getModuleInfoWithoutVersion.version) === version) {
252
+ return getModuleInfoWithoutVersion;
253
+ }
254
+ }
255
+ return;
256
+ };
257
+ const getGlobalSnapshotInfoByModuleInfo = (moduleInfo)=>getTargetSnapshotInfoByModuleInfo(moduleInfo, nativeGlobal.__FEDERATION__.moduleInfo);
258
+ const setGlobalSnapshotInfoByModuleInfo = (remoteInfo, moduleDetailInfo)=>{
259
+ const moduleKey = getFMId(remoteInfo);
260
+ nativeGlobal.__FEDERATION__.moduleInfo[moduleKey] = moduleDetailInfo;
261
+ return nativeGlobal.__FEDERATION__.moduleInfo;
262
+ };
263
+ const addGlobalSnapshot = (moduleInfos)=>{
264
+ nativeGlobal.__FEDERATION__.moduleInfo = _extends({}, nativeGlobal.__FEDERATION__.moduleInfo, moduleInfos);
265
+ return ()=>{
266
+ const keys = Object.keys(moduleInfos);
267
+ for (const key of keys){
268
+ delete nativeGlobal.__FEDERATION__.moduleInfo[key];
269
+ }
270
+ };
271
+ };
272
+ const getRemoteEntryExports = (name, globalName)=>{
273
+ const remoteEntryKey = globalName || `__FEDERATION_${name}:custom__`;
274
+ const entryExports = CurrentGlobal[remoteEntryKey];
275
+ return {
276
+ remoteEntryKey,
277
+ entryExports
278
+ };
279
+ };
280
+ // This function is used to register global plugins.
281
+ // It iterates over the provided plugins and checks if they are already registered.
282
+ // If a plugin is not registered, it is added to the global plugins.
283
+ // If a plugin is already registered, a warning message is logged.
284
+ const registerGlobalPlugins = (plugins)=>{
285
+ const { __GLOBAL_PLUGIN__ } = nativeGlobal.__FEDERATION__;
286
+ plugins.forEach((plugin)=>{
287
+ if (__GLOBAL_PLUGIN__.findIndex((p)=>p.name === plugin.name) === -1) {
288
+ __GLOBAL_PLUGIN__.push(plugin);
289
+ } else {
290
+ warn(`The plugin ${plugin.name} has been registered.`);
291
+ }
292
+ });
293
+ };
294
+ const getGlobalHostPlugins = ()=>nativeGlobal.__FEDERATION__.__GLOBAL_PLUGIN__;
295
+ const getPreloaded = (id)=>CurrentGlobal.__FEDERATION__.__PRELOADED_MAP__.get(id);
296
+ const setPreloaded = (id)=>CurrentGlobal.__FEDERATION__.__PRELOADED_MAP__.set(id, true);
297
+
298
+ const DEFAULT_SCOPE = 'default';
299
+ const DEFAULT_REMOTE_TYPE = 'global';
300
+
301
+ // fork from https://github.com/originjs/vite-plugin-federation/blob/v1.1.12/packages/lib/src/utils/semver/index.ts
302
+ // those constants are based on https://www.rubydoc.info/gems/semantic_range/3.0.0/SemanticRange#BUILDIDENTIFIER-constant
303
+ // Copyright (c)
304
+ // vite-plugin-federation is licensed under Mulan PSL v2.
305
+ // You can use this software according to the terms and conditions of the Mulan PSL v2.
306
+ // You may obtain a copy of Mulan PSL v2 at:
307
+ // http://license.coscl.org.cn/MulanPSL2
308
+ // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
309
+ // See the Mulan PSL v2 for more details.
310
+ const buildIdentifier = '[0-9A-Za-z-]+';
311
+ const build = `(?:\\+(${buildIdentifier}(?:\\.${buildIdentifier})*))`;
312
+ const numericIdentifier = '0|[1-9]\\d*';
313
+ const numericIdentifierLoose = '[0-9]+';
314
+ const nonNumericIdentifier = '\\d*[a-zA-Z-][a-zA-Z0-9-]*';
315
+ const preReleaseIdentifierLoose = `(?:${numericIdentifierLoose}|${nonNumericIdentifier})`;
316
+ const preReleaseLoose = `(?:-?(${preReleaseIdentifierLoose}(?:\\.${preReleaseIdentifierLoose})*))`;
317
+ const preReleaseIdentifier = `(?:${numericIdentifier}|${nonNumericIdentifier})`;
318
+ const preRelease = `(?:-(${preReleaseIdentifier}(?:\\.${preReleaseIdentifier})*))`;
319
+ const xRangeIdentifier = `${numericIdentifier}|x|X|\\*`;
320
+ const xRangePlain = `[v=\\s]*(${xRangeIdentifier})(?:\\.(${xRangeIdentifier})(?:\\.(${xRangeIdentifier})(?:${preRelease})?${build}?)?)?`;
321
+ const hyphenRange = `^\\s*(${xRangePlain})\\s+-\\s+(${xRangePlain})\\s*$`;
322
+ const mainVersionLoose = `(${numericIdentifierLoose})\\.(${numericIdentifierLoose})\\.(${numericIdentifierLoose})`;
323
+ const loosePlain = `[v=\\s]*${mainVersionLoose}${preReleaseLoose}?${build}?`;
324
+ const gtlt = '((?:<|>)?=?)';
325
+ const comparatorTrim = `(\\s*)${gtlt}\\s*(${loosePlain}|${xRangePlain})`;
326
+ const loneTilde = '(?:~>?)';
327
+ const tildeTrim = `(\\s*)${loneTilde}\\s+`;
328
+ const loneCaret = '(?:\\^)';
329
+ const caretTrim = `(\\s*)${loneCaret}\\s+`;
330
+ const star = '(<|>)?=?\\s*\\*';
331
+ const caret = `^${loneCaret}${xRangePlain}$`;
332
+ const mainVersion = `(${numericIdentifier})\\.(${numericIdentifier})\\.(${numericIdentifier})`;
333
+ const fullPlain = `v?${mainVersion}${preRelease}?${build}?`;
334
+ const tilde = `^${loneTilde}${xRangePlain}$`;
335
+ const xRange = `^${gtlt}\\s*${xRangePlain}$`;
336
+ const comparator = `^${gtlt}\\s*(${fullPlain})$|^$`;
337
+ // copy from semver package
338
+ const gte0 = '^\\s*>=\\s*0.0.0\\s*$';
339
+
340
+ // fork from https://github.com/originjs/vite-plugin-federation/blob/v1.1.12/packages/lib/src/utils/semver/index.ts
341
+ // Copyright (c)
342
+ // vite-plugin-federation is licensed under Mulan PSL v2.
343
+ // You can use this software according to the terms and conditions of the Mulan PSL v2.
344
+ // You may obtain a copy of Mulan PSL v2 at:
345
+ // http://license.coscl.org.cn/MulanPSL2
346
+ // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
347
+ // See the Mulan PSL v2 for more details.
348
+ function parseRegex(source) {
349
+ return new RegExp(source);
350
+ }
351
+ function isXVersion(version) {
352
+ return !version || version.toLowerCase() === 'x' || version === '*';
353
+ }
354
+ function pipe(...fns) {
355
+ return (x)=>fns.reduce((v, f)=>f(v), x);
356
+ }
357
+ function extractComparator(comparatorString) {
358
+ return comparatorString.match(parseRegex(comparator));
359
+ }
360
+ function combineVersion(major, minor, patch, preRelease) {
361
+ const mainVersion = `${major}.${minor}.${patch}`;
362
+ if (preRelease) {
363
+ return `${mainVersion}-${preRelease}`;
364
+ }
365
+ return mainVersion;
366
+ }
367
+
368
+ // fork from https://github.com/originjs/vite-plugin-federation/blob/v1.1.12/packages/lib/src/utils/semver/index.ts
369
+ // Copyright (c)
370
+ // vite-plugin-federation is licensed under Mulan PSL v2.
371
+ // You can use this software according to the terms and conditions of the Mulan PSL v2.
372
+ // You may obtain a copy of Mulan PSL v2 at:
373
+ // http://license.coscl.org.cn/MulanPSL2
374
+ // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
375
+ // See the Mulan PSL v2 for more details.
376
+ function parseHyphen(range) {
377
+ return range.replace(parseRegex(hyphenRange), (_range, from, fromMajor, fromMinor, fromPatch, _fromPreRelease, _fromBuild, to, toMajor, toMinor, toPatch, toPreRelease)=>{
378
+ if (isXVersion(fromMajor)) {
379
+ from = '';
380
+ } else if (isXVersion(fromMinor)) {
381
+ from = `>=${fromMajor}.0.0`;
382
+ } else if (isXVersion(fromPatch)) {
383
+ from = `>=${fromMajor}.${fromMinor}.0`;
384
+ } else {
385
+ from = `>=${from}`;
386
+ }
387
+ if (isXVersion(toMajor)) {
388
+ to = '';
389
+ } else if (isXVersion(toMinor)) {
390
+ to = `<${Number(toMajor) + 1}.0.0-0`;
391
+ } else if (isXVersion(toPatch)) {
392
+ to = `<${toMajor}.${Number(toMinor) + 1}.0-0`;
393
+ } else if (toPreRelease) {
394
+ to = `<=${toMajor}.${toMinor}.${toPatch}-${toPreRelease}`;
395
+ } else {
396
+ to = `<=${to}`;
397
+ }
398
+ return `${from} ${to}`.trim();
399
+ });
400
+ }
401
+ function parseComparatorTrim(range) {
402
+ return range.replace(parseRegex(comparatorTrim), '$1$2$3');
403
+ }
404
+ function parseTildeTrim(range) {
405
+ return range.replace(parseRegex(tildeTrim), '$1~');
406
+ }
407
+ function parseCaretTrim(range) {
408
+ return range.replace(parseRegex(caretTrim), '$1^');
409
+ }
410
+ function parseCarets(range) {
411
+ return range.trim().split(/\s+/).map((rangeVersion)=>rangeVersion.replace(parseRegex(caret), (_, major, minor, patch, preRelease)=>{
412
+ if (isXVersion(major)) {
413
+ return '';
414
+ } else if (isXVersion(minor)) {
415
+ return `>=${major}.0.0 <${Number(major) + 1}.0.0-0`;
416
+ } else if (isXVersion(patch)) {
417
+ if (major === '0') {
418
+ return `>=${major}.${minor}.0 <${major}.${Number(minor) + 1}.0-0`;
419
+ } else {
420
+ return `>=${major}.${minor}.0 <${Number(major) + 1}.0.0-0`;
421
+ }
422
+ } else if (preRelease) {
423
+ if (major === '0') {
424
+ if (minor === '0') {
425
+ return `>=${major}.${minor}.${patch}-${preRelease} <${major}.${minor}.${Number(patch) + 1}-0`;
426
+ } else {
427
+ return `>=${major}.${minor}.${patch}-${preRelease} <${major}.${Number(minor) + 1}.0-0`;
428
+ }
429
+ } else {
430
+ return `>=${major}.${minor}.${patch}-${preRelease} <${Number(major) + 1}.0.0-0`;
431
+ }
432
+ } else {
433
+ if (major === '0') {
434
+ if (minor === '0') {
435
+ return `>=${major}.${minor}.${patch} <${major}.${minor}.${Number(patch) + 1}-0`;
436
+ } else {
437
+ return `>=${major}.${minor}.${patch} <${major}.${Number(minor) + 1}.0-0`;
438
+ }
439
+ }
440
+ return `>=${major}.${minor}.${patch} <${Number(major) + 1}.0.0-0`;
441
+ }
442
+ })).join(' ');
443
+ }
444
+ function parseTildes(range) {
445
+ return range.trim().split(/\s+/).map((rangeVersion)=>rangeVersion.replace(parseRegex(tilde), (_, major, minor, patch, preRelease)=>{
446
+ if (isXVersion(major)) {
447
+ return '';
448
+ } else if (isXVersion(minor)) {
449
+ return `>=${major}.0.0 <${Number(major) + 1}.0.0-0`;
450
+ } else if (isXVersion(patch)) {
451
+ return `>=${major}.${minor}.0 <${major}.${Number(minor) + 1}.0-0`;
452
+ } else if (preRelease) {
453
+ return `>=${major}.${minor}.${patch}-${preRelease} <${major}.${Number(minor) + 1}.0-0`;
454
+ }
455
+ return `>=${major}.${minor}.${patch} <${major}.${Number(minor) + 1}.0-0`;
456
+ })).join(' ');
457
+ }
458
+ function parseXRanges(range) {
459
+ return range.split(/\s+/).map((rangeVersion)=>rangeVersion.trim().replace(parseRegex(xRange), (ret, gtlt, major, minor, patch, preRelease)=>{
460
+ const isXMajor = isXVersion(major);
461
+ const isXMinor = isXMajor || isXVersion(minor);
462
+ const isXPatch = isXMinor || isXVersion(patch);
463
+ if (gtlt === '=' && isXPatch) {
464
+ gtlt = '';
465
+ }
466
+ preRelease = '';
467
+ if (isXMajor) {
468
+ if (gtlt === '>' || gtlt === '<') {
469
+ // nothing is allowed
470
+ return '<0.0.0-0';
471
+ } else {
472
+ // nothing is forbidden
473
+ return '*';
474
+ }
475
+ } else if (gtlt && isXPatch) {
476
+ // replace X with 0
477
+ if (isXMinor) {
478
+ minor = 0;
479
+ }
480
+ patch = 0;
481
+ if (gtlt === '>') {
482
+ // >1 => >=2.0.0
483
+ // >1.2 => >=1.3.0
484
+ gtlt = '>=';
485
+ if (isXMinor) {
486
+ major = Number(major) + 1;
487
+ minor = 0;
488
+ patch = 0;
489
+ } else {
490
+ minor = Number(minor) + 1;
491
+ patch = 0;
492
+ }
493
+ } else if (gtlt === '<=') {
494
+ // <=0.7.x is actually <0.8.0, since any 0.7.x should pass
495
+ // Similarly, <=7.x is actually <8.0.0, etc.
496
+ gtlt = '<';
497
+ if (isXMinor) {
498
+ major = Number(major) + 1;
499
+ } else {
500
+ minor = Number(minor) + 1;
501
+ }
502
+ }
503
+ if (gtlt === '<') {
504
+ preRelease = '-0';
505
+ }
506
+ return `${gtlt + major}.${minor}.${patch}${preRelease}`;
507
+ } else if (isXMinor) {
508
+ return `>=${major}.0.0${preRelease} <${Number(major) + 1}.0.0-0`;
509
+ } else if (isXPatch) {
510
+ return `>=${major}.${minor}.0${preRelease} <${major}.${Number(minor) + 1}.0-0`;
511
+ }
512
+ return ret;
513
+ })).join(' ');
514
+ }
515
+ function parseStar(range) {
516
+ return range.trim().replace(parseRegex(star), '');
517
+ }
518
+ function parseGTE0(comparatorString) {
519
+ return comparatorString.trim().replace(parseRegex(gte0), '');
520
+ }
521
+
522
+ // fork from https://github.com/originjs/vite-plugin-federation/blob/v1.1.12/packages/lib/src/utils/semver/index.ts
523
+ // Copyright (c)
524
+ // vite-plugin-federation is licensed under Mulan PSL v2.
525
+ // You can use this software according to the terms and conditions of the Mulan PSL v2.
526
+ // You may obtain a copy of Mulan PSL v2 at:
527
+ // http://license.coscl.org.cn/MulanPSL2
528
+ // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
529
+ // See the Mulan PSL v2 for more details.
530
+ function compareAtom(rangeAtom, versionAtom) {
531
+ rangeAtom = Number(rangeAtom) || rangeAtom;
532
+ versionAtom = Number(versionAtom) || versionAtom;
533
+ if (rangeAtom > versionAtom) {
534
+ return 1;
535
+ }
536
+ if (rangeAtom === versionAtom) {
537
+ return 0;
538
+ }
539
+ return -1;
540
+ }
541
+ function comparePreRelease(rangeAtom, versionAtom) {
542
+ const { preRelease: rangePreRelease } = rangeAtom;
543
+ const { preRelease: versionPreRelease } = versionAtom;
544
+ if (rangePreRelease === undefined && Boolean(versionPreRelease)) {
545
+ return 1;
546
+ }
547
+ if (Boolean(rangePreRelease) && versionPreRelease === undefined) {
548
+ return -1;
549
+ }
550
+ if (rangePreRelease === undefined && versionPreRelease === undefined) {
551
+ return 0;
552
+ }
553
+ for(let i = 0, n = rangePreRelease.length; i <= n; i++){
554
+ const rangeElement = rangePreRelease[i];
555
+ const versionElement = versionPreRelease[i];
556
+ if (rangeElement === versionElement) {
557
+ continue;
558
+ }
559
+ if (rangeElement === undefined && versionElement === undefined) {
560
+ return 0;
561
+ }
562
+ if (!rangeElement) {
563
+ return 1;
564
+ }
565
+ if (!versionElement) {
566
+ return -1;
567
+ }
568
+ return compareAtom(rangeElement, versionElement);
569
+ }
570
+ return 0;
571
+ }
572
+ function compareVersion(rangeAtom, versionAtom) {
573
+ return compareAtom(rangeAtom.major, versionAtom.major) || compareAtom(rangeAtom.minor, versionAtom.minor) || compareAtom(rangeAtom.patch, versionAtom.patch) || comparePreRelease(rangeAtom, versionAtom);
574
+ }
575
+ function eq(rangeAtom, versionAtom) {
576
+ return rangeAtom.version === versionAtom.version;
577
+ }
578
+ function compare(rangeAtom, versionAtom) {
579
+ switch(rangeAtom.operator){
580
+ case '':
581
+ case '=':
582
+ return eq(rangeAtom, versionAtom);
583
+ case '>':
584
+ return compareVersion(rangeAtom, versionAtom) < 0;
585
+ case '>=':
586
+ return eq(rangeAtom, versionAtom) || compareVersion(rangeAtom, versionAtom) < 0;
587
+ case '<':
588
+ return compareVersion(rangeAtom, versionAtom) > 0;
589
+ case '<=':
590
+ return eq(rangeAtom, versionAtom) || compareVersion(rangeAtom, versionAtom) > 0;
591
+ case undefined:
592
+ {
593
+ // mean * or x -> all versions
594
+ return true;
595
+ }
596
+ default:
597
+ return false;
598
+ }
599
+ }
600
+
601
+ // fork from https://github.com/originjs/vite-plugin-federation/blob/v1.1.12/packages/lib/src/utils/semver/index.ts
602
+ // Copyright (c)
603
+ // vite-plugin-federation is licensed under Mulan PSL v2.
604
+ // You can use this software according to the terms and conditions of the Mulan PSL v2.
605
+ // You may obtain a copy of Mulan PSL v2 at:
606
+ // http://license.coscl.org.cn/MulanPSL2
607
+ // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
608
+ // See the Mulan PSL v2 for more details.
609
+ function parseComparatorString(range) {
610
+ return pipe(// handle caret
611
+ // ^ --> * (any, kinda silly)
612
+ // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0-0
613
+ // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0-0
614
+ // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0
615
+ // ^1.2.3 --> >=1.2.3 <2.0.0-0
616
+ // ^1.2.0 --> >=1.2.0 <2.0.0-0
617
+ parseCarets, // handle tilde
618
+ // ~, ~> --> * (any, kinda silly)
619
+ // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0
620
+ // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0-0
621
+ // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0
622
+ // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0
623
+ // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0
624
+ parseTildes, parseXRanges, parseStar)(range);
625
+ }
626
+ function parseRange(range) {
627
+ return pipe(// handle hyphenRange
628
+ // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
629
+ parseHyphen, // handle trim comparator
630
+ // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
631
+ parseComparatorTrim, // handle trim tilde
632
+ // `~ 1.2.3` => `~1.2.3`
633
+ parseTildeTrim, // handle trim caret
634
+ // `^ 1.2.3` => `^1.2.3`
635
+ parseCaretTrim)(range.trim()).split(/\s+/).join(' ');
636
+ }
637
+ function satisfy(version, range) {
638
+ if (!version) {
639
+ return false;
640
+ }
641
+ const parsedRange = parseRange(range);
642
+ const parsedComparator = parsedRange.split(' ').map((rangeVersion)=>parseComparatorString(rangeVersion)).join(' ');
643
+ const comparators = parsedComparator.split(/\s+/).map((comparator)=>parseGTE0(comparator));
644
+ const extractedVersion = extractComparator(version);
645
+ if (!extractedVersion) {
646
+ return false;
647
+ }
648
+ const [, versionOperator, , versionMajor, versionMinor, versionPatch, versionPreRelease] = extractedVersion;
649
+ const versionAtom = {
650
+ operator: versionOperator,
651
+ version: combineVersion(versionMajor, versionMinor, versionPatch, versionPreRelease),
652
+ major: versionMajor,
653
+ minor: versionMinor,
654
+ patch: versionPatch,
655
+ preRelease: versionPreRelease == null ? void 0 : versionPreRelease.split('.')
656
+ };
657
+ for (const comparator of comparators){
658
+ const extractedComparator = extractComparator(comparator);
659
+ if (!extractedComparator) {
660
+ return false;
661
+ }
662
+ const [, rangeOperator, , rangeMajor, rangeMinor, rangePatch, rangePreRelease] = extractedComparator;
663
+ const rangeAtom = {
664
+ operator: rangeOperator,
665
+ version: combineVersion(rangeMajor, rangeMinor, rangePatch, rangePreRelease),
666
+ major: rangeMajor,
667
+ minor: rangeMinor,
668
+ patch: rangePatch,
669
+ preRelease: rangePreRelease == null ? void 0 : rangePreRelease.split('.')
670
+ };
671
+ if (!compare(rangeAtom, versionAtom)) {
672
+ return false; // early return
673
+ }
674
+ }
675
+ return true;
676
+ }
677
+
678
+ function formatShare(shareArgs, from, name, shareStrategy) {
679
+ let get;
680
+ if ('get' in shareArgs) {
681
+ // eslint-disable-next-line prefer-destructuring
682
+ get = shareArgs.get;
683
+ } else if ('lib' in shareArgs) {
684
+ get = ()=>Promise.resolve(shareArgs.lib);
685
+ } else {
686
+ get = ()=>Promise.resolve(()=>{
687
+ throw new Error(`Can not get shared '${name}'!`);
688
+ });
689
+ }
690
+ if (shareArgs.strategy) {
691
+ warn(`"shared.strategy is deprecated, please set in initOptions.shareStrategy instead!"`);
692
+ }
693
+ var _shareArgs_version, _shareArgs_scope, _shareArgs_strategy;
694
+ return _extends({
695
+ deps: [],
696
+ useIn: [],
697
+ from,
698
+ loading: null
699
+ }, shareArgs, {
700
+ shareConfig: _extends({
701
+ requiredVersion: `^${shareArgs.version}`,
702
+ singleton: false,
703
+ eager: false,
704
+ strictVersion: false
705
+ }, shareArgs.shareConfig),
706
+ get,
707
+ loaded: (shareArgs == null ? void 0 : shareArgs.loaded) || 'lib' in shareArgs ? true : undefined,
708
+ version: (_shareArgs_version = shareArgs.version) != null ? _shareArgs_version : '0',
709
+ scope: Array.isArray(shareArgs.scope) ? shareArgs.scope : [
710
+ (_shareArgs_scope = shareArgs.scope) != null ? _shareArgs_scope : 'default'
711
+ ],
712
+ strategy: ((_shareArgs_strategy = shareArgs.strategy) != null ? _shareArgs_strategy : shareStrategy) || 'version-first'
713
+ });
714
+ }
715
+ function formatShareConfigs(globalOptions, userOptions) {
716
+ const shareArgs = userOptions.shared || {};
717
+ const from = userOptions.name;
718
+ const shareInfos = Object.keys(shareArgs).reduce((res, pkgName)=>{
719
+ const arrayShareArgs = arrayOptions(shareArgs[pkgName]);
720
+ res[pkgName] = res[pkgName] || [];
721
+ arrayShareArgs.forEach((shareConfig)=>{
722
+ res[pkgName].push(formatShare(shareConfig, from, pkgName, userOptions.shareStrategy));
723
+ });
724
+ return res;
725
+ }, {});
726
+ const shared = _extends({}, globalOptions.shared);
727
+ Object.keys(shareInfos).forEach((shareKey)=>{
728
+ if (!shared[shareKey]) {
729
+ shared[shareKey] = shareInfos[shareKey];
730
+ } else {
731
+ shareInfos[shareKey].forEach((newUserSharedOptions)=>{
732
+ const isSameVersion = shared[shareKey].find((sharedVal)=>sharedVal.version === newUserSharedOptions.version);
733
+ if (!isSameVersion) {
734
+ shared[shareKey].push(newUserSharedOptions);
735
+ }
736
+ });
737
+ }
738
+ });
739
+ return {
740
+ shared,
741
+ shareInfos
742
+ };
743
+ }
744
+ function versionLt(a, b) {
745
+ const transformInvalidVersion = (version)=>{
746
+ const isNumberVersion = !Number.isNaN(Number(version));
747
+ if (isNumberVersion) {
748
+ const splitArr = version.split('.');
749
+ let validVersion = version;
750
+ for(let i = 0; i < 3 - splitArr.length; i++){
751
+ validVersion += '.0';
752
+ }
753
+ return validVersion;
754
+ }
755
+ return version;
756
+ };
757
+ if (satisfy(transformInvalidVersion(a), `<=${transformInvalidVersion(b)}`)) {
758
+ return true;
759
+ } else {
760
+ return false;
761
+ }
762
+ }
763
+ const findVersion = (shareVersionMap, cb)=>{
764
+ const callback = cb || function(prev, cur) {
765
+ return versionLt(prev, cur);
766
+ };
767
+ return Object.keys(shareVersionMap).reduce((prev, cur)=>{
768
+ if (!prev) {
769
+ return cur;
770
+ }
771
+ if (callback(prev, cur)) {
772
+ return cur;
773
+ }
774
+ // default version is '0' https://github.com/webpack/webpack/blob/main/lib/sharing/ProvideSharedModule.js#L136
775
+ if (prev === '0') {
776
+ return cur;
777
+ }
778
+ return prev;
779
+ }, 0);
780
+ };
781
+ const isLoaded = (shared)=>{
782
+ return Boolean(shared.loaded) || typeof shared.lib === 'function';
783
+ };
784
+ const isLoading = (shared)=>{
785
+ return Boolean(shared.loading);
786
+ };
787
+ function findSingletonVersionOrderByVersion(shareScopeMap, scope, pkgName) {
788
+ const versions = shareScopeMap[scope][pkgName];
789
+ const callback = function(prev, cur) {
790
+ return !isLoaded(versions[prev]) && versionLt(prev, cur);
791
+ };
792
+ return findVersion(shareScopeMap[scope][pkgName], callback);
793
+ }
794
+ function findSingletonVersionOrderByLoaded(shareScopeMap, scope, pkgName) {
795
+ const versions = shareScopeMap[scope][pkgName];
796
+ const callback = function(prev, cur) {
797
+ const isLoadingOrLoaded = (shared)=>{
798
+ return isLoaded(shared) || isLoading(shared);
799
+ };
800
+ if (isLoadingOrLoaded(versions[cur])) {
801
+ if (isLoadingOrLoaded(versions[prev])) {
802
+ return Boolean(versionLt(prev, cur));
803
+ } else {
804
+ return true;
805
+ }
806
+ }
807
+ if (isLoadingOrLoaded(versions[prev])) {
808
+ return false;
809
+ }
810
+ return versionLt(prev, cur);
811
+ };
812
+ return findVersion(shareScopeMap[scope][pkgName], callback);
813
+ }
814
+ function getFindShareFunction(strategy) {
815
+ if (strategy === 'loaded-first') {
816
+ return findSingletonVersionOrderByLoaded;
817
+ }
818
+ return findSingletonVersionOrderByVersion;
819
+ }
820
+ function getRegisteredShare(localShareScopeMap, pkgName, shareInfo, resolveShare) {
821
+ if (!localShareScopeMap) {
822
+ return;
823
+ }
824
+ const { shareConfig, scope = DEFAULT_SCOPE, strategy } = shareInfo;
825
+ const scopes = Array.isArray(scope) ? scope : [
826
+ scope
827
+ ];
828
+ for (const sc of scopes){
829
+ if (shareConfig && localShareScopeMap[sc] && localShareScopeMap[sc][pkgName]) {
830
+ const { requiredVersion } = shareConfig;
831
+ const findShareFunction = getFindShareFunction(strategy);
832
+ const maxOrSingletonVersion = findShareFunction(localShareScopeMap, sc, pkgName);
833
+ //@ts-ignore
834
+ const defaultResolver = ()=>{
835
+ if (shareConfig.singleton) {
836
+ if (typeof requiredVersion === 'string' && !satisfy(maxOrSingletonVersion, requiredVersion)) {
837
+ const msg = `Version ${maxOrSingletonVersion} from ${maxOrSingletonVersion && localShareScopeMap[sc][pkgName][maxOrSingletonVersion].from} of shared singleton module ${pkgName} does not satisfy the requirement of ${shareInfo.from} which needs ${requiredVersion})`;
838
+ if (shareConfig.strictVersion) {
839
+ error(msg);
840
+ } else {
841
+ warn(msg);
842
+ }
843
+ }
844
+ return localShareScopeMap[sc][pkgName][maxOrSingletonVersion];
845
+ } else {
846
+ if (requiredVersion === false || requiredVersion === '*') {
847
+ return localShareScopeMap[sc][pkgName][maxOrSingletonVersion];
848
+ }
849
+ if (satisfy(maxOrSingletonVersion, requiredVersion)) {
850
+ return localShareScopeMap[sc][pkgName][maxOrSingletonVersion];
851
+ }
852
+ for (const [versionKey, versionValue] of Object.entries(localShareScopeMap[sc][pkgName])){
853
+ if (satisfy(versionKey, requiredVersion)) {
854
+ return versionValue;
855
+ }
856
+ }
857
+ }
858
+ };
859
+ const params = {
860
+ shareScopeMap: localShareScopeMap,
861
+ scope: sc,
862
+ pkgName,
863
+ version: maxOrSingletonVersion,
864
+ GlobalFederation: Global.__FEDERATION__,
865
+ resolver: defaultResolver
866
+ };
867
+ const resolveShared = resolveShare.emit(params) || params;
868
+ return resolveShared.resolver();
869
+ }
870
+ }
871
+ }
872
+ function getGlobalShareScope() {
873
+ return Global.__FEDERATION__.__SHARE__;
874
+ }
875
+ function getTargetSharedOptions(options) {
876
+ const { pkgName, extraOptions, shareInfos } = options;
877
+ const defaultResolver = (sharedOptions)=>{
878
+ if (!sharedOptions) {
879
+ return undefined;
880
+ }
881
+ const shareVersionMap = {};
882
+ sharedOptions.forEach((shared)=>{
883
+ shareVersionMap[shared.version] = shared;
884
+ });
885
+ const callback = function(prev, cur) {
886
+ return !isLoaded(shareVersionMap[prev]) && versionLt(prev, cur);
887
+ };
888
+ const maxVersion = findVersion(shareVersionMap, callback);
889
+ return shareVersionMap[maxVersion];
890
+ };
891
+ var _extraOptions_resolver;
892
+ const resolver = (_extraOptions_resolver = extraOptions == null ? void 0 : extraOptions.resolver) != null ? _extraOptions_resolver : defaultResolver;
893
+ return Object.assign({}, resolver(shareInfos[pkgName]), extraOptions == null ? void 0 : extraOptions.customShareInfo);
894
+ }
895
+
896
+ const ShareUtils = {
897
+ getRegisteredShare,
898
+ getGlobalShareScope
899
+ };
900
+ const GlobalUtils = {
901
+ Global,
902
+ nativeGlobal,
903
+ resetFederationGlobalInfo,
904
+ setGlobalFederationInstance,
905
+ getGlobalFederationConstructor,
906
+ setGlobalFederationConstructor,
907
+ getInfoWithoutType,
908
+ getGlobalSnapshot,
909
+ getTargetSnapshotInfoByModuleInfo,
910
+ getGlobalSnapshotInfoByModuleInfo,
911
+ setGlobalSnapshotInfoByModuleInfo,
912
+ addGlobalSnapshot,
913
+ getRemoteEntryExports,
914
+ registerGlobalPlugins,
915
+ getGlobalHostPlugins,
916
+ getPreloaded,
917
+ setPreloaded
918
+ };
919
+ var helpers = {
920
+ global: GlobalUtils,
921
+ share: ShareUtils
922
+ };
923
+
924
+ function getBuilderId() {
925
+ //@ts-ignore
926
+ return typeof FEDERATION_BUILD_IDENTIFIER !== 'undefined' ? FEDERATION_BUILD_IDENTIFIER : '';
927
+ }
928
+
929
+ // Function to match a remote with its name and expose
930
+ // id: pkgName(@federation/app1) + expose(button) = @federation/app1/button
931
+ // id: alias(app1) + expose(button) = app1/button
932
+ // id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort
933
+ function matchRemoteWithNameAndExpose(remotes, id) {
934
+ for (const remote of remotes){
935
+ // match pkgName
936
+ const isNameMatched = id.startsWith(remote.name);
937
+ let expose = id.replace(remote.name, '');
938
+ if (isNameMatched) {
939
+ if (expose.startsWith('/')) {
940
+ const pkgNameOrAlias = remote.name;
941
+ expose = `.${expose}`;
942
+ return {
943
+ pkgNameOrAlias,
944
+ expose,
945
+ remote
946
+ };
947
+ } else if (expose === '') {
948
+ return {
949
+ pkgNameOrAlias: remote.name,
950
+ expose: '.',
951
+ remote
952
+ };
953
+ }
954
+ }
955
+ // match alias
956
+ const isAliasMatched = remote.alias && id.startsWith(remote.alias);
957
+ let exposeWithAlias = remote.alias && id.replace(remote.alias, '');
958
+ if (remote.alias && isAliasMatched) {
959
+ if (exposeWithAlias && exposeWithAlias.startsWith('/')) {
960
+ const pkgNameOrAlias = remote.alias;
961
+ exposeWithAlias = `.${exposeWithAlias}`;
962
+ return {
963
+ pkgNameOrAlias,
964
+ expose: exposeWithAlias,
965
+ remote
966
+ };
967
+ } else if (exposeWithAlias === '') {
968
+ return {
969
+ pkgNameOrAlias: remote.alias,
970
+ expose: '.',
971
+ remote
972
+ };
973
+ }
974
+ }
975
+ }
976
+ return;
977
+ }
978
+ // Function to match a remote with its name or alias
979
+ function matchRemote(remotes, nameOrAlias) {
980
+ for (const remote of remotes){
981
+ const isNameMatched = nameOrAlias === remote.name;
982
+ if (isNameMatched) {
983
+ return remote;
984
+ }
985
+ const isAliasMatched = remote.alias && nameOrAlias === remote.alias;
986
+ if (isAliasMatched) {
987
+ return remote;
988
+ }
989
+ }
990
+ return;
991
+ }
992
+
993
+ function registerPlugins(plugins, hookInstances) {
994
+ const globalPlugins = getGlobalHostPlugins();
995
+ // Incorporate global plugins
996
+ if (globalPlugins.length > 0) {
997
+ globalPlugins.forEach((plugin)=>{
998
+ if (plugins == null ? void 0 : plugins.find((item)=>item.name !== plugin.name)) {
999
+ plugins.push(plugin);
1000
+ }
1001
+ });
1002
+ }
1003
+ if (plugins && plugins.length > 0) {
1004
+ plugins.forEach((plugin)=>{
1005
+ hookInstances.forEach((hookInstance)=>{
1006
+ hookInstance.applyPlugin(plugin);
1007
+ });
1008
+ });
1009
+ }
1010
+ return plugins;
1011
+ }
1012
+
1013
+ async function loadEsmEntry({ entry, remoteEntryExports }) {
1014
+ return new Promise((resolve, reject)=>{
1015
+ try {
1016
+ if (!remoteEntryExports) {
1017
+ import(/* webpackIgnore: true */ entry).then(resolve).catch(reject);
1018
+ } else {
1019
+ resolve(remoteEntryExports);
1020
+ }
1021
+ } catch (e) {
1022
+ reject(e);
1023
+ }
1024
+ });
1025
+ }
1026
+ async function loadSystemJsEntry({ entry, remoteEntryExports }) {
1027
+ return new Promise((resolve, reject)=>{
1028
+ try {
1029
+ if (!remoteEntryExports) {
1030
+ //@ts-ignore
1031
+ if (typeof __system_context__ === 'undefined') {
1032
+ //@ts-ignore
1033
+ System.import(entry).then(resolve).catch(reject);
1034
+ } else {
1035
+ new Function('callbacks', `System.import("${entry}").then(callbacks[0]).catch(callbacks[1])`)([
1036
+ resolve,
1037
+ reject
1038
+ ]);
1039
+ }
1040
+ } else {
1041
+ resolve(remoteEntryExports);
1042
+ }
1043
+ } catch (e) {
1044
+ reject(e);
1045
+ }
1046
+ });
1047
+ }
1048
+ async function loadEntryScript({ name, globalName, entry, loaderHook }) {
1049
+ const { entryExports: remoteEntryExports } = getRemoteEntryExports(name, globalName);
1050
+ if (remoteEntryExports) {
1051
+ return remoteEntryExports;
1052
+ }
1053
+ return loadScript(entry, {
1054
+ attrs: {},
1055
+ createScriptHook: (url, attrs)=>{
1056
+ const res = loaderHook.lifecycle.createScript.emit({
1057
+ url,
1058
+ attrs
1059
+ });
1060
+ if (!res) return;
1061
+ if (res instanceof HTMLScriptElement) {
1062
+ return res;
1063
+ }
1064
+ if ('script' in res || 'timeout' in res) {
1065
+ return res;
1066
+ }
1067
+ return;
1068
+ }
1069
+ }).then(()=>{
1070
+ const { remoteEntryKey, entryExports } = getRemoteEntryExports(name, globalName);
1071
+ assert(entryExports, getShortErrorMsg(RUNTIME_001, runtimeDescMap, {
1072
+ remoteName: name,
1073
+ remoteEntryUrl: entry,
1074
+ remoteEntryKey
1075
+ }));
1076
+ return entryExports;
1077
+ }).catch((e)=>{
1078
+ throw e;
1079
+ });
1080
+ }
1081
+ async function loadEntryDom({ remoteInfo, remoteEntryExports, loaderHook }) {
1082
+ const { entry, entryGlobalName: globalName, name, type } = remoteInfo;
1083
+ switch(type){
1084
+ case 'esm':
1085
+ case 'module':
1086
+ return loadEsmEntry({
1087
+ entry,
1088
+ remoteEntryExports
1089
+ });
1090
+ case 'system':
1091
+ return loadSystemJsEntry({
1092
+ entry,
1093
+ remoteEntryExports
1094
+ });
1095
+ default:
1096
+ return loadEntryScript({
1097
+ entry,
1098
+ globalName,
1099
+ name,
1100
+ loaderHook
1101
+ });
1102
+ }
1103
+ }
1104
+ async function loadEntryNode({ remoteInfo, loaderHook }) {
1105
+ const { entry, entryGlobalName: globalName, name, type } = remoteInfo;
1106
+ const { entryExports: remoteEntryExports } = getRemoteEntryExports(name, globalName);
1107
+ if (remoteEntryExports) {
1108
+ return remoteEntryExports;
1109
+ }
1110
+ return loadScriptNode(entry, {
1111
+ attrs: {
1112
+ name,
1113
+ globalName,
1114
+ type
1115
+ },
1116
+ loaderHook: {
1117
+ createScriptHook: (url, attrs = {})=>{
1118
+ const res = loaderHook.lifecycle.createScript.emit({
1119
+ url,
1120
+ attrs
1121
+ });
1122
+ if (!res) return;
1123
+ if ('url' in res) {
1124
+ return res;
1125
+ }
1126
+ return;
1127
+ }
1128
+ }
1129
+ }).then(()=>{
1130
+ const { remoteEntryKey, entryExports } = getRemoteEntryExports(name, globalName);
1131
+ assert(entryExports, getShortErrorMsg(RUNTIME_001, runtimeDescMap, {
1132
+ remoteName: name,
1133
+ remoteEntryUrl: entry,
1134
+ remoteEntryKey
1135
+ }));
1136
+ return entryExports;
1137
+ }).catch((e)=>{
1138
+ throw e;
1139
+ });
1140
+ }
1141
+ function getRemoteEntryUniqueKey(remoteInfo) {
1142
+ const { entry, name } = remoteInfo;
1143
+ return composeKeyWithSeparator(name, entry);
1144
+ }
1145
+ async function getRemoteEntry({ origin, remoteEntryExports, remoteInfo }) {
1146
+ const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);
1147
+ if (remoteEntryExports) {
1148
+ return remoteEntryExports;
1149
+ }
1150
+ if (!globalLoading[uniqueKey]) {
1151
+ const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;
1152
+ origin.loaderHook.lifecycle.createScript;
1153
+ const loaderHook = origin.loaderHook;
1154
+ globalLoading[uniqueKey] = loadEntryHook.emit({
1155
+ loaderHook,
1156
+ remoteInfo,
1157
+ remoteEntryExports
1158
+ }).then((res)=>{
1159
+ if (res) {
1160
+ return res;
1161
+ }
1162
+ return isBrowserEnv() ? loadEntryDom({
1163
+ remoteInfo,
1164
+ remoteEntryExports,
1165
+ loaderHook
1166
+ }) : loadEntryNode({
1167
+ remoteInfo,
1168
+ loaderHook
1169
+ });
1170
+ });
1171
+ }
1172
+ return globalLoading[uniqueKey];
1173
+ }
1174
+ function getRemoteInfo(remote) {
1175
+ return _extends({}, remote, {
1176
+ entry: 'entry' in remote ? remote.entry : '',
1177
+ type: remote.type || DEFAULT_REMOTE_TYPE,
1178
+ entryGlobalName: remote.entryGlobalName || remote.name,
1179
+ shareScope: remote.shareScope || DEFAULT_SCOPE
1180
+ });
1181
+ }
1182
+
1183
+ let Module = class Module {
1184
+ async getEntry() {
1185
+ if (this.remoteEntryExports) {
1186
+ return this.remoteEntryExports;
1187
+ }
1188
+ // Get remoteEntry.js
1189
+ const remoteEntryExports = await getRemoteEntry({
1190
+ origin: this.host,
1191
+ remoteInfo: this.remoteInfo,
1192
+ remoteEntryExports: this.remoteEntryExports
1193
+ });
1194
+ assert(remoteEntryExports, `remoteEntryExports is undefined \n ${safeToString(this.remoteInfo)}`);
1195
+ this.remoteEntryExports = remoteEntryExports;
1196
+ return this.remoteEntryExports;
1197
+ }
1198
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
1199
+ async get(id, expose, options, remoteSnapshot) {
1200
+ const { loadFactory = true } = options || {
1201
+ loadFactory: true
1202
+ };
1203
+ // Get remoteEntry.js
1204
+ const remoteEntryExports = await this.getEntry();
1205
+ if (!this.inited) {
1206
+ const localShareScopeMap = this.host.shareScopeMap;
1207
+ const remoteShareScope = this.remoteInfo.shareScope || 'default';
1208
+ if (!localShareScopeMap[remoteShareScope]) {
1209
+ localShareScopeMap[remoteShareScope] = {};
1210
+ }
1211
+ const shareScope = localShareScopeMap[remoteShareScope];
1212
+ const initScope = [];
1213
+ const remoteEntryInitOptions = {
1214
+ version: this.remoteInfo.version || ''
1215
+ };
1216
+ // Help to find host instance
1217
+ Object.defineProperty(remoteEntryInitOptions, 'shareScopeMap', {
1218
+ value: localShareScopeMap,
1219
+ // remoteEntryInitOptions will be traversed and assigned during container init, ,so this attribute is not allowed to be traversed
1220
+ enumerable: false
1221
+ });
1222
+ const initContainerOptions = await this.host.hooks.lifecycle.beforeInitContainer.emit({
1223
+ shareScope,
1224
+ // @ts-ignore shareScopeMap will be set by Object.defineProperty
1225
+ remoteEntryInitOptions,
1226
+ initScope,
1227
+ remoteInfo: this.remoteInfo,
1228
+ origin: this.host
1229
+ });
1230
+ if (typeof (remoteEntryExports == null ? void 0 : remoteEntryExports.init) === 'undefined') {
1231
+ error(getShortErrorMsg(RUNTIME_002, runtimeDescMap, {
1232
+ remoteName: name,
1233
+ remoteEntryUrl: this.remoteInfo.entry,
1234
+ remoteEntryKey: this.remoteInfo.entryGlobalName
1235
+ }));
1236
+ }
1237
+ await remoteEntryExports.init(initContainerOptions.shareScope, initContainerOptions.initScope, initContainerOptions.remoteEntryInitOptions);
1238
+ await this.host.hooks.lifecycle.initContainer.emit(_extends({}, initContainerOptions, {
1239
+ id,
1240
+ remoteSnapshot,
1241
+ remoteEntryExports
1242
+ }));
1243
+ }
1244
+ this.lib = remoteEntryExports;
1245
+ this.inited = true;
1246
+ let moduleFactory;
1247
+ moduleFactory = await this.host.loaderHook.lifecycle.getModuleFactory.emit({
1248
+ remoteEntryExports,
1249
+ expose,
1250
+ moduleInfo: this.remoteInfo
1251
+ });
1252
+ // get exposeGetter
1253
+ if (!moduleFactory) {
1254
+ moduleFactory = await remoteEntryExports.get(expose);
1255
+ }
1256
+ assert(moduleFactory, `${getFMId(this.remoteInfo)} remote don't export ${expose}.`);
1257
+ // keep symbol for module name always one format
1258
+ const symbolName = processModuleAlias(this.remoteInfo.name, expose);
1259
+ const wrapModuleFactory = this.wraperFactory(moduleFactory, symbolName);
1260
+ if (!loadFactory) {
1261
+ return wrapModuleFactory;
1262
+ }
1263
+ const exposeContent = await wrapModuleFactory();
1264
+ return exposeContent;
1265
+ }
1266
+ wraperFactory(moduleFactory, id) {
1267
+ function defineModuleId(res, id) {
1268
+ if (res && typeof res === 'object' && Object.isExtensible(res) && !Object.getOwnPropertyDescriptor(res, Symbol.for('mf_module_id'))) {
1269
+ Object.defineProperty(res, Symbol.for('mf_module_id'), {
1270
+ value: id,
1271
+ enumerable: false
1272
+ });
1273
+ }
1274
+ }
1275
+ if (moduleFactory instanceof Promise) {
1276
+ return async ()=>{
1277
+ const res = await moduleFactory();
1278
+ // This parameter is used for bridge debugging
1279
+ defineModuleId(res, id);
1280
+ return res;
1281
+ };
1282
+ } else {
1283
+ return ()=>{
1284
+ const res = moduleFactory();
1285
+ // This parameter is used for bridge debugging
1286
+ defineModuleId(res, id);
1287
+ return res;
1288
+ };
1289
+ }
1290
+ }
1291
+ constructor({ remoteInfo, host }){
1292
+ this.inited = false;
1293
+ this.lib = undefined;
1294
+ this.remoteInfo = remoteInfo;
1295
+ this.host = host;
1296
+ }
1297
+ };
1298
+
1299
+ class SyncHook {
1300
+ on(fn) {
1301
+ if (typeof fn === 'function') {
1302
+ this.listeners.add(fn);
1303
+ }
1304
+ }
1305
+ once(fn) {
1306
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
1307
+ const self = this;
1308
+ this.on(function wrapper(...args) {
1309
+ self.remove(wrapper);
1310
+ // eslint-disable-next-line prefer-spread
1311
+ return fn.apply(null, args);
1312
+ });
1313
+ }
1314
+ emit(...data) {
1315
+ let result;
1316
+ if (this.listeners.size > 0) {
1317
+ // eslint-disable-next-line prefer-spread
1318
+ this.listeners.forEach((fn)=>{
1319
+ result = fn(...data);
1320
+ });
1321
+ }
1322
+ return result;
1323
+ }
1324
+ remove(fn) {
1325
+ this.listeners.delete(fn);
1326
+ }
1327
+ removeAll() {
1328
+ this.listeners.clear();
1329
+ }
1330
+ constructor(type){
1331
+ this.type = '';
1332
+ this.listeners = new Set();
1333
+ if (type) {
1334
+ this.type = type;
1335
+ }
1336
+ }
1337
+ }
1338
+
1339
+ class AsyncHook extends SyncHook {
1340
+ emit(...data) {
1341
+ let result;
1342
+ const ls = Array.from(this.listeners);
1343
+ if (ls.length > 0) {
1344
+ let i = 0;
1345
+ const call = (prev)=>{
1346
+ if (prev === false) {
1347
+ return false; // Abort process
1348
+ } else if (i < ls.length) {
1349
+ return Promise.resolve(ls[i++].apply(null, data)).then(call);
1350
+ } else {
1351
+ return prev;
1352
+ }
1353
+ };
1354
+ result = call();
1355
+ }
1356
+ return Promise.resolve(result);
1357
+ }
1358
+ }
1359
+
1360
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
1361
+ function checkReturnData(originalData, returnedData) {
1362
+ if (!isObject(returnedData)) {
1363
+ return false;
1364
+ }
1365
+ if (originalData !== returnedData) {
1366
+ // eslint-disable-next-line no-restricted-syntax
1367
+ for(const key in originalData){
1368
+ if (!(key in returnedData)) {
1369
+ return false;
1370
+ }
1371
+ }
1372
+ }
1373
+ return true;
1374
+ }
1375
+ class SyncWaterfallHook extends SyncHook {
1376
+ emit(data) {
1377
+ if (!isObject(data)) {
1378
+ error(`The data for the "${this.type}" hook should be an object.`);
1379
+ }
1380
+ for (const fn of this.listeners){
1381
+ try {
1382
+ const tempData = fn(data);
1383
+ if (checkReturnData(data, tempData)) {
1384
+ data = tempData;
1385
+ } else {
1386
+ this.onerror(`A plugin returned an unacceptable value for the "${this.type}" type.`);
1387
+ break;
1388
+ }
1389
+ } catch (e) {
1390
+ warn(e);
1391
+ this.onerror(e);
1392
+ }
1393
+ }
1394
+ return data;
1395
+ }
1396
+ constructor(type){
1397
+ super(), this.onerror = error;
1398
+ this.type = type;
1399
+ }
1400
+ }
1401
+
1402
+ class AsyncWaterfallHook extends SyncHook {
1403
+ emit(data) {
1404
+ if (!isObject(data)) {
1405
+ error(`The response data for the "${this.type}" hook must be an object.`);
1406
+ }
1407
+ const ls = Array.from(this.listeners);
1408
+ if (ls.length > 0) {
1409
+ let i = 0;
1410
+ const processError = (e)=>{
1411
+ warn(e);
1412
+ this.onerror(e);
1413
+ return data;
1414
+ };
1415
+ const call = (prevData)=>{
1416
+ if (checkReturnData(data, prevData)) {
1417
+ data = prevData;
1418
+ if (i < ls.length) {
1419
+ try {
1420
+ return Promise.resolve(ls[i++](data)).then(call, processError);
1421
+ } catch (e) {
1422
+ return processError(e);
1423
+ }
1424
+ }
1425
+ } else {
1426
+ this.onerror(`A plugin returned an incorrect value for the "${this.type}" type.`);
1427
+ }
1428
+ return data;
1429
+ };
1430
+ return Promise.resolve(call(data));
1431
+ }
1432
+ return Promise.resolve(data);
1433
+ }
1434
+ constructor(type){
1435
+ super(), this.onerror = error;
1436
+ this.type = type;
1437
+ }
1438
+ }
1439
+
1440
+ class PluginSystem {
1441
+ applyPlugin(plugin) {
1442
+ assert(isPlainObject(plugin), 'Plugin configuration is invalid.');
1443
+ // The plugin's name is mandatory and must be unique
1444
+ const pluginName = plugin.name;
1445
+ assert(pluginName, 'A name must be provided by the plugin.');
1446
+ if (!this.registerPlugins[pluginName]) {
1447
+ this.registerPlugins[pluginName] = plugin;
1448
+ Object.keys(this.lifecycle).forEach((key)=>{
1449
+ const pluginLife = plugin[key];
1450
+ if (pluginLife) {
1451
+ this.lifecycle[key].on(pluginLife);
1452
+ }
1453
+ });
1454
+ }
1455
+ }
1456
+ removePlugin(pluginName) {
1457
+ assert(pluginName, 'A name is required.');
1458
+ const plugin = this.registerPlugins[pluginName];
1459
+ assert(plugin, `The plugin "${pluginName}" is not registered.`);
1460
+ Object.keys(plugin).forEach((key)=>{
1461
+ if (key !== 'name') {
1462
+ this.lifecycle[key].remove(plugin[key]);
1463
+ }
1464
+ });
1465
+ }
1466
+ // eslint-disable-next-line @typescript-eslint/no-shadow
1467
+ inherit({ lifecycle, registerPlugins }) {
1468
+ Object.keys(lifecycle).forEach((hookName)=>{
1469
+ assert(!this.lifecycle[hookName], `The hook "${hookName}" has a conflict and cannot be inherited.`);
1470
+ this.lifecycle[hookName] = lifecycle[hookName];
1471
+ });
1472
+ Object.keys(registerPlugins).forEach((pluginName)=>{
1473
+ assert(!this.registerPlugins[pluginName], `The plugin "${pluginName}" has a conflict and cannot be inherited.`);
1474
+ this.applyPlugin(registerPlugins[pluginName]);
1475
+ });
1476
+ }
1477
+ constructor(lifecycle){
1478
+ this.registerPlugins = {};
1479
+ this.lifecycle = lifecycle;
1480
+ this.lifecycleKeys = Object.keys(lifecycle);
1481
+ }
1482
+ }
1483
+
1484
+ function defaultPreloadArgs(preloadConfig) {
1485
+ return _extends({
1486
+ resourceCategory: 'sync',
1487
+ share: true,
1488
+ depsRemote: true,
1489
+ prefetchInterface: false
1490
+ }, preloadConfig);
1491
+ }
1492
+ function formatPreloadArgs(remotes, preloadArgs) {
1493
+ return preloadArgs.map((args)=>{
1494
+ const remoteInfo = matchRemote(remotes, args.nameOrAlias);
1495
+ assert(remoteInfo, `Unable to preload ${args.nameOrAlias} as it is not included in ${!remoteInfo && safeToString({
1496
+ remoteInfo,
1497
+ remotes
1498
+ })}`);
1499
+ return {
1500
+ remote: remoteInfo,
1501
+ preloadConfig: defaultPreloadArgs(args)
1502
+ };
1503
+ });
1504
+ }
1505
+ function normalizePreloadExposes(exposes) {
1506
+ if (!exposes) {
1507
+ return [];
1508
+ }
1509
+ return exposes.map((expose)=>{
1510
+ if (expose === '.') {
1511
+ return expose;
1512
+ }
1513
+ if (expose.startsWith('./')) {
1514
+ return expose.replace('./', '');
1515
+ }
1516
+ return expose;
1517
+ });
1518
+ }
1519
+ function preloadAssets(remoteInfo, host, assets, // It is used to distinguish preload from load remote parallel loading
1520
+ useLinkPreload = true) {
1521
+ const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets;
1522
+ if (host.options.inBrowser) {
1523
+ entryAssets.forEach((asset)=>{
1524
+ const { moduleInfo } = asset;
1525
+ const module = host.moduleCache.get(remoteInfo.name);
1526
+ if (module) {
1527
+ getRemoteEntry({
1528
+ origin: host,
1529
+ remoteInfo: moduleInfo,
1530
+ remoteEntryExports: module.remoteEntryExports
1531
+ });
1532
+ } else {
1533
+ getRemoteEntry({
1534
+ origin: host,
1535
+ remoteInfo: moduleInfo,
1536
+ remoteEntryExports: undefined
1537
+ });
1538
+ }
1539
+ });
1540
+ if (useLinkPreload) {
1541
+ const defaultAttrs = {
1542
+ rel: 'preload',
1543
+ as: 'style'
1544
+ };
1545
+ cssAssets.forEach((cssUrl)=>{
1546
+ const { link: cssEl, needAttach } = createLink({
1547
+ url: cssUrl,
1548
+ cb: ()=>{
1549
+ // noop
1550
+ },
1551
+ attrs: defaultAttrs,
1552
+ createLinkHook: (url, attrs)=>{
1553
+ const res = host.loaderHook.lifecycle.createLink.emit({
1554
+ url,
1555
+ attrs
1556
+ });
1557
+ if (res instanceof HTMLLinkElement) {
1558
+ return res;
1559
+ }
1560
+ return;
1561
+ }
1562
+ });
1563
+ needAttach && document.head.appendChild(cssEl);
1564
+ });
1565
+ } else {
1566
+ const defaultAttrs = {
1567
+ rel: 'stylesheet',
1568
+ type: 'text/css'
1569
+ };
1570
+ cssAssets.forEach((cssUrl)=>{
1571
+ const { link: cssEl, needAttach } = createLink({
1572
+ url: cssUrl,
1573
+ cb: ()=>{
1574
+ // noop
1575
+ },
1576
+ attrs: defaultAttrs,
1577
+ createLinkHook: (url, attrs)=>{
1578
+ const res = host.loaderHook.lifecycle.createLink.emit({
1579
+ url,
1580
+ attrs
1581
+ });
1582
+ if (res instanceof HTMLLinkElement) {
1583
+ return res;
1584
+ }
1585
+ return;
1586
+ },
1587
+ needDeleteLink: false
1588
+ });
1589
+ needAttach && document.head.appendChild(cssEl);
1590
+ });
1591
+ }
1592
+ if (useLinkPreload) {
1593
+ const defaultAttrs = {
1594
+ rel: 'preload',
1595
+ as: 'script'
1596
+ };
1597
+ jsAssetsWithoutEntry.forEach((jsUrl)=>{
1598
+ const { link: linkEl, needAttach } = createLink({
1599
+ url: jsUrl,
1600
+ cb: ()=>{
1601
+ // noop
1602
+ },
1603
+ attrs: defaultAttrs,
1604
+ createLinkHook: (url, attrs)=>{
1605
+ const res = host.loaderHook.lifecycle.createLink.emit({
1606
+ url,
1607
+ attrs
1608
+ });
1609
+ if (res instanceof HTMLLinkElement) {
1610
+ return res;
1611
+ }
1612
+ return;
1613
+ }
1614
+ });
1615
+ needAttach && document.head.appendChild(linkEl);
1616
+ });
1617
+ } else {
1618
+ const defaultAttrs = {
1619
+ fetchpriority: 'high',
1620
+ type: (remoteInfo == null ? void 0 : remoteInfo.type) === 'module' ? 'module' : 'text/javascript'
1621
+ };
1622
+ jsAssetsWithoutEntry.forEach((jsUrl)=>{
1623
+ const { script: scriptEl, needAttach } = createScript({
1624
+ url: jsUrl,
1625
+ cb: ()=>{
1626
+ // noop
1627
+ },
1628
+ attrs: defaultAttrs,
1629
+ createScriptHook: (url, attrs)=>{
1630
+ const res = host.loaderHook.lifecycle.createScript.emit({
1631
+ url,
1632
+ attrs
1633
+ });
1634
+ if (res instanceof HTMLScriptElement) {
1635
+ return res;
1636
+ }
1637
+ return;
1638
+ },
1639
+ needDeleteScript: true
1640
+ });
1641
+ needAttach && document.head.appendChild(scriptEl);
1642
+ });
1643
+ }
1644
+ }
1645
+ }
1646
+
1647
+ function assignRemoteInfo(remoteInfo, remoteSnapshot) {
1648
+ const remoteEntryInfo = getRemoteEntryInfoFromSnapshot(remoteSnapshot);
1649
+ if (!remoteEntryInfo.url) {
1650
+ error(`The attribute remoteEntry of ${remoteInfo.name} must not be undefined.`);
1651
+ }
1652
+ let entryUrl = getResourceUrl(remoteSnapshot, remoteEntryInfo.url);
1653
+ if (!isBrowserEnv() && !entryUrl.startsWith('http')) {
1654
+ entryUrl = `https:${entryUrl}`;
1655
+ }
1656
+ remoteInfo.type = remoteEntryInfo.type;
1657
+ remoteInfo.entryGlobalName = remoteEntryInfo.globalName;
1658
+ remoteInfo.entry = entryUrl;
1659
+ remoteInfo.version = remoteSnapshot.version;
1660
+ remoteInfo.buildVersion = remoteSnapshot.buildVersion;
1661
+ }
1662
+ function snapshotPlugin() {
1663
+ return {
1664
+ name: 'snapshot-plugin',
1665
+ async afterResolve (args) {
1666
+ const { remote, pkgNameOrAlias, expose, origin, remoteInfo } = args;
1667
+ if (!isRemoteInfoWithEntry(remote) || !isPureRemoteEntry(remote)) {
1668
+ const { remoteSnapshot, globalSnapshot } = await origin.snapshotHandler.loadRemoteSnapshotInfo(remote);
1669
+ assignRemoteInfo(remoteInfo, remoteSnapshot);
1670
+ // preloading assets
1671
+ const preloadOptions = {
1672
+ remote,
1673
+ preloadConfig: {
1674
+ nameOrAlias: pkgNameOrAlias,
1675
+ exposes: [
1676
+ expose
1677
+ ],
1678
+ resourceCategory: 'sync',
1679
+ share: false,
1680
+ depsRemote: false
1681
+ }
1682
+ };
1683
+ const assets = await origin.remoteHandler.hooks.lifecycle.generatePreloadAssets.emit({
1684
+ origin,
1685
+ preloadOptions,
1686
+ remoteInfo,
1687
+ remote,
1688
+ remoteSnapshot,
1689
+ globalSnapshot
1690
+ });
1691
+ if (assets) {
1692
+ preloadAssets(remoteInfo, origin, assets, false);
1693
+ }
1694
+ return _extends({}, args, {
1695
+ remoteSnapshot
1696
+ });
1697
+ }
1698
+ return args;
1699
+ }
1700
+ };
1701
+ }
1702
+
1703
+ // name
1704
+ // name:version
1705
+ function splitId(id) {
1706
+ const splitInfo = id.split(':');
1707
+ if (splitInfo.length === 1) {
1708
+ return {
1709
+ name: splitInfo[0],
1710
+ version: undefined
1711
+ };
1712
+ } else if (splitInfo.length === 2) {
1713
+ return {
1714
+ name: splitInfo[0],
1715
+ version: splitInfo[1]
1716
+ };
1717
+ } else {
1718
+ return {
1719
+ name: splitInfo[1],
1720
+ version: splitInfo[2]
1721
+ };
1722
+ }
1723
+ }
1724
+ // Traverse all nodes in moduleInfo and traverse the entire snapshot
1725
+ function traverseModuleInfo(globalSnapshot, remoteInfo, traverse, isRoot, memo = {}, remoteSnapshot) {
1726
+ const id = getFMId(remoteInfo);
1727
+ const { value: snapshotValue } = getInfoWithoutType(globalSnapshot, id);
1728
+ const effectiveRemoteSnapshot = remoteSnapshot || snapshotValue;
1729
+ if (effectiveRemoteSnapshot && !isManifestProvider(effectiveRemoteSnapshot)) {
1730
+ traverse(effectiveRemoteSnapshot, remoteInfo, isRoot);
1731
+ if (effectiveRemoteSnapshot.remotesInfo) {
1732
+ const remoteKeys = Object.keys(effectiveRemoteSnapshot.remotesInfo);
1733
+ for (const key of remoteKeys){
1734
+ if (memo[key]) {
1735
+ continue;
1736
+ }
1737
+ memo[key] = true;
1738
+ const subRemoteInfo = splitId(key);
1739
+ const remoteValue = effectiveRemoteSnapshot.remotesInfo[key];
1740
+ traverseModuleInfo(globalSnapshot, {
1741
+ name: subRemoteInfo.name,
1742
+ version: remoteValue.matchedVersion
1743
+ }, traverse, false, memo, undefined);
1744
+ }
1745
+ }
1746
+ }
1747
+ }
1748
+ // eslint-disable-next-line max-lines-per-function
1749
+ function generatePreloadAssets(origin, preloadOptions, remote, globalSnapshot, remoteSnapshot) {
1750
+ const cssAssets = [];
1751
+ const jsAssets = [];
1752
+ const entryAssets = [];
1753
+ const loadedSharedJsAssets = new Set();
1754
+ const loadedSharedCssAssets = new Set();
1755
+ const { options } = origin;
1756
+ const { preloadConfig: rootPreloadConfig } = preloadOptions;
1757
+ const { depsRemote } = rootPreloadConfig;
1758
+ const memo = {};
1759
+ traverseModuleInfo(globalSnapshot, remote, (moduleInfoSnapshot, remoteInfo, isRoot)=>{
1760
+ let preloadConfig;
1761
+ if (isRoot) {
1762
+ preloadConfig = rootPreloadConfig;
1763
+ } else {
1764
+ if (Array.isArray(depsRemote)) {
1765
+ // eslint-disable-next-line array-callback-return
1766
+ const findPreloadConfig = depsRemote.find((remoteConfig)=>{
1767
+ if (remoteConfig.nameOrAlias === remoteInfo.name || remoteConfig.nameOrAlias === remoteInfo.alias) {
1768
+ return true;
1769
+ }
1770
+ return false;
1771
+ });
1772
+ if (!findPreloadConfig) {
1773
+ return;
1774
+ }
1775
+ preloadConfig = defaultPreloadArgs(findPreloadConfig);
1776
+ } else if (depsRemote === true) {
1777
+ preloadConfig = rootPreloadConfig;
1778
+ } else {
1779
+ return;
1780
+ }
1781
+ }
1782
+ const remoteEntryUrl = getResourceUrl(moduleInfoSnapshot, getRemoteEntryInfoFromSnapshot(moduleInfoSnapshot).url);
1783
+ if (remoteEntryUrl) {
1784
+ entryAssets.push({
1785
+ name: remoteInfo.name,
1786
+ moduleInfo: {
1787
+ name: remoteInfo.name,
1788
+ entry: remoteEntryUrl,
1789
+ type: 'remoteEntryType' in moduleInfoSnapshot ? moduleInfoSnapshot.remoteEntryType : 'global',
1790
+ entryGlobalName: 'globalName' in moduleInfoSnapshot ? moduleInfoSnapshot.globalName : remoteInfo.name,
1791
+ shareScope: '',
1792
+ version: 'version' in moduleInfoSnapshot ? moduleInfoSnapshot.version : undefined
1793
+ },
1794
+ url: remoteEntryUrl
1795
+ });
1796
+ }
1797
+ let moduleAssetsInfo = 'modules' in moduleInfoSnapshot ? moduleInfoSnapshot.modules : [];
1798
+ const normalizedPreloadExposes = normalizePreloadExposes(preloadConfig.exposes);
1799
+ if (normalizedPreloadExposes.length && 'modules' in moduleInfoSnapshot) {
1800
+ var _moduleInfoSnapshot_modules;
1801
+ moduleAssetsInfo = moduleInfoSnapshot == null ? void 0 : (_moduleInfoSnapshot_modules = moduleInfoSnapshot.modules) == null ? void 0 : _moduleInfoSnapshot_modules.reduce((assets, moduleAssetInfo)=>{
1802
+ if ((normalizedPreloadExposes == null ? void 0 : normalizedPreloadExposes.indexOf(moduleAssetInfo.moduleName)) !== -1) {
1803
+ assets.push(moduleAssetInfo);
1804
+ }
1805
+ return assets;
1806
+ }, []);
1807
+ }
1808
+ function handleAssets(assets) {
1809
+ const assetsRes = assets.map((asset)=>getResourceUrl(moduleInfoSnapshot, asset));
1810
+ if (preloadConfig.filter) {
1811
+ return assetsRes.filter(preloadConfig.filter);
1812
+ }
1813
+ return assetsRes;
1814
+ }
1815
+ if (moduleAssetsInfo) {
1816
+ const assetsLength = moduleAssetsInfo.length;
1817
+ for(let index = 0; index < assetsLength; index++){
1818
+ const assetsInfo = moduleAssetsInfo[index];
1819
+ const exposeFullPath = `${remoteInfo.name}/${assetsInfo.moduleName}`;
1820
+ origin.remoteHandler.hooks.lifecycle.handlePreloadModule.emit({
1821
+ id: assetsInfo.moduleName === '.' ? remoteInfo.name : exposeFullPath,
1822
+ name: remoteInfo.name,
1823
+ remoteSnapshot: moduleInfoSnapshot,
1824
+ preloadConfig,
1825
+ remote: remoteInfo,
1826
+ origin
1827
+ });
1828
+ const preloaded = getPreloaded(exposeFullPath);
1829
+ if (preloaded) {
1830
+ continue;
1831
+ }
1832
+ if (preloadConfig.resourceCategory === 'all') {
1833
+ cssAssets.push(...handleAssets(assetsInfo.assets.css.async));
1834
+ cssAssets.push(...handleAssets(assetsInfo.assets.css.sync));
1835
+ jsAssets.push(...handleAssets(assetsInfo.assets.js.async));
1836
+ jsAssets.push(...handleAssets(assetsInfo.assets.js.sync));
1837
+ // eslint-disable-next-line no-constant-condition
1838
+ } else if (preloadConfig.resourceCategory = 'sync') {
1839
+ cssAssets.push(...handleAssets(assetsInfo.assets.css.sync));
1840
+ jsAssets.push(...handleAssets(assetsInfo.assets.js.sync));
1841
+ }
1842
+ setPreloaded(exposeFullPath);
1843
+ }
1844
+ }
1845
+ }, true, memo, remoteSnapshot);
1846
+ if (remoteSnapshot.shared) {
1847
+ const collectSharedAssets = (shareInfo, snapshotShared)=>{
1848
+ const registeredShared = getRegisteredShare(origin.shareScopeMap, snapshotShared.sharedName, shareInfo, origin.sharedHandler.hooks.lifecycle.resolveShare);
1849
+ // 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.
1850
+ if (registeredShared && typeof registeredShared.lib === 'function') {
1851
+ snapshotShared.assets.js.sync.forEach((asset)=>{
1852
+ loadedSharedJsAssets.add(asset);
1853
+ });
1854
+ snapshotShared.assets.css.sync.forEach((asset)=>{
1855
+ loadedSharedCssAssets.add(asset);
1856
+ });
1857
+ }
1858
+ };
1859
+ remoteSnapshot.shared.forEach((shared)=>{
1860
+ var _options_shared;
1861
+ const shareInfos = (_options_shared = options.shared) == null ? void 0 : _options_shared[shared.sharedName];
1862
+ if (!shareInfos) {
1863
+ return;
1864
+ }
1865
+ // if no version, preload all shared
1866
+ const sharedOptions = shared.version ? shareInfos.find((s)=>s.version === shared.version) : shareInfos;
1867
+ if (!sharedOptions) {
1868
+ return;
1869
+ }
1870
+ const arrayShareInfo = arrayOptions(sharedOptions);
1871
+ arrayShareInfo.forEach((s)=>{
1872
+ collectSharedAssets(s, shared);
1873
+ });
1874
+ });
1875
+ }
1876
+ const needPreloadJsAssets = jsAssets.filter((asset)=>!loadedSharedJsAssets.has(asset));
1877
+ const needPreloadCssAssets = cssAssets.filter((asset)=>!loadedSharedCssAssets.has(asset));
1878
+ return {
1879
+ cssAssets: needPreloadCssAssets,
1880
+ jsAssetsWithoutEntry: needPreloadJsAssets,
1881
+ entryAssets
1882
+ };
1883
+ }
1884
+ const generatePreloadAssetsPlugin = function() {
1885
+ return {
1886
+ name: 'generate-preload-assets-plugin',
1887
+ async generatePreloadAssets (args) {
1888
+ const { origin, preloadOptions, remoteInfo, remote, globalSnapshot, remoteSnapshot } = args;
1889
+ if (isRemoteInfoWithEntry(remote) && isPureRemoteEntry(remote)) {
1890
+ return {
1891
+ cssAssets: [],
1892
+ jsAssetsWithoutEntry: [],
1893
+ entryAssets: [
1894
+ {
1895
+ name: remote.name,
1896
+ url: remote.entry,
1897
+ moduleInfo: {
1898
+ name: remoteInfo.name,
1899
+ entry: remote.entry,
1900
+ type: remoteInfo.type || 'global',
1901
+ entryGlobalName: '',
1902
+ shareScope: ''
1903
+ }
1904
+ }
1905
+ ]
1906
+ };
1907
+ }
1908
+ assignRemoteInfo(remoteInfo, remoteSnapshot);
1909
+ const assets = generatePreloadAssets(origin, preloadOptions, remoteInfo, globalSnapshot, remoteSnapshot);
1910
+ return assets;
1911
+ }
1912
+ };
1913
+ };
1914
+
1915
+ function getGlobalRemoteInfo(moduleInfo, origin) {
1916
+ const hostGlobalSnapshot = getGlobalSnapshotInfoByModuleInfo({
1917
+ name: origin.options.name,
1918
+ version: origin.options.version
1919
+ });
1920
+ // get remote detail info from global
1921
+ const globalRemoteInfo = hostGlobalSnapshot && 'remotesInfo' in hostGlobalSnapshot && hostGlobalSnapshot.remotesInfo && getInfoWithoutType(hostGlobalSnapshot.remotesInfo, moduleInfo.name).value;
1922
+ if (globalRemoteInfo && globalRemoteInfo.matchedVersion) {
1923
+ return {
1924
+ hostGlobalSnapshot,
1925
+ globalSnapshot: getGlobalSnapshot(),
1926
+ remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({
1927
+ name: moduleInfo.name,
1928
+ version: globalRemoteInfo.matchedVersion
1929
+ })
1930
+ };
1931
+ }
1932
+ return {
1933
+ hostGlobalSnapshot: undefined,
1934
+ globalSnapshot: getGlobalSnapshot(),
1935
+ remoteSnapshot: getGlobalSnapshotInfoByModuleInfo({
1936
+ name: moduleInfo.name,
1937
+ version: 'version' in moduleInfo ? moduleInfo.version : undefined
1938
+ })
1939
+ };
1940
+ }
1941
+ class SnapshotHandler {
1942
+ async loadSnapshot(moduleInfo) {
1943
+ const { options } = this.HostInstance;
1944
+ const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } = this.getGlobalRemoteInfo(moduleInfo);
1945
+ const { remoteSnapshot: globalRemoteSnapshot, globalSnapshot: globalSnapshotRes } = await this.hooks.lifecycle.loadSnapshot.emit({
1946
+ options,
1947
+ moduleInfo,
1948
+ hostGlobalSnapshot,
1949
+ remoteSnapshot,
1950
+ globalSnapshot
1951
+ });
1952
+ return {
1953
+ remoteSnapshot: globalRemoteSnapshot,
1954
+ globalSnapshot: globalSnapshotRes
1955
+ };
1956
+ }
1957
+ // eslint-disable-next-line max-lines-per-function
1958
+ async loadRemoteSnapshotInfo(moduleInfo) {
1959
+ const { options } = this.HostInstance;
1960
+ await this.hooks.lifecycle.beforeLoadRemoteSnapshot.emit({
1961
+ options,
1962
+ moduleInfo
1963
+ });
1964
+ let hostSnapshot = getGlobalSnapshotInfoByModuleInfo({
1965
+ name: this.HostInstance.options.name,
1966
+ version: this.HostInstance.options.version
1967
+ });
1968
+ if (!hostSnapshot) {
1969
+ hostSnapshot = {
1970
+ version: this.HostInstance.options.version || '',
1971
+ remoteEntry: '',
1972
+ remotesInfo: {}
1973
+ };
1974
+ addGlobalSnapshot({
1975
+ [this.HostInstance.options.name]: hostSnapshot
1976
+ });
1977
+ }
1978
+ // In dynamic loadRemote scenarios, incomplete remotesInfo delivery may occur. In such cases, the remotesInfo in the host needs to be completed in the snapshot at runtime.
1979
+ // This ensures the snapshot's integrity and helps the chrome plugin correctly identify all producer modules, ensuring that proxyable producer modules will not be missing.
1980
+ if (hostSnapshot && 'remotesInfo' in hostSnapshot && !getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name).value) {
1981
+ if ('version' in moduleInfo || 'entry' in moduleInfo) {
1982
+ hostSnapshot.remotesInfo = _extends({}, hostSnapshot == null ? void 0 : hostSnapshot.remotesInfo, {
1983
+ [moduleInfo.name]: {
1984
+ matchedVersion: 'version' in moduleInfo ? moduleInfo.version : moduleInfo.entry
1985
+ }
1986
+ });
1987
+ }
1988
+ }
1989
+ const { hostGlobalSnapshot, remoteSnapshot, globalSnapshot } = this.getGlobalRemoteInfo(moduleInfo);
1990
+ const { remoteSnapshot: globalRemoteSnapshot, globalSnapshot: globalSnapshotRes } = await this.hooks.lifecycle.loadSnapshot.emit({
1991
+ options,
1992
+ moduleInfo,
1993
+ hostGlobalSnapshot,
1994
+ remoteSnapshot,
1995
+ globalSnapshot
1996
+ });
1997
+ let mSnapshot;
1998
+ let gSnapshot;
1999
+ // global snapshot includes manifest or module info includes manifest
2000
+ if (globalRemoteSnapshot) {
2001
+ if (isManifestProvider(globalRemoteSnapshot)) {
2002
+ const remoteEntry = isBrowserEnv() ? globalRemoteSnapshot.remoteEntry : globalRemoteSnapshot.ssrRemoteEntry || globalRemoteSnapshot.remoteEntry || '';
2003
+ const moduleSnapshot = await this.getManifestJson(remoteEntry, moduleInfo, {});
2004
+ // eslint-disable-next-line @typescript-eslint/no-shadow
2005
+ const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(_extends({}, moduleInfo, {
2006
+ // The global remote may be overridden
2007
+ // Therefore, set the snapshot key to the global address of the actual request
2008
+ entry: remoteEntry
2009
+ }), moduleSnapshot);
2010
+ mSnapshot = moduleSnapshot;
2011
+ gSnapshot = globalSnapshotRes;
2012
+ } else {
2013
+ const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
2014
+ options: this.HostInstance.options,
2015
+ moduleInfo,
2016
+ remoteSnapshot: globalRemoteSnapshot,
2017
+ from: 'global'
2018
+ });
2019
+ mSnapshot = remoteSnapshotRes;
2020
+ gSnapshot = globalSnapshotRes;
2021
+ }
2022
+ } else {
2023
+ if (isRemoteInfoWithEntry(moduleInfo)) {
2024
+ // get from manifest.json and merge remote info from remote server
2025
+ const moduleSnapshot = await this.getManifestJson(moduleInfo.entry, moduleInfo, {});
2026
+ // eslint-disable-next-line @typescript-eslint/no-shadow
2027
+ const globalSnapshotRes = setGlobalSnapshotInfoByModuleInfo(moduleInfo, moduleSnapshot);
2028
+ const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
2029
+ options: this.HostInstance.options,
2030
+ moduleInfo,
2031
+ remoteSnapshot: moduleSnapshot,
2032
+ from: 'global'
2033
+ });
2034
+ mSnapshot = remoteSnapshotRes;
2035
+ gSnapshot = globalSnapshotRes;
2036
+ } else {
2037
+ error(getShortErrorMsg(RUNTIME_007, runtimeDescMap, {
2038
+ hostName: moduleInfo.name,
2039
+ hostVersion: moduleInfo.version,
2040
+ globalSnapshot: JSON.stringify(globalSnapshotRes)
2041
+ }));
2042
+ }
2043
+ }
2044
+ await this.hooks.lifecycle.afterLoadSnapshot.emit({
2045
+ options,
2046
+ moduleInfo,
2047
+ remoteSnapshot: mSnapshot
2048
+ });
2049
+ return {
2050
+ remoteSnapshot: mSnapshot,
2051
+ globalSnapshot: gSnapshot
2052
+ };
2053
+ }
2054
+ getGlobalRemoteInfo(moduleInfo) {
2055
+ return getGlobalRemoteInfo(moduleInfo, this.HostInstance);
2056
+ }
2057
+ async getManifestJson(manifestUrl, moduleInfo, extraOptions) {
2058
+ const getManifest = async ()=>{
2059
+ let manifestJson = this.manifestCache.get(manifestUrl);
2060
+ if (manifestJson) {
2061
+ return manifestJson;
2062
+ }
2063
+ try {
2064
+ let res = await this.loaderHook.lifecycle.fetch.emit(manifestUrl, {});
2065
+ if (!res || !(res instanceof Response)) {
2066
+ res = await fetch(manifestUrl, {});
2067
+ }
2068
+ manifestJson = await res.json();
2069
+ assert(manifestJson.metaData && manifestJson.exposes && manifestJson.shared, `${manifestUrl} is not a federation manifest`);
2070
+ this.manifestCache.set(manifestUrl, manifestJson);
2071
+ return manifestJson;
2072
+ } catch (err) {
2073
+ delete this.manifestLoading[manifestUrl];
2074
+ error(getShortErrorMsg(RUNTIME_003, runtimeDescMap, {
2075
+ manifestUrl,
2076
+ moduleName: moduleInfo.name
2077
+ }, `${err}`));
2078
+ }
2079
+ };
2080
+ const asyncLoadProcess = async ()=>{
2081
+ const manifestJson = await getManifest();
2082
+ const remoteSnapshot = generateSnapshotFromManifest(manifestJson, {
2083
+ version: manifestUrl
2084
+ });
2085
+ const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
2086
+ options: this.HostInstance.options,
2087
+ moduleInfo,
2088
+ manifestJson,
2089
+ remoteSnapshot,
2090
+ manifestUrl,
2091
+ from: 'manifest'
2092
+ });
2093
+ return remoteSnapshotRes;
2094
+ };
2095
+ if (!this.manifestLoading[manifestUrl]) {
2096
+ this.manifestLoading[manifestUrl] = asyncLoadProcess().then((res)=>res);
2097
+ }
2098
+ return this.manifestLoading[manifestUrl];
2099
+ }
2100
+ constructor(HostInstance){
2101
+ this.loadingHostSnapshot = null;
2102
+ this.manifestCache = new Map();
2103
+ this.hooks = new PluginSystem({
2104
+ beforeLoadRemoteSnapshot: new AsyncHook('beforeLoadRemoteSnapshot'),
2105
+ loadSnapshot: new AsyncWaterfallHook('loadGlobalSnapshot'),
2106
+ loadRemoteSnapshot: new AsyncWaterfallHook('loadRemoteSnapshot'),
2107
+ afterLoadSnapshot: new AsyncWaterfallHook('afterLoadSnapshot')
2108
+ });
2109
+ this.manifestLoading = Global.__FEDERATION__.__MANIFEST_LOADING__;
2110
+ this.HostInstance = HostInstance;
2111
+ this.loaderHook = HostInstance.loaderHook;
2112
+ }
2113
+ }
2114
+
2115
+ class SharedHandler {
2116
+ // register shared in shareScopeMap
2117
+ registerShared(globalOptions, userOptions) {
2118
+ const { shareInfos, shared } = formatShareConfigs(globalOptions, userOptions);
2119
+ const sharedKeys = Object.keys(shareInfos);
2120
+ sharedKeys.forEach((sharedKey)=>{
2121
+ const sharedVals = shareInfos[sharedKey];
2122
+ sharedVals.forEach((sharedVal)=>{
2123
+ const registeredShared = getRegisteredShare(this.shareScopeMap, sharedKey, sharedVal, this.hooks.lifecycle.resolveShare);
2124
+ if (!registeredShared && sharedVal && sharedVal.lib) {
2125
+ this.setShared({
2126
+ pkgName: sharedKey,
2127
+ lib: sharedVal.lib,
2128
+ get: sharedVal.get,
2129
+ loaded: true,
2130
+ shared: sharedVal,
2131
+ from: userOptions.name
2132
+ });
2133
+ }
2134
+ });
2135
+ });
2136
+ return {
2137
+ shareInfos,
2138
+ shared
2139
+ };
2140
+ }
2141
+ async loadShare(pkgName, extraOptions) {
2142
+ const { host } = this;
2143
+ // This function performs the following steps:
2144
+ // 1. Checks if the currently loaded share already exists, if not, it throws an error
2145
+ // 2. Searches globally for a matching share, if found, it uses it directly
2146
+ // 3. If not found, it retrieves it from the current share and stores the obtained share globally.
2147
+ const shareInfo = getTargetSharedOptions({
2148
+ pkgName,
2149
+ extraOptions,
2150
+ shareInfos: host.options.shared
2151
+ });
2152
+ if (shareInfo == null ? void 0 : shareInfo.scope) {
2153
+ await Promise.all(shareInfo.scope.map(async (shareScope)=>{
2154
+ await Promise.all(this.initializeSharing(shareScope, {
2155
+ strategy: shareInfo.strategy
2156
+ }));
2157
+ return;
2158
+ }));
2159
+ }
2160
+ const loadShareRes = await this.hooks.lifecycle.beforeLoadShare.emit({
2161
+ pkgName,
2162
+ shareInfo,
2163
+ shared: host.options.shared,
2164
+ origin: host
2165
+ });
2166
+ const { shareInfo: shareInfoRes } = loadShareRes;
2167
+ // Assert that shareInfoRes exists, if not, throw an error
2168
+ assert(shareInfoRes, `Cannot find ${pkgName} Share in the ${host.options.name}. Please ensure that the ${pkgName} Share parameters have been injected`);
2169
+ // Retrieve from cache
2170
+ const registeredShared = getRegisteredShare(this.shareScopeMap, pkgName, shareInfoRes, this.hooks.lifecycle.resolveShare);
2171
+ const addUseIn = (shared)=>{
2172
+ if (!shared.useIn) {
2173
+ shared.useIn = [];
2174
+ }
2175
+ addUniqueItem(shared.useIn, host.options.name);
2176
+ };
2177
+ if (registeredShared && registeredShared.lib) {
2178
+ addUseIn(registeredShared);
2179
+ return registeredShared.lib;
2180
+ } else if (registeredShared && registeredShared.loading && !registeredShared.loaded) {
2181
+ const factory = await registeredShared.loading;
2182
+ registeredShared.loaded = true;
2183
+ if (!registeredShared.lib) {
2184
+ registeredShared.lib = factory;
2185
+ }
2186
+ addUseIn(registeredShared);
2187
+ return factory;
2188
+ } else if (registeredShared) {
2189
+ const asyncLoadProcess = async ()=>{
2190
+ const factory = await registeredShared.get();
2191
+ shareInfoRes.lib = factory;
2192
+ shareInfoRes.loaded = true;
2193
+ addUseIn(shareInfoRes);
2194
+ const gShared = getRegisteredShare(this.shareScopeMap, pkgName, shareInfoRes, this.hooks.lifecycle.resolveShare);
2195
+ if (gShared) {
2196
+ gShared.lib = factory;
2197
+ gShared.loaded = true;
2198
+ }
2199
+ return factory;
2200
+ };
2201
+ const loading = asyncLoadProcess();
2202
+ this.setShared({
2203
+ pkgName,
2204
+ loaded: false,
2205
+ shared: registeredShared,
2206
+ from: host.options.name,
2207
+ lib: null,
2208
+ loading
2209
+ });
2210
+ return loading;
2211
+ } else {
2212
+ if (extraOptions == null ? void 0 : extraOptions.customShareInfo) {
2213
+ return false;
2214
+ }
2215
+ const asyncLoadProcess = async ()=>{
2216
+ const factory = await shareInfoRes.get();
2217
+ shareInfoRes.lib = factory;
2218
+ shareInfoRes.loaded = true;
2219
+ addUseIn(shareInfoRes);
2220
+ const gShared = getRegisteredShare(this.shareScopeMap, pkgName, shareInfoRes, this.hooks.lifecycle.resolveShare);
2221
+ if (gShared) {
2222
+ gShared.lib = factory;
2223
+ gShared.loaded = true;
2224
+ }
2225
+ return factory;
2226
+ };
2227
+ const loading = asyncLoadProcess();
2228
+ this.setShared({
2229
+ pkgName,
2230
+ loaded: false,
2231
+ shared: shareInfoRes,
2232
+ from: host.options.name,
2233
+ lib: null,
2234
+ loading
2235
+ });
2236
+ return loading;
2237
+ }
2238
+ }
2239
+ /**
2240
+ * This function initializes the sharing sequence (executed only once per share scope).
2241
+ * It accepts one argument, the name of the share scope.
2242
+ * If the share scope does not exist, it creates one.
2243
+ */ // eslint-disable-next-line @typescript-eslint/member-ordering
2244
+ initializeSharing(shareScopeName = DEFAULT_SCOPE, extraOptions) {
2245
+ const { host } = this;
2246
+ const from = extraOptions == null ? void 0 : extraOptions.from;
2247
+ const strategy = extraOptions == null ? void 0 : extraOptions.strategy;
2248
+ let initScope = extraOptions == null ? void 0 : extraOptions.initScope;
2249
+ const promises = [];
2250
+ if (from !== 'build') {
2251
+ const { initTokens } = this;
2252
+ if (!initScope) initScope = [];
2253
+ let initToken = initTokens[shareScopeName];
2254
+ if (!initToken) initToken = initTokens[shareScopeName] = {
2255
+ from: this.host.name
2256
+ };
2257
+ if (initScope.indexOf(initToken) >= 0) return promises;
2258
+ initScope.push(initToken);
2259
+ }
2260
+ const shareScope = this.shareScopeMap;
2261
+ const hostName = host.options.name;
2262
+ // Creates a new share scope if necessary
2263
+ if (!shareScope[shareScopeName]) {
2264
+ shareScope[shareScopeName] = {};
2265
+ }
2266
+ // Executes all initialization snippets from all accessible modules
2267
+ const scope = shareScope[shareScopeName];
2268
+ const register = (name, shared)=>{
2269
+ var _activeVersion_shareConfig;
2270
+ const { version, eager } = shared;
2271
+ scope[name] = scope[name] || {};
2272
+ const versions = scope[name];
2273
+ const activeVersion = versions[version];
2274
+ const activeVersionEager = Boolean(activeVersion && (activeVersion.eager || ((_activeVersion_shareConfig = activeVersion.shareConfig) == null ? void 0 : _activeVersion_shareConfig.eager)));
2275
+ if (!activeVersion || activeVersion.strategy !== 'loaded-first' && !activeVersion.loaded && (Boolean(!eager) !== !activeVersionEager ? eager : hostName > activeVersion.from)) {
2276
+ versions[version] = shared;
2277
+ }
2278
+ };
2279
+ const initFn = (mod)=>mod && mod.init && mod.init(shareScope[shareScopeName], initScope);
2280
+ const initRemoteModule = async (key)=>{
2281
+ const { module } = await host.remoteHandler.getRemoteModuleAndOptions({
2282
+ id: key
2283
+ });
2284
+ if (module.getEntry) {
2285
+ let remoteEntryExports;
2286
+ try {
2287
+ remoteEntryExports = await module.getEntry();
2288
+ } catch (error) {
2289
+ remoteEntryExports = await host.remoteHandler.hooks.lifecycle.errorLoadRemote.emit({
2290
+ id: key,
2291
+ error,
2292
+ from: 'runtime',
2293
+ lifecycle: 'beforeLoadShare',
2294
+ origin: host
2295
+ });
2296
+ }
2297
+ if (!module.inited) {
2298
+ await initFn(remoteEntryExports);
2299
+ module.inited = true;
2300
+ }
2301
+ }
2302
+ };
2303
+ Object.keys(host.options.shared).forEach((shareName)=>{
2304
+ const sharedArr = host.options.shared[shareName];
2305
+ sharedArr.forEach((shared)=>{
2306
+ if (shared.scope.includes(shareScopeName)) {
2307
+ register(shareName, shared);
2308
+ }
2309
+ });
2310
+ });
2311
+ // TODO: strategy==='version-first' need to be removed in the future
2312
+ if (host.options.shareStrategy === 'version-first' || strategy === 'version-first') {
2313
+ host.options.remotes.forEach((remote)=>{
2314
+ if (remote.shareScope === shareScopeName) {
2315
+ promises.push(initRemoteModule(remote.name));
2316
+ }
2317
+ });
2318
+ }
2319
+ return promises;
2320
+ }
2321
+ // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.
2322
+ // 1. If the loaded shared already exists globally, then it will be reused
2323
+ // 2. If lib exists in local shared, it will be used directly
2324
+ // 3. If the local get returns something other than Promise, then it will be used directly
2325
+ loadShareSync(pkgName, extraOptions) {
2326
+ const { host } = this;
2327
+ const shareInfo = getTargetSharedOptions({
2328
+ pkgName,
2329
+ extraOptions,
2330
+ shareInfos: host.options.shared
2331
+ });
2332
+ if (shareInfo == null ? void 0 : shareInfo.scope) {
2333
+ shareInfo.scope.forEach((shareScope)=>{
2334
+ this.initializeSharing(shareScope, {
2335
+ strategy: shareInfo.strategy
2336
+ });
2337
+ });
2338
+ }
2339
+ const registeredShared = getRegisteredShare(this.shareScopeMap, pkgName, shareInfo, this.hooks.lifecycle.resolveShare);
2340
+ const addUseIn = (shared)=>{
2341
+ if (!shared.useIn) {
2342
+ shared.useIn = [];
2343
+ }
2344
+ addUniqueItem(shared.useIn, host.options.name);
2345
+ };
2346
+ if (registeredShared) {
2347
+ if (typeof registeredShared.lib === 'function') {
2348
+ addUseIn(registeredShared);
2349
+ if (!registeredShared.loaded) {
2350
+ registeredShared.loaded = true;
2351
+ if (registeredShared.from === host.options.name) {
2352
+ shareInfo.loaded = true;
2353
+ }
2354
+ }
2355
+ return registeredShared.lib;
2356
+ }
2357
+ if (typeof registeredShared.get === 'function') {
2358
+ const module = registeredShared.get();
2359
+ if (!(module instanceof Promise)) {
2360
+ addUseIn(registeredShared);
2361
+ this.setShared({
2362
+ pkgName,
2363
+ loaded: true,
2364
+ from: host.options.name,
2365
+ lib: module,
2366
+ shared: registeredShared
2367
+ });
2368
+ return module;
2369
+ }
2370
+ }
2371
+ }
2372
+ if (shareInfo.lib) {
2373
+ if (!shareInfo.loaded) {
2374
+ shareInfo.loaded = true;
2375
+ }
2376
+ return shareInfo.lib;
2377
+ }
2378
+ if (shareInfo.get) {
2379
+ const module = shareInfo.get();
2380
+ if (module instanceof Promise) {
2381
+ const errorCode = (extraOptions == null ? void 0 : extraOptions.from) === 'build' ? RUNTIME_005 : RUNTIME_006;
2382
+ throw new Error(getShortErrorMsg(errorCode, runtimeDescMap, {
2383
+ hostName: host.options.name,
2384
+ sharedPkgName: pkgName
2385
+ }));
2386
+ }
2387
+ shareInfo.lib = module;
2388
+ this.setShared({
2389
+ pkgName,
2390
+ loaded: true,
2391
+ from: host.options.name,
2392
+ lib: shareInfo.lib,
2393
+ shared: shareInfo
2394
+ });
2395
+ return shareInfo.lib;
2396
+ }
2397
+ throw new Error(getShortErrorMsg(RUNTIME_006, runtimeDescMap, {
2398
+ hostName: host.options.name,
2399
+ sharedPkgName: pkgName
2400
+ }));
2401
+ }
2402
+ initShareScopeMap(scopeName, shareScope, extraOptions = {}) {
2403
+ const { host } = this;
2404
+ this.shareScopeMap[scopeName] = shareScope;
2405
+ this.hooks.lifecycle.initContainerShareScopeMap.emit({
2406
+ shareScope,
2407
+ options: host.options,
2408
+ origin: host,
2409
+ scopeName,
2410
+ hostShareScopeMap: extraOptions.hostShareScopeMap
2411
+ });
2412
+ }
2413
+ setShared({ pkgName, shared, from, lib, loading, loaded, get }) {
2414
+ const { version, scope = 'default' } = shared, shareInfo = _object_without_properties_loose(shared, [
2415
+ "version",
2416
+ "scope"
2417
+ ]);
2418
+ const scopes = Array.isArray(scope) ? scope : [
2419
+ scope
2420
+ ];
2421
+ scopes.forEach((sc)=>{
2422
+ if (!this.shareScopeMap[sc]) {
2423
+ this.shareScopeMap[sc] = {};
2424
+ }
2425
+ if (!this.shareScopeMap[sc][pkgName]) {
2426
+ this.shareScopeMap[sc][pkgName] = {};
2427
+ }
2428
+ if (!this.shareScopeMap[sc][pkgName][version]) {
2429
+ this.shareScopeMap[sc][pkgName][version] = _extends({
2430
+ version,
2431
+ scope: [
2432
+ 'default'
2433
+ ]
2434
+ }, shareInfo, {
2435
+ lib,
2436
+ loaded,
2437
+ loading
2438
+ });
2439
+ if (get) {
2440
+ this.shareScopeMap[sc][pkgName][version].get = get;
2441
+ }
2442
+ return;
2443
+ }
2444
+ const registeredShared = this.shareScopeMap[sc][pkgName][version];
2445
+ if (loading && !registeredShared.loading) {
2446
+ registeredShared.loading = loading;
2447
+ }
2448
+ });
2449
+ }
2450
+ _setGlobalShareScopeMap(hostOptions) {
2451
+ const globalShareScopeMap = getGlobalShareScope();
2452
+ const identifier = hostOptions.id || hostOptions.name;
2453
+ if (identifier && !globalShareScopeMap[identifier]) {
2454
+ globalShareScopeMap[identifier] = this.shareScopeMap;
2455
+ }
2456
+ }
2457
+ constructor(host){
2458
+ this.hooks = new PluginSystem({
2459
+ afterResolve: new AsyncWaterfallHook('afterResolve'),
2460
+ beforeLoadShare: new AsyncWaterfallHook('beforeLoadShare'),
2461
+ // not used yet
2462
+ loadShare: new AsyncHook(),
2463
+ resolveShare: new SyncWaterfallHook('resolveShare'),
2464
+ // maybe will change, temporarily for internal use only
2465
+ initContainerShareScopeMap: new SyncWaterfallHook('initContainerShareScopeMap')
2466
+ });
2467
+ this.host = host;
2468
+ this.shareScopeMap = {};
2469
+ this.initTokens = {};
2470
+ this._setGlobalShareScopeMap(host.options);
2471
+ }
2472
+ }
2473
+
2474
+ class RemoteHandler {
2475
+ formatAndRegisterRemote(globalOptions, userOptions) {
2476
+ const userRemotes = userOptions.remotes || [];
2477
+ return userRemotes.reduce((res, remote)=>{
2478
+ this.registerRemote(remote, res, {
2479
+ force: false
2480
+ });
2481
+ return res;
2482
+ }, globalOptions.remotes);
2483
+ }
2484
+ setIdToRemoteMap(id, remoteMatchInfo) {
2485
+ const { remote, expose } = remoteMatchInfo;
2486
+ const { name, alias } = remote;
2487
+ this.idToRemoteMap[id] = {
2488
+ name: remote.name,
2489
+ expose
2490
+ };
2491
+ if (alias && id.startsWith(name)) {
2492
+ const idWithAlias = id.replace(name, alias);
2493
+ this.idToRemoteMap[idWithAlias] = {
2494
+ name: remote.name,
2495
+ expose
2496
+ };
2497
+ return;
2498
+ }
2499
+ if (alias && id.startsWith(alias)) {
2500
+ const idWithName = id.replace(alias, name);
2501
+ this.idToRemoteMap[idWithName] = {
2502
+ name: remote.name,
2503
+ expose
2504
+ };
2505
+ }
2506
+ }
2507
+ // eslint-disable-next-line max-lines-per-function
2508
+ // eslint-disable-next-line @typescript-eslint/member-ordering
2509
+ async loadRemote(id, options) {
2510
+ const { host } = this;
2511
+ try {
2512
+ const { loadFactory = true } = options || {
2513
+ loadFactory: true
2514
+ };
2515
+ // 1. Validate the parameters of the retrieved module. There are two module request methods: pkgName + expose and alias + expose.
2516
+ // 2. Request the snapshot information of the current host and globally store the obtained snapshot information. The retrieved module information is partially offline and partially online. The online module information will retrieve the modules used online.
2517
+ // 3. Retrieve the detailed information of the current module from global (remoteEntry address, expose resource address)
2518
+ // 4. After retrieving remoteEntry, call the init of the module, and then retrieve the exported content of the module through get
2519
+ // id: pkgName(@federation/app1) + expose(button) = @federation/app1/button
2520
+ // id: alias(app1) + expose(button) = app1/button
2521
+ // id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort
2522
+ const { module, moduleOptions, remoteMatchInfo } = await this.getRemoteModuleAndOptions({
2523
+ id
2524
+ });
2525
+ const { pkgNameOrAlias, remote, expose, id: idRes, remoteSnapshot } = remoteMatchInfo;
2526
+ const moduleOrFactory = await module.get(idRes, expose, options, remoteSnapshot);
2527
+ const moduleWrapper = await this.hooks.lifecycle.onLoad.emit({
2528
+ id: idRes,
2529
+ pkgNameOrAlias,
2530
+ expose,
2531
+ exposeModule: loadFactory ? moduleOrFactory : undefined,
2532
+ exposeModuleFactory: loadFactory ? undefined : moduleOrFactory,
2533
+ remote,
2534
+ options: moduleOptions,
2535
+ moduleInstance: module,
2536
+ origin: host
2537
+ });
2538
+ this.setIdToRemoteMap(id, remoteMatchInfo);
2539
+ if (typeof moduleWrapper === 'function') {
2540
+ return moduleWrapper;
2541
+ }
2542
+ return moduleOrFactory;
2543
+ } catch (error) {
2544
+ const { from = 'runtime' } = options || {
2545
+ from: 'runtime'
2546
+ };
2547
+ const failOver = await this.hooks.lifecycle.errorLoadRemote.emit({
2548
+ id,
2549
+ error,
2550
+ from,
2551
+ lifecycle: 'onLoad',
2552
+ origin: host
2553
+ });
2554
+ if (!failOver) {
2555
+ throw error;
2556
+ }
2557
+ return failOver;
2558
+ }
2559
+ }
2560
+ // eslint-disable-next-line @typescript-eslint/member-ordering
2561
+ async preloadRemote(preloadOptions) {
2562
+ const { host } = this;
2563
+ await this.hooks.lifecycle.beforePreloadRemote.emit({
2564
+ preloadOps: preloadOptions,
2565
+ options: host.options,
2566
+ origin: host
2567
+ });
2568
+ const preloadOps = formatPreloadArgs(host.options.remotes, preloadOptions);
2569
+ await Promise.all(preloadOps.map(async (ops)=>{
2570
+ const { remote } = ops;
2571
+ const remoteInfo = getRemoteInfo(remote);
2572
+ const { globalSnapshot, remoteSnapshot } = await host.snapshotHandler.loadRemoteSnapshotInfo(remote);
2573
+ const assets = await this.hooks.lifecycle.generatePreloadAssets.emit({
2574
+ origin: host,
2575
+ preloadOptions: ops,
2576
+ remote,
2577
+ remoteInfo,
2578
+ globalSnapshot,
2579
+ remoteSnapshot
2580
+ });
2581
+ if (!assets) {
2582
+ return;
2583
+ }
2584
+ preloadAssets(remoteInfo, host, assets);
2585
+ }));
2586
+ }
2587
+ registerRemotes(remotes, options) {
2588
+ const { host } = this;
2589
+ remotes.forEach((remote)=>{
2590
+ this.registerRemote(remote, host.options.remotes, {
2591
+ force: options == null ? void 0 : options.force
2592
+ });
2593
+ });
2594
+ }
2595
+ async getRemoteModuleAndOptions(options) {
2596
+ const { host } = this;
2597
+ const { id } = options;
2598
+ let loadRemoteArgs;
2599
+ try {
2600
+ loadRemoteArgs = await this.hooks.lifecycle.beforeRequest.emit({
2601
+ id,
2602
+ options: host.options,
2603
+ origin: host
2604
+ });
2605
+ } catch (error) {
2606
+ loadRemoteArgs = await this.hooks.lifecycle.errorLoadRemote.emit({
2607
+ id,
2608
+ options: host.options,
2609
+ origin: host,
2610
+ from: 'runtime',
2611
+ error,
2612
+ lifecycle: 'beforeRequest'
2613
+ });
2614
+ if (!loadRemoteArgs) {
2615
+ throw error;
2616
+ }
2617
+ }
2618
+ const { id: idRes } = loadRemoteArgs;
2619
+ const remoteSplitInfo = matchRemoteWithNameAndExpose(host.options.remotes, idRes);
2620
+ assert(remoteSplitInfo, getShortErrorMsg(RUNTIME_004, runtimeDescMap, {
2621
+ hostName: host.options.name,
2622
+ requestId: idRes
2623
+ }));
2624
+ const { remote: rawRemote } = remoteSplitInfo;
2625
+ const remoteInfo = getRemoteInfo(rawRemote);
2626
+ const matchInfo = await host.sharedHandler.hooks.lifecycle.afterResolve.emit(_extends({
2627
+ id: idRes
2628
+ }, remoteSplitInfo, {
2629
+ options: host.options,
2630
+ origin: host,
2631
+ remoteInfo
2632
+ }));
2633
+ const { remote, expose } = matchInfo;
2634
+ assert(remote && expose, `The 'beforeRequest' hook was executed, but it failed to return the correct 'remote' and 'expose' values while loading ${idRes}.`);
2635
+ let module = host.moduleCache.get(remote.name);
2636
+ const moduleOptions = {
2637
+ host: host,
2638
+ remoteInfo
2639
+ };
2640
+ if (!module) {
2641
+ module = new Module(moduleOptions);
2642
+ host.moduleCache.set(remote.name, module);
2643
+ }
2644
+ return {
2645
+ module,
2646
+ moduleOptions,
2647
+ remoteMatchInfo: matchInfo
2648
+ };
2649
+ }
2650
+ registerRemote(remote, targetRemotes, options) {
2651
+ const { host } = this;
2652
+ const normalizeRemote = ()=>{
2653
+ if (remote.alias) {
2654
+ // Validate if alias equals the prefix of remote.name and remote.alias, if so, throw an error
2655
+ // As multi-level path references cannot guarantee unique names, alias being a prefix of remote.name is not supported
2656
+ const findEqual = targetRemotes.find((item)=>{
2657
+ var _item_alias;
2658
+ return remote.alias && (item.name.startsWith(remote.alias) || ((_item_alias = item.alias) == null ? void 0 : _item_alias.startsWith(remote.alias)));
2659
+ });
2660
+ assert(!findEqual, `The alias ${remote.alias} of remote ${remote.name} is not allowed to be the prefix of ${findEqual && findEqual.name} name or alias`);
2661
+ }
2662
+ // Set the remote entry to a complete path
2663
+ if ('entry' in remote) {
2664
+ if (isBrowserEnv() && !remote.entry.startsWith('http')) {
2665
+ remote.entry = new URL(remote.entry, window.location.origin).href;
2666
+ }
2667
+ }
2668
+ if (!remote.shareScope) {
2669
+ remote.shareScope = DEFAULT_SCOPE;
2670
+ }
2671
+ if (!remote.type) {
2672
+ remote.type = DEFAULT_REMOTE_TYPE;
2673
+ }
2674
+ };
2675
+ this.hooks.lifecycle.beforeRegisterRemote.emit({
2676
+ remote,
2677
+ origin: host
2678
+ });
2679
+ const registeredRemote = targetRemotes.find((item)=>item.name === remote.name);
2680
+ if (!registeredRemote) {
2681
+ normalizeRemote();
2682
+ targetRemotes.push(remote);
2683
+ this.hooks.lifecycle.registerRemote.emit({
2684
+ remote,
2685
+ origin: host
2686
+ });
2687
+ } else {
2688
+ const messages = [
2689
+ `The remote "${remote.name}" is already registered.`,
2690
+ (options == null ? void 0 : options.force) ? 'Hope you have known that OVERRIDE it may have some unexpected errors' : 'If you want to merge the remote, you can set "force: true".'
2691
+ ];
2692
+ if (options == null ? void 0 : options.force) {
2693
+ // remove registered remote
2694
+ this.removeRemote(registeredRemote);
2695
+ normalizeRemote();
2696
+ targetRemotes.push(remote);
2697
+ this.hooks.lifecycle.registerRemote.emit({
2698
+ remote,
2699
+ origin: host
2700
+ });
2701
+ }
2702
+ warn$1(messages.join(' '));
2703
+ }
2704
+ }
2705
+ removeRemote(remote) {
2706
+ try {
2707
+ const { host } = this;
2708
+ const { name } = remote;
2709
+ const remoteIndex = host.options.remotes.findIndex((item)=>item.name === name);
2710
+ if (remoteIndex !== -1) {
2711
+ host.options.remotes.splice(remoteIndex, 1);
2712
+ }
2713
+ const loadedModule = host.moduleCache.get(remote.name);
2714
+ if (loadedModule) {
2715
+ const remoteInfo = loadedModule.remoteInfo;
2716
+ const key = remoteInfo.entryGlobalName;
2717
+ if (CurrentGlobal[key]) {
2718
+ var _Object_getOwnPropertyDescriptor;
2719
+ if ((_Object_getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor(CurrentGlobal, key)) == null ? void 0 : _Object_getOwnPropertyDescriptor.configurable) {
2720
+ delete CurrentGlobal[key];
2721
+ } else {
2722
+ // @ts-ignore
2723
+ CurrentGlobal[key] = undefined;
2724
+ }
2725
+ }
2726
+ const remoteEntryUniqueKey = getRemoteEntryUniqueKey(loadedModule.remoteInfo);
2727
+ if (globalLoading[remoteEntryUniqueKey]) {
2728
+ delete globalLoading[remoteEntryUniqueKey];
2729
+ }
2730
+ host.snapshotHandler.manifestCache.delete(remoteInfo.entry);
2731
+ // delete unloaded shared and instance
2732
+ let remoteInsId = remoteInfo.buildVersion ? composeKeyWithSeparator(remoteInfo.name, remoteInfo.buildVersion) : remoteInfo.name;
2733
+ const remoteInsIndex = CurrentGlobal.__FEDERATION__.__INSTANCES__.findIndex((ins)=>{
2734
+ if (remoteInfo.buildVersion) {
2735
+ return ins.options.id === remoteInsId;
2736
+ } else {
2737
+ return ins.name === remoteInsId;
2738
+ }
2739
+ });
2740
+ if (remoteInsIndex !== -1) {
2741
+ const remoteIns = CurrentGlobal.__FEDERATION__.__INSTANCES__[remoteInsIndex];
2742
+ remoteInsId = remoteIns.options.id || remoteInsId;
2743
+ const globalShareScopeMap = getGlobalShareScope();
2744
+ let isAllSharedNotUsed = true;
2745
+ const needDeleteKeys = [];
2746
+ Object.keys(globalShareScopeMap).forEach((instId)=>{
2747
+ const shareScopeMap = globalShareScopeMap[instId];
2748
+ shareScopeMap && Object.keys(shareScopeMap).forEach((shareScope)=>{
2749
+ const shareScopeVal = shareScopeMap[shareScope];
2750
+ shareScopeVal && Object.keys(shareScopeVal).forEach((shareName)=>{
2751
+ const sharedPkgs = shareScopeVal[shareName];
2752
+ sharedPkgs && Object.keys(sharedPkgs).forEach((shareVersion)=>{
2753
+ const shared = sharedPkgs[shareVersion];
2754
+ if (shared && typeof shared === 'object' && shared.from === remoteInfo.name) {
2755
+ if (shared.loaded || shared.loading) {
2756
+ shared.useIn = shared.useIn.filter((usedHostName)=>usedHostName !== remoteInfo.name);
2757
+ if (shared.useIn.length) {
2758
+ isAllSharedNotUsed = false;
2759
+ } else {
2760
+ needDeleteKeys.push([
2761
+ instId,
2762
+ shareScope,
2763
+ shareName,
2764
+ shareVersion
2765
+ ]);
2766
+ }
2767
+ } else {
2768
+ needDeleteKeys.push([
2769
+ instId,
2770
+ shareScope,
2771
+ shareName,
2772
+ shareVersion
2773
+ ]);
2774
+ }
2775
+ }
2776
+ });
2777
+ });
2778
+ });
2779
+ });
2780
+ if (isAllSharedNotUsed) {
2781
+ remoteIns.shareScopeMap = {};
2782
+ delete globalShareScopeMap[remoteInsId];
2783
+ }
2784
+ needDeleteKeys.forEach(([insId, shareScope, shareName, shareVersion])=>{
2785
+ var _globalShareScopeMap_insId_shareScope_shareName, _globalShareScopeMap_insId_shareScope, _globalShareScopeMap_insId;
2786
+ (_globalShareScopeMap_insId = globalShareScopeMap[insId]) == null ? true : (_globalShareScopeMap_insId_shareScope = _globalShareScopeMap_insId[shareScope]) == null ? true : (_globalShareScopeMap_insId_shareScope_shareName = _globalShareScopeMap_insId_shareScope[shareName]) == null ? true : delete _globalShareScopeMap_insId_shareScope_shareName[shareVersion];
2787
+ });
2788
+ CurrentGlobal.__FEDERATION__.__INSTANCES__.splice(remoteInsIndex, 1);
2789
+ }
2790
+ const { hostGlobalSnapshot } = getGlobalRemoteInfo(remote, host);
2791
+ if (hostGlobalSnapshot) {
2792
+ const remoteKey = hostGlobalSnapshot && 'remotesInfo' in hostGlobalSnapshot && hostGlobalSnapshot.remotesInfo && getInfoWithoutType(hostGlobalSnapshot.remotesInfo, remote.name).key;
2793
+ if (remoteKey) {
2794
+ delete hostGlobalSnapshot.remotesInfo[remoteKey];
2795
+ if (//eslint-disable-next-line no-extra-boolean-cast
2796
+ Boolean(Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey])) {
2797
+ delete Global.__FEDERATION__.__MANIFEST_LOADING__[remoteKey];
2798
+ }
2799
+ }
2800
+ }
2801
+ host.moduleCache.delete(remote.name);
2802
+ }
2803
+ } catch (err) {
2804
+ logger.log('removeRemote fail: ', err);
2805
+ }
2806
+ }
2807
+ constructor(host){
2808
+ this.hooks = new PluginSystem({
2809
+ beforeRegisterRemote: new SyncWaterfallHook('beforeRegisterRemote'),
2810
+ registerRemote: new SyncWaterfallHook('registerRemote'),
2811
+ beforeRequest: new AsyncWaterfallHook('beforeRequest'),
2812
+ onLoad: new AsyncHook('onLoad'),
2813
+ handlePreloadModule: new SyncHook('handlePreloadModule'),
2814
+ errorLoadRemote: new AsyncHook('errorLoadRemote'),
2815
+ beforePreloadRemote: new AsyncHook('beforePreloadRemote'),
2816
+ generatePreloadAssets: new AsyncHook('generatePreloadAssets'),
2817
+ // not used yet
2818
+ afterPreloadRemote: new AsyncHook(),
2819
+ loadEntry: new AsyncHook()
2820
+ });
2821
+ this.host = host;
2822
+ this.idToRemoteMap = {};
2823
+ }
2824
+ }
2825
+
2826
+ class FederationHost {
2827
+ initOptions(userOptions) {
2828
+ this.registerPlugins(userOptions.plugins);
2829
+ const options = this.formatOptions(this.options, userOptions);
2830
+ this.options = options;
2831
+ return options;
2832
+ }
2833
+ async loadShare(pkgName, extraOptions) {
2834
+ return this.sharedHandler.loadShare(pkgName, extraOptions);
2835
+ }
2836
+ // The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.
2837
+ // 1. If the loaded shared already exists globally, then it will be reused
2838
+ // 2. If lib exists in local shared, it will be used directly
2839
+ // 3. If the local get returns something other than Promise, then it will be used directly
2840
+ loadShareSync(pkgName, extraOptions) {
2841
+ return this.sharedHandler.loadShareSync(pkgName, extraOptions);
2842
+ }
2843
+ initializeSharing(shareScopeName = DEFAULT_SCOPE, extraOptions) {
2844
+ return this.sharedHandler.initializeSharing(shareScopeName, extraOptions);
2845
+ }
2846
+ initRawContainer(name, url, container) {
2847
+ const remoteInfo = getRemoteInfo({
2848
+ name,
2849
+ entry: url
2850
+ });
2851
+ const module = new Module({
2852
+ host: this,
2853
+ remoteInfo
2854
+ });
2855
+ module.remoteEntryExports = container;
2856
+ this.moduleCache.set(name, module);
2857
+ return module;
2858
+ }
2859
+ // eslint-disable-next-line max-lines-per-function
2860
+ // eslint-disable-next-line @typescript-eslint/member-ordering
2861
+ async loadRemote(id, options) {
2862
+ return this.remoteHandler.loadRemote(id, options);
2863
+ }
2864
+ // eslint-disable-next-line @typescript-eslint/member-ordering
2865
+ async preloadRemote(preloadOptions) {
2866
+ return this.remoteHandler.preloadRemote(preloadOptions);
2867
+ }
2868
+ initShareScopeMap(scopeName, shareScope, extraOptions = {}) {
2869
+ this.sharedHandler.initShareScopeMap(scopeName, shareScope, extraOptions);
2870
+ }
2871
+ formatOptions(globalOptions, userOptions) {
2872
+ const { shared } = formatShareConfigs(globalOptions, userOptions);
2873
+ const { userOptions: userOptionsRes, options: globalOptionsRes } = this.hooks.lifecycle.beforeInit.emit({
2874
+ origin: this,
2875
+ userOptions,
2876
+ options: globalOptions,
2877
+ shareInfo: shared
2878
+ });
2879
+ const remotes = this.remoteHandler.formatAndRegisterRemote(globalOptionsRes, userOptionsRes);
2880
+ const { shared: handledShared } = this.sharedHandler.registerShared(globalOptionsRes, userOptionsRes);
2881
+ const plugins = [
2882
+ ...globalOptionsRes.plugins
2883
+ ];
2884
+ if (userOptionsRes.plugins) {
2885
+ userOptionsRes.plugins.forEach((plugin)=>{
2886
+ if (!plugins.includes(plugin)) {
2887
+ plugins.push(plugin);
2888
+ }
2889
+ });
2890
+ }
2891
+ const optionsRes = _extends({}, globalOptions, userOptions, {
2892
+ plugins,
2893
+ remotes,
2894
+ shared: handledShared
2895
+ });
2896
+ this.hooks.lifecycle.init.emit({
2897
+ origin: this,
2898
+ options: optionsRes
2899
+ });
2900
+ return optionsRes;
2901
+ }
2902
+ registerPlugins(plugins) {
2903
+ const pluginRes = registerPlugins(plugins, [
2904
+ this.hooks,
2905
+ this.remoteHandler.hooks,
2906
+ this.sharedHandler.hooks,
2907
+ this.snapshotHandler.hooks,
2908
+ this.loaderHook,
2909
+ this.bridgeHook
2910
+ ]);
2911
+ // Merge plugin
2912
+ this.options.plugins = this.options.plugins.reduce((res, plugin)=>{
2913
+ if (!plugin) return res;
2914
+ if (res && !res.find((item)=>item.name === plugin.name)) {
2915
+ res.push(plugin);
2916
+ }
2917
+ return res;
2918
+ }, pluginRes || []);
2919
+ }
2920
+ registerRemotes(remotes, options) {
2921
+ return this.remoteHandler.registerRemotes(remotes, options);
2922
+ }
2923
+ constructor(userOptions){
2924
+ this.hooks = new PluginSystem({
2925
+ beforeInit: new SyncWaterfallHook('beforeInit'),
2926
+ init: new SyncHook(),
2927
+ // maybe will change, temporarily for internal use only
2928
+ beforeInitContainer: new AsyncWaterfallHook('beforeInitContainer'),
2929
+ // maybe will change, temporarily for internal use only
2930
+ initContainer: new AsyncWaterfallHook('initContainer')
2931
+ });
2932
+ this.version = "0.6.14";
2933
+ this.moduleCache = new Map();
2934
+ this.loaderHook = new PluginSystem({
2935
+ // FIXME: may not be suitable , not open to the public yet
2936
+ getModuleInfo: new SyncHook(),
2937
+ createScript: new SyncHook(),
2938
+ createLink: new SyncHook(),
2939
+ // only work for manifest , so not open to the public yet
2940
+ fetch: new AsyncHook(),
2941
+ getModuleFactory: new AsyncHook()
2942
+ });
2943
+ this.bridgeHook = new PluginSystem({
2944
+ beforeBridgeRender: new SyncHook(),
2945
+ afterBridgeRender: new SyncHook(),
2946
+ beforeBridgeDestroy: new SyncHook(),
2947
+ afterBridgeDestroy: new SyncHook()
2948
+ });
2949
+ // TODO: Validate the details of the options
2950
+ // Initialize options with default values
2951
+ const defaultOptions = {
2952
+ id: getBuilderId(),
2953
+ name: userOptions.name,
2954
+ plugins: [
2955
+ snapshotPlugin(),
2956
+ generatePreloadAssetsPlugin()
2957
+ ],
2958
+ remotes: [],
2959
+ shared: {},
2960
+ inBrowser: isBrowserEnv()
2961
+ };
2962
+ this.name = userOptions.name;
2963
+ this.options = defaultOptions;
2964
+ this.snapshotHandler = new SnapshotHandler(this);
2965
+ this.sharedHandler = new SharedHandler(this);
2966
+ this.remoteHandler = new RemoteHandler(this);
2967
+ this.shareScopeMap = this.sharedHandler.shareScopeMap;
2968
+ this.registerPlugins([
2969
+ ...defaultOptions.plugins,
2970
+ ...userOptions.plugins || []
2971
+ ]);
2972
+ this.options = this.formatOptions(defaultOptions, userOptions);
2973
+ }
2974
+ }
2975
+
2976
+ var index = /*#__PURE__*/Object.freeze({
2977
+ __proto__: null
2978
+ });
2979
+
2980
+ export { CurrentGlobal, FederationHost, Global, Module, addGlobalSnapshot, assert, getGlobalFederationConstructor, getGlobalSnapshot, getInfoWithoutType, getRegisteredShare, getRemoteEntry, getRemoteInfo, helpers, isStaticResourcesEqual, matchRemoteWithNameAndExpose, registerGlobalPlugins, resetFederationGlobalInfo, safeWrapper, satisfy, setGlobalFederationConstructor, setGlobalFederationInstance, index as types };