56 lines
2.7 KiB
TypeScript
56 lines
2.7 KiB
TypeScript
import type {Json} from '../../../types/bot/workflow/workflow.ts';
|
|
import type {WorkflowStartTemplate} from '../../../types/bot/workflow/metadata.ts';
|
|
import {describe, output} from '../metadata.ts';
|
|
|
|
export const config_template: WorkflowStartTemplate = {
|
|
name: 'timer', version: '1.0.0',
|
|
i18n: describe('定时启动', '机器人出生并就绪后,按指定毫秒间隔启动工作流。'),
|
|
config: [
|
|
{name: 'auto_start', type: 'boolean', required: false, default: true,
|
|
i18n: describe('自动定时', '机器人连接并出生后自动启动定时器。')},
|
|
{name: 'mode', type: 'select', required: false, default: 'repeat',
|
|
i18n: describe('定时模式', '执行一次或按间隔重复执行。'), options: [
|
|
{value: 'once', i18n: describe('一次', '一次启动被接受后停止。')},
|
|
{value: 'repeat', i18n: describe('重复', '按间隔持续尝试启动。')},
|
|
]},
|
|
{name: 'max_runs', type: 'number', nullable: true, required: false, default: null,
|
|
integer: true, min: 1, max: 100000,
|
|
i18n: describe('最大启动次数', '仅计入已启动或排队的请求;null 表示无限次。')},
|
|
{
|
|
name: 'interval_ms', type: 'number', required: true, integer: true,
|
|
min: 10, max: 2_147_483_647, default: 1000,
|
|
i18n: describe('间隔毫秒', '定时触发的间隔,必须是至少 10 毫秒的安全整数。'),
|
|
}],
|
|
output: {
|
|
...output('object', '定时数据', '每次定时触发时生成的事件名称和时间戳。'),
|
|
properties: {
|
|
event: output('string', '事件名称', '固定为 timer。'),
|
|
timestamp: output('number', '触发时间', '触发时的 Unix 时间戳,单位为毫秒。'),
|
|
},
|
|
},
|
|
};
|
|
|
|
export function schedule_timer_start(interval_ms: number,
|
|
start: (trigger: Record<string, Json>) => void): () => void {
|
|
if (!Number.isSafeInteger(interval_ms) || interval_ms < 10 || interval_ms > 2_147_483_647) {
|
|
throw new Error('Invalid workflow timer interval');
|
|
}
|
|
const timer = setTimeout(() => start({event: 'timer', timestamp: Date.now()}), interval_ms);
|
|
timer.unref?.();
|
|
return () => clearTimeout(timer);
|
|
}
|
|
|
|
export function register_timer_start(interval_ms: number,
|
|
start: (trigger: Record<string, Json>) => void): () => void {
|
|
let disposed = false;
|
|
let cancel: () => void;
|
|
const schedule = () => {
|
|
cancel = schedule_timer_start(interval_ms, trigger => {
|
|
try { start(trigger); }
|
|
finally { if (!disposed) schedule(); }
|
|
});
|
|
};
|
|
schedule();
|
|
return () => { disposed = true; cancel(); };
|
|
}
|