Skip to content

Commit

Permalink
Merge pull request #23 from CrimsonChi/fix/watch-getter-ref
Browse files Browse the repository at this point in the history
chore: expose entangle method on signal and ensure we set watch getter ref on change
  • Loading branch information
LankyMoose authored Oct 13, 2024
2 parents c3ebb19 + 1d065aa commit e62e460
Showing 1 changed file with 32 additions and 22 deletions.
54 changes: 32 additions & 22 deletions packages/lib/src/signal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { HMRAccept } from "./hmr"
import { $HMR_ACCEPT, $SIGNAL } from "./constants.js"
import { __DEV__ } from "./env.js"
import { node } from "./globals.js"
import { useHook } from "./hooks/utils.js"
import { cleanupHook, useHook } from "./hooks/utils.js"
import {
getVNodeAppContext,
isVNode,
Expand Down Expand Up @@ -159,6 +159,10 @@ class WatchEffect {
this.cleanup?.call?.()
this.isRunning = false
}

static getter(watcher: WatchEffect) {
return watcher.getter
}
}

export const watch = (getter: () => (() => void) | void) => {
Expand All @@ -174,7 +178,13 @@ export const watch = (getter: () => (() => void) | void) => {
watcher: null as any as WatchEffect,
},
({ hook, isInit }) => {
if (isInit) {
let hasGetterChanged =
!!hook.watcher && WatchEffect.getter(hook.watcher) !== getter
if (hasGetterChanged) {
cleanupHook(hook)
}

if (isInit || hasGetterChanged) {
hook.watcher = new WatchEffect(getter)
hook.watcher.start()

Expand Down Expand Up @@ -271,7 +281,7 @@ export class Signal<T> {
}

get value() {
onSignalValueObserved(this)
Signal.entangle(this)
return this.$value
}

Expand All @@ -289,7 +299,7 @@ export class Signal<T> {
}

toString() {
onSignalValueObserved(this)
Signal.entangle(this)
return `${this.$value}`
}

Expand Down Expand Up @@ -329,7 +339,7 @@ export class Signal<T> {
if (desc && !desc.writable) return signal
return Object.defineProperty(signal, "value", {
get: function (this: Signal<T>) {
onSignalValueObserved(this)
Signal.entangle(this)
return this.$value
},
configurable: true,
Expand All @@ -340,7 +350,7 @@ export class Signal<T> {
if (desc && desc.writable) return signal
return Object.defineProperty(signal, "value", {
get: function (this: Signal<T>) {
onSignalValueObserved(this)
Signal.entangle(this)
return this.$value
},
set: function (this: Signal<T>, value) {
Expand All @@ -355,6 +365,22 @@ export class Signal<T> {
throw new Error("attempted to get computed getter on non-computed signal")
return signal.$getter
}

static entangle<T>(signal: Signal<T>) {
if (isTracking) {
if (!node.current || (node.current && sideEffectsEnabled())) {
trackedSignals.push(signal)
}
return
}
if (node.current) {
if (!sideEffectsEnabled()) return
if (!node.current.subs) node.current.subs = [signal]
else if (node.current.subs.indexOf(signal) === -1)
node.current.subs.push(signal)
Signal.subscribers(signal).add(node.current)
}
}
}

let isTracking = false
Expand Down Expand Up @@ -485,19 +511,3 @@ export const tick = () => {
}
})
}

const onSignalValueObserved = (signal: Signal<any>) => {
if (isTracking) {
if (!node.current || (node.current && sideEffectsEnabled())) {
trackedSignals.push(signal)
}
return
}
if (node.current) {
if (!sideEffectsEnabled()) return
if (!node.current.subs) node.current.subs = [signal]
else if (node.current.subs.indexOf(signal) === -1)
node.current.subs.push(signal)
Signal.subscribers(signal).add(node.current)
}
}

0 comments on commit e62e460

Please sign in to comment.