utills 0.1.2 → 0.1.4

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.
Files changed (70) hide show
  1. package/README.md +91 -12
  2. package/dist/core/copyToClipboard.d.ts +18 -0
  3. package/dist/core/copyToClipboard.d.ts.map +1 -0
  4. package/dist/core/copyToClipboard.js +50 -0
  5. package/dist/core/copyToClipboard.js.map +1 -0
  6. package/dist/core/debounce.d.ts +17 -0
  7. package/dist/core/debounce.d.ts.map +1 -0
  8. package/dist/core/debounce.js +51 -0
  9. package/dist/core/debounce.js.map +1 -0
  10. package/dist/core/formatDate.d.ts +23 -0
  11. package/dist/core/formatDate.d.ts.map +1 -0
  12. package/dist/core/formatDate.js +92 -0
  13. package/dist/core/formatDate.js.map +1 -0
  14. package/dist/core/fuzzySearch.d.ts +22 -0
  15. package/dist/core/fuzzySearch.d.ts.map +1 -0
  16. package/dist/core/fuzzySearch.js +58 -0
  17. package/dist/core/fuzzySearch.js.map +1 -0
  18. package/dist/core/generateSecret.d.ts +1 -0
  19. package/dist/core/generateSecret.d.ts.map +1 -0
  20. package/dist/core/generateSecret.js +1 -0
  21. package/dist/core/generateSecret.js.map +1 -0
  22. package/dist/core/index.d.ts +13 -0
  23. package/dist/core/index.d.ts.map +1 -0
  24. package/dist/core/index.js +13 -0
  25. package/dist/core/index.js.map +1 -0
  26. package/dist/core/paginate.d.ts +19 -0
  27. package/dist/core/paginate.d.ts.map +1 -0
  28. package/dist/core/paginate.js +34 -0
  29. package/dist/core/paginate.js.map +1 -0
  30. package/dist/core/randomId.d.ts +1 -0
  31. package/dist/core/randomId.d.ts.map +1 -0
  32. package/dist/core/randomId.js +1 -0
  33. package/dist/core/randomId.js.map +1 -0
  34. package/dist/core/randomNumber.d.ts +20 -0
  35. package/dist/core/randomNumber.d.ts.map +1 -0
  36. package/dist/core/randomNumber.js +32 -0
  37. package/dist/core/randomNumber.js.map +1 -0
  38. package/dist/core/readTime.d.ts +17 -0
  39. package/dist/core/readTime.d.ts.map +1 -0
  40. package/dist/core/readTime.js +30 -0
  41. package/dist/core/readTime.js.map +1 -0
  42. package/dist/core/slugify.d.ts +21 -0
  43. package/dist/core/slugify.d.ts.map +1 -0
  44. package/dist/core/slugify.js +37 -0
  45. package/dist/core/slugify.js.map +1 -0
  46. package/dist/core/sortBy.d.ts +29 -0
  47. package/dist/core/sortBy.d.ts.map +1 -0
  48. package/dist/core/sortBy.js +66 -0
  49. package/dist/core/sortBy.js.map +1 -0
  50. package/dist/core/throttle.d.ts +30 -0
  51. package/dist/core/throttle.d.ts.map +1 -0
  52. package/dist/core/throttle.js +78 -0
  53. package/dist/core/throttle.js.map +1 -0
  54. package/dist/core/timeAgo.d.ts +1 -0
  55. package/dist/core/timeAgo.d.ts.map +1 -0
  56. package/dist/core/timeAgo.js +1 -0
  57. package/dist/core/timeAgo.js.map +1 -0
  58. package/dist/core/timePeriod.d.ts +9 -0
  59. package/dist/core/timePeriod.d.ts.map +1 -0
  60. package/dist/core/timePeriod.js +28 -0
  61. package/dist/core/timePeriod.js.map +1 -0
  62. package/dist/core/truncate.d.ts +22 -0
  63. package/dist/core/truncate.d.ts.map +1 -0
  64. package/dist/core/truncate.js +70 -0
  65. package/dist/core/truncate.js.map +1 -0
  66. package/dist/index.d.ts +1 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +1 -0
  69. package/dist/index.js.map +1 -0
  70. package/package.json +8 -2
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
- # utils
1
+ # utills
2
2
 
