Skip to content

Instantly share code, notes, and snippets.

@joshnuss
Last active January 7, 2025 03:13
Show Gist options
  • Save joshnuss/60f376be1bd05797409975760c7fca02 to your computer and use it in GitHub Desktop.
Save joshnuss/60f376be1bd05797409975760c7fca02 to your computer and use it in GitHub Desktop.
Signals experiment
<html>
<body>
<h1></h1>
<button onclick="decrement()">-</button>
<button onclick="increment()">+</button>
<script>
function signal(initial, callback = null) {
let value = initial
let subscribers = new Set(callback ? [callback] : [])
return {
get current() {
return value
},
set current(change) {
value = change
subscribers.forEach(callback => callback(value))
},
subscribe(callback) {
subscribers.add(callback)
return () => subscribers.delete(callback)
}
}
}
function computed(callback, dependencies) {
const value = signal(callback())
dependencies.forEach(dependency => {
dependency.subscribe(() => {
value.current = callback()
})
})
return value
}
/* this part would be generated from a compiler, similar to Svelte */
/*
<script>
let num = 0
@computed
let double = num * 2
function increment() {
num++
}
function decrement() {
num--
}
<script>
<h1>{double}</h1>
<button onclick={decrement}>-</button>
<button onclick={increment}>+</button>
*/
// let num = 0
// re-written by compiler to:
let num = signal(0)
// @computed
// let double = num * 2
// re-written by compiler to:
let double = computed(() => num.current * 2, [num])
// <h1>{double}</h1>
// re-written by compiler to:
const h1 = document.querySelector('h1')
h1.textContent = double.current
double.subscribe(() => {
h1.textContent = double.current
})
function increment() {
// num++
// re-written by compiler to:
num.current++
}
function decrement() {
// num--
// re-written by compiler to:
num.current--
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment