import { EnzymeExtensionManager } from './manager.js'; import { EnzymeExtension, LifecycleHooks, IExtensionEventEmitter } from './types.js'; /** * Configuration for enzyme extension client */ export interface EnzymeExtensionClientConfig { /** Enable debug logging */ debug?: boolean; /** Custom configuration */ [key: string]: unknown; } /** * Enzyme client with Prisma-like $extends method * * @example * ```ts * const client = createExtensionClient() * .$extends(loggingExtension) * .$extends(cacheExtension) * .$extends(metricsExtension); * * // Extensions are immutable - each $extends returns a new client * const clientWithLogging = client.$extends(loggingExtension); * const clientWithAll = clientWithLogging.$extends(cacheExtension); * * // Use client methods (added by extensions) * await client.myCustomMethod(); * ``` */ export declare class EnzymeExtensionClient { private readonly manager; private readonly config; constructor(config?: EnzymeExtensionClientConfig, manager?: EnzymeExtensionManager); /** * Extend the client with an extension (Prisma pattern) * Returns a new client instance with the extension applied (immutable) * * @param extension - The extension to apply * @returns A new client with the extension registered * * @example * ```ts * const loggingExtension: EnzymeExtension = { * name: 'logging', * hooks: { * beforeOperation: async (ctx) => { * console.log(`[${ctx.operation}] Starting...`); * }, * }, * client: { * log: (message: string) => { * console.log(`[CLIENT] ${message}`); * }, * }, * }; * * const client = new EnzymeExtensionClient().$extends(loggingExtension); * client.log('Hello, world!'); // Uses extension method * ``` */ $extends(extension: EnzymeExtension): this; /** * Get the extension manager (for advanced use cases) * * @example * ```ts * const manager = client.$manager; * console.log(manager.count); // Number of registered extensions * ``` */ get $manager(): EnzymeExtensionManager; /** * Get the event emitter for inter-extension communication * * @example * ```ts * client.$events.on('user:login', (event) => { * console.log('User logged in:', event.payload); * }); * * client.$events.emit('user:login', { userId: 123 }); * ``` */ get $events(): IExtensionEventEmitter; /** * Execute lifecycle hooks manually * * @example * ```ts * await client.$executeHooks('onMount', { * component: 'MyComponent', * // ... * }); * ``` */ $executeHooks(hookName: keyof LifecycleHooks, context: unknown): Promise; /** * Execute beforeOperation hooks * Returns modified args and cancellation status * * @example * ```ts * const { args, cancelled } = await client.$beforeOperation('fetchUser', { * userId: 123, * }); * * if (!cancelled) { * // Proceed with operation using modified args * } * ``` */ $beforeOperation(operation: string, args: TArgs, metadata?: Record): Promise<{ args: TArgs; cancelled: boolean; }>; /** * Execute afterOperation hooks * Returns modified result * * @example * ```ts * const startTime = Date.now(); * const result = await fetchUser(userId); * const duration = Date.now() - startTime; * * const modifiedResult = await client.$afterOperation( * 'fetchUser', * { userId }, * result, * duration * ); * ``` */ $afterOperation(operation: string, args: TArgs, result: TResult, duration: number, metadata?: Record): Promise; /** * Execute mount hooks (React lifecycle) * * @example * ```ts * useEffect(() => { * client.$mount('MyComponent'); * return () => client.$unmount('MyComponent'); * }, []); * ``` */ $mount(component?: string, data?: Record): Promise; /** * Execute unmount hooks (React lifecycle) */ $unmount(component?: string, data?: Record): Promise; /** * Get list of registered extension names * * @example * ```ts * const extensions = client.$list(); * console.log(`Registered extensions: ${extensions.join(', ')}`); * ``` */ $list(): string[]; /** * Get extension by name * * @example * ```ts * const extension = client.$get('logging'); * if (extension) { * console.log('Logging extension version:', extension.version); * } * ``` */ $get(name: string): EnzymeExtension | undefined; /** * Check if extension is registered * * @example * ```ts * if (client.$has('analytics')) { * // Analytics extension is available * } * ``` */ $has(name: string): boolean; /** * Get count of registered extensions * * @example * ```ts * console.log(`${client.$count} extensions registered`); * ``` */ get $count(): number; /** * Wrap an async operation with before/after hooks * * @example * ```ts * const fetchUser = async (userId: number) => { * return client.$wrap('fetchUser', { userId }, async (args) => { * const response = await fetch(`/api/users/${args.userId}`); * return response.json(); * }); * }; * ``` */ $wrap, TResult>(operation: string, args: TArgs, fn: (args: TArgs) => Promise, metadata?: Record): Promise; /** * Bind client methods from all registered extensions * This makes extension methods available directly on the client */ private bindClientMethods; } /** * Create a new enzyme extension client * * @param config - Optional client configuration * @returns A new extension client * * @example * ```ts * const client = createExtensionClient({ debug: true }); * ``` */ export declare function createExtensionClient(config?: EnzymeExtensionClientConfig): EnzymeExtensionClient; /** * Create a pre-configured enzyme client with extensions * * @param extensions - Extensions to register * @param config - Optional client configuration * @returns A new extension client with extensions applied * * @example * ```ts * const client = createClientWithExtensions( * [loggingExtension, cacheExtension], * { debug: true } * ); * ``` */ export declare function createClientWithExtensions(extensions: EnzymeExtension[], config?: EnzymeExtensionClientConfig): EnzymeExtensionClient; /** * Define an extension with the fluent builder API * * @example * ```ts * import { defineExtension } from '@/lib/extensions'; * * const myExtension = defineExtension({ * name: 'my-extension', * version: '1.0.0', * hooks: { * onInit: async (ctx) => { * console.log('Extension initialized!'); * }, * }, * client: { * myMethod: () => { * console.log('Custom method from extension'); * }, * }, * }); * * const client = createExtensionClient().$extends(myExtension); * client.myMethod(); // "Custom method from extension" * ``` */ export declare function defineExtension(extension: T): T;