@fuzdev/fuz_util 0.45.2 → 0.46.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/dist/array.d.ts +1 -1
- package/dist/array.js +1 -1
- package/dist/async.d.ts +18 -0
- package/dist/async.d.ts.map +1 -1
- package/dist/async.js +63 -3
- package/dist/dom.d.ts +2 -2
- package/dist/dom.js +2 -2
- package/dist/fetch.d.ts +1 -1
- package/dist/fetch.js +1 -1
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +10 -10
- package/dist/path.d.ts +1 -1
- package/dist/path.js +2 -2
- package/dist/print.d.ts +1 -1
- package/dist/print.js +1 -1
- package/dist/process.d.ts +303 -43
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +475 -108
- package/dist/random.d.ts +1 -1
- package/dist/random.js +1 -1
- package/dist/regexp.d.ts +1 -1
- package/dist/regexp.js +1 -1
- package/package.json +6 -5
- package/src/lib/array.ts +1 -1
- package/src/lib/async.ts +72 -3
- package/src/lib/dom.ts +2 -2
- package/src/lib/fetch.ts +1 -1
- package/src/lib/git.ts +20 -10
- package/src/lib/path.ts +2 -2
- package/src/lib/print.ts +1 -1
- package/src/lib/process.ts +681 -135
- package/src/lib/random.ts +1 -1
- package/src/lib/regexp.ts +1 -1
package/dist/regexp.js
CHANGED
|
@@ -6,7 +6,7 @@ export const escape_regexp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
|
6
6
|
/**
|
|
7
7
|
* Reset a RegExp's lastIndex to 0 for global and sticky patterns.
|
|
8
8
|
* Ensures consistent behavior by clearing state that affects subsequent matches.
|
|
9
|
-
* @mutates regexp sets lastIndex to 0 if regexp is global or sticky
|
|
9
|
+
* @mutates regexp - sets lastIndex to 0 if regexp is global or sticky
|
|
10
10
|
*/
|
|
11
11
|
export const reset_regexp = (regexp) => {
|
|
12
12
|
if (regexp.global || regexp.sticky) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fuzdev/fuz_util",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0",
|
|
4
4
|
"description": "utility belt for JS",
|
|
5
5
|
"glyph": "🦕",
|
|
6
6
|
"logo": "logo.svg",
|
|
@@ -61,16 +61,17 @@
|
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@changesets/changelog-git": "^0.2.1",
|
|
64
|
-
"@fuzdev/fuz_code": "^0.
|
|
65
|
-
"@fuzdev/fuz_css": "^0.
|
|
66
|
-
"@fuzdev/fuz_ui": "^0.
|
|
64
|
+
"@fuzdev/fuz_code": "^0.40.0",
|
|
65
|
+
"@fuzdev/fuz_css": "^0.44.1",
|
|
66
|
+
"@fuzdev/fuz_ui": "^0.179.0",
|
|
67
67
|
"@ryanatkn/eslint-config": "^0.9.0",
|
|
68
|
-
"@ryanatkn/gro": "^0.
|
|
68
|
+
"@ryanatkn/gro": "^0.186.0",
|
|
69
69
|
"@sveltejs/adapter-static": "^3.0.10",
|
|
70
70
|
"@sveltejs/kit": "^2.49.1",
|
|
71
71
|
"@sveltejs/package": "^2.5.7",
|
|
72
72
|
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
|
73
73
|
"@types/node": "^24.10.1",
|
|
74
|
+
"@webref/css": "^8.2.0",
|
|
74
75
|
"dequal": "^2.0.3",
|
|
75
76
|
"eslint": "^9.39.1",
|
|
76
77
|
"eslint-plugin-svelte": "^3.13.1",
|
package/src/lib/array.ts
CHANGED
|
@@ -9,7 +9,7 @@ export const to_array = <T>(value: T): T extends ReadonlyArray<any> ? T : Array<
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Removes an element from `array` at `index` in an unordered manner.
|
|
12
|
-
* @mutates array swaps element at index with last element, then removes last element
|
|
12
|
+
* @mutates array - swaps element at index with last element, then removes last element
|
|
13
13
|
*/
|
|
14
14
|
export const remove_unordered = (array: Array<any>, index: number): void => {
|
|
15
15
|
array[index] = array[array.length - 1];
|
package/src/lib/async.ts
CHANGED
|
@@ -34,6 +34,77 @@ export const create_deferred = <T>(): Deferred<T> => {
|
|
|
34
34
|
return {promise, resolve, reject};
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Runs an async function on each item with controlled concurrency.
|
|
39
|
+
* Like `map_concurrent` but doesn't collect results (more efficient for side effects).
|
|
40
|
+
*
|
|
41
|
+
* @param items array of items to process
|
|
42
|
+
* @param fn async function to apply to each item
|
|
43
|
+
* @param concurrency maximum number of concurrent operations
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* await each_concurrent(
|
|
48
|
+
* file_paths,
|
|
49
|
+
* async (path) => { await unlink(path); },
|
|
50
|
+
* 5, // max 5 concurrent deletions
|
|
51
|
+
* );
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export const each_concurrent = async <T>(
|
|
55
|
+
items: Array<T>,
|
|
56
|
+
fn: (item: T, index: number) => Promise<void>,
|
|
57
|
+
concurrency: number,
|
|
58
|
+
): Promise<void> => {
|
|
59
|
+
if (concurrency < 1) {
|
|
60
|
+
throw new Error('concurrency must be at least 1');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let next_index = 0;
|
|
64
|
+
let active_count = 0;
|
|
65
|
+
let rejected = false;
|
|
66
|
+
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
const run_next = (): void => {
|
|
69
|
+
// Stop spawning if we've rejected
|
|
70
|
+
if (rejected) return;
|
|
71
|
+
|
|
72
|
+
// Check if we're done
|
|
73
|
+
if (next_index >= items.length && active_count === 0) {
|
|
74
|
+
resolve();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Spawn workers up to concurrency limit
|
|
79
|
+
while (active_count < concurrency && next_index < items.length) {
|
|
80
|
+
const index = next_index++;
|
|
81
|
+
const item = items[index]!;
|
|
82
|
+
active_count++;
|
|
83
|
+
|
|
84
|
+
fn(item, index)
|
|
85
|
+
.then(() => {
|
|
86
|
+
if (rejected) return;
|
|
87
|
+
active_count--;
|
|
88
|
+
run_next();
|
|
89
|
+
})
|
|
90
|
+
.catch((error) => {
|
|
91
|
+
if (rejected) return;
|
|
92
|
+
rejected = true;
|
|
93
|
+
reject(error); // eslint-disable-line @typescript-eslint/prefer-promise-reject-errors
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// Handle empty array
|
|
99
|
+
if (items.length === 0) {
|
|
100
|
+
resolve();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
run_next();
|
|
105
|
+
});
|
|
106
|
+
};
|
|
107
|
+
|
|
37
108
|
/**
|
|
38
109
|
* Maps over items with controlled concurrency, preserving input order.
|
|
39
110
|
*
|
|
@@ -64,7 +135,6 @@ export const map_concurrent = async <T, R>(
|
|
|
64
135
|
let next_index = 0;
|
|
65
136
|
let active_count = 0;
|
|
66
137
|
let rejected = false;
|
|
67
|
-
let reject_error: unknown;
|
|
68
138
|
|
|
69
139
|
return new Promise((resolve, reject) => {
|
|
70
140
|
const run_next = (): void => {
|
|
@@ -93,8 +163,7 @@ export const map_concurrent = async <T, R>(
|
|
|
93
163
|
.catch((error) => {
|
|
94
164
|
if (rejected) return;
|
|
95
165
|
rejected = true;
|
|
96
|
-
|
|
97
|
-
reject(reject_error); // eslint-disable-line @typescript-eslint/prefer-promise-reject-errors
|
|
166
|
+
reject(error); // eslint-disable-line @typescript-eslint/prefer-promise-reject-errors
|
|
98
167
|
});
|
|
99
168
|
}
|
|
100
169
|
};
|
package/src/lib/dom.ts
CHANGED
|
@@ -63,7 +63,7 @@ export const is_interactive = (el: any): boolean => {
|
|
|
63
63
|
* @param event
|
|
64
64
|
* @param immediate defaults to `true` to use `stopImmediatePropagation` over `stopPropagation`
|
|
65
65
|
* @param preventDefault defaults to `true`
|
|
66
|
-
* @mutates event calls preventDefault(), stopPropagation(), or stopImmediatePropagation()
|
|
66
|
+
* @mutates event - calls preventDefault(), stopPropagation(), or stopImmediatePropagation()
|
|
67
67
|
* @returns
|
|
68
68
|
*/
|
|
69
69
|
export const swallow = <
|
|
@@ -86,7 +86,7 @@ export const swallow = <
|
|
|
86
86
|
/**
|
|
87
87
|
* Handles the value of an event's target and invokes a callback.
|
|
88
88
|
* Defaults to swallowing the event to prevent default actions and propagation.
|
|
89
|
-
* @mutates event calls `swallow()` which mutates the event if `swallow_event` is true
|
|
89
|
+
* @mutates event - calls `swallow()` which mutates the event if `swallow_event` is true
|
|
90
90
|
*/
|
|
91
91
|
export const handle_target_value =
|
|
92
92
|
(cb: (value: any, event: any) => void, swallow_event = true) =>
|
package/src/lib/fetch.ts
CHANGED
|
@@ -48,7 +48,7 @@ export interface FetchValueOptions<TValue, TParams = undefined> {
|
|
|
48
48
|
* If the `value` is cached, only the cached safe subset of the `headers` are returned.
|
|
49
49
|
* (currently just `etag` and `last-modified`)
|
|
50
50
|
* Otherwise the full `res.headers` are included.
|
|
51
|
-
* @mutates options.cache calls `cache.set()` to store fetched results if cache is provided
|
|
51
|
+
* @mutates options.cache - calls `cache.set()` to store fetched results if cache is provided
|
|
52
52
|
*/
|
|
53
53
|
export const fetch_value = async <TValue = any, TParams = undefined>(
|
|
54
54
|
url: string | URL,
|
package/src/lib/git.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {SpawnOptions} from 'node:child_process';
|
|
2
2
|
import {z} from 'zod';
|
|
3
3
|
|
|
4
|
-
import {spawn, spawn_out} from './process.js';
|
|
4
|
+
import {spawn, spawn_out, spawn_result_to_message} from './process.js';
|
|
5
5
|
import type {Flavored} from './types.js';
|
|
6
6
|
import {to_file_path} from './path.js';
|
|
7
7
|
import {fs_exists} from './fs.js';
|
|
@@ -65,11 +65,11 @@ export const git_remote_branch_exists = async (
|
|
|
65
65
|
);
|
|
66
66
|
if (result.ok) {
|
|
67
67
|
return true;
|
|
68
|
-
} else if (result.code === 2) {
|
|
68
|
+
} else if ('code' in result && result.code === 2) {
|
|
69
69
|
return false;
|
|
70
70
|
} else {
|
|
71
71
|
throw Error(
|
|
72
|
-
`git_remote_branch_exists failed for origin '${origin}' and branch '${final_branch}' with
|
|
72
|
+
`git_remote_branch_exists failed for origin '${origin}' and branch '${final_branch}' with ${spawn_result_to_message(result)}`,
|
|
73
73
|
);
|
|
74
74
|
}
|
|
75
75
|
};
|
|
@@ -235,7 +235,7 @@ export const git_fetch = async (
|
|
|
235
235
|
const result = await spawn('git', args, options);
|
|
236
236
|
if (!result.ok) {
|
|
237
237
|
throw Error(
|
|
238
|
-
`git_fetch failed for origin '${origin}' and branch '${branch}' with
|
|
238
|
+
`git_fetch failed for origin '${origin}' and branch '${branch}' with ${spawn_result_to_message(result)}`,
|
|
239
239
|
);
|
|
240
240
|
}
|
|
241
241
|
};
|
|
@@ -254,7 +254,9 @@ export const git_checkout = async (
|
|
|
254
254
|
}
|
|
255
255
|
const result = await spawn('git', ['checkout', branch], options);
|
|
256
256
|
if (!result.ok) {
|
|
257
|
-
throw Error(
|
|
257
|
+
throw Error(
|
|
258
|
+
`git_checkout failed for branch '${branch}' with ${spawn_result_to_message(result)}`,
|
|
259
|
+
);
|
|
258
260
|
}
|
|
259
261
|
return current_branch;
|
|
260
262
|
};
|
|
@@ -271,7 +273,7 @@ export const git_pull = async (
|
|
|
271
273
|
if (branch) args.push(branch);
|
|
272
274
|
const result = await spawn('git', args, options);
|
|
273
275
|
if (!result.ok) {
|
|
274
|
-
throw Error(`git_pull failed for branch '${branch}' with
|
|
276
|
+
throw Error(`git_pull failed for branch '${branch}' with ${spawn_result_to_message(result)}`);
|
|
275
277
|
}
|
|
276
278
|
};
|
|
277
279
|
|
|
@@ -289,7 +291,9 @@ export const git_push = async (
|
|
|
289
291
|
if (set_upstream) args.push('-u');
|
|
290
292
|
const result = await spawn('git', args, options);
|
|
291
293
|
if (!result.ok) {
|
|
292
|
-
throw Error(
|
|
294
|
+
throw Error(
|
|
295
|
+
`git_push failed for branch '${final_branch}' with ${spawn_result_to_message(result)}`,
|
|
296
|
+
);
|
|
293
297
|
}
|
|
294
298
|
};
|
|
295
299
|
|
|
@@ -311,7 +315,9 @@ export const git_push_to_create = async (
|
|
|
311
315
|
push_args.push(final_branch);
|
|
312
316
|
const result = await spawn('git', push_args, options);
|
|
313
317
|
if (!result.ok) {
|
|
314
|
-
throw Error(
|
|
318
|
+
throw Error(
|
|
319
|
+
`git_push failed for branch '${final_branch}' with ${spawn_result_to_message(result)}`,
|
|
320
|
+
);
|
|
315
321
|
}
|
|
316
322
|
};
|
|
317
323
|
|
|
@@ -324,7 +330,9 @@ export const git_delete_local_branch = async (
|
|
|
324
330
|
): Promise<void> => {
|
|
325
331
|
const result = await spawn('git', ['branch', '-D', branch], options);
|
|
326
332
|
if (!result.ok) {
|
|
327
|
-
throw Error(
|
|
333
|
+
throw Error(
|
|
334
|
+
`git_delete_local_branch failed for branch '${branch}' with ${spawn_result_to_message(result)}`,
|
|
335
|
+
);
|
|
328
336
|
}
|
|
329
337
|
};
|
|
330
338
|
|
|
@@ -338,7 +346,9 @@ export const git_delete_remote_branch = async (
|
|
|
338
346
|
): Promise<void> => {
|
|
339
347
|
const result = await spawn('git', ['push', origin, ':' + branch], options);
|
|
340
348
|
if (!result.ok) {
|
|
341
|
-
throw Error(
|
|
349
|
+
throw Error(
|
|
350
|
+
`git_delete_remote_branch failed for branch '${branch}' with ${spawn_result_to_message(result)}`,
|
|
351
|
+
);
|
|
342
352
|
}
|
|
343
353
|
};
|
|
344
354
|
|
package/src/lib/path.ts
CHANGED
|
@@ -98,7 +98,7 @@ export const parse_path_pieces = (raw_path: string): Array<PathPiece> => {
|
|
|
98
98
|
* Converts a string into a URL-compatible slug.
|
|
99
99
|
* @param str the string to convert
|
|
100
100
|
* @param map_special_characters if `true`, characters like `ñ` are converted to their ASCII equivalents, runs around 5x faster when disabled
|
|
101
|
-
* @mutates special_char_mappers calls `get_special_char_mappers()` which lazily initializes the module-level array if `map_special_characters` is true
|
|
101
|
+
* @mutates special_char_mappers - calls `get_special_char_mappers()` which lazily initializes the module-level array if `map_special_characters` is true
|
|
102
102
|
*/
|
|
103
103
|
export const slugify = (str: string, map_special_characters = true): string => {
|
|
104
104
|
let s = str.toLowerCase();
|
|
@@ -123,7 +123,7 @@ let special_char_mappers: Array<(s: string) => string> | undefined;
|
|
|
123
123
|
/**
|
|
124
124
|
* Lazily constructs `special_char_mappers` which
|
|
125
125
|
* converts special characters to their ASCII equivalents.
|
|
126
|
-
* @mutates special_char_mappers pushes mapper functions into module-level array on first call
|
|
126
|
+
* @mutates special_char_mappers - pushes mapper functions into module-level array on first call
|
|
127
127
|
*/
|
|
128
128
|
const get_special_char_mappers = (): Array<(s: string) => string> => {
|
|
129
129
|
if (special_char_mappers) return special_char_mappers;
|
package/src/lib/print.ts
CHANGED
|
@@ -7,7 +7,7 @@ export let st: typeof styleText = (_, v) => v;
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Configures the module-level styling function for colored output.
|
|
10
|
-
* @mutates st assigns the module-level `st` variable
|
|
10
|
+
* @mutates st - assigns the module-level `st` variable
|
|
11
11
|
*/
|
|
12
12
|
export const configure_print_colors = (
|
|
13
13
|
s: typeof styleText | null | undefined,
|