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.
- package/.editorconfig +21 -0
- package/.eslintrc.cjs +26 -0
- package/GEMINI.md +1 -0
- package/README.md +38 -0
- package/docs/.vitepress/config.ts +52 -0
- package/docs/README.md +120 -0
- package/docs/api/devtools.md +232 -0
- package/docs/api/index.md +178 -0
- package/docs/api/scheduler.md +322 -0
- package/docs/api/task.md +439 -0
- package/docs/api/types.md +365 -0
- package/docs/examples/index.md +295 -0
- package/docs/guide/best-practices.md +436 -0
- package/docs/guide/core-concepts.md +363 -0
- package/docs/guide/getting-started.md +138 -0
- package/docs/index.md +33 -0
- package/docs/public/logo.svg +54 -0
- package/examples/browser/index.html +354 -0
- package/examples/node/simple.js +36 -0
- package/examples/react-demo/index.html +12 -0
- package/examples/react-demo/package.json +23 -0
- package/examples/react-demo/src/App.css +212 -0
- package/examples/react-demo/src/App.jsx +160 -0
- package/examples/react-demo/src/main.jsx +9 -0
- package/examples/react-demo/vite.config.ts +12 -0
- package/examples/react-demo/yarn.lock +752 -0
- package/examples/vue-demo/index.html +12 -0
- package/examples/vue-demo/package.json +21 -0
- package/examples/vue-demo/src/App.vue +373 -0
- package/examples/vue-demo/src/main.ts +4 -0
- package/examples/vue-demo/vite.config.ts +13 -0
- package/examples/vue-demo/yarn.lock +375 -0
- package/package.json +51 -0
- package/src/constants.ts +18 -0
- package/src/core/retry-strategy.ts +28 -0
- package/src/core/scheduler.ts +601 -0
- package/src/core/task-registry.ts +58 -0
- package/src/index.ts +74 -0
- package/src/platform/browser/browser-timer.ts +66 -0
- package/src/platform/browser/main-thread-timer.ts +16 -0
- package/src/platform/browser/worker.ts +31 -0
- package/src/platform/node/debug-cli.ts +19 -0
- package/src/platform/node/node-timer.ts +15 -0
- package/src/platform/timer-strategy.ts +19 -0
- package/src/plugins/dev-tools.ts +101 -0
- package/src/types.ts +115 -0
- package/src/ui/components/devtools.ts +525 -0
- package/src/ui/components/floating-trigger.ts +102 -0
- package/src/ui/components/icons.ts +16 -0
- package/src/ui/components/resizer.ts +129 -0
- package/src/ui/components/task-detail.ts +228 -0
- package/src/ui/components/task-header.ts +319 -0
- package/src/ui/components/task-list.ts +416 -0
- package/src/ui/components/timeline.ts +364 -0
- package/src/ui/debug-panel.ts +56 -0
- package/src/ui/i18n/en.ts +76 -0
- package/src/ui/i18n/index.ts +42 -0
- package/src/ui/i18n/zh.ts +76 -0
- package/src/ui/store/dev-tools-store.ts +191 -0
- package/src/ui/styles/theme.css.ts +56 -0
- package/src/ui/styles.ts +43 -0
- package/src/utils/cron-lite.ts +221 -0
- package/src/utils/cron.ts +20 -0
- package/src/utils/id.ts +10 -0
- package/src/utils/schedule.ts +93 -0
- package/src/vite-env.d.ts +1 -0
- package/stats.html +4949 -0
- package/tests/integration/Debug.test.ts +58 -0
- package/tests/unit/Plugin.test.ts +16 -0
- package/tests/unit/RetryStrategy.test.ts +21 -0
- package/tests/unit/Scheduler.test.ts +38 -0
- package/tests/unit/schedule.test.ts +70 -0
- package/tests/unit/ui/DevToolsStore.test.ts +67 -0
- package/tsconfig.json +28 -0
- package/vite.config.ts +51 -0
- package/vitest.config.ts +24 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
# 类型定义
|
|
2
|
+
|
|
3
|
+
Hyper Scheduler 的完整 TypeScript 类型定义。
|
|
4
|
+
|
|
5
|
+
## 核心类型
|
|
6
|
+
|
|
7
|
+
### SchedulerConfig
|
|
8
|
+
|
|
9
|
+
调度器配置接口。
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
interface SchedulerConfig {
|
|
13
|
+
debug?: boolean;
|
|
14
|
+
maxHistory?: number;
|
|
15
|
+
timezone?: string;
|
|
16
|
+
plugins?: HyperSchedulerPlugin[];
|
|
17
|
+
driver?: 'worker' | 'main';
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
22
|
+
|------|------|--------|------|
|
|
23
|
+
| `debug` | `boolean` | `false` | 启用调试日志 |
|
|
24
|
+
| `maxHistory` | `number` | `50` | 每个任务保留的最大执行历史记录数 |
|
|
25
|
+
| `timezone` | `string` | 系统时区 | 全局时区设置,如 `'Asia/Shanghai'` |
|
|
26
|
+
| `plugins` | `HyperSchedulerPlugin[]` | `[]` | 插件实例数组 |
|
|
27
|
+
| `driver` | `'worker' \| 'main'` | `'worker'` | 定时器驱动方式(仅浏览器):`'worker'` 使用 Web Worker,`'main'` 使用主线程 |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
### TaskDefinition
|
|
32
|
+
|
|
33
|
+
任务定义接口,用于创建新任务。
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
interface TaskDefinition {
|
|
37
|
+
id: string;
|
|
38
|
+
schedule: string;
|
|
39
|
+
handler: () => void | Promise<void>;
|
|
40
|
+
tags?: string[];
|
|
41
|
+
options?: TaskOptions;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
| 属性 | 类型 | 必填 | 说明 |
|
|
46
|
+
|------|------|------|------|
|
|
47
|
+
| `id` | `string` | ✓ | 任务唯一标识符 |
|
|
48
|
+
| `schedule` | `string` | ✓ | 调度规则(Cron 表达式或时间间隔) |
|
|
49
|
+
| `handler` | `() => void \| Promise<void>` | ✓ | 任务执行函数 |
|
|
50
|
+
| `tags` | `string[]` | - | 任务标签 |
|
|
51
|
+
| `options` | `TaskOptions` | - | 任务选项 |
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
### TaskOptions
|
|
56
|
+
|
|
57
|
+
任务配置选项接口。
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
interface TaskOptions {
|
|
61
|
+
retry?: RetryConfig;
|
|
62
|
+
timezone?: string;
|
|
63
|
+
onError?: (error: Error, taskId: string) => void;
|
|
64
|
+
driver?: 'worker' | 'main';
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| 属性 | 类型 | 说明 |
|
|
69
|
+
|------|------|------|
|
|
70
|
+
| `retry` | `RetryConfig` | 重试配置 |
|
|
71
|
+
| `timezone` | `string` | 任务专属时区 |
|
|
72
|
+
| `onError` | `(error: Error, taskId: string) => void` | 错误处理回调 |
|
|
73
|
+
| `driver` | `'worker' \| 'main'` | 定时器驱动方式(仅浏览器),覆盖全局配置 |
|
|
74
|
+
|
|
75
|
+
#### RetryConfig
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
interface RetryConfig {
|
|
79
|
+
maxAttempts: number;
|
|
80
|
+
initialDelay: number;
|
|
81
|
+
factor?: number;
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
86
|
+
|------|------|--------|------|
|
|
87
|
+
| `maxAttempts` | `number` | - | 最大重试次数 |
|
|
88
|
+
| `initialDelay` | `number` | - | 首次重试延迟(毫秒) |
|
|
89
|
+
| `factor` | `number` | `2` | 延迟递增因子 |
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
### Task
|
|
94
|
+
|
|
95
|
+
任务运行时对象,继承自 `TaskDefinition`。
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
interface Task extends TaskDefinition {
|
|
99
|
+
status: TaskStatus;
|
|
100
|
+
lastRun?: number;
|
|
101
|
+
nextRun?: number;
|
|
102
|
+
executionCount?: number;
|
|
103
|
+
history: ExecutionRecord[];
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
| 属性 | 类型 | 说明 |
|
|
108
|
+
|------|------|------|
|
|
109
|
+
| `status` | `TaskStatus` | 任务状态 |
|
|
110
|
+
| `lastRun` | `number` | 上次执行时间戳(毫秒) |
|
|
111
|
+
| `nextRun` | `number` | 下次执行时间戳(毫秒) |
|
|
112
|
+
| `executionCount` | `number` | 累计执行次数 |
|
|
113
|
+
| `history` | `ExecutionRecord[]` | 执行历史记录 |
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
### TaskStatus
|
|
118
|
+
|
|
119
|
+
任务状态枚举。
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
type TaskStatus = 'idle' | 'running' | 'stopped' | 'error';
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
| 值 | 说明 |
|
|
126
|
+
|----|------|
|
|
127
|
+
| `idle` | 等待调度 |
|
|
128
|
+
| `running` | 正在执行 |
|
|
129
|
+
| `stopped` | 已停止 |
|
|
130
|
+
| `error` | 执行出错 |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
### ExecutionRecord
|
|
135
|
+
|
|
136
|
+
任务执行记录接口。
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
interface ExecutionRecord {
|
|
140
|
+
timestamp: number;
|
|
141
|
+
duration: number;
|
|
142
|
+
success: boolean;
|
|
143
|
+
error?: string;
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
| 属性 | 类型 | 说明 |
|
|
148
|
+
|------|------|------|
|
|
149
|
+
| `timestamp` | `number` | 执行时间戳(毫秒) |
|
|
150
|
+
| `duration` | `number` | 执行耗时(毫秒) |
|
|
151
|
+
| `success` | `boolean` | 是否成功 |
|
|
152
|
+
| `error` | `string` | 错误信息(失败时) |
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 插件类型
|
|
157
|
+
|
|
158
|
+
### HyperSchedulerPlugin
|
|
159
|
+
|
|
160
|
+
插件接口。
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
interface HyperSchedulerPlugin {
|
|
164
|
+
name: string;
|
|
165
|
+
init(scheduler: Scheduler, options?: any): void;
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
| 属性 | 类型 | 说明 |
|
|
170
|
+
|------|------|------|
|
|
171
|
+
| `name` | `string` | 插件名称 |
|
|
172
|
+
| `init` | `(scheduler: Scheduler, options?: any) => void` | 初始化方法 |
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
### DevToolsOptions
|
|
177
|
+
|
|
178
|
+
DevTools 插件配置接口。
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
interface DevToolsOptions {
|
|
182
|
+
theme?: 'light' | 'dark' | 'auto';
|
|
183
|
+
dockPosition?: 'right' | 'bottom';
|
|
184
|
+
language?: 'en' | 'zh';
|
|
185
|
+
defaultZoom?: number;
|
|
186
|
+
trigger?: TriggerOptions;
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
191
|
+
|------|------|--------|------|
|
|
192
|
+
| `theme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | 主题模式 |
|
|
193
|
+
| `dockPosition` | `'right' \| 'bottom'` | `'right'` | 面板停靠位置 |
|
|
194
|
+
| `language` | `'en' \| 'zh'` | `'en'` | 界面语言 |
|
|
195
|
+
| `defaultZoom` | `number` | `1` | 时间线默认缩放级别 (0.5-5) |
|
|
196
|
+
| `trigger` | `TriggerOptions` | - | 悬浮按钮配置 |
|
|
197
|
+
|
|
198
|
+
#### TriggerOptions
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
interface TriggerOptions {
|
|
202
|
+
backgroundColor?: string;
|
|
203
|
+
textColor?: string;
|
|
204
|
+
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
209
|
+
|------|------|--------|------|
|
|
210
|
+
| `backgroundColor` | `string` | `'#3b82f6'` | 背景色 |
|
|
211
|
+
| `textColor` | `string` | `'#ffffff'` | 文字/图标颜色 |
|
|
212
|
+
| `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | `'bottom-right'` | 位置 |
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## 内部类型
|
|
217
|
+
|
|
218
|
+
以下类型主要用于内部实现和高级用法。
|
|
219
|
+
|
|
220
|
+
### TaskSnapshot
|
|
221
|
+
|
|
222
|
+
任务快照接口,用于序列化和传输。
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
interface TaskSnapshot {
|
|
226
|
+
id: string;
|
|
227
|
+
status: string;
|
|
228
|
+
lastRun: number | null;
|
|
229
|
+
nextRun: number | null;
|
|
230
|
+
executionCount: number;
|
|
231
|
+
schedule: string;
|
|
232
|
+
tags: string[];
|
|
233
|
+
error: string | null;
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
### TaskControlAPI
|
|
240
|
+
|
|
241
|
+
任务控制 API 接口。
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
interface TaskControlAPI {
|
|
245
|
+
trigger(taskId: string): Promise<void>;
|
|
246
|
+
pause(taskId: string): void;
|
|
247
|
+
resume(taskId: string): void;
|
|
248
|
+
remove(taskId: string): void;
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
### SchedulerIntrospectionAPI
|
|
255
|
+
|
|
256
|
+
调度器内省 API 接口。
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
interface SchedulerIntrospectionAPI {
|
|
260
|
+
getTasks(): TaskSnapshot[];
|
|
261
|
+
on(event: string, handler: (data: any) => void): () => void;
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 类型导出
|
|
268
|
+
|
|
269
|
+
所有类型都可以从主包导出:
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
import type {
|
|
273
|
+
// 核心类型
|
|
274
|
+
SchedulerConfig,
|
|
275
|
+
TaskDefinition,
|
|
276
|
+
TaskOptions,
|
|
277
|
+
Task,
|
|
278
|
+
TaskStatus,
|
|
279
|
+
ExecutionRecord,
|
|
280
|
+
|
|
281
|
+
// 插件类型
|
|
282
|
+
HyperSchedulerPlugin,
|
|
283
|
+
DevToolsOptions,
|
|
284
|
+
|
|
285
|
+
// 内部类型
|
|
286
|
+
TaskSnapshot,
|
|
287
|
+
TaskControlAPI,
|
|
288
|
+
SchedulerIntrospectionAPI
|
|
289
|
+
} from 'hyper-scheduler';
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## 使用示例
|
|
293
|
+
|
|
294
|
+
### 类型安全的任务定义
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
import type { TaskDefinition, TaskOptions } from 'hyper-scheduler';
|
|
298
|
+
|
|
299
|
+
const taskOptions: TaskOptions = {
|
|
300
|
+
retry: {
|
|
301
|
+
maxAttempts: 3,
|
|
302
|
+
initialDelay: 1000,
|
|
303
|
+
factor: 2
|
|
304
|
+
},
|
|
305
|
+
timezone: 'Asia/Shanghai',
|
|
306
|
+
onError: (error, taskId) => {
|
|
307
|
+
console.error(`Task ${taskId} failed:`, error);
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
const taskDef: TaskDefinition = {
|
|
312
|
+
id: 'my-task',
|
|
313
|
+
schedule: '*/5 * * * * *',
|
|
314
|
+
handler: async () => {
|
|
315
|
+
await doSomething();
|
|
316
|
+
},
|
|
317
|
+
tags: ['sync', 'critical'],
|
|
318
|
+
options: taskOptions
|
|
319
|
+
};
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### 自定义插件
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
import type { HyperSchedulerPlugin, Scheduler } from 'hyper-scheduler';
|
|
326
|
+
|
|
327
|
+
class MyPlugin implements HyperSchedulerPlugin {
|
|
328
|
+
name = 'MyPlugin';
|
|
329
|
+
|
|
330
|
+
init(scheduler: Scheduler, options?: any): void {
|
|
331
|
+
scheduler.on('task_completed', ({ taskId, duration }) => {
|
|
332
|
+
console.log(`Task ${taskId} took ${duration}ms`);
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
const scheduler = new Scheduler({
|
|
338
|
+
plugins: [new MyPlugin()]
|
|
339
|
+
});
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### 类型守卫
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
import type { Task, TaskStatus } from 'hyper-scheduler';
|
|
346
|
+
|
|
347
|
+
function isRunning(task: Task): boolean {
|
|
348
|
+
return task.status === 'running';
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function hasError(task: Task): boolean {
|
|
352
|
+
return task.status === 'error';
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const task = scheduler.getTask('my-task');
|
|
356
|
+
if (task && isRunning(task)) {
|
|
357
|
+
console.log('Task is currently running');
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## 相关链接
|
|
362
|
+
|
|
363
|
+
- [Scheduler API](./scheduler.md) - 调度器 API
|
|
364
|
+
- [Task API](./task.md) - 任务 API
|
|
365
|
+
- [DevTools API](./devtools.md) - 调试工具 API
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# 示例演示:双线程心跳监控
|
|
2
|
+
|
|
3
|
+
本示例展示了 `Hyper Scheduler` 的核心能力:**双线程任务调度**。你可以同时在主线程(Main Thread)和 Web Worker 线程中运行任务,互不干扰。
|
|
4
|
+
|
|
5
|
+
## 安装与引入
|
|
6
|
+
|
|
7
|
+
### 1. 安装
|
|
8
|
+
|
|
9
|
+
使用你喜欢的包管理器安装 `hyper-scheduler`:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# npm
|
|
13
|
+
npm install hyper-scheduler
|
|
14
|
+
|
|
15
|
+
# yarn
|
|
16
|
+
yarn add hyper-scheduler
|
|
17
|
+
|
|
18
|
+
# pnpm
|
|
19
|
+
pnpm add hyper-scheduler
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 2. 引入
|
|
23
|
+
|
|
24
|
+
**ES Modules (React, Vue, Node.js ESM)**
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
import { Scheduler, DevTools } from 'hyper-scheduler';
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**CommonJS (Node.js CJS)**
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
const { Scheduler } = require('hyper-scheduler');
|
|
34
|
+
// 注意:DevTools 在纯 Node.js 环境下不可用
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**浏览器 (CDN)**
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<script src="https://unpkg.com/hyper-scheduler/dist/index.umd.js"></script>
|
|
41
|
+
<script>
|
|
42
|
+
const { Scheduler, DevTools } = window.HyperScheduler;
|
|
43
|
+
</script>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## 场景描述
|
|
47
|
+
|
|
48
|
+
我们模拟了一个简单的系统监控场景,包含两个独立的任务:
|
|
49
|
+
|
|
50
|
+
1. **🔴 主线程任务 (Main Thread)**:
|
|
51
|
+
* **频率**: 每 3 秒
|
|
52
|
+
* **用途**: 模拟必须访问 DOM 或 UI 的轻量级任务。
|
|
53
|
+
* **配置**: `options: { driver: 'main' }`
|
|
54
|
+
2. **🔵 Worker 任务 (Worker Thread)**:
|
|
55
|
+
* **频率**: 每 5 秒
|
|
56
|
+
* **用途**: 模拟繁重的数据处理、计算或网络请求,完全**不阻塞 UI**。
|
|
57
|
+
* **配置**: 默认行为 (或 `options: { driver: 'worker' }`)
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 完整代码示例
|
|
62
|
+
|
|
63
|
+
以下代码展示了如何在不同环境中实现上述场景,代码已包含完整的现代化 UI 逻辑。
|
|
64
|
+
|
|
65
|
+
::: tip 提示
|
|
66
|
+
点击下方选项卡切换查看不同环境的实现代码。
|
|
67
|
+
:::
|
|
68
|
+
|
|
69
|
+
::: code-group
|
|
70
|
+
|
|
71
|
+
```html [Browser (CDN)]
|
|
72
|
+
<!DOCTYPE html>
|
|
73
|
+
<html lang="zh-CN">
|
|
74
|
+
<head>
|
|
75
|
+
<!-- ...样式代码省略,请参考 React/Vue 示例中的 CSS ... -->
|
|
76
|
+
<style>
|
|
77
|
+
/* 核心布局与样式 */
|
|
78
|
+
:root { --bg-color: #f8fafc; /* ... */ }
|
|
79
|
+
.dashboard { display: grid; grid-template-columns: 300px 1fr; /* ... */ }
|
|
80
|
+
/* 按钮状态控制 */
|
|
81
|
+
#btn-stop { display: none; }
|
|
82
|
+
body.running #btn-start { display: none; }
|
|
83
|
+
body.running #btn-stop { display: block; }
|
|
84
|
+
</style>
|
|
85
|
+
</head>
|
|
86
|
+
<body>
|
|
87
|
+
<div class="dashboard">
|
|
88
|
+
<!-- ... HTML 结构 ... -->
|
|
89
|
+
<div class="actions">
|
|
90
|
+
<button class="btn-start" id="btn-start">▶ 启动调度器</button>
|
|
91
|
+
<button class="btn-stop" id="btn-stop">⏹ 停止调度器</button>
|
|
92
|
+
</div>
|
|
93
|
+
<!-- ... -->
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<script src="https://unpkg.com/hyper-scheduler/dist/index.umd.js"></script>
|
|
97
|
+
<script>
|
|
98
|
+
const { Scheduler, DevTools } = window.HyperScheduler;
|
|
99
|
+
|
|
100
|
+
// 1. 初始化调度器
|
|
101
|
+
const scheduler = new Scheduler({
|
|
102
|
+
debug: true,
|
|
103
|
+
plugins: [new DevTools({ theme: 'auto', language: 'zh' })]
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// 2. 注册主线程任务
|
|
107
|
+
scheduler.createTask({
|
|
108
|
+
id: 'main-heartbeat',
|
|
109
|
+
schedule: '3s',
|
|
110
|
+
options: { driver: 'main' },
|
|
111
|
+
handler: () => log('❤️ [Main] 主线程心跳检测正常', 'error')
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// 3. 注册 Worker 任务
|
|
115
|
+
scheduler.createTask({
|
|
116
|
+
id: 'worker-heartbeat',
|
|
117
|
+
schedule: '5s',
|
|
118
|
+
handler: () => log('💙 [Worker] 后台线程任务执行中', 'info')
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// 4. 按钮逻辑
|
|
122
|
+
document.getElementById('btn-start').onclick = () => {
|
|
123
|
+
scheduler.start();
|
|
124
|
+
document.body.classList.add('running');
|
|
125
|
+
log('🚀 调度器系统已启动', 'success');
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
document.getElementById('btn-stop').onclick = () => {
|
|
129
|
+
scheduler.stop();
|
|
130
|
+
document.body.classList.remove('running');
|
|
131
|
+
log('⏹️ 调度器系统已停止', 'info');
|
|
132
|
+
};
|
|
133
|
+
</script>
|
|
134
|
+
</body>
|
|
135
|
+
</html>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
```javascript [Node.js]
|
|
139
|
+
import { Scheduler } from 'hyper-scheduler';
|
|
140
|
+
|
|
141
|
+
// 1. Node 环境初始化
|
|
142
|
+
const scheduler = new Scheduler({ debug: true });
|
|
143
|
+
|
|
144
|
+
// 辅助函数:格式化时间
|
|
145
|
+
const time = () => new Date().toLocaleTimeString('zh-CN', { hour12: false });
|
|
146
|
+
|
|
147
|
+
console.log('✨ 系统就绪,等待启动指令...');
|
|
148
|
+
|
|
149
|
+
// 2. 主线程心跳
|
|
150
|
+
scheduler.createTask({
|
|
151
|
+
id: 'main-heartbeat',
|
|
152
|
+
schedule: '3s',
|
|
153
|
+
options: { driver: 'main' },
|
|
154
|
+
handler: () => {
|
|
155
|
+
console.log(`[${time()}] ❤️ [Main] 主线程心跳检测正常`);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// 3. Worker 线程心跳
|
|
160
|
+
scheduler.createTask({
|
|
161
|
+
id: 'worker-heartbeat',
|
|
162
|
+
schedule: '5s',
|
|
163
|
+
handler: () => {
|
|
164
|
+
console.log(`[${time()}] 💙 [Worker] 后台线程任务执行中`);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// 4. 启动
|
|
169
|
+
scheduler.start();
|
|
170
|
+
console.log(`[${time()}] 🚀 调度器已启动,按 Ctrl+C 退出`);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
```jsx [React]
|
|
174
|
+
import { useState, useEffect, useRef } from 'react';
|
|
175
|
+
import { Scheduler, DevTools } from 'hyper-scheduler';
|
|
176
|
+
import './App.css';
|
|
177
|
+
|
|
178
|
+
function App() {
|
|
179
|
+
const [logs, setLogs] = useState([]);
|
|
180
|
+
const [isRunning, setIsRunning] = useState(false);
|
|
181
|
+
const schedulerRef = useRef(null);
|
|
182
|
+
// ... 滚动条 ref 等 ...
|
|
183
|
+
|
|
184
|
+
useEffect(() => {
|
|
185
|
+
// 1. 初始化
|
|
186
|
+
schedulerRef.current = new Scheduler({
|
|
187
|
+
debug: true,
|
|
188
|
+
plugins: [new DevTools({ theme: 'auto', language: 'zh' })]
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// 2. 注册任务
|
|
192
|
+
schedulerRef.current.createTask({
|
|
193
|
+
id: 'main-heartbeat',
|
|
194
|
+
schedule: '3s',
|
|
195
|
+
options: { driver: 'main' },
|
|
196
|
+
handler: () => addLog('❤️ [Main] 主线程心跳检测正常', 'error')
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
schedulerRef.current.createTask({
|
|
200
|
+
id: 'worker-heartbeat',
|
|
201
|
+
schedule: '5s',
|
|
202
|
+
handler: () => addLog('💙 [Worker] 后台线程任务执行中', 'info')
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
return () => {
|
|
206
|
+
if (schedulerRef.current) schedulerRef.current.stop();
|
|
207
|
+
};
|
|
208
|
+
}, []);
|
|
209
|
+
|
|
210
|
+
// 3. 切换逻辑
|
|
211
|
+
const handleToggle = () => {
|
|
212
|
+
if (isRunning) {
|
|
213
|
+
schedulerRef.current.stop();
|
|
214
|
+
addLog('⏹️ 调度器系统已停止', 'info');
|
|
215
|
+
} else {
|
|
216
|
+
schedulerRef.current.start();
|
|
217
|
+
addLog('🚀 调度器系统已启动', 'success');
|
|
218
|
+
}
|
|
219
|
+
setIsRunning(!isRunning);
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
return (
|
|
223
|
+
<div className="dashboard">
|
|
224
|
+
{/* ... UI 结构 ... */}
|
|
225
|
+
<button
|
|
226
|
+
className={isRunning ? 'btn-stop' : 'btn-start'}
|
|
227
|
+
onClick={handleToggle}
|
|
228
|
+
>
|
|
229
|
+
{isRunning ? '⏹ 停止调度器' : '▶ 启动调度器'}
|
|
230
|
+
</button>
|
|
231
|
+
{/* ... */}
|
|
232
|
+
</div>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
```vue [Vue 3]
|
|
238
|
+
<script setup>
|
|
239
|
+
import { ref, onMounted, onUnmounted } from 'vue'
|
|
240
|
+
import { Scheduler, DevTools } from 'hyper-scheduler'
|
|
241
|
+
|
|
242
|
+
const scheduler = ref(null)
|
|
243
|
+
const isRunning = ref(false)
|
|
244
|
+
// ... 日志逻辑 ...
|
|
245
|
+
|
|
246
|
+
onMounted(() => {
|
|
247
|
+
// 1. 初始化
|
|
248
|
+
scheduler.value = new Scheduler({
|
|
249
|
+
debug: true,
|
|
250
|
+
plugins: [new DevTools({ theme: 'auto', language: 'zh' })]
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
// 2. 注册任务
|
|
254
|
+
scheduler.value.createTask({
|
|
255
|
+
id: 'main-heartbeat',
|
|
256
|
+
schedule: '3s',
|
|
257
|
+
options: { driver: 'main' },
|
|
258
|
+
handler: () => addLog('❤️ [Main] 主线程心跳检测正常', 'error')
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
scheduler.value.createTask({
|
|
262
|
+
id: 'worker-heartbeat',
|
|
263
|
+
schedule: '5s',
|
|
264
|
+
handler: () => addLog('💙 [Worker] 后台线程任务执行中', 'info')
|
|
265
|
+
})
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
// 3. 切换逻辑
|
|
269
|
+
const handleToggle = () => {
|
|
270
|
+
if (isRunning.value) {
|
|
271
|
+
scheduler.value.stop()
|
|
272
|
+
addLog('⏹️ 调度器系统已停止', 'info')
|
|
273
|
+
} else {
|
|
274
|
+
scheduler.value.start()
|
|
275
|
+
addLog('🚀 调度器系统已启动', 'success')
|
|
276
|
+
}
|
|
277
|
+
isRunning.value = !isRunning.value
|
|
278
|
+
}
|
|
279
|
+
</script>
|
|
280
|
+
|
|
281
|
+
<template>
|
|
282
|
+
<div class="dashboard">
|
|
283
|
+
<!-- ... UI 结构 ... -->
|
|
284
|
+
<button
|
|
285
|
+
:class="isRunning ? 'btn-stop' : 'btn-start'"
|
|
286
|
+
@click="handleToggle"
|
|
287
|
+
>
|
|
288
|
+
{{ isRunning ? '⏹ 停止调度器' : '▶ 启动调度器' }}
|
|
289
|
+
</button>
|
|
290
|
+
<!-- ... -->
|
|
291
|
+
</div>
|
|
292
|
+
</template>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
:::
|