hyper-scheduler 1.1.3 → 1.1.5

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 (35) hide show
  1. package/README.md +2 -2
  2. package/dist/constants.d.ts +17 -0
  3. package/dist/core/retry-strategy.d.ts +15 -0
  4. package/dist/core/scheduler.d.ts +120 -0
  5. package/dist/core/task-registry.d.ts +43 -0
  6. package/dist/index.d.ts +23 -0
  7. package/dist/platform/browser/browser-timer.d.ts +20 -0
  8. package/dist/platform/browser/main-thread-timer.d.ts +10 -0
  9. package/dist/platform/browser/worker.d.ts +10 -0
  10. package/dist/platform/node/debug-cli.d.ts +8 -0
  11. package/dist/platform/node/node-timer.d.ts +9 -0
  12. package/dist/platform/timer-strategy.d.ts +18 -0
  13. package/dist/plugins/dev-tools.d.ts +10 -0
  14. package/dist/types.d.ts +119 -0
  15. package/dist/ui/components/devtools.d.ts +30 -0
  16. package/dist/ui/components/floating-trigger.d.ts +27 -0
  17. package/dist/ui/components/icons.d.ts +16 -0
  18. package/dist/ui/components/resizer.d.ts +14 -0
  19. package/dist/ui/components/task-detail.d.ts +13 -0
  20. package/dist/ui/components/task-header.d.ts +37 -0
  21. package/dist/ui/components/task-list.d.ts +21 -0
  22. package/dist/ui/components/timeline.d.ts +26 -0
  23. package/dist/ui/i18n/en.d.ts +76 -0
  24. package/dist/ui/i18n/index.d.ts +5 -0
  25. package/dist/ui/i18n/zh.d.ts +76 -0
  26. package/dist/ui/store/dev-tools-store.d.ts +53 -0
  27. package/dist/ui/styles/theme.css.d.ts +1 -0
  28. package/dist/utils/cron-lite.d.ts +13 -0
  29. package/dist/utils/id.d.ts +6 -0
  30. package/dist/utils/schedule.d.ts +23 -0
  31. package/package.json +4 -4
  32. package/dist/logo.svg +0 -54
  33. package/dist/task-list.png +0 -0
  34. package/public/logo.svg +0 -54
  35. package/public/task-list.png +0 -0
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="public/logo.svg" width="120" height="120" alt="Hyper Scheduler Logo">
2
+ <img src="https://github.com/CrazyMrYan/hyper-scheduler/raw/main/public/logo.svg" width="120" height="120" alt="Hyper Scheduler Logo">
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Hyper Scheduler</h1>
@@ -21,7 +21,7 @@ A lightweight, dependency-free (core) JavaScript task scheduler supporting Cron
21
21
 
22
22
  ## DevTools
23
23
 
