react-native-inapp-inspector 1.1.29 → 1.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/components/AnalyticsDetail.js +668 -108
- package/dist/commonjs/components/AppHeaderLogo.js +5 -2
- package/dist/commonjs/components/ConsoleLogCard.js +81 -59
- package/dist/commonjs/components/DomainHeader.js +21 -17
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +297 -200
- package/dist/commonjs/components/Inspector/ConsoleTab.js +162 -56
- package/dist/commonjs/components/Inspector/InspectorHeader.js +56 -119
- package/dist/commonjs/components/Inspector/LogDetail.js +45 -12
- package/dist/commonjs/components/Inspector/NetworkTab.js +4 -1
- package/dist/commonjs/components/Inspector/ReduxDetail.js +237 -42
- package/dist/commonjs/components/Inspector/ReduxTab.js +456 -35
- package/dist/commonjs/components/JsonViewer.js +1 -1
- package/dist/commonjs/components/NetworkIcons.js +19 -10
- package/dist/commonjs/components/TreeNode.js +12 -2
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/reduxLogger.js +128 -5
- package/dist/commonjs/helpers/index.d.ts +1 -1
- package/dist/commonjs/helpers/index.js +32 -16
- package/dist/commonjs/i18n/locales/en.json +45 -2
- package/dist/commonjs/styles/AppColors.d.ts +6 -0
- package/dist/commonjs/styles/AppColors.js +6 -0
- package/dist/commonjs/styles/index.d.ts +22 -1
- package/dist/commonjs/styles/index.js +25 -4
- package/dist/commonjs/types/interfaces.d.ts +7 -0
- package/dist/esm/components/AnalyticsDetail.js +670 -110
- package/dist/esm/components/AppHeaderLogo.js +5 -2
- package/dist/esm/components/ConsoleLogCard.js +81 -59
- package/dist/esm/components/DomainHeader.js +21 -17
- package/dist/esm/components/Inspector/AnalyticsTab.js +298 -201
- package/dist/esm/components/Inspector/ConsoleTab.js +163 -57
- package/dist/esm/components/Inspector/InspectorHeader.js +57 -120
- package/dist/esm/components/Inspector/LogDetail.js +45 -12
- package/dist/esm/components/Inspector/NetworkTab.js +4 -1
- package/dist/esm/components/Inspector/ReduxDetail.js +239 -44
- package/dist/esm/components/Inspector/ReduxTab.js +458 -37
- package/dist/esm/components/JsonViewer.js +1 -1
- package/dist/esm/components/NetworkIcons.js +19 -10
- package/dist/esm/components/TreeNode.js +12 -2
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/reduxLogger.js +128 -5
- package/dist/esm/helpers/index.d.ts +1 -1
- package/dist/esm/helpers/index.js +32 -16
- package/dist/esm/i18n/locales/en.json +45 -2
- package/dist/esm/styles/AppColors.d.ts +6 -0
- package/dist/esm/styles/AppColors.js +6 -0
- package/dist/esm/styles/index.d.ts +22 -1
- package/dist/esm/styles/index.js +25 -4
- package/dist/esm/types/interfaces.d.ts +7 -0
- package/package.json +11 -11
|
@@ -362,15 +362,21 @@ export const ForwardChevronIcon = ({ color = AppColors.grayTextWeak, size = 14,
|
|
|
362
362
|
export const BundleIcon = PackageIcon;
|
|
363
363
|
export const LiveStateIcon = ({ color = AppColors.purple, size = 14, }) => {
|
|
364
364
|
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
365
|
-
<
|
|
366
|
-
<Circle cx="12" cy="12" r="
|
|
367
|
-
<Circle cx="12" cy="12" r="
|
|
365
|
+
<Circle cx="12" cy="12" r="9" stroke={color} strokeWidth="1.8" strokeDasharray="3 3" opacity={0.6}/>
|
|
366
|
+
<Circle cx="12" cy="12" r="4.5" stroke={color} strokeWidth="1.8"/>
|
|
367
|
+
<Circle cx="12" cy="12" r="2" fill={color}/>
|
|
368
|
+
<Path d="M12 2v2.5M12 19.5V22M2 12h2.5M19.5 12H22" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
|
|
368
369
|
</Svg>);
|
|
369
370
|
};
|
|
370
371
|
export const TimelineIcon = ({ color = AppColors.purple, size = 14, }) => {
|
|
371
372
|
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
372
|
-
<
|
|
373
|
-
<
|
|
373
|
+
<Path d="M6 3v18" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
|
|
374
|
+
<Circle cx="6" cy="6" r="2.5" stroke={color} strokeWidth="1.8" fill={`${color}25`}/>
|
|
375
|
+
<Path d="M6 12h5a3 3 0 0 0 3-3V6" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
|
|
376
|
+
<Circle cx="14" cy="6" r="2.5" stroke={color} strokeWidth="1.8" fill={color}/>
|
|
377
|
+
<Circle cx="6" cy="18" r="2.5" stroke={color} strokeWidth="1.8" fill={color}/>
|
|
378
|
+
<Path d="M6 18h8" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
|
|
379
|
+
<Circle cx="17" cy="18" r="2.5" stroke={color} strokeWidth="1.8" fill={`${color}25`}/>
|
|
374
380
|
</Svg>);
|
|
375
381
|
};
|
|
376
382
|
export const RefreshCcwIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
@@ -380,15 +386,18 @@ export const RefreshCcwIcon = ({ color = AppColors.grayTextWeak, size = 14, }) =
|
|
|
380
386
|
};
|
|
381
387
|
export const StorageIcon = ({ color = AppColors.purple, size = 14, }) => {
|
|
382
388
|
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
383
|
-
<Ellipse cx="12" cy="
|
|
384
|
-
<Path d="
|
|
385
|
-
<Path d="M4
|
|
389
|
+
<Ellipse cx="12" cy="5" rx="8" ry="2.5" stroke={color} strokeWidth="1.8"/>
|
|
390
|
+
<Path d="M4 5v4.5c0 1.38 3.58 2.5 8 2.5s8-1.12 8-2.5V5" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
|
|
391
|
+
<Path d="M4 9.5v4.5c0 1.38 3.58 2.5 8 2.5s8-1.12 8-2.5v-4.5" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
|
|
392
|
+
<Path d="M4 14v4.5c0 1.38 3.58 2.5 8 2.5s8-1.12 8-2.5V14" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
|
|
386
393
|
</Svg>);
|
|
387
394
|
};
|
|
388
395
|
export const MetadataIcon = ({ color = AppColors.purple, size = 14, }) => {
|
|
389
396
|
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
390
|
-
<
|
|
391
|
-
<Path d="
|
|
397
|
+
<Rect x="3" y="3" width="18" height="18" rx="4" stroke={color} strokeWidth="1.8"/>
|
|
398
|
+
<Path d="M7 8h10M7 12h6M7 16h7" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
|
|
399
|
+
<Circle cx="16.5" cy="12" r="1.5" fill={color}/>
|
|
400
|
+
<Circle cx="16.5" cy="16" r="1.5" fill={color}/>
|
|
392
401
|
</Svg>);
|
|
393
402
|
};
|
|
394
403
|
export const ReduxIcon = ({ color = AppColors.purple, size = 14, }) => {
|
|
@@ -7,9 +7,19 @@ import { ChevronIcon, DocIcon } from './NetworkIcons';
|
|
|
7
7
|
// Stylesheet
|
|
8
8
|
import { AppColors } from '../styles/AppColors';
|
|
9
9
|
import styles from '../styles';
|
|
10
|
-
const TreeNode = React.memo(function TreeNode({ data, name, level = 0, search, forceOpen, defaultExpandDepth, }) {
|
|
11
|
-
const [localOpen, setLocalOpen] = useState(
|
|
10
|
+
const TreeNode = React.memo(function TreeNode({ data, name, level = 0, search, forceOpen, defaultExpandDepth = 1, }) {
|
|
11
|
+
const [localOpen, setLocalOpen] = useState(() => {
|
|
12
|
+
if (forceOpen !== undefined) {
|
|
13
|
+
return forceOpen;
|
|
14
|
+
}
|
|
15
|
+
return defaultExpandDepth !== undefined ? level < defaultExpandDepth : level < 1;
|
|
16
|
+
});
|
|
12
17
|
const open = localOpen;
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (forceOpen !== undefined) {
|
|
20
|
+
setLocalOpen(forceOpen);
|
|
21
|
+
}
|
|
22
|
+
}, [forceOpen]);
|
|
13
23
|
const isObject = typeof data === 'object' && data !== null;
|
|
14
24
|
const isArray = Array.isArray(data);
|
|
15
25
|
// Declare all hooks at the top unconditionally (prevents "Rendered fewer hooks than expected" error)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "1.1.
|
|
1
|
+
export declare const LIB_VERSION = "1.1.32";
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// that bypass the wrapped dispatch (thunk/saga internals capture the raw
|
|
12
12
|
// dispatch reference at store-creation time) still update the state tree
|
|
13
13
|
// and per-reducer "last action" consistently.
|
|
14
|
+
import { parseStackLine } from '../helpers';
|
|
14
15
|
let currentReduxState = null;
|
|
15
16
|
const listeners = new Set();
|
|
16
17
|
let globalReduxAutoRefresh = true;
|
|
@@ -63,7 +64,106 @@ function actionTypeOf(action) {
|
|
|
63
64
|
}
|
|
64
65
|
return 'UNKNOWN_ACTION';
|
|
65
66
|
}
|
|
66
|
-
function
|
|
67
|
+
function detectActionOrigin(stack, actionType, actionObj) {
|
|
68
|
+
const stackLower = (stack || '').toLowerCase();
|
|
69
|
+
const typeLower = (actionType || '').toLowerCase();
|
|
70
|
+
// Explicit hint on action if developer tagged it
|
|
71
|
+
if (actionObj && actionObj.__origin) {
|
|
72
|
+
const raw = String(actionObj.__origin).toLowerCase();
|
|
73
|
+
if (raw.includes('saga'))
|
|
74
|
+
return { originType: 'saga' };
|
|
75
|
+
if (raw.includes('thunk'))
|
|
76
|
+
return { originType: 'thunk' };
|
|
77
|
+
if (raw.includes('ui'))
|
|
78
|
+
return { originType: 'ui' };
|
|
79
|
+
}
|
|
80
|
+
// 1. Saga Detection (Stack + Action naming conventions)
|
|
81
|
+
const isSaga = stackLower.includes('redux-saga') ||
|
|
82
|
+
stackLower.includes('runputeffect') ||
|
|
83
|
+
stackLower.includes('proc.js') ||
|
|
84
|
+
stackLower.includes('effects.js') ||
|
|
85
|
+
stackLower.includes('sagamiddleware') ||
|
|
86
|
+
stackLower.includes('saga.ts') ||
|
|
87
|
+
stackLower.includes('saga.js') ||
|
|
88
|
+
stackLower.includes('sagas') ||
|
|
89
|
+
typeLower.includes('saga') ||
|
|
90
|
+
typeLower.startsWith('saga/') ||
|
|
91
|
+
typeLower.startsWith('@saga/');
|
|
92
|
+
// 2. Thunk / RTK Query Detection
|
|
93
|
+
const isThunk = stackLower.includes('createasyncthunk') ||
|
|
94
|
+
stackLower.includes('redux-thunk') ||
|
|
95
|
+
stackLower.includes('rtk-query') ||
|
|
96
|
+
stackLower.includes('thunkmiddleware') ||
|
|
97
|
+
stackLower.includes('actioncreator') ||
|
|
98
|
+
typeLower.includes('thunk') ||
|
|
99
|
+
typeLower.endsWith('/pending') ||
|
|
100
|
+
typeLower.endsWith('/fulfilled') ||
|
|
101
|
+
typeLower.endsWith('/rejected');
|
|
102
|
+
// 3. Parse Stack Frames to find best application caller
|
|
103
|
+
const lines = (stack || '').split('\n').map(l => l.trim()).filter(Boolean);
|
|
104
|
+
let bestFrame = null;
|
|
105
|
+
for (let i = 0; i < lines.length; i++) {
|
|
106
|
+
const line = lines[i];
|
|
107
|
+
// Ignore logger / middleware lines inside inspector
|
|
108
|
+
if (line.includes('reduxLogger') ||
|
|
109
|
+
line.includes('inspectorReduxMiddleware') ||
|
|
110
|
+
line.includes('recordAction') ||
|
|
111
|
+
line.includes('redux.js') ||
|
|
112
|
+
line.includes('redux.cjs')) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const parsed = parseStackLine(line, false);
|
|
116
|
+
if (parsed.frameType === 'app' || (!parsed.isRuntimeNoise && parsed.fileName !== 'Unknown')) {
|
|
117
|
+
bestFrame = parsed;
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (!bestFrame && lines.length > 0) {
|
|
122
|
+
for (let i = 0; i < lines.length; i++) {
|
|
123
|
+
if (!lines[i].includes('reduxLogger') && !lines[i].includes('inspectorReduxMiddleware')) {
|
|
124
|
+
bestFrame = parseStackLine(lines[i], false);
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
let originType = 'direct';
|
|
130
|
+
if (isSaga || (bestFrame && bestFrame.fileName?.toLowerCase().includes('saga'))) {
|
|
131
|
+
originType = 'saga';
|
|
132
|
+
}
|
|
133
|
+
else if (isThunk || (bestFrame && bestFrame.fileName?.toLowerCase().includes('thunk'))) {
|
|
134
|
+
originType = 'thunk';
|
|
135
|
+
}
|
|
136
|
+
else if (bestFrame &&
|
|
137
|
+
(bestFrame.fileName?.endsWith('.tsx') ||
|
|
138
|
+
bestFrame.functionName?.includes('onPress') ||
|
|
139
|
+
bestFrame.functionName?.includes('touchable') ||
|
|
140
|
+
bestFrame.functionName?.includes('Effect'))) {
|
|
141
|
+
originType = 'ui';
|
|
142
|
+
}
|
|
143
|
+
else if (stackLower.includes('listener') || stackLower.includes('subscribe')) {
|
|
144
|
+
originType = 'listener';
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
originType,
|
|
148
|
+
caller: bestFrame?.copyableLocation || bestFrame?.raw || undefined,
|
|
149
|
+
callerFile: bestFrame?.fullPath || bestFrame?.fileName || undefined,
|
|
150
|
+
callerLine: bestFrame?.lineNumber ? Number(bestFrame.lineNumber) : undefined,
|
|
151
|
+
callerCol: bestFrame?.columnNumber ? Number(bestFrame.columnNumber) : undefined,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function extractSliceName(actionType, affectedSlices) {
|
|
155
|
+
if (affectedSlices && affectedSlices.length > 0) {
|
|
156
|
+
return affectedSlices[0];
|
|
157
|
+
}
|
|
158
|
+
// If Redux Toolkit action format: e.g. "users/fetchById" -> "users"
|
|
159
|
+
const match = actionType.match(/^([a-zA-Z0-9_\-]+)\//);
|
|
160
|
+
if (match && match[1] && !match[1].startsWith('@@')) {
|
|
161
|
+
return match[1];
|
|
162
|
+
}
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
165
|
+
function recordAction(action, prevState, nextState, rawStack) {
|
|
166
|
+
const stack = rawStack || new Error().stack || '';
|
|
67
167
|
const type = actionTypeOf(action);
|
|
68
168
|
const payload = action && typeof action === 'object' && action.payload !== undefined
|
|
69
169
|
? action.payload
|
|
@@ -71,13 +171,26 @@ function recordAction(action, prevState, nextState) {
|
|
|
71
171
|
const now = Date.now();
|
|
72
172
|
const timestamp = new Date(now).toLocaleTimeString();
|
|
73
173
|
const affectedSlices = [];
|
|
174
|
+
const origin = detectActionOrigin(stack, type, action);
|
|
175
|
+
const sliceName = extractSliceName(type, affectedSlices);
|
|
74
176
|
if (prevState &&
|
|
75
177
|
nextState &&
|
|
76
178
|
typeof prevState === 'object' &&
|
|
77
179
|
typeof nextState === 'object') {
|
|
78
180
|
Object.keys(nextState).forEach(key => {
|
|
79
181
|
if (prevState[key] !== nextState[key]) {
|
|
80
|
-
lastActionForReducer[key] = {
|
|
182
|
+
lastActionForReducer[key] = {
|
|
183
|
+
type,
|
|
184
|
+
payload,
|
|
185
|
+
timestamp,
|
|
186
|
+
updatedAt: now,
|
|
187
|
+
originType: origin.originType,
|
|
188
|
+
callerFile: origin.callerFile,
|
|
189
|
+
callerLine: origin.callerLine,
|
|
190
|
+
callerCol: origin.callerCol,
|
|
191
|
+
caller: origin.caller,
|
|
192
|
+
stack,
|
|
193
|
+
};
|
|
81
194
|
affectedSlices.push(key);
|
|
82
195
|
}
|
|
83
196
|
});
|
|
@@ -91,6 +204,13 @@ function recordAction(action, prevState, nextState) {
|
|
|
91
204
|
affectedSlices,
|
|
92
205
|
prevState,
|
|
93
206
|
nextState,
|
|
207
|
+
stack,
|
|
208
|
+
caller: origin.caller,
|
|
209
|
+
callerFile: origin.callerFile,
|
|
210
|
+
callerLine: origin.callerLine,
|
|
211
|
+
callerCol: origin.callerCol,
|
|
212
|
+
originType: origin.originType,
|
|
213
|
+
sliceName,
|
|
94
214
|
});
|
|
95
215
|
if (actionHistory.length > MAX_HISTORY) {
|
|
96
216
|
actionHistory.length = MAX_HISTORY;
|
|
@@ -116,6 +236,7 @@ function recordAction(action, prevState, nextState) {
|
|
|
116
236
|
*/
|
|
117
237
|
export const inspectorReduxMiddleware = (storeApi) => (next) => (action) => {
|
|
118
238
|
middlewareAttached = true;
|
|
239
|
+
const capturedStack = new Error().stack || '';
|
|
119
240
|
// Thunks are functions — let them run; their inner plain-action dispatches
|
|
120
241
|
// pass back through this same middleware, so nothing is lost.
|
|
121
242
|
if (typeof action === 'function') {
|
|
@@ -126,7 +247,7 @@ export const inspectorReduxMiddleware = (storeApi) => (next) => (action) => {
|
|
|
126
247
|
const nextState = storeApi.getState();
|
|
127
248
|
if (currentReduxState == null)
|
|
128
249
|
currentReduxState = nextState;
|
|
129
|
-
recordAction(action, prevState, nextState);
|
|
250
|
+
recordAction(action, prevState, nextState, capturedStack);
|
|
130
251
|
return result;
|
|
131
252
|
};
|
|
132
253
|
export const connectReduxStore = (store) => {
|
|
@@ -148,6 +269,7 @@ export const connectReduxStore = (store) => {
|
|
|
148
269
|
const originalDispatch = store.dispatch.bind(store);
|
|
149
270
|
let inWrappedDispatch = false;
|
|
150
271
|
store.dispatch = (action) => {
|
|
272
|
+
const capturedStack = new Error().stack || '';
|
|
151
273
|
if (middlewareAttached || typeof action === 'function') {
|
|
152
274
|
// Middleware handles recording, or it's a thunk whose inner dispatches
|
|
153
275
|
// will be picked up individually.
|
|
@@ -168,7 +290,7 @@ export const connectReduxStore = (store) => {
|
|
|
168
290
|
finally {
|
|
169
291
|
inWrappedDispatch = false;
|
|
170
292
|
}
|
|
171
|
-
recordAction(action, prevState, store.getState());
|
|
293
|
+
recordAction(action, prevState, store.getState(), capturedStack);
|
|
172
294
|
return result;
|
|
173
295
|
};
|
|
174
296
|
setReduxState(store.getState());
|
|
@@ -192,6 +314,7 @@ export const connectReduxStore = (store) => {
|
|
|
192
314
|
}
|
|
193
315
|
// Change arrived outside the wrapped dispatch — record it so the
|
|
194
316
|
// timeline stays consistent, even without the original action type.
|
|
195
|
-
|
|
317
|
+
const subStack = new Error().stack || '';
|
|
318
|
+
recordAction({ type: '@@inspector/EXTERNAL_STATE_CHANGE' }, prevState, nextState, subStack);
|
|
196
319
|
});
|
|
197
320
|
};
|
|
@@ -53,7 +53,7 @@ export interface ParsedStackFrame {
|
|
|
53
53
|
}
|
|
54
54
|
/** Parses a stack trace line to extract function name, file name, extension (.tsx/.jsx/.ts), line, and column numbers */
|
|
55
55
|
export declare const parseStackLine: (rawLine: string, isOrigin?: boolean) => ParsedStackFrame;
|
|
56
|
-
/** Opens a file and line number directly in VS Code */
|
|
56
|
+
/** Opens a file and line number directly in VS Code / system editor */
|
|
57
57
|
export declare const openInVSCode: (filePath: string, lineNumber?: string | number, columnNumber?: string | number) => void;
|
|
58
58
|
export declare const ANALYTICS_EVENT_PALETTE: string[];
|
|
59
59
|
export declare const getEventColor: (name: string) => string;
|
|
@@ -540,28 +540,44 @@ export const parseStackLine = (rawLine, isOrigin = false) => {
|
|
|
540
540
|
copyableLocation,
|
|
541
541
|
};
|
|
542
542
|
};
|
|
543
|
-
/** Opens a file and line number directly in VS Code */
|
|
543
|
+
/** Opens a file and line number directly in VS Code / system editor */
|
|
544
544
|
export const openInVSCode = (filePath, lineNumber, columnNumber) => {
|
|
545
|
+
const numLine = lineNumber ? Number(lineNumber) : 1;
|
|
546
|
+
const numCol = columnNumber ? Number(columnNumber) : 1;
|
|
545
547
|
const line = lineNumber ? `:${lineNumber}` : '';
|
|
546
548
|
const col = columnNumber ? `:${columnNumber}` : '';
|
|
547
549
|
const cleanPath = filePath.replace(/^file:\/\//, '');
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
550
|
+
// 1. Notify Metro dev server on host to launch editor directly on local system
|
|
551
|
+
const metroHosts = [
|
|
552
|
+
'http://localhost:8081',
|
|
553
|
+
'http://127.0.0.1:8081',
|
|
554
|
+
'http://10.0.2.2:8081',
|
|
555
|
+
];
|
|
556
|
+
metroHosts.forEach(host => {
|
|
557
|
+
try {
|
|
558
|
+
fetch(`${host}/open-stack-frame`, {
|
|
559
|
+
method: 'POST',
|
|
560
|
+
headers: { 'Content-Type': 'application/json' },
|
|
561
|
+
body: JSON.stringify({
|
|
562
|
+
file: cleanPath,
|
|
563
|
+
lineNumber: numLine,
|
|
564
|
+
column: numCol,
|
|
565
|
+
}),
|
|
566
|
+
}).catch(() => { });
|
|
553
567
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
568
|
+
catch { }
|
|
569
|
+
});
|
|
570
|
+
// 2. Also invoke native URL scheme handlers
|
|
571
|
+
const vscodeUrl = `vscode://file/${cleanPath.replace(/^\/+/, '')}${line}${col}`;
|
|
572
|
+
const cursorUrl = `cursor://file/${cleanPath.replace(/^\/+/, '')}${line}${col}`;
|
|
573
|
+
const vscodeInsidersUrl = `vscode-insiders://file/${cleanPath.replace(/^\/+/, '')}${line}${col}`;
|
|
574
|
+
Linking.openURL(vscodeUrl).catch(() => {
|
|
575
|
+
Linking.openURL(cursorUrl).catch(() => {
|
|
576
|
+
Linking.openURL(vscodeInsidersUrl).catch(() => {
|
|
577
|
+
// Fallback: Copy to clipboard so user can jump immediately
|
|
578
|
+
copyToClipboard(`${cleanPath}${line}${col}`, 'Location');
|
|
560
579
|
});
|
|
561
|
-
}
|
|
562
|
-
})
|
|
563
|
-
.catch(() => {
|
|
564
|
-
Linking.openURL(vscodeUrl).catch(() => { });
|
|
580
|
+
});
|
|
565
581
|
});
|
|
566
582
|
};
|
|
567
583
|
// ─── Analytics Helpers ────────────────────────────────────────────────────────
|
|
@@ -282,7 +282,19 @@
|
|
|
282
282
|
"timeNow": "NOW",
|
|
283
283
|
"selectedBucket": "Bucket: {{time}} ({{count}} events)",
|
|
284
284
|
"totalRevenue": "Revenue",
|
|
285
|
-
"activeDistribution": "Category Split"
|
|
285
|
+
"activeDistribution": "Category Split",
|
|
286
|
+
"allCategory": "All",
|
|
287
|
+
"screensCategory": "Screens",
|
|
288
|
+
"overviewTab": "Overview",
|
|
289
|
+
"jsonTreeTab": "JSON Tree",
|
|
290
|
+
"rawPayloadTab": "Raw Payload",
|
|
291
|
+
"sessionContext": "Session Context",
|
|
292
|
+
"userPropertiesSnapshot": "User Properties Snapshot",
|
|
293
|
+
"parameterKeys": "Parameters ({{count}})",
|
|
294
|
+
"searchParameters": "Search parameters...",
|
|
295
|
+
"noParamsFound": "No parameters match your search",
|
|
296
|
+
"sourceFirebase": "FIREBASE GA4",
|
|
297
|
+
"sourceCustom": "CUSTOM / MANUAL"
|
|
286
298
|
},
|
|
287
299
|
"redux": {
|
|
288
300
|
"title": "Redux",
|
|
@@ -308,7 +320,38 @@
|
|
|
308
320
|
"connectionStatus": "Connected",
|
|
309
321
|
"connectionStatusNone": "Not connected",
|
|
310
322
|
"autoRefresh": "Auto-refresh",
|
|
311
|
-
"paused": "Paused"
|
|
323
|
+
"paused": "Paused",
|
|
324
|
+
"liveState": "Live State",
|
|
325
|
+
"timeline": "Timeline",
|
|
326
|
+
"persisted": "Persisted",
|
|
327
|
+
"storage": "Storage",
|
|
328
|
+
"metadata": "Metadata",
|
|
329
|
+
"inMemory": "In-Memory",
|
|
330
|
+
"slice": "SLICE",
|
|
331
|
+
"rootKeys": "Root Keys",
|
|
332
|
+
"size": "Size",
|
|
333
|
+
"actions": "actions",
|
|
334
|
+
"keys": "Keys",
|
|
335
|
+
"last": "Last",
|
|
336
|
+
"live": "Live",
|
|
337
|
+
"loading": "Loading",
|
|
338
|
+
"error": "Error",
|
|
339
|
+
"empty": "Empty",
|
|
340
|
+
"payload": "Payload",
|
|
341
|
+
"actionPayload": "Action Payload:",
|
|
342
|
+
"stateChangesDiff": "State Changes (Diff):",
|
|
343
|
+
"tapToInspectAction": "Tap to inspect action payload & diff changes",
|
|
344
|
+
"noDispatchedActions": "No dispatched actions recorded for this slice yet.",
|
|
345
|
+
"sliceJson": "Slice JSON",
|
|
346
|
+
"originSaga": "SAGA",
|
|
347
|
+
"originThunk": "THUNK",
|
|
348
|
+
"originUi": "UI",
|
|
349
|
+
"originDirect": "DIRECT",
|
|
350
|
+
"originListener": "LISTENER",
|
|
351
|
+
"triggeredFrom": "Triggered From:",
|
|
352
|
+
"openInEditor": "Open in Editor",
|
|
353
|
+
"callStack": "Call Stack Trace",
|
|
354
|
+
"sliceOrigin": "Slice / Origin"
|
|
312
355
|
},
|
|
313
356
|
"performance": {
|
|
314
357
|
"title": "Performance",
|
|
@@ -124,6 +124,9 @@ declare const LightColors: {
|
|
|
124
124
|
emerald700: string;
|
|
125
125
|
pink100: string;
|
|
126
126
|
sky100: string;
|
|
127
|
+
teal100: string;
|
|
128
|
+
teal700: string;
|
|
129
|
+
purple700: string;
|
|
127
130
|
indigo50: string;
|
|
128
131
|
gray100: string;
|
|
129
132
|
gray200: string;
|
|
@@ -279,6 +282,9 @@ export declare const getThemeColors: (isDark: boolean) => {
|
|
|
279
282
|
emerald700: string;
|
|
280
283
|
pink100: string;
|
|
281
284
|
sky100: string;
|
|
285
|
+
teal100: string;
|
|
286
|
+
teal700: string;
|
|
287
|
+
purple700: string;
|
|
282
288
|
indigo50: string;
|
|
283
289
|
gray100: string;
|
|
284
290
|
gray200: string;
|
|
@@ -130,6 +130,9 @@ const LightColors = {
|
|
|
130
130
|
emerald700: '#047857',
|
|
131
131
|
pink100: '#FCE7F3',
|
|
132
132
|
sky100: '#E0F2FE',
|
|
133
|
+
teal100: '#CCFBF1',
|
|
134
|
+
teal700: '#0F766E',
|
|
135
|
+
purple700: '#6D28D9',
|
|
133
136
|
indigo50: '#EEF2FF',
|
|
134
137
|
gray100: '#F3F4F6',
|
|
135
138
|
gray200: '#E5E7EB',
|
|
@@ -300,6 +303,9 @@ const DarkColors = {
|
|
|
300
303
|
emerald700: '#34D399',
|
|
301
304
|
pink100: '#341626',
|
|
302
305
|
sky100: '#0C2744',
|
|
306
|
+
teal100: '#134E4A',
|
|
307
|
+
teal700: '#2DD4BF',
|
|
308
|
+
purple700: '#8B5CF6',
|
|
303
309
|
indigo50: '#1E1B3A',
|
|
304
310
|
gray100: '#2A2438',
|
|
305
311
|
gray200: '#362C4E',
|
|
@@ -427,6 +427,12 @@ export declare const getRawStyles: (colors: typeof AppColors) => {
|
|
|
427
427
|
borderWidth: number;
|
|
428
428
|
borderColor: string;
|
|
429
429
|
};
|
|
430
|
+
domainHeaderCardExpanded: {
|
|
431
|
+
borderBottomLeftRadius: number;
|
|
432
|
+
borderBottomRightRadius: number;
|
|
433
|
+
borderBottomWidth: number;
|
|
434
|
+
marginBottom: number;
|
|
435
|
+
};
|
|
430
436
|
domainHeaderTopRow: {
|
|
431
437
|
flexDirection: string;
|
|
432
438
|
alignItems: string;
|
|
@@ -436,6 +442,8 @@ export declare const getRawStyles: (colors: typeof AppColors) => {
|
|
|
436
442
|
flexDirection: string;
|
|
437
443
|
alignItems: string;
|
|
438
444
|
flex: number;
|
|
445
|
+
minWidth: number;
|
|
446
|
+
marginRight: number;
|
|
439
447
|
gap: number;
|
|
440
448
|
};
|
|
441
449
|
domainIconWrap: {
|
|
@@ -502,6 +510,7 @@ export declare const getRawStyles: (colors: typeof AppColors) => {
|
|
|
502
510
|
domainStatsGroup: {
|
|
503
511
|
flexDirection: string;
|
|
504
512
|
alignItems: string;
|
|
513
|
+
flexShrink: number;
|
|
505
514
|
gap: number;
|
|
506
515
|
};
|
|
507
516
|
domainStatPill: {
|
|
@@ -522,8 +531,20 @@ export declare const getRawStyles: (colors: typeof AppColors) => {
|
|
|
522
531
|
treeNodeRow: {
|
|
523
532
|
flexDirection: string;
|
|
524
533
|
alignItems: string;
|
|
525
|
-
|
|
534
|
+
marginHorizontal: number;
|
|
526
535
|
paddingRight: number;
|
|
536
|
+
paddingLeft: number;
|
|
537
|
+
backgroundColor: string;
|
|
538
|
+
borderLeftWidth: number;
|
|
539
|
+
borderRightWidth: number;
|
|
540
|
+
borderColor: string;
|
|
541
|
+
};
|
|
542
|
+
treeNodeRowLast: {
|
|
543
|
+
borderBottomWidth: number;
|
|
544
|
+
borderBottomLeftRadius: number;
|
|
545
|
+
borderBottomRightRadius: number;
|
|
546
|
+
marginBottom: number;
|
|
547
|
+
paddingBottom: number;
|
|
527
548
|
};
|
|
528
549
|
treeLines: {
|
|
529
550
|
width: number;
|
package/dist/esm/styles/index.js
CHANGED
|
@@ -7,8 +7,8 @@ export const getRawStyles = (colors) => ({
|
|
|
7
7
|
header: {
|
|
8
8
|
flexDirection: 'row',
|
|
9
9
|
alignItems: 'center',
|
|
10
|
-
paddingHorizontal:
|
|
11
|
-
paddingVertical:
|
|
10
|
+
paddingHorizontal: 12,
|
|
11
|
+
paddingVertical: 10,
|
|
12
12
|
zIndex: 10,
|
|
13
13
|
minHeight: 56,
|
|
14
14
|
shadowColor: colors.black,
|
|
@@ -388,6 +388,12 @@ export const getRawStyles = (colors) => ({
|
|
|
388
388
|
borderWidth: 1,
|
|
389
389
|
borderColor: colors.grayBorderSecondary,
|
|
390
390
|
},
|
|
391
|
+
domainHeaderCardExpanded: {
|
|
392
|
+
borderBottomLeftRadius: 0,
|
|
393
|
+
borderBottomRightRadius: 0,
|
|
394
|
+
borderBottomWidth: 0,
|
|
395
|
+
marginBottom: 0,
|
|
396
|
+
},
|
|
391
397
|
domainHeaderTopRow: {
|
|
392
398
|
flexDirection: 'row',
|
|
393
399
|
alignItems: 'center',
|
|
@@ -397,6 +403,8 @@ export const getRawStyles = (colors) => ({
|
|
|
397
403
|
flexDirection: 'row',
|
|
398
404
|
alignItems: 'center',
|
|
399
405
|
flex: 1,
|
|
406
|
+
minWidth: 0,
|
|
407
|
+
marginRight: 6,
|
|
400
408
|
gap: 8,
|
|
401
409
|
},
|
|
402
410
|
domainIconWrap: {
|
|
@@ -463,6 +471,7 @@ export const getRawStyles = (colors) => ({
|
|
|
463
471
|
domainStatsGroup: {
|
|
464
472
|
flexDirection: 'row',
|
|
465
473
|
alignItems: 'center',
|
|
474
|
+
flexShrink: 0,
|
|
466
475
|
gap: 4,
|
|
467
476
|
},
|
|
468
477
|
domainStatPill: {
|
|
@@ -483,8 +492,20 @@ export const getRawStyles = (colors) => ({
|
|
|
483
492
|
treeNodeRow: {
|
|
484
493
|
flexDirection: 'row',
|
|
485
494
|
alignItems: 'stretch',
|
|
486
|
-
|
|
487
|
-
paddingRight:
|
|
495
|
+
marginHorizontal: 12,
|
|
496
|
+
paddingRight: 8,
|
|
497
|
+
paddingLeft: 4,
|
|
498
|
+
backgroundColor: colors.grayBackground,
|
|
499
|
+
borderLeftWidth: 1,
|
|
500
|
+
borderRightWidth: 1,
|
|
501
|
+
borderColor: colors.grayBorderSecondary,
|
|
502
|
+
},
|
|
503
|
+
treeNodeRowLast: {
|
|
504
|
+
borderBottomWidth: 1,
|
|
505
|
+
borderBottomLeftRadius: 10,
|
|
506
|
+
borderBottomRightRadius: 10,
|
|
507
|
+
marginBottom: 8,
|
|
508
|
+
paddingBottom: 6,
|
|
488
509
|
},
|
|
489
510
|
treeLines: {
|
|
490
511
|
width: 28,
|
|
@@ -119,6 +119,13 @@ export interface ReduxHistoryEntry {
|
|
|
119
119
|
affectedSlices: string[];
|
|
120
120
|
prevState?: any;
|
|
121
121
|
nextState?: any;
|
|
122
|
+
stack?: string;
|
|
123
|
+
caller?: string;
|
|
124
|
+
callerFile?: string;
|
|
125
|
+
callerLine?: number;
|
|
126
|
+
callerCol?: number;
|
|
127
|
+
originType?: 'saga' | 'thunk' | 'ui' | 'direct' | 'listener';
|
|
128
|
+
sliceName?: string;
|
|
122
129
|
}
|
|
123
130
|
export interface InspectorStorage {
|
|
124
131
|
getItem: (key: string) => string | null | Promise<string | null>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-inapp-inspector",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.32",
|
|
4
4
|
"description": "The zero-config, all-in-one in-app debugger for React Native & Expo. Inspect Network (fetch/axios), Console logs, Stack Traces, Redux State, Firebase Analytics, and JS Bundle size directly on device.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -90,19 +90,19 @@
|
|
|
90
90
|
}
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
93
|
-
"@react-navigation/native": "
|
|
94
|
-
"@types/react": "
|
|
95
|
-
"@types/react-native": "
|
|
96
|
-
"axios": "
|
|
97
|
-
"prettier": "
|
|
93
|
+
"@react-navigation/native": "6.1.9",
|
|
94
|
+
"@types/react": "19.1.0",
|
|
95
|
+
"@types/react-native": "0.72.0",
|
|
96
|
+
"axios": "1.7.2",
|
|
97
|
+
"prettier": "2.8.8",
|
|
98
98
|
"react": "19.1.0",
|
|
99
99
|
"react-native": "0.81.4",
|
|
100
|
-
"react-native-bundle-visualizer": "
|
|
101
|
-
"react-native-linear-gradient": "
|
|
102
|
-
"react-native-svg": "
|
|
103
|
-
"typescript": "
|
|
100
|
+
"react-native-bundle-visualizer": "4.0.0",
|
|
101
|
+
"react-native-linear-gradient": "2.8.3",
|
|
102
|
+
"react-native-svg": "15.14.0",
|
|
103
|
+
"typescript": "5.8.3"
|
|
104
104
|
},
|
|
105
105
|
"dependencies": {
|
|
106
|
-
"@react-native-clipboard/clipboard": "
|
|
106
|
+
"@react-native-clipboard/clipboard": "1.16.3"
|
|
107
107
|
}
|
|
108
108
|
}
|