import type { AdminEventDescriptor, AdminEventHookHandler, LifecycleHookEvent, LifecycleHookHandler } from './types' type HookBuckets = Map[]> const lifecycleHooks = new Map() const adminEventHooks: Array<{ descriptor: AdminEventDescriptor handler: AdminEventHookHandler }> = [] export function registerHook( entityType: string, event: Event, handler: LifecycleHookHandler ): () => void { const normalizedEntityType = entityType.trim() if (!normalizedEntityType || normalizedEntityType === '*') { throw new Error('Lifecycle hooks must be registered for a specific entity type') } const buckets = lifecycleHooks.get(normalizedEntityType) ?? new Map() const handlers = buckets.get(event) ?? [] handlers.push(handler as LifecycleHookHandler) buckets.set(event, handlers) lifecycleHooks.set(normalizedEntityType, buckets) return () => { const currentHandlers = buckets.get(event) if (!currentHandlers) return const index = currentHandlers.indexOf(handler as LifecycleHookHandler) if (index >= 0) { currentHandlers.splice(index, 1) } } } export function getRegisteredHooks( entityType: string, event: Event ): LifecycleHookHandler[] { return [...((lifecycleHooks.get(entityType)?.get(event) ?? []) as LifecycleHookHandler[])] } export function getLifecycleHookSummary(): Record< string, Partial> > { const summary: Record>> = {} for (const [entityType, events] of lifecycleHooks.entries()) { summary[entityType] = {} for (const [event, handlers] of events.entries()) { summary[entityType][event] = handlers.length } } return summary } export function registerAdminHook( descriptor: AdminEventDescriptor, handler: AdminEventHookHandler ): () => void { adminEventHooks.push({ descriptor, handler }) return () => { const index = adminEventHooks.findIndex((entry) => entry.handler === handler) if (index >= 0) { adminEventHooks.splice(index, 1) } } } export function getRegisteredAdminHooks( event: Required ): AdminEventHookHandler[] { return adminEventHooks .filter(({ descriptor }) => { if (descriptor.category && descriptor.category !== event.category) return false if (descriptor.action && descriptor.action !== event.action) return false return true }) .map(({ handler }) => handler) }