initial commit

This commit is contained in:
2026-01-27 09:55:09 -05:00
commit ccbe9cd7bf
18 changed files with 2210 additions and 0 deletions

View File

@@ -0,0 +1,115 @@
package functions
import (
"fmt"
"reflect"
"strings"
"sync"
"reichard.io/poiesis/internal/tsconvert"
)
var (
functionRegistry = make(map[string]Function)
registryMutex sync.RWMutex
)
func registerFunction[A Args, R any](name string, isAsync bool, fn GoFunc[A, R]) {
// Lock Registry
registryMutex.Lock()
defer registryMutex.Unlock()
// Validate Args Type
tType := reflect.TypeFor[A]()
if tType.Kind() != reflect.Struct {
panic(fmt.Sprintf("function %s: argument must be a struct type, got %v", name, tType))
}
// Collect Types and Generate Definition
fnType := reflect.TypeOf(fn)
types := tsconvert.CollectTypes(tType, fnType)
definition := tsconvert.GenerateFunctionDecl(name, tType, fnType, isAsync)
// Register Function
functionRegistry[name] = &functionImpl[A, R]{
name: name,
fn: fn,
types: types.All(),
definition: definition,
isAsync: isAsync,
}
}
func GetFunctionDeclarations() string {
// Lock Registry
registryMutex.RLock()
defer registryMutex.RUnlock()
// Collect Type Definitions
typeDefinitions := make(map[string]bool)
var typeDefs []string
var functionDecls []string
for _, fn := range functionRegistry {
for _, t := range fn.Types() {
if !typeDefinitions[t] {
typeDefinitions[t] = true
typeDefs = append(typeDefs, t)
}
}
functionDecls = append(functionDecls, fn.Definition())
}
// Build Result
result := strings.Join(typeDefs, "\n\n")
if len(result) > 0 && len(functionDecls) > 0 {
result += "\n\n"
}
result += strings.Join(functionDecls, "\n")
return result
}
// GetTypeDeclarations returns all type declarations from all registered functions.
// This is used for aggregating types across multiple functions.
func GetTypeDeclarations() map[string]string {
// Lock Registry
registryMutex.RLock()
defer registryMutex.RUnlock()
// Collect All Types
allTypes := make(map[string]string)
for _, fn := range functionRegistry {
for name, def := range fn.Types() {
if existing, ok := allTypes[name]; ok && existing != def {
// Type Conflict Detected - Skip
continue
}
allTypes[name] = def
}
}
return allTypes
}
func GetRegisteredFunctions() map[string]Function {
// Lock Registry
registryMutex.RLock()
defer registryMutex.RUnlock()
// Copy Registry
result := make(map[string]Function, len(functionRegistry))
for k, v := range functionRegistry {
result[k] = v
}
return result
}
func RegisterFunction[T Args, R any](name string, fn GoFunc[T, R]) {
// Register Sync Function
registerFunction(name, false, fn)
}
func RegisterAsyncFunction[T Args, R any](name string, fn GoFunc[T, R]) {
// Register Async Function
registerFunction(name, true, fn)
}