react-native-debug-toolkit 3.3.4 → 3.5.0

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 (258) hide show
  1. package/README.md +48 -46
  2. package/README.zh-CN.md +48 -46
  3. package/android/src/main/java/com/reactnativedebugtoolkit/DebugToolkitDevConnectModule.java +0 -187
  4. package/bin/debug-toolkit.js +0 -16
  5. package/ios/DebugToolkitDevConnect.h +0 -12
  6. package/ios/DebugToolkitDevConnect.mm +0 -321
  7. package/lib/commonjs/constants/logLevels.js +19 -0
  8. package/lib/commonjs/constants/logLevels.js.map +1 -0
  9. package/lib/commonjs/core/initialize.js +36 -18
  10. package/lib/commonjs/core/initialize.js.map +1 -1
  11. package/lib/commonjs/features/console/ConsoleLogTab.js +4 -15
  12. package/lib/commonjs/features/console/ConsoleLogTab.js.map +1 -1
  13. package/lib/commonjs/features/console/index.js +15 -8
  14. package/lib/commonjs/features/console/index.js.map +1 -1
  15. package/lib/commonjs/features/devConnect/DevConnectTab.js +18 -470
  16. package/lib/commonjs/features/devConnect/DevConnectTab.js.map +1 -1
  17. package/lib/commonjs/features/devConnect/devConnectPreferences.js +0 -12
  18. package/lib/commonjs/features/devConnect/devConnectPreferences.js.map +1 -1
  19. package/lib/commonjs/features/devConnect/devConnectUtils.js +2 -57
  20. package/lib/commonjs/features/devConnect/devConnectUtils.js.map +1 -1
  21. package/lib/commonjs/features/devConnect/index.js +1 -23
  22. package/lib/commonjs/features/devConnect/index.js.map +1 -1
  23. package/lib/commonjs/features/devConnect/nativeDevConnect.js +1 -103
  24. package/lib/commonjs/features/devConnect/nativeDevConnect.js.map +1 -1
  25. package/lib/commonjs/features/network/NetworkLogTab.js +91 -93
  26. package/lib/commonjs/features/network/NetworkLogTab.js.map +1 -1
  27. package/lib/commonjs/features/network/index.js +7 -4
  28. package/lib/commonjs/features/network/index.js.map +1 -1
  29. package/lib/commonjs/features/sessionHistory/SessionHistoryTab.js +1044 -0
  30. package/lib/commonjs/features/sessionHistory/SessionHistoryTab.js.map +1 -0
  31. package/lib/commonjs/features/sessionHistory/index.js +103 -0
  32. package/lib/commonjs/features/sessionHistory/index.js.map +1 -0
  33. package/lib/commonjs/features/track/index.js +4 -3
  34. package/lib/commonjs/features/track/index.js.map +1 -1
  35. package/lib/commonjs/index.js +27 -0
  36. package/lib/commonjs/index.js.map +1 -1
  37. package/lib/commonjs/ui/DebugView.js +3 -0
  38. package/lib/commonjs/ui/DebugView.js.map +1 -1
  39. package/lib/commonjs/ui/panel/DebugPanel.js +67 -34
  40. package/lib/commonjs/ui/panel/DebugPanel.js.map +1 -1
  41. package/lib/commonjs/ui/panel/FeatureIntroCard.js +131 -0
  42. package/lib/commonjs/ui/panel/FeatureIntroCard.js.map +1 -0
  43. package/lib/commonjs/ui/panel/FeatureRail.js +163 -0
  44. package/lib/commonjs/ui/panel/FeatureRail.js.map +1 -0
  45. package/lib/commonjs/ui/panel/FloatPanelView.js +169 -32
  46. package/lib/commonjs/ui/panel/FloatPanelView.js.map +1 -1
  47. package/lib/commonjs/ui/panel/buildFeatureSummary.js +207 -0
  48. package/lib/commonjs/ui/panel/buildFeatureSummary.js.map +1 -0
  49. package/lib/commonjs/ui/panel/filterFeatureSnapshot.js +43 -0
  50. package/lib/commonjs/ui/panel/filterFeatureSnapshot.js.map +1 -0
  51. package/lib/commonjs/ui/panel/tabPersistence.js +17 -0
  52. package/lib/commonjs/ui/panel/tabPersistence.js.map +1 -0
  53. package/lib/commonjs/ui/theme/colors.js +6 -0
  54. package/lib/commonjs/ui/theme/colors.js.map +1 -1
  55. package/lib/commonjs/utils/DaemonClient.js +30 -8
  56. package/lib/commonjs/utils/DaemonClient.js.map +1 -1
  57. package/lib/commonjs/utils/SessionManager.js +132 -0
  58. package/lib/commonjs/utils/SessionManager.js.map +1 -0
  59. package/lib/commonjs/utils/StorageAdapter.js +104 -0
  60. package/lib/commonjs/utils/StorageAdapter.js.map +1 -0
  61. package/lib/commonjs/utils/createChannelFeature.js +22 -5
  62. package/lib/commonjs/utils/createChannelFeature.js.map +1 -1
  63. package/lib/commonjs/utils/createDebugTab.js +21 -0
  64. package/lib/commonjs/utils/createDebugTab.js.map +1 -0
  65. package/lib/commonjs/utils/createPersistedObservableStore.js +14 -8
  66. package/lib/commonjs/utils/createPersistedObservableStore.js.map +1 -1
  67. package/lib/commonjs/utils/debugPreferences.js +28 -6
  68. package/lib/commonjs/utils/debugPreferences.js.map +1 -1
  69. package/lib/commonjs/utils/deviceReport.js +5 -1
  70. package/lib/commonjs/utils/deviceReport.js.map +1 -1
  71. package/lib/commonjs/utils/logRuntime.js +32 -0
  72. package/lib/commonjs/utils/logRuntime.js.map +1 -0
  73. package/lib/module/constants/logLevels.js +15 -0
  74. package/lib/module/constants/logLevels.js.map +1 -0
  75. package/lib/module/core/initialize.js +36 -18
  76. package/lib/module/core/initialize.js.map +1 -1
  77. package/lib/module/features/console/ConsoleLogTab.js +1 -12
  78. package/lib/module/features/console/ConsoleLogTab.js.map +1 -1
  79. package/lib/module/features/console/index.js +15 -8
  80. package/lib/module/features/console/index.js.map +1 -1
  81. package/lib/module/features/devConnect/DevConnectTab.js +21 -473
  82. package/lib/module/features/devConnect/DevConnectTab.js.map +1 -1
  83. package/lib/module/features/devConnect/devConnectPreferences.js +1 -12
  84. package/lib/module/features/devConnect/devConnectPreferences.js.map +1 -1
  85. package/lib/module/features/devConnect/devConnectUtils.js +1 -53
  86. package/lib/module/features/devConnect/devConnectUtils.js.map +1 -1
  87. package/lib/module/features/devConnect/index.js +5 -9
  88. package/lib/module/features/devConnect/index.js.map +1 -1
  89. package/lib/module/features/devConnect/nativeDevConnect.js +1 -100
  90. package/lib/module/features/devConnect/nativeDevConnect.js.map +1 -1
  91. package/lib/module/features/network/NetworkLogTab.js +91 -93
  92. package/lib/module/features/network/NetworkLogTab.js.map +1 -1
  93. package/lib/module/features/network/index.js +7 -4
  94. package/lib/module/features/network/index.js.map +1 -1
  95. package/lib/module/features/sessionHistory/SessionHistoryTab.js +1039 -0
  96. package/lib/module/features/sessionHistory/SessionHistoryTab.js.map +1 -0
  97. package/lib/module/features/sessionHistory/index.js +99 -0
  98. package/lib/module/features/sessionHistory/index.js.map +1 -0
  99. package/lib/module/features/track/index.js +4 -3
  100. package/lib/module/features/track/index.js.map +1 -1
  101. package/lib/module/index.js +4 -0
  102. package/lib/module/index.js.map +1 -1
  103. package/lib/module/ui/DebugView.js +3 -0
  104. package/lib/module/ui/DebugView.js.map +1 -1
  105. package/lib/module/ui/panel/DebugPanel.js +67 -34
  106. package/lib/module/ui/panel/DebugPanel.js.map +1 -1
  107. package/lib/module/ui/panel/FeatureIntroCard.js +126 -0
  108. package/lib/module/ui/panel/FeatureIntroCard.js.map +1 -0
  109. package/lib/module/ui/panel/FeatureRail.js +158 -0
  110. package/lib/module/ui/panel/FeatureRail.js.map +1 -0
  111. package/lib/module/ui/panel/FloatPanelView.js +170 -33
  112. package/lib/module/ui/panel/FloatPanelView.js.map +1 -1
  113. package/lib/module/ui/panel/buildFeatureSummary.js +203 -0
  114. package/lib/module/ui/panel/buildFeatureSummary.js.map +1 -0
  115. package/lib/module/ui/panel/filterFeatureSnapshot.js +39 -0
  116. package/lib/module/ui/panel/filterFeatureSnapshot.js.map +1 -0
  117. package/lib/module/ui/panel/tabPersistence.js +13 -0
  118. package/lib/module/ui/panel/tabPersistence.js.map +1 -0
  119. package/lib/module/ui/theme/colors.js +6 -0
  120. package/lib/module/ui/theme/colors.js.map +1 -1
  121. package/lib/module/utils/DaemonClient.js +30 -8
  122. package/lib/module/utils/DaemonClient.js.map +1 -1
  123. package/lib/module/utils/SessionManager.js +127 -0
  124. package/lib/module/utils/SessionManager.js.map +1 -0
  125. package/lib/module/utils/StorageAdapter.js +96 -0
  126. package/lib/module/utils/StorageAdapter.js.map +1 -0
  127. package/lib/module/utils/createChannelFeature.js +22 -5
  128. package/lib/module/utils/createChannelFeature.js.map +1 -1
  129. package/lib/module/utils/createDebugTab.js +17 -0
  130. package/lib/module/utils/createDebugTab.js.map +1 -0
  131. package/lib/module/utils/createPersistedObservableStore.js +14 -8
  132. package/lib/module/utils/createPersistedObservableStore.js.map +1 -1
  133. package/lib/module/utils/debugPreferences.js +27 -6
  134. package/lib/module/utils/debugPreferences.js.map +1 -1
  135. package/lib/module/utils/deviceReport.js +4 -1
  136. package/lib/module/utils/deviceReport.js.map +1 -1
  137. package/lib/module/utils/logRuntime.js +26 -0
  138. package/lib/module/utils/logRuntime.js.map +1 -0
  139. package/lib/typescript/src/constants/logLevels.d.ts +3 -0
  140. package/lib/typescript/src/constants/logLevels.d.ts.map +1 -0
  141. package/lib/typescript/src/core/initialize.d.ts +6 -0
  142. package/lib/typescript/src/core/initialize.d.ts.map +1 -1
  143. package/lib/typescript/src/features/console/ConsoleLogTab.d.ts.map +1 -1
  144. package/lib/typescript/src/features/console/index.d.ts +2 -1
  145. package/lib/typescript/src/features/console/index.d.ts.map +1 -1
  146. package/lib/typescript/src/features/devConnect/DevConnectTab.d.ts.map +1 -1
  147. package/lib/typescript/src/features/devConnect/devConnectPreferences.d.ts +0 -2
  148. package/lib/typescript/src/features/devConnect/devConnectPreferences.d.ts.map +1 -1
  149. package/lib/typescript/src/features/devConnect/devConnectUtils.d.ts +0 -20
  150. package/lib/typescript/src/features/devConnect/devConnectUtils.d.ts.map +1 -1
  151. package/lib/typescript/src/features/devConnect/index.d.ts +2 -2
  152. package/lib/typescript/src/features/devConnect/index.d.ts.map +1 -1
  153. package/lib/typescript/src/features/devConnect/nativeDevConnect.d.ts +0 -25
  154. package/lib/typescript/src/features/devConnect/nativeDevConnect.d.ts.map +1 -1
  155. package/lib/typescript/src/features/devConnect/types.d.ts +1 -3
  156. package/lib/typescript/src/features/devConnect/types.d.ts.map +1 -1
  157. package/lib/typescript/src/features/network/NetworkLogTab.d.ts.map +1 -1
  158. package/lib/typescript/src/features/network/index.d.ts +2 -1
  159. package/lib/typescript/src/features/network/index.d.ts.map +1 -1
  160. package/lib/typescript/src/features/sessionHistory/SessionHistoryTab.d.ts +20 -0
  161. package/lib/typescript/src/features/sessionHistory/SessionHistoryTab.d.ts.map +1 -0
  162. package/lib/typescript/src/features/sessionHistory/index.d.ts +4 -0
  163. package/lib/typescript/src/features/sessionHistory/index.d.ts.map +1 -0
  164. package/lib/typescript/src/features/track/index.d.ts +2 -1
  165. package/lib/typescript/src/features/track/index.d.ts.map +1 -1
  166. package/lib/typescript/src/index.d.ts +6 -0
  167. package/lib/typescript/src/index.d.ts.map +1 -1
  168. package/lib/typescript/src/types/feature.d.ts +1 -1
  169. package/lib/typescript/src/types/feature.d.ts.map +1 -1
  170. package/lib/typescript/src/types/index.d.ts +2 -0
  171. package/lib/typescript/src/types/index.d.ts.map +1 -1
  172. package/lib/typescript/src/ui/DebugView.d.ts +4 -2
  173. package/lib/typescript/src/ui/DebugView.d.ts.map +1 -1
  174. package/lib/typescript/src/ui/panel/DebugPanel.d.ts +3 -1
  175. package/lib/typescript/src/ui/panel/DebugPanel.d.ts.map +1 -1
  176. package/lib/typescript/src/ui/panel/FeatureIntroCard.d.ts +11 -0
  177. package/lib/typescript/src/ui/panel/FeatureIntroCard.d.ts.map +1 -0
  178. package/lib/typescript/src/ui/panel/FeatureRail.d.ts +16 -0
  179. package/lib/typescript/src/ui/panel/FeatureRail.d.ts.map +1 -0
  180. package/lib/typescript/src/ui/panel/FloatPanelView.d.ts.map +1 -1
  181. package/lib/typescript/src/ui/panel/buildFeatureSummary.d.ts +13 -0
  182. package/lib/typescript/src/ui/panel/buildFeatureSummary.d.ts.map +1 -0
  183. package/lib/typescript/src/ui/panel/filterFeatureSnapshot.d.ts +3 -0
  184. package/lib/typescript/src/ui/panel/filterFeatureSnapshot.d.ts.map +1 -0
  185. package/lib/typescript/src/ui/panel/tabPersistence.d.ts +3 -0
  186. package/lib/typescript/src/ui/panel/tabPersistence.d.ts.map +1 -0
  187. package/lib/typescript/src/ui/theme/colors.d.ts +5 -0
  188. package/lib/typescript/src/ui/theme/colors.d.ts.map +1 -1
  189. package/lib/typescript/src/utils/DaemonClient.d.ts +7 -1
  190. package/lib/typescript/src/utils/DaemonClient.d.ts.map +1 -1
  191. package/lib/typescript/src/utils/SessionManager.d.ts +30 -0
  192. package/lib/typescript/src/utils/SessionManager.d.ts.map +1 -0
  193. package/lib/typescript/src/utils/StorageAdapter.d.ts +38 -0
  194. package/lib/typescript/src/utils/StorageAdapter.d.ts.map +1 -0
  195. package/lib/typescript/src/utils/createChannelFeature.d.ts +2 -0
  196. package/lib/typescript/src/utils/createChannelFeature.d.ts.map +1 -1
  197. package/lib/typescript/src/utils/createDebugTab.d.ts +18 -0
  198. package/lib/typescript/src/utils/createDebugTab.d.ts.map +1 -0
  199. package/lib/typescript/src/utils/createPersistedObservableStore.d.ts +4 -1
  200. package/lib/typescript/src/utils/createPersistedObservableStore.d.ts.map +1 -1
  201. package/lib/typescript/src/utils/debugPreferences.d.ts +1 -4
  202. package/lib/typescript/src/utils/debugPreferences.d.ts.map +1 -1
  203. package/lib/typescript/src/utils/deviceReport.d.ts +1 -0
  204. package/lib/typescript/src/utils/deviceReport.d.ts.map +1 -1
  205. package/lib/typescript/src/utils/logRuntime.d.ts +13 -0
  206. package/lib/typescript/src/utils/logRuntime.d.ts.map +1 -0
  207. package/package.json +10 -6
  208. package/src/constants/logLevels.ts +13 -0
  209. package/src/core/initialize.ts +61 -21
  210. package/src/features/console/ConsoleLogTab.tsx +1 -14
  211. package/src/features/console/index.ts +18 -8
  212. package/src/features/devConnect/DevConnectTab.tsx +17 -381
  213. package/src/features/devConnect/devConnectPreferences.ts +0 -15
  214. package/src/features/devConnect/devConnectUtils.ts +1 -81
  215. package/src/features/devConnect/index.ts +2 -9
  216. package/src/features/devConnect/nativeDevConnect.ts +1 -136
  217. package/src/features/devConnect/types.ts +1 -3
  218. package/src/features/network/NetworkLogTab.tsx +61 -71
  219. package/src/features/network/index.ts +12 -3
  220. package/src/features/sessionHistory/SessionHistoryTab.tsx +691 -0
  221. package/src/features/sessionHistory/index.ts +102 -0
  222. package/src/features/track/index.ts +10 -3
  223. package/src/index.ts +13 -0
  224. package/src/types/feature.ts +2 -1
  225. package/src/types/index.ts +10 -0
  226. package/src/ui/DebugView.tsx +6 -1
  227. package/src/ui/panel/DebugPanel.tsx +60 -30
  228. package/src/ui/panel/FeatureIntroCard.tsx +127 -0
  229. package/src/ui/panel/FeatureRail.tsx +165 -0
  230. package/src/ui/panel/FloatPanelView.tsx +176 -25
  231. package/src/ui/panel/buildFeatureSummary.ts +288 -0
  232. package/src/ui/panel/filterFeatureSnapshot.ts +51 -0
  233. package/src/ui/panel/tabPersistence.ts +22 -0
  234. package/src/ui/theme/colors.ts +7 -0
  235. package/src/utils/DaemonClient.ts +33 -5
  236. package/src/utils/SessionManager.ts +174 -0
  237. package/src/utils/StorageAdapter.ts +135 -0
  238. package/src/utils/createChannelFeature.ts +28 -6
  239. package/src/utils/createDebugTab.ts +32 -0
  240. package/src/utils/createPersistedObservableStore.ts +18 -10
  241. package/src/utils/debugPreferences.ts +38 -8
  242. package/src/utils/deviceReport.ts +5 -1
  243. package/src/utils/logRuntime.ts +39 -0
  244. package/app.plugin.js +0 -51
  245. package/dev-client.js +0 -3
  246. package/lib/commonjs/ui/panel/FeatureTabBar.js +0 -182
  247. package/lib/commonjs/ui/panel/FeatureTabBar.js.map +0 -1
  248. package/lib/module/ui/panel/FeatureTabBar.js +0 -177
  249. package/lib/module/ui/panel/FeatureTabBar.js.map +0 -1
  250. package/lib/typescript/src/ui/panel/FeatureTabBar.d.ts +0 -13
  251. package/lib/typescript/src/ui/panel/FeatureTabBar.d.ts.map +0 -1
  252. package/scripts/bundle/android.js +0 -101
  253. package/scripts/bundle/cli.js +0 -57
  254. package/scripts/bundle/doctor.js +0 -38
  255. package/scripts/bundle/ios.js +0 -179
  256. package/scripts/bundle/setup.js +0 -39
  257. package/scripts/debug-bundle.gradle +0 -147
  258. 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', '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, 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,12 +22,15 @@ 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';
