sitepong 0.0.6 → 0.0.7

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.
@@ -1,112 +1,8 @@
1
1
  import React, { Component, ReactNode, ErrorInfo } from 'react';
2
+ import { S as SitePongConfig, C as CaptureContext, L as LogLevel, U as User, a as addBreadcrumb } from '../breadcrumbs-DwXK5gNn.mjs';
2
3
  import { TrackProperties, UserTraits, GroupTraits, DeviceSignals, WebVitals } from '../index.mjs';
3
4
  export { CapturedError, CronCheckinOptions, CronHandle, DatabaseQueryEvent, DatabaseTrackerConfig, ErrorContext, FraudCheckResult, MetricOptions, PerformanceConfig, PerformanceSpan, PerformanceTransaction, ProfileData, ProfileFrame, ProfilerConfig, ReplayConfig, ReplayEvent, SitePongConfig, SitePongInitConfig, TraceContext, TracePropagator, VisitorIdResult, areFlagsReady, captureError, captureMessage, clearAnonymousId, createTraceContext, cronCheckin, cronStart, cronWrap, dbTrack, dbTrackSync, endSpan, endTransaction, extractTrace, flush, flushMetrics, flushProfiles, generateSpanId, generateTraceId, getAllFlags, getAnonymousId, getDbNPlusOnePatterns, getDbQueryCount, getDeviceSignals, getFlag, getFraudCheck, getLatestProfile, getProfiles, getReplaySessionId, getVariant, getVariantPayload, getVisitorId, getWebVitals, group, identify, init, isReplayRecording, metricDistribution, metricGauge, metricHistogram, metricIncrement, metricStartTimer, metricTime, profile, propagateTrace, refreshFlags, resetAnalytics, resetDbQueryCount, setAnonymousId, setContext, setTags, setUser, startProfileSpan, startReplay, startSpan, startTransaction, stopReplay, track, trackPageView, waitForFlags } from '../index.mjs';
4
5
 
5
- /**
6
- * SitePong SDK Types
7
- */
8
- interface SitePongConfig {
9
- /** DSN in format: https://<public_key>@ingest.sitepong.com/<project_id> */
10
- dsn?: string;
11
- /** API key in format: sp_live_xxx or sp_test_xxx */
12
- apiKey?: string;
13
- /** Environment name (e.g., 'production', 'staging', 'development') */
14
- environment?: string;
15
- /** Release/version string */
16
- release?: string;
17
- /** Enable debug logging */
18
- debug?: boolean;
19
- /** Enable/disable the SDK entirely */
20
- enabled?: boolean;
21
- /** Sample rate for errors (0.0 to 1.0) */
22
- sampleRate?: number;
23
- /** Maximum number of breadcrumbs to keep */
24
- maxBreadcrumbs?: number;
25
- /** Hook to modify or filter events before sending */
26
- beforeSend?: (event: ErrorEvent) => ErrorEvent | null;
27
- /** Auto-capture configuration */
28
- autoCapture?: {
29
- errors?: boolean;
30
- unhandledRejections?: boolean;
31
- console?: boolean;
32
- };
33
- /** Custom API endpoint (for self-hosted) */
34
- apiEndpoint?: string;
35
- }
36
- interface User {
37
- id?: string;
38
- email?: string;
39
- username?: string;
40
- [key: string]: unknown;
41
- }
42
- interface Breadcrumb {
43
- type: "default" | "http" | "navigation" | "ui" | "console" | "error";
44
- category?: string;
45
- message?: string;
46
- level?: "fatal" | "error" | "warning" | "info" | "debug";
47
- timestamp: number;
48
- data?: Record<string, unknown>;
49
- }
50
- interface ErrorEvent {
51
- event_id: string;
52
- timestamp: string;
53
- level: "fatal" | "error" | "warning" | "info" | "debug";
54
- message: string;
55
- exception?: {
56
- type: string;
57
- value: string;
58
- stacktrace?: StackFrame[];
59
- };
60
- tags?: Record<string, string>;
61
- extra?: Record<string, unknown>;
62
- user?: User;
63
- breadcrumbs?: Breadcrumb[];
64
- context?: {
65
- browser?: BrowserContext;
66
- os?: OSContext;
67
- device?: DeviceContext;
68
- [key: string]: unknown;
69
- };
70
- environment?: string;
71
- release?: string;
72
- request?: {
73
- url?: string;
74
- method?: string;
75
- headers?: Record<string, string>;
76
- };
77
- }
78
- interface StackFrame {
79
- filename?: string;
80
- function?: string;
81
- lineno?: number;
82
- colno?: number;
83
- in_app?: boolean;
84
- context_line?: string;
85
- pre_context?: string[];
86
- post_context?: string[];
87
- }
88
- interface BrowserContext {
89
- name?: string;
90
- version?: string;
91
- }
92
- interface OSContext {
93
- name?: string;
94
- version?: string;
95
- }
96
- interface DeviceContext {
97
- family?: string;
98
- model?: string;
99
- brand?: string;
100
- }
101
- type LogLevel = "fatal" | "error" | "warning" | "info" | "debug";
102
- interface CaptureContext {
103
- tags?: Record<string, string>;
104
- extra?: Record<string, unknown>;
105
- user?: User;
106
- level?: LogLevel;
107
- fingerprint?: string[];
108
- }
109
-
110
6
  interface SitePongContextValue {
111
7
  isInitialized: boolean;
112
8
  }
