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
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";var t=Object.defineProperty,e=(e,s,i)=>((e,s,i)=>s in e?t(e,s,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[s]=i)(e,"symbol"!=typeof s?s+"":s,i);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s={IDLE:"idle",RUNNING:"running",STOPPED:"stopped",ERROR:"error"},i={TASK_REGISTERED:"task_registered",TASK_STARTED:"task_started",TASK_COMPLETED:"task_completed",TASK_FAILED:"task_failed",TASK_STOPPED:"task_stopped",TASK_REMOVED:"task_removed",TASK_UPDATED:"task_updated",SCHEDULER_STARTED:"scheduler_started",SCHEDULER_STOPPED:"scheduler_stopped"};class r{constructor(){e(this,"tasks"),e(this,"namespaceIndex"),this.tasks=new Map,this.namespaceIndex=new Map}addTask(t){var e,s;if(this.tasks.has(t.id))throw new Error(`Task with ID "${t.id}" already exists.`);this.tasks.set(t.id,t);const i=(null==(e=t.options)?void 0:e.namespace)||"default";this.namespaceIndex.has(i)||this.namespaceIndex.set(i,new Set),null==(s=this.namespaceIndex.get(i))||s.add(t.id)}getTask(t){return this.tasks.get(t)}deleteTask(t){var e,s,i;const r=this.tasks.get(t);if(!r)return!1;const n=(null==(e=r.options)?void 0:e.namespace)||"default";return null==(s=this.namespaceIndex.get(n))||s.delete(t),0===(null==(i=this.namespaceIndex.get(n))?void 0:i.size)&&this.namespaceIndex.delete(n),this.tasks.delete(t)}getAllTasks(){return Array.from(this.tasks.values())}getTasksByNamespace(t){const e=this.namespaceIndex.get(t);return e?Array.from(e).map(t=>this.tasks.get(t)).filter(Boolean):[]}clear(){this.tasks.clear(),this.namespaceIndex.clear()}}function n(t,e,s){const i=new Set;if("*"===t){for(let t=e;t<=s;t++)i.add(t);return Array.from(i).sort((t,e)=>t-e)}const r=t.split(",");for(const n of r)if(n.includes("/")){const[t,r]=n.split("/"),o=parseInt(r,10);if("*"===t)for(let n=e;n<=s;n+=o)i.add(n);else if(t.includes("-")){const[r,n]=t.split("-").map(Number);if(r<e||n>s)throw new Error(`Value out of range: ${r}-${n} (expected ${e}-${s})`);for(let t=r;t<=n;t+=o)i.add(t)}else{const r=parseInt(t,10);if(r<e||r>s)throw new Error(`Value out of range: ${r} (expected ${e}-${s})`);for(let t=r;t<=s;t+=o)i.add(t)}}else if(n.includes("-")){const[t,r]=n.split("-").map(Number);if(t<e||r>s)throw new Error(`Value out of range: ${t}-${r} (expected ${e}-${s})`);for(let e=t;e<=r;e++)i.add(e)}else{const t=parseInt(n,10);if(t<e||t>s)throw new Error(`Value out of range: ${t} (expected ${e}-${s})`);i.add(t)}return Array.from(i).sort((t,e)=>t-e)}function o(t){const e=t.trim().split(/\s+/);let s,i,r,o,a,l;if(5===e.length)s=[0],[i,r,o,a,l]=[n(e[0],0,59),n(e[1],0,23),n(e[2],1,31),n(e[3],1,12),n(e[4],0,6)];else{if(6!==e.length)throw new Error(`Invalid cron expression: expected 5 or 6 fields, got ${e.length}`);[s,i,r,o,a,l]=[n(e[0],0,59),n(e[1],0,59),n(e[2],0,23),n(e[3],1,31),n(e[4],1,12),n(e[5],0,6)]}return{second:s,minute:i,hour:r,dayOfMonth:o,month:a,dayOfWeek:l}}function a(t,e){const s=t.getSeconds(),i=t.getMinutes(),r=t.getHours(),n=t.getDate(),o=t.getMonth()+1,a=t.getDay();return e.second.includes(s)&&e.minute.includes(i)&&e.hour.includes(r)&&e.month.includes(o)&&(e.dayOfMonth.includes(n)||e.dayOfWeek.includes(a))}function l(t){const e=t.match(/^(\d+)(s|m|h|d)$/);if(e){const t=parseInt(e[1],10);let s=1e3;switch(e[2]){case"s":s=1e3;break;case"m":s=6e4;break;case"h":s=36e5;break;case"d":s=864e5}return{type:"interval",value:t*s}}try{return function(t){try{o(t)}catch(e){throw new Error(`Invalid cron expression: ${t}`)}}(t),{type:"cron",value:t}}catch(s){throw new Error(`无效的调度格式: "${t}". 必须是有效的 Cron 表达式或间隔字符串 (例如 "10s")。`)}}function c(t,e){let s;if(s="string"==typeof t?l(t):t,"interval"===s.type){const t=s.value,i=(null==e?void 0:e.lastRun)||Date.now();return new Date(i+t)}{const t=s.value;try{return function(t){var e,s,i;const r=o(t);let n=new Date((new Date).getTime()+1e3);n.setMilliseconds(0);let l=0;for(;l<126144e3;){if(a(n,r))return n;const t=n.getSeconds(),o=n.getMinutes(),c=n.getHours();if(!r.second.includes(t)){const s=null!=(e=r.second.find(e=>e>t))?e:r.second[0];s>t?n.setSeconds(s):n.setMinutes(o+1,s),n.setMilliseconds(0),l++;continue}if(!r.minute.includes(o)){const t=null!=(s=r.minute.find(t=>t>o))?s:r.minute[0];t>o?n.setMinutes(t,r.second[0]):n.setHours(c+1,t,r.second[0]),n.setMilliseconds(0),l++;continue}if(!r.hour.includes(c)){const t=null!=(i=r.hour.find(t=>t>c))?i:r.hour[0];t>c||n.setDate(n.getDate()+1),n.setHours(t,r.minute[0],r.second[0]),n.setMilliseconds(0),l++;continue}n=new Date(n.getTime()+1e3),l++}throw new Error(`Could not find next run time for cron expression: ${t}`)}(t,null==e||e.timezone)}catch(i){throw new Error(`无法计算下一次 Cron 运行时间: ${t}`)}}}class u{static getDelay(t,e){if(!e)return-1;const{maxAttempts:s,initialDelay:i,factor:r=2}=e;return t>=s?-1:i*Math.pow(r,t)}}let d=class{constructor(t,s={},i){e(this,"registry"),e(this,"config"),e(this,"defaultTimerStrategy"),e(this,"timerStrategyFactory"),e(this,"taskTimerStrategies"),e(this,"running"),e(this,"timers"),e(this,"listeners"),e(this,"eventListeners"),this.registry=new r,this.defaultTimerStrategy=t,this.timerStrategyFactory=i,this.taskTimerStrategies=new Map,this.config={debug:!1,maxHistory:50,...s},this.running=!1,this.timers=new Map,this.listeners=[],this.eventListeners=new Map,this.config.plugins&&Array.isArray(this.config.plugins)&&this.config.plugins.forEach(t=>{try{this.log(`Initializing plugin: ${t.name}`),t.init(this)}catch(e){console.warn(`[HyperScheduler] Failed to initialize plugin ${t.name}:`,e)}})}subscribe(t){return this.listeners.push(t),()=>{this.listeners=this.listeners.filter(e=>e!==t)}}on(t,e){return this.eventListeners.has(t)||this.eventListeners.set(t,new Set),this.eventListeners.get(t).add(e),()=>{var s;null==(s=this.eventListeners.get(t))||s.delete(e)}}emit(t,e){const s=this.eventListeners.get(t);s&&s.forEach(t=>t(e))}getTimerStrategy(t){var e;const s=null==(e=t.options)?void 0:e.driver,i=this.config.driver,r=s||i;if(!r||!this.timerStrategyFactory)return this.defaultTimerStrategy;const n=`${t.id}_${r}`;if(this.taskTimerStrategies.has(n))return this.taskTimerStrategies.get(n);const o=this.timerStrategyFactory(r);return this.taskTimerStrategies.set(n,o),o}notify(){if(this.listeners.length>0){const t=this.registry.getAllTasks();this.listeners.forEach(e=>e(t))}}createTask(t){var e;!function(t){if(!t||"string"!=typeof t||""===t.trim())throw new Error("Task ID must be a non-empty string.")}(t.id),l(t.schedule);const r={...t,tags:t.tags||[],status:s.STOPPED,history:[],executionCount:0};this.registry.addTask(r),this.log(`Task created: ${r.id}`),this.emit(i.TASK_REGISTERED,{taskId:r.id,task:r}),this.notify(),this.running&&(r.status=s.IDLE,(null==(e=r.options)?void 0:e.runImmediately)&&this.triggerTask(r.id),this.scheduleTask(r))}deleteTask(t){this.stopTask(t);const e=this.registry.deleteTask(t);return e&&(this.log(`Task deleted: ${t}`),this.emit(i.TASK_REMOVED,{taskId:t}),this.notify()),e}startTask(t){const e=this.registry.getTask(t);if(!e)throw new Error(`Task not found: ${t}`);if(e.status===s.RUNNING)return;const r=this.timers.get(t);r&&(this.getTimerStrategy(e).cancel(r),this.timers.delete(t)),e.status=s.IDLE,this.log(`Starting task: ${t}`),this.emit(i.TASK_STARTED,{taskId:t,task:e}),this.notify(),this.scheduleTaskForce(e)}scheduleTaskForce(t){var e;try{const s=c(t.schedule,{timezone:(null==(e=t.options)?void 0:e.timezone)||this.config.timezone,lastRun:t.lastRun});t.nextRun=s.getTime();const i=Date.now(),r=Math.max(0,s.getTime()-i);this.log(`Scheduling task ${t.id} for ${s.toISOString()} (in ${r}ms)`);const n=this.getTimerStrategy(t).schedule(()=>{this.executeTaskIndividual(t)},r);this.timers.set(t.id,n)}catch(i){this.log(`Error scheduling task ${t.id}: ${i}`),t.status=s.ERROR,this.notify()}}async executeTaskIndividual(t,e=0){var r,n;if(this.timers.delete(t.id),t.status===s.STOPPED)return;t.status=s.RUNNING,t.lastRun=Date.now(),t.executionCount=(t.executionCount||0)+1;const o=Date.now();this.log(`Executing task: ${t.id} (Attempt ${e})`),this.emit(i.TASK_STARTED,{taskId:t.id,task:t}),this.notify();try{await t.handler();const e=Date.now()-o;this.recordHistory(t,{timestamp:o,duration:e,success:!0}),t.status=s.IDLE,this.log(`Task execution success: ${t.id}`),this.emit(i.TASK_COMPLETED,{taskId:t.id,task:t,duration:e}),this.notify(),this.scheduleTaskForce(t)}catch(a){const c=Date.now()-o;if(this.recordHistory(t,{timestamp:o,duration:c,success:!1,error:a.message}),this.log(`Task execution failed: ${t.id} - ${a.message}`),this.emit(i.TASK_FAILED,{taskId:t.id,task:t,error:a.message,duration:c}),null==(r=t.options)?void 0:r.onError)try{t.options.onError(a,t.id)}catch(l){this.log(`onError callback failed: ${l}`)}const d=u.getDelay(e,null==(n=t.options)?void 0:n.retry);if(d>=0){this.log(`Retrying task ${t.id} in ${d}ms (Attempt ${e+1})`);const i=this.getTimerStrategy(t).schedule(()=>{this.executeTaskIndividual(t,e+1)},d);this.timers.set(t.id,i),t.status=s.ERROR,this.notify()}else t.status=s.ERROR,this.notify(),this.scheduleTaskForce(t)}}stopTask(t){const e=this.registry.getTask(t),r=this.timers.get(t);r&&e?(this.getTimerStrategy(e).cancel(r),this.timers.delete(t)):r&&(this.defaultTimerStrategy.cancel(r),this.timers.delete(t)),e&&(e.status=s.STOPPED,this.log(`Task stopped: ${t}`),this.emit(i.TASK_STOPPED,{taskId:t,task:e}),this.notify())}getTask(t){return this.registry.getTask(t)}getAllTasks(t){return t?this.registry.getTasksByNamespace(t):this.registry.getAllTasks()}isRunning(){return this.running}getTaskDriver(t){var e;const s=this.registry.getTask(t);return s?(null==(e=s.options)?void 0:e.driver)||this.config.driver||"worker":this.config.driver||"worker"}getGlobalDriver(){return this.config.driver||"worker"}async triggerTask(t){const e=this.getTask(t);if(!e)return;if(e.status===s.RUNNING)return;const r=e.status;e.status=s.RUNNING,e.lastRun=Date.now(),e.executionCount=(e.executionCount||0)+1;const n=Date.now();this.log(`Triggering task: ${e.id}`),this.emit(i.TASK_STARTED,{taskId:e.id,task:e}),this.notify();try{await e.handler();const t=Date.now()-n;this.recordHistory(e,{timestamp:n,duration:t,success:!0}),e.status=r,this.log(`Task trigger success: ${e.id}`),this.emit(i.TASK_COMPLETED,{taskId:e.id,task:e,duration:t}),this.notify()}catch(o){const t=Date.now()-n;this.recordHistory(e,{timestamp:n,duration:t,success:!1,error:o.message}),this.log(`Task trigger failed: ${e.id} - ${o.message}`),this.emit(i.TASK_FAILED,{taskId:e.id,task:e,error:o.message,duration:t}),e.status=r,this.notify()}}start(t){if(!t&&this.running)return;this.log(t?`Scheduler starting for scope: ${t}`:"Scheduler started"),this.emit(i.SCHEDULER_STARTED,{running:!0,scope:t});(t?this.registry.getTasksByNamespace(t):this.registry.getAllTasks()).forEach(t=>{var e;t.status===s.STOPPED&&(t.status=s.IDLE,this.emit(i.TASK_UPDATED,{taskId:t.id,task:t})),t.status!==s.RUNNING&&((null==(e=t.options)?void 0:e.runImmediately)&&this.triggerTask(t.id),this.scheduleTask(t))}),t||(this.running=!0),this.notify()}stop(t){if(!t&&!this.running)return;this.log(t?`Scheduler stopping for scope: ${t}`:"Scheduler stopped"),this.emit(i.SCHEDULER_STOPPED,{running:!1,scope:t});(t?this.registry.getTasksByNamespace(t):this.registry.getAllTasks()).forEach(t=>{const e=this.timers.get(t.id);e&&(this.getTimerStrategy(t).cancel(e),this.timers.delete(t.id)),t.status!==s.STOPPED&&(t.status=s.STOPPED,this.emit(i.TASK_UPDATED,{taskId:t.id,task:t}))}),t||(this.running=!1),this.notify()}scheduleTask(t){var e;try{const s=c(t.schedule,{timezone:(null==(e=t.options)?void 0:e.timezone)||this.config.timezone,lastRun:t.lastRun});t.nextRun=s.getTime();const i=Date.now(),r=Math.max(0,s.getTime()-i);this.log(`Scheduling task ${t.id} for ${s.toISOString()} (in ${r}ms)`);const n=this.getTimerStrategy(t).schedule(()=>{this.executeTask(t)},r);this.timers.set(t.id,n)}catch(i){this.log(`Error scheduling task ${t.id}: ${i}`),t.status=s.ERROR}}async executeTask(t,e=0,r=!1){var n,o;if(this.timers.delete(t.id),!r&&t.status===s.STOPPED)return;t.status=s.RUNNING,t.lastRun=Date.now(),t.executionCount=(t.executionCount||0)+1;const a=Date.now();this.log(`Executing task: ${t.id} (Attempt ${e})`),this.emit(i.TASK_STARTED,{taskId:t.id,task:t}),this.notify();try{await t.handler();const e=Date.now()-a;this.recordHistory(t,{timestamp:a,duration:e,success:!0}),t.status=s.IDLE,this.log(`Task execution success: ${t.id}`),this.emit(i.TASK_COMPLETED,{taskId:t.id,task:t,duration:e}),this.notify(),this.scheduleTask(t)}catch(l){const r=Date.now()-a;if(this.recordHistory(t,{timestamp:a,duration:r,success:!1,error:l.message}),this.log(`Task execution failed: ${t.id} - ${l.message}`),this.emit(i.TASK_FAILED,{taskId:t.id,task:t,error:l.message,duration:r}),null==(n=t.options)?void 0:n.onError)try{t.options.onError(l,t.id)}catch(c){this.log(`onError callback failed: ${c}`)}const d=u.getDelay(e,null==(o=t.options)?void 0:o.retry);if(d>=0){this.log(`Retrying task ${t.id} in ${d}ms (Attempt ${e+1})`);const i=this.getTimerStrategy(t).schedule(()=>{this.executeTask(t,e+1)},d);this.timers.set(t.id,i),t.status=s.ERROR,this.notify()}else t.status=s.ERROR,this.notify(),this.scheduleTask(t)}}recordHistory(t,e){t.history.unshift(e),this.config.maxHistory&&t.history.length>this.config.maxHistory&&t.history.pop()}log(t){this.config.debug&&console.log(`[HyperScheduler] ${t}`)}};class h{schedule(t,e){return setTimeout(t,e)}cancel(t){clearTimeout(t)}}const g="IWZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2NvbnN0IGU9bmV3IE1hcDtzZWxmLm9ubWVzc2FnZT1zPT57Y29uc3R7aWQ6dCxkZWxheTpjLHR5cGU6bH09cy5kYXRhO2lmKCJzY2hlZHVsZSI9PT1sKXtjb25zdCBzPXNlbGYuc2V0VGltZW91dCgoKT0+e3NlbGYucG9zdE1lc3NhZ2Uoe2lkOnQsdHlwZToidGljayJ9KSxlLmRlbGV0ZSh0KX0sYyk7ZS5zZXQodCxzKX1lbHNlIGlmKCJjYW5jZWwiPT09bCl7Y29uc3Qgcz1lLmdldCh0KTt2b2lkIDAhPT1zJiYoc2VsZi5jbGVhclRpbWVvdXQocyksZS5kZWxldGUodCkpfX19KCk7Cg==",m="undefined"!=typeof self&&self.Blob&&new Blob([(k=g,Uint8Array.from(atob(k),t=>t.charCodeAt(0)))],{type:"text/javascript;charset=utf-8"});var k;function f(t){let e;try{if(e=m&&(self.URL||self.webkitURL).createObjectURL(m),!e)throw"";const s=new Worker(e,{name:null==t?void 0:t.name});return s.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(e)}),s}catch(s){return new Worker("data:text/javascript;base64,"+g,{name:null==t?void 0:t.name})}finally{e&&(self.URL||self.webkitURL).revokeObjectURL(e)}}class T{constructor(){e(this,"worker"),e(this,"callbacks"),e(this,"nextId"),this.worker=void 0!==f?new f:{postMessage:()=>{},onmessage:null,terminate:()=>{},addEventListener:()=>{},removeEventListener:()=>{},dispatchEvent:()=>!1},this.callbacks=new Map,this.nextId=1,this.worker.onmessage=t=>{const{id:e,type:s}=t.data;if("tick"===s){const t=this.callbacks.get(e);t&&(t(),this.callbacks.delete(e))}}}schedule(t,e){const s=this.nextId++;return this.callbacks.set(s,t),this.worker.postMessage({id:s,delay:e,type:"schedule"}),s}cancel(t){this.worker.postMessage({id:t,type:"cancel"}),this.callbacks.delete(t)}}class p{schedule(t,e){return window.setTimeout(t,e)}cancel(t){window.clearTimeout(t)}}const y="undefined"!=typeof window&&void 0!==window.document;let E=null,S=null;exports.CoreScheduler=d,exports.DevTools=class{constructor(t={}){e(this,"name","DevTools"),e(this,"options"),this.options=t}init(t){"undefined"!=typeof window&&void 0!==window.document&&this.mount(t)}async mount(t){try{await Promise.resolve().then(()=>require("./devtools-Bxtz0rO_.cjs")),await customElements.whenDefined("hs-devtools"),this.setupElement(t)}catch(e){console.error("[DevTools] Failed to mount:",e)}}setupElement(t){try{let e=document.querySelector("hs-devtools");e&&e.remove(),e=document.createElement("hs-devtools");const i=this.options;console.log("[DevTools Plugin] options:",JSON.stringify(i)),i.theme&&e.setAttribute("theme",i.theme),i.dockPosition&&e.setAttribute("dock",i.dockPosition),i.language&&e.setAttribute("language",i.language),i.defaultZoom&&e.setAttribute("default-zoom",i.defaultZoom.toString()),i.trigger&&(i.trigger.backgroundColor&&e.setAttribute("trigger-bg",i.trigger.backgroundColor),i.trigger.textColor&&e.setAttribute("trigger-color",i.trigger.textColor),i.trigger.position&&e.setAttribute("trigger-position",i.trigger.position)),console.log("[DevTools Plugin] attributes set:",e.getAttribute("dock"),e.getAttribute("trigger-position")),document.body.appendChild(e),"function"==typeof e.setScheduler?e.setScheduler({getTasks:()=>t.getAllTasks().map(e=>{var i;return{id:e.id,status:e.status,lastRun:e.lastRun||null,nextRun:e.nextRun||null,executionCount:e.executionCount||0,schedule:e.schedule,tags:e.tags||[],error:e.status===s.ERROR?"Execution failed":null,driver:t.getTaskDriver(e.id),namespace:(null==(i=e.options)?void 0:i.namespace)||"default"}}),on:(e,s)=>t.on(e,s),isRunning:()=>t.isRunning(),trigger:e=>t.triggerTask(e),pause:e=>t.stopTask(e),resume:e=>t.startTask(e),remove:e=>t.deleteTask(e)}):console.warn("[DevTools] hs-devtools element does not have setScheduler method.")}catch(e){console.error("[DevTools] Failed to setup element:",e)}}},exports.Scheduler=class extends d{constructor(t){super(function(t){if(y)return"main"===((null==t?void 0:t.driver)||"worker")?(S||(S=new p),S):(E||(E=new T),E);return new h}(t),t,function(){if(y)return t=>"main"===t?(S||(S=new p),S):(E||(E=new T),E)}())}},exports.SchedulerEvents=i,exports.TaskStatus=s;