tc39 / proposal-signals

A proposal to add signals to JavaScript.
MIT License
2.87k stars 54 forks source link

False positive in cycle detection for asymmetric cycles #201

Open prophile opened 2 weeks ago

prophile commented 2 weeks ago

Consider the following code:

import { Signal } from './dist/index.js'

let switchFlag = false

const state = new Signal.State({})
let b
const a = new Signal.Computed(() => {
  if (switchFlag) {
    return b.get()
  } else {
    return state.get()
  }
})
b = new Signal.Computed(() => {
  if (switchFlag) {
    return state.get()
  } else {
    return a.get()
  }
})
const c = new Signal.Computed(() => [a.get(), b.get()])

c.get()
switchFlag = true
state.set({})
c.get()

For either value of switchFlag the dependency graph is acyclic, but this code currently raises "Detected cycle in computations" according to the polyfill at f7c550b.

The "Algorithm: recalculate dirty computed Signal" specification heavily implies that sources aren't retained between evaluations of a Computed's callback.