about-system 0.10.11 → 0.10.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,7 +15,7 @@ declare function battery(context: InfoContext): string;
15
15
  * Uses fuzzy matching to find similar CPU models
16
16
  * @param context - Info context with cache
17
17
  * @returns Benchmark info with score and rank, or empty string
18
- * @example "38k #1 top 1%", "21k #68 top 7%"
18
+ * @example "38k #1 Top 1%", "21k #68 Top 7%"
19
19
  */
20
20
  declare function bench(context: InfoContext): string;
21
21
 
@@ -74,7 +74,7 @@ declare function cpu(context: InfoContext): string;
74
74
  * Includes score, rank, and architecture type (ARM/Intel/AMD)
75
75
  * @param context - Info context with cache
76
76
  * @returns Detailed benchmark info with architecture, or empty string
77
- * @example "Geekbench 6: 38k (Rank #1, top 1%) - ARM", "Geekbench 6: 21k (Rank #68, top 7%) - Intel"
77
+ * @example "Geekbench 6: 38k (Rank #1, Top 1%) - ARM", "Geekbench 6: 21k (Rank #68, Top 7%) - Intel"
78
78
  */
79
79
  declare function cpu_bench_info(context: InfoContext): string;
80
80
 
@@ -142,7 +142,7 @@ declare function gpu(context: InfoContext): string;
142
142
  * Uses fuzzy matching to find similar GPU models
143
143
  * @param context - Info context with cache
144
144
  * @returns Benchmark info with score and rank, or empty string
145
- * @example "38k #1 top 1%", "21k #68 top 7%"
145
+ * @example "38k #1 Top 1%", "21k #68 Top 7%"
146
146
  */
147
147
  declare function gpu_bench(context: InfoContext): string;
148
148
 
@@ -151,7 +151,7 @@ declare function gpu_bench(context: InfoContext): string;
151
151
  * Includes score, rank, and vendor detection
152
152
  * @param context - Info context with cache
153
153
  * @returns Detailed benchmark info with vendor, or empty string
154
- * @example "Geekbench 6: 38k (Rank #1, top 1%) - NVIDIA", "Geekbench 6: 21k (Rank #68, top 7%) - AMD"
154
+ * @example "Geekbench 6: 38k (Rank #1, Top 1%) - NVIDIA", "Geekbench 6: 21k (Rank #68, Top 7%) - AMD"
155
155
  */
156
156
  declare function gpu_bench_info(context: InfoContext): string;
157
157
 
@@ -1,6 +1,6 @@
1
1
  import "os";
2
2
  import "fs";
3
- import { g as i, i as m, l as r, s as n } from "./system-info-api-D85U-_0W.js";
3
+ import { g as i, i as m, l as r, s as n } from "./system-info-api-7iy1ZV2o.js";
4
4
  import "path";
