react-native-debug-toolkit 3.2.6 → 3.2.8

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.
@@ -1,4 +1,5 @@
1
1
  #import <Foundation/Foundation.h>
2
+ #import <React/RCTBridge.h>
2
3
  #import <React/RCTBundleManager.h>
3
4
  #import <React/RCTBridgeModule.h>
4
5
  #import <React/RCTBundleURLProvider.h>
@@ -17,6 +18,7 @@ static NSString *const DebugToolkitBundleRoot = @"index";
17
18
 
18
19
  RCT_EXPORT_MODULE(DebugToolkitDevConnect)
19
20
 
21
+ @synthesize bridge = _bridge;
20
22
  @synthesize bundleManager = _bundleManager;
21
23
 
22
24
  + (BOOL)requiresMainQueueSetup
@@ -24,100 +26,141 @@ RCT_EXPORT_MODULE(DebugToolkitDevConnect)
24
26
  return NO;
25
27
  }
26
28
 
27
- - (void)applyBundleURL:(NSURL *)bundleURL
28
- reason:(NSString *)reason
29
- result:(id)result
30
- resolve:(RCTPromiseResolveBlock)resolve
29
+ - (dispatch_queue_t)methodQueue
31
30
  {
32
- dispatch_async(dispatch_get_main_queue(), ^{
33
- if (self->_bundleManager) {
34
- if (bundleURL) {
35
- self->_bundleManager.bundleURL = bundleURL;
36
- } else {
37
- [self->_bundleManager resetBundleURL];
38
- }
31
+ return dispatch_get_main_queue();
32
+ }
33
+
34
+ #pragma mark - Bundle Manager Resolution
35
+
36
+ - (RCTBundleManager *)resolveBundleManager
37
+ {
38
+ if (_bundleManager) {
39
+ return _bundleManager;
40
+ }
41
+ if (_bridge) {
42
+ return [_bridge moduleForClass:[RCTBundleManager class]];
43
+ }
44
+ return nil;
45
+ }
46
+
47
+ #pragma mark - Apply Bundle URL (multi-strategy)
48
+
49
+ - (BOOL)applyBundleURL:(NSURL *)bundleURL
50
+ {
51
+ RCTBundleManager *bm = [self resolveBundleManager];
52
+ if (bm) {
53
+ if (bundleURL) {
54
+ bm.bundleURL = bundleURL;
39
55
  } else {
40
- RCTReloadCommandSetBundleURL(bundleURL);
56
+ [bm resetBundleURL];
41
57
  }
42
- resolve(result ?: [NSNull null]);
43
- RCTTriggerReloadCommandListeners(reason);
44
- });
58
+ return YES;
59
+ }
60
+
61
+ if (bundleURL) {
62
+ RCTReloadCommandSetBundleURL(bundleURL);
63
+ return YES;
64
+ }
65
+
66
+ return NO;
45
67
  }
46
68
 
69
+ #pragma mark - Exported Methods
70
+
47
71
  RCT_EXPORT_METHOD(getMetroHost:(RCTPromiseResolveBlock)resolve
48
72
  rejecter:(__unused RCTPromiseRejectBlock)reject)
49
73
  {
50
- NSString *host = [RCTBundleURLProvider sharedSettings].jsLocation;
51
- resolve(host ?: [NSNull null]);
74
+ @try {
75
+ NSString *host = [RCTBundleURLProvider sharedSettings].jsLocation;
76
+ resolve(host ?: [NSNull null]);
77
+ } @catch (NSException *exception) {
78
+ reject(@"native_error", exception.reason, nil);
79
+ }
52
80
  }
53
81
 
54
82
  RCT_EXPORT_METHOD(applyMetroHost:(NSString *)hostPort
55
83
  resolver:(RCTPromiseResolveBlock)resolve
56
84
  rejecter:(RCTPromiseRejectBlock)reject)
57
85
  {
58
- if (hostPort.length == 0) {
59
- reject(@"invalid_host", @"Metro host cannot be empty.", nil);
60
- return;
61
- }
86
+ @try {
87
+ if (hostPort.length == 0) {
88
+ reject(@"invalid_host", @"Metro host cannot be empty.", nil);
89
+ return;
90
+ }
62
91
 
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];
92
+ RCTBundleURLProvider *settings = [RCTBundleURLProvider sharedSettings];
67
93
 
68
- if (host.length == 0 && port.length == 0) {
69
- [self resetMetroHost:resolve rejecter:reject];
70
- return;
71
- }
94
+ NSRange separator = [hostPort rangeOfString:@":" options:NSBackwardsSearch];
95
+ NSString *host = separator.location == NSNotFound
96
+ ? hostPort
97
+ : [hostPort substringToIndex:separator.location];
98
+ NSString *port = separator.location == NSNotFound
99
+ ? @""
100
+ : [hostPort substringFromIndex:separator.location + 1];
72
101
 
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
- }
102
+ if (host.length == 0 && port.length == 0) {
103
+ [self resetMetroHost:resolve rejecter:reject];
104
+ return;
105
+ }
106
+
107
+ NSNumberFormatter *formatter = [NSNumberFormatter new];
108
+ formatter.numberStyle = NSNumberFormatterDecimalStyle;
109
+ NSNumber *portNumber = [formatter numberFromString:port];
110
+ if (portNumber == nil) {
111
+ portNumber = [NSNumber numberWithInt:RCT_METRO_PORT];
112
+ }
113
+
114
+ NSString *normalizedHostPort = [NSString stringWithFormat:@"%@:%d", host, portNumber.intValue];
79
115
 
80
- NSString *normalizedHostPort = [NSString stringWithFormat:@"%@:%d", host, portNumber.intValue];
81
- settings.jsLocation = normalizedHostPort;
116
+ settings.jsLocation = normalizedHostPort;
82
117
 
83
- NSURL *bundleURL = nil;
84
- if (DebugToolkitBundleRoot.length == 0) {
85
- if (_bundleManager) {
86
- [_bundleManager resetBundleURL];
87
- bundleURL = _bundleManager.bundleURL;
118
+ NSURL *bundleURL = nil;
119
+ if (DebugToolkitBundleRoot.length > 0) {
120
+ bundleURL = [settings jsBundleURLForBundleRoot:DebugToolkitBundleRoot];
88
121
  }
89
- } else {
90
- bundleURL = [settings jsBundleURLForBundleRoot:DebugToolkitBundleRoot];
91
- }
92
122
 
93
- NSMutableDictionary *result = [@{ @"hostPort" : normalizedHostPort } mutableCopy];
94
- if (bundleURL.absoluteString) {
95
- result[@"bundleURL"] = bundleURL.absoluteString;
96
- }
123
+ [self applyBundleURL:bundleURL];
97
124
 
98
- [self applyBundleURL:bundleURL
99
- reason:@"Dev menu - apply changes"
100
- result:result
101
- resolve:resolve];
125
+ NSMutableDictionary *result = [@{@"hostPort" : normalizedHostPort} mutableCopy];
126
+ RCTBundleManager *bm = [self resolveBundleManager];
127
+ if (bm && bm.bundleURL.absoluteString) {
128
+ result[@"bundleURL"] = bm.bundleURL.absoluteString;
129
+ }
130
+
131
+ RCTTriggerReloadCommandListeners(@"Dev menu - apply changes");
132
+ resolve(result);
133
+ } @catch (NSException *exception) {
134
+ reject(@"native_error", exception.reason, nil);
135
+ }
102
136
  }
