@logbrew/react-native 0.1.3 → 0.1.5
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.
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
package co.logbrew.reactnative;
|
|
2
|
+
|
|
3
|
+
import android.system.ErrnoException;
|
|
4
|
+
import android.system.Os;
|
|
5
|
+
import android.system.OsConstants;
|
|
6
|
+
import java.io.File;
|
|
7
|
+
import java.io.FileDescriptor;
|
|
8
|
+
|
|
9
|
+
final class AndroidParentDirectorySync implements FatalRecordStore.ParentDirectorySync {
|
|
10
|
+
@Override
|
|
11
|
+
public FatalRecordStore.ParentDirectorySyncResult sync(File directory) {
|
|
12
|
+
FileDescriptor descriptor;
|
|
13
|
+
try {
|
|
14
|
+
descriptor =
|
|
15
|
+
Os.open(
|
|
16
|
+
directory.getAbsolutePath(),
|
|
17
|
+
OsConstants.O_RDONLY | OsConstants.O_CLOEXEC | OsConstants.O_NOFOLLOW,
|
|
18
|
+
0);
|
|
19
|
+
} catch (ErrnoException | RuntimeException error) {
|
|
20
|
+
return FatalRecordStore.ParentDirectorySyncResult.FAILED;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
FatalRecordStore.ParentDirectorySyncResult result;
|
|
24
|
+
try {
|
|
25
|
+
if (!OsConstants.S_ISDIR(Os.fstat(descriptor).st_mode)) {
|
|
26
|
+
result = FatalRecordStore.ParentDirectorySyncResult.FAILED;
|
|
27
|
+
} else {
|
|
28
|
+
result = syncDescriptor(descriptor);
|
|
29
|
+
}
|
|
30
|
+
} catch (ErrnoException | RuntimeException error) {
|
|
31
|
+
result = FatalRecordStore.ParentDirectorySyncResult.FAILED;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
Os.close(descriptor);
|
|
36
|
+
} catch (ErrnoException | RuntimeException error) {
|
|
37
|
+
return FatalRecordStore.ParentDirectorySyncResult.FAILED;
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private static FatalRecordStore.ParentDirectorySyncResult syncDescriptor(
|
|
43
|
+
FileDescriptor descriptor) {
|
|
44
|
+
try {
|
|
45
|
+
Os.fsync(descriptor);
|
|
46
|
+
return FatalRecordStore.ParentDirectorySyncResult.SYNCHRONIZED;
|
|
47
|
+
} catch (ErrnoException error) {
|
|
48
|
+
return unsupportedDirectorySync(error.errno)
|
|
49
|
+
? FatalRecordStore.ParentDirectorySyncResult.UNSUPPORTED
|
|
50
|
+
: FatalRecordStore.ParentDirectorySyncResult.FAILED;
|
|
51
|
+
} catch (RuntimeException error) {
|
|
52
|
+
return FatalRecordStore.ParentDirectorySyncResult.FAILED;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private static boolean unsupportedDirectorySync(int errno) {
|
|
57
|
+
return errno == OsConstants.EINVAL
|
|
58
|
+
|| errno == OsConstants.ENOTSUP
|
|
59
|
+
|| errno == OsConstants.EOPNOTSUPP;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -6,12 +6,9 @@ import java.io.DataInputStream;
|
|
|
6
6
|
import java.io.DataOutputStream;
|
|
7
7
|
import java.io.EOFException;
|
|
8
8
|
import java.io.File;
|
|
9
|
-
import java.io.FileDescriptor;
|
|
10
9
|
import java.io.FileInputStream;
|
|
11
10
|
import java.io.FileOutputStream;
|
|
12
11
|
import java.io.IOException;
|
|
13
|
-
import java.lang.reflect.Field;
|
|
14
|
-
import java.lang.reflect.Method;
|
|
15
12
|
import java.nio.charset.StandardCharsets;
|
|
16
13
|
import java.util.ArrayList;
|
|
17
14
|
import java.util.Arrays;
|
|
@@ -49,15 +46,23 @@ final class FatalRecordStore {
|
|
|
49
46
|
"SyntaxError",
|
|
50
47
|
"TypeError",
|
|
51
48
|
"URIError")));
|
|
49
|
+
private static final ParentDirectorySync UNSUPPORTED_PARENT_DIRECTORY_SYNC =
|
|
50
|
+
directory -> ParentDirectorySyncResult.UNSUPPORTED;
|
|
52
51
|
|
|
53
52
|
private final File directory;
|
|
54
53
|
private final File recordFile;
|
|
55
54
|
private final File temporaryFile;
|
|
55
|
+
private final ParentDirectorySync parentDirectorySync;
|
|
56
56
|
|
|
57
57
|
FatalRecordStore(File directory) {
|
|
58
|
+
this(directory, UNSUPPORTED_PARENT_DIRECTORY_SYNC);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
FatalRecordStore(File directory, ParentDirectorySync parentDirectorySync) {
|
|
58
62
|
this.directory = resolveCanonicalParent(directory);
|
|
59
63
|
this.recordFile = new File(this.directory, RECORD_FILE_NAME);
|
|
60
64
|
this.temporaryFile = new File(this.directory, TEMP_FILE_NAME);
|
|
65
|
+
this.parentDirectorySync = parentDirectorySync;
|
|
61
66
|
}
|
|
62
67
|
|
|
63
68
|
synchronized Result write(Record incoming) {
|
|
@@ -525,35 +530,17 @@ final class FatalRecordStore {
|
|
|
525
530
|
}
|
|
526
531
|
|
|
527
532
|
private boolean syncParentDirectory() {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
| intField(constants, "O_CLOEXEC");
|
|
534
|
-
Class<?> os = Class.forName("android.system.Os");
|
|
535
|
-
Method open = os.getMethod("open", String.class, int.class, int.class);
|
|
536
|
-
Method fsync = os.getMethod("fsync", FileDescriptor.class);
|
|
537
|
-
Method close = os.getMethod("close", FileDescriptor.class);
|
|
538
|
-
FileDescriptor descriptor =
|
|
539
|
-
(FileDescriptor) open.invoke(null, directory.getAbsolutePath(), flags, 0);
|
|
540
|
-
try {
|
|
541
|
-
fsync.invoke(null, descriptor);
|
|
542
|
-
} finally {
|
|
543
|
-
close.invoke(null, descriptor);
|
|
544
|
-
}
|
|
545
|
-
return true;
|
|
546
|
-
} catch (ClassNotFoundException unavailableOutsideAndroid) {
|
|
547
|
-
return true;
|
|
548
|
-
} catch (ReflectiveOperationException | RuntimeException error) {
|
|
549
|
-
return false;
|
|
550
|
-
}
|
|
533
|
+
return parentDirectorySync.sync(directory) != ParentDirectorySyncResult.FAILED;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
interface ParentDirectorySync {
|
|
537
|
+
ParentDirectorySyncResult sync(File directory);
|
|
551
538
|
}
|
|
552
539
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
540
|
+
enum ParentDirectorySyncResult {
|
|
541
|
+
SYNCHRONIZED,
|
|
542
|
+
UNSUPPORTED,
|
|
543
|
+
FAILED
|
|
557
544
|
}
|
|
558
545
|
|
|
559
546
|
static final class Frame {
|
|
@@ -35,7 +35,12 @@ final class FatalStoreModuleImpl {
|
|
|
35
35
|
|
|
36
36
|
FatalStoreModuleImpl(ReactApplicationContext context) {
|
|
37
37
|
File root = context.getNoBackupFilesDir();
|
|
38
|
-
store =
|
|
38
|
+
store =
|
|
39
|
+
root == null
|
|
40
|
+
? null
|
|
41
|
+
: new FatalRecordStore(
|
|
42
|
+
new File(root, "logbrew-fatal-js"),
|
|
43
|
+
new AndroidParentDirectorySync());
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
WritableMap writeFatalRecord(ReadableMap input) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@logbrew/react-native",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "React Native screen, error, trace, action, and network timeline helpers for LogBrew.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.cjs",
|
|
@@ -202,7 +202,7 @@
|
|
|
202
202
|
"url": "git+https://github.com/LogBrewCo/sdk.git"
|
|
203
203
|
},
|
|
204
204
|
"peerDependencies": {
|
|
205
|
-
"@logbrew/sdk": "^0.1.
|
|
205
|
+
"@logbrew/sdk": "^0.1.5",
|
|
206
206
|
"react": ">=18",
|
|
207
207
|
"react-native": ">=0.72"
|
|
208
208
|
},
|