glitchgrab 1.15.0 → 1.16.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 +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +104 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +101 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -288,4 +288,12 @@ declare function captureContext(visitedPages: string[]): CapturedContext;
|
|
|
288
288
|
*/
|
|
289
289
|
declare function sendReport(payload: ReportPayload, baseUrl?: string): Promise<ReportResult | null>;
|
|
290
290
|
|
|
291
|
-
|
|
291
|
+
declare function computeSignature(params: {
|
|
292
|
+
errorMessage: string | undefined;
|
|
293
|
+
pageUrl: string | undefined;
|
|
294
|
+
errorStack?: string | undefined;
|
|
295
|
+
}): string;
|
|
296
|
+
declare function shouldSkipDuplicate(signature: string, windowMs?: number, now?: number): boolean;
|
|
297
|
+
declare function clearDedupCache(): void;
|
|
298
|
+
|
|
299
|
+
export { type Breadcrumb, type BreadcrumbType, type CapturedContext, type DeviceInfo, type GlitchgrabConfig, GlitchgrabErrorBoundary, GlitchgrabProvider, type GlitchgrabProviderProps, type GlitchgrabReport, type GlitchgrabSession, ReportButton, type ReportButtonProps, type ReportPayload, type ReportResult, type ReportSeverity, type ReportType, type UseGlitchgrabReturn, addBreadcrumb, captureContext, captureDeviceInfo, clearBreadcrumbs, clearDedupCache, computeSignature, fetchGlitchgrabReports, getBreadcrumbs, initBreadcrumbs, sanitizeUrl, sendReport, shouldSkipDuplicate, useGlitchgrab, useGlitchgrabActions, useGlitchgrabReports };
|
package/dist/index.d.ts
CHANGED
|
@@ -288,4 +288,12 @@ declare function captureContext(visitedPages: string[]): CapturedContext;
|
|
|
288
288
|
*/
|
|
289
289
|
declare function sendReport(payload: ReportPayload, baseUrl?: string): Promise<ReportResult | null>;
|
|
290
290
|
|
|
291
|
-
|
|
291
|
+
declare function computeSignature(params: {
|
|
292
|
+
errorMessage: string | undefined;
|
|
293
|
+
pageUrl: string | undefined;
|
|
294
|
+
errorStack?: string | undefined;
|
|
295
|
+
}): string;
|
|
296
|
+
declare function shouldSkipDuplicate(signature: string, windowMs?: number, now?: number): boolean;
|
|
297
|
+
declare function clearDedupCache(): void;
|
|
298
|
+
|
|
299
|
+
export { type Breadcrumb, type BreadcrumbType, type CapturedContext, type DeviceInfo, type GlitchgrabConfig, GlitchgrabErrorBoundary, GlitchgrabProvider, type GlitchgrabProviderProps, type GlitchgrabReport, type GlitchgrabSession, ReportButton, type ReportButtonProps, type ReportPayload, type ReportResult, type ReportSeverity, type ReportType, type UseGlitchgrabReturn, addBreadcrumb, captureContext, captureDeviceInfo, clearBreadcrumbs, clearDedupCache, computeSignature, fetchGlitchgrabReports, getBreadcrumbs, initBreadcrumbs, sanitizeUrl, sendReport, shouldSkipDuplicate, useGlitchgrab, useGlitchgrabActions, useGlitchgrabReports };
|
package/dist/index.js
CHANGED
|
@@ -38,11 +38,14 @@ __export(index_exports, {
|
|
|
38
38
|
captureContext: () => captureContext,
|
|
39
39
|
captureDeviceInfo: () => captureDeviceInfo,
|
|
40
40
|
clearBreadcrumbs: () => clearBreadcrumbs,
|
|
41
|
+
clearDedupCache: () => clearDedupCache,
|
|
42
|
+
computeSignature: () => computeSignature,
|
|
41
43
|
fetchGlitchgrabReports: () => fetchGlitchgrabReports,
|
|
42
44
|
getBreadcrumbs: () => getBreadcrumbs,
|
|
43
45
|
initBreadcrumbs: () => initBreadcrumbs,
|
|
44
46
|
sanitizeUrl: () => sanitizeUrl,
|
|
45
47
|
sendReport: () => sendReport,
|
|
48
|
+
shouldSkipDuplicate: () => shouldSkipDuplicate,
|
|
46
49
|
useGlitchgrab: () => useGlitchgrab,
|
|
47
50
|
useGlitchgrabActions: () => useGlitchgrabActions,
|
|
48
51
|
useGlitchgrabReports: () => useGlitchgrabReports
|
|
@@ -313,6 +316,73 @@ async function sendReport(payload, baseUrl) {
|
|
|
313
316
|
}
|
|
314
317
|
}
|
|
315
318
|
|
|
319
|
+
// src/dedup.ts
|
|
320
|
+
var DEFAULT_WINDOW_MS = 5 * 60 * 1e3;
|
|
321
|
+
var MAX_ENTRIES = 100;
|
|
322
|
+
var seen = /* @__PURE__ */ new Map();
|
|
323
|
+
function hashString(input) {
|
|
324
|
+
let h1 = 3735928559 ^ 0;
|
|
325
|
+
let h2 = 1103547991 ^ 0;
|
|
326
|
+
for (let i = 0; i < input.length; i++) {
|
|
327
|
+
const ch = input.charCodeAt(i);
|
|
328
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
329
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
330
|
+
}
|
|
331
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
332
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
333
|
+
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36);
|
|
334
|
+
}
|
|
335
|
+
function topStackFrame(stack) {
|
|
336
|
+
if (!stack) return "";
|
|
337
|
+
const lines = stack.split("\n");
|
|
338
|
+
for (const line of lines) {
|
|
339
|
+
const t = line.trim();
|
|
340
|
+
if (t.startsWith("at ") || t.includes("@")) {
|
|
341
|
+
return t;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return "";
|
|
345
|
+
}
|
|
346
|
+
function stripUrlQuery(url) {
|
|
347
|
+
if (!url) return "";
|
|
348
|
+
try {
|
|
349
|
+
const u = new URL(url);
|
|
350
|
+
return `${u.origin}${u.pathname}`;
|
|
351
|
+
} catch (e) {
|
|
352
|
+
const q = url.indexOf("?");
|
|
353
|
+
return q === -1 ? url : url.slice(0, q);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function computeSignature(params) {
|
|
357
|
+
var _a, _b;
|
|
358
|
+
const msg = (_b = (_a = params.errorMessage) == null ? void 0 : _a.trim()) != null ? _b : "";
|
|
359
|
+
const page = stripUrlQuery(params.pageUrl);
|
|
360
|
+
const frame = topStackFrame(params.errorStack);
|
|
361
|
+
return hashString(`${msg}|${page}|${frame}`);
|
|
362
|
+
}
|
|
363
|
+
function shouldSkipDuplicate(signature, windowMs = DEFAULT_WINDOW_MS, now = Date.now()) {
|
|
364
|
+
const last = seen.get(signature);
|
|
365
|
+
if (last !== void 0 && now - last < windowMs) {
|
|
366
|
+
return true;
|
|
367
|
+
}
|
|
368
|
+
seen.set(signature, now);
|
|
369
|
+
if (seen.size > MAX_ENTRIES) {
|
|
370
|
+
const cutoff = now - windowMs;
|
|
371
|
+
for (const [sig, ts] of seen) {
|
|
372
|
+
if (ts < cutoff) seen.delete(sig);
|
|
373
|
+
}
|
|
374
|
+
if (seen.size > MAX_ENTRIES) {
|
|
375
|
+
const excess = seen.size - MAX_ENTRIES;
|
|
376
|
+
const keys = Array.from(seen.keys()).slice(0, excess);
|
|
377
|
+
for (const k of keys) seen.delete(k);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
function clearDedupCache() {
|
|
383
|
+
seen.clear();
|
|
384
|
+
}
|
|
385
|
+
|
|
316
386
|
// src/error-boundary.tsx
|
|
317
387
|
var GlitchgrabErrorBoundary = class extends React.Component {
|
|
318
388
|
constructor(props) {
|
|
@@ -326,6 +396,15 @@ var GlitchgrabErrorBoundary = class extends React.Component {
|
|
|
326
396
|
var _a, _b;
|
|
327
397
|
try {
|
|
328
398
|
const context = captureContext(this.props.visitedPages);
|
|
399
|
+
const sig = computeSignature({
|
|
400
|
+
errorMessage: error.message,
|
|
401
|
+
pageUrl: context.url,
|
|
402
|
+
errorStack: error.stack
|
|
403
|
+
});
|
|
404
|
+
if (shouldSkipDuplicate(sig)) {
|
|
405
|
+
if (this.props.onError) this.props.onError(error);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
329
408
|
const payload = {
|
|
330
409
|
token: this.props.token,
|
|
331
410
|
source: "SDK_AUTO",
|
|
@@ -1257,25 +1336,31 @@ function GlitchgrabProviderInner({
|
|
|
1257
1336
|
if (typeof window === "undefined") return;
|
|
1258
1337
|
if (process.env.NODE_ENV === "development") return;
|
|
1259
1338
|
const handleError = (event) => {
|
|
1260
|
-
var _a, _b, _c, _d, _e;
|
|
1339
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1261
1340
|
try {
|
|
1262
1341
|
const context = captureContext(visitedPagesRef.current);
|
|
1342
|
+
const sig = computeSignature({
|
|
1343
|
+
errorMessage: event.message,
|
|
1344
|
+
pageUrl: context.url,
|
|
1345
|
+
errorStack: (_a = event.error) == null ? void 0 : _a.stack
|
|
1346
|
+
});
|
|
1347
|
+
if (shouldSkipDuplicate(sig)) return;
|
|
1263
1348
|
const payload = {
|
|
1264
1349
|
token,
|
|
1265
1350
|
source: "SDK_AUTO",
|
|
1266
1351
|
type: "BUG",
|
|
1267
1352
|
errorMessage: event.message,
|
|
1268
|
-
errorStack: (
|
|
1353
|
+
errorStack: (_b = event.error) == null ? void 0 : _b.stack,
|
|
1269
1354
|
pageUrl: context.url,
|
|
1270
1355
|
userAgent: context.userAgent,
|
|
1271
1356
|
breadcrumbs: context.breadcrumbs,
|
|
1272
|
-
deviceInfo: (
|
|
1357
|
+
deviceInfo: (_c = context.deviceInfo) != null ? _c : void 0,
|
|
1273
1358
|
metadata: {
|
|
1274
1359
|
timestamp: context.timestamp,
|
|
1275
1360
|
visitedPages: JSON.stringify(context.visitedPages),
|
|
1276
|
-
filename: (
|
|
1277
|
-
lineno: String((
|
|
1278
|
-
colno: String((
|
|
1361
|
+
filename: (_d = event.filename) != null ? _d : "",
|
|
1362
|
+
lineno: String((_e = event.lineno) != null ? _e : ""),
|
|
1363
|
+
colno: String((_f = event.colno) != null ? _f : ""),
|
|
1279
1364
|
...(session == null ? void 0 : session.userId) ? { sessionUserId: session.userId } : {},
|
|
1280
1365
|
...(session == null ? void 0 : session.name) ? { sessionUserName: String(session.name) } : {},
|
|
1281
1366
|
...(session == null ? void 0 : session.email) ? { sessionUserEmail: String(session.email) } : {}
|
|
@@ -1293,12 +1378,20 @@ function GlitchgrabProviderInner({
|
|
|
1293
1378
|
try {
|
|
1294
1379
|
const context = captureContext(visitedPagesRef.current);
|
|
1295
1380
|
const reason = event.reason;
|
|
1381
|
+
const errMsg = reason instanceof Error ? reason.message : String(reason);
|
|
1382
|
+
const errStack = reason instanceof Error ? reason.stack : void 0;
|
|
1383
|
+
const sig = computeSignature({
|
|
1384
|
+
errorMessage: errMsg,
|
|
1385
|
+
pageUrl: context.url,
|
|
1386
|
+
errorStack: errStack
|
|
1387
|
+
});
|
|
1388
|
+
if (shouldSkipDuplicate(sig)) return;
|
|
1296
1389
|
const payload = {
|
|
1297
1390
|
token,
|
|
1298
1391
|
source: "SDK_AUTO",
|
|
1299
1392
|
type: "BUG",
|
|
1300
|
-
errorMessage:
|
|
1301
|
-
errorStack:
|
|
1393
|
+
errorMessage: errMsg,
|
|
1394
|
+
errorStack: errStack,
|
|
1302
1395
|
pageUrl: context.url,
|
|
1303
1396
|
userAgent: context.userAgent,
|
|
1304
1397
|
breadcrumbs: context.breadcrumbs,
|
|
@@ -1623,11 +1716,14 @@ function useGlitchgrabActions({
|
|
|
1623
1716
|
captureContext,
|
|
1624
1717
|
captureDeviceInfo,
|
|
1625
1718
|
clearBreadcrumbs,
|
|
1719
|
+
clearDedupCache,
|
|
1720
|
+
computeSignature,
|
|
1626
1721
|
fetchGlitchgrabReports,
|
|
1627
1722
|
getBreadcrumbs,
|
|
1628
1723
|
initBreadcrumbs,
|
|
1629
1724
|
sanitizeUrl,
|
|
1630
1725
|
sendReport,
|
|
1726
|
+
shouldSkipDuplicate,
|
|
1631
1727
|
useGlitchgrab,
|
|
1632
1728
|
useGlitchgrabActions,
|
|
1633
1729
|
useGlitchgrabReports
|