hyper-scheduler 1.0.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.
Files changed (76) hide show
  1. package/.editorconfig +21 -0
  2. package/.eslintrc.cjs +26 -0
  3. package/GEMINI.md +1 -0
  4. package/README.md +38 -0
  5. package/docs/.vitepress/config.ts +52 -0
  6. package/docs/README.md +120 -0
  7. package/docs/api/devtools.md +232 -0
  8. package/docs/api/index.md +178 -0
  9. package/docs/api/scheduler.md +322 -0
  10. package/docs/api/task.md +439 -0
  11. package/docs/api/types.md +365 -0
  12. package/docs/examples/index.md +295 -0
  13. package/docs/guide/best-practices.md +436 -0
  14. package/docs/guide/core-concepts.md +363 -0
  15. package/docs/guide/getting-started.md +138 -0
  16. package/docs/index.md +33 -0
  17. package/docs/public/logo.svg +54 -0
  18. package/examples/browser/index.html +354 -0
  19. package/examples/node/simple.js +36 -0
  20. package/examples/react-demo/index.html +12 -0
  21. package/examples/react-demo/package.json +23 -0
  22. package/examples/react-demo/src/App.css +212 -0
  23. package/examples/react-demo/src/App.jsx +160 -0
  24. package/examples/react-demo/src/main.jsx +9 -0
  25. package/examples/react-demo/vite.config.ts +12 -0
  26. package/examples/react-demo/yarn.lock +752 -0
  27. package/examples/vue-demo/index.html +12 -0
  28. package/examples/vue-demo/package.json +21 -0
  29. package/examples/vue-demo/src/App.vue +373 -0
  30. package/examples/vue-demo/src/main.ts +4 -0
  31. package/examples/vue-demo/vite.config.ts +13 -0
  32. package/examples/vue-demo/yarn.lock +375 -0
  33. package/package.json +51 -0
  34. package/src/constants.ts +18 -0
  35. package/src/core/retry-strategy.ts +28 -0
  36. package/src/core/scheduler.ts +601 -0
  37. package/src/core/task-registry.ts +58 -0
  38. package/src/index.ts +74 -0
  39. package/src/platform/browser/browser-timer.ts +66 -0
  40. package/src/platform/browser/main-thread-timer.ts +16 -0
  41. package/src/platform/browser/worker.ts +31 -0
  42. package/src/platform/node/debug-cli.ts +19 -0
  43. package/src/platform/node/node-timer.ts +15 -0
  44. package/src/platform/timer-strategy.ts +19 -0
  45. package/src/plugins/dev-tools.ts +101 -0
  46. package/src/types.ts +115 -0
  47. package/src/ui/components/devtools.ts +525 -0
  48. package/src/ui/components/floating-trigger.ts +102 -0
  49. package/src/ui/components/icons.ts +16 -0
  50. package/src/ui/components/resizer.ts +129 -0
  51. package/src/ui/components/task-detail.ts +228 -0
  52. package/src/ui/components/task-header.ts +319 -0
  53. package/src/ui/components/task-list.ts +416 -0
  54. package/src/ui/components/timeline.ts +364 -0
  55. package/src/ui/debug-panel.ts +56 -0
  56. package/src/ui/i18n/en.ts +76 -0
  57. package/src/ui/i18n/index.ts +42 -0
  58. package/src/ui/i18n/zh.ts +76 -0
  59. package/src/ui/store/dev-tools-store.ts +191 -0
  60. package/src/ui/styles/theme.css.ts +56 -0
  61. package/src/ui/styles.ts +43 -0
  62. package/src/utils/cron-lite.ts +221 -0
  63. package/src/utils/cron.ts +20 -0
  64. package/src/utils/id.ts +10 -0
  65. package/src/utils/schedule.ts +93 -0
  66. package/src/vite-env.d.ts +1 -0
  67. package/stats.html +4949 -0
  68. package/tests/integration/Debug.test.ts +58 -0
  69. package/tests/unit/Plugin.test.ts +16 -0
  70. package/tests/unit/RetryStrategy.test.ts +21 -0
  71. package/tests/unit/Scheduler.test.ts +38 -0
  72. package/tests/unit/schedule.test.ts +70 -0
  73. package/tests/unit/ui/DevToolsStore.test.ts +67 -0
  74. package/tsconfig.json +28 -0
  75. package/vite.config.ts +51 -0
  76. package/vitest.config.ts +24 -0
