Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-mediator

In-process messaging for Pudu: requests, notifications, streams, pipeline behaviors, processors, and exception handling

0.1.0Apache-2.01

InstallClose

Notification.pudu

Pudu58 lines2.2 KB

GitHub ↗
1/** @Mediator.Notification.Kind — notifications delivered to every handler */2module PuduLangMediator.Notification34import PuduLangMediator.Context as Context5import PuduLangMediator.Message as Message6import PuduLangMediator as Messaging7import PuduLangMediator.Utils.Erasure as Erasure89/** @Mediator.Notification.Handler — receives one notification */10export type Handler[N, E] = fn(N, Context.Context) -> Messaging.Outcome[(), E]1112/** @Mediator.Notification.Named — a handler with the name publishers report it by */13export type Named[N, E] = { name: Str, handle: Handler[N, E] }1415/** @Mediator.Notification.Route — every handler registered for one kind */16export type Route[N, E] = { handlers: Array[Named[N, E]] }1718/** @Mediator.Notification.Kind — the typed identity of one notification */19export type Kind[N, E] = {20  info: Message.Info,21  routes: Erasure.Slot[Route[N, E]],22  invokers: Erasure.Slot[Handler[N, E]],23  notifications: Erasure.Slot[N],24  outcomes: Erasure.Slot[Messaging.Outcome[(), E]]25}2627/// A kind of notification whose handlers fail with `E`. Make each kind once and share it.28export fn kind[N, E](name: Str) -> Kind[N, E] {29  Kind {30    info: Message.Info{name: name, shape: Message.Event, tags: []},31    routes: Erasure.slot(),32    invokers: Erasure.slot(),33    notifications: Erasure.slot(),34    outcomes: Erasure.slot()35  }36}3738/// The same kind carrying `tags` as well, which open components may read.39export fn tagged[N, E](subject: &Kind[N, E], tags: Array[Str]) -> Kind[N, E] {40  Kind{..*subject, info: Message.Info{..subject.info, tags: subject.info.tags.concat(tags)}}41}4243/// A route with no handlers.44export fn route[N, E]() -> Route[N, E] { Route{handlers: []} }4546/// An envelope carrying `notification`, for a publisher that does not name its type.47export fn envelope[N, E](subject: &Kind[N, E], notification: N) -> Message.Envelope {48  Message.sealed(&subject.info, &subject.notifications, notification)49}5051/// The outcome an answer holds, when this kind answered it; a publication nobody heard succeeded.52export fn answerOf[N, E](subject: &Kind[N, E], answer: &Message.Answer) -> Option[Messaging.Outcome[(), E]] {53  match answer.delivery {54    case Message.Unheard if answer.info.name == subject.info.name => Some(Ok(()))55    case _ => Message.read(&subject.outcomes, answer)56  }57}58