/// <reference types="node" />
import * as net from "net";
import { IContainerLogMessage, IModuleOptions, Module } from "../../container";
import { Observable, Subject } from "../../container/RxJS";
import { IErrorChainSerialised } from "../error";
import { Process, ProcessError } from "./Process";
/** Process message types. */
export declare enum EProcessMessageType {
    Log = 0,
    Metric = 1,
    CallRequest = 2,
    CallResponse = 3,
    Event = 4,
    Socket = 5,
    User = 6,
}
/** Process call method options. */
export interface IProcessCallOptions {
    timeout?: number;
    args?: any[];
    channel?: string;
}
/** Process event method options. */
export interface IProcessEventOptions<T> {
    data?: T;
    channel?: string;
}
/** Process call function signature. */
export declare type IProcessCallType = (...args: any[]) => Observable<any>;
/** Process call request message data. */
export interface IProcessCallRequestData {
    id: number;
    target: string;
    method: string;
    args: any[];
}
/** Process call response message data. */
export interface IProcessCallResponseData {
    id: number;
    next?: any;
    error?: IErrorChainSerialised;
    complete?: boolean;
}
/** Process event message data. */
export interface IProcessEventData {
    name: string;
    data?: any;
    channel?: string;
}
/** Process data types. */
export declare type IProcessMessageData = IContainerLogMessage | IProcessCallRequestData | IProcessCallResponseData | IProcessEventData | any;
/** Process message interface. */
export interface IProcessMessage extends Object {
    type: EProcessMessageType;
    data: IProcessMessageData;
    channel?: string;
}
/** Process send method interface. */
export interface IProcessSend {
    messages$: Observable<IProcessMessage>;
    send: (type: EProcessMessageType, data: any, channel?: string) => void;
}
export declare class ChildProcess extends Process implements IProcessSend {
    /** Default module name. */
    static readonly moduleName: string;
    /** Default values. */
    static readonly DEFAULT: {
        TIMEOUT: number;
        STATUS_INTERVAL: number;
        CHANNEL: string;
        ENCODING: string;
    };
    /** Class event names. */
    static readonly EVENT: {
        SOCKET: string;
        CHANNEL: string;
        STATUS: string;
    };
    /** Configure socket for interprocess communication. */
    static socketConfigure(options: {
        socket: net.Socket;
        onError: (error: ProcessError) => void;
        onData: (data: IProcessMessage) => void;
    }): net.Socket;
    /** Serialise input data for socket. */
    static socketSerialise(data: any): string;
    /** Deserialise input data from socket. */
    static socketDeserialise(data: string): IProcessMessage[];
    /** Extract serialisable error properties to object. */
    static serialiseError(error: Error): IErrorChainSerialised;
    /** Convert serialised error to error instance. */
    static deserialiseError(error: IErrorChainSerialised): ProcessError;
    /** Send call request to process. */
    static sendCallRequest<T>(emitter: IProcessSend, mod: Module, target: string, method: string, id: number, options?: IProcessCallOptions): Observable<T>;
    /** Handle method call requests. */
    static handleCallRequest(emitter: IProcessSend, mod: Module, data: IProcessCallRequestData, channel?: string): void;
    /** Handle method call responses. */
    static handleCallResponse<T>(messages$: Observable<IProcessMessage>, id: number, args: any[], timeout: number): Observable<T>;
    /** Send event to process. */
    static sendEvent<T>(emitter: IProcessSend, mod: Module, name: string, options?: IProcessEventOptions<T>): void;
    /** Listen for events from process. */
    static listenForEvent<T>(events$: Observable<IProcessEventData>, name: string, channel?: string): Observable<T>;
    /** Socket handle received from parent process. */
    sockets: {
        [key: string]: net.Socket | undefined;
    };
    /** Messages received from parent process. */
    readonly messages$: Subject<IProcessMessage>;
    /** Events received from parent process. */
    readonly events$: Subject<IProcessEventData>;
    protected currentIdentifier: number;
    constructor(options: IModuleOptions);
    /** Send message to channel process. */
    send(type: EProcessMessageType, data: any, channel?: string): void;
    /** Make call to module.method in parent process. */
    call<T>(target: string, method: string, options?: IProcessCallOptions): Observable<T>;
    /** Send event with optional data to parent process. */
    event<T>(name: string, options?: IProcessEventOptions<T>): void;
    /** Listen for event sent by parent process. */
    listen<T>(name: string, channel?: string): Observable<T>;
    /** Incrementing counter for unique identifiers. */
    protected readonly nextIdentifier: number;
    /** Handle messages received from parent process. */
    protected handleMessage(message: IProcessMessage): void;
    /** Override process down handler to close socket if present. */
    protected onSignal(signal: string): void;
}
