react-native-debug-toolkit 3.3.8 → 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/README.md +40 -26
  2. package/README.zh-CN.md +52 -38
  3. package/android/src/main/java/com/reactnativedebugtoolkit/DebugToolkitNativeLogsModule.java +146 -0
  4. package/android/src/main/java/com/reactnativedebugtoolkit/ReactNativeDebugToolkitPackage.java +5 -3
  5. package/ios/DebugToolkitNativeLogs.mm +92 -0
  6. package/lib/commonjs/constants/logLevels.js +19 -0
  7. package/lib/commonjs/constants/logLevels.js.map +1 -0
  8. package/lib/commonjs/core/initialize.js +32 -19
  9. package/lib/commonjs/core/initialize.js.map +1 -1
  10. package/lib/commonjs/features/console/ConsoleLogTab.js +4 -15
  11. package/lib/commonjs/features/console/ConsoleLogTab.js.map +1 -1
  12. package/lib/commonjs/features/console/index.js +15 -8
  13. package/lib/commonjs/features/console/index.js.map +1 -1
  14. package/lib/commonjs/features/nativeLogs/NativeLogTab.js +156 -0
  15. package/lib/commonjs/features/nativeLogs/NativeLogTab.js.map +1 -0
  16. package/lib/commonjs/features/nativeLogs/index.js +97 -0
  17. package/lib/commonjs/features/nativeLogs/index.js.map +1 -0
  18. package/lib/commonjs/features/nativeLogs/nativeLogsBridge.js +71 -0
  19. package/lib/commonjs/features/nativeLogs/nativeLogsBridge.js.map +1 -0
  20. package/lib/commonjs/features/network/NetworkLogTab.js +90 -95
  21. package/lib/commonjs/features/network/NetworkLogTab.js.map +1 -1
  22. package/lib/commonjs/features/network/index.js +7 -4
  23. package/lib/commonjs/features/network/index.js.map +1 -1
  24. package/lib/commonjs/features/sessionHistory/SessionHistoryTab.js +1046 -0
  25. package/lib/commonjs/features/sessionHistory/SessionHistoryTab.js.map +1 -0
  26. package/lib/commonjs/features/sessionHistory/index.js +104 -0
  27. package/lib/commonjs/features/sessionHistory/index.js.map +1 -0
  28. package/lib/commonjs/features/track/index.js +4 -3
  29. package/lib/commonjs/features/track/index.js.map +1 -1
  30. package/lib/commonjs/index.js +27 -0
  31. package/lib/commonjs/index.js.map +1 -1
  32. package/lib/commonjs/ui/DebugView.js +2 -0
  33. package/lib/commonjs/ui/DebugView.js.map +1 -1
  34. package/lib/commonjs/ui/panel/DebugPanel.js +67 -34
  35. package/lib/commonjs/ui/panel/DebugPanel.js.map +1 -1
  36. package/lib/commonjs/ui/panel/FeatureIntroCard.js +151 -0
  37. package/lib/commonjs/ui/panel/FeatureIntroCard.js.map +1 -0
  38. package/lib/commonjs/ui/panel/FeatureRail.js +163 -0
  39. package/lib/commonjs/ui/panel/FeatureRail.js.map +1 -0
  40. package/lib/commonjs/ui/panel/FloatPanelView.js +119 -22
  41. package/lib/commonjs/ui/panel/FloatPanelView.js.map +1 -1
  42. package/lib/commonjs/ui/panel/buildFeatureSummary.js +207 -0
  43. package/lib/commonjs/ui/panel/buildFeatureSummary.js.map +1 -0
  44. package/lib/commonjs/ui/panel/filterFeatureSnapshot.js +43 -0
  45. package/lib/commonjs/ui/panel/filterFeatureSnapshot.js.map +1 -0
  46. package/lib/commonjs/ui/theme/colors.js +6 -0
  47. package/lib/commonjs/ui/theme/colors.js.map +1 -1
  48. package/lib/commonjs/utils/DaemonClient.js +30 -8
  49. package/lib/commonjs/utils/DaemonClient.js.map +1 -1
  50. package/lib/commonjs/utils/SessionManager.js +132 -0
  51. package/lib/commonjs/utils/SessionManager.js.map +1 -0
  52. package/lib/commonjs/utils/StorageAdapter.js +104 -0
  53. package/lib/commonjs/utils/StorageAdapter.js.map +1 -0
  54. package/lib/commonjs/utils/createChannelFeature.js +22 -5
  55. package/lib/commonjs/utils/createChannelFeature.js.map +1 -1
  56. package/lib/commonjs/utils/createPersistedObservableStore.js +14 -8
  57. package/lib/commonjs/utils/createPersistedObservableStore.js.map +1 -1
  58. package/lib/commonjs/utils/debugPreferences.js +28 -5
  59. package/lib/commonjs/utils/debugPreferences.js.map +1 -1
  60. package/lib/commonjs/utils/deviceReport.js +5 -1
  61. package/lib/commonjs/utils/deviceReport.js.map +1 -1
  62. package/lib/commonjs/utils/logRuntime.js +32 -0
  63. package/lib/commonjs/utils/logRuntime.js.map +1 -0
  64. package/lib/module/constants/logLevels.js +15 -0
  65. package/lib/module/constants/logLevels.js.map +1 -0
  66. package/lib/module/core/initialize.js +32 -19
  67. package/lib/module/core/initialize.js.map +1 -1
  68. package/lib/module/features/console/ConsoleLogTab.js +1 -12
  69. package/lib/module/features/console/ConsoleLogTab.js.map +1 -1
  70. package/lib/module/features/console/index.js +15 -8
  71. package/lib/module/features/console/index.js.map +1 -1
  72. package/lib/module/features/nativeLogs/NativeLogTab.js +151 -0
  73. package/lib/module/features/nativeLogs/NativeLogTab.js.map +1 -0
  74. package/lib/module/features/nativeLogs/index.js +91 -0
  75. package/lib/module/features/nativeLogs/index.js.map +1 -0
  76. package/lib/module/features/nativeLogs/nativeLogsBridge.js +63 -0
  77. package/lib/module/features/nativeLogs/nativeLogsBridge.js.map +1 -0
  78. package/lib/module/features/network/NetworkLogTab.js +90 -95
  79. package/lib/module/features/network/NetworkLogTab.js.map +1 -1
  80. package/lib/module/features/network/index.js +7 -4
  81. package/lib/module/features/network/index.js.map +1 -1
  82. package/lib/module/features/sessionHistory/SessionHistoryTab.js +1041 -0
  83. package/lib/module/features/sessionHistory/SessionHistoryTab.js.map +1 -0
  84. package/lib/module/features/sessionHistory/index.js +100 -0
  85. package/lib/module/features/sessionHistory/index.js.map +1 -0
  86. package/lib/module/features/track/index.js +4 -3
  87. package/lib/module/features/track/index.js.map +1 -1
  88. package/lib/module/index.js +3 -0
  89. package/lib/module/index.js.map +1 -1
  90. package/lib/module/ui/DebugView.js +2 -0
  91. package/lib/module/ui/DebugView.js.map +1 -1
  92. package/lib/module/ui/panel/DebugPanel.js +67 -34
  93. package/lib/module/ui/panel/DebugPanel.js.map +1 -1
  94. package/lib/module/ui/panel/FeatureIntroCard.js +146 -0
  95. package/lib/module/ui/panel/FeatureIntroCard.js.map +1 -0
  96. package/lib/module/ui/panel/FeatureRail.js +158 -0
  97. package/lib/module/ui/panel/FeatureRail.js.map +1 -0
  98. package/lib/module/ui/panel/FloatPanelView.js +119 -22
  99. package/lib/module/ui/panel/FloatPanelView.js.map +1 -1
  100. package/lib/module/ui/panel/buildFeatureSummary.js +203 -0
  101. package/lib/module/ui/panel/buildFeatureSummary.js.map +1 -0
  102. package/lib/module/ui/panel/filterFeatureSnapshot.js +39 -0
  103. package/lib/module/ui/panel/filterFeatureSnapshot.js.map +1 -0
  104. package/lib/module/ui/theme/colors.js +6 -0
  105. package/lib/module/ui/theme/colors.js.map +1 -1
  106. package/lib/module/utils/DaemonClient.js +30 -8
  107. package/lib/module/utils/DaemonClient.js.map +1 -1
  108. package/lib/module/utils/SessionManager.js +127 -0
  109. package/lib/module/utils/SessionManager.js.map +1 -0
  110. package/lib/module/utils/StorageAdapter.js +96 -0
  111. package/lib/module/utils/StorageAdapter.js.map +1 -0
  112. package/lib/module/utils/createChannelFeature.js +22 -5
  113. package/lib/module/utils/createChannelFeature.js.map +1 -1
  114. package/lib/module/utils/createPersistedObservableStore.js +14 -8
  115. package/lib/module/utils/createPersistedObservableStore.js.map +1 -1
  116. package/lib/module/utils/debugPreferences.js +27 -5
  117. package/lib/module/utils/debugPreferences.js.map +1 -1
  118. package/lib/module/utils/deviceReport.js +4 -1
  119. package/lib/module/utils/deviceReport.js.map +1 -1
  120. package/lib/module/utils/logRuntime.js +26 -0
  121. package/lib/module/utils/logRuntime.js.map +1 -0
  122. package/lib/typescript/src/constants/logLevels.d.ts +3 -0
  123. package/lib/typescript/src/constants/logLevels.d.ts.map +1 -0
  124. package/lib/typescript/src/core/initialize.d.ts +6 -0
  125. package/lib/typescript/src/core/initialize.d.ts.map +1 -1
  126. package/lib/typescript/src/features/console/ConsoleLogTab.d.ts.map +1 -1
  127. package/lib/typescript/src/features/console/index.d.ts +2 -1
  128. package/lib/typescript/src/features/console/index.d.ts.map +1 -1
  129. package/lib/typescript/src/features/nativeLogs/NativeLogTab.d.ts +4 -0
  130. package/lib/typescript/src/features/nativeLogs/NativeLogTab.d.ts.map +1 -0
  131. package/lib/typescript/src/features/nativeLogs/index.d.ts +12 -0
  132. package/lib/typescript/src/features/nativeLogs/index.d.ts.map +1 -0
  133. package/lib/typescript/src/features/nativeLogs/nativeLogsBridge.d.ts +11 -0
  134. package/lib/typescript/src/features/nativeLogs/nativeLogsBridge.d.ts.map +1 -0
  135. package/lib/typescript/src/features/network/NetworkLogTab.d.ts.map +1 -1
  136. package/lib/typescript/src/features/network/index.d.ts +2 -1
  137. package/lib/typescript/src/features/network/index.d.ts.map +1 -1
  138. package/lib/typescript/src/features/sessionHistory/SessionHistoryTab.d.ts +20 -0
  139. package/lib/typescript/src/features/sessionHistory/SessionHistoryTab.d.ts.map +1 -0
  140. package/lib/typescript/src/features/sessionHistory/index.d.ts +4 -0
  141. package/lib/typescript/src/features/sessionHistory/index.d.ts.map +1 -0
  142. package/lib/typescript/src/features/track/index.d.ts +2 -1
  143. package/lib/typescript/src/features/track/index.d.ts.map +1 -1
  144. package/lib/typescript/src/index.d.ts +7 -1
  145. package/lib/typescript/src/index.d.ts.map +1 -1
  146. package/lib/typescript/src/types/feature.d.ts +1 -1
  147. package/lib/typescript/src/types/feature.d.ts.map +1 -1
  148. package/lib/typescript/src/types/index.d.ts +3 -1
  149. package/lib/typescript/src/types/index.d.ts.map +1 -1
  150. package/lib/typescript/src/types/logs.d.ts +15 -0
  151. package/lib/typescript/src/types/logs.d.ts.map +1 -1
  152. package/lib/typescript/src/ui/DebugView.d.ts.map +1 -1
  153. package/lib/typescript/src/ui/panel/DebugPanel.d.ts +3 -1
  154. package/lib/typescript/src/ui/panel/DebugPanel.d.ts.map +1 -1
  155. package/lib/typescript/src/ui/panel/FeatureIntroCard.d.ts +14 -0
  156. package/lib/typescript/src/ui/panel/FeatureIntroCard.d.ts.map +1 -0
  157. package/lib/typescript/src/ui/panel/FeatureRail.d.ts +16 -0
  158. package/lib/typescript/src/ui/panel/FeatureRail.d.ts.map +1 -0
  159. package/lib/typescript/src/ui/panel/FloatPanelView.d.ts.map +1 -1
  160. package/lib/typescript/src/ui/panel/buildFeatureSummary.d.ts +13 -0
  161. package/lib/typescript/src/ui/panel/buildFeatureSummary.d.ts.map +1 -0
  162. package/lib/typescript/src/ui/panel/filterFeatureSnapshot.d.ts +3 -0
  163. package/lib/typescript/src/ui/panel/filterFeatureSnapshot.d.ts.map +1 -0
  164. package/lib/typescript/src/ui/theme/colors.d.ts +5 -0
  165. package/lib/typescript/src/ui/theme/colors.d.ts.map +1 -1
  166. package/lib/typescript/src/utils/DaemonClient.d.ts +7 -1
  167. package/lib/typescript/src/utils/DaemonClient.d.ts.map +1 -1
  168. package/lib/typescript/src/utils/SessionManager.d.ts +30 -0
  169. package/lib/typescript/src/utils/SessionManager.d.ts.map +1 -0
  170. package/lib/typescript/src/utils/StorageAdapter.d.ts +38 -0
  171. package/lib/typescript/src/utils/StorageAdapter.d.ts.map +1 -0
  172. package/lib/typescript/src/utils/createChannelFeature.d.ts +2 -0
  173. package/lib/typescript/src/utils/createChannelFeature.d.ts.map +1 -1
  174. package/lib/typescript/src/utils/createPersistedObservableStore.d.ts +4 -1
  175. package/lib/typescript/src/utils/createPersistedObservableStore.d.ts.map +1 -1
  176. package/lib/typescript/src/utils/debugPreferences.d.ts +1 -3
  177. package/lib/typescript/src/utils/debugPreferences.d.ts.map +1 -1
  178. package/lib/typescript/src/utils/deviceReport.d.ts +1 -0
  179. package/lib/typescript/src/utils/deviceReport.d.ts.map +1 -1
  180. package/lib/typescript/src/utils/logRuntime.d.ts +13 -0
  181. package/lib/typescript/src/utils/logRuntime.d.ts.map +1 -0
  182. package/node/daemon/src/console/console.html +18 -0
  183. package/node/mcp/src/logs.js +1 -1
  184. package/package.json +9 -1
  185. package/src/constants/logLevels.ts +13 -0
  186. package/src/core/initialize.ts +54 -25
  187. package/src/features/console/ConsoleLogTab.tsx +1 -14
  188. package/src/features/console/index.ts +18 -8
  189. package/src/features/nativeLogs/NativeLogTab.tsx +66 -0
  190. package/src/features/nativeLogs/index.ts +94 -0
  191. package/src/features/nativeLogs/nativeLogsBridge.ts +51 -0
  192. package/src/features/network/NetworkLogTab.tsx +60 -71
  193. package/src/features/network/index.ts +12 -3
  194. package/src/features/sessionHistory/SessionHistoryTab.tsx +693 -0
  195. package/src/features/sessionHistory/index.ts +102 -0
  196. package/src/features/track/index.ts +10 -3
  197. package/src/index.ts +16 -0
  198. package/src/types/feature.ts +3 -1
  199. package/src/types/index.ts +13 -0
  200. package/src/types/logs.ts +17 -0
  201. package/src/ui/DebugView.tsx +2 -0
  202. package/src/ui/panel/DebugPanel.tsx +60 -30
  203. package/src/ui/panel/FeatureIntroCard.tsx +147 -0
  204. package/src/ui/panel/FeatureRail.tsx +165 -0
  205. package/src/ui/panel/FloatPanelView.tsx +123 -15
  206. package/src/ui/panel/buildFeatureSummary.ts +288 -0
  207. package/src/ui/panel/filterFeatureSnapshot.ts +51 -0
  208. package/src/ui/theme/colors.ts +7 -0
  209. package/src/utils/DaemonClient.ts +33 -5
  210. package/src/utils/SessionManager.ts +174 -0
  211. package/src/utils/StorageAdapter.ts +135 -0
  212. package/src/utils/createChannelFeature.ts +28 -6
  213. package/src/utils/createPersistedObservableStore.ts +18 -10
  214. package/src/utils/debugPreferences.ts +38 -7
  215. package/src/utils/deviceReport.ts +5 -1
  216. package/src/utils/logRuntime.ts +39 -0
  217. package/lib/commonjs/ui/panel/FeatureTabBar.js +0 -182
  218. package/lib/commonjs/ui/panel/FeatureTabBar.js.map +0 -1
  219. package/lib/module/ui/panel/FeatureTabBar.js +0 -177
  220. package/lib/module/ui/panel/FeatureTabBar.js.map +0 -1
  221. package/lib/typescript/src/ui/panel/FeatureTabBar.d.ts +0 -13
  222. package/lib/typescript/src/ui/panel/FeatureTabBar.d.ts.map +0 -1
  223. package/src/ui/panel/FeatureTabBar.tsx +0 -204
