package bonsai

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type
include module type of Virtual_dom.Vdom.Effect
include module type of struct include Ui_effect end
module type Handler = Virtual_dom.Vdom.Effect.Handler
type 'a t = 'a Virtual_dom.Vdom.Effect.t = ..

'a Effect.t represents some computation of type 'a that can be performed outside of the typical computational/incremental structure of a Bonsai program . Examples of this computation might be:

  • Calling an RPC and getting the result back
  • Running expensive computation on a web-worker thread
  • Requesting some information from the imperative "Start.Handle"-holding code

If you have a value of type 'a Effect.t, you can schedule it to be run by calling inject and providing a function that will be called when the callback completes.

type t +=
  1. | Ignore : unit t
  2. | Many : unit t list -> unit t
include Core.Monad.S with type 'a t := 'a t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t

t >>= f returns a computation that sequences the computations represented by two monad elements. The resulting computation first does t to yield a value v, and then runs the computation returned by f v.

val (>>|) : 'a t -> ('a -> 'b) -> 'b t

t >>| f is t >>= (fun a -> return (f a)).

module Monad_infix = Ui_effect.Monad_infix
val bind : 'a t -> f:('a -> 'b t) -> 'b t

bind t ~f = t >>= f

val return : 'a -> 'a t

return v returns the (trivial) computation that returns v.

val map : 'a t -> f:('a -> 'b) -> 'b t

map t ~f is t >>| f.

val join : 'a t t -> 'a t

join t is t >>= (fun t' -> t').

val ignore_m : 'a t -> unit t

ignore_m t is map t ~f:(fun _ -> ()). ignore_m used to be called ignore, but we decided that was a bad name, because it shadowed the widely used Caml.ignore. Some monads still do let ignore = ignore_m for historical reasons.

val all : 'a t list -> 'a list t
val all_unit : unit t list -> unit t

Like all, but ensures that every monadic value in the list produces a unit value, all of which are discarded rather than being collected into a list.

module Let_syntax = Ui_effect.Let_syntax
val never : 'a t

An effect that never completes

val lazy_ : 'a t Core.Lazy.t -> 'a t

If creating an effect could be expensive, you can wrap its construction in a lazy and pass it to this function so that its construction will be deferred until it's about to be evaluated.

val print_s : Core.Sexp.t -> unit t

Prints the sexp when scheduled.

val of_sync_fun : ('query -> 'result) -> 'query -> 'result t

of_sync_fun is similar to of_deferred_fun but with a synchronous function instead of a deferred one. This can be used for functions that are synchronous but side-effecting, or as a mock-function in tests that replace the usages of of_deferred_fun in the actual app.

Note that, unlike of_deferred_fun, the function must return immediately, so it's not possible to test the behaviour of tour app between calling the function and the effect becoming 'determined'. If you need to do this, see of_svar and of_query_response_tracker below.

module Define = Ui_effect.Define
module Define1 = Ui_effect.Define1
module Private = Ui_effect.Private
module For_testing = Ui_effect.For_testing
module type Visibility_handler = Virtual_dom.Vdom.Effect.Visibility_handler
type t +=
  1. | Viewport_changed
    (*

    Viewport_changed events are delivered to all visibility handlers

    *)
  2. | Stop_propagation
    (*

    Stop_propagation prevents the underlying DOM event from propagating up to the parent elements

    *)
  3. | Stop_immediate_propagation
    (*

    Stop_immediate_propagation causes sequence_as_sibling to ignore next sequenced event.

    *)
  4. | Prevent_default
    (*

    Prevent_default prevents the default browser action from occurring as a result of this event

    *)
val sequence_as_sibling : unit t -> unless_stopped:(unit -> unit t) -> unit t

Sequences two events, but only if the first is neither Stop_immediate_propagation nor a Many which contains Stop_immediate_propagation. Use this instead of Many if combining events that are associated with the same source; for example, the motivation for this function is for merging Inputs of hooks.

The second argument is a function that takes unit not because it is expected to be impure, but because often it is computed via some arbitrary handler function. Using hooks as an example, often the input to a hook has type 'a -> Effect.t. To merge inputs f and g, you might write

fun x -> sequence_as_sibling (f x) (g x)

but this might unnecessarily call g if f returns something with Stop_immediate_propagation. Instead, using this API, you must write

fun x -> sequence_as_sibling (f x) (fun () -> (g x))

For registering a handler for Viewport_changed events. Note that if this functor is called multiple times, each handler will see all of the events.

val of_deferred_fun : ('query -> 'response Async_kernel.Deferred.t) -> 'query -> 'response t

of_deferred_fun is a way to convert from a deferred-returning function to an effect-returning function. This function is commonly used to wrap RPC calls. Memory is allocated permanently every time that of_deferred_fun is called, so be sure to re-use the function inside the Staged.t!