@softarc/native-federation-orchestrator 4.5.1 → 4.5.3

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.
@@ -18,32 +18,35 @@ function createGetShared(ports) {
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 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);
21
+ if (!version.remotes[0]) continue;
22
+ const requiredVersion = resolveRequiredVersion(version, options, scopeType);
23
+ const claimed = /* @__PURE__ */ new Set();
24
+ for (const source of version.remotes) {
25
+ for (const [entryName, file] of Object.entries(source.entries)) {
26
+ if (claimed.has(entryName)) continue;
27
+ claimed.add(entryName);
28
+ const url = resolveUrl(source, file);
29
+ if (!url) continue;
30
+ const shareObject = {
31
+ version: version.tag,
32
+ get: () => ports.browser.importModule(url).then((module) => () => module),
33
+ shareConfig: {
34
+ singleton,
35
+ requiredVersion,
36
+ ...scopeType === "strict" ? { strictVersion: true } : {}
37
+ }
38
+ };
39
+ if (scopeType !== "global") shareObject.scope = scope;
40
+ if (!shared[entryName]) shared[entryName] = [];
41
+ shared[entryName].push(shareObject);
42
+ }
38
43
  }
39
44
  }
40
45
  }
41
46
  }
42
47
  return shared;
43
48
  };
44
- function resolveUrl(version, file) {
45
- const source = version.remotes[0];
46
- if (!source) return void 0;
49
+ function resolveUrl(source, file) {
47
50
  return ports.remoteInfoRepo.tryGet(source.name).map((remote) => join(remote.scopeUrl, file)).get();
48
51
  }
49
52
  }
@@ -52,6 +55,8 @@ function resolveRequiredVersion(version, options, scopeType) {
52
55
  if (typeof options.requiredVersionPrefix === "string") {
53
56
  return `${options.requiredVersionPrefix}${version.tag}`;
54
57
  }
58
+ const declared = new Set(version.remotes.map((r) => r.requiredVersion));
59
+ if (declared.size > 1) return version.tag;
55
60
  return version.remotes[0]?.requiredVersion || `^${version.tag}`;
56
61
  }
57
62
  export {
@@ -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 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;",
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, SharedVersionMeta } 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 if (!version.remotes[0]) continue;\n\n const requiredVersion = resolveRequiredVersion(version, options, scopeType);\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 const claimed = new Set<string>();\n for (const source of version.remotes) {\n for (const [entryName, file] of Object.entries(source.entries)) {\n if (claimed.has(entryName)) continue;\n claimed.add(entryName);\n\n const url = resolveUrl(source, 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,\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\n return shared;\n };\n\n function resolveUrl(source: SharedVersionMeta, file: string): string | undefined {\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 // `remotes[0]` is the serving basis, ordered by entrypoint coverage: it says nothing about\n // what the version demands. Advertising its range would let MF hand a sibling a copy that\n // sibling's own range rejects, so a disagreement pins to the tag \u2014 the only value no remote\n // can reject, and the one the import map already commits to.\n const declared = new Set(version.remotes.map(r => r.requiredVersion));\n if (declared.size > 1) return 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,cAAI,CAAC,QAAQ,QAAQ,CAAC,EAAG;AAEzB,gBAAM,kBAAkB,uBAAuB,SAAS,SAAS,SAAS;AAI1E,gBAAM,UAAU,oBAAI,IAAY;AAChC,qBAAW,UAAU,QAAQ,SAAS;AACpC,uBAAW,CAAC,WAAW,IAAI,KAAK,OAAO,QAAQ,OAAO,OAAO,GAAG;AAC9D,kBAAI,QAAQ,IAAI,SAAS,EAAG;AAC5B,sBAAQ,IAAI,SAAS;AAErB,oBAAM,MAAM,WAAW,QAAQ,IAAI;AACnC,kBAAI,CAAC,IAAK;AAEV,oBAAM,cAAsB;AAAA,gBAC1B,SAAS,QAAQ;AAAA,gBACjB,KAAK,MAAM,MAAM,QAAQ,aAAa,GAAG,EAAE,KAAK,YAAU,MAAM,MAAM;AAAA,gBACtE,aAAa;AAAA,kBACX;AAAA,kBACA;AAAA,kBACA,GAAI,cAAc,WAAW,EAAE,eAAe,KAAK,IAAI,CAAC;AAAA,gBAC1D;AAAA,cACF;AACA,kBAAI,cAAc,SAAU,aAAY,QAAQ;AAEhD,kBAAI,CAAC,OAAO,SAAS,EAAG,QAAO,SAAS,IAAI,CAAC;AAC7C,qBAAO,SAAS,EAAG,KAAK,WAAW;AAAA,YACrC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,WAAW,QAA2B,MAAkC;AAC/E,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;AAKA,QAAM,WAAW,IAAI,IAAI,QAAQ,QAAQ,IAAI,OAAK,EAAE,eAAe,CAAC;AACpE,MAAI,SAAS,OAAO,EAAG,QAAO,QAAQ;AAEtC,SAAO,QAAQ,QAAQ,CAAC,GAAG,mBAAmB,IAAI,QAAQ,GAAG;AAC/D;",
6
6
  "names": []
7
7
  }