@softarc/native-federation-orchestrator 4.8.0 → 4.10.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.
Files changed (48) hide show
  1. package/README.md +2 -2
  2. package/fesm2022/@softarc/native-federation-orchestrator.mjs +874 -343
  3. package/fesm2022/@softarc/native-federation-orchestrator.mjs.map +4 -4
  4. package/fesm2022/module-federation.mjs +78 -21
  5. package/fesm2022/module-federation.mjs.map +3 -3
  6. package/fesm2022/node.mjs +949 -347
  7. package/fesm2022/node.mjs.map +4 -4
  8. package/fesm2022/options.mjs +27 -2
  9. package/fesm2022/options.mjs.map +3 -3
  10. package/package.json +3 -3
  11. package/quickstart.mjs +16 -14
  12. package/types/lib/core/1.domain/externals/basis.d.ts +2 -2
  13. package/types/lib/core/1.domain/externals/claims.d.ts +1 -2
  14. package/types/lib/core/1.domain/externals/serving.d.ts +2 -2
  15. package/types/lib/core/1.domain/externals/specifier.d.ts +11 -6
  16. package/types/lib/core/1.domain/externals/version.contract.d.ts +4 -0
  17. package/types/lib/core/1.domain/import-map/eager-preloads.d.ts +10 -0
  18. package/types/lib/core/1.domain/pooling/builds.d.ts +9 -3
  19. package/types/lib/core/1.domain/pooling/election.d.ts +2 -1
  20. package/types/lib/core/1.domain/pooling/gate.d.ts +4 -2
  21. package/types/lib/core/1.domain/pooling/membership.d.ts +4 -2
  22. package/types/lib/core/1.domain/pooling/plan.d.ts +2 -0
  23. package/types/lib/core/1.domain/remote/remote-module.contract.d.ts +1 -0
  24. package/types/lib/core/1.domain/remote-entry/mark-dense.d.ts +2 -0
  25. package/types/lib/core/1.domain/remote-entry/remote-entry.contract.d.ts +6 -3
  26. package/types/lib/core/2.app/config/import-map.contract.d.ts +4 -7
  27. package/types/lib/core/2.app/config/index.d.ts +2 -2
  28. package/types/lib/core/2.app/config/mode.contract.d.ts +2 -0
  29. package/types/lib/core/2.app/driver-ports/init/flow.contract.d.ts +2 -4
  30. package/types/lib/core/2.app/driver-ports/init/for-exposing-module-loader.port.d.ts +6 -2
  31. package/types/lib/core/2.app/driving-ports/for-browser-tasks.d.ts +1 -0
  32. package/types/lib/core/2.app/driving-ports/for-remote-info-storage.port.d.ts +1 -0
  33. package/types/lib/core/2.app/steps/collect-eager-preloads.d.ts +4 -0
  34. package/types/lib/core/2.app/steps/get-remote-entries.d.ts +1 -1
  35. package/types/lib/core/2.app/steps/preload-hint.d.ts +4 -0
  36. package/types/lib/core/2.app/steps/store-remote-entry.d.ts +0 -14
  37. package/types/lib/core/3.adapters/remote-entry/normalize-remote-entry.d.ts +4 -0
  38. package/types/lib/core/4.config/import-map/index.d.ts +2 -0
  39. package/types/lib/core/4.config/import-map/no-preload.d.ts +2 -0
  40. package/types/lib/core/4.config/import-map/preload-in-dom.d.ts +2 -0
  41. package/types/lib/core/4.config/storage/storage.config.d.ts +2 -1
  42. package/types/lib/core/5.di/federation-result.factory.d.ts +3 -2
  43. package/types/lib/core/init-federation.contract.d.ts +2 -0
  44. package/types/lib/index.d.ts +1 -1
  45. package/types/lib/node/adapters/fs-remote-entry-provider.d.ts +2 -1
  46. package/types/lib/node/init-federation.node.d.ts +2 -7
  47. package/types/lib/node.index.d.ts +1 -1
  48. package/types/lib/utils/union-find.d.ts +4 -0
@@ -28,9 +28,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  mod
29
29
  ));
30
30
 
