react-native-debug-toolkit 3.2.5 → 3.2.7
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>
|
|
@@ -23,21 +24,9 @@ RCT_EXPORT_MODULE(DebugToolkitDevConnect)
|
|
|
23
24
|
return NO;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
- (
|
|
27
|
-
reason:(NSString *)reason
|
|
28
|
-
result:(id)result
|
|
29
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
27
|
+
- (dispatch_queue_t)methodQueue
|
|
30
28
|
{
|
|
31
|
-
|
|
32
|
-
if (bundleURL) {
|
|
33
|
-
if (self->_bundleManager) {
|
|
34
|
-
self->_bundleManager.bundleURL = bundleURL;
|
|
35
|
-
}
|
|
36
|
-
RCTReloadCommandSetBundleURL(bundleURL);
|
|
37
|
-
}
|
|
38
|
-
resolve(result ?: [NSNull null]);
|
|
39
|
-
RCTTriggerReloadCommandListeners(reason);
|
|
40
|
-
});
|
|
29
|
+
return dispatch_get_main_queue();
|
|
41
30
|
}
|
|
42
31
|
|
|
43
32
|
RCT_EXPORT_METHOD(getMetroHost:(RCTPromiseResolveBlock)resolve
|
|
@@ -56,12 +45,46 @@ RCT_EXPORT_METHOD(applyMetroHost:(NSString *)hostPort
|
|
|
56
45
|
return;
|
|
57
46
|
}
|
|
58
47
|
|
|
59
|
-
[RCTBundleURLProvider sharedSettings]
|
|
60
|
-
|
|
61
|
-
[
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
48
|
+
RCTBundleURLProvider *settings = [RCTBundleURLProvider sharedSettings];
|
|
49
|
+
NSRange separator = [hostPort rangeOfString:@":" options:NSBackwardsSearch];
|
|
50
|
+
NSString *host = separator.location == NSNotFound ? hostPort : [hostPort substringToIndex:separator.location];
|
|
51
|
+
NSString *port = separator.location == NSNotFound ? @"" : [hostPort substringFromIndex:separator.location + 1];
|
|
52
|
+
|
|
53
|
+
if (host.length == 0 && port.length == 0) {
|
|
54
|
+
[self resetMetroHost:resolve rejecter:reject];
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
NSNumberFormatter *formatter = [NSNumberFormatter new];
|
|
59
|
+
formatter.numberStyle = NSNumberFormatterDecimalStyle;
|
|
60
|
+
NSNumber *portNumber = [formatter numberFromString:port];
|
|
61
|
+
if (portNumber == nil) {
|
|
62
|
+
portNumber = [NSNumber numberWithInt:RCT_METRO_PORT];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
NSString *normalizedHostPort = [NSString stringWithFormat:@"%@:%d", host, portNumber.intValue];
|
|
66
|
+
settings.jsLocation = normalizedHostPort;
|
|
67
|
+
|
|
68
|
+
if (DebugToolkitBundleRoot.length == 0) {
|
|
69
|
+
if (_bundleManager) {
|
|
70
|
+
[_bundleManager resetBundleURL];
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
NSURL *bundleURL = [settings jsBundleURLForBundleRoot:DebugToolkitBundleRoot];
|
|
74
|
+
if (_bundleManager) {
|
|
75
|
+
_bundleManager.bundleURL = bundleURL;
|
|
76
|
+
} else {
|
|
77
|
+
RCTReloadCommandSetBundleURL(bundleURL);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
NSMutableDictionary *result = [@{@"hostPort" : normalizedHostPort} mutableCopy];
|
|
82
|
+
if (_bundleManager && _bundleManager.bundleURL.absoluteString) {
|
|
83
|
+
result[@"bundleURL"] = _bundleManager.bundleURL.absoluteString;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
RCTTriggerReloadCommandListeners(@"DevConnect - apply changes");
|
|
87
|
+
resolve(result);
|
|
65
88
|
}
|
|
66
89
|
|
|
67
90
|
RCT_EXPORT_METHOD(resetMetroHost:(RCTPromiseResolveBlock)resolve
|
|
@@ -69,10 +92,13 @@ RCT_EXPORT_METHOD(resetMetroHost:(RCTPromiseResolveBlock)resolve
|
|
|
69
92
|
{
|
|
70
93
|
[[RCTBundleURLProvider sharedSettings] resetToDefaults];
|
|
71
94
|
NSURL *bundleURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForFallbackExtension:nil];
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
95
|
+
if (_bundleManager) {
|
|
96
|
+
_bundleManager.bundleURL = bundleURL;
|
|
97
|
+
} else {
|
|
98
|
+
RCTReloadCommandSetBundleURL(bundleURL);
|
|
99
|
+
}
|
|
100
|
+
RCTTriggerReloadCommandListeners(@"DevConnect - reset to default");
|
|
101
|
+
resolve([NSNull null]);
|
|
76
102
|
}
|
|
77
103
|
|
|
78
104
|
RCT_EXPORT_METHOD(getPreference:(NSString *)key
|
|
@@ -108,7 +134,6 @@ RCT_EXPORT_METHOD(getLocalIp:(RCTPromiseResolveBlock)resolve
|
|
|
108
134
|
{
|
|
109
135
|
struct ifaddrs *interfaces = NULL;
|
|
110
136
|
if (getifaddrs(&interfaces) == 0) {
|
|
111
|
-
// First pass: prefer Wi-Fi interface (en0)
|
|
112
137
|
struct ifaddrs *iface = interfaces;
|
|
113
138
|
while (iface != NULL) {
|
|
114
139
|
if (iface->ifa_addr->sa_family == AF_INET && !(iface->ifa_flags & IFF_LOOPBACK)) {
|
|
@@ -124,7 +149,6 @@ RCT_EXPORT_METHOD(getLocalIp:(RCTPromiseResolveBlock)resolve
|
|
|
124
149
|
}
|
|
125
150
|
iface = iface->ifa_next;
|
|
126
151
|
}
|
|
127
|
-
// Second pass: any non-loopback IPv4
|
|
128
152
|
iface = interfaces;
|
|
129
153
|
while (iface != NULL) {
|
|
130
154
|
if (iface->ifa_addr->sa_family == AF_INET && !(iface->ifa_flags & IFF_LOOPBACK)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-debug-toolkit",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.7",
|
|
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",
|