react-native-debug-toolkit 3.2.5 → 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.
@@ -17,6 +17,7 @@ import com.facebook.react.bridge.UiThreadUtil;
17
17
  import com.facebook.react.bridge.WritableMap;
18
18
 
19
19
  import java.lang.reflect.Method;
20
+ import java.lang.reflect.Proxy;
20
21
  import java.net.Inet4Address;
21
22
  import java.net.InetAddress;
22
23
  import java.net.NetworkInterface;
@@ -24,7 +25,9 @@ import java.util.Enumeration;
24
25
 
25
26
  public class DebugToolkitDevConnectModule extends ReactContextBaseJavaModule {
26
27
  private static final String MODULE_NAME = "DebugToolkitDevConnect";
28
+ private static final String BUNDLE_ROOT = "index";
27
29
  private static final String DEBUG_SERVER_HOST_KEY = "debug_http_host";
30
+ private static final String KOTLIN_FUNCTION1_CLASS = "kotlin.jvm.functions.Function1";
28
31
  private static final String APPLY_RELOAD_REASON = "DebugToolkit DevConnect Metro host changed";
29
32
  private static final String RESET_RELOAD_REASON = "DebugToolkit DevConnect Metro host reset";
30
33
 
@@ -69,6 +72,46 @@ public class DebugToolkitDevConnectModule extends ReactContextBaseJavaModule {
69
72
  setter.invoke(packagerConnectionSettings, hostPort);
70
73
  }
71
74
 
75
+ private boolean setReactHostBundleSource(Object reactHost, String hostPort) throws Exception {
76
+ if (hostPort.length() == 0) {
77
+ return false;
78
+ }
79
+
80
+ try {
81
+ Class<?> function1Class = Class.forName(KOTLIN_FUNCTION1_CLASS);
82
+ Method setBundleSourceMethod = reactHost.getClass().getMethod(
83
+ "setBundleSource",
84
+ String.class,
85
+ String.class,
86
+ function1Class
87
+ );
88
+ Object queryMapper = Proxy.newProxyInstance(
89
+ function1Class.getClassLoader(),
90
+ new Class<?>[] { function1Class },
91
+ (proxy, method, args) -> {
92
+ String methodName = method.getName();
93
+ if ("invoke".equals(methodName)) {
94
+ return args != null && args.length > 0 ? args[0] : null;
95
+ }
96
+ if ("toString".equals(methodName)) {
97
+ return "DebugToolkitIdentityQueryMapper";
98
+ }
99
+ if ("hashCode".equals(methodName)) {
100
+ return System.identityHashCode(proxy);
101
+ }
102
+ if ("equals".equals(methodName)) {
103
+ return proxy == (args != null && args.length > 0 ? args[0] : null);
104
+ }
105
+ return null;
106
+ }
107
+ );
108
+ setBundleSourceMethod.invoke(reactHost, hostPort, BUNDLE_ROOT, queryMapper);
109
+ return true;
110
+ } catch (ClassNotFoundException | NoSuchMethodException ignored) {
111
+ return false;
112
+ }
113
+ }
114
+
72
115
  private boolean triggerDevSupportReload(
73
116
  @Nullable Object devSupportManager,
74
117
  String hostPort
@@ -98,6 +141,10 @@ public class DebugToolkitDevConnectModule extends ReactContextBaseJavaModule {
98
141
  return false;
99
142
  }
100
143
 
144
+ if (setReactHostBundleSource(reactHost, hostPort)) {
145
+ return true;
146
+ }
147
+
101
148
  if (triggerDevSupportReload(callGetter(reactHost, "getDevSupportManager"), hostPort)) {
102
149
  return true;
103
150
  }
@@ -2,6 +2,7 @@
2
2
  #import <React/RCTBundleManager.h>
3
3
  #import <React/RCTBridgeModule.h>
4
4
  #import <React/RCTBundleURLProvider.h>
5
+ #import <React/RCTDefines.h>
5
6
  #import <React/RCTReloadCommand.h>
6
7
  #include <ifaddrs.h>
7
8
  #include <arpa/inet.h>
@@ -29,10 +30,13 @@ RCT_EXPORT_MODULE(DebugToolkitDevConnect)
29
30
  resolve:(RCTPromiseResolveBlock)resolve
30
31
  {
31
32
  dispatch_async(dispatch_get_main_queue(), ^{
32
- if (bundleURL) {
33
- if (self->_bundleManager) {
33
+ if (self->_bundleManager) {
34
+ if (bundleURL) {
34
35
  self->_bundleManager.bundleURL = bundleURL;
36
+ } else {
37
+ [self->_bundleManager resetBundleURL];
35
38
  }
39
+ } else {
36
40
  RCTReloadCommandSetBundleURL(bundleURL);
37
41
  }
38
42
  resolve(result ?: [NSNull null]);
@@ -56,11 +60,44 @@ RCT_EXPORT_METHOD(applyMetroHost:(NSString *)hostPort
56
60
  return;
57
61
  }
58
62
 
59
- [RCTBundleURLProvider sharedSettings].jsLocation = hostPort;
60
- NSURL *bundleURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:DebugToolkitBundleRoot];
63
+ RCTBundleURLProvider *settings = [RCTBundleURLProvider sharedSettings];
64
+ NSRange separator = [hostPort rangeOfString:@":" options:NSBackwardsSearch];
65
+ NSString *host = separator.location == NSNotFound ? hostPort : [hostPort substringToIndex:separator.location];
66
+ NSString *port = separator.location == NSNotFound ? @"" : [hostPort substringFromIndex:separator.location + 1];
67
+
68
+ if (host.length == 0 && port.length == 0) {
69
+ [self resetMetroHost:resolve rejecter:reject];
70
+ return;
71
+ }
72
+
73
+ NSNumberFormatter *formatter = [NSNumberFormatter new];
74
+ formatter.numberStyle = NSNumberFormatterDecimalStyle;
75
+ NSNumber *portNumber = [formatter numberFromString:port];
76
+ if (portNumber == nil) {
77
+ portNumber = [NSNumber numberWithInt:RCT_METRO_PORT];
78
+ }
79
+
80
+ NSString *normalizedHostPort = [NSString stringWithFormat:@"%@:%d", host, portNumber.intValue];
81
+ settings.jsLocation = normalizedHostPort;
82
+
83
+ NSURL *bundleURL = nil;
84
+ if (DebugToolkitBundleRoot.length == 0) {
85
+ if (_bundleManager) {
86
+ [_bundleManager resetBundleURL];
87
+ bundleURL = _bundleManager.bundleURL;
88
+ }
89
+ } else {
90
+ bundleURL = [settings jsBundleURLForBundleRoot:DebugToolkitBundleRoot];
91
+ }
92
+
93
+ NSMutableDictionary *result = [@{ @"hostPort" : normalizedHostPort } mutableCopy];
94
+ if (bundleURL.absoluteString) {
95
+ result[@"bundleURL"] = bundleURL.absoluteString;
96
+ }
97
+
61
98
  [self applyBundleURL:bundleURL
62
- reason:@"DebugToolkit DevConnect Metro host changed"
63
- result:@{ @"hostPort" : hostPort }
99
+ reason:@"Dev menu - apply changes"
100
+ result:result
64
101
  resolve:resolve];
65
102
  }
66
103
 
@@ -70,7 +107,7 @@ RCT_EXPORT_METHOD(resetMetroHost:(RCTPromiseResolveBlock)resolve
70
107
  [[RCTBundleURLProvider sharedSettings] resetToDefaults];
71
108
  NSURL *bundleURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForFallbackExtension:nil];
72
109
  [self applyBundleURL:bundleURL
73
- reason:@"DebugToolkit DevConnect Metro host reset"
110
+ reason:@"Dev menu - reset to default"
74
111
  result:[NSNull null]
75
112
  resolve:resolve];
76
113
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-debug-toolkit",
3
- "version": "3.2.5",
3
+ "version": "3.2.6",
4
4
  "description": "A local-first React Native debug toolkit with Web Console, HTTP API, and MCP support for AI-readable app logs",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",