-module(roar). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/roar.gleam"). -export([new/2, on/3, subscribe/2, publish/3]). -export_type([roar/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. -opaque roar(DRW) :: {roar, whisper:whisper(DRW), binary()}. -file("src/roar.gleam", 33). ?DOC( " Create a new distributed pub/sub router.\n" "\n" " - `capacity`: Maximum number of messages buffered per subscription\n" " - `scope`: Unique identifier for this router's cluster scope. Only routers\n" " with matching scopes will exchange messages across nodes.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " let router = roar.new(capacity: 50, scope: \"chat_system\")\n" " ```\n" ). -spec new(integer(), binary()) -> roar(any()). new(Capacity, Scope) -> {roar, whisper:new(Capacity), Scope}. -file("src/roar.gleam", 52). ?DOC( " Register a callback function to be invoked when messages are published to a topic.\n" "\n" " The callback is triggered for messages published locally and from remote nodes\n" " in the same scope. Returns a cancellation function to stop listening.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " let cancel = roar.on(router, \"notifications\", fn(msg) {\n" " io.println(\"Received: \" <> msg)\n" " })\n" "\n" " // Later, stop listening\n" " cancel()\n" " ```\n" ). -spec on(roar(DRZ), binary(), fun((DRZ) -> nil)) -> fun(() -> nil). on(Roar, Topic, Listener) -> Local_cancel = whisper:on(erlang:element(2, Roar), Topic, Listener), Distributed_cancel = roar_ffi:on_distributed( erlang:element(3, Roar), Topic, Listener ), fun() -> Local_cancel(), Distributed_cancel() end. -file("src/roar.gleam", 87). ?DOC( " Subscribe to a topic and receive messages through a buffered subscription.\n" "\n" " Messages published locally or from remote nodes in the same scope are queued\n" " in the subscription buffer. Use the returned subscription's `receive` function\n" " to consume messages, and `cancel` to unsubscribe.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " let sub = roar.subscribe(router, \"events\")\n" "\n" " case sub.receive() {\n" " Ok(message) -> io.println(\"Got: \" <> message)\n" " Error(Nil) -> io.println(\"No messages available\")\n" " }\n" "\n" " sub.cancel()\n" " ```\n" ). -spec subscribe(roar(DSC), binary()) -> whisper:subscription(DSC). subscribe(Roar, Topic) -> Sub = whisper:subscribe(erlang:element(2, Roar), Topic), roar_ffi:subscribe_distributed( erlang:element(3, Roar), Topic, erlang:element(2, Roar) ), Sub. -file("src/roar.gleam", 112). ?DOC( " Publish a message to all subscribers of a topic across the cluster.\n" "\n" " The message is delivered to:\n" " - All local subscribers on this node\n" " - All subscribers on remote nodes in the same scope\n" "\n" " ## Example\n" "\n" " ```gleam\n" " roar.publish(router, \"alerts\", \"System maintenance in 5 minutes\")\n" " // All subscribers across all nodes receive this message\n" " ```\n" ). -spec publish(roar(DSH), binary(), DSH) -> nil. publish(Roar, Topic, Message) -> whisper:publish(erlang:element(2, Roar), Topic, Message), roar_ffi:publish_distributed(erlang:element(3, Roar), Topic, Message).