1 | /**
|
2 | * A type alias for a slot function.
|
3 | *
|
4 | * @param sender - The object emitting the signal.
|
5 | *
|
6 | * @param args - The args object emitted with the signal.
|
7 | *
|
8 | * #### Notes
|
9 | * A slot is invoked when a signal to which it is connected is emitted.
|
10 | */
|
11 | export type Slot<T, U> = (sender: T, args: U) => void;
|
12 | /**
|
13 | * An object used for type-safe inter-object communication.
|
14 | *
|
15 | * #### Notes
|
16 | * Signals provide a type-safe implementation of the publish-subscribe
|
17 | * pattern. An object (publisher) declares which signals it will emit,
|
18 | * and consumers connect callbacks (subscribers) to those signals. The
|
19 | * subscribers are invoked whenever the publisher emits the signal.
|
20 | */
|
21 | export interface ISignal<T, U> {
|
22 | /**
|
23 | * Connect a slot to the signal.
|
24 | *
|
25 | * @param slot - The slot to invoke when the signal is emitted.
|
26 | *
|
27 | * @param thisArg - The `this` context for the slot. If provided,
|
28 | * this must be a non-primitive object.
|
29 | *
|
30 | * @returns `true` if the connection succeeds, `false` otherwise.
|
31 | *
|
32 | * #### Notes
|
33 | * Slots are invoked in the order in which they are connected.
|
34 | *
|
35 | * Signal connections are unique. If a connection already exists for
|
36 | * the given `slot` and `thisArg`, this method returns `false`.
|
37 | *
|
38 | * A newly connected slot will not be invoked until the next time the
|
39 | * signal is emitted, even if the slot is connected while the signal
|
40 | * is dispatching.
|
41 | */
|
42 | connect(slot: Slot<T, U>, thisArg?: any): boolean;
|
43 | /**
|
44 | * Disconnect a slot from the signal.
|
45 | *
|
46 | * @param slot - The slot to disconnect from the signal.
|
47 | *
|
48 | * @param thisArg - The `this` context for the slot. If provided,
|
49 | * this must be a non-primitive object.
|
50 | *
|
51 | * @returns `true` if the connection is removed, `false` otherwise.
|
52 | *
|
53 | * #### Notes
|
54 | * If no connection exists for the given `slot` and `thisArg`, this
|
55 | * method returns `false`.
|
56 | *
|
57 | * A disconnected slot will no longer be invoked, even if the slot
|
58 | * is disconnected while the signal is dispatching.
|
59 | */
|
60 | disconnect(slot: Slot<T, U>, thisArg?: any): boolean;
|
61 | }
|
62 | /**
|
63 | * An object that is both a signal and an async iterable.
|
64 | */
|
65 | export interface IStream<T, U> extends ISignal<T, U>, AsyncIterable<U> {
|
66 | }
|
67 | /**
|
68 | * A concrete implementation of `ISignal`.
|
69 | *
|
70 | * #### Example
|
71 | * ```typescript
|
72 | * import { ISignal, Signal } from '@lumino/signaling';
|
73 | *
|
74 | * class SomeClass {
|
75 | *
|
76 | * constructor(name: string) {
|
77 | * this.name = name;
|
78 | * }
|
79 | *
|
80 | * readonly name: string;
|
81 | *
|
82 | * get valueChanged: ISignal<this, number> {
|
83 | * return this._valueChanged;
|
84 | * }
|
85 | *
|
86 | * get value(): number {
|
87 | * return this._value;
|
88 | * }
|
89 | *
|
90 | * set value(value: number) {
|
91 | * if (value === this._value) {
|
92 | * return;
|
93 | * }
|
94 | * this._value = value;
|
95 | * this._valueChanged.emit(value);
|
96 | * }
|
97 | *
|
98 | * private _value = 0;
|
99 | * private _valueChanged = new Signal<this, number>(this);
|
100 | * }
|
101 | *
|
102 | * function logger(sender: SomeClass, value: number): void {
|
103 | * console.log(sender.name, value);
|
104 | * }
|
105 | *
|
106 | * let m1 = new SomeClass('foo');
|
107 | * let m2 = new SomeClass('bar');
|
108 | *
|
109 | * m1.valueChanged.connect(logger);
|
110 | * m2.valueChanged.connect(logger);
|
111 | *
|
112 | * m1.value = 42; // logs: foo 42
|
113 | * m2.value = 17; // logs: bar 17
|
114 | * ```
|
115 | */
|
116 | export declare class Signal<T, U> implements ISignal<T, U> {
|
117 | /**
|
118 | * Construct a new signal.
|
119 | *
|
120 | * @param sender - The sender which owns the signal.
|
121 | */
|
122 | constructor(sender: T);
|
123 | /**
|
124 | * The sender which owns the signal.
|
125 | */
|
126 | readonly sender: T;
|
127 | /**
|
128 | * Connect a slot to the signal.
|
129 | *
|
130 | * @param slot - The slot to invoke when the signal is emitted.
|
131 | *
|
132 | * @param thisArg - The `this` context for the slot. If provided,
|
133 | * this must be a non-primitive object.
|
134 | *
|
135 | * @returns `true` if the connection succeeds, `false` otherwise.
|
136 | */
|
137 | connect(slot: Slot<T, U>, thisArg?: unknown): boolean;
|
138 | /**
|
139 | * Disconnect a slot from the signal.
|
140 | *
|
141 | * @param slot - The slot to disconnect from the signal.
|
142 | *
|
143 | * @param thisArg - The `this` context for the slot. If provided,
|
144 | * this must be a non-primitive object.
|
145 | *
|
146 | * @returns `true` if the connection is removed, `false` otherwise.
|
147 | */
|
148 | disconnect(slot: Slot<T, U>, thisArg?: unknown): boolean;
|
149 | /**
|
150 | * Emit the signal and invoke the connected slots.
|
151 | *
|
152 | * @param args - The args to pass to the connected slots.
|
153 | *
|
154 | * #### Notes
|
155 | * Slots are invoked synchronously in connection order.
|
156 | *
|
157 | * Exceptions thrown by connected slots will be caught and logged.
|
158 | */
|
159 | emit(args: U): void;
|
160 | }
|
161 | /**
|
162 | * The namespace for the `Signal` class statics.
|
163 | */
|
164 | export declare namespace Signal {
|
165 | /**
|
166 | * Remove all connections between a sender and receiver.
|
167 | *
|
168 | * @param sender - The sender object of interest.
|
169 | *
|
170 | * @param receiver - The receiver object of interest.
|
171 | *
|
172 | * #### Notes
|
173 | * If a `thisArg` is provided when connecting a signal, that object
|
174 | * is considered the receiver. Otherwise, the `slot` is considered
|
175 | * the receiver.
|
176 | */
|
177 | function disconnectBetween(sender: unknown, receiver: unknown): void;
|
178 | /**
|
179 | * Remove all connections where the given object is the sender.
|
180 | *
|
181 | * @param sender - The sender object of interest.
|
182 | */
|
183 | function disconnectSender(sender: unknown): void;
|
184 | /**
|
185 | * Remove all connections where the given object is the receiver.
|
186 | *
|
187 | * @param receiver - The receiver object of interest.
|
188 | *
|
189 | * #### Notes
|
190 | * If a `thisArg` is provided when connecting a signal, that object
|
191 | * is considered the receiver. Otherwise, the `slot` is considered
|
192 | * the receiver.
|
193 | */
|
194 | function disconnectReceiver(receiver: unknown): void;
|
195 | /**
|
196 | * Remove all connections where an object is the sender or receiver.
|
197 | *
|
198 | * @param object - The object of interest.
|
199 | *
|
200 | * #### Notes
|
201 | * If a `thisArg` is provided when connecting a signal, that object
|
202 | * is considered the receiver. Otherwise, the `slot` is considered
|
203 | * the receiver.
|
204 | */
|
205 | function disconnectAll(object: unknown): void;
|
206 | /**
|
207 | * Clear all signal data associated with the given object.
|
208 | *
|
209 | * @param object - The object for which the data should be cleared.
|
210 | *
|
211 | * #### Notes
|
212 | * This removes all signal connections and any other signal data
|
213 | * associated with the object.
|
214 | */
|
215 | function clearData(object: unknown): void;
|
216 | /**
|
217 | * A type alias for the exception handler function.
|
218 | */
|
219 | type ExceptionHandler = (err: Error) => void;
|
220 | /**
|
221 | * Get the signal exception handler.
|
222 | *
|
223 | * @returns The current exception handler.
|
224 | *
|
225 | * #### Notes
|
226 | * The default exception handler is `console.error`.
|
227 | */
|
228 | function getExceptionHandler(): ExceptionHandler;
|
229 | /**
|
230 | * Set the signal exception handler.
|
231 | *
|
232 | * @param handler - The function to use as the exception handler.
|
233 | *
|
234 | * @returns The old exception handler.
|
235 | *
|
236 | * #### Notes
|
237 | * The exception handler is invoked when a slot throws an exception.
|
238 | */
|
239 | function setExceptionHandler(handler: ExceptionHandler): ExceptionHandler;
|
240 | }
|
241 | /**
|
242 | * A concrete implementation of `IStream`.
|
243 | *
|
244 | * #### Example
|
245 | * ```typescript
|
246 | * import { IStream, Stream } from '@lumino/signaling';
|
247 | *
|
248 | * class SomeClass {
|
249 | *
|
250 | * constructor(name: string) {
|
251 | * this.name = name;
|
252 | * }
|
253 | *
|
254 | * readonly name: string;
|
255 | *
|
256 | * get pings(): IStream<this, string> {
|
257 | * return this._pings;
|
258 | * }
|
259 | *
|
260 | * ping(value: string) {
|
261 | * this._pings.emit(value);
|
262 | * }
|
263 | *
|
264 | * private _pings = new Stream<this, string>(this);
|
265 | * }
|
266 | *
|
267 | * let m1 = new SomeClass('foo');
|
268 | *
|
269 | * m1.pings.connect((_, value: string) => {
|
270 | * console.log('connect', value);
|
271 | * });
|
272 | *
|
273 | * void (async () => {
|
274 | * for await (const ping of m1.pings) {
|
275 | * console.log('iterator', ping);
|
276 | * }
|
277 | * })();
|
278 | *
|
279 | * m1.ping('alpha'); // logs: connect alpha
|
280 | * // logs: iterator alpha
|
281 | * m1.ping('beta'); // logs: connect beta
|
282 | * // logs: iterator beta
|
283 | * ```
|
284 | */
|
285 | export declare class Stream<T, U> extends Signal<T, U> implements IStream<T, U> {
|
286 | /**
|
287 | * Return an async iterator that yields every emission.
|
288 | */
|
289 | [Symbol.asyncIterator](): AsyncIterableIterator<U>;
|
290 | /**
|
291 | * Emit the signal, invoke the connected slots, and yield the emission.
|
292 | *
|
293 | * @param args - The args to pass to the connected slots.
|
294 | */
|
295 | emit(args: U): void;
|
296 | /**
|
297 | * Stop the stream's async iteration.
|
298 | */
|
299 | stop(): void;
|
300 | private _pending;
|
301 | }
|