@fulgurjs/federation 5.7.0 → 5.8.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 (34) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/DESIGN.md +3 -0
  3. package/README.en.md +316 -363
  4. package/README.md +264 -1182
  5. package/dist/bridge-app-react.cjs +5 -1
  6. package/dist/bridge-app-react.js +5 -1
  7. package/dist/{chunk-OLQGJR2Z.js → chunk-GLASM5EX.js} +47 -17
  8. package/dist/{chunk-NHSQHAS4.js → chunk-V6EASSCR.js} +1 -1
  9. package/dist/{chunk-WOYDFERL.js → chunk-X34EJB4H.js} +1 -1
  10. package/dist/index.cjs +117 -13
  11. package/dist/index.js +117 -13
  12. package/dist/react.d.ts +4 -0
  13. package/dist/runtime-entry.d.ts +4 -0
  14. package/dist/runtime.js +22 -21
  15. package/docs/API.en.md +328 -0
  16. package/docs/API.md +913 -0
  17. package/docs/webpack-mf-/345/257/271/347/205/247/344/270/216/347/274/272/345/217/243.md +64 -37
  18. package/examples/bridge/react-host/package-lock.json +4 -4
  19. package/examples/bridge/react-host/package.json +1 -1
  20. package/examples/bridge/react-remote/package-lock.json +4 -4
  21. package/examples/bridge/react-remote/package.json +1 -1
  22. package/examples/bridge/vue-host/package-lock.json +4 -4
  23. package/examples/bridge/vue-host/package.json +3 -3
  24. package/examples/bridge/vue-remote/package-lock.json +4 -4
  25. package/examples/bridge/vue-remote/package.json +1 -1
  26. package/examples/react/host/package-lock.json +4 -4
  27. package/examples/react/host/package.json +1 -1
  28. package/examples/react/remote/package-lock.json +4 -4
  29. package/examples/react/remote/package.json +1 -1
  30. package/examples/vue/host/package-lock.json +4 -4
  31. package/examples/vue/host/package.json +1 -1
  32. package/examples/vue/remote/package-lock.json +4 -4
  33. package/examples/vue/remote/package.json +1 -1
  34. package/package.json +6 -4
