UNPKG

unified-error-handling

Version:

A lightweight, zero-dependency error handling library with dynamic adapter loading for multiple error tracking services

1,835 lines 59.1 kB
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __esm = (fn, res) => function __init() {
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/adapters/base-adapter.ts
var BaseAdapter;
var init_base_adapter = __esm({
  "src/adapters/base-adapter.ts"() {
    "use strict";
    BaseAdapter = class {
      config;
      sdkInstance;
      sdkLoaded = false;
      async initialize(config) {
        this.config = config;
        await this.loadSDK();
        await this.initializeSDK();
      }
      async captureMessage(message, level) {
        const error = {
          message,
          timestamp: Date.now(),
          context: {},
          breadcrumbs: [],
          level: level || "info",
          handled: true,
          source: "manual"
        };
        await this.captureError(error);
      }
      async setContext(_context) {
      }
      async addBreadcrumb(_breadcrumb) {
      }
      async flush() {
      }
      async close() {
      }
      async dynamicImport(packageName) {
        try {
          return await import(packageName);
        } catch (_error) {
          throw new Error(
            `Failed to load ${packageName}. Please install it:
npm install ${packageName}
or
yarn add ${packageName}`
          );
        }
      }
    };
  }
});

// src/adapters/sentry-adapter.ts
var sentry_adapter_exports = {};
__export(sentry_adapter_exports, {
  SentryAdapter: () => SentryAdapter
});
var SentryAdapter;
var init_sentry_adapter = __esm({
  "src/adapters/sentry-adapter.ts"() {
    "use strict";
    init_base_adapter();
    SentryAdapter = class extends BaseAdapter {
      name = "sentry";
      Sentry;
      async loadSDK() {
        if (this.sdkLoaded) return;
        try {
          const sentryModule = await this.dynamicImport("@sentry/browser");
          this.Sentry = sentryModule;
          this.sdkLoaded = true;
        } catch (error) {
          if (typeof window !== "undefined" && window.Sentry) {
            this.Sentry = window.Sentry;
            this.sdkLoaded = true;
          } else {
            throw error;
          }
        }
      }
      async initializeSDK() {
        if (!this.config.dsn) {
          throw new Error("Sentry DSN is required");
        }
        this.Sentry.init({
          dsn: this.config.dsn,
          environment: this.config.environment,
          release: this.config.release,
          debug: this.config.debug,
          beforeSend: this.config.beforeSend,
          // Disable Sentry's own global handlers since we handle them
          integrations: this.config.integrations ? this.config.integrations : (integrations) => integrations.filter(
            (integration) => !["GlobalHandlers", "TryCatch"].includes(integration.name)
          )
        });
      }
      async captureError(error) {
        const sentryError = new Error(error.message);
        if (error.stack) {
          sentryError.stack = error.stack;
        }
        this.Sentry.captureException(sentryError, {
          level: error.level,
          contexts: {
            custom: error.context.custom,
            device: error.context.device
          },
          tags: error.context.tags,
          extra: {
            ...error.context.extra,
            fingerprint: error.fingerprint,
            handled: error.handled,
            source: error.source
          },
          user: error.context.user,
          breadcrumbs: error.breadcrumbs.map((b) => ({
            timestamp: b.timestamp / 1e3,
            // Sentry expects seconds
            message: b.message,
            category: b.category,
            level: b.level,
            data: b.data
          }))
        });
      }
      async setContext(context) {
        if (context.user) {
          this.Sentry.setUser(context.user);
        }
        if (context.tags) {
          Object.entries(context.tags).forEach(([key, value]) => {
            this.Sentry.setTag(key, value);
          });
        }
        if (context.extra) {
          Object.entries(context.extra).forEach(([key, value]) => {
            this.Sentry.setExtra(key, value);
          });
        }
        if (context.custom) {
          this.Sentry.setContext("custom", context.custom);
        }
        if (context.device) {
          this.Sentry.setContext("device", context.device);
        }
      }
      async addBreadcrumb(breadcrumb) {
        this.Sentry.addBreadcrumb({
          timestamp: breadcrumb.timestamp / 1e3,
          message: breadcrumb.message,
          category: breadcrumb.category,
          level: breadcrumb.level,
          data: breadcrumb.data
        });
      }
      async flush() {
        await this.Sentry.flush();
      }
      async close() {
        await this.Sentry.close();
      }
    };
  }
});

// src/adapters/firebase-adapter.ts
var firebase_adapter_exports = {};
__export(firebase_adapter_exports, {
  FirebaseAdapter: () => FirebaseAdapter
});
var FirebaseAdapter;
var init_firebase_adapter = __esm({
  "src/adapters/firebase-adapter.ts"() {
    "use strict";
    init_base_adapter();
    FirebaseAdapter = class extends BaseAdapter {
      name = "firebase";
      crashlytics;
      analytics;
      async loadSDK() {
        if (this.sdkLoaded) return;
        try {
          const { initializeApp, getApps } = await this.dynamicImport("firebase/app");
          const { getCrashlytics } = await this.dynamicImport("firebase/crashlytics");
          const { getAnalytics } = await this.dynamicImport("firebase/analytics");
          let app;
          if (getApps().length === 0) {
            if (!this.config.firebaseConfig) {
              throw new Error("Firebase configuration is required");
            }
            app = initializeApp(this.config.firebaseConfig);
          } else {
            app = getApps()[0];
          }
          this.crashlytics = getCrashlytics(app);
          if (this.config.enableAnalytics !== false) {
            try {
              this.analytics = getAnalytics(app);
            } catch (e) {
              console.warn("Firebase Analytics not available:", e);
            }
          }
          this.sdkLoaded = true;
        } catch (_error) {
          throw new Error(
            `Failed to load Firebase SDK. Please install:
npm install firebase
or include Firebase SDK via CDN`
          );
        }
      }
      async initializeSDK() {
      }
      async captureError(error) {
        const { recordException, log, setCustomKey } = await this.dynamicImport("firebase/crashlytics");
        if (error.context.tags) {
          for (const [key, value] of Object.entries(error.context.tags)) {
            setCustomKey(this.crashlytics, key, value);
          }
        }
        if (error.context.extra) {
          for (const [key, value] of Object.entries(error.context.extra)) {
            setCustomKey(this.crashlytics, key, JSON.stringify(value));
          }
        }
        setCustomKey(this.crashlytics, "error_level", error.level || "error");
        setCustomKey(this.crashlytics, "error_source", error.source || "unknown");
        setCustomKey(this.crashlytics, "error_handled", String(error.handled));
        for (const breadcrumb of error.breadcrumbs) {
          log(this.crashlytics, `[${breadcrumb.category || "general"}] ${breadcrumb.message}`);
        }
        const errorObj = new Error(error.message);
        if (error.stack) {
          errorObj.stack = error.stack;
        }
        errorObj.name = error.type || "Error";
        recordException(this.crashlytics, errorObj);
        if (this.analytics) {
          const { logEvent } = await this.dynamicImport("firebase/analytics");
          logEvent(this.analytics, "exception", {
            description: error.message,
            fatal: error.level === "fatal"
          });
        }
      }
      async setContext(context) {
        var _a2;
        const { setUserId, setCustomKey } = await this.dynamicImport("firebase/crashlytics");
        if ((_a2 = context.user) == null ? void 0 : _a2.id) {
          setUserId(this.crashlytics, context.user.id);
        }
        if (context.user) {
          for (const [key, value] of Object.entries(context.user)) {
            if (key !== "id") {
              setCustomKey(this.crashlytics, `user_${key}`, String(value));
            }
          }
        }
        if (context.device) {
          for (const [key, value] of Object.entries(context.device)) {
            setCustomKey(this.crashlytics, `device_${key}`, String(value));
          }
        }
        if (context.custom) {
          for (const [key, value] of Object.entries(context.custom)) {
            setCustomKey(this.crashlytics, key, JSON.stringify(value));
          }
        }
      }
      async addBreadcrumb(breadcrumb) {
        const { log } = await this.dynamicImport("firebase/crashlytics");
        const level = breadcrumb.level || "info";
        const category = breadcrumb.category || "general";
        log(this.crashlytics, `[${level}][${category}] ${breadcrumb.message}`);
      }
      async flush() {
      }
      async close() {
      }
    };
  }
});

// src/adapters/datadog-adapter.ts
var datadog_adapter_exports = {};
__export(datadog_adapter_exports, {
  DataDogAdapter: () => DataDogAdapter
});
var DataDogAdapter;
var init_datadog_adapter = __esm({
  "src/adapters/datadog-adapter.ts"() {
    "use strict";
    init_base_adapter();
    DataDogAdapter = class extends BaseAdapter {
      name = "datadog";
      datadogRum;
      datadogLogs;
      async loadSDK() {
        if (this.sdkLoaded) return;
        try {
          const ddRum = await this.dynamicImport("@datadog/browser-rum");
          const ddLogs = await this.dynamicImport("@datadog/browser-logs");
          this.datadogRum = ddRum.datadogRum;
          this.datadogLogs = ddLogs.datadogLogs;
          this.sdkLoaded = true;
        } catch (_error) {
          throw new Error(
            `Failed to load DataDog SDK. Please install:
pnpm add @datadog/browser-rum @datadog/browser-logs
or include DataDog SDK via CDN`
          );
        }
      }
      async initializeSDK() {
        if (!this.config.applicationId || !this.config.clientToken) {
          throw new Error("DataDog requires applicationId and clientToken");
        }
        this.datadogRum.init({
          applicationId: this.config.applicationId,
          clientToken: this.config.clientToken,
          site: this.config.site || "datadoghq.com",
          service: this.config.service || "unified-error-handling",
          env: this.config.environment || "production",
          version: this.config.release || "1.0.0",
          sessionSampleRate: this.config.sessionSampleRate ?? 100,
          sessionReplaySampleRate: this.config.sessionReplaySampleRate ?? 0,
          trackUserInteractions: this.config.trackInteractions ?? true,
          trackResources: true,
          trackLongTasks: true,
          defaultPrivacyLevel: this.config.defaultPrivacyLevel || "mask-user-input"
        });
        this.datadogLogs.init({
          clientToken: this.config.clientToken,
          site: this.config.site || "datadoghq.com",
          service: this.config.service || "unified-error-handling",
          env: this.config.environment || "production",
          forwardErrorsToLogs: true,
          sessionSampleRate: 100
        });
        if (this.config.sessionReplaySampleRate && this.config.sessionReplaySampleRate > 0) {
          this.datadogRum.startSessionReplayRecording();
        }
      }
      async captureError(error) {
        const errorObj = new Error(error.message);
        if (error.stack) {
          errorObj.stack = error.stack;
        }
        errorObj.name = error.type || "Error";
        this.datadogRum.addError(errorObj, {
          source: error.source || "custom",
          level: error.level || "error",
          handled: error.handled,
          ...error.context.extra
        });
        this.datadogLogs.logger.error(error.message, {
          error: {
            kind: error.type,
            message: error.message,
            stack: error.stack
          },
          ...error.context.tags,
          ...error.context.extra
        });
      }
      async setContext(context) {
        if (context.user) {
          this.datadogRum.setUser({
            id: context.user.id,
            email: context.user.email,
            name: context.user.username,
            ...context.user
          });
        }
        if (context.custom) {
          for (const [key, value] of Object.entries(context.custom)) {
            this.datadogRum.setGlobalContextProperty(key, value);
          }
        }
        if (context.tags) {
          for (const [key, value] of Object.entries(context.tags)) {
            this.datadogRum.setGlobalContextProperty(key, value);
          }
        }
      }
      async addBreadcrumb(breadcrumb) {
        this.datadogRum.addAction(breadcrumb.message, {
          category: breadcrumb.category || "custom",
          level: breadcrumb.level || "info",
          ...breadcrumb.data
        });
      }
      async flush() {
      }
      async close() {
        if (this.config.sessionReplaySampleRate && this.config.sessionReplaySampleRate > 0) {
          this.datadogRum.stopSessionReplayRecording();
        }
      }
    };
  }
});

// src/adapters/bugsnag-adapter.ts
var bugsnag_adapter_exports = {};
__export(bugsnag_adapter_exports, {
  BugsnagAdapter: () => BugsnagAdapter
});
var BugsnagAdapter;
var init_bugsnag_adapter = __esm({
  "src/adapters/bugsnag-adapter.ts"() {
    "use strict";
    init_base_adapter();
    BugsnagAdapter = class extends BaseAdapter {
      name = "bugsnag";
      bugsnag;
      async loadSDK() {
        if (this.sdkLoaded) return;
        try {
          const BugsnagModule = await this.dynamicImport("@bugsnag/js");
          this.bugsnag = BugsnagModule.default || BugsnagModule;
          this.sdkLoaded = true;
        } catch (_error) {
          throw new Error(
            `Failed to load Bugsnag SDK. Please install:
pnpm add @bugsnag/js
or include Bugsnag SDK via CDN`
          );
        }
      }
      async initializeSDK() {
        if (!this.config.apiKey) {
          throw new Error("Bugsnag requires an apiKey");
        }
        this.bugsnag.start({
          apiKey: this.config.apiKey,
          appVersion: this.config.appVersion || this.config.release,
          appType: this.config.appType || "browser",
          releaseStage: this.config.environment || "production",
          enabledReleaseStages: this.config.enabledReleaseStages || [
            "development",
            "staging",
            "production"
          ],
          autoDetectErrors: this.config.autoDetectErrors ?? true,
          autoTrackSessions: this.config.autoSessionTracking ?? true,
          maxBreadcrumbs: this.config.maxBreadcrumbs || 25,
          enabledBreadcrumbTypes: this.config.enabledBreadcrumbTypes || [
            "error",
            "log",
            "navigation",
            "request",
            "user"
          ],
          redactedKeys: this.config.redactedKeys || ["password", "token", "secret", "apiKey"],
          onError: (event) => {
            if (this.config.context) {
              event.addMetadata("custom", this.config.context);
            }
            if (this.config.tags) {
              event.addMetadata("tags", this.config.tags);
            }
            return true;
          }
        });
      }
      async captureError(error) {
        const errorObj = new Error(error.message);
        if (error.stack) {
          errorObj.stack = error.stack;
        }
        errorObj.name = error.type || "Error";
        this.bugsnag.notify(errorObj, (event) => {
          switch (error.level) {
            case "fatal":
            case "error":
              event.severity = "error";
              break;
            case "warning":
              event.severity = "warning";
              break;
            default:
              event.severity = "info";
          }
          if (error.context.tags) {
            event.addMetadata("tags", error.context.tags);
          }
          if (error.context.extra) {
            event.addMetadata("extra", error.context.extra);
          }
          event.unhandled = !error.handled;
          for (const breadcrumb of error.breadcrumbs) {
            event.addMetadata("breadcrumbs", {
              [breadcrumb.timestamp || Date.now()]: breadcrumb.message
            });
          }
        });
      }
      async setContext(context) {
        if (context.user) {
          this.bugsnag.setUser(context.user.id, context.user.email, context.user.username);
        }
        if (context.custom) {
          this.bugsnag.addMetadata("custom", context.custom);
        }
        if (context.device) {
          this.bugsnag.addMetadata("device", context.device);
        }
        if (context.tags) {
          this.bugsnag.addMetadata("tags", context.tags);
        }
      }
      async addBreadcrumb(breadcrumb) {
        this.bugsnag.leaveBreadcrumb(breadcrumb.message, breadcrumb.data || {}, breadcrumb.category);
      }
      async flush() {
      }
      async close() {
      }
    };
  }
});

// src/adapters/rollbar-adapter.ts
var rollbar_adapter_exports = {};
__export(rollbar_adapter_exports, {
  RollbarAdapter: () => RollbarAdapter
});
var RollbarAdapter;
var init_rollbar_adapter = __esm({
  "src/adapters/rollbar-adapter.ts"() {
    "use strict";
    init_base_adapter();
    RollbarAdapter = class extends BaseAdapter {
      name = "rollbar";
      rollbar;
      async loadSDK() {
        if (this.sdkLoaded) return;
        try {
          const RollbarModule = await this.dynamicImport("rollbar");
          this.rollbar = RollbarModule.default || RollbarModule;
          this.sdkLoaded = true;
        } catch (_error) {
          throw new Error(
            `Failed to load Rollbar SDK. Please install:
pnpm add rollbar
or include Rollbar SDK via CDN`
          );
        }
      }
      async initializeSDK() {
        if (!this.config.accessToken) {
          throw new Error("Rollbar requires an accessToken");
        }
        this.rollbar = new this.rollbar({
          accessToken: this.config.accessToken,
          captureUncaught: this.config.captureUncaught ?? true,
          captureUnhandledRejections: this.config.captureUnhandledRejections ?? true,
          environment: this.config.environment || "production",
          codeVersion: this.config.codeVersion || this.config.release,
          autoInstrument: this.config.autoInstrument ?? true,
          maxItems: this.config.maxItems || 5,
          itemsPerMinute: this.config.itemsPerMinute || 60,
          captureIp: this.config.captureIp ?? "anonymize",
          captureEmail: this.config.captureEmail ?? false,
          captureUsername: this.config.captureUsername ?? false,
          verbose: this.config.verbose ?? false,
          logLevel: this.config.logLevel || "debug",
          payload: {
            ...this.config.payload,
            client: {
              javascript: {
                source_map_enabled: true,
                code_version: this.config.codeVersion || this.config.release
              }
            }
          }
        });
      }
      async captureError(error) {
        const errorObj = new Error(error.message);
        if (error.stack) {
          errorObj.stack = error.stack;
        }
        errorObj.name = error.type || "Error";
        let level;
        switch (error.level) {
          case "fatal":
            level = "critical";
            break;
          case "error":
            level = "error";
            break;
          case "warning":
            level = "warning";
            break;
          case "info":
            level = "info";
            break;
          default:
            level = "debug";
        }
        const custom = {
          source: error.source,
          handled: error.handled,
          ...error.context.extra
        };
        if (error.context.tags) {
          custom.tags = error.context.tags;
        }
        if (error.breadcrumbs.length > 0) {
          custom.breadcrumbs = error.breadcrumbs.map((b) => ({
            message: b.message,
            category: b.category,
            level: b.level,
            timestamp: b.timestamp
          }));
        }
        this.rollbar[level](errorObj, custom);
      }
      async setContext(context) {
        if (context.user) {
          this.rollbar.configure({
            payload: {
              person: {
                id: context.user.id,
                email: context.user.email,
                username: context.user.username
              }
            }
          });
        }
        if (context.custom) {
          this.rollbar.configure({
            payload: {
              custom: context.custom
            }
          });
        }
      }
      async addBreadcrumb(breadcrumb) {
        this.rollbar.info(`[${breadcrumb.category || "breadcrumb"}] ${breadcrumb.message}`, {
          breadcrumb: true,
          ...breadcrumb.data
        });
      }
      async flush() {
        if (this.rollbar && typeof this.rollbar.wait === "function") {
          await new Promise((resolve) => {
            this.rollbar.wait(resolve);
          });
        }
      }
      async close() {
      }
    };
  }
});

// src/adapters/logrocket-adapter.ts
var logrocket_adapter_exports = {};
__export(logrocket_adapter_exports, {
  LogRocketAdapter: () => LogRocketAdapter
});
var LogRocketAdapter;
var init_logrocket_adapter = __esm({
  "src/adapters/logrocket-adapter.ts"() {
    "use strict";
    init_base_adapter();
    LogRocketAdapter = class extends BaseAdapter {
      name = "logrocket";
      logRocket;
      async loadSDK() {
        if (this.sdkLoaded) return;
        try {
          const LogRocketModule = await this.dynamicImport("logrocket");
          this.logRocket = LogRocketModule.default || LogRocketModule;
          this.sdkLoaded = true;
        } catch (_error) {
          throw new Error(
            `Failed to load LogRocket SDK. Please install:
pnpm add logrocket
or include LogRocket SDK via CDN`
          );
        }
      }
      async initializeSDK() {
        if (!this.config.appId) {
          throw new Error("LogRocket requires an appId");
        }
        this.logRocket.init(this.config.appId, {
          release: this.config.release,
          console: {
            isEnabled: this.config.console ?? true
          },
          network: {
            isEnabled: this.config.network ?? true,
            requestSanitizer: this.config.requestSanitizer,
            responseSanitizer: this.config.responseSanitizer
          },
          dom: {
            isEnabled: this.config.dom ?? true,
            inputSanitizer: this.config.inputSanitizer ?? true,
            textSanitizer: this.config.textSanitizer ?? false
          },
          shouldCaptureIP: this.config.shouldCaptureIP ?? false,
          rootHostname: this.config.rootHostname,
          mergeIframes: this.config.mergeIframes ?? false
        });
      }
      async captureError(error) {
        const errorObj = new Error(error.message);
        if (error.stack) {
          errorObj.stack = error.stack;
        }
        errorObj.name = error.type || "Error";
        this.logRocket.captureException(errorObj, {
          tags: error.context.tags || {},
          extra: {
            level: error.level,
            source: error.source,
            handled: error.handled,
            ...error.context.extra
          }
        });
        this.logRocket.track("Error", {
          message: error.message,
          type: error.type,
          level: error.level,
          source: error.source,
          handled: error.handled
        });
      }
      async setContext(context) {
        if (context.user) {
          this.logRocket.identify(context.user.id || "anonymous", {
            email: context.user.email,
            name: context.user.username,
            ...context.user
          });
        }
        if (context.custom) {
          for (const [key, value] of Object.entries(context.custom)) {
            this.logRocket.track(key, value);
          }
        }
      }
      async addBreadcrumb(breadcrumb) {
        this.logRocket.track(breadcrumb.category || "breadcrumb", {
          message: breadcrumb.message,
          level: breadcrumb.level,
          ...breadcrumb.data
        });
      }
      async flush() {
      }
      async close() {
      }
    };
  }
});

// src/adapters/raygun-adapter.ts
var raygun_adapter_exports = {};
__export(raygun_adapter_exports, {
  RaygunAdapter: () => RaygunAdapter
});
var RaygunAdapter;
var init_raygun_adapter = __esm({
  "src/adapters/raygun-adapter.ts"() {
    "use strict";
    init_base_adapter();
    RaygunAdapter = class extends BaseAdapter {
      name = "raygun";
      raygun;
      async loadSDK() {
        if (this.sdkLoaded) return;
        try {
          const RaygunModule = await this.dynamicImport("raygun4js");
          this.raygun = RaygunModule.default || RaygunModule;
          this.sdkLoaded = true;
        } catch (_error) {
          throw new Error(
            `Failed to load Raygun SDK. Please install:
pnpm add raygun4js
or include Raygun SDK via CDN`
          );
        }
      }
      async initializeSDK() {
        if (!this.config.apiKey) {
          throw new Error("Raygun requires an apiKey");
        }
        this.raygun("apiKey", this.config.apiKey);
        this.raygun("options", {
          ignoreAjaxAbort: this.config.ignoreAjaxAbort ?? true,
          ignoreAjaxError: this.config.ignoreAjaxError ?? false,
          debugMode: this.config.debug ?? false,
          wrapAsynchronousCallbacks: true,
          disableAnonymousUserTracking: this.config.disableAnonymousUserTracking ?? false,
          disableErrorTracking: this.config.disableErrorTracking ?? false,
          disablePulse: this.config.disablePulse ?? true,
          pulseMaxVirtualPageDuration: 30 * 60 * 1e3,
          // 30 minutes
          pulseIgnoreUrlCasing: true
        });
        if (this.config.release) {
          this.raygun("setVersion", this.config.release);
        }
        this.raygun("enableCrashReporting", this.config.enableCrashReporting ?? true);
        if (!this.config.disablePulse) {
          this.raygun("enablePulse", true);
        }
        if (this.config.withTags && this.config.withTags.length > 0) {
          this.raygun("withTags", this.config.withTags);
        }
        if (this.config.customData) {
          this.raygun("withCustomData", this.config.customData);
        }
      }
      async captureError(error) {
        const errorObj = new Error(error.message);
        if (error.stack) {
          errorObj.stack = error.stack;
        }
        errorObj.name = error.type || "Error";
        const customData = {
          level: error.level,
          source: error.source,
          handled: error.handled,
          breadcrumbs: error.breadcrumbs.map((b) => ({
            message: b.message,
            category: b.category,
            timestamp: b.timestamp
          })),
          ...error.context.extra
        };
        const tags = [];
        if (error.context.tags) {
          for (const [key, value] of Object.entries(error.context.tags)) {
            tags.push(`${key}:${value}`);
          }
        }
        tags.push(`level:${error.level}`);
        tags.push(`handled:${error.handled}`);
        this.raygun("send", errorObj, customData, tags);
      }
      async setContext(context) {
        if (context.user) {
          this.raygun("setUser", {
            identifier: context.user.id,
            email: context.user.email,
            fullName: context.user.username,
            isAnonymous: !context.user.id
          });
        }
        if (context.custom) {
          this.raygun("withCustomData", context.custom);
        }
        if (context.tags) {
          const tags = Object.entries(context.tags).map(([key, value]) => `${key}:${value}`);
          this.raygun("withTags", tags);
        }
      }
      async addBreadcrumb(breadcrumb) {
        this.raygun("recordBreadcrumb", breadcrumb.message, {
          category: breadcrumb.category,
          level: breadcrumb.level,
          ...breadcrumb.data
        });
      }
      async flush() {
      }
      async close() {
        this.raygun("enableCrashReporting", false);
        this.raygun("enablePulse", false);
      }
    };
  }
});

// src/adapters/appcenter-adapter.ts
var appcenter_adapter_exports = {};
__export(appcenter_adapter_exports, {
  AppCenterAdapter: () => AppCenterAdapter
});
var AppCenterAdapter;
var init_appcenter_adapter = __esm({
  "src/adapters/appcenter-adapter.ts"() {
    "use strict";
    init_base_adapter();
    AppCenterAdapter = class extends BaseAdapter {
      name = "appcenter";
      crashes;
      analytics;
      async loadSDK() {
        if (this.sdkLoaded) return;
        try {
          const AppCenterCrashes = await this.dynamicImport("appcenter-crashes");
          const AppCenterAnalytics = await this.dynamicImport("appcenter-analytics");
          this.crashes = AppCenterCrashes.default || AppCenterCrashes;
          this.analytics = AppCenterAnalytics.default || AppCenterAnalytics;
          this.sdkLoaded = true;
        } catch (_error) {
          throw new Error(
            `Failed to load AppCenter SDK. Please install:
pnpm add appcenter-crashes appcenter-analytics
Note: AppCenter is primarily for React Native/mobile apps.
For web apps, consider using a different adapter.`
          );
        }
      }
      async initializeSDK() {
        if (!this.config.appSecret) {
          throw new Error("AppCenter requires an appSecret");
        }
        if (this.crashes && typeof this.crashes.setEnabled === "function") {
          await this.crashes.setEnabled(true);
        }
        if (this.analytics && typeof this.analytics.setEnabled === "function") {
          await this.analytics.setEnabled(true);
        }
        if (this.config.userId && this.crashes && typeof this.crashes.setUserId === "function") {
          await this.crashes.setUserId(this.config.userId);
        }
      }
      async captureError(error) {
        const errorObj = new Error(error.message);
        if (error.stack) {
          errorObj.stack = error.stack;
        }
        errorObj.name = error.type || "Error";
        const properties = {
          level: error.level || "error",
          source: error.source || "unknown",
          handled: String(error.handled)
        };
        if (error.context.tags) {
          for (const [key, value] of Object.entries(error.context.tags)) {
            properties[key] = String(value);
          }
        }
        if (error.context.extra) {
          for (const [key, value] of Object.entries(error.context.extra)) {
            properties[`extra_${key}`] = typeof value === "string" ? value : JSON.stringify(value);
          }
        }
        if (this.crashes && typeof this.crashes.trackError === "function") {
          await this.crashes.trackError(errorObj, properties);
        }
        if (this.analytics && typeof this.analytics.trackEvent === "function") {
          await this.analytics.trackEvent("Error", {
            message: error.message.substring(0, 256),
            // AppCenter has property length limits
            type: error.type || "Error",
            ...properties
          });
        }
      }
      async setContext(context) {
        var _a2;
        if (((_a2 = context.user) == null ? void 0 : _a2.id) && this.crashes && typeof this.crashes.setUserId === "function") {
          await this.crashes.setUserId(context.user.id);
        }
        if (context.user && this.analytics && typeof this.analytics.trackEvent === "function") {
          await this.analytics.trackEvent("UserIdentified", {
            userId: context.user.id || "anonymous",
            email: context.user.email || "",
            username: context.user.username || ""
          });
        }
      }
      async addBreadcrumb(breadcrumb) {
        if (this.analytics && typeof this.analytics.trackEvent === "function") {
          await this.analytics.trackEvent("Breadcrumb", {
            message: breadcrumb.message.substring(0, 256),
            category: breadcrumb.category || "custom",
            level: breadcrumb.level || "info"
          });
        }
      }
      async flush() {
      }
      async close() {
        if (this.crashes && typeof this.crashes.setEnabled === "function") {
          await this.crashes.setEnabled(false);
        }
        if (this.analytics && typeof this.analytics.setEnabled === "function") {
          await this.analytics.setEnabled(false);
        }
      }
    };
  }
});

// src/adapters/custom-adapter.ts
function createCustomAdapter(config) {
  return new CustomAdapter(config);
}
var CustomAdapter;
var init_custom_adapter = __esm({
  "src/adapters/custom-adapter.ts"() {
    "use strict";
    CustomAdapter = class {
      name = "custom";
      config;
      context = {};
      breadcrumbs = [];
      constructor(config) {
        this.config = config;
      }
      async initialize() {
        if (this.config.initialize) {
          await this.config.initialize();
        }
      }
      async captureError(error) {
        const fullContext = {
          ...this.context,
          ...error.context
        };
        await this.config.send(error, fullContext);
      }
      async captureMessage(message, level) {
        const error = {
          message,
          timestamp: Date.now(),
          context: this.context,
          breadcrumbs: [...this.breadcrumbs],
          level: level || "info",
          handled: true,
          source: "manual"
        };
        await this.captureError(error);
      }
      async setContext(context) {
        this.context = { ...context };
        if (this.config.setContext) {
          await this.config.setContext(context);
        }
      }
      async addBreadcrumb(breadcrumb) {
        this.breadcrumbs.push(breadcrumb);
        if (this.config.addBreadcrumb) {
          await this.config.addBreadcrumb(breadcrumb);
        }
      }
      async flush() {
        if (this.config.flush) {
          await this.config.flush();
        }
      }
      async close() {
        if (this.config.close) {
          await this.config.close();
        }
      }
    };
  }
});

// src/adapters/index.ts
var adapters_exports = {};
__export(adapters_exports, {
  AppCenterAdapter: () => AppCenterAdapter,
  BaseAdapter: () => BaseAdapter,
  BugsnagAdapter: () => BugsnagAdapter,
  CustomAdapter: () => CustomAdapter,
  DataDogAdapter: () => DataDogAdapter,
  FirebaseAdapter: () => FirebaseAdapter,
  LogRocketAdapter: () => LogRocketAdapter,
  RaygunAdapter: () => RaygunAdapter,
  RollbarAdapter: () => RollbarAdapter,
  SentryAdapter: () => SentryAdapter,
  createCustomAdapter: () => createCustomAdapter,
  loadAdapter: () => loadAdapter
});
async function loadAdapter(name) {
  switch (name) {
    case "sentry": {
      const { SentryAdapter: SentryAdapter2 } = await Promise.resolve().then(() => (init_sentry_adapter(), sentry_adapter_exports));
      return new SentryAdapter2();
    }
    case "firebase": {
      const { FirebaseAdapter: FirebaseAdapter2 } = await Promise.resolve().then(() => (init_firebase_adapter(), firebase_adapter_exports));
      return new FirebaseAdapter2();
    }
    case "datadog": {
      const { DataDogAdapter: DataDogAdapter2 } = await Promise.resolve().then(() => (init_datadog_adapter(), datadog_adapter_exports));
      return new DataDogAdapter2();
    }
    case "bugsnag": {
      const { BugsnagAdapter: BugsnagAdapter2 } = await Promise.resolve().then(() => (init_bugsnag_adapter(), bugsnag_adapter_exports));
      return new BugsnagAdapter2();
    }
    case "rollbar": {
      const { RollbarAdapter: RollbarAdapter2 } = await Promise.resolve().then(() => (init_rollbar_adapter(), rollbar_adapter_exports));
      return new RollbarAdapter2();
    }
    case "logrocket": {
      const { LogRocketAdapter: LogRocketAdapter2 } = await Promise.resolve().then(() => (init_logrocket_adapter(), logrocket_adapter_exports));
      return new LogRocketAdapter2();
    }
    case "raygun": {
      const { RaygunAdapter: RaygunAdapter2 } = await Promise.resolve().then(() => (init_raygun_adapter(), raygun_adapter_exports));
      return new RaygunAdapter2();
    }
    case "appcenter": {
      const { AppCenterAdapter: AppCenterAdapter2 } = await Promise.resolve().then(() => (init_appcenter_adapter(), appcenter_adapter_exports));
      return new AppCenterAdapter2();
    }
    default:
      return null;
  }
}
var init_adapters = __esm({
  "src/adapters/index.ts"() {
    "use strict";
    init_base_adapter();
    init_sentry_adapter();
    init_firebase_adapter();
    init_datadog_adapter();
    init_bugsnag_adapter();
    init_rollbar_adapter();
    init_logrocket_adapter();
    init_raygun_adapter();
    init_appcenter_adapter();
    init_custom_adapter();
  }
});

// src/index.ts
var index_exports = {};
__export(index_exports, {
  CustomAdapter: () => CustomAdapter,
  FirebaseAdapter: () => FirebaseAdapter,
  SentryAdapter: () => SentryAdapter,
  addBreadcrumb: () => addBreadcrumb,
  captureError: () => captureError,
  captureMessage: () => captureMessage,
  clearBreadcrumbs: () => clearBreadcrumbs,
  createAdapter: () => createAdapter,
  createCustomAdapter: () => createCustomAdapter,
  errorStore: () => errorStore,
  flush: () => flush,
  initialize: () => initialize,
  registerAdapter: () => registerAdapter,
  removeAdapter: () => removeAdapter,
  reset: () => reset,
  setContext: () => setContext,
  setUser: () => setUser,
  subscribe: () => subscribe,
  useAdapter: () => useAdapter
});
module.exports = __toCommonJS(index_exports);

// src/utils/error-enricher.ts
function enrichError(error) {
  if (typeof window !== "undefined") {
    error.context.device = {
      ...error.context.device,
      userAgent: navigator.userAgent,
      language: navigator.language,
      platform: navigator.platform,
      cookieEnabled: navigator.cookieEnabled,
      onLine: navigator.onLine,
      viewport: {
        width: window.innerWidth,
        height: window.innerHeight
      },
      screen: {
        width: screen.width,
        height: screen.height,
        colorDepth: screen.colorDepth
      }
    };
    error.context.extra = {
      ...error.context.extra,
      url: window.location.href,
      referrer: document.referrer
    };
  }
  if (!error.fingerprint) {
    error.fingerprint = generateFingerprint(error);
  }
  if (error.stack) {
    const parsedStack = parseStackTrace(error.stack);
    error.context.extra = {
      ...error.context.extra,
      parsedStack
    };
  }
  return error;
}
function generateFingerprint(error) {
  const parts = [
    error.type || "Error",
    error.message,
    error.stack ? extractTopStackFrame(error.stack) : ""
  ].filter(Boolean);
  return parts.join("|").replace(/\s+/g, " ").trim();
}
function extractTopStackFrame(stack) {
  const lines = stack.split("\n");
  for (const line of lines) {
    if (line.includes("at ") && !line.includes("Error")) {
      return line.trim();
    }
  }
  return "";
}
function parseStackTrace(stack) {
  const frames = [];
  const lines = stack.split("\n");
  for (const line of lines) {
    if (!line.includes("at ")) continue;
    const functionMatch = line.match(/at\s+([^\s]+)\s+\(/);
    const functionName = functionMatch ? functionMatch[1] : "<anonymous>";
    const fileMatch = line.match(/\((.+):(\d+):(\d+)\)/);
    if (fileMatch) {
      frames.push({
        function: functionName,
        file: fileMatch[1],
        line: parseInt(fileMatch[2], 10),
        column: parseInt(fileMatch[3], 10)
      });
    } else {
      const altMatch = line.match(/at\s+(.+):(\d+):(\d+)/);
      if (altMatch) {
        frames.push({
          file: altMatch[1],
          line: parseInt(altMatch[2], 10),
          column: parseInt(altMatch[3], 10)
        });
      }
    }
  }
  return frames;
}

// src/utils/console-interceptor.ts
var ConsoleInterceptor = class {
  originalConsole = {
    error: console.error,
    warn: console.warn,
    log: console.log,
    info: console.info
  };
  enabled = false;
  enable() {
    if (this.enabled) return;
    console.error = (...args) => {
      this.originalConsole.error.apply(console, args);
      const error = args[0] instanceof Error ? args[0] : new Error(String(args[0]));
      errorStore.captureError(error, {
        extra: {
          source: "console.error",
          consoleArgs: args.slice(1)
        }
      });
      errorStore.addBreadcrumb({
        message: `console.error: ${args.map((arg) => String(arg)).join(" ")}`,
        category: "console",
        level: "error"
      });
    };
    console.warn = (...args) => {
      this.originalConsole.warn.apply(console, args);
      errorStore.addBreadcrumb({
        message: `console.warn: ${args.map((arg) => String(arg)).join(" ")}`,
        category: "console",
        level: "warning"
      });
    };
    console.log = (...args) => {
      this.originalConsole.log.apply(console, args);
      errorStore.addBreadcrumb({
        message: `console.log: ${args.map((arg) => String(arg)).join(" ")}`,
        category: "console",
        level: "info"
      });
    };
    console.info = (...args) => {
      this.originalConsole.info.apply(console, args);
      errorStore.addBreadcrumb({
        message: `console.info: ${args.map((arg) => String(arg)).join(" ")}`,
        category: "console",
        level: "info"
      });
    };
    this.enabled = true;
  }
  disable() {
    if (!this.enabled) return;
    console.error = this.originalConsole.error;
    console.warn = this.originalConsole.warn;
    console.log = this.originalConsole.log;
    console.info = this.originalConsole.info;
    this.enabled = false;
  }
};
var consoleInterceptor = new ConsoleInterceptor();

// src/utils/network-interceptor.ts
var _a, _b;
var NetworkInterceptor = class {
  enabled = false;
  originalFetch = typeof window !== "undefined" ? window.fetch : void 0;
  xhrPrototype = typeof XMLHttpRequest !== "undefined" ? XMLHttpRequest.prototype : void 0;
  originalOpen = (_a = this.xhrPrototype) == null ? void 0 : _a.open;
  originalSend = (_b = this.xhrPrototype) == null ? void 0 : _b.send;
  enable() {
    if (this.enabled || typeof window === "undefined" || !this.originalFetch || !this.xhrPrototype) return;
    window.fetch = async (...args) => {
      const [input, init] = args;
      const url = typeof input === "string" ? input : input instanceof Request ? input.url : input.toString();
      const method = (init == null ? void 0 : init.method) || "GET";
      const startTime = Date.now();
      try {
        const response = await this.originalFetch.apply(window, args);
        const duration = Date.now() - startTime;
        errorStore.addBreadcrumb({
          message: `${method} ${url} (${response.status})`,
          category: "fetch",
          level: response.ok ? "info" : "warning",
          data: {
            method,
            url,
            status: response.status,
            statusText: response.statusText,
            duration
          }
        });
        if (!response.ok && response.status >= 400) {
          const error = new Error(`HTTP ${response.status}: ${response.statusText}`);
          errorStore.captureError(error, {
            extra: {
              source: "fetch",
              url,
              method,
              status: response.status,
              statusText: response.statusText,
              duration
            }
          });
        }
        return response;
      } catch (error) {
        const duration = Date.now() - startTime;
        errorStore.addBreadcrumb({
          message: `${method} ${url} (failed)`,
          category: "fetch",
          level: "error",
          data: {
            method,
            url,
            error: String(error),
            duration
          }
        });
        errorStore.captureError(error, {
          extra: {
            source: "fetch",
            url,
            method,
            duration
          }
        });
        throw error;
      }
    };
    const self = this;
    this.xhrPrototype.open = function(method, url, ...args) {
      this._method = method;
      this._url = url;
      this._startTime = Date.now();
      return self.originalOpen.apply(this, [method, url, ...args]);
    };
    this.xhrPrototype.send = function(...args) {
      const xhr = this;
      xhr.addEventListener("load", function() {
        const duration = Date.now() - (xhr._startTime || 0);
        errorStore.addBreadcrumb({
          message: `${xhr._method} ${xhr._url} (${xhr.status})`,
          category: "xhr",
          level: xhr.status >= 200 && xhr.status < 400 ? "info" : "warning",
          data: {
            method: xhr._method,
            url: xhr._url,
            status: xhr.status,
            statusText: xhr.statusText,
            duration
          }
        });
        if (xhr.status >= 400) {
          const error = new Error(`HTTP ${xhr.status}: ${xhr.statusText}`);
          errorStore.captureError(error, {
            extra: {
              source: "xhr",
              url: xhr._url,
              method: xhr._method,
              status: xhr.status,
              statusText: xhr.statusText,
              duration
            }
          });
        }
      });
      xhr.addEventListener("error", function() {
        const duration = Date.now() - (xhr._startTime || 0);
        errorStore.addBreadcrumb({
          message: `${xhr._method} ${xhr._url} (failed)`,
          category: "xhr",
          level: "error",
          data: {
            method: xhr._method,
            url: xhr._url,
            duration
          }
        });
        const error = new Error(`XHR failed: ${xhr._method} ${xhr._url}`);
        errorStore.captureError(error, {
          extra: {
            source: "xhr",
            url: xhr._url,
            method: xhr._method,
            duration
          }
        });
      });
      return self.originalSend.apply(this, args);
    };
    this.enabled = true;
  }
  disable() {
    if (!this.enabled || typeof window === "undefined" || !this.originalFetch || !this.xhrPrototype) return;
    window.fetch = this.originalFetch;
    if (this.originalOpen) this.xhrPrototype.open = this.originalOpen;
    if (this.originalSend) this.xhrPrototype.send = this.originalSend;
    this.enabled = false;
  }
};
var networkInterceptor = new NetworkInterceptor();

// src/store/error-store.ts
var ErrorStoreImpl = class {
  // State
  context = {};
  breadcrumbs = [];
  adapters = /* @__PURE__ */ new Map();
  activeAdapter = null;
  config = {
    maxBreadcrumbs: 100,
    enableGlobalHandlers: true,
    enableOfflineQueue: true,
    enableConsoleCapture: true,
    enableNetworkCapture: false,
    debug: false
  };
  initialized = false;
  offline = false;
  errorQueue = [];
  // Private properties
  listeners = /* @__PURE__ */ new Set();
  globalHandlersInstalled = false;
  offlineHandler;
  onlineHandler;
  constructor() {
    if (typeof window !== "undefined") {
      this.setupOfflineHandlers();
    }
  }
  // Actions
  initialize(config) {
    if (this.initialized) {
      console.warn("[ErrorStore] Already initialized");
      return;
    }
    this.config = { ...this.config, ...config };
    this.initialized = true;
    if (this.config.enableGlobalHandlers && typeof window !== "undefined") {
      this.installGlobalHandlers();
    }
    if (this.config.enableConsoleCapture) {
      consoleInterceptor.enable();
    }
    if (this.config.enableNetworkCapture) {
      networkInterceptor.enable();
    }
    if (typeof window !== "undefined") {
      this.setContext({
        device: {
          platform: "web",
          userAgent: navigator.userAgent,
          language: navigator.language,
          viewport: {
            width: window.innerWidth,
            height: window.innerHeight
          }
        }
      });
    }
  }
  captureError(error, additionalContext) {
    if (!this.initialized) {
      console.warn("[ErrorStore] Not initialized. Call initialize() first.");
      return;
    }
    let normalizedError = this.normalizeError(error, additionalContext);
    normalizedError = enrichError(normalizedError);
    if (this.config.beforeSend) {
      const processed = this.config.beforeSend(normalizedError);
      if (!processed) return;
    }
    if (this.offline && this.config.enableOfflineQueue) {
      this.errorQueue.push(normalizedError);
      return;
    }
    this.sendToAdapter(normalizedError);
    this.listeners.forEach((listener) => listener(normalizedError));
  }
  captureMessage(message, level = "info") {
    const error = new Error(message);
    error.name = "CapturedMessage";
    this.captureError(error, { extra: { level } });
  }
  setUser(user) {
    var _a2;
    if (user === null) {
      delete this.context.user;
    } else {
      this.context.user = { ...user };
    }
    if (this.activeAdapter) {
      const adapter = this.adapters.get(this.activeAdapter);
      (_a2 = adapter == null ? void 0 : adapter.setContext) == null ? void 0 : _a2.call(adapter, this.context);
    }
  }
  setContext(context) {
    var _a2;
    this.context = {
      ...this.context,
      ...context,
      // Deep merge for nested objects
      user: context.user ? { ...this.context.user, ...context.user } : this.context.user,
      device: context.device ? { ...this.context.device, ...context.device } : this.context.device,
      custom: context.custom ? { ...this.context.custom, ...context.custom } : this.context.custom,
      tags: context.tags ? { ...this.context.tags, ...context.tags } : this.context.tags,
      extra: context.extra ? { ...this.context.extra, ...context.extra } : this.context.extra
    };
    if (this.activeAdapter) {
      const adapter = this.adapters.get(this.activeAdapter);
      (_a2 = adapter == null ? void 0 : adapter.setContext) == null ? void 0 : _a2.call(adapter, this.context);
    }
  }
  addBreadcrumb(breadcrumb) {
    var _a2;
    const fullBreadcrumb = {
      ...breadcrumb,
      timestamp: Date.now()
    };
    this.breadcrumbs.push(fullBreadcrumb);
    if (this.config.maxBreadcrumbs && this.breadcrumbs.length > this.config.maxBreadcrumbs) {
      this.breadcrumbs = this.breadcrumbs.slice(-this.config.maxBreadcrumbs);
    }
    if (this.activeAdapter) {
      const adapter = this.adapters.get(this.activeAdapter);
      (_a2 = adapter == null ? void 0 : adapter.addBreadcrumb) == null ? void 0 : _a2.call(adapter, fullBreadcrumb);
    }
  }
  clearBreadcrumbs() {
    this.breadcrumbs = [];
  }
  async useAdapter(name, config) {
    let adapter = this.adapters.get(name);
    if (!adapter) {
      adapter = await this.loadBuiltInAdapter(name) || void 0;
      if (!adapter) {
        throw new Error(`Adapter '${name}' not found. You may need to register a custom adapter.`);
      }
    }
    await adapter.initialize(config);
    this.adapters.set(name, adapter);
    this.activeAdapter = name;
    if (adapter.setContext) {
      await adapter.setContext(this.context);
    }
    if (adapter.addBreadcrumb) {
      for (const breadcrumb of this.breadcrumbs) {
        await adapter.addBreadcrumb(breadcrumb);
      }
    }
    if (this.errorQueue.length > 0) {
      await this.processOfflineQueue();
    }
  }
  removeAdapter(name) {
    var _a2;
    const adapter = this.adapters.get(name);
    if (adapter) {
      (_a2 = adapter.close) == null ? void 0 : _a2.call(adapter);
      this.adapters.delete(name);
      if (this.activeAdapter === name) {
        this.activeAdapter = null;
      }
    }
  }
  async flush() {
    var _a2;
    if (this.activeAdapter) {
      const adapter = this.adapters.get(this.activeAdapter);
      await ((_a2 = adapter == null ? void 0 : adapter.flush) == null ? void 0 : _a2.call(adapter));
    }
  }
  reset() {
    this.adapters.forEach((adapter) => {
      var _a2;
      return (_a2 = adapter.close) == null ? void 0 : _a2.call(adapter);
    });
    this.context = {};
    this.breadcrumbs = [];
    this.adapters.clear();
    this.activeAdapter = null;
    this.errorQueue = [];
    this.initialized = false;
    if (this.globalHandlersInstalled) {
      this.removeGlobalHandlers();
    }
    consoleInterceptor.disable();
    networkInterceptor.disable();
  }
  // Public methods for advanced usage
  subscribe(listener) {
    this.listeners.add(listener);
    return () => this.listeners.delete(listener);
  }
  registerAdapter(name, adapter) {
    this.adapters.set(name, adapter);
  }
  // Private methods
  normalizeError(error, additionalContext) {
    const errorObj = typeof error === "string" ? new Error(error) : error;
    return {
      message: errorObj.message || "Unknown error",
      stack: errorObj.stack,
      type: errorObj.name || "Error",
      timestamp: Date.now(),
      context: {
        ...this.context,
        ...additionalContext
      },
      breadcrumbs: [...this.breadcrumbs],
      level: "error",
      handled: true,
      source: "manual"
    };
  }
  async sendToAdapter(error) {
    if (!this.activeAdapter) {
      if (this.config.debug) {
        console.error("[ErrorStore] No active adapter. Error:", error);
      }
      return;
    }
    const adapter = this.adapters.get(this.activeAdapter);
    if (adapter) {
      try {
        await adapter.captureError(error);
      } catch (err) {
        console.error(`[ErrorStore] Failed to send error to adapter '${this.activeAdapter}':`, err);
      }
    }
  }
  installGlobalHandlers() {
    if (this.globalHandlersInstalled) return;
    window.addEventListener("error", (event) => {
      this.captureError(event.error || new Error(event.message), {
        extra: {
          source: "global",
          filename: event.filename,
          lineno: event.lineno,
          colno: event.colno
        }
      });
    });
    window.addEventListener("unhandledrejection", (event) => {
      const error = event.reason instanceof Error ? event.reason : new Error(String(event.reason));
      this.captureError(error, {
        extra: {
          source: "unhandledRejection",
          promise: event.promise
        }
      });
    });
    this.globalHandlersInstalled = true;
  }
  removeGlobalHandlers() {
    this.globalHandlersInstalled = false;
  }
  setupOfflineHandlers() {
    this.offline = !navigator.onLine;
    this.offlineHandler = () => {
      this.offline = true;
      this.addBreadcrumb({
        message: "Device went offline",
        category: "network",
        level: "warning"
      });
    };
    this.onlineHandler = () => {
      this.offline = false;
      this.addBreadcrumb({
        message: "Device came online",
        category: "network",
        level: "info"
      });
      if (this.errorQueue.length > 0) {
        this.processOfflineQueue();
      }
    };
    window.addEventListener("offline", this.offlineHandler);
    window.addEventListener("online", this.onlineHandler);
  }
  async processOfflineQueue() {
    const errors = [...this.errorQueue];
    this.errorQueue = [];
    for (const error of errors) {
      await this.sendToAdapter(error);
    }
  }
  async loadBuiltInAdapter(name) {
    switch (name) {
      case "console":
        return {
          name: "console",
          async initialize() {
            var _a2;
            const originalLog = ((_a2 = consoleInterceptor["originalConsole"]) == null ? void 0 : _a2.log) || console.log;
            originalLog("[ConsoleAdapter] Initialized");
          },
          async captureError(error) {
            var _a2;
            const originalError = ((_a2 = consoleInterceptor["originalConsole"]) == null ? void 0 : _a2.error) || console.error;
            originalError("[Error]", error);
          },
          async captureMessage(message, level) {
            var _a2;
            const originalLog = ((_a2 = consoleInterceptor["originalConsole"]) == null ? void 0 : _a2.log) || console.log;
            originalLog(`[${level || "info"}]`, message);
          }
        };
      case "sentry":
      case "firebase":
      case "datadog":
      case "bugsnag":
      case "rollbar":
      case "logrocket":
      case "raygun":
      case "appcenter": {
        const { loadAdapter: loadAdapter2 } = await Promise.resolve().then(() => (init_adapters(), adapters_exports));
        return await loadAdapter2(name);
      }
      default:
        return null;
    }
  }
};
var errorStore = new ErrorStoreImpl();
var initialize = errorStore.initialize.bind(errorStore);
var captureError = errorStore.captureError.bind(errorStore);
var captureMessage = errorStore.captureMessage.bind(errorStore);
var setUser = errorStore.setUser.bind(errorStore);
var setContext = errorStore.setContext.bind(errorStore);
var addBreadcrumb = errorStore.addBreadcrumb.bind(errorStore);
var clearBreadcrumbs = errorStore.clearBreadcrumbs.bind(errorStore);
var useAdapter = errorStore.useAdapter.bind(errorStore);
var removeAdapter = errorStore.removeAdapter.bind(errorStore);
var flush = errorStore.flush.bind(errorStore);
var reset = errorStore.reset.bind(errorStore);
var subscribe = errorStore.subscribe.bind(errorStore);
var registerAdapter = errorStore.registerAdapter.bind(errorStore);

// src/index.ts
init_custom_adapter();
init_sentry_adapter();
init_firebase_adapter();
init_custom_adapter();
init_custom_adapter();
function createAdapter(name, config) {
  const adapter = createCustomAdapter(config);
  errorStore.registerAdapter(name, adapter);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  CustomAdapter,
  FirebaseAdapter,
  SentryAdapter,
  addBreadcrumb,
  captureError,
  captureMessage,
  clearBreadcrumbs,
  createAdapter,
  createCustomAdapter,
  errorStore,
  flush,
  initialize,
  registerAdapter,
  removeAdapter,
  reset,
  setContext,
  setUser,
  subscribe,
  useAdapter
});