@publikit/utils 0.1.1 → 1.0.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/CHANGELOG.md +21 -0
- package/README.md +24 -0
- package/dist/async.cjs +35 -0
- package/dist/async.cjs.map +1 -0
- package/dist/async.d.cts +14 -0
- package/dist/async.d.ts +14 -0
- package/dist/async.js +33 -0
- package/dist/async.js.map +1 -0
- package/dist/cn.cjs +13 -0
- package/dist/cn.cjs.map +1 -0
- package/dist/cn.d.cts +9 -0
- package/dist/cn.d.ts +9 -0
- package/dist/cn.js +11 -0
- package/dist/cn.js.map +1 -0
- package/dist/error.cjs +22 -0
- package/dist/error.cjs.map +1 -0
- package/dist/error.d.cts +6 -0
- package/dist/error.d.ts +6 -0
- package/dist/error.js +20 -0
- package/dist/error.js.map +1 -0
- package/dist/format.cjs +29 -0
- package/dist/format.cjs.map +1 -0
- package/dist/format.d.cts +10 -0
- package/dist/format.d.ts +10 -0
- package/dist/format.js +26 -0
- package/dist/format.js.map +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -35
- package/dist/index.d.ts +5 -35
- package/dist/index.js.map +1 -1
- package/package.json +27 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Initial release of `@publikit/utils` as a Publikit L0 foundation package.
|
|
8
|
+
- `cn` for `clsx` + `tailwind-merge` class-name composition.
|
|
9
|
+
- `ClassValue` type export for typed class-name composition.
|
|
10
|
+
- `debounce` with `cancel()` and `flush()` helpers.
|
|
11
|
+
- `getErrorMessage` for safe unknown error extraction.
|
|
12
|
+
- `formatBytes` and `calculateUsagePercentage` formatting utilities.
|
|
13
|
+
- Subpath exports: `@publikit/utils/cn`, `/async`, `/error`, and `/format`.
|
|
14
|
+
- `docs/PUBLISHING.md`.
|
|
15
|
+
- Coverage script.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Package metadata now points to `packages/utils`.
|
|
20
|
+
- README documents the L0 role and headless L2 usage.
|
|
21
|
+
- Test coverage now includes Tailwind conflict merging and additional edge cases.
|
package/README.md
CHANGED
|
@@ -4,6 +4,10 @@ Framework-agnostic utility functions for Publikit packages and applications.
|
|
|
4
4
|
|
|
5
5
|
- **No React peer dependency** — safe for scripts, edge workers, and non-UI code
|
|
6
6
|
- **Tree-shakeable** — `sideEffects: false`
|
|
7
|
+
- **L0 foundation** — shared helpers for headless L2 packages and consumer apps
|
|
8
|
+
|
|
9
|
+
See the [package taxonomy](../docs/PACKAGE-TAXONOMY.md) for where L0 utilities
|
|
10
|
+
fit in Publikit.
|
|
7
11
|
|
|
8
12
|
## Installation
|
|
9
13
|
|
|
@@ -16,11 +20,21 @@ npm install @publikit/utils
|
|
|
16
20
|
| Export | Description |
|
|
17
21
|
|--------|-------------|
|
|
18
22
|
| `cn` | Merge Tailwind classes (`clsx` + `tailwind-merge`) |
|
|
23
|
+
| `ClassValue` | Type accepted by `cn` |
|
|
19
24
|
| `debounce` | Debounce function calls |
|
|
20
25
|
| `getErrorMessage` | Extract message from unknown errors |
|
|
21
26
|
| `formatBytes` | Human-readable byte sizes |
|
|
22
27
|
| `calculateUsagePercentage` | Percentage capped at 100 |
|
|
23
28
|
|
|
29
|
+
Subpath exports are available for focused imports:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { cn } from '@publikit/utils/cn';
|
|
33
|
+
import { debounce } from '@publikit/utils/async';
|
|
34
|
+
import { getErrorMessage } from '@publikit/utils/error';
|
|
35
|
+
import { formatBytes } from '@publikit/utils/format';
|
|
36
|
+
```
|
|
37
|
+
|
|
24
38
|
## Usage
|
|
25
39
|
|
|
26
40
|
```ts
|
|
@@ -32,6 +46,16 @@ const message = getErrorMessage(error, 'Something went wrong');
|
|
|
32
46
|
const size = formatBytes(1_048_576); // "1 MB"
|
|
33
47
|
```
|
|
34
48
|
|
|
49
|
+
## Role in Headless L2 Packages
|
|
50
|
+
|
|
51
|
+
Headless L2 modules use `cn` to merge consumer-provided `classNames` with
|
|
52
|
+
conditional state classes. Non-Tailwind consumers can ignore that merge behavior
|
|
53
|
+
and style stable `data-slot` attributes instead.
|
|
54
|
+
|
|
55
|
+
`formatBytes`, `calculateUsagePercentage`, and `getErrorMessage` are app-level
|
|
56
|
+
convenience utilities; they are kept framework-agnostic so they can be reused in
|
|
57
|
+
PHO, scripts, and workers.
|
|
58
|
+
|
|
35
59
|
## Related packages
|
|
36
60
|
|
|
37
61
|
- [`@publikit/hooks`](../hooks) — generic React hooks
|
package/dist/async.cjs
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// async.ts
|
|
4
|
+
function debounce(fn, ms) {
|
|
5
|
+
let timeoutId = null;
|
|
6
|
+
let lastArgs = null;
|
|
7
|
+
const debounced = (...args) => {
|
|
8
|
+
lastArgs = args;
|
|
9
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
10
|
+
timeoutId = setTimeout(() => {
|
|
11
|
+
timeoutId = null;
|
|
12
|
+
if (lastArgs) {
|
|
13
|
+
fn(...lastArgs);
|
|
14
|
+
lastArgs = null;
|
|
15
|
+
}
|
|
16
|
+
}, ms);
|
|
17
|
+
};
|
|
18
|
+
debounced.cancel = () => {
|
|
19
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
20
|
+
timeoutId = null;
|
|
21
|
+
lastArgs = null;
|
|
22
|
+
};
|
|
23
|
+
debounced.flush = () => {
|
|
24
|
+
if (!timeoutId || !lastArgs) return;
|
|
25
|
+
clearTimeout(timeoutId);
|
|
26
|
+
timeoutId = null;
|
|
27
|
+
fn(...lastArgs);
|
|
28
|
+
lastArgs = null;
|
|
29
|
+
};
|
|
30
|
+
return debounced;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
exports.debounce = debounce;
|
|
34
|
+
//# sourceMappingURL=async.cjs.map
|
|
35
|
+
//# sourceMappingURL=async.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../async.ts"],"names":[],"mappings":";;;AAYO,SAAS,QAAA,CACd,IACA,EAAA,EACyB;AACzB,EAAA,IAAI,SAAA,GAAkD,IAAA;AACtD,EAAA,IAAI,QAAA,GAAqB,IAAA;AAEzB,EAAA,MAAM,SAAA,GAAY,IAAI,IAAA,KAAY;AAChC,IAAA,QAAA,GAAW,IAAA;AACX,IAAA,IAAI,SAAA,eAAwB,SAAS,CAAA;AACrC,IAAA,SAAA,GAAY,WAAW,MAAM;AAC3B,MAAA,SAAA,GAAY,IAAA;AACZ,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,EAAA,CAAG,GAAG,QAAQ,CAAA;AACd,QAAA,QAAA,GAAW,IAAA;AAAA,MACb;AAAA,IACF,GAAG,EAAE,CAAA;AAAA,EACP,CAAA;AAEA,EAAA,SAAA,CAAU,SAAS,MAAM;AACvB,IAAA,IAAI,SAAA,eAAwB,SAAS,CAAA;AACrC,IAAA,SAAA,GAAY,IAAA;AACZ,IAAA,QAAA,GAAW,IAAA;AAAA,EACb,CAAA;AAEA,EAAA,SAAA,CAAU,QAAQ,MAAM;AACtB,IAAA,IAAI,CAAC,SAAA,IAAa,CAAC,QAAA,EAAU;AAC7B,IAAA,YAAA,CAAa,SAAS,CAAA;AACtB,IAAA,SAAA,GAAY,IAAA;AACZ,IAAA,EAAA,CAAG,GAAG,QAAQ,CAAA;AACd,IAAA,QAAA,GAAW,IAAA;AAAA,EACb,CAAA;AAEA,EAAA,OAAO,SAAA;AACT","file":"async.cjs","sourcesContent":["/**\r\n * Debounced function with cancel and flush helpers.\r\n */\r\nexport interface DebouncedFunction<A extends unknown[], R> {\r\n (...args: A): void;\r\n cancel(): void;\r\n flush(): void;\r\n}\r\n\r\n/**\r\n * Debounce a function — only invoke after `ms` milliseconds of inactivity.\r\n */\r\nexport function debounce<A extends unknown[], R>(\r\n fn: (...args: A) => R,\r\n ms: number\r\n): DebouncedFunction<A, R> {\r\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\r\n let lastArgs: A | null = null;\r\n\r\n const debounced = (...args: A) => {\r\n lastArgs = args;\r\n if (timeoutId) clearTimeout(timeoutId);\r\n timeoutId = setTimeout(() => {\r\n timeoutId = null;\r\n if (lastArgs) {\r\n fn(...lastArgs);\r\n lastArgs = null;\r\n }\r\n }, ms);\r\n };\r\n\r\n debounced.cancel = () => {\r\n if (timeoutId) clearTimeout(timeoutId);\r\n timeoutId = null;\r\n lastArgs = null;\r\n };\r\n\r\n debounced.flush = () => {\r\n if (!timeoutId || !lastArgs) return;\r\n clearTimeout(timeoutId);\r\n timeoutId = null;\r\n fn(...lastArgs);\r\n lastArgs = null;\r\n };\r\n\r\n return debounced;\r\n}\r\n"]}
|
package/dist/async.d.cts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debounced function with cancel and flush helpers.
|
|
3
|
+
*/
|
|
4
|
+
interface DebouncedFunction<A extends unknown[], R> {
|
|
5
|
+
(...args: A): void;
|
|
6
|
+
cancel(): void;
|
|
7
|
+
flush(): void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Debounce a function — only invoke after `ms` milliseconds of inactivity.
|
|
11
|
+
*/
|
|
12
|
+
declare function debounce<A extends unknown[], R>(fn: (...args: A) => R, ms: number): DebouncedFunction<A, R>;
|
|
13
|
+
|
|
14
|
+
export { type DebouncedFunction, debounce };
|
package/dist/async.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debounced function with cancel and flush helpers.
|
|
3
|
+
*/
|
|
4
|
+
interface DebouncedFunction<A extends unknown[], R> {
|
|
5
|
+
(...args: A): void;
|
|
6
|
+
cancel(): void;
|
|
7
|
+
flush(): void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Debounce a function — only invoke after `ms` milliseconds of inactivity.
|
|
11
|
+
*/
|
|
12
|
+
declare function debounce<A extends unknown[], R>(fn: (...args: A) => R, ms: number): DebouncedFunction<A, R>;
|
|
13
|
+
|
|
14
|
+
export { type DebouncedFunction, debounce };
|
package/dist/async.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// async.ts
|
|
2
|
+
function debounce(fn, ms) {
|
|
3
|
+
let timeoutId = null;
|
|
4
|
+
let lastArgs = null;
|
|
5
|
+
const debounced = (...args) => {
|
|
6
|
+
lastArgs = args;
|
|
7
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
8
|
+
timeoutId = setTimeout(() => {
|
|
9
|
+
timeoutId = null;
|
|
10
|
+
if (lastArgs) {
|
|
11
|
+
fn(...lastArgs);
|
|
12
|
+
lastArgs = null;
|
|
13
|
+
}
|
|
14
|
+
}, ms);
|
|
15
|
+
};
|
|
16
|
+
debounced.cancel = () => {
|
|
17
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
18
|
+
timeoutId = null;
|
|
19
|
+
lastArgs = null;
|
|
20
|
+
};
|
|
21
|
+
debounced.flush = () => {
|
|
22
|
+
if (!timeoutId || !lastArgs) return;
|
|
23
|
+
clearTimeout(timeoutId);
|
|
24
|
+
timeoutId = null;
|
|
25
|
+
fn(...lastArgs);
|
|
26
|
+
lastArgs = null;
|
|
27
|
+
};
|
|
28
|
+
return debounced;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { debounce };
|
|
32
|
+
//# sourceMappingURL=async.js.map
|
|
33
|
+
//# sourceMappingURL=async.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../async.ts"],"names":[],"mappings":";AAYO,SAAS,QAAA,CACd,IACA,EAAA,EACyB;AACzB,EAAA,IAAI,SAAA,GAAkD,IAAA;AACtD,EAAA,IAAI,QAAA,GAAqB,IAAA;AAEzB,EAAA,MAAM,SAAA,GAAY,IAAI,IAAA,KAAY;AAChC,IAAA,QAAA,GAAW,IAAA;AACX,IAAA,IAAI,SAAA,eAAwB,SAAS,CAAA;AACrC,IAAA,SAAA,GAAY,WAAW,MAAM;AAC3B,MAAA,SAAA,GAAY,IAAA;AACZ,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,EAAA,CAAG,GAAG,QAAQ,CAAA;AACd,QAAA,QAAA,GAAW,IAAA;AAAA,MACb;AAAA,IACF,GAAG,EAAE,CAAA;AAAA,EACP,CAAA;AAEA,EAAA,SAAA,CAAU,SAAS,MAAM;AACvB,IAAA,IAAI,SAAA,eAAwB,SAAS,CAAA;AACrC,IAAA,SAAA,GAAY,IAAA;AACZ,IAAA,QAAA,GAAW,IAAA;AAAA,EACb,CAAA;AAEA,EAAA,SAAA,CAAU,QAAQ,MAAM;AACtB,IAAA,IAAI,CAAC,SAAA,IAAa,CAAC,QAAA,EAAU;AAC7B,IAAA,YAAA,CAAa,SAAS,CAAA;AACtB,IAAA,SAAA,GAAY,IAAA;AACZ,IAAA,EAAA,CAAG,GAAG,QAAQ,CAAA;AACd,IAAA,QAAA,GAAW,IAAA;AAAA,EACb,CAAA;AAEA,EAAA,OAAO,SAAA;AACT","file":"async.js","sourcesContent":["/**\r\n * Debounced function with cancel and flush helpers.\r\n */\r\nexport interface DebouncedFunction<A extends unknown[], R> {\r\n (...args: A): void;\r\n cancel(): void;\r\n flush(): void;\r\n}\r\n\r\n/**\r\n * Debounce a function — only invoke after `ms` milliseconds of inactivity.\r\n */\r\nexport function debounce<A extends unknown[], R>(\r\n fn: (...args: A) => R,\r\n ms: number\r\n): DebouncedFunction<A, R> {\r\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\r\n let lastArgs: A | null = null;\r\n\r\n const debounced = (...args: A) => {\r\n lastArgs = args;\r\n if (timeoutId) clearTimeout(timeoutId);\r\n timeoutId = setTimeout(() => {\r\n timeoutId = null;\r\n if (lastArgs) {\r\n fn(...lastArgs);\r\n lastArgs = null;\r\n }\r\n }, ms);\r\n };\r\n\r\n debounced.cancel = () => {\r\n if (timeoutId) clearTimeout(timeoutId);\r\n timeoutId = null;\r\n lastArgs = null;\r\n };\r\n\r\n debounced.flush = () => {\r\n if (!timeoutId || !lastArgs) return;\r\n clearTimeout(timeoutId);\r\n timeoutId = null;\r\n fn(...lastArgs);\r\n lastArgs = null;\r\n };\r\n\r\n return debounced;\r\n}\r\n"]}
|
package/dist/cn.cjs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var clsx = require('clsx');
|
|
4
|
+
var tailwindMerge = require('tailwind-merge');
|
|
5
|
+
|
|
6
|
+
// cn.ts
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
exports.cn = cn;
|
|
12
|
+
//# sourceMappingURL=cn.cjs.map
|
|
13
|
+
//# sourceMappingURL=cn.cjs.map
|
package/dist/cn.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../cn.ts"],"names":["twMerge","clsx"],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAOA,qBAAA,CAAQC,SAAA,CAAK,MAAM,CAAC,CAAA;AAC7B","file":"cn.cjs","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\r\nimport { twMerge } from 'tailwind-merge';\r\n\r\nexport type { ClassValue } from 'clsx';\r\n\r\n/**\r\n * Merge Tailwind CSS class names with conflict resolution.\r\n */\r\nexport function cn(...inputs: ClassValue[]): string {\r\n return twMerge(clsx(inputs));\r\n}\r\n"]}
|
package/dist/cn.d.cts
ADDED
package/dist/cn.d.ts
ADDED
package/dist/cn.js
ADDED
package/dist/cn.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../cn.ts"],"names":[],"mappings":";;;;AAQO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B","file":"cn.js","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\r\nimport { twMerge } from 'tailwind-merge';\r\n\r\nexport type { ClassValue } from 'clsx';\r\n\r\n/**\r\n * Merge Tailwind CSS class names with conflict resolution.\r\n */\r\nexport function cn(...inputs: ClassValue[]): string {\r\n return twMerge(clsx(inputs));\r\n}\r\n"]}
|
package/dist/error.cjs
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// error.ts
|
|
4
|
+
function getErrorMessage(error, defaultMessage) {
|
|
5
|
+
if (error instanceof Error && error.message) {
|
|
6
|
+
return error.message;
|
|
7
|
+
}
|
|
8
|
+
if (typeof error === "string" && error.trim()) {
|
|
9
|
+
return error;
|
|
10
|
+
}
|
|
11
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
12
|
+
const message = error.message;
|
|
13
|
+
if (typeof message === "string" && message.trim()) {
|
|
14
|
+
return message;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return defaultMessage;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exports.getErrorMessage = getErrorMessage;
|
|
21
|
+
//# sourceMappingURL=error.cjs.map
|
|
22
|
+
//# sourceMappingURL=error.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../error.ts"],"names":[],"mappings":";;;AAGO,SAAS,eAAA,CAAgB,OAAgB,cAAA,EAAgC;AAC9E,EAAA,IAAI,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,OAAA,EAAS;AAC3C,IAAA,OAAO,KAAA,CAAM,OAAA;AAAA,EACf;AAEA,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,MAAK,EAAG;AAC7C,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,IAAY,aAAa,KAAA,EAAO;AAC5D,IAAA,MAAM,UAAW,KAAA,CAA+B,OAAA;AAChD,IAAA,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,OAAA,CAAQ,MAAK,EAAG;AACjD,MAAA,OAAO,OAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,cAAA;AACT","file":"error.cjs","sourcesContent":["/**\r\n * Extract a human-readable message from an unknown error value.\r\n */\r\nexport function getErrorMessage(error: unknown, defaultMessage: string): string {\r\n if (error instanceof Error && error.message) {\r\n return error.message;\r\n }\r\n\r\n if (typeof error === 'string' && error.trim()) {\r\n return error;\r\n }\r\n\r\n if (error && typeof error === 'object' && 'message' in error) {\r\n const message = (error as { message: unknown }).message;\r\n if (typeof message === 'string' && message.trim()) {\r\n return message;\r\n }\r\n }\r\n\r\n return defaultMessage;\r\n}\r\n"]}
|
package/dist/error.d.cts
ADDED
package/dist/error.d.ts
ADDED
package/dist/error.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// error.ts
|
|
2
|
+
function getErrorMessage(error, defaultMessage) {
|
|
3
|
+
if (error instanceof Error && error.message) {
|
|
4
|
+
return error.message;
|
|
5
|
+
}
|
|
6
|
+
if (typeof error === "string" && error.trim()) {
|
|
7
|
+
return error;
|
|
8
|
+
}
|
|
9
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
10
|
+
const message = error.message;
|
|
11
|
+
if (typeof message === "string" && message.trim()) {
|
|
12
|
+
return message;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return defaultMessage;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { getErrorMessage };
|
|
19
|
+
//# sourceMappingURL=error.js.map
|
|
20
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../error.ts"],"names":[],"mappings":";AAGO,SAAS,eAAA,CAAgB,OAAgB,cAAA,EAAgC;AAC9E,EAAA,IAAI,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,OAAA,EAAS;AAC3C,IAAA,OAAO,KAAA,CAAM,OAAA;AAAA,EACf;AAEA,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,MAAK,EAAG;AAC7C,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,IAAY,aAAa,KAAA,EAAO;AAC5D,IAAA,MAAM,UAAW,KAAA,CAA+B,OAAA;AAChD,IAAA,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,OAAA,CAAQ,MAAK,EAAG;AACjD,MAAA,OAAO,OAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,cAAA;AACT","file":"error.js","sourcesContent":["/**\r\n * Extract a human-readable message from an unknown error value.\r\n */\r\nexport function getErrorMessage(error: unknown, defaultMessage: string): string {\r\n if (error instanceof Error && error.message) {\r\n return error.message;\r\n }\r\n\r\n if (typeof error === 'string' && error.trim()) {\r\n return error;\r\n }\r\n\r\n if (error && typeof error === 'object' && 'message' in error) {\r\n const message = (error as { message: unknown }).message;\r\n if (typeof message === 'string' && message.trim()) {\r\n return message;\r\n }\r\n }\r\n\r\n return defaultMessage;\r\n}\r\n"]}
|
package/dist/format.cjs
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// format.ts
|
|
4
|
+
function formatBytes(bytes) {
|
|
5
|
+
if (!Number.isFinite(bytes) || bytes <= 0) {
|
|
6
|
+
return "0 B";
|
|
7
|
+
}
|
|
8
|
+
const k = 1024;
|
|
9
|
+
const sizes = ["B", "KB", "MB", "GB", "TB"];
|
|
10
|
+
const i = Math.min(
|
|
11
|
+
Math.floor(Math.log(bytes) / Math.log(k)),
|
|
12
|
+
sizes.length - 1
|
|
13
|
+
);
|
|
14
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
|
15
|
+
}
|
|
16
|
+
function calculateUsagePercentage(current, limit) {
|
|
17
|
+
if (!Number.isFinite(current) || !Number.isFinite(limit) || limit <= 0) {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
if (current <= 0) {
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
return Math.min(100, Math.round(current / limit * 100));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
exports.calculateUsagePercentage = calculateUsagePercentage;
|
|
27
|
+
exports.formatBytes = formatBytes;
|
|
28
|
+
//# sourceMappingURL=format.cjs.map
|
|
29
|
+
//# sourceMappingURL=format.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../format.ts"],"names":[],"mappings":";;;AAGO,SAAS,YAAY,KAAA,EAAuB;AACjD,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,IAAK,SAAS,CAAA,EAAG;AACzC,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,CAAA,GAAI,IAAA;AACV,EAAA,MAAM,QAAQ,CAAC,GAAA,EAAK,IAAA,EAAM,IAAA,EAAM,MAAM,IAAI,CAAA;AAC1C,EAAA,MAAM,IAAI,IAAA,CAAK,GAAA;AAAA,IACb,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,IACxC,MAAM,MAAA,GAAS;AAAA,GACjB;AACA,EAAA,OAAO,CAAA,EAAG,UAAA,CAAA,CAAY,KAAA,GAAQ,IAAA,CAAK,IAAI,CAAA,EAAG,CAAC,CAAA,EAAG,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,CAAA,EAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACvE;AAKO,SAAS,wBAAA,CAAyB,SAAiB,KAAA,EAAuB;AAC/E,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA,IAAK,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA,IAAS,CAAA,EAAG;AACtE,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,WAAW,CAAA,EAAG;AAChB,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAA,CAAK,IAAI,GAAA,EAAK,IAAA,CAAK,MAAO,OAAA,GAAU,KAAA,GAAS,GAAG,CAAC,CAAA;AAC1D","file":"format.cjs","sourcesContent":["/**\r\n * Format a byte count as a human-readable string.\r\n */\r\nexport function formatBytes(bytes: number): string {\r\n if (!Number.isFinite(bytes) || bytes <= 0) {\r\n return '0 B';\r\n }\r\n\r\n const k = 1024;\r\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\r\n const i = Math.min(\r\n Math.floor(Math.log(bytes) / Math.log(k)),\r\n sizes.length - 1\r\n );\r\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\r\n}\r\n\r\n/**\r\n * Calculate usage percentage capped at 100.\r\n */\r\nexport function calculateUsagePercentage(current: number, limit: number): number {\r\n if (!Number.isFinite(current) || !Number.isFinite(limit) || limit <= 0) {\r\n return 0;\r\n }\r\n\r\n if (current <= 0) {\r\n return 0;\r\n }\r\n\r\n return Math.min(100, Math.round((current / limit) * 100));\r\n}\r\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format a byte count as a human-readable string.
|
|
3
|
+
*/
|
|
4
|
+
declare function formatBytes(bytes: number): string;
|
|
5
|
+
/**
|
|
6
|
+
* Calculate usage percentage capped at 100.
|
|
7
|
+
*/
|
|
8
|
+
declare function calculateUsagePercentage(current: number, limit: number): number;
|
|
9
|
+
|
|
10
|
+
export { calculateUsagePercentage, formatBytes };
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format a byte count as a human-readable string.
|
|
3
|
+
*/
|
|
4
|
+
declare function formatBytes(bytes: number): string;
|
|
5
|
+
/**
|
|
6
|
+
* Calculate usage percentage capped at 100.
|
|
7
|
+
*/
|
|
8
|
+
declare function calculateUsagePercentage(current: number, limit: number): number;
|
|
9
|
+
|
|
10
|
+
export { calculateUsagePercentage, formatBytes };
|
package/dist/format.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// format.ts
|
|
2
|
+
function formatBytes(bytes) {
|
|
3
|
+
if (!Number.isFinite(bytes) || bytes <= 0) {
|
|
4
|
+
return "0 B";
|
|
5
|
+
}
|
|
6
|
+
const k = 1024;
|
|
7
|
+
const sizes = ["B", "KB", "MB", "GB", "TB"];
|
|
8
|
+
const i = Math.min(
|
|
9
|
+
Math.floor(Math.log(bytes) / Math.log(k)),
|
|
10
|
+
sizes.length - 1
|
|
11
|
+
);
|
|
12
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
|
13
|
+
}
|
|
14
|
+
function calculateUsagePercentage(current, limit) {
|
|
15
|
+
if (!Number.isFinite(current) || !Number.isFinite(limit) || limit <= 0) {
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
|
18
|
+
if (current <= 0) {
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
return Math.min(100, Math.round(current / limit * 100));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { calculateUsagePercentage, formatBytes };
|
|
25
|
+
//# sourceMappingURL=format.js.map
|
|
26
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../format.ts"],"names":[],"mappings":";AAGO,SAAS,YAAY,KAAA,EAAuB;AACjD,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,IAAK,SAAS,CAAA,EAAG;AACzC,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,CAAA,GAAI,IAAA;AACV,EAAA,MAAM,QAAQ,CAAC,GAAA,EAAK,IAAA,EAAM,IAAA,EAAM,MAAM,IAAI,CAAA;AAC1C,EAAA,MAAM,IAAI,IAAA,CAAK,GAAA;AAAA,IACb,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,IACxC,MAAM,MAAA,GAAS;AAAA,GACjB;AACA,EAAA,OAAO,CAAA,EAAG,UAAA,CAAA,CAAY,KAAA,GAAQ,IAAA,CAAK,IAAI,CAAA,EAAG,CAAC,CAAA,EAAG,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,CAAA,EAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACvE;AAKO,SAAS,wBAAA,CAAyB,SAAiB,KAAA,EAAuB;AAC/E,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA,IAAK,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA,IAAS,CAAA,EAAG;AACtE,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,WAAW,CAAA,EAAG;AAChB,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAA,CAAK,IAAI,GAAA,EAAK,IAAA,CAAK,MAAO,OAAA,GAAU,KAAA,GAAS,GAAG,CAAC,CAAA;AAC1D","file":"format.js","sourcesContent":["/**\r\n * Format a byte count as a human-readable string.\r\n */\r\nexport function formatBytes(bytes: number): string {\r\n if (!Number.isFinite(bytes) || bytes <= 0) {\r\n return '0 B';\r\n }\r\n\r\n const k = 1024;\r\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\r\n const i = Math.min(\r\n Math.floor(Math.log(bytes) / Math.log(k)),\r\n sizes.length - 1\r\n );\r\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\r\n}\r\n\r\n/**\r\n * Calculate usage percentage capped at 100.\r\n */\r\nexport function calculateUsagePercentage(current: number, limit: number): number {\r\n if (!Number.isFinite(current) || !Number.isFinite(limit) || limit <= 0) {\r\n return 0;\r\n }\r\n\r\n if (current <= 0) {\r\n return 0;\r\n }\r\n\r\n return Math.min(100, Math.round((current / limit) * 100));\r\n}\r\n"]}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../cn.ts","../async.ts","../error.ts","../format.ts"],"names":["twMerge","clsx"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"sources":["../cn.ts","../async.ts","../error.ts","../format.ts"],"names":["twMerge","clsx"],"mappings":"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","file":"index.cjs","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\r\nimport { twMerge } from 'tailwind-merge';\r\n\r\nexport type { ClassValue } from 'clsx';\r\n\r\n/**\r\n * Merge Tailwind CSS class names with conflict resolution.\r\n */\r\nexport function cn(...inputs: ClassValue[]): string {\r\n return twMerge(clsx(inputs));\r\n}\r\n","/**\r\n * Debounced function with cancel and flush helpers.\r\n */\r\nexport interface DebouncedFunction<A extends unknown[], R> {\r\n (...args: A): void;\r\n cancel(): void;\r\n flush(): void;\r\n}\r\n\r\n/**\r\n * Debounce a function — only invoke after `ms` milliseconds of inactivity.\r\n */\r\nexport function debounce<A extends unknown[], R>(\r\n fn: (...args: A) => R,\r\n ms: number\r\n): DebouncedFunction<A, R> {\r\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\r\n let lastArgs: A | null = null;\r\n\r\n const debounced = (...args: A) => {\r\n lastArgs = args;\r\n if (timeoutId) clearTimeout(timeoutId);\r\n timeoutId = setTimeout(() => {\r\n timeoutId = null;\r\n if (lastArgs) {\r\n fn(...lastArgs);\r\n lastArgs = null;\r\n }\r\n }, ms);\r\n };\r\n\r\n debounced.cancel = () => {\r\n if (timeoutId) clearTimeout(timeoutId);\r\n timeoutId = null;\r\n lastArgs = null;\r\n };\r\n\r\n debounced.flush = () => {\r\n if (!timeoutId || !lastArgs) return;\r\n clearTimeout(timeoutId);\r\n timeoutId = null;\r\n fn(...lastArgs);\r\n lastArgs = null;\r\n };\r\n\r\n return debounced;\r\n}\r\n","/**\r\n * Extract a human-readable message from an unknown error value.\r\n */\r\nexport function getErrorMessage(error: unknown, defaultMessage: string): string {\r\n if (error instanceof Error && error.message) {\r\n return error.message;\r\n }\r\n\r\n if (typeof error === 'string' && error.trim()) {\r\n return error;\r\n }\r\n\r\n if (error && typeof error === 'object' && 'message' in error) {\r\n const message = (error as { message: unknown }).message;\r\n if (typeof message === 'string' && message.trim()) {\r\n return message;\r\n }\r\n }\r\n\r\n return defaultMessage;\r\n}\r\n","/**\r\n * Format a byte count as a human-readable string.\r\n */\r\nexport function formatBytes(bytes: number): string {\r\n if (!Number.isFinite(bytes) || bytes <= 0) {\r\n return '0 B';\r\n }\r\n\r\n const k = 1024;\r\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\r\n const i = Math.min(\r\n Math.floor(Math.log(bytes) / Math.log(k)),\r\n sizes.length - 1\r\n );\r\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\r\n}\r\n\r\n/**\r\n * Calculate usage percentage capped at 100.\r\n */\r\nexport function calculateUsagePercentage(current: number, limit: number): number {\r\n if (!Number.isFinite(current) || !Number.isFinite(limit) || limit <= 0) {\r\n return 0;\r\n }\r\n\r\n if (current <= 0) {\r\n return 0;\r\n }\r\n\r\n return Math.min(100, Math.round((current / limit) * 100));\r\n}\r\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,35 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
declare function cn(...inputs: ClassValue[]): string;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Debounced function with cancel and flush helpers.
|
|
10
|
-
*/
|
|
11
|
-
interface DebouncedFunction<A extends unknown[], R> {
|
|
12
|
-
(...args: A): void;
|
|
13
|
-
cancel(): void;
|
|
14
|
-
flush(): void;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Debounce a function — only invoke after `ms` milliseconds of inactivity.
|
|
18
|
-
*/
|
|
19
|
-
declare function debounce<A extends unknown[], R>(fn: (...args: A) => R, ms: number): DebouncedFunction<A, R>;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Extract a human-readable message from an unknown error value.
|
|
23
|
-
*/
|
|
24
|
-
declare function getErrorMessage(error: unknown, defaultMessage: string): string;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Format a byte count as a human-readable string.
|
|
28
|
-
*/
|
|
29
|
-
declare function formatBytes(bytes: number): string;
|
|
30
|
-
/**
|
|
31
|
-
* Calculate usage percentage capped at 100.
|
|
32
|
-
*/
|
|
33
|
-
declare function calculateUsagePercentage(current: number, limit: number): number;
|
|
34
|
-
|
|
35
|
-
export { type DebouncedFunction, calculateUsagePercentage, cn, debounce, formatBytes, getErrorMessage };
|
|
1
|
+
export { cn } from './cn.cjs';
|
|
2
|
+
export { DebouncedFunction, debounce } from './async.cjs';
|
|
3
|
+
export { getErrorMessage } from './error.cjs';
|
|
4
|
+
export { calculateUsagePercentage, formatBytes } from './format.cjs';
|
|
5
|
+
export { ClassValue } from 'clsx';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,35 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
declare function cn(...inputs: ClassValue[]): string;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Debounced function with cancel and flush helpers.
|
|
10
|
-
*/
|
|
11
|
-
interface DebouncedFunction<A extends unknown[], R> {
|
|
12
|
-
(...args: A): void;
|
|
13
|
-
cancel(): void;
|
|
14
|
-
flush(): void;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Debounce a function — only invoke after `ms` milliseconds of inactivity.
|
|
18
|
-
*/
|
|
19
|
-
declare function debounce<A extends unknown[], R>(fn: (...args: A) => R, ms: number): DebouncedFunction<A, R>;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Extract a human-readable message from an unknown error value.
|
|
23
|
-
*/
|
|
24
|
-
declare function getErrorMessage(error: unknown, defaultMessage: string): string;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Format a byte count as a human-readable string.
|
|
28
|
-
*/
|
|
29
|
-
declare function formatBytes(bytes: number): string;
|
|
30
|
-
/**
|
|
31
|
-
* Calculate usage percentage capped at 100.
|
|
32
|
-
*/
|
|
33
|
-
declare function calculateUsagePercentage(current: number, limit: number): number;
|
|
34
|
-
|
|
35
|
-
export { type DebouncedFunction, calculateUsagePercentage, cn, debounce, formatBytes, getErrorMessage };
|
|
1
|
+
export { cn } from './cn.js';
|
|
2
|
+
export { DebouncedFunction, debounce } from './async.js';
|
|
3
|
+
export { getErrorMessage } from './error.js';
|
|
4
|
+
export { calculateUsagePercentage, formatBytes } from './format.js';
|
|
5
|
+
export { ClassValue } from 'clsx';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../cn.ts","../async.ts","../error.ts","../format.ts"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"sources":["../cn.ts","../async.ts","../error.ts","../format.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\r\nimport { twMerge } from 'tailwind-merge';\r\n\r\nexport type { ClassValue } from 'clsx';\r\n\r\n/**\r\n * Merge Tailwind CSS class names with conflict resolution.\r\n */\r\nexport function cn(...inputs: ClassValue[]): string {\r\n return twMerge(clsx(inputs));\r\n}\r\n","/**\r\n * Debounced function with cancel and flush helpers.\r\n */\r\nexport interface DebouncedFunction<A extends unknown[], R> {\r\n (...args: A): void;\r\n cancel(): void;\r\n flush(): void;\r\n}\r\n\r\n/**\r\n * Debounce a function — only invoke after `ms` milliseconds of inactivity.\r\n */\r\nexport function debounce<A extends unknown[], R>(\r\n fn: (...args: A) => R,\r\n ms: number\r\n): DebouncedFunction<A, R> {\r\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\r\n let lastArgs: A | null = null;\r\n\r\n const debounced = (...args: A) => {\r\n lastArgs = args;\r\n if (timeoutId) clearTimeout(timeoutId);\r\n timeoutId = setTimeout(() => {\r\n timeoutId = null;\r\n if (lastArgs) {\r\n fn(...lastArgs);\r\n lastArgs = null;\r\n }\r\n }, ms);\r\n };\r\n\r\n debounced.cancel = () => {\r\n if (timeoutId) clearTimeout(timeoutId);\r\n timeoutId = null;\r\n lastArgs = null;\r\n };\r\n\r\n debounced.flush = () => {\r\n if (!timeoutId || !lastArgs) return;\r\n clearTimeout(timeoutId);\r\n timeoutId = null;\r\n fn(...lastArgs);\r\n lastArgs = null;\r\n };\r\n\r\n return debounced;\r\n}\r\n","/**\r\n * Extract a human-readable message from an unknown error value.\r\n */\r\nexport function getErrorMessage(error: unknown, defaultMessage: string): string {\r\n if (error instanceof Error && error.message) {\r\n return error.message;\r\n }\r\n\r\n if (typeof error === 'string' && error.trim()) {\r\n return error;\r\n }\r\n\r\n if (error && typeof error === 'object' && 'message' in error) {\r\n const message = (error as { message: unknown }).message;\r\n if (typeof message === 'string' && message.trim()) {\r\n return message;\r\n }\r\n }\r\n\r\n return defaultMessage;\r\n}\r\n","/**\r\n * Format a byte count as a human-readable string.\r\n */\r\nexport function formatBytes(bytes: number): string {\r\n if (!Number.isFinite(bytes) || bytes <= 0) {\r\n return '0 B';\r\n }\r\n\r\n const k = 1024;\r\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\r\n const i = Math.min(\r\n Math.floor(Math.log(bytes) / Math.log(k)),\r\n sizes.length - 1\r\n );\r\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\r\n}\r\n\r\n/**\r\n * Calculate usage percentage capped at 100.\r\n */\r\nexport function calculateUsagePercentage(current: number, limit: number): number {\r\n if (!Number.isFinite(current) || !Number.isFinite(limit) || limit <= 0) {\r\n return 0;\r\n }\r\n\r\n if (current <= 0) {\r\n return 0;\r\n }\r\n\r\n return Math.min(100, Math.round((current / limit) * 100));\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@publikit/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Framework-agnostic utility functions for Publikit packages and applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -11,11 +11,32 @@
|
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
12
|
"import": "./dist/index.js",
|
|
13
13
|
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./cn": {
|
|
16
|
+
"types": "./dist/cn.d.ts",
|
|
17
|
+
"import": "./dist/cn.js",
|
|
18
|
+
"require": "./dist/cn.cjs"
|
|
19
|
+
},
|
|
20
|
+
"./async": {
|
|
21
|
+
"types": "./dist/async.d.ts",
|
|
22
|
+
"import": "./dist/async.js",
|
|
23
|
+
"require": "./dist/async.cjs"
|
|
24
|
+
},
|
|
25
|
+
"./error": {
|
|
26
|
+
"types": "./dist/error.d.ts",
|
|
27
|
+
"import": "./dist/error.js",
|
|
28
|
+
"require": "./dist/error.cjs"
|
|
29
|
+
},
|
|
30
|
+
"./format": {
|
|
31
|
+
"types": "./dist/format.d.ts",
|
|
32
|
+
"import": "./dist/format.js",
|
|
33
|
+
"require": "./dist/format.cjs"
|
|
14
34
|
}
|
|
15
35
|
},
|
|
16
36
|
"files": [
|
|
17
37
|
"dist",
|
|
18
38
|
"README.md",
|
|
39
|
+
"CHANGELOG.md",
|
|
19
40
|
"LICENSE"
|
|
20
41
|
],
|
|
21
42
|
"sideEffects": false,
|
|
@@ -25,7 +46,8 @@
|
|
|
25
46
|
"clean": "rimraf dist",
|
|
26
47
|
"prepublishOnly": "npm run clean && npm run build",
|
|
27
48
|
"typecheck": "tsc --noEmit",
|
|
28
|
-
"test": "vitest run"
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"test:coverage": "vitest run --coverage"
|
|
29
51
|
},
|
|
30
52
|
"keywords": [
|
|
31
53
|
"utilities",
|
|
@@ -39,9 +61,9 @@
|
|
|
39
61
|
"repository": {
|
|
40
62
|
"type": "git",
|
|
41
63
|
"url": "git+https://github.com/pirimera/publikit.git",
|
|
42
|
-
"directory": "utils"
|
|
64
|
+
"directory": "packages/utils"
|
|
43
65
|
},
|
|
44
|
-
"homepage": "https://github.com/pirimera/publikit/tree/main/utils#readme",
|
|
66
|
+
"homepage": "https://github.com/pirimera/publikit/tree/main/packages/utils#readme",
|
|
45
67
|
"bugs": {
|
|
46
68
|
"url": "https://github.com/pirimera/publikit/issues"
|
|
47
69
|
},
|
|
@@ -59,6 +81,7 @@
|
|
|
59
81
|
"rimraf": "^5.0.0",
|
|
60
82
|
"tsup": "^8.0.0",
|
|
61
83
|
"typescript": "^5.8.3",
|
|
84
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
62
85
|
"vitest": "^4.0.18"
|
|
63
86
|
}
|
|
64
87
|
}
|