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
@@ -463,16 +463,22 @@ exports.ForwardChevronIcon = ForwardChevronIcon;
463
463
  exports.BundleIcon = exports.PackageIcon;
464
464
  const LiveStateIcon = ({ color = AppColors_1.AppColors.purple, size = 14, }) => {
465
465
  return (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
466
- <react_native_svg_1.Path d="M12 3v3M12 18v3M3 12h3M18 12h3" stroke={color} strokeWidth="2" strokeLinecap="round"/>
467
- <react_native_svg_1.Circle cx="12" cy="12" r="3.5" stroke={color} strokeWidth="1.8" fill={`${color}22`}/>
468
- <react_native_svg_1.Circle cx="12" cy="12" r="1.5" fill={color}/>
466
+ <react_native_svg_1.Circle cx="12" cy="12" r="9" stroke={color} strokeWidth="1.8" strokeDasharray="3 3" opacity={0.6}/>
467
+ <react_native_svg_1.Circle cx="12" cy="12" r="4.5" stroke={color} strokeWidth="1.8"/>
468
+ <react_native_svg_1.Circle cx="12" cy="12" r="2" fill={color}/>
469
+ <react_native_svg_1.Path d="M12 2v2.5M12 19.5V22M2 12h2.5M19.5 12H22" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
469
470
  </react_native_svg_1.default>);
470
471
  };
471
472
  exports.LiveStateIcon = LiveStateIcon;
472
473
  const TimelineIcon = ({ color = AppColors_1.AppColors.purple, size = 14, }) => {
473
474
  return (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
474
- <react_native_svg_1.Circle cx="12" cy="12" r="8.5" stroke={color} strokeWidth="1.8"/>
475
- <react_native_svg_1.Path d="M12 7.5v4.5l3 2" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
475
+ <react_native_svg_1.Path d="M6 3v18" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
476
+ <react_native_svg_1.Circle cx="6" cy="6" r="2.5" stroke={color} strokeWidth="1.8" fill={`${color}25`}/>
477
+ <react_native_svg_1.Path d="M6 12h5a3 3 0 0 0 3-3V6" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
478
+ <react_native_svg_1.Circle cx="14" cy="6" r="2.5" stroke={color} strokeWidth="1.8" fill={color}/>
479
+ <react_native_svg_1.Circle cx="6" cy="18" r="2.5" stroke={color} strokeWidth="1.8" fill={color}/>
480
+ <react_native_svg_1.Path d="M6 18h8" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
481
+ <react_native_svg_1.Circle cx="17" cy="18" r="2.5" stroke={color} strokeWidth="1.8" fill={`${color}25`}/>
476
482
  </react_native_svg_1.default>);
477
483
  };
478
484
  exports.TimelineIcon = TimelineIcon;
@@ -484,16 +490,19 @@ const RefreshCcwIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 14,
484
490
  exports.RefreshCcwIcon = RefreshCcwIcon;
485
491
  const StorageIcon = ({ color = AppColors_1.AppColors.purple, size = 14, }) => {
486
492
  return (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
487
- <react_native_svg_1.Ellipse cx="12" cy="6" rx="8" ry="2.8" stroke={color} strokeWidth="1.8"/>
488
- <react_native_svg_1.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"/>
489
- <react_native_svg_1.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"/>
493
+ <react_native_svg_1.Ellipse cx="12" cy="5" rx="8" ry="2.5" stroke={color} strokeWidth="1.8"/>
494
+ <react_native_svg_1.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"/>
495
+ <react_native_svg_1.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"/>
496
+ <react_native_svg_1.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"/>
490
497
  </react_native_svg_1.default>);
491
498
  };
492
499
  exports.StorageIcon = StorageIcon;
