@softarc/native-federation-orchestrator 4.4.1 → 4.5.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.
Files changed (25) hide show
  1. package/README.md +2 -2
  2. package/fesm2022/@softarc/native-federation-orchestrator.mjs +517 -76
  3. package/fesm2022/@softarc/native-federation-orchestrator.mjs.map +4 -4
  4. package/fesm2022/module-federation.mjs +21 -17
  5. package/fesm2022/module-federation.mjs.map +2 -2
  6. package/fesm2022/node.mjs +439 -72
  7. package/fesm2022/node.mjs.map +4 -4
  8. package/package.json +1 -1
  9. package/quickstart.mjs +13 -13
  10. package/types/lib/core/1.domain/externals/version.contract.d.ts +3 -2
  11. package/types/lib/core/1.domain/remote-entry/remote-entry.contract.d.ts +6 -4
  12. package/types/lib/core/2.app/config/mode.contract.d.ts +6 -0
  13. package/types/lib/core/2.app/driver-ports/init/drivers.contract.d.ts +4 -0
  14. package/types/lib/core/2.app/driver-ports/init/for-pooling-dynamic-externals.port.d.ts +8 -0
  15. package/types/lib/core/2.app/driver-ports/init/for-pooling-shared-externals.port.d.ts +1 -0
  16. package/types/lib/core/2.app/driver-ports/init/index.d.ts +2 -0
  17. package/types/lib/core/2.app/driving-ports/for-shared-externals-storage.port.d.ts +2 -0
  18. package/types/lib/core/2.app/steps/convert-to-import-map.d.ts +2 -1
  19. package/types/lib/core/2.app/steps/pooling/pool-dynamic-externals.d.ts +3 -0
  20. package/types/lib/core/2.app/steps/pooling/pool-graph.d.ts +25 -0
  21. package/types/lib/core/2.app/steps/pooling/pool-shared-externals.d.ts +5 -0
  22. package/types/lib/core/2.app/steps/pooling/pool.types.d.ts +25 -0
  23. package/types/lib/core/2.app/steps/pooling/pool.util.d.ts +4 -0
  24. package/types/lib/core/2.app/steps/store-remote-entry.d.ts +2 -2
  25. package/types/lib/core/3.adapters/http/remote-entry-provider.d.ts +2 -1
@@ -12,35 +12,39 @@ function createGetShared(ports) {
12
12
  for (const scope of ports.sharedExternalsRepo.getScopes({ includeGlobal: true })) {
13
13
  const scopeType = ports.sharedExternalsRepo.scopeType(scope);
14
14
  const externals = ports.sharedExternalsRepo.getFromScope(scope);
15
- for (const [packageName, external] of Object.entries(externals)) {
15
+ for (const external of Object.values(externals)) {
16
16
  const shareVersions = external.versions.filter((v) => v.action === "share");
17
17
  if (shareVersions.length === 0) continue;
18
18
  const versions = scopeType === "strict" ? shareVersions : shareVersions.slice(0, 1);
19
19
  const singleton = scopeType === "strict" ? false : options.singleton ?? true;
20
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);
21
+ const source = version.remotes[0];
22
+ if (!source) continue;
23
+ for (const [entryName, file] of Object.entries(source.entries)) {
24
+ const url = resolveUrl(version, file);
25
+ if (!url) continue;
26
+ const shareObject = {
27
+ version: version.tag,
28
+ get: () => ports.browser.importModule(url).then((module) => () => module),
29
+ shareConfig: {
30
+ singleton,
31
+ requiredVersion: resolveRequiredVersion(version, options, scopeType),
32
+ ...scopeType === "strict" ? { strictVersion: true } : {}
33
+ }
34
+ };
35
+ if (scopeType !== "global") shareObject.scope = scope;
36
+ if (!shared[entryName]) shared[entryName] = [];
37
+ shared[entryName].push(shareObject);
38
+ }
35
39
  }
36
40
  }
37
41
  }
38
42
  return shared;
39
43
  };
40
- function resolveUrl(version) {
44
+ function resolveUrl(version, file) {
41
45
  const source = version.remotes[0];
42
46
  if (!source) return void 0;
43
- return ports.remoteInfoRepo.tryGet(source.name).map((remote) => join(remote.scopeUrl, source.file)).get();
47
+ return ports.remoteInfoRepo.tryGet(source.name).map((remote) => join(remote.scopeUrl, file)).get();
44
48
  }
45
49
  }
46
50
  function resolveRequiredVersion(version, options, scopeType) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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;",
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 external of Object.values(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 source = version.remotes[0];\n if (!source) continue;\n\n // MF's shared config is flat: one key per entrypoint. Emit a separate\n // Shared for each entry so secondary entrypoints reach MF consumers.\n for (const [entryName, file] of Object.entries(source.entries)) {\n const url = resolveUrl(version, file);\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[entryName]) shared[entryName] = [];\n shared[entryName]!.push(shareObject);\n }\n }\n }\n }\n\n return shared;\n };\n\n function resolveUrl(version: SharedVersion, file: string): 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, 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,YAAY,OAAO,OAAO,SAAS,GAAG;AAC/C,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,SAAS,QAAQ,QAAQ,CAAC;AAChC,cAAI,CAAC,OAAQ;AAIb,qBAAW,CAAC,WAAW,IAAI,KAAK,OAAO,QAAQ,OAAO,OAAO,GAAG;AAC9D,kBAAM,MAAM,WAAW,SAAS,IAAI;AACpC,gBAAI,CAAC,IAAK;AAEV,kBAAM,cAAsB;AAAA,cAC1B,SAAS,QAAQ;AAAA,cACjB,KAAK,MAAM,MAAM,QAAQ,aAAa,GAAG,EAAE,KAAK,YAAU,MAAM,MAAM;AAAA,cACtE,aAAa;AAAA,gBACX;AAAA,gBACA,iBAAiB,uBAAuB,SAAS,SAAS,SAAS;AAAA,gBACnE,GAAI,cAAc,WAAW,EAAE,eAAe,KAAK,IAAI,CAAC;AAAA,cAC1D;AAAA,YACF;AACA,gBAAI,cAAc,SAAU,aAAY,QAAQ;AAEhD,gBAAI,CAAC,OAAO,SAAS,EAAG,QAAO,SAAS,IAAI,CAAC;AAC7C,mBAAO,SAAS,EAAG,KAAK,WAAW;AAAA,UACrC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,WAAW,SAAwB,MAAkC;AAC5E,UAAM,SAAS,QAAQ,QAAQ,CAAC;AAChC,QAAI,CAAC,OAAQ,QAAO;AAEpB,WAAO,MAAM,eACV,OAAO,OAAO,IAAI,EAClB,IAAI,YAAgB,KAAK,OAAO,UAAU,IAAI,CAAC,EAC/C,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
6
  "names": []
7
7
  }