@onekeyfe/react-native-tcp-socket 1.1.56
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/TcpSocket.podspec +19 -0
- package/android/build.gradle +77 -0
- package/android/src/main/java/com/rntcpsocket/RNTcpSocketModule.kt +35 -0
- package/android/src/main/java/com/rntcpsocket/RNTcpSocketPackage.kt +33 -0
- package/ios/TcpSocket.h +5 -0
- package/ios/TcpSocket.mm +151 -0
- package/lib/module/NativeTcpSocket.js +5 -0
- package/lib/module/NativeTcpSocket.js.map +1 -0
- package/lib/module/index.js +43 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeTcpSocket.d.ts +11 -0
- package/lib/typescript/src/NativeTcpSocket.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +17 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +157 -0
- package/src/NativeTcpSocket.ts +17 -0
- package/src/index.tsx +57 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "TcpSocket"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"]
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
|
|
13
|
+
s.platforms = { :ios => min_ios_version_supported }
|
|
14
|
+
s.source = { :git => "https://github.com/OneKeyHQ/app-modules/react-native-tcp-socket.git", :tag => "#{s.version}" }
|
|
15
|
+
|
|
16
|
+
s.source_files = "ios/**/*.{h,m,mm}"
|
|
17
|
+
|
|
18
|
+
install_modules_dependencies(s)
|
|
19
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
ext.getExtOrDefault = {name ->
|
|
3
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['RNTcpSocket_' + name]
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
repositories {
|
|
7
|
+
google()
|
|
8
|
+
mavenCentral()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
dependencies {
|
|
12
|
+
classpath "com.android.tools.build:gradle:8.7.2"
|
|
13
|
+
// noinspection DifferentKotlinGradleVersion
|
|
14
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
apply plugin: "com.android.library"
|
|
20
|
+
apply plugin: "kotlin-android"
|
|
21
|
+
|
|
22
|
+
apply plugin: "com.facebook.react"
|
|
23
|
+
|
|
24
|
+
def getExtOrIntegerDefault(name) {
|
|
25
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["RNTcpSocket_" + name]).toInteger()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
android {
|
|
29
|
+
namespace "com.rntcpsocket"
|
|
30
|
+
|
|
31
|
+
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
|
|
32
|
+
|
|
33
|
+
defaultConfig {
|
|
34
|
+
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
|
|
35
|
+
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
buildFeatures {
|
|
39
|
+
buildConfig true
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
buildTypes {
|
|
43
|
+
release {
|
|
44
|
+
minifyEnabled false
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
lintOptions {
|
|
49
|
+
disable "GradleCompatible"
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
compileOptions {
|
|
53
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
54
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
sourceSets {
|
|
58
|
+
main {
|
|
59
|
+
java.srcDirs += [
|
|
60
|
+
"generated/java",
|
|
61
|
+
"generated/jni"
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
repositories {
|
|
68
|
+
mavenCentral()
|
|
69
|
+
google()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
def kotlin_version = getExtOrDefault("kotlinVersion")
|
|
73
|
+
|
|
74
|
+
dependencies {
|
|
75
|
+
implementation "com.facebook.react:react-android"
|
|
76
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
77
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
package com.rntcpsocket
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Promise
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
5
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
6
|
+
import java.net.InetSocketAddress
|
|
7
|
+
import java.net.Socket
|
|
8
|
+
|
|
9
|
+
@ReactModule(name = RNTcpSocketModule.NAME)
|
|
10
|
+
class RNTcpSocketModule(reactContext: ReactApplicationContext) :
|
|
11
|
+
NativeRNTcpSocketSpec(reactContext) {
|
|
12
|
+
|
|
13
|
+
companion object {
|
|
14
|
+
const val NAME = "RNTcpSocket"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override fun getName(): String = NAME
|
|
18
|
+
|
|
19
|
+
override fun connectWithTimeout(host: String, port: Double, timeoutMs: Double, promise: Promise) {
|
|
20
|
+
Thread {
|
|
21
|
+
try {
|
|
22
|
+
val portInt = port.toInt()
|
|
23
|
+
val timeout = timeoutMs.toInt()
|
|
24
|
+
val startTime = System.currentTimeMillis()
|
|
25
|
+
Socket().use { socket ->
|
|
26
|
+
socket.connect(InetSocketAddress(host, portInt), timeout)
|
|
27
|
+
}
|
|
28
|
+
val elapsed = System.currentTimeMillis() - startTime
|
|
29
|
+
promise.resolve(elapsed.toDouble())
|
|
30
|
+
} catch (e: Exception) {
|
|
31
|
+
promise.reject("TCP_SOCKET_ERROR", e.message, e)
|
|
32
|
+
}
|
|
33
|
+
}.start()
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package com.rntcpsocket
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.BaseReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.module.model.ReactModuleInfo
|
|
7
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
8
|
+
import java.util.HashMap
|
|
9
|
+
|
|
10
|
+
class RNTcpSocketPackage : BaseReactPackage() {
|
|
11
|
+
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
|
|
12
|
+
return if (name == RNTcpSocketModule.NAME) {
|
|
13
|
+
RNTcpSocketModule(reactContext)
|
|
14
|
+
} else {
|
|
15
|
+
null
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
|
|
20
|
+
return ReactModuleInfoProvider {
|
|
21
|
+
val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
|
|
22
|
+
moduleInfos[RNTcpSocketModule.NAME] = ReactModuleInfo(
|
|
23
|
+
RNTcpSocketModule.NAME,
|
|
24
|
+
RNTcpSocketModule.NAME,
|
|
25
|
+
false, // canOverrideExistingModule
|
|
26
|
+
false, // needsEagerInit
|
|
27
|
+
false, // isCxxModule
|
|
28
|
+
true // isTurboModule
|
|
29
|
+
)
|
|
30
|
+
moduleInfos
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
package/ios/TcpSocket.h
ADDED
package/ios/TcpSocket.mm
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#import "TcpSocket.h"
|
|
2
|
+
|
|
3
|
+
#include <arpa/inet.h>
|
|
4
|
+
#include <errno.h>
|
|
5
|
+
#include <fcntl.h>
|
|
6
|
+
#include <netdb.h>
|
|
7
|
+
#include <netinet/in.h>
|
|
8
|
+
#include <string.h>
|
|
9
|
+
#include <sys/select.h>
|
|
10
|
+
#include <sys/socket.h>
|
|
11
|
+
#include <sys/time.h>
|
|
12
|
+
#include <unistd.h>
|
|
13
|
+
|
|
14
|
+
@implementation TcpSocket
|
|
15
|
+
|
|
16
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
17
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
18
|
+
{
|
|
19
|
+
return std::make_shared<facebook::react::NativeRNTcpSocketSpecJSI>(params);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
+ (NSString *)moduleName
|
|
23
|
+
{
|
|
24
|
+
return @"RNTcpSocket";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
+ (BOOL)requiresMainQueueSetup
|
|
28
|
+
{
|
|
29
|
+
return NO;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// MARK: - connectWithTimeout
|
|
33
|
+
|
|
34
|
+
- (void)connectWithTimeout:(NSString *)host
|
|
35
|
+
port:(double)port
|
|
36
|
+
timeoutMs:(double)timeoutMs
|
|
37
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
38
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
39
|
+
{
|
|
40
|
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
41
|
+
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970] * 1000.0;
|
|
42
|
+
|
|
43
|
+
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
44
|
+
if (sockfd < 0) {
|
|
45
|
+
reject(@"SOCKET_ERROR", @"Failed to create socket", nil);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Set non-blocking mode
|
|
50
|
+
int flags = fcntl(sockfd, F_GETFL, 0);
|
|
51
|
+
if (flags < 0) {
|
|
52
|
+
close(sockfd);
|
|
53
|
+
reject(@"SOCKET_ERROR", @"Failed to get socket flags", nil);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
|
57
|
+
close(sockfd);
|
|
58
|
+
reject(@"SOCKET_ERROR", @"Failed to set non-blocking mode", nil);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Resolve hostname
|
|
63
|
+
struct addrinfo hints;
|
|
64
|
+
struct addrinfo *res = NULL;
|
|
65
|
+
memset(&hints, 0, sizeof(hints));
|
|
66
|
+
hints.ai_family = AF_UNSPEC;
|
|
67
|
+
hints.ai_socktype = SOCK_STREAM;
|
|
68
|
+
|
|
69
|
+
char portStr[16];
|
|
70
|
+
snprintf(portStr, sizeof(portStr), "%d", (int)port);
|
|
71
|
+
|
|
72
|
+
int gaiResult = getaddrinfo([host UTF8String], portStr, &hints, &res);
|
|
73
|
+
if (gaiResult != 0) {
|
|
74
|
+
close(sockfd);
|
|
75
|
+
reject(@"DNS_ERROR",
|
|
76
|
+
[NSString stringWithFormat:@"%s", gai_strerror(gaiResult)],
|
|
77
|
+
nil);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Attempt non-blocking connect
|
|
82
|
+
int connectResult = connect(sockfd, res->ai_addr, res->ai_addrlen);
|
|
83
|
+
freeaddrinfo(res);
|
|
84
|
+
|
|
85
|
+
if (connectResult < 0 && errno != EINPROGRESS) {
|
|
86
|
+
close(sockfd);
|
|
87
|
+
reject(@"CONNECT_ERROR",
|
|
88
|
+
[NSString stringWithUTF8String:strerror(errno)],
|
|
89
|
+
nil);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// If already connected (unlikely for non-blocking, but handle it)
|
|
94
|
+
if (connectResult == 0) {
|
|
95
|
+
close(sockfd);
|
|
96
|
+
NSTimeInterval elapsed = [[NSDate date] timeIntervalSince1970] * 1000.0 - startTime;
|
|
97
|
+
resolve(@((NSInteger)elapsed));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Wait for connection with select() and timeout
|
|
102
|
+
fd_set writeSet;
|
|
103
|
+
FD_ZERO(&writeSet);
|
|
104
|
+
FD_SET(sockfd, &writeSet);
|
|
105
|
+
|
|
106
|
+
long timeoutLong = (long)timeoutMs;
|
|
107
|
+
struct timeval tv;
|
|
108
|
+
tv.tv_sec = timeoutLong / 1000;
|
|
109
|
+
tv.tv_usec = (int)((timeoutLong % 1000) * 1000);
|
|
110
|
+
|
|
111
|
+
int selectResult = select(sockfd + 1, NULL, &writeSet, NULL, &tv);
|
|
112
|
+
|
|
113
|
+
if (selectResult == 0) {
|
|
114
|
+
// Timeout
|
|
115
|
+
close(sockfd);
|
|
116
|
+
reject(@"ETIMEDOUT", @"Connection timeout", nil);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (selectResult < 0) {
|
|
121
|
+
close(sockfd);
|
|
122
|
+
reject(@"SELECT_ERROR",
|
|
123
|
+
[NSString stringWithUTF8String:strerror(errno)],
|
|
124
|
+
nil);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Check for socket-level error via getsockopt
|
|
129
|
+
int socketError = 0;
|
|
130
|
+
socklen_t optLen = sizeof(socketError);
|
|
131
|
+
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &socketError, &optLen) < 0) {
|
|
132
|
+
close(sockfd);
|
|
133
|
+
reject(@"CONNECT_ERROR", @"Failed to get socket error", nil);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
close(sockfd);
|
|
138
|
+
|
|
139
|
+
if (socketError != 0) {
|
|
140
|
+
reject(@"CONNECT_ERROR",
|
|
141
|
+
[NSString stringWithUTF8String:strerror(socketError)],
|
|
142
|
+
nil);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
NSTimeInterval elapsed = [[NSDate date] timeIntervalSince1970] * 1000.0 - startTime;
|
|
147
|
+
resolve(@((NSInteger)elapsed));
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeTcpSocket.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAAQ,cAAc;AAgBlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,aAAa,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import NativeTcpSocket from "./NativeTcpSocket.js";
|
|
4
|
+
|
|
5
|
+
// Compatibility shim that mimics the react-native-tcp-socket createConnection API
|
|
6
|
+
// but uses a simple Promise underneath (works in background Hermes runtime)
|
|
7
|
+
|
|
8
|
+
function createConnection(options, connectCallback) {
|
|
9
|
+
const timeout = options.timeout ?? 5000;
|
|
10
|
+
const handlers = {};
|
|
11
|
+
let destroyed = false;
|
|
12
|
+
NativeTcpSocket.connectWithTimeout(options.host, options.port, timeout).then(() => {
|
|
13
|
+
if (!destroyed) connectCallback();
|
|
14
|
+
}).catch(err => {
|
|
15
|
+
if (!destroyed) {
|
|
16
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
17
|
+
if (errMsg.includes('timeout') || errMsg.includes('ETIMEDOUT') || errMsg.includes('Connection timeout')) {
|
|
18
|
+
handlers.timeout?.();
|
|
19
|
+
} else if (handlers.error) {
|
|
20
|
+
handlers.error(err instanceof Error ? err : new Error(errMsg));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
const shim = {
|
|
25
|
+
on(event, handler) {
|
|
26
|
+
if (event === 'error') {
|
|
27
|
+
handlers.error = handler;
|
|
28
|
+
} else if (event === 'timeout') {
|
|
29
|
+
handlers.timeout = handler;
|
|
30
|
+
}
|
|
31
|
+
return shim;
|
|
32
|
+
},
|
|
33
|
+
destroy() {
|
|
34
|
+
destroyed = true;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
return shim;
|
|
38
|
+
}
|
|
39
|
+
export default {
|
|
40
|
+
createConnection
|
|
41
|
+
};
|
|
42
|
+
export { NativeTcpSocket };
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NativeTcpSocket","createConnection","options","connectCallback","timeout","handlers","destroyed","connectWithTimeout","host","port","then","catch","err","errMsg","Error","message","String","includes","error","shim","on","event","handler","destroy"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,eAAe,MAAM,sBAAmB;;AAE/C;AACA;;AAOA,SAASC,gBAAgBA,CACvBC,OAAyD,EACzDC,eAA2B,EACZ;EACf,MAAMC,OAAO,GAAGF,OAAO,CAACE,OAAO,IAAI,IAAI;EACvC,MAAMC,QAAgE,GAAG,CAAC,CAAC;EAE3E,IAAIC,SAAS,GAAG,KAAK;EAErBN,eAAe,CAACO,kBAAkB,CAACL,OAAO,CAACM,IAAI,EAAEN,OAAO,CAACO,IAAI,EAAEL,OAAO,CAAC,CACpEM,IAAI,CAAC,MAAM;IACV,IAAI,CAACJ,SAAS,EAAEH,eAAe,CAAC,CAAC;EACnC,CAAC,CAAC,CACDQ,KAAK,CAAEC,GAAY,IAAK;IACvB,IAAI,CAACN,SAAS,EAAE;MACd,MAAMO,MAAM,GACVD,GAAG,YAAYE,KAAK,GAAGF,GAAG,CAACG,OAAO,GAAGC,MAAM,CAACJ,GAAa,CAAC;MAC5D,IACEC,MAAM,CAACI,QAAQ,CAAC,SAAS,CAAC,IAC1BJ,MAAM,CAACI,QAAQ,CAAC,WAAW,CAAC,IAC5BJ,MAAM,CAACI,QAAQ,CAAC,oBAAoB,CAAC,EACrC;QACAZ,QAAQ,CAACD,OAAO,GAAG,CAAC;MACtB,CAAC,MAAM,IAAIC,QAAQ,CAACa,KAAK,EAAE;QACzBb,QAAQ,CAACa,KAAK,CAACN,GAAG,YAAYE,KAAK,GAAGF,GAAG,GAAG,IAAIE,KAAK,CAACD,MAAM,CAAC,CAAC;MAChE;IACF;EACF,CAAC,CAAC;EAEJ,MAAMM,IAAI,GAAG;IACXC,EAAEA,CAACC,KAAa,EAAEC,OAA8B,EAAE;MAChD,IAAID,KAAK,KAAK,OAAO,EAAE;QACrBhB,QAAQ,CAACa,KAAK,GAAGI,OAA+B;MAClD,CAAC,MAAM,IAAID,KAAK,KAAK,SAAS,EAAE;QAC9BhB,QAAQ,CAACD,OAAO,GAAGkB,OAAqB;MAC1C;MACA,OAAOH,IAAI;IACb,CAAC;IACDI,OAAOA,CAAA,EAAG;MACRjB,SAAS,GAAG,IAAI;IAClB;EACF,CAA6B;EAC7B,OAAOa,IAAI;AACb;AAEA,eAAe;EAAElB;AAAiB,CAAC;AACnC,SAASD,eAAe","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TurboModule } from 'react-native';
|
|
2
|
+
export interface Spec extends TurboModule {
|
|
3
|
+
/**
|
|
4
|
+
* Attempt a TCP connection to host:port.
|
|
5
|
+
* Resolves with connection time in ms, rejects with error message.
|
|
6
|
+
*/
|
|
7
|
+
connectWithTimeout(host: string, port: number, timeoutMs: number): Promise<number>;
|
|
8
|
+
}
|
|
9
|
+
declare const _default: Spec;
|
|
10
|
+
export default _default;
|
|
11
|
+
//# sourceMappingURL=NativeTcpSocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeTcpSocket.d.ts","sourceRoot":"","sources":["../../../src/NativeTcpSocket.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC;;;OAGG;IACH,kBAAkB,CAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAAC;CACpB;;AAED,wBAAqE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import NativeTcpSocket from './NativeTcpSocket';
|
|
2
|
+
export interface TcpSocketShim {
|
|
3
|
+
on(event: 'error', handler: (err: Error) => void): this;
|
|
4
|
+
on(event: 'timeout', handler: () => void): this;
|
|
5
|
+
destroy(): void;
|
|
6
|
+
}
|
|
7
|
+
declare function createConnection(options: {
|
|
8
|
+
host: string;
|
|
9
|
+
port: number;
|
|
10
|
+
timeout?: number;
|
|
11
|
+
}, connectCallback: () => void): TcpSocketShim;
|
|
12
|
+
declare const _default: {
|
|
13
|
+
createConnection: typeof createConnection;
|
|
14
|
+
};
|
|
15
|
+
export default _default;
|
|
16
|
+
export { NativeTcpSocket };
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAIhD,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IACxD,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAChD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,iBAAS,gBAAgB,CACvB,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,EACzD,eAAe,EAAE,MAAM,IAAI,GAC1B,aAAa,CAwCf;;;;AAED,wBAAoC;AACpC,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@onekeyfe/react-native-tcp-socket",
|
|
3
|
+
"version": "1.1.56",
|
|
4
|
+
"description": "react-native-tcp-socket",
|
|
5
|
+
"main": "./lib/module/index.js",
|
|
6
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"source": "./src/index.tsx",
|
|
10
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
11
|
+
"default": "./lib/module/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"src",
|
|
17
|
+
"lib",
|
|
18
|
+
"ios",
|
|
19
|
+
"*.podspec",
|
|
20
|
+
"!ios/build",
|
|
21
|
+
"!**/__tests__",
|
|
22
|
+
"!**/__fixtures__",
|
|
23
|
+
"!**/__mocks__",
|
|
24
|
+
"!**/.*",
|
|
25
|
+
"android"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"clean": "del-cli ios/build lib",
|
|
29
|
+
"prepare": "bob build",
|
|
30
|
+
"typecheck": "tsc",
|
|
31
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
32
|
+
"test": "jest",
|
|
33
|
+
"release": "yarn prepare && npm whoami && npm publish --access public"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"react-native",
|
|
37
|
+
"ios",
|
|
38
|
+
"tcp",
|
|
39
|
+
"socket"
|
|
40
|
+
],
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "git+https://github.com/OneKeyHQ/app-modules/react-native-tcp-socket.git"
|
|
44
|
+
},
|
|
45
|
+
"author": "@onekeyhq <huanming@onekey.so> (https://github.com/OneKeyHQ/app-modules)",
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/OneKeyHQ/app-modules/react-native-tcp-socket/issues"
|
|
49
|
+
},
|
|
50
|
+
"homepage": "https://github.com/OneKeyHQ/app-modules/react-native-tcp-socket#readme",
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"registry": "https://registry.npmjs.org/"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@commitlint/config-conventional": "^19.8.1",
|
|
56
|
+
"@eslint/compat": "^1.3.2",
|
|
57
|
+
"@eslint/eslintrc": "^3.3.1",
|
|
58
|
+
"@eslint/js": "^9.35.0",
|
|
59
|
+
"@react-native/babel-preset": "0.83.0",
|
|
60
|
+
"@react-native/eslint-config": "0.83.0",
|
|
61
|
+
"@release-it/conventional-changelog": "^10.0.1",
|
|
62
|
+
"@types/jest": "^29.5.14",
|
|
63
|
+
"@types/react": "^19.2.0",
|
|
64
|
+
"commitlint": "^19.8.1",
|
|
65
|
+
"del-cli": "^6.0.0",
|
|
66
|
+
"eslint": "^9.35.0",
|
|
67
|
+
"eslint-config-prettier": "^10.1.8",
|
|
68
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
69
|
+
"jest": "^29.7.0",
|
|
70
|
+
"lefthook": "^2.0.3",
|
|
71
|
+
"prettier": "^2.8.8",
|
|
72
|
+
"react": "19.2.0",
|
|
73
|
+
"react-native": "patch:react-native@npm%3A0.83.0#~/.yarn/patches/react-native-npm-0.83.0-577d0f2d83.patch",
|
|
74
|
+
"react-native-builder-bob": "^0.40.17",
|
|
75
|
+
"release-it": "^19.0.4",
|
|
76
|
+
"turbo": "^2.5.6",
|
|
77
|
+
"typescript": "^5.9.2"
|
|
78
|
+
},
|
|
79
|
+
"peerDependencies": {
|
|
80
|
+
"react": "*",
|
|
81
|
+
"react-native": "*"
|
|
82
|
+
},
|
|
83
|
+
"react-native-builder-bob": {
|
|
84
|
+
"source": "src",
|
|
85
|
+
"output": "lib",
|
|
86
|
+
"targets": [
|
|
87
|
+
[
|
|
88
|
+
"module",
|
|
89
|
+
{
|
|
90
|
+
"esm": true
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
[
|
|
94
|
+
"typescript",
|
|
95
|
+
{
|
|
96
|
+
"project": "tsconfig.build.json"
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
"codegenConfig": {
|
|
102
|
+
"name": "RNTcpSocketSpec",
|
|
103
|
+
"type": "modules",
|
|
104
|
+
"jsSrcsDir": "src",
|
|
105
|
+
"android": {
|
|
106
|
+
"javaPackageName": "com.rntcpsocket"
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"prettier": {
|
|
110
|
+
"quoteProps": "consistent",
|
|
111
|
+
"singleQuote": true,
|
|
112
|
+
"tabWidth": 2,
|
|
113
|
+
"trailingComma": "es5",
|
|
114
|
+
"useTabs": false
|
|
115
|
+
},
|
|
116
|
+
"jest": {
|
|
117
|
+
"preset": "react-native",
|
|
118
|
+
"modulePathIgnorePatterns": [
|
|
119
|
+
"<rootDir>/lib/"
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
"commitlint": {
|
|
123
|
+
"extends": [
|
|
124
|
+
"@commitlint/config-conventional"
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
"release-it": {
|
|
128
|
+
"git": {
|
|
129
|
+
"commitMessage": "chore: release ${version}",
|
|
130
|
+
"tagName": "v${version}"
|
|
131
|
+
},
|
|
132
|
+
"npm": {
|
|
133
|
+
"publish": true
|
|
134
|
+
},
|
|
135
|
+
"github": {
|
|
136
|
+
"release": true
|
|
137
|
+
},
|
|
138
|
+
"plugins": {
|
|
139
|
+
"@release-it/conventional-changelog": {
|
|
140
|
+
"preset": {
|
|
141
|
+
"name": "angular"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
"create-react-native-library": {
|
|
147
|
+
"type": "turbo-module",
|
|
148
|
+
"languages": "kotlin-objc",
|
|
149
|
+
"tools": [
|
|
150
|
+
"eslint",
|
|
151
|
+
"jest",
|
|
152
|
+
"lefthook",
|
|
153
|
+
"release-it"
|
|
154
|
+
],
|
|
155
|
+
"version": "0.56.0"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import type { TurboModule } from 'react-native';
|
|
4
|
+
|
|
5
|
+
export interface Spec extends TurboModule {
|
|
6
|
+
/**
|
|
7
|
+
* Attempt a TCP connection to host:port.
|
|
8
|
+
* Resolves with connection time in ms, rejects with error message.
|
|
9
|
+
*/
|
|
10
|
+
connectWithTimeout(
|
|
11
|
+
host: string,
|
|
12
|
+
port: number,
|
|
13
|
+
timeoutMs: number,
|
|
14
|
+
): Promise<number>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default TurboModuleRegistry.getEnforcing<Spec>('RNTcpSocket');
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import NativeTcpSocket from './NativeTcpSocket';
|
|
2
|
+
|
|
3
|
+
// Compatibility shim that mimics the react-native-tcp-socket createConnection API
|
|
4
|
+
// but uses a simple Promise underneath (works in background Hermes runtime)
|
|
5
|
+
export interface TcpSocketShim {
|
|
6
|
+
on(event: 'error', handler: (err: Error) => void): this;
|
|
7
|
+
on(event: 'timeout', handler: () => void): this;
|
|
8
|
+
destroy(): void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function createConnection(
|
|
12
|
+
options: { host: string; port: number; timeout?: number },
|
|
13
|
+
connectCallback: () => void,
|
|
14
|
+
): TcpSocketShim {
|
|
15
|
+
const timeout = options.timeout ?? 5000;
|
|
16
|
+
const handlers: { error?: (err: Error) => void; timeout?: () => void } = {};
|
|
17
|
+
|
|
18
|
+
let destroyed = false;
|
|
19
|
+
|
|
20
|
+
NativeTcpSocket.connectWithTimeout(options.host, options.port, timeout)
|
|
21
|
+
.then(() => {
|
|
22
|
+
if (!destroyed) connectCallback();
|
|
23
|
+
})
|
|
24
|
+
.catch((err: unknown) => {
|
|
25
|
+
if (!destroyed) {
|
|
26
|
+
const errMsg =
|
|
27
|
+
err instanceof Error ? err.message : String(err as string);
|
|
28
|
+
if (
|
|
29
|
+
errMsg.includes('timeout') ||
|
|
30
|
+
errMsg.includes('ETIMEDOUT') ||
|
|
31
|
+
errMsg.includes('Connection timeout')
|
|
32
|
+
) {
|
|
33
|
+
handlers.timeout?.();
|
|
34
|
+
} else if (handlers.error) {
|
|
35
|
+
handlers.error(err instanceof Error ? err : new Error(errMsg));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const shim = {
|
|
41
|
+
on(event: string, handler: (err?: Error) => void) {
|
|
42
|
+
if (event === 'error') {
|
|
43
|
+
handlers.error = handler as (err: Error) => void;
|
|
44
|
+
} else if (event === 'timeout') {
|
|
45
|
+
handlers.timeout = handler as () => void;
|
|
46
|
+
}
|
|
47
|
+
return shim as unknown as TcpSocketShim;
|
|
48
|
+
},
|
|
49
|
+
destroy() {
|
|
50
|
+
destroyed = true;
|
|
51
|
+
},
|
|
52
|
+
} as unknown as TcpSocketShim;
|
|
53
|
+
return shim;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export default { createConnection };
|
|
57
|
+
export { NativeTcpSocket };
|