npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@brmtech/countdown

v0.1.0

Published

A TypeScript countdown and duration formatting utility.

Readme

@brmtech/countdown

一个轻量的 TypeScript 倒计时工具,提供秒数格式化、通用倒计时控制器,以及适合 Vue/React 等 UI 场景使用的数字拆分结果。

安装

npm install @brmtech/countdown

快速开始

import { createCountdown, formatDuration } from '@brmtech/countdown';

console.log(formatDuration(90));
// '00:00:01:30'

const countdown = createCountdown(90, {
  units: ['minute', 'second'],
  onTick(snapshot) {
    console.log(snapshot.formatted);
  },
  onFinish() {
    console.log('done');
  },
});

countdown.start();

导出的 API

import {
  formatDuration,
  createCountdown,
  useFormatTime,
} from '@brmtech/countdown';

默认导出为 useFormatTime

import useFormatTime from '@brmtech/countdown';

formatDuration(seconds, options?)

把总秒数格式化为字符串,或返回适合数字格子 UI 渲染的对象数组。

参数

| 参数 | 类型 | 必填 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | seconds | number \| string | 是 | - | 总秒数。负数、NaNInfinity 会按 0 处理;小数会向上取整。 | | options.units | CountdownUnit[] | 否 | ['day', 'hour', 'minute', 'second'] | 输出单位及顺序。可选值:daydayshourhoursminuteminutessecondseconds。省略更大单位时,剩余时间会累加到当前最大展示单位。 | | options.separator | string | 否 | ':' | returnTypestring 时,各单位之间的连接符。 | | options.labels | Partial<Record<CountdownUnit, string>> | 否 | {} | 单位标签,会追加在每个展示值后。 | | options.template | string | 否 | - | 自定义每个单位的字符串模板,支持 {value}{raw}{unit}{label}。 | | options.padZero | boolean | 否 | true | 是否把每个单位补齐到两位。 | | options.trimZero | boolean | 否 | false | 是否移除字符串输出中的前置零单位。 | | options.compact | boolean | 否 | false | trimZero 的别名。 | | options.returnType | 'string' \| 'object' | 否 | 'string' | 返回字符串或对象数组。 |

返回值

returnTypestring 时返回:

string

returnTypeobject 时返回:

Array<{
  key: CountdownUnit;
  value: string;
  digits: string[];
}>

示例

formatDuration(90061);
// '01:01:01:01'

formatDuration('90', {
  units: ['minute', 'second'],
});
// '01:30'

formatDuration(90061, {
  units: ['hours', 'minutes', 'seconds'],
  separator: '-',
});
// '25-01-01'

formatDuration(61, {
  units: ['minutes', 'seconds'],
  returnType: 'object',
});
// [
//   { key: 'minutes', value: '01', digits: ['0', '1'] },
//   { key: 'seconds', value: '01', digits: ['0', '1'] }
// ]

formatDuration(61, {
  units: ['minute', 'second'],
  padZero: false,
});
// '1:1'

formatDuration(90, {
  units: ['day', 'hour', 'minute', 'second'],
  labels: { minute: 'm', second: 's' },
  separator: ' ',
  compact: true,
});
// '01m 30s'

formatDuration(1.25, {
  units: ['second', 'millisecond'],
  labels: { second: 's', millisecond: 'ms' },
  separator: ' ',
  template: '{raw}{label}',
});
// '1s 250ms'

createCountdown(secondsOrOptions?, options?)

创建一个可开始、暂停、恢复、停止、重置和手动结束的倒计时控制器。它用结束时间计算真实剩余秒数,因此页面卡顿或定时器延迟时也会自动校正。

调用方式

createCountdown(90);
createCountdown('90', { units: ['minute', 'second'] });
createCountdown({ seconds: 90, autoStart: true });
createCountdown({ endTime: Date.now() + 10 * 60 * 1000 });

配置参数

