@softarc/native-federation-orchestrator 4.4.0 → 4.5.0
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 +2 -2
- package/fesm2022/@softarc/native-federation-orchestrator.mjs +523 -82
- package/fesm2022/@softarc/native-federation-orchestrator.mjs.map +4 -4
- package/fesm2022/module-federation.mjs +21 -17
- package/fesm2022/module-federation.mjs.map +2 -2
- package/fesm2022/node.mjs +453 -76
- package/fesm2022/node.mjs.map +4 -4
- package/fesm2022/sdk.mjs +63 -1
- package/fesm2022/sdk.mjs.map +3 -3
- package/package.json +1 -1
- package/quickstart.mjs +13 -13
- package/types/lib/core/1.domain/externals/version.contract.d.ts +3 -2
- package/types/lib/core/1.domain/remote-entry/remote-entry.contract.d.ts +8 -4
- package/types/lib/core/2.app/config/mode.contract.d.ts +7 -0
- package/types/lib/core/2.app/driver-ports/init/drivers.contract.d.ts +4 -0
- package/types/lib/core/2.app/driver-ports/init/for-pooling-dynamic-externals.port.d.ts +8 -0
- package/types/lib/core/2.app/driver-ports/init/for-pooling-shared-externals.port.d.ts +1 -0
- package/types/lib/core/2.app/driver-ports/init/index.d.ts +2 -0
- package/types/lib/core/2.app/driving-ports/for-shared-externals-storage.port.d.ts +2 -0
- package/types/lib/core/2.app/steps/convert-to-import-map.d.ts +2 -1
- package/types/lib/core/2.app/steps/pooling/pool-dynamic-externals.d.ts +3 -0
- package/types/lib/core/2.app/steps/pooling/pool-graph.d.ts +25 -0
- package/types/lib/core/2.app/steps/pooling/pool-shared-externals.d.ts +5 -0
- package/types/lib/core/2.app/steps/pooling/pool.types.d.ts +25 -0
- package/types/lib/core/2.app/steps/pooling/pool.util.d.ts +4 -0
- package/types/lib/core/2.app/steps/store-remote-entry.d.ts +2 -2
- package/types/lib/core/3.adapters/http/remote-entry-provider.d.ts +2 -1
|
@@ -1283,7 +1283,7 @@ var createInitFlow = ({
|
|
|
1283
1283
|
adapters,
|
|
1284
1284
|
config
|
|
1285
1285
|
}) => {
|
|
1286
|
-
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) => ({
|
|
1286
|
+
return (remotesOrManifestUrl) => flow.getRemoteEntries(remotesOrManifestUrl).then(flow.processRemoteEntries).then(flow.determineSharedExternals).then(flow.poolSharedExternals).then(flow.generateImportMap).then((importMap) => flow.commitChanges(importMap, { override: true })).then(flow.exposeModuleLoader).then((loadRemoteModule) => ({
|
|
1287
1287
|
config,
|
|
1288
1288
|
adapters,
|
|
1289
1289
|
loadRemoteModule
|
|
@@ -1294,7 +1294,7 @@ var createInitFlow = ({
|
|
|
1294
1294
|
var createInitRemoteEntryFlow = ({
|
|
1295
1295
|
flow
|
|
1296
1296
|
}) => {
|
|
1297
|
-
const processDynamicRemoteEntry = (remoteEntry) => flow.updateCache(remoteEntry).then(flow.convertToImportMap).then(flow.commitChanges);
|
|
1297
|
+
const processDynamicRemoteEntry = (remoteEntry) => flow.updateCache(remoteEntry).then(flow.poolDynamicExternals).then(flow.convertToImportMap).then(flow.commitChanges);
|
|
1298
1298
|
return (remoteEntryUrl, remote) => flow.getRemoteEntry(remoteEntryUrl, remote).then((entry) => entry.map(processDynamicRemoteEntry).orElse(Promise.resolve())).then(() => void 0);
|
|
1299
1299
|
};
|
|
1300
1300
|
|
|
@@ -1335,16 +1335,25 @@ function createGetRemoteEntries(config, ports) {
|
|
|
1335
1335
|
};
|
|
1336
1336
|
function addHostRemoteEntry(manifest) {
|
|
1337
1337
|
if (!config.hostRemoteEntry) return manifest;
|
|
1338
|
-
const { name, url,
|
|
1339
|
-
const urlWithCache = cacheTag ? `${url}?cacheTag=${cacheTag}` : url;
|
|
1338
|
+
const { name, url, integrity } = config.hostRemoteEntry;
|
|
1340
1339
|
return {
|
|
1341
1340
|
...manifest,
|
|
1342
|
-
[name]: integrity ? { url
|
|
1341
|
+
[name]: integrity ? { url, integrity } : url
|
|
1343
1342
|
};
|
|
1344
1343
|
}
|
|
1345
1344
|
function normalizeEntry(descriptor) {
|
|
1346
1345
|
return typeof descriptor === "string" ? { url: descriptor } : descriptor;
|
|
1347
1346
|
}
|
|
1347
|
+
function withCacheTag(url, cacheTag) {
|
|
1348
|
+
if (!cacheTag) return url;
|
|
1349
|
+
return `${url}${url.includes("?") ? "&" : "?"}cacheTag=${cacheTag}`;
|
|
1350
|
+
}
|
|
1351
|
+
function resolveCacheTag(remoteName) {
|
|
1352
|
+
if (config.hostRemoteEntry && remoteName === config.hostRemoteEntry.name && config.hostRemoteEntry.cacheTag) {
|
|
1353
|
+
return config.hostRemoteEntry.cacheTag;
|
|
1354
|
+
}
|
|
1355
|
+
return config.profile.cacheTag;
|
|
1356
|
+
}
|
|
1348
1357
|
async function fetchRemoteEntries(manifest) {
|
|
1349
1358
|
const fetchPromises = Object.entries(manifest).map(
|
|
1350
1359
|
([remoteName, descriptor]) => fetchRemoteEntry(remoteName, descriptor)
|
|
@@ -1365,8 +1374,9 @@ function createGetRemoteEntries(config, ports) {
|
|
|
1365
1374
|
}
|
|
1366
1375
|
});
|
|
1367
1376
|
if (skip) return false;
|
|
1377
|
+
const fetchUrl = withCacheTag(remoteEntryUrl, resolveCacheTag(remoteName));
|
|
1368
1378
|
try {
|
|
1369
|
-
const remoteEntry = integrity ? await ports.remoteEntryProvider.provide(
|
|
1379
|
+
const remoteEntry = integrity ? await ports.remoteEntryProvider.provide(fetchUrl, { integrity }) : await ports.remoteEntryProvider.provide(fetchUrl);
|
|
1370
1380
|
config.log.debug(
|
|
1371
1381
|
1,
|
|
1372
1382
|
`Fetched '${remoteEntry.name}' from '${remoteEntry.url}', exposing: ${JSON.stringify(remoteEntry.exposes)}`
|
|
@@ -1444,6 +1454,7 @@ function createStoreRemoteEntry(config, ports, logStep) {
|
|
|
1444
1454
|
const tag = resolveVersion(remoteEntry, external);
|
|
1445
1455
|
if (tag === null) return;
|
|
1446
1456
|
if (external.singleton) {
|
|
1457
|
+
if (external.pool?.trim()) ports.sharedExternalsRepo.markPoolTagPresent();
|
|
1447
1458
|
onSharedExternal(remoteEntry, external, sharedExternalContext(remoteEntry, external, tag));
|
|
1448
1459
|
} else {
|
|
1449
1460
|
addScopedExternal(remoteEntry, external, tag);
|
|
@@ -1463,8 +1474,8 @@ function createStoreRemoteEntry(config, ports, logStep) {
|
|
|
1463
1474
|
function addScopedExternal(remoteEntry, sharedInfo, tag) {
|
|
1464
1475
|
ports.scopedExternalsRepo.addExternal(remoteEntry.name, sharedInfo.packageName, {
|
|
1465
1476
|
tag,
|
|
1466
|
-
|
|
1467
|
-
|
|
1477
|
+
bundle: sharedInfo.bundle,
|
|
1478
|
+
entries: sharedInfo.entries
|
|
1468
1479
|
});
|
|
1469
1480
|
}
|
|
1470
1481
|
function resolveVersion(remoteEntry, external) {
|
|
@@ -1486,12 +1497,13 @@ function createStoreRemoteEntry(config, ports, logStep) {
|
|
|
1486
1497
|
function sharedExternalContext(remoteEntry, sharedInfo, tag) {
|
|
1487
1498
|
const scopeType = ports.sharedExternalsRepo.scopeType(sharedInfo.shareScope);
|
|
1488
1499
|
const remote = {
|
|
1489
|
-
file: sharedInfo.outFileName,
|
|
1490
1500
|
name: remoteEntry.name,
|
|
1491
1501
|
bundle: sharedInfo.bundle,
|
|
1492
1502
|
strictVersion: sharedInfo.strictVersion,
|
|
1493
1503
|
cached: false,
|
|
1494
|
-
requiredVersion: scopeType === "strict" ? tag : sharedInfo.requiredVersion || tag
|
|
1504
|
+
requiredVersion: scopeType === "strict" ? tag : sharedInfo.requiredVersion || tag,
|
|
1505
|
+
...sharedInfo.pool?.trim() ? { pool: sharedInfo.pool } : {},
|
|
1506
|
+
entries: sharedInfo.entries
|
|
1495
1507
|
};
|
|
1496
1508
|
const cached = ports.sharedExternalsRepo.tryGet(sharedInfo.packageName, sharedInfo.shareScope).orElse({ dirty: false, versions: [] });
|
|
1497
1509
|
return {
|
|
@@ -1566,6 +1578,66 @@ function createProcessRemoteEntries(config, ports) {
|
|
|
1566
1578
|
var GLOBAL_SCOPE = "__GLOBAL__";
|
|
1567
1579
|
var STRICT_SCOPE = "strict";
|
|
1568
1580
|
|
|
1581
|
+
// src/lib/core/1.domain/remote-entry/remote-entry.contract.ts
|
|
1582
|
+
var CHUNK_PREFIX = "@nf-internal";
|
|
1583
|
+
function toDenseSharedInfoFormat(shared) {
|
|
1584
|
+
return shared.map((external) => {
|
|
1585
|
+
if ("entries" in external) return external;
|
|
1586
|
+
const { outFileName, ...baseSharedInfoProps } = external;
|
|
1587
|
+
return {
|
|
1588
|
+
...baseSharedInfoProps,
|
|
1589
|
+
entries: { [external.packageName]: outFileName }
|
|
1590
|
+
};
|
|
1591
|
+
});
|
|
1592
|
+
}
|
|
1593
|
+
function inferPackageFromSecondary(secondary) {
|
|
1594
|
+
const parts = secondary.split("/");
|
|
1595
|
+
if (secondary.startsWith("@") && parts.length >= 2) {
|
|
1596
|
+
return parts[0] + "/" + parts[1];
|
|
1597
|
+
}
|
|
1598
|
+
return parts[0] ?? secondary;
|
|
1599
|
+
}
|
|
1600
|
+
function densifyExternals(shared) {
|
|
1601
|
+
const result = [];
|
|
1602
|
+
const groupIndex = /* @__PURE__ */ new Map();
|
|
1603
|
+
for (const entry of shared) {
|
|
1604
|
+
const isDense = "entries" in entry;
|
|
1605
|
+
const isChunk = entry.packageName.startsWith(CHUNK_PREFIX + "/");
|
|
1606
|
+
if (isDense || isChunk) {
|
|
1607
|
+
result.push(entry);
|
|
1608
|
+
continue;
|
|
1609
|
+
}
|
|
1610
|
+
const parent = inferPackageFromSecondary(entry.packageName);
|
|
1611
|
+
const sig = JSON.stringify({
|
|
1612
|
+
singleton: entry.singleton,
|
|
1613
|
+
strictVersion: entry.strictVersion,
|
|
1614
|
+
requiredVersion: entry.requiredVersion,
|
|
1615
|
+
version: entry.version,
|
|
1616
|
+
shareScope: entry.shareScope
|
|
1617
|
+
});
|
|
1618
|
+
const key = parent + " " + sig;
|
|
1619
|
+
const existing = groupIndex.get(key);
|
|
1620
|
+
if (existing === void 0) {
|
|
1621
|
+
const dense = {
|
|
1622
|
+
singleton: entry.singleton,
|
|
1623
|
+
strictVersion: entry.strictVersion,
|
|
1624
|
+
requiredVersion: entry.requiredVersion,
|
|
1625
|
+
packageName: parent,
|
|
1626
|
+
entries: { [entry.packageName]: entry.outFileName }
|
|
1627
|
+
};
|
|
1628
|
+
if (entry.version !== void 0) dense.version = entry.version;
|
|
1629
|
+
if (entry.shareScope !== void 0) dense.shareScope = entry.shareScope;
|
|
1630
|
+
if (entry.bundle !== void 0) dense.bundle = entry.bundle;
|
|
1631
|
+
if (entry.dev !== void 0) dense.dev = entry.dev;
|
|
1632
|
+
groupIndex.set(key, result.length);
|
|
1633
|
+
result.push(dense);
|
|
1634
|
+
} else {
|
|
1635
|
+
result[existing].entries[entry.packageName] = entry.outFileName;
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
return result;
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1569
1641
|
// src/lib/core/2.app/steps/determine-shared-externals.ts
|
|
1570
1642
|
function createDetermineSharedExternals(config, ports) {
|
|
1571
1643
|
return () => {
|
|
@@ -1643,7 +1715,290 @@ function createDetermineSharedExternals(config, ports) {
|
|
|
1643
1715
|
}
|
|
1644
1716
|
}
|
|
1645
1717
|
|
|
1646
|
-
//
|
|
1718
|
+
// src/lib/core/2.app/steps/pooling/pool-graph.ts
|
|
1719
|
+
var SCOPED_PACKAGE = /^@([^/]+)\//;
|
|
1720
|
+
function createDSU() {
|
|
1721
|
+
const ids = /* @__PURE__ */ new Map();
|
|
1722
|
+
const parent = [];
|
|
1723
|
+
const size = [];
|
|
1724
|
+
const intern = (key) => {
|
|
1725
|
+
let id = ids.get(key);
|
|
1726
|
+
if (id === void 0) {
|
|
1727
|
+
id = parent.length;
|
|
1728
|
+
ids.set(key, id);
|
|
1729
|
+
parent.push(id);
|
|
1730
|
+
size.push(1);
|
|
1731
|
+
}
|
|
1732
|
+
return id;
|
|
1733
|
+
};
|
|
1734
|
+
const findRoot = (x) => {
|
|
1735
|
+
while (parent[x] !== x) {
|
|
1736
|
+
parent[x] = parent[parent[x]];
|
|
1737
|
+
x = parent[x];
|
|
1738
|
+
}
|
|
1739
|
+
return x;
|
|
1740
|
+
};
|
|
1741
|
+
return {
|
|
1742
|
+
union(a, b) {
|
|
1743
|
+
let rootA = findRoot(intern(a));
|
|
1744
|
+
let rootB = findRoot(intern(b));
|
|
1745
|
+
if (rootA === rootB) return;
|
|
1746
|
+
if (size[rootA] < size[rootB]) [rootA, rootB] = [rootB, rootA];
|
|
1747
|
+
parent[rootB] = rootA;
|
|
1748
|
+
size[rootA] = size[rootA] + size[rootB];
|
|
1749
|
+
},
|
|
1750
|
+
// Interns the key if unseen — an isolated key is its own component.
|
|
1751
|
+
component(key) {
|
|
1752
|
+
return findRoot(intern(key));
|
|
1753
|
+
}
|
|
1754
|
+
};
|
|
1755
|
+
}
|
|
1756
|
+
var extNode = (name) => `ext\0${name}`;
|
|
1757
|
+
var tagNode = (remote, tag) => `tag\0${remote}\0${tag}`;
|
|
1758
|
+
var scopeNode = (scope) => `scope\0${scope}`;
|
|
1759
|
+
function autoScope(name, useAutoExternalPooling) {
|
|
1760
|
+
return useAutoExternalPooling ? SCOPED_PACKAGE.exec(name)?.[1] : void 0;
|
|
1761
|
+
}
|
|
1762
|
+
function groupByMembership(candidates, log) {
|
|
1763
|
+
const dsu = createDSU();
|
|
1764
|
+
const tagged = /* @__PURE__ */ new Set();
|
|
1765
|
+
const poolable = [];
|
|
1766
|
+
for (const candidate of candidates) {
|
|
1767
|
+
let joined = false;
|
|
1768
|
+
if (candidate.scope !== void 0) {
|
|
1769
|
+
dsu.union(extNode(candidate.name), scopeNode(candidate.scope));
|
|
1770
|
+
joined = true;
|
|
1771
|
+
}
|
|
1772
|
+
for (const edge of candidate.tags) {
|
|
1773
|
+
dsu.union(extNode(candidate.name), tagNode(edge.remote, edge.tag));
|
|
1774
|
+
tagged.add(candidate.name);
|
|
1775
|
+
joined = true;
|
|
1776
|
+
}
|
|
1777
|
+
if (joined) poolable.push({ name: candidate.name, value: candidate.value });
|
|
1778
|
+
}
|
|
1779
|
+
const byComponent = /* @__PURE__ */ new Map();
|
|
1780
|
+
for (const entry of poolable) {
|
|
1781
|
+
const root = dsu.component(extNode(entry.name));
|
|
1782
|
+
(byComponent.get(root) ?? byComponent.set(root, []).get(root)).push(entry);
|
|
1783
|
+
}
|
|
1784
|
+
const pools = [];
|
|
1785
|
+
for (const members of byComponent.values()) {
|
|
1786
|
+
members.sort((a, b) => a.name.localeCompare(b.name));
|
|
1787
|
+
if (members.length < 2) {
|
|
1788
|
+
const only = members[0];
|
|
1789
|
+
if (tagged.has(only.name)) {
|
|
1790
|
+
log?.warn(
|
|
1791
|
+
3,
|
|
1792
|
+
`[${only.name}] declares a 'pool' tag but no other external joined its pool; likely a typo or a missing sibling.`
|
|
1793
|
+
);
|
|
1794
|
+
}
|
|
1795
|
+
continue;
|
|
1796
|
+
}
|
|
1797
|
+
pools.push(members);
|
|
1798
|
+
}
|
|
1799
|
+
pools.sort((a, b) => a[0].name.localeCompare(b[0].name));
|
|
1800
|
+
return new Map(pools.map((members) => [members[0].name, members.map((m) => m.value)]));
|
|
1801
|
+
}
|
|
1802
|
+
function buildPools(sharedExternals, useAutoExternalPooling, log) {
|
|
1803
|
+
const candidates = Object.entries(sharedExternals).map(
|
|
1804
|
+
([name, external]) => ({
|
|
1805
|
+
name,
|
|
1806
|
+
scope: autoScope(name, useAutoExternalPooling),
|
|
1807
|
+
tags: external.versions.flatMap(
|
|
1808
|
+
(v) => v.remotes.flatMap((r) => {
|
|
1809
|
+
const tag = r.pool?.trim();
|
|
1810
|
+
return tag ? [{ remote: r.name, tag }] : [];
|
|
1811
|
+
})
|
|
1812
|
+
),
|
|
1813
|
+
value: { name, external }
|
|
1814
|
+
})
|
|
1815
|
+
);
|
|
1816
|
+
return groupByMembership(candidates, log);
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
// src/lib/core/2.app/steps/pooling/pool.util.ts
|
|
1820
|
+
function versionForRemote(member, remote) {
|
|
1821
|
+
return member.external.versions.find((v) => v.remotes.some((r) => r.name === remote));
|
|
1822
|
+
}
|
|
1823
|
+
function remotesInPool(members) {
|
|
1824
|
+
return [
|
|
1825
|
+
...new Set(members.flatMap((m) => m.external.versions.flatMap((v) => v.remotes.map((r) => r.name))))
|
|
1826
|
+
];
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
// src/lib/core/2.app/steps/pooling/pool-shared-externals.ts
|
|
1830
|
+
function poolWinners(members) {
|
|
1831
|
+
return members.map((member) => {
|
|
1832
|
+
const share = member.external.versions.find((v) => v.action === "share");
|
|
1833
|
+
return {
|
|
1834
|
+
member,
|
|
1835
|
+
tag: share?.tag ?? "",
|
|
1836
|
+
providers: new Set((share?.remotes ?? []).map((r) => r.name))
|
|
1837
|
+
};
|
|
1838
|
+
});
|
|
1839
|
+
}
|
|
1840
|
+
function selectCoverageAnchor(winners) {
|
|
1841
|
+
const coverage = /* @__PURE__ */ new Map();
|
|
1842
|
+
for (const winner of winners)
|
|
1843
|
+
for (const remote of winner.providers) coverage.set(remote, (coverage.get(remote) ?? 0) + 1);
|
|
1844
|
+
if (coverage.size === 0) return void 0;
|
|
1845
|
+
const anchorRemote = [...coverage.keys()].sort(
|
|
1846
|
+
(a, b) => coverage.get(b) - coverage.get(a) || a.localeCompare(b)
|
|
1847
|
+
)[0];
|
|
1848
|
+
return {
|
|
1849
|
+
anchorRemote,
|
|
1850
|
+
tagPerMember: Object.fromEntries(
|
|
1851
|
+
winners.filter((w) => w.providers.has(anchorRemote)).map((w) => [w.member.name, w.tag])
|
|
1852
|
+
)
|
|
1853
|
+
};
|
|
1854
|
+
}
|
|
1855
|
+
function classifyPoolConservative(members, anchor) {
|
|
1856
|
+
const classification = /* @__PURE__ */ new Map();
|
|
1857
|
+
for (const remote of remotesInPool(members)) {
|
|
1858
|
+
let coverageForced = false;
|
|
1859
|
+
let verdict = "follow";
|
|
1860
|
+
for (const member of members) {
|
|
1861
|
+
const version = versionForRemote(member, remote);
|
|
1862
|
+
if (!version) continue;
|
|
1863
|
+
const anchorTag = anchor.tagPerMember[member.name];
|
|
1864
|
+
if (!anchorTag) {
|
|
1865
|
+
coverageForced = true;
|
|
1866
|
+
continue;
|
|
1867
|
+
}
|
|
1868
|
+
if (version.tag === anchorTag) continue;
|
|
1869
|
+
if (version.action === "scope") {
|
|
1870
|
+
verdict = "scope-incompat";
|
|
1871
|
+
break;
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
classification.set(
|
|
1875
|
+
remote,
|
|
1876
|
+
verdict === "scope-incompat" ? "scope-incompat" : coverageForced ? "scope-coverage" : "follow"
|
|
1877
|
+
);
|
|
1878
|
+
}
|
|
1879
|
+
classification.set(anchor.anchorRemote, "follow");
|
|
1880
|
+
return classification;
|
|
1881
|
+
}
|
|
1882
|
+
function createPoolSharedExternals(config, ports) {
|
|
1883
|
+
return () => {
|
|
1884
|
+
const { useAutoExternalPooling } = config.feature;
|
|
1885
|
+
if (!useAutoExternalPooling && !ports.sharedExternalsRepo.hasPoolTag()) {
|
|
1886
|
+
return Promise.resolve();
|
|
1887
|
+
}
|
|
1888
|
+
for (const scope of ports.sharedExternalsRepo.getScopes()) {
|
|
1889
|
+
if (ports.sharedExternalsRepo.scopeType(scope) === "strict") continue;
|
|
1890
|
+
const sharedExternals = ports.sharedExternalsRepo.getFromScope(scope);
|
|
1891
|
+
try {
|
|
1892
|
+
for (const [poolName, members] of buildPools(
|
|
1893
|
+
sharedExternals,
|
|
1894
|
+
useAutoExternalPooling,
|
|
1895
|
+
config.log
|
|
1896
|
+
)) {
|
|
1897
|
+
poolFamily(poolName, members, scope);
|
|
1898
|
+
}
|
|
1899
|
+
} catch (error) {
|
|
1900
|
+
if (error instanceof NFError) return Promise.reject(error);
|
|
1901
|
+
config.log.error(3, `[${scope}] failed to pool shared externals.`, {
|
|
1902
|
+
sharedExternals,
|
|
1903
|
+
error
|
|
1904
|
+
});
|
|
1905
|
+
return Promise.reject(
|
|
1906
|
+
new NFError(`Could not pool shared externals in scope ${scope}.`, error)
|
|
1907
|
+
);
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
return Promise.resolve();
|
|
1911
|
+
};
|
|
1912
|
+
function poolFamily(poolName, members, scope) {
|
|
1913
|
+
if (members.length < 2) return;
|
|
1914
|
+
const allRemotes = remotesInPool(members);
|
|
1915
|
+
if (allRemotes.length < 2) return;
|
|
1916
|
+
const anchor = selectCoverageAnchor(poolWinners(members));
|
|
1917
|
+
if (!anchor) return;
|
|
1918
|
+
const classification = classifyPoolConservative(members, anchor);
|
|
1919
|
+
config.log.debug(
|
|
1920
|
+
3,
|
|
1921
|
+
`[${scope}][pool:${poolName}] members=[${members.map((m) => m.name).join(", ")}], anchor=${anchor.anchorRemote}, remotes={${allRemotes.map((r) => `${r}:${classification.get(r)}`).join(", ")}}`
|
|
1922
|
+
);
|
|
1923
|
+
const incompatForced = allRemotes.some((r) => classification.get(r) === "scope-incompat");
|
|
1924
|
+
if (incompatForced && config.strict.strictExternalCompatibility) {
|
|
1925
|
+
config.log.error(
|
|
1926
|
+
3,
|
|
1927
|
+
`[${scope}][pool:${poolName}] A remote is version-incompatible with anchor '${anchor.anchorRemote}'.`
|
|
1928
|
+
);
|
|
1929
|
+
throw new NFError(`Could not pool '${poolName}' in scope ${scope}.`);
|
|
1930
|
+
}
|
|
1931
|
+
for (const member of members) {
|
|
1932
|
+
const rebuilt = rebuildMember(member, anchor, classification);
|
|
1933
|
+
warnIfScopedOnly(poolName, member.name, rebuilt, scope);
|
|
1934
|
+
ports.sharedExternalsRepo.addOrUpdate(member.name, rebuilt, scope);
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
function warnIfScopedOnly(poolName, memberName, rebuilt, scope) {
|
|
1938
|
+
if (rebuilt.versions.some((v) => v.action === "share")) return;
|
|
1939
|
+
const copies = rebuilt.versions.reduce((n, v) => n + v.remotes.length, 0);
|
|
1940
|
+
config.log.warn(
|
|
1941
|
+
3,
|
|
1942
|
+
`[${scope}][pool:${poolName}] '${memberName}' is scoped-only \u2014 no coherent shared build provides it; ${copies} remotes download their own copy.`
|
|
1943
|
+
);
|
|
1944
|
+
}
|
|
1945
|
+
function rebuildMember(member, anchor, classification) {
|
|
1946
|
+
const anchorTag = anchor.tagPerMember[member.name];
|
|
1947
|
+
const entries = member.external.versions.flatMap(
|
|
1948
|
+
(v) => v.remotes.map((meta) => ({ remote: meta.name, tag: v.tag, host: v.host, meta }))
|
|
1949
|
+
);
|
|
1950
|
+
if (!anchorTag) {
|
|
1951
|
+
return {
|
|
1952
|
+
dirty: false,
|
|
1953
|
+
versions: entries.length > 0 ? [
|
|
1954
|
+
{
|
|
1955
|
+
tag: entries[0].tag,
|
|
1956
|
+
host: false,
|
|
1957
|
+
action: "scope",
|
|
1958
|
+
remotes: entries.map((e) => e.meta)
|
|
1959
|
+
}
|
|
1960
|
+
] : []
|
|
1961
|
+
};
|
|
1962
|
+
}
|
|
1963
|
+
const anchorMeta = entries.find(
|
|
1964
|
+
(e) => e.remote === anchor.anchorRemote && e.tag === anchorTag
|
|
1965
|
+
).meta;
|
|
1966
|
+
const anchorHost = member.external.versions.find((v) => v.tag === anchorTag)?.host ?? false;
|
|
1967
|
+
const scopes = (e) => {
|
|
1968
|
+
const cls = classification.get(e.remote);
|
|
1969
|
+
return cls === "scope-incompat" || cls === "scope-coverage" && e.tag !== anchorTag;
|
|
1970
|
+
};
|
|
1971
|
+
const shareOnAnchor = entries.filter(
|
|
1972
|
+
(e) => e.remote !== anchor.anchorRemote && e.tag === anchorTag && !scopes(e)
|
|
1973
|
+
);
|
|
1974
|
+
const shareVersion = {
|
|
1975
|
+
tag: anchorTag,
|
|
1976
|
+
host: anchorHost,
|
|
1977
|
+
action: "share",
|
|
1978
|
+
remotes: [anchorMeta, ...shareOnAnchor.map((e) => e.meta)]
|
|
1979
|
+
};
|
|
1980
|
+
const skipByTag = /* @__PURE__ */ new Map();
|
|
1981
|
+
for (const e of entries) {
|
|
1982
|
+
if (e.tag === anchorTag || scopes(e)) continue;
|
|
1983
|
+
const version = skipByTag.get(e.tag) ?? {
|
|
1984
|
+
tag: e.tag,
|
|
1985
|
+
host: e.host,
|
|
1986
|
+
action: "skip",
|
|
1987
|
+
remotes: []
|
|
1988
|
+
};
|
|
1989
|
+
version.remotes.push(e.meta);
|
|
1990
|
+
skipByTag.set(e.tag, version);
|
|
1991
|
+
}
|
|
1992
|
+
const scoped = entries.filter((e) => scopes(e));
|
|
1993
|
+
const scopeVersion = scoped.length > 0 ? [{ tag: anchorTag, host: false, action: "scope", remotes: scoped.map((e) => e.meta) }] : [];
|
|
1994
|
+
return {
|
|
1995
|
+
dirty: false,
|
|
1996
|
+
versions: [shareVersion, ...skipByTag.values(), ...scopeVersion]
|
|
1997
|
+
};
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
// node_modules/.pnpm/@softarc+native-federation@4.3.0_typescript@6.0.3/node_modules/@softarc/native-federation/dist/lib/domain/core/build-notification-options.contract.js
|
|
1647
2002
|
var BuildNotificationType = /* @__PURE__ */ ((BuildNotificationType2) => {
|
|
1648
2003
|
BuildNotificationType2["COMPLETED"] = "federation-rebuild-complete";
|
|
1649
2004
|
BuildNotificationType2["ERROR"] = "federation-rebuild-error";
|
|
@@ -1651,14 +2006,14 @@ var BuildNotificationType = /* @__PURE__ */ ((BuildNotificationType2) => {
|
|
|
1651
2006
|
return BuildNotificationType2;
|
|
1652
2007
|
})(BuildNotificationType || {});
|
|
1653
2008
|
|
|
1654
|
-
// node_modules/.pnpm/@softarc+native-federation@4.
|
|
1655
|
-
var
|
|
2009
|
+
// node_modules/.pnpm/@softarc+native-federation@4.3.0_typescript@6.0.3/node_modules/@softarc/native-federation/dist/lib/domain/core/chunk.js
|
|
2010
|
+
var CHUNK_PREFIX2 = "@nf-internal";
|
|
1656
2011
|
function toChunkImport(fileName) {
|
|
1657
2012
|
if (fileName.startsWith("./")) {
|
|
1658
2013
|
fileName = fileName.slice(2);
|
|
1659
2014
|
}
|
|
1660
2015
|
const packageName = fileName.replace(/.(m|c)?js$/, "");
|
|
1661
|
-
return
|
|
2016
|
+
return CHUNK_PREFIX2 + "/" + packageName;
|
|
1662
2017
|
}
|
|
1663
2018
|
|
|
1664
2019
|
// src/lib/core/2.app/steps/generate-import-map.ts
|
|
@@ -1686,12 +2041,9 @@ function createGenerateImportMap(config, ports) {
|
|
|
1686
2041
|
});
|
|
1687
2042
|
addToScope(importMap, remote.scopeUrl, createScopeModules(externals, remote.scopeUrl));
|
|
1688
2043
|
for (const version of Object.values(externals)) {
|
|
1689
|
-
|
|
1690
|
-
importMap,
|
|
1691
|
-
|
|
1692
|
-
remoteName,
|
|
1693
|
-
version.file
|
|
1694
|
-
);
|
|
2044
|
+
for (const file of Object.values(version.entries)) {
|
|
2045
|
+
addIntegrity(importMap, join(remote.scopeUrl, file), remoteName, file);
|
|
2046
|
+
}
|
|
1695
2047
|
}
|
|
1696
2048
|
Object.values(externals).filter((e) => !!e.bundle).forEach((e) => registerBundleChunks(chunkBundles, remoteName, e.bundle));
|
|
1697
2049
|
}
|
|
@@ -1699,8 +2051,10 @@ function createGenerateImportMap(config, ports) {
|
|
|
1699
2051
|
}
|
|
1700
2052
|
function createScopeModules(externals, scope) {
|
|
1701
2053
|
const modules = {};
|
|
1702
|
-
for (const
|
|
1703
|
-
|
|
2054
|
+
for (const version of Object.values(externals)) {
|
|
2055
|
+
for (const [packageName, file] of Object.entries(version.entries)) {
|
|
2056
|
+
modules[packageName] = join(scope, file);
|
|
2057
|
+
}
|
|
1704
2058
|
}
|
|
1705
2059
|
return modules;
|
|
1706
2060
|
}
|
|
@@ -1720,47 +2074,49 @@ function createGenerateImportMap(config, ports) {
|
|
|
1720
2074
|
if (version.action === "scope") {
|
|
1721
2075
|
for (const remote of version.remotes) {
|
|
1722
2076
|
const remoteScope = getScope2(shareScope, remote.name, externalName);
|
|
1723
|
-
const
|
|
1724
|
-
|
|
1725
|
-
[
|
|
1726
|
-
|
|
1727
|
-
|
|
2077
|
+
for (const [packageName, file] of Object.entries(remote.entries)) {
|
|
2078
|
+
const url = join(remoteScope, file);
|
|
2079
|
+
addToScope(importMap, remoteScope, { [packageName]: url });
|
|
2080
|
+
addIntegrity(importMap, url, remote.name, file);
|
|
2081
|
+
}
|
|
1728
2082
|
registerBundleChunks(chunkBundles, remote.name, remote.bundle);
|
|
1729
2083
|
remote.cached = true;
|
|
1730
2084
|
}
|
|
1731
2085
|
continue;
|
|
1732
2086
|
}
|
|
1733
|
-
const scope = getScope2(shareScope, version.remotes[0].name, externalName);
|
|
1734
|
-
let targetFileUrl = join(scope, version.remotes[0].file);
|
|
1735
|
-
let targetFileSource = {
|
|
1736
|
-
name: version.remotes[0].name,
|
|
1737
|
-
file: version.remotes[0].file
|
|
1738
|
-
};
|
|
1739
2087
|
version.remotes[0].cached = true;
|
|
2088
|
+
let source = version.remotes[0];
|
|
2089
|
+
let sourceScope = getScope2(shareScope, source.name, externalName);
|
|
1740
2090
|
if (version.action === "share") {
|
|
1741
|
-
registerBundleChunks(chunkBundles,
|
|
1742
|
-
}
|
|
1743
|
-
if (version.action === "skip") {
|
|
2091
|
+
registerBundleChunks(chunkBundles, source.name, source.bundle);
|
|
2092
|
+
} else if (version.action === "skip") {
|
|
1744
2093
|
if (!override) {
|
|
1745
2094
|
override = findOverride(external, shareScope, externalName) ?? "NOT_AVAILABLE";
|
|
1746
2095
|
}
|
|
1747
2096
|
if (override !== "NOT_AVAILABLE") {
|
|
1748
2097
|
if (!overrideScope)
|
|
1749
2098
|
overrideScope = getScope2(shareScope, override.remotes[0].name, externalName);
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
name: override.remotes[0].name,
|
|
1753
|
-
file: override.remotes[0].file
|
|
1754
|
-
};
|
|
2099
|
+
source = override.remotes[0];
|
|
2100
|
+
sourceScope = overrideScope;
|
|
1755
2101
|
override.remotes[0].cached = true;
|
|
1756
2102
|
version.remotes[0].cached = false;
|
|
1757
2103
|
}
|
|
1758
2104
|
}
|
|
2105
|
+
const mappings = Object.entries(source.entries).map(([packageName, file]) => ({
|
|
2106
|
+
packageName,
|
|
2107
|
+
url: join(sourceScope, file),
|
|
2108
|
+
name: source.name,
|
|
2109
|
+
file
|
|
2110
|
+
}));
|
|
1759
2111
|
version.remotes.forEach((r) => {
|
|
1760
|
-
const
|
|
1761
|
-
|
|
2112
|
+
const rScope = getScope2(shareScope, r.name, externalName);
|
|
2113
|
+
for (const m of mappings) {
|
|
2114
|
+
addToScope(importMap, rScope, { [m.packageName]: m.url });
|
|
2115
|
+
}
|
|
1762
2116
|
});
|
|
1763
|
-
|
|
2117
|
+
for (const m of mappings) {
|
|
2118
|
+
addIntegrity(importMap, m.url, m.name, m.file);
|
|
2119
|
+
}
|
|
1764
2120
|
}
|
|
1765
2121
|
ports.sharedExternalsRepo.addOrUpdate(externalName, external, shareScope);
|
|
1766
2122
|
}
|
|
@@ -1801,11 +2157,11 @@ function createGenerateImportMap(config, ports) {
|
|
|
1801
2157
|
if (version.action === "scope") {
|
|
1802
2158
|
for (const remote of version.remotes) {
|
|
1803
2159
|
const remoteScope = getScope2(GLOBAL_SCOPE, remote.name, externalName);
|
|
1804
|
-
const
|
|
1805
|
-
|
|
1806
|
-
[
|
|
1807
|
-
|
|
1808
|
-
|
|
2160
|
+
for (const [packageName, file] of Object.entries(remote.entries)) {
|
|
2161
|
+
const url = join(remoteScope, file);
|
|
2162
|
+
addToScope(importMap, remoteScope, { [packageName]: url });
|
|
2163
|
+
addIntegrity(importMap, url, remote.name, file);
|
|
2164
|
+
}
|
|
1809
2165
|
remote.cached = true;
|
|
1810
2166
|
registerBundleChunks(chunkBundles, remote.name, remote.bundle);
|
|
1811
2167
|
}
|
|
@@ -1816,9 +2172,11 @@ function createGenerateImportMap(config, ports) {
|
|
|
1816
2172
|
continue;
|
|
1817
2173
|
}
|
|
1818
2174
|
const scope = getScope2(GLOBAL_SCOPE, version.remotes[0].name, externalName);
|
|
1819
|
-
const
|
|
1820
|
-
|
|
1821
|
-
|
|
2175
|
+
for (const [packageName, file] of Object.entries(version.remotes[0].entries)) {
|
|
2176
|
+
const url = join(scope, file);
|
|
2177
|
+
addToGlobal(importMap, { [packageName]: url });
|
|
2178
|
+
addIntegrity(importMap, url, version.remotes[0].name, file);
|
|
2179
|
+
}
|
|
1822
2180
|
registerBundleChunks(chunkBundles, version.remotes[0].name, version.remotes[0].bundle);
|
|
1823
2181
|
version.remotes[0].cached = true;
|
|
1824
2182
|
}
|
|
@@ -2054,8 +2412,8 @@ function createUpdateCache(config, ports) {
|
|
|
2054
2412
|
storeRemoteEntry(remoteEntry, (entry, external, ctx) => {
|
|
2055
2413
|
const { action, sharedVersion } = resolveSharedExternal(entry, external, ctx);
|
|
2056
2414
|
actions[external.packageName] = { action };
|
|
2057
|
-
if (action === "skip" && external.shareScope && sharedVersion?.remotes[0]?.
|
|
2058
|
-
actions[external.packageName].override =
|
|
2415
|
+
if (action === "skip" && external.shareScope && sharedVersion?.remotes[0]?.entries) {
|
|
2416
|
+
actions[external.packageName].override = resolveOverrideEntries(
|
|
2059
2417
|
entry,
|
|
2060
2418
|
external,
|
|
2061
2419
|
sharedVersion
|
|
@@ -2099,8 +2457,15 @@ function createUpdateCache(config, ports) {
|
|
|
2099
2457
|
commit();
|
|
2100
2458
|
return { action, sharedVersion };
|
|
2101
2459
|
}
|
|
2102
|
-
function
|
|
2103
|
-
return ports.remoteInfoRepo.tryGet(sharedVersion.remotes[0].name).map(
|
|
2460
|
+
function resolveOverrideEntries(remoteEntry, external, sharedVersion) {
|
|
2461
|
+
return ports.remoteInfoRepo.tryGet(sharedVersion.remotes[0].name).map(
|
|
2462
|
+
(remote) => Object.fromEntries(
|
|
2463
|
+
Object.entries(sharedVersion.remotes[0].entries).map(([packageName, file]) => [
|
|
2464
|
+
packageName,
|
|
2465
|
+
join(remote.scopeUrl, file)
|
|
2466
|
+
])
|
|
2467
|
+
)
|
|
2468
|
+
).orThrow(() => {
|
|
2104
2469
|
config.log.error(
|
|
2105
2470
|
8,
|
|
2106
2471
|
`[${external.shareScope ?? GLOBAL_SCOPE}][${remoteEntry.name}][${external.packageName}@${external.version}][override] Remote name not found in cache.`
|
|
@@ -2112,14 +2477,56 @@ function createUpdateCache(config, ports) {
|
|
|
2112
2477
|
}
|
|
2113
2478
|
}
|
|
2114
2479
|
|
|
2115
|
-
// src/lib/core/2.app/steps/
|
|
2116
|
-
function
|
|
2480
|
+
// src/lib/core/2.app/steps/pooling/pool-dynamic-externals.ts
|
|
2481
|
+
function createPoolDynamicExternals(config) {
|
|
2117
2482
|
return ({ entry, actions }) => {
|
|
2483
|
+
const { useAutoExternalPooling } = config.feature;
|
|
2484
|
+
if (!useAutoExternalPooling && !(entry.shared ?? []).some((e) => e.pool?.trim())) {
|
|
2485
|
+
return Promise.resolve({ entry, actions });
|
|
2486
|
+
}
|
|
2487
|
+
const byScope = /* @__PURE__ */ new Map();
|
|
2488
|
+
for (const external of entry.shared ?? []) {
|
|
2489
|
+
const name = external.packageName;
|
|
2490
|
+
if (!external.singleton || !actions[name]) continue;
|
|
2491
|
+
if (external.shareScope === STRICT_SCOPE) continue;
|
|
2492
|
+
const tag = external.pool?.trim();
|
|
2493
|
+
const shareScope = external.shareScope ?? GLOBAL_SCOPE;
|
|
2494
|
+
const candidates = byScope.get(shareScope) ?? [];
|
|
2495
|
+
candidates.push({
|
|
2496
|
+
name,
|
|
2497
|
+
scope: autoScope(name, useAutoExternalPooling),
|
|
2498
|
+
tags: tag ? [{ remote: entry.name, tag }] : [],
|
|
2499
|
+
value: name
|
|
2500
|
+
});
|
|
2501
|
+
byScope.set(shareScope, candidates);
|
|
2502
|
+
}
|
|
2503
|
+
const scope = (name) => {
|
|
2504
|
+
actions[name].action = "scope";
|
|
2505
|
+
delete actions[name].override;
|
|
2506
|
+
};
|
|
2507
|
+
for (const candidates of byScope.values()) {
|
|
2508
|
+
for (const members of groupByMembership(candidates).values()) {
|
|
2509
|
+
const memberActions = members.map((name) => actions[name].action);
|
|
2510
|
+
if (memberActions.includes("scope")) {
|
|
2511
|
+
members.forEach(scope);
|
|
2512
|
+
} else if (memberActions.includes("share") && memberActions.includes("skip")) {
|
|
2513
|
+
members.filter((name) => actions[name].action === "share").forEach(scope);
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
return Promise.resolve({ entry, actions });
|
|
2518
|
+
};
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
// src/lib/core/2.app/steps/convert-to-import-map.ts
|
|
2522
|
+
function createConvertToImportMap(config, ports) {
|
|
2523
|
+
const { log } = config;
|
|
2524
|
+
return async ({ entry, actions }) => {
|
|
2118
2525
|
const importMap = { imports: {} };
|
|
2119
2526
|
addExternals(entry, actions, importMap);
|
|
2120
2527
|
addRemoteInfos(entry, importMap);
|
|
2121
2528
|
log.debug(9, `[${entry.name}] Processed actions:`, actions);
|
|
2122
|
-
return
|
|
2529
|
+
return importMap;
|
|
2123
2530
|
};
|
|
2124
2531
|
function addExternals(remoteEntry, actions, importMap) {
|
|
2125
2532
|
if (!remoteEntry.shared) {
|
|
@@ -2130,9 +2537,11 @@ function createConvertToImportMap({ log }, ports) {
|
|
|
2130
2537
|
const chunkBundles = /* @__PURE__ */ new Set(["mapping-or-exposed"]);
|
|
2131
2538
|
remoteEntry.shared.forEach((external) => {
|
|
2132
2539
|
if (!external.singleton) {
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2540
|
+
Object.entries(external.entries).forEach(([packageName, fileName]) => {
|
|
2541
|
+
const url = join(remoteEntryScope, fileName);
|
|
2542
|
+
addToScopes(remoteEntryScope, packageName, url, importMap);
|
|
2543
|
+
addIntegrity(importMap, url, integrityMap, fileName);
|
|
2544
|
+
});
|
|
2136
2545
|
if (external?.bundle) chunkBundles.add(external?.bundle);
|
|
2137
2546
|
return;
|
|
2138
2547
|
}
|
|
@@ -2144,33 +2553,48 @@ function createConvertToImportMap({ log }, ports) {
|
|
|
2144
2553
|
return;
|
|
2145
2554
|
}
|
|
2146
2555
|
if (actions[external.packageName].action === "skip") {
|
|
2556
|
+
const override = actions[external.packageName].override;
|
|
2147
2557
|
if (!external.shareScope) return;
|
|
2148
|
-
if (
|
|
2149
|
-
|
|
2150
|
-
remoteEntryScope,
|
|
2151
|
-
|
|
2152
|
-
actions[external.packageName].override,
|
|
2153
|
-
importMap
|
|
2154
|
-
);
|
|
2558
|
+
if (override) {
|
|
2559
|
+
Object.entries(override).forEach(([packageName, url]) => {
|
|
2560
|
+
addToScopes(remoteEntryScope, packageName, url, importMap);
|
|
2561
|
+
});
|
|
2155
2562
|
return;
|
|
2156
2563
|
}
|
|
2564
|
+
log.error(
|
|
2565
|
+
9,
|
|
2566
|
+
`[${remoteEntry.name}][${external.packageName}] shareScope skip has no override.`
|
|
2567
|
+
);
|
|
2568
|
+
if (config.strict.strictImportMap) throw new NFError("Could not create ImportMap.");
|
|
2569
|
+
Object.entries(external.entries).forEach(([packageName, fileName]) => {
|
|
2570
|
+
const url = join(remoteEntryScope, fileName);
|
|
2571
|
+
addToScopes(remoteEntryScope, packageName, url, importMap);
|
|
2572
|
+
addIntegrity(importMap, url, integrityMap, fileName);
|
|
2573
|
+
});
|
|
2574
|
+
return;
|
|
2157
2575
|
}
|
|
2158
2576
|
if (external?.bundle) chunkBundles.add(external?.bundle);
|
|
2159
2577
|
if (actions[external.packageName].action === "scope") {
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2578
|
+
Object.entries(external.entries).forEach(([packageName, fileName]) => {
|
|
2579
|
+
const url = join(remoteEntryScope, fileName);
|
|
2580
|
+
addToScopes(remoteEntryScope, packageName, url, importMap);
|
|
2581
|
+
addIntegrity(importMap, url, integrityMap, fileName);
|
|
2582
|
+
});
|
|
2163
2583
|
return;
|
|
2164
2584
|
}
|
|
2165
2585
|
if (external.shareScope) {
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2586
|
+
Object.entries(external.entries).forEach(([packageName, fileName]) => {
|
|
2587
|
+
const url = join(remoteEntryScope, fileName);
|
|
2588
|
+
addToScopes(remoteEntryScope, packageName, url, importMap);
|
|
2589
|
+
addIntegrity(importMap, url, integrityMap, fileName);
|
|
2590
|
+
});
|
|
2169
2591
|
return;
|
|
2170
2592
|
}
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2593
|
+
Object.entries(external.entries).forEach(([packageName, fileName]) => {
|
|
2594
|
+
const url = join(remoteEntryScope, fileName);
|
|
2595
|
+
importMap.imports[packageName] = url;
|
|
2596
|
+
addIntegrity(importMap, url, integrityMap, fileName);
|
|
2597
|
+
});
|
|
2174
2598
|
});
|
|
2175
2599
|
addChunkImports(importMap, remoteEntry, remoteEntryScope, chunkBundles);
|
|
2176
2600
|
}
|
|
@@ -2217,11 +2641,13 @@ var createInitDrivers = ({
|
|
|
2217
2641
|
getRemoteEntries: createGetRemoteEntries(config, adapters),
|
|
2218
2642
|
processRemoteEntries: createProcessRemoteEntries(config, adapters),
|
|
2219
2643
|
determineSharedExternals: createDetermineSharedExternals(config, adapters),
|
|
2644
|
+
poolSharedExternals: createPoolSharedExternals(config, adapters),
|
|
2220
2645
|
generateImportMap: createGenerateImportMap(config, adapters),
|
|
2221
2646
|
commitChanges: createCommitChanges(config, adapters),
|
|
2222
2647
|
exposeModuleLoader: createExposeModuleLoader(config, adapters),
|
|
2223
2648
|
getRemoteEntry: createGetRemoteEntry(config, adapters),
|
|
2224
2649
|
updateCache: createUpdateCache(config, adapters),
|
|
2650
|
+
poolDynamicExternals: createPoolDynamicExternals(config),
|
|
2225
2651
|
convertToImportMap: createConvertToImportMap(config, adapters)
|
|
2226
2652
|
});
|
|
2227
2653
|
var INIT_FLOW_FACTORY = ({
|
|
@@ -2333,7 +2759,7 @@ var createManifestProvider = () => {
|
|
|
2333
2759
|
};
|
|
2334
2760
|
|
|
2335
2761
|
// src/lib/core/3.adapters/http/remote-entry-provider.ts
|
|
2336
|
-
var createRemoteEntryProvider = () => {
|
|
2762
|
+
var createRemoteEntryProvider = (config) => {
|
|
2337
2763
|
const ensureOk = (response) => {
|
|
2338
2764
|
if (!response.ok)
|
|
2339
2765
|
return Promise.reject(new Error(`${response.status} - ${response.statusText}`));
|
|
@@ -2345,6 +2771,10 @@ var createRemoteEntryProvider = () => {
|
|
|
2345
2771
|
if (!remoteEntry.url) remoteEntry.url = remoteEntryUrl;
|
|
2346
2772
|
return remoteEntry;
|
|
2347
2773
|
};
|
|
2774
|
+
const normalizeRemoteEntry = (raw) => {
|
|
2775
|
+
const shared = config.feature.convertFlatSharedInfo ? densifyExternals(raw.shared ?? []) : toDenseSharedInfoFormat(raw.shared ?? []);
|
|
2776
|
+
return { ...raw, shared };
|
|
2777
|
+
};
|
|
2348
2778
|
const formatError = (remoteEntryUrl) => (err) => {
|
|
2349
2779
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2350
2780
|
throw new NFError(`Fetch of '${remoteEntryUrl}' returned ${msg}`);
|
|
@@ -2357,7 +2787,7 @@ var createRemoteEntryProvider = () => {
|
|
|
2357
2787
|
await verifyIntegrity(bytes, opts.integrity);
|
|
2358
2788
|
return JSON.parse(new TextDecoder().decode(bytes));
|
|
2359
2789
|
};
|
|
2360
|
-
return fetch(remoteEntryUrl).then(ensureOk).then(parse).then(fillEmptyFields(remoteEntryUrl)).catch(formatError(remoteEntryUrl));
|
|
2790
|
+
return fetch(remoteEntryUrl).then(ensureOk).then(parse).then(normalizeRemoteEntry).then(fillEmptyFields(remoteEntryUrl)).catch(formatError(remoteEntryUrl));
|
|
2361
2791
|
}
|
|
2362
2792
|
};
|
|
2363
2793
|
};
|
|
@@ -2433,7 +2863,14 @@ var createSharedExternalsRepository = (config) => {
|
|
|
2433
2863
|
);
|
|
2434
2864
|
if (config.clearStorage) STORAGE.clear();
|
|
2435
2865
|
const _cache = STORAGE.get();
|
|
2866
|
+
let _sawPoolTag = false;
|
|
2436
2867
|
return {
|
|
2868
|
+
markPoolTagPresent: function() {
|
|
2869
|
+
_sawPoolTag = true;
|
|
2870
|
+
},
|
|
2871
|
+
hasPoolTag: function() {
|
|
2872
|
+
return _sawPoolTag;
|
|
2873
|
+
},
|
|
2437
2874
|
getFromScope: function(shareScope) {
|
|
2438
2875
|
return { ..._cache[shareScope ?? GLOBAL_SCOPE] };
|
|
2439
2876
|
},
|
|
@@ -2543,7 +2980,7 @@ var createDriving = (config) => {
|
|
|
2543
2980
|
const adapters = {
|
|
2544
2981
|
versionCheck: createVersionCheck(),
|
|
2545
2982
|
manifestProvider: createManifestProvider(),
|
|
2546
|
-
remoteEntryProvider: createRemoteEntryProvider(),
|
|
2983
|
+
remoteEntryProvider: createRemoteEntryProvider(config),
|
|
2547
2984
|
remoteInfoRepo: createRemoteInfoRepository(config),
|
|
2548
2985
|
scopedExternalsRepo: createScopedExternalsRepository(config),
|
|
2549
2986
|
sharedExternalsRepo: createSharedExternalsRepository(config),
|
|
@@ -2786,7 +3223,11 @@ var createModeConfig = (override) => {
|
|
|
2786
3223
|
};
|
|
2787
3224
|
return {
|
|
2788
3225
|
strict: strictnessConfig,
|
|
2789
|
-
profile: { ...defaultProfile, ...override.profile ?? {} }
|
|
3226
|
+
profile: { ...defaultProfile, ...override.profile ?? {} },
|
|
3227
|
+
feature: {
|
|
3228
|
+
convertFlatSharedInfo: override.feature?.convertFlatSharedInfo ?? false,
|
|
3229
|
+
useAutoExternalPooling: override.feature?.useAutoExternalPooling ?? false
|
|
3230
|
+
}
|
|
2790
3231
|
};
|
|
2791
3232
|
};
|
|
2792
3233
|
|