@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.
Files changed (144) hide show
  1. package/README.md +1 -1
  2. package/dist/__tests__/mocks/next-server.d.ts.map +1 -1
  3. package/dist/__tests__/mocks/next-server.js.map +1 -1
  4. package/dist/client/error-boundary.d.ts +80 -0
  5. package/dist/client/error-boundary.d.ts.map +1 -0
  6. package/dist/client/error-boundary.js +182 -0
  7. package/dist/client/error-boundary.js.map +1 -0
  8. package/dist/client/index.d.ts +2 -1
  9. package/dist/client/index.d.ts.map +1 -1
  10. package/dist/client/index.js +2 -0
  11. package/dist/client/index.js.map +1 -1
  12. package/dist/client/transport.d.ts +42 -0
  13. package/dist/client/transport.d.ts.map +1 -1
  14. package/dist/client/transport.js +143 -2
  15. package/dist/client/transport.js.map +1 -1
  16. package/dist/client.d.ts +2 -1
  17. package/dist/client.d.ts.map +1 -1
  18. package/dist/client.js +2 -0
  19. package/dist/client.js.map +1 -1
  20. package/dist/db/drizzle.d.ts +115 -0
  21. package/dist/db/drizzle.d.ts.map +1 -0
  22. package/dist/db/drizzle.js +174 -0
  23. package/dist/db/drizzle.js.map +1 -0
  24. package/dist/db/index.d.ts +49 -0
  25. package/dist/db/index.d.ts.map +1 -0
  26. package/dist/db/index.js +51 -0
  27. package/dist/db/index.js.map +1 -0
  28. package/dist/db/prisma.d.ts +114 -0
  29. package/dist/db/prisma.d.ts.map +1 -0
  30. package/dist/db/prisma.js +144 -0
  31. package/dist/db/prisma.js.map +1 -0
  32. package/dist/db/query-logger.d.ts +30 -0
  33. package/dist/db/query-logger.d.ts.map +1 -0
  34. package/dist/db/query-logger.js +169 -0
  35. package/dist/db/query-logger.js.map +1 -0
  36. package/dist/db/types.d.ts +102 -0
  37. package/dist/db/types.d.ts.map +1 -0
  38. package/dist/db/types.js +28 -0
  39. package/dist/db/types.js.map +1 -0
  40. package/dist/dev/api/index.d.ts +13 -0
  41. package/dist/dev/api/index.d.ts.map +1 -0
  42. package/dist/dev/api/index.js +13 -0
  43. package/dist/dev/api/index.js.map +1 -0
  44. package/dist/dev/api/logs-stream.d.ts +119 -0
  45. package/dist/dev/api/logs-stream.d.ts.map +1 -0
  46. package/dist/dev/api/logs-stream.js +156 -0
  47. package/dist/dev/api/logs-stream.js.map +1 -0
  48. package/dist/dev/filters.d.ts +17 -0
  49. package/dist/dev/filters.d.ts.map +1 -0
  50. package/dist/dev/filters.js +96 -0
  51. package/dist/dev/filters.js.map +1 -0
  52. package/dist/dev/hooks/use-logs.d.ts +53 -0
  53. package/dist/dev/hooks/use-logs.d.ts.map +1 -0
  54. package/dist/dev/hooks/use-logs.js +205 -0
  55. package/dist/dev/hooks/use-logs.js.map +1 -0
  56. package/dist/dev/index.d.ts +35 -0
  57. package/dist/dev/index.d.ts.map +1 -0
  58. package/dist/dev/index.js +41 -0
  59. package/dist/dev/index.js.map +1 -0
  60. package/dist/dev/log-entry.d.ts +12 -0
  61. package/dist/dev/log-entry.d.ts.map +1 -0
  62. package/dist/dev/log-entry.js +152 -0
  63. package/dist/dev/log-entry.js.map +1 -0
  64. package/dist/dev/log-viewer.d.ts +11 -0
  65. package/dist/dev/log-viewer.d.ts.map +1 -0
  66. package/dist/dev/log-viewer.js +49 -0
  67. package/dist/dev/log-viewer.js.map +1 -0
  68. package/dist/dev/metrics-card.d.ts +18 -0
  69. package/dist/dev/metrics-card.d.ts.map +1 -0
  70. package/dist/dev/metrics-card.js +75 -0
  71. package/dist/dev/metrics-card.js.map +1 -0
  72. package/dist/dev/metrics-histogram.d.ts +12 -0
  73. package/dist/dev/metrics-histogram.d.ts.map +1 -0
  74. package/dist/dev/metrics-histogram.js +69 -0
  75. package/dist/dev/metrics-histogram.js.map +1 -0
  76. package/dist/dev/metrics-panel.d.ts +10 -0
  77. package/dist/dev/metrics-panel.d.ts.map +1 -0
  78. package/dist/dev/metrics-panel.js +84 -0
  79. package/dist/dev/metrics-panel.js.map +1 -0
  80. package/dist/dev/overlay.d.ts +55 -0
  81. package/dist/dev/overlay.d.ts.map +1 -0
  82. package/dist/dev/overlay.js +204 -0
  83. package/dist/dev/overlay.js.map +1 -0
  84. package/dist/dev/store.d.ts +186 -0
  85. package/dist/dev/store.d.ts.map +1 -0
  86. package/dist/dev/store.js +214 -0
  87. package/dist/dev/store.js.map +1 -0
  88. package/dist/error/boundary.d.ts +36 -0
  89. package/dist/error/boundary.d.ts.map +1 -0
  90. package/dist/error/boundary.js +263 -0
  91. package/dist/error/boundary.js.map +1 -0
  92. package/dist/error/breadcrumbs.d.ts +95 -0
  93. package/dist/error/breadcrumbs.d.ts.map +1 -0
  94. package/dist/error/breadcrumbs.js +273 -0
  95. package/dist/error/breadcrumbs.js.map +1 -0
  96. package/dist/error/fingerprint.d.ts +42 -0
  97. package/dist/error/fingerprint.d.ts.map +1 -0
  98. package/dist/error/fingerprint.js +135 -0
  99. package/dist/error/fingerprint.js.map +1 -0
  100. package/dist/error/index.d.ts +52 -0
  101. package/dist/error/index.d.ts.map +1 -0
  102. package/dist/error/index.js +56 -0
  103. package/dist/error/index.js.map +1 -0
  104. package/dist/error/stack-parser.d.ts +43 -0
  105. package/dist/error/stack-parser.d.ts.map +1 -0
  106. package/dist/error/stack-parser.js +166 -0
  107. package/dist/error/stack-parser.js.map +1 -0
  108. package/dist/error/types.d.ts +152 -0
  109. package/dist/error/types.d.ts.map +1 -0
  110. package/dist/error/types.js +10 -0
  111. package/dist/error/types.js.map +1 -0
  112. package/dist/metrics/hooks/use-route-metrics.d.ts +91 -0
  113. package/dist/metrics/hooks/use-route-metrics.d.ts.map +1 -0
  114. package/dist/metrics/hooks/use-route-metrics.js +216 -0
  115. package/dist/metrics/hooks/use-route-metrics.js.map +1 -0
  116. package/dist/metrics/hooks/use-web-vitals.d.ts +70 -0
  117. package/dist/metrics/hooks/use-web-vitals.d.ts.map +1 -0
  118. package/dist/metrics/hooks/use-web-vitals.js +146 -0
  119. package/dist/metrics/hooks/use-web-vitals.js.map +1 -0
  120. package/dist/metrics/index.d.ts +51 -0
  121. package/dist/metrics/index.d.ts.map +1 -0
  122. package/dist/metrics/index.js +56 -0
  123. package/dist/metrics/index.js.map +1 -0
  124. package/dist/metrics/reporter.d.ts +87 -0
  125. package/dist/metrics/reporter.d.ts.map +1 -0
  126. package/dist/metrics/reporter.js +178 -0
  127. package/dist/metrics/reporter.js.map +1 -0
  128. package/dist/metrics/store.d.ts +34 -0
  129. package/dist/metrics/store.d.ts.map +1 -0
  130. package/dist/metrics/store.js +172 -0
  131. package/dist/metrics/store.js.map +1 -0
  132. package/dist/metrics/thresholds.d.ts +84 -0
  133. package/dist/metrics/thresholds.d.ts.map +1 -0
  134. package/dist/metrics/thresholds.js +148 -0
  135. package/dist/metrics/thresholds.js.map +1 -0
  136. package/dist/metrics/types.d.ts +211 -0
  137. package/dist/metrics/types.d.ts.map +1 -0
  138. package/dist/metrics/types.js +10 -0
  139. package/dist/metrics/types.js.map +1 -0
  140. package/dist/metrics/web-vitals.d.ts +72 -0
  141. package/dist/metrics/web-vitals.d.ts.map +1 -0
  142. package/dist/metrics/web-vitals.js +89 -0
  143. package/dist/metrics/web-vitals.js.map +1 -0
  144. package/package.json +28 -6
