mirror of
https://github.com/NotAShelf/nix-evaluator-stats.git
synced 2026-04-12 14:27:41 +00:00
treewide: adapt for monorepo layout; initial TUI work
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Id40b5f5ccb55a8a1ea2793192a38f0256a6a6964
This commit is contained in:
parent
e36b0d89da
commit
33ec901788
35 changed files with 1699 additions and 413 deletions
38
packages/ui-utils/README.md
Normal file
38
packages/ui-utils/README.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# @ns/ui-utils
|
||||
|
||||
Display formatting utilities for Nix evaluator statistics. Framework-agnostic
|
||||
number, byte, and time formatters.
|
||||
|
||||
## Usage
|
||||
|
||||
```typescript
|
||||
import {
|
||||
formatBytes,
|
||||
formatNumber,
|
||||
formatPercent,
|
||||
formatTime,
|
||||
} from "@ns/ui-utils";
|
||||
|
||||
// Format bytes
|
||||
console.log(formatBytes(1024)); // "1.00 KB"
|
||||
console.log(formatBytes(1048576)); // "1.00 MB"
|
||||
|
||||
// Format large numbers
|
||||
console.log(formatNumber(1234)); // "1.23K"
|
||||
console.log(formatNumber(1234567)); // "1.23M"
|
||||
|
||||
// Format time
|
||||
console.log(formatTime(0.0001)); // "100.00μs"
|
||||
console.log(formatTime(0.5)); // "500.00ms"
|
||||
console.log(formatTime(5.234)); // "5.234s"
|
||||
|
||||
// Format percentage
|
||||
console.log(formatPercent(0.123)); // "12.30%"
|
||||
```
|
||||
|
||||
## Design
|
||||
|
||||
All formatters are pure functions with no dependencies, making them easy to use
|
||||
in any UI framework (React, SolidJS, Vue, etc.) or in CLI [^1] applications.
|
||||
|
||||
[^1]: Could you have guessed that this is the main goal?
|
||||
20
packages/ui-utils/package.json
Normal file
20
packages/ui-utils/package.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "@ns/ui-utils",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"check": "tsc --noEmit"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
23
packages/ui-utils/src/formatters.ts
Normal file
23
packages/ui-utils/src/formatters.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
export function formatBytes(bytes: number): string {
|
||||
if (bytes === 0) return '0 B';
|
||||
const units = ['B', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log2(bytes) / 10);
|
||||
return `${(bytes / (1 << (i * 10))).toFixed(2)} ${units[i]}`;
|
||||
}
|
||||
|
||||
export function formatNumber(num: number): string {
|
||||
if (num >= 1e9) return (num / 1e9).toFixed(2) + 'B';
|
||||
if (num >= 1e6) return (num / 1e6).toFixed(2) + 'M';
|
||||
if (num >= 1e3) return (num / 1e3).toFixed(2) + 'K';
|
||||
return num.toString();
|
||||
}
|
||||
|
||||
export function formatTime(seconds: number): string {
|
||||
if (seconds < 0.001) return (seconds * 1e6).toFixed(2) + 'μs';
|
||||
if (seconds < 1) return (seconds * 1000).toFixed(2) + 'ms';
|
||||
return seconds.toFixed(3) + 's';
|
||||
}
|
||||
|
||||
export function formatPercent(value: number): string {
|
||||
return (value * 100).toFixed(2) + '%';
|
||||
}
|
||||
1
packages/ui-utils/src/index.ts
Normal file
1
packages/ui-utils/src/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from './formatters';
|
||||
18
packages/ui-utils/tsconfig.json
Normal file
18
packages/ui-utils/tsconfig.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"lib": ["ES2022"],
|
||||
"moduleResolution": "bundler",
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue