registry.go raw
1 //go:build !(js && wasm)
2
3 package sync
4
5 import (
6 "context"
7 "sort"
8 "sync"
9
10 "next.orly.dev/pkg/lol/errorf"
11 "next.orly.dev/pkg/database"
12 )
13
14 // DriverFactory is the signature for sync driver factory functions.
15 type DriverFactory func(ctx context.Context, db database.Database, cfg *DriverConfig) (Service, error)
16
17 // DriverConfig holds configuration for sync drivers.
18 type DriverConfig struct {
19 // Common settings
20 LogLevel string
21
22 // Negentropy-specific settings
23 TargetRelays []string
24 Filter string
25 SyncInterval string
26 BatchSize int
27
28 // Cluster-specific settings
29 AdminNpubs []string
30 PropagatePrivilegedEvents bool
31 PollInterval string
32
33 // Distributed-specific settings
34 NodeID string
35 RelayURL string
36 Peers []string
37
38 // Relay group settings
39 RelayGroups []string
40 }
41
42 // DriverInfo contains metadata about a registered sync driver.
43 type DriverInfo struct {
44 Name string
45 Description string
46 Factory DriverFactory
47 }
48
49 // Service is the interface that sync drivers must implement.
50 type Service interface {
51 // Start begins the sync service
52 Start() error
53 // Stop stops the sync service
54 Stop() error
55 // Type returns the service type name
56 Type() string
57 }
58
59 var (
60 driversMu sync.RWMutex
61 drivers = make(map[string]*DriverInfo)
62 )
63
64 // RegisterDriver registers a sync driver with the given name and factory.
65 // This is typically called from init() in the driver package.
66 func RegisterDriver(name, description string, factory DriverFactory) {
67 driversMu.Lock()
68 defer driversMu.Unlock()
69 drivers[name] = &DriverInfo{
70 Name: name,
71 Description: description,
72 Factory: factory,
73 }
74 }
75
76 // GetDriver returns the factory for the named driver, or nil if not found.
77 func GetDriver(name string) DriverFactory {
78 driversMu.RLock()
79 defer driversMu.RUnlock()
80 if info, ok := drivers[name]; ok {
81 return info.Factory
82 }
83 return nil
84 }
85
86 // HasDriver returns true if the named driver is registered.
87 func HasDriver(name string) bool {
88 driversMu.RLock()
89 defer driversMu.RUnlock()
90 _, ok := drivers[name]
91 return ok
92 }
93
94 // ListDrivers returns a sorted list of registered driver names.
95 func ListDrivers() []string {
96 driversMu.RLock()
97 defer driversMu.RUnlock()
98 names := make([]string, 0, len(drivers))
99 for name := range drivers {
100 names = append(names, name)
101 }
102 sort.Strings(names)
103 return names
104 }
105
106 // ListDriversWithInfo returns information about all registered drivers.
107 func ListDriversWithInfo() []*DriverInfo {
108 driversMu.RLock()
109 defer driversMu.RUnlock()
110 infos := make([]*DriverInfo, 0, len(drivers))
111 for _, info := range drivers {
112 infos = append(infos, info)
113 }
114 // Sort by name for consistent output
115 sort.Slice(infos, func(i, j int) bool {
116 return infos[i].Name < infos[j].Name
117 })
118 return infos
119 }
120
121 // NewFromDriver creates a sync service using the named driver.
122 // Returns an error if the driver is not registered.
123 func NewFromDriver(ctx context.Context, driverName string, db database.Database, cfg *DriverConfig) (Service, error) {
124 factory := GetDriver(driverName)
125 if factory == nil {
126 return nil, errorf.E("sync driver %q not available; registered: %v", driverName, ListDrivers())
127 }
128 return factory(ctx, db, cfg)
129 }
130