@softarc/native-federation-runtime 4.0.0-RC2 → 4.0.0-RC4
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/README.md +11 -0
- package/package.json +6 -1
- package/lib/get-shared.d.ts +0 -19
- package/lib/init-federation.d.ts +0 -104
- package/lib/load-remote-module.d.ts +0 -82
- package/lib/model/build-notifications-options.d.ts +0 -1
- package/lib/model/externals.d.ts +0 -3
- package/lib/model/federation-info.d.ts +0 -6
- package/lib/model/global-cache.d.ts +0 -11
- package/lib/model/import-map.d.ts +0 -7
- package/lib/model/remotes.d.ts +0 -9
- package/lib/utils/add-import-map.d.ts +0 -2
- package/lib/utils/path-utils.d.ts +0 -13
- package/lib/utils/trusted-types.d.ts +0 -1
- package/lib/watch-federation-build.d.ts +0 -9
package/README.md
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softarc/native-federation-runtime",
|
|
3
|
-
"version": "4.0.0-
|
|
3
|
+
"version": "4.0.0-RC4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -16,8 +16,13 @@
|
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
18
|
"lib",
|
|
19
|
+
"index.d.ts",
|
|
20
|
+
"index.js",
|
|
19
21
|
"!**/*.tsbuildinfo"
|
|
20
22
|
],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@softarc/native-federation": "4.0.0-RC4"
|
|
25
|
+
},
|
|
21
26
|
"devDependencies": {
|
|
22
27
|
"@types/node": "^22.5.4",
|
|
23
28
|
"vitest": "^3.0.0",
|
package/lib/get-shared.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
type Type<T> = new () => T;
|
|
2
|
-
export type ShareObject = {
|
|
3
|
-
version: string;
|
|
4
|
-
scope?: string;
|
|
5
|
-
get: () => Promise<() => Type<unknown>>;
|
|
6
|
-
shareConfig?: {
|
|
7
|
-
singleton?: boolean;
|
|
8
|
-
requiredVersion: string;
|
|
9
|
-
};
|
|
10
|
-
};
|
|
11
|
-
export type ShareConfig = {
|
|
12
|
-
[pkgName: string]: Array<ShareObject>;
|
|
13
|
-
};
|
|
14
|
-
export type ShareOptions = {
|
|
15
|
-
singleton: boolean;
|
|
16
|
-
requiredVersionPrefix: '^' | '~' | '>' | '>=' | '';
|
|
17
|
-
};
|
|
18
|
-
export declare function getShared(options?: ShareOptions): ShareConfig;
|
|
19
|
-
export {};
|
package/lib/init-federation.d.ts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { type FederationInfo } from '@softarc/native-federation/domain';
|
|
2
|
-
import { type InitFederationOptions, type ProcessRemoteInfoOptions } from './model/federation-info.js';
|
|
3
|
-
import { type ImportMap } from './model/import-map.js';
|
|
4
|
-
/**
|
|
5
|
-
* Initializes the Native Federation runtime for the host application.
|
|
6
|
-
*
|
|
7
|
-
* This is the main entry point for setting up federation. It performs the following:
|
|
8
|
-
* 1. Loads the host's remoteEntry.json to discover shared dependencies
|
|
9
|
-
* 2. Loads each remote's remoteEntry.json to discover exposed modules
|
|
10
|
-
* 3. Creates an ES Module import map with proper scoping
|
|
11
|
-
* 4. Injects the import map into the DOM as a <script type="importmap-shim">
|
|
12
|
-
*
|
|
13
|
-
* The import map allows dynamic imports to resolve correctly:
|
|
14
|
-
* - Host shared deps go in root imports (e.g., "angular": "./angular.js")
|
|
15
|
-
* - Remote exposed modules go in root imports (e.g., "mfe1/Component": "http://...")
|
|
16
|
-
* - Remote shared deps go in scoped imports for proper resolution
|
|
17
|
-
*
|
|
18
|
-
* @param remotesOrManifestUrl - Either:
|
|
19
|
-
* - A record of remote names to their remoteEntry.json URLs
|
|
20
|
-
* Example: { mfe1: 'http://localhost:3000/remoteEntry.json' }
|
|
21
|
-
* - A URL to a manifest.json that contains the remotes record
|
|
22
|
-
* Example: 'http://localhost:3000/federation-manifest.json'
|
|
23
|
-
*
|
|
24
|
-
* @param options - Configuration options:
|
|
25
|
-
* - cacheTag: A version string to append as query param for cache busting
|
|
26
|
-
* Example: { cacheTag: 'v1.0.0' } results in '?t=v1.0.0' on all requests
|
|
27
|
-
*
|
|
28
|
-
* @returns The final merged ImportMap that was injected into the DOM
|
|
29
|
-
*
|
|
30
|
-
*/
|
|
31
|
-
export declare function initFederation(remotesOrManifestUrl?: Record<string, string> | string, options?: InitFederationOptions): Promise<ImportMap>;
|
|
32
|
-
/**
|
|
33
|
-
* Fetches and registers multiple remote applications in parallel and merges their import maps.
|
|
34
|
-
*
|
|
35
|
-
* This function is the orchestrator for loading all remotes. It:
|
|
36
|
-
* 1. Creates a promise for each remote to load its remoteEntry.json
|
|
37
|
-
* 2. Applies cache busting to each remote URL
|
|
38
|
-
* 3. Handles errors gracefully (logs or throws based on options)
|
|
39
|
-
* 4. Merges all successful remote import maps into one
|
|
40
|
-
*
|
|
41
|
-
* Each remote contributes:
|
|
42
|
-
* - Its exposed modules to the root imports
|
|
43
|
-
* - Its shared dependencies to scoped imports
|
|
44
|
-
*
|
|
45
|
-
* @param remotes - Record of remote names to their remoteEntry.json URLs
|
|
46
|
-
* @param options - Processing options including:
|
|
47
|
-
* - throwIfRemoteNotFound: Whether to throw or log on remote load failure
|
|
48
|
-
* - cacheTag: Cache busting tag to append to URLs
|
|
49
|
-
*
|
|
50
|
-
* @returns Merged import map containing all remotes' contributions
|
|
51
|
-
*
|
|
52
|
-
*/
|
|
53
|
-
export declare function fetchAndRegisterRemotes(remotes: Record<string, string>, options?: ProcessRemoteInfoOptions): Promise<ImportMap>;
|
|
54
|
-
/**
|
|
55
|
-
* @deprecated Use `fetchAndRegisterRemotes` instead.
|
|
56
|
-
* @param remotes
|
|
57
|
-
* @param options
|
|
58
|
-
* @returns
|
|
59
|
-
*/
|
|
60
|
-
export declare function processRemoteInfos(remotes: Record<string, string>, options?: ProcessRemoteInfoOptions): Promise<ImportMap>;
|
|
61
|
-
/**
|
|
62
|
-
* Fetches a single remote application's remoteEntry.json file and registers it in the system (global registry).
|
|
63
|
-
*
|
|
64
|
-
* This function handles everything needed to integrate one remote:
|
|
65
|
-
* 1. Fetches the remote's remoteEntry.json file
|
|
66
|
-
* 2. Extracts the base URL from the remoteEntry path
|
|
67
|
-
* 3. Creates import map entries for exposed modules and shared deps
|
|
68
|
-
* 4. Registers the remote in the global remotes registry
|
|
69
|
-
* 5. Sets up hot reload watching if configured (development mode)
|
|
70
|
-
*
|
|
71
|
-
* @param federationInfoUrl - Full URL to the remote's remoteEntry.json
|
|
72
|
-
* @param remoteName - Name to use for this remote (optional, uses info.name if not provided)
|
|
73
|
-
*
|
|
74
|
-
* @returns Import map containing this remote's exposed modules and shared dependencies
|
|
75
|
-
*
|
|
76
|
-
* @example
|
|
77
|
-
* ```typescript
|
|
78
|
-
* const importMap = await fetchAndRegisterRemote(
|
|
79
|
-
* 'http://localhost:3000/mfe1/remoteEntry.json',
|
|
80
|
-
* 'mfe1'
|
|
81
|
-
* );
|
|
82
|
-
* // Result: {
|
|
83
|
-
* // imports: { 'mfe1/Component': 'http://localhost:3000/mfe1/Component.js' },
|
|
84
|
-
* // scopes: { 'http://localhost:3000/mfe1/': { 'lodash': '...' } }
|
|
85
|
-
* // }
|
|
86
|
-
* ```
|
|
87
|
-
*/
|
|
88
|
-
export declare function fetchAndRegisterRemote(federationInfoUrl: string, remoteName?: string): Promise<ImportMap>;
|
|
89
|
-
/**
|
|
90
|
-
* Processes the host application's federation info into an import map.
|
|
91
|
-
*
|
|
92
|
-
* The host app typically doesn't expose modules (it's the consumer),
|
|
93
|
-
* but it does share dependencies that should be available to remotes.
|
|
94
|
-
*
|
|
95
|
-
* Host shared dependencies go in root-level imports (not scoped) because:
|
|
96
|
-
* 1. The host loads first and establishes the base environment
|
|
97
|
-
* 2. Remotes should prefer host versions to avoid duplication
|
|
98
|
-
*
|
|
99
|
-
* @param hostInfo - Federation info from the host's remoteEntry.json
|
|
100
|
-
* @param relBundlesPath - Relative path to the host's bundle directory (default: './')
|
|
101
|
-
*
|
|
102
|
-
* @returns Import map with host's shared dependencies in root imports
|
|
103
|
-
*/
|
|
104
|
-
export declare function processHostInfo(hostInfo: FederationInfo, relBundlesPath?: string): Promise<ImportMap>;
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Options for loading a remote module.
|
|
3
|
-
*
|
|
4
|
-
* @template T - The expected type of the module's exports
|
|
5
|
-
*
|
|
6
|
-
* @property remoteEntry - Optional URL to the remote's remoteEntry.json file.
|
|
7
|
-
* Used for lazy-loading remotes that weren't registered during initFederation
|
|
8
|
-
* Example: 'http://localhost:3000/remoteEntry.json'
|
|
9
|
-
*
|
|
10
|
-
* @property remoteName - Optional name of the remote application.
|
|
11
|
-
* Should match the name used during initFederation or the name in remoteEntry.json.
|
|
12
|
-
* Example: 'mfe1'
|
|
13
|
-
*
|
|
14
|
-
* @property exposedModule - The key of the exposed module to load (required).
|
|
15
|
-
* Must match the key defined in the remote's federation config.
|
|
16
|
-
* Example: './Component' or './Dashboard'
|
|
17
|
-
*
|
|
18
|
-
* @property fallback - Optional fallback value to return if the remote or module cannot be loaded.
|
|
19
|
-
* Prevents throwing errors and provides graceful degradation.
|
|
20
|
-
* Example: A default component or null
|
|
21
|
-
*/
|
|
22
|
-
export type LoadRemoteModuleOptions<T = any> = {
|
|
23
|
-
remoteEntry?: string;
|
|
24
|
-
remoteName?: string;
|
|
25
|
-
exposedModule: string;
|
|
26
|
-
fallback?: T;
|
|
27
|
-
};
|
|
28
|
-
/**
|
|
29
|
-
* Dynamically loads a remote module at runtime from a federated application.
|
|
30
|
-
*
|
|
31
|
-
* This is the primary API for consuming remote modules after federation has been initialized.
|
|
32
|
-
* It supports two calling patterns:
|
|
33
|
-
*
|
|
34
|
-
* **Pattern 1: Using options object**
|
|
35
|
-
* ```typescript
|
|
36
|
-
* const module = await loadRemoteModule({
|
|
37
|
-
* remoteName: 'mfe1',
|
|
38
|
-
* exposedModule: './Component',
|
|
39
|
-
* fallback: DefaultComponent
|
|
40
|
-
* });
|
|
41
|
-
* ```
|
|
42
|
-
*
|
|
43
|
-
* **Pattern 2: Using positional arguments**
|
|
44
|
-
* ```typescript
|
|
45
|
-
* const module = await loadRemoteModule('mfe1', './Component');
|
|
46
|
-
* ```
|
|
47
|
-
*
|
|
48
|
-
* ## Loading Process
|
|
49
|
-
*
|
|
50
|
-
* 1. **Normalize Options**: Converts arguments into a standard options object
|
|
51
|
-
* 2. **Ensure Remote Initialized**: If remoteEntry is provided and remote isn't loaded,
|
|
52
|
-
* fetches and registers it dynamically
|
|
53
|
-
* 3. **Resolve Remote Name**: Determines remote name from options or remoteEntry URL
|
|
54
|
-
* 4. **Validate Remote**: Checks if remote exists in the registry
|
|
55
|
-
* 5. **Validate Exposed Module**: Verifies the requested module is exposed by the remote
|
|
56
|
-
* 6. **Import Module**: Uses dynamic import or import-shim to load the module
|
|
57
|
-
* 7. **Handle Errors**: Returns fallback if provided, otherwise throws
|
|
58
|
-
*
|
|
59
|
-
* ## Lazy Loading Support
|
|
60
|
-
*
|
|
61
|
-
* If you provide a `remoteEntry` URL for a remote that wasn't initialized during
|
|
62
|
-
* `initFederation()`, this function will automatically:
|
|
63
|
-
* - Fetch the remote's remoteEntry.json
|
|
64
|
-
* - Register it in the global registry
|
|
65
|
-
* - Update the import map
|
|
66
|
-
* - Then load the requested module
|
|
67
|
-
*
|
|
68
|
-
* This enables on-demand loading of remotes based on user interactions.
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
* @template T - The expected type of the module's exports
|
|
72
|
-
*
|
|
73
|
-
* @param options - Configuration object for loading the remote module
|
|
74
|
-
* @returns Promise resolving to the loaded module or fallback value
|
|
75
|
-
*
|
|
76
|
-
* @throws Error if remote is not found and no fallback is provided
|
|
77
|
-
* @throws Error if exposed module doesn't exist and no fallback is provided
|
|
78
|
-
* @throws Error if module import fails and no fallback is provided
|
|
79
|
-
*
|
|
80
|
-
*/
|
|
81
|
-
export declare function loadRemoteModule<T = any>(options: LoadRemoteModuleOptions): Promise<T>;
|
|
82
|
-
export declare function loadRemoteModule<T = any>(remoteName: string, exposedModule: string): Promise<T>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const BUILD_NOTIFICATIONS_ENDPOINT = "/@angular-architects/native-federation:build-notifications";
|
package/lib/model/externals.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Remote } from './remotes.js';
|
|
2
|
-
export declare const nfNamespace = "__NATIVE_FEDERATION__";
|
|
3
|
-
export type NfCache = {
|
|
4
|
-
externals: Map<string, string>;
|
|
5
|
-
remoteNamesToRemote: Map<string, Remote>;
|
|
6
|
-
baseUrlToRemoteNames: Map<string, string>;
|
|
7
|
-
};
|
|
8
|
-
export type Global = {
|
|
9
|
-
[nfNamespace]: NfCache;
|
|
10
|
-
};
|
|
11
|
-
export declare const globalCache: NfCache;
|
package/lib/model/remotes.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { FederationInfo } from '@softarc/native-federation/domain';
|
|
2
|
-
export type Remote = FederationInfo & {
|
|
3
|
-
baseUrl: string;
|
|
4
|
-
};
|
|
5
|
-
export declare function addRemote(remoteName: string, remote: Remote): void;
|
|
6
|
-
export declare function getRemoteNameByBaseUrl(baseUrl: string): string | undefined;
|
|
7
|
-
export declare function isRemoteInitialized(baseUrl: string): boolean;
|
|
8
|
-
export declare function getRemote(remoteName: string): Remote | undefined;
|
|
9
|
-
export declare function hasRemote(remoteName: string): boolean;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns the full directory of a given path.
|
|
3
|
-
* @param url - The path to get the directory of.
|
|
4
|
-
* @returns The full directory of the path.
|
|
5
|
-
*/
|
|
6
|
-
export declare function getDirectory(url: string): string;
|
|
7
|
-
/**
|
|
8
|
-
* Joins two paths together taking into account trailing slashes and "./" prefixes.
|
|
9
|
-
* @param path1 - The first path to join.
|
|
10
|
-
* @param path2 - The second path to join.
|
|
11
|
-
* @returns The joined path.
|
|
12
|
-
*/
|
|
13
|
-
export declare function joinPaths(path1: string, path2: string): string;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function tryCreateTrustedScript(script: string): string | TrustedScript;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Watches for federation build completion events and automatically reloads the page.
|
|
3
|
-
*
|
|
4
|
-
* This function establishes a Server-Sent Events (SSE) connection to listen for
|
|
5
|
-
* 'federation-rebuild-complete' notifications. When a build completes successfully,
|
|
6
|
-
* it triggers a page reload to reflect the latest changes.
|
|
7
|
-
* @param endpoint - The SSE endpoint URL to watch for build notifications.
|
|
8
|
-
*/
|
|
9
|
-
export declare function watchFederationBuildCompletion(endpoint: string): void;
|