Skip to content

Commit

Permalink
feat!: update API to use unified options object
Browse files Browse the repository at this point in the history
- Replace individual parameters with unified options object
- Add type-safe args array parameter for timer arguments
- Update documentation and examples
- Update all test cases
- Update playground demo

Before:
```ts
pausableTimers(callback, delay, options)
```
After:
```ts
pausableTimers({
  args: [callback, delay],
  ...options
})
```

BREAKING CHANGE: The API now accepts a single options object instead of separate parameters.
  • Loading branch information
byronogis committed Dec 28, 2024
1 parent ad14cc2 commit 806e829
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 65 deletions.
26 changes: 14 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ deno install pausable-timers
```ts
import { pausableTimers } from 'pausable-timers'

const timer = pausableTimers(() => {
/**
* Execute after 1 second
* 1s 后执行
*/
}, 1000, {
const timer = pausableTimers({
mode: 'interval', // 'timeout' | 'interval'
args: [() => {
/**
* Execute after 1 second
* 1s 后执行
*/
}, 1000]
})

timer.pause()
Expand All @@ -73,16 +74,17 @@ Customize the timeout/interval power, like using [worker-timers](https://github.
import { pausableTimers } from 'pausable-timers'
import { clearInterval, clearTimeout, setInterval, setTimeout } from 'worker-timers'

const timer = pausableTimers(() => {
/**
* Execute after 1 second
* 1s 后执行
*/
}, 1000, {
const timer = pausableTimers({
setTimeout,
setInterval,
clearTimeout,
clearInterval,
args: [() => {
/**
* Execute after 1 second
* 1s 后执行
*/
}, 1000,]
})
```

Expand Down
37 changes: 18 additions & 19 deletions playground/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,25 +93,24 @@ function startTimer() {
}

elements.statusText.textContent = ''
timer = pausableTimers(() => {
if (mode === 'timeout') {
cancelAnimationFrame(animationFrameId)
updateProgress(0, delay)
elements.statusText.textContent = 'Completed!'
updateButtons(false)
}
else {
// 在 interval 模式下,先取消动画帧
cancelAnimationFrame(animationFrameId)
// 立即重置进度条到 100%(无动画)
updateProgress(delay, delay)
// 在 interval 模式下添加循环次数显示
cycleCount++
elements.statusText.textContent = `Cycle ${cycleCount}`
// 立即开始新的倒计时(有动画)
requestAnimationFrame(() => animate(delay))
}
}, delay, { mode })
timer = pausableTimers({
args: [() => {
if (mode === 'timeout') {
cancelAnimationFrame(animationFrameId)
updateProgress(0, delay)
elements.statusText.textContent = 'Completed!'
updateButtons(false)
}
else {
cancelAnimationFrame(animationFrameId)
updateProgress(delay, delay)
cycleCount++
elements.statusText.textContent = `Cycle ${cycleCount}`
requestAnimationFrame(() => animate(delay))
}
}, delay],
mode,
})

updateButtons(true)
// 启动时也应用相同的逻辑
Expand Down
29 changes: 18 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,23 @@
* Creates a pausable timer that can be used as either a timeout or interval
* 创建一个可暂停的定时器,可用作超时或间隔计时器
*
* @param callback - Function to be executed when the timer triggers
* 定时器触发时执行的函数
* @param delay - Delay in milliseconds before the callback is executed
* 回调函数执行前的延迟时间(毫秒)
* @param options - Configuration options for the timer
* 定时器的配置选项
*/
export function pausableTimers(
callback: () => void,
delay: number, // milliseconds
options: PausableTimersOptions = {},
export function pausableTimers<T extends any[] = any[]>(
options: PausableTimersOptions<T>,
): PausableTimersReturns {
const {
mode = 'timeout',
setTimeout = globalThis.setTimeout,
setInterval = globalThis.setInterval,
clearTimeout = globalThis.clearTimeout,
clearInterval = globalThis.clearInterval,
args,
} = options

const [callback, delay, ...restArgs] = args

let timerId: ReturnType<typeof setTimeout> | null = null
let startTime = Date.now() // milliseconds since epoch
let remaining = delay // milliseconds
Expand Down Expand Up @@ -54,13 +51,13 @@ export function pausableTimers(
}

const _timeoutCallback = () => {
callback()
callback(...restArgs)
_clear(true)
completed = true
}

const _internalCallback = () => {
callback()
callback(...restArgs)
_resetState()
}

Expand Down Expand Up @@ -125,7 +122,17 @@ export function pausableTimers(
}
}

interface PausableTimersOptions {
interface PausableTimersOptions<T extends any[] = any[]> {
/**
* Timer arguments array
* 计时器参数数组,第一个参数为必传的回调函数,第二个参数为延迟时间,后续为可选的泛型参数数组
* 如果使用自定义计时器,参数需要与自定义计时器的参数定义保持一致
* @example
* - [() => console.log('test'), 0] // 立即执行
* - [() => console.log('test'), 1000] // 延迟1秒
* - [(name, age) => console.log(`${name}: ${age}`), 1000, 'World', 18] // 带类型的参数
*/
args: [handler: (...args: T) => void, delay: number, ...args: T]
/**
* Timer mode: 'timeout' or 'interval'
* 定时器模式:'timeout' 或 'interval'
Expand Down
Loading

0 comments on commit 806e829

Please sign in to comment.