@debugbundle/sdk-react-native 1.1.0 → 1.3.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/CHANGELOG.md +43 -0
- package/DebugBundleReactNative.podspec +4 -3
- package/LICENSE +202 -0
- package/README.md +13 -3
- package/android/build.gradle +70 -1
- package/android/src/main/java/com/debugbundle/reactnative/DebugBundleReactNativeModule.java +369 -78
- package/android/src/test/java/com/debugbundle/reactnative/DebugBundleReactNativeModuleTest.java +474 -0
- package/app.plugin.js +1 -1
- package/dist/NativeDebugBundleReactNative.d.ts +5 -1
- package/dist/NativeDebugBundleReactNative.d.ts.map +1 -1
- package/dist/before-send.d.ts +3 -0
- package/dist/before-send.d.ts.map +1 -0
- package/dist/before-send.js +136 -0
- package/dist/client.d.ts +0 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +224 -64
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js +3 -15
- package/dist/testing.d.ts +9 -2
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +18 -0
- package/dist/types.d.ts +16 -5
- package/dist/types.d.ts.map +1 -1
- package/ios/DebugBundleReactNative.swift +120 -13
- package/ios/DebugBundleReactNativeBridge.mm +73 -0
- package/package.json +7 -3
- package/src/NativeDebugBundleReactNative.ts +5 -1
- package/src/before-send.ts +172 -0
- package/src/client.ts +245 -68
- package/src/index.ts +2 -0
- package/src/native.ts +3 -25
- package/src/testing.ts +28 -2
- package/src/types.ts +22 -5
- package/ios/DebugBundleReactNativeBridge.m +0 -28
|
@@ -1,31 +1,48 @@
|
|
|
1
1
|
package com.debugbundle.reactnative;
|
|
2
2
|
|
|
3
|
+
import android.content.Context;
|
|
3
4
|
import com.debugbundle.android.DebugBundle;
|
|
4
5
|
import com.debugbundle.android.DebugBundleConfig;
|
|
5
6
|
import com.debugbundle.android.DebugBundleLogLevel;
|
|
6
7
|
import com.debugbundle.android.DebugBundleRequestInfo;
|
|
7
8
|
import com.debugbundle.android.DebugBundleResponseInfo;
|
|
8
9
|
import com.facebook.react.bridge.Arguments;
|
|
10
|
+
import com.facebook.react.bridge.Dynamic;
|
|
9
11
|
import com.facebook.react.bridge.Promise;
|
|
10
12
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
11
13
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
12
14
|
import com.facebook.react.bridge.ReactMethod;
|
|
13
15
|
import com.facebook.react.bridge.ReadableMap;
|
|
14
16
|
import com.facebook.react.bridge.WritableMap;
|
|
15
|
-
import java.lang.reflect.Constructor;
|
|
16
17
|
import java.lang.reflect.Method;
|
|
18
|
+
import java.util.ArrayList;
|
|
17
19
|
import java.util.Collections;
|
|
20
|
+
import java.util.HashSet;
|
|
21
|
+
import java.util.LinkedHashMap;
|
|
22
|
+
import java.util.List;
|
|
18
23
|
import java.util.Locale;
|
|
19
24
|
import java.util.Map;
|
|
25
|
+
import java.util.Set;
|
|
20
26
|
|
|
21
27
|
public final class DebugBundleReactNativeModule extends ReactContextBaseJavaModule {
|
|
22
28
|
public static final String NAME = "DebugBundleReactNative";
|
|
23
29
|
|
|
24
30
|
private final ReactApplicationContext reactContext;
|
|
31
|
+
private final NativeOperations nativeOperations;
|
|
32
|
+
private final WritableMapFactory writableMapFactory;
|
|
25
33
|
|
|
26
34
|
public DebugBundleReactNativeModule(ReactApplicationContext reactContext) {
|
|
35
|
+
this(reactContext, new DefaultNativeOperations(), Arguments::createMap);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
DebugBundleReactNativeModule(
|
|
39
|
+
ReactApplicationContext reactContext,
|
|
40
|
+
NativeOperations nativeOperations,
|
|
41
|
+
WritableMapFactory writableMapFactory) {
|
|
27
42
|
super(reactContext);
|
|
28
43
|
this.reactContext = reactContext;
|
|
44
|
+
this.nativeOperations = nativeOperations;
|
|
45
|
+
this.writableMapFactory = writableMapFactory;
|
|
29
46
|
}
|
|
30
47
|
|
|
31
48
|
@Override
|
|
@@ -36,7 +53,7 @@ public final class DebugBundleReactNativeModule extends ReactContextBaseJavaModu
|
|
|
36
53
|
@ReactMethod
|
|
37
54
|
public void initialize(ReadableMap config, Promise promise) {
|
|
38
55
|
try {
|
|
39
|
-
|
|
56
|
+
nativeOperations.initialize(reactContext.getApplicationContext(), createConfig(config));
|
|
40
57
|
promise.resolve(stateMap());
|
|
41
58
|
} catch (Throwable ignored) {
|
|
42
59
|
promise.resolve(degradedState("android_initialize_failed"));
|
|
@@ -48,25 +65,24 @@ public final class DebugBundleReactNativeModule extends ReactContextBaseJavaModu
|
|
|
48
65
|
try {
|
|
49
66
|
String eventType = stringOrDefault(event, "event_type", "");
|
|
50
67
|
Map<String, Object> payload = hashMap(event, "payload");
|
|
51
|
-
DebugBundle debugBundle = DebugBundle.INSTANCE;
|
|
52
68
|
|
|
53
69
|
if ("frontend_exception".equals(eventType)) {
|
|
54
|
-
|
|
70
|
+
nativeOperations.captureException(
|
|
55
71
|
new RuntimeException(stringValue(payload.get("error"), "React Native exception")),
|
|
56
72
|
payload);
|
|
57
73
|
} else if ("frontend_breadcrumb".equals(eventType)) {
|
|
58
|
-
|
|
74
|
+
nativeOperations.captureBreadcrumb(
|
|
59
75
|
stringValue(payload.get("breadcrumb_type"), "react_native"),
|
|
60
76
|
null,
|
|
61
77
|
payload);
|
|
62
78
|
} else if ("log_event".equals(eventType)) {
|
|
63
|
-
|
|
79
|
+
nativeOperations.captureLog(
|
|
64
80
|
stringValue(payload.get("message"), ""),
|
|
65
81
|
logLevel(stringValue(payload.get("level"), null)),
|
|
66
82
|
payload);
|
|
67
83
|
} else if ("request_event".equals(eventType)) {
|
|
68
84
|
ReadableMap correlation = event.hasKey("correlation") ? event.getMap("correlation") : null;
|
|
69
|
-
|
|
85
|
+
nativeOperations.captureRequest(
|
|
70
86
|
new DebugBundleRequestInfo(
|
|
71
87
|
stringValue(payload.get("method"), "GET"),
|
|
72
88
|
stringValue(payload.get("url"), ""),
|
|
@@ -80,7 +96,7 @@ public final class DebugBundleReactNativeModule extends ReactContextBaseJavaModu
|
|
|
80
96
|
payload,
|
|
81
97
|
false);
|
|
82
98
|
} else {
|
|
83
|
-
|
|
99
|
+
nativeOperations.captureMessage(
|
|
84
100
|
"react_native_event:" + eventType,
|
|
85
101
|
DebugBundleLogLevel.Warning,
|
|
86
102
|
payload);
|
|
@@ -91,16 +107,52 @@ public final class DebugBundleReactNativeModule extends ReactContextBaseJavaModu
|
|
|
91
107
|
}
|
|
92
108
|
}
|
|
93
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Canonical bridge added after the original translation-based enqueue API.
|
|
112
|
+
* The legacy method above remains available for installed JS/native pairs.
|
|
113
|
+
*/
|
|
114
|
+
@ReactMethod
|
|
115
|
+
public void enqueueCanonicalEvent(ReadableMap event, Promise promise) {
|
|
116
|
+
try {
|
|
117
|
+
promise.resolve(
|
|
118
|
+
nativeOperations.captureExternalEvent(normalizeBridgeMap(event.toHashMap())));
|
|
119
|
+
} catch (Throwable ignored) {
|
|
120
|
+
promise.resolve(false);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
125
|
+
public boolean isProbeActive(String label) {
|
|
126
|
+
try {
|
|
127
|
+
return nativeOperations.isProbeActive(label);
|
|
128
|
+
} catch (Throwable ignored) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@ReactMethod
|
|
134
|
+
public void captureProbe(
|
|
135
|
+
String label,
|
|
136
|
+
ReadableMap data,
|
|
137
|
+
String occurredAt,
|
|
138
|
+
Promise promise) {
|
|
139
|
+
try {
|
|
140
|
+
promise.resolve(nativeOperations.captureExternalProbe(
|
|
141
|
+
currentSdkVersion,
|
|
142
|
+
currentService,
|
|
143
|
+
currentEnvironment,
|
|
144
|
+
label,
|
|
145
|
+
data.toHashMap(),
|
|
146
|
+
occurredAt));
|
|
147
|
+
} catch (Throwable ignored) {
|
|
148
|
+
promise.resolve(false);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
94
152
|
@ReactMethod
|
|
95
153
|
public void flush(Promise promise) {
|
|
96
154
|
try {
|
|
97
|
-
|
|
98
|
-
"flush-LRDsOJo$default",
|
|
99
|
-
DebugBundle.class,
|
|
100
|
-
long.class,
|
|
101
|
-
int.class,
|
|
102
|
-
Object.class);
|
|
103
|
-
flushDefault.invoke(null, DebugBundle.INSTANCE, 0L, 1, null);
|
|
155
|
+
nativeOperations.flush();
|
|
104
156
|
promise.resolve(null);
|
|
105
157
|
} catch (Throwable ignored) {
|
|
106
158
|
promise.resolve(null);
|
|
@@ -113,89 +165,84 @@ public final class DebugBundleReactNativeModule extends ReactContextBaseJavaModu
|
|
|
113
165
|
}
|
|
114
166
|
|
|
115
167
|
@ReactMethod
|
|
116
|
-
public void setContext(String key,
|
|
168
|
+
public void setContext(String key, Dynamic value, Promise promise) {
|
|
117
169
|
try {
|
|
118
|
-
|
|
170
|
+
nativeOperations.setContext(key, dynamicValue(value));
|
|
119
171
|
promise.resolve(null);
|
|
120
172
|
} catch (Throwable ignored) {
|
|
121
173
|
promise.resolve(null);
|
|
174
|
+
} finally {
|
|
175
|
+
try {
|
|
176
|
+
value.recycle();
|
|
177
|
+
} catch (Throwable ignored) {
|
|
178
|
+
// React Native bridge cleanup must not escape into the host process.
|
|
179
|
+
}
|
|
122
180
|
}
|
|
123
181
|
}
|
|
124
182
|
|
|
125
183
|
@ReactMethod
|
|
126
|
-
public void
|
|
184
|
+
public void setContextValue(String key, ReadableMap entry, Promise promise) {
|
|
127
185
|
try {
|
|
128
|
-
|
|
186
|
+
nativeOperations.setContext(key, entry.toHashMap().get("value"));
|
|
187
|
+
promise.resolve(null);
|
|
129
188
|
} catch (Throwable ignored) {
|
|
130
|
-
promise.resolve(
|
|
189
|
+
promise.resolve(null);
|
|
131
190
|
}
|
|
132
191
|
}
|
|
133
192
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
if (constructor == null) {
|
|
143
|
-
throw new NoSuchMethodException("DebugBundleConfig default constructor");
|
|
193
|
+
@ReactMethod
|
|
194
|
+
public void activateProbeTriggerToken(String token, Promise promise) {
|
|
195
|
+
try {
|
|
196
|
+
promise.resolve(nativeOperations.activateProbeTriggerToken(token));
|
|
197
|
+
} catch (Throwable ignored) {
|
|
198
|
+
promise.resolve(false);
|
|
144
199
|
}
|
|
145
|
-
|
|
200
|
+
}
|
|
146
201
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
mask = useProvided(mask, 2);
|
|
151
|
-
mask = useProvided(mask, 3);
|
|
152
|
-
mask = useProvided(mask, 4);
|
|
153
|
-
mask = useProvided(mask, 10);
|
|
154
|
-
mask = useProvided(mask, 11);
|
|
155
|
-
mask = useProvided(mask, 12);
|
|
156
|
-
mask = useProvided(mask, 31);
|
|
202
|
+
private String currentSdkVersion = "1.3.0";
|
|
203
|
+
private String currentService = "react-native-app";
|
|
204
|
+
private String currentEnvironment = "production";
|
|
157
205
|
|
|
158
|
-
|
|
206
|
+
private DebugBundleConfig createConfig(ReadableMap config) {
|
|
207
|
+
currentSdkVersion = stringOrDefault(config, "sdkVersion", "1.3.0");
|
|
208
|
+
currentService = stringOrDefault(config, "service", "react-native-app");
|
|
209
|
+
currentEnvironment = stringOrDefault(config, "environment", "production");
|
|
210
|
+
return DebugBundleConfig.create(
|
|
159
211
|
stringOrDefault(config, "projectToken", ""),
|
|
160
212
|
booleanOrDefault(config, "enabled", true),
|
|
161
|
-
|
|
162
|
-
|
|
213
|
+
currentEnvironment,
|
|
214
|
+
currentService,
|
|
163
215
|
stringOrDefault(config, "endpoint", DebugBundleConfig.DEFAULT_ENDPOINT),
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
216
|
+
intOrDefault(config, "batchSize", 10),
|
|
217
|
+
longOrDefault(config, "flushInterval", 3000L),
|
|
218
|
+
doubleOrDefault(config, "sampleRate", 1.0),
|
|
219
|
+
doubleOrDefault(config, "sessionSampleRate", 1.0),
|
|
220
|
+
longOrDefault(config, "requestTimeout", 5000L),
|
|
169
221
|
stringOrDefault(config, "releaseChannel", "production"),
|
|
170
222
|
stringOrNull(config, "appVersion"),
|
|
171
223
|
stringOrNull(config, "buildNumber"),
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
false,
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
false,
|
|
189
|
-
Collections.emptySet(),
|
|
190
|
-
stringOrDefault(config, "sdkVersion", "1.1.0"),
|
|
191
|
-
mask,
|
|
192
|
-
null);
|
|
224
|
+
intOrDefault(config, "maxEventsPerSession", 100),
|
|
225
|
+
intOrDefault(config, "maxBreadcrumbs", 20),
|
|
226
|
+
booleanOrDefault(config, "captureScreens", true),
|
|
227
|
+
booleanOrDefault(config, "captureActions", false),
|
|
228
|
+
booleanOrDefault(config, "captureNetwork", true),
|
|
229
|
+
booleanOrDefault(config, "captureLogs", true),
|
|
230
|
+
logLevel(stringOrNull(config, "logLevel")),
|
|
231
|
+
stringSet(config, "headerAllowlist", Collections.emptySet()),
|
|
232
|
+
intOrDefault(config, "offlineQueueMaxEvents", 500),
|
|
233
|
+
longOrDefault(config, "offlineQueueMaxBytes", 5L * 1024L * 1024L),
|
|
234
|
+
longOrDefault(config, "offlineQueueTtl", 72L * 60L * 60L * 1000L),
|
|
235
|
+
intOrDefault(config, "maxProbeLabels", 50),
|
|
236
|
+
intOrDefault(config, "maxProbeEntriesPerLabel", 10),
|
|
237
|
+
booleanOrDefault(config, "probeFlushOnError", true),
|
|
238
|
+
stringSet(config, "redactFields", Collections.emptySet()),
|
|
239
|
+
currentSdkVersion);
|
|
193
240
|
}
|
|
194
241
|
|
|
195
242
|
private WritableMap stateMap() {
|
|
196
|
-
WritableMap state =
|
|
197
|
-
state.putString("status",
|
|
198
|
-
Long lastEventAt =
|
|
243
|
+
WritableMap state = writableMapFactory.create();
|
|
244
|
+
state.putString("status", nativeOperations.statusName().toLowerCase(Locale.ROOT));
|
|
245
|
+
Long lastEventAt = nativeOperations.lastEventAt();
|
|
199
246
|
if (lastEventAt == null) {
|
|
200
247
|
state.putNull("lastEventAt");
|
|
201
248
|
} else {
|
|
@@ -207,7 +254,7 @@ public final class DebugBundleReactNativeModule extends ReactContextBaseJavaModu
|
|
|
207
254
|
}
|
|
208
255
|
|
|
209
256
|
private WritableMap degradedState(String reason) {
|
|
210
|
-
WritableMap state =
|
|
257
|
+
WritableMap state = writableMapFactory.create();
|
|
211
258
|
state.putString("status", "degraded");
|
|
212
259
|
state.putNull("lastEventAt");
|
|
213
260
|
state.putBoolean("nativeModuleAvailable", true);
|
|
@@ -215,10 +262,6 @@ public final class DebugBundleReactNativeModule extends ReactContextBaseJavaModu
|
|
|
215
262
|
return state;
|
|
216
263
|
}
|
|
217
264
|
|
|
218
|
-
private static int useProvided(int mask, int index) {
|
|
219
|
-
return mask & ~(1 << index);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
265
|
private static Map<String, Object> hashMap(ReadableMap map, String key) {
|
|
223
266
|
ReadableMap nested = map.hasKey(key) ? map.getMap(key) : null;
|
|
224
267
|
if (nested == null) {
|
|
@@ -249,6 +292,44 @@ public final class DebugBundleReactNativeModule extends ReactContextBaseJavaModu
|
|
|
249
292
|
return map.getBoolean(key);
|
|
250
293
|
}
|
|
251
294
|
|
|
295
|
+
private static int intOrDefault(ReadableMap map, String key, int fallback) {
|
|
296
|
+
if (!map.hasKey(key) || map.isNull(key)) {
|
|
297
|
+
return fallback;
|
|
298
|
+
}
|
|
299
|
+
return map.getInt(key);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
private static long longOrDefault(ReadableMap map, String key, long fallback) {
|
|
303
|
+
if (!map.hasKey(key) || map.isNull(key)) {
|
|
304
|
+
return fallback;
|
|
305
|
+
}
|
|
306
|
+
return (long) map.getDouble(key);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
private static double doubleOrDefault(ReadableMap map, String key, double fallback) {
|
|
310
|
+
if (!map.hasKey(key) || map.isNull(key)) {
|
|
311
|
+
return fallback;
|
|
312
|
+
}
|
|
313
|
+
return map.getDouble(key);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
private static Set<String> stringSet(
|
|
317
|
+
ReadableMap map,
|
|
318
|
+
String key,
|
|
319
|
+
Set<String> fallback) {
|
|
320
|
+
if (!map.hasKey(key) || map.isNull(key) || map.getArray(key) == null) {
|
|
321
|
+
return fallback;
|
|
322
|
+
}
|
|
323
|
+
List<Object> values = map.getArray(key).toArrayList();
|
|
324
|
+
Set<String> result = new HashSet<>();
|
|
325
|
+
for (Object value : values) {
|
|
326
|
+
if (value instanceof String) {
|
|
327
|
+
result.add((String) value);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return result;
|
|
331
|
+
}
|
|
332
|
+
|
|
252
333
|
private static String stringValue(Object value, String fallback) {
|
|
253
334
|
return value == null ? fallback : value.toString();
|
|
254
335
|
}
|
|
@@ -261,6 +342,66 @@ public final class DebugBundleReactNativeModule extends ReactContextBaseJavaModu
|
|
|
261
342
|
return value instanceof Number ? ((Number) value).longValue() : null;
|
|
262
343
|
}
|
|
263
344
|
|
|
345
|
+
private static Map<String, Object> normalizeBridgeMap(Map<String, Object> values) {
|
|
346
|
+
Map<String, Object> normalized = new LinkedHashMap<>();
|
|
347
|
+
for (Map.Entry<String, Object> entry : values.entrySet()) {
|
|
348
|
+
normalized.put(entry.getKey(), normalizeBridgeValue(entry.getValue()));
|
|
349
|
+
}
|
|
350
|
+
return normalized;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
private static Object normalizeBridgeValue(Object value) {
|
|
354
|
+
if (value instanceof Double) {
|
|
355
|
+
double number = (Double) value;
|
|
356
|
+
if (Double.isFinite(number)
|
|
357
|
+
&& number == Math.rint(number)
|
|
358
|
+
&& number >= Long.MIN_VALUE
|
|
359
|
+
&& number <= Long.MAX_VALUE) {
|
|
360
|
+
return (long) number;
|
|
361
|
+
}
|
|
362
|
+
return number;
|
|
363
|
+
}
|
|
364
|
+
if (value instanceof Map<?, ?>) {
|
|
365
|
+
Map<String, Object> normalized = new LinkedHashMap<>();
|
|
366
|
+
for (Map.Entry<?, ?> entry : ((Map<?, ?>) value).entrySet()) {
|
|
367
|
+
if (entry.getKey() instanceof String) {
|
|
368
|
+
normalized.put(
|
|
369
|
+
(String) entry.getKey(),
|
|
370
|
+
normalizeBridgeValue(entry.getValue()));
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return normalized;
|
|
374
|
+
}
|
|
375
|
+
if (value instanceof List<?>) {
|
|
376
|
+
List<Object> normalized = new ArrayList<>();
|
|
377
|
+
for (Object item : (List<?>) value) {
|
|
378
|
+
normalized.add(normalizeBridgeValue(item));
|
|
379
|
+
}
|
|
380
|
+
return normalized;
|
|
381
|
+
}
|
|
382
|
+
return value;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
private static Object dynamicValue(Dynamic value) {
|
|
386
|
+
if (value == null || value.isNull()) {
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
switch (value.getType()) {
|
|
390
|
+
case Boolean:
|
|
391
|
+
return value.asBoolean();
|
|
392
|
+
case Number:
|
|
393
|
+
return value.asDouble();
|
|
394
|
+
case String:
|
|
395
|
+
return value.asString();
|
|
396
|
+
case Map:
|
|
397
|
+
return value.asMap().toHashMap();
|
|
398
|
+
case Array:
|
|
399
|
+
return value.asArray().toArrayList();
|
|
400
|
+
default:
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
264
405
|
private static DebugBundleLogLevel logLevel(String value) {
|
|
265
406
|
if (value == null) {
|
|
266
407
|
return DebugBundleLogLevel.Warning;
|
|
@@ -278,4 +419,154 @@ public final class DebugBundleReactNativeModule extends ReactContextBaseJavaModu
|
|
|
278
419
|
return DebugBundleLogLevel.Warning;
|
|
279
420
|
}
|
|
280
421
|
}
|
|
422
|
+
|
|
423
|
+
interface WritableMapFactory {
|
|
424
|
+
WritableMap create();
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
interface NativeOperations {
|
|
428
|
+
void initialize(Context context, DebugBundleConfig config);
|
|
429
|
+
|
|
430
|
+
void captureException(Throwable error, Map<String, Object> context);
|
|
431
|
+
|
|
432
|
+
void captureBreadcrumb(String type, String route, Map<String, Object> data);
|
|
433
|
+
|
|
434
|
+
void captureLog(
|
|
435
|
+
String message,
|
|
436
|
+
DebugBundleLogLevel level,
|
|
437
|
+
Map<String, Object> context);
|
|
438
|
+
|
|
439
|
+
void captureRequest(
|
|
440
|
+
DebugBundleRequestInfo request,
|
|
441
|
+
DebugBundleResponseInfo response,
|
|
442
|
+
Map<String, Object> context,
|
|
443
|
+
boolean force);
|
|
444
|
+
|
|
445
|
+
void captureMessage(
|
|
446
|
+
String message,
|
|
447
|
+
DebugBundleLogLevel level,
|
|
448
|
+
Map<String, Object> context);
|
|
449
|
+
|
|
450
|
+
boolean captureExternalEvent(Map<String, Object> event);
|
|
451
|
+
|
|
452
|
+
boolean isProbeActive(String label);
|
|
453
|
+
|
|
454
|
+
boolean captureExternalProbe(
|
|
455
|
+
String sdkVersion,
|
|
456
|
+
String service,
|
|
457
|
+
String environment,
|
|
458
|
+
String label,
|
|
459
|
+
Map<String, Object> data,
|
|
460
|
+
String occurredAt);
|
|
461
|
+
|
|
462
|
+
void flush() throws ReflectiveOperationException;
|
|
463
|
+
|
|
464
|
+
void setContext(String key, Object value);
|
|
465
|
+
|
|
466
|
+
boolean activateProbeTriggerToken(String token);
|
|
467
|
+
|
|
468
|
+
String statusName();
|
|
469
|
+
|
|
470
|
+
Long lastEventAt();
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
private static final class DefaultNativeOperations implements NativeOperations {
|
|
474
|
+
@Override
|
|
475
|
+
public void initialize(Context context, DebugBundleConfig config) {
|
|
476
|
+
DebugBundle.init(context, config);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
@Override
|
|
480
|
+
public void captureException(Throwable error, Map<String, Object> context) {
|
|
481
|
+
DebugBundle.INSTANCE.captureException(error, context);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
@Override
|
|
485
|
+
public void captureBreadcrumb(String type, String route, Map<String, Object> data) {
|
|
486
|
+
DebugBundle.INSTANCE.captureBreadcrumb(type, route, data);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
@Override
|
|
490
|
+
public void captureLog(
|
|
491
|
+
String message,
|
|
492
|
+
DebugBundleLogLevel level,
|
|
493
|
+
Map<String, Object> context) {
|
|
494
|
+
DebugBundle.INSTANCE.captureLog(message, level, context);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
@Override
|
|
498
|
+
public void captureRequest(
|
|
499
|
+
DebugBundleRequestInfo request,
|
|
500
|
+
DebugBundleResponseInfo response,
|
|
501
|
+
Map<String, Object> context,
|
|
502
|
+
boolean force) {
|
|
503
|
+
DebugBundle.INSTANCE.captureRequest(request, response, context, force);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
@Override
|
|
507
|
+
public void captureMessage(
|
|
508
|
+
String message,
|
|
509
|
+
DebugBundleLogLevel level,
|
|
510
|
+
Map<String, Object> context) {
|
|
511
|
+
DebugBundle.INSTANCE.captureMessage(message, level, context);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
@Override
|
|
515
|
+
public boolean captureExternalEvent(Map<String, Object> event) {
|
|
516
|
+
return DebugBundle.captureExternalEvent(event);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
@Override
|
|
520
|
+
public boolean isProbeActive(String label) {
|
|
521
|
+
return DebugBundle.isExternalProbeActive(label);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
@Override
|
|
525
|
+
public boolean captureExternalProbe(
|
|
526
|
+
String sdkVersion,
|
|
527
|
+
String service,
|
|
528
|
+
String environment,
|
|
529
|
+
String label,
|
|
530
|
+
Map<String, Object> data,
|
|
531
|
+
String occurredAt) {
|
|
532
|
+
return DebugBundle.captureExternalProbe(
|
|
533
|
+
sdkVersion,
|
|
534
|
+
service,
|
|
535
|
+
environment,
|
|
536
|
+
label,
|
|
537
|
+
data,
|
|
538
|
+
occurredAt);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
@Override
|
|
542
|
+
public void flush() throws ReflectiveOperationException {
|
|
543
|
+
Method flushDefault = DebugBundle.class.getDeclaredMethod(
|
|
544
|
+
"flush-LRDsOJo$default",
|
|
545
|
+
DebugBundle.class,
|
|
546
|
+
long.class,
|
|
547
|
+
int.class,
|
|
548
|
+
Object.class);
|
|
549
|
+
flushDefault.invoke(null, DebugBundle.INSTANCE, 0L, 1, null);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
@Override
|
|
553
|
+
public void setContext(String key, Object value) {
|
|
554
|
+
DebugBundle.INSTANCE.setContext(key, value);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
@Override
|
|
558
|
+
public boolean activateProbeTriggerToken(String token) {
|
|
559
|
+
return DebugBundle.INSTANCE.activateProbeTriggerToken(token);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
@Override
|
|
563
|
+
public String statusName() {
|
|
564
|
+
return DebugBundle.INSTANCE.getStatus().name();
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
@Override
|
|
568
|
+
public Long lastEventAt() {
|
|
569
|
+
return DebugBundle.INSTANCE.getLastEventAt();
|
|
570
|
+
}
|
|
571
|
+
}
|
|
281
572
|
}
|