@interfere/next 0.0.0-alpha.10

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 (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +307 -0
  3. package/dist/core/client.d.ts +23 -0
  4. package/dist/core/client.d.ts.map +1 -0
  5. package/dist/core/client.js +125 -0
  6. package/dist/core/client.js.map +1 -0
  7. package/dist/core/client.test.d.ts +2 -0
  8. package/dist/core/client.test.d.ts.map +1 -0
  9. package/dist/core/client.test.js +238 -0
  10. package/dist/core/client.test.js.map +1 -0
  11. package/dist/core/encoders.d.ts +3 -0
  12. package/dist/core/encoders.d.ts.map +1 -0
  13. package/dist/core/encoders.js +5 -0
  14. package/dist/core/encoders.js.map +1 -0
  15. package/dist/core/encoders.test.d.ts +2 -0
  16. package/dist/core/encoders.test.d.ts.map +1 -0
  17. package/dist/core/encoders.test.js +55 -0
  18. package/dist/core/encoders.test.js.map +1 -0
  19. package/dist/core/error-handlers.d.ts +14 -0
  20. package/dist/core/error-handlers.d.ts.map +1 -0
  21. package/dist/core/error-handlers.js +191 -0
  22. package/dist/core/error-handlers.js.map +1 -0
  23. package/dist/index.d.ts +8 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +11 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/next/error-boundary.d.ts +17 -0
  28. package/dist/next/error-boundary.d.ts.map +1 -0
  29. package/dist/next/error-boundary.jsx +32 -0
  30. package/dist/next/error-boundary.jsx.map +1 -0
  31. package/dist/next/middleware.d.ts +8 -0
  32. package/dist/next/middleware.d.ts.map +1 -0
  33. package/dist/next/middleware.js +139 -0
  34. package/dist/next/middleware.js.map +1 -0
  35. package/dist/react/provider.d.ts +16 -0
  36. package/dist/react/provider.d.ts.map +1 -0
  37. package/dist/react/provider.jsx +25 -0
  38. package/dist/react/provider.jsx.map +1 -0
  39. package/dist/session/replay.d.ts +3 -0
  40. package/dist/session/replay.d.ts.map +1 -0
  41. package/dist/session/replay.js +76 -0
  42. package/dist/session/replay.js.map +1 -0
  43. package/dist/session/session-summary.d.ts +3 -0
  44. package/dist/session/session-summary.d.ts.map +1 -0
  45. package/dist/session/session-summary.js +167 -0
  46. package/dist/session/session-summary.js.map +1 -0
  47. package/package.json +53 -0
@@ -0,0 +1,238 @@
1
+ import { sessionIdLength } from '@interfere/schemas';
2
+ import { nanoid, urlAlphabet } from 'nanoid';
3
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
4
+ import { capture, flush, getSessionId, init } from './client.js';
5
+ const SESSION_ID_REGEX = new RegExp(`^[${urlAlphabet.split('').sort().join('')}]{${sessionIdLength}}$`);
6
+ describe('client', () => {
7
+ beforeEach(() => {
8
+ vi.resetModules();
9
+ vi.clearAllMocks();
10
+ vi.clearAllTimers();
11
+ vi.useFakeTimers();
12
+ });
13
+ afterEach(() => {
14
+ vi.useRealTimers();
15
+ });
16
+ describe('init', () => {
17
+ it('initializes with required config', () => {
18
+ const client = init({ surface: 'if_p_test' });
19
+ expect(client).toBeDefined();
20
+ });
21
+ it('uses default endpoint', () => {
22
+ const fetchSpy = vi
23
+ .spyOn(global, 'fetch')
24
+ .mockResolvedValue(new Response());
25
+ init({ surface: 'if_p_test' });
26
+ capture('error', { test: true });
27
+ flush();
28
+ expect(fetchSpy).toHaveBeenCalledWith('https://api.interfere.com/ingest/v0', expect.any(Object));
29
+ });
30
+ it('uses custom endpoint', () => {
31
+ const fetchSpy = vi
32
+ .spyOn(global, 'fetch')
33
+ .mockResolvedValue(new Response());
34
+ init({
35
+ surface: 'if_p_test',
36
+ options: { endpoint: 'http://localhost:3001/ingest/v0' },
37
+ });
38
+ capture('error', { test: true });
39
+ flush();
40
+ expect(fetchSpy).toHaveBeenCalledWith('http://localhost:3001/ingest/v0', expect.any(Object));
41
+ });
42
+ });
43
+ describe('capture', () => {
44
+ it('throws if not initialized', async () => {
45
+ vi.resetModules();
46
+ const { capture: freshCapture } = await import('./client.js');
47
+ expect(() => freshCapture('error', {})).toThrow('[interfere] not initialized');
48
+ });
49
+ it('queues events', () => {
50
+ const fetchSpy = vi
51
+ .spyOn(global, 'fetch')
52
+ .mockResolvedValue(new Response());
53
+ init({ surface: 'if_p_test' });
54
+ capture('ui_event', { action: 'click' });
55
+ capture('error', { message: 'test error' });
56
+ // In server mode, each capture auto-flushes
57
+ // So we expect 2 fetch calls
58
+ expect(fetchSpy).toHaveBeenCalledTimes(2);
59
+ const call1 = fetchSpy.mock.calls[0];
60
+ const call2 = fetchSpy.mock.calls[1];
61
+ if (!(call1?.[1] && call2?.[1])) {
62
+ throw new Error('Expected 2 fetch calls');
63
+ }
64
+ const body1 = JSON.parse(call1[1].body);
65
+ const body2 = JSON.parse(call2[1].body);
66
+ expect(body1).toHaveLength(1);
67
+ expect(body1[0].type).toBe('ui_event');
68
+ expect(body2).toHaveLength(1);
69
+ expect(body2[0].type).toBe('error');
70
+ });
71
+ it('auto-flushes after 10 events', () => {
72
+ const fetchSpy = vi
73
+ .spyOn(global, 'fetch')
74
+ .mockResolvedValue(new Response());
75
+ init({ surface: 'if_p_test' });
76
+ // In server mode, each capture triggers a flush
77
+ for (let i = 0; i < 10; i++) {
78
+ capture('ui_event', { index: i });
79
+ }
80
+ // Each capture causes a flush in server mode
81
+ expect(fetchSpy).toHaveBeenCalledTimes(10);
82
+ });
83
+ it('includes correct envelope structure', () => {
84
+ const fetchSpy = vi
85
+ .spyOn(global, 'fetch')
86
+ .mockResolvedValue(new Response());
87
+ init({ surface: 'if_p_test', options: { env: 'production' } });
88
+ capture('network', { url: '/api/test' });
89
+ flush();
90
+ const call = fetchSpy.mock.calls[0];
91
+ if (!call?.[1]) {
92
+ throw new Error('Expected fetch call');
93
+ }
94
+ const body = JSON.parse(call[1].body);
95
+ const envelope = body[0];
96
+ expect(envelope.v).toBe(0);
97
+ expect(envelope.runtime).toBe('server'); // Default in test environment
98
+ expect(envelope.surface).toBe('if_p_test');
99
+ expect(envelope.env).toBe('production');
100
+ expect(envelope.clientTs).toBeGreaterThan(0);
101
+ expect(envelope.sessionId).toMatch(SESSION_ID_REGEX);
102
+ expect(envelope.seq).toBe(1);
103
+ expect(envelope.type).toBe('network');
104
+ expect(envelope.payload).toBeDefined();
105
+ });
106
+ });
107
+ describe('flush', () => {
108
+ it('does nothing with empty queue', () => {
109
+ const fetchSpy = vi
110
+ .spyOn(global, 'fetch')
111
+ .mockResolvedValue(new Response());
112
+ init({ surface: 'if_p_test' });
113
+ flush();
114
+ expect(fetchSpy).not.toHaveBeenCalled();
115
+ });
116
+ it('clears queue after flush', () => {
117
+ const fetchSpy = vi
118
+ .spyOn(global, 'fetch')
119
+ .mockResolvedValue(new Response());
120
+ init({ surface: 'if_p_test' });
121
+ capture('error', { test: true });
122
+ flush();
123
+ expect(fetchSpy).toHaveBeenCalledTimes(1);
124
+ flush(); // Second flush should do nothing
125
+ expect(fetchSpy).toHaveBeenCalledTimes(1);
126
+ });
127
+ it('handles fetch errors in debug mode', async () => {
128
+ const fetchSpy = vi
129
+ .spyOn(global, 'fetch')
130
+ .mockRejectedValue(new Error('Network error'));
131
+ init({ surface: 'if_p_test', options: { debug: true } });
132
+ capture('error', { test: true });
133
+ // Should not throw
134
+ expect(() => flush()).not.toThrow();
135
+ await vi.waitFor(() => {
136
+ expect(fetchSpy).toHaveBeenCalled();
137
+ });
138
+ });
139
+ });
140
+ describe('getSessionId', () => {
141
+ it('throws if not initialized', async () => {
142
+ vi.resetModules();
143
+ const { getSessionId: freshGetSessionId } = await import('./client.js');
144
+ expect(() => freshGetSessionId()).toThrow('[interfere] not initialized');
145
+ });
146
+ it('returns consistent session ID', () => {
147
+ init({ surface: 'if_p_test' });
148
+ const id1 = getSessionId();
149
+ const id2 = getSessionId();
150
+ expect(id1).toBe(id2);
151
+ expect(id1).toMatch(SESSION_ID_REGEX);
152
+ });
153
+ it('uses provided session ID', () => {
154
+ const customId = nanoid(sessionIdLength);
155
+ init({ surface: 'if_p_test', options: { sessionId: customId } });
156
+ expect(getSessionId()).toBe(customId);
157
+ });
158
+ });
159
+ describe('runtime detection', () => {
160
+ it('detects server runtime by default', () => {
161
+ const fetchSpy = vi
162
+ .spyOn(global, 'fetch')
163
+ .mockResolvedValue(new Response());
164
+ init({ surface: 'if_p_test' });
165
+ capture('server_req', {});
166
+ flush();
167
+ const call = fetchSpy.mock.calls[0];
168
+ if (!call?.[1]) {
169
+ throw new Error('Expected fetch call');
170
+ }
171
+ const body = JSON.parse(call[1].body);
172
+ expect(body[0].runtime).toBe('server');
173
+ });
174
+ it('detects client runtime with window', async () => {
175
+ const originalWindow = global.window;
176
+ global.window = {
177
+ addEventListener: vi.fn(),
178
+ };
179
+ vi.resetModules();
180
+ const { init: freshInit, capture: freshCapture, flush: freshFlush, } = await import('./client.js');
181
+ const fetchSpy = vi
182
+ .spyOn(global, 'fetch')
183
+ .mockResolvedValue(new Response());
184
+ freshInit({ surface: 'if_p_test' });
185
+ freshCapture('ui_event', {});
186
+ // Client mode doesn't auto-flush
187
+ expect(fetchSpy).not.toHaveBeenCalled();
188
+ freshFlush();
189
+ const call = fetchSpy.mock.calls[0];
190
+ if (!call?.[1]) {
191
+ throw new Error('Expected fetch call');
192
+ }
193
+ const body = JSON.parse(call[1].body);
194
+ expect(body[0].runtime).toBe('client');
195
+ global.window = originalWindow;
196
+ });
197
+ });
198
+ describe('client mode features', () => {
199
+ it('uses fetch with keepalive when sendBeacon is available', async () => {
200
+ const originalWindow = global.window;
201
+ const fetchSpy = vi.fn().mockResolvedValue(new Response());
202
+ const sendBeaconSpy = vi.fn().mockReturnValue(true);
203
+ // Create a proper mock window with sendBeacon on it
204
+ global.window = {
205
+ addEventListener: vi.fn(),
206
+ navigator: {
207
+ sendBeacon: sendBeaconSpy,
208
+ },
209
+ };
210
+ global.fetch = fetchSpy;
211
+ vi.resetModules();
212
+ const { init: freshInit, capture: freshCapture, flush: freshFlush, } = await import('./client.js');
213
+ freshInit({ surface: 'if_p_test' });
214
+ freshCapture('ui_event', {});
215
+ freshFlush();
216
+ // Should use fetch with keepalive, not sendBeacon
217
+ expect(sendBeaconSpy).not.toHaveBeenCalled();
218
+ expect(fetchSpy).toHaveBeenCalledWith('https://api.interfere.com/ingest/v0', expect.objectContaining({
219
+ method: 'POST',
220
+ keepalive: true,
221
+ headers: expect.any(Headers),
222
+ body: expect.any(String),
223
+ }));
224
+ global.window = originalWindow;
225
+ global.fetch = fetch;
226
+ });
227
+ it('sets up auto-flush timer in client mode', async () => {
228
+ const originalWindow = global.window;
229
+ global.window = { addEventListener: vi.fn() };
230
+ vi.resetModules();
231
+ const { init: freshInit } = await import('./client.js');
232
+ freshInit({ surface: 'if_p_test', options: { flushInterval: 1000 } });
233
+ expect(global.window.addEventListener).toHaveBeenCalledWith('beforeunload', expect.any(Function));
234
+ global.window = originalWindow;
235
+ });
236
+ });
237
+ });
238
+ //# sourceMappingURL=client.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.test.js","sourceRoot":"","sources":["../../src/core/client.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const encode: (data: unknown) => Uint8Array;
2
+ export declare const decode: (data: Uint8Array) => unknown;
3
+ //# sourceMappingURL=encoders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoders.d.ts","sourceRoot":"","sources":["../../src/core/encoders.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,GAAI,MAAM,OAAO,KAAG,UACD,CAAC;AACvC,eAAO,MAAM,MAAM,GAAI,MAAM,UAAU,KAAG,OACR,CAAC"}
@@ -0,0 +1,5 @@
1
+ const encoder = new TextEncoder();
2
+ const decoder = new TextDecoder();
3
+ export const encode = (data) => encoder.encode(JSON.stringify(data));
4
+ export const decode = (data) => JSON.parse(decoder.decode(data));
5
+ //# sourceMappingURL=encoders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoders.js","sourceRoot":"","sources":["../../src/core/encoders.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAClC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAa,EAAc,EAAE,CAClD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AACvC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAgB,EAAW,EAAE,CAClD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=encoders.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoders.test.d.ts","sourceRoot":"","sources":["../../src/core/encoders.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { decode, encode } from './encoders.js';
3
+ describe('encoders', () => {
4
+ describe('encode', () => {
5
+ it('encodes strings to Uint8Array', () => {
6
+ const result = encode('hello');
7
+ expect(result).toBeInstanceOf(Uint8Array);
8
+ expect(new TextDecoder().decode(result)).toBe('"hello"');
9
+ });
10
+ it('encodes objects to Uint8Array', () => {
11
+ const obj = { foo: 'bar', num: 123 };
12
+ const result = encode(obj);
13
+ expect(result).toBeInstanceOf(Uint8Array);
14
+ expect(new TextDecoder().decode(result)).toBe('{"foo":"bar","num":123}');
15
+ });
16
+ it('encodes arrays to Uint8Array', () => {
17
+ const arr = [1, 2, 3];
18
+ const result = encode(arr);
19
+ expect(result).toBeInstanceOf(Uint8Array);
20
+ expect(new TextDecoder().decode(result)).toBe('[1,2,3]');
21
+ });
22
+ it('encodes null', () => {
23
+ expect(new TextDecoder().decode(encode(null))).toBe('null');
24
+ });
25
+ it('handles undefined by encoding as null', () => {
26
+ // JSON.stringify(undefined) returns undefined, which becomes empty string
27
+ // This is expected behavior for JSON
28
+ const result = encode(undefined);
29
+ expect(result).toBeInstanceOf(Uint8Array);
30
+ });
31
+ });
32
+ describe('decode', () => {
33
+ it('decodes Uint8Array back to original values', () => {
34
+ const testCases = [
35
+ 'hello',
36
+ { foo: 'bar', num: 123 },
37
+ [1, 2, 3],
38
+ null,
39
+ true,
40
+ false,
41
+ 42,
42
+ ];
43
+ for (const original of testCases) {
44
+ const encoded = encode(original);
45
+ const decoded = decode(encoded);
46
+ expect(decoded).toEqual(original);
47
+ }
48
+ });
49
+ it('throws on invalid JSON', () => {
50
+ const invalidJson = new TextEncoder().encode('not valid json');
51
+ expect(() => decode(invalidJson)).toThrow();
52
+ });
53
+ });
54
+ });
55
+ //# sourceMappingURL=encoders.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoders.test.js","sourceRoot":"","sources":["../../src/core/encoders.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export declare function setupClientErrorHandlers(): void;
2
+ export declare function captureServerError(error: unknown, request?: Request, context?: {
3
+ pathname?: string;
4
+ renderingError?: boolean;
5
+ [key: string]: unknown;
6
+ }): void;
7
+ export declare function captureErrorBoundaryError(error: Error, errorInfo: {
8
+ componentStack: string;
9
+ }): void;
10
+ export declare function captureApiRouteError(error: unknown, req: Request, pathname: string): void;
11
+ type AsyncFunction = (...args: unknown[]) => Promise<unknown>;
12
+ export declare function withErrorCapture<T extends AsyncFunction>(fn: T, context?: Record<string, unknown>): T;
13
+ export {};
14
+ //# sourceMappingURL=error-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handlers.d.ts","sourceRoot":"","sources":["../../src/core/error-handlers.ts"],"names":[],"mappings":"AA4DA,wBAAgB,wBAAwB,IAAI,IAAI,CAiE/C;AAGD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,OAAO,EACjB,OAAO,CAAC,EAAE;IACR,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,GACA,IAAI,CAoBN;AAGD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,GACpC,IAAI,CAQN;AAGD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,MAAM,GACf,IAAI,CAcN;AA+BD,KAAK,aAAa,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE9D,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,aAAa,EACtD,EAAE,EAAE,CAAC,EACL,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,CAAC,CAkBH"}
@@ -0,0 +1,191 @@
1
+ import { capture } from './client.js';
2
+ // Flag to prevent infinite loops when capturing errors
3
+ let isCapturing = false;
4
+ function serializeError(error) {
5
+ if (error instanceof Error) {
6
+ return {
7
+ message: error.message,
8
+ stack: error.stack,
9
+ name: error.name,
10
+ cause: error.cause,
11
+ };
12
+ }
13
+ if (typeof error === 'string') {
14
+ return {
15
+ message: error,
16
+ name: 'Error',
17
+ };
18
+ }
19
+ return {
20
+ message: String(error),
21
+ name: 'UnknownError',
22
+ };
23
+ }
24
+ // Safe capture that doesn't throw if SDK isn't initialized
25
+ function safeCapture(eventType, payload) {
26
+ // Prevent recursive captures
27
+ if (isCapturing) {
28
+ return;
29
+ }
30
+ try {
31
+ isCapturing = true;
32
+ capture(eventType, payload);
33
+ }
34
+ catch {
35
+ // SDK not initialized yet, skip capture
36
+ // In production, you might want to queue these events for later
37
+ }
38
+ finally {
39
+ isCapturing = false;
40
+ }
41
+ }
42
+ // Client-side error handling
43
+ export function setupClientErrorHandlers() {
44
+ if (typeof window === 'undefined') {
45
+ return;
46
+ }
47
+ // Handle unhandled errors
48
+ window.addEventListener('error', (event) => {
49
+ const errorInfo = {
50
+ message: event.message,
51
+ name: 'WindowError',
52
+ fileName: event.filename,
53
+ lineNumber: event.lineno,
54
+ columnNumber: event.colno,
55
+ stack: event.error?.stack,
56
+ };
57
+ safeCapture('error', {
58
+ type: 'unhandled_error',
59
+ error: errorInfo,
60
+ url: window.location.href,
61
+ userAgent: navigator.userAgent,
62
+ timestamp: Date.now(),
63
+ });
64
+ });
65
+ // Handle unhandled promise rejections
66
+ window.addEventListener('unhandledrejection', (event) => {
67
+ const errorInfo = serializeError(event.reason);
68
+ safeCapture('error', {
69
+ type: 'unhandled_rejection',
70
+ error: errorInfo,
71
+ url: window.location.href,
72
+ userAgent: navigator.userAgent,
73
+ timestamp: Date.now(),
74
+ });
75
+ });
76
+ // Override console.error to capture logged errors
77
+ // biome-ignore lint/suspicious/noConsole: We need to override console.error for error tracking
78
+ const originalConsoleError = console.error;
79
+ console.error = (...args) => {
80
+ originalConsoleError.apply(console, args);
81
+ // Convert arguments to a readable format
82
+ const message = args
83
+ .map((arg) => {
84
+ if (typeof arg === 'object') {
85
+ try {
86
+ return JSON.stringify(arg);
87
+ }
88
+ catch {
89
+ return String(arg);
90
+ }
91
+ }
92
+ return String(arg);
93
+ })
94
+ .join(' ');
95
+ safeCapture('error', {
96
+ type: 'console_error',
97
+ message,
98
+ url: typeof window !== 'undefined' ? window.location.href : undefined,
99
+ timestamp: Date.now(),
100
+ });
101
+ };
102
+ }
103
+ // Server/Edge error handling for Next.js
104
+ export function captureServerError(error, request, context) {
105
+ const errorInfo = serializeError(error);
106
+ const runtime = typeof globalThis !== 'undefined' && 'EdgeRuntime' in globalThis
107
+ ? 'edge'
108
+ : 'server';
109
+ safeCapture(runtime === 'edge' ? 'edge_error' : 'server_error', {
110
+ type: 'server_error',
111
+ error: errorInfo,
112
+ request: request
113
+ ? {
114
+ url: request.url,
115
+ method: request.method,
116
+ headers: Object.fromEntries(request.headers.entries()),
117
+ }
118
+ : undefined,
119
+ context,
120
+ timestamp: Date.now(),
121
+ });
122
+ }
123
+ // Next.js specific error boundary helper
124
+ export function captureErrorBoundaryError(error, errorInfo) {
125
+ safeCapture('error', {
126
+ type: 'error_boundary',
127
+ error: serializeError(error),
128
+ componentStack: errorInfo.componentStack,
129
+ url: typeof window !== 'undefined' ? window.location.href : undefined,
130
+ timestamp: Date.now(),
131
+ });
132
+ }
133
+ // Capture Next.js API route errors
134
+ export function captureApiRouteError(error, req, pathname) {
135
+ const errorInfo = serializeError(error);
136
+ safeCapture('server_error', {
137
+ type: 'api_route_error',
138
+ error: errorInfo,
139
+ request: {
140
+ url: req.url,
141
+ method: req.method,
142
+ headers: Object.fromEntries(req.headers.entries()),
143
+ pathname,
144
+ },
145
+ timestamp: Date.now(),
146
+ });
147
+ }
148
+ // Determine runtime environment
149
+ function getRuntime() {
150
+ if (typeof window !== 'undefined') {
151
+ return 'client';
152
+ }
153
+ if (typeof globalThis !== 'undefined' && 'EdgeRuntime' in globalThis) {
154
+ return 'edge';
155
+ }
156
+ return 'server';
157
+ }
158
+ // Get event type based on runtime
159
+ function getErrorEventType(runtime) {
160
+ switch (runtime) {
161
+ case 'client':
162
+ return 'error';
163
+ case 'edge':
164
+ return 'edge_error';
165
+ case 'server':
166
+ return 'server_error';
167
+ default:
168
+ // This should never happen due to the type constraint, but satisfies the linter
169
+ return 'error';
170
+ }
171
+ }
172
+ export function withErrorCapture(fn, context) {
173
+ return (async (...args) => {
174
+ try {
175
+ return await fn(...args);
176
+ }
177
+ catch (error) {
178
+ const runtime = getRuntime();
179
+ const eventType = getErrorEventType(runtime);
180
+ safeCapture(eventType, {
181
+ type: 'wrapped_function_error',
182
+ error: serializeError(error),
183
+ functionName: fn.name || 'anonymous',
184
+ context,
185
+ timestamp: Date.now(),
186
+ });
187
+ throw error;
188
+ }
189
+ });
190
+ }
191
+ //# sourceMappingURL=error-handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handlers.js","sourceRoot":"","sources":["../../src/core/error-handlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export type { Config, Env, Envelope, EventType, InitConfig, SessionId, SurfaceId, } from '@interfere/schemas';
2
+ export { capture, flush, getSessionId, init } from './core/client.js';
3
+ export { decode, encode } from './core/encoders.js';
4
+ export { captureApiRouteError, captureErrorBoundaryError, captureServerError, setupClientErrorHandlers, withErrorCapture, } from './core/error-handlers.js';
5
+ export { InterfereErrorBoundary } from './next/error-boundary.jsx';
6
+ export { createInterfereErrorHandler, withInterfereApiRoute, withInterfereMiddleware, withInterfereServerComponent, } from './next/middleware.js';
7
+ export { InterfereProvider, useInterfere } from './react/provider.jsx';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,MAAM,EACN,GAAG,EACH,QAAQ,EACR,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,GACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,kBAAkB,EAClB,wBAAwB,EACxB,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,EACrB,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ // Core client functionality
2
+ export { capture, flush, getSessionId, init } from './core/client.js';
3
+ export { decode, encode } from './core/encoders.js';
4
+ // Error handling utilities
5
+ export { captureApiRouteError, captureErrorBoundaryError, captureServerError, setupClientErrorHandlers, withErrorCapture, } from './core/error-handlers.js';
6
+ // Next.js specific components and utilities
7
+ export { InterfereErrorBoundary } from './next/error-boundary.jsx';
8
+ export { createInterfereErrorHandler, withInterfereApiRoute, withInterfereMiddleware, withInterfereServerComponent, } from './next/middleware.js';
9
+ // React components and hooks
10
+ export { InterfereProvider, useInterfere } from './react/provider.jsx';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAY5B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACpD,2BAA2B;AAC3B,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,kBAAkB,EAClB,wBAAwB,EACxB,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAElC,4CAA4C;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,EACrB,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,sBAAsB,CAAC;AAC9B,6BAA6B;AAC7B,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import React, { type ReactNode } from 'react';
2
+ interface Props {
3
+ children: ReactNode;
4
+ fallback?: ReactNode;
5
+ }
6
+ interface State {
7
+ hasError: boolean;
8
+ error?: Error;
9
+ }
10
+ export declare class InterfereErrorBoundary extends React.Component<Props, State> {
11
+ constructor(props: Props);
12
+ static getDerivedStateFromError(error: Error): State;
13
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;
14
+ render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
15
+ }
16
+ export {};
17
+ //# sourceMappingURL=error-boundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-boundary.d.ts","sourceRoot":"","sources":["../../src/next/error-boundary.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG9C,UAAU,KAAK;IACb,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,UAAU,KAAK;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAMD,qBAAa,sBAAuB,SAAQ,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC;gBAC3D,KAAK,EAAE,KAAK;IAKxB,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK;IAI3C,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,GAAG,IAAI;IAQjE,MAAM;CAgBhB"}