Comprehensive message passing system for JavaScript/TypeScript applications with advanced conflation and hook capabilities
npx @tessl/cli install tessl/npm-lumino--messaging@2.0.0@lumino/messaging provides a comprehensive message passing system for JavaScript/TypeScript applications, implementing a sophisticated message queue and dispatch mechanism. It defines core Message classes with support for message conflation to optimize performance by merging similar messages, message handlers for processing different message types, and a message loop system that ensures proper message ordering and delivery.
npm install @lumino/messagingimport {
Message,
ConflatableMessage,
IMessageHandler,
IMessageHook,
MessageHook,
MessageLoop
} from "@lumino/messaging";For CommonJS:
const {
Message,
ConflatableMessage,
IMessageHandler,
IMessageHook,
MessageHook,
MessageLoop
} = require("@lumino/messaging");import { Message, MessageLoop, IMessageHandler } from "@lumino/messaging";
// Create a message handler
class MyHandler implements IMessageHandler {
processMessage(msg: Message): void {
console.log(`Processing message: ${msg.type}`);
}
}
// Send messages immediately
const handler = new MyHandler();
const message = new Message("update");
// Send message immediately
MessageLoop.sendMessage(handler, message);
// Post message for future processing
MessageLoop.postMessage(handler, message);@lumino/messaging is built around several key components:
Message class and specialized ConflatableMessage for automatic message mergingIMessageHandler defines objects that can process messagesIMessageHook enables message interception and filteringCore message classes for creating and managing messages in the system.
/**
* Base message class for message passing system
*/
class Message {
constructor(type: string);
readonly type: string;
get isConflatable(): boolean;
conflate(other: Message): boolean;
}
/**
* Convenience message class that conflates automatically
*/
class ConflatableMessage extends Message {
constructor(type: string);
get isConflatable(): boolean;
conflate(other: ConflatableMessage): boolean;
}Usage Example:
import { Message, ConflatableMessage } from "@lumino/messaging";
// Create basic message
const basicMessage = new Message("resize");
// Create conflatable message for optimization
const conflatable = new ConflatableMessage("update-layout");
// Check if message can be conflated
console.log(basicMessage.isConflatable); // false
console.log(conflatable.isConflatable); // trueInterface for objects that can process messages.
/**
* Interface for objects that can process messages
*/
interface IMessageHandler {
processMessage(msg: Message): void;
}Usage Example:
import { IMessageHandler, Message } from "@lumino/messaging";
class WidgetHandler implements IMessageHandler {
private element: HTMLElement;
constructor(element: HTMLElement) {
this.element = element;
}
processMessage(msg: Message): void {
switch (msg.type) {
case "resize":
this.handleResize();
break;
case "update":
this.handleUpdate();
break;
}
}
private handleResize(): void {
// Handle resize logic
}
private handleUpdate(): void {
// Handle update logic
}
}Interface and type for intercepting messages before they reach handlers.
/**
* Interface for objects that can intercept messages
*/
interface IMessageHook {
messageHook(handler: IMessageHandler, msg: Message): boolean;
}
/**
* Type alias for message hook object or function
*/
type MessageHook = IMessageHook | ((handler: IMessageHandler, msg: Message) => boolean);Usage Example:
import { IMessageHook, MessageHook, IMessageHandler, Message } from "@lumino/messaging";
// Hook as object
class LoggingHook implements IMessageHook {
messageHook(handler: IMessageHandler, msg: Message): boolean {
console.log(`Intercepted message: ${msg.type}`);
return true; // Allow message to continue
}
}
// Hook as function
const filterHook: MessageHook = (handler, msg) => {
// Block messages of type "blocked"
return msg.type !== "blocked";
};Central message loop functionality for sending, posting, and managing messages.
namespace MessageLoop {
/**
* Send a message to a handler immediately
*/
function sendMessage(handler: IMessageHandler, msg: Message): void;
/**
* Post a message to a handler for future processing with conflation
*/
function postMessage(handler: IMessageHandler, msg: Message): void;
/**
* Install a message hook for a handler
*/
function installMessageHook(handler: IMessageHandler, hook: MessageHook): void;
/**
* Remove an installed message hook
*/
function removeMessageHook(handler: IMessageHandler, hook: MessageHook): void;
/**
* Clear all message data for a handler
*/
function clearData(handler: IMessageHandler): void;
/**
* Process all pending posted messages immediately
*/
function flush(): void;
/**
* Get the current exception handler
*/
function getExceptionHandler(): ExceptionHandler;
/**
* Set the exception handler, returns the old one
*/
function setExceptionHandler(handler: ExceptionHandler): ExceptionHandler;
/**
* Type alias for exception handler function
*/
type ExceptionHandler = (err: Error) => void;
}Usage Examples:
import { MessageLoop, Message, IMessageHandler } from "@lumino/messaging";
class Handler implements IMessageHandler {
messages: string[] = [];
processMessage(msg: Message): void {
this.messages.push(msg.type);
}
}
const handler = new Handler();
// Send message immediately
MessageLoop.sendMessage(handler, new Message("immediate"));
// Post message for later (with conflation)
MessageLoop.postMessage(handler, new Message("deferred"));
// Install hook to intercept messages
MessageLoop.installMessageHook(handler, (h, msg) => {
console.log(`Hook intercepted: ${msg.type}`);
return true; // Allow message to continue
});
// Clear all data for handler
MessageLoop.clearData(handler);
// Process pending messages immediately
MessageLoop.flush();
// Custom exception handling
MessageLoop.setExceptionHandler((err) => {
console.error("Message processing error:", err);
});Advanced feature for optimizing message processing by merging similar messages.
Key Concepts:
isConflatable returning trueconflate() method for custom merge logicUsage Example:
import { ConflatableMessage, MessageLoop, IMessageHandler } from "@lumino/messaging";
// Custom conflatable message
class UpdateMessage extends ConflatableMessage {
constructor(public data: any) {
super("update");
}
conflate(other: UpdateMessage): boolean {
// Merge data from other message
this.data = { ...this.data, ...other.data };
return true; // Successfully conflated
}
}
const handler: IMessageHandler = {
processMessage(msg: Message): void {
if (msg instanceof UpdateMessage) {
console.log("Processing update with data:", msg.data);
}
}
};
// These will be conflated into a single message
MessageLoop.postMessage(handler, new UpdateMessage({ x: 1 }));
MessageLoop.postMessage(handler, new UpdateMessage({ y: 2 }));
MessageLoop.postMessage(handler, new UpdateMessage({ z: 3 }));
// Only one message will be processed with merged data: { x: 1, y: 2, z: 3 }The message system includes built-in exception handling:
console.errorMessageLoop.setExceptionHandler()true by default to continue message processing