@gjsify/child_process 0.64.19 → 0.64.21

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/lib/esm/index.js CHANGED
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{communicateWithTimeout as e}from"./communicate.js";import{applyArgv0 as t,detachedPrefix as n,killProcess as r,shellArgv as i}from"./platform/index.js";import a from"@girs/glib-2.0";import o from"@girs/gio-2.0";import{EventEmitter as s}from"node:events";import{Buffer as c}from"node:buffer";import{Readable as l,Writable as u}from"node:stream";import{fileURLToPath as d}from"node:url";import{deferEmit as f,gbytesToUint8Array as p}from"@gjsify/utils";import{acquireMainLoop as m,releaseMainLoop as h,trackedCallback as g}from"@gjsify/utils/main-loop";var GioInputStreamReadable=class extends l{_stream;_cancellable=new o.Cancellable;constructor(e){super(),this._stream=e}_read(e){this._stream.read_bytes_async(Math.max(e,4096),a.PRIORITY_DEFAULT,this._cancellable,g((e,t)=>{try{let e=this._stream.read_bytes_finish(t).get_data();!e||e.length===0?this.push(null):this.push(c.from(e))}catch(e){this._cancellable.is_cancelled()||this.destroy(e)}}))}_destroy(e,t){this._cancellable.cancel(),t(e)}},GioOutputStreamWritable=class extends u{_stream;_cancellable=new o.Cancellable;_closed=!1;constructor(e){super(),this._stream=e}_write(e,t,n){if(this._closed){n(Error(`write after end`));return}let r=typeof e==`string`?c.from(e):e instanceof Uint8Array?e:c.from(e);this._stream.write_bytes_async(new a.Bytes(r),a.PRIORITY_DEFAULT,this._cancellable,g((e,t)=>{try{this._stream.write_bytes_finish(t),n()}catch(e){this._cancellable.is_cancelled()?n():n(e)}}))}_final(e){if(this._closed){e();return}this._closed=!0;try{this._stream.close(null)}catch{}e()}_destroy(e,t){if(this._cancellable.cancel(),!this._closed){this._closed=!0;try{this._stream.close(null)}catch{}}t(e)}};function _gioErrorToNodeError(e,t,n){let r=e??Error(`Unknown spawn error`),i=r,o=r.code,s=r.matches,c=!1;if(typeof s==`function`)try{c=s.call(r,a.SpawnError,a.SpawnError.NOENT)===!0}catch{}if(!c&&o===a.SpawnError.NOENT&&(c=!0),!c&&typeof r.message==`string`&&/No such file or directory|ENOENT|Failed to execute|nicht gefunden|nicht ausgeführt/i.test(r.message)&&(c=!0),c){let e=Error(`spawn ${t} ENOENT`);return e.code=`ENOENT`,e.errno=-2,e.syscall=`spawn ${t}`,e.path=t,e.spawnargs=n.slice(),e}if(r instanceof Error)return i;let l=r,u=typeof l.message==`string`?l.message:String(r),d=Error(u);return(typeof o==`number`||typeof o==`string`)&&(d.code=o),d}const _=new Set;var ChildProcess=class extends s{pid;exitCode=null;signalCode=null;killed=!1;connected=!1;stdin=null;stdout=null;stderr=null;get stdio(){return[this.stdin,this.stdout,this.stderr]}_subprocess=null;_setSubprocess(e,t){this._subprocess=e,t>0&&(this.pid=t)}kill(e){if(!this._subprocess)return!1;try{return r(this._subprocess,e??`SIGTERM`),this.killed=!0,!0}catch{return!1}}_holdsProcess=!1;_closed=!1;_holdProcess(){this.once(`close`,()=>{this._closed=!0,this._dropHold()}),this._acquireHold()}_acquireHold(){this._holdsProcess||this._closed||(this._holdsProcess=!0,m())}_dropHold(){this._holdsProcess&&(this._holdsProcess=!1,setTimeout(h,0))}ref(){return this._acquireHold(),this}unref(){return this._dropHold(),this}};function _normalizeCwd(e){if(e!=null){if(typeof e==`string`)return e;if(typeof e==`object`&&e&&typeof e.href==`string`&&typeof e.protocol==`string`){let t=e;if(t.protocol!==`file:`)throw TypeError(`The URL must be of scheme file:; received '${t.protocol}' for 'options.cwd'`);return d(t)}return e instanceof Uint8Array?new TextDecoder().decode(e):String(e)}}function _encodeEnvValue(e){if(e!==void 0)return`${e}`}function _spawnSubprocess(e,r,i){let a=new o.SubprocessLauncher({flags:r}),s=_normalizeCwd(i?.cwd);if(s!==void 0&&a.set_cwd(s),i?.env){let e=i.env;a.set_environ([]);let t=new Set;for(let n in e){if(t.has(n))continue;t.add(n);let r=_encodeEnvValue(e[n]);r!==void 0&&a.setenv(n,r,!0)}}let c=e;if(i?.argv0!==void 0&&i.argv0!==null){if(typeof i.argv0!=`string`)throw TypeError(`The "options.argv0" property must be of type string. Received type ${typeof i.argv0}`);c=t(i.argv0,e)}if(i?.detached===!0){let e=n();e!==null&&(c=[...e,...c])}let l=a.spawnv(c);return{proc:l,pid:_capturePidAtSpawn(l)}}function _capturePidAtSpawn(e){let t=e.get_identifier();if(t){let e=parseInt(t,10);if(e>0)return e}return 0}function _watchStdioForClose(e){let t=[e.stdout,e.stderr].filter(e=>e!==null);if(t.length===0)return(t,n)=>{e.emit(`exit`,t,n),e.emit(`close`,t,n)};let n=t.length,r=!1,i=null,a=null,closeIfDone=()=>{r&&n===0&&e.emit(`close`,i,a)};for(let e of t){let t=!1,settleOnce=()=>{t||(t=!0,--n,closeIfDone())};e.once(`end`,settleOnce),e.once(`close`,settleOnce)}return(n,o)=>{i=n,a=o,r=!0,e.emit(`exit`,n,o),queueMicrotask(()=>{for(let e of t)e.destroyed||e.readableEnded||e.listenerCount(`data`)>0||e.listenerCount(`readable`)>0||e.resume()}),closeIfDone()}}function _communicateSync(t,n,i,a){if(i<=0){let e=t.communicate(n,null);return{stdout:e[1]??null,stderr:e[2]??null,timedOut:!1}}let o=e(t,n,i,()=>{r(t,a??`SIGTERM`)});if(o.error)throw o.error;return{stdout:o.stdout,stderr:o.stderr,timedOut:o.timedOut}}function _syncTimeoutError(e,t,n,r,i){let a=t?p(t):new Uint8Array,o=n?p(n):new Uint8Array,s=new TextDecoder().decode(o),l=Error(`Command failed: ${e}\n${s}`);return l.code=`ETIMEDOUT`,l.killed=!0,l.signal=typeof i==`string`?i:`SIGTERM`,l.status=null,r===`buffer`||r===null?(l.stdout=c.from(a),l.stderr=c.from(o)):(l.stdout=new TextDecoder().decode(a),l.stderr=s),l}function execSync(e,t){let n=t?.encoding,r=t?.input,s=o.SubprocessFlags.STDOUT_PIPE|o.SubprocessFlags.STDERR_PIPE|(r?o.SubprocessFlags.STDIN_PIPE:o.SubprocessFlags.NONE),l=i(e,t?.shell),u;try{({proc:u}=_spawnSubprocess(l,s,t))}catch(e){throw _gioErrorToNodeError(e,l[0],l.slice(1))}let d=r?new a.Bytes(typeof r==`string`?new TextEncoder().encode(r):r):null,f=t?.timeout&&t.timeout>0?t.timeout:0,{stdout:m,stderr:h,timedOut:g}=_communicateSync(u,d,f,t?.killSignal);if(g)throw _syncTimeoutError(e,m,h,n,t?.killSignal);let _=u.get_exit_status();if(_!==0){let t=h?new TextDecoder().decode(p(h)):``,r=m?new TextDecoder().decode(p(m)):``,i=Error(`Command failed: ${e}\n${t}`);throw i.status=_,n===`buffer`||n===null?(i.stderr=h?c.from(p(h)):c.alloc(0),i.stdout=m?c.from(p(m)):c.alloc(0)):(i.stderr=t,i.stdout=r),i}if(!m)return n===`buffer`||n==null?c.alloc(0):``;let v=p(m);if(n===`buffer`||n==null)return c.from(v);let y=c.isEncoding(n)?n:`utf8`;return c.from(v).toString(y)}function _decodeExecOutput(e,t){let n=e??new Uint8Array;if(t===`buffer`||t===null)return c.from(n);let r=t&&c.isEncoding(t)?t:`utf8`;return c.from(n).toString(r)}function _normalizeKillSignal(e){return e??`SIGTERM`}function _exec(e,t,n){typeof t==`function`&&(n=t,t={});let r=t||{},a=new ChildProcess,s=o.SubprocessFlags.STDOUT_PIPE|o.SubprocessFlags.STDERR_PIPE,c=r.maxBuffer??1024*1024,l=r.timeout&&r.timeout>0?r.timeout:0,u=_normalizeKillSignal(r.killSignal),d=r.signal;return _execImpl(a,i(e,r.shell),s,r,{cmd:e,encoding:r.encoding,maxBuffer:c,timeoutMs:l,killSignal:u,abortSignal:d,callback:n})}function _absorbExecError(){}function _execImpl(e,t,n,i,a){e.on(`error`,_absorbExecError);let o=null,s=!1,c=null,l=null,armTimeout=t=>{a.timeoutMs&&(o=setTimeout(()=>{s=!0;try{r(t,a.killSignal)}catch{}e.killed=!0},a.timeoutMs))},disarmTimeout=()=>{o!==null&&(clearTimeout(o),o=null)},armAbort=t=>{if(!a.abortSignal)return;let fire=()=>{c=Error(`The operation was aborted`),c.name=`AbortError`;try{r(t,a.killSignal)}catch{}e.killed=!0};if(a.abortSignal.aborted){queueMicrotask(fire);return}l=fire,a.abortSignal.addEventListener(`abort`,l,{once:!0})},disarmAbort=()=>{a.abortSignal&&l&&(a.abortSignal.removeEventListener(`abort`,l),l=null)};try{let{proc:r,pid:o}=_spawnSubprocess(t,n,i);e._setSubprocess(r,o),_.add(e),armTimeout(r),armAbort(r);let l=_watchStdioForClose(e);e._holdProcess(),r.communicate_async(null,null,(t,n)=>{disarmTimeout(),disarmAbort(),_.delete(e);try{let[,t,i]=r.communicate_finish(n),o=t?p(t):null,u=i?p(i):null,d=null;a.maxBuffer!==1/0&&o&&o.length>a.maxBuffer&&(o=o.subarray(0,a.maxBuffer),d=RangeError(`stdout maxBuffer length exceeded`),d.code=`ERR_CHILD_PROCESS_STDIO_MAXBUFFER`),!d&&a.maxBuffer!==1/0&&u&&u.length>a.maxBuffer&&(u=u.subarray(0,a.maxBuffer),d=RangeError(`stderr maxBuffer length exceeded`),d.code=`ERR_CHILD_PROCESS_STDIO_MAXBUFFER`);let f=_decodeExecOutput(o,a.encoding),m=_decodeExecOutput(u,a.encoding),h=r.get_if_exited()?r.get_exit_status():null,g=r.get_if_signaled()?typeof a.killSignal==`string`?a.killSignal:`SIGTERM`:null;e.exitCode=h,e.signalCode=g;let _=null;if(c)_=c,_.killed=!0,_.signal=g,_.stdout=f,_.stderr=m,_.cmd=a.cmd;else if(d)_=d,_.killed=e.killed,_.signal=g,_.stdout=f,_.stderr=m,_.cmd=a.cmd;else if(s)_=Error(`Command failed: ${a.cmd}`),_.killed=!0,_.code=null,_.signal=typeof a.killSignal==`string`?a.killSignal:`SIGTERM`,_.stdout=f,_.stderr=m,_.cmd=a.cmd;else if(h!==0&&h!==null){let t=typeof m==`string`?m:m.toString();_=Error(`Command failed: ${a.cmd}\n${t}`),_.code=h,_.killed=e.killed,_.signal=g,_.stdout=f,_.stderr=m,_.cmd=a.cmd}else g&&(_=Error(`Command failed: ${a.cmd}`),_.killed=!0,_.signal=g,_.code=null,_.stdout=f,_.stderr=m,_.cmd=a.cmd);a.callback&&a.callback(_,f,m),l(h,g)}catch(t){let n=t instanceof Error?t:Error(String(t));a.callback&&a.callback(n,``,``),e.emit(`error`,n)}}),queueMicrotask(()=>e.emit(`spawn`))}catch(n){disarmTimeout(),disarmAbort();let r=_gioErrorToNodeError(n,t[0]??``,t.slice(1));setTimeout(()=>{a.callback&&a.callback(r,``,``),e.emit(`error`,r)},0)}return e}function execFile(e,t,n,r){let i=[],a={},s;typeof t==`function`?s=t:Array.isArray(t)?(i=t,typeof n==`function`?s=n:(a=n||{},s=r)):t&&typeof t==`object`&&(a=t,s=typeof n==`function`?n:r);let c=new ChildProcess,l=o.SubprocessFlags.STDOUT_PIPE|o.SubprocessFlags.STDERR_PIPE,u=a.maxBuffer??1024*1024,d=a.timeout&&a.timeout>0?a.timeout:0,f=_normalizeKillSignal(a.killSignal);return _execImpl(c,[e,...i],l,a,{cmd:e,encoding:a.encoding,maxBuffer:u,timeoutMs:d,killSignal:f,abortSignal:a.signal,callback:s})}function definePromisifiedExec(e){Object.defineProperty(e,Symbol.for(`nodejs.util.promisify.custom`),{enumerable:!1,value:(...t)=>{let n,r=new Promise((r,i)=>{let callback=(e,t,n)=>{e===null?r({stdout:t,stderr:n}):(e.stdout=t,e.stderr=n,i(e))};n=e(...t,callback)});return r.child=n,r}})}definePromisifiedExec(_exec),definePromisifiedExec(execFile);function execFileSync(e,t,n){let r=[],i;Array.isArray(t)?(r=t,i=n):t&&typeof t==`object`&&(i=t);let s=i?.encoding,l=i?.input,u=o.SubprocessFlags.STDOUT_PIPE|o.SubprocessFlags.STDERR_PIPE|(l?o.SubprocessFlags.STDIN_PIPE:o.SubprocessFlags.NONE),d;try{({proc:d}=_spawnSubprocess([e,...r],u,i))}catch(t){throw _gioErrorToNodeError(t,e,r)}let f=l?new a.Bytes(typeof l==`string`?new TextEncoder().encode(l):l):null,m=i?.timeout&&i.timeout>0?i.timeout:0,{stdout:h,stderr:g,timedOut:_}=_communicateSync(d,f,m,i?.killSignal);if(_)throw _syncTimeoutError(`${e} ${r.join(` `)}`.trim(),h,g,s,i?.killSignal);let v=d.get_exit_status();if(v!==0){let t=g?new TextDecoder().decode(p(g)):``,n=h?new TextDecoder().decode(p(h)):``,i=Error(`Command failed: ${e} ${r.join(` `)}`);throw i.status=v,s===`buffer`||s===null?(i.stderr=g?c.from(p(g)):c.alloc(0),i.stdout=h?c.from(p(h)):c.alloc(0)):(i.stderr=t,i.stdout=n),i}if(!h)return s===`buffer`||s==null?c.alloc(0):``;let y=p(h);if(s===`buffer`||s==null)return c.from(y);let b=c.isEncoding(s)?s:`utf8`;return c.from(y).toString(b)}function spawn(e,t,n){let r,a;if(Array.isArray(t))r=t,a=n;else if(t!=null){if(typeof t!=`object`)throw TypeError(`The "args" argument must be of type object. Received type ${typeof t}`);r=void 0,a=t}else r=void 0,a=t;if(a!=null&&typeof a!=`object`)throw TypeError(`The "options" argument must be of type object. Received type ${typeof a}`);if(a?.argv0!==void 0&&a.argv0!==null&&typeof a.argv0!=`string`)throw TypeError(`The "options.argv0" property must be of type string. Received type ${typeof a.argv0}`);a?.cwd!==void 0&&_normalizeCwd(a.cwd);let s=r||[],c=new ChildProcess,l=a?.shell,u;u=l?i([e,...s].join(` `),l):[e,...s];let d=a?.stdio,p=Array.isArray(d)?[typeof d[0]==`string`?d[0]:`pipe`,typeof d[1]==`string`?d[1]:`pipe`,typeof d[2]==`string`?d[2]:`pipe`]:typeof d==`string`?[d,d,d]:[`pipe`,`pipe`,`pipe`],m=o.SubprocessFlags.NONE;p[0]===`pipe`?m|=o.SubprocessFlags.STDIN_PIPE:p[0]===`inherit`&&(m|=o.SubprocessFlags.STDIN_INHERIT),p[1]===`pipe`&&(m|=o.SubprocessFlags.STDOUT_PIPE),p[1]===`ignore`&&(m|=o.SubprocessFlags.STDOUT_SILENCE),p[2]===`pipe`&&(m|=o.SubprocessFlags.STDERR_PIPE),p[2]===`ignore`&&(m|=o.SubprocessFlags.STDERR_SILENCE);try{let{proc:e,pid:t}=_spawnSubprocess(u,m,a);if(c._setSubprocess(e,t),_.add(c),p[0]===`pipe`){let t=e.get_stdin_pipe();t&&(c.stdin=new GioOutputStreamWritable(t))}let n=e.get_stdout_pipe();n&&(c.stdout=new GioInputStreamReadable(n));let r=e.get_stderr_pipe();r&&(c.stderr=new GioInputStreamReadable(r));let i=_watchStdioForClose(c);c._holdProcess();let o=a?.signal,s=null,emitAbortError=()=>{let e=a?.killSignal??`SIGTERM`;c.kill(e);let t=Error(`The operation was aborted`);t.name=`AbortError`,c.emit(`error`,t)};o&&(o.aborted?queueMicrotask(emitAbortError):(s=emitAbortError,o.addEventListener(`abort`,s,{once:!0})));let l=null;if(a?.timeout&&a.timeout>0){let e=a.killSignal??`SIGTERM`;l=setTimeout(()=>{c.kill(e),l=null},a.timeout)}e.wait_async(null,(t,n)=>{try{e.wait_finish(n);let t=e.get_if_exited()?e.get_exit_status():null,r=null;if(e.get_if_signaled()){let e=a?.killSignal;r=typeof e==`string`?e:`SIGTERM`}c.exitCode=t,c.signalCode=r,l!==null&&(clearTimeout(l),l=null),o&&s&&o.removeEventListener(`abort`,s),c.stdin&&!c.stdin.destroyed&&c.stdin.destroy(),i(t,r)}catch(e){c.emit(`error`,e instanceof Error?e:Error(String(e)))}_.delete(c)}),queueMicrotask(()=>c.emit(`spawn`))}catch(t){f(c,`error`,_gioErrorToNodeError(t,l?e:u[0]??``,l?s:u.slice(1)))}return c}function spawnSync(t,n,s){let l,u;if(Array.isArray(n))l=n,u=s;else if(n!=null){if(typeof n!=`object`)throw TypeError(`The "args" argument must be of type object. Received type ${typeof n}`);l=void 0,u=n}else l=void 0,u=n;if(u!=null&&typeof u!=`object`)throw TypeError(`The "options" argument must be of type object. Received type ${typeof u}`);if(u?.argv0!==void 0&&u.argv0!==null&&typeof u.argv0!=`string`)throw TypeError(`The "options.argv0" property must be of type string. Received type ${typeof u.argv0}`);u?.cwd!==void 0&&_normalizeCwd(u.cwd);let d=l||[],f=u?.shell,m=u?.input,h;h=f?i([t,...d].join(` `),f):[t,...d];let g=u?.timeout&&u.timeout>0?u.timeout:0,_=o.SubprocessFlags.STDOUT_PIPE|o.SubprocessFlags.STDERR_PIPE|(m?o.SubprocessFlags.STDIN_PIPE:o.SubprocessFlags.NONE),v=m;if(v!=null&&typeof v!=`string`&&!(v instanceof Uint8Array)&&!(v instanceof ArrayBuffer)&&!ArrayBuffer.isView(v))throw TypeError(`The "input" property must be of type string, Buffer, TypedArray, or DataView. Received type ${typeof v}`);let y=u?.encoding,b=y===`buffer`||y==null?c.alloc(0):``,x,S=0;try{({proc:x,pid:S}=_spawnSubprocess(h,_,u))}catch(e){let n=f?t:h[0]??``,r=f?d:h.slice(1);return{pid:0,output:[null,b,b],stdout:b,stderr:b,status:null,signal:null,error:_gioErrorToNodeError(e,n,r)}}let C=m?new a.Bytes(typeof m==`string`?new TextEncoder().encode(m):m):null,w,T,E=null,D=!1;try{if(g>0){let t=e(x,C,g,()=>{r(x,u?.killSignal??`SIGTERM`)});if(D=t.timedOut,t.error)throw t.error;w=t.stdout,T=t.stderr}else{let e=x.communicate(C,null);w=e[1]??null,T=e[2]??null}}catch(e){E=e instanceof Error?e:Error(String(e)),w=null,T=null}let O=w?c.from(p(w)):c.alloc(0),k=T?c.from(p(T)):c.alloc(0),decode=e=>{if(y===`buffer`||y==null)return e;let t=c.isEncoding(y)?y:`utf8`;return e.toString(t)},A=decode(O),j=decode(k),M=x.get_if_exited()?x.get_exit_status():null,N=null;if(x.get_if_signaled()){let e=u?.killSignal;N=typeof e==`string`?e:`SIGTERM`}D&&(N=typeof u?.killSignal==`string`?u.killSignal:`SIGTERM`);let P={pid:S,output:[null,A,j],stdout:A,stderr:j,status:D?null:M,signal:N};if(D){let e=Error(`Command failed: ${h.join(` `)}\n${typeof j==`string`?j:j.toString()}`);e.code=`ETIMEDOUT`,e.killed=!0,e.signal=N,P.error=e}else E&&(P.error=E);return P}var v={ChildProcess,exec:_exec,execSync,execFile,execFileSync,spawn,spawnSync};export{ChildProcess,v as default,_exec as exec,execFile,execFileSync,execSync,spawn,spawnSync};
1
+ import"./_virtual/_rolldown/runtime.js";import{communicateWithTimeout as e}from"./communicate.js";import{applyArgv0 as t,detachedPrefix as n,killProcess as r,shellArgv as i}from"./platform/index.js";import a from"@girs/glib-2.0";import o from"@girs/gio-2.0";import{EventEmitter as s}from"node:events";import{Buffer as c}from"node:buffer";import{Readable as l,Writable as u}from"node:stream";import{fileURLToPath as d}from"node:url";import{deferEmit as f,gbytesToUint8Array as p}from"@gjsify/utils";import{acquireMainLoop as m,releaseMainLoop as h,trackedCallback as g}from"@gjsify/utils/main-loop";import{hostExecPath as _}from"@gjsify/utils/core";import{setupNodeChannel as v}from"@gjsify/ipc-channel/node-channel";import{fdChannel as y}from"@gjsify/sab-native";var GioInputStreamReadable=class extends l{_stream;_cancellable=new o.Cancellable;constructor(e){super(),this._stream=e}_read(e){this._stream.read_bytes_async(Math.max(e,4096),a.PRIORITY_DEFAULT,this._cancellable,g((e,t)=>{try{let e=this._stream.read_bytes_finish(t).get_data();!e||e.length===0?this.push(null):this.push(c.from(e))}catch(e){this._cancellable.is_cancelled()||this.destroy(e)}}))}_destroy(e,t){this._cancellable.cancel(),t(e)}},GioOutputStreamWritable=class extends u{_stream;_cancellable=new o.Cancellable;_closed=!1;constructor(e){super(),this._stream=e}_write(e,t,n){if(this._closed){n(Error(`write after end`));return}let r=typeof e==`string`?c.from(e):e instanceof Uint8Array?e:c.from(e);this._stream.write_bytes_async(new a.Bytes(r),a.PRIORITY_DEFAULT,this._cancellable,g((e,t)=>{try{this._stream.write_bytes_finish(t),n()}catch(e){this._cancellable.is_cancelled()?n():n(e)}}))}_final(e){if(this._closed){e();return}this._closed=!0;try{this._stream.close(null)}catch{}e()}_destroy(e,t){if(this._cancellable.cancel(),!this._closed){this._closed=!0;try{this._stream.close(null)}catch{}}t(e)}};function _gioErrorToNodeError(e,t,n){let r=e??Error(`Unknown spawn error`),i=r,o=r.code,s=r.matches,c=!1;if(typeof s==`function`)try{c=s.call(r,a.SpawnError,a.SpawnError.NOENT)===!0}catch{}if(!c&&o===a.SpawnError.NOENT&&(c=!0),!c&&typeof r.message==`string`&&/No such file or directory|ENOENT|Failed to execute|nicht gefunden|nicht ausgeführt/i.test(r.message)&&(c=!0),c){let e=Error(`spawn ${t} ENOENT`);return e.code=`ENOENT`,e.errno=-2,e.syscall=`spawn ${t}`,e.path=t,e.spawnargs=n.slice(),e}if(r instanceof Error)return i;let l=r,u=typeof l.message==`string`?l.message:String(r),d=Error(u);return(typeof o==`number`||typeof o==`string`)&&(d.code=o),d}const b=new Set;var ChildProcess=class extends s{pid;exitCode=null;signalCode=null;killed=!1;connected=!1;stdin=null;stdout=null;stderr=null;get stdio(){return[this.stdin,this.stdout,this.stderr]}_subprocess=null;_setSubprocess(e,t){this._subprocess=e,t>0&&(this.pid=t)}kill(e){if(!this._subprocess)return!1;try{return r(this._subprocess,e??`SIGTERM`),this.killed=!0,!0}catch{return!1}}_holdsProcess=!1;_closed=!1;_holdProcess(){this.once(`close`,()=>{this._closed=!0,this._dropHold()}),this._acquireHold()}_acquireHold(){this._holdsProcess||this._closed||(this._holdsProcess=!0,m())}_dropHold(){this._holdsProcess&&(this._holdsProcess=!1,setTimeout(h,0))}ref(){return this._acquireHold(),this}unref(){return this._dropHold(),this}};function _normalizeCwd(e){if(e!=null){if(typeof e==`string`)return e;if(typeof e==`object`&&e&&typeof e.href==`string`&&typeof e.protocol==`string`){let t=e;if(t.protocol!==`file:`)throw TypeError(`The URL must be of scheme file:; received '${t.protocol}' for 'options.cwd'`);return d(t)}return e instanceof Uint8Array?new TextDecoder().decode(e):String(e)}}function _encodeEnvValue(e){if(e!==void 0)return`${e}`}function _spawnSubprocess(e,r,i){let a=new o.SubprocessLauncher({flags:r}),s=_normalizeCwd(i?.cwd);if(s!==void 0&&a.set_cwd(s),i?.env){let e=i.env;a.set_environ([]);let t=new Set;for(let n in e){if(t.has(n))continue;t.add(n);let r=_encodeEnvValue(e[n]);r!==void 0&&a.setenv(n,r,!0)}}for(let[e,t]of Object.entries(i?.extraEnv??{}))a.setenv(e,t,!0);for(let{source:e,target:t}of i?.takeFds??[])a.take_fd(e,t);let c=e;if(i?.argv0!==void 0&&i.argv0!==null){if(typeof i.argv0!=`string`)throw TypeError(`The "options.argv0" property must be of type string. Received type ${typeof i.argv0}`);c=t(i.argv0,e)}if(i?.detached===!0){let e=n();e!==null&&(c=[...e,...c])}let l;try{l=a.spawnv(c)}finally{i?.takeFds?.length&&queueMicrotask(()=>a.close())}let u=_capturePidAtSpawn(l);return{proc:l,pid:u}}function _capturePidAtSpawn(e){let t=e.get_identifier();if(t){let e=parseInt(t,10);if(e>0)return e}return 0}function _watchStdioForClose(e,t=!1){let n=[e.stdout,e.stderr].filter(e=>e!==null);if(n.length===0&&!t)return(t,n)=>{e.emit(`exit`,t,n),e.emit(`close`,t,n)};let r=n.length+ +!!t,i=!1,a=null,o=null,closeIfDone=()=>{i&&r===0&&e.emit(`close`,a,o)};for(let e of n){let t=!1,settleOnce=()=>{t||(t=!0,--r,closeIfDone())};e.once(`end`,settleOnce),e.once(`close`,settleOnce)}return t&&e.once(`disconnect`,()=>{--r,closeIfDone()}),(t,r)=>{a=t,o=r,i=!0,e.emit(`exit`,t,r),queueMicrotask(()=>{for(let e of n)e.destroyed||e.readableEnded||e.listenerCount(`data`)>0||e.listenerCount(`readable`)>0||e.resume()}),closeIfDone()}}function _communicateSync(t,n,i,a){if(i<=0){let e=t.communicate(n,null);return{stdout:e[1]??null,stderr:e[2]??null,timedOut:!1}}let o=e(t,n,i,()=>{r(t,a??`SIGTERM`)});if(o.error)throw o.error;return{stdout:o.stdout,stderr:o.stderr,timedOut:o.timedOut}}function _syncTimeoutError(e,t,n,r,i){let a=t?p(t):new Uint8Array,o=n?p(n):new Uint8Array,s=new TextDecoder().decode(o),l=Error(`Command failed: ${e}\n${s}`);return l.code=`ETIMEDOUT`,l.killed=!0,l.signal=typeof i==`string`?i:`SIGTERM`,l.status=null,r===`buffer`||r===null?(l.stdout=c.from(a),l.stderr=c.from(o)):(l.stdout=new TextDecoder().decode(a),l.stderr=s),l}function execSync(e,t){let n=t?.encoding,r=t?.input,s=o.SubprocessFlags.STDOUT_PIPE|o.SubprocessFlags.STDERR_PIPE|(r?o.SubprocessFlags.STDIN_PIPE:o.SubprocessFlags.NONE),l=i(e,t?.shell),u;try{({proc:u}=_spawnSubprocess(l,s,t))}catch(e){throw _gioErrorToNodeError(e,l[0],l.slice(1))}let d=r?new a.Bytes(typeof r==`string`?new TextEncoder().encode(r):r):null,f=t?.timeout&&t.timeout>0?t.timeout:0,{stdout:m,stderr:h,timedOut:g}=_communicateSync(u,d,f,t?.killSignal);if(g)throw _syncTimeoutError(e,m,h,n,t?.killSignal);let _=u.get_exit_status();if(_!==0){let t=h?new TextDecoder().decode(p(h)):``,r=m?new TextDecoder().decode(p(m)):``,i=Error(`Command failed: ${e}\n${t}`);throw i.status=_,n===`buffer`||n===null?(i.stderr=h?c.from(p(h)):c.alloc(0),i.stdout=m?c.from(p(m)):c.alloc(0)):(i.stderr=t,i.stdout=r),i}if(!m)return n===`buffer`||n==null?c.alloc(0):``;let v=p(m);if(n===`buffer`||n==null)return c.from(v);let y=c.isEncoding(n)?n:`utf8`;return c.from(v).toString(y)}function _decodeExecOutput(e,t){let n=e??new Uint8Array;if(t===`buffer`||t===null)return c.from(n);let r=t&&c.isEncoding(t)?t:`utf8`;return c.from(n).toString(r)}function _normalizeKillSignal(e){return e??`SIGTERM`}function _exec(e,t,n){typeof t==`function`&&(n=t,t={});let r=t||{},a=new ChildProcess,s=o.SubprocessFlags.STDOUT_PIPE|o.SubprocessFlags.STDERR_PIPE,c=r.maxBuffer??1024*1024,l=r.timeout&&r.timeout>0?r.timeout:0,u=_normalizeKillSignal(r.killSignal),d=r.signal;return _execImpl(a,i(e,r.shell),s,r,{cmd:e,encoding:r.encoding,maxBuffer:c,timeoutMs:l,killSignal:u,abortSignal:d,callback:n})}function _absorbExecError(){}function _execImpl(e,t,n,i,a){e.on(`error`,_absorbExecError);let o=null,s=!1,c=null,l=null,armTimeout=t=>{a.timeoutMs&&(o=setTimeout(()=>{s=!0;try{r(t,a.killSignal)}catch{}e.killed=!0},a.timeoutMs))},disarmTimeout=()=>{o!==null&&(clearTimeout(o),o=null)},armAbort=t=>{if(!a.abortSignal)return;let fire=()=>{c=Error(`The operation was aborted`),c.name=`AbortError`;try{r(t,a.killSignal)}catch{}e.killed=!0};if(a.abortSignal.aborted){queueMicrotask(fire);return}l=fire,a.abortSignal.addEventListener(`abort`,l,{once:!0})},disarmAbort=()=>{a.abortSignal&&l&&(a.abortSignal.removeEventListener(`abort`,l),l=null)};try{let{proc:r,pid:o}=_spawnSubprocess(t,n,i);e._setSubprocess(r,o),b.add(e),armTimeout(r),armAbort(r);let l=_watchStdioForClose(e);e._holdProcess(),r.communicate_async(null,null,(t,n)=>{disarmTimeout(),disarmAbort(),b.delete(e);try{let[,t,i]=r.communicate_finish(n),o=t?p(t):null,u=i?p(i):null,d=null;a.maxBuffer!==1/0&&o&&o.length>a.maxBuffer&&(o=o.subarray(0,a.maxBuffer),d=RangeError(`stdout maxBuffer length exceeded`),d.code=`ERR_CHILD_PROCESS_STDIO_MAXBUFFER`),!d&&a.maxBuffer!==1/0&&u&&u.length>a.maxBuffer&&(u=u.subarray(0,a.maxBuffer),d=RangeError(`stderr maxBuffer length exceeded`),d.code=`ERR_CHILD_PROCESS_STDIO_MAXBUFFER`);let f=_decodeExecOutput(o,a.encoding),m=_decodeExecOutput(u,a.encoding),h=r.get_if_exited()?r.get_exit_status():null,g=r.get_if_signaled()?typeof a.killSignal==`string`?a.killSignal:`SIGTERM`:null;e.exitCode=h,e.signalCode=g;let _=null;if(c)_=c,_.killed=!0,_.signal=g,_.stdout=f,_.stderr=m,_.cmd=a.cmd;else if(d)_=d,_.killed=e.killed,_.signal=g,_.stdout=f,_.stderr=m,_.cmd=a.cmd;else if(s)_=Error(`Command failed: ${a.cmd}`),_.killed=!0,_.code=null,_.signal=typeof a.killSignal==`string`?a.killSignal:`SIGTERM`,_.stdout=f,_.stderr=m,_.cmd=a.cmd;else if(h!==0&&h!==null){let t=typeof m==`string`?m:m.toString();_=Error(`Command failed: ${a.cmd}\n${t}`),_.code=h,_.killed=e.killed,_.signal=g,_.stdout=f,_.stderr=m,_.cmd=a.cmd}else g&&(_=Error(`Command failed: ${a.cmd}`),_.killed=!0,_.signal=g,_.code=null,_.stdout=f,_.stderr=m,_.cmd=a.cmd);a.callback&&a.callback(_,f,m),l(h,g)}catch(t){let n=t instanceof Error?t:Error(String(t));a.callback&&a.callback(n,``,``),e.emit(`error`,n)}}),queueMicrotask(()=>e.emit(`spawn`))}catch(n){disarmTimeout(),disarmAbort();let r=_gioErrorToNodeError(n,t[0]??``,t.slice(1));setTimeout(()=>{a.callback&&a.callback(r,``,``),e.emit(`error`,r)},0)}return e}function execFile(e,t,n,r){let i=[],a={},s;typeof t==`function`?s=t:Array.isArray(t)?(i=t,typeof n==`function`?s=n:(a=n||{},s=r)):t&&typeof t==`object`&&(a=t,s=typeof n==`function`?n:r);let c=new ChildProcess,l=o.SubprocessFlags.STDOUT_PIPE|o.SubprocessFlags.STDERR_PIPE,u=a.maxBuffer??1024*1024,d=a.timeout&&a.timeout>0?a.timeout:0,f=_normalizeKillSignal(a.killSignal);return _execImpl(c,[e,...i],l,a,{cmd:e,encoding:a.encoding,maxBuffer:u,timeoutMs:d,killSignal:f,abortSignal:a.signal,callback:s})}function definePromisifiedExec(e){Object.defineProperty(e,Symbol.for(`nodejs.util.promisify.custom`),{enumerable:!1,value:(...t)=>{let n,r=new Promise((r,i)=>{let callback=(e,t,n)=>{e===null?r({stdout:t,stderr:n}):(e.stdout=t,e.stderr=n,i(e))};n=e(...t,callback)});return r.child=n,r}})}definePromisifiedExec(_exec),definePromisifiedExec(execFile);function execFileSync(e,t,n){let r=[],i;Array.isArray(t)?(r=t,i=n):t&&typeof t==`object`&&(i=t);let s=i?.encoding,l=i?.input,u=o.SubprocessFlags.STDOUT_PIPE|o.SubprocessFlags.STDERR_PIPE|(l?o.SubprocessFlags.STDIN_PIPE:o.SubprocessFlags.NONE),d;try{({proc:d}=_spawnSubprocess([e,...r],u,i))}catch(t){throw _gioErrorToNodeError(t,e,r)}let f=l?new a.Bytes(typeof l==`string`?new TextEncoder().encode(l):l):null,m=i?.timeout&&i.timeout>0?i.timeout:0,{stdout:h,stderr:g,timedOut:_}=_communicateSync(d,f,m,i?.killSignal);if(_)throw _syncTimeoutError(`${e} ${r.join(` `)}`.trim(),h,g,s,i?.killSignal);let v=d.get_exit_status();if(v!==0){let t=g?new TextDecoder().decode(p(g)):``,n=h?new TextDecoder().decode(p(h)):``,i=Error(`Command failed: ${e} ${r.join(` `)}`);throw i.status=v,s===`buffer`||s===null?(i.stderr=g?c.from(p(g)):c.alloc(0),i.stdout=h?c.from(p(h)):c.alloc(0)):(i.stderr=t,i.stdout=n),i}if(!h)return s===`buffer`||s==null?c.alloc(0):``;let y=p(h);if(s===`buffer`||s==null)return c.from(y);let b=c.isEncoding(s)?s:`utf8`;return c.from(y).toString(b)}function spawn(e,t,n){let r,a;if(Array.isArray(t))r=t,a=n;else if(t!=null){if(typeof t!=`object`)throw TypeError(`The "args" argument must be of type object. Received type ${typeof t}`);r=void 0,a=t}else r=void 0,a=t;if(a!=null&&typeof a!=`object`)throw TypeError(`The "options" argument must be of type object. Received type ${typeof a}`);if(a?.argv0!==void 0&&a.argv0!==null&&typeof a.argv0!=`string`)throw TypeError(`The "options.argv0" property must be of type string. Received type ${typeof a.argv0}`);a?.cwd!==void 0&&_normalizeCwd(a.cwd);let s=r||[],c=new ChildProcess,l=a?.shell,u;u=l?i([e,...s].join(` `),l):[e,...s];let d=a?.stdio,p=Array.isArray(d)?[typeof d[0]==`string`?d[0]:`pipe`,typeof d[1]==`string`?d[1]:`pipe`,typeof d[2]==`string`?d[2]:`pipe`]:typeof d==`string`?[d,d,d]:[`pipe`,`pipe`,`pipe`],m=o.SubprocessFlags.NONE;p[0]===`pipe`?m|=o.SubprocessFlags.STDIN_PIPE:p[0]===`inherit`&&(m|=o.SubprocessFlags.STDIN_INHERIT),p[1]===`pipe`&&(m|=o.SubprocessFlags.STDOUT_PIPE),p[1]===`ignore`&&(m|=o.SubprocessFlags.STDOUT_SILENCE),p[2]===`pipe`&&(m|=o.SubprocessFlags.STDERR_PIPE),p[2]===`ignore`&&(m|=o.SubprocessFlags.STDERR_SILENCE);let h=_openIpcSlot(d,a?.serialization);try{let{proc:e,pid:t}=_spawnSubprocess(u,m,{...a,takeFds:h?[{source:h.childFd,target:h.slot}]:void 0,extraEnv:h?{NODE_CHANNEL_FD:String(h.slot),NODE_CHANNEL_SERIALIZATION_MODE:`json`}:void 0});if(c._setSubprocess(e,t),b.add(c),h&&v(c,h.parentFd),p[0]===`pipe`){let t=e.get_stdin_pipe();t&&(c.stdin=new GioOutputStreamWritable(t))}let n=e.get_stdout_pipe();n&&(c.stdout=new GioInputStreamReadable(n));let r=e.get_stderr_pipe();r&&(c.stderr=new GioInputStreamReadable(r));let i=_watchStdioForClose(c,h!==null);c._holdProcess();let o=a?.signal,s=null,emitAbortError=()=>{let e=a?.killSignal??`SIGTERM`;c.kill(e);let t=Error(`The operation was aborted`);t.name=`AbortError`,c.emit(`error`,t)};o&&(o.aborted?queueMicrotask(emitAbortError):(s=emitAbortError,o.addEventListener(`abort`,s,{once:!0})));let l=null;if(a?.timeout&&a.timeout>0){let e=a.killSignal??`SIGTERM`;l=setTimeout(()=>{c.kill(e),l=null},a.timeout)}e.wait_async(null,(t,n)=>{try{e.wait_finish(n);let t=e.get_if_exited()?e.get_exit_status():null,r=null;if(e.get_if_signaled()){let e=a?.killSignal;r=typeof e==`string`?e:`SIGTERM`}c.exitCode=t,c.signalCode=r,l!==null&&(clearTimeout(l),l=null),o&&s&&o.removeEventListener(`abort`,s),c.stdin&&!c.stdin.destroyed&&c.stdin.destroy(),i(t,r)}catch(e){c.emit(`error`,e instanceof Error?e:Error(String(e)))}b.delete(c)}),queueMicrotask(()=>c.emit(`spawn`))}catch(t){h&&!c.channel&&y?.closeFd(h.parentFd),f(c,`error`,_gioErrorToNodeError(t,l?e:u[0]??``,l?s:u.slice(1)))}return c}function _codedError(e,t,n){let r=new e(n);return r.code=t,r}function _openIpcSlot(e,t){if(!Array.isArray(e))return null;let n=e.indexOf(`ipc`);if(n===-1)return null;if(e.indexOf(`ipc`,n+1)!==-1)throw _codedError(Error,`ERR_IPC_ONE_PIPE`,`Child process can have only one IPC pipe`);if(n<3)throw _codedError(Error,`ERR_FEATURE_UNAVAILABLE_ON_PLATFORM`,`An 'ipc' channel on stdin, stdout or stderr is not supported under GJS`);if(t!==void 0&&t!==`json`)throw _codedError(Error,`ERR_FEATURE_UNAVAILABLE_ON_PLATFORM`,`serialization: '${t}' is not supported under GJS yet; use 'json'`);let r=y?.makeStreamPair()??null;if(!r)throw _codedError(Error,`ERR_FEATURE_UNAVAILABLE_ON_PLATFORM`,`An 'ipc' channel needs @gjsify/sab-native with make_stream_pair, which this install lacks`);return{slot:n,parentFd:r.parentFd,childFd:r.childFd}}function fork(e,t,n){let r=[],i=n;if(Array.isArray(t))r=t;else if(t!=null){if(typeof t!=`object`)throw TypeError(`The "args" argument must be an instance of Array. Received type ${typeof t}`);i=t}if(i!=null&&typeof i!=`object`)throw TypeError(`The "options" argument must be of type object. Received type ${typeof i}`);let a=typeof e==`string`?e:_normalizeCwd(e);if(typeof a!=`string`)throw TypeError(`The "modulePath" argument must be of type string. Received type ${typeof e}`);let o={...i,shell:!1},s=!o.execPath,c=o.execPath||_()||globalThis.process?.execPath||`gjs`,l=[...o.execArgv??(s?globalThis.process?.execArgv??[]:[])];s&&!l.includes(`-m`)&&l.push(`-m`);let u=o.stdio;if(typeof u==`string`)u=[u,u,u,`ipc`];else if(!Array.isArray(u)){let e=o.silent?`pipe`:`inherit`;u=[e,e,e,`ipc`]}else if(!u.includes(`ipc`))throw _codedError(Error,`ERR_CHILD_PROCESS_IPC_REQUIRED`,`Forked processes must have an IPC channel, missing value 'ipc' in options.stdio`);return spawn(c,[...l,a,...r],{...o,stdio:u})}function spawnSync(t,n,s){let l,u;if(Array.isArray(n))l=n,u=s;else if(n!=null){if(typeof n!=`object`)throw TypeError(`The "args" argument must be of type object. Received type ${typeof n}`);l=void 0,u=n}else l=void 0,u=n;if(u!=null&&typeof u!=`object`)throw TypeError(`The "options" argument must be of type object. Received type ${typeof u}`);if(u?.argv0!==void 0&&u.argv0!==null&&typeof u.argv0!=`string`)throw TypeError(`The "options.argv0" property must be of type string. Received type ${typeof u.argv0}`);u?.cwd!==void 0&&_normalizeCwd(u.cwd);let d=l||[],f=u?.shell,m=u?.input,h;h=f?i([t,...d].join(` `),f):[t,...d];let g=u?.timeout&&u.timeout>0?u.timeout:0,_=o.SubprocessFlags.STDOUT_PIPE|o.SubprocessFlags.STDERR_PIPE|(m?o.SubprocessFlags.STDIN_PIPE:o.SubprocessFlags.NONE),v=m;if(v!=null&&typeof v!=`string`&&!(v instanceof Uint8Array)&&!(v instanceof ArrayBuffer)&&!ArrayBuffer.isView(v))throw TypeError(`The "input" property must be of type string, Buffer, TypedArray, or DataView. Received type ${typeof v}`);let y=u?.encoding,b=y===`buffer`||y==null?c.alloc(0):``,x,S=0;try{({proc:x,pid:S}=_spawnSubprocess(h,_,u))}catch(e){let n=f?t:h[0]??``,r=f?d:h.slice(1);return{pid:0,output:[null,b,b],stdout:b,stderr:b,status:null,signal:null,error:_gioErrorToNodeError(e,n,r)}}let C=m?new a.Bytes(typeof m==`string`?new TextEncoder().encode(m):m):null,w,T,E=null,D=!1;try{if(g>0){let t=e(x,C,g,()=>{r(x,u?.killSignal??`SIGTERM`)});if(D=t.timedOut,t.error)throw t.error;w=t.stdout,T=t.stderr}else{let e=x.communicate(C,null);w=e[1]??null,T=e[2]??null}}catch(e){E=e instanceof Error?e:Error(String(e)),w=null,T=null}let O=w?c.from(p(w)):c.alloc(0),k=T?c.from(p(T)):c.alloc(0),decode=e=>{if(y===`buffer`||y==null)return e;let t=c.isEncoding(y)?y:`utf8`;return e.toString(t)},A=decode(O),j=decode(k),M=x.get_if_exited()?x.get_exit_status():null,N=null;if(x.get_if_signaled()){let e=u?.killSignal;N=typeof e==`string`?e:`SIGTERM`}D&&(N=typeof u?.killSignal==`string`?u.killSignal:`SIGTERM`);let P={pid:S,output:[null,A,j],stdout:A,stderr:j,status:D?null:M,signal:N};if(D){let e=Error(`Command failed: ${h.join(` `)}\n${typeof j==`string`?j:j.toString()}`);e.code=`ETIMEDOUT`,e.killed=!0,e.signal=N,P.error=e}else E&&(P.error=E);return P}var x={ChildProcess,exec:_exec,execSync,execFile,execFileSync,fork,spawn,spawnSync};export{ChildProcess,x as default,_exec as exec,execFile,execFileSync,execSync,fork,spawn,spawnSync};
@@ -0,0 +1,2 @@
1
+ declare const _default: () => Promise<void>;
2
+ export default _default;
@@ -2,6 +2,7 @@ import Gio from '@girs/gio-2.0';
2
2
  import { EventEmitter } from 'node:events';
