Skip to content

Instantly share code, notes, and snippets.

@Sheraff
Created February 23, 2026 10:32
Show Gist options
  • Select an option

  • Save Sheraff/5b27afddc8da89b6f2686bff05087057 to your computer and use it in GitHub Desktop.

Select an option

Save Sheraff/5b27afddc8da89b6f2686bff05087057 to your computer and use it in GitHub Desktop.
interface ReadonlySignal<T> {
invalidate(): void
readonly value: T
}
interface WritableSignal<T> {
value: T
}
let running: ReadonlySignal<any> | null = null
type CreatedSignal<T> = T extends (() => infer U) ? ReadonlySignal<U> : WritableSignal<T>
function createSignal<T>(valueOrGetter: T | (() => T)): CreatedSignal<T> {
const deps = new Set<ReadonlySignal<any>>()
let value: T
const invalidateDeps = () => {
for (const dep of deps) {
dep.invalidate()
}
}
if (typeof valueOrGetter === 'function') {
let stale = true
const self = {
invalidate: () => {
stale = true
invalidateDeps()
},
get value() {
if (running && running !== self) deps.add(running)
if (!stale) return value
const before = running
running = self as ReadonlySignal<any>
value = (valueOrGetter as () => T)()
running = before
stale = false
return value
}
} as CreatedSignal<T>
return self
} else {
value = valueOrGetter as T
const self = {
get value() {
if (running) deps.add(running)
return value
},
set value(next) {
value = next
invalidateDeps()
}
} as CreatedSignal<T>
return self
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment