@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 ADDED
@@ -0,0 +1,11 @@
1
+ # runtime
2
+
3
+ This library was generated with [Nx](https://nx.dev).
4
+
5
+ ## Building
6
+
7
+ Run `nx build runtime` to build the library.
8
+
9
+ ## Running unit tests
10
+
11
+ Run `nx test runtime` to execute the unit tests via [Vitest](https://vitest.dev/).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softarc/native-federation-runtime",
3
- "version": "4.0.0-RC2",
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",
@@ -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 {};
@@ -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";
@@ -1,3 +0,0 @@
1
- import type { SharedInfo } from '@softarc/native-federation/domain';
2
- export declare function getExternalUrl(shared: SharedInfo): string | undefined;
3
- export declare function setExternalUrl(shared: SharedInfo, url: string): void;
@@ -1,6 +0,0 @@
1
- export interface InitFederationOptions {
2
- cacheTag?: string;
3
- }
4
- export interface ProcessRemoteInfoOptions extends InitFederationOptions {
5
- throwIfRemoteNotFound: boolean;
6
- }
@@ -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;
@@ -1,7 +0,0 @@
1
- export type Imports = Record<string, string>;
2
- export type Scopes = Record<string, Imports>;
3
- export type ImportMap = {
4
- imports: Imports;
5
- scopes: Scopes;
6
- };
7
- export declare function mergeImportMaps(map1: ImportMap, map2: ImportMap): ImportMap;
@@ -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,2 +0,0 @@
1
- import type { ImportMap } from '../model/import-map.js';
2
- export declare function appendImportMap(importMap: ImportMap): void;
@@ -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;