react-native-debug-toolkit 3.2.4 → 3.2.6

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 (25) hide show
  1. package/android/src/main/java/com/reactnativedebugtoolkit/DebugToolkitDevConnectModule.java +94 -12
  2. package/ios/DebugToolkitDevConnect.mm +69 -20
  3. package/lib/commonjs/features/devConnect/DevConnectTab.js +91 -11
  4. package/lib/commonjs/features/devConnect/DevConnectTab.js.map +1 -1
  5. package/lib/commonjs/features/devConnect/devConnectPreferences.js +6 -2
  6. package/lib/commonjs/features/devConnect/devConnectPreferences.js.map +1 -1
  7. package/lib/commonjs/features/devConnect/index.js +11 -2
  8. package/lib/commonjs/features/devConnect/index.js.map +1 -1
  9. package/lib/module/features/devConnect/DevConnectTab.js +92 -12
  10. package/lib/module/features/devConnect/DevConnectTab.js.map +1 -1
  11. package/lib/module/features/devConnect/devConnectPreferences.js +6 -2
  12. package/lib/module/features/devConnect/devConnectPreferences.js.map +1 -1
  13. package/lib/module/features/devConnect/index.js +11 -2
  14. package/lib/module/features/devConnect/index.js.map +1 -1
  15. package/lib/typescript/src/features/devConnect/DevConnectTab.d.ts +1 -1
  16. package/lib/typescript/src/features/devConnect/DevConnectTab.d.ts.map +1 -1
  17. package/lib/typescript/src/features/devConnect/devConnectPreferences.d.ts.map +1 -1
  18. package/lib/typescript/src/features/devConnect/index.d.ts.map +1 -1
  19. package/lib/typescript/src/features/devConnect/types.d.ts +4 -0
  20. package/lib/typescript/src/features/devConnect/types.d.ts.map +1 -1
  21. package/package.json +1 -1
  22. package/src/features/devConnect/DevConnectTab.tsx +103 -12
  23. package/src/features/devConnect/devConnectPreferences.ts +7 -2
  24. package/src/features/devConnect/index.ts +13 -2
  25. package/src/features/devConnect/types.ts +8 -0
@@ -30,12 +30,13 @@ import {
30
30
  parseComputerTarget,
31
31
  } from './devConnectUtils';
32
32
  import {
33
+ saveComputerHost,
33
34
  saveComputerTarget,
34
35
  saveDaemonPort,
35
36
  saveMetroPort,
36
37
  } from './devConnectPreferences';
37
38
  import { applyMetroBundle, resetMetroBundle } from './nativeDevConnect';
38
- import type { DevConnectState } from './types';
39
+ import type { DevConnectFeatureControls, DevConnectSettingsPatch, DevConnectState } from './types';
39
40
 
40
41
  const CONNECTION_TIMEOUT_MS = 2000;
41
42
 
@@ -61,7 +62,7 @@ function describeMetroFailure(result: { reason: string; error?: string }): strin
61
62
  return result.error ? `Metro switch failed: ${result.error}` : 'Metro switch failed.';
62
63
  }
63
64
 
64
- export function DevConnectTab({ snapshot }: DebugFeatureRenderProps<DevConnectState>) {
65
+ export function DevConnectTab({ snapshot, feature }: DebugFeatureRenderProps<DevConnectState>) {
65
66
  const inputRef = useRef<TextInput>(null);
66
67
  const [computerHost, setComputerHost] = useState(snapshot.computerHost);
67
68
  const [metroPort, setMetroPort] = useState(snapshot.metroPort);
@@ -74,13 +75,26 @@ export function DevConnectTab({ snapshot }: DebugFeatureRenderProps<DevConnectSt
74
75
 
75
76
  const isSim = snapshot.isSimulator;
76
77
 
78
+ const updateFeatureSettings = useCallback((patch: DevConnectSettingsPatch) => {
79
+ (feature as unknown as DevConnectFeatureControls).updateSettings?.(patch);
80
+ }, [feature]);
81
+
77
82
  useEffect(() => {
78
83
  setComputerHost(snapshot.computerHost);
84
+ }, [snapshot.computerHost]);
85
+
86
+ useEffect(() => {
79
87
  setMetroPort(snapshot.metroPort);
88
+ }, [snapshot.metroPort]);
89
+
90
+ useEffect(() => {
80
91
  setDaemonPort(snapshot.daemonPort);
92
+ }, [snapshot.daemonPort]);
93
+
94
+ useEffect(() => {
81
95
  setStreaming(snapshot.streaming);
82
96
  setSyncState(snapshot.streaming ? 'running' : 'idle');
83
- }, [snapshot.computerHost, snapshot.daemonPort, snapshot.metroPort, snapshot.streaming]);
97
+ }, [snapshot.streaming]);
84
98
 
85
99
  const metroHost = isSim ? getSimulatorMetroHost() : computerHost;
86
100
  const metroTarget = useMemo(
@@ -97,29 +111,97 @@ export function DevConnectTab({ snapshot }: DebugFeatureRenderProps<DevConnectSt
97
111
  const target = parseComputerTarget(value);
98
112
  if (target) {
99
113
  setMetroPort(target.metroPort);
100
- saveComputerTarget(value).catch(() => {});
114
+ saveComputerTarget(value)
115
+ .then((savedTarget) => {
116
+ if (savedTarget) {
117
+ updateFeatureSettings({
118
+ computerHost: savedTarget.computerHost,
119
+ metroPort: savedTarget.metroPort,
120
+ });
121
+ }
122
+ })
123
+ .catch(() => {});
101
124
  }
102
125
  setSyncState((prev) => (prev === 'failed' ? 'idle' : prev));
103
126
  setMessage(null);
104
- }, []);
127
+ }, [updateFeatureSettings]);
105
128
 