| 参数 | 类型 | 必填 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | seconds | number \| string | 否 | 0 | 总秒数。 | | duration | number \| string | 否 | - | 总秒数,等同 seconds。 | | durationMs | number \| string | 否 | - | 总毫秒数,会转换为秒。 | | endTime | number \| string \| Date | 否 | - | 结束时间,支持秒级时间戳、毫秒级时间戳、日期字符串、Date。 | | targetTime | number \| string \| Date | 否 | - | 结束时间,等同 endTime。 | | interval | number | 否 | 1000 | 刷新间隔,单位毫秒。只影响回调频率,不影响真实剩余时间计算。 | | autoStart | boolean | 否 | false | 创建后是否自动开始。 | | immediate | boolean | 否 | true | startresetsetRemainingfinish 时是否立即触发一次 onTick。 | | units | CountdownUnit[] | 否 | ['day', 'hour', 'minute', 'second'] | 默认格式化单位。 | | separator | string | 否 | ':' | 默认格式化连接符。 | | padZero | boolean | 否 | true | 默认是否补零。 | | returnType | 'string' \| 'object' | 否 | 'string' | snapshot.formatted 的默认返回类型。 | | formatter | (remaining, formatOptions) => string \| DurationPart[] | 否 | formatDuration | 自定义格式化函数。 | | formatOptions | FormatDurationOptions | 否 | 当前配置对象 | 传给 formatter 的配置。 | | signal | AbortSignal | 否 | - | 外部中止信号,触发后会自动 stop()。 | | onTick | (snapshot) => void | 否 | - | 每次触发快照时调用。 | | onChange | (snapshot) => void | 否 | - | 公开控制方法改变状态或剩余时间后调用。 | | onStatusChange | (change) => void | 否 | - | idlerunningpausedstoppedfinished 状态变化时调用。 | | onFinish | (snapshot) => void | 否 | - | 当前这一轮倒计时归零时调用一次。 |

当第一个参数是对象时,会和第二个 options 合并,第二个 options 优先级更高。

返回控制器

| 属性/方法 | 类型 | 说明 | | --- | --- | --- | | start(seconds?) | (seconds?: number \| string \| CountdownOptions) => CountdownSnapshot | 开始倒计时。传入参数时会先重设总时长。 | | pause() | () => CountdownSnapshot | 暂停并保留当前剩余秒数。 | | resume(seconds?) | 同 start | 继续倒计时。它是 start 的别名。 | | stop() | () => CountdownSnapshot | 停止定时器并保留当前状态。 | | finish() | () => CountdownSnapshot | 立即归零,并触发 onFinish。 | | reset(seconds?) | (seconds?: number \| string \| CountdownOptions) => CountdownSnapshot | 重置倒计时;如果重置前正在运行,会继续运行。 | | restart(seconds?) | (seconds?: number \| string \| CountdownOptions) => CountdownSnapshot | 重置并立即开始。 | | add(seconds) | (seconds: number \| string \| CountdownOptions) => CountdownSnapshot | 给当前剩余时间增加秒数或配置中的时长。 | | subtract(seconds) | (seconds: number \| string \| CountdownOptions) => CountdownSnapshot | 从当前剩余时间扣减秒数或配置中的时长。 | | setRemaining(seconds) | (seconds: number \| string \| CountdownOptions) => CountdownSnapshot | 手动设置剩余秒数。 | | getSnapshot() | () => CountdownSnapshot | 获取当前快照。 | | remaining | number | 当前剩余秒数。 | | remainingMs | number | 当前剩余毫秒数。 | | parts | DurationPart[] | 当前拆分后的单位数组。 | | formatted | string \| DurationPart[] | 当前格式化结果。 | | progress | number | 当前进度,范围 01。 | | percent | number | 当前进度百分比,范围 0100。 | | status | 'idle' \| 'running' \| 'paused' \| 'stopped' \| 'finished' | 当前状态。 | | isRunning | boolean | 是否正在运行。 | | isFinished | boolean | 是否已归零。 |

