mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2025-12-14 01:20:36 +00:00
194 lines
5.3 KiB
Go
194 lines
5.3 KiB
Go
package websocketspec
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/bitechdev/ResolveSpec/pkg/common"
|
|
)
|
|
|
|
// HookType represents the type of lifecycle hook
|
|
type HookType string
|
|
|
|
const (
|
|
// BeforeRead is called before a read operation
|
|
BeforeRead HookType = "before_read"
|
|
// AfterRead is called after a read operation
|
|
AfterRead HookType = "after_read"
|
|
|
|
// BeforeCreate is called before a create operation
|
|
BeforeCreate HookType = "before_create"
|
|
// AfterCreate is called after a create operation
|
|
AfterCreate HookType = "after_create"
|
|
|
|
// BeforeUpdate is called before an update operation
|
|
BeforeUpdate HookType = "before_update"
|
|
// AfterUpdate is called after an update operation
|
|
AfterUpdate HookType = "after_update"
|
|
|
|
// BeforeDelete is called before a delete operation
|
|
BeforeDelete HookType = "before_delete"
|
|
// AfterDelete is called after a delete operation
|
|
AfterDelete HookType = "after_delete"
|
|
|
|
// BeforeSubscribe is called before creating a subscription
|
|
BeforeSubscribe HookType = "before_subscribe"
|
|
// AfterSubscribe is called after creating a subscription
|
|
AfterSubscribe HookType = "after_subscribe"
|
|
|
|
// BeforeUnsubscribe is called before removing a subscription
|
|
BeforeUnsubscribe HookType = "before_unsubscribe"
|
|
// AfterUnsubscribe is called after removing a subscription
|
|
AfterUnsubscribe HookType = "after_unsubscribe"
|
|
|
|
// BeforeConnect is called when a new connection is established
|
|
BeforeConnect HookType = "before_connect"
|
|
// AfterConnect is called after a connection is established
|
|
AfterConnect HookType = "after_connect"
|
|
|
|
// BeforeDisconnect is called before a connection is closed
|
|
BeforeDisconnect HookType = "before_disconnect"
|
|
// AfterDisconnect is called after a connection is closed
|
|
AfterDisconnect HookType = "after_disconnect"
|
|
)
|
|
|
|
// HookContext contains context information for hook execution
|
|
type HookContext struct {
|
|
// Context is the request context
|
|
Context context.Context
|
|
|
|
// Handler provides access to the handler, database, and registry
|
|
Handler *Handler
|
|
|
|
// Connection is the WebSocket connection
|
|
Connection *Connection
|
|
|
|
// Message is the original message
|
|
Message *Message
|
|
|
|
// Schema is the database schema
|
|
Schema string
|
|
|
|
// Entity is the table/model name
|
|
Entity string
|
|
|
|
// TableName is the actual database table name
|
|
TableName string
|
|
|
|
// Model is the registered model instance
|
|
Model interface{}
|
|
|
|
// ModelPtr is a pointer to the model for queries
|
|
ModelPtr interface{}
|
|
|
|
// Options contains the parsed request options
|
|
Options *common.RequestOptions
|
|
|
|
// ID is the record ID for single-record operations
|
|
ID string
|
|
|
|
// Data is the request data (for create/update operations)
|
|
Data interface{}
|
|
|
|
// Result is the operation result (for after hooks)
|
|
Result interface{}
|
|
|
|
// Subscription is the subscription being created/removed
|
|
Subscription *Subscription
|
|
|
|
// Error is any error that occurred (for after hooks)
|
|
Error error
|
|
|
|
// Metadata is additional context data
|
|
Metadata map[string]interface{}
|
|
}
|
|
|
|
// HookFunc is a function that processes a hook
|
|
type HookFunc func(*HookContext) error
|
|
|
|
// HookRegistry manages lifecycle hooks
|
|
type HookRegistry struct {
|
|
hooks map[HookType][]HookFunc
|
|
}
|
|
|
|
// NewHookRegistry creates a new hook registry
|
|
func NewHookRegistry() *HookRegistry {
|
|
return &HookRegistry{
|
|
hooks: make(map[HookType][]HookFunc),
|
|
}
|
|
}
|
|
|
|
// Register registers a hook function for a specific hook type
|
|
func (hr *HookRegistry) Register(hookType HookType, fn HookFunc) {
|
|
hr.hooks[hookType] = append(hr.hooks[hookType], fn)
|
|
}
|
|
|
|
// RegisterBefore registers a hook that runs before an operation
|
|
// Convenience method for BeforeRead, BeforeCreate, BeforeUpdate, BeforeDelete
|
|
func (hr *HookRegistry) RegisterBefore(operation OperationType, fn HookFunc) {
|
|
switch operation {
|
|
case OperationRead:
|
|
hr.Register(BeforeRead, fn)
|
|
case OperationCreate:
|
|
hr.Register(BeforeCreate, fn)
|
|
case OperationUpdate:
|
|
hr.Register(BeforeUpdate, fn)
|
|
case OperationDelete:
|
|
hr.Register(BeforeDelete, fn)
|
|
case OperationSubscribe:
|
|
hr.Register(BeforeSubscribe, fn)
|
|
case OperationUnsubscribe:
|
|
hr.Register(BeforeUnsubscribe, fn)
|
|
}
|
|
}
|
|
|
|
// RegisterAfter registers a hook that runs after an operation
|
|
// Convenience method for AfterRead, AfterCreate, AfterUpdate, AfterDelete
|
|
func (hr *HookRegistry) RegisterAfter(operation OperationType, fn HookFunc) {
|
|
switch operation {
|
|
case OperationRead:
|
|
hr.Register(AfterRead, fn)
|
|
case OperationCreate:
|
|
hr.Register(AfterCreate, fn)
|
|
case OperationUpdate:
|
|
hr.Register(AfterUpdate, fn)
|
|
case OperationDelete:
|
|
hr.Register(AfterDelete, fn)
|
|
case OperationSubscribe:
|
|
hr.Register(AfterSubscribe, fn)
|
|
case OperationUnsubscribe:
|
|
hr.Register(AfterUnsubscribe, fn)
|
|
}
|
|
}
|
|
|
|
// Execute runs all hooks for a specific type
|
|
func (hr *HookRegistry) Execute(hookType HookType, ctx *HookContext) error {
|
|
hooks, exists := hr.hooks[hookType]
|
|
if !exists {
|
|
return nil
|
|
}
|
|
|
|
for _, hook := range hooks {
|
|
if err := hook(ctx); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// HasHooks checks if any hooks are registered for a hook type
|
|
func (hr *HookRegistry) HasHooks(hookType HookType) bool {
|
|
hooks, exists := hr.hooks[hookType]
|
|
return exists && len(hooks) > 0
|
|
}
|
|
|
|
// Clear removes all hooks of a specific type
|
|
func (hr *HookRegistry) Clear(hookType HookType) {
|
|
delete(hr.hooks, hookType)
|
|
}
|
|
|
|
// ClearAll removes all registered hooks
|
|
func (hr *HookRegistry) ClearAll() {
|
|
hr.hooks = make(map[HookType][]HookFunc)
|
|
}
|