htmgo/framework/session/state.go

78 lines
1.7 KiB
Go
Raw Normal View History

2024-10-16 20:43:34 +00:00
package session
2024-10-08 17:48:28 +00:00
import (
2024-10-09 14:57:51 +00:00
"fmt"
2024-10-08 17:48:28 +00:00
"github.com/maddalax/htmgo/framework/h"
"github.com/puzpuzpuz/xsync/v3"
)
2024-10-16 20:43:34 +00:00
type Id string
2024-10-08 17:48:28 +00:00
2024-10-16 20:43:34 +00:00
var cache = xsync.NewMapOf[Id, *xsync.MapOf[string, any]]()
2024-10-08 17:48:28 +00:00
type State struct {
2024-10-16 20:43:34 +00:00
SessionId Id
2024-10-08 17:48:28 +00:00
}
func NewState(ctx *h.RequestContext) *State {
id := GetSessionId(ctx)
cache.Store(id, xsync.NewMapOf[string, any]())
return &State{
SessionId: id,
}
}
func CreateSession(ctx *h.RequestContext) Id {
sessionId := fmt.Sprintf("session-id-%s", h.GenId(30))
ctx.Set("session-id", sessionId)
return Id(sessionId)
}
2024-10-16 20:43:34 +00:00
func GetSessionId(ctx *h.RequestContext) Id {
2024-10-09 14:57:51 +00:00
sessionIdRaw := ctx.Get("session-id")
2024-10-08 17:48:28 +00:00
sessionId := ""
2024-10-09 14:57:51 +00:00
if sessionIdRaw == "" || sessionIdRaw == nil {
panic("session id is not set, please use session.CreateSession(ctx) in middleware to create a session id")
2024-10-09 14:57:51 +00:00
} else {
sessionId = sessionIdRaw.(string)
2024-10-08 17:48:28 +00:00
}
2024-10-16 20:43:34 +00:00
return Id(sessionId)
2024-10-08 17:48:28 +00:00
}
2024-10-16 20:43:34 +00:00
func Update[T any](sessionId Id, key string, compute func(prev T) T) T {
2024-10-08 17:48:28 +00:00
actual := Get[T](sessionId, key, *new(T))
next := compute(actual)
Set(sessionId, key, next)
return next
}
2024-10-16 20:43:34 +00:00
func Get[T any](sessionId Id, key string, fallback T) T {
2024-10-08 17:48:28 +00:00
actual, _ := cache.LoadOrCompute(sessionId, func() *xsync.MapOf[string, any] {
return xsync.NewMapOf[string, any]()
})
value, exists := actual.Load(key)
if exists {
return value.(T)
}
return fallback
}
2024-10-16 20:43:34 +00:00
func Set(sessionId Id, key string, value any) {
2024-10-08 17:48:28 +00:00
actual, _ := cache.LoadOrCompute(sessionId, func() *xsync.MapOf[string, any] {
return xsync.NewMapOf[string, any]()
})
actual.Store(key, value)
}
2024-10-16 20:23:36 +00:00
2024-10-16 20:43:34 +00:00
func UseState[T any](sessionId Id, key string, initial T) (func() T, func(T)) {
2024-10-16 20:23:36 +00:00
var get = func() T {
return Get[T](sessionId, key, initial)
}
var set = func(value T) {
Set(sessionId, key, value)
}
return get, set
}