106
129
  const handleMetroPortChange = useCallback((value: string) => {
107
130
  setMetroPort(value);
108
131
  const normalized = normalizePort(value);
109
132
  if (normalized) {
110
- saveMetroPort(normalized).catch(() => {});
133
+ saveMetroPort(normalized)
134
+ .then(() => updateFeatureSettings({ metroPort: normalized }))
135
+ .catch(() => {});
111
136
  }
112
137
  setMessage(null);
113
- }, []);
138
+ }, [updateFeatureSettings]);
114
139
 
115
140
  const handleDaemonPortChange = useCallback((value: string) => {
116
141
  setDaemonPort(value);
117
142
  const normalized = normalizePort(value);
118
143
  if (normalized) {
119
- saveDaemonPort(normalized).catch(() => {});
144
+ saveDaemonPort(normalized)
145
+ .then(() => updateFeatureSettings({ daemonPort: normalized }))
146
+ .catch(() => {});
120
147
  }
121
148
  setMessage(null);
122
- }, []);
149
+ }, [updateFeatureSettings]);
150
+
151
+ const persistConnectionSettings = useCallback(async (): Promise<boolean> => {
152
+ const normalizedDaemonPort = normalizePort(daemonPort);
153
+ if (!normalizedDaemonPort) {
154
+ setMessage('Enter a valid desktop logs port.');
155
+ return false;
156
+ }
157
+
158
+ const patch: DevConnectSettingsPatch = { daemonPort: normalizedDaemonPort };
159
+ const writes: Array<Promise<unknown>> = [saveDaemonPort(normalizedDaemonPort)];
160
+ setDaemonPort(normalizedDaemonPort);
161
+
162
+ if (!isSim) {
163
+ const normalizedHost = normalizeComputerHost(computerHost);
164
+ if (!normalizedHost) {
165
+ setMessage('Enter your computer IP first.');
166
+ return false;
167
+ }
168
+ patch.computerHost = normalizedHost;
169
+ writes.push(saveComputerHost(normalizedHost));
170
+ setComputerHost(normalizedHost);
171
+ }
172
+
173
+ const normalizedMetroPort = normalizePort(metroPort);
174
+ if (normalizedMetroPort) {
175
+ patch.metroPort = normalizedMetroPort;
176
+ writes.push(saveMetroPort(normalizedMetroPort));
177
+ setMetroPort(normalizedMetroPort);
178
+ }
179
+
180
+ await Promise.all(writes);
181
+ updateFeatureSettings(patch);
182
+ return true;
183
+ }, [computerHost, daemonPort, isSim, metroPort, updateFeatureSettings]);
184
+
185
+ const persistMetroSettings = useCallback(async (): Promise<boolean> => {
186
+ if (!metroTarget) {
187
+ setMessage('Enter a valid computer IP and Metro port.');
188
+ return false;
189
+ }
190
+
191
+ const patch: DevConnectSettingsPatch = { metroPort: metroTarget.port };
192
+ const writes: Array<Promise<unknown>> = [saveMetroPort(metroTarget.port)];
193
+ setMetroPort(metroTarget.port);
194
+
195
+ if (!isSim) {
196
+ patch.computerHost = metroTarget.host;
197
+ writes.push(saveComputerTarget(metroTarget.hostPort));
198
+ setComputerHost(metroTarget.host);
199
+ }
200
+
201
+ await Promise.all(writes);
202
+ updateFeatureSettings(patch);
203
+ return true;
204
+ }, [isSim, metroTarget, updateFeatureSettings]);
123
205
 
124
206
  const validateSettings = useCallback((): boolean => {
125
207
  if (!isSim && !normalizeComputerHost(computerHost)) {
@@ -162,6 +244,9 @@ export function DevConnectTab({ snapshot }: DebugFeatureRenderProps<DevConnectSt
162
244
  if (!validateSettings()) {
163
245
  return;
164
246
  }
247
+ if (!(await persistConnectionSettings())) {
248
+ return;
249
+ }
165
250
 
166
251
  const daemonOptions = configureDaemon();
167
252
  setMessage('Checking desktop connection...');
@@ -200,12 +285,15 @@ export function DevConnectTab({ snapshot }: DebugFeatureRenderProps<DevConnectSt
200
285
  },
201
286
  });
202
287
  setStreaming(true);
203
- }, [configureDaemon, streaming, validateSettings]);
288
+ }, [configureDaemon, persistConnectionSettings, streaming, validateSettings]);
204
289
 