CountdownSnapshot

interface CountdownSnapshot {
  total: number;
  totalMs: number;
  remaining: number;
  remainingMs: number;
  elapsed: number;
  elapsedMs: number;
  formatted: string | DurationPart[];
  parts: DurationPart[];
  progress: number;
  percent: number;
  status: 'idle' | 'running' | 'paused' | 'stopped' | 'finished';
  isRunning: boolean;
  isFinished: boolean;
}

| 字段 | 说明 | | --- | --- | | total | 本轮倒计时初始秒数。 | | totalMs | 本轮倒计时初始毫秒数。 | | remaining | 当前剩余秒数。 | | remainingMs | 当前剩余毫秒数。 | | elapsed | 已经过秒数。 | | elapsedMs | 已经过毫秒数。 | | formatted | 格式化后的展示值。 | | parts | 拆分后的单位数组,适合数字格子 UI。 | | progress | 当前进度,范围 01。 | | percent | 当前进度百分比,范围 0100。 | | status | 当前状态。 | | isRunning | 当前是否正在运行。 | | isFinished | 当前是否已归零。 |

示例:基础倒计时

const countdown = createCountdown(90, {
  units: ['minute', 'second'],
  onTick({ remaining, formatted }) {
    console.log(remaining, formatted);
  },
  onFinish() {
    console.log('done');
  },
});

countdown.start();

示例:接口返回字符串秒数

const countdown = createCountdown('90', {
  units: ['minute', 'second'],
  onTick({ formatted }) {
    console.log(formatted);
  },
});

countdown.start();

示例:按结束时间倒计时

const countdown = createCountdown({
  endTime: Date.now() + 10 * 60 * 1000,
  units: ['minute', 'second'],
  autoStart: true,
  onTick({ formatted }) {
    console.log(formatted);
  },
});

示例:数字格子 UI

const countdown = createCountdown(90061, {
  units: ['hours', 'minutes', 'seconds'],
  onTick({ parts }) {
    for (const part of parts) {
      console.log(part.key, part.digits);
    }
  },
});

countdown.start();

示例:formatted 直接返回对象数组

const countdown = createCountdown(90061, {
  returnType: 'object',
  onTick({ formatted }) {
    console.log(formatted);
  },
});

countdown.start();

示例:手动控制

const countdown = createCountdown(120);

countdown.start();
countdown.pause();
countdown.resume();
countdown.setRemaining(30);
countdown.reset(60);
countdown.finish();
countdown.stop();

示例:Vue 中使用

import { onMounted, onUnmounted, ref } from 'vue';
import { createCountdown } from '@brmtech/countdown';

const timeText = ref('00:00');

const countdown = createCountdown(90, {
  units: ['minute', 'second'],
  onTick({ formatted }) {
    timeText.value = String(formatted);
  },
  onFinish() {
    console.log('finish');
  },
});

onMounted(() => countdown.start());
onUnmounted(() => countdown.stop());

useFormatTime()

返回当前包提供的两个核心工具,适合在业务代码里统一注入或解构使用。

返回值

{
  formatDuration,
  createCountdown,
}

示例

import { useFormatTime } from '@brmtech/countdown';

const { formatDuration, createCountdown } = useFormatTime();

console.log(formatDuration(61, { units: ['minute', 'second'] }));

const countdown = createCountdown(10, {
  onFinish() {
    console.log('done');
  },
});

类型导出

import type {
  CountdownController,
  CountdownFormatter,
  CountdownOptions,
  CountdownSecondsInput,
  CountdownSnapshot,
  CountdownStartInput,
  CountdownTimeInput,
  CountdownUnit,
  DurationPart,
  FormatDurationOptions,
  FormattedDuration,
  FormatTimeHelpers,
} from '@brmtech/countdown';