Interface: IsolatedChildLike
Defined in: src/batteries/isolation/child_process/transport.ts:102
The minimal Node ChildProcess-shaped duck this transport drives. Structurally satisfied by BOTH:
- the object returned by
node:child_process's ownfork(), and - an
execa≥9 subprocess spawned with{ ipc: true }— empirically verified: execa'sSubprocess<OptionsType>type isOmit<ChildProcess, keyof ExecaCustomSubprocess<OptionsType>> & ExecaCustomSubprocess<OptionsType>, i.e. it keeps the classic NodeChildProcessEventEmitter surface (.send(),.on('message'|'exit'|'error', ...),.kill(),.connected) alongside execa's own promise-basedsendMessage()/getEachMessage()API. This transport only ever uses the classic EventEmitter surface, so an execa{ ipc: true }subprocess satisfies this duck WITHOUT any adapter.
execa's channel, like node's own fork(), defaults to JSON-style serialization unless the subprocess is spawned with serialization: 'advanced' (execa forwards that option straight to the underlying child_process.fork() it uses internally for ipc: true) — the same "pin advanced for exotic-value fidelity" requirement documented on ForkIsolatedOptions applies whether the child came from this module's own fork() call or from a caller-supplied ChildResolver.
Remarks
A ChildResolver must NOT itself attach a 'message' listener to the child it returns before handing it back to this transport (e.g. for logging). Node buffers a child's message/ipc events until the FIRST listener is attached, then flushes the whole buffer to that one listener exactly once — a resolver-side listener attached first (even just to log) permanently steals the buffered ready envelope from connect()'s own listener, which then waits out readyTimeoutMs for a ready that already came and went. execa's Subprocess additionally proxies raw child events through its own internal debounced message re-emitter (see execa's lib/ipc/forward.js), so this applies to execa subprocesses too — empirically confirmed by instrumenting a resolver with a diagnostic subprocess.on('message', ...) and observing the resulting connection hang.
A ChildResolver that returns an execa { ipc: true } subprocess should attach its own no-op .catch(() => {}) to it before returning. execa's subprocess is ITSELF a promise (via mergePromise) that settles REJECTED on a non-zero exit or termination signal — including the ordinary SIGTERM this transport's terminate() sends on every dispose()/recycle(). Since this transport only ever drives the classic EventEmitter surface (never awaits/.then()s the child itself — see this module's spawnChild remarks for why an unguarded await/return of a thenable child is unsafe in the first place), nothing else ever attaches a rejection handler; without one, a routine terminate() reports as an unhandled promise rejection.
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
connected? | boolean | Whether the IPC channel is currently open. Read once at connect time for a send-before-connect sanity check; not polled thereafter. | src/batteries/isolation/child_process/transport.ts:120 |
Methods
kill()
kill(signal?: number | Signals): boolean | void;Defined in: src/batteries/isolation/child_process/transport.ts:117
Send a termination signal to the child.
Parameters
| Parameter | Type |
|---|---|
signal? | number | Signals |
Returns
boolean | void
off()?
optional off(event: string, fn: (...args: any[]) => void): unknown;Defined in: src/batteries/isolation/child_process/transport.ts:113
Unsubscribe, mirroring .on. Optional — some resolvers may return a duck without it; this transport degrades to leaking the listener rather than throwing (the process is short-lived and torn down on terminate()/recycle() regardless).
Parameters
| Parameter | Type |
|---|---|
event | string |
fn | (...args: any[]) => void |
Returns
unknown
on()
on(event: string, fn: (...args: any[]) => void): unknown;Defined in: src/batteries/isolation/child_process/transport.ts:109
Subscribe to a child lifecycle/IPC event ('message', 'exit', 'error'). Listener param typed any[] to structurally match node's own ChildProcess#on overload set (whose listener signatures are themselves (...args: any[]) => void).
Parameters
| Parameter | Type |
|---|---|
event | string |
fn | (...args: any[]) => void |
Returns
unknown
removeListener()?
optional removeListener(event: string, fn: (...args: any[]) => void): unknown;Defined in: src/batteries/isolation/child_process/transport.ts:115
Alias some ducks expose instead of/alongside off.
Parameters
| Parameter | Type |
|---|---|
event | string |
fn | (...args: any[]) => void |
Returns
unknown
send()?
optional send(msg: unknown): boolean | void;Defined in: src/batteries/isolation/child_process/transport.ts:105
Send a message across the IPC channel. Returns false (or void, depending on the implementation) when the channel is closed/backed-up; this transport does not currently act on that return value.
Parameters
| Parameter | Type |
|---|---|
msg | unknown |
Returns
boolean | void