You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
3.2 KiB
122 lines
3.2 KiB
// Package routing provides event routing services for the ORLY relay. |
|
// It dispatches events to specialized handlers based on event kind. |
|
package routing |
|
|
|
import ( |
|
"git.mleku.dev/mleku/nostr/encoders/event" |
|
) |
|
|
|
// Action indicates what to do after routing. |
|
type Action int |
|
|
|
const ( |
|
// Continue means continue to normal processing. |
|
Continue Action = iota |
|
// Handled means event was fully handled, return success. |
|
Handled |
|
// Error means an error occurred. |
|
Error |
|
) |
|
|
|
// Result contains the routing decision. |
|
type Result struct { |
|
Action Action |
|
Message string // Success or error message |
|
Error error // Error if Action == Error |
|
} |
|
|
|
// ContinueResult returns a result indicating normal processing should continue. |
|
func ContinueResult() Result { |
|
return Result{Action: Continue} |
|
} |
|
|
|
// HandledResult returns a result indicating the event was fully handled. |
|
func HandledResult(msg string) Result { |
|
return Result{Action: Handled, Message: msg} |
|
} |
|
|
|
// ErrorResult returns a result indicating an error occurred. |
|
func ErrorResult(err error) Result { |
|
return Result{Action: Error, Error: err} |
|
} |
|
|
|
// Handler processes a specific event kind. |
|
// authedPubkey is the authenticated pubkey of the connection (may be nil). |
|
type Handler func(ev *event.E, authedPubkey []byte) Result |
|
|
|
// KindCheck tests whether an event kind matches a category (e.g., ephemeral). |
|
type KindCheck struct { |
|
Name string |
|
Check func(kind uint16) bool |
|
Handler Handler |
|
} |
|
|
|
// Router dispatches events to specialized handlers. |
|
type Router interface { |
|
// Route checks if event should be handled specially. |
|
Route(ev *event.E, authedPubkey []byte) Result |
|
|
|
// Register adds a handler for a specific kind. |
|
Register(kind uint16, handler Handler) |
|
|
|
// RegisterKindCheck adds a handler for a kind category. |
|
RegisterKindCheck(name string, check func(uint16) bool, handler Handler) |
|
} |
|
|
|
// DefaultRouter implements Router with a handler registry. |
|
type DefaultRouter struct { |
|
handlers map[uint16]Handler |
|
kindChecks []KindCheck |
|
} |
|
|
|
// New creates a new DefaultRouter. |
|
func New() *DefaultRouter { |
|
return &DefaultRouter{ |
|
handlers: make(map[uint16]Handler), |
|
kindChecks: make([]KindCheck, 0), |
|
} |
|
} |
|
|
|
// Register adds a handler for a specific kind. |
|
func (r *DefaultRouter) Register(kind uint16, handler Handler) { |
|
r.handlers[kind] = handler |
|
} |
|
|
|
// RegisterKindCheck adds a handler for a kind category. |
|
func (r *DefaultRouter) RegisterKindCheck(name string, check func(uint16) bool, handler Handler) { |
|
r.kindChecks = append(r.kindChecks, KindCheck{ |
|
Name: name, |
|
Check: check, |
|
Handler: handler, |
|
}) |
|
} |
|
|
|
// Route checks if event should be handled specially. |
|
func (r *DefaultRouter) Route(ev *event.E, authedPubkey []byte) Result { |
|
// Check exact kind matches first (higher priority) |
|
if handler, ok := r.handlers[ev.Kind]; ok { |
|
return handler(ev, authedPubkey) |
|
} |
|
|
|
// Check kind property handlers (ephemeral, replaceable, etc.) |
|
for _, kc := range r.kindChecks { |
|
if kc.Check(ev.Kind) { |
|
return kc.Handler(ev, authedPubkey) |
|
} |
|
} |
|
|
|
return ContinueResult() |
|
} |
|
|
|
// HasHandler returns true if a handler is registered for the given kind. |
|
func (r *DefaultRouter) HasHandler(kind uint16) bool { |
|
if _, ok := r.handlers[kind]; ok { |
|
return true |
|
} |
|
for _, kc := range r.kindChecks { |
|
if kc.Check(kind) { |
|
return true |
|
} |
|
} |
|
return false |
|
}
|
|
|