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.
Files changed (51) hide show
  1. package/dist/commonjs/components/AnalyticsDetail.js +668 -108
  2. package/dist/commonjs/components/AppHeaderLogo.js +5 -2
  3. package/dist/commonjs/components/ConsoleLogCard.js +81 -59
  4. package/dist/commonjs/components/DomainHeader.js +21 -17
  5. package/dist/commonjs/components/Inspector/AnalyticsTab.js +297 -200
  6. package/dist/commonjs/components/Inspector/ConsoleTab.js +162 -56
  7. package/dist/commonjs/components/Inspector/InspectorHeader.js +56 -119
  8. package/dist/commonjs/components/Inspector/LogDetail.js +45 -12
  9. package/dist/commonjs/components/Inspector/NetworkTab.js +4 -1
  10. package/dist/commonjs/components/Inspector/ReduxDetail.js +237 -42
  11. package/dist/commonjs/components/Inspector/ReduxTab.js +456 -35
  12. package/dist/commonjs/components/JsonViewer.js +1 -1
  13. package/dist/commonjs/components/NetworkIcons.js +19 -10
  14. package/dist/commonjs/components/TreeNode.js +12 -2
  15. package/dist/commonjs/constants/version.d.ts +1 -1
  16. package/dist/commonjs/constants/version.js +1 -1
  17. package/dist/commonjs/customHooks/reduxLogger.js +128 -5
  18. package/dist/commonjs/helpers/index.d.ts +1 -1
  19. package/dist/commonjs/helpers/index.js +32 -16
  20. package/dist/commonjs/i18n/locales/en.json +45 -2
  21. package/dist/commonjs/styles/AppColors.d.ts +6 -0
  22. package/dist/commonjs/styles/AppColors.js +6 -0
  23. package/dist/commonjs/styles/index.d.ts +22 -1
  24. package/dist/commonjs/styles/index.js +25 -4
  25. package/dist/commonjs/types/interfaces.d.ts +7 -0
  26. package/dist/esm/components/AnalyticsDetail.js +670 -110
  27. package/dist/esm/components/AppHeaderLogo.js +5 -2
  28. package/dist/esm/components/ConsoleLogCard.js +81 -59
  29. package/dist/esm/components/DomainHeader.js +21 -17
  30. package/dist/esm/components/Inspector/AnalyticsTab.js +298 -201
  31. package/dist/esm/components/Inspector/ConsoleTab.js +163 -57
  32. package/dist/esm/components/Inspector/InspectorHeader.js +57 -120
  33. package/dist/esm/components/Inspector/LogDetail.js +45 -12
  34. package/dist/esm/components/Inspector/NetworkTab.js +4 -1
  35. package/dist/esm/components/Inspector/ReduxDetail.js +239 -44
  36. package/dist/esm/components/Inspector/ReduxTab.js +458 -37
  37. package/dist/esm/components/JsonViewer.js +1 -1
  38. package/dist/esm/components/NetworkIcons.js +19 -10
  39. package/dist/esm/components/TreeNode.js +12 -2
  40. package/dist/esm/constants/version.d.ts +1 -1
  41. package/dist/esm/constants/version.js +1 -1
  42. package/dist/esm/customHooks/reduxLogger.js +128 -5
  43. package/dist/esm/helpers/index.d.ts +1 -1
  44. package/dist/esm/helpers/index.js +32 -16
  45. package/dist/esm/i18n/locales/en.json +45 -2
  46. package/dist/esm/styles/AppColors.d.ts +6 -0
  47. package/dist/esm/styles/AppColors.js +6 -0
  48. package/dist/esm/styles/index.d.ts +22 -1
  49. package/dist/esm/styles/index.js +25 -4
  50. package/dist/esm/types/interfaces.d.ts +7 -0
  51. 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
- <Path d="M12 3v3M12 18v3M3 12h3M18 12h3" stroke={color} strokeWidth="2" strokeLinecap="round"/>
366
- <Circle cx="12" cy="12" r="3.5" stroke={color} strokeWidth="1.8" fill={`${color}22`}/>
367
- <Circle cx="12" cy="12" r="1.5" fill={color}/>
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
- <Circle cx="12" cy="12" r="8.5" stroke={color} strokeWidth="1.8"/>
373
- <Path d="M12 7.5v4.5l3 2" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
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="6" rx="8" ry="2.8" stroke={color} strokeWidth="1.8"/>
384
- <Path d="M20 12c0 1.55-3.58 2.8-8 2.8s-8-1.25-8-2.8" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
385
- <Path d="M4 6v12c0 1.55 3.58 2.8 8 2.8s8-1.25 8-2.8V6" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
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
- <Circle cx="12" cy="12" r="8.5" stroke={color} strokeWidth="1.8"/>
391
- <Path d="M12 16v-4M12 8.2h.01" stroke={color} strokeWidth="2" strokeLinecap="round"/>
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(forceOpen || (defaultExpandDepth !== undefined ? level < defaultExpandDepth : false));
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.29";
1
+ export declare const LIB_VERSION = "1.1.32";
@@ -1,3 +1,3 @@
1
1
  // AUTO-GENERATED FILE — do not edit by hand.
2
2
  // Regenerated from package.json on every build by scripts/gen-version.js.
3
- export const LIB_VERSION = '1.1.29';
3
+ export 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 recordAction(action, prevState, nextState) {
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] = { type, payload, timestamp, updatedAt: now };
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
- recordAction({ type: '@@inspector/EXTERNAL_STATE_CHANGE' }, prevState, nextState);
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
- const vscodeUrl = `vscode://file/${cleanPath.replace(/^\/+/, '')}${line}${col}`;
549
- Linking.canOpenURL(vscodeUrl)
550
- .then(supported => {
551
- if (supported) {
552
- Linking.openURL(vscodeUrl);
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
- else {
555
- Linking.openURL(vscodeUrl).catch(() => {
556
- const insidersUrl = `vscode-insiders://file/${cleanPath.replace(/^\/+/, '')}${line}${col}`;
557
- Linking.openURL(insidersUrl).catch(() => {
558
- Alert.alert('Open in VS Code', `Target location:\n${cleanPath}${line}${col}\n\nPlease ensure VS Code is installed.`, [{ text: 'OK' }]);
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
- paddingLeft: number;
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;
@@ -7,8 +7,8 @@ export const getRawStyles = (colors) => ({
7
7
  header: {
8
8
  flexDirection: 'row',
9
9
  alignItems: 'center',
10
- paddingHorizontal: 10,
11
- paddingVertical: 8,
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
- paddingLeft: 12,
487
- paddingRight: 12,
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.29",
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": "^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",
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": "^4.0.0",
101
- "react-native-linear-gradient": "^2.8.3",
102
- "react-native-svg": "^15.14.0",
103
- "typescript": "^5.8.3"
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": "^1.16.3"
106
+ "@react-native-clipboard/clipboard": "1.16.3"
107
107
  }
108
108
  }