25
26
 
26
27
  // Hooks
27
28
  export { useNavigationLogger } from './features/navigation/useNavigationLogger';
28
29
 
29
30
  // Utilities
30
31
  export { safeStringify } from './utils/safeStringify';
32
+ export { createDebugTab } from './utils/createDebugTab';
33
+ export type { CreateDebugTabOptions } from './utils/createDebugTab';
31
34
  export { copyToComputer, logToComputer, fmt } from './utils/copyToComputer';
32
35
  export type { CopyResult, CopyOptions, CopyMethod } from './utils/copyToComputer';
33
36
  export { createDebugDeviceReport } from './utils/deviceReport';
@@ -45,6 +48,16 @@ export type {
45
48
  ReportToDaemonOptions,
46
49
  } from './utils/DaemonClient';
47
50
  export { getDefaultDaemonEndpoint } from './utils/DaemonClient';
51
+ export {
52
+ createDefaultLogStorage,
53
+ MemoryStorageAdapter,
54
+ } from './utils/StorageAdapter';
55
+ export type { StorageAdapter } from './utils/StorageAdapter';
56
+ export type {
57
+ LogFeatureKey,
58
+ LogSession,
59
+ SessionManagerOptions,
60
+ } from './utils/SessionManager';
48
61
 
49
62
  // Types
