@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.
- package/LICENSE +21 -0
- package/README.md +307 -0
- package/dist/core/client.d.ts +23 -0
- package/dist/core/client.d.ts.map +1 -0
- package/dist/core/client.js +125 -0
- package/dist/core/client.js.map +1 -0
- package/dist/core/client.test.d.ts +2 -0
- package/dist/core/client.test.d.ts.map +1 -0
- package/dist/core/client.test.js +238 -0
- package/dist/core/client.test.js.map +1 -0
- package/dist/core/encoders.d.ts +3 -0
- package/dist/core/encoders.d.ts.map +1 -0
- package/dist/core/encoders.js +5 -0
- package/dist/core/encoders.js.map +1 -0
- package/dist/core/encoders.test.d.ts +2 -0
- package/dist/core/encoders.test.d.ts.map +1 -0
- package/dist/core/encoders.test.js +55 -0
- package/dist/core/encoders.test.js.map +1 -0
- package/dist/core/error-handlers.d.ts +14 -0
- package/dist/core/error-handlers.d.ts.map +1 -0
- package/dist/core/error-handlers.js +191 -0
- package/dist/core/error-handlers.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/next/error-boundary.d.ts +17 -0
- package/dist/next/error-boundary.d.ts.map +1 -0
- package/dist/next/error-boundary.jsx +32 -0
- package/dist/next/error-boundary.jsx.map +1 -0
- package/dist/next/middleware.d.ts +8 -0
- package/dist/next/middleware.d.ts.map +1 -0
- package/dist/next/middleware.js +139 -0
- package/dist/next/middleware.js.map +1 -0
- package/dist/react/provider.d.ts +16 -0
- package/dist/react/provider.d.ts.map +1 -0
- package/dist/react/provider.jsx +25 -0
- package/dist/react/provider.jsx.map +1 -0
- package/dist/session/replay.d.ts +3 -0
- package/dist/session/replay.d.ts.map +1 -0
- package/dist/session/replay.js +76 -0
- package/dist/session/replay.js.map +1 -0
- package/dist/session/session-summary.d.ts +3 -0
- package/dist/session/session-summary.d.ts.map +1 -0
- package/dist/session/session-summary.js +167 -0
- package/dist/session/session-summary.js.map +1 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Interfere, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# @interfere/next
|
|
2
|
+
|
|
3
|
+
Official Next.js SDK for Interfere error monitoring and analytics.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @interfere/next
|
|
9
|
+
# or
|
|
10
|
+
yarn add @interfere/next
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @interfere/next
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
### 1. Initialize the SDK
|
|
18
|
+
|
|
19
|
+
Create a file to initialize Interfere (e.g., `lib/interfere.ts`):
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { init } from '@interfere/next';
|
|
23
|
+
|
|
24
|
+
export const interfere = init({
|
|
25
|
+
project: process.env.NEXT_PUBLIC_INTERFERE_PROJECT_ID!,
|
|
26
|
+
options: {
|
|
27
|
+
env: process.env.NODE_ENV as 'development' | 'preview' | 'production',
|
|
28
|
+
debug: process.env.NODE_ENV === 'development',
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Add Error Boundary (App Directory)
|
|
34
|
+
|
|
35
|
+
In your root layout (`app/layout.tsx`):
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { InterfereProvider, InterfereErrorBoundary } from '@interfere/next';
|
|
39
|
+
import { interfere } from '@/lib/interfere';
|
|
40
|
+
|
|
41
|
+
export default function RootLayout({
|
|
42
|
+
children,
|
|
43
|
+
}: {
|
|
44
|
+
children: React.ReactNode;
|
|
45
|
+
}) {
|
|
46
|
+
return (
|
|
47
|
+
<html lang="en">
|
|
48
|
+
<body>
|
|
49
|
+
<InterfereProvider>
|
|
50
|
+
<InterfereErrorBoundary>
|
|
51
|
+
{children}
|
|
52
|
+
</InterfereErrorBoundary>
|
|
53
|
+
</InterfereProvider>
|
|
54
|
+
</body>
|
|
55
|
+
</html>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3. Add Error Handler (App Directory)
|
|
61
|
+
|
|
62
|
+
Create `app/error.tsx`:
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
'use client';
|
|
66
|
+
|
|
67
|
+
import { useEffect } from 'react';
|
|
68
|
+
import { captureErrorBoundaryError } from '@interfere/next';
|
|
69
|
+
|
|
70
|
+
export default function Error({
|
|
71
|
+
error,
|
|
72
|
+
reset,
|
|
73
|
+
}: {
|
|
74
|
+
error: Error & { digest?: string };
|
|
75
|
+
reset: () => void;
|
|
76
|
+
}) {
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
captureErrorBoundaryError(error, {
|
|
79
|
+
componentStack: error.stack || '',
|
|
80
|
+
});
|
|
81
|
+
}, [error]);
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<div>
|
|
85
|
+
<h2>Something went wrong!</h2>
|
|
86
|
+
<button onClick={() => reset()}>Try again</button>
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 4. Add Global Error Handler
|
|
93
|
+
|
|
94
|
+
Create `app/global-error.tsx`:
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
'use client';
|
|
98
|
+
|
|
99
|
+
import { createInterfereErrorHandler } from '@interfere/next';
|
|
100
|
+
|
|
101
|
+
const errorHandler = createInterfereErrorHandler();
|
|
102
|
+
|
|
103
|
+
export default function GlobalError({
|
|
104
|
+
error,
|
|
105
|
+
reset,
|
|
106
|
+
}: {
|
|
107
|
+
error: Error & { digest?: string };
|
|
108
|
+
reset: () => void;
|
|
109
|
+
}) {
|
|
110
|
+
errorHandler(error, { digest: error.digest });
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<html>
|
|
114
|
+
<body>
|
|
115
|
+
<h2>Something went wrong!</h2>
|
|
116
|
+
<button onClick={() => reset()}>Try again</button>
|
|
117
|
+
</body>
|
|
118
|
+
</html>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## API Routes
|
|
124
|
+
|
|
125
|
+
### Automatic Error Capture
|
|
126
|
+
|
|
127
|
+
Wrap your API route handlers:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// app/api/users/route.ts
|
|
131
|
+
import { withInterfereApiRoute } from '@interfere/next';
|
|
132
|
+
|
|
133
|
+
export const GET = withInterfereApiRoute(async (request) => {
|
|
134
|
+
// Your API logic here
|
|
135
|
+
const users = await fetchUsers();
|
|
136
|
+
return Response.json(users);
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Manual Error Capture
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
// app/api/webhook/route.ts
|
|
144
|
+
import { captureServerError } from '@interfere/next';
|
|
145
|
+
|
|
146
|
+
export async function POST(request: Request) {
|
|
147
|
+
try {
|
|
148
|
+
const body = await request.json();
|
|
149
|
+
// Process webhook
|
|
150
|
+
} catch (error) {
|
|
151
|
+
captureServerError(error, request, {
|
|
152
|
+
pathname: '/api/webhook',
|
|
153
|
+
type: 'webhook_error',
|
|
154
|
+
});
|
|
155
|
+
return Response.json({ error: 'Webhook failed' }, { status: 500 });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Middleware
|
|
161
|
+
|
|
162
|
+
Wrap your middleware to capture errors:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// middleware.ts
|
|
166
|
+
import { withInterfereMiddleware } from '@interfere/next';
|
|
167
|
+
import { NextResponse } from 'next/server';
|
|
168
|
+
|
|
169
|
+
export default withInterfereMiddleware(async (request) => {
|
|
170
|
+
// Your middleware logic
|
|
171
|
+
return NextResponse.next();
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
export const config = {
|
|
175
|
+
matcher: '/api/:path*',
|
|
176
|
+
};
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Server Components
|
|
180
|
+
|
|
181
|
+
Wrap async server components:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
// app/dashboard/page.tsx
|
|
185
|
+
import { withInterfereServerComponent } from '@interfere/next';
|
|
186
|
+
|
|
187
|
+
async function DashboardPage() {
|
|
188
|
+
const data = await fetchDashboardData();
|
|
189
|
+
return <Dashboard data={data} />;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export default withInterfereServerComponent(DashboardPage, 'DashboardPage');
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Custom Event Capture
|
|
196
|
+
|
|
197
|
+
Capture custom events and errors:
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import { capture, captureServerError } from '@interfere/next';
|
|
201
|
+
|
|
202
|
+
// Capture custom events
|
|
203
|
+
capture('custom', {
|
|
204
|
+
action: 'user_signup',
|
|
205
|
+
userId: user.id,
|
|
206
|
+
plan: 'premium',
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// Capture handled errors
|
|
210
|
+
try {
|
|
211
|
+
await riskyOperation();
|
|
212
|
+
} catch (error) {
|
|
213
|
+
captureServerError(error, undefined, {
|
|
214
|
+
operation: 'risky_operation',
|
|
215
|
+
context: { userId: user.id },
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## React Hook
|
|
221
|
+
|
|
222
|
+
Use the `useInterfere` hook in client components:
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
'use client';
|
|
226
|
+
|
|
227
|
+
import { useInterfere } from '@interfere/next';
|
|
228
|
+
|
|
229
|
+
export function Button() {
|
|
230
|
+
const { capture } = useInterfere();
|
|
231
|
+
|
|
232
|
+
const handleClick = () => {
|
|
233
|
+
capture('ui_event', {
|
|
234
|
+
action: 'button_click',
|
|
235
|
+
label: 'cta_button',
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
return <button onClick={handleClick}>Click me</button>;
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Configuration Options
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
init({
|
|
247
|
+
project: 'if_proj_xxx', // Your project ID
|
|
248
|
+
options: {
|
|
249
|
+
env: 'production', // 'development' | 'preview' | 'production'
|
|
250
|
+
flushInterval: 5000, // Flush interval in ms (client-side only)
|
|
251
|
+
debug: false, // Enable debug logging
|
|
252
|
+
sessionId: 'custom-session-id', // Optional custom session ID
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Event Types
|
|
258
|
+
|
|
259
|
+
The SDK automatically captures these event types:
|
|
260
|
+
|
|
261
|
+
- `error` - Client-side errors (unhandled errors, promise rejections)
|
|
262
|
+
- `server_error` - Server-side errors in API routes and server components
|
|
263
|
+
- `edge_error` - Edge runtime errors in middleware
|
|
264
|
+
- `server_req` - Server request events (API routes)
|
|
265
|
+
- `edge_req` - Edge request events (middleware)
|
|
266
|
+
- `ui_event` - User interface events
|
|
267
|
+
- `custom` - Custom application events
|
|
268
|
+
- `network` - Network request events (coming soon)
|
|
269
|
+
|
|
270
|
+
## Best Practices
|
|
271
|
+
|
|
272
|
+
1. **Initialize Early**: Initialize Interfere as early as possible in your application lifecycle.
|
|
273
|
+
|
|
274
|
+
2. **Use Error Boundaries**: Always wrap your app with `InterfereErrorBoundary` to catch React errors.
|
|
275
|
+
|
|
276
|
+
3. **Wrap Async Functions**: Use `withErrorCapture` or specific wrappers for automatic error tracking.
|
|
277
|
+
|
|
278
|
+
4. **Add Context**: Include relevant context when capturing errors manually:
|
|
279
|
+
```typescript
|
|
280
|
+
captureServerError(error, request, {
|
|
281
|
+
userId: session.userId,
|
|
282
|
+
action: 'update_profile',
|
|
283
|
+
metadata: { ... },
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
5. **Environment Variables**: Store your project ID in environment variables:
|
|
288
|
+
```bash
|
|
289
|
+
NEXT_PUBLIC_INTERFERE_PROJECT_ID=if_proj_xxx
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## TypeScript
|
|
293
|
+
|
|
294
|
+
The SDK is fully typed. Import types as needed:
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
import type {
|
|
298
|
+
Config,
|
|
299
|
+
InitConfig,
|
|
300
|
+
EventType,
|
|
301
|
+
Envelope,
|
|
302
|
+
} from '@interfere/next';
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## License
|
|
306
|
+
|
|
307
|
+
MIT
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type EventType, type InitConfig } from '@interfere/schemas';
|
|
2
|
+
declare class InterfereClient {
|
|
3
|
+
private surface;
|
|
4
|
+
private config;
|
|
5
|
+
private queue;
|
|
6
|
+
seq: number;
|
|
7
|
+
private sessionId;
|
|
8
|
+
private runtime;
|
|
9
|
+
flushTimer?: NodeJS.Timeout;
|
|
10
|
+
constructor({ surface, options }: InitConfig);
|
|
11
|
+
private detectRuntime;
|
|
12
|
+
private generateSessionId;
|
|
13
|
+
private startFlushTimer;
|
|
14
|
+
capture(type: EventType, payload: unknown): void;
|
|
15
|
+
flush(): void;
|
|
16
|
+
getSessionId(): string;
|
|
17
|
+
}
|
|
18
|
+
export declare const init: (props: InitConfig) => InterfereClient;
|
|
19
|
+
export declare const capture: (type: EventType, payload: unknown) => void;
|
|
20
|
+
export declare const flush: () => void;
|
|
21
|
+
export declare const getSessionId: () => string;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAC;AAK5B,cAAM,eAAe;IACnB,OAAO,CAAC,OAAO,CAAY;IAC3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAkB;IAC/B,GAAG,SAAK;IACR,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;gBAEhB,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,UAAU;IAwB5C,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAoBhD,KAAK,IAAI,IAAI;IAwCb,YAAY,IAAI,MAAM;CAGvB;AAID,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,KAAG,eAQxC,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,MAAM,SAAS,EAAE,SAAS,OAAO,KAAG,IAK3D,CAAC;AAEF,eAAO,MAAM,KAAK,QAAO,IAExB,CAAC;AAEF,eAAO,MAAM,YAAY,QAAO,MAM/B,CAAC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { configSchema, } from '@interfere/schemas';
|
|
2
|
+
import { nanoid } from 'nanoid';
|
|
3
|
+
import { encode } from './encoders.js';
|
|
4
|
+
import { setupClientErrorHandlers } from './error-handlers.js';
|
|
5
|
+
class InterfereClient {
|
|
6
|
+
surface;
|
|
7
|
+
config;
|
|
8
|
+
queue = [];
|
|
9
|
+
seq = 0;
|
|
10
|
+
sessionId;
|
|
11
|
+
runtime;
|
|
12
|
+
flushTimer;
|
|
13
|
+
constructor({ surface, options }) {
|
|
14
|
+
this.runtime = this.detectRuntime();
|
|
15
|
+
this.sessionId = options?.sessionId || this.generateSessionId();
|
|
16
|
+
this.surface = surface;
|
|
17
|
+
const { success, data, error } = configSchema.safeParse(options ?? {});
|
|
18
|
+
if (!success) {
|
|
19
|
+
throw new Error(`[Interfere] invalid config: ${error.message}`);
|
|
20
|
+
}
|
|
21
|
+
this.config = data;
|
|
22
|
+
if (this.runtime === 'client') {
|
|
23
|
+
this.startFlushTimer();
|
|
24
|
+
if (typeof window !== 'undefined') {
|
|
25
|
+
window.addEventListener('beforeunload', () => this.flush());
|
|
26
|
+
}
|
|
27
|
+
// Set up client error handlers
|
|
28
|
+
setupClientErrorHandlers();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
detectRuntime() {
|
|
32
|
+
if (typeof window !== 'undefined') {
|
|
33
|
+
return 'client';
|
|
34
|
+
}
|
|
35
|
+
if (typeof globalThis !== 'undefined' && 'EdgeRuntime' in globalThis) {
|
|
36
|
+
return 'edge';
|
|
37
|
+
}
|
|
38
|
+
return 'server';
|
|
39
|
+
}
|
|
40
|
+
generateSessionId() {
|
|
41
|
+
return nanoid();
|
|
42
|
+
}
|
|
43
|
+
startFlushTimer() {
|
|
44
|
+
this.flushTimer = setInterval(() => this.flush(), this.config.flushInterval);
|
|
45
|
+
}
|
|
46
|
+
capture(type, payload) {
|
|
47
|
+
const envelope = {
|
|
48
|
+
v: 0,
|
|
49
|
+
runtime: this.runtime,
|
|
50
|
+
surface: this.surface,
|
|
51
|
+
...this.config,
|
|
52
|
+
clientTs: Date.now(),
|
|
53
|
+
sessionId: this.sessionId,
|
|
54
|
+
seq: ++this.seq,
|
|
55
|
+
type,
|
|
56
|
+
payload: Array.from(encode(payload)),
|
|
57
|
+
};
|
|
58
|
+
this.queue.push(envelope);
|
|
59
|
+
if (this.runtime !== 'client' || this.queue.length >= 10) {
|
|
60
|
+
this.flush();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
flush() {
|
|
64
|
+
if (this.queue.length === 0) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const batch = [...this.queue];
|
|
68
|
+
this.queue = [];
|
|
69
|
+
const body = JSON.stringify(batch);
|
|
70
|
+
const headers = new Headers({
|
|
71
|
+
'Content-Type': 'application/json',
|
|
72
|
+
'x-interfere-surface': this.surface,
|
|
73
|
+
});
|
|
74
|
+
if (this.runtime === 'client' &&
|
|
75
|
+
typeof window !== 'undefined' &&
|
|
76
|
+
typeof window.navigator?.sendBeacon === 'function') {
|
|
77
|
+
// sendBeacon doesn't support custom headers, so we need to use fetch
|
|
78
|
+
// with keepalive for reliability
|
|
79
|
+
fetch(this.config.endpoint, {
|
|
80
|
+
method: 'POST',
|
|
81
|
+
headers,
|
|
82
|
+
body,
|
|
83
|
+
keepalive: true,
|
|
84
|
+
}).catch(() => {
|
|
85
|
+
// Silently fail - don't capture SDK's own errors to prevent loops
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
fetch(this.config.endpoint, {
|
|
90
|
+
method: 'POST',
|
|
91
|
+
headers,
|
|
92
|
+
body,
|
|
93
|
+
}).catch(() => {
|
|
94
|
+
// Silently fail - don't capture SDK's own errors to prevent loops
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
getSessionId() {
|
|
99
|
+
return this.sessionId;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
let instance = null;
|
|
103
|
+
export const init = (props) => {
|
|
104
|
+
if (!props.surface) {
|
|
105
|
+
throw new Error('[Interfere] surface required');
|
|
106
|
+
}
|
|
107
|
+
instance = new InterfereClient(props);
|
|
108
|
+
return instance;
|
|
109
|
+
};
|
|
110
|
+
export const capture = (type, payload) => {
|
|
111
|
+
if (!instance) {
|
|
112
|
+
throw new Error('[interfere] not initialized');
|
|
113
|
+
}
|
|
114
|
+
instance.capture(type, payload);
|
|
115
|
+
};
|
|
116
|
+
export const flush = () => {
|
|
117
|
+
instance?.flush();
|
|
118
|
+
};
|
|
119
|
+
export const getSessionId = () => {
|
|
120
|
+
if (!instance) {
|
|
121
|
+
throw new Error('[interfere] not initialized');
|
|
122
|
+
}
|
|
123
|
+
return instance.getSessionId();
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.test.d.ts","sourceRoot":"","sources":["../../src/core/client.test.ts"],"names":[],"mappings":""}
|