@@ -215,11 +111,6 @@ declare class SitePongErrorBoundary extends Component<SitePongErrorBoundaryProps
215
111
  render(): ReactNode;
216
112
  }
217
113
 
218
- /**
219
- * Add a breadcrumb to the trail
220
- */
221
- declare function addBreadcrumb(breadcrumb: Omit<Breadcrumb, "timestamp">): void;
222
-
223
114
  /**
224
115
  * Hook to access all SitePong SDK methods
225
116
  *
@@ -1,112 +1,8 @@
1
1
  import React, { Component, ReactNode, ErrorInfo } from 'react';
2
+ import { S as SitePongConfig, C as CaptureContext, L as LogLevel, U as User, a as addBreadcrumb } from '../breadcrumbs-DwXK5gNn.js';
2
3
  import { TrackProperties, UserTraits, GroupTraits, DeviceSignals, WebVitals } from '../index.js';
3
4
  export { CapturedError, CronCheckinOptions, CronHandle, DatabaseQueryEvent, DatabaseTrackerConfig, ErrorContext, FraudCheckResult, MetricOptions, PerformanceConfig, PerformanceSpan, PerformanceTransaction, ProfileData, ProfileFrame, ProfilerConfig, ReplayConfig, ReplayEvent, SitePongConfig, SitePongInitConfig, TraceContext, TracePropagator, VisitorIdResult, areFlagsReady, captureError, captureMessage, clearAnonymousId, createTraceContext, cronCheckin, cronStart, cronWrap, dbTrack, dbTrackSync, endSpan, endTransaction, extractTrace, flush, flushMetrics, flushProfiles, generateSpanId, generateTraceId, getAllFlags, getAnonymousId, getDbNPlusOnePatterns, getDbQueryCount, getDeviceSignals, getFlag, getFraudCheck, getLatestProfile, getProfiles, getReplaySessionId, getVariant, getVariantPayload, getVisitorId, getWebVitals, group, identify, init, isReplayRecording, metricDistribution, metricGauge, metricHistogram, metricIncrement, metricStartTimer, metricTime, profile, propagateTrace, refreshFlags, resetAnalytics, resetDbQueryCount, setAnonymousId, setContext, setTags, setUser, startProfileSpan, startReplay, startSpan, startTransaction, stopReplay, track, trackPageView, waitForFlags } from '../index.js';
4
5
 
5
- /**
6
- * SitePong SDK Types
7
- */
8
- interface SitePongConfig {
9
- /** DSN in format: https://<public_key>@ingest.sitepong.com/<project_id> */
10
- dsn?: string;
11
- /** API key in format: sp_live_xxx or sp_test_xxx */
12
- apiKey?: string;
13
- /** Environment name (e.g., 'production', 'staging', 'development') */
14
- environment?: string;
15
- /** Release/version string */
16
- release?: string;
17
- /** Enable debug logging */
18
- debug?: boolean;
19
- /** Enable/disable the SDK entirely */
20
- enabled?: boolean;
21
- /** Sample rate for errors (0.0 to 1.0) */
22
- sampleRate?: number;
23
- /** Maximum number of breadcrumbs to keep */
24
- maxBreadcrumbs?: number;
25
- /** Hook to modify or filter events before sending */
26
- beforeSend?: (event: ErrorEvent) => ErrorEvent | null;
27
- /** Auto-capture configuration */
28
- autoCapture?: {
29
- errors?: boolean;
30
- unhandledRejections?: boolean;
31
- console?: boolean;
32
- };
33
- /** Custom API endpoint (for self-hosted) */
34
- apiEndpoint?: string;
35
- }
36
- interface User {
37
- id?: string;
38
- email?: string;
39
- username?: string;
40
- [key: string]: unknown;
41
- }
42
- interface Breadcrumb {
43
- type: "default" | "http" | "navigation" | "ui" | "console" | "error";
44
- category?: string;
45
- message?: string;
46
- level?: "fatal" | "error" | "warning" | "info" | "debug";
47
- timestamp: number;
48
- data?: Record<string, unknown>;
49
- }
50
- interface ErrorEvent {
51
- event_id: string;
52
- timestamp: string;
53
- level: "fatal" | "error" | "warning" | "info" | "debug";
54
- message: string;
55
- exception?: {
56
- type: string;
57
- value: string;
58
- stacktrace?: StackFrame[];
59
- };
60
- tags?: Record<string, string>;
61
- extra?: Record<string, unknown>;
62
- user?: User;
63
- breadcrumbs?: Breadcrumb[];
64
- context?: {
65
- browser?: BrowserContext;
66
- os?: OSContext;
67
- device?: DeviceContext;
68
- [key: string]: unknown;
69
- };
70
- environment?: string;
71
- release?: string;
72
- request?: {
73
- url?: string;
74
- method?: string;
75
- headers?: Record<string, string>;
76
- };
77
- }
78
- interface StackFrame {
79
- filename?: string;
80
- function?: string;
81
- lineno?: number;
82
- colno?: number;
83
- in_app?: boolean;
84
- context_line?: string;
85
- pre_context?: string[];
86
- post_context?: string[];
87
- }
88
- interface BrowserContext {
89
- name?: string;
90
- version?: string;
91
- }
92
- interface OSContext {
93
- name?: string;
94
- version?: string;
95
- }
96
- interface DeviceContext {
97
- family?: string;
98
- model?: string;
99
- brand?: string;
100
- }
101
- type LogLevel = "fatal" | "error" | "warning" | "info" | "debug";
102
- interface CaptureContext {
103
- tags?: Record<string, string>;
104
- extra?: Record<string, unknown>;
105
- user?: User;
106
- level?: LogLevel;
107
- fingerprint?: string[];
108
- }
109
-
110
6
  interface SitePongContextValue {
111
7
  isInitialized: boolean;
112
8
  }