205
290
  const sendOnce = useCallback(async () => {
206
291
  if (!validateSettings()) {
207
292
  return;
208
293
  }
294
+ if (!(await persistConnectionSettings())) {
295
+ return;
296
+ }
209
297
 
210
298
  const daemonOptions = configureDaemon();
211
299
  setSending(true);
@@ -236,7 +324,7 @@ export function DevConnectTab({ snapshot }: DebugFeatureRenderProps<DevConnectSt
236
324
  } finally {
237
325
  setSending(false);
238
326
  }
239
- }, [configureDaemon, validateSettings]);
327
+ }, [configureDaemon, persistConnectionSettings, validateSettings]);
240
328
 
241
329
  const applyRemoteBundle = useCallback(async () => {
242
330
  if (!metroTarget) {
@@ -251,6 +339,9 @@ export function DevConnectTab({ snapshot }: DebugFeatureRenderProps<DevConnectSt
251
339
  setMetroBusy(true);
252
340
  setMessage('Checking Metro...');
253
341
  try {
342
+ if (!(await persistMetroSettings())) {
343
+ return;
344
+ }
254
345
  const result = await applyMetroBundle(metroTarget.host, metroTarget.port);
255
346
  if (result.ok) {
256
347
  setMessage(`Using Metro at ${result.hostPort}. Reloading...`);
@@ -260,7 +351,7 @@ export function DevConnectTab({ snapshot }: DebugFeatureRenderProps<DevConnectSt
260
351
  } finally {
261
352
  setMetroBusy(false);
262
353
  }
263
- }, [metroTarget, snapshot.nativeMetroAvailable]);
354
+ }, [metroTarget, persistMetroSettings, snapshot.nativeMetroAvailable]);
264
355
 
265
356
  const resetRemoteBundle = useCallback(async () => {
266
357
  if (!snapshot.nativeMetroAvailable) {
@@ -40,8 +40,13 @@ export async function saveComputerTarget(value: string): Promise<ParsedComputerT
40
40
  }
41
41
 
42
42
  export async function saveComputerHost(value: string): Promise<string | null> {
43
- const target = await saveComputerTarget(value);
44
- return target?.computerHost ?? null;
43
+ const host = normalizeComputerHost(value);
44
+ if (!host) {
45
+ return null;
46
+ }
47
+
48
+ await setPreference(KEYS.computerHost, host);
49
+ return host;
45
50
  }
46
51
 
47
52
  export async function saveMetroPort(value: string): Promise<string | null> {
@@ -5,7 +5,7 @@ import { getDeviceLocalIp, isNativeDevConnectAvailable } from './nativeDevConnec
5
5
  import { isSimulator } from './platformDetect';
6
6
  import { daemonClient } from '../../utils/DaemonClient';
7
7
  import type { DebugFeature, DebugFeatureListener } from '../../types';
8
- import type { DevConnectState } from './types';
8
+ import type { DevConnectFeatureControls, DevConnectSettingsPatch, DevConnectState } from './types';
9
9
 
10
10
  export type { DevConnectState } from './types';
11
11
  export {
@@ -44,7 +44,15 @@ export const createDevConnectFeature = (): DebugFeature<DevConnectState> => {
44
44
  listeners.forEach((listener) => listener());
45
45
  };
46
46
 
47
- return {
47
+ const updateSettings = (patch: DevConnectSettingsPatch) => {
48
+ state = {
49
+ ...state,
50
+ ...patch,
51
+ };
52
+ notify();
53
+ };
54
+
55
+ const feature: DebugFeature<DevConnectState> & DevConnectFeatureControls = {
48
56
  name: 'devConnect',
49
57
  label: 'DevConnect',
50
58
  renderContent: DevConnectTab,
@@ -86,5 +94,8 @@ export const createDevConnectFeature = (): DebugFeature<DevConnectState> => {
86
94
  listeners.delete(listener);
87
95
  };
88
96
  },
97
+ updateSettings,
89
98
  };
99
+
100
+ return feature;
90
101
  };
@@ -7,3 +7,11 @@ export interface DevConnectState {
7
7
  nativeMetroAvailable: boolean;
8
8
  streaming: boolean;
9
9
  }
10
+
11
+ export type DevConnectSettingsPatch = Partial<
12
+ Pick<DevConnectState, 'computerHost' | 'metroPort' | 'daemonPort'>
13
+ >;
14
+
15
+ export interface DevConnectFeatureControls {
16
+ updateSettings?: (patch: DevConnectSettingsPatch) => void;
17
+ }