50
63
  export type {
@@ -10,7 +10,8 @@ export type BuiltInFeatureName =
10
10
  | 'track'
11
11
  | 'environment'
12
12
  | 'clipboard'
13
- | 'devConnect';
13
+ | 'devConnect'
14
+ | 'sessionHistory';
14
15
 
15
16
  export interface DebugFeatureRenderProps<TSnapshot = unknown> {
16
17
  snapshot: TSnapshot;
@@ -28,3 +28,13 @@ export type {
28
28
  ThirdPartyLib,
29
29
  ThirdPartyLibAction,
30
30
  } from './thirdPartyLibs';
31
+
32
+ export type {
33
+ StorageAdapter,
34
+ } from '../utils/StorageAdapter';
35
+
36
+ export type {
37
+ LogFeatureKey,
38
+ LogSession,
39
+ SessionManagerOptions,
40
+ } from '../utils/SessionManager';
@@ -3,7 +3,7 @@ import { DebugToolkitProvider } from '../core/DebugToolkitProvider';
3
3
  import { initializeDebugToolkit } from '../core/initialize';
4
4
  import type { FeatureConfigs } from '../core/initialize';
5
5
  import { useNavigationLogger } from '../features/navigation/useNavigationLogger';
6
- import type { EnvironmentConfig, NavigationContainerRef } from '../types';
6
+ import type { AnyDebugFeature, EnvironmentConfig, NavigationContainerRef } from '../types';
7
7
 
8
8
  // --- Types ---
9
9
 
@@ -14,6 +14,8 @@ export interface DebugViewProps {
14
14
  * Set to `false` to disable a feature.
15
15
  */
16
16
  features?: Partial<FeatureConfigs>;
17
+ /** Custom tabs/features appended after built-in features. */
18
+ customFeatures?: AnyDebugFeature[];
17
19
  /** Navigation container ref for route tracking. */
18
20
  navigationRef?: React.RefObject<NavigationContainerRef | null>;
19
21
  /** Environment configs for runtime host switching. */
@@ -38,6 +40,7 @@ function NavigationLoggerInner({
38
40
  export function DebugView({
39
41
  children,
40
42
  features,
43
+ customFeatures,
41
44
  navigationRef,
42
45
  environments,
43
46
  enabled,
@@ -54,6 +57,7 @@ export function DebugView({
54
57
  track: true,
55
58
  clipboard: true,
56
59
  devConnect: true,
60
+ sessionHistory: true,
57
61
  ...features,
58
62
  };
59
63
 
@@ -66,6 +70,7 @@ export function DebugView({
66
70
  let cancelled = false;
67
71
  initializeDebugToolkit({
68
72
  features: resolvedFeatures,
73
+ customFeatures,
69
74
  enabled,
70
75
  }).then((toolkit) => {
71
76
  if (!cancelled) {
@@ -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,127 @@
1
+ import React from 'react';
2
+ import { View, Text, Pressable, 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
+ }
17
+
18
+ export function FeatureIntroCard({
19
+ title,
20
+ summary,
21
+ filterBad,
22
+ onFilterBad,
23
+ }: FeatureIntroCardProps) {
24
+ const {
25
+ statusLabel,
26
+ statusColor,
27
+ supportsBadFilter,
28
+ } = summary;
29
+
30
+ return (
31
+ <View style={styles.card}>
32
+ <View style={styles.titleRow}>
33
+ <Text style={styles.title} numberOfLines={1}>{title}</Text>
34
+ {statusLabel && (
35
+ <View style={[styles.statusChip, statusColor && { backgroundColor: hexWithAlpha(statusColor, '18') }]}>
36
+ <Text style={[styles.statusText, statusColor && { color: statusColor }]} numberOfLines={1}>
37
+ {statusLabel}
38
+ </Text>
39
+ </View>
40
+ )}
41
+ </View>
42
+ {supportsBadFilter && (
43
+ <View style={styles.actionRow}>
44
+ <Pressable
45
+ style={[styles.chip, !filterBad && styles.chipActive]}
46
+ onPress={() => onFilterBad(false)}
47
+ >
48
+ <Text style={[styles.chipText, !filterBad && styles.chipTextActive]}>All</Text>
49
+ </Pressable>
50
+ {supportsBadFilter && (
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
+ )}
58
+ </View>
59
+ )}
60
+ </View>
61
+ );
62
+ }
63
+
64
+ const styles = StyleSheet.create({
65
+ card: {
66
+ paddingHorizontal: 14,
67
+ paddingVertical: 10,
68
+ borderBottomWidth: StyleSheet.hairlineWidth,
69
+ borderBottomColor: Colors.border,
70
+ backgroundColor: Colors.background,
71
+ },
72
+ titleRow: {
73
+ flexDirection: 'row',
74
+ alignItems: 'center',
75
+ gap: 8,
76
+ },
77
+ title: {
78
+ fontSize: 17,
79
+ fontWeight: '700',
80
+ color: Colors.text,
81
+ flex: 1,
82
+ },
83
+ statusChip: {
84
+ paddingHorizontal: 8,
85
+ paddingVertical: 2,
86
+ borderRadius: 8,
87
+ backgroundColor: Colors.signalDefaultBg,
88
+ },
89
+ statusText: {
90
+ fontSize: 11,
91
+ fontWeight: '700',
92
+ color: Colors.textSecondary,
93
+ },
94
+ actionRow: {
95
+ flexDirection: 'row',
96
+ gap: 6,
97
+ marginTop: 8,
98
+ },
99
+ chip: {
100
+ height: 26,
101
+ paddingHorizontal: 12,
102
+ justifyContent: 'center',
103
+ borderRadius: 13,
104
+ borderWidth: 1,
105
+ borderColor: Colors.border,
106
+ backgroundColor: Colors.surface,
107
+ },
108
+ chipActive: {
109
+ backgroundColor: Colors.text,
110
+ borderColor: Colors.text,
111
+ },
112
+ chipBadActive: {
113
+ backgroundColor: Colors.error,
114
+ borderColor: Colors.error,
115
+ },
116
+ chipText: {
117
+ fontSize: 11,
118
+ fontWeight: '700',
119
+ color: Colors.textSecondary,
120
+ },
121
+ chipTextActive: {
122
+ color: '#fff',
123
+ },
124
+ chipTextBad: {
125
+ color: '#fff',
126
+ },
127
+ });
@@ -0,0 +1,165 @@
1
+ import React from 'react';
2
+ import { View, Text, StyleSheet, ScrollView, Pressable } from 'react-native';
3
+ import { Colors } from '../theme/colors';
4
+
5
+ // ─── Label Model ──────────────────────────────────────
6
+
7
+ const SHORT_LABEL_MAP: Record<string, string> = {
8
+ network: 'network',
9
+ console: 'console',
10
+ native: 'native',
11
+ navigation: 'nav',
12
+ zustand: 'zustand',
13
+ track: 'track',
14
+ clipboard: 'clip',
15
+ environment: 'env',
16
+ devConnect: 'dev',
17
+ sessionHistory: 'session',
18
+ thirdPartyLibs: 'libs',
19
+ };
20
+
21
+ export function shortLabelForFeature(label: string, id: string): string {
22
+ const mapped = SHORT_LABEL_MAP[id];
23
+ if (mapped) return mapped;
24
+ const trimmed = label.trim();
25
+ return trimmed.toLowerCase().slice(0, 7);
26
+ }
27
+
28
+ // ─── Rail Component ───────────────────────────────────
29
+
30
+ export interface RailItem {
31
+ id: string;
32
+ label: string;
33
+ dotColor?: string | null;
34
+ count?: number;
35
+ }
36
+
37
+ interface FeatureRailProps {
38
+ items: RailItem[];
39
+ activeIndex: number;
40
+ onSelectTab: (index: number) => void;
41
+ }
42
+
43
+ export function FeatureRail({ items, activeIndex, onSelectTab }: FeatureRailProps) {
44
+ return (
45
+ <View style={styles.rail}>
46
+ <ScrollView
47
+ showsVerticalScrollIndicator={false}
48
+ contentContainerStyle={styles.scrollContent}
49
+ >
50
+ {items.map((item, index) => {
51
+ const isActive = index === activeIndex;
52
+ const short = shortLabelForFeature(item.label, item.id);
53
+ const dotColor = item.dotColor ?? null;
54
+ const hasCount = item.count != null && item.count > 0;
55
+ return (
56
+ <Pressable
57
+ key={item.id}
58
+ onPress={() => onSelectTab(index)}
59
+ style={[styles.item, isActive && styles.activeItem]}
60
+ accessibilityRole="tab"
61
+ accessibilityLabel={item.label}
62
+ accessibilityState={{ selected: isActive }}
63
+ >
64
+ {isActive && <View style={styles.activeBar} />}
65
+ <Text
66
+ style={[styles.itemName, isActive && styles.activeItemName]}
67
+ numberOfLines={1}
68
+ >
69
+ {short}
70
+ </Text>
71
+ <View style={styles.itemMeta}>
72
+ {dotColor && (
73
+ <View style={[styles.dot, { backgroundColor: dotColor }]} />
74
+ )}
75
+ {hasCount && (
76
+ <View style={styles.countPill}>
77
+ <Text style={styles.countText}>{item.count}</Text>
78
+ </View>
79
+ )}
80
+ </View>
81
+ </Pressable>
82
+ );
83
+ })}
84
+ </ScrollView>
85
+ </View>
86
+ );
87
+ }
88
+
89
+ const RAIL_WIDTH = 80;
90
+
91
+ const styles = StyleSheet.create({
92
+ rail: {
93
+ width: RAIL_WIDTH,
94
+ backgroundColor: Colors.railBackground,
95
+ borderRightWidth: StyleSheet.hairlineWidth,
96
+ borderRightColor: Colors.panelDivider,
97
+ },
98
+ scrollContent: {
99
+ paddingVertical: 6,
100
+ paddingHorizontal: 6,
101
+ gap: 3,
102
+ },
103
+ item: {
104
+ minHeight: 56,
105
+ borderRadius: 8,
106
+ justifyContent: 'center',
107
+ alignItems: 'center',
108
+ paddingVertical: 8,
109
+ paddingHorizontal: 4,
110
+ position: 'relative',
111
+ overflow: 'hidden',
112
+ },
113
+ activeItem: {
114
+ backgroundColor: Colors.surface,
115
+ elevation: 2,
116
+ shadowColor: '#000',
117
+ shadowOffset: { width: 0, height: 2 },
118
+ shadowOpacity: 0.06,
119
+ shadowRadius: 4,
120
+ },
121
+ activeBar: {
122
+ position: 'absolute',
123
+ left: 0,
124
+ top: 10,
125
+ bottom: 10,
126
+ width: 3,
127
+ borderRadius: 1.5,
128
+ backgroundColor: Colors.primary,
129
+ },
130
+ itemName: {
131
+ fontSize: 9,
132
+ fontWeight: '700',
133
+ color: Colors.textSecondary,
134
+ letterSpacing: 0,
135
+ },
136
+ activeItemName: {
137
+ color: Colors.text,
138
+ fontWeight: '800',
139
+ },
140
+ itemMeta: {
141
+ marginTop: 4,
142
+ flexDirection: 'row',
143
+ alignItems: 'center',
144
+ gap: 3,
145
+ },
146
+ dot: {
147
+ width: 6,
148
+ height: 6,
149
+ borderRadius: 3,
150
+ },
151
+ countPill: {
152
+ minWidth: 18,
153
+ height: 14,
154
+ borderRadius: 7,
155
+ backgroundColor: Colors.background,
156
+ paddingHorizontal: 4,
157
+ alignItems: 'center',
158
+ justifyContent: 'center',
159
+ },
160
+ countText: {
161
+ fontSize: 8,
162
+ fontWeight: '800',
163
+ color: Colors.textSecondary,
164
+ },
165
+ });