@vestig/next 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/__tests__/mocks/next-server.d.ts.map +1 -1
- package/dist/__tests__/mocks/next-server.js.map +1 -1
- package/dist/client/error-boundary.d.ts +80 -0
- package/dist/client/error-boundary.d.ts.map +1 -0
- package/dist/client/error-boundary.js +182 -0
- package/dist/client/error-boundary.js.map +1 -0
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/transport.d.ts +42 -0
- package/dist/client/transport.d.ts.map +1 -1
- package/dist/client/transport.js +143 -2
- package/dist/client/transport.js.map +1 -1
- package/dist/client.d.ts +2 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -1
- package/dist/db/drizzle.d.ts +115 -0
- package/dist/db/drizzle.d.ts.map +1 -0
- package/dist/db/drizzle.js +174 -0
- package/dist/db/drizzle.js.map +1 -0
- package/dist/db/index.d.ts +49 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +51 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/prisma.d.ts +114 -0
- package/dist/db/prisma.d.ts.map +1 -0
- package/dist/db/prisma.js +144 -0
- package/dist/db/prisma.js.map +1 -0
- package/dist/db/query-logger.d.ts +30 -0
- package/dist/db/query-logger.d.ts.map +1 -0
- package/dist/db/query-logger.js +169 -0
- package/dist/db/query-logger.js.map +1 -0
- package/dist/db/types.d.ts +102 -0
- package/dist/db/types.d.ts.map +1 -0
- package/dist/db/types.js +28 -0
- package/dist/db/types.js.map +1 -0
- package/dist/dev/api/index.d.ts +13 -0
- package/dist/dev/api/index.d.ts.map +1 -0
- package/dist/dev/api/index.js +13 -0
- package/dist/dev/api/index.js.map +1 -0
- package/dist/dev/api/logs-stream.d.ts +119 -0
- package/dist/dev/api/logs-stream.d.ts.map +1 -0
- package/dist/dev/api/logs-stream.js +156 -0
- package/dist/dev/api/logs-stream.js.map +1 -0
- package/dist/dev/filters.d.ts +17 -0
- package/dist/dev/filters.d.ts.map +1 -0
- package/dist/dev/filters.js +96 -0
- package/dist/dev/filters.js.map +1 -0
- package/dist/dev/hooks/use-logs.d.ts +53 -0
- package/dist/dev/hooks/use-logs.d.ts.map +1 -0
- package/dist/dev/hooks/use-logs.js +205 -0
- package/dist/dev/hooks/use-logs.js.map +1 -0
- package/dist/dev/index.d.ts +35 -0
- package/dist/dev/index.d.ts.map +1 -0
- package/dist/dev/index.js +41 -0
- package/dist/dev/index.js.map +1 -0
- package/dist/dev/log-entry.d.ts +12 -0
- package/dist/dev/log-entry.d.ts.map +1 -0
- package/dist/dev/log-entry.js +152 -0
- package/dist/dev/log-entry.js.map +1 -0
- package/dist/dev/log-viewer.d.ts +11 -0
- package/dist/dev/log-viewer.d.ts.map +1 -0
- package/dist/dev/log-viewer.js +49 -0
- package/dist/dev/log-viewer.js.map +1 -0
- package/dist/dev/metrics-card.d.ts +18 -0
- package/dist/dev/metrics-card.d.ts.map +1 -0
- package/dist/dev/metrics-card.js +75 -0
- package/dist/dev/metrics-card.js.map +1 -0
- package/dist/dev/metrics-histogram.d.ts +12 -0
- package/dist/dev/metrics-histogram.d.ts.map +1 -0
- package/dist/dev/metrics-histogram.js +69 -0
- package/dist/dev/metrics-histogram.js.map +1 -0
- package/dist/dev/metrics-panel.d.ts +10 -0
- package/dist/dev/metrics-panel.d.ts.map +1 -0
- package/dist/dev/metrics-panel.js +84 -0
- package/dist/dev/metrics-panel.js.map +1 -0
- package/dist/dev/overlay.d.ts +55 -0
- package/dist/dev/overlay.d.ts.map +1 -0
- package/dist/dev/overlay.js +204 -0
- package/dist/dev/overlay.js.map +1 -0
- package/dist/dev/store.d.ts +186 -0
- package/dist/dev/store.d.ts.map +1 -0
- package/dist/dev/store.js +214 -0
- package/dist/dev/store.js.map +1 -0
- package/dist/error/boundary.d.ts +36 -0
- package/dist/error/boundary.d.ts.map +1 -0
- package/dist/error/boundary.js +263 -0
- package/dist/error/boundary.js.map +1 -0
- package/dist/error/breadcrumbs.d.ts +95 -0
- package/dist/error/breadcrumbs.d.ts.map +1 -0
- package/dist/error/breadcrumbs.js +273 -0
- package/dist/error/breadcrumbs.js.map +1 -0
- package/dist/error/fingerprint.d.ts +42 -0
- package/dist/error/fingerprint.d.ts.map +1 -0
- package/dist/error/fingerprint.js +135 -0
- package/dist/error/fingerprint.js.map +1 -0
- package/dist/error/index.d.ts +52 -0
- package/dist/error/index.d.ts.map +1 -0
- package/dist/error/index.js +56 -0
- package/dist/error/index.js.map +1 -0
- package/dist/error/stack-parser.d.ts +43 -0
- package/dist/error/stack-parser.d.ts.map +1 -0
- package/dist/error/stack-parser.js +166 -0
- package/dist/error/stack-parser.js.map +1 -0
- package/dist/error/types.d.ts +152 -0
- package/dist/error/types.d.ts.map +1 -0
- package/dist/error/types.js +10 -0
- package/dist/error/types.js.map +1 -0
- package/dist/metrics/hooks/use-route-metrics.d.ts +91 -0
- package/dist/metrics/hooks/use-route-metrics.d.ts.map +1 -0
- package/dist/metrics/hooks/use-route-metrics.js +216 -0
- package/dist/metrics/hooks/use-route-metrics.js.map +1 -0
- package/dist/metrics/hooks/use-web-vitals.d.ts +70 -0
- package/dist/metrics/hooks/use-web-vitals.d.ts.map +1 -0
- package/dist/metrics/hooks/use-web-vitals.js +146 -0
- package/dist/metrics/hooks/use-web-vitals.js.map +1 -0
- package/dist/metrics/index.d.ts +51 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +56 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/reporter.d.ts +87 -0
- package/dist/metrics/reporter.d.ts.map +1 -0
- package/dist/metrics/reporter.js +178 -0
- package/dist/metrics/reporter.js.map +1 -0
- package/dist/metrics/store.d.ts +34 -0
- package/dist/metrics/store.d.ts.map +1 -0
- package/dist/metrics/store.js +172 -0
- package/dist/metrics/store.js.map +1 -0
- package/dist/metrics/thresholds.d.ts +84 -0
- package/dist/metrics/thresholds.d.ts.map +1 -0
- package/dist/metrics/thresholds.js +148 -0
- package/dist/metrics/thresholds.js.map +1 -0
- package/dist/metrics/types.d.ts +211 -0
- package/dist/metrics/types.d.ts.map +1 -0
- package/dist/metrics/types.js +10 -0
- package/dist/metrics/types.js.map +1 -0
- package/dist/metrics/web-vitals.d.ts +72 -0
- package/dist/metrics/web-vitals.d.ts.map +1 -0
- package/dist/metrics/web-vitals.js +89 -0
- package/dist/metrics/web-vitals.js.map +1 -0
- package/package.json +28 -6
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Fingerprinting
|
|
3
|
+
*
|
|
4
|
+
* Generates unique fingerprints for errors to group similar errors together.
|
|
5
|
+
* Useful for error aggregation in monitoring systems.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
import type { FingerprintOptions, StackFrame } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* Generate a fingerprint for an error
|
|
12
|
+
*
|
|
13
|
+
* The fingerprint is designed to group similar errors together while
|
|
14
|
+
* distinguishing between genuinely different errors.
|
|
15
|
+
*
|
|
16
|
+
* @param error - The error to fingerprint
|
|
17
|
+
* @param frames - Parsed stack frames
|
|
18
|
+
* @param options - Fingerprinting options
|
|
19
|
+
* @returns A hex string fingerprint
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const fingerprint = generateFingerprint(error, frames)
|
|
24
|
+
* // 'a1b2c3d4e5f6g7h8'
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function generateFingerprint(error: Error, frames: StackFrame[], options?: FingerprintOptions): string;
|
|
28
|
+
/**
|
|
29
|
+
* Check if two errors have the same fingerprint
|
|
30
|
+
*/
|
|
31
|
+
export declare function isSameError(error1: {
|
|
32
|
+
fingerprint: string;
|
|
33
|
+
}, error2: {
|
|
34
|
+
fingerprint: string;
|
|
35
|
+
}): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Group errors by fingerprint
|
|
38
|
+
*/
|
|
39
|
+
export declare function groupErrors<T extends {
|
|
40
|
+
fingerprint: string;
|
|
41
|
+
}>(errors: T[]): Map<string, T[]>;
|
|
42
|
+
//# sourceMappingURL=fingerprint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/error/fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AA2E7D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,UAAU,EAAE,EACpB,OAAO,GAAE,kBAAuB,GAC9B,MAAM,CAsCR;AAED;;GAEG;AACH,wBAAgB,WAAW,CAC1B,MAAM,EAAE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,EAC/B,MAAM,EAAE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAC7B,OAAO,CAET;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAU5F"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Fingerprinting
|
|
3
|
+
*
|
|
4
|
+
* Generates unique fingerprints for errors to group similar errors together.
|
|
5
|
+
* Useful for error aggregation in monitoring systems.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Simple hash function for strings
|
|
11
|
+
* Uses djb2 algorithm for fast, consistent hashing
|
|
12
|
+
*/
|
|
13
|
+
function hashString(str) {
|
|
14
|
+
let hash = 5381;
|
|
15
|
+
for (let i = 0; i < str.length; i++) {
|
|
16
|
+
hash = (hash * 33) ^ str.charCodeAt(i);
|
|
17
|
+
}
|
|
18
|
+
return (hash >>> 0).toString(16).padStart(8, '0');
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Normalize a file path for consistent fingerprinting
|
|
22
|
+
* Removes dynamic parts like hashes, timestamps, query strings
|
|
23
|
+
*/
|
|
24
|
+
function normalizeFilePath(path) {
|
|
25
|
+
return (path
|
|
26
|
+
// Remove webpack chunk hashes
|
|
27
|
+
.replace(/\.[a-f0-9]{8,}\./, '.')
|
|
28
|
+
// Remove query strings
|
|
29
|
+
.replace(/\?.*$/, '')
|
|
30
|
+
// Remove line/column from paths
|
|
31
|
+
.replace(/:\d+:\d+$/, '')
|
|
32
|
+
// Normalize slashes
|
|
33
|
+
.replace(/\\/g, '/')
|
|
34
|
+
// Remove absolute path prefixes
|
|
35
|
+
.replace(/^.*\/node_modules\//, 'node_modules/')
|
|
36
|
+
.replace(/^.*\/(src|app|pages|components)\//, '$1/'));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Normalize function name for consistent fingerprinting
|
|
40
|
+
*/
|
|
41
|
+
function normalizeFunctionName(name) {
|
|
42
|
+
if (!name)
|
|
43
|
+
return '<anonymous>';
|
|
44
|
+
return (name
|
|
45
|
+
// Remove React component wrappers
|
|
46
|
+
.replace(/^(Object\.)?/, '')
|
|
47
|
+
// Remove module prefixes
|
|
48
|
+
.replace(/^exports\./, '')
|
|
49
|
+
// Remove async prefixes
|
|
50
|
+
.replace(/^async /, ''));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extract key parts from an error message
|
|
54
|
+
* Removes dynamic values like IDs, timestamps, etc.
|
|
55
|
+
*/
|
|
56
|
+
function normalizeErrorMessage(message) {
|
|
57
|
+
return (message
|
|
58
|
+
// Remove UUIDs
|
|
59
|
+
.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '<UUID>')
|
|
60
|
+
// Remove numbers that look like IDs
|
|
61
|
+
.replace(/\b\d{5,}\b/g, '<ID>')
|
|
62
|
+
// Remove URLs
|
|
63
|
+
.replace(/https?:\/\/[^\s]+/g, '<URL>')
|
|
64
|
+
// Remove file paths
|
|
65
|
+
.replace(/\/[^\s:]+\.(js|ts|tsx|jsx)/g, '<FILE>')
|
|
66
|
+
// Remove quoted strings (might be dynamic)
|
|
67
|
+
.replace(/"[^"]{20,}"/g, '"<STRING>"')
|
|
68
|
+
.replace(/'[^']{20,}'/g, "'<STRING>'")
|
|
69
|
+
// Trim whitespace
|
|
70
|
+
.trim());
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Generate a fingerprint for an error
|
|
74
|
+
*
|
|
75
|
+
* The fingerprint is designed to group similar errors together while
|
|
76
|
+
* distinguishing between genuinely different errors.
|
|
77
|
+
*
|
|
78
|
+
* @param error - The error to fingerprint
|
|
79
|
+
* @param frames - Parsed stack frames
|
|
80
|
+
* @param options - Fingerprinting options
|
|
81
|
+
* @returns A hex string fingerprint
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```ts
|
|
85
|
+
* const fingerprint = generateFingerprint(error, frames)
|
|
86
|
+
* // 'a1b2c3d4e5f6g7h8'
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export function generateFingerprint(error, frames, options = {}) {
|
|
90
|
+
const { includeFilePaths = true, includeLineNumbers = false, maxFrames = 5 } = options;
|
|
91
|
+
const parts = [];
|
|
92
|
+
// 1. Error type/name
|
|
93
|
+
parts.push(error.name || 'Error');
|
|
94
|
+
// 2. Normalized error message
|
|
95
|
+
parts.push(normalizeErrorMessage(error.message));
|
|
96
|
+
// 3. Stack frames (focus on app code)
|
|
97
|
+
const appFrames = frames.filter((f) => f.isAppCode).slice(0, maxFrames);
|
|
98
|
+
// If no app frames, use first few frames
|
|
99
|
+
const relevantFrames = appFrames.length > 0 ? appFrames : frames.slice(0, maxFrames);
|
|
100
|
+
for (const frame of relevantFrames) {
|
|
101
|
+
const frameParts = [];
|
|
102
|
+
// Function name is most stable
|
|
103
|
+
frameParts.push(normalizeFunctionName(frame.functionName));
|
|
104
|
+
// File path (optional)
|
|
105
|
+
if (includeFilePaths && frame.fileName) {
|
|
106
|
+
frameParts.push(normalizeFilePath(frame.fileName));
|
|
107
|
+
}
|
|
108
|
+
// Line number (optional - less stable across builds)
|
|
109
|
+
if (includeLineNumbers && frame.lineNumber) {
|
|
110
|
+
frameParts.push(String(frame.lineNumber));
|
|
111
|
+
}
|
|
112
|
+
parts.push(frameParts.join(':'));
|
|
113
|
+
}
|
|
114
|
+
// Generate hash from combined parts
|
|
115
|
+
return hashString(parts.join('|'));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Check if two errors have the same fingerprint
|
|
119
|
+
*/
|
|
120
|
+
export function isSameError(error1, error2) {
|
|
121
|
+
return error1.fingerprint === error2.fingerprint;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Group errors by fingerprint
|
|
125
|
+
*/
|
|
126
|
+
export function groupErrors(errors) {
|
|
127
|
+
const groups = new Map();
|
|
128
|
+
for (const error of errors) {
|
|
129
|
+
const existing = groups.get(error.fingerprint) ?? [];
|
|
130
|
+
existing.push(error);
|
|
131
|
+
groups.set(error.fingerprint, existing);
|
|
132
|
+
}
|
|
133
|
+
return groups;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=fingerprint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../src/error/fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;GAGG;AACH,SAAS,UAAU,CAAC,GAAW;IAC9B,IAAI,IAAI,GAAG,IAAI,CAAA;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;IACvC,CAAC;IACD,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;AAClD,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,IAAY;IACtC,OAAO,CACN,IAAI;QACH,8BAA8B;SAC7B,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;QACjC,uBAAuB;SACtB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QACrB,gCAAgC;SAC/B,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QACzB,oBAAoB;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;QACpB,gCAAgC;SAC/B,OAAO,CAAC,qBAAqB,EAAE,eAAe,CAAC;SAC/C,OAAO,CAAC,mCAAmC,EAAE,KAAK,CAAC,CACrD,CAAA;AACF,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,IAAwB;IACtD,IAAI,CAAC,IAAI;QAAE,OAAO,aAAa,CAAA;IAE/B,OAAO,CACN,IAAI;QACH,kCAAkC;SACjC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;QAC5B,yBAAyB;SACxB,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;QAC1B,wBAAwB;SACvB,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CACxB,CAAA;AACF,CAAC;AAED;;;GAGG;AACH,SAAS,qBAAqB,CAAC,OAAe;IAC7C,OAAO,CACN,OAAO;QACN,eAAe;SACd,OAAO,CAAC,gEAAgE,EAAE,QAAQ,CAAC;QACpF,oCAAoC;SACnC,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,cAAc;SACb,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;QACvC,oBAAoB;SACnB,OAAO,CAAC,6BAA6B,EAAE,QAAQ,CAAC;QACjD,2CAA2C;SAC1C,OAAO,CAAC,cAAc,EAAE,YAAY,CAAC;SACrC,OAAO,CAAC,cAAc,EAAE,YAAY,CAAC;QACtC,kBAAkB;SACjB,IAAI,EAAE,CACR,CAAA;AACF,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,mBAAmB,CAClC,KAAY,EACZ,MAAoB,EACpB,UAA8B,EAAE;IAEhC,MAAM,EAAE,gBAAgB,GAAG,IAAI,EAAE,kBAAkB,GAAG,KAAK,EAAE,SAAS,GAAG,CAAC,EAAE,GAAG,OAAO,CAAA;IAEtF,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,qBAAqB;IACrB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,CAAA;IAEjC,8BAA8B;IAC9B,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;IAEhD,sCAAsC;IACtC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;IAEvE,yCAAyC;IACzC,MAAM,cAAc,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;IAEpF,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACpC,MAAM,UAAU,GAAa,EAAE,CAAA;QAE/B,+BAA+B;QAC/B,UAAU,CAAC,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAA;QAE1D,uBAAuB;QACvB,IAAI,gBAAgB,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACxC,UAAU,CAAC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;QACnD,CAAC;QAED,qDAAqD;QACrD,IAAI,kBAAkB,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YAC5C,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAA;QAC1C,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IACjC,CAAC;IAED,oCAAoC;IACpC,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAC1B,MAA+B,EAC/B,MAA+B;IAE/B,OAAO,MAAM,CAAC,WAAW,KAAK,MAAM,CAAC,WAAW,CAAA;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAoC,MAAW;IACzE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAe,CAAA;IAErC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;QACpD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;IACxC,CAAC;IAED,OAAO,MAAM,CAAA;AACd,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vestig/next/error - Enhanced Error Handling
|
|
3
|
+
*
|
|
4
|
+
* This module provides enhanced error handling for Next.js applications
|
|
5
|
+
* with rich development experience including:
|
|
6
|
+
*
|
|
7
|
+
* - **Stack trace parsing** with app code highlighting
|
|
8
|
+
* - **Breadcrumb trails** showing events before the error
|
|
9
|
+
* - **Error fingerprinting** for grouping similar errors
|
|
10
|
+
* - **React component tree** visualization
|
|
11
|
+
*
|
|
12
|
+
* @example Basic Usage
|
|
13
|
+
* ```tsx
|
|
14
|
+
* // app/layout.tsx
|
|
15
|
+
* import { EnhancedErrorBoundary } from '@vestig/next/error'
|
|
16
|
+
*
|
|
17
|
+
* export default function RootLayout({ children }) {
|
|
18
|
+
* return (
|
|
19
|
+
* <html>
|
|
20
|
+
* <body>
|
|
21
|
+
* <EnhancedErrorBoundary>
|
|
22
|
+
* {children}
|
|
23
|
+
* </EnhancedErrorBoundary>
|
|
24
|
+
* </body>
|
|
25
|
+
* </html>
|
|
26
|
+
* )
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example With Breadcrumb Tracking
|
|
31
|
+
* ```tsx
|
|
32
|
+
* import { EnhancedErrorBoundary, setupClickTracking, setupFetchTracking } from '@vestig/next/error'
|
|
33
|
+
*
|
|
34
|
+
* // In a client component
|
|
35
|
+
* useEffect(() => {
|
|
36
|
+
* const cleanupClick = setupClickTracking()
|
|
37
|
+
* const cleanupFetch = setupFetchTracking()
|
|
38
|
+
* return () => {
|
|
39
|
+
* cleanupClick()
|
|
40
|
+
* cleanupFetch()
|
|
41
|
+
* }
|
|
42
|
+
* }, [])
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @packageDocumentation
|
|
46
|
+
*/
|
|
47
|
+
export { EnhancedErrorBoundary } from './boundary';
|
|
48
|
+
export { breadcrumbStore, addLogBreadcrumb, addNavigationBreadcrumb, addClickBreadcrumb, addInputBreadcrumb, addFetchBreadcrumb, addErrorBreadcrumb, addCustomBreadcrumb, setupClickTracking, setupFetchTracking, formatBreadcrumbs, getCategoryIcon, } from './breadcrumbs';
|
|
49
|
+
export { parseStackTrace, parseComponentStack, getMostRelevantFrame, formatStackFrame, formatStackTrace, } from './stack-parser';
|
|
50
|
+
export { generateFingerprint, isSameError, groupErrors, } from './fingerprint';
|
|
51
|
+
export type { BreadcrumbCategory, Breadcrumb, StackFrame, EnhancedError, EnhancedErrorBoundaryProps, EnhancedErrorBoundaryState, FingerprintOptions, BreadcrumbStore, } from './types';
|
|
52
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/error/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAKH,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAGlD,OAAO,EACN,eAAe,EACf,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,GACf,MAAM,eAAe,CAAA;AAGtB,OAAO,EACN,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,GAChB,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EACN,mBAAmB,EACnB,WAAW,EACX,WAAW,GACX,MAAM,eAAe,CAAA;AAGtB,YAAY,EACX,kBAAkB,EAClB,UAAU,EACV,UAAU,EACV,aAAa,EACb,0BAA0B,EAC1B,0BAA0B,EAC1B,kBAAkB,EAClB,eAAe,GACf,MAAM,SAAS,CAAA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vestig/next/error - Enhanced Error Handling
|
|
3
|
+
*
|
|
4
|
+
* This module provides enhanced error handling for Next.js applications
|
|
5
|
+
* with rich development experience including:
|
|
6
|
+
*
|
|
7
|
+
* - **Stack trace parsing** with app code highlighting
|
|
8
|
+
* - **Breadcrumb trails** showing events before the error
|
|
9
|
+
* - **Error fingerprinting** for grouping similar errors
|
|
10
|
+
* - **React component tree** visualization
|
|
11
|
+
*
|
|
12
|
+
* @example Basic Usage
|
|
13
|
+
* ```tsx
|
|
14
|
+
* // app/layout.tsx
|
|
15
|
+
* import { EnhancedErrorBoundary } from '@vestig/next/error'
|
|
16
|
+
*
|
|
17
|
+
* export default function RootLayout({ children }) {
|
|
18
|
+
* return (
|
|
19
|
+
* <html>
|
|
20
|
+
* <body>
|
|
21
|
+
* <EnhancedErrorBoundary>
|
|
22
|
+
* {children}
|
|
23
|
+
* </EnhancedErrorBoundary>
|
|
24
|
+
* </body>
|
|
25
|
+
* </html>
|
|
26
|
+
* )
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example With Breadcrumb Tracking
|
|
31
|
+
* ```tsx
|
|
32
|
+
* import { EnhancedErrorBoundary, setupClickTracking, setupFetchTracking } from '@vestig/next/error'
|
|
33
|
+
*
|
|
34
|
+
* // In a client component
|
|
35
|
+
* useEffect(() => {
|
|
36
|
+
* const cleanupClick = setupClickTracking()
|
|
37
|
+
* const cleanupFetch = setupFetchTracking()
|
|
38
|
+
* return () => {
|
|
39
|
+
* cleanupClick()
|
|
40
|
+
* cleanupFetch()
|
|
41
|
+
* }
|
|
42
|
+
* }, [])
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @packageDocumentation
|
|
46
|
+
*/
|
|
47
|
+
'use client';
|
|
48
|
+
// Main error boundary component
|
|
49
|
+
export { EnhancedErrorBoundary } from './boundary';
|
|
50
|
+
// Breadcrumb system
|
|
51
|
+
export { breadcrumbStore, addLogBreadcrumb, addNavigationBreadcrumb, addClickBreadcrumb, addInputBreadcrumb, addFetchBreadcrumb, addErrorBreadcrumb, addCustomBreadcrumb, setupClickTracking, setupFetchTracking, formatBreadcrumbs, getCategoryIcon, } from './breadcrumbs';
|
|
52
|
+
// Stack trace parsing
|
|
53
|
+
export { parseStackTrace, parseComponentStack, getMostRelevantFrame, formatStackFrame, formatStackTrace, } from './stack-parser';
|
|
54
|
+
// Error fingerprinting
|
|
55
|
+
export { generateFingerprint, isSameError, groupErrors, } from './fingerprint';
|
|
56
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/error/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,YAAY,CAAA;AAEZ,gCAAgC;AAChC,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAElD,oBAAoB;AACpB,OAAO,EACN,eAAe,EACf,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,GACf,MAAM,eAAe,CAAA;AAEtB,sBAAsB;AACtB,OAAO,EACN,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,GAChB,MAAM,gBAAgB,CAAA;AAEvB,uBAAuB;AACvB,OAAO,EACN,mBAAmB,EACnB,WAAW,EACX,WAAW,GACX,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stack Trace Parser
|
|
3
|
+
*
|
|
4
|
+
* Parses JavaScript error stack traces into structured frames.
|
|
5
|
+
* Supports Chrome, Firefox, Safari, and Edge stack trace formats.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
import type { StackFrame } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* Parse an error stack trace into structured frames
|
|
12
|
+
*
|
|
13
|
+
* @param stack - The error.stack string
|
|
14
|
+
* @returns Array of parsed stack frames
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* try {
|
|
19
|
+
* throw new Error('Test')
|
|
20
|
+
* } catch (e) {
|
|
21
|
+
* const frames = parseStackTrace(e.stack)
|
|
22
|
+
* // [{ functionName: 'test', fileName: '/app/src/test.ts', lineNumber: 5, ... }]
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseStackTrace(stack: string | undefined): StackFrame[];
|
|
27
|
+
/**
|
|
28
|
+
* Parse React component stack into readable format
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseComponentStack(componentStack: string | undefined): string[];
|
|
31
|
+
/**
|
|
32
|
+
* Get the most relevant stack frame (first app code frame)
|
|
33
|
+
*/
|
|
34
|
+
export declare function getMostRelevantFrame(frames: StackFrame[]): StackFrame | null;
|
|
35
|
+
/**
|
|
36
|
+
* Format a stack frame for display
|
|
37
|
+
*/
|
|
38
|
+
export declare function formatStackFrame(frame: StackFrame): string;
|
|
39
|
+
/**
|
|
40
|
+
* Format entire stack trace for display
|
|
41
|
+
*/
|
|
42
|
+
export declare function formatStackTrace(frames: StackFrame[]): string;
|
|
43
|
+
//# sourceMappingURL=stack-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack-parser.d.ts","sourceRoot":"","sources":["../../src/error/stack-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAkEzC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,EAAE,CAcvE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAsBhF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,GAAG,IAAI,CAW5E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAqB1D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAE7D"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stack Trace Parser
|
|
3
|
+
*
|
|
4
|
+
* Parses JavaScript error stack traces into structured frames.
|
|
5
|
+
* Supports Chrome, Firefox, Safari, and Edge stack trace formats.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Regex patterns for different browser stack trace formats
|
|
11
|
+
*/
|
|
12
|
+
const CHROME_STACK_REGEX = /^\s*at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?$/;
|
|
13
|
+
const FIREFOX_STACK_REGEX = /^(?:(.+)@)?(.+?):(\d+):(\d+)$/;
|
|
14
|
+
const SAFARI_STACK_REGEX = /^(?:(.+)@)?(.+?):(\d+):(\d+)$/;
|
|
15
|
+
/**
|
|
16
|
+
* Check if a file path is from node_modules
|
|
17
|
+
*/
|
|
18
|
+
function isNodeModulePath(path) {
|
|
19
|
+
return path.includes('node_modules') || path.includes('node:');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Check if a file path is from app source code
|
|
23
|
+
*/
|
|
24
|
+
function isAppCodePath(path) {
|
|
25
|
+
// Not from node_modules
|
|
26
|
+
if (isNodeModulePath(path))
|
|
27
|
+
return false;
|
|
28
|
+
// Common app directories
|
|
29
|
+
const appPatterns = ['/src/', '/app/', '/pages/', '/components/', '/lib/', '/utils/', '/hooks/'];
|
|
30
|
+
return appPatterns.some((pattern) => path.includes(pattern));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Parse a single stack frame line
|
|
34
|
+
*/
|
|
35
|
+
function parseStackLine(line) {
|
|
36
|
+
const trimmedLine = line.trim();
|
|
37
|
+
if (!trimmedLine || trimmedLine === 'Error')
|
|
38
|
+
return null;
|
|
39
|
+
// Try Chrome format first (most common)
|
|
40
|
+
let match = CHROME_STACK_REGEX.exec(trimmedLine);
|
|
41
|
+
if (match) {
|
|
42
|
+
const [, functionName, fileName, lineNumber, columnNumber] = match;
|
|
43
|
+
return {
|
|
44
|
+
functionName: functionName?.trim(),
|
|
45
|
+
fileName: fileName,
|
|
46
|
+
lineNumber: parseInt(lineNumber ?? '0', 10),
|
|
47
|
+
columnNumber: parseInt(columnNumber ?? '0', 10),
|
|
48
|
+
isNodeModule: isNodeModulePath(fileName ?? ''),
|
|
49
|
+
isAppCode: isAppCodePath(fileName ?? ''),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// Try Firefox/Safari format
|
|
53
|
+
match = FIREFOX_STACK_REGEX.exec(trimmedLine);
|
|
54
|
+
if (match) {
|
|
55
|
+
const [, functionName, fileName, lineNumber, columnNumber] = match;
|
|
56
|
+
return {
|
|
57
|
+
functionName: functionName?.trim(),
|
|
58
|
+
fileName: fileName,
|
|
59
|
+
lineNumber: parseInt(lineNumber ?? '0', 10),
|
|
60
|
+
columnNumber: parseInt(columnNumber ?? '0', 10),
|
|
61
|
+
isNodeModule: isNodeModulePath(fileName ?? ''),
|
|
62
|
+
isAppCode: isAppCodePath(fileName ?? ''),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Parse an error stack trace into structured frames
|
|
69
|
+
*
|
|
70
|
+
* @param stack - The error.stack string
|
|
71
|
+
* @returns Array of parsed stack frames
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* try {
|
|
76
|
+
* throw new Error('Test')
|
|
77
|
+
* } catch (e) {
|
|
78
|
+
* const frames = parseStackTrace(e.stack)
|
|
79
|
+
* // [{ functionName: 'test', fileName: '/app/src/test.ts', lineNumber: 5, ... }]
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export function parseStackTrace(stack) {
|
|
84
|
+
if (!stack)
|
|
85
|
+
return [];
|
|
86
|
+
const lines = stack.split('\n');
|
|
87
|
+
const frames = [];
|
|
88
|
+
for (const line of lines) {
|
|
89
|
+
const frame = parseStackLine(line);
|
|
90
|
+
if (frame) {
|
|
91
|
+
frames.push(frame);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return frames;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Parse React component stack into readable format
|
|
98
|
+
*/
|
|
99
|
+
export function parseComponentStack(componentStack) {
|
|
100
|
+
if (!componentStack)
|
|
101
|
+
return [];
|
|
102
|
+
const lines = componentStack.split('\n');
|
|
103
|
+
const components = [];
|
|
104
|
+
for (const line of lines) {
|
|
105
|
+
const trimmed = line.trim();
|
|
106
|
+
if (!trimmed)
|
|
107
|
+
continue;
|
|
108
|
+
// Extract component name from "at ComponentName (file:line:col)"
|
|
109
|
+
const match = /^at\s+(\w+)/.exec(trimmed);
|
|
110
|
+
if (match?.[1]) {
|
|
111
|
+
components.push(match[1]);
|
|
112
|
+
}
|
|
113
|
+
else if (trimmed.startsWith('in ')) {
|
|
114
|
+
// Alternative format: "in ComponentName"
|
|
115
|
+
const componentName = trimmed.slice(3).split(' ')[0];
|
|
116
|
+
if (componentName)
|
|
117
|
+
components.push(componentName);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return components;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get the most relevant stack frame (first app code frame)
|
|
124
|
+
*/
|
|
125
|
+
export function getMostRelevantFrame(frames) {
|
|
126
|
+
// First, try to find an app code frame
|
|
127
|
+
const appFrame = frames.find((f) => f.isAppCode);
|
|
128
|
+
if (appFrame)
|
|
129
|
+
return appFrame;
|
|
130
|
+
// Fall back to first non-node_modules frame
|
|
131
|
+
const nonModuleFrame = frames.find((f) => !f.isNodeModule);
|
|
132
|
+
if (nonModuleFrame)
|
|
133
|
+
return nonModuleFrame;
|
|
134
|
+
// Last resort: first frame
|
|
135
|
+
return frames[0] ?? null;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Format a stack frame for display
|
|
139
|
+
*/
|
|
140
|
+
export function formatStackFrame(frame) {
|
|
141
|
+
const parts = [];
|
|
142
|
+
if (frame.functionName) {
|
|
143
|
+
parts.push(frame.functionName);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
parts.push('<anonymous>');
|
|
147
|
+
}
|
|
148
|
+
if (frame.fileName) {
|
|
149
|
+
let location = frame.fileName;
|
|
150
|
+
if (frame.lineNumber) {
|
|
151
|
+
location += `:${frame.lineNumber}`;
|
|
152
|
+
if (frame.columnNumber) {
|
|
153
|
+
location += `:${frame.columnNumber}`;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
parts.push(`(${location})`);
|
|
157
|
+
}
|
|
158
|
+
return parts.join(' ');
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Format entire stack trace for display
|
|
162
|
+
*/
|
|
163
|
+
export function formatStackTrace(frames) {
|
|
164
|
+
return frames.map((frame, i) => ` at ${formatStackFrame(frame)}`).join('\n');
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=stack-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack-parser.js","sourceRoot":"","sources":["../../src/error/stack-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Types for Better Error DX
|
|
3
|
+
*
|
|
4
|
+
* Types for enhanced error handling with source maps,
|
|
5
|
+
* breadcrumbs, and fingerprinting.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Breadcrumb categories for filtering
|
|
11
|
+
*/
|
|
12
|
+
export type BreadcrumbCategory = 'log' | 'navigation' | 'click' | 'input' | 'fetch' | 'error' | 'custom';
|
|
13
|
+
/**
|
|
14
|
+
* Enhanced breadcrumb with more context
|
|
15
|
+
*/
|
|
16
|
+
export interface Breadcrumb {
|
|
17
|
+
/** Unique ID */
|
|
18
|
+
id: string;
|
|
19
|
+
/** ISO timestamp */
|
|
20
|
+
timestamp: string;
|
|
21
|
+
/** Breadcrumb category */
|
|
22
|
+
category: BreadcrumbCategory;
|
|
23
|
+
/** Log level (for log breadcrumbs) */
|
|
24
|
+
level?: 'trace' | 'debug' | 'info' | 'warn' | 'error';
|
|
25
|
+
/** Human-readable message */
|
|
26
|
+
message: string;
|
|
27
|
+
/** Logger namespace */
|
|
28
|
+
namespace?: string;
|
|
29
|
+
/** Additional data */
|
|
30
|
+
data?: Record<string, unknown>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Parsed stack frame from error stack trace
|
|
34
|
+
*/
|
|
35
|
+
export interface StackFrame {
|
|
36
|
+
/** Function name (if available) */
|
|
37
|
+
functionName?: string;
|
|
38
|
+
/** File path */
|
|
39
|
+
fileName?: string;
|
|
40
|
+
/** Line number (1-indexed) */
|
|
41
|
+
lineNumber?: number;
|
|
42
|
+
/** Column number (1-indexed) */
|
|
43
|
+
columnNumber?: number;
|
|
44
|
+
/** Whether this is from node_modules */
|
|
45
|
+
isNodeModule: boolean;
|
|
46
|
+
/** Whether this is from the app's source code */
|
|
47
|
+
isAppCode: boolean;
|
|
48
|
+
/** Source code context (if available via source maps) */
|
|
49
|
+
sourceContext?: {
|
|
50
|
+
/** Lines before the error line */
|
|
51
|
+
pre: string[];
|
|
52
|
+
/** The error line */
|
|
53
|
+
line: string;
|
|
54
|
+
/** Lines after the error line */
|
|
55
|
+
post: string[];
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Enhanced error with parsed stack and fingerprint
|
|
60
|
+
*/
|
|
61
|
+
export interface EnhancedError {
|
|
62
|
+
/** Original error */
|
|
63
|
+
error: Error;
|
|
64
|
+
/** Error fingerprint for grouping */
|
|
65
|
+
fingerprint: string;
|
|
66
|
+
/** Parsed stack frames */
|
|
67
|
+
frames: StackFrame[];
|
|
68
|
+
/** React component stack */
|
|
69
|
+
componentStack?: string;
|
|
70
|
+
/** Breadcrumbs leading up to the error */
|
|
71
|
+
breadcrumbs: Breadcrumb[];
|
|
72
|
+
/** Timestamp when error occurred */
|
|
73
|
+
timestamp: string;
|
|
74
|
+
/** Browser/environment info */
|
|
75
|
+
environment: {
|
|
76
|
+
userAgent: string;
|
|
77
|
+
url: string;
|
|
78
|
+
pathname: string;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Props for enhanced error boundary
|
|
83
|
+
*/
|
|
84
|
+
export interface EnhancedErrorBoundaryProps {
|
|
85
|
+
children: React.ReactNode;
|
|
86
|
+
/**
|
|
87
|
+
* Custom fallback UI
|
|
88
|
+
*/
|
|
89
|
+
fallback?: React.ReactNode | ((error: EnhancedError) => React.ReactNode);
|
|
90
|
+
/**
|
|
91
|
+
* Callback when error is caught
|
|
92
|
+
*/
|
|
93
|
+
onError?: (error: EnhancedError) => void;
|
|
94
|
+
/**
|
|
95
|
+
* Maximum breadcrumbs to keep
|
|
96
|
+
* @default 50
|
|
97
|
+
*/
|
|
98
|
+
maxBreadcrumbs?: number;
|
|
99
|
+
/**
|
|
100
|
+
* Show source code context in development
|
|
101
|
+
* @default true in development
|
|
102
|
+
*/
|
|
103
|
+
showSourceContext?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Show breadcrumbs in error UI
|
|
106
|
+
* @default true in development
|
|
107
|
+
*/
|
|
108
|
+
showBreadcrumbs?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Categories of breadcrumbs to capture
|
|
111
|
+
* @default all categories
|
|
112
|
+
*/
|
|
113
|
+
breadcrumbCategories?: BreadcrumbCategory[];
|
|
114
|
+
/**
|
|
115
|
+
* Report errors to endpoint
|
|
116
|
+
*/
|
|
117
|
+
reportEndpoint?: string;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* State for enhanced error boundary
|
|
121
|
+
*/
|
|
122
|
+
export interface EnhancedErrorBoundaryState {
|
|
123
|
+
hasError: boolean;
|
|
124
|
+
enhancedError: EnhancedError | null;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Options for error fingerprinting
|
|
128
|
+
*/
|
|
129
|
+
export interface FingerprintOptions {
|
|
130
|
+
/** Include file paths in fingerprint */
|
|
131
|
+
includeFilePaths?: boolean;
|
|
132
|
+
/** Include line numbers in fingerprint */
|
|
133
|
+
includeLineNumbers?: boolean;
|
|
134
|
+
/** Maximum stack frames to consider */
|
|
135
|
+
maxFrames?: number;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Breadcrumb store interface
|
|
139
|
+
*/
|
|
140
|
+
export interface BreadcrumbStore {
|
|
141
|
+
/** Add a breadcrumb */
|
|
142
|
+
add: (breadcrumb: Omit<Breadcrumb, 'id' | 'timestamp'>) => void;
|
|
143
|
+
/** Get all breadcrumbs */
|
|
144
|
+
getAll: () => Breadcrumb[];
|
|
145
|
+
/** Get breadcrumbs by category */
|
|
146
|
+
getByCategory: (category: BreadcrumbCategory) => Breadcrumb[];
|
|
147
|
+
/** Clear all breadcrumbs */
|
|
148
|
+
clear: () => void;
|
|
149
|
+
/** Set maximum breadcrumbs */
|
|
150
|
+
setMaxSize: (size: number) => void;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=types.d.ts.map
|