@vestig/next 0.6.0 → 0.9.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 +50 -0
- package/dist/client/transport.d.ts.map +1 -1
- package/dist/client/transport.js +200 -3
- 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 +100 -0
- package/dist/dev/filters.js.map +1 -0
- package/dist/dev/hooks/use-logs.d.ts +55 -0
- package/dist/dev/hooks/use-logs.d.ts.map +1 -0
- package/dist/dev/hooks/use-logs.js +202 -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 +216 -0
- package/dist/dev/overlay.js.map +1 -0
- package/dist/dev/store.d.ts +126 -0
- package/dist/dev/store.d.ts.map +1 -0
- package/dist/dev/store.js +210 -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 +93 -0
- package/dist/metrics/hooks/use-route-metrics.d.ts.map +1 -0
- package/dist/metrics/hooks/use-route-metrics.js +217 -0
- package/dist/metrics/hooks/use-route-metrics.js.map +1 -0
- package/dist/metrics/hooks/use-web-vitals.d.ts +73 -0
- package/dist/metrics/hooks/use-web-vitals.d.ts.map +1 -0
- package/dist/metrics/hooks/use-web-vitals.js +141 -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 +67 -0
- package/dist/metrics/store.d.ts.map +1 -0
- package/dist/metrics/store.js +187 -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 +215 -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,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Breadcrumb System
|
|
3
|
+
*
|
|
4
|
+
* Captures user actions and events leading up to an error.
|
|
5
|
+
* Provides context for debugging by showing what happened before the crash.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Create a unique breadcrumb ID
|
|
11
|
+
*/
|
|
12
|
+
function createBreadcrumbId() {
|
|
13
|
+
return `bc_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 5)}`;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create the breadcrumb store
|
|
17
|
+
*/
|
|
18
|
+
function createBreadcrumbStore() {
|
|
19
|
+
let breadcrumbs = [];
|
|
20
|
+
let maxSize = 50;
|
|
21
|
+
return {
|
|
22
|
+
add(entry) {
|
|
23
|
+
const breadcrumb = {
|
|
24
|
+
...entry,
|
|
25
|
+
id: createBreadcrumbId(),
|
|
26
|
+
timestamp: new Date().toISOString(),
|
|
27
|
+
};
|
|
28
|
+
breadcrumbs.push(breadcrumb);
|
|
29
|
+
// Trim to max size
|
|
30
|
+
if (breadcrumbs.length > maxSize) {
|
|
31
|
+
breadcrumbs = breadcrumbs.slice(-maxSize);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
getAll() {
|
|
35
|
+
return [...breadcrumbs];
|
|
36
|
+
},
|
|
37
|
+
getByCategory(category) {
|
|
38
|
+
return breadcrumbs.filter((b) => b.category === category);
|
|
39
|
+
},
|
|
40
|
+
clear() {
|
|
41
|
+
breadcrumbs = [];
|
|
42
|
+
},
|
|
43
|
+
setMaxSize(size) {
|
|
44
|
+
maxSize = size;
|
|
45
|
+
if (breadcrumbs.length > maxSize) {
|
|
46
|
+
breadcrumbs = breadcrumbs.slice(-maxSize);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Global breadcrumb store singleton
|
|
53
|
+
*/
|
|
54
|
+
export const breadcrumbStore = createBreadcrumbStore();
|
|
55
|
+
/**
|
|
56
|
+
* Add a log breadcrumb
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* addLogBreadcrumb('info', 'User clicked button', 'ui')
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export function addLogBreadcrumb(level, message, namespace, data) {
|
|
64
|
+
breadcrumbStore.add({
|
|
65
|
+
category: 'log',
|
|
66
|
+
level,
|
|
67
|
+
message,
|
|
68
|
+
namespace,
|
|
69
|
+
data,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Add a navigation breadcrumb
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* addNavigationBreadcrumb('/dashboard', '/settings')
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export function addNavigationBreadcrumb(from, to) {
|
|
81
|
+
breadcrumbStore.add({
|
|
82
|
+
category: 'navigation',
|
|
83
|
+
message: `Navigated from ${from} to ${to}`,
|
|
84
|
+
data: { from, to },
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Add a click breadcrumb
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* addClickBreadcrumb('Submit button', 'button#submit')
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export function addClickBreadcrumb(elementDescription, selector) {
|
|
96
|
+
breadcrumbStore.add({
|
|
97
|
+
category: 'click',
|
|
98
|
+
message: `Clicked: ${elementDescription}`,
|
|
99
|
+
data: selector ? { selector } : undefined,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Add an input breadcrumb (sanitizes sensitive data)
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* addInputBreadcrumb('email', 'user@example.com', 'input#email')
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export function addInputBreadcrumb(fieldName, value, selector) {
|
|
111
|
+
// Sanitize potentially sensitive fields
|
|
112
|
+
const sensitiveFields = ['password', 'token', 'secret', 'key', 'credit', 'card', 'ssn', 'cvv'];
|
|
113
|
+
const isSensitive = sensitiveFields.some((f) => fieldName.toLowerCase().includes(f));
|
|
114
|
+
breadcrumbStore.add({
|
|
115
|
+
category: 'input',
|
|
116
|
+
message: `Input: ${fieldName}`,
|
|
117
|
+
data: {
|
|
118
|
+
field: fieldName,
|
|
119
|
+
value: isSensitive ? '[REDACTED]' : value,
|
|
120
|
+
selector,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Add a fetch/API breadcrumb
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```ts
|
|
129
|
+
* addFetchBreadcrumb('GET', '/api/users', 200, 150)
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
export function addFetchBreadcrumb(method, url, status, durationMs) {
|
|
133
|
+
breadcrumbStore.add({
|
|
134
|
+
category: 'fetch',
|
|
135
|
+
message: `${method} ${url}${status ? ` → ${status}` : ''}`,
|
|
136
|
+
data: {
|
|
137
|
+
method,
|
|
138
|
+
url,
|
|
139
|
+
status,
|
|
140
|
+
durationMs,
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Add an error breadcrumb (for non-fatal errors)
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```ts
|
|
149
|
+
* addErrorBreadcrumb('Failed to load user preferences', error)
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
export function addErrorBreadcrumb(message, error) {
|
|
153
|
+
breadcrumbStore.add({
|
|
154
|
+
category: 'error',
|
|
155
|
+
level: 'error',
|
|
156
|
+
message,
|
|
157
|
+
data: error
|
|
158
|
+
? {
|
|
159
|
+
name: error.name,
|
|
160
|
+
message: error.message,
|
|
161
|
+
}
|
|
162
|
+
: undefined,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Add a custom breadcrumb
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```ts
|
|
170
|
+
* addCustomBreadcrumb('Feature flag enabled', { flag: 'new-dashboard' })
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
export function addCustomBreadcrumb(message, data) {
|
|
174
|
+
breadcrumbStore.add({
|
|
175
|
+
category: 'custom',
|
|
176
|
+
message,
|
|
177
|
+
data,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Setup automatic click tracking
|
|
182
|
+
* Call this once in your app to capture click breadcrumbs
|
|
183
|
+
*/
|
|
184
|
+
export function setupClickTracking() {
|
|
185
|
+
if (typeof document === 'undefined')
|
|
186
|
+
return () => { };
|
|
187
|
+
const handleClick = (event) => {
|
|
188
|
+
const target = event.target;
|
|
189
|
+
if (!target)
|
|
190
|
+
return;
|
|
191
|
+
// Get a description of the clicked element
|
|
192
|
+
let description = target.tagName.toLowerCase();
|
|
193
|
+
// Add text content if short enough
|
|
194
|
+
const textContent = target.textContent?.trim();
|
|
195
|
+
if (textContent && textContent.length < 50) {
|
|
196
|
+
description += `: "${textContent.slice(0, 30)}${textContent.length > 30 ? '...' : ''}"`;
|
|
197
|
+
}
|
|
198
|
+
// Add id or class for identification
|
|
199
|
+
if (target.id) {
|
|
200
|
+
description += ` #${target.id}`;
|
|
201
|
+
}
|
|
202
|
+
else if (target.className && typeof target.className === 'string') {
|
|
203
|
+
const firstClass = target.className.split(' ')[0];
|
|
204
|
+
if (firstClass)
|
|
205
|
+
description += ` .${firstClass}`;
|
|
206
|
+
}
|
|
207
|
+
// Build selector
|
|
208
|
+
let selector = target.tagName.toLowerCase();
|
|
209
|
+
if (target.id)
|
|
210
|
+
selector += `#${target.id}`;
|
|
211
|
+
addClickBreadcrumb(description, selector);
|
|
212
|
+
};
|
|
213
|
+
document.addEventListener('click', handleClick, { capture: true, passive: true });
|
|
214
|
+
return () => {
|
|
215
|
+
document.removeEventListener('click', handleClick, { capture: true });
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Setup automatic fetch tracking
|
|
220
|
+
* Patches global fetch to capture API call breadcrumbs
|
|
221
|
+
*/
|
|
222
|
+
export function setupFetchTracking() {
|
|
223
|
+
if (typeof window === 'undefined')
|
|
224
|
+
return () => { };
|
|
225
|
+
const originalFetch = window.fetch;
|
|
226
|
+
window.fetch = async function (input, init) {
|
|
227
|
+
const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;
|
|
228
|
+
const method = init?.method ?? 'GET';
|
|
229
|
+
const startTime = performance.now();
|
|
230
|
+
try {
|
|
231
|
+
const response = await originalFetch.call(this, input, init);
|
|
232
|
+
const duration = performance.now() - startTime;
|
|
233
|
+
addFetchBreadcrumb(method, url, response.status, duration);
|
|
234
|
+
return response;
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
const duration = performance.now() - startTime;
|
|
238
|
+
addFetchBreadcrumb(method, url, 0, duration);
|
|
239
|
+
throw error;
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
return () => {
|
|
243
|
+
window.fetch = originalFetch;
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Format breadcrumbs for display
|
|
248
|
+
*/
|
|
249
|
+
export function formatBreadcrumbs(breadcrumbs) {
|
|
250
|
+
return breadcrumbs
|
|
251
|
+
.map((b) => {
|
|
252
|
+
const time = new Date(b.timestamp).toLocaleTimeString();
|
|
253
|
+
const prefix = b.level ? `[${b.level.toUpperCase()}]` : `[${b.category.toUpperCase()}]`;
|
|
254
|
+
return `${time} ${prefix} ${b.message}`;
|
|
255
|
+
})
|
|
256
|
+
.join('\n');
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Get category icon for display
|
|
260
|
+
*/
|
|
261
|
+
export function getCategoryIcon(category) {
|
|
262
|
+
const icons = {
|
|
263
|
+
log: '📝',
|
|
264
|
+
navigation: '🧭',
|
|
265
|
+
click: '👆',
|
|
266
|
+
input: '⌨️',
|
|
267
|
+
fetch: '🌐',
|
|
268
|
+
error: '❌',
|
|
269
|
+
custom: '📌',
|
|
270
|
+
};
|
|
271
|
+
return icons[category];
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=breadcrumbs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breadcrumbs.js","sourceRoot":"","sources":["../../src/error/breadcrumbs.ts"],"names":[],"mappings":"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"}
|
|
@@ -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":"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"}
|
|
@@ -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"}
|