1+ /**
2+ * Uppercases the first character of a string and returns the result.
3+ */
14export function capitalize ( str : string ) {
25 return str . charAt ( 0 ) . toUpperCase ( ) + str . slice ( 1 )
36}
47
8+ /**
9+ * Converts a kebab-case slug (eg. "my-example") into a Title Case string.
10+ */
511export function slugToTitle ( str : string ) {
612 return str
713 . split ( '-' )
@@ -18,11 +24,18 @@ export function slugToTitle(str: string) {
1824// },
1925// }
2026
27+ /**
28+ * Returns the last element from an array.
29+ */
2130export function last < T > ( arr : T [ ] ) {
2231 return arr [ arr . length - 1 ]
2332}
2433
25- // Generates path replacing tokens with params
34+ /**
35+ * Generates a route path by replacing token segments in an id with params.
36+ * The id uses dot-notation which is converted to slashes; `$param` tokens are
37+ * replaced from `params`, and `$*` is treated as the catch-all segment.
38+ */
2639export function generatePath (
2740 id : string ,
2841 params : Record < string , string | undefined >
@@ -36,6 +49,9 @@ export function generatePath(
3649 return result
3750}
3851
52+ /**
53+ * Returns a shallow-copied array with items shuffled.
54+ */
3955export function shuffle < T > ( arr : T [ ] ) {
4056 const random = Math . random ( )
4157 const result = arr . slice ( )
@@ -50,10 +66,18 @@ export function shuffle<T>(arr: T[]) {
5066 return result
5167}
5268
69+ /**
70+ * Returns a single random element from an array. Accepts an optional
71+ * `random` function for deterministic tests.
72+ */
5373export function sample ( arr : any [ ] , random = Math . random ( ) ) {
5474 return arr [ Math . floor ( random * arr . length ) ]
5575}
5676
77+ /**
78+ * Sorts an array by a computed value. Undefined values are ordered last and
79+ * numeric strings are coerced to numbers for intuitive sorting.
80+ */
5781export function sortBy < T > ( arr : T [ ] , accessor : ( d : T ) => any = ( d ) => d ) : T [ ] {
5882 return arr
5983 . map ( ( d : any , i : any ) => [ d , i ] )
@@ -76,6 +100,9 @@ export function sortBy<T>(arr: T[], accessor: (d: T) => any = (d) => d): T[] {
76100 . map ( ( d : any ) => d [ 0 ] )
77101}
78102
103+ /**
104+ * Returns true if the string fully represents a number (no extra characters).
105+ */
79106export function isNumericString ( str : string ) : boolean {
80107 if ( typeof str !== 'string' ) {
81108 return false // we only process strings!
@@ -134,6 +161,10 @@ export function removeLeadingSlash(path: string): string {
134161 return path . replace ( / ^ \/ / , '' )
135162}
136163
164+ /**
165+ * Measures and logs the execution time of the provided function and returns
166+ * its result. Works with both sync and async functions.
167+ */
137168export async function logTime < T > (
138169 lable : string ,
139170 fn : ( ) => T
0 commit comments