@fuzdev/fuz_util 0.43.0 → 0.44.1

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.
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- The MIT License (MIT)
1
+ MIT License
2
2
 
3
3
  Copyright (c) fuz.dev
4
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"benchmark_baseline.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/benchmark_baseline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"benchmark_baseline.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/benchmark_baseline.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,9 @@ import { readFile, writeFile, mkdir, rm } from 'node:fs/promises';
6
6
  import { join } from 'node:path';
7
7
  import { z } from 'zod';
8
8
  import { fs_exists } from './fs.js';
9
+ import { git_info_get } from './git.js';
9
10
  import { benchmark_stats_compare, } from './benchmark_stats.js';
11
+ import { stats_confidence_interval_from_summary } from './stats.js';
10
12
  // Version for forward compatibility - increment when schema changes
11
13
  const BASELINE_VERSION = 1;
12
14
  /**
@@ -39,15 +41,6 @@ export const BenchmarkBaseline = z.object({
39
41
  });
40
42
  const DEFAULT_BASELINE_PATH = '.gro/benchmarks';
41
43
  const BASELINE_FILENAME = 'baseline.json';
42
- /** Z-score for 95% confidence interval */
43
- const Z_95 = 1.96;
44
- /**
45
- * Calculate 95% confidence interval from mean, std_dev, and sample_size.
46
- */
47
- const calculate_confidence_interval = (mean, std_dev, sample_size) => {
48
- const margin = Z_95 * (std_dev / Math.sqrt(sample_size));
49
- return [mean - margin, mean + margin];
50
- };
51
44
  /**
52
45
  * Convert benchmark results to baseline entries.
53
46
  */
@@ -67,26 +60,6 @@ const results_to_entries = (results) => {
67
60
  sample_size: r.stats.sample_size,
68
61
  }));
69
62
  };
70
- /**
71
- * Try to get git info from the environment or git commands.
72
- */
73
- const get_git_info = async () => {
74
- try {
75
- const { promisify } = await import('node:util');
76
- const exec = promisify((await import('node:child_process')).exec);
77
- const [commit_result, branch_result] = await Promise.all([
78
- exec('git rev-parse HEAD').catch(() => ({ stdout: '' })),
79
- exec('git rev-parse --abbrev-ref HEAD').catch(() => ({ stdout: '' })),
80
- ]);
81
- return {
82
- commit: commit_result.stdout.trim() || null,
83
- branch: branch_result.stdout.trim() || null,
84
- };
85
- }
86
- catch {
87
- return { commit: null, branch: null };
88
- }
89
- };
90
63
  /**
91
64
  * Save benchmark results as the current baseline.
92
65
  *
@@ -107,7 +80,7 @@ export const benchmark_baseline_save = async (results, options = {}) => {
107
80
  let git_commit = options.git_commit;
108
81
  let git_branch = options.git_branch;
109
82
  if (git_commit === undefined || git_branch === undefined) {
110
- const git_info = await get_git_info();
83
+ const git_info = await git_info_get();
111
84
  git_commit ??= git_info.commit;
112
85
  git_branch ??= git_info.branch;
113
86
  }
@@ -234,13 +207,13 @@ export const benchmark_baseline_compare = async (results, options = {}) => {
234
207
  mean_ns: baseline_entry.mean_ns,
235
208
  std_dev_ns: baseline_entry.std_dev_ns,
236
209
  sample_size: baseline_entry.sample_size,
237
- confidence_interval_ns: calculate_confidence_interval(baseline_entry.mean_ns, baseline_entry.std_dev_ns, baseline_entry.sample_size),
210
+ confidence_interval_ns: stats_confidence_interval_from_summary(baseline_entry.mean_ns, baseline_entry.std_dev_ns, baseline_entry.sample_size),
238
211
  };
239
212
  const current_stats = {
240
213
  mean_ns: current.mean_ns,
241
214
  std_dev_ns: current.std_dev_ns,
242
215
  sample_size: current.sample_size,
243
- confidence_interval_ns: calculate_confidence_interval(current.mean_ns, current.std_dev_ns, current.sample_size),
216
+ confidence_interval_ns: stats_confidence_interval_from_summary(current.mean_ns, current.std_dev_ns, current.sample_size),
244
217
  };
245
218
  const comparison = benchmark_stats_compare(baseline_stats, current_stats);
246
219
  const task_comparison = {
@@ -8,19 +8,13 @@ import type { BenchmarkResult, BenchmarkGroup } from './benchmark_types.js';
8
8
  * @example
9
9
  * ```ts
10
10
  * console.log(benchmark_format_table(results));
11
- * // ┌────┬─────────────┬────────────┬────────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐
12
- * // │ Task Name │ ops/sec │ median(μs) │ p75 (μs) │ p90 (μs) │ p95 (μs) │ p99 (μs) │ min (μs) │ max (μs) │ vs Best │
13
- * // ├────┼─────────────┼────────────┼────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
14
- * // │ 🐇 │ slugify v2 │ 1,237,144 │ 0.81 │ 0.85 │ 0.89 │ 0.95 │ 1.20 │ 0.72 │ 2.45 │ baseline │
15
- * // │ 🐢 │ slugify │ 261,619 │ 3.82 │ 3.95 │ 4.12 │ 4.35 │ 5.10 │ 3.21 │ 12.45 │ 4.73x │
16
- * // └────┴─────────────┴────────────┴────────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘
11
+ * // ┌─────────────┬────────────┬────────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐
12
+ * // │ Task Name │ ops/sec │ median(μs) │ p75 (μs) │ p90 (μs) │ p95 (μs) │ p99 (μs) │ min (μs) │ max (μs) │ vs Best │
13
+ * // ├─────────────┼────────────┼────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
14
+ * // │ slugify v2 │ 1,237,144 │ 0.81 │ 0.85 │ 0.89 │ 0.95 │ 1.20 │ 0.72 │ 2.45 │ baseline │
15
+ * // │ slugify │ 261,619 │ 3.82 │ 3.95 │ 4.12 │ 4.35 │ 5.10 │ 3.21 │ 12.45 │ 4.73x │
16
+ * // └─────────────┴────────────┴────────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘
17
17
  * ```
18
- *
19
- * **Performance tier animals:**
20
- * - 🐆 Cheetah: >1M ops/sec (extremely fast)
21
- * - 🐇 Rabbit: >100K ops/sec (fast)
22
- * - 🐢 Turtle: >10K ops/sec (moderate)
23
- * - 🐌 Snail: <10K ops/sec (slow)
24
18
  */
