Skip to content

Introduction

Cross-process communication manager. Responsible for creating, managing, and terminating external child processes (Go/Python/Java backends), with dynamic port allocation and dual-index tracking (pid and name). Includes the Cross class (manager), CrossProcess class (per-process instance), and the cross singleton.

Important

Cross-process APIs are only available in the main process. They cannot be used in child processes (jobs) or renderer processes.

Import

javascript
// CJS
const { cross, Cross, CrossProcess } = require('ee-core/cross');

// ESM
import { cross, Cross, CrossProcess } from 'ee-core/cross';

// Types (CJS / ESM)
import type { CrossRunOptions, CrossProcessOptions, CrossHost, CrossTargetConfig } from 'ee-core/cross';
// or
import type { CrossTargetConfig } from 'ee-core/types';

API

Cross Class

The Cross class is the cross-process manager. It implements the CrossHost interface, providing event notification capability for child processes. Manages processes via children (pid index) and childrenMap (name index) dual indexes, supporting operations by pid or name.


cross.create()

Description: Create and start all cross-process services with enable=true in config. Iterates over config.cross configuration, calling run() for each service with enable=true.

Returns: Promise<void>

Example:

javascript
import { cross } from 'ee-core/cross';
await cross.create();

See also: cross.run()


cross.run(service, opt)

Description: Run the specified cross-process service. Merges config defaults with runtime options, dynamically allocates a port if specified, creates a CrossProcess child process, and registers it in both pid and name indexes. If a duplicate service name exists, appends a pid suffix to avoid conflicts.

Parameters:

ParameterTypeRequiredDescription
servicestringYesService name (key in config.cross)
optCrossRunOptionsNoRuntime options to override config defaults

Returns: Promise<CrossProcess> — the created child process instance

Throws: Throws Error when service configuration does not exist in config.cross

Example:

javascript
import { cross } from 'ee-core/cross';
import { getExtraResourcesDir } from 'ee-core/ps';
import path from 'path';

// Run with config defaults
const entity = await cross.run('go');

// Run with runtime overrides
const opt = {
  name: 'goapp',
  cmd: path.join(getExtraResourcesDir(), 'goapp'),
  directory: getExtraResourcesDir(),
  args: ['--port=7073'],
  appExit: true,
};
const entity = await cross.run('go', opt);

cross.kill(pid)

Description: Terminate child process by pid.

Parameters:

ParameterTypeRequiredDescription
pidstring | numberYesProcess ID

Returns: void


cross.killByName(name)

Description: Terminate child process by name.

Parameters:

ParameterTypeRequiredDescription
namestringYesService name

Returns: void


cross.killAll()

Description: Terminate all child processes.

Returns: void

Example:

javascript
cross.killAll();

cross.getUrl(name)

Description: Get the URL of the specified service.

Parameters:

ParameterTypeRequiredDescription
namestringYesService name

Returns: string | undefined — service URL (e.g. http://127.0.0.1:7070), or undefined if process not found

Example:

javascript
const url = cross.getUrl('goServer');
// http://127.0.0.1:7070

cross.getProcByName(name)

Description: Get a CrossProcess instance by name.

Parameters:

ParameterTypeRequiredDescription
namestringYesService name

Returns: CrossProcess — the process instance

Throws: Throws Error when process with given name does not exist


cross.getProc(pid)

Description: Get a CrossProcess instance by pid.

Parameters:

ParameterTypeRequiredDescription
pidstring | numberYesProcess ID

Returns: CrossProcess — the process instance

Throws: Throws Error when process with given pid does not exist


cross.getPids()

Description: Get list of all child process pids.

Returns: string[] — array of pid strings


CrossProcess Class

The CrossProcess class encapsulates the complete lifecycle of an external process: Create -> Run -> Listen for events -> Terminate. Notifies the Cross manager of child process events (exit/error) via the host's emitter.

Process path resolution rules:

  • Config has cmd -> use cmd as executable file path (relative paths resolved based on directory or extraResourcesDir in production)
  • Config has no cmd -> use extraResourcesDir/{name} as path
  • Windows platform automatically adds .exe extension when windowsExtname=true or in production
  • Dev environment resolves relative to project root; production relative to extraResources directory

CrossProcess Properties

PropertyTypeDescription
pidnumberChild process PID
namestringUnique service name (may be rewritten by Cross manager to avoid conflicts)
portnumberAllocated port number
configCrossTargetConfigService configuration
childChildProcess | undefinedThe process object spawned via cross-spawn
emitterEventEmitterPer-process EventEmitter instance
hostCrossHostHost (Cross manager) for notifying process events

entity.kill(timeout)

Description: Terminate the child process. First sends SIGINT signal for graceful exit, then sends SIGKILL for forced termination if SIGINT fails. Timeout safety net: if exit event is not triggered within timeout, manually calls _exitElectron.

Parameters:

ParameterTypeRequiredDescription
timeoutnumberNoTimeout for waiting exit in milliseconds (default: 1000)

Returns: void

Example:

javascript
const entity = await cross.run('goServer');
entity.kill();      // default 1000ms timeout
entity.kill(3000);  // custom timeout

entity.getUrl()

Description: Get the service URL of the child process. Parses hostname and ssl flag from startup arguments, constructs HTTP/HTTPS URL. Outputs warning when port is 0.

Returns: string — service URL (e.g. http://127.0.0.1:7070)

Example:

javascript
const entity = await cross.run('goServer');
const url = entity.getUrl();
// http://127.0.0.1:7070

entity.getArgsObj()

Description: Get key-value object of startup arguments parsed from config.args.

Returns: Record<string, unknown> — parsed arguments object

Example:

javascript
const entity = await cross.run('goServer');
const args = entity.getArgsObj();
// { port: '7070', hostname: '127.0.0.1' }

entity.setPort(port)

Description: Set port number. Strings are converted to numbers.

Parameters:

ParameterTypeRequiredDescription
portstring | numberYesPort number

Returns: void


Types

CrossRunOptions

typescript
type CrossRunOptions = Partial<CrossTargetConfig>;

All CrossTargetConfig properties are optional here since they override config defaults.

CrossProcessOptions

typescript
interface CrossProcessOptions {
  /** Target service configuration */
  targetConf: CrossTargetConfig;
  /** Allocated port number */
  port: number;
}

CrossHost

typescript
interface CrossHost {
  /** Event emitter for receiving child process exit/error events */
  emitter: EventEmitter | undefined;
}

Interface that Cross implements. CrossProcess communicates with the host through this interface, sending child process exit and error events.

CrossTargetConfig

typescript
interface CrossTargetConfig {
  /** Target process name identifier (e.g. 'go', 'python') */
  name: string;
  /** Whether to enable this cross-process target */
  enable?: boolean;
  /** Command line arguments passed to the child process */
  args?: string[];
  /** Startup command (e.g. 'go', 'python3'), empty means use script for direct fork */
  cmd?: string;
  /** Child process working directory, defaults to project root directory */
  directory?: string;
  /** Whether to automatically add .exe extension on Windows */
  windowsExtname?: boolean;
  /** Child process stdio configuration */
  stdio?: ('pipe' | 'ignore' | 'inherit' | 'ipc')[];
  /** Whether to exit the main application when the child process exits */
  appExit?: boolean;
  /** Child process listening port */
  port?: number;
  /** Child process service URL (e.g. http://localhost:port) */
  url?: string;
}