@bugpulse/react-native 0.1.0 → 0.2.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.
Files changed (52) hide show
  1. package/README.md +41 -0
  2. package/dist/AnnotationCanvas.d.ts +3 -1
  3. package/dist/AnnotationCanvas.d.ts.map +1 -1
  4. package/dist/AnnotationCanvas.js +34 -8
  5. package/dist/AnnotationCanvas.js.map +1 -1
  6. package/dist/BugReportModal.d.ts +3 -1
  7. package/dist/BugReportModal.d.ts.map +1 -1
  8. package/dist/BugReportModal.js +136 -47
  9. package/dist/BugReportModal.js.map +1 -1
  10. package/dist/BugReportProvider.d.ts +3 -1
  11. package/dist/BugReportProvider.d.ts.map +1 -1
  12. package/dist/BugReportProvider.js +9 -3
  13. package/dist/BugReportProvider.js.map +1 -1
  14. package/dist/DeviceInfo.d.ts.map +1 -1
  15. package/dist/DeviceInfo.js +13 -1
  16. package/dist/DeviceInfo.js.map +1 -1
  17. package/dist/NavigationTracker.d.ts +6 -1
  18. package/dist/NavigationTracker.d.ts.map +1 -1
  19. package/dist/NavigationTracker.js +58 -23
  20. package/dist/NavigationTracker.js.map +1 -1
  21. package/dist/ShakeDetector.d.ts.map +1 -1
  22. package/dist/ShakeDetector.js +50 -17
  23. package/dist/ShakeDetector.js.map +1 -1
  24. package/dist/StateCapture.d.ts.map +1 -1
  25. package/dist/StateCapture.js +8 -9
  26. package/dist/StateCapture.js.map +1 -1
  27. package/dist/__tests__/BugReportModal.test.d.ts +2 -0
  28. package/dist/__tests__/BugReportModal.test.d.ts.map +1 -0
  29. package/dist/__tests__/BugReportModal.test.js +168 -0
  30. package/dist/__tests__/BugReportModal.test.js.map +1 -0
  31. package/dist/__tests__/integrations/slack.test.js +1 -1
  32. package/dist/__tests__/integrations/slack.test.js.map +1 -1
  33. package/dist/__tests__/useThemeColors.test.d.ts +2 -0
  34. package/dist/__tests__/useThemeColors.test.d.ts.map +1 -0
  35. package/dist/__tests__/useThemeColors.test.js +38 -0
  36. package/dist/__tests__/useThemeColors.test.js.map +1 -0
  37. package/dist/index.d.ts +2 -0
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +3 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/integrations/slack.d.ts.map +1 -1
  42. package/dist/integrations/slack.js +41 -24
  43. package/dist/integrations/slack.js.map +1 -1
  44. package/dist/integrations/webhook.d.ts +1 -0
  45. package/dist/integrations/webhook.d.ts.map +1 -1
  46. package/dist/integrations/webhook.js +29 -6
  47. package/dist/integrations/webhook.js.map +1 -1
  48. package/dist/useThemeColors.d.ts +16 -0
  49. package/dist/useThemeColors.d.ts.map +1 -0
  50. package/dist/useThemeColors.js +36 -0
  51. package/dist/useThemeColors.js.map +1 -0
  52. package/package.json +10 -2
@@ -1,4 +1,5 @@
1
1
  import React, { type ReactNode } from 'react';
2
+ import { type ColorSchemeName } from 'react-native';
2
3
  import type { Integration, BugReport } from './integrations/types';
