@mushi-mushi/core 1.7.2 → 1.7.5

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.cts CHANGED
@@ -117,6 +117,18 @@ interface MushiWidgetConfig {
117
117
  featureRequestDescription?: string;
118
118
  /** Minimum description character count before the submit button enables. */
119
119
  minDescriptionLength?: number;
120
+ /**
121
+ * CSS selectors of host-app elements that the widget trigger and panel must
122
+ * never visually overlap. At render time the widget queries each selector,
123
+ * measures the union bounding rect, and nudges `--mushi-top` / `--mushi-bottom`
124
+ * so the panel clears every avoided element by at least 8px.
125
+ *
126
+ * Typical use: avoid a sticky mobile header or a fixed sign-in CTA.
127
+ *
128
+ * @example
129
+ * avoidSelectors: ['[data-mobile-header]', '#sign-in-cta']
130
+ */
131
+ avoidSelectors?: string[];
120
132
  }
121
133
  /**
122
134
  * Configuration for the `trigger: 'banner'` header-strip launcher.
@@ -336,6 +348,18 @@ interface MushiCooldownConfig {
336
348
  maxProactivePerSession?: number;
337
349
  dismissCooldownHours?: number;
338
350
  suppressAfterDismissals?: number;
351
+ /**
352
+ * Cross-reload re-show cooldown, in minutes (default 30; `0` disables).
353
+ *
354
+ * The `dismissCooldownHours` window only starts after a clean dismissal is
355
+ * recorded (widget `onClose`). A page reload or crash tears down the JS
356
+ * context before that, so on a broken/reloading page the proactive panel
357
+ * would otherwise re-open on every load. When a prompt is shown the SDK
358
+ * persists a timestamp; a fresh session (new JS context) suppresses prompts
359
+ * shown within this window. Within a live session the per-session limit
360
+ * governs instead, so this never blocks a legitimate second trigger.
361
+ */
362
+ reshowCooldownMinutes?: number;
339
363
  }