24
- ![](./public/task-list.png)
24
+ ![](https://github.com/CrazyMrYan/hyper-scheduler/raw/main/public/task-list.png)
25
25
 
26
26
  ## Quick Start
27
27
 
@@ -0,0 +1,17 @@
1
+ export declare const TaskStatus: {
2
+ readonly IDLE: "idle";
3
+ readonly RUNNING: "running";
4
+ readonly STOPPED: "stopped";
5
+ readonly ERROR: "error";
6
+ };
7
+ export declare const SchedulerEvents: {
8
+ readonly TASK_REGISTERED: "task_registered";
9
+ readonly TASK_STARTED: "task_started";
10
+ readonly TASK_COMPLETED: "task_completed";
11
+ readonly TASK_FAILED: "task_failed";
12
+ readonly TASK_STOPPED: "task_stopped";
13
+ readonly TASK_REMOVED: "task_removed";
14
+ readonly TASK_UPDATED: "task_updated";
15
+ readonly SCHEDULER_STARTED: "scheduler_started";
16
+ readonly SCHEDULER_STOPPED: "scheduler_stopped";
17
+ };
@@ -0,0 +1,15 @@
1
+ import { TaskOptions } from '../types';
2
+ /**
3
+ * 重试策略工具类。
4
+ * 提供指数退避等重试延迟计算逻辑。
5
+ */
6
+ export declare class RetryStrategy {
7
+ /**
8
+ * 计算下一次重试的延迟时间。
9
+ * 采用指数退避算法 (Exponential Backoff)。
10
+ * @param attempt 当前重试次数 (从 0 开始,0 表示第一次重试)
11
+ * @param options 任务的重试配置
12
+ * @returns 延迟毫秒数,如果超过最大尝试次数则返回 -1
13
+ */
14
+ static getDelay(attempt: number, options?: TaskOptions['retry']): number;
15
+ }
@@ -0,0 +1,120 @@
1
+ import { SchedulerConfig, Task, TaskDefinition } from '../types';
2
+ import { TimerStrategy } from '../platform/timer-strategy';
3
+ export type TimerStrategyFactory = (driver: 'worker' | 'main') => TimerStrategy;
4
+ /**
5
+ * 核心调度器类。
6
+ * 负责管理任务生命周期、时间循环和任务执行。
7
+ */
8
+ export declare class Scheduler {
9
+ private registry;
10
+ private config;
11
+ private defaultTimerStrategy;
12
+ private timerStrategyFactory?;
13
+ private taskTimerStrategies;
14
+ private running;
15
+ private timers;
16
+ private listeners;
17
+ private eventListeners;
18
+ /**
19
+ * 创建一个新的调度器实例。
20
+ * @param timerStrategy 默认计时策略(NodeTimer 或 BrowserTimer)
21
+ * @param config 调度器配置
22
+ * @param timerStrategyFactory 可选的定时器策略工厂,用于创建任务级别的定时器
23
+ */
24
+ constructor(timerStrategy: TimerStrategy, config?: SchedulerConfig, timerStrategyFactory?: TimerStrategyFactory);
25
+ /**
26
+ * 订阅任务列表变更事件。
27
+ * 当任务创建、状态改变或删除时触发。
28
+ * @param listener 回调函数
29
+ * @returns 取消订阅的函数
30
+ */
31
+ subscribe(listener: (tasks: Task[]) => void): () => void;
32
+ /**
33
+ * 订阅特定事件
34
+ * @param event 事件名称
35
+ * @param handler 事件处理函数
36
+ * @returns 取消订阅的函数
37
+ */
38
+ on(event: string, handler: (payload: any) => void): () => void;
39
+ private emit;
40
+ /**
41
+ * 获取任务的定时器策略
42
+ * 优先使用任务级别配置,其次使用全局配置,最后使用默认策略
43
+ */
44
+ private getTimerStrategy;
45
+ private notify;
46
+ /**
47
+ * 创建并注册一个新任务。
48
+ * @param definition 任务定义
49
+ */
50
+ createTask(definition: TaskDefinition): void;
51
+ /**
52
+ * 删除指定 ID 的任务。
53
+ * @param id 任务 ID
54
+ * @returns 如果删除成功返回 true,否则返回 false
55
+ */
56
+ deleteTask(id: string): boolean;
57
+ /**
58
+ * 手动启动一个任务(将其置为 idle 状态并重新加入调度)。
59
+ * 即使调度器未启动,也可以单独启动某个任务。
60
+ * @param id 任务 ID
61
+ */
62
+ startTask(id: string): void;
63
+ /**
64
+ * 强制调度任务,即使调度器未启动
65
+ */
66
+ private scheduleTaskForce;
67
+ /**
68
+ * 执行单个任务(用于独立启动的任务)
69
+ */
70
+ private executeTaskIndividual;
71
+ /**
72
+ * 停止一个任务(取消当前的定时器并标记为 stopped)。
73
+ * @param id 任务 ID
74
+ */
75
+ stopTask(id: string): void;
76
+ /**
77
+ * 获取任务信息。
78
+ * @param id 任务 ID
79
+ */
80
+ getTask(id: string): Task | undefined;
81
+ /**
82
+ * 获取所有任务,可按命名空间筛选。
83
+ * @param namespace 可选的命名空间名称
84
+ * @returns 任务数组
85
+ */
86
+ getAllTasks(namespace?: string): Task[];
87
+ /**
88
+ * 获取调度器运行状态。
89
+ */
90
+ isRunning(): boolean;
91
+ /**
92
+ * 获取任务的实际驱动方式。
93
+ * 优先使用任务级配置,其次使用全局配置,默认为 'worker'。
94
+ */
95
+ getTaskDriver(id: string): 'worker' | 'main';
96
+ /**
97
+ * 获取全局驱动配置。
98
+ */
99
+ getGlobalDriver(): 'worker' | 'main';
100
+ /**
101
+ * 手动触发任务执行(忽略调度器状态,立即执行一次)。
102
+ * 执行完成后恢复到之前的状态。
103
+ * @param id 任务 ID
104
+ */
105
+ triggerTask(id: string): Promise<void>;
106
+ /**
107
+ * 启动调度器。
108
+ * 开始处理所有任务(除了手动停止的任务)。
109
+ */
110
+ start(scope?: string): void;
111
+ /**
112
+ * 停止调度器。
113
+ * 取消所有正在等待的定时器。
114
+ */
115
+ stop(scope?: string): void;
116
+ private scheduleTask;
117
+ private executeTask;
118
+ private recordHistory;
119
+ private log;
120
+ }
@@ -0,0 +1,43 @@
1
+ import { Task } from '../types';
2
+ /**
3
+ * 任务注册表。
4
+ * 负责存储和管理所有的任务实例。
5
+ */
6
+ export declare class TaskRegistry {
7
+ private tasks;
8
+ private namespaceIndex;
9
+ constructor();
10
+ /**
11
+ * 注册一个新任务。
12
+ * @param task 任务对象
13
+ * @throws Error 如果 ID 已存在
14
+ */
15
+ addTask(task: Task): void;
16
+ /**
17
+ * 根据 ID 获取任务。
18
+ * @param id 任务 ID
19
+ * @returns 任务对象或 undefined
20
+ */
21
+ getTask(id: string): Task | undefined;
22
+ /**
23
+ * 删除任务。
24
+ * @param id 任务 ID
25
+ * @returns 是否删除成功
26
+ */
27
+ deleteTask(id: string): boolean;
28
+ /**
29
+ * 获取所有已注册的任务。
30
+ * @returns 任务数组
31
+ */
32
+ getAllTasks(): Task[];
33
+ /**
34
+ * 根据命名空间获取所有任务。
35
+ * @param namespace 命名空间名称
36
+ * @returns 该命名空间下的任务数组
37
+ */
38
+ getTasksByNamespace(namespace: string): Task[];
39
+ /**
40
+ * 清空所有任务和索引。
41
+ */
42
+ clear(): void;
43
+ }
@@ -0,0 +1,23 @@
1
+ import { Scheduler as CoreScheduler } from './core/scheduler';
2
+ import { SchedulerConfig } from './types';
3
+ import { DevTools } from './plugins/dev-tools';
4
+ import { TaskStatus, SchedulerEvents } from './constants';
5
+ /**
6
+ * Hyper Scheduler 主入口类。
7
+ * 自动根据运行环境(浏览器或 Node.js)选择合适的计时策略。
8
+ *
9
+ * 支持两级 driver 配置:
10
+ * 1. 全局配置:new Scheduler({ driver: 'worker' | 'main' })
11
+ * 2. 任务级配置:createTask({ options: { driver: 'worker' | 'main' } })
12
+ *
13
+ * 任务级配置优先于全局配置。
14
+ */
15
+ export declare class Scheduler extends CoreScheduler {
16
+ /**
17
+ * 创建调度器实例。
18
+ * @param config 配置项
19
+ */
20
+ constructor(config?: SchedulerConfig);
21
+ }
22
+ export * from './types';
23
+ export { CoreScheduler, DevTools, TaskStatus, SchedulerEvents };
@@ -0,0 +1,20 @@
1
+ import { TimerStrategy } from '../timer-strategy';
2
+ /**
3
+ * 浏览器环境下的计时策略实现。
4
+ * 使用 Web Worker 来运行计时循环,以避免后台标签页的节流限制。
5
+ */
6
+ export declare class BrowserTimer implements TimerStrategy {
7
+ private worker;
8
+ private callbacks;
9
+ private nextId;
10
+ constructor();
11
+ /**
12
+ * 安排一个定时任务。
13
+ * 向 Web Worker 发送消息以注册计时器。
14
+ */
15
+ schedule(callback: () => void, delay: number): number;
16
+ /**
17
+ * 取消一个定时任务。
18
+ */
19
+ cancel(handle: number): void;
20
+ }
@@ -0,0 +1,10 @@
1
+ import { TimerStrategy } from '../timer-strategy';
2
+ /**
3
+ * 浏览器环境下的主线程计时策略实现。
4
+ * 使用原生的 setTimeout/clearTimeout,运行在主线程上。
5
+ * 注意:在后台标签页中可能受到浏览器节流限制。
6
+ */
7
+ export declare class MainThreadTimer implements TimerStrategy {
8
+ schedule(callback: () => void, delay: number): number;
9
+ cancel(handle: number): void;
10
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Web Worker 脚本。
3
+ * 用于在后台线程中运行计时器,避免主线程阻塞或页面后台节流影响计时精度。
4
+ */
5
+ interface TimerMessage {
6
+ id: number;
7
+ delay: number;
8
+ type: 'schedule' | 'cancel';
9
+ }
10
+ declare const timers: Map<number, number>;
@@ -0,0 +1,8 @@
1
+ import { Task } from '../../types';
2
+ /**
3
+ * Node.js 环境下的调试 CLI 工具。
4
+ * 用于在控制台输出任务状态表格。
5
+ */
6
+ export declare class DebugCLI {
7
+ static logTaskUpdate(tasks: Task[]): void;
8
+ }
@@ -0,0 +1,9 @@
1
+ import { TimerStrategy } from '../timer-strategy';
2
+ /**
3
+ * Node.js 环境下的计时策略实现。
4
+ * 简单包装了原生的 setTimeout 和 clearTimeout。
5
+ */
6
+ export declare class NodeTimer implements TimerStrategy {
7
+ schedule(callback: () => void, delay: number): NodeJS.Timeout;
8
+ cancel(handle: NodeJS.Timeout): void;
9
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 计时策略接口。
3
+ * 定义了跨平台计时器(Node.js 和 浏览器)的统一接口。
4
+ */
5
+ export interface TimerStrategy {
6
+ /**
7
+ * 安排一个回调函数在指定延迟后执行。
8
+ * @param callback 回调函数
9
+ * @param delay 延迟毫秒数
10
+ * @returns 用于取消定时器的句柄 (Handle)
11
+ */
12
+ schedule(callback: () => void, delay: number): any;
13
+ /**
14
+ * 取消一个已安排的定时器。
15
+ * @param handle schedule 方法返回的句柄
16
+ */
17
+ cancel(handle: any): void;
18
+ }
@@ -0,0 +1,10 @@
1
+ import { Scheduler } from '../core/scheduler';
2
+ import { DevToolsOptions, HyperSchedulerPlugin } from '../types';
3
+ export declare class DevTools implements HyperSchedulerPlugin {
4
+ name: string;
5
+ private options;
6
+ constructor(options?: DevToolsOptions);
7
+ init(scheduler: Scheduler): void;
8
+ private mount;
9
+ private setupElement;
10
+ }
@@ -0,0 +1,119 @@
1
+ import { TaskStatus as TaskStatusEnum } from './constants';
2
+ export type TaskStatus = typeof TaskStatusEnum[keyof typeof TaskStatusEnum];
3
+ export interface ExecutionRecord {
4
+ timestamp: number;
5
+ duration: number;
6
+ success: boolean;
7
+ error?: string;
8
+ }
9
+ export interface TaskOptions {
10
+ retry?: {
11
+ maxAttempts: number;
12
+ initialDelay: number;
13
+ factor?: number;
14
+ };
15
+ timezone?: string;
16
+ /** 任务执行失败时的错误处理回调 */
17
+ onError?: (error: Error, taskId: string) => void;
18
+ /**
19
+ * 任务隔离的命名空间。
20
+ * 默认值: 'default'
21
+ */
22
+ namespace?: string;
23
+ /**
24
+ * 如果为 true,任务将在调度器启动时(或在创建时如果调度器已启动)立即运行一次。
25
+ * 默认值: false
26
+ */
27
+ runImmediately?: boolean;
28
+ /**
29
+ * 定时器驱动方式(仅浏览器环境有效)
30
+ * - 'worker': 使用 Web Worker(默认,更精确,不受后台节流影响)
31
+ * - 'main': 使用主线程 setTimeout(更简单,但可能受后台节流影响)
32
+ * 如果不指定,则使用调度器全局配置
33
+ */
34
+ driver?: 'worker' | 'main';
35
+ }
36
+ export interface TaskDefinition {
37
+ id: string;
38
+ /**
39
+ * 任务调度规则。
40
+ * 支持:
41
+ * 1. Cron 表达式 (例如: "*\/5 * * * * *")
42
+ * 2. 间隔字符串 (例如: "10s", "5m", "1h")
43
+ */
44
+ schedule: string;
45
+ handler: () => void | Promise<void>;
46
+ options?: TaskOptions;
47
+ tags?: string[];
48
+ }
49
+ export interface Task extends TaskDefinition {
50
+ status: TaskStatus;
51
+ lastRun?: number;
52
+ nextRun?: number;
53
+ history: ExecutionRecord[];
54
+ tags?: string[];
55
+ executionCount?: number;
56
+ }
57
+ export interface SchedulerConfig {
58
+ debug?: boolean;
59
+ maxHistory?: number;
60
+ timezone?: string;
61
+ plugins?: HyperSchedulerPlugin[];
62
+ /**
63
+ * 定时器驱动方式(仅浏览器环境有效)
64
+ * - 'worker': 使用 Web Worker(默认,更精确,不受后台节流影响)
65
+ * - 'main': 使用主线程 setTimeout(更简单,但可能受后台节流影响)
66
+ */
67
+ driver?: 'worker' | 'main';
68
+ }
69
+ export interface HyperSchedulerPlugin {
70
+ name: string;
71
+ init(scheduler: any, options?: any): void;
72
+ }
73
+ export interface TaskSnapshot {
74
+ id: string;
75
+ status: string;
76
+ lastRun: number | null;
77
+ nextRun: number | null;
78
+ executionCount: number;
79
+ schedule: string;
80
+ tags: string[];
81
+ error: string | null;
82
+ driver: 'worker' | 'main';
83
+ namespace?: string;
84
+ }
85
+ export interface DevToolsOptions {
86
+ /** 主题模式 */
87
+ theme?: 'light' | 'dark' | 'auto';
88
+ /** 面板停靠位置 */
89
+ dockPosition?: 'right' | 'bottom';
90
+ /** 界面语言 */
91
+ language?: 'en' | 'zh';
92
+ /** 时间线默认缩放级别 (0.5-5) */
93
+ defaultZoom?: number;
94
+ /**
95
+ * 缩放时间步长 (单位毫秒)
96
+ * 默认值: 1000 (1秒)
97
+ */
98
+ zoomStep?: number;
99
+ /** 悬浮按钮配置 */
100
+ trigger?: {
101
+ /** 背景色 */
102
+ backgroundColor?: string;
103
+ /** 文字/图标颜色 */
104
+ textColor?: string;
105
+ /** 位置 */
106
+ position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
107
+ };
108
+ }
109
+ export interface TaskControlAPI {
110
+ trigger(taskId: string): Promise<void>;
111
+ pause(taskId: string): void;
112
+ resume(taskId: string): void;
113
+ remove(taskId: string): void;
114
+ }
115
+ export interface SchedulerIntrospectionAPI {
116
+ getTasks(): TaskSnapshot[];
117
+ on(event: string, handler: (data: any) => void): () => void;
118
+ isRunning(): boolean;
119
+ }
@@ -0,0 +1,30 @@
1
+ import { SchedulerIntrospectionAPI, TaskControlAPI } from '../../types';
2
+ import './floating-trigger';
3
+ import './task-header';
4
+ import './task-list';
5
+ import './task-detail';
6
+ import './timeline';
7
+ import './resizer';
8
+ export declare class DevTools extends HTMLElement {
9
+ private _shadow;
10
+ private store;
11
+ private scheduler?;
12
+ private rAFId?;
13
+ private lastTime;
14
+ private $panel;
15
+ private $header;
16
+ private $taskList;
17
+ private $taskDetail;
18
+ private $timeline;
19
+ private $trigger;
20
+ private $overlay;
21
+ constructor();
22
+ connectedCallback(): void;
23
+ disconnectedCallback(): void;
24
+ setScheduler(api: SchedulerIntrospectionAPI & TaskControlAPI): void;
25
+ private cacheDom;
26
+ private bindStore;
27
+ private addEventListeners;
28
+ private startLoop;
29
+ render(): void;
30
+ }
@@ -0,0 +1,27 @@
1
+ export declare class FloatingTrigger extends HTMLElement {
2
+ private _shadow;
3
+ private _position;
4
+ private _bgColor;
5
+ private _textColor;
6
+ private _isDragging;
7
+ private _wasDragging;
8
+ private _offsetX;
9
+ private _offsetY;
10
+ private _isCollapsed;
11
+ private _savedX;
12
+ private _savedY;
13
+ static get observedAttributes(): string[];
14
+ constructor();
15
+ connectedCallback(): void;
16
+ disconnectedCallback(): void;
17
+ private onResize;
18
+ attributeChangedCallback(name: string, _oldVal: string, newVal: string): void;
19
+ private loadState;
20
+ private resetPositionToDefault;
21
+ private saveState;
22
+ private applyPosition;
23
+ private updateStyles;
24
+ private updateCollapsedState;
25
+ addEventListeners(): void;
26
+ render(): void;
27
+ }
@@ -0,0 +1,16 @@
1
+ export declare const ICONS: {
2
+ back: string;
3
+ trigger: string;
4
+ pause: string;
5
+ resume: string;
6
+ remove: string;
7
+ close: string;
8
+ settings: string;
9
+ sun: string;
10
+ moon: string;
11
+ dock: string;
12
+ dockRight: string;
13
+ dockBottom: string;
14
+ chart: string;
15
+ list: string;
16
+ };
@@ -0,0 +1,14 @@
1
+ export declare class Resizer extends HTMLElement {
2
+ private _shadow;
3
+ private startX;
4
+ private startY;
5
+ private startWidth;
6
+ private startHeight;
7
+ private panel;
8
+ private mode;
9
+ constructor();
10
+ private isMobile;
11
+ connectedCallback(): void;
12
+ private addEventListeners;
13
+ render(): void;
14
+ }
@@ -0,0 +1,13 @@
1
+ import { TaskSnapshot, ExecutionRecord } from '../../types';
2
+ export declare class TaskDetail extends HTMLElement {
3
+ private _shadow;
4
+ private _task;
5
+ private _history;
6
+ constructor();
7
+ connectedCallback(): void;
8
+ set task(task: TaskSnapshot | null);
9
+ set history(h: ExecutionRecord[]);
10
+ updateTexts(): void;
11
+ private renderContent;
12
+ render(): void;
13
+ }
@@ -0,0 +1,37 @@
1
+ export declare class TaskHeader extends HTMLElement {
2
+ private _shadow;
3
+ private _fps;
4
+ private _stats;
5
+ private _theme;
6
+ private _activeTab;
7
+ private _language;
8
+ private _schedulerRunning;
9
+ private $fps;
10
+ private $stats;
11
+ private $schedulerStatus;
12
+ private $themeIcon;
13
+ private $dockIcon;
14
+ private $tabs;
15
+ private $searchInput;
16
+ private $title;
17
+ private $langBtn;
18
+ constructor();
19
+ connectedCallback(): void;
20
+ set fps(val: number);
21
+ set stats(val: {
22
+ active: number;
23
+ total: number;
24
+ });
25
+ set schedulerRunning(val: boolean);
26
+ set theme(val: 'light' | 'dark' | 'auto');
27
+ set language(val: 'en' | 'zh');
28
+ set dockPosition(val: 'right' | 'bottom');
29
+ set activeTab(val: 'tasks' | 'timeline');
30
+ private cacheDom;
31
+ private addEventListeners;
32
+ private updateThemeIcon;
33
+ private updateTabs;
34
+ private updateTexts;
35
+ private updateView;
36
+ render(): void;
37
+ }
@@ -0,0 +1,21 @@
1
+ import { TaskSnapshot } from '../../types';
2
+ export declare class TaskList extends HTMLElement {
3
+ private _shadow;
4
+ private _allTasks;
5
+ private _filteredTasks;
6
+ private _lastExecutionTimes;
7
+ private _expandedNamespaces;
8
+ constructor();
9
+ connectedCallback(): void;
10
+ set tasks(map: Map<string, TaskSnapshot>);
11
+ private groupTasksByNamespace;
12
+ filter(text: string, map: Map<string, TaskSnapshot>): void;
13
+ updateHeaders(): void;
14
+ private getStatusIcon;
15
+ private formatSchedule;
16
+ private formatTime;
17
+ private getDriverBadge;
18
+ private renderTaskRow;
19
+ private renderRows;
20
+ render(): void;
21
+ }
@@ -0,0 +1,26 @@
1
+ import { TaskSnapshot, ExecutionRecord } from '../../types';
2
+ export declare class Timeline extends HTMLElement {
3
+ private _shadow;
4
+ private _tasks;
5
+ private _history;
6
+ private $canvas;
7
+ private ctx;
8
+ private timeRange;
9
+ private zoom;
10
+ constructor();
11
+ connectedCallback(): void;
12
+ set data(val: {
13
+ tasks: Map<string, TaskSnapshot>;
14
+ history: Map<string, ExecutionRecord[]>;
15
+ });
16
+ set defaultZoom(val: number);
17
+ updateTexts(): void;
18
+ private updateZoomLabel;
19
+ private setupZoom;
20
+ private startLoop;
21
+ private draw;
22
+ private drawTimeAxis;
23
+ private drawTaskRow;
24
+ private drawLegend;
25
+ render(): void;
26
+ }
@@ -0,0 +1,76 @@
1
+ export declare const en: {
2
+ header: {
3
+ title: string;
4
+ searchPlaceholder: string;
5
+ toggleDock: string;
6
+ toggleTheme: string;
7
+ close: string;
8
+ };
9
+ stats: {
10
+ loading: string;
11
+ fps: string;
12
+ status: string;
13
+ active: string;
14
+ total: string;
15
+ mainThread: string;
16
+ scheduler: string;
17
+ running: string;
18
+ stopped: string;
19
+ };
20
+ tabs: {
21
+ tasks: string;
22
+ timeline: string;
23
+ };
24
+ list: {
25
+ idTags: string;
26
+ status: string;
27
+ driver: string;
28
+ driverWorker: string;
29
+ driverMain: string;
30
+ schedule: string;
31
+ count: string;
32
+ lastRun: string;
33
+ actions: string;
34
+ noTags: string;
35
+ tip: string;
36
+ };
37
+ detail: {
38
+ back: string;
39
+ details: string;
40
+ config: string;
41
+ history: string;
42
+ lastRuns: string;
43
+ avgDuration: string;
44
+ startTime: string;
45
+ duration: string;
46
+ drift: string;
47
+ status: string;
48
+ noHistory: string;
49
+ noTask: string;
50
+ success: string;
51
+ failed: string;
52
+ error: string;
53
+ };
54
+ timeline: {
55
+ zoom: string;
56
+ timeRange: string;
57
+ legend: string;
58
+ instant: string;
59
+ duration: string;
60
+ workerDriver: string;
61
+ mainDriver: string;
62
+ };
63
+ status: {
64
+ running: string;
65
+ paused: string;
66
+ stopped: string;
67
+ idle: string;
68
+ error: string;
69
+ };
70
+ actions: {
71
+ trigger: string;
72
+ start: string;
73
+ stop: string;
74
+ remove: string;
75
+ };
76
+ };
@@ -0,0 +1,5 @@
1
+ type Lang = 'en' | 'zh';
2
+ export declare function setLanguage(lang: Lang): void;
3
+ export declare function getLanguage(): Lang;
4
+ export declare function t(key: string, params?: Record<string, any>): string;
5
+ export {};
@@ -0,0 +1,76 @@
1
+ export declare const zh: {
2
+ header: {
3
+ title: string;
4
+ searchPlaceholder: string;
5
+ toggleDock: string;
6
+ toggleTheme: string;
7
+ close: string;
8
+ };
9
+ stats: {
10
+ loading: string;
11
+ fps: string;
12
+ status: string;
13
+ active: string;
14
+ total: string;
15
+ mainThread: string;
16
+ scheduler: string;
17
+ running: string;
18
+ stopped: string;
19
+ };
20
+ tabs: {
21
+ tasks: string;
22
+ timeline: string;
23
+ };
24
+ list: {
25
+ idTags: string;
26
+ status: string;
27
+ driver: string;
28
+ driverWorker: string;
29
+ driverMain: string;
30
+ schedule: string;
31
+ count: string;
32
+ lastRun: string;
33
+ actions: string;
34
+ noTags: string;
35
+ tip: string;
36
+ };
37
+ detail: {
38
+ back: string;
39
+ details: string;
40
+ config: string;
41
+ history: string;
42
+ lastRuns: string;
43
+ avgDuration: string;
44
+ startTime: string;
45
+ duration: string;
46
+ drift: string;
47
+ status: string;
48
+ noHistory: string;
49
+ noTask: string;
50
+ success: string;
51
+ failed: string;
52
+ error: string;
53
+ };
54
+ timeline: {
55
+ zoom: string;
56
+ timeRange: string;
57
+ legend: string;
58
+ instant: string;
59
+ duration: string;
60
+ workerDriver: string;
61
+ mainDriver: string;
62
+ };
63
+ status: {
64
+ running: string;
65
+ paused: string;
66
+ stopped: string;
67
+ idle: string;
68
+ error: string;
69
+ };
70
+ actions: {
71
+ trigger: string;
72
+ start: string;
73
+ stop: string;
74
+ remove: string;
75
+ };
76
+ };
@@ -0,0 +1,53 @@
1
+ import { TaskSnapshot, TaskControlAPI } from '../../types';
2
+ export interface DevToolsState {
3
+ isOpen: boolean;
4
+ activeTab: 'tasks' | 'timeline';
5
+ theme: 'light' | 'dark' | 'auto';
6
+ dockPosition: 'right' | 'bottom';
7
+ panelSize: {
8
+ width: number;
9
+ height: number;
10
+ };
11
+ language: 'en' | 'zh';
12
+ filterText: string;
13
+ selectedTaskId: string | null;
14
+ tasks: Map<string, TaskSnapshot>;
15
+ history: Map<string, any[]>;
16
+ fps: number;
17
+ schedulerRunning: boolean;
18
+ }
19
+ type Listener<T> = (value: T) => void;
20
+ export declare class DevToolsStore {
21
+ private state;
22
+ private listeners;
23
+ private scheduler?;
24
+ constructor();
25
+ setScheduler(scheduler: TaskControlAPI): void;
26
+ getState(): Readonly<DevToolsState>;
27
+ subscribe<K extends keyof DevToolsState>(key: K, callback: Listener<DevToolsState[K]>): () => void;
28
+ private notify;
29
+ toggle(): void;
30
+ setTheme(theme: 'light' | 'dark' | 'auto'): void;
31
+ /**
32
+ * Set language synchronously without notifying listeners.
33
+ * Used during initialization before child components render.
34
+ */
35
+ setLanguageSync(lang: 'en' | 'zh'): void;
36
+ setLanguage(lang: 'en' | 'zh'): void;
37
+ setPanelSize(size: {
38
+ width?: number;
39
+ height?: number;
40
+ }): void;
41
+ setTab(tab: 'tasks' | 'timeline'): void;
42
+ setDockPosition(pos: 'right' | 'bottom'): void;
43
+ setFilterText(text: string): void;
44
+ updateTask(task: TaskSnapshot): void;
45
+ selectTask(id: string | null): void;
46
+ addHistory(taskId: string, record: any): void;
47
+ triggerTask(id: string): Promise<void>;
48
+ stopTask(id: string): void;
49
+ startTask(id: string): void;
50
+ removeTask(id: string): void;
51
+ setSchedulerRunning(running: boolean): void;
52
+ }
53
+ export {};
@@ -0,0 +1 @@
1
+ export declare const themeStyles = "\n :host {\n --hs-font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n --hs-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n --hs-font-size: 12px;\n --hs-line-height: 1.5;\n --hs-panel-width: 400px;\n --hs-panel-height: 300px;\n \n /* \u7B49\u5BBD\u6570\u5B57\u5B57\u4F53 */\n --hs-font-monospaced-num: var(--hs-font-mono);\n\n /* Light Theme (Default) */\n --hs-bg: #ffffff;\n --hs-bg-secondary: #f3f4f6;\n --hs-text: #1f2937;\n --hs-text-secondary: #6b7280;\n --hs-border: #e5e7eb;\n --hs-primary: #3b82f6;\n --hs-primary-hover: #2563eb;\n --hs-danger: #ef4444;\n --hs-danger-hover: #dc2626;\n --hs-success: #10b981;\n --hs-warning: #f59e0b;\n \n --hs-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n --hs-radius: 6px;\n --hs-header-height: 40px;\n --hs-z-index: 9999;\n --hs-z-index-overlay: 9998;\n\n /* Default display styles for the host itself */\n background: var(--hs-bg);\n color: var(--hs-text);\n font-family: var(--hs-font-family);\n font-size: var(--hs-font-size);\n line-height: var(--hs-line-height);\n }\n\n :host([theme=\"dark\"]) {\n --hs-bg: #111827;\n --hs-bg-secondary: #1f2937;\n --hs-text: #f9fafb;\n --hs-text-secondary: #9ca3af;\n --hs-border: #374151;\n --hs-primary: #60a5fa;\n --hs-primary-hover: #3b82f6;\n --hs-danger: #f87171;\n --hs-danger-hover: #ef4444;\n --hs-success: #34d399;\n --hs-warning: #fbbf24;\n \n --hs-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.5), 0 2px 4px -1px rgba(0, 0, 0, 0.3);\n }\n\n :host {\n background: var(--hs-bg);\n color: var(--hs-text);\n }\n";
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 轻量级 Cron 解析器
3
+ * 支持标准 5 位和 6 位 cron 表达式
4
+ * 格式: [秒] 分 时 日 月 周
5
+ */
6
+ /**
7
+ * 验证 cron 表达式
8
+ */
9
+ export declare function validateCron(expression: string): void;
10
+ /**
11
+ * 计算下一次运行时间
12
+ */
13
+ export declare function getNextRun(expression: string, _timezone?: string): Date;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 验证任务 ID 是否为非空字符串。
3
+ * @param id 待验证的 ID
4
+ * @throws Error 如果 ID 无效
5
+ */
6
+ export declare function validateId(id: string): void;
@@ -0,0 +1,23 @@
1
+ export type ScheduleType = 'cron' | 'interval';
2
+ export interface ParsedSchedule {
3
+ type: ScheduleType;
4
+ value: any | number;
5
+ }
6
+ /**
7
+ * 解析调度规则字符串,将其转换为 Cron 表达式对象或毫秒级间隔。
8
+ * 支持的间隔格式: "10s", "5m", "2h", "1d"。
9
+ * @param schedule 调度规则字符串
10
+ * @returns 解析后的调度对象
11
+ * @throws Error 如果字符串格式无效
12
+ */
13
+ export declare function parseSchedule(schedule: string): ParsedSchedule;
14
+ /**
15
+ * 计算下一次运行时间。
16
+ * @param schedule 调度规则字符串或已解析的对象
17
+ * @param options 可选配置 (cron 的时区,interval 的上次运行时间)
18
+ * @returns 下一次运行的 Date 对象
19
+ */
20
+ export declare function getNextRun(schedule: string | ParsedSchedule, options?: {
21
+ timezone?: string;
22
+ lastRun?: number;
23
+ }): Date;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyper-scheduler",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
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",
@@ -8,6 +8,7 @@
8
8
  "types": "./dist/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
+ "types": "./dist/index.d.ts",
11
12
  "import": "./dist/index.js",
12
13
  "require": "./dist/index.cjs"
13
14
  }
@@ -15,8 +16,7 @@
15
16
  "files": [
16
17
  "dist",
17
18
  "README.md",
18
- "LICENSE",
19
- "public"
19
+ "LICENSE"
20
20
  ],
21
21
  "scripts": {
22
22
  "dev": "vite",
@@ -27,7 +27,7 @@
27
27
  "example:vue": "cd examples/vue-demo && yarn && yarn dev",
28
28
  "example:react": "cd examples/react-demo && yarn && yarn dev",
29
29
  "dev:all": "concurrently \"yarn docs:dev\" \"yarn example:vue\" \"yarn example:react\" \"vite examples/browser --port 3003\"",
30
- "build": "tsc && vite build",
30
+ "build": "npx vite build && tsc -p tsconfig.build.json",
31
31
  "prepublishOnly": "yarn build",
32
32
  "test": "vitest",
33
33
  "lint": "eslint . --ext .ts"
package/dist/logo.svg DELETED
@@ -1,54 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none">
2
- <defs>
3
- <linearGradient id="main" x1="0%" y1="0%" x2="100%" y2="100%">
4
- <stop offset="0%" style="stop-color:#6366f1"/>
5
- <stop offset="100%" style="stop-color:#a855f7"/>
6
- </linearGradient>
7
- <linearGradient id="bolt" x1="50%" y1="0%" x2="50%" y2="100%">
8
- <stop offset="0%" style="stop-color:#fcd34d"/>
9
- <stop offset="100%" style="stop-color:#f59e0b"/>
10
- </linearGradient>
11
- <filter id="glow">
12
- <feGaussianBlur stdDeviation="2" result="blur"/>
13
- <feMerge>
14
- <feMergeNode in="blur"/>
15
- <feMergeNode in="SourceGraphic"/>
16
- </feMerge>
17
- </filter>
18
- <filter id="softShadow">
19
- <feDropShadow dx="0" dy="2" stdDeviation="3" flood-color="#6366f1" flood-opacity="0.3"/>
20
- </filter>
21
- </defs>
22
-
23
- <!-- 背景圆 - 柔和填充 -->
24
- <circle cx="64" cy="64" r="56" fill="url(#main)" opacity="0.1"/>
25
-
26
- <!-- 刻度点 - 简约时钟感 -->
27
- <g fill="url(#main)" opacity="0.7">
28
- <circle cx="64" cy="16" r="4"/>
29
- <circle cx="112" cy="64" r="4"/>
30
- <circle cx="64" cy="112" r="4"/>
31
- <circle cx="16" cy="64" r="4"/>
32
- </g>
33
-
34
- <!-- 次要刻度 -->
35
- <g fill="url(#main)" opacity="0.35">
36
- <circle cx="98" cy="26" r="2.5"/>
37
- <circle cx="102" cy="98" r="2.5"/>
38
- <circle cx="26" cy="98" r="2.5"/>
39
- <circle cx="30" cy="26" r="2.5"/>
40
- </g>
41
-
42
- <!-- 闪电 - 核心元素 -->
43
- <path d="M72 20 L44 68 L62 68 L52 108 L88 52 L68 52 L72 20Z"
44
- fill="url(#bolt)"
45
- filter="url(#glow)"/>
46
-
47
- <!-- 闪电高光 -->
48
- <path d="M70 26 L50 64 L62 64 L56 92"
49
- stroke="#fff"
50
- stroke-width="2"
51
- stroke-linecap="round"
52
- fill="none"
53
- opacity="0.4"/>
54
- </svg>
Binary file
package/public/logo.svg DELETED
@@ -1,54 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none">
2
- <defs>
3
- <linearGradient id="main" x1="0%" y1="0%" x2="100%" y2="100%">
4
- <stop offset="0%" style="stop-color:#6366f1"/>
5
- <stop offset="100%" style="stop-color:#a855f7"/>
6
- </linearGradient>
7
- <linearGradient id="bolt" x1="50%" y1="0%" x2="50%" y2="100%">
8
- <stop offset="0%" style="stop-color:#fcd34d"/>
9
- <stop offset="100%" style="stop-color:#f59e0b"/>
10
- </linearGradient>
11
- <filter id="glow">
12
- <feGaussianBlur stdDeviation="2" result="blur"/>
13
- <feMerge>
14
- <feMergeNode in="blur"/>
15
- <feMergeNode in="SourceGraphic"/>
16
- </feMerge>
17
- </filter>
18
- <filter id="softShadow">
19
- <feDropShadow dx="0" dy="2" stdDeviation="3" flood-color="#6366f1" flood-opacity="0.3"/>
20
- </filter>
21
- </defs>
22
-
23
- <!-- 背景圆 - 柔和填充 -->
24
- <circle cx="64" cy="64" r="56" fill="url(#main)" opacity="0.1"/>
25
-
26
- <!-- 刻度点 - 简约时钟感 -->
27
- <g fill="url(#main)" opacity="0.7">
28
- <circle cx="64" cy="16" r="4"/>
29
- <circle cx="112" cy="64" r="4"/>
30
- <circle cx="64" cy="112" r="4"/>
31
- <circle cx="16" cy="64" r="4"/>
32
- </g>
33
-
34
- <!-- 次要刻度 -->
35
- <g fill="url(#main)" opacity="0.35">
36
- <circle cx="98" cy="26" r="2.5"/>
37
- <circle cx="102" cy="98" r="2.5"/>
38
- <circle cx="26" cy="98" r="2.5"/>
39
- <circle cx="30" cy="26" r="2.5"/>
40
- </g>
41
-
42
- <!-- 闪电 - 核心元素 -->
43
- <path d="M72 20 L44 68 L62 68 L52 108 L88 52 L68 52 L72 20Z"
44
- fill="url(#bolt)"
45
- filter="url(#glow)"/>
46
-
47
- <!-- 闪电高光 -->
48
- <path d="M70 26 L50 64 L62 64 L56 92"
49
- stroke="#fff"
50
- stroke-width="2"
51
- stroke-linecap="round"
52
- fill="none"
53
- opacity="0.4"/>
54
- </svg>
Binary file