3
4
  interface BugReportContextValue {
4
5
  triggerBugReport: () => void;
@@ -10,10 +11,11 @@ interface BugReportProviderProps {
10
11
  shakeThreshold?: number;
11
12
  shakeEnabled?: boolean;
12
13
  screenNameProvider?: () => string;
14
+ colorScheme?: ColorSchemeName;
13
15
  enabled?: boolean;
14
16
  onError?: (error: Error, report: BugReport) => void;
15
17
  }
16
- export declare function BugReportProvider({ children, integrations, metadata, shakeThreshold, shakeEnabled, screenNameProvider, enabled, onError, }: BugReportProviderProps): React.JSX.Element;
18
+ export declare function BugReportProvider({ children, integrations, metadata, shakeThreshold, shakeEnabled, screenNameProvider, colorScheme, enabled, onError, }: BugReportProviderProps): React.JSX.Element;
17
19
  export declare function useBugReport(): BugReportContextValue;
18
20
  export {};
19
21
  //# sourceMappingURL=BugReportProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BugReportProvider.d.ts","sourceRoot":"","sources":["../src/BugReportProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAQf,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAInE,UAAU,qBAAqB;IAC7B,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAMD,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,SAAS,CAAC;IACpB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,MAAM,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;CACrD;AAID,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,YAAY,EACZ,QAAa,EACb,cAAc,EACd,YAAmB,EACnB,kBAA8C,EAC9C,OAAc,EACd,OAAO,GACR,EAAE,sBAAsB,qBAiExB;AAED,wBAAgB,YAAY,IAAI,qBAAqB,CAMpD"}
1
+ {"version":3,"file":"BugReportProvider.d.ts","sourceRoot":"","sources":["../src/BugReportProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAQ,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAO1D,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAInE,UAAU,qBAAqB;IAC7B,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAMD,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,SAAS,CAAC;IACpB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,MAAM,CAAC;IAClC,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;CACrD;AAED,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,YAAY,EACZ,QAAa,EACb,cAAc,EACd,YAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,OAAc,EACd,OAAO,GACR,EAAE,sBAAsB,qBAyExB;AAED,wBAAgB,YAAY,IAAI,qBAAqB,CAMpD"}
@@ -45,13 +45,19 @@ const NavigationTracker_1 = require("./NavigationTracker");
45
45
  const ErrorBoundary_1 = require("./ErrorBoundary");
46
46
  const DEBOUNCE_MS = 3000;
47
47
  const BugReportContext = (0, react_1.createContext)(undefined);
48
- const defaultScreenNameProvider = () => 'unknown';
49
- function BugReportProvider({ children, integrations, metadata = {}, shakeThreshold, shakeEnabled = true, screenNameProvider = defaultScreenNameProvider, enabled = true, onError, }) {
48
+ function BugReportProvider({ children, integrations, metadata = {}, shakeThreshold, shakeEnabled = true, screenNameProvider, colorScheme, enabled = true, onError, }) {
50
49
  const [isModalVisible, setIsModalVisible] = (0, react_1.useState)(false);
51
50
  const [screenshotUri, setScreenshotUri] = (0, react_1.useState)(null);
52
51
  const isModalVisibleRef = (0, react_1.useRef)(false);
53
52
  const lastTriggerTimestamp = (0, react_1.useRef)(0);
54
53
  const viewShotRef = (0, react_1.useRef)(null);
54
+ // Auto-detect screen name from NavigationTracker if no provider given
55
+ const resolvedScreenNameProvider = (0, react_1.useCallback)(() => {
56
+ if (screenNameProvider)
57
+ return screenNameProvider();
58
+ const trackedPathname = (0, NavigationTracker_1.getCurrentPathname)();
59
+ return trackedPathname ?? 'unknown';
60
+ }, [screenNameProvider]);
55
61
  const triggerBugReport = (0, react_1.useCallback)(async () => {
56
62
  const now = Date.now();
57
63
  if (now - lastTriggerTimestamp.current < DEBOUNCE_MS)
@@ -90,7 +96,7 @@ function BugReportProvider({ children, integrations, metadata = {}, shakeThresho
90
96
  <react_native_1.View ref={viewShotRef} style={{ flex: 1 }} collapsable={false}>
91
97
  {children}
92
98
  </react_native_1.View>
93
- <BugReportModal_1.BugReportModal visible={isModalVisible} screenshotUri={screenshotUri} integrations={integrations} metadata={metadata} screenNameProvider={screenNameProvider} onClose={handleClose} onSubmitSuccess={handleSubmitSuccess} onError={onError}/>
99
+ <BugReportModal_1.BugReportModal visible={isModalVisible} screenshotUri={screenshotUri} integrations={integrations} metadata={metadata} screenNameProvider={resolvedScreenNameProvider} colorScheme={colorScheme} onClose={handleClose} onSubmitSuccess={handleSubmitSuccess} onError={onError}/>
94
100
  </BugReportContext.Provider>);
95
101
  }
96
102
  function useBugReport() {
@@ -1 +1 @@
1
- {"version":3,"file":"BugReportProvider.js","sourceRoot":"","sources":["../src/BugReportProvider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BugReportProvider.js","sourceRoot":"","sources":["../src/BugReportProvider.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceInfo.d.ts","sourceRoot":"","sources":["../src/DeviceInfo.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,wBAAgB,iBAAiB,IAAI,UAAU,CAqB9C"}
1
+ {"version":3,"file":"DeviceInfo.d.ts","sourceRoot":"","sources":["../src/DeviceInfo.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAavD,wBAAgB,iBAAiB,IAAI,UAAU,CAqB9C"}
@@ -41,6 +41,18 @@ const react_native_1 = require("react-native");
41
41
  const Device = __importStar(require("expo-device"));
42
42
  const expo_localization_1 = require("expo-localization");
43
43
  const expo_constants_1 = __importDefault(require("expo-constants"));
44
+ function getInstallationId() {
45
+ // Constants.installationId is deprecated in newer Expo SDKs
46
+ // Fall back gracefully through available identifiers
47
+ try {
48
+ if (expo_constants_1.default.installationId)
49
+ return expo_constants_1.default.installationId;
50
+ }
51
+ catch {
52
+ // property may not exist
53
+ }
54
+ return expo_constants_1.default.sessionId ?? 'unknown';
55
+ }
44
56
  function collectDeviceInfo() {
45
57
  const { width, height } = react_native_1.Dimensions.get('window');
46
58
  const locales = (0, expo_localization_1.getLocales)();
@@ -56,7 +68,7 @@ function collectDeviceInfo() {
56
68
  'unknown',
57
69
  screenSize: `${width}x${height}`,
58
70
  locale,
59
- installationId: expo_constants_1.default.installationId ?? 'unknown',
71
+ installationId: getInstallationId(),
60
72
  expoConfig,
61
73
  };
62
74
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceInfo.js","sourceRoot":"","sources":["../src/DeviceInfo.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,8CAqBC;AA3BD,+CAAoD;AACpD,oDAAsC;AACtC,yDAA+C;AAC/C,oEAAuC;AAGvC,SAAgB,iBAAiB;IAC/B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,yBAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,IAAA,8BAAU,GAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,SAAS,CAAC;IAEpD,MAAM,UAAU,GAAG,wBAAS,CAAC,UAAU;QACrC,CAAC,CAAC,EAAE,IAAI,EAAE,wBAAS,CAAC,UAAU,CAAC,IAAI,IAAI,SAAS,EAAE,IAAI,EAAE,wBAAS,CAAC,UAAU,CAAC,IAAI,IAAI,SAAS,EAAE;QAChG,CAAC,CAAC,IAAI,CAAC;IAET,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,SAAS,IAAI,GAAG,uBAAQ,CAAC,EAAE,SAAS;QAClD,EAAE,EAAE,GAAG,uBAAQ,CAAC,EAAE,IAAI,uBAAQ,CAAC,OAAO,EAAE;QACxC,UAAU,EACR,wBAAS,CAAC,UAAU,EAAE,OAAO;YAC7B,wBAAS,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO;YAC/C,SAAS;QACX,UAAU,EAAE,GAAG,KAAK,IAAI,MAAM,EAAE;QAChC,MAAM;QACN,cAAc,EAAE,wBAAS,CAAC,cAAc,IAAI,SAAS;QACrD,UAAU;KACX,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"DeviceInfo.js","sourceRoot":"","sources":["../src/DeviceInfo.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBA,8CAqBC;AAtCD,+CAAoD;AACpD,oDAAsC;AACtC,yDAA+C;AAC/C,oEAAuC;AAGvC,SAAS,iBAAiB;IACxB,4DAA4D;IAC5D,qDAAqD;IACrD,IAAI,CAAC;QACH,IAAI,wBAAS,CAAC,cAAc;YAAE,OAAO,wBAAS,CAAC,cAAc,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,yBAAyB;IAC3B,CAAC;IACD,OAAO,wBAAS,CAAC,SAAS,IAAI,SAAS,CAAC;AAC1C,CAAC;AAED,SAAgB,iBAAiB;IAC/B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,yBAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,IAAA,8BAAU,GAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,SAAS,CAAC;IAEpD,MAAM,UAAU,GAAG,wBAAS,CAAC,UAAU;QACrC,CAAC,CAAC,EAAE,IAAI,EAAE,wBAAS,CAAC,UAAU,CAAC,IAAI,IAAI,SAAS,EAAE,IAAI,EAAE,wBAAS,CAAC,UAAU,CAAC,IAAI,IAAI,SAAS,EAAE;QAChG,CAAC,CAAC,IAAI,CAAC;IAET,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,SAAS,IAAI,GAAG,uBAAQ,CAAC,EAAE,SAAS;QAClD,EAAE,EAAE,GAAG,uBAAQ,CAAC,EAAE,IAAI,uBAAQ,CAAC,OAAO,EAAE;QACxC,UAAU,EACR,wBAAS,CAAC,UAAU,EAAE,OAAO;YAC7B,wBAAS,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO;YAC/C,SAAS;QACX,UAAU,EAAE,GAAG,KAAK,IAAI,MAAM,EAAE;QAChC,MAAM;QACN,cAAc,EAAE,iBAAiB,EAAE;QACnC,UAAU;KACX,CAAC;AACJ,CAAC"}
@@ -1,5 +1,10 @@
1
1
  import type { NavEntry } from './integrations/types';
2
- export declare function useNavigationTracker(): void;
2
+ /**
3
+ * Track navigation changes via Expo Router.
4
+ * Safe to call regardless of whether expo-router is installed.
5
+ */
6
+ export declare const useNavigationTracker: () => void;
7
+ export declare function getCurrentPathname(): string | null;
3
8
  export declare function freezeNavHistory(): void;
4
9
  export declare function getNavHistory(): NavEntry[];
5
10
  export declare function clearNavHistory(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationTracker.d.ts","sourceRoot":"","sources":["../src/NavigationTracker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQrD,wBAAgB,oBAAoB,IAAI,IAAI,CA4B3C;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAWvC;AAED,wBAAgB,aAAa,IAAI,QAAQ,EAAE,CAE1C;AAED,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAGtC"}
1
+ {"version":3,"file":"NavigationTracker.d.ts","sourceRoot":"","sources":["../src/NavigationTracker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AA0DrD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,IAEvB,CAAC;AAEnB,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAElD;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAoBvC;AAED,wBAAgB,aAAa,IAAI,QAAQ,EAAE,CAE1C;AAED,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAItC"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useNavigationTracker = useNavigationTracker;
3
+ exports.useNavigationTracker = void 0;
4
+ exports.getCurrentPathname = getCurrentPathname;
4
5
  exports.freezeNavHistory = freezeNavHistory;
5
6
  exports.getNavHistory = getNavHistory;
6
7
  exports.clearNavHistory = clearNavHistory;
@@ -9,28 +10,38 @@ const react_1 = require("react");
9
10
  const RingBuffer_1 = require("./RingBuffer");
10
11
  const MAX_ENTRIES = 10;
11
12
  const MAX_TOTAL_BYTES = 20 * 1024; // 20KB
13
+ const MAX_ENTRY_BYTES = 2 * 1024; // 2KB per entry estimate
12
14
  const navBuffer = new RingBuffer_1.RingBuffer(MAX_ENTRIES);
13
15
  let frozenHistory = null;
14
- function useNavigationTracker() {
15
- let usePathname;
16
- let useSegments;
17
- try {
18
- // Optional import — graceful when expo-router is not installed
19
- // eslint-disable-next-line @typescript-eslint/no-var-requires
20
- const expoRouter = require('expo-router');
21
- usePathname = expoRouter.usePathname;
22
- useSegments = expoRouter.useSegments;
16
+ let currentPathname = null;
17
+ // Detect expo-router availability once at module load
18
+ let expoRouterHooks = null;
19
+ try {
20
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
21
+ const expoRouter = require('expo-router');
22
+ if (expoRouter.usePathname && expoRouter.useSegments) {
23
+ expoRouterHooks = {
24
+ usePathname: expoRouter.usePathname,
25
+ useSegments: expoRouter.useSegments,
26
+ };
23
27
  }
24
- catch {
25
- // expo-router not available — no-op
26
- }
27
- const pathname = usePathname?.() ?? null;
28
- const segments = useSegments?.() ?? null;
28
+ }
29
+ catch {
30
+ // expo-router not available
31
+ }
32
+ /**
33
+ * Hook for tracking navigation when expo-router IS available.
34
+ * Always calls the same hooks in the same order (React rules of hooks).
35
+ */
36
+ function useExpoRouterTracker() {
37
+ const pathname = expoRouterHooks.usePathname();
38
+ const segments = expoRouterHooks.useSegments();
29
39
  const lastPathname = (0, react_1.useRef)(null);
30
40
  (0, react_1.useEffect)(() => {
31
- if (pathname === null || pathname === lastPathname.current)
41
+ if (pathname === lastPathname.current)
32
42
  return;
33
43
  lastPathname.current = pathname;
44
+ currentPathname = pathname;
34
45
  navBuffer.push({
35
46
  pathname,
36
47
  segments: segments ?? [],
@@ -38,15 +49,38 @@ function useNavigationTracker() {
38
49
  });
39
50
  }, [pathname, segments]);
40
51
  }
52
+ /**
53
+ * No-op hook when expo-router is not installed.
54
+ */
55
+ function useNoOpTracker() {
56
+ // intentionally empty — no hooks called, consistent every render
57
+ }
58
+ /**
59
+ * Track navigation changes via Expo Router.
60
+ * Safe to call regardless of whether expo-router is installed.
61
+ */
62
+ exports.useNavigationTracker = expoRouterHooks
63
+ ? useExpoRouterTracker
64
+ : useNoOpTracker;
65
+ function getCurrentPathname() {
66
+ return currentPathname;
67
+ }
41
68
  function freezeNavHistory() {
42
- let entries = navBuffer.getAll();
43
- // Enforce 20KB total cap drop oldest entries until under limit
44
- let totalBytes = JSON.stringify(entries).length;
45
- while (totalBytes > MAX_TOTAL_BYTES && entries.length > 1) {
46
- entries = entries.slice(1);
47
- totalBytes = JSON.stringify(entries).length;
69
+ const entries = navBuffer.getAll();
70
+ // Single-pass size check: estimate total size and drop oldest if over limit
71
+ let totalBytes = 0;
72
+ let startIndex = 0;
73
+ const entrySizes = [];
74
+ for (const entry of entries) {
75
+ const size = entry.pathname.length + JSON.stringify(entry.segments).length + 60; // overhead
76
+ entrySizes.push(size);
77
+ totalBytes += size;
78
+ }
79
+ while (totalBytes > MAX_TOTAL_BYTES && startIndex < entries.length - 1) {
80
+ totalBytes -= entrySizes[startIndex];
81
+ startIndex++;
48
82
  }
49
- frozenHistory = entries;
83
+ frozenHistory = startIndex > 0 ? entries.slice(startIndex) : entries;
50
84
  }
51
85
  function getNavHistory() {
52
86
  return frozenHistory ?? [];
@@ -57,5 +91,6 @@ function clearNavHistory() {
57
91
  function resetNavTracker() {
58
92
  navBuffer.clear();
59
93
  frozenHistory = null;
94
+ currentPathname = null;
60
95
  }
61
96
  //# sourceMappingURL=NavigationTracker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationTracker.js","sourceRoot":"","sources":["../src/NavigationTracker.ts"],"names":[],"mappings":";;AAUA,oDA4BC;AAED,4CAWC;AAED,sCAEC;AAED,0CAEC;AAED,0CAGC;AAhED,iCAA0C;AAC1C,6CAA0C;AAG1C,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,eAAe,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO;AAE1C,MAAM,SAAS,GAAG,IAAI,uBAAU,CAAW,WAAW,CAAC,CAAC;AACxD,IAAI,aAAa,GAAsB,IAAI,CAAC;AAE5C,SAAgB,oBAAoB;IAClC,IAAI,WAAuC,CAAC;IAC5C,IAAI,WAAyC,CAAC;IAE9C,IAAI,CAAC;QACH,+DAA+D;QAC/D,8DAA8D;QAC9D,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;QAC1C,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC;QACrC,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,oCAAoC;IACtC,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,EAAE,EAAE,IAAI,IAAI,CAAC;IACzC,MAAM,QAAQ,GAAG,WAAW,EAAE,EAAE,IAAI,IAAI,CAAC;IACzC,MAAM,YAAY,GAAG,IAAA,cAAM,EAAgB,IAAI,CAAC,CAAC;IAEjD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,YAAY,CAAC,OAAO;YAAE,OAAO;QACnE,YAAY,CAAC,OAAO,GAAG,QAAQ,CAAC;QAEhC,SAAS,CAAC,IAAI,CAAC;YACb,QAAQ;YACR,QAAQ,EAAE,QAAQ,IAAI,EAAE;YACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC3B,CAAC;AAED,SAAgB,gBAAgB;IAC9B,IAAI,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;IAEjC,iEAAiE;IACjE,IAAI,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAChD,OAAO,UAAU,GAAG,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1D,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAC9C,CAAC;IAED,aAAa,GAAG,OAAO,CAAC;AAC1B,CAAC;AAED,SAAgB,aAAa;IAC3B,OAAO,aAAa,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,SAAgB,eAAe;IAC7B,aAAa,GAAG,IAAI,CAAC;AACvB,CAAC;AAED,SAAgB,eAAe;IAC7B,SAAS,CAAC,KAAK,EAAE,CAAC;IAClB,aAAa,GAAG,IAAI,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"NavigationTracker.js","sourceRoot":"","sources":["../src/NavigationTracker.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ShakeDetector.d.ts","sourceRoot":"","sources":["../src/ShakeDetector.ts"],"names":[],"mappings":"AASA,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,IAAI,EACnB,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAClD,IAAI,CAwCN"}
1
+ {"version":3,"file":"ShakeDetector.d.ts","sourceRoot":"","sources":["../src/ShakeDetector.ts"],"names":[],"mappings":"AA6BA,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,IAAI,EACnB,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAClD,IAAI,CAwDN"}
@@ -8,6 +8,25 @@ const SHAKE_COUNT_REQUIRED = 3;
8
8
  const SHAKE_WINDOW_MS = 800;
9
9
  const COOLDOWN_MS = 3000;
10
10
  const UPDATE_INTERVAL_MS = 100;
11
+ // Try to load expo-haptics (optional peer dep)
12
+ let Haptics = null;
13
+ let ImpactFeedbackStyle = null;
14
+ try {
15
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
16
+ const haptics = require('expo-haptics');
17
+ Haptics = haptics;
18
+ ImpactFeedbackStyle = haptics.ImpactFeedbackStyle;
19
+ }
20
+ catch {
21
+ // expo-haptics not installed — haptic feedback disabled
22
+ }
23
+ function triggerHaptic() {
24
+ if (Haptics && ImpactFeedbackStyle) {
25
+ Haptics.impactAsync(ImpactFeedbackStyle.Medium).catch(() => {
26
+ // Haptic failed silently (e.g., unsupported device)
27
+ });
28
+ }
29
+ }
11
30
  function useShakeDetector(onShake, options) {
12
31
  const onShakeRef = (0, react_1.useRef)(onShake);
13
32
  const threshold = options?.threshold ?? DEFAULT_THRESHOLD;
@@ -20,24 +39,38 @@ function useShakeDetector(onShake, options) {
20
39
  return;
21
40
  let shakeTimestamps = [];
22
41
  let lastShakeTime = 0;
23
- expo_sensors_1.Accelerometer.setUpdateInterval(UPDATE_INTERVAL_MS);
24
- const subscription = expo_sensors_1.Accelerometer.addListener(({ x, y, z }) => {
25
- const totalForce = Math.sqrt(x * x + y * y + z * z);
26
- if (totalForce < threshold)
27
- return;
28
- const now = Date.now();
29
- if (now - lastShakeTime < COOLDOWN_MS)
30
- return;
31
- shakeTimestamps.push(now);
32
- shakeTimestamps = shakeTimestamps.filter((ts) => now - ts < SHAKE_WINDOW_MS);
33
- if (shakeTimestamps.length >= SHAKE_COUNT_REQUIRED) {
34
- lastShakeTime = now;
35
- shakeTimestamps = [];
36
- onShakeRef.current();
37
- }
38
- });
42
+ try {
43
+ expo_sensors_1.Accelerometer.setUpdateInterval(UPDATE_INTERVAL_MS);
44
+ }
45
+ catch {
46
+ console.warn('[BugPulse] Accelerometer not available on this device. Shake-to-report disabled. Use triggerBugReport() instead.');
47
+ return;
48
+ }
49
+ let subscription = null;
50
+ try {
51
+ subscription = expo_sensors_1.Accelerometer.addListener(({ x, y, z }) => {
52
+ const totalForce = Math.sqrt(x * x + y * y + z * z);
53
+ if (totalForce < threshold)
54
+ return;
55
+ const now = Date.now();
56
+ if (now - lastShakeTime < COOLDOWN_MS)
57
+ return;
58
+ shakeTimestamps.push(now);
59
+ shakeTimestamps = shakeTimestamps.filter((ts) => now - ts < SHAKE_WINDOW_MS);
60
+ if (shakeTimestamps.length >= SHAKE_COUNT_REQUIRED) {
61
+ lastShakeTime = now;
62
+ shakeTimestamps = [];
63
+ triggerHaptic();
64
+ onShakeRef.current();
65
+ }
66
+ });
67
+ }
68
+ catch {
69
+ console.warn('[BugPulse] Failed to start accelerometer listener. Shake-to-report disabled.');
70
+ return;
71
+ }
39
72
  return () => {
40
- subscription.remove();
73
+ subscription?.remove();
41
74
  };
42
75
  }, [threshold, enabled]);
43
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ShakeDetector.js","sourceRoot":"","sources":["../src/ShakeDetector.ts"],"names":[],"mappings":";;AASA,4CA2CC;AApDD,iCAA0C;AAC1C,+CAA6C;AAE7C,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,MAAM,eAAe,GAAG,GAAG,CAAC;AAC5B,MAAM,WAAW,GAAG,IAAI,CAAC;AACzB,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B,SAAgB,gBAAgB,CAC9B,OAAmB,EACnB,OAAmD;IAEnD,MAAM,UAAU,GAAG,IAAA,cAAM,EAAC,OAAO,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,iBAAiB,CAAC;IAC1D,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC;IAEzC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IAC/B,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,IAAI,eAAe,GAAa,EAAE,CAAC;QACnC,IAAI,aAAa,GAAG,CAAC,CAAC;QAEtB,4BAAa,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;QAEpD,MAAM,YAAY,GAAG,4BAAa,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE;YAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACpD,IAAI,UAAU,GAAG,SAAS;gBAAE,OAAO;YAEnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,IAAI,GAAG,GAAG,aAAa,GAAG,WAAW;gBAAE,OAAO;YAE9C,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC1B,eAAe,GAAG,eAAe,CAAC,MAAM,CACtC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,EAAE,GAAG,eAAe,CACnC,CAAC;YAEF,IAAI,eAAe,CAAC,MAAM,IAAI,oBAAoB,EAAE,CAAC;gBACnD,aAAa,GAAG,GAAG,CAAC;gBACpB,eAAe,GAAG,EAAE,CAAC;gBACrB,UAAU,CAAC,OAAO,EAAE,CAAC;YACvB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;AAC3B,CAAC"}
1
+ {"version":3,"file":"ShakeDetector.js","sourceRoot":"","sources":["../src/ShakeDetector.ts"],"names":[],"mappings":";;AA6BA,4CA2DC;AAxFD,iCAA0C;AAC1C,+CAA6C;AAE7C,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,MAAM,eAAe,GAAG,GAAG,CAAC;AAC5B,MAAM,WAAW,GAAG,IAAI,CAAC;AACzB,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B,+CAA+C;AAC/C,IAAI,OAAO,GAA6D,IAAI,CAAC;AAC7E,IAAI,mBAAmB,GAA8B,IAAI,CAAC;AAC1D,IAAI,CAAC;IACH,8DAA8D;IAC9D,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACxC,OAAO,GAAG,OAAO,CAAC;IAClB,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;AACpD,CAAC;AAAC,MAAM,CAAC;IACP,wDAAwD;AAC1D,CAAC;AAED,SAAS,aAAa;IACpB,IAAI,OAAO,IAAI,mBAAmB,EAAE,CAAC;QACnC,OAAO,CAAC,WAAW,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACzD,oDAAoD;QACtD,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,SAAgB,gBAAgB,CAC9B,OAAmB,EACnB,OAAmD;IAEnD,MAAM,UAAU,GAAG,IAAA,cAAM,EAAC,OAAO,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,iBAAiB,CAAC;IAC1D,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC;IAEzC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IAC/B,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,IAAI,eAAe,GAAa,EAAE,CAAC;QACnC,IAAI,aAAa,GAAG,CAAC,CAAC;QAEtB,IAAI,CAAC;YACH,4BAAa,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CACV,kHAAkH,CACnH,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,YAAY,GAAkC,IAAI,CAAC;QACvD,IAAI,CAAC;YACH,YAAY,GAAG,4BAAa,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE;gBACvD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;gBACpD,IAAI,UAAU,GAAG,SAAS;oBAAE,OAAO;gBAEnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACvB,IAAI,GAAG,GAAG,aAAa,GAAG,WAAW;oBAAE,OAAO;gBAE9C,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC1B,eAAe,GAAG,eAAe,CAAC,MAAM,CACtC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,EAAE,GAAG,eAAe,CACnC,CAAC;gBAEF,IAAI,eAAe,CAAC,MAAM,IAAI,oBAAoB,EAAE,CAAC;oBACnD,aAAa,GAAG,GAAG,CAAC;oBACpB,eAAe,GAAG,EAAE,CAAC;oBACrB,aAAa,EAAE,CAAC;oBAChB,UAAU,CAAC,OAAO,EAAE,CAAC;gBACvB,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CACV,8EAA8E,CAC/E,CAAC;YACF,OAAO;QACT,CAAC;QAED,OAAO,GAAG,EAAE;YACV,YAAY,EAAE,MAAM,EAAE,CAAC;QACzB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;AAC3B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"StateCapture.d.ts","sourceRoot":"","sources":["../src/StateCapture.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAgC1D,wBAAgB,UAAU,CACxB,KAAK,EAAE;IAAE,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,OAAO,CAAA;CAAE,EACnF,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GACxB,IAAI,CAkBN;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAM/C;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAO1C;AAED,wBAAgB,gBAAgB,IAAI,aAAa,EAAE,CAElD;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED,wBAAgB,cAAc,IAAI,IAAI,CAMrC"}
1
+ {"version":3,"file":"StateCapture.d.ts","sourceRoot":"","sources":["../src/StateCapture.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AA+B1D,wBAAgB,UAAU,CACxB,KAAK,EAAE;IAAE,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,OAAO,CAAA;CAAE,EACnF,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GACxB,IAAI,CAkBN;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAM/C;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAO1C;AAED,wBAAgB,gBAAgB,IAAI,aAAa,EAAE,CAElD;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED,wBAAgB,cAAc,IAAI,IAAI,CAMrC"}
@@ -13,19 +13,18 @@ const TRUNCATED_MARKER = '"[TRUNCATED]"';
13
13
  const stores = new Map();
14
14
  let frozenSnapshot = null;
15
15
  function serializeState(state) {
16
- let json;
17
16
  try {
18
- json = JSON.stringify(state);
17
+ const json = JSON.stringify(state);
18
+ if (json.length > MAX_SNAPSHOT_BYTES) {
19
+ return { json: JSON.stringify('[STATE TOO LARGE - ' + json.length + ' bytes]'), truncated: true };
20
+ }
21
+ return { json, truncated: false };
19
22
  }
20
- catch {
21
- console.warn('[expo-bug-report] Failed to serialize state (circular reference?). Skipping snapshot.');
23
+ catch (error) {
24
+ const reason = error instanceof Error ? error.message : 'unknown error';
25
+ console.warn(`[BugPulse] Failed to serialize state: ${reason}. Skipping snapshot.`);
22
26
  return { json: TRUNCATED_MARKER, truncated: true };
23
27
  }
24
- if (json.length > MAX_SNAPSHOT_BYTES) {
25
- // Truncate to valid JSON by wrapping in a string marker rather than slicing mid-JSON
26
- return { json: JSON.stringify('[STATE TOO LARGE - ' + json.length + ' bytes]'), truncated: true };
27
- }
28
- return { json, truncated: false };
29
28
  }
30
29
  function trackStore(store, options) {
31
30
  if (stores.has(options.name)) {
@@ -1 +1 @@
1
- {"version":3,"file":"StateCapture.js","sourceRoot":"","sources":["../src/StateCapture.ts"],"names":[],"mappings":";;AAiCA,gCAqBC;AAED,oCAMC;AAED,kDAOC;AAED,4CAEC;AAED,8CAEC;AAED,wCAMC;AAvFD,6CAA0C;AAG1C,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO;AAC7C,MAAM,gBAAgB,GAAG,eAAe,CAAC;AAQzC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;AAC/C,IAAI,cAAc,GAA2B,IAAI,CAAC;AAElD,SAAS,cAAc,CAAC,KAAc;IACpC,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,IAAI,CAAC,uFAAuF,CAAC,CAAC;QACtG,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACrD,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,GAAG,kBAAkB,EAAE,CAAC;QACrC,qFAAqF;QACrF,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,qBAAqB,GAAG,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACpG,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,SAAgB,UAAU,CACxB,KAAmF,EACnF,OAAyB;IAEzB,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,uBAAU,CAAgB,WAAW,CAAC,CAAC;IAE1D,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACvC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC7D,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,KAAK,EAAE,IAAI;YACX,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,SAAS;SACV,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,SAAgB,YAAY,CAAC,IAAY;IACvC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,WAAW,EAAE,CAAC;QACtB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,SAAgB,mBAAmB;IACjC,MAAM,YAAY,GAAoB,EAAE,CAAC;IACzC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QACtC,YAAY,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IACpE,cAAc,GAAG,YAAY,CAAC;AAChC,CAAC;AAED,SAAgB,gBAAgB;IAC9B,OAAO,cAAc,IAAI,EAAE,CAAC;AAC9B,CAAC;AAED,SAAgB,iBAAiB;IAC/B,cAAc,GAAG,IAAI,CAAC;AACxB,CAAC;AAED,SAAgB,cAAc;IAC5B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QACtC,OAAO,CAAC,WAAW,EAAE,CAAC;IACxB,CAAC;IACD,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,cAAc,GAAG,IAAI,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"StateCapture.js","sourceRoot":"","sources":["../src/StateCapture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=BugReportModal.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BugReportModal.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/BugReportModal.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const react_native_1 = require("@testing-library/react-native");
8
+ const BugReportModal_1 = require("../BugReportModal");
9
+ // Note: RN Modal renders even when visible=false in jest (content is always in the tree)
10
+ jest.mock('../AnnotationCanvas', () => ({
11
+ AnnotationCanvas: () => null,
12
+ }));
13
+ jest.mock('../DeviceInfo', () => ({
14
+ collectDeviceInfo: () => ({
15
+ model: 'Test Device',
16
+ os: 'ios 17.0',
17
+ appVersion: '1.0.0',
18
+ screenSize: '390x844',
19
+ locale: 'en-US',
20
+ installationId: 'test-id',
21
+ expoConfig: null,
22
+ }),
23
+ }));
24
+ jest.mock('../StateCapture', () => ({
25
+ getStateSnapshot: () => [{ name: 'app', state: '{}', timestamp: 't', truncated: false }],
26
+ }));
27
+ jest.mock('../NavigationTracker', () => ({
28
+ getNavHistory: () => [{ pathname: '/home', segments: ['home'], timestamp: 't' }],
29
+ }));
30
+ jest.mock('../ErrorBoundary', () => ({
31
+ getLastError: () => null,
32
+ }));
33
+ jest.mock('../useThemeColors', () => ({
34
+ useThemeColors: () => ({
35
+ background: '#fff', surface: '#F2F2F7', border: '#E5E5EA', text: '#000',
36
+ textSecondary: '#8E8E93', textTertiary: '#C7C7CC', inputBackground: '#F2F2F7',
37
+ inputBorder: '#E5E5EA', primary: '#007AFF', error: '#FF3B30', disabled: '#C7C7CC',
38
+ }),
39
+ }));
40
+ function createMockIntegration(overrides) {
41
+ return {
42
+ name: 'test',
43
+ send: jest.fn().mockResolvedValue({ success: true }),
44
+ ...overrides,
45
+ };
46
+ }
47
+ // Helper: find a TouchableOpacity by its accessibilityLabel in the JSON tree and call onPress
48
+ function pressButton(root, label) {
49
+ const json = root.toJSON();
50
+ const node = findByProp(json, 'accessibilityLabel', label);
51
+ if (!node || !node.props?.onPress)
52
+ throw new Error(`Button "${label}" not found or has no onPress`);
53
+ node.props.onPress();
54
+ }
55
+ function findByProp(node, prop, value) {
56
+ if (!node)
57
+ return null;
58
+ if (node.props?.[prop] === value)
59
+ return node;
60
+ if (Array.isArray(node.children)) {
61
+ for (const child of node.children) {
62
+ const found = findByProp(child, prop, value);
63
+ if (found)
64
+ return found;
65
+ }
66
+ }
67
+ return null;
68
+ }
69
+ const defaultProps = {
70
+ visible: true,
71
+ screenshotUri: null,
72
+ integrations: [createMockIntegration()],
73
+ metadata: {},
74
+ screenNameProvider: () => 'TestScreen',
75
+ onClose: jest.fn(),
76
+ };
77
+ describe('BugReportModal', () => {
78
+ beforeEach(() => {
79
+ jest.clearAllMocks();
80
+ });
81
+ it('renders describe step with expected content', () => {
82
+ const root = (0, react_native_1.render)(<BugReportModal_1.BugReportModal {...defaultProps}/>);
83
+ // toJSON may wrap in Modal — stringify the full tree
84
+ const json = JSON.stringify(root.toJSON());
85
+ expect(json).toContain('Bug Report');
86
+ expect(json).toContain('Submit');
87
+ expect(json).toContain('What went wrong?');
88
+ expect(json).toContain('Screen: ');
89
+ expect(json).toContain('TestScreen');
90
+ });
91
+ it('passes visible=false to Modal', () => {
92
+ const root = (0, react_native_1.render)(<BugReportModal_1.BugReportModal {...defaultProps} visible={false}/>);
93
+ // RN Modal renders children in test env. Verify visible prop is passed correctly
94
+ const json = JSON.stringify(root.toJSON());
95
+ expect(json).toContain('"visible":false');
96
+ });
97
+ it('shows Expo Go banner when no screenshot', () => {
98
+ const root = (0, react_native_1.render)(<BugReportModal_1.BugReportModal {...defaultProps} screenshotUri={null}/>);
99
+ expect(JSON.stringify(root.toJSON())).toContain('Screenshot unavailable');
100
+ });
101
+ it('shows diagnostics summary (report preview)', () => {
102
+ const root = (0, react_native_1.render)(<BugReportModal_1.BugReportModal {...defaultProps}/>);
103
+ const json = JSON.stringify(root.toJSON());
104
+ expect(json).toContain('1 state snapshot');
105
+ expect(json).toContain('1 nav event');
106
+ });
107
+ it('calls onClose when close pressed', async () => {
108
+ const onClose = jest.fn();
109
+ const root = (0, react_native_1.render)(<BugReportModal_1.BugReportModal {...defaultProps} onClose={onClose}/>);
110
+ await (0, react_native_1.act)(() => { pressButton(root, 'Close bug report'); });
111
+ expect(onClose).toHaveBeenCalledTimes(1);
112
+ });
113
+ it('calls integration.send on submit', async () => {
114
+ const mockSend = jest.fn().mockResolvedValue({ success: true });
115
+ const integration = createMockIntegration({ send: mockSend });
116
+ const root = (0, react_native_1.render)(<BugReportModal_1.BugReportModal {...defaultProps} integrations={[integration]}/>);
117
+ await (0, react_native_1.act)(async () => { pressButton(root, 'Submit bug report'); });
118
+ await (0, react_native_1.waitFor)(() => { expect(mockSend).toHaveBeenCalledTimes(1); });
119
+ const report = mockSend.mock.calls[0][0];
120
+ expect(report.screen).toBe('TestScreen');
121
+ expect(report.device.model).toBe('Test Device');
122
+ expect(report.diagnostics.stateSnapshots).toHaveLength(1);
123
+ });
124
+ it('shows success after successful submit', async () => {
125
+ const root = (0, react_native_1.render)(<BugReportModal_1.BugReportModal {...defaultProps}/>);
126
+ await (0, react_native_1.act)(async () => { pressButton(root, 'Submit bug report'); });
127
+ await (0, react_native_1.waitFor)(() => { expect(JSON.stringify(root.toJSON())).toContain('Sent!'); });
128
+ });
129
+ it('shows error when integration fails', async () => {
130
+ const integration = createMockIntegration({
131
+ send: jest.fn().mockResolvedValue({ success: false, error: 'Network error' }),
132
+ });
133
+ const root = (0, react_native_1.render)(<BugReportModal_1.BugReportModal {...defaultProps} integrations={[integration]}/>);
134
+ await (0, react_native_1.act)(async () => { pressButton(root, 'Submit bug report'); });
135
+ await (0, react_native_1.waitFor)(() => {
136
+ const json = JSON.stringify(root.toJSON());
137
+ expect(json).toContain('Failed to send');
138
+ expect(json).toContain('Network error');
139
+ });
140
+ });
141
+ it('handles send exception gracefully (stuck modal fix)', async () => {
142
+ const integration = createMockIntegration({
143
+ send: jest.fn().mockRejectedValue(new Error('Crash')),
144
+ });
145
+ const root = (0, react_native_1.render)(<BugReportModal_1.BugReportModal {...defaultProps} integrations={[integration]}/>);
146
+ await (0, react_native_1.act)(async () => { pressButton(root, 'Submit bug report'); });
147
+ await (0, react_native_1.waitFor)(() => { expect(JSON.stringify(root.toJSON())).toContain('Failed to send'); });
148
+ });
149
+ it('calls onSubmitSuccess on success', async () => {
150
+ const onSubmitSuccess = jest.fn();
151
+ const root = (0, react_native_1.render)(<BugReportModal_1.BugReportModal {...defaultProps} onSubmitSuccess={onSubmitSuccess}/>);
152
+ await (0, react_native_1.act)(async () => { pressButton(root, 'Submit bug report'); });
153
+ await (0, react_native_1.waitFor)(() => { expect(onSubmitSuccess).toHaveBeenCalledTimes(1); });
154
+ });
155
+ it('calls onError on failure', async () => {
156
+ const onError = jest.fn();
157
+ const integration = createMockIntegration({
158
+ send: jest.fn().mockResolvedValue({ success: false, error: 'Whoops' }),
159
+ });
160
+ const root = (0, react_native_1.render)(<BugReportModal_1.BugReportModal {...defaultProps} integrations={[integration]} onError={onError}/>);
161
+ await (0, react_native_1.act)(async () => { pressButton(root, 'Submit bug report'); });
162
+ await (0, react_native_1.waitFor)(() => {
163
+ expect(onError).toHaveBeenCalledTimes(1);
164
+ expect(onError.mock.calls[0][0].message).toBe('Whoops');
165
+ });
166
+ });
167
+ });
168
+ //# sourceMappingURL=BugReportModal.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BugReportModal.test.js","sourceRoot":"","sources":["../../src/__tests__/BugReportModal.test.tsx"],"names":[],"mappings":"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"}
@@ -102,7 +102,7 @@ describe('SlackIntegration', () => {
102
102
  const blocks = body.blocks;
103
103
  // Should have header, main info, diagnostics, no image
104
104
  expect(blocks.length).toBeGreaterThanOrEqual(3);
105
- const diagnosticsBlock = blocks.find((b) => b.type === 'section' && b.text?.text?.includes('Last Error'));
105
+ const diagnosticsBlock = blocks.find((b) => b.type === 'section' && b.text?.text?.includes('Error'));
106
106
  expect(diagnosticsBlock).toBeDefined();
107
107
  expect(diagnosticsBlock.text.text).toContain('TypeError');
108
108
  expect(diagnosticsBlock.text.text).toContain('/home');