103
137
 
104
138
  RCT_EXPORT_METHOD(resetMetroHost:(RCTPromiseResolveBlock)resolve
105
139
  rejecter:(__unused RCTPromiseRejectBlock)reject)
106
140
  {
107
- [[RCTBundleURLProvider sharedSettings] resetToDefaults];
108
- NSURL *bundleURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForFallbackExtension:nil];
109
- [self applyBundleURL:bundleURL
110
- reason:@"Dev menu - reset to default"
111
- result:[NSNull null]
112
- resolve:resolve];
141
+ @try {
142
+ RCTBundleURLProvider *settings = [RCTBundleURLProvider sharedSettings];
143
+ [settings resetToDefaults];
144
+ NSURL *bundleURL = [settings jsBundleURLForFallbackExtension:nil];
145
+
146
+ [self applyBundleURL:bundleURL];
147
+ RCTTriggerReloadCommandListeners(@"Dev menu - reset to default");
148
+ resolve([NSNull null]);
149
+ } @catch (NSException *exception) {
150
+ reject(@"native_error", exception.reason, nil);
151
+ }
113
152
  }
114
153
 
115
154
  RCT_EXPORT_METHOD(getPreference:(NSString *)key
116
155
  resolver:(RCTPromiseResolveBlock)resolve
117
156
  rejecter:(__unused RCTPromiseRejectBlock)reject)
118
157
  {
119
- NSString *value = [[NSUserDefaults standardUserDefaults] stringForKey:key];
120
- resolve(value ?: [NSNull null]);
158
+ @try {
159
+ NSString *value = [[NSUserDefaults standardUserDefaults] stringForKey:key];
160
+ resolve(value ?: [NSNull null]);
161
+ } @catch (NSException *exception) {
162
+ reject(@"native_error", exception.reason, nil);
163
+ }
121
164
  }
122
165
 
