Files
tether/engine.go
T
wisplite 8092488b29 mutation proof of concept
client can now send mutations and server properly executes them
TODO: implement query execution, add auth, add storage
2026-04-21 23:07:55 -05:00

84 lines
2.6 KiB
Go

package tether
import (
"log/slog"
"net/http"
"github.com/wisplite/tether/reactivity"
"gorm.io/gorm"
)
type Engine struct {
db *gorm.DB
mutations map[string]func(ctx *MutationCtx) error
queries map[string]func(ctx *QueryCtx) error
tracker *reactivity.Tracker
}
func NewEngine(db *gorm.DB) *Engine {
slog.SetLogLoggerLevel(slog.LevelDebug)
tracker := reactivity.NewTracker()
return &Engine{db: db, mutations: make(map[string]func(ctx *MutationCtx) error), queries: make(map[string]func(ctx *QueryCtx) error), tracker: tracker}
}
func (e *Engine) RegisterMutation(name string, mutation func(ctx *MutationCtx) error) {
e.mutations[name] = mutation // stores the mutation in the list of valid mutations
slog.Debug("Registered mutation", "name", name)
}
func (e *Engine) RegisterQuery(name string, query func(ctx *QueryCtx) error) {
e.queries[name] = query // stores the query in the list of valid queries
slog.Debug("Registered query", "name", name)
}
func (e *Engine) CreateTable(name string, schema interface{}) {
e.db.AutoMigrate(schema)
slog.Debug("Created table", "name", name)
}
func (e *Engine) Handle(w http.ResponseWriter, r *http.Request) {
reactivity.Handle(w, r, e, e.tracker) // wraps the raw websocket connection with the engine handler
}
func (e *Engine) OnConnect(clientID string) error {
slog.Debug("Connected to websocket", "client", clientID)
// TODO: implement the logic to handle the connection
return nil
}
func (e *Engine) OnDisconnect(clientID string) error {
slog.Debug("Disconnected from websocket", "client", clientID)
// TODO: implement the logic to handle the disconnection
return nil
}
func (e *Engine) ExecuteQuery(query string) (interface{}, error) {
/*
TODO: implement the logic to execute the query
Steps needed:
1. Check which tables updated
2. Get the queries that rely on the tables
3. Get the subscriptions that need updating
4. Calculate hash for every query
5. Send the updated queries if hash changed
*/
return nil, nil
}
func (e *Engine) ExecuteMutation(mutation string, params map[string]interface{}) (interface{}, error) {
result := e.mutations[mutation](&MutationCtx{DB: e.db, AuthCtx: &AuthCtx{UserID: "", IsLoggedIn: true}, Params: params})
return result, nil
}
func (e *Engine) OnReceiveMessage(clientID string, msg map[string]interface{}) error {
slog.Debug("Received message", "from", clientID, "message", msg)
switch msg["type"] {
case "query":
query := msg["location"].(string) + "?" + msg["params"].(string)
e.tracker.SubscribeToQuery(clientID, query)
case "mutation":
e.ExecuteMutation(msg["location"].(string), msg["params"].(map[string]interface{}))
}
return nil
}