Created
December 5, 2023 21:04
-
-
Save thomaswilburn/c6dc0036f75f94eefd8e17d0fa79b36c to your computer and use it in GitHub Desktop.
Classy signals
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var tracking = []; | |
var pending = new Set(); | |
function anticipate(fn) { | |
pending.add(fn); | |
requestAnimationFrame(() => { | |
for (var p of pending) p(); | |
pending.clear(); | |
}); | |
} | |
class Signal { | |
#value = undefined; | |
#watchers = new Set(); | |
constructor(value) { | |
this.#value = value; | |
} | |
get value() { | |
var active = tracking.at(-1); | |
if (active) { | |
this.#watchers.add(active); | |
} | |
return this.#value; | |
} | |
set value(value) { | |
if (value == this.#value) return | |
this.#value = value; | |
for (var watcher of this.#watchers) { | |
anticipate(watcher); | |
} | |
} | |
destroy() { | |
this.#watchers.clear(); | |
} | |
} | |
class Derived extends Signal { | |
#value = undefined; | |
constructor(fn) { | |
super(); | |
trackExecution(() => { | |
this.value = fn(); | |
}); | |
} | |
} | |
function trackExecution(fn) { | |
tracking.push(fn); | |
fn(); | |
tracking.pop(); | |
} | |
var a = new Signal(0); | |
var b = new Signal(0); | |
var sum = new Derived(function() { | |
console.info("sum!"); | |
return a.value + b.value; | |
}); | |
var sumSquared = new Derived(function() { | |
console.info("square!"); | |
return sum.value ** 2; | |
}); | |
trackExecution(function() { | |
console.info("tracked!") | |
console.log("a + b", sum.value); | |
console.log("sum^2", sumSquared.value); | |
}); | |
console.log("a = 1"); | |
a.value = 1; | |
console.log("b = 3"); | |
b.value = 3; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment