@chatbi-v/core 3.0.0 → 3.1.1
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/README.md +1 -1
- package/dist/{adapter → adapters}/index.cjs +12 -8
- package/dist/{adapter → adapters}/index.mjs +1 -1
- package/dist/chunk-6ZN23KJA.mjs +60 -0
- package/dist/chunk-AAKBSVX6.mjs +220 -0
- package/dist/{chunk-BOR237QK.mjs → chunk-K6BVKKI6.mjs} +8 -4
- package/dist/index.cjs +510 -214
- package/dist/index.d.cts +32 -1160
- package/dist/index.d.ts +32 -1160
- package/dist/index.mjs +493 -405
- package/dist/manifest/index.cjs +253 -0
- package/dist/manifest/index.d.cts +56 -0
- package/dist/manifest/index.d.ts +56 -0
- package/dist/manifest/index.mjs +20 -0
- package/dist/plugin-port-CHRPxDOi.d.cts +1092 -0
- package/dist/plugin-port-CHRPxDOi.d.ts +1092 -0
- package/dist/semver/index.cjs +449 -0
- package/dist/semver/index.d.cts +192 -0
- package/dist/semver/index.d.ts +192 -0
- package/dist/semver/index.mjs +355 -0
- package/package.json +21 -9
- /package/dist/{adapter → adapters}/index.d.cts +0 -0
- /package/dist/{adapter → adapters}/index.d.ts +0 -0
package/dist/index.mjs
CHANGED
|
@@ -2,11 +2,27 @@ import {
|
|
|
2
2
|
AdapterRegistry,
|
|
3
3
|
BaseAdapter,
|
|
4
4
|
adapterRegistry
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-K6BVKKI6.mjs";
|
|
6
|
+
import {
|
|
7
|
+
EXTENSION_TYPES,
|
|
8
|
+
PLUGIN_TYPES,
|
|
9
|
+
PluginManifestSchema,
|
|
10
|
+
RENDER_MODES,
|
|
11
|
+
assertManifest,
|
|
12
|
+
extractManifestFromPlugin,
|
|
13
|
+
normalizePluginManifest,
|
|
14
|
+
validateManifest
|
|
15
|
+
} from "./chunk-AAKBSVX6.mjs";
|
|
16
|
+
import {
|
|
17
|
+
maxSatisfying
|
|
18
|
+
} from "./chunk-6ZN23KJA.mjs";
|
|
6
19
|
|
|
7
20
|
// src/types/branded.ts
|
|
8
21
|
import { z } from "zod";
|
|
9
|
-
var PluginIdSchema = z.string().min(1, "Plugin ID \u4E0D\u80FD\u4E3A\u7A7A").regex(
|
|
22
|
+
var PluginIdSchema = z.string().min(1, "Plugin ID \u4E0D\u80FD\u4E3A\u7A7A").regex(
|
|
23
|
+
/^[a-zA-Z0-9][-a-zA-Z0-9.]*[a-zA-Z0-9]$/,
|
|
24
|
+
"Plugin ID \u5FC5\u987B\u7B26\u5408\u53CD\u5411\u57DF\u540D\u683C\u5F0F"
|
|
25
|
+
);
|
|
10
26
|
var SlotKeySchema = z.string().min(1, "SlotKey \u4E0D\u80FD\u4E3A\u7A7A");
|
|
11
27
|
function createPluginId(id) {
|
|
12
28
|
const validated = PluginIdSchema.parse(id);
|
|
@@ -66,115 +82,6 @@ function isRoutePath(value) {
|
|
|
66
82
|
}
|
|
67
83
|
}
|
|
68
84
|
|
|
69
|
-
// src/manifest/PluginManifest.ts
|
|
70
|
-
import { z as z3 } from "zod";
|
|
71
|
-
var EXTENSION_TYPES = ["slot", "hook", "command", "service"];
|
|
72
|
-
var RENDER_MODES = ["replace", "append", "prepend"];
|
|
73
|
-
var ExtensionSchema = z3.object({
|
|
74
|
-
/** 扩展点名称/标识符 */
|
|
75
|
-
name: z3.string().min(1, "\u6269\u5C55\u70B9\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A"),
|
|
76
|
-
/** 扩展点类型 */
|
|
77
|
-
type: z3.enum(EXTENSION_TYPES),
|
|
78
|
-
/** 扩展点描述 */
|
|
79
|
-
description: z3.string().optional(),
|
|
80
|
-
/** 对于 slot 类型,指定插槽位置 */
|
|
81
|
-
slot: z3.string().optional(),
|
|
82
|
-
/** 扩展点的配置选项 */
|
|
83
|
-
config: z3.record(z3.any()).optional(),
|
|
84
|
-
/**
|
|
85
|
-
* 渲染模式
|
|
86
|
-
* @description 定义插槽内容的渲染方式:replace(替换)、append(追加)、prepend(前置)
|
|
87
|
-
*/
|
|
88
|
-
renderMode: z3.enum(RENDER_MODES).optional(),
|
|
89
|
-
/**
|
|
90
|
-
* 条件渲染配置
|
|
91
|
-
* @description 用于条件渲染,如 requiresAuth: true 表示需要认证
|
|
92
|
-
*/
|
|
93
|
-
condition: z3.record(z3.any()).optional()
|
|
94
|
-
});
|
|
95
|
-
var DependencySchema = z3.object({
|
|
96
|
-
/** 依赖插件 ID */
|
|
97
|
-
id: z3.string().min(1, "\u4F9D\u8D56\u63D2\u4EF6 ID \u4E0D\u80FD\u4E3A\u7A7A"),
|
|
98
|
-
/** 依赖版本范围 (SemVer) */
|
|
99
|
-
version: z3.string().min(1, "\u4F9D\u8D56\u7248\u672C\u4E0D\u80FD\u4E3A\u7A7A"),
|
|
100
|
-
/** 是否为可选依赖 */
|
|
101
|
-
optional: z3.boolean().optional().default(false)
|
|
102
|
-
});
|
|
103
|
-
var PLUGIN_TYPES = ["business", "functional", "view", "theme", "renderer", "system"];
|
|
104
|
-
var EntrySchema = z3.union([
|
|
105
|
-
z3.string().min(1, "\u5165\u53E3\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A"),
|
|
106
|
-
z3.object({
|
|
107
|
-
/** 入口文件 URL */
|
|
108
|
-
url: z3.string().min(1, "\u5165\u53E3 URL \u4E0D\u80FD\u4E3A\u7A7A"),
|
|
109
|
-
/** 共享作用域 (用于模块联邦) */
|
|
110
|
-
shareScope: z3.string().optional()
|
|
111
|
-
})
|
|
112
|
-
]);
|
|
113
|
-
var CompatibilitySchema = z3.object({
|
|
114
|
-
/** 最低宿主版本 */
|
|
115
|
-
minVersion: z3.string().optional(),
|
|
116
|
-
/** 最高宿主版本 */
|
|
117
|
-
maxVersion: z3.string().optional(),
|
|
118
|
-
/** 兼容的宿主版本列表 */
|
|
119
|
-
supportedVersions: z3.array(z3.string()).optional()
|
|
120
|
-
});
|
|
121
|
-
var CapabilitiesSchema = z3.record(z3.boolean());
|
|
122
|
-
var ConfigurationSchema = z3.array(
|
|
123
|
-
z3.object({
|
|
124
|
-
key: z3.string().min(1),
|
|
125
|
-
type: z3.enum(["string", "number", "boolean", "select"]),
|
|
126
|
-
label: z3.string().min(1),
|
|
127
|
-
description: z3.string().optional(),
|
|
128
|
-
default: z3.any().optional(),
|
|
129
|
-
options: z3.array(z3.object({ label: z3.string(), value: z3.any() })).optional()
|
|
130
|
-
})
|
|
131
|
-
);
|
|
132
|
-
var PERMISSION_ACTIONS = ["read", "write", "execute", "admin"];
|
|
133
|
-
var PERMISSION_SCOPES = ["plugin", "global", "user"];
|
|
134
|
-
var PluginManifestSchema = z3.object({
|
|
135
|
-
/** 插件唯一 ID (推荐反向域名格式) */
|
|
136
|
-
id: z3.string().min(1, "\u63D2\u4EF6 ID \u4E0D\u80FD\u4E3A\u7A7A"),
|
|
137
|
-
/** 插件版本号 (SemVer) */
|
|
138
|
-
version: z3.string().min(1, "\u7248\u672C\u53F7\u4E0D\u80FD\u4E3A\u7A7A").refine(
|
|
139
|
-
(v) => /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/.test(v),
|
|
140
|
-
{ message: "\u7248\u672C\u53F7\u5FC5\u987B\u7B26\u5408 SemVer \u683C\u5F0F" }
|
|
141
|
-
),
|
|
142
|
-
/** 插件显示名称 */
|
|
143
|
-
name: z3.string().min(1, "\u63D2\u4EF6\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A"),
|
|
144
|
-
/** 插件入口 */
|
|
145
|
-
entry: EntrySchema,
|
|
146
|
-
/** 插件类型 */
|
|
147
|
-
type: z3.enum(PLUGIN_TYPES).optional().default("business"),
|
|
148
|
-
/** 插件功能描述 */
|
|
149
|
-
description: z3.string().optional(),
|
|
150
|
-
/** 插件作者 */
|
|
151
|
-
author: z3.string().optional(),
|
|
152
|
-
/** 插件图标 */
|
|
153
|
-
icon: z3.string().optional(),
|
|
154
|
-
/** 兼容性要求 */
|
|
155
|
-
compatibility: CompatibilitySchema.optional(),
|
|
156
|
-
/** 插件依赖 */
|
|
157
|
-
dependencies: z3.array(DependencySchema).optional().default([]),
|
|
158
|
-
/** 扩展点声明 */
|
|
159
|
-
extensions: z3.array(ExtensionSchema).optional().default([]),
|
|
160
|
-
/** 能力声明 */
|
|
161
|
-
capabilities: CapabilitiesSchema.optional(),
|
|
162
|
-
/** 配置项定义 */
|
|
163
|
-
configuration: ConfigurationSchema.optional(),
|
|
164
|
-
/** 存储定义 */
|
|
165
|
-
storage: z3.array(z3.any()).optional(),
|
|
166
|
-
/** 路由定义 (仅供展示,实际路由在运行时注册) */
|
|
167
|
-
routes: z3.array(z3.object({ path: z3.string() })).optional(),
|
|
168
|
-
/** 权限声明 */
|
|
169
|
-
permissions: z3.array(z3.object({
|
|
170
|
-
action: z3.enum(PERMISSION_ACTIONS),
|
|
171
|
-
scope: z3.enum(PERMISSION_SCOPES),
|
|
172
|
-
resource: z3.string()
|
|
173
|
-
})).optional(),
|
|
174
|
-
/** 插件优先级 */
|
|
175
|
-
priority: z3.number().optional().default(100)
|
|
176
|
-
});
|
|
177
|
-
|
|
178
85
|
// src/types/utils.ts
|
|
179
86
|
function isPluginManifest(value) {
|
|
180
87
|
return PluginManifestSchema.safeParse(value).success;
|
|
@@ -195,7 +102,7 @@ var Slot = {
|
|
|
195
102
|
Custom: "custom"
|
|
196
103
|
};
|
|
197
104
|
var BasePlugin = class {
|
|
198
|
-
/**
|
|
105
|
+
/**
|
|
199
106
|
* 插件 ID
|
|
200
107
|
* @description 自动从 metadata.id 获取
|
|
201
108
|
*/
|
|
@@ -346,7 +253,9 @@ var Logger = class _Logger {
|
|
|
346
253
|
return [`%c ${prefix} %c${locStr}`, style, locStyle];
|
|
347
254
|
} else {
|
|
348
255
|
const colorCode = getAnsiColorForString(prefix);
|
|
349
|
-
return [
|
|
256
|
+
return [
|
|
257
|
+
`${colorCode}[${prefix}]${ANSI.reset}${ANSI.dim}${locStr}${ANSI.reset}`
|
|
258
|
+
];
|
|
350
259
|
}
|
|
351
260
|
}
|
|
352
261
|
/**
|
|
@@ -360,11 +269,18 @@ var Logger = class _Logger {
|
|
|
360
269
|
const countStyle = "color: gray; font-size: 0.9em;";
|
|
361
270
|
const locStyle = "color: gray; font-size: 0.8em; font-family: monospace; font-weight: normal;";
|
|
362
271
|
const countStr = count > 0 ? `(${count > 1 ? count + " messages" : "1 message"}${countDetails ? ", " + countDetails : ""})` : "";
|
|
363
|
-
return [
|
|
272
|
+
return [
|
|
273
|
+
`%c ${prefix} %c ${countStr}%c${locStr}`,
|
|
274
|
+
badgeStyle,
|
|
275
|
+
countStyle,
|
|
276
|
+
locStyle
|
|
277
|
+
];
|
|
364
278
|
} else {
|
|
365
279
|
const colorCode = getAnsiColorForString(prefix);
|
|
366
280
|
const countStr = count > 0 ? `(${count > 1 ? count + " messages" : "1 message"}${countDetails ? ", " + countDetails : ""})` : "";
|
|
367
|
-
return [
|
|
281
|
+
return [
|
|
282
|
+
`${colorCode}[${prefix}]${ANSI.reset} ${ANSI.dim}${countStr}${locStr}${ANSI.reset}`
|
|
283
|
+
];
|
|
368
284
|
}
|
|
369
285
|
}
|
|
370
286
|
/**
|
|
@@ -420,14 +336,22 @@ var Logger = class _Logger {
|
|
|
420
336
|
});
|
|
421
337
|
prefixOrder.forEach((prefix) => {
|
|
422
338
|
const entries = groups.get(prefix);
|
|
423
|
-
const counts = entries.reduce(
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
339
|
+
const counts = entries.reduce(
|
|
340
|
+
(acc, curr) => {
|
|
341
|
+
const key = curr.level === 2 /* WARN */ ? "warn" : "info";
|
|
342
|
+
acc[key] = (acc[key] || 0) + 1;
|
|
343
|
+
return acc;
|
|
344
|
+
},
|
|
345
|
+
{}
|
|
346
|
+
);
|
|
428
347
|
const countDetails = Object.entries(counts).map(([k, v]) => `${v} ${k}`).join(", ");
|
|
429
348
|
const lastLocation = entries[entries.length - 1].location;
|
|
430
|
-
const groupTitleArgs = _Logger.getGroupTitleArgs(
|
|
349
|
+
const groupTitleArgs = _Logger.getGroupTitleArgs(
|
|
350
|
+
prefix,
|
|
351
|
+
entries.length,
|
|
352
|
+
entries.length > 1 ? countDetails : "",
|
|
353
|
+
lastLocation
|
|
354
|
+
);
|
|
431
355
|
console.groupCollapsed(...groupTitleArgs);
|
|
432
356
|
entries.forEach((entry) => {
|
|
433
357
|
const method = entry.level === 2 /* WARN */ ? "warn" : entry.level === 0 /* DEBUG */ ? "debug" : "info";
|
|
@@ -472,7 +396,11 @@ var Logger = class _Logger {
|
|
|
472
396
|
if (_Logger.level <= 1 /* INFO */) {
|
|
473
397
|
_Logger.flush();
|
|
474
398
|
const location2 = getCallerLocation();
|
|
475
|
-
const prefixArgs = this.getFormattedPrefix(
|
|
399
|
+
const prefixArgs = this.getFormattedPrefix(
|
|
400
|
+
this.prefix,
|
|
401
|
+
1 /* INFO */,
|
|
402
|
+
location2
|
|
403
|
+
);
|
|
476
404
|
if (_Logger.isBrowser) {
|
|
477
405
|
if (collapsed) {
|
|
478
406
|
console.groupCollapsed(...prefixArgs, label);
|
|
@@ -539,7 +467,7 @@ var ServiceRegistry = class {
|
|
|
539
467
|
* 异步等待并获取服务
|
|
540
468
|
* @description 如果服务尚未注册,将返回一个 Promise,直到该服务被注册时 resolve。
|
|
541
469
|
* 支持设置超时时间,防止因插件加载失败导致的永久挂起。
|
|
542
|
-
*
|
|
470
|
+
*
|
|
543
471
|
* @template T - 服务类型的泛型
|
|
544
472
|
* @param name - 待等待的服务名称
|
|
545
473
|
* @param timeout - 超时时间 (毫秒),默认 10000ms (10秒)。若为 0 则永不超时。
|
|
@@ -568,7 +496,9 @@ var ServiceRegistry = class {
|
|
|
568
496
|
if (set.size === 0) this.listeners.delete(name);
|
|
569
497
|
}
|
|
570
498
|
const availableServices = Array.from(this.services.keys());
|
|
571
|
-
logger2.warn(
|
|
499
|
+
logger2.warn(
|
|
500
|
+
`\u7B49\u5F85\u670D\u52A1 "${name}" \u8D85\u65F6\u3002\u5F53\u524D\u53EF\u7528\u670D\u52A1: ${availableServices.join(", ")}`
|
|
501
|
+
);
|
|
572
502
|
reject(new Error(`\u7B49\u5F85\u670D\u52A1 "${name}" \u8D85\u65F6 (${timeout}ms)`));
|
|
573
503
|
}, timeout);
|
|
574
504
|
}
|
|
@@ -630,7 +560,9 @@ var ConfigManager = class {
|
|
|
630
560
|
* 深度合并两个对象
|
|
631
561
|
*/
|
|
632
562
|
deepMerge(target, source) {
|
|
633
|
-
const result = {
|
|
563
|
+
const result = {
|
|
564
|
+
...target
|
|
565
|
+
};
|
|
634
566
|
if (source === null || source === void 0) {
|
|
635
567
|
return result;
|
|
636
568
|
}
|
|
@@ -681,7 +613,9 @@ var ToolRegistry = class {
|
|
|
681
613
|
*/
|
|
682
614
|
register(tool) {
|
|
683
615
|
if (this.tools.has(tool.name)) {
|
|
684
|
-
console.warn(
|
|
616
|
+
console.warn(
|
|
617
|
+
`[AI Tool] Tool ${tool.name} is already registered, overwriting.`
|
|
618
|
+
);
|
|
685
619
|
}
|
|
686
620
|
this.tools.set(tool.name, tool);
|
|
687
621
|
}
|
|
@@ -721,8 +655,14 @@ var MockAIProvider = class {
|
|
|
721
655
|
["greeting", "\u4F60\u597D\uFF01\u6211\u662F AI \u52A9\u624B\uFF0C\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u52A9\u4F60\u7684\u5417\uFF1F"],
|
|
722
656
|
["weather", "\u4ECA\u5929\u5929\u6C14\u6674\u6717\uFF0C\u9002\u5408\u51FA\u884C\uFF01"],
|
|
723
657
|
["time", `\u73B0\u5728\u65F6\u95F4\u662F ${(/* @__PURE__ */ new Date()).toLocaleString()}`],
|
|
724
|
-
[
|
|
725
|
-
|
|
658
|
+
[
|
|
659
|
+
"help",
|
|
660
|
+
"\u6211\u53EF\u4EE5\u5E2E\u4F60\uFF1A\n1. \u67E5\u8BE2\u5929\u6C14\n2. \u6267\u884C\u8BA1\u7B97\n3. \u83B7\u53D6\u65F6\u95F4\n4. \u56DE\u7B54\u95EE\u9898"
|
|
661
|
+
],
|
|
662
|
+
[
|
|
663
|
+
"default",
|
|
664
|
+
'\u6211\u6536\u5230\u4F60\u7684\u6D88\u606F: "{input}"\u3002\u4F60\u53EF\u4EE5\u95EE\u6211\u5929\u6C14\u3001\u65F6\u95F4\uFF0C\u6216\u8005\u9700\u8981\u4EC0\u4E48\u5E2E\u52A9\uFF1F'
|
|
665
|
+
]
|
|
726
666
|
]);
|
|
727
667
|
/**
|
|
728
668
|
* 生成回复
|
|
@@ -733,7 +673,9 @@ var MockAIProvider = class {
|
|
|
733
673
|
return this.responses.get("greeting");
|
|
734
674
|
}
|
|
735
675
|
if (/(天气|weather)/i.test(input)) {
|
|
736
|
-
const cityMatch = input.match(
|
|
676
|
+
const cityMatch = input.match(
|
|
677
|
+
/(?:在|到|北京|上海|广州|深圳|杭州)?(.+?(?:天气|weather))/i
|
|
678
|
+
);
|
|
737
679
|
const city = cityMatch?.[1]?.replace(/天气|weather/gi, "").trim() || "\u5317\u4EAC";
|
|
738
680
|
return `${city} \u4ECA\u5929\u5929\u6C14\u6674\u6717\uFF0C25\xB0C\uFF0C\u9002\u5408\u51FA\u884C\uFF01`;
|
|
739
681
|
}
|
|
@@ -755,7 +697,9 @@ var MockAIProvider = class {
|
|
|
755
697
|
* 聊天(非流式)
|
|
756
698
|
*/
|
|
757
699
|
async chat(messages, options) {
|
|
758
|
-
await new Promise(
|
|
700
|
+
await new Promise(
|
|
701
|
+
(resolve) => setTimeout(resolve, 500 + Math.random() * 500)
|
|
702
|
+
);
|
|
759
703
|
const lastMessage = messages[messages.length - 1];
|
|
760
704
|
const content = lastMessage?.content || "";
|
|
761
705
|
return {
|
|
@@ -777,7 +721,9 @@ var MockAIProvider = class {
|
|
|
777
721
|
type: "content",
|
|
778
722
|
content: char
|
|
779
723
|
};
|
|
780
|
-
await new Promise(
|
|
724
|
+
await new Promise(
|
|
725
|
+
(resolve) => setTimeout(resolve, 30 + Math.random() * 50)
|
|
726
|
+
);
|
|
781
727
|
}
|
|
782
728
|
yield { type: "done" };
|
|
783
729
|
}
|
|
@@ -975,7 +921,9 @@ var SessionManager = class {
|
|
|
975
921
|
return this.sessions.get(id) || null;
|
|
976
922
|
}
|
|
977
923
|
listSessions() {
|
|
978
|
-
return Array.from(this.sessions.values()).sort(
|
|
924
|
+
return Array.from(this.sessions.values()).sort(
|
|
925
|
+
(a, b) => b.updatedAt - a.updatedAt
|
|
926
|
+
);
|
|
979
927
|
}
|
|
980
928
|
deleteSession(id) {
|
|
981
929
|
this.sessions.delete(id);
|
|
@@ -1036,8 +984,8 @@ var SessionLocalStorageAdapter = class {
|
|
|
1036
984
|
};
|
|
1037
985
|
|
|
1038
986
|
// src/ai/store.ts
|
|
1039
|
-
import {
|
|
1040
|
-
var
|
|
987
|
+
import { createStore } from "zustand/vanilla";
|
|
988
|
+
var aiStore = createStore((set, get) => ({
|
|
1041
989
|
// Initial state
|
|
1042
990
|
provider: null,
|
|
1043
991
|
sessions: [],
|
|
@@ -1135,7 +1083,7 @@ var useAIStore = create((set, get) => ({
|
|
|
1135
1083
|
}));
|
|
1136
1084
|
function createAIStore(apiKey, defaultModel) {
|
|
1137
1085
|
const provider = new OpenAIProvider(apiKey, { model: defaultModel });
|
|
1138
|
-
|
|
1086
|
+
aiStore.getState().setProvider(provider);
|
|
1139
1087
|
}
|
|
1140
1088
|
|
|
1141
1089
|
// src/domain/auto-loader.ts
|
|
@@ -1144,13 +1092,17 @@ var DEFAULT_RULES = [
|
|
|
1144
1092
|
{ pathSegment: "@chatbi-plugins", idPrefix: "@chatbi-v/plugin" },
|
|
1145
1093
|
{ pathSegment: "@chatbi-apps", idPrefix: "@chatbi-v/app" },
|
|
1146
1094
|
{ pathSegment: "packages/plugins", idPrefix: "@chatbi-v/plugin" },
|
|
1147
|
-
{ pathSegment: "packages/apps", idPrefix: "@chatbi-v/app" }
|
|
1095
|
+
{ pathSegment: "packages/apps", idPrefix: "@chatbi-v/app" },
|
|
1096
|
+
{ pathSegment: "apps", idPrefix: "@chatbi-v/app" }
|
|
1148
1097
|
];
|
|
1149
1098
|
var resolvePluginRegistry = (options) => {
|
|
1150
1099
|
const { modules, rules = DEFAULT_RULES } = options;
|
|
1151
1100
|
const registry = {};
|
|
1152
1101
|
const compiledRules = rules.map((rule) => {
|
|
1153
|
-
const escapedSegment = rule.pathSegment.replace(
|
|
1102
|
+
const escapedSegment = rule.pathSegment.replace(
|
|
1103
|
+
/[.*+?^${}()|[\]\\]/g,
|
|
1104
|
+
"\\$&"
|
|
1105
|
+
);
|
|
1154
1106
|
return {
|
|
1155
1107
|
...rule,
|
|
1156
1108
|
regex: new RegExp(`${escapedSegment}/([^/]+)/src/index`)
|
|
@@ -1230,7 +1182,7 @@ var CoreError = class extends Error {
|
|
|
1230
1182
|
}
|
|
1231
1183
|
};
|
|
1232
1184
|
function handleError(error, options) {
|
|
1233
|
-
const { code, strategy, defaultValue, logger:
|
|
1185
|
+
const { code, strategy, defaultValue, logger: logger11, context } = options;
|
|
1234
1186
|
const coreError = error instanceof CoreError ? error : new CoreError(
|
|
1235
1187
|
code,
|
|
1236
1188
|
error instanceof Error ? error.message : String(error),
|
|
@@ -1239,16 +1191,16 @@ function handleError(error, options) {
|
|
|
1239
1191
|
);
|
|
1240
1192
|
switch (strategy) {
|
|
1241
1193
|
case "throw" /* THROW */:
|
|
1242
|
-
|
|
1194
|
+
logger11?.error(`[${code}] \u9519\u8BEF\u629B\u51FA:`, coreError);
|
|
1243
1195
|
throw coreError;
|
|
1244
1196
|
case "resolve" /* RESOLVE */:
|
|
1245
|
-
|
|
1197
|
+
logger11?.warn(`[${code}] \u9519\u8BEF\u5DF2\u964D\u7EA7:`, coreError);
|
|
1246
1198
|
return defaultValue;
|
|
1247
1199
|
case "reject" /* REJECT */:
|
|
1248
|
-
|
|
1200
|
+
logger11?.error(`[${code}] \u9519\u8BEF\u62D2\u7EDD:`, coreError);
|
|
1249
1201
|
return Promise.reject(coreError);
|
|
1250
1202
|
case "silent" /* SILENT */:
|
|
1251
|
-
|
|
1203
|
+
logger11?.debug(`[${code}] \u9519\u8BEF\u5DF2\u9759\u9ED8:`, coreError);
|
|
1252
1204
|
return defaultValue;
|
|
1253
1205
|
}
|
|
1254
1206
|
}
|
|
@@ -1496,7 +1448,9 @@ var PerformanceStorage = class {
|
|
|
1496
1448
|
*/
|
|
1497
1449
|
enforceLifecycleLimit() {
|
|
1498
1450
|
if (this.lifecycleCache.length > this.settings.maxLifecycleRecords) {
|
|
1499
|
-
this.lifecycleCache = this.lifecycleCache.slice(
|
|
1451
|
+
this.lifecycleCache = this.lifecycleCache.slice(
|
|
1452
|
+
-this.settings.maxLifecycleRecords
|
|
1453
|
+
);
|
|
1500
1454
|
}
|
|
1501
1455
|
}
|
|
1502
1456
|
/**
|
|
@@ -1504,7 +1458,9 @@ var PerformanceStorage = class {
|
|
|
1504
1458
|
*/
|
|
1505
1459
|
enforceRuntimeLimit() {
|
|
1506
1460
|
if (this.runtimeCache.length > this.settings.maxRuntimeSamples) {
|
|
1507
|
-
this.runtimeCache = this.runtimeCache.slice(
|
|
1461
|
+
this.runtimeCache = this.runtimeCache.slice(
|
|
1462
|
+
-this.settings.maxRuntimeSamples
|
|
1463
|
+
);
|
|
1508
1464
|
}
|
|
1509
1465
|
}
|
|
1510
1466
|
/**
|
|
@@ -1512,7 +1468,10 @@ var PerformanceStorage = class {
|
|
|
1512
1468
|
*/
|
|
1513
1469
|
persistLifecycle() {
|
|
1514
1470
|
try {
|
|
1515
|
-
this.systemStorage.setItem(
|
|
1471
|
+
this.systemStorage.setItem(
|
|
1472
|
+
this.LIFECYCLE_KEY,
|
|
1473
|
+
JSON.stringify(this.lifecycleCache)
|
|
1474
|
+
);
|
|
1516
1475
|
} catch (e) {
|
|
1517
1476
|
console.warn("[PerformanceStorage] Failed to persist lifecycle:", e);
|
|
1518
1477
|
}
|
|
@@ -1522,7 +1481,10 @@ var PerformanceStorage = class {
|
|
|
1522
1481
|
*/
|
|
1523
1482
|
persistRuntime() {
|
|
1524
1483
|
try {
|
|
1525
|
-
this.systemStorage.setItem(
|
|
1484
|
+
this.systemStorage.setItem(
|
|
1485
|
+
this.RUNTIME_KEY,
|
|
1486
|
+
JSON.stringify(this.runtimeCache)
|
|
1487
|
+
);
|
|
1526
1488
|
} catch (e) {
|
|
1527
1489
|
console.warn("[PerformanceStorage] Failed to persist runtime:", e);
|
|
1528
1490
|
}
|
|
@@ -1558,8 +1520,12 @@ var PerformanceStorage = class {
|
|
|
1558
1520
|
this.systemStorage.removeItem(this.LIFECYCLE_KEY);
|
|
1559
1521
|
this.systemStorage.removeItem(this.RUNTIME_KEY);
|
|
1560
1522
|
} else {
|
|
1561
|
-
this.lifecycleCache = this.lifecycleCache.filter(
|
|
1562
|
-
|
|
1523
|
+
this.lifecycleCache = this.lifecycleCache.filter(
|
|
1524
|
+
(m) => m.pluginId !== pluginId
|
|
1525
|
+
);
|
|
1526
|
+
this.runtimeCache = this.runtimeCache.filter(
|
|
1527
|
+
(m) => m.pluginId !== pluginId
|
|
1528
|
+
);
|
|
1563
1529
|
this.persistLifecycle();
|
|
1564
1530
|
this.persistRuntime();
|
|
1565
1531
|
}
|
|
@@ -1651,7 +1617,7 @@ var LocalStorageAdapter = class {
|
|
|
1651
1617
|
}
|
|
1652
1618
|
/**
|
|
1653
1619
|
* 清空存储空间
|
|
1654
|
-
* @description
|
|
1620
|
+
* @description
|
|
1655
1621
|
* - 若定义了前缀:仅删除以该前缀开头的键名,不影响其他数据。
|
|
1656
1622
|
* - 若未定义前缀:调用原生 `localStorage.clear()` 清空所有数据。
|
|
1657
1623
|
*/
|
|
@@ -1761,8 +1727,8 @@ var DefaultEventBus = class {
|
|
|
1761
1727
|
};
|
|
1762
1728
|
|
|
1763
1729
|
// src/store.ts
|
|
1764
|
-
import { createStore } from "zustand/vanilla";
|
|
1765
|
-
var coreStore =
|
|
1730
|
+
import { createStore as createStore2 } from "zustand/vanilla";
|
|
1731
|
+
var coreStore = createStore2((set) => ({
|
|
1766
1732
|
pluginVersion: 0,
|
|
1767
1733
|
slotVersions: {},
|
|
1768
1734
|
routeVersion: 0,
|
|
@@ -1833,7 +1799,12 @@ var ProxySandbox = class {
|
|
|
1833
1799
|
allowNetwork: true,
|
|
1834
1800
|
...options
|
|
1835
1801
|
};
|
|
1836
|
-
const dangerousGlobals = [
|
|
1802
|
+
const dangerousGlobals = [
|
|
1803
|
+
"eval",
|
|
1804
|
+
"Function",
|
|
1805
|
+
"importScripts",
|
|
1806
|
+
"execScript"
|
|
1807
|
+
];
|
|
1837
1808
|
for (const dangerous of dangerousGlobals) {
|
|
1838
1809
|
if (typeof globalContext[dangerous] !== "undefined") {
|
|
1839
1810
|
logger6.warn(
|
|
@@ -1899,11 +1870,17 @@ var ProxySandbox = class {
|
|
|
1899
1870
|
*/
|
|
1900
1871
|
inactive() {
|
|
1901
1872
|
this.running = false;
|
|
1902
|
-
this.effectPool.timeouts.forEach(
|
|
1873
|
+
this.effectPool.timeouts.forEach(
|
|
1874
|
+
(id) => this.globalContext.clearTimeout(id)
|
|
1875
|
+
);
|
|
1903
1876
|
this.effectPool.timeouts.clear();
|
|
1904
|
-
this.effectPool.intervals.forEach(
|
|
1877
|
+
this.effectPool.intervals.forEach(
|
|
1878
|
+
(id) => this.globalContext.clearInterval(id)
|
|
1879
|
+
);
|
|
1905
1880
|
this.effectPool.intervals.clear();
|
|
1906
|
-
this.effectPool.rafs.forEach(
|
|
1881
|
+
this.effectPool.rafs.forEach(
|
|
1882
|
+
(id) => this.globalContext.cancelAnimationFrame(id)
|
|
1883
|
+
);
|
|
1907
1884
|
this.effectPool.rafs.clear();
|
|
1908
1885
|
this.effectPool.listeners.forEach((listeners, type) => {
|
|
1909
1886
|
listeners.forEach(({ listener, options }) => {
|
|
@@ -2050,7 +2027,9 @@ var ProxySandbox = class {
|
|
|
2050
2027
|
fakeWindow.removeEventListener = (type, listener, options) => {
|
|
2051
2028
|
const listeners = this.effectPool.listeners.get(type);
|
|
2052
2029
|
if (listeners) {
|
|
2053
|
-
const index = listeners.findIndex(
|
|
2030
|
+
const index = listeners.findIndex(
|
|
2031
|
+
(item) => item.listener === listener && item.options === options
|
|
2032
|
+
);
|
|
2054
2033
|
if (index !== -1) listeners.splice(index, 1);
|
|
2055
2034
|
}
|
|
2056
2035
|
return this.globalContext.removeEventListener(type, listener, options);
|
|
@@ -2149,36 +2128,43 @@ var PluginRuntime = class {
|
|
|
2149
2128
|
logger7.debug(`\u5DF2\u4E3A\u63D2\u4EF6 ${this.plugin.id} \u81EA\u52A8\u6CE8\u518C API \u914D\u7F6E`);
|
|
2150
2129
|
}
|
|
2151
2130
|
if (this.plugin.metadata.configuration && this.plugin.metadata.configuration.length > 0) {
|
|
2152
|
-
const configMap = new Map(
|
|
2131
|
+
const configMap = new Map(
|
|
2132
|
+
this.plugin.metadata.configuration.map((c) => [c.key, c])
|
|
2133
|
+
);
|
|
2153
2134
|
const getterCache = /* @__PURE__ */ new Map();
|
|
2154
|
-
const configService = new Proxy(
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
if (getterCache.has(prop)) {
|
|
2161
|
-
return getterCache.get(prop);
|
|
2135
|
+
const configService = new Proxy(
|
|
2136
|
+
{},
|
|
2137
|
+
{
|
|
2138
|
+
get: (target, prop) => {
|
|
2139
|
+
if (typeof prop !== "string") {
|
|
2140
|
+
return Reflect.get(target, prop);
|
|
2162
2141
|
}
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2142
|
+
if (prop.startsWith("get")) {
|
|
2143
|
+
if (getterCache.has(prop)) {
|
|
2144
|
+
return getterCache.get(prop);
|
|
2145
|
+
}
|
|
2146
|
+
const configKey = prop.slice(3).charAt(0).toLowerCase() + prop.slice(3).slice(1);
|
|
2147
|
+
const configItem = configMap.get(configKey);
|
|
2148
|
+
if (configItem) {
|
|
2149
|
+
if (configItem.private || configItem.internal) {
|
|
2150
|
+
logger7.warn(`\u5C1D\u8BD5\u8BBF\u95EE\u79C1\u6709\u914D\u7F6E: ${configKey}`);
|
|
2151
|
+
const noop = () => void 0;
|
|
2152
|
+
getterCache.set(prop, noop);
|
|
2153
|
+
return noop;
|
|
2154
|
+
}
|
|
2155
|
+
const getter = () => this.context.storage.get(configKey);
|
|
2156
|
+
getterCache.set(prop, getter);
|
|
2157
|
+
return getter;
|
|
2171
2158
|
}
|
|
2172
|
-
const getter = () => this.context.storage.get(configKey);
|
|
2173
|
-
getterCache.set(prop, getter);
|
|
2174
|
-
return getter;
|
|
2175
2159
|
}
|
|
2160
|
+
return Reflect.get(target, prop);
|
|
2176
2161
|
}
|
|
2177
|
-
return Reflect.get(target, prop);
|
|
2178
2162
|
}
|
|
2179
|
-
|
|
2163
|
+
);
|
|
2180
2164
|
this.context.registerService("config", configService);
|
|
2181
|
-
logger7.debug(
|
|
2165
|
+
logger7.debug(
|
|
2166
|
+
`\u5DF2\u4E3A\u63D2\u4EF6 ${this.plugin.id} \u81EA\u52A8\u6CE8\u518C\u914D\u7F6E\u670D\u52A1 (Proxy Mode)`
|
|
2167
|
+
);
|
|
2182
2168
|
}
|
|
2183
2169
|
if (this.plugin.onLoad) {
|
|
2184
2170
|
await this.plugin.onLoad(this.context);
|
|
@@ -2373,6 +2359,7 @@ var ScopedStorageAdapter = class {
|
|
|
2373
2359
|
};
|
|
2374
2360
|
|
|
2375
2361
|
// src/domain/storage-manager.ts
|
|
2362
|
+
var logger8 = createLogger("StorageManager");
|
|
2376
2363
|
var DEFAULT_MAX_CACHE_SIZE = 100;
|
|
2377
2364
|
var LRUCache = class {
|
|
2378
2365
|
constructor(maxSize = DEFAULT_MAX_CACHE_SIZE) {
|
|
@@ -2436,6 +2423,22 @@ var StorageManager = class {
|
|
|
2436
2423
|
registerSchema(pluginId, schema) {
|
|
2437
2424
|
this.schemas.set(pluginId, schema);
|
|
2438
2425
|
}
|
|
2426
|
+
/**
|
|
2427
|
+
* 删除插件的所有存储数据
|
|
2428
|
+
* @description 包括插件私有存储、上下文存储、注册 Schema 及内存缓存
|
|
2429
|
+
* @param pluginId - 插件 ID
|
|
2430
|
+
*/
|
|
2431
|
+
deletePluginStorage(pluginId) {
|
|
2432
|
+
const pluginPrefix = `plugin:${pluginId}:`;
|
|
2433
|
+
this.schemas.delete(pluginId);
|
|
2434
|
+
const cacheKeys = this.memoryCache.keys();
|
|
2435
|
+
cacheKeys.forEach((key) => {
|
|
2436
|
+
if (key.startsWith(pluginPrefix)) {
|
|
2437
|
+
this.memoryCache.delete(key);
|
|
2438
|
+
}
|
|
2439
|
+
});
|
|
2440
|
+
logger8.debug(`[StorageManager] Deleted storage for plugin: ${pluginId}`);
|
|
2441
|
+
}
|
|
2439
2442
|
/**
|
|
2440
2443
|
* 内部校验方法:检查键名是否在 Schema 中声明
|
|
2441
2444
|
* @param pluginId - 插件 ID
|
|
@@ -2447,12 +2450,16 @@ var StorageManager = class {
|
|
|
2447
2450
|
if (!schemaList) return;
|
|
2448
2451
|
const item = schemaList.find((s) => s.key === key);
|
|
2449
2452
|
if (!item) {
|
|
2450
|
-
console.warn(
|
|
2453
|
+
console.warn(
|
|
2454
|
+
`[Storage] Key "${key}" not defined in plugin "${pluginId}" schema.`
|
|
2455
|
+
);
|
|
2451
2456
|
return;
|
|
2452
2457
|
}
|
|
2453
2458
|
const definedScope = item.scope || "plugin";
|
|
2454
2459
|
if (definedScope !== scope) {
|
|
2455
|
-
console.warn(
|
|
2460
|
+
console.warn(
|
|
2461
|
+
`[Storage] Key "${key}" defined in scope "${definedScope}" but accessed via "${scope}".`
|
|
2462
|
+
);
|
|
2456
2463
|
}
|
|
2457
2464
|
}
|
|
2458
2465
|
/**
|
|
@@ -2485,7 +2492,7 @@ var StorageManager = class {
|
|
|
2485
2492
|
* - 自动序列化/反序列化 JSON。
|
|
2486
2493
|
* - 自动校验 Schema。
|
|
2487
2494
|
* - 取值回退逻辑:持久化存储 -> ConfigManager -> Schema 默认值。
|
|
2488
|
-
*
|
|
2495
|
+
*
|
|
2489
2496
|
* @param pluginId - 插件 ID
|
|
2490
2497
|
* @returns 包含 get/set/remove 及 shared 子对象的复合接口
|
|
2491
2498
|
*/
|
|
@@ -2555,7 +2562,7 @@ var StorageManager = class {
|
|
|
2555
2562
|
};
|
|
2556
2563
|
|
|
2557
2564
|
// src/domain/plugin-manager.ts
|
|
2558
|
-
var
|
|
2565
|
+
var logger9 = createLogger("PluginManager");
|
|
2559
2566
|
var PluginErrorType = /* @__PURE__ */ ((PluginErrorType2) => {
|
|
2560
2567
|
PluginErrorType2["RECOVERABLE"] = "recoverable";
|
|
2561
2568
|
PluginErrorType2["FATAL"] = "fatal";
|
|
@@ -2689,10 +2696,10 @@ var PluginManager = class {
|
|
|
2689
2696
|
const savedStates = systemStorage.getItem("plugin_states");
|
|
2690
2697
|
if (savedStates) {
|
|
2691
2698
|
this.pluginStates = JSON.parse(savedStates);
|
|
2692
|
-
|
|
2699
|
+
logger9.debug("\u4ECE\u7CFB\u7EDF\u5B58\u50A8\u4E2D\u52A0\u8F7D\u72B6\u6001:", this.pluginStates);
|
|
2693
2700
|
}
|
|
2694
2701
|
} catch (e) {
|
|
2695
|
-
|
|
2702
|
+
logger9.error("\u52A0\u8F7D\u63D2\u4EF6\u72B6\u6001\u5931\u8D25:", e);
|
|
2696
2703
|
}
|
|
2697
2704
|
}
|
|
2698
2705
|
/**
|
|
@@ -2701,9 +2708,9 @@ var PluginManager = class {
|
|
|
2701
2708
|
saveStates() {
|
|
2702
2709
|
try {
|
|
2703
2710
|
this.storageManager.getSystemStorage().setItem("plugin_states", JSON.stringify(this.pluginStates));
|
|
2704
|
-
|
|
2711
|
+
logger9.debug("\u5DF2\u4FDD\u5B58\u63D2\u4EF6\u72B6\u6001\u5230\u5B58\u50A8");
|
|
2705
2712
|
} catch (e) {
|
|
2706
|
-
|
|
2713
|
+
logger9.error("\u4FDD\u5B58\u63D2\u4EF6\u72B6\u6001\u5931\u8D25:", e);
|
|
2707
2714
|
}
|
|
2708
2715
|
}
|
|
2709
2716
|
/**
|
|
@@ -2808,7 +2815,9 @@ var PluginManager = class {
|
|
|
2808
2815
|
if (this.sharedContext) {
|
|
2809
2816
|
await this.mountPlugin(pluginId);
|
|
2810
2817
|
} else {
|
|
2811
|
-
|
|
2818
|
+
logger9.warn(
|
|
2819
|
+
`PluginManager \u5C1A\u672A\u521D\u59CB\u5316\uFF0C\u63D2\u4EF6 ${pluginId} \u5DF2\u6807\u8BB0\u4E3A\u542F\u7528\u4F46\u672A\u6302\u8F7D\u3002\u8BF7\u786E\u4FDD\u8C03\u7528 initPlugins()\u3002`
|
|
2820
|
+
);
|
|
2812
2821
|
}
|
|
2813
2822
|
}
|
|
2814
2823
|
/**
|
|
@@ -2895,17 +2904,116 @@ var PluginManager = class {
|
|
|
2895
2904
|
const plugin = this.plugins.get(pluginId);
|
|
2896
2905
|
if (plugin) {
|
|
2897
2906
|
try {
|
|
2898
|
-
const runtime = new PluginRuntime(
|
|
2907
|
+
const runtime = new PluginRuntime(
|
|
2908
|
+
plugin,
|
|
2909
|
+
this.sharedContext,
|
|
2910
|
+
this.storageManager
|
|
2911
|
+
);
|
|
2899
2912
|
this.runtimes.set(pluginId, runtime);
|
|
2900
2913
|
runtime.mount();
|
|
2901
2914
|
} catch (e) {
|
|
2902
|
-
|
|
2915
|
+
logger9.error(`\u542F\u7528\u63D2\u4EF6 ${pluginId} \u5931\u8D25:`, e);
|
|
2903
2916
|
}
|
|
2904
2917
|
}
|
|
2905
2918
|
}
|
|
2906
2919
|
}
|
|
2907
2920
|
this.notify();
|
|
2908
2921
|
}
|
|
2922
|
+
/**
|
|
2923
|
+
* 删除插件及其所有关联状态
|
|
2924
|
+
* @description 完整清理流程:禁用 -> 卸载运行时 -> 清理存储 -> 清理配置 -> 清理状态 -> 通知
|
|
2925
|
+
* @param pluginId - 插件 ID
|
|
2926
|
+
* @param cleanupStorage - 是否清理存储(默认 true)
|
|
2927
|
+
*/
|
|
2928
|
+
async deletePlugin(pluginId, cleanupStorage = true) {
|
|
2929
|
+
logger9.info(`[PluginManager] Deleting plugin: ${pluginId}`);
|
|
2930
|
+
if (!this.plugins.has(pluginId)) {
|
|
2931
|
+
logger9.warn(
|
|
2932
|
+
`[PluginManager] Plugin ${pluginId} not found, skipping delete`
|
|
2933
|
+
);
|
|
2934
|
+
return;
|
|
2935
|
+
}
|
|
2936
|
+
this.togglePlugin(pluginId, false);
|
|
2937
|
+
if (cleanupStorage) {
|
|
2938
|
+
this.storageManager.deletePluginStorage(pluginId);
|
|
2939
|
+
}
|
|
2940
|
+
configManager.delete(pluginId);
|
|
2941
|
+
this.plugins.delete(pluginId);
|
|
2942
|
+
this.runtimes.delete(pluginId);
|
|
2943
|
+
delete this.pluginStates[pluginId];
|
|
2944
|
+
this.extensions.forEach((extList, slot) => {
|
|
2945
|
+
const filtered = extList.filter((ext) => ext._pluginId !== pluginId);
|
|
2946
|
+
if (filtered.length !== extList.length) {
|
|
2947
|
+
this.extensions.set(slot, filtered);
|
|
2948
|
+
}
|
|
2949
|
+
});
|
|
2950
|
+
this.memoizedExtensions.clear();
|
|
2951
|
+
this.memoizedRoutes = null;
|
|
2952
|
+
this.notify();
|
|
2953
|
+
logger9.info(`[PluginManager] Plugin ${pluginId} deleted successfully`);
|
|
2954
|
+
}
|
|
2955
|
+
/**
|
|
2956
|
+
* 更新插件元数据和包地址
|
|
2957
|
+
* @description 更新流程:禁用旧版本 -> 卸载 -> 更新元数据 -> 重新加载并激活
|
|
2958
|
+
* @param pluginId - 插件 ID
|
|
2959
|
+
* @param newManifest - 新的插件清单
|
|
2960
|
+
* @param newBundleUrl - 新的包地址(可选,如果不改变则传 undefined)
|
|
2961
|
+
*/
|
|
2962
|
+
async updatePlugin(pluginId, newManifest, newBundleUrl) {
|
|
2963
|
+
logger9.info(`[PluginManager] Updating plugin: ${pluginId}`);
|
|
2964
|
+
const existingPlugin = this.plugins.get(pluginId);
|
|
2965
|
+
if (!existingPlugin) {
|
|
2966
|
+
logger9.warn(
|
|
2967
|
+
`[PluginManager] Plugin ${pluginId} not found, cannot update`
|
|
2968
|
+
);
|
|
2969
|
+
return;
|
|
2970
|
+
}
|
|
2971
|
+
this.togglePlugin(pluginId, false);
|
|
2972
|
+
this.runtimes.delete(pluginId);
|
|
2973
|
+
const updatedPlugin = {
|
|
2974
|
+
...existingPlugin,
|
|
2975
|
+
// @ts-expect-error - existing type issue
|
|
2976
|
+
metadata: {
|
|
2977
|
+
...existingPlugin.metadata,
|
|
2978
|
+
...newManifest,
|
|
2979
|
+
// 确保 ID 不被覆盖
|
|
2980
|
+
id: pluginId
|
|
2981
|
+
}
|
|
2982
|
+
};
|
|
2983
|
+
if (newBundleUrl) {
|
|
2984
|
+
try {
|
|
2985
|
+
const reloadedPlugin = await this.loadRemotePlugin(
|
|
2986
|
+
pluginId,
|
|
2987
|
+
newBundleUrl,
|
|
2988
|
+
{ version: newManifest.version }
|
|
2989
|
+
);
|
|
2990
|
+
if (reloadedPlugin) {
|
|
2991
|
+
reloadedPlugin.metadata = {
|
|
2992
|
+
...reloadedPlugin.metadata,
|
|
2993
|
+
...newManifest,
|
|
2994
|
+
id: pluginId
|
|
2995
|
+
};
|
|
2996
|
+
this.plugins.set(pluginId, reloadedPlugin);
|
|
2997
|
+
} else {
|
|
2998
|
+
this.plugins.set(pluginId, updatedPlugin);
|
|
2999
|
+
}
|
|
3000
|
+
} catch (e) {
|
|
3001
|
+
logger9.error(
|
|
3002
|
+
`[PluginManager] Failed to reload plugin ${pluginId} from ${newBundleUrl}:`,
|
|
3003
|
+
e
|
|
3004
|
+
);
|
|
3005
|
+
this.plugins.set(pluginId, updatedPlugin);
|
|
3006
|
+
}
|
|
3007
|
+
} else {
|
|
3008
|
+
this.plugins.set(pluginId, updatedPlugin);
|
|
3009
|
+
}
|
|
3010
|
+
const pluginToRegister = this.plugins.get(pluginId);
|
|
3011
|
+
if (pluginToRegister) {
|
|
3012
|
+
this.register(pluginToRegister, true);
|
|
3013
|
+
}
|
|
3014
|
+
this.notify();
|
|
3015
|
+
logger9.info(`[PluginManager] Plugin ${pluginId} updated successfully`);
|
|
3016
|
+
}
|
|
2909
3017
|
/**
|
|
2910
3018
|
* 设置插件的显示排序权重
|
|
2911
3019
|
* @param pluginId - 插件 ID
|
|
@@ -2969,7 +3077,7 @@ var PluginManager = class {
|
|
|
2969
3077
|
try {
|
|
2970
3078
|
this.storageManager.getContextStorage(pluginId).set(key, value);
|
|
2971
3079
|
} catch (e) {
|
|
2972
|
-
|
|
3080
|
+
logger9.warn("\u4FDD\u5B58\u914D\u7F6E\u5230\u5B58\u50A8\u5931\u8D25", e);
|
|
2973
3081
|
}
|
|
2974
3082
|
this.eventBus.emit("config:changed", { pluginId, key, value });
|
|
2975
3083
|
}
|
|
@@ -3020,7 +3128,9 @@ var PluginManager = class {
|
|
|
3020
3128
|
const runtime = this.runtimes.get(pluginId);
|
|
3021
3129
|
return runtime ? runtime.isLoadedStatus() : false;
|
|
3022
3130
|
});
|
|
3023
|
-
const sortedExtensions = extensions.sort(
|
|
3131
|
+
const sortedExtensions = extensions.sort(
|
|
3132
|
+
(a, b) => (a.order || 0) - (b.order || 0)
|
|
3133
|
+
);
|
|
3024
3134
|
this.memoizedExtensions.set(slotStr, sortedExtensions);
|
|
3025
3135
|
return sortedExtensions;
|
|
3026
3136
|
}
|
|
@@ -3059,7 +3169,7 @@ var PluginManager = class {
|
|
|
3059
3169
|
*/
|
|
3060
3170
|
register(plugin, notify = true) {
|
|
3061
3171
|
if (!this.validatePlugin(plugin)) {
|
|
3062
|
-
|
|
3172
|
+
logger9.error(`\u63D2\u4EF6\u6CE8\u518C\u5931\u8D25: ${plugin?.id || "\u672A\u77E5"}`);
|
|
3063
3173
|
return;
|
|
3064
3174
|
}
|
|
3065
3175
|
if (this.plugins.has(plugin.id)) {
|
|
@@ -3127,12 +3237,14 @@ var PluginManager = class {
|
|
|
3127
3237
|
this.handleRendererPlugin(plugin);
|
|
3128
3238
|
break;
|
|
3129
3239
|
default:
|
|
3130
|
-
|
|
3240
|
+
logger9.warn(
|
|
3241
|
+
`\u63D2\u4EF6 ${plugin.id} \u7C7B\u578B\u672A\u77E5: ${plugin.metadata.type}, fallback to business logic`
|
|
3242
|
+
);
|
|
3131
3243
|
this.handleBusinessPlugin(plugin);
|
|
3132
3244
|
break;
|
|
3133
3245
|
}
|
|
3134
3246
|
if (plugin.metadata.routes && plugin.metadata.routes.length > 0) {
|
|
3135
|
-
|
|
3247
|
+
logger9.info(`\u5DF2\u4ECE\u63D2\u4EF6 ${plugin.id} \u6536\u96C6\u8DEF\u7531:`, plugin.metadata.routes);
|
|
3136
3248
|
}
|
|
3137
3249
|
if (plugin.metadata.extensions && plugin.metadata.extensions.length > 0) {
|
|
3138
3250
|
plugin.metadata.extensions.forEach((ext) => {
|
|
@@ -3140,10 +3252,10 @@ var PluginManager = class {
|
|
|
3140
3252
|
list.push({ ...ext, _pluginId: plugin.id });
|
|
3141
3253
|
this.extensions.set(ext.slot, list);
|
|
3142
3254
|
});
|
|
3143
|
-
|
|
3255
|
+
logger9.info(`\u5DF2\u4ECE\u63D2\u4EF6 ${plugin.id} \u6536\u96C6\u6269\u5C55\u70B9`);
|
|
3144
3256
|
}
|
|
3145
3257
|
this.plugins.set(plugin.id, plugin);
|
|
3146
|
-
|
|
3258
|
+
logger9.info(`\u63D2\u4EF6 ${plugin.id} \u5DF2\u6CE8\u518C\u4E3A ${plugin.metadata.type}\u3002`);
|
|
3147
3259
|
if (notify) {
|
|
3148
3260
|
this.notify();
|
|
3149
3261
|
}
|
|
@@ -3157,7 +3269,7 @@ var PluginManager = class {
|
|
|
3157
3269
|
const runtime = this.runtimes.get(pluginId);
|
|
3158
3270
|
if (!runtime) {
|
|
3159
3271
|
const msg = `\u5C1D\u8BD5\u6302\u8F7D\u4E0D\u5B58\u5728\u6216\u672A\u521D\u59CB\u5316\u7684\u63D2\u4EF6: ${pluginId}`;
|
|
3160
|
-
|
|
3272
|
+
logger9.warn(msg);
|
|
3161
3273
|
throw new Error(msg);
|
|
3162
3274
|
}
|
|
3163
3275
|
if (runtime.status === "mounted") return;
|
|
@@ -3165,7 +3277,7 @@ var PluginManager = class {
|
|
|
3165
3277
|
if (plugin?.metadata.dependencies) {
|
|
3166
3278
|
for (const depId of plugin.metadata.dependencies) {
|
|
3167
3279
|
if (!this.runtimes.has(depId)) {
|
|
3168
|
-
|
|
3280
|
+
logger9.error(`\u63D2\u4EF6 ${pluginId} \u4F9D\u8D56\u7F3A\u5931: ${depId}`);
|
|
3169
3281
|
throw new Error(`Dependency ${depId} missing for ${pluginId}`);
|
|
3170
3282
|
}
|
|
3171
3283
|
await this.mountPlugin(depId);
|
|
@@ -3175,7 +3287,7 @@ var PluginManager = class {
|
|
|
3175
3287
|
try {
|
|
3176
3288
|
await runtime.load();
|
|
3177
3289
|
} catch (e) {
|
|
3178
|
-
|
|
3290
|
+
logger9.error(`\u63D2\u4EF6 ${pluginId} load \u5931\u8D25:`, e);
|
|
3179
3291
|
throw e;
|
|
3180
3292
|
}
|
|
3181
3293
|
}
|
|
@@ -3184,7 +3296,7 @@ var PluginManager = class {
|
|
|
3184
3296
|
await runtime.mount();
|
|
3185
3297
|
this.notify();
|
|
3186
3298
|
} catch (e) {
|
|
3187
|
-
|
|
3299
|
+
logger9.error(`\u63D2\u4EF6 ${pluginId} \u6302\u8F7D\u5931\u8D25:`, e);
|
|
3188
3300
|
throw e;
|
|
3189
3301
|
}
|
|
3190
3302
|
}
|
|
@@ -3196,7 +3308,7 @@ var PluginManager = class {
|
|
|
3196
3308
|
*/
|
|
3197
3309
|
async initPlugins(sharedContext = {}, autoMount = false) {
|
|
3198
3310
|
if (this.isInitializing) {
|
|
3199
|
-
|
|
3311
|
+
logger9.warn("PluginManager is already initializing, skipping...");
|
|
3200
3312
|
return;
|
|
3201
3313
|
}
|
|
3202
3314
|
this.isInitializing = true;
|
|
@@ -3208,7 +3320,11 @@ var PluginManager = class {
|
|
|
3208
3320
|
this.plugins.forEach((plugin) => {
|
|
3209
3321
|
if (!this.isPluginEnabled(plugin.id)) return;
|
|
3210
3322
|
if (!this.runtimes.has(plugin.id)) {
|
|
3211
|
-
const runtime = new PluginRuntime(
|
|
3323
|
+
const runtime = new PluginRuntime(
|
|
3324
|
+
plugin,
|
|
3325
|
+
this.sharedContext,
|
|
3326
|
+
this.storageManager
|
|
3327
|
+
);
|
|
3212
3328
|
this.runtimes.set(plugin.id, runtime);
|
|
3213
3329
|
}
|
|
3214
3330
|
});
|
|
@@ -3218,7 +3334,9 @@ var PluginManager = class {
|
|
|
3218
3334
|
for (const id of sortedPluginIds) {
|
|
3219
3335
|
const plugin = this.plugins.get(id);
|
|
3220
3336
|
if (plugin?.metadata.dependencies) {
|
|
3221
|
-
const missing = plugin.metadata.dependencies.filter(
|
|
3337
|
+
const missing = plugin.metadata.dependencies.filter(
|
|
3338
|
+
(depId) => !this.runtimes.has(depId)
|
|
3339
|
+
);
|
|
3222
3340
|
if (missing.length > 0) {
|
|
3223
3341
|
missingDeps.set(id, missing);
|
|
3224
3342
|
idsToLoad.delete(id);
|
|
@@ -3228,7 +3346,7 @@ var PluginManager = class {
|
|
|
3228
3346
|
}
|
|
3229
3347
|
if (missingDeps.size > 0) {
|
|
3230
3348
|
missingDeps.forEach((deps, id) => {
|
|
3231
|
-
|
|
3349
|
+
logger9.error(`\u63D2\u4EF6 ${id} \u65E0\u6CD5\u52A0\u8F7D\uFF0C\u7F3A\u5931\u4F9D\u8D56: ${deps.join(", ")}`);
|
|
3232
3350
|
});
|
|
3233
3351
|
}
|
|
3234
3352
|
for (const id of sortedPluginIds) {
|
|
@@ -3260,9 +3378,11 @@ var PluginManager = class {
|
|
|
3260
3378
|
let lastError;
|
|
3261
3379
|
for (let attempt = 0; attempt <= defaultRetryConfig.maxRetries; attempt++) {
|
|
3262
3380
|
try {
|
|
3263
|
-
|
|
3381
|
+
logger9.info(
|
|
3382
|
+
`[PluginManager] invoking onLoad for ${pluginId} (attempt ${attempt + 1})`
|
|
3383
|
+
);
|
|
3264
3384
|
await runtime.load();
|
|
3265
|
-
|
|
3385
|
+
logger9.info(`[PluginManager] onLoad completed for ${pluginId}`);
|
|
3266
3386
|
this.eventBus.emit("plugin:loaded", { pluginId, attempt });
|
|
3267
3387
|
return;
|
|
3268
3388
|
} catch (e) {
|
|
@@ -3271,7 +3391,7 @@ var PluginManager = class {
|
|
|
3271
3391
|
handleError(e, {
|
|
3272
3392
|
code: "2002" /* PLUGIN_LOAD_FAILED */,
|
|
3273
3393
|
strategy: "silent" /* SILENT */,
|
|
3274
|
-
logger:
|
|
3394
|
+
logger: logger9,
|
|
3275
3395
|
context: {
|
|
3276
3396
|
pluginId,
|
|
3277
3397
|
attempt: attempt + 1,
|
|
@@ -3279,7 +3399,10 @@ var PluginManager = class {
|
|
|
3279
3399
|
phase: "load"
|
|
3280
3400
|
}
|
|
3281
3401
|
});
|
|
3282
|
-
|
|
3402
|
+
logger9.warn(
|
|
3403
|
+
`\u63D2\u4EF6 ${pluginId} \u52A0\u8F7D\u5931\u8D25 (attempt ${attempt + 1}, type: ${errorType}):`,
|
|
3404
|
+
e
|
|
3405
|
+
);
|
|
3283
3406
|
this.eventBus.emit("plugin:error", {
|
|
3284
3407
|
pluginId,
|
|
3285
3408
|
error: e,
|
|
@@ -3291,11 +3414,11 @@ var PluginManager = class {
|
|
|
3291
3414
|
break;
|
|
3292
3415
|
}
|
|
3293
3416
|
const delay = calculateRetryDelay(defaultRetryConfig, attempt);
|
|
3294
|
-
|
|
3417
|
+
logger9.info(`\u63D2\u4EF6 ${pluginId} \u5C06\u5728 ${delay}ms \u540E\u91CD\u8BD5...`);
|
|
3295
3418
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
3296
3419
|
}
|
|
3297
3420
|
}
|
|
3298
|
-
|
|
3421
|
+
logger9.error(`\u63D2\u4EF6 ${pluginId} \u52A0\u8F7D\u5931\u8D25\uFF0C\u5DF2\u8FBE\u6700\u5927\u91CD\u8BD5\u6B21\u6570:`, lastError);
|
|
3299
3422
|
this.eventBus.emit("plugin:load-failed", { pluginId, error: lastError });
|
|
3300
3423
|
}
|
|
3301
3424
|
/**
|
|
@@ -3306,7 +3429,7 @@ var PluginManager = class {
|
|
|
3306
3429
|
for (let attempt = 0; attempt <= defaultRetryConfig.maxRetries; attempt++) {
|
|
3307
3430
|
try {
|
|
3308
3431
|
await runtime.mount();
|
|
3309
|
-
|
|
3432
|
+
logger9.info(`[PluginManager] onMount completed for ${pluginId}`);
|
|
3310
3433
|
this.eventBus.emit("plugin:mounted", { pluginId, attempt });
|
|
3311
3434
|
return;
|
|
3312
3435
|
} catch (e) {
|
|
@@ -3315,7 +3438,7 @@ var PluginManager = class {
|
|
|
3315
3438
|
handleError(e, {
|
|
3316
3439
|
code: "2003" /* PLUGIN_MOUNT_FAILED */,
|
|
3317
3440
|
strategy: "silent" /* SILENT */,
|
|
3318
|
-
logger:
|
|
3441
|
+
logger: logger9,
|
|
3319
3442
|
context: {
|
|
3320
3443
|
pluginId,
|
|
3321
3444
|
attempt: attempt + 1,
|
|
@@ -3323,7 +3446,10 @@ var PluginManager = class {
|
|
|
3323
3446
|
phase: "mount"
|
|
3324
3447
|
}
|
|
3325
3448
|
});
|
|
3326
|
-
|
|
3449
|
+
logger9.warn(
|
|
3450
|
+
`\u63D2\u4EF6 ${pluginId} \u6302\u8F7D\u5931\u8D25 (attempt ${attempt + 1}, type: ${errorType}):`,
|
|
3451
|
+
e
|
|
3452
|
+
);
|
|
3327
3453
|
this.eventBus.emit("plugin:error", {
|
|
3328
3454
|
pluginId,
|
|
3329
3455
|
error: e,
|
|
@@ -3335,11 +3461,11 @@ var PluginManager = class {
|
|
|
3335
3461
|
break;
|
|
3336
3462
|
}
|
|
3337
3463
|
const delay = calculateRetryDelay(defaultRetryConfig, attempt);
|
|
3338
|
-
|
|
3464
|
+
logger9.info(`\u63D2\u4EF6 ${pluginId} \u5C06\u5728 ${delay}ms \u540E\u91CD\u8BD5...`);
|
|
3339
3465
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
3340
3466
|
}
|
|
3341
3467
|
}
|
|
3342
|
-
|
|
3468
|
+
logger9.error(`\u63D2\u4EF6 ${pluginId} \u6302\u8F7D\u5931\u8D25\uFF0C\u5DF2\u8FBE\u6700\u5927\u91CD\u8BD5\u6B21\u6570:`, lastError);
|
|
3343
3469
|
this.eventBus.emit("plugin:mount-failed", { pluginId, error: lastError });
|
|
3344
3470
|
}
|
|
3345
3471
|
/**
|
|
@@ -3353,7 +3479,7 @@ var PluginManager = class {
|
|
|
3353
3479
|
const visit = (id) => {
|
|
3354
3480
|
if (visited.has(id)) return;
|
|
3355
3481
|
if (visiting.has(id)) {
|
|
3356
|
-
|
|
3482
|
+
logger9.error(`\u5FAA\u73AF\u4F9D\u8D56\u68C0\u6D4B\u5230: ${id}`);
|
|
3357
3483
|
return;
|
|
3358
3484
|
}
|
|
3359
3485
|
visiting.add(id);
|
|
@@ -3370,9 +3496,9 @@ var PluginManager = class {
|
|
|
3370
3496
|
sorted.push(id);
|
|
3371
3497
|
};
|
|
3372
3498
|
const priorityMap = {
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3499
|
+
system: 100,
|
|
3500
|
+
functional: 50,
|
|
3501
|
+
business: 10
|
|
3376
3502
|
};
|
|
3377
3503
|
const sortedIdsByType = [...ids].sort((a, b) => {
|
|
3378
3504
|
const pA = priorityMap[this.plugins.get(a)?.metadata.type || ""] || 0;
|
|
@@ -3389,34 +3515,43 @@ var PluginManager = class {
|
|
|
3389
3515
|
* @param notify 是否在加载完成后触发通知,默认为 true
|
|
3390
3516
|
*/
|
|
3391
3517
|
async loadPlugins(configs, registry, notify = true) {
|
|
3392
|
-
|
|
3393
|
-
const localLoadPromises = Object.entries(registry).map(
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3518
|
+
logger9.info("\u5F00\u59CB\u52A0\u8F7D\u63D2\u4EF6...");
|
|
3519
|
+
const localLoadPromises = Object.entries(registry).map(
|
|
3520
|
+
async ([registryId, importFn]) => {
|
|
3521
|
+
try {
|
|
3522
|
+
const module = await importFn();
|
|
3523
|
+
const config = configs[registryId];
|
|
3524
|
+
const plugin = this.instantiatePlugin(registryId, module, config);
|
|
3525
|
+
if (plugin && config) {
|
|
3526
|
+
configManager.set(plugin.id, config);
|
|
3527
|
+
}
|
|
3528
|
+
return plugin;
|
|
3529
|
+
} catch (e) {
|
|
3530
|
+
logger9.error(`\u52A0\u8F7D\u672C\u5730\u63D2\u4EF6\u6A21\u5757 ${registryId} \u5931\u8D25:`, e);
|
|
3531
|
+
return null;
|
|
3400
3532
|
}
|
|
3401
|
-
return plugin;
|
|
3402
|
-
} catch (e) {
|
|
3403
|
-
logger8.error(`\u52A0\u8F7D\u672C\u5730\u63D2\u4EF6\u6A21\u5757 ${registryId} \u5931\u8D25:`, e);
|
|
3404
|
-
return null;
|
|
3405
3533
|
}
|
|
3406
|
-
|
|
3534
|
+
);
|
|
3407
3535
|
const onlineLoadPromises = Object.entries(configs).filter(([id, config]) => config.url && !registry[id]).map(async ([pluginId, config]) => {
|
|
3408
3536
|
try {
|
|
3409
|
-
const plugin = await this.loadRemotePlugin(
|
|
3537
|
+
const plugin = await this.loadRemotePlugin(
|
|
3538
|
+
pluginId,
|
|
3539
|
+
config.url,
|
|
3540
|
+
config
|
|
3541
|
+
);
|
|
3410
3542
|
if (plugin && config) {
|
|
3411
3543
|
configManager.set(plugin.id, config);
|
|
3412
3544
|
}
|
|
3413
3545
|
return plugin;
|
|
3414
3546
|
} catch (e) {
|
|
3415
|
-
|
|
3547
|
+
logger9.error(`\u52A0\u8F7D\u5728\u7EBF\u63D2\u4EF6 ${pluginId} \u5931\u8D25:`, e);
|
|
3416
3548
|
return null;
|
|
3417
3549
|
}
|
|
3418
3550
|
});
|
|
3419
|
-
const loadedPlugins = await Promise.all([
|
|
3551
|
+
const loadedPlugins = await Promise.all([
|
|
3552
|
+
...localLoadPromises,
|
|
3553
|
+
...onlineLoadPromises
|
|
3554
|
+
]);
|
|
3420
3555
|
loadedPlugins.forEach((plugin) => {
|
|
3421
3556
|
if (plugin) {
|
|
3422
3557
|
this.register(plugin, false);
|
|
@@ -3425,7 +3560,7 @@ var PluginManager = class {
|
|
|
3425
3560
|
if (notify) {
|
|
3426
3561
|
this.notify();
|
|
3427
3562
|
}
|
|
3428
|
-
|
|
3563
|
+
logger9.info(`\u63D2\u4EF6\u52A0\u8F7D\u5B8C\u6210\uFF0C\u5171\u52A0\u8F7D ${this.plugins.size} \u4E2A\u63D2\u4EF6`);
|
|
3429
3564
|
}
|
|
3430
3565
|
/**
|
|
3431
3566
|
* 加载远程插件
|
|
@@ -3434,16 +3569,21 @@ var PluginManager = class {
|
|
|
3434
3569
|
* @param config 插件配置
|
|
3435
3570
|
*/
|
|
3436
3571
|
async loadRemotePlugin(pluginId, url, config) {
|
|
3437
|
-
|
|
3572
|
+
logger9.info(`\u6B63\u5728\u4ECE ${url} \u52A0\u8F7D\u8FDC\u7A0B\u63D2\u4EF6 ${pluginId}...`);
|
|
3438
3573
|
if (config?.format === "iife") {
|
|
3439
3574
|
return this.loadIIFEPlugin(pluginId, url, config);
|
|
3440
3575
|
}
|
|
3441
3576
|
try {
|
|
3442
|
-
const dynamicImport = new Function(
|
|
3577
|
+
const dynamicImport = new Function(
|
|
3578
|
+
"specifier",
|
|
3579
|
+
"return import(specifier)"
|
|
3580
|
+
);
|
|
3443
3581
|
const module = await dynamicImport(url);
|
|
3444
3582
|
return this.instantiatePlugin(pluginId, module, config);
|
|
3445
3583
|
} catch (e) {
|
|
3446
|
-
|
|
3584
|
+
logger9.warn(
|
|
3585
|
+
`ESM \u52A0\u8F7D\u5931\u8D25 (${e instanceof Error ? e.message : String(e)})\uFF0C\u5C1D\u8BD5 IIFE \u52A0\u8F7D: ${pluginId}`
|
|
3586
|
+
);
|
|
3447
3587
|
return this.loadIIFEPlugin(pluginId, url, config);
|
|
3448
3588
|
}
|
|
3449
3589
|
}
|
|
@@ -3460,7 +3600,9 @@ var PluginManager = class {
|
|
|
3460
3600
|
if (pluginModule) {
|
|
3461
3601
|
resolve(this.instantiatePlugin(pluginId, pluginModule, config));
|
|
3462
3602
|
} else {
|
|
3463
|
-
reject(
|
|
3603
|
+
reject(
|
|
3604
|
+
new Error(`\u8FDC\u7A0B\u63D2\u4EF6 ${pluginId} \u52A0\u8F7D\u540E\u672A\u627E\u5230\u5168\u5C40\u53D8\u91CF ${globalName}`)
|
|
3605
|
+
);
|
|
3464
3606
|
}
|
|
3465
3607
|
};
|
|
3466
3608
|
script.onerror = () => reject(new Error(`\u8FDC\u7A0B\u63D2\u4EF6 ${pluginId} \u52A0\u8F7D\u5931\u8D25: ${url}`));
|
|
@@ -3484,7 +3626,9 @@ var PluginManager = class {
|
|
|
3484
3626
|
if (PluginClass) {
|
|
3485
3627
|
const isClass = typeof PluginClass === "function" && PluginClass.prototype;
|
|
3486
3628
|
if (isClass) {
|
|
3487
|
-
|
|
3629
|
+
logger9.warn(
|
|
3630
|
+
`\u63D2\u4EF6 ${pluginId} \u4F7F\u7528\u4E86\u7C7B\u5B9A\u4E49\u6A21\u5F0F\u3002\u5EFA\u8BAE\u7EDF\u4E00\u4F7F\u7528 definePlugin() \u5DE5\u5382\u6A21\u5F0F\u4EE5\u6D88\u9664\u6B67\u4E49\u5E76\u7B80\u5316\u4EE3\u7801\u3002`
|
|
3631
|
+
);
|
|
3488
3632
|
}
|
|
3489
3633
|
const pluginInstance = typeof PluginClass === "function" ? new PluginClass() : PluginClass;
|
|
3490
3634
|
const isFilePath = pluginId.includes("/") && (pluginId.includes(".ts") || pluginId.includes(".tsx"));
|
|
@@ -3502,11 +3646,14 @@ var PluginManager = class {
|
|
|
3502
3646
|
}
|
|
3503
3647
|
}
|
|
3504
3648
|
if (config) {
|
|
3505
|
-
pluginInstance.defaultConfig = {
|
|
3649
|
+
pluginInstance.defaultConfig = {
|
|
3650
|
+
...pluginInstance.defaultConfig,
|
|
3651
|
+
...config
|
|
3652
|
+
};
|
|
3506
3653
|
}
|
|
3507
3654
|
return pluginInstance;
|
|
3508
3655
|
}
|
|
3509
|
-
|
|
3656
|
+
logger9.warn(`\u6A21\u5757 ${pluginId} \u672A\u5BFC\u51FA\u6709\u6548\u7684\u63D2\u4EF6\u5165\u53E3`);
|
|
3510
3657
|
return null;
|
|
3511
3658
|
}
|
|
3512
3659
|
// --- Private Handlers ---
|
|
@@ -3521,35 +3668,35 @@ var PluginManager = class {
|
|
|
3521
3668
|
if (plugin.defaultConfig) {
|
|
3522
3669
|
this.registerDefaultConfig(plugin.id, plugin.defaultConfig);
|
|
3523
3670
|
}
|
|
3524
|
-
|
|
3671
|
+
logger9.debug(`[Business] \u4E1A\u52A1\u63D2\u4EF6 ${plugin.id} \u5DF2\u6CE8\u518C\uFF08\u9ED8\u8BA4\u7981\u7528\uFF09`);
|
|
3525
3672
|
}
|
|
3526
3673
|
handleFunctionalPlugin(plugin) {
|
|
3527
3674
|
const config = PLUGIN_TYPE_CONFIGS.functional;
|
|
3528
3675
|
this.pluginLazyInit.set(plugin.id, true);
|
|
3529
3676
|
this.pluginDefaultEnabled.set(plugin.id, config.defaultEnabled);
|
|
3530
|
-
|
|
3677
|
+
logger9.debug(`[Functional] \u529F\u80FD\u63D2\u4EF6 ${plugin.id} \u5DF2\u6CE8\u518C\uFF08\u61D2\u52A0\u8F7D\uFF09`);
|
|
3531
3678
|
}
|
|
3532
3679
|
handleViewPlugin(plugin) {
|
|
3533
3680
|
const config = PLUGIN_TYPE_CONFIGS.view;
|
|
3534
3681
|
this.pluginLazyInit.set(plugin.id, true);
|
|
3535
3682
|
this.pluginDefaultEnabled.set(plugin.id, config.defaultEnabled);
|
|
3536
|
-
|
|
3683
|
+
logger9.debug(`[View] \u89C6\u56FE\u63D2\u4EF6 ${plugin.id} \u5DF2\u6CE8\u518C\uFF08\u61D2\u52A0\u8F7D\uFF09`);
|
|
3537
3684
|
}
|
|
3538
3685
|
handleThemePlugin(plugin) {
|
|
3539
3686
|
const config = PLUGIN_TYPE_CONFIGS.theme;
|
|
3540
3687
|
this.pluginDefaultEnabled.set(plugin.id, config.defaultEnabled);
|
|
3541
|
-
|
|
3688
|
+
logger9.debug(`[Theme] \u4E3B\u9898\u63D2\u4EF6 ${plugin.id} \u5DF2\u6CE8\u518C`);
|
|
3542
3689
|
}
|
|
3543
3690
|
handleRendererPlugin(plugin) {
|
|
3544
3691
|
const config = PLUGIN_TYPE_CONFIGS.renderer;
|
|
3545
3692
|
this.pluginDefaultEnabled.set(plugin.id, config.defaultEnabled);
|
|
3546
|
-
|
|
3693
|
+
logger9.debug(`[Renderer] \u6E32\u67D3\u63D2\u4EF6 ${plugin.id} \u5DF2\u6CE8\u518C`);
|
|
3547
3694
|
}
|
|
3548
3695
|
handleSystemPlugin(plugin) {
|
|
3549
3696
|
const config = PLUGIN_TYPE_CONFIGS.system;
|
|
3550
3697
|
this.pluginForces.set(plugin.id, true);
|
|
3551
3698
|
this.pluginDefaultEnabled.set(plugin.id, true);
|
|
3552
|
-
|
|
3699
|
+
logger9.debug(`[System] \u7CFB\u7EDF\u63D2\u4EF6 ${plugin.id} \u5DF2\u6CE8\u518C\uFF08\u5F3A\u5236\u542F\u7528\uFF09`);
|
|
3553
3700
|
}
|
|
3554
3701
|
/**
|
|
3555
3702
|
* 注册插件默认配置
|
|
@@ -3564,8 +3711,8 @@ var PluginManager = class {
|
|
|
3564
3711
|
var pluginManager = new PluginManager(new LocalStorageAdapter());
|
|
3565
3712
|
|
|
3566
3713
|
// src/feature-flag/FeatureRegistry.ts
|
|
3567
|
-
import { create as create2 } from "zustand";
|
|
3568
3714
|
import { createJSONStorage, persist } from "zustand/middleware";
|
|
3715
|
+
import { createStore as createStore3 } from "zustand/vanilla";
|
|
3569
3716
|
var FEATURE_NAMESPACE_PREFIX = "chatbi:feature:";
|
|
3570
3717
|
var STORAGE_KEY2 = "chatbi:feature:store";
|
|
3571
3718
|
function simpleHash(str) {
|
|
@@ -3604,7 +3751,7 @@ function evaluateRules(rules, context) {
|
|
|
3604
3751
|
}
|
|
3605
3752
|
return false;
|
|
3606
3753
|
}
|
|
3607
|
-
var
|
|
3754
|
+
var featureFlagsStore = createStore3()(
|
|
3608
3755
|
persist(
|
|
3609
3756
|
(set, get) => ({
|
|
3610
3757
|
features: {},
|
|
@@ -3765,109 +3912,6 @@ function createUserRule(userId) {
|
|
|
3765
3912
|
};
|
|
3766
3913
|
}
|
|
3767
3914
|
|
|
3768
|
-
// src/feature-flag/useFeature.ts
|
|
3769
|
-
import { useShallow } from "zustand/react/shallow";
|
|
3770
|
-
function useFeature(flagName, context) {
|
|
3771
|
-
const { isEnabled, getFeature } = useFeatureFlags(
|
|
3772
|
-
useShallow((state) => ({
|
|
3773
|
-
isEnabled: state.isEnabled,
|
|
3774
|
-
getFeature: state.getFeature
|
|
3775
|
-
}))
|
|
3776
|
-
);
|
|
3777
|
-
const enabled = isEnabled(flagName, context);
|
|
3778
|
-
const config = getFeature(flagName);
|
|
3779
|
-
return {
|
|
3780
|
-
isEnabled: enabled,
|
|
3781
|
-
config
|
|
3782
|
-
};
|
|
3783
|
-
}
|
|
3784
|
-
|
|
3785
|
-
// src/manifest/ManifestValidator.ts
|
|
3786
|
-
function formatZodErrors(error) {
|
|
3787
|
-
return error.errors.map((err) => ({
|
|
3788
|
-
message: err.message,
|
|
3789
|
-
path: err.path.map(String),
|
|
3790
|
-
type: err.code
|
|
3791
|
-
}));
|
|
3792
|
-
}
|
|
3793
|
-
function validateManifest(raw) {
|
|
3794
|
-
const result = PluginManifestSchema.safeParse(raw);
|
|
3795
|
-
if (result.success) {
|
|
3796
|
-
return {
|
|
3797
|
-
valid: true,
|
|
3798
|
-
data: result.data
|
|
3799
|
-
};
|
|
3800
|
-
}
|
|
3801
|
-
return {
|
|
3802
|
-
valid: false,
|
|
3803
|
-
errors: formatZodErrors(result.error)
|
|
3804
|
-
};
|
|
3805
|
-
}
|
|
3806
|
-
function assertManifest(raw) {
|
|
3807
|
-
return PluginManifestSchema.parse(raw);
|
|
3808
|
-
}
|
|
3809
|
-
|
|
3810
|
-
// src/manifest/ManifestWrapper.ts
|
|
3811
|
-
function extractManifestFromPlugin(plugin) {
|
|
3812
|
-
const input = plugin;
|
|
3813
|
-
const metadata = input.metadata;
|
|
3814
|
-
const manifest = {
|
|
3815
|
-
id: input.id || metadata?.id,
|
|
3816
|
-
version: metadata?.version || "1.0.0",
|
|
3817
|
-
name: metadata?.name || input.name,
|
|
3818
|
-
type: metadata?.type || input.type,
|
|
3819
|
-
description: metadata?.description || input.description,
|
|
3820
|
-
author: metadata?.author || input.author,
|
|
3821
|
-
icon: metadata?.icon || input.icon,
|
|
3822
|
-
entry: input.entry || "index.js"
|
|
3823
|
-
};
|
|
3824
|
-
const deps = metadata?.dependencies || input.dependencies;
|
|
3825
|
-
if (Array.isArray(deps)) {
|
|
3826
|
-
manifest.dependencies = deps.map((dep) => {
|
|
3827
|
-
if (typeof dep === "string") {
|
|
3828
|
-
return { id: dep, version: "*", optional: false };
|
|
3829
|
-
}
|
|
3830
|
-
return dep;
|
|
3831
|
-
});
|
|
3832
|
-
}
|
|
3833
|
-
const extensions = metadata?.extensions || input.extensions;
|
|
3834
|
-
if (Array.isArray(extensions)) {
|
|
3835
|
-
manifest.extensions = extensions.map((ext) => ({
|
|
3836
|
-
name: ext.slot || ext.name,
|
|
3837
|
-
type: "slot",
|
|
3838
|
-
description: ext.meta?.description,
|
|
3839
|
-
slot: ext.slot
|
|
3840
|
-
}));
|
|
3841
|
-
}
|
|
3842
|
-
const caps = metadata?.capabilities || input.capabilities;
|
|
3843
|
-
if (caps && typeof caps === "object") {
|
|
3844
|
-
manifest.capabilities = caps;
|
|
3845
|
-
}
|
|
3846
|
-
const config = metadata?.configuration || input.configuration;
|
|
3847
|
-
if (Array.isArray(config)) {
|
|
3848
|
-
manifest.configuration = config;
|
|
3849
|
-
}
|
|
3850
|
-
return manifest;
|
|
3851
|
-
}
|
|
3852
|
-
function normalizePluginManifest(input) {
|
|
3853
|
-
let manifest;
|
|
3854
|
-
if (!input || typeof input !== "object") {
|
|
3855
|
-
return {
|
|
3856
|
-
valid: false,
|
|
3857
|
-
errors: [{ message: "\u8F93\u5165\u5FC5\u987B\u662F\u5BF9\u8C61", path: [], type: "invalid_type" }]
|
|
3858
|
-
};
|
|
3859
|
-
}
|
|
3860
|
-
const record = input;
|
|
3861
|
-
if (record.id && record.version && record.name && record.entry) {
|
|
3862
|
-
manifest = record;
|
|
3863
|
-
} else if (record.metadata) {
|
|
3864
|
-
manifest = extractManifestFromPlugin(record);
|
|
3865
|
-
} else {
|
|
3866
|
-
manifest = extractManifestFromPlugin(record);
|
|
3867
|
-
}
|
|
3868
|
-
return validateManifest(manifest);
|
|
3869
|
-
}
|
|
3870
|
-
|
|
3871
3915
|
// src/api/adapters/axios-adapter.ts
|
|
3872
3916
|
import axios from "axios";
|
|
3873
3917
|
var AxiosAdapter = class {
|
|
@@ -3893,7 +3937,7 @@ var AxiosAdapter = class {
|
|
|
3893
3937
|
// 强制不缓存流式响应
|
|
3894
3938
|
headers: {
|
|
3895
3939
|
"Cache-Control": "no-cache",
|
|
3896
|
-
|
|
3940
|
+
Pragma: "no-cache",
|
|
3897
3941
|
...config.headers
|
|
3898
3942
|
},
|
|
3899
3943
|
// 自定义适配器:在拦截器链中执行 fetch
|
|
@@ -3923,7 +3967,9 @@ var AxiosAdapter = class {
|
|
|
3923
3967
|
if (hijacked) return;
|
|
3924
3968
|
}
|
|
3925
3969
|
if (!(fetchResponse instanceof Response)) {
|
|
3926
|
-
throw new Error(
|
|
3970
|
+
throw new Error(
|
|
3971
|
+
"\u6D41\u5F0F\u8BF7\u6C42\u5931\u8D25\uFF1A\u672A\u80FD\u83B7\u53D6\u5230\u539F\u59CB\u54CD\u5E94\u6D41\uFF0C\u8BF7\u68C0\u67E5 Axios \u54CD\u5E94\u62E6\u622A\u5668\u662F\u5426\u6B63\u786E\u5904\u7406\u4E86 Response \u5BF9\u8C61\u3002"
|
|
3972
|
+
);
|
|
3927
3973
|
}
|
|
3928
3974
|
if (!fetchResponse.ok) {
|
|
3929
3975
|
throw new Error(`HTTP error! status: ${fetchResponse.status}`);
|
|
@@ -3957,7 +4003,7 @@ var AxiosAdapter = class {
|
|
|
3957
4003
|
};
|
|
3958
4004
|
|
|
3959
4005
|
// src/api/engine.ts
|
|
3960
|
-
var
|
|
4006
|
+
var logger10 = createLogger("ApiEngine");
|
|
3961
4007
|
var ApiEngine = class {
|
|
3962
4008
|
adapter;
|
|
3963
4009
|
config = {};
|
|
@@ -3997,7 +4043,7 @@ var ApiEngine = class {
|
|
|
3997
4043
|
* @param config 配置对象
|
|
3998
4044
|
*/
|
|
3999
4045
|
register(config) {
|
|
4000
|
-
|
|
4046
|
+
logger10.info("\u6B63\u5728\u6CE8\u518C API \u914D\u7F6E:", Object.keys(config));
|
|
4001
4047
|
this.config = { ...this.config, ...config };
|
|
4002
4048
|
}
|
|
4003
4049
|
/**
|
|
@@ -4016,10 +4062,16 @@ var ApiEngine = class {
|
|
|
4016
4062
|
async call(module, action, data, options = {}) {
|
|
4017
4063
|
const endpoint = this.getEndpoint(module, action);
|
|
4018
4064
|
if (!endpoint) {
|
|
4019
|
-
|
|
4065
|
+
logger10.warn(
|
|
4066
|
+
`\u672A\u627E\u5230 API \u5B9A\u4E49: ${module}.${action} (\u5F53\u524D\u5DF2\u6CE8\u518C\u6A21\u5757: ${Object.keys(this.config).join(", ")})`
|
|
4067
|
+
);
|
|
4020
4068
|
return Promise.resolve(void 0);
|
|
4021
4069
|
}
|
|
4022
|
-
const requestConfig = await this.prepareRequestConfig(
|
|
4070
|
+
const requestConfig = await this.prepareRequestConfig(
|
|
4071
|
+
endpoint,
|
|
4072
|
+
data,
|
|
4073
|
+
options
|
|
4074
|
+
);
|
|
4023
4075
|
let response;
|
|
4024
4076
|
try {
|
|
4025
4077
|
response = await this.adapter.request(requestConfig, endpoint);
|
|
@@ -4030,9 +4082,12 @@ var ApiEngine = class {
|
|
|
4030
4082
|
throw error;
|
|
4031
4083
|
}
|
|
4032
4084
|
}
|
|
4033
|
-
const hijacked = await this.applyResponseInterceptors(
|
|
4085
|
+
const hijacked = await this.applyResponseInterceptors(
|
|
4086
|
+
response,
|
|
4087
|
+
requestConfig
|
|
4088
|
+
);
|
|
4034
4089
|
if (hijacked) {
|
|
4035
|
-
|
|
4090
|
+
logger10.info("\u8BF7\u6C42\u88AB\u62E6\u622A\u5668\u52AB\u6301:", module, action);
|
|
4036
4091
|
return void 0;
|
|
4037
4092
|
}
|
|
4038
4093
|
this.checkHttpStatus(response);
|
|
@@ -4050,14 +4105,18 @@ var ApiEngine = class {
|
|
|
4050
4105
|
async stream(module, action, data, options = {}) {
|
|
4051
4106
|
const endpoint = this.getEndpoint(module, action);
|
|
4052
4107
|
if (!endpoint) {
|
|
4053
|
-
|
|
4108
|
+
logger10.warn(`\u672A\u627E\u5230 API \u5B9A\u4E49: ${module}.${action}\uFF0C\u8DF3\u8FC7\u6D41\u5F0F\u8BF7\u6C42\u3002`);
|
|
4054
4109
|
return;
|
|
4055
4110
|
}
|
|
4056
4111
|
if (!this.adapter.stream) {
|
|
4057
|
-
|
|
4112
|
+
logger10.warn("\u5F53\u524D API \u9002\u914D\u5668\u4E0D\u652F\u6301\u6D41\u5F0F\u4F20\u8F93\u3002");
|
|
4058
4113
|
return;
|
|
4059
4114
|
}
|
|
4060
|
-
const requestConfig = await this.prepareRequestConfig(
|
|
4115
|
+
const requestConfig = await this.prepareRequestConfig(
|
|
4116
|
+
endpoint,
|
|
4117
|
+
data,
|
|
4118
|
+
options
|
|
4119
|
+
);
|
|
4061
4120
|
const callbacks = {
|
|
4062
4121
|
onMessage: options.onMessage,
|
|
4063
4122
|
onError: options.onError,
|
|
@@ -4069,9 +4128,12 @@ var ApiEngine = class {
|
|
|
4069
4128
|
{
|
|
4070
4129
|
...callbacks,
|
|
4071
4130
|
onResponse: async (response) => {
|
|
4072
|
-
const hijacked = await this.applyResponseInterceptors(
|
|
4131
|
+
const hijacked = await this.applyResponseInterceptors(
|
|
4132
|
+
response,
|
|
4133
|
+
requestConfig
|
|
4134
|
+
);
|
|
4073
4135
|
if (hijacked) {
|
|
4074
|
-
|
|
4136
|
+
logger10.info("\u6D41\u5F0F\u8BF7\u6C42\u88AB\u62E6\u622A\u5668\u52AB\u6301:", module, action);
|
|
4075
4137
|
if (requestConfig.signal instanceof AbortController) {
|
|
4076
4138
|
requestConfig.signal.abort();
|
|
4077
4139
|
}
|
|
@@ -4099,7 +4161,8 @@ var ApiEngine = class {
|
|
|
4099
4161
|
const pathParams = options.params || {};
|
|
4100
4162
|
url = url.replace(/:([a-zA-Z0-9_]+)/g, (_, key) => {
|
|
4101
4163
|
if (pathParams[key] !== void 0) return String(pathParams[key]);
|
|
4102
|
-
if (data && typeof data === "object" && data[key] !== void 0)
|
|
4164
|
+
if (data && typeof data === "object" && data[key] !== void 0)
|
|
4165
|
+
return String(data[key]);
|
|
4103
4166
|
return `:${key}`;
|
|
4104
4167
|
});
|
|
4105
4168
|
const method = endpoint.method;
|
|
@@ -4171,7 +4234,7 @@ var ApiEngine = class {
|
|
|
4171
4234
|
if (!isSuccess) {
|
|
4172
4235
|
const strategy = endpoint.errorStrategy || "reject";
|
|
4173
4236
|
if (strategy === "reject") {
|
|
4174
|
-
|
|
4237
|
+
logger10.error(`API \u8BF7\u6C42\u4E1A\u52A1\u9519\u8BEF (${module}.${action}):`, res.message);
|
|
4175
4238
|
throw new Error(res.message || `Request failed with code ${code}`);
|
|
4176
4239
|
}
|
|
4177
4240
|
}
|
|
@@ -4331,9 +4394,9 @@ function resolveApiModules(definitionsMap, mocksMap = {}) {
|
|
|
4331
4394
|
}
|
|
4332
4395
|
|
|
4333
4396
|
// src/utils/date.ts
|
|
4334
|
-
import "dayjs/locale/zh-cn";
|
|
4397
|
+
import "dayjs/locale/zh-cn.js";
|
|
4335
4398
|
import dayjs from "dayjs";
|
|
4336
|
-
import relativeTime from "dayjs/plugin/relativeTime";
|
|
4399
|
+
import relativeTime from "dayjs/plugin/relativeTime.js";
|
|
4337
4400
|
dayjs.extend(relativeTime);
|
|
4338
4401
|
dayjs.locale("zh-cn");
|
|
4339
4402
|
var dateUtils = {
|
|
@@ -4544,7 +4607,10 @@ var RemoteLoader = class {
|
|
|
4544
4607
|
*/
|
|
4545
4608
|
constructor(options = {}) {
|
|
4546
4609
|
const cacheOptions = options.cache || { ttl: 5 * 60 * 1e3 };
|
|
4547
|
-
const retryOptions = options.retry || {
|
|
4610
|
+
const retryOptions = options.retry || {
|
|
4611
|
+
maxRetries: 3,
|
|
4612
|
+
retryDelay: 1e3
|
|
4613
|
+
};
|
|
4548
4614
|
this.options = {
|
|
4549
4615
|
timeout: options.timeout || 1e4,
|
|
4550
4616
|
retry: retryOptions,
|
|
@@ -4605,10 +4671,18 @@ var RemoteLoader = class {
|
|
|
4605
4671
|
async loadManifest(sourceId) {
|
|
4606
4672
|
const source = this.sources.get(sourceId);
|
|
4607
4673
|
if (!source) {
|
|
4608
|
-
return this.createErrorResult(
|
|
4674
|
+
return this.createErrorResult(
|
|
4675
|
+
"NOT_FOUND",
|
|
4676
|
+
`Source ${sourceId} not found`,
|
|
4677
|
+
false
|
|
4678
|
+
);
|
|
4609
4679
|
}
|
|
4610
4680
|
if (!source.enabled) {
|
|
4611
|
-
return this.createErrorResult(
|
|
4681
|
+
return this.createErrorResult(
|
|
4682
|
+
"NOT_FOUND",
|
|
4683
|
+
`Source ${sourceId} is disabled`,
|
|
4684
|
+
false
|
|
4685
|
+
);
|
|
4612
4686
|
}
|
|
4613
4687
|
const cacheKey = source.url;
|
|
4614
4688
|
const cached = this.cache.get(cacheKey);
|
|
@@ -4624,7 +4698,11 @@ var RemoteLoader = class {
|
|
|
4624
4698
|
const validationResult = validateManifest(data);
|
|
4625
4699
|
if (!validationResult.valid) {
|
|
4626
4700
|
const errors = validationResult.errors?.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ");
|
|
4627
|
-
return this.createErrorResult(
|
|
4701
|
+
return this.createErrorResult(
|
|
4702
|
+
"VALIDATION_ERROR",
|
|
4703
|
+
`Manifest validation failed: ${errors}`,
|
|
4704
|
+
false
|
|
4705
|
+
);
|
|
4628
4706
|
}
|
|
4629
4707
|
this.cache.set(cacheKey, validationResult.data);
|
|
4630
4708
|
return {
|
|
@@ -4647,7 +4725,7 @@ var RemoteLoader = class {
|
|
|
4647
4725
|
const response = await axios2.get(url, {
|
|
4648
4726
|
timeout: this.options.timeout,
|
|
4649
4727
|
headers: {
|
|
4650
|
-
|
|
4728
|
+
Accept: "application/json"
|
|
4651
4729
|
}
|
|
4652
4730
|
});
|
|
4653
4731
|
return response.data;
|
|
@@ -4669,7 +4747,11 @@ var RemoteLoader = class {
|
|
|
4669
4747
|
handleLoadError(error) {
|
|
4670
4748
|
const axiosError = error;
|
|
4671
4749
|
if (axiosError.code === "ECONNREFUSED" || axiosError.code === "ENOTFOUND") {
|
|
4672
|
-
return this.createErrorResult(
|
|
4750
|
+
return this.createErrorResult(
|
|
4751
|
+
"NETWORK",
|
|
4752
|
+
`Network error: ${axiosError.message}`,
|
|
4753
|
+
true
|
|
4754
|
+
);
|
|
4673
4755
|
}
|
|
4674
4756
|
if (axiosError.code === "ETIMEDOUT" || axiosError.code === "ECONNABORTED") {
|
|
4675
4757
|
return this.createErrorResult("TIMEOUT", "Request timeout", true);
|
|
@@ -4678,16 +4760,28 @@ var RemoteLoader = class {
|
|
|
4678
4760
|
return this.createErrorResult("NOT_FOUND", "Manifest not found", false);
|
|
4679
4761
|
}
|
|
4680
4762
|
if (axiosError.response?.status && axiosError.response.status >= 500) {
|
|
4681
|
-
return this.createErrorResult(
|
|
4763
|
+
return this.createErrorResult(
|
|
4764
|
+
"NETWORK",
|
|
4765
|
+
`Server error: ${axiosError.response.status}`,
|
|
4766
|
+
true
|
|
4767
|
+
);
|
|
4682
4768
|
}
|
|
4683
4769
|
if (axiosError.response?.data) {
|
|
4684
4770
|
try {
|
|
4685
4771
|
JSON.parse(JSON.stringify(axiosError.response.data));
|
|
4686
4772
|
} catch (e) {
|
|
4687
|
-
return this.createErrorResult(
|
|
4773
|
+
return this.createErrorResult(
|
|
4774
|
+
"PARSE",
|
|
4775
|
+
`Failed to parse response: ${e instanceof Error ? e.message : String(e)}`,
|
|
4776
|
+
false
|
|
4777
|
+
);
|
|
4688
4778
|
}
|
|
4689
4779
|
}
|
|
4690
|
-
return this.createErrorResult(
|
|
4780
|
+
return this.createErrorResult(
|
|
4781
|
+
"NETWORK",
|
|
4782
|
+
axiosError.message || "Unknown error",
|
|
4783
|
+
this.retryStrategy.isRetryable(axiosError)
|
|
4784
|
+
);
|
|
4691
4785
|
}
|
|
4692
4786
|
/**
|
|
4693
4787
|
* 创建错误结果
|
|
@@ -4737,15 +4831,7 @@ var RemoteLoader = class {
|
|
|
4737
4831
|
};
|
|
4738
4832
|
|
|
4739
4833
|
// src/dependency/ConflictResolver.ts
|
|
4740
|
-
import semver2 from "semver";
|
|
4741
|
-
|
|
4742
|
-
// src/semver/SemverResolver.ts
|
|
4743
4834
|
import semver from "semver";
|
|
4744
|
-
function maxSatisfying(range, versions) {
|
|
4745
|
-
return semver.maxSatisfying(versions, range);
|
|
4746
|
-
}
|
|
4747
|
-
|
|
4748
|
-
// src/dependency/ConflictResolver.ts
|
|
4749
4835
|
var ConflictResolver = class {
|
|
4750
4836
|
/**
|
|
4751
4837
|
* 解决版本冲突
|
|
@@ -4783,12 +4869,12 @@ var ConflictResolver = class {
|
|
|
4783
4869
|
if (versions.length === 1) {
|
|
4784
4870
|
return versions[0];
|
|
4785
4871
|
}
|
|
4786
|
-
const exactVersions = versions.filter((v) =>
|
|
4872
|
+
const exactVersions = versions.filter((v) => semver.valid(v));
|
|
4787
4873
|
if (exactVersions.length > 0) {
|
|
4788
|
-
const sorted2 = [...exactVersions].sort(
|
|
4874
|
+
const sorted2 = [...exactVersions].sort(semver.rcompare);
|
|
4789
4875
|
return sorted2[0];
|
|
4790
4876
|
}
|
|
4791
|
-
const sorted = [...versions].sort(
|
|
4877
|
+
const sorted = [...versions].sort(semver.rcompare);
|
|
4792
4878
|
return sorted[0];
|
|
4793
4879
|
}
|
|
4794
4880
|
/**
|
|
@@ -4804,7 +4890,7 @@ var ConflictResolver = class {
|
|
|
4804
4890
|
if (versions.length === 1) {
|
|
4805
4891
|
return versions[0];
|
|
4806
4892
|
}
|
|
4807
|
-
const sorted = [...versions].sort(
|
|
4893
|
+
const sorted = [...versions].sort(semver.compare);
|
|
4808
4894
|
return sorted[0];
|
|
4809
4895
|
}
|
|
4810
4896
|
/**
|
|
@@ -4828,7 +4914,10 @@ var CycleDetector = class {
|
|
|
4828
4914
|
detect(plugins) {
|
|
4829
4915
|
const graph = /* @__PURE__ */ new Map();
|
|
4830
4916
|
for (const plugin of plugins) {
|
|
4831
|
-
graph.set(
|
|
4917
|
+
graph.set(
|
|
4918
|
+
plugin.id,
|
|
4919
|
+
plugin.dependencies.map((d) => d.id)
|
|
4920
|
+
);
|
|
4832
4921
|
}
|
|
4833
4922
|
return this.detectFromGraph(graph);
|
|
4834
4923
|
}
|
|
@@ -5013,7 +5102,7 @@ var NpmRegistry = class {
|
|
|
5013
5102
|
baseURL: baseUrl,
|
|
5014
5103
|
timeout: 1e4,
|
|
5015
5104
|
headers: {
|
|
5016
|
-
|
|
5105
|
+
Accept: "application/json"
|
|
5017
5106
|
}
|
|
5018
5107
|
});
|
|
5019
5108
|
this.cache = new LRUCache3({
|
|
@@ -5144,7 +5233,7 @@ function getDefaultRegistry() {
|
|
|
5144
5233
|
}
|
|
5145
5234
|
|
|
5146
5235
|
// src/dependency/SharedDepsDetector.ts
|
|
5147
|
-
import
|
|
5236
|
+
import semver2 from "semver";
|
|
5148
5237
|
var SharedDepsDetector = class {
|
|
5149
5238
|
/**
|
|
5150
5239
|
* 检测共享依赖
|
|
@@ -5195,13 +5284,13 @@ var SharedDepsDetector = class {
|
|
|
5195
5284
|
if (uniqueVersions.length <= 1) {
|
|
5196
5285
|
return false;
|
|
5197
5286
|
}
|
|
5198
|
-
const exactVersions = uniqueVersions.filter((v) =>
|
|
5287
|
+
const exactVersions = uniqueVersions.filter((v) => semver2.valid(v));
|
|
5199
5288
|
if (exactVersions.length > 1) {
|
|
5200
5289
|
for (let i = 0; i < exactVersions.length; i++) {
|
|
5201
5290
|
for (let j = i + 1; j < exactVersions.length; j++) {
|
|
5202
5291
|
const v1 = exactVersions[i];
|
|
5203
5292
|
const v2 = exactVersions[j];
|
|
5204
|
-
if (!
|
|
5293
|
+
if (!semver2.satisfies(v1, `^${v2}`) && !semver2.satisfies(v2, `^${v1}`)) {
|
|
5205
5294
|
return true;
|
|
5206
5295
|
}
|
|
5207
5296
|
}
|
|
@@ -5222,9 +5311,9 @@ var SharedDepsDetector = class {
|
|
|
5222
5311
|
if (uniqueVersions.length === 1) {
|
|
5223
5312
|
return uniqueVersions[0];
|
|
5224
5313
|
}
|
|
5225
|
-
const exactVersions = uniqueVersions.filter((v) =>
|
|
5226
|
-
const rangeVersions = uniqueVersions.filter((v) =>
|
|
5227
|
-
const sorted = [...exactVersions, ...rangeVersions].sort(
|
|
5314
|
+
const exactVersions = uniqueVersions.filter((v) => semver2.valid(v));
|
|
5315
|
+
const rangeVersions = uniqueVersions.filter((v) => semver2.validRange(v));
|
|
5316
|
+
const sorted = [...exactVersions, ...rangeVersions].sort(semver2.rcompare);
|
|
5228
5317
|
return sorted[0] ?? uniqueVersions[0];
|
|
5229
5318
|
}
|
|
5230
5319
|
/**
|
|
@@ -5240,7 +5329,7 @@ var SharedDepsDetector = class {
|
|
|
5240
5329
|
if (uniqueVersions.length === 1) {
|
|
5241
5330
|
return uniqueVersions[0];
|
|
5242
5331
|
}
|
|
5243
|
-
const sorted = [...uniqueVersions].sort(
|
|
5332
|
+
const sorted = [...uniqueVersions].sort(semver2.compare);
|
|
5244
5333
|
return sorted[0];
|
|
5245
5334
|
}
|
|
5246
5335
|
};
|
|
@@ -5300,6 +5389,7 @@ export {
|
|
|
5300
5389
|
StorageManager,
|
|
5301
5390
|
ToolRegistry,
|
|
5302
5391
|
adapterRegistry,
|
|
5392
|
+
aiStore,
|
|
5303
5393
|
apiEngine,
|
|
5304
5394
|
assertManifest,
|
|
5305
5395
|
cleanUrlParams,
|
|
@@ -5323,6 +5413,7 @@ export {
|
|
|
5323
5413
|
evaluateRule,
|
|
5324
5414
|
evaluateRules,
|
|
5325
5415
|
extractManifestFromPlugin,
|
|
5416
|
+
featureFlagsStore,
|
|
5326
5417
|
getDefaultRegistry,
|
|
5327
5418
|
handleError,
|
|
5328
5419
|
simpleHash2 as hashString,
|
|
@@ -5340,9 +5431,6 @@ export {
|
|
|
5340
5431
|
resolvePluginRegistry,
|
|
5341
5432
|
serviceRegistry,
|
|
5342
5433
|
simpleHash,
|
|
5343
|
-
useAIStore,
|
|
5344
|
-
useFeature,
|
|
5345
|
-
useFeatureFlags,
|
|
5346
5434
|
validateManifest,
|
|
5347
5435
|
version
|
|
5348
5436
|
};
|