@module-federation/runtime 0.0.0-next-20241018073700 → 0.0.0-next-20241021083129

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/share.esm.js CHANGED
@@ -1,5 +1,5 @@
1
- import { _ as _object_without_properties_loose, a as _extends } from './polyfills.esm.js';
2
1
  import { isBrowserEnv, isDebugMode } from '@module-federation/sdk';
2
+ import { a as _object_without_properties_loose, _ as _extends } from './polyfills.esm.js';
3
3
 
4
4
  function getBuilderId() {
5
5
  //@ts-ignore
@@ -85,6 +85,20 @@ function getRemoteEntryInfoFromSnapshot(snapshot) {
85
85
  }
86
86
  return defaultRemoteEntryInfo;
87
87
  }
88
+ const processModuleAlias = (name, subPath)=>{
89
+ // @host/ ./button -> @host/button
90
+ let moduleName;
91
+ if (name.endsWith('/')) {
92
+ moduleName = name.slice(0, -1);
93
+ } else {
94
+ moduleName = name;
95
+ }
96
+ if (subPath.startsWith('.')) {
97
+ subPath = subPath.slice(1);
98
+ }
99
+ moduleName = moduleName + subPath;
100
+ return moduleName;
101
+ };
88
102
 
89
103
  const nativeGlobal = (()=>{
90
104
  try {
@@ -273,9 +287,214 @@ const getGlobalHostPlugins = ()=>nativeGlobal.__FEDERATION__.__GLOBAL_PLUGIN__;
273
287
  const getPreloaded = (id)=>globalThis.__FEDERATION__.__PRELOADED_MAP__.get(id);
274
288
  const setPreloaded = (id)=>globalThis.__FEDERATION__.__PRELOADED_MAP__.set(id, true);
275
289
 
290
+ function registerPlugins(plugins, hookInstances) {
291
+ const globalPlugins = getGlobalHostPlugins();
292
+ // Incorporate global plugins
293
+ if (globalPlugins.length > 0) {
294
+ globalPlugins.forEach((plugin)=>{
295
+ if (plugins == null ? void 0 : plugins.find((item)=>item.name !== plugin.name)) {
296
+ plugins.push(plugin);
297
+ }
298
+ });
299
+ }
300
+ if (plugins && plugins.length > 0) {
301
+ plugins.forEach((plugin)=>{
302
+ hookInstances.forEach((hookInstance)=>{
303
+ hookInstance.applyPlugin(plugin);
304
+ });
305
+ });
306
+ }
307
+ return plugins;
308
+ }
309
+
276
310
  const DEFAULT_SCOPE = 'default';
277
311
  const DEFAULT_REMOTE_TYPE = 'global';
278
312
 
313
+ class SyncHook {
314
+ on(fn) {
315
+ if (typeof fn === 'function') {
316
+ this.listeners.add(fn);
317
+ }
318
+ }
319
+ once(fn) {
320
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
321
+ const self = this;
322
+ this.on(function wrapper(...args) {
323
+ self.remove(wrapper);
324
+ // eslint-disable-next-line prefer-spread
325
+ return fn.apply(null, args);
326
+ });
327
+ }
328
+ emit(...data) {
329
+ let result;
330
+ if (this.listeners.size > 0) {
331
+ // eslint-disable-next-line prefer-spread
332
+ this.listeners.forEach((fn)=>{
333
+ result = fn(...data);
334
+ });
335
+ }
336
+ return result;
337
+ }
338
+ remove(fn) {
339
+ this.listeners.delete(fn);
340
+ }
341
+ removeAll() {
342
+ this.listeners.clear();
343
+ }
344
+ constructor(type){
345
+ this.type = '';
346
+ this.listeners = new Set();
347
+ if (type) {
348
+ this.type = type;
349
+ }
350
+ }
351
+ }
352
+
353
+ class AsyncHook extends SyncHook {
354
+ emit(...data) {
355
+ let result;
356
+ const ls = Array.from(this.listeners);
357
+ if (ls.length > 0) {
358
+ let i = 0;
359
+ const call = (prev)=>{
360
+ if (prev === false) {
361
+ return false; // Abort process
362
+ } else if (i < ls.length) {
363
+ return Promise.resolve(ls[i++].apply(null, data)).then(call);
364
+ } else {
365
+ return prev;
366
+ }
367
+ };
368
+ result = call();
369
+ }
370
+ return Promise.resolve(result);
371
+ }
372
+ }
373
+
374
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
375
+ function checkReturnData(originalData, returnedData) {
376
+ if (!isObject(returnedData)) {
377
+ return false;
378
+ }
379
+ if (originalData !== returnedData) {
380
+ // eslint-disable-next-line no-restricted-syntax
381
+ for(const key in originalData){
382
+ if (!(key in returnedData)) {
383
+ return false;
384
+ }
385
+ }
386
+ }
387
+ return true;
388
+ }
389
+ class SyncWaterfallHook extends SyncHook {
390
+ emit(data) {
391
+ if (!isObject(data)) {
392
+ error(`The data for the "${this.type}" hook should be an object.`);
393
+ }
394
+ for (const fn of this.listeners){
395
+ try {
396
+ const tempData = fn(data);
397
+ if (checkReturnData(data, tempData)) {
398
+ data = tempData;
399
+ } else {
400
+ this.onerror(`A plugin returned an unacceptable value for the "${this.type}" type.`);
401
+ break;
402
+ }
403
+ } catch (e) {
404
+ warn(e);
405
+ this.onerror(e);
406
+ }
407
+ }
408
+ return data;
409
+ }
410
+ constructor(type){
411
+ super(), this.onerror = error;
412
+ this.type = type;
413
+ }
414
+ }
415
+
416
+ class AsyncWaterfallHook extends SyncHook {
417
+ emit(data) {
418
+ if (!isObject(data)) {
419
+ error(`The response data for the "${this.type}" hook must be an object.`);
420
+ }
421
+ const ls = Array.from(this.listeners);
422
+ if (ls.length > 0) {
423
+ let i = 0;
424
+ const processError = (e)=>{
425
+ warn(e);
426
+ this.onerror(e);
427
+ return data;
428
+ };
429
+ const call = (prevData)=>{
430
+ if (checkReturnData(data, prevData)) {
431
+ data = prevData;
432
+ if (i < ls.length) {
433
+ try {
434
+ return Promise.resolve(ls[i++](data)).then(call, processError);
435
+ } catch (e) {
436
+ return processError(e);
437
+ }
438
+ }
439
+ } else {
440
+ this.onerror(`A plugin returned an incorrect value for the "${this.type}" type.`);
441
+ }
442
+ return data;
443
+ };
444
+ return Promise.resolve(call(data));
445
+ }
446
+ return Promise.resolve(data);
447
+ }
448
+ constructor(type){
449
+ super(), this.onerror = error;
450
+ this.type = type;
451
+ }
452
+ }
453
+
454
+ class PluginSystem {
455
+ applyPlugin(plugin) {
456
+ assert(isPlainObject(plugin), 'Plugin configuration is invalid.');
457
+ // The plugin's name is mandatory and must be unique
458
+ const pluginName = plugin.name;
459
+ assert(pluginName, 'A name must be provided by the plugin.');
460
+ if (!this.registerPlugins[pluginName]) {
461
+ this.registerPlugins[pluginName] = plugin;
462
+ Object.keys(this.lifecycle).forEach((key)=>{
463
+ const pluginLife = plugin[key];
464
+ if (pluginLife) {
465
+ this.lifecycle[key].on(pluginLife);
466
+ }
467
+ });
468
+ }
469
+ }
470
+ removePlugin(pluginName) {
471
+ assert(pluginName, 'A name is required.');
472
+ const plugin = this.registerPlugins[pluginName];
473
+ assert(plugin, `The plugin "${pluginName}" is not registered.`);
474
+ Object.keys(plugin).forEach((key)=>{
475
+ if (key !== 'name') {
476
+ this.lifecycle[key].remove(plugin[key]);
477
+ }
478
+ });
479
+ }
480
+ // eslint-disable-next-line @typescript-eslint/no-shadow
481
+ inherit({ lifecycle, registerPlugins }) {
482
+ Object.keys(lifecycle).forEach((hookName)=>{
483
+ assert(!this.lifecycle[hookName], `The hook "${hookName}" has a conflict and cannot be inherited.`);
484
+ this.lifecycle[hookName] = lifecycle[hookName];
485
+ });
486
+ Object.keys(registerPlugins).forEach((pluginName)=>{
487
+ assert(!this.registerPlugins[pluginName], `The plugin "${pluginName}" has a conflict and cannot be inherited.`);
488
+ this.applyPlugin(registerPlugins[pluginName]);
489
+ });
490
+ }
491
+ constructor(lifecycle){
492
+ this.registerPlugins = {};
493
+ this.lifecycle = lifecycle;
494
+ this.lifecycleKeys = Object.keys(lifecycle);
495
+ }
496
+ }
497
+
279
498
  // fork from https://github.com/originjs/vite-plugin-federation/blob/v1.1.12/packages/lib/src/utils/semver/index.ts
280
499
  // those constants are based on https://www.rubydoc.info/gems/semantic_range/3.0.0/SemanticRange#BUILDIDENTIFIER-constant
281
500
  // Copyright (c)
@@ -865,4 +1084,4 @@ function getTargetSharedOptions(options) {
865
1084
  return Object.assign({}, resolver(shareInfos[pkgName]), extraOptions == null ? void 0 : extraOptions.customShareInfo);
866
1085
  }
867
1086
 
868
- export { isPlainObject as A, isRemoteInfoWithEntry as B, isPureRemoteEntry as C, DEFAULT_REMOTE_TYPE as D, getRemoteEntryInfoFromSnapshot as E, arrayOptions as F, Global as G, formatShareConfigs as H, getTargetSharedOptions as I, addUniqueItem as J, getBuilderId as K, getGlobalShareScope as a, getGlobalFederationInstance as b, getGlobalFederationConstructor as c, setGlobalFederationConstructor as d, getInfoWithoutType as e, getGlobalSnapshot as f, getRegisteredShare as g, getTargetSnapshotInfoByModuleInfo as h, getGlobalSnapshotInfoByModuleInfo as i, setGlobalSnapshotInfoByModuleInfo as j, addGlobalSnapshot as k, getRemoteEntryExports as l, registerGlobalPlugins as m, nativeGlobal as n, getGlobalHostPlugins as o, getPreloaded as p, setPreloaded as q, resetFederationGlobalInfo as r, setGlobalFederationInstance as s, globalLoading as t, DEFAULT_SCOPE as u, assert as v, getFMId as w, isObject as x, error as y, warn as z };
1087
+ export { AsyncHook as A, processModuleAlias as B, isRemoteInfoWithEntry as C, DEFAULT_REMOTE_TYPE as D, isPureRemoteEntry as E, getRemoteEntryInfoFromSnapshot as F, Global as G, error as H, arrayOptions as I, formatShareConfigs as J, getTargetSharedOptions as K, addUniqueItem as L, getBuilderId as M, PluginSystem as P, SyncHook as S, AsyncWaterfallHook as a, SyncWaterfallHook as b, getGlobalShareScope as c, getGlobalFederationInstance as d, getGlobalFederationConstructor as e, setGlobalFederationConstructor as f, getRegisteredShare as g, getInfoWithoutType as h, getGlobalSnapshot as i, getTargetSnapshotInfoByModuleInfo as j, getGlobalSnapshotInfoByModuleInfo as k, setGlobalSnapshotInfoByModuleInfo as l, addGlobalSnapshot as m, nativeGlobal as n, getRemoteEntryExports as o, registerGlobalPlugins as p, getGlobalHostPlugins as q, resetFederationGlobalInfo as r, setGlobalFederationInstance as s, getPreloaded as t, setPreloaded as u, registerPlugins as v, globalLoading as w, DEFAULT_SCOPE as x, assert as y, getFMId as z };
@@ -1,5 +1,7 @@
1
1
  import { resetFederationGlobalInfo, getGlobalFederationInstance, setGlobalFederationInstance, getGlobalFederationConstructor, setGlobalFederationConstructor, getInfoWithoutType, getGlobalSnapshot, getTargetSnapshotInfoByModuleInfo, getGlobalSnapshotInfoByModuleInfo, setGlobalSnapshotInfoByModuleInfo, addGlobalSnapshot, getRemoteEntryExports, registerGlobalPlugins, getGlobalHostPlugins, getPreloaded, setPreloaded, Global } from './global';
2
2
  import { getRegisteredShare, getGlobalShareScope } from './utils/share';
3
+ import * as pluginHelper from './utils/hooks';
4
+ import { registerPlugins } from './utils';
3
5
  interface IShareUtils {
4
6
  getRegisteredShare: typeof getRegisteredShare;
5
7
  getGlobalShareScope: typeof getGlobalShareScope;
@@ -23,6 +25,8 @@ interface IGlobalUtils {
23
25
  getGlobalHostPlugins: typeof getGlobalHostPlugins;
24
26
  getPreloaded: typeof getPreloaded;
25
27
  setPreloaded: typeof setPreloaded;
28
+ registerPlugins: typeof registerPlugins;
29
+ pluginHelper: typeof pluginHelper;
26
30
  }
27
31
  declare const _default: {
28
32
  global: IGlobalUtils;
@@ -32,6 +32,11 @@ export declare class SnapshotHandler {
32
32
  remoteSnapshot: ModuleInfo;
33
33
  from: "global" | "manifest";
34
34
  }>;
35
+ afterLoadSnapshot: AsyncWaterfallHook<{
36
+ options: Options;
37
+ moduleInfo: Remote;
38
+ remoteSnapshot: ModuleInfo;
39
+ }>;
35
40
  }>;
36
41
  loaderHook: FederationHost['loaderHook'];
37
42
  manifestLoading: Record<string, Promise<ModuleInfo>>;
@@ -4,7 +4,7 @@ export type Optional<T, K extends keyof T> = Omit<T, K> & Partial<T>;
4
4
  export type PartialOptional<T, K extends keyof T> = Omit<T, K> & {
5
5
  [P in K]-?: T[P];
6
6
  };
7
- interface RemoteInfoCommon {
7
+ export interface RemoteInfoCommon {
8
8
  alias?: string;
9
9
  shareScope?: string;
10
10
  type?: RemoteEntryType;
@@ -23,8 +23,9 @@ type RemoteLifeCycle = RemoteHandler['hooks']['lifecycle'];
23
23
  type RemoteLifeCycleCyclePartial = Partial<{
24
24
  [k in keyof RemoteLifeCycle]: Parameters<RemoteLifeCycle[k]['on']>[0];
25
25
  }>;
26
- export type FederationRuntimePlugin = CoreLifeCyclePartial & SnapshotLifeCycleCyclePartial & SharedLifeCycleCyclePartial & RemoteLifeCycleCyclePartial & ModuleLifeCycleCyclePartial & {
26
+ type LifeCycle = CoreLifeCyclePartial & SnapshotLifeCycleCyclePartial & SharedLifeCycleCyclePartial & RemoteLifeCycleCyclePartial & ModuleLifeCycleCyclePartial & {
27
27
  name: string;
28
28
  version?: string;
29
29
  };
30
+ export type FederationRuntimePlugin<T = LifeCycle> = LifeCycle & T;
30
31
  export {};
@@ -1,4 +1,5 @@
1
1
  import { FederationHost } from '../core';
2
2
  import { UserOptions } from '../type';
3
3
  import { Module } from '../module';
4
- export declare function registerPlugins(plugins: UserOptions['plugins'], hookInstances: Array<FederationHost['hooks'] | FederationHost['snapshotHandler']['hooks'] | FederationHost['sharedHandler']['hooks'] | FederationHost['remoteHandler']['hooks'] | Module['host']['loaderHook']>): import("../type").FederationRuntimePlugin[] | undefined;
4
+ import { PluginSystem } from './hooks';
5
+ export declare function registerPlugins<Y extends Record<string, any>, T extends PluginSystem<Y>>(plugins: UserOptions['plugins'], hookInstances: Array<T | FederationHost['hooks'] | FederationHost['snapshotHandler']['hooks'] | FederationHost['sharedHandler']['hooks'] | FederationHost['remoteHandler']['hooks'] | Module['host']['loaderHook']>): import("../type").FederationRuntimePlugin[] | undefined;
@@ -15,3 +15,4 @@ export declare function getRemoteEntryInfoFromSnapshot(snapshot: ModuleInfo): {
15
15
  type: RemoteEntryType;
16
16
  globalName: string;
17
17
  };
18
+ export declare const processModuleAlias: (name: string, subPath: string) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/runtime",
3
- "version": "0.0.0-next-20241018073700",
3
+ "version": "0.0.0-next-20241021083129",
4
4
  "author": "zhouxiao <codingzx@gmail.com>",
5
5
  "main": "./dist/index.cjs.js",
6
6
  "module": "./dist/index.esm.js",
@@ -50,6 +50,6 @@
50
50
  }
51
51
  },
52
52
  "dependencies": {
53
- "@module-federation/sdk": "0.0.0-next-20241018073700"
53
+ "@module-federation/sdk": "0.0.0-next-20241021083129"
54
54
  }
55
55
  }