@chatbi-v/core 2.1.3 → 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 {
@@ -1706,6 +1751,7 @@ var PluginManager = class {
1706
1751
  }
1707
1752
  } finally {
1708
1753
  this.isInitializing = false;
1754
+ this.notify();
1709
1755
  }
1710
1756
  }
1711
1757
  /**
@@ -1752,8 +1798,9 @@ var PluginManager = class {
1752
1798
  * 加载插件列表
1753
1799
  * @param configs 插件配置
1754
1800
  * @param registry 插件注册表 (动态导入函数)
1801
+ * @param notify 是否在加载完成后触发通知,默认为 true
1755
1802
  */
1756
- async loadPlugins(configs, registry) {
1803
+ async loadPlugins(configs, registry, notify = true) {
1757
1804
  logger6.info("\u5F00\u59CB\u52A0\u8F7D\u63D2\u4EF6...");
1758
1805
  const localLoadPromises = Object.entries(registry).map(async ([registryId, importFn]) => {
1759
1806
  try {
@@ -1787,7 +1834,9 @@ var PluginManager = class {
1787
1834
  this.register(plugin, false);
1788
1835
  }
1789
1836
  });
1790
- this.notify();
1837
+ if (notify) {
1838
+ this.notify();
1839
+ }
1791
1840
  logger6.info(`\u63D2\u4EF6\u52A0\u8F7D\u5B8C\u6210\uFF0C\u5171\u52A0\u8F7D ${this.plugins.size} \u4E2A\u63D2\u4EF6`);
1792
1841
  }
1793
1842
  /**
@@ -1950,7 +1999,7 @@ var PluginErrorBoundary = class extends Component {
1950
1999
  };
1951
2000
 
1952
2001
  // src/components/PluginSlot.tsx
1953
- import { useMemo, useState, useEffect, Suspense } from "react";
2002
+ import { useMemo, useState, useEffect, Suspense, startTransition as startTransition2 } from "react";
1954
2003
 
1955
2004
  // src/components/SlotSkeletons.tsx
1956
2005
  import { jsx as jsx3, jsxs } from "react/jsx-runtime";
@@ -1977,6 +2026,17 @@ var SlotSkeletons = ({ slot, expanded }) => {
1977
2026
 
1978
2027
  // src/components/PluginSlot.tsx
1979
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
+ };
1980
2040
  var PluginSlot = ({
1981
2041
  slot,
1982
2042
  props = {},
@@ -1989,7 +2049,9 @@ var PluginSlot = ({
1989
2049
  const [, forceUpdate] = useState({});
1990
2050
  useEffect(() => {
1991
2051
  const unsubscribe = pluginManager.subscribe(() => {
1992
- forceUpdate({});
2052
+ startTransition2(() => {
2053
+ forceUpdate({});
2054
+ });
1993
2055
  }, slot);
1994
2056
  return unsubscribe;
1995
2057
  }, [slot]);
@@ -2010,7 +2072,14 @@ var PluginSlot = ({
2010
2072
  return {
2011
2073
  key,
2012
2074
  extension: ext,
2013
- 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)
2014
2083
  };
2015
2084
  });
2016
2085
  }, [extensions, mergedProps]);
@@ -2632,10 +2701,10 @@ var usePluginLoader = (options) => {
2632
2701
  const { configManager: configManager2 } = await import("./config-manager-3TKURRUT.mjs");
2633
2702
  configManager2.set("system", options.systemConfig);
2634
2703
  }
2635
- await pluginManager.loadPlugins(pluginConfigs, finalRegistry);
2636
- await pluginManager.initPlugins(sharedContext);
2704
+ await pluginManager.loadPlugins(pluginConfigs, finalRegistry, false);
2705
+ await pluginManager.initPlugins(sharedContext, false);
2637
2706
  setPluginsLoaded(true);
2638
- logger10.info("Plugins loaded successfully");
2707
+ logger10.info("Plugins loaded successfully (Lazy Mode)");
2639
2708
  } catch (error) {
2640
2709
  logger10.error("Failed to load plugins:", error);
2641
2710
  } finally {
@@ -2643,14 +2712,9 @@ var usePluginLoader = (options) => {
2643
2712
  }
2644
2713
  };
2645
2714
  load();
2646
- return () => {
2647
- unsubscribe();
2648
- };
2715
+ return unsubscribe;
2649
2716
  }, []);
2650
- return {
2651
- pluginsLoaded,
2652
- pluginVersion
2653
- };
2717
+ return { pluginsLoaded, pluginVersion };
2654
2718
  };
2655
2719
  export {
2656
2720
  ApiEngine,