@@ -0,0 +1,102 @@
1
+ import { SessionHistoryTab, type SessionHistoryState, type SelectedSession, type LogCounts, type SessionHistoryFeature } from './SessionHistoryTab';
2
+ import type { LogFeatureKey } from '../../types';
3
+ import { createDebugTab } from '../../utils/createDebugTab';
4
+ import { getDefaultLogRuntime, type LogRuntimeContext } from '../../utils/logRuntime';
5
+
6
+ const FEATURE_KEYS: LogFeatureKey[] = ['console_logs', 'network_logs', 'native_logs', 'track_logs'];
7
+
8
+ export function createSessionHistoryFeature(
9
+ runtime: LogRuntimeContext = getDefaultLogRuntime(),
10
+ ): SessionHistoryFeature {
11
+ let listeners: Array<() => void> = [];
12
+ let sessions = runtime.sessionManager.getCurrentSession() ? [runtime.sessionManager.getCurrentSession()] : [];
13
+ let currentSessionId = runtime.sessionManager.getCurrentSession().id;
14
+ let loading = false;
15
+ let selected: SelectedSession | null = null;
16
+ let initialized = false;
17
+ let logCounts: Record<string, LogCounts> = {};
18
+
19
+ function notify() {
20
+ listeners.forEach((l) => l());
21
+ }
22
+
23
+ function getSnapshot(): SessionHistoryState {
24
+ return { sessions, currentSessionId, loading, selectedSession: selected, storageType: runtime.logStorage.constructor.name, logCounts };
25
+ }
26
+
27
+ async function loadLogCounts(sessionIds: string[]) {
28
+ const counts: Record<string, LogCounts> = {};
29
+ await Promise.all(
30
+ sessionIds.map(async (id) => {
31
+ const c: LogCounts = { console_logs: 0, network_logs: 0, native_logs: 0, track_logs: 0 };
32
+ await Promise.all(
33
+ FEATURE_KEYS.map(async (key) => {
34
+ c[key] = await runtime.sessionManager.getSessionLogCount(id, key);
35
+ }),
36
+ );
37
+ counts[id] = c;
38
+ }),
39
+ );
40
+ return counts;
41
+ }
42
+
43
+ async function loadSession(sessionId: string | null) {
44
+ if (sessionId === null) {
45
+ selected = null;
46
+ notify();
47
+ return;
48
+ }
49
+
50
+ loading = true;
51
+ selected = null;
52
+ notify();
53
+
54
+ const logs: Record<LogFeatureKey, unknown[]> = {} as Record<LogFeatureKey, unknown[]>;
55
+ await Promise.all(
56
+ FEATURE_KEYS.map(async (key) => {
57
+ logs[key] = await runtime.sessionManager.loadSessionLogs(sessionId, key);
58
+ }),
59
+ );
60
+
61
+ loading = false;
62
+ selected = { sessionId, logs };
63
+ notify();
64
+ }
65
+
66
+ const feature: SessionHistoryFeature = {
67
+ ...createDebugTab<SessionHistoryState>({
68
+ name: 'sessionHistory',
69
+ label: 'Sessions',
70
+ getSnapshot,
71
+ render: SessionHistoryTab,
72
+ setup: async () => {
73
+ if (initialized) return;
74
+ initialized = true;
75
+ loading = true;
76
+ notify();
77
+ try {
78
+ sessions = await runtime.sessionManager.getSessionHistory();
79
+ currentSessionId = runtime.sessionManager.getCurrentSession().id;
80
+ logCounts = await loadLogCounts(sessions.map((s) => s.id));
81
+ } catch (e) {
82
+ console.warn('[SessionHistory] setup error:', e);
83
+ }
84
+ loading = false;
85
+ notify();
86
+ },
87
+ cleanup: () => {
88
+ initialized = false;
89
+ selected = null;
90
+ },
91
+ subscribe: (listener) => {
92
+ listeners.push(listener);
93
+ return () => {
94
+ listeners = listeners.filter((l) => l !== listener);
95
+ };
96
+ },
97
+ }),
98
+ loadSession,
99
+ };
100
+
101
+ return feature;
102
+ }
@@ -2,7 +2,7 @@ import { TrackLogTab } from './TrackLogTab';
2
2
  import type { DebugFeature, TrackLogEntry } from '../../types';