5
5
  export {
6
6
  i as getSystemInfo,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "about-system",
3
- "version": "0.10.11",
3
+ "version": "0.10.13",
4
4
  "description": "A Node.js script to display key system information with emojis. Cross-platform support for Windows, macOS, and Linux with customizable output and caching.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,28 +1,43 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import { formatBench, topPercent } from "./hardware";
3
3
 
4
+ /** Builds a table of `count` entries at each score, highest first. */
5
+ function table(groups: [score: number, count: number][]): number[] {
6
+ return groups.flatMap(([score, count]) => Array<number>(count).fill(score));
7
+ }
8
+
4
9
  describe("topPercent", () => {
5
- it("rounds up so the fastest entry reads top 1%", () => {
6
- expect(topPercent(1, 1000)).toBe(1);
7
- expect(topPercent(68, 1000)).toBe(7);
8
- expect(topPercent(50, 1000)).toBe(5);
10
+ // 1,000 entries: 4 at 100, 18 at 99, 35 at 98, 80 at 97, rest at 50
11
+ const scores = table([[100, 4], [99, 18], [98, 35], [97, 80], [50, 863]]);
12
+
13
+ it("grades by how many score strictly higher, so ties share a bucket", () => {
14
+ expect(topPercent(100, scores)).toBe(1);
15
+ expect(topPercent(99, scores)).toBe(1);
16
+ expect(topPercent(98, scores)).toBe(3);
17
+ expect(topPercent(97, scores)).toBe(6);
18
+ });
19
+
20
+ it("keeps a large tie together instead of splitting it by rank", () => {
21
+ const tied = table([[100, 50], [90, 950]]);
22
+ expect(topPercent(100, tied)).toBe(1);
23
+ expect(topPercent(90, tied)).toBe(5);
9
24
  });
10
25
 
11
26
  it("stays within 1..100", () => {
12
- expect(topPercent(1000, 1000)).toBe(100);
13
- expect(topPercent(1200, 1000)).toBe(100);
14
- expect(topPercent(5, 0)).toBe(100);
27
+ expect(topPercent(1, table([[10, 999], [1, 1]]))).toBe(100);
28
+ expect(topPercent(5, [])).toBe(100);
15
29
  });
16
30
  });
17
31
 
18
32
  describe("formatBench", () => {
19
- it("rounds the score to whole thousands and appends the percentile", () => {
20
- expect(formatBench(37967, 1, 1000)).toBe("38k #1 top 1%");
21
- expect(formatBench(20512, 68, 1000)).toBe("21k #68 top 7%");
22
- expect(formatBench(386779, 5, 1026)).toBe("387k #5 top 1%");
33
+ const scores = table([[37967, 1], [30000, 66], [20512, 1], [10000, 932]]);
34
+
35
+ it("rounds the score to whole thousands and appends the Top percentile", () => {
36
+ expect(formatBench(37967, 1, scores)).toBe("38k #1 Top 1%");
37
+ expect(formatBench(20512, 68, scores)).toBe("21k #68 Top 7%");
23
38
  });
24
39
 
25
40
  it("never prints a decimal in the score", () => {
26
- expect(formatBench(19249, 91, 1000)).not.toMatch(/\d\.\d/);
41
+ expect(formatBench(19249, 91, scores)).not.toMatch(/\d\.\d/);
27
42
  });
28
43
  });
@@ -12,27 +12,30 @@ import { getCachedValue, setCachedValue } from "../cache/cache";
12
12
  import Fuse from "fuse.js";
13
13
 
14
14
  /**
15
- * Formats a Geekbench score in whole thousands with its rank and how far up
16
- * the table that rank sits.
15
+ * Formats a Geekbench score in whole thousands with its rank and the share of
16
+ * the table scoring above it.
17
17
  * @param score - Raw Geekbench score
18
18
  * @param rank - Rank in the benchmark table (1 = fastest)
19
- * @param total - Number of entries in the benchmark table
19
+ * @param scores - Every score in the benchmark table
20
20
  * @returns Score, rank and top percentile
21
- * @example formatBench(20512, 68, 1500) // "21k #68 top 7%"
21
+ * @example formatBench(20512, 68, scores) // "21k #68 Top 7%"
22
22
  */
23
- export function formatBench(score: number, rank: number, total: number): string {
24
- return `${Math.round(score / 1000)}k #${rank} top ${topPercent(rank, total)}%`;
23
+ export function formatBench(score: number, rank: number, scores: number[]): string {
24
+ return `${Math.round(score / 1000)}k #${rank} Top ${topPercent(score, scores)}%`;
25
25
  }
26
26
 
27
27
  /**
28
- * Percentile bucket a rank falls in, rounded up so rank 1 reads "top 1%"
29
- * @param rank - Rank in the benchmark table (1 = fastest)
30
- * @param total - Number of entries in the benchmark table
28
+ * Score-based top percentile with ties: the share of entries scoring strictly
29
+ * higher, rounded up, so every entry with the same score shares one bucket and
30
+ * the fastest scores all read "Top 1%".
31
+ * @param score - Raw Geekbench score
32
+ * @param scores - Every score in the benchmark table
31
33
  * @returns Whole percentage between 1 and 100
32
34
  */
33
- export function topPercent(rank: number, total: number): number {
34
- if (!total || total < 1) return 100;
35
- return Math.min(100, Math.max(1, Math.ceil((rank / total) * 100)));
35
+ export function topPercent(score: number, scores: number[]): number {
36
+ if (!scores.length) return 100;
37
+ const above = scores.filter((s) => s > score).length;
38
+ return Math.min(100, Math.max(1, Math.ceil((above / scores.length) * 100)));
36
39
  }
37
40
 
38
41
  /**
@@ -246,7 +249,7 @@ export function screen_resolution(): string {
246
249
  * Uses fuzzy matching to find similar CPU models
247
250
  * @param context - Info context with cache
248
251
  * @returns Benchmark info with score and rank, or empty string
249
- * @example "38k #1 top 1%", "21k #68 top 7%"
252
+ * @example "38k #1 Top 1%", "21k #68 Top 7%"
250
253
  */
251
254
  export function bench(context: InfoContext): string {
252
255
  const cached = getCachedValue(context.cache, "bench");
@@ -298,7 +301,7 @@ export function bench(context: InfoContext): string {
298
301
  const results = fuse.search(cpuName);
299
302
  if (results.length > 0) {
300
303
  const match = results[0].item;
301
- const result = formatBench(match.score, match.rank, scores.length);
304
+ const result = formatBench(match.score, match.rank, scores.map((item) => item[1]));
302
305
  setCachedValue(context.cache, "bench", result);
303
306
  return result;
304
307
  }
@@ -315,7 +318,7 @@ export function bench(context: InfoContext): string {
315
318
  * Includes score, rank, and architecture type (ARM/Intel/AMD)
316
319
  * @param context - Info context with cache
317
320
  * @returns Detailed benchmark info with architecture, or empty string
318
- * @example "Geekbench 6: 38k (Rank #1, top 1%) - ARM", "Geekbench 6: 21k (Rank #68, top 7%) - Intel"
321
+ * @example "Geekbench 6: 38k (Rank #1, Top 1%) - ARM", "Geekbench 6: 21k (Rank #68, Top 7%) - Intel"
319
322
  */
320
323
  export function cpu_bench_info(context: InfoContext): string {
321
324
  const cached = getCachedValue(context.cache, "cpu_bench_info");
@@ -373,7 +376,7 @@ export function cpu_bench_info(context: InfoContext): string {
373
376
  const match = results[0].item;
374
377
  const score = Math.round(match.score / 1000);
375
378
  const rank = match.rank;
376
- const top = topPercent(rank, scores.length);
379
+ const top = topPercent(match.score, scores.map((item) => item[1]));
377
380
 
378
381
  // Detect architecture type
379
382
  let arch = "Unknown";
@@ -387,7 +390,7 @@ export function cpu_bench_info(context: InfoContext): string {
387
390
  arch = "ARM";
388
391
  }
389
392
 
390
- const result = `Geekbench 6: ${score}k (Rank #${rank}, top ${top}%) - ${arch}`;
393
+ const result = `Geekbench 6: ${score}k (Rank #${rank}, Top ${top}%) - ${arch}`;
391
394
  setCachedValue(context.cache, "cpu_bench_info", result);
392
395
  return result;
393
396
  }
@@ -404,7 +407,7 @@ export function cpu_bench_info(context: InfoContext): string {
404
407
  * Uses fuzzy matching to find similar GPU models
405
408
  * @param context - Info context with cache
406
409
  * @returns Benchmark info with score and rank, or empty string
407
- * @example "38k #1 top 1%", "21k #68 top 7%"
410
+ * @example "38k #1 Top 1%", "21k #68 Top 7%"
408
411
  */
409
412
  export function gpu_bench(context: InfoContext): string {
410
413
  const cached = getCachedValue(context.cache, "gpu_bench");
@@ -456,7 +459,7 @@ export function gpu_bench(context: InfoContext): string {
456
459
  const results = fuse.search(gpuName);
457
460
  if (results.length > 0) {
458
461
  const match = results[0].item;
459
- const result = formatBench(match.score, match.rank, scores.length);
462
+ const result = formatBench(match.score, match.rank, scores.map((item) => item[1]));
460
463
  setCachedValue(context.cache, "gpu_bench", result);
461
464
  return result;
462
465
  }
@@ -473,7 +476,7 @@ export function gpu_bench(context: InfoContext): string {
473
476
  * Includes score, rank, and vendor detection
474
477
  * @param context - Info context with cache
475
478
  * @returns Detailed benchmark info with vendor, or empty string
476
- * @example "Geekbench 6: 38k (Rank #1, top 1%) - NVIDIA", "Geekbench 6: 21k (Rank #68, top 7%) - AMD"
479
+ * @example "Geekbench 6: 38k (Rank #1, Top 1%) - NVIDIA", "Geekbench 6: 21k (Rank #68, Top 7%) - AMD"
477
480
  */
478
481
  export function gpu_bench_info(context: InfoContext): string {
479
482
  const cached = getCachedValue(context.cache, "gpu_bench_info");
@@ -531,7 +534,7 @@ export function gpu_bench_info(context: InfoContext): string {
531
534
  const match = results[0].item;
532
535
  const score = Math.round(match.score / 1000);
533
536
  const rank = match.rank;
534
- const top = topPercent(rank, scores.length);
537
+ const top = topPercent(match.score, scores.map((item) => item[1]));
535
538
 
536
539
  // Detect vendor from GPU name
537
540
  let vendor = "Unknown";
@@ -554,7 +557,7 @@ export function gpu_bench_info(context: InfoContext): string {
554
557
  vendor = "Intel";
555
558
  }
556
559
 
557
- const result = `Geekbench 6: ${score}k (Rank #${rank}, top ${top}%) - ${vendor}`;
560
+ const result = `Geekbench 6: ${score}k (Rank #${rank}, Top ${top}%) - ${vendor}`;
558
561
  setCachedValue(context.cache, "gpu_bench_info", result);
559
562
  return result;
560
563
  }
@@ -125,12 +125,12 @@ export interface SystemInfo {
125
125
  /**
126
126
  * CPU benchmark score from Geekbench 6 multi-core
127
127
  * Shows performance score (in thousands) and ranking position
128
- * Uses fuzzy matching to find similar CPU models from top 1000 list
128
+ * Uses fuzzy matching to find similar CPU models from Top 1000 list
129
129
  * Empty string if CPU not found or benchmark data unavailable
130
130
  *
131
131
  * @example
132
- * - "38k #1 top 1%" (top performing CPU)
133
- * - "21k #68 top 7%" (mid-range CPU)
132
+ * - "38k #1 Top 1%" (top performing CPU)
133
+ * - "21k #68 Top 7%" (mid-range CPU)
134
134
  * - "" (CPU not in benchmark database)
135
135
  */
136
136
  bench: string;
@@ -142,9 +142,9 @@ export interface SystemInfo {
142
142
  * Empty string if CPU not found or benchmark data unavailable
143
143
  *
144
144
  * @example
145
- * - "Geekbench 6: 38k (Rank #1, top 1%) - ARM" (Apple M4 Ultra)
146
- * - "Geekbench 6: 21k (Rank #68, top 7%) - Intel" (Intel Core i9)
147
- * - "Geekbench 6: 19k (Rank #91, top 10%) - AMD" (AMD Ryzen 9 7950X)
145
+ * - "Geekbench 6: 38k (Rank #1, Top 1%) - ARM" (Apple M4 Ultra)
146
+ * - "Geekbench 6: 21k (Rank #68, Top 7%) - Intel" (Intel Core i9)
147
+ * - "Geekbench 6: 19k (Rank #91, Top 10%) - AMD" (AMD Ryzen 9 7950X)
148
148
  * - "" (CPU not in benchmark database)
149
149
  */
150
150
  cpu_bench_info: string;
@@ -156,8 +156,8 @@ export interface SystemInfo {
156
156
  * Empty string if GPU not found or benchmark data unavailable
157
157
  *
158
158
  * @example
159
- * - "38k #1 top 1%" (top performing GPU)
160
- * - "21k #68 top 7%" (mid-range GPU)
159
+ * - "38k #1 Top 1%" (top performing GPU)
160
+ * - "21k #68 Top 7%" (mid-range GPU)
161
161
  * - "" (GPU not in benchmark database)
162
162
  */
163
163
  gpu_bench: string;
@@ -169,8 +169,8 @@ export interface SystemInfo {
169
169
  * Empty string if GPU not found or benchmark data unavailable
170
170
  *
171
171
  * @example
172
- * - "Geekbench 6: 38k (Rank #1, top 1%) - NVIDIA" (NVIDIA GPU)
173
- * - "Geekbench 6: 21k (Rank #68, top 7%) - AMD" (AMD GPU)
172
+ * - "Geekbench 6: 38k (Rank #1, Top 1%) - NVIDIA" (NVIDIA GPU)
173
+ * - "Geekbench 6: 21k (Rank #68, Top 7%) - AMD" (AMD GPU)
174
174
  * - "" (GPU not in benchmark database)
175
175
  */
176
176
  gpu_bench_info: string;