routing.go raw
1 // Package routing provides event routing services for the ORLY relay.
2 // It dispatches events to specialized handlers based on event kind.
3 package routing
4
5 import (
6 "next.orly.dev/pkg/nostr/encoders/event"
7 )
8
9 // Action indicates what to do after routing.
10 type Action int
11
12 const (
13 // Continue means continue to normal processing.
14 Continue Action = iota
15 // Handled means event was fully handled, return success.
16 Handled
17 // Error means an error occurred.
18 Error
19 )
20
21 // Result contains the routing decision.
22 type Result struct {
23 Action Action
24 Message string // Success or error message
25 Error error // Error if Action == Error
26 }
27
28 // ContinueResult returns a result indicating normal processing should continue.
29 func ContinueResult() Result {
30 return Result{Action: Continue}
31 }
32
33 // HandledResult returns a result indicating the event was fully handled.
34 func HandledResult(msg string) Result {
35 return Result{Action: Handled, Message: msg}
36 }
37
38 // ErrorResult returns a result indicating an error occurred.
39 func ErrorResult(err error) Result {
40 return Result{Action: Error, Error: err}
41 }
42
43 // Handler processes a specific event kind.
44 // authedPubkey is the authenticated pubkey of the connection (may be nil).
45 type Handler func(ev *event.E, authedPubkey []byte) Result
46
47 // KindCheck tests whether an event kind matches a category (e.g., ephemeral).
48 type KindCheck struct {
49 Name string
50 Check func(kind uint16) bool
51 Handler Handler
52 }
53
54 // Router dispatches events to specialized handlers.
55 type Router interface {
56 // Route checks if event should be handled specially.
57 Route(ev *event.E, authedPubkey []byte) Result
58
59 // Register adds a handler for a specific kind.
60 Register(kind uint16, handler Handler)
61
62 // RegisterKindCheck adds a handler for a kind category.
63 RegisterKindCheck(name string, check func(uint16) bool, handler Handler)
64 }
65
66 // DefaultRouter implements Router with a handler registry.
67 type DefaultRouter struct {
68 handlers map[uint16]Handler
69 kindChecks []KindCheck
70 }
71
72 // New creates a new DefaultRouter.
73 func New() *DefaultRouter {
74 return &DefaultRouter{
75 handlers: make(map[uint16]Handler),
76 kindChecks: make([]KindCheck, 0),
77 }
78 }
79
80 // Register adds a handler for a specific kind.
81 func (r *DefaultRouter) Register(kind uint16, handler Handler) {
82 r.handlers[kind] = handler
83 }
84
85 // RegisterKindCheck adds a handler for a kind category.
86 func (r *DefaultRouter) RegisterKindCheck(name string, check func(uint16) bool, handler Handler) {
87 r.kindChecks = append(r.kindChecks, KindCheck{
88 Name: name,
89 Check: check,
90 Handler: handler,
91 })
92 }
93
94 // Route checks if event should be handled specially.
95 func (r *DefaultRouter) Route(ev *event.E, authedPubkey []byte) Result {
96 // Check exact kind matches first (higher priority)
97 if handler, ok := r.handlers[ev.Kind]; ok {
98 return handler(ev, authedPubkey)
99 }
100
101 // Check kind property handlers (ephemeral, replaceable, etc.)
102 for _, kc := range r.kindChecks {
103 if kc.Check(ev.Kind) {
104 return kc.Handler(ev, authedPubkey)
105 }
106 }
107
108 return ContinueResult()
109 }
110
111 // HasHandler returns true if a handler is registered for the given kind.
112 func (r *DefaultRouter) HasHandler(kind uint16) bool {
113 if _, ok := r.handlers[kind]; ok {
114 return true
115 }
116 for _, kc := range r.kindChecks {
117 if kc.Check(kind) {
118 return true
119 }
120 }
121 return false
122 }
123