UNPKG

9.59 kBTypeScriptView Raw
1/**
2 * A message which can be delivered to a message handler.
3 *
4 * #### Notes
5 * This class may be subclassed to create complex message types.
6 */
7export declare class Message {
8 /**
9 * Construct a new message.
10 *
11 * @param type - The type of the message.
12 */
13 constructor(type: string);
14 /**
15 * The type of the message.
16 *
17 * #### Notes
18 * The `type` of a message should be related directly to its actual
19 * runtime type. This means that `type` can and will be used to cast
20 * the message to the relevant derived `Message` subtype.
21 */
22 readonly type: string;
23 /**
24 * Test whether the message is conflatable.
25 *
26 * #### Notes
27 * Message conflation is an advanced topic. Most message types will
28 * not make use of this feature.
29 *
30 * If a conflatable message is posted to a handler while another
31 * conflatable message of the same `type` has already been posted
32 * to the handler, the `conflate()` method of the existing message
33 * will be invoked. If that method returns `true`, the new message
34 * will not be enqueued. This allows messages to be compressed, so
35 * that only a single instance of the message type is processed per
36 * cycle, no matter how many times messages of that type are posted.
37 *
38 * Custom message types may reimplement this property.
39 *
40 * The default implementation is always `false`.
41 */
42 get isConflatable(): boolean;
43 /**
44 * Conflate this message with another message of the same `type`.
45 *
46 * @param other - A conflatable message of the same `type`.
47 *
48 * @returns `true` if the message was successfully conflated, or
49 * `false` otherwise.
50 *
51 * #### Notes
52 * Message conflation is an advanced topic. Most message types will
53 * not make use of this feature.
54 *
55 * This method is called automatically by the message loop when the
56 * given message is posted to the handler paired with this message.
57 * This message will already be enqueued and conflatable, and the
58 * given message will have the same `type` and also be conflatable.
59 *
60 * This method should merge the state of the other message into this
61 * message as needed so that when this message is finally delivered
62 * to the handler, it receives the most up-to-date information.
63 *
64 * If this method returns `true`, it signals that the other message
65 * was successfully conflated and that message will not be enqueued.
66 *
67 * If this method returns `false`, the other message will be enqueued
68 * for normal delivery.
69 *
70 * Custom message types may reimplement this method.
71 *
72 * The default implementation always returns `false`.
73 */
74 conflate(other: Message): boolean;
75}
76/**
77 * A convenience message class which conflates automatically.
78 *
79 * #### Notes
80 * Message conflation is an advanced topic. Most user code will not
81 * make use of this class.
82 *
83 * This message class is useful for creating message instances which
84 * should be conflated, but which have no state other than `type`.
85 *
86 * If conflation of stateful messages is required, a custom `Message`
87 * subclass should be created.
88 */
89export declare class ConflatableMessage extends Message {
90 /**
91 * Test whether the message is conflatable.
92 *
93 * #### Notes
94 * This property is always `true`.
95 */
96 get isConflatable(): boolean;
97 /**
98 * Conflate this message with another message of the same `type`.
99 *
100 * #### Notes
101 * This method always returns `true`.
102 */
103 conflate(other: ConflatableMessage): boolean;
104}
105/**
106 * An object which handles messages.
107 *
108 * #### Notes
109 * A message handler is a simple way of defining a type which can act
110 * upon on a large variety of external input without requiring a large
111 * abstract API surface. This is particularly useful in the context of
112 * widget frameworks where the number of distinct message types can be
113 * unbounded.
114 */
115export interface IMessageHandler {
116 /**
117 * Process a message sent to the handler.
118 *
119 * @param msg - The message to be processed.
120 */
121 processMessage(msg: Message): void;
122}
123/**
124 * An object which intercepts messages sent to a message handler.
125 *
126 * #### Notes
127 * A message hook is useful for intercepting or spying on messages
128 * sent to message handlers which were either not created by the
129 * consumer, or when subclassing the handler is not feasible.
130 *
131 * If `messageHook` returns `false`, no other message hooks will be
132 * invoked and the message will not be delivered to the handler.
133 *
134 * If all installed message hooks return `true`, the message will
135 * be delivered to the handler for processing.
136 *
137 * **See also:** {@link MessageLoop.installMessageHook} and {@link MessageLoop.removeMessageHook}
138 */
139export interface IMessageHook {
140 /**
141 * Intercept a message sent to a message handler.
142 *
143 * @param handler - The target handler of the message.
144 *
145 * @param msg - The message to be sent to the handler.
146 *
147 * @returns `true` if the message should continue to be processed
148 * as normal, or `false` if processing should cease immediately.
149 */
150 messageHook(handler: IMessageHandler, msg: Message): boolean;
151}
152/**
153 * A type alias for message hook object or function.
154 *
155 * #### Notes
156 * The signature and semantics of a message hook function are the same
157 * as the `messageHook` method of {@link IMessageHook}.
158 */
159export type MessageHook = IMessageHook | ((handler: IMessageHandler, msg: Message) => boolean);
160/**
161 * The namespace for the global singleton message loop.
162 */
163export declare namespace MessageLoop {
164 /**
165 * Send a message to a message handler to process immediately.
166 *
167 * @param handler - The handler which should process the message.
168 *
169 * @param msg - The message to deliver to the handler.
170 *
171 * #### Notes
172 * The message will first be sent through any installed message hooks
173 * for the handler. If the message passes all hooks, it will then be
174 * delivered to the `processMessage` method of the handler.
175 *
176 * The message will not be conflated with pending posted messages.
177 *
178 * Exceptions in hooks and handlers will be caught and logged.
179 */
180 function sendMessage(handler: IMessageHandler, msg: Message): void;
181 /**
182 * Post a message to a message handler to process in the future.
183 *
184 * @param handler - The handler which should process the message.
185 *
186 * @param msg - The message to post to the handler.
187 *
188 * #### Notes
189 * The message will be conflated with the pending posted messages for
190 * the handler, if possible. If the message is not conflated, it will
191 * be queued for normal delivery on the next cycle of the event loop.
192 *
193 * Exceptions in hooks and handlers will be caught and logged.
194 */
195 function postMessage(handler: IMessageHandler, msg: Message): void;
196 /**
197 * Install a message hook for a message handler.
198 *
199 * @param handler - The message handler of interest.
200 *
201 * @param hook - The message hook to install.
202 *
203 * #### Notes
204 * A message hook is invoked before a message is delivered to the
205 * handler. If the hook returns `false`, no other hooks will be
206 * invoked and the message will not be delivered to the handler.
207 *
208 * The most recently installed message hook is executed first.
209 *
210 * If the hook is already installed, this is a no-op.
211 */
212 function installMessageHook(handler: IMessageHandler, hook: MessageHook): void;
213 /**
214 * Remove an installed message hook for a message handler.
215 *
216 * @param handler - The message handler of interest.
217 *
218 * @param hook - The message hook to remove.
219 *
220 * #### Notes
221 * It is safe to call this function while the hook is executing.
222 *
223 * If the hook is not installed, this is a no-op.
224 */
225 function removeMessageHook(handler: IMessageHandler, hook: MessageHook): void;
226 /**
227 * Clear all message data associated with a message handler.
228 *
229 * @param handler - The message handler of interest.
230 *
231 * #### Notes
232 * This will clear all posted messages and hooks for the handler.
233 */
234 function clearData(handler: IMessageHandler): void;
235 /**
236 * Process the pending posted messages in the queue immediately.
237 *
238 * #### Notes
239 * This function is useful when posted messages must be processed immediately.
240 *
241 * This function should normally not be needed, but it may be
242 * required to work around certain browser idiosyncrasies.
243 *
244 * Recursing into this function is a no-op.
245 */
246 function flush(): void;
247 /**
248 * A type alias for the exception handler function.
249 */
250 type ExceptionHandler = (err: Error) => void;
251 /**
252 * Get the message loop exception handler.
253 *
254 * @returns The current exception handler.
255 *
256 * #### Notes
257 * The default exception handler is `console.error`.
258 */
259 function getExceptionHandler(): ExceptionHandler;
260 /**
261 * Set the message loop exception handler.
262 *
263 * @param handler - The function to use as the exception handler.
264 *
265 * @returns The old exception handler.
266 *
267 * #### Notes
268 * The exception handler is invoked when a message handler or a
269 * message hook throws an exception.
270 */
271 function setExceptionHandler(handler: ExceptionHandler): ExceptionHandler;
272}