@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.
- package/README.md +41 -0
- package/dist/AnnotationCanvas.d.ts +3 -1
- package/dist/AnnotationCanvas.d.ts.map +1 -1
- package/dist/AnnotationCanvas.js +34 -8
- package/dist/AnnotationCanvas.js.map +1 -1
- package/dist/BugReportModal.d.ts +3 -1
- package/dist/BugReportModal.d.ts.map +1 -1
- package/dist/BugReportModal.js +136 -47
- package/dist/BugReportModal.js.map +1 -1
- package/dist/BugReportProvider.d.ts +3 -1
- package/dist/BugReportProvider.d.ts.map +1 -1
- package/dist/BugReportProvider.js +9 -3
- package/dist/BugReportProvider.js.map +1 -1
- package/dist/DeviceInfo.d.ts.map +1 -1
- package/dist/DeviceInfo.js +13 -1
- package/dist/DeviceInfo.js.map +1 -1
- package/dist/NavigationTracker.d.ts +6 -1
- package/dist/NavigationTracker.d.ts.map +1 -1
- package/dist/NavigationTracker.js +58 -23
- package/dist/NavigationTracker.js.map +1 -1
- package/dist/ShakeDetector.d.ts.map +1 -1
- package/dist/ShakeDetector.js +50 -17
- package/dist/ShakeDetector.js.map +1 -1
- package/dist/StateCapture.d.ts.map +1 -1
- package/dist/StateCapture.js +8 -9
- package/dist/StateCapture.js.map +1 -1
- package/dist/__tests__/BugReportModal.test.d.ts +2 -0
- package/dist/__tests__/BugReportModal.test.d.ts.map +1 -0
- package/dist/__tests__/BugReportModal.test.js +168 -0
- package/dist/__tests__/BugReportModal.test.js.map +1 -0
- package/dist/__tests__/integrations/slack.test.js +1 -1
- package/dist/__tests__/integrations/slack.test.js.map +1 -1
- package/dist/__tests__/useThemeColors.test.d.ts +2 -0
- package/dist/__tests__/useThemeColors.test.d.ts.map +1 -0
- package/dist/__tests__/useThemeColors.test.js +38 -0
- package/dist/__tests__/useThemeColors.test.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/slack.d.ts.map +1 -1
- package/dist/integrations/slack.js +41 -24
- package/dist/integrations/slack.js.map +1 -1
- package/dist/integrations/webhook.d.ts +1 -0
- package/dist/integrations/webhook.d.ts.map +1 -1
- package/dist/integrations/webhook.js +29 -6
- package/dist/integrations/webhook.js.map +1 -1
- package/dist/useThemeColors.d.ts +16 -0
- package/dist/useThemeColors.d.ts.map +1 -0
- package/dist/useThemeColors.js +36 -0
- package/dist/useThemeColors.js.map +1 -0
- 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;
|
|
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
|
-
|
|
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={
|
|
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"BugReportProvider.js","sourceRoot":"","sources":["../src/BugReportProvider.tsx"],"names":[],"mappings":"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"}
|
package/dist/DeviceInfo.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/DeviceInfo.js
CHANGED
|
@@ -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:
|
|
71
|
+
installationId: getInstallationId(),
|
|
60
72
|
expoConfig,
|
|
61
73
|
};
|
|
62
74
|
}
|
package/dist/DeviceInfo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceInfo.js","sourceRoot":"","sources":["../src/DeviceInfo.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
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
|
-
|
|
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;
|
|
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 =
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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 ===
|
|
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
|
-
|
|
43
|
-
//
|
|
44
|
-
let totalBytes =
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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":"
|
|
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":"
|
|
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"}
|
package/dist/ShakeDetector.js
CHANGED
|
@@ -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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
|
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":";;
|
|
1
|
+
{"version":3,"file":"ShakeDetector.js","sourceRoot":"","sources":["../src/ShakeDetector.ts"],"names":[],"mappings":"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"}
|
|
@@ -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;
|
|
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"}
|
package/dist/StateCapture.js
CHANGED
|
@@ -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
|
-
|
|
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)) {
|
package/dist/StateCapture.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StateCapture.js","sourceRoot":"","sources":["../src/StateCapture.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"StateCapture.js","sourceRoot":"","sources":["../src/StateCapture.ts"],"names":[],"mappings":"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"}
|
|
@@ -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('
|
|
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');
|