@drakkar.software/sunglasses-core 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +124 -4
- package/dist/index.d.ts +124 -4
- package/dist/index.js +108 -3
- package/dist/index.mjs +104 -2
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -523,9 +523,8 @@ interface ISunglassesTypedClient<T extends EventMap> extends ISunglassesClient {
|
|
|
523
523
|
capture<K extends keyof T & string>(eventName: K, ...args: T[K] extends undefined ? [properties?: Record<string, unknown>] : [properties: T[K]]): void;
|
|
524
524
|
}
|
|
525
525
|
/**
|
|
526
|
-
* Standard properties emitted by error-capturing
|
|
527
|
-
*
|
|
528
|
-
* `@drakkar.software/sunglasses-adapter-posthog`, and `SunglassesErrorBoundary`.
|
|
526
|
+
* Standard properties emitted by error-capturing code as `$error` events.
|
|
527
|
+
* Used by `captureException`, `SunglassesErrorBoundary`, and `autoCaptureErrors`.
|
|
529
528
|
*/
|
|
530
529
|
interface ErrorEventProperties {
|
|
531
530
|
$error_message: string;
|
|
@@ -1179,6 +1178,20 @@ interface CaptureExceptionOptions {
|
|
|
1179
1178
|
* object to capture, or `null` to skip capture entirely.
|
|
1180
1179
|
*/
|
|
1181
1180
|
beforeCapture?: (props: ErrorEventProperties) => Record<string, unknown> | null;
|
|
1181
|
+
/**
|
|
1182
|
+
* Drop errors with the same fingerprint (name + message + first stack frame)
|
|
1183
|
+
* captured within {@link dedupeWindowMs}. This collapses the common
|
|
1184
|
+
* double-capture cases — e.g. an error boundary plus `console.error` capture
|
|
1185
|
+
* reporting the same render error, or a global handler firing repeatedly for
|
|
1186
|
+
* the same throw. The fingerprint deliberately ignores the `handled` flag and
|
|
1187
|
+
* `$error_source`, so the first capture wins. Default: `true`.
|
|
1188
|
+
*/
|
|
1189
|
+
dedupe?: boolean;
|
|
1190
|
+
/**
|
|
1191
|
+
* Time window (ms) used by {@link dedupe}. Identical errors within this window
|
|
1192
|
+
* are dropped. Default: `1000`.
|
|
1193
|
+
*/
|
|
1194
|
+
dedupeWindowMs?: number;
|
|
1182
1195
|
}
|
|
1183
1196
|
/**
|
|
1184
1197
|
* Normalize any thrown value into a SunGlasses `$error` event and capture it
|
|
@@ -1203,6 +1216,113 @@ interface CaptureExceptionOptions {
|
|
|
1203
1216
|
*/
|
|
1204
1217
|
declare function captureException(client: ISunglassesClient, error: unknown, options?: CaptureExceptionOptions): void;
|
|
1205
1218
|
|
|
1219
|
+
/** Console methods that can be captured. */
|
|
1220
|
+
type ConsoleLevel = 'error' | 'warn';
|
|
1221
|
+
/**
|
|
1222
|
+
* Options for {@link patchConsole}.
|
|
1223
|
+
*/
|
|
1224
|
+
interface ConsoleCaptureOptions {
|
|
1225
|
+
/** Console methods to capture. Default: `['error']`. */
|
|
1226
|
+
levels?: ConsoleLevel[];
|
|
1227
|
+
/**
|
|
1228
|
+
* Skip console output whose composed message matches any of these patterns.
|
|
1229
|
+
* Pattern is tested against the raw (pre-truncation) message.
|
|
1230
|
+
*/
|
|
1231
|
+
ignorePatterns?: RegExp[];
|
|
1232
|
+
/** Truncate the composed message to this many characters. Default: `200`. */
|
|
1233
|
+
maxMessageLength?: number;
|
|
1234
|
+
/** Include a stack trace in `$error_stack`. Default: `false` (privacy-safe). */
|
|
1235
|
+
includeStack?: boolean;
|
|
1236
|
+
/** Extra properties merged into every captured `$error` event. */
|
|
1237
|
+
properties?: Record<string, unknown>;
|
|
1238
|
+
}
|
|
1239
|
+
/**
|
|
1240
|
+
* Configuration for the providers' `autoCaptureErrors` option. Extends
|
|
1241
|
+
* {@link CaptureExceptionOptions} (applied to unhandled global errors) with
|
|
1242
|
+
* toggles for the global handlers and console capture.
|
|
1243
|
+
*/
|
|
1244
|
+
interface AutoCaptureErrorsOptions extends CaptureExceptionOptions {
|
|
1245
|
+
/**
|
|
1246
|
+
* Install the platform uncaught-error handlers (web `window` `'error'`,
|
|
1247
|
+
* React Native `ErrorUtils`). Default: `true`.
|
|
1248
|
+
*/
|
|
1249
|
+
globalHandlers?: boolean;
|
|
1250
|
+
/**
|
|
1251
|
+
* Capture unhandled promise rejections (web `window` `'unhandledrejection'`,
|
|
1252
|
+
* React Native engine-specific rejection tracking). Default: `true`.
|
|
1253
|
+
*/
|
|
1254
|
+
unhandledRejections?: boolean;
|
|
1255
|
+
/**
|
|
1256
|
+
* Also capture console output as `$error` events. `true` captures
|
|
1257
|
+
* `console.error`; pass {@link ConsoleCaptureOptions} to configure levels.
|
|
1258
|
+
* Default: off.
|
|
1259
|
+
*/
|
|
1260
|
+
console?: boolean | ConsoleCaptureOptions;
|
|
1261
|
+
}
|
|
1262
|
+
/**
|
|
1263
|
+
* Patch the global `console` so that `console.error` / `console.warn` (per
|
|
1264
|
+
* `levels`) are also captured as SunGlasses `$error` events
|
|
1265
|
+
* (`$error_handled: false`, `$error_source: 'console'`).
|
|
1266
|
+
*
|
|
1267
|
+
* Works identically on web and React Native — both expose a global `console`.
|
|
1268
|
+
* The original method is always called first, so logs still appear in the
|
|
1269
|
+
* console. Returns an unpatch function that restores the original methods.
|
|
1270
|
+
*
|
|
1271
|
+
* Guards against infinite recursion: SunGlasses' own logger writes to
|
|
1272
|
+
* `console.error`/`console.warn` (prefixed with `[SunGlasses]`), and
|
|
1273
|
+
* `client.capture()` may log on failure. A re-entrancy flag plus a prefix skip
|
|
1274
|
+
* prevent a capture -> log -> capture loop.
|
|
1275
|
+
*
|
|
1276
|
+
* @param client - SunGlasses client instance.
|
|
1277
|
+
* @param options - Optional capture configuration.
|
|
1278
|
+
* @returns A function that restores the original console methods.
|
|
1279
|
+
*
|
|
1280
|
+
* @example
|
|
1281
|
+
* ```ts
|
|
1282
|
+
* const unpatch = patchConsole(client, { levels: ['error', 'warn'] });
|
|
1283
|
+
* // ... later
|
|
1284
|
+
* unpatch();
|
|
1285
|
+
* ```
|
|
1286
|
+
*/
|
|
1287
|
+
declare function patchConsole(client: ISunglassesClient, options?: ConsoleCaptureOptions): () => void;
|
|
1288
|
+
|
|
1289
|
+
/**
|
|
1290
|
+
* Describes a global (non-render) error surfaced by a platform global handler.
|
|
1291
|
+
* Published by the providers' auto-capture handlers and consumed by
|
|
1292
|
+
* `SunglassesGlobalErrorBoundary` to decide whether to render its fallback UI.
|
|
1293
|
+
*
|
|
1294
|
+
* The raw `error` reference is forwarded only to in-process subscribers; nothing
|
|
1295
|
+
* is persisted, logged, or sent anywhere by the bus itself.
|
|
1296
|
+
*/
|
|
1297
|
+
interface GlobalErrorInfo {
|
|
1298
|
+
/** The thrown value (an `Error`, string, or arbitrary object). */
|
|
1299
|
+
error: unknown;
|
|
1300
|
+
/**
|
|
1301
|
+
* Whether the runtime considered the error fatal. Uncaught errors are fatal
|
|
1302
|
+
* unless the platform reports otherwise; unhandled promise rejections are
|
|
1303
|
+
* non-fatal.
|
|
1304
|
+
*/
|
|
1305
|
+
fatal: boolean;
|
|
1306
|
+
/** Whether the error came from an uncaught error or an unhandled rejection. */
|
|
1307
|
+
kind: 'error' | 'rejection';
|
|
1308
|
+
}
|
|
1309
|
+
/** A subscriber notified for every published {@link GlobalErrorInfo}. */
|
|
1310
|
+
type GlobalErrorListener = (info: GlobalErrorInfo) => void;
|
|
1311
|
+
/**
|
|
1312
|
+
* Publish a global error to all current subscribers. Subscriber errors are
|
|
1313
|
+
* swallowed so one faulty listener cannot break others or the caller.
|
|
1314
|
+
*
|
|
1315
|
+
* @param info - The global error descriptor.
|
|
1316
|
+
*/
|
|
1317
|
+
declare function publishGlobalError(info: GlobalErrorInfo): void;
|
|
1318
|
+
/**
|
|
1319
|
+
* Subscribe to global errors published via {@link publishGlobalError}.
|
|
1320
|
+
*
|
|
1321
|
+
* @param listener - Called for each published error.
|
|
1322
|
+
* @returns An unsubscribe function.
|
|
1323
|
+
*/
|
|
1324
|
+
declare function subscribeGlobalError(listener: GlobalErrorListener): () => void;
|
|
1325
|
+
|
|
1206
1326
|
/**
|
|
1207
1327
|
* A typed analytics stub that is safe to use before the SDK initialises.
|
|
1208
1328
|
*
|
|
@@ -1275,4 +1395,4 @@ declare function sha256Hex(input: string): Promise<string>;
|
|
|
1275
1395
|
*/
|
|
1276
1396
|
declare function nowISO(): string;
|
|
1277
1397
|
|
|
1278
|
-
export { type AppMetadata, type AppUpdateInfo, type CaptureExceptionOptions, type CleanupConfig, type ConsentHistoryEntry, ConsentManager, type ConsentState, type ConsentStatus, type ErrorEventProperties, type EventContext, type EventCountPeriod, EventCounter, type EventMap, EventQueue, type EventType, FrequencyMiddleware, type FrequencyMiddlewareOptions, type HttpAdapterConfig, type IAnalyticsAdapter, type IEventCounter, type IMiddleware, type IStorageAdapter, type ISunglassesClient, type ISunglassesTypedClient, IdentityManager, type IdentityState, LocalEventArchive, type Logger, type MiddlewareNext, MiddlewarePipeline, PiiSanitizer, SamplingMiddleware, type SamplingMiddlewareOptions, type ScreenTrackingOptions, SessionManager, type SessionState, type SunglassesConfig, SunglassesCore, type SunglassesEvent, TraitManager, type UserDataExport, asTyped, captureException, createLazyClient, createLogger, generateUUID, nowISO, sha256Hex };
|
|
1398
|
+
export { type AppMetadata, type AppUpdateInfo, type AutoCaptureErrorsOptions, type CaptureExceptionOptions, type CleanupConfig, type ConsentHistoryEntry, ConsentManager, type ConsentState, type ConsentStatus, type ConsoleCaptureOptions, type ConsoleLevel, type ErrorEventProperties, type EventContext, type EventCountPeriod, EventCounter, type EventMap, EventQueue, type EventType, FrequencyMiddleware, type FrequencyMiddlewareOptions, type GlobalErrorInfo, type GlobalErrorListener, type HttpAdapterConfig, type IAnalyticsAdapter, type IEventCounter, type IMiddleware, type IStorageAdapter, type ISunglassesClient, type ISunglassesTypedClient, IdentityManager, type IdentityState, LocalEventArchive, type Logger, type MiddlewareNext, MiddlewarePipeline, PiiSanitizer, SamplingMiddleware, type SamplingMiddlewareOptions, type ScreenTrackingOptions, SessionManager, type SessionState, type SunglassesConfig, SunglassesCore, type SunglassesEvent, TraitManager, type UserDataExport, asTyped, captureException, createLazyClient, createLogger, generateUUID, nowISO, patchConsole, publishGlobalError, sha256Hex, subscribeGlobalError };
|
package/dist/index.d.ts
CHANGED
|
@@ -523,9 +523,8 @@ interface ISunglassesTypedClient<T extends EventMap> extends ISunglassesClient {
|
|
|
523
523
|
capture<K extends keyof T & string>(eventName: K, ...args: T[K] extends undefined ? [properties?: Record<string, unknown>] : [properties: T[K]]): void;
|
|
524
524
|
}
|
|
525
525
|
/**
|
|
526
|
-
* Standard properties emitted by error-capturing
|
|
527
|
-
*
|
|
528
|
-
* `@drakkar.software/sunglasses-adapter-posthog`, and `SunglassesErrorBoundary`.
|
|
526
|
+
* Standard properties emitted by error-capturing code as `$error` events.
|
|
527
|
+
* Used by `captureException`, `SunglassesErrorBoundary`, and `autoCaptureErrors`.
|
|
529
528
|
*/
|
|
530
529
|
interface ErrorEventProperties {
|
|
531
530
|
$error_message: string;
|
|
@@ -1179,6 +1178,20 @@ interface CaptureExceptionOptions {
|
|
|
1179
1178
|
* object to capture, or `null` to skip capture entirely.
|
|
1180
1179
|
*/
|
|
1181
1180
|
beforeCapture?: (props: ErrorEventProperties) => Record<string, unknown> | null;
|
|
1181
|
+
/**
|
|
1182
|
+
* Drop errors with the same fingerprint (name + message + first stack frame)
|
|
1183
|
+
* captured within {@link dedupeWindowMs}. This collapses the common
|
|
1184
|
+
* double-capture cases — e.g. an error boundary plus `console.error` capture
|
|
1185
|
+
* reporting the same render error, or a global handler firing repeatedly for
|
|
1186
|
+
* the same throw. The fingerprint deliberately ignores the `handled` flag and
|
|
1187
|
+
* `$error_source`, so the first capture wins. Default: `true`.
|
|
1188
|
+
*/
|
|
1189
|
+
dedupe?: boolean;
|
|
1190
|
+
/**
|
|
1191
|
+
* Time window (ms) used by {@link dedupe}. Identical errors within this window
|
|
1192
|
+
* are dropped. Default: `1000`.
|
|
1193
|
+
*/
|
|
1194
|
+
dedupeWindowMs?: number;
|
|
1182
1195
|
}
|
|
1183
1196
|
/**
|
|
1184
1197
|
* Normalize any thrown value into a SunGlasses `$error` event and capture it
|
|
@@ -1203,6 +1216,113 @@ interface CaptureExceptionOptions {
|
|
|
1203
1216
|
*/
|
|
1204
1217
|
declare function captureException(client: ISunglassesClient, error: unknown, options?: CaptureExceptionOptions): void;
|
|
1205
1218
|
|
|
1219
|
+
/** Console methods that can be captured. */
|
|
1220
|
+
type ConsoleLevel = 'error' | 'warn';
|
|
1221
|
+
/**
|
|
1222
|
+
* Options for {@link patchConsole}.
|
|
1223
|
+
*/
|
|
1224
|
+
interface ConsoleCaptureOptions {
|
|
1225
|
+
/** Console methods to capture. Default: `['error']`. */
|
|
1226
|
+
levels?: ConsoleLevel[];
|
|
1227
|
+
/**
|
|
1228
|
+
* Skip console output whose composed message matches any of these patterns.
|
|
1229
|
+
* Pattern is tested against the raw (pre-truncation) message.
|
|
1230
|
+
*/
|
|
1231
|
+
ignorePatterns?: RegExp[];
|
|
1232
|
+
/** Truncate the composed message to this many characters. Default: `200`. */
|
|
1233
|
+
maxMessageLength?: number;
|
|
1234
|
+
/** Include a stack trace in `$error_stack`. Default: `false` (privacy-safe). */
|
|
1235
|
+
includeStack?: boolean;
|
|
1236
|
+
/** Extra properties merged into every captured `$error` event. */
|
|
1237
|
+
properties?: Record<string, unknown>;
|
|
1238
|
+
}
|
|
1239
|
+
/**
|
|
1240
|
+
* Configuration for the providers' `autoCaptureErrors` option. Extends
|
|
1241
|
+
* {@link CaptureExceptionOptions} (applied to unhandled global errors) with
|
|
1242
|
+
* toggles for the global handlers and console capture.
|
|
1243
|
+
*/
|
|
1244
|
+
interface AutoCaptureErrorsOptions extends CaptureExceptionOptions {
|
|
1245
|
+
/**
|
|
1246
|
+
* Install the platform uncaught-error handlers (web `window` `'error'`,
|
|
1247
|
+
* React Native `ErrorUtils`). Default: `true`.
|
|
1248
|
+
*/
|
|
1249
|
+
globalHandlers?: boolean;
|
|
1250
|
+
/**
|
|
1251
|
+
* Capture unhandled promise rejections (web `window` `'unhandledrejection'`,
|
|
1252
|
+
* React Native engine-specific rejection tracking). Default: `true`.
|
|
1253
|
+
*/
|
|
1254
|
+
unhandledRejections?: boolean;
|
|
1255
|
+
/**
|
|
1256
|
+
* Also capture console output as `$error` events. `true` captures
|
|
1257
|
+
* `console.error`; pass {@link ConsoleCaptureOptions} to configure levels.
|
|
1258
|
+
* Default: off.
|
|
1259
|
+
*/
|
|
1260
|
+
console?: boolean | ConsoleCaptureOptions;
|
|
1261
|
+
}
|
|
1262
|
+
/**
|
|
1263
|
+
* Patch the global `console` so that `console.error` / `console.warn` (per
|
|
1264
|
+
* `levels`) are also captured as SunGlasses `$error` events
|
|
1265
|
+
* (`$error_handled: false`, `$error_source: 'console'`).
|
|
1266
|
+
*
|
|
1267
|
+
* Works identically on web and React Native — both expose a global `console`.
|
|
1268
|
+
* The original method is always called first, so logs still appear in the
|
|
1269
|
+
* console. Returns an unpatch function that restores the original methods.
|
|
1270
|
+
*
|
|
1271
|
+
* Guards against infinite recursion: SunGlasses' own logger writes to
|
|
1272
|
+
* `console.error`/`console.warn` (prefixed with `[SunGlasses]`), and
|
|
1273
|
+
* `client.capture()` may log on failure. A re-entrancy flag plus a prefix skip
|
|
1274
|
+
* prevent a capture -> log -> capture loop.
|
|
1275
|
+
*
|
|
1276
|
+
* @param client - SunGlasses client instance.
|
|
1277
|
+
* @param options - Optional capture configuration.
|
|
1278
|
+
* @returns A function that restores the original console methods.
|
|
1279
|
+
*
|
|
1280
|
+
* @example
|
|
1281
|
+
* ```ts
|
|
1282
|
+
* const unpatch = patchConsole(client, { levels: ['error', 'warn'] });
|
|
1283
|
+
* // ... later
|
|
1284
|
+
* unpatch();
|
|
1285
|
+
* ```
|
|
1286
|
+
*/
|
|
1287
|
+
declare function patchConsole(client: ISunglassesClient, options?: ConsoleCaptureOptions): () => void;
|
|
1288
|
+
|
|
1289
|
+
/**
|
|
1290
|
+
* Describes a global (non-render) error surfaced by a platform global handler.
|
|
1291
|
+
* Published by the providers' auto-capture handlers and consumed by
|
|
1292
|
+
* `SunglassesGlobalErrorBoundary` to decide whether to render its fallback UI.
|
|
1293
|
+
*
|
|
1294
|
+
* The raw `error` reference is forwarded only to in-process subscribers; nothing
|
|
1295
|
+
* is persisted, logged, or sent anywhere by the bus itself.
|
|
1296
|
+
*/
|
|
1297
|
+
interface GlobalErrorInfo {
|
|
1298
|
+
/** The thrown value (an `Error`, string, or arbitrary object). */
|
|
1299
|
+
error: unknown;
|
|
1300
|
+
/**
|
|
1301
|
+
* Whether the runtime considered the error fatal. Uncaught errors are fatal
|
|
1302
|
+
* unless the platform reports otherwise; unhandled promise rejections are
|
|
1303
|
+
* non-fatal.
|
|
1304
|
+
*/
|
|
1305
|
+
fatal: boolean;
|
|
1306
|
+
/** Whether the error came from an uncaught error or an unhandled rejection. */
|
|
1307
|
+
kind: 'error' | 'rejection';
|
|
1308
|
+
}
|
|
1309
|
+
/** A subscriber notified for every published {@link GlobalErrorInfo}. */
|
|
1310
|
+
type GlobalErrorListener = (info: GlobalErrorInfo) => void;
|
|
1311
|
+
/**
|
|
1312
|
+
* Publish a global error to all current subscribers. Subscriber errors are
|
|
1313
|
+
* swallowed so one faulty listener cannot break others or the caller.
|
|
1314
|
+
*
|
|
1315
|
+
* @param info - The global error descriptor.
|
|
1316
|
+
*/
|
|
1317
|
+
declare function publishGlobalError(info: GlobalErrorInfo): void;
|
|
1318
|
+
/**
|
|
1319
|
+
* Subscribe to global errors published via {@link publishGlobalError}.
|
|
1320
|
+
*
|
|
1321
|
+
* @param listener - Called for each published error.
|
|
1322
|
+
* @returns An unsubscribe function.
|
|
1323
|
+
*/
|
|
1324
|
+
declare function subscribeGlobalError(listener: GlobalErrorListener): () => void;
|
|
1325
|
+
|
|
1206
1326
|
/**
|
|
1207
1327
|
* A typed analytics stub that is safe to use before the SDK initialises.
|
|
1208
1328
|
*
|
|
@@ -1275,4 +1395,4 @@ declare function sha256Hex(input: string): Promise<string>;
|
|
|
1275
1395
|
*/
|
|
1276
1396
|
declare function nowISO(): string;
|
|
1277
1397
|
|
|
1278
|
-
export { type AppMetadata, type AppUpdateInfo, type CaptureExceptionOptions, type CleanupConfig, type ConsentHistoryEntry, ConsentManager, type ConsentState, type ConsentStatus, type ErrorEventProperties, type EventContext, type EventCountPeriod, EventCounter, type EventMap, EventQueue, type EventType, FrequencyMiddleware, type FrequencyMiddlewareOptions, type HttpAdapterConfig, type IAnalyticsAdapter, type IEventCounter, type IMiddleware, type IStorageAdapter, type ISunglassesClient, type ISunglassesTypedClient, IdentityManager, type IdentityState, LocalEventArchive, type Logger, type MiddlewareNext, MiddlewarePipeline, PiiSanitizer, SamplingMiddleware, type SamplingMiddlewareOptions, type ScreenTrackingOptions, SessionManager, type SessionState, type SunglassesConfig, SunglassesCore, type SunglassesEvent, TraitManager, type UserDataExport, asTyped, captureException, createLazyClient, createLogger, generateUUID, nowISO, sha256Hex };
|
|
1398
|
+
export { type AppMetadata, type AppUpdateInfo, type AutoCaptureErrorsOptions, type CaptureExceptionOptions, type CleanupConfig, type ConsentHistoryEntry, ConsentManager, type ConsentState, type ConsentStatus, type ConsoleCaptureOptions, type ConsoleLevel, type ErrorEventProperties, type EventContext, type EventCountPeriod, EventCounter, type EventMap, EventQueue, type EventType, FrequencyMiddleware, type FrequencyMiddlewareOptions, type GlobalErrorInfo, type GlobalErrorListener, type HttpAdapterConfig, type IAnalyticsAdapter, type IEventCounter, type IMiddleware, type IStorageAdapter, type ISunglassesClient, type ISunglassesTypedClient, IdentityManager, type IdentityState, LocalEventArchive, type Logger, type MiddlewareNext, MiddlewarePipeline, PiiSanitizer, SamplingMiddleware, type SamplingMiddlewareOptions, type ScreenTrackingOptions, SessionManager, type SessionState, type SunglassesConfig, SunglassesCore, type SunglassesEvent, TraitManager, type UserDataExport, asTyped, captureException, createLazyClient, createLogger, generateUUID, nowISO, patchConsole, publishGlobalError, sha256Hex, subscribeGlobalError };
|
package/dist/index.js
CHANGED
|
@@ -38,7 +38,10 @@ __export(index_exports, {
|
|
|
38
38
|
createLogger: () => createLogger,
|
|
39
39
|
generateUUID: () => generateUUID,
|
|
40
40
|
nowISO: () => nowISO,
|
|
41
|
-
|
|
41
|
+
patchConsole: () => patchConsole,
|
|
42
|
+
publishGlobalError: () => publishGlobalError,
|
|
43
|
+
sha256Hex: () => sha256Hex,
|
|
44
|
+
subscribeGlobalError: () => subscribeGlobalError
|
|
42
45
|
});
|
|
43
46
|
module.exports = __toCommonJS(index_exports);
|
|
44
47
|
|
|
@@ -1611,6 +1614,22 @@ function extractStack(stack, maxFrames) {
|
|
|
1611
1614
|
}
|
|
1612
1615
|
return void 0;
|
|
1613
1616
|
}
|
|
1617
|
+
var dedupeStore = /* @__PURE__ */ new WeakMap();
|
|
1618
|
+
function isDuplicate(client, fingerprint, windowMs) {
|
|
1619
|
+
const now = Date.now();
|
|
1620
|
+
let seen = dedupeStore.get(client);
|
|
1621
|
+
if (!seen) {
|
|
1622
|
+
seen = /* @__PURE__ */ new Map();
|
|
1623
|
+
dedupeStore.set(client, seen);
|
|
1624
|
+
}
|
|
1625
|
+
for (const [fp, ts] of seen) {
|
|
1626
|
+
if (now - ts > windowMs) seen.delete(fp);
|
|
1627
|
+
}
|
|
1628
|
+
const last = seen.get(fingerprint);
|
|
1629
|
+
if (last !== void 0 && now - last <= windowMs) return true;
|
|
1630
|
+
seen.set(fingerprint, now);
|
|
1631
|
+
return false;
|
|
1632
|
+
}
|
|
1614
1633
|
function captureException(client, error, options = {}) {
|
|
1615
1634
|
const {
|
|
1616
1635
|
handled = true,
|
|
@@ -1620,11 +1639,18 @@ function captureException(client, error, options = {}) {
|
|
|
1620
1639
|
maxMessageLength = 200,
|
|
1621
1640
|
ignorePatterns = [],
|
|
1622
1641
|
properties,
|
|
1623
|
-
beforeCapture
|
|
1642
|
+
beforeCapture,
|
|
1643
|
+
dedupe = true,
|
|
1644
|
+
dedupeWindowMs = 1e3
|
|
1624
1645
|
} = options;
|
|
1625
1646
|
const normalized = normalizeError(error);
|
|
1626
1647
|
const rawMessage = normalized.message;
|
|
1627
1648
|
if (ignorePatterns.some((p) => p.test(rawMessage))) return;
|
|
1649
|
+
if (dedupe) {
|
|
1650
|
+
const firstFrame = extractStack(normalized.stack, 1) ?? "";
|
|
1651
|
+
const fingerprint = `${normalized.name}|${rawMessage}|${firstFrame}`;
|
|
1652
|
+
if (isDuplicate(client, fingerprint, dedupeWindowMs)) return;
|
|
1653
|
+
}
|
|
1628
1654
|
let props = {
|
|
1629
1655
|
...properties,
|
|
1630
1656
|
$error_message: rawMessage.slice(0, maxMessageLength),
|
|
@@ -1645,6 +1671,82 @@ function captureException(client, error, options = {}) {
|
|
|
1645
1671
|
}
|
|
1646
1672
|
}
|
|
1647
1673
|
|
|
1674
|
+
// src/patchConsole.ts
|
|
1675
|
+
var SELF_LOG_PREFIX = "[SunGlasses]";
|
|
1676
|
+
var LEVEL_TO_SEVERITY = {
|
|
1677
|
+
error: "error",
|
|
1678
|
+
warn: "warning"
|
|
1679
|
+
};
|
|
1680
|
+
function composeMessage(args) {
|
|
1681
|
+
return args.map((arg) => {
|
|
1682
|
+
if (typeof arg === "string") return arg;
|
|
1683
|
+
if (arg instanceof Error) return arg.message;
|
|
1684
|
+
try {
|
|
1685
|
+
return typeof arg === "object" && arg !== null ? JSON.stringify(arg) : String(arg);
|
|
1686
|
+
} catch {
|
|
1687
|
+
return "[object]";
|
|
1688
|
+
}
|
|
1689
|
+
}).join(" ");
|
|
1690
|
+
}
|
|
1691
|
+
function patchConsole(client, options = {}) {
|
|
1692
|
+
const {
|
|
1693
|
+
levels = ["error"],
|
|
1694
|
+
ignorePatterns = [],
|
|
1695
|
+
maxMessageLength = 200,
|
|
1696
|
+
includeStack = false,
|
|
1697
|
+
properties
|
|
1698
|
+
} = options;
|
|
1699
|
+
const uniqueLevels = Array.from(new Set(levels));
|
|
1700
|
+
const originals = /* @__PURE__ */ new Map();
|
|
1701
|
+
let isCapturing = false;
|
|
1702
|
+
for (const level of uniqueLevels) {
|
|
1703
|
+
const original = console[level];
|
|
1704
|
+
originals.set(level, original);
|
|
1705
|
+
console[level] = (...args) => {
|
|
1706
|
+
original.apply(console, args);
|
|
1707
|
+
if (isCapturing) return;
|
|
1708
|
+
if (typeof args[0] === "string" && args[0].startsWith(SELF_LOG_PREFIX)) return;
|
|
1709
|
+
const rawMessage = composeMessage(args);
|
|
1710
|
+
if (ignorePatterns.some((p) => p.test(rawMessage))) return;
|
|
1711
|
+
const errorArg = args.find((a) => a instanceof Error);
|
|
1712
|
+
isCapturing = true;
|
|
1713
|
+
try {
|
|
1714
|
+
captureException(client, errorArg ?? rawMessage, {
|
|
1715
|
+
handled: false,
|
|
1716
|
+
level: LEVEL_TO_SEVERITY[level],
|
|
1717
|
+
includeStack,
|
|
1718
|
+
maxMessageLength,
|
|
1719
|
+
properties: { ...properties, $error_source: "console" }
|
|
1720
|
+
});
|
|
1721
|
+
} finally {
|
|
1722
|
+
isCapturing = false;
|
|
1723
|
+
}
|
|
1724
|
+
};
|
|
1725
|
+
}
|
|
1726
|
+
return () => {
|
|
1727
|
+
for (const [level, original] of originals) {
|
|
1728
|
+
console[level] = original;
|
|
1729
|
+
}
|
|
1730
|
+
};
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
// src/errorBus.ts
|
|
1734
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
1735
|
+
function publishGlobalError(info) {
|
|
1736
|
+
for (const listener of listeners) {
|
|
1737
|
+
try {
|
|
1738
|
+
listener(info);
|
|
1739
|
+
} catch {
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
function subscribeGlobalError(listener) {
|
|
1744
|
+
listeners.add(listener);
|
|
1745
|
+
return () => {
|
|
1746
|
+
listeners.delete(listener);
|
|
1747
|
+
};
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1648
1750
|
// src/LazyClient.ts
|
|
1649
1751
|
function createLazyClient() {
|
|
1650
1752
|
let _inner = null;
|
|
@@ -1782,5 +1884,8 @@ function createLazyClient() {
|
|
|
1782
1884
|
createLogger,
|
|
1783
1885
|
generateUUID,
|
|
1784
1886
|
nowISO,
|
|
1785
|
-
|
|
1887
|
+
patchConsole,
|
|
1888
|
+
publishGlobalError,
|
|
1889
|
+
sha256Hex,
|
|
1890
|
+
subscribeGlobalError
|
|
1786
1891
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1567,6 +1567,22 @@ function extractStack(stack, maxFrames) {
|
|
|
1567
1567
|
}
|
|
1568
1568
|
return void 0;
|
|
1569
1569
|
}
|
|
1570
|
+
var dedupeStore = /* @__PURE__ */ new WeakMap();
|
|
1571
|
+
function isDuplicate(client, fingerprint, windowMs) {
|
|
1572
|
+
const now = Date.now();
|
|
1573
|
+
let seen = dedupeStore.get(client);
|
|
1574
|
+
if (!seen) {
|
|
1575
|
+
seen = /* @__PURE__ */ new Map();
|
|
1576
|
+
dedupeStore.set(client, seen);
|
|
1577
|
+
}
|
|
1578
|
+
for (const [fp, ts] of seen) {
|
|
1579
|
+
if (now - ts > windowMs) seen.delete(fp);
|
|
1580
|
+
}
|
|
1581
|
+
const last = seen.get(fingerprint);
|
|
1582
|
+
if (last !== void 0 && now - last <= windowMs) return true;
|
|
1583
|
+
seen.set(fingerprint, now);
|
|
1584
|
+
return false;
|
|
1585
|
+
}
|
|
1570
1586
|
function captureException(client, error, options = {}) {
|
|
1571
1587
|
const {
|
|
1572
1588
|
handled = true,
|
|
@@ -1576,11 +1592,18 @@ function captureException(client, error, options = {}) {
|
|
|
1576
1592
|
maxMessageLength = 200,
|
|
1577
1593
|
ignorePatterns = [],
|
|
1578
1594
|
properties,
|
|
1579
|
-
beforeCapture
|
|
1595
|
+
beforeCapture,
|
|
1596
|
+
dedupe = true,
|
|
1597
|
+
dedupeWindowMs = 1e3
|
|
1580
1598
|
} = options;
|
|
1581
1599
|
const normalized = normalizeError(error);
|
|
1582
1600
|
const rawMessage = normalized.message;
|
|
1583
1601
|
if (ignorePatterns.some((p) => p.test(rawMessage))) return;
|
|
1602
|
+
if (dedupe) {
|
|
1603
|
+
const firstFrame = extractStack(normalized.stack, 1) ?? "";
|
|
1604
|
+
const fingerprint = `${normalized.name}|${rawMessage}|${firstFrame}`;
|
|
1605
|
+
if (isDuplicate(client, fingerprint, dedupeWindowMs)) return;
|
|
1606
|
+
}
|
|
1584
1607
|
let props = {
|
|
1585
1608
|
...properties,
|
|
1586
1609
|
$error_message: rawMessage.slice(0, maxMessageLength),
|
|
@@ -1601,6 +1624,82 @@ function captureException(client, error, options = {}) {
|
|
|
1601
1624
|
}
|
|
1602
1625
|
}
|
|
1603
1626
|
|
|
1627
|
+
// src/patchConsole.ts
|
|
1628
|
+
var SELF_LOG_PREFIX = "[SunGlasses]";
|
|
1629
|
+
var LEVEL_TO_SEVERITY = {
|
|
1630
|
+
error: "error",
|
|
1631
|
+
warn: "warning"
|
|
1632
|
+
};
|
|
1633
|
+
function composeMessage(args) {
|
|
1634
|
+
return args.map((arg) => {
|
|
1635
|
+
if (typeof arg === "string") return arg;
|
|
1636
|
+
if (arg instanceof Error) return arg.message;
|
|
1637
|
+
try {
|
|
1638
|
+
return typeof arg === "object" && arg !== null ? JSON.stringify(arg) : String(arg);
|
|
1639
|
+
} catch {
|
|
1640
|
+
return "[object]";
|
|
1641
|
+
}
|
|
1642
|
+
}).join(" ");
|
|
1643
|
+
}
|
|
1644
|
+
function patchConsole(client, options = {}) {
|
|
1645
|
+
const {
|
|
1646
|
+
levels = ["error"],
|
|
1647
|
+
ignorePatterns = [],
|
|
1648
|
+
maxMessageLength = 200,
|
|
1649
|
+
includeStack = false,
|
|
1650
|
+
properties
|
|
1651
|
+
} = options;
|
|
1652
|
+
const uniqueLevels = Array.from(new Set(levels));
|
|
1653
|
+
const originals = /* @__PURE__ */ new Map();
|
|
1654
|
+
let isCapturing = false;
|
|
1655
|
+
for (const level of uniqueLevels) {
|
|
1656
|
+
const original = console[level];
|
|
1657
|
+
originals.set(level, original);
|
|
1658
|
+
console[level] = (...args) => {
|
|
1659
|
+
original.apply(console, args);
|
|
1660
|
+
if (isCapturing) return;
|
|
1661
|
+
if (typeof args[0] === "string" && args[0].startsWith(SELF_LOG_PREFIX)) return;
|
|
1662
|
+
const rawMessage = composeMessage(args);
|
|
1663
|
+
if (ignorePatterns.some((p) => p.test(rawMessage))) return;
|
|
1664
|
+
const errorArg = args.find((a) => a instanceof Error);
|
|
1665
|
+
isCapturing = true;
|
|
1666
|
+
try {
|
|
1667
|
+
captureException(client, errorArg ?? rawMessage, {
|
|
1668
|
+
handled: false,
|
|
1669
|
+
level: LEVEL_TO_SEVERITY[level],
|
|
1670
|
+
includeStack,
|
|
1671
|
+
maxMessageLength,
|
|
1672
|
+
properties: { ...properties, $error_source: "console" }
|
|
1673
|
+
});
|
|
1674
|
+
} finally {
|
|
1675
|
+
isCapturing = false;
|
|
1676
|
+
}
|
|
1677
|
+
};
|
|
1678
|
+
}
|
|
1679
|
+
return () => {
|
|
1680
|
+
for (const [level, original] of originals) {
|
|
1681
|
+
console[level] = original;
|
|
1682
|
+
}
|
|
1683
|
+
};
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
// src/errorBus.ts
|
|
1687
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
1688
|
+
function publishGlobalError(info) {
|
|
1689
|
+
for (const listener of listeners) {
|
|
1690
|
+
try {
|
|
1691
|
+
listener(info);
|
|
1692
|
+
} catch {
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
function subscribeGlobalError(listener) {
|
|
1697
|
+
listeners.add(listener);
|
|
1698
|
+
return () => {
|
|
1699
|
+
listeners.delete(listener);
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1604
1703
|
// src/LazyClient.ts
|
|
1605
1704
|
function createLazyClient() {
|
|
1606
1705
|
let _inner = null;
|
|
@@ -1737,5 +1836,8 @@ export {
|
|
|
1737
1836
|
createLogger,
|
|
1738
1837
|
generateUUID,
|
|
1739
1838
|
nowISO,
|
|
1740
|
-
|
|
1839
|
+
patchConsole,
|
|
1840
|
+
publishGlobalError,
|
|
1841
|
+
sha256Hex,
|
|
1842
|
+
subscribeGlobalError
|
|
1741
1843
|
};
|