@kaiserofthenight/human-js 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.
@@ -0,0 +1,209 @@
1
+ /**
2
+ * UTILITY HELPER FUNCTIONS
3
+ *
4
+ * Common utilities for everyday development.
5
+ */
6
+
7
+ /**
8
+ * Generate unique ID
9
+ */
10
+ export function uid(prefix = 'id') {
11
+ return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
12
+ }
13
+
14
+ /**
15
+ * Deep clone object
16
+ */
17
+ export function clone(obj) {
18
+ return JSON.parse(JSON.stringify(obj));
19
+ }
20
+
21
+ /**
22
+ * Deep merge objects
23
+ */
24
+ export function merge(...objects) {
25
+ return objects.reduce((result, obj) => {
26
+ Object.keys(obj).forEach(key => {
27
+ if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
28
+ result[key] = merge(result[key] || {}, obj[key]);
29
+ } else {
30
+ result[key] = obj[key];
31
+ }
32
+ });
33
+ return result;
34
+ }, {});
35
+ }
36
+
37
+ /**
38
+ * Format date
39
+ */
40
+ export function formatDate(date, format = 'YYYY-MM-DD') {
41
+ const d = new Date(date);
42
+ const year = d.getFullYear();
43
+ const month = String(d.getMonth() + 1).padStart(2, '0');
44
+ const day = String(d.getDate()).padStart(2, '0');
45
+ const hours = String(d.getHours()).padStart(2, '0');
46
+ const minutes = String(d.getMinutes()).padStart(2, '0');
47
+ const seconds = String(d.getSeconds()).padStart(2, '0');
48
+
49
+ return format
50
+ .replace('YYYY', year)
51
+ .replace('MM', month)
52
+ .replace('DD', day)
53
+ .replace('HH', hours)
54
+ .replace('mm', minutes)
55
+ .replace('ss', seconds);
56
+ }
57
+
58
+ /**
59
+ * Sleep/delay
60
+ */
61
+ export function sleep(ms) {
62
+ return new Promise(resolve => setTimeout(resolve, ms));
63
+ }
64
+
65
+ /**
66
+ * Capitalize string
67
+ */
68
+ export function capitalize(str) {
69
+ return str.charAt(0).toUpperCase() + str.slice(1);
70
+ }
71
+
72
+ /**
73
+ * Truncate string
74
+ */
75
+ export function truncate(str, length = 50, suffix = '...') {
76
+ if (str.length <= length) return str;
77
+ return str.substring(0, length) + suffix;
78
+ }
79
+
80
+ /**
81
+ * Random number between min and max
82
+ */
83
+ export function random(min, max) {
84
+ return Math.floor(Math.random() * (max - min + 1)) + min;
85
+ }
86
+
87
+ /**
88
+ * Shuffle array
89
+ */
90
+ export function shuffle(array) {
91
+ const copy = [...array];
92
+ for (let i = copy.length - 1; i > 0; i--) {
93
+ const j = Math.floor(Math.random() * (i + 1));
94
+ [copy[i], copy[j]] = [copy[j], copy[i]];
95
+ }
96
+ return copy;
97
+ }
98
+
99
+ /**
100
+ * Group array by key
101
+ */
102
+ export function groupBy(array, key) {
103
+ return array.reduce((result, item) => {
104
+ const group = typeof key === 'function' ? key(item) : item[key];
105
+ if (!result[group]) result[group] = [];
106
+ result[group].push(item);
107
+ return result;
108
+ }, {});
109
+ }
110
+
111
+ /**
112
+ * Unique array values
113
+ */
114
+ export function unique(array) {
115
+ return [...new Set(array)];
116
+ }
117
+
118
+ /**
119
+ * Check if object is empty
120
+ */
121
+ export function isEmpty(obj) {
122
+ if (obj === null || obj === undefined) return true;
123
+ if (Array.isArray(obj)) return obj.length === 0;
124
+ if (typeof obj === 'object') return Object.keys(obj).length === 0;
125
+ return false;
126
+ }
127
+
128
+ /**
129
+ * Get nested object property safely
130
+ */
131
+ export function get(obj, path, defaultValue = undefined) {
132
+ const keys = path.split('.');
133
+ let result = obj;
134
+
135
+ for (const key of keys) {
136
+ if (result === null || result === undefined) {
137
+ return defaultValue;
138
+ }
139
+ result = result[key];
140
+ }
141
+
142
+ return result !== undefined ? result : defaultValue;
143
+ }
144
+
145
+ /**
146
+ * Set nested object property
147
+ */
148
+ export function set(obj, path, value) {
149
+ const keys = path.split('.');
150
+ const lastKey = keys.pop();
151
+ let current = obj;
152
+
153
+ for (const key of keys) {
154
+ if (!current[key] || typeof current[key] !== 'object') {
155
+ current[key] = {};
156
+ }
157
+ current = current[key];
158
+ }
159
+
160
+ current[lastKey] = value;
161
+ return obj;
162
+ }
163
+
164
+ /**
165
+ * Pick properties from object
166
+ */
167
+ export function pick(obj, keys) {
168
+ return keys.reduce((result, key) => {
169
+ if (key in obj) result[key] = obj[key];
170
+ return result;
171
+ }, {});
172
+ }
173
+
174
+ /**
175
+ * Omit properties from object
176
+ */
177
+ export function omit(obj, keys) {
178
+ const result = { ...obj };
179
+ keys.forEach(key => delete result[key]);
180
+ return result;
181
+ }
182
+
183
+ /**
184
+ * Wait for condition to be true
185
+ */
186
+ export async function waitFor(condition, timeout = 5000) {
187
+ const startTime = Date.now();
188
+
189
+ while (!condition()) {
190
+ if (Date.now() - startTime > timeout) {
191
+ throw new Error('Timeout waiting for condition');
192
+ }
193
+ await sleep(100);
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Retry function on failure
199
+ */
200
+ export async function retry(fn, maxAttempts = 3, delay = 1000) {
201
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
202
+ try {
203
+ return await fn();
204
+ } catch (error) {
205
+ if (attempt === maxAttempts) throw error;
206
+ await sleep(delay);
207
+ }
208
+ }
209
+ }