@crashsense/core 1.0.4 → 1.1.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 +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +411 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +411 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -30,7 +30,12 @@ function resolveConfig(userConfig) {
|
|
|
30
30
|
preCrashMemoryThreshold: userConfig.preCrashMemoryThreshold ?? 0.8,
|
|
31
31
|
piiScrubbing: userConfig.piiScrubbing ?? true,
|
|
32
32
|
debug: userConfig.debug ?? false,
|
|
33
|
-
onCrash: userConfig.onCrash ?? null
|
|
33
|
+
onCrash: userConfig.onCrash ?? null,
|
|
34
|
+
enableOOMRecovery: userConfig.enableOOMRecovery ?? false,
|
|
35
|
+
checkpointInterval: userConfig.checkpointInterval ?? 1e4,
|
|
36
|
+
oomRecoveryThreshold: userConfig.oomRecoveryThreshold ?? 0.3,
|
|
37
|
+
flushEndpoint: userConfig.flushEndpoint ?? null,
|
|
38
|
+
onOOMRecovery: userConfig.onOOMRecovery ?? null
|
|
34
39
|
};
|
|
35
40
|
}
|
|
36
41
|
|
|
@@ -968,6 +973,373 @@ function classifyCrash(event) {
|
|
|
968
973
|
};
|
|
969
974
|
}
|
|
970
975
|
|
|
976
|
+
// src/checkpoint-manager.ts
|
|
977
|
+
var CHECKPOINT_KEY = "__crashsense_checkpoint";
|
|
978
|
+
var CHECKPOINT_VERSION = 1;
|
|
979
|
+
function createCheckpointManager(bus, config, sessionId, deviceInfo, getSystemState, getBreadcrumbs) {
|
|
980
|
+
let intervalId = null;
|
|
981
|
+
let checkpointCount = 0;
|
|
982
|
+
const preCrashWarnings = [];
|
|
983
|
+
let lastMemoryTrend = null;
|
|
984
|
+
function hasSessionStorage() {
|
|
985
|
+
try {
|
|
986
|
+
return typeof sessionStorage !== "undefined" && sessionStorage !== null;
|
|
987
|
+
} catch {
|
|
988
|
+
return false;
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
function writeCheckpoint() {
|
|
992
|
+
if (!hasSessionStorage()) return;
|
|
993
|
+
checkpointCount++;
|
|
994
|
+
const systemState = getSystemState();
|
|
995
|
+
if (systemState.memory?.trend) {
|
|
996
|
+
lastMemoryTrend = systemState.memory.trend;
|
|
997
|
+
}
|
|
998
|
+
const checkpoint = {
|
|
999
|
+
version: CHECKPOINT_VERSION,
|
|
1000
|
+
timestamp: Date.now(),
|
|
1001
|
+
sessionId,
|
|
1002
|
+
appId: config.appId,
|
|
1003
|
+
url: typeof location !== "undefined" ? location.href : "",
|
|
1004
|
+
breadcrumbs: getBreadcrumbs().slice(-20),
|
|
1005
|
+
systemState,
|
|
1006
|
+
device: deviceInfo,
|
|
1007
|
+
preCrashWarnings: preCrashWarnings.slice(-5),
|
|
1008
|
+
memoryTrend: lastMemoryTrend,
|
|
1009
|
+
checkpointCount
|
|
1010
|
+
};
|
|
1011
|
+
try {
|
|
1012
|
+
sessionStorage.setItem(CHECKPOINT_KEY, JSON.stringify(checkpoint));
|
|
1013
|
+
bus.emit("checkpoint_written", { timestamp: checkpoint.timestamp, sessionId });
|
|
1014
|
+
} catch {
|
|
1015
|
+
try {
|
|
1016
|
+
const minimal = {
|
|
1017
|
+
...checkpoint,
|
|
1018
|
+
breadcrumbs: checkpoint.breadcrumbs.slice(-5),
|
|
1019
|
+
systemState: { memory: systemState.memory }
|
|
1020
|
+
};
|
|
1021
|
+
sessionStorage.setItem(CHECKPOINT_KEY, JSON.stringify(minimal));
|
|
1022
|
+
} catch {
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
bus.on("pre_crash_warning", (data) => {
|
|
1027
|
+
preCrashWarnings.push({
|
|
1028
|
+
level: data.level,
|
|
1029
|
+
reason: data.reason,
|
|
1030
|
+
timestamp: data.timestamp
|
|
1031
|
+
});
|
|
1032
|
+
while (preCrashWarnings.length > 10) {
|
|
1033
|
+
preCrashWarnings.shift();
|
|
1034
|
+
}
|
|
1035
|
+
writeCheckpoint();
|
|
1036
|
+
});
|
|
1037
|
+
bus.on("crash_detected", () => {
|
|
1038
|
+
writeCheckpoint();
|
|
1039
|
+
});
|
|
1040
|
+
return {
|
|
1041
|
+
start() {
|
|
1042
|
+
if (typeof window === "undefined") return;
|
|
1043
|
+
if (!hasSessionStorage()) return;
|
|
1044
|
+
writeCheckpoint();
|
|
1045
|
+
intervalId = setInterval(writeCheckpoint, config.checkpointInterval);
|
|
1046
|
+
},
|
|
1047
|
+
stop() {
|
|
1048
|
+
if (intervalId !== null) {
|
|
1049
|
+
clearInterval(intervalId);
|
|
1050
|
+
intervalId = null;
|
|
1051
|
+
}
|
|
1052
|
+
},
|
|
1053
|
+
/** Force an immediate checkpoint write (used by lifecycle flush) */
|
|
1054
|
+
flush() {
|
|
1055
|
+
writeCheckpoint();
|
|
1056
|
+
},
|
|
1057
|
+
/** Read and remove the stored checkpoint (used by OOM recovery on next load) */
|
|
1058
|
+
static: {
|
|
1059
|
+
readCheckpoint() {
|
|
1060
|
+
try {
|
|
1061
|
+
if (typeof sessionStorage === "undefined") return null;
|
|
1062
|
+
const raw = sessionStorage.getItem(CHECKPOINT_KEY);
|
|
1063
|
+
if (!raw) return null;
|
|
1064
|
+
const data = JSON.parse(raw);
|
|
1065
|
+
if (data.version !== CHECKPOINT_VERSION) return null;
|
|
1066
|
+
return data;
|
|
1067
|
+
} catch {
|
|
1068
|
+
return null;
|
|
1069
|
+
}
|
|
1070
|
+
},
|
|
1071
|
+
clearCheckpoint() {
|
|
1072
|
+
try {
|
|
1073
|
+
if (typeof sessionStorage !== "undefined") {
|
|
1074
|
+
sessionStorage.removeItem(CHECKPOINT_KEY);
|
|
1075
|
+
}
|
|
1076
|
+
} catch {
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
},
|
|
1080
|
+
/** Clear checkpoint on clean shutdown (destroy) */
|
|
1081
|
+
clearOnDestroy() {
|
|
1082
|
+
try {
|
|
1083
|
+
if (hasSessionStorage()) {
|
|
1084
|
+
sessionStorage.removeItem(CHECKPOINT_KEY);
|
|
1085
|
+
}
|
|
1086
|
+
} catch {
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
function readCheckpoint() {
|
|
1092
|
+
try {
|
|
1093
|
+
if (typeof sessionStorage === "undefined") return null;
|
|
1094
|
+
const raw = sessionStorage.getItem(CHECKPOINT_KEY);
|
|
1095
|
+
if (!raw) return null;
|
|
1096
|
+
const data = JSON.parse(raw);
|
|
1097
|
+
if (data.version !== CHECKPOINT_VERSION) return null;
|
|
1098
|
+
return data;
|
|
1099
|
+
} catch {
|
|
1100
|
+
return null;
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
function clearCheckpoint() {
|
|
1104
|
+
try {
|
|
1105
|
+
if (typeof sessionStorage !== "undefined") {
|
|
1106
|
+
sessionStorage.removeItem(CHECKPOINT_KEY);
|
|
1107
|
+
}
|
|
1108
|
+
} catch {
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
function getNavigationType() {
|
|
1112
|
+
try {
|
|
1113
|
+
if (typeof performance === "undefined") return "unknown";
|
|
1114
|
+
const entries = performance.getEntriesByType("navigation");
|
|
1115
|
+
if (entries.length > 0) {
|
|
1116
|
+
return entries[0].type || "unknown";
|
|
1117
|
+
}
|
|
1118
|
+
} catch {
|
|
1119
|
+
}
|
|
1120
|
+
return "unknown";
|
|
1121
|
+
}
|
|
1122
|
+
function getWasDiscarded() {
|
|
1123
|
+
try {
|
|
1124
|
+
const doc = document;
|
|
1125
|
+
if ("wasDiscarded" in doc) {
|
|
1126
|
+
return doc.wasDiscarded;
|
|
1127
|
+
}
|
|
1128
|
+
} catch {
|
|
1129
|
+
}
|
|
1130
|
+
return void 0;
|
|
1131
|
+
}
|
|
1132
|
+
function detectOOMRecovery(bus, config, currentSessionId) {
|
|
1133
|
+
if (typeof window === "undefined") return null;
|
|
1134
|
+
const checkpoint = readCheckpoint();
|
|
1135
|
+
if (!checkpoint) return null;
|
|
1136
|
+
clearCheckpoint();
|
|
1137
|
+
const now = Date.now();
|
|
1138
|
+
const timeSinceCheckpoint = now - checkpoint.timestamp;
|
|
1139
|
+
const MAX_OOM_AGE = 5 * 60 * 1e3;
|
|
1140
|
+
if (timeSinceCheckpoint > MAX_OOM_AGE) return null;
|
|
1141
|
+
if (checkpoint.appId !== config.appId) return null;
|
|
1142
|
+
const wasDiscarded = getWasDiscarded();
|
|
1143
|
+
const navigationType = getNavigationType();
|
|
1144
|
+
const deviceInfo = collectDeviceInfo();
|
|
1145
|
+
const signals = [];
|
|
1146
|
+
let probability = 0;
|
|
1147
|
+
if (wasDiscarded === true) {
|
|
1148
|
+
probability += 0.45;
|
|
1149
|
+
signals.push({
|
|
1150
|
+
signal: "document_was_discarded",
|
|
1151
|
+
weight: 0.45,
|
|
1152
|
+
evidence: "document.wasDiscarded is true \u2014 OS confirmed tab discard"
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1155
|
+
if (navigationType === "reload" && timeSinceCheckpoint < 3e4) {
|
|
1156
|
+
probability += 0.25;
|
|
1157
|
+
signals.push({
|
|
1158
|
+
signal: "recent_reload",
|
|
1159
|
+
weight: 0.25,
|
|
1160
|
+
evidence: `Page reloaded ${Math.round(timeSinceCheckpoint / 1e3)}s after last checkpoint`
|
|
1161
|
+
});
|
|
1162
|
+
} else if (navigationType === "reload" && timeSinceCheckpoint < 6e4) {
|
|
1163
|
+
probability += 0.15;
|
|
1164
|
+
signals.push({
|
|
1165
|
+
signal: "moderate_reload",
|
|
1166
|
+
weight: 0.15,
|
|
1167
|
+
evidence: `Page reloaded ${Math.round(timeSinceCheckpoint / 1e3)}s after last checkpoint`
|
|
1168
|
+
});
|
|
1169
|
+
}
|
|
1170
|
+
if (checkpoint.memoryTrend === "growing") {
|
|
1171
|
+
probability += 0.1;
|
|
1172
|
+
signals.push({
|
|
1173
|
+
signal: "memory_growing_trend",
|
|
1174
|
+
weight: 0.1,
|
|
1175
|
+
evidence: "Memory was in growing trend before tab died"
|
|
1176
|
+
});
|
|
1177
|
+
} else if (checkpoint.memoryTrend === "spike") {
|
|
1178
|
+
probability += 0.08;
|
|
1179
|
+
signals.push({
|
|
1180
|
+
signal: "memory_spike",
|
|
1181
|
+
weight: 0.08,
|
|
1182
|
+
evidence: "Memory was spiking before tab died"
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
if (checkpoint.preCrashWarnings.length > 0) {
|
|
1186
|
+
const highestLevel = checkpoint.preCrashWarnings.reduce((max, w) => {
|
|
1187
|
+
const severity = { elevated: 1, critical: 2, imminent: 3 };
|
|
1188
|
+
return (severity[w.level] || 0) > (severity[max.level] || 0) ? w : max;
|
|
1189
|
+
}, checkpoint.preCrashWarnings[0]);
|
|
1190
|
+
if (highestLevel.level === "imminent") {
|
|
1191
|
+
probability += 0.15;
|
|
1192
|
+
signals.push({
|
|
1193
|
+
signal: "pre_crash_warning_imminent",
|
|
1194
|
+
weight: 0.15,
|
|
1195
|
+
evidence: `Pre-crash warning at IMMINENT level: ${highestLevel.reason}`
|
|
1196
|
+
});
|
|
1197
|
+
} else if (highestLevel.level === "critical") {
|
|
1198
|
+
probability += 0.1;
|
|
1199
|
+
signals.push({
|
|
1200
|
+
signal: "pre_crash_warning_critical",
|
|
1201
|
+
weight: 0.1,
|
|
1202
|
+
evidence: `Pre-crash warning at CRITICAL level: ${highestLevel.reason}`
|
|
1203
|
+
});
|
|
1204
|
+
} else {
|
|
1205
|
+
probability += 0.05;
|
|
1206
|
+
signals.push({
|
|
1207
|
+
signal: "pre_crash_warning_elevated",
|
|
1208
|
+
weight: 0.05,
|
|
1209
|
+
evidence: `Pre-crash warning at ELEVATED level: ${highestLevel.reason}`
|
|
1210
|
+
});
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
const memUtil = checkpoint.systemState?.memory?.utilizationPercent;
|
|
1214
|
+
if (memUtil !== void 0 && memUtil !== null && memUtil > 85) {
|
|
1215
|
+
probability += 0.1;
|
|
1216
|
+
signals.push({
|
|
1217
|
+
signal: "high_memory_at_checkpoint",
|
|
1218
|
+
weight: 0.1,
|
|
1219
|
+
evidence: `Memory was at ${memUtil}% utilization at last checkpoint`
|
|
1220
|
+
});
|
|
1221
|
+
}
|
|
1222
|
+
if (checkpoint.device.touchSupport && checkpoint.device.deviceMemory !== null && checkpoint.device.deviceMemory <= 4) {
|
|
1223
|
+
probability += 0.05;
|
|
1224
|
+
signals.push({
|
|
1225
|
+
signal: "mobile_low_memory_device",
|
|
1226
|
+
weight: 0.05,
|
|
1227
|
+
evidence: `Touch device with ${checkpoint.device.deviceMemory}GB RAM \u2014 higher OOM risk`
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
probability = Math.min(probability, 1);
|
|
1231
|
+
if (probability < config.oomRecoveryThreshold) return null;
|
|
1232
|
+
const report = {
|
|
1233
|
+
id: generateId(),
|
|
1234
|
+
type: "oom_recovery",
|
|
1235
|
+
timestamp: now,
|
|
1236
|
+
probability,
|
|
1237
|
+
sessionId: currentSessionId,
|
|
1238
|
+
previousSessionId: checkpoint.sessionId,
|
|
1239
|
+
timeSinceLastCheckpoint: timeSinceCheckpoint,
|
|
1240
|
+
wasDiscarded,
|
|
1241
|
+
navigationType,
|
|
1242
|
+
lastCheckpoint: checkpoint,
|
|
1243
|
+
device: deviceInfo,
|
|
1244
|
+
signals
|
|
1245
|
+
};
|
|
1246
|
+
bus.emit("oom_recovery", { report });
|
|
1247
|
+
if (config.onOOMRecovery) {
|
|
1248
|
+
try {
|
|
1249
|
+
config.onOOMRecovery(report);
|
|
1250
|
+
} catch {
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
if (config.debug) {
|
|
1254
|
+
logOOMRecovery(report);
|
|
1255
|
+
}
|
|
1256
|
+
return report;
|
|
1257
|
+
}
|
|
1258
|
+
function logOOMRecovery(report) {
|
|
1259
|
+
if (typeof console === "undefined") return;
|
|
1260
|
+
const header = `[CrashSense] OOM Recovery Detected (${(report.probability * 100).toFixed(0)}% confidence)`;
|
|
1261
|
+
const details = [
|
|
1262
|
+
`Previous session: ${report.previousSessionId}`,
|
|
1263
|
+
`Time since last checkpoint: ${Math.round(report.timeSinceLastCheckpoint / 1e3)}s`,
|
|
1264
|
+
`Navigation type: ${report.navigationType}`,
|
|
1265
|
+
`document.wasDiscarded: ${report.wasDiscarded}`,
|
|
1266
|
+
`Last URL: ${report.lastCheckpoint.url}`,
|
|
1267
|
+
`Memory trend: ${report.lastCheckpoint.memoryTrend || "unknown"}`,
|
|
1268
|
+
`Pre-crash warnings: ${report.lastCheckpoint.preCrashWarnings.length}`,
|
|
1269
|
+
`Breadcrumbs recovered: ${report.lastCheckpoint.breadcrumbs.length}`
|
|
1270
|
+
];
|
|
1271
|
+
console.groupCollapsed?.(header) ?? console.log(header);
|
|
1272
|
+
for (const d of details) console.log(d);
|
|
1273
|
+
if (report.signals.length > 0) {
|
|
1274
|
+
console.log("Signals:");
|
|
1275
|
+
for (const s of report.signals) {
|
|
1276
|
+
console.log(` - ${s.signal} (${(s.weight * 100).toFixed(0)}%): ${s.evidence}`);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
console.groupEnd?.();
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
// src/lifecycle-flush.ts
|
|
1283
|
+
function createLifecycleFlush(bus, config, sessionId, getSystemState, getBreadcrumbs, flushCheckpoint) {
|
|
1284
|
+
let installed = false;
|
|
1285
|
+
function buildFlushPayload(reason) {
|
|
1286
|
+
return JSON.stringify({
|
|
1287
|
+
type: "lifecycle_flush",
|
|
1288
|
+
reason,
|
|
1289
|
+
timestamp: Date.now(),
|
|
1290
|
+
sessionId,
|
|
1291
|
+
appId: config.appId,
|
|
1292
|
+
url: typeof location !== "undefined" ? location.href : "",
|
|
1293
|
+
breadcrumbs: getBreadcrumbs().slice(-10),
|
|
1294
|
+
systemState: getSystemState()
|
|
1295
|
+
});
|
|
1296
|
+
}
|
|
1297
|
+
function flush(reason) {
|
|
1298
|
+
flushCheckpoint();
|
|
1299
|
+
if (config.flushEndpoint && typeof navigator !== "undefined" && navigator.sendBeacon) {
|
|
1300
|
+
try {
|
|
1301
|
+
const payload = buildFlushPayload(reason);
|
|
1302
|
+
navigator.sendBeacon(config.flushEndpoint, payload);
|
|
1303
|
+
} catch {
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
bus.emit("lifecycle_flush", { reason, timestamp: Date.now() });
|
|
1307
|
+
}
|
|
1308
|
+
function handleVisibilityChange() {
|
|
1309
|
+
if (typeof document !== "undefined" && document.visibilityState === "hidden") {
|
|
1310
|
+
flush("visibilitychange_hidden");
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
function handlePageHide() {
|
|
1314
|
+
flush("pagehide");
|
|
1315
|
+
}
|
|
1316
|
+
function handleFreeze() {
|
|
1317
|
+
flush("freeze");
|
|
1318
|
+
}
|
|
1319
|
+
return {
|
|
1320
|
+
install() {
|
|
1321
|
+
if (typeof window === "undefined") return;
|
|
1322
|
+
if (installed) return;
|
|
1323
|
+
installed = true;
|
|
1324
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
1325
|
+
window.addEventListener("pagehide", handlePageHide, { capture: true });
|
|
1326
|
+
if ("onfreeze" in document) {
|
|
1327
|
+
document.addEventListener("freeze", handleFreeze);
|
|
1328
|
+
}
|
|
1329
|
+
},
|
|
1330
|
+
uninstall() {
|
|
1331
|
+
if (typeof window === "undefined") return;
|
|
1332
|
+
if (!installed) return;
|
|
1333
|
+
installed = false;
|
|
1334
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
1335
|
+
window.removeEventListener("pagehide", handlePageHide, { capture: true });
|
|
1336
|
+
if ("onfreeze" in document) {
|
|
1337
|
+
document.removeEventListener("freeze", handleFreeze);
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
};
|
|
1341
|
+
}
|
|
1342
|
+
|
|
971
1343
|
// src/crashsense.ts
|
|
972
1344
|
function createCrashSense(userConfig) {
|
|
973
1345
|
const config = resolveConfig(userConfig);
|
|
@@ -985,6 +1357,34 @@ function createCrashSense(userConfig) {
|
|
|
985
1357
|
const breadcrumbTracker = createBreadcrumbTracker(bus);
|
|
986
1358
|
const iframeTracker = createIframeTracker(bus);
|
|
987
1359
|
const preCrashWarning = createPreCrashWarning(bus, config, memoryMonitor, iframeTracker);
|
|
1360
|
+
const checkpointManager = createCheckpointManager(
|
|
1361
|
+
bus,
|
|
1362
|
+
config,
|
|
1363
|
+
sessionId,
|
|
1364
|
+
deviceInfo,
|
|
1365
|
+
() => ({
|
|
1366
|
+
memory: memoryMonitor.getSnapshot(),
|
|
1367
|
+
cpu: eventLoopMonitor.getCpuSnapshot(),
|
|
1368
|
+
eventLoop: eventLoopMonitor.getEventLoopSnapshot(),
|
|
1369
|
+
network: networkMonitor.getSnapshot(),
|
|
1370
|
+
iframe: config.enableIframeTracking ? iframeTracker.getSnapshot() : void 0
|
|
1371
|
+
}),
|
|
1372
|
+
() => breadcrumbTracker.getBreadcrumbs()
|
|
1373
|
+
);
|
|
1374
|
+
const lifecycleFlush = createLifecycleFlush(
|
|
1375
|
+
bus,
|
|
1376
|
+
config,
|
|
1377
|
+
sessionId,
|
|
1378
|
+
() => ({
|
|
1379
|
+
memory: memoryMonitor.getSnapshot(),
|
|
1380
|
+
cpu: eventLoopMonitor.getCpuSnapshot(),
|
|
1381
|
+
eventLoop: eventLoopMonitor.getEventLoopSnapshot(),
|
|
1382
|
+
network: networkMonitor.getSnapshot(),
|
|
1383
|
+
iframe: config.enableIframeTracking ? iframeTracker.getSnapshot() : void 0
|
|
1384
|
+
}),
|
|
1385
|
+
() => breadcrumbTracker.getBreadcrumbs(),
|
|
1386
|
+
() => checkpointManager.flush()
|
|
1387
|
+
);
|
|
988
1388
|
function buildRawEvent(error, source) {
|
|
989
1389
|
const stack = error.stack ? parseStackTrace(error.stack) : [];
|
|
990
1390
|
return {
|
|
@@ -1133,6 +1533,9 @@ function createCrashSense(userConfig) {
|
|
|
1133
1533
|
data: { level: data.level, memoryUtilization: data.memoryUtilization, iframeCount: data.iframeCount }
|
|
1134
1534
|
});
|
|
1135
1535
|
});
|
|
1536
|
+
if (config.enableOOMRecovery) {
|
|
1537
|
+
detectOOMRecovery(bus, config, sessionId);
|
|
1538
|
+
}
|
|
1136
1539
|
errorInterceptor.install();
|
|
1137
1540
|
breadcrumbTracker.install();
|
|
1138
1541
|
if (config.enableMemoryMonitoring) memoryMonitor.start();
|
|
@@ -1140,6 +1543,10 @@ function createCrashSense(userConfig) {
|
|
|
1140
1543
|
if (config.enableNetworkMonitoring) networkMonitor.start();
|
|
1141
1544
|
if (config.enableIframeTracking) iframeTracker.start();
|
|
1142
1545
|
if (config.enablePreCrashWarning) preCrashWarning.start();
|
|
1546
|
+
if (config.enableOOMRecovery) {
|
|
1547
|
+
checkpointManager.start();
|
|
1548
|
+
lifecycleFlush.install();
|
|
1549
|
+
}
|
|
1143
1550
|
const core = {
|
|
1144
1551
|
get config() {
|
|
1145
1552
|
return config;
|
|
@@ -1197,6 +1604,9 @@ function createCrashSense(userConfig) {
|
|
|
1197
1604
|
networkMonitor.stop();
|
|
1198
1605
|
iframeTracker.stop();
|
|
1199
1606
|
preCrashWarning.stop();
|
|
1607
|
+
checkpointManager.stop();
|
|
1608
|
+
checkpointManager.clearOnDestroy();
|
|
1609
|
+
lifecycleFlush.uninstall();
|
|
1200
1610
|
for (const plugin of plugins) {
|
|
1201
1611
|
plugin.teardown();
|
|
1202
1612
|
}
|