3
3
  import { createEventChannel } from '../../utils/createEventChannel';
4
4
  import { createChannelFeature } from '../../utils/createChannelFeature';
5
- import { KEYS } from '../../utils/debugPreferences';
5
+ import { getDefaultLogRuntime, type LogRuntimeContext } from '../../utils/logRuntime';
6
6
 
7
7
  export interface TrackEventData {
8
8
  eventName: string;
@@ -22,7 +22,10 @@ export interface TrackFeatureConfig {
22
22
  maxLogs?: number;
23
23
  }
24
24
 
25
- export const createTrackFeature = (config?: TrackFeatureConfig): DebugFeature<TrackLogEntry[]> =>
25
+ export const createTrackFeature = (
26
+ config?: TrackFeatureConfig,
27
+ runtime: LogRuntimeContext = getDefaultLogRuntime(),
28
+ ): DebugFeature<TrackLogEntry[]> =>
26
29
  createChannelFeature(
27
30
  () => trackChannel,
28
31
  (payload, id) => ({ ...payload, id }),
@@ -31,7 +34,11 @@ export const createTrackFeature = (config?: TrackFeatureConfig): DebugFeature<Tr
31
34
  label: 'Track',
32
35
  renderContent: TrackLogTab,
33
36
  maxLogs: config?.maxLogs,
34
- persist: { storageKey: KEYS.trackLogs, maxPersist: 50 },
37
+ persist: {
38
+ storage: runtime.logStorage,
39
+ storageKey: runtime.sessionManager.getLogStorageKey('track_logs'),
40
+ maxPersist: 50,
41
+ },
35
42
  },
36
43
  );
