Download packages/pi-tui/src/components/loader.ts from SaylorTwift/kimi-code: direct link, hf CLI and curl.
- Browser
- Download file 2.81 kB
-
https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/pi-tui/src/components/loader.ts
- Command line
-
hf download hf://SaylorTwift/kimi-code/packages/pi-tui/src/components/loader.ts
-
curl -L -o loader.ts https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/pi-tui/src/components/loader.ts
2.81 kB
| import type { TUI } from "../tui.ts"; | |
| import { Text } from "./text.ts"; | |
| export interface LoaderIndicatorOptions { | |
| /** Animation frames. Use an empty array to hide the indicator. */ | |
| frames?: string[]; | |
| /** Frame interval in milliseconds for animated indicators. */ | |
| intervalMs?: number; | |
| } | |
| const DEFAULT_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]; | |
| const DEFAULT_INTERVAL_MS = 80; | |
| /** | |
| * Loader component that updates with an optional spinning animation. | |
| */ | |
| export class Loader extends Text { | |
| private frames = [...DEFAULT_FRAMES]; | |
| private intervalMs = DEFAULT_INTERVAL_MS; | |
| private currentFrame = 0; | |
| private intervalId: NodeJS.Timeout | null = null; | |
| private ui: TUI | null = null; | |
| private renderIndicatorVerbatim = false; | |
| private spinnerColorFn: (str: string) => string; | |
| private messageColorFn: (str: string) => string; | |
| private message: string = "Loading..."; | |
| constructor( | |
| ui: TUI, | |
| spinnerColorFn: (str: string) => string, | |
| messageColorFn: (str: string) => string, | |
| message: string = "Loading...", | |
| indicator?: LoaderIndicatorOptions, | |
| ) { | |
| super("", 1, 0); | |
| this.ui = ui; | |
| this.spinnerColorFn = spinnerColorFn; | |
| this.messageColorFn = messageColorFn; | |
| this.message = message; | |
| this.setIndicator(indicator); | |
| } | |
| override render(width: number): string[] { | |
| return ["", ...super.render(width)]; | |
| } | |
| start(): void { | |
| this.updateDisplay(); | |
| this.restartAnimation(); | |
| } | |
| stop(): void { | |
| if (this.intervalId) { | |
| clearInterval(this.intervalId); | |
| this.intervalId = null; | |
| } | |
| } | |
| setMessage(message: string): void { | |
| this.message = message; | |
| this.updateDisplay(); | |
| } | |
| override invalidate(): void { | |
| super.invalidate(); | |
| this.updateDisplay(); | |
| } | |
| setIndicator(indicator?: LoaderIndicatorOptions): void { | |
| this.renderIndicatorVerbatim = indicator !== undefined; | |
| this.frames = indicator?.frames !== undefined ? [...indicator.frames] : [...DEFAULT_FRAMES]; | |
| this.intervalMs = indicator?.intervalMs && indicator.intervalMs > 0 ? indicator.intervalMs : DEFAULT_INTERVAL_MS; | |
| this.currentFrame = 0; | |
| this.start(); | |
| } | |
| private restartAnimation(): void { | |
| this.stop(); | |
| if (this.frames.length <= 1) { | |
| return; | |
| } | |
| this.intervalId = setInterval(() => { | |
| this.currentFrame = (this.currentFrame + 1) % this.frames.length; | |
| this.updateDisplay(); | |
| }, this.intervalMs); | |
| } | |
| protected getRenderedIndicator(): string { | |
| const frame = this.frames[this.currentFrame] ?? ""; | |
| return this.renderIndicatorVerbatim ? frame : this.spinnerColorFn(frame); | |
| } | |
| private updateDisplay(): void { | |
| const renderedFrame = this.getRenderedIndicator(); | |
| const indicator = renderedFrame.length > 0 ? `${renderedFrame} ` : ""; | |
| this.setText(`${indicator}${this.messageColorFn(this.message)}`); | |
| if (this.ui) { | |
| this.ui.requestRender(); | |
| } | |
| } | |
| } | |