340
364
  interface MushiPreFilterConfig {
341
365
  enabled?: boolean;
@@ -833,6 +857,34 @@ interface MushiDiagnosticsResult {
833
857
  captureScreenshotAvailable: boolean;
834
858
  captureNetworkIntercepting: boolean;
835
859
  sdkVersion: string;
860
+ /**
861
+ * True when the widget host element has `pointer-events: none` and
862
+ * zero width/height — i.e. it cannot act as a touch blocker over host UI.
863
+ * False when the SDK has not yet mounted, or when a consumer has overridden
864
+ * the host styles without restoring the pass-through contract.
865
+ */
866
+ widgetHostPointerSafe: boolean;
867
+ /**
868
+ * Bounding rect of the widget host element (`offsetWidth × offsetHeight`).
869
+ * Should be `{ width: 0, height: 0 }` for a healthy SDK — the host is
870
+ * zero-sized with `overflow: visible` so the shadow internals extend
871
+ * outward without creating a hit-test surface. `null` when not mounted.
872
+ */
873
+ widgetHostBounds: {
874
+ width: number;
875
+ height: number;
876
+ } | null;
877
+ /**
878
+ * True when the widget is currently suppressed: `hideOnSelector` matched an
879
+ * element, `hideOnRoutes` matched the current pathname, or `hide()` was
880
+ * called. A suppressed widget renders nothing and removes the body nudge.
881
+ */
882
+ widgetSuppressed: boolean;
883
+ /**
884
+ * True when `trigger: 'banner'` is active and the banner is currently
885
+ * rendered in the shadow DOM (not dismissed, not suppressed).
886
+ */
887
+ bannerRendered: boolean;
836
888
  }
837
889
  interface MushiSDKInstance {
838
890
  /**
@@ -1204,6 +1256,27 @@ declare function captureEnvironment(): MushiEnvironment;
1204
1256
 
1205
1257
  declare function getReporterToken(): string;
1206
1258
 
1259
+ /**
1260
+ * RFC-4122 v4 UUID generator with a capability ladder so it works in every
1261
+ * runtime a Mushi SDK ships to:
1262
+ *
1263
+ * 1. `crypto.randomUUID()` — browsers (secure context), Node 19+, Deno
1264
+ * 2. `crypto.getRandomValues()` — older browsers, RN with a crypto polyfill
1265
+ * 3. `Math.random()` — Hermes / JSC without a crypto polyfill
1266
+ *
1267
+ * Why this exists: report ids are written to the `reports.id uuid` column on
1268
+ * the backend. SDKs that minted ad-hoc ids (`rn-<ts>-<rand>`, `mushi_<hex>`)
1269
+ * failed the Postgres uuid cast (22P02) and the report was silently dropped
1270
+ * (Sentry MUSHI-MUSHI-SERVER-D). Emitting a well-formed UUID at the source
1271
+ * keeps the value valid end-to-end.
1272
+ *
1273
+ * A report id is an identifier, not a secret. The `Math.random` fallback only
1274
+ * affects collision odds — negligible at our volume, and the backend dedupes
1275
+ * on the `reports` primary key regardless — so we never throw just because a
1276
+ * runtime lacks a CSPRNG.
1277
+ */
1278
+ declare function newUuid(): string;
1279
+
1207
1280
  /**
1208
1281
  * §3c — stable device fingerprint hash.
1209
1282
  *
@@ -1402,4 +1475,4 @@ declare function createLogger(options: LoggerOptions): Logger;
1402
1475
  */
1403
1476
  declare const noopLogger: Logger;
1404
1477
 
1405
- export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiBannerConfig, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiEventHandler, type MushiEventType, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiNetworkEntry, type MushiOfflineConfig, type MushiOnDeviceClassifier, type MushiOnDeviceClassifierInput, type MushiOnDeviceClassifierResult, type MushiPerformanceMetrics, type MushiPreFilterConfig, type MushiPreset, type MushiPrivacyConfig, type MushiProactiveConfig, type MushiRegion, type MushiReport, type MushiReportBuilder, type MushiReportCategory, type MushiReportStatus, type MushiReporterComment, type MushiReporterReport, type MushiReputationResult, type MushiRewardsConfig, type MushiRuntimeSdkConfig, type MushiSDKInstance, type MushiSdkVersionInfo, type MushiSelectedElement, type MushiSentryConfig, type MushiSentryContext, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PiiScrubberConfig, type PreFilterResult, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, captureEnvironment, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, getDeviceFingerprintHash, getReporterToken, getSessionId, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
1478
+ export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiBannerConfig, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiEventHandler, type MushiEventType, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiNetworkEntry, type MushiOfflineConfig, type MushiOnDeviceClassifier, type MushiOnDeviceClassifierInput, type MushiOnDeviceClassifierResult, type MushiPerformanceMetrics, type MushiPreFilterConfig, type MushiPreset, type MushiPrivacyConfig, type MushiProactiveConfig, type MushiRegion, type MushiReport, type MushiReportBuilder, type MushiReportCategory, type MushiReportStatus, type MushiReporterComment, type MushiReporterReport, type MushiReputationResult, type MushiRewardsConfig, type MushiRuntimeSdkConfig, type MushiSDKInstance, type MushiSdkVersionInfo, type MushiSelectedElement, type MushiSentryConfig, type MushiSentryContext, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PiiScrubberConfig, type PreFilterResult, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, captureEnvironment, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, getDeviceFingerprintHash, getReporterToken, getSessionId, newUuid, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
package/dist/index.d.ts CHANGED
@@ -117,6 +117,18 @@ interface MushiWidgetConfig {
117
117
  featureRequestDescription?: string;
118
118
  /** Minimum description character count before the submit button enables. */
119
119
  minDescriptionLength?: number;
120
+ /**
121
+ * CSS selectors of host-app elements that the widget trigger and panel must
122
+ * never visually overlap. At render time the widget queries each selector,
123
+ * measures the union bounding rect, and nudges `--mushi-top` / `--mushi-bottom`
124
+ * so the panel clears every avoided element by at least 8px.
125
+ *
126
+ * Typical use: avoid a sticky mobile header or a fixed sign-in CTA.
127
+ *
128
+ * @example
129
+ * avoidSelectors: ['[data-mobile-header]', '#sign-in-cta']
130
+ */
131
+ avoidSelectors?: string[];
120
132
  }
121
133
  /**
122
134
  * Configuration for the `trigger: 'banner'` header-strip launcher.
@@ -336,6 +348,18 @@ interface MushiCooldownConfig {
336
348
  maxProactivePerSession?: number;
337
349
  dismissCooldownHours?: number;
338
350
  suppressAfterDismissals?: number;
351
+ /**
352
+ * Cross-reload re-show cooldown, in minutes (default 30; `0` disables).
353
+ *
354
+ * The `dismissCooldownHours` window only starts after a clean dismissal is
355
+ * recorded (widget `onClose`). A page reload or crash tears down the JS
356
+ * context before that, so on a broken/reloading page the proactive panel
357
+ * would otherwise re-open on every load. When a prompt is shown the SDK
358
+ * persists a timestamp; a fresh session (new JS context) suppresses prompts
359
+ * shown within this window. Within a live session the per-session limit
360
+ * governs instead, so this never blocks a legitimate second trigger.
361
+ */
362
+ reshowCooldownMinutes?: number;
339
363
  }
340
364
  interface MushiPreFilterConfig {
341
365
  enabled?: boolean;
@@ -833,6 +857,34 @@ interface MushiDiagnosticsResult {
833
857
  captureScreenshotAvailable: boolean;
834
858
  captureNetworkIntercepting: boolean;
835
859
  sdkVersion: string;
860
+ /**
861
+ * True when the widget host element has `pointer-events: none` and
862
+ * zero width/height — i.e. it cannot act as a touch blocker over host UI.
863
+ * False when the SDK has not yet mounted, or when a consumer has overridden
864
+ * the host styles without restoring the pass-through contract.
865
+ */
866
+ widgetHostPointerSafe: boolean;
867
+ /**
868
+ * Bounding rect of the widget host element (`offsetWidth × offsetHeight`).
869
+ * Should be `{ width: 0, height: 0 }` for a healthy SDK — the host is
870
+ * zero-sized with `overflow: visible` so the shadow internals extend
871
+ * outward without creating a hit-test surface. `null` when not mounted.
872
+ */
873
+ widgetHostBounds: {
874
+ width: number;
875
+ height: number;
876
+ } | null;
877
+ /**
878
+ * True when the widget is currently suppressed: `hideOnSelector` matched an
879
+ * element, `hideOnRoutes` matched the current pathname, or `hide()` was
880
+ * called. A suppressed widget renders nothing and removes the body nudge.
881
+ */
882
+ widgetSuppressed: boolean;
883
+ /**
884
+ * True when `trigger: 'banner'` is active and the banner is currently
885
+ * rendered in the shadow DOM (not dismissed, not suppressed).
886
+ */
887
+ bannerRendered: boolean;
836
888
  }
837
889
  interface MushiSDKInstance {
838
890
  /**
@@ -1204,6 +1256,27 @@ declare function captureEnvironment(): MushiEnvironment;
1204
1256
 
1205
1257
  declare function getReporterToken(): string;
1206
1258
 
1259
+ /**
1260
+ * RFC-4122 v4 UUID generator with a capability ladder so it works in every
1261
+ * runtime a Mushi SDK ships to:
1262
+ *
1263
+ * 1. `crypto.randomUUID()` — browsers (secure context), Node 19+, Deno
1264
+ * 2. `crypto.getRandomValues()` — older browsers, RN with a crypto polyfill
1265
+ * 3. `Math.random()` — Hermes / JSC without a crypto polyfill
1266
+ *
1267
+ * Why this exists: report ids are written to the `reports.id uuid` column on
1268
+ * the backend. SDKs that minted ad-hoc ids (`rn-<ts>-<rand>`, `mushi_<hex>`)
1269
+ * failed the Postgres uuid cast (22P02) and the report was silently dropped
1270
+ * (Sentry MUSHI-MUSHI-SERVER-D). Emitting a well-formed UUID at the source
1271
+ * keeps the value valid end-to-end.
1272
+ *
1273
+ * A report id is an identifier, not a secret. The `Math.random` fallback only
1274
+ * affects collision odds — negligible at our volume, and the backend dedupes
1275
+ * on the `reports` primary key regardless — so we never throw just because a
1276
+ * runtime lacks a CSPRNG.
1277
+ */
1278
+ declare function newUuid(): string;
1279
+
1207
1280
  /**
1208
1281
  * §3c — stable device fingerprint hash.
1209
1282
  *
@@ -1402,4 +1475,4 @@ declare function createLogger(options: LoggerOptions): Logger;
1402
1475
  */
1403
1476
  declare const noopLogger: Logger;
1404
1477
 
1405
- export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiBannerConfig, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiEventHandler, type MushiEventType, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiNetworkEntry, type MushiOfflineConfig, type MushiOnDeviceClassifier, type MushiOnDeviceClassifierInput, type MushiOnDeviceClassifierResult, type MushiPerformanceMetrics, type MushiPreFilterConfig, type MushiPreset, type MushiPrivacyConfig, type MushiProactiveConfig, type MushiRegion, type MushiReport, type MushiReportBuilder, type MushiReportCategory, type MushiReportStatus, type MushiReporterComment, type MushiReporterReport, type MushiReputationResult, type MushiRewardsConfig, type MushiRuntimeSdkConfig, type MushiSDKInstance, type MushiSdkVersionInfo, type MushiSelectedElement, type MushiSentryConfig, type MushiSentryContext, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PiiScrubberConfig, type PreFilterResult, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, captureEnvironment, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, getDeviceFingerprintHash, getReporterToken, getSessionId, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
1478
+ export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiBannerConfig, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiEventHandler, type MushiEventType, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiNetworkEntry, type MushiOfflineConfig, type MushiOnDeviceClassifier, type MushiOnDeviceClassifierInput, type MushiOnDeviceClassifierResult, type MushiPerformanceMetrics, type MushiPreFilterConfig, type MushiPreset, type MushiPrivacyConfig, type MushiProactiveConfig, type MushiRegion, type MushiReport, type MushiReportBuilder, type MushiReportCategory, type MushiReportStatus, type MushiReporterComment, type MushiReporterReport, type MushiReputationResult, type MushiRewardsConfig, type MushiRuntimeSdkConfig, type MushiSDKInstance, type MushiSdkVersionInfo, type MushiSelectedElement, type MushiSentryConfig, type MushiSentryContext, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PiiScrubberConfig, type PreFilterResult, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, captureEnvironment, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, getDeviceFingerprintHash, getReporterToken, getSessionId, newUuid, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
package/dist/index.js CHANGED
@@ -1035,6 +1035,26 @@ function generateToken() {
1035
1035
  return `mushi_${hex}`;
1036
1036
  }
1037
1037
 
1038
+ // src/uuid.ts
1039
+ function newUuid() {
1040
+ const c = typeof crypto !== "undefined" ? crypto : void 0;
1041
+ if (c?.randomUUID) {
1042
+ return c.randomUUID();
1043
+ }
1044
+ const bytes = new Uint8Array(16);
1045
+ if (c?.getRandomValues) {
1046
+ c.getRandomValues(bytes);
1047
+ } else {
1048
+ for (let i = 0; i < bytes.length; i++) {
1049
+ bytes[i] = Math.floor(Math.random() * 256);
1050
+ }
1051
+ }
1052
+ bytes[6] = bytes[6] & 15 | 64;
1053
+ bytes[8] = bytes[8] & 63 | 128;
1054
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
1055
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
1056
+ }
1057
+
1038
1058
  // src/fingerprint.ts
1039
1059
  var CACHE_KEY = "mushi_fingerprint_hash";
1040
1060
  function collectInputs() {
@@ -1278,6 +1298,6 @@ function normaliseThrown(thrown) {
1278
1298
  return { name: "Error", message: String(thrown) };
1279
1299
  }
1280
1300
 
1281
- export { DEFAULT_API_ENDPOINT, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, REGION_ENDPOINTS, captureEnvironment, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, getDeviceFingerprintHash, getReporterToken, getSessionId, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
1301
+ export { DEFAULT_API_ENDPOINT, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, REGION_ENDPOINTS, captureEnvironment, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, getDeviceFingerprintHash, getReporterToken, getSessionId, newUuid, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
1282
1302
  //# sourceMappingURL=index.js.map
1283
1303
  //# sourceMappingURL=index.js.map