-- | Component capable of debouncing actions
module Halogen.Component.Debounced where

import Control.Monad.State.Delayed.Delayer
import Control.Monad.State.Delayed.Trans
import Data.NT
import Data.Time
import HPrelude
import Halogen.Component
import Halogen.Query.HalogenM
import System.IO.Unsafe (unsafePerformIO)

unsafeMkDebouncedComponent
  :: forall state query action slots input output m
   . NominalDiffTime
  -> ComponentSpec' state query action slots input output m (DelayedStateT state (HalogenM state action slots output m))
  -> Component query input output m
unsafeMkDebouncedComponent :: forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *).
NominalDiffTime
-> ComponentSpec'
     state
     query
     action
     slots
     input
     output
     m
     (DelayedStateT state (HalogenM state action slots output m))
-> Component query input output m
unsafeMkDebouncedComponent NominalDiffTime
timeout ComponentSpec'
  state
  query
  action
  slots
  input
  output
  m
  (DelayedStateT state (HalogenM state action slots output m))
cs = do
  Delayer state
-> ComponentSpec'
     state
     query
     action
     slots
     input
     output
     m
     (DelayedStateT state (HalogenM state action slots output m))
-> Component query input output m
forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *).
Delayer state
-> ComponentSpec'
     state
     query
     action
     slots
     input
     output
     m
     (DelayedStateT state (HalogenM state action slots output m))
-> Component query input output m
mkDebouncedComponent' (IO (Delayer state) -> Delayer state
forall a. IO a -> a
unsafePerformIO (IO (Delayer state) -> Delayer state)
-> IO (Delayer state) -> Delayer state
forall a b. (a -> b) -> a -> b
$ NominalDiffTime -> IO (Delayer state)
forall (m :: * -> *) s.
MonadIO m =>
NominalDiffTime -> m (Delayer s)
mkEmptyDelayer NominalDiffTime
timeout) ComponentSpec'
  state
  query
  action
  slots
  input
  output
  m
  (DelayedStateT state (HalogenM state action slots output m))
cs

mkDebouncedComponent'
  :: forall state query action slots input output m
   . Delayer state
  -> ComponentSpec' state query action slots input output m (DelayedStateT state (HalogenM state action slots output m))
  -> Component query input output m
mkDebouncedComponent' :: forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *).
Delayer state
-> ComponentSpec'
     state
     query
     action
     slots
     input
     output
     m
     (DelayedStateT state (HalogenM state action slots output m))
-> Component query input output m
mkDebouncedComponent' Delayer state
delayer ComponentSpec {HalogenQ query action input
~> DelayedStateT state (HalogenM state action slots output m)
state -> HTML (ComponentSlot slots m action) action
input -> m state
initialState :: input -> m state
render :: state -> HTML (ComponentSlot slots m action) action
eval :: HalogenQ query action input
~> DelayedStateT state (HalogenM state action slots output m)
eval :: forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *) (n :: * -> *).
ComponentSpec' state query action slots input output m n
-> HalogenQ query action input ~> n
initialState :: forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *) (n :: * -> *).
ComponentSpec' state query action slots input output m n
-> input -> m state
render :: forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *) (n :: * -> *).
ComponentSpec' state query action slots input output m n
-> state -> HTML (ComponentSlot slots m action) action
..} =
  ComponentSpec state query action slots input output m
-> Component query input output m
forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *).
ComponentSpec state query action slots input output m
-> Component query input output m
mkComponent
    (ComponentSpec state query action slots input output m
 -> Component query input output m)
-> ComponentSpec state query action slots input output m
-> Component query input output m
forall a b. (a -> b) -> a -> b
$ ComponentSpec
      { initialState :: input -> m state
initialState = input -> m state
initialState
      , render :: state -> HTML (ComponentSlot slots m action) action
render = state -> HTML (ComponentSlot slots m action) action
render
      , eval :: HalogenQ query action input ~> HalogenM state action slots output m
eval = (forall a.
 HalogenQ query action input a
 -> HalogenM state action slots output m a)
-> HalogenQ query action input
   ~> HalogenM state action slots output m
forall {k} (m :: k -> *) (n :: k -> *).
(forall (a :: k). m a -> n a) -> m ~> n
NT ((forall a.
  HalogenQ query action input a
  -> HalogenM state action slots output m a)
 -> HalogenQ query action input
    ~> HalogenM state action slots output m)
-> (forall a.
    HalogenQ query action input a
    -> HalogenM state action slots output m a)
-> HalogenQ query action input
   ~> HalogenM state action slots output m
forall a b. (a -> b) -> a -> b
$ Delayer state
-> DelayedStateT state (HalogenM state action slots output m) a
-> HalogenM state action slots output m a
forall (m :: * -> *) s a.
Monad m =>
Delayer s -> DelayedStateT s m a -> m a
runDelayedStateT Delayer state
delayer (DelayedStateT state (HalogenM state action slots output m) a
 -> HalogenM state action slots output m a)
-> (HalogenQ query action input a
    -> DelayedStateT state (HalogenM state action slots output m) a)
-> HalogenQ query action input a
-> HalogenM state action slots output m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HalogenQ query action input
 ~> DelayedStateT state (HalogenM state action slots output m))
-> HalogenQ query action input a
-> DelayedStateT state (HalogenM state action slots output m) a
forall {k} (m :: k -> *) (n :: k -> *) (a :: k).
(m ~> n) -> m a -> n a
runNT HalogenQ query action input
~> DelayedStateT state (HalogenM state action slots output m)
eval
      }