@sohanemon/utils 6.3.8 → 6.4.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/README.md +12 -2
- package/dist/components/index.cjs +1 -1
- package/dist/components/index.d.cts +101 -5
- package/dist/components/index.d.ts +97 -1
- package/dist/components/index.js +1 -1
- package/dist/{functions-DdbPkP6e.cjs → functions-BQWC9vZ0.cjs} +1 -1
- package/dist/hooks/index.cjs +1 -1
- package/dist/hooks/index.d.cts +337 -23
- package/dist/hooks/index.d.ts +337 -23
- package/dist/hooks/index.js +1 -1
- package/dist/hooks-C9b8HxlS.js +1 -0
- package/dist/hooks-CswCcD42.cjs +1 -0
- package/dist/{index-BZaFEd2-.d.ts → index-CKE8ocfo.d.ts} +479 -59
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +890 -57
- package/dist/index.d.ts +443 -1
- package/dist/schedule-BqFAJlSO.d.cts +43 -0
- package/package.json +4 -2
- package/dist/hooks-Brgpm2Un.cjs +0 -1
- package/dist/hooks-CKCxXGDE.js +0 -1
- package/dist/schedule-CRsY0oqG.d.cts +0 -15
package/dist/index.d.cts
CHANGED
|
@@ -1,11 +1,63 @@
|
|
|
1
|
-
import { n as Task, r as schedule, t as ScheduleOpts } from "./schedule-
|
|
1
|
+
import { n as Task, r as schedule, t as ScheduleOpts } from "./schedule-BqFAJlSO.cjs";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { ClassValue } from "clsx";
|
|
4
4
|
|
|
5
5
|
//#region src/functions/cookie.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Sets a client-side cookie with optional expiration and path.
|
|
9
|
+
*
|
|
10
|
+
* @param name - The name of the cookie
|
|
11
|
+
* @param value - The value to store in the cookie
|
|
12
|
+
* @param days - Optional number of days until the cookie expires
|
|
13
|
+
* @param path - Optional path for the cookie (defaults to '/')
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Set a cookie that expires in 7 days
|
|
17
|
+
* setClientSideCookie('userId', '12345', 7);
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // Set a session cookie (no expiration)
|
|
21
|
+
* setClientSideCookie('sessionId', 'abc123');
|
|
22
|
+
*/
|
|
6
23
|
declare const setClientSideCookie: (name: string, value: string, days?: number, path?: string) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Deletes a client-side cookie by setting its expiration to a past date.
|
|
26
|
+
*
|
|
27
|
+
* @param name - The name of the cookie to delete
|
|
28
|
+
* @param path - Optional path for the cookie (defaults to '/')
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // Delete a cookie
|
|
32
|
+
* deleteClientSideCookie('userId');
|
|
33
|
+
*/
|
|
7
34
|
declare const deleteClientSideCookie: (name: string, path?: string) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Checks if a client-side cookie exists.
|
|
37
|
+
*
|
|
38
|
+
* @param name - The name of the cookie to check
|
|
39
|
+
* @returns True if the cookie exists, false otherwise
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* // Check if a cookie exists
|
|
43
|
+
* if (hasClientSideCookie('userId')) {
|
|
44
|
+
* console.log('User is logged in');
|
|
45
|
+
* }
|
|
46
|
+
*/
|
|
8
47
|
declare const hasClientSideCookie: (name: string) => boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Retrieves the value of a client-side cookie.
|
|
50
|
+
*
|
|
51
|
+
* @param name - The name of the cookie to retrieve
|
|
52
|
+
* @returns An object containing the cookie value, or undefined if not found
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* // Get a cookie value
|
|
56
|
+
* const { value } = getClientSideCookie('userId');
|
|
57
|
+
* if (value) {
|
|
58
|
+
* console.log('User ID:', value);
|
|
59
|
+
* }
|
|
60
|
+
*/
|
|
9
61
|
declare const getClientSideCookie: (name: string) => {
|
|
10
62
|
value: string | undefined;
|
|
11
63
|
};
|
|
@@ -41,20 +93,52 @@ type TMerged<T> = [T] extends [Array<any>] ? { [K in keyof T]: TMerged<T[K]> } :
|
|
|
41
93
|
* @returns The merged object with proper typing
|
|
42
94
|
*
|
|
43
95
|
* @example
|
|
44
|
-
* // Basic merge
|
|
96
|
+
* // Basic shallow merge
|
|
45
97
|
* deepmerge({ a: 1 }, { b: 2 }) // { a: 1, b: 2 }
|
|
46
98
|
*
|
|
47
99
|
* @example
|
|
48
|
-
* //
|
|
49
|
-
* deepmerge({
|
|
100
|
+
* // Deep merge of nested objects
|
|
101
|
+
* deepmerge({ user: { name: 'John' } }, { user: { age: 30 } })
|
|
102
|
+
* // { user: { name: 'John', age: 30 } }
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* // Array concatenation
|
|
106
|
+
* deepmerge({ tags: ['react'] }, { tags: ['typescript'] }, { arrayMerge: 'concat' })
|
|
107
|
+
* // { tags: ['react', 'typescript'] }
|
|
50
108
|
*
|
|
51
109
|
* @example
|
|
52
|
-
* // Array
|
|
53
|
-
* deepmerge({
|
|
110
|
+
* // Array replacement (default)
|
|
111
|
+
* deepmerge({ items: [1, 2] }, { items: [3, 4] })
|
|
112
|
+
* // { items: [3, 4] }
|
|
54
113
|
*
|
|
55
114
|
* @example
|
|
56
|
-
* //
|
|
57
|
-
* deepmerge(
|
|
115
|
+
* // Custom array merging
|
|
116
|
+
* deepmerge(
|
|
117
|
+
* { scores: [85, 90] },
|
|
118
|
+
* { scores: [95] },
|
|
119
|
+
* { arrayMerge: (target, source) => [...target, ...source] }
|
|
120
|
+
* )
|
|
121
|
+
* // { scores: [85, 90, 95] }
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* // Configuration merging
|
|
125
|
+
* const defaultConfig = { theme: 'light', features: { darkMode: false } };
|
|
126
|
+
* const userConfig = { theme: 'dark', features: { darkMode: true, animations: true } };
|
|
127
|
+
* deepmerge(defaultConfig, userConfig);
|
|
128
|
+
* // { theme: 'dark', features: { darkMode: true, animations: true } }
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* // State updates in reducers
|
|
132
|
+
* const initialState = { user: { profile: { name: '' } }, settings: {} };
|
|
133
|
+
* const action = { user: { profile: { name: 'Alice' } }, settings: { theme: 'dark' } };
|
|
134
|
+
* const newState = deepmerge(initialState, action);
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* // Merging API responses
|
|
138
|
+
* const cachedData = { posts: [{ id: 1, title: 'Old' }] };
|
|
139
|
+
* const freshData = { posts: [{ id: 1, title: 'Updated', author: 'Bob' }] };
|
|
140
|
+
* deepmerge(cachedData, freshData);
|
|
141
|
+
* // { posts: [{ id: 1, title: 'Updated', author: 'Bob' }] }
|
|
58
142
|
*/
|
|
59
143
|
declare function deepmerge<T extends Record<string, any>, S$1 extends Record<string, any>[]>(target: T, ...sources: S$1): TMerged<T | S$1[number]>;
|
|
60
144
|
declare function deepmerge<T extends Record<string, any>, S$1 extends Record<string, any>[]>(target: T, sources: S$1, options?: {
|
|
@@ -73,8 +157,42 @@ type Hydrate<T> = T extends null ? undefined : T extends (infer U)[] ? Hydrate<U
|
|
|
73
157
|
* @returns Same type as input, but with all nulls replaced by undefined
|
|
74
158
|
*
|
|
75
159
|
* @example
|
|
76
|
-
*
|
|
77
|
-
*
|
|
160
|
+
* ```ts
|
|
161
|
+
* // Basic object hydration
|
|
162
|
+
* hydrate({ name: null, age: 25 }) // { name: undefined, age: 25 }
|
|
163
|
+
*
|
|
164
|
+
* // Nested object hydration
|
|
165
|
+
* hydrate({
|
|
166
|
+
* user: { email: null, profile: { avatar: null } },
|
|
167
|
+
* settings: { theme: 'dark' }
|
|
168
|
+
* })
|
|
169
|
+
* // { user: { email: undefined, profile: { avatar: undefined } }, settings: { theme: 'dark' } }
|
|
170
|
+
*
|
|
171
|
+
* // Array hydration
|
|
172
|
+
* hydrate([null, 'hello', null, 42]) // [undefined, 'hello', undefined, 42]
|
|
173
|
+
*
|
|
174
|
+
* // Mixed data structures
|
|
175
|
+
* hydrate({
|
|
176
|
+
* posts: [null, { title: 'Hello', content: null }],
|
|
177
|
+
* metadata: { published: null, tags: ['react', null] }
|
|
178
|
+
* })
|
|
179
|
+
* ```
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```ts
|
|
183
|
+
* // API response normalization
|
|
184
|
+
* const apiResponse = await fetch('/api/user');
|
|
185
|
+
* const rawData = await apiResponse.json(); // May contain null values
|
|
186
|
+
* const normalizedData = hydrate(rawData); // Convert nulls to undefined
|
|
187
|
+
*
|
|
188
|
+
* // Database result processing
|
|
189
|
+
* const dbResult = query('SELECT * FROM users'); // Some fields may be NULL
|
|
190
|
+
* const cleanData = hydrate(dbResult); // Normalize for consistent handling
|
|
191
|
+
*
|
|
192
|
+
* // Form data sanitization
|
|
193
|
+
* const formData = getFormValues(); // May have null values from empty fields
|
|
194
|
+
* const sanitizedData = hydrate(formData); // Prepare for validation/state
|
|
195
|
+
* ```
|
|
78
196
|
*/
|
|
79
197
|
declare function hydrate<T>(data: T): Hydrate<T>;
|
|
80
198
|
//#endregion
|
|
@@ -158,14 +276,32 @@ declare function getObjectValue<T, S$1 extends string>(obj: T, path: S$1): GetVa
|
|
|
158
276
|
* @returns The same object/function, augmented with the given properties
|
|
159
277
|
*
|
|
160
278
|
* @example
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
* const
|
|
168
|
-
*
|
|
279
|
+
* ```ts
|
|
280
|
+
* // Extend a plain object
|
|
281
|
+
* const config = extendProps({ apiUrl: '/api' }, { timeout: 5000 });
|
|
282
|
+
* // config has both apiUrl and timeout properties
|
|
283
|
+
*
|
|
284
|
+
* // Extend a function with metadata
|
|
285
|
+
* const fetchData = (url: string) => fetch(url).then(r => r.json());
|
|
286
|
+
* const enhancedFetch = extendProps(fetchData, {
|
|
287
|
+
* description: 'Data fetching utility',
|
|
288
|
+
* version: '1.0'
|
|
289
|
+
* });
|
|
290
|
+
* // enhancedFetch is callable and has description/version properties
|
|
291
|
+
*
|
|
292
|
+
* // Create plugin system
|
|
293
|
+
* const basePlugin = { name: 'base', enabled: true };
|
|
294
|
+
* const authPlugin = extendProps(basePlugin, {
|
|
295
|
+
* authenticate: (token: string) => validateToken(token)
|
|
296
|
+
* });
|
|
297
|
+
*
|
|
298
|
+
* // Build configuration objects
|
|
299
|
+
* const defaultSettings = { theme: 'light', lang: 'en' };
|
|
300
|
+
* const userSettings = extendProps(defaultSettings, {
|
|
301
|
+
* theme: 'dark',
|
|
302
|
+
* notifications: true
|
|
303
|
+
* });
|
|
304
|
+
* ```
|
|
169
305
|
*/
|
|
170
306
|
declare function extendProps<T extends object, P$1 extends object>(base: T, props: P$1): T & P$1;
|
|
171
307
|
//#endregion
|
|
@@ -196,11 +332,52 @@ declare function extendProps<T extends object, P$1 extends object>(base: T, prop
|
|
|
196
332
|
*
|
|
197
333
|
* @example
|
|
198
334
|
* ```ts
|
|
335
|
+
* // Poll for job completion
|
|
199
336
|
* const job = await poll(async () => {
|
|
200
337
|
* const status = await getJobStatus();
|
|
201
338
|
* return status === 'done' ? status : null;
|
|
202
339
|
* }, { interval: 3000, timeout: 60000 });
|
|
203
340
|
* ```
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* ```ts
|
|
344
|
+
* // Wait for API endpoint to be ready
|
|
345
|
+
* const apiReady = await poll(async () => {
|
|
346
|
+
* try {
|
|
347
|
+
* await fetch('/api/health');
|
|
348
|
+
* return true;
|
|
349
|
+
* } catch {
|
|
350
|
+
* return null;
|
|
351
|
+
* }
|
|
352
|
+
* }, { interval: 1000, timeout: 30000 });
|
|
353
|
+
* ```
|
|
354
|
+
*
|
|
355
|
+
* @example
|
|
356
|
+
* ```ts
|
|
357
|
+
* // Poll with abort signal for cancellation
|
|
358
|
+
* const controller = new AbortController();
|
|
359
|
+
* setTimeout(() => controller.abort(), 10000); // Cancel after 10s
|
|
360
|
+
*
|
|
361
|
+
* try {
|
|
362
|
+
* const result = await poll(
|
|
363
|
+
* () => checkExternalService(),
|
|
364
|
+
* { interval: 2000, signal: controller.signal }
|
|
365
|
+
* );
|
|
366
|
+
* } catch (err) {
|
|
367
|
+
* if (err.name === 'AbortError') {
|
|
368
|
+
* console.log('Polling was cancelled');
|
|
369
|
+
* }
|
|
370
|
+
* }
|
|
371
|
+
* ```
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```ts
|
|
375
|
+
* // Poll for user action completion
|
|
376
|
+
* const userConfirmed = await poll(async () => {
|
|
377
|
+
* const confirmations = await getPendingConfirmations();
|
|
378
|
+
* return confirmations.length > 0 ? confirmations[0] : null;
|
|
379
|
+
* }, { interval: 5000, timeout: 300000 }); // 5 min timeout
|
|
380
|
+
* ```
|
|
204
381
|
*/
|
|
205
382
|
declare function poll<T>(cond: () => Promise<T | null | false | undefined>, {
|
|
206
383
|
interval,
|
|
@@ -224,11 +401,62 @@ declare function poll<T>(cond: () => Promise<T | null | false | undefined>, {
|
|
|
224
401
|
*
|
|
225
402
|
* @example
|
|
226
403
|
* ```ts
|
|
227
|
-
*
|
|
228
|
-
*
|
|
404
|
+
* // Synchronous error handling
|
|
405
|
+
* const [err, value] = shield(() => {
|
|
406
|
+
* if (Math.random() > 0.5) throw new Error('Random failure');
|
|
407
|
+
* return 'success';
|
|
408
|
+
* });
|
|
409
|
+
* if (err) {
|
|
410
|
+
* console.error('Operation failed:', err);
|
|
411
|
+
* } else {
|
|
412
|
+
* console.log('Result:', value);
|
|
413
|
+
* }
|
|
414
|
+
*
|
|
415
|
+
* // Asynchronous error handling
|
|
416
|
+
* const [asyncErr, result] = await shield(async () => {
|
|
417
|
+
* const response = await fetch('/api/data');
|
|
418
|
+
* if (!response.ok) throw new Error('API error');
|
|
419
|
+
* return response.json();
|
|
420
|
+
* });
|
|
421
|
+
* if (asyncErr) {
|
|
422
|
+
* console.error('API call failed:', asyncErr);
|
|
423
|
+
* } else {
|
|
424
|
+
* processData(result);
|
|
425
|
+
* }
|
|
426
|
+
*
|
|
427
|
+
* // API calls with fallbacks
|
|
428
|
+
* const [fetchErr, data] = await shield(fetchUserData(userId));
|
|
429
|
+
* const userData = fetchErr ? getCachedUserData(userId) : data;
|
|
430
|
+
*
|
|
431
|
+
* // File operations
|
|
432
|
+
* const [fileErr, content] = shield(() => readFileSync('config.json'));
|
|
433
|
+
* if (fileErr) {
|
|
434
|
+
* console.warn('Could not read config, using defaults');
|
|
435
|
+
* return defaultConfig;
|
|
436
|
+
* }
|
|
437
|
+
* ```
|
|
229
438
|
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
439
|
+
* @example
|
|
440
|
+
* ```ts
|
|
441
|
+
* // In async functions
|
|
442
|
+
* async function safeApiCall() {
|
|
443
|
+
* const [err, result] = await shield(callExternalAPI());
|
|
444
|
+
* if (err) {
|
|
445
|
+
* await logError(err);
|
|
446
|
+
* return null;
|
|
447
|
+
* }
|
|
448
|
+
* return result;
|
|
449
|
+
* }
|
|
450
|
+
*
|
|
451
|
+
* // In event handlers
|
|
452
|
+
* function handleSubmit(formData) {
|
|
453
|
+
* const [validationErr, validatedData] = shield(() => validateForm(formData));
|
|
454
|
+
* if (validationErr) {
|
|
455
|
+
* showValidationError(validationErr);
|
|
456
|
+
* return;
|
|
457
|
+
* }
|
|
458
|
+
* submitData(validatedData);
|
|
459
|
+
* }
|
|
232
460
|
* ```
|
|
233
461
|
*/
|
|
234
462
|
declare function shield<T, E = Error>(operation: Promise<T>): Promise<[E | null, T | null]>;
|
|
@@ -240,6 +468,12 @@ declare function shield<T, E = Error>(operation: () => T): [E | null, T | null];
|
|
|
240
468
|
*
|
|
241
469
|
* @param {...ClassValue[]} inputs - Class names to merge.
|
|
242
470
|
* @returns {string} - A string of merged class names.
|
|
471
|
+
*
|
|
472
|
+
* @example
|
|
473
|
+
* ```ts
|
|
474
|
+
* cn('px-2 py-1', 'bg-red-500') // 'px-2 py-1 bg-red-500'
|
|
475
|
+
* cn('px-2', 'px-4') // 'px-4' (Tailwind resolves conflicts)
|
|
476
|
+
* ```
|
|
243
477
|
*/
|
|
244
478
|
declare function cn(...inputs: ClassValue[]): string;
|
|
245
479
|
/**
|
|
@@ -250,16 +484,40 @@ declare function cn(...inputs: ClassValue[]): string;
|
|
|
250
484
|
* @param href - The target URL.
|
|
251
485
|
* @param path - The current browser path.
|
|
252
486
|
* @returns - True if the navigation is active, false otherwise.
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* ```ts
|
|
490
|
+
* isNavActive('/about', '/about/team') // true
|
|
491
|
+
* isNavActive('/contact', '/about') // false
|
|
492
|
+
* ```
|
|
253
493
|
*/
|
|
254
494
|
declare function isNavActive(href: string, path: string): boolean;
|
|
255
495
|
/**
|
|
256
496
|
* Checks if a link is active, considering optional localization prefixes.
|
|
257
497
|
*
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
* @param
|
|
262
|
-
* @
|
|
498
|
+
* Compares paths while ignoring locale prefixes (e.g., /en/, /fr/) for consistent
|
|
499
|
+
* navigation highlighting across different language versions of the same page.
|
|
500
|
+
*
|
|
501
|
+
* @param params - Parameters object.
|
|
502
|
+
* @param params.path - The target path of the link.
|
|
503
|
+
* @param params.currentPath - The current browser path.
|
|
504
|
+
* @param params.locales - Supported locale prefixes to ignore during comparison.
|
|
505
|
+
* @param params.exact - Whether to require exact path match (default: true). If false, checks if current path starts with target path.
|
|
506
|
+
* @returns True if the link is active, false otherwise.
|
|
507
|
+
*
|
|
508
|
+
* @example
|
|
509
|
+
* ```ts
|
|
510
|
+
* // Exact match
|
|
511
|
+
* isLinkActive({ path: '/about', currentPath: '/about' }) // true
|
|
512
|
+
* isLinkActive({ path: '/about', currentPath: '/about/team' }) // false
|
|
513
|
+
*
|
|
514
|
+
* // With locales
|
|
515
|
+
* isLinkActive({ path: '/about', currentPath: '/en/about' }) // true
|
|
516
|
+
* isLinkActive({ path: '/about', currentPath: '/fr/about' }) // true
|
|
517
|
+
*
|
|
518
|
+
* // Partial match
|
|
519
|
+
* isLinkActive({ path: '/blog', currentPath: '/blog/post-1', exact: false }) // true
|
|
520
|
+
* ```
|
|
263
521
|
*/
|
|
264
522
|
declare function isLinkActive({
|
|
265
523
|
path,
|
|
@@ -275,29 +533,74 @@ declare function isLinkActive({
|
|
|
275
533
|
/**
|
|
276
534
|
* Cleans a file path by removing the `/public/` prefix if present.
|
|
277
535
|
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
536
|
+
* Useful when working with static assets that may have been processed
|
|
537
|
+
* or when normalizing paths between development and production environments.
|
|
538
|
+
*
|
|
539
|
+
* @param src - The source path to clean.
|
|
540
|
+
* @returns The cleaned path with `/public/` prefix removed and whitespace trimmed.
|
|
541
|
+
*
|
|
542
|
+
* @example
|
|
543
|
+
* ```ts
|
|
544
|
+
* cleanSrc('/public/images/logo.png') // '/images/logo.png'
|
|
545
|
+
* cleanSrc('images/logo.png') // 'images/logo.png'
|
|
546
|
+
* cleanSrc(' /public/docs/readme.md ') // '/docs/readme.md'
|
|
547
|
+
* ```
|
|
280
548
|
*/
|
|
281
549
|
declare function cleanSrc(src: string): string;
|
|
282
550
|
/**
|
|
283
551
|
* Smoothly scrolls to the top or bottom of a specified container.
|
|
284
552
|
*
|
|
285
|
-
*
|
|
286
|
-
*
|
|
553
|
+
* Provides smooth scrolling animation to either end of a scrollable element.
|
|
554
|
+
* Accepts either a CSS selector string or a React ref to the container element.
|
|
555
|
+
*
|
|
556
|
+
* @param containerSelector - The CSS selector string or React ref for the scrollable container.
|
|
557
|
+
* @param to - Direction to scroll: 'top' for top of container, 'bottom' for bottom.
|
|
558
|
+
*
|
|
559
|
+
* @example
|
|
560
|
+
* ```ts
|
|
561
|
+
* // Scroll to top using selector
|
|
562
|
+
* scrollTo('.main-content', 'top');
|
|
563
|
+
*
|
|
564
|
+
* // Scroll to bottom using ref
|
|
565
|
+
* scrollTo(containerRef, 'bottom');
|
|
566
|
+
* ```
|
|
287
567
|
*/
|
|
288
568
|
declare const scrollTo: (containerSelector: string | React.RefObject<HTMLDivElement>, to: "top" | "bottom") => void;
|
|
289
569
|
/**
|
|
290
|
-
* Copies a given string to the clipboard.
|
|
570
|
+
* Copies a given string to the clipboard using the modern Clipboard API.
|
|
291
571
|
*
|
|
292
|
-
*
|
|
293
|
-
*
|
|
572
|
+
* Safely attempts to copy text to the user's clipboard. Falls back gracefully
|
|
573
|
+
* if the Clipboard API is not available or if the operation fails.
|
|
574
|
+
*
|
|
575
|
+
* @param value - The text value to copy to the clipboard.
|
|
576
|
+
* @param onSuccess - Optional callback executed after successful copy operation.
|
|
577
|
+
*
|
|
578
|
+
* @example
|
|
579
|
+
* ```ts
|
|
580
|
+
* copyToClipboard('Hello World!', () => {
|
|
581
|
+
* console.log('Text copied successfully');
|
|
582
|
+
* });
|
|
583
|
+
* ```
|
|
294
584
|
*/
|
|
295
585
|
declare const copyToClipboard: (value: string, onSuccess?: () => void) => void;
|
|
296
586
|
/**
|
|
297
|
-
* Converts camelCase, PascalCase, kebab-case, snake_case into normal case.
|
|
587
|
+
* Converts various case styles (camelCase, PascalCase, kebab-case, snake_case) into readable normal case.
|
|
298
588
|
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
589
|
+
* Transforms technical naming conventions into human-readable titles by:
|
|
590
|
+
* - Adding spaces between words
|
|
591
|
+
* - Capitalizing the first letter of each word
|
|
592
|
+
* - Handling common separators (-, _, camelCase boundaries)
|
|
593
|
+
*
|
|
594
|
+
* @param inputString - The string to convert (supports camelCase, PascalCase, kebab-case, snake_case).
|
|
595
|
+
* @returns The converted string in normal case (title case).
|
|
596
|
+
*
|
|
597
|
+
* @example
|
|
598
|
+
* ```ts
|
|
599
|
+
* convertToNormalCase('camelCase') // 'Camel Case'
|
|
600
|
+
* convertToNormalCase('kebab-case') // 'Kebab Case'
|
|
601
|
+
* convertToNormalCase('snake_case') // 'Snake Case'
|
|
602
|
+
* convertToNormalCase('PascalCase') // 'Pascal Case'
|
|
603
|
+
* ```
|
|
301
604
|
*/
|
|
302
605
|
declare function convertToNormalCase(inputString: string): string;
|
|
303
606
|
/**
|
|
@@ -314,6 +617,17 @@ declare const convertToSlug: (str: string) => string;
|
|
|
314
617
|
* Checks if the code is running in a server-side environment.
|
|
315
618
|
*
|
|
316
619
|
* @returns - True if the code is executed in SSR (Server-Side Rendering) context, false otherwise
|
|
620
|
+
*
|
|
621
|
+
* @example
|
|
622
|
+
* ```ts
|
|
623
|
+
* if (isSSR) {
|
|
624
|
+
* // Server-side only code
|
|
625
|
+
* console.log('Running on server');
|
|
626
|
+
* } else {
|
|
627
|
+
* // Client-side only code
|
|
628
|
+
* window.addEventListener('load', () => {});
|
|
629
|
+
* }
|
|
630
|
+
* ```
|
|
317
631
|
*/
|
|
318
632
|
declare const isSSR: boolean;
|
|
319
633
|
/**
|
|
@@ -321,6 +635,13 @@ declare const isSSR: boolean;
|
|
|
321
635
|
*
|
|
322
636
|
* @param str - The SVG string to encode
|
|
323
637
|
* @returns - Base64-encoded string representation of the SVG
|
|
638
|
+
*
|
|
639
|
+
* @example
|
|
640
|
+
* ```ts
|
|
641
|
+
* const svg = '<svg><circle cx="50" cy="50" r="40"/></svg>';
|
|
642
|
+
* const base64 = svgToBase64(svg);
|
|
643
|
+
* // Use in data URL: `data:image/svg+xml;base64,${base64}`
|
|
644
|
+
* ```
|
|
324
645
|
*/
|
|
325
646
|
declare const svgToBase64: (str: string) => string;
|
|
326
647
|
/**
|
|
@@ -362,9 +683,23 @@ type DebouncedFunction<F$1 extends (...args: any[]) => any> = {
|
|
|
362
683
|
* @throws {RangeError} If the `wait` parameter is negative.
|
|
363
684
|
*
|
|
364
685
|
* @example
|
|
686
|
+
* ```ts
|
|
687
|
+
* // Basic debouncing
|
|
365
688
|
* const log = debounce((message: string) => console.log(message), 200);
|
|
366
689
|
* log('Hello'); // Logs "Hello" after 200ms if no other call is made.
|
|
367
690
|
* console.log(log.isPending); // true if the timer is active.
|
|
691
|
+
*
|
|
692
|
+
* // Immediate execution
|
|
693
|
+
* const save = debounce(() => saveToServer(), 500, { immediate: true });
|
|
694
|
+
* save(); // Executes immediately, then waits 500ms for subsequent calls
|
|
695
|
+
*
|
|
696
|
+
* // Check pending state
|
|
697
|
+
* const debouncedSearch = debounce(searchAPI, 300);
|
|
698
|
+
* debouncedSearch('query');
|
|
699
|
+
* if (debouncedSearch.isPending) {
|
|
700
|
+
* showLoadingIndicator();
|
|
701
|
+
* }
|
|
702
|
+
* ```
|
|
368
703
|
*/
|
|
369
704
|
declare function debounce<F$1 extends (...args: any[]) => any>(function_: F$1, wait?: number, options?: {
|
|
370
705
|
immediate: boolean;
|
|
@@ -399,9 +734,29 @@ type ThrottledFunction<F$1 extends (...args: any[]) => any> = {
|
|
|
399
734
|
* @throws {RangeError} If the `wait` parameter is negative.
|
|
400
735
|
*
|
|
401
736
|
* @example
|
|
737
|
+
* ```ts
|
|
738
|
+
* // Basic throttling (leading edge by default)
|
|
402
739
|
* const log = throttle((message: string) => console.log(message), 200);
|
|
403
|
-
* log('Hello'); // Logs "Hello" immediately
|
|
404
|
-
*
|
|
740
|
+
* log('Hello'); // Logs "Hello" immediately
|
|
741
|
+
* log('World'); // Ignored for 200ms
|
|
742
|
+
* console.log(log.isPending); // true if within throttle window
|
|
743
|
+
*
|
|
744
|
+
* // Trailing edge only
|
|
745
|
+
* const trailingLog = throttle(() => console.log('trailing'), 200, {
|
|
746
|
+
* leading: false,
|
|
747
|
+
* trailing: true
|
|
748
|
+
* });
|
|
749
|
+
* trailingLog(); // No immediate execution
|
|
750
|
+
* // After 200ms: logs "trailing"
|
|
751
|
+
*
|
|
752
|
+
* // Both edges
|
|
753
|
+
* const bothLog = throttle(() => console.log('both'), 200, {
|
|
754
|
+
* leading: true,
|
|
755
|
+
* trailing: true
|
|
756
|
+
* });
|
|
757
|
+
* bothLog(); // Immediate execution
|
|
758
|
+
* // After 200ms: executes again if called during window
|
|
759
|
+
* ```
|
|
405
760
|
*/
|
|
406
761
|
declare function throttle<F$1 extends (...args: any[]) => any>(function_: F$1, wait?: number, options?: {
|
|
407
762
|
leading?: boolean;
|
|
@@ -409,26 +764,31 @@ declare function throttle<F$1 extends (...args: any[]) => any>(function_: F$1, w
|
|
|
409
764
|
}): ThrottledFunction<F$1>;
|
|
410
765
|
/**
|
|
411
766
|
* Formats a string by replacing each '%s' placeholder with the corresponding argument.
|
|
412
|
-
* This function mimics the basic behavior of C's printf for %s substitution.
|
|
413
767
|
*
|
|
414
|
-
*
|
|
768
|
+
* Mimics the basic behavior of C's printf for %s substitution. Supports both
|
|
769
|
+
* variadic arguments and array-based argument passing. Extra placeholders
|
|
770
|
+
* are left as-is, missing arguments result in empty strings.
|
|
415
771
|
*
|
|
416
772
|
* @param format - The format string containing '%s' placeholders.
|
|
417
|
-
* @param args - The values to substitute
|
|
418
|
-
* @returns The formatted string with
|
|
773
|
+
* @param args - The values to substitute, either as separate arguments or a single array.
|
|
774
|
+
* @returns The formatted string with placeholders replaced by arguments.
|
|
419
775
|
*
|
|
420
776
|
* @example
|
|
421
777
|
* ```ts
|
|
422
|
-
*
|
|
423
|
-
*
|
|
778
|
+
* // Basic usage with separate arguments
|
|
779
|
+
* printf("%s love %s", "I", "Bangladesh") // "I love Bangladesh"
|
|
780
|
+
*
|
|
781
|
+
* // Using array of arguments
|
|
782
|
+
* printf("%s love %s", ["I", "Bangladesh"]) // "I love Bangladesh"
|
|
783
|
+
*
|
|
784
|
+
* // Extra placeholders remain unchanged
|
|
785
|
+
* printf("%s %s %s", "Hello", "World") // "Hello World %s"
|
|
424
786
|
*
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
* // message2 === "I love Bangladesh"
|
|
787
|
+
* // Missing arguments become empty strings
|
|
788
|
+
* printf("%s and %s", "this") // "this and "
|
|
428
789
|
*
|
|
429
|
-
* //
|
|
430
|
-
*
|
|
431
|
-
* // incomplete === "Bangladesh is beautiful"
|
|
790
|
+
* // Multiple occurrences
|
|
791
|
+
* printf("%s %s %s", "repeat", "repeat", "repeat") // "repeat repeat repeat"
|
|
432
792
|
* ```
|
|
433
793
|
*/
|
|
434
794
|
declare function printf(format: string, ...args: unknown[]): string;
|
|
@@ -436,29 +796,54 @@ declare function printf(format: string, ...args: unknown[]): string;
|
|
|
436
796
|
* Merges multiple refs into a single ref callback.
|
|
437
797
|
*
|
|
438
798
|
* @param refs - An array of refs to merge.
|
|
439
|
-
*
|
|
440
799
|
* @returns - A function that updates the merged ref with the provided value.
|
|
800
|
+
*
|
|
801
|
+
* @example
|
|
802
|
+
* ```tsx
|
|
803
|
+
* const MyComponent = () => {
|
|
804
|
+
* const ref1 = useRef<HTMLDivElement>(null);
|
|
805
|
+
* const ref2 = useRef<HTMLDivElement>(null);
|
|
806
|
+
*
|
|
807
|
+
* const mergedRef = mergeRefs(ref1, ref2);
|
|
808
|
+
*
|
|
809
|
+
* return <div ref={mergedRef}>Content</div>;
|
|
810
|
+
* };
|
|
811
|
+
* ```
|
|
441
812
|
*/
|
|
442
813
|
type MergeRefs = <T>(...refs: Array<React.Ref<T> | undefined>) => React.RefCallback<T>;
|
|
443
814
|
declare const mergeRefs: MergeRefs;
|
|
444
815
|
/**
|
|
445
|
-
* Navigates to the specified client-side hash without
|
|
446
|
-
* use `scroll-margin-top` with css to add margins
|
|
816
|
+
* Navigates to the specified client-side hash without triggering SSR.
|
|
447
817
|
*
|
|
448
|
-
*
|
|
818
|
+
* Smoothly scrolls to an element by ID and updates the URL hash.
|
|
819
|
+
* Use `scroll-margin-top` CSS property to add margins for fixed headers.
|
|
449
820
|
*
|
|
450
|
-
* @
|
|
821
|
+
* @param id - The ID of the element (without #) to navigate to.
|
|
822
|
+
* @param opts - Additional options for scrollIntoView.
|
|
823
|
+
*
|
|
824
|
+
* @example
|
|
825
|
+
* ```ts
|
|
826
|
+
* // Navigate to an element
|
|
827
|
+
* goToClientSideHash('section-about');
|
|
828
|
+
*
|
|
829
|
+
* // With custom scroll behavior
|
|
830
|
+
* goToClientSideHash('contact', { behavior: 'auto', block: 'center' });
|
|
831
|
+
* ```
|
|
451
832
|
*/
|
|
452
833
|
declare function goToClientSideHash(id: string, opts?: ScrollIntoViewOptions): void;
|
|
453
834
|
/**
|
|
454
835
|
* Escapes a string for use in a regular expression.
|
|
455
836
|
*
|
|
456
837
|
* @param str - The string to escape
|
|
457
|
-
* @returns - The escaped string
|
|
838
|
+
* @returns - The escaped string safe for use in RegExp constructor
|
|
458
839
|
*
|
|
459
840
|
* @example
|
|
841
|
+
* ```ts
|
|
460
842
|
* const escapedString = escapeRegExp('Hello, world!');
|
|
461
843
|
* // escapedString === 'Hello\\, world!'
|
|
844
|
+
*
|
|
845
|
+
* const regex = new RegExp(escapeRegExp(userInput));
|
|
846
|
+
* ```
|
|
462
847
|
*/
|
|
463
848
|
declare function escapeRegExp(str: string): string;
|
|
464
849
|
/**
|
|
@@ -474,6 +859,13 @@ declare function escapeRegExp(str: string): string;
|
|
|
474
859
|
* @param options.removeAccents - Whether to remove diacritic marks like accents (default: true)
|
|
475
860
|
* @param options.removeNonAlphanumeric - Whether to trim non-alphanumeric characters from the edges (default: true)
|
|
476
861
|
* @returns The normalized string
|
|
862
|
+
*
|
|
863
|
+
* @example
|
|
864
|
+
* ```ts
|
|
865
|
+
* normalizeText('Café') // 'cafe'
|
|
866
|
+
* normalizeText(' Hello! ') // 'hello'
|
|
867
|
+
* normalizeText('José', { removeAccents: false }) // 'josé'
|
|
868
|
+
* ```
|
|
477
869
|
*/
|
|
478
870
|
declare function normalizeText(str?: string | null, options?: {
|
|
479
871
|
lowercase?: boolean;
|
|
@@ -482,31 +874,422 @@ declare function normalizeText(str?: string | null, options?: {
|
|
|
482
874
|
}): string;
|
|
483
875
|
//#endregion
|
|
484
876
|
//#region src/types/utilities.d.ts
|
|
877
|
+
/**
|
|
878
|
+
* Extracts the keys of an object type as a union type.
|
|
879
|
+
*
|
|
880
|
+
* @template T - The object type to extract keys from
|
|
881
|
+
* @returns A union of all keys in the object type
|
|
882
|
+
*
|
|
883
|
+
* @example
|
|
884
|
+
* ```ts
|
|
885
|
+
* type User = { name: string; age: number };
|
|
886
|
+
* type UserKeys = Keys<User>; // 'name' | 'age'
|
|
887
|
+
* ```
|
|
888
|
+
*/
|
|
485
889
|
type Keys<T extends object> = keyof T;
|
|
890
|
+
/**
|
|
891
|
+
* Extracts the values of an object type as a union type.
|
|
892
|
+
*
|
|
893
|
+
* @template T - The object type to extract values from
|
|
894
|
+
* @returns A union of all values in the object type
|
|
895
|
+
*
|
|
896
|
+
* @example
|
|
897
|
+
* ```ts
|
|
898
|
+
* type User = { name: string; age: number };
|
|
899
|
+
* type UserValues = Values<User>; // string | number
|
|
900
|
+
* ```
|
|
901
|
+
*/
|
|
486
902
|
type Values<T extends object> = T[keyof T];
|
|
903
|
+
/**
|
|
904
|
+
* Makes all properties of an object type optional recursively.
|
|
905
|
+
*
|
|
906
|
+
* This type traverses through nested objects and arrays, making all properties optional.
|
|
907
|
+
* Functions and primitives are left unchanged.
|
|
908
|
+
*
|
|
909
|
+
* @template T - The type to make deeply partial
|
|
910
|
+
* @returns A type with all properties optional recursively
|
|
911
|
+
*
|
|
912
|
+
* @example
|
|
913
|
+
* ```ts
|
|
914
|
+
* type Config = {
|
|
915
|
+
* server: { host: string; port: number };
|
|
916
|
+
* features: string[];
|
|
917
|
+
* };
|
|
918
|
+
*
|
|
919
|
+
* type PartialConfig = DeepPartial<Config>;
|
|
920
|
+
* // {
|
|
921
|
+
* // server?: { host?: string; port?: number };
|
|
922
|
+
* // features?: string[];
|
|
923
|
+
* // }
|
|
924
|
+
* ```
|
|
925
|
+
*/
|
|
487
926
|
type DeepPartial<T> = T extends Function ? T : T extends Array<infer U> ? Array<DeepPartial<U>> : T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T;
|
|
927
|
+
/**
|
|
928
|
+
* Makes only specified properties of an object type optional.
|
|
929
|
+
*
|
|
930
|
+
* @template T - The base object type
|
|
931
|
+
* @template K - The keys to make optional
|
|
932
|
+
* @returns An object type with specified properties optional
|
|
933
|
+
*
|
|
934
|
+
* @example
|
|
935
|
+
* ```ts
|
|
936
|
+
* type User = { name: string; age: number; email: string };
|
|
937
|
+
* type PartialUser = SelectivePartial<User, 'age' | 'email'>;
|
|
938
|
+
* // { name: string; age?: number; email?: string }
|
|
939
|
+
* ```
|
|
940
|
+
*/
|
|
488
941
|
type SelectivePartial<T, K$1 extends keyof T> = Omit<T, K$1> & Partial<Pick<T, K$1>>;
|
|
942
|
+
/**
|
|
943
|
+
* Makes all properties of an object type required recursively.
|
|
944
|
+
*
|
|
945
|
+
* This type traverses through nested objects and arrays, making all properties required.
|
|
946
|
+
* Functions and primitives are left unchanged.
|
|
947
|
+
*
|
|
948
|
+
* @template T - The type to make deeply required
|
|
949
|
+
* @returns A type with all properties required recursively
|
|
950
|
+
*
|
|
951
|
+
* @example
|
|
952
|
+
* ```ts
|
|
953
|
+
* type PartialConfig = {
|
|
954
|
+
* server?: { host?: string; port?: number };
|
|
955
|
+
* };
|
|
956
|
+
*
|
|
957
|
+
* type RequiredConfig = DeepRequired<PartialConfig>;
|
|
958
|
+
* // {
|
|
959
|
+
* // server: { host: string; port: number };
|
|
960
|
+
* // }
|
|
961
|
+
* ```
|
|
962
|
+
*/
|
|
489
963
|
type DeepRequired<T> = T extends Function ? T : T extends Array<infer U> ? Array<DeepRequired<U>> : T extends object ? { [K in keyof T]-?: DeepRequired<T[K]> } : T;
|
|
964
|
+
/**
|
|
965
|
+
* Makes only specified properties of an object type required.
|
|
966
|
+
*
|
|
967
|
+
* @template T - The base object type
|
|
968
|
+
* @template K - The keys to make required
|
|
969
|
+
* @returns An object type with specified properties required
|
|
970
|
+
*
|
|
971
|
+
* @example
|
|
972
|
+
* ```ts
|
|
973
|
+
* type PartialUser = { name?: string; age?: number; email?: string };
|
|
974
|
+
* type RequiredUser = SelectiveRequired<PartialUser, 'name'>;
|
|
975
|
+
* // { name: string; age?: number; email?: string }
|
|
976
|
+
* ```
|
|
977
|
+
*/
|
|
490
978
|
type SelectiveRequired<T, K$1 extends keyof T> = Omit<T, K$1> & Required<Pick<T, K$1>>;
|
|
979
|
+
/**
|
|
980
|
+
* Creates a type where all properties are never (useful for excluding types).
|
|
981
|
+
*
|
|
982
|
+
* This can be used to create mutually exclusive types or to exclude certain properties.
|
|
983
|
+
*
|
|
984
|
+
* @template T - The object type to transform
|
|
985
|
+
* @returns An object type with all properties set to never
|
|
986
|
+
*
|
|
987
|
+
* @example
|
|
988
|
+
* ```ts
|
|
989
|
+
* type User = { name: string; age: number };
|
|
990
|
+
* type ExcludedUser = Never<User>; // { name: never; age: never }
|
|
991
|
+
* ```
|
|
992
|
+
*/
|
|
491
993
|
type Never<T> = { [K in keyof T]: never };
|
|
994
|
+
/**
|
|
995
|
+
* Makes all properties of an object type nullable recursively.
|
|
996
|
+
*
|
|
997
|
+
* @template T - The type to make nullable
|
|
998
|
+
* @returns A type where all properties can be null
|
|
999
|
+
*
|
|
1000
|
+
* @example
|
|
1001
|
+
* ```ts
|
|
1002
|
+
* type User = { name: string; profile: { age: number } };
|
|
1003
|
+
* type NullableUser = Nullable<User>;
|
|
1004
|
+
* // { name: string | null; profile: { age: number | null } | null }
|
|
1005
|
+
* ```
|
|
1006
|
+
*/
|
|
492
1007
|
type Nullable<T> = T extends object ? { [P in keyof T]: Nullable<T[P]> } : T | null;
|
|
1008
|
+
/**
|
|
1009
|
+
* Makes all properties of an object type optional (undefined) recursively.
|
|
1010
|
+
*
|
|
1011
|
+
* @template T - The type to make optional
|
|
1012
|
+
* @returns A type where all properties can be undefined
|
|
1013
|
+
*
|
|
1014
|
+
* @example
|
|
1015
|
+
* ```ts
|
|
1016
|
+
* type User = { name: string; profile: { age: number } };
|
|
1017
|
+
* type OptionalUser = Optional<User>;
|
|
1018
|
+
* // { name: string | undefined; profile: { age: number | undefined } | undefined }
|
|
1019
|
+
* ```
|
|
1020
|
+
*/
|
|
493
1021
|
type Optional<T> = T extends object ? { [P in keyof T]: Optional<T[P]> } : T | undefined;
|
|
1022
|
+
/**
|
|
1023
|
+
* Makes all properties of an object type nullish (null or undefined) recursively.
|
|
1024
|
+
*
|
|
1025
|
+
* @template T - The type to make nullish
|
|
1026
|
+
* @returns A type where all properties can be null or undefined
|
|
1027
|
+
*
|
|
1028
|
+
* @example
|
|
1029
|
+
* ```ts
|
|
1030
|
+
* type User = { name: string; profile: { age: number } };
|
|
1031
|
+
* type NullishUser = Nullish<User>;
|
|
1032
|
+
* // { name: string | null | undefined; profile: { age: number | null | undefined } | null | undefined }
|
|
1033
|
+
* ```
|
|
1034
|
+
*/
|
|
494
1035
|
type Nullish<T> = T extends object ? { [P in keyof T]: Nullish<T[P]> } : T | null | undefined;
|
|
1036
|
+
/**
|
|
1037
|
+
* Makes all properties of an object type optional and nullish recursively.
|
|
1038
|
+
*
|
|
1039
|
+
* This combines optional properties with nullish values.
|
|
1040
|
+
*
|
|
1041
|
+
* @template T - The type to make maybe
|
|
1042
|
+
* @returns A type where all properties are optional and can be null or undefined
|
|
1043
|
+
*
|
|
1044
|
+
* @example
|
|
1045
|
+
* ```ts
|
|
1046
|
+
* type User = { name: string; profile: { age: number } };
|
|
1047
|
+
* type MaybeUser = Maybe<User>;
|
|
1048
|
+
* // { name?: string | null | undefined; profile?: { age?: number | null | undefined } | null | undefined }
|
|
1049
|
+
* ```
|
|
1050
|
+
*/
|
|
495
1051
|
type Maybe<T> = T extends object ? { [P in keyof T]?: Nullish<T[P]> } : T | null | undefined;
|
|
1052
|
+
/**
|
|
1053
|
+
* Makes all properties of an object type readonly recursively.
|
|
1054
|
+
*
|
|
1055
|
+
* This type traverses through nested objects and arrays, making all properties readonly.
|
|
1056
|
+
* Functions and primitives are left unchanged.
|
|
1057
|
+
*
|
|
1058
|
+
* @template T - The type to make deeply readonly
|
|
1059
|
+
* @returns A type with all properties readonly recursively
|
|
1060
|
+
*
|
|
1061
|
+
* @example
|
|
1062
|
+
* ```ts
|
|
1063
|
+
* type Config = {
|
|
1064
|
+
* server: { host: string; port: number };
|
|
1065
|
+
* features: string[];
|
|
1066
|
+
* };
|
|
1067
|
+
*
|
|
1068
|
+
* type ReadonlyConfig = DeepReadonly<Config>;
|
|
1069
|
+
* // {
|
|
1070
|
+
* // readonly server: { readonly host: string; readonly port: number };
|
|
1071
|
+
* // readonly features: readonly string[];
|
|
1072
|
+
* // }
|
|
1073
|
+
* ```
|
|
1074
|
+
*/
|
|
496
1075
|
type DeepReadonly<T> = T extends Function ? T : T extends Array<infer U> ? ReadonlyArray<DeepReadonly<U>> : T extends object ? { readonly [K in keyof T]: DeepReadonly<T[K]> } : T;
|
|
1076
|
+
/**
|
|
1077
|
+
* Removes readonly modifier from all properties of an object type recursively.
|
|
1078
|
+
*
|
|
1079
|
+
* @template T - The readonly type to make mutable
|
|
1080
|
+
* @returns A type with all readonly modifiers removed
|
|
1081
|
+
*
|
|
1082
|
+
* @example
|
|
1083
|
+
* ```ts
|
|
1084
|
+
* type ReadonlyUser = { readonly name: string; readonly profile: { readonly age: number } };
|
|
1085
|
+
* type MutableUser = Mutable<ReadonlyUser>;
|
|
1086
|
+
* // { name: string; profile: { age: number } }
|
|
1087
|
+
* ```
|
|
1088
|
+
*/
|
|
497
1089
|
type Mutable<T> = { -readonly [P in keyof T]: T[P] };
|
|
1090
|
+
/**
|
|
1091
|
+
* Extracts keys of an object type that have values of a specific type.
|
|
1092
|
+
*
|
|
1093
|
+
* @template T - The object type to search
|
|
1094
|
+
* @template U - The value type to match
|
|
1095
|
+
* @returns A union of keys whose values match the specified type
|
|
1096
|
+
*
|
|
1097
|
+
* @example
|
|
1098
|
+
* ```ts
|
|
1099
|
+
* type User = { name: string; age: number; active: boolean };
|
|
1100
|
+
* type StringKeys = KeysOfType<User, string>; // 'name'
|
|
1101
|
+
* type NumberKeys = KeysOfType<User, number>; // 'age'
|
|
1102
|
+
* ```
|
|
1103
|
+
*/
|
|
498
1104
|
type KeysOfType<T, U$1> = { [K in keyof T]: T[K] extends U$1 ? K : never }[keyof T];
|
|
1105
|
+
/**
|
|
1106
|
+
* Omits properties from an object type that have values of a specific type.
|
|
1107
|
+
*
|
|
1108
|
+
* @template T - The object type to filter
|
|
1109
|
+
* @template U - The value type to exclude
|
|
1110
|
+
* @returns An object type without properties of the specified value type
|
|
1111
|
+
*
|
|
1112
|
+
* @example
|
|
1113
|
+
* ```ts
|
|
1114
|
+
* type Mixed = { name: string; age: number; active: boolean };
|
|
1115
|
+
* type WithoutStrings = OmitByType<Mixed, string>; // { age: number; active: boolean }
|
|
1116
|
+
* ```
|
|
1117
|
+
*/
|
|
499
1118
|
type OmitByType<T, U$1> = { [K in keyof T as T[K] extends U$1 ? never : K]: T[K] };
|
|
1119
|
+
/**
|
|
1120
|
+
* Makes specified properties required while keeping others as-is.
|
|
1121
|
+
*
|
|
1122
|
+
* @template T - The base object type
|
|
1123
|
+
* @template K - The keys to make required
|
|
1124
|
+
* @returns An object type with specified properties required
|
|
1125
|
+
*
|
|
1126
|
+
* @example
|
|
1127
|
+
* ```ts
|
|
1128
|
+
* type PartialUser = { name?: string; age?: number; email?: string };
|
|
1129
|
+
* type RequiredNameUser = RequiredKeys<PartialUser, 'name'>;
|
|
1130
|
+
* // { name: string; age?: number; email?: string }
|
|
1131
|
+
* ```
|
|
1132
|
+
*/
|
|
500
1133
|
type RequiredKeys<T, K$1 extends keyof T> = Omit<T, K$1> & Required<Pick<T, K$1>>;
|
|
1134
|
+
/**
|
|
1135
|
+
* Computes the symmetric difference between two object types.
|
|
1136
|
+
*
|
|
1137
|
+
* Properties that exist in either T or U but not in both.
|
|
1138
|
+
*
|
|
1139
|
+
* @template T - First object type
|
|
1140
|
+
* @template U - Second object type
|
|
1141
|
+
* @returns Properties unique to T or U
|
|
1142
|
+
*
|
|
1143
|
+
* @example
|
|
1144
|
+
* ```ts
|
|
1145
|
+
* type A = { x: number; y: string };
|
|
1146
|
+
* type B = { y: string; z: boolean };
|
|
1147
|
+
* type DiffAB = Diff<A, B>; // { x: number; z: boolean }
|
|
1148
|
+
* ```
|
|
1149
|
+
*/
|
|
501
1150
|
type Diff<T, U$1> = Omit<T, keyof U$1> & Omit<U$1, keyof T>;
|
|
1151
|
+
/**
|
|
1152
|
+
* Computes the intersection of two object types (properties present in both).
|
|
1153
|
+
*
|
|
1154
|
+
* @template T - First object type
|
|
1155
|
+
* @template U - Second object type
|
|
1156
|
+
* @returns Properties that exist in both T and U
|
|
1157
|
+
*
|
|
1158
|
+
* @example
|
|
1159
|
+
* ```ts
|
|
1160
|
+
* type A = { x: number; y: string };
|
|
1161
|
+
* type B = { y: string; z: boolean };
|
|
1162
|
+
* type IntersectionAB = Intersection<A, B>; // { y: string }
|
|
1163
|
+
* ```
|
|
1164
|
+
*/
|
|
502
1165
|
type Intersection<T extends object, U$1 extends object> = Pick<T, Extract<keyof T, keyof U$1> & Extract<keyof U$1, keyof T>>;
|
|
1166
|
+
/**
|
|
1167
|
+
* Merges two object types, combining their properties.
|
|
1168
|
+
*
|
|
1169
|
+
* @template T - First object type
|
|
1170
|
+
* @template U - Second object type
|
|
1171
|
+
* @returns A merged object type with properties from both
|
|
1172
|
+
*
|
|
1173
|
+
* @example
|
|
1174
|
+
* ```ts
|
|
1175
|
+
* type A = { x: number; y: string };
|
|
1176
|
+
* type B = { y: boolean; z: string };
|
|
1177
|
+
* type Merged = Merge<A, B>; // { x: number; y: boolean; z: string }
|
|
1178
|
+
* ```
|
|
1179
|
+
*/
|
|
503
1180
|
type Merge<T extends object, U$1 extends object, I = Diff<T, U$1> & Intersection<U$1, T> & Diff<U$1, T>> = Pick<I, keyof I>;
|
|
1181
|
+
/**
|
|
1182
|
+
* Subtracts properties of one object type from another.
|
|
1183
|
+
*
|
|
1184
|
+
* @template T - The object type to subtract from
|
|
1185
|
+
* @template U - The object type whose properties to subtract
|
|
1186
|
+
* @returns T without properties that exist in U
|
|
1187
|
+
*
|
|
1188
|
+
* @example
|
|
1189
|
+
* ```ts
|
|
1190
|
+
* type A = { x: number; y: string; z: boolean };
|
|
1191
|
+
* type B = { y: string };
|
|
1192
|
+
* type Subtracted = Substract<A, B>; // { x: number; z: boolean }
|
|
1193
|
+
* ```
|
|
1194
|
+
*/
|
|
504
1195
|
type Substract<T extends object, U$1 extends object> = Omit<T, keyof U$1>;
|
|
1196
|
+
/**
|
|
1197
|
+
* Represents either all properties present or none of them.
|
|
1198
|
+
*
|
|
1199
|
+
* Useful for creating mutually exclusive configurations.
|
|
1200
|
+
*
|
|
1201
|
+
* @template T - The object type
|
|
1202
|
+
* @returns Either the full object or an empty object with optional properties
|
|
1203
|
+
*
|
|
1204
|
+
* @example
|
|
1205
|
+
* ```ts
|
|
1206
|
+
* type Config = { host: string; port: number };
|
|
1207
|
+
* type AllOrNoneConfig = AllOrNone<Config>;
|
|
1208
|
+
* // { host: string; port: number } | {}
|
|
1209
|
+
* ```
|
|
1210
|
+
*/
|
|
505
1211
|
type AllOrNone<T> = T | { [P in keyof T]?: never };
|
|
1212
|
+
/**
|
|
1213
|
+
* Represents exactly one property from an object type being present.
|
|
1214
|
+
*
|
|
1215
|
+
* Useful for creating discriminated unions or mutually exclusive options.
|
|
1216
|
+
*
|
|
1217
|
+
* @template T - The object type
|
|
1218
|
+
* @returns A union where only one property is present at a time
|
|
1219
|
+
*
|
|
1220
|
+
* @example
|
|
1221
|
+
* ```ts
|
|
1222
|
+
* type Action = { type: 'create'; payload: string } | { type: 'update'; id: number };
|
|
1223
|
+
* type OneAction = OneOf<Action>;
|
|
1224
|
+
* // { type: 'create'; payload: string } | { type: 'update'; id: number }
|
|
1225
|
+
* ```
|
|
1226
|
+
*/
|
|
506
1227
|
type OneOf<T> = { [K in keyof T]: Pick<T, K> }[keyof T];
|
|
1228
|
+
/**
|
|
1229
|
+
* Represents exactly two properties from an object type being present.
|
|
1230
|
+
*
|
|
1231
|
+
* @template T - The object type
|
|
1232
|
+
* @returns A union where exactly two properties are present at a time
|
|
1233
|
+
*
|
|
1234
|
+
* @example
|
|
1235
|
+
* ```ts
|
|
1236
|
+
* type Config = { a: number; b: string; c: boolean };
|
|
1237
|
+
* type TwoConfig = TwoOf<Config>;
|
|
1238
|
+
* // { a: number; b: string } | { a: number; c: boolean } | { b: string; c: boolean }
|
|
1239
|
+
* ```
|
|
1240
|
+
*/
|
|
507
1241
|
type TwoOf<T> = { [K in keyof T]: { [L in Exclude<keyof T, K>]: Pick<T, K | L> }[Exclude<keyof T, K>] }[keyof T];
|
|
1242
|
+
/**
|
|
1243
|
+
* Prettifies a complex type by expanding it for better readability in tooltips.
|
|
1244
|
+
*
|
|
1245
|
+
* This type doesn't change the runtime type but helps with IntelliSense display.
|
|
1246
|
+
*
|
|
1247
|
+
* @template T - The type to prettify
|
|
1248
|
+
* @returns The same type but expanded for better readability
|
|
1249
|
+
*
|
|
1250
|
+
* @example
|
|
1251
|
+
* ```ts
|
|
1252
|
+
* type Complex = { a: string } & { b: number };
|
|
1253
|
+
* type PrettyComplex = Prettify<Complex>; // Shows as { a: string; b: number }
|
|
1254
|
+
* ```
|
|
1255
|
+
*/
|
|
508
1256
|
type Prettify<T> = { [K in keyof T]: T[K] } & {};
|
|
1257
|
+
/**
|
|
1258
|
+
* Extracts all nested keys of an object type as dot-separated strings.
|
|
1259
|
+
*
|
|
1260
|
+
* @template ObjectType - The object type to extract nested keys from
|
|
1261
|
+
* @template IgnoreKeys - Keys to ignore during extraction
|
|
1262
|
+
* @returns A union of dot-separated string paths
|
|
1263
|
+
*
|
|
1264
|
+
* @example
|
|
1265
|
+
* ```ts
|
|
1266
|
+
* type User = {
|
|
1267
|
+
* name: string;
|
|
1268
|
+
* profile: { age: number; address: { city: string } };
|
|
1269
|
+
* tags: string[];
|
|
1270
|
+
* };
|
|
1271
|
+
*
|
|
1272
|
+
* type UserPaths = NestedKeyOf<User>;
|
|
1273
|
+
* // 'name' | 'profile' | 'profile.age' | 'profile.address' | 'profile.address.city' | 'tags'
|
|
1274
|
+
* ```
|
|
1275
|
+
*/
|
|
509
1276
|
type NestedKeyOf<ObjectType extends object, IgnoreKeys extends string = never> = { [Key in keyof ObjectType & string]: Key extends IgnoreKeys ? never : ObjectType[Key] extends object ? ObjectType[Key] extends Array<any> ? Key : `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key], IgnoreKeys>}` : `${Key}` }[keyof ObjectType & string];
|
|
1277
|
+
/**
|
|
1278
|
+
* Creates a type that excludes properties present in another type.
|
|
1279
|
+
*
|
|
1280
|
+
* This is useful for creating mutually exclusive types.
|
|
1281
|
+
*
|
|
1282
|
+
* @template T - The base type
|
|
1283
|
+
* @template U - The type whose properties to exclude
|
|
1284
|
+
* @returns A type with properties from T that are not in U
|
|
1285
|
+
*
|
|
1286
|
+
* @example
|
|
1287
|
+
* ```ts
|
|
1288
|
+
* type A = { x: number; y: string };
|
|
1289
|
+
* type B = { y: string };
|
|
1290
|
+
* type WithoutB = Without<A, B>; // { x?: never }
|
|
1291
|
+
* ```
|
|
1292
|
+
*/
|
|
510
1293
|
type Without<T, U$1> = { [P in Exclude<keyof T, keyof U$1>]?: never };
|
|
511
1294
|
//#endregion
|
|
512
1295
|
//#region src/types/gates.d.ts
|
|
@@ -642,11 +1425,61 @@ type NAND<T extends any[]> = NOT<AND<T>>;
|
|
|
642
1425
|
type NOR<T extends any[]> = NOT<OR<T>>;
|
|
643
1426
|
//#endregion
|
|
644
1427
|
//#region src/types/guards.d.ts
|
|
1428
|
+
/**
|
|
1429
|
+
* Represents primitive JavaScript types including null and undefined.
|
|
1430
|
+
*/
|
|
645
1431
|
type Primitive = string | number | bigint | boolean | symbol | null | undefined;
|
|
1432
|
+
/**
|
|
1433
|
+
* Represents all falsy values in JavaScript.
|
|
1434
|
+
*/
|
|
646
1435
|
type Falsy = false | '' | 0 | null | undefined;
|
|
1436
|
+
/**
|
|
1437
|
+
* Type guard that checks if a value is falsy.
|
|
1438
|
+
*
|
|
1439
|
+
* @param val - The value to check
|
|
1440
|
+
* @returns True if the value is falsy, false otherwise
|
|
1441
|
+
*
|
|
1442
|
+
* @example
|
|
1443
|
+
* if (isFalsy(value)) {
|
|
1444
|
+
* console.log('Value is falsy');
|
|
1445
|
+
* }
|
|
1446
|
+
*/
|
|
647
1447
|
declare const isFalsy: (val: unknown) => val is Falsy;
|
|
1448
|
+
/**
|
|
1449
|
+
* Type guard that checks if a value is null or undefined.
|
|
1450
|
+
*
|
|
1451
|
+
* @param val - The value to check
|
|
1452
|
+
* @returns True if the value is null or undefined, false otherwise
|
|
1453
|
+
*
|
|
1454
|
+
* @example
|
|
1455
|
+
* if (isNullish(value)) {
|
|
1456
|
+
* console.log('Value is null or undefined');
|
|
1457
|
+
* }
|
|
1458
|
+
*/
|
|
648
1459
|
declare const isNullish: (val: unknown) => val is null | undefined;
|
|
1460
|
+
/**
|
|
1461
|
+
* Type guard that checks if a value is a primitive type.
|
|
1462
|
+
*
|
|
1463
|
+
* @param val - The value to check
|
|
1464
|
+
* @returns True if the value is a primitive, false otherwise
|
|
1465
|
+
*
|
|
1466
|
+
* @example
|
|
1467
|
+
* if (isPrimitive(value)) {
|
|
1468
|
+
* console.log('Value is a primitive type');
|
|
1469
|
+
* }
|
|
1470
|
+
*/
|
|
649
1471
|
declare const isPrimitive: (val: unknown) => val is Primitive;
|
|
1472
|
+
/**
|
|
1473
|
+
* Type guard that checks if a value is a plain object (not an array, function, etc.).
|
|
1474
|
+
*
|
|
1475
|
+
* @param value - The value to check
|
|
1476
|
+
* @returns True if the value is a plain object, false otherwise
|
|
1477
|
+
*
|
|
1478
|
+
* @example
|
|
1479
|
+
* if (isPlainObject(value)) {
|
|
1480
|
+
* console.log('Value is a plain object');
|
|
1481
|
+
* }
|
|
1482
|
+
*/
|
|
650
1483
|
declare function isPlainObject(value: unknown): value is Record<string, any>;
|
|
651
1484
|
//#endregion
|
|
652
1485
|
export { AND, AllOrNone, BUFFER, DeepPartial, DeepReadonly, DeepRequired, Diff, Falsy, IMPLIES, Intersection, Keys, KeysOfType, Maybe, Merge, MergeRefs, Mutable, NAND, NOR, NOT, NestedKeyOf, Never, Nullable, Nullish, OR, OmitByType, OneOf, Optional, Prettify, Primitive, RequiredKeys, ScheduleOpts, SelectivePartial, SelectiveRequired, Substract, Task, TwoOf, Values, Without, XNOR, XNOR_Binary, XOR, XOR_Binary, cleanSrc, cn, convertToNormalCase, convertToSlug, copyToClipboard, debounce, deepmerge, deleteClientSideCookie, escapeRegExp, extendProps, getClientSideCookie, getObjectValue, goToClientSideHash, hasClientSideCookie, hydrate, isFalsy, isLinkActive, isNavActive, isNullish, isPlainObject, isPrimitive, isSSR, mergeRefs, normalizeText, poll, printf, schedule, scrollTo, setClientSideCookie, shield, sleep, svgToBase64, throttle };
|