@zhin.js/plugin-repeater 1.1.7 → 1.1.9

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 CHANGED
@@ -5,22 +5,23 @@
5
5
  ## 安装
6
6
 
7
7
  ```bash
8
- npm install @zhin.js/plugin-repeater
8
+ pnpm exec zhin install @zhin.js/plugin-repeater
9
9
  ```
10
10
 
11
11
  ## 配置
12
12
 
13
- 在 `zhin.config.yml` 中添加:
13
+ 在应用目录运行安装命令,会安装依赖并挂载到 `package.json#zhin.plugins`,实例名为 `repeater`。在 `zhin.config.yml` 的实例节点修改配置:
14
14
 
15
15
  ```yaml
16
16
  plugins:
17
- - "@zhin.js/plugin-repeater"
18
- repeater:
19
- threshold: 3 # 触发复读的最少人数(默认 3)
20
- cooldown: 30000 # 同一群冷却时间,毫秒(默认 30s)
21
- maxLength: 200 # 消息长度上限,超过不触发(默认 200)
17
+ repeater:
18
+ threshold: 3 # 触发复读的最少人数(默认 3)
19
+ cooldown: 30000 # 同一群冷却时间,毫秒(默认 30s)
20
+ maxLength: 200 # 消息长度上限,超过不触发(默认 200)
22
21
  ```
23
22
 
23
+ 配置声明位于 `src/config.ts`,由 `plugin.ts` 暴露给 Runtime 与 Console;默认值、类型、范围和表单说明由同一声明生成。配置不满足范围或含未知字段时,候选代不会激活;有效配置更新只重载插件。
24
+
24
25
  ## 工作原理
25
26
 
26
27
  1. 监听群聊消息,记录每条消息的内容和发送者
@@ -1,10 +1,10 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  import { defineCommand } from 'zhin.js/command';
3
- import { resolveRepeaterConfig, } from "../../lib/engine.js";
3
+ import {} from "../../lib/engine.js";
4
4
  import { repeaterEngineToken } from "../../lib/runtime.js";
5
5
  export default defineCommand({
6
6
  description: '查看复读机的运行状态',
7
7
  execute({ config, use }) {
8
- return use(repeaterEngineToken).statusLines(resolveRepeaterConfig(config));
8
+ return use(repeaterEngineToken).statusLines(config);
9
9
  },
10
10
  });
@@ -1,6 +1,5 @@
1
1
  import { defineCommand } from 'zhin.js/command';
2
2
  import {
3
- resolveRepeaterConfig,
4
3
  type RepeaterConfig,
5
4
  } from '../../src/engine.js';
6
5
  import { repeaterEngineToken } from '../../src/runtime.js';
@@ -8,6 +7,6 @@ import { repeaterEngineToken } from '../../src/runtime.js';
8
7
  export default defineCommand<RepeaterConfig>({
9
8
  description: '查看复读机的运行状态',
10
9
  execute({ config, use }) {
11
- return use(repeaterEngineToken).statusLines(resolveRepeaterConfig(config));
10
+ return use(repeaterEngineToken).statusLines(config);
12
11
  },
13
12
  });
