; feed/notify — a notification feed is a thin layer over a recipient's inbox: ; the events directed at a user, optionally verb-filtered, and a digest that ; collapses "alice, bob and 1 other liked X" by (verb, object). ; ; Requires: lib/feed/normalize.sx, lib/feed/stream.sx, lib/feed/fanout.sx ; (feed/inbox-for, feed/-elem?). ; all inbox events for a user (their raw notifications) (define feed/notifications (fn (inbox user) (feed/inbox-for inbox user))) ; restrict to notification-worthy verbs (e.g. (list "like" "reply" "follow")) (define feed/notify-verbs (fn (inbox user verbs) (feed/filter (feed/inbox-for inbox user) (fn (ev) (feed/-elem? (get (get ev :activity) :verb) verbs))))) ; group key "verb|object" — deterministic, sortable (define feed/-notify-key (fn (ev) (let ((a (get ev :activity))) (string-append (get a :verb) "|" (get a :object))))) ; digest: one entry per (verb, object) with the distinct actors and a count, ; ordered by key for determinism. (define feed/notify-digest (fn (inbox user) (let ((events (feed/items (feed/inbox-for inbox user)))) (let ((groups (reduce (fn (g ev) (let ((a (get ev :activity)) (k (feed/-notify-key ev))) (let ((cur (get g k {:object (get a :object) :actors (list) :verb (get a :verb)}))) (assoc g k (assoc cur :actors (append (get cur :actors) (list (get a :actor)))))))) {} events))) (map (fn (k) (let ((grp (get groups k))) (assoc grp :count (len (get grp :actors))))) (sort (keys groups)))))))