-
Notifications
You must be signed in to change notification settings - Fork 0
feat(nodejs): add breadcrumbs API (add, get, clear) aligned with JS catcher #47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
cea689a
chore: init
Dobrunia 0e1ce58
fix: build
Dobrunia 519dfc1
fix: lint
Dobrunia b99f941
Bump version up to 3.2.1
github-actions[bot] ad43bb1
fix: lint
Dobrunia be82694
chore: bump version to 3.3.0
Dobrunia 5399d08
refactor: update type exports in index.ts
Dobrunia fafe24e
docs: clarify breadcrumbs behavior in README and index.ts
Dobrunia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| /** | ||
| * @file Breadcrumbs module - chronological trail of events before an error. Custom breadcrumbs only (HawkCatcher.breadcrumbs.add()). Possible future auto-capture: outgoing HTTP, unhandledRejection/uncaughtException, console.log/intercept, DB query hooks. | ||
| */ | ||
| import type { Breadcrumb } from '@hawk.so/types'; | ||
|
|
||
| /** | ||
| * Default maximum number of breadcrumbs to store | ||
| */ | ||
| const DEFAULT_MAX_BREADCRUMBS = 15; | ||
|
|
||
| /** | ||
| * Hint object passed to beforeBreadcrumb callback (same concept as in JS catcher; in Node no event/response yet, use for custom context) | ||
| */ | ||
| export interface BreadcrumbHint { | ||
| [key: string]: unknown; | ||
| } | ||
|
|
||
| /** | ||
| * Configuration options for breadcrumbs (same shape as @hawk.so/javascript; no trackFetch/trackNavigation/trackClicks in Node) | ||
| */ | ||
| export interface BreadcrumbsOptions { | ||
| /** | ||
| * Maximum number of breadcrumbs to store (FIFO). When the limit is reached, oldest are removed. | ||
| * @default 15 | ||
| */ | ||
| maxBreadcrumbs?: number; | ||
|
|
||
| /** | ||
| * Hook called before each breadcrumb is stored. Return null to discard. Return modified breadcrumb to store it. | ||
| * @param breadcrumb - Breadcrumb to store (can be mutated and returned) | ||
| * @param hint - Optional context (e.g. for filtering) | ||
| * @returns Modified breadcrumb to store, or null to discard | ||
| */ | ||
| beforeBreadcrumb?: (breadcrumb: Breadcrumb, hint?: BreadcrumbHint) => Breadcrumb | null; | ||
| } | ||
|
|
||
| /** | ||
| * Breadcrumb input - timestamp optional (auto-generated if omitted). Same as @hawk.so/javascript BreadcrumbInput. | ||
| */ | ||
| // eslint-disable-next-line jsdoc/require-jsdoc -- type alias documented above | ||
| export type BreadcrumbInput = Omit<Breadcrumb, 'timestamp'> & { timestamp?: Breadcrumb['timestamp'] }; | ||
|
|
||
| /** | ||
| * Internal breadcrumbs options (all fields set during init from BreadcrumbsOptions) | ||
| */ | ||
| interface InternalBreadcrumbsOptions { | ||
| /** Maximum number of breadcrumbs to keep (FIFO) */ | ||
| maxBreadcrumbs: number; | ||
|
|
||
| /** Optional hook before storing each breadcrumb */ | ||
| beforeBreadcrumb?: BreadcrumbsOptions['beforeBreadcrumb']; | ||
| } | ||
|
|
||
| /** | ||
| * Manages breadcrumb buffer and add/get/clear API | ||
| */ | ||
| export class BreadcrumbManager { | ||
| private static instance: BreadcrumbManager | null = null; | ||
|
|
||
| private readonly breadcrumbs: Breadcrumb[] = []; | ||
|
|
||
| private options: InternalBreadcrumbsOptions = { | ||
| maxBreadcrumbs: DEFAULT_MAX_BREADCRUMBS, | ||
| }; | ||
|
|
||
| private isInitialized = false; | ||
|
|
||
| /** | ||
| * Private constructor for singleton | ||
| */ | ||
| private constructor() {} | ||
|
|
||
| /** | ||
| * Get singleton instance (created on first call). | ||
| * @returns The shared BreadcrumbManager | ||
| */ | ||
| public static getInstance(): BreadcrumbManager { | ||
| if (BreadcrumbManager.instance === null) { | ||
| BreadcrumbManager.instance = new BreadcrumbManager(); | ||
| } | ||
|
|
||
| return BreadcrumbManager.instance; | ||
| } | ||
|
|
||
| /** | ||
| * Initialize with options. Call once when HawkCatcher.init() runs. | ||
| * @param options - Configuration (maxBreadcrumbs, beforeBreadcrumb) | ||
| */ | ||
| public init(options: BreadcrumbsOptions = {}): void { | ||
| if (this.isInitialized) { | ||
| return; | ||
| } | ||
|
|
||
| this.options = { | ||
| maxBreadcrumbs: options.maxBreadcrumbs ?? DEFAULT_MAX_BREADCRUMBS, | ||
| beforeBreadcrumb: options.beforeBreadcrumb, | ||
| }; | ||
|
|
||
Dobrunia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| this.isInitialized = true; | ||
| } | ||
|
|
||
| /** | ||
| * Add a breadcrumb. Timestamp is set to Date.now() if omitted. | ||
| * @param breadcrumb - Breadcrumb data (type, message, category, level, data) | ||
| * @param hint - Optional hint for beforeBreadcrumb callback | ||
| */ | ||
| public addBreadcrumb(breadcrumb: BreadcrumbInput, hint?: BreadcrumbHint): void { | ||
| const bc: Breadcrumb = { | ||
| ...breadcrumb, | ||
| timestamp: breadcrumb.timestamp ?? Date.now(), | ||
| }; | ||
|
|
||
| if (this.options.beforeBreadcrumb) { | ||
| const result = this.options.beforeBreadcrumb(bc, hint); | ||
|
|
||
| if (result === null) { | ||
| return; | ||
| } | ||
|
|
||
| Object.assign(bc, result); | ||
| } | ||
|
|
||
| this.breadcrumbs.push(bc); | ||
|
|
||
| if (this.breadcrumbs.length > this.options.maxBreadcrumbs) { | ||
| this.breadcrumbs.shift(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Snapshot of current breadcrumbs (oldest to newest) | ||
| */ | ||
| public getBreadcrumbs(): Breadcrumb[] { | ||
| return [...this.breadcrumbs]; | ||
| } | ||
|
|
||
| /** | ||
| * Clear all breadcrumbs (e.g. after sending an event) | ||
| */ | ||
| public clear(): void { | ||
| this.breadcrumbs.length = 0; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.