Packages
Event-Hub is a Gleam library that provides simple hubs with publishers and subscribers for event-driven observers. It supports asynchronous message handling and event notifications, decoupling components efficiently. It works on Erlang and JavaScript.
Current section
Files
Jump to
Current section
Files
src/event_hub@stateful.erl
-module(event_hub@stateful).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-define(FILEPATH, "src/event_hub/stateful.gleam").
-export([new/2, state/1, notify/2, subscribe/3]).
-export_type([hub/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" The `stateful` module provides a way to manage and notify subscribers about events based on a mutable state.\n"
" It supports creating observers that can maintain and update state, which can be useful for handling stateful events\n"
" in an application.\n"
"\n"
" ## Examples\n"
"\n"
" ### Stateful Observer\n"
" ```gleam\n"
" import gleam/io\n"
" import event_hub/stateful\n"
" \n"
" pub fn main() {\n"
" use hub <- stateful.new(\"initial state\")\n"
" let #(current_state, unsubscribe) =\n"
" stateful.subscribe(hub, True, fn(value) {\n"
" io.println(\"Received initial state: \" <> value)\n"
" })\n"
" \n"
" io.println(\"Current state: \" <> current_state)\n"
" \n"
" stateful.notify(hub, \"new state\")\n"
" \n"
" unsubscribe()\n"
" stateful.notify(hub, \"final state\")\n"
" }\n"
" ```\n"
).
-type hub(EFH) :: any() | {gleam_phantom, EFH}.
-file("src/event_hub/stateful.gleam", 86).
?DOC(
" Creates a new stateful observer hub with an initial state, executes the given context with the hub, and stops the hub afterward.\n"
"\n"
" ## Parameters\n"
" - `value`: The initial state value.\n"
" - `context`: A function that takes the created `Hub` and returns a result.\n"
"\n"
" ## Returns\n"
" The result of executing the context function.\n"
"\n"
" ## Example\n"
" ```gleam\n"
" import event_hub/stateful\n"
"\n"
" pub fn example() {\n"
" stateful.new(\"initial state\", fn(hub) {\n"
" // Use the hub\n"
" Nil\n"
" })\n"
" }\n"
" ```\n"
).
-spec new(EFV, fun((hub(EFV)) -> EFX)) -> EFX.
new(Value, Context) ->
Hub = event_hub_ffi:start_stateful(Value),
Result = Context(Hub),
event_hub_ffi:stop_stateful(Hub),
Result.
-file("src/event_hub/stateful.gleam", 114).
?DOC(
" Retrieves the current state of the hub.\n"
"\n"
" ## Parameters\n"
" - `hub`: The `Hub` to retrieve the state from.\n"
"\n"
" ## Returns\n"
" The current state value.\n"
"\n"
" ## Example\n"
" ```gleam\n"
" import event_hub/stateful\n"
"\n"
" pub fn example(hub: stateful.Hub(String)) {\n"
" let current_state = stateful.state(hub)\n"
" }\n"
" ```\n"
).
-spec state(hub(EFY)) -> EFY.
state(Hub) ->
event_hub_ffi:current_state(Hub).
-file("src/event_hub/stateful.gleam", 133).
?DOC(
" Notifies subscribers of the hub about an event with a new state value.\n"
" These notifications occur in parallel but `notify` waits for all of them to complete.\n"
"\n"
" ## Parameters\n"
" - `hub`: The `Hub` to notify.\n"
" - `value`: The new state value.\n"
"\n"
" ## Example\n"
" ```gleam\n"
" import event_hub/stateful\n"
"\n"
" pub fn example(hub: stateful.Hub(String)) {\n"
" stateful.notify(hub, \"new state\")\n"
" }\n"
" ```\n"
).
-spec notify(hub(EGA), EGA) -> nil.
notify(Hub, Value) ->
event_hub_ffi:invoke_stateful(Hub, Value).
-file("src/event_hub/stateful.gleam", 164).
?DOC(
" Subscribes to state changes and returns the current state and an unsubscribe function.\n"
" The callback will be invoked with the current state value when `notify` is called.\n"
" If `notify_current_state` is `True`, the callback will be immediately invoked with the current state.\n"
"\n"
" ## Parameters\n"
" - `hub`: The `Hub` to add the callback to.\n"
" - `notify_current_state`: Whether to immediately invoke the callback with the current state.\n"
" - `callback`: The callback function to invoke with the state value.\n"
"\n"
" ## Returns\n"
" A tuple containing the current state value and an `Unsubscribe` function that can be called to remove the callback.\n"
"\n"
" ## Example\n"
" ```gleam\n"
" import gleam/io\n"
" import event_hub/stateful\n"
" \n"
" pub fn example(hub: stateful.Hub(String)) {\n"
" let #(current_state, unsubscribe) =\n"
" stateful.subscribe(hub, True, fn(value) {\n"
" io.println(\"Received state: \" <> value)\n"
" })\n"
" \n"
" // To unsubscribe\n"
" unsubscribe()\n"
" }\n"
" ```\n"
).
-spec subscribe(hub(EGC), boolean(), fun((EGC) -> nil)) -> {EGC, fun(() -> nil)}.
subscribe(Hub, Notify_current_state, Callback) ->
case Notify_current_state of
true ->
Current_state = state(Hub),
Callback(Current_state);
false ->
nil
end,
{Value, Index} = event_hub_ffi:add_stateful(Hub, Callback),
Unsubscribe = fun() -> event_hub_ffi:remove_stateful(Hub, Index) end,
{Value, Unsubscribe}.