feat: notify document updates over websocket
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/tim/md-hub-secure/apps/server/internal/docs"
|
||||
"github.com/tim/md-hub-secure/apps/server/internal/httpserver"
|
||||
"github.com/tim/md-hub-secure/apps/server/internal/markdown"
|
||||
"github.com/tim/md-hub-secure/apps/server/internal/realtime"
|
||||
"github.com/tim/md-hub-secure/apps/server/internal/store"
|
||||
)
|
||||
|
||||
@@ -21,6 +22,8 @@ type App struct {
|
||||
cfg config.Config
|
||||
logger *slog.Logger
|
||||
db database.DB
|
||||
docs *docs.Service
|
||||
hub *realtime.Hub
|
||||
server *http.Server
|
||||
}
|
||||
|
||||
@@ -46,7 +49,12 @@ func New(ctx context.Context, cfg config.Config, logger *slog.Logger) (*App, err
|
||||
renderer := markdown.NewRenderer()
|
||||
repo := docs.NewRepository(db.SQL())
|
||||
service := docs.NewService(cfg.Content.SourceDir, contentStore, renderer, repo, logger)
|
||||
if err := service.SyncSourceDir(ctx); err != nil {
|
||||
hub := realtime.NewHub(logger)
|
||||
service.OnChange(func(change docs.DocumentChange) {
|
||||
hub.Broadcast(realtime.Event{Type: "document_version", Data: change})
|
||||
})
|
||||
|
||||
if _, err := service.SyncSourceDir(ctx); err != nil {
|
||||
logger.Warn("initial content sync failed", "error", err)
|
||||
}
|
||||
|
||||
@@ -56,6 +64,7 @@ func New(ctx context.Context, cfg config.Config, logger *slog.Logger) (*App, err
|
||||
Documents: service,
|
||||
Repository: repo,
|
||||
ContentStore: contentStore,
|
||||
Hub: hub,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("build http handler: %w", err)
|
||||
@@ -74,11 +83,15 @@ func New(ctx context.Context, cfg config.Config, logger *slog.Logger) (*App, err
|
||||
cfg: cfg,
|
||||
logger: logger,
|
||||
db: db,
|
||||
docs: service,
|
||||
hub: hub,
|
||||
server: server,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *App) Run(ctx context.Context) error {
|
||||
go a.watchDocuments(ctx)
|
||||
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
@@ -93,6 +106,22 @@ func (a *App) Run(ctx context.Context) error {
|
||||
return a.server.ListenAndServe()
|
||||
}
|
||||
|
||||
func (a *App) watchDocuments(ctx context.Context) {
|
||||
ticker := time.NewTicker(2 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
if _, err := a.docs.SyncSourceDir(ctx); err != nil {
|
||||
a.logger.Warn("document sync poll failed", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) Close() error {
|
||||
return a.db.Close()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user