@0xtld/tair-node
Version:
A Node.js package for Tair functionality with configuration, core, and helper modules.
107 lines (91 loc) • 2.96 kB
text/typescript
import { ColorTheme } from './colors';
const colors = new ColorTheme();
interface CountdownOptions {
showCursor?: boolean;
colors?: {
message?: string;
timer?: string;
reset?: string;
};
format?: string;
message?: string;
clearOnComplete?: boolean;
}
class CountdownTimer {
private options: CountdownOptions;
constructor(options: CountdownOptions = {}) {
this.options = {
showCursor: false,
colors: {
message: colors.colors.timerCount,
timer: colors.colors.timerWarn,
reset: colors.colors.reset,
},
format: 'HH:mm:ss',
message: 'Remaining time: ',
clearOnComplete: true,
...options,
};
}
private formatTime(timeInSeconds: number, format: string = this.options.format!): string {
const hours = Math.floor(timeInSeconds / 3600);
const minutes = Math.floor((timeInSeconds % 3600) / 60);
const seconds = timeInSeconds % 60;
const padNumber = (num: number) => num.toString().padStart(2, '0');
switch (format.toUpperCase()) {
case 'HH:MM:SS':
return `${padNumber(hours)}:${padNumber(minutes)}:${padNumber(seconds)}`;
case 'MM:SS':
return `${padNumber(minutes)}:${padNumber(seconds)}`;
case 'SS':
return padNumber(seconds);
case 'FULL':
return `${hours}h ${minutes}m ${seconds}s`;
case 'COMPACT':
return hours > 0
? `${hours}h${minutes}m`
: minutes > 0
? `${minutes}m${seconds}s`
: `${seconds}s`;
default:
return `${padNumber(hours)}:${padNumber(minutes)}:${padNumber(seconds)}`;
}
}
async start(seconds: number, options: CountdownOptions = {}): Promise<void> {
const config = { ...this.options, ...options };
if (!config.showCursor) {
process.stdout.write('\x1B[?25l');
}
const {
message,
} = config;
const messageColor = config.colors?.message || colors.colors.message;
const timerColor = config.colors?.timer || colors.colors.timerWarn;
const reset = config.colors?.reset || colors.colors.reset;
try {
for (let i = seconds; i > 0; i--) {
process.stdout.clearLine(0);
process.stdout.cursorTo(0);
const timeString = this.formatTime(i, config.format);
process.stdout.write(
`${messageColor}${message}${timerColor}${timeString}${reset}`
);
await new Promise((resolve) => setTimeout(resolve, 1000));
}
if (config.clearOnComplete) {
process.stdout.clearLine(0);
process.stdout.cursorTo(0);
}
} finally {
if (!config.showCursor) {
process.stdout.write('\x1B[?25h');
}
}
}
static async countdown(seconds: number, options: CountdownOptions = {}): Promise<void> {
const timer = new CountdownTimer(options);
await timer.start(seconds);
}
}
export { CountdownOptions, CountdownTimer };
export default CountdownTimer;