@gjsify/child_process 0.36.0 → 0.37.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.
Files changed (2) hide show
  1. package/lib/types/index.d.ts +35 -107
  2. package/package.json +7 -7
@@ -27,12 +27,8 @@ export interface ExecOptions {
27
27
  uid?: number;
28
28
  gid?: number;
29
29
  windowsHide?: boolean;
30
- /**
31
- * Allows aborting the child process via an `AbortController`. When the
32
- * signal fires, the child is killed with `killSignal` (default `SIGTERM`)
33
- * and the registered callback receives an `Error` with `name: 'AbortError'`.
34
- * Reference: https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback
35
- */
30
+ /** On abort the child is killed with `killSignal` (default `SIGTERM`) and the
31
+ * callback receives an `Error` with `name: 'AbortError'`. */
36
32
  signal?: AbortSignal;
37
33
  }
38
34
  export interface ExecSyncOptions {
@@ -61,42 +57,25 @@ export interface SpawnOptions {
61
57
  uid?: number;
62
58
  gid?: number;
63
59
  /**
64
- * Override what the child process sees as `argv[0]`.
65
- *
66
- * `Gio.SubprocessLauncher` does not expose `set_child_setup` to GIR, so on
67
- * POSIX this is implemented by wrapping the spawn through a shell's
68
- * `exec -a "$0" "$@"`. Not expressible on Windows — throws there
69
- * (`ERR_UNSUPPORTED_OPERATION`).
60
+ * `Gio.SubprocessLauncher` hides `set_child_setup` from GIR, so on POSIX
61
+ * argv[0] is overridden by wrapping the spawn in a shell's
62
+ * `exec -a "$0" "$@"`. Inexpressible on Windows — throws
63
+ * `ERR_UNSUPPORTED_OPERATION` there.
70
64
  */
71
65
  argv0?: string;
72
66
  /**
73
- * Spawn the child as the leader of a new session/process group so it
74
- * survives the parent exiting.
75
- *
76
- * POSIX: uses `setsid(1)` resolved from PATH. When no `setsid` binary
77
- * exists (stock macOS, Windows) the child is still spawned and still
78
- * outlives the parent, but is not promoted to a session leader — see the
79
- * package README for the exact per-platform contract.
67
+ * Leader of a new session/process group, via `setsid(1)` from PATH. With no
68
+ * `setsid` binary (stock macOS, Windows) the child still spawns and still
69
+ * outlives the parent, it is just not promoted to session leader.
80
70
  */
81
71
  detached?: boolean;
82
- /**
83
- * Accepted and ignored on every platform: `Gio.SubprocessLauncher` exposes
84
- * no `CreateProcess` creation flags, so the console-window suppression
85
- * Node performs on Windows is unreachable from GIR.
86
- */
72
+ /** Accepted and ignored everywhere: GIR exposes no `CreateProcess` creation flags. */
87
73
  windowsHide?: boolean;
88
- /**
89
- * Accepted and ignored on every platform: GLib always builds the Windows
90
- * command line itself (`protect_argv()`), so its argument quoting cannot
91
- * be bypassed the way libuv's can.
92
- */
74
+ /** Accepted and ignored everywhere: GLib builds the Windows command line itself
75
+ * (`protect_argv()`), so its quoting cannot be bypassed as libuv's can. */
93
76
  windowsVerbatimArguments?: boolean;
94
- /**
95
- * Allows aborting the child process via an `AbortController`. When the
96
- * signal fires, the child is killed with `killSignal` (default `SIGTERM`)
97
- * and an `error` event with `name: 'AbortError'` is emitted.
98
- * Reference: https://nodejs.org/api/child_process.html#child_processspawncommand-args-options
99
- */
77
+ /** On abort the child is killed with `killSignal` (default `SIGTERM`) and an
78
+ * `error` event with `name: 'AbortError'` is emitted. */
100
79
  signal?: AbortSignal;
101
80
  }
102
81
  export interface SpawnSyncResult {
@@ -108,9 +87,6 @@ export interface SpawnSyncResult {
108
87
  signal: string | null;
109
88
  error?: Error;
110
89
  }
111
- /**
112
- * ChildProcess — EventEmitter wrapping Gio.Subprocess.
113
- */
114
90
  export declare class ChildProcess extends EventEmitter {
115
91
  pid?: number;
116
92
  exitCode: number | null;
@@ -121,42 +97,26 @@ export declare class ChildProcess extends EventEmitter {
121
97
  stdout: Readable | null;
122
98
  stderr: Readable | null;
123
99
  /**
124
- * Node-compatible `stdio` tuple — `[stdin, stdout, stderr, ...extraFds]`.
125
- * Index 0/1/2 mirror the named streams above. Slots 3+ are reserved for
126
- * `options.stdio = ['pipe', 'pipe', 'pipe', 'pipe']` extra fds, which we
127
- * don't surface yet — `null` placeholders match Node's shape when extras
128
- * weren't requested. Consumers like execa iterate this array (e.g. to
129
- * dispose streams on subprocess exit), so the property MUST exist even
130
- * when nothing was piped.
100
+ * `[stdin, stdout, stderr]` only — extra fds from
101
+ * `options.stdio = [..., 'pipe']` are not surfaced, so the tuple never grows
102
+ * past index 2. Must exist even when nothing was piped: execa iterates it to
103
+ * dispose streams on subprocess exit.
131
104
  */
132
105
  get stdio(): Array<Writable | Readable | null>;
133
106
  private _subprocess;
134
107
  /**
135
- * @internal Adopt the underlying Gio.Subprocess.
136
- *
137
- * `pid` is supplied by the caller (`_spawnSubprocess`) rather than read
138
- * here via `proc.get_identifier()`, because that accessor is RACY for an
139
- * instant-exit child: `g_subprocess_get_identifier()` returns the pid only
140
- * while `subprocess->pid != 0`, and GSubprocess's child-watch (running on
141
- * the GLib *worker thread*, not the main context — see
142
- * `g_subprocess_exited` in glib's `gio/gsubprocess.c`) sets `pid = 0` the
143
- * instant it reaps the child. For a fast child like `echo`, that reap can
144
- * win the race against any synchronous JS read, leaving `get_identifier()`
145
- * permanently null. Node guarantees `cp.pid` is a positive integer
146
- * synchronously, so we capture the pid at spawn time — the one moment it
147
- * is provably still alive — and hand it in here. See
148
- * `_capturePidAtSpawn` / `_spawnSubprocess`.
108
+ * @internal The caller passes `pid` in rather than letting us read
109
+ * `proc.get_identifier()`, which is racy: GSubprocess's child-watch runs on
110
+ * the GLib worker thread and nulls the identifier the instant it reaps, so a
111
+ * fast child like `echo` can beat any synchronous JS read and leave the pid
112
+ * permanently unreadable. Node promises `cp.pid` synchronously, so
113
+ * `_capturePidAtSpawn` takes it at spawn time instead.
149
114
  */
150
115
  _setSubprocess(proc: Gio.Subprocess, pid: number): void;
151
116
  /**
152
- * Send a signal to the child process.
153
- *
154
- * Accepts a numeric signal or a POSIX signal NAME (`'SIGTERM'`,
155
- * `'SIGKILL'`, …). Unrecognised names default to SIGTERM the way
156
- * Gio's `send_signal` does. Returns `true` on success / when the
157
- * signal was at least dispatched, `false` if we no longer have a
158
- * subprocess handle (matches Node's "no-op on already-reaped child"
159
- * return shape).
117
+ * Accepts a signal number or POSIX name; an unrecognised name falls back to
118
+ * SIGTERM rather than throwing. `false` when there is no subprocess handle
119
+ * left — Node's "no-op on an already-reaped child" shape.
160
120
  */
161
121
  kill(signal?: string | number): boolean;
162
122
  ref(): this;
@@ -166,58 +126,26 @@ export declare function execSync(command: string, options?: ExecSyncOptions): Bu
166
126
  /**
167
127
  * Execute a command in a shell (async with callback).
168
128
  *
169
- * Supports the full Node option set (per
170
- * `refs/node/lib/child_process.js` and the
171
- * `refs/node-test/parallel/test-child-process-exec-*` tests):
172
- * - `encoding`: `'utf8'` (default), other `BufferEncoding`, `'buffer'`
173
- * or `null` (→ Buffer)
174
- * - `timeout`: kill the child with `killSignal` (default `SIGTERM`)
175
- * after N ms; the callback receives an Error with `killed: true`
176
- * and `signal` set to the kill signal
177
- * - `maxBuffer`: throw `ERR_CHILD_PROCESS_STDIO_MAXBUFFER` when the
178
- * captured stdout/stderr exceeds N bytes (default 1 MiB, matching
179
- * Node's `MAX_BUFFER`); the child is killed and the truncated
180
- * output is returned
181
- * - `signal` (`AbortSignal`): kill the child on abort and surface an
182
- * `AbortError` to the callback
183
- * - `killSignal`: signal used by timeout / abort (default `SIGTERM`)
184
- * - `cwd` / `env` / `shell` / `uid` / `gid` / `argv0` etc. via
185
- * `_spawnSubprocess`
129
+ * Option semantics follow `refs/node/lib/child_process.js` and the
130
+ * `refs/node-test/parallel/test-child-process-exec-*` tests.
186
131
  */
187
132
  declare function _exec(command: string, options?: ExecOptions | ((error: ExecError | null, stdout: string | Buffer, stderr: string | Buffer) => void), callback?: (error: ExecError | null, stdout: string | Buffer, stderr: string | Buffer) => void): ChildProcess;
188
133
  export { _exec as exec };
189
- /**
190
- * Execute a file directly without shell (async).
191
- *
192
- * Shares the timeout / maxBuffer / signal / encoding plumbing with `exec`
193
- * via `_execImpl`. The only structural difference is argv construction
194
- * (no shell wrap).
195
- */
134
+ /** Execute a file directly without shell (async). */
196
135
  export declare function execFile(file: string, args?: string[] | ((error: ExecError | null, stdout: string | Buffer, stderr: string | Buffer) => void), options?: ExecOptions | ((error: ExecError | null, stdout: string | Buffer, stderr: string | Buffer) => void), callback?: (error: ExecError | null, stdout: string | Buffer, stderr: string | Buffer) => void): ChildProcess;
197
136
  /**
198
- * Execute a file directly without shell (sync).
199
- *
200
- * Node's overloads accept `execFileSync(file)`, `execFileSync(file, args)`,
201
- * `execFileSync(file, options)` and `execFileSync(file, args, options)`.
202
- * Match all four — passing options as the 2nd positional must not be
203
- * spread into argv.
137
+ * Execute a file directly without shell (sync). All four Node overloads are
138
+ * accepted, so options as the 2nd positional must not be spread into argv.
204
139
  */
205
140
  export declare function execFileSync(file: string, args?: string[] | ExecSyncOptions, options?: ExecSyncOptions): Buffer | string;
206
141
  /**
207
142
  * Spawn a new process (async, with event-based API).
208
143
  *
209
- * Node accepts both `spawn(command, args, options)` and `spawn(command, options)`
210
- * — the second form omits args. Detect the overload at the boundary so callers
211
- * that pass options as the 2nd positional (e.g. `spawn('sh', { shell: true })`)
212
- * don't get the options object spread into argv.
144
+ * The `spawn(command, options)` overload is detected at the boundary so
145
+ * `spawn('sh', { shell: true })` does not spread the options object into argv.
213
146
  */
214
147
  export declare function spawn(command: string, argsOrOptions?: string[] | SpawnOptions, maybeOptions?: SpawnOptions): ChildProcess;
215
- /**
216
- * Spawn a new process (sync).
217
- *
218
- * Same overload as `spawn`: accepts both `(command, args, options)` and
219
- * `(command, options)`.
220
- */
148
+ /** Spawn a new process (sync). Same overloads as `spawn`. */
221
149
  export declare function spawnSync(command: string, argsOrOptions?: string[] | ExecSyncOptions, maybeOptions?: ExecSyncOptions): SpawnSyncResult;
222
150
  declare const _default: {
223
151
  ChildProcess: typeof ChildProcess;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/child_process",
3
- "version": "0.36.0",
3
+ "version": "0.37.0",
4
4
  "description": "Node.js child_process module for Gjs",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -37,18 +37,18 @@
37
37
  "child_process"
38
38
  ],
39
39
  "devDependencies": {
40
- "@gjsify/cli": "^0.36.0",
41
- "@gjsify/dom-elements": "^0.36.0",
42
- "@gjsify/unit": "^0.36.0",
40
+ "@gjsify/cli": "^0.37.0",
41
+ "@gjsify/dom-elements": "^0.37.0",
42
+ "@gjsify/unit": "^0.37.0",
43
43
  "@types/node": "^25.9.2",
44
44
  "typescript": "^6.0.3"
45
45
  },
46
46
  "dependencies": {
47
47
  "@girs/gio-2.0": "^4.1.0",
48
48
  "@girs/glib-2.0": "^4.1.0",
49
- "@gjsify/buffer": "^0.36.0",
50
- "@gjsify/events": "^0.36.0",
51
- "@gjsify/utils": "^0.36.0"
49
+ "@gjsify/buffer": "^0.37.0",
50
+ "@gjsify/events": "^0.37.0",
51
+ "@gjsify/utils": "^0.37.0"
52
52
  },
53
53
  "gjsify": {
54
54
  "runtimes": {