react-native-inapp-inspector 2.0.6 → 2.0.7

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.
@@ -18,13 +18,13 @@ import { isReduxConnected } from '../../customHooks/reduxLogger';
18
18
  import { isAnalyticsConnected } from '../../customHooks/analyticsLogger';
19
19
  import { useTranslation } from '../../i18n';
20
20
  import { getTelemetryConsentStatus, setTelemetryConsent, sendSessionTelemetryPing, } from '../../helpers/telemetry';
21
- import { SignalIcon, TerminalIcon, AnalyticsIcon, SettingsIcon, SunIcon, MoonIcon, ScreenIcon, MotionIcon, LayersIcon, EyeIcon, CheckIcon, TrashIcon, PackageIcon, ReduxIcon, PerformanceIcon, CrashIcon, ShieldAlertIcon, ForwardChevronIcon, ChevronDownIcon, NpmIcon, DatabaseIcon, DevicePhoneIcon, ShieldCheckIcon, CpuIcon, } from '../NetworkIcons';
21
+ import { SignalIcon, TerminalIcon, AnalyticsIcon, SettingsIcon, GlobeIcon, SunIcon, MoonIcon, ScreenIcon, MotionIcon, LayersIcon, EyeIcon, CheckIcon, TrashIcon, PackageIcon, ReduxIcon, PerformanceIcon, CrashIcon, ShieldAlertIcon, ForwardChevronIcon, ChevronDownIcon, NpmIcon, DatabaseIcon, DevicePhoneIcon, ShieldCheckIcon, CpuIcon, } from '../NetworkIcons';
22
22
  import { LIB_VERSION } from '../../constants';
23
23
  import { copyToClipboard } from '../../helpers';
24
24
  import { showToast } from '../../helpers/toast';
