@mushi-mushi/core 1.32.0 → 1.32.3
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/README.md +2 -2
- package/dist/index.cjs +63 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -10
- package/dist/index.d.ts +12 -10
- package/dist/index.js +63 -30
- package/dist/index.js.map +1 -1
- package/dist/reporter-channels.d.cts +1 -1
- package/dist/reporter-channels.d.ts +1 -1
- package/dist/{types-0j5BJ3aC.d.cts → types-DhR6TWJZ.d.cts} +55 -21
- package/dist/{types-0j5BJ3aC.d.ts → types-DhR6TWJZ.d.ts} +55 -21
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { M as MushiApiClient, a as MushiConfig, b as MushiPreFilterConfig, c as MushiReport, d as MushiOfflineConfig, e as MushiEnvironment, f as MushiAnalyticsConfig, g as MushiPropertyValue, h as MushiBreadcrumb } from './types-
|
|
2
|
-
export { i as MushiActivityEvent, j as MushiApiCascadeConfig, k as MushiApiResponse, l as MushiAssistantConfig, m as MushiAssistantReply, n as MushiAssistantStep, o as MushiBannerConfig, p as MushiBannerLink, q as MushiBetaChangelogEntry, r as MushiBetaModeConfig, s as MushiCaptureConfig, t as MushiCaptureEventInput, u as MushiCaptureExceptionOptions, v as MushiConsoleEntry, w as MushiCooldownConfig, x as MushiCrossAppReport, y as MushiCustomCategory, z as MushiDiagnosticsResult, A as MushiDiscoverInventoryConfig, B as MushiDiscoveryEventPayload, C as MushiEventHandler, D as MushiEventType, E as MushiHallOfFameEntry, F as
|
|
1
|
+
import { M as MushiApiClient, a as MushiConfig, b as MushiPreFilterConfig, c as MushiReport, d as MushiOfflineConfig, e as MushiEnvironment, f as MushiAnalyticsConfig, g as MushiPropertyValue, h as MushiBreadcrumb } from './types-DhR6TWJZ.cjs';
|
|
2
|
+
export { i as MushiActivityEvent, j as MushiApiCascadeConfig, k as MushiApiResponse, l as MushiAssistantConfig, m as MushiAssistantReply, n as MushiAssistantStep, o as MushiBannerConfig, p as MushiBannerLink, q as MushiBetaChangelogEntry, r as MushiBetaModeConfig, s as MushiCaptureConfig, t as MushiCaptureEventInput, u as MushiCaptureExceptionOptions, v as MushiConsoleEntry, w as MushiCooldownConfig, x as MushiCrossAppReport, y as MushiCustomCategory, z as MushiDiagnosticsResult, A as MushiDiscoverInventoryConfig, B as MushiDiscoveryEventPayload, C as MushiEventHandler, D as MushiEventType, E as MushiHallOfFameEntry, F as MushiInitConfig, G as MushiIntegrationsConfig, H as MushiLeaderboardEntry, I as MushiNetworkEntry, J as MushiNotificationsConfig, K as MushiOnDeviceClassifier, L as MushiOnDeviceClassifierInput, N as MushiOnDeviceClassifierResult, O as MushiPageContext, P as MushiPerformanceMetrics, Q as MushiPreset, R as MushiPrivacyConfig, S as MushiProactiveConfig, T as MushiProductEventPayload, U as MushiPushSubscriptionJSON, V as MushiReportBuilder, W as MushiReportCategory, X as MushiReportStatus, Y as MushiReporterChannelUnavailable, Z as MushiReporterComment, _ as MushiReporterNotificationPrefs, $ as MushiReporterPrefsUpdate, a0 as MushiReporterReport, a1 as MushiReporterReportDetail, a2 as MushiReporterTimelineItem, a3 as MushiReporterUpdates, a4 as MushiReputationResult, a5 as MushiRewardsConfig, a6 as MushiRuntimeSdkConfig, a7 as MushiRuntimeWidgetConfig, a8 as MushiSDKInstance, a9 as MushiSdkVersionInfo, aa as MushiSelectedElement, ab as MushiSentryConfig, ac as MushiSentryContext, ad as MushiSessionEventPayload, ae as MushiTesterReputation, af as MushiTierResult, ag as MushiTimelineEntry, ah as MushiTimelineKind, ai as MushiTracePropagationConfig, aj as MushiUrlMatcher, ak as MushiWidgetAnchor, al as MushiWidgetConfig } from './types-DhR6TWJZ.cjs';
|
|
3
3
|
|
|
4
|
-
/** Replay the
|
|
4
|
+
/** Replay the in-flight POST via keepalive/beacon during pagehide. */
|
|
5
5
|
declare function flushLastOutboundOnUnload(): boolean;
|
|
6
6
|
/** Header carrying the signed end-user identity token (verified server-side). */
|
|
7
7
|
declare const MUSHI_USER_TOKEN_HEADER = "X-Mushi-User-Token";
|
|
@@ -463,19 +463,21 @@ interface SessionTrackerOptions {
|
|
|
463
463
|
* Initialise the session tracker. Call once at SDK init for web environments.
|
|
464
464
|
* Subsequent calls on the same page are no-ops (idempotent).
|
|
465
465
|
*
|
|
466
|
-
* Emits, once the analytics gate allows it: session_start,
|
|
467
|
-
* minute
|
|
468
|
-
*
|
|
469
|
-
*
|
|
466
|
+
* Emits, once the analytics gate allows it: session_start, a heartbeat after
|
|
467
|
+
* each minute without another request while the tab is visible, one
|
|
468
|
+
* session_end per hide (visibilitychange/pagehide), and page_view when a
|
|
469
|
+
* history API navigation changes the pathname. Under `consent: 'required'`
|
|
470
|
+
* nothing is sent until setConsent('granted').
|
|
470
471
|
*/
|
|
471
472
|
declare function initSessionTracker(opts: SessionTrackerOptions): void;
|
|
472
473
|
/**
|
|
473
474
|
* Record a page view manually — call from framework router hooks where the
|
|
474
475
|
* history patch may fire too early (e.g. React Router v7 loader transitions),
|
|
475
|
-
* or from a host that initialised with `patchHistory: false`.
|
|
476
|
+
* or from a host that initialised with `patchHistory: false`. A call whose
|
|
477
|
+
* pathname matches the last page view is ignored: it is the same page.
|
|
476
478
|
*/
|
|
477
479
|
declare function trackPageView(route?: string): void;
|
|
478
|
-
/**
|
|
480
|
+
/** Set the identity heartbeats carry: a SHA-256 hex of the host user id, never the raw id. */
|
|
479
481
|
declare function updateSessionIdentity(userIdHash: string | null): void;
|
|
480
482
|
/** Tear down timers (e.g. in tests or SSR environments). */
|
|
481
483
|
declare function destroySessionTracker(): void;
|
|
@@ -1217,7 +1219,7 @@ declare function resolveWidgetAccent(mode: MushiThemeMode, accent?: string, acce
|
|
|
1217
1219
|
* label / CTA wording (seen as inconsistent across the four host apps).
|
|
1218
1220
|
*/
|
|
1219
1221
|
declare const MUSHI_COPY: {
|
|
1220
|
-
readonly bannerLabel: "
|
|
1222
|
+
readonly bannerLabel: "Feedback";
|
|
1221
1223
|
readonly bannerMessage: "Found a bug? Tap to report it.";
|
|
1222
1224
|
readonly bugCta: "Report a bug";
|
|
1223
1225
|
readonly featureCta: "Feature request";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { M as MushiApiClient, a as MushiConfig, b as MushiPreFilterConfig, c as MushiReport, d as MushiOfflineConfig, e as MushiEnvironment, f as MushiAnalyticsConfig, g as MushiPropertyValue, h as MushiBreadcrumb } from './types-
|
|
2
|
-
export { i as MushiActivityEvent, j as MushiApiCascadeConfig, k as MushiApiResponse, l as MushiAssistantConfig, m as MushiAssistantReply, n as MushiAssistantStep, o as MushiBannerConfig, p as MushiBannerLink, q as MushiBetaChangelogEntry, r as MushiBetaModeConfig, s as MushiCaptureConfig, t as MushiCaptureEventInput, u as MushiCaptureExceptionOptions, v as MushiConsoleEntry, w as MushiCooldownConfig, x as MushiCrossAppReport, y as MushiCustomCategory, z as MushiDiagnosticsResult, A as MushiDiscoverInventoryConfig, B as MushiDiscoveryEventPayload, C as MushiEventHandler, D as MushiEventType, E as MushiHallOfFameEntry, F as
|
|
1
|
+
import { M as MushiApiClient, a as MushiConfig, b as MushiPreFilterConfig, c as MushiReport, d as MushiOfflineConfig, e as MushiEnvironment, f as MushiAnalyticsConfig, g as MushiPropertyValue, h as MushiBreadcrumb } from './types-DhR6TWJZ.js';
|
|
2
|
+
export { i as MushiActivityEvent, j as MushiApiCascadeConfig, k as MushiApiResponse, l as MushiAssistantConfig, m as MushiAssistantReply, n as MushiAssistantStep, o as MushiBannerConfig, p as MushiBannerLink, q as MushiBetaChangelogEntry, r as MushiBetaModeConfig, s as MushiCaptureConfig, t as MushiCaptureEventInput, u as MushiCaptureExceptionOptions, v as MushiConsoleEntry, w as MushiCooldownConfig, x as MushiCrossAppReport, y as MushiCustomCategory, z as MushiDiagnosticsResult, A as MushiDiscoverInventoryConfig, B as MushiDiscoveryEventPayload, C as MushiEventHandler, D as MushiEventType, E as MushiHallOfFameEntry, F as MushiInitConfig, G as MushiIntegrationsConfig, H as MushiLeaderboardEntry, I as MushiNetworkEntry, J as MushiNotificationsConfig, K as MushiOnDeviceClassifier, L as MushiOnDeviceClassifierInput, N as MushiOnDeviceClassifierResult, O as MushiPageContext, P as MushiPerformanceMetrics, Q as MushiPreset, R as MushiPrivacyConfig, S as MushiProactiveConfig, T as MushiProductEventPayload, U as MushiPushSubscriptionJSON, V as MushiReportBuilder, W as MushiReportCategory, X as MushiReportStatus, Y as MushiReporterChannelUnavailable, Z as MushiReporterComment, _ as MushiReporterNotificationPrefs, $ as MushiReporterPrefsUpdate, a0 as MushiReporterReport, a1 as MushiReporterReportDetail, a2 as MushiReporterTimelineItem, a3 as MushiReporterUpdates, a4 as MushiReputationResult, a5 as MushiRewardsConfig, a6 as MushiRuntimeSdkConfig, a7 as MushiRuntimeWidgetConfig, a8 as MushiSDKInstance, a9 as MushiSdkVersionInfo, aa as MushiSelectedElement, ab as MushiSentryConfig, ac as MushiSentryContext, ad as MushiSessionEventPayload, ae as MushiTesterReputation, af as MushiTierResult, ag as MushiTimelineEntry, ah as MushiTimelineKind, ai as MushiTracePropagationConfig, aj as MushiUrlMatcher, ak as MushiWidgetAnchor, al as MushiWidgetConfig } from './types-DhR6TWJZ.js';
|
|
3
3
|
|
|
4
|
-
/** Replay the
|
|
4
|
+
/** Replay the in-flight POST via keepalive/beacon during pagehide. */
|
|
5
5
|
declare function flushLastOutboundOnUnload(): boolean;
|
|
6
6
|
/** Header carrying the signed end-user identity token (verified server-side). */
|
|
7
7
|
declare const MUSHI_USER_TOKEN_HEADER = "X-Mushi-User-Token";
|
|
@@ -463,19 +463,21 @@ interface SessionTrackerOptions {
|
|
|
463
463
|
* Initialise the session tracker. Call once at SDK init for web environments.
|
|
464
464
|
* Subsequent calls on the same page are no-ops (idempotent).
|
|
465
465
|
*
|
|
466
|
-
* Emits, once the analytics gate allows it: session_start,
|
|
467
|
-
* minute
|
|
468
|
-
*
|
|
469
|
-
*
|
|
466
|
+
* Emits, once the analytics gate allows it: session_start, a heartbeat after
|
|
467
|
+
* each minute without another request while the tab is visible, one
|
|
468
|
+
* session_end per hide (visibilitychange/pagehide), and page_view when a
|
|
469
|
+
* history API navigation changes the pathname. Under `consent: 'required'`
|
|
470
|
+
* nothing is sent until setConsent('granted').
|
|
470
471
|
*/
|
|
471
472
|
declare function initSessionTracker(opts: SessionTrackerOptions): void;
|
|
472
473
|
/**
|
|
473
474
|
* Record a page view manually — call from framework router hooks where the
|
|
474
475
|
* history patch may fire too early (e.g. React Router v7 loader transitions),
|
|
475
|
-
* or from a host that initialised with `patchHistory: false`.
|
|
476
|
+
* or from a host that initialised with `patchHistory: false`. A call whose
|
|
477
|
+
* pathname matches the last page view is ignored: it is the same page.
|
|
476
478
|
*/
|
|
477
479
|
declare function trackPageView(route?: string): void;
|
|
478
|
-
/**
|
|
480
|
+
/** Set the identity heartbeats carry: a SHA-256 hex of the host user id, never the raw id. */
|
|
479
481
|
declare function updateSessionIdentity(userIdHash: string | null): void;
|
|
480
482
|
/** Tear down timers (e.g. in tests or SSR environments). */
|
|
481
483
|
declare function destroySessionTracker(): void;
|
|
@@ -1217,7 +1219,7 @@ declare function resolveWidgetAccent(mode: MushiThemeMode, accent?: string, acce
|
|
|
1217
1219
|
* label / CTA wording (seen as inconsistent across the four host apps).
|
|
1218
1220
|
*/
|
|
1219
1221
|
declare const MUSHI_COPY: {
|
|
1220
|
-
readonly bannerLabel: "
|
|
1222
|
+
readonly bannerLabel: "Feedback";
|
|
1221
1223
|
readonly bannerMessage: "Found a bug? Tap to report it.";
|
|
1222
1224
|
readonly bugCta: "Report a bug";
|
|
1223
1225
|
readonly featureCta: "Feature request";
|
package/dist/index.js
CHANGED
|
@@ -167,8 +167,9 @@ function isPageUnloading() {
|
|
|
167
167
|
// src/api-client.ts
|
|
168
168
|
var lastOutbound = null;
|
|
169
169
|
function flushLastOutboundOnUnload() {
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
const outbound = lastOutbound;
|
|
171
|
+
lastOutbound = null;
|
|
172
|
+
return !!outbound && sendOnUnload(outbound);
|
|
172
173
|
}
|
|
173
174
|
var _credWarningEmitted = false;
|
|
174
175
|
var MUSHI_USER_TOKEN_HEADER = "X-Mushi-User-Token";
|
|
@@ -250,8 +251,10 @@ function createApiClient(options) {
|
|
|
250
251
|
...extraHeaders
|
|
251
252
|
};
|
|
252
253
|
const serialized = body ? JSON.stringify(body) : void 0;
|
|
254
|
+
let outbound = null;
|
|
253
255
|
if (serialized && method !== "GET" && internalKind !== "reporter-poll") {
|
|
254
|
-
|
|
256
|
+
outbound = { url, headers, body: serialized, path };
|
|
257
|
+
lastOutbound = outbound;
|
|
255
258
|
}
|
|
256
259
|
try {
|
|
257
260
|
const response = await fetch(url, {
|
|
@@ -321,6 +324,8 @@ function createApiClient(options) {
|
|
|
321
324
|
message: error instanceof Error ? error.message : "Unknown network error"
|
|
322
325
|
}
|
|
323
326
|
};
|
|
327
|
+
} finally {
|
|
328
|
+
if (lastOutbound === outbound) lastOutbound = null;
|
|
324
329
|
}
|
|
325
330
|
}
|
|
326
331
|
async function requestForReporter(method, path, reporterToken, body) {
|
|
@@ -618,6 +623,7 @@ function matchesErrorFilter(value, filters) {
|
|
|
618
623
|
continue;
|
|
619
624
|
}
|
|
620
625
|
try {
|
|
626
|
+
filter.lastIndex = 0;
|
|
621
627
|
if (filter.test(value)) return true;
|
|
622
628
|
} catch {
|
|
623
629
|
}
|
|
@@ -1588,14 +1594,10 @@ function createOfflineQueue(config = {}) {
|
|
|
1588
1594
|
});
|
|
1589
1595
|
break;
|
|
1590
1596
|
}
|
|
1591
|
-
const permanent = result.error?.code === "HTTP_400" || result.error?.code === "HTTP_413" || result.error?.code === "HTTP_422" || result.error?.code === "INGEST_ERROR" || result.error?.code === "VALIDATION_ERROR" ||
|
|
1592
|
-
// retrying re-serialises the multi-MB body every sync tick and wedges
|
|
1593
|
-
// the queue (it matches neither permanent nor transient otherwise).
|
|
1594
|
-
// SERIALIZE_FAILED (circular ref) is likewise unrecoverable on retry.
|
|
1595
|
-
result.error?.code === "PAYLOAD_TOO_LARGE" || result.error?.code === "SERIALIZE_FAILED" || typeof result.error?.message === "string" && /invalid payload|description must be at least|validation/i.test(
|
|
1597
|
+
const permanent = result.error?.code === "HTTP_400" || result.error?.status === 401 || result.error?.status === 403 || result.error?.code === "HTTP_401" || result.error?.code === "HTTP_403" || result.error?.code === "HTTP_413" || result.error?.code === "HTTP_422" || result.error?.code === "INGEST_ERROR" || result.error?.code === "VALIDATION_ERROR" || result.error?.code === "PAYLOAD_TOO_LARGE" || result.error?.code === "SERIALIZE_FAILED" || typeof result.error?.message === "string" && /invalid payload|description must be at least|validation/i.test(
|
|
1596
1598
|
result.error.message
|
|
1597
1599
|
);
|
|
1598
|
-
const transient = !permanent && (result.error?.code === "NETWORK_ERROR" || result.error?.code === "
|
|
1600
|
+
const transient = !permanent && (result.error?.code === "NETWORK_ERROR" || result.error?.code === "HTTP_429" || result.error?.code === "HTTP_502" || result.error?.code === "HTTP_503" || result.error?.code === "HTTP_504" || typeof result.error?.code === "string" && result.error.code.startsWith("HTTP_5"));
|
|
1599
1601
|
if (permanent) {
|
|
1600
1602
|
await removeRow(backend, rowId);
|
|
1601
1603
|
} else {
|
|
@@ -2040,7 +2042,7 @@ function randomSuffix() {
|
|
|
2040
2042
|
}
|
|
2041
2043
|
let n = 0;
|
|
2042
2044
|
for (const b of bytes) n = n * 256 + b >>> 0;
|
|
2043
|
-
return n.toString(36).padStart(6, "0")
|
|
2045
|
+
return (n % 36 ** 6).toString(36).padStart(6, "0");
|
|
2044
2046
|
}
|
|
2045
2047
|
|
|
2046
2048
|
// src/analytics-gate.ts
|
|
@@ -2112,7 +2114,9 @@ var _sdkVersion;
|
|
|
2112
2114
|
var _userIdHash = null;
|
|
2113
2115
|
var _reporterToken = null;
|
|
2114
2116
|
var _pageViewCount = 0;
|
|
2115
|
-
var _heartbeatTimer
|
|
2117
|
+
var _heartbeatTimer;
|
|
2118
|
+
var _lastRoute = null;
|
|
2119
|
+
var _endSent = false;
|
|
2116
2120
|
var _initialized = false;
|
|
2117
2121
|
var _active = false;
|
|
2118
2122
|
var _started = false;
|
|
@@ -2154,30 +2158,62 @@ function send(payload) {
|
|
|
2154
2158
|
if (!_client || !_active) return;
|
|
2155
2159
|
_client.postSessionEvent(payload).catch(() => {
|
|
2156
2160
|
});
|
|
2161
|
+
scheduleHeartbeat();
|
|
2162
|
+
}
|
|
2163
|
+
function clearHeartbeat() {
|
|
2164
|
+
clearTimeout(_heartbeatTimer);
|
|
2165
|
+
}
|
|
2166
|
+
function scheduleHeartbeat() {
|
|
2167
|
+
clearHeartbeat();
|
|
2168
|
+
if (!_active || globalThis.document?.visibilityState === "hidden") return;
|
|
2169
|
+
_heartbeatTimer = setTimeout(() => {
|
|
2170
|
+
send(buildPayload("session_heartbeat", { route: currentRoute() }));
|
|
2171
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
2157
2172
|
}
|
|
2158
2173
|
function recordPageView(route) {
|
|
2159
2174
|
if (!_active) return;
|
|
2175
|
+
if (route === _lastRoute) return;
|
|
2176
|
+
_lastRoute = route;
|
|
2160
2177
|
_pageViewCount += 1;
|
|
2161
2178
|
send(buildPayload("page_view", { route }));
|
|
2162
2179
|
}
|
|
2180
|
+
function sendSessionEnd() {
|
|
2181
|
+
if (_endSent || !_active) return;
|
|
2182
|
+
_endSent = true;
|
|
2183
|
+
send(buildPayload("session_end", { route: currentRoute() }));
|
|
2184
|
+
clearHeartbeat();
|
|
2185
|
+
}
|
|
2163
2186
|
function activate() {
|
|
2164
2187
|
if (_active || !_initialized) return;
|
|
2165
2188
|
_active = true;
|
|
2166
2189
|
if (!_started) {
|
|
2167
2190
|
_started = true;
|
|
2168
2191
|
_pageViewCount = 1;
|
|
2169
|
-
|
|
2192
|
+
_lastRoute = currentRoute();
|
|
2193
|
+
send(buildPayload("session_start", { route: _lastRoute, referrer: referrerOrigin() }));
|
|
2194
|
+
} else {
|
|
2195
|
+
scheduleHeartbeat();
|
|
2170
2196
|
}
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2197
|
+
}
|
|
2198
|
+
function onHide() {
|
|
2199
|
+
if (document.visibilityState === "hidden") {
|
|
2200
|
+
sendSessionEnd();
|
|
2201
|
+
} else {
|
|
2202
|
+
_endSent = false;
|
|
2203
|
+
scheduleHeartbeat();
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
function onPagehide() {
|
|
2207
|
+
sendSessionEnd();
|
|
2208
|
+
}
|
|
2209
|
+
function onPageshow(event) {
|
|
2210
|
+
if (!event.persisted) return;
|
|
2211
|
+
_endSent = false;
|
|
2212
|
+
scheduleHeartbeat();
|
|
2174
2213
|
}
|
|
2175
2214
|
function deactivate() {
|
|
2176
2215
|
_active = false;
|
|
2177
|
-
|
|
2178
|
-
clearInterval(_heartbeatTimer);
|
|
2179
|
-
_heartbeatTimer = null;
|
|
2180
|
-
}
|
|
2216
|
+
clearHeartbeat();
|
|
2181
2217
|
}
|
|
2182
2218
|
function initSessionTracker(opts) {
|
|
2183
2219
|
if (_initialized || typeof window === "undefined") return;
|
|
@@ -2187,17 +2223,11 @@ function initSessionTracker(opts) {
|
|
|
2187
2223
|
_sdkVersion = opts.sdkVersion;
|
|
2188
2224
|
_reporterToken = opts.reporterToken ?? opts.reporterTokenHash ?? null;
|
|
2189
2225
|
_userIdHash = opts.userIdHash ?? null;
|
|
2190
|
-
const onHide = () => {
|
|
2191
|
-
if (typeof document !== "undefined" && document.visibilityState === "hidden") {
|
|
2192
|
-
send(buildPayload("session_end", { route: currentRoute() }));
|
|
2193
|
-
}
|
|
2194
|
-
};
|
|
2195
2226
|
if (typeof document !== "undefined") {
|
|
2196
2227
|
document.addEventListener("visibilitychange", onHide, { passive: true });
|
|
2197
2228
|
}
|
|
2198
|
-
window.addEventListener("pagehide",
|
|
2199
|
-
|
|
2200
|
-
}, { passive: true });
|
|
2229
|
+
window.addEventListener("pagehide", onPagehide, { passive: true });
|
|
2230
|
+
window.addEventListener("pageshow", onPageshow, { passive: true });
|
|
2201
2231
|
if (opts.patchHistory !== false) {
|
|
2202
2232
|
patchHistoryForPageViews();
|
|
2203
2233
|
}
|
|
@@ -2212,6 +2242,7 @@ function trackPageView(route) {
|
|
|
2212
2242
|
recordPageView(route ?? currentRoute());
|
|
2213
2243
|
}
|
|
2214
2244
|
function updateSessionIdentity(userIdHash) {
|
|
2245
|
+
if (userIdHash && userIdHash !== _userIdHash) _lastRoute = null;
|
|
2215
2246
|
_userIdHash = userIdHash;
|
|
2216
2247
|
}
|
|
2217
2248
|
function destroySessionTracker() {
|
|
@@ -2220,6 +2251,8 @@ function destroySessionTracker() {
|
|
|
2220
2251
|
_unsubscribeConsent = null;
|
|
2221
2252
|
_initialized = false;
|
|
2222
2253
|
_started = false;
|
|
2254
|
+
_lastRoute = null;
|
|
2255
|
+
_endSent = false;
|
|
2223
2256
|
_client = null;
|
|
2224
2257
|
}
|
|
2225
2258
|
var _historyPatched = false;
|
|
@@ -2541,10 +2574,10 @@ function initEventTracker(opts) {
|
|
|
2541
2574
|
_flushTimer = setInterval(() => {
|
|
2542
2575
|
void flushNow();
|
|
2543
2576
|
}, interval);
|
|
2544
|
-
const
|
|
2577
|
+
const onHide2 = () => {
|
|
2545
2578
|
if (typeof document !== "undefined" && document.visibilityState === "hidden") void flushNow();
|
|
2546
2579
|
};
|
|
2547
|
-
if (typeof document !== "undefined") document.addEventListener("visibilitychange",
|
|
2580
|
+
if (typeof document !== "undefined") document.addEventListener("visibilitychange", onHide2, { passive: true });
|
|
2548
2581
|
window.addEventListener("pagehide", () => {
|
|
2549
2582
|
void flushNow();
|
|
2550
2583
|
}, { passive: true });
|
|
@@ -3008,7 +3041,7 @@ function resolveWidgetAccent(mode, accent = "", accentText = "") {
|
|
|
3008
3041
|
return { accent: resolvedAccent, accentWash, accentInk };
|
|
3009
3042
|
}
|
|
3010
3043
|
var MUSHI_COPY = {
|
|
3011
|
-
bannerLabel: "
|
|
3044
|
+
bannerLabel: "Feedback",
|
|
3012
3045
|
bannerMessage: "Found a bug? Tap to report it.",
|
|
3013
3046
|
bugCta: "Report a bug",
|
|
3014
3047
|
featureCta: "Feature request",
|