import { BannerContent, ModalContent, TooltipContent } from '@prosdevlab/experience-sdk-plugins'; export { BannerContent, ModalContent, TooltipContent, bannerPlugin, debugPlugin, frequencyPlugin } from '@prosdevlab/experience-sdk-plugins'; import { SDK } from '@lytics/sdk-kit'; /** * Type Definitions for Experience SDK * * These types define the public API surface and should remain stable. * Breaking changes to these types require a major version bump. */ /** * Experience Definition * * An experience represents a targeted piece of content (banner, modal, tooltip) * that should be shown to users based on targeting rules. */ interface Experience { /** Unique identifier for the experience */ id: string; /** Type of experience to render */ type: 'banner' | 'modal' | 'tooltip' | 'inline'; /** Rules that determine when/where to show this experience */ targeting: TargetingRules; /** Content to display (type-specific) */ content: ExperienceContent; /** Optional frequency capping configuration */ frequency?: FrequencyConfig; /** Priority for ordering (higher = more important, default: 0) */ priority?: number; /** Display conditions (triggers, timing) */ display?: DisplayConditions; } /** * Targeting Rules * * Rules that determine when an experience should be shown. * All rules must pass for the experience to be shown. */ interface TargetingRules { /** URL-based targeting */ url?: UrlRule; /** Frequency-based targeting */ frequency?: FrequencyRule; } /** * URL Targeting Rule * * Determines if current URL matches the target. * Multiple patterns can be specified; first match wins. */ interface UrlRule { /** URL must contain this string */ contains?: string; /** URL must exactly match this string */ equals?: string; /** URL must match this regular expression */ matches?: RegExp; } /** * Frequency Targeting Rule * * Limits how often an experience can be shown. */ interface FrequencyRule { /** Maximum number of times to show */ max: number; /** Time period for the cap */ per: 'session' | 'day' | 'week'; } /** * Frequency Configuration * * Configuration for frequency capping at the experience level. */ interface FrequencyConfig { /** Maximum number of impressions */ max: number; /** Time period for the cap */ per: 'session' | 'day' | 'week'; } /** * Display Conditions * * Conditions that determine when an experience should be displayed. */ interface DisplayConditions { /** Trigger type (e.g., scrollDepth, exitIntent, timeDelay) */ trigger?: string; /** Trigger-specific configuration data */ triggerData?: any; /** Frequency capping for this experience */ frequency?: FrequencyConfig; } /** * Experience Content (type-specific) * * Union type for all possible experience content types. * Content types are defined in the plugins package. */ type ExperienceContent = BannerContent | ModalContent | TooltipContent; /** * Modal Action Button * * Defines an action button in a modal. */ interface ModalAction { /** Button label text */ label: string; /** Action to perform when clicked */ action: 'close' | 'confirm' | 'dismiss'; } /** * Evaluation Context * * Context information used to evaluate targeting rules. * This is the input to the decision-making process. */ interface Context { /** Current page URL */ url?: string; /** User-specific context */ user?: UserContext; /** Evaluation timestamp */ timestamp?: number; /** Custom context properties */ custom?: Record; /** Trigger state (for display condition plugins) */ triggers?: TriggerState; } /** * Trigger State * * Tracks which trigger-based display conditions have fired. * Used by plugins like exitIntent, scrollDepth, pageVisits, timeDelay. */ interface TriggerState { /** Exit intent trigger state */ exitIntent?: { /** Whether the trigger has fired */ triggered: boolean; /** When the trigger fired (unix timestamp) */ timestamp?: number; /** Additional trigger-specific data */ lastY?: number; previousY?: number; velocity?: number; timeOnPage?: number; }; /** Scroll depth trigger state */ scrollDepth?: { triggered: boolean; timestamp?: number; /** Current scroll percentage (0-100) */ percent?: number; }; /** Page visits trigger state */ pageVisits?: { triggered: boolean; timestamp?: number; /** Total visit count */ count?: number; /** Whether this is the first visit */ firstVisit?: boolean; }; /** Time delay trigger state */ timeDelay?: { triggered: boolean; timestamp?: number; /** Total elapsed time (ms, includes paused time) */ elapsed?: number; /** Active elapsed time (ms, excludes paused time) */ activeElapsed?: number; /** Whether timer was paused */ wasPaused?: boolean; /** Number of visibility changes */ visibilityChanges?: number; }; /** Modal trigger state (when modal is shown) */ modal?: { triggered: boolean; timestamp?: number; /** Experience ID of the shown modal */ experienceId?: string; /** Whether the modal is currently showing */ shown?: boolean; }; /** Extensible for future triggers */ [key: string]: any; } /** * User Context * * User-specific information for targeting. */ interface UserContext { /** User identifier */ id?: string; /** Whether user is a returning visitor */ returning?: boolean; /** Additional custom user properties */ [key: string]: any; } /** * Decision Output - Core of Explainability * * The result of evaluating experiences against a context. * Includes human-readable reasons and machine-readable trace. */ interface Decision { /** Whether to show an experience */ show: boolean; /** ID of the experience to show (if show=true) */ experienceId?: string; /** Human-readable reasons for the decision */ reasons: string[]; /** Machine-readable trace of evaluation steps */ trace: TraceStep[]; /** Context used for evaluation */ context: Context; /** Metadata about the evaluation */ metadata: DecisionMetadata; } /** * Trace Step * * A single step in the evaluation trace. * Provides detailed information about each evaluation step. */ interface TraceStep { /** Name of the evaluation step */ step: string; /** When this step started (unix timestamp) */ timestamp: number; /** How long this step took (milliseconds) */ duration: number; /** Input to this step */ input?: any; /** Output from this step */ output?: any; /** Whether this step passed */ passed: boolean; } /** * Decision Metadata * * Metadata about the evaluation process. */ interface DecisionMetadata { /** When evaluation completed (unix timestamp) */ evaluatedAt: number; /** Total time taken (milliseconds) */ totalDuration: number; /** Number of experiences evaluated */ experiencesEvaluated: number; } /** * Experience SDK Configuration * * Configuration options for the Experience SDK. */ interface ExperienceConfig { /** Enable debug mode (verbose logging) */ debug?: boolean; /** Storage backend to use */ storage?: 'session' | 'local' | 'memory'; /** Additional custom configuration */ [key: string]: any; } /** * Runtime State * * Internal runtime state (exposed for inspection/debugging). */ interface RuntimeState { /** Whether the runtime has been initialized */ initialized: boolean; /** Registered experiences */ experiences: Map; /** History of decisions made */ decisions: Decision[]; /** Current configuration */ config: ExperienceConfig; } /** * Experience Runtime * * Core class that manages experience registration and evaluation. * Built on @lytics/sdk-kit for plugin system and lifecycle management. * * Design principles: * - Pure functions for evaluation logic (easy to test) * - Event-driven architecture (extensible via plugins) * - Explainability-first (every decision has reasons) */ declare class ExperienceRuntime { sdk: SDK; private experiences; private decisions; private initialized; private destroyed; private triggerContext; constructor(config?: ExperienceConfig); /** * Setup listeners for trigger:* events * This enables event-driven display conditions */ /** * Setup listeners for trigger:* events * This enables event-driven display conditions * * Note: sdk-kit's emitter passes only the event payload to wildcard listeners, * not the event name. Display condition plugins must include trigger metadata * in their payload (e.g., { trigger: 'exitIntent', ...data }) */ private setupTriggerListeners; /** * Initialize the runtime */ init(config?: ExperienceConfig): Promise; /** * Register an experience */ register(id: string, experience: Omit): void; /** * Evaluate experiences against context * Returns decision with explainability * First match wins (use evaluateAll() for multiple experiences) */ evaluate(context?: Partial): Decision; /** * Evaluate all experiences against context * Returns multiple decisions (sorted by priority) * All matching experiences will be shown */ evaluateAll(context?: Partial): Decision[]; /** * Explain a specific experience */ explain(experienceId: string): Decision | null; /** * Get runtime state (for inspection) */ getState(): RuntimeState; /** * Event subscription (proxy to SDK) */ on(event: string, handler: (...args: any[]) => void): () => void; /** * Destroy runtime */ destroy(): Promise; } /** * Build evaluation context from partial input * Pure function - no side effects */ declare function buildContext(partial?: Partial): Context; /** * Evaluate an experience against context * Pure function - returns reasons and trace */ declare function evaluateExperience(experience: Experience, context: Context): { matched: boolean; reasons: string[]; trace: TraceStep[]; }; /** * Evaluate URL targeting rule * Pure function - deterministic output */ declare function evaluateUrlRule(rule: UrlRule, url?: string): boolean; /** * Singleton Pattern Implementation * * Provides a default singleton instance with convenient wrapper functions * for simple use cases, plus createInstance() for advanced scenarios. */ /** * Create a new Experience SDK instance * * Use this for advanced scenarios where you need multiple isolated runtimes. * * @example * ```typescript * import { createInstance } from '@prosdevlab/experience-sdk'; * * const exp = createInstance({ debug: true }); * await exp.init(); * exp.register('welcome', { ... }); * ``` */ declare function createInstance(config?: ExperienceConfig): ExperienceRuntime; /** * Initialize the Experience SDK * * @example * ```typescript * import { init } from '@prosdevlab/experience-sdk'; * await init({ debug: true }); * ``` */ declare function init(config?: ExperienceConfig): Promise; /** * Register an experience * * @example * ```typescript * import { register } from '@prosdevlab/experience-sdk'; * * register('welcome-banner', { * type: 'banner', * targeting: { url: { contains: '/' } }, * content: { title: 'Welcome!', message: 'Thanks for visiting' } * }); * ``` */ declare function register(id: string, experience: Omit): void; /** * Evaluate experiences against current context * First match wins (use evaluateAll() for multiple experiences) * * @example * ```typescript * import { evaluate } from '@prosdevlab/experience-sdk'; * * const decision = evaluate({ url: window.location.href }); * if (decision.show) { * console.log('Show experience:', decision.experienceId); * console.log('Reasons:', decision.reasons); * } * ``` */ declare function evaluate(context?: Partial): Decision; /** * Evaluate all experiences against current context * Returns array of decisions sorted by priority (higher = more important) * All matching experiences will be shown * * @example * ```typescript * import { evaluateAll } from '@prosdevlab/experience-sdk'; * * const decisions = evaluateAll({ url: window.location.href }); * decisions.forEach(decision => { * if (decision.show) { * console.log('Show:', decision.experienceId); * console.log('Reasons:', decision.reasons); * } * }); * ``` */ declare function evaluateAll(context?: Partial): Decision[]; /** * Explain why a specific experience would/wouldn't show * * @example * ```typescript * import { explain } from '@prosdevlab/experience-sdk'; * * const explanation = explain('welcome-banner'); * console.log('Would show?', explanation?.show); * console.log('Reasons:', explanation?.reasons); * ``` */ declare function explain(experienceId: string): Decision | null; /** * Get current runtime state * * @example * ```typescript * import { getState } from '@prosdevlab/experience-sdk'; * * const state = getState(); * console.log('Initialized?', state.initialized); * console.log('Experiences:', Array.from(state.experiences.keys())); * ``` */ declare function getState(): RuntimeState; /** * Subscribe to SDK events * * @example * ```typescript * import { on } from '@prosdevlab/experience-sdk'; * * const unsubscribe = on('experiences:evaluated', (decision) => { * console.log('Evaluation:', decision); * }); * * // Later: unsubscribe() * ``` */ declare function on(event: string, handler: (...args: unknown[]) => void): () => void; /** * Destroy the SDK instance * * @example * ```typescript * import { destroy } from '@prosdevlab/experience-sdk'; * await destroy(); * ``` */ declare function destroy(): Promise; declare const experiencesProxy: { createInstance: typeof createInstance; init: typeof init; register: typeof register; evaluate: typeof evaluate; evaluateAll: typeof evaluateAll; explain: typeof explain; getState: typeof getState; on: typeof on; destroy: typeof destroy; }; export { type Context, type Decision, type DecisionMetadata, type Experience, type ExperienceConfig, type ExperienceContent, ExperienceRuntime, type FrequencyConfig, type FrequencyRule, type ModalAction, type RuntimeState, type TargetingRules, type TraceStep, type UrlRule, type UserContext, buildContext, createInstance, destroy, evaluate, evaluateAll, evaluateExperience, evaluateUrlRule, experiencesProxy as experiences, explain, getState, init, on, register };