react-native 0.78.1 → 0.78.2

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.
@@ -118,4 +118,11 @@
118
118
  return nullptr;
119
119
  }
120
120
 
121
+ - (void)loadSourceForBridge:(RCTBridge *)bridge
122
+ onProgress:(RCTSourceLoadProgressBlock)onProgress
123
+ onComplete:(RCTSourceLoadBlock)loadCallback
124
+ {
125
+ [RCTJavaScriptLoader loadBundleAtURL:[self sourceURLForBridge:bridge] onProgress:onProgress onComplete:loadCallback];
126
+ }
127
+
121
128
  @end
@@ -1019,7 +1019,7 @@ function useTextInputStateSynchronization_STATE({
1019
1019
  mostRecentEventCount: number,
1020
1020
  selection: ?Selection,
1021
1021
  inputRef: React.RefObject<null | HostInstance>,
1022
- text: string,
1022
+ text?: string,
1023
1023
  viewCommands: ViewCommands,
1024
1024
  }): {
1025
1025
  setLastNativeText: string => void,
@@ -1100,7 +1100,7 @@ function useTextInputStateSynchronization_REFS({
1100
1100
  mostRecentEventCount: number,
1101
1101
  selection: ?Selection,
1102
1102
  inputRef: React.RefObject<null | HostInstance>,
1103
- text: string,
1103
+ text?: string,
1104
1104
  viewCommands: ViewCommands,
1105
1105
  }): {
1106
1106
  setLastNativeText: string => void,
@@ -1314,7 +1314,7 @@ function InternalTextInput(props: Props): React.Node {
1314
1314
  ? props.value
1315
1315
  : typeof props.defaultValue === 'string'
1316
1316
  ? props.defaultValue
1317
- : '';
1317
+ : undefined;
1318
1318
 
1319
1319
  const viewCommands =
1320
1320
  AndroidTextInputCommands ||
@@ -16,7 +16,7 @@ const version: $ReadOnly<{
16
16
  }> = {
17
17
  major: 0,
18
18
  minor: 78,
19
- patch: 1,
19
+ patch: 2,
20
20
  prerelease: null,
21
21
  };
22
22
 
@@ -8,6 +8,8 @@
8
8
  #import <React/RCTDataRequestHandler.h>
9
9
  #import <ReactCommon/RCTTurboModule.h>
10
10
 
11
+ #import <mutex>
12
+
11
13
  #import "RCTNetworkPlugins.h"
12
14
 
13
15
  @interface RCTDataRequestHandler () <RCTTurboModule>
@@ -15,14 +17,22 @@
15
17
 
16
18
  @implementation RCTDataRequestHandler {
17
19
  NSOperationQueue *_queue;
20
+ std::mutex _operationHandlerMutexLock;
18
21
  }
19
22
 
20
23
  RCT_EXPORT_MODULE()
21
24
 
22
25
  - (void)invalidate
23
26
  {
24
- [_queue cancelAllOperations];
25
- _queue = nil;
27
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
28
+ if (_queue) {
29
+ for (NSOperation *operation in _queue.operations) {
30
+ if (!operation.isCancelled && !operation.isFinished) {
31
+ [operation cancel];
32
+ }
33
+ }
34
+ _queue = nil;
35
+ }
26
36
  }
27
37
 
28
38
  - (BOOL)canHandleRequest:(NSURLRequest *)request
@@ -32,6 +42,7 @@ RCT_EXPORT_MODULE()
32
42
 
33
43
  - (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate
34
44
  {
45
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
35
46
  // Lazy setup
36
47
  if (!_queue) {
37
48
  _queue = [NSOperationQueue new];
@@ -69,7 +80,10 @@ RCT_EXPORT_MODULE()
69
80
 
70
81
  - (void)cancelRequest:(NSOperation *)op
71
82
  {
72
- [op cancel];
83
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
84
+ if (!op.isCancelled && !op.isFinished) {
85
+ [op cancel];
86
+ }
73
87
  }
74
88
 
75
89
  - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
@@ -7,6 +7,8 @@
7
7
 
8
8
  #import <React/RCTFileRequestHandler.h>
9
9
 
10
+ #import <mutex>
11
+
10
12
  #import <MobileCoreServices/MobileCoreServices.h>
11
13
 
12
14
  #import <React/RCTUtils.h>
@@ -19,14 +21,22 @@
19
21
 
20
22
  @implementation RCTFileRequestHandler {
21
23
  NSOperationQueue *_fileQueue;
24
+ std::mutex _operationHandlerMutexLock;
22
25
  }
23
26
 
24
27
  RCT_EXPORT_MODULE()
25
28
 
26
29
  - (void)invalidate
27
30
  {
28
- [_fileQueue cancelAllOperations];
29
- _fileQueue = nil;
31
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
32
+ if (_fileQueue) {
33
+ for (NSOperation *operation in _fileQueue.operations) {
34
+ if (!operation.isCancelled && !operation.isFinished) {
35
+ [operation cancel];
36
+ }
37
+ }
38
+ _fileQueue = nil;
39
+ }
30
40
  }
31
41
 
32
42
  - (BOOL)canHandleRequest:(NSURLRequest *)request
@@ -36,6 +46,7 @@ RCT_EXPORT_MODULE()
36
46
 
37
47
  - (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate
38
48
  {
49
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
39
50
  // Lazy setup
40
51
  if (!_fileQueue) {
41
52
  _fileQueue = [NSOperationQueue new];
@@ -83,7 +94,10 @@ RCT_EXPORT_MODULE()
83
94
 
84
95
  - (void)cancelRequest:(NSOperation *)op
85
96
  {
86
- [op cancel];
97
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
98
+ if (!op.isCancelled && !op.isFinished) {
99
+ [op cancel];
100
+ }
87
101
  }
88
102
 
89
103
  - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
@@ -23,7 +23,7 @@ NSDictionary* RCTGetReactNativeVersion(void)
23
23
  __rnVersion = @{
24
24
  RCTVersionMajor: @(0),
25
25
  RCTVersionMinor: @(78),
26
- RCTVersionPatch: @(1),
26
+ RCTVersionPatch: @(2),
27
27
  RCTVersionPrerelease: [NSNull null],
28
28
  };
29
29
  });
@@ -1,4 +1,4 @@
1
- VERSION_NAME=0.78.1
1
+ VERSION_NAME=0.78.2
2
2
  react.internal.publishingGroup=com.facebook.react
3
3
 
4
4
  android.useAndroidX=true
@@ -173,7 +173,7 @@ public class FabricUIManager
173
173
  private final CopyOnWriteArrayList<UIManagerListener> mListeners = new CopyOnWriteArrayList<>();
174
174
 
175
175
  private boolean mMountNotificationScheduled = false;
176
- private final List<Integer> mMountedSurfaceIds = new ArrayList<>();
176
+ private List<Integer> mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
177
177
 
178
178
  @ThreadConfined(UI)
179
179
  @NonNull
@@ -1250,12 +1250,15 @@ public class FabricUIManager
1250
1250
 
1251
1251
  // Collect surface IDs for all the mount items
1252
1252
  for (MountItem mountItem : mountItems) {
1253
- if (mountItem != null && !mMountedSurfaceIds.contains(mountItem.getSurfaceId())) {
1254
- mMountedSurfaceIds.add(mountItem.getSurfaceId());
1253
+ if (mountItem != null
1254
+ && !mSurfaceIdsWithPendingMountNotification.contains(mountItem.getSurfaceId())) {
1255
+ mSurfaceIdsWithPendingMountNotification.add(mountItem.getSurfaceId());
1255
1256
  }
1256
1257
  }
1257
1258
 
1258
- if (!mMountNotificationScheduled && !mMountedSurfaceIds.isEmpty()) {
1259
+ if (!mMountNotificationScheduled && !mSurfaceIdsWithPendingMountNotification.isEmpty()) {
1260
+ mMountNotificationScheduled = true;
1261
+
1259
1262
  // Notify mount when the effects are visible and prevent mount hooks to
1260
1263
  // delay paint.
1261
1264
  UiThreadUtil.getUiThreadHandler()
@@ -1265,17 +1268,19 @@ public class FabricUIManager
1265
1268
  public void run() {
1266
1269
  mMountNotificationScheduled = false;
1267
1270
 
1271
+ // Create a copy in case mount hooks trigger more mutations
1272
+ final List<Integer> surfaceIdsToReportMount =
1273
+ mSurfaceIdsWithPendingMountNotification;
1274
+ mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
1275
+
1268
1276
  final @Nullable FabricUIManagerBinding binding = mBinding;
1269
1277
  if (binding == null || mDestroyed) {
1270
- mMountedSurfaceIds.clear();
1271
1278
  return;
1272
1279
  }
1273
1280
 
1274
- for (int surfaceId : mMountedSurfaceIds) {
1281
+ for (int surfaceId : surfaceIdsToReportMount) {
1275
1282
  binding.reportMount(surfaceId);
1276
1283
  }
1277
-
1278
- mMountedSurfaceIds.clear();
1279
1284
  }
1280
1285
  });
1281
1286
  }
@@ -17,6 +17,6 @@ public class ReactNativeVersion {
17
17
  public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
18
18
  "major", 0,
19
19
  "minor", 78,
20
- "patch", 1,
20
+ "patch", 2,
21
21
  "prerelease", null);
22
22
  }
@@ -588,9 +588,6 @@ public class ReactViewGroup extends ViewGroup
588
588
  UiThreadUtil.assertOnUiThread();
589
589
  checkViewClippingTag(child, Boolean.TRUE);
590
590
  if (!customDrawOrderDisabled()) {
591
- if (indexOfChild(child) == -1) {
592
- return;
593
- }
594
591
  getDrawingOrderHelper().handleRemoveView(child);
595
592
  setChildrenDrawingOrderEnabled(getDrawingOrderHelper().shouldEnableCustomDrawingOrder());
596
593
  } else {
@@ -17,7 +17,7 @@ namespace facebook::react {
17
17
  constexpr struct {
18
18
  int32_t Major = 0;
19
19
  int32_t Minor = 78;
20
- int32_t Patch = 1;
20
+ int32_t Patch = 2;
21
21
  std::string_view Prerelease = "";
22
22
  } ReactNativeVersion;
23
23
 
@@ -57,7 +57,7 @@ static jsi::Value convertNSNumberToJSINumber(jsi::Runtime &runtime, NSNumber *va
57
57
 
58
58
  static jsi::String convertNSStringToJSIString(jsi::Runtime &runtime, NSString *value)
59
59
  {
60
- return jsi::String::createFromUtf8(runtime, [value UTF8String] ?: "");
60
+ return jsi::String::createFromUtf8(runtime, [value UTF8String] ? [value UTF8String] : "");
61
61
  }
62
62
 
63
63
  static jsi::Object convertNSDictionaryToJSIObject(jsi::Runtime &runtime, NSDictionary *value)
@@ -203,7 +203,11 @@ static jsi::Value createJSRuntimeError(jsi::Runtime &runtime, const std::string
203
203
  /**
204
204
  * Creates JSError with current JS runtime and NSException stack trace.
205
205
  */
206
- static jsi::JSError convertNSExceptionToJSError(jsi::Runtime &runtime, NSException *exception)
206
+ static jsi::JSError convertNSExceptionToJSError(
207
+ jsi::Runtime &runtime,
208
+ NSException *exception,
209
+ const std::string &moduleName,
210
+ const std::string &methodName)
207
211
  {
208
212
  std::string reason = [exception.reason UTF8String];
209
213
 
@@ -214,7 +218,8 @@ static jsi::JSError convertNSExceptionToJSError(jsi::Runtime &runtime, NSExcepti
214
218
  cause.setProperty(
215
219
  runtime, "stackReturnAddresses", convertNSArrayToJSIArray(runtime, exception.callStackReturnAddresses));
216
220
 
217
- jsi::Value error = createJSRuntimeError(runtime, "Exception in HostFunction: " + reason);
221
+ std::string message = moduleName + "." + methodName + " raised an exception: " + reason;
222
+ jsi::Value error = createJSRuntimeError(runtime, message);
218
223
  error.asObject(runtime).setProperty(runtime, "cause", std::move(cause));
219
224
  return {runtime, std::move(error)};
220
225
  }
@@ -346,28 +351,34 @@ id ObjCTurboModule::performMethodInvocation(
346
351
  }
347
352
 
348
353
  if (isSync) {
349
- TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodNameStr.c_str());
354
+ TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
350
355
  } else {
351
- TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodNameStr.c_str(), asyncCallCounter);
356
+ TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
352
357
  }
353
358
 
354
359
  @try {
355
360
  [inv invokeWithTarget:strongModule];
356
361
  } @catch (NSException *exception) {
357
- throw convertNSExceptionToJSError(runtime, exception);
362
+ if (isSync) {
363
+ // We can only convert NSException to JSError in sync method calls.
364
+ // See https://github.com/reactwg/react-native-new-architecture/discussions/276#discussioncomment-12567155
365
+ throw convertNSExceptionToJSError(runtime, exception, std::string{moduleName}, methodNameStr);
366
+ } else {
367
+ @throw exception;
368
+ }
358
369
  } @finally {
359
370
  [retainedObjectsForInvocation removeAllObjects];
360
371
  }
361
372
 
362
373
  if (!isSync) {
363
- TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodNameStr.c_str(), asyncCallCounter);
374
+ TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
364
375
  return;
365
376
  }
366
377
 
367
378
  void *rawResult;
368
379
  [inv getReturnValue:&rawResult];
369
380
  result = (__bridge id)rawResult;
370
- TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodNameStr.c_str());
381
+ TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
371
382
  };
372
383
 
373
384
  if (isSync) {
@@ -409,23 +420,23 @@ void ObjCTurboModule::performVoidMethodInvocation(
409
420
  }
410
421
 
411
422
  if (shouldVoidMethodsExecuteSync_) {
412
- TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodNameStr.c_str());
423
+ TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
413
424
  } else {
414
- TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodNameStr.c_str(), asyncCallCounter);
425
+ TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
415
426
  }
416
427
 
417
428
  @try {
418
429
  [inv invokeWithTarget:strongModule];
419
430
  } @catch (NSException *exception) {
420
- throw convertNSExceptionToJSError(runtime, exception);
431
+ throw convertNSExceptionToJSError(runtime, exception, std::string{moduleName}, methodNameStr);
421
432
  } @finally {
422
433
  [retainedObjectsForInvocation removeAllObjects];
423
434
  }
424
435
 
425
436
  if (shouldVoidMethodsExecuteSync_) {
426
- TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodNameStr.c_str());
437
+ TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
427
438
  } else {
428
- TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodNameStr.c_str(), asyncCallCounter);
439
+ TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
429
440
  }
430
441
 
431
442
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native",
3
- "version": "0.78.1",
3
+ "version": "0.78.2",
4
4
  "description": "A framework for building native apps using React",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -108,13 +108,13 @@
108
108
  },
109
109
  "dependencies": {
110
110
  "@jest/create-cache-key-function": "^29.6.3",
111
- "@react-native/assets-registry": "0.78.1",
112
- "@react-native/codegen": "0.78.1",
113
- "@react-native/community-cli-plugin": "0.78.1",
114
- "@react-native/gradle-plugin": "0.78.1",
115
- "@react-native/js-polyfills": "0.78.1",
116
- "@react-native/normalize-colors": "0.78.1",
117
- "@react-native/virtualized-lists": "0.78.1",
111
+ "@react-native/assets-registry": "0.78.2",
112
+ "@react-native/codegen": "0.78.2",
113
+ "@react-native/community-cli-plugin": "0.78.2",
114
+ "@react-native/gradle-plugin": "0.78.2",
115
+ "@react-native/js-polyfills": "0.78.2",
116
+ "@react-native/normalize-colors": "0.78.2",
117
+ "@react-native/virtualized-lists": "0.78.2",
118
118
  "abort-controller": "^3.0.0",
119
119
  "anser": "^1.4.9",
120
120
  "ansi-regex": "^5.0.0",
@@ -129,8 +129,8 @@
129
129
  "invariant": "^2.2.4",
130
130
  "jest-environment-node": "^29.6.3",
131
131
  "memoize-one": "^5.0.0",
132
- "metro-runtime": "^0.81.0",
133
- "metro-source-map": "^0.81.0",
132
+ "metro-runtime": "^0.81.3",
133
+ "metro-source-map": "^0.81.3",
134
134
  "nullthrows": "^1.1.1",
135
135
  "pretty-format": "^29.7.0",
136
136
  "promise": "^8.3.0",
Binary file
Binary file
Binary file