3
- ![thumbmail](./public/assets/utills-web.jpg)
3
+ ![thumbmail](https://raw.githubusercontent.com/safayet35/utills/main/public/assets/utills-web.jpg)
4
4
 
5
5
  Lightweight, dependency-free utility functions for modern JavaScript and TypeScript projects.
6
6
 
7
- This package is designed to be simple, secure, and developer-friendly.
7
+ This package is designed to be **simple**, **secure**, and **developer-friendly**.
8
8
  It works in both **Node.js** and **browser environments** and follows modern **ESM standards**.
9
9
 
10
- **Check out** 👉 [Docs](https://utills.vercel.app/)
10
+ 👉 **Documentation:** https://utills.vercel.app/
11
11
 
12
12
  ---
13
13
 
@@ -18,30 +18,30 @@ It works in both **Node.js** and **browser environments** and follows modern **E
18
18
  - Zero external dependencies
19
19
  - Tree-shaking friendly
20
20
  - Browser & Node.js support
21
- - Secure (crypto-based utilities)
21
+ - Crypto-based secure utilities
22
+ - Fully unit-tested with **Vitest**
22
23
 
23
24
  ---
24
25
 
25
26
  ## 📦 Installation
26
27
 
27
28
  ```bash
28
- npm install utils
29
+ npm install utills
29
30
  ```
30
31
 
31
32
  # Usage
32
33
 
33
34
  ```bash
34
-
35
35
  import {
36
36
  randomId,
37
37
  timeAgo,
38
- } from "utils";
38
+ } from "utills";
39
39
 
40
40
  randomId();
41
41
  timeAgo(Date.now() - 60000);
42
42
  ```
43
43
 
44
- ## Available Utilities
44
+ ## Example Utilities
45
45
 
46
46
  | Method | Parameters | Returns | Description |
47
47
  | ------------------ | ----------------- | -------- | ------------------------------------------------------------ |
@@ -49,9 +49,33 @@ timeAgo(Date.now() - 60000);
49
49
  | **generateSecret** | `length?` | `string` | Generates a cryptographically secure secret token. |
50
50
  | **timeAgo** | `date`, `locale?` | `string` | Returns human-readable relative time (e.g. "2 minutes ago"). |
51
51
 
52
+ ## Testing
53
+
54
+ This project uses Vitest for unit testing.
55
+
56
+ All utility functions must include tests, even if they generate random values.
57
+
58
+ Run test
59
+
60
+ ```bash
61
+ npm run test
62
+ ```
63
+
64
+ Testing rules:
65
+
66
+ - Each utility must have a corresponding test file
67
+ - Random-based utilities should be tested using:
68
+ - output length
69
+ - output type
70
+ - allowed character sets
71
+ - error cases
72
+ - Edge cases must be covered
73
+
52
74
  ## Contributing
53
75
 
54
- Contributions are welcome and appreciated.
76
+ Contributions are welcome and appreciated!
77
+
78
+ Before contributing, please read the guidelines below carefully.
55
79
 
56
80
  ## How to contribute
57
81
 
@@ -76,6 +100,12 @@ git checkout -b feature/new-utility
76
100
  src/core/
77
101
  ```
78
102
 
103
+ Rules
104
+
105
+ - One utility per file
106
+ - Must support both JS & TS
107
+ - Must handle invalid inputs properly
108
+
79
109
  5: Export it from:
80
110
 
81
111
  ```bash
@@ -84,13 +114,57 @@ src/core/index.ts
84
114
 
85
115
  6: Build and test
86
116
 
117
+ Add tests using Vitest for your utility.
118
+
119
+ ```bash
120
+ npm run test
121
+ ```
122
+
123
+ Pull requests **without tests will not be accepted**
124
+
125
+ 7: Update Docs (Required)
126
+
127
+ This project has a docs website.
128
+
129
+ After adding a utility, you must update the docs data file:
130
+
131
+ ```bash
132
+ docs/src/api/methods.data.js
133
+ ```
134
+
135
+ Add your utility following the existing pattern, including:
136
+
137
+ - name
138
+ - description
139
+ - parameters
140
+ - return type
141
+ - example usage
142
+
143
+ Example structure:
144
+
145
+ ```bash
146
+ {
147
+ name: "yourUtility",
148
+ description: "What this utility does",
149
+ params: [],
150
+ returns: "string",
151
+ example: `import { yourUtility } from "utills"
152
+
153
+ yourUtility();`
154
+ }
155
+ ```
156
+
157
+ This data is used to render the API documentation UI
158
+
159
+ 8: Build and verify
160
+
87
161
  ```bash
88
162
  npm run build
89
163
  ```
90
164
 
91
- 7: Commit your changes with a clear message
165
+ 9: Commit & Open PR
92
166
 
93
- 8: Open a Pull Request
167
+ Use clear commit messages and open a Pull Request with a proper description.
94
168
 
95
169
  ## Contribution Guideline
96
170
 
@@ -99,6 +173,8 @@ npm run build
99
173
  - Use native APIs where possible
100
174
  - Handle edge cases properly
101
175
  - Keep code clean and readable
176
+ - Tests are mandatory
177
+ - Utilities should be reusable & generic
102
178
 
103
179
  ## Roadmap
104
180
 
@@ -110,3 +186,6 @@ npm run build
110
186
  ## License
111
187
 
112
188
  MIT License © Safayet Rahman
189
+
190
+
191
+
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copies a string to the system clipboard.
3
+ * Uses the modern Clipboard API where available, with a fallback to `execCommand`
4
+ * for older browsers or non-secure contexts.
5
+ *
6
+ * @param {string} text - The text to copy.
7
+ * @returns {Promise<boolean>} Resolves to `true` if successful, `false` otherwise.
8
+ *
9
+ * @example
10
+ * await copyToClipboard("Hello World");
11
+ *
12
+ * // Handle result
13
+ * if (await copyToClipboard("Token")) {
14
+ * console.log("Copied!");
15
+ * }
16
+ */
17
+ export declare function copyToClipboard(text: string): Promise<boolean>;
18
+ //# sourceMappingURL=copyToClipboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copyToClipboard.d.ts","sourceRoot":"","sources":["../../src/core/copyToClipboard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAoCpE"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Copies a string to the system clipboard.
3
+ * Uses the modern Clipboard API where available, with a fallback to `execCommand`
4
+ * for older browsers or non-secure contexts.
5
+ *
6
+ * @param {string} text - The text to copy.
7
+ * @returns {Promise<boolean>} Resolves to `true` if successful, `false` otherwise.
8
+ *
9
+ * @example
10
+ * await copyToClipboard("Hello World");
11
+ *
12
+ * // Handle result
13
+ * if (await copyToClipboard("Token")) {
14
+ * console.log("Copied!");
15
+ * }
16
+ */
17
+ export async function copyToClipboard(text) {
18
+ if (typeof window === 'undefined' || !text) {
19
+ return false;
20
+ }
21
+ try {
22
+ // 1. Try Modern Async API (Secure contexts only)
23
+ if (navigator?.clipboard?.writeText) {
24
+ await navigator.clipboard.writeText(text);
25
+ return true;
26
+ }
27
+ }
28
+ catch (err) {
29
+ // Continue to fallback if modern API fails
30
+ }
31
+ // 2. Fallback for older browsers or non-HTTPS contexts
32
+ try {
33
+ const textArea = document.createElement('textarea');
34
+ textArea.value = text;
35
+ // Ensure the textarea is not visible but part of the DOM
36
+ textArea.style.position = 'fixed';
37
+ textArea.style.left = '-9999px';
38
+ textArea.style.top = '0';
39
+ document.body.appendChild(textArea);
40
+ textArea.focus();
41
+ textArea.select();
42
+ const successful = document.execCommand('copy');
43
+ document.body.removeChild(textArea);
44
+ return successful;
45
+ }
46
+ catch (err) {
47
+ return false;
48
+ }
49
+ }
50
+ //# sourceMappingURL=copyToClipboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copyToClipboard.js","sourceRoot":"","sources":["../../src/core/copyToClipboard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY;IAChD,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,CAAC,IAAI,EAAE,CAAC;QAC3C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,iDAAiD;QACjD,IAAI,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;YACpC,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,2CAA2C;IAC7C,CAAC;IAED,uDAAuD;IACvD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACpD,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;QAEtB,yDAAyD;QACzD,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC;QAClC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC;QAChC,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;QACzB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAEpC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACjB,QAAQ,CAAC,MAAM,EAAE,CAAC;QAElB,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAChD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAEpC,OAAO,UAAU,CAAC;IACpB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Creates a debounced version of a function that delays its execution.
3
+ * Useful for optimizing frequent events like search input, resize, or scroll.
4
+ *
5
+ * @example
6
+ * const debouncedFn = debounce((value: string) => {
7
+ * console.log(value);
8
+ * }, 300);
9
+ *
10
+ * debouncedFn("hello");
11
+ */
12
+ export declare function debounce<T extends (...args: any[]) => void>(fn: T, delay: number): {
13
+ (...args: Parameters<T>): void;
14
+ cancel: () => void;
15
+ flush: () => void;
16
+ };
17
+ //# sourceMappingURL=debounce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../src/core/debounce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,EACzD,EAAE,EAAE,CAAC,EACL,KAAK,EAAE,MAAM,GACZ;IACD,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CA8CA"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Creates a debounced version of a function that delays its execution.
3
+ * Useful for optimizing frequent events like search input, resize, or scroll.
4
+ *
5
+ * @example
6
+ * const debouncedFn = debounce((value: string) => {
7
+ * console.log(value);
8
+ * }, 300);
9
+ *
10
+ * debouncedFn("hello");
11
+ */
12
+ export function debounce(fn, delay) {
13
+ if (typeof fn !== "function") {
14
+ throw new TypeError("debounce: fn must be a function");
15
+ }
16
+ if (typeof delay !== "number" || delay < 0) {
17
+ throw new TypeError("debounce: delay must be a non-negative number");
18
+ }
19
+ let timer = null;
20
+ let lastArgs = null;
21
+ const debounced = (...args) => {
22
+ lastArgs = args;
23
+ if (timer) {
24
+ clearTimeout(timer);
25
+ }
26
+ timer = setTimeout(() => {
27
+ timer = null;
28
+ if (lastArgs) {
29
+ fn(...lastArgs);
30
+ lastArgs = null;
31
+ }
32
+ }, delay);
33
+ };
34
+ debounced.cancel = () => {
35
+ if (timer) {
36
+ clearTimeout(timer);
37
+ timer = null;
38
+ lastArgs = null;
39
+ }
40
+ };
41
+ debounced.flush = () => {
42
+ if (timer && lastArgs) {
43
+ clearTimeout(timer);
44
+ fn(...lastArgs);
45
+ timer = null;
46
+ lastArgs = null;
47
+ }
48
+ };
49
+ return debounced;
50
+ }
51
+ //# sourceMappingURL=debounce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debounce.js","sourceRoot":"","sources":["../../src/core/debounce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,QAAQ,CACtB,EAAK,EACL,KAAa;IAMb,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,IAAI,SAAS,CAAC,iCAAiC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,SAAS,CAAC,+CAA+C,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,KAAK,GAAyC,IAAI,CAAC;IACvD,IAAI,QAAQ,GAAyB,IAAI,CAAC;IAE1C,MAAM,SAAS,GAAG,CAAC,GAAG,IAAmB,EAAE,EAAE;QAC3C,QAAQ,GAAG,IAAI,CAAC;QAEhB,IAAI,KAAK,EAAE,CAAC;YACV,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QAED,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YACtB,KAAK,GAAG,IAAI,CAAC;YACb,IAAI,QAAQ,EAAE,CAAC;gBACb,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC;gBAChB,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;QACH,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC,CAAC;IAEF,SAAS,CAAC,MAAM,GAAG,GAAG,EAAE;QACtB,IAAI,KAAK,EAAE,CAAC;YACV,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,KAAK,GAAG,IAAI,CAAC;YACb,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IAEF,SAAS,CAAC,KAAK,GAAG,GAAG,EAAE;QACrB,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;YACtB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC;YAChB,KAAK,GAAG,IAAI,CAAC;YACb,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Formats a date into a specific pattern, locale-based style, or relative time.
3
+ * Supports internationalization (i18n) via locale codes.
4
+ *
5
+ * @param {Date | string | number} date - The input date.
6
+ * @param {string} [format="medium"] - The pattern (e.g., "YYYY-MM-DD"), style ("full", "long", "medium", "short"), or "relative".
7
+ * @param {string} [locale="en-US"] - The BCP 47 language tag (e.g., "en-US", "bn-BD").
8
+ * @returns {string} The formatted string.
9
+ * @throws {TypeError} If the date is invalid.
10
+ *
11
+ * @example
12
+ * // Custom Pattern
13
+ * formatDate(new Date(), "DD MMMM, YYYY", "bn-BD"); // "২৫ অক্টোবর, ২০২৩"
14
+ *
15
+ * // Standard Styles
16
+ * formatDate(new Date(), "full", "en-US"); // "Wednesday, October 25, 2023"
17
+ *
18
+ * // Relative Time
19
+ * formatDate(Date.now() - 3600000, "relative", "en-US"); // "1 hour ago"
20
+ * formatDate(Date.now() - 3600000, "relative", "bn-BD"); // "১ ঘণ্টা আগে"
21
+ */
22
+ export declare function formatDate(date: Date | string | number, format?: string, locale?: string): string;
23
+ //# sourceMappingURL=formatDate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatDate.d.ts","sourceRoot":"","sources":["../../src/core/formatDate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAC5B,MAAM,GAAE,MAAiB,EACzB,MAAM,GAAE,MAAgB,GACvB,MAAM,CAyER"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Formats a date into a specific pattern, locale-based style, or relative time.
3
+ * Supports internationalization (i18n) via locale codes.
4
+ *
5
+ * @param {Date | string | number} date - The input date.
6
+ * @param {string} [format="medium"] - The pattern (e.g., "YYYY-MM-DD"), style ("full", "long", "medium", "short"), or "relative".
7
+ * @param {string} [locale="en-US"] - The BCP 47 language tag (e.g., "en-US", "bn-BD").
8
+ * @returns {string} The formatted string.
9
+ * @throws {TypeError} If the date is invalid.
10
+ *
11
+ * @example
12
+ * // Custom Pattern
13
+ * formatDate(new Date(), "DD MMMM, YYYY", "bn-BD"); // "২৫ অক্টোবর, ২০২৩"
14
+ *
15
+ * // Standard Styles
16
+ * formatDate(new Date(), "full", "en-US"); // "Wednesday, October 25, 2023"
17
+ *
18
+ * // Relative Time
19
+ * formatDate(Date.now() - 3600000, "relative", "en-US"); // "1 hour ago"
20
+ * formatDate(Date.now() - 3600000, "relative", "bn-BD"); // "১ ঘণ্টা আগে"
21
+ */
22
+ export function formatDate(date, format = "medium", locale = "en-US") {
23
+ const d = new Date(date);
24
+ if (isNaN(d.getTime())) {
25
+ throw new TypeError("Invalid date provided");
26
+ }
27
+ // 1. Handle "Relative" Time (e.g., "2 hours ago")
28
+ if (format === "relative") {
29
+ const diff = Date.now() - d.getTime();
30
+ const isFuture = diff < 0;
31
+ const absDiff = Math.abs(diff);
32
+ const seconds = Math.floor(absDiff / 1000);
33
+ const minutes = Math.floor(seconds / 60);
34
+ const hours = Math.floor(minutes / 60);
35
+ const days = Math.floor(hours / 24);
36
+ const months = Math.floor(days / 30);
37
+ const years = Math.floor(days / 365);
38
+ // Create localized relative formatter
39
+ // Note: Intl.RelativeTimeFormat is supported in Node 12+ and all modern browsers
40
+ const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
41
+ const dir = isFuture ? 1 : -1; // 1 for future ("in..."), -1 for past ("...ago")
42
+ if (years > 0)
43
+ return rtf.format(years * dir, "year");
44
+ if (months > 0)
45
+ return rtf.format(months * dir, "month");
46
+ if (days > 0)
47
+ return rtf.format(days * dir, "day");
48
+ if (hours > 0)
49
+ return rtf.format(hours * dir, "hour");
50
+ if (minutes > 0)
51
+ return rtf.format(minutes * dir, "minute");
52
+ return rtf.format(seconds * dir, "second");
53
+ }
54
+ // 2. Handle Standard Intl Styles (full, long, medium, short)
55
+ const styles = ["full", "long", "medium", "short"];
56
+ if (styles.includes(format)) {
57
+ return new Intl.DateTimeFormat(locale, {
58
+ dateStyle: format,
59
+ // timeStyle can be added optionally, but usually strictly requested for dates
60
+ }).format(d);
61
+ }
62
+ // 3. Handle Custom Token Pattern (e.g., YYYY-MM-DD)
63
+ // We use Intl for specific names (Months, Days) to support the locale
64
+ const getPart = (options) => new Intl.DateTimeFormat(locale, options).format(d);
65
+ const map = {
66
+ YYYY: getPart({ year: "numeric" }), // 2023 or ২০২৩ (if locale supports numberingSystem)
67
+ YY: getPart({ year: "2-digit" }),
68
+ MMMM: getPart({ month: "long" }), // January / জানুয়ারি
69
+ MMM: getPart({ month: "short" }), // Jan / জানু
70
+ MM: getPart({ month: "2-digit" }), // 01
71
+ M: getPart({ month: "numeric" }), // 1
72
+ dddd: getPart({ weekday: "long" }), // Monday / সোমবার
73
+ ddd: getPart({ weekday: "short" }), // Mon / সোম
74
+ DD: getPart({ day: "2-digit" }), // 25
75
+ D: getPart({ day: "numeric" }), // 25
76
+ HH: String(d.getHours()).padStart(2, "0"), // Keeping time ISO/numeric for patterns usually
77
+ H: d.getHours(),
78
+ hh: String(d.getHours() % 12 || 12).padStart(2, "0"),
79
+ h: d.getHours() % 12 || 12,
80
+ mm: String(d.getMinutes()).padStart(2, "0"),
81
+ ss: String(d.getSeconds()).padStart(2, "0"),
82
+ a: getPart({ hour: "numeric", hour12: true }).replace(/[^a-zA-Z]/g, ""), // Extract AM/PM locally if possible, or fallback logic
83
+ };
84
+ // Custom Regex for replacement
85
+ const regex = /\[([^\]]+)]|YYYY|YY|MMMM|MMM|MM|M|dddd|ddd|DD|D|HH|H|hh|h|mm|ss|a/g;
86
+ return format.replace(regex, (match, escapedText) => {
87
+ if (escapedText)
88
+ return escapedText;
89
+ return String(map[match]);
90
+ });
91
+ }
92
+ //# sourceMappingURL=formatDate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatDate.js","sourceRoot":"","sources":["../../src/core/formatDate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Perform an advanced lightweight fuzzy search on an array of objects.
3
+ * Supports multiple keys, nested keys (dot-notation), case sensitivity,
4
+ * and partial fuzzy matching.
5
+ *
6
+ * Design decision:
7
+ * - `keys` is OPTIONAL.
8
+ * If not provided, all enumerable values of the object are searched.
9
+ * This keeps the API flexible while allowing strict control when needed.
10
+ *
11
+ * @example
12
+ * fuzzySearch(users, "john", { keys: ["name", "email"] });
13
+ *
14
+ * @example
15
+ * fuzzySearch(posts, "react", { keys: ["author.name", "title"] });
16
+ */
17
+ export declare function fuzzySearch<T extends Record<string, any>>(list: T[], query: string, options?: {
18
+ keys?: string[];
19
+ caseSensitive?: boolean;
20
+ threshold?: number;
21
+ }): T[];
22
+ //# sourceMappingURL=fuzzySearch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fuzzySearch.d.ts","sourceRoot":"","sources":["../../src/core/fuzzySearch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACvD,IAAI,EAAE,CAAC,EAAE,EACT,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IACR,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACA,CAAC,EAAE,CAsDL"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Perform an advanced lightweight fuzzy search on an array of objects.
3
+ * Supports multiple keys, nested keys (dot-notation), case sensitivity,
4
+ * and partial fuzzy matching.
5
+ *
6
+ * Design decision:
7
+ * - `keys` is OPTIONAL.
8
+ * If not provided, all enumerable values of the object are searched.
9
+ * This keeps the API flexible while allowing strict control when needed.
10
+ *
11
+ * @example
12
+ * fuzzySearch(users, "john", { keys: ["name", "email"] });
13
+ *
14
+ * @example
15
+ * fuzzySearch(posts, "react", { keys: ["author.name", "title"] });
16
+ */
17
+ export function fuzzySearch(list, query, options) {
18
+ if (!Array.isArray(list)) {
19
+ throw new TypeError("fuzzySearch: list must be an array");
20
+ }
21
+ if (typeof query !== "string") {
22
+ throw new TypeError("fuzzySearch: query must be a string");
23
+ }
24
+ const { keys, caseSensitive = false, threshold = 0.4, } = options || {};
25
+ if (typeof threshold !== "number" || threshold < 0 || threshold > 1) {
26
+ throw new TypeError("fuzzySearch: threshold must be between 0 and 1");
27
+ }
28
+ if (query.trim() === "")
29
+ return list;
30
+ const normalize = (value) => caseSensitive ? value : value.toLowerCase();
31
+ const normalizedQuery = normalize(query);
32
+ function getValueByPath(obj, path) {
33
+ return path
34
+ .split(".")
35
+ .reduce((acc, key) => (acc != null ? acc[key] : undefined), obj) ?? "";
36
+ }
37
+ function similarity(a, b) {
38
+ let matches = 0;
39
+ const len = Math.max(a.length, b.length);
40
+ for (let i = 0; i < Math.min(a.length, b.length); i++) {
41
+ if (a[i] === b[i])
42
+ matches++;
43
+ }
44
+ return len === 0 ? 0 : matches / len;
45
+ }
46
+ return list.filter((item) => {
47
+ const values = keys
48
+ ? keys.map((key) => String(getValueByPath(item, key)))
49
+ : Object.values(item).map((v) => String(v));
50
+ return values.some((value) => {
51
+ const source = normalize(value);
52
+ if (source.includes(normalizedQuery))
53
+ return true;
54
+ return similarity(source, normalizedQuery) >= threshold;
55
+ });
56
+ });
57
+ }
58
+ //# sourceMappingURL=fuzzySearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fuzzySearch.js","sourceRoot":"","sources":["../../src/core/fuzzySearch.ts"],"names":[],"mappings":"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"}
@@ -7,3 +7,4 @@
7
7
  * generateSecret(64)
8
8
  */
9
9
  export declare function generateSecret(length?: number): string;
10
+ //# sourceMappingURL=generateSecret.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateSecret.d.ts","sourceRoot":"","sources":["../../src/core/generateSecret.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,GAAE,MAAW,GAAG,MAAM,CAwB1D"}
@@ -25,3 +25,4 @@ export function generateSecret(length = 32) {
25
25
  }
26
26
  return secret;
27
27
  }
