import { Brand } from '../shared/type-utils.js'; /** * Unique extension identifier * Prevents mixing different extension types (compile-time safety) */ export type ExtensionId = Brand; /** * Unique hook identifier */ export type HookId = Brand; /** * Unique component extension identifier */ export type ComponentExtensionId = Brand; /** * Type-safe extension ID constructor */ export declare function createExtensionId(id: string): ExtensionId; /** * Type-safe hook ID constructor */ export declare function createHookId(id: string): HookId; /** * Extension priority for execution order * Higher priority extensions execute first */ export type ExtensionPriority = number; /** * Default priority values */ export declare const ExtensionPriorities: { readonly CRITICAL: 1000; readonly HIGH: 500; readonly NORMAL: 0; readonly LOW: -500; readonly LOWEST: -1000; }; /** * Context provided to onInit hook */ export interface InitContext { /** Extension name */ extensionName: string; /** Configuration passed to the client */ config: Record; /** Timestamp when initialized */ timestamp: number; } /** * Context provided to onMount hook (React lifecycle) */ export interface MountContext { /** Extension name */ extensionName: string; /** Component or module being mounted */ component?: string; /** Mount-specific data */ data?: Record; /** Timestamp when mounted */ timestamp: number; } /** * Context provided to onUnmount hook (React lifecycle) */ export interface UnmountContext { /** Extension name */ extensionName: string; /** Component or module being unmounted */ component?: string; /** Cleanup-specific data */ data?: Record; /** Timestamp when unmounted */ timestamp: number; } /** * Context provided to onError hook */ export interface ErrorContext { /** Extension name where error occurred */ extensionName: string; /** Hook name where error occurred */ hookName: string; /** The error that was thrown */ error: Error; /** Operation that was being performed */ operation: string; /** Retry the failed operation */ retry: () => Promise; /** Timestamp when error occurred */ timestamp: number; } /** * Context provided to beforeOperation hook */ export interface BeforeOperationContext { /** Extension name */ extensionName: string; /** Operation name (e.g., 'fetch', 'mutate', 'render') */ operation: string; /** Operation arguments (mutable) */ args: TArgs; /** Modify arguments before execution */ modify: (changes: Partial) => void; /** Cancel the operation */ cancel: () => void; /** Operation metadata */ metadata?: Record; /** Timestamp */ timestamp: number; } /** * Context provided to afterOperation hook */ export interface AfterOperationContext { /** Extension name */ extensionName: string; /** Operation name */ operation: string; /** Original operation arguments */ args: TArgs; /** Operation result (mutable) */ result: TResult; /** Modify result before returning */ modify: (changes: Partial) => void; /** Operation duration in ms */ duration: number; /** Operation metadata */ metadata?: Record; /** Timestamp */ timestamp: number; } /** * Extension lifecycle hook function types */ export type InitHook = (context: InitContext) => Promise | void; export type MountHook = (context: MountContext) => Promise | void; export type UnmountHook = (context: UnmountContext) => Promise | void; export type ErrorHook = (context: ErrorContext) => Promise | void; export type BeforeOperationHook = (context: BeforeOperationContext) => Promise | void; export type AfterOperationHook = (context: AfterOperationContext) => Promise | void; /** * Lifecycle hooks configuration */ export interface LifecycleHooks { /** Called when extension is registered */ onInit?: InitHook; /** Called when component/module mounts (React lifecycle) */ onMount?: MountHook; /** Called when component/module unmounts (React lifecycle) */ onUnmount?: UnmountHook; /** Called when an error occurs in any hook */ onError?: ErrorHook; /** Called before any operation (middleware pattern) */ beforeOperation?: BeforeOperationHook; /** Called after any operation (middleware pattern) */ afterOperation?: AfterOperationHook; } /** * Component enhancer function type * Used to wrap or enhance React components */ export type ComponentEnhancer = (Component: React.ComponentType) => React.ComponentType; /** * Component hook type * Custom hooks provided by extensions */ export type ComponentHook = (...args: unknown[]) => TResult; /** * Component extensions configuration */ export interface ComponentExtensions { /** Component enhancers (HOCs) */ enhancers?: Record; /** Custom React hooks */ hooks?: Record; /** Component-level utilities */ utils?: Record unknown>; } /** * State selector function type */ export type StateSelector = (state: TState) => TResult; /** * State action creator type */ export type StateActionCreator = (payload: TPayload) => { type: string; payload: TPayload; }; /** * State middleware function type */ export type StateMiddleware = (state: TState, action: { type: string; payload?: unknown; }) => TState; /** * State extensions configuration */ export interface StateExtensions { /** State selectors */ selectors?: Record; /** Action creators */ actions?: Record; /** State middleware */ middleware?: StateMiddleware[]; /** Initial state contributions */ initialState?: Record; } /** * API endpoint definition */ export interface ApiEndpoint { /** HTTP method or operation type */ method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | string; /** Endpoint path or operation name */ path?: string; /** Endpoint handler */ handler: (args: TArgs) => Promise | TResult; /** Request transformer */ transformRequest?: (args: TArgs) => unknown; /** Response transformer */ transformResponse?: (response: unknown) => TResult; /** Error transformer */ transformError?: (error: unknown) => Error; } /** * API interceptor for request/response modification */ export interface ApiInterceptor { /** Request interceptor */ request?: (config: RequestConfig) => Promise | RequestConfig; /** Response interceptor */ response?: (response: T) => Promise | T; /** Error interceptor */ error?: (error: Error) => Promise | never; } /** * Request configuration */ export interface RequestConfig { url?: string; method?: string; headers?: Record; params?: Record; data?: unknown; timeout?: number; metadata?: Record; } /** * API extensions configuration */ export interface ApiExtensions { /** Custom API endpoints */ endpoints?: Record; /** Request/response interceptors */ interceptors?: ApiInterceptor[]; /** API-level utilities */ utils?: Record unknown>; } /** * Complete Enzyme Extension definition * Inspired by Prisma's extension architecture * * @example * ```ts * const loggingExtension: EnzymeExtension = { * name: 'logging', * version: '1.0.0', * description: 'Logs all operations', * priority: ExtensionPriorities.HIGH, * hooks: { * beforeOperation: async (ctx) => { * console.log(`[${ctx.operation}] Starting...`); * }, * afterOperation: async (ctx) => { * console.log(`[${ctx.operation}] Completed in ${ctx.duration}ms`); * }, * }, * }; * ``` */ export interface EnzymeExtension { /** Extension name (required, must be unique) */ name: string; /** Extension version (semver recommended) */ version?: string; /** Extension description */ description?: string; /** Execution priority (higher = earlier execution) */ priority?: ExtensionPriority; /** Lifecycle hooks */ hooks?: LifecycleHooks; /** Component-level extensions */ component?: ComponentExtensions; /** State management extensions */ state?: StateExtensions; /** API/network extensions */ api?: ApiExtensions; /** Client-level methods and utilities */ client?: Record any>; /** Extension metadata */ metadata?: Record; } /** * Extension manager interface */ export interface IExtensionManager { /** Register an extension */ register(extension: EnzymeExtension): void; /** Unregister an extension by name */ unregister(name: string): boolean; /** Get all registered extensions */ getExtensions(): EnzymeExtension[]; /** Get extension by name */ getExtension(name: string): EnzymeExtension | undefined; /** Check if extension is registered */ hasExtension(name: string): boolean; /** Get extension count */ readonly count: number; /** Execute lifecycle hooks */ executeHooks(hookName: keyof LifecycleHooks, context: unknown): Promise; /** Clear all extensions */ clear(): void; } /** * Exact type matching for strict checking * Prevents excess properties in extension definitions */ export type Exact = Input extends Shape ? Exclude extends never ? Input : never : never; /** * Deep partial type for configuration */ export type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial; } : T; /** * Extract extension client methods */ export type ExtensionClientMethods = T['client'] extends Record unknown> ? T['client'] : Record; /** * Merge multiple extension client methods */ export type MergeExtensionMethods = T extends [ infer First extends EnzymeExtension, ...infer Rest extends EnzymeExtension[] ] ? ExtensionClientMethods & MergeExtensionMethods : Record; /** * Extension client type with merged methods */ export type ExtendedClient = TBase & MergeExtensionMethods; /** * Enzyme namespace for extension utilities */ export declare namespace Enzyme { /** * Define an extension with type inference and validation * * @example * ```ts * const myExtension = Enzyme.defineExtension({ * name: 'my-extension', * version: '1.0.0', * hooks: { * onInit: async (ctx) => { * console.log('Initialized!'); * }, * }, * }); * ``` */ function defineExtension(extension: T): T; /** * Create a typed hook context */ function createHookContext(_hookName: T, data: unknown): unknown; /** * Type guard for extension validation */ function isValidExtension(value: unknown): value is EnzymeExtension; /** * Extension builder for fluent API * * @example * ```ts * const ext = Enzyme.extension('my-ext') * .version('1.0.0') * .priority(ExtensionPriorities.HIGH) * .onInit(async (ctx) => { ... }) * .build(); * ``` */ function extension(name: string): ExtensionBuilder; } /** * Fluent extension builder */ export declare class ExtensionBuilder { private ext; constructor(name: string); version(v: string): this; description(d: string): this; priority(p: ExtensionPriority): this; onInit(hook: InitHook): this; onMount(hook: MountHook): this; onUnmount(hook: UnmountHook): this; onError(hook: ErrorHook): this; beforeOperation(hook: BeforeOperationHook): this; afterOperation(hook: AfterOperationHook): this; withComponent(component: ComponentExtensions): this; withState(state: StateExtensions): this; withApi(api: ApiExtensions): this; withClient(client: Record unknown>): this; withMetadata(metadata: Record): this; build(): EnzymeExtension; } /** * Extension event for pub/sub communication between extensions */ export interface ExtensionEvent { /** Event type/name */ type: string; /** Event payload */ payload: TPayload; /** Source extension */ source: string; /** Timestamp */ timestamp: number; /** Event metadata */ metadata?: Record; } /** * Extension event handler */ export type ExtensionEventHandler = (event: ExtensionEvent) => Promise | void; /** * Extension event emitter interface */ export interface IExtensionEventEmitter { /** Emit an event */ emit(type: string, payload: T, metadata?: Record): void; /** Subscribe to events */ on(type: string, handler: ExtensionEventHandler): () => void; /** Subscribe to events (once) */ once(type: string, handler: ExtensionEventHandler): () => void; /** Unsubscribe from events */ off(type: string, handler: ExtensionEventHandler): void; }