37
44
 
package/src/index.ts CHANGED
@@ -22,6 +22,9 @@ export type { EnvironmentFeatureAPI } from './features/environment';
22
22
  export { createClipboardFeature } from './features/clipboard';
23
23
  export { createDevConnectFeature } from './features/devConnect';
24
24
  export type { DevConnectState } from './features/devConnect';
25
+ export { createSessionHistoryFeature } from './features/sessionHistory';
26
+ export { createNativeLogsFeature } from './features/nativeLogs';
27
+ export type { NativeLogsFeatureConfig } from './features/nativeLogs';
25
28
 
26
29
  // Hooks
27
30
  export { useNavigationLogger } from './features/navigation/useNavigationLogger';
@@ -47,6 +50,16 @@ export type {
47
50
  ReportToDaemonOptions,
48
51
  } from './utils/DaemonClient';
49
52
  export { getDefaultDaemonEndpoint } from './utils/DaemonClient';
53
+ export {
54
+ createDefaultLogStorage,
55
+ MemoryStorageAdapter,
56
+ } from './utils/StorageAdapter';
57
+ export type { StorageAdapter } from './utils/StorageAdapter';
58
+ export type {
59
+ LogFeatureKey,
60
+ LogSession,
61
+ SessionManagerOptions,
62
+ } from './utils/SessionManager';
50
63
 
