Draft: First draft of new fiber based server #7

Merged
baez90 merged 16 commits from migrate-to-fiber into master 2022-03-15 16:39:37 +00:00
5 changed files with 89 additions and 60 deletions
Showing only changes of commit 3f847e0b8b - Show all commits

View file

@ -51,8 +51,8 @@ var (
hub := events.NewEventHub( hub := events.NewEventHub(
wdfs, wdfs,
fnv.New32a(), fnv.New32a(),
events.FileNameTrigger(args[0]), events.MutationReloadForFile(args[0]),
events.FileNameTrigger(filepath.Base(cfg.ConfigFileInUse)), events.MutationConfigReloadForFile(filepath.Base(cfg.ConfigFileInUse)),
) )
api.NoCache(app) api.NoCache(app)

View file

@ -3,9 +3,10 @@ package config
var ( var (
defaults = map[string]interface{}{ defaults = map[string]interface{}{
"mermaid.theme": "forest", "mermaid.theme": "forest",
"reveal.theme": "beige", "theme": "beige",
"codeTheme": "monokai", "codeTheme": "monokai",
"transition": TransitionNone, "transition": TransitionNone,
"controlsLayout": ControlsLayoutEdges,
"controls": true, "controls": true,
"progress": true, "progress": true,
"history": true, "history": true,
@ -23,10 +24,14 @@ const (
TransitionConvex Transition = "convex" TransitionConvex Transition = "convex"
TransitionConcave Transition = "concave" TransitionConcave Transition = "concave"
TransitionZoom Transition = "zoom" TransitionZoom Transition = "zoom"
ControlsLayoutBottomRight ControlsLayout = "bottom-right"
ControlsLayoutEdges ControlsLayout = "edges"
) )
type ( type (
Transition string Transition string
ControlsLayout string
Mermaid struct { Mermaid struct {
Theme string `json:"theme"` Theme string `json:"theme"`
} }
@ -40,6 +45,7 @@ type (
CodeTheme string `json:"codeTheme"` CodeTheme string `json:"codeTheme"`
Transition Transition `json:"transition"` Transition Transition `json:"transition"`
Controls bool `json:"controls"` Controls bool `json:"controls"`
ControlsLayout ControlsLayout `json:"controlsLayout"`
Progress bool `json:"progress"` Progress bool `json:"progress"`
History bool `json:"history"` History bool `json:"history"`
Center bool `json:"center"` Center bool `json:"center"`

View file

@ -21,14 +21,15 @@ const (
) )
type ( type (
ReloadTrigger interface { EventMutation interface {
Triggers(ev fs.Event) bool OnEvent(in ContentEvent, ev fs.Event) (out ContentEvent)
} }
ContentEvent struct { ContentEvent struct {
File string `json:"file"` File string `json:"file"`
FileNameHash string `json:"fileNameHash"` FileNameHash string `json:"fileNameHash"`
Timestamp string `json:"ts"` Timestamp string `json:"ts"`
ForceReload bool `json:"forceReload"` ForceReload bool `json:"forceReload"`
ReloadConfig bool `json:"reloadConfig"`
} }
EventSource interface { EventSource interface {
io.Closer io.Closer
@ -43,27 +44,32 @@ type (
EventHandler EventHandler
OnError chan error OnError chan error
} }
FileNameTrigger string MutationReloadForFile string
FileSuffixTrigger string MutationConfigReloadForFile string
) )
func (t FileNameTrigger) Triggers(ev fs.Event) bool { func (t MutationReloadForFile) OnEvent(in ContentEvent, ev fs.Event) (out ContentEvent) {
fileBase := filepath.Base(ev.File) if strings.EqualFold(filepath.Base(ev.File), string(t)) {
return strings.EqualFold(fileBase, string(t)) in.ForceReload = true
}
return in
} }
func (t FileSuffixTrigger) Triggers(ev fs.Event) bool { func (t MutationConfigReloadForFile) OnEvent(in ContentEvent, ev fs.Event) (out ContentEvent) {
return strings.HasSuffix(strings.ToLower(filepath.Base(ev.File)), strings.ToLower(string(t))) if strings.EqualFold(filepath.Base(ev.File), string(t)) {
in.ReloadConfig = true
}
return in
} }
func (f EventHandlerFunc) OnEvent(ev ContentEvent) error { func (f EventHandlerFunc) OnEvent(ev ContentEvent) error {
return f(ev) return f(ev)
} }
func NewEventHub(eventSource EventSource, fileNameHash hash.Hash, triggers ...ReloadTrigger) *EventHub { func NewEventHub(eventSource EventSource, fileNameHash hash.Hash, mutations ...EventMutation) *EventHub {
hub := &EventHub{ hub := &EventHub{
FileNameHash: fileNameHash, FileNameHash: fileNameHash,
reloadTriggers: triggers, mutations: mutations,
source: eventSource, source: eventSource,
subscriptions: make(map[uuid.UUID]*subscription), subscriptions: make(map[uuid.UUID]*subscription),
done: make(chan struct{}), done: make(chan struct{}),
@ -76,7 +82,7 @@ func NewEventHub(eventSource EventSource, fileNameHash hash.Hash, triggers ...Re
type EventHub struct { type EventHub struct {
FileNameHash hash.Hash FileNameHash hash.Hash
reloadTriggers []ReloadTrigger mutations []EventMutation
lock sync.RWMutex lock sync.RWMutex
done chan struct{} done chan struct{}
source EventSource source EventSource
@ -129,20 +135,16 @@ func (h *EventHub) notifySubscribers(ev fs.Event) {
h.lock.RLock() h.lock.RLock()
defer h.lock.RUnlock() defer h.lock.RUnlock()
var triggerReload bool
for idx := range h.reloadTriggers {
if triggerReload = h.reloadTriggers[idx].Triggers(ev); triggerReload {
break
}
}
ce := ContentEvent{ ce := ContentEvent{
File: fmt.Sprintf("/%s", ev.File), File: fmt.Sprintf("/%s", ev.File),
Timestamp: strconv.FormatInt(ev.Timestamp.Unix(), baseDecimal), Timestamp: strconv.FormatInt(ev.Timestamp.Unix(), baseDecimal),
ForceReload: triggerReload,
FileNameHash: hex.EncodeToString(h.FileNameHash.Sum([]byte(path.Base(ev.File)))), FileNameHash: hex.EncodeToString(h.FileNameHash.Sum([]byte(path.Base(ev.File)))),
} }
for idx := range h.mutations {
ce = h.mutations[idx].OnEvent(ce, ev)
}
for _, handler := range h.subscriptions { for _, handler := range h.subscriptions {
if err := handler.OnEvent(ce); err != nil { if err := handler.OnEvent(ce); err != nil {
handler.OnError <- err handler.OnError <- err

View file

@ -3,6 +3,16 @@ codeTheme: monokai
horizontalSeparator: === horizontalSeparator: ===
verticalSeparator: --- verticalSeparator: ---
transition: convex transition: convex
menu.numbers: false controlsLayout: edges
controls: true
progress: true
history: true
center: true
slideNumber: true
menu:
numbers: false
useTextContentForMissingTitles: true
mermaid:
theme: forest
stylesheets: stylesheets:
- custom.css - custom.css

View file

@ -25,9 +25,13 @@ async function setSlidesContent() {
document.getElementById("content-root").innerHTML = contentDocument.documentElement.innerHTML document.getElementById("content-root").innerHTML = contentDocument.documentElement.innerHTML
} }
async function initReveal() { async function getRevealConfig() {
let resp = await fetch('/api/v1/config/reveal') let resp = await fetch('/api/v1/config/reveal')
let cfg = await resp.json() return await resp.json()
}
async function initReveal() {
let cfg = await getRevealConfig()
Reveal.initialize({ Reveal.initialize({
controls: cfg.controls, controls: cfg.controls,
progress: cfg.progress, progress: cfg.progress,
@ -97,9 +101,16 @@ function subscribeToEvents() {
source.onmessage = (ev => { source.onmessage = (ev => {
let obj = JSON.parse(ev.data); let obj = JSON.parse(ev.data);
console.log(obj); console.log(obj);
if (obj.forceReload) { switch (true) {
case obj.forceReload:
window.location.reload() window.location.reload()
} else { break
case obj.reloadConfig:
getRevealConfig().then(cfg => {
Reveal.configure(cfg)
})
break
default:
switch (true) { switch (true) {
case obj.file.endsWith(".css"): case obj.file.endsWith(".css"):
let cssLink = document.querySelector(`link[rel=stylesheet][id="${obj.fileNameHash}"]`); let cssLink = document.querySelector(`link[rel=stylesheet][id="${obj.fileNameHash}"]`);