493
500
  const MetadataIcon = ({ color = AppColors_1.AppColors.purple, size = 14, }) => {
494
501
  return (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
495
- <react_native_svg_1.Circle cx="12" cy="12" r="8.5" stroke={color} strokeWidth="1.8"/>
496
- <react_native_svg_1.Path d="M12 16v-4M12 8.2h.01" stroke={color} strokeWidth="2" strokeLinecap="round"/>
502
+ <react_native_svg_1.Rect x="3" y="3" width="18" height="18" rx="4" stroke={color} strokeWidth="1.8"/>
503
+ <react_native_svg_1.Path d="M7 8h10M7 12h6M7 16h7" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
504
+ <react_native_svg_1.Circle cx="16.5" cy="12" r="1.5" fill={color}/>
505
+ <react_native_svg_1.Circle cx="16.5" cy="16" r="1.5" fill={color}/>
497
506
  </react_native_svg_1.default>);
498
507
  };
499
508
  exports.MetadataIcon = MetadataIcon;
@@ -45,9 +45,19 @@ const NetworkIcons_1 = require("./NetworkIcons");
45
45
  // Stylesheet
46
46
  const AppColors_1 = require("../styles/AppColors");
47
47
  const styles_1 = __importDefault(require("../styles"));
48
- const TreeNode = react_1.default.memo(function TreeNode({ data, name, level = 0, search, forceOpen, defaultExpandDepth, }) {
49
- const [localOpen, setLocalOpen] = (0, react_1.useState)(forceOpen || (defaultExpandDepth !== undefined ? level < defaultExpandDepth : false));
48
+ const TreeNode = react_1.default.memo(function TreeNode({ data, name, level = 0, search, forceOpen, defaultExpandDepth = 1, }) {
49
+ const [localOpen, setLocalOpen] = (0, react_1.useState)(() => {
50
+ if (forceOpen !== undefined) {
51
+ return forceOpen;
52
+ }
53
+ return defaultExpandDepth !== undefined ? level < defaultExpandDepth : level < 1;
54
+ });
50
55
  const open = localOpen;
56
+ (0, react_1.useEffect)(() => {
57
+ if (forceOpen !== undefined) {
58
+ setLocalOpen(forceOpen);
59
+ }
60
+ }, [forceOpen]);
51
61
  const isObject = typeof data === 'object' && data !== null;
52
62
  const isArray = Array.isArray(data);
53
63
  // 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";
@@ -3,4 +3,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LIB_VERSION = void 0;
4
4
  // AUTO-GENERATED FILE — do not edit by hand.
5
5
  // Regenerated from package.json on every build by scripts/gen-version.js.
6
- exports.LIB_VERSION = '1.1.29';
6
+ exports.LIB_VERSION = '1.1.32';
@@ -14,6 +14,7 @@
14
14
  // and per-reducer "last action" consistently.
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.connectReduxStore = exports.inspectorReduxMiddleware = exports.subscribeReduxState = exports.setReduxState = exports.clearActionHistory = exports.getActionHistory = exports.clearLastActionForReducer = exports.getLastActionForReducer = exports.getReduxAutoRefresh = exports.setReduxAutoRefresh = exports.getReduxState = exports.isReduxConnected = void 0;
17
+ const helpers_1 = require("../helpers");
17
18
  let currentReduxState = null;
18
19
  const listeners = new Set();
19
20
  let globalReduxAutoRefresh = true;
@@ -76,7 +77,106 @@ function actionTypeOf(action) {
76
77
  }
77
78
  return 'UNKNOWN_ACTION';
78
79
  }
79
- function recordAction(action, prevState, nextState) {
80
+ function detectActionOrigin(stack, actionType, actionObj) {
81
+ const stackLower = (stack || '').toLowerCase();
82
+ const typeLower = (actionType || '').toLowerCase();
83
+ // Explicit hint on action if developer tagged it
84
+ if (actionObj && actionObj.__origin) {
85
+ const raw = String(actionObj.__origin).toLowerCase();
86
+ if (raw.includes('saga'))
87
+ return { originType: 'saga' };
88
+ if (raw.includes('thunk'))
89
+ return { originType: 'thunk' };
90
+ if (raw.includes('ui'))
91
+ return { originType: 'ui' };
92
+ }
93
+ // 1. Saga Detection (Stack + Action naming conventions)
94
+ const isSaga = stackLower.includes('redux-saga') ||
95
+ stackLower.includes('runputeffect') ||
96
+ stackLower.includes('proc.js') ||
97
+ stackLower.includes('effects.js') ||
98
+ stackLower.includes('sagamiddleware') ||
99
+ stackLower.includes('saga.ts') ||
100
+ stackLower.includes('saga.js') ||
101
+ stackLower.includes('sagas') ||
102
+ typeLower.includes('saga') ||
103
+ typeLower.startsWith('saga/') ||
104
+ typeLower.startsWith('@saga/');
105
+ // 2. Thunk / RTK Query Detection
106
+ const isThunk = stackLower.includes('createasyncthunk') ||
107
+ stackLower.includes('redux-thunk') ||
108
+ stackLower.includes('rtk-query') ||
109
+ stackLower.includes('thunkmiddleware') ||
110
+ stackLower.includes('actioncreator') ||
111
+ typeLower.includes('thunk') ||
112
+ typeLower.endsWith('/pending') ||
113
+ typeLower.endsWith('/fulfilled') ||
114
+ typeLower.endsWith('/rejected');
115
+ // 3. Parse Stack Frames to find best application caller
116
+ const lines = (stack || '').split('\n').map(l => l.trim()).filter(Boolean);
117
+ let bestFrame = null;
118
+ for (let i = 0; i < lines.length; i++) {
119
+ const line = lines[i];
120
+ // Ignore logger / middleware lines inside inspector
121
+ if (line.includes('reduxLogger') ||
122
+ line.includes('inspectorReduxMiddleware') ||
123
+ line.includes('recordAction') ||
124
+ line.includes('redux.js') ||
125
+ line.includes('redux.cjs')) {
126
+ continue;
127
+ }
128
+ const parsed = (0, helpers_1.parseStackLine)(line, false);
129
+ if (parsed.frameType === 'app' || (!parsed.isRuntimeNoise && parsed.fileName !== 'Unknown')) {
130
+ bestFrame = parsed;
131
+ break;
132
+ }
133
+ }
134
+ if (!bestFrame && lines.length > 0) {
135
+ for (let i = 0; i < lines.length; i++) {
136
+ if (!lines[i].includes('reduxLogger') && !lines[i].includes('inspectorReduxMiddleware')) {
137
+ bestFrame = (0, helpers_1.parseStackLine)(lines[i], false);
138
+ break;
139
+ }
140
+ }
141
+ }
142
+ let originType = 'direct';
143
+ if (isSaga || (bestFrame && bestFrame.fileName?.toLowerCase().includes('saga'))) {
144
+ originType = 'saga';
145
+ }
146
+ else if (isThunk || (bestFrame && bestFrame.fileName?.toLowerCase().includes('thunk'))) {
147
+ originType = 'thunk';
148
+ }
149
+ else if (bestFrame &&
150
+ (bestFrame.fileName?.endsWith('.tsx') ||
151
+ bestFrame.functionName?.includes('onPress') ||
152
+ bestFrame.functionName?.includes('touchable') ||
153
+ bestFrame.functionName?.includes('Effect'))) {
154
+ originType = 'ui';
155
+ }
156
+ else if (stackLower.includes('listener') || stackLower.includes('subscribe')) {
157
+ originType = 'listener';
158
+ }
159
+ return {
160
+ originType,
161
+ caller: bestFrame?.copyableLocation || bestFrame?.raw || undefined,
162
+ callerFile: bestFrame?.fullPath || bestFrame?.fileName || undefined,
163
+ callerLine: bestFrame?.lineNumber ? Number(bestFrame.lineNumber) : undefined,
164
+ callerCol: bestFrame?.columnNumber ? Number(bestFrame.columnNumber) : undefined,
165
+ };
166
+ }
167
+ function extractSliceName(actionType, affectedSlices) {
168
+ if (affectedSlices && affectedSlices.length > 0) {
169
+ return affectedSlices[0];
170
+ }
171
+ // If Redux Toolkit action format: e.g. "users/fetchById" -> "users"
172
+ const match = actionType.match(/^([a-zA-Z0-9_\-]+)\//);
173
+ if (match && match[1] && !match[1].startsWith('@@')) {
174
+ return match[1];
175
+ }
176
+ return undefined;
177
+ }
178
+ function recordAction(action, prevState, nextState, rawStack) {
179
+ const stack = rawStack || new Error().stack || '';
80
180
  const type = actionTypeOf(action);
81
181
  const payload = action && typeof action === 'object' && action.payload !== undefined
82
182
  ? action.payload
@@ -84,13 +184,26 @@ function recordAction(action, prevState, nextState) {
84
184
  const now = Date.now();
85
185
  const timestamp = new Date(now).toLocaleTimeString();
86
186
  const affectedSlices = [];
187
+ const origin = detectActionOrigin(stack, type, action);
188
+ const sliceName = extractSliceName(type, affectedSlices);
87
189
  if (prevState &&
88
190
  nextState &&
89
191
  typeof prevState === 'object' &&
90
192
  typeof nextState === 'object') {
91
193
  Object.keys(nextState).forEach(key => {
92
194
  if (prevState[key] !== nextState[key]) {
93
- lastActionForReducer[key] = { type, payload, timestamp, updatedAt: now };
195
+ lastActionForReducer[key] = {
196
+ type,
197
+ payload,
198
+ timestamp,
199
+ updatedAt: now,
200
+ originType: origin.originType,
201
+ callerFile: origin.callerFile,
202
+ callerLine: origin.callerLine,
203
+ callerCol: origin.callerCol,
204
+ caller: origin.caller,
205
+ stack,
206
+ };
94
207
  affectedSlices.push(key);
95
208
  }
96
209
  });
@@ -104,6 +217,13 @@ function recordAction(action, prevState, nextState) {
104
217
  affectedSlices,
105
218
  prevState,
106
219
  nextState,
220
+ stack,
221
+ caller: origin.caller,
222
+ callerFile: origin.callerFile,
223
+ callerLine: origin.callerLine,
224
+ callerCol: origin.callerCol,
225
+ originType: origin.originType,
226
+ sliceName,
107
227
  });
108
228
  if (actionHistory.length > MAX_HISTORY) {
109
229
  actionHistory.length = MAX_HISTORY;
@@ -129,6 +249,7 @@ function recordAction(action, prevState, nextState) {
129
249
  */
130
250
  const inspectorReduxMiddleware = (storeApi) => (next) => (action) => {
131
251
  middlewareAttached = true;
252
+ const capturedStack = new Error().stack || '';
132
253
  // Thunks are functions — let them run; their inner plain-action dispatches
133
254
  // pass back through this same middleware, so nothing is lost.
134
255
  if (typeof action === 'function') {
@@ -139,7 +260,7 @@ const inspectorReduxMiddleware = (storeApi) => (next) => (action) => {
139
260
  const nextState = storeApi.getState();
140
261
  if (currentReduxState == null)
141
262
  currentReduxState = nextState;
142
- recordAction(action, prevState, nextState);
263
+ recordAction(action, prevState, nextState, capturedStack);
143
264
  return result;
144
265
  };
145
266
  exports.inspectorReduxMiddleware = inspectorReduxMiddleware;
@@ -162,6 +283,7 @@ const connectReduxStore = (store) => {
162
283
  const originalDispatch = store.dispatch.bind(store);
163
284
  let inWrappedDispatch = false;
164
285
  store.dispatch = (action) => {
286
+ const capturedStack = new Error().stack || '';
165
287
  if (middlewareAttached || typeof action === 'function') {
166
288
  // Middleware handles recording, or it's a thunk whose inner dispatches
167
289
  // will be picked up individually.
@@ -182,7 +304,7 @@ const connectReduxStore = (store) => {
182
304
  finally {
183
305
  inWrappedDispatch = false;
184
306
  }
185
- recordAction(action, prevState, store.getState());
307
+ recordAction(action, prevState, store.getState(), capturedStack);
186
308
  return result;
187
309
  };
188
310
  (0, exports.setReduxState)(store.getState());
@@ -206,7 +328,8 @@ const connectReduxStore = (store) => {
206
328
  }
207
329
  // Change arrived outside the wrapped dispatch — record it so the
208
330
  // timeline stays consistent, even without the original action type.
209
- recordAction({ type: '@@inspector/EXTERNAL_STATE_CHANGE' }, prevState, nextState);
331
+ const subStack = new Error().stack || '';
332
+ recordAction({ type: '@@inspector/EXTERNAL_STATE_CHANGE' }, prevState, nextState, subStack);
210
333
  });
211
334
  };
212
335
  exports.connectReduxStore = connectReduxStore;
@@ -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;
@@ -576,28 +576,44 @@ const parseStackLine = (rawLine, isOrigin = false) => {
576
576
  };
577
577
  };
578
578
  exports.parseStackLine = parseStackLine;
579
- /** Opens a file and line number directly in VS Code */
579
+ /** Opens a file and line number directly in VS Code / system editor */
580
580
  const openInVSCode = (filePath, lineNumber, columnNumber) => {
581
+ const numLine = lineNumber ? Number(lineNumber) : 1;
582
+ const numCol = columnNumber ? Number(columnNumber) : 1;
581
583
  const line = lineNumber ? `:${lineNumber}` : '';
582
584
  const col = columnNumber ? `:${columnNumber}` : '';
583
585
  const cleanPath = filePath.replace(/^file:\/\//, '');
584
- const vscodeUrl = `vscode://file/${cleanPath.replace(/^\/+/, '')}${line}${col}`;
585
- react_native_1.Linking.canOpenURL(vscodeUrl)
586
- .then(supported => {
587
- if (supported) {
588
- react_native_1.Linking.openURL(vscodeUrl);
586
+ // 1. Notify Metro dev server on host to launch editor directly on local system
587
+ const metroHosts = [
588
+ 'http://localhost:8081',
589
+ 'http://127.0.0.1:8081',
590
+ 'http://10.0.2.2:8081',
591
+ ];
592
+ metroHosts.forEach(host => {
593
+ try {
594
+ fetch(`${host}/open-stack-frame`, {
595
+ method: 'POST',
596
+ headers: { 'Content-Type': 'application/json' },
597
+ body: JSON.stringify({
598
+ file: cleanPath,
599
+ lineNumber: numLine,
600
+ column: numCol,
601
+ }),
602
+ }).catch(() => { });
589
603
  }
590
- else {
591
- react_native_1.Linking.openURL(vscodeUrl).catch(() => {
592
- const insidersUrl = `vscode-insiders://file/${cleanPath.replace(/^\/+/, '')}${line}${col}`;
593
- react_native_1.Linking.openURL(insidersUrl).catch(() => {
594
- react_native_1.Alert.alert('Open in VS Code', `Target location:\n${cleanPath}${line}${col}\n\nPlease ensure VS Code is installed.`, [{ text: 'OK' }]);
595
- });
604
+ catch { }
605
+ });
606
+ // 2. Also invoke native URL scheme handlers
607
+ const vscodeUrl = `vscode://file/${cleanPath.replace(/^\/+/, '')}${line}${col}`;
608
+ const cursorUrl = `cursor://file/${cleanPath.replace(/^\/+/, '')}${line}${col}`;
609
+ const vscodeInsidersUrl = `vscode-insiders://file/${cleanPath.replace(/^\/+/, '')}${line}${col}`;
610
+ react_native_1.Linking.openURL(vscodeUrl).catch(() => {
611
+ react_native_1.Linking.openURL(cursorUrl).catch(() => {
612
+ react_native_1.Linking.openURL(vscodeInsidersUrl).catch(() => {
613
+ // Fallback: Copy to clipboard so user can jump immediately
614
+ (0, exports.copyToClipboard)(`${cleanPath}${line}${col}`, 'Location');
596
615
  });
597
- }
598
- })
599
- .catch(() => {
600
- react_native_1.Linking.openURL(vscodeUrl).catch(() => { });
616
+ });
601
617
  });
602
618
  };
603
619
  exports.openInVSCode = openInVSCode;
@@ -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;
@@ -133,6 +133,9 @@ const LightColors = {
133
133
  emerald700: '#047857',
134
134
  pink100: '#FCE7F3',
135
135
  sky100: '#E0F2FE',
136
+ teal100: '#CCFBF1',
137
+ teal700: '#0F766E',
138
+ purple700: '#6D28D9',
136
139
  indigo50: '#EEF2FF',
137
140
  gray100: '#F3F4F6',
138
141
  gray200: '#E5E7EB',
@@ -303,6 +306,9 @@ const DarkColors = {
303
306
  emerald700: '#34D399',
304
307
  pink100: '#341626',
305
308
  sky100: '#0C2744',
309
+ teal100: '#134E4A',
310
+ teal700: '#2DD4BF',
311
+ purple700: '#8B5CF6',
306
312
  indigo50: '#1E1B3A',
307
313
  gray100: '#2A2438',
308
314
  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;
@@ -43,8 +43,8 @@ const getRawStyles = (colors) => ({
43
43
  header: {
44
44
  flexDirection: 'row',
45
45
  alignItems: 'center',
46
- paddingHorizontal: 10,
47
- paddingVertical: 8,
46
+ paddingHorizontal: 12,
47
+ paddingVertical: 10,
48
48
  zIndex: 10,
49
49
  minHeight: 56,
50
50
  shadowColor: colors.black,
@@ -424,6 +424,12 @@ const getRawStyles = (colors) => ({
424
424
  borderWidth: 1,
425
425
  borderColor: colors.grayBorderSecondary,
426
426
  },
427
+ domainHeaderCardExpanded: {
428
+ borderBottomLeftRadius: 0,
429
+ borderBottomRightRadius: 0,
430
+ borderBottomWidth: 0,
431
+ marginBottom: 0,
432
+ },
427
433
  domainHeaderTopRow: {
428
434
  flexDirection: 'row',
429
435
  alignItems: 'center',
@@ -433,6 +439,8 @@ const getRawStyles = (colors) => ({
433
439
  flexDirection: 'row',
434
440
  alignItems: 'center',
435
441
  flex: 1,
442
+ minWidth: 0,
443
+ marginRight: 6,
436
444
  gap: 8,
437
445
  },
438
446
  domainIconWrap: {
@@ -499,6 +507,7 @@ const getRawStyles = (colors) => ({
499
507
  domainStatsGroup: {
500
508
  flexDirection: 'row',
501
509
  alignItems: 'center',
510
+ flexShrink: 0,
502
511
  gap: 4,
503
512
  },
504
513
  domainStatPill: {
@@ -519,8 +528,20 @@ const getRawStyles = (colors) => ({
519
528
  treeNodeRow: {
520
529
  flexDirection: 'row',
521
530
  alignItems: 'stretch',
522
- paddingLeft: 12,
523
- paddingRight: 12,
531
+ marginHorizontal: 12,
532
+ paddingRight: 8,
533
+ paddingLeft: 4,
534
+ backgroundColor: colors.grayBackground,
535
+ borderLeftWidth: 1,
536
+ borderRightWidth: 1,
537
+ borderColor: colors.grayBorderSecondary,
538
+ },
539
+ treeNodeRowLast: {
540
+ borderBottomWidth: 1,
541
+ borderBottomLeftRadius: 10,
542
+ borderBottomRightRadius: 10,
543
+ marginBottom: 8,
544
+ paddingBottom: 6,
524
545
  },
525
546
  treeLines: {
526
547
  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>;