-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsignals.js
36 lines (31 loc) · 940 Bytes
/
signals.js
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
export class Signal extends EventTarget {
#value;
get value () { return this.#value; }
set value (value) {
if (this.#value === value) return;
this.#value = value;
this.dispatchEvent(new CustomEvent('change'));
}
constructor (value) {
super();
this.#value = value;
}
effect(fn) {
fn();
this.addEventListener('change', fn);
return () => this.removeEventListener('change', fn);
}
valueOf () { return this.#value; }
toString () { return String(this.#value); }
}
export class Computed extends Signal {
constructor (fn, deps) {
super(fn(...deps));
for (const dep of deps) {
if (dep instanceof Signal)
dep.addEventListener('change', () => this.value = fn(...deps));
}
}
}
export const signal = _ => new Signal(_);
export const computed = (fn, deps) => new Computed(fn, deps);