@@ -0,0 +1,439 @@
1
+ # Task
2
+
3
+ 任务是调度器的基本执行单元,包含调度规则、执行逻辑和配置选项。
4
+
5
+ ## TaskDefinition
6
+
7
+ 任务定义接口,用于创建新任务。
8
+
9
+ ```typescript
10
+ interface TaskDefinition {
11
+ id: string;
12
+ schedule: string;
13
+ handler: () => void | Promise<void>;
14
+ tags?: string[];
15
+ options?: TaskOptions;
16
+ }
17
+ ```
18
+
19
+ ### 属性
20
+
21
+ #### id
22
+
23
+ - **类型**: `string`
24
+ - **必填**: ✓
25
+
26
+ 任务的唯一标识符,用于查询、触发、停止等操作。
27
+
28
+ ```typescript
29
+ scheduler.createTask({
30
+ id: 'daily-report',
31
+ // ...
32
+ });
33
+ ```
34
+
35
+ #### schedule
36
+
37
+ - **类型**: `string`
38
+ - **必填**: ✓
39
+
40
+ 任务的调度规则,支持两种格式:
41
+
42
+ **1. Cron 表达式**
43
+
44
+ 标准的 6 位 Cron 表达式:`秒 分 时 日 月 周`
45
+
46
+ ```typescript
47
+ // 每分钟执行
48
+ schedule: '0 * * * * *'
49
+
50
+ // 每 5 秒执行
51
+ schedule: '*/5 * * * * *'
52
+
53
+ // 每天凌晨 2:00 执行
54
+ schedule: '0 0 2 * * *'
55
+
56
+ // 每周一 9:00 执行
57
+ schedule: '0 0 9 * * 1'
58
+ ```
59
+
60
+ **2. 时间间隔**
61
+
62
+ 人性化的时间间隔字符串:
63
+
64
+ ```typescript
65
+ // 每 30 秒
66
+ schedule: '30s'
67
+
68
+ // 每 5 分钟
69
+ schedule: '5m'
70
+
71
+ // 每 2 小时
72
+ schedule: '2h'
73
+
74
+ // 每天
75
+ schedule: '1d'
76
+ ```
77
+
78
+ #### handler
79
+
80
+ - **类型**: `() => void | Promise<void>`
81
+ - **必填**: ✓
82
+
83
+ 任务执行函数,支持同步和异步。
84
+
85
+ ```typescript
86
+ // 同步函数
87
+ handler: () => {
88
+ console.log('Task executed');
89
+ }
90
+
91
+ // 异步函数
92
+ handler: async () => {
93
+ const data = await fetchData();
94
+ await processData(data);
95
+ }
96
+ ```
97
+
98
+ #### tags
99
+
100
+ - **类型**: `string[]`
101
+ - **可选**
102
+
103
+ 任务标签,用于分类和过滤。
104
+
105
+ ```typescript
106
+ scheduler.createTask({
107
+ id: 'sync-orders',
108
+ schedule: '1m',
109
+ tags: ['sync', 'orders', 'critical'],
110
+ handler: async () => {
111
+ await syncOrders();
112
+ }
113
+ });
114
+ ```
115
+
116
+ #### options
117
+
118
+ - **类型**: `TaskOptions`
119
+ - **可选**
120
+
121
+ 任务配置选项,详见 [TaskOptions](#taskoptions)。
122
+
123
+ ## TaskOptions
124
+
125
+ 任务配置选项接口。
126
+
127
+ ```typescript
128
+ interface TaskOptions {
129
+ retry?: RetryConfig;
130
+ timezone?: string;
131
+ driver?: 'main' | 'worker';
132
+ onError?: (error: Error, taskId: string) => void;
133
+ }
134
+ ```
135
+
136
+ ### retry
137
+
138
+ - **类型**: `RetryConfig`
139
+ - **可选**
140
+
141
+ 任务失败时的重试配置。
142
+
143
+ ```typescript
144
+ interface RetryConfig {
145
+ maxAttempts: number; // 最大重试次数
146
+ initialDelay: number; // 首次重试延迟(毫秒)
147
+ factor?: number; // 延迟递增因子,默认 2
148
+ }
149
+ ```
150
+
151
+ 重试延迟计算公式:`initialDelay * (factor ^ attempt)`
152
+
153
+ #### 示例
154
+
155
+ ```typescript
156
+ scheduler.createTask({
157
+ id: 'api-call',
158
+ schedule: '1m',
159
+ handler: async () => {
160
+ await callAPI();
161
+ },
162
+ options: {
163
+ retry: {
164
+ maxAttempts: 3,
165
+ initialDelay: 1000,
166
+ factor: 2
167
+ }
168
+ }
169
+ });
170
+
171
+ // 重试延迟序列:
172
+ // 第 1 次重试:1000ms (1s)
173
+ // 第 2 次重试:2000ms (2s)
174
+ // 第 3 次重试:4000ms (4s)
175
+ ```
176
+
177
+ ### timezone
178
+
179
+ - **类型**: `string`
180
+ - **可选**
181
+
182
+ 任务专属时区,覆盖全局时区设置。使用 IANA 时区标识符。
183
+
184
+ #### 示例
185
+
186
+ ```typescript
187
+ scheduler.createTask({
188
+ id: 'tokyo-report',
189
+ schedule: '0 0 9 * * *', // 每天 9:00
190
+ handler: () => generateReport(),
191
+ options: {
192
+ timezone: 'Asia/Tokyo'
193
+ }
194
+ });
195
+
196
+ scheduler.createTask({
197
+ id: 'ny-report',
198
+ schedule: '0 0 9 * * *', // 每天 9:00
199
+ handler: () => generateReport(),
200
+ options: {
201
+ timezone: 'America/New_York'
202
+ }
203
+ });
204
+ ```
205
+
206
+ ### driver
207
+
208
+ - **类型**: `'main' | 'worker'`
209
+ - **默认值**: `'worker'`
210
+ - **可选**
211
+
212
+ 指定任务的运行环境(驱动模式)。
213
+
214
+ | 模式 | 说明 | 适用场景 |
215
+ |------|------|----------|
216
+ | `'worker'` | 任务在 Web Worker 线程中运行计时器 | 繁重计算、高频任务、不想阻塞 UI |
217
+ | `'main'` | 任务在主线程中运行 (setInterval/setTimeout) | 需要访问 DOM 或 window 对象、简单的 UI 更新 |
218
+
219
+ #### 示例
220
+
221
+ ```typescript
222
+ // 在 Worker 中运行(默认)
223
+ scheduler.createTask({
224
+ id: 'heavy-calc',
225
+ schedule: '5s',
226
+ handler: () => heavyComputation(),
227
+ options: {
228
+ driver: 'worker'
229
+ }
230
+ });
231
+
232
+ // 在主线程中运行
233
+ scheduler.createTask({
234
+ id: 'ui-update',
235
+ schedule: '1s',
236
+ handler: () => updateClockUI(),
237
+ options: {
238
+ driver: 'main'
239
+ }
240
+ });
241
+ ```
242
+
243
+ ### onError
244
+
245
+ - **类型**: `(error: Error, taskId: string) => void`
246
+ - **可选**
247
+
248
+ 任务执行失败时的错误处理回调函数。
249
+
250
+ #### 示例
251
+
252
+ ```typescript
253
+ scheduler.createTask({
254
+ id: 'critical-task',
255
+ schedule: '30s',
256
+ handler: async () => {
257
+ await criticalOperation();
258
+ },
259
+ options: {
260
+ onError: (error, taskId) => {
261
+ // 记录错误日志
262
+ logger.error(`Task ${taskId} failed:`, error);
263
+
264
+ // 发送告警通知
265
+ alertService.send({
266
+ title: 'Task Failed',
267
+ message: error.message,
268
+ taskId
269
+ });
270
+ }
271
+ }
272
+ });
273
+ ```
274
+
275
+ ## Task
276
+
277
+ 任务运行时对象,继承自 `TaskDefinition` 并包含运行时状态。
278
+
279
+ ```typescript
280
+ interface Task extends TaskDefinition {
281
+ status: TaskStatus;
282
+ lastRun?: number;
283
+ nextRun?: number;
284
+ executionCount?: number;
285
+ history: ExecutionRecord[];
286
+ }
287
+ ```
288
+
289
+ ### 属性
290
+
291
+ #### status
292
+
293
+ - **类型**: `TaskStatus`
294
+
295
+ 任务当前状态。
296
+
297
+ ```typescript
298
+ type TaskStatus = 'idle' | 'running' | 'stopped' | 'error';
299
+ ```
300
+
301
+ | 状态 | 说明 |
302
+ |------|------|
303
+ | `idle` | 等待调度,将在下次触发时间执行 |
304
+ | `running` | 正在执行 |
305
+ | `stopped` | 已停止,不参与调度 |
306
+ | `error` | 执行出错 |
307
+
308
+ #### lastRun
309
+
310
+ - **类型**: `number | undefined`
311
+
312
+ 上次执行时间戳(毫秒)。
313
+
314
+ ```typescript
315
+ const task = scheduler.getTask('my-task');
316
+ if (task.lastRun) {
317
+ console.log('Last run:', new Date(task.lastRun));
318
+ }
319
+ ```
320
+
321
+ #### nextRun
322
+
323
+ - **类型**: `number | undefined`
324
+
325
+ 下次执行时间戳(毫秒)。
326
+
327
+ ```typescript
328
+ const task = scheduler.getTask('my-task');
329
+ if (task.nextRun) {
330
+ console.log('Next run:', new Date(task.nextRun));
331
+ console.log('Time until next run:', task.nextRun - Date.now(), 'ms');
332
+ }
333
+ ```
334
+
335
+ #### executionCount
336
+
337
+ - **类型**: `number | undefined`
338
+
339
+ 任务累计执行次数。
340
+
341
+ ```typescript
342
+ const task = scheduler.getTask('my-task');
343
+ console.log(`Executed ${task.executionCount} times`);
344
+ ```
345
+
346
+ #### history
347
+
348
+ - **类型**: `ExecutionRecord[]`
349
+
350
+ 任务执行历史记录数组,最多保留 `maxHistory` 条(默认 50)。
351
+
352
+ ```typescript
353
+ interface ExecutionRecord {
354
+ timestamp: number; // 执行时间戳
355
+ duration: number; // 执行耗时(毫秒)
356
+ success: boolean; // 是否成功
357
+ error?: string; // 错误信息(失败时)
358
+ }
359
+ ```
360
+
361
+ #### 示例
362
+
363
+ ```typescript
364
+ const task = scheduler.getTask('my-task');
365
+
366
+ // 查看最近 5 次执行
367
+ task.history.slice(-5).forEach(record => {
368
+ const time = new Date(record.timestamp).toLocaleString();
369
+ const status = record.success ? '✓' : '✗';
370
+ console.log(`${status} ${time} - ${record.duration}ms`);
371
+ if (record.error) {
372
+ console.log(` Error: ${record.error}`);
373
+ }
374
+ });
375
+
376
+ // 计算成功率
377
+ const successCount = task.history.filter(r => r.success).length;
378
+ const successRate = (successCount / task.history.length * 100).toFixed(2);
379
+ console.log(`Success rate: ${successRate}%`);
380
+
381
+ // 计算平均执行时间
382
+ const avgDuration = task.history.reduce((sum, r) => sum + r.duration, 0) / task.history.length;
383
+ console.log(`Average duration: ${avgDuration.toFixed(2)}ms`);
384
+ ```
385
+
386
+ ## 完整示例
387
+
388
+ ```typescript
389
+ import { Scheduler } from 'hyper-scheduler';
390
+
391
+ const scheduler = new Scheduler({
392
+ debug: true,
393
+ maxHistory: 100
394
+ });
395
+
396
+ // 创建带完整配置的任务
397
+ scheduler.createTask({
398
+ id: 'data-sync',
399
+ schedule: '*/30 * * * * *', // 每 30 秒
400
+ tags: ['sync', 'data', 'high-priority'],
401
+ handler: async () => {
402
+ const data = await fetchRemoteData();
403
+ await saveToDatabase(data);
404
+ },
405
+ options: {
406
+ timezone: 'Asia/Shanghai',
407
+ retry: {
408
+ maxAttempts: 3,
409
+ initialDelay: 1000,
410
+ factor: 2
411
+ },
412
+ onError: (error, taskId) => {
413
+ console.error(`[${taskId}] Error:`, error.message);
414
+ // 发送告警
415
+ sendAlert({
416
+ taskId,
417
+ error: error.message,
418
+ timestamp: Date.now()
419
+ });
420
+ }
421
+ }
422
+ });
423
+
424
+ scheduler.start();
425
+
426
+ // 查询任务状态
427
+ setTimeout(() => {
428
+ const task = scheduler.getTask('data-sync');
429
+ console.log('Task status:', task.status);
430
+ console.log('Execution count:', task.executionCount);
431
+ console.log('Last 3 executions:', task.history.slice(-3));
432
+ }, 60000);
433
+ ```
434
+
435
+ ## 相关链接
436
+
437
+ - [Scheduler API](./scheduler.md) - 调度器 API
438
+ - [核心概念](../guide/core-concepts.md) - 任务状态流转
439
+ - [类型定义](./types.md) - 完整类型定义