hyper-scheduler 1.0.0 → 1.1.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 (86) hide show
  1. package/README.md +17 -0
  2. package/dist/devtools-Bxtz0rO_.cjs +1 -0
  3. package/dist/devtools-ByJU-Gv1.js +2505 -0
  4. package/dist/index.cjs +1 -0
  5. package/dist/index.js +1048 -0
  6. package/dist/index.umd.cjs +1 -0
  7. package/docs/.vitepress/cache/deps/_metadata.json +31 -0
  8. package/docs/.vitepress/cache/deps/chunk-EKBJ2FPM.js +12798 -0
  9. package/docs/.vitepress/cache/deps/chunk-EKBJ2FPM.js.map +7 -0
  10. package/docs/.vitepress/cache/deps/package.json +3 -0
  11. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +4505 -0
  12. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +7 -0
  13. package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +9731 -0
  14. package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +7 -0
  15. package/docs/.vitepress/cache/deps/vue.js +347 -0
  16. package/docs/.vitepress/cache/deps/vue.js.map +7 -0
  17. package/docs/.vitepress/config.ts +4 -0
  18. package/docs/.vitepress/theme/components/DemoFrame.vue +111 -0
  19. package/docs/.vitepress/theme/custom.css +6 -0
  20. package/docs/.vitepress/theme/index.ts +10 -0
  21. package/docs/api/devtools.md +13 -0
  22. package/docs/api/scheduler.md +28 -8
  23. package/docs/examples/index.md +55 -8
  24. package/docs/guide/getting-started.md +38 -0
  25. package/package.json +13 -4
  26. package/.editorconfig +0 -21
  27. package/.eslintrc.cjs +0 -26
  28. package/GEMINI.md +0 -1
  29. package/examples/browser/index.html +0 -354
  30. package/examples/node/simple.js +0 -36
  31. package/examples/react-demo/index.html +0 -12
  32. package/examples/react-demo/package.json +0 -23
  33. package/examples/react-demo/src/App.css +0 -212
  34. package/examples/react-demo/src/App.jsx +0 -160
  35. package/examples/react-demo/src/main.jsx +0 -9
  36. package/examples/react-demo/vite.config.ts +0 -12
  37. package/examples/react-demo/yarn.lock +0 -752
  38. package/examples/vue-demo/index.html +0 -12
  39. package/examples/vue-demo/package.json +0 -21
  40. package/examples/vue-demo/src/App.vue +0 -373
  41. package/examples/vue-demo/src/main.ts +0 -4
  42. package/examples/vue-demo/vite.config.ts +0 -13
  43. package/examples/vue-demo/yarn.lock +0 -375
  44. package/src/constants.ts +0 -18
  45. package/src/core/retry-strategy.ts +0 -28
  46. package/src/core/scheduler.ts +0 -601
  47. package/src/core/task-registry.ts +0 -58
  48. package/src/index.ts +0 -74
  49. package/src/platform/browser/browser-timer.ts +0 -66
  50. package/src/platform/browser/main-thread-timer.ts +0 -16
  51. package/src/platform/browser/worker.ts +0 -31
  52. package/src/platform/node/debug-cli.ts +0 -19
  53. package/src/platform/node/node-timer.ts +0 -15
  54. package/src/platform/timer-strategy.ts +0 -19
  55. package/src/plugins/dev-tools.ts +0 -101
  56. package/src/types.ts +0 -115
  57. package/src/ui/components/devtools.ts +0 -525
  58. package/src/ui/components/floating-trigger.ts +0 -102
  59. package/src/ui/components/icons.ts +0 -16
  60. package/src/ui/components/resizer.ts +0 -129
  61. package/src/ui/components/task-detail.ts +0 -228
  62. package/src/ui/components/task-header.ts +0 -319
  63. package/src/ui/components/task-list.ts +0 -416
  64. package/src/ui/components/timeline.ts +0 -364
  65. package/src/ui/debug-panel.ts +0 -56
  66. package/src/ui/i18n/en.ts +0 -76
  67. package/src/ui/i18n/index.ts +0 -42
  68. package/src/ui/i18n/zh.ts +0 -76
  69. package/src/ui/store/dev-tools-store.ts +0 -191
  70. package/src/ui/styles/theme.css.ts +0 -56
  71. package/src/ui/styles.ts +0 -43
  72. package/src/utils/cron-lite.ts +0 -221
  73. package/src/utils/cron.ts +0 -20
  74. package/src/utils/id.ts +0 -10
  75. package/src/utils/schedule.ts +0 -93
  76. package/src/vite-env.d.ts +0 -1
  77. package/stats.html +0 -4949
  78. package/tests/integration/Debug.test.ts +0 -58
  79. package/tests/unit/Plugin.test.ts +0 -16
  80. package/tests/unit/RetryStrategy.test.ts +0 -21
  81. package/tests/unit/Scheduler.test.ts +0 -38
  82. package/tests/unit/schedule.test.ts +0 -70
  83. package/tests/unit/ui/DevToolsStore.test.ts +0 -67
  84. package/tsconfig.json +0 -28
  85. package/vite.config.ts +0 -51
  86. package/vitest.config.ts +0 -24