@@ -0,0 +1,263 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Component } from 'react';
4
+ import { parseStackTrace, parseComponentStack, getMostRelevantFrame } from './stack-parser';
5
+ import { generateFingerprint } from './fingerprint';
6
+ import { breadcrumbStore, getCategoryIcon } from './breadcrumbs';
7
+ /**
8
+ * Create an enhanced error object with all context
9
+ */
10
+ function createEnhancedError(error, errorInfo) {
11
+ const frames = parseStackTrace(error.stack);
12
+ const fingerprint = generateFingerprint(error, frames);
13
+ const breadcrumbs = breadcrumbStore.getAll();
14
+ return {
15
+ error,
16
+ fingerprint,
17
+ frames,
18
+ componentStack: errorInfo.componentStack ?? undefined,
19
+ breadcrumbs,
20
+ timestamp: new Date().toISOString(),
21
+ environment: {
22
+ userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'unknown',
23
+ url: typeof window !== 'undefined' ? window.location.href : 'unknown',
24
+ pathname: typeof window !== 'undefined' ? window.location.pathname : 'unknown',
25
+ },
26
+ };
27
+ }
28
+ /**
29
+ * Development Error UI Component
30
+ */
31
+ function DevErrorUI({ enhancedError, onReset, showBreadcrumbs = true, }) {
32
+ const { error, frames, componentStack, breadcrumbs, fingerprint } = enhancedError;
33
+ const relevantFrame = getMostRelevantFrame(frames);
34
+ const componentNames = parseComponentStack(componentStack);
35
+ const containerStyle = {
36
+ position: 'fixed',
37
+ inset: 0,
38
+ backgroundColor: 'rgba(0, 0, 0, 0.85)',
39
+ zIndex: 99999,
40
+ overflow: 'auto',
41
+ fontFamily: 'system-ui, -apple-system, sans-serif',
42
+ };
43
+ const contentStyle = {
44
+ maxWidth: '900px',
45
+ margin: '40px auto',
46
+ padding: '24px',
47
+ backgroundColor: '#1a1a2e',
48
+ borderRadius: '12px',
49
+ color: '#e4e4e7',
50
+ };
51
+ const headerStyle = {
52
+ display: 'flex',
53
+ alignItems: 'flex-start',
54
+ gap: '16px',
55
+ marginBottom: '24px',
56
+ paddingBottom: '16px',
57
+ borderBottom: '1px solid rgba(255, 255, 255, 0.1)',
58
+ };
59
+ const errorIconStyle = {
60
+ width: '48px',
61
+ height: '48px',
62
+ borderRadius: '50%',
63
+ backgroundColor: '#dc2626',
64
+ display: 'flex',
65
+ alignItems: 'center',
66
+ justifyContent: 'center',
67
+ fontSize: '24px',
68
+ flexShrink: 0,
69
+ };
70
+ const errorTitleStyle = {
71
+ fontSize: '20px',
72
+ fontWeight: 700,
73
+ color: '#fca5a5',
74
+ margin: 0,
75
+ };
76
+ const errorMessageStyle = {
77
+ fontSize: '16px',
78
+ color: '#e4e4e7',
79
+ margin: '8px 0 0',
80
+ lineHeight: 1.5,
81
+ };
82
+ const sectionStyle = {
83
+ marginBottom: '20px',
84
+ };
85
+ const sectionTitleStyle = {
86
+ fontSize: '12px',
87
+ fontWeight: 600,
88
+ textTransform: 'uppercase',
89
+ letterSpacing: '0.05em',
90
+ color: '#a1a1aa',
91
+ marginBottom: '8px',
92
+ };
93
+ const codeBlockStyle = {
94
+ backgroundColor: '#0f0f1a',
95
+ borderRadius: '8px',
96
+ padding: '12px',
97
+ fontSize: '13px',
98
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
99
+ overflow: 'auto',
100
+ maxHeight: '200px',
101
+ };
102
+ const frameStyle = (isAppCode) => ({
103
+ padding: '4px 0',
104
+ color: isAppCode ? '#93c5fd' : '#71717a',
105
+ borderLeft: isAppCode ? '2px solid #3b82f6' : '2px solid transparent',
106
+ paddingLeft: '8px',
107
+ });
108
+ const componentStyle = {
109
+ display: 'inline-block',
110
+ padding: '2px 8px',
111
+ margin: '2px',
112
+ backgroundColor: 'rgba(139, 92, 246, 0.2)',
113
+ borderRadius: '4px',
114
+ fontSize: '12px',
115
+ color: '#c4b5fd',
116
+ };
117
+ const breadcrumbStyle = {
118
+ display: 'flex',
119
+ alignItems: 'flex-start',
120
+ gap: '8px',
121
+ padding: '6px 0',
122
+ borderBottom: '1px solid rgba(255, 255, 255, 0.05)',
123
+ fontSize: '12px',
124
+ };
125
+ const buttonStyle = {
126
+ padding: '10px 20px',
127
+ backgroundColor: '#3b82f6',
128
+ color: 'white',
129
+ border: 'none',
130
+ borderRadius: '6px',
131
+ fontSize: '14px',
132
+ fontWeight: 500,
133
+ cursor: 'pointer',
134
+ };
135
+ const fingerprintStyle = {
136
+ fontSize: '11px',
137
+ color: '#71717a',
138
+ fontFamily: 'monospace',
139
+ };
140
+ return (_jsx("div", { style: containerStyle, children: _jsxs("div", { style: contentStyle, children: [_jsxs("div", { style: headerStyle, children: [_jsx("div", { style: errorIconStyle, children: "\uD83D\uDCA5" }), _jsxs("div", { style: { flex: 1 }, children: [_jsx("h1", { style: errorTitleStyle, children: error.name }), _jsx("p", { style: errorMessageStyle, children: error.message }), relevantFrame && (_jsxs("p", { style: { ...fingerprintStyle, marginTop: '8px' }, children: [relevantFrame.fileName, ":", relevantFrame.lineNumber] }))] }), _jsx("button", { style: buttonStyle, onClick: onReset, children: "Try Again" })] }), componentNames.length > 0 && (_jsxs("div", { style: sectionStyle, children: [_jsx("div", { style: sectionTitleStyle, children: "Component Tree" }), _jsx("div", { children: componentNames.map((name, i) => (_jsx("span", { style: componentStyle, children: name }, i))) })] })), _jsxs("div", { style: sectionStyle, children: [_jsx("div", { style: sectionTitleStyle, children: "Stack Trace" }), _jsx("div", { style: codeBlockStyle, children: frames.slice(0, 10).map((frame, i) => (_jsxs("div", { style: frameStyle(frame.isAppCode), children: [frame.functionName || '<anonymous>', ' ', _jsxs("span", { style: { color: '#52525b' }, children: ["(", frame.fileName, ":", frame.lineNumber, ")"] })] }, i))) })] }), showBreadcrumbs && breadcrumbs.length > 0 && (_jsxs("div", { style: sectionStyle, children: [_jsxs("div", { style: sectionTitleStyle, children: ["Breadcrumbs (", breadcrumbs.length, " events before crash)"] }), _jsx("div", { style: { ...codeBlockStyle, maxHeight: '250px' }, children: breadcrumbs.slice(-15).map((bc) => (_jsxs("div", { style: breadcrumbStyle, children: [_jsx("span", { style: { flexShrink: 0 }, children: getCategoryIcon(bc.category) }), _jsx("span", { style: { color: '#a1a1aa', flexShrink: 0, width: '70px' }, children: new Date(bc.timestamp).toLocaleTimeString() }), _jsx("span", { style: { flex: 1 }, children: bc.message })] }, bc.id))) })] })), _jsx("div", { style: { ...sectionStyle, marginBottom: 0 }, children: _jsxs("div", { style: fingerprintStyle, children: ["Error fingerprint: ", fingerprint] }) })] }) }));
141
+ }
142
+ /**
143
+ * Production Error UI Component
144
+ */
145
+ function ProdErrorUI({ error, onReset, }) {
146
+ return (_jsxs("div", { role: "alert", style: {
147
+ padding: '40px 20px',
148
+ textAlign: 'center',
149
+ fontFamily: 'system-ui, sans-serif',
150
+ }, children: [_jsx("div", { style: { fontSize: '48px', marginBottom: '16px' }, children: "\uD83D\uDE35" }), _jsx("h1", { style: { fontSize: '24px', margin: '0 0 8px', color: '#1f2937' }, children: "Something went wrong" }), _jsx("p", { style: { color: '#6b7280', marginBottom: '24px' }, children: "We've been notified and are working on a fix." }), _jsx("button", { onClick: onReset, style: {
151
+ padding: '12px 24px',
152
+ backgroundColor: '#3b82f6',
153
+ color: 'white',
154
+ border: 'none',
155
+ borderRadius: '8px',
156
+ fontSize: '16px',
157
+ cursor: 'pointer',
158
+ }, children: "Try Again" })] }));
159
+ }
160
+ /**
161
+ * Enhanced Error Boundary Component
162
+ *
163
+ * Provides rich error context including:
164
+ * - Parsed stack traces with app code highlighted
165
+ * - Breadcrumb trail of events before the error
166
+ * - React component tree
167
+ * - Error fingerprinting for grouping
168
+ *
169
+ * @example
170
+ * ```tsx
171
+ * import { EnhancedErrorBoundary } from '@vestig/next/error'
172
+ *
173
+ * export default function Layout({ children }) {
174
+ * return (
175
+ * <EnhancedErrorBoundary
176
+ * showBreadcrumbs
177
+ * onError={(err) => sendToErrorService(err)}
178
+ * >
179
+ * {children}
180
+ * </EnhancedErrorBoundary>
181
+ * )
182
+ * }
183
+ * ```
184
+ */
185
+ export class EnhancedErrorBoundary extends Component {
186
+ constructor(props) {
187
+ super(props);
188
+ this.state = {
189
+ hasError: false,
190
+ enhancedError: null,
191
+ };
192
+ // Set max breadcrumbs
193
+ if (props.maxBreadcrumbs) {
194
+ breadcrumbStore.setMaxSize(props.maxBreadcrumbs);
195
+ }
196
+ }
197
+ static getDerivedStateFromError(error) {
198
+ return { hasError: true };
199
+ }
200
+ componentDidCatch(error, errorInfo) {
201
+ const enhancedError = createEnhancedError(error, errorInfo);
202
+ this.setState({ enhancedError });
203
+ // Call onError callback
204
+ this.props.onError?.(enhancedError);
205
+ // Report to endpoint if configured
206
+ if (this.props.reportEndpoint) {
207
+ this.reportError(enhancedError);
208
+ }
209
+ }
210
+ async reportError(enhancedError) {
211
+ if (!this.props.reportEndpoint)
212
+ return;
213
+ try {
214
+ await fetch(this.props.reportEndpoint, {
215
+ method: 'POST',
216
+ headers: { 'Content-Type': 'application/json' },
217
+ body: JSON.stringify({
218
+ fingerprint: enhancedError.fingerprint,
219
+ error: {
220
+ name: enhancedError.error.name,
221
+ message: enhancedError.error.message,
222
+ stack: enhancedError.error.stack,
223
+ },
224
+ frames: enhancedError.frames,
225
+ breadcrumbs: enhancedError.breadcrumbs,
226
+ environment: enhancedError.environment,
227
+ timestamp: enhancedError.timestamp,
228
+ }),
229
+ });
230
+ }
231
+ catch {
232
+ // Silently fail - don't want to cause more errors
233
+ }
234
+ }
235
+ handleReset = () => {
236
+ this.setState({
237
+ hasError: false,
238
+ enhancedError: null,
239
+ });
240
+ breadcrumbStore.clear();
241
+ };
242
+ render() {
243
+ const { hasError, enhancedError } = this.state;
244
+ const { children, fallback, showBreadcrumbs = true } = this.props;
245
+ if (hasError && enhancedError) {
246
+ // Custom fallback
247
+ if (typeof fallback === 'function') {
248
+ return fallback(enhancedError);
249
+ }
250
+ if (fallback !== undefined) {
251
+ return fallback;
252
+ }
253
+ // Development UI
254
+ if (process.env.NODE_ENV === 'development') {
255
+ return (_jsx(DevErrorUI, { enhancedError: enhancedError, onReset: this.handleReset, showBreadcrumbs: showBreadcrumbs }));
256
+ }
257
+ // Production UI
258
+ return _jsx(ProdErrorUI, { error: enhancedError.error, onReset: this.handleReset });
259
+ }
260
+ return children;
261
+ }
262
+ }
263
+ //# sourceMappingURL=boundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundary.js","sourceRoot":"","sources":["../../src/error/boundary.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
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
+ import type { Breadcrumb, BreadcrumbCategory, BreadcrumbStore } from './types';
10
+ /**
11
+ * Global breadcrumb store singleton
12
+ */
13
+ export declare const breadcrumbStore: BreadcrumbStore;
14
+ /**
15
+ * Add a log breadcrumb
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * addLogBreadcrumb('info', 'User clicked button', 'ui')
20
+ * ```
21
+ */
22
+ export declare function addLogBreadcrumb(level: Breadcrumb['level'], message: string, namespace?: string, data?: Record<string, unknown>): void;
23
+ /**
24
+ * Add a navigation breadcrumb
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * addNavigationBreadcrumb('/dashboard', '/settings')
29
+ * ```
30
+ */
31
+ export declare function addNavigationBreadcrumb(from: string, to: string): void;
32
+ /**
33
+ * Add a click breadcrumb
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * addClickBreadcrumb('Submit button', 'button#submit')
38
+ * ```
39
+ */
40
+ export declare function addClickBreadcrumb(elementDescription: string, selector?: string): void;
41
+ /**
42
+ * Add an input breadcrumb (sanitizes sensitive data)
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * addInputBreadcrumb('email', 'user@example.com', 'input#email')
47
+ * ```
48
+ */
49
+ export declare function addInputBreadcrumb(fieldName: string, value?: string, selector?: string): void;
50
+ /**
51
+ * Add a fetch/API breadcrumb
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * addFetchBreadcrumb('GET', '/api/users', 200, 150)
56
+ * ```
57
+ */
58
+ export declare function addFetchBreadcrumb(method: string, url: string, status?: number, durationMs?: number): void;
59
+ /**
60
+ * Add an error breadcrumb (for non-fatal errors)
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * addErrorBreadcrumb('Failed to load user preferences', error)
65
+ * ```
66
+ */
67
+ export declare function addErrorBreadcrumb(message: string, error?: Error): void;
68
+ /**
69
+ * Add a custom breadcrumb
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * addCustomBreadcrumb('Feature flag enabled', { flag: 'new-dashboard' })
74
+ * ```
75
+ */
76
+ export declare function addCustomBreadcrumb(message: string, data?: Record<string, unknown>): void;
77
+ /**
78
+ * Setup automatic click tracking
79
+ * Call this once in your app to capture click breadcrumbs
80
+ */
81
+ export declare function setupClickTracking(): () => void;
82
+ /**
83
+ * Setup automatic fetch tracking
84
+ * Patches global fetch to capture API call breadcrumbs
85
+ */
86
+ export declare function setupFetchTracking(): () => void;
87
+ /**
88
+ * Format breadcrumbs for display
89
+ */
90
+ export declare function formatBreadcrumbs(breadcrumbs: Breadcrumb[]): string;
91
+ /**
92
+ * Get category icon for display
93
+ */
94
+ export declare function getCategoryIcon(category: BreadcrumbCategory): string;
95
+ //# sourceMappingURL=breadcrumbs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breadcrumbs.d.ts","sourceRoot":"","sources":["../../src/error/breadcrumbs.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAqD9E;;GAEG;AACH,eAAO,MAAM,eAAe,iBAA0B,CAAA;AAEtD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,EAC1B,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,IAAI,CAQN;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAMtE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,kBAAkB,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAMtF;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAc7F;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CACjC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GACjB,IAAI,CAWN;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAYvE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAMzF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,IAAI,CAoC/C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,IAAI,CA2B/C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CAQnE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,CAWpE"}
@@ -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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"}