react-native-inapp-inspector 1.1.35 → 2.0.1
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 +123 -101
- package/android/build.gradle +13 -1
- package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +890 -0
- package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.kt +17 -0
- package/dist/commonjs/components/ConsoleLogCard.js +5 -5
- package/dist/commonjs/components/CopyButton.js +3 -0
- package/dist/commonjs/components/EndOfListFooter.js +1 -1
- package/dist/commonjs/components/ErrorBoundary.js +3 -0
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +25 -73
- package/dist/commonjs/components/Inspector/BundleTab.js +671 -189
- package/dist/commonjs/components/Inspector/ConsoleTab.js +110 -99
- package/dist/commonjs/components/Inspector/CrashTab.js +99 -91
- package/dist/commonjs/components/Inspector/InspectorHeader.js +107 -20
- package/dist/commonjs/components/Inspector/MainScreen.js +111 -68
- package/dist/commonjs/components/Inspector/NetworkTab.js +151 -30
- package/dist/commonjs/components/Inspector/PerformanceTab.js +96 -3
- package/dist/commonjs/components/Inspector/ReduxTab.js +18 -10
- package/dist/commonjs/components/Inspector/SettingsPanel.js +1218 -1238
- package/dist/commonjs/components/Inspector/TabBar.js +4 -2
- package/dist/commonjs/components/JsonViewer.js +9 -4
- package/dist/commonjs/components/LogCard.js +31 -1
- package/dist/commonjs/components/LogSyntaxHighlighter.d.ts +16 -0
- package/dist/commonjs/components/LogSyntaxHighlighter.js +130 -0
- package/dist/commonjs/components/NetworkIcons.d.ts +3 -0
- package/dist/commonjs/components/NetworkIcons.js +15 -1
- package/dist/commonjs/components/Slider.d.ts +13 -0
- package/dist/commonjs/components/Slider.js +261 -0
- package/dist/commonjs/components/TouchableScale.d.ts +1 -0
- package/dist/commonjs/components/TouchableScale.js +30 -32
- package/dist/commonjs/constants/index.d.ts +1 -2
- package/dist/commonjs/constants/index.js +4 -0
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/analyticsLogger.d.ts +4 -0
- package/dist/commonjs/customHooks/analyticsLogger.js +8 -6
- package/dist/commonjs/customHooks/crashHandler.js +8 -1
- package/dist/commonjs/helpers/index.d.ts +1 -0
- package/dist/commonjs/helpers/index.js +25 -1
- package/dist/commonjs/helpers/searchQueryParser.d.ts +6 -0
- package/dist/commonjs/helpers/searchQueryParser.js +236 -0
- package/dist/commonjs/helpers/settingsStore.d.ts +9 -0
- package/dist/commonjs/helpers/settingsStore.js +59 -3
- package/dist/commonjs/index.d.ts +1 -0
- package/dist/commonjs/index.js +220 -43
- package/dist/commonjs/native/NativeInspector.d.ts +125 -0
- package/dist/commonjs/native/NativeInspector.js +313 -0
- package/dist/commonjs/native/NativeNetworkInspector.d.ts +22 -0
- package/dist/commonjs/native/NativeNetworkInspector.js +4 -0
- package/dist/commonjs/styles/index.js +41 -41
- package/dist/commonjs/types/enums.d.ts +1 -1
- package/dist/commonjs/types/interfaces.d.ts +9 -0
- package/dist/esm/components/ConsoleLogCard.js +5 -5
- package/dist/esm/components/CopyButton.js +3 -0
- package/dist/esm/components/EndOfListFooter.js +2 -2
- package/dist/esm/components/ErrorBoundary.js +3 -0
- package/dist/esm/components/Inspector/AnalyticsTab.js +27 -75
- package/dist/esm/components/Inspector/BundleTab.js +671 -189
- package/dist/esm/components/Inspector/ConsoleTab.js +111 -100
- package/dist/esm/components/Inspector/CrashTab.js +99 -91
- package/dist/esm/components/Inspector/InspectorHeader.js +108 -21
- package/dist/esm/components/Inspector/MainScreen.js +113 -70
- package/dist/esm/components/Inspector/NetworkTab.js +152 -31
- package/dist/esm/components/Inspector/PerformanceTab.js +96 -3
- package/dist/esm/components/Inspector/ReduxTab.js +18 -10
- package/dist/esm/components/Inspector/SettingsPanel.js +1222 -1242
- package/dist/esm/components/Inspector/TabBar.js +4 -2
- package/dist/esm/components/JsonViewer.js +9 -4
- package/dist/esm/components/LogCard.js +32 -2
- package/dist/esm/components/LogSyntaxHighlighter.d.ts +16 -0
- package/dist/esm/components/LogSyntaxHighlighter.js +123 -0
- package/dist/esm/components/NetworkIcons.d.ts +3 -0
- package/dist/esm/components/NetworkIcons.js +11 -0
- package/dist/esm/components/Slider.d.ts +13 -0
- package/dist/esm/components/Slider.js +222 -0
- package/dist/esm/components/TouchableScale.d.ts +1 -0
- package/dist/esm/components/TouchableScale.js +31 -33
- package/dist/esm/constants/index.d.ts +1 -2
- package/dist/esm/constants/index.js +4 -0
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/analyticsLogger.d.ts +4 -0
- package/dist/esm/customHooks/analyticsLogger.js +6 -5
- package/dist/esm/customHooks/crashHandler.js +8 -1
- package/dist/esm/helpers/index.d.ts +1 -0
- package/dist/esm/helpers/index.js +11 -1
- package/dist/esm/helpers/searchQueryParser.d.ts +6 -0
- package/dist/esm/helpers/searchQueryParser.js +233 -0
- package/dist/esm/helpers/settingsStore.d.ts +9 -0
- package/dist/esm/helpers/settingsStore.js +58 -3
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +207 -44
- package/dist/esm/native/NativeInspector.d.ts +125 -0
- package/dist/esm/native/NativeInspector.js +289 -0
- package/dist/esm/native/NativeNetworkInspector.d.ts +22 -0
- package/dist/esm/native/NativeNetworkInspector.js +2 -0
- package/dist/esm/styles/index.js +41 -41
- package/dist/esm/types/enums.d.ts +1 -1
- package/dist/esm/types/interfaces.d.ts +9 -0
- package/ios/NetworkInspectorModule.h +6 -0
- package/ios/NetworkInspectorModule.m +760 -5
- package/package.json +13 -2
- package/react-native-inapp-inspector.podspec +7 -2
- package/android/src/main/java/com/inappinspector/NetworkInspectorModule.java +0 -97
- package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.java +0 -28
|
@@ -43,7 +43,7 @@ const addEvent = (event) => {
|
|
|
43
43
|
if (!isAnalyticsModuleEnabled)
|
|
44
44
|
return;
|
|
45
45
|
events.unshift(event);
|
|
46
|
-
events = events.slice(0,
|
|
46
|
+
events = events.slice(0, 75);
|
|
47
47
|
notify();
|
|
48
48
|
};
|
|
49
49
|
// ─── Public subscribe / query API ────────────────────────────────────────────
|
|
@@ -94,10 +94,11 @@ export const logAnalyticsEvent = (name, params = {}, userProperties = {}) => {
|
|
|
94
94
|
* setupAnalyticsLogger(analytics());
|
|
95
95
|
*/
|
|
96
96
|
let isAnalyticsPatched = false;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Returns true if analytics logging is active (always ready for custom and Firebase events).
|
|
99
|
+
*/
|
|
100
|
+
export const isAnalyticsConnected = () => true;
|
|
101
|
+
export const isFirebaseAnalyticsPatched = () => isAnalyticsPatched;
|
|
101
102
|
export const setupAnalyticsLogger = (analyticsInstance) => {
|
|
102
103
|
if (!analyticsInstance) {
|
|
103
104
|
console.warn('[AnalyticsLogger] No analytics instance provided — skipping setup.');
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LogBox, NativeModules, TurboModuleRegistry, NativeEventEmitter, Platform, AppState, Dimensions, } from 'react-native';
|
|
2
2
|
import { CrashExportFormat, CrashType } from '../types/enums';
|
|
3
3
|
import { addLogFromCrash } from './consoleLogger';
|
|
4
|
+
import { showNativeFloatingButton, setNativeFloatingButtonBadge, } from '../native/NativeInspector';
|
|
4
5
|
import { t } from '../i18n';
|
|
5
6
|
export { CrashExportFormat };
|
|
6
7
|
let crashListeners = [];
|
|
@@ -9,7 +10,7 @@ let lastHandledErrorTimestamp = 0;
|
|
|
9
10
|
let crashRecordsStore = [];
|
|
10
11
|
let breadcrumbsStore = [];
|
|
11
12
|
const MAX_BREADCRUMBS = 50;
|
|
12
|
-
let maxStoredCrashes =
|
|
13
|
+
let maxStoredCrashes = 50;
|
|
13
14
|
const appStartTime = Date.now();
|
|
14
15
|
let isCrashModuleEnabled = false;
|
|
15
16
|
export const setCrashModuleEnabled = (enabled) => {
|
|
@@ -365,6 +366,12 @@ export const handleInterceptedCrash = (errorOrTitle, rawStack, isFatal = false,
|
|
|
365
366
|
logId: log?.id,
|
|
366
367
|
crashRecord,
|
|
367
368
|
});
|
|
369
|
+
// Ensure native floating icon is visible & badged even if React UI is broken
|
|
370
|
+
try {
|
|
371
|
+
showNativeFloatingButton();
|
|
372
|
+
setNativeFloatingButtonBadge(true);
|
|
373
|
+
}
|
|
374
|
+
catch { }
|
|
368
375
|
return crashRecord;
|
|
369
376
|
}
|
|
370
377
|
catch (err) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { NetworkLog, RouteInfo, DiffResult, JsonContent, StackFrameType } from '../types';
|
|
2
|
+
export * from './searchQueryParser';
|
|
2
3
|
export declare const getDomainColor: (domain: string) => string;
|
|
3
4
|
export declare const formatDateTime: (timestamp: number) => string;
|
|
4
5
|
export declare const formatTimestamp: (timestamp: number) => string;
|
|
@@ -5,6 +5,7 @@ import { showToast } from './toast';
|
|
|
5
5
|
import { AppColors } from '../styles/AppColors';
|
|
6
6
|
// Constants
|
|
7
7
|
import { DOMAIN_COLORS, DURATION_FAST_MS, DURATION_SLOW_MS } from '../constants';
|
|
8
|
+
export * from './searchQueryParser';
|
|
8
9
|
export const getDomainColor = (domain) => {
|
|
9
10
|
if (!domain)
|
|
10
11
|
return DOMAIN_COLORS[0];
|
|
@@ -156,9 +157,18 @@ export const getFetchCommand = (log) => {
|
|
|
156
157
|
export const deduplicateLogs = (raw) => {
|
|
157
158
|
const map = new Map();
|
|
158
159
|
raw.forEach(entry => {
|
|
159
|
-
if (!map.has(entry.id)
|
|
160
|
+
if (!map.has(entry.id)) {
|
|
160
161
|
map.set(entry.id, entry);
|
|
161
162
|
}
|
|
163
|
+
else {
|
|
164
|
+
const existing = map.get(entry.id);
|
|
165
|
+
if (existing.status == null && entry.status != null) {
|
|
166
|
+
map.set(entry.id, entry);
|
|
167
|
+
}
|
|
168
|
+
else if ((entry.startTime ?? 0) >= (existing.startTime ?? 0)) {
|
|
169
|
+
map.set(entry.id, entry);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
162
172
|
});
|
|
163
173
|
return Array.from(map.values()).sort((a, b) => b.id - a.id);
|
|
164
174
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { NetworkLog } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Parses query strings like `method:POST is:error slow:>1s status:200 auth`
|
|
4
|
+
* and checks whether a given NetworkLog matches all tokens.
|
|
5
|
+
*/
|
|
6
|
+
export declare function matchNetworkLogQuery(log: NetworkLog, searchQuery: string, routePath?: string): boolean;
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses query strings like `method:POST is:error slow:>1s status:200 auth`
|
|
3
|
+
* and checks whether a given NetworkLog matches all tokens.
|
|
4
|
+
*/
|
|
5
|
+
export function matchNetworkLogQuery(log, searchQuery, routePath) {
|
|
6
|
+
if (!searchQuery || searchQuery.trim().length === 0)
|
|
7
|
+
return true;
|
|
8
|
+
const rawTokens = searchQuery
|
|
9
|
+
.trim()
|
|
10
|
+
.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) || [];
|
|
11
|
+
if (rawTokens.length === 0)
|
|
12
|
+
return true;
|
|
13
|
+
const methodStr = (log.method || '').toLowerCase();
|
|
14
|
+
const urlStr = (log.url || '').toLowerCase();
|
|
15
|
+
const statusNum = typeof log.status === 'number' ? log.status : parseInt(String(log.status || 0), 10);
|
|
16
|
+
const statusStr = String(log.status ?? '');
|
|
17
|
+
const durationNum = log.duration || 0;
|
|
18
|
+
const clientStr = (log.client || '').toLowerCase();
|
|
19
|
+
const reqStr = typeof log.request === 'string' ? log.request : JSON.stringify(log.request || '');
|
|
20
|
+
const resStr = typeof log.response === 'string' ? log.response : JSON.stringify(log.response || '');
|
|
21
|
+
const reqHeadersStr = JSON.stringify(log.requestHeaders || '').toLowerCase();
|
|
22
|
+
const resHeadersStr = JSON.stringify(log.responseHeaders || '').toLowerCase();
|
|
23
|
+
const pathStr = routePath ? routePath.toLowerCase() : '';
|
|
24
|
+
const fullSearchCorpus = [
|
|
25
|
+
methodStr,
|
|
26
|
+
urlStr,
|
|
27
|
+
statusStr,
|
|
28
|
+
pathStr,
|
|
29
|
+
clientStr,
|
|
30
|
+
reqStr.toLowerCase(),
|
|
31
|
+
resStr.toLowerCase(),
|
|
32
|
+
reqHeadersStr,
|
|
33
|
+
resHeadersStr,
|
|
34
|
+
].join(' ');
|
|
35
|
+
for (const rawToken of rawTokens) {
|
|
36
|
+
const token = rawToken.replace(/^["']|["']$/g, '').trim();
|
|
37
|
+
if (!token)
|
|
38
|
+
continue;
|
|
39
|
+
const lowerToken = token.toLowerCase();
|
|
40
|
+
// 1. method:<VAL> or m:<VAL>
|
|
41
|
+
if (lowerToken.startsWith('method:') || lowerToken.startsWith('m:')) {
|
|
42
|
+
const targetMethod = lowerToken.replace(/^(method:|m:)/, '').trim();
|
|
43
|
+
if (targetMethod.startsWith('!')) {
|
|
44
|
+
if (methodStr === targetMethod.slice(1))
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
if (methodStr !== targetMethod)
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
// 2. status:<VAL> or s:<VAL>
|
|
54
|
+
if (lowerToken.startsWith('status:') || lowerToken.startsWith('s:')) {
|
|
55
|
+
const val = lowerToken.replace(/^(status:|s:)/, '').trim();
|
|
56
|
+
if (val.startsWith('>=')) {
|
|
57
|
+
const threshold = parseInt(val.slice(2), 10);
|
|
58
|
+
if (isNaN(threshold) || statusNum < threshold)
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
else if (val.startsWith('>')) {
|
|
62
|
+
const threshold = parseInt(val.slice(1), 10);
|
|
63
|
+
if (isNaN(threshold) || statusNum <= threshold)
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
else if (val.startsWith('<=')) {
|
|
67
|
+
const threshold = parseInt(val.slice(2), 10);
|
|
68
|
+
if (isNaN(threshold) || statusNum > threshold)
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
else if (val.startsWith('<')) {
|
|
72
|
+
const threshold = parseInt(val.slice(1), 10);
|
|
73
|
+
if (isNaN(threshold) || statusNum >= threshold)
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
else if (val.endsWith('xx') || val.endsWith('x')) {
|
|
77
|
+
const prefix = val.replace(/x/g, '');
|
|
78
|
+
if (!statusStr.startsWith(prefix))
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const targetCode = parseInt(val, 10);
|
|
83
|
+
if (!isNaN(targetCode)) {
|
|
84
|
+
if (statusNum !== targetCode)
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
else if (!statusStr.includes(val)) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
// 3. is:<FLAG>
|
|
94
|
+
if (lowerToken.startsWith('is:')) {
|
|
95
|
+
const flag = lowerToken.slice(3).trim();
|
|
96
|
+
if (flag === 'error' || flag === 'failed' || flag === 'err' || flag === 'fail') {
|
|
97
|
+
const isErr = log.status === 0 || log.status == null || statusNum >= 400;
|
|
98
|
+
if (!isErr)
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
else if (flag === 'success' || flag === 'ok' || flag === '2xx') {
|
|
102
|
+
const isSuccess = statusNum >= 200 && statusNum < 300;
|
|
103
|
+
if (!isSuccess)
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
else if (flag === 'slow') {
|
|
107
|
+
if (durationNum < 1000)
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
else if (flag === 'fast') {
|
|
111
|
+
if (durationNum >= 200)
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
else if (flag === 'graphql' || flag === 'gql') {
|
|
115
|
+
const isGql = urlStr.includes('graphql') ||
|
|
116
|
+
clientStr === 'graphql' ||
|
|
117
|
+
clientStr === 'apollo';
|
|
118
|
+
if (!isGql)
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
else if (flag === 'https') {
|
|
122
|
+
if (!urlStr.startsWith('https'))
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
else if (flag === 'http') {
|
|
126
|
+
if (urlStr.startsWith('https') || !urlStr.startsWith('http'))
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
else if (flag === 'json') {
|
|
130
|
+
const isJson = reqHeadersStr.includes('application/json') ||
|
|
131
|
+
resHeadersStr.includes('application/json') ||
|
|
132
|
+
urlStr.includes('.json');
|
|
133
|
+
if (!isJson)
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
// 4. slow:<DURATION> or dur:<DURATION> or duration:<DURATION>
|
|
139
|
+
if (lowerToken.startsWith('slow:') ||
|
|
140
|
+
lowerToken.startsWith('dur:') ||
|
|
141
|
+
lowerToken.startsWith('duration:')) {
|
|
142
|
+
const val = lowerToken.replace(/^(slow:|dur:|duration:)/, '').trim();
|
|
143
|
+
let thresholdMs = 0;
|
|
144
|
+
let isGreater = true;
|
|
145
|
+
let cleanVal = val;
|
|
146
|
+
if (val.startsWith('>=')) {
|
|
147
|
+
isGreater = true;
|
|
148
|
+
cleanVal = val.slice(2);
|
|
149
|
+
}
|
|
150
|
+
else if (val.startsWith('>')) {
|
|
151
|
+
isGreater = true;
|
|
152
|
+
cleanVal = val.slice(1);
|
|
153
|
+
}
|
|
154
|
+
else if (val.startsWith('<=')) {
|
|
155
|
+
isGreater = false;
|
|
156
|
+
cleanVal = val.slice(2);
|
|
157
|
+
}
|
|
158
|
+
else if (val.startsWith('<')) {
|
|
159
|
+
isGreater = false;
|
|
160
|
+
cleanVal = val.slice(1);
|
|
161
|
+
}
|
|
162
|
+
if (cleanVal.endsWith('s') && !cleanVal.endsWith('ms')) {
|
|
163
|
+
thresholdMs = parseFloat(cleanVal.slice(0, -1)) * 1000;
|
|
164
|
+
}
|
|
165
|
+
else if (cleanVal.endsWith('ms')) {
|
|
166
|
+
thresholdMs = parseFloat(cleanVal.slice(0, -2));
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
thresholdMs = parseFloat(cleanVal);
|
|
170
|
+
}
|
|
171
|
+
if (!isNaN(thresholdMs)) {
|
|
172
|
+
if (isGreater) {
|
|
173
|
+
if (durationNum < thresholdMs)
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
if (durationNum > thresholdMs)
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
// 5. client:<CLIENT> or c:<CLIENT>
|
|
184
|
+
if (lowerToken.startsWith('client:') || lowerToken.startsWith('c:')) {
|
|
185
|
+
const targetClient = lowerToken.replace(/^(client:|c:)/, '').trim();
|
|
186
|
+
if (!clientStr.includes(targetClient))
|
|
187
|
+
return false;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
// 6. domain:<DOMAIN> or d:<DOMAIN>
|
|
191
|
+
if (lowerToken.startsWith('domain:') || lowerToken.startsWith('d:')) {
|
|
192
|
+
const targetDomain = lowerToken.replace(/^(domain:|d:)/, '').trim();
|
|
193
|
+
if (!urlStr.includes(targetDomain))
|
|
194
|
+
return false;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
// 7. path:<PATH> or p:<PATH>
|
|
198
|
+
if (lowerToken.startsWith('path:') || lowerToken.startsWith('p:')) {
|
|
199
|
+
const targetPath = lowerToken.replace(/^(path:|p:)/, '').trim();
|
|
200
|
+
if (!urlStr.includes(targetPath) && !pathStr.includes(targetPath)) {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
// 8. req:<TERM> or body:<TERM>
|
|
206
|
+
if (lowerToken.startsWith('req:') || lowerToken.startsWith('body:')) {
|
|
207
|
+
const target = lowerToken.replace(/^(req:|body:)/, '').trim();
|
|
208
|
+
if (!reqStr.toLowerCase().includes(target))
|
|
209
|
+
return false;
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
// 9. res:<TERM>
|
|
213
|
+
if (lowerToken.startsWith('res:')) {
|
|
214
|
+
const target = lowerToken.slice(4).trim();
|
|
215
|
+
if (!resStr.toLowerCase().includes(target))
|
|
216
|
+
return false;
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
// 10. header:<TERM> or h:<TERM>
|
|
220
|
+
if (lowerToken.startsWith('header:') || lowerToken.startsWith('h:')) {
|
|
221
|
+
const target = lowerToken.replace(/^(header:|h:)/, '').trim();
|
|
222
|
+
if (!reqHeadersStr.includes(target) && !resHeadersStr.includes(target)) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
// 11. Generic Plain Substring Match
|
|
228
|
+
if (!fullSearchCorpus.includes(lowerToken)) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
@@ -6,3 +6,12 @@ export declare function saveSettings(settings: PersistedSettings): void;
|
|
|
6
6
|
export declare function clearPersistedSettings(): Promise<void>;
|
|
7
7
|
export declare const isPersistentStorageAvailable: () => boolean;
|
|
8
8
|
export declare function getCustomStorage(): InspectorStorage | null;
|
|
9
|
+
export interface RamLimitsProfile {
|
|
10
|
+
maxNetworkLogs: number;
|
|
11
|
+
maxConsoleLogs: number;
|
|
12
|
+
maxAnalyticsEvents: number;
|
|
13
|
+
maxCrashRecords: number;
|
|
14
|
+
profileName: 'High-End' | 'Standard' | 'Compact' | 'Ultra-Light';
|
|
15
|
+
freeRamMb: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function calculateRamBasedLimits(freeRamMb: number): RamLimitsProfile;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// Backed by iOS Settings (NSUserDefaults) for iOS, or custom storage if passed (e.g. AsyncStorage/MMKV).
|
|
4
4
|
// Contains an in-memory fallback for Android or Jest test environments.
|
|
5
5
|
import { Platform, Settings } from 'react-native';
|
|
6
|
+
import { getNativeStorageItem, setNativeStorageItem, isNativeModuleAvailable, } from '../native/NativeInspector';
|
|
6
7
|
// In-memory fallback (settings survive for the app session only).
|
|
7
8
|
const memory = new Map();
|
|
8
9
|
let customStorage = null;
|
|
@@ -19,6 +20,13 @@ export async function loadSettings() {
|
|
|
19
20
|
const parsed = JSON.parse(raw);
|
|
20
21
|
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
21
22
|
}
|
|
23
|
+
if (isNativeModuleAvailable()) {
|
|
24
|
+
const raw = await getNativeStorageItem(SETTINGS_KEY);
|
|
25
|
+
if (raw) {
|
|
26
|
+
const parsed = JSON.parse(raw);
|
|
27
|
+
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
22
30
|
if (Platform.OS === 'ios') {
|
|
23
31
|
const raw = Settings.get(SETTINGS_KEY);
|
|
24
32
|
if (!raw)
|
|
@@ -29,7 +37,7 @@ export async function loadSettings() {
|
|
|
29
37
|
}
|
|
30
38
|
return raw && typeof raw === 'object' ? raw : {};
|
|
31
39
|
}
|
|
32
|
-
//
|
|
40
|
+
// In-memory fallback
|
|
33
41
|
const raw = memory.get(SETTINGS_KEY);
|
|
34
42
|
if (!raw)
|
|
35
43
|
return {};
|
|
@@ -47,11 +55,13 @@ export function saveSettings(settings) {
|
|
|
47
55
|
customStorage.setItem(SETTINGS_KEY, raw);
|
|
48
56
|
return;
|
|
49
57
|
}
|
|
58
|
+
if (isNativeModuleAvailable()) {
|
|
59
|
+
setNativeStorageItem(SETTINGS_KEY, raw);
|
|
60
|
+
}
|
|
50
61
|
if (Platform.OS === 'ios') {
|
|
51
62
|
Settings.set({ [SETTINGS_KEY]: raw });
|
|
52
63
|
return;
|
|
53
64
|
}
|
|
54
|
-
// Android/fallback: memory
|
|
55
65
|
memory.set(SETTINGS_KEY, raw);
|
|
56
66
|
}
|
|
57
67
|
catch {
|
|
@@ -69,6 +79,9 @@ export async function clearPersistedSettings() {
|
|
|
69
79
|
}
|
|
70
80
|
return;
|
|
71
81
|
}
|
|
82
|
+
if (isNativeModuleAvailable()) {
|
|
83
|
+
await setNativeStorageItem(SETTINGS_KEY, null);
|
|
84
|
+
}
|
|
72
85
|
if (Platform.OS === 'ios') {
|
|
73
86
|
Settings.set({ [SETTINGS_KEY]: null });
|
|
74
87
|
return;
|
|
@@ -80,8 +93,50 @@ export async function clearPersistedSettings() {
|
|
|
80
93
|
}
|
|
81
94
|
}
|
|
82
95
|
export const isPersistentStorageAvailable = () => {
|
|
83
|
-
return customStorage !== null || Platform.OS === 'ios';
|
|
96
|
+
return customStorage !== null || isNativeModuleAvailable() || Platform.OS === 'ios';
|
|
84
97
|
};
|
|
85
98
|
export function getCustomStorage() {
|
|
86
99
|
return customStorage;
|
|
87
100
|
}
|
|
101
|
+
export function calculateRamBasedLimits(freeRamMb) {
|
|
102
|
+
if (freeRamMb >= 3000) {
|
|
103
|
+
return {
|
|
104
|
+
maxNetworkLogs: 100,
|
|
105
|
+
maxConsoleLogs: 100,
|
|
106
|
+
maxAnalyticsEvents: 75,
|
|
107
|
+
maxCrashRecords: 50,
|
|
108
|
+
profileName: 'High-End',
|
|
109
|
+
freeRamMb,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
else if (freeRamMb >= 1500) {
|
|
113
|
+
return {
|
|
114
|
+
maxNetworkLogs: 100,
|
|
115
|
+
maxConsoleLogs: 100,
|
|
116
|
+
maxAnalyticsEvents: 75,
|
|
117
|
+
maxCrashRecords: 50,
|
|
118
|
+
profileName: 'Standard',
|
|
119
|
+
freeRamMb,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
else if (freeRamMb >= 600) {
|
|
123
|
+
return {
|
|
124
|
+
maxNetworkLogs: 100,
|
|
125
|
+
maxConsoleLogs: 100,
|
|
126
|
+
maxAnalyticsEvents: 50,
|
|
127
|
+
maxCrashRecords: 25,
|
|
128
|
+
profileName: 'Compact',
|
|
129
|
+
freeRamMb,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
return {
|
|
134
|
+
maxNetworkLogs: 50,
|
|
135
|
+
maxConsoleLogs: 50,
|
|
136
|
+
maxAnalyticsEvents: 25,
|
|
137
|
+
maxCrashRecords: 15,
|
|
138
|
+
profileName: 'Ultra-Light',
|
|
139
|
+
freeRamMb,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -12,4 +12,5 @@ export { connectReduxStore, inspectorReduxMiddleware, getReduxState, subscribeRe
|
|
|
12
12
|
export { getEventCategory, registerGAPlugin, type GAPlugin, } from './helpers/gaAnalyticsRegistry';
|
|
13
13
|
export { usePerformanceTracker, useComponentProfiler, useNavigationProfiler, trackComponentRender, trackNavigationTransition, trackHeavyTask, measureAsync, getHermesMemoryStats, registerComponentProfile, subscribeRenderProfiles, getRenderProfiles, logPerformanceEvent, clearPerformanceEvents, subscribePerformanceEvents, getPerformanceEvents, getInitialRenderProfiles, getInitialPerformanceEvents, generateFixSnippet, } from './customHooks/performanceTracker';
|
|
14
14
|
export { InspectLog, InspectTrackTime, InspectCatch, type InspectLogOptions, } from './decorators';
|
|
15
|
+
export { getNativeDeviceMetrics, enableNativeCrashProtection, subscribeNativeCrashes, showNativeFloatingButton, hideNativeFloatingButton, setNativeFloatingButtonBadge, subscribeNativeFloatingButtonPress, subscribeNativeDeviceShake, startNativeFpsMonitoring, stopNativeFpsMonitoring, getNativeFpsMetrics, getNativeStorageItem, setNativeStorageItem, isNativeModuleAvailable, type NativeDeviceMetrics, type NativeCrashEvent, type FloatingButtonOptions, type NativeFpsMetrics, } from './native/NativeInspector';
|
|
15
16
|
export { ActiveTab, Method, StatusFilter, SortOrder, LocalFilter, ModalAnimationType, SettingsPage, SettingsSubTab, LogFilter, ConsoleLogType, AnalyticsEventSource, GAEventCategory, StackFrameType, DiffResultType, BundleSubTab, PerformanceSubTab, CrashType, CrashExportFormat, CrashDetailSubTab, CrashFilterType, BreadcrumbType, } from './types';
|