filter.go raw

   1  package relay
   2  
   3  import (
   4  	"git.mleku.dev/mleku/dendrite/pkg/axiom"
   5  	"git.mleku.dev/mleku/dendrite/pkg/nostr"
   6  )
   7  
   8  // CoherenceFilter rejects events whose decomposed elements don't bond
   9  // to any existing lattice structure. An event that produces zero
  10  // elements matching any known constraint is structurally incoherent
  11  // with the relay's content — noise, not signal.
  12  type CoherenceFilter struct {
  13  	// KnownTypes is the set of element type tags that the lattice
  14  	// currently has sites for. Events must produce at least one
  15  	// element with a type in this set to pass the filter.
  16  	KnownTypes map[string]bool
  17  }
  18  
  19  // Admits returns true if the event's decomposed elements include at
  20  // least one element type known to the lattice. An event that bonds
  21  // nowhere is spam — it has no structural relationship to the content
  22  // the relay serves.
  23  func (f *CoherenceFilter) Admits(ev *nostr.Event) bool {
  24  	if len(f.KnownTypes) == 0 {
  25  		return true // no filter configured → admit all
  26  	}
  27  
  28  	elems := nostr.EventToElements(ev)
  29  	for _, e := range elems {
  30  		if f.KnownTypes[e.Type()] {
  31  			return true
  32  		}
  33  	}
  34  	return false
  35  }
  36  
  37  // NewCoherenceFilter creates a filter from a set of constraints.
  38  // The filter admits events that produce elements matching any of
  39  // the constraint tags.
  40  func NewCoherenceFilter(constraints []axiom.Constraint) *CoherenceFilter {
  41  	types := make(map[string]bool, len(constraints))
  42  	for _, c := range constraints {
  43  		types[c.Tag()] = true
  44  	}
  45  	return &CoherenceFilter{KnownTypes: types}
  46  }
  47