/**
 * A message which can be delivered to a message handler.
 *
 * #### Notes
 * This class may be subclassed to create complex message types.
 */
export declare class Message {
    /**
     * Construct a new message.
     *
     * @param type - The type of the message.
     */
    constructor(type: string);
    /**
     * The type of the message.
     *
     * #### Notes
     * The `type` of a message should be related directly to its actual
     * runtime type. This means that `type` can and will be used to cast
     * the message to the relevant derived `Message` subtype.
     */
    readonly type: string;
    /**
     * Test whether the message is conflatable.
     *
     * #### Notes
     * Message conflation is an advanced topic. Most message types will
     * not make use of this feature.
     *
     * If a conflatable message is posted to a handler while another
     * conflatable message of the same `type` has already been posted
     * to the handler, the `conflate()` method of the existing message
     * will be invoked. If that method returns `true`, the new message
     * will not be enqueued. This allows messages to be compressed, so
     * that only a single instance of the message type is processed per
     * cycle, no matter how many times messages of that type are posted.
     *
     * Custom message types may reimplement this property.
     *
     * The default implementation is always `false`.
     */
    get isConflatable(): boolean;
    /**
     * Conflate this message with another message of the same `type`.
     *
     * @param other - A conflatable message of the same `type`.
     *
     * @returns `true` if the message was successfully conflated, or
     *   `false` otherwise.
     *
     * #### Notes
     * Message conflation is an advanced topic. Most message types will
     * not make use of this feature.
     *
     * This method is called automatically by the message loop when the
     * given message is posted to the handler paired with this message.
     * This message will already be enqueued and conflatable, and the
     * given message will have the same `type` and also be conflatable.
     *
     * This method should merge the state of the other message into this
     * message as needed so that when this message is finally delivered
     * to the handler, it receives the most up-to-date information.
     *
     * If this method returns `true`, it signals that the other message
     * was successfully conflated and that message will not be enqueued.
     *
     * If this method returns `false`, the other message will be enqueued
     * for normal delivery.
     *
     * Custom message types may reimplement this method.
     *
     * The default implementation always returns `false`.
     */
    conflate(other: Message): boolean;
}
/**
 * A convenience message class which conflates automatically.
 *
 * #### Notes
 * Message conflation is an advanced topic. Most user code will not
 * make use of this class.
 *
 * This message class is useful for creating message instances which
 * should be conflated, but which have no state other than `type`.
 *
 * If conflation of stateful messages is required, a custom `Message`
 * subclass should be created.
 */
export declare class ConflatableMessage extends Message {
    /**
     * Test whether the message is conflatable.
     *
     * #### Notes
     * This property is always `true`.
     */
    get isConflatable(): boolean;
    /**
     * Conflate this message with another message of the same `type`.
     *
     * #### Notes
     * This method always returns `true`.
     */
    conflate(other: ConflatableMessage): boolean;
}
/**
 * An object which handles messages.
 *
 * #### Notes
 * A message handler is a simple way of defining a type which can act
 * upon on a large variety of external input without requiring a large
 * abstract API surface. This is particularly useful in the context of
 * widget frameworks where the number of distinct message types can be
 * unbounded.
 */
export interface IMessageHandler {
    /**
     * Process a message sent to the handler.
     *
     * @param msg - The message to be processed.
     */
    processMessage(msg: Message): void;
}
/**
 * An object which intercepts messages sent to a message handler.
 *
 * #### Notes
 * A message hook is useful for intercepting or spying on messages
 * sent to message handlers which were either not created by the
 * consumer, or when subclassing the handler is not feasible.
 *
 * If `messageHook` returns `false`, no other message hooks will be
 * invoked and the message will not be delivered to the handler.
 *
 * If all installed message hooks return `true`, the message will
 * be delivered to the handler for processing.
 *
 * **See also:** {@link MessageLoop.installMessageHook} and {@link MessageLoop.removeMessageHook}
 */