@@ -2,6 +2,22 @@
2
2
 
3
3
  本示例展示了 `Hyper Scheduler` 的核心能力:**双线程任务调度**。你可以同时在主线程(Main Thread)和 Web Worker 线程中运行任务,互不干扰。
4
4
 
5
+ ## 在线演示
6
+
7
+ 以下示例展示了完全相同的“双线程心跳监控”逻辑在不同框架中的运行效果。你可以直接在这里交互,或点击右上角图标在新窗口打开。
8
+
9
+ ### Browser (原生 JS)
10
+
11
+ <DemoFrame path="/examples/browser/" :devPort="3003" devPath="/examples/browser/index.html" title="examples/browser/index.html" />
12
+
13
+ ### Vue 3 Demo
14
+
15
+ <DemoFrame path="/examples/vue-demo/" :devPort="3001" title="examples/vue-demo" />
16
+
17
+ ### React Demo
18
+
19
+ <DemoFrame path="/examples/react-demo/" :devPort="3002" title="examples/react-demo" />
20
+
5
21
  ## 安装与引入
6
22
 
7
23
  ### 1. 安装
@@ -9,12 +25,12 @@
9
25
  使用你喜欢的包管理器安装 `hyper-scheduler`:
10
26
 
11
27
  ```bash
28
+ # yarn (推荐)
29
+ yarn add hyper-scheduler
30
+
12
31
  # npm
13
32
  npm install hyper-scheduler
14
33
 
15
- # yarn
16
- yarn add hyper-scheduler
17
-
18
34
  # pnpm
19
35
  pnpm add hyper-scheduler
20
36
  ```
@@ -107,7 +123,11 @@ const { Scheduler } = require('hyper-scheduler');
107
123
  scheduler.createTask({
108
124
  id: 'main-heartbeat',
109
125
  schedule: '3s',
110
- options: { driver: 'main' },
126
+ options: {
127
+ driver: 'main',
128
+ namespace: 'ui',
129
+ runImmediately: true
130
+ },
111
131
  handler: () => log('❤️ [Main] 主线程心跳检测正常', 'error')
112
132
  });
113
133
 
@@ -115,6 +135,9 @@ const { Scheduler } = require('hyper-scheduler');
115
135
  scheduler.createTask({
116
136
  id: 'worker-heartbeat',
117
137
  schedule: '5s',
138
+ options: {
139
+ namespace: 'background'
140
+ },
118
141
  handler: () => log('💙 [Worker] 后台线程任务执行中', 'info')
119
142
  });
120
143
 
