
Catalog.pudu
Pudu141 lines5.1 KB
1/** @Mediator.Catalog.Registry — every registration gathered before a build */2module PuduLangMediator.Catalog34import Std.HashMap as HashMap5import PuduLangMediator.Context as Context6import PuduLangMediator.Domain.Census as Census7import PuduLangMediator.Domain.Order as Order8import PuduLangMediator.Message as Message9import PuduLangMediator.Open as Open10import PuduLangMediator.Publishing as Publishing11import PuduLangMediator.Utils.Erasure as Erasure1213/** @Mediator.Catalog.Scope — which failures exception actions observe */14export type Scope = ForUnhandled | ForAll1516/** @Mediator.Catalog.Assembly — the open components and options every kind is built with */17export type Assembly = {18 marks: Array[Order.Mark],19 behaviors: Array[dynamic Open.Behavior],20 preProcessors: Array[dynamic Open.PreProcessor],21 postProcessors: Array[dynamic Open.PostProcessor],22 exceptionActions: Array[dynamic Open.ExceptionAction],23 listeners: Array[Open.Listener],24 streamBehaviors: Array[dynamic Open.StreamBehavior],25 publisher: dynamic Publishing.Strategy,26 actionScope: Scope27}2829/** @Mediator.Catalog.Dispatch — how an envelope of one kind is answered */30export type Dispatch31 = Answering(fn(Message.Envelope, Context.Context) -> Message.Answer)32 | Streaming(fn(Message.Envelope, Context.Context, fn(Erasure.Packed) -> Bool) -> Message.Answer)3334/** @Mediator.Catalog.Compiled — one kind's composed pipeline, typed and untyped */35export type Compiled = { info: Message.Info, invoke: Erasure.Packed, dispatch: Dispatch }3637/** @Mediator.Catalog.Entry — one kind's registrations, counted, before composition */38export type Entry = {39 info: Message.Info,40 route: Erasure.Packed,41 handlers: Int,42 components: Int,43 collisions: Int,44 finish: fn(Erasure.Packed, Assembly) -> Compiled45}4647/** @Mediator.Catalog.Catalog — the registrations of one mediator, by shape and name */48export type Catalog = {49 requests: HashMap.HashMap[Str, Entry],50 notifications: HashMap.HashMap[Str, Entry],51 streams: HashMap.HashMap[Str, Entry],52 assembly: Assembly53}545556export fn empty(publisher: dynamic Publishing.Strategy, actionScope: Scope) -> Catalog {57 Catalog {58 requests: HashMap.empty(),59 notifications: HashMap.empty(),60 streams: HashMap.empty(),61 assembly: Assembly {62 marks: [],63 behaviors: [],64 preProcessors: [],65 postProcessors: [],66 exceptionActions: [],67 listeners: [],68 streamBehaviors: [],69 publisher: publisher,70 actionScope: actionScope71 }72 }73}747576777879export fn touch[R](80 table: &HashMap.HashMap[Str, Entry],81 info: &Message.Info,82 routes: &Erasure.Slot[R],83 blank: R,84 change: fn(R) -> R,85 handlers: Int,86 components: Int,87 finish: fn(Erasure.Packed, Assembly) -> Compiled88) -> HashMap.HashMap[Str, Entry] {89 let name = info.name90 match HashMap.get(table, &name) {91 case None => {92 HashMap.insert(table, name, Entry{info: *info, route: Erasure.pack(routes, change(blank)), handlers: handlers, components: components, collisions: 0, finish: finish})93 }94 case Some(entry) => {95 match Erasure.unpack(routes, &entry.route) {96 case Some(route) => {97 HashMap.insert(table, name, Entry {98 ..entry,99 route: Erasure.pack(routes, change(route)),100 handlers: entry.handlers + handlers,101 components: entry.components + components102 })103 }104 case None => HashMap.insert(table, name, Entry{..entry, collisions: entry.collisions + 1})105 }106 }107 }108}109110111export fn marked(catalog: Catalog, layer: Order.Layer, name: Str) -> Catalog {112 Catalog{..catalog, assembly: Assembly{..catalog.assembly, marks: catalog.assembly.marks.push(Order.Closed(layer, name))}}113}114115116export fn problems(catalog: &Catalog) -> Array[Str] {117 var found: Array[Str] = []118 for table in [catalog.requests, catalog.notifications, catalog.streams] {119 for entry in HashMap.values(&table) {120 let single = entry.info.shape != Message.Event121 found = found.concat(Census.problems(&Census.Census {122 name: entry.info.name,123 handlers: entry.handlers,124 components: entry.components,125 collisions: entry.collisions,126 single: single127 }))128 }129 }130 found131}132133134export fn compile(table: &HashMap.HashMap[Str, Entry], assembly: &Assembly) -> HashMap.HashMap[Str, Compiled] {135 var compiled: HashMap.HashMap[Str, Compiled] = HashMap.empty()136 for entry in HashMap.values(table) {137 compiled = HashMap.insert(&compiled, entry.info.name, (entry.finish)(entry.route, *assembly))138 }139 compiled140}141