sig
  module type PCLOCK =
    sig
      val now_d_ps : unit -> int * int64
      val period_d_ps : unit -> (int * int64) option
      val current_tz_offset_s : unit -> int option
    end
  module type MCLOCK =
    sig
      type ns_span = int64
      val elapsed_ns : unit -> Tick.MCLOCK.ns_span
      val period_ns : unit -> Tick.MCLOCK.ns_span option
    end
  module type MTICK =
    sig
      type ns_span = int64
      val tock :
        delay_ns:Tick.MTICK.ns_span -> (Tick.MTICK.ns_span -> unit) -> unit
    end
  module type LIFECYCLE =
    sig
      type 'a event
      type watcher
      val watch :
        'Tick.LIFECYCLE.event -> ('-> unit) -> Tick.LIFECYCLE.watcher
      val unwatch : Tick.LIFECYCLE.watcher -> unit
      val poweron : unit Tick.LIFECYCLE.event
      val poweroff : unit Tick.LIFECYCLE.event
      val suspend : unit Tick.LIFECYCLE.event
      val resume : unit Tick.LIFECYCLE.event
    end
  module type KV =
    sig
      type 'a codec =
          ('-> string) * (string -> ('a, Rresult.R.msg) Rresult.result)
      exception Decode_error of string * Rresult.R.msg
      type 'a key
      val key : string -> 'Tick.KV.codec -> 'Tick.KV.key
      val key_name : 'Tick.KV.key -> string
      val key_codec : 'Tick.KV.key -> 'Tick.KV.codec
      val mem : 'Tick.KV.key -> bool
      val find : 'Tick.KV.key -> 'a option
      val get : ?absent:'-> 'Tick.KV.key -> 'a
      val set : 'Tick.KV.key -> 'a option -> unit
      type watcher
      val watch :
        'Tick.KV.key ->
        ('Tick.KV.key -> 'a option -> unit) -> Tick.KV.watcher
      val unwatch : Tick.KV.watcher -> unit
    end
  module type WATCHER =
    sig
      type span_ns = int64
      type trigger
      type t
      val watch :
        delay_ns:Tick.WATCHER.span_ns ->
        Tick.WATCHER.trigger -> Tick.WATCHER.t
      val unwatch : Tick.WATCHER.t -> unit
      val waiting : Tick.WATCHER.t -> bool
      val linger_ns : Tick.WATCHER.t -> Tick.WATCHER.span_ns
      val delay_ns : Tick.WATCHER.t -> Tick.WATCHER.span_ns
      val trigger : Tick.WATCHER.t -> Tick.WATCHER.trigger
      val fold : ('-> Tick.WATCHER.t -> 'a) -> '-> 'a
    end
  module type WATCHER_FUN =
    sig
      type t
      type trigger = Tick.WATCHER_FUN.t -> unit
      type span_ns = int64
      val watch : delay_ns:span_ns -> trigger -> t
      val unwatch : t -> unit
      val waiting : t -> bool
      val linger_ns : t -> span_ns
      val delay_ns : t -> span_ns
      val trigger : t -> trigger
      val fold : ('-> t -> 'a) -> '-> 'a
    end
  module Make_unreliable : functor (M : MCLOCK) (MT : MTICK-> WATCHER_FUN
  module Make_suspension_resistant :
    functor (P : PCLOCK) (M : MCLOCK) (MT : MTICK) (E : LIFECYCLE->
      WATCHER_FUN
  module type PERSISTENT_TRIGGER =
    sig
      type t
      val actuate : int64 -> int64 -> Tick.PERSISTENT_TRIGGER.t -> unit
      val codec :
        (Tick.PERSISTENT_TRIGGER.t -> string) *
        (string -> (Tick.PERSISTENT_TRIGGER.t, Rresult.R.msg) Rresult.result)
    end
  module Make_poweroff_resistant :
    functor
      (P : PCLOCK) (M : MCLOCK) (MT : MTICK) (E : LIFECYCLE) (T : PERSISTENT_TRIGGER) (Kv : KV->
      sig
        type span_ns = int64
        type trigger = T.t
        type t
        val watch : delay_ns:span_ns -> trigger -> t
        val unwatch : t -> unit
        val waiting : t -> bool
        val linger_ns : t -> span_ns
        val delay_ns : t -> span_ns
        val trigger : t -> trigger
        val fold : ('-> t -> 'a) -> '-> 'a
      end
end