
Notification.pudu
Pudu58 lines2.2 KB
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}262728export 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}373839export 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}424344export fn route[N, E]() -> Route[N, E] { Route{handlers: []} }454647export fn envelope[N, E](subject: &Kind[N, E], notification: N) -> Message.Envelope {48 Message.sealed(&subject.info, &subject.notifications, notification)49}505152export 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