123
166
  RCT_EXPORT_METHOD(setPreference:(NSString *)key
@@ -125,9 +168,13 @@ RCT_EXPORT_METHOD(setPreference:(NSString *)key
125
168
  resolver:(RCTPromiseResolveBlock)resolve
126
169
  rejecter:(__unused RCTPromiseRejectBlock)reject)
127
170
  {
128
- [[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
129
- [[NSUserDefaults standardUserDefaults] synchronize];
130
- resolve([NSNull null]);
171
+ @try {
172
+ [[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
173
+ [[NSUserDefaults standardUserDefaults] synchronize];
174
+ resolve([NSNull null]);
175
+ } @catch (NSException *exception) {
176
+ reject(@"native_error", exception.reason, nil);
177
+ }
131
178
  }
132
179
 
133
180
  RCT_EXPORT_METHOD(isDebugBuild:(RCTPromiseResolveBlock)resolve
@@ -143,13 +190,27 @@ RCT_EXPORT_METHOD(isDebugBuild:(RCTPromiseResolveBlock)resolve
143
190
  RCT_EXPORT_METHOD(getLocalIp:(RCTPromiseResolveBlock)resolve
144
191
  rejecter:(__unused RCTPromiseRejectBlock)reject)
145
192
  {
146
- struct ifaddrs *interfaces = NULL;
147
- if (getifaddrs(&interfaces) == 0) {
148
- // First pass: prefer Wi-Fi interface (en0)
149
- struct ifaddrs *iface = interfaces;
150
- while (iface != NULL) {
151
- if (iface->ifa_addr->sa_family == AF_INET && !(iface->ifa_flags & IFF_LOOPBACK)) {
152
- if (strcmp(iface->ifa_name, "en0") == 0) {
193
+ @try {
194
+ struct ifaddrs *interfaces = NULL;
195
+ if (getifaddrs(&interfaces) == 0) {
196
+ struct ifaddrs *iface = interfaces;
197
+ while (iface != NULL) {
198
+ if (iface->ifa_addr != NULL && iface->ifa_addr->sa_family == AF_INET && !(iface->ifa_flags & IFF_LOOPBACK)) {
199
+ if (strcmp(iface->ifa_name, "en0") == 0) {
200
+ char addrStr[INET_ADDRSTRLEN];
201
+ struct sockaddr_in *sin = (struct sockaddr_in *)iface->ifa_addr;
202
+ inet_ntop(AF_INET, &sin->sin_addr, addrStr, sizeof(addrStr));
203
+ NSString *ip = [NSString stringWithUTF8String:addrStr];
204
+ freeifaddrs(interfaces);
205
+ resolve(ip);
206
+ return;
207
+ }
208
+ }
209
+ iface = iface->ifa_next;
210
+ }
211
+ iface = interfaces;
212
+ while (iface != NULL) {
213
+ if (iface->ifa_addr != NULL && iface->ifa_addr->sa_family == AF_INET && !(iface->ifa_flags & IFF_LOOPBACK)) {
153
214
  char addrStr[INET_ADDRSTRLEN];
154
215
  struct sockaddr_in *sin = (struct sockaddr_in *)iface->ifa_addr;
155
216
  inet_ntop(AF_INET, &sin->sin_addr, addrStr, sizeof(addrStr));
@@ -158,26 +219,14 @@ RCT_EXPORT_METHOD(getLocalIp:(RCTPromiseResolveBlock)resolve
158
219
  resolve(ip);
159
220
  return;
160
221
  }
222
+ iface = iface->ifa_next;
161
223
  }
162
- iface = iface->ifa_next;
163
- }
164
- // Second pass: any non-loopback IPv4
165
- iface = interfaces;
166
- while (iface != NULL) {
167
- if (iface->ifa_addr->sa_family == AF_INET && !(iface->ifa_flags & IFF_LOOPBACK)) {
168
- char addrStr[INET_ADDRSTRLEN];
169
- struct sockaddr_in *sin = (struct sockaddr_in *)iface->ifa_addr;
170
- inet_ntop(AF_INET, &sin->sin_addr, addrStr, sizeof(addrStr));
171
- NSString *ip = [NSString stringWithUTF8String:addrStr];
172
- freeifaddrs(interfaces);
173
- resolve(ip);
174
- return;
175
- }
176
- iface = iface->ifa_next;
177
224
  }
225
+ freeifaddrs(interfaces);
226
+ resolve([NSNull null]);
227
+ } @catch (NSException *exception) {
228
+ reject(@"native_error", exception.reason, nil);
178
229
  }
179
- freeifaddrs(interfaces);
180
- resolve([NSNull null]);
181
230
  }
182
231
 
183
232
  @end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-debug-toolkit",
3
- "version": "3.2.6",
3
+ "version": "3.2.8",
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",