25
19
  export declare const benchmark_format_table: (results: Array<BenchmarkResult>) => string;
26
20
  /**
@@ -87,6 +81,7 @@ export declare const benchmark_format_json: (results: Array<BenchmarkResult>, op
87
81
  export declare const benchmark_format_table_grouped: (results: Array<BenchmarkResult>, groups: Array<BenchmarkGroup>) => string;
88
82
  /**
89
83
  * Format a number with fixed decimal places and thousands separators.
84
+ * @see {@link format_number} in maths.ts for the underlying implementation.
90
85
  */
91
86
  export declare const benchmark_format_number: (n: number, decimals?: number) => string;
92
87
  //# sourceMappingURL=benchmark_format.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"benchmark_format.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/benchmark_format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,eAAe,EAAE,cAAc,EAAC,MAAM,sBAAsB,CAAC;AA8C1E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,sBAAsB,GAAI,SAAS,KAAK,CAAC,eAAe,CAAC,KAAG,MAmFxE,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,yBAAyB,GAAI,SAAS,KAAK,CAAC,eAAe,CAAC,KAAG,MA4E3E,CAAC;AAEF,MAAM,WAAW,0BAA0B;IAC1C,8CAA8C;IAC9C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0EAA0E;IAC1E,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,GACjC,SAAS,KAAK,CAAC,eAAe,CAAC,EAC/B,UAAU,0BAA0B,KAClC,MA6BF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,8BAA8B,GAC1C,SAAS,KAAK,CAAC,eAAe,CAAC,EAC/B,QAAQ,KAAK,CAAC,cAAc,CAAC,KAC3B,MA2BF,CAAC;AAGF;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAAI,GAAG,MAAM,EAAE,WAAU,MAAU,KAAG,MAGzE,CAAC"}
