@leancodepl/utils 8.4.0 → 8.5.1

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/index.cjs.js CHANGED
@@ -3,7 +3,21 @@
3
3
  var invariant = require('tiny-invariant');
4
4
  var react = require('react');
5
5
 
6
- function addPrefix(object, prefix) {
6
+ /**
7
+ * Adds a prefix to all keys in an object, creating a new object with prefixed keys.
8
+ *
9
+ * @template T - The type of the input object
10
+ * @template TPrefix - The type of the prefix string
11
+ * @param object - The object whose keys will be prefixed
12
+ * @param prefix - The prefix string to add to each key
13
+ * @returns A new object with all keys prefixed
14
+ * @example
15
+ * ```typescript
16
+ * const apiData = { userId: 1, userName: 'John' };
17
+ * const prefixed = addPrefix(apiData, 'api_');
18
+ * // Result: { api_userId: 1, api_userName: 'John' }
19
+ * ```
20
+ */ function addPrefix(object, prefix) {
7
21
  return Object.fromEntries(Object.entries(object).map(([key, value])=>[
8
22
  `${prefix}${key}`,
9
23
  value
@@ -16,10 +30,30 @@ function transformFirst(value, transformFn) {
16
30
  }
17
31
  return transformFn(value[0]) + value.slice(1);
18
32
  }
19
- function toLowerFirst(value) {
33
+ /**
34
+ * Converts the first character of a string to lowercase.
35
+ *
36
+ * @param value - The string to transform
37
+ * @returns The string with the first character in lowercase
38
+ * @example
39
+ * ```typescript
40
+ * const result = toLowerFirst('UserName');
41
+ * // Result: 'userName'
42
+ * ```
43
+ */ function toLowerFirst(value) {
20
44
  return transformFirst(value, (value)=>value.toLowerCase());
21
45
  }
22
- function toUpperFirst(value) {
46
+ /**
47
+ * Converts the first character of a string to uppercase.
48
+ *
49
+ * @param value - The string to transform
50
+ * @returns The string with the first character in uppercase
51
+ * @example
52
+ * ```typescript
53
+ * const result = toUpperFirst('userName');
54
+ * // Result: 'UserName'
55
+ * ```
56
+ */ function toUpperFirst(value) {
23
57
  return transformFirst(value, (value)=>value.toUpperCase());
24
58
  }
25
59
 
@@ -49,36 +83,151 @@ function transformDeep(value, mode) {
49
83
  }
50
84
  return value;
51
85
  }
52
- function uncapitalizeDeep(value) {
86
+ /**
87
+ * Recursively transforms all object keys to use uncapitalized (camelCase) format.
88
+ *
89
+ * @template T - The type of the input value
90
+ * @param value - The value to transform (can be object, array, or primitive)
91
+ * @returns A new object with all keys converted to camelCase
92
+ * @example
93
+ * ```typescript
94
+ * const serverData = { UserId: 1, UserName: 'John', Profile: { FirstName: 'John' } };
95
+ * const clientData = uncapitalizeDeep(serverData);
96
+ * // Result: { userId: 1, userName: 'John', profile: { firstName: 'John' } }
97
+ * ```
98
+ */ function uncapitalizeDeep(value) {
53
99
  return transformDeep(value, "uncapitalize");
54
100
  }
55
- function capitalizeDeep(value) {
101
+ /**
102
+ * Recursively transforms all object keys to use capitalized (PascalCase) format.
103
+ *
104
+ * @template T - The type of the input value
105
+ * @param value - The value to transform (can be object, array, or primitive)
106
+ * @returns A new object with all keys converted to PascalCase
107
+ * @example
108
+ * ```typescript
109
+ * const clientData = { userId: 1, userName: 'John', profile: { firstName: 'John' } };
110
+ * const serverData = capitalizeDeep(clientData);
111
+ * // Result: { UserId: 1, UserName: 'John', Profile: { FirstName: 'John' } }
112
+ * ```
113
+ */ function capitalizeDeep(value) {
56
114
  return transformDeep(value, "capitalize");
57
115
  }
58
116
 
59
- function assertDefined(value, message) {
117
+ /**
118
+ * Asserts that a value is not undefined. Throws an error if the value is undefined.
119
+ * This is a type assertion function that narrows the type to exclude undefined.
120
+ *
121
+ * @template T - The type of the value being checked
122
+ * @param value - The value to check for undefined
123
+ * @param message - Optional error message to use if assertion fails
124
+ * @throws {Error} When the value is undefined
125
+ * @example
126
+ * ```typescript
127
+ * function processUser(user?: User) {
128
+ * assertDefined(user);
129
+ * return user.name; // TypeScript knows user is defined
130
+ * }
131
+ * ```
132
+ */ function assertDefined(value, message) {
60
133
  invariant(value !== undefined, message);
61
134
  }
62
135
 
63
- function assertNotNull(value, message) {
136
+ /**
137
+ * Asserts that a value is not null. Throws an error if the value is null.
138
+ * This is a type assertion function that narrows the type to exclude null.
139
+ *
140
+ * @template T - The type of the value being checked
141
+ * @param value - The value to check for null
142
+ * @param message - Optional error message to use if assertion fails
143
+ * @throws {Error} When the value is null
144
+ * @example
145
+ * ```typescript
146
+ * function processData(data: string | null) {
147
+ * assertNotNull(data);
148
+ * return data.toUpperCase(); // TypeScript knows data is not null
149
+ * }
150
+ * ```
151
+ */ function assertNotNull(value, message) {
64
152
  invariant(value !== null, message);
65
153
  }
66
154
 
67
- function assertNotEmpty(value, message) {
155
+ /**
156
+ * Asserts that a value is not null or undefined. Throws an error if the value is null or undefined.
157
+ * This is a type assertion function that narrows the type to exclude null and undefined.
158
+ *
159
+ * @template T - The type of the value being checked
160
+ * @param value - The value to check for null or undefined
161
+ * @param message - Optional error message to use if assertion fails
162
+ * @throws {Error} When the value is null or undefined
163
+ * @example
164
+ * ```typescript
165
+ * function processOptionalData(data?: string | null) {
166
+ * assertNotEmpty(data);
167
+ * return data.toUpperCase(); // TypeScript knows data is not null/undefined
168
+ * }
169
+ * ```
170
+ */ function assertNotEmpty(value, message) {
68
171
  invariant(value !== null && value !== undefined, message);
69
172
  }
70
173
 
71
- function ensureDefined(value, message) {
174
+ /**
175
+ * Ensures that a value is defined, returning it if defined or throwing an error if undefined.
176
+ *
177
+ * @template T - The type of the value being checked
178
+ * @param value - The value to ensure is defined
179
+ * @param message - Optional error message to use if the value is undefined
180
+ * @returns The value if it is defined
181
+ * @throws {Error} When the value is undefined
182
+ * @example
183
+ * ```typescript
184
+ * function processUser(user?: User) {
185
+ * const definedUser = ensureDefined(user);
186
+ * return definedUser.name; // definedUser is guaranteed to be defined
187
+ * }
188
+ * ```
189
+ */ function ensureDefined(value, message) {
72
190
  assertDefined(value, message);
73
191
  return value;
74
192
  }
75
193
 
76
- function ensureNotNull(value, message) {
194
+ /**
195
+ * Ensures that a value is not null, returning it if not null or throwing an error if null.
196
+ * Unlike assertNotNull, this function returns the value for use in expressions.
197
+ *
198
+ * @template T - The type of the value being checked
199
+ * @param value - The value to ensure is not null
200
+ * @param message - Optional error message to use if the value is null
201
+ * @returns The value if it is not null
202
+ * @throws {Error} When the value is null
203
+ * @example
204
+ * ```typescript
205
+ * function processData(data: string | null) {
206
+ * const nonNullData = ensureNotNull(data);
207
+ * return nonNullData.toUpperCase(); // nonNullData is guaranteed to be not null
208
+ * }
209
+ * ```
210
+ */ function ensureNotNull(value, message) {
77
211
  assertNotNull(value, message);
78
212
  return value;
79
213
  }
80
214
 
81
- function ensureNotEmpty(value, message) {
215
+ /**
216
+ * Ensures that a value is not null or undefined, returning it if valid or throwing an error if empty.
217
+ *
218
+ * @template T - The type of the value being checked
219
+ * @param value - The value to ensure is not null or undefined
220
+ * @param message - Optional error message to use if the value is null or undefined
221
+ * @returns The value if it is not null or undefined
222
+ * @throws {Error} When the value is null or undefined
223
+ * @example
224
+ * ```typescript
225
+ * function processOptionalData(data?: string | null) {
226
+ * const validData = ensureNotEmpty(data);
227
+ * return validData.toUpperCase(); // validData is guaranteed to be not null/undefined
228
+ * }
229
+ * ```
230
+ */ function ensureNotEmpty(value, message) {
82
231
  assertNotEmpty(value, message);
83
232
  return value;
84
233
  }
@@ -98,7 +247,30 @@ function downloadFile(dataOrUrl, options = {}) {
98
247
  }
99
248
  }
100
249
 
101
- function useRunInTask() {
250
+ /**
251
+ * React hook for tracking async task execution with loading state.
252
+ * Automatically manages a loading counter and provides a wrapper function for tasks.
253
+ *
254
+ * @returns A tuple containing [isLoading: boolean, runInTask: function]
255
+ * @example
256
+ * ```typescript
257
+ * function MyComponent() {
258
+ * const [isLoading, runInTask] = useRunInTask();
259
+ *
260
+ * const handleSave = async () => {
261
+ * await runInTask(async () => {
262
+ * await saveData();
263
+ * });
264
+ * };
265
+ *
266
+ * return (
267
+ * <button onClick={handleSave} disabled={isLoading}>
268
+ * {isLoading ? 'Saving...' : 'Save'}
269
+ * </button>
270
+ * );
271
+ * }
272
+ * ```
273
+ */ function useRunInTask() {
102
274
  const [runningTasks, setRunningTasks] = react.useState(0);
103
275
  const runInTask = react.useCallback(async (task)=>{
104
276
  setRunningTasks((runningTasks)=>runningTasks + 1);
@@ -126,7 +298,34 @@ function useBoundRunInTask(block) {
126
298
  ];
127
299
  }
128
300
 
129
- function useKeyByRoute(routeMatches) {
301
+ /**
302
+ * React hook for generating keys based on current route matches.
303
+ *
304
+ * @template TKey - The type of the route keys
305
+ * @param routeMatches - Record of route keys to match objects or arrays
306
+ * @returns Array of active route keys
307
+ * @example
308
+ * ```typescript
309
+ * function NavigationComponent() {
310
+ * const routeMatches = {
311
+ * home: useRouteMatch('/'),
312
+ * about: useRouteMatch('/about'),
313
+ * contact: useRouteMatch('/contact')
314
+ * };
315
+ *
316
+ * const activeRoutes = useKeyByRoute(routeMatches);
317
+ * // Returns ['home'] if on home page, ['about'] if on about page, etc.
318
+ *
319
+ * return (
320
+ * <nav>
321
+ * {activeRoutes.map(route => (
322
+ * <span key={route}>Active: {route}</span>
323
+ * ))}
324
+ * </nav>
325
+ * );
326
+ * }
327
+ * ```
328
+ */ function useKeyByRoute(routeMatches) {
130
329
  const keys = [];
131
330
  for(const key in routeMatches){
132
331
  const matches = routeMatches[key];
@@ -137,7 +336,27 @@ function useKeyByRoute(routeMatches) {
137
336
  return keys;
138
337
  }
139
338
 
140
- function useSetUnset(set) {
339
+ /**
340
+ * React hook for boolean state management helpers.
341
+ *
342
+ * @param set - The state setter function from useState
343
+ * @returns A tuple containing [setTrue: function, setFalse: function]
344
+ * @example
345
+ * ```typescript
346
+ * function MyComponent() {
347
+ * const [isVisible, setIsVisible] = useState(false);
348
+ * const [show, hide] = useSetUnset(setIsVisible);
349
+ *
350
+ * return (
351
+ * <div>
352
+ * <button onClick={show}>Show</button>
353
+ * <button onClick={hide}>Hide</button>
354
+ * {isVisible && <div>Content is visible</div>}
355
+ * </div>
356
+ * );
357
+ * }
358
+ * ```
359
+ */ function useSetUnset(set) {
141
360
  return [
142
361
  react.useCallback(()=>set(true), [
143
362
  set
@@ -148,7 +367,28 @@ function useSetUnset(set) {
148
367
  ];
149
368
  }
150
369
 
151
- function useDialog(onAfterClose) {
370
+ /**
371
+ * React hook for managing dialog state with optional callback after closing.
372
+ * Provides convenient open/close functions and tracks the dialog's open state.
373
+ *
374
+ * @param onAfterClose - Optional callback function to execute after the dialog closes
375
+ * @returns Object containing dialog state and control functions
376
+ * @example
377
+ * ```typescript
378
+ * function MyComponent() {
379
+ * const { isDialogOpen, openDialog, closeDialog } = useDialog(() => {
380
+ * console.log('Dialog closed');
381
+ * });
382
+ *
383
+ * return (
384
+ * <div>
385
+ * <button onClick={openDialog}>Open Dialog</button>
386
+ * {isDialogOpen && <Dialog onClose={closeDialog} />}
387
+ * </div>
388
+ * );
389
+ * }
390
+ * ```
391
+ */ function useDialog(onAfterClose) {
152
392
  const [isDialogOpen, setIsDialogOpen] = react.useState(false);
153
393
  const [openDialog, closeDialog] = useSetUnset(setIsDialogOpen);
154
394
  const close = react.useCallback(()=>{
package/index.esm.js CHANGED
@@ -1,7 +1,21 @@
1
1
  import invariant from 'tiny-invariant';
2
2
  import { useState, useCallback, useMemo } from 'react';
3
3
 
4
- function addPrefix(object, prefix) {
4
+ /**
5
+ * Adds a prefix to all keys in an object, creating a new object with prefixed keys.
6
+ *
7
+ * @template T - The type of the input object
8
+ * @template TPrefix - The type of the prefix string
9
+ * @param object - The object whose keys will be prefixed
10
+ * @param prefix - The prefix string to add to each key
11
+ * @returns A new object with all keys prefixed
12
+ * @example
13
+ * ```typescript
14
+ * const apiData = { userId: 1, userName: 'John' };
15
+ * const prefixed = addPrefix(apiData, 'api_');
16
+ * // Result: { api_userId: 1, api_userName: 'John' }
17
+ * ```
18
+ */ function addPrefix(object, prefix) {
5
19
  return Object.fromEntries(Object.entries(object).map(([key, value])=>[
6
20
  `${prefix}${key}`,
7
21
  value
@@ -14,10 +28,30 @@ function transformFirst(value, transformFn) {
14
28
  }
15
29
  return transformFn(value[0]) + value.slice(1);
16
30
  }
17
- function toLowerFirst(value) {
31
+ /**
32
+ * Converts the first character of a string to lowercase.
33
+ *
34
+ * @param value - The string to transform
35
+ * @returns The string with the first character in lowercase
36
+ * @example
37
+ * ```typescript
38
+ * const result = toLowerFirst('UserName');
39
+ * // Result: 'userName'
40
+ * ```
41
+ */ function toLowerFirst(value) {
18
42
  return transformFirst(value, (value)=>value.toLowerCase());
19
43
  }
20
- function toUpperFirst(value) {
44
+ /**
45
+ * Converts the first character of a string to uppercase.
46
+ *
47
+ * @param value - The string to transform
48
+ * @returns The string with the first character in uppercase
49
+ * @example
50
+ * ```typescript
51
+ * const result = toUpperFirst('userName');
52
+ * // Result: 'UserName'
53
+ * ```
54
+ */ function toUpperFirst(value) {
21
55
  return transformFirst(value, (value)=>value.toUpperCase());
22
56
  }
23
57
 
@@ -47,36 +81,151 @@ function transformDeep(value, mode) {
47
81
  }
48
82
  return value;
49
83
  }
50
- function uncapitalizeDeep(value) {
84
+ /**
85
+ * Recursively transforms all object keys to use uncapitalized (camelCase) format.
86
+ *
87
+ * @template T - The type of the input value
88
+ * @param value - The value to transform (can be object, array, or primitive)
89
+ * @returns A new object with all keys converted to camelCase
90
+ * @example
91
+ * ```typescript
92
+ * const serverData = { UserId: 1, UserName: 'John', Profile: { FirstName: 'John' } };
93
+ * const clientData = uncapitalizeDeep(serverData);
94
+ * // Result: { userId: 1, userName: 'John', profile: { firstName: 'John' } }
95
+ * ```
96
+ */ function uncapitalizeDeep(value) {
51
97
  return transformDeep(value, "uncapitalize");
52
98
  }
53
- function capitalizeDeep(value) {
99
+ /**
100
+ * Recursively transforms all object keys to use capitalized (PascalCase) format.
101
+ *
102
+ * @template T - The type of the input value
103
+ * @param value - The value to transform (can be object, array, or primitive)
104
+ * @returns A new object with all keys converted to PascalCase
105
+ * @example
106
+ * ```typescript
107
+ * const clientData = { userId: 1, userName: 'John', profile: { firstName: 'John' } };
108
+ * const serverData = capitalizeDeep(clientData);
109
+ * // Result: { UserId: 1, UserName: 'John', Profile: { FirstName: 'John' } }
110
+ * ```
111
+ */ function capitalizeDeep(value) {
54
112
  return transformDeep(value, "capitalize");
55
113
  }
56
114
 
57
- function assertDefined(value, message) {
115
+ /**
116
+ * Asserts that a value is not undefined. Throws an error if the value is undefined.
117
+ * This is a type assertion function that narrows the type to exclude undefined.
118
+ *
119
+ * @template T - The type of the value being checked
120
+ * @param value - The value to check for undefined
121
+ * @param message - Optional error message to use if assertion fails
122
+ * @throws {Error} When the value is undefined
123
+ * @example
124
+ * ```typescript
125
+ * function processUser(user?: User) {
126
+ * assertDefined(user);
127
+ * return user.name; // TypeScript knows user is defined
128
+ * }
129
+ * ```
130
+ */ function assertDefined(value, message) {
58
131
  invariant(value !== undefined, message);
59
132
  }
60
133
 
61
- function assertNotNull(value, message) {
134
+ /**
135
+ * Asserts that a value is not null. Throws an error if the value is null.
136
+ * This is a type assertion function that narrows the type to exclude null.
137
+ *
138
+ * @template T - The type of the value being checked
139
+ * @param value - The value to check for null
140
+ * @param message - Optional error message to use if assertion fails
141
+ * @throws {Error} When the value is null
142
+ * @example
143
+ * ```typescript
144
+ * function processData(data: string | null) {
145
+ * assertNotNull(data);
146
+ * return data.toUpperCase(); // TypeScript knows data is not null
147
+ * }
148
+ * ```
149
+ */ function assertNotNull(value, message) {
62
150
  invariant(value !== null, message);
63
151
  }
64
152
 
65
- function assertNotEmpty(value, message) {
153
+ /**
154
+ * Asserts that a value is not null or undefined. Throws an error if the value is null or undefined.
155
+ * This is a type assertion function that narrows the type to exclude null and undefined.
156
+ *
157
+ * @template T - The type of the value being checked
158
+ * @param value - The value to check for null or undefined
159
+ * @param message - Optional error message to use if assertion fails
160
+ * @throws {Error} When the value is null or undefined
161
+ * @example
162
+ * ```typescript
163
+ * function processOptionalData(data?: string | null) {
164
+ * assertNotEmpty(data);
165
+ * return data.toUpperCase(); // TypeScript knows data is not null/undefined
166
+ * }
167
+ * ```
168
+ */ function assertNotEmpty(value, message) {
66
169
  invariant(value !== null && value !== undefined, message);
67
170
  }
68
171
 
69
- function ensureDefined(value, message) {
172
+ /**
173
+ * Ensures that a value is defined, returning it if defined or throwing an error if undefined.
174
+ *
175
+ * @template T - The type of the value being checked
176
+ * @param value - The value to ensure is defined
177
+ * @param message - Optional error message to use if the value is undefined
178
+ * @returns The value if it is defined
179
+ * @throws {Error} When the value is undefined
180
+ * @example
181
+ * ```typescript
182
+ * function processUser(user?: User) {
183
+ * const definedUser = ensureDefined(user);
184
+ * return definedUser.name; // definedUser is guaranteed to be defined
185
+ * }
186
+ * ```
187
+ */ function ensureDefined(value, message) {
70
188
  assertDefined(value, message);
71
189
  return value;
72
190
  }
73
191
 
74
- function ensureNotNull(value, message) {
192
+ /**
193
+ * Ensures that a value is not null, returning it if not null or throwing an error if null.
194
+ * Unlike assertNotNull, this function returns the value for use in expressions.
195
+ *
196
+ * @template T - The type of the value being checked
197
+ * @param value - The value to ensure is not null
198
+ * @param message - Optional error message to use if the value is null
199
+ * @returns The value if it is not null
200
+ * @throws {Error} When the value is null
201
+ * @example
202
+ * ```typescript
203
+ * function processData(data: string | null) {
204
+ * const nonNullData = ensureNotNull(data);
205
+ * return nonNullData.toUpperCase(); // nonNullData is guaranteed to be not null
206
+ * }
207
+ * ```
208
+ */ function ensureNotNull(value, message) {
75
209
  assertNotNull(value, message);
76
210
  return value;
77
211
  }
78
212
 
79
- function ensureNotEmpty(value, message) {
213
+ /**
214
+ * Ensures that a value is not null or undefined, returning it if valid or throwing an error if empty.
215
+ *
216
+ * @template T - The type of the value being checked
217
+ * @param value - The value to ensure is not null or undefined
218
+ * @param message - Optional error message to use if the value is null or undefined
219
+ * @returns The value if it is not null or undefined
220
+ * @throws {Error} When the value is null or undefined
221
+ * @example
222
+ * ```typescript
223
+ * function processOptionalData(data?: string | null) {
224
+ * const validData = ensureNotEmpty(data);
225
+ * return validData.toUpperCase(); // validData is guaranteed to be not null/undefined
226
+ * }
227
+ * ```
228
+ */ function ensureNotEmpty(value, message) {
80
229
  assertNotEmpty(value, message);
81
230
  return value;
82
231
  }
@@ -96,7 +245,30 @@ function downloadFile(dataOrUrl, options = {}) {
96
245
  }
97
246
  }
98
247
 
99
- function useRunInTask() {
248
+ /**
249
+ * React hook for tracking async task execution with loading state.
250
+ * Automatically manages a loading counter and provides a wrapper function for tasks.
251
+ *
252
+ * @returns A tuple containing [isLoading: boolean, runInTask: function]
253
+ * @example
254
+ * ```typescript
255
+ * function MyComponent() {
256
+ * const [isLoading, runInTask] = useRunInTask();
257
+ *
258
+ * const handleSave = async () => {
259
+ * await runInTask(async () => {
260
+ * await saveData();
261
+ * });
262
+ * };
263
+ *
264
+ * return (
265
+ * <button onClick={handleSave} disabled={isLoading}>
266
+ * {isLoading ? 'Saving...' : 'Save'}
267
+ * </button>
268
+ * );
269
+ * }
270
+ * ```
271
+ */ function useRunInTask() {
100
272
  const [runningTasks, setRunningTasks] = useState(0);
101
273
  const runInTask = useCallback(async (task)=>{
102
274
  setRunningTasks((runningTasks)=>runningTasks + 1);
@@ -124,7 +296,34 @@ function useBoundRunInTask(block) {
124
296
  ];
125
297
  }
126
298
 
127
- function useKeyByRoute(routeMatches) {
299
+ /**
300
+ * React hook for generating keys based on current route matches.
301
+ *
302
+ * @template TKey - The type of the route keys
303
+ * @param routeMatches - Record of route keys to match objects or arrays
304
+ * @returns Array of active route keys
305
+ * @example
306
+ * ```typescript
307
+ * function NavigationComponent() {
308
+ * const routeMatches = {
309
+ * home: useRouteMatch('/'),
310
+ * about: useRouteMatch('/about'),
311
+ * contact: useRouteMatch('/contact')
312
+ * };
313
+ *
314
+ * const activeRoutes = useKeyByRoute(routeMatches);
315
+ * // Returns ['home'] if on home page, ['about'] if on about page, etc.
316
+ *
317
+ * return (
318
+ * <nav>
319
+ * {activeRoutes.map(route => (
320
+ * <span key={route}>Active: {route}</span>
321
+ * ))}
322
+ * </nav>
323
+ * );
324
+ * }
325
+ * ```
326
+ */ function useKeyByRoute(routeMatches) {
128
327
  const keys = [];
129
328
  for(const key in routeMatches){
130
329
  const matches = routeMatches[key];
@@ -135,7 +334,27 @@ function useKeyByRoute(routeMatches) {
135
334
  return keys;
136
335
  }
137
336
 
138
- function useSetUnset(set) {
337
+ /**
338
+ * React hook for boolean state management helpers.
339
+ *
340
+ * @param set - The state setter function from useState
341
+ * @returns A tuple containing [setTrue: function, setFalse: function]
342
+ * @example
343
+ * ```typescript
344
+ * function MyComponent() {
345
+ * const [isVisible, setIsVisible] = useState(false);
346
+ * const [show, hide] = useSetUnset(setIsVisible);
347
+ *
348
+ * return (
349
+ * <div>
350
+ * <button onClick={show}>Show</button>
351
+ * <button onClick={hide}>Hide</button>
352
+ * {isVisible && <div>Content is visible</div>}
353
+ * </div>
354
+ * );
355
+ * }
356
+ * ```
357
+ */ function useSetUnset(set) {
139
358
  return [
140
359
  useCallback(()=>set(true), [
141
360
  set
@@ -146,7 +365,28 @@ function useSetUnset(set) {
146
365
  ];
147
366
  }
148
367
 
149
- function useDialog(onAfterClose) {
368
+ /**
369
+ * React hook for managing dialog state with optional callback after closing.
370
+ * Provides convenient open/close functions and tracks the dialog's open state.
371
+ *
372
+ * @param onAfterClose - Optional callback function to execute after the dialog closes
373
+ * @returns Object containing dialog state and control functions
374
+ * @example
375
+ * ```typescript
376
+ * function MyComponent() {
377
+ * const { isDialogOpen, openDialog, closeDialog } = useDialog(() => {
378
+ * console.log('Dialog closed');
379
+ * });
380
+ *
381
+ * return (
382
+ * <div>
383
+ * <button onClick={openDialog}>Open Dialog</button>
384
+ * {isDialogOpen && <Dialog onClose={closeDialog} />}
385
+ * </div>
386
+ * );
387
+ * }
388
+ * ```
389
+ */ function useDialog(onAfterClose) {
150
390
  const [isDialogOpen, setIsDialogOpen] = useState(false);
151
391
  const [openDialog, closeDialog] = useSetUnset(setIsDialogOpen);
152
392
  const close = useCallback(()=>{