@chatbi-v/core 2.1.4 → 2.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1639,11 +1639,53 @@ var PluginManager = class {
1639
1639
  this.notify();
1640
1640
  }
1641
1641
  }
1642
+ /**
1643
+ * 手动挂载指定插件(支持按需加载)
1644
+ * @description 如果插件依赖尚未挂载,会递归挂载所有依赖
1645
+ * @param pluginId 插件 ID
1646
+ */
1647
+ async mountPlugin(pluginId) {
1648
+ const runtime = this.runtimes.get(pluginId);
1649
+ if (!runtime) {
1650
+ const msg = `\u5C1D\u8BD5\u6302\u8F7D\u4E0D\u5B58\u5728\u6216\u672A\u521D\u59CB\u5316\u7684\u63D2\u4EF6: ${pluginId}`;
1651
+ logger6.warn(msg);
1652
+ throw new Error(msg);
1653
+ }
1654
+ if (runtime.status === "mounted") return;
1655
+ const plugin = this.plugins.get(pluginId);
1656
+ if (plugin?.metadata.dependencies) {
1657
+ for (const depId of plugin.metadata.dependencies) {
1658
+ if (!this.runtimes.has(depId)) {
1659
+ logger6.error(`\u63D2\u4EF6 ${pluginId} \u4F9D\u8D56\u7F3A\u5931: ${depId}`);
1660
+ throw new Error(`Dependency ${depId} missing for ${pluginId}`);
1661
+ }
1662
+ await this.mountPlugin(depId);
1663
+ }
1664
+ }
1665
+ if (runtime.status === "initial") {
1666
+ try {
1667
+ await runtime.load();
1668
+ } catch (e) {
1669
+ logger6.error(`\u63D2\u4EF6 ${pluginId} load \u5931\u8D25:`, e);
1670
+ throw e;
1671
+ }
1672
+ }
1673
+ if (runtime.status === "loaded") {
1674
+ try {
1675
+ await runtime.mount();
1676
+ this.notify();
1677
+ } catch (e) {
1678
+ logger6.error(`\u63D2\u4EF6 ${pluginId} \u6302\u8F7D\u5931\u8D25:`, e);
1679
+ throw e;
1680
+ }
1681
+ }
1682
+ }
1642
1683
  /**
1643
1684
  * 初始化所有插件
1644
1685
  * @param sharedContext 共享上下文
1686
+ * @param autoMount 是否自动挂载所有插件 (默认为 false,启用按需加载模式)
1645
1687
  */
