@gajae-code/utils 0.7.10 → 0.8.0

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/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@gajae-code/utils",
4
- "version": "0.7.10",
4
+ "version": "0.8.0",
5
5
  "description": "Shared utilities for pi packages",
6
- "homepage": "https://gaebal-gajae.dev",
6
+ "homepage": "https://gajae-code.com",
7
7
  "author": "Yeachan-Heo",
8
8
  "license": "MIT",
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "git+https://github.com/gajae-ai/gajae-code.git",
11
+ "url": "git+https://github.com/Yeachan-Heo/gajae-code.git",
12
12
  "directory": "packages/utils"
13
13
  },
14
14
  "bugs": {
15
- "url": "https://github.com/gajae-ai/gajae-code/issues"
15
+ "url": "https://github.com/Yeachan-Heo/gajae-code/issues"
16
16
  },
17
17
  "keywords": [
18
18
  "utilities",
@@ -31,7 +31,7 @@
31
31
  "fmt": "biome format --write ."
32
32
  },
33
33
  "dependencies": {
34
- "@gajae-code/natives": "0.7.10",
34
+ "@gajae-code/natives": "0.8.0",
35
35
  "beautiful-mermaid": "^1.1.3",
36
36
  "handlebars": "^4.7.9",
37
37
  "winston": "^3.19.0",
package/src/format.ts CHANGED
@@ -33,9 +33,9 @@ export function formatDuration(ms: number): string {
33
33
  export function formatNumber(n: number): string {
34
34
  if (n < 1_000) return n.toString();
35
35
  if (n < 10_000) return `${trim1(n / 1_000)}K`;
36
- if (n < 1_000_000) return `${Math.round(n / 1_000)}K`;
36
+ if (n < 1_000_000) return `${roundBelow(n / 1_000, 1_000)}K`;
37
37
  if (n < 10_000_000) return `${trim1(n / 1_000_000)}M`;
38
- if (n < 1_000_000_000) return `${Math.round(n / 1_000_000)}M`;
38
+ if (n < 1_000_000_000) return `${roundBelow(n / 1_000_000, 1_000)}M`;
39
39
  if (n < 10_000_000_000) return `${trim1(n / 1_000_000_000)}B`;
40
40
  return `${Math.round(n / 1_000_000_000)}B`;
41
41
  }
@@ -46,15 +46,26 @@ function trim1(n: number): string {
46
46
  return s.endsWith(".0") ? s.slice(0, -2) : s;
47
47
  }
48
48
 
49
+ /** Round to an integer without crossing the next compact suffix boundary. */
50
+ function roundBelow(n: number, nextUnit: number): number {
51
+ return Math.min(Math.round(n), nextUnit - 1);
52
+ }
53
+
49
54
  /**
50
55
  * Format a byte count to a human-readable string.
51
56
  * Examples: "512B", "1.5KB", "2.3MB", "1.2GB"
52
57
  */
53
58
  export function formatBytes(bytes: number): string {
54
59
  if (bytes < 1024) return `${bytes}B`;
55
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
56
- if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
57
- return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)}GB`;
60
+ if (bytes < 1024 * 1024) return `${formatByteUnit(bytes, 1024)}KB`;
61
+ if (bytes < 1024 * 1024 * 1024) return `${formatByteUnit(bytes, 1024 * 1024)}MB`;
62
+ return `${formatByteUnit(bytes, 1024 * 1024 * 1024)}GB`;
63
+ }
64
+
65
+ /** Format bytes to 1 decimal without rounding up into the next byte unit. */
66
+ function formatByteUnit(bytes: number, unit: number): string {
67
+ const tenths = Math.min(Math.round((bytes / unit) * 10), 1024 * 10 - 1);
68
+ return (tenths / 10).toFixed(1);
58
69
  }
59
70
 
60
71
  /**
package/src/glob.ts CHANGED
@@ -145,6 +145,8 @@ export async function globPaths(patterns: string | string[], options: GlobPathsO
145
145
  effectiveExclude = [...effectiveExclude, ...gitignorePatterns];
146
146
  }
147
147
 
148
+ const excludeGlobs = effectiveExclude.map(pattern => new Glob(pattern));
149
+
148
150
  const base = cwd ?? getProjectDir();
149
151
  const allResults: string[] = [];
150
152
 
@@ -171,17 +173,10 @@ export async function globPaths(patterns: string | string[], options: GlobPathsO
171
173
 
172
174
  // Check exclusion patterns
173
175
  const normalized = entry.replace(/\\/g, "/");
174
- let excluded = false;
175
- for (const excludePattern of effectiveExclude) {
176
- const excludeGlob = new Glob(excludePattern);
177
- if (excludeGlob.match(normalized)) {
178
- excluded = true;
179
- break;
180
- }
181
- }
182
- if (!excluded) {
183
- allResults.push(normalized);
176
+ if (excludeGlobs.some(excludeGlob => excludeGlob.match(normalized))) {
177
+ continue;
184
178
  }
179
+ allResults.push(normalized);
185
180
  }
186
181
  }
187
182
 
package/src/postmortem.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import inspector from "node:inspector";
9
9
  import { isMainThread } from "node:worker_threads";
10
- import { logger } from ".";
10
+ import * as logger from "./logger";
11
11
  import { safeStderrWrite } from "./safe-stderr";
12
12
 
13
13
  // Cleanup reasons, in order of priority/meaning.
@@ -39,6 +39,9 @@ function runCleanup(reason: Reason): Promise<void> {
39
39
  cleanupStage = "running";
40
40
  break;
41
41
  case "running":
42
+ if (reason === Reason.EXIT) {
43
+ return Promise.resolve();
44
+ }
42
45
  logger.error("Cleanup invoked recursively", { stack: new Error().stack });
43
46
  return Promise.resolve();
44
47
  case "complete":