Module: Hibiki::Trackable

Included in:
Derived, State
Defined in:
lib/hibiki/tracking.rb

Overview

---- shared subscription behaviour -----------------------------------------

Instance Method Summary collapse

Instance Method Details

#changed_from?(seen) ⇒ Boolean

The flush gate's question, answered by the source so its own equality decides (Solid's equals option, on createSignal and createMemo alike): nil → == as always, false → never equal (every write notifies), callable → comparator(prev, next). Both gates consult the same @equals — a comparator honored on write but not at flush would let the batch flush silently swallow the very change the write announced.

Returns:

  • (Boolean)


85
86
87
88
89
90
91
# File 'lib/hibiki/tracking.rb', line 85

def changed_from?(seen)
  case @equals
  when nil then peek != seen
  when false then true
  else !@equals.call(seen, peek)
  end
end

#notifyObject



93
94
95
96
# File 'lib/hibiki/tracking.rb', line 93

def notify
  # dup: invalidation may mutate the set while we iterate
  subscribers.dup.each(&:invalidate)
end

#register_dependencyObject

Called on every read: if someone reactive is currently computing, they now depend on us — record both directions of the edge, so the observer can sever it before its next rerun.

The VALUE travels with the edge: an observer that remembers what it saw can decide later whether anything it reads actually changed (Svelte's $derived compares; see Observer#sources_changed?). peek is the documented read-without-an-edge, and we're already clean here — a Derived recomputes before it registers — so it costs a cache read.



69
70
71
72
73
74
75
# File 'lib/hibiki/tracking.rb', line 69

def register_dependency
  observer = Hibiki.current_observer
  return unless observer

  subscribers << observer
  observer.add_source(self, peek)
end

#subscribersObject



58
# File 'lib/hibiki/tracking.rb', line 58

def subscribers = (@subscribers ||= Set.new)

#unsubscribe(observer) ⇒ Object



77
# File 'lib/hibiki/tracking.rb', line 77

def unsubscribe(observer) = subscribers.delete(observer)