@@ -150,7 +173,11 @@ console.log('✨ 系统就绪,等待启动指令...');
150
173
  scheduler.createTask({
151
174
  id: 'main-heartbeat',
152
175
  schedule: '3s',
153
- options: { driver: 'main' },
176
+ options: {
177
+ driver: 'main',
178
+ namespace: 'ui',
179
+ runImmediately: true
180
+ },
154
181
  handler: () => {
155
182
  console.log(`[${time()}] ❤️ [Main] 主线程心跳检测正常`);
156
183
  }
@@ -160,6 +187,9 @@ scheduler.createTask({
160
187
  scheduler.createTask({
161
188
  id: 'worker-heartbeat',
162
189
  schedule: '5s',
190
+ options: {
191
+ namespace: 'background'
192
+ },
163
193
  handler: () => {
164
194
  console.log(`[${time()}] 💙 [Worker] 后台线程任务执行中`);
165
195
  }
@@ -189,16 +219,25 @@ function App() {
189
219
  });
190
220
 
191
221
  // 2. 注册任务
222
+ // 主线程心跳 (明确指定 driver: 'main')
192
223
  schedulerRef.current.createTask({
193
224
  id: 'main-heartbeat',
194
225
  schedule: '3s',
195
- options: { driver: 'main' },
226
+ options: {
227
+ driver: 'main',
228
+ namespace: 'ui',
229
+ runImmediately: true
230
+ },
196
231
  handler: () => addLog('❤️ [Main] 主线程心跳检测正常', 'error')
197
232
  });
198
233
 
234
+ // Worker 线程心跳 (默认即为 Worker 驱动)
199
235
  schedulerRef.current.createTask({
200
236
  id: 'worker-heartbeat',
201
237
  schedule: '5s',
238
+ options: {
239
+ namespace: 'background'
240
+ },
202
241
  handler: () => addLog('💙 [Worker] 后台线程任务执行中', 'info')
203
242
  });
204
243
 
@@ -250,17 +289,25 @@ onMounted(() => {
250
289
  plugins: [new DevTools({ theme: 'auto', language: 'zh' })]
251
290
  })
252
291
 
253
- // 2. 注册任务
292
+ // 主线程心跳 (明确指定 driver: 'main')
254
293
  scheduler.value.createTask({
255
294
  id: 'main-heartbeat',
256
295
  schedule: '3s',
257
- options: { driver: 'main' },
296
+ options: {
297
+ driver: 'main',
298
+ namespace: 'ui',
299
+ runImmediately: true
300
+ },
258
301
  handler: () => addLog('❤️ [Main] 主线程心跳检测正常', 'error')
259
302
  })
260
303
 
304
+ // Worker 线程心跳 (默认即为 Worker 驱动)
261
305
  scheduler.value.createTask({
262
306
  id: 'worker-heartbeat',
263
307
  schedule: '5s',
308
+ options: {
309
+ namespace: 'background'
310
+ },
264
311
  handler: () => addLog('💙 [Worker] 后台线程任务执行中', 'info')
265
312
  })
266
313
  })
@@ -78,6 +78,44 @@ scheduler.createTask({
78
78
  scheduler.start();
79
79
  ```
80
80
 
81
+ ## 进阶功能
82
+
83
+ ### 1. 使用命名空间
84
+
85
+ 可以将任务隔离到不同的命名空间中,以便进行批量管理(如启动、停止特定组的任务)。
86
+
87
+ ```typescript
88
+ scheduler.createTask({
89
+ id: 'system-log',
90
+ schedule: '1m',
91
+ handler: () => console.log('System Log'),
92
+ options: { namespace: 'system' }
93
+ });
94
+
95
+ scheduler.createTask({
96
+ id: 'user-notification',
97
+ schedule: '5m',
98
+ handler: () => console.log('User Notification'),
99
+ options: { namespace: 'user' }
100
+ });
101
+
102
+ // 仅启动 system 命名空间下的任务
103
+ scheduler.start('system');
104
+ ```
105
+
106
+ ### 2. 立即触发
107
+
108
+ 默认情况下,任务会在第一次调度时间到达时执行。如果你希望任务在调度器启动时(或创建时)立即执行一次,可以使用 `runImmediately` 选项。
109
+
110
+ ```typescript
111
+ scheduler.createTask({
112
+ id: 'init-check',
113
+ schedule: '1h',
114
+ handler: () => console.log('Checking status...'),
115
+ options: { runImmediately: true }
116
+ });
117
+ ```
118
+
81
119
  ## 浏览器环境
82
120
 
83
121
  在浏览器中可以启用可视化调试工具,通过在 Scheduler 构造函数中传入 DevTools 插件实现:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyper-scheduler",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "A lightweight, dependency-free (core) JavaScript task scheduler supporting Cron expressions and Web Workers.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.umd.js",
@@ -12,15 +12,23 @@
12
12
  "require": "./dist/index.cjs"
13
13
  }
14
14
  },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE",
19
+ "docs"
20
+ ],
15
21
  "scripts": {
16
22
  "dev": "vite",
17
23
  "docs:dev": "vitepress dev docs",
18
24
  "docs:build": "vitepress build docs",
19
25
  "example:node": "node examples/node/simple.js",
20
- "example:browser": "vite examples/browser",
21
- "example:vue": "npm install --prefix examples/vue-demo && npm run dev --prefix examples/vue-demo",
22
- "example:react": "npm install --prefix examples/react-demo && npm run dev --prefix examples/react-demo",
26
+ "example:browser": "vite serve . --port 3003",
27
+ "example:vue": "cd examples/vue-demo && yarn && yarn dev",
28
+ "example:react": "cd examples/react-demo && yarn && yarn dev",
29
+ "dev:all": "concurrently \"yarn docs:dev\" \"yarn example:vue\" \"yarn example:react\" \"vite examples/browser --port 3003\"",
23
30
  "build": "tsc && vite build",
31
+ "prepublishOnly": "yarn build",
24
32
  "test": "vitest",
25
33
  "lint": "eslint . --ext .ts"
26
34
  },
@@ -38,6 +46,7 @@
38
46
  "@typescript-eslint/eslint-plugin": "^8.48.0",
39
47
  "@typescript-eslint/parser": "^8.48.0",
40
48
  "@vitest/coverage-v8": "^4.0.14",
49
+ "concurrently": "^9.2.1",
41
50
  "eslint": "^8.0.0",
42
51
  "jsdom": "^27.2.0",
43
52
  "rollup-plugin-visualizer": "^6.0.5",
package/.editorconfig DELETED
@@ -1,21 +0,0 @@
1
- # EditorConfig is awesome: https://EditorConfig.org
2
-
3
- # top-most EditorConfig file
4
- root = true
5
-
6
- # Unix-style newlines with a newline ending every file
7
- [*]
8
- end_of_line = lf
9
- insert_final_newline = true
10
- charset = utf-8
11
-
12
- # TypeScript files
13
- [*.ts]
14
- indent_style = space
15
- indent_size = 2
16
- trim_trailing_whitespace = true
17
-
18
- # Disable auto-fix for critical UI components
19
- [src/ui/components/{Timeline,TaskList,DevTools}.ts]
20
- # These files have specific logic that should not be auto-fixed
21
- # Manual review required for any changes
package/.eslintrc.cjs DELETED
@@ -1,26 +0,0 @@
1
- module.exports = {
2
- root: true,
3
- env: {
4
- browser: true,
5
- es2021: true,
6
- node: true,
7
- },
8
- extends: [
9
- 'eslint:recommended',
10
- 'plugin:@typescript-eslint/recommended',
11
- ],
12
- parser: '@typescript-eslint/parser',
13
- parserOptions: {
14
- ecmaVersion: 12,
15
- sourceType: 'module',
16
- },
17
- plugins: [
18
- '@typescript-eslint',
19
- ],
20
- rules: {
21
- '@typescript-eslint/no-explicit-any': 'off',
22
- '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
23
- 'no-console': 'off',
24
- },
25
- ignorePatterns: ['dist/', 'coverage/', 'examples/'],
26
- };
package/GEMINI.md DELETED
@@ -1 +0,0 @@
1
- 全部采用中文作为主要语言进行输出,包括文档和注释
@@ -1,354 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="zh-CN">
3
-
4
- <head>
5
- <meta charset="UTF-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>Hyper Scheduler - 浏览器示例</title>
8
- <style>
9
- :root {
10
- --bg-color: #f8fafc;
11
- --card-bg: #ffffff;
12
- --text-primary: #1e293b;
13
- --text-secondary: #64748b;
14
- --accent-color: #3b82f6;
15
- --accent-hover: #2563eb;
16
- --danger-color: #ef4444;
17
- --danger-hover: #dc2626;
18
- --success-color: #10b981;
19
- --border-radius: 12px;
20
- --shadow-sm: 0 1px 3px rgba(0,0,0,0.1);
21
- --shadow-md: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -1px rgba(0,0,0,0.06);
22
- --font-mono: 'SFMono-Regular', Consolas, 'Lxgw WenKai', 'Liberation Mono', Menlo, monospace;
23
- }
24
-
25
- * {
26
- margin: 0;
27
- padding: 0;
28
- box-sizing: border-box;
29
- }
30
-
31
- body {
32
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
33
- background: var(--bg-color);
34
- color: var(--text-primary);
35
- height: 100vh;
36
- display: flex;
37
- align-items: center;
38
- justify-content: center;
39
- padding: 20px;
40
- }
41
-
42
- .dashboard {
43
- display: grid;
44
- grid-template-columns: 300px 1fr;
45
- gap: 24px;
46
- width: 100%;
47
- max-width: 1000px;
48
- height: 600px;
49
- background: var(--bg-color);
50
- }
51
-
52
- /* 左侧控制面板 */
53
- .control-panel {
54
- background: var(--card-bg);
55
- border-radius: var(--border-radius);
56
- padding: 24px;
57
- box-shadow: var(--shadow-md);
58
- display: flex;
59
- flex-direction: column;
60
- justify-content: space-between;
61
- }
62
-
63
- .header h1 {
64
- font-size: 24px;
65
- font-weight: 700;
66
- margin-bottom: 8px;
67
- background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
68
- -webkit-background-clip: text;
69
- -webkit-text-fill-color: transparent;
70
- }
71
-
72
- .header p {
73
- color: var(--text-secondary);
74
- font-size: 14px;
75
- margin-bottom: 24px;
76
- }
77
-
78
- .task-status {
79
- margin-bottom: auto;
80
- }
81
-
82
- .status-item {
83
- display: flex;
84
- align-items: center;
85
- padding: 12px;
86
- background: #f1f5f9;
87
- border-radius: 8px;
88
- margin-bottom: 12px;
89
- font-size: 14px;
90
- }
91
-
92
- .status-dot {
93
- width: 8px;
94
- height: 8px;
95
- border-radius: 50%;
96
- margin-right: 10px;
97
- }
98
-
99
- .dot-main { background: #ef4444; box-shadow: 0 0 8px rgba(239, 68, 68, 0.4); }
100
- .dot-worker { background: #3b82f6; box-shadow: 0 0 8px rgba(59, 130, 246, 0.4); }
101
-
102
- .actions {
103
- display: flex;
104
- flex-direction: column;
105
- gap: 12px;
106
- }
107
-
108
- /* 按钮状态控制 */
109
- #btn-stop { display: none; }
110
- body.running #btn-start { display: none; }
111
- body.running #btn-stop { display: block; }
112
-
113
- button {
114
- display: flex;
115
- align-items: center;
116
- justify-content: center;
117
- width: 100%;
118
- padding: 12px;
119
- border: none;
120
- border-radius: 8px;
121
- font-size: 14px;
122
- font-weight: 600;
123
- cursor: pointer;
124
- transition: all 0.2s ease;
125
- }
126
-
127
- .btn-start {
128
- background: var(--accent-color);
129
- color: white;
130
- }
131
- .btn-start:hover { background: var(--accent-hover); transform: translateY(-1px); }
132
- .btn-start:active { transform: translateY(0); }
133
-
134
- .btn-stop {
135
- background: #fff;
136
- color: var(--danger-color);
137
- border: 1px solid var(--danger-color);
138
- }
139
- .btn-stop:hover { background: #fef2f2; }
140
-
141
- .info-tip {
142
- margin-top: 20px;
143
- font-size: 12px;
144
- color: var(--text-secondary);
145
- text-align: center;
146
- background: #f8fafc;
147
- padding: 8px;
148
- border-radius: 6px;
149
- border: 1px dashed #cbd5e1;
150
- }
151
-
152
- /* 右侧日志面板 */
153
- .log-panel {
154
- background: #1e293b; /* 深色背景用于日志 */
155
- border-radius: var(--border-radius);
156
- box-shadow: var(--shadow-md);
157
- display: flex;
158
- flex-direction: column;
159
- overflow: hidden;
160
- }
161
-
162
- .log-header {
163
- padding: 16px 24px;
164
- border-bottom: 1px solid #334155;
165
- display: flex;
166
- justify-content: space-between;
167
- align-items: center;
168
- background: #0f172a;
169
- }
170
-
171
- .log-header h2 {
172
- color: #e2e8f0;
173
- font-size: 16px;
174
- font-weight: 600;
175
- display: flex;
176
- align-items: center;
177
- gap: 8px;
178
- }
179
-
180
- .log-box {
181
- flex: 1;
182
- padding: 20px;
183
- overflow-y: auto;
184
- font-family: var(--font-mono);
185
- font-size: 13px;
186
- line-height: 1.8;
187
- }
188
-
189
- /* 滚动条美化 */
190
- .log-box::-webkit-scrollbar { width: 6px; }
191
- .log-box::-webkit-scrollbar-track { background: #1e293b; }
192
- .log-box::-webkit-scrollbar-thumb { background: #475569; border-radius: 3px; }
193
-
194
- /* 日志条目样式 */
195
- .log-item {
196
- display: flex;
197
- margin-bottom: 6px;
198
- animation: fadeIn 0.3s ease;
199
- }
200
-
201
- @keyframes fadeIn {
202
- from { opacity: 0; transform: translateY(5px); }
203
- to { opacity: 1; transform: translateY(0); }
204
- }
205
-
206
- .log-time {
207
- color: #64748b;
208
- margin-right: 12px;
209
- min-width: 85px;
210
- }
211
-
212
- .log-content { color: #e2e8f0; }
213
- .log-type-success .log-content { color: #4ade80; }
214
- .log-type-info .log-content { color: #60a5fa; }
215
- .log-type-error .log-content { color: #f87171; }
216
-
217
- @media (max-width: 768px) {
218
- .dashboard { grid-template-columns: 1fr; height: auto; }
219
- body { height: auto; }
220
- .log-panel { height: 400px; }
221
- }
222
- </style>
223
- </head>
224
-
225
- <body>
226
- <div class="dashboard">
227
- <!-- 左侧控制区 -->
228
- <div class="control-panel">
229
- <div>
230
- <div class="header">
231
- <h1>Hyper Scheduler</h1>
232
- <p>双线程任务调度演示</p>
233
- </div>
234
-
235
- <div class="task-status">
236
- <div class="status-item">
237
- <span class="status-dot dot-main"></span>
238
- <div>
239
- <strong>主线程任务</strong>
240
- <div style="font-size: 12px; color: #64748b; margin-top: 2px">每 3 秒 (driver: 'main')</div>
241
- </div>
242
- </div>
243
- <div class="status-item">
244
- <span class="status-dot dot-worker"></span>
245
- <div>
246
- <strong>Worker 任务</strong>
247
- <div style="font-size: 12px; color: #64748b; margin-top: 2px">每 5 秒 (driver: 'worker')</div>
248
- </div>
249
- </div>
250
- </div>
251
- </div>
252
-
253
- <div>
254
- <div class="actions">
255
- <button class="btn-start" id="btn-start">
256
- <span style="margin-right: 8px">▶</span> 启动调度器
257
- </button>
258
- <button class="btn-stop" id="btn-stop">
259
- <span style="margin-right: 8px">⏹</span> 停止调度器
260
- </button>
261
- </div>
262
- <div class="info-tip">
263
- 💡 点击右下角悬浮球打开调试面板
264
- </div>
265
- </div>
266
- </div>
267
-
268
- <!-- 右侧日志区 -->
269
- <div class="log-panel">
270
- <div class="log-header">
271
- <h2>
272
- <span>📋</span> 执行日志
273
- </h2>
274
- <div style="font-size: 12px; color: #64748b">实时监控中...</div>
275
- </div>
276
- <div id="logs" class="log-box"></div>
277
- </div>
278
- </div>
279
-
280
- <script src="../../dist/index.umd.cjs"></script>
281
- <script>
282
- const logBox = document.getElementById('logs');
283
-
284
- function log(msg, type = 'info') {
285
- const time = new Date().toLocaleTimeString('zh-CN', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' });
286
-
287
- const item = document.createElement('div');
288
- item.className = `log-item log-type-${type}`;
289
-
290
- item.innerHTML = `
291
- <span class="log-time">${time}</span>
292
- <span class="log-content">${msg}</span>
293
- `;
294
-
295
- logBox.appendChild(item);
296
-
297
- // 保持最新的日志可见,但如果用户向上滚动了则不强制滚动
298
- const isScrolledToBottom = logBox.scrollHeight - logBox.clientHeight <= logBox.scrollTop + 10;
299
- if (isScrolledToBottom || logBox.children.length <= 2) {
300
- logBox.scrollTop = logBox.scrollHeight;
301
- }
302
- }
303
-
304
- const { Scheduler, DevTools } = window.HyperScheduler;
305
-
306
- const scheduler = new Scheduler({
307
- debug: true,
308
- plugins: [new DevTools({
309
- theme: 'auto',
310
- language: 'zh',
311
- trigger: {
312
- position: 'bottom-right',
313
- backgroundColor: '#3b82f6'
314
- }
315
- })]
316
- });
317
-
318
- // 主线程心跳 (明确指定 driver: 'main')
319
- scheduler.createTask({
320
- id: 'main-heartbeat',
321
- schedule: '3s',
322
- options: { driver: 'main' },
323
- handler: () => {
324
- log('❤️ [Main] 主线程心跳检测正常', 'error'); // 使用 error 样式红色,对应 UI 的红色点
325
- }
326
- });
327
-
328
- // Worker 线程心跳 (默认即为 Worker 驱动)
329
- scheduler.createTask({
330
- id: 'worker-heartbeat',
331
- schedule: '5s',
332
- handler: () => {
333
- log('💙 [Worker] 后台线程任务执行中', 'info'); // 使用 info 样式蓝色,对应 UI 的蓝色点
334
- }
335
- });
336
-
337
- // 按钮事件
338
- document.getElementById('btn-start').onclick = () => {
339
- scheduler.start();
340
- document.body.classList.add('running');
341
- log('🚀 调度器系统已启动', 'success');
342
- };
343
-
344
- document.getElementById('btn-stop').onclick = () => {
345
- scheduler.stop();
346
- document.body.classList.remove('running');
347
- log('⏹️ 调度器系统已停止', 'info');
348
- };
349
-
350
- log('✨ 系统就绪,等待启动指令...', 'info');
351
- </script>
352
- </body>
353
-
354
- </html>
@@ -1,36 +0,0 @@
1
- // 注意: 在实际项目中,你应该使用 import { Scheduler } from 'hyper-scheduler';
2
- // 此处为了演示本地构建版本,直接引用 dist 目录下的 ESM 构建产物
3
-
4
- import { Scheduler } from '../../dist/index.js';
5
-
6
- // 创建调度器
7
- const scheduler = new Scheduler({ debug: true });
8
-
9
- // 辅助函数:格式化时间
10
- const time = () => new Date().toLocaleTimeString('zh-CN', { hour12: false });
11
-
12
- console.log('✨ 系统就绪,等待启动指令...');
13
-
14
- // 主线程心跳 (明确指定 driver: 'main')
15
- scheduler.createTask({
16
- id: 'main-heartbeat',
17
- schedule: '3s',
18
- options: { driver: 'main' }, // 明确指定为主线程驱动
19
- handler: () => {
20
- console.log(`[${time()}] ❤️ [Main] 主线程心跳检测正常`);
21
- }
22
- });
23
-
24
- // Worker 线程心跳 (默认即为 Worker 驱动)
25
- scheduler.createTask({
26
- id: 'worker-heartbeat',
27
- schedule: '5s',
28
- handler: () => {
29
- console.log(`[${time()}] 💙 [Worker] 后台线程任务执行中`);
30
- }
31
- });
32
-
33
- // 启动调度器
34
- scheduler.start();
35
-
36
- console.log(`[${time()}] 🚀 调度器已启动,按 Ctrl+C 退出`);
@@ -1,12 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Hyper Scheduler React Demo</title>
7
- </head>
8
- <body>
9
- <div id="root"></div>
10
- <script type="module" src="/src/main.jsx"></script>
11
- </body>
12
- </html>