All files / src/Observable Observable.ts

81.81% Statements 9/11
100% Branches 2/2
60% Functions 3/5
81.81% Lines 9/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 549x                     9x   137x                                               309x   309x 205x   205x 134x       309x            
import { scope } from '../constants'
import { type Observer } from '../types'
 
/**
 * Base reactive value **requiring subclasses to implement `update()`** for watcher notifications.
 *
 * Provides automatic observer tracking when `value` is accessed in `Observer` (`State`, `Compute`).
 *
 * @class Observable
 * @template V - state value type
 */
export abstract class Observable<V> {
  /** Set of registered observers */
  readonly observers = new Set<Observer>()
 
  /** Raw value. No auto-subscription on direct access (unlike `value`). */
  abstract raw: V
 
  /** @deprecated Use raw field */
  get rawValue () {
    return this.raw
  }
 
  /** @deprecated Use raw field */
  set rawValue (raw: V) {
    this.raw = raw
  }
 
  /**
   * Current value with automatic subscription.
   *
   * Accessing `value` inside an `Observer` automatically subscribes the watcher.
   *
   * @example
   * new Watch(() => console.log(state.value)) // auto-subscribes
   */
  get value () {
    const { activeWatcher } = scope
 
    if (activeWatcher) {
      this.observers.add(activeWatcher)
 
      activeWatcher.destructors.add(() => {
        this.observers.delete(activeWatcher)
      })
    }
 
    return this.raw
  }
 
  /** Must be implemented by subclasses to notify watchers */
  abstract update (): void
}