From 8df48ecf0758eb50112f648737ed79d7098c9e99 Mon Sep 17 00:00:00 2001 From: Reversean Date: Tue, 3 Mar 2026 19:58:57 +0300 Subject: [PATCH] refactor(core): BreadcrumbStore abstraction and browser implementation added --- .../core/src/breadcrumbs/breadcrumb-store.ts | 27 ++++++ packages/core/src/index.ts | 1 + packages/javascript/src/addons/breadcrumbs.ts | 51 +++++----- packages/javascript/src/catcher.ts | 23 ++--- .../javascript/src/types/breadcrumbs-api.ts | 11 --- packages/javascript/src/types/index.ts | 10 +- packages/javascript/tests/breadcrumbs.test.ts | 92 +++++++++---------- .../javascript/tests/catcher.addons.test.ts | 4 +- .../tests/catcher.breadcrumbs.test.ts | 4 +- .../javascript/tests/catcher.context.test.ts | 4 +- .../tests/catcher.global-handlers.test.ts | 4 +- packages/javascript/tests/catcher.test.ts | 8 +- .../tests/catcher.transport.test.ts | 4 +- .../javascript/tests/catcher.user.test.ts | 4 +- 14 files changed, 134 insertions(+), 113 deletions(-) create mode 100644 packages/core/src/breadcrumbs/breadcrumb-store.ts delete mode 100644 packages/javascript/src/types/breadcrumbs-api.ts diff --git a/packages/core/src/breadcrumbs/breadcrumb-store.ts b/packages/core/src/breadcrumbs/breadcrumb-store.ts new file mode 100644 index 00000000..54e2eeec --- /dev/null +++ b/packages/core/src/breadcrumbs/breadcrumb-store.ts @@ -0,0 +1,27 @@ +import type { Breadcrumb } from '@hawk.so/types'; + +/** + * Hint passed to beforeBreadcrumb callback. + */ +export interface BreadcrumbHint { + [key: string]: unknown; +} + +/** + * Breadcrumb input type - breadcrumb data with optional timestamp. + */ +export type BreadcrumbInput = Omit & { timestamp?: number }; + +/** + * Contract for breadcrumb storage. Also serves as public breadcrumbs API. + */ +export interface BreadcrumbStore { + add(breadcrumb: BreadcrumbInput, hint?: BreadcrumbHint): void; + get(): Breadcrumb[]; + clear(): void; +} + +/** + * @deprecated Use {@link BreadcrumbStore} instead. + */ +export type BreadcrumbsAPI = BreadcrumbStore; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index fb1d91f7..30fe1af4 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -12,3 +12,4 @@ export { StackParser } from './modules/stack-parser'; export { buildElementSelector } from './utils/selector'; export { EventRejectedError } from './errors'; export { isErrorProcessed, markErrorAsProcessed } from './utils/event'; +export type { BreadcrumbStore, BreadcrumbsAPI, BreadcrumbHint, BreadcrumbInput } from './breadcrumbs/breadcrumb-store'; diff --git a/packages/javascript/src/addons/breadcrumbs.ts b/packages/javascript/src/addons/breadcrumbs.ts index c953e790..c243512e 100644 --- a/packages/javascript/src/addons/breadcrumbs.ts +++ b/packages/javascript/src/addons/breadcrumbs.ts @@ -2,6 +2,7 @@ * @file Breadcrumbs module - captures chronological trail of events before an error */ import type { Breadcrumb, BreadcrumbLevel, BreadcrumbType, Json, JsonNode } from '@hawk.so/types'; +import type { BreadcrumbHint, BreadcrumbInput, BreadcrumbStore } from '@hawk.so/core'; import { buildElementSelector, isValidBreadcrumb, log, Sanitizer } from '@hawk.so/core'; /** @@ -10,9 +11,10 @@ import { buildElementSelector, isValidBreadcrumb, log, Sanitizer } from '@hawk.s const DEFAULT_MAX_BREADCRUMBS = 15; /** - * Hint object passed to beforeBreadcrumb callback + * Hint object passed to beforeBreadcrumb callback. + * Extends generic {@link BreadcrumbHint} with browser-specific data. */ -export interface BreadcrumbHint { +export interface BrowserBreadcrumbHint extends BreadcrumbHint { /** * Original event that triggered the breadcrumb (if any) */ @@ -51,7 +53,7 @@ export interface BreadcrumbsOptions { * - Return `false` — the breadcrumb will be discarded. * - Any other value is invalid — the original breadcrumb is stored as-is (a warning is logged). */ - beforeBreadcrumb?: (breadcrumb: Breadcrumb, hint?: BreadcrumbHint) => Breadcrumb | false | void; + beforeBreadcrumb?: (breadcrumb: Breadcrumb, hint?: BrowserBreadcrumbHint) => Breadcrumb | false | void; /** * Enable automatic fetch/XHR breadcrumbs @@ -75,12 +77,6 @@ export interface BreadcrumbsOptions { trackClicks?: boolean; } -/** - * Breadcrumb input type - breadcrumb data with optional timestamp - * (timestamp will be auto-generated if not provided) - */ -export type BreadcrumbInput = Omit & { timestamp?: Breadcrumb['timestamp'] }; - /** * Internal breadcrumbs options - all fields except 'beforeBreadcrumb' are required * (they have default values and are always set during init) @@ -90,17 +86,18 @@ interface InternalBreadcrumbsOptions { trackFetch: boolean; trackNavigation: boolean; trackClicks: boolean; - beforeBreadcrumb?: (breadcrumb: Breadcrumb, hint?: BreadcrumbHint) => Breadcrumb | false | void; + beforeBreadcrumb?: (breadcrumb: Breadcrumb, hint?: BrowserBreadcrumbHint) => Breadcrumb | false | void; } /** - * BreadcrumbManager - singleton that manages breadcrumb collection and storage + * Browser implementation of BreadcrumbStore. + * Singleton that manages breadcrumb collection and storage. */ -export class BreadcrumbManager { +export class BrowserBreadcrumbStore implements BreadcrumbStore { /** * Singleton instance */ - private static instance: BreadcrumbManager | null = null; + private static instance: BrowserBreadcrumbStore | null = null; /** * Breadcrumbs buffer (FIFO) @@ -167,10 +164,10 @@ export class BreadcrumbManager { /** * Get singleton instance */ - public static getInstance(): BreadcrumbManager { - BreadcrumbManager.instance ??= new BreadcrumbManager(); + public static getInstance(): BrowserBreadcrumbStore { + BrowserBreadcrumbStore.instance ??= new BrowserBreadcrumbStore(); - return BreadcrumbManager.instance; + return BrowserBreadcrumbStore.instance; } /** @@ -180,7 +177,7 @@ export class BreadcrumbManager { */ public init(options: BreadcrumbsOptions = {}): void { if (this.isInitialized) { - log('[BreadcrumbManager] init has already been called; breadcrumb configuration is global and subsequent init options are ignored.', 'warn'); + log('[BrowserBreadcrumbStore] init has already been called; breadcrumb configuration is global and subsequent init options are ignored.', 'warn'); return; } @@ -219,7 +216,7 @@ export class BreadcrumbManager { * @param hint - Optional hint object with original event data (Event, Response, XMLHttpRequest, etc.) * Used by beforeBreadcrumb callback to access original event context */ - public addBreadcrumb(breadcrumb: BreadcrumbInput, hint?: BreadcrumbHint): void { + public add(breadcrumb: BreadcrumbInput, hint?: BrowserBreadcrumbHint): void { /** * Ensure timestamp */ @@ -293,14 +290,14 @@ export class BreadcrumbManager { /** * Get current breadcrumbs snapshot (oldest to newest) */ - public getBreadcrumbs(): Breadcrumb[] { + public get(): Breadcrumb[] { return [ ...this.breadcrumbs ]; } /** * Clear all breadcrumbs */ - public clearBreadcrumbs(): void { + public clear(): void { this.breadcrumbs.length = 0; } @@ -358,9 +355,9 @@ export class BreadcrumbManager { this.popstateHandler = null; } - this.clearBreadcrumbs(); + this.clear(); this.isInitialized = false; - BreadcrumbManager.instance = null; + BrowserBreadcrumbStore.instance = null; } @@ -399,7 +396,7 @@ export class BreadcrumbManager { const duration = Date.now() - startTime; - manager.addBreadcrumb({ + manager.add({ type: 'request', category: 'fetch', message: `${response.status} ${method} ${url}`, @@ -419,7 +416,7 @@ export class BreadcrumbManager { } catch (error) { const duration = Date.now() - startTime; - manager.addBreadcrumb({ + manager.add({ type: 'request', category: 'fetch', message: `[FAIL] ${method} ${url}`, @@ -483,7 +480,7 @@ export class BreadcrumbManager { const url = this.hawkUrl || ''; const status = this.status; - manager.addBreadcrumb({ + manager.add({ type: 'request', category: 'xhr', message: `${status} ${method} ${url}`, @@ -529,7 +526,7 @@ export class BreadcrumbManager { lastUrl = to; - manager.addBreadcrumb({ + manager.add({ type: 'navigation', category: 'navigation', message: `Navigated to ${to}`, @@ -599,7 +596,7 @@ export class BreadcrumbManager { */ const text = (target.textContent || target.innerText || '').trim().substring(0, 50); - manager.addBreadcrumb({ + manager.add({ type: 'ui', category: 'ui.click', message: `Click on ${selector}`, diff --git a/packages/javascript/src/catcher.ts b/packages/javascript/src/catcher.ts index 08b0e889..e75c4108 100644 --- a/packages/javascript/src/catcher.ts +++ b/packages/javascript/src/catcher.ts @@ -1,6 +1,6 @@ import './modules/element-sanitizer'; import Socket from './modules/socket'; -import type { BreadcrumbsAPI, CatcherMessage, HawkInitialSettings, HawkJavaScriptEvent, Transport } from './types'; +import type { CatcherMessage, HawkInitialSettings, HawkJavaScriptEvent, Transport } from './types'; import { VueIntegration } from './integrations/vue'; import type { AffectedUser, @@ -13,7 +13,8 @@ import type { } from '@hawk.so/types'; import type { JavaScriptCatcherIntegrations } from '@/types'; import { ConsoleCatcher } from './addons/consoleCatcher'; -import { BreadcrumbManager } from './addons/breadcrumbs'; +import { BrowserBreadcrumbStore } from './addons/breadcrumbs'; +import type { BreadcrumbStore } from '@hawk.so/core'; import { EventRejectedError, HawkUserManager, @@ -123,7 +124,7 @@ export default class Catcher { /** * Breadcrumb manager instance */ - private readonly breadcrumbManager: BreadcrumbManager | null; + private readonly breadcrumbStore: BrowserBreadcrumbStore | null; /** * Manages currently authenticated user identity. @@ -195,10 +196,10 @@ export default class Catcher { * Initialize breadcrumbs */ if (settings.breadcrumbs !== false) { - this.breadcrumbManager = BreadcrumbManager.getInstance(); - this.breadcrumbManager.init(settings.breadcrumbs ?? {}); + this.breadcrumbStore = BrowserBreadcrumbStore.getInstance(); + this.breadcrumbStore.init(settings.breadcrumbs ?? {}); } else { - this.breadcrumbManager = null; + this.breadcrumbStore = null; } /** @@ -297,11 +298,11 @@ export default class Catcher { * data: { userId: '123' } * }); */ - public get breadcrumbs(): BreadcrumbsAPI { + public get breadcrumbs(): BreadcrumbStore { return { - add: (breadcrumb, hint) => this.breadcrumbManager?.addBreadcrumb(breadcrumb, hint), - get: () => this.breadcrumbManager?.getBreadcrumbs() ?? [], - clear: () => this.breadcrumbManager?.clearBreadcrumbs(), + add: (breadcrumb, hint) => this.breadcrumbStore?.add(breadcrumb, hint), + get: () => this.breadcrumbStore?.get() ?? [], + clear: () => this.breadcrumbStore?.clear(), }; } @@ -578,7 +579,7 @@ export default class Catcher { * Get breadcrumbs for event payload */ private getBreadcrumbsForEvent(): HawkJavaScriptEvent['breadcrumbs'] { - const breadcrumbs = this.breadcrumbManager?.getBreadcrumbs(); + const breadcrumbs = this.breadcrumbStore?.get(); return breadcrumbs && breadcrumbs.length > 0 ? breadcrumbs : undefined; } diff --git a/packages/javascript/src/types/breadcrumbs-api.ts b/packages/javascript/src/types/breadcrumbs-api.ts deleted file mode 100644 index 777dcdf3..00000000 --- a/packages/javascript/src/types/breadcrumbs-api.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { Breadcrumb } from '@hawk.so/types'; -import type { BreadcrumbInput, BreadcrumbHint } from '../addons/breadcrumbs'; - -/** - * Breadcrumbs API interface - */ -export interface BreadcrumbsAPI { - add: (breadcrumb: BreadcrumbInput, hint?: BreadcrumbHint) => void; - get: () => Breadcrumb[]; - clear: () => void; -} diff --git a/packages/javascript/src/types/index.ts b/packages/javascript/src/types/index.ts index f2829160..5cf529ad 100644 --- a/packages/javascript/src/types/index.ts +++ b/packages/javascript/src/types/index.ts @@ -1,9 +1,14 @@ import type { CatcherMessage } from './catcher-message'; import type { HawkInitialSettings } from './hawk-initial-settings'; import type { Transport } from '@hawk.so/core'; +import type { BreadcrumbsAPI, BreadcrumbStore } from '@hawk.so/core'; import type { HawkJavaScriptEvent } from './event'; -import type { VueIntegrationData, NuxtIntegrationData, NuxtIntegrationAddons, JavaScriptCatcherIntegrations } from './integrations'; -import type { BreadcrumbsAPI } from './breadcrumbs-api'; +import type { + JavaScriptCatcherIntegrations, + NuxtIntegrationAddons, + NuxtIntegrationData, + VueIntegrationData +} from './integrations'; export type { CatcherMessage, @@ -14,5 +19,6 @@ export type { NuxtIntegrationData, NuxtIntegrationAddons, JavaScriptCatcherIntegrations, + BreadcrumbStore, BreadcrumbsAPI }; diff --git a/packages/javascript/tests/breadcrumbs.test.ts b/packages/javascript/tests/breadcrumbs.test.ts index 7afec05c..b73888c6 100644 --- a/packages/javascript/tests/breadcrumbs.test.ts +++ b/packages/javascript/tests/breadcrumbs.test.ts @@ -1,14 +1,14 @@ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; -import { BreadcrumbManager } from '../src/addons/breadcrumbs'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { BrowserBreadcrumbStore } from '../src/addons/breadcrumbs'; import type { Breadcrumb } from '@hawk.so/types'; import * as core from '@hawk.so/core'; function resetManager(): void { // eslint-disable-next-line @typescript-eslint/no-explicit-any - (BreadcrumbManager as any).instance = null; + (BrowserBreadcrumbStore as any).instance = null; } -describe('BreadcrumbManager', () => { +describe('BrowserBreadcrumbStore', () => { let logSpy: ReturnType; beforeEach(() => { @@ -21,19 +21,19 @@ describe('BreadcrumbManager', () => { }); it('should return empty array when no breadcrumbs added', () => { - const m = BreadcrumbManager.getInstance(); + const m = BrowserBreadcrumbStore.getInstance(); m.init(); - expect(m.getBreadcrumbs()).toEqual([]); + expect(m.get()).toEqual([]); }); it('should store breadcrumb with auto-generated timestamp', () => { - const m = BreadcrumbManager.getInstance(); + const m = BrowserBreadcrumbStore.getInstance(); m.init(); - m.addBreadcrumb({ type: 'default', message: 'test', level: 'info' }); + m.add({ type: 'default', message: 'test', level: 'info' }); - const crumbs = m.getBreadcrumbs(); + const crumbs = m.get(); expect(crumbs).toHaveLength(1); expect(crumbs[0].message).toBe('test'); @@ -41,24 +41,24 @@ describe('BreadcrumbManager', () => { }); it('should keep explicit timestamp as-is', () => { - const m = BreadcrumbManager.getInstance(); + const m = BrowserBreadcrumbStore.getInstance(); m.init(); - m.addBreadcrumb({ type: 'default', message: 'test', level: 'info', timestamp: 12345 }); + m.add({ type: 'default', message: 'test', level: 'info', timestamp: 12345 }); - expect(m.getBreadcrumbs()[0].timestamp).toBe(12345); + expect(m.get()[0].timestamp).toBe(12345); }); it('should drop oldest breadcrumbs when buffer overflows (FIFO)', () => { - const m = BreadcrumbManager.getInstance(); + const m = BrowserBreadcrumbStore.getInstance(); m.init({ maxBreadcrumbs: 3 }); for (let i = 0; i < 5; i++) { - m.addBreadcrumb({ type: 'default', message: `msg-${i}`, level: 'info' }); + m.add({ type: 'default', message: `msg-${i}`, level: 'info' }); } - const crumbs = m.getBreadcrumbs(); + const crumbs = m.get(); expect(crumbs).toHaveLength(3); expect(crumbs[0].message).toBe('msg-2'); @@ -66,55 +66,55 @@ describe('BreadcrumbManager', () => { }); it('should store max 15 breadcrumbs by default', () => { - const m = BreadcrumbManager.getInstance(); + const m = BrowserBreadcrumbStore.getInstance(); m.init(); for (let i = 0; i < 20; i++) { - m.addBreadcrumb({ type: 'default', message: `msg-${i}`, level: 'info' }); + m.add({ type: 'default', message: `msg-${i}`, level: 'info' }); } - expect(m.getBreadcrumbs()).toHaveLength(15); + expect(m.get()).toHaveLength(15); }); it('should empty buffer on clear', () => { - const m = BreadcrumbManager.getInstance(); + const m = BrowserBreadcrumbStore.getInstance(); m.init(); - m.addBreadcrumb({ type: 'default', message: 'test', level: 'info' }); - m.clearBreadcrumbs(); + m.add({ type: 'default', message: 'test', level: 'info' }); + m.clear(); - expect(m.getBreadcrumbs()).toEqual([]); + expect(m.get()).toEqual([]); }); it('should return a copy, not the internal array', () => { - const m = BreadcrumbManager.getInstance(); + const m = BrowserBreadcrumbStore.getInstance(); m.init(); - m.addBreadcrumb({ type: 'default', message: 'test', level: 'info' }); + m.add({ type: 'default', message: 'test', level: 'info' }); - const first = m.getBreadcrumbs(); - const second = m.getBreadcrumbs(); + const first = m.get(); + const second = m.get(); expect(first).not.toBe(second); expect(first).toEqual(second); first.push({ type: 'default', message: 'injected', level: 'info', timestamp: 0 } as Breadcrumb); - expect(m.getBreadcrumbs()).toHaveLength(1); + expect(m.get()).toHaveLength(1); }); it('should ignore second init call', () => { - const m = BreadcrumbManager.getInstance(); + const m = BrowserBreadcrumbStore.getInstance(); m.init({ maxBreadcrumbs: 5 }); m.init({ maxBreadcrumbs: 100 }); for (let i = 0; i < 10; i++) { - m.addBreadcrumb({ type: 'default', message: `msg-${i}`, level: 'info' }); + m.add({ type: 'default', message: `msg-${i}`, level: 'info' }); } - expect(m.getBreadcrumbs()).toHaveLength(5); + expect(m.get()).toHaveLength(5); }); }); @@ -132,7 +132,7 @@ describe('beforeBreadcrumb', () => { it('should store modified breadcrumb when hook returns changed object', () => { // Arrange - const m = BreadcrumbManager.getInstance(); + const m = BrowserBreadcrumbStore.getInstance(); m.init({ beforeBreadcrumb(bc) { @@ -143,25 +143,25 @@ describe('beforeBreadcrumb', () => { }); // Act - m.addBreadcrumb({ type: 'default', message: 'original', level: 'info' }); + m.add({ type: 'default', message: 'original', level: 'info' }); // Assert - expect(m.getBreadcrumbs()[0].message).toBe('MODIFIED'); + expect(m.get()[0].message).toBe('MODIFIED'); }); it('should not store breadcrumb when hook returns false', () => { // Arrange - const m = BreadcrumbManager.getInstance(); + const m = BrowserBreadcrumbStore.getInstance(); m.init({ beforeBreadcrumb: () => false, }); // Act - m.addBreadcrumb({ type: 'default', message: 'drop', level: 'info' }); + m.add({ type: 'default', message: 'drop', level: 'info' }); // Assert - expect(m.getBreadcrumbs()).toHaveLength(0); + expect(m.get()).toHaveLength(0); }); it.each([ @@ -172,7 +172,7 @@ describe('beforeBreadcrumb', () => { { label: 'true', value: true }, ])('should store original breadcrumb and warn when hook returns $label', ({ value }) => { // Arrange - const m = BreadcrumbManager.getInstance(); + const m = BrowserBreadcrumbStore.getInstance(); m.init({ // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -180,10 +180,10 @@ describe('beforeBreadcrumb', () => { }); // Act - m.addBreadcrumb({ type: 'default', message: 'original', level: 'info' }); + m.add({ type: 'default', message: 'original', level: 'info' }); // Assert - expect(m.getBreadcrumbs()[0].message).toBe('original'); + expect(m.get()[0].message).toBe('original'); expect(logSpy).toHaveBeenCalledWith( expect.stringContaining('Invalid beforeBreadcrumb value'), 'warn' @@ -192,7 +192,7 @@ describe('beforeBreadcrumb', () => { it('should store original breadcrumb and warn when hook deletes required field (message)', () => { // Arrange - const m = BreadcrumbManager.getInstance(); + const m = BrowserBreadcrumbStore.getInstance(); m.init({ beforeBreadcrumb(bc) { @@ -204,15 +204,15 @@ describe('beforeBreadcrumb', () => { }); // Act - m.addBreadcrumb({ type: 'default', message: 'keep-me', level: 'info' }); + m.add({ type: 'default', message: 'keep-me', level: 'info' }); // Assert — fallback to original, message preserved - expect(m.getBreadcrumbs()[0].message).toBe('keep-me'); + expect(m.get()[0].message).toBe('keep-me'); }); it('should filter breadcrumbs by category using hook', () => { // Arrange - const m = BreadcrumbManager.getInstance(); + const m = BrowserBreadcrumbStore.getInstance(); m.init({ beforeBreadcrumb(bc) { @@ -221,11 +221,11 @@ describe('beforeBreadcrumb', () => { }); // Act - m.addBreadcrumb({ type: 'default', message: 'public', level: 'info', category: 'public' }); - m.addBreadcrumb({ type: 'default', message: 'secret', level: 'info', category: 'secret' }); + m.add({ type: 'default', message: 'public', level: 'info', category: 'public' }); + m.add({ type: 'default', message: 'secret', level: 'info', category: 'secret' }); // Assert - const crumbs = m.getBreadcrumbs(); + const crumbs = m.get(); expect(crumbs).toHaveLength(1); expect(crumbs[0].message).toBe('public'); diff --git a/packages/javascript/tests/catcher.addons.test.ts b/packages/javascript/tests/catcher.addons.test.ts index ff8c5689..d44dea01 100644 --- a/packages/javascript/tests/catcher.addons.test.ts +++ b/packages/javascript/tests/catcher.addons.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { BreadcrumbManager } from '../src/addons/breadcrumbs'; +import { BrowserBreadcrumbStore } from '../src/addons/breadcrumbs'; import { wait, createTransport, getLastPayload, createCatcher } from './catcher.helpers'; const mockParse = vi.hoisted(() => vi.fn().mockResolvedValue([])); @@ -11,7 +11,7 @@ describe('Catcher', () => { beforeEach(() => { localStorage.clear(); mockParse.mockResolvedValue([]); - (BreadcrumbManager as any).instance = null; + (BrowserBreadcrumbStore as any).instance = null; }); // ── Environment addons ──────────────────────────────────────────────────── diff --git a/packages/javascript/tests/catcher.breadcrumbs.test.ts b/packages/javascript/tests/catcher.breadcrumbs.test.ts index 45cd450a..80880a3c 100644 --- a/packages/javascript/tests/catcher.breadcrumbs.test.ts +++ b/packages/javascript/tests/catcher.breadcrumbs.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { BreadcrumbManager } from '../src/addons/breadcrumbs'; +import { BrowserBreadcrumbStore } from '../src/addons/breadcrumbs'; import { wait, createTransport, getLastPayload, createCatcher } from './catcher.helpers'; const mockParse = vi.hoisted(() => vi.fn().mockResolvedValue([])); @@ -11,7 +11,7 @@ describe('Catcher', () => { beforeEach(() => { localStorage.clear(); mockParse.mockResolvedValue([]); - (BreadcrumbManager as any).instance = null; + (BrowserBreadcrumbStore as any).instance = null; }); // ── Breadcrumbs trail ───────────────────────────────────────────────────── diff --git a/packages/javascript/tests/catcher.context.test.ts b/packages/javascript/tests/catcher.context.test.ts index 231b653c..10b23a70 100644 --- a/packages/javascript/tests/catcher.context.test.ts +++ b/packages/javascript/tests/catcher.context.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { BreadcrumbManager } from '../src/addons/breadcrumbs'; +import { BrowserBreadcrumbStore } from '../src/addons/breadcrumbs'; import { wait, createTransport, getLastPayload, createCatcher } from './catcher.helpers'; const mockParse = vi.hoisted(() => vi.fn().mockResolvedValue([])); @@ -11,7 +11,7 @@ describe('Catcher', () => { beforeEach(() => { localStorage.clear(); mockParse.mockResolvedValue([]); - (BreadcrumbManager as any).instance = null; + (BrowserBreadcrumbStore as any).instance = null; }); // ── Context enrichment ──────────────────────────────────────────────────── diff --git a/packages/javascript/tests/catcher.global-handlers.test.ts b/packages/javascript/tests/catcher.global-handlers.test.ts index 34c18108..7d1bd122 100644 --- a/packages/javascript/tests/catcher.global-handlers.test.ts +++ b/packages/javascript/tests/catcher.global-handlers.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import Catcher from '../src/catcher'; -import { BreadcrumbManager } from '../src/addons/breadcrumbs'; +import { BrowserBreadcrumbStore } from '../src/addons/breadcrumbs'; import { TEST_TOKEN, wait, createTransport, getLastPayload } from './catcher.helpers'; const mockParse = vi.hoisted(() => vi.fn().mockResolvedValue([])); @@ -12,7 +12,7 @@ describe('Catcher', () => { beforeEach(() => { localStorage.clear(); mockParse.mockResolvedValue([]); - (BreadcrumbManager as any).instance = null; + (BrowserBreadcrumbStore as any).instance = null; }); // ── Global error handlers ───────────────────────────────────────────────── diff --git a/packages/javascript/tests/catcher.test.ts b/packages/javascript/tests/catcher.test.ts index 25a363a7..8c13c7c8 100644 --- a/packages/javascript/tests/catcher.test.ts +++ b/packages/javascript/tests/catcher.test.ts @@ -1,7 +1,7 @@ -import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import Catcher from '../src/catcher'; -import { BreadcrumbManager } from '../src/addons/breadcrumbs'; -import { TEST_TOKEN, wait, createTransport, getLastPayload, createCatcher } from './catcher.helpers'; +import { BrowserBreadcrumbStore } from '../src/addons/breadcrumbs'; +import { createCatcher, createTransport, getLastPayload, TEST_TOKEN, wait } from './catcher.helpers'; // StackParser is mocked to prevent real network calls to source files in the jsdom environment. const mockParse = vi.hoisted(() => vi.fn().mockResolvedValue([])); @@ -17,7 +17,7 @@ describe('Catcher', () => { beforeEach(() => { localStorage.clear(); mockParse.mockResolvedValue([]); - (BreadcrumbManager as any).instance = null; + (BrowserBreadcrumbStore as any).instance = null; }); // ── Constructor variants ────────────────────────────────────────────────── diff --git a/packages/javascript/tests/catcher.transport.test.ts b/packages/javascript/tests/catcher.transport.test.ts index a59f4b1e..ec83a0c3 100644 --- a/packages/javascript/tests/catcher.transport.test.ts +++ b/packages/javascript/tests/catcher.transport.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { BreadcrumbManager } from '../src/addons/breadcrumbs'; +import { BrowserBreadcrumbStore } from '../src/addons/breadcrumbs'; import type { Transport } from '../src'; import { wait, createCatcher, createTransport } from './catcher.helpers'; @@ -12,7 +12,7 @@ describe('Catcher', () => { beforeEach(() => { localStorage.clear(); mockParse.mockResolvedValue([]); - (BreadcrumbManager as any).instance = null; + (BrowserBreadcrumbStore as any).instance = null; }); describe('transport failure', () => { diff --git a/packages/javascript/tests/catcher.user.test.ts b/packages/javascript/tests/catcher.user.test.ts index 6f2d29a8..96cabeaa 100644 --- a/packages/javascript/tests/catcher.user.test.ts +++ b/packages/javascript/tests/catcher.user.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { BreadcrumbManager } from '../src/addons/breadcrumbs'; +import { BrowserBreadcrumbStore } from '../src/addons/breadcrumbs'; import { wait, createTransport, getLastPayload, createCatcher } from './catcher.helpers'; const mockParse = vi.hoisted(() => vi.fn().mockResolvedValue([])); @@ -11,7 +11,7 @@ describe('Catcher', () => { beforeEach(() => { localStorage.clear(); mockParse.mockResolvedValue([]); - (BreadcrumbManager as any).instance = null; + (BrowserBreadcrumbStore as any).instance = null; }); // ── User identity ─────────────────────────────────────────────────────────