25
25
  const SettingsPanel = () => {
26
26
  const { t } = useTranslation();
27
- const { settingsPage, setSettingsPage, settingsActiveSubTab, setSettingsActiveSubTab, tabVisibility, toggleTabVisibility, defaultTab, setDefaultTab, isDark, setIsDark, modalHeightPercent, setModalHeightPercent, modalAnimationType, setModalAnimationType, showDuplicateLogs, setShowDuplicateLogs, showUpdateToast, setShowUpdateToast, showConsoleLevels, setShowConsoleLevels, resetToDefaults, storage, logs, consoleLogs, analyticsEvents, reduxState, maxNetworkLogs, setMaxNetworkLogs, maxConsoleLogs, setMaxConsoleLogs, maxAnalyticsEventsLimit, setMaxAnalyticsEventsLimit, isAutoRamLimitEnabled, setIsAutoRamLimitEnabled, deviceFreeRamMb, isPerformanceHudEnabled, setIsPerformanceHudEnabled, reduxAutoRefresh, setReduxAutoRefreshState, reduxExpandDepth, setReduxExpandDepth, switchActiveTab, setSelected, setSelectedEvent, setReduxState, crashRecords, maxCrashLogs, setMaxCrashLogs, updateAvailable, latestNpmVersion, } = useInspector();
27
+ const { settingsPage, setSettingsPage, settingsActiveSubTab, setSettingsActiveSubTab, tabVisibility, toggleTabVisibility, defaultTab, setDefaultTab, isDark, setIsDark, modalHeightPercent, setModalHeightPercent, modalAnimationType, setModalAnimationType, showDuplicateLogs, setShowDuplicateLogs, showUpdateToast, setShowUpdateToast, showConsoleLevels, setShowConsoleLevels, resetToDefaults, storage, logs, consoleLogs, analyticsEvents, reduxState, maxNetworkLogs, setMaxNetworkLogs, maxConsoleLogs, setMaxConsoleLogs, maxAnalyticsEventsLimit, setMaxAnalyticsEventsLimit, isAutoRamLimitEnabled, setIsAutoRamLimitEnabled, deviceFreeRamMb, isPerformanceHudEnabled, setIsPerformanceHudEnabled, reduxAutoRefresh, setReduxAutoRefreshState, reduxExpandDepth, setReduxExpandDepth, switchActiveTab, setSelected, setSelectedEvent, setReduxState, crashRecords, maxCrashLogs, setMaxCrashLogs, updateAvailable, latestNpmVersion, openWalkthrough, deviceInfo, auditReport, storageEntries, } = useInspector();
28
28
  const [stagedHeight, setStagedHeight] = useState(modalHeightPercent);
29
29
  const [telemetryConsent, setTelemetryConsentState] = useState(true);
30
30
  useEffect(() => {
@@ -424,17 +424,23 @@ const SettingsPanel = () => {
424
424
  ? `${logs.length} requests • Limit: ${maxNetworkLogs}`
425
425
  : moduleItem.key === 'logs'
426
426
  ? `${consoleLogs.length} logs • Limit: ${maxConsoleLogs}`
427
- : moduleItem.key === 'performance'
428
- ? '60 FPS TargetMemory Telemetry'
429
- : moduleItem.key === 'bundle'
430
- ? 'Metro Packager Dependency Map'
431
- : moduleItem.key === 'crash'
432
- ? `${crashRecords?.length || 0} crashes recorded Crash Guard`
433
- : moduleItem.key === 'analytics'
434
- ? `${analyticsEvents.length} events logged`
435
- : moduleItem.key === 'redux'
436
- ? `${Object.keys(reduxState || {}).length} slices Depth: ${reduxExpandDepth}`
437
- : '';
427
+ : moduleItem.key === 'storage'
428
+ ? `${storageEntries?.length || 0} keys AsyncStorage/MMKV`
429
+ : moduleItem.key === 'device'
430
+ ? `${deviceInfo?.platform ? deviceInfo.platform.toUpperCase() : 'Device'}Hermes ${deviceInfo?.isHermes ? 'Enabled' : 'Off'}`
431
+ : moduleItem.key === 'audit'
432
+ ? `${auditReport?.score != null ? `${auditReport.score}/100 ScoreQuality Audit` : 'Package & Health Audit'}`
433
+ : moduleItem.key === 'performance'
434
+ ? '60 FPS Target • Memory Telemetry'
435
+ : moduleItem.key === 'bundle'
436
+ ? 'Metro PackagerDependency Map'
437
+ : moduleItem.key === 'crash'
438
+ ? `${crashRecords?.length || 0} crashes recorded • Crash Guard`
439
+ : moduleItem.key === 'analytics'
440
+ ? `${analyticsEvents.length} events logged`
441
+ : moduleItem.key === 'redux'
442
+ ? `${Object.keys(reduxState || {}).length} slices • Depth: ${reduxExpandDepth}`
443
+ : '';
438
444
  return (<View key={moduleItem.key} style={{
439
445
  backgroundColor: AppColors.primaryLight,
440
446
  borderRadius: 14,
@@ -703,29 +709,29 @@ const SettingsPanel = () => {
703
709
  borderTopColor: AppColors.dividerColor,
704
710
  }}>
705
711
  {/* Live Info Pill */}
706
- <View style={{
707
- flexDirection: 'row',
708
- alignItems: 'center',
709
- gap: 6,
710
- flex: 1,
711
- }}>
712
- <View style={{
713
- width: 6,
714
- height: 6,
715
- borderRadius: 3,
716
- backgroundColor: isChecked
717
- ? AppColors.liveGreen
718
- : AppColors.grayTextWeak,
719
- }}/>
720
- <Text style={{
721
- fontFamily: AppFonts.interMedium,
722
- fontSize: 11,
723
- color: AppColors.grayText,
724
- lineHeight: 14,
725
- }}>
726
- {liveStats}
727
- </Text>
728
- </View>
712
+ {Boolean(liveStats) ? (<View style={{
713
+ flexDirection: 'row',
714
+ alignItems: 'center',
715
+ gap: 6,
716
+ flex: 1,
717
+ }}>
718
+ <View style={{
719
+ width: 6,
720
+ height: 6,
721
+ borderRadius: 3,
722
+ backgroundColor: isChecked
723
+ ? AppColors.liveGreen
724
+ : AppColors.grayTextWeak,
725
+ }}/>
726
+ <Text style={{
727
+ fontFamily: AppFonts.interMedium,
728
+ fontSize: 11,
729
+ color: AppColors.grayText,
730
+ lineHeight: 14,
731
+ }}>
732
+ {liveStats}
733
+ </Text>
734
+ </View>) : (<View style={{ flex: 1 }}/>)}
729
735
 
730
736
  {/* Sleek Configure Button */}
731
737
  <TouchableScale accessible={true} accessibilityRole="button" accessibilityLabel={`Configure ${moduleItem.label} settings`} onPress={() => {
@@ -1224,6 +1230,88 @@ const SettingsPanel = () => {
1224
1230
 
1225
1231
  {/* ─── TAB 3: UI & APPEARANCE ────────────────────────────────────────── */}
1226
1232
  {settingsActiveSubTab === 'ui' && (<View style={{ gap: 14 }}>
1233
+ {/* Section 0: Interactive Walkthrough Tour */}
1234
+ <View style={{
1235
+ backgroundColor: AppColors.primaryLight,
1236
+ borderRadius: 14,
1237
+ borderWidth: 1,
1238
+ borderColor: AppColors.grayBorderSecondary,
1239
+ overflow: 'hidden',
1240
+ padding: 14,
1241
+ gap: 12,
1242
+ }}>
1243
+ <Text style={{
1244
+ fontFamily: AppFonts.interBold,
1245
+ fontSize: 11,
1246
+ lineHeight: 14,
1247
+ color: AppColors.grayTextWeak,
1248
+ letterSpacing: 0.8,
1249
+ }}>
1250
+ ONBOARDING & GUIDE
1251
+ </Text>
1252
+
1253
+ <View style={{
1254
+ flexDirection: 'row',
1255
+ alignItems: 'center',
1256
+ justifyContent: 'space-between',
1257
+ gap: 10,
1258
+ }}>
1259
+ <View style={{
1260
+ flexDirection: 'row',
1261
+ alignItems: 'center',
1262
+ gap: 10,
1263
+ flex: 1,
1264
+ }}>
1265
+ <View style={{
1266
+ width: 34,
1267
+ height: 34,
1268
+ borderRadius: 9,
1269
+ backgroundColor: `${AppColors.purple}16`,
1270
+ alignItems: 'center',
1271
+ justifyContent: 'center',
1272
+ }}>
1273
+ <GlobeIcon color={AppColors.purple} size={16}/>
1274
+ </View>
1275
+ <View style={{ flex: 1 }}>
1276
+ <Text style={{
1277
+ fontFamily: AppFonts.interBold,
1278
+ fontSize: 13.5,
1279
+ lineHeight: 18,
1280
+ color: AppColors.primaryBlack,
1281
+ }}>
1282
+ First-Time Walkthrough
1283
+ </Text>
1284
+ <Text style={{
1285
+ fontFamily: AppFonts.interRegular,
1286
+ fontSize: 11.5,
1287
+ color: AppColors.grayTextWeak,
1288
+ marginTop: 1,
1289
+ lineHeight: 16,
1290
+ }}>
1291
+ Explore features, gestures & developer tools
1292
+ </Text>
1293
+ </View>
1294
+ </View>
1295
+
1296
+ <TouchableScale style={{
1297
+ backgroundColor: `${AppColors.purple}14`,
1298
+ borderColor: `${AppColors.purple}30`,
1299
+ borderWidth: 1,
1300
+ paddingHorizontal: 12,
1301
+ paddingVertical: 7,
1302
+ borderRadius: 8,
1303
+ }} onPress={openWalkthrough} hitSlop={8}>
1304
+ <Text style={{
1305
+ fontFamily: AppFonts.interBold,
1306
+ fontSize: 12,
1307
+ color: AppColors.purple,
1308
+ }}>
1309
+ Start Tour →
1310
+ </Text>
1311
+ </TouchableScale>
1312
+ </View>
1313
+ </View>
1314
+
1227
1315
  {/* Section 1: Appearance */}
1228
1316
  <View style={{
1229
1317
  backgroundColor: AppColors.primaryLight,
@@ -1 +1 @@
1
- export declare const LIB_VERSION = "2.0.6";
1
+ export declare const LIB_VERSION = "2.0.7";
@@ -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 = '2.0.6';
3
+ export const LIB_VERSION = '2.0.7';
@@ -2,7 +2,7 @@ import { InspectorStorage, PersistedSettings } from '../types';
2
2
  export { InspectorStorage, PersistedSettings };
3
3
  export declare function setCustomStorage(storage: InspectorStorage | null): void;
4
4
  export declare function loadSettings(): Promise<PersistedSettings>;
5
- export declare function saveSettings(settings: PersistedSettings): void;
5
+ export declare function saveSettings(settings: PersistedSettings): Promise<void>;
6
6
  export declare function clearPersistedSettings(): Promise<void>;
7
7
  export declare const isPersistentStorageAvailable: () => boolean;
8
8
  export declare function getCustomStorage(): InspectorStorage | null;
@@ -48,9 +48,11 @@ export async function loadSettings() {
48
48
  return {};
49
49
  }
50
50
  }
51
- export function saveSettings(settings) {
51
+ export async function saveSettings(settings) {
52
52
  try {
53
- const raw = JSON.stringify(settings);
53
+ const existing = await loadSettings();
54
+ const merged = { ...existing, ...settings };
55
+ const raw = JSON.stringify(merged);
54
56
  if (customStorage) {
55
57
  customStorage.setItem(SETTINGS_KEY, raw);
56
58
  return;
package/dist/esm/index.js CHANGED
@@ -89,6 +89,8 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
89
89
  const [sectionFilters, setSectionFilters] = useState({});
90
90
  const [collapsedSections, setCollapsedSections] = useState(new Set());
91
91
  const [showHeaderInfo, setShowHeaderInfo] = useState(true);
92
+ const [isWalkthroughVisible, setIsWalkthroughVisible] = useState(true);
93
+ const hasCompletedWalkthroughRef = useRef(null);
92
94
  const [sortOrder, setSortOrder] = useState('newest');
93
95
  // #7 — sort order for the Logs (console) tab
94
96
  const [logSortOrder, setLogSortOrder] = useState('newest');
@@ -392,6 +394,7 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
392
394
  };
393
395
  setActiveTab(vis[dt] ? dt : 'apis');
394
396
  }
397
+ hasCompletedWalkthroughRef.current = saved.hasCompletedWalkthrough === true;
395
398
  settingsHydratedRef.current = true;
396
399
  });
397
400
  return () => {
@@ -857,6 +860,11 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
857
860
  setSelectedReduxSlice(null);
858
861
  setSelectedReduxAction(null);
859
862
  setSelectedCrash(null);
863
+ // Trigger first-time walkthrough strictly on first FAB launch if not yet completed
864
+ if (hasCompletedWalkthroughRef.current === false) {
865
+ setIsWalkthroughVisible(true);
866
+ hasCompletedWalkthroughRef.current = true;
867
+ }
860
868
  // Track inspector opened event in GA4
861
869
  trackInspectorOpen({ activeTab: target });
862
870
  // Instant synchronization of data collected while modal was closed
@@ -1702,6 +1710,12 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1702
1710
  setModalAnimationType,
1703
1711
  hasNavigationContext,
1704
1712
  setNavState,
1713
+ isWalkthroughVisible,
1714
+ setIsWalkthroughVisible,
1715
+ openWalkthrough: () => {
1716
+ setSettingsPage(null);
1717
+ setIsWalkthroughVisible(true);
1718
+ },
1705
1719
  // ─── Tabs ───────────────────────────────────────────────────────────
1706
1720
  activeTab,
1707
1721
  switchActiveTab,
@@ -211,6 +211,7 @@ export interface PersistedSettings {
211
211
  reduxExpandDepth?: number;
212
212
  showDuplicateLogs?: boolean;
213
213
  showUpdateToast?: boolean;
214
+ hasCompletedWalkthrough?: boolean;
214
215
  }
215
216
  export interface NetworkInspectorProps {
216
217
  enabled?: boolean;
@@ -244,6 +245,9 @@ export interface InspectorContextValue {
244
245
  setModalAnimationType: React.Dispatch<React.SetStateAction<'slide' | 'fade' | 'none'>>;
245
246
  hasNavigationContext: boolean;
246
247
  setNavState: React.Dispatch<React.SetStateAction<any>>;
248
+ isWalkthroughVisible: boolean;
249
+ setIsWalkthroughVisible: React.Dispatch<React.SetStateAction<boolean>>;
250
+ openWalkthrough: () => void;
247
251
  activeTab: ActiveTab;
248
252
  switchActiveTab: (key: ActiveTab) => void;
249
253
  tabVisibility: Record<ActiveTab, boolean>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-inapp-inspector",
3
- "version": "2.0.6",
3
+ "version": "2.0.7",
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",