change version, add logical route groups

This commit is contained in:
Sky Johnson 2025-05-28 22:40:34 -05:00
parent 39d14d0025
commit 163e94d576
2 changed files with 79 additions and 39 deletions

View File

@ -51,7 +51,7 @@ type LuaRouter struct {
bytecodeCache *fastcache.Cache // Cache for compiled bytecode
// Middleware tracking for path hierarchy
middlewareFiles map[string][]string // path -> middleware file paths
middlewareFiles map[string][]string // filesystem path -> middleware file paths
// New caching fields
middlewareCache map[string][]byte // path -> content
@ -72,6 +72,40 @@ type node struct {
paramChild *node // Parameter/wildcard child
err error // Compilation error if any
modTime time.Time // Last modification time
fsPath string // Original filesystem path (includes groups)
}
// pathInfo holds both filesystem and URL path information
type pathInfo struct {
fsPath string // Filesystem path (includes groups)
urlPath string // URL path (excludes groups)
}
// parsePathWithGroups separates filesystem path from URL path
func parsePathWithGroups(fsPath string) pathInfo {
segments := strings.Split(strings.Trim(fsPath, "/"), "/")
var urlSegments []string
for _, segment := range segments {
if segment == "" {
continue
}
// Skip group segments for URL path
if len(segment) >= 3 && segment[0] == '(' && segment[len(segment)-1] == ')' {
continue
}
urlSegments = append(urlSegments, segment)
}
urlPath := "/"
if len(urlSegments) > 0 {
urlPath = "/" + strings.Join(urlSegments, "/")
}
return pathInfo{
fsPath: fsPath,
urlPath: urlPath,
}
}
// NewLuaRouter creates a new LuaRouter instance
@ -136,12 +170,13 @@ func (r *LuaRouter) buildRoutes() error {
return err
}
urlPath := "/"
fsPath := "/"
if relDir != "." {
urlPath = "/" + strings.ReplaceAll(relDir, "\\", "/")
fsPath = "/" + strings.ReplaceAll(relDir, "\\", "/")
}
r.middlewareFiles[urlPath] = append(r.middlewareFiles[urlPath], path)
// Use filesystem path for middleware (includes groups)
r.middlewareFiles[fsPath] = append(r.middlewareFiles[fsPath], path)
}
return nil
@ -169,19 +204,22 @@ func (r *LuaRouter) buildRoutes() error {
return err
}
urlPath := "/"
fsPath := "/"
if relDir != "." {
urlPath = "/" + strings.ReplaceAll(relDir, "\\", "/")
fsPath = "/" + strings.ReplaceAll(relDir, "\\", "/")
}
pathInfo := parsePathWithGroups(fsPath)
// Handle index.lua files
if fileName == "index" {
for _, method := range []string{"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"} {
root := r.routes[method]
node := r.findOrCreateNode(root, urlPath)
node := r.findOrCreateNode(root, pathInfo.urlPath)
node.indexFile = path
node.modTime = info.ModTime()
r.compileWithMiddleware(node, urlPath, path)
node.fsPath = pathInfo.fsPath
r.compileWithMiddleware(node, pathInfo.fsPath, path)
}
return nil
}
@ -193,14 +231,14 @@ func (r *LuaRouter) buildRoutes() error {
return nil
}
r.addRoute(root, urlPath, path, info.ModTime())
r.addRoute(root, pathInfo, path, info.ModTime())
return nil
})
}
// addRoute adds a route to the routing tree
func (r *LuaRouter) addRoute(root *node, urlPath, handlerPath string, modTime time.Time) error {
segments := strings.Split(strings.Trim(urlPath, "/"), "/")
func (r *LuaRouter) addRoute(root *node, pathInfo pathInfo, handlerPath string, modTime time.Time) error {
segments := strings.Split(strings.Trim(pathInfo.urlPath, "/"), "/")
current := root
for _, segment := range segments {
@ -230,18 +268,19 @@ func (r *LuaRouter) addRoute(root *node, urlPath, handlerPath string, modTime ti
current.handler = handlerPath
current.modTime = modTime
current.fsPath = pathInfo.fsPath
return r.compileWithMiddleware(current, urlPath, handlerPath)
return r.compileWithMiddleware(current, pathInfo.fsPath, handlerPath)
}
// compileWithMiddleware combines middleware and handler source, then compiles
func (r *LuaRouter) compileWithMiddleware(n *node, urlPath, scriptPath string) error {
func (r *LuaRouter) compileWithMiddleware(n *node, fsPath, scriptPath string) error {
if scriptPath == "" {
return nil
}
// Check if we need to recompile by comparing modification times
sourceKey := r.getSourceCacheKey(urlPath, scriptPath)
sourceKey := r.getSourceCacheKey(fsPath, scriptPath)
needsRecompile := false
// Check handler modification time
@ -258,7 +297,7 @@ func (r *LuaRouter) compileWithMiddleware(n *node, urlPath, scriptPath string) e
// Check middleware modification times
if !needsRecompile {
middlewareChain := r.getMiddlewareChain(urlPath)
middlewareChain := r.getMiddlewareChain(fsPath)
for _, mwPath := range middlewareChain {
mwInfo, err := os.Stat(mwPath)
if err != nil {
@ -282,7 +321,7 @@ func (r *LuaRouter) compileWithMiddleware(n *node, urlPath, scriptPath string) e
}
// Build combined source
combinedSource, err := r.buildCombinedSource(urlPath, scriptPath)
combinedSource, err := r.buildCombinedSource(fsPath, scriptPath)
if err != nil {
n.err = err
return err
@ -309,11 +348,11 @@ func (r *LuaRouter) compileWithMiddleware(n *node, urlPath, scriptPath string) e
}
// buildCombinedSource builds the combined middleware + handler source
func (r *LuaRouter) buildCombinedSource(urlPath, scriptPath string) (string, error) {
func (r *LuaRouter) buildCombinedSource(fsPath, scriptPath string) (string, error) {
var combinedSource strings.Builder
// Get middleware chain
middlewareChain := r.getMiddlewareChain(urlPath)
// Get middleware chain using filesystem path
middlewareChain := r.getMiddlewareChain(fsPath)
// Add middleware in order
for _, mwPath := range middlewareChain {
@ -368,20 +407,20 @@ func (r *LuaRouter) getFileContent(path string) ([]byte, error) {
}
// getSourceCacheKey generates a unique key for combined source
func (r *LuaRouter) getSourceCacheKey(urlPath, scriptPath string) string {
middlewareChain := r.getMiddlewareChain(urlPath)
func (r *LuaRouter) getSourceCacheKey(fsPath, scriptPath string) string {
middlewareChain := r.getMiddlewareChain(fsPath)
var keyParts []string
keyParts = append(keyParts, middlewareChain...)
keyParts = append(keyParts, scriptPath)
return strings.Join(keyParts, "|")
}
// getMiddlewareChain returns middleware files that apply to the given path
func (r *LuaRouter) getMiddlewareChain(urlPath string) []string {
// getMiddlewareChain returns middleware files that apply to the given filesystem path
func (r *LuaRouter) getMiddlewareChain(fsPath string) []string {
var chain []string
// Collect middleware from root to specific path
pathParts := strings.Split(strings.Trim(urlPath, "/"), "/")
// Collect middleware from root to specific path using filesystem path (includes groups)
pathParts := strings.Split(strings.Trim(fsPath, "/"), "/")
if pathParts[0] == "" {
pathParts = []string{}
}
@ -391,7 +430,7 @@ func (r *LuaRouter) getMiddlewareChain(urlPath string) []string {
chain = append(chain, mw...)
}
// Add middleware from each path level
// Add middleware from each path level (including groups)
currentPath := ""
for _, part := range pathParts {
currentPath += "/" + part
@ -403,7 +442,7 @@ func (r *LuaRouter) getMiddlewareChain(urlPath string) []string {
return chain
}
// findOrCreateNode finds or creates a node at the given path
// findOrCreateNode finds or creates a node at the given URL path (excludes groups)
func (r *LuaRouter) findOrCreateNode(root *node, urlPath string) *node {
segments := strings.Split(strings.Trim(urlPath, "/"), "/")
current := root
@ -467,7 +506,7 @@ func getBytecodeKey(handlerPath string) []byte {
return uint64ToBytes(key)
}
// Match finds a handler for the given method and path
// Match finds a handler for the given method and path (URL path, excludes groups)
func (r *LuaRouter) Match(method, path string, params *Params) (*node, bool) {
params.Count = 0
@ -565,8 +604,12 @@ func (r *LuaRouter) GetRouteInfo(method, path string, params *Params) ([]byte, s
scriptPath = n.indexFile
}
urlPath := r.getNodeURLPath(n)
if err := r.compileWithMiddleware(n, urlPath, scriptPath); err != nil {
fsPath := n.fsPath
if fsPath == "" {
fsPath = "/"
}
if err := r.compileWithMiddleware(n, fsPath, scriptPath); err != nil {
return nil, handlerPath, n.err, true
}
@ -602,8 +645,11 @@ func (r *LuaRouter) GetRouteInfo(method, path string, params *Params) ([]byte, s
bytecode := r.bytecodeCache.Get(nil, bytecodeKey)
if len(bytecode) == 0 {
urlPath := r.getNodeURLPath(node)
if err := r.compileWithMiddleware(node, urlPath, scriptPath); err != nil {
fsPath := node.fsPath
if fsPath == "" {
fsPath = "/"
}
if err := r.compileWithMiddleware(node, fsPath, scriptPath); err != nil {
return nil, scriptPath, node.err, true
}
bytecode = r.bytecodeCache.Get(nil, bytecodeKey)
@ -617,12 +663,6 @@ func (r *LuaRouter) GetRouteInfo(method, path string, params *Params) ([]byte, s
return bytecode, scriptPath, node.err, true
}
// getNodeURLPath reconstructs URL path for a node (simplified)
func (r *LuaRouter) getNodeURLPath(node *node) string {
// This is a simplified implementation - in practice you'd traverse up the tree
return "/"
}
// nodeForHandler finds a node by its handler path
func (r *LuaRouter) nodeForHandler(handlerPath string) (*node, bool) {
r.mu.RLock()

View File

@ -1,7 +1,7 @@
package metadata
// Version holds the current Moonshark version
const Version = "0.1"
const Version = "1.0"
// Build time information
var (