51
64
  // Types
52
65
  export type {
@@ -58,6 +71,9 @@ export type {
58
71
  FeatureDataProvider,
59
72
  NetworkLogEntry,
60
73
  ConsoleLogEntry,
74
+ NativeLogEntry,
75
+ NativeLogLevel,
76
+ NativeLogSource,
61
77
  ZustandLogEntry,
62
78
  NavigationLogEntry,
63
79
  TrackLogEntry,
@@ -5,12 +5,14 @@ export type DebugFeatureListener = () => void;
5
5
  export type BuiltInFeatureName =
6
6
  | 'network'
7
7
  | 'console'
8
+ | 'native'
8
9
  | 'zustand'
9
10
  | 'navigation'
10
11
  | 'track'
11
12
  | 'environment'
12
13
  | 'clipboard'
13
- | 'devConnect';
14
+ | 'devConnect'
15
+ | 'sessionHistory';
14
16
 
15
17
  export interface DebugFeatureRenderProps<TSnapshot = unknown> {
16
18
  snapshot: TSnapshot;
@@ -10,6 +10,9 @@ export type {
10
10
  export type {
11
11
  ConsoleLogEntry,
12
12
  NavigationLogEntry,
13
+ NativeLogEntry,
14
+ NativeLogLevel,
15
+ NativeLogSource,
13
16
  NetworkLogEntry,
14
17
  TrackLogEntry,
15
18
  ZustandLogEntry,
@@ -28,3 +31,13 @@ export type {
28
31
  ThirdPartyLib,
29
32
  ThirdPartyLibAction,
30
33
  } from './thirdPartyLibs';
34
+
35
+ export type {
36
+ StorageAdapter,
37
+ } from '../utils/StorageAdapter';
38
+
39
+ export type {
40
+ LogFeatureKey,
41
+ LogSession,
42
+ SessionManagerOptions,
43
+ } from '../utils/SessionManager';
package/src/types/logs.ts CHANGED
@@ -52,3 +52,20 @@ export interface TrackLogEntry {
52
52
  eventName: string;
53
53
  [key: string]: unknown;
54
54
  }
55
+
56
+ export type NativeLogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'unknown';
57
+ export type NativeLogSource = 'logcat' | 'rctLog' | 'manual';
58
+
59
+ export interface NativeLogEntry {
60
+ id: string;
61
+ timestamp: number;
62
+ platform: 'android' | 'ios' | 'unknown';
63
+ level: NativeLogLevel;
64
+ source: NativeLogSource;
65
+ message: string;
66
+ tag?: string;
67
+ thread?: string;
68
+ file?: string;
69
+ line?: number;
70
+ raw?: string;
71
+ }
@@ -52,11 +52,13 @@ export function DebugView({
52
52
  const resolvedFeatures: FeatureConfigs = {
53
53
  network: true,
54
54
  console: true,
55
+ native: true,
55
56
  zustand: true,
56
57
  navigation: true,
57
58
  track: true,
58
59
  clipboard: true,
59
60
  devConnect: true,
61
+ sessionHistory: true,
60
62
  ...features,
61
63
  };
62
64
 
@@ -14,10 +14,12 @@ import { Colors } from '../theme/colors';
14
14
  interface DebugPanelProps {
15
15
  onClose: () => void;
16
16
  onClearAll: () => void;
17
+ syncLabel?: string;
18
+ syncColor?: string;
17
19
  children: React.ReactNode;
18
20
  }
19
21
 
20
- export function DebugPanel({ onClose, onClearAll, children }: DebugPanelProps) {
22
+ export function DebugPanel({ onClose, onClearAll, syncLabel, syncColor, children }: DebugPanelProps) {
21
23
  const { height: screenHeight } = useWindowDimensions();
22
24
  const panelTranslateY = useRef(new Animated.Value(screenHeight)).current;
23
25
  const backdropOpacity = useRef(new Animated.Value(0)).current;
@@ -99,20 +101,35 @@ export function DebugPanel({ onClose, onClearAll, children }: DebugPanelProps) {
99
101
  <View style={styles.dragIndicator} />
100
102
  </View>
101
103
  <View style={styles.header}>
102
- <Text style={styles.headerTitle}>Debug Toolkit</Text>
104
+ <View style={styles.headerLeft}>
105
+ <Text style={styles.headerTitle}>Debug Toolkit</Text>
106
+ {syncLabel && (
107
+ <View style={styles.syncRow}>
108
+ <View style={[styles.syncDot, syncColor ? { backgroundColor: syncColor } : null]} />
109
+ <Text style={styles.syncText} numberOfLines={1}>{syncLabel}</Text>
110
+ </View>
111
+ )}
112
+ </View>
103
113
  <View style={styles.headerButtons}>
104
114
  <TouchableOpacity
105
115
  onPress={() => {
106
116
  onClearAll();
107
117
  closePanel();
108
118
  }}
109
- style={styles.clearButton}
119
+ style={styles.iconButton}
110
120
  activeOpacity={0.6}
121
+ accessibilityLabel="Clear all"
122
+ accessibilityRole="button"
111
123
  >
112
- <Text style={styles.clearButtonText}>Clear</Text>
124
+ <Text style={styles.iconButtonText}>C</Text>
113
125
  </TouchableOpacity>
114
- <Pressable onPress={closePanel} style={styles.closeButton}>
115
- <Text style={styles.closeButtonText}>✕</Text>
126
+ <Pressable
127
+ onPress={closePanel}
128
+ style={styles.iconButton}
129
+ accessibilityLabel="Close panel"
130
+ accessibilityRole="button"
131
+ >
132
+ <Text style={styles.iconButtonText}>✕</Text>
116
133
  </Pressable>
117
134
  </View>
118
135
  </View>
@@ -156,13 +173,13 @@ const styles = StyleSheet.create({
156
173
  },
157
174
  dragHandle: {
158
175
  width: '100%',
159
- height: 28,
176
+ height: 26,
160
177
  alignItems: 'center',
161
178
  justifyContent: 'center',
162
179
  backgroundColor: Colors.surface,
163
180
  },
164
181
  dragIndicator: {
165
- width: 40,
182
+ width: 42,
166
183
  height: 4,
167
184
  borderRadius: 2,
168
185
  backgroundColor: Colors.textLight,
@@ -172,44 +189,57 @@ const styles = StyleSheet.create({
172
189
  flexDirection: 'row',
173
190
  justifyContent: 'space-between',
174
191
  alignItems: 'center',
175
- paddingHorizontal: 20,
176
- paddingTop: 6,
192
+ paddingHorizontal: 14,
193
+ paddingTop: 8,
177
194
  paddingBottom: 10,
178
195
  backgroundColor: Colors.surface,
196
+ borderBottomWidth: StyleSheet.hairlineWidth,
197
+ borderBottomColor: Colors.border,
198
+ },
199
+ headerLeft: {
200
+ flex: 1,
201
+ minWidth: 0,
179
202
  },
180
203
  headerTitle: {
181
204
  fontSize: 17,
182
- fontWeight: '600',
205
+ fontWeight: '700',
183
206
  color: Colors.text,
184
207
  },
185
- headerButtons: {
208
+ syncRow: {
186
209
  flexDirection: 'row',
187
210
  alignItems: 'center',
188
- gap: 12,
211
+ gap: 6,
212
+ marginTop: 4,
189
213
  },
190
- clearButton: {
191
- paddingHorizontal: 12,
192
- paddingVertical: 6,
193
- borderRadius: 8,
194
- backgroundColor: `${Colors.error}0F`,
214
+ syncDot: {
215
+ width: 7,
216
+ height: 7,
217
+ borderRadius: 3.5,
218
+ backgroundColor: Colors.success,
195
219
  },
196
- clearButtonText: {
197
- color: Colors.error,
198
- fontSize: 14,
199
- fontWeight: '500',
220
+ syncText: {
221
+ fontSize: 11,
222
+ fontWeight: '700',
223
+ color: Colors.textSecondary,
200
224
  },
201
- closeButton: {
202
- width: 30,
203
- height: 30,
204
- borderRadius: 15,
225
+ headerButtons: {
226
+ flexDirection: 'row',
227
+ alignItems: 'center',
228
+ gap: 7,
229
+ },
230
+ iconButton: {
231
+ width: 32,
232
+ height: 32,
233
+ borderRadius: 8,
234
+ borderWidth: 1,
235
+ borderColor: Colors.border,
205
236
  backgroundColor: Colors.background,
206
237
  alignItems: 'center',
207
238
  justifyContent: 'center',
208
239
  },
209
- closeButtonText: {
210
- fontSize: 16,
211
- fontWeight: '400',
240
+ iconButtonText: {
241
+ fontSize: 14,
242
+ fontWeight: '700',
212
243
  color: Colors.textSecondary,
213
- lineHeight: 16,
214
244
  },
215
245
  });
@@ -0,0 +1,147 @@
1
+ import React from 'react';
2
+ import { View, Text, Pressable, TextInput, StyleSheet } from 'react-native';
3
+ import { Colors } from '../theme/colors';
4
+ import type { FeatureSummary } from './buildFeatureSummary';
5
+
6
+ function hexWithAlpha(hex: string, alpha: string): string {
7
+ if (/^#[0-9a-fA-F]{6}$/.test(hex)) return hex + alpha;
8
+ return Colors.signalDefaultBg;
9
+ }
10
+
11
+ interface FeatureIntroCardProps {
12
+ title: string;
13
+ summary: FeatureSummary;
14
+ filterBad: boolean;
15
+ onFilterBad: (bad: boolean) => void;
16
+ searchQuery?: string;
17
+ onSearchChange?: (text: string) => void;
18
+ showSearch?: boolean;
19
+ }
20
+
21
+ export function FeatureIntroCard({
22
+ title,
23
+ summary,
24
+ filterBad,
25
+ onFilterBad,
26
+ searchQuery,
27
+ onSearchChange,
28
+ showSearch,
29
+ }: FeatureIntroCardProps) {
30
+ const { statusLabel, statusColor, supportsBadFilter } = summary;
31
+
32
+ return (
33
+ <View style={styles.card}>
34
+ <View style={styles.titleRow}>
35
+ <Text style={styles.title} numberOfLines={1}>{title}</Text>
36
+ {statusLabel && (
37
+ <View style={[styles.statusChip, statusColor && { backgroundColor: hexWithAlpha(statusColor, '18') }]}>
38
+ <Text style={[styles.statusText, statusColor && { color: statusColor }]} numberOfLines={1}>
39
+ {statusLabel}
40
+ </Text>
41
+ </View>
42
+ )}
43
+ {supportsBadFilter && (
44
+ <View style={styles.filterRow}>
45
+ <Pressable
46
+ style={[styles.chip, !filterBad && styles.chipActive]}
47
+ onPress={() => onFilterBad(false)}
48
+ >
49
+ <Text style={[styles.chipText, !filterBad && styles.chipTextActive]}>All</Text>
50
+ </Pressable>
51
+ <Pressable
52
+ style={[styles.chip, filterBad && styles.chipBadActive]}
53
+ onPress={() => onFilterBad(true)}
54
+ >
55
+ <Text style={[styles.chipText, filterBad && styles.chipTextBad]}>Bad</Text>
56
+ </Pressable>
57
+ </View>
58
+ )}
59
+ </View>
60
+ {showSearch && (
61
+ <TextInput
62
+ style={styles.searchInput}
63
+ placeholder="Search..."
64
+ placeholderTextColor={Colors.textLight}
65
+ value={searchQuery}
66
+ onChangeText={onSearchChange}
67
+ returnKeyType="search"
68
+ />
69
+ )}
70
+ </View>
71
+ );
72
+ }
73
+
74
+ const styles = StyleSheet.create({
75
+ card: {
76
+ paddingHorizontal: 12,
77
+ paddingTop: 8,
78
+ paddingBottom: 6,
79
+ borderBottomWidth: StyleSheet.hairlineWidth,
80
+ borderBottomColor: Colors.border,
81
+ backgroundColor: Colors.background,
82
+ },
83
+ titleRow: {
84
+ flexDirection: 'row',
85
+ alignItems: 'center',
86
+ gap: 8,
87
+ },
88
+ title: {
89
+ fontSize: 15,
90
+ fontWeight: '700',
91
+ color: Colors.text,
92
+ },
93
+ statusChip: {
94
+ paddingHorizontal: 8,
95
+ paddingVertical: 2,
96
+ borderRadius: 8,
97
+ backgroundColor: Colors.signalDefaultBg,
98
+ },
99
+ statusText: {
100
+ fontSize: 11,
101
+ fontWeight: '700',
102
+ color: Colors.textSecondary,
103
+ },
104
+ filterRow: {
105
+ flexDirection: 'row',
106
+ gap: 6,
107
+ },
108
+ chip: {
109
+ height: 24,
110
+ paddingHorizontal: 10,
111
+ justifyContent: 'center',
112
+ borderRadius: 12,
113
+ borderWidth: 1,
114
+ borderColor: Colors.border,
115
+ backgroundColor: Colors.surface,
116
+ },
117
+ chipActive: {
118
+ backgroundColor: Colors.text,
119
+ borderColor: Colors.text,
120
+ },
121
+ chipBadActive: {
122
+ backgroundColor: Colors.error,
123
+ borderColor: Colors.error,
124
+ },
125
+ chipText: {
126
+ fontSize: 11,
127
+ fontWeight: '700',
128
+ color: Colors.textSecondary,
129
+ },
130
+ chipTextActive: {
131
+ color: '#fff',
132
+ },
133
+ chipTextBad: {
134
+ color: '#fff',
135
+ },
136
+ searchInput: {
137
+ height: 32,
138
+ borderWidth: 1,
139
+ borderColor: Colors.border,
140
+ borderRadius: 8,
141
+ backgroundColor: Colors.surface,
142
+ paddingHorizontal: 10,
143
+ fontSize: 13,
144
+ color: Colors.text,
145
+ marginTop: 6,
146
+ },
147
+ });