From a0efa92b2bc8bd1e966a7531616f6451b0fc559c Mon Sep 17 00:00:00 2001 From: Reversean Date: Thu, 12 Feb 2026 20:59:50 +0300 Subject: [PATCH 1/2] refactor(core): UserManager abstraction added --- .github/workflows/main.yml | 4 +- package.json | 2 + packages/core/package.json | 9 ++- packages/core/src/index.ts | 2 + .../src/users/hawk-storage-user-manager.ts | 49 ++++++++++++++ packages/core/src/users/user-manager.ts | 26 ++++++++ .../users/hawk-storage-user-manager.test.ts | 41 ++++++++++++ packages/core/tsconfig.test.json | 13 ++++ packages/core/vitest.config.ts | 15 +++++ packages/javascript/src/catcher.ts | 65 +++++++++---------- packages/javascript/vite.config.ts | 1 + packages/javascript/vitest.config.ts | 1 + yarn.lock | 3 + 13 files changed, 192 insertions(+), 39 deletions(-) create mode 100644 packages/core/src/users/hawk-storage-user-manager.ts create mode 100644 packages/core/src/users/user-manager.ts create mode 100644 packages/core/tests/users/hawk-storage-user-manager.test.ts create mode 100644 packages/core/tsconfig.test.json create mode 100644 packages/core/vitest.config.ts diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fade885..1881dea 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,13 +22,15 @@ jobs: CI_JOB_NUMBER: 2 steps: - uses: actions/checkout@v1 + with: + fetch-depth: 0 - name: Use Node.js from .nvmrc uses: actions/setup-node@v6 with: node-version-file: '.nvmrc' - run: corepack enable - run: yarn install - - run: yarn workspace @hawk.so/javascript test + - run: yarn test:modified origin/${{ github.event.pull_request.base.ref }} build: runs-on: ubuntu-latest diff --git a/package.json b/package.json index 01c1ec1..d59466e 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "dev": "yarn workspace @hawk.so/javascript dev", "build:all": "yarn workspaces foreach -Apt run build", "build:modified": "yarn workspaces foreach --since=\"$@\" -Rpt run build", + "test:all": "yarn workspaces foreach -Apt run test", + "test:modified": "yarn workspaces foreach --since=\"$@\" -Rpt run test", "stats": "yarn workspace @hawk.so/javascript stats", "lint": "eslint -c ./.eslintrc.cjs packages/*/src --ext .ts,.js --fix", "lint-test": "eslint -c ./.eslintrc.cjs packages/*/src --ext .ts,.js" diff --git a/packages/core/package.json b/packages/core/package.json index e06be1d..60734a6 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -17,7 +17,10 @@ } }, "scripts": { - "build": "vite build" + "build": "vite build", + "test": "vitest run", + "test:coverage": "vitest run --coverage", + "lint": "eslint --fix \"src/**/*.{js,ts}\"" }, "repository": { "type": "git", @@ -34,7 +37,9 @@ }, "homepage": "https://github.com/codex-team/hawk.javascript#readme", "devDependencies": { + "@vitest/coverage-v8": "^4.0.18", "vite": "^7.3.1", - "vite-plugin-dts": "^4.2.4" + "vite-plugin-dts": "^4.2.4", + "vitest": "^4.0.18" } } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 6a701eb..00d172a 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1 +1,3 @@ export type { HawkStorage } from './storages/hawk-storage'; +export type { UserManager } from './users/user-manager'; +export { HawkStorageUserManager } from './users/hawk-storage-user-manager'; diff --git a/packages/core/src/users/hawk-storage-user-manager.ts b/packages/core/src/users/hawk-storage-user-manager.ts new file mode 100644 index 0000000..4392f91 --- /dev/null +++ b/packages/core/src/users/hawk-storage-user-manager.ts @@ -0,0 +1,49 @@ +import type { AffectedUser } from '@hawk.so/types'; +import type { HawkStorage } from '../storages/hawk-storage'; +import type { UserManager } from './user-manager'; + +/** + * Storage key used to persist the user identifier. + */ +const HAWK_USER_STORAGE_KEY = 'hawk-user-id'; + +/** + * {@link UserManager} implementation that persists the affected user + * via an injected {@link HawkStorage} backend. + */ +export class HawkStorageUserManager implements UserManager { + /** + * Underlying storage used to read and write the user identifier. + */ + private readonly storage: HawkStorage; + + /** + * @param storage - Storage backend to use for persistence. + */ + constructor(storage: HawkStorage) { + this.storage = storage; + } + + /** @inheritDoc */ + public getUser(): AffectedUser | null { + const storedId = this.storage.getItem(HAWK_USER_STORAGE_KEY); + + if (storedId) { + return { + id: storedId, + }; + } + + return null; + } + + /** @inheritDoc */ + public setUser(user: AffectedUser): void { + this.storage.setItem(HAWK_USER_STORAGE_KEY, user.id); + } + + /** @inheritDoc */ + public clear(): void { + this.storage.removeItem(HAWK_USER_STORAGE_KEY); + } +} diff --git a/packages/core/src/users/user-manager.ts b/packages/core/src/users/user-manager.ts new file mode 100644 index 0000000..f3a1f5b --- /dev/null +++ b/packages/core/src/users/user-manager.ts @@ -0,0 +1,26 @@ +import type { AffectedUser } from '@hawk.so/types'; + +/** + * Contract for user identity managers. + * + * Implementations are responsible for persisting and retrieving the + * {@link AffectedUser} that is attached to every error report sent by the catcher. + */ +export interface UserManager { + /** + * Returns the current affected user, or `null` if none has been set. + */ + getUser(): AffectedUser | null + + /** + * Replaces the stored user with the provided one. + * + * @param user - The affected user to persist. + */ + setUser(user: AffectedUser): void + + /** + * Removes any previously stored user data. + */ + clear(): void +} diff --git a/packages/core/tests/users/hawk-storage-user-manager.test.ts b/packages/core/tests/users/hawk-storage-user-manager.test.ts new file mode 100644 index 0000000..8710f39 --- /dev/null +++ b/packages/core/tests/users/hawk-storage-user-manager.test.ts @@ -0,0 +1,41 @@ +import { describe, it, expect, beforeEach, vi } from 'vitest'; +import { HawkStorageUserManager } from '../../src'; +import type { HawkStorage } from '../../src'; + +describe('StorageUserManager', () => { + let storage: HawkStorage; + let manager: HawkStorageUserManager; + + beforeEach(() => { + storage = { + getItem: vi.fn().mockReturnValue(null), + setItem: vi.fn(), + removeItem: vi.fn(), + }; + manager = new HawkStorageUserManager(storage); + }); + + it('should return null when storage is empty', () => { + expect(manager.getUser()).toBeNull(); + expect(storage.getItem).toHaveBeenCalledWith('hawk-user-id'); + }); + + it('should return user when ID exists in storage', () => { + vi.mocked(storage.getItem).mockReturnValue('test-user-123'); + + expect(manager.getUser()).toEqual({id: 'test-user-123'}); + expect(storage.getItem).toHaveBeenCalledWith('hawk-user-id'); + }); + + it('should persist user ID via setUser()', () => { + manager.setUser({id: 'user-abc'}); + + expect(storage.setItem).toHaveBeenCalledWith('hawk-user-id', 'user-abc'); + }); + + it('should remove user ID via clear()', () => { + manager.clear(); + + expect(storage.removeItem).toHaveBeenCalledWith('hawk-user-id'); + }); +}); diff --git a/packages/core/tsconfig.test.json b/packages/core/tsconfig.test.json new file mode 100644 index 0000000..38db19a --- /dev/null +++ b/packages/core/tsconfig.test.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": null, + "declaration": false, + "types": ["vitest/globals"] + }, + "include": [ + "src/**/*", + "tests/**/*", + "vitest.config.ts" + ] +} diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts new file mode 100644 index 0000000..aee2668 --- /dev/null +++ b/packages/core/vitest.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + globals: true, + include: ['tests/**/*.test.ts'], + typecheck: { + tsconfig: './tsconfig.test.json', + }, + coverage: { + provider: 'v8', + include: ['src/**/*.ts'], + }, + }, +}); diff --git a/packages/javascript/src/catcher.ts b/packages/javascript/src/catcher.ts index b18d868..4b66a65 100644 --- a/packages/javascript/src/catcher.ts +++ b/packages/javascript/src/catcher.ts @@ -4,7 +4,6 @@ import log from './utils/log'; import StackParser from './modules/stackParser'; import type { CatcherMessage, HawkInitialSettings, BreadcrumbsAPI, Transport } from './types'; import { VueIntegration } from './integrations/vue'; -import { id } from './utils/id'; import type { AffectedUser, EventContext, @@ -19,6 +18,10 @@ import { isErrorProcessed, markErrorAsProcessed } from './utils/event'; import { ConsoleCatcher } from './addons/consoleCatcher'; import { BreadcrumbManager } from './addons/breadcrumbs'; import { validateUser, validateContext, isValidEventPayload } from './utils/validation'; +import type { UserManager } from '@hawk.so/core'; +import { HawkStorageUserManager } from '@hawk.so/core'; +import { HawkLocalStorage } from './storages/hawk-local-storage'; +import { id } from './utils/id'; /** * Allow to use global VERSION, that will be overwritten by Webpack @@ -62,11 +65,6 @@ export default class Catcher { */ private readonly release: string | undefined; - /** - * Current authenticated user - */ - private user: AffectedUser; - /** * Any additional data passed by user for sending with all messages */ @@ -111,6 +109,11 @@ export default class Catcher { */ private readonly breadcrumbManager: BreadcrumbManager | null; + /** + * Current authenticated user manager instance + */ + private readonly userManager: UserManager = new HawkStorageUserManager(new HawkLocalStorage()); + /** * Catcher constructor * @@ -126,7 +129,9 @@ export default class Catcher { this.token = settings.token; this.debug = settings.debug || false; this.release = settings.release !== undefined ? String(settings.release) : undefined; - this.setUser(settings.user || Catcher.getGeneratedUser()); + if (settings.user) { + this.setUser(settings.user); + } this.setContext(settings.context || undefined); this.beforeSend = settings.beforeSend; this.disableVueErrorHandler = @@ -189,27 +194,6 @@ export default class Catcher { } } - /** - * Generates user if no one provided via HawkCatcher settings - * After generating, stores user for feature requests - */ - private static getGeneratedUser(): AffectedUser { - let userId: string; - const LOCAL_STORAGE_KEY = 'hawk-user-id'; - const storedId = localStorage.getItem(LOCAL_STORAGE_KEY); - - if (storedId) { - userId = storedId; - } else { - userId = id(); - localStorage.setItem(LOCAL_STORAGE_KEY, userId); - } - - return { - id: userId, - }; - } - /** * Send test event from client */ @@ -272,14 +256,14 @@ export default class Catcher { return; } - this.user = user; + this.userManager.setUser(user); } /** - * Clear current user information (revert to generated user) + * Clear current user information */ public clearUser(): void { - this.user = Catcher.getGeneratedUser(); + this.userManager.clear(); } /** @@ -533,7 +517,7 @@ export default class Catcher { private getIntegrationId(): string { try { const decodedIntegrationToken: DecodedIntegrationToken = JSON.parse(atob(this.token)); - const { integrationId } = decodedIntegrationToken; + const {integrationId} = decodedIntegrationToken; if (!integrationId || integrationId === '') { throw new Error(); @@ -565,10 +549,19 @@ export default class Catcher { } /** - * Current authenticated user + * Returns the current user if exists, otherwise creates and persists a new one. */ - private getUser(): HawkJavaScriptEvent['user'] { - return this.user || null; + private getUser(): AffectedUser { + const user = this.userManager.getUser(); + + if (user) { + return user; + } + const newUser: AffectedUser = {id: id()}; + + this.userManager.setUser(newUser); + + return newUser; } /** @@ -635,7 +628,7 @@ export default class Catcher { * @param {Error|string} error — caught error */ private getAddons(error: Error | string): HawkJavaScriptEvent['addons'] { - const { innerWidth, innerHeight } = window; + const {innerWidth, innerHeight} = window; const userAgent = window.navigator.userAgent; const location = window.location.href; const getParams = this.getGetParams(); diff --git a/packages/javascript/vite.config.ts b/packages/javascript/vite.config.ts index 47fe52e..65b622e 100644 --- a/packages/javascript/vite.config.ts +++ b/packages/javascript/vite.config.ts @@ -26,6 +26,7 @@ export default defineConfig(() => { fileName: 'hawk', }, rollupOptions: { + external: ['@hawk.so/core'], plugins: [ license({ thirdParty: { diff --git a/packages/javascript/vitest.config.ts b/packages/javascript/vitest.config.ts index 47ad6a2..68e2cda 100644 --- a/packages/javascript/vitest.config.ts +++ b/packages/javascript/vitest.config.ts @@ -14,5 +14,6 @@ export default defineConfig({ alias: { '@/types': path.resolve(__dirname, './src/types'), }, + conditions: ['source'], }, }); diff --git a/yarn.lock b/yarn.lock index a2aacdf..65b88ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -587,8 +587,11 @@ __metadata: version: 0.0.0-use.local resolution: "@hawk.so/core@workspace:packages/core" dependencies: + "@hawk.so/types": "npm:0.5.8" + "@vitest/coverage-v8": "npm:^4.0.18" vite: "npm:^7.3.1" vite-plugin-dts: "npm:^4.2.4" + vitest: "npm:^4.0.18" languageName: unknown linkType: soft From 77fb17d65af73fa6b3198ab41439c039bb6eedf6 Mon Sep 17 00:00:00 2001 From: Reversean Date: Wed, 18 Feb 2026 20:52:37 +0300 Subject: [PATCH 2/2] refactor(core): UserManager replaced with HawkUserManager --- packages/core/package.json | 3 + packages/core/src/index.ts | 3 +- .../src/users/hawk-storage-user-manager.ts | 49 ------------- packages/core/src/users/hawk-user-manager.ts | 71 ++++++++++++++++++ packages/core/src/users/user-manager.ts | 26 ------- .../users/hawk-storage-user-manager.test.ts | 41 ----------- .../tests/users/hawk-user-manager.test.ts | 72 +++++++++++++++++++ packages/javascript/src/catcher.ts | 20 +++--- 8 files changed, 155 insertions(+), 130 deletions(-) delete mode 100644 packages/core/src/users/hawk-storage-user-manager.ts create mode 100644 packages/core/src/users/hawk-user-manager.ts delete mode 100644 packages/core/src/users/user-manager.ts delete mode 100644 packages/core/tests/users/hawk-storage-user-manager.test.ts create mode 100644 packages/core/tests/users/hawk-user-manager.test.ts diff --git a/packages/core/package.json b/packages/core/package.json index 60734a6..6797c92 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -36,6 +36,9 @@ "url": "https://github.com/codex-team/hawk.javascript/issues" }, "homepage": "https://github.com/codex-team/hawk.javascript#readme", + "dependencies": { + "@hawk.so/types": "0.5.8" + }, "devDependencies": { "@vitest/coverage-v8": "^4.0.18", "vite": "^7.3.1", diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 00d172a..1a05cf1 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,3 +1,2 @@ export type { HawkStorage } from './storages/hawk-storage'; -export type { UserManager } from './users/user-manager'; -export { HawkStorageUserManager } from './users/hawk-storage-user-manager'; +export { HawkUserManager } from './users/hawk-user-manager'; diff --git a/packages/core/src/users/hawk-storage-user-manager.ts b/packages/core/src/users/hawk-storage-user-manager.ts deleted file mode 100644 index 4392f91..0000000 --- a/packages/core/src/users/hawk-storage-user-manager.ts +++ /dev/null @@ -1,49 +0,0 @@ -import type { AffectedUser } from '@hawk.so/types'; -import type { HawkStorage } from '../storages/hawk-storage'; -import type { UserManager } from './user-manager'; - -/** - * Storage key used to persist the user identifier. - */ -const HAWK_USER_STORAGE_KEY = 'hawk-user-id'; - -/** - * {@link UserManager} implementation that persists the affected user - * via an injected {@link HawkStorage} backend. - */ -export class HawkStorageUserManager implements UserManager { - /** - * Underlying storage used to read and write the user identifier. - */ - private readonly storage: HawkStorage; - - /** - * @param storage - Storage backend to use for persistence. - */ - constructor(storage: HawkStorage) { - this.storage = storage; - } - - /** @inheritDoc */ - public getUser(): AffectedUser | null { - const storedId = this.storage.getItem(HAWK_USER_STORAGE_KEY); - - if (storedId) { - return { - id: storedId, - }; - } - - return null; - } - - /** @inheritDoc */ - public setUser(user: AffectedUser): void { - this.storage.setItem(HAWK_USER_STORAGE_KEY, user.id); - } - - /** @inheritDoc */ - public clear(): void { - this.storage.removeItem(HAWK_USER_STORAGE_KEY); - } -} diff --git a/packages/core/src/users/hawk-user-manager.ts b/packages/core/src/users/hawk-user-manager.ts new file mode 100644 index 0000000..7c965c3 --- /dev/null +++ b/packages/core/src/users/hawk-user-manager.ts @@ -0,0 +1,71 @@ +import type { AffectedUser } from '@hawk.so/types'; +import type { HawkStorage } from '../storages/hawk-storage'; + +/** + * Storage key used to persist the auto-generated user ID. + */ +export const HAWK_USER_ID_KEY = 'hawk-user-id'; + +/** + * Manages the affected user identity. + * + * Manually provided users are kept in memory only (they don't change restarts). + * {@link HawkStorage} is used solely to persist the auto-generated ID + * so it survives across sessions. + */ +export class HawkUserManager { + /** + * In-memory user set explicitly via {@link setUser}. + */ + private user: AffectedUser | null = null; + + /** + * Underlying storage used to persist auto-generated user ID. + */ + private readonly storage: HawkStorage; + + /** + * @param storage - Storage backend to use for persistence. + */ + constructor(storage: HawkStorage) { + this.storage = storage; + } + + /** + * Returns the current affected user, or `null` if none is available. + * + * Priority: in-memory user > persisted user ID. + */ + public getUser(): AffectedUser | null { + if (this.user) { + return this.user; + } + const storedId = this.storage.getItem(HAWK_USER_ID_KEY); + return storedId ? { id: storedId } : null; + } + + /** + * Sets the user explicitly (in memory only). + * + * @param user - The affected user provided by the application. + */ + public setUser(user: AffectedUser): void { + this.user = user; + } + + /** + * Persists an auto-generated user ID to storage. + * + * @param id - The generated ID to persist. + */ + public persistGeneratedId(id: string): void { + this.storage.setItem(HAWK_USER_ID_KEY, id); + } + + /** + * Clears the explicitly set user, falling back to the persisted user ID. + */ + public clear(): void { + this.user = null; + } +} diff --git a/packages/core/src/users/user-manager.ts b/packages/core/src/users/user-manager.ts deleted file mode 100644 index f3a1f5b..0000000 --- a/packages/core/src/users/user-manager.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { AffectedUser } from '@hawk.so/types'; - -/** - * Contract for user identity managers. - * - * Implementations are responsible for persisting and retrieving the - * {@link AffectedUser} that is attached to every error report sent by the catcher. - */ -export interface UserManager { - /** - * Returns the current affected user, or `null` if none has been set. - */ - getUser(): AffectedUser | null - - /** - * Replaces the stored user with the provided one. - * - * @param user - The affected user to persist. - */ - setUser(user: AffectedUser): void - - /** - * Removes any previously stored user data. - */ - clear(): void -} diff --git a/packages/core/tests/users/hawk-storage-user-manager.test.ts b/packages/core/tests/users/hawk-storage-user-manager.test.ts deleted file mode 100644 index 8710f39..0000000 --- a/packages/core/tests/users/hawk-storage-user-manager.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { describe, it, expect, beforeEach, vi } from 'vitest'; -import { HawkStorageUserManager } from '../../src'; -import type { HawkStorage } from '../../src'; - -describe('StorageUserManager', () => { - let storage: HawkStorage; - let manager: HawkStorageUserManager; - - beforeEach(() => { - storage = { - getItem: vi.fn().mockReturnValue(null), - setItem: vi.fn(), - removeItem: vi.fn(), - }; - manager = new HawkStorageUserManager(storage); - }); - - it('should return null when storage is empty', () => { - expect(manager.getUser()).toBeNull(); - expect(storage.getItem).toHaveBeenCalledWith('hawk-user-id'); - }); - - it('should return user when ID exists in storage', () => { - vi.mocked(storage.getItem).mockReturnValue('test-user-123'); - - expect(manager.getUser()).toEqual({id: 'test-user-123'}); - expect(storage.getItem).toHaveBeenCalledWith('hawk-user-id'); - }); - - it('should persist user ID via setUser()', () => { - manager.setUser({id: 'user-abc'}); - - expect(storage.setItem).toHaveBeenCalledWith('hawk-user-id', 'user-abc'); - }); - - it('should remove user ID via clear()', () => { - manager.clear(); - - expect(storage.removeItem).toHaveBeenCalledWith('hawk-user-id'); - }); -}); diff --git a/packages/core/tests/users/hawk-user-manager.test.ts b/packages/core/tests/users/hawk-user-manager.test.ts new file mode 100644 index 0000000..3ef9a72 --- /dev/null +++ b/packages/core/tests/users/hawk-user-manager.test.ts @@ -0,0 +1,72 @@ +import { describe, it, expect, beforeEach, vi } from 'vitest'; +import { HawkUserManager } from '../../src'; +import type { HawkStorage } from '../../src'; + +describe('HawkUserManager', () => { + let storage: HawkStorage; + let manager: HawkUserManager; + + beforeEach(() => { + storage = { + getItem: vi.fn().mockReturnValue(null), + setItem: vi.fn(), + removeItem: vi.fn(), + }; + manager = new HawkUserManager(storage); + }); + + it('should return null when no user is set and storage is empty', () => { + expect(manager.getUser()).toBeNull(); + }); + + it('should return in-memory user set via setUser()', () => { + const user = { id: 'user-1', name: 'Ryan Gosling', url: 'https://example.com', photo: 'https://example.com/photo.png' }; + + manager.setUser(user); + + expect(manager.getUser()).toEqual(user); + expect(storage.setItem).not.toHaveBeenCalled(); + }); + + it('should not touch storage when setUser() is called', () => { + manager.setUser({ id: 'user-1' }); + + expect(storage.setItem).not.toHaveBeenCalled(); + expect(storage.removeItem).not.toHaveBeenCalled(); + }); + + it('should return anonymous user from storage when no in-memory user is set', () => { + vi.mocked(storage.getItem).mockReturnValue('anon-123'); + + expect(manager.getUser()).toEqual({ id: 'anon-123' }); + expect(storage.getItem).toHaveBeenCalledWith('hawk-user-id'); + }); + + it('should prefer in-memory user over persisted anonymous ID', () => { + vi.mocked(storage.getItem).mockReturnValue('anon-123'); + manager.setUser({ id: 'explicit-user' }); + + expect(manager.getUser()).toEqual({ id: 'explicit-user' }); + }); + + it('should persist anonymous ID via persistGeneratedId()', () => { + manager.persistGeneratedId('anon-456'); + + expect(storage.setItem).toHaveBeenCalledWith('hawk-user-id', 'anon-456'); + }); + + it('should clear in-memory user and fall back to persisted anonymous ID', () => { + vi.mocked(storage.getItem).mockReturnValue('anon-123'); + manager.setUser({ id: 'user-1' }); + manager.clear(); + + expect(manager.getUser()).toEqual({ id: 'anon-123' }); + }); + + it('should return null after clear() when no anonymous ID is persisted', () => { + manager.setUser({ id: 'user-1' }); + manager.clear(); + + expect(manager.getUser()).toBeNull(); + }); +}); diff --git a/packages/javascript/src/catcher.ts b/packages/javascript/src/catcher.ts index 4b66a65..63bcb29 100644 --- a/packages/javascript/src/catcher.ts +++ b/packages/javascript/src/catcher.ts @@ -18,8 +18,7 @@ import { isErrorProcessed, markErrorAsProcessed } from './utils/event'; import { ConsoleCatcher } from './addons/consoleCatcher'; import { BreadcrumbManager } from './addons/breadcrumbs'; import { validateUser, validateContext, isValidEventPayload } from './utils/validation'; -import type { UserManager } from '@hawk.so/core'; -import { HawkStorageUserManager } from '@hawk.so/core'; +import { HawkUserManager } from '@hawk.so/core'; import { HawkLocalStorage } from './storages/hawk-local-storage'; import { id } from './utils/id'; @@ -112,7 +111,7 @@ export default class Catcher { /** * Current authenticated user manager instance */ - private readonly userManager: UserManager = new HawkStorageUserManager(new HawkLocalStorage()); + private readonly userManager: HawkUserManager = new HawkUserManager(new HawkLocalStorage()); /** * Catcher constructor @@ -517,7 +516,7 @@ export default class Catcher { private getIntegrationId(): string { try { const decodedIntegrationToken: DecodedIntegrationToken = JSON.parse(atob(this.token)); - const {integrationId} = decodedIntegrationToken; + const { integrationId } = decodedIntegrationToken; if (!integrationId || integrationId === '') { throw new Error(); @@ -549,19 +548,16 @@ export default class Catcher { } /** - * Returns the current user if exists, otherwise creates and persists a new one. + * Returns the current user if set, otherwise generates and persists an anonymous ID. */ private getUser(): AffectedUser { const user = this.userManager.getUser(); - if (user) { return user; } - const newUser: AffectedUser = {id: id()}; - - this.userManager.setUser(newUser); - - return newUser; + const generatedId = id(); + this.userManager.persistGeneratedId(generatedId); + return { id: generatedId }; } /** @@ -628,7 +624,7 @@ export default class Catcher { * @param {Error|string} error — caught error */ private getAddons(error: Error | string): HawkJavaScriptEvent['addons'] { - const {innerWidth, innerHeight} = window; + const { innerWidth, innerHeight } = window; const userAgent = window.navigator.userAgent; const location = window.location.href; const getParams = this.getGetParams();