react-native-debug-toolkit 0.3.0 → 0.4.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.
- package/README.md +18 -0
- package/android/src/main/java/com/debugtoolkit/BuildTypeModule.java +3 -27
- package/android/src/main/java/com/reactnative/debuglibs/RNDebugLibsModule.java +65 -0
- package/android/src/main/java/com/reactnative/debuglibs/RNDebugLibsPackage.java +28 -0
- package/index.js +6 -1
- package/ios/BuildTypeModule.h +5 -0
- package/ios/BuildTypeModule.m +6 -35
- package/ios/RNDebugLibs.h +10 -0
- package/ios/RNDebugLibs.m +79 -0
- package/lib/NativeDebugLibs.js +43 -0
- package/lib/features/NavigationLogFeature.js +47 -0
- package/lib/features/ThirdPartyLibsFeature.js +65 -0
- package/lib/hooks/useNavigationLogger.js +92 -0
- package/lib/index.js +16 -2
- package/lib/navigation/NavigationLogger.js +1 -0
- package/lib/utils/DebugConst.js +23 -5
- package/lib/utils/StorageUtils.js +1 -0
- package/lib/views/FloatPanelView.js +127 -10
- package/lib/views/NavigationLogDetails.js +294 -0
- package/lib/views/SubViewNavigationLogs.js +199 -0
- package/lib/views/SubViewThirdPartyLibs.js +239 -0
- package/package.json +2 -1
- package/react-native-debug-toolkit.podspec +25 -0
- package/react-native.config.js +10 -0
package/README.md
CHANGED
|
@@ -10,6 +10,24 @@ npm install react-native-debug-toolkit
|
|
|
10
10
|
yarn add react-native-debug-toolkit
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
### iOS Additional Setup
|
|
14
|
+
|
|
15
|
+
This toolkit uses FLEX and DoraemonKit for iOS debugging features. To properly integrate:
|
|
16
|
+
|
|
17
|
+
1. Make sure CocoaPods is installed in your project
|
|
18
|
+
2. Add these dependencies to your Podfile:
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
pod 'FLEX', :configurations => ['Debug']
|
|
22
|
+
pod 'DoraemonKit/Core', :configurations => ['Debug']
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
3. Run pod install in your iOS directory:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cd ios && pod install
|
|
29
|
+
```
|
|
30
|
+
|
|
13
31
|
## Basic Usage
|
|
14
32
|
|
|
15
33
|
```javascript
|
|
@@ -4,7 +4,6 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
|
|
4
4
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
5
5
|
import com.facebook.react.bridge.ReactMethod;
|
|
6
6
|
import com.facebook.react.bridge.Promise;
|
|
7
|
-
import com.facebook.react.bridge.Callback;
|
|
8
7
|
|
|
9
8
|
import java.util.HashMap;
|
|
10
9
|
import java.util.Map;
|
|
@@ -25,36 +24,13 @@ public class BuildTypeModule extends ReactContextBaseJavaModule {
|
|
|
25
24
|
@Override
|
|
26
25
|
public Map<String, Object> getConstants() {
|
|
27
26
|
final Map<String, Object> constants = new HashMap<>();
|
|
28
|
-
constants.put("
|
|
27
|
+
constants.put("buildType", BuildConfig.DEBUG ? "debug" : "release");
|
|
29
28
|
return constants;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
@ReactMethod
|
|
33
|
-
public void isDebugMode(Promise promise) {
|
|
34
|
-
try {
|
|
35
|
-
promise.resolve(BuildConfig.DEBUG);
|
|
36
|
-
} catch (Exception e) {
|
|
37
|
-
promise.reject("ERR_UNEXPECTED", e.getMessage(), e);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@ReactMethod
|
|
42
|
-
public void isReleaseMode(Promise promise) {
|
|
43
|
-
try {
|
|
44
|
-
promise.resolve(!BuildConfig.DEBUG);
|
|
45
|
-
} catch (Exception e) {
|
|
46
|
-
promise.reject("ERR_UNEXPECTED", e.getMessage(), e);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
51
|
-
public Boolean isDebugModeSync() {
|
|
52
|
-
return BuildConfig.DEBUG;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
31
|
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
56
|
-
public
|
|
57
|
-
return
|
|
32
|
+
public String getBuildTypeSync() {
|
|
33
|
+
return BuildConfig.DEBUG ? "debug" : "release";
|
|
58
34
|
}
|
|
59
35
|
|
|
60
36
|
@ReactMethod
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
package com.reactnative.debuglibs;
|
|
2
|
+
|
|
3
|
+
import android.app.Application;
|
|
4
|
+
import androidx.annotation.NonNull;
|
|
5
|
+
|
|
6
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
7
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
8
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
9
|
+
|
|
10
|
+
import com.didichuxing.doraemonkit.DoKit;
|
|
11
|
+
import com.didichuxing.doraemonkit.kit.AbstractKit;
|
|
12
|
+
|
|
13
|
+
import java.util.ArrayList;
|
|
14
|
+
import java.util.List;
|
|
15
|
+
|
|
16
|
+
public class RNDebugLibsModule extends ReactContextBaseJavaModule {
|
|
17
|
+
private final ReactApplicationContext reactContext;
|
|
18
|
+
|
|
19
|
+
public RNDebugLibsModule(ReactApplicationContext reactContext) {
|
|
20
|
+
super(reactContext);
|
|
21
|
+
this.reactContext = reactContext;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@NonNull
|
|
25
|
+
@Override
|
|
26
|
+
public String getName() {
|
|
27
|
+
return "RNDebugLibs";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@ReactMethod
|
|
31
|
+
public void showExplorer() {
|
|
32
|
+
// FLEX is iOS only
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@ReactMethod
|
|
36
|
+
public void hideExplorer() {
|
|
37
|
+
// FLEX is iOS only
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@ReactMethod
|
|
41
|
+
public void toggleExplorer() {
|
|
42
|
+
// FLEX is iOS only
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@ReactMethod
|
|
46
|
+
public void installDoraemonKit(String productId) {
|
|
47
|
+
Application app = (Application) reactContext.getApplicationContext();
|
|
48
|
+
List<AbstractKit> kits = new ArrayList<>();
|
|
49
|
+
// Initialize DoKit with custom kits if needed
|
|
50
|
+
DoKit.Builder(app)
|
|
51
|
+
.productId(productId)
|
|
52
|
+
.customKits(kits)
|
|
53
|
+
.build();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@ReactMethod
|
|
57
|
+
public void showDoraemonKit() {
|
|
58
|
+
DoKit.showToolPanel();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@ReactMethod
|
|
62
|
+
public void hideDoraemonKit() {
|
|
63
|
+
DoKit.hideToolPanel();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
package com.reactnative.debuglibs;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
|
|
5
|
+
import com.facebook.react.ReactPackage;
|
|
6
|
+
import com.facebook.react.bridge.NativeModule;
|
|
7
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
8
|
+
import com.facebook.react.uimanager.ViewManager;
|
|
9
|
+
|
|
10
|
+
import java.util.ArrayList;
|
|
11
|
+
import java.util.Collections;
|
|
12
|
+
import java.util.List;
|
|
13
|
+
|
|
14
|
+
public class RNDebugLibsPackage implements ReactPackage {
|
|
15
|
+
@NonNull
|
|
16
|
+
@Override
|
|
17
|
+
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
|
|
18
|
+
List<NativeModule> modules = new ArrayList<>();
|
|
19
|
+
modules.add(new RNDebugLibsModule(reactContext));
|
|
20
|
+
return modules;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@NonNull
|
|
24
|
+
@Override
|
|
25
|
+
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
|
|
26
|
+
return Collections.emptyList();
|
|
27
|
+
}
|
|
28
|
+
}
|
package/index.js
CHANGED
|
@@ -9,6 +9,8 @@ import { createNetworkFeature } from './lib/features/NetworkFeature'
|
|
|
9
9
|
import { createPerformanceFeature } from './lib/features/PerformanceFeature'
|
|
10
10
|
import { createConsoleLogFeature } from './lib/features/ConsoleLogFeature'
|
|
11
11
|
import { createZustandLogFeature, addZustandLog } from './lib/features/ZustandLogFeature'
|
|
12
|
+
import { createNavigationLogFeature, addNavigationLog } from './lib/features/NavigationLogFeature'
|
|
13
|
+
import { useNavigationLogger } from './lib/hooks/useNavigationLogger'
|
|
12
14
|
|
|
13
15
|
export {
|
|
14
16
|
DebugToolKit,
|
|
@@ -17,7 +19,10 @@ export {
|
|
|
17
19
|
createPerformanceFeature,
|
|
18
20
|
createConsoleLogFeature,
|
|
19
21
|
createZustandLogFeature,
|
|
20
|
-
addZustandLog
|
|
22
|
+
addZustandLog,
|
|
23
|
+
createNavigationLogFeature,
|
|
24
|
+
addNavigationLog,
|
|
25
|
+
useNavigationLogger
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
export default DebugToolKit
|
package/ios/BuildTypeModule.h
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
#import <React/RCTBridgeModule.h>
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BuildTypeModule
|
|
5
|
+
* Native module that provides information about the current build type (debug or release)
|
|
6
|
+
* Used to conditionally enable debugging tools only in debug builds
|
|
7
|
+
*/
|
|
3
8
|
@interface BuildTypeModule : NSObject <RCTBridgeModule>
|
|
4
9
|
@end
|
package/ios/BuildTypeModule.m
CHANGED
|
@@ -12,49 +12,20 @@ RCT_EXPORT_MODULE();
|
|
|
12
12
|
- (NSDictionary *)constantsToExport
|
|
13
13
|
{
|
|
14
14
|
#ifdef DEBUG
|
|
15
|
-
|
|
15
|
+
NSString *buildType = @"debug";
|
|
16
16
|
#else
|
|
17
|
-
|
|
17
|
+
NSString *buildType = @"release";
|
|
18
18
|
#endif
|
|
19
19
|
|
|
20
|
-
return @{ @"
|
|
20
|
+
return @{ @"buildType": buildType };
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(
|
|
23
|
+
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getBuildTypeSync)
|
|
24
24
|
{
|
|
25
25
|
#ifdef DEBUG
|
|
26
|
-
return @
|
|
26
|
+
return @"debug";
|
|
27
27
|
#else
|
|
28
|
-
return @
|
|
29
|
-
#endif
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isReleaseModeSync)
|
|
33
|
-
{
|
|
34
|
-
#ifdef DEBUG
|
|
35
|
-
return @(NO);
|
|
36
|
-
#else
|
|
37
|
-
return @(YES);
|
|
38
|
-
#endif
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
RCT_EXPORT_METHOD(isDebugMode:(RCTPromiseResolveBlock)resolve
|
|
42
|
-
rejecter:(RCTPromiseRejectBlock)reject)
|
|
43
|
-
{
|
|
44
|
-
#ifdef DEBUG
|
|
45
|
-
resolve(@(YES));
|
|
46
|
-
#else
|
|
47
|
-
resolve(@(NO));
|
|
48
|
-
#endif
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
RCT_EXPORT_METHOD(isReleaseMode:(RCTPromiseResolveBlock)resolve
|
|
52
|
-
rejecter:(RCTPromiseRejectBlock)reject)
|
|
53
|
-
{
|
|
54
|
-
#ifdef DEBUG
|
|
55
|
-
resolve(@(NO));
|
|
56
|
-
#else
|
|
57
|
-
resolve(@(YES));
|
|
28
|
+
return @"release";
|
|
58
29
|
#endif
|
|
59
30
|
}
|
|
60
31
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* RNDebugLibs
|
|
5
|
+
* Native module that provides access to FLEX and DoraemonKit debugging tools
|
|
6
|
+
* Note: These debugging tools are only available in DEBUG builds
|
|
7
|
+
*/
|
|
8
|
+
@interface RNDebugLibs : NSObject <RCTBridgeModule>
|
|
9
|
+
|
|
10
|
+
@end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#import "RNDebugLibs.h"
|
|
2
|
+
|
|
3
|
+
#ifdef DEBUG
|
|
4
|
+
#import "FLEXManager.h"
|
|
5
|
+
#import <DoraemonKit/DoraemonManager.h>
|
|
6
|
+
#endif
|
|
7
|
+
|
|
8
|
+
@implementation RNDebugLibs
|
|
9
|
+
|
|
10
|
+
// Export the module
|
|
11
|
+
RCT_EXPORT_MODULE();
|
|
12
|
+
|
|
13
|
+
RCT_EXPORT_METHOD(showExplorer)
|
|
14
|
+
{
|
|
15
|
+
#ifdef DEBUG
|
|
16
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
17
|
+
[[FLEXManager sharedManager] showExplorer];
|
|
18
|
+
});
|
|
19
|
+
#else
|
|
20
|
+
NSLog(@"[RNDebugLibs] showExplorer is only available in DEBUG builds");
|
|
21
|
+
#endif
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
RCT_EXPORT_METHOD(hideExplorer)
|
|
25
|
+
{
|
|
26
|
+
#ifdef DEBUG
|
|
27
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
28
|
+
[[FLEXManager sharedManager] hideExplorer];
|
|
29
|
+
});
|
|
30
|
+
#else
|
|
31
|
+
NSLog(@"[RNDebugLibs] hideExplorer is only available in DEBUG builds");
|
|
32
|
+
#endif
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
RCT_EXPORT_METHOD(toggleExplorer)
|
|
36
|
+
{
|
|
37
|
+
#ifdef DEBUG
|
|
38
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
39
|
+
[[FLEXManager sharedManager] toggleExplorer];
|
|
40
|
+
});
|
|
41
|
+
#else
|
|
42
|
+
NSLog(@"[RNDebugLibs] toggleExplorer is only available in DEBUG builds");
|
|
43
|
+
#endif
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
RCT_EXPORT_METHOD(installDoraemonKit:(NSString *)productId)
|
|
47
|
+
{
|
|
48
|
+
#ifdef DEBUG
|
|
49
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
50
|
+
[[DoraemonManager shareInstance] installWithPid:productId];
|
|
51
|
+
});
|
|
52
|
+
#else
|
|
53
|
+
NSLog(@"[RNDebugLibs] installDoraemonKit is only available in DEBUG builds");
|
|
54
|
+
#endif
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
RCT_EXPORT_METHOD(showDoraemonKit)
|
|
58
|
+
{
|
|
59
|
+
#ifdef DEBUG
|
|
60
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
61
|
+
[[DoraemonManager shareInstance] showDoraemon];
|
|
62
|
+
});
|
|
63
|
+
#else
|
|
64
|
+
NSLog(@"[RNDebugLibs] showDoraemonKit is only available in DEBUG builds");
|
|
65
|
+
#endif
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
RCT_EXPORT_METHOD(hideDoraemonKit)
|
|
69
|
+
{
|
|
70
|
+
#ifdef DEBUG
|
|
71
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
72
|
+
[[DoraemonManager shareInstance] hiddenDoraemon];
|
|
73
|
+
});
|
|
74
|
+
#else
|
|
75
|
+
NSLog(@"[RNDebugLibs] hideDoraemonKit is only available in DEBUG builds");
|
|
76
|
+
#endif
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { NativeModules, Platform } from 'react-native'
|
|
2
|
+
|
|
3
|
+
const { RNDebugLibs } = NativeModules
|
|
4
|
+
|
|
5
|
+
export default class NativeDebugLibs {
|
|
6
|
+
// FLEX methods (iOS only)
|
|
7
|
+
static showExplorer() {
|
|
8
|
+
if (Platform.OS === 'ios' && RNDebugLibs) {
|
|
9
|
+
RNDebugLibs.showExplorer()
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
static hideExplorer() {
|
|
14
|
+
if (Platform.OS === 'ios' && RNDebugLibs) {
|
|
15
|
+
RNDebugLibs.hideExplorer()
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static toggleExplorer() {
|
|
20
|
+
if (Platform.OS === 'ios' && RNDebugLibs) {
|
|
21
|
+
RNDebugLibs.toggleExplorer()
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// DoraemonKit/DoKit methods
|
|
26
|
+
static installDoraemonKit(productId) {
|
|
27
|
+
if (RNDebugLibs) {
|
|
28
|
+
RNDebugLibs.installDoraemonKit(productId)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static showDoraemonKit() {
|
|
33
|
+
if (RNDebugLibs) {
|
|
34
|
+
RNDebugLibs.showDoraemonKit()
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static hideDoraemonKit() {
|
|
39
|
+
if (RNDebugLibs) {
|
|
40
|
+
RNDebugLibs.hideDoraemonKit()
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const MAX_LOGS = 200; // Max number of navigation logs to store
|
|
2
|
+
const logs = [];
|
|
3
|
+
const originalNavigationMethods = {}; // Store original navigation methods
|
|
4
|
+
|
|
5
|
+
const setup = () => {
|
|
6
|
+
if (!__DEV__) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
// Note: Actual navigation interception will be done in the main app code
|
|
10
|
+
// This is just a setup function for compatibility with the feature API
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// Function to add navigation log
|
|
14
|
+
export const addNavigationLog = (action, from, to, startTime, duration) => {
|
|
15
|
+
// Store log data
|
|
16
|
+
logs.push({
|
|
17
|
+
timestamp: new Date(),
|
|
18
|
+
action: action, // push, pop, replace, etc.
|
|
19
|
+
from: from, // source route info
|
|
20
|
+
to: to, // destination route info
|
|
21
|
+
startTime: startTime,
|
|
22
|
+
duration: duration,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Trim logs if they exceed the maximum limit
|
|
26
|
+
if (logs.length > MAX_LOGS) {
|
|
27
|
+
logs.splice(0, logs.length - MAX_LOGS);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const getData = () => {
|
|
32
|
+
return logs;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const cleanup = () => {
|
|
36
|
+
logs.length = 0; // Clear array
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const createNavigationLogFeature = () => {
|
|
40
|
+
return {
|
|
41
|
+
name: 'navigation',
|
|
42
|
+
label: 'Navigation Logs',
|
|
43
|
+
setup: setup,
|
|
44
|
+
getData: getData,
|
|
45
|
+
cleanup: cleanup,
|
|
46
|
+
};
|
|
47
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import NativeDebugLibs from '../NativeDebugLibs';
|
|
3
|
+
|
|
4
|
+
// Define available third-party debug libraries
|
|
5
|
+
const availableLibs = [
|
|
6
|
+
{
|
|
7
|
+
id: 'flex',
|
|
8
|
+
name: 'FLEX',
|
|
9
|
+
description: 'In-app debugging and exploration tool for iOS',
|
|
10
|
+
platform: 'ios',
|
|
11
|
+
icon: 'tools',
|
|
12
|
+
actions: [
|
|
13
|
+
{ id: 'showExplorer', label: 'Show Explorer', method: NativeDebugLibs.showExplorer },
|
|
14
|
+
{ id: 'hideExplorer', label: 'Hide Explorer', method: NativeDebugLibs.hideExplorer },
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: 'doraemonkit',
|
|
19
|
+
name: 'DoraemonKit',
|
|
20
|
+
description: 'A full-featured iOS & Android development assistant',
|
|
21
|
+
platform: 'both',
|
|
22
|
+
icon: 'box',
|
|
23
|
+
actions: [
|
|
24
|
+
{ id: 'showDoraemonKit', label: 'Show DoraemonKit', method: NativeDebugLibs.showDoraemonKit },
|
|
25
|
+
{ id: 'hideDoraemonKit', label: 'Hide DoraemonKit', method: NativeDebugLibs.hideDoraemonKit },
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
// Get libraries available for current platform
|
|
31
|
+
const getPlatformLibs = () => {
|
|
32
|
+
const currentPlatform = Platform.OS;
|
|
33
|
+
return availableLibs.filter(lib =>
|
|
34
|
+
lib.platform === 'both' || lib.platform === currentPlatform
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Setup function is minimal since we're just presenting UI options
|
|
39
|
+
const setup = () => {
|
|
40
|
+
if (!__DEV__) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// No additional setup needed beyond initialization
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Get data - return available libraries for this platform
|
|
47
|
+
const getData = () => {
|
|
48
|
+
return getPlatformLibs();
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Cleanup function (if needed)
|
|
52
|
+
const cleanup = () => {
|
|
53
|
+
// Nothing specific to clean up
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// Export the feature factory function
|
|
57
|
+
export const createThirdPartyLibsFeature = () => {
|
|
58
|
+
return {
|
|
59
|
+
name: 'thirdPartyLibs',
|
|
60
|
+
label: 'Debug Libraries',
|
|
61
|
+
setup,
|
|
62
|
+
getData,
|
|
63
|
+
cleanup
|
|
64
|
+
};
|
|
65
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import { addNavigationLog } from '../features/NavigationLogFeature';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Custom hook to log React Navigation events for debugging
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
*
|
|
9
|
+
* // In your navigation container
|
|
10
|
+
* import { useNavigationLogger } from 'react-native-debug-toolkit';
|
|
11
|
+
*
|
|
12
|
+
* function App() {
|
|
13
|
+
* const navigationRef = useRef();
|
|
14
|
+
*
|
|
15
|
+
* // Enable navigation logging
|
|
16
|
+
* useNavigationLogger(navigationRef);
|
|
17
|
+
*
|
|
18
|
+
* return (
|
|
19
|
+
* <NavigationContainer ref={navigationRef}>
|
|
20
|
+
* // ... your navigation structure
|
|
21
|
+
* </NavigationContainer>
|
|
22
|
+
* );
|
|
23
|
+
* }
|
|
24
|
+
*/
|
|
25
|
+
export function useNavigationLogger(navigationRef) {
|
|
26
|
+
// Track previous state
|
|
27
|
+
const routeRef = useRef(null);
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!__DEV__ || !navigationRef.current) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Create listeners for navigation events
|
|
35
|
+
const unsubscribeReady = navigationRef.current?.addListener('state', (e) => {
|
|
36
|
+
if (!navigationRef.current) return;
|
|
37
|
+
|
|
38
|
+
const state = navigationRef.current.getRootState();
|
|
39
|
+
if (!state) return;
|
|
40
|
+
|
|
41
|
+
const currentRoute = navigationRef.current.getCurrentRoute();
|
|
42
|
+
|
|
43
|
+
if (!currentRoute) return;
|
|
44
|
+
|
|
45
|
+
// First render won't have a previous state
|
|
46
|
+
if (!routeRef.current) {
|
|
47
|
+
routeRef.current = currentRoute;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Determine the navigation action
|
|
52
|
+
let action = 'navigate';
|
|
53
|
+
|
|
54
|
+
// Check if this was a push (adding to history) or replace
|
|
55
|
+
const routes = state.routes;
|
|
56
|
+
if (routes.length > 0) {
|
|
57
|
+
const prevIndex = routes.findIndex(route => route.key === routeRef.current.key);
|
|
58
|
+
const currentIndex = routes.findIndex(route => route.key === currentRoute.key);
|
|
59
|
+
|
|
60
|
+
if (currentIndex > prevIndex) {
|
|
61
|
+
action = 'push';
|
|
62
|
+
} else if (currentIndex < prevIndex) {
|
|
63
|
+
action = 'pop';
|
|
64
|
+
} else if (currentIndex === prevIndex) {
|
|
65
|
+
action = 'replace';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Log the navigation
|
|
70
|
+
addNavigationLog(
|
|
71
|
+
action,
|
|
72
|
+
{
|
|
73
|
+
name: routeRef.current.name,
|
|
74
|
+
params: routeRef.current.params,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: currentRoute.name,
|
|
78
|
+
params: currentRoute.params,
|
|
79
|
+
},
|
|
80
|
+
performance.now(), // Approximate time
|
|
81
|
+
0 // No duration measurement available for this event type
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// Update the reference
|
|
85
|
+
routeRef.current = currentRoute;
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
return () => {
|
|
89
|
+
unsubscribeReady && unsubscribeReady();
|
|
90
|
+
};
|
|
91
|
+
}, [navigationRef]);
|
|
92
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -3,6 +3,9 @@ import { createNetworkFeature } from './features/NetworkFeature'
|
|
|
3
3
|
import { createPerformanceFeature} from './features/PerformanceFeature'
|
|
4
4
|
import { createConsoleLogFeature } from './features/ConsoleLogFeature'
|
|
5
5
|
import { createZustandLogFeature, zustandLogMiddleware } from './features/ZustandLogFeature'
|
|
6
|
+
import { createNavigationLogFeature, addNavigationLog } from './features/NavigationLogFeature'
|
|
7
|
+
import { createThirdPartyLibsFeature } from './features/ThirdPartyLibsFeature'
|
|
8
|
+
import NativeDebugLibs from './NativeDebugLibs'
|
|
6
9
|
|
|
7
10
|
// Registry mapping feature names (strings) to their creator functions
|
|
8
11
|
const featureRegistry = {
|
|
@@ -10,24 +13,32 @@ const featureRegistry = {
|
|
|
10
13
|
console: createConsoleLogFeature,
|
|
11
14
|
performance: createPerformanceFeature,
|
|
12
15
|
zustand: createZustandLogFeature,
|
|
16
|
+
navigation: createNavigationLogFeature,
|
|
17
|
+
thirdPartyLibs: createThirdPartyLibsFeature,
|
|
13
18
|
// Add other built-in features here
|
|
14
19
|
// 'storage': createStorageFeature,
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
// List of default features (can use strings now)
|
|
18
|
-
const defaultFeatures = ['network', 'console', 'zustand']
|
|
23
|
+
const defaultFeatures = ['network', 'console', 'zustand', 'navigation', 'thirdPartyLibs']
|
|
19
24
|
|
|
20
25
|
/**
|
|
21
26
|
* Initializes and shows the Debug ToolKit panel with specified features.
|
|
22
27
|
* Only runs in development mode (__DEV__ === true).
|
|
23
28
|
* Features can be specified as strings (e.g., 'network') or creator functions.
|
|
24
29
|
* @param {Array<string|Function>} features - Array of feature names (strings) or creator functions. Defaults to standard features.
|
|
30
|
+
* @param {Object} options - Additional options like doraemonProductId for third-party debug libraries
|
|
25
31
|
*/
|
|
26
|
-
export function initializeDebugToolkit(features = defaultFeatures) {
|
|
32
|
+
export function initializeDebugToolkit(features = defaultFeatures, options = {}) {
|
|
27
33
|
|
|
28
34
|
try {
|
|
29
35
|
const debugToolKit = new DebugToolKit();
|
|
30
36
|
|
|
37
|
+
// Initialize third-party debug libraries if configured
|
|
38
|
+
if (options.doraemonProductId) {
|
|
39
|
+
NativeDebugLibs.installDoraemonKit(options.doraemonProductId);
|
|
40
|
+
}
|
|
41
|
+
|
|
31
42
|
features.forEach(featureIdentifier => {
|
|
32
43
|
let feature = null;
|
|
33
44
|
let featureCreator = null;
|
|
@@ -81,6 +92,9 @@ export {
|
|
|
81
92
|
createPerformanceFeature,
|
|
82
93
|
createConsoleLogFeature,
|
|
83
94
|
createZustandLogFeature,
|
|
95
|
+
createNavigationLogFeature,
|
|
96
|
+
createThirdPartyLibsFeature,
|
|
97
|
+
addNavigationLog,
|
|
84
98
|
zustandLogMiddleware, // Export middleware for use in Zustand stores
|
|
85
99
|
featureRegistry
|
|
86
100
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|