/** * Configuration management with dot-notation paths and underwrite pattern. * * The Config class manages SDK configuration with support for: * - Dot-notation paths for nested access (`'my.plugin.setting'`) * - Underwrite pattern for defaults (existing values take precedence) * - Required plugin tracking * - Immutable getAll() for safe access * * @example * ```typescript * const config = new Config({ api: { timeout: 5000 } }); * * // Set defaults (won't overwrite existing timeout) * config.defaults({ api: { timeout: 3000, retries: 3 } }); * * // Get with dot-notation * config.get('api.timeout'); // 5000 * config.get('api.retries'); // 3 * * // Set values * config.set('api.baseUrl', 'https://api.example.com'); * ``` */ declare class Config { private data; private required; /** * Create a new Config instance. * * @param initialConfig - Initial configuration object */ constructor(initialConfig?: Record); /** * Set default configuration values using underwrite pattern. * * Existing configuration values always take precedence over defaults. * This allows plugins to provide defaults without overwriting user config. * * @param config - Default configuration object * * @example * ```typescript * // User provided config * const config = new Config({ api: { timeout: 10000 } }); * * // Plugin sets defaults * config.defaults({ * api: { timeout: 3000, retries: 3 }, * debug: false * }); * * // Result: { api: { timeout: 10000, retries: 3 }, debug: false } * // User's timeout (10000) wins over default (3000) * ``` */ defaults(config: Record): void; /** * Merge configuration values (new values override existing). * * New configuration values take precedence over existing values. * This is the opposite of defaults() and is used when user provides new config. * * @param config - Configuration object to merge * * @example * ```typescript * const config = new Config({ api: { timeout: 3000 } }); * * // User provides new config * config.merge({ api: { timeout: 10000, retries: 3 } }); * * // Result: { api: { timeout: 10000, retries: 3 } } * // New timeout (10000) wins over existing (3000) * ``` */ merge(config: Record): void; /** * Get a configuration value by dot-notation path. * * @param path - Dot-notation path (e.g., 'api.timeout') * @returns Configuration value or undefined if not found * * @example * ```typescript * config.get('api.timeout'); // 5000 * config.get('api.retries'); // 3 * config.get('nonexistent.path'); // undefined * config.get('api.timeout'); // Type-safe access * ``` */ get(path: string): T; /** * Set a configuration value by dot-notation path. * * Creates intermediate objects as needed. * * @param path - Dot-notation path (e.g., 'api.timeout') * @param value - Value to set * * @example * ```typescript * config.set('api.timeout', 5000); * config.set('api.headers.authorization', 'Bearer token'); * config.set('deeply.nested.value', 42); * ``` */ set(path: string, value: any): void; /** * Mark a plugin namespace as required. * * Required plugins must be properly enabled for the SDK to function. * * @param namespace - Plugin namespace to mark as required * * @example * ```typescript * config.markRequired('analytics'); * config.isRequired('analytics'); // true * ``` */ markRequired(namespace?: string): void; /** * Check if a plugin namespace is marked as required. * * @param namespace - Plugin namespace to check * @returns True if the namespace is required */ isRequired(namespace: string): boolean; /** * Get all configuration as an immutable copy. * * Returns a deep copy to prevent external mutation of config. * * @returns Copy of the entire configuration object * * @example * ```typescript * const allConfig = config.getAll(); * allConfig.api = {}; // Does not affect internal config * ``` */ getAll(): Record; } /** * Event Emitter with wildcard pattern matching support. * * Supports wildcard patterns for event subscriptions: * - Exact match: `'widget.show'` matches `'widget.show'` * - Wildcard suffix: `'widget.*'` matches `'widget.show'`, `'widget.hide'`, etc. * - Wildcard prefix: `'*.show'` matches `'widget.show'`, `'modal.show'`, etc. * - Match all: `'*'` matches all events * * Uses regex compilation for efficient pattern matching. */ declare class Emitter$1 { private subscriptions; /** * Subscribe to an event or pattern. * * @param event - Event name or wildcard pattern * @param handler - Event handler function * @returns Unsubscribe function * * @example * ```typescript * const emitter = new Emitter(); * * // Exact match * emitter.on('user.login', (data) => console.log('Login:', data)); * * // Wildcard patterns * emitter.on('user.*', (data) => console.log('User event:', data)); * emitter.on('*.error', (data) => console.log('Error:', data)); * emitter.on('*', (data) => console.log('Any event:', data)); * * // Unsubscribe * const unsub = emitter.on('test', handler); * unsub(); * ``` */ on(event: string, handler: (...args: any[]) => void): () => void; /** * Unsubscribe from an event or pattern. * * @param event - Event name or pattern to unsubscribe from * @param handler - Handler function to remove */ off(event: string, handler: (...args: any[]) => void): void; /** * Emit an event to all matching subscribers. * * Notifies all handlers whose patterns match the event name. * Handlers are called with the provided arguments. * Errors in handlers are caught and logged to prevent breaking the event flow. * * @param event - Event name to emit * @param args - Arguments to pass to handlers * * @example * ```typescript * emitter.emit('user.login', { userId: '123' }); * emitter.emit('widget.show', { id: 'modal-1' }, { animate: true }); * ``` */ emit(event: string, ...args: any[]): void; /** * Remove all event listeners. * * Useful for cleanup when destroying the SDK instance. */ removeAllListeners(): void; /** * Compile a pattern string into a RegExp for matching. * * Converts wildcard patterns into regular expressions: * - `widget.*` → `/^widget\.(.*?)$/` * - `*.show` → `/^(.*?)\.show$/` * - `*` → `/^(.*?)$/` * * @param pattern - Pattern string with optional wildcards * @returns Compiled RegExp for matching event names * @private */ private compilePattern; /** * Escape special regex characters in a string. * * @param str - String to escape * @returns Escaped string safe for use in RegExp * @private */ private escapeRegExp; } /** * Expose capability for adding plugin methods to SDK instance. * * Plugins use this to add public API methods that users can call. * Methods are merged directly onto the SDK instance. * * @example * ```typescript * const expose = new Expose(sdkInstance); * expose.expose({ * track(event: string) { * console.log('Tracking:', event); * } * }); * // Now: sdk.track('page_view'); * ``` */ declare class Expose { private sdk; /** * Create an Expose instance. * * @param sdk - SDK instance to expose methods on */ constructor(sdk: any); /** * Expose methods on the SDK instance. * * Merges the provided methods object onto the SDK instance, * making them available as `sdk.methodName()`. * * @param api - Object containing methods to expose * * @example * ```typescript * expose.expose({ * track(event: string, properties?: any) { * // Track event * }, * identify(userId: string) { * // Identify user * } * }); * * // Available as: * // sdk.track('page_view', { path: '/home' }); * // sdk.identify('user-123'); * ``` */ expose(api: Record): void; } /** * Namespace capability for plugin identification. * * Each plugin must claim a unique namespace to identify itself. * Namespaces are used for config scoping and event namespacing. * * @example * ```typescript * const namespace = new Namespace(); * namespace.ns('analytics.tracking'); * console.log(namespace.name); // 'analytics.tracking' * ``` */ declare class Namespace { /** * The plugin's namespace. * Set via the `ns()` method, can only be set once. */ name: string; /** * Set the plugin's namespace. * * Can only be called once per instance. Attempting to set it again throws an error. * * @param namespace - Dot-notation namespace (e.g., 'analytics.tracking') * @throws Error if namespace is already set * * @example * ```typescript * const ns = new Namespace(); * ns.ns('my.plugin'); // Success * ns.ns('other.plugin'); // Throws Error * ``` */ ns(namespace: string): void; } /** * Capability interfaces for the SDK Kit plugin system. * * These interfaces define the capabilities that plugins receive via capability injection. * Each capability provides specific functionality that plugins can use. * * @module capability.types */ /** * Capability for setting a plugin's namespace. * * Plugins must claim a namespace to identify themselves and scope their configuration. * The namespace is used for config scoping and event namespacing. * * @example * ```typescript * plugin.ns('analytics.tracking'); * ``` */ interface Namespaced { /** * Set the plugin's namespace. * * @param namespace - Dot-notation namespace (e.g., 'analytics.tracking') */ ns(namespace: string): void; } /** * Capability for emitting and subscribing to events. * * Provides an event system with wildcard pattern matching support. * Plugins can listen to events and emit their own namespaced events. * * @example * ```typescript * // Subscribe to events * const unsubscribe = plugin.on('user.*', (event, data) => { * console.log('User event:', event, data); * }); * * // Emit events * plugin.emit('user.login', { userId: '123' }); * * // Unsubscribe * unsubscribe(); * ``` */ interface Emitter { /** * Subscribe to an event. * * Supports wildcard patterns: * - Exact match: `'user.login'` * - Wildcard suffix: `'user.*'` matches all `user.` events * - Wildcard prefix: `'*.login'` matches all `.login` events * - Match all: `'*'` matches all events * * @param event - Event name or pattern * @param handler - Event handler function * @returns Unsubscribe function */ on(event: string, handler: (...args: any[]) => void): () => void; /** * Unsubscribe from an event. * * @param event - Event name or pattern * @param handler - Event handler function to remove */ off(event: string, handler: (...args: any[]) => void): void; /** * Emit an event. * * Notifies all matching listeners with the provided arguments. * * @param event - Event name * @param args - Arguments to pass to handlers */ emit(event: string, ...args: any[]): void; } /** * Capability for setting default configuration values. * * Plugins can provide default configuration that won't overwrite existing user config. * Uses an "underwrite" pattern where existing values take precedence. * * @example * ```typescript * plugin.defaults({ * analytics: { * tracking: { * enabled: true, * sampleRate: 1.0 * } * } * }); * ``` */ interface Defaulter { /** * Set default configuration values. * * Only sets values that don't already exist in the config. * Existing user configuration always takes precedence. * * @param config - Default configuration object */ defaults(config: Record): void; } /** * Capability for exposing public API methods. * * Plugins can add methods to the SDK instance that users can call. * Exposed methods become part of the SDK's public API. * * @example * ```typescript * plugin.expose({ * track(event: string, properties?: Record) { * plugin.emit('analytics.track', { event, properties }); * }, * identify(userId: string) { * plugin.emit('analytics.identify', { userId }); * } * }); * * // Users can then call: * // sdk.track('Page Viewed', { path: '/home' }); * // sdk.identify('user-123'); * ``` */ interface Exposer { /** * Expose methods on the SDK instance. * * @param api - Object containing methods to expose */ expose(api: Record): void; } /** * Capability for marking a plugin as required. * * Required plugins prevent the SDK from initializing if they're not properly configured. * This is useful for critical plugins that the SDK depends on. * * @example * ```typescript * plugin.mustEnable(); * ``` */ interface Requirer { /** * Mark this plugin as required. * * The SDK will ensure required plugins are properly enabled before initialization. */ mustEnable(): void; } /** * Capability for plugins to extend other plugins. * * Allows plugins to register methods that other plugins can use, creating a * plugin-to-plugin API separate from the user-facing API exposed via expose(). * * This enables patterns like: * - Cross-cutting utilities (logging, metrics, debugging) * - Middleware patterns (consent gating, rate limiting) * - Validation utilities (schema validation, type checking) * * ## Type Safety with Module Augmentation * * For type-safe held capabilities, use TypeScript module augmentation to extend * the Plugin interface with your custom methods: * * ```typescript * // logging-plugin.ts * import type { Plugin } from '@lytics/sdk-kit'; * * // Extend the Plugin interface * declare module '@lytics/sdk-kit' { * interface Plugin { * log?(level: 'debug' | 'info' | 'warn' | 'error', message: string, data?: any): void; * } * } * * export const loggingPlugin: PluginFunction = (plugin, instance, config) => { * plugin.ns('logging'); * * plugin.hold({ * log(level: 'debug' | 'info' | 'warn' | 'error', message: string, data?: any) { * const namespace = this.namespace || 'sdk'; * console.log(`[${namespace}] [${level}] ${message}`, data); * } * }); * }; * ``` * * After importing the logging plugin, TypeScript will provide autocomplete * and type checking for plugin.log() calls in other plugins: * * ```typescript * // storage-plugin.ts * import '../logging-plugin'; // Triggers module augmentation * * export const storagePlugin: PluginFunction = (plugin, instance, config) => { * plugin.ns('storage'); * * // TypeScript knows about plugin.log() and its signature * plugin.log?.('info', 'Storage initialized'); * * plugin.expose({ * storage: { * set(key: string, value: any) { * // Autocomplete shows valid log levels * plugin.log?.('debug', 'Storage set', { key }); * localStorage.setItem(key, JSON.stringify(value)); * } * } * }); * }; * ``` * * ## Safe Patterns for Held Capabilities * * ### Pattern 1: Optional Dependencies (Graceful Degradation) * * ```typescript * function storagePlugin(plugin, instance, config) { * plugin.ns('storage'); * * // Check capability and warn if missing * if (!plugin.hasCapability('log')) { * console.warn('[storage] Logging plugin not loaded - logs disabled'); * } * * // Use optional chaining for safe access * plugin.log?.('info', 'Storage initialized'); * } * ``` * * ### Pattern 2: Required Dependencies (Fail Fast) * * ```typescript * function analyticsPlugin(plugin, instance, config) { * plugin.ns('analytics'); * * // Fail if required capability missing * if (!plugin.hasCapability('log')) { * throw new Error('Analytics plugin requires logging plugin to be loaded first'); * } * * // Safe to call without optional chaining * plugin.log('info', 'Analytics initialized'); * } * ``` * * ### Pattern 3: Conditional Features * * ```typescript * function transportPlugin(plugin, instance, config) { * plugin.ns('transport'); * * const hasLogging = plugin.hasCapability('log'); * const hasMetrics = plugin.hasCapability('recordMetric'); * * plugin.expose({ * send(request: any) { * const startTime = Date.now(); * * fetch(request.url, request.options) * .then(response => { * if (hasLogging) { * plugin.log?.('info', 'Request completed', { url: request.url }); * } * if (hasMetrics) { * plugin.recordMetric?.('http.duration', Date.now() - startTime); * } * }); * } * }); * } * ``` * * @example Basic usage - Providing a capability * ```typescript * // Logging plugin provides capability * function loggingPlugin(plugin, instance, config) { * plugin.ns('logging'); * * plugin.hold({ * log(level: string, message: string, data?: any) { * console.log(`[${this.namespace}] ${message}`, data); * } * }); * } * ``` * * @example Basic usage - Consuming a capability * ```typescript * // Storage plugin uses capability * function storagePlugin(plugin, instance, config) { * plugin.ns('storage'); * * if (!plugin.hasCapability('log')) { * console.warn('Logging not available'); * } * * plugin.log?.('info', 'Storage initialized'); * } * ``` */ interface Extensible { /** * Register capabilities that other plugins can use. * * Methods are added to Plugin.prototype, making them available to all * plugin instances as if they were built-in capabilities. * * Held methods are bound to the calling plugin's context, so `this.namespace` * refers to the plugin that calls the method, not the plugin that registered it. * * **Load Order**: Plugins must call hold() before other plugins can use the capability. * Provider plugins should load before consumer plugins. * * **Type Safety**: Use TypeScript module augmentation to add type definitions for * held capabilities. See the Extensible interface documentation for examples. * * @param methods - Object containing methods to register * * @example Providing a logging capability * ```typescript * plugin.hold({ * log(level: string, message: string, data?: any) { * const namespace = this.namespace || 'sdk'; * console.log(`[${namespace}] ${message}`, data); * } * }); * ``` * * @example Providing multiple capabilities * ```typescript * plugin.hold({ * log(level: string, message: string, data?: any) { * console.log(`[${this.namespace}] ${message}`, data); * }, * debug(message: string, data?: any) { * if (config.get('debug.enabled')) { * console.debug(`[${this.namespace}] ${message}`, data); * } * } * }); * ``` */ hold(methods: Record): void; /** * Check if a capability has been registered. * * Use this to validate dependencies before calling held methods. * Enables graceful degradation when optional capabilities are missing. * * **Best Practice**: Always check capabilities before using them, or use * optional chaining (`plugin.log?.()`) for safe access. * * @param name - Capability name to check * @returns True if capability has been registered * * @example Checking optional dependency * ```typescript * if (!plugin.hasCapability('log')) { * console.warn('[storage] Logging not available - logs disabled'); * } * * // Safe to use with optional chaining * plugin.log?.('info', 'Operation completed'); * ``` * * @example Checking required dependency * ```typescript * if (!plugin.hasCapability('log')) { * throw new Error('This plugin requires logging plugin to be loaded first'); * } * * // Safe to call without optional chaining * plugin.log('info', 'Operation completed'); * ``` * * @example Conditional feature enablement * ```typescript * const hasLogging = plugin.hasCapability('log'); * const hasMetrics = plugin.hasCapability('recordMetric'); * * function performOperation() { * if (hasLogging) { * plugin.log?.('info', 'Operation started'); * } * // ... operation logic ... * if (hasMetrics) { * plugin.recordMetric?.('operations', 1); * } * } * ``` */ hasCapability(name: string): boolean; } /** * Plugin system types. * * These types define the plugin architecture and function signatures. * * @module plugin.types */ /** * Plugin interface combining all capabilities. * * Plugins receive this object as their first parameter, providing access to * all plugin capabilities through capability injection. * * This follows the JSTag3 pattern of intersection types for capabilities. * * @since 1.0.0 - Base capabilities (Namespaced, Emitter, Defaulter, Exposer, Requirer) * @since 2.0.0 - Added Extensible for plugin-to-plugin capabilities */ interface Plugin extends Namespaced, Emitter, Defaulter, Exposer, Requirer, Extensible { } /** * Plugin function signature. * * Plugins are pure functions that receive capabilities and configure themselves. * This follows the functional plugin pattern from JSTag3. * * Plugins can: * 1. **Set namespace** - Identify themselves and scope configuration * 2. **Set defaults** - Provide default configuration values * 3. **Expose public API** - Add methods to the SDK instance for users * 4. **Hold capabilities** - Provide methods to other plugins (plugin-to-plugin API) * 5. **Listen to events** - Subscribe to SDK and plugin events * 6. **Mark as required** - Prevent SDK initialization if not properly configured * * @param plugin - Plugin capabilities (namespace, emit, defaults, expose, hold, etc.) * @param instance - SDK instance for subscribing to SDK events * @param config - Configuration object for reading plugin config * * @example Basic plugin with user-facing API * ```typescript * function analyticsPlugin( * plugin: Plugin, * instance: SDK, * config: Config * ): void { * // 1. Set namespace * plugin.ns('analytics'); * * // 2. Set defaults * plugin.defaults({ * analytics: { * enabled: true, * endpoint: '/api/track' * } * }); * * // 3. Expose public API * plugin.expose({ * track(event: string, properties?: any) { * const endpoint = config.get('analytics.endpoint'); * fetch(endpoint, { * method: 'POST', * body: JSON.stringify({ event, properties }) * }); * } * }); * * // 4. Listen to SDK events * instance.on('sdk:ready', () => { * console.log('Analytics plugin initialized'); * }); * } * * // Usage * const sdk = new SDK({ analytics: { endpoint: '/track' } }); * sdk.use(analyticsPlugin); * await sdk.init(); * sdk.track('Page Viewed'); * ``` * * @example Plugin providing capabilities to other plugins * ```typescript * // Logging plugin provides log() capability to other plugins * function loggingPlugin(plugin: Plugin, instance: SDK, config: Config): void { * plugin.ns('logging'); * * plugin.defaults({ * logging: { enabled: true, level: 'info' } * }); * * // Provide capability to other plugins via hold() * plugin.hold({ * log(level: string, message: string, data?: any) { * if (!config.get('logging.enabled')) return; * const namespace = this.namespace || 'sdk'; * console.log(`[${namespace}] [${level}] ${message}`, data); * } * }); * } * * // Usage: Load logging first, then other plugins can use plugin.log() * sdk.use(loggingPlugin).use(storagePlugin); * ``` * * @example Plugin using capabilities from other plugins * ```typescript * function storagePlugin(plugin: Plugin, instance: SDK, config: Config): void { * plugin.ns('storage'); * * // Check if logging capability is available * if (!plugin.hasCapability('log')) { * console.warn('[storage] Logging plugin not loaded - logs disabled'); * } * * // Use logging capability if available (safe with optional chaining) * plugin.log?.('info', 'Storage plugin initialized'); * * plugin.expose({ * storage: { * set(key: string, value: any) { * plugin.log?.('debug', 'Storage set', { key }); * localStorage.setItem(key, JSON.stringify(value)); * }, * get(key: string): any { * plugin.log?.('debug', 'Storage get', { key }); * const value = localStorage.getItem(key); * return value ? JSON.parse(value) : undefined; * } * } * }); * } * * // Usage: Load logging before storage to enable logging * sdk.use(loggingPlugin).use(storagePlugin); * ``` * * @example Plugin with required dependency * ```typescript * function analyticsPlugin(plugin: Plugin, instance: SDK, config: Config): void { * plugin.ns('analytics'); * * // Fail fast if required capability is missing * if (!plugin.hasCapability('log')) { * throw new Error('Analytics plugin requires logging plugin to be loaded first'); * } * * plugin.log('info', 'Analytics initialized'); * * plugin.expose({ * track(event: string, properties?: any) { * plugin.log('debug', 'Tracking event', { event, properties }); * // ... tracking logic ... * } * }); * } * * // Load order matters: logging must be loaded first * sdk.use(loggingPlugin).use(analyticsPlugin); * ``` */ type PluginFunction = (plugin: Plugin, instance: SDK, config: Config) => void; /** * SDK configuration and related types. * * @module sdk.types */ /** * Configuration object passed to the SDK constructor. * * The SDK accepts any configuration shape, allowing plugins to define * their own namespaced configuration. * * @example * ```typescript * const sdk = new SDK({ * name: 'my-app', * analytics: { * tracking: { * enabled: true, * apiKey: 'abc123' * } * }, * storage: { * type: 'localStorage', * prefix: 'myapp_' * } * }); * ``` */ interface SDKConfig { /** * Optional SDK name for identification. */ name?: string; /** * Additional configuration properties. * * Plugins typically namespace their config under their plugin name. * For example, a storage plugin might use `config.storage`. */ [key: string]: any; } /** * Main SDK class * * Composes all capabilities and provides the plugin registration system. * Follows functional plugin architecture with capability injection. */ /** * SDK - Main SDK class for building JavaScript SDKs * * @example * ```typescript * const sdk = new SDK({ name: 'my-sdk' }); * * sdk.use((plugin, instance, config) => { * plugin.ns('my.plugin'); * plugin.defaults({ my: { setting: 'value' } }); * plugin.expose({ * track(event: string) { * console.log('Tracking:', event); * } * }); * }); * * await sdk.init(); * sdk.track('page_view'); * ``` */ declare class SDK { /** * Configuration instance * @private */ private configInstance; /** * Event emitter instance * @private */ private emitter; /** * Registered plugins by namespace * @private */ private plugins; /** * Registry of capabilities held by plugins * @private */ private capabilities; /** * Initialization state * @private */ private isInitialized; /** * Create a new SDK instance. * * @param config - Initial SDK configuration * * @example * ```typescript * const sdk = new SDK({ * name: 'my-sdk', * api: { * endpoint: 'https://api.example.com', * timeout: 5000 * } * }); * ``` */ constructor(config?: SDKConfig); /** * Register a plugin. * * Plugins receive capability-injected objects and can extend the SDK. * Supports method chaining. * * @param pluginFn - Plugin function * @returns this - For method chaining * * @example * ```typescript * sdk * .use(analyticsPlugin) * .use(trackingPlugin) * .init(); * ``` */ use(pluginFn: PluginFunction): this; /** * Initialize the SDK. * * Emits `sdk:init` event before initialization and `sdk:ready` after. * Idempotent - can be called multiple times safely. * * @param config - Optional configuration to merge with existing config * @returns Promise that resolves when initialization is complete * * @example * ```typescript * sdk.on('sdk:ready', () => { * console.log('SDK is ready!'); * }); * * await sdk.init({ api: { timeout: 5000 } }); * ``` */ init(config?: SDKConfig): Promise; /** * Destroy the SDK. * * Emits `sdk:destroy` event, clears all plugins, and removes all event listeners. * * @returns Promise that resolves when destruction is complete * * @example * ```typescript * await sdk.destroy(); * ``` */ destroy(): Promise; /** * Get a configuration value by path. * * Delegates to the Config capability. * * @param path - Dot-notation path (e.g., 'api.timeout') * @returns Configuration value * * @example * ```typescript * const timeout = sdk.get('api.timeout'); * const nested = sdk.get('my.plugin.setting'); * ``` */ get(path: string): T; /** * Set a configuration value by path. * * Delegates to the Config capability. * * @param path - Dot-notation path (e.g., 'api.timeout') * @param value - Value to set * * @example * ```typescript * sdk.set('api.timeout', 10000); * sdk.set('my.plugin.enabled', true); * ``` */ set(path: string, value: any): void; /** * Subscribe to an event. * * Delegates to the Emitter capability. Supports wildcard patterns. * * @param event - Event name or pattern (e.g., 'track:*') * @param handler - Event handler function * @returns Unsubscribe function * * @example * ```typescript * const unsubscribe = sdk.on('track:page', (data) => { * console.log('Page tracked:', data); * }); * * // Later... * unsubscribe(); * ``` */ on(event: string, handler: (...args: any[]) => void): () => void; /** * Unsubscribe from an event. * * Delegates to the Emitter capability. * * @param event - Event name * @param handler - Event handler function to remove * * @example * ```typescript * const handler = () => console.log('ready'); * sdk.on('sdk:ready', handler); * sdk.off('sdk:ready', handler); * ``` */ off(event: string, handler: (...args: any[]) => void): void; /** * Emit an event. * * Delegates to the Emitter capability. * * @param event - Event name * @param args - Event arguments * * @example * ```typescript * sdk.emit('custom:event', { data: 'value' }); * ``` */ emit(event: string, ...args: any[]): void; /** * Get all configuration as an immutable copy. * * Delegates to the Config capability. * * @returns Copy of the entire configuration object * * @example * ```typescript * const allConfig = sdk.getAll(); * console.log(allConfig); * ``` */ getAll(): Record; /** * Check if SDK is initialized. * * @returns true if initialized, false otherwise * * @example * ```typescript * if (sdk.isReady()) { * sdk.track('event'); * } * ``` */ isReady(): boolean; } /** * Plugin registration helper * TODO: Implement per specs/phase-1-core-sdk/plan.md */ declare function use(this: any, pluginFn: PluginFunction): any; /** * Deep merge utility with "underwrite" pattern. * * Recursively merges source into target, where **target values take precedence**. * This is the opposite of typical deep merge where source wins. * * This "underwrite" pattern is used for config defaults: * - User config (target) always wins * - Defaults (source) only fill in missing values * * @param target - Target object (takes precedence) * @param source - Source object (provides defaults) * @returns New merged object (does not mutate inputs) * * @example * ```typescript * const userConfig = { api: { timeout: 5000 } }; * const defaults = { api: { timeout: 3000, retries: 3 }, debug: false }; * * const result = deepMerge(target, source); * // Result: { * // api: { timeout: 5000, retries: 3 }, // timeout from user, retries from defaults * // debug: false // debug from defaults * // } * ``` */ declare function deepMerge(target: Record, source: Record): Record; export { Config, type Defaulter, type Emitter, Emitter$1 as EventEmitter, Expose, type Exposer, type Extensible, Namespace, type Namespaced, type Plugin, type PluginFunction, type Requirer, SDK, type SDKConfig, deepMerge, use };