Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 54s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
77 lines
2.4 KiB
Plaintext
77 lines
2.4 KiB
Plaintext
; feed/dedupe — collapse duplicate items, keeping first occurrence per key.
|
|
; Each verb may want its own key (see briefing): "alice posted X" keys on
|
|
; (actor verb object) — distinct per actor; "alice liked X / bob liked X"
|
|
; collapse on (verb object) so the cross-actor likes fold into one.
|
|
;
|
|
; Requires: lib/feed/normalize.sx, lib/feed/stream.sx, lib/feed/fanout.sx
|
|
; (feed/-elem? lives in fanout.sx).
|
|
|
|
; generic: dedupe a stream by key-fn, first occurrence wins (stable)
|
|
(define
|
|
feed/-dedup-by
|
|
(fn
|
|
(items key-fn)
|
|
(get
|
|
(reduce
|
|
(fn
|
|
(st x)
|
|
(let
|
|
((k (key-fn x)))
|
|
(if (feed/-elem? k (get st :seen)) st {:seen (append (get st :seen) (list k)) :out (append (get st :out) (list x))})))
|
|
{:seen (list) :out (list)}
|
|
items)
|
|
:out)))
|
|
|
|
(define
|
|
feed/dedupe
|
|
(fn
|
|
(stream key-fn)
|
|
(feed/stream (feed/-dedup-by (feed/items stream) key-fn))))
|
|
|
|
; --- keys -------------------------------------------------------------------
|
|
|
|
(define
|
|
feed/activity-key
|
|
(fn (a) (list (get a :actor) (get a :verb) (get a :object))))
|
|
|
|
; collapse cross-actor duplicates of the same verb+object (e.g. likes)
|
|
(define feed/collapse-key (fn (a) (list (get a :verb) (get a :object))))
|
|
|
|
; per-receiver inbox key — one inbox event per (receiver, actor, verb, object)
|
|
(define
|
|
feed/event-key
|
|
(fn
|
|
(ev)
|
|
(let
|
|
((a (get ev :activity)))
|
|
(list (get ev :to) (get a :actor) (get a :verb) (get a :object)))))
|
|
|
|
; verbs whose duplicates collapse across actors (reactions, not authorship).
|
|
; rebindable: callers can (set! feed/collapse-verbs ...) to tune the policy.
|
|
(define
|
|
feed/collapse-verbs
|
|
(list "like" "favourite" "follow" "boost" "repost"))
|
|
|
|
; per-verb key: collapse-verbs fold on (verb object); the rest key on
|
|
; (actor verb object).
|
|
(define
|
|
feed/smart-key
|
|
(fn
|
|
(a)
|
|
(if
|
|
(feed/-elem? (get a :verb) feed/collapse-verbs)
|
|
(feed/collapse-key a)
|
|
(feed/activity-key a))))
|
|
|
|
; --- ready-made dedupers ----------------------------------------------------
|
|
|
|
(define feed/dedupe-activities (fn (s) (feed/dedupe s feed/activity-key)))
|
|
|
|
(define feed/dedupe-collapse (fn (s) (feed/dedupe s feed/collapse-key)))
|
|
|
|
; verb-aware: reactions collapse cross-actor, posts stay distinct per actor
|
|
(define feed/dedupe-smart (fn (s) (feed/dedupe s feed/smart-key)))
|
|
|
|
; dedupe an inbox: at most one event per receiver per (actor verb object)
|
|
(define feed/dedupe-inbox (fn (inbox) (feed/dedupe inbox feed/event-key)))
|