UNPKG

perf-observer-kit

Version:

A lightweight, flexible library for monitoring web performance metrics including Core Web Vitals, resource loading performance, long tasks, and navigation timing.

3,082 lines 127 kB
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.PerfObserverKit = {}));
})(this, (function (exports) { 'use strict';

    /**
     * 指标类型枚举
     */
    exports.MetricType = void 0;
    (function (MetricType) {
        MetricType["WEB_VITALS"] = "coreWebVitals";
        MetricType["RESOURCES"] = "resources";
        MetricType["LONG_TASKS"] = "longTasks";
        MetricType["NAVIGATION"] = "navigation";
        MetricType["BROWSER_INFO"] = "browserInfo";
    })(exports.MetricType || (exports.MetricType = {}));

    /**
     * Utility functions to check browser support for performance APIs
     */
    const browserSupport = {
        /**
         * Check if the Performance API is supported
         */
        hasPerformanceAPI() {
            return typeof window !== 'undefined' &&
                typeof performance !== 'undefined';
        },
        /**
         * Check if PerformanceObserver is supported
         */
        hasPerformanceObserver() {
            return typeof window !== 'undefined' &&
                typeof PerformanceObserver !== 'undefined';
        },
        /**
         * Check if a specific performance entry type is supported
         */
        supportsEntryType(entryType) {
            if (!this.hasPerformanceObserver()) {
                return false;
            }
            // In modern browsers, we can check supported entry types
            if (PerformanceObserver.supportedEntryTypes) {
                return PerformanceObserver.supportedEntryTypes.includes(entryType);
            }
            // Fallback detection for older browsers
            switch (entryType) {
                case 'navigation':
                    return typeof PerformanceNavigationTiming !== 'undefined';
                case 'resource':
                    return typeof PerformanceResourceTiming !== 'undefined';
                case 'largest-contentful-paint':
                case 'layout-shift':
                case 'first-input':
                case 'longtask':
                    // No reliable feature detection for these in older browsers
                    // Try to create an observer as a test
                    try {
                        const observer = new PerformanceObserver(() => { });
                        observer.observe({ type: entryType, buffered: true });
                        observer.disconnect();
                        return true;
                    }
                    catch (e) {
                        return false;
                    }
                default:
                    return false;
            }
        }
    };

    /**
     * 日志级别定义
     */
    exports.LogLevel = void 0;
    (function (LogLevel) {
        LogLevel[LogLevel["NONE"] = 0] = "NONE";
        LogLevel[LogLevel["ERROR"] = 1] = "ERROR";
        LogLevel[LogLevel["WARN"] = 2] = "WARN";
        LogLevel[LogLevel["INFO"] = 3] = "INFO";
        LogLevel[LogLevel["DEBUG"] = 4] = "DEBUG"; // 输出所有日志,包括调试信息
    })(exports.LogLevel || (exports.LogLevel = {}));
    // 检测是否为生产环境 - 这将由terser自动删除生产版本中不需要的代码
    const IS_DEV = typeof process === 'undefined' || !process.env || "production" !== 'production';
    /**
     * 日志工具类 - 精简版实现,在生产环境会被优化
     */
    class Logger {
        /**
         * 创建日志器实例
         * @param options 日志器选项
         */
        constructor(options = {}) {
            var _a, _b, _c;
            this.level = (_a = options.level) !== null && _a !== void 0 ? _a : exports.LogLevel.INFO;
            this.prefix = (_b = options.prefix) !== null && _b !== void 0 ? _b : '[PerfObserverKit]';
            this.disableInProduction = (_c = options.disableInProduction) !== null && _c !== void 0 ? _c : false; // 默认允许在生产环境输出日志
        }
        /**
         * 设置日志级别
         * @param level 日志级别
         */
        setLevel(level) {
            this.level = level;
            // 输出一条日志,确认级别已更改
        }
        /**
         * 设置日志器选项
         * @param options 要设置的选项
         */
        setOptions(options) {
            if (options.level !== undefined) {
                this.level = options.level;
            }
            if (options.prefix !== undefined) {
                this.prefix = options.prefix;
            }
            if (options.disableInProduction !== undefined) {
                this.disableInProduction = options.disableInProduction;
            }
        }
        /**
         * 输出调试日志
         * @param args 日志内容
         */
        debug(...args) {
            // 移除IS_DEV条件,允许生产环境输出调试信息
            if (this.shouldLog(exports.LogLevel.DEBUG)) ;
        }
        /**
         * 输出普通信息日志
         * @param args 日志内容
         */
        info(...args) {
            // 移除IS_DEV条件,允许生产环境输出信息
            if (this.shouldLog(exports.LogLevel.INFO)) ;
        }
        /**
         * 输出警告日志
         * @param args 日志内容
         */
        warn(...args) {
            // 警告总是保留,但在生产环境会受日志级别限制
            if (this.shouldLog(exports.LogLevel.WARN)) {
                console.warn(this.prefix, ...args);
            }
        }
        /**
         * 输出错误日志
         * @param args 日志内容
         */
        error(...args) {
            // 错误总是保留,但在生产环境会受日志级别限制
            if (this.shouldLog(exports.LogLevel.ERROR)) {
                console.error(this.prefix, ...args);
            }
        }
        /**
         * 判断是否应该输出指定级别的日志
         * @param messageLevel 日志消息级别
         * @returns 是否应该输出
         */
        shouldLog(messageLevel) {
            // 移除自动禁用生产环境日志的功能,改为完全尊重disableInProduction设置
            if (!IS_DEV && this.disableInProduction) {
                return false;
            }
            return messageLevel <= this.level;
        }
        /**
         * 获取当前日志配置
         * @returns 当前日志配置
         */
        getConfiguration() {
            return {
                level: this.level,
                levelName: exports.LogLevel[this.level],
                disableInProduction: this.disableInProduction,
                isProduction: !IS_DEV
            };
        }
    }
    /**
     * 全局默认日志器实例
     */
    const logger = new Logger();

    /**
     * 网络性能指标收集器
     * 提供收集和分析网络性能相关数据的工具方法
     */
    class NetworkMetricsCollector {
        /**
         * 获取当前网络状态信息
         * @returns 网络信息对象
         */
        static getNetworkInformation() {
            if (typeof navigator !== 'undefined' && 'connection' in navigator) {
                const connection = navigator.connection;
                if (connection) {
                    return {
                        downlink: connection.downlink,
                        effectiveType: connection.effectiveType,
                        rtt: connection.rtt,
                        saveData: connection.saveData
                    };
                }
            }
            return undefined;
        }
        /**
         * 获取完整的网络上下文信息
         * @param extraContext 额外的上下文信息
         * @returns 网络上下文信息
         */
        static getNetworkContext(extraContext = {}) {
            const networkInfo = this.getNetworkInformation();
            return {
                networkInfo: networkInfo ? {
                    downlink: networkInfo.downlink,
                    effectiveType: networkInfo.effectiveType,
                    rtt: networkInfo.rtt,
                    saveData: networkInfo.saveData
                } : undefined,
                url: typeof window !== 'undefined' ? window.location.href : undefined,
                visibilityState: typeof document !== 'undefined' ? document.visibilityState : undefined,
                ...extraContext
            };
        }
        /**
         * 计算网络质量评分
         * @param networkInfo 网络信息对象
         * @returns 'good' | 'needs-improvement' | 'poor'
         */
        static rateNetworkQuality(networkInfo) {
            if (!networkInfo) {
                return 'needs-improvement';
            }
            // 根据网络类型评估
            if (networkInfo.effectiveType === '4g' && networkInfo.downlink && networkInfo.downlink >= 5) {
                return 'good';
            }
            else if (networkInfo.effectiveType === '4g' || networkInfo.effectiveType === '3g') {
                return 'needs-improvement';
            }
            else {
                return 'poor';
            }
        }
    }

    function calculateTime(end, start) {
        return (typeof end === 'number' && typeof start === 'number') ? Math.max(end - start, 0) : 0;
    }
    /**
     * 计算两个时间点之间的差值,确保结果为非负
     * @param end 结束时间点
     * @param start 开始时间点
     * @returns 非负的时间差值
     */
    function calculateTimeDelta(end, start) {
        const delta = end - start;
        return delta > 0 ? delta : 0;
    }

    /**
     * 基础观察者类
     * 提供所有Web指标观察者共享的功能
     */
    class BaseObserver {
        constructor(options) {
            this.observer = null;
            // 页面可见性和用户交互相关属性
            this.isPageVisible = true;
            this.userHasInteracted = false;
            this.visibilityChangeHandler = null;
            this.userInteractionHandler = null;
            this.pageshowHandler = null;
            this.onUpdate = options.onUpdate;
        }
        /**
         * 启动观察
         */
        start() {
            this.setupVisibilityTracking();
            this.setupUserInteractionTracking();
            this.setupPageshowListener();
            this.observe();
        }
        /**
         * 停止观察
         */
        stop() {
            if (this.observer) {
                this.observer.disconnect();
                this.observer = null;
            }
            this.cleanupEventListeners();
        }
        /**
         * 清理事件监听器
         */
        cleanupEventListeners() {
            // 移除页面可见性监听
            if (this.visibilityChangeHandler && typeof document !== 'undefined') {
                document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
                this.visibilityChangeHandler = null;
            }
            // 移除用户交互监听
            if (this.userInteractionHandler && typeof document !== 'undefined') {
                document.removeEventListener('click', this.userInteractionHandler);
                document.removeEventListener('keydown', this.userInteractionHandler);
                this.userInteractionHandler = null;
            }
            // 移除pageshow监听
            if (this.pageshowHandler && typeof window !== 'undefined') {
                window.removeEventListener('pageshow', this.pageshowHandler);
                this.pageshowHandler = null;
            }
        }
        /**
         * 设置页面可见性跟踪
         */
        setupVisibilityTracking() {
            if (typeof document === 'undefined') {
                return;
            }
            this.isPageVisible = document.visibilityState === 'visible';
            this.visibilityChangeHandler = (event) => {
                this.isPageVisible = document.visibilityState === 'visible';
                logger.debug('页面可见性变化:', this.isPageVisible ? '可见' : '隐藏');
                // 通知子类可见性变化
                this.onVisibilityChange(this.isPageVisible);
            };
            document.addEventListener('visibilitychange', this.visibilityChangeHandler);
        }
        /**
         * 设置用户交互跟踪
         */
        setupUserInteractionTracking() {
            if (typeof document === 'undefined') {
                return;
            }
            this.userInteractionHandler = (event) => {
                if (this.userHasInteracted) {
                    return; // 已经处理过用户交互了,不重复处理
                }
                this.userHasInteracted = true;
                logger.debug('用户已交互');
            };
            // 监听点击和键盘事件
            document.addEventListener('click', this.userInteractionHandler);
            document.addEventListener('keydown', this.userInteractionHandler);
        }
        /**
         * 设置bfcache恢复监听
         */
        setupPageshowListener() {
            if (typeof window === 'undefined') {
                return;
            }
            this.pageshowHandler = (event) => {
                // 只有当页面是从bfcache恢复时才处理
                if (event.persisted) {
                    logger.info('页面从bfcache恢复');
                    // 重置用户交互状态
                    this.userHasInteracted = false;
                    // 由子类实现具体的bfcache恢复处理
                    this.onBFCacheRestore(event);
                }
            };
            window.addEventListener('pageshow', this.pageshowHandler);
        }
        /**
         * 获取网络状态信息
         * @returns 网络信息对象
         */
        getNetworkInformation() {
            return NetworkMetricsCollector.getNetworkInformation();
        }
        /**
         * 获取完整的网络上下文
         * @param extraContext 额外的上下文信息
         * @returns 完整的上下文数据
         */
        getNetworkContext(extraContext = {}) {
            // 获取当前页面URL
            const currentUrl = typeof window !== 'undefined' ? window.location.href : undefined;
            return NetworkMetricsCollector.getNetworkContext({
                ...extraContext,
                userHasInteracted: this.userHasInteracted,
                url: currentUrl
            });
        }
        /**
         * 计算两个时间点之间的差值,确保结果为非负
         * @param end 结束时间点
         * @param start 开始时间点
         * @returns 非负的时间差值
         */
        calculateTimeDelta(end, start) {
            return calculateTimeDelta(end, start);
        }
        /**
         * 页面可见性变化时的回调 - 可由子类重写
         * @param isVisible 页面是否可见
         */
        onVisibilityChange(isVisible) {
            // 默认实现为空,由子类覆盖
        }
        /**
         * BFCache恢复处理 - 由子类重写
         */
        onBFCacheRestore(event) {
            // 默认实现为空,由子类覆盖
        }
    }

    /**
     * First Contentful Paint (FCP) 观察者
     * 负责测量页面首次内容绘制时间
     * 重新实现基于Google Web Vitals库 (https://github.com/GoogleChrome/web-vitals)
     */
    class FCPObserver extends BaseObserver {
        constructor(options) {
            super(options);
            this.fcpObserver = null;
            // 记录指标是否已上报
            this.metricReported = false;
            // 初始化首次隐藏时间
            this.firstHiddenTime = this.initFirstHiddenTime();
            // 监听visibility变化以更新首次隐藏时间
            this.setupFirstHiddenTimeListener();
        }
        /**
         * 获取页面首次隐藏的时间
         */
        initFirstHiddenTime() {
            // 如果页面已经是隐藏状态,返回0
            if (typeof document !== 'undefined' && document.visibilityState === 'hidden') {
                return 0;
            }
            // 否则返回无限大,表示页面尚未隐藏
            return Infinity;
        }
        /**
         * 设置监听页面首次隐藏的事件
         */
        setupFirstHiddenTimeListener() {
            if (typeof document === 'undefined')
                return;
            const updateHiddenTime = () => {
                if (document.visibilityState === 'hidden' && this.firstHiddenTime === Infinity) {
                    this.firstHiddenTime = performance.now();
                    logger.debug(`记录页面首次隐藏时间: ${this.firstHiddenTime}ms`);
                }
            };
            // 监听页面visibility变化
            document.addEventListener('visibilitychange', updateHiddenTime, { once: true });
            // 页面卸载时也视为隐藏
            document.addEventListener('unload', updateHiddenTime, { once: true });
        }
        /**
         * 获取激活开始时间
         */
        getActivationStart() {
            if (typeof performance === 'undefined')
                return 0;
            const entries = performance.getEntriesByType('navigation');
            if (!entries || entries.length === 0)
                return 0;
            const navigationEntry = entries[0];
            // activationStart是非标准属性,在某些浏览器中可用
            const activationStart = navigationEntry === null || navigationEntry === void 0 ? void 0 : navigationEntry.activationStart;
            return activationStart ? activationStart : 0;
        }
        /**
         * 为FCP指标分配评级
         */
        assignFCPRating(value) {
            if (value <= FCPObserver.FCP_GOOD_THRESHOLD) {
                return 'good';
            }
            else if (value <= FCPObserver.FCP_NEEDS_IMPROVEMENT_THRESHOLD) {
                return 'needs-improvement';
            }
            else {
                return 'poor';
            }
        }
        /**
         * 实现观察FCP的方法
         */
        observe() {
            if (typeof PerformanceObserver === 'undefined') {
                logger.error('PerformanceObserver API不可用,无法监控FCP');
                return;
            }
            try {
                this.fcpObserver = new PerformanceObserver((entryList) => {
                    const entries = entryList.getEntries();
                    for (const entry of entries) {
                        if (entry.name === 'first-contentful-paint') {
                            // 只有当页面在FCP发生前未隐藏时才报告
                            if (entry.startTime < this.firstHiddenTime) {
                                // 计算FCP值,考虑activationStart(预渲染)
                                const fcpValue = Math.max(entry.startTime - this.getActivationStart(), 0);
                                const fcp = {
                                    name: 'FCP',
                                    value: fcpValue,
                                    unit: 'ms',
                                    timestamp: new Date().getTime(),
                                    url: typeof window !== 'undefined' ? window.location.href : undefined,
                                    networkMetrics: this.getNetworkInformation()
                                };
                                // 设置评级
                                fcp.rating = this.assignFCPRating(fcp.value);
                                this.onUpdate(fcp);
                                // 标记指标已报告
                                this.metricReported = true;
                            }
                            else {
                                logger.debug('页面在FCP前已隐藏,忽略此FCP事件');
                            }
                            // FCP只报告一次
                            if (this.fcpObserver) {
                                this.fcpObserver.disconnect();
                                this.fcpObserver = null;
                            }
                            break;
                        }
                    }
                });
                this.fcpObserver.observe({ type: 'paint', buffered: true });
            }
            catch (error) {
                logger.error('FCP监控不受支持', error);
            }
        }
        /**
         * 停止FCP观察
         */
        stop() {
            if (this.fcpObserver) {
                this.fcpObserver.disconnect();
                this.fcpObserver = null;
            }
            super.stop();
        }
        /**
         * 页面可见性变化时的回调
         * @param isVisible 页面是否可见
         */
        onVisibilityChange(isVisible) {
            if (!isVisible && this.firstHiddenTime === Infinity) {
                this.firstHiddenTime = performance.now();
                logger.debug(`页面隐藏,更新firstHiddenTime: ${this.firstHiddenTime}ms`);
            }
        }
        /**
         * BFCache恢复处理
         * 在bfcache恢复后,使用双RAF测量时间为新的FCP值
         */
        onBFCacheRestore(event) {
            // 对于BFCache恢复,我们需要新的FCP测量
            // 重置状态
            this.metricReported = false;
            this.firstHiddenTime = this.initFirstHiddenTime();
            this.setupFirstHiddenTimeListener();
            // 创建一个新的FCP指标,使用恢复时间差作为值
            const restoreTime = event.timeStamp;
            // 使用双重requestAnimationFrame确保我们在浏览器绘制后进行测量
            const doubleRAF = (callback) => {
                requestAnimationFrame(() => {
                    requestAnimationFrame(() => {
                        callback();
                    });
                });
            };
            doubleRAF(() => {
                const currentTime = performance.now();
                const timeFromRestore = currentTime - restoreTime;
                const fcp = {
                    name: 'FCP',
                    value: timeFromRestore,
                    unit: 'ms',
                    timestamp: currentTime,
                    url: typeof window !== 'undefined' ? window.location.href : undefined,
                    context: {
                        bfcacheRestore: true,
                        restoreTime: restoreTime
                    }
                };
                fcp.rating = this.assignFCPRating(fcp.value);
                logger.info(`从bfcache恢复到现在的时间: ${timeFromRestore}ms,作为新的FCP值`);
                this.onUpdate(fcp);
                this.metricReported = true;
            });
            // 重新观察FCP,以防有更早的绘制事件
            this.observe();
        }
    }
    // FCP评分阈值(毫秒)
    FCPObserver.FCP_GOOD_THRESHOLD = 1800;
    FCPObserver.FCP_NEEDS_IMPROVEMENT_THRESHOLD = 3000;

    /**
     * Largest Contentful Paint (LCP) 观察者
     * 负责测量页面最大内容绘制时间
     * 重新实现基于Google Web Vitals库 (https://github.com/GoogleChrome/web-vitals)
     */
    class LCPObserver extends BaseObserver {
        constructor(options) {
            super(options);
            this.lcpObserver = null;
            // 记录指标是否已上报
            this.metricReported = false;
            // 初始化首次隐藏时间
            this.firstHiddenTime = this.initFirstHiddenTime();
            // 监听visibility变化以更新首次隐藏时间
            this.setupFirstHiddenTimeListener();
        }
        /**
         * 获取页面首次隐藏的时间
         */
        initFirstHiddenTime() {
            // 如果页面已经是隐藏状态,返回0
            if (typeof document !== 'undefined' && document.visibilityState === 'hidden') {
                return 0;
            }
            // 否则返回无限大,表示页面尚未隐藏
            return Infinity;
        }
        /**
         * 设置监听页面首次隐藏的事件
         */
        setupFirstHiddenTimeListener() {
            if (typeof document === 'undefined')
                return;
            const updateHiddenTime = () => {
                if (document.visibilityState === 'hidden' && this.firstHiddenTime === Infinity) {
                    this.firstHiddenTime = performance.now();
                    logger.debug(`记录页面首次隐藏时间: ${this.firstHiddenTime}ms`);
                }
            };
            // 监听页面visibility变化
            document.addEventListener('visibilitychange', updateHiddenTime, { once: true });
            // 页面卸载时也视为隐藏
            document.addEventListener('unload', updateHiddenTime, { once: true });
        }
        /**
         * 获取激活开始时间
         */
        getActivationStart() {
            if (typeof performance === 'undefined')
                return 0;
            const entries = performance.getEntriesByType('navigation');
            if (!entries || entries.length === 0)
                return 0;
            const navigationEntry = entries[0];
            // activationStart是非标准属性,在某些浏览器中可用
            const activationStart = navigationEntry === null || navigationEntry === void 0 ? void 0 : navigationEntry.activationStart;
            return activationStart ? activationStart : 0;
        }
        /**
         * 实现观察LCP的方法
         */
        observe() {
            this.startLCPMonitoring();
        }
        /**
         * 为LCP指标分配评级
         */
        assignLCPRating(value) {
            if (value <= LCPObserver.LCP_GOOD_THRESHOLD) {
                return 'good';
            }
            else if (value <= LCPObserver.LCP_NEEDS_IMPROVEMENT_THRESHOLD) {
                return 'needs-improvement';
            }
            else {
                return 'poor';
            }
        }
        /**
         * 启动LCP监控
         */
        startLCPMonitoring() {
            if (typeof PerformanceObserver === 'undefined') {
                logger.error('PerformanceObserver API不可用,无法监控LCP');
                return;
            }
            try {
                this.lcpObserver = new PerformanceObserver((entryList) => {
                    // 获取所有entries,但如果不需要报告所有变化,只考虑最后一个
                    const entries = entryList.getEntries();
                    // 遍历entries(通常只有一个)
                    entries.forEach(entry => {
                        // 只有当页面在LCP发生前未隐藏时才报告
                        if (entry.startTime < this.firstHiddenTime) {
                            // 计算LCP值,考虑activationStart(预渲染)
                            const lcpValue = Math.max(entry.startTime - this.getActivationStart(), 0);
                            // 创建LCP指标
                            const lcp = {
                                name: 'LCP',
                                value: lcpValue,
                                unit: 'ms',
                                timestamp: new Date().getTime(),
                                url: typeof window !== 'undefined' ? window.location.href : undefined,
                                networkMetrics: this.getNetworkInformation(),
                                context: {
                                    elementId: entry.element ? entry.element.id || null : null,
                                    elementTagName: entry.element ? entry.element.tagName || null : null,
                                    elementType: entry.element ? entry.element.type || null : null,
                                    size: entry.size || 0
                                }
                            };
                            // 设置评级
                            lcp.rating = this.assignLCPRating(lcp.value);
                            // 发送指标更新
                            this.onUpdate(lcp);
                        }
                        else {
                            logger.debug('页面在LCP前已隐藏,忽略此LCP事件');
                        }
                    });
                });
                // 启动观察
                this.lcpObserver.observe({ type: 'largest-contentful-paint', buffered: true });
                // 设置停止监听的条件
                this.setupStopListening();
            }
            catch (error) {
                logger.error('LCP监控不受支持', error);
            }
        }
        /**
         * 设置停止监听的各种条件
         */
        setupStopListening() {
            // 用于确保只报告一次的函数
            const stopListening = () => {
                if (this.metricReported || !this.lcpObserver)
                    return;
                // 处理所有剩余记录
                const records = this.lcpObserver.takeRecords();
                if (records && records.length > 0) {
                    const lastEntry = records[records.length - 1];
                    if (lastEntry && lastEntry.startTime < this.firstHiddenTime) {
                        const lcpValue = Math.max(lastEntry.startTime - this.getActivationStart(), 0);
                        const lcp = {
                            name: 'LCP',
                            value: lcpValue,
                            unit: 'ms',
                            timestamp: new Date().getTime(),
                            url: typeof window !== 'undefined' ? window.location.href : undefined,
                            networkMetrics: this.getNetworkInformation(),
                            context: {
                                elementId: lastEntry.element ? lastEntry.element.id || null : null,
                                elementTagName: lastEntry.element ? lastEntry.element.tagName || null : null,
                                elementType: lastEntry.element ? lastEntry.element.type || null : null,
                                size: lastEntry.size || 0,
                                finalReport: true
                            }
                        };
                        lcp.rating = this.assignLCPRating(lcp.value);
                        this.onUpdate(lcp);
                    }
                }
                // 断开观察器连接
                this.lcpObserver.disconnect();
                this.lcpObserver = null;
                this.metricReported = true;
                logger.debug('LCP测量完成,指标已报告');
            };
            // 监听用户交互事件(键盘和点击)
            const addInteractionListener = (type) => {
                if (typeof document === 'undefined')
                    return;
                document.addEventListener(type, () => {
                    // 使用setTimeout将回调放入单独的任务中,减少对INP的影响
                    setTimeout(() => {
                        logger.debug(`检测到用户${type}交互,停止LCP监听`);
                        stopListening();
                    }, 0);
                }, { once: true, capture: true });
            };
            ['keydown', 'click'].forEach(addInteractionListener);
            // 监听页面隐藏事件
            if (typeof document !== 'undefined') {
                document.addEventListener('visibilitychange', () => {
                    if (document.visibilityState === 'hidden') {
                        logger.debug('页面隐藏,停止LCP监听');
                        stopListening();
                    }
                });
            }
        }
        /**
         * 停止LCP观察
         */
        stop() {
            if (this.lcpObserver) {
                this.lcpObserver.disconnect();
                this.lcpObserver = null;
            }
            super.stop();
        }
        /**
         * 页面可见性变化时的回调
         * @param isVisible 页面是否可见
         */
        onVisibilityChange(isVisible) {
            if (!isVisible && this.firstHiddenTime === Infinity) {
                this.firstHiddenTime = performance.now();
                logger.debug(`页面隐藏,更新firstHiddenTime: ${this.firstHiddenTime}ms`);
            }
        }
        /**
         * BFCache恢复处理
         * 在bfcache恢复后重新计算从恢复到当前的时间差作为新的LCP
         */
        onBFCacheRestore(event) {
            // 断开现有的LCP观察器
            if (this.lcpObserver) {
                this.lcpObserver.disconnect();
                this.lcpObserver = null;
            }
            // 重置状态
            this.metricReported = false;
            this.firstHiddenTime = this.initFirstHiddenTime();
            this.setupFirstHiddenTimeListener();
            // 创建一个新的LCP指标,使用恢复时间差作为值
            const restoreTime = event.timeStamp;
            // 使用双重requestAnimationFrame确保我们在浏览器绘制后进行测量
            const doubleRAF = (callback) => {
                requestAnimationFrame(() => {
                    requestAnimationFrame(() => {
                        callback();
                    });
                });
            };
            doubleRAF(() => {
                const currentTime = performance.now();
                const timeFromRestore = currentTime - restoreTime;
                const lcp = {
                    name: 'LCP',
                    value: timeFromRestore,
                    unit: 'ms',
                    timestamp: currentTime,
                    url: typeof window !== 'undefined' ? window.location.href : undefined,
                    context: {
                        bfcacheRestore: true,
                        restoreTime: restoreTime
                    }
                };
                lcp.rating = this.assignLCPRating(lcp.value);
                logger.info(`从bfcache恢复到现在的时间: ${timeFromRestore}ms,作为新的LCP值`);
                this.onUpdate(lcp);
                this.metricReported = true;
            });
            // 重新开始LCP监测以捕获后续可能的更大内容
            this.startLCPMonitoring();
        }
    }
    // LCP评分阈值(毫秒)
    LCPObserver.LCP_GOOD_THRESHOLD = 2500;
    LCPObserver.LCP_NEEDS_IMPROVEMENT_THRESHOLD = 4000;

    /**
     * First Input Delay (FID) 观察者
     * 负责测量页面首次输入延迟时间
     */
    class FIDObserver extends BaseObserver {
        constructor(options) {
            super(options);
            this.fidObserver = null;
        }
        /**
         * 实现观察FID的方法
         */
        observe() {
            try {
                this.fidObserver = new PerformanceObserver((entryList) => {
                    const entries = entryList.getEntries();
                    for (const entry of entries) {
                        if (entry.name === 'first-input') {
                            const fidEntry = entry;
                            const fid = {
                                name: 'FID',
                                value: fidEntry.processingStart - fidEntry.startTime,
                                unit: 'ms',
                                timestamp: new Date().getTime(),
                            };
                            // FID rating thresholds (ms)
                            if (fid.value <= 100) {
                                fid.rating = 'good';
                            }
                            else if (fid.value <= 300) {
                                fid.rating = 'needs-improvement';
                            }
                            else {
                                fid.rating = 'poor';
                            }
                            this.onUpdate(fid);
                            // FID is only reported once
                            if (this.fidObserver) {
                                this.fidObserver.disconnect();
                                this.fidObserver = null;
                            }
                            break;
                        }
                    }
                });
                this.fidObserver.observe({ type: 'first-input', buffered: true });
            }
            catch (error) {
                logger.error('FID监控不受支持', error);
            }
        }
        /**
         * 停止FID观察
         */
        stop() {
            if (this.fidObserver) {
                this.fidObserver.disconnect();
                this.fidObserver = null;
            }
            super.stop();
        }
        /**
         * 页面可见性变化时的回调
         * @param isVisible 页面是否可见
         */
        onVisibilityChange(isVisible) {
            // FID通常是页面加载后的首次输入事件,不需要在可见性变化时特殊处理
            if (!isVisible) {
                logger.debug('页面隐藏,FID已经收集或仍在等待首次输入事件');
            }
            else {
                logger.debug('页面重新可见,FID状态不变');
            }
        }
        /**
         * BFCache恢复处理
         * FID通常不需要在bfcache恢复时重新计算
         */
        onBFCacheRestore(event) {
            // FID不需要特殊处理bfcache恢复
        }
    }

    /**
     * Cumulative Layout Shift (CLS) 观察者
     * 负责测量页面布局稳定性
     * 使用 Google Web Vitals 推荐的会话窗口计算方法
     */
    class CLSObserver extends BaseObserver {
        constructor(options) {
            super(options);
            this.clsObserver = null;
            // 会话窗口相关属性
            this.sessionCount = 0; // 当前会话中的偏移数量
            this.sessionValues = [0]; // 各个会话窗口的CLS值
            this.sessionGap = 1000; // 会话间隔时间,单位毫秒
            this.sessionMax = 5; // 最大会话窗口数量
            this.maxSessionEntries = 100; // 每个会话记录的最大偏移数量
            // 上次报告的CLS值
            this.prevReportedValue = 0;
            // 上次偏移的时间戳
            this.lastEntryTime = 0;
            // 是否需要在页面重新可见时重置会话
            this.shouldResetOnNextVisible = false;
            // 防抖计时器
            this.reportDebounceTimer = null;
            // 防抖延迟
            this.reportDebounceDelay = 500;
            // 初始化首次隐藏时间
            this.firstHiddenTime = this.initFirstHiddenTime();
            // 监听visibility变化以更新首次隐藏时间
            this.setupFirstHiddenTimeListener();
        }
        /**
         * 获取页面首次隐藏的时间
         */
        initFirstHiddenTime() {
            // 如果页面已经是隐藏状态,返回0
            if (typeof document !== 'undefined' && document.visibilityState === 'hidden') {
                return 0;
            }
            // 否则返回无限大,表示页面尚未隐藏
            return Infinity;
        }
        /**
         * 设置监听页面首次隐藏的事件
         */
        setupFirstHiddenTimeListener() {
            if (typeof document === 'undefined')
                return;
            const updateHiddenTime = () => {
                if (document.visibilityState === 'hidden' && this.firstHiddenTime === Infinity) {
                    this.firstHiddenTime = performance.now();
                    logger.debug(`记录页面首次隐藏时间: ${this.firstHiddenTime}ms`);
                }
            };
            // 监听页面visibility变化
            document.addEventListener('visibilitychange', updateHiddenTime, { once: true });
            // 页面卸载时也视为隐藏
            document.addEventListener('unload', updateHiddenTime, { once: true });
        }
        /**
         * 为CLS指标分配评级
         */
        assignCLSRating(value) {
            if (value <= CLSObserver.CLS_GOOD_THRESHOLD) {
                return 'good';
            }
            else if (value <= CLSObserver.CLS_NEEDS_IMPROVEMENT_THRESHOLD) {
                return 'needs-improvement';
            }
            else {
                return 'poor';
            }
        }
        /**
         * 实现观察CLS的方法
         */
        observe() {
            if (typeof PerformanceObserver === 'undefined') {
                logger.error('PerformanceObserver API不可用,无法监控CLS');
                return;
            }
            try {
                this.clsObserver = new PerformanceObserver((entryList) => {
                    const entries = entryList.getEntries();
                    // 只处理页面在可见状态时发生的布局偏移
                    if (document.visibilityState !== 'visible') {
                        logger.debug('页面不可见,忽略布局偏移事件');
                        return;
                    }
                    // 处理新会话的标志
                    let newSessionStarted = false;
                    for (const entry of entries) {
                        // 只计算用户未操作时的布局偏移
                        const layoutShift = entry;
                        if (!layoutShift.hadRecentInput && layoutShift.startTime < this.firstHiddenTime) {
                            // 获取偏移发生的时间戳
                            const currentTime = layoutShift.startTime;
                            // 判断是否需要开始新会话
                            if (this.shouldResetOnNextVisible || currentTime - this.lastEntryTime > this.sessionGap) {
                                this.startNewSession(layoutShift.value);
                                newSessionStarted = true;
                                this.shouldResetOnNextVisible = false;
                            }
                            else {
                                // 累加到当前会话,但限制记录的事件数量
                                if (this.sessionCount < this.maxSessionEntries) {
                                    this.sessionCount++;
                                    // 累加到当前会话
                                    const currentSessionIndex = this.sessionValues.length - 1;
                                    this.sessionValues[currentSessionIndex] += layoutShift.value;
                                }
                            }
                            // 更新最后一次偏移时间
                            this.lastEntryTime = currentTime;
                            // 防抖处理,减少频繁报告
                            this.debouncedReportCLS();
                        }
                    }
                    // 如果开始了新会话,立即报告一次,不需要防抖
                    if (newSessionStarted) {
                        this.reportCLS(this.calculateCLS());
                    }
                });
                // 使用buffered选项确保不会丢失之前的布局偏移
                this.clsObserver.observe({ type: 'layout-shift', buffered: true });
                logger.debug('CLS观察者已启动,开始监控布局偏移');
            }
            catch (error) {
                logger.error('CLS监控不受支持', error);
            }
        }
        /**
         * 开始新的会话窗口
         * @param initialValue 初始偏移值
         */
        startNewSession(initialValue) {
            // 添加新会话
            this.sessionValues.push(initialValue);
            this.sessionCount = 1;
            // 如果会话窗口超过限制,移除最小的会话
            if (this.sessionValues.length > this.sessionMax) {
                // 找到最小的会话值及其索引
                let minValue = Infinity;
                let minIndex = 0;
                for (let i = 0; i < this.sessionValues.length; i++) {
                    if (this.sessionValues[i] < minValue) {
                        minValue = this.sessionValues[i];
                        minIndex = i;
                    }
                }
                // 移除最小的会话
                this.sessionValues.splice(minIndex, 1);
            }
            logger.debug(`开始新的CLS会话,当前会话数: ${this.sessionValues.length}`);
        }
        /**
         * 防抖报告CLS,减少频繁更新
         */
        debouncedReportCLS() {
            // 清除现有计时器
            if (this.reportDebounceTimer !== null) {
                window.clearTimeout(this.reportDebounceTimer);
            }
            // 设置新计时器
            this.reportDebounceTimer = window.setTimeout(() => {
                const clsValue = this.calculateCLS();
                // 只有当CLS值显著变化时才报告
                if (Math.abs(clsValue - this.prevReportedValue) >= 0.01) {
                    this.reportCLS(clsValue);
                }
                this.reportDebounceTimer = null;
            }, this.reportDebounceDelay);
        }
        /**
         * 计算最终CLS值
         * 取所有会话窗口中的最大值
         */
        calculateCLS() {
            return Math.max(...this.sessionValues);
        }
        /**
         * 报告CLS指标
         */
        reportCLS(clsValue) {
            const cls = {
                name: 'CLS',
                value: clsValue,
                unit: '', // CLS没有单位,是无量纲数值
                timestamp: new Date().getTime(),
                url: typeof window !== 'undefined' ? window.location.href : undefined,
                // 添加网络信息和其他上下文
                context: {
                    shiftCount: this.sessionCount,
                    sessionCount: this.sessionValues.length,
                    sessionValues: [...this.sessionValues],
                    largestSession: this.calculateCLS(),
                    isPageVisible: document.visibilityState === 'visible',
                    firstHiddenTime: this.firstHiddenTime === Infinity ? null : this.firstHiddenTime
                }
            };
            // 设置评级
            cls.rating = this.assignCLSRating(cls.value);
            logger.debug(`报告CLS值: ${cls.value},评级: ${cls.rating},页面可见性: ${document.visibilityState}`);
            this.onUpdate(cls);
            // 更新上次报告的值
            this.prevReportedValue = clsValue;
        }
        /**
         * 停止CLS观察
         */
        stop() {
            // 清除防抖计时器
            if (this.reportDebounceTimer !== null) {
                window.clearTimeout(this.reportDebounceTimer);
                this.reportDebounceTimer = null;
            }
            if (this.clsObserver) {
                this.clsObserver.disconnect();
                this.clsObserver = null;
            }
            super.stop();
        }
        /**
         * 页面可见性变化时的回调
         * @param isVisible 页面是否可见
         */
        onVisibilityChange(isVisible) {
            if (!isVisible) {
                // 页面隐藏时,报告当前的CLS值
                if (this.firstHiddenTime === Infinity) {
                    this.firstHiddenTime = performance.now();
                    logger.debug(`页面隐藏,更新firstHiddenTime: ${this.firstHiddenTime}ms`);
                }
                const clsValue = this.calculateCLS();
                // 无论大小变化,都在页面隐藏时报告一次
                this.reportCLS(clsValue);
                // 标记需要在页面重新可见时开始新会话
                this.shouldResetOnNextVisible = true;
            }
            else {
                // 页面重新变为可见
                if (this.shouldResetOnNextVisible) {
                    logger.debug('页面重新可见,准备开始新的CLS会话');
                    // 实际的重置会在下一个布局偏移发生时生效
                }
            }
        }
        /**
         * BFCache恢复处理
         * CLS应该重置累积值
         */
        onBFCacheRestore(event) {
            // 重置CLS会话值
            this.sessionValues = [0];
            this.sessionCount = 0;
            this.prevReportedValue = 0;
            this.lastEntryTime = 0;
            // 清除计时器
            if (this.reportDebounceTimer !== null) {
                window.clearTimeout(this.reportDebounceTimer);
                this.reportDebounceTimer = null;
            }
            // 重置firstHiddenTime
            this.firstHiddenTime = this.initFirstHiddenTime();
            this.setupFirstHiddenTimeListener();
            logger.info('CLS值已在bfcache恢复后重置');
            // 重新开始CLS监测
            if (this.clsObserver) {
                this.clsObserver.observe({ type: 'layout-shift', buffered: true });
            }
        }
    }
    // CLS评分阈值
    CLSObserver.CLS_GOOD_THRESHOLD = 0.1;
    CLSObserver.CLS_NEEDS_IMPROVEMENT_THRESHOLD = 0.25;

    /**
     * Interaction to Next Paint (INP) 观察者
     * 负责测量页面交互响应性能
     * 实现基于 Google Web Vitals 推荐方法
     */
    class INPObserver extends BaseObserver {
        constructor(options) {
            super(options);
            this.inpObserver = null;
            // 存储所有交互事件的持续时间
            this.interactionEvents = [];
            // 上次报告的INP值
            this.lastReportedINP = 0;
            // 报告频率控制
            this.minReportingChange = 10; // 最小报告变化阈值(毫秒)
            // 初始化首次隐藏时间
            this.firstHiddenTime = this.initFirstHiddenTime();
            // 监听visibility变化以更新首次隐藏时间
            this.setupFirstHiddenTimeListener();
        }
        /**
         * 获取页面首次隐藏的时间
         */
        initFirstHiddenTime() {
            // 如果页面已经是隐藏状态,返回0
            if (typeof document !== 'undefined' && document.visibilityState === 'hidden') {
                return 0;
            }
            // 否则返回无限大,表示页面尚未隐藏
            return Infinity;
        }
        /**
         * 设置监听页面首次隐藏的事件
         */
        setupFirstHiddenTimeListener() {
            if (typeof document === 'undefined')
                return;
            const updateHiddenTime = () => {
                if (document.visibilityState === 'hidden' && this.firstHiddenTime === Infinity) {
                    this.firstHiddenTime = performance.now();
                    logger.debug(`记录页面首次隐藏时间: ${this.firstHiddenTime}ms`);
                }
            };
            // 监听页面visibility变化
            document.addEventListener('visibilitychange', updateHiddenTime, { once: true });
            // 页面卸载时也视为隐藏
            document.addEventListener('unload', updateHiddenTime, { once: true });
        }
        /**
         * 为INP指标分配评级
         */
        assignINPRating(value) {
            if (value <= INPObserver.INP_GOOD_THRESHOLD) {
                return 'good';
            }
            else if (value <= INPObserver.INP_NEEDS_IMPROVEMENT_THRESHOLD) {
                return 'needs-improvement';
            }
            else {
                return 'poor';
            }
        }
        /**
         * 实现观察INP的方法
         */
        observe() {
            if (typeof PerformanceObserver === 'undefined') {
                logger.error('PerformanceObserver API不可用,无法监控INP');
                return;
            }
            try {
                // 定义要观察的交互类型
                const eventTypes = ['click', 'keydown', 'pointerdown'];
                this.inpObserver = new PerformanceObserver((entryList) => {
                    // 只处理页面在可见状态时发生的交互
                    if (document.visibilityState !== 'visible')
                        return;
                    const events = entryList.getEntries();
                    // 处理每个交互事件
                    for (const event of events) {
                        // 只处理发生在页面可见状态的交互
                        if (event.startTime < this.firstHiddenTime) {
                            const timing = event;
                            // 检查事件类型是否在我们关注的范围内
                            if (eventTypes.includes(timing.name)) {
                                this.interactionEvents.push({
                                    duration: timing.duration,
                                    name: timing.name,
                                    startTime: timing.startTime
                                });
                                // 计算并可能报告新的INP值
                                this.calculateAndReportINP();
                            }
                        }
                    }
                });
                // 使用类型断言处理非标准属性
                try {
                    // 尝试使用带有durationThreshold的observe
                    // durationThreshold是较新浏览器中可用的非标准属性
                    this.inpObserver.observe({
                        type: 'event',
                        buffered: true,
                        // 使用类型断言来处理非标准属性
                        ...{ durationThreshold: 16 } // 只测量至少持续16ms的事件
                    });
                }
                catch (error) {
                    // 回退到不带durationThreshold的observe
                    this.inpObserver.observe({
                        type: 'event',
                        buffered: true
                    });
                    logger.warn('浏览器不支持durationThreshold参数,使用默认配置');
                }
            }
            catch (error) {
                logger.error('INP监控不受支持', error);
            }
        }
        /**
         * 计算INP(交互到下一次绘制)值
         * 使用Google推荐的方法(取第75百分位数)
         */
        calculateINP() {
            if (this.interactionEvents.length === 0) {
                return 0;
            }
            // 将交互事件按持续时间排序
            const sortedDurations = this.interactionEvents.map(event => event.duration).sort((a, b) => a - b);
            // 计算第75百分位数
            const percentile = 0.75;
            const index = Math.floor(sortedDurations.length * percentile);
            // 如果只有一个交互,直接返回
            if (sortedDurations.length === 1) {
                return sortedDurations[0];
            }
            // 返回第75百分位数的值
            return sortedDurations[index];
        }
        /**
         * 计算并报告INP值,如果值有显著变化
         */
        calculateAndReportINP() {
            // 计算新的INP值
            const inpValue = this.calculateINP();
            // 只有当INP值显著变化时才报告
            if (Math.abs(inpValue - this.lastReportedINP) >= this.minReportingChange) {
                // 创建INP指标对象
                const inp = {
                    name: 'INP',
                    value: inpValue,
                    unit: 'ms',
                    timestamp: new Date().getTime(),
                    url: typeof window !== 'undefined' ? window.location.href : undefined,
                    context: {
                        interactionCount: this.interactionEvents.length,
                        percentile: 75,
                        highestDuration: Math.max(...this.interactionEvents.map(e => e.duration)),
                        medianDuration: this.interactionEvents.length > 0
                            ? this.interactionEvents.map(e => e.duration).sort((a, b) => a - b)[Math.floor(this.interactionEvents.length / 2)]
                            : 0,
                        eventTypes: [...new Set(this.interactionEvents.map(e => e.name))],
                        firstHiddenTime: this.firstHiddenTime === Infinity ? null : this.firstHiddenTime
                    }
                };
                // 设置评级
                inp.rating = this.assignINPRating(inp.value);
                logger.debug(`报告INP值: ${inp.value}ms,评级: ${inp.rating},基于${this.interactionEvents.length}个交互`);
                this.onUpdate(inp);
                // 更新最后报告的值
                this.lastReportedINP = inpValue;
            }
        }
        /**
         * 停止INP观察
         */
        stop() {
            if (this.inpObserver) {
                this.inpObserver.disconnect();
                this.inpObserver = null;
            }
            super.stop();
        }
        /**
         * 页面可见性变化时的回调
         * @param isVisible 页面是否可见
         */
        onVisibilityChange(isVisible) {
            // 更新firstHiddenTime
            if (!isVisible && this.firstHiddenTime === Infinity) {
                this.firstHiddenTime = performance.now();
                logger.debug(`页面隐藏,更新firstHiddenTime: ${this.firstHiddenTime}ms`);
                // 当页面隐藏时,报告当前的INP值
                if (this.interactionEvents.length > 0) {
                    this.calculateAndReportINP();
                }
            }
        }
        /**
         * BFCache恢复处理
         * 重置INP监测
         */
        onBFCacheRestore(event) {
            // 重置INP值和交互事件
            this.interactionEvents = [];
            this.lastReportedINP = 0;
            // 重置firstHiddenTime
            this.firstHiddenTime = this.initFirstHiddenTime();
            this.setupFirstHiddenTimeListener();
            logger.info('INP监测已在bfcache恢复后重置');
            // 重新启动INP监测
            if (this.inpObserver) {
                this.inpObserver.disconnect();
                this.inpObserver = null;
            }
            this.observe();
        }
    }
    // INP评分阈值(毫秒)
    INPObserver.INP_GOOD_THRESHOLD = 200;
    INPObserver.INP_NEEDS_IMPROVEMENT_THRESHOLD = 500;

    /**
     * 核心Web指标观察者
     * 负责监控所有Core Web Vitals指标
     */
    class CoreWebVitalsObserver {
        constructor(options) {
            this.metrics = {};
            // 各个指标的观察者
            this.fcpObserver = null;
            this.lcpObserver = null;
            this.fidObserver = null;
            this.clsObserver = null;
            this.inpObserver = null;
            this.onUpdate = options.onUpdate;
            this.options = {
                // 默认启用
                enabled: options.enabled !== undefined ? options.enabled : false,
                // FCP和LCP默认启用,其他指标默认不启用
                fcp: options.fcp !== undefined ? options.fcp : false,
                lcp: options.lcp !== undefined ? options.lcp : false,
                fid: options.fid !== undefined ? options.fid : false,
                cls: options.cls !== undefined ? options.cls : false,
                inp: options.inp !== undefined ? options.inp : false,
                // 其他选项
                backgroundLoadThreshold: options.backgroundLoadThreshold,
                ...options
            };
            logger.debug('核心Web指标观察者已创建,初始配置:', {
                enabled: this.options.enabled,
                fcp: this.options.fcp,
                lcp: this.options.lcp,
                fid: this.options.fid,
                cls: this.options.cls,
                inp: this.options.inp
            });
        }
        /**
         * 开始监控所有核心Web指标
         */
        start() {
            logger.info('开始监控核心Web指标');
            // 启动FCP监测
            if (this.options.fcp) {
                logger.debug('启动FCP监测');
                this.startFCPMonitoring();
            }
            // 启动LCP监测
            if (this.options.lcp) {
                logger.debug('启动LCP监测');
                this.startLCPMonitoring();
            }
            // 启动FID监测
            if (this.options.fid) {
                logger.debug('启动FID监测');
                this.startFIDMonitoring();
            }
            // 启动CLS监测
            if (this.options.cls) {
                logger.debug('启动CLS监测');
                this.startCLSMonitoring();
            }
            // 启动INP监测
            if (this.options.inp) {
                logger.debug('启动INP监测');
                this.startINPMonitoring();
            }
            logger.debug('核心Web指标监控启动完成');
        }
        /**
         * 停止所有监控
         */
        stop() {
            logger.info('停止所有核心Web指标监控');
            if (this.fcpObserver) {
                this.fcpObserver.stop();
                this.fcpObserver = null;
                logger.debug('FCP监控已停止');
            }
            if (this.lcpObserver) {
                this.lcpObserver.stop();
                this.lcpObserver = null;
                logger.debug('LCP监控已停止');
            }
            if (this.fidObserver) {
                this.fidObserver.stop();
                this.fidObserver = null;
                logger.debug('FID监控已停止');
            }
            if (this.clsObserver) {
                this.clsObserver.stop();
                this.clsObserver = null;
                logger.debug('CLS监控已停止');
            }
            if (this.inpObserver) {
                this.inpObserver.stop();
                this.inpObserver = null;
                logger.debug('INP监控已停止');
            }
            logger.debug('所有核心Web指标监控均已停止');
        }
        /**
         * 发送指标更新通知
         */
        notifyMetricsUpdate() {
            logger.debug('发送核心Web指标更新通知');
            this.onUpdate(this.metrics);
        }
        /**
         * 启动FCP监测
         */
        startFCPMonitoring() {
            try {
                this.fcpObserver = new FCPObserver({
                    onUpdate: (metric) => {
                        this.metrics.fcp = metric;
                        logger.debug('FCP指标已更新:', metric.value.toFixed(2) + 'ms', `(${metric.rating})`);
                        this.notifyMetricsUpdate();
                    }
                });
                this.fcpObserver.start();
            }
            catch (error) {
                logger.error('启动FCP监控失败:', error);
            }
        }
        /**
         * 启动LCP监测
         */
        startLCPMonitoring() {
            try {
                this.lcpObserver = new LCPObserver({
                    onUpdate: (metric) => {
                        this.metrics.lcp = metric;
                        logger.debug('LCP指标已更新:', metric.value.toFixed(2) + 'ms', `(${metric.rating})`);
                        this.notifyMetricsUpdate();
                    },
                    backgroundLoadThreshold: this.options.backgroundLoadThreshold
                });
                this.lcpObserver.start();
            }
            catch (error) {
                logger.error('启动LCP监控失败:', error);
            }
        }
        /**
         * 启动FID监测
         */
        startFIDMonitoring() {
            try {
                this.fidObserver = new FIDObserver({
                    onUpdate: (metric) => {
                        this.metrics.fid = metric;
                        logger.debug('FID指标已更新:', metric.value.toFixed(2) + 'ms', `(${metric.rating})`);
                        this.notifyMetricsUpdate();
                    }
                });
                this.fidObserver.start();
            }
            catch (error) {
                logger.error('启动FID监控失败:', error);
            }
        }
        /**
         * 启动CLS监测
         */
        startCLSMonitoring() {
            try {
                this.clsObserver = new CLSObserver({
                    onUpdate: (metric) => {
                        this.metrics.cls = metric;
                        logger.debug('CLS指标已更新:', metric.value.toFixed(4), `(${metric.rating})`);
                        this.notifyMetricsUpdate();
                    }
                });
                this.clsObserver.start();
            }
            catch (error) {
                logger.error('启动CLS监控失败:', error);
            }
        }
        /**
         * 启动INP监测
         */
        startINPMonitoring() {
            try {
                this.inpObserver = new INPObserver({
                    onUpdate: (metric) => {
                        this.metrics.inp = metric;
                        logger.debug('INP指标已更新:', metric.value.toFixed(2) + 'ms', `(${metric.rating})`);
                        this.notifyMetricsUpdate();
                    }
                });
                this.inpObserver.start();
            }
            catch (error) {
                logger.error('启动INP监控失败:', error);
            }
        }
    }

    /**
     * 资源计时观察者
     * 监控并收集页面资源加载性能指标
     */
    class ResourceTimingObserver {
        /**
         * 创建资源计时观察者实例
         * @param onUpdate 当收集到新资源时的回调函数
         * @param excludedPatterns 要排除的资源URL模式
         * @param allowedResourceTypes 允许监控的资源类型
         */
        constructor(onUpdate, excludedPatterns = [], allowedResourceTypes) {
            this.observer = null;
            this.resources = [];
            this.excludedPatterns = [];
            this.allowedResourceTypes = ['script', 'link', 'img', 'css', 'font'];
            this.onUpdate = onUpdate;
            this.excludedPatterns = excludedPatterns;
            if (allowedResourceTypes === null || allowedResourceTypes === void 0 ? void 0 : allowedResourceTypes.length) {
                this.allowedResourceTypes = allowedResourceTypes;
            }
            logger.debug('资源计时观察者已创建', {
                excludedPatterns: this.excludedPatterns.length,
                allowedResourceTypes: this.allowedResourceTypes
            });
        }
        /**
         * 开始监控资源加载性能
         */
        start() {
            logger.info('开始监控资源加载性能');
            if (typeof PerformanceObserver === 'undefined') {
                logger.warn('PerformanceObserver API不可用,无法监控资源加载性能');
                return;
            }
            try {
                this.observer = new PerformanceObserver(this.handleEntries.bind(this));
                this.observer.observe({ type: 'resource', buffered: true });
                logger.debug('资源计时观察者已启动');
            }
            catch (error) {
                logger.error('资源计时监控不支持', error);
            }
        }
        /**
         * 处理性能观察者捕获的条目
         */
        handleEntries(entryList) {
            const entries = entryList.getEntries();
            let hasNewEntries = false;
            let newEntriesCount = 0;
            for (const entry of entries) {
                if (entry.entryType !== 'resource')
                    continue;
                const resourceEntry = entry;
                // 应用过滤逻辑
                if (!this.shouldProcessEntry(resourceEntry))
                    continue;
                // 构建资源指标并添加到集合
                const resourceMetric = this.buildResourceMetric(resourceEntry);
                this.resources.push(resourceMetric);
                hasNewEntries = true;
                newEntriesCount++;
                logger.debug('记录资源性能指标:', {
                    type: resourceEntry.initiatorType,
                    url: this.shortenUrl(resourceEntry.name),
                    size: `${(resourceEntry.transferSize / 1024).toFixed(2)}KB`,
                    duration: `${resourceEntry.duration.toFixed(2)}ms`
                });
            }
            // 只有在有新条目时才触发更新
            if (hasNewEntries) {
                logger.info(`新增${newEntriesCount}个资源性能指标,总计${this.resources.length}个`);
                this.onUpdate(this.resources);
                this.resources = [];
            }
        }
        /**
         * 判断是否应该处理资源条目
         */
        shouldProcessEntry(resourceEntry) {
            // 检查资源类型是否允许监控
            if (!this.allowedResourceTypes.includes(resourceEntry.initiatorType)) {
                logger.debug('忽略不在允许类型中的资源:', resourceEntry.initiatorType, this.shortenUrl(resourceEntry.name));
                return false;
            }
            // 检查是否在排除列表中
            if (this.isExcluded(resourceEntry.name)) {
                logger.debug('忽略在排除列表中的资源:', this.shortenUrl(resourceEntry.name));
                return false;
            }
            // 检查是否为重复条目
            const isDuplicate = this.resources.some(r => r.url === resourceEntry.name && r.startTime === resourceEntry.startTime);
            if (isDuplicate) {
                logger.debug('忽略重复的资源:', this.shortenUrl(resourceEntry.name));
            }
            return !isDuplicate;
        }
        /**
         * 从资源条目构建资源指标对象
         */
        buildResourceMetric(resourceEntry) {
            // 计算时间指标
            const dnsTime = calculateTimeDelta(resourceEntry.domainLookupEnd, resourceEntry.domainLookupStart);
            const tcpTime = calculateTimeDelta(resourceEntry.connectEnd, resourceEntry.connectStart);
            const sslTime = resourceEntry.secureConnectionStart > 0
                ? calculateTimeDelta(resourceEntry.connectEnd, resourceEntry.secureConnectionStart)
                : 0;
            const ttfb = calculateTimeDelta(resourceEntry.responseStart, resourceEntry.requestStart);
            const requestTime = calculateTimeDelta(resourceEntry.responseStart, resourceEntry.fetchStart);
            const responseTime = calculateTimeDelta(resourceEntry.responseEnd, resourceEntry.responseStart);
            // 获取网络信息
            const networkMetrics = NetworkMetricsCollector.getNetworkInformation();
            return {
                url: resourceEntry.name,
                initiatorType: resourceEntry.initiatorType,
                startTime: resourceEntry.startTime,
                duration: resourceEntry.duration,
                transferSize: resourceEntry.transferSize,
                decodedBodySize: resourceEntry.decodedBodySize,
                encodedSize: resourceEntry.encodedBodySize || undefined,
                responseEnd: resourceEntry.responseEnd,
                ttfb,
                dnsTime,
                tcpTime,
                sslTime,
                requestTime,
                responseTime,
                networkMetrics,
                timestamp: new Date().getTime(),
                metric: 'resources'
            };
        }
        /**
         * 检查资源URL是否应被排除
         */
        isExcluded(url) {
            if (!this.excludedPatterns.length) {
                return false;
            }
            return this.excludedPatterns.some(pattern => {
                if (pattern instanceof RegExp) {
                    return pattern.test(url);
                }
                return url.includes(pattern);
            });
        }
        /**
         * 停止资源性能监控
         */
        stop() {
            logger.info('停止资源性能监控');
            if (this.observer) {
                this.observer.disconnect();
                this.observer = null;
                logger.debug('资源计时观察者已断开连接');
            }
        }
        /**
         * 获取收集到的资源性能指标
         */
        getResources() {
            return this.resources;
        }
        /**
         * 清除已收集的资源性能指标
         */
        clearResources() {
            const count = this.resources.length;
            this.resources = [];
            logger.info(`清除了${count}个资源性能指标`);
            if (typeof performance !== 'undefined' &&
                typeof performance.clearResourceTimings === 'function') {
                performance.clearResourceTimings();
                logger.debug('清除了浏览器性能条目缓存');
            }
        }
        /**
         * 截断URL以便于日志输出
         * @param url 完整URL
         * @returns 截断后的URL
         */
        shortenUrl(url) {
            try {
                const urlObj = new URL(url);
                const pathname = urlObj.pathname;
                // 只返回主机名和路径名的最后部分
                return urlObj.hostname + pathname.substring(pathname.lastIndexOf('/'));
            }
            catch (e) {
                // 如果URL解析失败,则返回截断后的URL
                return url.length > 40 ? url.substring(0, 25) + '...' + url.substring(url.length - 12) : url;
            }
        }
    }

    /**
     * 长任务监控观察者
     * 负责监控并收集页面中的长任务(Long Tasks)信息
     */
    class LongTasksObserver {
        /**
         * 创建长任务观察者实例
         * @param options 长任务观察者配置
         */
        constructor(options) {
            this.observer = null;
            this.longTasks = [];
            this.onUpdate = options.onUpdate;
            this.options = {
                enabled: options.enabled !== undefined ? options.enabled : true,
                threshold: options.threshold || 50, // 默认50毫秒
                maxEntries: options.maxEntries || 100,
                ...options
            };
            logger.debug('长任务观察者已创建,配置:', {
                enabled: this.options.enabled,
                threshold: this.options.threshold,
                maxEntries: this.options.maxEntries
            });
        }
        /**
         * 开始监控长任务
         */
        start() {
            logger.info('开始长任务监控');
            try {
                this.observer = new PerformanceObserver((entryList) => {
                    const entries = entryList.getEntries();
                    let newTasksCount = 0;
                    for (const entry of entries) {
                        // 检查任务持续时间是否超过阈值
                        if (entry.duration < (this.options.threshold || 50)) {
                            continue;
                        }
                        const attribution = this.getAttribution(entry);
                        const longTask = {
                            duration: entry.duration,
                            startTime: entry.startTime,
                            attribution,
                            timestamp: new Date().getTime(),
                            metric: 'longTasks'
                        };
                        this.longTasks.push(longTask);
                        newTasksCount++;
                        logger.debug('检测到长任务:', {
                            duration: `${entry.duration.toFixed(2)}ms`,
                            source: attribution || 'unknown'
                        });
                        // 如果超过最大条目数,移除最旧的
                        const maxEntries = this.options.maxEntries || 100;
                        if (this.longTasks.length > maxEntries) {
                            this.longTasks.shift();
                            logger.debug('超出最大长任务记录数,移除最旧的条目');
                        }
                    }
                    if (newTasksCount > 0) {
                        logger.info(`检测到${newTasksCount}个新的长任务,总计${this.longTasks.length}个`);
                        this.onUpdate(this.longTasks);
                        this.longTasks = [];
                    }
                });
                this.observer.observe({ type: 'longtask', buffered: true });
                logger.debug('长任务观察者已启动,阈值为', this.options.threshold, 'ms');
            }
            catch (error) {
                logger.error('长任务监控不受支持', error);
            }
        }
        /**
         * 停止监控长任务
         */
        stop() {
            logger.info('停止长任务监控');
            if (this.observer) {
                this.observer.disconnect();
                this.observer = null;
                logger.debug('长任务观察者已断开连接');
            }
        }
        /**
         * 获取收集到的长任务数据
         */
        getLongTasks() {
            return this.longTasks;
        }
        /**
         * 清除收集到的长任务数据
         */
        clearLongTasks() {
            const count = this.longTasks.length;
            this.longTasks = [];
            logger.info(`清除了${count}个长任务记录`);
        }
        /**
         * 获取长任务的归属信息
         */
        getAttribution(entry) {
            // Try to get attribution from the entry if available
            if ('attribution' in entry) {
                const attribution = entry.attribution;
                if (Array.isArray(attribution) && attribution.length > 0) {
                    const attributionEntry = attribution[0];
                    if (attributionEntry.containerName) {
                        return attributionEntry.containerName;
                    }
                    else if (attributionEntry.containerSrc) {
                        return attributionEntry.containerSrc;
                    }
                    else if (attributionEntry.containerId) {
                        return attributionEntry.containerId;
                    }
                    else if (attributionEntry.containerType) {
                        return attributionEntry.containerType;
                    }
                }
            }
            return 'unknown';
        }
    }

    /**
     * 导航计时观察者
     * 收集页面加载性能指标,包括导航计时、网络信息等
     */
    class NavigationObserver {
        constructor(options) {
            // 存储收集到的指标数据
            this.metrics = {};
            // 当前实例状态标记
            this.isStarted = false;
            this.hasCollectedMetrics = false;
            // 性能观察器和超时控制
            this.perfObserver = null;
            this.timeoutId = null;
            // 配置常量
            this.MAX_WAIT_TIME_MS = 10000; // 10秒超时限制
            this.MAX_POLL_ATTEMPTS = 10; // 最大轮询次数
            this.POLL_INTERVAL_MS = 200; // 轮询间隔
            this.metricsUpdateCallback = options.onUpdate;
            this.options = {
                enabled: options.enabled !== undefined ? options.enabled : true,
                includeRawTiming: options.includeRawTiming || false,
                onUpdate: options.onUpdate
            };
            logger.debug('创建导航计时观察者', {
                enabled: this.options.enabled,
                includeRawTiming: this.options.includeRawTiming
            });
        }
        start() {
            // 避免重复启动或已收集过指标
            if (!this.canStart()) {
                return;
            }
            this.isStarted = true;
            this.timeoutId = window.setTimeout(() => {
                logger.warn(`等待超过${this.MAX_WAIT_TIME_MS}ms,强制收集可用的导航性能数据`);
                this.collectNavigationData(true); // 强制收集
                this.cleanupResources();
            }, this.MAX_WAIT_TIME_MS);
            // 尝试使用PerformanceObserver(现代浏览器首选方法)
            if (typeof PerformanceObserver !== 'undefined') {
                try {
                    this.perfObserver = new PerformanceObserver((entries) => {
                        const navigationEntries = entries.getEntries()
                            .filter(entry => entry.entryType === 'navigation');
                        if (navigationEntries.length === 0) {
                            return;
                        }
                        const latestEntry = navigationEntries[navigationEntries.length - 1];
                        if (this.isLoadEventComplete(latestEntry)) {
                            this.processNavigationData(latestEntry);
                            this.cleanupResources();
                        }
                    });
                    this.perfObserver.observe({ type: 'navigation', buffered: true });
                    logger.debug('开始使用PerformanceObserver监测导航性能');
                }
                catch (error) {
                    logger.error('PerformanceObserver初始化失败', error);
                    this.startWithTraditionalMethod();
                }
            }
            else {
                this.startWithTraditionalMethod();
            }
        }
        stop() {
            logger.info('停止导航性能数据收集');
            this.isStarted = false;
            this.cleanupResources();
        }
        /**
         * 获取收集到的导航性能指标
         */
        getMetrics() {
            return this.metrics;
        }
        /**
         * 检查是否可以开始收集指标
         */
        canStart() {
            if (!this.options.enabled) {
                logger.debug('导航计时观察者已禁用');
                return false;
            }
            if (this.isStarted) {
                logger.debug('导航计时观察者已处于活动状态');
                return false;
            }
            if (this.hasCollectedMetrics) {
                logger.debug('导航计时观察者已收集过指标');
                return false;
            }
            return true;
        }
        /**
         * 清理超时定时器
         */
        clearTimeout() {
            if (this.timeoutId !== null) {
                window.clearTimeout(this.timeoutId);
                this.timeoutId = null;
            }
        }
        /**
         * 清理所有资源
         */
        cleanupResources() {
            // 清理性能观察者
            if (this.perfObserver) {
                this.perfObserver.disconnect();
                this.perfObserver = null;
            }
            // 清理定时器
            this.clearTimeout();
        }
        /**
         * 使用传统方法开始收集导航性能数据
         */
        startWithTraditionalMethod() {
            logger.info('使用传统方法收集导航性能数据');
            if (document.readyState === 'complete') {
                this.pollForNavigationData();
            }
            else {
                window.addEventListener('load', () => {
                    setTimeout(() => this.pollForNavigationData(), 100);
                });
            }
        }
        /**
         * 通过轮询方式检查并获取导航性能数据
         */
        pollForNavigationData(attemptCount = 0) {
            // 超过最大尝试次数,强制收集
            if (attemptCount > this.MAX_POLL_ATTEMPTS) {
                logger.warn(`轮询${this.MAX_POLL_ATTEMPTS}次后未获取到完整数据,强制收集可用数据`);
                this.collectNavigationData(true);
                return;
            }
            // 尝试获取导航性能条目
            const navEntry = this.getLatestNavigationEntry();
            if (!navEntry) {
                logger.warn('未找到导航性能条目');
                return;
            }
            // 检查数据是否完整
            if (this.isLoadEventComplete(navEntry)) {
                this.collectNavigationData();
                this.clearTimeout();
            }
            else {
                // 延迟后再次尝试
                setTimeout(() => this.pollForNavigationData(attemptCount + 1), this.POLL_INTERVAL_MS);
            }
        }
        /**
         * 获取最新的导航性能条目
         */
        getLatestNavigationEntry() {
            if (!('performance' in window) || !('getEntriesByType' in performance)) {
                return null;
            }
            const entries = performance.getEntriesByType('navigation');
            if (!entries || entries.length === 0) {
                return null;
            }
            return entries[entries.length - 1];
        }
        /**
         * 收集导航计时数据
         */
        collectNavigationData(forceProcess = false) {
            const navEntry = this.getLatestNavigationEntry();
            if (!navEntry) {
                logger.warn('无法收集导航性能数据:未找到导航性能条目');
                return;
            }
            // 检查loadEvent数据是否完整
            if (!forceProcess && !this.isLoadEventComplete(navEntry)) {
                logger.warn('导航性能数据不完整:load事件未完成');
                return;
            }
            this.processNavigationData(navEntry);
        }
        /**
         * 判断load事件是否已完成
         */
        isLoadEventComplete(entry) {
            // 检查loadEvent相关属性是否有效
            const hasValidStart = typeof entry.loadEventStart === 'number' && entry.loadEventStart > 0;
            const hasValidEnd = typeof entry.loadEventEnd === 'number' && entry.loadEventEnd > 0;
            const isComplete = hasValidStart && hasValidEnd && entry.loadEventEnd >= entry.loadEventStart;
            if (!isComplete) {
                logger.debug('load事件数据不完整', {
                    loadEventStart: entry.loadEventStart,
                    loadEventEnd: entry.loadEventEnd
                });
            }
            return isComplete;
        }
        /**
         * 处理导航性能条目,提取和计算指标
         */
        processNavigationData(entry) {
            var _a, _b, _c, _d;
            // 计算性能指标
            const timingMetrics = {
                // 资源加载阶段
                unloadTime: calculateTime(entry.unloadEventEnd, entry.unloadEventStart),
                redirectTime: calculateTime(entry.redirectEnd, entry.redirectStart),
                // Service Worker阶段
                serviceWorkerTime: entry.workerStart > 0
                    ? calculateTime(entry.workerStart, entry.fetchStart)
                    : undefined,
                // DNS/TCP/SSL阶段
                appCacheTime: calculateTime(entry.domainLookupStart, entry.fetchStart),
                dnsTime: calculateTime(entry.domainLookupEnd, entry.domainLookupStart),
                tcpTime: calculateTime(entry.connectEnd, entry.connectStart),
                sslTime: entry.secureConnectionStart > 0
                    ? calculateTime(entry.connectEnd, entry.secureConnectionStart)
                    : undefined,
                // 请求/响应阶段
                requestTime: calculateTime(entry.responseStart, entry.requestStart),
                ttfb: calculateTime(entry.responseStart, entry.requestStart),
                resourceFetchTime: calculateTime(entry.responseStart, entry.fetchStart),
                responseTime: calculateTime(entry.responseEnd, entry.responseStart),
                // DOM处理阶段
                initDOMTime: calculateTime(entry.domInteractive, entry.responseEnd),
                processingTime: calculateTime(entry.domComplete, entry.domInteractive),
                contentLoadTime: calculateTime(entry.domContentLoadedEventEnd, entry.domContentLoadedEventStart),
                // 页面加载完成指标
                domContentLoaded: calculateTime(entry.domContentLoadedEventEnd, entry.startTime),
                loadEventDuration: calculateTime(entry.loadEventEnd, entry.loadEventStart),
                frontEndTime: calculateTime(entry.loadEventEnd, entry.responseEnd),
                totalLoadTime: calculateTime(entry.loadEventEnd, entry.startTime)
            };
            // 获取网络信息
            const networkMetrics = NetworkMetricsCollector.getNetworkInformation();
            // 获取当前页面URL
            const pageUrl = typeof window !== 'undefined' ? window.location.href : entry.name;
            logger.info('导航性能指标', {
                url: entry.name, // 移除查询参数
                ttfb: `${((_a = timingMetrics.ttfb) === null || _a === void 0 ? void 0 : _a.toFixed(2)) || 0}ms`,
                domContentLoaded: `${((_b = timingMetrics.domContentLoaded) === null || _b === void 0 ? void 0 : _b.toFixed(2)) || 0}ms`,
                loadEventDuration: `${((_c = timingMetrics.loadEventDuration) === null || _c === void 0 ? void 0 : _c.toFixed(2)) || 0}ms`,
                totalLoadTime: `${((_d = timingMetrics.totalLoadTime) === null || _d === void 0 ? void 0 : _d.toFixed(2)) || 0}ms`
            });
            // 整合所有指标
            this.metrics = {
                ...timingMetrics,
                url: pageUrl,
                metric: 'navigation',
                networkMetrics,
                timestamp: Date.now(),
                complete: true
            };
            // 根据配置添加原始计时数据
            if (this.options.includeRawTiming) {
                this.metrics.rawTiming = {
                    navigationStart: entry.startTime,
                    unloadEventStart: entry.unloadEventStart,
                    unloadEventEnd: entry.unloadEventEnd,
                    redirectStart: entry.redirectStart,
                    redirectEnd: entry.redirectEnd,
                    fetchStart: entry.fetchStart,
                    domainLookupStart: entry.domainLookupStart,
                    domainLookupEnd: entry.domainLookupEnd,
                    connectStart: entry.connectStart,
                    connectEnd: entry.connectEnd,
                    secureConnectionStart: entry.secureConnectionStart,
                    requestStart: entry.requestStart,
                    responseStart: entry.responseStart,
                    responseEnd: entry.responseEnd,
                    domInteractive: entry.domInteractive,
                    domContentLoadedEventStart: entry.domContentLoadedEventStart,
                    domContentLoadedEventEnd: entry.domContentLoadedEventEnd,
                    domComplete: entry.domComplete,
                    loadEventStart: entry.loadEventStart,
                    loadEventEnd: entry.loadEventEnd,
                    type: entry.type,
                    redirectCount: entry.redirectCount,
                };
            }
            // 调用回调函数
            this.metricsUpdateCallback(this.metrics);
            this.hasCollectedMetrics = true;
        }
    }

    /**
     * 浏览器和设备信息收集器
     * 提供收集浏览器环境信息的方法
     */
    class BrowserInfoCollector {
        /**
         * 获取浏览器和设备相关信息
         * @returns 浏览器和设备信息
         */
        static getBrowserInfo() {
            if (typeof window === 'undefined' || typeof navigator === 'undefined') {
                return {};
            }
            try {
                return {
                    userAgent: navigator.userAgent,
                    language: navigator.language,
                    platform: navigator.platform,
                    vendor: navigator.vendor,
                    screenSize: {
                        width: window.screen.width,
                        height: window.screen.height
                    },
                    windowSize: {
                        width: window.innerWidth,
                        height: window.innerHeight
                    },
                    devicePixelRatio: window.devicePixelRatio,
                    cookiesEnabled: navigator.cookieEnabled
                };
            }
            catch (error) {
                console.warn('无法获取完整的浏览器信息', error);
                return {};
            }
        }
        /**
         * 检测浏览器名称和版本
         * @returns 浏览器名称和版本信息
         */
        static detectBrowser() {
            var _a, _b, _c, _d, _e, _f, _g, _h, _j;
            if (typeof navigator === 'undefined') {
                return { name: 'unknown', version: 'unknown' };
            }
            const userAgent = navigator.userAgent;
            let browserName = 'unknown';
            let version = 'unknown';
            try {
                // 检测常见浏览器
                if (userAgent.indexOf('Firefox') > -1) {
                    browserName = 'Firefox';
                    version = ((_a = userAgent.match(/Firefox\/([\d.]+)/)) === null || _a === void 0 ? void 0 : _a[1]) || '';
                }
                else if (userAgent.indexOf('Edge') > -1 || userAgent.indexOf('Edg/') > -1) {
                    browserName = 'Edge';
                    version = ((_b = userAgent.match(/Edge\/([\d.]+)/)) === null || _b === void 0 ? void 0 : _b[1]) ||
                        ((_c = userAgent.match(/Edg\/([\d.]+)/)) === null || _c === void 0 ? void 0 : _c[1]) || '';
                }
                else if (userAgent.indexOf('Chrome') > -1) {
                    browserName = 'Chrome';
                    version = ((_d = userAgent.match(/Chrome\/([\d.]+)/)) === null || _d === void 0 ? void 0 : _d[1]) || '';
                }
                else if (userAgent.indexOf('Safari') > -1 && userAgent.indexOf('Chrome') === -1) {
                    browserName = 'Safari';
                    version = ((_e = userAgent.match(/Version\/([\d.]+)/)) === null || _e === void 0 ? void 0 : _e[1]) || '';
                }
                else if (userAgent.indexOf('MSIE') > -1 || userAgent.indexOf('Trident/') > -1) {
                    browserName = 'Internet Explorer';
                    version = ((_f = userAgent.match(/MSIE ([\d.]+)/)) === null || _f === void 0 ? void 0 : _f[1]) ||
                        ((_g = userAgent.match(/rv:([\d.]+)/)) === null || _g === void 0 ? void 0 : _g[1]) || '';
                }
                else if (userAgent.indexOf('Opera') > -1 || userAgent.indexOf('OPR/') > -1) {
                    browserName = 'Opera';
                    version = ((_h = userAgent.match(/Opera\/([\d.]+)/)) === null || _h === void 0 ? void 0 : _h[1]) ||
                        ((_j = userAgent.match(/OPR\/([\d.]+)/)) === null || _j === void 0 ? void 0 : _j[1]) || '';
                }
                return { name: browserName, version };
            }
            catch (error) {
                console.warn('无法检测浏览器版本', error);
                return { name: 'unknown', version: 'unknown' };
            }
        }
        /**
         * 检测操作系统
         * @returns 操作系统名称和版本信息
         */
        static detectOS() {
            var _a, _b, _c, _d, _e;
            if (typeof navigator === 'undefined') {
                return { name: 'unknown', version: 'unknown' };
            }
            const userAgent = navigator.userAgent;
            let osName = 'unknown';
            let version = 'unknown';
            try {
                if (userAgent.indexOf('Windows') > -1) {
                    osName = 'Windows';
                    if (userAgent.indexOf('Windows NT 10.0') > -1)
                        version = '10';
                    else if (userAgent.indexOf('Windows NT 6.3') > -1)
                        version = '8.1';
                    else if (userAgent.indexOf('Windows NT 6.2') > -1)
                        version = '8';
                    else if (userAgent.indexOf('Windows NT 6.1') > -1)
                        version = '7';
                    else if (userAgent.indexOf('Windows NT 6.0') > -1)
                        version = 'Vista';
                    else if (userAgent.indexOf('Windows NT 5.1') > -1)
                        version = 'XP';
                }
                else if (userAgent.indexOf('Mac OS X') > -1) {
                    osName = 'macOS';
                    version = ((_b = (_a = userAgent.match(/Mac OS X ([0-9_\.]+)/)) === null || _a === void 0 ? void 0 : _a[1]) === null || _b === void 0 ? void 0 : _b.replace(/_/g, '.')) || '';
                }
                else if (userAgent.indexOf('Android') > -1) {
                    osName = 'Android';
                    version = ((_c = userAgent.match(/Android ([0-9\.]+)/)) === null || _c === void 0 ? void 0 : _c[1]) || '';
                }
                else if (userAgent.indexOf('iOS') > -1 || userAgent.indexOf('iPhone') > -1 || userAgent.indexOf('iPad') > -1) {
                    osName = 'iOS';
                    version = ((_e = (_d = userAgent.match(/OS ([0-9_\.]+)/)) === null || _d === void 0 ? void 0 : _d[1]) === null || _e === void 0 ? void 0 : _e.replace(/_/g, '.')) || '';
                }
                else if (userAgent.indexOf('Linux') > -1) {
                    osName = 'Linux';
                }
                return { name: osName, version };
            }
            catch (error) {
                console.warn('无法检测操作系统', error);
                return { name: 'unknown', version: 'unknown' };
            }
        }
        /**
         * 获取完整的环境信息
         * @returns 完整的浏览器和操作系统信息
         */
        static getEnvironmentInfo() {
            const browserInfo = this.getBrowserInfo();
            const browserDetails = this.detectBrowser();
            const osDetails = this.detectOS();
            return {
                ...browserInfo,
                browser: browserDetails,
                os: osDetails
            };
        }
    }

    /**
     * 浏览器信息观察者
     * 负责收集和监控浏览器和设备相关信息
     */
    class BrowserInfoObserver {
        /**
         * 创建浏览器信息观察者实例
         * @param options 浏览器信息观察者配置
         */
        constructor(options) {
            this.browserInfo = {};
            this.resizeHandler = null;
            this._resizeTimeout = 0;
            this.onUpdate = options.onUpdate;
            this.options = {
                enabled: options.enabled !== undefined ? options.enabled : true,
                trackResize: options.trackResize !== undefined ? options.trackResize : false,
                includeOSDetails: options.includeOSDetails !== undefined ? options.includeOSDetails : true,
                includeSizeInfo: options.includeSizeInfo !== undefined ? options.includeSizeInfo : true,
                onUpdate: options.onUpdate
            };
        }
        /**
         * 开始收集浏览器信息
         */
        start() {
            if (!this.options.enabled) {
                return;
            }
            try {
                // 收集初始浏览器信息
                this.collectBrowserInfo();
                // 如果启用了调整大小跟踪,则设置调整大小事件监听器
                if (this.options.trackResize && typeof window !== 'undefined') {
                    this.resizeHandler = this.handleResize.bind(this);
                    window.addEventListener('resize', this.resizeHandler);
                    logger.debug('开始监听窗口大小变化');
                }
                logger.info('浏览器信息观察者已启动');
            }
            catch (error) {
                logger.error('启动浏览器信息观察者时出错', error);
            }
        }
        /**
         * 停止收集浏览器信息
         */
        stop() {
            if (this.resizeHandler && typeof window !== 'undefined') {
                window.removeEventListener('resize', this.resizeHandler);
                this.resizeHandler = null;
            }
            logger.info('浏览器信息观察者已停止');
        }
        /**
         * 获取收集到的浏览器信息
         * @returns 浏览器和设备信息
         */
        getBrowserInfo() {
            return this.browserInfo;
        }
        /**
         * 手动更新浏览器信息
         */
        refresh() {
            this.collectBrowserInfo();
        }
        /**
         * 收集浏览器信息
         */
        collectBrowserInfo() {
            try {
                // 获取完整的环境信息
                const fullInfo = BrowserInfoCollector.getEnvironmentInfo();
                // 根据选项过滤信息
                if (!this.options.includeOSDetails) {
                    delete fullInfo.os;
                }
                if (!this.options.includeSizeInfo) {
                    delete fullInfo.screenSize;
                    delete fullInfo.windowSize;
                    delete fullInfo.devicePixelRatio;
                }
                // 添加当前URL
                if (typeof window !== 'undefined') {
                    fullInfo.url = window.location.href;
                }
                this.browserInfo = fullInfo;
                // 通知更新
                this.onUpdate(this.browserInfo);
            }
            catch (error) {
                logger.error('收集浏览器信息时出错', error);
            }
        }
        /**
         * 处理窗口大小调整事件
         */
        handleResize() {
            if (typeof window === 'undefined') {
                return;
            }
            // 使用防抖动以避免频繁更新
            if (this.resizeHandler) {
                window.clearTimeout(this._resizeTimeout);
                this._resizeTimeout = window.setTimeout(() => {
                    logger.debug('窗口大小已更改,更新浏览器信息');
                    this.collectBrowserInfo();
                }, 500); // 500ms防抖动
            }
        }
    }

    // 从package.json获取版本号 - 这个值会在构建时被rollup插件替换
    // 使用字符串形式,避免TypeScript编译错误
    const VERSION = '0.0.6';
    /**
     * 性能观察工具包 - 性能监控的主类
     */
    class PerfObserverKit {
        /**
         * 创建性能观察工具包实例
         */
        constructor(options = {}) {
            this.coreWebVitalsObserver = null;
            this.resourceTimingObserver = null;
            this.longTasksObserver = null;
            this.navigationObserver = null;
            this.browserInfoObserver = null;
            this.metrics = {
                coreWebVitals: {},
                resources: [],
                longTasks: [],
                navigation: {},
                browserInfo: {}
            };
            this.isRunning = false;
            // 检查基本兼容性
            this.checkBrowserCompatibility();
            // 验证输入选项
            this.validateOptions(options);
            // 规范化和组合选项
            const logLevel = this.determineLogLevel(options);
            this.options = {
                onMetrics: options.onMetrics || null,
                debug: options.debug !== undefined ? options.debug : false,
                logLevel,
                autoStart: options.autoStart !== undefined ? options.autoStart : false,
                samplingRate: options.samplingRate !== undefined ? options.samplingRate : 0,
                coreWebVitals: this.normalizeCoreWebVitalsOptions(options.coreWebVitals),
                resources: this.normalizeResourceOptions(options.resources),
                longTasks: this.normalizeModuleOptions(options.longTasks, false),
                navigation: this.normalizeModuleOptions(options.navigation, false),
                browserInfo: this.normalizeModuleOptions(options.browserInfo, false)
            };
            // 初始化日志系统 - 通过显式设置选项,确保即使在生产环境也能使用调试模式
            logger.setOptions({
                level: this.options.logLevel,
                disableInProduction: false // 确保生产环境中也能使用日志
            });
            // 输出初始化日志
            logger.debug('PerfObserverKit初始化完成,配置:', this.options);
            // 如果启用了自动开始,则自动启动监控
            if (this.options.autoStart) {
                this.start();
            }
        }
        /**
         * 验证传入的选项
         */
        validateOptions(options) {
            // 验证采样率
            if (options.samplingRate !== undefined &&
                (typeof options.samplingRate !== 'number' ||
                    options.samplingRate < 0 ||
                    options.samplingRate > 1)) {
                logger.warn('无效的采样率设置,应为0到1之间的数字,将使用默认值0');
                options.samplingRate = 0;
            }
            // 验证onMetrics回调
            if (options.onMetrics !== undefined && typeof options.onMetrics !== 'function') {
                logger.warn('onMetrics必须是一个函数,将使用默认空函数');
                options.onMetrics = () => { };
            }
        }
        /**
         * 检查浏览器兼容性
         */
        checkBrowserCompatibility() {
            if (!browserSupport.hasPerformanceAPI()) {
                logger.warn('当前浏览器不支持Performance API');
            }
            if (!browserSupport.hasPerformanceObserver()) {
                logger.warn('当前浏览器不支持PerformanceObserver');
            }
        }
        /**
         * 确定使用的日志级别
         */
        determineLogLevel(options) {
            if (options.logLevel !== undefined) {
                // 确保值在有效范围内
                const level = Number(options.logLevel);
                if (level >= exports.LogLevel.NONE && level <= exports.LogLevel.DEBUG) {
                    return level;
                }
            }
            // 基于debug选项设置默认日志级别
            return options.debug ? exports.LogLevel.DEBUG : exports.LogLevel.WARN;
        }
        /**
         * 规范化模块配置为标准格式
         * @param options 用户提供的模块配置
         * @param defaultEnabled 默认是否启用
         */
        normalizeModuleOptions(options, defaultEnabled) {
            try {
                // 处理布尔值情况
                if (typeof options === 'boolean') {
                    return { enabled: options };
                }
                // 处理对象情况
                if (options && typeof options === 'object') {
                    return {
                        ...options,
                        enabled: options.enabled !== undefined ? options.enabled : defaultEnabled
                    };
                }
                // 处理未定义情况
                return { enabled: defaultEnabled };
            }
            catch (error) {
                logger.error('规范化模块配置失败:', error);
                return { enabled: defaultEnabled };
            }
        }
        /**
         * 规范化资源计时选项
         */
        normalizeResourceOptions(options) {
            try {
                // 首先使用通用方法获取基础选项
                const normalizedOptions = this.normalizeModuleOptions(options, true);
                // 处理配置选项,设置默认值
                return {
                    ...normalizedOptions,
                    maxResources: normalizedOptions.maxResources !== undefined ? normalizedOptions.maxResources : 100,
                    excludedPatterns: normalizedOptions.excludedPatterns || [],
                    allowedTypes: normalizedOptions.allowedTypes || [], // 默认允许所有类型
                    captureNetworkInfo: normalizedOptions.captureNetworkInfo !== undefined ? normalizedOptions.captureNetworkInfo : true,
                    maxEntries: normalizedOptions.maxEntries !== undefined ? normalizedOptions.maxEntries : 100
                };
            }
            catch (error) {
                logger.error('规范化资源计时选项失败:', error);
                return {
                    enabled: false,
                    maxResources: 100,
                    excludedPatterns: [],
                    allowedTypes: [],
                    captureNetworkInfo: true,
                    maxEntries: 100
                };
            }
        }
        /**
         * 规范化核心Web指标选项
         */
        normalizeCoreWebVitalsOptions(options) {
            try {
                // 首先使用通用方法获取基础选项
                const normalizedOptions = this.normalizeModuleOptions(options, false);
                // 如果传入的是布尔值true,启用所有指标
                if (options === true) {
                    return {
                        enabled: true,
                        fcp: true,
                        lcp: true,
                        fid: false,
                        cls: false,
                        inp: false,
                        maxLongTasks: 50,
                        maxResources: 100
                    };
                }
                // 处理配置选项,设置默认值
                return {
                    ...normalizedOptions,
                    fcp: normalizedOptions.fcp !== undefined ? normalizedOptions.fcp : false,
                    lcp: normalizedOptions.lcp !== undefined ? normalizedOptions.lcp : false,
                    fid: normalizedOptions.fid !== undefined ? normalizedOptions.fid : false,
                    cls: normalizedOptions.cls !== undefined ? normalizedOptions.cls : false,
                    inp: normalizedOptions.inp !== undefined ? normalizedOptions.inp : false,
                    maxLongTasks: normalizedOptions.maxLongTasks !== undefined ? normalizedOptions.maxLongTasks : 50,
                    maxResources: normalizedOptions.maxResources !== undefined ? normalizedOptions.maxResources : 100
                };
            }
            catch (error) {
                logger.error('规范化核心Web指标选项失败:', error);
                return {
                    enabled: false,
                    fcp: false,
                    lcp: false,
                    fid: false,
                    cls: false,
                    inp: false,
                    maxLongTasks: 50,
                    maxResources: 100
                };
            }
        }
        /**
         * 开始监控性能指标
         */
        start() {
            if (this.isRunning) {
                logger.warn('性能监控已经在运行中');
                return;
            }
            logger.info('开始监控性能指标');
            // 采样率检查 - 如果配置了采样率,根据随机数决定是否收集数据
            if (this.options.samplingRate > 0 && Math.random() > this.options.samplingRate) {
                logger.debug(`根据采样率(${this.options.samplingRate})决定不收集此会话的性能数据`);
                // 将状态设置为运行中,但实际不启动监控
                this.isRunning = true;
                return;
            }
            // 使用通用方法启动各个观察器
            this.startObserver('coreWebVitals', this.startCoreWebVitalsMonitoring.bind(this));
            this.startObserver('resources', this.startResourceTimingMonitoring.bind(this));
            this.startObserver('longTasks', this.startLongTasksMonitoring.bind(this));
            this.startObserver('navigation', this.startNavigationMonitoring.bind(this));
            this.startObserver('browserInfo', this.startBrowserInfoMonitoring.bind(this));
            this.isRunning = true;
            logger.debug('所有启用的性能监控模块已启动');
        }
        /**
         * 通用启动观察器方法
         */
        startObserver(name, startMethod) {
            const option = this.options[name];
            if (option && option.enabled) {
                startMethod();
            }
        }
        /**
         * 停止监控性能指标
         */
        stop() {
            if (!this.isRunning) {
                logger.warn('性能监控未在运行中');
                return;
            }
            logger.info('停止监控性能指标');
            // 停止并清理所有观察器
            this.cleanupObserver(this.coreWebVitalsObserver);
            this.cleanupObserver(this.resourceTimingObserver);
            this.cleanupObserver(this.longTasksObserver);
            this.cleanupObserver(this.navigationObserver);
            this.cleanupObserver(this.browserInfoObserver);
            // 重置所有观察器引用
            this.coreWebVitalsObserver = null;
            this.resourceTimingObserver = null;
            this.longTasksObserver = null;
            this.navigationObserver = null;
            this.browserInfoObserver = null;
            this.isRunning = false;
            logger.debug('所有性能监控模块已停止');
        }
        /**
         * 清理观察器
         */
        cleanupObserver(observer) {
            if (observer) {
                try {
                    observer.stop();
                }
                catch (error) {
                    logger.error('停止观察器失败:', error);
                }
            }
        }
        /**
         * 获取当前的指标数据
         */
        getMetrics() {
            return this.metrics;
        }
        /**
         * 清除指标数据
         */
        clearMetrics() {
            logger.debug('清除指标数据,保留浏览器信息');
            // 保存当前的浏览器信息
            const currentBrowserInfo = this.metrics.browserInfo;
            this.metrics = {
                coreWebVitals: {},
                resources: [],
                longTasks: [],
                navigation: {},
                // 保留浏览器信息不清除
                browserInfo: currentBrowserInfo
            };
        }
        /**
         * 设置日志级别
         * @param level 日志级别
         */
        setLogLevel(level) {
            if (level >= exports.LogLevel.NONE && level <= exports.LogLevel.DEBUG) {
                this.options.logLevel = level;
                logger.setLevel(level);
                logger.debug('已更新日志级别为:', level);
            }
            else {
                logger.warn('无效的日志级别:', level);
            }
        }
        /**
         * 设置调试模式
         * @param enabled 是否启用调试模式
         */
        setDebugMode(enabled) {
            this.options.debug = enabled;
            // 如果启用了调试模式,自动将日志级别设置为DEBUG
            if (enabled && this.options.logLevel < exports.LogLevel.DEBUG) {
                this.setLogLevel(exports.LogLevel.DEBUG);
            }
            // 确保生产环境也可以看到日志
            logger.setOptions({
                disableInProduction: false
            });
            logger.debug('调试模式已' + (enabled ? '启用' : '禁用'));
            // 输出更详细的诊断信息
            if (enabled) {
                const config = logger.getConfiguration();
                logger.debug('日志配置状态:', config);
                logger.debug('当前监控状态:', {
                    isRunning: this.isRunning,
                    activeObservers: {
                        coreWebVitals: !!this.coreWebVitalsObserver,
                        resources: !!this.resourceTimingObserver,
                        longTasks: !!this.longTasksObserver,
                        navigation: !!this.navigationObserver,
                        browserInfo: !!this.browserInfoObserver
                    }
                });
            }
        }
        /**
         * 开始监控核心Web指标
         */
        startCoreWebVitalsMonitoring() {
            try {
                const requiredEntryTypes = [
                    'paint', // For FCP
                    'largest-contentful-paint',
                    'first-input',
                    'layout-shift'
                ];
                // 检查所需的条目类型是否受支持
                const unsupportedTypes = requiredEntryTypes.filter(type => !browserSupport.supportsEntryType(type));
                if (unsupportedTypes.length > 0) {
                    logger.warn(`部分核心Web指标在当前浏览器中不受支持: ${unsupportedTypes.join(', ')}`);
                }
                // 将配置传递给观察者
                const options = this.options.coreWebVitals;
                this.coreWebVitalsObserver = new CoreWebVitalsObserver({
                    onUpdate: (coreWebVitalsMetrics) => {
                        this.metrics.coreWebVitals = coreWebVitalsMetrics;
                        this.notifyMetricsUpdate(exports.MetricType.WEB_VITALS, coreWebVitalsMetrics);
                    },
                    enabled: options.enabled,
                    fcp: options.fcp,
                    lcp: options.lcp,
                    fid: options.fid,
                    cls: options.cls,
                    inp: options.inp,
                    backgroundLoadThreshold: options.backgroundLoadThreshold
                });
                this.coreWebVitalsObserver.start();
                logger.debug('核心Web指标监控已启动');
            }
            catch (error) {
                logger.error('启动核心Web指标监控失败:', error);
            }
        }
        /**
         * 开始监控资源计时
         */
        startResourceTimingMonitoring() {
            try {
                if (!browserSupport.supportsEntryType('resource')) {
                    logger.warn('当前浏览器不支持资源计时监控');
                    return;
                }
                const options = this.options.resources;
                this.resourceTimingObserver = new ResourceTimingObserver((resources) => {
                    this.notifyMetricsUpdate(exports.MetricType.RESOURCES, resources);
                    this.metrics.resources.push(...resources);
                    this.metrics.resources = this.metrics.resources.slice(-options.maxResources);
                }, options.excludedPatterns, options.allowedTypes);
                this.resourceTimingObserver.start();
                logger.debug('资源计时监控已启动');
            }
            catch (error) {
                logger.error('启动资源计时监控失败:', error);
            }
        }
        /**
         * 开始监控长任务
         */
        startLongTasksMonitoring() {
            try {
                if (!browserSupport.supportsEntryType('longtask')) {
                    logger.warn('当前浏览器不支持长任务监控');
                    return;
                }
                const options = this.options.longTasks;
                const maxLongTasks = options.maxLongTasks || 50; // 提供默认值防止未定义
                this.longTasksObserver = new LongTasksObserver({
                    onUpdate: (longTasks) => {
                        this.notifyMetricsUpdate(exports.MetricType.LONG_TASKS, longTasks);
                        this.metrics.longTasks.push(...longTasks);
                        this.metrics.longTasks = this.metrics.longTasks.slice(-maxLongTasks);
                    },
                    enabled: options.enabled,
                    threshold: options.threshold,
                    maxEntries: options.maxEntries
                });
                this.longTasksObserver.start();
                logger.debug('长任务监控已启动');
            }
            catch (error) {
                logger.error('启动长任务监控失败:', error);
            }
        }
        /**
         * 开始监控导航计时
         */
        startNavigationMonitoring() {
            try {
                if (!browserSupport.supportsEntryType('navigation')) {
                    logger.warn('当前浏览器不支持导航计时监控');
                    return;
                }
                const options = this.options.navigation;
                this.navigationObserver = new NavigationObserver({
                    onUpdate: (navigationMetrics) => {
                        this.metrics.navigation = navigationMetrics;
                        this.notifyMetricsUpdate(exports.MetricType.NAVIGATION, navigationMetrics);
                    },
                    enabled: options.enabled,
                    includeRawTiming: options.includeRawTiming
                });
                this.navigationObserver.start();
                logger.debug('导航计时监控已启动');
            }
            catch (error) {
                logger.error('启动导航计时监控失败:', error);
            }
        }
        /**
         * 开始监控浏览器信息
         */
        startBrowserInfoMonitoring() {
            try {
                const options = this.options.browserInfo;
                // 如果配置未启用,则直接返回
                if (!options.enabled) {
                    logger.debug('浏览器信息监控未启用');
                    return;
                }
                this.browserInfoObserver = new BrowserInfoObserver({
                    onUpdate: (browserInfo) => {
                        this.metrics.browserInfo = browserInfo;
                        this.notifyMetricsUpdate(exports.MetricType.BROWSER_INFO, browserInfo);
                    },
                    // 不再强制设为true,而是使用配置值
                    enabled: options.enabled,
                    trackResize: options.trackResize,
                    includeOSDetails: options.includeOSDetails,
                    includeSizeInfo: options.includeSizeInfo
                });
                this.browserInfoObserver.start();
                logger.debug('浏览器信息监控已启动');
            }
            catch (error) {
                logger.error('启动浏览器信息监控失败:', error);
            }
        }
        /**
         * 通知指标更新给回调函数
         */
        notifyMetricsUpdate(type, metrics) {
            try {
                if (this.options.onMetrics) {
                    // 调用回调函数
                    this.options.onMetrics(type, metrics);
                }
            }
            catch (error) {
                logger.error('指标更新回调执行失败:', error);
            }
        }
        /**
         * 获取库版本信息
         */
        getVersion() {
            return VERSION;
        }
        /**
         * 检查当前环境是否支持所有必要的API
         */
        static checkBrowserSupport() {
            const details = {
                performanceAPI: browserSupport.hasPerformanceAPI(),
                performanceObserver: browserSupport.hasPerformanceObserver(),
                navigation: browserSupport.supportsEntryType('navigation'),
                longtask: browserSupport.supportsEntryType('longtask'),
                resources: browserSupport.supportsEntryType('resource'),
                paint: browserSupport.supportsEntryType('paint'),
                largestContentfulPaint: browserSupport.supportsEntryType('largest-contentful-paint'),
                firstInput: browserSupport.supportsEntryType('first-input'),
                layoutShift: browserSupport.supportsEntryType('layout-shift')
            };
            // 基本支持需要Performance API和PerformanceObserver
            const supported = details.performanceAPI && details.performanceObserver;
            return { supported, details };
        }
        getStatus() {
            return {
                isRunning: this.isRunning,
                metrics: {
                    coreWebVitals: !!this.coreWebVitalsObserver,
                    resources: !!this.resourceTimingObserver,
                    longTasks: !!this.longTasksObserver,
                    navigation: !!this.navigationObserver,
                    browserInfo: !!this.browserInfoObserver
                }
            };
        }
    }

    /**
     * 浏览器入口文件
     * 这个文件是为了生成可直接在浏览器中使用的UMD模块
     */
    // 创建一个对象供浏览器使用
    const LibraryExports = {
        PerfObserverKit: PerfObserverKit,
        CoreWebVitalsObserver: CoreWebVitalsObserver,
        MetricType: exports.MetricType,
        logger: logger,
        LogLevel: exports.LogLevel
    };

    exports.CoreWebVitalsObserver = CoreWebVitalsObserver;
    exports.PerfObserverKit = PerfObserverKit;
    exports["default"] = LibraryExports;
    exports.logger = logger;

    Object.defineProperty(exports, '__esModule', { value: true });

}));
//# sourceMappingURL=perf-observer-kit.browser.js.map