@onekeyfe/react-native-background-thread 1.1.47 → 1.1.49
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/android/src/main/java/com/backgroundthread/BackgroundThreadManager.kt +99 -25
- package/android/src/main/java/com/backgroundthread/BackgroundThreadModule.kt +11 -0
- package/ios/BackgroundRunnerReactNativeDelegate.h +7 -0
- package/ios/BackgroundRunnerReactNativeDelegate.mm +82 -7
- package/ios/BackgroundThread.h +4 -0
- package/ios/BackgroundThread.mm +16 -0
- package/ios/BackgroundThreadManager.h +8 -0
- package/ios/BackgroundThreadManager.mm +37 -3
- package/lib/module/NativeBackgroundThread.js.map +1 -1
- package/lib/typescript/src/NativeBackgroundThread.d.ts +1 -0
- package/lib/typescript/src/NativeBackgroundThread.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/NativeBackgroundThread.ts +4 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package com.backgroundthread
|
|
2
2
|
|
|
3
|
+
import android.net.Uri
|
|
3
4
|
import com.facebook.react.ReactPackage
|
|
4
5
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
5
6
|
import com.facebook.react.ReactInstanceEventListener
|
|
@@ -14,6 +15,7 @@ import com.facebook.react.fabric.ComponentFactory
|
|
|
14
15
|
import com.facebook.react.runtime.ReactHostImpl
|
|
15
16
|
import com.facebook.react.runtime.hermes.HermesInstance
|
|
16
17
|
import com.facebook.react.shell.MainReactPackage
|
|
18
|
+
import java.io.File
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* Singleton manager for the background React Native runtime.
|
|
@@ -92,13 +94,61 @@ class BackgroundThreadManager private constructor() {
|
|
|
92
94
|
|
|
93
95
|
// ── Background runner lifecycle ─────────────────────────────────────────
|
|
94
96
|
|
|
97
|
+
private fun isRemoteBundleUrl(entryURL: String): Boolean {
|
|
98
|
+
return entryURL.startsWith("http://") || entryURL.startsWith("https://")
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private fun resolveLocalBundlePath(entryURL: String): String? {
|
|
102
|
+
if (entryURL.startsWith("file://")) {
|
|
103
|
+
return Uri.parse(entryURL).path
|
|
104
|
+
}
|
|
105
|
+
if (entryURL.startsWith("/")) {
|
|
106
|
+
return entryURL
|
|
107
|
+
}
|
|
108
|
+
return null
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private fun createDownloadedBundleLoader(appContext: android.content.Context, entryURL: String): JSBundleLoader {
|
|
112
|
+
return object : JSBundleLoader() {
|
|
113
|
+
override fun loadScript(delegate: com.facebook.react.bridge.JSBundleLoaderDelegate): String {
|
|
114
|
+
val tempFile = File(appContext.cacheDir, "background.bundle")
|
|
115
|
+
try {
|
|
116
|
+
java.net.URL(entryURL).openStream().use { input ->
|
|
117
|
+
tempFile.outputStream().use { output ->
|
|
118
|
+
input.copyTo(output)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
BTLogger.info("Background bundle downloaded to ${tempFile.absolutePath}")
|
|
122
|
+
} catch (e: Exception) {
|
|
123
|
+
BTLogger.error("Failed to download background bundle: ${e.message}")
|
|
124
|
+
throw RuntimeException("Failed to download background bundle from $entryURL", e)
|
|
125
|
+
}
|
|
126
|
+
delegate.loadScriptFromFile(tempFile.absolutePath, entryURL, false)
|
|
127
|
+
return entryURL
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private fun createLocalFileBundleLoader(localPath: String, sourceURL: String): JSBundleLoader {
|
|
133
|
+
return object : JSBundleLoader() {
|
|
134
|
+
override fun loadScript(delegate: com.facebook.react.bridge.JSBundleLoaderDelegate): String {
|
|
135
|
+
val bundleFile = File(localPath)
|
|
136
|
+
if (!bundleFile.exists()) {
|
|
137
|
+
BTLogger.error("Background bundle file does not exist: $localPath")
|
|
138
|
+
throw RuntimeException("Background bundle file does not exist: $localPath")
|
|
139
|
+
}
|
|
140
|
+
delegate.loadScriptFromFile(bundleFile.absolutePath, sourceURL, false)
|
|
141
|
+
return sourceURL
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
95
146
|
@OptIn(UnstableReactNativeAPI::class)
|
|
96
147
|
fun startBackgroundRunnerWithEntryURL(context: ReactApplicationContext, entryURL: String) {
|
|
97
148
|
if (isStarted) {
|
|
98
149
|
BTLogger.warn("Background runner already started")
|
|
99
150
|
return
|
|
100
151
|
}
|
|
101
|
-
isStarted = true
|
|
102
152
|
BTLogger.info("Starting background runner with entryURL: $entryURL")
|
|
103
153
|
|
|
104
154
|
val appContext = context.applicationContext
|
|
@@ -106,34 +156,18 @@ class BackgroundThreadManager private constructor() {
|
|
|
106
156
|
if (reactPackages.isNotEmpty()) {
|
|
107
157
|
reactPackages
|
|
108
158
|
} else {
|
|
109
|
-
BTLogger.warn("No ReactPackages registered for background runtime;
|
|
159
|
+
BTLogger.warn("No ReactPackages registered for background runtime; call setReactPackages(...) from host before start. Falling back to MainReactPackage only.")
|
|
110
160
|
listOf(MainReactPackage())
|
|
111
161
|
}
|
|
112
162
|
|
|
113
|
-
val
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
java.net.URL(entryURL).openStream().use { input ->
|
|
121
|
-
tempFile.outputStream().use { output ->
|
|
122
|
-
input.copyTo(output)
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
BTLogger.info("Background bundle downloaded to ${tempFile.absolutePath}")
|
|
126
|
-
} catch (e: Exception) {
|
|
127
|
-
BTLogger.error("Failed to download background bundle: ${e.message}")
|
|
128
|
-
throw RuntimeException("Failed to download background bundle from $entryURL", e)
|
|
129
|
-
}
|
|
130
|
-
delegate.loadScriptFromFile(tempFile.absolutePath, entryURL, false)
|
|
131
|
-
return entryURL
|
|
132
|
-
}
|
|
163
|
+
val localBundlePath = resolveLocalBundlePath(entryURL)
|
|
164
|
+
val bundleLoader =
|
|
165
|
+
when {
|
|
166
|
+
isRemoteBundleUrl(entryURL) -> createDownloadedBundleLoader(appContext, entryURL)
|
|
167
|
+
localBundlePath != null -> createLocalFileBundleLoader(localBundlePath, entryURL)
|
|
168
|
+
entryURL.startsWith("assets://") -> JSBundleLoader.createAssetLoader(appContext, entryURL, true)
|
|
169
|
+
else -> JSBundleLoader.createAssetLoader(appContext, "assets://$entryURL", true)
|
|
133
170
|
}
|
|
134
|
-
} else {
|
|
135
|
-
JSBundleLoader.createAssetLoader(appContext, "assets://$entryURL", true)
|
|
136
|
-
}
|
|
137
171
|
|
|
138
172
|
val delegate = DefaultReactHostDelegate(
|
|
139
173
|
jsMainModulePath = MODULE_NAME,
|
|
@@ -177,6 +211,7 @@ class BackgroundThreadManager private constructor() {
|
|
|
177
211
|
})
|
|
178
212
|
|
|
179
213
|
host.start()
|
|
214
|
+
isStarted = true
|
|
180
215
|
}
|
|
181
216
|
|
|
182
217
|
/**
|
|
@@ -207,6 +242,45 @@ class BackgroundThreadManager private constructor() {
|
|
|
207
242
|
}
|
|
208
243
|
}
|
|
209
244
|
|
|
245
|
+
// ── Segment Registration (Phase 2.5 spike) ─────────────────────────────
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Register a HBC segment in the background runtime.
|
|
249
|
+
* Uses CatalystInstance.registerSegment() on the background ReactContext.
|
|
250
|
+
*
|
|
251
|
+
* @param segmentId The segment ID to register
|
|
252
|
+
* @param path Absolute file path to the .seg.hbc file
|
|
253
|
+
* @throws IllegalStateException if background runtime is not started
|
|
254
|
+
* @throws IllegalArgumentException if segment file does not exist
|
|
255
|
+
*/
|
|
256
|
+
fun registerSegmentInBackground(segmentId: Int, path: String) {
|
|
257
|
+
if (!isStarted) {
|
|
258
|
+
throw IllegalStateException("Background runtime not started")
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
val file = File(path)
|
|
262
|
+
if (!file.exists()) {
|
|
263
|
+
throw IllegalArgumentException("Segment file not found: $path")
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
val context = bgReactHost?.currentReactContext
|
|
267
|
+
?: throw IllegalStateException("Background ReactContext not available")
|
|
268
|
+
|
|
269
|
+
context.runOnJSQueueThread {
|
|
270
|
+
try {
|
|
271
|
+
if (context.hasCatalystInstance()) {
|
|
272
|
+
context.catalystInstance.registerSegment(segmentId, path)
|
|
273
|
+
BTLogger.info("Segment registered in background runtime: id=$segmentId, path=$path")
|
|
274
|
+
} else {
|
|
275
|
+
BTLogger.error("Background CatalystInstance not available for segment registration")
|
|
276
|
+
}
|
|
277
|
+
} catch (e: Exception) {
|
|
278
|
+
BTLogger.error("Failed to register segment in background runtime: ${e.message}")
|
|
279
|
+
throw e
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
210
284
|
// ── Lifecycle ───────────────────────────────────────────────────────────
|
|
211
285
|
|
|
212
286
|
val isBackgroundStarted: Boolean get() = isStarted
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package com.backgroundthread
|
|
2
2
|
|
|
3
|
+
import com.facebook.react.bridge.Promise
|
|
3
4
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
5
|
import com.facebook.react.module.annotations.ReactModule
|
|
5
6
|
|
|
@@ -26,4 +27,14 @@ class BackgroundThreadModule(reactContext: ReactApplicationContext) :
|
|
|
26
27
|
override fun startBackgroundRunnerWithEntryURL(entryURL: String) {
|
|
27
28
|
BackgroundThreadManager.getInstance().startBackgroundRunnerWithEntryURL(reactApplicationContext, entryURL)
|
|
28
29
|
}
|
|
30
|
+
|
|
31
|
+
override fun loadSegmentInBackground(segmentId: Double, path: String, promise: Promise) {
|
|
32
|
+
try {
|
|
33
|
+
BackgroundThreadManager.getInstance()
|
|
34
|
+
.registerSegmentInBackground(segmentId.toInt(), path)
|
|
35
|
+
promise.resolve(null)
|
|
36
|
+
} catch (e: Exception) {
|
|
37
|
+
promise.reject("BG_SEGMENT_LOAD_ERROR", e.message, e)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
29
40
|
}
|
|
@@ -31,6 +31,13 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
31
31
|
*/
|
|
32
32
|
- (instancetype)init;
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Register a HBC segment in the background runtime (Phase 2.5 spike).
|
|
36
|
+
* Uses RCTInstance's registerSegmentWithId:path: API.
|
|
37
|
+
* Must be called after hostDidStart: has completed.
|
|
38
|
+
*/
|
|
39
|
+
- (BOOL)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path;
|
|
40
|
+
|
|
34
41
|
@end
|
|
35
42
|
|
|
36
43
|
NS_ASSUME_NONNULL_END
|
|
@@ -71,6 +71,51 @@ static void invokeOptionalGlobalFunction(jsi::Runtime &runtime, const char *name
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
static NSURL *resolveMainBundleResourceURL(NSString *resourceName)
|
|
75
|
+
{
|
|
76
|
+
if (resourceName.length == 0) {
|
|
77
|
+
return nil;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
NSURL *directURL = [[NSBundle mainBundle] URLForResource:resourceName withExtension:nil];
|
|
81
|
+
if (directURL) {
|
|
82
|
+
return directURL;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
NSString *normalizedName = [resourceName hasPrefix:@"/"]
|
|
86
|
+
? resourceName.lastPathComponent
|
|
87
|
+
: resourceName;
|
|
88
|
+
NSString *extension = normalizedName.pathExtension;
|
|
89
|
+
NSString *baseName = normalizedName.stringByDeletingPathExtension;
|
|
90
|
+
if (baseName.length == 0) {
|
|
91
|
+
return nil;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return [[NSBundle mainBundle] URLForResource:baseName
|
|
95
|
+
withExtension:extension.length > 0 ? extension : nil];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static NSURL *resolveBundleSourceURL(NSString *jsBundleSourceNS)
|
|
99
|
+
{
|
|
100
|
+
if (jsBundleSourceNS.length == 0) {
|
|
101
|
+
return nil;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
NSURL *parsedURL = [NSURL URLWithString:jsBundleSourceNS];
|
|
105
|
+
if (parsedURL.scheme.length > 0) {
|
|
106
|
+
if (parsedURL.isFileURL && parsedURL.path.length > 0) {
|
|
107
|
+
return [NSURL fileURLWithPath:parsedURL.path];
|
|
108
|
+
}
|
|
109
|
+
return parsedURL;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if ([jsBundleSourceNS hasPrefix:@"/"]) {
|
|
113
|
+
return [NSURL fileURLWithPath:jsBundleSourceNS];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return resolveMainBundleResourceURL(jsBundleSourceNS);
|
|
117
|
+
}
|
|
118
|
+
|
|
74
119
|
@interface BackgroundReactNativeDelegate () {
|
|
75
120
|
RCTInstance *_rctInstance;
|
|
76
121
|
std::string _origin;
|
|
@@ -127,17 +172,19 @@ static void invokeOptionalGlobalFunction(jsi::Runtime &runtime, const char *name
|
|
|
127
172
|
{
|
|
128
173
|
if (!_jsBundleSource.empty()) {
|
|
129
174
|
NSString *jsBundleSourceNS = [NSString stringWithUTF8String:_jsBundleSource.c_str()];
|
|
130
|
-
NSURL *
|
|
131
|
-
if (
|
|
132
|
-
return
|
|
175
|
+
NSURL *resolvedURL = resolveBundleSourceURL(jsBundleSourceNS);
|
|
176
|
+
if (resolvedURL) {
|
|
177
|
+
return resolvedURL;
|
|
133
178
|
}
|
|
134
179
|
|
|
135
|
-
|
|
136
|
-
return [[NSBundle mainBundle] URLForResource:jsBundleSourceNS withExtension:nil];
|
|
137
|
-
}
|
|
180
|
+
[BTLogger warn:[NSString stringWithFormat:@"Unable to resolve custom jsBundleSource=%@", jsBundleSourceNS]];
|
|
138
181
|
}
|
|
139
182
|
|
|
140
|
-
|
|
183
|
+
NSURL *defaultBundleURL = resolveMainBundleResourceURL(@"background.bundle");
|
|
184
|
+
if (defaultBundleURL) {
|
|
185
|
+
return defaultBundleURL;
|
|
186
|
+
}
|
|
187
|
+
return [[NSBundle mainBundle] URLForResource:@"background" withExtension:@"bundle"];
|
|
141
188
|
}
|
|
142
189
|
|
|
143
190
|
- (void)hostDidStart:(RCTHost *)host
|
|
@@ -175,6 +222,34 @@ static void invokeOptionalGlobalFunction(jsi::Runtime &runtime, const char *name
|
|
|
175
222
|
}];
|
|
176
223
|
}
|
|
177
224
|
|
|
225
|
+
#pragma mark - Segment Registration (Phase 2.5 spike)
|
|
226
|
+
|
|
227
|
+
- (BOOL)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path
|
|
228
|
+
{
|
|
229
|
+
if (!_rctInstance) {
|
|
230
|
+
[BTLogger error:@"Cannot register segment: background RCTInstance not available"];
|
|
231
|
+
return NO;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
@try {
|
|
235
|
+
SEL sel = NSSelectorFromString(@"registerSegmentWithId:path:");
|
|
236
|
+
if ([_rctInstance respondsToSelector:sel]) {
|
|
237
|
+
#pragma clang diagnostic push
|
|
238
|
+
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
|
|
239
|
+
[_rctInstance performSelector:sel withObject:segmentId withObject:path];
|
|
240
|
+
#pragma clang diagnostic pop
|
|
241
|
+
[BTLogger info:[NSString stringWithFormat:@"Segment registered in background runtime: id=%@, path=%@", segmentId, path]];
|
|
242
|
+
return YES;
|
|
243
|
+
} else {
|
|
244
|
+
[BTLogger error:@"RCTInstance does not respond to registerSegmentWithId:path:"];
|
|
245
|
+
return NO;
|
|
246
|
+
}
|
|
247
|
+
} @catch (NSException *exception) {
|
|
248
|
+
[BTLogger error:[NSString stringWithFormat:@"Failed to register segment: %@", exception.reason]];
|
|
249
|
+
return NO;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
178
253
|
#pragma mark - RCTTurboModuleManagerDelegate
|
|
179
254
|
|
|
180
255
|
- (id<RCTModuleProvider>)getModuleProvider:(const char *)name
|
package/ios/BackgroundThread.h
CHANGED
|
@@ -5,5 +5,9 @@
|
|
|
5
5
|
- (void)startBackgroundRunner;
|
|
6
6
|
- (void)startBackgroundRunnerWithEntryURL:(NSString *)entryURL;
|
|
7
7
|
- (void)installSharedBridge;
|
|
8
|
+
- (void)loadSegmentInBackground:(double)segmentId
|
|
9
|
+
path:(NSString *)path
|
|
10
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
11
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
8
12
|
|
|
9
13
|
@end
|
package/ios/BackgroundThread.mm
CHANGED
|
@@ -29,6 +29,22 @@
|
|
|
29
29
|
[BTLogger info:@"installSharedBridge called (no-op on iOS, installed from AppDelegate)"];
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
- (void)loadSegmentInBackground:(double)segmentId
|
|
33
|
+
path:(NSString *)path
|
|
34
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
35
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
36
|
+
BackgroundThreadManager *manager = [BackgroundThreadManager sharedInstance];
|
|
37
|
+
[manager registerSegmentInBackground:@((int)segmentId)
|
|
38
|
+
path:path
|
|
39
|
+
completion:^(NSError * _Nullable error) {
|
|
40
|
+
if (error) {
|
|
41
|
+
reject(@"BG_SEGMENT_LOAD_ERROR", error.localizedDescription, error);
|
|
42
|
+
} else {
|
|
43
|
+
resolve(nil);
|
|
44
|
+
}
|
|
45
|
+
}];
|
|
46
|
+
}
|
|
47
|
+
|
|
32
48
|
+ (NSString *)moduleName
|
|
33
49
|
{
|
|
34
50
|
return @"BackgroundThread";
|
|
@@ -26,6 +26,14 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
26
26
|
/// Check if background runner is started
|
|
27
27
|
@property (nonatomic, readonly) BOOL isStarted;
|
|
28
28
|
|
|
29
|
+
/// Register a HBC segment in the background runtime (Phase 2.5 spike)
|
|
30
|
+
/// @param segmentId The segment ID to register
|
|
31
|
+
/// @param path Absolute file path to the .seg.hbc file
|
|
32
|
+
/// @param completion Callback with nil error on success, or NSError on failure
|
|
33
|
+
- (void)registerSegmentInBackground:(NSNumber *)segmentId
|
|
34
|
+
path:(NSString *)path
|
|
35
|
+
completion:(void (^)(NSError * _Nullable error))completion;
|
|
36
|
+
|
|
29
37
|
@end
|
|
30
38
|
|
|
31
39
|
NS_ASSUME_NONNULL_END
|
|
@@ -107,9 +107,7 @@ static NSString *const MODULE_DEBUG_URL = @"http://localhost:8082/apps/mobile/ba
|
|
|
107
107
|
self.reactNativeFactoryDelegate = [[BackgroundReactNativeDelegate alloc] init];
|
|
108
108
|
self.reactNativeFactory = [[RCTReactNativeFactory alloc] initWithDelegate:self.reactNativeFactoryDelegate];
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
[self.reactNativeFactoryDelegate setJsBundleSource:std::string([entryURL UTF8String])];
|
|
112
|
-
#endif
|
|
110
|
+
[self.reactNativeFactoryDelegate setJsBundleSource:std::string([entryURL UTF8String])];
|
|
113
111
|
|
|
114
112
|
[self.reactNativeFactory.rootViewFactory viewWithModuleName:MODULE_NAME
|
|
115
113
|
initialProperties:initialProperties
|
|
@@ -117,4 +115,40 @@ static NSString *const MODULE_DEBUG_URL = @"http://localhost:8082/apps/mobile/ba
|
|
|
117
115
|
});
|
|
118
116
|
}
|
|
119
117
|
|
|
118
|
+
#pragma mark - Segment Registration (Phase 2.5 spike)
|
|
119
|
+
|
|
120
|
+
- (void)registerSegmentInBackground:(NSNumber *)segmentId
|
|
121
|
+
path:(NSString *)path
|
|
122
|
+
completion:(void (^)(NSError * _Nullable error))completion
|
|
123
|
+
{
|
|
124
|
+
if (!self.isStarted || !self.reactNativeFactoryDelegate) {
|
|
125
|
+
NSError *error = [NSError errorWithDomain:@"BackgroundThread"
|
|
126
|
+
code:1
|
|
127
|
+
userInfo:@{NSLocalizedDescriptionKey: @"Background runtime not started"}];
|
|
128
|
+
if (completion) completion(error);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Verify the file exists
|
|
133
|
+
if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
|
|
134
|
+
NSError *error = [NSError errorWithDomain:@"BackgroundThread"
|
|
135
|
+
code:2
|
|
136
|
+
userInfo:@{NSLocalizedDescriptionKey:
|
|
137
|
+
[NSString stringWithFormat:@"Segment file not found: %@", path]}];
|
|
138
|
+
if (completion) completion(error);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
BOOL success = [self.reactNativeFactoryDelegate registerSegmentWithId:segmentId path:path];
|
|
143
|
+
if (success) {
|
|
144
|
+
if (completion) completion(nil);
|
|
145
|
+
} else {
|
|
146
|
+
NSError *error = [NSError errorWithDomain:@"BackgroundThread"
|
|
147
|
+
code:3
|
|
148
|
+
userInfo:@{NSLocalizedDescriptionKey:
|
|
149
|
+
@"Failed to register segment in background runtime"}];
|
|
150
|
+
if (completion) completion(error);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
120
154
|
@end
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeBackgroundThread.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAAQ,cAAc;
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeBackgroundThread.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAAQ,cAAc;AAYlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,kBAAkB,CAAC","ignoreList":[]}
|
|
@@ -2,6 +2,7 @@ import type { TurboModule } from 'react-native';
|
|
|
2
2
|
export interface Spec extends TurboModule {
|
|
3
3
|
startBackgroundRunnerWithEntryURL(entryURL: string): void;
|
|
4
4
|
installSharedBridge(): void;
|
|
5
|
+
loadSegmentInBackground(segmentId: number, path: string): Promise<void>;
|
|
5
6
|
}
|
|
6
7
|
declare const _default: Spec;
|
|
7
8
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeBackgroundThread.d.ts","sourceRoot":"","sources":["../../../src/NativeBackgroundThread.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,iCAAiC,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1D,mBAAmB,IAAI,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeBackgroundThread.d.ts","sourceRoot":"","sources":["../../../src/NativeBackgroundThread.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,iCAAiC,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1D,mBAAmB,IAAI,IAAI,CAAC;IAC5B,uBAAuB,CACrB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;;AAED,wBAA0E"}
|
package/package.json
CHANGED
|
@@ -4,6 +4,10 @@ import type { TurboModule } from 'react-native';
|
|
|
4
4
|
export interface Spec extends TurboModule {
|
|
5
5
|
startBackgroundRunnerWithEntryURL(entryURL: string): void;
|
|
6
6
|
installSharedBridge(): void;
|
|
7
|
+
loadSegmentInBackground(
|
|
8
|
+
segmentId: number,
|
|
9
|
+
path: string,
|
|
10
|
+
): Promise<void>;
|
|
7
11
|
}
|
|
8
12
|
|
|
9
13
|
export default TurboModuleRegistry.getEnforcing<Spec>('BackgroundThread');
|