Class: Hibiki::Effect

Inherits:
Object
  • Object
show all
Includes:
Observer, Owner
Defined in:
lib/hibiki/effect.rb

Overview

---- effect -----------------------------------------------------------------

Instance Method Summary collapse

Methods included from Owner

#add_cleanup, #adopt

Methods included from Observer

#add_source, #clear_sources, #sources

Constructor Details

#initialize(scheduler: nil, &block) ⇒ Effect

scheduler: hands re-runs to the caller instead of running inline (Vue's ReactiveEffect scheduler): a callable receiving the effect, which calls #run whenever it's ready — on the graph's own execution context. The initial run is never scheduled: dependency collection must happen at creation, and Vue's constructor runs directly too.



14
15
16
17
18
19
20
21
22
# File 'lib/hibiki/effect.rb', line 14

def initialize(scheduler: nil, &block)
  @block = block
  @scheduler = scheduler
  @disposed = false
  # Effects created while another effect (or root) runs are owned by it
  # and disposed when the owner re-runs or is disposed.
  Hibiki.current_owner&.adopt(self)
  run
end

Instance Method Details

#disposeObject

Sever every subscription and take owned children/cleanups down with us. A disposed effect never runs again — including a pending batch flush.



29
30
31
32
33
34
35
# File 'lib/hibiki/effect.rb', line 29

def dispose
  return if @disposed

  @disposed = true
  dispose_owned
  clear_sources
end

#disposed?Boolean

Returns:

  • (Boolean)


24
# File 'lib/hibiki/effect.rb', line 24

def disposed? = @disposed

#invalidateObject

Under a batch, defer: Hibiki queues us (deduplicated) and re-runs the block once at flush instead of once per write. With a scheduler, the re-run is handed to it right where it would have happened — after the batch dedup, so the flush's error isolation covers a raising scheduler too, and N batched writes mean one scheduler call.



42
43
44
45
46
47
48
# File 'lib/hibiki/effect.rb', line 42

def invalidate
  return if @disposed
  return Hibiki.schedule(self) if Hibiki.batching?
  return @scheduler.call(self) if @scheduler

  run
end

#runObject

Public for scheduled effects: the scheduler (or whoever it handed us to) calls this when it's time to re-run. No-op once disposed — a debounced run firing late must lose to dispose, like a pending flush does. A raise propagates to the caller: a deferred run is outside any flush, so the integration owns rescue there.



55
56
57
58
59
60
61
62
63
# File 'lib/hibiki/effect.rb', line 55

def run
  return if @disposed

  dispose_owned
  clear_sources
  Hibiki.own(self) do
    Hibiki.track(self) { @block.call }
  end
end