31
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/debug.js
31
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/debug.js
32
32
  var require_debug = __commonJS({
33
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/debug.js"(exports, module) {
33
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/debug.js"(exports, module) {
34
34
  "use strict";
35
35
  var debug = typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error("SEMVER", ...args) : () => {
36
36
  };
@@ -38,9 +38,9 @@ var require_debug = __commonJS({
38
38
  }
39
39
  });
40
40
 
41
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/constants.js
41
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/constants.js
42
42
  var require_constants = __commonJS({
43
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/constants.js"(exports, module) {
43
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/constants.js"(exports, module) {
44
44
  "use strict";
45
45
  var SEMVER_SPEC_VERSION = "2.0.0";
46
46
  var MAX_LENGTH = 256;
@@ -48,6 +48,33 @@ var require_constants = __commonJS({
48
48
  9007199254740991;
49
49
  var MAX_SAFE_COMPONENT_LENGTH = 16;
50
50
  var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6;
51
+ var WHITESPACE_CHARACTERS = [
52
+ " ",
53
+ "\n",
54
+ "\v",
55
+ "\f",
56
+ "\r",
57
+ " ",
58
+ "\xA0",
59
+ "\u1680",
60
+ "\u2000",
61
+ "\u2001",
62
+ "\u2002",
63
+ "\u2003",
64
+ "\u2004",
65
+ "\u2005",
66
+ "\u2006",
67
+ "\u2007",
68
+ "\u2008",
69
+ "\u2009",
70
+ "\u200A",
71
+ "\u2028",
72
+ "\u2029",
73
+ "\u202F",
74
+ "\u205F",
75
+ "\u3000",
76
+ "\uFEFF"
77
+ ];
51
78
  var RELEASE_TYPES = [
52
79
  "major",
53
80
  "premajor",
@@ -62,6 +89,7 @@ var require_constants = __commonJS({
62
89
  MAX_SAFE_COMPONENT_LENGTH,
63
90
  MAX_SAFE_BUILD_LENGTH,
64
91
  MAX_SAFE_INTEGER,
92
+ WHITESPACE_CHARACTERS,
65
93
  RELEASE_TYPES,
66
94
  SEMVER_SPEC_VERSION,
67
95
  FLAG_INCLUDE_PRERELEASE: 1,
@@ -70,9 +98,9 @@ var require_constants = __commonJS({
70
98
  }
71
99
  });
72
100
 
73
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/re.js
101
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/re.js
74
102
  var require_re = __commonJS({
75
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/re.js"(exports, module) {
103
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/re.js"(exports, module) {
76
104
  "use strict";
77
105
  var {
78
106
  MAX_SAFE_COMPONENT_LENGTH,
@@ -158,9 +186,9 @@ var require_re = __commonJS({
158
186
  }
159
187
  });
160
188
 
161
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/parse-options.js
189
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/parse-options.js
162
190
  var require_parse_options = __commonJS({
163
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/parse-options.js"(exports, module) {
191
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/parse-options.js"(exports, module) {
164
192
  "use strict";
165
193
  var looseOption = Object.freeze({ loose: true });
166
194
  var emptyOpts = Object.freeze({});
@@ -177,9 +205,9 @@ var require_parse_options = __commonJS({
177
205
  }
178
206
  });
179
207
 
180
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/identifiers.js
208
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/identifiers.js
181
209
  var require_identifiers = __commonJS({
182
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/identifiers.js"(exports, module) {
210
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/identifiers.js"(exports, module) {
183
211
  "use strict";
184
212
  var numeric = /^[0-9]+$/;
185
213
  var compareIdentifiers = (a, b) => {
@@ -202,9 +230,9 @@ var require_identifiers = __commonJS({
202
230
  }
203
231
  });
204
232
 
205
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/semver.js
233
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/classes/semver.js
206
234
  var require_semver = __commonJS({
207
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/semver.js"(exports, module) {
235
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/classes/semver.js"(exports, module) {
208
236
  "use strict";
209
237
  var debug = require_debug();
210
238
  var { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants();
@@ -494,9 +522,9 @@ var require_semver = __commonJS({
494
522
  }
495
523
  });
496
524
 
497
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/parse.js
525
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/parse.js
498
526
  var require_parse = __commonJS({
499
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/parse.js"(exports, module) {
527
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/parse.js"(exports, module) {
500
528
  "use strict";
501
529
  var SemVer2 = require_semver();
502
530
  var parse = (version, options, throwErrors = false) => {
@@ -516,9 +544,9 @@ var require_parse = __commonJS({
516
544
  }
517
545
  });
518
546
 
519
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/valid.js
547
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/valid.js
520
548
  var require_valid = __commonJS({
521
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/valid.js"(exports, module) {
549
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/valid.js"(exports, module) {
522
550
  "use strict";
523
551
  var parse = require_parse();
524
552
  var valid = (version, options) => {
@@ -529,9 +557,9 @@ var require_valid = __commonJS({
529
557
  }
530
558
  });
531
559
 
532
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/lrucache.js
560
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/lrucache.js
533
561
  var require_lrucache = __commonJS({
534
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/lrucache.js"(exports, module) {
562
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/lrucache.js"(exports, module) {
535
563
  "use strict";
536
564
  var LRUCache = class {
537
565
  constructor() {
@@ -567,9 +595,9 @@ var require_lrucache = __commonJS({
567
595
  }
568
596
  });
569
597
 
570
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/compare.js
598
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/compare.js
571
599
  var require_compare = __commonJS({
572
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/compare.js"(exports, module) {
600
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/compare.js"(exports, module) {
573
601
  "use strict";
574
602
  var SemVer2 = require_semver();
575
603
  var compare = (a, b, loose) => new SemVer2(a, loose).compare(new SemVer2(b, loose));
@@ -577,9 +605,9 @@ var require_compare = __commonJS({
577
605
  }
578
606
  });
579
607
 
580
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/eq.js
608
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/eq.js
581
609
  var require_eq = __commonJS({
582
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/eq.js"(exports, module) {
610
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/eq.js"(exports, module) {
583
611
  "use strict";
584
612
  var compare = require_compare();
585
613
  var eq = (a, b, loose) => compare(a, b, loose) === 0;
@@ -587,9 +615,9 @@ var require_eq = __commonJS({
587
615
  }
588
616
  });
589
617
 
590
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/neq.js
618
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/neq.js
591
619
  var require_neq = __commonJS({
592
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/neq.js"(exports, module) {
620
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/neq.js"(exports, module) {
593
621
  "use strict";
594
622
  var compare = require_compare();
595
623
  var neq = (a, b, loose) => compare(a, b, loose) !== 0;
@@ -597,9 +625,9 @@ var require_neq = __commonJS({
597
625
  }
598
626
  });
599
627
 
600
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/gt.js
628
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/gt.js
601
629
  var require_gt = __commonJS({
602
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/gt.js"(exports, module) {
630
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/gt.js"(exports, module) {
603
631
  "use strict";
604
632
  var compare = require_compare();
605
633
  var gt = (a, b, loose) => compare(a, b, loose) > 0;
@@ -607,9 +635,9 @@ var require_gt = __commonJS({
607
635
  }
608
636
  });
609
637
 
610
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/gte.js
638
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/gte.js
611
639
  var require_gte = __commonJS({
612
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/gte.js"(exports, module) {
640
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/gte.js"(exports, module) {
613
641
  "use strict";
614
642
  var compare = require_compare();
615
643
  var gte = (a, b, loose) => compare(a, b, loose) >= 0;
@@ -617,9 +645,9 @@ var require_gte = __commonJS({
617
645
  }
618
646
  });
619
647
 
620
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/lt.js
648
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/lt.js
621
649
  var require_lt = __commonJS({
622
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/lt.js"(exports, module) {
650
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/lt.js"(exports, module) {
623
651
  "use strict";
624
652
  var compare = require_compare();
625
653
  var lt = (a, b, loose) => compare(a, b, loose) < 0;
@@ -627,9 +655,9 @@ var require_lt = __commonJS({
627
655
  }
628
656
  });
629
657
 
630
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/lte.js
658
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/lte.js
631
659
  var require_lte = __commonJS({
632
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/lte.js"(exports, module) {
660
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/lte.js"(exports, module) {
633
661
  "use strict";
634
662
  var compare = require_compare();
635
663
  var lte = (a, b, loose) => compare(a, b, loose) <= 0;
@@ -637,9 +665,9 @@ var require_lte = __commonJS({
637
665
  }
638
666
  });
639
667
 
640
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/cmp.js
668
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/cmp.js
641
669
  var require_cmp = __commonJS({
642
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/cmp.js"(exports, module) {
670
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/cmp.js"(exports, module) {
643
671
  "use strict";
644
672
  var eq = require_eq();
645
673
  var neq = require_neq();
@@ -687,9 +715,9 @@ var require_cmp = __commonJS({
687
715
  }
688
716
  });
689
717
 
690
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/comparator.js
718
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/classes/comparator.js
691
719
  var require_comparator = __commonJS({
692
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/comparator.js"(exports, module) {
720
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/classes/comparator.js"(exports, module) {
693
721
  "use strict";
694
722
  var ANY = /* @__PURE__ */ Symbol("SemVer ANY");
695
723
  var Comparator = class _Comparator {
@@ -800,9 +828,200 @@ var require_comparator = __commonJS({
800
828
  }
801
829
  });
802
830
 
803
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/range.js
831
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/trim-comparator-whitespace.js
832
+ var require_trim_comparator_whitespace = __commonJS({
833
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/internal/trim-comparator-whitespace.js"(exports, module) {
834
+ "use strict";
835
+ var {
836
+ MAX_LENGTH,
837
+ MAX_SAFE_BUILD_LENGTH,
838
+ WHITESPACE_CHARACTERS
839
+ } = require_constants();
840
+ var whitespace = new Uint8Array(65536);
841
+ for (const char of WHITESPACE_CHARACTERS) {
842
+ whitespace[char.charCodeAt(0)] = 1;
843
+ }
844
+ var isWhitespace = (char) => char !== void 0 && whitespace[char.charCodeAt(0)] === 1;
845
+ var isVersionPrefix = (char) => char === "v" || char === "=" || isWhitespace(char);
846
+ var isDigit = (char) => char !== void 0 && char >= "0" && char <= "9";
847
+ var isLetter = (char) => char !== void 0 && (char >= "a" && char <= "z" || char >= "A" && char <= "Z");
848
+ var isIdentifierCharacter = (char) => isDigit(char) || isLetter(char) || char === "-";
849
+ var isVersionStart = (char) => isDigit(char) || char === "x" || char === "X" || char === "*";
850
+ var findDigitsEndIndex = (range, start, limit, digitRuns) => {
851
+ if (!isDigit(range[start])) {
852
+ return start;
853
+ }
854
+ if (start >= digitRuns.start && start < digitRuns.end) {
855
+ return Math.min(start + limit, digitRuns.end);
856
+ }
857
+ if (start >= digitRuns.previousStart && start < digitRuns.previousEnd) {
858
+ return Math.min(start + limit, digitRuns.previousEnd);
859
+ }
860
+ let end = start + 1;
861
+ while (isDigit(range[end])) {
862
+ end++;
863
+ }
864
+ digitRuns.previousStart = digitRuns.start;
865
+ digitRuns.previousEnd = digitRuns.end;
866
+ digitRuns.start = start;
867
+ digitRuns.end = end;
868
+ return Math.min(start + limit, end);
869
+ };
870
+ var findVersionNumberEndIndex = (range, start, loose, digitRuns) => {
871
+ if (!loose && range[start] === "0") {
872
+ return start + 1;
873
+ }
874
+ return findDigitsEndIndex(range, start, loose ? MAX_LENGTH : MAX_LENGTH + 1, digitRuns);
875
+ };
876
+ var findPrereleaseIdentifierEndIndex = (range, start, loose, digitRuns) => {
877
+ const digitsEnd = findDigitsEndIndex(range, start, MAX_LENGTH, digitRuns);
878
+ if (isLetter(range[digitsEnd]) || range[digitsEnd] === "-") {
879
+ let end = digitsEnd + 1;
880
+ const limit = end + MAX_SAFE_BUILD_LENGTH;
881
+ while (end < limit && isIdentifierCharacter(range[end])) {
882
+ end++;
883
+ }
884
+ return end;
885
+ }
886
+ return findVersionNumberEndIndex(range, start, loose, digitRuns);
887
+ };
888
+ var findPrereleaseEndIndex = (range, start, loose, digitRuns) => {
889
+ const hyphen = range[start] === "-";
890
+ if (!loose && !hyphen) {
891
+ return start;
892
+ }
893
+ const identifierStart = start + (hyphen ? 1 : 0);
894
+ let end = findPrereleaseIdentifierEndIndex(range, identifierStart, loose, digitRuns);
895
+ if (end === identifierStart) {
896
+ if (!loose || !hyphen) {
897
+ return start;
898
+ }
899
+ end = findPrereleaseIdentifierEndIndex(range, start, loose, digitRuns);
900
+ }
901
+ while (range[end] === ".") {
902
+ const next = findPrereleaseIdentifierEndIndex(range, end + 1, loose, digitRuns);
903
+ if (next === end + 1) {
904
+ break;
905
+ }
906
+ end = next;
907
+ }
908
+ return end;
909
+ };
910
+ var findBuildIdentifierEndIndex = (range, start) => {
911
+ let end = start;
912
+ while (end - start < MAX_SAFE_BUILD_LENGTH && isIdentifierCharacter(range[end])) {
913
+ end++;
914
+ }
915
+ return end;
916
+ };
917
+ var findBuildEndIndex = (range, start) => {
918
+ if (range[start] !== "+") {
919
+ return start;
920
+ }
921
+ let end = findBuildIdentifierEndIndex(range, start + 1);
922
+ if (end === start + 1) {
923
+ return start;
924
+ }
925
+ while (range[end] === ".") {
926
+ const next = findBuildIdentifierEndIndex(range, end + 1);
927
+ if (next === end + 1) {
928
+ break;
929
+ }
930
+ end = next;
931
+ }
932
+ return end;
933
+ };
934
+ var findLooseFullVersionEndIndex = (range, start, digitRuns) => {
935
+ let end = start;
936
+ for (let component = 0; component < 3; component++) {
937
+ const next = findVersionNumberEndIndex(range, end, true, digitRuns);
938
+ if (next === end) {
939
+ return start;
940
+ }
941
+ end = next;
942
+ if (component < 2) {
943
+ if (range[end] !== ".") {
944
+ return start;
945
+ }
946
+ end++;
947
+ }
948
+ }
949
+ const prereleaseEnd = findPrereleaseEndIndex(range, end, true, digitRuns);
950
+ return findBuildEndIndex(range, prereleaseEnd);
951
+ };
952
+ var findPartialVersionComponentEndIndex = (range, start, digitRuns) => {
953
+ if (isDigit(range[start])) {
954
+ return findVersionNumberEndIndex(range, start, false, digitRuns);
955
+ }
956
+ return isVersionStart(range[start]) ? start + 1 : start;
957
+ };
958
+ var findPartialVersionEndIndex = (range, start, digitRuns) => {
959
+ let end = findPartialVersionComponentEndIndex(range, start, digitRuns);
960
+ for (let component = 0; component < 2; component++) {
961
+ if (range[end] !== ".") {
962
+ return end;
963
+ }
964
+ const next = findPartialVersionComponentEndIndex(range, end + 1, digitRuns);
965
+ if (next === end + 1) {
966
+ return end;
967
+ }
968
+ end = next;
969
+ }
970
+ const prereleaseEnd = findPrereleaseEndIndex(range, end, false, digitRuns);
971
+ return findBuildEndIndex(range, prereleaseEnd);
972
+ };
973
+ var findVersionEndIndex = (range, start, digitRuns) => {
974
+ const fullVersionEnd = findLooseFullVersionEndIndex(range, start, digitRuns);
975
+ return fullVersionEnd !== start ? fullVersionEnd : findPartialVersionEndIndex(range, start, digitRuns);
976
+ };
977
+ var findRemovableWhitespaceIndex = (range, matchStart) => {
978
+ let position = matchStart;
979
+ if (isWhitespace(range[position])) {
980
+ position++;
981
+ }
982
+ if (range[position] === "<" || range[position] === ">") {
983
+ position++;
984
+ }
985
+ if (range[position] === "=") {
986
+ position++;
987
+ }
988
+ return isWhitespace(range[position]) ? position : -1;
989
+ };
990
+ var trimComparatorWhitespace = (range) => {
991
+ let result = "";
992
+ let copyFrom = 0;
993
+ let cursor = 0;
994
+ const digitRuns = { start: -1, end: -1, previousStart: -1, previousEnd: -1 };
995
+ while (cursor < range.length) {
996
+ const matchStart = cursor;
997
+ if (range[cursor] === "<" || range[cursor] === ">") {
998
+ cursor++;
999
+ } else if (!isVersionPrefix(range[cursor]) && !isVersionStart(range[cursor])) {
1000
+ cursor++;
1001
+ continue;
1002
+ }
1003
+ while (cursor < range.length && isVersionPrefix(range[cursor])) {
1004
+ cursor++;
1005
+ }
1006
+ if (!isVersionStart(range[cursor])) {
1007
+ continue;
1008
+ }
1009
+ const whitespacePosition = findRemovableWhitespaceIndex(range, matchStart);
1010
+ if (whitespacePosition !== -1) {
1011
+ result += range.slice(copyFrom, whitespacePosition);
1012
+ copyFrom = whitespacePosition + 1;
1013
+ }
1014
+ cursor = findVersionEndIndex(range, cursor, digitRuns);
1015
+ }
1016
+ return result + range.slice(copyFrom);
1017
+ };
1018
+ module.exports = trimComparatorWhitespace;
1019
+ }
1020
+ });
1021
+
1022
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/classes/range.js
804
1023
  var require_range = __commonJS({
805
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/range.js"(exports, module) {
1024
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/classes/range.js"(exports, module) {
806
1025
  "use strict";
807
1026
  var SPACE_CHARACTERS = /\s+/g;
808
1027
  var Range = class _Range {
@@ -881,7 +1100,7 @@ var require_range = __commonJS({
881
1100
  const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE];
882
1101
  range = range.replace(hr, hyphenReplace(this.options.includePrerelease));
883
1102
  debug("hyphen replace", range);
884
- range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace);
1103
+ range = trimComparatorWhitespace(range);
885
1104
  debug("comparator trim", range);
886
1105
  range = range.replace(re[t.TILDETRIM], tildeTrimReplace);
887
1106
  debug("tilde trim", range);
@@ -951,11 +1170,11 @@ var require_range = __commonJS({
951
1170
  var Comparator = require_comparator();
952
1171
  var debug = require_debug();
953
1172
  var SemVer2 = require_semver();
1173
+ var trimComparatorWhitespace = require_trim_comparator_whitespace();
954
1174
  var {
955
1175
  safeRe: re,
956
1176
  src,
957
1177
  t,
958
- comparatorTrimReplace,
959
1178
  tildeTrimReplace,
960
1179
  caretTrimReplace
961
1180
  } = require_re();
@@ -1185,9 +1404,9 @@ var require_range = __commonJS({
1185
1404
  }
1186
1405
  });
1187
1406
 
1188
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/satisfies.js
1407
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/satisfies.js
1189
1408
  var require_satisfies = __commonJS({
1190
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/satisfies.js"(exports, module) {
1409
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/functions/satisfies.js"(exports, module) {
1191
1410
  "use strict";
1192
1411
  var Range = require_range();
1193
1412
  var satisfies = (version, range, options) => {
@@ -1202,9 +1421,9 @@ var require_satisfies = __commonJS({
1202
1421
  }
1203
1422
  });
1204
1423
 
1205
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/min-version.js
1424
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/ranges/min-version.js
1206
1425
  var require_min_version = __commonJS({
1207
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/min-version.js"(exports, module) {
1426
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/ranges/min-version.js"(exports, module) {
1208
1427
  "use strict";
1209
1428
  var SemVer2 = require_semver();
1210
1429
  var Range = require_range();
@@ -1261,9 +1480,9 @@ var require_min_version = __commonJS({
1261
1480
  }
1262
1481
  });
1263
1482
 
1264
- // node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/valid.js
1483
+ // node_modules/.pnpm/semver@7.8.6/node_modules/semver/ranges/valid.js
1265
1484
  var require_valid2 = __commonJS({
1266
- "node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/valid.js"(exports, module) {
1485
+ "node_modules/.pnpm/semver@7.8.6/node_modules/semver/ranges/valid.js"(exports, module) {
1267
1486
  "use strict";
1268
1487
  var Range = require_range();
1269
1488
  var validRange = (range, options) => {
@@ -1283,10 +1502,10 @@ var createInitFlow = ({
1283
1502
  adapters,
1284
1503
  config
1285
1504
  }) => {
1286
- return (remotesOrManifestUrl) => flow.getRemoteEntries(remotesOrManifestUrl).then(flow.processRemoteEntries).then(flow.poolSharedExternals).then(flow.determineSharedExternals).then(flow.decideServingBuilds).then(flow.generateImportMap).then((importMap) => flow.commitChanges(importMap, { override: true })).then(flow.exposeModuleLoader).then((loadRemoteModule) => ({
1505
+ return (remotesOrManifestUrl) => flow.getRemoteEntries(remotesOrManifestUrl).then(flow.processRemoteEntries).then(flow.poolSharedExternals).then(flow.determineSharedExternals).then(flow.decideServingBuilds).then(flow.generateImportMap).then((importMap) => flow.commitChanges(importMap, { override: true })).then(flow.exposeModuleLoader).then((access) => ({
1287
1506
  config,
1288
1507
  adapters,
1289
- loadRemoteModule
1508
+ ...access
1290
1509
  }));
1291
1510
  };
1292
1511
 
@@ -1325,8 +1544,140 @@ function getScope(path) {
1325
1544
  return `${parts.join("/")}/`;
1326
1545
  }
1327
1546
 
1547
+ // src/lib/core/2.app/steps/store-remote-entry.ts
1548
+ function createRemoveCachedRemoteEntries(ports) {
1549
+ return (remoteNames) => {
1550
+ if (remoteNames.size === 0) return;
1551
+ for (const remoteName of remoteNames) {
1552
+ ports.remoteInfoRepo.remove(remoteName);
1553
+ ports.scopedExternalsRepo.remove(remoteName);
1554
+ ports.sharedChunksRepo.remove(remoteName);
1555
+ }
1556
+ ports.sharedExternalsRepo.removeFromAllScopes(remoteNames);
1557
+ };
1558
+ }
1559
+ function createStoreRemoteEntry(config, ports, logStep) {
1560
+ return (remoteEntry, onSharedExternal) => {
1561
+ addRemoteInfoToStorage(remoteEntry);
1562
+ addExternalsToStorage(remoteEntry, onSharedExternal);
1563
+ addSharedChunksToStorage(remoteEntry);
1564
+ };
1565
+ function addRemoteInfoToStorage({ name, url, exposes, integrity }) {
1566
+ ports.remoteInfoRepo.addOrUpdate(name, {
1567
+ scopeUrl: getScope(url),
1568
+ exposes: Object.values(exposes ?? []).map((m) => {
1569
+ const chunks = Object.values(m.chunks ?? {}).filter((c) => c.initial).map((c) => c.file);
1570
+ return {
1571
+ moduleName: m.key,
1572
+ file: m.outFileName,
1573
+ ...chunks.length ? { chunks } : {}
1574
+ };
1575
+ }),
1576
+ ...integrity ? { integrity } : {}
1577
+ });
1578
+ }
1579
+ function addExternalsToStorage(remoteEntry, onSharedExternal) {
1580
+ remoteEntry.shared.forEach((external) => {
1581
+ const tag = resolveVersion(remoteEntry, external);
1582
+ if (tag === null) return;
1583
+ if (external.singleton) {
1584
+ if (external.requiredVersion && !ports.versionCheck.isCompatible(tag, external.requiredVersion))
1585
+ config.log.warn(
1586
+ logStep,
1587
+ `[${remoteEntry.name}][${external.packageName}] requiredVersion '${external.requiredVersion}' excludes its own version '${tag}'; '${tag}' is still accepted for it.`
1588
+ );
1589
+ onSharedExternal(remoteEntry, external, sharedExternalContext(remoteEntry, external, tag));
1590
+ } else {
1591
+ addScopedExternal(remoteEntry, external, tag);
1592
+ }
1593
+ });
1594
+ }
1595
+ function addSharedChunksToStorage(remoteEntry) {
1596
+ if (!remoteEntry.chunks) return;
1597
+ config.log.debug(
1598
+ logStep,
1599
+ `Adding chunks for remote "${remoteEntry.name}", bundles: [${Object.keys(remoteEntry.chunks).join(", ")}]`
1600
+ );
1601
+ Object.entries(remoteEntry.chunks).forEach(([bundleName, chunks]) => {
1602
+ ports.sharedChunksRepo.addOrReplace(remoteEntry.name, bundleName, chunks);
1603
+ });
1604
+ }
1605
+ function addScopedExternal(remoteEntry, sharedInfo, tag) {
1606
+ const { packageName, entries } = sharedInfo;
1607
+ const key = packageName in entries ? packageName : Object.keys(entries)[0] ?? packageName;
1608
+ ports.scopedExternalsRepo.addExternal(remoteEntry.name, key, {
1609
+ tag,
1610
+ bundle: sharedInfo.bundle,
1611
+ entries,
1612
+ ...sharedInfo.preload ? { preload: true } : {}
1613
+ });
1614
+ }
1615
+ function resolveVersion(remoteEntry, external) {
1616
+ if (external.version && ports.versionCheck.isValidSemver(external.version)) {
1617
+ return external.version;
1618
+ }
1619
+ const errorMsg = `[${remoteEntry.name}][${external.packageName}] Version '${external.version}' is not a valid version.`;
1620
+ if (config.strict.strictExternalVersion) {
1621
+ config.log.error(logStep, errorMsg);
1622
+ throw new NFError(`Could not process remote '${remoteEntry.name}'`);
1623
+ }
1624
+ if (config.profile.skipInvalidExternalVersions) {
1625
+ config.log.warn(logStep, `${errorMsg} Skipping external.`);
1626
+ return null;
1627
+ }
1628
+ config.log.warn(logStep, errorMsg);
1629
+ return ports.versionCheck.smallestVersion(external.requiredVersion);
1630
+ }
1631
+ function sharedExternalContext(remoteEntry, sharedInfo, tag) {
1632
+ const scopeType = ports.sharedExternalsRepo.scopeType(sharedInfo.shareScope);
1633
+ const remote = {
1634
+ name: remoteEntry.name,
1635
+ bundle: sharedInfo.bundle,
1636
+ strictVersion: sharedInfo.strictVersion,
1637
+ cached: false,
1638
+ requiredVersion: scopeType === "strict" ? tag : sharedInfo.requiredVersion || tag,
1639
+ ...sharedInfo.pool?.trim() ? { pool: sharedInfo.pool } : {},
1640
+ ...sharedInfo.dense ? { dense: true } : {},
1641
+ entries: sharedInfo.entries,
1642
+ ...sharedInfo.preload ? { preload: true } : {},
1643
+ ...sharedInfo.dev ? { dev: true } : {}
1644
+ };
1645
+ let stored;
1646
+ const readRecord = () => stored ??= ports.sharedExternalsRepo.tryGet(sharedInfo.packageName, sharedInfo.shareScope).get() ?? { dirty: false, versions: [] };
1647
+ return {
1648
+ tag,
1649
+ remote,
1650
+ readRecord,
1651
+ scopeType,
1652
+ assertSameVersionCompatibility(matchingVersion) {
1653
+ if (!remote.strictVersion) return;
1654
+ if (matchingVersion.remotes[0].requiredVersion === remote.requiredVersion) return;
1655
+ const errorMsg = `[${remoteEntry.name}][${sharedInfo.packageName}@${sharedInfo.version}] Required version-range '${remote.requiredVersion}' does not match cached version-range '${matchingVersion.remotes[0].requiredVersion}'`;
1656
+ if (config.strict.strictExternalSameVersionCompatibility) {
1657
+ config.log.error(logStep, errorMsg);
1658
+ throw new NFError(`Could not process remote '${remoteEntry.name}'`);
1659
+ }
1660
+ config.log.warn(logStep, errorMsg);
1661
+ },
1662
+ write() {
1663
+ ports.sharedExternalsRepo.addOrUpdate(
1664
+ sharedInfo.packageName,
1665
+ {
1666
+ ...readRecord(),
1667
+ versions: readRecord().versions.sort(
1668
+ (a, b) => ports.versionCheck.compare(b.tag, a.tag)
1669
+ )
1670
+ },
1671
+ sharedInfo.shareScope
1672
+ );
1673
+ }
1674
+ };
1675
+ }
1676
+ }
1677
+
1328
1678
  // src/lib/core/2.app/steps/get-remote-entries.ts
1329
1679
  function createGetRemoteEntries(config, ports) {
1680
+ const removeCachedRemoteEntries = createRemoveCachedRemoteEntries(ports);
1330
1681
  return (remotesOrManifestUrl = {}) => {
1331
1682
  const manifestPromise = config.manifestIntegrity ? ports.manifestProvider.provide(remotesOrManifestUrl, {
1332
1683
  integrity: config.manifestIntegrity
@@ -1334,7 +1685,7 @@ function createGetRemoteEntries(config, ports) {
1334
1685
  return manifestPromise.catch((e) => {
1335
1686
  config.log.error(1, "Could not fetch manifest.", e);
1336
1687
  return Promise.reject(new NFError("Failed to fetch manifest"));
1337
- }).then(addHostRemoteEntry).then(fetchRemoteEntries).then(removeSkippedRemotes).then(checkForSSE);
1688
+ }).then(addHostRemoteEntry).then(dropUnlistedRemotes).then(fetchRemoteEntries).then(removeSkippedRemotes).then(checkForSSE);
1338
1689
  };
1339
1690
  function addHostRemoteEntry(manifest) {
1340
1691
  if (!config.hostRemoteEntry) return manifest;
@@ -1344,6 +1695,26 @@ function createGetRemoteEntries(config, ports) {
1344
1695
  [name]: integrity ? { url, integrity } : url
1345
1696
  };
1346
1697
  }
1698
+ function dropUnlistedRemotes(manifest) {
1699
+ if (config.profile.mergeManifests !== false) return manifest;
1700
+ const listedUrls = new Set(
1701
+ Object.values(manifest).map((descriptor) => normalizeEntry(descriptor).url)
1702
+ );
1703
+ const isListed = (remoteName, info) => Object.hasOwn(manifest, remoteName) || listedUrls.has(storedEntryUrl(info));
1704
+ const unlisted = new Set(
1705
+ Object.entries(ports.remoteInfoRepo.getAll()).filter(([remoteName, info]) => !isListed(remoteName, info)).map(([remoteName]) => remoteName)
1706
+ );
1707
+ if (unlisted.size > 0)
1708
+ config.log.debug(
1709
+ 1,
1710
+ `Removing stored remotes the manifest doesn't list: ${[...unlisted].join(", ")}.`
1711
+ );
1712
+ removeCachedRemoteEntries(unlisted);
1713
+ return manifest;
1714
+ }
1715
+ function storedEntryUrl(info) {
1716
+ return join(info.scopeUrl, "remoteEntry.json");
1717
+ }
1347
1718
  function normalizeEntry(descriptor) {
1348
1719
  return typeof descriptor === "string" ? { url: descriptor } : descriptor;
1349
1720
  }
@@ -1368,7 +1739,7 @@ function createGetRemoteEntries(config, ports) {
1368
1739
  let isOverride = false;
1369
1740
  let skip = false;
1370
1741
  ports.remoteInfoRepo.tryGet(remoteName).ifPresent((cachedRemoteInfo) => {
1371
- if (config.profile.overrideCachedRemotes !== "never" && (remoteEntryUrl !== join(cachedRemoteInfo.scopeUrl, "remoteEntry.json") || config.profile.overrideCachedRemotesIfURLMatches)) {
1742
+ if (config.profile.overrideCachedRemotes !== "never" && (remoteEntryUrl !== storedEntryUrl(cachedRemoteInfo) || config.profile.overrideCachedRemotesIfURLMatches)) {
1372
1743
  config.log.debug(1, `Overriding existing remote '${remoteName}' with '${remoteEntryUrl}'.`);
1373
1744
  isOverride = true;
1374
1745
  } else {
@@ -1436,19 +1807,20 @@ function compareStrings(a, b) {
1436
1807
 
1437
1808
  // src/lib/core/1.domain/externals/basis.ts
1438
1809
  var coverage = (remote) => Object.keys(remote.entries).length;
1439
- function isBetterBasis(candidate, basis) {
1810
+ function isBetterBasis(candidate, basis, preferDev = false) {
1811
+ if (preferDev && Boolean(basis.dev) !== Boolean(candidate.dev)) return Boolean(candidate.dev);
1440
1812
  if (basis.cached !== candidate.cached) return candidate.cached;
1441
1813
  const byCoverage = coverage(candidate) - coverage(basis);
1442
1814
  return byCoverage === 0 ? compareStrings(candidate.name, basis.name) < 0 : byCoverage > 0;
1443
1815
  }
1444
- function addRemoteToVersion(version, remote, isHost = false) {
1816
+ function addRemoteToVersion(version, remote, isHost = false, preferDev = false) {
1445
1817
  if (isHost) {
1446
1818
  version.host = true;
1447
1819
  version.remotes.unshift(remote);
1448
1820
  return;
1449
1821
  }
1450
1822
  const basis = version.remotes[0];
1451
- if (basis && !version.host && isBetterBasis(remote, basis)) {
1823
+ if (basis && !version.host && isBetterBasis(remote, basis, preferDev)) {
1452
1824
  version.remotes.unshift(remote);
1453
1825
  return;
1454
1826
  }
@@ -1561,125 +1933,6 @@ function scopeRemotes(versions, remotes) {
1561
1933
  return rows.filter((v) => v.remotes.length > 0);
1562
1934
  }
1563
1935
 
1564
- // src/lib/core/2.app/steps/store-remote-entry.ts
1565
- function createRemoveCachedRemoteEntries(ports) {
1566
- return (remoteNames) => {
1567
- if (remoteNames.size === 0) return;
1568
- for (const remoteName of remoteNames) {
1569
- ports.remoteInfoRepo.remove(remoteName);
1570
- ports.scopedExternalsRepo.remove(remoteName);
1571
- ports.sharedChunksRepo.remove(remoteName);
1572
- }
1573
- ports.sharedExternalsRepo.removeFromAllScopes(remoteNames);
1574
- };
1575
- }
1576
- function createStoreRemoteEntry(config, ports, logStep) {
1577
- return (remoteEntry, onSharedExternal) => {
1578
- addRemoteInfoToStorage(remoteEntry);
1579
- addExternalsToStorage(remoteEntry, onSharedExternal);
1580
- addSharedChunksToStorage(remoteEntry);
1581
- };
1582
- function addRemoteInfoToStorage({ name, url, exposes, integrity }) {
1583
- ports.remoteInfoRepo.addOrUpdate(name, {
1584
- scopeUrl: getScope(url),
1585
- exposes: Object.values(exposes ?? []).map((m) => ({
1586
- moduleName: m.key,
1587
- file: m.outFileName
1588
- })),
1589
- ...integrity ? { integrity } : {}
1590
- });
1591
- }
1592
- function addExternalsToStorage(remoteEntry, onSharedExternal) {
1593
- remoteEntry.shared.forEach((external) => {
1594
- const tag = resolveVersion(remoteEntry, external);
1595
- if (tag === null) return;
1596
- if (external.singleton) {
1597
- if (external.requiredVersion && !ports.versionCheck.isCompatible(tag, external.requiredVersion))
1598
- config.log.warn(
1599
- logStep,
1600
- `[${remoteEntry.name}][${external.packageName}] requiredVersion '${external.requiredVersion}' excludes its own version '${tag}'; '${tag}' is still accepted for it.`
1601
- );
1602
- onSharedExternal(remoteEntry, external, sharedExternalContext(remoteEntry, external, tag));
1603
- } else {
1604
- addScopedExternal(remoteEntry, external, tag);
1605
- }
1606
- });
1607
- }
1608
- function addSharedChunksToStorage(remoteEntry) {
1609
- if (!remoteEntry.chunks) return;
1610
- config.log.debug(
1611
- logStep,
1612
- `Adding chunks for remote "${remoteEntry.name}", bundles: [${Object.keys(remoteEntry.chunks).join(", ")}]`
1613
- );
1614
- Object.entries(remoteEntry.chunks).forEach(([bundleName, chunks]) => {
1615
- ports.sharedChunksRepo.addOrReplace(remoteEntry.name, bundleName, chunks);
1616
- });
1617
- }
1618
- function addScopedExternal(remoteEntry, sharedInfo, tag) {
1619
- ports.scopedExternalsRepo.addExternal(remoteEntry.name, sharedInfo.packageName, {
1620
- tag,
1621
- bundle: sharedInfo.bundle,
1622
- entries: sharedInfo.entries
1623
- });
1624
- }
1625
- function resolveVersion(remoteEntry, external) {
1626
- if (external.version && ports.versionCheck.isValidSemver(external.version)) {
1627
- return external.version;
1628
- }
1629
- const errorMsg = `[${remoteEntry.name}][${external.packageName}] Version '${external.version}' is not a valid version.`;
1630
- if (config.strict.strictExternalVersion) {
1631
- config.log.error(logStep, errorMsg);
1632
- throw new NFError(`Could not process remote '${remoteEntry.name}'`);
1633
- }
1634
- if (config.profile.skipInvalidExternalVersions) {
1635
- config.log.warn(logStep, `${errorMsg} Skipping external.`);
1636
- return null;
1637
- }
1638
- config.log.warn(logStep, errorMsg);
1639
- return ports.versionCheck.smallestVersion(external.requiredVersion);
1640
- }
1641
- function sharedExternalContext(remoteEntry, sharedInfo, tag) {
1642
- const scopeType = ports.sharedExternalsRepo.scopeType(sharedInfo.shareScope);
1643
- const remote = {
1644
- name: remoteEntry.name,
1645
- bundle: sharedInfo.bundle,
1646
- strictVersion: sharedInfo.strictVersion,
1647
- cached: false,
1648
- requiredVersion: scopeType === "strict" ? tag : sharedInfo.requiredVersion || tag,
1649
- ...sharedInfo.pool?.trim() ? { pool: sharedInfo.pool } : {},
1650
- entries: sharedInfo.entries
1651
- };
1652
- let stored;
1653
- const readRecord = () => stored ??= ports.sharedExternalsRepo.tryGet(sharedInfo.packageName, sharedInfo.shareScope).get() ?? { dirty: false, versions: [] };
1654
- return {
1655
- tag,
1656
- remote,
1657
- readRecord,
1658
- scopeType,
1659
- assertSameVersionCompatibility(matchingVersion) {
1660
- if (!remote.strictVersion) return;
1661
- if (matchingVersion.remotes[0].requiredVersion === remote.requiredVersion) return;
1662
- const errorMsg = `[${remoteEntry.name}][${sharedInfo.packageName}@${sharedInfo.version}] Required version-range '${remote.requiredVersion}' does not match cached version-range '${matchingVersion.remotes[0].requiredVersion}'`;
1663
- if (config.strict.strictExternalSameVersionCompatibility) {
1664
- config.log.error(logStep, errorMsg);
1665
- throw new NFError(`Could not process remote '${remoteEntry.name}'`);
1666
- }
1667
- config.log.warn(logStep, errorMsg);
1668
- },
1669
- write() {
1670
- ports.sharedExternalsRepo.addOrUpdate(
1671
- sharedInfo.packageName,
1672
- {
1673
- ...readRecord(),
1674
- versions: readRecord().versions.sort((a, b) => ports.versionCheck.compare(b.tag, a.tag))
1675
- },
1676
- sharedInfo.shareScope
1677
- );
1678
- }
1679
- };
1680
- }
1681
- }
1682
-
1683
1936
  // src/lib/core/2.app/steps/process-remote-entries.ts
1684
1937
  function createProcessRemoteEntries(config, ports) {
1685
1938
  const storeRemoteEntry = createStoreRemoteEntry(config, ports, 2);
@@ -1725,7 +1978,12 @@ function createProcessRemoteEntries(config, ports) {
1725
1978
  const matchingVersion = findVersionForTag(cached.versions, tag);
1726
1979
  if (matchingVersion) {
1727
1980
  assertSameVersionCompatibility(matchingVersion);
1728
- addRemoteToVersion(matchingVersion, remote, !matchingVersion.host && !!remoteEntry?.host);
1981
+ addRemoteToVersion(
1982
+ matchingVersion,
1983
+ remote,
1984
+ !matchingVersion.host && !!remoteEntry?.host,
1985
+ config.profile.enableDebugging
1986
+ );
1729
1987
  } else {
1730
1988
  cached.versions.push({
1731
1989
  tag,
@@ -1847,6 +2105,7 @@ function createDetermineSharedExternals(config, ports) {
1847
2105
  if (!sharedVersion) {
1848
2106
  let leastExtraDownloads = Number.MAX_VALUE;
1849
2107
  let leastTears = Number.MAX_VALUE;
2108
+ let leaderShared = false;
1850
2109
  const selfServing = new Map(
1851
2110
  external.versions.map((v) => {
1852
2111
  const groups = /* @__PURE__ */ new Map();
@@ -1869,16 +2128,19 @@ function createDetermineSharedExternals(config, ports) {
1869
2128
  );
1870
2129
  external.versions.forEach((vA) => {
1871
2130
  const extraDownloads = external.versions.reduce((sum, vB) => sum + costOf(vB, vA.tag), 0);
2131
+ const alreadyShared = vA.action === "share" && !!vA.remotes[0]?.cached;
1872
2132
  if (extraDownloads < leastExtraDownloads) {
1873
2133
  leastExtraDownloads = extraDownloads;
1874
2134
  leastTears = uncoveredTears(external, vA, accepts);
2135
+ leaderShared = alreadyShared;
1875
2136
  sharedVersion = vA;
1876
2137
  return;
1877
2138
  }
1878
- if (extraDownloads > leastExtraDownloads) return;
2139
+ if (extraDownloads > leastExtraDownloads || leaderShared) return;
1879
2140
  const tears = uncoveredTears(external, vA, accepts);
1880
- if (tears < leastTears) {
2141
+ if (alreadyShared || tears < leastTears) {
1881
2142
  leastTears = tears;
2143
+ leaderShared = alreadyShared;
1882
2144
  sharedVersion = vA;
1883
2145
  }
1884
2146
  });
@@ -1890,28 +2152,81 @@ function createDetermineSharedExternals(config, ports) {
1890
2152
  }
1891
2153
  }
1892
2154
 
2155
+ // src/lib/utils/union-find.ts
2156
+ function unionFind() {
2157
+ const parent = /* @__PURE__ */ new Map();
2158
+ const find = (node) => {
2159
+ for (let up = parent.get(node); up !== void 0; up = parent.get(node)) {
2160
+ const grand = parent.get(up);
2161
+ if (grand === void 0) return up;
2162
+ parent.set(node, grand);
2163
+ node = grand;
2164
+ }
2165
+ return node;
2166
+ };
2167
+ const union = (a, b) => {
2168
+ const rootA = find(a);
2169
+ const rootB = find(b);
2170
+ if (rootA !== rootB) parent.set(rootB, rootA);
2171
+ };
2172
+ return { find, union };
2173
+ }
2174
+
1893
2175
  // src/lib/core/1.domain/externals/specifier.ts
1894
- function owningPackage(name) {
2176
+ function npmPackageOf(name) {
1895
2177
  const depth = name.startsWith("@") ? 2 : 1;
1896
2178
  let cut = -1;
1897
2179
  for (let seen = 0; seen < depth; seen++) {
1898
2180
  cut = name.indexOf("/", cut + 1);
1899
- if (cut === -1) return void 0;
2181
+ if (cut === -1) return name;
1900
2182
  }
1901
2183
  return name.slice(0, cut);
1902
2184
  }
1903
- var packageOf = (name) => owningPackage(name) ?? name;
2185
+ function packageOfIn(scope, loading = []) {
2186
+ if (!declaresLibrary(scope, loading)) return npmPackageOf;
2187
+ const { find, union } = unionFind();
2188
+ const shortest = /* @__PURE__ */ new Map();
2189
+ for (const [name, copy] of copiesIn(scope, loading)) {
2190
+ const anchor = anchorOf(name, copy);
2191
+ for (const specifier in copy.entries) {
2192
+ const best = shorter(
2193
+ shortest.get(find(anchor)) ?? anchor,
2194
+ shortest.get(find(specifier)) ?? specifier
2195
+ );
2196
+ union(anchor, specifier);
2197
+ shortest.set(find(anchor), best);
2198
+ }
2199
+ }
2200
+ return (specifier) => {
2201
+ const npm = npmPackageOf(specifier);
2202
+ return shortest.get(find(specifier)) ?? shortest.get(find(npm)) ?? npm;
2203
+ };
2204
+ }
2205
+ var shorter = (a, b) => b.length < a.length || b.length === a.length && compareStrings(b, a) < 0 ? b : a;
2206
+ function declaresLibrary(scope, loading) {
2207
+ const isLibrary = (name, copies) => npmPackageOf(name) !== name && copies.some((copy) => copy.dense);
2208
+ return loading.some(([name, copy]) => isLibrary(name, [copy])) || Object.entries(scope).some(
2209
+ ([name, external]) => external.versions.some((version) => isLibrary(name, version.remotes))
2210
+ );
2211
+ }
2212
+ var anchorOf = (name, copy) => copy.dense ? name : npmPackageOf(name);
2213
+ function* copiesIn(scope, loading) {
2214
+ yield* loading;
2215
+ for (const [name, external] of Object.entries(scope))
2216
+ for (const version of external.versions) for (const copy of version.remotes) yield [name, copy];
2217
+ }
1904
2218
  var SpecifierTags = class extends Map {
1905
- packages = /* @__PURE__ */ new Map();
1906
- constructor(entries = []) {
2219
+ constructor(packageOf, entries = []) {
1907
2220
  super();
2221
+ this.packageOf = packageOf;
1908
2222
  for (const [specifier, tag] of entries) this.set(specifier, tag);
1909
2223
  }
2224
+ packageOf;
2225
+ packages = /* @__PURE__ */ new Map();
1910
2226
  set(specifier, tag) {
1911
2227
  super.set(specifier, tag);
1912
- const pkg = owningPackage(specifier);
1913
- if (pkg === void 0) this.packages.set(specifier, tag);
1914
- else if (!this.packages.has(pkg)) this.packages.set(pkg, tag);
2228
+ const pkg = this.packageOf(specifier);
2229
+ if (pkg === specifier || !this.packages.has(pkg)) this.packages.set(pkg, tag);
1915
2230
  return this;
1916
2231
  }
1917
2232
  clear() {
@@ -1919,10 +2234,10 @@ var SpecifierTags = class extends Map {
1919
2234
  this.packages.clear();
1920
2235
  }
1921
2236
  pinnedTag(specifier) {
1922
- return this.get(specifier) ?? this.packages.get(owningPackage(specifier) ?? specifier);
2237
+ return this.get(specifier) ?? this.packages.get(this.packageOf(specifier));
1923
2238
  }
1924
2239
  };
1925
- function groupByPackage(items, nameOf) {
2240
+ function groupByPackage(items, nameOf, packageOf) {
1926
2241
  const packages = /* @__PURE__ */ new Map();
1927
2242
  for (const item of items) {
1928
2243
  const pkg = packageOf(nameOf(item));
@@ -1936,14 +2251,11 @@ function groupByPackage(items, nameOf) {
1936
2251
  // src/lib/core/1.domain/pooling/builds.ts
1937
2252
  function copiesByRemote(members) {
1938
2253
  const shipped = /* @__PURE__ */ new Map();
1939
- for (const member of members) {
1940
- const seen = /* @__PURE__ */ new Set();
1941
- for (const version of member.external.versions)
1942
- for (const meta of version.remotes) {
1943
- if (seen.has(meta.name)) continue;
1944
- seen.add(meta.name);
1945
- let copies = shipped.get(meta.name);
1946
- if (!copies) shipped.set(meta.name, copies = []);
2254
+ for (const member of members)
2255
+ for (const [remote, records] of recordsByRemote(member)) {
2256
+ let copies = shipped.get(remote);
2257
+ if (!copies) shipped.set(remote, copies = []);
2258
+ for (const { version, meta } of records)
1947
2259
  copies.push({
1948
2260
  member: member.name,
1949
2261
  tag: version.tag,
@@ -1952,13 +2264,22 @@ function copiesByRemote(members) {
1952
2264
  host: version.host && meta === version.remotes[0],
1953
2265
  specifiers: Object.keys(meta.entries)
1954
2266
  });
1955
- }
1956
- }
2267
+ }
1957
2268
  return shipped;
1958
2269
  }
2270
+ function recordsByRemote(member) {
2271
+ const records = /* @__PURE__ */ new Map();
2272
+ for (const version of member.external.versions)
2273
+ for (const meta of version.remotes) {
2274
+ const mine = records.get(meta.name);
2275
+ if (!mine) records.set(meta.name, [{ version, meta }]);
2276
+ else if (mine[0].version.tag === version.tag) mine.push({ version, meta });
2277
+ }
2278
+ return records;
2279
+ }
1959
2280
  var specifierCount = (copies) => copies.reduce((n, copy) => n + copy.specifiers.length, 0);
1960
- function buildOf(owner, copies) {
1961
- const tags = new SpecifierTags();
2281
+ function buildOf(owner, copies, packageOf) {
2282
+ const tags = new SpecifierTags(packageOf);
1962
2283
  const tagByMember = /* @__PURE__ */ new Map();
1963
2284
  for (const copy of copies) {
1964
2285
  for (const specifier of copy.specifiers)
@@ -2000,12 +2321,14 @@ function unwitnessedGap(copies, tags, builds) {
2000
2321
  function elect(input) {
2001
2322
  const shipped = copiesByRemote(input.members);
2002
2323
  const builds = /* @__PURE__ */ new Map();
2003
- for (const [owner, copies] of shipped) builds.set(owner, buildOf(owner, copies));
2324
+ for (const [owner, copies] of shipped) builds.set(owner, buildOf(owner, copies, input.packageOf));
2004
2325
  const pool = {
2005
2326
  ...input,
2006
2327
  shipped,
2007
2328
  builds,
2008
- packages: new Map([...shipped].map(([owner, copies]) => [owner, packageCopies(owner, copies)])),
2329
+ packages: new Map(
2330
+ [...shipped].map(([owner, copies]) => [owner, packageCopies(owner, copies, input.packageOf)])
2331
+ ),
2009
2332
  remotes: [...shipped.keys()],
2010
2333
  servesAt: (remote, tags) => serves(shipped.get(remote), tags, input.acceptsTag),
2011
2334
  agreesAt: (remote, tags) => agrees(shipped.get(remote), tags)
@@ -2068,7 +2391,7 @@ function roundOne(pool, hostRemote) {
2068
2391
  (c) => c.build.owner === pool.previousWinner ? 1 : 0
2069
2392
  ]);
2070
2393
  const winner = round1Winner.build.owner;
2071
- const globalTags = new SpecifierTags(round1Winner.build.tags);
2394
+ const globalTags = new SpecifierTags(pool.packageOf, round1Winner.build.tags);
2072
2395
  const globalRemotes = /* @__PURE__ */ new Set([winner, ...round1Winner.served]);
2073
2396
  const pending = remotes.filter((r) => !globalRemotes.has(r));
2074
2397
  return { winner, globalTags, globalRemotes, extensions: /* @__PURE__ */ new Set(), subpools: [], pending };
@@ -2125,7 +2448,7 @@ function addExtensions(pool, state) {
2125
2448
  for (const s of offer.specifiers) globalTags.set(s, offer.tag);
2126
2449
  }
2127
2450
  }
2128
- function packageCopies(owner, copies) {
2451
+ function packageCopies(owner, copies, packageOf) {
2129
2452
  const packages = /* @__PURE__ */ new Map();
2130
2453
  for (const copy of copies)
2131
2454
  for (const s of copy.specifiers) {
@@ -2167,7 +2490,7 @@ function settle(pool, state) {
2167
2490
  const dropped = new Set([...extensions].filter((pkg) => !publishedWhole(pool, state, pkg)));
2168
2491
  if (dropped.size === 0) return demoted;
2169
2492
  for (const pkg of dropped) extensions.delete(pkg);
2170
- const kept = [...globalTags].filter(([s]) => !dropped.has(packageOf(s)));
2493
+ const kept = [...globalTags].filter(([s]) => !dropped.has(pool.packageOf(s)));
2171
2494
  globalTags.clear();
2172
2495
  for (const [s, tag] of kept) globalTags.set(s, tag);
2173
2496
  for (const remote of globalRemotes)
@@ -2183,7 +2506,7 @@ function settle(pool, state) {
2183
2506
  }
2184
2507
  }
2185
2508
  function publishedWhole(pool, state, pkg) {
2186
- const published = new Set([...state.globalTags.keys()].filter((s) => packageOf(s) === pkg));
2509
+ const published = new Set([...state.globalTags.keys()].filter((s) => pool.packageOf(s) === pkg));
2187
2510
  const tag = state.globalTags.pinnedTag(pkg);
2188
2511
  return [...state.globalRemotes].some((remote) => {
2189
2512
  const copy = pool.packages.get(remote).get(pkg);
@@ -2232,24 +2555,6 @@ function placeRemotes(globalRemotes, subpools, self, missOf2) {
2232
2555
  }
2233
2556
 
2234
2557
  // src/lib/core/1.domain/pooling/membership.ts
2235
- function unionFind() {
2236
- const parent = /* @__PURE__ */ new Map();
2237
- const find = (node) => {
2238
- for (let up = parent.get(node); up !== void 0; up = parent.get(node)) {
2239
- const grand = parent.get(up);
2240
- if (grand === void 0) return up;
2241
- parent.set(node, grand);
2242
- node = grand;
2243
- }
2244
- return node;
2245
- };
2246
- const union = (a, b) => {
2247
- const rootA = find(a);
2248
- const rootB = find(b);
2249
- if (rootA !== rootB) parent.set(rootB, rootA);
2250
- };
2251
- return { find, union };
2252
- }
2253
2558
  var extNode = (name) => `ext\0${name}`;
2254
2559
  var labelNode = (label) => `label\0${label}`;
2255
2560
  var labelOf = (pool) => pool?.trim() || void 0;
@@ -2262,13 +2567,13 @@ function labelsIn(sharedExternals) {
2262
2567
  );
2263
2568
  return labelsOf;
2264
2569
  }
2265
- function labelledComponents(labelsOf) {
2570
+ function labelledComponents(labelsOf, packageOf) {
2266
2571
  const { find, union } = unionFind();
2267
2572
  for (const [name, labels] of labelsOf)
2268
2573
  for (const label of labels) union(extNode(name), labelNode(label));
2269
2574
  for (const name of labelsOf.keys()) {
2270
- const owner = owningPackage(name);
2271
- if (owner !== void 0) union(extNode(name), extNode(owner));
2575
+ const owner = packageOf(name);
2576
+ if (owner !== name) union(extNode(name), extNode(owner));
2272
2577
  }
2273
2578
  const byComponent = /* @__PURE__ */ new Map();
2274
2579
  for (const name of labelsOf.keys()) {
@@ -2278,11 +2583,11 @@ function labelledComponents(labelsOf) {
2278
2583
  }
2279
2584
  return [...byComponent.values()].filter((names) => names.some((n) => labelsOf.get(n).length > 0));
2280
2585
  }
2281
- function buildPools(sharedExternals) {
2586
+ function buildPools(sharedExternals, packageOf = packageOfIn(sharedExternals)) {
2282
2587
  const labelsOf = labelsIn(sharedExternals);
2283
2588
  const pools = /* @__PURE__ */ new Map();
2284
2589
  const labelledAlone = [];
2285
- for (const names of labelledComponents(labelsOf)) {
2590
+ for (const names of labelledComponents(labelsOf, packageOf)) {
2286
2591
  if (names.length < 2) labelledAlone.push(names[0]);
2287
2592
  else {
2288
2593
  const members = names.map((name) => ({ name, external: sharedExternals[name] }));
@@ -2292,9 +2597,9 @@ function buildPools(sharedExternals) {
2292
2597
  );
2293
2598
  }
2294
2599
  }
2295
- return { pools, labelledAlone };
2600
+ return { pools, labelledAlone, packageOf };
2296
2601
  }
2297
- function pooledPackagesWith(sharedExternals, copies) {
2602
+ function pooledPackagesWith(sharedExternals, copies, packageOf) {
2298
2603
  const labelsOf = labelsIn(sharedExternals);
2299
2604
  for (const { name, pool } of copies) {
2300
2605
  const labels = labelsOf.get(name) ?? [];
@@ -2302,7 +2607,7 @@ function pooledPackagesWith(sharedExternals, copies) {
2302
2607
  labelsOf.set(name, label === void 0 ? labels : [...labels, label]);
2303
2608
  }
2304
2609
  return new Set(
2305
- labelledComponents(labelsOf).filter((names) => names.length > 1).flatMap((names) => names.map(packageOf))
2610
+ labelledComponents(labelsOf, packageOf).filter((names) => names.length > 1).flatMap((names) => names.map(packageOf))
2306
2611
  );
2307
2612
  }
2308
2613
  function mostDeclaredLabel(members, labelsOf) {
@@ -2348,7 +2653,7 @@ function memberRecord(member, pool, compare) {
2348
2653
  const row = { tag, host: false, action, remotes: [meta] };
2349
2654
  placed.push(row);
2350
2655
  if (meta.name !== pool.winner) return;
2351
- winnerRow = row;
2656
+ winnerRow ??= row;
2352
2657
  row.host = pool.winnerIsHost;
2353
2658
  };
2354
2659
  for (const version of member.external.versions)
@@ -2362,9 +2667,9 @@ function memberRecord(member, pool, compare) {
2362
2667
  place(version.tag, "skip", { ...meta, servedBy: placement.owner });
2363
2668
  else place(version.tag, "scope", { ...meta, poolCause: placement.cause });
2364
2669
  }
2670
+ const rank2 = (name) => name === pool.winner ? 0 : claimsGlobally(name) ? 1 : 2;
2365
2671
  const rows = mergeRows(placed, winnerRow);
2366
- for (const row of rows)
2367
- row.remotes.sort((a, b) => Number(!claimsGlobally(a.name)) - Number(!claimsGlobally(b.name)));
2672
+ for (const row of rows) row.remotes.sort((a, b) => rank2(a.name) - rank2(b.name));
2368
2673
  const order = { share: 0, skip: 1, scope: 2 };
2369
2674
  const newest = byTag(compare);
2370
2675
  const versions = rows.sort((a, b) => newest(a, b) || order[a.action] - order[b.action]);
@@ -2385,14 +2690,16 @@ function moveCopy(external, remote, move, compare) {
2385
2690
  if ("fromMap" in move) return recordFromMap(external, remote);
2386
2691
  const moved = [];
2387
2692
  const versions = external.versions.map((v) => {
2388
- const copy = v.remotes.find((r) => r.name === remote);
2389
- if (!copy) return v;
2390
- const { servedBy: _servedBy, ...rest } = copy;
2391
- const meta = { ...rest, cached: true, poolCause: move.cause };
2392
- if (v.action === "scope")
2393
- return { ...v, remotes: v.remotes.map((r) => r === copy ? meta : r) };
2394
- moved.push({ tag: v.tag, meta });
2395
- return { ...v, remotes: v.remotes.filter((r) => r !== copy) };
2693
+ const replaced = /* @__PURE__ */ new Map();
2694
+ for (const copy of v.remotes) {
2695
+ if (copy.name !== remote) continue;
2696
+ const { servedBy: _servedBy, ...rest } = copy;
2697
+ replaced.set(copy, { ...rest, cached: true, poolCause: move.cause });
2698
+ }
2699
+ if (replaced.size === 0) return v;
2700
+ if (v.action === "scope") return { ...v, remotes: v.remotes.map((r) => replaced.get(r) ?? r) };
2701
+ for (const meta of replaced.values()) moved.push({ tag: v.tag, meta });
2702
+ return { ...v, remotes: v.remotes.filter((r) => !replaced.has(r)) };
2396
2703
  }).filter((v) => v.remotes.length > 0);
2397
2704
  for (const { tag, meta } of moved) {
2398
2705
  const scoped = rowAt(versions, tag, "scope");
@@ -2405,10 +2712,10 @@ function recordFromMap(external, remote) {
2405
2712
  const opened = external.versions.find(
2406
2713
  (v) => v.action !== "skip" && v.remotes.some((r) => r.name === remote)
2407
2714
  );
2408
- const meta = { ...opened.remotes.find((r) => r.name === remote), cached: false };
2409
2715
  const joined = rowAt(external.versions, opened.tag, "skip");
2410
2716
  const into = joined ? { ...joined, remotes: [...joined.remotes] } : { ...opened, action: "skip", remotes: [] };
2411
- addRemoteToVersion(into, meta);
2717
+ for (const copy of opened.remotes)
2718
+ if (copy.name === remote) addRemoteToVersion(into, { ...copy, cached: false });
2412
2719
  const versions = external.versions.flatMap((v) => {
2413
2720
  if (v === joined) return [into];
2414
2721
  if (v !== opened) return [v];
@@ -2438,14 +2745,14 @@ function renamedRecords(scope, pools) {
2438
2745
  // src/lib/core/1.domain/pooling/plan.ts
2439
2746
  function planElection(scope, poolable) {
2440
2747
  if (!poolable || !Object.values(scope).some((external) => external.dirty) || !scopeHasPoolState(scope))
2441
- return { pools: /* @__PURE__ */ new Map(), stripped: /* @__PURE__ */ new Map(), labelledAlone: [] };
2442
- const { pools, labelledAlone } = buildPools(scope);
2748
+ return { pools: /* @__PURE__ */ new Map(), stripped: /* @__PURE__ */ new Map(), labelledAlone: [], packageOf: npmPackageOf };
2749
+ const { pools, labelledAlone, packageOf } = buildPools(scope);
2443
2750
  const pooled = new Set([...pools.values()].flatMap((members) => members.map((m) => m.name)));
2444
2751
  const stripped = /* @__PURE__ */ new Map();
2445
2752
  for (const [name, external] of Object.entries(scope))
2446
2753
  if (!pooled.has(name) && hasPoolResults(external))
2447
2754
  stripped.set(name, { ...withoutPoolResults(external), dirty: true });
2448
- return { pools, stripped, labelledAlone };
2755
+ return { pools, stripped, labelledAlone, packageOf };
2449
2756
  }
2450
2757
 
2451
2758
  // src/lib/core/2.app/steps/pooling/pool-shared-externals.ts
@@ -2459,7 +2766,7 @@ function createPoolSharedExternals(config, ports) {
2459
2766
  const plan = planElection(sharedExternals, repo.scopeType(scope) !== "strict");
2460
2767
  logPlan(plan, sharedExternals, scope);
2461
2768
  for (const [poolName, members] of plan.pools)
2462
- for (const [name, record] of poolRecords(poolName, members, scope))
2769
+ for (const [name, record] of poolRecords(poolName, members, plan.packageOf, scope))
2463
2770
  repo.addOrUpdate(name, record, scope);
2464
2771
  for (const [name, external] of plan.stripped) repo.addOrUpdate(name, external, scope);
2465
2772
  } catch (error) {
@@ -2494,9 +2801,10 @@ function createPoolSharedExternals(config, ports) {
2494
2801
  `[${scope}] '${name}' has a 'pool' label that joins no other external; likely a typo or a missing sibling.`
2495
2802
  );
2496
2803
  }
2497
- function poolRecords(poolName, members, scope) {
2804
+ function poolRecords(poolName, members, packageOf, scope) {
2498
2805
  const election = elect({
2499
2806
  members,
2807
+ packageOf,
2500
2808
  acceptsTag: createAcceptsTag(ports.versionCheck.isCompatible, compare),
2501
2809
  compare,
2502
2810
  previousWinner: previousWinner(members),
@@ -2557,12 +2865,13 @@ function missWarning(remote, miss, placed, counts) {
2557
2865
 
2558
2866
  // src/lib/core/1.domain/externals/serving.ts
2559
2867
  var byServingRank = (a, b) => Number(b.host) - Number(a.host) || a.downloads - b.downloads || a.fallbacks - b.fallbacks || Number(b.rootBasis) - Number(a.rootBasis) || compareStrings(a.remote, b.remote);
2560
- var packagesOf = (scope) => groupByPackage(Object.keys(scope), (name) => name);
2868
+ var packagesOf = (scope) => groupByPackage(Object.keys(scope), (name) => name, packageOfIn(scope));
2561
2869
  var isPooled = (externals) => externals.some(([, e]) => e.poolName !== void 0);
2562
- function servingBuildOf(externals, accepts) {
2870
+ function servingBuildOf(pkg, externals, accepts) {
2563
2871
  if (externals.length === 0) return void 0;
2564
- const pkg = packageOf(externals[0][0]);
2565
- const rootRows = shareRows(externals.find(([name]) => name === pkg)?.[1]);
2872
+ const rootRows = shareRows(externals.find(([name]) => name === pkg)?.[1]).filter(
2873
+ (row) => row.remotes.some((copy) => pkg in copy.entries)
2874
+ );
2566
2875
  const rows = rootRows.length > 0 ? rootRows : externals.flatMap(([, e]) => shareRows(e));
2567
2876
  if (isPooled(externals)) return pooledBuild(externals, rows);
2568
2877
  const consumers = consumersOf(externals);
@@ -2591,11 +2900,12 @@ function cheapestBuild(field, costOf) {
2591
2900
  }
2592
2901
  function shareServingCopies(external, serving) {
2593
2902
  for (const row of external.versions) {
2594
- const copy = row.remotes.find((c) => c.name === serving.remote);
2595
- if (row.action !== "skip" || !copy || rowAt(external.versions, row.tag, "share")) continue;
2903
+ if (row.action !== "skip" || rowAt(external.versions, row.tag, "share")) continue;
2904
+ const own = row.remotes.filter((c) => c.name === serving.remote);
2905
+ if (own.length === 0) continue;
2596
2906
  row.action = "share";
2597
- if (row.remotes[0] !== copy) row.host = false;
2598
- row.remotes = [copy, ...row.remotes.filter((c) => c !== copy)];
2907
+ if (row.remotes[0] !== own[0]) row.host = false;
2908
+ row.remotes = [...own, ...row.remotes.filter((c) => c.name !== serving.remote)];
2599
2909
  }
2600
2910
  }
2601
2911
  function followServingBuild(external, serving, accepts) {
@@ -2640,20 +2950,20 @@ function shareRows(external) {
2640
2950
  return external?.versions.filter((v) => v.action === "share") ?? [];
2641
2951
  }
2642
2952
  function buildsOf(rows, rootRows, consumers) {
2643
- const candidates = /* @__PURE__ */ new Map();
2953
+ const builds = /* @__PURE__ */ new Map();
2644
2954
  for (const row of rows)
2645
2955
  for (const copy of row.remotes) {
2646
2956
  const key = `${row.tag}|${copy.name}`;
2647
- if (copy.servedBy || candidates.has(key) || shipsTwoTags(consumers.get(copy.name))) continue;
2957
+ if (copy.servedBy || builds.has(key) || shipsTwoTags(consumers.get(copy.name))) continue;
2648
2958
  const basis = copy === row.remotes[0];
2649
- candidates.set(key, {
2959
+ builds.set(key, {
2650
2960
  remote: copy.name,
2651
2961
  tag: row.tag,
2652
2962
  host: basis && row.host,
2653
2963
  rootBasis: basis && rootRows.includes(row)
2654
2964
  });
2655
2965
  }
2656
- return [...candidates.values()];
2966
+ return [...builds.values()];
2657
2967
  }
2658
2968
  function pooledBuild(externals, rows) {
2659
2969
  const winner = externals.find(([, e]) => e.poolWinner !== void 0)?.[1].poolWinner;
@@ -2662,10 +2972,7 @@ function pooledBuild(externals, rows) {
2662
2972
  );
2663
2973
  const own = shipped.find((c) => c.remote === winner);
2664
2974
  if (own) return own;
2665
- const width = ({ remote, tag }) => externals.reduce((n, [, e]) => {
2666
- const copy = shareRows(e).find((row) => row.tag === tag)?.remotes.find((c) => c.name === remote);
2667
- return n + Object.keys(copy?.entries ?? {}).length;
2668
- }, 0);
2975
+ const width = ({ remote, tag }) => externals.flatMap(([, e]) => shareRows(e).find((row) => row.tag === tag)?.remotes ?? []).filter((copy) => copy.name === remote).reduce((n, copy) => n + Object.keys(copy.entries).length, 0);
2669
2976
  return shipped.map((c) => ({ c, width: width(c) })).sort((a, b) => b.width - a.width || compareStrings(a.c.remote, b.c.remote))[0]?.c;
2670
2977
  }
2671
2978
  function consumersOf(externals) {
@@ -2763,8 +3070,8 @@ function splitsPackage(placed, surface, tag, accepts) {
2763
3070
  });
2764
3071
  return placed.some(onMap) && (shipsTwoTags(placed) || placed.some((p) => !onMap(p) || uncovered(p)));
2765
3072
  }
2766
- function loadSplitsPackage(copies, claims, accepts) {
2767
- const root = claims.find(([specifier]) => specifier === packageOf(specifier))?.[1];
3073
+ function loadSplitsPackage(pkg, copies, claims, accepts) {
3074
+ const root = claims.find(([specifier]) => specifier === pkg)?.[1];
2768
3075
  const servingTag = root?.tag ?? claims[0][1].tag;
2769
3076
  const surface = new Map(
2770
3077
  claims.map(([specifier, { tag }]) => [specifier, root ? tag : servingTag])
@@ -2810,7 +3117,7 @@ function createDecideServingBuilds(config, ports) {
2810
3117
  }
2811
3118
  };
2812
3119
  function decidePackage(shareScope, pkg, externals, accepts) {
2813
- const serving = servingBuildOf(externals, accepts);
3120
+ const serving = servingBuildOf(pkg, externals, accepts);
2814
3121
  const before = externals.map(([, external]) => shapeOf(external));
2815
3122
  const pooled = isPooled(externals);
2816
3123
  const toFollow = pooled ? void 0 : serving;
@@ -2896,7 +3203,6 @@ function committedClaims(externals, { shareScope, without }) {
2896
3203
  const publishes = (copy) => copy.name !== without && (shareScope !== GLOBAL_SCOPE || copy.cached);
2897
3204
  return claimTable(externals, publishes).claims;
2898
3205
  }
2899
- var claimsByPackage = (claims) => groupByPackage(claims, ([specifier]) => specifier);
2900
3206
  function versionClaims(version, servingBuild) {
2901
3207
  const claims = /* @__PURE__ */ new Map();
2902
3208
  const claim = (specifier, copy) => {
@@ -2907,7 +3213,7 @@ function versionClaims(version, servingBuild) {
2907
3213
  return claims;
2908
3214
  }
2909
3215
 
2910
- // node_modules/.pnpm/@softarc+native-federation@4.8.0/node_modules/@softarc/native-federation/dist/lib/domain/core/build-notification-options.contract.js
3216
+ // node_modules/.pnpm/@softarc+native-federation@4.10.0/node_modules/@softarc/native-federation/dist/lib/domain/core/build-notification-options.contract.js
2911
3217
  var BuildNotificationType = /* @__PURE__ */ ((BuildNotificationType2) => {
2912
3218
  BuildNotificationType2["COMPLETED"] = "federation-rebuild-complete";
2913
3219
  BuildNotificationType2["ERROR"] = "federation-rebuild-error";
@@ -2915,13 +3221,14 @@ var BuildNotificationType = /* @__PURE__ */ ((BuildNotificationType2) => {
2915
3221
  return BuildNotificationType2;
2916
3222
  })(BuildNotificationType || {});
2917
3223
 
2918
- // node_modules/.pnpm/@softarc+native-federation@4.8.0/node_modules/@softarc/native-federation/dist/lib/domain/core/chunk.js
3224
+ // node_modules/.pnpm/@softarc+native-federation@4.10.0/node_modules/@softarc/native-federation/dist/lib/domain/core/chunk.js
2919
3225
  var CHUNK_PREFIX = "@nf-internal";
3226
+ var SCRIPT_EXTENSION = /\.(m|c)?js$/;
2920
3227
  function toChunkImport(fileName) {
2921
3228
  if (fileName.startsWith("./")) {
2922
3229
  fileName = fileName.slice(2);
2923
3230
  }
2924
- const packageName = fileName.replace(/.(m|c)?js$/, "");
3231
+ const packageName = fileName.replace(SCRIPT_EXTENSION, "");
2925
3232
  return CHUNK_PREFIX + "/" + packageName;
2926
3233
  }
2927
3234
 
@@ -3311,16 +3618,99 @@ function shipsOnly(version, served) {
3311
3618
  return only;
3312
3619
  }
3313
3620
 
3621
+ // src/lib/core/2.app/steps/preload-hint.ts
3622
+ function createPreloadHint(log, browser, logStep) {
3623
+ const ignore = (error) => log.debug(logStep, "Ignored a failing preload hint.", error);
3624
+ return (collectUrls) => {
3625
+ if (!browser.preloadModules) return;
3626
+ try {
3627
+ const urls = collectUrls();
3628
+ if (urls.length === 0) return;
3629
+ void Promise.resolve(browser.preloadModules(urls)).catch(ignore);
3630
+ } catch (error) {
3631
+ ignore(error);
3632
+ }
3633
+ };
3634
+ }
3635
+
3636
+ // src/lib/core/1.domain/import-map/eager-preloads.ts
3637
+ function eagerPreloadUrls(importMap, candidates) {
3638
+ let mapped;
3639
+ const urls = /* @__PURE__ */ new Set();
3640
+ const bundlesAdded = /* @__PURE__ */ new Set();
3641
+ for (const { scopeUrl, entryFiles, bundle } of candidates) {
3642
+ mapped ??= mappedUrls(importMap);
3643
+ const entryUrls = entryFiles.map((file) => join(scopeUrl, file));
3644
+ const served = entryUrls.length > 0 && entryUrls.every((url) => mapped.has(url));
3645
+ if (!served) continue;
3646
+ entryUrls.forEach((url) => urls.add(url));
3647
+ if (!bundle) continue;
3648
+ const bundleKey = `${scopeUrl}
3649
+ ${bundle.name}`;
3650
+ if (bundlesAdded.has(bundleKey)) continue;
3651
+ bundlesAdded.add(bundleKey);
3652
+ bundle.chunkFiles.forEach((file) => urls.add(join(scopeUrl, file)));
3653
+ }
3654
+ return [...urls];
3655
+ }
3656
+ var mappedUrls = (importMap) => /* @__PURE__ */ new Set([
3657
+ ...Object.values(importMap.imports),
3658
+ ...Object.values(importMap.scopes ?? {}).flatMap((scope) => Object.values(scope))
3659
+ ]);
3660
+
3661
+ // src/lib/core/2.app/steps/collect-eager-preloads.ts
3662
+ function createCollectEagerPreloads(ports) {
3663
+ return (importMap) => eagerPreloadUrls(importMap, candidates());
3664
+ function* candidates() {
3665
+ for (const [remoteName, copy] of storedCopies()) {
3666
+ if (!copy.preload) continue;
3667
+ const scopeUrl = ports.remoteInfoRepo.tryGet(remoteName).get()?.scopeUrl;
3668
+ if (!scopeUrl) continue;
3669
+ yield {
3670
+ scopeUrl,
3671
+ entryFiles: Object.values(copy.entries),
3672
+ ...copy.bundle && {
3673
+ bundle: {
3674
+ name: copy.bundle,
3675
+ chunkFiles: ports.sharedChunksRepo.tryGet(remoteName, copy.bundle).orElse([])
3676
+ }
3677
+ }
3678
+ };
3679
+ }
3680
+ }
3681
+ function* storedCopies() {
3682
+ const shared = ports.sharedExternalsRepo;
3683
+ for (const shareScope of shared.getScopes())
3684
+ for (const external of Object.values(shared.getFromScope(shareScope)))
3685
+ for (const version of external.versions)
3686
+ for (const copy of version.remotes) yield [copy.name, copy];
3687
+ for (const [remoteName, externals] of Object.entries(ports.scopedExternalsRepo.getAll()))
3688
+ for (const copy of Object.values(externals)) yield [remoteName, copy];
3689
+ }
3690
+ }
3691
+
3314
3692
  // src/lib/core/2.app/steps/commit-changes.ts
3315
3693
  function createCommitChanges(config, ports) {
3316
- return (importMap, { markUndecided = false, ...browserOpts } = {}) => Promise.resolve(importMap).then((map) => addToBrowser(map, browserOpts)).then(() => {
3694
+ const preload = createPreloadHint(config.log, ports.browser, 5);
3695
+ const collectEagerPreloads = createCollectEagerPreloads(ports);
3696
+ return (importMap, { markUndecided = false, ...browserOpts } = {}) => Promise.resolve(importMap).then((map) => addToBrowser(map, browserOpts)).then((added) => {
3317
3697
  if (markUndecided) markUndecidedScopes();
3318
3698
  persistRepositoryChanges();
3699
+ preloadOnceAdded(added, importMap);
3319
3700
  });
3320
3701
  function addToBrowser(importMap, opts) {
3321
- ports.browser.setImportMapFn(importMap, opts);
3702
+ const added = ports.browser.setImportMapFn(importMap, opts);
3322
3703
  config.log.debug(5, "Added import map to browser.", importMap);
3323
- return importMap;
3704
+ return { added };
3705
+ }
3706
+ function preloadOnceAdded({ added }, importMap) {
3707
+ Promise.resolve(added).then(
3708
+ () => preload(() => collectEagerPreloads(importMap)),
3709
+ (error) => {
3710
+ config.log.error(5, "Could not add the import map.", error);
3711
+ return Promise.reject(error);
3712
+ }
3713
+ );
3324
3714
  }
3325
3715
  function markUndecidedScopes() {
3326
3716
  const repo = ports.sharedExternalsRepo;
@@ -3361,6 +3751,7 @@ function createRollbackChanges(config, ports) {
3361
3751
 
3362
3752
  // src/lib/core/2.app/steps/expose-module-loader.ts
3363
3753
  function createExposeModuleLoader(config, ports) {
3754
+ const preload = createPreloadHint(config.log, ports.browser, 6);
3364
3755
  const loadRemoteModule = (remoteName, exposedModule) => {
3365
3756
  try {
3366
3757
  if (!ports.remoteInfoRepo.contains(remoteName)) {
@@ -3372,6 +3763,7 @@ function createExposeModuleLoader(config, ports) {
3372
3763
  )
3373
3764
  );
3374
3765
  config.log.debug(6, `Loading initialized module '${remoteModuleUrl}'`);
3766
+ preload(() => ports.remoteInfoRepo.getModuleChunkUrls(remoteName, exposedModule));
3375
3767
  return ports.browser.importModule(remoteModuleUrl);
3376
3768
  } catch (error) {
3377
3769
  config.log.error(6, `Failed to load module ${join(remoteName, exposedModule)}: `, {
@@ -3382,7 +3774,15 @@ function createExposeModuleLoader(config, ports) {
3382
3774
  );
3383
3775
  }
3384
3776
  };
3385
- return () => Promise.resolve(loadRemoteModule);
3777
+ const preloadRemoteModule = (remoteName, exposedModule) => preload(() => {
3778
+ const url = ports.remoteInfoRepo.tryGetModule(remoteName, exposedModule);
3779
+ if (!url.isPresent()) {
3780
+ config.log.debug(6, `Nothing to preload for '${remoteName}/${exposedModule}'.`);
3781
+ return [];
3782
+ }
3783
+ return [url.get(), ...ports.remoteInfoRepo.getModuleChunkUrls(remoteName, exposedModule)];
3784
+ });
3785
+ return () => Promise.resolve({ loadRemoteModule, preloadRemoteModule });
3386
3786
  }
3387
3787
 
3388
3788
  // src/lib/utils/optional.ts
@@ -3522,18 +3922,19 @@ function createUpdateCache(config, ports) {
3522
3922
  function decidePackages(remoteEntry, pending) {
3523
3923
  const decisions = /* @__PURE__ */ new Map();
3524
3924
  const viewOf = loadViewOf(remoteEntry, pending);
3525
- for (const group of pendingPerPackage(pending)) {
3925
+ for (const group of pendingPerPackage(pending, viewOf)) {
3526
3926
  const decision = group[0].ctx.scopeType === "strict" ? { action: "share" } : decidePackage(remoteEntry, group, viewOf(group[0].external.shareScope));
3527
3927
  for (const item of group) decisions.set(item, decision);
3528
3928
  }
3529
3929
  scopeOpenedPackages(decisions);
3530
3930
  return decisions;
3531
3931
  }
3532
- function pendingPerPackage(pending) {
3932
+ function pendingPerPackage(pending, viewOf) {
3533
3933
  const packages = /* @__PURE__ */ new Map();
3534
3934
  for (const item of pending) {
3535
3935
  const { shareScope, packageName } = item.external;
3536
- const key = `${shareScope ?? GLOBAL_SCOPE}\0${packageOf(packageName)}`;
3936
+ const pkg = item.ctx.scopeType === "strict" ? packageName : viewOf(shareScope).packageOf(packageName);
3937
+ const key = `${shareScope ?? GLOBAL_SCOPE}\0${pkg}`;
3537
3938
  const group = packages.get(key);
3538
3939
  if (group) group.push(item);
3539
3940
  else packages.set(key, [item]);
@@ -3551,20 +3952,34 @@ function createUpdateCache(config, ports) {
3551
3952
  shareScope: scope,
3552
3953
  without: remoteEntry.name
3553
3954
  });
3554
- const claimsIn = claimsByPackage(claims);
3955
+ const packageOf = packageOfIn(record, loadingIn(pending, scope));
3956
+ const claimsIn = groupByPackage(claims, ([specifier]) => specifier, packageOf);
3555
3957
  let pooled;
3556
3958
  view = {
3959
+ packageOf,
3557
3960
  claims,
3558
3961
  claimsOf: (pkg) => claimsIn.get(pkg) ?? [],
3559
- inPool: (pkg) => (pooled ??= pooledPackagesWith(record, copiesIn(pending, scope))).has(pkg)
3962
+ inPool: (pkg) => {
3963
+ pooled ??= pooledPackagesWith(record, labelledCopiesIn(pending, scope), packageOf);
3964
+ return pooled.has(pkg);
3965
+ }
3560
3966
  };
3561
3967
  views.set(scope, view);
3562
3968
  }
3563
3969
  return view;
3564
3970
  };
3565
3971
  }
3566
- function copiesIn(pending, scope) {
3567
- return pending.filter(({ external }) => (external.shareScope ?? GLOBAL_SCOPE) === scope).map(({ external, ctx }) => ({ name: external.packageName, pool: ctx.remote.pool }));
3972
+ function inScope(pending, scope) {
3973
+ return pending.filter(({ external }) => (external.shareScope ?? GLOBAL_SCOPE) === scope);
3974
+ }
3975
+ function loadingIn(pending, scope) {
3976
+ return inScope(pending, scope).map(({ external, ctx }) => [external.packageName, ctx.remote]);
3977
+ }
3978
+ function labelledCopiesIn(pending, scope) {
3979
+ return inScope(pending, scope).map(({ external, ctx }) => ({
3980
+ name: external.packageName,
3981
+ pool: ctx.remote.pool
3982
+ }));
3568
3983
  }
3569
3984
  function scopeOpenedPackages(decisions) {
3570
3985
  if (![...decisions.values()].some((d) => d.action === "scope" && d.partlyServed)) return;
@@ -3573,15 +3988,16 @@ function createUpdateCache(config, ports) {
3573
3988
  decisions.set(item, { action: "scope", partlyServed: false });
3574
3989
  }
3575
3990
  function decidePackage(remoteEntry, group, view) {
3576
- const pkg = packageOf(group[0].external.packageName);
3991
+ const pkg = view.packageOf(group[0].external.packageName);
3577
3992
  const claims = view.claimsOf(pkg);
3578
3993
  if (claims.length === 0) return { action: "share" };
3579
3994
  const specifiers = group.flatMap(({ external }) => Object.keys(external.entries));
3580
3995
  const builds = specifiers.every((specifier) => view.claims.has(specifier)) ? new Set(specifiers.map((specifier) => view.claims.get(specifier).copy.name)) : void 0;
3581
3996
  const rejections = group.flatMap((item) => rejectionsOf(item, view.claims));
3582
3997
  if (rejections.length > 0) {
3583
- const fromTwoBuilds = builds !== void 0 && builds.size > 1;
3584
- for (const rejection of refused(group, rejections, fromTwoBuilds, claims, view.inPool(pkg)))
3998
+ const copies = group.map(({ ctx }) => ({ tag: ctx.tag, copy: ctx.remote }));
3999
+ const splits = builds !== void 0 && builds.size > 1 || loadSplitsPackage(pkg, copies, claims, accepts);
4000
+ for (const rejection of refused(rejections, splits, view.inPool(pkg)))
3585
4001
  reportIncompatible(remoteEntry, rejection);
3586
4002
  return { action: "scope", partlyServed: false };
3587
4003
  }
@@ -3602,9 +4018,7 @@ function createUpdateCache(config, ports) {
3602
4018
  return claim && !accepts(claim.tag, ctx.tag, ctx.remote.requiredVersion) ? [{ item, specifier, claim }] : [];
3603
4019
  });
3604
4020
  }
3605
- function refused(group, rejections, fromTwoBuilds, claims, pooled) {
3606
- const copies = group.map(({ ctx }) => ({ tag: ctx.tag, copy: ctx.remote }));
3607
- const splits = fromTwoBuilds || loadSplitsPackage(copies, claims, accepts);
4021
+ function refused(rejections, splits, pooled) {
3608
4022
  const first = /* @__PURE__ */ new Map();
3609
4023
  for (const rejection of rejections)
3610
4024
  if (!first.has(rejection.item) && (pooled || !splits || electionKeeps(rejection)))
@@ -3681,16 +4095,25 @@ function createUpdateCache(config, ports) {
3681
4095
  }
3682
4096
 
3683
4097
  // src/lib/core/1.domain/pooling/gate.ts
3684
- function committedView(members, shipped, recordOrder, { shareScope, without }) {
4098
+ function committedView(members, shipped, recordOrder, {
4099
+ shareScope,
4100
+ without,
4101
+ packageOf
4102
+ }) {
3685
4103
  const global = /* @__PURE__ */ new Map();
3686
4104
  const claims = committedClaims(inRecordOrder(members, recordOrder), { shareScope, without });
3687
4105
  for (const [specifier, { tag, copy }] of claims)
3688
4106
  global.set(specifier, { tag, remote: copy.name, file: copy.entries[specifier] });
3689
4107
  const builds = /* @__PURE__ */ new Map();
3690
4108
  for (const [owner, copies] of shipped)
3691
- if (owner !== without) builds.set(owner, buildOf(owner, copies));
4109
+ if (owner !== without) builds.set(owner, buildOf(owner, copies, packageOf));
3692
4110
  const fileOf = subpoolFilesOf(members);
3693
- return { builds, global, runsOffMap: runsOffMapOf(members, global, builds, fileOf) };
4111
+ return {
4112
+ packageOf,
4113
+ builds,
4114
+ global,
4115
+ runsOffMap: runsOffMapOf(members, global, builds, fileOf)
4116
+ };
3694
4117
  }
3695
4118
  function subpoolFilesOf(members) {
3696
4119
  const subpoolOwners = /* @__PURE__ */ new Set();
@@ -3733,45 +4156,65 @@ function runsOffMapOf(members, global, builds, fileOf) {
3733
4156
  function judgeRemote(copies, view, accepts) {
3734
4157
  const { rejected, missing } = scan(copies, view, accepts);
3735
4158
  if (rejected) return { cause: "incompatible", ...rejected };
3736
- const globalTags = new SpecifierTags([...view.global].map(([s, { tag }]) => [s, tag]));
4159
+ const globalTags = new SpecifierTags(
4160
+ view.packageOf,
4161
+ [...view.global].map(([s, { tag }]) => [s, tag])
4162
+ );
3737
4163
  const binding = offMapBinding(copies, view, globalTags);
3738
4164
  if (binding) return { cause: "uncovered", ...binding };
4165
+ if (servedSplit(copies, view)) return { cause: "uncovered", unshipped: true };
3739
4166
  if (agrees(copies, globalTags)) return "global";
3740
4167
  if (missing !== void 0) return { cause: "uncovered", specifier: missing };
3741
4168
  if (unwitnessedGap(copies, globalTags, view.builds.values()) === void 0) return "global";
3742
4169
  return { cause: "uncovered", unshipped: true };
3743
4170
  }
4171
+ function servedSplit(copies, view) {
4172
+ const loaded = new Set(copies.flatMap((copy) => copy.specifiers.map(view.packageOf)));
4173
+ const servedBy = /* @__PURE__ */ new Map();
4174
+ for (const [specifier, { remote }] of view.global) {
4175
+ const pkg = view.packageOf(specifier);
4176
+ if (!loaded.has(pkg)) continue;
4177
+ const first = servedBy.get(pkg);
4178
+ if (first === void 0) servedBy.set(pkg, remote);
4179
+ else if (first !== remote) return true;
4180
+ }
4181
+ return false;
4182
+ }
3744
4183
  function coverFromMap(remote, mine, view, actions, policy) {
3745
4184
  const files = [];
3746
4185
  for (const member of mine) {
3747
4186
  const action = actions[member.name];
3748
- const copy = member.external.versions.flatMap((v) => v.remotes).find((r) => r.name === remote);
3749
- if (!copy) continue;
3750
- const mapped = mapFiles(copy, view, policy, action);
4187
+ const copies = recordsByRemote(member).get(remote);
4188
+ if (!copies) continue;
4189
+ const entries = {};
4190
+ for (const { meta } of copies)
4191
+ for (const [specifier, file] of Object.entries(meta.entries)) entries[specifier] ??= file;
4192
+ const inShareRow = copies.some(({ version }) => version.action === "share");
4193
+ const mapped = mapFiles(entries, view, policy, action);
3751
4194
  if ("unmapped" in mapped) return mapped;
3752
- files.push({ member, action, copy, ...mapped });
4195
+ files.push({ member, action, entries, inShareRow, ...mapped });
3753
4196
  }
3754
4197
  const reaches = reachesOf(remote, files, view);
3755
4198
  const bound = boundByFile(reaches, view);
3756
4199
  if (bound !== void 0) return { bound };
3757
- const servedPackages = new Set([...view.global.keys()].map(packageOf));
3758
- const gap = files.map((file) => gapOf(file, servedPackages)).find((specifier) => specifier !== void 0);
4200
+ const servedPackages = new Set([...view.global.keys()].map(view.packageOf));
4201
+ const gap = files.map((file) => gapOf(file, servedPackages, view.packageOf)).find((specifier) => specifier !== void 0);
3759
4202
  if (gap !== void 0) return { gap };
3760
4203
  return { covers: files.filter(covering).map(coverOf) };
3761
4204
  }
3762
- function gapOf({ copy, covered }, servedPackages) {
3763
- const entrypoints = Object.keys(copy.entries);
4205
+ function gapOf({ entries, covered }, servedPackages, packageOf) {
4206
+ const entrypoints = Object.keys(entries);
3764
4207
  const missing = entrypoints.filter((specifier) => !covered.has(specifier));
3765
4208
  if (missing.length < entrypoints.length) return missing[0];
3766
4209
  return missing.find((specifier) => servedPackages.has(packageOf(specifier)));
3767
4210
  }
3768
- function covering({ action, copy, covered }) {
4211
+ function covering({ action, entries, covered }) {
3769
4212
  if (action.action === "skip") return true;
3770
- const entrypoints = Object.keys(copy.entries);
4213
+ const entrypoints = Object.keys(entries);
3771
4214
  return entrypoints.length > 0 && entrypoints.every((specifier) => covered.has(specifier));
3772
4215
  }
3773
- function coverOf({ member, action, copy, covered, override }) {
3774
- const toSkip = action.action !== "skip" || covered.size > action.covered.length && member.external.versions.some((v) => v.action === "share" && v.remotes.includes(copy));
4216
+ function coverOf({ member, action, inShareRow, covered, override }) {
4217
+ const toSkip = action.action !== "skip" || covered.size > action.covered.length && inShareRow;
3775
4218
  return { name: member.name, toSkip, override };
3776
4219
  }
3777
4220
  function reachesOf(remote, files, view) {
@@ -3782,7 +4225,7 @@ function reachesOf(remote, files, view) {
3782
4225
  };
3783
4226
  for (const file of files) {
3784
4227
  const takesMap = covering(file);
3785
- for (const [specifier, own] of Object.entries(file.copy.entries)) {
4228
+ for (const [specifier, own] of Object.entries(file.entries)) {
3786
4229
  if (!takesMap || !file.covered.has(specifier)) reaches.set(specifier, { remote, file: own });
3787
4230
  else {
3788
4231
  const reach = fromMap(specifier);
@@ -3809,10 +4252,10 @@ function boundByFile(reaches, view) {
3809
4252
  }
3810
4253
  return void 0;
3811
4254
  }
3812
- function mapFiles(copy, view, policy, action) {
4255
+ function mapFiles(entries, view, policy, action) {
3813
4256
  const covered = new Set(action.covered);
3814
4257
  const override = { ...action.override };
3815
- for (const specifier in copy.entries) {
4258
+ for (const specifier in entries) {
3816
4259
  const source = view.global.get(specifier);
3817
4260
  if (!source) continue;
3818
4261
  if (policy.shareScope !== GLOBAL_SCOPE) {
@@ -3837,14 +4280,17 @@ function scan(copies, view, accepts) {
3837
4280
  return { rejected, missing };
3838
4281
  }
3839
4282
  function offMapBinding(copies, view, globalTags) {
3840
- const own = new SpecifierTags(copies.flatMap((c) => c.specifiers.map((s) => [s, c.tag])));
4283
+ const own = new SpecifierTags(
4284
+ view.packageOf,
4285
+ copies.flatMap((c) => c.specifiers.map((s) => [s, c.tag]))
4286
+ );
3841
4287
  const servers = /* @__PURE__ */ new Set();
3842
4288
  for (const copy of copies)
3843
4289
  for (const specifier of copy.specifiers) {
3844
4290
  const build = view.global.get(specifier)?.remote;
3845
4291
  if (build !== void 0) servers.add(build);
3846
4292
  }
3847
- const firstRun = new SpecifierTags();
4293
+ const firstRun = new SpecifierTags(view.packageOf);
3848
4294
  for (const build of servers)
3849
4295
  for (const [specifier, { tag }] of view.runsOffMap.get(build) ?? []) {
3850
4296
  const reached = globalTags.pinnedTag(specifier) ?? own.pinnedTag(specifier) ?? firstRun.pinnedTag(specifier);
@@ -3869,13 +4315,21 @@ function createPoolDynamicExternals(config, ports) {
3869
4315
  for (const [scope, names] of poolableNames(entry, actions)) {
3870
4316
  const committed = ports.sharedExternalsRepo.getFromScope(scope);
3871
4317
  if (!scopeHasPoolState(committed)) continue;
3872
- const { pools } = buildPools(committed);
3873
- const moves = judgeScope(entry.name, names, actions, pools, Object.keys(committed), scope);
4318
+ const { pools, packageOf } = buildPools(committed);
4319
+ const moves = judgeScope(
4320
+ entry.name,
4321
+ names,
4322
+ actions,
4323
+ pools,
4324
+ packageOf,
4325
+ Object.keys(committed),
4326
+ scope
4327
+ );
3874
4328
  writeMoves(entry.name, names, moves, committed, pools, scope);
3875
4329
  }
3876
4330
  return Promise.resolve({ entry, actions: publicActions(actions) });
3877
4331
  };
3878
- function judgeScope(remote, names, actions, pools, recordOrder, scope) {
4332
+ function judgeScope(remote, names, actions, pools, packageOf, recordOrder, scope) {
3879
4333
  const policy = { shareScope: scope, scopeUrlOf };
3880
4334
  const moves = /* @__PURE__ */ new Map();
3881
4335
  const selfServe = (members, cause) => {
@@ -3891,7 +4345,8 @@ function createPoolDynamicExternals(config, ports) {
3891
4345
  const shipped = copiesByRemote(pool);
3892
4346
  const view = committedView(pool, shipped, recordOrder, {
3893
4347
  shareScope: scope,
3894
- without: remote
4348
+ without: remote,
4349
+ packageOf
3895
4350
  });
3896
4351
  const own = shipped.get(remote) ?? [];
3897
4352
  const verdict = judgeRemote(own, view, accepts);
@@ -4123,7 +4578,8 @@ var INIT_FLOW_FACTORY = ({
4123
4578
  var createBrowser = (config) => {
4124
4579
  return {
4125
4580
  setImportMapFn: config.setImportMapFn,
4126
- importModule: config.loadModuleFn
4581
+ importModule: config.loadModuleFn,
4582
+ preloadModules: config.preloadModulesFn
4127
4583
  };
4128
4584
  };
4129
4585
 
@@ -4226,7 +4682,12 @@ var createManifestProvider = () => {
4226
4682
  };
4227
4683
  };
4228
4684
 
4229
- // node_modules/.pnpm/@softarc+native-federation@4.8.0/node_modules/@softarc/native-federation/dist/lib/utils/normalize.js
4685
+ // src/lib/core/1.domain/remote-entry/mark-dense.ts
4686
+ function markDense(shared) {
4687
+ return shared.map((entry) => "entries" in entry ? { ...entry, dense: true } : entry);
4688
+ }
4689
+
4690
+ // node_modules/.pnpm/@softarc+native-federation@4.10.0/node_modules/@softarc/native-federation/dist/lib/utils/normalize.js
4230
4691
  function inferPackageFromSecondary(secondary) {
4231
4692
  const parts = secondary.split("/");
4232
4693
  if (secondary.startsWith("@") && parts.length >= 2) {
@@ -4235,14 +4696,14 @@ function inferPackageFromSecondary(secondary) {
4235
4696
  return parts[0];
4236
4697
  }
4237
4698
 
4238
- // node_modules/.pnpm/@softarc+native-federation@4.8.0/node_modules/@softarc/native-federation/dist/lib/core/output/densify-externals.js
4699
+ // node_modules/.pnpm/@softarc+native-federation@4.10.0/node_modules/@softarc/native-federation/dist/lib/core/output/densify-externals.js
4239
4700
  function isDense(entry) {
4240
4701
  return "entries" in entry;
4241
4702
  }
4242
4703
  function isFlatChunk(entry) {
4243
4704
  return entry.packageName.startsWith(CHUNK_PREFIX);
4244
4705
  }
4245
- function densifyExternals(shared) {
4706
+ function densifyExternals(shared, declaredPackages) {
4246
4707
  const result = [];
4247
4708
  const groupIndex = /* @__PURE__ */ new Map();
4248
4709
  for (const entry of shared) {
@@ -4256,7 +4717,7 @@ function densifyExternals(shared) {
4256
4717
  continue;
4257
4718
  }
4258
4719
  const { outFileName, packageName, dev, ...meta } = entry;
4259
- const parent = inferPackageFromSecondary(packageName);
4720
+ const parent = declaredPackages.get(packageName) ?? inferPackageFromSecondary(packageName);
4260
4721
  const sig = JSON.stringify(meta, Object.keys(meta).sort());
4261
4722
  const key = parent + " " + sig;
4262
4723
  const existing = groupIndex.get(key);
@@ -4286,6 +4747,16 @@ function toDenseSharedInfoFormat(shared) {
4286
4747
  });
4287
4748
  }
4288
4749
 
4750
+ // src/lib/core/3.adapters/remote-entry/normalize-remote-entry.ts
4751
+ var normalizeRemoteEntry = (raw, remoteEntryUrl, config) => {
4752
+ const marked = markDense(raw.shared ?? []);
4753
+ const shared = config.feature.convertFlatSharedInfo ? densifyExternals(marked, /* @__PURE__ */ new Map()) : toDenseSharedInfoFormat(marked);
4754
+ const remoteEntry = { ...raw, shared };
4755
+ if (!remoteEntry.exposes) remoteEntry.exposes = [];
4756
+ if (!remoteEntry.url) remoteEntry.url = remoteEntryUrl;
4757
+ return remoteEntry;
4758
+ };
4759
+
4289
4760
  // src/lib/core/3.adapters/http/remote-entry-provider.ts
4290
4761
  var createRemoteEntryProvider = (config) => {
4291
4762
  const ensureOk = (response) => {
@@ -4293,16 +4764,6 @@ var createRemoteEntryProvider = (config) => {
4293
4764
  return Promise.reject(new Error(`${response.status} - ${response.statusText}`));
4294
4765
  return response;
4295
4766
  };
4296
- const fillEmptyFields = (remoteEntryUrl) => (remoteEntry) => {
4297
- if (!remoteEntry.exposes) remoteEntry.exposes = [];
4298
- if (!remoteEntry.shared) remoteEntry.shared = [];
4299
- if (!remoteEntry.url) remoteEntry.url = remoteEntryUrl;
4300
- return remoteEntry;
4301
- };
4302
- const normalizeRemoteEntry = (raw) => {
4303
- const shared = config.feature.convertFlatSharedInfo ? densifyExternals(raw.shared ?? []) : toDenseSharedInfoFormat(raw.shared ?? []);
4304
- return { ...raw, shared };
4305
- };
4306
4767
  const formatError = (remoteEntryUrl) => (err) => {
4307
4768
  const msg = err instanceof Error ? err.message : String(err);
4308
4769
  throw new NFError(`Fetch of '${remoteEntryUrl}' returned ${msg}`);
@@ -4315,7 +4776,7 @@ var createRemoteEntryProvider = (config) => {
4315
4776
  await verifyIntegrity(bytes, opts.integrity);
4316
4777
  return JSON.parse(new TextDecoder().decode(bytes));
4317
4778
  };
4318
- return fetch(remoteEntryUrl).then(ensureOk).then(parse).then(normalizeRemoteEntry).then(fillEmptyFields(remoteEntryUrl)).catch(formatError(remoteEntryUrl));
4779
+ return fetch(remoteEntryUrl).then(ensureOk).then(parse).then((raw) => normalizeRemoteEntry(raw, remoteEntryUrl, config)).catch(formatError(remoteEntryUrl));
4319
4780
  }
4320
4781
  };
4321
4782
  };
@@ -4359,6 +4820,11 @@ var createRemoteInfoRepository = (config) => {
4359
4820
  (m) => join(_cache[remoteName].scopeUrl, m.file)
4360
4821
  );
4361
4822
  },
4823
+ getModuleChunkUrls: function(remoteName, exposedModule) {
4824
+ const remote = _cache[remoteName];
4825
+ const chunks = remote?.exposes.find((m) => m.moduleName === exposedModule)?.chunks ?? [];
4826
+ return chunks.map((file) => join(remote.scopeUrl, file));
4827
+ },
4362
4828
  getAll: function() {
4363
4829
  return _cache;
4364
4830
  },
@@ -4793,6 +5259,18 @@ var replaceInDOM = (mapType, trustedTypesPolicyName = "nfo") => (importMap, opts
4793
5259
  return Promise.resolve(importMap);
4794
5260
  };
4795
5261
 
5262
+ // src/lib/core/4.config/import-map/preload-in-dom.ts
5263
+ var preloadInDOM = (rel) => {
5264
+ const preloaded = /* @__PURE__ */ new Set();
5265
+ return (urls) => {
5266
+ for (const href of urls) {
5267
+ if (preloaded.has(href)) continue;
5268
+ preloaded.add(href);
5269
+ document.head.appendChild(Object.assign(document.createElement("link"), { rel, href }));
5270
+ }
5271
+ };
5272
+ };
5273
+
4796
5274
  // src/lib/core/4.config/import-map/use-default.ts
4797
5275
  var useDefaultImportMap = (trustedTypesPolicyName = "nfo") => ({
4798
5276
  loadModuleFn: (url) => {
@@ -4803,20 +5281,27 @@ var useDefaultImportMap = (trustedTypesPolicyName = "nfo") => ({
4803
5281
  );
4804
5282
  },
4805
5283
  setImportMapFn: replaceInDOM("importmap", trustedTypesPolicyName),
5284
+ preloadModulesFn: preloadInDOM("modulepreload"),
4806
5285
  reloadBrowserFn: () => {
4807
5286
  window.location.reload();
4808
5287
  }
4809
5288
  });
4810
5289
 
5290
+ // src/lib/core/4.config/import-map/no-preload.ts
5291
+ var noPreload = () => {
5292
+ };
5293
+
4811
5294
  // src/lib/core/4.config/import-map/import-map.config.ts
4812
5295
  var createImportMapConfig = (o) => {
4813
5296
  const fallback = useDefaultImportMap(o.trustedTypesPolicyName);
4814
5297
  return {
4815
5298
  setImportMapFn: o.setImportMapFn ?? fallback.setImportMapFn,
4816
5299
  loadModuleFn: o.loadModuleFn ?? fallback.loadModuleFn,
4817
- reloadBrowserFn: o.reloadBrowserFn ?? fallback.reloadBrowserFn
5300
+ reloadBrowserFn: o.reloadBrowserFn ?? fallback.reloadBrowserFn,
5301
+ preloadModulesFn: o.preloadModulesFn ?? defaultPreload(o, fallback)
4818
5302
  };
4819
5303
  };
5304
+ var defaultPreload = (o, fallback) => o.loadModuleFn ? noPreload : fallback.preloadModulesFn;
4820
5305
 
4821
5306
  // src/lib/core/4.config/host/host.config.ts
4822
5307
  var createHostConfig = (override) => {
@@ -4923,7 +5408,7 @@ globalThisStorageEntry.type = "globalThis";
4923
5408
  Object.freeze(globalThisStorageEntry);
4924
5409
 
4925
5410
  // src/lib/core/4.config/orchestrator-version.ts
4926
- var ORCHESTRATOR_VERSION = true ? "4.8.0" : "dev";
5411
+ var ORCHESTRATOR_VERSION = true ? "4.10.0" : "dev";
4927
5412
 
4928
5413
  // src/lib/core/4.config/storage/publish-storage-info.ts
4929
5414
  var KEYS = Object.freeze(Object.values(STORAGE_KEYS));
@@ -4966,10 +5451,49 @@ var isOutdatedCache = (storage) => {
4966
5451
  cacheState.update({ version: ORCHESTRATOR_VERSION, undecidedScopes: [] });
4967
5452
  return Object.values(STORAGE_KEYS).filter((key) => key !== STORAGE_KEYS.cacheState).some((key) => storage(key, null).get() !== null);
4968
5453
  };
4969
- var createStorageConfig = (override) => {
5454
+ var guardWrites = (storage, log) => {
5455
+ let failed = false;
5456
+ const memory = /* @__PURE__ */ new Map();
5457
+ const write = (key, value, persist) => {
5458
+ if (!failed) {
5459
+ try {
5460
+ persist();
5461
+ return;
5462
+ } catch (error) {
5463
+ failed = true;
5464
+ try {
5465
+ storage(STORAGE_KEYS.cacheState, null).set(null);
5466
+ } catch {
5467
+ }
5468
+ log.warn(
5469
+ 5,
5470
+ `Could not save '${key}' to storage; this page runs from memory and the next page starts without a cache.`,
5471
+ error
5472
+ );
5473
+ }
5474
+ }
5475
+ memory.set(key, cloneEntry(key, value));
5476
+ };
5477
+ return (key, initialValue) => {
5478
+ const inner = storage(key, initialValue);
5479
+ const entry = {
5480
+ get: () => memory.has(key) ? cloneEntry(key, memory.get(key)) : inner.get(),
5481
+ set: (value) => {
5482
+ write(key, value, () => void inner.set(value));
5483
+ return entry;
5484
+ },
5485
+ clear: () => {
5486
+ write(key, initialValue, () => void inner.clear());
5487
+ return entry;
5488
+ }
5489
+ };
5490
+ return entry;
5491
+ };
5492
+ };
5493
+ var createStorageConfig = (override, log) => {
4970
5494
  const creator = override.storage ?? globalThisStorageEntry;
4971
5495
  const namespace = override.storageNamespace ?? "__NATIVE_FEDERATION__";
4972
- const storage = creator(namespace);
5496
+ const storage = guardWrites(creator(namespace), log);
4973
5497
  publishStorageInfo({
4974
5498
  type: creator.type ?? "custom",
4975
5499
  namespace,
@@ -4988,7 +5512,9 @@ var defaultProfile = {
4988
5512
  latestSharedExternal: false,
4989
5513
  skipInvalidExternalVersions: false,
4990
5514
  overrideCachedRemotes: "init-only",
4991
- overrideCachedRemotesIfURLMatches: false
5515
+ overrideCachedRemotesIfURLMatches: false,
5516
+ mergeManifests: true,
5517
+ enableDebugging: false
4992
5518
  };
4993
5519
 
4994
5520
  // src/lib/core/4.config/mode/mode.config.ts
@@ -5016,19 +5542,25 @@ var createModeConfig = (override) => {
5016
5542
  };
5017
5543
 
5018
5544
  // src/lib/core/5.di/config.factory.ts
5019
- var createConfigHandlers = (overrides) => ({
5020
- ...createImportMapConfig(overrides),
5021
- ...createHostConfig(overrides),
5022
- ...createLogConfig(overrides),
5023
- ...createStorageConfig(overrides),
5024
- ...createModeConfig(overrides)
5025
- });
5545
+ var createConfigHandlers = (overrides) => {
5546
+ const logConfig = createLogConfig(overrides);
5547
+ return {
5548
+ ...createImportMapConfig(overrides),
5549
+ ...createHostConfig(overrides),
5550
+ ...logConfig,
5551
+ ...createStorageConfig(overrides, logConfig.log),
5552
+ ...createModeConfig(overrides)
5553
+ };
5554
+ };
5026
5555
 
5027
5556
  // src/lib/core/5.di/federation-result.factory.ts
5028
5557
  var createFederationResult = ({
5029
5558
  config,
5030
5559
  adapters,
5031
5560
  loadRemoteModule,
5561
+ // A host composing init by hand may not pass it.
5562
+ preloadRemoteModule = () => {
5563
+ },
5032
5564
  initRemoteEntryFlow,
5033
5565
  afterInitRemoteEntry
5034
5566
  }) => {
@@ -5044,6 +5576,7 @@ var createFederationResult = ({
5044
5576
  adapters,
5045
5577
  loadRemoteModule,
5046
5578
  load: loadRemoteModule,
5579
+ preloadRemoteModule,
5047
5580
  as: () => ({
5048
5581
  loadRemoteModule,
5049
5582
  load: loadRemoteModule
@@ -5059,9 +5592,7 @@ var initFederation = (remotesOrManifestUrl, options = {}) => {
5059
5592
  const factory = INIT_FLOW_FACTORY({ adapters, config });
5060
5593
  const initFlow = createInitFlow(factory);
5061
5594
  const initRemoteEntryFlow = createInitRemoteEntryFlow(factory);
5062
- return initFlow(remotesOrManifestUrl).then(
5063
- ({ loadRemoteModule }) => createFederationResult({ config, adapters, loadRemoteModule, initRemoteEntryFlow })
5064
- ).catch((e) => {
5595
+ return initFlow(remotesOrManifestUrl).then((access) => createFederationResult({ config, adapters, ...access, initRemoteEntryFlow })).catch((e) => {
5065
5596
  createStateDump(config, adapters)(`[init] STATE DUMP`);
5066
5597
  return Promise.reject(e);
5067
5598
  });