@ryantest/openclaw-qqbot 1.6.7-beta.5 → 1.6.7-beta.7

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.
@@ -14,23 +14,42 @@ import { getPackageVersion } from "./utils/pkg-version.js";
14
14
  // Re-export 供外部模块使用(gateway.ts / startup-greeting.ts 等)
15
15
  export { getFrameworkVersion, parseFrameworkDateVersion } from "./upgrade-utils.js";
16
16
  let PLUGIN_VERSION = getPackageVersion(import.meta.url);
17
- // ============ 指令注册表 ============
18
- const commands = new Map();
17
+ // ============ 指令注册表(延迟初始化避免循环依赖 TDZ) ============
18
+ let commands = null;
19
+ function getCommandsMap() {
20
+ if (!commands)
21
+ commands = new Map();
22
+ return commands;
23
+ }
24
+ /** 待注册的指令队列(在循环依赖模块 import 时暂存) */
25
+ const pendingRegistrations = [];
19
26
  export function registerCommand(cmd) {
20
- commands.set(cmd.name.toLowerCase(), cmd);
27
+ if (commands) {
28
+ commands.set(cmd.name.toLowerCase(), cmd);
29
+ }
30
+ else {
31
+ pendingRegistrations.push(cmd);
32
+ }
21
33
  }
22
34
  /** 获取指令注册表(只读访问,供 bot-help 等使用) */
23
35
  export function getCommands() {
24
- return commands;
36
+ return getCommandsMap();
25
37
  }
26
38
  // ============ 注册所有内置指令 ============
27
39
  // 通过 side-effect import 触发各指令模块的 registerCommand 调用
40
+ // 此时 commands 可能还未初始化(循环依赖),指令暂存到 pendingRegistrations
28
41
  import "./commands/bot-ping.js";
29
42
  import "./commands/bot-version.js";
30
43
  import "./commands/bot-help.js";
31
44
  import "./commands/bot-upgrade.js";
32
45
  import "./commands/bot-logs.js";
33
46
  import "./commands/bot-clear-storage.js";
47
+ // flush 待注册队列
48
+ getCommandsMap();
49
+ for (const cmd of pendingRegistrations) {
50
+ commands.set(cmd.name.toLowerCase(), cmd);
51
+ }
52
+ pendingRegistrations.length = 0;
34
53
  // ============ 匹配入口 ============
35
54
  /**
36
55
  * 尝试匹配并执行插件级斜杠指令
@@ -45,7 +64,7 @@ export async function matchSlashCommand(ctx) {
45
64
  const spaceIdx = content.indexOf(" ");
46
65
  const cmdName = (spaceIdx === -1 ? content.slice(1) : content.slice(1, spaceIdx)).toLowerCase();
47
66
  const args = spaceIdx === -1 ? "" : content.slice(spaceIdx + 1).trim();
48
- const cmd = commands.get(cmdName);
67
+ const cmd = getCommandsMap().get(cmdName);
49
68
  if (!cmd)
50
69
  return null; // 不是插件级指令,交给框架
51
70
  // /指令 ? — 返回用法说明
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryantest/openclaw-qqbot",
3
- "version": "1.6.7-beta.5",
3
+ "version": "1.6.7-beta.7",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -87,22 +87,35 @@ export interface SlashCommand {
87
87
  handler: (ctx: SlashCommandContext) => SlashCommandResult | Promise<SlashCommandResult>;
88
88
  }
89
89
 
90
- // ============ 指令注册表 ============
90
+ // ============ 指令注册表(延迟初始化避免循环依赖 TDZ) ============
91
91
 
92
- const commands: Map<string, SlashCommand> = new Map();
92
+ let commands: Map<string, SlashCommand> | null = null;
93
+
94
+ function getCommandsMap(): Map<string, SlashCommand> {
95
+ if (!commands) commands = new Map();
96
+ return commands;
97
+ }
98
+
99
+ /** 待注册的指令队列(在循环依赖模块 import 时暂存) */
100
+ const pendingRegistrations: SlashCommand[] = [];
93
101
 
94
102
  export function registerCommand(cmd: SlashCommand): void {
95
- commands.set(cmd.name.toLowerCase(), cmd);
103
+ if (commands) {
104
+ commands.set(cmd.name.toLowerCase(), cmd);
105
+ } else {
106
+ pendingRegistrations.push(cmd);
107
+ }
96
108
  }
97
109
 
98
110
  /** 获取指令注册表(只读访问,供 bot-help 等使用) */
99
111
  export function getCommands(): ReadonlyMap<string, SlashCommand> {
100
- return commands;
112
+ return getCommandsMap();
101
113
  }
102
114
 
103
115
  // ============ 注册所有内置指令 ============
104
116
 
105
117
  // 通过 side-effect import 触发各指令模块的 registerCommand 调用
118
+ // 此时 commands 可能还未初始化(循环依赖),指令暂存到 pendingRegistrations
106
119
  import "./commands/bot-ping.js";
107
120
  import "./commands/bot-version.js";
108
121
  import "./commands/bot-help.js";
@@ -110,6 +123,13 @@ import "./commands/bot-upgrade.js";
110
123
  import "./commands/bot-logs.js";
111
124
  import "./commands/bot-clear-storage.js";
112
125
 
126
+ // flush 待注册队列
127
+ getCommandsMap();
128
+ for (const cmd of pendingRegistrations) {
129
+ commands!.set(cmd.name.toLowerCase(), cmd);
130
+ }
131
+ pendingRegistrations.length = 0;
132
+
113
133
  // ============ 匹配入口 ============
114
134
 
115
135
  /**
@@ -126,7 +146,7 @@ export async function matchSlashCommand(ctx: SlashCommandContext): Promise<Slash
126
146
  const cmdName = (spaceIdx === -1 ? content.slice(1) : content.slice(1, spaceIdx)).toLowerCase();
127
147
  const args = spaceIdx === -1 ? "" : content.slice(spaceIdx + 1).trim();
128
148
 
129
- const cmd = commands.get(cmdName);
149
+ const cmd = getCommandsMap().get(cmdName);
130
150
  if (!cmd) return null; // 不是插件级指令,交给框架
131
151
 
132
152
  // /指令 ? — 返回用法说明