@@ -79,8 +79,12 @@ function defineBridgeApp(factory, options = {}) {
79
79
  entriesByEl.set(el, entry);
80
80
  const promise = (async () => {
81
81
  const reactDomClient = await import("react-dom/client");
82
+ const createRoot = reactDomClient.createRoot ?? reactDomClient.default?.createRoot;
82
83
  if (entry.status === "abort" || entriesByEl.get(el) !== entry) return;
83
- const root = reactDomClient.createRoot(el);
84
+ if (typeof createRoot !== "function") throw new Error(
85
+ "react-dom/client \u672A\u5BFC\u51FA createRoot\u3002\u8BF7\u6838\u5BF9 React \u4E0E renderer \u7248\u672C\u53CA\u5171\u4EAB\u5B50\u8DEF\u5F84\u914D\u7F6E\u3002"
86
+ );
87
+ const root = createRoot(el);
84
88
  entry.root = root;
85
89
  entry.status = "live";
86
90
  const phaseRef = { current: "pending" };
@@ -45,8 +45,12 @@ function defineBridgeApp(factory, options = {}) {
45
45
  entriesByEl.set(el, entry);
46
46
  const promise = (async () => {
47
47
  const reactDomClient = await import("react-dom/client");
48
+ const createRoot = reactDomClient.createRoot ?? reactDomClient.default?.createRoot;
48
49
  if (entry.status === "abort" || entriesByEl.get(el) !== entry) return;
49
- const root = reactDomClient.createRoot(el);
50
+ if (typeof createRoot !== "function") throw new Error(
51
+ "react-dom/client \u672A\u5BFC\u51FA createRoot\u3002\u8BF7\u6838\u5BF9 React \u4E0E renderer \u7248\u672C\u53CA\u5171\u4EAB\u5B50\u8DEF\u5F84\u914D\u7F6E\u3002"
52
+ );
53
+ const root = createRoot(el);
50
54
  entry.root = root;
51
55
  entry.status = "live";
52
56
  const phaseRef = { current: "pending" };
@@ -550,12 +550,14 @@ function createRuntime() {
550
550
  if (pick.version === localVersion) {
551
551
  pick.value = instance;
552
552
  pick.loaded = true;
553
- } else if (opts.singleton) {
554
- pick.value = instance;
555
- pick.loaded = true;
556
- console.warn(
557
- `[fulgurjs:MFU-010] \u5171\u4EAB\u5355\u4F8B "${key}" \u7684\u9996\u6B21\u6D88\u8D39\u8005\u4EE5\u672C\u5730\u7248\u672C ${localVersion} \u63A5\u7BA1\u4E86 ${pick.from} \u58F0\u660E\u7684 ${pick.version} \u69FD\u4F4D\uFF08\u8BE5\u7248\u672C\u5C1A\u672A\u52A0\u8F7D\uFF09\u3002`
558
- );
553
+ } else if (opts.singleton && !pick.pendingGet) {
554
+ registerShare2(scopeName, key, localVersion, () => Promise.resolve(instance), {
555
+ from: "fulgurjs:local-fallback",
556
+ loaded: true
557
+ });
558
+ const local = scope[key][localVersion];
559
+ local.value = instance;
560
+ local.loaded = true;
559
561
  }
560
562
  }
561
563
  } catch {
@@ -573,7 +575,9 @@ function createRuntime() {
573
575
  const scopeName = opts.shareScope || "default";
574
576
  const shareKey = opts.shareKey || name;
575
577
  const byName = getScope(scopeName)[shareKey] || {};
576
- let entry = selectShareEntry(name, opts);
578
+ const requestKey = shareRequestKey(name, opts);
579
+ const snapshot = hooks.resolveShare ? resolvedShareSnapshots.get(requestKey) : void 0;
580
+ let entry = snapshot || selectShareEntry(name, opts);
577
581
  if (!entry) {
578
582
  if (opts.fallback) {
579
583
  const instance2 = await opts.fallback();
@@ -590,7 +594,7 @@ function createRuntime() {
590
594
  emitError({ remote: shareKey, error: err });
591
595
  throw err;
592
596
  }
593
- if (hooks.resolveShare) {
597
+ if (hooks.resolveShare && !snapshot) {
594
598
  const picked = await hooks.resolveShare({
595
599
  shareKey,
596
600
  shareScope: scopeName,
@@ -599,6 +603,7 @@ function createRuntime() {
599
603
  available: Object.values(byName)
600
604
  });
601
605
  if (picked) entry = picked;
606
+ resolvedShareSnapshots.set(requestKey, entry);
602
607
  }
603
608
  if (entry.value !== void 0) {
604
609
  resolvedShareSnapshots.set(shareRequestKey(name, opts), entry);
@@ -622,6 +627,7 @@ function createRuntime() {
622
627
  return entry.value;
623
628
  }
624
629
  entry.loaded = false;
630
+ if (resolvedShareSnapshots.get(requestKey) === entry) resolvedShareSnapshots.delete(requestKey);
625
631
  throw e;
626
632
  } finally {
627
633
  if (entry.pendingGet === pending) entry.pendingGet = void 0;
@@ -644,7 +650,7 @@ function createRuntime() {
644
650
  const snapKey = shareRequestKey(name, opts);
645
651
  const snap = resolvedShareSnapshots.get(snapKey);
646
652
  if (snap && snap.value !== void 0) return { kind: "ready", value: snap.value };
647
- const pickedRaw = hooks.resolveShare({
653
+ const pickedRaw = snap || hooks.resolveShare({
648
654
  shareKey,
649
655
  shareScope: scopeName,
650
656
  requiredVersion: opts.requiredVersion,
@@ -652,11 +658,13 @@ function createRuntime() {
652
658
  available: Object.values(getScope(scopeName)[shareKey] || {})
653
659
  });
654
660
  if (pickedRaw && typeof pickedRaw.then === "function") {
661
+ void Promise.resolve(pickedRaw).catch(() => {
662
+ });
655
663
  throw new FgError(
656
664
  ErrorCodes.SHARE_NOT_AVAILABLE,
657
665
  `\u73B0\u8C61\uFF1AresolveShare \u5BF9\u5171\u4EAB "${shareKey}" \u8FD4\u56DE\u4E86 Promise\uFF0C\u4F46\u8BE5\u5171\u4EAB\u6B63\u88AB\u540C\u6B65\u9759\u6001\u5BFC\u5165\u6D88\u8D39\uFF08Vite 8 \u540C\u6B65\u534F\u5546\u95E8\u9762\uFF09\u3002
658
666
  \u539F\u56E0\uFF1A\u6A21\u5757\u6C42\u503C\u671F\u65E0\u6CD5\u7B49\u5F85\u5F02\u6B65\u51B3\u7B56\uFF1B\u9759\u6001\u5BFC\u5165\u4E0D\u80FD\u9759\u9ED8\u5FFD\u7565 hook \u51B3\u7B56\u3002
659
- \u4FEE\u6CD5\uFF1A\u8BA9 resolveShare \u5BF9\u8BE5\u952E\u540C\u6B65\u8FD4\u56DE picked\uFF08\u4ECE available \u4E2D\u9009\u62E9\uFF09\uFF1B\u6216\u8BA9\u9996\u6B21\u6D88\u8D39\u5148\u7ECF\u4E00\u6B21\u52A8\u6001 loadShare \u5B8C\u6210\u534F\u5546\uFF08\u6210\u529F\u5FEB\u7167\u4F1A\u88AB\u9759\u6001\u5BFC\u5165\u590D\u7528\uFF09\u3002`,
667
+ \u4FEE\u6CD5\uFF1AVite 8 HTML \u5165\u53E3\u4F1A\u5148\u5B8C\u6210\u5F02\u6B65\u534F\u5546\uFF1B\u5176\u4ED6\u5165\u53E3\u8BF7\u5148\u52A8\u6001 loadShare \u5EFA\u7ACB\u5FEB\u7167\uFF0C\u518D\u5BFC\u5165\u6D88\u8D39\u8005\uFF0C\u6216\u8BA9\u8BE5\u952E\u540C\u6B65\u8FD4\u56DE picked\u3002`,
660
668
  { shareKey, requiredVersion: opts.requiredVersion, syncUnsupported: true }
661
669
  );
662
670
  }
@@ -669,8 +677,9 @@ function createRuntime() {
669
677
  if (picked.version !== void 0 && picked.version === opts.localVersion) return { kind: "local" };
670
678
  throw new FgError(
671
679
  ErrorCodes.SHARE_NOT_AVAILABLE,
672
- `\u73B0\u8C61\uFF1AresolveShare \u4E3A\u5171\u4EAB "${shareKey}" \u9009\u62E9\u4E86 ${picked.version ?? "\u672A\u5C31\u7EEA\u6761\u76EE"}\uFF08\u5C1A\u672A\u52A0\u8F7D\uFF09\uFF0C\u540C\u6B65\u9759\u6001\u5BFC\u5165\u65E0\u6CD5\u7B49\u5F85\u5176\u5B9E\u4F8B\u5C31\u7EEA\u3002
673
- \u4FEE\u6CD5\uFF1A\u8BA9 hook \u4F18\u5148\u9009\u62E9\u5DF2\u5C31\u7EEA\u5B9E\u4F8B\u6216\u672C\u5E94\u7528\u672C\u5730\u7248\u672C\uFF08${opts.localVersion ?? "\u672A\u58F0\u660E"}\uFF09\uFF0C\u6216\u5148\u7ECF\u52A8\u6001 loadShare \u5B8C\u6210\u534F\u5546\u3002`,
680
+ `\u73B0\u8C61\uFF1AresolveShare \u4E3A "${shareKey}" \u9009\u62E9\u4E86\u672A\u5C31\u7EEA\u7684 ${picked.version ?? "\u6761\u76EE"}\u3002
681
+ \u539F\u56E0\uFF1A\u540C\u6B65\u6D88\u8D39\u4E0D\u80FD\u7B49\u5F85\u52A0\u8F7D\u3002
682
+ \u4FEE\u6CD5\uFF1A\u5148\u52A8\u6001 loadShare \u518D\u5BFC\u5165\u6D88\u8D39\u8005\uFF0C\u6216\u9009\u62E9\u5DF2\u5C31\u7EEA\u5B9E\u4F8B/\u672C\u5730\u7248\u672C ${opts.localVersion ?? "\u672A\u58F0\u660E"}\u3002`,
674
683
  { shareKey, requiredVersion: opts.requiredVersion, syncUnsupported: true }
675
684
  );
676
685
  }
@@ -679,12 +688,12 @@ function createRuntime() {
679
688
  if (!entry) return { kind: "local" };
680
689
  if (entry.value !== void 0) return { kind: "ready", value: entry.value };
681
690
  if (entry.version !== void 0 && entry.version === opts.localVersion) return { kind: "local" };
682
- if (opts.singleton) {
683
- if (opts.strictVersion) {
691
+ if (opts.singleton || opts.strictVersion && opts.requiredVersion && (!opts.localVersion || !satisfies(opts.localVersion, opts.requiredVersion))) {
692
+ if (opts.strictVersion || entry.pendingGet) {
684
693
  throw new FgError(
685
694
  ErrorCodes.SHARE_NOT_AVAILABLE,
686
- `\u73B0\u8C61\uFF1A\u5171\u4EAB\u5355\u4F8B "${shareKey}" \u9009\u4E2D\u4E86 ${entry.from} \u63D0\u4F9B\u7684 ${entry.version}\uFF08\u5C1A\u672A\u52A0\u8F7D\uFF09\uFF0C\u540C\u6B65\u9759\u6001\u5BFC\u5165\u65E0\u6CD5\u7B49\u5F85\u5176\u5B9E\u4F8B\u5C31\u7EEA\u3002
687
- \u539F\u56E0\uFF1A\u5355\u4F8B\u5FC5\u987B\u5168\u9875\u4E00\u81F4\uFF0C\u4E0D\u80FD\u9759\u9ED8\u6539\u7528\u672C\u5730\u526F\u672C\u5206\u88C2\u5B9E\u4F8B\u3002
695
+ `\u73B0\u8C61\uFF1A\u5171\u4EAB "${shareKey}" \u9009\u4E2D\u4E86 ${entry.from} \u63D0\u4F9B\u7684 ${entry.version}\uFF08\u5C1A\u672A\u52A0\u8F7D\uFF09\uFF0C\u540C\u6B65\u9759\u6001\u5BFC\u5165\u65E0\u6CD5\u7B49\u5F85\u5176\u5B9E\u4F8B\u5C31\u7EEA\u3002
696
+ \u539F\u56E0\uFF1A\u4E0D\u80FD\u6539\u7528\u4E0D\u517C\u5BB9\u7684\u672C\u5730\u526F\u672C\u6216\u5206\u88C2\u5355\u4F8B\u3002
688
697
  \u4FEE\u6CD5\uFF1A\u8BA9\u8BE5\u5171\u4EAB\u7684\u9996\u6B21\u6D88\u8D39\u5148\u7ECF\u4E00\u6B21\u52A8\u6001 loadShare \u5B8C\u6210\u52A0\u8F7D\uFF0C\u6216\u5C06\u672C\u5E94\u7528\u7248\u672C\u4E0E\u4F5C\u7528\u57DF\u63D0\u4F9B\u7248\u672C\u5BF9\u9F50\u3002`,
689
698
  { shareKey, requiredVersion: opts.requiredVersion, syncUnsupported: true }
690
699
  );
@@ -699,10 +708,27 @@ function createRuntime() {
699
708
  return { kind: "local" };
700
709
  }
701
710
  console.warn(
702
- `[fulgurjs] \u5171\u4EAB "${shareKey}" \u7684\u540C\u6B65\u9759\u6001\u6D88\u8D39\u4F7F\u7528\u672C\u5730\u526F\u672C ${opts.localVersion ?? ""}\uFF08\u4F5C\u7528\u57DF\u4E2D\u6EE1\u8DB3\u8981\u6C42\u7684\u53E6\u4E00\u7248\u672C ${entry.version} \u5C1A\u672A\u5C31\u7EEA\uFF0C\u65E0\u6CD5\u540C\u6B65\u7B49\u5F85\uFF09\uFF1B\u975E\u5355\u4F8B\u5141\u8BB8\u591A\u7248\u672C\u5171\u5B58\u3002`
711
+ `[fulgurjs] \u5171\u4EAB "${shareKey}"\uFF1A\u975E\u5355\u4F8B\u540C\u6B65\u6D88\u8D39\u4F7F\u7528\u672C\u5730 ${opts.localVersion ?? ""}\uFF0C\u8FDC\u7A0B ${entry.version} \u5C1A\u672A\u5C31\u7EEA\u3002`
703
712
  );
704
713
  return { kind: "local" };
705
714
  }
715
+ async function prepareShares2(requests) {
716
+ if (!hooks.resolveShare) return;
717
+ for (const { name, opts } of requests) {
718
+ const key = shareRequestKey(name, opts);
719
+ if (resolvedShareSnapshots.has(key)) continue;
720
+ const entry = selectShareEntry(name, opts);
721
+ const picked = await hooks.resolveShare({
722
+ shareKey: opts.shareKey || name,
723
+ shareScope: opts.shareScope || "default",
724
+ requiredVersion: opts.requiredVersion,
725
+ picked: entry,
726
+ available: Object.values(getScope(opts.shareScope || "default")[opts.shareKey || name] || {})
727
+ }) || entry;
728
+ if (picked) resolvedShareSnapshots.set(key, picked);
729
+ }
730
+ for (const { name, opts } of requests) await loadShare2(name, opts);
731
+ }
706
732
  function sanitizeUrl(u) {
707
733
  try {
708
734
  const x = new URL(u, typeof location < "u" ? location.href : "http://f.invalid");
@@ -1138,6 +1164,7 @@ ${hints.join("\n")}`,
1138
1164
  registerPlugins: registerPlugins2,
1139
1165
  loadShare: loadShare2,
1140
1166
  loadShareSync: loadShareSync2,
1167
+ prepareShares: prepareShares2,
1141
1168
  getLoadedShare: getLoadedShare2,
1142
1169
  pinLoadedShare: pinLoadedShare2,
1143
1170
  loadRemote: loadRemote2,
@@ -1161,6 +1188,9 @@ var registerRemote = runtime.registerRemote;
1161
1188
  var registerPlugins = runtime.registerPlugins;
1162
1189
  var loadShare = runtime.loadShare;
1163
1190
  var getLoadedShare = runtime.getLoadedShare;
1191
+ var prepareShares = runtime.prepareShares || (async (requests) => {
1192
+ for (const { name, opts } of requests) await runtime.loadShare(name, opts);
1193
+ });
1164
1194
  var loadShareSync = runtime.loadShareSync;
1165
1195
  var pinLoadedShare = runtime.pinLoadedShare;
1166
1196
  var loadRemote = runtime.loadRemote;
@@ -10,7 +10,7 @@ import {
10
10
  releaseBridgeSession,
11
11
  resolveBridgeContext,
12
12
  withBridgeTimeout
13
- } from "./chunk-OLQGJR2Z.js";
13
+ } from "./chunk-GLASM5EX.js";
14
14
 
15
15
  // src/bridge-host-vue.ts
16
16
  import { defineComponent, h, onActivated, onBeforeUnmount, onDeactivated, onMounted, ref, shallowRef, toRaw, watch } from "vue";
@@ -10,7 +10,7 @@ import {
10
10
  releaseBridgeSession,
11
11
  resolveBridgeContext,
12
12
  withBridgeTimeout
13
- } from "./chunk-OLQGJR2Z.js";
13
+ } from "./chunk-GLASM5EX.js";
14
14
 
15
15
  // src/bridge-host-react.ts
16
16
  import {