28
+ //# sourceMappingURL=generateSecret.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateSecret.js","sourceRoot":"","sources":["../../src/core/generateSecret.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE;IAChD,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;IAClE,CAAC;IAED,MAAM,OAAO,GAAG,gEAAgE,CAAA;IAChF,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAA;IAEpC,mCAAmC;IACnC,MAAM,SAAS,GACb,OAAO,MAAM,KAAK,WAAW;QAC3B,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,aAAa;YACb,OAAO,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAA;IAEjC,MAAM,YAAY,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAA;IAC5C,SAAS,CAAC,eAAe,CAAC,YAAY,CAAC,CAAA;IAEvC,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAA;IACpD,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -1,3 +1,16 @@
1
1
  export { randomId } from "./randomId.js";
2
2
  export { generateSecret } from "./generateSecret.js";
3
3
  export { timeAgo } from "./timeAgo.js";
4
+ export { timePeriod } from "./timePeriod.js";
5
+ export { readTime } from "./readTime.js";
6
+ export { fuzzySearch } from "./fuzzySearch.js";
7
+ export { debounce } from "./debounce.js";
8
+ export { throttle } from "./throttle.js";
9
+ export { paginate } from "./paginate.js";
10
+ export { slugify } from "./slugify.js";
11
+ export { truncate } from "./truncate.js";
12
+ export { sortBy } from "./sortBy.js";
13
+ export { randomNumber } from "./randomNumber.js";
14
+ export { copyToClipboard } from "./copyToClipboard.js";
15
+ export { formatDate } from "./formatDate.js";
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA"}
@@ -1,3 +1,16 @@
1
1
  export { randomId } from "./randomId.js";
