import { arrayRemoveElement } from './array' // I'm aware of this one, but like mine better ;) // https://github.com/proposal-signals/proposal-signals export type SignalWatcher = (value: T, oldValue: T) => void export type Signal = [ () => T, (value: T) => void, (fn: SignalWatcher) => () => void, (fn: SignalWatcher) => void, ] & { get: () => T set: (value: T) => void on: (fn: SignalWatcher) => () => void off: (fn: SignalWatcher) => void } /** Super simple signal implementation */ export function useSignal(value: T, onChange?: SignalWatcher): Signal { let signal = structuredClone(value) const watchers: SignalWatcher[] = [] function off(fn: SignalWatcher) { arrayRemoveElement(watchers, fn) } function on(fn: SignalWatcher) { watchers.push(fn) return () => off(fn) } if (onChange) watchers.push(onChange) const get = () => structuredClone(signal) const set = (value: T) => { if (value !== signal) { const oldValue = signal signal = value watchers.forEach(fn => fn(value, oldValue)) } } const obj: any = [get, set, on, off] obj.get = get obj.set = set obj.on = on obj.off = off return obj }