@@ -215,11 +111,6 @@ declare class SitePongErrorBoundary extends Component<SitePongErrorBoundaryProps
215
111
  render(): ReactNode;
216
112
  }
217
113
 
218
- /**
219
- * Add a breadcrumb to the trail
220
- */
221
- declare function addBreadcrumb(breadcrumb: Omit<Breadcrumb, "timestamp">): void;
222
-
223
114
  /**
224
115
  * Hook to access all SitePong SDK methods
225
116
  *
@@ -0,0 +1,46 @@
1
+ import { S as SitePongConfig, C as CaptureContext, L as LogLevel } from '../breadcrumbs-DwXK5gNn.mjs';
2
+ export { E as ErrorEvent, a as addBreadcrumb, c as clearBreadcrumbs, g as getBreadcrumbs } from '../breadcrumbs-DwXK5gNn.mjs';
3
+
4
+ /**
5
+ * Server-side exports for @sitepong/react
6
+ * Use this for Next.js API routes, Express, and other Node.js servers
7
+ */
8
+
9
+ /**
10
+ * Initialize SitePong for server-side usage
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * // In your server entry point or API route
15
+ * import { initServer } from '@sitepong/react/server';
16
+ *
17
+ * initServer({
18
+ * dsn: process.env.SITEPONG_DSN,
19
+ * environment: process.env.NODE_ENV,
20
+ * });
21
+ * ```
22
+ */
23
+ declare function initServer(config: SitePongConfig): void;
24
+ /**
25
+ * Get the current server configuration
26
+ */
27
+ declare function getServerConfig(): SitePongConfig | null;
28
+ /**
29
+ * Capture an exception on the server
30
+ */
31
+ declare function captureServerException(error: Error | unknown, context?: CaptureContext & {
32
+ request?: {
33
+ url?: string;
34
+ method?: string;
35
+ headers?: Record<string, string>;
36
+ query?: Record<string, string>;
37
+ body?: unknown;
38
+ ip?: string;
39
+ };
40
+ }): Promise<string | null>;
41
+ /**
42
+ * Capture a message on the server
43
+ */
44
+ declare function captureServerMessage(message: string, level?: LogLevel, context?: CaptureContext): Promise<string | null>;
45
+
46
+ export { CaptureContext, LogLevel, SitePongConfig, captureServerException, captureServerMessage, getServerConfig, initServer };
@@ -0,0 +1,46 @@
1
+ import { S as SitePongConfig, C as CaptureContext, L as LogLevel } from '../breadcrumbs-DwXK5gNn.js';
2
+ export { E as ErrorEvent, a as addBreadcrumb, c as clearBreadcrumbs, g as getBreadcrumbs } from '../breadcrumbs-DwXK5gNn.js';
3
+
4
+ /**
5
+ * Server-side exports for @sitepong/react
6
+ * Use this for Next.js API routes, Express, and other Node.js servers
7
+ */
8
+
9
+ /**
10
+ * Initialize SitePong for server-side usage
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * // In your server entry point or API route
15
+ * import { initServer } from '@sitepong/react/server';
16
+ *
17
+ * initServer({
18
+ * dsn: process.env.SITEPONG_DSN,
19
+ * environment: process.env.NODE_ENV,
20
+ * });
21
+ * ```
22
+ */
23
+ declare function initServer(config: SitePongConfig): void;
24
+ /**
25
+ * Get the current server configuration
26
+ */
27
+ declare function getServerConfig(): SitePongConfig | null;
28
+ /**
29
+ * Capture an exception on the server
30
+ */
31
+ declare function captureServerException(error: Error | unknown, context?: CaptureContext & {
32
+ request?: {
33
+ url?: string;
34
+ method?: string;
35
+ headers?: Record<string, string>;
36
+ query?: Record<string, string>;
37
+ body?: unknown;
38
+ ip?: string;
39
+ };
40
+ }): Promise<string | null>;
41
+ /**
42
+ * Capture a message on the server
43
+ */
44
+ declare function captureServerMessage(message: string, level?: LogLevel, context?: CaptureContext): Promise<string | null>;
45
+
46
+ export { CaptureContext, LogLevel, SitePongConfig, captureServerException, captureServerMessage, getServerConfig, initServer };
@@ -0,0 +1,360 @@
1
+ 'use strict';
2
+
3
+ // src/core/dsn.ts
4
+ function parseDSN(dsn) {
5
+ const match = dsn.match(
6
+ /^(https?):\/\/([^@]+)@([^/]+)\/(.+)$/
7
+ );
8
+ if (!match) {
9
+ throw new Error(
10
+ `Invalid DSN: ${dsn}. Expected format: https://<public_key>@<host>/<project_id>`
11
+ );
12
+ }
13
+ const [, protocol, publicKey, host, projectId] = match;
14
+ return {
15
+ protocol,
16
+ publicKey,
17
+ host,
18
+ projectId
19
+ };
20
+ }
21
+ function getApiEndpoint(config) {
22
+ if (config.apiEndpoint) {
23
+ return config.apiEndpoint;
24
+ }
25
+ if (config.dsn) {
26
+ const parsed = parseDSN(config.dsn);
27
+ return `${parsed.protocol}://${parsed.host}`;
28
+ }
29
+ return "https://api.sitepong.com";
30
+ }
31
+ function getAuthHeaders(config) {
32
+ if (config.dsn) {
33
+ const parsed = parseDSN(config.dsn);
34
+ return {
35
+ "X-SitePong-Key": parsed.publicKey,
36
+ "X-SitePong-Project": parsed.projectId
37
+ };
38
+ }
39
+ if (config.apiKey) {
40
+ return {
41
+ Authorization: `Bearer ${config.apiKey}`
42
+ };
43
+ }
44
+ return {};
45
+ }
46
+ function validateConfig(config) {
47
+ if (!config.dsn && !config.apiKey) {
48
+ throw new Error(
49
+ "SitePong: You must provide either a DSN or an API key"
50
+ );
51
+ }
52
+ if (config.dsn && config.apiKey) {
53
+ console.warn(
54
+ "SitePong: Both DSN and API key provided. DSN will be used."
55
+ );
56
+ }
57
+ if (config.sampleRate !== void 0) {
58
+ if (config.sampleRate < 0 || config.sampleRate > 1) {
59
+ throw new Error(
60
+ "SitePong: sampleRate must be between 0 and 1"
61
+ );
62
+ }
63
+ }
64
+ }
65
+
66
+ // src/utils/platform.ts
67
+ function detectPlatform() {
68
+ if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
69
+ return "react-native";
70
+ }
71
+ if (typeof process !== "undefined" && process.versions && process.versions.node) {
72
+ return "node";
73
+ }
74
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
75
+ return "browser";
76
+ }
77
+ return "unknown";
78
+ }
79
+ var currentPlatform = detectPlatform();
80
+ function isReactNative() {
81
+ return currentPlatform === "react-native";
82
+ }
83
+
84
+ // src/utils/stacktrace.ts
85
+ function parseStackTrace(error) {
86
+ if (!error.stack) {
87
+ return [];
88
+ }
89
+ const lines = error.stack.split("\n");
90
+ const frames = [];
91
+ for (const line of lines) {
92
+ const frame = parseStackLine(line);
93
+ if (frame) {
94
+ frames.push(frame);
95
+ }
96
+ }
97
+ return frames;
98
+ }
99
+ function parseStackLine(line) {
100
+ const chromeMatch = line.match(
101
+ /^\s*at\s+(?:(.+?)\s+\()?(?:(.+?):(\d+):(\d+))\)?$/
102
+ );
103
+ if (chromeMatch) {
104
+ return {
105
+ function: chromeMatch[1] || "anonymous",
106
+ filename: chromeMatch[2],
107
+ lineno: parseInt(chromeMatch[3], 10),
108
+ colno: parseInt(chromeMatch[4], 10),
109
+ in_app: !chromeMatch[2]?.includes("node_modules")
110
+ };
111
+ }
112
+ const firefoxMatch = line.match(/^(.+?)@(.+?):(\d+):(\d+)$/);
113
+ if (firefoxMatch) {
114
+ return {
115
+ function: firefoxMatch[1] || "anonymous",
116
+ filename: firefoxMatch[2],
117
+ lineno: parseInt(firefoxMatch[3], 10),
118
+ colno: parseInt(firefoxMatch[4], 10),
119
+ in_app: !firefoxMatch[2]?.includes("node_modules")
120
+ };
121
+ }
122
+ return null;
123
+ }
124
+ function generateEventId() {
125
+ const hex = "0123456789abcdef";
126
+ let id = "";
127
+ for (let i = 0; i < 32; i++) {
128
+ id += hex[Math.floor(Math.random() * 16)];
129
+ }
130
+ return id;
131
+ }
132
+ function getBrowserContext() {
133
+ if (isReactNative()) {
134
+ return {
135
+ browser: { name: "React Native", version: "unknown" },
136
+ os: { name: "unknown", version: "unknown" },
137
+ runtime: { name: "React Native", version: "unknown" }
138
+ };
139
+ }
140
+ if (typeof process !== "undefined" && process.versions?.node) {
141
+ return {
142
+ browser: { name: "Node.js", version: process.versions.node },
143
+ os: {
144
+ name: process.platform || "unknown",
145
+ version: process.version || "unknown"
146
+ },
147
+ runtime: { name: "Node.js", version: process.versions.node }
148
+ };
149
+ }
150
+ if (typeof navigator === "undefined") {
151
+ return {
152
+ browser: { name: "unknown", version: "unknown" },
153
+ os: { name: "unknown", version: "unknown" }
154
+ };
155
+ }
156
+ const ua = navigator.userAgent;
157
+ let browserName = "unknown";
158
+ let browserVersion = "unknown";
159
+ if (ua.includes("Firefox/")) {
160
+ browserName = "Firefox";
161
+ browserVersion = ua.match(/Firefox\/(\d+)/)?.[1] || "unknown";
162
+ } else if (ua.includes("Edg/")) {
163
+ browserName = "Edge";
164
+ browserVersion = ua.match(/Edg\/(\d+)/)?.[1] || "unknown";
165
+ } else if (ua.includes("Chrome/")) {
166
+ browserName = "Chrome";
167
+ browserVersion = ua.match(/Chrome\/(\d+)/)?.[1] || "unknown";
168
+ } else if (ua.includes("Safari/") && !ua.includes("Chrome")) {
169
+ browserName = "Safari";
170
+ browserVersion = ua.match(/Version\/(\d+)/)?.[1] || "unknown";
171
+ }
172
+ let osName = "unknown";
173
+ let osVersion = "unknown";
174
+ if (ua.includes("Windows")) {
175
+ osName = "Windows";
176
+ osVersion = ua.match(/Windows NT (\d+\.\d+)/)?.[1] || "unknown";
177
+ } else if (ua.includes("Mac OS X")) {
178
+ osName = "macOS";
179
+ osVersion = ua.match(/Mac OS X (\d+[._]\d+)/)?.[1]?.replace("_", ".") || "unknown";
180
+ } else if (ua.includes("Linux")) {
181
+ osName = "Linux";
182
+ } else if (ua.includes("Android")) {
183
+ osName = "Android";
184
+ osVersion = ua.match(/Android (\d+)/)?.[1] || "unknown";
185
+ } else if (ua.includes("iOS") || ua.includes("iPhone") || ua.includes("iPad")) {
186
+ osName = "iOS";
187
+ osVersion = ua.match(/OS (\d+)/)?.[1] || "unknown";
188
+ }
189
+ return {
190
+ browser: { name: browserName, version: browserVersion },
191
+ os: { name: osName, version: osVersion }
192
+ };
193
+ }
194
+
195
+ // src/core/breadcrumbs.ts
196
+ var MAX_BREADCRUMBS = 100;
197
+ var BreadcrumbManager = class {
198
+ constructor() {
199
+ this.breadcrumbs = [];
200
+ this.maxBreadcrumbs = MAX_BREADCRUMBS;
201
+ }
202
+ setMaxBreadcrumbs(max) {
203
+ this.maxBreadcrumbs = max;
204
+ this.trim();
205
+ }
206
+ add(breadcrumb) {
207
+ const entry = {
208
+ ...breadcrumb,
209
+ timestamp: Date.now()
210
+ };
211
+ this.breadcrumbs.push(entry);
212
+ this.trim();
213
+ }
214
+ getAll() {
215
+ return [...this.breadcrumbs];
216
+ }
217
+ clear() {
218
+ this.breadcrumbs = [];
219
+ }
220
+ trim() {
221
+ if (this.breadcrumbs.length > this.maxBreadcrumbs) {
222
+ this.breadcrumbs = this.breadcrumbs.slice(-this.maxBreadcrumbs);
223
+ }
224
+ }
225
+ };
226
+ var breadcrumbs = new BreadcrumbManager();
227
+ function addBreadcrumb(breadcrumb) {
228
+ breadcrumbs.add(breadcrumb);
229
+ }
230
+ function getBreadcrumbs() {
231
+ return breadcrumbs.getAll();
232
+ }
233
+ function clearBreadcrumbs() {
234
+ breadcrumbs.clear();
235
+ }
236
+
237
+ // src/server/index.ts
238
+ var serverConfig = null;
239
+ function initServer(config) {
240
+ validateConfig(config);
241
+ serverConfig = {
242
+ enabled: true,
243
+ debug: false,
244
+ sampleRate: 1,
245
+ ...config
246
+ };
247
+ if (serverConfig.debug) {
248
+ console.log("[SitePong] Server SDK initialized");
249
+ }
250
+ }
251
+ function getServerConfig() {
252
+ return serverConfig;
253
+ }
254
+ async function captureServerException(error, context) {
255
+ if (!serverConfig?.enabled) {
256
+ return null;
257
+ }
258
+ const err = error instanceof Error ? error : new Error(String(error));
259
+ const event = createServerErrorEvent(err, context);
260
+ await sendServerEvent(event);
261
+ return event.event_id;
262
+ }
263
+ async function captureServerMessage(message, level = "info", context) {
264
+ if (!serverConfig?.enabled) {
265
+ return null;
266
+ }
267
+ const event = createServerMessageEvent(message, level, context);
268
+ await sendServerEvent(event);
269
+ return event.event_id;
270
+ }
271
+ function createServerErrorEvent(error, context) {
272
+ const browserContext = getBrowserContext();
273
+ return {
274
+ event_id: generateEventId(),
275
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
276
+ level: context?.level || "error",
277
+ message: error.message,
278
+ exception: {
279
+ type: error.name,
280
+ value: error.message,
281
+ stacktrace: parseStackTrace(error)
282
+ },
283
+ tags: { ...context?.tags, runtime: "server" },
284
+ extra: { ...context?.extra },
285
+ user: context?.user,
286
+ breadcrumbs: getBreadcrumbs(),
287
+ context: {
288
+ runtime: browserContext.runtime || { name: "Node.js", version: process.version }
289
+ },
290
+ environment: serverConfig?.environment,
291
+ release: serverConfig?.release,
292
+ request: context?.request
293
+ };
294
+ }
295
+ function createServerMessageEvent(message, level, context) {
296
+ return {
297
+ event_id: generateEventId(),
298
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
299
+ level,
300
+ message,
301
+ tags: { ...context?.tags, runtime: "server" },
302
+ extra: { ...context?.extra },
303
+ user: context?.user,
304
+ breadcrumbs: getBreadcrumbs(),
305
+ environment: serverConfig?.environment,
306
+ release: serverConfig?.release
307
+ };
308
+ }
309
+ async function sendServerEvent(event) {
310
+ if (!serverConfig) return;
311
+ const endpoint = getApiEndpoint(serverConfig);
312
+ const headers = getAuthHeaders(serverConfig);
313
+ try {
314
+ const response = await fetch(`${endpoint}/api/errors`, {
315
+ method: "POST",
316
+ headers: {
317
+ "Content-Type": "application/json",
318
+ ...headers
319
+ },
320
+ body: JSON.stringify({
321
+ title: event.exception?.type || "Error",
322
+ message: event.message,
323
+ stack: event.exception?.stacktrace?.map(
324
+ (frame) => ` at ${frame.function || "anonymous"} (${frame.filename}:${frame.lineno}:${frame.colno})`
325
+ ).join("\n"),
326
+ level: event.level,
327
+ timestamp: event.timestamp,
328
+ environment: event.environment,
329
+ release: event.release,
330
+ tags: event.tags,
331
+ extra: event.extra,
332
+ user: event.user,
333
+ breadcrumbs: event.breadcrumbs,
334
+ context: event.context,
335
+ request: event.request
336
+ })
337
+ });
338
+ if (serverConfig.debug) {
339
+ if (response.ok) {
340
+ console.log("[SitePong] Server event sent:", event.event_id);
341
+ } else {
342
+ console.error("[SitePong] Failed to send server event:", response.status);
343
+ }
344
+ }
345
+ } catch (err) {
346
+ if (serverConfig.debug) {
347
+ console.error("[SitePong] Error sending server event:", err);
348
+ }
349
+ }
350
+ }
351
+
352
+ exports.addBreadcrumb = addBreadcrumb;
353
+ exports.captureServerException = captureServerException;
354
+ exports.captureServerMessage = captureServerMessage;
355
+ exports.clearBreadcrumbs = clearBreadcrumbs;
356
+ exports.getBreadcrumbs = getBreadcrumbs;
357
+ exports.getServerConfig = getServerConfig;
358
+ exports.initServer = initServer;
359
+ //# sourceMappingURL=index.js.map
360
+ //# sourceMappingURL=index.js.map