@softarc/native-federation-orchestrator 4.3.1 → 4.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/fesm2022/@softarc/native-federation-orchestrator.mjs +20 -10
- package/fesm2022/@softarc/native-federation-orchestrator.mjs.map +3 -3
- package/fesm2022/module-federation.mjs +56 -0
- package/fesm2022/module-federation.mjs.map +7 -0
- package/fesm2022/node.mjs +19 -9
- package/fesm2022/node.mjs.map +3 -3
- package/package.json +5 -1
- package/quickstart.mjs +11 -11
- package/types/lib/core/2.app/config/mode.contract.d.ts +1 -0
- package/types/lib/core/2.app/driver-ports/init/for-committing-changes.port.d.ts +5 -1
- package/types/lib/module-federation/get-shared.d.ts +7 -0
- package/types/lib/module-federation/share-infos.contract.d.ts +45 -0
- package/types/lib/module-federation.index.d.ts +2 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// src/lib/utils/path.ts
|
|
2
|
+
function join(pathA, pathB) {
|
|
3
|
+
pathA = pathA.endsWith("/") ? pathA.slice(0, -1) : pathA;
|
|
4
|
+
pathB = pathB.startsWith("/") ? pathB.slice(1) : pathB;
|
|
5
|
+
return `${pathA}/${pathB}`;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// src/lib/module-federation/get-shared.ts
|
|
9
|
+
function createGetShared(ports) {
|
|
10
|
+
return (options = {}) => {
|
|
11
|
+
const shared = {};
|
|
12
|
+
for (const scope of ports.sharedExternalsRepo.getScopes({ includeGlobal: true })) {
|
|
13
|
+
const scopeType = ports.sharedExternalsRepo.scopeType(scope);
|
|
14
|
+
const externals = ports.sharedExternalsRepo.getFromScope(scope);
|
|
15
|
+
for (const [packageName, external] of Object.entries(externals)) {
|
|
16
|
+
const shareVersions = external.versions.filter((v) => v.action === "share");
|
|
17
|
+
if (shareVersions.length === 0) continue;
|
|
18
|
+
const versions = scopeType === "strict" ? shareVersions : shareVersions.slice(0, 1);
|
|
19
|
+
const singleton = scopeType === "strict" ? false : options.singleton ?? true;
|
|
20
|
+
for (const version of versions) {
|
|
21
|
+
const url = resolveUrl(version);
|
|
22
|
+
if (!url) continue;
|
|
23
|
+
const shareObject = {
|
|
24
|
+
version: version.tag,
|
|
25
|
+
get: () => ports.browser.importModule(url).then((module) => () => module),
|
|
26
|
+
shareConfig: {
|
|
27
|
+
singleton,
|
|
28
|
+
requiredVersion: resolveRequiredVersion(version, options, scopeType),
|
|
29
|
+
...scopeType === "strict" ? { strictVersion: true } : {}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
if (scopeType !== "global") shareObject.scope = scope;
|
|
33
|
+
if (!shared[packageName]) shared[packageName] = [];
|
|
34
|
+
shared[packageName].push(shareObject);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return shared;
|
|
39
|
+
};
|
|
40
|
+
function resolveUrl(version) {
|
|
41
|
+
const source = version.remotes[0];
|
|
42
|
+
if (!source) return void 0;
|
|
43
|
+
return ports.remoteInfoRepo.tryGet(source.name).map((remote) => join(remote.scopeUrl, source.file)).get();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function resolveRequiredVersion(version, options, scopeType) {
|
|
47
|
+
if (scopeType === "strict") return version.tag;
|
|
48
|
+
if (typeof options.requiredVersionPrefix === "string") {
|
|
49
|
+
return `${options.requiredVersionPrefix}${version.tag}`;
|
|
50
|
+
}
|
|
51
|
+
return version.remotes[0]?.requiredVersion || `^${version.tag}`;
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
createGetShared
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=module-federation.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/lib/utils/path.ts", "../../src/lib/module-federation/get-shared.ts"],
|
|
4
|
+
"sourcesContent": ["function join(pathA: string, pathB: string): string {\n pathA = pathA.endsWith('/') ? pathA.slice(0, -1) : pathA;\n pathB = pathB.startsWith('/') ? pathB.slice(1) : pathB;\n return `${pathA}/${pathB}`;\n}\n\nfunction getScope(path: string) {\n if (!path) return '';\n\n const parts = path.split('/');\n\n if (parts[parts.length - 1] === '' || parts[parts.length - 1]!.includes('.')) {\n parts.pop();\n }\n if (parts.length < 1) return '';\n\n return `${parts.join('/')}/`;\n}\n\nexport { join, getScope };\n", "import type { DrivingContract } from 'lib/core/2.app/driving-ports/driving.contract';\nimport type { SharedVersion } from 'lib/core/1.domain';\nimport type { GetSharedOptions, ShareInfos, Shared } from './share-infos.contract';\nimport * as _path from 'lib/utils/path';\n\n/**\n * Adapts native federation's shared externals to the `ShareInfos` shape webpack\n * Module Federation expects (see `docs/module-federation.md`).\n */\nexport function createGetShared(\n ports: Pick<DrivingContract, 'sharedExternalsRepo' | 'remoteInfoRepo' | 'browser'>\n): (options?: GetSharedOptions) => ShareInfos {\n return (options = {}) => {\n const shared: ShareInfos = {};\n\n for (const scope of ports.sharedExternalsRepo.getScopes({ includeGlobal: true })) {\n const scopeType = ports.sharedExternalsRepo.scopeType(scope);\n const externals = ports.sharedExternalsRepo.getFromScope(scope);\n\n for (const [packageName, external] of Object.entries(externals)) {\n const shareVersions = external.versions.filter(v => v.action === 'share');\n if (shareVersions.length === 0) continue;\n\n // The strict scope is a version -> location map: every version is shared\n // side by side and stays non-singleton. Other scopes share one singleton.\n const versions = scopeType === 'strict' ? shareVersions : shareVersions.slice(0, 1);\n const singleton = scopeType === 'strict' ? false : (options.singleton ?? true);\n\n for (const version of versions) {\n const url = resolveUrl(version);\n if (!url) continue;\n\n const shareObject: Shared = {\n version: version.tag,\n get: () => ports.browser.importModule(url).then(module => () => module),\n shareConfig: {\n singleton,\n requiredVersion: resolveRequiredVersion(version, options, scopeType),\n ...(scopeType === 'strict' ? { strictVersion: true } : {}),\n },\n };\n if (scopeType !== 'global') shareObject.scope = scope;\n\n if (!shared[packageName]) shared[packageName] = [];\n shared[packageName]!.push(shareObject);\n }\n }\n }\n\n return shared;\n };\n\n function resolveUrl(version: SharedVersion): string | undefined {\n const source = version.remotes[0];\n if (!source) return undefined;\n\n return ports.remoteInfoRepo\n .tryGet(source.name)\n .map(remote => _path.join(remote.scopeUrl, source.file))\n .get();\n }\n}\n\nfunction resolveRequiredVersion(\n version: SharedVersion,\n options: GetSharedOptions,\n scopeType: 'global' | 'strict' | 'shareScope'\n): string {\n // Strict shares a specific version, not a range: pin to the exact tag so a\n // consumer reuses only that version (MF matches via satisfy(version, required)).\n if (scopeType === 'strict') return version.tag;\n if (typeof options.requiredVersionPrefix === 'string') {\n return `${options.requiredVersionPrefix}${version.tag}`;\n }\n return version.remotes[0]?.requiredVersion || `^${version.tag}`;\n}\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAS,KAAK,OAAe,OAAuB;AAClD,UAAQ,MAAM,SAAS,GAAG,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI;AACnD,UAAQ,MAAM,WAAW,GAAG,IAAI,MAAM,MAAM,CAAC,IAAI;AACjD,SAAO,GAAG,KAAK,IAAI,KAAK;AAC1B;;;ACKO,SAAS,gBACd,OAC4C;AAC5C,SAAO,CAAC,UAAU,CAAC,MAAM;AACvB,UAAM,SAAqB,CAAC;AAE5B,eAAW,SAAS,MAAM,oBAAoB,UAAU,EAAE,eAAe,KAAK,CAAC,GAAG;AAChF,YAAM,YAAY,MAAM,oBAAoB,UAAU,KAAK;AAC3D,YAAM,YAAY,MAAM,oBAAoB,aAAa,KAAK;AAE9D,iBAAW,CAAC,aAAa,QAAQ,KAAK,OAAO,QAAQ,SAAS,GAAG;AAC/D,cAAM,gBAAgB,SAAS,SAAS,OAAO,OAAK,EAAE,WAAW,OAAO;AACxE,YAAI,cAAc,WAAW,EAAG;AAIhC,cAAM,WAAW,cAAc,WAAW,gBAAgB,cAAc,MAAM,GAAG,CAAC;AAClF,cAAM,YAAY,cAAc,WAAW,QAAS,QAAQ,aAAa;AAEzE,mBAAW,WAAW,UAAU;AAC9B,gBAAM,MAAM,WAAW,OAAO;AAC9B,cAAI,CAAC,IAAK;AAEV,gBAAM,cAAsB;AAAA,YAC1B,SAAS,QAAQ;AAAA,YACjB,KAAK,MAAM,MAAM,QAAQ,aAAa,GAAG,EAAE,KAAK,YAAU,MAAM,MAAM;AAAA,YACtE,aAAa;AAAA,cACX;AAAA,cACA,iBAAiB,uBAAuB,SAAS,SAAS,SAAS;AAAA,cACnE,GAAI,cAAc,WAAW,EAAE,eAAe,KAAK,IAAI,CAAC;AAAA,YAC1D;AAAA,UACF;AACA,cAAI,cAAc,SAAU,aAAY,QAAQ;AAEhD,cAAI,CAAC,OAAO,WAAW,EAAG,QAAO,WAAW,IAAI,CAAC;AACjD,iBAAO,WAAW,EAAG,KAAK,WAAW;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,WAAW,SAA4C;AAC9D,UAAM,SAAS,QAAQ,QAAQ,CAAC;AAChC,QAAI,CAAC,OAAQ,QAAO;AAEpB,WAAO,MAAM,eACV,OAAO,OAAO,IAAI,EAClB,IAAI,YAAgB,KAAK,OAAO,UAAU,OAAO,IAAI,CAAC,EACtD,IAAI;AAAA,EACT;AACF;AAEA,SAAS,uBACP,SACA,SACA,WACQ;AAGR,MAAI,cAAc,SAAU,QAAO,QAAQ;AAC3C,MAAI,OAAO,QAAQ,0BAA0B,UAAU;AACrD,WAAO,GAAG,QAAQ,qBAAqB,GAAG,QAAQ,GAAG;AAAA,EACvD;AACA,SAAO,QAAQ,QAAQ,CAAC,GAAG,mBAAmB,IAAI,QAAQ,GAAG;AAC/D;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/fesm2022/node.mjs
CHANGED
|
@@ -1890,7 +1890,7 @@ var createInitFlow = ({
|
|
|
1890
1890
|
adapters,
|
|
1891
1891
|
config
|
|
1892
1892
|
}) => {
|
|
1893
|
-
return (remotesOrManifestUrl) => flow.getRemoteEntries(remotesOrManifestUrl).then(flow.processRemoteEntries).then(flow.determineSharedExternals).then(flow.generateImportMap).then(flow.commitChanges).then(flow.exposeModuleLoader).then((loadRemoteModule) => ({
|
|
1893
|
+
return (remotesOrManifestUrl) => flow.getRemoteEntries(remotesOrManifestUrl).then(flow.processRemoteEntries).then(flow.determineSharedExternals).then(flow.generateImportMap).then((importMap) => flow.commitChanges(importMap, { override: true })).then(flow.exposeModuleLoader).then((loadRemoteModule) => ({
|
|
1894
1894
|
config,
|
|
1895
1895
|
adapters,
|
|
1896
1896
|
loadRemoteModule
|
|
@@ -1918,16 +1918,25 @@ function createGetRemoteEntries(config, ports) {
|
|
|
1918
1918
|
};
|
|
1919
1919
|
function addHostRemoteEntry(manifest) {
|
|
1920
1920
|
if (!config.hostRemoteEntry) return manifest;
|
|
1921
|
-
const { name, url,
|
|
1922
|
-
const urlWithCache = cacheTag ? `${url}?cacheTag=${cacheTag}` : url;
|
|
1921
|
+
const { name, url, integrity } = config.hostRemoteEntry;
|
|
1923
1922
|
return {
|
|
1924
1923
|
...manifest,
|
|
1925
|
-
[name]: integrity ? { url
|
|
1924
|
+
[name]: integrity ? { url, integrity } : url
|
|
1926
1925
|
};
|
|
1927
1926
|
}
|
|
1928
1927
|
function normalizeEntry(descriptor) {
|
|
1929
1928
|
return typeof descriptor === "string" ? { url: descriptor } : descriptor;
|
|
1930
1929
|
}
|
|
1930
|
+
function withCacheTag(url, cacheTag) {
|
|
1931
|
+
if (!cacheTag) return url;
|
|
1932
|
+
return `${url}${url.includes("?") ? "&" : "?"}cacheTag=${cacheTag}`;
|
|
1933
|
+
}
|
|
1934
|
+
function resolveCacheTag(remoteName) {
|
|
1935
|
+
if (config.hostRemoteEntry && remoteName === config.hostRemoteEntry.name && config.hostRemoteEntry.cacheTag) {
|
|
1936
|
+
return config.hostRemoteEntry.cacheTag;
|
|
1937
|
+
}
|
|
1938
|
+
return config.profile.cacheTag;
|
|
1939
|
+
}
|
|
1931
1940
|
async function fetchRemoteEntries(manifest) {
|
|
1932
1941
|
const fetchPromises = Object.entries(manifest).map(
|
|
1933
1942
|
([remoteName, descriptor]) => fetchRemoteEntry(remoteName, descriptor)
|
|
@@ -1948,8 +1957,9 @@ function createGetRemoteEntries(config, ports) {
|
|
|
1948
1957
|
}
|
|
1949
1958
|
});
|
|
1950
1959
|
if (skip) return false;
|
|
1960
|
+
const fetchUrl = withCacheTag(remoteEntryUrl, resolveCacheTag(remoteName));
|
|
1951
1961
|
try {
|
|
1952
|
-
const remoteEntry = integrity ? await ports.remoteEntryProvider.provide(
|
|
1962
|
+
const remoteEntry = integrity ? await ports.remoteEntryProvider.provide(fetchUrl, { integrity }) : await ports.remoteEntryProvider.provide(fetchUrl);
|
|
1953
1963
|
config.log.debug(
|
|
1954
1964
|
1,
|
|
1955
1965
|
`Fetched '${remoteEntry.name}' from '${remoteEntry.url}', exposing: ${JSON.stringify(remoteEntry.exposes)}`
|
|
@@ -2222,7 +2232,7 @@ function createDetermineSharedExternals(config, ports) {
|
|
|
2222
2232
|
}
|
|
2223
2233
|
}
|
|
2224
2234
|
|
|
2225
|
-
// node_modules/.pnpm/@softarc+native-federation@4.2.
|
|
2235
|
+
// node_modules/.pnpm/@softarc+native-federation@4.2.1_typescript@6.0.3/node_modules/@softarc/native-federation/dist/lib/domain/core/chunk.js
|
|
2226
2236
|
var CHUNK_PREFIX = "@nf-internal";
|
|
2227
2237
|
function toChunkImport(fileName) {
|
|
2228
2238
|
if (fileName.startsWith("./")) {
|
|
@@ -2473,9 +2483,9 @@ function createGenerateImportMap(config, ports) {
|
|
|
2473
2483
|
|
|
2474
2484
|
// src/lib/core/2.app/steps/commit-changes.ts
|
|
2475
2485
|
function createCommitChanges(config, ports) {
|
|
2476
|
-
return (importMap) => Promise.resolve(importMap).then(addToBrowser).then(persistRepositoryChanges);
|
|
2477
|
-
function addToBrowser(importMap) {
|
|
2478
|
-
ports.browser.setImportMapFn(importMap);
|
|
2486
|
+
return (importMap, opts = {}) => Promise.resolve(importMap).then((map) => addToBrowser(map, opts)).then(persistRepositoryChanges);
|
|
2487
|
+
function addToBrowser(importMap, opts) {
|
|
2488
|
+
ports.browser.setImportMapFn(importMap, opts);
|
|
2479
2489
|
config.log.debug(5, "Added import map to browser.", importMap);
|
|
2480
2490
|
return importMap;
|
|
2481
2491
|
}
|