@fuzdev/fuz_util 0.48.0 → 0.48.2
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/process.d.ts +42 -1
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +46 -2
- package/package.json +2 -2
- package/src/lib/process.ts +67 -2
package/dist/process.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type SpawnOptions, type ChildProcess } from 'node:child_process';
|
|
1
|
+
import { spawn as node_spawn_child_process, type SpawnOptions, type ChildProcess } from 'node:child_process';
|
|
2
2
|
/**
|
|
3
3
|
* Spawn failed before the process could run.
|
|
4
4
|
*
|
|
@@ -64,6 +64,10 @@ export interface SpawnProcessOptions extends SpawnOptions {
|
|
|
64
64
|
* Sends SIGTERM when exceeded. A value of 0 triggers immediate SIGTERM.
|
|
65
65
|
*/
|
|
66
66
|
timeout_ms?: number;
|
|
67
|
+
/**
|
|
68
|
+
* Custom spawn function for testing. Defaults to `node:child_process` spawn.
|
|
69
|
+
*/
|
|
70
|
+
spawn_child_process?: typeof node_spawn_child_process;
|
|
67
71
|
}
|
|
68
72
|
/**
|
|
69
73
|
* Options for killing processes.
|
|
@@ -80,6 +84,16 @@ export interface DespawnOptions {
|
|
|
80
84
|
*/
|
|
81
85
|
timeout_ms?: number;
|
|
82
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Result of spawning a detached process.
|
|
89
|
+
*/
|
|
90
|
+
export type SpawnDetachedResult = {
|
|
91
|
+
ok: true;
|
|
92
|
+
child: ChildProcess;
|
|
93
|
+
} | {
|
|
94
|
+
ok: false;
|
|
95
|
+
message: string;
|
|
96
|
+
};
|
|
83
97
|
/**
|
|
84
98
|
* Handle for a spawned process with access to the child and completion promise.
|
|
85
99
|
*/
|
|
@@ -245,6 +259,33 @@ export declare const despawn_all: (options?: DespawnOptions) => Promise<Array<Sp
|
|
|
245
259
|
* @see ProcessRegistry.attach_error_handler
|
|
246
260
|
*/
|
|
247
261
|
export declare const attach_process_error_handler: (options?: Parameters<ProcessRegistry["attach_error_handler"]>[0]) => (() => void);
|
|
262
|
+
/**
|
|
263
|
+
* Spawns a detached process that continues after parent exits.
|
|
264
|
+
*
|
|
265
|
+
* Unlike other spawn functions, this is NOT tracked in any ProcessRegistry.
|
|
266
|
+
* The spawned process is meant to outlive the parent (e.g., daemon processes).
|
|
267
|
+
*
|
|
268
|
+
* @param command - The command to run
|
|
269
|
+
* @param args - Arguments to pass to the command
|
|
270
|
+
* @param options - Spawn options (use `stdio` to redirect output to file descriptors)
|
|
271
|
+
* @returns Result with pid on success, or error message on failure
|
|
272
|
+
*
|
|
273
|
+
* @example
|
|
274
|
+
* ```ts
|
|
275
|
+
* // Simple detached process
|
|
276
|
+
* const result = spawn_detached('node', ['daemon.js'], {cwd: '/app'});
|
|
277
|
+
*
|
|
278
|
+
* // With log file (caller handles file opening)
|
|
279
|
+
* import {openSync, closeSync} from 'node:fs';
|
|
280
|
+
* const log_fd = openSync('/var/log/daemon.log', 'a');
|
|
281
|
+
* const result = spawn_detached('node', ['daemon.js'], {
|
|
282
|
+
* cwd: '/app',
|
|
283
|
+
* stdio: ['ignore', log_fd, log_fd],
|
|
284
|
+
* });
|
|
285
|
+
* closeSync(log_fd);
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
export declare const spawn_detached: (command: string, args?: ReadonlyArray<string>, options?: SpawnOptions) => SpawnDetachedResult;
|
|
248
289
|
/**
|
|
249
290
|
* Formats a child process for display.
|
|
250
291
|
*
|
package/dist/process.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/process.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/process.ts"],"names":[],"mappings":"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"}
|
package/dist/process.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { spawn as
|
|
1
|
+
import { spawn as node_spawn_child_process, } from 'node:child_process';
|
|
2
2
|
import { styleText as st } from 'node:util';
|
|
3
3
|
import { Logger } from './log.js';
|
|
4
4
|
import { print_error, print_key_value } from './print.js';
|
|
@@ -117,7 +117,7 @@ export class ProcessRegistry {
|
|
|
117
117
|
* @returns Handle with `child` process and `closed` promise
|
|
118
118
|
*/
|
|
119
119
|
spawn(command, args = [], options) {
|
|
120
|
-
const { signal, timeout_ms, ...spawn_options } = options ?? {};
|
|
120
|
+
const { signal, timeout_ms, spawn_child_process = node_spawn_child_process, ...spawn_options } = options ?? {};
|
|
121
121
|
validate_timeout_ms(timeout_ms);
|
|
122
122
|
const child = spawn_child_process(command, args, { stdio: 'inherit', ...spawn_options });
|
|
123
123
|
this.processes.add(child);
|
|
@@ -351,6 +351,50 @@ export const despawn_all = (options) => process_registry_default.despawn_all(opt
|
|
|
351
351
|
* @see ProcessRegistry.attach_error_handler
|
|
352
352
|
*/
|
|
353
353
|
export const attach_process_error_handler = (options) => process_registry_default.attach_error_handler(options);
|
|
354
|
+
/**
|
|
355
|
+
* Spawns a detached process that continues after parent exits.
|
|
356
|
+
*
|
|
357
|
+
* Unlike other spawn functions, this is NOT tracked in any ProcessRegistry.
|
|
358
|
+
* The spawned process is meant to outlive the parent (e.g., daemon processes).
|
|
359
|
+
*
|
|
360
|
+
* @param command - The command to run
|
|
361
|
+
* @param args - Arguments to pass to the command
|
|
362
|
+
* @param options - Spawn options (use `stdio` to redirect output to file descriptors)
|
|
363
|
+
* @returns Result with pid on success, or error message on failure
|
|
364
|
+
*
|
|
365
|
+
* @example
|
|
366
|
+
* ```ts
|
|
367
|
+
* // Simple detached process
|
|
368
|
+
* const result = spawn_detached('node', ['daemon.js'], {cwd: '/app'});
|
|
369
|
+
*
|
|
370
|
+
* // With log file (caller handles file opening)
|
|
371
|
+
* import {openSync, closeSync} from 'node:fs';
|
|
372
|
+
* const log_fd = openSync('/var/log/daemon.log', 'a');
|
|
373
|
+
* const result = spawn_detached('node', ['daemon.js'], {
|
|
374
|
+
* cwd: '/app',
|
|
375
|
+
* stdio: ['ignore', log_fd, log_fd],
|
|
376
|
+
* });
|
|
377
|
+
* closeSync(log_fd);
|
|
378
|
+
* ```
|
|
379
|
+
*/
|
|
380
|
+
export const spawn_detached = (command, args = [], options) => {
|
|
381
|
+
try {
|
|
382
|
+
const child = node_spawn_child_process(command, args, {
|
|
383
|
+
stdio: 'ignore',
|
|
384
|
+
...options,
|
|
385
|
+
detached: true,
|
|
386
|
+
});
|
|
387
|
+
// Allow parent to exit independently
|
|
388
|
+
child.unref();
|
|
389
|
+
if (child.pid === undefined) {
|
|
390
|
+
return { ok: false, message: 'Failed to get child PID' };
|
|
391
|
+
}
|
|
392
|
+
return { ok: true, child };
|
|
393
|
+
}
|
|
394
|
+
catch (error) {
|
|
395
|
+
return { ok: false, message: error instanceof Error ? error.message : String(error) };
|
|
396
|
+
}
|
|
397
|
+
};
|
|
354
398
|
//
|
|
355
399
|
// Formatting Utilities
|
|
356
400
|
//
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fuzdev/fuz_util",
|
|
3
|
-
"version": "0.48.
|
|
3
|
+
"version": "0.48.2",
|
|
4
4
|
"description": "utility belt for JS",
|
|
5
5
|
"glyph": "🦕",
|
|
6
6
|
"logo": "logo.svg",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"@fuzdev/fuz_css": "^0.44.1",
|
|
66
66
|
"@fuzdev/fuz_ui": "^0.179.0",
|
|
67
67
|
"@ryanatkn/eslint-config": "^0.9.0",
|
|
68
|
-
"@ryanatkn/gro": "^0.
|
|
68
|
+
"@ryanatkn/gro": "^0.189.3",
|
|
69
69
|
"@sveltejs/adapter-static": "^3.0.10",
|
|
70
70
|
"@sveltejs/kit": "^2.50.1",
|
|
71
71
|
"@sveltejs/package": "^2.5.7",
|
package/src/lib/process.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
spawn as
|
|
2
|
+
spawn as node_spawn_child_process,
|
|
3
3
|
type SpawnOptions,
|
|
4
4
|
type ChildProcess,
|
|
5
5
|
} from 'node:child_process';
|
|
@@ -98,6 +98,10 @@ export interface SpawnProcessOptions extends SpawnOptions {
|
|
|
98
98
|
* Sends SIGTERM when exceeded. A value of 0 triggers immediate SIGTERM.
|
|
99
99
|
*/
|
|
100
100
|
timeout_ms?: number;
|
|
101
|
+
/**
|
|
102
|
+
* Custom spawn function for testing. Defaults to `node:child_process` spawn.
|
|
103
|
+
*/
|
|
104
|
+
spawn_child_process?: typeof node_spawn_child_process;
|
|
101
105
|
}
|
|
102
106
|
|
|
103
107
|
/**
|
|
@@ -116,6 +120,11 @@ export interface DespawnOptions {
|
|
|
116
120
|
timeout_ms?: number;
|
|
117
121
|
}
|
|
118
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Result of spawning a detached process.
|
|
125
|
+
*/
|
|
126
|
+
export type SpawnDetachedResult = {ok: true; child: ChildProcess} | {ok: false; message: string};
|
|
127
|
+
|
|
119
128
|
//
|
|
120
129
|
// Process Handle Types
|
|
121
130
|
//
|
|
@@ -251,7 +260,12 @@ export class ProcessRegistry {
|
|
|
251
260
|
args: ReadonlyArray<string> = [],
|
|
252
261
|
options?: SpawnProcessOptions,
|
|
253
262
|
): SpawnedProcess {
|
|
254
|
-
const {
|
|
263
|
+
const {
|
|
264
|
+
signal,
|
|
265
|
+
timeout_ms,
|
|
266
|
+
spawn_child_process = node_spawn_child_process,
|
|
267
|
+
...spawn_options
|
|
268
|
+
} = options ?? {};
|
|
255
269
|
validate_timeout_ms(timeout_ms);
|
|
256
270
|
const child = spawn_child_process(command, args, {stdio: 'inherit', ...spawn_options});
|
|
257
271
|
|
|
@@ -544,6 +558,57 @@ export const attach_process_error_handler = (
|
|
|
544
558
|
options?: Parameters<ProcessRegistry['attach_error_handler']>[0],
|
|
545
559
|
): (() => void) => process_registry_default.attach_error_handler(options);
|
|
546
560
|
|
|
561
|
+
/**
|
|
562
|
+
* Spawns a detached process that continues after parent exits.
|
|
563
|
+
*
|
|
564
|
+
* Unlike other spawn functions, this is NOT tracked in any ProcessRegistry.
|
|
565
|
+
* The spawned process is meant to outlive the parent (e.g., daemon processes).
|
|
566
|
+
*
|
|
567
|
+
* @param command - The command to run
|
|
568
|
+
* @param args - Arguments to pass to the command
|
|
569
|
+
* @param options - Spawn options (use `stdio` to redirect output to file descriptors)
|
|
570
|
+
* @returns Result with pid on success, or error message on failure
|
|
571
|
+
*
|
|
572
|
+
* @example
|
|
573
|
+
* ```ts
|
|
574
|
+
* // Simple detached process
|
|
575
|
+
* const result = spawn_detached('node', ['daemon.js'], {cwd: '/app'});
|
|
576
|
+
*
|
|
577
|
+
* // With log file (caller handles file opening)
|
|
578
|
+
* import {openSync, closeSync} from 'node:fs';
|
|
579
|
+
* const log_fd = openSync('/var/log/daemon.log', 'a');
|
|
580
|
+
* const result = spawn_detached('node', ['daemon.js'], {
|
|
581
|
+
* cwd: '/app',
|
|
582
|
+
* stdio: ['ignore', log_fd, log_fd],
|
|
583
|
+
* });
|
|
584
|
+
* closeSync(log_fd);
|
|
585
|
+
* ```
|
|
586
|
+
*/
|
|
587
|
+
export const spawn_detached = (
|
|
588
|
+
command: string,
|
|
589
|
+
args: ReadonlyArray<string> = [],
|
|
590
|
+
options?: SpawnOptions,
|
|
591
|
+
): SpawnDetachedResult => {
|
|
592
|
+
try {
|
|
593
|
+
const child = node_spawn_child_process(command, args, {
|
|
594
|
+
stdio: 'ignore',
|
|
595
|
+
...options,
|
|
596
|
+
detached: true,
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
// Allow parent to exit independently
|
|
600
|
+
child.unref();
|
|
601
|
+
|
|
602
|
+
if (child.pid === undefined) {
|
|
603
|
+
return {ok: false, message: 'Failed to get child PID'};
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
return {ok: true, child};
|
|
607
|
+
} catch (error) {
|
|
608
|
+
return {ok: false, message: error instanceof Error ? error.message : String(error)};
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
|
|
547
612
|
//
|
|
548
613
|
// Formatting Utilities
|
|
549
614
|
//
|