Finished event to subgraph conversion.
Wrote expander pattern for custom rules.
This commit is contained in:
7
event.go
7
event.go
@@ -4,7 +4,7 @@ import (
|
|||||||
roots "git.wisehodl.dev/jay/go-roots/events"
|
roots "git.wisehodl.dev/jay/go-roots/events"
|
||||||
)
|
)
|
||||||
|
|
||||||
func EventToSubgraph(e roots.Event) *Subgraph {
|
func EventToSubgraph(e roots.Event, exp ExpanderRegistry) *Subgraph {
|
||||||
subgraph := NewSubgraph()
|
subgraph := NewSubgraph()
|
||||||
|
|
||||||
// Create Event node
|
// Create Event node
|
||||||
@@ -45,6 +45,11 @@ func EventToSubgraph(e roots.Event) *Subgraph {
|
|||||||
subgraph.AddRel(rel)
|
subgraph.AddRel(rel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run expanders
|
||||||
|
for _, expander := range exp {
|
||||||
|
expander(e, subgraph)
|
||||||
|
}
|
||||||
|
|
||||||
return subgraph
|
return subgraph
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,11 +83,79 @@ func TestEventToSubgraph(t *testing.T) {
|
|||||||
return s
|
return s
|
||||||
}(),
|
}(),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "e tag with valid hex64",
|
||||||
|
event: roots.Event{
|
||||||
|
ID: ids["a"], PubKey: ids["b"],
|
||||||
|
CreatedAt: static.CreatedAt, Kind: static.Kind, Content: static.Content,
|
||||||
|
Tags: []roots.Tag{{"e", ids["c"]}},
|
||||||
|
},
|
||||||
|
expected: func() *Subgraph {
|
||||||
|
s, eventNode, _ := baseSubgraph(ids["a"], ids["b"])
|
||||||
|
tagNode := NewTagNode("e", ids["c"])
|
||||||
|
referencedEvent := NewEventNode(ids["c"])
|
||||||
|
s.AddNode(tagNode)
|
||||||
|
s.AddNode(referencedEvent)
|
||||||
|
s.AddRel(NewTaggedRel(eventNode, tagNode, nil))
|
||||||
|
s.AddRel(NewReferencesEventRel(tagNode, referencedEvent, nil))
|
||||||
|
return s
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "e tag with invalid value",
|
||||||
|
event: roots.Event{
|
||||||
|
ID: ids["a"], PubKey: ids["b"],
|
||||||
|
CreatedAt: static.CreatedAt, Kind: static.Kind, Content: static.Content,
|
||||||
|
Tags: []roots.Tag{{"e", "notvalid"}},
|
||||||
|
},
|
||||||
|
expected: func() *Subgraph {
|
||||||
|
s, eventNode, _ := baseSubgraph(ids["a"], ids["b"])
|
||||||
|
tagNode := NewTagNode("e", "notvalid")
|
||||||
|
s.AddNode(tagNode)
|
||||||
|
s.AddRel(NewTaggedRel(eventNode, tagNode, nil))
|
||||||
|
return s
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "p tag with valid hex64",
|
||||||
|
event: roots.Event{
|
||||||
|
ID: ids["a"], PubKey: ids["b"],
|
||||||
|
CreatedAt: static.CreatedAt, Kind: static.Kind, Content: static.Content,
|
||||||
|
Tags: []roots.Tag{{"p", ids["d"]}},
|
||||||
|
},
|
||||||
|
expected: func() *Subgraph {
|
||||||
|
s, eventNode, _ := baseSubgraph(ids["a"], ids["b"])
|
||||||
|
tagNode := NewTagNode("p", ids["d"])
|
||||||
|
referencedUser := NewUserNode(ids["d"])
|
||||||
|
s.AddNode(tagNode)
|
||||||
|
s.AddNode(referencedUser)
|
||||||
|
s.AddRel(NewTaggedRel(eventNode, tagNode, nil))
|
||||||
|
s.AddRel(NewReferencesUserRel(tagNode, referencedUser, nil))
|
||||||
|
return s
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "p tag with invalid value",
|
||||||
|
event: roots.Event{
|
||||||
|
ID: ids["a"], PubKey: ids["b"],
|
||||||
|
CreatedAt: static.CreatedAt, Kind: static.Kind, Content: static.Content,
|
||||||
|
Tags: []roots.Tag{{"p", "notvalid"}},
|
||||||
|
},
|
||||||
|
expected: func() *Subgraph {
|
||||||
|
s, eventNode, _ := baseSubgraph(ids["a"], ids["b"])
|
||||||
|
tagNode := NewTagNode("p", "notvalid")
|
||||||
|
s.AddNode(tagNode)
|
||||||
|
s.AddRel(NewTaggedRel(eventNode, tagNode, nil))
|
||||||
|
return s
|
||||||
|
}(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expanders := GetDefaultExpanderRegistry()
|
||||||
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
got := EventToSubgraph(tc.event)
|
got := EventToSubgraph(tc.event, expanders)
|
||||||
assertSubgraphsEqual(t, tc.expected, got)
|
assertSubgraphsEqual(t, tc.expected, got)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
88
expanders.go
Normal file
88
expanders.go
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
package heartwood
|
||||||
|
|
||||||
|
import (
|
||||||
|
roots "git.wisehodl.dev/jay/go-roots/events"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Expander func(e roots.Event, s *Subgraph)
|
||||||
|
type ExpanderRegistry []Expander
|
||||||
|
|
||||||
|
func NewExpanderRegistry() ExpanderRegistry {
|
||||||
|
return []Expander{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDefaultExpanderRegistry() ExpanderRegistry {
|
||||||
|
registry := NewExpanderRegistry()
|
||||||
|
|
||||||
|
registry.Add(ExpandTaggedEvents)
|
||||||
|
registry.Add(ExpandTaggedUsers)
|
||||||
|
|
||||||
|
return registry
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ExpanderRegistry) Add(m Expander) {
|
||||||
|
*r = append(*r, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default Expander Functions
|
||||||
|
|
||||||
|
func ExpandTaggedEvents(e roots.Event, s *Subgraph) {
|
||||||
|
tagNodes := s.NodesByLabel("Tag")
|
||||||
|
for _, tag := range e.Tags {
|
||||||
|
if !isValidTag(tag) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name := tag[0]
|
||||||
|
value := tag[1]
|
||||||
|
|
||||||
|
if name != "e" || !roots.Hex64Pattern.MatchString(value) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
tagNode := findTagNode(tagNodes, name, value)
|
||||||
|
if tagNode == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
referencedEvent := NewEventNode(value)
|
||||||
|
|
||||||
|
s.AddNode(referencedEvent)
|
||||||
|
s.AddRel(NewReferencesEventRel(tagNode, referencedEvent, nil))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExpandTaggedUsers(e roots.Event, s *Subgraph) {
|
||||||
|
tagNodes := s.NodesByLabel("Tag")
|
||||||
|
for _, tag := range e.Tags {
|
||||||
|
if !isValidTag(tag) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name := tag[0]
|
||||||
|
value := tag[1]
|
||||||
|
|
||||||
|
if name != "p" || !roots.Hex64Pattern.MatchString(value) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
tagNode := findTagNode(tagNodes, name, value)
|
||||||
|
if tagNode == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
referencedEvent := NewUserNode(value)
|
||||||
|
|
||||||
|
s.AddNode(referencedEvent)
|
||||||
|
s.AddRel(NewReferencesUserRel(tagNode, referencedEvent, nil))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
|
||||||
|
func findTagNode(nodes []*Node, name, value string) *Node {
|
||||||
|
for _, node := range nodes {
|
||||||
|
if node.Props["name"] == name && node.Props["value"] == value {
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
10
graph.go
10
graph.go
@@ -199,6 +199,16 @@ func (s *Subgraph) Rels() []*Relationship {
|
|||||||
return s.rels
|
return s.rels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Subgraph) NodesByLabel(label string) []*Node {
|
||||||
|
nodes := []*Node{}
|
||||||
|
for _, node := range s.nodes {
|
||||||
|
if node.Labels.Contains(label) {
|
||||||
|
nodes = append(nodes, node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nodes
|
||||||
|
}
|
||||||
|
|
||||||
// ========================================
|
// ========================================
|
||||||
// Structured Subgraph
|
// Structured Subgraph
|
||||||
// ========================================
|
// ========================================
|
||||||
|
|||||||
Reference in New Issue
Block a user