1
+ {"version":3,"file":"benchmark_format.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/benchmark_format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,eAAe,EAAE,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAK1E;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,sBAAsB,GAAI,SAAS,KAAK,CAAC,eAAe,CAAC,KAAG,MAiFxE,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,yBAAyB,GAAI,SAAS,KAAK,CAAC,eAAe,CAAC,KAAG,MA4E3E,CAAC;AAEF,MAAM,WAAW,0BAA0B;IAC1C,8CAA8C;IAC9C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0EAA0E;IAC1E,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,GACjC,SAAS,KAAK,CAAC,eAAe,CAAC,EAC/B,UAAU,0BAA0B,KAClC,MA6BF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,8BAA8B,GAC1C,SAAS,KAAK,CAAC,eAAe,CAAC,EAC/B,QAAQ,KAAK,CAAC,cAAc,CAAC,KAC3B,MA2BF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,0CAAgB,CAAC"}
@@ -1,41 +1,6 @@
1
- import { time_unit_detect_best, time_format } from './time.js';
2
- /**
3
- * Calculate the display width of a string in terminal columns.
4
- * Emojis and other wide characters take 2 columns.
5
- */
6
- const string_display_width = (str) => {
7
- let width = 0;
8
- for (const char of str) {
9
- const code = char.codePointAt(0);
10
- // Emoji and other wide characters (rough heuristic)
11
- // - Most emoji are in range 0x1F300-0x1FAFF
12
- // - Some are in 0x2600-0x27BF (misc symbols)
13
- // - CJK characters 0x4E00-0x9FFF also double-width but not handling here
14
- if ((code >= 0x1f300 && code <= 0x1faff) ||
15
- (code >= 0x2600 && code <= 0x27bf) ||
16
- (code >= 0x1f600 && code <= 0x1f64f) ||
17
- (code >= 0x1f680 && code <= 0x1f6ff)) {
18
- width += 2;
19
- }
20
- else {
21
- width += 1;
22
- }
23
- }
24
- return width;
25
- };
26
- /**
27
- * Pad a string to a target display width (accounting for wide characters).
28
- */
29
- const pad_to_width = (str, target_width, align = 'left') => {
30
- const current_width = string_display_width(str);
31
- const padding = Math.max(0, target_width - current_width);
32
- if (align === 'left') {
33
- return str + ' '.repeat(padding);
34
- }
35
- else {
36
- return ' '.repeat(padding) + str;
37
- }
38
- };
1
+ import { time_unit_detect_best, time_format, TIME_UNIT_DISPLAY } from './time.js';
2
+ import { string_display_width, pad_width } from './string.js';
3
+ import { format_number } from './maths.js';
39
4
  /**
40
5
  * Format results as an ASCII table with percentiles, min/max, and relative performance.
41
6
  * All times use the same unit for easy comparison.
@@ -45,19 +10,13 @@ const pad_to_width = (str, target_width, align = 'left') => {
45
10
  * @example
46
11
  * ```ts
47
12
  * console.log(benchmark_format_table(results));
48
- * // ┌────┬─────────────┬────────────┬────────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐
49
- * // │ Task Name │ ops/sec │ median(μs) │ p75 (μs) │ p90 (μs) │ p95 (μs) │ p99 (μs) │ min (μs) │ max (μs) │ vs Best │
50
- * // ├────┼─────────────┼────────────┼────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
51
- * // │ 🐇 │ slugify v2 │ 1,237,144 │ 0.81 │ 0.85 │ 0.89 │ 0.95 │ 1.20 │ 0.72 │ 2.45 │ baseline │
52
- * // │ 🐢 │ slugify │ 261,619 │ 3.82 │ 3.95 │ 4.12 │ 4.35 │ 5.10 │ 3.21 │ 12.45 │ 4.73x │
53
- * // └────┴─────────────┴────────────┴────────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘
13
+ * // ┌─────────────┬────────────┬────────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐
14
+ * // │ Task Name │ ops/sec │ median(μs) │ p75 (μs) │ p90 (μs) │ p95 (μs) │ p99 (μs) │ min (μs) │ max (μs) │ vs Best │
15
+ * // ├─────────────┼────────────┼────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
16
+ * // │ slugify v2 │ 1,237,144 │ 0.81 │ 0.85 │ 0.89 │ 0.95 │ 1.20 │ 0.72 │ 2.45 │ baseline │
17
+ * // │ slugify │ 261,619 │ 3.82 │ 3.95 │ 4.12 │ 4.35 │ 5.10 │ 3.21 │ 12.45 │ 4.73x │
18
+ * // └─────────────┴────────────┴────────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘
54
19
  * ```
55
- *
56
- * **Performance tier animals:**
57
- * - 🐆 Cheetah: >1M ops/sec (extremely fast)
58
- * - 🐇 Rabbit: >100K ops/sec (fast)
59
- * - 🐢 Turtle: >10K ops/sec (moderate)
60
- * - 🐌 Snail: <10K ops/sec (slow)
61
20
  */
