-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathsignal.ts
55 lines (44 loc) · 1.24 KB
/
signal.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class Signal {
private _id = 0
private _listeners: { [key: string]: Function } = {}
dispatch(...args: any[]) {
for (const key in this._listeners) {
this._listeners[key](...args)
}
}
attach(listener: Function) {
if (typeof listener !== 'function') {
throw new Error('listener function expected')
}
const id = this._id++
this._listeners[id] = listener
// return function that'll detach the listener
return () => delete this._listeners[id]
}
}
const memArgsSymbol = '__private__memoized__arguments__'
class MemoizedSignal extends Signal {
private [memArgsSymbol]: any[] = []
constructor(...memoizedArgs: any[]) {
super()
if (!memoizedArgs.length) {
throw new Error('Initial value to be memoized expected')
}
this[memArgsSymbol] = memoizedArgs
}
dispatch(...args: any[]) {
this[memArgsSymbol] = args
super.dispatch(...args)
}
attach(listener: Function) {
/*
* attaching first so that we throw a sensible
* error if listener is not a function without
* duplication of is function check
*/
const detachListener = super.attach(listener)
listener(...this[memArgsSymbol])
return detachListener
}
}
export { Signal, MemoizedSignal }