enzyme.go raw

   1  package nostr
   2  
   3  import (
   4  	"fmt"
   5  	"strings"
   6  
   7  	"git.mleku.dev/mleku/dendrite/pkg/axiom"
   8  )
   9  
  10  // element is the concrete axiom.Element type for Nostr events.
  11  type element struct {
  12  	tag string
  13  	val any
  14  }
  15  
  16  func (e element) Type() string { return e.tag }
  17  func (e element) Value() any   { return e.val }
  18  
  19  // EventToElements decomposes a validated Nostr event into typed lattice
  20  // elements. Each event produces elements for its structural parts:
  21  // pubkey, kind, content words, tags, and references.
  22  func EventToElements(ev *Event) []axiom.Element {
  23  	var elems []axiom.Element
  24  
  25  	// The event itself.
  26  	elems = append(elems, element{"event", ev.ID[:16]})
  27  
  28  	// Author identity.
  29  	elems = append(elems, element{"pubkey", ev.Pubkey})
  30  
  31  	// Kind as a typed element.
  32  	elems = append(elems, element{"kind", fmt.Sprintf("%d", ev.Kind)})
  33  
  34  	// Content — decompose into words for bonding.
  35  	if ev.Content != "" {
  36  		words := strings.Fields(ev.Content)
  37  		for _, w := range words {
  38  			// Skip very short words.
  39  			if len(w) > 2 {
  40  				elems = append(elems, element{"word", w})
  41  			}
  42  		}
  43  		// Also emit the content as a literal for format-string absorption.
  44  		if len(ev.Content) > 10 && len(ev.Content) < 200 {
  45  			elems = append(elems, element{"literal", fmt.Sprintf("%q", ev.Content)})
  46  		}
  47  	}
  48  
  49  	// Tags — each tag becomes a typed element.
  50  	for _, tag := range ev.Tags {
  51  		if len(tag) < 2 {
  52  			continue
  53  		}
  54  		switch tag[0] {
  55  		case "e":
  56  			// Event reference.
  57  			elems = append(elems, element{"e-tag", tag[1]})
  58  		case "p":
  59  			// Pubkey mention.
  60  			elems = append(elems, element{"p-tag", tag[1]})
  61  		case "t":
  62  			// Hashtag.
  63  			elems = append(elems, element{"hashtag", tag[1]})
  64  		default:
  65  			// Generic tag.
  66  			elems = append(elems, element{"tag", tag[0] + ":" + tag[1]})
  67  		}
  68  	}
  69  
  70  	// Timestamp as a structural element.
  71  	elems = append(elems, element{"timestamp", fmt.Sprintf("%d", ev.CreatedAt)})
  72  
  73  	return elems
  74  }
  75