62
21
  export const benchmark_format_table = (results) => {
63
22
  if (results.length === 0)
@@ -65,13 +24,12 @@ export const benchmark_format_table = (results) => {
65
24
  // Detect best unit for all results
66
25
  const mean_times = results.map((r) => r.stats.mean_ns);
67
26
  const unit = time_unit_detect_best(mean_times);
68
- const unit_str = UNIT_LABELS[unit];
27
+ const unit_str = TIME_UNIT_DISPLAY[unit];
69
28
  // Find fastest for relative comparison
70
29
  const fastest_ops = Math.max(...results.map((r) => r.stats.ops_per_second));
71
30
  const rows = [];
72
31
  // Header with unit
73
32
  rows.push([
74
- '',
75
33
  'Task Name',
76
34
  'ops/sec',
77
35
  `median (${unit_str})`,
@@ -85,7 +43,6 @@ export const benchmark_format_table = (results) => {
85
43
  ]);
86
44
  // Data rows - all use same unit
87
45
  results.forEach((r) => {
88
- const tier = get_perf_tier(r.stats.ops_per_second);
89
46
  const ops_sec = benchmark_format_number(r.stats.ops_per_second, 2);
90
47
  const median = time_format(r.stats.median_ns, unit, 2).replace(unit_str, '').trim();
91
48
  const p75 = time_format(r.stats.p75_ns, unit, 2).replace(unit_str, '').trim();
@@ -97,7 +54,7 @@ export const benchmark_format_table = (results) => {
97
54
  // Calculate relative performance
98
55
  const ratio = fastest_ops / r.stats.ops_per_second;
99
56
  const vs_best = ratio === 1.0 ? 'baseline' : `${ratio.toFixed(2)}x`;
100
- rows.push([tier, r.name, ops_sec, median, p75, p90, p95, p99, min, max, vs_best]);
57
+ rows.push([r.name, ops_sec, median, p75, p90, p95, p99, min, max, vs_best]);
101
58
  });
102
59
  // Calculate column widths (using display width for proper emoji handling)
103
60
  const widths = rows[0].map((_, col_i) => {
@@ -108,7 +65,7 @@ export const benchmark_format_table = (results) => {
108
65
  // Top border
109
66
  lines.push('┌' + widths.map((w) => '─'.repeat(w + 2)).join('┬') + '┐');
110
67
  // Header
111
- const header = rows[0].map((cell, i) => ' ' + pad_to_width(cell, widths[i]) + ' ').join('│');
68
+ const header = rows[0].map((cell, i) => ' ' + pad_width(cell, widths[i]) + ' ').join('│');
112
69
  lines.push('│' + header + '│');
113
70
  // Header separator
114
71
  lines.push('├' + widths.map((w) => '─'.repeat(w + 2)).join('┼') + '┤');
@@ -116,12 +73,12 @@ export const benchmark_format_table = (results) => {
116
73
  for (let i = 1; i < rows.length; i++) {
117
74
  const row = rows[i].map((cell, col_i) => {
118
75
  const width = widths[col_i];
119
- // Left-align tier emoji and task name, right-align numbers
120
- if (col_i === 0 || col_i === 1) {
121
- return ' ' + pad_to_width(cell, width, 'left') + ' ';
76
+ // Left-align task name, right-align numbers
77
+ if (col_i === 0) {
78
+ return ' ' + pad_width(cell, width, 'left') + ' ';
122
79
  }
123
80
  else {
124
- return ' ' + pad_to_width(cell, width, 'right') + ' ';
81
+ return ' ' + pad_width(cell, width, 'right') + ' ';
125
82
  }
126
83
  }).join('│');
127
84
  lines.push('│' + row + '│');
@@ -151,7 +108,7 @@ export const benchmark_format_markdown = (results) => {
151
108
  // Detect best unit for all results
152
109
  const mean_times = results.map((r) => r.stats.mean_ns);
153
110
  const unit = time_unit_detect_best(mean_times);
154
- const unit_str = UNIT_LABELS[unit];
111
+ const unit_str = TIME_UNIT_DISPLAY[unit];
155
112
  // Find fastest for relative comparison
156
113
  const fastest_ops = Math.max(...results.map((r) => r.stats.ops_per_second));
157
114
  const rows = [];
@@ -302,26 +259,8 @@ export const benchmark_format_table_grouped = (results, groups) => {
302
259
  }
303
260
  return sections.join('\n');
304
261
  };
305
- // TODO consider extracting to a general format utility module when more formatters are needed
306
262
  /**
307
263
  * Format a number with fixed decimal places and thousands separators.
264
+ * @see {@link format_number} in maths.ts for the underlying implementation.
308
265
  */
309
- export const benchmark_format_number = (n, decimals = 2) => {
310
- if (!isFinite(n))
311
- return String(n);
312
- return n.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
313
- };
314
- /**
315
- * Get performance tier symbol based on ops/sec.
316
- */
317
- const get_perf_tier = (ops_per_sec) => {
318
- if (ops_per_sec >= 1_000_000)
319
- return '🐆'; // > 1M ops/sec (cheetah - extremely fast)
320
- if (ops_per_sec >= 100_000)
321
- return '🐇'; // > 100K ops/sec (rabbit - fast)
322
- if (ops_per_sec >= 10_000)
323
- return '🐢'; // > 10K ops/sec (turtle - moderate)
324
- return '🐌'; // < 10K ops/sec (snail - slow)
325
- };
326
- /** Unit labels for display (μs instead of us). */
327
- const UNIT_LABELS = { ns: 'ns', us: 'μs', ms: 'ms', s: 's' };
266
+ export const benchmark_format_number = format_number;
@@ -1 +1 @@
1
- {"version":3,"file":"benchmark_stats.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/benchmark_stats.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,mFAAmF;IACnF,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,CAAC;IAC5B,kEAAkE;IAClE,aAAa,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,WAAW,EAAE,OAAO,CAAC;IACrB,kFAAkF;IAClF,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,gBAAgB,EAAE,eAAe,CAAC;IAClC,mDAAmD;IACnD,UAAU,EAAE,OAAO,CAAC;IACpB,sDAAsD;IACtD,cAAc,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,qBAAa,cAAc;IAC1B,yCAAyC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iCAAiC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,wCAAwC;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,sBAAsB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,sDAAsD;IACtD,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpC,yCAAyC;IACzC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,8CAA8C;IAC9C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,0DAA0D;IAC1D,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,mDAAmD;IACnD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,sEAAsE;IACtE,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;gBAEvB,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC;IAiErC;;OAEG;IACH,QAAQ,IAAI,MAAM;CAGlB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,GACnC,GAAG,wBAAwB,EAC3B,GAAG,wBAAwB,EAC3B,UAAU,uBAAuB,KAC/B,mBA6GF,CAAC"}
1
+ {"version":3,"file":"benchmark_stats.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/benchmark_stats.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgBH;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,mFAAmF;IACnF,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,CAAC;IAC5B,kEAAkE;IAClE,aAAa,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,WAAW,EAAE,OAAO,CAAC;IACrB,kFAAkF;IAClF,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,gBAAgB,EAAE,eAAe,CAAC;IAClC,mDAAmD;IACnD,UAAU,EAAE,OAAO,CAAC;IACpB,sDAAsD;IACtD,cAAc,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,qBAAa,cAAc;IAC1B,yCAAyC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iCAAiC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,wCAAwC;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,sBAAsB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,sDAAsD;IACtD,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpC,yCAAyC;IACzC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,8CAA8C;IAC9C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,0DAA0D;IAC1D,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,mDAAmD;IACnD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,sEAAsE;IACtE,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;gBAEvB,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC;IAiErC;;OAEG;IACH,QAAQ,IAAI,MAAM;CAGlB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,GACnC,GAAG,wBAAwB,EAC3B,GAAG,wBAAwB,EAC3B,UAAU,uBAAuB,KAC/B,mBA6GF,CAAC"}
@@ -4,7 +4,7 @@
4
4
  * All timing values are in nanoseconds.
5
5
  */
6
6
  import { TIME_NS_PER_SEC, time_format_adaptive } from './time.js';
7
- import { stats_mean, stats_median, stats_std_dev, stats_percentile, stats_cv, stats_min_max, stats_confidence_interval, stats_outliers_mad, } from './stats.js';
7
+ import { stats_mean, stats_median, stats_std_dev, stats_percentile, stats_cv, stats_min_max, stats_confidence_interval, stats_outliers_mad, stats_welch_t_test, stats_t_distribution_p_value, } from './stats.js';
8
8
  /**
9
9
  * Complete statistical analysis of timing measurements.
10
10
  * Includes outlier detection, descriptive statistics, and performance metrics.
@@ -150,9 +150,9 @@ export const benchmark_stats_compare = (a, b, options) => {
150
150
  p_value = a.mean_ns === b.mean_ns ? 1 : 0;
151
151
  }
152
152
  else {
153
- const { t_statistic, degrees_of_freedom } = welch_t_test(a.mean_ns, a.std_dev_ns, a.sample_size, b.mean_ns, b.std_dev_ns, b.sample_size);
153
+ const { t_statistic, degrees_of_freedom } = stats_welch_t_test(a.mean_ns, a.std_dev_ns, a.sample_size, b.mean_ns, b.std_dev_ns, b.sample_size);
154
154
  // Calculate two-tailed p-value using t-distribution approximation
155
- p_value = t_distribution_p_value(Math.abs(t_statistic), degrees_of_freedom);
155
+ p_value = stats_t_distribution_p_value(Math.abs(t_statistic), degrees_of_freedom);
156
156
  }
157
157
  // Cohen's d effect size
158
158
  const pooled_std_dev = Math.sqrt(((a.sample_size - 1) * a.std_dev_ns ** 2 + (b.sample_size - 1) * b.std_dev_ns ** 2) /
@@ -217,120 +217,3 @@ export const benchmark_stats_compare = (a, b, options) => {
217
217
  recommendation,
218
218
  };
219
219
  };
220
- /**
221
- * Calculate Welch's t-test statistic and degrees of freedom.
222
- * Welch's t-test is more robust than Student's t-test when variances are unequal.
223
- */
224
- const welch_t_test = (mean1, std1, n1, mean2, std2, n2) => {
225
- const var1 = std1 ** 2;
226
- const var2 = std2 ** 2;
227
- const se1 = var1 / n1;
228
- const se2 = var2 / n2;
229
- const t_statistic = (mean1 - mean2) / Math.sqrt(se1 + se2);
230
- // Welch-Satterthwaite degrees of freedom
231
- const numerator = (se1 + se2) ** 2;
232
- const denominator = se1 ** 2 / (n1 - 1) + se2 ** 2 / (n2 - 1);
233
- const degrees_of_freedom = numerator / denominator;
234
- return { t_statistic, degrees_of_freedom };
235
- };
236
- /**
237
- * Approximate p-value from t-distribution using the approximation formula.
238
- * This avoids requiring a full t-distribution table or library.
239
- * For large df (>30), this approximation is very accurate.
240
- */
241
- const t_distribution_p_value = (t, df) => {
242
- // Use normal approximation for large df
243
- if (df > 100) {
244
- // Standard normal CDF approximation
245
- return 2 * (1 - normal_cdf(t));
246
- }
247
- // For smaller df, use a more accurate approximation
248
- // Based on the incomplete beta function relationship
249
- const x = df / (df + t * t);
250
- const a = df / 2;
251
- const b = 0.5;
252
- // Approximation of regularized incomplete beta function
253
- // This is accurate to about 4 decimal places for typical use cases
254
- const beta_approx = incomplete_beta_approx(x, a, b);
255
- return beta_approx;
256
- };
257
- /**
258
- * Standard normal CDF approximation (Abramowitz and Stegun formula 7.1.26).
259
- */
260
- const normal_cdf = (x) => {
261
- const t = 1 / (1 + 0.2316419 * Math.abs(x));
262
- const d = 0.3989423 * Math.exp((-x * x) / 2);
263
- const p = d * t * (0.3193815 + t * (-0.3565638 + t * (1.781478 + t * (-1.821256 + t * 1.330274))));
264
- return x > 0 ? 1 - p : p;
265
- };
266
- /**
267
- * Approximate regularized incomplete beta function for p-value calculation.
268
- * Uses continued fraction expansion for reasonable accuracy.
269
- */
270
- const incomplete_beta_approx = (x, a, b) => {
271
- // Simple approximation using the relationship between beta and normal distributions
272
- // For our use case (t-distribution p-values), this provides sufficient accuracy
273
- if (x <= 0)
274
- return 0;
275
- if (x >= 1)
276
- return 1;
277
- // Use symmetry if needed
278
- if (x > (a + 1) / (a + b + 2)) {
279
- return 1 - incomplete_beta_approx(1 - x, b, a);
280
- }
281
- // Continued fraction approximation (first few terms)
282
- const lnBeta = ln_gamma(a) + ln_gamma(b) - ln_gamma(a + b);
283
- const front = Math.exp(Math.log(x) * a + Math.log(1 - x) * b - lnBeta) / a;
284
- // Simple continued fraction (limited iterations for speed)
285
- let f = 1;
286
- let c = 1;
287
- let d = 0;
288
- for (let m = 1; m <= 100; m++) {
289
- const m2 = 2 * m;
290
- // Even step
291
- let aa = (m * (b - m) * x) / ((a + m2 - 1) * (a + m2));
292
- d = 1 + aa * d;
293
- if (Math.abs(d) < 1e-30)
294
- d = 1e-30;
295
- c = 1 + aa / c;
296
- if (Math.abs(c) < 1e-30)
297
- c = 1e-30;
298
- d = 1 / d;
299
- f *= d * c;
300
- // Odd step
301
- aa = (-(a + m) * (a + b + m) * x) / ((a + m2) * (a + m2 + 1));
302
- d = 1 + aa * d;
303
- if (Math.abs(d) < 1e-30)
304
- d = 1e-30;
305
- c = 1 + aa / c;
306
- if (Math.abs(c) < 1e-30)
307
- c = 1e-30;
308
- d = 1 / d;
309
- const delta = d * c;
310
- f *= delta;
311
- if (Math.abs(delta - 1) < 1e-8)
312
- break;
313
- }
314
- return front * f;
315
- };
316
- /**
317
- * Log gamma function approximation (Lanczos approximation).
318
- */
319
- const ln_gamma = (z) => {
320
- const g = 7;
321
- const c = [
322
- 0.99999999999980993, 676.5203681218851, -1259.1392167224028, 771.32342877765313,
323
- -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6,
324
- 1.5056327351493116e-7,
325
- ];
326
- if (z < 0.5) {
327
- return Math.log(Math.PI / Math.sin(Math.PI * z)) - ln_gamma(1 - z);
328
- }
329
- const z_adj = z - 1;
330
- let x = c[0];
331
- for (let i = 1; i < g + 2; i++) {
332
- x += c[i] / (z_adj + i);
333
- }
334
- const t = z_adj + g + 0.5;
335
- return 0.5 * Math.log(2 * Math.PI) + (z_adj + 0.5) * Math.log(t) - t + Math.log(x);
336
- };
package/dist/git.d.ts CHANGED
@@ -1,6 +1,18 @@
1
1
  import type { SpawnOptions } from 'node:child_process';
2
2
  import { z } from 'zod';
3
3
  import type { Flavored } from './types.js';
4
+ /**
5
+ * Basic git repository info.
6
+ */
7
+ export interface GitInfo {
8
+ commit: string | null;
9
+ branch: string | null;
10
+ }
11
+ /**
12
+ * Get basic git info (commit hash and branch name) without throwing.
13
+ * Returns null values if git commands fail (e.g., not in a git repo).
14
+ */
15
+ export declare const git_info_get: (options?: SpawnOptions) => Promise<GitInfo>;
4
16
  export declare const GitOrigin: z.ZodString;
5
17
  export type GitOrigin = Flavored<string, 'GitOrigin'>;
6
18
  export declare const GitBranch: z.ZodString;
package/dist/git.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"git.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/git.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/git.ts"],"names":[],"mappings":"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"}
package/dist/git.js CHANGED
@@ -2,6 +2,20 @@ import { z } from 'zod';
2
2
  import { spawn, spawn_out } from './process.js';
3
3
  import { to_file_path } from './path.js';
4
4
  import { fs_exists } from './fs.js';
5
+ /**
6
+ * Get basic git info (commit hash and branch name) without throwing.
7
+ * Returns null values if git commands fail (e.g., not in a git repo).
8
+ */
9
+ export const git_info_get = async (options) => {
10
+ const [commit_result, branch_result] = await Promise.all([
11
+ spawn_out('git', ['rev-parse', 'HEAD'], options).catch(() => ({ stdout: null })),
12
+ spawn_out('git', ['rev-parse', '--abbrev-ref', 'HEAD'], options).catch(() => ({ stdout: null })),
13
+ ]);
14
+ return {
15
+ commit: commit_result.stdout?.trim() || null,
16
+ branch: branch_result.stdout?.trim() || null,
17
+ };
18
+ };
5
19
  export const GitOrigin = z.string();
6
20
  export const GitBranch = z.string();
7
21
  /**
package/dist/maths.d.ts CHANGED
@@ -82,4 +82,8 @@ export declare const GR_9 = 76.01315561749645;
82
82
  * golden ratio/mean constants, `1/(GR**9)`, useful for scaling: https://wikipedia.org/wiki/Golden_ratio
83
83
  */
84
84
  export declare const GR_9i = 0.013155617496424835;
85
+ /**
86
+ * Format a number with fixed decimal places and thousands separators.
87
+ */
88
+ export declare const format_number: (n: number, decimals?: number) => string;
85
89
  //# sourceMappingURL=maths.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"maths.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/maths.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,KAAK,GAAI,GAAG,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,MAC5B,CAAC;AAEjC;;GAEG;AACH,eAAO,MAAM,IAAI,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,QAAQ,MAAM,KAAG,MAAuC,CAAC;AAEpG;;GAEG;AACH,eAAO,MAAM,KAAK,GAAI,GAAG,MAAM,EAAE,UAAU,MAAM,KAAG,MAGnD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,EAAE,oBAAoB,CAAC;AACpC;;GAEG;AACH,eAAO,MAAM,IAAI,qBAAqB,CAAC;AACvC;;GAEG;AACH,eAAO,MAAM,IAAI,oBAAoB,CAAC;AACtC;;GAEG;AACH,eAAO,MAAM,KAAK,sBAAsB,CAAC;AACzC;;GAEG;AACH,eAAO,MAAM,IAAI,mBAAmB,CAAC;AACrC;;GAEG;AACH,eAAO,MAAM,KAAK,qBAAqB,CAAC;AACxC;;GAEG;AACH,eAAO,MAAM,IAAI,oBAAoB,CAAC;AACtC;;GAEG;AACH,eAAO,MAAM,KAAK,sBAAsB,CAAC;AACzC;;GAEG;AACH,eAAO,MAAM,IAAI,qBAAqB,CAAC;AACvC;;GAEG;AACH,eAAO,MAAM,KAAK,sBAAsB,CAAC;AACzC;;GAEG;AACH,eAAO,MAAM,IAAI,qBAAqB,CAAC;AACvC;;GAEG;AACH,eAAO,MAAM,KAAK,qBAAqB,CAAC;AACxC;;GAEG;AACH,eAAO,MAAM,IAAI,oBAAoB,CAAC;AACtC;;GAEG;AACH,eAAO,MAAM,KAAK,sBAAsB,CAAC;AACzC;;GAEG;AACH,eAAO,MAAM,IAAI,qBAAqB,CAAC;AACvC;;GAEG;AACH,eAAO,MAAM,KAAK,sBAAsB,CAAC;AACzC;;GAEG;AACH,eAAO,MAAM,IAAI,oBAAoB,CAAC;AACtC;;GAEG;AACH,eAAO,MAAM,KAAK,uBAAuB,CAAC"}
1
+ {"version":3,"file":"maths.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/maths.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,KAAK,GAAI,GAAG,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,MAC5B,CAAC;AAEjC;;GAEG;AACH,eAAO,MAAM,IAAI,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,QAAQ,MAAM,KAAG,MAAuC,CAAC;AAEpG;;GAEG;AACH,eAAO,MAAM,KAAK,GAAI,GAAG,MAAM,EAAE,UAAU,MAAM,KAAG,MAGnD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,EAAE,oBAAoB,CAAC;AACpC;;GAEG;AACH,eAAO,MAAM,IAAI,qBAAqB,CAAC;AACvC;;GAEG;AACH,eAAO,MAAM,IAAI,oBAAoB,CAAC;AACtC;;GAEG;AACH,eAAO,MAAM,KAAK,sBAAsB,CAAC;AACzC;;GAEG;AACH,eAAO,MAAM,IAAI,mBAAmB,CAAC;AACrC;;GAEG;AACH,eAAO,MAAM,KAAK,qBAAqB,CAAC;AACxC;;GAEG;AACH,eAAO,MAAM,IAAI,oBAAoB,CAAC;AACtC;;GAEG;AACH,eAAO,MAAM,KAAK,sBAAsB,CAAC;AACzC;;GAEG;AACH,eAAO,MAAM,IAAI,qBAAqB,CAAC;AACvC;;GAEG;AACH,eAAO,MAAM,KAAK,sBAAsB,CAAC;AACzC;;GAEG;AACH,eAAO,MAAM,IAAI,qBAAqB,CAAC;AACvC;;GAEG;AACH,eAAO,MAAM,KAAK,qBAAqB,CAAC;AACxC;;GAEG;AACH,eAAO,MAAM,IAAI,oBAAoB,CAAC;AACtC;;GAEG;AACH,eAAO,MAAM,KAAK,sBAAsB,CAAC;AACzC;;GAEG;AACH,eAAO,MAAM,IAAI,qBAAqB,CAAC;AACvC;;GAEG;AACH,eAAO,MAAM,KAAK,sBAAsB,CAAC;AACzC;;GAEG;AACH,eAAO,MAAM,IAAI,oBAAoB,CAAC;AACtC;;GAEG;AACH,eAAO,MAAM,KAAK,uBAAuB,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,GAAG,MAAM,EAAE,WAAU,MAAU,KAAG,MAG/D,CAAC"}
package/dist/maths.js CHANGED
@@ -85,3 +85,11 @@ export const GR_9 = 76.01315561749645;
85
85
  * golden ratio/mean constants, `1/(GR**9)`, useful for scaling: https://wikipedia.org/wiki/Golden_ratio
86
86
  */
87
87
  export const GR_9i = 0.013155617496424835;
88
+ /**
89
+ * Format a number with fixed decimal places and thousands separators.
90
+ */
91
+ export const format_number = (n, decimals = 2) => {
92
+ if (!isFinite(n))
93
+ return String(n);
94
+ return n.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
95
+ };
package/dist/process.d.ts CHANGED
@@ -74,4 +74,8 @@ export interface RestartableProcess {
74
74
  * handling many concurrent `restart` calls gracefully.
75
75
  */
76
76
  export declare const spawn_restartable_process: (command: string, args?: ReadonlyArray<string>, options?: SpawnOptions) => RestartableProcess;
77
+ /**
78
+ * Check if a PID is still running.
79
+ */
80
+ export declare const process_is_pid_running: (pid: number) => boolean;
77
81
  //# sourceMappingURL=process.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"process.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,MAAM,oBAAoB,CAAC;AAK5B,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AAIxC,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,OAAO;IACvB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC9B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAID,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAEnD;;;;GAIG;AACH,eAAO,MAAM,KAAK,GAAI,GAAG,MAAM,UAAU,CAAC,OAAO,aAAa,CAAC,KAAG,OAAO,CAAC,WAAW,CACvD,CAAC;AAE/B,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,GACrB,SAAS,MAAM,EACf,OAAM,aAAa,CAAC,MAAM,CAAM,EAChC,UAAU,YAAY,KACpB,OAAO,CAAC,UAAU,CAYpB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACzB,SAAS,MAAM,EACf,OAAM,aAAa,CAAC,MAAM,CAAM,EAChC,UAAU,YAAY,KACpB,cAUF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,OAAO,YAAY,KAAG,MACwC,CAAC;AAEnG;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,GAAG,CAAC,YAAY,CAAa,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,OAAO,YAAY,KAAG,CAAC,MAAM,IAAI,CAWtE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,GAAI,OAAO,YAAY,KAAG,OAAO,CAAC,WAAW,CAShE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,QAAO,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CACQ,CAAC;AAElE;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,GACzC,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,uBAAuB,KAAK,MAAM,GAAG,IAAI,EACtF,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,uBAAuB,KAAK,MAAM,GAAG,IAAI,EACtF,eAAc,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,uBAAuB,KAAK,IACtD,KACd,IAYF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,WAAW,KAAG,MAKxD,CAAC;AAGF,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,GACrC,SAAS,MAAM,EACf,OAAM,aAAa,CAAC,MAAM,CAAM,EAChC,UAAU,YAAY,KACpB,kBAuBF,CAAC"}
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,MAAM,oBAAoB,CAAC;AAK5B,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AAIxC,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,OAAO;IACvB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC9B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAID,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAEnD;;;;GAIG;AACH,eAAO,MAAM,KAAK,GAAI,GAAG,MAAM,UAAU,CAAC,OAAO,aAAa,CAAC,KAAG,OAAO,CAAC,WAAW,CACvD,CAAC;AAE/B,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,GACrB,SAAS,MAAM,EACf,OAAM,aAAa,CAAC,MAAM,CAAM,EAChC,UAAU,YAAY,KACpB,OAAO,CAAC,UAAU,CAYpB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACzB,SAAS,MAAM,EACf,OAAM,aAAa,CAAC,MAAM,CAAM,EAChC,UAAU,YAAY,KACpB,cAUF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,OAAO,YAAY,KAAG,MACwC,CAAC;AAEnG;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,GAAG,CAAC,YAAY,CAAa,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,OAAO,YAAY,KAAG,CAAC,MAAM,IAAI,CAWtE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,GAAI,OAAO,YAAY,KAAG,OAAO,CAAC,WAAW,CAShE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,QAAO,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CACQ,CAAC;AAElE;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,GACzC,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,uBAAuB,KAAK,MAAM,GAAG,IAAI,EACtF,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,uBAAuB,KAAK,MAAM,GAAG,IAAI,EACtF,eAAc,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,uBAAuB,KAAK,IACtD,KACd,IAYF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,WAAW,KAAG,MAKxD,CAAC;AAGF,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,GACrC,SAAS,MAAM,EACf,OAAM,aAAa,CAAC,MAAM,CAAM,EAChC,UAAU,YAAY,KACpB,kBAuBF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,GAAI,KAAK,MAAM,KAAG,OASpD,CAAC"}
package/dist/process.js CHANGED
@@ -146,3 +146,17 @@ export const spawn_restartable_process = (command, args = [], options) => {
146
146
  void restart();
147
147
  return { restart, kill };
148
148
  };
149
+ /**
150
+ * Check if a PID is still running.
151
+ */
152
+ export const process_is_pid_running = (pid) => {
153
+ try {
154
+ // Sending signal 0 doesn't actually send a signal, just checks if process exists
155
+ process.kill(pid, 0);
156
+ return true;
157
+ }
158
+ catch (err) {
159
+ // ESRCH = no such process, EPERM = exists but no permission
160
+ return err.code === 'EPERM';
161
+ }
162
+ };
@@ -13,8 +13,8 @@ import { z } from 'zod';
13
13
  */
14
14
  export declare const DeclarationKind: z.ZodEnum<{
15
15
  function: "function";
16
- type: "type";
17
16
  json: "json";
17
+ type: "type";
18
18
  variable: "variable";
19
19
  class: "class";
20
20
  constructor: "constructor";
@@ -77,8 +77,8 @@ export declare const DeclarationJson: z.ZodObject<{
77
77
  name: z.ZodString;
78
78
  kind: z.ZodEnum<{
79
79
  function: "function";
80
- type: "type";
81
80
  json: "json";
81
+ type: "type";
82
82
  variable: "variable";
83
83
  class: "class";
84
84
  constructor: "constructor";
@@ -169,8 +169,8 @@ export declare const ModuleJson: z.ZodObject<{
169
169
  name: z.ZodString;
170
170
  kind: z.ZodEnum<{
171
171
  function: "function";
172
- type: "type";
173
172
  json: "json";
173
+ type: "type";
174
174
  variable: "variable";
175
175
  class: "class";
176
176
  constructor: "constructor";
@@ -271,8 +271,8 @@ export declare const SourceJson: z.ZodObject<{
271
271
  name: z.ZodString;
272
272
  kind: z.ZodEnum<{
273
273
  function: "function";
274
- type: "type";
275
274
  json: "json";
275
+ type: "type";
276
276
  variable: "variable";
277
277
  class: "class";
278
278
  constructor: "constructor";