@yunzai-ng/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +51 -0
- package/dist/adapter/accounts.d.ts +174 -0
- package/dist/adapter/accounts.d.ts.map +1 -0
- package/dist/adapter/accounts.js +653 -0
- package/dist/adapter/accounts.js.map +1 -0
- package/dist/adapter/bots.d.ts +142 -0
- package/dist/adapter/bots.d.ts.map +1 -0
- package/dist/adapter/bots.js +454 -0
- package/dist/adapter/bots.js.map +1 -0
- package/dist/adapter/host.d.ts +114 -0
- package/dist/adapter/host.d.ts.map +1 -0
- package/dist/adapter/host.js +90 -0
- package/dist/adapter/host.js.map +1 -0
- package/dist/adapter/login.d.ts +174 -0
- package/dist/adapter/login.d.ts.map +1 -0
- package/dist/adapter/login.js +345 -0
- package/dist/adapter/login.js.map +1 -0
- package/dist/adapter/registry.d.ts +102 -0
- package/dist/adapter/registry.d.ts.map +1 -0
- package/dist/adapter/registry.js +150 -0
- package/dist/adapter/registry.js.map +1 -0
- package/dist/config/core-config.d.ts +151 -0
- package/dist/config/core-config.d.ts.map +1 -0
- package/dist/config/core-config.js +338 -0
- package/dist/config/core-config.js.map +1 -0
- package/dist/config/schema.d.ts +449 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +871 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/store.d.ts +184 -0
- package/dist/config/store.d.ts.map +1 -0
- package/dist/config/store.js +428 -0
- package/dist/config/store.js.map +1 -0
- package/dist/config/yaml.d.ts +23 -0
- package/dist/config/yaml.d.ts.map +1 -0
- package/dist/config/yaml.js +108 -0
- package/dist/config/yaml.js.map +1 -0
- package/dist/http/client.d.ts +82 -0
- package/dist/http/client.d.ts.map +1 -0
- package/dist/http/client.js +658 -0
- package/dist/http/client.js.map +1 -0
- package/dist/index.d.ts +77 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +94 -0
- package/dist/index.js.map +1 -0
- package/dist/kernel/app.d.ts +244 -0
- package/dist/kernel/app.d.ts.map +1 -0
- package/dist/kernel/app.js +654 -0
- package/dist/kernel/app.js.map +1 -0
- package/dist/kernel/kv-sink.d.ts +34 -0
- package/dist/kernel/kv-sink.d.ts.map +1 -0
- package/dist/kernel/kv-sink.js +25 -0
- package/dist/kernel/kv-sink.js.map +1 -0
- package/dist/kernel/policy.d.ts +77 -0
- package/dist/kernel/policy.d.ts.map +1 -0
- package/dist/kernel/policy.js +99 -0
- package/dist/kernel/policy.js.map +1 -0
- package/dist/kernel/runtime.d.ts +117 -0
- package/dist/kernel/runtime.d.ts.map +1 -0
- package/dist/kernel/runtime.js +197 -0
- package/dist/kernel/runtime.js.map +1 -0
- package/dist/kernel/sql-sink.d.ts +36 -0
- package/dist/kernel/sql-sink.d.ts.map +1 -0
- package/dist/kernel/sql-sink.js +114 -0
- package/dist/kernel/sql-sink.js.map +1 -0
- package/dist/logger/format.d.ts +67 -0
- package/dist/logger/format.d.ts.map +1 -0
- package/dist/logger/format.js +218 -0
- package/dist/logger/format.js.map +1 -0
- package/dist/logger/index.d.ts +97 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +363 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger/rotate.d.ts +47 -0
- package/dist/logger/rotate.d.ts.map +1 -0
- package/dist/logger/rotate.js +242 -0
- package/dist/logger/rotate.js.map +1 -0
- package/dist/message/segment.d.ts +255 -0
- package/dist/message/segment.d.ts.map +1 -0
- package/dist/message/segment.js +510 -0
- package/dist/message/segment.js.map +1 -0
- package/dist/message/split.d.ts +34 -0
- package/dist/message/split.d.ts.map +1 -0
- package/dist/message/split.js +79 -0
- package/dist/message/split.js.map +1 -0
- package/dist/message/target.d.ts +29 -0
- package/dist/message/target.d.ts.map +1 -0
- package/dist/message/target.js +34 -0
- package/dist/message/target.js.map +1 -0
- package/dist/pipeline/cooldown.d.ts +84 -0
- package/dist/pipeline/cooldown.d.ts.map +1 -0
- package/dist/pipeline/cooldown.js +94 -0
- package/dist/pipeline/cooldown.js.map +1 -0
- package/dist/pipeline/dispatch.d.ts +98 -0
- package/dist/pipeline/dispatch.d.ts.map +1 -0
- package/dist/pipeline/dispatch.js +323 -0
- package/dist/pipeline/dispatch.js.map +1 -0
- package/dist/pipeline/event.d.ts +130 -0
- package/dist/pipeline/event.d.ts.map +1 -0
- package/dist/pipeline/event.js +538 -0
- package/dist/pipeline/event.js.map +1 -0
- package/dist/pipeline/middleware.d.ts +63 -0
- package/dist/pipeline/middleware.d.ts.map +1 -0
- package/dist/pipeline/middleware.js +174 -0
- package/dist/pipeline/middleware.js.map +1 -0
- package/dist/pipeline/prompt.d.ts +80 -0
- package/dist/pipeline/prompt.d.ts.map +1 -0
- package/dist/pipeline/prompt.js +155 -0
- package/dist/pipeline/prompt.js.map +1 -0
- package/dist/pipeline/router.d.ts +98 -0
- package/dist/pipeline/router.d.ts.map +1 -0
- package/dist/pipeline/router.js +489 -0
- package/dist/pipeline/router.js.map +1 -0
- package/dist/platform/detect.d.ts +24 -0
- package/dist/platform/detect.d.ts.map +1 -0
- package/dist/platform/detect.js +178 -0
- package/dist/platform/detect.js.map +1 -0
- package/dist/platform/paths.d.ts +38 -0
- package/dist/platform/paths.d.ts.map +1 -0
- package/dist/platform/paths.js +129 -0
- package/dist/platform/paths.js.map +1 -0
- package/dist/platform/system.d.ts +71 -0
- package/dist/platform/system.d.ts.map +1 -0
- package/dist/platform/system.js +242 -0
- package/dist/platform/system.js.map +1 -0
- package/dist/plugin/context.d.ts +92 -0
- package/dist/plugin/context.d.ts.map +1 -0
- package/dist/plugin/context.js +573 -0
- package/dist/plugin/context.js.map +1 -0
- package/dist/plugin/define.d.ts +92 -0
- package/dist/plugin/define.d.ts.map +1 -0
- package/dist/plugin/define.js +82 -0
- package/dist/plugin/define.js.map +1 -0
- package/dist/plugin/discover.d.ts +106 -0
- package/dist/plugin/discover.d.ts.map +1 -0
- package/dist/plugin/discover.js +254 -0
- package/dist/plugin/discover.js.map +1 -0
- package/dist/plugin/events.d.ts +109 -0
- package/dist/plugin/events.d.ts.map +1 -0
- package/dist/plugin/events.js +209 -0
- package/dist/plugin/events.js.map +1 -0
- package/dist/plugin/hooks.d.ts +266 -0
- package/dist/plugin/hooks.d.ts.map +1 -0
- package/dist/plugin/hooks.js +84 -0
- package/dist/plugin/hooks.js.map +1 -0
- package/dist/plugin/host.d.ts +160 -0
- package/dist/plugin/host.d.ts.map +1 -0
- package/dist/plugin/host.js +546 -0
- package/dist/plugin/host.js.map +1 -0
- package/dist/plugin/market.d.ts +264 -0
- package/dist/plugin/market.d.ts.map +1 -0
- package/dist/plugin/market.js +700 -0
- package/dist/plugin/market.js.map +1 -0
- package/dist/plugin/services.d.ts +116 -0
- package/dist/plugin/services.d.ts.map +1 -0
- package/dist/plugin/services.js +213 -0
- package/dist/plugin/services.js.map +1 -0
- package/dist/plugin/tar.d.ts +65 -0
- package/dist/plugin/tar.d.ts.map +1 -0
- package/dist/plugin/tar.js +277 -0
- package/dist/plugin/tar.js.map +1 -0
- package/dist/render/registry.d.ts +127 -0
- package/dist/render/registry.d.ts.map +1 -0
- package/dist/render/registry.js +306 -0
- package/dist/render/registry.js.map +1 -0
- package/dist/scheduler/index.d.ts +67 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +279 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/server/api.d.ts +179 -0
- package/dist/server/api.d.ts.map +1 -0
- package/dist/server/api.js +602 -0
- package/dist/server/api.js.map +1 -0
- package/dist/server/auth.d.ts +83 -0
- package/dist/server/auth.d.ts.map +1 -0
- package/dist/server/auth.js +178 -0
- package/dist/server/auth.js.map +1 -0
- package/dist/server/browse.d.ts +60 -0
- package/dist/server/browse.d.ts.map +1 -0
- package/dist/server/browse.js +187 -0
- package/dist/server/browse.js.map +1 -0
- package/dist/server/files.d.ts +27 -0
- package/dist/server/files.d.ts.map +1 -0
- package/dist/server/files.js +76 -0
- package/dist/server/files.js.map +1 -0
- package/dist/server/index.d.ts +189 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +1123 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/table.d.ts +105 -0
- package/dist/server/table.d.ts.map +1 -0
- package/dist/server/table.js +289 -0
- package/dist/server/table.js.map +1 -0
- package/dist/store/index.d.ts +50 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +120 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/json.d.ts +73 -0
- package/dist/store/json.d.ts.map +1 -0
- package/dist/store/json.js +174 -0
- package/dist/store/json.js.map +1 -0
- package/dist/store/kv.d.ts +126 -0
- package/dist/store/kv.d.ts.map +1 -0
- package/dist/store/kv.js +232 -0
- package/dist/store/kv.js.map +1 -0
- package/dist/store/level.d.ts +103 -0
- package/dist/store/level.d.ts.map +1 -0
- package/dist/store/level.js +119 -0
- package/dist/store/level.js.map +1 -0
- package/dist/store/memory.d.ts +61 -0
- package/dist/store/memory.d.ts.map +1 -0
- package/dist/store/memory.js +94 -0
- package/dist/store/memory.js.map +1 -0
- package/dist/store/sql.d.ts +142 -0
- package/dist/store/sql.d.ts.map +1 -0
- package/dist/store/sql.js +246 -0
- package/dist/store/sql.js.map +1 -0
- package/dist/testing/fake.d.ts +109 -0
- package/dist/testing/fake.d.ts.map +1 -0
- package/dist/testing/fake.js +196 -0
- package/dist/testing/fake.js.map +1 -0
- package/dist/testing/index.d.ts +16 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +16 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/mock-adapter.d.ts +205 -0
- package/dist/testing/mock-adapter.d.ts.map +1 -0
- package/dist/testing/mock-adapter.js +309 -0
- package/dist/testing/mock-adapter.js.map +1 -0
- package/dist/util/deep.d.ts +108 -0
- package/dist/util/deep.d.ts.map +1 -0
- package/dist/util/deep.js +275 -0
- package/dist/util/deep.js.map +1 -0
- package/dist/util/defer.d.ts +107 -0
- package/dist/util/defer.d.ts.map +1 -0
- package/dist/util/defer.js +163 -0
- package/dist/util/defer.js.map +1 -0
- package/dist/util/dispose.d.ts +88 -0
- package/dist/util/dispose.d.ts.map +1 -0
- package/dist/util/dispose.js +143 -0
- package/dist/util/dispose.js.map +1 -0
- package/dist/util/duration.d.ts +28 -0
- package/dist/util/duration.d.ts.map +1 -0
- package/dist/util/duration.js +77 -0
- package/dist/util/duration.js.map +1 -0
- package/dist/util/fs.d.ts +110 -0
- package/dist/util/fs.d.ts.map +1 -0
- package/dist/util/fs.js +269 -0
- package/dist/util/fs.js.map +1 -0
- package/dist/util/id.d.ts +49 -0
- package/dist/util/id.d.ts.map +1 -0
- package/dist/util/id.js +87 -0
- package/dist/util/id.js.map +1 -0
- package/dist/util/lru.d.ts +74 -0
- package/dist/util/lru.d.ts.map +1 -0
- package/dist/util/lru.js +156 -0
- package/dist/util/lru.js.map +1 -0
- package/dist/util/queue.d.ts +64 -0
- package/dist/util/queue.d.ts.map +1 -0
- package/dist/util/queue.js +147 -0
- package/dist/util/queue.js.map +1 -0
- package/dist/util/text.d.ts +86 -0
- package/dist/util/text.d.ts.map +1 -0
- package/dist/util/text.js +182 -0
- package/dist/util/text.js.map +1 -0
- package/package.json +44 -0
- package/src/adapter/accounts.ts +758 -0
- package/src/adapter/bots.ts +582 -0
- package/src/adapter/host.ts +224 -0
- package/src/adapter/login.ts +481 -0
- package/src/adapter/registry.ts +202 -0
- package/src/config/core-config.test.ts +60 -0
- package/src/config/core-config.ts +401 -0
- package/src/config/schema.test.ts +179 -0
- package/src/config/schema.ts +1036 -0
- package/src/config/store.test.ts +245 -0
- package/src/config/store.ts +506 -0
- package/src/config/yaml.ts +119 -0
- package/src/http/client.test.ts +568 -0
- package/src/http/client.ts +777 -0
- package/src/index.ts +106 -0
- package/src/kernel/app.test.ts +267 -0
- package/src/kernel/app.ts +843 -0
- package/src/kernel/kv-sink.ts +58 -0
- package/src/kernel/policy.ts +120 -0
- package/src/kernel/runtime.test.ts +542 -0
- package/src/kernel/runtime.ts +307 -0
- package/src/kernel/sql-sink.ts +154 -0
- package/src/logger/format.ts +259 -0
- package/src/logger/index.ts +427 -0
- package/src/logger/rotate.ts +265 -0
- package/src/message/segment.test.ts +335 -0
- package/src/message/segment.ts +569 -0
- package/src/message/split.ts +97 -0
- package/src/message/target.ts +48 -0
- package/src/pipeline/cooldown.ts +136 -0
- package/src/pipeline/dispatch.ts +419 -0
- package/src/pipeline/event.ts +735 -0
- package/src/pipeline/middleware.test.ts +426 -0
- package/src/pipeline/middleware.ts +199 -0
- package/src/pipeline/prompt.ts +212 -0
- package/src/pipeline/router.test.ts +432 -0
- package/src/pipeline/router.ts +575 -0
- package/src/platform/detect.ts +178 -0
- package/src/platform/paths.ts +147 -0
- package/src/platform/system.test.ts +102 -0
- package/src/platform/system.ts +289 -0
- package/src/plugin/context.test.ts +459 -0
- package/src/plugin/context.ts +757 -0
- package/src/plugin/define.test.ts +120 -0
- package/src/plugin/define.ts +142 -0
- package/src/plugin/discover.test.ts +253 -0
- package/src/plugin/discover.ts +353 -0
- package/src/plugin/events.test.ts +162 -0
- package/src/plugin/events.ts +266 -0
- package/src/plugin/hooks.ts +373 -0
- package/src/plugin/host.test.ts +696 -0
- package/src/plugin/host.ts +738 -0
- package/src/plugin/market.test.ts +781 -0
- package/src/plugin/market.ts +870 -0
- package/src/plugin/services.test.ts +135 -0
- package/src/plugin/services.ts +261 -0
- package/src/plugin/tar.test.ts +158 -0
- package/src/plugin/tar.ts +309 -0
- package/src/render/registry.test.ts +127 -0
- package/src/render/registry.ts +439 -0
- package/src/scheduler/index.ts +357 -0
- package/src/server/api.test.ts +802 -0
- package/src/server/api.ts +869 -0
- package/src/server/auth.ts +201 -0
- package/src/server/browse.test.ts +193 -0
- package/src/server/browse.ts +240 -0
- package/src/server/files.ts +97 -0
- package/src/server/index.test.ts +566 -0
- package/src/server/index.ts +1386 -0
- package/src/server/table.ts +351 -0
- package/src/store/index.ts +156 -0
- package/src/store/json.ts +198 -0
- package/src/store/kv.test.ts +307 -0
- package/src/store/kv.ts +256 -0
- package/src/store/level.ts +167 -0
- package/src/store/memory.ts +109 -0
- package/src/store/sql.test.ts +204 -0
- package/src/store/sql.ts +324 -0
- package/src/testing/fake.ts +297 -0
- package/src/testing/index.ts +15 -0
- package/src/testing/mock-adapter.ts +588 -0
- package/src/util/deep.ts +272 -0
- package/src/util/defer.ts +211 -0
- package/src/util/dispose.ts +169 -0
- package/src/util/duration.ts +82 -0
- package/src/util/fs.ts +279 -0
- package/src/util/id.ts +94 -0
- package/src/util/lru.ts +185 -0
- package/src/util/queue.ts +167 -0
- package/src/util/text.ts +189 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 插件名合法形式
|
|
3
|
+
*
|
|
4
|
+
* 与配置名规则保持一致(见 config/store.ts):插件名直接就是
|
|
5
|
+
* `config/<name>.yaml` 的文件名。额外排除了 `:`(KV 命名空间分隔符)
|
|
6
|
+
* 与路径分隔符,否则一个插件能读写别人的命名空间。
|
|
7
|
+
*/
|
|
8
|
+
const NAME_RE = /^[a-z][a-z0-9._-]*$/i;
|
|
9
|
+
/** 标记"这是 definePlugin 的产物",用于加载时校验默认导出 */
|
|
10
|
+
const BRAND = Symbol.for("yunzai-ng.plugin");
|
|
11
|
+
/**
|
|
12
|
+
* 声明一个插件
|
|
13
|
+
*
|
|
14
|
+
* @param input 插件定义
|
|
15
|
+
* @returns 供内核加载的插件定义(已冻结)
|
|
16
|
+
* @throws 插件名缺失/非法、`setup` 不是函数、依赖项写法错误时
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* export default definePlugin({
|
|
20
|
+
* name: "mhy-game",
|
|
21
|
+
* configSchema: s.object({ cookie: s.string().default("") }),
|
|
22
|
+
* setup(ctx) {
|
|
23
|
+
* ctx.command("#体力").desc("查询实时便笺").action(async e => {
|
|
24
|
+
* await e.reply(ctx.config.get().cookie ? "查询中" : "请先配置 cookie")
|
|
25
|
+
* })
|
|
26
|
+
* }
|
|
27
|
+
* })
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export function definePlugin(input) {
|
|
31
|
+
if (typeof input?.name !== "string" || input.name.length === 0) {
|
|
32
|
+
throw new Error("definePlugin:缺少 name,插件必须有名字");
|
|
33
|
+
}
|
|
34
|
+
if (!NAME_RE.test(input.name)) {
|
|
35
|
+
throw new Error(`definePlugin:插件名 ${input.name} 不合法。需以字母开头,只含字母、数字与 . - _(它同时是配置文件名与存储命名空间)`);
|
|
36
|
+
}
|
|
37
|
+
if (typeof input.setup !== "function") {
|
|
38
|
+
throw new Error(`definePlugin:插件 ${input.name} 缺少 setup 函数`);
|
|
39
|
+
}
|
|
40
|
+
if (input.dependencies && !Array.isArray(input.dependencies)) {
|
|
41
|
+
throw new Error(`definePlugin:插件 ${input.name} 的 dependencies 必须是字符串数组`);
|
|
42
|
+
}
|
|
43
|
+
for (const dep of input.dependencies ?? []) {
|
|
44
|
+
if (typeof dep !== "string" || dep.length === 0) {
|
|
45
|
+
throw new Error(`definePlugin:插件 ${input.name} 的 dependencies 含空项`);
|
|
46
|
+
}
|
|
47
|
+
if (dep === input.name) {
|
|
48
|
+
throw new Error(`definePlugin:插件 ${input.name} 依赖了自己`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (input.priority !== undefined && !Number.isFinite(input.priority)) {
|
|
52
|
+
throw new Error(`definePlugin:插件 ${input.name} 的 priority 必须是数字`);
|
|
53
|
+
}
|
|
54
|
+
// 浅冻结:防止插件在运行期改自己的元信息(改了内核也不会重新读,只会造成困惑)
|
|
55
|
+
return Object.freeze({ ...input, [BRAND]: true });
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 判断一个值是否 `definePlugin` 的产物
|
|
59
|
+
*
|
|
60
|
+
* 加载器用它区分"插件写错了默认导出"和"插件确实是插件",
|
|
61
|
+
* 从而给出"请用 definePlugin 包一层"这种能直接照做的提示。
|
|
62
|
+
* @param value 待判定值
|
|
63
|
+
* @returns 是否为插件定义
|
|
64
|
+
*/
|
|
65
|
+
export function isPluginDefinition(value) {
|
|
66
|
+
return typeof value === "object" && value !== null && value[BRAND] === true;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 宽松判定:像插件定义但可能没走 `definePlugin`
|
|
70
|
+
*
|
|
71
|
+
* 允许手写对象(如测试里的假插件、compat 插件动态生成的定义),
|
|
72
|
+
* 只要有 name 与 setup 就接受,但加载器会记一条 debug 提示。
|
|
73
|
+
* @param value 待判定值
|
|
74
|
+
* @returns 是否可当作插件定义使用
|
|
75
|
+
*/
|
|
76
|
+
export function looksLikePlugin(value) {
|
|
77
|
+
if (typeof value !== "object" || value === null)
|
|
78
|
+
return false;
|
|
79
|
+
const obj = value;
|
|
80
|
+
return typeof obj.name === "string" && typeof obj.setup === "function";
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=define.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../src/plugin/define.ts"],"names":[],"mappings":"AAmBA;;;;;;GAMG;AACH,MAAM,OAAO,GAAG,sBAAsB,CAAA;AAEtC,0CAA0C;AAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;AAsC5C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAC1B,KAA2B;IAE3B,IAAI,OAAO,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;IACjD,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,oBAAoB,KAAK,CAAC,IAAI,8CAA8C,CAAC,CAAA;IAC/F,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,CAAC,IAAI,cAAc,CAAC,CAAA;IAC9D,CAAC;IACD,IAAI,KAAK,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,CAAC,IAAI,0BAA0B,CAAC,CAAA;IAC1E,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;QAC3C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,CAAC,IAAI,qBAAqB,CAAC,CAAA;QACrE,CAAC;QACD,IAAI,GAAG,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,CAAC,IAAI,QAAQ,CAAC,CAAA;QACxD,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,CAAC,IAAI,mBAAmB,CAAC,CAAA;IACnE,CAAC;IAED,yCAAyC;IACzC,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAA6C,CAAA;AAC/F,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAK,KAAiC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAA;AAC1G,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAC7D,MAAM,GAAG,GAAG,KAAkC,CAAA;IAC9C,OAAO,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,UAAU,CAAA;AACxE,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { Logger } from "@yunzai-ng/types";
|
|
2
|
+
/** package.json 里与本框架相关的字段 */
|
|
3
|
+
interface PackageManifest {
|
|
4
|
+
/** npm 包名 */
|
|
5
|
+
name?: string;
|
|
6
|
+
/** 版本 */
|
|
7
|
+
version?: string;
|
|
8
|
+
/** 说明 */
|
|
9
|
+
description?: string;
|
|
10
|
+
/** 作者,可能是字符串或对象 */
|
|
11
|
+
author?: string | {
|
|
12
|
+
name?: string;
|
|
13
|
+
};
|
|
14
|
+
/** 主页 */
|
|
15
|
+
homepage?: string;
|
|
16
|
+
/** 入口 */
|
|
17
|
+
main?: string;
|
|
18
|
+
/** 模块入口 */
|
|
19
|
+
module?: string;
|
|
20
|
+
/** exports 映射(只认 `"."`) */
|
|
21
|
+
exports?: unknown;
|
|
22
|
+
/** 框架专属字段,用于不执行代码就能读到的信息 */
|
|
23
|
+
yunzai?: {
|
|
24
|
+
/** 覆盖插件名 */
|
|
25
|
+
name?: string;
|
|
26
|
+
/** 是否禁用 */
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
/** 入口文件 */
|
|
29
|
+
entry?: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** 一个待加载的插件候选 */
|
|
33
|
+
export interface PluginCandidate {
|
|
34
|
+
/**
|
|
35
|
+
* 名字线索(目录名或包名)
|
|
36
|
+
*
|
|
37
|
+
* 真正的插件名以 `definePlugin({ name })` 为准;这个只用于导入失败时的日志,
|
|
38
|
+
* 因为那时候还读不到定义。
|
|
39
|
+
*/
|
|
40
|
+
id: string;
|
|
41
|
+
/** 插件根目录绝对路径 */
|
|
42
|
+
dir: string;
|
|
43
|
+
/** 入口文件绝对路径 */
|
|
44
|
+
entry: string;
|
|
45
|
+
/** 是否为随发行版预置的插件 */
|
|
46
|
+
builtin: boolean;
|
|
47
|
+
/** package.json 内容(若有) */
|
|
48
|
+
manifest?: PackageManifest;
|
|
49
|
+
}
|
|
50
|
+
/** 被跳过的插件及原因 */
|
|
51
|
+
export interface SkippedPlugin {
|
|
52
|
+
/** 插件名 */
|
|
53
|
+
name: string;
|
|
54
|
+
/** 跳过原因(直接展示给用户,必须能照着解决) */
|
|
55
|
+
reason: string;
|
|
56
|
+
}
|
|
57
|
+
/** 发现插件的参数 */
|
|
58
|
+
export interface DiscoverOptions {
|
|
59
|
+
/** 要扫描的目录(绝对路径),按顺序扫描,先出现者优先 */
|
|
60
|
+
dirs: string[];
|
|
61
|
+
/** 其中属于"内置"的目录,用于给候选打 builtin 标记 */
|
|
62
|
+
builtinDirs?: string[];
|
|
63
|
+
/** 用户在配置里禁用的插件名 */
|
|
64
|
+
disabled?: readonly string[];
|
|
65
|
+
/** 日志器 */
|
|
66
|
+
logger: Logger;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 发现全部插件
|
|
70
|
+
*
|
|
71
|
+
* 同名插件只保留先扫到的那份(目录顺序即优先级),并记一条警告 ——
|
|
72
|
+
* 用户插件目录排在预置目录之前,因此复制一份预置插件加以修改即可覆盖原插件。
|
|
73
|
+
* @param opts 参数
|
|
74
|
+
* @returns 候选数组
|
|
75
|
+
*/
|
|
76
|
+
export declare function discoverPlugins(opts: DiscoverOptions): Promise<PluginCandidate[]>;
|
|
77
|
+
/** 参与排序所需的最小信息 */
|
|
78
|
+
export interface OrderableUnit {
|
|
79
|
+
/** 插件名 */
|
|
80
|
+
name: string;
|
|
81
|
+
/** 依赖的插件名 */
|
|
82
|
+
dependencies?: string[];
|
|
83
|
+
/** 优先级,小者先加载 */
|
|
84
|
+
priority?: number;
|
|
85
|
+
}
|
|
86
|
+
/** 排序结果 */
|
|
87
|
+
export interface LoadOrder<T extends OrderableUnit> {
|
|
88
|
+
/** 可加载的插件,已按依赖与优先级排好 */
|
|
89
|
+
order: T[];
|
|
90
|
+
/** 被跳过的插件 */
|
|
91
|
+
skipped: SkippedPlugin[];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 规划加载顺序
|
|
95
|
+
*
|
|
96
|
+
* 三步:去重 → 剔除依赖不可满足者(级联)→ 拓扑排序。
|
|
97
|
+
*
|
|
98
|
+
* 排序在同层节点之间以 `(priority, name)` 作**确定性**排序:
|
|
99
|
+
* 同一份插件集合在任何机器上都得到相同顺序,否则"甲机器正常、乙机器异常"
|
|
100
|
+
* 这类问题会耗费大量排障时间。
|
|
101
|
+
* @param units 待排序的插件定义
|
|
102
|
+
* @returns 顺序与跳过列表
|
|
103
|
+
*/
|
|
104
|
+
export declare function resolveLoadOrder<T extends OrderableUnit>(units: readonly T[]): LoadOrder<T>;
|
|
105
|
+
export {};
|
|
106
|
+
//# sourceMappingURL=discover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../src/plugin/discover.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAkB9C,8BAA8B;AAC9B,UAAU,eAAe;IACvB,aAAa;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS;IACT,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS;IACT,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mBAAmB;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACnC,SAAS;IACT,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS;IACT,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,2BAA2B;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,4BAA4B;IAC5B,MAAM,CAAC,EAAE;QACP,YAAY;QACZ,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,WAAW;QACX,QAAQ,CAAC,EAAE,OAAO,CAAA;QAClB,WAAW;QACX,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;CACF;AAED,iBAAiB;AACjB,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,EAAE,EAAE,MAAM,CAAA;IACV,gBAAgB;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,eAAe;IACf,KAAK,EAAE,MAAM,CAAA;IACb,mBAAmB;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,eAAe,CAAA;CAC3B;AAED,gBAAgB;AAChB,MAAM,WAAW,aAAa;IAC5B,UAAU;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAA;CACf;AAED,cAAc;AACd,MAAM,WAAW,eAAe;IAC9B,gCAAgC;IAChC,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,mBAAmB;IACnB,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC5B,UAAU;IACV,MAAM,EAAE,MAAM,CAAA;CACf;AAkHD;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CA0BvF;AAED,kBAAkB;AAClB,MAAM,WAAW,aAAa;IAC5B,UAAU;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa;IACb,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,WAAW;AACX,MAAM,WAAW,SAAS,CAAC,CAAC,SAAS,aAAa;IAChD,wBAAwB;IACxB,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,aAAa;IACb,OAAO,EAAE,aAAa,EAAE,CAAA;CACzB;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CA2E3F"}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 模块职责:发现磁盘上的插件、解析入口、规划加载顺序
|
|
3
|
+
* 依赖方向:依赖 util/fs、类型包;不 import 任何插件
|
|
4
|
+
* 生命周期:每次全量加载/热重载时调用
|
|
5
|
+
* 注意事项:**顺序规划与文件发现分离**是这里的关键:先把候选文件找出来 → 全部 import
|
|
6
|
+
* 拿到声明式元信息 → 用依赖图算出确定顺序 → 再按序 setup。加载顺序由声明的
|
|
7
|
+
* 依赖决定,而非文件名字典序。
|
|
8
|
+
*
|
|
9
|
+
* 依赖缺失**不连坐内核**:只把依赖它的插件标记为跳过,其余照常工作。
|
|
10
|
+
*/
|
|
11
|
+
import { basename, isAbsolute, join, resolve } from "node:path";
|
|
12
|
+
import { isDirectory, isFile, listDirs, listFiles, readJson } from "../util/fs.js";
|
|
13
|
+
/**
|
|
14
|
+
* 本进程是否运行在 TypeScript 源码模式
|
|
15
|
+
*
|
|
16
|
+
* 通过"本模块自身是否 .ts"判断:vitest / tsx 下为真,编译产物下为假。
|
|
17
|
+
* 为真时才把 `src/index.ts` 当作合法入口,否则一个没编译的插件会以
|
|
18
|
+
* "Unknown file extension .ts" 这种毫无指向性的错误失败。
|
|
19
|
+
*/
|
|
20
|
+
const TS_RUNTIME = import.meta.url.endsWith(".ts");
|
|
21
|
+
/** 依次尝试的入口文件(相对插件目录) */
|
|
22
|
+
const ENTRY_CANDIDATES = ["dist/index.js", "index.js", "index.mjs", "lib/index.js"];
|
|
23
|
+
/** 单文件插件允许的扩展名 */
|
|
24
|
+
const SINGLE_FILE_EXT = [".js", ".mjs"];
|
|
25
|
+
/**
|
|
26
|
+
* 解析 package.json 的入口字段
|
|
27
|
+
*
|
|
28
|
+
* 只认 `exports["."]` 的字符串形式与 `import`/`default` 条件;再复杂的条件导出
|
|
29
|
+
* 交给 Node 自己解析(此时返回 undefined,由调用方回落到目录导入)。
|
|
30
|
+
* @param manifest package.json 内容
|
|
31
|
+
* @returns 相对路径;无法确定时 undefined
|
|
32
|
+
*/
|
|
33
|
+
function entryFromManifest(manifest) {
|
|
34
|
+
if (manifest.yunzai?.entry)
|
|
35
|
+
return manifest.yunzai.entry;
|
|
36
|
+
const exp = manifest.exports;
|
|
37
|
+
if (typeof exp === "string")
|
|
38
|
+
return exp;
|
|
39
|
+
if (exp && typeof exp === "object") {
|
|
40
|
+
const dot = exp["."];
|
|
41
|
+
if (typeof dot === "string")
|
|
42
|
+
return dot;
|
|
43
|
+
if (dot && typeof dot === "object") {
|
|
44
|
+
const cond = dot;
|
|
45
|
+
for (const key of ["import", "module", "default"]) {
|
|
46
|
+
const value = cond[key];
|
|
47
|
+
if (typeof value === "string")
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return manifest.module ?? manifest.main;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 在插件目录里找入口文件
|
|
56
|
+
* @param dir 插件目录
|
|
57
|
+
* @param manifest package.json 内容
|
|
58
|
+
* @returns 入口绝对路径;找不到时 undefined
|
|
59
|
+
*/
|
|
60
|
+
async function resolveEntry(dir, manifest) {
|
|
61
|
+
const declared = manifest ? entryFromManifest(manifest) : undefined;
|
|
62
|
+
if (declared) {
|
|
63
|
+
const full = resolve(dir, declared);
|
|
64
|
+
if (await isFile(full))
|
|
65
|
+
return full;
|
|
66
|
+
}
|
|
67
|
+
const candidates = TS_RUNTIME ? [...ENTRY_CANDIDATES, "src/index.ts", "index.ts"] : ENTRY_CANDIDATES;
|
|
68
|
+
for (const rel of candidates) {
|
|
69
|
+
const full = join(dir, rel);
|
|
70
|
+
if (await isFile(full))
|
|
71
|
+
return full;
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 取插件名线索
|
|
77
|
+
*
|
|
78
|
+
* 优先 `yunzai.name`,其次去掉 scope 的包名,最后目录名。
|
|
79
|
+
* @param dir 插件目录
|
|
80
|
+
* @param manifest package.json 内容
|
|
81
|
+
* @returns 名字线索
|
|
82
|
+
*/
|
|
83
|
+
function idOf(dir, manifest) {
|
|
84
|
+
const explicit = manifest?.yunzai?.name;
|
|
85
|
+
if (explicit)
|
|
86
|
+
return explicit;
|
|
87
|
+
const pkg = manifest?.name;
|
|
88
|
+
if (pkg)
|
|
89
|
+
return pkg.startsWith("@") ? (pkg.split("/")[1] ?? pkg) : pkg;
|
|
90
|
+
return basename(dir);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 扫描一个目录下的全部插件
|
|
94
|
+
* @param root 要扫描的目录
|
|
95
|
+
* @param builtin 是否标记为内置
|
|
96
|
+
* @param logger 日志器
|
|
97
|
+
* @returns 候选数组
|
|
98
|
+
*/
|
|
99
|
+
async function scanDir(root, builtin, logger) {
|
|
100
|
+
if (!(await isDirectory(root)))
|
|
101
|
+
return [];
|
|
102
|
+
const out = [];
|
|
103
|
+
for (const name of await listDirs(root)) {
|
|
104
|
+
// `.` 开头是隐藏目录,`_` 开头约定为"作者临时禁用",node_modules 不用说
|
|
105
|
+
if (name.startsWith(".") || name.startsWith("_") || name === "node_modules")
|
|
106
|
+
continue;
|
|
107
|
+
const dir = join(root, name);
|
|
108
|
+
const manifest = await readJson(join(dir, "package.json"));
|
|
109
|
+
if (manifest?.yunzai?.disabled) {
|
|
110
|
+
logger.debug(`插件目录 ${name} 在 package.json 里自我标记为 disabled,跳过`);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const entry = await resolveEntry(dir, manifest);
|
|
114
|
+
if (!entry) {
|
|
115
|
+
logger.warn(`插件目录 ${name} 里找不到入口文件:请提供 ${ENTRY_CANDIDATES.join(" / ")} 之一,` +
|
|
116
|
+
`或在 package.json 的 main / yunzai.entry 里指明。若是 TypeScript 插件,请先编译`);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
out.push({ id: idOf(dir, manifest), dir, entry, builtin, manifest });
|
|
120
|
+
}
|
|
121
|
+
// 顶层单文件插件:plugins/我的小功能.js。给"就想加个几十行小功能"的用户留的口子,
|
|
122
|
+
// 不必为此建目录和 package.json
|
|
123
|
+
for (const ext of SINGLE_FILE_EXT) {
|
|
124
|
+
for (const file of await listFiles(root, ext)) {
|
|
125
|
+
const name = basename(file, ext);
|
|
126
|
+
if (name.startsWith(".") || name.startsWith("_"))
|
|
127
|
+
continue;
|
|
128
|
+
out.push({ id: name, dir: root, entry: join(root, file), builtin });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* 发现全部插件
|
|
135
|
+
*
|
|
136
|
+
* 同名插件只保留先扫到的那份(目录顺序即优先级),并记一条警告 ——
|
|
137
|
+
* 用户插件目录排在预置目录之前,因此复制一份预置插件加以修改即可覆盖原插件。
|
|
138
|
+
* @param opts 参数
|
|
139
|
+
* @returns 候选数组
|
|
140
|
+
*/
|
|
141
|
+
export async function discoverPlugins(opts) {
|
|
142
|
+
const builtin = new Set((opts.builtinDirs ?? []).map(dir => resolve(dir)));
|
|
143
|
+
const disabled = new Set(opts.disabled ?? []);
|
|
144
|
+
const seen = new Map();
|
|
145
|
+
for (const raw of opts.dirs) {
|
|
146
|
+
if (!isAbsolute(raw)) {
|
|
147
|
+
opts.logger.warn(`插件目录 ${raw} 不是绝对路径,已忽略(相对路径会随启动方式变化)`);
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
const dir = resolve(raw);
|
|
151
|
+
for (const candidate of await scanDir(dir, builtin.has(dir), opts.logger)) {
|
|
152
|
+
if (disabled.has(candidate.id)) {
|
|
153
|
+
opts.logger.info(`插件 ${candidate.id} 已被用户禁用,跳过`);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
const exists = seen.get(candidate.id);
|
|
157
|
+
if (exists) {
|
|
158
|
+
opts.logger.warn(`发现同名插件 ${candidate.id}:使用 ${exists.dir},忽略 ${candidate.dir}`);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
seen.set(candidate.id, candidate);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return [...seen.values()];
|
|
165
|
+
}
|
|
166
|
+
/** 默认加载优先级 */
|
|
167
|
+
const DEFAULT_PRIORITY = 100;
|
|
168
|
+
/**
|
|
169
|
+
* 规划加载顺序
|
|
170
|
+
*
|
|
171
|
+
* 三步:去重 → 剔除依赖不可满足者(级联)→ 拓扑排序。
|
|
172
|
+
*
|
|
173
|
+
* 排序在同层节点之间以 `(priority, name)` 作**确定性**排序:
|
|
174
|
+
* 同一份插件集合在任何机器上都得到相同顺序,否则"甲机器正常、乙机器异常"
|
|
175
|
+
* 这类问题会耗费大量排障时间。
|
|
176
|
+
* @param units 待排序的插件定义
|
|
177
|
+
* @returns 顺序与跳过列表
|
|
178
|
+
*/
|
|
179
|
+
export function resolveLoadOrder(units) {
|
|
180
|
+
const skipped = [];
|
|
181
|
+
const byName = new Map();
|
|
182
|
+
for (const unit of units) {
|
|
183
|
+
if (byName.has(unit.name)) {
|
|
184
|
+
skipped.push({ name: unit.name, reason: `插件名 ${unit.name} 重复,只加载第一个` });
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
byName.set(unit.name, unit);
|
|
188
|
+
}
|
|
189
|
+
// 级联剔除:A 依赖 B,B 因缺依赖被剔除,A 也留不住
|
|
190
|
+
let changed = true;
|
|
191
|
+
while (changed) {
|
|
192
|
+
changed = false;
|
|
193
|
+
for (const [name, unit] of byName) {
|
|
194
|
+
const missing = (unit.dependencies ?? []).filter(dep => !byName.has(dep));
|
|
195
|
+
if (missing.length === 0)
|
|
196
|
+
continue;
|
|
197
|
+
byName.delete(name);
|
|
198
|
+
skipped.push({
|
|
199
|
+
name,
|
|
200
|
+
reason: `依赖的插件未安装或已被跳过:${missing.join("、")}。装上它们或删掉本插件的依赖声明`
|
|
201
|
+
});
|
|
202
|
+
changed = true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/** 同层排序:优先级小者先,其次名字字典序 */
|
|
206
|
+
const compare = (a, b) => {
|
|
207
|
+
const pa = a.priority ?? DEFAULT_PRIORITY;
|
|
208
|
+
const pb = b.priority ?? DEFAULT_PRIORITY;
|
|
209
|
+
return pa !== pb ? pa - pb : a.name.localeCompare(b.name);
|
|
210
|
+
};
|
|
211
|
+
// Kahn:indegree 为"还有几个依赖没就绪"
|
|
212
|
+
const indegree = new Map();
|
|
213
|
+
const dependents = new Map();
|
|
214
|
+
for (const [name, unit] of byName) {
|
|
215
|
+
const deps = (unit.dependencies ?? []).filter(dep => byName.has(dep));
|
|
216
|
+
indegree.set(name, deps.length);
|
|
217
|
+
for (const dep of deps) {
|
|
218
|
+
const list = dependents.get(dep);
|
|
219
|
+
if (list)
|
|
220
|
+
list.push(name);
|
|
221
|
+
else
|
|
222
|
+
dependents.set(dep, [name]);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
const ready = [...byName.values()].filter(unit => indegree.get(unit.name) === 0).sort(compare);
|
|
226
|
+
const order = [];
|
|
227
|
+
while (ready.length > 0) {
|
|
228
|
+
const unit = ready.shift();
|
|
229
|
+
order.push(unit);
|
|
230
|
+
for (const name of dependents.get(unit.name) ?? []) {
|
|
231
|
+
const left = (indegree.get(name) ?? 0) - 1;
|
|
232
|
+
indegree.set(name, left);
|
|
233
|
+
if (left !== 0)
|
|
234
|
+
continue;
|
|
235
|
+
const next = byName.get(name);
|
|
236
|
+
if (!next)
|
|
237
|
+
continue;
|
|
238
|
+
// 插进有序位置,保持"每次取出的都是当前可加载里最该先加载的那个"
|
|
239
|
+
const at = ready.findIndex(item => compare(item, next) > 0);
|
|
240
|
+
if (at < 0)
|
|
241
|
+
ready.push(next);
|
|
242
|
+
else
|
|
243
|
+
ready.splice(at, 0, next);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (order.length !== byName.size) {
|
|
247
|
+
const loop = [...byName.keys()].filter(name => (indegree.get(name) ?? 0) > 0).sort();
|
|
248
|
+
for (const name of loop) {
|
|
249
|
+
skipped.push({ name, reason: `插件依赖成环,无法确定加载顺序:${loop.join(" → ")}` });
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return { order, skipped };
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=discover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/plugin/discover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 模块职责:内核事件总线(`ctx.on` 的实现)
|
|
3
|
+
* 依赖方向:依赖 util/defer、类型包
|
|
4
|
+
* 生命周期:应用级单例
|
|
5
|
+
* 注意事项:刻意不使用 Node 的 EventEmitter,原因有三 ——
|
|
6
|
+
*
|
|
7
|
+
* 1) **错误隔离**。EventEmitter 中一个监听器抛错即中断整条 emit 链,
|
|
8
|
+
* 其后的监听器收不到事件;异步监听器抛错更会转为
|
|
9
|
+
* unhandledRejection 直接终止进程 —— 一个插件的缺陷便影响全部插件。
|
|
10
|
+
* 2) **可等待异步监听器**。`app/stopping` 必须等待插件保存完状态方可继续
|
|
11
|
+
* 停机,而 EventEmitter 不 await 返回的 Promise。
|
|
12
|
+
* 3) **可按插件归属批量摘除**,且每次订阅均返回 Disposer,
|
|
13
|
+
* 热重载不残留悬空监听器。
|
|
14
|
+
*
|
|
15
|
+
* 单个监听器超时(缺省 10s)会被**放弃等待**并记录警告:无法真正终止它,
|
|
16
|
+
* 但绝不使一个阻塞的插件永久阻止停机流程完成。
|
|
17
|
+
*/
|
|
18
|
+
import type { Awaitable, Disposer, Logger } from "@yunzai-ng/types";
|
|
19
|
+
import type { CoreEventMap } from "@yunzai-ng/types";
|
|
20
|
+
/** 事件总线参数 */
|
|
21
|
+
export interface EventBusOptions {
|
|
22
|
+
/** 日志器 */
|
|
23
|
+
logger: Logger;
|
|
24
|
+
/** 单个监听器等待上限毫秒,缺省 10000;<=0 表示不限时 */
|
|
25
|
+
handlerTimeout?: number;
|
|
26
|
+
}
|
|
27
|
+
/** 监听器的对外描述 */
|
|
28
|
+
export interface ListenerInfo {
|
|
29
|
+
/** 事件名 */
|
|
30
|
+
event: string;
|
|
31
|
+
/** 归属插件 */
|
|
32
|
+
owner: string;
|
|
33
|
+
/** 触发次数 */
|
|
34
|
+
calls: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 内核事件总线
|
|
38
|
+
*
|
|
39
|
+
* 键类型来自 `CoreEventMap`,因此 `ctx.on("bot/online", bot => ...)` 里
|
|
40
|
+
* `bot` 的类型是自动推出来的,写错事件名编译期就报错。
|
|
41
|
+
*/
|
|
42
|
+
export declare class CoreEventBus {
|
|
43
|
+
#private;
|
|
44
|
+
/**
|
|
45
|
+
* @param opts 参数
|
|
46
|
+
*/
|
|
47
|
+
constructor(opts: EventBusOptions);
|
|
48
|
+
/**
|
|
49
|
+
* 订阅事件
|
|
50
|
+
* @param event 事件名
|
|
51
|
+
* @param fn 处理函数
|
|
52
|
+
* @param owner 归属插件名
|
|
53
|
+
* @returns 取消订阅句柄;重复调用无副作用
|
|
54
|
+
*/
|
|
55
|
+
on<K extends keyof CoreEventMap>(event: K, fn: (...args: CoreEventMap[K]) => Awaitable<void>, owner?: string): Disposer;
|
|
56
|
+
/**
|
|
57
|
+
* 订阅一次
|
|
58
|
+
* @param event 事件名
|
|
59
|
+
* @param fn 处理函数
|
|
60
|
+
* @param owner 归属插件名
|
|
61
|
+
* @returns 取消订阅句柄
|
|
62
|
+
*/
|
|
63
|
+
once<K extends keyof CoreEventMap>(event: K, fn: (...args: CoreEventMap[K]) => Awaitable<void>, owner?: string): Disposer;
|
|
64
|
+
/**
|
|
65
|
+
* 触发事件并等待全部监听器结束
|
|
66
|
+
*
|
|
67
|
+
* 监听器按注册顺序**同时启动**(而非串行),因为它们之间不应有依赖关系;
|
|
68
|
+
* 谁想要顺序保证就该用服务依赖或中间件优先级表达,而不是偷偷依赖注册顺序。
|
|
69
|
+
* @param event 事件名
|
|
70
|
+
* @param args 事件参数
|
|
71
|
+
* @returns 全部监听器结束(或超时被放弃)后兑现;本身永不拒绝
|
|
72
|
+
*/
|
|
73
|
+
emit<K extends keyof CoreEventMap>(event: K, ...args: CoreEventMap[K]): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* 触发事件但不等待
|
|
76
|
+
*
|
|
77
|
+
* 用于消息统计一类"通知即可"的场景:绝不能让某个插件的统计逻辑拖慢
|
|
78
|
+
* 消息处理主链路。错误照样被记录。
|
|
79
|
+
* @param event 事件名
|
|
80
|
+
* @param args 事件参数
|
|
81
|
+
*/
|
|
82
|
+
emitDetached<K extends keyof CoreEventMap>(event: K, ...args: CoreEventMap[K]): void;
|
|
83
|
+
/**
|
|
84
|
+
* 某事件当前的监听器数量
|
|
85
|
+
* @param event 事件名
|
|
86
|
+
* @returns 数量
|
|
87
|
+
*/
|
|
88
|
+
count<K extends keyof CoreEventMap>(event: K): number;
|
|
89
|
+
/**
|
|
90
|
+
* 摘除某插件的全部监听器
|
|
91
|
+
* @param owner 插件名
|
|
92
|
+
* @returns 摘除的数量
|
|
93
|
+
*/
|
|
94
|
+
removeByOwner(owner: string): number;
|
|
95
|
+
/**
|
|
96
|
+
* 列出全部监听器
|
|
97
|
+
* @returns 描述数组
|
|
98
|
+
*/
|
|
99
|
+
list(): ListenerInfo[];
|
|
100
|
+
/** 清空全部监听器并停止接受事件 */
|
|
101
|
+
close(): void;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 创建事件总线
|
|
105
|
+
* @param opts 参数
|
|
106
|
+
* @returns 总线实例
|
|
107
|
+
*/
|
|
108
|
+
export declare function createEventBus(opts: EventBusOptions): CoreEventBus;
|
|
109
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/plugin/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAkBpD,aAAa;AACb,MAAM,WAAW,eAAe;IAC9B,UAAU;IACV,MAAM,EAAE,MAAM,CAAA;IACd,qCAAqC;IACrC,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,eAAe;AACf,MAAM,WAAW,YAAY;IAC3B,UAAU;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW;IACX,KAAK,EAAE,MAAM,CAAA;IACb,WAAW;IACX,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;;GAKG;AACH,qBAAa,YAAY;;IAUvB;;OAEG;gBACS,IAAI,EAAE,eAAe;IAKjC;;;;;;OAMG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,YAAY,EAC7B,KAAK,EAAE,CAAC,EACR,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,IAAI,CAAC,EACjD,KAAK,SAAS,GACb,QAAQ;IAIX;;;;;;OAMG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,YAAY,EAC/B,KAAK,EAAE,CAAC,EACR,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,IAAI,CAAC,EACjD,KAAK,SAAS,GACb,QAAQ;IAIX;;;;;;;;OAQG;IACG,IAAI,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAO3F;;;;;;;OAOG;IACH,YAAY,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI;IAUpF;;;;OAIG;IACH,KAAK,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM;IAIrD;;;;OAIG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAWpC;;;OAGG;IACH,IAAI,IAAI,YAAY,EAAE;IAQtB,qBAAqB;IACrB,KAAK,IAAI,IAAI;CA4Ed;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,YAAY,CAElE"}
|