Skip to content

procxy / Procxy

Type Alias: Procxy<T, Mode, SupportHandles>

ts
type Procxy<T, Mode, SupportHandles> = { [K in keyof ProcxiableMethods<T, Mode>]: ProcxiableMethods<T, Mode>[K] extends (args: infer A) => infer R ? (args: A) => Promise<Awaited<R>> : never } & ReadonlyProperties<T, Mode> & {
  $process: ChildProcess;
  [asyncDispose]: Promise<void>;
  [dispose]: void;
  $terminate: Promise<void>;
} & SupportHandles extends true ? {
  $sendHandle: Promise<void>;
} : {
} & T extends EventEmitter<infer E> ? E extends Record<string | symbol, any[]> ? {
  off: Procxy<T, Mode, SupportHandles>;
  on: Procxy<T, Mode, SupportHandles>;
  once: Procxy<T, Mode, SupportHandles>;
  removeListener: Procxy<T, Mode, SupportHandles>;
} : {
  off: Procxy<T, Mode, SupportHandles>;
  on: Procxy<T, Mode, SupportHandles>;
  once: Procxy<T, Mode, SupportHandles>;
  removeListener: Procxy<T, Mode, SupportHandles>;
} : T extends EventEmitter ? {
  off: Procxy<T, Mode, SupportHandles>;
  on: Procxy<T, Mode, SupportHandles>;
  once: Procxy<T, Mode, SupportHandles>;
  removeListener: Procxy<T, Mode, SupportHandles>;
} : {
};

Defined in: src/types/procxy.ts:324

Use When Avoid When Pitfalls

The proxy type returned by procxy() — a transparent async mirror of a remote class instance.

Type Declaration

NameTypeDescriptionDefined in
$processChildProcessAccess to the underlying Node.js ChildProcess instance. Use with caution; modifying the process may break Procxy.src/types/procxy.ts:350
[asyncDispose]()() => Promise<void>Asynchronous dispose for await using statements. Awaits full termination of the child process.src/types/procxy.ts:364
[dispose]()() => voidSynchronous dispose for using statements. Initiates termination but does not wait for completion. For guaranteed cleanup, use Symbol.asyncDispose instead.src/types/procxy.ts:357
$terminate()() => Promise<void>Explicitly terminate the child process. Subsequent method calls will fail with ChildCrashedError.src/types/procxy.ts:344

Type Parameters

Type ParameterDefault typeDescription
T-The original class type whose instance runs in the child process
Mode extends SerializationMode"json"Serialization mode: 'json' (default) or 'advanced'
SupportHandles extends booleanfalseLiteral true to add $sendHandle; false (default) to omit it - You need the return type of procxy() for a function parameter or variable annotation - You are building higher-order abstractions over proxied classes and need type-level introspection - You want to constrain a generic to only accept Procxy instances (T extends Procxy<any>) - You expect property reads to reflect live child state — they don't; properties are snapshotted at the time of each read call - NEVER check proxy instanceof MyClass — the proxy is a plain object; instanceof will always be false - NEVER destructure methods off the proxy (const { add } = proxy) — the IPC context is lost and calls will throw - NEVER call $terminate() and then await another method — the child is gone; the call throws ChildCrashedError

Remarks

Procxy<T> transforms T for cross-process use:

Methods: Every method of T whose parameters and return value are serializable under Mode is included, with its return type wrapped in Promise. Methods with non-serializable signatures are silently omitted from the proxy type (TypeScript will report a type error if you try to call them). Async methods are flattened — Promise<Promise<X>> becomes Promise<X> via Awaited<R>.

Properties: Non-method properties that are serializable are included as readonly. They reflect the value the child had at last read; they are not live references. Setting a property on the proxy has no effect on the child — use a method for that.

Lifecycle ($ prefix): Four lifecycle members are always present regardless of T:

  • $terminate() — sends SIGTERM to the child and waits for it to exit
  • $process — the raw ChildProcess handle; inspect pid, exitCode, kill() etc.
  • [Symbol.dispose]() — synchronous dispose for using (initiates but does not await termination)
  • [Symbol.asyncDispose]() — async dispose for await using (awaits full shutdown)

EventEmitter: When T extends EventEmitter<E>, the proxy gains typed on, once, off, and removeListener methods. Events are forwarded over IPC from child to parent. Only events whose listener parameters are JSON-serializable are forwarded; events with Function parameters are filtered out at the type level. .emit() is not available on the proxy — events originate in the child only.

Handle passing (SupportHandles extends true): When enabled, a $sendHandle(handle, id?) method is added. The handle (Socket, Server, dgram.Socket, or fd) is transferred to the child and must not be used in the parent after the call. Full support on Unix; limited on Windows.

Examples

typescript
import { procxy, type Procxy } from 'procxy';
import { Calculator } from './calculator.js';

// Explicit type annotation
let calc: Procxy<Calculator>;
calc = await procxy(Calculator);
const result = await calc.add(1, 2); // Promise<number>
await calc.$terminate();
typescript
// await using for automatic cleanup
import { procxy } from 'procxy';
import { Calculator } from './calculator.js';

await using calc = await procxy(Calculator);
const sum = await calc.add(3, 4); // 7
// calc.$terminate() is called automatically here
typescript
// Advanced mode with Buffer support
import { procxy } from 'procxy';
import { ImageResizer } from './image-resizer.js';

await using resizer = await procxy(
  ImageResizer,
  './image-resizer.js',
  { serialization: 'advanced' } as const
);
const thumbnail: Buffer = await resizer.resize(sourceBuffer, 200, 200);

See

Released under the MIT License.