Created
April 13, 2024 13:36
-
-
Save dy/bbac687464ccf5322ab0e2fd0680dc4d to your computer and use it in GitHub Desktop.
signal polyfill preact
This file contains hidden or 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
// @preact/signals compatible wrapper for signal proposal | |
import { Signal } from 'signal-polyfill' | |
const { untrack, Watcher } = Signal.subtle | |
export const signal = v => wrap(new Signal.State(v)) | |
export const computed = fn => wrap(new Signal.Computed(fn)) | |
export { untrack as untracked } | |
const wrap = (s) => { | |
let get = () => s.get() | |
Object.defineProperty(s, 'value', { | |
get, | |
set(v) { s.set(v) } | |
}) | |
s.peek = () => untrack(get) | |
s.toJSON = s.then = s.toString = s.valueOf = get | |
return s | |
} | |
let pending = false; | |
let fxWatcher = new Watcher(() => { | |
if (!pending) { | |
pending = true; | |
queueMicrotask(flushPending); | |
} | |
}); | |
function flushPending() { | |
pending = false; | |
console.log('flush pending') | |
for (const signal of fxWatcher.getPending()) { | |
signal.get(); | |
} | |
fxWatcher.watch(); | |
} | |
let idx = 0 | |
export function effect(cb) { | |
let destructor; | |
let c = new Signal.Computed(() => { typeof destructor === 'function' && destructor(); destructor = cb(); }); | |
c.idx = idx++ | |
console.log('watch', c) | |
fxWatcher.watch(c); | |
c.get(); | |
return () => { | |
typeof destructor === 'function' && destructor(); | |
unwatch(c) | |
}; | |
} | |
function unwatch(c) { | |
fxWatcher.unwatch(c) | |
} | |
// batched destructor (unstable) - faster | |
/* | |
let toUnwatch = new Set | |
function unwatch(s) { | |
console.log('unwatch', s) | |
if (!toUnwatch.size) { | |
queueMicrotask(flushUnwatch); | |
} | |
toUnwatch.add(s) | |
} | |
const flushUnwatch = () => { | |
let u = [...toUnwatch] | |
toUnwatch.clear() | |
fxWatcher.unwatch(...u) | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment