react-native-debug-toolkit 2.0.0 → 2.1.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 (228) hide show
  1. package/README.md +72 -72
  2. package/README.zh-CN.md +209 -0
  3. package/lib/commonjs/components/ClipboardTab.js +15 -16
  4. package/lib/commonjs/components/ClipboardTab.js.map +1 -1
  5. package/lib/commonjs/components/ConsoleLogTab.js +69 -202
  6. package/lib/commonjs/components/ConsoleLogTab.js.map +1 -1
  7. package/lib/commonjs/components/DebugPanel.js +230 -0
  8. package/lib/commonjs/components/DebugPanel.js.map +1 -0
  9. package/lib/commonjs/components/DebugView.js +66 -0
  10. package/lib/commonjs/components/DebugView.js.map +1 -0
  11. package/lib/commonjs/components/EnvironmentTab.js +22 -23
  12. package/lib/commonjs/components/EnvironmentTab.js.map +1 -1
  13. package/lib/commonjs/components/FeatureTabBar.js +182 -0
  14. package/lib/commonjs/components/FeatureTabBar.js.map +1 -0
  15. package/lib/commonjs/components/FloatIcon.js +187 -0
  16. package/lib/commonjs/components/FloatIcon.js.map +1 -0
  17. package/lib/commonjs/components/FloatPanelView.js +140 -723
  18. package/lib/commonjs/components/FloatPanelView.js.map +1 -1
  19. package/lib/commonjs/components/NavigationLogTab.js +8 -8
  20. package/lib/commonjs/components/NavigationLogTab.js.map +1 -1
  21. package/lib/commonjs/components/NetworkLogTab.js +179 -350
  22. package/lib/commonjs/components/NetworkLogTab.js.map +1 -1
  23. package/lib/commonjs/components/ThirdPartyLibsTab.js +8 -8
  24. package/lib/commonjs/components/ThirdPartyLibsTab.js.map +1 -1
  25. package/lib/commonjs/components/TrackLogTab.js +106 -248
  26. package/lib/commonjs/components/TrackLogTab.js.map +1 -1
  27. package/lib/commonjs/components/ZustandLogTab.js +148 -288
  28. package/lib/commonjs/components/ZustandLogTab.js.map +1 -1
  29. package/lib/commonjs/components/shared/CollapsibleSection.js +4 -4
  30. package/lib/commonjs/components/shared/CollapsibleSection.js.map +1 -1
  31. package/lib/commonjs/components/shared/CopyButton.js +3 -3
  32. package/lib/commonjs/components/shared/CopyButton.js.map +1 -1
  33. package/lib/commonjs/components/shared/LogListScreen.js +174 -0
  34. package/lib/commonjs/components/shared/LogListScreen.js.map +1 -0
  35. package/lib/commonjs/core/DebugToolkit.js +92 -112
  36. package/lib/commonjs/core/DebugToolkit.js.map +1 -1
  37. package/lib/commonjs/core/DebugToolkitProvider.js +30 -28
  38. package/lib/commonjs/core/DebugToolkitProvider.js.map +1 -1
  39. package/lib/commonjs/features/ClipboardFeature.js +6 -2
  40. package/lib/commonjs/features/ClipboardFeature.js.map +1 -1
  41. package/lib/commonjs/features/ConsoleLogFeature.js +66 -49
  42. package/lib/commonjs/features/ConsoleLogFeature.js.map +1 -1
  43. package/lib/commonjs/features/EnvironmentFeature.js +5 -13
  44. package/lib/commonjs/features/EnvironmentFeature.js.map +1 -1
  45. package/lib/commonjs/features/NavigationLogFeature.js +17 -38
  46. package/lib/commonjs/features/NavigationLogFeature.js.map +1 -1
  47. package/lib/commonjs/features/NetworkFeature.js +35 -256
  48. package/lib/commonjs/features/NetworkFeature.js.map +1 -1
  49. package/lib/commonjs/features/TrackFeature.js +17 -38
  50. package/lib/commonjs/features/TrackFeature.js.map +1 -1
  51. package/lib/commonjs/features/ZustandLogFeature.js +21 -38
  52. package/lib/commonjs/features/ZustandLogFeature.js.map +1 -1
  53. package/lib/commonjs/hooks/useNavigationLogger.js.map +1 -1
  54. package/lib/commonjs/index.js +7 -20
  55. package/lib/commonjs/index.js.map +1 -1
  56. package/lib/commonjs/initialize.js +19 -96
  57. package/lib/commonjs/initialize.js.map +1 -1
  58. package/lib/commonjs/interceptors/networkInterceptor.js +466 -0
  59. package/lib/commonjs/interceptors/networkInterceptor.js.map +1 -0
  60. package/lib/commonjs/utils/colors.js +48 -0
  61. package/lib/commonjs/utils/colors.js.map +1 -0
  62. package/lib/commonjs/utils/createChannelFeature.js +48 -0
  63. package/lib/commonjs/utils/createChannelFeature.js.map +1 -0
  64. package/lib/commonjs/utils/layout.js +8 -0
  65. package/lib/commonjs/utils/layout.js.map +1 -0
  66. package/lib/commonjs/utils/urlRewriterRegistry.js +14 -0
  67. package/lib/commonjs/utils/urlRewriterRegistry.js.map +1 -0
  68. package/lib/module/components/ClipboardTab.js +8 -8
  69. package/lib/module/components/ClipboardTab.js.map +1 -1
  70. package/lib/module/components/ConsoleLogTab.js +66 -199
  71. package/lib/module/components/ConsoleLogTab.js.map +1 -1
  72. package/lib/module/components/DebugPanel.js +225 -0
  73. package/lib/module/components/DebugPanel.js.map +1 -0
  74. package/lib/module/components/DebugView.js +61 -0
  75. package/lib/module/components/DebugView.js.map +1 -0
  76. package/lib/module/components/EnvironmentTab.js +3 -3
  77. package/lib/module/components/EnvironmentTab.js.map +1 -1
  78. package/lib/module/components/FeatureTabBar.js +177 -0
  79. package/lib/module/components/FeatureTabBar.js.map +1 -0
  80. package/lib/module/components/FloatIcon.js +182 -0
  81. package/lib/module/components/FloatIcon.js.map +1 -0
  82. package/lib/module/components/FloatPanelView.js +141 -723
  83. package/lib/module/components/FloatPanelView.js.map +1 -1
  84. package/lib/module/components/NavigationLogTab.js +1 -1
  85. package/lib/module/components/NavigationLogTab.js.map +1 -1
  86. package/lib/module/components/NetworkLogTab.js +167 -338
  87. package/lib/module/components/NetworkLogTab.js.map +1 -1
  88. package/lib/module/components/ThirdPartyLibsTab.js +1 -1
  89. package/lib/module/components/ThirdPartyLibsTab.js.map +1 -1
  90. package/lib/module/components/TrackLogTab.js +94 -236
  91. package/lib/module/components/TrackLogTab.js.map +1 -1
  92. package/lib/module/components/ZustandLogTab.js +136 -276
  93. package/lib/module/components/ZustandLogTab.js.map +1 -1
  94. package/lib/module/components/shared/CollapsibleSection.js +1 -1
  95. package/lib/module/components/shared/CollapsibleSection.js.map +1 -1
  96. package/lib/module/components/shared/CopyButton.js +1 -1
  97. package/lib/module/components/shared/CopyButton.js.map +1 -1
  98. package/lib/module/components/shared/LogListScreen.js +169 -0
  99. package/lib/module/components/shared/LogListScreen.js.map +1 -0
  100. package/lib/module/core/DebugToolkit.js +92 -111
  101. package/lib/module/core/DebugToolkit.js.map +1 -1
  102. package/lib/module/core/DebugToolkitProvider.js +31 -29
  103. package/lib/module/core/DebugToolkitProvider.js.map +1 -1
  104. package/lib/module/features/ClipboardFeature.js +6 -2
  105. package/lib/module/features/ClipboardFeature.js.map +1 -1
  106. package/lib/module/features/ConsoleLogFeature.js +65 -49
  107. package/lib/module/features/ConsoleLogFeature.js.map +1 -1
  108. package/lib/module/features/EnvironmentFeature.js +5 -13
  109. package/lib/module/features/EnvironmentFeature.js.map +1 -1
  110. package/lib/module/features/NavigationLogFeature.js +16 -38
  111. package/lib/module/features/NavigationLogFeature.js.map +1 -1
  112. package/lib/module/features/NetworkFeature.js +34 -255
  113. package/lib/module/features/NetworkFeature.js.map +1 -1
  114. package/lib/module/features/TrackFeature.js +16 -38
  115. package/lib/module/features/TrackFeature.js.map +1 -1
  116. package/lib/module/features/ZustandLogFeature.js +22 -38
  117. package/lib/module/features/ZustandLogFeature.js.map +1 -1
  118. package/lib/module/hooks/useNavigationLogger.js.map +1 -1
  119. package/lib/module/index.js +2 -3
  120. package/lib/module/index.js.map +1 -1
  121. package/lib/module/initialize.js +19 -95
  122. package/lib/module/initialize.js.map +1 -1
  123. package/lib/module/interceptors/networkInterceptor.js +460 -0
  124. package/lib/module/interceptors/networkInterceptor.js.map +1 -0
  125. package/lib/module/utils/colors.js +43 -0
  126. package/lib/module/utils/colors.js.map +1 -0
  127. package/lib/module/utils/createChannelFeature.js +44 -0
  128. package/lib/module/utils/createChannelFeature.js.map +1 -0
  129. package/lib/module/utils/layout.js +4 -0
  130. package/lib/module/utils/layout.js.map +1 -0
  131. package/lib/module/utils/urlRewriterRegistry.js +10 -0
  132. package/lib/module/utils/urlRewriterRegistry.js.map +1 -0
  133. package/lib/typescript/src/components/ClipboardTab.d.ts.map +1 -1
  134. package/lib/typescript/src/components/ConsoleLogTab.d.ts.map +1 -1
  135. package/lib/typescript/src/components/DebugPanel.d.ts +9 -0
  136. package/lib/typescript/src/components/DebugPanel.d.ts.map +1 -0
  137. package/lib/typescript/src/components/DebugView.d.ts +19 -0
  138. package/lib/typescript/src/components/DebugView.d.ts.map +1 -0
  139. package/lib/typescript/src/components/EnvironmentTab.d.ts.map +1 -1
  140. package/lib/typescript/src/components/FeatureTabBar.d.ts +13 -0
  141. package/lib/typescript/src/components/FeatureTabBar.d.ts.map +1 -0
  142. package/lib/typescript/src/components/FloatIcon.d.ts +12 -0
  143. package/lib/typescript/src/components/FloatIcon.d.ts.map +1 -0
  144. package/lib/typescript/src/components/FloatPanelView.d.ts +4 -59
  145. package/lib/typescript/src/components/FloatPanelView.d.ts.map +1 -1
  146. package/lib/typescript/src/components/NetworkLogTab.d.ts.map +1 -1
  147. package/lib/typescript/src/components/ThirdPartyLibsTab.d.ts.map +1 -1
  148. package/lib/typescript/src/components/TrackLogTab.d.ts.map +1 -1
  149. package/lib/typescript/src/components/ZustandLogTab.d.ts.map +1 -1
  150. package/lib/typescript/src/components/shared/LogListScreen.d.ts +21 -0
  151. package/lib/typescript/src/components/shared/LogListScreen.d.ts.map +1 -0
  152. package/lib/typescript/src/core/DebugToolkit.d.ts +11 -18
  153. package/lib/typescript/src/core/DebugToolkit.d.ts.map +1 -1
  154. package/lib/typescript/src/core/DebugToolkitProvider.d.ts +2 -5
  155. package/lib/typescript/src/core/DebugToolkitProvider.d.ts.map +1 -1
  156. package/lib/typescript/src/features/ClipboardFeature.d.ts +4 -0
  157. package/lib/typescript/src/features/ClipboardFeature.d.ts.map +1 -1
  158. package/lib/typescript/src/features/ConsoleLogFeature.d.ts +2 -0
  159. package/lib/typescript/src/features/ConsoleLogFeature.d.ts.map +1 -1
  160. package/lib/typescript/src/features/EnvironmentFeature.d.ts.map +1 -1
  161. package/lib/typescript/src/features/NavigationLogFeature.d.ts +2 -0
  162. package/lib/typescript/src/features/NavigationLogFeature.d.ts.map +1 -1
  163. package/lib/typescript/src/features/NetworkFeature.d.ts +7 -20
  164. package/lib/typescript/src/features/NetworkFeature.d.ts.map +1 -1
  165. package/lib/typescript/src/features/TrackFeature.d.ts +2 -0
  166. package/lib/typescript/src/features/TrackFeature.d.ts.map +1 -1
  167. package/lib/typescript/src/features/ZustandLogFeature.d.ts +2 -0
  168. package/lib/typescript/src/features/ZustandLogFeature.d.ts.map +1 -1
  169. package/lib/typescript/src/hooks/useNavigationLogger.d.ts +1 -8
  170. package/lib/typescript/src/hooks/useNavigationLogger.d.ts.map +1 -1
  171. package/lib/typescript/src/index.d.ts +5 -5
  172. package/lib/typescript/src/index.d.ts.map +1 -1
  173. package/lib/typescript/src/initialize.d.ts +3 -22
  174. package/lib/typescript/src/initialize.d.ts.map +1 -1
  175. package/lib/typescript/src/interceptors/networkInterceptor.d.ts +18 -0
  176. package/lib/typescript/src/interceptors/networkInterceptor.d.ts.map +1 -0
  177. package/lib/typescript/src/types/index.d.ts +26 -29
  178. package/lib/typescript/src/types/index.d.ts.map +1 -1
  179. package/lib/typescript/src/utils/colors.d.ts +21 -0
  180. package/lib/typescript/src/utils/colors.d.ts.map +1 -0
  181. package/lib/typescript/src/utils/createChannelFeature.d.ts +18 -0
  182. package/lib/typescript/src/utils/createChannelFeature.d.ts.map +1 -0
  183. package/lib/typescript/src/utils/layout.d.ts +2 -0
  184. package/lib/typescript/src/utils/layout.d.ts.map +1 -0
  185. package/lib/typescript/src/utils/urlRewriterRegistry.d.ts +7 -0
  186. package/lib/typescript/src/utils/urlRewriterRegistry.d.ts.map +1 -0
  187. package/package.json +5 -1
  188. package/src/components/ClipboardTab.tsx +8 -8
  189. package/src/components/ConsoleLogTab.tsx +49 -163
  190. package/src/components/DebugPanel.tsx +215 -0
  191. package/src/components/DebugView.tsx +80 -0
  192. package/src/components/EnvironmentTab.tsx +3 -3
  193. package/src/components/FeatureTabBar.tsx +204 -0
  194. package/src/components/FloatIcon.tsx +171 -0
  195. package/src/components/FloatPanelView.tsx +135 -647
  196. package/src/components/NavigationLogTab.tsx +1 -1
  197. package/src/components/NetworkLogTab.tsx +128 -269
  198. package/src/components/ThirdPartyLibsTab.tsx +3 -3
  199. package/src/components/TrackLogTab.tsx +53 -188
  200. package/src/components/ZustandLogTab.tsx +79 -181
  201. package/src/components/shared/CollapsibleSection.tsx +1 -1
  202. package/src/components/shared/CopyButton.tsx +1 -1
  203. package/src/components/shared/LogListScreen.tsx +164 -0
  204. package/src/core/DebugToolkit.tsx +114 -138
  205. package/src/core/DebugToolkitProvider.tsx +32 -38
  206. package/src/features/ClipboardFeature.ts +6 -2
  207. package/src/features/ConsoleLogFeature.ts +66 -68
  208. package/src/features/EnvironmentFeature.ts +5 -13
  209. package/src/features/NavigationLogFeature.ts +12 -42
  210. package/src/features/NetworkFeature.ts +43 -405
  211. package/src/features/TrackFeature.ts +14 -49
  212. package/src/features/ZustandLogFeature.ts +16 -42
  213. package/src/hooks/useNavigationLogger.ts +1 -6
  214. package/src/index.ts +5 -9
  215. package/src/initialize.ts +28 -120
  216. package/src/interceptors/networkInterceptor.ts +646 -0
  217. package/src/types/index.ts +25 -36
  218. package/src/utils/colors.ts +38 -0
  219. package/src/utils/createChannelFeature.ts +55 -0
  220. package/src/utils/layout.ts +1 -0
  221. package/src/utils/urlRewriterRegistry.ts +10 -0
  222. package/lib/commonjs/utils/constants.js +0 -135
  223. package/lib/commonjs/utils/constants.js.map +0 -1
  224. package/lib/module/utils/constants.js +0 -130
  225. package/lib/module/utils/constants.js.map +0 -1
  226. package/lib/typescript/src/utils/constants.d.ts +0 -96
  227. package/lib/typescript/src/utils/constants.d.ts.map +0 -1
  228. package/src/utils/constants.ts +0 -91
@@ -1,67 +1,76 @@
1
1
  import { ConsoleLogTab } from '../components/ConsoleLogTab';
2
2
  import type { ConsoleLogEntry, DebugFeature } from '../types';
3
- import { createEventChannel } from '../utils/createEventChannel';
4
3
  import { createObservableStore } from '../utils/createObservableStore';
5
4
 
6
- type ConsoleLogPayload = Omit<ConsoleLogEntry, 'id'>;
7
-
8
- const DEFAULT_MAX_LOGS = 200;
9
- const consoleChannel = createEventChannel<ConsoleLogPayload>();
10
- const originalConsole: Partial<Record<ConsoleLogEntry['level'], (...args: unknown[]) => void>> =
11
- {};
12
5
  const LEVELS: ConsoleLogEntry['level'][] = ['log', 'info', 'warn', 'error'];
13
6
 
14
- let consoleCaptureRefCount = 0;
7
+ // ─── Console capture manager (encapsulated mutable state) ──
8
+
9
+ const consoleCapture = (() => {
10
+ const originalMethods: Partial<Record<ConsoleLogEntry['level'], (...args: unknown[]) => void>> = {};
11
+ let refCount = 0;
15
12
 
16
- function stopConsoleCapture(): void {
17
- consoleCaptureRefCount = Math.max(0, consoleCaptureRefCount - 1);
13
+ function stop(): void {
14
+ refCount = Math.max(0, refCount - 1);
15
+ if (refCount > 0) return;
18
16
 
19
- if (consoleCaptureRefCount > 0) {
20
- return;
17
+ LEVELS.forEach((level) => {
18
+ const original = originalMethods[level];
19
+ if (original) {
20
+ console[level] = original;
21
+ delete originalMethods[level];
22
+ }
23
+ });
21
24
  }
22
25
 
23
- LEVELS.forEach((level) => {
24
- const originalMethod = originalConsole[level];
26
+ function isIntercepted(): boolean {
27
+ return LEVELS.some((level) => originalMethods[level] !== undefined);
28
+ }
25
29
 
26
- if (!originalMethod) {
27
- return;
30
+ function start(emit: (entry: ConsoleLogEntry) => void): () => void {
31
+ refCount += 1;
32
+ if (isIntercepted()) {
33
+ return () => { stop(); };
28
34
  }
29
35
 
30
- console[level] = originalMethod;
31
- delete originalConsole[level];
32
- });
33
- }
34
-
35
- function startConsoleCapture(): () => void {
36
- consoleCaptureRefCount += 1;
37
-
38
- if (consoleCaptureRefCount > 1) {
39
- return () => {
40
- stopConsoleCapture();
41
- };
36
+ LEVELS.forEach((level) => {
37
+ originalMethods[level] = console[level];
38
+
39
+ console[level] = (...args: unknown[]) => {
40
+ originalMethods[level]?.apply(console, args);
41
+ if (level === 'log' && typeof args[0] === 'string' && args[0].startsWith('[DebugToolkit:Copy]')) {
42
+ return;
43
+ }
44
+ emit({
45
+ id: '',
46
+ timestamp: Date.now(),
47
+ level,
48
+ data: args,
49
+ });
50
+ };
51
+ });
52
+
53
+ return () => { stop(); };
42
54
  }
43
55
 
44
- LEVELS.forEach((level) => {
45
- originalConsole[level] = console[level];
46
-
47
- console[level] = (...args: unknown[]) => {
48
- originalConsole[level]?.apply(console, args);
49
- // Skip DebugToolkit's own copy-to-computer logs to avoid Console tab noise
50
- if (level === 'log' && typeof args[0] === 'string' && args[0].startsWith('[DebugToolkit:Copy]')) {
51
- return;
52
- }
53
- consoleChannel.emit({
54
- timestamp: Date.now(),
55
- level,
56
- data: args,
56
+ return {
57
+ start,
58
+ reset() {
59
+ LEVELS.forEach((level) => {
60
+ const original = originalMethods[level];
61
+ if (original) {
62
+ console[level] = original;
63
+ delete originalMethods[level];
64
+ }
57
65
  });
58
- };
59
- });
60
-
61
- return () => {
62
- stopConsoleCapture();
66
+ refCount = 0;
67
+ },
63
68
  };
64
- }
69
+ })();
70
+
71
+ // ─── Feature factory ──────────────────────────────────
72
+
73
+ const DEFAULT_MAX_LOGS = 200;
65
74
 
66
75
  export interface ConsoleFeatureConfig {
67
76
  /** Maximum number of console logs to keep (default: 200) */
@@ -73,7 +82,6 @@ export const createConsoleLogFeature = (config?: ConsoleFeatureConfig): DebugFea
73
82
  const logStore = createObservableStore<ConsoleLogEntry>();
74
83
  let nextId = 0;
75
84
  let initialized = false;
76
- let unsubscribeLogs: (() => void) | null = null;
77
85
  let stopCapture: (() => void) | null = null;
78
86
 
79
87
  return {
@@ -81,33 +89,18 @@ export const createConsoleLogFeature = (config?: ConsoleFeatureConfig): DebugFea
81
89
  label: 'Console',
82
90
  renderContent: ConsoleLogTab,
83
91
  setup: () => {
84
- if (initialized) {
85
- return;
86
- }
92
+ if (initialized) return;
87
93
 
88
- unsubscribeLogs = consoleChannel.subscribe((entry) => {
89
- logStore.push(
90
- {
91
- ...entry,
92
- id: String(nextId++),
93
- },
94
- maxLogs,
95
- );
94
+ stopCapture = consoleCapture.start((entry) => {
95
+ logStore.push({ ...entry, id: String(nextId++) }, maxLogs);
96
96
  });
97
- stopCapture = startConsoleCapture();
98
97
  initialized = true;
99
98
  },
100
99
  getData: () => logStore.getData(),
101
- clear: () => {
102
- logStore.clear();
103
- },
100
+ clear: () => { logStore.clear(); },
104
101
  cleanup: () => {
105
- if (!initialized) {
106
- return;
107
- }
102
+ if (!initialized) return;
108
103
 
109
- unsubscribeLogs?.();
110
- unsubscribeLogs = null;
111
104
  stopCapture?.();
112
105
  stopCapture = null;
113
106
  logStore.clear();
@@ -116,3 +109,8 @@ export const createConsoleLogFeature = (config?: ConsoleFeatureConfig): DebugFea
116
109
  subscribe: (listener) => logStore.subscribe(listener),
117
110
  };
118
111
  };
112
+
113
+ /** Reset module-level state for testing */
114
+ export function _resetConsoleForTesting(): void {
115
+ consoleCapture.reset();
116
+ }
@@ -1,7 +1,7 @@
1
1
  import { EnvironmentTab } from '../components/EnvironmentTab';
2
2
  import type { DebugFeature, EnvironmentConfig, EnvironmentState } from '../types';
3
3
  import { createObservableStore } from '../utils/createObservableStore';
4
- import { setUrlRewriter } from './NetworkFeature';
4
+ import { urlRewriter } from '../utils/urlRewriterRegistry';
5
5
 
6
6
  // Lazy AsyncStorage loader
7
7
  type AsyncStorageModule = {
@@ -97,9 +97,9 @@ export const createEnvironmentFeature = (
97
97
  if (initialized) {
98
98
  try {
99
99
  if (envId && environments.length > 0) {
100
- setUrlRewriter(createUrlRewriter());
100
+ urlRewriter.set(createUrlRewriter());
101
101
  } else {
102
- setUrlRewriter(null);
102
+ urlRewriter.set(null);
103
103
  }
104
104
  } catch (err) {
105
105
  if (__DEV__) console.warn('[DebugToolkit] Failed to set URL rewriter:', err);
@@ -144,11 +144,7 @@ export const createEnvironmentFeature = (
144
144
 
145
145
  // Install rewriter if an environment is already selected
146
146
  if (activeEnvironmentId && environments.length > 0) {
147
- try {
148
- setUrlRewriter(createUrlRewriter());
149
- } catch {
150
- // NetworkFeature may not be available
151
- }
147
+ urlRewriter.set(createUrlRewriter());
152
148
  }
153
149
 
154
150
  // Async persistence load (will override if a preference exists)
@@ -161,11 +157,7 @@ export const createEnvironmentFeature = (
161
157
  },
162
158
  cleanup: () => {
163
159
  if (!initialized) return;
164
- try {
165
- setUrlRewriter(null);
166
- } catch (err) {
167
- if (__DEV__) console.warn('[DebugToolkit] Failed to set URL rewriter:', err);
168
- }
160
+ urlRewriter.set(null);
169
161
  activeEnvironmentId = null;
170
162
  currentHostsMap = null;
171
163
  stateStore.clear();
@@ -1,12 +1,11 @@
1
1
  import { NavigationLogTab } from '../components/NavigationLogTab';
2
2
  import type { DebugFeature, NavigationLogEntry } from '../types';
3
3
  import { createEventChannel } from '../utils/createEventChannel';
4
- import { createObservableStore } from '../utils/createObservableStore';
4
+ import { createChannelFeature } from '../utils/createChannelFeature';
5
5
 
6
6
  type NavigationLogPayload = Omit<NavigationLogEntry, 'id'>;
7
7
 
8
- const DEFAULT_MAX_LOGS = 200;
9
- const navigationChannel = createEventChannel<NavigationLogPayload>();
8
+ let navigationChannel = createEventChannel<NavigationLogPayload>();
10
9
 
11
10
  export const addNavigationLog = (
12
11
  action: string,
@@ -32,43 +31,14 @@ export interface NavigationFeatureConfig {
32
31
  maxLogs?: number;
33
32
  }
34
33
 
35
- export const createNavigationLogFeature = (config?: NavigationFeatureConfig): DebugFeature<NavigationLogEntry> => {
36
- const maxLogs = config?.maxLogs ?? DEFAULT_MAX_LOGS;
37
- const logStore = createObservableStore<NavigationLogEntry>();
38
- let nextId = 0;
39
- let unsubscribeLogs: (() => void) | null = null;
40
- let initialized = false;
34
+ export const createNavigationLogFeature = (config?: NavigationFeatureConfig): DebugFeature<NavigationLogEntry> =>
35
+ createChannelFeature(
36
+ () => navigationChannel,
37
+ (payload, id) => ({ ...payload, id }),
38
+ { name: 'navigation', label: 'Navigation', renderContent: NavigationLogTab, maxLogs: config?.maxLogs },
39
+ );
41
40
 
42
- return {
43
- name: 'navigation',
44
- label: 'Navigation',
45
- renderContent: NavigationLogTab,
46
- setup: () => {
47
- if (initialized) {
48
- return;
49
- }
50
-
51
- unsubscribeLogs = navigationChannel.subscribe((entry) => {
52
- logStore.push(
53
- {
54
- ...entry,
55
- id: String(nextId++),
56
- },
57
- maxLogs,
58
- );
59
- });
60
- initialized = true;
61
- },
62
- getData: () => logStore.getData(),
63
- clear: () => {
64
- logStore.clear();
65
- },
66
- cleanup: () => {
67
- unsubscribeLogs?.();
68
- unsubscribeLogs = null;
69
- logStore.clear();
70
- initialized = false;
71
- },
72
- subscribe: (listener) => logStore.subscribe(listener),
73
- };
74
- };
41
+ /** Reset module-level state for testing */
42
+ export function _resetNavigationForTesting(): void {
43
+ navigationChannel = createEventChannel<NavigationLogPayload>();
44
+ }