@mushi-mushi/web 1.3.0 → 1.5.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.cjs +121 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +121 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -3090,6 +3090,15 @@ function maskElement(el) {
|
|
|
3090
3090
|
}
|
|
3091
3091
|
|
|
3092
3092
|
// src/capture/performance.ts
|
|
3093
|
+
var INP_DURATION_THRESHOLD_MS = 40;
|
|
3094
|
+
function describeElement(target) {
|
|
3095
|
+
if (!target || !target.tagName) return void 0;
|
|
3096
|
+
const el = target;
|
|
3097
|
+
const tag = el.tagName.toLowerCase();
|
|
3098
|
+
const id = el.id ? `#${el.id}` : "";
|
|
3099
|
+
const cls = el.classList && el.classList.length > 0 ? `.${el.classList[0]}` : "";
|
|
3100
|
+
return `${tag}${id}${cls}`;
|
|
3101
|
+
}
|
|
3093
3102
|
function createPerformanceCapture() {
|
|
3094
3103
|
const metrics = {};
|
|
3095
3104
|
const observers = [];
|
|
@@ -3141,6 +3150,53 @@ function createPerformanceCapture() {
|
|
|
3141
3150
|
observers.push(longTaskObserver);
|
|
3142
3151
|
} catch {
|
|
3143
3152
|
}
|
|
3153
|
+
try {
|
|
3154
|
+
const seenInteractions = /* @__PURE__ */ new Map();
|
|
3155
|
+
const inpObserver = new PerformanceObserver((list) => {
|
|
3156
|
+
for (const entry of list.getEntries()) {
|
|
3157
|
+
const interactionId = entry.interactionId;
|
|
3158
|
+
if (!interactionId) continue;
|
|
3159
|
+
const prev = seenInteractions.get(interactionId) ?? 0;
|
|
3160
|
+
if (entry.duration > prev) {
|
|
3161
|
+
seenInteractions.set(interactionId, entry.duration);
|
|
3162
|
+
}
|
|
3163
|
+
if (entry.duration > (metrics.inp ?? 0)) {
|
|
3164
|
+
metrics.inp = entry.duration;
|
|
3165
|
+
const inputDelay = entry.processingStart - entry.startTime;
|
|
3166
|
+
const processingDuration = entry.processingEnd - entry.processingStart;
|
|
3167
|
+
const presentationDelay = entry.startTime + entry.duration - entry.processingEnd;
|
|
3168
|
+
metrics.inpAttribution = {
|
|
3169
|
+
eventType: entry.name,
|
|
3170
|
+
targetSelector: describeElement(entry.target),
|
|
3171
|
+
inputDelay: Math.max(0, inputDelay),
|
|
3172
|
+
processingDuration: Math.max(0, processingDuration),
|
|
3173
|
+
presentationDelay: Math.max(0, presentationDelay)
|
|
3174
|
+
};
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
3177
|
+
});
|
|
3178
|
+
inpObserver.observe({
|
|
3179
|
+
type: "event",
|
|
3180
|
+
// `durationThreshold` filters out fast (< 40 ms) interactions
|
|
3181
|
+
// that sit below human perception. Spec-recommended floor.
|
|
3182
|
+
durationThreshold: INP_DURATION_THRESHOLD_MS,
|
|
3183
|
+
buffered: true
|
|
3184
|
+
});
|
|
3185
|
+
observers.push(inpObserver);
|
|
3186
|
+
} catch {
|
|
3187
|
+
}
|
|
3188
|
+
try {
|
|
3189
|
+
const fidObserver = new PerformanceObserver((list) => {
|
|
3190
|
+
for (const entry of list.getEntries()) {
|
|
3191
|
+
if (metrics.fid === void 0) {
|
|
3192
|
+
metrics.fid = entry.processingStart - entry.startTime;
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
});
|
|
3196
|
+
fidObserver.observe({ type: "first-input", buffered: true });
|
|
3197
|
+
observers.push(fidObserver);
|
|
3198
|
+
} catch {
|
|
3199
|
+
}
|
|
3144
3200
|
}
|
|
3145
3201
|
if (typeof performance !== "undefined" && performance.getEntriesByType) {
|
|
3146
3202
|
try {
|
|
@@ -3971,7 +4027,7 @@ function createProactiveManager(config = {}) {
|
|
|
3971
4027
|
|
|
3972
4028
|
// src/version.ts
|
|
3973
4029
|
var MUSHI_SDK_PACKAGE = "@mushi-mushi/web";
|
|
3974
|
-
var MUSHI_SDK_VERSION = "1.
|
|
4030
|
+
var MUSHI_SDK_VERSION = "1.5.0" ;
|
|
3975
4031
|
|
|
3976
4032
|
// src/mushi.ts
|
|
3977
4033
|
var instance = null;
|
|
@@ -4448,17 +4504,43 @@ function createInstance(config) {
|
|
|
4448
4504
|
};
|
|
4449
4505
|
config.integrations.custom(builder);
|
|
4450
4506
|
}
|
|
4451
|
-
|
|
4507
|
+
let finalReport = report;
|
|
4508
|
+
if (config.beforeSendFeedback) {
|
|
4509
|
+
try {
|
|
4510
|
+
const hookResult = await Promise.race([
|
|
4511
|
+
Promise.resolve(config.beforeSendFeedback(report)),
|
|
4512
|
+
// 2s timeout — async hooks must not block the user's "submit"
|
|
4513
|
+
// for longer than the network would. Falls back to original.
|
|
4514
|
+
new Promise(
|
|
4515
|
+
(resolve) => setTimeout(() => resolve(report), 2e3)
|
|
4516
|
+
)
|
|
4517
|
+
]);
|
|
4518
|
+
if (hookResult === null) {
|
|
4519
|
+
log.info("Report dropped by beforeSendFeedback hook", { reportId: report.id });
|
|
4520
|
+
return;
|
|
4521
|
+
}
|
|
4522
|
+
finalReport = hookResult;
|
|
4523
|
+
} catch (err) {
|
|
4524
|
+
log.warn("beforeSendFeedback hook threw \u2014 sending unmodified report", {
|
|
4525
|
+
error: err instanceof Error ? err.message : String(err)
|
|
4526
|
+
});
|
|
4527
|
+
}
|
|
4528
|
+
}
|
|
4529
|
+
emit("report:submitted", { reportId: finalReport.id });
|
|
4452
4530
|
if (typeof navigator !== "undefined" && !navigator.onLine) {
|
|
4453
|
-
await offlineQueue.enqueue(
|
|
4454
|
-
log.info("Offline \u2014 report queued", { reportId:
|
|
4455
|
-
emit("report:queued", { reportId:
|
|
4531
|
+
await offlineQueue.enqueue(finalReport);
|
|
4532
|
+
log.info("Offline \u2014 report queued", { reportId: finalReport.id });
|
|
4533
|
+
emit("report:queued", { reportId: finalReport.id });
|
|
4456
4534
|
return;
|
|
4457
4535
|
}
|
|
4458
|
-
const result = await apiClient2.submitReport(
|
|
4536
|
+
const result = await apiClient2.submitReport(finalReport);
|
|
4459
4537
|
if (result.ok) {
|
|
4460
4538
|
log.info("Report sent", { reportId: result.data?.reportId });
|
|
4461
4539
|
emit("report:sent", { reportId: result.data?.reportId });
|
|
4540
|
+
if (result.data?.cursorAgentId) {
|
|
4541
|
+
const d = result.data;
|
|
4542
|
+
emit("report:dispatched", { reportId: d.reportId, agentId: d.cursorAgentId, fixId: d.fixId });
|
|
4543
|
+
}
|
|
4462
4544
|
breadcrumbs.add({
|
|
4463
4545
|
category: "lifecycle",
|
|
4464
4546
|
level: "info",
|
|
@@ -4475,13 +4557,13 @@ function createInstance(config) {
|
|
|
4475
4557
|
} catch {
|
|
4476
4558
|
}
|
|
4477
4559
|
} else {
|
|
4478
|
-
log.warn("Report failed, queuing for retry", { reportId:
|
|
4479
|
-
await offlineQueue.enqueue(
|
|
4480
|
-
emit("report:failed", { reportId:
|
|
4560
|
+
log.warn("Report failed, queuing for retry", { reportId: finalReport.id, error: result.error });
|
|
4561
|
+
await offlineQueue.enqueue(finalReport);
|
|
4562
|
+
emit("report:failed", { reportId: finalReport.id, error: result.error });
|
|
4481
4563
|
breadcrumbs.add({
|
|
4482
4564
|
category: "lifecycle",
|
|
4483
4565
|
level: "warning",
|
|
4484
|
-
message: `Mushi report queued for retry (${
|
|
4566
|
+
message: `Mushi report queued for retry (${finalReport.id})`
|
|
4485
4567
|
});
|
|
4486
4568
|
}
|
|
4487
4569
|
pendingScreenshot = null;
|
|
@@ -4743,6 +4825,35 @@ function createInstance(config) {
|
|
|
4743
4825
|
if (typeof globalThis !== "undefined" && (bootstrapConfig.debug ?? false)) {
|
|
4744
4826
|
exposeMarketingRecorder(widget);
|
|
4745
4827
|
}
|
|
4828
|
+
if (typeof window !== "undefined" && typeof localStorage !== "undefined") {
|
|
4829
|
+
const SENTINEL_KEY = "mushi:last-run";
|
|
4830
|
+
let crashed = null;
|
|
4831
|
+
try {
|
|
4832
|
+
const previous = localStorage.getItem(SENTINEL_KEY);
|
|
4833
|
+
crashed = previous === null ? null : previous === "unfinished";
|
|
4834
|
+
localStorage.setItem(SENTINEL_KEY, "unfinished");
|
|
4835
|
+
} catch {
|
|
4836
|
+
crashed = null;
|
|
4837
|
+
}
|
|
4838
|
+
try {
|
|
4839
|
+
window.addEventListener("pagehide", () => {
|
|
4840
|
+
try {
|
|
4841
|
+
localStorage.setItem(SENTINEL_KEY, "clean");
|
|
4842
|
+
} catch {
|
|
4843
|
+
}
|
|
4844
|
+
});
|
|
4845
|
+
} catch {
|
|
4846
|
+
}
|
|
4847
|
+
if (typeof bootstrapConfig.onCrashedLastRun === "function") {
|
|
4848
|
+
try {
|
|
4849
|
+
bootstrapConfig.onCrashedLastRun({ crashed });
|
|
4850
|
+
} catch (err) {
|
|
4851
|
+
log.warn("onCrashedLastRun hook threw", {
|
|
4852
|
+
error: err instanceof Error ? err.message : String(err)
|
|
4853
|
+
});
|
|
4854
|
+
}
|
|
4855
|
+
}
|
|
4856
|
+
}
|
|
4746
4857
|
return sdk;
|
|
4747
4858
|
}
|
|
4748
4859
|
function mergeRuntimeConfig(config, runtime) {
|