export interface IMessageHook {
    /**
     * Intercept a message sent to a message handler.
     *
     * @param handler - The target handler of the message.
     *
     * @param msg - The message to be sent to the handler.
     *
     * @returns `true` if the message should continue to be processed
     *   as normal, or `false` if processing should cease immediately.
     */
    messageHook(handler: IMessageHandler, msg: Message): boolean;
}
/**
 * A type alias for message hook object or function.
 *
 * #### Notes
 * The signature and semantics of a message hook function are the same
 * as the `messageHook` method of {@link IMessageHook}.
 */
export type MessageHook = IMessageHook | ((handler: IMessageHandler, msg: Message) => boolean);
/**
 * The namespace for the global singleton message loop.
 */
export declare namespace MessageLoop {
    /**
     * Send a message to a message handler to process immediately.
     *
     * @param handler - The handler which should process the message.
     *
     * @param msg - The message to deliver to the handler.
     *
     * #### Notes
     * The message will first be sent through any installed message hooks
     * for the handler. If the message passes all hooks, it will then be
     * delivered to the `processMessage` method of the handler.
     *
     * The message will not be conflated with pending posted messages.
     *
     * Exceptions in hooks and handlers will be caught and logged.
     */
    function sendMessage(handler: IMessageHandler, msg: Message): void;
    /**
     * Post a message to a message handler to process in the future.
     *
     * @param handler - The handler which should process the message.
     *
     * @param msg - The message to post to the handler.
     *
     * #### Notes
     * The message will be conflated with the pending posted messages for
     * the handler, if possible. If the message is not conflated, it will
     * be queued for normal delivery on the next cycle of the event loop.
     *
     * Exceptions in hooks and handlers will be caught and logged.
     */
    function postMessage(handler: IMessageHandler, msg: Message): void;
    /**
     * Install a message hook for a message handler.
     *
     * @param handler - The message handler of interest.
     *
     * @param hook - The message hook to install.
     *
     * #### Notes
     * A message hook is invoked before a message is delivered to the
     * handler. If the hook returns `false`, no other hooks will be
     * invoked and the message will not be delivered to the handler.
     *
     * The most recently installed message hook is executed first.
     *
     * If the hook is already installed, this is a no-op.
     */
    function installMessageHook(handler: IMessageHandler, hook: MessageHook): void;
    /**
     * Remove an installed message hook for a message handler.
     *
     * @param handler - The message handler of interest.
     *
     * @param hook - The message hook to remove.
     *
     * #### Notes
     * It is safe to call this function while the hook is executing.
     *
     * If the hook is not installed, this is a no-op.
     */
    function removeMessageHook(handler: IMessageHandler, hook: MessageHook): void;
    /**
     * Clear all message data associated with a message handler.
     *
     * @param handler - The message handler of interest.
     *
     * #### Notes
     * This will clear all posted messages and hooks for the handler.
     */
    function clearData(handler: IMessageHandler): void;
    /**
     * Process the pending posted messages in the queue immediately.
     *
     * #### Notes
     * This function is useful when posted messages must be processed immediately.
     *
     * This function should normally not be needed, but it may be
     * required to work around certain browser idiosyncrasies.
     *
     * Recursing into this function is a no-op.
     */
    function flush(): void;
    /**
     * A type alias for the exception handler function.
     */
    type ExceptionHandler = (err: Error) => void;
    /**
     * Get the message loop exception handler.
     *
     * @returns The current exception handler.
     *
     * #### Notes
     * The default exception handler is `console.error`.
     */
    function getExceptionHandler(): ExceptionHandler;
    /**
     * Set the message loop exception handler.
     *
     * @param handler - The function to use as the exception handler.
     *
     * @returns The old exception handler.
     *
     * #### Notes
     * The exception handler is invoked when a message handler or a
     * message hook throws an exception.
     */
    function setExceptionHandler(handler: ExceptionHandler): ExceptionHandler;
}