3
3
  import { Buffer } from 'node:buffer';
4
4
  import { Readable, Writable } from 'node:stream';
5
+ import { type NodeChannelHandle, type SendCallback } from '@gjsify/ipc-channel/node-channel';
5
6
  interface ExecError extends Error {
6
7
  /** `null` when the child was signalled (timeout kill) — matches Node. */
7
8
  status?: number | null;
@@ -77,6 +78,15 @@ export interface SpawnOptions {
77
78
  /** On abort the child is killed with `killSignal` (default `SIGTERM`) and an
78
79
  * `error` event with `name: 'AbortError'` is emitted. */
79
80
  signal?: AbortSignal;
81
+ /** Only `'json'`, Node's newline-framed wire, so the peer may be Node or GJS. */
82
+ serialization?: 'json' | 'advanced';
83
+ }
84
+ export interface ForkOptions extends SpawnOptions {
85
+ /** Defaults to the running GJS binary, which then gets `-m` to load an ES module. */
86
+ execPath?: string;
87
+ execArgv?: string[];
88
+ /** `stdio: 'pipe'` instead of the default `'inherit'`. */
89
+ silent?: boolean;
80
90
  }
81
91
  export interface SpawnSyncResult {
82
92
  pid: number;
@@ -96,6 +106,10 @@ export declare class ChildProcess extends EventEmitter {
96
106
  stdin: Writable | null;
97
107
  stdout: Readable | null;
98
108
  stderr: Readable | null;
109
+ /** Present only on a child spawned with an `'ipc'` slot, as in Node. */
110
+ send?: (message: unknown, sendHandle?: unknown, options?: unknown, callback?: SendCallback) => boolean;
111
+ disconnect?: () => void;
112
+ channel?: NodeChannelHandle | null;
99
113
  /**
100
114
  * `[stdin, stdout, stderr]` only — extra fds from
101
115
  * `options.stdio = [..., 'pipe']` are not surfaced, so the tuple never grows
@@ -152,6 +166,15 @@ export declare function execFileSync(file: string, args?: string[] | ExecSyncOpt
152
166
  * `spawn('sh', { shell: true })` does not spread the options object into argv.
153
167
  */
154
168
  export declare function spawn(command: string, argsOrOptions?: string[] | SpawnOptions, maybeOptions?: SpawnOptions): ChildProcess;
169
+ /**
170
+ * Run a module in a new process with an IPC channel, as Node's `fork` does:
171
+ * `execPath`, then `execArgv`, the module and `args`, with `stdio` defaulting to
172
+ * `'inherit'` (or `'pipe'` with `silent`) plus `'ipc'` on fd 3.
173
+ *
174
+ * Without an `execPath` the child is the running GJS binary, and `-m` is put
175
+ * in front of the module, because GJS loads an ES module only with it.
176
+ */
177
+ export declare function fork(modulePath: string | URL, argsOrOptions?: string[] | ForkOptions, maybeOptions?: ForkOptions): ChildProcess;
155
178
  /** Spawn a new process (sync). Same overloads as `spawn`. */
156
179
  export declare function spawnSync(command: string, argsOrOptions?: string[] | ExecSyncOptions, maybeOptions?: ExecSyncOptions): SpawnSyncResult;
157
180
  declare const _default: {
@@ -160,6 +183,7 @@ declare const _default: {
160
183
  execSync: typeof execSync;
161
184
  execFile: typeof execFile;
162
185
  execFileSync: typeof execFileSync;
186
+ fork: typeof fork;
163
187
  spawn: typeof spawn;
164
188
  spawnSync: typeof spawnSync;
165
189
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/child_process",
3
- "version": "0.64.19",
3
+ "version": "0.64.21",
4
4
  "description": "Node.js child_process module for Gjs",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -19,14 +19,15 @@
19
19
  "lib"
20
20
  ],
21
21
  "scripts": {
22
- "clear": "gjsify clear lib tsconfig.tsbuildinfo tsconfig.types.tsbuildinfo test.gjs.mjs test.node.mjs",
22
+ "clear": "gjsify clear lib tsconfig.tsbuildinfo tsconfig.types.tsbuildinfo fixtures test.gjs.mjs test.node.mjs",
23
23
  "check": "gjsify tsc --noEmit",
24
24
  "build": "gjsify run build:gjsify && gjsify run build:types",
25
25
  "build:gjsify": "gjsify build --library 'src/**/*.{ts,js}' --exclude 'src/**/*.spec.{mts,ts}' 'src/test.{mts,ts}'",
26
26
  "build:types": "gjsify tsc",
27
27
  "build:test": "gjsify run build:test:gjs && gjsify run build:test:node",
28
- "build:test:gjs": "gjsify build src/test.mts --app gjs --outfile test.gjs.mjs",
29
- "build:test:node": "gjsify build src/test.mts --app node --outfile test.node.mjs",
28
+ "build:test:fixtures": "gjsify build src/fixtures/fork-child.mjs --app gjs --outfile fixtures/fork-child.gjs.mjs && gjsify build src/fixtures/fork-child.mjs --app node --outfile fixtures/fork-child.node.mjs",
29
+ "build:test:gjs": "gjsify run build:test:fixtures && gjsify build src/test.mts --app gjs --outfile test.gjs.mjs",
30
+ "build:test:node": "gjsify run build:test:fixtures && gjsify build src/test.mts --app node --outfile test.node.mjs",
30
31
  "test": "gjsify run build:gjsify && gjsify run build:test && gjsify run test:node && gjsify run test:gjs",
31
32
  "test:gjs": "gjsify run test.gjs.mjs",
32
33
  "test:node": "node test.node.mjs"
@@ -37,18 +38,20 @@
37
38
  "child_process"
38
39
  ],
39
40
  "devDependencies": {
40
- "@gjsify/cli": "^0.64.19",
41
- "@gjsify/dom-elements": "^0.64.19",
42
- "@gjsify/unit": "^0.64.19",
41
+ "@gjsify/cli": "^0.64.21",
42
+ "@gjsify/dom-elements": "^0.64.21",
43
+ "@gjsify/unit": "^0.64.21",
43
44
  "@types/node": "^25.9.2",
44
45
  "typescript": "^6.0.3"
45
46
  },
46
47
  "dependencies": {
47
48
  "@girs/gio-2.0": "5.4.0",
48
49
  "@girs/glib-2.0": "5.4.0",
49
- "@gjsify/buffer": "^0.64.19",
50
- "@gjsify/events": "^0.64.19",
51
- "@gjsify/utils": "^0.64.19"
50
+ "@gjsify/buffer": "^0.64.21",
51
+ "@gjsify/events": "^0.64.21",
52
+ "@gjsify/ipc-channel": "^0.64.21",
53
+ "@gjsify/sab-native": "^0.64.21",
54
+ "@gjsify/utils": "^0.64.21"
52
55
  },
53
56
  "gjsify": {
54
57
  "runtimes": {