import { pull } from 'lodash'

type Listener<T> = (value: T) => void

export class ObservableValue<T> {
  protected value: T
  private listeners: Listener<T>[] = []

  constructor(initial: T) {
    this.value = initial
  }

  set(value: T) {
    if (this.value !== value) {
      this.value = value
      this.listeners.forEach(l => l(value))
    }
  }

  get(): T {
    return this.value
  }

  onChange(listener: (value: T) => void) {
    this.listeners.push(listener)
    return () => {
      pull(this.listeners, listener)
    }
  }
}