1646
- async initPlugins(sharedContext = {}) {
1688
+ async initPlugins(sharedContext = {}, autoMount = false) {
1647
1689
  if (this.isInitializing) {
1648
1690
  logger6.warn("PluginManager is already initializing, skipping...");
1649
1691
  return;
@@ -1695,6 +1737,9 @@ var PluginManager = class {
1695
1737
  }
1696
1738
  for (const id of sortedPluginIds) {
1697
1739
  if (!idsToLoad.has(id)) continue;
1740
+ const plugin = this.plugins.get(id);
1741
+ const shouldMount = autoMount || plugin && ["system", "theme"].includes(plugin.metadata.type);
1742
+ if (!shouldMount) continue;
1698
1743
  const runtime = this.runtimes.get(id);
1699
1744
  if (runtime && (runtime.status === "loaded" || runtime.status === "initial")) {
1700
1745
  try {
@@ -1954,7 +1999,7 @@ var PluginErrorBoundary = class extends Component {
1954
1999
  };
1955
2000
 
1956
2001
  // src/components/PluginSlot.tsx
1957
- import { useMemo, useState, useEffect, Suspense } from "react";
2002
+ import { useMemo, useState, useEffect, Suspense, startTransition as startTransition2 } from "react";
1958
2003
 
1959
2004
  // src/components/SlotSkeletons.tsx
1960
2005
  import { jsx as jsx3, jsxs } from "react/jsx-runtime";
@@ -1981,6 +2026,17 @@ var SlotSkeletons = ({ slot, expanded }) => {
1981
2026
 
1982
2027
  // src/components/PluginSlot.tsx
1983
2028
  import { Fragment, jsx as jsx4 } from "react/jsx-runtime";
2029
+ var ExtensionLoader = ({ pluginId, component: Component2, props }) => {
2030
+ const status = pluginManager.getPluginRuntimeStatus(pluginId);
2031
+ if (status !== "mounted") {
2032
+ const error = pluginManager.getPluginError(pluginId);
2033
+ if (error) {
2034
+ throw error;
2035
+ }
2036
+ throw pluginManager.mountPlugin(pluginId);
2037
+ }
2038
+ return /* @__PURE__ */ jsx4(Component2, { ...props });
2039
+ };
1984
2040
  var PluginSlot = ({
1985
2041
  slot,
1986
2042
  props = {},
@@ -1993,7 +2049,9 @@ var PluginSlot = ({
1993
2049
  const [, forceUpdate] = useState({});
1994
2050
  useEffect(() => {
1995
2051
  const unsubscribe = pluginManager.subscribe(() => {
1996
- forceUpdate({});
2052
+ startTransition2(() => {
2053
+ forceUpdate({});
2054
+ });
1997
2055
  }, slot);
1998
2056
  return unsubscribe;
1999
2057
  }, [slot]);
@@ -2014,7 +2072,14 @@ var PluginSlot = ({
2014
2072
  return {
2015
2073
  key,
2016
2074
  extension: ext,
2017
- component: /* @__PURE__ */ jsx4(PluginErrorBoundary, { pluginId: ext._pluginId, children: /* @__PURE__ */ jsx4(Suspense, { fallback: skeleton || /* @__PURE__ */ jsx4(SlotSkeletons, { slot }), children: /* @__PURE__ */ jsx4(Component2, { ...mergedProps }) }) }, key)
2075
+ component: /* @__PURE__ */ jsx4(PluginErrorBoundary, { pluginId: ext._pluginId, children: /* @__PURE__ */ jsx4(Suspense, { fallback: skeleton || /* @__PURE__ */ jsx4(SlotSkeletons, { slot }), children: /* @__PURE__ */ jsx4(
2076
+ ExtensionLoader,
2077
+ {
2078
+ pluginId: ext._pluginId || "",
2079
+ component: Component2,
2080
+ props: mergedProps
2081
+ }
2082
+ ) }) }, key)
2018
2083
  };
2019
2084
  });
2020
2085
  }, [extensions, mergedProps]);
@@ -2637,9 +2702,9 @@ var usePluginLoader = (options) => {
2637
2702
  configManager2.set("system", options.systemConfig);
2638
2703
  }
2639
2704
  await pluginManager.loadPlugins(pluginConfigs, finalRegistry, false);
2640
- await pluginManager.initPlugins(sharedContext);
2705
+ await pluginManager.initPlugins(sharedContext, false);
2641
2706
  setPluginsLoaded(true);
2642
- logger10.info("Plugins loaded successfully");
2707
+ logger10.info("Plugins loaded successfully (Lazy Mode)");
2643
2708
  } catch (error) {
2644
2709
  logger10.error("Failed to load plugins:", error);
2645
2710
  } finally {
@@ -2647,14 +2712,9 @@ var usePluginLoader = (options) => {
2647
2712
  }
2648
2713
  };
2649
2714
  load();
2650
- return () => {
2651
- unsubscribe();
2652
- };
2715
+ return unsubscribe;
2653
2716
  }, []);
2654
- return {
2655
- pluginsLoaded,
2656
- pluginVersion
2657
- };
2717
+ return { pluginsLoaded, pluginVersion };
2658
2718
  };
2659
2719
  export {
2660
2720
  ApiEngine,