@@ -0,0 +1,18 @@
1
+ import { Schema } from 'zhin.js';
2
+ export declare const DEFAULT_REPEATER_CONFIG: Readonly<{
3
+ threshold: 3;
4
+ cooldown: 30000;
5
+ maxLength: 200;
6
+ }>;
7
+ /** Runtime validation, inferred types and Console forms share this declaration. */
8
+ export declare const repeaterConfig: Schema<Schema.InputRecord<{
9
+ threshold: Schema<number, number> & Schema.Present;
10
+ cooldown: Schema<number, number> & Schema.Present;
11
+ maxLength: Schema<number, number> & Schema.Present;
12
+ }>, {
13
+ threshold: number;
14
+ cooldown: number;
15
+ maxLength: number;
16
+ } & {}>;
17
+ export type RepeaterConfig = Schema.Output<typeof repeaterConfig>;
18
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,eAAO,MAAM,uBAAuB;;;;EAIlC,CAAC;AAEH,mFAAmF;AACnF,eAAO,MAAM,cAAc;;;;;;;;OAIzB,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC"}
package/lib/config.js ADDED
@@ -0,0 +1,13 @@
1
+ import { Schema } from 'zhin.js';
2
+ export const DEFAULT_REPEATER_CONFIG = Object.freeze({
3
+ threshold: 3,
4
+ cooldown: 30_000,
5
+ maxLength: 200,
6
+ });
7
+ /** Runtime validation, inferred types and Console forms share this declaration. */
8
+ export const repeaterConfig = Schema.object({
9
+ threshold: Schema.number().min(2).max(10).step(1).default(DEFAULT_REPEATER_CONFIG.threshold).description('触发复读的最少人数').effect('reload'),
10
+ cooldown: Schema.number().min(5_000).max(300_000).default(DEFAULT_REPEATER_CONFIG.cooldown).description('同一群冷却时间 (ms)').effect('reload'),
11
+ maxLength: Schema.number().min(10).max(1_000).step(1).default(DEFAULT_REPEATER_CONFIG.maxLength).description('消息长度上限').effect('reload'),
12
+ });
13
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,CAAC;IACnD,SAAS,EAAE,CAAC;IACZ,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,GAAG;CACf,CAAC,CAAC;AAEH,mFAAmF;AACnF,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IACtI,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IACxI,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;CACxI,CAAC,CAAC"}
package/lib/engine.d.ts CHANGED
@@ -1,10 +1,6 @@
1
- export interface RepeaterConfig {
2
- readonly threshold: number;
3
- readonly cooldown: number;
4
- readonly maxLength: number;
5
- }
6
- export declare const DEFAULT_REPEATER_CONFIG: RepeaterConfig;
7
- export declare function resolveRepeaterConfig(raw: unknown): RepeaterConfig;
1
+ import type { RepeaterConfig } from './config.js';
2
+ export { DEFAULT_REPEATER_CONFIG } from './config.js';
3
+ export type { RepeaterConfig } from './config.js';
8
4
  export interface RepeaterInboundFields {
9
5
  readonly conversation: {
10
6
  readonly kind: 'private' | 'group' | 'channel';
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,uBAAuB,EAAE,cAIpC,CAAC;AAEH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAMlE;AAOD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,YAAY,EAAE;QACrB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;QAC/C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC3E,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAY5E;AASD,MAAM,MAAM,kBAAkB,GAC1B;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5D,qBAAa,cAAc;;;IAezB,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,CAAC,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,cAAc,GAAG,kBAAkB;IAuChF,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM;IAW3C,UAAU,CAAC,GAAG,SAAa,EAAE,MAAM,SAAa,EAAE,QAAQ,SAAqB,GAAG,IAAI;IAStF,OAAO,IAAI,IAAI;CAMhB"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,YAAY,EAAE;QACrB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;QAC/C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC3E,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAY5E;AASD,MAAM,MAAM,kBAAkB,GAC1B;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5D,qBAAa,cAAc;;;IAezB,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,CAAC,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,cAAc,GAAG,kBAAkB;IAuChF,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM;IAW3C,UAAU,CAAC,GAAG,SAAa,EAAE,MAAM,SAAa,EAAE,QAAQ,SAAqB,GAAG,IAAI;IAStF,OAAO,IAAI,IAAI;CAMhB"}
package/lib/engine.js CHANGED
@@ -1,19 +1,5 @@
1
- export const DEFAULT_REPEATER_CONFIG = Object.freeze({
2
- threshold: 3,
3
- cooldown: 30_000,
4
- maxLength: 200,
5
- });
6
- export function resolveRepeaterConfig(raw) {
7
- const input = raw && typeof raw === 'object' ? raw : {};
8
- const threshold = clampNumber(input.threshold, DEFAULT_REPEATER_CONFIG.threshold, 2, 10);
9
- const cooldown = clampNumber(input.cooldown, DEFAULT_REPEATER_CONFIG.cooldown, 5_000, 300_000);
10
- const maxLength = clampNumber(input.maxLength, DEFAULT_REPEATER_CONFIG.maxLength, 10, 1_000);
11
- return Object.freeze({ threshold, cooldown, maxLength });
12
- }
13
- function clampNumber(value, fallback, min, max) {
14
- const n = typeof value === 'number' && Number.isFinite(value) ? value : fallback;
15
- return Math.min(max, Math.max(min, Math.trunc(n)));
16
- }
1
+ import { DEFAULT_REPEATER_CONFIG } from './config.js';
2
+ export { DEFAULT_REPEATER_CONFIG } from './config.js';
17
3
  /**
18
4
  * Best-effort group detection for Plugin Runtime `Message`.
19
5
  * Channel type comes from `conversation.kind`(metadata.type/channelType 优先,
package/lib/engine.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export { DEFAULT_REPEATER_CONFIG, RepeaterEngine, resolveGroupId, resolveRepeaterConfig, } from './engine.js';
1
+ export { DEFAULT_REPEATER_CONFIG, RepeaterEngine, resolveGroupId, } from './engine.js';
2
2
  export type { RepeaterConfig, RepeaterInboundFields, RepeaterTickResult } from './engine.js';
3
3
  export { repeaterEngineToken } from './runtime.js';
4
+ export { repeaterConfig } from './config.js';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,cAAc,EACd,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
package/lib/index.js CHANGED
@@ -1,3 +1,4 @@
1
- export { DEFAULT_REPEATER_CONFIG, RepeaterEngine, resolveGroupId, resolveRepeaterConfig, } from './engine.js';
1
+ export { DEFAULT_REPEATER_CONFIG, RepeaterEngine, resolveGroupId, } from './engine.js';
2
2
  export { repeaterEngineToken } from './runtime.js';
3
+ export { repeaterConfig } from './config.js';
3
4
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,cAAc,EACd,qBAAqB,GACtB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
@@ -1,6 +1,6 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  import { defineMiddleware } from 'zhin.js/middleware';
3
- import { resolveRepeaterConfig, } from "../../lib/engine.js";
3
+ import {} from "../../lib/engine.js";
4
4
  import { repeaterEngineToken } from "../../lib/runtime.js";
5
5
  /**
6
6
  * Runtime `Message` 是 conversation 原生:`conversation.kind/id` 直接喂给引擎
@@ -11,7 +11,7 @@ import { repeaterEngineToken } from "../../lib/runtime.js";
11
11
  export default defineMiddleware({
12
12
  target: 'inbound',
13
13
  async handle(context, next) {
14
- const config = resolveRepeaterConfig(context.config);
14
+ const config = context.config;
15
15
  const engine = context.use(repeaterEngineToken);
16
16
  const result = engine.tick({
17
17
  conversation: {
@@ -1,7 +1,6 @@
1
1
  import { defineMiddleware } from 'zhin.js/middleware';
2
2
  import type { Message } from '@zhin.js/core/runtime';
3
3
  import {
4
- resolveRepeaterConfig,
5
4
  type RepeaterConfig,
6
5
  } from '../../src/engine.js';
7
6
  import { repeaterEngineToken } from '../../src/runtime.js';
@@ -15,7 +14,7 @@ import { repeaterEngineToken } from '../../src/runtime.js';
15
14
  export default defineMiddleware<Message, RepeaterConfig>({
16
15
  target: 'inbound',
17
16
  async handle(context, next) {
18
- const config = resolveRepeaterConfig(context.config);
17
+ const config = context.config;
19
18
  const engine = context.use(repeaterEngineToken);
20
19
  const result = engine.tick({
21
20
  conversation: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/plugin-repeater",
3
- "version": "1.1.7",
3
+ "version": "1.1.9",
4
4
  "description": "Repeater plugin for Zhin.js — auto-repeat when group members echo the same content (Plugin Runtime)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -8,14 +8,12 @@
8
8
  "exports": {
9
9
  ".": {
10
10
  "types": "./lib/index.d.ts",
11
- "development": "./src/index.ts",
12
11
  "import": "./lib/index.js"
13
12
  },
14
13
  "./package.json": "./package.json"
15
14
  },
16
15
  "files": [
17
16
  "plugin.js",
18
- "schema.json",
19
17
  "commands",
20
18
  "middlewares",
21
19
  "src",
@@ -41,13 +39,13 @@
41
39
  },
42
40
  "license": "MIT",
43
41
  "dependencies": {
44
- "@zhin.js/core": "1.1.42",
45
- "@zhin.js/skill": "1.1.4"
42
+ "@zhin.js/core": "1.1.44",
43
+ "@zhin.js/skill": "1.1.6"
46
44
  },
47
45
  "devDependencies": {
48
46
  "typescript": "^6.0.3",
49
47
  "vitest": "^4.1.10",
50
- "zhin.js": "1.1.7"
48
+ "zhin.js": "1.1.9"
51
49
  },
52
50
  "repository": {
53
51
  "type": "git",
@@ -59,7 +57,7 @@
59
57
  "registry": "https://registry.npmjs.org"
60
58
  },
61
59
  "engines": {
62
- "node": "^20.19.0 || >=22.12.0"
60
+ "node": ">=22.19.0"
63
61
  },
64
62
  "zhin": {
65
63
  "protocol": 1,
@@ -84,9 +82,9 @@
84
82
  "plugins": []
85
83
  },
86
84
  "peerDependencies": {
87
- "@zhin.js/command": "^1.1.5",
88
- "@zhin.js/middleware": "^1.1.4",
89
- "zhin.js": "^1.1.7"
85
+ "@zhin.js/command": "^1.1.7",
86
+ "@zhin.js/middleware": "^1.1.6",
87
+ "zhin.js": "^1.1.9"
90
88
  },
91
89
  "peerDependenciesMeta": {
92
90
  "@zhin.js/command": {
package/plugin.js CHANGED
@@ -2,8 +2,10 @@
2
2
  import { definePlugin } from 'zhin.js';
3
3
  import { RepeaterEngine } from "./lib/engine.js";
4
4
  import { repeaterEngineToken } from "./lib/runtime.js";
5
+ import { repeaterConfig } from "./lib/config.js";
5
6
  export default definePlugin({
6
7
  name: 'repeater',
8
+ config: repeaterConfig,
7
9
  metadata: {
8
10
  displayName: 'Repeater',
9
11
  },
package/src/config.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { Schema } from 'zhin.js';
2
+
3
+ export const DEFAULT_REPEATER_CONFIG = Object.freeze({
4
+ threshold: 3,
5
+ cooldown: 30_000,
6
+ maxLength: 200,
7
+ });
8
+
9
+ /** Runtime validation, inferred types and Console forms share this declaration. */
10
+ export const repeaterConfig = Schema.object({
11
+ threshold: Schema.number().min(2).max(10).step(1).default(DEFAULT_REPEATER_CONFIG.threshold).description('触发复读的最少人数').effect('reload'),
12
+ cooldown: Schema.number().min(5_000).max(300_000).default(DEFAULT_REPEATER_CONFIG.cooldown).description('同一群冷却时间 (ms)').effect('reload'),
13
+ maxLength: Schema.number().min(10).max(1_000).step(1).default(DEFAULT_REPEATER_CONFIG.maxLength).description('消息长度上限').effect('reload'),
14
+ });
15
+
16
+ export type RepeaterConfig = Schema.Output<typeof repeaterConfig>;
package/src/engine.ts CHANGED
@@ -1,27 +1,7 @@
1
- export interface RepeaterConfig {
2
- readonly threshold: number;
3
- readonly cooldown: number;
4
- readonly maxLength: number;
5
- }
6
-
7
- export const DEFAULT_REPEATER_CONFIG: RepeaterConfig = Object.freeze({
8
- threshold: 3,
9
- cooldown: 30_000,
10
- maxLength: 200,
11
- });
12
-
13
- export function resolveRepeaterConfig(raw: unknown): RepeaterConfig {
14
- const input = raw && typeof raw === 'object' ? raw as Record<string, unknown> : {};
15
- const threshold = clampNumber(input.threshold, DEFAULT_REPEATER_CONFIG.threshold, 2, 10);
16
- const cooldown = clampNumber(input.cooldown, DEFAULT_REPEATER_CONFIG.cooldown, 5_000, 300_000);
17
- const maxLength = clampNumber(input.maxLength, DEFAULT_REPEATER_CONFIG.maxLength, 10, 1_000);
18
- return Object.freeze({ threshold, cooldown, maxLength });
19
- }
20
-
21
- function clampNumber(value: unknown, fallback: number, min: number, max: number): number {
22
- const n = typeof value === 'number' && Number.isFinite(value) ? value : fallback;
23
- return Math.min(max, Math.max(min, Math.trunc(n)));
24
- }
1
+ import { DEFAULT_REPEATER_CONFIG } from './config.js';
2
+ import type { RepeaterConfig } from './config.js';
3
+ export { DEFAULT_REPEATER_CONFIG } from './config.js';
4
+ export type { RepeaterConfig } from './config.js';
25
5
 
26
6
  export interface RepeaterInboundFields {
27
7
  readonly conversation: {
@@ -69,7 +49,7 @@ export class RepeaterEngine {
69
49
  #totalRepeats = 0;
70
50
  #cleanupTimer?: ReturnType<typeof setInterval>;
71
51
  /** 最近一次 tick 的配置冷却,供 pruneStale 用实际配置而非默认值清理。 */
72
- #lastCooldown = DEFAULT_REPEATER_CONFIG.cooldown;
52
+ #lastCooldown: number = DEFAULT_REPEATER_CONFIG.cooldown;
73
53
 
74
54
  constructor() {
75
55
  this.#cleanupTimer = setInterval(() => this.pruneStale(), 120_000);
package/src/index.ts CHANGED
@@ -2,7 +2,7 @@ export {
2
2
  DEFAULT_REPEATER_CONFIG,
3
3
  RepeaterEngine,
4
4
  resolveGroupId,
5
- resolveRepeaterConfig,
6
5
  } from './engine.js';
7
6
  export type { RepeaterConfig, RepeaterInboundFields, RepeaterTickResult } from './engine.js';
8
7
  export { repeaterEngineToken } from './runtime.js';
8
+ export { repeaterConfig } from './config.js';
package/schema.json DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "type": "object",
4
- "additionalProperties": false,
5
- "properties": {
6
- "threshold": {
7
- "type": "number",
8
- "default": 3,
9
- "minimum": 2,
10
- "maximum": 10,
11
- "description": "触发复读的最少人数"
12
- },
13
- "cooldown": {
14
- "type": "number",
15
- "default": 30000,
16
- "minimum": 5000,
17
- "maximum": 300000,
18
- "description": "同一群冷却时间 (ms)"
19
- },
20
- "maxLength": {
21
- "type": "number",
22
- "default": 200,
23
- "minimum": 10,
24
- "maximum": 1000,
25
- "description": "消息长度上限"
26
- }
27
- }
28
- }