@chatbi-v/core 2.1.1 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ConfigManager,
3
3
  configManager
4
- } from "./chunk-4AJ6VW5G.mjs";
4
+ } from "./chunk-QET56C3T.mjs";
5
5
 
6
6
  // src/ports/plugin-port.ts
7
7
  var PLUGIN_TYPES = ["business", "functional", "view", "theme", "renderer", "system"];
@@ -407,6 +407,9 @@ var useApi = () => {
407
407
  // src/components/PluginErrorBoundary.tsx
408
408
  import { Component } from "react";
409
409
 
410
+ // src/domain/plugin-manager.ts
411
+ import { startTransition } from "react";
412
+
410
413
  // src/adapters/local-storage-adapter.ts
411
414
  var LocalStorageAdapter = class {
412
415
  /** 命名空间前缀,所有存入的键名都会自动添加此前缀 */
@@ -1237,6 +1240,8 @@ var PluginManager = class {
1237
1240
  sharedContext = null;
1238
1241
  /** 收集到的插件工具函数集合 */
1239
1242
  utils = {};
1243
+ /** 是否正在初始化插件中,防止重入导致多次加载 */
1244
+ isInitializing = false;
1240
1245
  /**
1241
1246
  * 构造函数
1242
1247
  * @param storage - 底层存储适配器
@@ -1309,18 +1314,20 @@ var PluginManager = class {
1309
1314
  * @param affectedSlot - (可选) 受影响的插槽位置
1310
1315
  */
1311
1316
  notify(affectedSlot) {
1312
- if (affectedSlot) {
1313
- this.memoizedExtensions.delete(String(affectedSlot));
1314
- } else {
1315
- this.memoizedExtensions.clear();
1316
- this.memoizedRoutes = null;
1317
- }
1318
- this.listeners.forEach((listener) => listener());
1319
- if (affectedSlot) {
1320
- this.slotListeners.get(String(affectedSlot))?.forEach((listener) => listener());
1321
- } else {
1322
- this.slotListeners.forEach((set) => set.forEach((listener) => listener()));
1323
- }
1317
+ startTransition(() => {
1318
+ if (affectedSlot) {
1319
+ this.memoizedExtensions.delete(String(affectedSlot));
1320
+ } else {
1321
+ this.memoizedExtensions.clear();
1322
+ this.memoizedRoutes = null;
1323
+ }
1324
+ this.listeners.forEach((listener) => listener());
1325
+ if (affectedSlot) {
1326
+ this.slotListeners.get(String(affectedSlot))?.forEach((listener) => listener());
1327
+ } else {
1328
+ this.slotListeners.forEach((set) => set.forEach((listener) => listener()));
1329
+ }
1330
+ });
1324
1331
  }
1325
1332
  /**
1326
1333
  * 获取所有已注册的插件列表
@@ -1637,58 +1644,68 @@ var PluginManager = class {
1637
1644
  * @param sharedContext 共享上下文
1638
1645
  */
1639
1646
  async initPlugins(sharedContext = {}) {
1640
- this.sharedContext = {
1641
- ...sharedContext,
1642
- events: this.eventBus
1643
- };
1644
- this.plugins.forEach((plugin) => {
1645
- if (!this.isPluginEnabled(plugin.id)) return;
1646
- if (!this.runtimes.has(plugin.id)) {
1647
- const runtime = new PluginRuntime(plugin, this.sharedContext, this.storageManager);
1648
- this.runtimes.set(plugin.id, runtime);
1649
- }
1650
- });
1651
- const sortedPluginIds = this.getSortedPluginIds();
1652
- const missingDeps = /* @__PURE__ */ new Map();
1653
- const idsToLoad = new Set(sortedPluginIds);
1654
- for (const id of sortedPluginIds) {
1655
- const plugin = this.plugins.get(id);
1656
- if (plugin?.metadata.dependencies) {
1657
- const missing = plugin.metadata.dependencies.filter((depId) => !this.runtimes.has(depId));
1658
- if (missing.length > 0) {
1659
- missingDeps.set(id, missing);
1660
- idsToLoad.delete(id);
1661
- this.runtimes.delete(id);
1662
- }
1663
- }
1647
+ if (this.isInitializing) {
1648
+ logger6.warn("PluginManager is already initializing, skipping...");
1649
+ return;
1664
1650
  }
1665
- if (missingDeps.size > 0) {
1666
- missingDeps.forEach((deps, id) => {
1667
- logger6.error(`\u63D2\u4EF6 ${id} \u65E0\u6CD5\u52A0\u8F7D\uFF0C\u7F3A\u5931\u4F9D\u8D56: ${deps.join(", ")}`);
1651
+ this.isInitializing = true;
1652
+ try {
1653
+ this.sharedContext = {
1654
+ ...sharedContext,
1655
+ events: this.eventBus
1656
+ };
1657
+ this.plugins.forEach((plugin) => {
1658
+ if (!this.isPluginEnabled(plugin.id)) return;
1659
+ if (!this.runtimes.has(plugin.id)) {
1660
+ const runtime = new PluginRuntime(plugin, this.sharedContext, this.storageManager);
1661
+ this.runtimes.set(plugin.id, runtime);
1662
+ }
1668
1663
  });
1669
- }
1670
- for (const id of sortedPluginIds) {
1671
- if (!idsToLoad.has(id)) continue;
1672
- const runtime = this.runtimes.get(id);
1673
- if (runtime) {
1674
- try {
1675
- logger6.info(`[PluginManager] invoking onLoad for ${id}`);
1676
- await runtime.load();
1677
- logger6.info(`[PluginManager] onLoad completed for ${id}`);
1678
- } catch (e) {
1679
- logger6.error(`\u63D2\u4EF6 ${id} \u52A0\u8F7D\u5931\u8D25:`, e);
1664
+ const sortedPluginIds = this.getSortedPluginIds();
1665
+ const missingDeps = /* @__PURE__ */ new Map();
1666
+ const idsToLoad = new Set(sortedPluginIds);
1667
+ for (const id of sortedPluginIds) {
1668
+ const plugin = this.plugins.get(id);
1669
+ if (plugin?.metadata.dependencies) {
1670
+ const missing = plugin.metadata.dependencies.filter((depId) => !this.runtimes.has(depId));
1671
+ if (missing.length > 0) {
1672
+ missingDeps.set(id, missing);
1673
+ idsToLoad.delete(id);
1674
+ this.runtimes.delete(id);
1675
+ }
1680
1676
  }
1681
1677
  }
1682
- }
1683
- for (const id of sortedPluginIds) {
1684
- const runtime = this.runtimes.get(id);
1685
- if (runtime) {
1686
- try {
1687
- await runtime.mount();
1688
- } catch (e) {
1689
- logger6.error(`\u63D2\u4EF6 ${id} \u6302\u8F7D\u5931\u8D25:`, e);
1678
+ if (missingDeps.size > 0) {
1679
+ missingDeps.forEach((deps, id) => {
1680
+ logger6.error(`\u63D2\u4EF6 ${id} \u65E0\u6CD5\u52A0\u8F7D\uFF0C\u7F3A\u5931\u4F9D\u8D56: ${deps.join(", ")}`);
1681
+ });
1682
+ }
1683
+ for (const id of sortedPluginIds) {
1684
+ if (!idsToLoad.has(id)) continue;
1685
+ const runtime = this.runtimes.get(id);
1686
+ if (runtime && runtime.status === "initial") {
1687
+ try {
1688
+ logger6.info(`[PluginManager] invoking onLoad for ${id}`);
1689
+ await runtime.load();
1690
+ logger6.info(`[PluginManager] onLoad completed for ${id}`);
1691
+ } catch (e) {
1692
+ logger6.error(`\u63D2\u4EF6 ${id} \u52A0\u8F7D\u5931\u8D25:`, e);
1693
+ }
1690
1694
  }
1691
1695
  }
1696
+ for (const id of sortedPluginIds) {
1697
+ if (!idsToLoad.has(id)) continue;
1698
+ const runtime = this.runtimes.get(id);
1699
+ if (runtime && (runtime.status === "loaded" || runtime.status === "initial")) {
1700
+ try {
1701
+ await runtime.mount();
1702
+ } catch (e) {
1703
+ logger6.error(`\u63D2\u4EF6 ${id} \u6302\u8F7D\u5931\u8D25:`, e);
1704
+ }
1705
+ }
1706
+ }
1707
+ } finally {
1708
+ this.isInitializing = false;
1692
1709
  }
1693
1710
  }
1694
1711
  /**
@@ -1885,7 +1902,10 @@ var PluginErrorBoundary = class extends Component {
1885
1902
  * @param error - 捕获到的错误
1886
1903
  */
1887
1904
  static getDerivedStateFromError(error) {
1888
- return { hasError: true, error };
1905
+ if (error && typeof error.then === "function") {
1906
+ return { hasError: false, error: null };
1907
+ }
1908
+ return { hasError: true, error: error instanceof Error ? error : new Error(String(error)) };
1889
1909
  }
1890
1910
  /**
1891
1911
  * 捕获到错误后的回调
@@ -1893,6 +1913,9 @@ var PluginErrorBoundary = class extends Component {
1893
1913
  * @param errorInfo - 错误堆栈信息
1894
1914
  */
1895
1915
  componentDidCatch(error, errorInfo) {
1916
+ if (error && typeof error.then === "function") {
1917
+ return;
1918
+ }
1896
1919
  logger7.error(`\u63D2\u4EF6 ${this.props.pluginId || "\u672A\u77E5"} \u6E32\u67D3\u53D1\u751F\u9519\u8BEF:`, error, errorInfo);
1897
1920
  if (this.props.pluginId) {
1898
1921
  console.warn(`[PluginError] \u63D2\u4EF6 "${this.props.pluginId}" \u6E32\u67D3\u5931\u8D25\u3002\u60A8\u53EF\u4EE5\u5728\u63D2\u4EF6\u7BA1\u7406\u9762\u677F\u67E5\u770B\u8BE6\u7EC6\u4FE1\u606F\u3002`);
@@ -1927,8 +1950,33 @@ var PluginErrorBoundary = class extends Component {
1927
1950
  };
1928
1951
 
1929
1952
  // src/components/PluginSlot.tsx
1930
- import { useMemo, useState, useEffect } from "react";
1931
- import { Fragment, jsx as jsx3 } from "react/jsx-runtime";
1953
+ import { useMemo, useState, useEffect, Suspense } from "react";
1954
+
1955
+ // src/components/SlotSkeletons.tsx
1956
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
1957
+ var SidebarIconSkeleton = ({ expanded = false }) => /* @__PURE__ */ jsxs("div", { className: `flex items-center transition-all duration-300 relative
1958
+ ${expanded ? "w-full" : "w-12 justify-center"} px-3 h-11 rounded-xl`, children: [
1959
+ /* @__PURE__ */ jsx3("div", { className: "w-6 h-6 bg-slate-200 dark:bg-white/10 rounded-lg shrink-0 animate-pulse" }),
1960
+ expanded && /* @__PURE__ */ jsx3("div", { className: "ml-3 flex-1 h-4 bg-slate-200 dark:bg-white/10 rounded animate-pulse" })
1961
+ ] });
1962
+ var StatusBarItemSkeleton = () => /* @__PURE__ */ jsx3("div", { className: "h-4 w-16 bg-slate-200 dark:bg-white/10 rounded animate-pulse" });
1963
+ var AvatarSkeleton = () => /* @__PURE__ */ jsx3("div", { className: "w-10 h-10 rounded-full bg-slate-200 dark:bg-white/10 animate-pulse" });
1964
+ var BlockSkeleton = ({ className }) => /* @__PURE__ */ jsx3("div", { className: `bg-slate-200 dark:bg-white/10 rounded animate-pulse ${className || "w-full h-full"}` });
1965
+ var SlotSkeletons = ({ slot, expanded }) => {
1966
+ if (slot.includes("sidebar")) {
1967
+ return /* @__PURE__ */ jsx3(SidebarIconSkeleton, { expanded });
1968
+ }
1969
+ if (slot.includes("status")) {
1970
+ return /* @__PURE__ */ jsx3(StatusBarItemSkeleton, {});
1971
+ }
1972
+ if (slot.includes("avatar")) {
1973
+ return /* @__PURE__ */ jsx3(AvatarSkeleton, {});
1974
+ }
1975
+ return /* @__PURE__ */ jsx3(BlockSkeleton, {});
1976
+ };
1977
+
1978
+ // src/components/PluginSlot.tsx
1979
+ import { Fragment, jsx as jsx4 } from "react/jsx-runtime";
1932
1980
  var PluginSlot = ({
1933
1981
  slot,
1934
1982
  props = {},
@@ -1962,36 +2010,25 @@ var PluginSlot = ({
1962
2010
  return {
1963
2011
  key,
1964
2012
  extension: ext,
1965
- component: /* @__PURE__ */ jsx3(PluginErrorBoundary, { pluginId: ext._pluginId, children: /* @__PURE__ */ jsx3(Component2, { ...mergedProps }) }, key)
2013
+ component: /* @__PURE__ */ jsx4(PluginErrorBoundary, { pluginId: ext._pluginId, children: /* @__PURE__ */ jsx4(Suspense, { fallback: skeleton || /* @__PURE__ */ jsx4(SlotSkeletons, { slot }), children: /* @__PURE__ */ jsx4(Component2, { ...mergedProps }) }) }, key)
1966
2014
  };
1967
2015
  });
1968
2016
  }, [extensions, mergedProps]);
1969
2017
  if (items.length === 0) {
1970
2018
  if (fallback) {
1971
- return /* @__PURE__ */ jsx3(Fragment, { children: fallback });
2019
+ return /* @__PURE__ */ jsx4(Fragment, { children: fallback });
1972
2020
  }
1973
2021
  if (skeleton) {
1974
- return /* @__PURE__ */ jsx3("div", { className: `plugin-slot plugin-slot-${slot} plugin-slot-skeleton ${className || ""}`, style, children: skeleton });
2022
+ return /* @__PURE__ */ jsx4("div", { className: `plugin-slot plugin-slot-${slot} plugin-slot-skeleton ${className || ""}`, style, children: skeleton });
1975
2023
  }
1976
2024
  return null;
1977
2025
  }
1978
2026
  if (items.length === 1 && slot === "root-layout" && !className && !style && !renderItem) {
1979
- return /* @__PURE__ */ jsx3(Fragment, { children: items[0].component });
2027
+ return /* @__PURE__ */ jsx4(Fragment, { children: items[0].component });
1980
2028
  }
1981
- return /* @__PURE__ */ jsx3("div", { className: `plugin-slot plugin-slot-${slot} ${className || ""}`, style, children: renderItem ? items.map((item, index) => renderItem(item, index)) : items.map((item) => item.component) });
2029
+ return /* @__PURE__ */ jsx4("div", { className: `plugin-slot plugin-slot-${slot} ${className || ""}`, style, children: renderItem ? items.map((item, index) => renderItem(item, index)) : items.map((item) => item.component) });
1982
2030
  };
1983
2031
 
1984
- // src/components/SlotSkeletons.tsx
1985
- import { jsx as jsx4, jsxs } from "react/jsx-runtime";
1986
- var SidebarIconSkeleton = ({ expanded = false }) => /* @__PURE__ */ jsxs("div", { className: `flex items-center transition-all duration-300 relative
1987
- ${expanded ? "w-full" : "w-12 justify-center"} px-3 h-11 rounded-xl`, children: [
1988
- /* @__PURE__ */ jsx4("div", { className: "w-6 h-6 bg-slate-200 dark:bg-white/10 rounded-lg shrink-0 animate-pulse" }),
1989
- expanded && /* @__PURE__ */ jsx4("div", { className: "ml-3 flex-1 h-4 bg-slate-200 dark:bg-white/10 rounded animate-pulse" })
1990
- ] });
1991
- var StatusBarItemSkeleton = () => /* @__PURE__ */ jsx4("div", { className: "h-4 w-16 bg-slate-200 dark:bg-white/10 rounded animate-pulse" });
1992
- var AvatarSkeleton = () => /* @__PURE__ */ jsx4("div", { className: "w-10 h-10 rounded-full bg-slate-200 dark:bg-white/10 animate-pulse" });
1993
- var BlockSkeleton = ({ className }) => /* @__PURE__ */ jsx4("div", { className: `bg-slate-200 dark:bg-white/10 rounded animate-pulse ${className || "w-full h-full"}` });
1994
-
1995
2032
  // src/domain/auto-loader.ts
1996
2033
  var logger8 = createLogger("AutoLoader");
1997
2034
  var DEFAULT_RULES = [
@@ -2592,7 +2629,7 @@ var usePluginLoader = (options) => {
2592
2629
  }) : {};
2593
2630
  const finalRegistry = { ...discoveredRegistry, ...manualRegistry };
2594
2631
  if (options.systemConfig) {
2595
- const { configManager: configManager2 } = await import("./config-manager-F3GYW4BE.mjs");
2632
+ const { configManager: configManager2 } = await import("./config-manager-3TKURRUT.mjs");
2596
2633
  configManager2.set("system", options.systemConfig);
2597
2634
  }
2598
2635
  await pluginManager.loadPlugins(pluginConfigs, finalRegistry);
@@ -2640,6 +2677,7 @@ export {
2640
2677
  ServiceRegistry,
2641
2678
  SidebarIconSkeleton,
2642
2679
  Slot,
2680
+ SlotSkeletons,
2643
2681
  StatusBarItemSkeleton,
2644
2682
  StorageManager,
2645
2683
  apiEngine,
@@ -2661,3 +2699,4 @@ export {
2661
2699
  useStorageState,
2662
2700
  version
2663
2701
  };
2702
+ //# sourceMappingURL=index.mjs.map