@yunzai-ng/core 0.1.0 → 0.2.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/dist/config/core-config.d.ts +1 -1
- package/dist/platform/paths.d.ts +10 -0
- package/dist/platform/paths.d.ts.map +1 -1
- package/dist/platform/paths.js +50 -7
- package/dist/platform/paths.js.map +1 -1
- package/dist/store/sql.js +4 -4
- package/package.json +12 -2
- package/src/adapter/accounts.ts +1 -1
- package/src/adapter/bots.ts +1 -1
- package/src/adapter/host.ts +1 -1
- package/src/adapter/login.ts +1 -1
- package/src/kernel/app.ts +843 -843
- package/src/kernel/policy.ts +120 -120
- package/src/kernel/runtime.ts +1 -1
- package/src/pipeline/event.ts +1 -1
- package/src/platform/paths.test.ts +166 -0
- package/src/platform/paths.ts +52 -7
- package/src/platform/system.ts +1 -1
- package/src/plugin/market.ts +1 -1
- package/src/plugin/services.ts +1 -1
- package/src/render/registry.ts +1 -1
- package/src/scheduler/index.ts +1 -1
- package/src/server/auth.ts +1 -1
- package/src/server/files.ts +1 -1
- package/src/server/index.ts +1 -1
- package/src/store/index.ts +156 -156
- package/src/store/kv.ts +256 -256
- package/src/store/sql.ts +324 -324
package/src/store/index.ts
CHANGED
|
@@ -1,156 +1,156 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 模块职责:KV 存储的装配(驱动选择、自动降级、根命名空间)
|
|
3
|
-
* 依赖方向:依赖 store/{kv,memory,json,level}、util/fs、类型包
|
|
4
|
-
* 生命周期:应用级单例,`close()` 时落盘
|
|
5
|
-
* 注意事项:**存储不可用不等于机器人不可用。** `auto` 模式按 level → json → memory 逐级降级,
|
|
6
|
-
* 每次降级记一条 warn 说明原因;最坏退到纯内存(重启丢缓存),但机器人始终能收发消息。
|
|
7
|
-
*
|
|
8
|
-
* 外部注册的驱动(如 store-redis 插件)通过 `registerKvDriver()` 挂进来,
|
|
9
|
-
* 与内置驱动一视同仁 —— 这正是"一切皆可为插件"在存储层的落点。
|
|
10
|
-
*/
|
|
11
|
-
import { join } from "node:path"
|
|
12
|
-
import type { KvDriver, KvNamespace, Logger } from "@yunzai-ng/types"
|
|
13
|
-
import { Kv } from "./kv.js"
|
|
14
|
-
import { MemoryKvDriver } from "./memory.js"
|
|
15
|
-
import { JsonKvDriver } from "./json.js"
|
|
16
|
-
import { LevelKvDriver, loadLevel } from "./level.js"
|
|
17
|
-
|
|
18
|
-
/** 内置驱动 id */
|
|
19
|
-
export type BuiltinDriverId = "auto" | "level" | "json" | "memory"
|
|
20
|
-
|
|
21
|
-
/** 驱动工厂:拿到数据目录,产出一个尚未 open 的驱动 */
|
|
22
|
-
export type KvDriverFactory = (dir: string) => Promise<KvDriver> | KvDriver
|
|
23
|
-
|
|
24
|
-
/** 外部注册的驱动表(插件注册的驱动进这里) */
|
|
25
|
-
const externalDrivers = new Map<string, KvDriverFactory>()
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* 注册一个 KV 驱动
|
|
29
|
-
*
|
|
30
|
-
* 供 `store-redis` 这类插件调用;配置里把 `store.driver` 写成同一个 id 即可启用。
|
|
31
|
-
* @param id 驱动 id
|
|
32
|
-
* @param factory 驱动工厂
|
|
33
|
-
* @returns 取消注册
|
|
34
|
-
* @throws id 与内置驱动冲突时
|
|
35
|
-
*/
|
|
36
|
-
export function registerKvDriver(id: string, factory: KvDriverFactory): () => void {
|
|
37
|
-
if (id === "auto" || id === "level" || id === "json" || id === "memory") {
|
|
38
|
-
throw new Error(`驱动 id ${id} 与内置驱动冲突`)
|
|
39
|
-
}
|
|
40
|
-
externalDrivers.set(id, factory)
|
|
41
|
-
return () => void externalDrivers.delete(id)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** 打开 KV 存储的参数 */
|
|
45
|
-
export interface OpenKvOptions {
|
|
46
|
-
/** 数据目录(KV 数据会放在其子目录里) */
|
|
47
|
-
dir: string
|
|
48
|
-
/** 驱动 id,缺省 `auto` */
|
|
49
|
-
driver?: string
|
|
50
|
-
/** 日志器 */
|
|
51
|
-
logger: Logger
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/** 已打开的 KV 存储 */
|
|
55
|
-
export interface KvStore {
|
|
56
|
-
/** 实际生效的驱动 id(`auto` 会被解析为具体驱动) */
|
|
57
|
-
readonly driver: string
|
|
58
|
-
/** 根命名空间 */
|
|
59
|
-
readonly root: KvNamespace
|
|
60
|
-
/**
|
|
61
|
-
* 取一个子命名空间
|
|
62
|
-
* @param name 命名空间名
|
|
63
|
-
* @returns KV 视图
|
|
64
|
-
*/
|
|
65
|
-
namespace(name: string): KvNamespace
|
|
66
|
-
/** 关闭并落盘 */
|
|
67
|
-
close(): Promise<void>
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* 打开 KV 存储
|
|
72
|
-
*
|
|
73
|
-
* `auto` 的降级顺序:level(性能最优)→ json(纯 JS,Termux 兜底)→ memory。
|
|
74
|
-
* 显式指定驱动时同样会降级,但会将"所指定的驱动为何不可用"记为 warn,
|
|
75
|
-
* 而非静默替换 —— 使用者配置了 redis 却运行于内存驱动之上而不知情是最糟的情形。
|
|
76
|
-
* @param opts 参数
|
|
77
|
-
* @returns 已打开的 KV 存储
|
|
78
|
-
*/
|
|
79
|
-
export async function openKv(opts: OpenKvOptions): Promise<KvStore> {
|
|
80
|
-
const logger = opts.logger.child({ scope: "store" })
|
|
81
|
-
const requested = opts.driver ?? "auto"
|
|
82
|
-
const chain = resolveChain(requested)
|
|
83
|
-
|
|
84
|
-
let driver: KvDriver | undefined
|
|
85
|
-
for (const id of chain) {
|
|
86
|
-
try {
|
|
87
|
-
const candidate = await createDriver(id, opts.dir)
|
|
88
|
-
if (!candidate) {
|
|
89
|
-
logger.warn(`KV 驱动 ${id} 不可用(未安装或未注册),尝试下一个`)
|
|
90
|
-
continue
|
|
91
|
-
}
|
|
92
|
-
await candidate.open()
|
|
93
|
-
driver = candidate
|
|
94
|
-
if (id !== requested && requested !== "auto") {
|
|
95
|
-
logger.warn(`配置指定的 KV 驱动 ${requested} 不可用,已降级为 ${id}`)
|
|
96
|
-
}
|
|
97
|
-
break
|
|
98
|
-
} catch (err) {
|
|
99
|
-
logger.warn(`KV 驱动 ${id} 打开失败,尝试下一个`, err)
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (!driver) {
|
|
104
|
-
// chain 末尾恒为 memory,理论上到不了这里;留着是为了让失败可诊断而不是空指针
|
|
105
|
-
throw new Error("所有 KV 驱动均不可用")
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
logger.info(`KV 存储就绪:驱动 ${driver.id}`)
|
|
109
|
-
const root = new Kv(driver)
|
|
110
|
-
|
|
111
|
-
return {
|
|
112
|
-
driver: driver.id,
|
|
113
|
-
root,
|
|
114
|
-
namespace: (name: string) => root.sub(name),
|
|
115
|
-
close: async () => {
|
|
116
|
-
await driver.close()
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* 把请求的驱动 id 展开成降级链
|
|
123
|
-
* @param requested 请求的驱动 id
|
|
124
|
-
* @returns 依次尝试的驱动 id 列表,末尾恒为 memory
|
|
125
|
-
*/
|
|
126
|
-
function resolveChain(requested: string): string[] {
|
|
127
|
-
if (requested === "auto") return ["level", "json", "memory"]
|
|
128
|
-
if (requested === "memory") return ["memory"]
|
|
129
|
-
if (requested === "json") return ["json", "memory"]
|
|
130
|
-
if (requested === "level") return ["level", "json", "memory"]
|
|
131
|
-
// 外部驱动(redis 等)失败后退回内置默认链
|
|
132
|
-
return [requested, "level", "json", "memory"]
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* 按 id 造驱动
|
|
137
|
-
* @param id 驱动 id
|
|
138
|
-
* @param dir 数据目录
|
|
139
|
-
* @returns 驱动实例;不可用时 undefined
|
|
140
|
-
*/
|
|
141
|
-
async function createDriver(id: string, dir: string): Promise<KvDriver | undefined> {
|
|
142
|
-
switch (id) {
|
|
143
|
-
case "memory":
|
|
144
|
-
return new MemoryKvDriver()
|
|
145
|
-
case "json":
|
|
146
|
-
return new JsonKvDriver(join(dir, "kv.json"))
|
|
147
|
-
case "level": {
|
|
148
|
-
const ctor = await loadLevel()
|
|
149
|
-
return ctor ? new LevelKvDriver(join(dir, "kv"), ctor) : undefined
|
|
150
|
-
}
|
|
151
|
-
default: {
|
|
152
|
-
const factory = externalDrivers.get(id)
|
|
153
|
-
return factory ? await factory(dir) : undefined
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 模块职责:KV 存储的装配(驱动选择、自动降级、根命名空间)
|
|
3
|
+
* 依赖方向:依赖 store/{kv,memory,json,level}、util/fs、类型包
|
|
4
|
+
* 生命周期:应用级单例,`close()` 时落盘
|
|
5
|
+
* 注意事项:**存储不可用不等于机器人不可用。** `auto` 模式按 level → json → memory 逐级降级,
|
|
6
|
+
* 每次降级记一条 warn 说明原因;最坏退到纯内存(重启丢缓存),但机器人始终能收发消息。
|
|
7
|
+
*
|
|
8
|
+
* 外部注册的驱动(如 store-redis 插件)通过 `registerKvDriver()` 挂进来,
|
|
9
|
+
* 与内置驱动一视同仁 —— 这正是"一切皆可为插件"在存储层的落点。
|
|
10
|
+
*/
|
|
11
|
+
import { join } from "node:path"
|
|
12
|
+
import type { KvDriver, KvNamespace, Logger } from "@yunzai-ng/types"
|
|
13
|
+
import { Kv } from "./kv.js"
|
|
14
|
+
import { MemoryKvDriver } from "./memory.js"
|
|
15
|
+
import { JsonKvDriver } from "./json.js"
|
|
16
|
+
import { LevelKvDriver, loadLevel } from "./level.js"
|
|
17
|
+
|
|
18
|
+
/** 内置驱动 id */
|
|
19
|
+
export type BuiltinDriverId = "auto" | "level" | "json" | "memory"
|
|
20
|
+
|
|
21
|
+
/** 驱动工厂:拿到数据目录,产出一个尚未 open 的驱动 */
|
|
22
|
+
export type KvDriverFactory = (dir: string) => Promise<KvDriver> | KvDriver
|
|
23
|
+
|
|
24
|
+
/** 外部注册的驱动表(插件注册的驱动进这里) */
|
|
25
|
+
const externalDrivers = new Map<string, KvDriverFactory>()
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 注册一个 KV 驱动
|
|
29
|
+
*
|
|
30
|
+
* 供 `store-redis` 这类插件调用;配置里把 `store.driver` 写成同一个 id 即可启用。
|
|
31
|
+
* @param id 驱动 id
|
|
32
|
+
* @param factory 驱动工厂
|
|
33
|
+
* @returns 取消注册
|
|
34
|
+
* @throws id 与内置驱动冲突时
|
|
35
|
+
*/
|
|
36
|
+
export function registerKvDriver(id: string, factory: KvDriverFactory): () => void {
|
|
37
|
+
if (id === "auto" || id === "level" || id === "json" || id === "memory") {
|
|
38
|
+
throw new Error(`驱动 id ${id} 与内置驱动冲突`)
|
|
39
|
+
}
|
|
40
|
+
externalDrivers.set(id, factory)
|
|
41
|
+
return () => void externalDrivers.delete(id)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** 打开 KV 存储的参数 */
|
|
45
|
+
export interface OpenKvOptions {
|
|
46
|
+
/** 数据目录(KV 数据会放在其子目录里) */
|
|
47
|
+
dir: string
|
|
48
|
+
/** 驱动 id,缺省 `auto` */
|
|
49
|
+
driver?: string
|
|
50
|
+
/** 日志器 */
|
|
51
|
+
logger: Logger
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** 已打开的 KV 存储 */
|
|
55
|
+
export interface KvStore {
|
|
56
|
+
/** 实际生效的驱动 id(`auto` 会被解析为具体驱动) */
|
|
57
|
+
readonly driver: string
|
|
58
|
+
/** 根命名空间 */
|
|
59
|
+
readonly root: KvNamespace
|
|
60
|
+
/**
|
|
61
|
+
* 取一个子命名空间
|
|
62
|
+
* @param name 命名空间名
|
|
63
|
+
* @returns KV 视图
|
|
64
|
+
*/
|
|
65
|
+
namespace(name: string): KvNamespace
|
|
66
|
+
/** 关闭并落盘 */
|
|
67
|
+
close(): Promise<void>
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 打开 KV 存储
|
|
72
|
+
*
|
|
73
|
+
* `auto` 的降级顺序:level(性能最优)→ json(纯 JS,Termux 兜底)→ memory。
|
|
74
|
+
* 显式指定驱动时同样会降级,但会将"所指定的驱动为何不可用"记为 warn,
|
|
75
|
+
* 而非静默替换 —— 使用者配置了 redis 却运行于内存驱动之上而不知情是最糟的情形。
|
|
76
|
+
* @param opts 参数
|
|
77
|
+
* @returns 已打开的 KV 存储
|
|
78
|
+
*/
|
|
79
|
+
export async function openKv(opts: OpenKvOptions): Promise<KvStore> {
|
|
80
|
+
const logger = opts.logger.child({ scope: "store" })
|
|
81
|
+
const requested = opts.driver ?? "auto"
|
|
82
|
+
const chain = resolveChain(requested)
|
|
83
|
+
|
|
84
|
+
let driver: KvDriver | undefined
|
|
85
|
+
for (const id of chain) {
|
|
86
|
+
try {
|
|
87
|
+
const candidate = await createDriver(id, opts.dir)
|
|
88
|
+
if (!candidate) {
|
|
89
|
+
logger.warn(`KV 驱动 ${id} 不可用(未安装或未注册),尝试下一个`)
|
|
90
|
+
continue
|
|
91
|
+
}
|
|
92
|
+
await candidate.open()
|
|
93
|
+
driver = candidate
|
|
94
|
+
if (id !== requested && requested !== "auto") {
|
|
95
|
+
logger.warn(`配置指定的 KV 驱动 ${requested} 不可用,已降级为 ${id}`)
|
|
96
|
+
}
|
|
97
|
+
break
|
|
98
|
+
} catch (err) {
|
|
99
|
+
logger.warn(`KV 驱动 ${id} 打开失败,尝试下一个`, err)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (!driver) {
|
|
104
|
+
// chain 末尾恒为 memory,理论上到不了这里;留着是为了让失败可诊断而不是空指针
|
|
105
|
+
throw new Error("所有 KV 驱动均不可用")
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
logger.info(`KV 存储就绪:驱动 ${driver.id}`)
|
|
109
|
+
const root = new Kv(driver)
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
driver: driver.id,
|
|
113
|
+
root,
|
|
114
|
+
namespace: (name: string) => root.sub(name),
|
|
115
|
+
close: async () => {
|
|
116
|
+
await driver.close()
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* 把请求的驱动 id 展开成降级链
|
|
123
|
+
* @param requested 请求的驱动 id
|
|
124
|
+
* @returns 依次尝试的驱动 id 列表,末尾恒为 memory
|
|
125
|
+
*/
|
|
126
|
+
function resolveChain(requested: string): string[] {
|
|
127
|
+
if (requested === "auto") return ["level", "json", "memory"]
|
|
128
|
+
if (requested === "memory") return ["memory"]
|
|
129
|
+
if (requested === "json") return ["json", "memory"]
|
|
130
|
+
if (requested === "level") return ["level", "json", "memory"]
|
|
131
|
+
// 外部驱动(redis 等)失败后退回内置默认链
|
|
132
|
+
return [requested, "level", "json", "memory"]
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* 按 id 造驱动
|
|
137
|
+
* @param id 驱动 id
|
|
138
|
+
* @param dir 数据目录
|
|
139
|
+
* @returns 驱动实例;不可用时 undefined
|
|
140
|
+
*/
|
|
141
|
+
async function createDriver(id: string, dir: string): Promise<KvDriver | undefined> {
|
|
142
|
+
switch (id) {
|
|
143
|
+
case "memory":
|
|
144
|
+
return new MemoryKvDriver()
|
|
145
|
+
case "json":
|
|
146
|
+
return new JsonKvDriver(join(dir, "kv.json"))
|
|
147
|
+
case "level": {
|
|
148
|
+
const ctor = await loadLevel()
|
|
149
|
+
return ctor ? new LevelKvDriver(join(dir, "kv"), ctor) : undefined
|
|
150
|
+
}
|
|
151
|
+
default: {
|
|
152
|
+
const factory = externalDrivers.get(id)
|
|
153
|
+
return factory ? await factory(dir) : undefined
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|