2
2
  export { generateSecret } from "./generateSecret.js";
3
3
  export { timeAgo } from "./timeAgo.js";
4
+ export { timePeriod } from "./timePeriod.js";
5
+ export { readTime } from "./readTime.js";
6
+ export { fuzzySearch } from "./fuzzySearch.js";
7
+ export { debounce } from "./debounce.js";
8
+ export { throttle } from "./throttle.js";
9
+ export { paginate } from "./paginate.js";
10
+ export { slugify } from "./slugify.js";
11
+ export { truncate } from "./truncate.js";
12
+ export { sortBy } from "./sortBy.js";
13
+ export { randomNumber } from "./randomNumber.js";
14
+ export { copyToClipboard } from "./copyToClipboard.js";
15
+ export { formatDate } from "./formatDate.js";
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Create frontend-friendly pagination data from a list.
3
+ *
4
+ * @example
5
+ * paginate(items, { page: 1, pageSize: 10 });
6
+ */
7
+ export declare function paginate<T>(list: T[], options?: {
8
+ page?: number;
9
+ pageSize?: number;
10
+ }): {
11
+ data: T[];
12
+ page: number;
13
+ pageSize: number;
14
+ totalItems: number;
15
+ totalPages: number;
16
+ hasNext: boolean;
17
+ hasPrev: boolean;
18
+ };
19
+ //# sourceMappingURL=paginate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paginate.d.ts","sourceRoot":"","sources":["../../src/core/paginate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACxB,IAAI,EAAE,CAAC,EAAE,EACT,OAAO,CAAC,EAAE;IACR,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA;IACD,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB,CAgCA"}