Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ui_effect_intf.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167open!BasemoduletypeHandler=sigmoduleAction:sigtypetendvalhandle:Action.t->unitendmoduletypeHandler1=sigmoduleAction:sigtype'atendvalhandle:'aAction.t->on_response:('a->unit)->unitendmoduletypeS=sigtypeactiontype_tvalinject:action->unittendmoduletypeS1=sigtype'aactiontype_tvalinject:'aaction->'atendmoduletypeEffect=sigmoduletypeHandler=HandlermoduletypeS=S(** ['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'at=..type'at+=Ignore:unitt|Many:unittlist->unittincludeMonad.Swithtype'at:='at(** An effect that never completes *)valnever:'at(** 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. *)vallazy_:'atLazy.t->'at(** Prints the sexp when scheduled. *)valprint_s:Sexp.t->unitt(** [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. *)valof_sync_fun:('query->'result)->'query->'resultt(** Like [of_sync_fun] but with a pre-applied unit query. Side-effects in the function
will be run every time that the resulting effect is scheduled *)valof_thunk:(unit->'result)->'resulttmoduleDefine(Handler:Handler):Swithtypeaction:=Handler.Action.tandtype'at:='atmoduleDefine1(Handler:Handler1):S1withtype'aaction:='aHandler.Action.tandtype'at:='atmoduleExpert:sig(** [eval t ~f] runs the given effect, and calls [f] when the effect
completes. This function should not be called while constructing
effects; it's intended for use by libraries that actually schedule
effects, such as Bonsai, or Virtual_dom. *)valeval:'at->f:('a->unit)->unit(** [handle t] is the same as [eval t ~f:ignore] *)valhandle:unitt->unit(* We use this table for dispatching to the appropriate handler in an efficient way. *)typehide=T:('at*('a->unit))->hidevalhandlers:(hide->unit)Hashtbl.M(Int).tvalof_fun:f:(callback:('a->unit)->unit)->'atendmodulePrivate:sigmoduleCallback:sigtype'aeffect:='attype('a,'b)tvalmake:request:'a->on_response:('b->uniteffect)->('a,'b)tvalrequest:('a,'b)t->'avalrespond_to:('a,'b)t->'b->uniteffectendvalmake:request:'a->evaluator:(('a,'b)Callback.t->unit)->'btendmoduleFor_testing:sigmoduleSvar:sig(** You can think of an [Svar.t] as like an [Ivar.t] whose purpose is to allow us to
implement [of_svar] below.
(The difference between [Svar] and [Ivar] is that the former is synchronous. That
is, when [fill_if_empty] is called, it will directly call all of the handlers rather
than scheduling that they be called later. This semantics can be confusing to work
with in large-scale programs, as it means the control flow of your application hops
around a lot more. However, it does mean that you don't need a scheduler, so it's
easier to implement.) *)type'atvalcreate:unit->'atvalupon:'at->('a->unit)->unitvalfill_if_empty:'at->'a->unitvalpeek:'at->'aoptionend(** Create an effect from a function that returns an [Svar.t]. This is mostly useful in
testing, to emulate a ['query -> 'result Deferred.t] function that does not return
immediately. You may find [Query_response_tracker] a more convenient interface than
using [of_svar] directly.
*)valof_svar_fun:('query->'resultSvar.t)->'query->'resulttmoduleQuery_response_tracker:sig(** [Query_response_tracker] is an interface designed to make [of_svar] more
convenient to use. When the function returned by [of_query_response_tracker t] is
called (typically by your bonsai app), the query passed is stored within [t]. Your
test code can then call [maybe_respond] to cause those effects to 'become
determined'. *)type('q,'r)tvalcreate:unit->_ttype'rmaybe_respond=|No_response_yet|Respondof'rvalmaybe_respond:('q,'r)t->f:('q->'rmaybe_respond)->unitvalqueries_pending_response:('q,_)t->'qlistendvalof_query_response_tracker:('query,'result)Query_response_tracker.t->'query->'resulttendend